From 5280117b1e66555a526e04c624d9e1e8e7fec1ae Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Wed, 12 Jan 2022 10:01:25 +0100 Subject: [PATCH 01/20] hw/usb/dev-wacom: add missing HID descriptor Linux need to fill up the HID descriptor in order to let the driver be emulated. The descriptor was downloaded from [1]. The patch was tested with evtest tool on top of qemu 5.2.0 with linux kernel 4.19.208. [1] https://github.com/linuxwacom/wacom-hid-descriptors/tree/master/Wacom%20PenPartner Signed-off-by: Michael Trimarchi Co-developed-by: Michael Trimarchi Signed-off-by: Dario Binacchi Message-Id: <20220112090125.381364-1-dario.binacchi@amarulasolutions.com> Signed-off-by: Gerd Hoffmann --- hw/usb/dev-wacom.c | 72 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c index ed687bc9f1..8323650c6a 100644 --- a/hw/usb/dev-wacom.c +++ b/hw/usb/dev-wacom.c @@ -69,6 +69,65 @@ static const USBDescStrings desc_strings = { [STR_SERIALNUMBER] = "1", }; +static const uint8_t qemu_wacom_hid_report_descriptor[] = { + 0x05, 0x01, /* Usage Page (Desktop) */ + 0x09, 0x02, /* Usage (Mouse) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x85, 0x01, /* Report ID (1) */ + 0x09, 0x01, /* Usage (Pointer) */ + 0xa1, 0x00, /* Collection (Physical) */ + 0x05, 0x09, /* Usage Page (Button) */ + 0x19, 0x01, /* Usage Minimum (01h) */ + 0x29, 0x03, /* Usage Maximum (03h) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x95, 0x03, /* Report Count (3) */ + 0x75, 0x01, /* Report Size (1) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x95, 0x01, /* Report Count (1) */ + 0x75, 0x05, /* Report Size (5) */ + 0x81, 0x01, /* Input (Constant) */ + 0x05, 0x01, /* Usage Page (Desktop) */ + 0x09, 0x30, /* Usage (X) */ + 0x09, 0x31, /* Usage (Y) */ + 0x09, 0x38, /* Usage (Wheel) */ + 0x15, 0x81, /* Logical Minimum (-127) */ + 0x25, 0x7f, /* Logical Maximum (127) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x03, /* Report Count (3) */ + 0x81, 0x06, /* Input (Data, Variable, Relative) */ + 0x95, 0x03, /* Report Count (3) */ + 0x81, 0x01, /* Input (Constant) */ + 0xc0, /* End Collection */ + 0xc0, /* End Collection */ + 0x05, 0x0d, /* Usage Page (Digitizer) */ + 0x09, 0x01, /* Usage (Digitizer) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x85, 0x02, /* Report ID (2) */ + 0xa1, 0x00, /* Collection (Physical) */ + 0x06, 0x00, 0xff,/* Usage Page (ff00h), vendor-defined */ + 0x09, 0x01, /* Usage (01h) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xff, 0x00,/* Logical Maximum (255) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x07, /* Report Count (7) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0xc0, /* End Collection */ + 0x09, 0x01, /* Usage (01h) */ + 0x85, 0x63, /* Report ID (99) */ + 0x95, 0x07, /* Report Count (7) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x09, 0x01, /* Usage (01h) */ + 0x85, 0x02, /* Report ID (2) */ + 0x95, 0x01, /* Report Count (1) */ + 0xb1, 0x02, /* Feature (Variable) */ + 0x09, 0x01, /* Usage (01h) */ + 0x85, 0x03, /* Report ID (3) */ + 0x95, 0x01, /* Report Count (1) */ + 0xb1, 0x02, /* Feature (Variable) */ + 0xc0 /* End Collection */ +}; + static const USBDescIface desc_iface_wacom = { .bInterfaceNumber = 0, .bNumEndpoints = 1, @@ -86,7 +145,7 @@ static const USBDescIface desc_iface_wacom = { 0x00, /* u8 country_code */ 0x01, /* u8 num_descriptors */ USB_DT_REPORT, /* u8 type: Report */ - 0x6e, 0, /* u16 len */ + sizeof(qemu_wacom_hid_report_descriptor), 0, /* u16 len */ }, }, }, @@ -266,6 +325,17 @@ static void usb_wacom_handle_control(USBDevice *dev, USBPacket *p, } switch (request) { + case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: + switch (value >> 8) { + case 0x22: + memcpy(data, qemu_wacom_hid_report_descriptor, + sizeof(qemu_wacom_hid_report_descriptor)); + p->actual_length = sizeof(qemu_wacom_hid_report_descriptor); + break; + default: + return; + } + break; case WACOM_SET_REPORT: if (s->mouse_grabbed) { qemu_remove_mouse_event_handler(s->eh_entry); From 7cd2cfa2e6d61fac3652422f46aa77899bbeb757 Mon Sep 17 00:00:00 2001 From: zhenwei pi Date: Wed, 12 Jan 2022 09:58:35 +0800 Subject: [PATCH 02/20] usb: allow max 8192 bytes for desc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A device of USB video class usually uses larger desc structure, so use larger buffer to avoid failure. (dev-video.c is ready) This is an unlikely code path: 1, during guest startup, guest tries to probe device. 2, run 'lsusb' command in guest(or other similar commands). Reviewed-by: Daniel P. Berrangé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: zhenwei pi Message-Id: <20220112015835.900619-1-pizhenwei@bytedance.com> Signed-off-by: Gerd Hoffmann --- hw/usb/desc.c | 15 ++++++++------- hw/usb/desc.h | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/hw/usb/desc.c b/hw/usb/desc.c index 8b6eaea407..7f6cc2f99b 100644 --- a/hw/usb/desc.c +++ b/hw/usb/desc.c @@ -632,7 +632,8 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p, bool msos = (dev->flags & (1 << USB_DEV_FLAG_MSOS_DESC_IN_USE)); const USBDesc *desc = usb_device_get_usb_desc(dev); const USBDescDevice *other_dev; - uint8_t buf[256]; + size_t buflen = USB_DESC_MAX_LEN; + g_autofree uint8_t *buf = g_malloc(buflen); uint8_t type = value >> 8; uint8_t index = value & 0xff; int flags, ret = -1; @@ -650,36 +651,36 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p, switch(type) { case USB_DT_DEVICE: - ret = usb_desc_device(&desc->id, dev->device, msos, buf, sizeof(buf)); + ret = usb_desc_device(&desc->id, dev->device, msos, buf, buflen); trace_usb_desc_device(dev->addr, len, ret); break; case USB_DT_CONFIG: if (index < dev->device->bNumConfigurations) { ret = usb_desc_config(dev->device->confs + index, flags, - buf, sizeof(buf)); + buf, buflen); } trace_usb_desc_config(dev->addr, index, len, ret); break; case USB_DT_STRING: - ret = usb_desc_string(dev, index, buf, sizeof(buf)); + ret = usb_desc_string(dev, index, buf, buflen); trace_usb_desc_string(dev->addr, index, len, ret); break; case USB_DT_DEVICE_QUALIFIER: if (other_dev != NULL) { - ret = usb_desc_device_qualifier(other_dev, buf, sizeof(buf)); + ret = usb_desc_device_qualifier(other_dev, buf, buflen); } trace_usb_desc_device_qualifier(dev->addr, len, ret); break; case USB_DT_OTHER_SPEED_CONFIG: if (other_dev != NULL && index < other_dev->bNumConfigurations) { ret = usb_desc_config(other_dev->confs + index, flags, - buf, sizeof(buf)); + buf, buflen); buf[0x01] = USB_DT_OTHER_SPEED_CONFIG; } trace_usb_desc_other_speed_config(dev->addr, index, len, ret); break; case USB_DT_BOS: - ret = usb_desc_bos(desc, buf, sizeof(buf)); + ret = usb_desc_bos(desc, buf, buflen); trace_usb_desc_bos(dev->addr, len, ret); break; diff --git a/hw/usb/desc.h b/hw/usb/desc.h index 3ac604ecfa..35babdeff6 100644 --- a/hw/usb/desc.h +++ b/hw/usb/desc.h @@ -199,6 +199,7 @@ struct USBDesc { const USBDescMSOS *msos; }; +#define USB_DESC_MAX_LEN 8192 #define USB_DESC_FLAG_SUPER (1 << 1) /* little helpers */ From 1dbbe6f172810026c51dc84ed927a3cc23017949 Mon Sep 17 00:00:00 2001 From: Rao Lei Date: Wed, 5 Jan 2022 10:08:08 +0800 Subject: [PATCH 03/20] ui/vnc.c: Fixed a deadlock bug. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GDB statck is as follows: (gdb) bt 0 __lll_lock_wait (futex=futex@entry=0x56211df20360, private=0) at lowlevellock.c:52 1 0x00007f263caf20a3 in __GI___pthread_mutex_lock (mutex=0x56211df20360) at ../nptl/pthread_mutex_lock.c:80 2 0x000056211a757364 in qemu_mutex_lock_impl (mutex=0x56211df20360, file=0x56211a804857 "../ui/vnc-jobs.h", line=60) at ../util/qemu-thread-posix.c:80 3 0x000056211a0ef8c7 in vnc_lock_output (vs=0x56211df14200) at ../ui/vnc-jobs.h:60 4 0x000056211a0efcb7 in vnc_clipboard_send (vs=0x56211df14200, count=1, dwords=0x7ffdf1701338) at ../ui/vnc-clipboard.c:138 5 0x000056211a0f0129 in vnc_clipboard_notify (notifier=0x56211df244c8, data=0x56211dd1bbf0) at ../ui/vnc-clipboard.c:209 6 0x000056211a75dde8 in notifier_list_notify (list=0x56211afa17d0 , data=0x56211dd1bbf0) at ../util/notify.c:39 7 0x000056211a0bf0e6 in qemu_clipboard_update (info=0x56211dd1bbf0) at ../ui/clipboard.c:50 8 0x000056211a0bf05d in qemu_clipboard_peer_release (peer=0x56211df244c0, selection=QEMU_CLIPBOARD_SELECTION_CLIPBOARD) at ../ui/clipboard.c:41 9 0x000056211a0bef9b in qemu_clipboard_peer_unregister (peer=0x56211df244c0) at ../ui/clipboard.c:19 10 0x000056211a0d45f3 in vnc_disconnect_finish (vs=0x56211df14200) at ../ui/vnc.c:1358 11 0x000056211a0d4c9d in vnc_client_read (vs=0x56211df14200) at ../ui/vnc.c:1611 12 0x000056211a0d4df8 in vnc_client_io (ioc=0x56211ce70690, condition=G_IO_IN, opaque=0x56211df14200) at ../ui/vnc.c:1649 13 0x000056211a5b976c in qio_channel_fd_source_dispatch (source=0x56211ce50a00, callback=0x56211a0d4d71 , user_data=0x56211df14200) at ../io/channel-watch.c:84 14 0x00007f263ccede8e in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 15 0x000056211a77d4a1 in glib_pollfds_poll () at ../util/main-loop.c:232 16 0x000056211a77d51f in os_host_main_loop_wait (timeout=958545) at ../util/main-loop.c:255 17 0x000056211a77d630 in main_loop_wait (nonblocking=0) at ../util/main-loop.c:531 18 0x000056211a45bc8e in qemu_main_loop () at ../softmmu/runstate.c:726 19 0x000056211a0b45fa in main (argc=69, argv=0x7ffdf1701778, envp=0x7ffdf17019a8) at ../softmmu/main.c:50 From the call trace, we can see it is a deadlock bug. vnc_disconnect_finish will acquire the output_mutex. But, the output_mutex will be acquired again in vnc_clipboard_send. Repeated locking will cause deadlock. So, I move qemu_clipboard_peer_unregister() behind vnc_unlock_output(); Fixes: 0bf41cab93e ("ui/vnc: clipboard support") Signed-off-by: Lei Rao Reviewed-by: Marc-André Lureau Message-Id: <20220105020808.597325-1-lei.rao@intel.com> Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 1ed1c7efc6..3ccd33dedc 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1354,12 +1354,12 @@ void vnc_disconnect_finish(VncState *vs) /* last client gone */ vnc_update_server_surface(vs->vd); } + vnc_unlock_output(vs); + if (vs->cbpeer.notifier.notify) { qemu_clipboard_peer_unregister(&vs->cbpeer); } - vnc_unlock_output(vs); - qemu_mutex_destroy(&vs->output_mutex); if (vs->bh != NULL) { qemu_bh_delete(vs->bh); From ead789eb46a7df4eaab9e14e29e1d0d2a379988d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20R=C3=BCmelin?= Date: Sun, 26 Dec 2021 16:40:15 +0100 Subject: [PATCH 04/20] jackaudio: use ifdefs to hide unavailable functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows the jack_set_thread_creator() function and on MacOS the pthread_setname_np() function with a thread pointer paramater is not available. Use #ifdefs to remove the jack_set_thread_creator() function call and the qjack_thread_creator() function in both cases. The qjack_thread_creator() function just sets the name of the created thread for debugging purposes and isn't really necessary. From the jack_set_thread_creator() documentation: (...) No normal application/client should consider calling this. (...) Resolves: https://gitlab.com/qemu-project/qemu/-/issues/785 Signed-off-by: Volker Rümelin Reviewed-by: Christian Schoenebeck Message-Id: <20211226154017.6067-1-vr_qemu@t-online.de> Signed-off-by: Gerd Hoffmann --- audio/jackaudio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/audio/jackaudio.c b/audio/jackaudio.c index e7de6d5433..317009e936 100644 --- a/audio/jackaudio.c +++ b/audio/jackaudio.c @@ -622,6 +622,7 @@ static void qjack_enable_in(HWVoiceIn *hw, bool enable) ji->c.enabled = enable; } +#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID) static int qjack_thread_creator(jack_native_thread_t *thread, const pthread_attr_t *attr, void *(*function)(void *), void *arg) { @@ -635,6 +636,7 @@ static int qjack_thread_creator(jack_native_thread_t *thread, return ret; } +#endif static void *qjack_init(Audiodev *dev) { @@ -687,7 +689,9 @@ static void register_audio_jack(void) { qemu_mutex_init(&qjack_shutdown_lock); audio_driver_register(&jack_driver); +#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID) jack_set_thread_creator(qjack_thread_creator); +#endif jack_set_error_function(qjack_error); jack_set_info_function(qjack_info); } From 9d90ceb27461d7d0d172fd941b812d511794a6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20R=C3=BCmelin?= Date: Sun, 26 Dec 2021 16:40:16 +0100 Subject: [PATCH 05/20] dsoundaudio: fix crackling audio recordings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audio recordings with the DirectSound backend don't sound right. A look a the Microsoft online documentation tells us why. From the DirectSound Programming Guide, Capture Buffer Information: 'You can safely copy data from the buffer only up to the read cursor.' Change the code to read up to the read cursor instead of the capture cursor. Signed-off-by: Volker Rümelin Message-Id: <20211226154017.6067-2-vr_qemu@t-online.de> Signed-off-by: Gerd Hoffmann --- audio/dsoundaudio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index cfc79c129e..3dd2c4d4a6 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -536,13 +536,12 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; HRESULT hr; - DWORD cpos, rpos, act_size; + DWORD rpos, act_size; size_t req_size; int err; void *ret; - hr = IDirectSoundCaptureBuffer_GetCurrentPosition( - dscb, &cpos, ds->first_time ? &rpos : NULL); + hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, NULL, &rpos); if (FAILED(hr)) { dsound_logerr(hr, "Could not get capture buffer position\n"); *size = 0; @@ -554,7 +553,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) ds->first_time = false; } - req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul); + req_size = audio_ring_dist(rpos, hw->pos_emul, hw->size_emul); req_size = MIN(*size, MIN(req_size, hw->size_emul - hw->pos_emul)); if (req_size == 0) { From ecd5f2882fdd10f798984eb52abd00ffc78c2ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20R=C3=BCmelin?= Date: Sun, 26 Dec 2021 16:40:17 +0100 Subject: [PATCH 06/20] hw/audio/intel-hda: fix stream reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quote from: High Definition Audio Specification 1.0a, section 3.3.35 Offset 80: {IOB}SDnCTL Stream Reset (SRST): Writing a 1 causes the corresponding stream to be reset. The Stream Descriptor registers (except the SRST bit itself) ... are reset. Change the code to reset the Stream Descriptor Control and Status registers except the SRST bit. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/757 Signed-off-by: Volker Rümelin Message-Id: <20211226154017.6067-3-vr_qemu@t-online.de> Signed-off-by: Gerd Hoffmann --- hw/audio/intel-hda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index 2b55d52150..5f8a878f20 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -581,7 +581,7 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3 if (st->ctl & 0x01) { /* reset */ dprint(d, 1, "st #%d: reset\n", reg->stream); - st->ctl = SD_STS_FIFO_READY << 24; + st->ctl = SD_STS_FIFO_READY << 24 | SD_CTL_STREAM_RESET; } if ((st->ctl & 0x02) != (old & 0x02)) { uint32_t stnr = (st->ctl >> 20) & 0x0f; From fc94d1159c8c8da6105cd2beb11c1f24746a2d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 22 Dec 2021 18:40:32 +0400 Subject: [PATCH 07/20] ui/dbus: fix buffer-overflow detected by ASAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the last added dbus patch, I left a tiny BO: ==441487==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x611000025a70 at pc 0x7f0817bb764c bp 0x7ffde672ae60 sp 0x7ffde672ae58 WRITE of size 8 at 0x611000025a70 thread T0 #0 0x7f0817bb764b in dbus_vc_class_init ../ui/dbus.c:401 A cookie for ASAN! not you C :) Signed-off-by: Marc-André Lureau Fixes: 7f767ca35e5 ("ui/dbus: register D-Bus VC handler") Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211222144032.443424-1-marcandre.lureau@redhat.com> Signed-off-by: Gerd Hoffmann --- ui/dbus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/dbus.c b/ui/dbus.c index b2c1c9fb52..0074424c1f 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -405,6 +405,7 @@ dbus_vc_class_init(ObjectClass *oc, void *data) static const TypeInfo dbus_vc_type_info = { .name = TYPE_CHARDEV_VC, .parent = TYPE_CHARDEV_DBUS, + .class_size = sizeof(DBusVCClass), .class_init = dbus_vc_class_init, }; From 87800d940584cb22fbfa1a0da61f2365e6ede3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 16 Dec 2021 12:32:33 +0400 Subject: [PATCH 08/20] ui: fix gtk clipboard clear assertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When closing the QEMU Gtk display window, it can occasionaly warn: qemu-system-x86_64: Gtk: gtk_clipboard_set_with_data: assertion 'targets != NULL' failed #3 0x00007ffff4f02f22 in gtk_clipboard_set_with_data (clipboard=, targets=, n_targets=, get_func=, clear_func=, user_data=) at /usr/src/debug/gtk3-3.24.30-4.fc35.x86_64/gtk/gtkclipboard.c:672 #4 0x00007ffff552cd75 in gd_clipboard_update_info (gd=0x5555579a9e00, info=0x555557ba4b50) at ../ui/gtk-clipboard.c:98 #5 0x00007ffff552ce00 in gd_clipboard_notify (notifier=0x5555579aaba8, data=0x7fffffffd720) at ../ui/gtk-clipboard.c:128 #6 0x000055555603e0ff in notifier_list_notify (list=0x555556657470 , data=0x7fffffffd720) at ../util/notify.c:39 #7 0x000055555594e8e0 in qemu_clipboard_update (info=0x555557ba4b50) at ../ui/clipboard.c:54 #8 0x000055555594e840 in qemu_clipboard_peer_release (peer=0x55555684a5b0, selection=QEMU_CLIPBOARD_SELECTION_PRIMARY) at ../ui/clipboard.c:40 #9 0x000055555594e786 in qemu_clipboard_peer_unregister (peer=0x55555684a5b0) at ../ui/clipboard.c:19 #10 0x000055555595f044 in vdagent_disconnect (vd=0x55555684a400) at ../ui/vdagent.c:852 #11 0x000055555595f262 in vdagent_chr_fini (obj=0x55555684a400) at ../ui/vdagent.c:908 Signed-off-by: Marc-André Lureau Message-Id: <20211216083233.1166504-1-marcandre.lureau@redhat.com> Signed-off-by: Gerd Hoffmann --- ui/gtk-clipboard.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c index e0b8b283fe..d58fd761ab 100644 --- a/ui/gtk-clipboard.c +++ b/ui/gtk-clipboard.c @@ -83,7 +83,7 @@ static void gd_clipboard_update_info(GtkDisplayState *gd, if (info != qemu_clipboard_info(s)) { gd->cbpending[s] = 0; if (!self_update) { - GtkTargetList *list; + g_autoptr(GtkTargetList) list = NULL; GtkTargetEntry *targets; gint n_targets; @@ -94,15 +94,16 @@ static void gd_clipboard_update_info(GtkDisplayState *gd, targets = gtk_target_table_new_from_list(list, &n_targets); gtk_clipboard_clear(gd->gtkcb[s]); - gd->cbowner[s] = true; - gtk_clipboard_set_with_data(gd->gtkcb[s], - targets, n_targets, - gd_clipboard_get_data, - gd_clipboard_clear, - gd); + if (targets) { + gd->cbowner[s] = true; + gtk_clipboard_set_with_data(gd->gtkcb[s], + targets, n_targets, + gd_clipboard_get_data, + gd_clipboard_clear, + gd); - gtk_target_table_free(targets, n_targets); - gtk_target_list_unref(list); + gtk_target_table_free(targets, n_targets); + } } return; } From 1c6c0b9ec1c0d980d4f0ac2604c4f9fd9611034b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 10 Dec 2021 09:06:59 +0100 Subject: [PATCH 09/20] uas: add missing return MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we run the error handling code even for successful requests. Fixes: 13b250b12ad3 ("uas: add stream number sanity checks.") Reported-by: Guenter Roeck Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211210080659.2537084-1-kraxel@redhat.com> --- hw/usb/dev-uas.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index 599d6b52a0..c9f295e7e4 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -908,6 +908,7 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p) p->status = USB_RET_STALL; break; } + return; err_stream: error_report("%s: invalid stream %d", __func__, p->stream); From 3ac25236ea6dd52a44c679ebd0a8126662d0ab4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 6 Dec 2021 23:45:25 +0100 Subject: [PATCH 10/20] hw/display: Rename VGA_ISA_MM -> VGA_MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no ISA bus part in the MMIO VGA device, so rename: * hw/display/vga-isa-mm.c -> hw/display/vga-mmio.c * CONFIG_VGA_ISA_MM -> CONFIG_VGA_MMIO * ISAVGAMMState -> VGAMmioState * isa_vga_mm_init() -> vga_mmio_init() Reviewed-by: BALATON Zoltan Reviewed-by: Thomas Huth Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211206224528.563588-2-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- configs/devices/mips-softmmu/common.mak | 2 +- hw/display/Kconfig | 2 +- hw/display/meson.build | 2 +- hw/display/{vga-isa-mm.c => vga-mmio.c} | 19 +++++++++---------- hw/mips/Kconfig | 2 +- hw/mips/jazz.c | 2 +- include/hw/display/vga.h | 5 ++--- 7 files changed, 16 insertions(+), 18 deletions(-) rename hw/display/{vga-isa-mm.c => vga-mmio.c} (90%) diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak index 752b62b1e6..d2202c839e 100644 --- a/configs/devices/mips-softmmu/common.mak +++ b/configs/devices/mips-softmmu/common.mak @@ -7,7 +7,7 @@ CONFIG_ISA_BUS=y CONFIG_PCI=y CONFIG_PCI_DEVICES=y CONFIG_VGA_ISA=y -CONFIG_VGA_ISA_MM=y +CONFIG_VGA_MMIO=y CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_SERIAL=y diff --git a/hw/display/Kconfig b/hw/display/Kconfig index a2306b67d8..a1b159becd 100644 --- a/hw/display/Kconfig +++ b/hw/display/Kconfig @@ -49,7 +49,7 @@ config VGA_ISA depends on ISA_BUS select VGA -config VGA_ISA_MM +config VGA_MMIO bool select VGA diff --git a/hw/display/meson.build b/hw/display/meson.build index 861c43ff98..adc53dd8b6 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -18,7 +18,7 @@ softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xenfb.c')) softmmu_ss.add(when: 'CONFIG_VGA_PCI', if_true: files('vga-pci.c')) softmmu_ss.add(when: 'CONFIG_VGA_ISA', if_true: files('vga-isa.c')) -softmmu_ss.add(when: 'CONFIG_VGA_ISA_MM', if_true: files('vga-isa-mm.c')) +softmmu_ss.add(when: 'CONFIG_VGA_MMIO', if_true: files('vga-mmio.c')) softmmu_ss.add(when: 'CONFIG_VMWARE_VGA', if_true: files('vmware_vga.c')) softmmu_ss.add(when: 'CONFIG_BOCHS_DISPLAY', if_true: files('bochs-display.c')) diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-mmio.c similarity index 90% rename from hw/display/vga-isa-mm.c rename to hw/display/vga-mmio.c index 7321b7a06d..4ffe3afe32 100644 --- a/hw/display/vga-isa-mm.c +++ b/hw/display/vga-mmio.c @@ -1,5 +1,5 @@ /* - * QEMU ISA MM VGA Emulator. + * QEMU MMIO VGA Emulator. * * Copyright (c) 2003 Fabrice Bellard * @@ -32,15 +32,15 @@ #define VGA_RAM_SIZE (8 * MiB) -typedef struct ISAVGAMMState { +typedef struct VGAMmioState { VGACommonState vga; int it_shift; -} ISAVGAMMState; +} VGAMmioState; /* Memory mapped interface */ static uint64_t vga_mm_read(void *opaque, hwaddr addr, unsigned size) { - ISAVGAMMState *s = opaque; + VGAMmioState *s = opaque; return vga_ioport_read(&s->vga, addr >> s->it_shift) & MAKE_64BIT_MASK(0, size * 8); @@ -49,7 +49,7 @@ static uint64_t vga_mm_read(void *opaque, hwaddr addr, unsigned size) static void vga_mm_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { - ISAVGAMMState *s = opaque; + VGAMmioState *s = opaque; vga_ioport_write(&s->vga, addr >> s->it_shift, value & MAKE_64BIT_MASK(0, size * 8)); @@ -65,7 +65,7 @@ static const MemoryRegionOps vga_mm_ctrl_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void vga_mm_init(ISAVGAMMState *s, hwaddr vram_base, +static void vga_mm_init(VGAMmioState *s, hwaddr vram_base, hwaddr ctrl_base, int it_shift, MemoryRegion *address_space) { @@ -91,11 +91,10 @@ static void vga_mm_init(ISAVGAMMState *s, hwaddr vram_base, memory_region_set_coalescing(vga_io_memory); } -int isa_vga_mm_init(hwaddr vram_base, - hwaddr ctrl_base, int it_shift, - MemoryRegion *address_space) +int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, + int it_shift, MemoryRegion *address_space) { - ISAVGAMMState *s; + VGAMmioState *s; s = g_malloc0(sizeof(*s)); diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index b4c5549ce8..725525358d 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -16,7 +16,7 @@ config JAZZ select I8254 select I8257 select PCSPK - select VGA_ISA_MM + select VGA_MMIO select G364FB select DP8393X select ESP diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index f5a26e174d..8f345afd13 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -274,7 +274,7 @@ static void mips_jazz_init(MachineState *machine, } break; case JAZZ_PICA61: - isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory()); + vga_mmio_init(0x40000000, 0x60000000, 0, get_system_memory()); break; default: break; diff --git a/include/hw/display/vga.h b/include/hw/display/vga.h index 5f7825e0e3..c16a5c26da 100644 --- a/include/hw/display/vga.h +++ b/include/hw/display/vga.h @@ -24,8 +24,7 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; -int isa_vga_mm_init(hwaddr vram_base, - hwaddr ctrl_base, int it_shift, - MemoryRegion *address_space); +int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, + int it_shift, MemoryRegion *address_space); #endif From 6bd06f773163459706017d5fead84ae899e4ac16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 6 Dec 2021 23:45:26 +0100 Subject: [PATCH 11/20] hw/display/vga-mmio: Inline vga_mm_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline vga_mm_init() in vga_mmio_init() to simplify the next patch review. Kind of. Reviewed-by: BALATON Zoltan Reviewed-by: Thomas Huth Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211206224528.563588-3-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- hw/display/vga-mmio.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/hw/display/vga-mmio.c b/hw/display/vga-mmio.c index 4ffe3afe32..5671fdb920 100644 --- a/hw/display/vga-mmio.c +++ b/hw/display/vga-mmio.c @@ -65,12 +65,18 @@ static const MemoryRegionOps vga_mm_ctrl_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void vga_mm_init(VGAMmioState *s, hwaddr vram_base, - hwaddr ctrl_base, int it_shift, - MemoryRegion *address_space) +int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, + int it_shift, MemoryRegion *address_space) { + VGAMmioState *s; MemoryRegion *s_ioport_ctrl, *vga_io_memory; + s = g_malloc0(sizeof(*s)); + + s->vga.vram_size_mb = VGA_RAM_SIZE / MiB; + s->vga.global_vmstate = true; + vga_common_init(&s->vga, NULL); + s->it_shift = it_shift; s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl)); memory_region_init_io(s_ioport_ctrl, NULL, &vga_mm_ctrl_ops, s, @@ -89,19 +95,6 @@ static void vga_mm_init(VGAMmioState *s, hwaddr vram_base, memory_region_add_subregion(address_space, vram_base + 0x000a0000, vga_io_memory); memory_region_set_coalescing(vga_io_memory); -} - -int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, - int it_shift, MemoryRegion *address_space) -{ - VGAMmioState *s; - - s = g_malloc0(sizeof(*s)); - - s->vga.vram_size_mb = VGA_RAM_SIZE / MiB; - s->vga.global_vmstate = true; - vga_common_init(&s->vga, NULL); - vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space); s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s); From 23f6e3b11be74abae77584a069ec710d719ac5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 6 Dec 2021 23:45:27 +0100 Subject: [PATCH 12/20] hw/display/vga-mmio: QOM'ify vga_mmio_init() as TYPE_VGA_MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce TYPE_VGA_MMIO, a sysbus device. While there is no change in the vga_mmio_init() interface, this is a migration compatibility break of the MIPS Acer Pica 61 Jazz machine (pica61). Suggested-by: Thomas Huth Reviewed-by: BALATON Zoltan Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Message-Id: <20211206224528.563588-4-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- hw/display/vga-mmio.c | 132 +++++++++++++++++++++++++++------------ include/hw/display/vga.h | 2 + 2 files changed, 94 insertions(+), 40 deletions(-) diff --git a/hw/display/vga-mmio.c b/hw/display/vga-mmio.c index 5671fdb920..10bde32af5 100644 --- a/hw/display/vga-mmio.c +++ b/hw/display/vga-mmio.c @@ -23,21 +23,34 @@ */ #include "qemu/osdep.h" -#include "qemu/bitops.h" -#include "qemu/units.h" -#include "migration/vmstate.h" +#include "qapi/error.h" #include "hw/display/vga.h" +#include "hw/sysbus.h" +#include "hw/display/vga.h" +#include "hw/qdev-properties.h" #include "vga_int.h" -#include "ui/pixel_ops.h" -#define VGA_RAM_SIZE (8 * MiB) +/* + * QEMU interface: + * + sysbus MMIO region 0: VGA I/O registers + * + sysbus MMIO region 1: VGA MMIO registers + * + sysbus MMIO region 2: VGA memory + */ -typedef struct VGAMmioState { +OBJECT_DECLARE_SIMPLE_TYPE(VGAMmioState, VGA_MMIO) + +struct VGAMmioState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ VGACommonState vga; - int it_shift; -} VGAMmioState; + MemoryRegion iomem; + MemoryRegion lowmem; + + uint8_t it_shift; +}; -/* Memory mapped interface */ static uint64_t vga_mm_read(void *opaque, hwaddr addr, unsigned size) { VGAMmioState *s = opaque; @@ -65,42 +78,81 @@ static const MemoryRegionOps vga_mm_ctrl_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static void vga_mmio_reset(DeviceState *dev) +{ + VGAMmioState *s = VGA_MMIO(dev); + + vga_common_reset(&s->vga); +} + int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, int it_shift, MemoryRegion *address_space) { - VGAMmioState *s; - MemoryRegion *s_ioport_ctrl, *vga_io_memory; + DeviceState *dev; + SysBusDevice *s; - s = g_malloc0(sizeof(*s)); + dev = qdev_new(TYPE_VGA_MMIO); + qdev_prop_set_uint8(dev, "it_shift", it_shift); + s = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(s, &error_fatal); - s->vga.vram_size_mb = VGA_RAM_SIZE / MiB; - s->vga.global_vmstate = true; - vga_common_init(&s->vga, NULL); - - s->it_shift = it_shift; - s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl)); - memory_region_init_io(s_ioport_ctrl, NULL, &vga_mm_ctrl_ops, s, - "vga-mm-ctrl", 0x100000); - memory_region_set_flush_coalesced(s_ioport_ctrl); - - vga_io_memory = g_malloc(sizeof(*vga_io_memory)); - /* XXX: endianness? */ - memory_region_init_io(vga_io_memory, NULL, &vga_mem_ops, &s->vga, - "vga-mem", 0x20000); - - vmstate_register(NULL, 0, &vmstate_vga_common, s); - - memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl); - s->vga.bank_offset = 0; - memory_region_add_subregion(address_space, - vram_base + 0x000a0000, vga_io_memory); - memory_region_set_coalescing(vga_io_memory); - - s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s); - - memory_region_add_subregion(address_space, - VBE_DISPI_LFB_PHYSICAL_ADDRESS, - &s->vga.vram); + sysbus_mmio_map(s, 0, ctrl_base); + sysbus_mmio_map(s, 1, vram_base + 0x000a0000); + sysbus_mmio_map(s, 2, VBE_DISPI_LFB_PHYSICAL_ADDRESS); return 0; } + +static void vga_mmio_realizefn(DeviceState *dev, Error **errp) +{ + VGAMmioState *s = VGA_MMIO(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + + memory_region_init_io(&s->iomem, OBJECT(dev), &vga_mm_ctrl_ops, s, + "vga-mmio", 0x100000); + memory_region_set_flush_coalesced(&s->iomem); + sysbus_init_mmio(sbd, &s->iomem); + + /* XXX: endianness? */ + memory_region_init_io(&s->lowmem, OBJECT(dev), &vga_mem_ops, &s->vga, + "vga-lowmem", 0x20000); + memory_region_set_coalescing(&s->lowmem); + sysbus_init_mmio(sbd, &s->lowmem); + + s->vga.bank_offset = 0; + s->vga.global_vmstate = true; + vga_common_init(&s->vga, OBJECT(dev)); + sysbus_init_mmio(sbd, &s->vga.vram); + s->vga.con = graphic_console_init(dev, 0, s->vga.hw_ops, &s->vga); +} + +static Property vga_mmio_properties[] = { + DEFINE_PROP_UINT8("it_shift", VGAMmioState, it_shift, 0), + DEFINE_PROP_UINT32("vgamem_mb", VGAMmioState, vga.vram_size_mb, 8), + DEFINE_PROP_END_OF_LIST(), +}; + +static void vga_mmio_class_initfn(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = vga_mmio_realizefn; + dc->reset = vga_mmio_reset; + dc->vmsd = &vmstate_vga_common; + device_class_set_props(dc, vga_mmio_properties); + set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); +} + +static const TypeInfo vga_mmio_info = { + .name = TYPE_VGA_MMIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(VGAMmioState), + .class_init = vga_mmio_class_initfn, +}; + +static void vga_mmio_register_types(void) +{ + type_register_static(&vga_mmio_info); +} + +type_init(vga_mmio_register_types) diff --git a/include/hw/display/vga.h b/include/hw/display/vga.h index c16a5c26da..98b2e560f9 100644 --- a/include/hw/display/vga.h +++ b/include/hw/display/vga.h @@ -24,6 +24,8 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; +#define TYPE_VGA_MMIO "vga-mmio" + int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, int it_shift, MemoryRegion *address_space); From 7336c94434b2f697a375126d0df8549777a58148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 6 Dec 2021 23:45:28 +0100 Subject: [PATCH 13/20] hw/mips/jazz: Inline vga_mmio_init() and remove it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vga_mmio_init() is used only one time and not very helpful, inline and remove it. Reviewed-by: BALATON Zoltan Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Message-Id: <20211206224528.563588-5-f4bug@amsat.org> Signed-off-by: Gerd Hoffmann --- hw/display/vga-mmio.c | 19 ------------------- hw/mips/jazz.c | 9 ++++++++- include/hw/display/vga.h | 5 ----- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/hw/display/vga-mmio.c b/hw/display/vga-mmio.c index 10bde32af5..4969368081 100644 --- a/hw/display/vga-mmio.c +++ b/hw/display/vga-mmio.c @@ -24,7 +24,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "hw/display/vga.h" #include "hw/sysbus.h" #include "hw/display/vga.h" #include "hw/qdev-properties.h" @@ -85,24 +84,6 @@ static void vga_mmio_reset(DeviceState *dev) vga_common_reset(&s->vga); } -int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, - int it_shift, MemoryRegion *address_space) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new(TYPE_VGA_MMIO); - qdev_prop_set_uint8(dev, "it_shift", it_shift); - s = SYS_BUS_DEVICE(dev); - sysbus_realize_and_unref(s, &error_fatal); - - sysbus_mmio_map(s, 0, ctrl_base); - sysbus_mmio_map(s, 1, vram_base + 0x000a0000); - sysbus_mmio_map(s, 2, VBE_DISPI_LFB_PHYSICAL_ADDRESS); - - return 0; -} - static void vga_mmio_realizefn(DeviceState *dev, Error **errp) { VGAMmioState *s = VGA_MMIO(dev); diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index 8f345afd13..44f0d48bfd 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -43,6 +43,7 @@ #include "hw/rtc/mc146818rtc.h" #include "hw/timer/i8254.h" #include "hw/display/vga.h" +#include "hw/display/bochs-vbe.h" #include "hw/audio/pcspk.h" #include "hw/input/i8042.h" #include "hw/sysbus.h" @@ -274,7 +275,13 @@ static void mips_jazz_init(MachineState *machine, } break; case JAZZ_PICA61: - vga_mmio_init(0x40000000, 0x60000000, 0, get_system_memory()); + dev = qdev_new(TYPE_VGA_MMIO); + qdev_prop_set_uint8(dev, "it_shift", 0); + sysbus = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(sysbus, &error_fatal); + sysbus_mmio_map(sysbus, 0, 0x60000000); + sysbus_mmio_map(sysbus, 1, 0x400a0000); + sysbus_mmio_map(sysbus, 2, VBE_DISPI_LFB_PHYSICAL_ADDRESS); break; default: break; diff --git a/include/hw/display/vga.h b/include/hw/display/vga.h index 98b2e560f9..a79aa2909b 100644 --- a/include/hw/display/vga.h +++ b/include/hw/display/vga.h @@ -9,8 +9,6 @@ #ifndef QEMU_HW_DISPLAY_VGA_H #define QEMU_HW_DISPLAY_VGA_H -#include "exec/hwaddr.h" - /* * modules can reference this symbol to avoid being loaded * into system emulators without vga support @@ -26,7 +24,4 @@ extern enum vga_retrace_method vga_retrace_method; #define TYPE_VGA_MMIO "vga-mmio" -int vga_mmio_init(hwaddr vram_base, hwaddr ctrl_base, - int it_shift, MemoryRegion *address_space); - #endif From de72c4b7cdf6ec18bfe9fe714aa96e48db6fd895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 29 Nov 2021 14:05:08 +0000 Subject: [PATCH 14/20] edid: set default resolution to 1280x800 (WXGA) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently QEMU defaults to a resolution of 1024x768 when exposing EDID info to the guest OS. The EDID default info is important as this will influence what resolution many guest OS will configure the screen with on boot. It can also potentially influence what resolution the firmware will configure the screen with, though until very recently EDK2 would not handle EDID info. One important thing to bear in mind is that the default graphics card driver provided by Windows will leave the display set to whatever resolution was enabled by the firmware on boot. Even if sufficient VRAM is available, the resolution can't be changed without installing new drivers. IOW, the default resolution choice is quite important for usability of Windows. Modern real world monitor hardware for desktop/laptop has supported resolutions higher than 1024x768 for a long time now, perhaps as long as 15+ years. There are quite a wide variety of native resolutions in use today, however, and in wide screen form factors the height may not be all that tall. None the less, it is considered that there is scope for making the QEMU default resolution slightly larger. In considering what possible new default could be suitable, choices considered were 1280x720 (720p), 1280x800 (WXGA) and 1280x1024 (SXGA). In many ways, vertical space is the most important, and so 720p was discarded due to loosing vertical space, despite being 25% wider. The SXGA resolution would be good, but when taking into account window titlebars/toolbars and window manager desktop UI, this might be a little too tall for some users to fit the guest on their physical montior. This patch thus suggests a modest change to 1280x800 (WXGA). This only consumes 1 MB per colour channel, allowing double buffered framebuffer in 8 MB of VRAM. Width wise this is 25% larger than QEMU's current default, but height wise this only adds 5%, so the difference isn't massive on the QEMU side. Overall there doesn't appear to be a compelling reason to stick with 1024x768 resolution. Signed-off-by: Daniel P. Berrangé Reviewed-by: Gerd Hoffmann Message-Id: <20211129140508.1745130-1-berrange@redhat.com> Signed-off-by: Gerd Hoffmann --- hw/display/edid-generate.c | 4 ++-- include/hw/virtio/virtio-gpu.h | 4 ++-- qemu-edid.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/display/edid-generate.c b/hw/display/edid-generate.c index f2b874d5e3..6f5ac6a38a 100644 --- a/hw/display/edid-generate.c +++ b/hw/display/edid-generate.c @@ -401,10 +401,10 @@ void qemu_edid_generate(uint8_t *edid, size_t size, info->name = "QEMU Monitor"; } if (!info->prefx) { - info->prefx = 1024; + info->prefx = 1280; } if (!info->prefy) { - info->prefy = 768; + info->prefy = 800; } if (info->prefx >= 4096 || info->prefy >= 4096) { large_screen = 1; diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index acfba7c76c..2179b75703 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -147,8 +147,8 @@ struct VirtIOGPUBaseClass { DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \ DEFINE_PROP_BIT("edid", _state, _conf.flags, \ VIRTIO_GPU_FLAG_EDID_ENABLED, true), \ - DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \ - DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768) + DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \ + DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800) typedef struct VGPUDMABuf { QemuDmaBuf buf; diff --git a/qemu-edid.c b/qemu-edid.c index c3a9fba10d..20c958d9c7 100644 --- a/qemu-edid.c +++ b/qemu-edid.c @@ -10,8 +10,8 @@ #include "hw/display/edid.h" static qemu_edid_info info = { - .prefx = 1024, - .prefy = 768, + .prefx = 1280, + .prefy = 800, }; static void usage(FILE *out) From f0602b709985b28bc8ce572d6c517d9c26669735 Mon Sep 17 00:00:00 2001 From: Satyeshwar Singh Date: Tue, 16 Nov 2021 14:11:03 -0800 Subject: [PATCH 15/20] edid: Added support for 4k@60 Hz monitor Previously, the large modes (>1080p) that were generated by Qemu in its EDID were all 50 Hz. If we provide them to a Guest OS and the user selects one of these modes, then the OS by default only gets 50 FPS. This is especially true for Windows OS. With this patch, we are now exposing a 3840x2160@60 Hz which will allow the guest OS to get 60 FPS. Cc: Gerd Hoffmann Signed-off-by: Satyeshwar Singh Message-Id: <20211116221103.27128-1-dongwon.kim@intel.com> Signed-off-by: Gerd Hoffmann --- hw/display/edid-generate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/display/edid-generate.c b/hw/display/edid-generate.c index 6f5ac6a38a..bccf32af69 100644 --- a/hw/display/edid-generate.c +++ b/hw/display/edid-generate.c @@ -24,6 +24,9 @@ static const struct edid_mode { { .xres = 2048, .yres = 1152 }, { .xres = 1920, .yres = 1080, .dta = 31 }, + /* dea/dta extension timings (all @ 60 Hz) */ + { .xres = 3840, .yres = 2160, .dta = 97 }, + /* additional standard timings 3 (all @ 60Hz) */ { .xres = 1920, .yres = 1200, .xtra3 = 10, .bit = 0 }, { .xres = 1600, .yres = 1200, .xtra3 = 9, .bit = 2 }, From 64ebbb7d62cfe3e435b1ce87f839398b75bbc35a Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Sat, 8 Jan 2022 16:39:43 +0100 Subject: [PATCH 16/20] ps2: Initial horizontal scroll support This change adds support for horizontal scroll to ps/2 mouse device code. The code is implemented to match the logic of linux kernel which is used as a reference. Signed-off-by: Dmitry Petrov Message-Id: <20220108153947.171861-2-dpetroff@gmail.com> Signed-off-by: Gerd Hoffmann --- hw/input/ps2.c | 57 +++++++++++++++++++++++++++++++++++++++++++------- qapi/ui.json | 2 +- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 9376a8f4ce..6236711e1b 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -123,6 +123,7 @@ typedef struct { int mouse_dx; /* current values, needed for 'poll' mode */ int mouse_dy; int mouse_dz; + int mouse_dw; uint8_t mouse_buttons; } PS2MouseState; @@ -715,7 +716,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s) /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */ const int needed = s->mouse_type ? 4 : 3; unsigned int b; - int dx1, dy1, dz1; + int dx1, dy1, dz1, dw1; if (PS2_QUEUE_SIZE - s->common.queue.count < needed) { return 0; @@ -724,6 +725,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s) dx1 = s->mouse_dx; dy1 = s->mouse_dy; dz1 = s->mouse_dz; + dw1 = s->mouse_dw; /* XXX: increase range to 8 bits ? */ if (dx1 > 127) dx1 = 127; @@ -740,6 +742,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s) /* extra byte for IMPS/2 or IMEX */ switch(s->mouse_type) { default: + /* Just ignore the wheels if not supported */ + s->mouse_dz = 0; + s->mouse_dw = 0; break; case 3: if (dz1 > 127) @@ -747,13 +752,41 @@ static int ps2_mouse_send_packet(PS2MouseState *s) else if (dz1 < -127) dz1 = -127; ps2_queue_noirq(&s->common, dz1 & 0xff); + s->mouse_dz -= dz1; + s->mouse_dw = 0; break; case 4: - if (dz1 > 7) - dz1 = 7; - else if (dz1 < -7) - dz1 = -7; - b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); + /* + * This matches what the Linux kernel expects for exps/2 in + * drivers/input/mouse/psmouse-base.c. Note, if you happen to + * press/release the 4th or 5th buttons at the same moment as a + * horizontal wheel scroll, those button presses will get lost. I'm not + * sure what to do about that, since by this point we don't know + * whether those buttons actually changed state. + */ + if (dw1 != 0) { + if (dw1 > 31) { + dw1 = 31; + } else if (dw1 < -31) { + dw1 = -31; + } + + /* + * linux kernel expects first 6 bits to represent the value + * for horizontal scroll + */ + b = (dw1 & 0x3f) | 0x40; + s->mouse_dw -= dw1; + } else { + if (dz1 > 7) { + dz1 = 7; + } else if (dz1 < -7) { + dz1 = -7; + } + + b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); + s->mouse_dz -= dz1; + } ps2_queue_noirq(&s->common, b); break; } @@ -764,7 +797,6 @@ static int ps2_mouse_send_packet(PS2MouseState *s) /* update deltas */ s->mouse_dx -= dx1; s->mouse_dy -= dy1; - s->mouse_dz -= dz1; return 1; } @@ -806,6 +838,12 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { s->mouse_dz++; } + + if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) { + s->mouse_dw--; + } else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) { + s->mouse_dw++; + } } else { s->mouse_buttons &= ~bmap[btn->button]; } @@ -833,8 +871,10 @@ static void ps2_mouse_sync(DeviceState *dev) /* if not remote, send event. Multiple events are sent if too big deltas */ while (ps2_mouse_send_packet(s)) { - if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) + if (s->mouse_dx == 0 && s->mouse_dy == 0 + && s->mouse_dz == 0 && s->mouse_dw == 0) { break; + } } } } @@ -1036,6 +1076,7 @@ static void ps2_mouse_reset(void *opaque) s->mouse_dx = 0; s->mouse_dy = 0; s->mouse_dz = 0; + s->mouse_dw = 0; s->mouse_buttons = 0; } diff --git a/qapi/ui.json b/qapi/ui.json index 2b4371da37..9354f4c467 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -905,7 +905,7 @@ ## { 'enum' : 'InputButton', 'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side', - 'extra' ] } + 'extra', 'wheel-left', 'wheel-right' ] } ## # @InputAxis: From d70a5de441d6a4634fae39253f26ef3f39f8622a Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Sat, 8 Jan 2022 16:39:44 +0100 Subject: [PATCH 17/20] ui/cocoa: pass horizontal scroll information to the device code Signed-off-by: Dmitry Petrov Message-Id: <20220108153947.171861-3-dpetroff@gmail.com> Signed-off-by: Gerd Hoffmann --- ui/cocoa.m | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 69745c483b..ac18e14ce0 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -970,21 +970,27 @@ QemuCocoaView *cocoaView; */ /* - * When deltaY is zero, it means that this scrolling event was - * either horizontal, or so fine that it only appears in - * scrollingDeltaY. So we drop the event. + * We shouldn't have got a scroll event when deltaY and delta Y + * are zero, hence no harm in dropping the event */ - if ([event deltaY] != 0) { + if ([event deltaY] != 0 || [event deltaX] != 0) { /* Determine if this is a scroll up or scroll down event */ - buttons = ([event deltaY] > 0) ? + if ([event deltaY] != 0) { + buttons = ([event deltaY] > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; + } else if ([event deltaX] != 0) { + buttons = ([event deltaX] > 0) ? + INPUT_BUTTON_WHEEL_LEFT : INPUT_BUTTON_WHEEL_RIGHT; + } + qemu_input_queue_btn(dcl.con, buttons, true); qemu_input_event_sync(); qemu_input_queue_btn(dcl.con, buttons, false); qemu_input_event_sync(); } + /* - * Since deltaY also reports scroll wheel events we prevent mouse + * Since deltaX/deltaY also report scroll wheel events we prevent mouse * movement code from executing. */ mouse_event = false; From 13cb360f6e60fca63b90ec0ff96f6135d937a1af Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Sat, 8 Jan 2022 16:39:45 +0100 Subject: [PATCH 18/20] ui/gtk: pass horizontal scroll information to the device code Signed-off-by: Dmitry Petrov Message-Id: <20220108153947.171861-4-dpetroff@gmail.com> Signed-off-by: Gerd Hoffmann --- ui/gtk.c | 54 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/ui/gtk.c b/ui/gtk.c index 6a1f65d518..a8567b9ddc 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -968,33 +968,63 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll, void *opaque) { VirtualConsole *vc = opaque; - InputButton btn; + InputButton btn_vertical; + InputButton btn_horizontal; + bool has_vertical = false; + bool has_horizontal = false; if (scroll->direction == GDK_SCROLL_UP) { - btn = INPUT_BUTTON_WHEEL_UP; + btn_vertical = INPUT_BUTTON_WHEEL_UP; + has_vertical = true; } else if (scroll->direction == GDK_SCROLL_DOWN) { - btn = INPUT_BUTTON_WHEEL_DOWN; + btn_vertical = INPUT_BUTTON_WHEEL_DOWN; + has_vertical = true; + } else if (scroll->direction == GDK_SCROLL_LEFT) { + btn_horizontal = INPUT_BUTTON_WHEEL_LEFT; + has_horizontal = true; + } else if (scroll->direction == GDK_SCROLL_RIGHT) { + btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT; + has_horizontal = true; } else if (scroll->direction == GDK_SCROLL_SMOOTH) { gdouble delta_x, delta_y; if (!gdk_event_get_scroll_deltas((GdkEvent *)scroll, &delta_x, &delta_y)) { return TRUE; } - if (delta_y == 0) { - return TRUE; - } else if (delta_y > 0) { - btn = INPUT_BUTTON_WHEEL_DOWN; + + if (delta_y > 0) { + btn_vertical = INPUT_BUTTON_WHEEL_DOWN; + has_vertical = true; + } else if (delta_y < 0) { + btn_vertical = INPUT_BUTTON_WHEEL_UP; + has_vertical = true; + } else if (delta_x > 0) { + btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT; + has_horizontal = true; + } else if (delta_x < 0) { + btn_horizontal = INPUT_BUTTON_WHEEL_LEFT; + has_horizontal = true; } else { - btn = INPUT_BUTTON_WHEEL_UP; + return TRUE; } } else { return TRUE; } - qemu_input_queue_btn(vc->gfx.dcl.con, btn, true); - qemu_input_event_sync(); - qemu_input_queue_btn(vc->gfx.dcl.con, btn, false); - qemu_input_event_sync(); + if (has_vertical) { + qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, true); + qemu_input_event_sync(); + qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, false); + qemu_input_event_sync(); + } + + if (has_horizontal) { + qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, true); + qemu_input_event_sync(); + qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, false); + qemu_input_event_sync(); + } + return TRUE; } From ed80f503a1cd31ee547bb44f7e13ea313733e8cc Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Sat, 8 Jan 2022 16:39:46 +0100 Subject: [PATCH 19/20] ui/sdl2: pass horizontal scroll information to the device code Signed-off-by: Dmitry Petrov Message-Id: <20220108153947.171861-5-dpetroff@gmail.com> Signed-off-by: Gerd Hoffmann --- ui/sdl2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/sdl2.c b/ui/sdl2.c index 0bd30504cf..46a252d7d9 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -33,6 +33,7 @@ #include "sysemu/runstate-action.h" #include "sysemu/sysemu.h" #include "ui/win32-kbd-hook.h" +#include "qemu/log.h" static int sdl2_num_outputs; static struct sdl2_console *sdl2_console; @@ -535,6 +536,10 @@ static void handle_mousewheel(SDL_Event *ev) btn = INPUT_BUTTON_WHEEL_UP; } else if (wev->y < 0) { btn = INPUT_BUTTON_WHEEL_DOWN; + } else if (wev->x < 0) { + btn = INPUT_BUTTON_WHEEL_RIGHT; + } else if (wev->x > 0) { + btn = INPUT_BUTTON_WHEEL_LEFT; } else { return; } From 17f6315ef883a142b6a41a491b63a6554e784a5c Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Sat, 8 Jan 2022 16:39:47 +0100 Subject: [PATCH 20/20] ui/input-legacy: pass horizontal scroll information This code seems to be used by vmport hack, passing these values allows to implement horizontal scroll support even when using vmport. In case it's not supported horizontal scroll will act as a vertical one. Signed-off-by: Dmitry Petrov Message-Id: <20220108153947.171861-6-dpetroff@gmail.com> Signed-off-by: Gerd Hoffmann --- ui/input-legacy.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 9fc78a639b..46ea74e44d 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "qapi/qapi-commands-ui.h" #include "ui/console.h" #include "keymaps.h" @@ -179,6 +180,20 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, 1, s->buttons); } + if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) { + s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, + s->axis[INPUT_AXIS_X], + s->axis[INPUT_AXIS_Y], + -2, + s->buttons); + } + if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) { + s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, + s->axis[INPUT_AXIS_X], + s->axis[INPUT_AXIS_Y], + 2, + s->buttons); + } break; case INPUT_EVENT_KIND_ABS: move = evt->u.abs.data;