qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR
@ 2024-08-20 11:56 Gao Shiyuan via
  2024-08-27 13:41 ` Stefano Garzarella
  2024-09-03 10:19 ` Michael S. Tsirkin
  0 siblings, 2 replies; 5+ messages in thread
From: Gao Shiyuan via @ 2024-08-20 11:56 UTC (permalink / raw)
  To: Michael S. Tsirkin, Stefano Garzarella, Jason Wang, zuoboqun
  Cc: qemu-devel, gaoshiyuan

When VHOST_USER_PROTOCOL_F_HOST_NOTIFIER feature negotiated and
virtio_queue_set_host_notifier_mr success on system blk
device's queue, the VM can't load MBR if the notify region's
address above 4GB.

Assign the address of notify region in the modern bar above 4G, the vp_notify
in SeaBIOS will use PCI Cfg Capability to write notify region. This will trap
into QEMU and be handled by the host bridge when we don't enable mmconfig.
QEMU will call virtio_write_config and since it writes to the BAR region
through the PCI Cfg Capability, it will call virtio_address_space_write.

virtio_queue_set_host_notifier_mr add host notifier subregion of notify region
MR, QEMU need write the mmap address instead of eventfd notify the hardware
accelerator at the vhost-user backend. So virtio_address_space_lookup in
virtio_address_space_write need return a host-notifier subregion of notify MR
instead of notify MR.

Add lookup subregion of VirtIOPCIRegion MR instead of only lookup container MR.

Fixes: a93c8d8 ("virtio-pci: Replace modern_as with direct access to modern_bar")

Co-developed-by: Zuo Boqun <zuoboqun@baidu.com>
Signed-off-by: Gao Shiyuan <gaoshiyuan@baidu.com>
Signed-off-by: Zuo Boqun <zuoboqun@baidu.com>
---
 hw/virtio/virtio-pci.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

---
v1 -> v2:
* modify commit message
* replace direct iteration over subregions with memory_region_find.

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 9534730bba..5d2d27a6a3 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -610,19 +610,29 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
 {
     int i;
     VirtIOPCIRegion *reg;
+    MemoryRegion *mr = NULL;
+    MemoryRegionSection mrs;
 
     for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
         reg = &proxy->regs[i];
         if (*off >= reg->offset &&
             *off + len <= reg->offset + reg->size) {
-            *off -= reg->offset;
-            return &reg->mr;
+            mrs = memory_region_find(&reg->mr, *off - reg->offset, len);
+            if (!mrs.mr) {
+                error_report("Failed to find memory region for address"
+                             "0x%" PRIx64 "", *off);
+                return NULL;
+            }
+            *off = mrs.offset_within_region;
+            memory_region_unref(mrs.mr);
+            return mrs.mr;
         }
     }
 
     return NULL;
 }
 
