aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-13 12:40:36 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-11-13 12:40:36 +0000
commit6980c128b5cbc1d2a1b85609bb4d1e006e65109e (patch)
tree9f88709c355aa38b91e18dafdb18f1fbf25e3bb6
parentbe2df2ac6f6b9eeee21cc057de0a119ac30fbc60 (diff)
parent172bc8520db1cb98d09b367360068a675fbc9413 (diff)
downloadqemu-6980c128b5cbc1d2a1b85609bb4d1e006e65109e.zip
qemu-6980c128b5cbc1d2a1b85609bb4d1e006e65109e.tar.gz
qemu-6980c128b5cbc1d2a1b85609bb4d1e006e65109e.tar.bz2
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20201113-pull-request' into staging
fixes for console, audio, usb, vga. # gpg: Signature made Fri 13 Nov 2020 12:29:44 GMT # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/fixes-20201113-pull-request: xhci: fix nec-usb-xhci properties hw/display/cirrus_vga: Fix hexadecimal format string specifier hw/display/cirrus_vga: Remove debugging code commented out hw/usb/Kconfig: Fix USB_XHCI_NEC (depends on USB_XHCI_PCI) console: avoid passing con=NULL to graphic_hw_update_done() audio/jack: fix use after free segfault Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--audio/jackaudio.c50
-rw-r--r--hw/display/cirrus_vga.c20
-rw-r--r--hw/usb/Kconfig3
-rw-r--r--hw/usb/hcd-xhci-nec.c31
-rw-r--r--ui/console.c5
5 files changed, 68 insertions, 41 deletions
diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 1e714b3..3b7c184 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/atomic.h"
+#include "qemu/main-loop.h"
#include "qemu-common.h"
#include "audio.h"
@@ -63,6 +64,7 @@ typedef struct QJackClient {
QJackState state;
jack_client_t *client;
jack_nframes_t freq;
+ QEMUBH *shutdown_bh;
struct QJack *j;
int nchannels;
@@ -87,6 +89,7 @@ QJackIn;
static int qjack_client_init(QJackClient *c);
static void qjack_client_connect_ports(QJackClient *c);
static void qjack_client_fini(QJackClient *c);
+static QemuMutex qjack_shutdown_lock;
static void qjack_buffer_create(QJackBuffer *buffer, int channels, int frames)
{
@@ -306,21 +309,27 @@ static int qjack_xrun(void *arg)
return 0;
}
+static void qjack_shutdown_bh(void *opaque)
+{
+ QJackClient *c = (QJackClient *)opaque;
+ qjack_client_fini(c);
+}
+
static void qjack_shutdown(void *arg)
{
QJackClient *c = (QJackClient *)arg;
c->state = QJACK_STATE_SHUTDOWN;
+ qemu_bh_schedule(c->shutdown_bh);
}
static void qjack_client_recover(QJackClient *c)
{
- if (c->state == QJACK_STATE_SHUTDOWN) {
- qjack_client_fini(c);
+ if (c->state != QJACK_STATE_DISCONNECTED) {
+ return;
}
/* packets is used simply to throttle this */
- if (c->state == QJACK_STATE_DISCONNECTED &&
- c->packets % 100 == 0) {
+ if (c->packets % 100 == 0) {
/* if enabled then attempt to recover */
if (c->enabled) {
@@ -489,15 +498,16 @@ static int qjack_init_out(HWVoiceOut *hw, struct audsettings *as,
QJackOut *jo = (QJackOut *)hw;
Audiodev *dev = (Audiodev *)drv_opaque;
- qjack_client_fini(&jo->c);
-
jo->c.out = true;
jo->c.enabled = false;
jo->c.nchannels = as->nchannels;
jo->c.opt = dev->u.jack.out;
+ jo->c.shutdown_bh = qemu_bh_new(qjack_shutdown_bh, &jo->c);
+
int ret = qjack_client_init(&jo->c);
if (ret != 0) {
+ qemu_bh_delete(jo->c.shutdown_bh);
return ret;
}
@@ -525,15 +535,16 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings *as,
QJackIn *ji = (QJackIn *)hw;
Audiodev *dev = (Audiodev *)drv_opaque;
- qjack_client_fini(&ji->c);
-
ji->c.out = false;
ji->c.enabled = false;
ji->c.nchannels = as->nchannels;
ji->c.opt = dev->u.jack.in;
+ ji->c.shutdown_bh = qemu_bh_new(qjack_shutdown_bh, &ji->c);
+
int ret = qjack_client_init(&ji->c);
if (ret != 0) {
+ qemu_bh_delete(ji->c.shutdown_bh);
return ret;
}
@@ -555,7 +566,7 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings *as,
return 0;
}
-static void qjack_client_fini(QJackClient *c)
+static void qjack_client_fini_locked(QJackClient *c)
{
switch (c->state) {
case QJACK_STATE_RUNNING:
@@ -564,28 +575,40 @@ static void qjack_client_fini(QJackClient *c)
case QJACK_STATE_SHUTDOWN:
jack_client_close(c->client);
+ c->client = NULL;
+
+ qjack_buffer_free(&c->fifo);
+ g_free(c->port);
+
+ c->state = QJACK_STATE_DISCONNECTED;
/* fallthrough */
case QJACK_STATE_DISCONNECTED:
break;
}
+}
- qjack_buffer_free(&c->fifo);
- g_free(c->port);
-
- c->state = QJACK_STATE_DISCONNECTED;
+static void qjack_client_fini(QJackClient *c)
+{
+ qemu_mutex_lock(&qjack_shutdown_lock);
+ qjack_client_fini_locked(c);
+ qemu_mutex_unlock(&qjack_shutdown_lock);
}
static void qjack_fini_out(HWVoiceOut *hw)
{
QJackOut *jo = (QJackOut *)hw;
qjack_client_fini(&jo->c);
+
+ qemu_bh_delete(jo->c.shutdown_bh);
}
static void qjack_fini_in(HWVoiceIn *hw)
{
QJackIn *ji = (QJackIn *)hw;
qjack_client_fini(&ji->c);
+
+ qemu_bh_delete(ji->c.shutdown_bh);
}
static void qjack_enable_out(HWVoiceOut *hw, bool enable)
@@ -662,6 +685,7 @@ static void qjack_info(const char *msg)
static void register_audio_jack(void)
{
+ qemu_mutex_init(&qjack_shutdown_lock);
audio_driver_register(&jack_driver);
jack_set_thread_creator(qjack_thread_creator);
jack_set_error_function(qjack_error);
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 722b9e7..fdca6ca 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2105,7 +2105,7 @@ static void cirrus_vga_mem_write(void *opaque,
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"cirrus: mem_writeb 0x" TARGET_FMT_plx " "
- "value 0x%02" PRIu64 "\n", addr, mem_value);
+ "value 0x%02" PRIx64 "\n", addr, mem_value);
}
}
@@ -2532,9 +2532,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
case 0x3c5:
val = cirrus_vga_read_sr(c);
break;
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
break;
case 0x3c6:
val = cirrus_read_hidden_dac(c);
@@ -2560,9 +2557,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
break;
case 0x3cf:
val = cirrus_vga_read_gr(c, s->gr_index);
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
break;
case 0x3b4:
case 0x3d4:
@@ -2571,9 +2565,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
case 0x3b5:
case 0x3d5:
val = cirrus_vga_read_cr(c, s->cr_index);
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
break;
case 0x3ba:
case 0x3da:
@@ -2645,9 +2636,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
s->sr_index = val;
break;
case 0x3c5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02" PRIu64 "\n", s->sr_index, val);
-#endif
cirrus_vga_write_sr(c, val);
break;
case 0x3c6:
@@ -2670,9 +2658,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
s->gr_index = val;
break;
case 0x3cf:
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02" PRIu64 "\n", s->gr_index, val);
-#endif
cirrus_vga_write_gr(c, s->gr_index, val);
break;
case 0x3b4:
@@ -2681,9 +2666,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
break;
case 0x3b5:
case 0x3d5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02"PRIu64"\n", s->cr_index, val);
-#endif
cirrus_vga_write_cr(c, val);
break;
case 0x3ba:
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index a674ce4..3b07d9c 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -43,8 +43,7 @@ config USB_XHCI_PCI
config USB_XHCI_NEC
bool
default y if PCI_DEVICES
- depends on PCI
- select USB_XHCI
+ select USB_XHCI_PCI
config USB_XHCI_SYSBUS
bool
diff --git a/hw/usb/hcd-xhci-nec.c b/hw/usb/hcd-xhci-nec.c
index 5707b2c..13a125a 100644
--- a/hw/usb/hcd-xhci-nec.c
+++ b/hw/usb/hcd-xhci-nec.c
@@ -27,18 +27,37 @@
#include "hcd-xhci-pci.h"
+typedef struct XHCINecState {
+ /*< private >*/
+ XHCIPciState parent_obj;
+ /*< public >*/
+ uint32_t flags;
+ uint32_t intrs;
+ uint32_t slots;
+} XHCINecState;
+
static Property nec_xhci_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("msi", XHCIPciState, msi, ON_OFF_AUTO_AUTO),
DEFINE_PROP_ON_OFF_AUTO("msix", XHCIPciState, msix, ON_OFF_AUTO_AUTO),
- DEFINE_PROP_BIT("superspeed-ports-first", XHCIPciState,
- xhci.flags, XHCI_FLAG_SS_FIRST, true),
- DEFINE_PROP_BIT("force-pcie-endcap", XHCIPciState, xhci.flags,
+ DEFINE_PROP_BIT("superspeed-ports-first", XHCINecState, flags,
+ XHCI_FLAG_SS_FIRST, true),
+ DEFINE_PROP_BIT("force-pcie-endcap", XHCINecState, flags,
XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
- DEFINE_PROP_UINT32("intrs", XHCIPciState, xhci.numintrs, XHCI_MAXINTRS),
- DEFINE_PROP_UINT32("slots", XHCIPciState, xhci.numslots, XHCI_MAXSLOTS),
+ DEFINE_PROP_UINT32("intrs", XHCINecState, intrs, XHCI_MAXINTRS),
+ DEFINE_PROP_UINT32("slots", XHCINecState, slots, XHCI_MAXSLOTS),
DEFINE_PROP_END_OF_LIST(),
};
+static void nec_xhci_instance_init(Object *obj)
+{
+ XHCIPciState *pci = XHCI_PCI(obj);
+ XHCINecState *nec = container_of(pci, XHCINecState, parent_obj);
+
+ pci->xhci.flags = nec->flags;
+ pci->xhci.numintrs = nec->intrs;
+ pci->xhci.numslots = nec->slots;
+}
+
static void nec_xhci_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -53,6 +72,8 @@ static void nec_xhci_class_init(ObjectClass *klass, void *data)
static const TypeInfo nec_xhci_info = {
.name = TYPE_NEC_XHCI,
.parent = TYPE_XHCI_PCI,
+ .instance_size = sizeof(XHCINecState),
+ .instance_init = nec_xhci_instance_init,
.class_init = nec_xhci_class_init,
};
diff --git a/ui/console.c b/ui/console.c
index e8e5970..e07d2c3 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -270,10 +270,11 @@ void graphic_hw_update_done(QemuConsole *con)
void graphic_hw_update(QemuConsole *con)
{
bool async = false;
+ con = con ? con : active_console;
if (!con) {
- con = active_console;
+ return;
}
- if (con && con->hw_ops->gfx_update) {
+ if (con->hw_ops->gfx_update) {
con->hw_ops->gfx_update(con->hw);
async = con->hw_ops->gfx_update_async;
}