From: Catalin Marinas Date: Wed, 9 Dec 2020 18:04:55 +0000 (+0000) Subject: Merge remote-tracking branch 'arm64/for-next/fixes' into for-next/core X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=d889797530c66f699170233474eab3361471e808;p=linux.git Merge remote-tracking branch 'arm64/for-next/fixes' into for-next/core * arm64/for-next/fixes: (26 commits) arm64: mte: fix prctl(PR_GET_TAGGED_ADDR_CTRL) if TCF0=NONE arm64: mte: Fix typo in macro definition arm64: entry: fix EL1 debug transitions arm64: entry: fix NMI {user, kernel}->kernel transitions arm64: entry: fix non-NMI kernel<->kernel transitions arm64: ptrace: prepare for EL1 irq/rcu tracking arm64: entry: fix non-NMI user<->kernel transitions arm64: entry: move el1 irq/nmi logic to C arm64: entry: prepare ret_to_user for function call arm64: entry: move enter_from_user_mode to entry-common.c arm64: entry: mark entry code as noinstr arm64: mark idle code as noinstr arm64: syscall: exit userspace before unmasking exceptions arm64: pgtable: Ensure dirty bit is preserved across pte_wrprotect() arm64: pgtable: Fix pte_accessible() ACPI/IORT: Fix doc warnings in iort.c arm64/fpsimd: add to to fix fpsimd build arm64: cpu_errata: Apply Erratum 845719 to KRYO2XX Silver arm64: proton-pack: Add KRYO2XX silver CPUs to spectre-v2 safe-list arm64: kpti: Add KRYO2XX gold/silver CPU cores to kpti safelist ... # Conflicts: # arch/arm64/include/asm/exception.h # arch/arm64/kernel/sdei.c --- d889797530c66f699170233474eab3361471e808 diff --cc arch/arm64/include/asm/exception.h index 2a8aa1884d8ab,0756191f44f64..78537393b6506 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@@ -31,8 -31,13 +31,13 @@@ static inline u32 disr_to_esr(u64 disr return esr; } + asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs); + asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs); asmlinkage void enter_from_user_mode(void); + asmlinkage void exit_to_user_mode(void); + void arm64_enter_nmi(struct pt_regs *regs); + void arm64_exit_nmi(struct pt_regs *regs); -void do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs); +void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs); void do_undefinstr(struct pt_regs *regs); void do_bti(struct pt_regs *regs); asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr); diff --cc arch/arm64/kernel/entry-common.c index dbbddfbf4a720,70e0a7591245d..5346953e4382e --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@@ -21,12 -113,15 +113,14 @@@ static void noinstr el1_abort(struct pt { unsigned long far = read_sysreg(far_el1); + enter_from_kernel_mode(regs); local_daif_inherit(regs); - far = untagged_addr(far); do_mem_abort(far, esr, regs); + local_daif_mask(); + exit_to_kernel_mode(regs); } - NOKPROBE_SYMBOL(el1_abort); - static void notrace el1_pc(struct pt_regs *regs, unsigned long esr) + static void noinstr el1_pc(struct pt_regs *regs, unsigned long esr) { unsigned long far = read_sysreg(far_el1); @@@ -111,13 -254,13 +253,12 @@@ static void noinstr el0_da(struct pt_re { unsigned long far = read_sysreg(far_el1); - user_exit_irqoff(); + enter_from_user_mode(); local_daif_restore(DAIF_PROCCTX); - far = untagged_addr(far); do_mem_abort(far, esr, regs); } - NOKPROBE_SYMBOL(el0_da); - static void notrace el0_ia(struct pt_regs *regs, unsigned long esr) + static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr) { unsigned long far = read_sysreg(far_el1); diff --cc arch/arm64/kernel/sdei.c index 35298f4e3fafc,793c46d6a4479..2c7ca449dd511 --- a/arch/arm64/kernel/sdei.c +++ b/arch/arm64/kernel/sdei.c @@@ -292,40 -223,13 +293,40 @@@ static __kprobes unsigned long _sdei_ha return vbar + 0x480; } +static void __kprobes notrace __sdei_pstate_entry(void) +{ + /* + * The original SDEI spec (ARM DEN 0054A) can be read ambiguously as to + * whether PSTATE bits are inherited unchanged or generated from + * scratch, and the TF-A implementation always clears PAN and always + * clears UAO. There are no other known implementations. + * + * Subsequent revisions (ARM DEN 0054B) follow the usual rules for how + * PSTATE is modified upon architectural exceptions, and so PAN is + * either inherited or set per SCTLR_ELx.SPAN, and UAO is always + * cleared. + * + * We must explicitly reset PAN to the expected state, including + * clearing it when the host isn't using it, in case a VM had it set. + */ + if (system_uses_hw_pan()) + set_pstate_pan(1); + else if (cpu_has_pan()) + set_pstate_pan(0); +} - asmlinkage __kprobes notrace unsigned long + asmlinkage noinstr unsigned long __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg) { unsigned long ret; + /* + * We didn't take an exception to get here, so the HW hasn't + * set/cleared bits in PSTATE that we may rely on. Initialize PAN. + */ + __sdei_pstate_entry(); + - nmi_enter(); + arm64_enter_nmi(regs); ret = _sdei_handler(regs, arg); diff --cc arch/arm64/kernel/syscall.c index fe3fa8fd13c83,f8f758e4a3064..f61e9d8cc55a1 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@@ -121,9 -121,8 +121,8 @@@ static void el0_svc_common(struct pt_re cortex_a76_erratum_1463225_svc_handler(); local_daif_restore(DAIF_PROCCTX); - user_exit(); - if (system_supports_mte() && (flags & _TIF_MTE_ASYNC_FAULT)) { + if (flags & _TIF_MTE_ASYNC_FAULT) { /* * Process the asynchronous tag check fault before the actual * syscall. do_notify_resume() will send a signal to userspace