+
 /* Below are generic functions to do memcpy from/to an address space,
  * without byteswaps, with input validation.
  *
-- 
2.39.3 (Apple Git-146)



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

* Re: [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR
  2024-08-20 11:56 [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR Gao Shiyuan via
@ 2024-08-27 13:41 ` Stefano Garzarella
  2024-08-29 13:13   ` Gao,Shiyuan via
  2024-09-03 10:19 ` Michael S. Tsirkin
  1 sibling, 1 reply; 5+ messages in thread
From: Stefano Garzarella @ 2024-08-27 13:41 UTC (permalink / raw)
  To: Gao Shiyuan; +Cc: Michael S. Tsirkin, Jason Wang, zuoboqun, qemu-devel

On Tue, Aug 20, 2024 at 07:56:31PM GMT, Gao Shiyuan wrote:
>When VHOST_USER_PROTOCOL_F_HOST_NOTIFIER feature negotiated and
>virtio_queue_set_host_notifier_mr success on system blk
>device's queue, the VM can't load MBR if the notify region's
>address above 4GB.
>
>Assign the address of notify region in the modern bar above 4G, the vp_notify
>in SeaBIOS will use PCI Cfg Capability to write notify region. This will trap
>into QEMU and be handled by the host bridge when we don't enable mmconfig.
>QEMU will call virtio_write_config and since it writes to the BAR region
>through the PCI Cfg Capability, it will call virtio_address_space_write.
>
>virtio_queue_set_host_notifier_mr add host notifier subregion of notify region
>MR, QEMU need write the mmap address instead of eventfd notify the hardware
>accelerator at the vhost-user backend. So virtio_address_space_lookup in
>virtio_address_space_write need return a host-notifier subregion of notify MR
>instead of notify MR.
>
>Add lookup subregion of VirtIOPCIRegion MR instead of only lookup container MR.
>
>Fixes: a93c8d8 ("virtio-pci: Replace modern_as with direct access to modern_bar")
>
>Co-developed-by: Zuo Boqun <zuoboqun@baidu.com>
>Signed-off-by: Gao Shiyuan <gaoshiyuan@baidu.com>
>Signed-off-by: Zuo Boqun <zuoboqun@baidu.com>
>---
> hw/virtio/virtio-pci.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
>---
>v1 -> v2:
>* modify commit message
>* replace direct iteration over subregions with memory_region_find.
>
>diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>index 9534730bba..5d2d27a6a3 100644
>--- a/hw/virtio/virtio-pci.c
>+++ b/hw/virtio/virtio-pci.c
>@@ -610,19 +610,29 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
> {
>     int i;
>     VirtIOPCIRegion *reg;
>+    MemoryRegion *mr = NULL;

`mr` looks unused.

>+    MemoryRegionSection mrs;

Please, can you move this declaration in the inner block where it's 
used?

>
>     for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
>         reg = &proxy->regs[i];
>         if (*off >= reg->offset &&
>             *off + len <= reg->offset + reg->size) {
>-            *off -= reg->offset;
>-            return &reg->mr;
>+            mrs = memory_region_find(&reg->mr, *off - reg->offset, 
>len);
>+            if (!mrs.mr) {
>+                error_report("Failed to find memory region for address"
>+                             "0x%" PRIx64 "", *off);
>+                return NULL;
>+            }
>+            *off = mrs.offset_within_region;
>+            memory_region_unref(mrs.mr);
>+            return mrs.mr;
>         }
>     }
>
>     return NULL;
> }
>
>+

Unrelated change.

Thanks,
Stefano

> /* Below are generic functions to do memcpy from/to an address space,
>  * without byteswaps, with input validation.
>  *
>-- 
>2.39.3 (Apple Git-146)
>



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

* Re: [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR
  2024-08-27 13:41 ` Stefano Garzarella
@ 2024-08-29 13:13   ` Gao,Shiyuan via
  2024-09-03 10:11     ` Stefano Garzarella
  0 siblings, 1 reply; 5+ messages in thread
From: Gao,Shiyuan via @ 2024-08-29 13:13 UTC (permalink / raw)
  To: Stefano Garzarella
  Cc: Michael S. Tsirkin, Jason Wang, Zuo,Boqun, qemu-devel@nongnu.org,
	Gao,Shiyuan

> >--- a/hw/virtio/virtio-pci.c
> >+++ b/hw/virtio/virtio-pci.c
> >@@ -610,19 +610,29 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
> > {
> >     int i;
> >     VirtIOPCIRegion *reg;
> >+    MemoryRegion *mr = NULL;
>
> `mr` looks unused.
>
> >+    MemoryRegionSection mrs;
>
> Please, can you move this declaration in the inner block where it's
> used?

ok, I will move to inner block and remove unused `mr`.

>
> >
> >     for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
> >         reg = &proxy->regs[i];
> >         if (*off >= reg->offset &&
> >             *off + len <= reg->offset + reg->size) {
> >-            *off -= reg->offset;
> >-            return &reg->mr;
> >+            mrs = memory_region_find(&reg->mr, *off - reg->offset,
> >len);
> >+            if (!mrs.mr) {
> >+                error_report("Failed to find memory region for address"
> >+                             "0x%" PRIx64 "", *off);
> >+                return NULL;
> >+            }
> >+            *off = mrs.offset_within_region;
> >+            memory_region_unref(mrs.mr);
> >+            return mrs.mr;
> >         }
> >     }
> >
> >     return NULL;
> > }
> >
> >+
>
> Unrelated change.

Perhaps this would be clearer but not universal in Version 1.

Without this patch, Only lookup common/isr/device/notify MR and
exclude their subregions.

When VHOST_USER_PROTOCOL_F_HOST_NOTIFIER enable, the notify MR has
host-notifier subregions and we need use host-notifier MR to
notify the hardware accelerator directly.

Further more, maybe common/isr/device MR also has subregions in
the future, so need memory_region_find for each MR incluing
their subregions and this will be more universal.

@@ -610,13 +610,22 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
 {
     int i;
     VirtIOPCIRegion *reg;
+    MemoryRegion *mr, *submr;

     for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
         reg = &proxy->regs[i];
         if (*off >= reg->offset &&
             *off + len <= reg->offset + reg->size) {
             *off -= reg->offset;
-            return &reg->mr;
+            mr = &reg->mr;
+            QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
+                if (*off >= submr->addr &&
+                    *off + len < submr->addr + submr->size) {
+                    *off -= submr->addr;
+                    return submr;
+                }
+            }
+            return mr;
         }
     }

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

* Re: [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR
  2024-08-29 13:13   ` Gao,Shiyuan via
@ 2024-09-03 10:11     ` Stefano Garzarella
  0 siblings, 0 replies; 5+ messages in thread
From: Stefano Garzarella @ 2024-09-03 10:11 UTC (permalink / raw)
  To: Gao,Shiyuan
  Cc: Michael S. Tsirkin, Jason Wang, Zuo,Boqun, qemu-devel@nongnu.org

On Thu, Aug 29, 2024 at 01:13:43PM GMT, Gao,Shiyuan wrote:
>> >--- a/hw/virtio/virtio-pci.c
>> >+++ b/hw/virtio/virtio-pci.c
>> >@@ -610,19 +610,29 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
>> > {
>> >     int i;
>> >     VirtIOPCIRegion *reg;
>> >+    MemoryRegion *mr = NULL;
>>
>> `mr` looks unused.
>>
>> >+    MemoryRegionSection mrs;
>>
>> Please, can you move this declaration in the inner block where it's
>> used?
>
>ok, I will move to inner block and remove unused `mr`.
>
>>
>> >
>> >     for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
>> >         reg = &proxy->regs[i];
>> >         if (*off >= reg->offset &&
>> >             *off + len <= reg->offset + reg->size) {
>> >-            *off -= reg->offset;
>> >-            return &reg->mr;
>> >+            mrs = memory_region_find(&reg->mr, *off - reg->offset,
>> >len);
>> >+            if (!mrs.mr) {
>> >+                error_report("Failed to find memory region for address"
>> >+                             "0x%" PRIx64 "", *off);
>> >+                return NULL;
>> >+            }
>> >+            *off = mrs.offset_within_region;
>> >+            memory_region_unref(mrs.mr);
>> >+            return mrs.mr;
>> >         }
>> >     }
>> >
>> >     return NULL;
>> > }
>> >
>> >+
>>
>> Unrelated change.
>
>Perhaps this would be clearer but not universal in Version 1.
>
>Without this patch, Only lookup common/isr/device/notify MR and
>exclude their subregions.
>
>When VHOST_USER_PROTOCOL_F_HOST_NOTIFIER enable, the notify MR has
>host-notifier subregions and we need use host-notifier MR to
>notify the hardware accelerator directly.
>
>Further more, maybe common/isr/device MR also has subregions in
>the future, so need memory_region_find for each MR incluing
>their subregions and this will be more universal.

I see, I don't have much experience with this, but what you say I think
makes sense. I would wait for a comment from Michael or Jason.

Thanks,
Stefano

>
>@@ -610,13 +610,22 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
> {
>     int i;
>     VirtIOPCIRegion *reg;
>+    MemoryRegion *mr, *submr;
>
>     for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
>         reg = &proxy->regs[i];
>         if (*off >= reg->offset &&
>             *off + len <= reg->offset + reg->size) {
>             *off -= reg->offset;
>-            return &reg->mr;
>+            mr = &reg->mr;
>+            QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
>+                if (*off >= submr->addr &&
>+                    *off + len < submr->addr + submr->size) {
>+                    *off -= submr->addr;
>+                    return submr;
>+                }
>+            }
>+            return mr;
>         }
>     }
>



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

* Re: [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR
  2024-08-20 11:56 [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR Gao Shiyuan via
  2024-08-27 13:41 ` Stefano Garzarella
@ 2024-09-03 10:19 ` Michael S. Tsirkin
  1 sibling, 0 replies; 5+ messages in thread
From: Michael S. Tsirkin @ 2024-09-03 10:19 UTC (permalink / raw)
  To: Gao Shiyuan; +Cc: Stefano Garzarella, Jason Wang, zuoboqun, qemu-devel

On Tue, Aug 20, 2024 at 07:56:31PM +0800, Gao Shiyuan wrote:
> When VHOST_USER_PROTOCOL_F_HOST_NOTIFIER feature negotiated and
> virtio_queue_set_host_notifier_mr success on system blk
> device's queue, the VM can't load MBR if the notify region's
> address above 4GB.
> 
> Assign the address of notify region in the modern bar above 4G, the vp_notify
> in SeaBIOS will use PCI Cfg Capability to write notify region. This will trap
> into QEMU and be handled by the host bridge when we don't enable mmconfig.
> QEMU will call virtio_write_config and since it writes to the BAR region
> through the PCI Cfg Capability, it will call virtio_address_space_write.
> 
> virtio_queue_set_host_notifier_mr add host notifier subregion of notify region
> MR, QEMU need write the mmap address instead of eventfd notify the hardware
> accelerator at the vhost-user backend. So virtio_address_space_lookup in
> virtio_address_space_write need return a host-notifier subregion of notify MR
> instead of notify MR.
> 
> Add lookup subregion of VirtIOPCIRegion MR instead of only lookup container MR.
> 
> Fixes: a93c8d8 ("virtio-pci: Replace modern_as with direct access to modern_bar")
> 
> Co-developed-by: Zuo Boqun <zuoboqun@baidu.com>
> Signed-off-by: Gao Shiyuan <gaoshiyuan@baidu.com>
> Signed-off-by: Zuo Boqun <zuoboqun@baidu.com>
> ---
>  hw/virtio/virtio-pci.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> ---
> v1 -> v2:
> * modify commit message
> * replace direct iteration over subregions with memory_region_find.
> 
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 9534730bba..5d2d27a6a3 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -610,19 +610,29 @@ static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
>  {
>      int i;
>      VirtIOPCIRegion *reg;
> +    MemoryRegion *mr = NULL;
> +    MemoryRegionSection mrs;
>  
>      for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
>          reg = &proxy->regs[i];
>          if (*off >= reg->offset &&
>              *off + len <= reg->offset + reg->size) {
> -            *off -= reg->offset;
> -            return &reg->mr;
> +            mrs = memory_region_find(&reg->mr, *off - reg->offset, len);
> +            if (!mrs.mr) {
> +                error_report("Failed to find memory region for address"
> +                             "0x%" PRIx64 "", *off);
> +                return NULL;
> +            }


I'm not sure when can this happen. If it can't assert will do.


> +            *off = mrs.offset_within_region;
> +            memory_region_unref(mrs.mr);
> +            return mrs.mr;
>          }
>      }
>  
>      return NULL;
>  }
>  
> +
>  /* Below are generic functions to do memcpy from/to an address space,
>   * without byteswaps, with input validation.
>   *
> -- 
> 2.39.3 (Apple Git-146)



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

end of thread, other threads:[~2024-09-03 12:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-20 11:56 [PATCH V2 1/1] virtio-pci: Add lookup subregion of VirtIOPCIRegion MR Gao Shiyuan via
2024-08-27 13:41 ` Stefano Garzarella
2024-08-29 13:13   ` Gao,Shiyuan via
2024-09-03 10:11     ` Stefano Garzarella
2024-09-03 10:19 ` Michael S. Tsirkin

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