qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PULL 00/25] Kraxel 20220926 patches
@ 2022-09-26  9:54 Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 01/25] ui/console: Get tab completion working again in the SDL monitor vc Gerd Hoffmann
                   ` (25 more replies)
  0 siblings, 26 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

The following changes since commit 6160d8ff81fb9fba70f5dad88d43ffd0fa44984c:

  Merge tag 'edgar/xilinx-next-2022-09-21.for-upstream' of https://github.com/edgarigl/qemu into staging (2022-09-22 13:24:28 -0400)

are available in the Git repository at:

  https://gitlab.com/kraxel/qemu.git tags/kraxel-20220926-pull-request

for you to fetch changes up to f76582f0a282ec95d6dc9c7cd1903c997fd060a6:

  virtio-gpu: update scanout if there is any area covered by the rect (2022-09-23 14:38:28 +0200)

----------------------------------------------------------------
usb: make usbnet work with xhci.
audio: add sndio backend.
misc bugfixes for console, xhci, ohci, audio, ati-vga and virtio-gpu.

----------------------------------------------------------------

Akihiko Odaki (3):
  ui/cocoa: Run qemu_init in the main thread
  Revert "main-loop: Disable block backend global state assertion on
    Cocoa"
  meson: Allow to enable gtk and sdl while cocoa is enabled

Alexandre Ratchov (1):
  audio: Add sndio backend

Cal Peake (1):
  ui/console: Get tab completion working again in the SDL monitor vc

Dongwon Kim (1):
  virtio-gpu: update scanout if there is any area covered by the rect

Gerd Hoffmann (2):
  usb/msd: move usb_msd_packet_complete()
  usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert

Marc-André Lureau (5):
  ui: add some vdagent related traces
  ui/clipboard: fix serial priority
  ui/vdagent: always reset the clipboard serial on caps
  ui/clipboard: reset the serial state on reset
  ui/vdagent: fix serial reset of guest agent

Michael Brown (4):
  usbnet: Add missing usb_wakeup() call in usbnet_receive()
  usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request
  usbnet: Detect short packets as sent by the xHCI controller
  usbnet: Report link-up via interrupt endpoint in CDC-ECM mode

Philippe Mathieu-Daudé (1):
  hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638)

Qiang Liu (3):
  hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is
    zero
  hcd-ohci: Fix inconsistency when resetting ohci root hubs
  hcd-xhci: drop operation with secondary stream arrays enabled

Thomas Huth (1):
  hw/usb/hcd-xhci: Check whether DMA accesses fail

Volker Rümelin (3):
  ui/console: fix three double frees in png_save()
  Revert "audio: Log context for audio bug"
  audio: remove abort() in audio_bug()

 meson_options.txt             |   4 +-
 audio/audio_template.h        |  29 +-
 include/hw/usb/msd.h          |   1 +
 include/qemu-main.h           |   3 +-
 include/qemu/main-loop.h      |  13 -
 include/sysemu/sysemu.h       |   2 +-
 include/ui/console.h          |   1 +
 audio/audio.c                 |  25 +-
 audio/sndioaudio.c            | 565 ++++++++++++++++++++++++++++++++++
 hw/display/ati_2d.c           |   6 +-
 hw/display/virtio-gpu.c       |   7 +-
 hw/usb/dev-network.c          |  38 ++-
 hw/usb/dev-storage.c          |  56 +++-
 hw/usb/hcd-ohci.c             |  12 +-
 hw/usb/hcd-xhci.c             |  68 +++-
 softmmu/main.c                |  10 +-
 softmmu/vl.c                  |   2 +-
 tests/qtest/fuzz/fuzz.c       |   2 +-
 ui/clipboard.c                |  18 +-
 ui/console.c                  |   6 +-
 ui/vdagent.c                  |  13 +-
 MAINTAINERS                   |   7 +
 audio/meson.build             |   1 +
 docs/devel/fuzzing.rst        |   4 +-
 hw/usb/trace-events           |   1 +
 meson.build                   |  19 +-
 qapi/audio.json               |  25 +-
 qemu-options.hx               |  16 +
 scripts/meson-buildoptions.sh |   7 +-
 ui/cocoa.m                    | 144 +++------
 ui/trace-events               |   5 +
 31 files changed, 904 insertions(+), 206 deletions(-)
 create mode 100644 audio/sndioaudio.c

-- 
2.37.3



^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PULL 01/25] ui/console: Get tab completion working again in the SDL monitor vc
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 02/25] ui/cocoa: Run qemu_init in the main thread Gerd Hoffmann
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Cal Peake

From: Cal Peake <cp@absolutedigital.net>

Define a QEMU special key constant for the tab key and add an entry for
it in the qcode_to_keysym table. This allows tab completion to work again
in the SDL monitor virtual console, which has been broken ever since the
migration from SDL1 to SDL2.

Signed-off-by: Cal Peake <cp@absolutedigital.net>
Message-Id: <7054816e-99c-7e2-6737-7cf98cc56e2@absolutedigital.net>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h | 1 +
 ui/console.c         | 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/ui/console.h b/include/ui/console.h
index c0520c694c23..e400ee9fa74b 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -70,6 +70,7 @@ void hmp_mouse_set(Monitor *mon, const QDict *qdict);
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
 #define QEMU_KEY_ESC1(c) ((c) | 0xe100)
+#define QEMU_KEY_TAB        0x0009
 #define QEMU_KEY_BACKSPACE  0x007f
 #define QEMU_KEY_UP         QEMU_KEY_ESC1('A')
 #define QEMU_KEY_DOWN       QEMU_KEY_ESC1('B')
diff --git a/ui/console.c b/ui/console.c
index 765892f84f1c..243f2f6e64ae 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1368,6 +1368,7 @@ static const int qcode_to_keysym[Q_KEY_CODE__MAX] = {
     [Q_KEY_CODE_PGUP]   = QEMU_KEY_PAGEUP,
     [Q_KEY_CODE_PGDN]   = QEMU_KEY_PAGEDOWN,
     [Q_KEY_CODE_DELETE] = QEMU_KEY_DELETE,
+    [Q_KEY_CODE_TAB]    = QEMU_KEY_TAB,
     [Q_KEY_CODE_BACKSPACE] = QEMU_KEY_BACKSPACE,
 };
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 02/25] ui/cocoa: Run qemu_init in the main thread
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 01/25] ui/console: Get tab completion working again in the SDL monitor vc Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 03/25] Revert "main-loop: Disable block backend global state assertion on Cocoa" Gerd Hoffmann
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

From: Akihiko Odaki <akihiko.odaki@gmail.com>

This work is based on:
https://patchew.org/QEMU/20220317125534.38706-1-philippe.mathieu.daude@gmail.com/

Simplify the initialization dance by running qemu_init() in the main
thread before the Cocoa event loop starts. The secondary thread only
runs only qemu_main_loop() and qemu_cleanup().

This fixes a case where addRemovableDevicesMenuItems() calls
qmp_query_block() while expecting the main thread to still hold
the BQL.

Overriding the code after calling qemu_init() is done by dynamically
replacing a function pointer variable, qemu_main when initializing
ui/cocoa, which unifies the static implementation of main() for
builds with ui/cocoa and ones without ui/cocoa.

Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Message-Id: <20220819132756.74641-2-akihiko.odaki@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/qemu-main.h     |   3 +-
 include/sysemu/sysemu.h |   2 +-
 softmmu/main.c          |  10 +--
 softmmu/vl.c            |   2 +-
 tests/qtest/fuzz/fuzz.c |   2 +-
 docs/devel/fuzzing.rst  |   4 +-
 ui/cocoa.m              | 144 ++++++++++++++--------------------------
 7 files changed, 62 insertions(+), 105 deletions(-)

diff --git a/include/qemu-main.h b/include/qemu-main.h
index 6a3e90d0ad59..940960a7dbcb 100644
--- a/include/qemu-main.h
+++ b/include/qemu-main.h
@@ -5,6 +5,7 @@
 #ifndef QEMU_MAIN_H
 #define QEMU_MAIN_H
 
-int qemu_main(int argc, char **argv, char **envp);
+int qemu_default_main(void);
+extern int (*qemu_main)(void);
 
 #endif /* QEMU_MAIN_H */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 31aa45160be8..6a7a31e64dea 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -102,7 +102,7 @@ void qemu_boot_set(const char *boot_order, Error **errp);
 
 bool defaults_enabled(void);
 
-void qemu_init(int argc, char **argv, char **envp);
+void qemu_init(int argc, char **argv);
 int qemu_main_loop(void);
 void qemu_cleanup(void);
 
diff --git a/softmmu/main.c b/softmmu/main.c
index 1b675a8c036f..694388bd7f7f 100644
--- a/softmmu/main.c
+++ b/softmmu/main.c
@@ -30,20 +30,20 @@
 #include <SDL.h>
 #endif
 
-int qemu_main(int argc, char **argv, char **envp)
+int qemu_default_main(void)
 {
     int status;
 
-    qemu_init(argc, argv, envp);
     status = qemu_main_loop();
     qemu_cleanup();
 
     return status;
 }
 
-#ifndef CONFIG_COCOA
+int (*qemu_main)(void) = qemu_default_main;
+
 int main(int argc, char **argv)
 {
-    return qemu_main(argc, argv, NULL);
+    qemu_init(argc, argv);
+    return qemu_main();
 }
-#endif
diff --git a/softmmu/vl.c b/softmmu/vl.c
index e62b9cc35d75..9abadcc15051 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2605,7 +2605,7 @@ void qmp_x_exit_preconfig(Error **errp)
     }
 }
 
-void qemu_init(int argc, char **argv, char **envp)
+void qemu_init(int argc, char **argv)
 {
     QemuOpts *opts;
     QemuOpts *icount_opts = NULL, *accel_opts = NULL;
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
index 2b3bc1fb9df5..eb7520544b80 100644
--- a/tests/qtest/fuzz/fuzz.c
+++ b/tests/qtest/fuzz/fuzz.c
@@ -218,7 +218,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
         g_free(pretty_cmd_line);
     }
 
-    qemu_init(result.we_wordc, result.we_wordv, NULL);
+    qemu_init(result.we_wordc, result.we_wordv);
 
     /* re-enable the rcu atfork, which was previously disabled in qemu_init */
     rcu_enable_atfork();
diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
index 784ecb99e667..715330c85613 100644
--- a/docs/devel/fuzzing.rst
+++ b/docs/devel/fuzzing.rst
@@ -287,8 +287,8 @@ select the fuzz target. Then, the qtest client is initialized. If the target
 requires qos, qgraph is set up and the QOM/LIBQOS modules are initialized.
 Then the QGraph is walked and the QEMU cmd_line is determined and saved.
 
-After this, the ``vl.c:qemu_main`` is called to set up the guest. There are
-target-specific hooks that can be called before and after qemu_main, for
+After this, the ``vl.c:main`` is called to set up the guest. There are
+target-specific hooks that can be called before and after main, for
 additional setup(e.g. PCI setup, or VM snapshotting).
 
 ``LLVMFuzzerTestOneInput``: Uses qtest/qos functions to act based on the fuzz
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 5a8bd5dd84e0..660d3e093569 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -100,13 +100,9 @@ static void cocoa_switch(DisplayChangeListener *dcl,
 static int left_command_key_enabled = 1;
 static bool swap_opt_cmd;
 
-static int gArgc;
-static char **gArgv;
 static bool stretch_video;
 static NSTextField *pauseLabel;
 
-static QemuSemaphore display_init_sem;
-static QemuSemaphore app_started_sem;
 static bool allow_events;
 
 static NSInteger cbchangecount = -1;
@@ -597,7 +593,7 @@ - (void) updateUIInfo
         /*
          * Don't try to tell QEMU about UI information in the application
          * startup phase -- we haven't yet registered dcl with the QEMU UI
-         * layer, and also trying to take the iothread lock would deadlock.
+         * layer.
          * When cocoa_display_init() does register the dcl, the UI layer
          * will call cocoa_switch(), which will call updateUIInfo, so
          * we don't lose any information here.
@@ -790,16 +786,6 @@ - (void) handleMonitorInput:(NSEvent *)event
 
 - (bool) handleEvent:(NSEvent *)event
 {
-    if(!allow_events) {
-        /*
-         * Just let OSX have all events that arrive before
-         * applicationDidFinishLaunching.
-         * This avoids a deadlock on the iothread lock, which cocoa_display_init()
-         * will not drop until after the app_started_sem is posted. (In theory
-         * there should not be any such events, but OSX Catalina now emits some.)
-         */
-        return false;
-    }
     return bool_with_iothread_lock(^{
         return [self handleEventLocked:event];
     });
@@ -1287,8 +1273,6 @@ - (void)applicationDidFinishLaunching: (NSNotification *) note
 {
     COCOA_DEBUG("QemuCocoaAppController: applicationDidFinishLaunching\n");
     allow_events = true;
-    /* Tell cocoa_display_init to proceed */
-    qemu_sem_post(&app_started_sem);
 }
 
 - (void)applicationWillTerminate:(NSNotification *)aNotification
@@ -1919,92 +1903,45 @@ static void cocoa_clipboard_request(QemuClipboardInfo *info,
 /*
  * The startup process for the OSX/Cocoa UI is complicated, because
  * OSX insists that the UI runs on the initial main thread, and so we
- * need to start a second thread which runs the vl.c qemu_main():
- *
- * Initial thread:                    2nd thread:
+ * need to start a second thread which runs the qemu_default_main():
  * in main():
- *  create qemu-main thread
- *  wait on display_init semaphore
- *                                    call qemu_main()
- *                                    ...
- *                                    in cocoa_display_init():
- *                                     post the display_init semaphore
- *                                     wait on app_started semaphore
- *  create application, menus, etc
- *  enter OSX run loop
- * in applicationDidFinishLaunching:
- *  post app_started semaphore
- *                                     tell main thread to fullscreen if needed
- *                                    [...]
- *                                    run qemu main-loop
- *
- * We do this in two stages so that we don't do the creation of the
- * GUI application menus and so on for command line options like --help
- * where we want to just print text to stdout and exit immediately.
+ *  in cocoa_display_init():
+ *   assign cocoa_main to qemu_main
+ *   create application, menus, etc
+ *  in cocoa_main():
+ *   create qemu-main thread
+ *   enter OSX run loop
  */
 
 static void *call_qemu_main(void *opaque)
 {
     int status;
 
-    COCOA_DEBUG("Second thread: calling qemu_main()\n");
-    status = qemu_main(gArgc, gArgv, *_NSGetEnviron());
-    COCOA_DEBUG("Second thread: qemu_main() returned, exiting\n");
+    COCOA_DEBUG("Second thread: calling qemu_default_main()\n");
+    qemu_mutex_lock_iothread();
+    status = qemu_default_main();
+    qemu_mutex_unlock_iothread();
+    COCOA_DEBUG("Second thread: qemu_default_main() returned, exiting\n");
     [cbowner release];
     exit(status);
 }
 
-int main (int argc, char **argv) {
+static int cocoa_main()
+{
     QemuThread thread;
 
-    COCOA_DEBUG("Entered main()\n");
-    gArgc = argc;
-    gArgv = argv;
-
-    qemu_sem_init(&display_init_sem, 0);
-    qemu_sem_init(&app_started_sem, 0);
+    COCOA_DEBUG("Entered %s()\n", __func__);
 
+    qemu_mutex_unlock_iothread();
     qemu_thread_create(&thread, "qemu_main", call_qemu_main,
                        NULL, QEMU_THREAD_DETACHED);
 
-    COCOA_DEBUG("Main thread: waiting for display_init_sem\n");
-    qemu_sem_wait(&display_init_sem);
-    COCOA_DEBUG("Main thread: initializing app\n");
-
-    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
-    // Pull this console process up to being a fully-fledged graphical
-    // app with a menubar and Dock icon
-    ProcessSerialNumber psn = { 0, kCurrentProcess };
-    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
-
-    [QemuApplication sharedApplication];
-
-    create_initial_menus();
-
-    /*
-     * Create the menu entries which depend on QEMU state (for consoles
-     * and removeable devices). These make calls back into QEMU functions,
-     * which is OK because at this point we know that the second thread
-     * holds the iothread lock and is synchronously waiting for us to
-     * finish.
-     */
-    add_console_menu_entries();
-    addRemovableDevicesMenuItems();
-
-    // Create an Application controller
-    QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init];
-    [NSApp setDelegate:appController];
-
     // Start the main event loop
     COCOA_DEBUG("Main thread: entering OSX run loop\n");
     [NSApp run];
-    COCOA_DEBUG("Main thread: left OSX run loop, exiting\n");
+    COCOA_DEBUG("Main thread: left OSX run loop, which should never happen\n");
 
-    [appController release];
-    [pool release];
-
-    return 0;
+    abort();
 }
 
 
@@ -2083,25 +2020,42 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
 
 static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
 {
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
     COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
 
-    /* Tell main thread to go ahead and create the app and enter the run loop */
-    qemu_sem_post(&display_init_sem);
-    qemu_sem_wait(&app_started_sem);
-    COCOA_DEBUG("cocoa_display_init: app start completed\n");
+    qemu_main = cocoa_main;
+
+    // Pull this console process up to being a fully-fledged graphical
+    // app with a menubar and Dock icon
+    ProcessSerialNumber psn = { 0, kCurrentProcess };
+    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+
+    [QemuApplication sharedApplication];
+
+    create_initial_menus();
+
+    /*
+     * Create the menu entries which depend on QEMU state (for consoles
+     * and removeable devices). These make calls back into QEMU functions,
+     * which is OK because at this point we know that the second thread
+     * holds the iothread lock and is synchronously waiting for us to
+     * finish.
+     */
+    add_console_menu_entries();
+    addRemovableDevicesMenuItems();
+
+    // Create an Application controller
+    QemuCocoaAppController *controller = [[QemuCocoaAppController alloc] init];
+    [NSApp setDelegate:controller];
 
-    QemuCocoaAppController *controller = (QemuCocoaAppController *)[[NSApplication sharedApplication] delegate];
     /* if fullscreen mode is to be used */
     if (opts->has_full_screen && opts->full_screen) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [NSApp activateIgnoringOtherApps: YES];
-            [controller toggleFullScreen: nil];
-        });
+        [NSApp activateIgnoringOtherApps: YES];
+        [controller toggleFullScreen: nil];
     }
     if (opts->u.cocoa.has_full_grab && opts->u.cocoa.full_grab) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [controller setFullGrab: nil];
-        });
+        [controller setFullGrab: nil];
     }
 
     if (opts->has_show_cursor && opts->show_cursor) {
@@ -2121,6 +2075,8 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
     qemu_event_init(&cbevent, false);
     cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
     qemu_clipboard_peer_register(&cbpeer);
+
+    [pool release];
 }
 
 static QemuDisplay qemu_display_cocoa = {
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 03/25] Revert "main-loop: Disable block backend global state assertion on Cocoa"
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 01/25] ui/console: Get tab completion working again in the SDL monitor vc Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 02/25] ui/cocoa: Run qemu_init in the main thread Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 04/25] meson: Allow to enable gtk and sdl while cocoa is enabled Gerd Hoffmann
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Emanuele Giuseppe Esposito

From: Akihiko Odaki <akihiko.odaki@gmail.com>

This reverts commit 47281859f66bdab1974fb122cab2cbb4a1c9af7f.

Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20220819132756.74641-3-akihiko.odaki@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/qemu/main-loop.h | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index c50d1b7e3ab6..aac707d073a1 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -284,23 +284,10 @@ bool qemu_in_main_thread(void);
  * Please refer to include/block/block-global-state.h for more
  * information about GS API.
  */
-#ifdef CONFIG_COCOA
-/*
- * When using the Cocoa UI, addRemovableDevicesMenuItems() is called from
- * a thread different from the QEMU main thread and can not take the BQL,
- * triggering this assertions in the block layer (commit 0439c5a462).
- * As the Cocoa fix is not trivial, disable this assertion for the v7.0.0
- * release (when using Cocoa); we will restore it immediately after the
- * release.
- * This issue is tracked as https://gitlab.com/qemu-project/qemu/-/issues/926
- */
-#define GLOBAL_STATE_CODE()
-#else
 #define GLOBAL_STATE_CODE()                                         \
     do {                                                            \
         assert(qemu_in_main_thread());                              \
     } while (0)
-#endif /* CONFIG_COCOA */
 
 /*
  * Mark and check that the function is part of the I/O API.
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 04/25] meson: Allow to enable gtk and sdl while cocoa is enabled
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 03/25] Revert "main-loop: Disable block backend global state assertion on Cocoa" Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 05/25] ui: add some vdagent related traces Gerd Hoffmann
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

From: Akihiko Odaki <akihiko.odaki@gmail.com>

As ui/cocoa does no longer override main(), ui/gtk and ui/sdl
can be enabled even ui/cocoa is enabled.

Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20220819132756.74641-4-akihiko.odaki@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 meson.build | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/meson.build b/meson.build
index 3885fc107633..d9ac91ff3659 100644
--- a/meson.build
+++ b/meson.build
@@ -589,12 +589,6 @@ endif
 
 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
                    required: get_option('cocoa'))
-if cocoa.found() and get_option('sdl').enabled()
-  error('Cocoa and SDL cannot be enabled at the same time')
-endif
-if cocoa.found() and get_option('gtk').enabled()
-  error('Cocoa and GTK+ cannot be enabled at the same time')
-endif
 
 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
@@ -921,7 +915,7 @@ if not get_option('brlapi').auto() or have_system
 endif
 
 sdl = not_found
-if not get_option('sdl').auto() or (have_system and not cocoa.found())
+if not get_option('sdl').auto() or have_system
   sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
   sdl_image = not_found
 endif
@@ -1187,7 +1181,7 @@ endif
 gtk = not_found
 gtkx11 = not_found
 vte = not_found
-if not get_option('gtk').auto() or (have_system and not cocoa.found())
+if not get_option('gtk').auto() or have_system
   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
                    method: 'pkg-config',
                    required: get_option('gtk'),
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 05/25] ui: add some vdagent related traces
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 04/25] meson: Allow to enable gtk and sdl while cocoa is enabled Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 06/25] ui/clipboard: fix serial priority Gerd Hoffmann
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

This helps debugging clipboard serial sync issues.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220912102455.111765-2-marcandre.lureau@redhat.com>

[ kraxel: code style fix ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/clipboard.c  | 11 +++++++++--
 ui/vdagent.c    |  4 ++++
 ui/trace-events |  5 +++++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/ui/clipboard.c b/ui/clipboard.c
index 9079ef829b51..cd5382fcb0c1 100644
--- a/ui/clipboard.c
+++ b/ui/clipboard.c
@@ -1,5 +1,6 @@
 #include "qemu/osdep.h"
 #include "ui/clipboard.h"
+#include "trace.h"
 
 static NotifierList clipboard_notifiers =
     NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
@@ -43,17 +44,23 @@ void qemu_clipboard_peer_release(QemuClipboardPeer *peer,
 
 bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client)
 {
+    bool ok;
+
     if (!info->has_serial ||
         !cbinfo[info->selection] ||
         !cbinfo[info->selection]->has_serial) {
+        trace_clipboard_check_serial(-1, -1, true);
         return true;
     }
 
     if (client) {
-        return cbinfo[info->selection]->serial >= info->serial;
+        ok = cbinfo[info->selection]->serial >= info->serial;
     } else {
-        return cbinfo[info->selection]->serial > info->serial;
+        ok = cbinfo[info->selection]->serial > info->serial;
     }
+
+    trace_clipboard_check_serial(cbinfo[info->selection]->serial, info->serial, ok);
+    return ok;
 }
 
 void qemu_clipboard_update(QemuClipboardInfo *info)
diff --git a/ui/vdagent.c b/ui/vdagent.c
index a899eed195d3..58ce7507fddc 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -533,6 +533,8 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev *vd, uint8_t s, uint32_t
         info->has_serial = true;
         info->serial = *(uint32_t *)data;
         if (info->serial < vd->last_serial[s]) {
+            trace_vdagent_cb_grab_discard(GET_NAME(sel_name, s),
+                                          vd->last_serial[s], info->serial);
             /* discard lower-ordering guest grab */
             return;
         }
@@ -853,6 +855,8 @@ static void vdagent_chr_accept_input(Chardev *chr)
 
 static void vdagent_disconnect(VDAgentChardev *vd)
 {
+    trace_vdagent_disconnect();
+
     buffer_reset(&vd->outbuf);
     vdagent_reset_bufs(vd);
     vd->caps = 0;
diff --git a/ui/trace-events b/ui/trace-events
index a922f00e10b4..977577fbba58 100644
--- a/ui/trace-events
+++ b/ui/trace-events
@@ -127,15 +127,20 @@ xkeymap_vendor(const char *name) "vendor '%s'"
 xkeymap_keycodes(const char *name) "keycodes '%s'"
 xkeymap_keymap(const char *name) "keymap '%s'"
 
+# clipboard.c
+clipboard_check_serial(int cur, int recv, bool ok) "cur:%d recv:%d %d"
+
 # vdagent.c
 vdagent_open(void) ""
 vdagent_close(void) ""
+vdagent_disconnect(void) ""
 vdagent_send(const char *name) "msg %s"
 vdagent_send_empty_clipboard(void) ""
 vdagent_recv_chunk(uint32_t size) "size %d"
 vdagent_recv_msg(const char *name, uint32_t size) "msg %s, size %d"
 vdagent_peer_cap(const char *name) "cap %s"
 vdagent_cb_grab_selection(const char *name) "selection %s"
+vdagent_cb_grab_discard(const char *name, int cur, int recv) "selection %s, cur:%d recv:%d"
 vdagent_cb_grab_type(const char *name) "type %s"
 vdagent_cb_serial_discard(uint32_t current, uint32_t received) "current=%u, received=%u"
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 06/25] ui/clipboard: fix serial priority
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 05/25] ui: add some vdagent related traces Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 07/25] ui/vdagent: always reset the clipboard serial on caps Gerd Hoffmann
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

The incoming grab event should have a higher serial.
See also "vdagent: introduce VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL":
https://gitlab.freedesktop.org/spice/spice-protocol/-/commit/045a6978d6dbbf7046affc5c321fa8177c8cce56

This is only a relevant fix for the -display dbus, only user of that
function.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220912102455.111765-3-marcandre.lureau@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/clipboard.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui/clipboard.c b/ui/clipboard.c
index cd5382fcb0c1..3e2d02d5490c 100644
--- a/ui/clipboard.c
+++ b/ui/clipboard.c
@@ -54,9 +54,9 @@ bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client)
     }
 
     if (client) {
-        ok = cbinfo[info->selection]->serial >= info->serial;
+        ok = info->serial >= cbinfo[info->selection]->serial;
     } else {
-        ok = cbinfo[info->selection]->serial > info->serial;
+        ok = info->serial > cbinfo[info->selection]->serial;
     }
 
     trace_clipboard_check_serial(cbinfo[info->selection]->serial, info->serial, ok);
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 07/25] ui/vdagent: always reset the clipboard serial on caps
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 06/25] ui/clipboard: fix serial priority Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 08/25] ui/clipboard: reset the serial state on reset Gerd Hoffmann
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

The guest agent doesn't know what is the current serial state. Reset the
serial value whenever a new agent connection is established.

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=2124446

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220912102455.111765-4-marcandre.lureau@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/vdagent.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/ui/vdagent.c b/ui/vdagent.c
index 58ce7507fddc..819e0dc1435b 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -719,8 +719,10 @@ static void vdagent_chr_recv_caps(VDAgentChardev *vd, VDAgentMessage *msg)
     if (have_mouse(vd) && vd->mouse_hs) {
         qemu_input_handler_activate(vd->mouse_hs);
     }
+
+    memset(vd->last_serial, 0, sizeof(vd->last_serial));
+
     if (have_clipboard(vd) && vd->cbpeer.notifier.notify == NULL) {
-        memset(vd->last_serial, 0, sizeof(vd->last_serial));
         vd->cbpeer.name = "vdagent";
         vd->cbpeer.notifier.notify = vdagent_clipboard_notify;
         vd->cbpeer.request = vdagent_clipboard_request;
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 08/25] ui/clipboard: reset the serial state on reset
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 07/25] ui/vdagent: always reset the clipboard serial on caps Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 09/25] ui/vdagent: fix serial reset of guest agent Gerd Hoffmann
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Not only we have to reset the vdagent clipboards serial state, but also
the current QEMU clipboards info serial (the value is currently used by
qemu_clipboard_check_serial, only used by -display dbus).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220912102455.111765-5-marcandre.lureau@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/clipboard.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/ui/clipboard.c b/ui/clipboard.c
index 3e2d02d5490c..3d14bffaf80f 100644
--- a/ui/clipboard.c
+++ b/ui/clipboard.c
@@ -139,7 +139,14 @@ void qemu_clipboard_request(QemuClipboardInfo *info,
 void qemu_clipboard_reset_serial(void)
 {
     QemuClipboardNotify notify = { .type = QEMU_CLIPBOARD_RESET_SERIAL };
+    int i;
 
+    for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
+        QemuClipboardInfo *info = qemu_clipboard_info(i);
+        if (info) {
+            info->serial = 0;
+        }
+    }
     notifier_list_notify(&clipboard_notifiers, &notify);
 }
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 09/25] ui/vdagent: fix serial reset of guest agent
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 08/25] ui/clipboard: reset the serial state on reset Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 10/25] ui/console: fix three double frees in png_save() Gerd Hoffmann
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

In order to reset the guest agent, we send CLOSED & OPENED events.

They are correctly received by the guest kernel. However, they might not
be noticed by the guest agent process, as the IO task (poll() for
example) might be wake up after both CLOSED & OPENED have been
processed.

Wait until the guest agent is disconnected to re-open our side.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220912102455.111765-6-marcandre.lureau@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/vdagent.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ui/vdagent.c b/ui/vdagent.c
index 819e0dc1435b..4bf50f0c4d88 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -471,7 +471,7 @@ static void vdagent_clipboard_reset_serial(VDAgentChardev *vd)
 
     /* reopen the agent connection to reset the serial state */
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
-    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    /* OPENED again after the guest disconnected, see set_fe_open */
 }
 
 static void vdagent_clipboard_notify(Notifier *notifier, void *data)
@@ -875,6 +875,9 @@ static void vdagent_chr_set_fe_open(struct Chardev *chr, int fe_open)
 {
     if (!fe_open) {
         trace_vdagent_close();
+        /* To reset_serial, we CLOSED our side. Make sure the other end knows we
+         * are ready again. */
+        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
         return;
     }
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 10/25] ui/console: fix three double frees in png_save()
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 09/25] ui/vdagent: fix serial reset of guest agent Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 11/25] hw/usb/hcd-xhci: Check whether DMA accesses fail Gerd Hoffmann
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Volker Rümelin

From: Volker Rümelin <vr_qemu@t-online.de>

The png_destroy_write_struct() function frees all memory used by
libpng. Don't use the glib auto cleanup mechanism to free the
memory allocated by libpng again. For the pixman image, use only the
auto cleanup mechanism and remove the qemu_pixman_image_unref()
function call to prevent another double free.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1210
Fixes: 9a0a119a38 ("Added parameter to take screenshot with screendump as PNG")
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20220919061956.30929-1-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index 243f2f6e64ae..49da6a91df6f 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -304,8 +304,8 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
 {
     int width = pixman_image_get_width(image);
     int height = pixman_image_get_height(image);
-    g_autofree png_struct *png_ptr = NULL;
-    g_autofree png_info *info_ptr = NULL;
+    png_struct *png_ptr;
+    png_info *info_ptr;
     g_autoptr(pixman_image_t) linebuf =
                             qemu_pixman_linebuf_create(PIXMAN_a8r8g8b8, width);
     uint8_t *buf = (uint8_t *)pixman_image_get_data(linebuf);
@@ -346,7 +346,6 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
         qemu_pixman_linebuf_fill(linebuf, image, width, 0, y);
         png_write_row(png_ptr, buf);
     }
-    qemu_pixman_image_unref(linebuf);
 
     png_write_end(png_ptr, NULL);
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 11/25] hw/usb/hcd-xhci: Check whether DMA accesses fail
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 10/25] ui/console: fix three double frees in png_save() Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 12/25] hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is zero Gerd Hoffmann
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

From: Thomas Huth <thuth@redhat.com>

If a guest sets up bad descriptors, it could force QEMU to access
non-existing memory regions. Thus we should check the return value
of dma_memory_read/write() to make sure that these errors don't go
unnoticed.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20220817160016.49752-1-thuth@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-xhci.c | 64 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 3c48b58ddeb5..acd60b1a4904 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -463,6 +463,12 @@ static void xhci_mfwrap_timer(void *opaque)
     xhci_mfwrap_update(xhci);
 }
 
+static void xhci_die(XHCIState *xhci)
+{
+    xhci->usbsts |= USBSTS_HCE;
+    DPRINTF("xhci: asserted controller error\n");
+}
+
 static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high)
 {
     if (sizeof(dma_addr_t) == 4) {
@@ -488,7 +494,14 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr,
 
     assert((len % sizeof(uint32_t)) == 0);
 
-    dma_memory_read(xhci->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED);
+    if (dma_memory_read(xhci->as, addr, buf, len,
+                        MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+                      __func__);
+        memset(buf, 0xff, len);
+        xhci_die(xhci);
+        return;
+    }
 
     for (i = 0; i < (len / sizeof(uint32_t)); i++) {
         buf[i] = le32_to_cpu(buf[i]);
@@ -496,7 +509,7 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr,
 }
 
 static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
-                                       uint32_t *buf, size_t len)
+                                       const uint32_t *buf, size_t len)
 {
     int i;
     uint32_t tmp[5];
@@ -508,7 +521,13 @@ static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
     for (i = 0; i < n; i++) {
         tmp[i] = cpu_to_le32(buf[i]);
     }
-    dma_memory_write(xhci->as, addr, tmp, len, MEMTXATTRS_UNSPECIFIED);
+    if (dma_memory_write(xhci->as, addr, tmp, len,
+                         MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+                      __func__);
+        xhci_die(xhci);
+        return;
+    }
 }
 
 static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport)
@@ -593,12 +612,6 @@ static inline int xhci_running(XHCIState *xhci)
     return !(xhci->usbsts & USBSTS_HCH);
 }
 
-static void xhci_die(XHCIState *xhci)
-{
-    xhci->usbsts |= USBSTS_HCE;
-    DPRINTF("xhci: asserted controller error\n");
-}
-
 static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
 {
     XHCIInterrupter *intr = &xhci->intr[v];
@@ -619,7 +632,12 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
                                ev_trb.status, ev_trb.control);
 
     addr = intr->er_start + TRB_SIZE*intr->er_ep_idx;
-    dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, MEMTXATTRS_UNSPECIFIED);
+    if (dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE,
+                         MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+                      __func__);
+        xhci_die(xhci);
+    }
 
     intr->er_ep_idx++;
     if (intr->er_ep_idx >= intr->er_size) {
@@ -680,8 +698,12 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
 
     while (1) {
         TRBType type;
-        dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
-                        MEMTXATTRS_UNSPECIFIED);
+        if (dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
+                            MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+                          __func__);
+            return 0;
+        }
         trb->addr = ring->dequeue;
         trb->ccs = ring->ccs;
         le64_to_cpus(&trb->parameter);
@@ -798,8 +820,14 @@ static void xhci_er_reset(XHCIState *xhci, int v)
         xhci_die(xhci);
         return;
     }
-    dma_memory_read(xhci->as, erstba, &seg, sizeof(seg),
-                    MEMTXATTRS_UNSPECIFIED);
+    if (dma_memory_read(xhci->as, erstba, &seg, sizeof(seg),
+                    MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+                      __func__);
+        xhci_die(xhci);
+        return;
+    }
+
     le32_to_cpus(&seg.addr_low);
     le32_to_cpus(&seg.addr_high);
     le32_to_cpus(&seg.size);
@@ -2415,8 +2443,12 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
     /* TODO: actually implement real values here */
     bw_ctx[0] = 0;
     memset(&bw_ctx[1], 80, xhci->numports); /* 80% */
-    dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
-                     MEMTXATTRS_UNSPECIFIED);
+    if (dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
+                     MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory write failed!\n",
+                      __func__);
+        return CC_TRB_ERROR;
+    }
 
     return CC_SUCCESS;
 }
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 12/25] hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is zero
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 11/25] hw/usb/hcd-xhci: Check whether DMA accesses fail Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs Gerd Hoffmann
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Qiang Liu,
	Gaoning Pan

From: Qiang Liu <cyruscyliu@gmail.com>

An abort happens in ohci_frame_boundary() when ohci->done is 0 [1].

``` c
static void ohci_frame_boundary(void *opaque)
{
    // ...
    if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
        if (!ohci->done)
            abort(); <----------------------------------------- [1]
```

This was reported in https://bugs.launchpad.net/qemu/+bug/1911216/,
https://lists.gnu.org/archive/html/qemu-devel/2021-06/msg03613.html, and
https://gitlab.com/qemu-project/qemu/-/issues/545. I can still reproduce it with
the latest QEMU.

This happends due to crafted ED with putting ISO_TD at physical address 0.

Suppose ed->head & OHCI_DPTR_MASK is 0 [2], and we memset 0 to the phyiscal
memory from 0 to sizeof(ohci_iso_td). Then, starting_frame [3] and frame_count
[4] are both 0. As we can control the value of ohci->frame_number (0 to 0x1f,
suppose 1), we then control the value of relative_frame_number to be 1 [6]. The
control flow goes to [7] where ohci->done is 0. Have returned from
ohci_service_iso_td(), ohci_frame_boundary() will abort() [1].

``` c
static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
{
    // ...
    addr = ed->head & OHCI_DPTR_MASK; // <--------------------- [2]

    if (ohci_read_iso_td(ohci, addr, &iso_td)) {   // <-------- [3]
        // ...

    starting_frame = OHCI_BM(iso_td.flags, TD_SF); // <-------- [4]
    frame_count = OHCI_BM(iso_td.flags, TD_FC);    // <-------- [5]
    relative_frame_number = USUB(ohci->frame_number, starting_frame);
                                                   // <-------- [6]
    if (relative_frame_number < 0) {
        return 1;
    } else if (relative_frame_number > frame_count) {
        // ...
        ohci->done = addr;                         // <-------- [7]
        // ...
    }
```

As only (afaik) a guest root user can manipulate ED, TD and the physical memory,
this assertion failure is not a security bug.

The idea to fix this issue is to drop ohci_service_iso_td() if ed->head &
OHCI_DPTR_MASK is 0, which is similar to the drop operation for
ohci_service_ed_list() when head is 0. Probably, a similar issue is in
ohci_service_td(). I drop ohci_service_td() if ed->head & OHCI_DPTR_MASK is 0.

Fixes: 7bfe577702 ("OHCI USB isochronous transfers support (Arnon Gilboa)")
Reported-by: Gaoning Pan <pgn@zju.edu.cn>
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/545
Buglink: https://lists.gnu.org/archive/html/qemu-devel/2021-06/msg03613.html
Buglink: https://bugs.launchpad.net/qemu/+bug/1911216
Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
Message-Id: <20220826051557.119570-1-cyruscyliu@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-ohci.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 895b29fb8657..72bdde92617c 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -571,6 +571,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
 
     addr = ed->head & OHCI_DPTR_MASK;
 
+    if (addr == 0) {
+        ohci_die(ohci);
+        return 1;
+    }
+
     if (ohci_read_iso_td(ohci, addr, &iso_td)) {
         trace_usb_ohci_iso_td_read_failed(addr);
         ohci_die(ohci);
@@ -858,6 +863,11 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
     int completion;
 
     addr = ed->head & OHCI_DPTR_MASK;
+    if (addr == 0) {
+        ohci_die(ohci);
+        return 1;
+    }
+
     /* See if this TD has already been submitted to the device.  */
     completion = (addr == ohci->async_td);
     if (completion && !ohci->async_complete) {
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 12/25] hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is zero Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-27  1:11   ` Stefan Hajnoczi
  2022-09-26  9:54 ` [PULL 14/25] usb/msd: move usb_msd_packet_complete() Gerd Hoffmann
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Qiang Liu

From: Qiang Liu <cyruscyliu@gmail.com>

I found an assertion failure in usb_cancel_packet() and posted my analysis in
https://gitlab.com/qemu-project/qemu/-/issues/1180. I think this issue is
because the inconsistency when resetting ohci root hubs.

There are two ways to reset ohci root hubs: 1) through HcRhPortStatus, 2)
through HcControl. However, when the packet's status is USB_PACKET_ASYNC,
resetting through HcRhPortStatus will complete the packet and thus resetting
through HcControl will fail. That is because IMO resetting through
HcRhPortStatus should first detach the port and then invoked usb_device_reset()
just like through HcControl. Therefore, I change usb_device_reset() to
usb_port_reset() where usb_detach() and usb_device_reset() are invoked
consequently.

Fixes: d28f4e2d8631 ("usb: kill USB_MSG_RESET")
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1180
Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
Message-Id: <20220830033022.1164961-1-cyruscyliu@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-ohci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 72bdde92617c..28d703481515 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1436,7 +1436,7 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
 
     if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
         trace_usb_ohci_port_reset(portnum);
-        usb_device_reset(port->port.dev);
+        usb_port_reset(&port->port);
         port->ctrl &= ~OHCI_PORT_PRS;
         /* ??? Should this also set OHCI_PORT_PESC.  */
         port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 14/25] usb/msd: move usb_msd_packet_complete()
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:54 ` [PULL 15/25] usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert Gerd Hoffmann
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

Change ordering to avoid adding forward declarations in
following patches.  Fix comment code style while being
at it.  No functional change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20220830063827.813053-2-kraxel@redhat.com>
---
 hw/usb/dev-storage.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 98639696e6d8..140ef2aeaa80 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -177,6 +177,20 @@ static const USBDesc desc = {
     .str   = desc_strings,
 };
 
+static void usb_msd_packet_complete(MSDState *s)
+{
+    USBPacket *p = s->packet;
+
+    /*
+     * Set s->packet to NULL before calling usb_packet_complete
+     * because another request may be issued before
+     * usb_packet_complete returns.
+     */
+    trace_usb_msd_packet_complete();
+    s->packet = NULL;
+    usb_packet_complete(&s->dev, p);
+}
+
 static void usb_msd_copy_data(MSDState *s, USBPacket *p)
 {
     uint32_t len;
@@ -208,18 +222,6 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p)
     memset(&s->csw, 0, sizeof(s->csw));
 }
 
-static void usb_msd_packet_complete(MSDState *s)
-{
-    USBPacket *p = s->packet;
-
-    /* Set s->packet to NULL before calling usb_packet_complete
-       because another request may be issued before
-       usb_packet_complete returns.  */
-    trace_usb_msd_packet_complete();
-    s->packet = NULL;
-    usb_packet_complete(&s->dev, p);
-}
-
 void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
 {
     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 15/25] usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (13 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 14/25] usb/msd: move usb_msd_packet_complete() Gerd Hoffmann
@ 2022-09-26  9:54 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 16/25] hcd-xhci: drop operation with secondary stream arrays enabled Gerd Hoffmann
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Qiang Liu

Add handler for fatal errors.  Moves device into error state where it
stops responding until the guest resets it.

Guest can send illegal requests where scsi command and usb packet
transfer directions are inconsistent.  Use the new usb_msd_fatal_error()
function instead of assert() in that case.

Reported-by: Qiang Liu <cyruscyliu@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Qiang Liu <cyruscyliu@gmail.com>
Message-Id: <20220830063827.813053-3-kraxel@redhat.com>
---
 include/hw/usb/msd.h |  1 +
 hw/usb/dev-storage.c | 30 +++++++++++++++++++++++++++++-
 hw/usb/trace-events  |  1 +
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/include/hw/usb/msd.h b/include/hw/usb/msd.h
index 54e9f38bda46..f9fd862b529a 100644
--- a/include/hw/usb/msd.h
+++ b/include/hw/usb/msd.h
@@ -40,6 +40,7 @@ struct MSDState {
     bool removable;
     bool commandlog;
     SCSIDevice *scsi_dev;
+    bool needs_reset;
 };
 
 typedef struct MSDState MSDState;
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 140ef2aeaa80..e3bcffb3e0d7 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -191,6 +191,23 @@ static void usb_msd_packet_complete(MSDState *s)
     usb_packet_complete(&s->dev, p);
 }
 
