[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 3/4] memory: split memory_region_from_host from
From: |
Marc-André Lureau |
Subject: |
Re: [Qemu-devel] [PATCH 3/4] memory: split memory_region_from_host from qemu_ram_addr_from_host |
Date: |
Thu, 26 May 2016 15:19:23 +0200 |
Hi
On Thu, May 26, 2016 at 10:49 AM, Paolo Bonzini <address@hidden> 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 <address@hidden>
> ---
> 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 <address@hidden>
--
Marc-André Lureau
- [Qemu-devel] [PATCH 0/4] More cleanups for RAMBlock/ram_addr_t vs. MemoryRegion, Paolo Bonzini, 2016/05/26
- [Qemu-devel] [PATCH 3/4] memory: split memory_region_from_host from qemu_ram_addr_from_host, Paolo Bonzini, 2016/05/26
- Re: [Qemu-devel] [PATCH 3/4] memory: split memory_region_from_host from qemu_ram_addr_from_host,
Marc-André Lureau <=
- [Qemu-devel] [PATCH 4/4] exec: hide mr->ram_addr from qemu_get_ram_ptr users, Paolo Bonzini, 2016/05/26
- [Qemu-devel] [PATCH 1/4] memory: remove qemu_get_ram_fd, qemu_set_ram_fd, qemu_ram_block_host_ptr, Paolo Bonzini, 2016/05/26
- [Qemu-devel] [PATCH 2/4] exec: remove ram_addr argument from qemu_ram_block_from_host, Paolo Bonzini, 2016/05/26