Patchwork [RFC,v9,06/27] virtio-blk: Take PCI memory range into account

login
register
mail settings
Submitter Stefan Hajnoczi
Date July 18, 2012, 3:07 p.m.
Message ID <1342624074-24650-7-git-send-email-stefanha@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/171720/
State New
Headers show

Comments

Stefan Hajnoczi - July 18, 2012, 3:07 p.m.
Support >4 GB physical memory accesses.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/virtio-blk.c |    7 +++++++
 1 file changed, 7 insertions(+)
Michael S. Tsirkin - July 18, 2012, 6:29 p.m.
On Wed, Jul 18, 2012 at 04:07:33PM +0100, Stefan Hajnoczi wrote:
> Support >4 GB physical memory accesses.
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Need some sane APIs, this is just too scary.

> ---
>  hw/virtio-blk.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
> index abd9386..99654f1 100644
> --- a/hw/virtio-blk.c
> +++ b/hw/virtio-blk.c
> @@ -64,6 +64,13 @@ static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
>   */
>  static inline void *phys_to_host(VirtIOBlock *s, target_phys_addr_t phys)
>  {
> +    /* Adjust for 3.6-4 GB PCI memory range */
> +    if (phys >= 0x100000000) {
> +        phys -= 0x100000000 - 0xe0000000;
> +    } else if (phys >= 0xe0000000) {
> +        fprintf(stderr, "phys_to_host bad physical address in PCI range %#lx\n", phys);
> +        exit(1);
> +    }
>      return s->phys_mem_zero_host_ptr + phys;
>  }
>  
> -- 
> 1.7.10.4
Stefan Hajnoczi - July 19, 2012, 9:14 a.m.
On Wed, Jul 18, 2012 at 7:29 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Wed, Jul 18, 2012 at 04:07:33PM +0100, Stefan Hajnoczi wrote:
>> Support >4 GB physical memory accesses.
>>
>> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> Need some sane APIs, this is just too scary.

Yes, this prototype has (at least) two layering violations:
1. Bypassing QEMU's memory subsystem because it isn't thread-safe.
2. Bypassing block layer and extracting the underlying fd out of a
raw-posix file, allowing us to do our own Linux AIO.

Stefan
Stefan Hajnoczi - July 19, 2012, 9:16 a.m.
On Thu, Jul 19, 2012 at 10:14 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Wed, Jul 18, 2012 at 7:29 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> On Wed, Jul 18, 2012 at 04:07:33PM +0100, Stefan Hajnoczi wrote:
>>> Support >4 GB physical memory accesses.
>>>
>>> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>
>> Need some sane APIs, this is just too scary.
>
> Yes, this prototype has (at least) two layering violations:
> 1. Bypassing QEMU's memory subsystem because it isn't thread-safe.

Maybe we can use MemoryListener to fix this, although we need to take
care of thread-safety.

Stefan
Avi Kivity - July 19, 2012, 9:29 a.m.
On 07/19/2012 12:16 PM, Stefan Hajnoczi wrote:
> On Thu, Jul 19, 2012 at 10:14 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
>> On Wed, Jul 18, 2012 at 7:29 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>>> On Wed, Jul 18, 2012 at 04:07:33PM +0100, Stefan Hajnoczi wrote:
>>>> Support >4 GB physical memory accesses.
>>>>
>>>> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>
>>> Need some sane APIs, this is just too scary.
>>
>> Yes, this prototype has (at least) two layering violations:
>> 1. Bypassing QEMU's memory subsystem because it isn't thread-safe.
> 
> Maybe we can use MemoryListener to fix this, although we need to take
> care of thread-safety.

Better to fix up the memory core.  It should be relatively easy to
rcu-ify it, as it already works by building a new memory map instead of
updating it in place.  Currently it has one root pointer, all that is
needed is to build it into a temporary pointer, then use
rcu_assign_pointer() to atomically switch the memory map.

Patch

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index abd9386..99654f1 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -64,6 +64,13 @@  static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
  */
 static inline void *phys_to_host(VirtIOBlock *s, target_phys_addr_t phys)
 {
+    /* Adjust for 3.6-4 GB PCI memory range */
+    if (phys >= 0x100000000) {
+        phys -= 0x100000000 - 0xe0000000;
+    } else if (phys >= 0xe0000000) {
+        fprintf(stderr, "phys_to_host bad physical address in PCI range %#lx\n", phys);
+        exit(1);
+    }
     return s->phys_mem_zero_host_ptr + phys;
 }