+static void usb_msd_fatal_error(MSDState *s)
+{
+    trace_usb_msd_fatal_error();
+
+    if (s->packet) {
+        s->packet->status = USB_RET_STALL;
+        usb_msd_packet_complete(s);
+    }
+
+    /*
+     * Guest messed up up device state with illegal requests.  Go
+     * ignore any requests until the guests resets the device (and
+     * brings it into a known state that way).
+     */
+    s->needs_reset = true;
+}
+
 static void usb_msd_copy_data(MSDState *s, USBPacket *p)
 {
     uint32_t len;
@@ -227,7 +244,11 @@ void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
     USBPacket *p = s->packet;
 
-    assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
+    if ((s->mode == USB_MSDM_DATAOUT) != (req->cmd.mode == SCSI_XFER_TO_DEV)) {
+        usb_msd_fatal_error(s);
+        return;
+    }
+
     s->scsi_len = len;
     s->scsi_off = 0;
     if (p) {
@@ -317,6 +338,8 @@ void usb_msd_handle_reset(USBDevice *dev)
 
     memset(&s->csw, 0, sizeof(s->csw));
     s->mode = USB_MSDM_CBW;
+
+    s->needs_reset = false;
 }
 
 static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
@@ -382,6 +405,11 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
     SCSIDevice *scsi_dev;
     uint32_t len;
 
+    if (s->needs_reset) {
+        p->status = USB_RET_STALL;
+        return;
+    }
+
     switch (p->pid) {
     case USB_TOKEN_OUT:
         if (devep != 2)
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
index 914ca7166829..b65269892c5e 100644
--- a/hw/usb/trace-events
+++ b/hw/usb/trace-events
@@ -263,6 +263,7 @@ usb_msd_packet_complete(void) ""
 usb_msd_cmd_submit(unsigned lun, unsigned tag, unsigned flags, unsigned len, unsigned data_len) "lun %u, tag 0x%x, flags 0x%08x, len %d, data-len %d"
 usb_msd_cmd_complete(unsigned status, unsigned tag) "status %d, tag 0x%x"
 usb_msd_cmd_cancel(unsigned tag) "tag 0x%x"
+usb_msd_fatal_error(void) ""
 
 # dev-uas.c
 usb_uas_reset(int addr) "dev %d"
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 16/25] hcd-xhci: drop operation with secondary stream arrays enabled
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (14 preceding siblings ...)
  2022-09-26  9:54 ` [PULL 15/25] usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 17/25] usbnet: Add missing usb_wakeup() call in usbnet_receive() Gerd Hoffmann
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Qiang Liu

From: Qiang Liu <cyruscyliu@gmail.com>

The abort() in xhci_find_stream() can be triggered via enabling the secondary
stream arrays by setting linear stream array (LSA) bit (in endpoint context) to
0. We may show warnings and drop this operation.

Fixes: 024426acc0a2 ("usb-xhci: usb3 streams")
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1192
Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
Message-Id: <20220904125926.2141607-1-cyruscyliu@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-xhci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index acd60b1a4904..8299f35e6695 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1020,7 +1020,9 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
         }
         sctx = epctx->pstreams + streamid;
     } else {
-        FIXME("secondary streams not implemented yet");
+        fprintf(stderr, "xhci: FIXME: secondary streams not implemented yet");
+        *cc_error = CC_INVALID_STREAM_TYPE_ERROR;
+        return NULL;
     }
 
     if (sctx->sct == -1) {
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 17/25] usbnet: Add missing usb_wakeup() call in usbnet_receive()
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (15 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 16/25] hcd-xhci: drop operation with secondary stream arrays enabled Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 18/25] usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request Gerd Hoffmann
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Michael Brown

From: Michael Brown <mcb30@ipxe.org>

usbnet_receive() does not currently wake up the USB endpoint, leading
to a dead RX datapath when used with a host controller such as xHCI
that relies on being woken up.

Fix by adding a call to usb_wakeup() at the end of usbnet_receive().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
Message-Id: <20220906183053.3625472-2-mcb30@ipxe.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-network.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 6c49c16015e0..61bf598870cb 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -647,6 +647,7 @@ struct USBNetState {
     uint8_t in_buf[2048];
 
     USBEndpoint *intr;
+    USBEndpoint *bulk_in;
 
     char usbstring_mac[13];
     NICState *nic;
@@ -1317,6 +1318,7 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
     memcpy(in_buf, buf, size);
     s->in_len = total_size;
     s->in_ptr = 0;
+    usb_wakeup(s->bulk_in, 0);
     return size;
 }
 
@@ -1359,6 +1361,7 @@ static void usb_net_realize(USBDevice *dev, Error **errp)
     s->filter = 0;
     s->vendorid = 0x1234;
     s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
+    s->bulk_in = usb_ep_get(dev, USB_TOKEN_IN, 2);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 18/25] usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (16 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 17/25] usbnet: Add missing usb_wakeup() call in usbnet_receive() Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 19/25] usbnet: Detect short packets as sent by the xHCI controller Gerd Hoffmann
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Michael Brown

From: Michael Brown <mcb30@ipxe.org>

The USB_CDC_SET_ETHERNET_PACKET_FILTER request is mandatory for
CDC-ECM devices.  Accept this request, ignoring the actual filter
value (to match the existing behaviour for RNDIS).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
Message-Id: <20220906183053.3625472-3-mcb30@ipxe.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-network.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 61bf598870cb..155df935cd68 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1122,6 +1122,12 @@ static void usb_net_handle_control(USBDevice *dev, USBPacket *p,
 #endif
         break;
 
+    case ClassInterfaceOutRequest | USB_CDC_SET_ETHERNET_PACKET_FILTER:
+        if (is_rndis(s)) {
+            goto fail;
+        }
+        break;
+
     default:
     fail:
         fprintf(stderr, "usbnet: failed control transaction: "
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 19/25] usbnet: Detect short packets as sent by the xHCI controller
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (17 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 18/25] usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 20/25] usbnet: Report link-up via interrupt endpoint in CDC-ECM mode Gerd Hoffmann
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Michael Brown

From: Michael Brown <mcb30@ipxe.org>

The xHCI controller will ignore the endpoint MTU and so may deliver
packets of any length.  Detect short packets as being any packet that
has a length of zero or a length that is not a multiple of the MTU.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
Message-Id: <20220906183053.3625472-4-mcb30@ipxe.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-network.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 155df935cd68..9d83974ec9f0 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1211,7 +1211,7 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
     s->out_ptr += sz;
 
     if (!is_rndis(s)) {
-        if (p->iov.size < 64) {
+        if (p->iov.size % 64 || p->iov.size == 0) {
             qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr);
             s->out_ptr = 0;
         }
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 20/25] usbnet: Report link-up via interrupt endpoint in CDC-ECM mode
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (18 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 19/25] usbnet: Detect short packets as sent by the xHCI controller Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 21/25] audio: Add sndio backend Gerd Hoffmann
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Michael Brown

From: Michael Brown <mcb30@ipxe.org>

Signed-off-by: Michael Brown <mcb30@ipxe.org>
Message-Id: <20220906183053.3625472-5-mcb30@ipxe.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-network.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 9d83974ec9f0..ac1adca54355 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -91,6 +91,8 @@ enum usbstring_idx {
 #define USB_CDC_SET_ETHERNET_PACKET_FILTER	0x43
 #define USB_CDC_GET_ETHERNET_STATISTIC		0x44
 
+#define USB_CDC_NETWORK_CONNECTION	0x00
+
 #define LOG2_STATUS_INTERVAL_MSEC	5    /* 1 << 5 == 32 msec */
 #define STATUS_BYTECOUNT		16   /* 8 byte header + data */
 
@@ -640,6 +642,8 @@ struct USBNetState {
     uint16_t filter;
     uint32_t vendorid;
 
+    uint16_t connection;
+
     unsigned int out_ptr;
     uint8_t out_buf[2048];
 
@@ -1140,18 +1144,28 @@ static void usb_net_handle_control(USBDevice *dev, USBPacket *p,
 
 static void usb_net_handle_statusin(USBNetState *s, USBPacket *p)
 {
-    le32 buf[2];
+    le32 rbuf[2];
+    uint16_t ebuf[4];
 
     if (p->iov.size < 8) {
         p->status = USB_RET_STALL;
         return;
     }
 
-    buf[0] = cpu_to_le32(1);
-    buf[1] = cpu_to_le32(0);
-    usb_packet_copy(p, buf, 8);
-    if (!s->rndis_resp.tqh_first) {
-        p->status = USB_RET_NAK;
+    if (is_rndis(s)) {
+        rbuf[0] = cpu_to_le32(1);
+        rbuf[1] = cpu_to_le32(0);
+        usb_packet_copy(p, rbuf, 8);
+        if (!s->rndis_resp.tqh_first) {
+            p->status = USB_RET_NAK;
+        }
+    } else {
+        ebuf[0] =
+            cpu_to_be16(ClassInterfaceRequest | USB_CDC_NETWORK_CONNECTION);
+        ebuf[1] = cpu_to_le16(s->connection);
+        ebuf[2] = cpu_to_le16(1);
+        ebuf[3] = cpu_to_le16(0);
+        usb_packet_copy(p, ebuf, 8);
     }
 
 #ifdef TRAFFIC_DEBUG
@@ -1366,6 +1380,7 @@ static void usb_net_realize(USBDevice *dev, Error **errp)
     s->media_state = 0;	/* NDIS_MEDIA_STATE_CONNECTED */;
     s->filter = 0;
     s->vendorid = 0x1234;
+    s->connection = 1;	/* Connected */
     s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
     s->bulk_in = usb_ep_get(dev, USB_TOKEN_IN, 2);
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 21/25] audio: Add sndio backend
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (19 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 20/25] usbnet: Report link-up via interrupt endpoint in CDC-ECM mode Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 22/25] Revert "audio: Log context for audio bug" Gerd Hoffmann
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Brad Smith,
	Volker Rümelin

From: Alexandre Ratchov <alex@caoua.org>

sndio is the native API used by OpenBSD, although it has been ported to
other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).

Signed-off-by: Brad Smith <brad@comstyle.com>
Signed-off-by: Alexandre Ratchov <alex@caoua.org>
Reviewed-by: Volker Rümelin <vr_qemu@t-online.de>
Tested-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <YxibXrWsrS3XYQM3@vm1.arverb.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 meson_options.txt             |   4 +-
 audio/audio_template.h        |   2 +
 audio/audio.c                 |   1 +
 audio/sndioaudio.c            | 565 ++++++++++++++++++++++++++++++++++
 MAINTAINERS                   |   7 +
 audio/meson.build             |   1 +
 meson.build                   |   9 +-
 qapi/audio.json               |  25 +-
 qemu-options.hx               |  16 +
 scripts/meson-buildoptions.sh |   7 +-
 10 files changed, 632 insertions(+), 5 deletions(-)
 create mode 100644 audio/sndioaudio.c

diff --git a/meson_options.txt b/meson_options.txt
index 63f072517427..9df9e86d7d35 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -21,7 +21,7 @@ option('tls_priority', type : 'string', value : 'NORMAL',
 option('default_devices', type : 'boolean', value : true,
        description: 'Include a default selection of devices in emulators')
 option('audio_drv_list', type: 'array', value: ['default'],
-       choices: ['alsa', 'coreaudio', 'default', 'dsound', 'jack', 'oss', 'pa', 'sdl'],
+       choices: ['alsa', 'coreaudio', 'default', 'dsound', 'jack', 'oss', 'pa', 'sdl', 'sndio'],
        description: 'Set audio driver list')
 option('block_drv_rw_whitelist', type : 'string', value : '',
        description: 'set block driver read-write whitelist (by default affects only QEMU, not tools like qemu-img)')
@@ -240,6 +240,8 @@ option('oss', type: 'feature', value: 'auto',
        description: 'OSS sound support')
 option('pa', type: 'feature', value: 'auto',
        description: 'PulseAudio sound support')
+option('sndio', type: 'feature', value: 'auto',
+       description: 'sndio sound support')
 
 option('vhost_kernel', type: 'feature', value: 'auto',
        description: 'vhost kernel backend support')
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 7192b19e7390..81860cea6202 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -336,6 +336,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
         return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
     case AUDIODEV_DRIVER_SDL:
         return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
+    case AUDIODEV_DRIVER_SNDIO:
+        return dev->u.sndio.TYPE;
     case AUDIODEV_DRIVER_SPICE:
         return dev->u.spice.TYPE;
     case AUDIODEV_DRIVER_WAV:
diff --git a/audio/audio.c b/audio/audio.c
index cfa4119c0598..5600593da043 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2030,6 +2030,7 @@ void audio_create_pdos(Audiodev *dev)
         CASE(OSS, oss, Oss);
         CASE(PA, pa, Pa);
         CASE(SDL, sdl, Sdl);
+        CASE(SNDIO, sndio, );
         CASE(SPICE, spice, );
         CASE(WAV, wav, );
 
diff --git a/audio/sndioaudio.c b/audio/sndioaudio.c
new file mode 100644
index 000000000000..7c45276d36ce
--- /dev/null
+++ b/audio/sndioaudio.c
@@ -0,0 +1,565 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2019 Alexandre Ratchov <alex@caoua.org>
+ */
+
+/*
+ * TODO :
+ *
+ * Use a single device and open it in full-duplex rather than
+ * opening it twice (once for playback once for recording).
+ *
+ * This is the only way to ensure that playback doesn't drift with respect
+ * to recording, which is what guest systems expect.
+ */
+
+#include <poll.h>
+#include <sndio.h>
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "audio.h"
+#include "trace.h"
+
+#define AUDIO_CAP "sndio"
+#include "audio_int.h"
+
+/* default latency in microseconds if no option is set */
+#define SNDIO_LATENCY_US   50000
+
+typedef struct SndioVoice {
+    union {
+        HWVoiceOut out;
+        HWVoiceIn in;
+    } hw;
+    struct sio_par par;
+    struct sio_hdl *hdl;
+    struct pollfd *pfds;
+    struct pollindex {
+        struct SndioVoice *self;
+        int index;
+    } *pindexes;
+    unsigned char *buf;
+    size_t buf_size;
+    size_t sndio_pos;
+    size_t qemu_pos;
+    unsigned int mode;
+    unsigned int nfds;
+    bool enabled;
+} SndioVoice;
+
+typedef struct SndioConf {
+    const char *devname;
+    unsigned int latency;
+} SndioConf;
+
+/* needed for forward reference */
+static void sndio_poll_in(void *arg);
+static void sndio_poll_out(void *arg);
+
+/*
+ * stop polling descriptors
+ */
+static void sndio_poll_clear(SndioVoice *self)
+{
+    struct pollfd *pfd;
+    int i;
+
+    for (i = 0; i < self->nfds; i++) {
+        pfd = &self->pfds[i];
+        qemu_set_fd_handler(pfd->fd, NULL, NULL, NULL);
+    }
+
+    self->nfds = 0;
+}
+
+/*
+ * write data to the device until it blocks or
+ * all of our buffered data is written
+ */
+static void sndio_write(SndioVoice *self)
+{
+    size_t todo, n;
+
+    todo = self->qemu_pos - self->sndio_pos;
+
+    /*
+     * transfer data to device, until it blocks
+     */
+    while (todo > 0) {
+        n = sio_write(self->hdl, self->buf + self->sndio_pos, todo);
+        if (n == 0) {
+            break;
+        }
+        self->sndio_pos += n;
+        todo -= n;
+    }
+
+    if (self->sndio_pos == self->buf_size) {
+        /*
+         * we complete the block
+         */
+        self->sndio_pos = 0;
+        self->qemu_pos = 0;
+    }
+}
+
+/*
+ * read data from the device until it blocks or
+ * there no room any longer
+ */
+static void sndio_read(SndioVoice *self)
+{
+    size_t todo, n;
+
+    todo = self->buf_size - self->sndio_pos;
+
+    /*
+     * transfer data from the device, until it blocks
+     */
+    while (todo > 0) {
+        n = sio_read(self->hdl, self->buf + self->sndio_pos, todo);
+        if (n == 0) {
+            break;
+        }
+        self->sndio_pos += n;
+        todo -= n;
+    }
+}
+
+/*
+ * Set handlers for all descriptors libsndio needs to
+ * poll
+ */
+static void sndio_poll_wait(SndioVoice *self)
+{
+    struct pollfd *pfd;
+    int events, i;
+
+    events = 0;
+    if (self->mode == SIO_PLAY) {
+        if (self->sndio_pos < self->qemu_pos) {
+            events |= POLLOUT;
+        }
+    } else {
+        if (self->sndio_pos < self->buf_size) {
+            events |= POLLIN;
+        }
+    }
+
+    /*
+     * fill the given array of descriptors with the events sndio
+     * wants, they are different from our 'event' variable because
+     * sndio may use descriptors internally.
+     */
+    self->nfds = sio_pollfd(self->hdl, self->pfds, events);
+
+    for (i = 0; i < self->nfds; i++) {
+        pfd = &self->pfds[i];
+        if (pfd->fd < 0) {
+            continue;
+        }
+        qemu_set_fd_handler(pfd->fd,
+            (pfd->events & POLLIN) ? sndio_poll_in : NULL,
+            (pfd->events & POLLOUT) ? sndio_poll_out : NULL,
+            &self->pindexes[i]);
+        pfd->revents = 0;
+    }
+}
+
+/*
+ * call-back called when one of the descriptors
+ * became readable or writable
+ */
+static void sndio_poll_event(SndioVoice *self, int index, int event)
+{
+    int revents;
+
+    /*
+     * ensure we're not called twice this cycle
+     */
+    sndio_poll_clear(self);
+
+    /*
+     * make self->pfds[] look as we're returning from poll syscal,
+     * this is how sio_revents expects events to be.
+     */
+    self->pfds[index].revents = event;
+
+    /*
+     * tell sndio to handle events and return whether we can read or
+     * write without blocking.
+     */
+    revents = sio_revents(self->hdl, self->pfds);
+    if (self->mode == SIO_PLAY) {
+        if (revents & POLLOUT) {
+            sndio_write(self);
+        }
+
+        if (self->qemu_pos < self->buf_size) {
+            audio_run(self->hw.out.s, "sndio_out");
+        }
+    } else {
+        if (revents & POLLIN) {
+            sndio_read(self);
+        }
+
+        if (self->qemu_pos < self->sndio_pos) {
+            audio_run(self->hw.in.s, "sndio_in");
+        }
+    }
+
+    /*
+     * audio_run() may have changed state
+     */
+    if (self->enabled) {
+        sndio_poll_wait(self);
+    }
+}
+
+/*
+ * return the upper limit of the amount of free play buffer space
+ */
+static size_t sndio_buffer_get_free(HWVoiceOut *hw)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    return self->buf_size - self->qemu_pos;
+}
+
+/*
+ * return a buffer where data to play can be stored,
+ * its size is stored in the location pointed by the size argument.
+ */
+static void *sndio_get_buffer_out(HWVoiceOut *hw, size_t *size)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    *size = self->buf_size - self->qemu_pos;
+    return self->buf + self->qemu_pos;
+}
+
+/*
+ * put back to sndio back-end a buffer returned by sndio_get_buffer_out()
+ */
+static size_t sndio_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    self->qemu_pos += size;
+    sndio_poll_wait(self);
+    return size;
+}
+
+/*
+ * return a buffer from where recorded data is available,
+ * its size is stored in the location pointed by the size argument.
+ * it may not exceed the initial value of "*size".
+ */
+static void *sndio_get_buffer_in(HWVoiceIn *hw, size_t *size)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+    size_t todo, max_todo;
+
+    /*
+     * unlike the get_buffer_out() method, get_buffer_in()
+     * must return a buffer of at most the given size, see audio.c
+     */
+    max_todo = *size;
+
+    todo = self->sndio_pos - self->qemu_pos;
+    if (todo > max_todo) {
+        todo = max_todo;
+    }
+
+    *size = todo;
+    return self->buf + self->qemu_pos;
+}
+
+/*
+ * discard the given amount of recorded data
+ */
+static void sndio_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    self->qemu_pos += size;
+    if (self->qemu_pos == self->buf_size) {
+        self->qemu_pos = 0;
+        self->sndio_pos = 0;
+    }
+    sndio_poll_wait(self);
+}
+
+/*
+ * call-back called when one of our descriptors becomes writable
+ */
+static void sndio_poll_out(void *arg)
+{
+    struct pollindex *pindex = (struct pollindex *) arg;
+
+    sndio_poll_event(pindex->self, pindex->index, POLLOUT);
+}
+
+/*
+ * call-back called when one of our descriptors becomes readable
+ */
+static void sndio_poll_in(void *arg)
+{
+    struct pollindex *pindex = (struct pollindex *) arg;
+
+    sndio_poll_event(pindex->self, pindex->index, POLLIN);
+}
+
+static void sndio_fini(SndioVoice *self)
+{
+    if (self->hdl) {
+        sio_close(self->hdl);
+        self->hdl = NULL;
+    }
+
+    g_free(self->pfds);
+    g_free(self->pindexes);
+    g_free(self->buf);
+}
+
+static int sndio_init(SndioVoice *self,
+                      struct audsettings *as, int mode, Audiodev *dev)
+{
+    AudiodevSndioOptions *opts = &dev->u.sndio;
+    unsigned long long latency;
+    const char *dev_name;
+    struct sio_par req;
+    unsigned int nch;
+    int i, nfds;
+
+    dev_name = opts->has_dev ? opts->dev : SIO_DEVANY;
+    latency = opts->has_latency ? opts->latency : SNDIO_LATENCY_US;
+
+    /* open the device in non-blocking mode */
+    self->hdl = sio_open(dev_name, mode, 1);
+    if (self->hdl == NULL) {
+        dolog("failed to open device\n");
+        return -1;
+    }
+
+    self->mode = mode;
+
+    sio_initpar(&req);
+
+    switch (as->fmt) {
+    case AUDIO_FORMAT_S8:
+        req.bits = 8;
+        req.sig = 1;
+        break;
+    case AUDIO_FORMAT_U8:
+        req.bits = 8;
+        req.sig = 0;
+        break;
+    case AUDIO_FORMAT_S16:
+        req.bits = 16;
+        req.sig = 1;
+        break;
+    case AUDIO_FORMAT_U16:
+        req.bits = 16;
+        req.sig = 0;
+        break;
+    case AUDIO_FORMAT_S32:
+        req.bits = 32;
+        req.sig = 1;
+        break;
+    case AUDIO_FORMAT_U32:
+        req.bits = 32;
+        req.sig = 0;
+        break;
+    default:
+        dolog("unknown audio sample format\n");
+        return -1;
+    }
+
+    if (req.bits > 8) {
+        req.le = as->endianness ? 0 : 1;
+    }
+
+    req.rate = as->freq;
+    if (mode == SIO_PLAY) {
+        req.pchan = as->nchannels;
+    } else {
+        req.rchan = as->nchannels;
+    }
+
+    /* set on-device buffer size */
+    req.appbufsz = req.rate * latency / 1000000;
+
+    if (!sio_setpar(self->hdl, &req)) {
+        dolog("failed set audio params\n");
+        goto fail;
+    }
+
+    if (!sio_getpar(self->hdl, &self->par)) {
+        dolog("failed get audio params\n");
+        goto fail;
+    }
+
+    nch = (mode == SIO_PLAY) ? self->par.pchan : self->par.rchan;
+
+    /*
+     * With the default setup, sndio supports any combination of parameters
+     * so these checks are mostly to catch configuration errors.
+     */
+    if (self->par.bits != req.bits || self->par.bps != req.bits / 8 ||
+        self->par.sig != req.sig || (req.bits > 8 && self->par.le != req.le) ||
+        self->par.rate != as->freq || nch != as->nchannels) {
+        dolog("unsupported audio params\n");
+        goto fail;
+    }
+
+    /*
+     * we use one block as buffer size; this is how
+     * transfers get well aligned
+     */
+    self->buf_size = self->par.round * self->par.bps * nch;
+
+    self->buf = g_malloc(self->buf_size);
+    if (self->buf == NULL) {
+        dolog("failed to allocate audio buffer\n");
+        goto fail;
+    }
+
+    nfds = sio_nfds(self->hdl);
+
+    self->pfds = g_malloc_n(nfds, sizeof(struct pollfd));
+    if (self->pfds == NULL) {
+        dolog("failed to allocate pollfd structures\n");
+        goto fail;
+    }
+
+    self->pindexes = g_malloc_n(nfds, sizeof(struct pollindex));
+    if (self->pindexes == NULL) {
+        dolog("failed to allocate pollindex structures\n");
+        goto fail;
+    }
+
+    for (i = 0; i < nfds; i++) {
+        self->pindexes[i].self = self;
+        self->pindexes[i].index = i;
+    }
+
+    return 0;
+fail:
+    sndio_fini(self);
+    return -1;
+}
+
+static void sndio_enable(SndioVoice *self, bool enable)
+{
+    if (enable) {
+        sio_start(self->hdl);
+        self->enabled = true;
+        sndio_poll_wait(self);
+    } else {
+        self->enabled = false;
+        sndio_poll_clear(self);
+        sio_stop(self->hdl);
+    }
+}
+
+static void sndio_enable_out(HWVoiceOut *hw, bool enable)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    sndio_enable(self, enable);
+}
+
+static void sndio_enable_in(HWVoiceIn *hw, bool enable)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    sndio_enable(self, enable);
+}
+
+static int sndio_init_out(HWVoiceOut *hw, struct audsettings *as, void *opaque)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    if (sndio_init(self, as, SIO_PLAY, opaque) == -1) {
+        return -1;
+    }
+
+    audio_pcm_init_info(&hw->info, as);
+    hw->samples = self->par.round;
+    return 0;
+}
+
+static int sndio_init_in(HWVoiceIn *hw, struct audsettings *as, void *opaque)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    if (sndio_init(self, as, SIO_REC, opaque) == -1) {
+        return -1;
+    }
+
+    audio_pcm_init_info(&hw->info, as);
+    hw->samples = self->par.round;
+    return 0;
+}
+
+static void sndio_fini_out(HWVoiceOut *hw)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    sndio_fini(self);
+}
+
+static void sndio_fini_in(HWVoiceIn *hw)
+{
+    SndioVoice *self = (SndioVoice *) hw;
+
+    sndio_fini(self);
+}
+
+static void *sndio_audio_init(Audiodev *dev)
+{
+    assert(dev->driver == AUDIODEV_DRIVER_SNDIO);
+    return dev;
+}
+
+static void sndio_audio_fini(void *opaque)
+{
+}
+
+static struct audio_pcm_ops sndio_pcm_ops = {
+    .init_out        = sndio_init_out,
+    .fini_out        = sndio_fini_out,
+    .enable_out      = sndio_enable_out,
+    .write           = audio_generic_write,
+    .buffer_get_free = sndio_buffer_get_free,
+    .get_buffer_out  = sndio_get_buffer_out,
+    .put_buffer_out  = sndio_put_buffer_out,
+    .init_in         = sndio_init_in,
+    .fini_in         = sndio_fini_in,
+    .read            = audio_generic_read,
+    .enable_in       = sndio_enable_in,
+    .get_buffer_in   = sndio_get_buffer_in,
+    .put_buffer_in   = sndio_put_buffer_in,
+};
+
+static struct audio_driver sndio_audio_driver = {
+    .name           = "sndio",
+    .descr          = "sndio https://sndio.org",
+    .init           = sndio_audio_init,
+    .fini           = sndio_audio_fini,
+    .pcm_ops        = &sndio_pcm_ops,
+    .can_be_default = 1,
+    .max_voices_out = INT_MAX,
+    .max_voices_in  = INT_MAX,
+    .voice_size_out = sizeof(SndioVoice),
+    .voice_size_in  = sizeof(SndioVoice)
+};
+
+static void register_audio_sndio(void)
+{
+    audio_driver_register(&sndio_audio_driver);
+}
+
+type_init(register_audio_sndio);
diff --git a/MAINTAINERS b/MAINTAINERS
index 738c4eb647c8..269e07cf4777 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2438,6 +2438,7 @@ X: audio/jackaudio.c
 X: audio/ossaudio.c
 X: audio/paaudio.c
 X: audio/sdlaudio.c
+X: audio/sndioaudio.c
 X: audio/spiceaudio.c
 F: qapi/audio.json
 
@@ -2482,6 +2483,12 @@ R: Thomas Huth <huth@tuxfamily.org>
 S: Odd Fixes
 F: audio/sdlaudio.c
 
+Sndio Audio backend
+M: Gerd Hoffmann <kraxel@redhat.com>
+R: Alexandre Ratchov <alex@caoua.org>
+S: Odd Fixes
+F: audio/sndioaudio.c
+
 Block layer core
 M: Kevin Wolf <kwolf@redhat.com>
 M: Hanna Reitz <hreitz@redhat.com>
diff --git a/audio/meson.build b/audio/meson.build
index 3abee908602a..34aed7834223 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -17,6 +17,7 @@ foreach m : [
   ['pa', pulse, files('paaudio.c')],
   ['sdl', sdl, files('sdlaudio.c')],
   ['jack', jack, files('jackaudio.c')],
+  ['sndio', sndio, files('sndioaudio.c')],
   ['spice', spice, files('spiceaudio.c')]
 ]
   if m[1].found()
diff --git a/meson.build b/meson.build
index d9ac91ff3659..13db89c65af1 100644
--- a/meson.build
+++ b/meson.build
@@ -675,6 +675,11 @@ if not get_option('jack').auto() or have_system
   jack = dependency('jack', required: get_option('jack'),
                     method: 'pkg-config', kwargs: static_kwargs)
 endif
+sndio = not_found
+if not get_option('sndio').auto() or have_system
+  sndio = dependency('sndio', required: get_option('sndio'),
+                    method: 'pkg-config', kwargs: static_kwargs)
+endif
 
 spice_protocol = not_found
 if not get_option('spice_protocol').auto() or have_system
@@ -1591,6 +1596,7 @@ if have_system
     'oss': oss.found(),
     'pa': pulse.found(),
     'sdl': sdl.found(),
+    'sndio': sndio.found(),
   }
   foreach k, v: audio_drivers_available
     config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
@@ -1598,7 +1604,7 @@ if have_system
 
   # Default to native drivers first, OSS second, SDL third
   audio_drivers_priority = \
-    [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
+    [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
     (targetos == 'linux' ? [] : [ 'sdl' ])
   audio_drivers_default = []
   foreach k: audio_drivers_priority
@@ -3922,6 +3928,7 @@ if vnc.found()
 endif
 if targetos not in ['darwin', 'haiku', 'windows']
   summary_info += {'OSS support':     oss}
+  summary_info += {'sndio support':   sndio}
 elif targetos == 'darwin'
   summary_info += {'CoreAudio support': coreaudio}
 elif targetos == 'windows'
diff --git a/qapi/audio.json b/qapi/audio.json
index 8099e3d7f13b..1e0a24bdfc40 100644
--- a/qapi/audio.json
+++ b/qapi/audio.json
@@ -106,6 +106,28 @@
     '*out':       'AudiodevAlsaPerDirectionOptions',
     '*threshold': 'uint32' } }
 
+##
+# @AudiodevSndioOptions:
+#
+# Options of the sndio audio backend.
+#
+# @in: options of the capture stream
+#
+# @out: options of the playback stream
+#
+# @dev: the name of the sndio device to use (default 'default')
+#
+# @latency: play buffer size (in microseconds)
+#
+# Since: 7.2
+##
+{ 'struct': 'AudiodevSndioOptions',
+  'data': {
+    '*in':        'AudiodevPerDirectionOptions',
+    '*out':       'AudiodevPerDirectionOptions',
+    '*dev':       'str',
+    '*latency':   'uint32'} }
+
 ##
 # @AudiodevCoreaudioPerDirectionOptions:
 #
@@ -387,7 +409,7 @@
 ##
 { 'enum': 'AudiodevDriver',
   'data': [ 'none', 'alsa', 'coreaudio', 'dbus', 'dsound', 'jack', 'oss', 'pa',
-            'sdl', 'spice', 'wav' ] }
+            'sdl', 'sndio', 'spice', 'wav' ] }
 
 ##
 # @Audiodev:
@@ -418,5 +440,6 @@
     'oss':       'AudiodevOssOptions',
     'pa':        'AudiodevPaOptions',
     'sdl':       'AudiodevSdlOptions',
+    'sndio':     'AudiodevSndioOptions',
     'spice':     'AudiodevGenericOptions',
     'wav':       'AudiodevWavOptions' } }
diff --git a/qemu-options.hx b/qemu-options.hx
index d8b5ce5b4354..2ff06884f42d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -769,6 +769,9 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
     "-audiodev sdl,id=id[,prop[=value][,...]]\n"
     "                in|out.buffer-count= number of buffers\n"
 #endif
+#ifdef CONFIG_AUDIO_SNDIO
+    "-audiodev sndio,id=id[,prop[=value][,...]]\n"
+#endif
 #ifdef CONFIG_SPICE
     "-audiodev spice,id=id[,prop[=value][,...]]\n"
 #endif
@@ -935,6 +938,19 @@ SRST
     ``in|out.buffer-count=count``
         Sets the count of the buffers.
 
+``-audiodev sndio,id=id[,prop[=value][,...]]``
+    Creates a backend using SNDIO. This backend is available on
+    OpenBSD and most other Unix-like systems.
+
+    Sndio specific options are:
+
+    ``in|out.dev=device``
+        Specify the sndio device to use for input and/or output. Default
+        is ``default``.
+
+    ``in|out.latency=usecs``
+        Sets the desired period length in microseconds.
+
 ``-audiodev spice,id=id[,prop[=value][,...]]``
     Creates a backend that sends audio through SPICE. This backend
     requires ``-spice`` and automatically selected in that case, so
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 359b04e0e6d3..f08e3a8a7e02 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -1,7 +1,7 @@
 # This file is generated by meson-buildoptions.py, do not edit!
 meson_options_help() {
-  printf "%s\n" '  --audio-drv-list=CHOICES Set audio driver list [default] (choices:'
-  printf "%s\n" '                           alsa/coreaudio/default/dsound/jack/oss/pa/sdl)'
+  printf "%s\n" '  --audio-drv-list=CHOICES Set audio driver list [default] (choices: alsa/co'
+  printf "%s\n" '                           reaudio/default/dsound/jack/oss/pa/sdl/sndio)'
   printf "%s\n" '  --block-drv-ro-whitelist=VALUE'
   printf "%s\n" '                           set block driver read-only whitelist (by default'
   printf "%s\n" '                           affects only QEMU, not tools like qemu-img)'
@@ -144,6 +144,7 @@ meson_options_help() {
   printf "%s\n" '  slirp-smbd      use smbd (at path --smbd=*) in slirp networking'
   printf "%s\n" '  smartcard       CA smartcard emulation support'
   printf "%s\n" '  snappy          snappy compression support'
+  printf "%s\n" '  sndio           sndio sound support'
   printf "%s\n" '  sparse          sparse checker'
   printf "%s\n" '  spice           Spice server support'
   printf "%s\n" '  spice-protocol  Spice protocol support'
@@ -393,6 +394,8 @@ _meson_option_parse() {
     --disable-smartcard) printf "%s" -Dsmartcard=disabled ;;
     --enable-snappy) printf "%s" -Dsnappy=enabled ;;
     --disable-snappy) printf "%s" -Dsnappy=disabled ;;
+    --enable-sndio) printf "%s" -Dsndio=enabled ;;
+    --disable-sndio) printf "%s" -Dsndio=disabled ;;
     --enable-sparse) printf "%s" -Dsparse=enabled ;;
     --disable-sparse) printf "%s" -Dsparse=disabled ;;
     --sphinx-build=*) quote_sh "-Dsphinx_build=$2" ;;
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 22/25] Revert "audio: Log context for audio bug"
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (20 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 21/25] audio: Add sndio backend Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 23/25] audio: remove abort() in audio_bug() Gerd Hoffmann
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Volker Rümelin

From: Volker Rümelin <vr_qemu@t-online.de>

This reverts commit 8e30d39bade3010387177ca23dbc2244352ed4a3.

Revert commit 8e30d39bad "audio: Log context for audio bug"
to make error propagation work again.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20220917131626.7521-1-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio_template.h | 27 +++++++++++++++------------
 audio/audio.c          | 25 +++++++++++++------------
 2 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/audio/audio_template.h b/audio/audio_template.h
index 81860cea6202..98ab557684d8 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -59,13 +59,12 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
     if (audio_bug(__func__, !voice_size && max_voices)) {
         dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
                drv->name, max_voices);
-        abort();
+        glue (s->nb_hw_voices_, TYPE) = 0;
     }
 
     if (audio_bug(__func__, voice_size && !max_voices)) {
         dolog ("drv=`%s' voice_size=%d max_voices=0\n",
                drv->name, voice_size);
