Patchwork [v5,13/18] x86/split_lock: Add a sysfs interface to allow user to enable or disable split lock detection on all CPUs during run time

login
register
mail settings
Submitter Fenghua Yu
Date March 12, 2019, 11 p.m.
Message ID <1552431636-31511-14-git-send-email-fenghua.yu@intel.com>
Download mbox | patch
Permalink /patch/747765/
State New
Headers show

Comments

Fenghua Yu - March 12, 2019, 11 p.m.
The interface /sys/device/system/cpu/split_lock_detect is added
to allow user to control split lock detection and show current split
lock detection setting.

Writing 1 to the file enables split lock detection and writing 0
disables split lock detection. Split lock detection is enabled or
disabled on all CPUs.

Reading the file shows current global split lock detection setting:
disabled when 0 and enabled when 1.

Please note the interface only shows global setting. During run time,
split lock detection on one CPU may be disabled if split lock
in kernel code happens on the CPU. The interface doesn't show split
lock detection status on individual CPU. User can run rdmsr on 0x33
to check split lock detection on each CPU.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
 arch/x86/kernel/cpu/intel.c | 67 +++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)
Dave Hansen - March 12, 2019, 11:48 p.m.
On 3/12/19 4:00 PM, Fenghua Yu wrote:
> The interface /sys/device/system/cpu/split_lock_detect is added
> to allow user to control split lock detection and show current split
> lock detection setting.

Did I miss the Documentation/ for this new sysfs feature?
Fenghua Yu - March 13, 2019, 12:53 a.m.
On Tue, Mar 12, 2019 at 04:48:09PM -0700, Dave Hansen wrote:
> On 3/12/19 4:00 PM, Fenghua Yu wrote:
> > The interface /sys/device/system/cpu/split_lock_detect is added
> > to allow user to control split lock detection and show current split
> > lock detection setting.
> 
> Did I miss the Documentation/ for this new sysfs feature?

I don't have a doc for the interface.

Should I create a new file in Documentation/ or can I add the interface
doc in an existing doc file?

Thanks.

-Fenghua
Dave Hansen - March 13, 2019, 1:08 a.m.
On 3/12/19 5:53 PM, Fenghua Yu wrote:
> On Tue, Mar 12, 2019 at 04:48:09PM -0700, Dave Hansen wrote:
>> On 3/12/19 4:00 PM, Fenghua Yu wrote:
>>> The interface /sys/device/system/cpu/split_lock_detect is added
>>> to allow user to control split lock detection and show current split
>>> lock detection setting.
>> Did I miss the Documentation/ for this new sysfs feature?
> I don't have a doc for the interface.
> 
> Should I create a new file in Documentation/ or can I add the interface
> doc in an existing doc file?

I'd suggest spending a few minutes familiarizing yourself with
Documentation/.  Maybe you can even grep for some other similar files in
there and see if those are documented.

Patch

diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 561f7d50246a..1b25ff8c75eb 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -34,6 +34,7 @@ 
 #define DISABLE_SPLIT_LOCK_DETECT 0
 #define ENABLE_SPLIT_LOCK_DETECT  1
 
+static DEFINE_MUTEX(split_lock_detect_mutex);
 static int split_lock_detect_val;
 
 /*
@@ -1083,3 +1084,69 @@  void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
 		split_lock_detect_val = 1;
 	}
 }
+
+static ssize_t
+split_lock_detect_show(struct device *dev, struct device_attribute *attr,
+		       char *buf)
+{
+	return sprintf(buf, "%u\n", READ_ONCE(split_lock_detect_val));
+}
+
+static ssize_t
+split_lock_detect_store(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	u32 val, l, h;
+	int cpu, ret;
+
+	ret = kstrtou32(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val != DISABLE_SPLIT_LOCK_DETECT && val != ENABLE_SPLIT_LOCK_DETECT)
+		return -EINVAL;
+
+	/*
+	 * Since split lock could be disabled by kernel #AC handler or user
+	 * may directly change bit 29 in MSR_TEST_CTL, split lock setting on
+	 * each CPU may be different from global setting split_lock_detect_val
+	 * by now. Update MSR on each CPU, so all of CPUs will have same split
+	 * lock setting.
+	 */
+	mutex_lock(&split_lock_detect_mutex);
+
+	WRITE_ONCE(split_lock_detect_val, val);
+
+	/*
+	 * Get MSR_TEST_CTL on this CPU, assuming all CPUs have same value
+	 * in the MSR except split lock detection bit (bit 29).
+	 */
+	rdmsr(MSR_TEST_CTL, l, h);
+	l = new_sp_test_ctl_val(l);
+	/* Update the split lock detection setting on all online CPUs. */
+	for_each_online_cpu(cpu)
+		wrmsr_on_cpu(cpu, MSR_TEST_CTL, l, h);
+
+	mutex_unlock(&split_lock_detect_mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(split_lock_detect);
+
+static int __init split_lock_init(void)
+{
+	int ret;
+
+	if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
+		return -ENODEV;
+
+	ret = device_create_file(cpu_subsys.dev_root,
+				 &dev_attr_split_lock_detect);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+subsys_initcall(split_lock_init);