aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-27 14:09:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-27 14:09:59 -0500
commit5d8686276a5acc0a3d8055028a6e9d990c9c4fbd (patch)
tree633652441a0e598950137357c35f9dcf6bfb6b00
parent5a44ed0d30dd0681df44eb085c31b371b7fe84fe (diff)
parent66362c9afc1d4a806280b9e3646d2d0a26cf83e9 (diff)
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas: - Build fix when !CONFIG_UID16 (the patch is touching generic files but it only affects arm64 builds; submitted by Arnd Bergmann) - EFI fixes to deal with early_memremap() returning NULL and correctly mapping run-time regions - Fix CPUID register extraction of unsigned fields (not to be sign-extended) - ASID allocator fix to deal with long-running tasks over multiple generation roll-overs - Revert support for marking page ranges as contiguous PTEs (it leads to TLB conflicts and requires additional non-trivial kernel changes) - Proper early_alloc() failure check - Disable KASan for 48-bit VA and 16KB page configuration (the pgd is larger than the KASan shadow memory) - Update the fault_info table (original descriptions based on early engineering spec) * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: efi: fix initcall return values arm64: efi: deal with NULL return value of early_memremap() arm64: debug: Treat the BRPs/WRPs as unsigned arm64: cpufeature: Track unsigned fields arm64: cpufeature: Add helpers for extracting unsigned values Revert "arm64: Mark kernel page ranges contiguous" arm64: mm: keep reserved ASIDs in sync with mm after multiple rollovers arm64: KASAN depends on !(ARM64_16K_PAGES && ARM64_VA_BITS_48) arm64: efi: correctly map runtime regions arm64: mm: fix fault_info table xFSC decoding arm64: fix building without CONFIG_UID16 arm64: early_alloc: Fix check for allocation failure
-rw-r--r--arch/arm64/Kconfig2
-rw-r--r--arch/arm64/include/asm/cpufeature.h22
-rw-r--r--arch/arm64/include/asm/hw_breakpoint.h6
-rw-r--r--arch/arm64/kernel/cpufeature.c37
-rw-r--r--arch/arm64/kernel/efi.c33
-rw-r--r--arch/arm64/mm/context.c38
-rw-r--r--arch/arm64/mm/fault.c28
-rw-r--r--arch/arm64/mm/mmu.c77
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/types.h2
10 files changed, 124 insertions, 123 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e55848c1edf4..871f21783866 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -49,7 +49,7 @@ config ARM64
49 select HAVE_ARCH_AUDITSYSCALL 49 select HAVE_ARCH_AUDITSYSCALL
50 select HAVE_ARCH_BITREVERSE 50 select HAVE_ARCH_BITREVERSE
51 select HAVE_ARCH_JUMP_LABEL 51 select HAVE_ARCH_JUMP_LABEL
52 select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP 52 select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
53 select HAVE_ARCH_KGDB 53 select HAVE_ARCH_KGDB
54 select HAVE_ARCH_SECCOMP_FILTER 54 select HAVE_ARCH_SECCOMP_FILTER
55 select HAVE_ARCH_TRACEHOOK 55 select HAVE_ARCH_TRACEHOOK
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 52722ee73dba..8f271b83f910 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -47,8 +47,12 @@ enum ftr_type {
47#define FTR_STRICT true /* SANITY check strict matching required */ 47#define FTR_STRICT true /* SANITY check strict matching required */
48#define FTR_NONSTRICT false /* SANITY check ignored */ 48#define FTR_NONSTRICT false /* SANITY check ignored */
49 49
50#define FTR_SIGNED true /* Value should be treated as signed */
51#define FTR_UNSIGNED false /* Value should be treated as unsigned */
52
50struct arm64_ftr_bits { 53struct arm64_ftr_bits {
51 bool strict; /* CPU Sanity check: strict matching required ? */ 54 bool sign; /* Value is signed ? */
55 bool strict; /* CPU Sanity check: strict matching required ? */
52 enum ftr_type type; 56 enum ftr_type type;
53 u8 shift; 57 u8 shift;
54 u8 width; 58 u8 width;
@@ -124,6 +128,18 @@ cpuid_feature_extract_field(u64 features, int field)
124 return cpuid_feature_extract_field_width(features, field, 4); 128 return cpuid_feature_extract_field_width(features, field, 4);
125} 129}
126 130
131static inline unsigned int __attribute_const__
132cpuid_feature_extract_unsigned_field_width(u64 features, int field, int width)
133{
134 return (u64)(features << (64 - width - field)) >> (64 - width);
135}
136
137static inline unsigned int __attribute_const__
138cpuid_feature_extract_unsigned_field(u64 features, int field)
139{
140 return cpuid_feature_extract_unsigned_field_width(features, field, 4);
141}
142
127static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp) 143static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp)
128{ 144{
129 return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift); 145 return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
@@ -131,7 +147,9 @@ static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp)
131 147
132static inline s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val) 148static inline s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val)
133{ 149{
134 return cpuid_feature_extract_field_width(val, ftrp->shift, ftrp->width); 150 return ftrp->sign ?
151 cpuid_feature_extract_field_width(val, ftrp->shift, ftrp->width) :
152 cpuid_feature_extract_unsigned_field_width(val, ftrp->shift, ftrp->width);
135} 153}
136 154
137static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0) 155static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index e54415ec6935..9732908bfc8a 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -138,16 +138,18 @@ extern struct pmu perf_ops_bp;
138/* Determine number of BRP registers available. */ 138/* Determine number of BRP registers available. */
139static inline int get_num_brps(void) 139static inline int get_num_brps(void)
140{ 140{
141 u64 dfr0 = read_system_reg(SYS_ID_AA64DFR0_EL1);
141 return 1 + 142 return 1 +
142 cpuid_feature_extract_field(read_system_reg(SYS_ID_AA64DFR0_EL1), 143 cpuid_feature_extract_unsigned_field(dfr0,
143 ID_AA64DFR0_BRPS_SHIFT); 144 ID_AA64DFR0_BRPS_SHIFT);
144} 145}
145 146
146/* Determine number of WRP registers available. */ 147/* Determine number of WRP registers available. */
147static inline int get_num_wrps(void) 148static inline int get_num_wrps(void)
148{ 149{
150 u64 dfr0 = read_system_reg(SYS_ID_AA64DFR0_EL1);
149 return 1 + 151 return 1 +
150 cpuid_feature_extract_field(read_system_reg(SYS_ID_AA64DFR0_EL1), 152 cpuid_feature_extract_unsigned_field(dfr0,
151 ID_AA64DFR0_WRPS_SHIFT); 153 ID_AA64DFR0_WRPS_SHIFT);
152} 154}
153 155
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index c8cf89223b5a..0669c63281ea 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -44,8 +44,9 @@ unsigned int compat_elf_hwcap2 __read_mostly;
44 44
45DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); 45DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
46 46
47#define ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \ 47#define __ARM64_FTR_BITS(SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
48 { \ 48 { \
49 .sign = SIGNED, \
49 .strict = STRICT, \ 50 .strict = STRICT, \
50 .type = TYPE, \ 51 .type = TYPE, \
51 .shift = SHIFT, \ 52 .shift = SHIFT, \
@@ -53,6 +54,14 @@ DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
53 .safe_val = SAFE_VAL, \ 54 .safe_val = SAFE_VAL, \
54 } 55 }
55 56
57/* Define a feature with signed values */
58#define ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
59 __ARM64_FTR_BITS(FTR_SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL)
60
61/* Define a feature with unsigned value */
62#define U_ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
63 __ARM64_FTR_BITS(FTR_UNSIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL)
64
56#define ARM64_FTR_END \ 65#define ARM64_FTR_END \
57 { \ 66 { \
58 .width = 0, \ 67 .width = 0, \
@@ -99,7 +108,7 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
99 * Differing PARange is fine as long as all peripherals and memory are mapped 108 * Differing PARange is fine as long as all peripherals and memory are mapped
100 * within the minimum PARange of all CPUs 109 * within the minimum PARange of all CPUs
101 */ 110 */
102 ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0), 111 U_ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0),
103 ARM64_FTR_END, 112 ARM64_FTR_END,
104}; 113};
105 114
@@ -115,18 +124,18 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
115}; 124};
116 125
117static struct arm64_ftr_bits ftr_ctr[] = { 126static struct arm64_ftr_bits ftr_ctr[] = {
118 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */ 127 U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */
119 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0), 128 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
120 ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */ 129 U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */
121 ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */ 130 U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */
122 ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */ 131 U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
123 /* 132 /*
124 * Linux can handle differing I-cache policies. Userspace JITs will 133 * Linux can handle differing I-cache policies. Userspace JITs will
125 * make use of *minLine 134 * make use of *minLine
126 */ 135 */
127 ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, 0), /* L1Ip */ 136 U_ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, 0), /* L1Ip */
128 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 10, 0), /* RAZ */ 137 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 10, 0), /* RAZ */
129 ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* IminLine */ 138 U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* IminLine */
130 ARM64_FTR_END, 139 ARM64_FTR_END,
131}; 140};
132 141
@@ -144,12 +153,12 @@ static struct arm64_ftr_bits ftr_id_mmfr0[] = {
144 153
145static struct arm64_ftr_bits ftr_id_aa64dfr0[] = { 154static struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
146 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0), 155 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
147 ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0), 156 U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0),
148 ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0), 157 U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0),
149 ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_BRPS_SHIFT, 4, 0), 158 U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_BRPS_SHIFT, 4, 0),
150 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0), 159 U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
151 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0), 160 U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0),
152 ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6), 161 U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
153 ARM64_FTR_END, 162 ARM64_FTR_END,
154}; 163};
155 164
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index fc5508e0df57..4eeb17198cfa 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -127,7 +127,11 @@ static int __init uefi_init(void)
127 table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables; 127 table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
128 config_tables = early_memremap(efi_to_phys(efi.systab->tables), 128 config_tables = early_memremap(efi_to_phys(efi.systab->tables),
129 table_size); 129 table_size);
130 130 if (config_tables == NULL) {
131 pr_warn("Unable to map EFI config table array.\n");
132 retval = -ENOMEM;
133 goto out;
134 }
131 retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, 135 retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
132 sizeof(efi_config_table_64_t), NULL); 136 sizeof(efi_config_table_64_t), NULL);
133 137
@@ -209,6 +213,14 @@ void __init efi_init(void)
209 PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK))); 213 PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK)));
210 memmap.phys_map = params.mmap; 214 memmap.phys_map = params.mmap;
211 memmap.map = early_memremap(params.mmap, params.mmap_size); 215 memmap.map = early_memremap(params.mmap, params.mmap_size);
216 if (memmap.map == NULL) {
217 /*
218 * If we are booting via UEFI, the UEFI memory map is the only
219 * description of memory we have, so there is little point in
220 * proceeding if we cannot access it.
221 */
222 panic("Unable to map EFI memory map.\n");
223 }
212 memmap.map_end = memmap.map + params.mmap_size; 224 memmap.map_end = memmap.map + params.mmap_size;
213 memmap.desc_size = params.desc_size; 225 memmap.desc_size = params.desc_size;
214 memmap.desc_version = params.desc_ver; 226 memmap.desc_version = params.desc_ver;
@@ -227,7 +239,6 @@ static bool __init efi_virtmap_init(void)
227 init_new_context(NULL, &efi_mm); 239 init_new_context(NULL, &efi_mm);
228 240
229 for_each_efi_memory_desc(&memmap, md) { 241 for_each_efi_memory_desc(&memmap, md) {
230 u64 paddr, npages, size;
231 pgprot_t prot; 242 pgprot_t prot;
232 243
233 if (!(md->attribute & EFI_MEMORY_RUNTIME)) 244 if (!(md->attribute & EFI_MEMORY_RUNTIME))
@@ -235,11 +246,6 @@ static bool __init efi_virtmap_init(void)
235 if (md->virt_addr == 0) 246 if (md->virt_addr == 0)
236 return false; 247 return false;
237 248
238 paddr = md->phys_addr;
239 npages = md->num_pages;
240 memrange_efi_to_native(&paddr, &npages);
241 size = npages << PAGE_SHIFT;
242
243 pr_info(" EFI remap 0x%016llx => %p\n", 249 pr_info(" EFI remap 0x%016llx => %p\n",
244 md->phys_addr, (void *)md->virt_addr); 250 md->phys_addr, (void *)md->virt_addr);
245 251
@@ -256,7 +262,8 @@ static bool __init efi_virtmap_init(void)
256 else 262 else
257 prot = PAGE_KERNEL; 263 prot = PAGE_KERNEL;
258 264
259 create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, 265 create_pgd_mapping(&efi_mm, md->phys_addr, md->virt_addr,
266 md->num_pages << EFI_PAGE_SHIFT,
260 __pgprot(pgprot_val(prot) | PTE_NG)); 267 __pgprot(pgprot_val(prot) | PTE_NG));
261 } 268 }
262 return true; 269 return true;
@@ -273,12 +280,12 @@ static int __init arm64_enable_runtime_services(void)
273 280
274 if (!efi_enabled(EFI_BOOT)) { 281 if (!efi_enabled(EFI_BOOT)) {
275 pr_info("EFI services will not be available.\n"); 282 pr_info("EFI services will not be available.\n");
276 return -1; 283 return 0;
277 } 284 }
278 285
279 if (efi_runtime_disabled()) { 286 if (efi_runtime_disabled()) {
280 pr_info("EFI runtime services will be disabled.\n"); 287 pr_info("EFI runtime services will be disabled.\n");
281 return -1; 288 return 0;
282 } 289 }
283 290
284 pr_info("Remapping and enabling EFI services.\n"); 291 pr_info("Remapping and enabling EFI services.\n");
@@ -288,7 +295,7 @@ static int __init arm64_enable_runtime_services(void)
288 mapsize); 295 mapsize);
289 if (!memmap.map) { 296 if (!memmap.map) {
290 pr_err("Failed to remap EFI memory map\n"); 297 pr_err("Failed to remap EFI memory map\n");
291 return -1; 298 return -ENOMEM;
292 } 299 }
293 memmap.map_end = memmap.map + mapsize; 300 memmap.map_end = memmap.map + mapsize;
294 efi.memmap = &memmap; 301 efi.memmap = &memmap;
@@ -297,13 +304,13 @@ static int __init arm64_enable_runtime_services(void)
297 sizeof(efi_system_table_t)); 304 sizeof(efi_system_table_t));
298 if (!efi.systab) { 305 if (!efi.systab) {
299 pr_err("Failed to remap EFI System Table\n"); 306 pr_err("Failed to remap EFI System Table\n");
300 return -1; 307 return -ENOMEM;
301 } 308 }
302 set_bit(EFI_SYSTEM_TABLES, &efi.flags); 309 set_bit(EFI_SYSTEM_TABLES, &efi.flags);
303 310
304 if (!efi_virtmap_init()) { 311 if (!efi_virtmap_init()) {
305 pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n"); 312 pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
306 return -1; 313 return -ENOMEM;
307 } 314 }
308 315
309 /* Set up runtime services function pointers */ 316 /* Set up runtime services function pointers */
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index f636a2639f03..e87f53ff5f58 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -76,13 +76,28 @@ static void flush_context(unsigned int cpu)
76 __flush_icache_all(); 76 __flush_icache_all();
77} 77}
78 78
79static int is_reserved_asid(u64 asid) 79static bool check_update_reserved_asid(u64 asid, u64 newasid)
80{ 80{
81 int cpu; 81 int cpu;
82 for_each_possible_cpu(cpu) 82 bool hit = false;
83 if (per_cpu(reserved_asids, cpu) == asid) 83
84 return 1; 84 /*
85 return 0; 85 * Iterate over the set of reserved ASIDs looking for a match.
86 * If we find one, then we can update our mm to use newasid
87 * (i.e. the same ASID in the current generation) but we can't
88 * exit the loop early, since we need to ensure that all copies
89 * of the old ASID are updated to reflect the mm. Failure to do
90 * so could result in us missing the reserved ASID in a future
91 * generation.
92 */
93 for_each_possible_cpu(cpu) {
94 if (per_cpu(reserved_asids, cpu) == asid) {
95 hit = true;
96 per_cpu(reserved_asids, cpu) = newasid;
97 }
98 }
99
100 return hit;
86} 101}
87 102
88static u64 new_context(struct mm_struct *mm, unsigned int cpu) 103static u64 new_context(struct mm_struct *mm, unsigned int cpu)
@@ -92,12 +107,14 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
92 u64 generation = atomic64_read(&asid_generation); 107 u64 generation = atomic64_read(&asid_generation);
93 108
94 if (asid != 0) { 109 if (asid != 0) {
110 u64 newasid = generation | (asid & ~ASID_MASK);
111
95 /* 112 /*
96 * If our current ASID was active during a rollover, we 113 * If our current ASID was active during a rollover, we
97 * can continue to use it and this was just a false alarm. 114 * can continue to use it and this was just a false alarm.
98 */ 115 */
99 if (is_reserved_asid(asid)) 116 if (check_update_reserved_asid(asid, newasid))
100 return generation | (asid & ~ASID_MASK); 117 return newasid;
101 118
102 /* 119 /*
103 * We had a valid ASID in a previous life, so try to re-use 120 * We had a valid ASID in a previous life, so try to re-use
@@ -105,7 +122,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
105 */ 122 */
106 asid &= ~ASID_MASK; 123 asid &= ~ASID_MASK;
107 if (!__test_and_set_bit(asid, asid_map)) 124 if (!__test_and_set_bit(asid, asid_map))
108 goto bump_gen; 125 return newasid;
109 } 126 }
110 127
111 /* 128 /*
@@ -129,10 +146,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
129set_asid: 146set_asid:
130 __set_bit(asid, asid_map); 147 __set_bit(asid, asid_map);
131 cur_idx = asid; 148 cur_idx = asid;
132 149 return asid | generation;
133bump_gen:
134 asid |= generation;
135 return asid;
136} 150}
137 151
138void check_and_switch_context(struct mm_struct *mm, unsigned int cpu) 152void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 19211c4a8911..92ddac1e8ca2 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -393,16 +393,16 @@ static struct fault_info {
393 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" }, 393 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" },
394 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" }, 394 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" },
395 { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, 395 { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
396 { do_bad, SIGBUS, 0, "reserved access flag fault" }, 396 { do_bad, SIGBUS, 0, "unknown 8" },
397 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" }, 397 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
398 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" }, 398 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
399 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" }, 399 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
400 { do_bad, SIGBUS, 0, "reserved permission fault" }, 400 { do_bad, SIGBUS, 0, "unknown 12" },
401 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" }, 401 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
402 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" }, 402 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
403 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" }, 403 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
404 { do_bad, SIGBUS, 0, "synchronous external abort" }, 404 { do_bad, SIGBUS, 0, "synchronous external abort" },
405 { do_bad, SIGBUS, 0, "asynchronous external abort" }, 405 { do_bad, SIGBUS, 0, "unknown 17" },
406 { do_bad, SIGBUS, 0, "unknown 18" }, 406 { do_bad, SIGBUS, 0, "unknown 18" },
407 { do_bad, SIGBUS, 0, "unknown 19" }, 407 { do_bad, SIGBUS, 0, "unknown 19" },
408 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, 408 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
@@ -410,16 +410,16 @@ static struct fault_info {
410 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, 410 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
411 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, 411 { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
412 { do_bad, SIGBUS, 0, "synchronous parity error" }, 412 { do_bad, SIGBUS, 0, "synchronous parity error" },
413 { do_bad, SIGBUS, 0, "asynchronous parity error" }, 413 { do_bad, SIGBUS, 0, "unknown 25" },
414 { do_bad, SIGBUS, 0, "unknown 26" }, 414 { do_bad, SIGBUS, 0, "unknown 26" },
415 { do_bad, SIGBUS, 0, "unknown 27" }, 415 { do_bad, SIGBUS, 0, "unknown 27" },
416 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" }, 416 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
417 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" }, 417 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
418 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" }, 418 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
419 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" }, 419 { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
420 { do_bad, SIGBUS, 0, "unknown 32" }, 420 { do_bad, SIGBUS, 0, "unknown 32" },
421 { do_bad, SIGBUS, BUS_ADRALN, "alignment fault" }, 421 { do_bad, SIGBUS, BUS_ADRALN, "alignment fault" },
422 { do_bad, SIGBUS, 0, "debug event" }, 422 { do_bad, SIGBUS, 0, "unknown 34" },
423 { do_bad, SIGBUS, 0, "unknown 35" }, 423 { do_bad, SIGBUS, 0, "unknown 35" },
424 { do_bad, SIGBUS, 0, "unknown 36" }, 424 { do_bad, SIGBUS, 0, "unknown 36" },
425 { do_bad, SIGBUS, 0, "unknown 37" }, 425 { do_bad, SIGBUS, 0, "unknown 37" },
@@ -433,21 +433,21 @@ static struct fault_info {
433 { do_bad, SIGBUS, 0, "unknown 45" }, 433 { do_bad, SIGBUS, 0, "unknown 45" },
434 { do_bad, SIGBUS, 0, "unknown 46" }, 434 { do_bad, SIGBUS, 0, "unknown 46" },
435 { do_bad, SIGBUS, 0, "unknown 47" }, 435 { do_bad, SIGBUS, 0, "unknown 47" },
436 { do_bad, SIGBUS, 0, "unknown 48" }, 436 { do_bad, SIGBUS, 0, "TLB conflict abort" },
437 { do_bad, SIGBUS, 0, "unknown 49" }, 437 { do_bad, SIGBUS, 0, "unknown 49" },
438 { do_bad, SIGBUS, 0, "unknown 50" }, 438 { do_bad, SIGBUS, 0, "unknown 50" },
439 { do_bad, SIGBUS, 0, "unknown 51" }, 439 { do_bad, SIGBUS, 0, "unknown 51" },
440 { do_bad, SIGBUS, 0, "implementation fault (lockdown abort)" }, 440 { do_bad, SIGBUS, 0, "implementation fault (lockdown abort)" },
441 { do_bad, SIGBUS, 0, "unknown 53" }, 441 { do_bad, SIGBUS, 0, "implementation fault (unsupported exclusive)" },
442 { do_bad, SIGBUS, 0, "unknown 54" }, 442 { do_bad, SIGBUS, 0, "unknown 54" },
443 { do_bad, SIGBUS, 0, "unknown 55" }, 443 { do_bad, SIGBUS, 0, "unknown 55" },
444 { do_bad, SIGBUS, 0, "unknown 56" }, 444 { do_bad, SIGBUS, 0, "unknown 56" },
445 { do_bad, SIGBUS, 0, "unknown 57" }, 445 { do_bad, SIGBUS, 0, "unknown 57" },
446 { do_bad, SIGBUS, 0, "implementation fault (coprocessor abort)" }, 446 { do_bad, SIGBUS, 0, "unknown 58" },
447 { do_bad, SIGBUS, 0, "unknown 59" }, 447 { do_bad, SIGBUS, 0, "unknown 59" },
448 { do_bad, SIGBUS, 0, "unknown 60" }, 448 { do_bad, SIGBUS, 0, "unknown 60" },
449 { do_bad, SIGBUS, 0, "unknown 61" }, 449 { do_bad, SIGBUS, 0, "section domain fault" },
450 { do_bad, SIGBUS, 0, "unknown 62" }, 450 { do_bad, SIGBUS, 0, "page domain fault" },
451 { do_bad, SIGBUS, 0, "unknown 63" }, 451 { do_bad, SIGBUS, 0, "unknown 63" },
452}; 452};
453 453
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index abb66f84d4ac..873e363048c6 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -64,8 +64,12 @@ EXPORT_SYMBOL(phys_mem_access_prot);
64 64
65static void __init *early_alloc(unsigned long sz) 65static void __init *early_alloc(unsigned long sz)
66{ 66{
67 void *ptr = __va(memblock_alloc(sz, sz)); 67 phys_addr_t phys;
68 BUG_ON(!ptr); 68 void *ptr;
69
70 phys = memblock_alloc(sz, sz);
71 BUG_ON(!phys);
72 ptr = __va(phys);
69 memset(ptr, 0, sz); 73 memset(ptr, 0, sz);
70 return ptr; 74 return ptr;
71} 75}
@@ -81,55 +85,19 @@ static void split_pmd(pmd_t *pmd, pte_t *pte)
81 do { 85 do {
82 /* 86 /*
83 * Need to have the least restrictive permissions available 87 * Need to have the least restrictive permissions available
84 * permissions will be fixed up later. Default the new page 88 * permissions will be fixed up later
85 * range as contiguous ptes.
86 */ 89 */
87 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC_CONT)); 90 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
88 pfn++; 91 pfn++;
89 } while (pte++, i++, i < PTRS_PER_PTE); 92 } while (pte++, i++, i < PTRS_PER_PTE);
90} 93}
91 94
92/*
93 * Given a PTE with the CONT bit set, determine where the CONT range
94 * starts, and clear the entire range of PTE CONT bits.
95 */
96static void clear_cont_pte_range(pte_t *pte, unsigned long addr)
97{
98 int i;
99
100 pte -= CONT_RANGE_OFFSET(addr);
101 for (i = 0; i < CONT_PTES; i++) {
102 set_pte(pte, pte_mknoncont(*pte));
103 pte++;
104 }
105 flush_tlb_all();
106}
107
108/*
109 * Given a range of PTEs set the pfn and provided page protection flags
110 */
111static void __populate_init_pte(pte_t *pte, unsigned long addr,
112 unsigned long end, phys_addr_t phys,
113 pgprot_t prot)
114{
115 unsigned long pfn = __phys_to_pfn(phys);
116
117 do {
118 /* clear all the bits except the pfn, then apply the prot */
119 set_pte(pte, pfn_pte(pfn, prot));
120 pte++;
121 pfn++;
122 addr += PAGE_SIZE;
123 } while (addr != end);
124}
125
126static void alloc_init_pte(pmd_t *pmd, unsigned long addr, 95static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
127 unsigned long end, phys_addr_t phys, 96 unsigned long end, unsigned long pfn,
128 pgprot_t prot, 97 pgprot_t prot,
129 void *(*alloc)(unsigned long size)) 98 void *(*alloc)(unsigned long size))
130{ 99{
131 pte_t *pte; 100 pte_t *pte;
132 unsigned long next;
133 101
134 if (pmd_none(*pmd) || pmd_sect(*pmd)) { 102 if (pmd_none(*pmd) || pmd_sect(*pmd)) {
135 pte = alloc(PTRS_PER_PTE * sizeof(pte_t)); 103 pte = alloc(PTRS_PER_PTE * sizeof(pte_t));
@@ -142,27 +110,9 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
142 110
143 pte = pte_offset_kernel(pmd, addr); 111 pte = pte_offset_kernel(pmd, addr);
144 do { 112 do {
145 next = min(end, (addr + CONT_SIZE) & CONT_MASK); 113 set_pte(pte, pfn_pte(pfn, prot));
146 if (((addr | next | phys) & ~CONT_MASK) == 0) { 114 pfn++;
147 /* a block of CONT_PTES */ 115 } while (pte++, addr += PAGE_SIZE, addr != end);
148 __populate_init_pte(pte, addr, next, phys,
149 __pgprot(pgprot_val(prot) | PTE_CONT));
150 } else {
151 /*
152 * If the range being split is already inside of a
153 * contiguous range but this PTE isn't going to be
154 * contiguous, then we want to unmark the adjacent
155 * ranges, then update the portion of the range we
156 * are interrested in.
157 */
158 clear_cont_pte_range(pte, addr);
159 __populate_init_pte(pte, addr, next, phys, prot);
160 }
161
162 pte += (next - addr) >> PAGE_SHIFT;
163 phys += next - addr;
164 addr = next;
165 } while (addr != end);
166} 116}
167 117
168static void split_pud(pud_t *old_pud, pmd_t *pmd) 118static void split_pud(pud_t *old_pud, pmd_t *pmd)
@@ -223,7 +173,8 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
223 } 173 }
224 } 174 }
225 } else { 175 } else {
226 alloc_init_pte(pmd, addr, next, phys, prot, alloc); 176 alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
177 prot, alloc);
227 } 178 }
228 phys += next - addr; 179 phys += next - addr;
229 } while (pmd++, addr = next, addr != end); 180 } while (pmd++, addr = next, addr != end);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a156b82dd14c..c2b66a277e98 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -524,7 +524,7 @@ asmlinkage long sys_chown(const char __user *filename,
524asmlinkage long sys_lchown(const char __user *filename, 524asmlinkage long sys_lchown(const char __user *filename,
525 uid_t user, gid_t group); 525 uid_t user, gid_t group);
526asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group); 526asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group);
527#ifdef CONFIG_UID16 527#ifdef CONFIG_HAVE_UID16
528asmlinkage long sys_chown16(const char __user *filename, 528asmlinkage long sys_chown16(const char __user *filename,
529 old_uid_t user, old_gid_t group); 529 old_uid_t user, old_gid_t group);
530asmlinkage long sys_lchown16(const char __user *filename, 530asmlinkage long sys_lchown16(const char __user *filename,
diff --git a/include/linux/types.h b/include/linux/types.h
index 70d8500bddf1..70dd3dfde631 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -35,7 +35,7 @@ typedef __kernel_gid16_t gid16_t;
35 35
36typedef unsigned long uintptr_t; 36typedef unsigned long uintptr_t;
37 37
38#ifdef CONFIG_UID16 38#ifdef CONFIG_HAVE_UID16
39/* This is defined by include/asm-{arch}/posix_types.h */ 39/* This is defined by include/asm-{arch}/posix_types.h */
40typedef __kernel_old_uid_t old_uid_t; 40typedef __kernel_old_uid_t old_uid_t;
41typedef __kernel_old_gid_t old_gid_t; 41typedef __kernel_old_gid_t old_gid_t;