Message ID | 20130328090416.GA18482@redhat.com |
---|---|
State | New |
Headers | show |
Il 28/03/2013 10:04, Michael S. Tsirkin ha scritto: >>> > > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 >>> > > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. >>> > > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 >>> > > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. >>> > > Calling l: 5124 for start_addr: c0000 for vq 2 >>> > > Unable to map ring buffer for ring 2 >>> > > l: 4096 ring_size: 5124 > okay so the ring address is within ROM. > Unsurprisingly it fails. > bios should stop device before write protect. > The above log is very early, when everything is RAM: vhost_set_memory: section: 0x7fe2801f2b60 section->size: 2146697216 add: 0 Before vhost_verify_ring_mappings: start_addr: c0000 size: 2146697216 The rings are not within ROM. ROM is at 0xc0000-0xcc000 according to the PAM registers. The way I followed the debug output, "Got ranges_overlap" means actually "bailing out because ranges do not overlap". In particular, here all three virtqueues fail the test, because this is the ROM area 0xc0000..0xc7fff: vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 32768 add: 1 Before vhost_verify_ring_mappings: start_addr: c0000 size: 32768 Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 2 ring_phys: ed000 ring_size: 5124 Just below, vhost looks at the large RAM area starting at 0xc8000 (it's large because 0xf0000..0xfffff is still RAM): vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 2146664448 add: 1 Before vhost_verify_ring_mappings: start_addr: c8000 size: 2146664448 Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. Calling l: 5124 for start_addr: c8000 for vq 2 Here vq 0 and 1 fail the test because they are in low RAM, vq 2 passes. After 0xf0000..0xfffff is marked readonly, vhost looks at the RAM between 0xc9000 and 0xf0000: vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 159744 add: 1 Before vhost_verify_ring_mappings: start_addr: c9000 size: 159744 Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. Calling l: 5124 for start_addr: c9000 for vq 2 and the ROM between 0xf0000 and 0xfffff, which no ring overlaps with: vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 65536 add: 1 Before vhost_verify_ring_mappings: start_addr: f0000 size: 65536 Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. Got ranges_overlap for vq: 2 ring_phys: ed000 ring_size: 5124 SeaBIOS is indeed not initializing vqs 0/1 (the control and event queues), so their ring_phys is 0. But the one that is failing is vq 2, the first request queue. Your patch seems good, but shouldn't fix this problem. Paolo
> I think it's the right thing to do, but maybe not the right place > to do this, need to reset after all IO is done, before > ring memory is write protected. Our emails are crossing each other unfortunately, but I want to reinforce this: ring memory is not write protected. Remember that SeaBIOS can even provide virtio-scsi access to DOS, so you must not reset the device. It must remain functional all the time, and the OS's own driver will reset it when it's started. Paolo
On Thu, 2013-03-28 at 11:03 +0100, Paolo Bonzini wrote: > Il 28/03/2013 10:04, Michael S. Tsirkin ha scritto: > >>> > > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 > >>> > > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > >>> > > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 > >>> > > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. > >>> > > Calling l: 5124 for start_addr: c0000 for vq 2 > >>> > > Unable to map ring buffer for ring 2 > >>> > > l: 4096 ring_size: 5124 > > okay so the ring address is within ROM. > > Unsurprisingly it fails. > > bios should stop device before write protect. > > > > The above log is very early, when everything is RAM: > > vhost_set_memory: section: 0x7fe2801f2b60 section->size: 2146697216 add: 0 > Before vhost_verify_ring_mappings: start_addr: c0000 size: 2146697216 > > The rings are not within ROM. ROM is at 0xc0000-0xcc000 according to the > PAM registers. > > The way I followed the debug output, "Got ranges_overlap" means > actually "bailing out because ranges do not overlap". Yes, this is when !ranges_overlap() is hit in vhost_verify_ring_mappings(), so the offending cpu_physical_memory_map() is skipped.. > In particular, > here all three virtqueues fail the test, because this is the ROM area > 0xc0000..0xc7fff: > > vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 32768 add: 1 > Before vhost_verify_ring_mappings: start_addr: c0000 size: 32768 > Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 2 ring_phys: ed000 ring_size: 5124 > > Just below, vhost looks at the large RAM area starting at 0xc8000 > (it's large because 0xf0000..0xfffff is still RAM): > > vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 2146664448 add: 1 > Before vhost_verify_ring_mappings: start_addr: c8000 size: 2146664448 > Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. > Calling l: 5124 for start_addr: c8000 for vq 2 > > Here vq 0 and 1 fail the test because they are in low RAM, vq 2 passes. > > After 0xf0000..0xfffff is marked readonly, Btw, the first vhost_set_memory() and failing vhost_verify_ring_mappings() do not occur until the pci_config_writeb(..., 0x31) code is executed in src/shadow.c:make_bios_readonly_intel() below: static void make_bios_readonly_intel(u16 bdf, u32 pam0) { // Flush any pending writes before locking memory. wbinvd(); // Write protect roms from 0xc0000-0xf0000 u32 romend = rom_get_last(), romtop = rom_get_max(); int i; for (i=0; i<6; i++) { u32 mem = BUILD_ROM_START + i * 32*1024; u32 pam = pam0 + 1 + i; if (romend <= mem + 16*1024 || romtop <= mem + 32*1024) { if (romend > mem && romtop > mem + 16*1024) pci_config_writeb(bdf, pam, 0x31); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ break; } pci_config_writeb(bdf, pam, 0x11); } // Write protect 0xf0000-0x100000 pci_config_writeb(bdf, pam0, 0x10); } Up until this point, vhost_verify_ring_mappings() is not called by vhost_set_memory() as vhost_dev_start() has not been invoked to set vdev->started yet.. > vhost looks at the RAM > between 0xc9000 and 0xf0000: > > vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 159744 add: 1 > Before vhost_verify_ring_mappings: start_addr: c9000 size: 159744 > Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. > Calling l: 5124 for start_addr: c9000 for vq 2 > > and the ROM between 0xf0000 and 0xfffff, which no ring overlaps with: > > vhost_set_memory: section: 0x7fe2801f2aa0 section->size: 65536 add: 1 > Before vhost_verify_ring_mappings: start_addr: f0000 size: 65536 > Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. > Got ranges_overlap for vq: 2 ring_phys: ed000 ring_size: 5124 > > > > SeaBIOS is indeed not initializing vqs 0/1 (the control and event > queues), so their ring_phys is 0. But the one that is failing is vq 2, > the first request queue. > > Your patch seems good, but shouldn't fix this problem. > > Paolo > -- > To unsubscribe from this list: send the line "unsubscribe target-devel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, 2013-03-28 at 06:13 -0400, Paolo Bonzini wrote: > > I think it's the right thing to do, but maybe not the right place > > to do this, need to reset after all IO is done, before > > ring memory is write protected. > > Our emails are crossing each other unfortunately, but I want to > reinforce this: ring memory is not write protected. Understood. However, AFAICT the act of write protecting these ranges for ROM generates the offending callbacks to vhost_set_memory(). The part that I'm missing is if ring memory is not being write protected by make_bios_readonly_intel(), why are the vhost_set_memory() calls being invoked..? > Remember that > SeaBIOS can even provide virtio-scsi access to DOS, so you must > not reset the device. It must remain functional all the time, > and the OS's own driver will reset it when it's started. > Mmmm, so a vp_reset() is out of the question then.. --nab
On Thu, 2013-03-28 at 11:04 +0200, Michael S. Tsirkin wrote: > On Thu, Mar 28, 2013 at 12:35:42AM -0700, Nicholas A. Bellinger wrote: > > On Wed, 2013-03-27 at 23:45 -0700, Nicholas A. Bellinger wrote: > > > On Wed, 2013-03-27 at 15:33 -0700, Nicholas A. Bellinger wrote: > > > > On Wed, 2013-03-27 at 23:56 +0200, Michael S. Tsirkin wrote: > > > > > On Wed, Mar 27, 2013 at 02:31:27PM -0700, Nicholas A. Bellinger wrote: > > <SNIP> > > locking shadow ram > > romend: 0x000cb800 romtop: 0x000ec000 > > mem: 0x000c0000, pam: 0x0000005a > > Calling pci_config_writeb(0x11): bdf: 0x0000 pam: 0x0000005a > > > > > <No QEMU output after pci_config_writeb(0x11) in make_bios_readonly..> > > > > > > Calling pci_config_writeb(0x31): bdf: 0x0000 pam: 0x0000005b > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > > > > > > mem: 0x000c8000, pam: 0x0000005b > > romend: 0x000cb800 mem + 16*1024: 0x000cc000 > > romtop: 0x000ec000 mem + 32*1024: 0x000d0000 > > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > romend: 0x000cb800, mem: 0x000c8000, romtop: 0x000ec000, mem + 16*1024: 0x000cc000 > > Calling pci_config_writeb(0x31): bdf: 0x0000 pam: 0x0000005b > > > > > > > <QEMU output after pci_config_writeb(0x31) in make_bios_readonly..> > > > > > > vhost_set_memory: section: 0x7fe2801f2b60 section->size: 2146697216 add: 0 > > > Before vhost_verify_ring_mappings: start_addr: c0000 size: 2146697216 > > > Checking vq: 0 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > > This is also a bug. -net always initializes VQs 0..N so this is what > vhost assumed. Please teach vhost that it should skip uninitialized > VQs. There are more places to fix. > Basically look for if (!virtio_queue_get_num(vdev, queue_no)), > all of them need to be updated to skip uninitialized vqs. > Probably switch to a new API checking PA too. > See patch below. <nod> > > > > Got ranges_overlap for vq: 0 ring_phys: 0 ring_size: 1028 > > > Checking vq: 1 ring_phys: 0 ring_size: 1028 >>>>>>>>>>>>>>>>>>. > > > Got ranges_overlap for vq: 1 ring_phys: 0 ring_size: 1028 > > > Checking vq: 2 ring_phys: ed000 ring_size: 5124 >>>>>>>>>>>>>>>>>>. > > > Calling l: 5124 for start_addr: c0000 for vq 2 > > > Unable to map ring buffer for ring 2 > > > l: 4096 ring_size: 5124 > > okay so the ring address is within ROM. > Unsurprisingly it fails. > bios should stop device before write protect. <SNIP> > --- > > virtio: add API to check that ring is setup > > virtio scsi makes it legal to only setup a subset of rings. The only > way to detect the ring is setup seems to be to check whether PA was > written to. Add API to do this, and teach code to use it instead of > checking hardware queue size. > > Signed-off-by: Michael S. Tsirkin <mst@redhat.com> > > ---> > > diff --git a/hw/virtio.c b/hw/virtio.c > index 26fbc79..ac12c01 100644 > --- a/hw/virtio.c > +++ b/hw/virtio.c > @@ -651,6 +651,11 @@ int virtio_queue_get_num(VirtIODevice *vdev, int n) > return vdev->vq[n].vring.num; > } > > +bool virtio_queue_valid(VirtIODevice *vdev, int n) > +{ > + return vdev->vq[n].vring.num && vdev->vq[n].vring.pa; > +} I assume you mean vring.desc here, right..? Sending out these as a separate patch series shortly. --nab
Il 29/03/2013 03:53, Nicholas A. Bellinger ha scritto: > On Thu, 2013-03-28 at 06:13 -0400, Paolo Bonzini wrote: >>> I think it's the right thing to do, but maybe not the right place >>> to do this, need to reset after all IO is done, before >>> ring memory is write protected. >> >> Our emails are crossing each other unfortunately, but I want to >> reinforce this: ring memory is not write protected. > > Understood. However, AFAICT the act of write protecting these ranges > for ROM generates the offending callbacks to vhost_set_memory(). > > The part that I'm missing is if ring memory is not being write protected > by make_bios_readonly_intel(), why are the vhost_set_memory() calls > being invoked..? Because mappings change for the region that contains the ring. vhost doesn't know yet that the changes do not affect ring memory, vhost_set_memory() is called exactly to ascertain that. Paolo > >> Remember that >> SeaBIOS can even provide virtio-scsi access to DOS, so you must >> not reset the device. It must remain functional all the time, >> and the OS's own driver will reset it when it's started. >> > > Mmmm, so a vp_reset() is out of the question then.. > > --nab > > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >
On Fri, 2013-03-29 at 09:14 +0100, Paolo Bonzini wrote: > Il 29/03/2013 03:53, Nicholas A. Bellinger ha scritto: > > On Thu, 2013-03-28 at 06:13 -0400, Paolo Bonzini wrote: > >>> I think it's the right thing to do, but maybe not the right place > >>> to do this, need to reset after all IO is done, before > >>> ring memory is write protected. > >> > >> Our emails are crossing each other unfortunately, but I want to > >> reinforce this: ring memory is not write protected. > > > > Understood. However, AFAICT the act of write protecting these ranges > > for ROM generates the offending callbacks to vhost_set_memory(). > > > > The part that I'm missing is if ring memory is not being write protected > > by make_bios_readonly_intel(), why are the vhost_set_memory() calls > > being invoked..? > > Because mappings change for the region that contains the ring. vhost > doesn't know yet that the changes do not affect ring memory, > vhost_set_memory() is called exactly to ascertain that. > Hi Paolo & Co, Here's a bit more information on what is going on with the same cpu_physical_memory_map() failure in vhost_verify_ring_mappings().. So as before, at the point that seabios is marking memory as readonly for ROM in src/shadow.c:make_bios_readonly_intel() with the following call: Calling pci_config_writeb(0x31): bdf: 0x0000 pam: 0x0000005b the memory API update hook triggers back into vhost_region_del() code, and following occurs: Entering vhost_region_del section: 0x7fd30a213b60 offset_within_region: 0xc0000 size: 2146697216 readonly: 0 vhost_region_del: is_rom: 0, rom_device: 0 vhost_region_del: readable: 1 vhost_region_del: ram_addr 0x0, addr: 0x0 size: 2147483648 vhost_region_del: name: pc.ram Entering vhost_set_memory, section: 0x7fd30a213b60 add: 0, dev->started: 1 Entering verify_ring_mappings: start_addr 0x00000000000c0000 size: 2146697216 verify_ring_mappings: ring_phys 0x0 ring_size: 0 verify_ring_mappings: ring_phys 0x0 ring_size: 0 verify_ring_mappings: ring_phys 0xed000 ring_size: 5124 verify_ring_mappings: calling cpu_physical_memory_map ring_phys: 0xed000 l: 5124 address_space_map: addr: 0xed000, plen: 5124 address_space_map: l: 4096, len: 5124 phys_page_find got PHYS_MAP_NODE_NIL >>>>>>>>>>>>>>>>>>>>>>.. address_space_map: section: 0x7fd30fabaed0 memory_region_is_ram: 0 readonly: 0 address_space_map: section: 0x7fd30fabaed0 offset_within_region: 0x0 section size: 18446744073709551615 Unable to map ring buffer for ring 2, l: 4096 So the interesting part is that phys_page_find() is not able to locate the corresponding page for vq->ring_phys: 0xed000 from the vhost_region_del() callback with section->offset_within_region: 0xc0000.. Is there any case where this would not be considered a bug..? register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 Entering vhost_region_add section: 0x7fd30a213aa0 offset_within_region: 0xc0000 size: 32768 readonly: 1 vhost_region_add: is_rom: 0, rom_device: 0 vhost_region_add: readable: 1 vhost_region_add: ram_addr 0x0000000000000000, addr: 0x 0 size: 2147483648 vhost_region_add: name: pc.ram Entering vhost_set_memory, section: 0x7fd30a213aa0 add: 1, dev->started: 1 Entering verify_ring_mappings: start_addr 0x00000000000c0000 size: 32768 verify_ring_mappings: ring_phys 0x0 ring_size: 0 verify_ring_mappings: ring_phys 0x0 ring_size: 0 verify_ring_mappings: ring_phys 0xed000 ring_size: 5124 verify_ring_mappings: Got !ranges_overlap, skipping register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 Entering vhost_region_add section: 0x7fd30a213aa0 offset_within_region: 0xc8000 size: 2146664448 readonly: 0 vhost_region_add: is_rom: 0, rom_device: 0 vhost_region_add: readable: 1 vhost_region_add: ram_addr 0x0000000000000000, addr: 0x 0 size: 2147483648 vhost_region_add: name: pc.ram Entering vhost_set_memory, section: 0x7fd30a213aa0 add: 1, dev->started: 1 Entering verify_ring_mappings: start_addr 0x00000000000c8000 size: 2146664448 verify_ring_mappings: ring_phys 0x0 ring_size: 0 verify_ring_mappings: ring_phys 0x0 ring_size: 0 verify_ring_mappings: ring_phys 0xed000 ring_size: 5124 verify_ring_mappings: calling cpu_physical_memory_map ring_phys: 0xed000 l: 5124 address_space_map: addr: 0xed000, plen: 5124 address_space_map: l: 4096, len: 5124 address_space_map: section: 0x7fd30fabb020 memory_region_is_ram: 1 readonly: 0 address_space_map: section: 0x7fd30fabb020 offset_within_region: 0xc8000 section size: 2146664448 address_space_map: l: 4096, len: 1028 address_space_map: section: 0x7fd30fabb020 memory_region_is_ram: 1 readonly: 0 address_space_map: section: 0x7fd30fabb020 offset_within_region: 0xc8000 section size: 2146664448 address_space_map: Calling qemu_ram_ptr_length: raddr: 0x ed000 rlen: 5124 address_space_map: After qemu_ram_ptr_length: raddr: 0x ed000 rlen: 5124 So here the vhost_region_add() callback for section->offset_within_region: 0xc8000 for vq->ring_phys: 0xed000 is able to locate *section via phys_page_find() within address_space_map(), and cpu_physical_memory_map() completes as expected.. register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 register_multipage : d: 0x7fd30f7d0ed0 section: 0x7fd30a2139b0 phys_page_find got PHYS_MAP_NODE_NIL >>>>>>>>>>>>>>>>>>>>>>.. So while plodding my way through the memory API, the thing that would be useful to know is if the offending *section that is missing for the first phys_page_find() call is getting removed before the callback makes it's way into vhost_verify_ring_mappings() code, or that some other bug is occuring..? Any idea on how this could be verified..? Thanks, --nab
diff --git a/hw/virtio.c b/hw/virtio.c index 26fbc79..ac12c01 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -651,6 +651,11 @@ int virtio_queue_get_num(VirtIODevice *vdev, int n) return vdev->vq[n].vring.num; } +bool virtio_queue_valid(VirtIODevice *vdev, int n) +{ + return vdev->vq[n].vring.num && vdev->vq[n].vring.pa; +} + int virtio_queue_get_id(VirtQueue *vq) { VirtIODevice *vdev = vq->vdev; diff --git a/hw/virtio.h b/hw/virtio.h index ca43fd7..d3f23c2 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -227,6 +227,7 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data); void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr); hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n); int virtio_queue_get_num(VirtIODevice *vdev, int n); +bool virtio_queue_valid(VirtIODevice *vdev, int n); void virtio_queue_notify(VirtIODevice *vdev, int n); uint16_t virtio_queue_vector(VirtIODevice *vdev, int n); void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);