diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/bugs.c | 4 | ||||
-rw-r--r-- | arch/arm/kernel/head-common.S | 6 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 40 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 31 |
4 files changed, 61 insertions, 20 deletions
diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c index 7be511310191..d41d3598e5e5 100644 --- a/arch/arm/kernel/bugs.c +++ b/arch/arm/kernel/bugs.c | |||
@@ -6,8 +6,8 @@ | |||
6 | void check_other_bugs(void) | 6 | void check_other_bugs(void) |
7 | { | 7 | { |
8 | #ifdef MULTI_CPU | 8 | #ifdef MULTI_CPU |
9 | if (processor.check_bugs) | 9 | if (cpu_check_bugs) |
10 | processor.check_bugs(); | 10 | cpu_check_bugs(); |
11 | #endif | 11 | #endif |
12 | } | 12 | } |
13 | 13 | ||
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 6e0375e7db05..997b02302c31 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -145,6 +145,9 @@ __mmap_switched_data: | |||
145 | #endif | 145 | #endif |
146 | .size __mmap_switched_data, . - __mmap_switched_data | 146 | .size __mmap_switched_data, . - __mmap_switched_data |
147 | 147 | ||
148 | __FINIT | ||
149 | .text | ||
150 | |||
148 | /* | 151 | /* |
149 | * This provides a C-API version of __lookup_processor_type | 152 | * This provides a C-API version of __lookup_processor_type |
150 | */ | 153 | */ |
@@ -156,9 +159,6 @@ ENTRY(lookup_processor_type) | |||
156 | ldmfd sp!, {r4 - r6, r9, pc} | 159 | ldmfd sp!, {r4 - r6, r9, pc} |
157 | ENDPROC(lookup_processor_type) | 160 | ENDPROC(lookup_processor_type) |
158 | 161 | ||
159 | __FINIT | ||
160 | .text | ||
161 | |||
162 | /* | 162 | /* |
163 | * Read processor ID register (CP#15, CR0), and look up in the linker-built | 163 | * Read processor ID register (CP#15, CR0), and look up in the linker-built |
164 | * supported processor list. Note that we can't use the absolute addresses | 164 | * supported processor list. Note that we can't use the absolute addresses |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index ac7e08886863..375b13f7e780 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -114,6 +114,11 @@ EXPORT_SYMBOL(elf_hwcap2); | |||
114 | 114 | ||
115 | #ifdef MULTI_CPU | 115 | #ifdef MULTI_CPU |
116 | struct processor processor __ro_after_init; | 116 | struct processor processor __ro_after_init; |
117 | #if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) | ||
118 | struct processor *cpu_vtable[NR_CPUS] = { | ||
119 | [0] = &processor, | ||
120 | }; | ||
121 | #endif | ||
117 | #endif | 122 | #endif |
118 | #ifdef MULTI_TLB | 123 | #ifdef MULTI_TLB |
119 | struct cpu_tlb_fns cpu_tlb __ro_after_init; | 124 | struct cpu_tlb_fns cpu_tlb __ro_after_init; |
@@ -666,28 +671,33 @@ static void __init smp_build_mpidr_hash(void) | |||
666 | } | 671 | } |
667 | #endif | 672 | #endif |
668 | 673 | ||
669 | static void __init setup_processor(void) | 674 | /* |
675 | * locate processor in the list of supported processor types. The linker | ||
676 | * builds this table for us from the entries in arch/arm/mm/proc-*.S | ||
677 | */ | ||
678 | struct proc_info_list *lookup_processor(u32 midr) | ||
670 | { | 679 | { |
671 | struct proc_info_list *list; | 680 | struct proc_info_list *list = lookup_processor_type(midr); |
672 | 681 | ||
673 | /* | ||
674 | * locate processor in the list of supported processor | ||
675 | * types. The linker builds this table for us from the | ||
676 | * entries in arch/arm/mm/proc-*.S | ||
677 | */ | ||
678 | list = lookup_processor_type(read_cpuid_id()); | ||
679 | if (!list) { | 682 | if (!list) { |
680 | pr_err("CPU configuration botched (ID %08x), unable to continue.\n", | 683 | pr_err("CPU%u: configuration botched (ID %08x), CPU halted\n", |
681 | read_cpuid_id()); | 684 | smp_processor_id(), midr); |
682 | while (1); | 685 | while (1) |
686 | /* can't use cpu_relax() here as it may require MMU setup */; | ||
683 | } | 687 | } |
684 | 688 | ||
689 | return list; | ||
690 | } | ||
691 | |||
692 | static void __init setup_processor(void) | ||
693 | { | ||
694 | unsigned int midr = read_cpuid_id(); | ||
695 | struct proc_info_list *list = lookup_processor(midr); | ||
696 | |||
685 | cpu_name = list->cpu_name; | 697 | cpu_name = list->cpu_name; |
686 | __cpu_architecture = __get_cpu_architecture(); | 698 | __cpu_architecture = __get_cpu_architecture(); |
687 | 699 | ||
688 | #ifdef MULTI_CPU | 700 | init_proc_vtable(list->proc); |
689 | processor = *list->proc; | ||
690 | #endif | ||
691 | #ifdef MULTI_TLB | 701 | #ifdef MULTI_TLB |
692 | cpu_tlb = *list->tlb; | 702 | cpu_tlb = *list->tlb; |
693 | #endif | 703 | #endif |
@@ -699,7 +709,7 @@ static void __init setup_processor(void) | |||
699 | #endif | 709 | #endif |
700 | 710 | ||
701 | pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", | 711 | pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", |
702 | cpu_name, read_cpuid_id(), read_cpuid_id() & 15, | 712 | list->cpu_name, midr, midr & 15, |
703 | proc_arch[cpu_architecture()], get_cr()); | 713 | proc_arch[cpu_architecture()], get_cr()); |
704 | 714 | ||
705 | snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", | 715 | snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 0978282d5fc2..12a6172263c0 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/mmu_context.h> | 42 | #include <asm/mmu_context.h> |
43 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
44 | #include <asm/pgalloc.h> | 44 | #include <asm/pgalloc.h> |
45 | #include <asm/procinfo.h> | ||
45 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
46 | #include <asm/sections.h> | 47 | #include <asm/sections.h> |
47 | #include <asm/tlbflush.h> | 48 | #include <asm/tlbflush.h> |
@@ -102,6 +103,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd) | |||
102 | #endif | 103 | #endif |
103 | } | 104 | } |
104 | 105 | ||
106 | #if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) | ||
107 | static int secondary_biglittle_prepare(unsigned int cpu) | ||
108 | { | ||
109 | if (!cpu_vtable[cpu]) | ||
110 | cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL); | ||
111 | |||
112 | return cpu_vtable[cpu] ? 0 : -ENOMEM; | ||
113 | } | ||
114 | |||
115 | static void secondary_biglittle_init(void) | ||
116 | { | ||
117 | init_proc_vtable(lookup_processor(read_cpuid_id())->proc); | ||
118 | } | ||
119 | #else | ||
120 | static int secondary_biglittle_prepare(unsigned int cpu) | ||
121 | { | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static void secondary_biglittle_init(void) | ||
126 | { | ||
127 | } | ||
128 | #endif | ||
129 | |||
105 | int __cpu_up(unsigned int cpu, struct task_struct *idle) | 130 | int __cpu_up(unsigned int cpu, struct task_struct *idle) |
106 | { | 131 | { |
107 | int ret; | 132 | int ret; |
@@ -109,6 +134,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) | |||
109 | if (!smp_ops.smp_boot_secondary) | 134 | if (!smp_ops.smp_boot_secondary) |
110 | return -ENOSYS; | 135 | return -ENOSYS; |
111 | 136 | ||
137 | ret = secondary_biglittle_prepare(cpu); | ||
138 | if (ret) | ||
139 | return ret; | ||
140 | |||
112 | /* | 141 | /* |
113 | * We need to tell the secondary core where to find | 142 | * We need to tell the secondary core where to find |
114 | * its stack and the page tables. | 143 | * its stack and the page tables. |
@@ -359,6 +388,8 @@ asmlinkage void secondary_start_kernel(void) | |||
359 | struct mm_struct *mm = &init_mm; | 388 | struct mm_struct *mm = &init_mm; |
360 | unsigned int cpu; | 389 | unsigned int cpu; |
361 | 390 | ||
391 | secondary_biglittle_init(); | ||
392 | |||
362 | /* | 393 | /* |
363 | * The identity mapping is uncached (strongly ordered), so | 394 | * The identity mapping is uncached (strongly ordered), so |
364 | * switch away from it before attempting any exclusive accesses. | 395 | * switch away from it before attempting any exclusive accesses. |