Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
"This addresses some problems with filesystem writeback due to the
recently merged hardware DBM patches, which caused us to treat some
read-only pages as dirty.

There are also some other, less significant fixes that are described
in the summary below:

A mixture of fixes for regressions introduced during the merge window,
some longer standing problems that we spotted and a couple of hardware
errata. The main changes are:

- Fix fallout from the h/w DBM patches, causing filesystem writeback
issues on both v8 and v8.1 CPUs

- Workaround for Cortex-A53 erratum #843419 in the module loader

- Fix for long-standing issue with compat big-endian signal handlers
using the saved floating point state"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: errata: add module build workaround for erratum #843419
arm64: compat: fix vfp save/restore across signal handlers in big-endian
arm64: cpu hotplug: ensure we mask out CPU_TASKS_FROZEN in notifiers
arm64: head.S: initialise mdcr_el2 in el2_setup
arm64: enable generic idle loop
arm64: pgtable: use a single bit for PTE_WRITE regardless of DBM
arm64: Fix pte_modify() to preserve the hardware dirty information
arm64: Fix the pte_hw_dirty() check when AF/DBM is enabled
arm64: dma-mapping: check whether cma area is initialized or not

+71 -22
+17
arch/arm64/Kconfig
··· 32 32 select GENERIC_CLOCKEVENTS_BROADCAST 33 33 select GENERIC_CPU_AUTOPROBE 34 34 select GENERIC_EARLY_IOREMAP 35 + select GENERIC_IDLE_POLL_SETUP 35 36 select GENERIC_IRQ_PROBE 36 37 select GENERIC_IRQ_SHOW 37 38 select GENERIC_IRQ_SHOW_LEVEL ··· 329 328 Please note that this does not necessarily enable the workaround, 330 329 as it depends on the alternative framework, which will only patch 331 330 the kernel if an affected CPU is detected. 331 + 332 + If unsure, say Y. 333 + 334 + config ARM64_ERRATUM_843419 335 + bool "Cortex-A53: 843419: A load or store might access an incorrect address" 336 + depends on MODULES 337 + default y 338 + help 339 + This option builds kernel modules using the large memory model in 340 + order to avoid the use of the ADRP instruction, which can cause 341 + a subsequent memory access to use an incorrect address on Cortex-A53 342 + parts up to r0p4. 343 + 344 + Note that the kernel itself must be linked with a version of ld 345 + which fixes potentially affected ADRP instructions through the 346 + use of veneers. 332 347 333 348 If unsure, say Y. 334 349
+4
arch/arm64/Makefile
··· 41 41 42 42 CHECKFLAGS += -D__aarch64__ 43 43 44 + ifeq ($(CONFIG_ARM64_ERRATUM_843419), y) 45 + CFLAGS_MODULE += -mcmodel=large 46 + endif 47 + 44 48 # Default value 45 49 head-y := arch/arm64/kernel/head.o 46 50
+4 -8
arch/arm64/include/asm/pgtable.h
··· 26 26 * Software defined PTE bits definition. 27 27 */ 28 28 #define PTE_VALID (_AT(pteval_t, 1) << 0) 29 + #define PTE_WRITE (PTE_DBM) /* same as DBM (51) */ 29 30 #define PTE_DIRTY (_AT(pteval_t, 1) << 55) 30 31 #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) 31 - #ifdef CONFIG_ARM64_HW_AFDBM 32 - #define PTE_WRITE (PTE_DBM) /* same as DBM */ 33 - #else 34 - #define PTE_WRITE (_AT(pteval_t, 1) << 57) 35 - #endif 36 32 #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ 37 33 38 34 /* ··· 142 146 #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) 143 147 144 148 #ifdef CONFIG_ARM64_HW_AFDBM 145 - #define pte_hw_dirty(pte) (!(pte_val(pte) & PTE_RDONLY)) 149 + #define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY)) 146 150 #else 147 151 #define pte_hw_dirty(pte) (0) 148 152 #endif ··· 234 238 * When hardware DBM is not present, the sofware PTE_DIRTY bit is updated via 235 239 * the page fault mechanism. Checking the dirty status of a pte becomes: 236 240 * 237 - * PTE_DIRTY || !PTE_RDONLY 241 + * PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY) 238 242 */ 239 243 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, 240 244 pte_t *ptep, pte_t pte) ··· 499 503 PTE_PROT_NONE | PTE_WRITE | PTE_TYPE_MASK; 500 504 /* preserve the hardware dirty information */ 501 505 if (pte_hw_dirty(pte)) 502 - newprot |= PTE_DIRTY; 506 + pte = pte_mkdirty(pte); 503 507 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 504 508 return pte; 505 509 }
+1 -1
arch/arm64/kernel/debug-monitors.c
··· 134 134 unsigned long action, void *data) 135 135 { 136 136 int cpu = (unsigned long)data; 137 - if (action == CPU_ONLINE) 137 + if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE) 138 138 smp_call_function_single(cpu, clear_os_lock, NULL, 1); 139 139 return NOTIFY_OK; 140 140 }
+5
arch/arm64/kernel/head.S
··· 523 523 msr hstr_el2, xzr // Disable CP15 traps to EL2 524 524 #endif 525 525 526 + /* EL2 debug */ 527 + mrs x0, pmcr_el0 // Disable debug access traps 528 + ubfx x0, x0, #11, #5 // to EL2 and allow access to 529 + msr mdcr_el2, x0 // all PMU counters from EL1 530 + 526 531 /* Stage-2 translation */ 527 532 msr vttbr_el2, xzr 528 533
+1 -1
arch/arm64/kernel/hw_breakpoint.c
··· 872 872 void *hcpu) 873 873 { 874 874 int cpu = (long)hcpu; 875 - if (action == CPU_ONLINE) 875 + if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE) 876 876 smp_call_function_single(cpu, hw_breakpoint_reset, NULL, 1); 877 877 return NOTIFY_OK; 878 878 }
+2
arch/arm64/kernel/module.c
··· 332 332 ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21, 333 333 AARCH64_INSN_IMM_ADR); 334 334 break; 335 + #ifndef CONFIG_ARM64_ERRATUM_843419 335 336 case R_AARCH64_ADR_PREL_PG_HI21_NC: 336 337 overflow_check = false; 337 338 case R_AARCH64_ADR_PREL_PG_HI21: 338 339 ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21, 339 340 AARCH64_INSN_IMM_ADR); 340 341 break; 342 + #endif 341 343 case R_AARCH64_ADD_ABS_LO12_NC: 342 344 case R_AARCH64_LDST8_ABS_LO12_NC: 343 345 overflow_check = false;
+36 -11
arch/arm64/kernel/signal32.c
··· 212 212 213 213 /* 214 214 * VFP save/restore code. 215 + * 216 + * We have to be careful with endianness, since the fpsimd context-switch 217 + * code operates on 128-bit (Q) register values whereas the compat ABI 218 + * uses an array of 64-bit (D) registers. Consequently, we need to swap 219 + * the two halves of each Q register when running on a big-endian CPU. 215 220 */ 221 + union __fpsimd_vreg { 222 + __uint128_t raw; 223 + struct { 224 + #ifdef __AARCH64EB__ 225 + u64 hi; 226 + u64 lo; 227 + #else 228 + u64 lo; 229 + u64 hi; 230 + #endif 231 + }; 232 + }; 233 + 216 234 static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) 217 235 { 218 236 struct fpsimd_state *fpsimd = &current->thread.fpsimd_state; 219 237 compat_ulong_t magic = VFP_MAGIC; 220 238 compat_ulong_t size = VFP_STORAGE_SIZE; 221 239 compat_ulong_t fpscr, fpexc; 222 - int err = 0; 240 + int i, err = 0; 223 241 224 242 /* 225 243 * Save the hardware registers to the fpsimd_state structure. ··· 253 235 /* 254 236 * Now copy the FP registers. Since the registers are packed, 255 237 * we can copy the prefix we want (V0-V15) as it is. 256 - * FIXME: Won't work if big endian. 257 238 */ 258 - err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs, 259 - sizeof(frame->ufp.fpregs)); 239 + for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i += 2) { 240 + union __fpsimd_vreg vreg = { 241 + .raw = fpsimd->vregs[i >> 1], 242 + }; 243 + 244 + __put_user_error(vreg.lo, &frame->ufp.fpregs[i], err); 245 + __put_user_error(vreg.hi, &frame->ufp.fpregs[i + 1], err); 246 + } 260 247 261 248 /* Create an AArch32 fpscr from the fpsr and the fpcr. */ 262 249 fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) | ··· 286 263 compat_ulong_t magic = VFP_MAGIC; 287 264 compat_ulong_t size = VFP_STORAGE_SIZE; 288 265 compat_ulong_t fpscr; 289 - int err = 0; 266 + int i, err = 0; 290 267 291 268 __get_user_error(magic, &frame->magic, err); 292 269 __get_user_error(size, &frame->size, err); ··· 296 273 if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) 297 274 return -EINVAL; 298 275 299 - /* 300 - * Copy the FP registers into the start of the fpsimd_state. 301 - * FIXME: Won't work if big endian. 302 - */ 303 - err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs, 304 - sizeof(frame->ufp.fpregs)); 276 + /* Copy the FP registers into the start of the fpsimd_state. */ 277 + for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i += 2) { 278 + union __fpsimd_vreg vreg; 279 + 280 + __get_user_error(vreg.lo, &frame->ufp.fpregs[i], err); 281 + __get_user_error(vreg.hi, &frame->ufp.fpregs[i + 1], err); 282 + fpsimd.vregs[i >> 1] = vreg.raw; 283 + } 305 284 306 285 /* Extract the fpsr and the fpcr from the fpscr */ 307 286 __get_user_error(fpscr, &frame->ufp.fpscr, err);
+1 -1
arch/arm64/mm/dma-mapping.c
··· 100 100 if (IS_ENABLED(CONFIG_ZONE_DMA) && 101 101 dev->coherent_dma_mask <= DMA_BIT_MASK(32)) 102 102 flags |= GFP_DMA; 103 - if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) { 103 + if (dev_get_cma_area(dev) && (flags & __GFP_WAIT)) { 104 104 struct page *page; 105 105 void *addr; 106 106