diff options
Diffstat (limited to 'arch/x86_64/mm/init.c')
-rw-r--r-- | arch/x86_64/mm/init.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 2b1d6c382396..be483a1d7b54 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -312,12 +312,19 @@ void __init init_memory_mapping(unsigned long start, unsigned long end) | |||
312 | 312 | ||
313 | extern struct x8664_pda cpu_pda[NR_CPUS]; | 313 | extern struct x8664_pda cpu_pda[NR_CPUS]; |
314 | 314 | ||
315 | /* Assumes all CPUs still execute in init_mm */ | 315 | void __cpuinit zap_low_mappings(int cpu) |
316 | void zap_low_mappings(void) | ||
317 | { | 316 | { |
318 | pgd_t *pgd = pgd_offset_k(0UL); | 317 | if (cpu == 0) { |
319 | pgd_clear(pgd); | 318 | pgd_t *pgd = pgd_offset_k(0UL); |
320 | flush_tlb_all(); | 319 | pgd_clear(pgd); |
320 | } else { | ||
321 | /* | ||
322 | * For AP's, zap the low identity mappings by changing the cr3 | ||
323 | * to init_level4_pgt and doing local flush tlb all | ||
324 | */ | ||
325 | asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); | ||
326 | } | ||
327 | __flush_tlb_all(); | ||
321 | } | 328 | } |
322 | 329 | ||
323 | /* Compute zone sizes for the DMA and DMA32 zones in a node. */ | 330 | /* Compute zone sizes for the DMA and DMA32 zones in a node. */ |
@@ -474,14 +481,13 @@ void __init mem_init(void) | |||
474 | datasize >> 10, | 481 | datasize >> 10, |
475 | initsize >> 10); | 482 | initsize >> 10); |
476 | 483 | ||
484 | #ifdef CONFIG_SMP | ||
477 | /* | 485 | /* |
478 | * Subtle. SMP is doing its boot stuff late (because it has to | 486 | * Sync boot_level4_pgt mappings with the init_level4_pgt |
479 | * fork idle threads) - but it also needs low mappings for the | 487 | * except for the low identity mappings which are already zapped |
480 | * protected-mode entry to work. We zap these entries only after | 488 | * in init_level4_pgt. This sync-up is essential for AP's bringup |
481 | * the WP-bit has been tested. | ||
482 | */ | 489 | */ |
483 | #ifndef CONFIG_SMP | 490 | memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t)); |
484 | zap_low_mappings(); | ||
485 | #endif | 491 | #endif |
486 | } | 492 | } |
487 | 493 | ||