mirror of https://gitee.com/openkylin/qemu.git
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>
This commit is contained in:
parent
0ce265ffef
commit
715c31ec8e
50
exec.c
50
exec.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue