diff options
| -rw-r--r-- | arch/sparc64/kernel/head.S | 30 | ||||
| -rw-r--r-- | arch/sparc64/kernel/setup.c | 23 | ||||
| -rw-r--r-- | arch/sparc64/kernel/smp.c | 16 | ||||
| -rw-r--r-- | include/asm-generic/pgtable.h | 11 | ||||
| -rw-r--r-- | include/asm-mips/pgtable.h | 10 | ||||
| -rw-r--r-- | include/asm-sparc64/pgtable.h | 17 |
6 files changed, 71 insertions, 36 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 3eadac5e171e..31c5892f5acc 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
| 11 | #include <linux/version.h> | 11 | #include <linux/version.h> |
| 12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| 13 | #include <linux/threads.h> | ||
| 13 | #include <asm/thread_info.h> | 14 | #include <asm/thread_info.h> |
| 14 | #include <asm/asi.h> | 15 | #include <asm/asi.h> |
| 15 | #include <asm/pstate.h> | 16 | #include <asm/pstate.h> |
| @@ -493,6 +494,35 @@ tlb_fixup_done: | |||
| 493 | call prom_init | 494 | call prom_init |
| 494 | mov %l7, %o0 ! OpenPROM cif handler | 495 | mov %l7, %o0 ! OpenPROM cif handler |
| 495 | 496 | ||
| 497 | /* Initialize current_thread_info()->cpu as early as possible. | ||
| 498 | * In order to do that accurately we have to patch up the get_cpuid() | ||
| 499 | * assembler sequences. And that, in turn, requires that we know | ||
| 500 | * if we are on a Starfire box or not. While we're here, patch up | ||
| 501 | * the sun4v sequences as well. | ||
| 502 | */ | ||
| 503 | call check_if_starfire | ||
| 504 | nop | ||
| 505 | call per_cpu_patch | ||
| 506 | nop | ||
| 507 | call sun4v_patch | ||
| 508 | nop | ||
| 509 | |||
| 510 | #ifdef CONFIG_SMP | ||
| 511 | call hard_smp_processor_id | ||
| 512 | nop | ||
| 513 | cmp %o0, NR_CPUS | ||
| 514 | blu,pt %xcc, 1f | ||
| 515 | nop | ||
| 516 | call boot_cpu_id_too_large | ||
| 517 | nop | ||
| 518 | /* Not reached... */ | ||
| 519 | |||
| 520 | 1: | ||
| 521 | #else | ||
| 522 | mov 0, %o0 | ||
| 523 | #endif | ||
| 524 | stb %o0, [%g6 + TI_CPU] | ||
| 525 | |||
| 496 | /* Off we go.... */ | 526 | /* Off we go.... */ |
| 497 | call start_kernel | 527 | call start_kernel |
| 498 | nop | 528 | nop |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 005167f82419..9cf1c88cd774 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
| @@ -220,7 +220,7 @@ char reboot_command[COMMAND_LINE_SIZE]; | |||
| 220 | 220 | ||
| 221 | static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; | 221 | static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; |
| 222 | 222 | ||
| 223 | static void __init per_cpu_patch(void) | 223 | void __init per_cpu_patch(void) |
| 224 | { | 224 | { |
| 225 | struct cpuid_patch_entry *p; | 225 | struct cpuid_patch_entry *p; |
| 226 | unsigned long ver; | 226 | unsigned long ver; |
| @@ -280,7 +280,7 @@ static void __init per_cpu_patch(void) | |||
| 280 | } | 280 | } |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | static void __init sun4v_patch(void) | 283 | void __init sun4v_patch(void) |
| 284 | { | 284 | { |
| 285 | struct sun4v_1insn_patch_entry *p1; | 285 | struct sun4v_1insn_patch_entry *p1; |
| 286 | struct sun4v_2insn_patch_entry *p2; | 286 | struct sun4v_2insn_patch_entry *p2; |
| @@ -315,6 +315,15 @@ static void __init sun4v_patch(void) | |||
| 315 | } | 315 | } |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | #ifdef CONFIG_SMP | ||
| 319 | void __init boot_cpu_id_too_large(int cpu) | ||
| 320 | { | ||
| 321 | prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n", | ||
| 322 | cpu, NR_CPUS); | ||
| 323 | prom_halt(); | ||
| 324 | } | ||
| 325 | #endif | ||
| 326 | |||
| 318 | void __init setup_arch(char **cmdline_p) | 327 | void __init setup_arch(char **cmdline_p) |
| 319 | { | 328 | { |
| 320 | /* Initialize PROM console and command line. */ | 329 | /* Initialize PROM console and command line. */ |
| @@ -332,16 +341,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 332 | conswitchp = &prom_con; | 341 | conswitchp = &prom_con; |
| 333 | #endif | 342 | #endif |
| 334 | 343 | ||
| 335 | /* Work out if we are starfire early on */ | ||
| 336 | check_if_starfire(); | ||
| 337 | |||
| 338 | /* Now we know enough to patch the get_cpuid sequences | ||
| 339 | * used by trap code. | ||
| 340 | */ | ||
| 341 | per_cpu_patch(); | ||
| 342 | |||
| 343 | sun4v_patch(); | ||
| 344 | |||
| 345 | boot_flags_init(*cmdline_p); | 344 | boot_flags_init(*cmdline_p); |
| 346 | 345 | ||
| 347 | idprom_init(); | 346 | idprom_init(); |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 90eaca3ec9a6..4e8cd79156e0 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
| @@ -1264,7 +1264,6 @@ void __init smp_tick_init(void) | |||
| 1264 | boot_cpu_id = hard_smp_processor_id(); | 1264 | boot_cpu_id = hard_smp_processor_id(); |
| 1265 | current_tick_offset = timer_tick_offset; | 1265 | current_tick_offset = timer_tick_offset; |
| 1266 | 1266 | ||
| 1267 | cpu_set(boot_cpu_id, cpu_online_map); | ||
| 1268 | prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; | 1267 | prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; |
| 1269 | } | 1268 | } |
| 1270 | 1269 | ||
| @@ -1345,18 +1344,6 @@ void __init smp_setup_cpu_possible_map(void) | |||
| 1345 | 1344 | ||
| 1346 | void __devinit smp_prepare_boot_cpu(void) | 1345 | void __devinit smp_prepare_boot_cpu(void) |
| 1347 | { | 1346 | { |
| 1348 | int cpu = hard_smp_processor_id(); | ||
| 1349 | |||
| 1350 | if (cpu >= NR_CPUS) { | ||
| 1351 | prom_printf("Serious problem, boot cpu id >= NR_CPUS\n"); | ||
| 1352 | prom_halt(); | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | current_thread_info()->cpu = cpu; | ||
| 1356 | __local_per_cpu_offset = __per_cpu_offset(cpu); | ||
| 1357 | |||
| 1358 | cpu_set(smp_processor_id(), cpu_online_map); | ||
| 1359 | cpu_set(smp_processor_id(), phys_cpu_present_map); | ||
| 1360 | } | 1347 | } |
| 1361 | 1348 | ||
| 1362 | int __devinit __cpu_up(unsigned int cpu) | 1349 | int __devinit __cpu_up(unsigned int cpu) |
| @@ -1433,4 +1420,7 @@ void __init setup_per_cpu_areas(void) | |||
| 1433 | 1420 | ||
| 1434 | for (i = 0; i < NR_CPUS; i++, ptr += size) | 1421 | for (i = 0; i < NR_CPUS; i++, ptr += size) |
| 1435 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); | 1422 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); |
| 1423 | |||
| 1424 | /* Setup %g5 for the boot cpu. */ | ||
| 1425 | __local_per_cpu_offset = __per_cpu_offset(smp_processor_id()); | ||
| 1436 | } | 1426 | } |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 358e4d309ceb..c2059a3a0621 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
| @@ -159,17 +159,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres | |||
| 159 | #define lazy_mmu_prot_update(pte) do { } while (0) | 159 | #define lazy_mmu_prot_update(pte) do { } while (0) |
| 160 | #endif | 160 | #endif |
| 161 | 161 | ||
| 162 | #ifndef __HAVE_ARCH_MULTIPLE_ZERO_PAGE | 162 | #ifndef __HAVE_ARCH_MOVE_PTE |
| 163 | #define move_pte(pte, prot, old_addr, new_addr) (pte) | 163 | #define move_pte(pte, prot, old_addr, new_addr) (pte) |
| 164 | #else | ||
| 165 | #define move_pte(pte, prot, old_addr, new_addr) \ | ||
| 166 | ({ \ | ||
| 167 | pte_t newpte = (pte); \ | ||
| 168 | if (pte_present(pte) && pfn_valid(pte_pfn(pte)) && \ | ||
| 169 | pte_page(pte) == ZERO_PAGE(old_addr)) \ | ||
| 170 | newpte = mk_pte(ZERO_PAGE(new_addr), (prot)); \ | ||
| 171 | newpte; \ | ||
| 172 | }) | ||
| 173 | #endif | 164 | #endif |
| 174 | 165 | ||
| 175 | /* | 166 | /* |
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 174a3cda8c26..f80fe75c7800 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h | |||
| @@ -70,7 +70,15 @@ extern unsigned long zero_page_mask; | |||
| 70 | #define ZERO_PAGE(vaddr) \ | 70 | #define ZERO_PAGE(vaddr) \ |
| 71 | (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) | 71 | (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) |
| 72 | 72 | ||
| 73 | #define __HAVE_ARCH_MULTIPLE_ZERO_PAGE | 73 | #define __HAVE_ARCH_MOVE_PTE |
| 74 | #define move_pte(pte, prot, old_addr, new_addr) \ | ||
| 75 | ({ \ | ||
| 76 | pte_t newpte = (pte); \ | ||
| 77 | if (pte_present(pte) && pfn_valid(pte_pfn(pte)) && \ | ||
| 78 | pte_page(pte) == ZERO_PAGE(old_addr)) \ | ||
| 79 | newpte = mk_pte(ZERO_PAGE(new_addr), (prot)); \ | ||
| 80 | newpte; \ | ||
| 81 | }) | ||
| 74 | 82 | ||
| 75 | extern void paging_init(void); | 83 | extern void paging_init(void); |
| 76 | 84 | ||
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index c44e7466534e..cd464f469a2c 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h | |||
| @@ -689,6 +689,23 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p | |||
| 689 | #define pte_clear(mm,addr,ptep) \ | 689 | #define pte_clear(mm,addr,ptep) \ |
| 690 | set_pte_at((mm), (addr), (ptep), __pte(0UL)) | 690 | set_pte_at((mm), (addr), (ptep), __pte(0UL)) |
| 691 | 691 | ||
| 692 | #ifdef DCACHE_ALIASING_POSSIBLE | ||
| 693 | #define __HAVE_ARCH_MOVE_PTE | ||
| 694 | #define move_pte(pte, prot, old_addr, new_addr) \ | ||
| 695 | ({ \ | ||
| 696 | pte_t newpte = (pte); \ | ||
| 697 | if (tlb_type != hypervisor && pte_present(pte)) { \ | ||
| 698 | unsigned long this_pfn = pte_pfn(pte); \ | ||
| 699 | \ | ||
| 700 | if (pfn_valid(this_pfn) && \ | ||
| 701 | (((old_addr) ^ (new_addr)) & (1 << 13))) \ | ||
| 702 | flush_dcache_page_all(current->mm, \ | ||
| 703 | pfn_to_page(this_pfn)); \ | ||
| 704 | } \ | ||
| 705 | newpte; \ | ||
| 706 | }) | ||
| 707 | #endif | ||
| 708 | |||
| 692 | extern pgd_t swapper_pg_dir[2048]; | 709 | extern pgd_t swapper_pg_dir[2048]; |
| 693 | extern pmd_t swapper_low_pmd_dir[2048]; | 710 | extern pmd_t swapper_low_pmd_dir[2048]; |
| 694 | 711 | ||
