diff options
author | Richard Braun <rbraun@sceen.net> | 2014-05-14 21:29:37 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2014-05-14 21:29:37 +0200 |
commit | 75857f8a118763c4f9b2716b94c5503ee2b5d449 (patch) | |
tree | 3f6dd5cfbed1dabf4a0fe146f1df34a0f0a3d036 /arch/x86/machine/pmap.c | |
parent | a9a0eb0f6fb7d11b0be15fad729aad974a9b8932 (diff) |
x86/pmap: fix PTEs accounting on page table duplication
Diffstat (limited to 'arch/x86/machine/pmap.c')
-rw-r--r-- | arch/x86/machine/pmap.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/x86/machine/pmap.c b/arch/x86/machine/pmap.c index 7869ee0..be6a26c 100644 --- a/arch/x86/machine/pmap.c +++ b/arch/x86/machine/pmap.c @@ -902,12 +902,12 @@ pmap_setup(void) } static void __init -pmap_copy_cpu_table_recursive(phys_addr_t pa, unsigned int level, - unsigned long start_va) +pmap_copy_cpu_table_recursive(struct vm_page *page, phys_addr_t pa, + unsigned long start_va, unsigned int level) { const struct pmap_pt_level *pt_level; struct pmap_tmp_mapping *mapping; - struct vm_page *page; + const struct vm_page *orig_page; pmap_pte_t *spt, *dpt; phys_addr_t lower_pa; unsigned int i, nr_ptps, first = first, last = last; @@ -917,6 +917,10 @@ pmap_copy_cpu_table_recursive(phys_addr_t pa, unsigned int level, pt_level = &pmap_pt_levels[level]; spt = &pt_level->ptemap_base[PMAP_PTEMAP_INDEX(start_va, pt_level->shift)]; + orig_page = vm_kmem_lookup_page((unsigned long)spt); + assert(orig_page != NULL); + page->pmap_page.nr_ptes = orig_page->pmap_page.nr_ptes; + if (level == PMAP_NR_LEVELS - 1) { is_root = 1; nr_ptps = PMAP_NR_RPTPS; @@ -961,7 +965,7 @@ pmap_copy_cpu_table_recursive(phys_addr_t pa, unsigned int level, pmap_unmap_ptp(mapping, nr_ptps); - pmap_copy_cpu_table_recursive(lower_pa, level - 1, va); + pmap_copy_cpu_table_recursive(page, lower_pa, va, level - 1); mapping = pmap_map_ptp(pa, nr_ptps); dpt = (pmap_pte_t *)mapping->va; @@ -982,7 +986,7 @@ pmap_copy_cpu_table(unsigned int cpu) page = vm_page_alloc(PMAP_RPTP_ORDER, VM_PAGE_PMAP); assert(page != NULL); pa = vm_page_to_pa(page); - pmap_copy_cpu_table_recursive(pa, PMAP_NR_LEVELS - 1, 0); + pmap_copy_cpu_table_recursive(page, pa, 0, PMAP_NR_LEVELS - 1); cpu_table->root_ptp_pa = pa; #ifdef X86_PAE |