diff options
| -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 | 83 | ||||
| -rw-r--r-- | arch/x86/xen/setup.c | 1 | ||||
| -rw-r--r-- | arch/x86/xen/time.c | 2 | ||||
| -rw-r--r-- | drivers/xen/balloon.c | 3 | ||||
| -rw-r--r-- | drivers/xen/pci.c | 27 |
7 files changed, 50 insertions, 74 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 9f5983b01ed9..b456b048eca9 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 | ||
| @@ -538,12 +532,13 @@ static bool alloc_p2m(unsigned long pfn) | |||
| 538 | unsigned topidx, mididx; | 532 | unsigned topidx, mididx; |
| 539 | unsigned long ***top_p, **mid; | 533 | unsigned long ***top_p, **mid; |
| 540 | unsigned long *top_mfn_p, *mid_mfn; | 534 | unsigned long *top_mfn_p, *mid_mfn; |
| 535 | unsigned long *p2m_orig; | ||
| 541 | 536 | ||
| 542 | topidx = p2m_top_index(pfn); | 537 | topidx = p2m_top_index(pfn); |
| 543 | mididx = p2m_mid_index(pfn); | 538 | mididx = p2m_mid_index(pfn); |
| 544 | 539 | ||
| 545 | top_p = &p2m_top[topidx]; | 540 | top_p = &p2m_top[topidx]; |
| 546 | mid = *top_p; | 541 | mid = ACCESS_ONCE(*top_p); |
| 547 | 542 | ||
| 548 | if (mid == p2m_mid_missing) { | 543 | if (mid == p2m_mid_missing) { |
| 549 | /* Mid level is missing, allocate a new one */ | 544 | /* Mid level is missing, allocate a new one */ |
| @@ -558,7 +553,7 @@ static bool alloc_p2m(unsigned long pfn) | |||
| 558 | } | 553 | } |
| 559 | 554 | ||
| 560 | top_mfn_p = &p2m_top_mfn[topidx]; | 555 | top_mfn_p = &p2m_top_mfn[topidx]; |
| 561 | mid_mfn = p2m_top_mfn_p[topidx]; | 556 | mid_mfn = ACCESS_ONCE(p2m_top_mfn_p[topidx]); |
| 562 | 557 | ||
| 563 | BUG_ON(virt_to_mfn(mid_mfn) != *top_mfn_p); | 558 | BUG_ON(virt_to_mfn(mid_mfn) != *top_mfn_p); |
| 564 | 559 | ||
| @@ -566,6 +561,7 @@ static bool alloc_p2m(unsigned long pfn) | |||
| 566 | /* Separately check the mid mfn level */ | 561 | /* Separately check the mid mfn level */ |
| 567 | unsigned long missing_mfn; | 562 | unsigned long missing_mfn; |
| 568 | unsigned long mid_mfn_mfn; | 563 | unsigned long mid_mfn_mfn; |
| 564 | unsigned long old_mfn; | ||
| 569 | 565 | ||
| 570 | mid_mfn = alloc_p2m_page(); | 566 | mid_mfn = alloc_p2m_page(); |