-        abort();
     }
 }
 
@@ -82,7 +81,6 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
         size_t samples = hw->samples;
         if (audio_bug(__func__, samples == 0)) {
             dolog("Attempted to allocate empty buffer\n");
-            abort();
         }
 
         HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples);
@@ -254,12 +252,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
 
     if (audio_bug(__func__, !drv)) {
         dolog ("No host audio driver\n");
-        abort();
+        return NULL;
     }
 
     if (audio_bug(__func__, !drv->pcm_ops)) {
         dolog ("Host audio driver without pcm_ops\n");
-        abort();
+        return NULL;
     }
 
     hw = audio_calloc(__func__, 1, glue(drv->voice_size_, TYPE));
@@ -277,13 +275,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
     QLIST_INIT (&hw->cap_head);
 #endif
     if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
-        g_free(hw);
-        return NULL;
+        goto err0;
     }
 
     if (audio_bug(__func__, hw->samples <= 0)) {
         dolog("hw->samples=%zd\n", hw->samples);
-        abort();
+        goto err1;
     }
 
     if (hw->info.is_float) {
@@ -312,6 +309,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
     audio_attach_capture (hw);
 #endif
     return hw;
+
+ err1:
+    glue (hw->pcm_ops->fini_, TYPE) (hw);
+ err0:
+    g_free (hw);
+    return NULL;
 }
 
 AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
