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

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux

Pull ARM updates from Russell King:

- add dev_is_amba() function to allow conversions during the next cycle

- improve PREEMPT_RT performance with VFP

- KASAN fixes for vmap stack

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux:
ARM: 9431/1: mm: Pair atomic_set_release() with _read_acquire()
ARM: 9430/1: entry: Do a dummy read from VMAP shadow
ARM: 9429/1: ioremap: Sync PGDs for VMALLOC shadow
ARM: 9426/1: vfp: Move sending signals outside of vfp_state_hold()ed section.
ARM: 9425/1: vfp: Use vfp_state_hold() in vfp_support_entry().
ARM: 9424/1: vfp: Use vfp_state_hold() in vfp_sync_hwstate().
ARM: 9423/1: vfp: Provide vfp_state_hold() for VFP locking.
ARM: 9415/1: amba: Add dev_is_amba() function and export it for modules

+102 -26
+8
arch/arm/kernel/entry-armv.S
··· 25 25 #include <asm/tls.h> 26 26 #include <asm/system_info.h> 27 27 #include <asm/uaccess-asm.h> 28 + #include <asm/kasan_def.h> 28 29 29 30 #include "entry-header.S" 30 31 #include <asm/probes.h> ··· 562 561 @ entries covering the vmalloc region. 563 562 @ 564 563 ldr r2, [ip] 564 + #ifdef CONFIG_KASAN_VMALLOC 565 + @ Also dummy read from the KASAN shadow memory for the new stack if we 566 + @ are using KASAN 567 + mov_l r2, KASAN_SHADOW_OFFSET 568 + add r2, r2, ip, lsr #KASAN_SHADOW_SCALE_SHIFT 569 + ldr r2, [r2] 570 + #endif 565 571 #endif 566 572 567 573 @ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what
+30 -5
arch/arm/mm/ioremap.c
··· 23 23 */ 24 24 #include <linux/module.h> 25 25 #include <linux/errno.h> 26 + #include <linux/kasan.h> 26 27 #include <linux/mm.h> 27 28 #include <linux/vmalloc.h> 28 29 #include <linux/io.h> ··· 116 115 } 117 116 EXPORT_SYMBOL(ioremap_page); 118 117 118 + #ifdef CONFIG_KASAN 119 + static unsigned long arm_kasan_mem_to_shadow(unsigned long addr) 120 + { 121 + return (unsigned long)kasan_mem_to_shadow((void *)addr); 122 + } 123 + #else 124 + static unsigned long arm_kasan_mem_to_shadow(unsigned long addr) 125 + { 126 + return 0; 127 + } 128 + #endif 129 + 130 + static void memcpy_pgd(struct mm_struct *mm, unsigned long start, 131 + unsigned long end) 132 + { 133 + end = ALIGN(end, PGDIR_SIZE); 134 + memcpy(pgd_offset(mm, start), pgd_offset_k(start), 135 + sizeof(pgd_t) * (pgd_index(end) - pgd_index(start))); 136 + } 137 + 119 138 void __check_vmalloc_seq(struct mm_struct *mm) 120 139 { 121 140 int seq; 122 141 123 142 do { 124 - seq = atomic_read(&init_mm.context.vmalloc_seq); 125 - memcpy(pgd_offset(mm, VMALLOC_START), 126 - pgd_offset_k(VMALLOC_START), 127 - sizeof(pgd_t) * (pgd_index(VMALLOC_END) - 128 - pgd_index(VMALLOC_START))); 143 + seq = atomic_read_acquire(&init_mm.context.vmalloc_seq); 144 + memcpy_pgd(mm, VMALLOC_START, VMALLOC_END); 145 + if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { 146 + unsigned long start = 147 + arm_kasan_mem_to_shadow(VMALLOC_START); 148 + unsigned long end = 149 + arm_kasan_mem_to_shadow(VMALLOC_END); 150 + memcpy_pgd(mm, start, end); 151 + } 129 152 /* 130 153 * Use a store-release so that other CPUs that observe the 131 154 * counter's new value are guaranteed to see the results of the
+53 -21
arch/arm/vfp/vfpmodule.c
··· 56 56 union vfp_state *vfp_current_hw_state[NR_CPUS]; 57 57 58 58 /* 59 + * Claim ownership of the VFP unit. 60 + * 61 + * The caller may change VFP registers until vfp_state_release() is called. 62 + * 63 + * local_bh_disable() is used to disable preemption and to disable VFP 64 + * processing in softirq context. On PREEMPT_RT kernels local_bh_disable() is 65 + * not sufficient because it only serializes soft interrupt related sections 66 + * via a local lock, but stays preemptible. Disabling preemption is the right 67 + * choice here as bottom half processing is always in thread context on RT 68 + * kernels so it implicitly prevents bottom half processing as well. 69 + */ 70 + static void vfp_state_hold(void) 71 + { 72 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 73 + local_bh_disable(); 74 + else 75 + preempt_disable(); 76 + } 77 + 78 + static void vfp_state_release(void) 79 + { 80 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 81 + local_bh_enable(); 82 + else 83 + preempt_enable(); 84 + } 85 + 86 + /* 59 87 * Is 'thread's most up to date state stored in this CPUs hardware? 60 88 * Must be called from non-preemptible context. 61 89 */ ··· 268 240 /* 269 241 * Process bitmask of exception conditions. 270 242 */ 271 - static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_regs *regs) 243 + static int vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr) 272 244 { 273 245 int si_code = 0; 274 246 ··· 276 248 277 249 if (exceptions == VFP_EXCEPTION_ERROR) { 278 250 vfp_panic("unhandled bounce", inst); 279 - vfp_raise_sigfpe(FPE_FLTINV, regs); 280 - return; 251 + return FPE_FLTINV; 281 252 } 282 253 283 254 /* ··· 304 277 RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF); 305 278 RAISE(FPSCR_IOC, FPSCR_IOE, FPE_FLTINV); 306 279 307 - if (si_code) 308 - vfp_raise_sigfpe(si_code, regs); 280 + return si_code; 309 281 } 310 282 311 283 /* ··· 350 324 static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) 351 325 { 352 326 u32 fpscr, orig_fpscr, fpsid, exceptions; 327 + int si_code2 = 0; 328 + int si_code = 0; 353 329 354 330 pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); 355 331 ··· 397 369 * unallocated VFP instruction but with FPSCR.IXE set and not 398 370 * on VFP subarch 1. 399 371 */ 400 - vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs); 401 - return; 372 + si_code = vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr); 373 + goto exit; 402 374 } 403 375 404 376 /* ··· 422 394 */ 423 395 exceptions = vfp_emulate_instruction(trigger, fpscr, regs); 424 396 if (exceptions) 425 - vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); 397 + si_code2 = vfp_raise_exceptions(exceptions, trigger, orig_fpscr); 426 398 427 399 /* 428 400 * If there isn't a second FP instruction, exit now. Note that 429 401 * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1. 430 402 */ 431 403 if ((fpexc & (FPEXC_EX | FPEXC_FP2V)) != (FPEXC_EX | FPEXC_FP2V)) 432 - return; 404 + goto exit; 433 405 434 406 /* 435 407 * The barrier() here prevents fpinst2 being read ··· 441 413 emulate: 442 414 exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs); 443 415 if (exceptions) 444 - vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); 416 + si_code = vfp_raise_exceptions(exceptions, trigger, orig_fpscr); 417 + exit: 418 + vfp_state_release(); 419 + if (si_code2) 420 + vfp_raise_sigfpe(si_code2, regs); 421 + if (si_code) 422 + vfp_raise_sigfpe(si_code, regs); 445 423 } 446 424 447 425 static void vfp_enable(void *unused) ··· 546 512 */ 547 513 void vfp_sync_hwstate(struct thread_info *thread) 548 514 { 549 - unsigned int cpu = get_cpu(); 515 + vfp_state_hold(); 550 516 551 - local_bh_disable(); 552 - 553 - if (vfp_state_in_hw(cpu, thread)) { 517 + if (vfp_state_in_hw(raw_smp_processor_id(), thread)) { 554 518 u32 fpexc = fmrx(FPEXC); 555 519 556 520 /* ··· 559 527 fmxr(FPEXC, fpexc); 560 528 } 561 529 562 - local_bh_enable(); 563 - put_cpu(); 530 + vfp_state_release(); 564 531 } 565 532 566 533 /* Ensure that the thread reloads the hardware VFP state on the next use. */ ··· 714 683 if (!user_mode(regs)) 715 684 return vfp_kmode_exception(regs, trigger); 716 685 717 - local_bh_disable(); 686 + vfp_state_hold(); 718 687 fpexc = fmrx(FPEXC); 719 688 720 689 /* ··· 779 748 * replay the instruction that trapped. 780 749 */ 781 750 fmxr(FPEXC, fpexc); 751 + vfp_state_release(); 782 752 } else { 783 753 /* Check for synchronous or asynchronous exceptions */ 784 754 if (!(fpexc & (FPEXC_EX | FPEXC_DEX))) { ··· 794 762 if (!(fpscr & FPSCR_IXE)) { 795 763 if (!(fpscr & FPSCR_LENGTH_MASK)) { 796 764 pr_debug("not VFP\n"); 797 - local_bh_enable(); 765 + vfp_state_release(); 798 766 return -ENOEXEC; 799 767 } 800 768 fpexc |= FPEXC_DEX; 801 769 } 802 770 } 803 771 bounce: regs->ARM_pc += 4; 772 + /* VFP_bounce() will invoke vfp_state_release() */ 804 773 VFP_bounce(trigger, fpexc, regs); 805 774 } 806 775 807 - local_bh_enable(); 808 776 return 0; 809 777 } 810 778 ··· 869 837 unsigned int cpu; 870 838 u32 fpexc; 871 839 872 - local_bh_disable(); 840 + vfp_state_hold(); 873 841 874 842 /* 875 843 * Kernel mode NEON is only allowed outside of hardirq context with ··· 900 868 { 901 869 /* Disable the NEON/VFP unit. */ 902 870 fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); 903 - local_bh_enable(); 871 + vfp_state_release(); 904 872 } 905 873 EXPORT_SYMBOL(kernel_neon_end); 906 874
+6
drivers/amba/bus.c
··· 449 449 }; 450 450 EXPORT_SYMBOL_GPL(amba_bustype); 451 451 452 + bool dev_is_amba(const struct device *dev) 453 + { 454 + return dev->bus == &amba_bustype; 455 + } 456 + EXPORT_SYMBOL_GPL(dev_is_amba); 457 + 452 458 static int __init amba_init(void) 453 459 { 454 460 return bus_register(&amba_bustype);
+5
include/linux/amba/bus.h
··· 121 121 #ifdef CONFIG_ARM_AMBA 122 122 int __amba_driver_register(struct amba_driver *, struct module *); 123 123 void amba_driver_unregister(struct amba_driver *); 124 + bool dev_is_amba(const struct device *dev); 124 125 #else 125 126 static inline int __amba_driver_register(struct amba_driver *drv, 126 127 struct module *owner) ··· 130 129 } 131 130 static inline void amba_driver_unregister(struct amba_driver *drv) 132 131 { 132 + } 133 + static inline bool dev_is_amba(const struct device *dev) 134 + { 135 + return false; 133 136 } 134 137 #endif 135 138