diff options
author | Avi Kivity <avi@redhat.com> | 2012-02-13 20:21:20 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-02-29 13:44:45 +0200 |
commit | 2999097bf178536188b0f4caf937c4d347e96627 (patch) | |
tree | 41e49c6289c0e2a28331e57bc20c8c41d9913f5d /exec.c | |
parent | f7bf546118837a64d4b04dd650e3f64eaa25e623 (diff) | |
download | qemu-2999097bf178536188b0f4caf937c4d347e96627.zip qemu-2999097bf178536188b0f4caf937c4d347e96627.tar.gz qemu-2999097bf178536188b0f4caf937c4d347e96627.tar.bz2 |
memory: change phys_page_set() to set multiple pages
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 41 |
1 files changed, 23 insertions, 18 deletions
@@ -436,8 +436,9 @@ static void phys_map_nodes_reset(void) } -static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t index, - uint16_t leaf, int level) +static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index, + target_phys_addr_t *nb, uint16_t leaf, + int level) { PhysPageEntry *p; int i; @@ -453,20 +454,27 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t index, } else { p = phys_map_nodes[lp->u.node]; } - lp = &p[(index >> (level * L2_BITS)) & (L2_SIZE - 1)]; + lp = &p[(*index >> (level * L2_BITS)) & (L2_SIZE - 1)]; - if (level == 0) { - lp->u.leaf = leaf; - } else { - phys_page_set_level(lp, index, leaf, level - 1); + while (*nb && lp < &p[L2_SIZE]) { + if (level == 0) { + lp->u.leaf = leaf; + ++*index; + --*nb; + } else { + phys_page_set_level(lp, index, nb, leaf, level - 1); + } + ++lp; } } -static void phys_page_set(target_phys_addr_t index, uint16_t leaf) +static void phys_page_set(target_phys_addr_t index, target_phys_addr_t nb, + uint16_t leaf) { - phys_map_node_reserve(P_L2_LEVELS); + /* Wildly overreserve - it doesn't matter much. */ + phys_map_node_reserve((nb + L2_SIZE - 1) / L2_SIZE * P_L2_LEVELS); - phys_page_set_level(&phys_map, index, leaf, P_L2_LEVELS - 1); + phys_page_set_level(&phys_map, &index, &nb, leaf, P_L2_LEVELS - 1); } static MemoryRegionSection phys_page_find(target_phys_addr_t index) @@ -2630,7 +2638,8 @@ static void register_subpage(MemoryRegionSection *section) if (!(existing.mr->subpage)) { subpage = subpage_init(base); subsection.mr = &subpage->iomem; - phys_page_set(base >> TARGET_PAGE_BITS, phys_section_add(&subsection)); + phys_page_set(base >> TARGET_PAGE_BITS, 1, + phys_section_add(&subsection)); } else { subpage = container_of(existing.mr, subpage_t, iomem); } @@ -2644,18 +2653,14 @@ static void register_multipage(MemoryRegionSection *section) { target_phys_addr_t start_addr = section->offset_within_address_space; ram_addr_t size = section->size; - target_phys_addr_t addr, end_addr; + target_phys_addr_t addr; uint16_t section_index = phys_section_add(section); assert(size); - end_addr = start_addr + (target_phys_addr_t)size; - addr = start_addr; - do { - phys_page_set(addr >> TARGET_PAGE_BITS, section_index); - addr += TARGET_PAGE_SIZE; - } while (addr != end_addr); + phys_page_set(addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS, + section_index); } void cpu_register_physical_memory_log(MemoryRegionSection *section, |