@@ -434,7 +437,7 @@ void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
     if (sw) {
         if (audio_bug(__func__, !card)) {
             dolog ("card=%p\n", card);
-            abort();
+            return;
         }
 
         glue (audio_close_, TYPE) (sw);
@@ -456,7 +459,7 @@ SW *glue (AUD_open_, TYPE) (
     if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
         dolog ("card=%p name=%p callback_fn=%p as=%p\n",
                card, name, callback_fn, as);
-        abort();
+        goto fail;
     }
 
     s = card->state;
@@ -467,12 +470,12 @@ SW *glue (AUD_open_, TYPE) (
 
     if (audio_bug(__func__, audio_validate_settings(as))) {
         audio_print_settings (as);
-        abort();
+        goto fail;
     }
 
     if (audio_bug(__func__, !s->drv)) {
         dolog ("Can not open `%s' (no host audio driver)\n", name);
-        abort();
+        goto fail;
     }
 
     if (sw && audio_pcm_info_eq (&sw->info, as)) {
diff --git a/audio/audio.c b/audio/audio.c
index 5600593da043..d96a13055940 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -118,6 +118,7 @@ int audio_bug (const char *funcname, int cond)
             AUD_log (NULL, "I am sorry\n");
         }
         AUD_log (NULL, "Context:\n");
+        abort();
     }
 
     return cond;
@@ -138,7 +139,7 @@ static inline int audio_bits_to_index (int bits)
     default:
         audio_bug ("bits_to_index", 1);
         AUD_log (NULL, "invalid bits %d\n", bits);
-        abort();
+        return 0;
     }
 }
 
@@ -156,7 +157,7 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size)
         AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
                  funcname);
         AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
-        abort();
+        return NULL;
     }
 
     return g_malloc0 (len);
@@ -543,7 +544,7 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
     size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
     if (audio_bug(__func__, live > hw->conv_buf->size)) {
         dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
-        abort();
+        return 0;
     }
     return live;
 }
@@ -581,7 +582,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
     }
     if (audio_bug(__func__, live > hw->conv_buf->size)) {
         dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
-        abort();
+        return 0;
     }
 
     rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
@@ -656,7 +657,7 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
 
         if (audio_bug(__func__, live > hw->mix_buf->size)) {
             dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
-            abort();
+            return 0;
         }
         return live;
     }
@@ -706,7 +707,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
     live = sw->total_hw_samples_mixed;
     if (audio_bug(__func__, live > hwsamples)) {
         dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples);
-        abort();
+        return 0;
     }
 
     if (live == hwsamples) {
@@ -998,7 +999,7 @@ static size_t audio_get_avail (SWVoiceIn *sw)
     if (audio_bug(__func__, live > sw->hw->conv_buf->size)) {
         dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live,
               sw->hw->conv_buf->size);
-        abort();
+        return 0;
     }
 
     ldebug (
@@ -1028,7 +1029,7 @@ static size_t audio_get_free(SWVoiceOut *sw)
     if (audio_bug(__func__, live > sw->hw->mix_buf->size)) {
         dolog("live=%zu sw->hw->mix_buf->size=%zu\n", live,
               sw->hw->mix_buf->size);
-        abort();
+        return 0;
     }
 
     dead = sw->hw->mix_buf->size - live;
@@ -1170,7 +1171,7 @@ static void audio_run_out (AudioState *s)
 
         if (audio_bug(__func__, live > hw->mix_buf->size)) {
             dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
-            abort();
+            continue;
         }
 
         if (hw->pending_disable && !nb_live) {
@@ -1203,7 +1204,7 @@ static void audio_run_out (AudioState *s)
         if (audio_bug(__func__, hw->mix_buf->pos >= hw->mix_buf->size)) {
             dolog("hw->mix_buf->pos=%zu hw->mix_buf->size=%zu played=%zu\n",
                   hw->mix_buf->pos, hw->mix_buf->size, played);
-            abort();
+            hw->mix_buf->pos = 0;
         }
 
 #ifdef DEBUG_OUT
@@ -1223,7 +1224,7 @@ static void audio_run_out (AudioState *s)
             if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) {
                 dolog("played=%zu sw->total_hw_samples_mixed=%zu\n",
                       played, sw->total_hw_samples_mixed);
-                abort();
+                played = sw->total_hw_samples_mixed;
             }
 
             sw->total_hw_samples_mixed -= played;
@@ -1346,7 +1347,7 @@ static void audio_run_capture (AudioState *s)
             if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) {
                 dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n",
                       captured, sw->total_hw_samples_mixed);
