diff --git a/SPECS/qemu/0059-hw-usb-host-libusb-udev-product_desc-is-non-NULL.patch b/SPECS/qemu/0059-hw-usb-host-libusb-udev-product_desc-is-non-NULL.patch new file mode 100644 index 000000000..2232ee7d6 --- /dev/null +++ b/SPECS/qemu/0059-hw-usb-host-libusb-udev-product_desc-is-non-NULL.patch @@ -0,0 +1,38 @@ +From 092fb023ac87a9d47615df2547aae6f7bcdf3599 Mon Sep 17 00:00:00 2001 +From: Dongwon Kim +Date: Wed, 14 Jan 2026 13:57:31 -0800 +Subject: [PATCH 3/6] hw/usb/host-libusb: udev->product_desc is non-NULL + +Null checking on udev->product_desc is always false as +it is an array. + +Signed-off-by: Dongwon Kim +--- + hw/usb/host-libusb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c +index 3a08caafa5..6291d57cea 100644 +--- a/hw/usb/host-libusb.c ++++ b/hw/usb/host-libusb.c +@@ -889,7 +889,7 @@ static void usb_host_ep_update(USBHostDevice *s) + if (!conf || conf->bNumInterfaces == 0) { + warn_report("usb-host: ignoring invalid configuration " + "for device %s (bus=%03d, addr=%03d)", +- udev->product_desc ? udev->product_desc : "unknown", ++ udev->product_desc, + s->bus_num, s->addr); + return; + } +@@ -916,7 +916,7 @@ static void usb_host_ep_update(USBHostDevice *s) + alt, + conf->interface[i].num_altsetting ? conf->interface[i].num_altsetting - 1 : -1, + i, +- udev->product_desc ? udev->product_desc : "unknown", ++ udev->product_desc, + s->bus_num, s->addr); + continue; + } +-- +2.43.0 + diff --git a/SPECS/qemu/0060-ui-gtk-Add-HW-cursor-and-render_sync-status-to-statu.patch b/SPECS/qemu/0060-ui-gtk-Add-HW-cursor-and-render_sync-status-to-statu.patch new file mode 100644 index 000000000..79d2f9e44 --- /dev/null +++ b/SPECS/qemu/0060-ui-gtk-Add-HW-cursor-and-render_sync-status-to-statu.patch @@ -0,0 +1,55 @@ +From 37c235ed7b3f18d5d7c3a437939742c0c4ccafe9 Mon Sep 17 00:00:00 2001 +From: Dongwon Kim +Date: Thu, 8 Jan 2026 15:31:32 -0800 +Subject: [PATCH] ui/gtk: Add HW cursor and render_sync status to status bar + +Display HW cursor and render_sync status at the beginning of the GTK +status bar before FPS information. The status shows 'on' when hw_cursor +option is enabled and a cursor image is present, otherwise shows 'off'. +Similarly, render_sync shows 'on' when dmabuf has render_sync enabled. + +This provides better visibility into hardware cursor and render_sync +state during runtime. + +Signed-off-by: Dongwon Kim +--- + ui/gtk.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/ui/gtk.c b/ui/gtk.c +index 1442507b45..9496b6dad4 100644 +--- a/ui/gtk.c ++++ b/ui/gtk.c +@@ -618,9 +618,28 @@ void gd_gl_count_frame(DisplayChangeListener *dcl, bool ups, bool fps) + + delta = curr - prev; + if (delta > 1000000) { +- int d = 0; ++ int d = 0; + /* update rate is calculated and displayed at every 1 secs */ + prev = curr; ++ ++ /* Add HW cursor status at the beginning */ ++ bool hw_cursor_active = false; ++ bool render_sync_active = false; ++ for (i = 0; i < vc->s->nb_vcs; i++) { ++ vc = &s->vc[i]; ++ if (vc->type == GD_VC_GFX && vc->gfx.cursor_image != NULL) { ++ hw_cursor_active = true; ++ } ++ if (vc->type == GD_VC_GFX && vc->gfx.guest_fb.dmabuf && ++ qemu_dmabuf_get_render_sync(vc->gfx.guest_fb.dmabuf)) { ++ render_sync_active = true; ++ } ++ } ++ offset += sprintf(ups_fps_str + offset, "HW cursor %s | render_sync %s ", ++ (s->opts->u.gtk.has_hw_cursor && ++ s->opts->u.gtk.hw_cursor && hw_cursor_active) ? "on" : "off", ++ render_sync_active ? "on" : "off"); ++ + for (i = 0; i < vc->s->nb_vcs; i++) { + vc = &s->vc[i]; + if (vc->type == GD_VC_GFX && +-- +2.43.0 + diff --git a/SPECS/qemu/0061-ui-gtk-check-return-value-of-gdk_seat_grab.patch b/SPECS/qemu/0061-ui-gtk-check-return-value-of-gdk_seat_grab.patch new file mode 100644 index 000000000..5b2746100 --- /dev/null +++ b/SPECS/qemu/0061-ui-gtk-check-return-value-of-gdk_seat_grab.patch @@ -0,0 +1,130 @@ +From 276b832f7d4d31b954155b362dff6fd0c39ac060 Mon Sep 17 00:00:00 2001 +From: Dongwon Kim +Date: Wed, 4 Mar 2026 21:31:59 -0800 +Subject: [PATCH 6/6] ui/gtk: check return value of gdk_seat_grab + +The function gd_grab_update previously ignored the return value of +gdk_seat_grab. This could lead to a state inconsistency where QEMU +believes it owns the input grab (setting kbd_owner or ptr_owner) +even if the underlying window system denied the request. + +Change gd_grab_update to return a boolean indicating success. +Update gd_grab_keyboard and gd_grab_pointer to check this status +before updating the owner pointers and calculating grab positions. + +Signed-off-by: Dongwon Kim +--- + ui/gtk.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +diff --git a/ui/gtk.c b/ui/gtk.c +index 5c14fbb186..cb7bb9dd36 100644 +--- a/ui/gtk.c ++++ b/ui/gtk.c +@@ -1602,7 +1602,6 @@ static gboolean gd_window_state_event(GtkWidget *widget, GdkEvent *event, + s->kbd_owner = NULL; + gd_grab_keyboard(vc, "windows-focused"); + } +- + } + + /* WA to fullscreen window if it's forcefully un-fullscreened by +@@ -1682,7 +1681,7 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque) + } + + static void gd_accel_grab_input(void *opaque); +-static void gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr); ++static bool gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr); + + static void gd_window_show_on_monitor(GdkDisplay *dpy, VirtualConsole *vc, + gint monitor_num) +@@ -2068,13 +2067,14 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque) + gd_update_full_redraw(vc); + } + +-static void gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr) ++static bool gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr) + { + GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area); + GdkSeat *seat = gdk_display_get_default_seat(display); + GdkWindow *window = gtk_widget_get_window(vc->gfx.drawing_area); + GdkSeatCapabilities caps = 0; + GdkCursor *cursor = NULL; ++ GdkGrabStatus grab_status; + + if (kbd) { + caps |= GDK_SEAT_CAPABILITY_KEYBOARD; +@@ -2085,15 +2085,21 @@ static void gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr) + } + + if (caps) { +- gdk_seat_grab(seat, window, caps, false, cursor, +- NULL, NULL, NULL); ++ grab_status = gdk_seat_grab(seat, window, caps, false, cursor, ++ NULL, NULL, NULL); ++ if (grab_status != GDK_GRAB_SUCCESS) { ++ return FALSE; ++ } + } else { + gdk_seat_ungrab(seat); + } ++ ++ return TRUE; + } + + static void gd_grab_keyboard(VirtualConsole *vc, const char *reason) + { ++ bool grab_status; + if (vc->s->kbd_owner) { + if (vc->s->kbd_owner == vc) { + return; +@@ -2103,8 +2109,10 @@ static void gd_grab_keyboard(VirtualConsole *vc, const char *reason) + } + + win32_kbd_set_grab(true); +- gd_grab_update(vc, true, vc->s->ptr_owner == vc); +- vc->s->kbd_owner = vc; ++ grab_status = gd_grab_update(vc, true, vc->s->ptr_owner == vc); ++ if (grab_status) { ++ vc->s->kbd_owner = vc; ++ } + gd_update_caption(vc->s); + trace_gd_grab(vc->label, "kbd", reason); + } +@@ -2127,6 +2135,7 @@ static void gd_ungrab_keyboard(GtkDisplayState *s) + static void gd_grab_pointer(VirtualConsole *vc, const char *reason) + { + GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area); ++ bool grab_status; + + if (vc->s->ptr_owner) { + if (vc->s->ptr_owner == vc) { +@@ -2136,10 +2145,13 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason) + } + } + +- gd_grab_update(vc, vc->s->kbd_owner == vc, true); +- gdk_device_get_position(gd_get_pointer(display), +- NULL, &vc->s->grab_x_root, &vc->s->grab_y_root); +- vc->s->ptr_owner = vc; ++ grab_status = gd_grab_update(vc, vc->s->kbd_owner == vc, true); ++ if (grab_status) { ++ gdk_device_get_position(gd_get_pointer(display), ++ NULL, &vc->s->grab_x_root, &vc->s->grab_y_root); ++ vc->s->ptr_owner = vc; ++ } ++ + gd_update_caption(vc->s); + trace_gd_grab(vc->label, "ptr", reason); + } +@@ -3019,7 +3031,6 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts) + vc = gd_vc_find_current(s); + g_signal_connect(s->window, "window-state-event", + G_CALLBACK(gd_window_state_event), vc); +- + gtk_widget_set_sensitive(s->view_menu, vc != NULL); + #ifdef CONFIG_VTE + gtk_widget_set_sensitive(s->copy_item, +-- +2.43.0 + diff --git a/SPECS/qemu/qemu.spec b/SPECS/qemu/qemu.spec index 351577d3c..f479f2e0e 100644 --- a/SPECS/qemu/qemu.spec +++ b/SPECS/qemu/qemu.spec @@ -446,7 +446,7 @@ Obsoletes: sgabios-bin <= 1:0.20180715git-10.fc38 Summary: QEMU is a FAST! processor emulator Name: qemu Version: 9.1.0 -Release: 6%{?dist} +Release: 7%{?dist} License: Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND FSFAP AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-2.0-or-later WITH GCC-exception-2.0 AND LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND MIT AND LicenseRef-Fedora-Public-Domain AND CC-BY-3.0 URL: http://www.qemu.org/ @@ -541,6 +541,9 @@ Patch59: 0056-hw-display-virtio-gpu-Properly-free-current_cursor.patch Patch60: 0057-ui-gtk-Re-grabbing-PTR-KBD-individually.patch Patch61: 0058-hw-usb-host-libusb-Do-not-assert-when-detects-invali.patch Patch62: CVE-2025-54567.patch +Patch63: 0059-hw-usb-host-libusb-udev-product_desc-is-non-NULL.patch +Patch64: 0060-ui-gtk-Add-HW-cursor-and-render_sync-status-to-statu.patch +Patch65: 0061-ui-gtk-check-return-value-of-gdk_seat_grab.patch BuildRequires: gnupg2 BuildRequires: meson >= %{meson_version} @@ -3539,6 +3542,11 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %changelog +* Mon Mar 17 2026 Dongwon Kim - 9.1.0-7 +- Mouse regrab fix +- Null check in libusb-udev-product_desc +- Check pass/fail from gdk_seat_grab + * Tue Jan 27 2025 Rajesh Shanmugam - 9.1.0-6 - Added 1 patch from Intel Distribution Qemu Commit 8e06d09 - Add patch for CVE-2025-54566 CVE-2025-54567