diff options
Diffstat (limited to 'arch')
34 files changed, 243 insertions, 207 deletions
| diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 7d59765aef22..c392e18f1e43 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -207,7 +207,7 @@ static void xen_power_off(void)  static irqreturn_t xen_arm_callback(int irq, void *arg)  { -	xen_hvm_evtchn_do_upcall(); +	xen_evtchn_do_upcall();  	return IRQ_HANDLED;  } diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 96e50227f940..5bba39376055 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -663,7 +663,7 @@ static inline bool supports_clearbhb(int scope)  		isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);  	return cpuid_feature_extract_unsigned_field(isar2, -						    ID_AA64ISAR2_EL1_BC_SHIFT); +						    ID_AA64ISAR2_EL1_CLRBHB_SHIFT);  }  const struct cpumask *system_32bit_el0_cpumask(void); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index b018ae12ff5f..444a73c2e638 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -222,7 +222,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {  static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {  	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),  	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0), -	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0), +	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),  	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0),  	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),  		       FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 2517ef7c21cf..76ce150e7347 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -1347,7 +1347,11 @@ UnsignedEnum	51:48	RPRFM  	0b0000	NI  	0b0001	IMP  EndEnum -Res0	47:28 +Res0	47:32 +UnsignedEnum	31:28	CLRBHB +	0b0000	NI +	0b0001	IMP +EndEnum  UnsignedEnum	27:24	PAC_frac  	0b0000	NI  	0b0001	IMP diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 15f6cfddcc08..41e8fe55cd98 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -907,3 +907,7 @@ EXPORT_SYMBOL(acpi_unregister_ioapic);   * TBD when IA64 starts to support suspend...   */  int acpi_suspend_lowlevel(void) { return 0; } + +void acpi_proc_quirk_mwait_check(void) +{ +} diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 54b9387c3691..3aaadfd2c8eb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -255,7 +255,7 @@ config PPC  	select HAVE_KPROBES  	select HAVE_KPROBES_ON_FTRACE  	select HAVE_KRETPROBES -	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT +	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT && (!ARCH_USING_PATCHABLE_FUNCTION_ENTRY || (!CC_IS_GCC || GCC_VERSION >= 110100))  	select HAVE_LIVEPATCH			if HAVE_DYNAMIC_FTRACE_WITH_REGS  	select HAVE_MOD_ARCH_SPECIFIC  	select HAVE_NMI				if PERF_EVENTS || (PPC64 && PPC_BOOK3S) diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index b8513dc3e53a..a1318ce18d0e 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)  	struct arch_hw_breakpoint *info;  	int i; +	preempt_disable(); +  	for (i = 0; i < nr_wp_slots(); i++) {  		struct perf_event *bp = __this_cpu_read(bp_per_reg[i]);  		if (unlikely(bp && counter_arch_bp(bp)->perf_single_step))  			goto reset;  	} -	return; +	goto out;  reset:  	regs_set_return_msr(regs, regs->msr & ~MSR_SE); @@ -245,6 +247,9 @@ reset:  		__set_breakpoint(i, info);  		info->perf_single_step = false;  	} + +out: +	preempt_enable();  }  static bool is_larx_stcx_instr(int type) @@ -363,6 +368,11 @@ static void handle_p10dd1_spurious_exception(struct perf_event **bp,  	}  } +/* + * Handle a DABR or DAWR exception. + * + * Called in atomic context. + */  int hw_breakpoint_handler(struct die_args *args)  {  	bool err = false; @@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler);  /*   * Handle single-step exceptions following a DABR hit. + * + * Called in atomic context.   */  static int single_step_dabr_instruction(struct die_args *args)  { @@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction);  /*   * Handle debug exception notifications. + * + * Called in atomic context.   */  int hw_breakpoint_exceptions_notify(  		struct notifier_block *unused, unsigned long val, void *data) diff --git a/arch/powerpc/kernel/hw_breakpoint_constraints.c b/arch/powerpc/kernel/hw_breakpoint_constraints.c index a74623025f3a..9e51801c4915 100644 --- a/arch/powerpc/kernel/hw_breakpoint_constraints.c +++ b/arch/powerpc/kernel/hw_breakpoint_constraints.c @@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,  			 int *type, int *size, unsigned long *ea)  {  	struct instruction_op op; +	int err; -	if (__get_user_instr(*instr, (void __user *)regs->nip)) +	pagefault_disable(); +	err = __get_user_instr(*instr, (void __user *)regs->nip); +	pagefault_enable(); + +	if (err)  		return;  	analyse_instr(&op, regs, *instr); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index eeff136b83d9..64ff37721fd0 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1512,23 +1512,11 @@ static void do_program_check(struct pt_regs *regs)  			return;  		} -		if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) { -			ppc_inst_t insn; - -			if (get_user_instr(insn, (void __user *)regs->nip)) { -				_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); -				return; -			} - -			if (ppc_inst_primary_opcode(insn) == 31 && -			    get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) { -				_exception(SIGILL, regs, ILL_ILLOPN, regs->nip); -				return; -			} +		/* User mode considers other cases after enabling IRQs */ +		if (!user_mode(regs)) { +			_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); +			return;  		} - -		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); -		return;  	}  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM  	if (reason & REASON_TM) { @@ -1561,16 +1549,44 @@ static void do_program_check(struct pt_regs *regs)  	/*  	 * If we took the program check in the kernel skip down to sending a -	 * SIGILL. The subsequent cases all relate to emulating instructions -	 * which we should only do for userspace. We also do not want to enable -	 * interrupts for kernel faults because that might lead to further -	 * faults, and loose the context of the original exception. +	 * SIGILL. The subsequent cases all relate to user space, such as +	 * emulating instructions which we should only do for user space. We +	 * also do not want to enable interrupts for kernel faults because that +	 * might lead to further faults, and loose the context of the original +	 * exception.  	 */  	if (!user_mode(regs))  		goto sigill;  	interrupt_cond_local_irq_enable(regs); +	/* +	 * (reason & REASON_TRAP) is mostly handled before enabling IRQs, +	 * except get_user_instr() can sleep so we cannot reliably inspect the +	 * current instruction in that context. Now that we know we are +	 * handling a user space trap and can sleep, we can check if the trap +	 * was a hashchk failure. +	 */ +	if (reason & REASON_TRAP) { +		if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) { +			ppc_inst_t insn; + +			if (get_user_instr(insn, (void __user *)regs->nip)) { +				_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); +				return; +			} + +			if (ppc_inst_primary_opcode(insn) == 31 && +			    get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) { +				_exception(SIGILL, regs, ILL_ILLOPN, regs->nip); +				return; +			} +		} + +		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); +		return; +	} +  	/* (reason & REASON_ILLEGAL) would be the obvious thing here,  	 * but there seems to be a hardware bug on the 405GP (RevD)  	 * that means ESR is sometimes set incorrectly - either to diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 317175791d23..3449be7c0d51 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event)  	}  	domain = event_get_domain(event); -	if (domain >= HV_PERF_DOMAIN_MAX) { +	if (domain  == 0 || domain >= HV_PERF_DOMAIN_MAX) {  		pr_devel("invalid domain %d\n", domain);  		return -EINVAL;  	} diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig index d9f1a2a83158..1824536cf6f2 100644 --- a/arch/powerpc/platforms/82xx/Kconfig +++ b/arch/powerpc/platforms/82xx/Kconfig @@ -2,6 +2,7 @@  menuconfig PPC_82xx  	bool "82xx-based boards (PQ II)"  	depends on PPC_BOOK3S_32 +	select FSL_SOC  if PPC_82xx @@ -9,7 +10,6 @@ config EP8248E  	bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)"  	select CPM2  	select PPC_INDIRECT_PCI if PCI -	select FSL_SOC  	select PHYLIB if NETDEVICES  	select MDIO_BITBANG if PHYLIB  	help @@ -22,7 +22,6 @@ config MGCOGE  	bool "Keymile MGCOGE"  	select CPM2  	select PPC_INDIRECT_PCI if PCI -	select FSL_SOC  	help  	  This enables support for the Keymile MGCOGE board. diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 6c2826417b33..93c60c0c9d4a 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -294,7 +294,7 @@ static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs)  	inc_irq_stat(irq_hv_callback_count); -	xen_hvm_evtchn_do_upcall(); +	xen_evtchn_do_upcall();  	set_irq_regs(old_regs);  } diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index 5ff49fd67732..571fe4d2d232 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -105,6 +105,13 @@  	CFI_POST_PADDING					\  	SYM_FUNC_END(__cfi_##name) +/* UML needs to be able to override memcpy() and friends for KASAN. */ +#ifdef CONFIG_UML +# define SYM_FUNC_ALIAS_MEMFUNC	SYM_FUNC_ALIAS_WEAK +#else +# define SYM_FUNC_ALIAS_MEMFUNC	SYM_FUNC_ALIAS +#endif +  /* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */  #define SYM_TYPED_FUNC_START(name)				\  	SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN)	\ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 416901d406f8..8dac45a2c7fc 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -186,8 +186,7 @@ do {						\  #else  #define deactivate_mm(tsk, mm)			\  do {						\ -	if (!tsk->vfork_done)			\ -		shstk_free(tsk);		\ +	shstk_free(tsk);			\  	load_gs_index(0);			\  	loadsegment(fs, 0);			\  } while (0) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 4acbcddddc29..772d03487520 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -9,13 +9,6 @@ struct paravirt_patch_site {  	u8 type;		/* type of this instruction */  	u8 len;			/* length of original instruction */  }; - -/* Lazy mode for batching updates / context switch */ -enum paravirt_lazy_mode { -	PARAVIRT_LAZY_NONE, -	PARAVIRT_LAZY_MMU, -	PARAVIRT_LAZY_CPU, -};  #endif  #ifdef CONFIG_PARAVIRT @@ -549,14 +542,6 @@ int paravirt_disable_iospace(void);  	__PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),	\  		     PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) -enum paravirt_lazy_mode paravirt_get_lazy_mode(void); -void paravirt_start_context_switch(struct task_struct *prev); -void paravirt_end_context_switch(struct task_struct *next); - -void paravirt_enter_lazy_mmu(void); -void paravirt_leave_lazy_mmu(void); -void paravirt_flush_lazy_mmu(void); -  void _paravirt_nop(void);  void paravirt_BUG(void);  unsigned long paravirt_ret0(void); diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 0086920cda06..a3669a7774ed 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -683,13 +683,11 @@ extern u16 get_llc_id(unsigned int cpu);  #ifdef CONFIG_CPU_SUP_AMD  extern u32 amd_get_nodes_per_socket(void);  extern u32 amd_get_highest_perf(void); -extern bool cpu_has_ibpb_brtype_microcode(void);  extern void amd_clear_divider(void);  extern void amd_check_microcode(void);  #else  static inline u32 amd_get_nodes_per_socket(void)	{ return 0; }  static inline u32 amd_get_highest_perf(void)		{ return 0; } -static inline bool cpu_has_ibpb_brtype_microcode(void)	{ return false; }  static inline void amd_clear_divider(void)		{ }  static inline void amd_check_microcode(void)		{ }  #endif diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 5fc35f889cd1..7048dfacc04b 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h @@ -36,6 +36,7 @@  extern struct shared_info *HYPERVISOR_shared_info;  extern struct start_info *xen_start_info; +#include <asm/bug.h>  #include <asm/processor.h>  #define XEN_SIGNATURE "XenVMMXenVMM" @@ -63,4 +64,40 @@ void __init xen_pvh_init(struct boot_params *boot_params);  void __init mem_map_via_hcall(struct boot_params *boot_params_p);  #endif +/* Lazy mode for batching updates / context switch */ +enum xen_lazy_mode { +	XEN_LAZY_NONE, +	XEN_LAZY_MMU, +	XEN_LAZY_CPU, +}; + +DECLARE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode); +DECLARE_PER_CPU(unsigned int, xen_lazy_nesting); + +static inline void enter_lazy(enum xen_lazy_mode mode) +{ +	enum xen_lazy_mode old_mode = this_cpu_read(xen_lazy_mode); + +	if (mode == old_mode) { +		this_cpu_inc(xen_lazy_nesting); +		return; +	} + +	BUG_ON(old_mode != XEN_LAZY_NONE); + +	this_cpu_write(xen_lazy_mode, mode); +} + +static inline void leave_lazy(enum xen_lazy_mode mode) +{ +	BUG_ON(this_cpu_read(xen_lazy_mode) != mode); + +	if (this_cpu_read(xen_lazy_nesting) == 0) +		this_cpu_write(xen_lazy_mode, XEN_LAZY_NONE); +	else +		this_cpu_dec(xen_lazy_nesting); +} + +enum xen_lazy_mode xen_get_lazy_mode(void); +  #endif /* _ASM_X86_XEN_HYPERVISOR_H */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index a5ead6a6d233..517ee01503be 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -720,13 +720,8 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)  {  	s32 *s; -	/* -	 * Do not patch out the default return thunks if those needed are the -	 * ones generated by the compiler. -	 */ -	if (cpu_feature_enabled(X86_FEATURE_RETHUNK) && -	    (x86_return_thunk == __x86_return_thunk)) -		return; +	if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) +		static_call_force_reinit();  	for (s = start; s < end; s++) {  		void *dest = NULL, *addr = (void *)s + *s; diff --git a/arch/x86/kernel/callthunks.c b/arch/x86/kernel/callthunks.c index c06bfc086565..faa9f2299848 100644 --- a/arch/x86/kernel/callthunks.c +++ b/arch/x86/kernel/callthunks.c @@ -272,7 +272,6 @@ void __init callthunks_patch_builtin_calls(void)  	pr_info("Setting up call depth tracking\n");  	mutex_lock(&text_mutex);  	callthunks_setup(&cs, &builtin_coretext); -	static_call_force_reinit();  	thunks_initialized = true;  	mutex_unlock(&text_mutex);  } diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index dd8379d84445..03ef962a6992 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -766,6 +766,15 @@ static void early_init_amd(struct cpuinfo_x86 *c)  	if (cpu_has(c, X86_FEATURE_TOPOEXT))  		smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; + +	if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) { +		if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB)) +			setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); +		else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { +			setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); +			setup_force_cpu_cap(X86_FEATURE_SBPB); +		} +	}  }  static void init_amd_k8(struct cpuinfo_x86 *c) @@ -1301,25 +1310,6 @@ void amd_check_microcode(void)  	on_each_cpu(zenbleed_check_cpu, NULL, 1);  } -bool cpu_has_ibpb_brtype_microcode(void) -{ -	switch (boot_cpu_data.x86) { -	/* Zen1/2 IBPB flushes branch type predictions too. */ -	case 0x17: -		return boot_cpu_has(X86_FEATURE_AMD_IBPB); -	case 0x19: -		/* Poke the MSR bit on Zen3/4 to check its presence. */ -		if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { -			setup_force_cpu_cap(X86_FEATURE_SBPB); -			return true; -		} else { -			return false; -		} -	default: -		return false; -	} -} -  /*   * Issue a DIV 0/1 insn to clear any division data from previous DIV   * operations. diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index f081d26616ac..10499bcd4e39 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -2404,27 +2404,16 @@ early_param("spec_rstack_overflow", srso_parse_cmdline);  static void __init srso_select_mitigation(void)  { -	bool has_microcode; +	bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE);  	if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off())  		goto pred_cmd; -	/* -	 * The first check is for the kernel running as a guest in order -	 * for guests to verify whether IBPB is a viable mitigation. -	 */ -	has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode();  	if (!has_microcode) {  		pr_warn("IBPB-extending microcode not applied!\n");  		pr_warn(SRSO_NOTICE);  	} else {  		/* -		 * Enable the synthetic (even if in a real CPUID leaf) -		 * flags for guests. -		 */ -		setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); - -		/*  		 * Zen1/2 with SMT off aren't vulnerable after the right  		 * IBPB microcode has been applied.  		 */ @@ -2444,7 +2433,7 @@ static void __init srso_select_mitigation(void)  	switch (srso_cmd) {  	case SRSO_CMD_OFF: -		return; +		goto pred_cmd;  	case SRSO_CMD_MICROCODE:  		if (has_microcode) { @@ -2717,7 +2706,7 @@ static ssize_t srso_show_state(char *buf)  	return sysfs_emit(buf, "%s%s\n",  			  srso_strings[srso_mitigation], -			  (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); +			  boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");  }  static ssize_t gds_show_state(char *buf) diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 975f98d5eee5..97f1436c1a20 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -143,66 +143,7 @@ int paravirt_disable_iospace(void)  	return request_resource(&ioport_resource, &reserve_ioports);  } -static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LAZY_NONE; - -static inline void enter_lazy(enum paravirt_lazy_mode mode) -{ -	BUG_ON(this_cpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); - -	this_cpu_write(paravirt_lazy_mode, mode); -} - -static void leave_lazy(enum paravirt_lazy_mode mode) -{ -	BUG_ON(this_cpu_read(paravirt_lazy_mode) != mode); - -	this_cpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE); -} - -void paravirt_enter_lazy_mmu(void) -{ -	enter_lazy(PARAVIRT_LAZY_MMU); -} - -void paravirt_leave_lazy_mmu(void) -{ -	leave_lazy(PARAVIRT_LAZY_MMU); -} - -void paravirt_flush_lazy_mmu(void) -{ -	preempt_disable(); - -	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { -		arch_leave_lazy_mmu_mode(); -		arch_enter_lazy_mmu_mode(); -	} - -	preempt_enable(); -} -  #ifdef CONFIG_PARAVIRT_XXL -void paravirt_start_context_switch(struct task_struct *prev) -{ -	BUG_ON(preemptible()); - -	if (this_cpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) { -		arch_leave_lazy_mmu_mode(); -		set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES); -	} -	enter_lazy(PARAVIRT_LAZY_CPU); -} - -void paravirt_end_context_switch(struct task_struct *next) -{ -	BUG_ON(preemptible()); - -	leave_lazy(PARAVIRT_LAZY_CPU); - -	if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) -		arch_enter_lazy_mmu_mode(); -} -  static noinstr void pv_native_write_cr2(unsigned long val)  {  	native_write_cr2(val); @@ -229,14 +170,6 @@ static noinstr void pv_native_safe_halt(void)  }  #endif -enum paravirt_lazy_mode paravirt_get_lazy_mode(void) -{ -	if (in_interrupt()) -		return PARAVIRT_LAZY_NONE; - -	return this_cpu_read(paravirt_lazy_mode); -} -  struct pv_info pv_info = {  	.name = "bare hardware",  #ifdef CONFIG_PARAVIRT_XXL diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 9f0909142a0a..b6f4e8399fca 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -257,13 +257,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)  	if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP)))  		io_bitmap_share(p); -	/* -	 * If copy_thread() if failing, don't leak the shadow stack possibly -	 * allocated in shstk_alloc_thread_stack() above. -	 */ -	if (ret) -		shstk_free(p); -  	return ret;  } diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index b9145a63da77..b098b1fa2470 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -358,15 +358,11 @@ static void __init add_early_ima_buffer(u64 phys_addr)  #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE)  int __init ima_free_kexec_buffer(void)  { -	int rc; -  	if (!ima_kexec_buffer_size)  		return -ENOENT; -	rc = memblock_phys_free(ima_kexec_buffer_phys, -				ima_kexec_buffer_size); -	if (rc) -		return rc; +	memblock_free_late(ima_kexec_buffer_phys, +			   ima_kexec_buffer_size);  	ima_kexec_buffer_phys = 0;  	ima_kexec_buffer_size = 0; diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c index fd689921a1db..59e15dd8d0f8 100644 --- a/arch/x86/kernel/shstk.c +++ b/arch/x86/kernel/shstk.c @@ -205,10 +205,21 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long cl  		return 0;  	/* -	 * For CLONE_VM, except vfork, the child needs a separate shadow +	 * For CLONE_VFORK the child will share the parents shadow stack. +	 * Make sure to clear the internal tracking of the thread shadow +	 * stack so the freeing logic run for child knows to leave it alone. +	 */ +	if (clone_flags & CLONE_VFORK) { +		shstk->base = 0; +		shstk->size = 0; +		return 0; +	} + +	/* +	 * For !CLONE_VM the child will use a copy of the parents shadow  	 * stack.  	 */ -	if ((clone_flags & (CLONE_VFORK | CLONE_VM)) != CLONE_VM) +	if (!(clone_flags & CLONE_VM))  		return 0;  	size = adjust_shstk_size(stack_size); @@ -408,7 +419,25 @@ void shstk_free(struct task_struct *tsk)  	if (!tsk->mm || tsk->mm != current->mm)  		return; +	/* +	 * If shstk->base is NULL, then this task is not managing its +	 * own shadow stack (CLONE_VFORK). So skip freeing it. +	 */ +	if (!shstk->base) +		return; + +	/* +	 * shstk->base is NULL for CLONE_VFORK child tasks, and so is +	 * normal. But size = 0 on a shstk->base is not normal and +	 * indicated an attempt to free the thread shadow stack twice. +	 * Warn about it. +	 */ +	if (WARN_ON(!shstk->size)) +		return; +  	unmap_shadow_stack(shstk->base, shstk->size); + +	shstk->size = 0;  }  static int wrss_control(bool enable) diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index 8f95fb267caa..76697df8dfd5 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S @@ -40,7 +40,7 @@ SYM_TYPED_FUNC_START(__memcpy)  SYM_FUNC_END(__memcpy)  EXPORT_SYMBOL(__memcpy) -SYM_FUNC_ALIAS(memcpy, __memcpy) +SYM_FUNC_ALIAS_MEMFUNC(memcpy, __memcpy)  EXPORT_SYMBOL(memcpy)  SYM_FUNC_START_LOCAL(memcpy_orig) diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S index 0559b206fb11..ccdf3a597045 100644 --- a/arch/x86/lib/memmove_64.S +++ b/arch/x86/lib/memmove_64.S @@ -212,5 +212,5 @@ SYM_FUNC_START(__memmove)  SYM_FUNC_END(__memmove)  EXPORT_SYMBOL(__memmove) -SYM_FUNC_ALIAS(memmove, __memmove) +SYM_FUNC_ALIAS_MEMFUNC(memmove, __memmove)  EXPORT_SYMBOL(memmove) diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index 7c59a704c458..3d818b849ec6 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S @@ -40,7 +40,7 @@ SYM_FUNC_START(__memset)  SYM_FUNC_END(__memset)  EXPORT_SYMBOL(__memset) -SYM_FUNC_ALIAS(memset, __memset) +SYM_FUNC_ALIAS_MEMFUNC(memset, __memset)  EXPORT_SYMBOL(memset)  SYM_FUNC_START_LOCAL(memset_orig) diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c index 863d0d6b3edc..7250d0e0e1a9 100644 --- a/arch/x86/xen/efi.c +++ b/arch/x86/xen/efi.c @@ -138,7 +138,7 @@ void __init xen_efi_init(struct boot_params *boot_params)  	if (efi_systab_xen == NULL)  		return; -	strncpy((char *)&boot_params->efi_info.efi_loader_signature, "Xen", +	strscpy((char *)&boot_params->efi_info.efi_loader_signature, "Xen",  			sizeof(boot_params->efi_info.efi_loader_signature));  	boot_params->efi_info.efi_systab = (__u32)__pa(efi_systab_xen);  	boot_params->efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32); diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index b8db2148c07d..0337392a3121 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(hypercall_page);   * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info   * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info   * but during boot it is switched to point to xen_vcpu_info. - * The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events. + * The pointer is used in xen_evtchn_do_upcall to acknowledge pending events.   */  DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);  DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 9a192f51f1b0..3f8c34707c50 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c @@ -136,7 +136,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback)  	inc_irq_stat(irq_hv_callback_count); -	xen_hvm_evtchn_do_upcall(); +	xen_evtchn_do_upcall();  	set_irq_regs(old_regs);  } diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 49352fad7d1d..bbbfdd495ebd 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -101,6 +101,17 @@ struct tls_descs {  	struct desc_struct desc[3];  }; +DEFINE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode) = XEN_LAZY_NONE; +DEFINE_PER_CPU(unsigned int, xen_lazy_nesting); + +enum xen_lazy_mode xen_get_lazy_mode(void) +{ +	if (in_interrupt()) +		return XEN_LAZY_NONE; + +	return this_cpu_read(xen_lazy_mode); +} +  /*   * Updating the 3 TLS descriptors in the GDT on every task switch is   * surprisingly expensive so we avoid updating them if they haven't @@ -362,10 +373,25 @@ static noinstr unsigned long xen_get_debugreg(int reg)  	return HYPERVISOR_get_debugreg(reg);  } +static void xen_start_context_switch(struct task_struct *prev) +{ +	BUG_ON(preemptible()); + +	if (this_cpu_read(xen_lazy_mode) == XEN_LAZY_MMU) { +		arch_leave_lazy_mmu_mode(); +		set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES); +	} +	enter_lazy(XEN_LAZY_CPU); +} +  static void xen_end_context_switch(struct task_struct *next)  { +	BUG_ON(preemptible()); +  	xen_mc_flush(); -	paravirt_end_context_switch(next); +	leave_lazy(XEN_LAZY_CPU); +	if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) +		arch_enter_lazy_mmu_mode();  }  static unsigned long xen_store_tr(void) @@ -472,7 +498,7 @@ static void xen_set_ldt(const void *addr, unsigned entries)  	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); -	xen_mc_issue(PARAVIRT_LAZY_CPU); +	xen_mc_issue(XEN_LAZY_CPU);  }  static void xen_load_gdt(const struct desc_ptr *dtr) @@ -568,7 +594,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)  	 * exception between the new %fs descriptor being loaded and  	 * %fs being effectively cleared at __switch_to().  	 */ -	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) +	if (xen_get_lazy_mode() == XEN_LAZY_CPU)  		loadsegment(fs, 0);  	xen_mc_batch(); @@ -577,7 +603,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)  	load_TLS_descriptor(t, cpu, 1);  	load_TLS_descriptor(t, cpu, 2); -	xen_mc_issue(PARAVIRT_LAZY_CPU); +	xen_mc_issue(XEN_LAZY_CPU);  }  static void xen_load_gs_index(unsigned int idx) @@ -909,7 +935,7 @@ static void xen_load_sp0(unsigned long sp0)  	mcs = xen_mc_entry(0);  	MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0); -	xen_mc_issue(PARAVIRT_LAZY_CPU); +	xen_mc_issue(XEN_LAZY_CPU);  	this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0);  } @@ -973,7 +999,7 @@ static void xen_write_cr0(unsigned long cr0)  	MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0); -	xen_mc_issue(PARAVIRT_LAZY_CPU); +	xen_mc_issue(XEN_LAZY_CPU);  }  static void xen_write_cr4(unsigned long cr4) @@ -1156,7 +1182,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {  #endif  		.io_delay = xen_io_delay, -		.start_context_switch = paravirt_start_context_switch, +		.start_context_switch = xen_start_context_switch,  		.end_context_switch = xen_end_context_switch,  	},  }; diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 1652c39e3dfb..b6830554ff69 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c @@ -236,7 +236,7 @@ static void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val)  	u.val = pmd_val_ma(val);  	xen_extend_mmu_update(&u); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	preempt_enable();  } @@ -270,7 +270,7 @@ static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval)  {  	struct mmu_update u; -	if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) +	if (xen_get_lazy_mode() != XEN_LAZY_MMU)  		return false;  	xen_mc_batch(); @@ -279,7 +279,7 @@ static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval)  	u.val = pte_val_ma(pteval);  	xen_extend_mmu_update(&u); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	return true;  } @@ -325,7 +325,7 @@ void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,  	u.val = pte_val_ma(pte);  	xen_extend_mmu_update(&u); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  }  /* Assume pteval_t is equivalent to all the other *val_t types. */ @@ -419,7 +419,7 @@ static void xen_set_pud_hyper(pud_t *ptr, pud_t val)  	u.val = pud_val_ma(val);  	xen_extend_mmu_update(&u); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	preempt_enable();  } @@ -499,7 +499,7 @@ static void __init xen_set_p4d_hyper(p4d_t *ptr, p4d_t val)  	__xen_set_p4d_hyper(ptr, val); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	preempt_enable();  } @@ -531,7 +531,7 @@ static void xen_set_p4d(p4d_t *ptr, p4d_t val)  	if (user_ptr)  		__xen_set_p4d_hyper((p4d_t *)user_ptr, val); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  }  #if CONFIG_PGTABLE_LEVELS >= 5 @@ -1245,7 +1245,7 @@ static noinline void xen_flush_tlb(void)  	op->cmd = MMUEXT_TLB_FLUSH_LOCAL;  	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	preempt_enable();  } @@ -1265,7 +1265,7 @@ static void xen_flush_tlb_one_user(unsigned long addr)  	op->arg1.linear_addr = addr & PAGE_MASK;  	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	preempt_enable();  } @@ -1302,7 +1302,7 @@ static void xen_flush_tlb_multi(const struct cpumask *cpus,  	MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  }  static unsigned long xen_read_cr3(void) @@ -1361,7 +1361,7 @@ static void xen_write_cr3(unsigned long cr3)  	else  		__xen_write_cr3(false, 0); -	xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */ +	xen_mc_issue(XEN_LAZY_CPU);  /* interrupts restored */  }  /* @@ -1396,7 +1396,7 @@ static void __init xen_write_cr3_init(unsigned long cr3)  	__xen_write_cr3(true, cr3); -	xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */ +	xen_mc_issue(XEN_LAZY_CPU);  /* interrupts restored */  }  static int xen_pgd_alloc(struct mm_struct *mm) @@ -1557,7 +1557,7 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn,  		if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned)  			__pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); -		xen_mc_issue(PARAVIRT_LAZY_MMU); +		xen_mc_issue(XEN_LAZY_MMU);  	}  } @@ -1587,7 +1587,7 @@ static inline void xen_release_ptpage(unsigned long pfn, unsigned level)  		__set_pfn_prot(pfn, PAGE_KERNEL); -		xen_mc_issue(PARAVIRT_LAZY_MMU); +		xen_mc_issue(XEN_LAZY_MMU);  		ClearPagePinned(page);  	} @@ -1804,7 +1804,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)  	 */  	xen_mc_batch();  	__xen_write_cr3(true, __pa(init_top_pgt)); -	xen_mc_issue(PARAVIRT_LAZY_CPU); +	xen_mc_issue(XEN_LAZY_CPU);  	/* We can't that easily rip out L3 and L2, as the Xen pagetables are  	 * set out this way: [L4], [L1], [L2], [L3], [L1], [L1] ...  for @@ -2083,6 +2083,23 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)  #endif  } +static void xen_enter_lazy_mmu(void) +{ +	enter_lazy(XEN_LAZY_MMU); +} + +static void xen_flush_lazy_mmu(void) +{ +	preempt_disable(); + +	if (xen_get_lazy_mode() == XEN_LAZY_MMU) { +		arch_leave_lazy_mmu_mode(); +		arch_enter_lazy_mmu_mode(); +	} + +	preempt_enable(); +} +  static void __init xen_post_allocator_init(void)  {  	pv_ops.mmu.set_pte = xen_set_pte; @@ -2107,7 +2124,7 @@ static void xen_leave_lazy_mmu(void)  {  	preempt_disable();  	xen_mc_flush(); -	paravirt_leave_lazy_mmu(); +	leave_lazy(XEN_LAZY_MMU);  	preempt_enable();  } @@ -2166,9 +2183,9 @@ static const typeof(pv_ops) xen_mmu_ops __initconst = {  		.exit_mmap = xen_exit_mmap,  		.lazy_mode = { -			.enter = paravirt_enter_lazy_mmu, +			.enter = xen_enter_lazy_mmu,  			.leave = xen_leave_lazy_mmu, -			.flush = paravirt_flush_lazy_mmu, +			.flush = xen_flush_lazy_mmu,  		},  		.set_fixmap = xen_set_fixmap, @@ -2385,7 +2402,7 @@ static noinline void xen_flush_tlb_all(void)  	op->cmd = MMUEXT_TLB_FLUSH_ALL;  	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); -	xen_mc_issue(PARAVIRT_LAZY_MMU); +	xen_mc_issue(XEN_LAZY_MMU);  	preempt_enable();  } diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h index 1c51b2c87f30..c3867b585e0d 100644 --- a/arch/x86/xen/multicalls.h +++ b/arch/x86/xen/multicalls.h @@ -26,7 +26,7 @@ static inline void xen_mc_batch(void)  	/* need to disable interrupts until this entry is complete */  	local_irq_save(flags); -	trace_xen_mc_batch(paravirt_get_lazy_mode()); +	trace_xen_mc_batch(xen_get_lazy_mode());  	__this_cpu_write(xen_mc_irq_flags, flags);  } @@ -44,7 +44,7 @@ static inline void xen_mc_issue(unsigned mode)  {  	trace_xen_mc_issue(mode); -	if ((paravirt_get_lazy_mode() & mode) == 0) +	if ((xen_get_lazy_mode() & mode) == 0)  		xen_mc_flush();  	/* restore flags saved in xen_mc_batch */ | 