-                abort();
+                captured = sw->total_hw_samples_mixed;
             }
 
             sw->total_hw_samples_mixed -= captured;
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 23/25] audio: remove abort() in audio_bug()
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (21 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 22/25] Revert "audio: Log context for audio bug" Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 24/25] hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638) Gerd Hoffmann
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Volker Rümelin

From: Volker Rümelin <vr_qemu@t-online.de>

Commit ab32b78cd1 "audio: Simplify audio_bug() removing old code"
introduced abort() in audio_bug() for regular builds.

audio_bug() was never meant to abort QEMU for the following
reasons.

  - There's code in audio_bug() that expects audio_bug() gets
    called more than once with error condition true. The variable
    'shown' is only 0 on first error.

  - All call sites test the return code of audio_bug(), print
    an error context message and handle the errror.

  - The abort() in audio_bug() enables a class of guest-triggered
    aborts similar to the Launchpad Bug #1910603 at
    https://bugs.launchpad.net/bugs/1910603.

Fixes: ab32b78cd1 "audio: Simplify audio_bug() removing old code"
Buglink: https://bugs.launchpad.net/bugs/1910603
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20220917131626.7521-2-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/audio/audio.c b/audio/audio.c
index d96a13055940..df6818ed5598 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -118,7 +118,6 @@ int audio_bug (const char *funcname, int cond)
             AUD_log (NULL, "I am sorry\n");
         }
         AUD_log (NULL, "Context:\n");
