diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/xen/enlighten.c | 3 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 5 | ||||
-rw-r--r-- | arch/x86/xen/p2m.c | 65 |
3 files changed, 18 insertions, 55 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 1a3f0445432a..fac5e4f9607c 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1636,9 +1636,6 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1636 | xen_raw_console_write("mapping kernel into physical memory\n"); | 1636 | xen_raw_console_write("mapping kernel into physical memory\n"); |
1637 | xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base, xen_start_info->nr_pages); | 1637 | xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base, xen_start_info->nr_pages); |
1638 | 1638 | ||
1639 | /* Allocate and initialize top and mid mfn levels for p2m structure */ | ||
1640 | xen_build_mfn_list_list(); | ||
1641 | |||
1642 | /* keep using Xen gdt for now; no urgent need to change it */ | 1639 | /* keep using Xen gdt for now; no urgent need to change it */ |
1643 | 1640 | ||
1644 | #ifdef CONFIG_X86_32 | 1641 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index f62af7647ec9..a8a1a3d08d4d 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1217,10 +1217,13 @@ static void __init xen_pagetable_p2m_copy(void) | |||
1217 | static void __init xen_pagetable_init(void) | 1217 | static void __init xen_pagetable_init(void) |
1218 | { | 1218 | { |
1219 | paging_init(); | 1219 | paging_init(); |
1220 | xen_setup_shared_info(); | ||
1221 | #ifdef CONFIG_X86_64 | 1220 | #ifdef CONFIG_X86_64 |
1222 | xen_pagetable_p2m_copy(); | 1221 | xen_pagetable_p2m_copy(); |
1223 | #endif | 1222 | #endif |
1223 | /* Allocate and initialize top and mid mfn levels for p2m structure */ | ||
1224 | xen_build_mfn_list_list(); | ||
1225 | |||
1226 | xen_setup_shared_info(); | ||
1224 | xen_post_allocator_init(); | 1227 | xen_post_allocator_init(); |
1225 | } | 1228 | } |
1226 | static void xen_write_cr2(unsigned long cr2) | 1229 | static void xen_write_cr2(unsigned long cr2) |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 4534320e66e4..d1b3da2960ab 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -163,6 +163,7 @@ | |||
163 | #include <linux/hash.h> | 163 | #include <linux/hash.h> |
164 | #include <linux/sched.h> | 164 | #include <linux/sched.h> |
165 | #include <linux/seq_file.h> | 165 | #include <linux/seq_file.h> |
166 | #include <linux/bootmem.h> | ||
166 | 167 | ||
167 | #include <asm/cache.h> | 168 | #include <asm/cache.h> |
168 | #include <asm/setup.h> | 169 | #include <asm/setup.h> |
@@ -181,21 +182,20 @@ static void __init m2p_override_init(void); | |||
181 | 182 | ||
182 | unsigned long xen_max_p2m_pfn __read_mostly; | 183 | unsigned long xen_max_p2m_pfn __read_mostly; |
183 | 184 | ||
185 | static unsigned long *p2m_mid_missing_mfn; | ||
186 | static unsigned long *p2m_top_mfn; | ||
187 | static unsigned long **p2m_top_mfn_p; | ||
188 | |||
184 | /* Placeholders for holes in the address space */ | 189 | /* Placeholders for holes in the address space */ |
185 | static RESERVE_BRK_ARRAY(unsigned long, p2m_missing, P2M_PER_PAGE); | 190 | static RESERVE_BRK_ARRAY(unsigned long, p2m_missing, P2M_PER_PAGE); |
186 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_missing, P2M_MID_PER_PAGE); | 191 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_missing, P2M_MID_PER_PAGE); |
187 | static RESERVE_BRK_ARRAY(unsigned long, p2m_mid_missing_mfn, P2M_MID_PER_PAGE); | ||
188 | 192 | ||
189 | static RESERVE_BRK_ARRAY(unsigned long **, p2m_top, P2M_TOP_PER_PAGE); | 193 | static RESERVE_BRK_ARRAY(unsigned long **, p2m_top, P2M_TOP_PER_PAGE); |
190 | static RESERVE_BRK_ARRAY(unsigned long, p2m_top_mfn, P2M_TOP_PER_PAGE); | ||
191 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_top_mfn_p, P2M_TOP_PER_PAGE); | ||
192 | 194 | ||
193 | static RESERVE_BRK_ARRAY(unsigned long, p2m_identity, P2M_PER_PAGE); | 195 | static RESERVE_BRK_ARRAY(unsigned long, p2m_identity, P2M_PER_PAGE); |
194 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_identity, P2M_MID_PER_PAGE); | 196 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_identity, P2M_MID_PER_PAGE); |
195 | static RESERVE_BRK_ARRAY(unsigned long, p2m_mid_identity_mfn, P2M_MID_PER_PAGE); | ||
196 | 197 | ||
197 | RESERVE_BRK(p2m_mid, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); | 198 | RESERVE_BRK(p2m_mid, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); |
198 | RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); | ||
199 | 199 | ||
200 | /* For each I/O range remapped we may lose up to two leaf pages for the boundary | 200 | /* For each I/O range remapped we may lose up to two leaf pages for the boundary |
201 | * violations and three mid pages to cover up to 3GB. With | 201 | * violations and three mid pages to cover up to 3GB. With |
@@ -272,11 +272,11 @@ static void p2m_init(unsigned long *p2m) | |||
272 | * Build the parallel p2m_top_mfn and p2m_mid_mfn structures | 272 | * Build the parallel p2m_top_mfn and p2m_mid_mfn structures |
273 | * | 273 | * |
274 | * This is called both at boot time, and after resuming from suspend: | 274 | * This is called both at boot time, and after resuming from suspend: |
275 | * - At boot time we're called very early, and must use extend_brk() | 275 | * - At boot time we're called rather early, and must use alloc_bootmem*() |
276 | * to allocate memory. | 276 | * to allocate memory. |
277 | * | 277 | * |
278 | * - After resume we're called from within stop_machine, but the mfn | 278 | * - After resume we're called from within stop_machine, but the mfn |
279 | * tree should alreay be completely allocated. | 279 | * tree should already be completely allocated. |
280 | */ | 280 | */ |
281 | void __ref xen_build_mfn_list_list(void) | 281 | void __ref xen_build_mfn_list_list(void) |
282 | { | 282 | { |
@@ -287,20 +287,17 @@ void __ref xen_build_mfn_list_list(void) | |||
287 | 287 | ||
288 | /* Pre-initialize p2m_top_mfn to be completely missing */ | 288 | /* Pre-initialize p2m_top_mfn to be completely missing */ |
289 | if (p2m_top_mfn == NULL) { | 289 | if (p2m_top_mfn == NULL) { |
290 | p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | 290 | p2m_mid_missing_mfn = alloc_bootmem_align(PAGE_SIZE, PAGE_SIZE); |
291 | p2m_mid_mfn_init(p2m_mid_missing_mfn, p2m_missing); | 291 | p2m_mid_mfn_init(p2m_mid_missing_mfn, p2m_missing); |
292 | p2m_mid_identity_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
293 | p2m_mid_mfn_init(p2m_mid_identity_mfn, p2m_identity); | ||
294 | 292 | ||
295 | p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | 293 | p2m_top_mfn_p = alloc_bootmem_align(PAGE_SIZE, PAGE_SIZE); |
296 | p2m_top_mfn_p_init(p2m_top_mfn_p); | 294 | p2m_top_mfn_p_init(p2m_top_mfn_p); |
297 | 295 | ||
298 | p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | 296 | p2m_top_mfn = alloc_bootmem_align(PAGE_SIZE, PAGE_SIZE); |
299 | p2m_top_mfn_init(p2m_top_mfn); | 297 | p2m_top_mfn_init(p2m_top_mfn); |
300 | } else { | 298 | } else { |
301 | /* Reinitialise, mfn's all change after migration */ | 299 | /* Reinitialise, mfn's all change after migration */ |
302 | p2m_mid_mfn_init(p2m_mid_missing_mfn, p2m_missing); | 300 | p2m_mid_mfn_init(p2m_mid_missing_mfn, p2m_missing); |
303 | p2m_mid_mfn_init(p2m_mid_identity_mfn, p2m_identity); | ||
304 | } | 301 | } |
305 | 302 | ||
306 | for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) { | 303 | for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) { |
@@ -328,10 +325,9 @@ void __ref xen_build_mfn_list_list(void) | |||
328 | /* | 325 | /* |
329 | * XXX boot-time only! We should never find | 326 | * XXX boot-time only! We should never find |
330 | * missing parts of the mfn tree after | 327 | * missing parts of the mfn tree after |
331 | * runtime. extend_brk() will BUG if we call | 328 | * runtime. |
332 | * it too late. | ||
333 | */ | 329 | */ |
334 | mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | 330 | mid_mfn_p = alloc_bootmem_align(PAGE_SIZE, PAGE_SIZE); |
335 | p2m_mid_mfn_init(mid_mfn_p, p2m_missing); | 331 | p2m_mid_mfn_init(mid_mfn_p, p2m_missing); |
336 | 332 | ||
337 | p2m_top_mfn_p[topidx] = mid_mfn_p; | 333 | p2m_top_mfn_p[topidx] = mid_mfn_p; |
@@ -415,7 +411,6 @@ void __init xen_build_dynamic_phys_to_machine(void) | |||
415 | m2p_override_init(); | 411 | m2p_override_init(); |
416 | } | 412 | } |
417 | #ifdef CONFIG_X86_64 | 413 | #ifdef CONFIG_X86_64 |
418 | #include <linux/bootmem.h> | ||
419 | unsigned long __init xen_revector_p2m_tree(void) | 414 | unsigned long __init xen_revector_p2m_tree(void) |
420 | { | 415 | { |
421 | unsigned long va_start; | 416 | unsigned long va_start; |
@@ -477,7 +472,6 @@ unsigned long __init xen_revector_p2m_tree(void) | |||
477 | 472 | ||
478 | copy_page(new, mid_p); | 473 | copy_page(new, mid_p); |
479 | p2m_top[topidx][mididx] = &mfn_list[pfn_free]; | 474 | p2m_top[topidx][mididx] = &mfn_list[pfn_free]; |
480 | p2m_top_mfn_p[topidx][mididx] = virt_to_mfn(&mfn_list[pfn_free]); | ||
481 | 475 | ||
482 | pfn_free += P2M_PER_PAGE; | 476 | pfn_free += P2M_PER_PAGE; |
483 | 477 | ||
@@ -610,7 +604,6 @@ static bool __init early_alloc_p2m(unsigned long pfn, bool check_boundary) | |||
610 | { | 604 | { |
611 | unsigned topidx, mididx, idx; | 605 | unsigned topidx, mididx, idx; |
612 | unsigned long *p2m; | 606 | unsigned long *p2m; |
613 | unsigned long *mid_mfn_p; | ||
614 | 607 | ||
615 | topidx = p2m_top_index(pfn); | 608 | topidx = p2m_top_index(pfn); |
616 | mididx = p2m_mid_index(pfn); | 609 | mididx = p2m_mid_index(pfn); |
@@ -637,43 +630,21 @@ static bool __init early_alloc_p2m(unsigned long pfn, bool check_boundary) | |||
637 | 630 | ||
638 | p2m_top[topidx][mididx] = p2m; | 631 | p2m_top[topidx][mididx] = p2m; |
639 | 632 | ||
640 | /* For save/restore we need to MFN of the P2M saved */ | ||
641 | |||
642 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
643 | WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing), | ||
644 | "P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n", | ||
645 | topidx, mididx); | ||
646 | mid_mfn_p[mididx] = virt_to_mfn(p2m); | ||
647 | |||
648 | return true; | 633 | return true; |
649 | } | 634 | } |
650 | 635 | ||
651 | static bool __init early_alloc_p2m_middle(unsigned long pfn) | 636 | static bool __init early_alloc_p2m_middle(unsigned long pfn) |
652 | { | 637 | { |
653 | unsigned topidx = p2m_top_index(pfn); | 638 | unsigned topidx = p2m_top_index(pfn); |
654 | unsigned long *mid_mfn_p; | ||
655 | unsigned long **mid; | 639 | unsigned long **mid; |
656 | 640 | ||
657 | mid = p2m_top[topidx]; | 641 | mid = p2m_top[topidx]; |
658 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
659 | if (mid == p2m_mid_missing) { | 642 | if (mid == p2m_mid_missing) { |
660 | mid = extend_brk(PAGE_SIZE, PAGE_SIZE); | 643 | mid = extend_brk(PAGE_SIZE, PAGE_SIZE); |
661 | 644 | ||
662 | p2m_mid_init(mid, p2m_missing); | 645 | p2m_mid_init(mid, p2m_missing); |
663 | 646 | ||
664 | p2m_top[topidx] = mid; | 647 | p2m_top[topidx] = mid; |
665 | |||
666 | BUG_ON(mid_mfn_p != p2m_mid_missing_mfn); | ||
667 | } | ||
668 | /* And the save/restore P2M tables.. */ | ||
669 | if (mid_mfn_p == p2m_mid_missing_mfn) { | ||
670 | mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
671 | p2m_mid_mfn_init(mid_mfn_p, p2m_missing); | ||
672 | |||
673 | p2m_top_mfn_p[topidx] = mid_mfn_p; | ||
674 | p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p); | ||
675 | /* Note: we don't set mid_mfn_p[midix] here, | ||
676 | * look in early_alloc_p2m() */ | ||
677 | } | 648 | } |
678 | return true; | 649 | return true; |
679 | } | 650 | } |
@@ -684,14 +655,13 @@ static bool __init early_alloc_p2m_middle(unsigned long pfn) | |||
684 | * replace the P2M leaf with a p2m_missing or p2m_identity. | 655 | * replace the P2M leaf with a p2m_missing or p2m_identity. |
685 | * Stick the old page in the new P2M tree location. | 656 | * Stick the old page in the new P2M tree location. |
686 | */ | 657 | */ |
687 | bool __init early_can_reuse_p2m_middle(unsigned long set_pfn, unsigned long set_mfn) | 658 | static bool __init early_can_reuse_p2m_middle(unsigned long set_pfn) |
688 | { | 659 | { |
689 | unsigned topidx; | 660 | unsigned topidx; |
690 | unsigned mididx; | 661 | unsigned mididx; |
691 | unsigned ident_pfns; | 662 | unsigned ident_pfns; |
692 | unsigned inv_pfns; | 663 | unsigned inv_pfns; |
693 | unsigned long *p2m; | 664 | unsigned long *p2m; |
694 | unsigned long *mid_mfn_p; | ||
695 | unsigned idx; | 665 | unsigned idx; |
696 | unsigned long pfn; | 666 | unsigned long pfn; |
697 | 667 | ||
@@ -737,11 +707,6 @@ bool __init early_can_reuse_p2m_middle(unsigned long set_pfn, unsigned long set_ | |||
737 | found: | 707 | found: |
738 | /* Found one, replace old with p2m_identity or p2m_missing */ | 708 | /* Found one, replace old with p2m_identity or p2m_missing */ |
739 | p2m_top[topidx][mididx] = (ident_pfns ? p2m_identity : p2m_missing); | 709 | p2m_top[topidx][mididx] = (ident_pfns ? p2m_identity : p2m_missing); |
740 | /* And the other for save/restore.. */ | ||
741 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
742 | /* NOTE: Even if it is a p2m_identity it should still be point to | ||
743 | * a page filled with INVALID_P2M_ENTRY entries. */ | ||
744 | mid_mfn_p[mididx] = virt_to_mfn(p2m_missing); | ||
745 | 710 | ||
746 | /* Reset where we want to stick the old page in. */ | 711 | /* Reset where we want to stick the old page in. */ |
747 | topidx = p2m_top_index(set_pfn); | 712 | topidx = p2m_top_index(set_pfn); |
@@ -756,8 +721,6 @@ found: | |||
756 | 721 | ||
757 | p2m_init(p2m); | 722 | p2m_init(p2m); |
758 | p2m_top[topidx][mididx] = p2m; | 723 | p2m_top[topidx][mididx] = p2m; |
759 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
760 | mid_mfn_p[mididx] = virt_to_mfn(p2m); | ||
761 | 724 | ||
762 | return true; | 725 | return true; |
763 | } | 726 | } |
@@ -767,7 +730,7 @@ bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn) | |||
767 | if (!early_alloc_p2m_middle(pfn)) | 730 | if (!early_alloc_p2m_middle(pfn)) |
768 | return false; | 731 | return false; |
769 | 732 | ||
770 | if (early_can_reuse_p2m_middle(pfn, mfn)) | 733 | if (early_can_reuse_p2m_middle(pfn)) |
771 | return __set_phys_to_machine(pfn, mfn); | 734 | return __set_phys_to_machine(pfn, mfn); |
772 | 735 | ||
773 | if (!early_alloc_p2m(pfn, false /* boundary crossover OK!*/)) | 736 | if (!early_alloc_p2m(pfn, false /* boundary crossover OK!*/)) |