aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-06 14:09:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-06 14:09:44 -0400
commit576c25eb5954035b64112188d9a2683144600f3d (patch)
tree7cef36c33078f18dcfb5614674044c4c10df8a0c /arch/arm64
parent5872c84027fdcc982e8109ca26d11e1117995745 (diff)
parent4d5e0b1527dd330940e8b7180b8d7016fc900352 (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/Kconfig3
-rw-r--r--arch/arm64/include/asm/elf.h3
-rw-r--r--arch/arm64/include/asm/neon.h14
-rw-r--r--arch/arm64/include/asm/pgtable-2level-types.h2
-rw-r--r--arch/arm64/include/asm/pgtable-3level-types.h2
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h1
-rw-r--r--arch/arm64/kernel/entry.S3
-rw-r--r--arch/arm64/kernel/fpsimd.c28
-rw-r--r--arch/arm64/kernel/head.S8
-rw-r--r--arch/arm64/kernel/perf_event.c7
-rw-r--r--arch/arm64/kernel/setup.c3
-rw-r--r--arch/arm64/kernel/smp.c6
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S3
-rw-r--r--arch/arm64/mm/mmu.c23
-rw-r--r--arch/arm64/mm/proc.S6
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
96config IOMMU_HELPER 96config IOMMU_HELPER
97 def_bool SWIOTLB 97 def_bool SWIOTLB
98 98
99config KERNEL_MODE_NEON
100 def_bool y
101
99source "init/Kconfig" 102source "init/Kconfig"
100 103
101source "kernel/Kconfig.freezer" 104source "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;
33typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 33typedef elf_greg_t elf_gregset_t[ELF_NGREG];
34typedef struct user_fpsimd_state elf_fpregset_t; 34typedef 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
13void kernel_neon_begin(void);
14void 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
19typedef u64 pteval_t; 21typedef u64 pteval_t;
20typedef u64 pgdval_t; 22typedef u64 pgdval_t;
21typedef pgdval_t pmdval_t; 23typedef 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
19typedef u64 pteval_t; 21typedef u64 pteval_t;
20typedef u64 pmdval_t; 22typedef u64 pmdval_t;
21typedef u64 pgdval_t; 23typedef 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
480el0_dbg: 483el0_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(&current->thread.fpsimd_state); 84 fpsimd_load_state(&current->thread.fpsimd_state);
84} 85}
85 86
87#ifdef CONFIG_KERNEL_MODE_NEON
88
89/*
90 * Kernel-side NEON support functions
91 */
92void 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(&current->thread.fpsimd_state);
100}
101EXPORT_SYMBOL(kernel_neon_begin);
102
103void kernel_neon_end(void)
104{
105 if (current->mm)
106 fpsimd_load_state(&current->thread.fpsimd_state);
107
108 preempt_enable();
109}
110EXPORT_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
116ENTRY(stext) 124ENTRY(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
224void __init smp_cpus_done(unsigned int max_cpus) 224void __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
233void __init smp_prepare_boot_cpu(void) 229void __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)
296static void __init map_mem(void) 296static 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
96ENDPROC(cpu_do_switch_mm) 96ENDPROC(cpu_do_switch_mm)
97 97
98cpu_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