diff mbox

[3/4] memory: split memory_region_from_host from qemu_ram_addr_from_host

Message ID 1464252584-30832-4-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini May 26, 2016, 8:49 a.m. UTC
Move the old qemu_ram_addr_from_host to memory_region_from_host and
make it return an offset within the region.  For qemu_ram_addr_from_host
return the ram_addr_t directly, similar to what it was before
commit 1b5ec23 ("memory: return MemoryRegion from qemu_ram_addr_from_host",
2013-07-04).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cputlb.c                  |  3 ++-
 exec.c                    | 10 +++++-----
 hw/virtio/vhost-user.c    | 16 +++++++---------
 include/exec/cpu-common.h |  2 +-
 include/exec/memory.h     | 20 ++++++++++++++++++++
 memory.c                  | 14 ++++++++++++--
 target-i386/kvm.c         |  6 ++++--
 7 files changed, 51 insertions(+), 20 deletions(-)

Comments

Marc-André Lureau May 26, 2016, 1:19 p.m. UTC | #1
Hi

On Thu, May 26, 2016 at 10:49 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Move the old qemu_ram_addr_from_host to memory_region_from_host and
> make it return an offset within the region.  For qemu_ram_addr_from_host
> return the ram_addr_t directly, similar to what it was before
> commit 1b5ec23 ("memory: return MemoryRegion from qemu_ram_addr_from_host",
> 2013-07-04).
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  cputlb.c                  |  3 ++-
>  exec.c                    | 10 +++++-----
>  hw/virtio/vhost-user.c    | 16 +++++++---------
>  include/exec/cpu-common.h |  2 +-
>  include/exec/memory.h     | 20 ++++++++++++++++++++
>  memory.c                  | 14 ++++++++++++--
>  target-i386/kvm.c         |  6 ++++--
>  7 files changed, 51 insertions(+), 20 deletions(-)
>
> diff --git a/cputlb.c b/cputlb.c
> index 1ff6354..23c9b91 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -246,7 +246,8 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
>  {
>      ram_addr_t ram_addr;
>
> -    if (qemu_ram_addr_from_host(ptr, &ram_addr) == NULL) {
> +    ram_addr = qemu_ram_addr_from_host(ptr);
> +    if (ram_addr == RAM_ADDR_INVALID) {
>          fprintf(stderr, "Bad ram pointer %p\n", ptr);
>          abort();
>      }
> diff --git a/exec.c b/exec.c
> index 65bad53..7f62835 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1964,18 +1964,17 @@ RAMBlock *qemu_ram_block_by_name(const char *name)
>
>  /* Some of the softmmu routines need to translate from a host pointer
>     (typically a TLB entry) back to a ram offset.  */
> -MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
> +ram_addr_t qemu_ram_addr_from_host(void *ptr)
>  {
>      RAMBlock *block;
>      ram_addr_t offset;
>
>      block = qemu_ram_block_from_host(ptr, false, &offset);
> -    *ram_addr = block->offset + offset;
>      if (!block) {
> -        return NULL;
> +        return RAM_ADDR_INVALID;
>      }
>
> -    return block->mr;
> +    return block->offset + offset;
>  }
>
>  /* Called within RCU critical section.  */
> @@ -2975,8 +2974,9 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
>          MemoryRegion *mr;
>          ram_addr_t addr1;
>
> -        mr = qemu_ram_addr_from_host(buffer, &addr1);
> +        mr = memory_region_from_host(buffer, &addr1);
>          assert(mr != NULL);
> +        addr1 += memory_region_get_ram_addr(mr);
>          if (is_write) {
>              invalidate_and_set_dirty(mr, addr1, access_len);
>          }
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 41908c0..495e09f 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -17,7 +17,6 @@
>  #include "sysemu/kvm.h"
>  #include "qemu/error-report.h"
>  #include "qemu/sockets.h"
> -#include "exec/ram_addr.h"
>  #include "migration/migration.h"
>
>  #include <sys/ioctl.h>
> @@ -247,19 +246,18 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
>
>      for (i = 0; i < dev->mem->nregions; ++i) {
>          struct vhost_memory_region *reg = dev->mem->regions + i;
> -        ram_addr_t ram_addr;
> +        ram_addr_t offset;
>          MemoryRegion *mr;
>
>          assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
> -        mr = qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
> -                                     &ram_addr);
> +        mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
> +                                     &offset);
>          fd = memory_region_get_fd(mr);
>          if (fd > 0) {
>              msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
>              msg.payload.memory.regions[fd_num].memory_size  = reg->memory_size;
>              msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
> -            msg.payload.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
> -                (uintptr_t) memory_region_get_ram_ptr(mr);
> +            msg.payload.memory.regions[fd_num].mmap_offset = offset;
>              assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
>              fds[fd_num++] = fd;
>          }
> @@ -617,14 +615,14 @@ static bool vhost_user_can_merge(struct vhost_dev *dev,
>                                   uint64_t start1, uint64_t size1,
>                                   uint64_t start2, uint64_t size2)
>  {
> -    ram_addr_t ram_addr;
> +    ram_addr_t offset;
>      int mfd, rfd;
>      MemoryRegion *mr;
>
> -    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
> +    mr = memory_region_from_host((void *)(uintptr_t)start1, &offset);
>      mfd = memory_region_get_fd(mr);
>
> -    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
> +    mr = memory_region_from_host((void *)(uintptr_t)start2, &offset);
>      rfd = memory_region_get_fd(mr);
>
>      return mfd == rfd;
> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
> index fc609ad..aaee995 100644
> --- a/include/exec/cpu-common.h
> +++ b/include/exec/cpu-common.h
> @@ -57,7 +57,7 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
>
>  void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
>  /* This should not be used by devices.  */
> -MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
> +ram_addr_t qemu_ram_addr_from_host(void *ptr);
>  RAMBlock *qemu_ram_block_by_name(const char *name);
>  RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
>                                     ram_addr_t *offset);
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 1678494..71a27ab 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -32,6 +32,8 @@
>  #include "qom/object.h"
>  #include "qemu/rcu.h"
>
> +#define RAM_ADDR_INVALID (~(ram_addr_t)0)
> +
>  #define MAX_PHYS_ADDR_SPACE_BITS 62
>  #define MAX_PHYS_ADDR            (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
>
> @@ -678,6 +680,24 @@ int memory_region_get_fd(MemoryRegion *mr);
>  void memory_region_set_fd(MemoryRegion *mr, int fd);
>
>  /**
> + * memory_region_from_host: Convert a pointer into a RAM memory region
> + * and an offset within it.
> + *
> + * Given a host pointer inside a RAM memory region (created with
> + * memory_region_init_ram() or memory_region_init_ram_ptr()), return
> + * the MemoryRegion and the offset within it.
> + *
> + * Use with care; by the time this function returns, the returned pointer is
> + * not protected by RCU anymore.  If the caller is not within an RCU critical
> + * section and does not hold the iothread lock, it must have other means of
> + * protecting the pointer, such as a reference to the region that includes
> + * the incoming ram_addr_t.
> + *
> + * @mr: the memory region being queried.

@ptr: host pointer to look up
@offset: set to result offset within the MemoryRegion

> + */
> +MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset);
> +
> +/**
>   * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
>   *
>   * Returns a host pointer to a RAM memory region (created with
> diff --git a/memory.c b/memory.c
> index d6a4a68..f8085ea 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -33,8 +33,6 @@
>
>  //#define DEBUG_UNASSIGNED
>
> -#define RAM_ADDR_INVALID (~(ram_addr_t)0)
> -
>  static unsigned memory_region_transaction_depth;
>  static bool memory_region_update_pending;
>  static bool ioeventfd_update_pending;
> @@ -1665,6 +1663,18 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
>      return ptr + offset;
>  }
>
> +MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset)
> +{
> +    RAMBlock *block;
> +
> +    block = qemu_ram_block_from_host(ptr, false, offset);
> +    if (!block) {
> +        return NULL;
> +    }
> +
> +    return block->mr;
> +}
> +
>  ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
>  {
>      return mr->ram_block ? mr->ram_block->offset : RAM_ADDR_INVALID;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 7b3667a..abf50e6 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -411,7 +411,8 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
>
>      if ((env->mcg_cap & MCG_SER_P) && addr
>          && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
> -        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
> +        ram_addr = qemu_ram_addr_from_host(addr);
> +        if (ram_addr == RAM_ADDR_INVALID ||
>              !kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
>              fprintf(stderr, "Hardware memory error for memory used by "
>                      "QEMU itself instead of guest system!\n");
> @@ -445,7 +446,8 @@ int kvm_arch_on_sigbus(int code, void *addr)
>          hwaddr paddr;
>
>          /* Hope we are lucky for AO MCE */
> -        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
> +        ram_addr = qemu_ram_addr_from_host(addr);
> +        if (ram_addr == RAM_ADDR_INVALID ||
>              !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
>                                                  addr, &paddr)) {
>              fprintf(stderr, "Hardware memory error for memory used by "
> --
> 2.5.5
>
>
>


Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
diff mbox

Patch

diff --git a/cputlb.c b/cputlb.c
index 1ff6354..23c9b91 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -246,7 +246,8 @@  static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
 {
     ram_addr_t ram_addr;
 
-    if (qemu_ram_addr_from_host(ptr, &ram_addr) == NULL) {
+    ram_addr = qemu_ram_addr_from_host(ptr);
+    if (ram_addr == RAM_ADDR_INVALID) {
         fprintf(stderr, "Bad ram pointer %p\n", ptr);
         abort();
     }
diff --git a/exec.c b/exec.c
index 65bad53..7f62835 100644
--- a/exec.c
+++ b/exec.c
@@ -1964,18 +1964,17 @@  RAMBlock *qemu_ram_block_by_name(const char *name)
 
 /* Some of the softmmu routines need to translate from a host pointer
    (typically a TLB entry) back to a ram offset.  */
-MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
+ram_addr_t qemu_ram_addr_from_host(void *ptr)
 {
     RAMBlock *block;
     ram_addr_t offset;
 
     block = qemu_ram_block_from_host(ptr, false, &offset);
-    *ram_addr = block->offset + offset;
     if (!block) {
-        return NULL;
+        return RAM_ADDR_INVALID;
     }
 
-    return block->mr;
+    return block->offset + offset;
 }
 
 /* Called within RCU critical section.  */
@@ -2975,8 +2974,9 @@  void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
         MemoryRegion *mr;
         ram_addr_t addr1;
 
-        mr = qemu_ram_addr_from_host(buffer, &addr1);
+        mr = memory_region_from_host(buffer, &addr1);
         assert(mr != NULL);
+        addr1 += memory_region_get_ram_addr(mr);
         if (is_write) {
             invalidate_and_set_dirty(mr, addr1, access_len);
         }
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 41908c0..495e09f 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -17,7 +17,6 @@ 
 #include "sysemu/kvm.h"
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
-#include "exec/ram_addr.h"
 #include "migration/migration.h"
 
 #include <sys/ioctl.h>
@@ -247,19 +246,18 @@  static int vhost_user_set_mem_table(struct vhost_dev *dev,
 
     for (i = 0; i < dev->mem->nregions; ++i) {
         struct vhost_memory_region *reg = dev->mem->regions + i;
-        ram_addr_t ram_addr;
+        ram_addr_t offset;
         MemoryRegion *mr;
 
         assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
-        mr = qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
-                                     &ram_addr);
+        mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
+                                     &offset);
         fd = memory_region_get_fd(mr);
         if (fd > 0) {
             msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
             msg.payload.memory.regions[fd_num].memory_size  = reg->memory_size;
             msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
-            msg.payload.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
-                (uintptr_t) memory_region_get_ram_ptr(mr);
+            msg.payload.memory.regions[fd_num].mmap_offset = offset;
             assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
             fds[fd_num++] = fd;
         }
@@ -617,14 +615,14 @@  static bool vhost_user_can_merge(struct vhost_dev *dev,
                                  uint64_t start1, uint64_t size1,
                                  uint64_t start2, uint64_t size2)
 {
-    ram_addr_t ram_addr;
+    ram_addr_t offset;
     int mfd, rfd;
     MemoryRegion *mr;
 
-    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
+    mr = memory_region_from_host((void *)(uintptr_t)start1, &offset);
     mfd = memory_region_get_fd(mr);
 
-    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
+    mr = memory_region_from_host((void *)(uintptr_t)start2, &offset);
     rfd = memory_region_get_fd(mr);
 
     return mfd == rfd;
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index fc609ad..aaee995 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -57,7 +57,7 @@  typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should not be used by devices.  */
-MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
+ram_addr_t qemu_ram_addr_from_host(void *ptr);
 RAMBlock *qemu_ram_block_by_name(const char *name);
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
                                    ram_addr_t *offset);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 1678494..71a27ab 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -32,6 +32,8 @@ 
 #include "qom/object.h"
 #include "qemu/rcu.h"
 
+#define RAM_ADDR_INVALID (~(ram_addr_t)0)
+
 #define MAX_PHYS_ADDR_SPACE_BITS 62
 #define MAX_PHYS_ADDR            (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
 
@@ -678,6 +680,24 @@  int memory_region_get_fd(MemoryRegion *mr);
 void memory_region_set_fd(MemoryRegion *mr, int fd);
 
 /**
+ * memory_region_from_host: Convert a pointer into a RAM memory region
+ * and an offset within it.
+ *
+ * Given a host pointer inside a RAM memory region (created with
+ * memory_region_init_ram() or memory_region_init_ram_ptr()), return
+ * the MemoryRegion and the offset within it.
+ *
+ * Use with care; by the time this function returns, the returned pointer is
+ * not protected by RCU anymore.  If the caller is not within an RCU critical
+ * section and does not hold the iothread lock, it must have other means of
+ * protecting the pointer, such as a reference to the region that includes
+ * the incoming ram_addr_t.
+ *
+ * @mr: the memory region being queried.
+ */
+MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset);
+
+/**
  * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
  *
  * Returns a host pointer to a RAM memory region (created with
diff --git a/memory.c b/memory.c
index d6a4a68..f8085ea 100644
--- a/memory.c
+++ b/memory.c
@@ -33,8 +33,6 @@ 
 
 //#define DEBUG_UNASSIGNED
 
-#define RAM_ADDR_INVALID (~(ram_addr_t)0)
-
 static unsigned memory_region_transaction_depth;
 static bool memory_region_update_pending;
 static bool ioeventfd_update_pending;
@@ -1665,6 +1663,18 @@  void *memory_region_get_ram_ptr(MemoryRegion *mr)
     return ptr + offset;
 }
 
+MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset)
+{
+    RAMBlock *block;
+
+    block = qemu_ram_block_from_host(ptr, false, offset);
+    if (!block) {
+        return NULL;
+    }
+
+    return block->mr;
+}
+
 ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
 {
     return mr->ram_block ? mr->ram_block->offset : RAM_ADDR_INVALID;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 7b3667a..abf50e6 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -411,7 +411,8 @@  int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
 
     if ((env->mcg_cap & MCG_SER_P) && addr
         && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
-        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
+        ram_addr = qemu_ram_addr_from_host(addr);
+        if (ram_addr == RAM_ADDR_INVALID ||
             !kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
                     "QEMU itself instead of guest system!\n");
@@ -445,7 +446,8 @@  int kvm_arch_on_sigbus(int code, void *addr)
         hwaddr paddr;
 
         /* Hope we are lucky for AO MCE */
-        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
+        ram_addr = qemu_ram_addr_from_host(addr);
+        if (ram_addr == RAM_ADDR_INVALID ||
             !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
                                                 addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "