mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
Merge 3e2cbc016b ("Merge tag 'x86_splitlock_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip") into android-mainline
Steps on the way to 5.19-rc1 Resolves merge conflicts in: kernel/fork.c Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ie6468a4dcebacddea949d1ad5dfbaddea481e033
This commit is contained in:
@@ -45,14 +45,12 @@ unsigned int x86_model(unsigned int sig);
|
||||
unsigned int x86_stepping(unsigned int sig);
|
||||
#ifdef CONFIG_CPU_SUP_INTEL
|
||||
extern void __init sld_setup(struct cpuinfo_x86 *c);
|
||||
extern void switch_to_sld(unsigned long tifn);
|
||||
extern bool handle_user_split_lock(struct pt_regs *regs, long error_code);
|
||||
extern bool handle_guest_split_lock(unsigned long ip);
|
||||
extern void handle_bus_lock(struct pt_regs *regs);
|
||||
u8 get_this_hybrid_cpu_type(void);
|
||||
#else
|
||||
static inline void __init sld_setup(struct cpuinfo_x86 *c) {}
|
||||
static inline void switch_to_sld(unsigned long tifn) {}
|
||||
static inline bool handle_user_split_lock(struct pt_regs *regs, long error_code)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -92,7 +92,6 @@ struct thread_info {
|
||||
#define TIF_NOCPUID 15 /* CPUID is not accessible in userland */
|
||||
#define TIF_NOTSC 16 /* TSC is not accessible in userland */
|
||||
#define TIF_NOTIFY_SIGNAL 17 /* signal notifications exist */
|
||||
#define TIF_SLD 18 /* Restore split lock detection on context switch */
|
||||
#define TIF_MEMDIE 20 /* is terminating due to OOM killer */
|
||||
#define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */
|
||||
#define TIF_IO_BITMAP 22 /* uses I/O bitmap */
|
||||
@@ -116,7 +115,6 @@ struct thread_info {
|
||||
#define _TIF_NOCPUID (1 << TIF_NOCPUID)
|
||||
#define _TIF_NOTSC (1 << TIF_NOTSC)
|
||||
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
|
||||
#define _TIF_SLD (1 << TIF_SLD)
|
||||
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
|
||||
#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
|
||||
#define _TIF_SPEC_FORCE_UPDATE (1 << TIF_SPEC_FORCE_UPDATE)
|
||||
@@ -128,7 +126,7 @@ struct thread_info {
|
||||
/* flags to check in __switch_to() */
|
||||
#define _TIF_WORK_CTXSW_BASE \
|
||||
(_TIF_NOCPUID | _TIF_NOTSC | _TIF_BLOCKSTEP | \
|
||||
_TIF_SSBD | _TIF_SPEC_FORCE_UPDATE | _TIF_SLD)
|
||||
_TIF_SSBD | _TIF_SPEC_FORCE_UPDATE)
|
||||
|
||||
/*
|
||||
* Avoid calls to __switch_to_xtra() on UP as STIBP is not evaluated.
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
#include <linux/smp.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/clock.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -999,6 +1002,8 @@ static const struct {
|
||||
|
||||
static struct ratelimit_state bld_ratelimit;
|
||||
|
||||
static DEFINE_SEMAPHORE(buslock_sem);
|
||||
|
||||
static inline bool match_option(const char *arg, int arglen, const char *opt)
|
||||
{
|
||||
int len = strlen(opt), ratelimit;
|
||||
@@ -1109,18 +1114,52 @@ static void split_lock_init(void)
|
||||
split_lock_verify_msr(sld_state != sld_off);
|
||||
}
|
||||
|
||||
static void __split_lock_reenable(struct work_struct *work)
|
||||
{
|
||||
sld_update_msr(true);
|
||||
up(&buslock_sem);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a CPU goes offline with pending delayed work to re-enable split lock
|
||||
* detection then the delayed work will be executed on some other CPU. That
|
||||
* handles releasing the buslock_sem, but because it executes on a
|
||||
* different CPU probably won't re-enable split lock detection. This is a
|
||||
* problem on HT systems since the sibling CPU on the same core may then be
|
||||
* left running with split lock detection disabled.
|
||||
*
|
||||
* Unconditionally re-enable detection here.
|
||||
*/
|
||||
static int splitlock_cpu_offline(unsigned int cpu)
|
||||
{
|
||||
sld_update_msr(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DECLARE_DELAYED_WORK(split_lock_reenable, __split_lock_reenable);
|
||||
|
||||
static void split_lock_warn(unsigned long ip)
|
||||
{
|
||||
pr_warn_ratelimited("#AC: %s/%d took a split_lock trap at address: 0x%lx\n",
|
||||
current->comm, current->pid, ip);
|
||||
int cpu;
|
||||
|
||||
/*
|
||||
* Disable the split lock detection for this task so it can make
|
||||
* progress and set TIF_SLD so the detection is re-enabled via
|
||||
* switch_to_sld() when the task is scheduled out.
|
||||
*/
|
||||
if (!current->reported_split_lock)
|
||||
pr_warn_ratelimited("#AC: %s/%d took a split_lock trap at address: 0x%lx\n",
|
||||
current->comm, current->pid, ip);
|
||||
current->reported_split_lock = 1;
|
||||
|
||||
/* misery factor #1, sleep 10ms before trying to execute split lock */
|
||||
if (msleep_interruptible(10) > 0)
|
||||
return;
|
||||
/* Misery factor #2, only allow one buslocked disabled core at a time */
|
||||
if (down_interruptible(&buslock_sem) == -EINTR)
|
||||
return;
|
||||
cpu = get_cpu();
|
||||
schedule_delayed_work_on(cpu, &split_lock_reenable, 2);
|
||||
|
||||
/* Disable split lock detection on this CPU to make progress */
|
||||
sld_update_msr(false);
|
||||
set_tsk_thread_flag(current, TIF_SLD);
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
bool handle_guest_split_lock(unsigned long ip)
|
||||
@@ -1193,18 +1232,6 @@ void handle_bus_lock(struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called only when switching between tasks with
|
||||
* different split-lock detection modes. It sets the MSR for the
|
||||
* mode of the new task. This is right most of the time, but since
|
||||
* the MSR is shared by hyperthreads on a physical core there can
|
||||
* be glitches when the two threads need different modes.
|
||||
*/
|
||||
void switch_to_sld(unsigned long tifn)
|
||||
{
|
||||
sld_update_msr(!(tifn & _TIF_SLD));
|
||||
}
|
||||
|
||||
/*
|
||||
* Bits in the IA32_CORE_CAPABILITIES are not architectural, so they should
|
||||
* only be trusted if it is confirmed that a CPU model implements a
|
||||
@@ -1230,6 +1257,7 @@ static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 1),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, 1),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 1),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, 1),
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1274,10 +1302,14 @@ static void sld_state_show(void)
|
||||
pr_info("disabled\n");
|
||||
break;
|
||||
case sld_warn:
|
||||
if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
|
||||
if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
|
||||
pr_info("#AC: crashing the kernel on kernel split_locks and warning on user-space split_locks\n");
|
||||
else if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
|
||||
if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
|
||||
"x86/splitlock", NULL, splitlock_cpu_offline) < 0)
|
||||
pr_warn("No splitlock CPU offline handler\n");
|
||||
} else if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT)) {
|
||||
pr_info("#DB: warning on user-space bus_locks\n");
|
||||
}
|
||||
break;
|
||||
case sld_fatal:
|
||||
if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
|
||||
|
||||
@@ -684,9 +684,6 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
|
||||
/* Enforce MSR update to ensure consistent state */
|
||||
__speculation_ctrl_update(~tifn, tifn);
|
||||
}
|
||||
|
||||
if ((tifp ^ tifn) & _TIF_SLD)
|
||||
switch_to_sld(tifn);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -942,6 +942,9 @@ struct task_struct {
|
||||
#ifdef CONFIG_IOMMU_SVA
|
||||
unsigned pasid_activated:1;
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_SUP_INTEL
|
||||
unsigned reported_split_lock:1;
|
||||
#endif
|
||||
|
||||
unsigned long atomic_flags; /* Flags requiring atomic access. */
|
||||
|
||||
|
||||
@@ -1054,8 +1054,14 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
|
||||
#ifdef CONFIG_MEMCG
|
||||
tsk->active_memcg = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_SUP_INTEL
|
||||
tsk->reported_split_lock = 0;
|
||||
#endif
|
||||
|
||||
memset(&tsk->android_vendor_data1, 0, sizeof(tsk->android_vendor_data1));
|
||||
memset(&tsk->android_oem_data1, 0, sizeof(tsk->android_oem_data1));
|
||||
|
||||
return tsk;
|
||||
|
||||
free_stack:
|
||||
|
||||
Reference in New Issue
Block a user