diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 14:09:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 14:09:44 -0400 |
commit | 576c25eb5954035b64112188d9a2683144600f3d (patch) | |
tree | 7cef36c33078f18dcfb5614674044c4c10df8a0c /arch/arm64 | |
parent | 5872c84027fdcc982e8109ca26d11e1117995745 (diff) | |
parent | 4d5e0b1527dd330940e8b7180b8d7016fc900352 (diff) |
Merge tag 'arm64-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64
Pull ARM64 update from Catalin Marinas:
- User tagged pointers support (top 8-bit of user pointers
automatically ignored by the CPU).
- Kernel mode NEON (no users for arm64 yet but work in progress).
- arm64 kernel Image header extended to accommodate future EFI stub.
- Remove BogoMIPS reporting (not relevant, it's just the timer
frequency).
- Clean-up (EM_AARCH64/EM_ARM to elf-em.h, ELF notes in read-only
segment, unused variable).
- Bug-fixes (RAM boundaries not 2MB aligned, perf, includes).
* tag 'arm64-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64:
Documentation/arm64: clarify requirements for DTB placement
arm64: mm: permit use of tagged pointers at EL0
Move the EM_ARM and EM_AARCH64 definitions to uapi/linux/elf-em.h
arm64: Remove unused cpu_name ascii in arch/arm64/mm/proc.S
arm64: delay: don't bother reporting bogomips in /proc/cpuinfo
arm64: Fix mapping of memory banks not ending on a PMD_SIZE boundary
arm64: move elf notes into readonly segment
arm64: Enable interrupts in the EL0 undef handler
arm64: Expand arm64 image header
ARM64: include: asm: include "asm/types.h" in "pgtable-2level-types.h" and "pgtable-3level-types.h"
arm64: add support for kernel mode NEON
arm64: perf: fix ARMv8 EVTYPE_MASK to include NSH bit
arm64: perf: fix group validation when using enable_on_exec
Diffstat (limited to 'arch/arm64')
-rw-r--r-- | arch/arm64/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/elf.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/neon.h | 14 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable-2level-types.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable-3level-types.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable-hwdef.h | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/fpsimd.c | 28 | ||||
-rw-r--r-- | arch/arm64/kernel/head.S | 8 | ||||
-rw-r--r-- | arch/arm64/kernel/perf_event.c | 7 | ||||
-rw-r--r-- | arch/arm64/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/arm64/kernel/vmlinux.lds.S | 3 | ||||
-rw-r--r-- | arch/arm64/mm/mmu.c | 23 | ||||
-rw-r--r-- | arch/arm64/mm/proc.S | 6 |
15 files changed, 90 insertions, 22 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9737e97f9f38..ae323a45c28c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -96,6 +96,9 @@ config SWIOTLB | |||
96 | config IOMMU_HELPER | 96 | config IOMMU_HELPER |
97 | def_bool SWIOTLB | 97 | def_bool SWIOTLB |
98 | 98 | ||
99 | config KERNEL_MODE_NEON | ||
100 | def_bool y | ||
101 | |||
99 | source "init/Kconfig" | 102 | source "init/Kconfig" |
100 | 103 | ||
101 | source "kernel/Kconfig.freezer" | 104 | source "kernel/Kconfig.freezer" |
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index fe32c0e4ac01..e7fa87f9201b 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h | |||
@@ -33,8 +33,6 @@ typedef unsigned long elf_greg_t; | |||
33 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | 33 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
34 | typedef struct user_fpsimd_state elf_fpregset_t; | 34 | typedef struct user_fpsimd_state elf_fpregset_t; |
35 | 35 | ||
36 | #define EM_AARCH64 183 | ||
37 | |||
38 | /* | 36 | /* |
39 | * AArch64 static relocation types. | 37 | * AArch64 static relocation types. |
40 | */ | 38 | */ |
@@ -151,7 +149,6 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm); | |||
151 | #define arch_randomize_brk arch_randomize_brk | 149 | #define arch_randomize_brk arch_randomize_brk |
152 | 150 | ||
153 | #ifdef CONFIG_COMPAT | 151 | #ifdef CONFIG_COMPAT |
154 | #define EM_ARM 40 | ||
155 | #define COMPAT_ELF_PLATFORM ("v8l") | 152 | #define COMPAT_ELF_PLATFORM ("v8l") |
156 | 153 | ||
157 | #define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3)) | 154 | #define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3)) |
diff --git a/arch/arm64/include/asm/neon.h b/arch/arm64/include/asm/neon.h new file mode 100644 index 000000000000..b0cc58a97780 --- /dev/null +++ b/arch/arm64/include/asm/neon.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * linux/arch/arm64/include/asm/neon.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #define cpu_has_neon() (1) | ||
12 | |||
13 | void kernel_neon_begin(void); | ||
14 | void kernel_neon_end(void); | ||
diff --git a/arch/arm64/include/asm/pgtable-2level-types.h b/arch/arm64/include/asm/pgtable-2level-types.h index 3c3ca7d361e4..5f101e63dfc1 100644 --- a/arch/arm64/include/asm/pgtable-2level-types.h +++ b/arch/arm64/include/asm/pgtable-2level-types.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #ifndef __ASM_PGTABLE_2LEVEL_TYPES_H | 16 | #ifndef __ASM_PGTABLE_2LEVEL_TYPES_H |
17 | #define __ASM_PGTABLE_2LEVEL_TYPES_H | 17 | #define __ASM_PGTABLE_2LEVEL_TYPES_H |
18 | 18 | ||
19 | #include <asm/types.h> | ||
20 | |||
19 | typedef u64 pteval_t; | 21 | typedef u64 pteval_t; |
20 | typedef u64 pgdval_t; | 22 | typedef u64 pgdval_t; |
21 | typedef pgdval_t pmdval_t; | 23 | typedef pgdval_t pmdval_t; |
diff --git a/arch/arm64/include/asm/pgtable-3level-types.h b/arch/arm64/include/asm/pgtable-3level-types.h index 4489615f14a9..4e94424938a4 100644 --- a/arch/arm64/include/asm/pgtable-3level-types.h +++ b/arch/arm64/include/asm/pgtable-3level-types.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #ifndef __ASM_PGTABLE_3LEVEL_TYPES_H | 16 | #ifndef __ASM_PGTABLE_3LEVEL_TYPES_H |
17 | #define __ASM_PGTABLE_3LEVEL_TYPES_H | 17 | #define __ASM_PGTABLE_3LEVEL_TYPES_H |
18 | 18 | ||
19 | #include <asm/types.h> | ||
20 | |||
19 | typedef u64 pteval_t; | 21 | typedef u64 pteval_t; |
20 | typedef u64 pmdval_t; | 22 | typedef u64 pmdval_t; |
21 | typedef u64 pgdval_t; | 23 | typedef u64 pgdval_t; |
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index e182a356c979..d57e66845c86 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h | |||
@@ -122,5 +122,6 @@ | |||
122 | #define TCR_TG1_64K (UL(1) << 30) | 122 | #define TCR_TG1_64K (UL(1) << 30) |
123 | #define TCR_IPS_40BIT (UL(2) << 32) | 123 | #define TCR_IPS_40BIT (UL(2) << 32) |
124 | #define TCR_ASID16 (UL(1) << 36) | 124 | #define TCR_ASID16 (UL(1) << 36) |
125 | #define TCR_TBI0 (UL(1) << 37) | ||
125 | 126 | ||
126 | #endif | 127 | #endif |
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 6ad781b21c08..3881fd115ebb 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
@@ -423,6 +423,7 @@ el0_da: | |||
423 | * Data abort handling | 423 | * Data abort handling |
424 | */ | 424 | */ |
425 | mrs x0, far_el1 | 425 | mrs x0, far_el1 |
426 | bic x0, x0, #(0xff << 56) | ||
426 | disable_step x1 | 427 | disable_step x1 |
427 | isb | 428 | isb |
428 | enable_dbg | 429 | enable_dbg |
@@ -476,6 +477,8 @@ el0_undef: | |||
476 | * Undefined instruction | 477 | * Undefined instruction |
477 | */ | 478 | */ |
478 | mov x0, sp | 479 | mov x0, sp |
480 | // enable interrupts before calling the main handler | ||
481 | enable_irq | ||
479 | b do_undefinstr | 482 | b do_undefinstr |
480 | el0_dbg: | 483 | el0_dbg: |
481 | /* | 484 | /* |
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index e8b8357aedb4..1f2e4d5a5c0f 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/signal.h> | 23 | #include <linux/signal.h> |
24 | #include <linux/hardirq.h> | ||
24 | 25 | ||
25 | #include <asm/fpsimd.h> | 26 | #include <asm/fpsimd.h> |
26 | #include <asm/cputype.h> | 27 | #include <asm/cputype.h> |
@@ -83,6 +84,33 @@ void fpsimd_flush_thread(void) | |||
83 | fpsimd_load_state(¤t->thread.fpsimd_state); | 84 | fpsimd_load_state(¤t->thread.fpsimd_state); |
84 | } | 85 | } |
85 | 86 | ||
87 | #ifdef CONFIG_KERNEL_MODE_NEON | ||
88 | |||
89 | /* | ||
90 | * Kernel-side NEON support functions | ||
91 | */ | ||
92 | void kernel_neon_begin(void) | ||
93 | { | ||
94 | /* Avoid using the NEON in interrupt context */ | ||
95 | BUG_ON(in_interrupt()); | ||
96 | preempt_disable(); | ||
97 | |||
98 | if (current->mm) | ||
99 | fpsimd_save_state(¤t->thread.fpsimd_state); | ||
100 | } | ||
101 | EXPORT_SYMBOL(kernel_neon_begin); | ||
102 | |||
103 | void kernel_neon_end(void) | ||
104 | { | ||
105 | if (current->mm) | ||
106 | fpsimd_load_state(¤t->thread.fpsimd_state); | ||
107 | |||
108 | preempt_enable(); | ||
109 | } | ||
110 | EXPORT_SYMBOL(kernel_neon_end); | ||
111 | |||
112 | #endif /* CONFIG_KERNEL_MODE_NEON */ | ||
113 | |||
86 | /* | 114 | /* |
87 | * FP/SIMD support code initialisation. | 115 | * FP/SIMD support code initialisation. |
88 | */ | 116 | */ |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 53dcae49e729..7090c126797c 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -112,6 +112,14 @@ | |||
112 | .quad TEXT_OFFSET // Image load offset from start of RAM | 112 | .quad TEXT_OFFSET // Image load offset from start of RAM |
113 | .quad 0 // reserved | 113 | .quad 0 // reserved |
114 | .quad 0 // reserved | 114 | .quad 0 // reserved |
115 | .quad 0 // reserved | ||
116 | .quad 0 // reserved | ||
117 | .quad 0 // reserved | ||
118 | .byte 0x41 // Magic number, "ARM\x64" | ||
119 | .byte 0x52 | ||
120 | .byte 0x4d | ||
121 | .byte 0x64 | ||
122 | .word 0 // reserved | ||
115 | 123 | ||
116 | ENTRY(stext) | 124 | ENTRY(stext) |
117 | mov x21, x0 // x21=FDT | 125 | mov x21, x0 // x21=FDT |
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 12e6ccb88691..cea1594ff933 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c | |||
@@ -325,7 +325,10 @@ validate_event(struct pmu_hw_events *hw_events, | |||
325 | if (is_software_event(event)) | 325 | if (is_software_event(event)) |
326 | return 1; | 326 | return 1; |
327 | 327 | ||
328 | if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) | 328 | if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) |
329 | return 1; | ||
330 | |||
331 | if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) | ||
329 | return 1; | 332 | return 1; |
330 | 333 | ||
331 | return armpmu->get_event_idx(hw_events, &fake_event) >= 0; | 334 | return armpmu->get_event_idx(hw_events, &fake_event) >= 0; |
@@ -781,7 +784,7 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
781 | /* | 784 | /* |
782 | * PMXEVTYPER: Event selection reg | 785 | * PMXEVTYPER: Event selection reg |
783 | */ | 786 | */ |
784 | #define ARMV8_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */ | 787 | #define ARMV8_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */ |
785 | #define ARMV8_EVTYPE_EVENT 0xff /* Mask for EVENT bits */ | 788 | #define ARMV8_EVTYPE_EVENT 0xff /* Mask for EVENT bits */ |
786 | 789 | ||
787 | /* | 790 | /* |
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index add6ea616843..bca4c1c2052a 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c | |||
@@ -328,9 +328,6 @@ static int c_show(struct seq_file *m, void *v) | |||
328 | #ifdef CONFIG_SMP | 328 | #ifdef CONFIG_SMP |
329 | seq_printf(m, "processor\t: %d\n", i); | 329 | seq_printf(m, "processor\t: %d\n", i); |
330 | #endif | 330 | #endif |
331 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", | ||
332 | loops_per_jiffy / (500000UL/HZ), | ||
333 | loops_per_jiffy / (5000UL/HZ) % 100); | ||
334 | } | 331 | } |
335 | 332 | ||
336 | /* dump out the processor features */ | 333 | /* dump out the processor features */ |
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index fee5cce83450..78db90dcc910 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
@@ -223,11 +223,7 @@ asmlinkage void secondary_start_kernel(void) | |||
223 | 223 | ||
224 | void __init smp_cpus_done(unsigned int max_cpus) | 224 | void __init smp_cpus_done(unsigned int max_cpus) |
225 | { | 225 | { |
226 | unsigned long bogosum = loops_per_jiffy * num_online_cpus(); | 226 | pr_info("SMP: Total of %d processors activated.\n", num_online_cpus()); |
227 | |||
228 | pr_info("SMP: Total of %d processors activated (%lu.%02lu BogoMIPS).\n", | ||
229 | num_online_cpus(), bogosum / (500000/HZ), | ||
230 | (bogosum / (5000/HZ)) % 100); | ||
231 | } | 227 | } |
232 | 228 | ||
233 | void __init smp_prepare_boot_cpu(void) | 229 | void __init smp_prepare_boot_cpu(void) |
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index f5e55747242f..f8ab9d8e2ea3 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S | |||
@@ -71,6 +71,7 @@ SECTIONS | |||
71 | 71 | ||
72 | RO_DATA(PAGE_SIZE) | 72 | RO_DATA(PAGE_SIZE) |
73 | EXCEPTION_TABLE(8) | 73 | EXCEPTION_TABLE(8) |
74 | NOTES | ||
74 | _etext = .; /* End of text and rodata section */ | 75 | _etext = .; /* End of text and rodata section */ |
75 | 76 | ||
76 | . = ALIGN(PAGE_SIZE); | 77 | . = ALIGN(PAGE_SIZE); |
@@ -122,8 +123,6 @@ SECTIONS | |||
122 | } | 123 | } |
123 | _edata_loc = __data_loc + SIZEOF(.data); | 124 | _edata_loc = __data_loc + SIZEOF(.data); |
124 | 125 | ||
125 | NOTES | ||
126 | |||
127 | BSS_SECTION(0, 0, 0) | 126 | BSS_SECTION(0, 0, 0) |
128 | _end = .; | 127 | _end = .; |
129 | 128 | ||
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index a8d1059b91b2..f557ebbe7013 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -296,6 +296,7 @@ void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt) | |||
296 | static void __init map_mem(void) | 296 | static void __init map_mem(void) |
297 | { | 297 | { |
298 | struct memblock_region *reg; | 298 | struct memblock_region *reg; |
299 | phys_addr_t limit; | ||
299 | 300 | ||
300 | /* | 301 | /* |
301 | * Temporarily limit the memblock range. We need to do this as | 302 | * Temporarily limit the memblock range. We need to do this as |
@@ -303,9 +304,11 @@ static void __init map_mem(void) | |||
303 | * memory addressable from the initial direct kernel mapping. | 304 | * memory addressable from the initial direct kernel mapping. |
304 | * | 305 | * |
305 | * The initial direct kernel mapping, located at swapper_pg_dir, | 306 | * The initial direct kernel mapping, located at swapper_pg_dir, |
306 | * gives us PGDIR_SIZE memory starting from PHYS_OFFSET (aligned). | 307 | * gives us PGDIR_SIZE memory starting from PHYS_OFFSET (which must be |
308 | * aligned to 2MB as per Documentation/arm64/booting.txt). | ||
307 | */ | 309 | */ |
308 | memblock_set_current_limit((PHYS_OFFSET & PGDIR_MASK) + PGDIR_SIZE); | 310 | limit = PHYS_OFFSET + PGDIR_SIZE; |
311 | memblock_set_current_limit(limit); | ||
309 | 312 | ||
310 | /* map all the memory banks */ | 313 | /* map all the memory banks */ |
311 | for_each_memblock(memory, reg) { | 314 | for_each_memblock(memory, reg) { |
@@ -315,6 +318,22 @@ static void __init map_mem(void) | |||
315 | if (start >= end) | 318 | if (start >= end) |
316 | break; | 319 | break; |
317 | 320 | ||
321 | #ifndef CONFIG_ARM64_64K_PAGES | ||
322 | /* | ||
323 | * For the first memory bank align the start address and | ||
324 | * current memblock limit to prevent create_mapping() from | ||
325 | * allocating pte page tables from unmapped memory. | ||
326 | * When 64K pages are enabled, the pte page table for the | ||
327 | * first PGDIR_SIZE is already present in swapper_pg_dir. | ||
328 | */ | ||
329 | if (start < limit) | ||
330 | start = ALIGN(start, PMD_SIZE); | ||
331 | if (end < limit) { | ||
332 | limit = end & PMD_MASK; | ||
333 | memblock_set_current_limit(limit); | ||
334 | } | ||
335 | #endif | ||
336 | |||
318 | create_mapping(start, __phys_to_virt(start), end - start); | 337 | create_mapping(start, __phys_to_virt(start), end - start); |
319 | } | 338 | } |
320 | 339 | ||
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index a82ae8868077..b1b31bbc967b 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S | |||
@@ -95,10 +95,6 @@ ENTRY(cpu_do_switch_mm) | |||
95 | ret | 95 | ret |
96 | ENDPROC(cpu_do_switch_mm) | 96 | ENDPROC(cpu_do_switch_mm) |
97 | 97 | ||
98 | cpu_name: | ||
99 | .ascii "AArch64 Processor" | ||
100 | .align | ||
101 | |||
102 | .section ".text.init", #alloc, #execinstr | 98 | .section ".text.init", #alloc, #execinstr |
103 | 99 | ||
104 | /* | 100 | /* |
@@ -151,7 +147,7 @@ ENTRY(__cpu_setup) | |||
151 | * both user and kernel. | 147 | * both user and kernel. |
152 | */ | 148 | */ |
153 | ldr x10, =TCR_TxSZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT | \ | 149 | ldr x10, =TCR_TxSZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT | \ |
154 | TCR_ASID16 | (1 << 31) | 150 | TCR_ASID16 | TCR_TBI0 | (1 << 31) |
155 | #ifdef CONFIG_ARM64_64K_PAGES | 151 | #ifdef CONFIG_ARM64_64K_PAGES |
156 | orr x10, x10, TCR_TG0_64K | 152 | orr x10, x10, TCR_TG0_64K |
157 | orr x10, x10, TCR_TG1_64K | 153 | orr x10, x10, TCR_TG1_64K |