QEMU中的legacyPCI和modernPCI的区别
第一种情况:使用Modern PCI
,禁用legacy PCI
设置virtio_queue_aio_set_host_notifier_handler
用的调动路径。
(gdb) bt
#0 virtio_queue_aio_set_host_notifier_handler (vq=0x5555578aedf0, ctx=0x5555569be6c0,
handle_output=0x5555558bef16 <virtio_blk_data_plane_handle_output>) at /root/code/qemu-4.1.0/hw/virtio/virtio.c:2525
#1 0x00005555558bf31b in virtio_blk_data_plane_start (vdev=0x5555578a2630) at /root/code/qemu-4.1.0/hw/block/dataplane/virtio-blk.c:234
#2 0x0000555555ba8b6b in virtio_bus_start_ioeventfd (bus=0x5555578a25b8) at hw/virtio/virtio-bus.c:224
#3 0x0000555555baab17 in virtio_pci_start_ioeventfd (proxy=0x55555789a4c0) at hw/virtio/virtio-pci.c:284
#4 0x0000555555bacf53 in virtio_pci_common_write (opaque=0x55555789a4c0, addr=20, val=15, size=1) at hw/virtio/virtio-pci.c:1235
#5 0x000055555586c133 in memory_region_write_accessor (mr=0x55555789ae90, addr=20, value=0x7fffdfffc358, size=1, shift=0, mask=255, attrs=...)
at /root/code/qemu-4.1.0/memory.c:508
#6 0x000055555586c33d in access_with_adjusted_size (addr=20, value=0x7fffdfffc358, size=1, access_size_min=1, access_size_max=4,
access_fn=0x55555586c053 <memory_region_write_accessor>, mr=0x55555789ae90, attrs=...) at /root/code/qemu-4.1.0/memory.c:574
#7 0x000055555586f473 in memory_region_dispatch_write (mr=0x55555789ae90, addr=20, data=15, size=1, attrs=...) at /root/code/qemu-4.1.0/memory.c:1502
#8 0x000055555580f212 in flatview_write_continue (fv=0x7fffd4003820, addr=4261429268, attrs=..., buf=0x7ffff7fee028 "\017\020", len=1, addr1=20,
l=1, mr=0x55555789ae90) at /root/code/qemu-4.1.0/exec.c:3337
#9 0x000055555580f36a in flatview_write (fv=0x7fffd4003820, addr=4261429268, attrs=..., buf=0x7ffff7fee028 "\017\020", len=1)
at /root/code/qemu-4.1.0/exec.c:3376
#10 0x000055555580f687 in address_space_write (as=0x5555567d60e0 <address_space_memory>, addr=4261429268, attrs=..., buf=0x7ffff7fee028 "\017\020",
len=1) at /root/code/qemu-4.1.0/exec.c:3466
#11 0x000055555580f6d9 in address_space_rw (as=0x5555567d60e0 <address_space_memory>, addr=4261429268, attrs=..., buf=0x7ffff7fee028 "\017\020",
len=1, is_write=true) at /root/code/qemu-4.1.0/exec.c:3477
#12 0x000055555588546e in kvm_cpu_exec (cpu=0x5555569ed430) at /root/code/qemu-4.1.0/accel/kvm/kvm-all.c:2286
#13 0x000055555585e835 in qemu_kvm_cpu_thread_fn (arg=0x5555569ed430) at /root/code/qemu-4.1.0/cpus.c:1285
#14 0x0000555555d86f99 in qemu_thread_start (args=0x555556a06900) at util/qemu-thread-posix.c:502
#15 0x00007ffff4909e65 in start_thread () from /lib64/libpthread.so.0
#16 0x00007ffff463288d in clone () from /lib64/libc.so.6
在函数virtio_pci_modern_regions_init
中,设置了virtio_pci_common_write
这个函数。来看看virtio_pci_modern_regions_init
函数的调用栈,如下:
(gdb) bt
#0 virtio_pci_modern_regions_init (proxy=0x55555789a4c0) at hw/virtio/virtio-pci.c:1431
#1 0x0000555555badd13 in virtio_pci_device_plugged (d=0x55555789a4c0, errp=0x7fffffffd868) at hw/virtio/virtio-pci.c:1595
#2 0x0000555555ba850e in virtio_bus_device_plugged (vdev=0x5555578a2630, errp=0x7fffffffd8c0) at hw/virtio/virtio-bus.c:75
#3 0x000055555591a483 in virtio_device_realize (dev=0x5555578a2630, errp=0x7fffffffd920) at /root/code/qemu-4.1.0/hw/virtio/virtio.c:2620
#4 0x0000555555a68aae in device_set_realized (obj=0x5555578a2630, value=true, errp=0x7fffffffdb58) at hw/core/qdev.c:834
#5 0x0000555555c4ba4f in property_set_bool (obj=0x5555578a2630, v=0x5555578a5fc0, name=0x555555f32f98 "realized", opaque=0x5555578a3cf0,
errp=0x7fffffffdb58) at qom/object.c:2079
#6 0x0000555555c49cb9 in object_property_set (obj=0x5555578a2630, v=0x5555578a5fc0, name=0x555555f32f98 "realized", errp=0x7fffffffdb58)
at qom/object.c:1271
#7 0x0000555555c4cdc4 in object_property_set_qobject (obj=0x5555578a2630, value=0x5555578a5f10, name=0x555555f32f98 "realized", errp=0x7fffffffdb58)
at qom/qom-qobject.c:26
#8 0x0000555555c49f97 in object_property_set_bool (obj=0x5555578a2630, value=true, name=0x555555f32f98 "realized", errp=0x7fffffffdb58)
at qom/object.c:1337
#9 0x000055555592dbc4 in virtio_blk_pci_realize (vpci_dev=0x55555789a4c0, errp=0x7fffffffdb58) at /root/code/qemu-4.1.0/hw/virtio/virtio-blk-pci.c:58
#10 0x0000555555bae634 in virtio_pci_realize (pci_dev=0x55555789a4c0, errp=0x7fffffffdb58) at hw/virtio/virtio-pci.c:1788
#11 0x0000555555b22308 in pci_qdev_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc10) at hw/pci/pci.c:2092
#12 0x0000555555bae9e5 in virtio_pci_dc_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc10) at hw/virtio/virtio-pci.c:1859
#13 0x0000555555a68aae in device_set_realized (obj=0x55555789a4c0, value=true, errp=0x7fffffffddf0) at hw/core/qdev.c:834
#14 0x0000555555c4ba4f in property_set_bool (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", opaque=0x55555789a030,
errp=0x7fffffffddf0) at qom/object.c:2079
#15 0x0000555555c49cb9 in object_property_set (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", errp=0x7fffffffddf0)
at qom/object.c:1271
#16 0x0000555555c4cdc4 in object_property_set_qobject (obj=0x55555789a4c0, value=0x5555578a7840, name=0x555555f500f2 "realized", errp=0x7fffffffddf0)
at qom/qom-qobject.c:26
#17 0x0000555555c49f97 in object_property_set_bool (obj=0x55555789a4c0, value=true, name=0x555555f500f2 "realized", errp=0x7fffffffddf0)
at qom/object.c:1337
#18 0x00005555559f146b in qdev_device_add (opts=0x5555568fbf50, errp=0x555556859010 <error_fatal>) at qdev-monitor.c:634
#19 0x00005555559f916b in device_init_func (opaque=0x0, opts=0x5555568fbf50, errp=0x555556859010 <error_fatal>) at vl.c:2191
#20 0x0000555555d9b5bb in qemu_opts_foreach (list=0x555556676040 <qemu_device_opts>, func=0x5555559f9144 <device_init_func>, opaque=0x0,
errp=0x555556859010 <error_fatal>) at util/qemu-option.c:1170
#21 0x00005555559fe128 in main (argc=27, argv=0x7fffffffe1e8, envp=0x7fffffffe2c8) at vl.c:4372
可以很明显看出,这个函数是在初始化PCI device的时候调用的,也即是说,modern PCI设备的内存空间是在初始化设备时就准备好的。
第二种情况:使用legacy PCI
,禁用Modern PCI
同样是设置virtio_queue_aio_set_host_notifier_handler
用的调动路径。
(gdb) bt
#0 virtio_queue_aio_set_host_notifier_handler (vq=0x5555578aa360, ctx=0x5555569be6c0,
handle_output=0x5555558bef16 <virtio_blk_data_plane_handle_output>) at /root/code/qemu-4.1.0/hw/virtio/virtio.c:2525
#1 0x00005555558bf31b in virtio_blk_data_plane_start (vdev=0x5555578a2630) at /root/code/qemu-4.1.0/hw/block/dataplane/virtio-blk.c:234
#2 0x0000555555ba8b6b in virtio_bus_start_ioeventfd (bus=0x5555578a25b8) at hw/virtio/virtio-bus.c:224
#3 0x0000555555baab17 in virtio_pci_start_ioeventfd (proxy=0x55555789a4c0) at hw/virtio/virtio-pci.c:284
#4 0x0000555555baacc4 in virtio_ioport_write (opaque=0x55555789a4c0, addr=18, val=7) at hw/virtio/virtio-pci.c:331
#5 0x0000555555bab126 in virtio_pci_config_write (opaque=0x55555789a4c0, addr=18, val=7, size=1) at hw/virtio/virtio-pci.c:452
#6 0x000055555586c133 in memory_region_write_accessor (mr=0x55555789ada0, addr=18, value=0x7fffdfffc318, size=1, shift=0, mask=255, attrs=...)
at /root/code/qemu-4.1.0/memory.c:508
#7 0x000055555586c33d in access_with_adjusted_size (addr=18, value=0x7fffdfffc318, size=1, access_size_min=1, access_size_max=4,
access_fn=0x55555586c053 <memory_region_write_accessor>, mr=0x55555789ada0, attrs=...) at /root/code/qemu-4.1.0/memory.c:574
#8 0x000055555586f473 in memory_region_dispatch_write (mr=0x55555789ada0, addr=18, data=7, size=1, attrs=...) at /root/code/qemu-4.1.0/memory.c:1502
#9 0x000055555580f212 in flatview_write_continue (fv=0x7fffd4019ae0, addr=49170, attrs=..., buf=0x7ffff7fef000 "\al", len=1, addr1=18, l=1,
mr=0x55555789ada0) at /root/code/qemu-4.1.0/exec.c:3337
#10 0x000055555580f36a in flatview_write (fv=0x7fffd4019ae0, addr=49170, attrs=..., buf=0x7ffff7fef000 "\al", len=1)
at /root/code/qemu-4.1.0/exec.c:3376
#11 0x000055555580f687 in address_space_write (as=0x5555567d6080 <address_space_io>, addr=49170, attrs=..., buf=0x7ffff7fef000 "\al", len=1)
at /root/code/qemu-4.1.0/exec.c:3466
#12 0x000055555580f6d9 in address_space_rw (as=0x5555567d6080 <address_space_io>, addr=49170, attrs=..., buf=0x7ffff7fef000 "\al", len=1,
is_write=true) at /root/code/qemu-4.1.0/exec.c:3477
#13 0x0000555555884c7a in kvm_handle_io (port=49170, attrs=..., data=0x7ffff7fef000, direction=1, size=1, count=1)
at /root/code/qemu-4.1.0/accel/kvm/kvm-all.c:2030
#14 0x000055555588541e in kvm_cpu_exec (cpu=0x5555569ed430) at /root/code/qemu-4.1.0/accel/kvm/kvm-all.c:2276
#15 0x000055555585e835 in qemu_kvm_cpu_thread_fn (arg=0x5555569ed430) at /root/code/qemu-4.1.0/cpus.c:1285
#16 0x0000555555d86f99 in qemu_thread_start (args=0x555556a06900) at util/qemu-thread-posix.c:502
#17 0x00007ffff4909e65 in start_thread () from /lib64/libpthread.so.0
#18 0x00007ffff463288d in clone () from /lib64/libc.so.6
到这里可以看到,使用modern pci
和legacy pci
的不同之处。