qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter
@ 2015-03-18  9:33 arei.gonglei
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 1/3] uhci: fix segfault when hot-unplugging uhci controller arei.gonglei
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: arei.gonglei @ 2015-03-18  9:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-stable, Gonglei, peter.huangpeng, kraxel

From: Gonglei <arei.gonglei@huawei.com>

When hot-unplugging the usb controllers (ehci/uhci),
we have to clean all resouce of these devices,
involved registered reset handler. Otherwise, it
may cause NULL pointer access and/or segmentation fault
if we reboot the guest os after hot-unplugging.
    
Let's hook up reset via DeviceClass->reset() and drop
the qemu_register_reset() call. Then Qemu will register
and unregister the reset handler automatically.

Cc: qemu-stable <qemu-stable@nongnu.org>

v4 -> v3:
 - add reset hookup for sysbus devices (ehci/ohci). (Gerd)

v2 -> v3:
 - rewrite each patch's title

v1 -> v2:
 - hooking up reset via DeviceClass->reset 
 and drop the qemu_register_reset() calls.   (Gerd)

Gonglei (3):
  uhci: fix segfault when hot-unplugging uhci controller
  ehci: fix segfault when hot-unplugging ehci controller
  ohci: fix resource cleanup leak

 hw/usb/hcd-ehci-pci.c    | 10 ++++++++++
 hw/usb/hcd-ehci-sysbus.c | 10 ++++++++++
 hw/usb/hcd-ehci.c        |  3 +--
 hw/usb/hcd-ehci.h        |  1 +
 hw/usb/hcd-ohci.c        | 20 +++++++++++++++++++-
 hw/usb/hcd-uhci.c        | 12 ++++++------
 6 files changed, 47 insertions(+), 9 deletions(-)

