Message ID | 1503013010-11500-2-git-send-email-zuban32s@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: > Introduce a new PCIExpress-to-PCI Bridge device, > which is a hot-pluggable PCI Express device and > supports devices hot-plug with SHPC. > > This device is intended to replace the DMI-to-PCI Bridge. > > Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> > Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> It's possible to crash QEMU by instantiating this device, with; $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: Assertion `!mr->container' failed. Aborted I didn't investigate the root cause.
On 19/09/2017 23:34, Eduardo Habkost wrote: > On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: >> Introduce a new PCIExpress-to-PCI Bridge device, >> which is a hot-pluggable PCI Express device and >> supports devices hot-plug with SHPC. >> >> This device is intended to replace the DMI-to-PCI Bridge. >> >> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> >> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> > > It's possible to crash QEMU by instantiating this device, with; > > $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge > qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: Assertion `!mr->container' failed. > Aborted Hi Edurado, > > I didn't investigate the root cause. > Thanks for reporting it! Aleksandr, can you have a look? Maybe we should not compile the device for ppc arch. (x86 and arm is enough) Appreciated, Marcel
ср, 20 сент. 2017 г. в 10:13, Marcel Apfelbaum <marcel@redhat.com>: > On 19/09/2017 23:34, Eduardo Habkost wrote: > > On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: > >> Introduce a new PCIExpress-to-PCI Bridge device, > >> which is a hot-pluggable PCI Express device and > >> supports devices hot-plug with SHPC. > >> > >> This device is intended to replace the DMI-to-PCI Bridge. > >> > >> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> > >> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> > > > > It's possible to crash QEMU by instantiating this device, with; > > > > $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge > > qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: > Assertion `!mr->container' failed. > > Aborted > > Hi Edurado, > > > > > I didn't investigate the root cause. > > > > Thanks for reporting it! > Aleksandr, can you have a look? Maybe we should not compile > the device for ppc arch. (x86 and arm is enough) I will see what can we do. Is x86 and arm really enough? > > Appreciated, > Marcel > > -- Aleksandr Bezzubikov
On Wed, Sep 20, 2017 at 09:52:01AM +0000, Aleksandr Bezzubikov wrote: > ср, 20 сент. 2017 г. в 10:13, Marcel Apfelbaum <marcel@redhat.com>: > > > On 19/09/2017 23:34, Eduardo Habkost wrote: > > > On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: > > >> Introduce a new PCIExpress-to-PCI Bridge device, > > >> which is a hot-pluggable PCI Express device and > > >> supports devices hot-plug with SHPC. > > >> > > >> This device is intended to replace the DMI-to-PCI Bridge. > > >> > > >> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> > > >> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> > > > > > > It's possible to crash QEMU by instantiating this device, with; > > > > > > $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge > > > qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: > > Assertion `!mr->container' failed. > > > Aborted > > > > Hi Edurado, > > > > > > > > I didn't investigate the root cause. > > > > > > > Thanks for reporting it! > > Aleksandr, can you have a look? Maybe we should not compile > > the device for ppc arch. (x86 and arm is enough) > > > I will see what can we do. Is x86 and arm really enough? I would investigate the original cause before disabling the device on other architectures, as we could be hiding a bug that's also present in x86. The backtrace looks like broken error handling logic somewhere: #0 0x00007fffea9ff1f7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x00007fffeaa008e8 in __GI_abort () at abort.c:90 #2 0x00007fffea9f8266 in __assert_fail_base (fmt=0x7fffeab4ae68 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x555555be4ac1 "!mr->container", file=file@entry=0x555555be49c4 "/root/qemu/memory.c", line=line@entry=1533, function=function@entry=0x555555be5100 <__PRETTY_FUNCTION__.28908> "memory_region_finalize") at assert.c:92 #3 0x00007fffea9f8312 in __GI___assert_fail (assertion=assertion@entry=0x555555be4ac1 "!mr->container", file=file@entry=0x555555be49c4 "/root/qemu/memory.c", line=line@entry=1533, function=function@entry=0x555555be5100 <__PRETTY_FUNCTION__.28908> "memory_region_finalize") at assert.c:101 #4 0x00005555557ff2df in memory_region_finalize (obj=<optimized out>) at /root/qemu/memory.c:1533 #5 0x0000555555ae77a2 in object_unref (type=<optimized out>, obj=0x555557c00d80) at /root/qemu/qom/object.c:453 #6 0x0000555555ae77a2 in object_unref (data=0x555557c00d80) at /root/qemu/qom/object.c:467 #7 0x0000555555ae77a2 in object_unref (obj=0x555557c00d80) at /root/qemu/qom/object.c:902 #8 0x0000555555ae67d7 in object_property_del_child (obj=0x555557ab6500, child=child@entry=0x555557c00d80, errp=0x0) at /root/qemu/qom/object.c:427 #9 0x0000555555ae6ff4 in object_unparent (obj=obj@entry=0x555557c00d80) at /root/qemu/qom/object.c:446 #10 0x0000555555a1c94e in shpc_free (d=d@entry=0x555557ab6500) at /root/qemu/hw/pci/shpc.c:676 #11 0x0000555555a12560 in pcie_pci_bridge_realize (d=0x555557ab6500, errp=0x7fffffffd530) at /root/qemu/hw/pci-bridge/pcie_pci_bridge.c:84 #12 0x0000555555a18d07 in pci_qdev_realize (qdev=0x555557ab6500, errp=0x7fffffffd5d0) at /root/qemu/hw/pci/pci.c:2024 #13 0x00005555559b53aa in device_set_realized (obj=<optimized out>, value=<optimized out>, errp=0x7fffffffd708) at /root/qemu/hw/core/qdev.c:914 #14 0x0000555555ae62fe in property_set_bool (obj=0x555557ab6500, v=<optimized out>, name=<optimized out>, opaque=0x555557ab7b30, errp=0x7fffffffd708) at /root/qemu/qom/object.c:1886 #15 0x0000555555aea3ef in object_property_set_qobject (obj=obj@entry=0x555557ab6500, value=value@entry=0x555557ab86b0, name=name@entry=0x555555c4f217 "realized", errp=errp@entry=0x7fffffffd708) at /root/qemu/qom/qom-qobject.c:27 #16 0x0000555555ae80a0 in object_property_set_bool (obj=0x555557ab6500, value=<optimized out>, name=0x555555c4f217 "realized", errp=0x7fffffffd708) at /root/qemu/qom/object.c:1162 #17 0x0000555555949824 in qdev_device_add (opts=0x5555567795b0, errp=errp@entry=0x7fffffffd7e0) at /root/qemu/qdev-monitor.c:630 #18 0x000055555594be87 in device_init_func (opaque=<optimized out>, opts=<optimized out>, errp=<optimized out>) at /root/qemu/vl.c:2418 #19 0x0000555555bc85ba in qemu_opts_foreach (list=<optimized out>, func=func@entry=0x55555594be60 <device_init_func>, opaque=opaque@entry=0x0, errp=errp@entry=0x0) at /root/qemu/util/qemu-option.c:1104 #20 0x000055555579f497 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /root/qemu/vl.c:4745 (gdb) fr 11 #11 0x0000555555a12560 in pcie_pci_bridge_realize (d=0x555557ab6500, errp=0x7fffffffd530) at /root/qemu/hw/pci-bridge/pcie_pci_bridge.c:84 84 shpc_free(d); (gdb) l 79 pcie_aer_exit(d); 80 aer_error: 81 pm_error: 82 pcie_cap_exit(d); 83 cap_error: 84 shpc_free(d); 85 error: 86 pci_bridge_exitfn(d); 87 } 88 (gdb)
On 20/09/2017 12:52, Aleksandr Bezzubikov wrote: > > ср, 20 сент. 2017 г. в 10:13, Marcel Apfelbaum <marcel@redhat.com > <mailto:marcel@redhat.com>>: > > On 19/09/2017 23:34, Eduardo Habkost wrote: > > On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: > >> Introduce a new PCIExpress-to-PCI Bridge device, > >> which is a hot-pluggable PCI Express device and > >> supports devices hot-plug with SHPC. > >> > >> This device is intended to replace the DMI-to-PCI Bridge. > >> > >> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com > <mailto:zuban32s@gmail.com>> > >> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com > <mailto:marcel@redhat.com>> > > > > It's possible to crash QEMU by instantiating this device, with; > > > > $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge > > qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: > Assertion `!mr->container' failed. > > Aborted > > Hi Edurado, > > > > > I didn't investigate the root cause. > > > > Thanks for reporting it! > Aleksandr, can you have a look? Maybe we should not compile > the device for ppc arch. (x86 and arm is enough) > > > I will see what can we do. Is x86 and arm really enough? > Well, I am being selfish, and it works for me lately :). Seriously speaking, the new generic PCI Express Port was restricted to x86 and arm for reasons I don't remember. Since your work has the same scope, the restriction makes sense. Please grep for CONFIG_PCIE_PORT to convince yourself and to help coding it. Thanks, Marcel > > > Appreciated, > Marcel > > -- > Aleksandr Bezzubikov
On 20/09/2017 16:57, Eduardo Habkost wrote: > On Wed, Sep 20, 2017 at 09:52:01AM +0000, Aleksandr Bezzubikov wrote: >> ср, 20 сент. 2017 г. в 10:13, Marcel Apfelbaum <marcel@redhat.com>: >> >>> On 19/09/2017 23:34, Eduardo Habkost wrote: >>>> On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: >>>>> Introduce a new PCIExpress-to-PCI Bridge device, >>>>> which is a hot-pluggable PCI Express device and >>>>> supports devices hot-plug with SHPC. >>>>> >>>>> This device is intended to replace the DMI-to-PCI Bridge. >>>>> >>>>> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> >>>>> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> >>>> >>>> It's possible to crash QEMU by instantiating this device, with; >>>> >>>> $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge >>>> qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: >>> Assertion `!mr->container' failed. >>>> Aborted >>> >>> Hi Edurado, >>> >>>> >>>> I didn't investigate the root cause. >>>> >>> >>> Thanks for reporting it! >>> Aleksandr, can you have a look? Maybe we should not compile >>> the device for ppc arch. (x86 and arm is enough) >> >> >> I will see what can we do. Is x86 and arm really enough? > > I would investigate the original cause before disabling the device on other > architectures, as we could be hiding a bug that's also present in x86. Agreed, it worth finding out the reason. But the restriction still makes sense. Thanks, Marcel The > backtrace looks like broken error handling logic somewhere: > > #0 0x00007fffea9ff1f7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 > #1 0x00007fffeaa008e8 in __GI_abort () at abort.c:90 > #2 0x00007fffea9f8266 in __assert_fail_base (fmt=0x7fffeab4ae68 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x555555be4ac1 "!mr->container", file=file@entry=0x555555be49c4 "/root/qemu/memory.c", line=line@entry=1533, function=function@entry=0x555555be5100 <__PRETTY_FUNCTION__.28908> "memory_region_finalize") at assert.c:92 > #3 0x00007fffea9f8312 in __GI___assert_fail (assertion=assertion@entry=0x555555be4ac1 "!mr->container", file=file@entry=0x555555be49c4 "/root/qemu/memory.c", line=line@entry=1533, function=function@entry=0x555555be5100 <__PRETTY_FUNCTION__.28908> "memory_region_finalize") at assert.c:101 > #4 0x00005555557ff2df in memory_region_finalize (obj=<optimized out>) at /root/qemu/memory.c:1533 > #5 0x0000555555ae77a2 in object_unref (type=<optimized out>, obj=0x555557c00d80) at /root/qemu/qom/object.c:453 > #6 0x0000555555ae77a2 in object_unref (data=0x555557c00d80) at /root/qemu/qom/object.c:467 > #7 0x0000555555ae77a2 in object_unref (obj=0x555557c00d80) at /root/qemu/qom/object.c:902 > #8 0x0000555555ae67d7 in object_property_del_child (obj=0x555557ab6500, child=child@entry=0x555557c00d80, errp=0x0) at /root/qemu/qom/object.c:427 > #9 0x0000555555ae6ff4 in object_unparent (obj=obj@entry=0x555557c00d80) at /root/qemu/qom/object.c:446 > #10 0x0000555555a1c94e in shpc_free (d=d@entry=0x555557ab6500) at /root/qemu/hw/pci/shpc.c:676 > #11 0x0000555555a12560 in pcie_pci_bridge_realize (d=0x555557ab6500, errp=0x7fffffffd530) at /root/qemu/hw/pci-bridge/pcie_pci_bridge.c:84 > #12 0x0000555555a18d07 in pci_qdev_realize (qdev=0x555557ab6500, errp=0x7fffffffd5d0) at /root/qemu/hw/pci/pci.c:2024 > #13 0x00005555559b53aa in device_set_realized (obj=<optimized out>, value=<optimized out>, errp=0x7fffffffd708) at /root/qemu/hw/core/qdev.c:914 > #14 0x0000555555ae62fe in property_set_bool (obj=0x555557ab6500, v=<optimized out>, name=<optimized out>, opaque=0x555557ab7b30, errp=0x7fffffffd708) at /root/qemu/qom/object.c:1886 > #15 0x0000555555aea3ef in object_property_set_qobject (obj=obj@entry=0x555557ab6500, value=value@entry=0x555557ab86b0, name=name@entry=0x555555c4f217 "realized", errp=errp@entry=0x7fffffffd708) at /root/qemu/qom/qom-qobject.c:27 > #16 0x0000555555ae80a0 in object_property_set_bool (obj=0x555557ab6500, value=<optimized out>, name=0x555555c4f217 "realized", errp=0x7fffffffd708) at /root/qemu/qom/object.c:1162 > #17 0x0000555555949824 in qdev_device_add (opts=0x5555567795b0, errp=errp@entry=0x7fffffffd7e0) at /root/qemu/qdev-monitor.c:630 > #18 0x000055555594be87 in device_init_func (opaque=<optimized out>, opts=<optimized out>, errp=<optimized out>) at /root/qemu/vl.c:2418 > #19 0x0000555555bc85ba in qemu_opts_foreach (list=<optimized out>, func=func@entry=0x55555594be60 <device_init_func>, opaque=opaque@entry=0x0, errp=errp@entry=0x0) at /root/qemu/util/qemu-option.c:1104 > #20 0x000055555579f497 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /root/qemu/vl.c:4745 > (gdb) fr 11 > #11 0x0000555555a12560 in pcie_pci_bridge_realize (d=0x555557ab6500, errp=0x7fffffffd530) at /root/qemu/hw/pci-bridge/pcie_pci_bridge.c:84 > 84 shpc_free(d); > (gdb) l > 79 pcie_aer_exit(d); > 80 aer_error: > 81 pm_error: > 82 pcie_cap_exit(d); > 83 cap_error: > 84 shpc_free(d); > 85 error: > 86 pci_bridge_exitfn(d); > 87 } > 88 > (gdb) > >
2017-09-20 17:02 GMT+03:00 Marcel Apfelbaum <marcel@redhat.com>: > On 20/09/2017 16:57, Eduardo Habkost wrote: >> >> On Wed, Sep 20, 2017 at 09:52:01AM +0000, Aleksandr Bezzubikov wrote: >>> >>> ср, 20 сент. 2017 г. в 10:13, Marcel Apfelbaum <marcel@redhat.com>: >>> >>>> On 19/09/2017 23:34, Eduardo Habkost wrote: >>>>> >>>>> On Fri, Aug 18, 2017 at 02:36:47AM +0300, Aleksandr Bezzubikov wrote: >>>>>> >>>>>> Introduce a new PCIExpress-to-PCI Bridge device, >>>>>> which is a hot-pluggable PCI Express device and >>>>>> supports devices hot-plug with SHPC. >>>>>> >>>>>> This device is intended to replace the DMI-to-PCI Bridge. >>>>>> >>>>>> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> >>>>>> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> >>>>> >>>>> >>>>> It's possible to crash QEMU by instantiating this device, with; >>>>> >>>>> $ qemu-system-ppc64 -machine prep -device pcie-pci-bridge >>>>> qemu-system-ppc64: qemu/memory.c:1533: memory_region_finalize: >>>> >>>> Assertion `!mr->container' failed. >>>>> >>>>> Aborted >>>> >>>> >>>> Hi Edurado, >>>> >>>>> >>>>> I didn't investigate the root cause. >>>>> >>>> >>>> Thanks for reporting it! >>>> Aleksandr, can you have a look? Maybe we should not compile >>>> the device for ppc arch. (x86 and arm is enough) >>> >>> >>> >>> I will see what can we do. Is x86 and arm really enough? >> >> >> I would investigate the original cause before disabling the device on >> other >> architectures, as we could be hiding a bug that's also present in x86. > > > Agreed, it worth finding out the reason. But the restriction > still makes sense. > > > Thanks, > Marcel > > > The >> >> backtrace looks like broken error handling logic somewhere: >> >> #0 0x00007fffea9ff1f7 in __GI_raise (sig=sig@entry=6) at >> ../nptl/sysdeps/unix/sysv/linux/raise.c:56 >> #1 0x00007fffeaa008e8 in __GI_abort () at abort.c:90 >> #2 0x00007fffea9f8266 in __assert_fail_base (fmt=0x7fffeab4ae68 >> "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", >> assertion=assertion@entry=0x555555be4ac1 "!mr->container", >> file=file@entry=0x555555be49c4 "/root/qemu/memory.c", line=line@entry=1533, >> function=function@entry=0x555555be5100 <__PRETTY_FUNCTION__.28908> >> "memory_region_finalize") at assert.c:92 >> #3 0x00007fffea9f8312 in __GI___assert_fail >> (assertion=assertion@entry=0x555555be4ac1 "!mr->container", >> file=file@entry=0x555555be49c4 "/root/qemu/memory.c", line=line@entry=1533, >> function=function@entry=0x555555be5100 <__PRETTY_FUNCTION__.28908> >> "memory_region_finalize") at assert.c:101 >> #4 0x00005555557ff2df in memory_region_finalize (obj=<optimized out>) at >> /root/qemu/memory.c:1533 >> #5 0x0000555555ae77a2 in object_unref (type=<optimized out>, >> obj=0x555557c00d80) at /root/qemu/qom/object.c:453 >> #6 0x0000555555ae77a2 in object_unref (data=0x555557c00d80) at >> /root/qemu/qom/object.c:467 >> #7 0x0000555555ae77a2 in object_unref (obj=0x555557c00d80) at >> /root/qemu/qom/object.c:902 >> #8 0x0000555555ae67d7 in object_property_del_child (obj=0x555557ab6500, >> child=child@entry=0x555557c00d80, errp=0x0) at /root/qemu/qom/object.c:427 >> #9 0x0000555555ae6ff4 in object_unparent (obj=obj@entry=0x555557c00d80) >> at /root/qemu/qom/object.c:446 >> #10 0x0000555555a1c94e in shpc_free (d=d@entry=0x555557ab6500) at >> /root/qemu/hw/pci/shpc.c:676 >> #11 0x0000555555a12560 in pcie_pci_bridge_realize (d=0x555557ab6500, >> errp=0x7fffffffd530) at /root/qemu/hw/pci-bridge/pcie_pci_bridge.c:84 >> #12 0x0000555555a18d07 in pci_qdev_realize (qdev=0x555557ab6500, >> errp=0x7fffffffd5d0) at /root/qemu/hw/pci/pci.c:2024 >> #13 0x00005555559b53aa in device_set_realized (obj=<optimized out>, >> value=<optimized out>, errp=0x7fffffffd708) at /root/qemu/hw/core/qdev.c:914 >> #14 0x0000555555ae62fe in property_set_bool (obj=0x555557ab6500, >> v=<optimized out>, name=<optimized out>, opaque=0x555557ab7b30, >> errp=0x7fffffffd708) at /root/qemu/qom/object.c:1886 >> #15 0x0000555555aea3ef in object_property_set_qobject >> (obj=obj@entry=0x555557ab6500, value=value@entry=0x555557ab86b0, >> name=name@entry=0x555555c4f217 "realized", errp=errp@entry=0x7fffffffd708) >> at /root/qemu/qom/qom-qobject.c:27 >> #16 0x0000555555ae80a0 in object_property_set_bool (obj=0x555557ab6500, >> value=<optimized out>, name=0x555555c4f217 "realized", errp=0x7fffffffd708) >> at /root/qemu/qom/object.c:1162 >> #17 0x0000555555949824 in qdev_device_add (opts=0x5555567795b0, >> errp=errp@entry=0x7fffffffd7e0) at /root/qemu/qdev-monitor.c:630 >> #18 0x000055555594be87 in device_init_func (opaque=<optimized out>, >> opts=<optimized out>, errp=<optimized out>) at /root/qemu/vl.c:2418 >> #19 0x0000555555bc85ba in qemu_opts_foreach (list=<optimized out>, >> func=func@entry=0x55555594be60 <device_init_func>, opaque=opaque@entry=0x0, >> errp=errp@entry=0x0) at /root/qemu/util/qemu-option.c:1104 >> #20 0x000055555579f497 in main (argc=<optimized out>, argv=<optimized >> out>, envp=<optimized out>) at /root/qemu/vl.c:4745 >> (gdb) fr 11 >> #11 0x0000555555a12560 in pcie_pci_bridge_realize (d=0x555557ab6500, >> errp=0x7fffffffd530) at /root/qemu/hw/pci-bridge/pcie_pci_bridge.c:84 >> 84 shpc_free(d); >> (gdb) l >> 79 pcie_aer_exit(d); >> 80 aer_error: >> 81 pm_error: >> 82 pcie_cap_exit(d); >> 83 cap_error: >> 84 shpc_free(d); >> 85 error: >> 86 pci_bridge_exitfn(d); >> 87 } >> 88 >> (gdb) >> >> > I've discovered the root cause of the problem - MSI is not supported by interrupt controller in 'prep' ppc64 machine, and then it seems that shpc_free is definitely not the right function to be used in this case. I suppose shpc_cleanup should be used there, I'll submit a patch to fix that.
diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs index c4683cf..666db37 100644 --- a/hw/pci-bridge/Makefile.objs +++ b/hw/pci-bridge/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-y += pci_bridge_dev.o +common-obj-y += pci_bridge_dev.o pcie_pci_bridge.o common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o common-obj-$(CONFIG_PXB) += pci_expander_bridge.o common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c new file mode 100644 index 0000000..9aa5cc3 --- /dev/null +++ b/hw/pci-bridge/pcie_pci_bridge.c @@ -0,0 +1,192 @@ +/* + * QEMU Generic PCIE-PCI Bridge + * + * Copyright (c) 2017 Aleksandr Bezzubikov + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/msi.h" +#include "hw/pci/shpc.h" +#include "hw/pci/slotid_cap.h" + +typedef struct PCIEPCIBridge { + /*< private >*/ + PCIBridge parent_obj; + + OnOffAuto msi; + MemoryRegion shpc_bar; + /*< public >*/ +} PCIEPCIBridge; + +#define TYPE_PCIE_PCI_BRIDGE_DEV "pcie-pci-bridge" +#define PCIE_PCI_BRIDGE_DEV(obj) \ + OBJECT_CHECK(PCIEPCIBridge, (obj), TYPE_PCIE_PCI_BRIDGE_DEV) + +static void pcie_pci_bridge_realize(PCIDevice *d, Error **errp) +{ + PCIBridge *br = PCI_BRIDGE(d); + PCIEPCIBridge *pcie_br = PCIE_PCI_BRIDGE_DEV(d); + int rc, pos; + + pci_bridge_initfn(d, TYPE_PCI_BUS); + + d->config[PCI_INTERRUPT_PIN] = 0x1; + memory_region_init(&pcie_br->shpc_bar, OBJECT(d), "shpc-bar", + shpc_bar_size(d)); + rc = shpc_init(d, &br->sec_bus, &pcie_br->shpc_bar, 0, errp); + if (rc) { + goto error; + } + + rc = pcie_cap_init(d, 0, PCI_EXP_TYPE_PCI_BRIDGE, 0, errp); + if (rc < 0) { + goto cap_error; + } + + pos = pci_add_capability(d, PCI_CAP_ID_PM, 0, PCI_PM_SIZEOF, errp); + if (pos < 0) { + goto pm_error; + } + d->exp.pm_cap = pos; + pci_set_word(d->config + pos + PCI_PM_PMC, 0x3); + + pcie_cap_arifwd_init(d); + pcie_cap_deverr_init(d); + + rc = pcie_aer_init(d, PCI_ERR_VER, 0x100, PCI_ERR_SIZEOF, errp); + if (rc < 0) { + goto aer_error; + } + + if (pcie_br->msi != ON_OFF_AUTO_OFF) { + rc = msi_init(d, 0, 1, true, true, errp); + if (rc < 0) { + goto msi_error; + } + } + pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64, &pcie_br->shpc_bar); + return; + +msi_error: + pcie_aer_exit(d); +aer_error: +pm_error: + pcie_cap_exit(d); +cap_error: + shpc_free(d); +error: + pci_bridge_exitfn(d); +} + +static void pcie_pci_bridge_exit(PCIDevice *d) +{ + PCIEPCIBridge *bridge_dev = PCIE_PCI_BRIDGE_DEV(d); + pcie_cap_exit(d); + shpc_cleanup(d, &bridge_dev->shpc_bar); + pci_bridge_exitfn(d); +} + +static void pcie_pci_bridge_reset(DeviceState *qdev) +{ + PCIDevice *d = PCI_DEVICE(qdev); + pci_bridge_reset(qdev); + msi_reset(d); + shpc_reset(d); +} + +static void pcie_pci_bridge_write_config(PCIDevice *d, + uint32_t address, uint32_t val, int len) +{ + pci_bridge_write_config(d, address, val, len); + msi_write_config(d, address, val, len); + shpc_cap_write_config(d, address, val, len); +} + +static Property pcie_pci_bridge_dev_properties[] = { + DEFINE_PROP_ON_OFF_AUTO("msi", PCIEPCIBridge, msi, ON_OFF_AUTO_ON), + DEFINE_PROP_END_OF_LIST(), +}; + +static const VMStateDescription pcie_pci_bridge_dev_vmstate = { + .name = TYPE_PCIE_PCI_BRIDGE_DEV, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj, PCIBridge), + SHPC_VMSTATE(shpc, PCIDevice, NULL), + VMSTATE_END_OF_LIST() + } +}; + +static void pcie_pci_bridge_hotplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled for " + "this %s", TYPE_PCIE_PCI_BRIDGE_DEV); + return; + } + shpc_device_hotplug_cb(hotplug_dev, dev, errp); +} + +static void pcie_pci_bridge_hot_unplug_request_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, + Error **errp) +{ + PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled for " + "this %s", TYPE_PCIE_PCI_BRIDGE_DEV); + return; + } + shpc_device_hot_unplug_request_cb(hotplug_dev, dev, errp); +} + +static void pcie_pci_bridge_class_init(ObjectClass *klass, void *data) +{ + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); + + k->is_express = 1; + k->is_bridge = 1; + k->vendor_id = PCI_VENDOR_ID_REDHAT; + k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE; + k->realize = pcie_pci_bridge_realize; + k->exit = pcie_pci_bridge_exit; + k->config_write = pcie_pci_bridge_write_config; + dc->vmsd = &pcie_pci_bridge_dev_vmstate; + dc->props = pcie_pci_bridge_dev_properties; + dc->vmsd = &pcie_pci_bridge_dev_vmstate; + dc->reset = &pcie_pci_bridge_reset; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + hc->plug = pcie_pci_bridge_hotplug_cb; + hc->unplug_request = pcie_pci_bridge_hot_unplug_request_cb; +} + +static const TypeInfo pcie_pci_bridge_info = { + .name = TYPE_PCIE_PCI_BRIDGE_DEV, + .parent = TYPE_PCI_BRIDGE, + .instance_size = sizeof(PCIEPCIBridge), + .class_init = pcie_pci_bridge_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { }, + } +}; + +static void pciepci_register(void) +{ + type_register_static(&pcie_pci_bridge_info); +} + +type_init(pciepci_register); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index e598b09..b33a34f 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -98,6 +98,7 @@ #define PCI_DEVICE_ID_REDHAT_PXB_PCIE 0x000b #define PCI_DEVICE_ID_REDHAT_PCIE_RP 0x000c #define PCI_DEVICE_ID_REDHAT_XHCI 0x000d +#define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000e #define PCI_DEVICE_ID_REDHAT_QXL 0x0100 #define FMT_PCIBUS PRIx64