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 Catalin Marinas:

- Explicitly encode the XZR register if the value passed to
write_sysreg_s() is 0.

The GIC CDEOI instruction is encoded as a system register write with
XZR as the source register. However, clang does not honour the "Z"
register constraint, leading to incorrect code generation

- Ensure the interrupts (DAIF.IF) are unmasked when completing
single-step of a suspended breakpoint before calling
exit_to_user_mode().

With pseudo-NMIs, interrupts are (additionally) masked at the PMR_EL1
register, handled by local_irq_*()

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: debug: always unmask interrupts in el0_softstp()
arm64/sysreg: Fix GIC CDEOI instruction encoding

+15 -4
+10 -1
arch/arm64/include/asm/sysreg.h
··· 1220 1220 __val; \ 1221 1221 }) 1222 1222 1223 + /* 1224 + * The "Z" constraint combined with the "%x0" template should be enough 1225 + * to force XZR generation if (v) is a constant 0 value but LLVM does not 1226 + * yet understand that modifier/constraint combo so a conditional is required 1227 + * to nudge the compiler into using XZR as a source for a 0 constant value. 1228 + */ 1223 1229 #define write_sysreg_s(v, r) do { \ 1224 1230 u64 __val = (u64)(v); \ 1225 1231 u32 __maybe_unused __check_r = (u32)(r); \ 1226 - asm volatile(__msr_s(r, "%x0") : : "rZ" (__val)); \ 1232 + if (__builtin_constant_p(__val) && __val == 0) \ 1233 + asm volatile(__msr_s(r, "xzr")); \ 1234 + else \ 1235 + asm volatile(__msr_s(r, "%x0") : : "r" (__val)); \ 1227 1236 } while (0) 1228 1237 1229 1238 /*
+5 -3
arch/arm64/kernel/entry-common.c
··· 697 697 698 698 static void noinstr el0_softstp(struct pt_regs *regs, unsigned long esr) 699 699 { 700 + bool step_done; 701 + 700 702 if (!is_ttbr0_addr(regs->pc)) 701 703 arm64_apply_bp_hardening(); 702 704 ··· 709 707 * If we are stepping a suspended breakpoint there's nothing more to do: 710 708 * the single-step is complete. 711 709 */ 712 - if (!try_step_suspended_breakpoints(regs)) { 713 - local_daif_restore(DAIF_PROCCTX); 710 + step_done = try_step_suspended_breakpoints(regs); 711 + local_daif_restore(DAIF_PROCCTX); 712 + if (!step_done) 714 713 do_el0_softstep(esr, regs); 715 - } 716 714 arm64_exit_to_user_mode(regs); 717 715 } 718 716