-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 1/3] uhci: fix segfault when hot-unplugging uhci controller
  2015-03-18  9:33 [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter arei.gonglei
@ 2015-03-18  9:33 ` arei.gonglei
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 2/3] ehci: fix segfault when hot-unplugging ehci controller arei.gonglei
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: arei.gonglei @ 2015-03-18  9:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-stable, Gonglei, peter.huangpeng, kraxel

From: Gonglei <arei.gonglei@huawei.com>

When hot-unplugging the usb controllers (ehci/uhci),
we have to clean all resouce of these devices,
involved registered reset handler. Otherwise, it
may cause NULL pointer access and/or segmentation fault
if we reboot the guest os after hot-unplugging.

Let's hook up reset via DeviceClass->reset() and drop
the qemu_register_reset() call. Then Qemu will register
and unregister the reset handler automatically.

Cc: qemu-stable <qemu-stable@nongnu.org>
Reported-by: Lidonglin <lidonglin@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/usb/hcd-uhci.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index f903de7..d8f0577 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -348,9 +348,10 @@ static void uhci_update_irq(UHCIState *s)
     pci_set_irq(&s->dev, level);
 }
 
-static void uhci_reset(void *opaque)
+static void uhci_reset(DeviceState *dev)
 {
-    UHCIState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(dev);
+    UHCIState *s = DO_UPCAST(UHCIState, dev, d);
     uint8_t *pci_conf;
     int i;
     UHCIPort *port;
@@ -454,11 +455,11 @@ static void uhci_port_write(void *opaque, hwaddr addr,
                 port = &s->ports[i];
                 usb_device_reset(port->port.dev);
             }
-            uhci_reset(s);
+            uhci_reset(DEVICE(s));
             return;
         }
         if (val & UHCI_CMD_HCRESET) {
-            uhci_reset(s);
+            uhci_reset(DEVICE(s));
             return;
         }
         s->cmd = val;
@@ -1226,8 +1227,6 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
     s->num_ports_vmstate = NB_PORTS;
     QTAILQ_INIT(&s->queues);
 
-    qemu_register_reset(uhci_reset, s);
-
     memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
                           "uhci", 0x20);
 
@@ -1303,6 +1302,7 @@ static void uhci_class_init(ObjectClass *klass, void *data)
     k->revision  = info->revision;
     k->class_id  = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
+    dc->reset = uhci_reset;
     if (!info->unplug) {
         /* uhci controllers in companion setups can't be hotplugged */
         dc->hotpluggable = false;
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 2/3] ehci: fix segfault when hot-unplugging ehci controller
  2015-03-18  9:33 [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter arei.gonglei
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 1/3] uhci: fix segfault when hot-unplugging uhci controller arei.gonglei
@ 2015-03-18  9:33 ` arei.gonglei
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 3/3] ohci: fix resource cleanup leak arei.gonglei
  2015-03-18 11:46 ` [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter Gerd Hoffmann
  3 siblings, 0 replies; 5+ messages in thread
From: arei.gonglei @ 2015-03-18  9:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-stable, Gonglei, peter.huangpeng, kraxel

From: Gonglei <arei.gonglei@huawei.com>

When hot-unplugging the usb controllers (ehci/uhci),
we have to clean all resouce of these devices,
involved registered reset handler. Otherwise, it
may cause NULL pointer access and/or segmentation fault
if we reboot the guest os after hot-unplugging.

Let's hook up reset via DeviceClass->reset() and drop
the qemu_register_reset() call. Then Qemu will register
and unregister the reset handler automatically.

Cc: qemu-stable <qemu-stable@nongnu.org>
Reported-by: Lidonglin <lidonglin@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/usb/hcd-ehci-pci.c    | 10 ++++++++++
 hw/usb/hcd-ehci-sysbus.c | 10 ++++++++++
 hw/usb/hcd-ehci.c        |  3 +--
 hw/usb/hcd-ehci.h        |  1 +
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 4c80707..7afa5f9 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -101,6 +101,15 @@ static void usb_ehci_pci_exit(PCIDevice *dev)
     }
 }
 
+static void usb_ehci_pci_reset(DeviceState *dev)
+{
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
+    EHCIPCIState *i = PCI_EHCI(pci_dev);
+    EHCIState *s = &i->ehci;
+
+    ehci_reset(s);
+}
+
 static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr,
                                       uint32_t val, int l)
 {
@@ -143,6 +152,7 @@ static void ehci_class_init(ObjectClass *klass, void *data)
     k->config_write = usb_ehci_pci_write_config;
     dc->vmsd = &vmstate_ehci_pci;
     dc->props = ehci_pci_properties;
+    dc->reset = usb_ehci_pci_reset;
 }
 
 static const TypeInfo ehci_pci_type_info = {
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index 19ed2c2..cd1cc14 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -42,6 +42,15 @@ static void usb_ehci_sysbus_realize(DeviceState *dev, Error **errp)
     sysbus_init_irq(d, &s->irq);
 }
 
+static void usb_ehci_sysbus_reset(DeviceState *dev)
+{
+    SysBusDevice *d = SYS_BUS_DEVICE(dev);
+    EHCISysBusState *i = SYS_BUS_EHCI(d);
+    EHCIState *s = &i->ehci;
+
+    ehci_reset(s);
+}
+
 static void ehci_sysbus_init(Object *obj)
 {
     SysBusDevice *d = SYS_BUS_DEVICE(obj);
@@ -70,6 +79,7 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data)
     dc->realize = usb_ehci_sysbus_realize;
     dc->vmsd = &vmstate_ehci_sysbus;
     dc->props = ehci_sysbus_properties;
+    dc->reset = usb_ehci_sysbus_reset;
     set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index ccf54b6..2a84f46 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -845,7 +845,7 @@ static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr)
 }
 
 /* 4.1 host controller initialization */
-static void ehci_reset(void *opaque)
+void ehci_reset(void *opaque)
 {
     EHCIState *s = opaque;
     int i;
@@ -2471,7 +2471,6 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
     s->async_bh = qemu_bh_new(ehci_frame_timer, s);
     s->device = dev;
 
-    qemu_register_reset(ehci_reset, s);
     s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
 }
 
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 2bc259c..87b240f 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -325,6 +325,7 @@ extern const VMStateDescription vmstate_ehci;
 void usb_ehci_init(EHCIState *s, DeviceState *dev);
 void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
 void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp);
+void ehci_reset(void *opaque);
 
 #define TYPE_PCI_EHCI "pci-ehci-usb"
 #define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI)
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 3/3] ohci: fix resource cleanup leak
  2015-03-18  9:33 [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter arei.gonglei
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 1/3] uhci: fix segfault when hot-unplugging uhci controller arei.gonglei
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 2/3] ehci: fix segfault when hot-unplugging ehci controller arei.gonglei
@ 2015-03-18  9:33 ` arei.gonglei
  2015-03-18 11:46 ` [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter Gerd Hoffmann
  3 siblings, 0 replies; 5+ messages in thread
From: arei.gonglei @ 2015-03-18  9:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-stable, Gonglei, peter.huangpeng, kraxel

From: Gonglei <arei.gonglei@huawei.com>

When hot-unplugging the usb controllers (ehci/uhci),
we have to clean all resouce of these devices,
involved registered reset handler. Otherwise, it
may cause NULL pointer access and/or segmentation fault
if we reboot the guest os after hot-unplugging.

Let's hook up reset via DeviceClass->reset() and drop
the qemu_register_reset() call. Then Qemu will register
and unregister the reset handler automatically.

Ohci does't support hotplugging/hotunplugging yet, but
existing resource cleanup leak logic likes ehci/uhci.

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/usb/hcd-ohci.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index a0d478e..ca7aeb3 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1879,7 +1879,6 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
     usb_packet_init(&ohci->usb_packet);
 
     ohci->async_td = 0;
-    qemu_register_reset(ohci_reset, ohci);
 
     return 0;
 }
@@ -1951,6 +1950,15 @@ static void usb_ohci_exit(PCIDevice *dev)
     }
 }
 
+static void usb_ohci_reset_pci(DeviceState *d)
+{
+    PCIDevice *dev = PCI_DEVICE(d);
+    OHCIPCIState *ohci = PCI_OHCI(dev);
+    OHCIState *s = &ohci->state;
+
+    ohci_reset(s);
+}
+
 #define TYPE_SYSBUS_OHCI "sysbus-ohci"
 #define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
 
@@ -1976,6 +1984,14 @@ static void ohci_realize_pxa(DeviceState *dev, Error **errp)
     sysbus_init_mmio(sbd, &s->ohci.mem);
 }
 
+static void usb_ohci_reset_sysbus(DeviceState *dev)
+{
+    OHCISysBusState *s = SYSBUS_OHCI(dev);
+    OHCIState *ohci = &s->ohci;
+
+    ohci_reset(ohci);
+}
+
 static Property ohci_pci_properties[] = {
     DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
     DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
@@ -2097,6 +2113,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
     dc->props = ohci_pci_properties;
     dc->hotpluggable = false;
     dc->vmsd = &vmstate_ohci;
+    dc->reset = usb_ohci_reset_pci;
 }
 
 static const TypeInfo ohci_pci_info = {
@@ -2120,6 +2137,7 @@ static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_USB, dc->categories);
     dc->desc = "OHCI USB Controller";
     dc->props = ohci_sysbus_properties;
+    dc->reset = usb_ohci_reset_sysbus;
 }
 
 static const TypeInfo ohci_sysbus_info = {
-- 
1.7.12.4

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

* Re: [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter
  2015-03-18  9:33 [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter arei.gonglei
                   ` (2 preceding siblings ...)
  2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 3/3] ohci: fix resource cleanup leak arei.gonglei
@ 2015-03-18 11:46 ` Gerd Hoffmann
  3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2015-03-18 11:46 UTC (permalink / raw)
  To: arei.gonglei; +Cc: qemu-stable, qemu-devel, peter.huangpeng

On Mi, 2015-03-18 at 17:33 +0800, arei.gonglei@huawei.com wrote:
> v4 -> v3:
>  - add reset hookup for sysbus devices (ehci/ohci). (Gerd)

Replaced patches.  make check failure is gone.  Good.

thanks,
  Gerd

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

end of thread, other threads:[~2015-03-18 11:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-18  9:33 [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter arei.gonglei
2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 1/3] uhci: fix segfault when hot-unplugging uhci controller arei.gonglei
2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 2/3] ehci: fix segfault when hot-unplugging ehci controller arei.gonglei
2015-03-18  9:33 ` [Qemu-devel] [PATCH v4 3/3] ohci: fix resource cleanup leak arei.gonglei
2015-03-18 11:46 ` [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter Gerd Hoffmann

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).