diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-11-22 12:04:31 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-12-22 16:00:23 +0100 |
commit | 715c31ec8e12107f47ac74b464c97e813c76f898 (patch) | |
tree | 61ea083c4b22600d0430ed66950ae3c31636c41d /exec.c | |
parent | 0ce265ffef87f19f4dd1ff0663e09a63d66ae408 (diff) | |
download | qemu-715c31ec8e12107f47ac74b464c97e813c76f898.zip qemu-715c31ec8e12107f47ac74b464c97e813c76f898.tar.gz qemu-715c31ec8e12107f47ac74b464c97e813c76f898.tar.bz2 |
exec: introduce address_space_extend_translation
This extracts the common part of address_space_map and
address_space_cache_init into a new function.
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 50 |
1 files changed, 29 insertions, 21 deletions
@@ -2938,6 +2938,31 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_ return true; } +static hwaddr +address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_len, + MemoryRegion *mr, hwaddr base, hwaddr len, + bool is_write) +{ + hwaddr done = 0; + hwaddr xlat; + MemoryRegion *this_mr; + + for (;;) { + target_len -= len; + addr += len; + done += len; + if (target_len == 0) { + return done; + } + + len = target_len; + this_mr = address_space_translate(as, addr, &xlat, &len, is_write); + if (this_mr != mr || xlat != base + done) { + return done; + } + } +} + /* Map a physical memory region into a host virtual address. * May map a subset of the requested range, given by and returned in *plen. * May return NULL if resources needed to perform the mapping are exhausted. @@ -2951,9 +2976,8 @@ void *address_space_map(AddressSpace *as, bool is_write) { hwaddr len = *plen; - hwaddr done = 0; - hwaddr l, xlat, base; - MemoryRegion *mr, *this_mr; + hwaddr l, xlat; + MemoryRegion *mr; void *ptr; if (len == 0) { @@ -2987,26 +3011,10 @@ void *address_space_map(AddressSpace *as, return bounce.buffer; } - base = xlat; - - for (;;) { - len -= l; - addr += l; - done += l; - if (len == 0) { - break; - } - - l = len; - this_mr = address_space_translate(as, addr, &xlat, &l, is_write); - if (this_mr != mr || xlat != base + done) { - break; - } - } memory_region_ref(mr); - *plen = done; - ptr = qemu_ram_ptr_length(mr->ram_block, base, plen); + *plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write); + ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen); rcu_read_unlock(); return ptr; |