Message ID | 1464252584-30832-4-git-send-email-pbonzini@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 --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 "
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(-)