-        abort();
     }
 
     return cond;
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 24/25] hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638)
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (22 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 23/25] audio: remove abort() in audio_bug() Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-26  9:55 ` [PULL 25/25] virtio-gpu: update scanout if there is any area covered by the rect Gerd Hoffmann
  2022-09-27  1:12 ` [PULL 00/25] Kraxel 20220926 patches Stefan Hajnoczi
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth,
	Philippe Mathieu-Daudé,
	Qiang Liu, Mauro Matteo Cascella

From: Philippe Mathieu-Daudé <philmd@redhat.com>

When building QEMU with DEBUG_ATI defined then running with
'-device ati-vga,romfile="" -d unimp,guest_errors -trace ati\*'
we get:

  ati_mm_write 4 0x16c0 DP_CNTL <- 0x1
  ati_mm_write 4 0x146c DP_GUI_MASTER_CNTL <- 0x2
  ati_mm_write 4 0x16c8 DP_MIX <- 0xff0000
  ati_mm_write 4 0x16c4 DP_DATATYPE <- 0x2
  ati_mm_write 4 0x224 CRTC_OFFSET <- 0x0
  ati_mm_write 4 0x142c DST_PITCH_OFFSET <- 0xfe00000
  ati_mm_write 4 0x1420 DST_Y <- 0x3fff
  ati_mm_write 4 0x1410 DST_HEIGHT <- 0x3fff
  ati_mm_write 4 0x1588 DST_WIDTH_X <- 0x3fff3fff
  ati_2d_blt: vram:0x7fff5fa00000 addr:0 ds:0x7fff61273800 stride:2560 bpp:32 rop:0xff
  ati_2d_blt: 0 0 0, 0 127 0, (0,0) -> (16383,16383) 16383x16383 > ^
  ati_2d_blt: pixman_fill(dst:0x7fff5fa00000, stride:254, bpp:8, x:16383, y:16383, w:16383, h:16383, xor:0xff000000)
  Thread 3 "qemu-system-i38" received signal SIGSEGV, Segmentation fault.
  (gdb) bt
  #0  0x00007ffff7f62ce0 in sse2_fill.lto_priv () at /lib64/libpixman-1.so.0
  #1  0x00007ffff7f09278 in pixman_fill () at /lib64/libpixman-1.so.0
  #2  0x0000555557b5a9af in ati_2d_blt (s=0x631000028800) at hw/display/ati_2d.c:196
  #3  0x0000555557b4b5a2 in ati_mm_write (opaque=0x631000028800, addr=5512, data=1073692671, size=4) at hw/display/ati.c:843
  #4  0x0000555558b90ec4 in memory_region_write_accessor (mr=0x631000039cc0, addr=5512, ..., size=4, ...) at softmmu/memory.c:492

Commit 584acf34cb0 ("ati-vga: Fix reverse bit blts") introduced
the local dst_x and dst_y which adjust the (x, y) coordinates
depending on the direction in the SRCCOPY ROP3 operation, but
forgot to address the same issue for the PATCOPY, BLACKNESS and
WHITENESS operations, which also call pixman_fill().

Fix that now by using the adjusted coordinates in the pixman_fill
call, and update the related debug printf().

Reported-by: Qiang Liu <qiangliu@zju.edu.cn>
Fixes: 584acf34cb0 ("ati-vga: Fix reverse bit blts")
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Mauro Matteo Cascella <mcascell@redhat.com>
Message-Id: <20210906153103.1661195-1-philmd@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/ati_2d.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 4dc10ea79529..692bec91de45 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -84,7 +84,7 @@ void ati_2d_blt(ATIVGAState *s)
     DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n",
             s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset,
             s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch,
-            s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y,
+            s->regs.src_x, s->regs.src_y, dst_x, dst_y,
             s->regs.dst_width, s->regs.dst_height,
             (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? '>' : '<'),
             (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? 'v' : '^'));
@@ -180,11 +180,11 @@ void ati_2d_blt(ATIVGAState *s)
         dst_stride /= sizeof(uint32_t);
         DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
                 dst_bits, dst_stride, bpp,
-                s->regs.dst_x, s->regs.dst_y,
+                dst_x, dst_y,
                 s->regs.dst_width, s->regs.dst_height,
                 filler);
         pixman_fill((uint32_t *)dst_bits, dst_stride, bpp,
-                    s->regs.dst_x, s->regs.dst_y,
+                    dst_x, dst_y,
                     s->regs.dst_width, s->regs.dst_height,
                     filler);
         if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PULL 25/25] virtio-gpu: update scanout if there is any area covered by the rect
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (23 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 24/25] hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638) Gerd Hoffmann
@ 2022-09-26  9:55 ` Gerd Hoffmann
  2022-09-27  1:12 ` [PULL 00/25] Kraxel 20220926 patches Stefan Hajnoczi
  25 siblings, 0 replies; 34+ messages in thread
From: Gerd Hoffmann @ 2022-09-26  9:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eric Blake, Markus Armbruster, Gerd Hoffmann, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth, Dongwon Kim,
	Marc-André Lureau

From: Dongwon Kim <dongwon.kim@intel.com>

The scanout is currently updated only if the whole rect is inside the
scanout space. This is not a correct condition because the scanout should
be updated even a small area in the scanout space is covered by the rect.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220909014052.7297-1-dongwon.kim@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/virtio-gpu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 20cc703dcc6e..5e15c79b94a5 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -515,9 +515,10 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
         for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
             scanout = &g->parent_obj.scanout[i];
             if (scanout->resource_id == res->resource_id &&
-                rf.r.x >= scanout->x && rf.r.y >= scanout->y &&
-                rf.r.x + rf.r.width <= scanout->x + scanout->width &&
-                rf.r.y + rf.r.height <= scanout->y + scanout->height &&
+                rf.r.x < scanout->x + scanout->width &&
+                rf.r.x + rf.r.width >= scanout->x &&
+                rf.r.y < scanout->y + scanout->height &&
+                rf.r.y + rf.r.height >= scanout->y &&
                 console_has_gl(scanout->con)) {
                 dpy_gl_update(scanout->con, 0, 0, scanout->width,
                               scanout->height);
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2022-09-26  9:54 ` [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs Gerd Hoffmann
@ 2022-09-27  1:11   ` Stefan Hajnoczi
  2022-09-28 12:24     ` Qiang Liu
  0 siblings, 1 reply; 34+ messages in thread
From: Stefan Hajnoczi @ 2022-09-27  1:11 UTC (permalink / raw)
  To: Gerd Hoffmann, cyruscyliu
  Cc: qemu-devel, Eric Blake, Markus Armbruster, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

On Mon, 26 Sept 2022 at 06:29, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> From: Qiang Liu <cyruscyliu@gmail.com>
>
> I found an assertion failure in usb_cancel_packet() and posted my analysis in
> https://gitlab.com/qemu-project/qemu/-/issues/1180. I think this issue is
> because the inconsistency when resetting ohci root hubs.
>
> There are two ways to reset ohci root hubs: 1) through HcRhPortStatus, 2)
> through HcControl. However, when the packet's status is USB_PACKET_ASYNC,
> resetting through HcRhPortStatus will complete the packet and thus resetting
> through HcControl will fail. That is because IMO resetting through
> HcRhPortStatus should first detach the port and then invoked usb_device_reset()
> just like through HcControl. Therefore, I change usb_device_reset() to
> usb_port_reset() where usb_detach() and usb_device_reset() are invoked
> consequently.
>
> Fixes: d28f4e2d8631 ("usb: kill USB_MSG_RESET")
> Reported-by: Qiang Liu <cyruscyliu@gmail.com>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1180
> Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
> Message-Id: <20220830033022.1164961-1-cyruscyliu@gmail.com>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/usb/hcd-ohci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

This commit breaks boot-serial-test on ppc64-softmmu.

  $ ./configure --enable-tcg-interpreter
'--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
x86_64-softmmu'
  $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
./tests/qtest/boot-serial-test; cd -

(Yes, the full --target-list is needed because boot-serial-test isn't
built when only ppc64-softmmu is selected.)

Here is the CI failure:
https://gitlab.com/qemu-project/qemu/-/jobs/3087540972#L22

Stefan

>
> diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
> index 72bdde92617c..28d703481515 100644
> --- a/hw/usb/hcd-ohci.c
> +++ b/hw/usb/hcd-ohci.c
> @@ -1436,7 +1436,7 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
>
>      if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
>          trace_usb_ohci_port_reset(portnum);
> -        usb_device_reset(port->port.dev);
> +        usb_port_reset(&port->port);
>          port->ctrl &= ~OHCI_PORT_PRS;
>          /* ??? Should this also set OHCI_PORT_PESC.  */
>          port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
> --
> 2.37.3
>
>


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PULL 00/25] Kraxel 20220926 patches
  2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
                   ` (24 preceding siblings ...)
  2022-09-26  9:55 ` [PULL 25/25] virtio-gpu: update scanout if there is any area covered by the rect Gerd Hoffmann
@ 2022-09-27  1:12 ` Stefan Hajnoczi
  25 siblings, 0 replies; 34+ messages in thread
From: Stefan Hajnoczi @ 2022-09-27  1:12 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: qemu-devel, Eric Blake, Markus Armbruster, Bandan Das,
	Alexander Bulekov, Laurent Vivier, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

Hi Gerd,
I'm dropping this pull request because it breaks boot-serial-test for
ppc64-softmmu. See my reply to the "hcd-ohci: Fix inconsistency when
resetting ohci root hubs" patch for more info.

Stefan


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2022-09-27  1:11   ` Stefan Hajnoczi
@ 2022-09-28 12:24     ` Qiang Liu
  2023-02-15 13:45       ` Qiang Liu
  0 siblings, 1 reply; 34+ messages in thread
From: Qiang Liu @ 2022-09-28 12:24 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Gerd Hoffmann, qemu-devel, Eric Blake, Markus Armbruster,
	Bandan Das, Alexander Bulekov, Laurent Vivier, Darren Kenny,
	Qiuhao Li, Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

[-- Attachment #1: Type: text/plain, Size: 2734 bytes --]

Hi,

I will take over this and fix it

Best,
Qiang

On Tue, Sep 27, 2022 at 9:11 AM Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Mon, 26 Sept 2022 at 06:29, Gerd Hoffmann <kraxel@redhat.com> wrote:
> >
> > From: Qiang Liu <cyruscyliu@gmail.com>
> >
> > I found an assertion failure in usb_cancel_packet() and posted my
> analysis in
> > https://gitlab.com/qemu-project/qemu/-/issues/1180. I think this issue
> is
> > because the inconsistency when resetting ohci root hubs.
> >
> > There are two ways to reset ohci root hubs: 1) through HcRhPortStatus, 2)
> > through HcControl. However, when the packet's status is USB_PACKET_ASYNC,
> > resetting through HcRhPortStatus will complete the packet and thus
> resetting
> > through HcControl will fail. That is because IMO resetting through
> > HcRhPortStatus should first detach the port and then invoked
> usb_device_reset()
> > just like through HcControl. Therefore, I change usb_device_reset() to
> > usb_port_reset() where usb_detach() and usb_device_reset() are invoked
> > consequently.
> >
> > Fixes: d28f4e2d8631 ("usb: kill USB_MSG_RESET")
> > Reported-by: Qiang Liu <cyruscyliu@gmail.com>
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1180
> > Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
> > Message-Id: <20220830033022.1164961-1-cyruscyliu@gmail.com>
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> > ---
> >  hw/usb/hcd-ohci.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
>
> This commit breaks boot-serial-test on ppc64-softmmu.
>
>   $ ./configure --enable-tcg-interpreter
> '--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
> m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
> x86_64-softmmu'
>   $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
> ./tests/qtest/boot-serial-test; cd -
>
> (Yes, the full --target-list is needed because boot-serial-test isn't
> built when only ppc64-softmmu is selected.)
>
> Here is the CI failure:
> https://gitlab.com/qemu-project/qemu/-/jobs/3087540972#L22
>
> Stefan
>
> >
> > diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
> > index 72bdde92617c..28d703481515 100644
> > --- a/hw/usb/hcd-ohci.c
> > +++ b/hw/usb/hcd-ohci.c
> > @@ -1436,7 +1436,7 @@ static void ohci_port_set_status(OHCIState *ohci,
> int portnum, uint32_t val)
> >
> >      if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS))
> {
> >          trace_usb_ohci_port_reset(portnum);
> > -        usb_device_reset(port->port.dev);
> > +        usb_port_reset(&port->port);
> >          port->ctrl &= ~OHCI_PORT_PRS;
> >          /* ??? Should this also set OHCI_PORT_PESC.  */
> >          port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
> > --
> > 2.37.3
> >
> >
>

[-- Attachment #2: Type: text/html, Size: 4258 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2022-09-28 12:24     ` Qiang Liu
@ 2023-02-15 13:45       ` Qiang Liu
  2023-02-15 14:34         ` Stefan Hajnoczi
  2023-02-15 16:10         ` Laurent Vivier
  0 siblings, 2 replies; 34+ messages in thread
From: Qiang Liu @ 2023-02-15 13:45 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Gerd Hoffmann, qemu-devel, Eric Blake, Markus Armbruster,
	Bandan Das, Alexander Bulekov, Laurent Vivier, Darren Kenny,
	Qiuhao Li, Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

[-- Attachment #1: Type: text/plain, Size: 890 bytes --]

Hi,

> This commit breaks boot-serial-test on ppc64-softmmu.
>>
>>   $ ./configure --enable-tcg-interpreter
>> '--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
>> m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
>> x86_64-softmmu'
>>   $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
>> ./tests/qtest/boot-serial-test; cd -
>>
>> (Yes, the full --target-list is needed because boot-serial-test isn't
>> built when only ppc64-softmmu is selected.)
>>
>> Here is the CI failure:
>> https://gitlab.com/qemu-project/qemu/-/jobs/3087540972#L22
>
>  I reproduced this failure and got "Out of malloc memory" error message in
the [openbios-ppc](
https://github.com/openbios/openbios/blob/4a0041107b8ef77e0e8337bfcb5f8078887261a7/libopenbios/ofmem_common.c#L134).
However, I'm not sure how to debug this. Have you run into this issue
before?

Best,
Qiang

[-- Attachment #2: Type: text/html, Size: 1618 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2023-02-15 13:45       ` Qiang Liu
@ 2023-02-15 14:34         ` Stefan Hajnoczi
  2023-02-15 16:28           ` Laurent Vivier
  2023-02-15 16:10         ` Laurent Vivier
  1 sibling, 1 reply; 34+ messages in thread
From: Stefan Hajnoczi @ 2023-02-15 14:34 UTC (permalink / raw)
  To: Qiang Liu
  Cc: Gerd Hoffmann, qemu-devel, Eric Blake, Markus Armbruster,
	Bandan Das, Alexander Bulekov, Laurent Vivier, Darren Kenny,
	Qiuhao Li, Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

On Wed, 15 Feb 2023 at 08:45, Qiang Liu <cyruscyliu@gmail.com> wrote:
>
> Hi,
>>>
>>> This commit breaks boot-serial-test on ppc64-softmmu.
>>>
>>>   $ ./configure --enable-tcg-interpreter
>>> '--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
>>> m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
>>> x86_64-softmmu'
>>>   $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
>>> ./tests/qtest/boot-serial-test; cd -
>>>
>>> (Yes, the full --target-list is needed because boot-serial-test isn't
>>> built when only ppc64-softmmu is selected.)
>>>
>>> Here is the CI failure:
>>> https://gitlab.com/qemu-project/qemu/-/jobs/3087540972#L22
>
>  I reproduced this failure and got "Out of malloc memory" error message in the [openbios-ppc](https://github.com/openbios/openbios/blob/4a0041107b8ef77e0e8337bfcb5f8078887261a7/libopenbios/ofmem_common.c#L134). However, I'm not sure how to debug this. Have you run into this issue before?

I don't. Maybe Gerd has an idea?

The memory allocation may be because there is either a request leak or
additional USB activity as a result of this patch.

Stefan


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2023-02-15 13:45       ` Qiang Liu
  2023-02-15 14:34         ` Stefan Hajnoczi
@ 2023-02-15 16:10         ` Laurent Vivier
  1 sibling, 0 replies; 34+ messages in thread
From: Laurent Vivier @ 2023-02-15 16:10 UTC (permalink / raw)
  To: Qiang Liu, Stefan Hajnoczi
  Cc: Gerd Hoffmann, qemu-devel, Eric Blake, Markus Armbruster,
	Bandan Das, Alexander Bulekov, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

On 2/15/23 14:45, Qiang Liu wrote:
> Hi,
> 
>         This commit breaks boot-serial-test on ppc64-softmmu.
> 
>            $ ./configure --enable-tcg-interpreter
>         '--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
>         m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
>         x86_64-softmmu'
>            $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
>         ./tests/qtest/boot-serial-test; cd -
> 
>         (Yes, the full --target-list is needed because boot-serial-test isn't
>         built when only ppc64-softmmu is selected.)
> 

I think we need something like this :

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index e97616d327c0..8203f6a71ad0 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -149,8 +149,8 @@ qtests_ppc = \
    qtests_filter + \
    (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + 
     \
    (config_all_devices.has_key('CONFIG_M48T59') ? ['m48t59-test'] : []) + 
     \
-  (config_all_devices.has_key('CONFIG_TCG') ? ['prom-env-test'] : []) + 
    \
-  (config_all_devices.has_key('CONFIG_TCG') ? ['boot-serial-test'] : []) + 
    \
+  (config_host.has_key('CONFIG_TCG') ? ['prom-env-test'] : []) +                      \
+  (config_host.has_key('CONFIG_TCG') ? ['boot-serial-test'] : []) +                   \
    ['boot-order-test']

  qtests_ppc64 = \

Thanks,
Laurent



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2023-02-15 14:34         ` Stefan Hajnoczi
@ 2023-02-15 16:28           ` Laurent Vivier
  2023-02-15 17:05             ` BALATON Zoltan
  0 siblings, 1 reply; 34+ messages in thread
From: Laurent Vivier @ 2023-02-15 16:28 UTC (permalink / raw)
  To: Qiang Liu, BALATON Zoltan
  Cc: Gerd Hoffmann, qemu-devel, Eric Blake, Markus Armbruster,
	Bandan Das, Alexander Bulekov, Darren Kenny, Qiuhao Li,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

On 2/15/23 15:34, Stefan Hajnoczi wrote:
> On Wed, 15 Feb 2023 at 08:45, Qiang Liu <cyruscyliu@gmail.com> wrote:
>>
>> Hi,
>>>>
>>>> This commit breaks boot-serial-test on ppc64-softmmu.
>>>>
>>>>    $ ./configure --enable-tcg-interpreter
>>>> '--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
>>>> m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
>>>> x86_64-softmmu'
>>>>    $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
>>>> ./tests/qtest/boot-serial-test; cd -
>>>>
>>>> (Yes, the full --target-list is needed because boot-serial-test isn't
>>>> built when only ppc64-softmmu is selected.)
>>>>
>>>> Here is the CI failure:
>>>> https://gitlab.com/qemu-project/qemu/-/jobs/3087540972#L22
>>
>>   I reproduced this failure and got "Out of malloc memory" error message in the [openbios-ppc](https://github.com/openbios/openbios/blob/4a0041107b8ef77e0e8337bfcb5f8078887261a7/libopenbios/ofmem_common.c#L134). However, I'm not sure how to debug this. Have you run into this issue before?
> 
> I don't. Maybe Gerd has an idea?
> 
> The memory allocation may be because there is either a request leak or
> additional USB activity as a result of this patch.

It looks like a bug in openbios ohci, perhaps Zoltan can help?

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs
  2023-02-15 16:28           ` Laurent Vivier
@ 2023-02-15 17:05             ` BALATON Zoltan
  0 siblings, 0 replies; 34+ messages in thread
From: BALATON Zoltan @ 2023-02-15 17:05 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: Qiang Liu, Gerd Hoffmann, qemu-devel, Eric Blake,
	Markus Armbruster, Bandan Das, Alexander Bulekov, Darren Kenny,
	Qiuhao Li, Paolo Bonzini, Philippe Mathieu-Daudé,
	Akihiko Odaki, Michael S. Tsirkin, Alexandre Ratchov,
	Peter Maydell, Stefan Hajnoczi, Thomas Huth

On Wed, 15 Feb 2023, Laurent Vivier wrote:
> On 2/15/23 15:34, Stefan Hajnoczi wrote:
>> On Wed, 15 Feb 2023 at 08:45, Qiang Liu <cyruscyliu@gmail.com> wrote:
>>> 
>>> Hi,
>>>>> 
>>>>> This commit breaks boot-serial-test on ppc64-softmmu.
>>>>>
>>>>>    $ ./configure --enable-tcg-interpreter
>>>>> '--target-list=aarch64-softmmu alpha-softmmu arm-softmmu hppa-softmmu
>>>>> m68k-softmmu microblaze-softmmu ppc64-softmmu s390x-softmmu
>>>>> x86_64-softmmu'
>>>>>    $ make && cd build && QTEST_QEMU_BINARY=./qemu-system-ppc64
>>>>> ./tests/qtest/boot-serial-test; cd -
>>>>> 
>>>>> (Yes, the full --target-list is needed because boot-serial-test isn't
>>>>> built when only ppc64-softmmu is selected.)
>>>>> 
>>>>> Here is the CI failure:
>>>>> https://gitlab.com/qemu-project/qemu/-/jobs/3087540972#L22
>>>
>>>   I reproduced this failure and got "Out of malloc memory" error message 
>>> in the 
>>> [openbios-ppc](https://github.com/openbios/openbios/blob/4a0041107b8ef77e0e8337bfcb5f8078887261a7/libopenbios/ofmem_common.c#L134). 
>>> However, I'm not sure how to debug this. Have you run into this issue 
>>> before?
>> 
>> I don't. Maybe Gerd has an idea?
>> 
>> The memory allocation may be because there is either a request leak or
>> additional USB activity as a result of this patch.
>
> It looks like a bug in openbios ohci, perhaps Zoltan can help?

Unfortunately I don't quite understand neither what this thread is about 
nor that openbios driver. Even though I've added that to openbios, all I 
did was porting the driver from coreboot's libpayload as noted in the 
copyright message of that file. So if you suspect it's a bug there you 
could try checking newer versions in libpayload and see if they've fixed 
anything that could help. On the other hand the OHCI emulation in QEMU is 
known to be incomplete and likely to have some bugs with guests that work 
on real hardware (e.g. MacOS <= 10.1) so it's more likely that QEMU 
behaves differently than it should assuming that the coreboot driver works 
on real hardware but I'm not sure about that either.

Regards,
BALATON Zoltan


^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2023-02-15 17:08 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-26  9:54 [PULL 00/25] Kraxel 20220926 patches Gerd Hoffmann
2022-09-26  9:54 ` [PULL 01/25] ui/console: Get tab completion working again in the SDL monitor vc Gerd Hoffmann
2022-09-26  9:54 ` [PULL 02/25] ui/cocoa: Run qemu_init in the main thread Gerd Hoffmann
2022-09-26  9:54 ` [PULL 03/25] Revert "main-loop: Disable block backend global state assertion on Cocoa" Gerd Hoffmann
2022-09-26  9:54 ` [PULL 04/25] meson: Allow to enable gtk and sdl while cocoa is enabled Gerd Hoffmann
2022-09-26  9:54 ` [PULL 05/25] ui: add some vdagent related traces Gerd Hoffmann
2022-09-26  9:54 ` [PULL 06/25] ui/clipboard: fix serial priority Gerd Hoffmann
2022-09-26  9:54 ` [PULL 07/25] ui/vdagent: always reset the clipboard serial on caps Gerd Hoffmann
2022-09-26  9:54 ` [PULL 08/25] ui/clipboard: reset the serial state on reset Gerd Hoffmann
2022-09-26  9:54 ` [PULL 09/25] ui/vdagent: fix serial reset of guest agent Gerd Hoffmann
2022-09-26  9:54 ` [PULL 10/25] ui/console: fix three double frees in png_save() Gerd Hoffmann
2022-09-26  9:54 ` [PULL 11/25] hw/usb/hcd-xhci: Check whether DMA accesses fail Gerd Hoffmann
2022-09-26  9:54 ` [PULL 12/25] hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is zero Gerd Hoffmann
2022-09-26  9:54 ` [PULL 13/25] hcd-ohci: Fix inconsistency when resetting ohci root hubs Gerd Hoffmann
2022-09-27  1:11   ` Stefan Hajnoczi
2022-09-28 12:24     ` Qiang Liu
2023-02-15 13:45       ` Qiang Liu
2023-02-15 14:34         ` Stefan Hajnoczi
2023-02-15 16:28           ` Laurent Vivier
2023-02-15 17:05             ` BALATON Zoltan
2023-02-15 16:10         ` Laurent Vivier
2022-09-26  9:54 ` [PULL 14/25] usb/msd: move usb_msd_packet_complete() Gerd Hoffmann
2022-09-26  9:54 ` [PULL 15/25] usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert Gerd Hoffmann
2022-09-26  9:55 ` [PULL 16/25] hcd-xhci: drop operation with secondary stream arrays enabled Gerd Hoffmann
2022-09-26  9:55 ` [PULL 17/25] usbnet: Add missing usb_wakeup() call in usbnet_receive() Gerd Hoffmann
2022-09-26  9:55 ` [PULL 18/25] usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request Gerd Hoffmann
2022-09-26  9:55 ` [PULL 19/25] usbnet: Detect short packets as sent by the xHCI controller Gerd Hoffmann
2022-09-26  9:55 ` [PULL 20/25] usbnet: Report link-up via interrupt endpoint in CDC-ECM mode Gerd Hoffmann
2022-09-26  9:55 ` [PULL 21/25] audio: Add sndio backend Gerd Hoffmann
2022-09-26  9:55 ` [PULL 22/25] Revert "audio: Log context for audio bug" Gerd Hoffmann
2022-09-26  9:55 ` [PULL 23/25] audio: remove abort() in audio_bug() Gerd Hoffmann
2022-09-26  9:55 ` [PULL 24/25] hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638) Gerd Hoffmann
2022-09-26  9:55 ` [PULL 25/25] virtio-gpu: update scanout if there is any area covered by the rect Gerd Hoffmann
2022-09-27  1:12 ` [PULL 00/25] Kraxel 20220926 patches Stefan Hajnoczi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).