* [PATCH v7 01/21] x86/common: Align cpu_caps_cleared and cpu_caps_set to unsigned long
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 02/21] drivers/net/b44: Align pwol_mask to unsigned long for better performance Fenghua Yu
` (19 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
cpu_caps_cleared[] and cpu_caps_set[] may not be aligned to unsigned long.
Atomic operations (i.e. set_bit() and clear_bit()) on the bitmaps may
access two cache lines (a.k.a. split lock) and cause the CPU to do a bus
lock to block all memory accesses from other processors to ensure
atomicity.
To avoid the overall performance degradation from the bus locking, align
the two variables to unsigned long.
Defining the variables as unsigned long may also fix the issue because
they will be naturally aligned to unsigned long. But that needs additional
code changes. Adding __aligned(unsigned long) is a simpler fix.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
---
arch/x86/kernel/cpu/common.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index cb28e98a0659..3716e2bb028b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -488,8 +488,9 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)
return NULL; /* Not found */
}
-__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
-__u32 cpu_caps_set[NCAPINTS + NBUGINTS];
+/* Aligned to unsigned long to avoid split lock in atomic bitmap ops */
+__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
+__u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
void load_percpu_segment(int cpu)
{
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 02/21] drivers/net/b44: Align pwol_mask to unsigned long for better performance
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 01/21] x86/common: Align cpu_caps_cleared and cpu_caps_set to unsigned long Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 03/21] wlcore: simplify/fix/optimize reg_ch_conf_pending operations Fenghua Yu
` (18 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
From: Peter Zijlstra <peterz@infradead.org>
A bit in pwol_mask is set in b44_magic_pattern() by atomic set_bit().
But since pwol_mask is local and never exposed to concurrency, there is
no need to set bit in pwol_mask atomically.
set_bit() sets the bit in a single unsigned long location. Because
pwol_mask may not be aligned to unsigned long, the location may cross two
cache lines. On x86, accessing two cache lines in locked instruction in
set_bit() is called split locked access and can cause overall performance
degradation.
So use non atomic __set_bit() to set pwol_mask bits. __set_bit() won't hit
split lock issue on x86.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
drivers/net/ethernet/broadcom/b44.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 97ab0dd25552..5738ab963dfb 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -1520,7 +1520,7 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
memset(ppattern + offset, 0xff, magicsync);
for (j = 0; j < magicsync; j++)
- set_bit(len++, (unsigned long *) pmask);
+ __set_bit(len++, (unsigned long *)pmask);
for (j = 0; j < B44_MAX_PATTERNS; j++) {
if ((B44_PATTERN_SIZE - len) >= ETH_ALEN)
@@ -1532,7 +1532,7 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
for (k = 0; k< ethaddr_bytes; k++) {
ppattern[offset + magicsync +
(j * ETH_ALEN) + k] = macaddr[k];
- set_bit(len++, (unsigned long *) pmask);
+ __set_bit(len++, (unsigned long *)pmask);
}
}
return len - 1;
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 03/21] wlcore: simplify/fix/optimize reg_ch_conf_pending operations
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 01/21] x86/common: Align cpu_caps_cleared and cpu_caps_set to unsigned long Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 02/21] drivers/net/b44: Align pwol_mask to unsigned long for better performance Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access Fenghua Yu
` (17 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
From: Paolo Bonzini <pbonzini@redhat.com>
Bitmaps are defined on unsigned longs, so the usage of u32[2] in the
wlcore driver is incorrect. As noted by Peter Zijlstra, casting arrays
to a bitmap is incorrect for big-endian architectures.
When looking at it I observed that:
- operations on reg_ch_conf_pending is always under the wl_lock mutex,
so set_bit is overkill
- the only case where reg_ch_conf_pending is accessed a u32 at a time is
unnecessary too.
This patch cleans up everything in this area, and changes tmp_ch_bitmap
to have the proper alignment.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
drivers/net/wireless/ti/wlcore/cmd.c | 15 ++++++---------
drivers/net/wireless/ti/wlcore/wlcore.h | 4 ++--
2 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 348be0aed97e..0415a064f6e2 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1700,14 +1700,14 @@ void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
ch_bit_idx = wlcore_get_reg_conf_ch_idx(band, channel);
if (ch_bit_idx >= 0 && ch_bit_idx <= WL1271_MAX_CHANNELS)
- set_bit(ch_bit_idx, (long *)wl->reg_ch_conf_pending);
+ __set_bit_le(ch_bit_idx, (long *)wl->reg_ch_conf_pending);
}
int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
{
struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL;
int ret = 0, i, b, ch_bit_idx;
- u32 tmp_ch_bitmap[2];
+ __le32 tmp_ch_bitmap[2] __aligned(sizeof(unsigned long));
struct wiphy *wiphy = wl->hw->wiphy;
struct ieee80211_supported_band *band;
bool timeout = false;
@@ -1717,7 +1717,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
wl1271_debug(DEBUG_CMD, "cmd reg domain config");
- memset(tmp_ch_bitmap, 0, sizeof(tmp_ch_bitmap));
+ memcpy(tmp_ch_bitmap, wl->reg_ch_conf_pending, sizeof(tmp_ch_bitmap));
for (b = NL80211_BAND_2GHZ; b <= NL80211_BAND_5GHZ; b++) {
band = wiphy->bands[b];
@@ -1738,13 +1738,10 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
if (ch_bit_idx < 0)
continue;
- set_bit(ch_bit_idx, (long *)tmp_ch_bitmap);
+ __set_bit_le(ch_bit_idx, (long *)tmp_ch_bitmap);
}
}
- tmp_ch_bitmap[0] |= wl->reg_ch_conf_pending[0];
- tmp_ch_bitmap[1] |= wl->reg_ch_conf_pending[1];
-
if (!memcmp(tmp_ch_bitmap, wl->reg_ch_conf_last, sizeof(tmp_ch_bitmap)))
goto out;
@@ -1754,8 +1751,8 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
goto out;
}
- cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]);
- cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]);
+ cmd->ch_bit_map1 = tmp_ch_bitmap[0];
+ cmd->ch_bit_map2 = tmp_ch_bitmap[1];
cmd->dfs_region = wl->dfs_region;
wl1271_debug(DEBUG_CMD,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index dd14850b0603..870eea3e7a27 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -320,9 +320,9 @@ struct wl1271 {
bool watchdog_recovery;
/* Reg domain last configuration */
- u32 reg_ch_conf_last[2] __aligned(8);
+ DECLARE_BITMAP(reg_ch_conf_last, 64);
/* Reg domain pending configuration */
- u32 reg_ch_conf_pending[2];
+ DECLARE_BITMAP(reg_ch_conf_pending, 64);
/* Pointer that holds DMA-friendly block for the mailbox */
void *mbox;
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (2 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 03/21] wlcore: simplify/fix/optimize reg_ch_conf_pending operations Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-18 9:20 ` David Laight
2019-04-17 21:33 ` [PATCH v7 05/21] x86/msr-index: Define MSR_IA32_CORE_CAPABILITY and split lock detection bit Fenghua Yu
` (16 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
set_cpu_cap() calls locked BTS and clear_cpu_cap() calls locked BTR to
operate on bitmap defined in x86_capability.
Locked BTS/BTR accesses a single unsigned long location. In 64-bit mode,
the location is at:
base address of x86_capability + (bit offset in x86_capability / 64) * 8
Since base address of x86_capability may not be aligned to unsigned long,
the single unsigned long location may cross two cache lines and
accessing the location by locked BTS/BTR introductions will cause
split lock.
To fix the split lock issue, align x86_capability to size of unsigned long
so that the location will be always within one cache line.
Changing x86_capability's type to unsigned long may also fix the issue
because x86_capability will be naturally aligned to size of unsigned long.
But this needs additional code changes. So choose the simpler solution
by setting the array's alignment to size of unsigned long.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/processor.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2bb3a648fc12..7c62b9ad6e5a 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -93,7 +93,9 @@ struct cpuinfo_x86 {
__u32 extended_cpuid_level;
/* Maximum supported CPUID level, -1=no CPUID: */
int cpuid_level;
- __u32 x86_capability[NCAPINTS + NBUGINTS];
+ /* Aligned to size of unsigned long to avoid split lock in atomic ops */
+ __u32 x86_capability[NCAPINTS + NBUGINTS]
+ __aligned(sizeof(unsigned long));
char x86_vendor_id[16];
char x86_model_id[64];
/* in KB - valid for CPUS which support this call: */
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* RE: [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access
2019-04-17 21:33 ` [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access Fenghua Yu
@ 2019-04-18 9:20 ` David Laight
2019-04-18 11:08 ` David Laight
0 siblings, 1 reply; 40+ messages in thread
From: David Laight @ 2019-04-18 9:20 UTC (permalink / raw)
To: 'Fenghua Yu',
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless
From: Fenghua Yu
> Sent: 17 April 2019 22:34
>
> set_cpu_cap() calls locked BTS and clear_cpu_cap() calls locked BTR to
> operate on bitmap defined in x86_capability.
>
> Locked BTS/BTR accesses a single unsigned long location. In 64-bit mode,
> the location is at:
> base address of x86_capability + (bit offset in x86_capability / 64) * 8
>
> Since base address of x86_capability may not be aligned to unsigned long,
> the single unsigned long location may cross two cache lines and
> accessing the location by locked BTS/BTR introductions will cause
> split lock.
Isn't the problem that the type (and definition) of x86_capability[] are wrong.
If the 'bitmap' functions are used for it, it should be defined as a bitmap.
This would make it 'unsigned long' not __u32.
This type munging of bitmaps only works on LE systems.
OTOH the locked BTS/BTR instructions could be changed to use 32 bit accesses.
ISTR some of the associated functions use byte accesses.
Perhaps there ought to be asm wrappers for BTS/BTR that do 8bit and
32bit accesses.
>
> To fix the split lock issue, align x86_capability to size of unsigned long
> so that the location will be always within one cache line.
>
> Changing x86_capability's type to unsigned long may also fix the issue
> because x86_capability will be naturally aligned to size of unsigned long.
> But this needs additional code changes. So choose the simpler solution
> by setting the array's alignment to size of unsigned long.
>
> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
> ---
> arch/x86/include/asm/processor.h | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
> index 2bb3a648fc12..7c62b9ad6e5a 100644
> --- a/arch/x86/include/asm/processor.h
> +++ b/arch/x86/include/asm/processor.h
> @@ -93,7 +93,9 @@ struct cpuinfo_x86 {
> __u32 extended_cpuid_level;
> /* Maximum supported CPUID level, -1=no CPUID: */
> int cpuid_level;
> - __u32 x86_capability[NCAPINTS + NBUGINTS];
> + /* Aligned to size of unsigned long to avoid split lock in atomic ops */
> + __u32 x86_capability[NCAPINTS + NBUGINTS]
> + __aligned(sizeof(unsigned long));
> char x86_vendor_id[16];
> char x86_model_id[64];
> /* in KB - valid for CPUS which support this call: */
> --
> 2.19.1
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access
2019-04-18 9:20 ` David Laight
@ 2019-04-18 11:08 ` David Laight
2019-04-18 11:49 ` Thomas Gleixner
0 siblings, 1 reply; 40+ messages in thread
From: David Laight @ 2019-04-18 11:08 UTC (permalink / raw)
To: David Laight, 'Fenghua Yu', 'Thomas Gleixner',
'Ingo Molnar', 'Borislav Petkov',
'H Peter Anvin', 'Paolo Bonzini',
'Dave Hansen', 'Ashok Raj',
'Peter Zijlstra', 'Ravi V Shankar',
'Xiaoyao Li ', 'Christopherson Sean J',
'Kalle Valo', 'Michael Chan'
Cc: 'linux-kernel', 'x86',
'kvm@vger.kernel.org', 'netdev@vger.kernel.org',
'linux-wireless@vger.kernel.org'
From: David Laight
> Sent: 18 April 2019 10:21
> From: Fenghua Yu
> > Sent: 17 April 2019 22:34
> >
> > set_cpu_cap() calls locked BTS and clear_cpu_cap() calls locked BTR to
> > operate on bitmap defined in x86_capability.
> >
> > Locked BTS/BTR accesses a single unsigned long location. In 64-bit mode,
> > the location is at:
> > base address of x86_capability + (bit offset in x86_capability / 64) * 8
> >
> > Since base address of x86_capability may not be aligned to unsigned long,
> > the single unsigned long location may cross two cache lines and
> > accessing the location by locked BTS/BTR introductions will cause
> > split lock.
>
> Isn't the problem that the type (and definition) of x86_capability[] are wrong.
> If the 'bitmap' functions are used for it, it should be defined as a bitmap.
> This would make it 'unsigned long' not __u32.
>
> This type munging of bitmaps only works on LE systems.
>
> OTOH the locked BTS/BTR instructions could be changed to use 32 bit accesses.
> ISTR some of the associated functions use byte accesses.
>
> Perhaps there ought to be asm wrappers for BTS/BTR that do 8bit and
> 32bit accesses.
A quick look shows that this isn't the only __32[] that is being
cast to (unsigned long) and then to set/test/clear_bit() in those
files.
I wonder how much other code is applying such casts?
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access
2019-04-18 11:08 ` David Laight
@ 2019-04-18 11:49 ` Thomas Gleixner
2019-04-18 13:14 ` David Laight
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-18 11:49 UTC (permalink / raw)
To: David Laight
Cc: 'Fenghua Yu', 'Ingo Molnar',
'Borislav Petkov', 'H Peter Anvin',
'Paolo Bonzini', 'Dave Hansen',
'Ashok Raj', 'Peter Zijlstra',
'Ravi V Shankar', 'Xiaoyao Li ',
'Christopherson Sean J', 'Kalle Valo',
'Michael Chan', 'linux-kernel', 'x86',
'kvm@vger.kernel.org', 'netdev@vger.kernel.org',
'linux-wireless@vger.kernel.org'
On Thu, 18 Apr 2019, David Laight wrote:
> From: David Laight
> > Sent: 18 April 2019 10:21
> > From: Fenghua Yu
> > > Sent: 17 April 2019 22:34
> > >
> > > set_cpu_cap() calls locked BTS and clear_cpu_cap() calls locked BTR to
> > > operate on bitmap defined in x86_capability.
> > >
> > > Locked BTS/BTR accesses a single unsigned long location. In 64-bit mode,
> > > the location is at:
> > > base address of x86_capability + (bit offset in x86_capability / 64) * 8
> > >
> > > Since base address of x86_capability may not be aligned to unsigned long,
> > > the single unsigned long location may cross two cache lines and
> > > accessing the location by locked BTS/BTR introductions will cause
> > > split lock.
> >
> > Isn't the problem that the type (and definition) of x86_capability[] are wrong.
> > If the 'bitmap' functions are used for it, it should be defined as a bitmap.
> > This would make it 'unsigned long' not __u32.
> >
> > This type munging of bitmaps only works on LE systems.
> >
> > OTOH the locked BTS/BTR instructions could be changed to use 32 bit accesses.
> > ISTR some of the associated functions use byte accesses.
> >
> > Perhaps there ought to be asm wrappers for BTS/BTR that do 8bit and
> > 32bit accesses.
>
> A quick look shows that this isn't the only __32[] that is being
> cast to (unsigned long) and then to set/test/clear_bit() in those
> files.
>
> I wonder how much other code is applying such casts?
The reason for the cpuid stuff using u32 is that this is actually the width
of the information retrieved from CPUID.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access
2019-04-18 11:49 ` Thomas Gleixner
@ 2019-04-18 13:14 ` David Laight
2019-04-18 13:26 ` David Laight
0 siblings, 1 reply; 40+ messages in thread
From: David Laight @ 2019-04-18 13:14 UTC (permalink / raw)
To: 'Thomas Gleixner'
Cc: 'Fenghua Yu', 'Ingo Molnar',
'Borislav Petkov', 'H Peter Anvin',
'Paolo Bonzini', 'Dave Hansen',
'Ashok Raj', 'Peter Zijlstra',
'Ravi V Shankar', 'Xiaoyao Li ',
'Christopherson Sean J', 'Kalle Valo',
'Michael Chan', 'linux-kernel', 'x86',
'kvm@vger.kernel.org', 'netdev@vger.kernel.org',
'linux-wireless@vger.kernel.org'
From: Thomas Gleixner
> Sent: 18 April 2019 12:49
> On Thu, 18 Apr 2019, David Laight wrote:
> > From: David Laight
> > > Sent: 18 April 2019 10:21
> > > From: Fenghua Yu
> > > > Sent: 17 April 2019 22:34
> > > >
> > > > set_cpu_cap() calls locked BTS and clear_cpu_cap() calls locked BTR to
> > > > operate on bitmap defined in x86_capability.
> > > >
> > > > Locked BTS/BTR accesses a single unsigned long location. In 64-bit mode,
> > > > the location is at:
> > > > base address of x86_capability + (bit offset in x86_capability / 64) * 8
> > > >
> > > > Since base address of x86_capability may not be aligned to unsigned long,
> > > > the single unsigned long location may cross two cache lines and
> > > > accessing the location by locked BTS/BTR introductions will cause
> > > > split lock.
> > >
> > > Isn't the problem that the type (and definition) of x86_capability[] are wrong.
> > > If the 'bitmap' functions are used for it, it should be defined as a bitmap.
> > > This would make it 'unsigned long' not __u32.
> > >
> > > This type munging of bitmaps only works on LE systems.
> > >
> > > OTOH the locked BTS/BTR instructions could be changed to use 32 bit accesses.
> > > ISTR some of the associated functions use byte accesses.
> > >
> > > Perhaps there ought to be asm wrappers for BTS/BTR that do 8bit and
> > > 32bit accesses.
> >
> > A quick look shows that this isn't the only __32[] that is being
> > cast to (unsigned long) and then to set/test/clear_bit() in those
> > files.
> >
> > I wonder how much other code is applying such casts?
>
> The reason for the cpuid stuff using u32 is that this is actually the width
> of the information retrieved from CPUID.
Right, but you shouldn't (as has been found out) cast pointers
to integer types.
Running
grep -r --include '*.[ch]' '_bit([^(]*, *([^)]* ' .
over the entire kernel source tree shows quite a few 'dubious' casts.
They'll be doubly dubious on BE systems.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access
2019-04-18 13:14 ` David Laight
@ 2019-04-18 13:26 ` David Laight
0 siblings, 0 replies; 40+ messages in thread
From: David Laight @ 2019-04-18 13:26 UTC (permalink / raw)
To: David Laight, 'Thomas Gleixner'
Cc: 'Fenghua Yu', 'Ingo Molnar',
'Borislav Petkov', 'H Peter Anvin',
'Paolo Bonzini', 'Dave Hansen',
'Ashok Raj', 'Peter Zijlstra',
'Ravi V Shankar', 'Xiaoyao Li ',
'Christopherson Sean J', 'Kalle Valo',
'Michael Chan', 'linux-kernel', 'x86',
'kvm@vger.kernel.org', 'netdev@vger.kernel.org',
'linux-wireless@vger.kernel.org'
From: David Laight
> Sent: 18 April 2019 14:15
...
> Running
> grep -r --include '*.[ch]' '_bit([^(]*, *([^)]* ' .
> over the entire kernel source tree shows quite a few 'dubious' casts.
>
> They'll be doubly dubious on BE systems.
The alternate pattern:
grep -r --include '*.[ch]' '_bit([^(]*, *([^)]*\*)' .
has a few less false positives and detects some extras with (void*)&foo->bar.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v7 05/21] x86/msr-index: Define MSR_IA32_CORE_CAPABILITY and split lock detection bit
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (3 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 04/21] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 06/21] x86/cpufeatures: Enumerate MSR_IA32_CORE_CAPABILITY Fenghua Yu
` (15 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
A new MSR_IA32_CORE_CAPABILITY (0xcf) is defined. Each bit in the MSR
enumerates a model specific feature. Currently bit 5 enumerates split
lock detection. When bit 5 is 1, split lock detection is supported.
When the bit is 0, split lock detection is not supported.
Please check the latest Intel 64 and IA-32 Architectures Software
Developer's Manual for more detailed information on the MSR and the
split lock detection bit.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/msr-index.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index ca5bc0eacb95..f65ef6f783d2 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -59,6 +59,9 @@
#define MSR_PLATFORM_INFO_CPUID_FAULT_BIT 31
#define MSR_PLATFORM_INFO_CPUID_FAULT BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT)
+#define MSR_IA32_CORE_CAPABILITY 0x000000cf
+#define CORE_CAP_SPLIT_LOCK_DETECT BIT(5) /* Detect split lock */
+
#define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
#define NHM_C3_AUTO_DEMOTE (1UL << 25)
#define NHM_C1_AUTO_DEMOTE (1UL << 26)
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 06/21] x86/cpufeatures: Enumerate MSR_IA32_CORE_CAPABILITY
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (4 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 05/21] x86/msr-index: Define MSR_IA32_CORE_CAPABILITY and split lock detection bit Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 07/21] x86/split_lock: Enumerate split lock detection by MSR_IA32_CORE_CAPABILITY Fenghua Yu
` (14 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
MSR_IA32_CORE_CAPABILITY (0xcf) contains bits that enumerate some model
specific features.
The MSR 0xcf itself is enumerated by CPUID.(EAX=0x7,ECX=0):EDX[30].
When this CPUID bit is 1, the MSR 0xcf exists.
Detailed information on the CPUID bit and the MSR can be found in the
latest Intel 64 and IA-32 Architectures Software Developer's Manual.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpufeatures.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 981ff9479648..eff25e2015a5 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -350,6 +350,7 @@
#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
+#define X86_FEATURE_CORE_CAPABILITY (18*32+30) /* "" IA32_CORE_CAPABILITY MSR */
#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
/*
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 07/21] x86/split_lock: Enumerate split lock detection by MSR_IA32_CORE_CAPABILITY
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (5 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 06/21] x86/cpufeatures: Enumerate MSR_IA32_CORE_CAPABILITY Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 08/21] x86/split_lock: Enumerate split lock detection on Icelake mobile processor Fenghua Yu
` (13 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Bits in MSR_IA32_CORE_CAPABILITY enumerate a few features that are not
enumerated through CPUID. Currently bit 5 is defined to enumerate
feature of split lock detection. All other bits are reserved now.
When bit 5 is 1, the feature is supported and feature bit
X86_FEATURE_SPLIT_LOCK_DETECT is set. Otherwise, the feature is not
available.
The MSR_IA32_CORE_CAPABILITY itself is enumerated by
CPUID.(EAX=0x7,ECX=0):EDX[30].
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpu.h | 5 ++
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/kernel/cpu/common.c | 2 +
arch/x86/kernel/cpu/cpuid-deps.c | 79 +++++++++++++++---------------
arch/x86/kernel/cpu/intel.c | 21 ++++++++
5 files changed, 69 insertions(+), 39 deletions(-)
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index adc6cc86b062..4e03f53fc079 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -40,4 +40,9 @@ int mwait_usable(const struct cpuinfo_x86 *);
unsigned int x86_family(unsigned int sig);
unsigned int x86_model(unsigned int sig);
unsigned int x86_stepping(unsigned int sig);
+#ifdef CONFIG_CPU_SUP_INTEL
+void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
+#else
+static inline void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) {}
+#endif
#endif /* _ASM_X86_CPU_H */
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index eff25e2015a5..db0c1826d7ad 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -221,6 +221,7 @@
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
#define X86_FEATURE_IBRS_ENHANCED ( 7*32+30) /* Enhanced IBRS */
+#define X86_FEATURE_SPLIT_LOCK_DETECT ( 7*32+31) /* #AC for split lock */
/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 3716e2bb028b..bbdd69dd4f5f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1105,6 +1105,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
cpu_set_bug_bits(c);
+ cpu_set_core_cap_bits(c);
+
fpu__init_system(c);
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index 2c0bd38a44ab..3d633f67fbd7 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -20,45 +20,46 @@ struct cpuid_dep {
* but it's difficult to tell that to the init reference checker.
*/
static const struct cpuid_dep cpuid_deps[] = {
- { X86_FEATURE_XSAVEOPT, X86_FEATURE_XSAVE },
- { X86_FEATURE_XSAVEC, X86_FEATURE_XSAVE },
- { X86_FEATURE_XSAVES, X86_FEATURE_XSAVE },
- { X86_FEATURE_AVX, X86_FEATURE_XSAVE },
- { X86_FEATURE_PKU, X86_FEATURE_XSAVE },
- { X86_FEATURE_MPX, X86_FEATURE_XSAVE },
- { X86_FEATURE_XGETBV1, X86_FEATURE_XSAVE },
- { X86_FEATURE_FXSR_OPT, X86_FEATURE_FXSR },
- { X86_FEATURE_XMM, X86_FEATURE_FXSR },
- { X86_FEATURE_XMM2, X86_FEATURE_XMM },
- { X86_FEATURE_XMM3, X86_FEATURE_XMM2 },
- { X86_FEATURE_XMM4_1, X86_FEATURE_XMM2 },
- { X86_FEATURE_XMM4_2, X86_FEATURE_XMM2 },
- { X86_FEATURE_XMM3, X86_FEATURE_XMM2 },
- { X86_FEATURE_PCLMULQDQ, X86_FEATURE_XMM2 },
- { X86_FEATURE_SSSE3, X86_FEATURE_XMM2, },
- { X86_FEATURE_F16C, X86_FEATURE_XMM2, },
- { X86_FEATURE_AES, X86_FEATURE_XMM2 },
- { X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 },
- { X86_FEATURE_FMA, X86_FEATURE_AVX },
- { X86_FEATURE_AVX2, X86_FEATURE_AVX, },
- { X86_FEATURE_AVX512F, X86_FEATURE_AVX, },
- { X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512PF, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512ER, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512CD, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512DQ, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512BW, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL },
- { X86_FEATURE_GFNI, X86_FEATURE_AVX512VL },
- { X86_FEATURE_VAES, X86_FEATURE_AVX512VL },
- { X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX512VL },
- { X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL },
- { X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL },
- { X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512_4FMAPS, X86_FEATURE_AVX512F },
- { X86_FEATURE_AVX512_VPOPCNTDQ, X86_FEATURE_AVX512F },
+ { X86_FEATURE_XSAVEOPT, X86_FEATURE_XSAVE },
+ { X86_FEATURE_XSAVEC, X86_FEATURE_XSAVE },
+ { X86_FEATURE_XSAVES, X86_FEATURE_XSAVE },
+ { X86_FEATURE_AVX, X86_FEATURE_XSAVE },
+ { X86_FEATURE_PKU, X86_FEATURE_XSAVE },
+ { X86_FEATURE_MPX, X86_FEATURE_XSAVE },
+ { X86_FEATURE_XGETBV1, X86_FEATURE_XSAVE },
+ { X86_FEATURE_FXSR_OPT, X86_FEATURE_FXSR },
+ { X86_FEATURE_XMM, X86_FEATURE_FXSR },
+ { X86_FEATURE_XMM2, X86_FEATURE_XMM },
+ { X86_FEATURE_XMM3, X86_FEATURE_XMM2 },
+ { X86_FEATURE_XMM4_1, X86_FEATURE_XMM2 },
+ { X86_FEATURE_XMM4_2, X86_FEATURE_XMM2 },
+ { X86_FEATURE_XMM3, X86_FEATURE_XMM2 },
+ { X86_FEATURE_PCLMULQDQ, X86_FEATURE_XMM2 },
+ { X86_FEATURE_SSSE3, X86_FEATURE_XMM2, },
+ { X86_FEATURE_F16C, X86_FEATURE_XMM2, },
+ { X86_FEATURE_AES, X86_FEATURE_XMM2 },
+ { X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 },
+ { X86_FEATURE_FMA, X86_FEATURE_AVX },
+ { X86_FEATURE_AVX2, X86_FEATURE_AVX, },
+ { X86_FEATURE_AVX512F, X86_FEATURE_AVX, },
+ { X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512PF, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512ER, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512CD, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512DQ, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512BW, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL },
+ { X86_FEATURE_GFNI, X86_FEATURE_AVX512VL },
+ { X86_FEATURE_VAES, X86_FEATURE_AVX512VL },
+ { X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX512VL },
+ { X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL },
+ { X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL },
+ { X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512_4FMAPS, X86_FEATURE_AVX512F },
+ { X86_FEATURE_AVX512_VPOPCNTDQ, X86_FEATURE_AVX512F },
+ { X86_FEATURE_SPLIT_LOCK_DETECT, X86_FEATURE_CORE_CAPABILITY},
{}
};
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index fc3c07fe7df5..ad3f72d106fc 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1029,3 +1029,24 @@ static const struct cpu_dev intel_cpu_dev = {
cpu_dev_register(intel_cpu_dev);
+static void __init set_split_lock_detect(void)
+{
+ setup_force_cpu_cap(X86_FEATURE_SPLIT_LOCK_DETECT);
+}
+
+void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
+{
+ u64 ia32_core_cap = 0;
+
+ if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITY))
+ return;
+
+ /*
+ * If MSR_IA32_CORE_CAPABILITY exists, enumerate features that are
+ * reported in the MSR.
+ */
+ rdmsrl(MSR_IA32_CORE_CAPABILITY, ia32_core_cap);
+
+ if (ia32_core_cap & CORE_CAP_SPLIT_LOCK_DETECT)
+ set_split_lock_detect();
+}
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 08/21] x86/split_lock: Enumerate split lock detection on Icelake mobile processor
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (6 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 07/21] x86/split_lock: Enumerate split lock detection by MSR_IA32_CORE_CAPABILITY Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:33 ` [PATCH v7 09/21] x86/split_lock: Define MSR TEST_CTL register Fenghua Yu
` (12 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Icelake mobile processor can detect split lock operations although
the processor doesn't have MSR IA32_CORE_CAPABILITY and split lock
detection bit in the MSR. Set split lock detection feature bit
X86_FEATURE_SPLIT_LOCK_DETECT on the processor based on its
family/model/stepping.
In the future, a few other processors may also have the split lock
detection feature but don't have MSR IA32_CORE_CAPABILITY. The feature
will be enumerated on those processors once their family/model/stepping
information is released.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/kernel/cpu/intel.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index ad3f72d106fc..62f61a961eb6 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1038,8 +1038,18 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
{
u64 ia32_core_cap = 0;
- if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITY))
+ if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITY)) {
+ /*
+ * The following processors have split lock detection feature.
+ * But since they don't have MSR IA32_CORE_CAPABILITY, the
+ * feature cannot be enumerated by the MSR. So enumerate the
+ * feature by family/model/stepping.
+ */
+ if (c->x86 == 6 && c->x86_model == INTEL_FAM6_ICELAKE_MOBILE)
+ set_split_lock_detect();
+
return;
+ }
/*
* If MSR_IA32_CORE_CAPABILITY exists, enumerate features that are
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 09/21] x86/split_lock: Define MSR TEST_CTL register
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (7 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 08/21] x86/split_lock: Enumerate split lock detection on Icelake mobile processor Fenghua Yu
@ 2019-04-17 21:33 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL Fenghua Yu
` (11 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:33 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Setting bit 29 in MSR TEST_CTL (0x33) enables split lock detection and
clearing the bit disables split lock detection.
Define the MSR and the bit. The definitions will be used in enabling or
disabling split lock detection.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/msr-index.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index f65ef6f783d2..296eeb761ab6 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -39,6 +39,10 @@
/* Intel MSRs. Some also available on other CPUs */
+#define MSR_TEST_CTL 0x00000033
+#define TEST_CTL_SPLIT_LOCK_DETECT_SHIFT 29
+#define TEST_CTL_SPLIT_LOCK_DETECT BIT(29)
+
#define MSR_IA32_SPEC_CTRL 0x00000048 /* Speculation Control */
#define SPEC_CTRL_IBRS (1 << 0) /* Indirect Branch Restricted Speculation */
#define SPEC_CTRL_STIBP_SHIFT 1 /* Single Thread Indirect Branch Predictor (STIBP) bit */
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (8 preceding siblings ...)
2019-04-17 21:33 ` [PATCH v7 09/21] x86/split_lock: Define MSR TEST_CTL register Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 22:14 ` Thomas Gleixner
2019-04-17 21:34 ` [PATCH v7 11/21] x86/split_lock: Handle #AC exception for split lock Fenghua Yu
` (10 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu, Xiaoyao Li
MSR TEST_CTL (0x33) value is cached in per CPU variable msr_test_ctl_cache.
The cached value will be used in virutalization to avoid costly MSR read.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
---
arch/x86/include/asm/cpu.h | 1 +
arch/x86/kernel/cpu/intel.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 4e03f53fc079..cd7493f20234 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -40,6 +40,7 @@ int mwait_usable(const struct cpuinfo_x86 *);
unsigned int x86_family(unsigned int sig);
unsigned int x86_model(unsigned int sig);
unsigned int x86_stepping(unsigned int sig);
+DECLARE_PER_CPU(u64, msr_test_ctl_cache);
#ifdef CONFIG_CPU_SUP_INTEL
void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
#else
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 62f61a961eb6..997d683d3c27 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -31,6 +31,9 @@
#include <asm/apic.h>
#endif
+DEFINE_PER_CPU(u64, msr_test_ctl_cache);
+EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
+
/*
* Just in case our CPU detection goes bad, or you have a weird system,
* allow a way to override the automatic disabling of MPX.
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL
2019-04-17 21:34 ` [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL Fenghua Yu
@ 2019-04-17 22:14 ` Thomas Gleixner
2019-04-18 1:28 ` Fenghua Yu
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-17 22:14 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless, Xiaoyao Li
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> MSR TEST_CTL (0x33) value is cached in per CPU variable msr_test_ctl_cache.
It _is_ cached? How so?
> The cached value will be used in virutalization to avoid costly MSR read.
>
> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
> Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
That SOB chain is bogus.
> ---
> arch/x86/include/asm/cpu.h | 1 +
> arch/x86/kernel/cpu/intel.c | 3 +++
> 2 files changed, 4 insertions(+)
>
> diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
> index 4e03f53fc079..cd7493f20234 100644
> --- a/arch/x86/include/asm/cpu.h
> +++ b/arch/x86/include/asm/cpu.h
> @@ -40,6 +40,7 @@ int mwait_usable(const struct cpuinfo_x86 *);
> unsigned int x86_family(unsigned int sig);
> unsigned int x86_model(unsigned int sig);
> unsigned int x86_stepping(unsigned int sig);
> +DECLARE_PER_CPU(u64, msr_test_ctl_cache);
> #ifdef CONFIG_CPU_SUP_INTEL
> void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
> #else
> diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
> index 62f61a961eb6..997d683d3c27 100644
> --- a/arch/x86/kernel/cpu/intel.c
> +++ b/arch/x86/kernel/cpu/intel.c
> @@ -31,6 +31,9 @@
> #include <asm/apic.h>
> #endif
>
> +DEFINE_PER_CPU(u64, msr_test_ctl_cache);
> +EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
Contrary to things like cpufeatures or MSR bits, it's pretty useless to
have a separate patch for this. Please fold this into the place which
actualy uses it.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL
2019-04-17 22:14 ` Thomas Gleixner
@ 2019-04-18 1:28 ` Fenghua Yu
2019-04-18 6:31 ` Thomas Gleixner
0 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-18 1:28 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless, Xiaoyao Li
On Thu, Apr 18, 2019 at 12:14:12AM +0200, Thomas Gleixner wrote:
> On Wed, 17 Apr 2019, Fenghua Yu wrote:
>
> > MSR TEST_CTL (0x33) value is cached in per CPU variable msr_test_ctl_cache.
>
> It _is_ cached? How so?
>
> > The cached value will be used in virutalization to avoid costly MSR read.
> >
> > Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
> > Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
>
> That SOB chain is bogus.
>
> > ---
> > arch/x86/include/asm/cpu.h | 1 +
> > arch/x86/kernel/cpu/intel.c | 3 +++
> > 2 files changed, 4 insertions(+)
> >
> > diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
> > index 4e03f53fc079..cd7493f20234 100644
> > --- a/arch/x86/include/asm/cpu.h
> > +++ b/arch/x86/include/asm/cpu.h
> > @@ -40,6 +40,7 @@ int mwait_usable(const struct cpuinfo_x86 *);
> > unsigned int x86_family(unsigned int sig);
> > unsigned int x86_model(unsigned int sig);
> > unsigned int x86_stepping(unsigned int sig);
> > +DECLARE_PER_CPU(u64, msr_test_ctl_cache);
> > #ifdef CONFIG_CPU_SUP_INTEL
> > void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
> > #else
> > diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
> > index 62f61a961eb6..997d683d3c27 100644
> > --- a/arch/x86/kernel/cpu/intel.c
> > +++ b/arch/x86/kernel/cpu/intel.c
> > @@ -31,6 +31,9 @@
> > #include <asm/apic.h>
> > #endif
> >
> > +DEFINE_PER_CPU(u64, msr_test_ctl_cache);
> > +EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
>
> Contrary to things like cpufeatures or MSR bits, it's pretty useless to
> have a separate patch for this. Please fold this into the place which
> actualy uses it.
Can I fold this patch into the KVM patch 0013 which first uses (reads) the
variable? But the variable will be set in later patches when enabling split
lock feature (patch 0014) and when enabling/disabling split lock feature
(patch 0015).
Is this a right sequence to fit the variable in the patch set?
Thanks.
-Fenghua
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL
2019-04-18 1:28 ` Fenghua Yu
@ 2019-04-18 6:31 ` Thomas Gleixner
0 siblings, 0 replies; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-18 6:31 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless, Xiaoyao Li
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> On Thu, Apr 18, 2019 at 12:14:12AM +0200, Thomas Gleixner wrote:
> > On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > > +DEFINE_PER_CPU(u64, msr_test_ctl_cache);
> > > +EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
> >
> > Contrary to things like cpufeatures or MSR bits, it's pretty useless to
> > have a separate patch for this. Please fold this into the place which
> > actualy uses it.
>
> Can I fold this patch into the KVM patch 0013 which first uses (reads) the
> variable? But the variable will be set in later patches when enabling split
> lock feature (patch 0014) and when enabling/disabling split lock feature
> (patch 0015).
>
> Is this a right sequence to fit the variable in the patch set?
As I said in the other reply, you are assuming that the content of that MSR
is 0. Which might be true now, but is that true in a year from now?
So you really want to at least initialize the variable by reading the MSR
_before_ you make use of it in KVM.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v7 11/21] x86/split_lock: Handle #AC exception for split lock
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (9 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 10/21] x86/split_lock: Define per CPU variable to cache MSR TEST_CTL Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 12/21] kvm/x86: Emulate MSR IA32_CORE_CAPABILITY Fenghua Yu
` (9 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
There may be different considerations on how to handle #AC for split lock,
e.g. how to handle system hang caused by split lock issue in firmware,
how to emulate faulting instruction, etc. We use a simple method to
handle user and kernel split lock and may extend the method in the future.
When #AC exception for split lock is triggered from user process, the
process is killed by SIGBUS. To execute the process properly, a user
application developer needs to fix the split lock issue.
When #AC exception for split lock is triggered from a kernel instruction,
disable split lock detection on local CPU and warn the split lock issue.
After the exception, the faulting instruction will be executed and kernel
execution continues. Split lock detection is only disabled on the local
CPU, not globally. It will be re-enabled if the CPU is offline and then
online or through sysfs interface.
A kernel/driver developer should check the warning, which contains helpful
faulting address, context, and callstack info, and fix the split lock
issues. Then further split lock issues may be captured and fixed.
After bit 29 in MSR_TEST_CTL is set to 1 in kernel, firmware inherits
the setting when firmware is executed in S4, S5, run time services, SMI,
etc. If there is a split lock operation in firmware, it will triggers
#AC and may hang the system depending on how firmware handles the #AC.
It's up to a firmware developer to fix split lock issues in firmware.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/kernel/traps.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index d26f9e9c3d83..c776bc0a47f5 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -61,6 +61,7 @@
#include <asm/mpx.h>
#include <asm/vm86.h>
#include <asm/umip.h>
+#include <asm/cpu.h>
#ifdef CONFIG_X86_64
#include <asm/x86_init.h>
@@ -293,9 +294,41 @@ DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, 0, NULL, "coprocessor segment overru
DO_ERROR(X86_TRAP_TS, SIGSEGV, 0, NULL, "invalid TSS", invalid_TSS)
DO_ERROR(X86_TRAP_NP, SIGBUS, 0, NULL, "segment not present", segment_not_present)
DO_ERROR(X86_TRAP_SS, SIGBUS, 0, NULL, "stack segment", stack_segment)
-DO_ERROR(X86_TRAP_AC, SIGBUS, BUS_ADRALN, NULL, "alignment check", alignment_check)
#undef IP
+dotraplinkage void do_alignment_check(struct pt_regs *regs, long error_code)
+{
+ unsigned int trapnr = X86_TRAP_AC;
+ char str[] = "alignment check";
+ int signr = SIGBUS;
+
+ RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+
+ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) ==
+ NOTIFY_STOP)
+ return;
+
+ cond_local_irq_enable(regs);
+ if (!user_mode(regs) &&
+ static_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
+ /*
+ * Only split lock can generate #AC from kernel at this point.
+ * Warn and disable split lock detection on this CPU. The
+ * faulting instruction will be executed without generating
+ * another #AC fault.
+ */
+ msr_clear_bit(MSR_TEST_CTL, TEST_CTL_SPLIT_LOCK_DETECT_SHIFT);
+ this_cpu_and(msr_test_ctl_cache, ~TEST_CTL_SPLIT_LOCK_DETECT);
+ WARN_ONCE(1, "split lock operation detected\n");
+
+ return;
+ }
+
+ /* Handle #AC generated in any other cases. */
+ do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs,
+ error_code, BUS_ADRALN, NULL);
+}
+
#ifdef CONFIG_VMAP_STACK
__visible void __noreturn handle_stack_overflow(const char *message,
struct pt_regs *regs,
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 12/21] kvm/x86: Emulate MSR IA32_CORE_CAPABILITY
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (10 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 11/21] x86/split_lock: Handle #AC exception for split lock Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 13/21] kvm/vmx: Emulate MSR TEST_CTL Fenghua Yu
` (8 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Xiaoyao Li, Fenghua Yu
From: Xiaoyao Li <xiaoyao.li@linux.intel.com>
MSR IA32_CORE_CAPABILITY is a feature-enumerating MSR, bit 5 of which
reports the capability of enabling detection of split locks (will be
supported on future processors based on Tremont microarchitecture and
later).
CPUID.(EAX=7H,ECX=0):EDX[30] enumerates the presence of the
IA32_CORE_CAPABILITY MSR.
Please check the latest Intel 64 and IA-32 Architectures Software
Developer's Manual for more detailed information on the MSR and
the split lock bit.
Since MSR_IA32_CORE_CAPABILITY is a feature-enumerating MSR that plays the
similar role as CPUID, it can be emulated in software regardless of host's
capability. What we need to do is to set the right value of it to report
the capability of guest.
In this patch, just set the guest's core_capability as 0, because we
haven't added support of the features it indicates to guest. It's for
bisectability.
Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/cpuid.c | 6 ++++++
arch/x86/kvm/x86.c | 22 ++++++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a9d03af34030..d4f9b13fcdd6 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -570,6 +570,7 @@ struct kvm_vcpu_arch {
u64 ia32_xss;
u64 microcode_version;
u64 arch_capabilities;
+ u64 core_capability;
/*
* Paging state of the vcpu
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index fd3951638ae4..4a2f7892ea31 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -505,6 +505,12 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
* if the host doesn't support it.
*/
entry->edx |= F(ARCH_CAPABILITIES);
+ /*
+ * Since we emulate MSR IA32_CORE_CAPABILITY in
+ * software, we can always enable it for guest
+ * regardless of host's capability.
+ */
+ entry->edx |= F(CORE_CAPABILITY);
} else {
entry->ebx = 0;
entry->ecx = 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a0d1fc80ac5a..e88be97d47b9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1161,6 +1161,7 @@ static u32 emulated_msrs[] = {
MSR_IA32_TSC_ADJUST,
MSR_IA32_TSCDEADLINE,
MSR_IA32_ARCH_CAPABILITIES,
+ MSR_IA32_CORE_CAPABILITY,
MSR_IA32_MISC_ENABLE,
MSR_IA32_MCG_STATUS,
MSR_IA32_MCG_CTL,
@@ -1200,6 +1201,7 @@ static u32 msr_based_features[] = {
MSR_F10H_DECFG,
MSR_IA32_UCODE_REV,
+ MSR_IA32_CORE_CAPABILITY,
MSR_IA32_ARCH_CAPABILITIES,
};
@@ -1227,9 +1229,17 @@ u64 kvm_get_arch_capabilities(void)
}
EXPORT_SYMBOL_GPL(kvm_get_arch_capabilities);
+static u64 kvm_get_core_capability(void)
+{
+ return 0;
+}
+
static int kvm_get_msr_feature(struct kvm_msr_entry *msr)
{
switch (msr->index) {
+ case MSR_IA32_CORE_CAPABILITY:
+ msr->data = kvm_get_core_capability();
+ break;
case MSR_IA32_ARCH_CAPABILITIES:
msr->data = kvm_get_arch_capabilities();
break;
@@ -2453,6 +2463,11 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
break;
case MSR_EFER:
return set_efer(vcpu, data);
+ case MSR_IA32_CORE_CAPABILITY:
+ if (!msr_info->host_initiated)
+ return 1;
+ vcpu->arch.core_capability = data;
+ break;
case MSR_K7_HWCR:
data &= ~(u64)0x40; /* ignore flush filter disable */
data &= ~(u64)0x100; /* ignore ignne emulation enable */
@@ -2764,6 +2779,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_TSC:
msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset;
break;
+ case MSR_IA32_CORE_CAPABILITY:
+ if (!msr_info->host_initiated &&
+ !guest_cpuid_has(vcpu, X86_FEATURE_CORE_CAPABILITY))
+ return 1;
+ msr_info->data = vcpu->arch.core_capability;
+ break;
case MSR_MTRRcap:
case 0x200 ... 0x2ff:
return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data);
@@ -8760,6 +8781,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
{
vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
+ vcpu->arch.core_capability = kvm_get_core_capability();
vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
kvm_vcpu_mtrr_init(vcpu);
vcpu_load(vcpu);
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 13/21] kvm/vmx: Emulate MSR TEST_CTL
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (11 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 12/21] kvm/x86: Emulate MSR IA32_CORE_CAPABILITY Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 14/21] x86/split_lock: Enable split lock detection by default Fenghua Yu
` (7 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Xiaoyao Li, Fenghua Yu
From: Xiaoyao Li <xiaoyao.li@linux.intel.com>
A control bit (bit 29) in TEST_CTL MSR 0x33 will be introduced in
future x86 processors. When bit 29 is set, the processor causes #AC
exception for split locked accesses at all CPL.
Please check the latest Intel 64 and IA-32 Architectures Software
Developer's Manual for more detailed information on the MSR and
the split lock bit.
This patch emulates MSR TEST_CTL with vmx->msr_test_ctl and does the
following:
1. As MSR TEST_CTL of guest is emulated, enable the related bit
in CORE_CAPABILITY to correctly report this feature to guest.
2. Differentiate MSR TEST_CTL between host and guest.
Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/kvm/vmx/vmx.c | 42 ++++++++++++++++++++++++++++++++++++++++++
arch/x86/kvm/vmx/vmx.h | 2 ++
arch/x86/kvm/x86.c | 19 ++++++++++++++++++-
3 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index b4e7d645275a..bbb9859350b5 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1663,6 +1663,11 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
u32 index;
switch (msr_info->index) {
+ case MSR_TEST_CTL:
+ if (!vmx->msr_test_ctl_mask)
+ return 1;
+ msr_info->data = vmx->msr_test_ctl;
+ break;
#ifdef CONFIG_X86_64
case MSR_FS_BASE:
msr_info->data = vmcs_readl(GUEST_FS_BASE);
@@ -1797,6 +1802,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
u32 index;
switch (msr_index) {
+ case MSR_TEST_CTL:
+ if (!vmx->msr_test_ctl_mask ||
+ (data & vmx->msr_test_ctl_mask) != data)
+ return 1;
+ vmx->msr_test_ctl = data;
+ break;
case MSR_EFER:
ret = kvm_set_msr_common(vcpu, msr_info);
break;
@@ -4106,6 +4117,16 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx)
}
}
+static u64 vmx_get_msr_test_ctl_mask(struct kvm_vcpu *vcpu)
+{
+ u64 mask = 0;
+
+ if (vcpu->arch.core_capability & CORE_CAP_SPLIT_LOCK_DETECT)
+ mask |= TEST_CTL_SPLIT_LOCK_DETECT;
+
+ return mask;
+}
+
static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -4114,6 +4135,8 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
vmx->rmode.vm86_active = 0;
vmx->spec_ctrl = 0;
+ vmx->msr_test_ctl = 0;
+ vmx->msr_test_ctl_mask = vmx_get_msr_test_ctl_mask(vcpu);
vcpu->arch.microcode_version = 0x100000000ULL;
vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
@@ -6313,6 +6336,23 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
msrs[i].host, false);
}
+static void atomic_switch_msr_test_ctl(struct vcpu_vmx *vmx)
+{
+ u64 host_msr_test_ctl;
+
+ if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
+ return;
+
+ host_msr_test_ctl = this_cpu_read(msr_test_ctl_cache);
+
+ if (host_msr_test_ctl == vmx->msr_test_ctl) {
+ clear_atomic_switch_msr(vmx, MSR_TEST_CTL);
+ } else {
+ add_atomic_switch_msr(vmx, MSR_TEST_CTL, vmx->msr_test_ctl,
+ host_msr_test_ctl, false);
+ }
+}
+
static void vmx_arm_hv_timer(struct vcpu_vmx *vmx, u32 val)
{
vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, val);
@@ -6421,6 +6461,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
atomic_switch_perf_msrs(vmx);
+ atomic_switch_msr_test_ctl(vmx);
+
vmx_update_hv_timer(vcpu);
/*
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index f879529906b4..8690a1295548 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -190,6 +190,8 @@ struct vcpu_vmx {
u64 msr_guest_kernel_gs_base;
#endif
+ u64 msr_test_ctl;
+ u64 msr_test_ctl_mask;
u64 spec_ctrl;
u32 vm_entry_controls_shadow;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e88be97d47b9..60aaf75d0fe5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1231,7 +1231,24 @@ EXPORT_SYMBOL_GPL(kvm_get_arch_capabilities);
static u64 kvm_get_core_capability(void)
{
- return 0;
+ u64 data = 0;
+
+ if (boot_cpu_has(X86_FEATURE_CORE_CAPABILITY)) {
+ rdmsrl(MSR_IA32_CORE_CAPABILITY, data);
+
+ /* mask non-virtualizable functions */
+ data &= CORE_CAP_SPLIT_LOCK_DETECT;
+ } else if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
+ /*
+ * There will be a list of FMS values that have split lock
+ * detection but lack the CORE CAPABILITY MSR. In this case,
+ * set CORE_CAP_SPLIT_LOCK_DETECT since we emulate
+ * MSR CORE_CAPABILITY.
+ */
+ data |= CORE_CAP_SPLIT_LOCK_DETECT;
+ }
+
+ return data;
}
static int kvm_get_msr_feature(struct kvm_msr_entry *msr)
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 14/21] x86/split_lock: Enable split lock detection by default
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (12 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 13/21] kvm/vmx: Emulate MSR TEST_CTL Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 22:41 ` Thomas Gleixner
2019-04-17 21:34 ` [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time Fenghua Yu
` (6 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
A split locked access locks bus and degrades overall memory access
performance. When split lock detection feature is enumerated, enable
the feature by default to find any split lock issue.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/kernel/cpu/intel.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 997d683d3c27..6a692d215bef 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -34,6 +34,8 @@
DEFINE_PER_CPU(u64, msr_test_ctl_cache);
EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
+static bool split_lock_detect_enable;
+
/*
* Just in case our CPU detection goes bad, or you have a weird system,
* allow a way to override the automatic disabling of MPX.
@@ -164,6 +166,23 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
return false;
}
+static void split_lock_update_msr(void *__unused)
+{
+ if (split_lock_detect_enable) {
+ msr_set_bit(MSR_TEST_CTL, TEST_CTL_SPLIT_LOCK_DETECT_SHIFT);
+ this_cpu_or(msr_test_ctl_cache, TEST_CTL_SPLIT_LOCK_DETECT);
+ } else {
+ msr_clear_bit(MSR_TEST_CTL, TEST_CTL_SPLIT_LOCK_DETECT_SHIFT);
+ this_cpu_and(msr_test_ctl_cache, ~TEST_CTL_SPLIT_LOCK_DETECT);
+ }
+}
+
+static void init_split_lock_detect(struct cpuinfo_x86 *c)
+{
+ if (cpu_has(c, X86_FEATURE_SPLIT_LOCK_DETECT))
+ split_lock_update_msr(NULL);
+}
+
static void early_init_intel(struct cpuinfo_x86 *c)
{
u64 misc_enable;
@@ -661,6 +680,8 @@ static void init_intel(struct cpuinfo_x86 *c)
{
early_init_intel(c);
+ init_split_lock_detect(c);
+
intel_workarounds(c);
/*
@@ -1032,9 +1053,22 @@ static const struct cpu_dev intel_cpu_dev = {
cpu_dev_register(intel_cpu_dev);
+#undef pr_fmt
+#define pr_fmt(fmt) "x86/split lock detection: " fmt
+
+static void show_split_lock_detection_info(void)
+{
+ if (split_lock_detect_enable)
+ pr_info("enabled\n");
+ else
+ pr_info("disabled\n");
+}
+
static void __init set_split_lock_detect(void)
{
setup_force_cpu_cap(X86_FEATURE_SPLIT_LOCK_DETECT);
+ split_lock_detect_enable = true;
+ show_split_lock_detection_info();
}
void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v7 14/21] x86/split_lock: Enable split lock detection by default
2019-04-17 21:34 ` [PATCH v7 14/21] x86/split_lock: Enable split lock detection by default Fenghua Yu
@ 2019-04-17 22:41 ` Thomas Gleixner
0 siblings, 0 replies; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-17 22:41 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> A split locked access locks bus and degrades overall memory access
> performance. When split lock detection feature is enumerated, enable
> the feature by default to find any split lock issue.
>
> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
> ---
> arch/x86/kernel/cpu/intel.c | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
> index 997d683d3c27..6a692d215bef 100644
> --- a/arch/x86/kernel/cpu/intel.c
> +++ b/arch/x86/kernel/cpu/intel.c
> @@ -34,6 +34,8 @@
> DEFINE_PER_CPU(u64, msr_test_ctl_cache);
> EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
>
> +static bool split_lock_detect_enable;
> +
> /*
> * Just in case our CPU detection goes bad, or you have a weird system,
> * allow a way to override the automatic disabling of MPX.
> @@ -164,6 +166,23 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
> return false;
> }
>
> +static void split_lock_update_msr(void *__unused)
> +{
> + if (split_lock_detect_enable) {
> + msr_set_bit(MSR_TEST_CTL, TEST_CTL_SPLIT_LOCK_DETECT_SHIFT);
> + this_cpu_or(msr_test_ctl_cache, TEST_CTL_SPLIT_LOCK_DETECT);
> + } else {
> + msr_clear_bit(MSR_TEST_CTL, TEST_CTL_SPLIT_LOCK_DETECT_SHIFT);
> + this_cpu_and(msr_test_ctl_cache, ~TEST_CTL_SPLIT_LOCK_DETECT);
> + }
Nothing in this file initializes msr_test_ctl_cache explicitely. Register
caching always requires to read the register and store it in the cache
before doing anything with it. Nothing guarantees that all bits in that MSR
are 0 by default forever.
And once you do that _before_ calling split_lock_update_msr() then you can
spare the RMW in that function.
> +static void init_split_lock_detect(struct cpuinfo_x86 *c)
> +{
> + if (cpu_has(c, X86_FEATURE_SPLIT_LOCK_DETECT))
> + split_lock_update_msr(NULL);
> +}
> +
> static void early_init_intel(struct cpuinfo_x86 *c)
> {
> u64 misc_enable;
> @@ -661,6 +680,8 @@ static void init_intel(struct cpuinfo_x86 *c)
> {
> early_init_intel(c);
>
> + init_split_lock_detect(c);
Sigh. Why needs this to be squeezed in the middle of the whole enumeration
stuff? Just because....
init_intel_misc_features() is called at the end and it does also MSR
caching etc. So down there is the right place.
> +
> intel_workarounds(c);
>
> /*
> @@ -1032,9 +1053,22 @@ static const struct cpu_dev intel_cpu_dev = {
>
> cpu_dev_register(intel_cpu_dev);
>
> +#undef pr_fmt
> +#define pr_fmt(fmt) "x86/split lock detection: " fmt
> +
> +static void show_split_lock_detection_info(void)
> +{
> + if (split_lock_detect_enable)
> + pr_info("enabled\n");
> + else
> + pr_info("disabled\n");
This function is truly useful. The else path is never invoked. See the call
site below.
> +}
> +
> static void __init set_split_lock_detect(void)
> {
> setup_force_cpu_cap(X86_FEATURE_SPLIT_LOCK_DETECT);
> + split_lock_detect_enable = true;
> + show_split_lock_detection_info();
> }
Oh well.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (13 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 14/21] x86/split_lock: Enable split lock detection by default Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 22:47 ` Thomas Gleixner
2019-04-17 21:34 ` [PATCH v7 16/21] x86/split_lock: Document the new sysfs file for split lock detection Fenghua Yu
` (5 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
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 [yY1] or [oO][nN] to the file enables split lock detection and
writing [nN0] or [oO][fF] disables split lock detection. Split lock
detection is enabled or disabled on all CPUs.
Reading the file returns current global split lock detection setting:
0: disabled
1: enabled
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/kernel/cpu/intel.c | 45 +++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 6a692d215bef..f2c04aa36d78 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -34,6 +34,7 @@
DEFINE_PER_CPU(u64, msr_test_ctl_cache);
EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cache);
+static DEFINE_MUTEX(split_lock_detect_mutex);
static bool split_lock_detect_enable;
/*
@@ -1097,3 +1098,47 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
if (ia32_core_cap & CORE_CAP_SPLIT_LOCK_DETECT)
set_split_lock_detect();
}
+
+static ssize_t
+split_lock_detect_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", split_lock_detect_enable);
+}
+
+static ssize_t
+split_lock_detect_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ bool val;
+ int ret;
+
+ ret = strtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ mutex_lock(&split_lock_detect_mutex);
+
+ split_lock_detect_enable = val;
+
+ /* Update the split lock detection setting in MSR on all online CPUs. */
+ on_each_cpu(split_lock_update_msr, NULL, 1);
+
+ show_split_lock_detection_info();
+
+ mutex_unlock(&split_lock_detect_mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(split_lock_detect);
+
+static int __init split_lock_init(void)
+{
+ if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
+ return -ENODEV;
+
+ return device_create_file(cpu_subsys.dev_root,
+ &dev_attr_split_lock_detect);
+}
+subsys_initcall(split_lock_init);
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
2019-04-17 21:34 ` [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time Fenghua Yu
@ 2019-04-17 22:47 ` Thomas Gleixner
2019-04-18 0:57 ` Fenghua Yu
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-17 22:47 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Wed, 17 Apr 2019, 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.
>
> Writing [yY1] or [oO][nN] to the file enables split lock detection and
> writing [nN0] or [oO][fF] disables split lock detection. Split lock
> detection is enabled or disabled on all CPUs.
>
> Reading the file returns current global split lock detection setting:
> 0: disabled
> 1: enabled
Again, You explain WHAT this patch does and still there is zero
justification why this sysfs knob is needed at all. I still do not see any
reason why this knob should exist.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
2019-04-17 22:47 ` Thomas Gleixner
@ 2019-04-18 0:57 ` Fenghua Yu
2019-04-18 6:41 ` Thomas Gleixner
0 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-18 0:57 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Thu, Apr 18, 2019 at 12:47:24AM +0200, Thomas Gleixner wrote:
> On Wed, 17 Apr 2019, 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.
> >
> > Writing [yY1] or [oO][nN] to the file enables split lock detection and
> > writing [nN0] or [oO][fF] disables split lock detection. Split lock
> > detection is enabled or disabled on all CPUs.
> >
> > Reading the file returns current global split lock detection setting:
> > 0: disabled
> > 1: enabled
>
> Again, You explain WHAT this patch does and still there is zero
> justification why this sysfs knob is needed at all. I still do not see any
> reason why this knob should exist.
An important application has split lock issues which are already discovered
and need to be fixed. But before the issues are fixed, sysadmin still wants to
run the application without rebooting the system, the sysfs knob can be useful
to turn off split lock detection. After the application is done, split lock
detection will be enabled again through the sysfs knob.
Without the sysfs knob, sysadmin has to reboot the system with kernel option
"no_split_lock_detect" to run the application before the split lock issues
are fixed.
Is this a valid justification why the sysfs knob is needed? If it is, I can
add the justification in the next version.
Thanks.
-Fenghua
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
2019-04-18 0:57 ` Fenghua Yu
@ 2019-04-18 6:41 ` Thomas Gleixner
2019-04-23 20:48 ` Fenghua Yu
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-18 6:41 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> On Thu, Apr 18, 2019 at 12:47:24AM +0200, Thomas Gleixner wrote:
> > On Wed, 17 Apr 2019, 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.
> > >
> > > Writing [yY1] or [oO][nN] to the file enables split lock detection and
> > > writing [nN0] or [oO][fF] disables split lock detection. Split lock
> > > detection is enabled or disabled on all CPUs.
> > >
> > > Reading the file returns current global split lock detection setting:
> > > 0: disabled
> > > 1: enabled
> >
> > Again, You explain WHAT this patch does and still there is zero
> > justification why this sysfs knob is needed at all. I still do not see any
> > reason why this knob should exist.
>
> An important application has split lock issues which are already discovered
> and need to be fixed. But before the issues are fixed, sysadmin still wants to
> run the application without rebooting the system, the sysfs knob can be useful
> to turn off split lock detection. After the application is done, split lock
> detection will be enabled again through the sysfs knob.
Are you sure that you are talking about the real world? I might buy the
'off' part somehow, but the 'on' part is beyond theoretical.
Even the 'off' part is dubious on a multi user machine. I personally would
neither think about using the sysfs knob nor about rebooting the machine
simply because I'd consider a lock operation accross a cacheline an malicious
DoS attempt. Why would I allow that?
So in reality the sysadmin will either move the workload to a machine w/o
the #AC magic or just tell the user to fix his crap.
> Without the sysfs knob, sysadmin has to reboot the system with kernel option
> "no_split_lock_detect" to run the application before the split lock issues
> are fixed.
>
> Is this a valid justification why the sysfs knob is needed? If it is, I can
> add the justification in the next version.
Why has this information not been in the changelog right away? I'm really
tired of asking the same questions and pointing you to
Documentation/process over and over.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
2019-04-18 6:41 ` Thomas Gleixner
@ 2019-04-23 20:48 ` Fenghua Yu
2019-04-24 13:45 ` David Laight
0 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-23 20:48 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Thu, Apr 18, 2019 at 08:41:30AM +0200, Thomas Gleixner wrote:
> On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > On Thu, Apr 18, 2019 at 12:47:24AM +0200, Thomas Gleixner wrote:
> > > On Wed, 17 Apr 2019, 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.
> > > >
> > > > Writing [yY1] or [oO][nN] to the file enables split lock detection and
> > > > writing [nN0] or [oO][fF] disables split lock detection. Split lock
> > > > detection is enabled or disabled on all CPUs.
> > > >
> > > > Reading the file returns current global split lock detection setting:
> > > > 0: disabled
> > > > 1: enabled
> > >
> > > Again, You explain WHAT this patch does and still there is zero
> > > justification why this sysfs knob is needed at all. I still do not see any
> > > reason why this knob should exist.
> >
> > An important application has split lock issues which are already discovered
> > and need to be fixed. But before the issues are fixed, sysadmin still wants to
> > run the application without rebooting the system, the sysfs knob can be useful
> > to turn off split lock detection. After the application is done, split lock
> > detection will be enabled again through the sysfs knob.
>
> Are you sure that you are talking about the real world? I might buy the
> 'off' part somehow, but the 'on' part is beyond theoretical.
>
> Even the 'off' part is dubious on a multi user machine. I personally would
> neither think about using the sysfs knob nor about rebooting the machine
> simply because I'd consider a lock operation accross a cacheline an malicious
> DoS attempt. Why would I allow that?
>
> So in reality the sysadmin will either move the workload to a machine w/o
> the #AC magic or just tell the user to fix his crap.
>
> > Without the sysfs knob, sysadmin has to reboot the system with kernel option
> > "no_split_lock_detect" to run the application before the split lock issues
> > are fixed.
> >
> > Is this a valid justification why the sysfs knob is needed? If it is, I can
> > add the justification in the next version.
>
> Why has this information not been in the changelog right away? I'm really
> tired of asking the same questions and pointing you to
> Documentation/process over and over.
So should I remove the sysfs knob patches in the next version?
Or add the following justification and still keep the sysfs knob patches?
"To workaround or debug a split lock issue, the administrator may need to
disable or enable split lock detection during run time without rebooting
the system."
Thanks.
-Fenghua
^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
2019-04-23 20:48 ` Fenghua Yu
@ 2019-04-24 13:45 ` David Laight
0 siblings, 0 replies; 40+ messages in thread
From: David Laight @ 2019-04-24 13:45 UTC (permalink / raw)
To: 'Fenghua Yu', Thomas Gleixner
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
From: Fenghua Yu
> Sent: 23 April 2019 21:48
>
> On Thu, Apr 18, 2019 at 08:41:30AM +0200, Thomas Gleixner wrote:
> > On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > > On Thu, Apr 18, 2019 at 12:47:24AM +0200, Thomas Gleixner wrote:
> > > > On Wed, 17 Apr 2019, 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.
> > > > >
> > > > > Writing [yY1] or [oO][nN] to the file enables split lock detection and
> > > > > writing [nN0] or [oO][fF] disables split lock detection. Split lock
> > > > > detection is enabled or disabled on all CPUs.
> > > > >
> > > > > Reading the file returns current global split lock detection setting:
> > > > > 0: disabled
> > > > > 1: enabled
> > > >
> > > > Again, You explain WHAT this patch does and still there is zero
> > > > justification why this sysfs knob is needed at all. I still do not see any
> > > > reason why this knob should exist.
> > >
> > > An important application has split lock issues which are already discovered
> > > and need to be fixed. But before the issues are fixed, sysadmin still wants to
> > > run the application without rebooting the system, the sysfs knob can be useful
> > > to turn off split lock detection. After the application is done, split lock
> > > detection will be enabled again through the sysfs knob.
> >
> > Are you sure that you are talking about the real world? I might buy the
> > 'off' part somehow, but the 'on' part is beyond theoretical.
> >
> > Even the 'off' part is dubious on a multi user machine. I personally would
> > neither think about using the sysfs knob nor about rebooting the machine
> > simply because I'd consider a lock operation accross a cacheline an malicious
> > DoS attempt. Why would I allow that?
> >
> > So in reality the sysadmin will either move the workload to a machine w/o
> > the #AC magic or just tell the user to fix his crap.
> >
> > > Without the sysfs knob, sysadmin has to reboot the system with kernel option
> > > "no_split_lock_detect" to run the application before the split lock issues
> > > are fixed.
> > >
> > > Is this a valid justification why the sysfs knob is needed? If it is, I can
> > > add the justification in the next version.
> >
> > Why has this information not been in the changelog right away? I'm really
> > tired of asking the same questions and pointing you to
> > Documentation/process over and over.
>
> So should I remove the sysfs knob patches in the next version?
>
> Or add the following justification and still keep the sysfs knob patches?
> "To workaround or debug a split lock issue, the administrator may need to
> disable or enable split lock detection during run time without rebooting
> the system."
I've also not seen patches to fix all the places where 'lock bit' operations
get used on int [] data.
Testing had showed one structure that needed 'fixing', there are some others
that are in .bss/.data.
A kernel build could suddenly have them misaligned and crossing a cache line.
All the places that cast the pointer to the bit ops are suspect.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v7 16/21] x86/split_lock: Document the new sysfs file for split lock detection
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (14 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 17/21] x86/clearcpuid: Support multiple clearcpuid options Fenghua Yu
` (4 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Add an ABI document entry for /sys/devices/system/cpu/split_lock_detect.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
.../ABI/testing/sysfs-devices-system-cpu | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 9605dbd4b5b5..aad7b1698065 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -67,6 +67,28 @@ Description: Discover NUMA node a CPU belongs to
/sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
+What: /sys/devices/system/cpu/split_lock_detect
+Date: March 2019
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description: (RW) Control split lock detection on Intel Tremont and
+ future CPUs
+
+ Reads return split lock detection status:
+ 0: disabled
+ 1: enabled
+
+ Writes enable or disable split lock detection:
+ The first character is one of 'Nn0' or [oO][fF] for off
+ disables the feature.
+ The first character is one of 'Yy1' or [oO][nN] for on
+ enables the feature.
+
+ Please note the interface only shows or controls global setting.
+ During run time, split lock detection on one CPU may be
+ disabled if split lock operation in kernel code happens on
+ the CPU. The interface doesn't show or control split lock
+ detection on individual CPU.
+
What: /sys/devices/system/cpu/cpu#/topology/core_id
/sys/devices/system/cpu/cpu#/topology/core_siblings
/sys/devices/system/cpu/cpu#/topology/core_siblings_list
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 17/21] x86/clearcpuid: Support multiple clearcpuid options
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (15 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 16/21] x86/split_lock: Document the new sysfs file for split lock detection Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 23:05 ` Thomas Gleixner
2019-04-17 21:34 ` [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid Fenghua Yu
` (3 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Currently only one kernel option "clearcpuid=" can be picked up by
kernel during boot time.
In some cases, user may want to clear a few cpu caps. This may be
useful to replace endless (new) kernel options like nosmep, nosmap,
etc.
Add support of multiple clearcpuid options to allow user to clear
multiple cpu caps.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cmdline.h | 3 +++
arch/x86/kernel/fpu/init.c | 30 ++++++++++++++++++++----------
arch/x86/lib/cmdline.c | 17 +++++++++++++++--
3 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/arch/x86/include/asm/cmdline.h b/arch/x86/include/asm/cmdline.h
index 6faaf27e8899..059e29558bb3 100644
--- a/arch/x86/include/asm/cmdline.h
+++ b/arch/x86/include/asm/cmdline.h
@@ -5,5 +5,8 @@
int cmdline_find_option_bool(const char *cmdline_ptr, const char *option);
int cmdline_find_option(const char *cmdline_ptr, const char *option,
char *buffer, int bufsize);
+int cmdline_find_option_in_range(const char *cmdline_ptr, int cmdline_size,
+ const char *option, char *buffer, int bufsize,
+ char **arg_pos);
#endif /* _ASM_X86_CMDLINE_H */
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 6abd83572b01..88bbba7ee96a 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -243,16 +243,31 @@ static void __init fpu__init_system_ctx_switch(void)
WARN_ON_FPU(current->thread.fpu.initialized);
}
+static void __init clear_cpuid(void)
+{
+ char arg[32], *argptr, *option_pos, clearcpuid_option[] = "clearcpuid";
+ int bit, cmdline_size;
+
+ /* Find each option in boot_command_line and clear specified cpu cap. */
+ cmdline_size = COMMAND_LINE_SIZE;
+ while (cmdline_find_option_in_range(boot_command_line, cmdline_size,
+ clearcpuid_option, arg,
+ sizeof(arg), &option_pos) >= 0) {
+ /* Chang command line range for next search. */
+ cmdline_size = option_pos - boot_command_line + 1;
+ argptr = arg;
+ if (get_option(&argptr, &bit) &&
+ bit >= 0 && bit < NCAPINTS * 32)
+ setup_clear_cpu_cap(bit);
+ }
+}
+
/*
* We parse fpu parameters early because fpu__init_system() is executed
* before parse_early_param().
*/
static void __init fpu__init_parse_early_param(void)
{
- char arg[32];
- char *argptr = arg;
- int bit;
-
if (cmdline_find_option_bool(boot_command_line, "no387"))
setup_clear_cpu_cap(X86_FEATURE_FPU);
@@ -271,12 +286,7 @@ static void __init fpu__init_parse_early_param(void)
if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
- if (cmdline_find_option(boot_command_line, "clearcpuid", arg,
- sizeof(arg)) &&
- get_option(&argptr, &bit) &&
- bit >= 0 &&
- bit < NCAPINTS * 32)
- setup_clear_cpu_cap(bit);
+ clear_cpuid();
}
/*
diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c
index 3261abb21ef4..9cf1a0773877 100644
--- a/arch/x86/lib/cmdline.c
+++ b/arch/x86/lib/cmdline.c
@@ -114,13 +114,15 @@ __cmdline_find_option_bool(const char *cmdline, int max_cmdline_size,
* @option: option string to look for
* @buffer: memory buffer to return the option argument
* @bufsize: size of the supplied memory buffer
+ * @option_pos: pointer to the option if found
*
* Returns the length of the argument (regardless of if it was
* truncated to fit in the buffer), or -1 on not found.
*/
static int
__cmdline_find_option(const char *cmdline, int max_cmdline_size,
- const char *option, char *buffer, int bufsize)
+ const char *option, char *buffer, int bufsize,
+ char **arg_pos)
{
char c;
int pos = 0, len = -1;
@@ -164,6 +166,9 @@ __cmdline_find_option(const char *cmdline, int max_cmdline_size,
len = 0;
bufptr = buffer;
state = st_bufcpy;
+ if (arg_pos)
+ *arg_pos = (char *)cmdline -
+ strlen(option) - 1;
break;
} else if (c == *opptr++) {
/*
@@ -211,5 +216,13 @@ int cmdline_find_option(const char *cmdline, const char *option, char *buffer,
int bufsize)
{
return __cmdline_find_option(cmdline, COMMAND_LINE_SIZE, option,
- buffer, bufsize);
+ buffer, bufsize, NULL);
+}
+
+int cmdline_find_option_in_range(const char *cmdline, int cmdline_size,
+ char *option, char *buffer, int bufsize,
+ char **arg_pos)
+{
+ return __cmdline_find_option(cmdline, cmdline_size, option, buffer,
+ bufsize, arg_pos);
}
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v7 17/21] x86/clearcpuid: Support multiple clearcpuid options
2019-04-17 21:34 ` [PATCH v7 17/21] x86/clearcpuid: Support multiple clearcpuid options Fenghua Yu
@ 2019-04-17 23:05 ` Thomas Gleixner
0 siblings, 0 replies; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-17 23:05 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> int cmdline_find_option_bool(const char *cmdline_ptr, const char *option);
> int cmdline_find_option(const char *cmdline_ptr, const char *option,
> char *buffer, int bufsize);
> +int cmdline_find_option_in_range(const char *cmdline_ptr, int cmdline_size,
> + const char *option, char *buffer, int bufsize,
> + char **arg_pos);
>
> #endif /* _ASM_X86_CMDLINE_H */
> diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
> index 6abd83572b01..88bbba7ee96a 100644
> --- a/arch/x86/kernel/fpu/init.c
> +++ b/arch/x86/kernel/fpu/init.c
> @@ -243,16 +243,31 @@ static void __init fpu__init_system_ctx_switch(void)
> WARN_ON_FPU(current->thread.fpu.initialized);
> }
>
> +static void __init clear_cpuid(void)
> +{
> + char arg[32], *argptr, *option_pos, clearcpuid_option[] = "clearcpuid";
> + int bit, cmdline_size;
> +
> + /* Find each option in boot_command_line and clear specified cpu cap. */
> + cmdline_size = COMMAND_LINE_SIZE;
> + while (cmdline_find_option_in_range(boot_command_line, cmdline_size,
> + clearcpuid_option, arg,
> + sizeof(arg), &option_pos) >= 0) {
> + /* Chang command line range for next search. */
Chang?
> + cmdline_size = option_pos - boot_command_line + 1;
> + argptr = arg;
> + if (get_option(&argptr, &bit) &&
> + bit >= 0 && bit < NCAPINTS * 32)
> + setup_clear_cpu_cap(bit);
> + }
> +}
> +
> /*
> * We parse fpu parameters early because fpu__init_system() is executed
> * before parse_early_param().
> */
> static void __init fpu__init_parse_early_param(void)
> {
> - char arg[32];
> - char *argptr = arg;
> - int bit;
> -
> if (cmdline_find_option_bool(boot_command_line, "no387"))
> setup_clear_cpu_cap(X86_FEATURE_FPU);
>
> @@ -271,12 +286,7 @@ static void __init fpu__init_parse_early_param(void)
> if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
> setup_clear_cpu_cap(X86_FEATURE_XSAVES);
>
> - if (cmdline_find_option(boot_command_line, "clearcpuid", arg,
> - sizeof(arg)) &&
> - get_option(&argptr, &bit) &&
> - bit >= 0 &&
> - bit < NCAPINTS * 32)
> - setup_clear_cpu_cap(bit);
> + clear_cpuid();
I have no idea how that clearcpuid evaluation ended up in the FPU code, but
it does not belong here at all as it can turn off arbitrary cpuid bits.
Please move this out first into a more sensible place in kernel/cpu/
> }
>
> /*
> diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c
> index 3261abb21ef4..9cf1a0773877 100644
> --- a/arch/x86/lib/cmdline.c
> +++ b/arch/x86/lib/cmdline.c
> @@ -114,13 +114,15 @@ __cmdline_find_option_bool(const char *cmdline, int max_cmdline_size,
> * @option: option string to look for
> * @buffer: memory buffer to return the option argument
> * @bufsize: size of the supplied memory buffer
> + * @option_pos: pointer to the option if found
> *
> * Returns the length of the argument (regardless of if it was
> * truncated to fit in the buffer), or -1 on not found.
> */
> static int
> __cmdline_find_option(const char *cmdline, int max_cmdline_size,
> - const char *option, char *buffer, int bufsize)
> + const char *option, char *buffer, int bufsize,
> + char **arg_pos)
Bah. For a silly per cpu variable you add a separate patch, but here you do
2 things in one go:
1) Change the parser
2) Change the call site.
No, you know exactly how this should be done.
> {
> char c;
> int pos = 0, len = -1;
> @@ -164,6 +166,9 @@ __cmdline_find_option(const char *cmdline, int max_cmdline_size,
> len = 0;
> bufptr = buffer;
> state = st_bufcpy;
> + if (arg_pos)
> + *arg_pos = (char *)cmdline -
> + strlen(option) - 1;
https://marc.info/?l=linux-kernel&m=148467980905537&w=2
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (16 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 17/21] x86/clearcpuid: Support multiple clearcpuid options Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 23:19 ` Thomas Gleixner
2019-04-17 21:34 ` [PATCH v7 19/21] x86/clearcpuid: Apply cleared feature bits that are forced set before Fenghua Yu
` (2 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
The kernel option clearcpuid currently only takes feature bit which
can be changed from kernel to kernel.
Extend clearcpuid to use cap flag string, which is defined in
x86_cap_flags[] and won't be changed from kernel to kernel.
And user can easily get the cap flag string from /proc/cpuinfo.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpufeature.h | 1 +
arch/x86/kernel/cpu/cpuid-deps.c | 26 ++++++++++++++++++++++++++
arch/x86/kernel/fpu/init.c | 3 ++-
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 0e56ff7e4848..823c4ab82e12 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -133,6 +133,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
extern void setup_clear_cpu_cap(unsigned int bit);
extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
+bool find_cpu_cap(char *cap_flag, unsigned int *pfeature);
#define setup_force_cpu_cap(bit) do { \
set_cpu_cap(&boot_cpu_data, bit); \
diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index 3d633f67fbd7..1a71434f7b46 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -120,3 +120,29 @@ void setup_clear_cpu_cap(unsigned int feature)
{
do_clear_cpu_cap(NULL, feature);
}
+
+/**
+ * find_cpu_cap - Given a cap flag string, find its corresponding feature bit.
+ * @cap_flag: cap flag string as defined in x86_cap_flags[]
+ * @pfeature: feature bit
+ *
+ * Return: true if the feature is found. false if not found
+ */
+bool find_cpu_cap(char *cap_flag, unsigned int *pfeature)
+{
+#ifdef CONFIG_X86_FEATURE_NAMES
+ unsigned int feature;
+
+ for (feature = 0; feature < NCAPINTS * 32; feature++) {
+ if (!x86_cap_flags[feature])
+ continue;
+
+ if (strcmp(cap_flag, x86_cap_flags[feature]) == 0) {
+ *pfeature = feature;
+
+ return true;
+ }
+ }
+#endif
+ return false;
+}
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 88bbba7ee96a..99b895eea166 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -256,7 +256,8 @@ static void __init clear_cpuid(void)
/* Chang command line range for next search. */
cmdline_size = option_pos - boot_command_line + 1;
argptr = arg;
- if (get_option(&argptr, &bit) &&
+ /* cpu cap can be specified by either feature bit or string */
+ if ((get_option(&argptr, &bit) || find_cpu_cap(arg, &bit)) &&
bit >= 0 && bit < NCAPINTS * 32)
setup_clear_cpu_cap(bit);
}
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid
2019-04-17 21:34 ` [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid Fenghua Yu
@ 2019-04-17 23:19 ` Thomas Gleixner
2019-04-17 23:47 ` Fenghua Yu
0 siblings, 1 reply; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-17 23:19 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> The kernel option clearcpuid currently only takes feature bit which
> can be changed from kernel to kernel.
>
> Extend clearcpuid to use cap flag string, which is defined in
> x86_cap_flags[] and won't be changed from kernel to kernel.
> And user can easily get the cap flag string from /proc/cpuinfo.
If your machine dies because init triggers #AC then please explain how that
easily can be read from /proc/cpuinfo and how the sysadmin can figure out
what the heck he needs to write on the kernel command line.
The whole 'clearcpuid' thing should have never been merged. It's a pure
testing/debugging thing. And no, we are not going to proliferate it and
extend it for dubious value. Quite the contrary, we should simply rip it
out.
Add a simple 'noac' or whatever command line option, which is documented
proper and can easily be mapped to a #AC crash during boot.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid
2019-04-17 23:19 ` Thomas Gleixner
@ 2019-04-17 23:47 ` Fenghua Yu
2019-04-18 6:16 ` Thomas Gleixner
0 siblings, 1 reply; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 23:47 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Thu, Apr 18, 2019 at 01:19:41AM +0200, Thomas Gleixner wrote:
> On Wed, 17 Apr 2019, Fenghua Yu wrote:
>
> > The kernel option clearcpuid currently only takes feature bit which
> > can be changed from kernel to kernel.
> >
> > Extend clearcpuid to use cap flag string, which is defined in
> > x86_cap_flags[] and won't be changed from kernel to kernel.
> > And user can easily get the cap flag string from /proc/cpuinfo.
>
> If your machine dies because init triggers #AC then please explain how that
> easily can be read from /proc/cpuinfo and how the sysadmin can figure out
> what the heck he needs to write on the kernel command line.
>
> The whole 'clearcpuid' thing should have never been merged. It's a pure
> testing/debugging thing. And no, we are not going to proliferate it and
> extend it for dubious value. Quite the contrary, we should simply rip it
> out.
So I can remove the four 'clearcpuid' related patches 0018-0021 in the next
version, right?
>
> Add a simple 'noac' or whatever command line option, which is documented
> proper and can easily be mapped to a #AC crash during boot.
OK. I will do this.
Thanks.
-Fenghua
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid
2019-04-17 23:47 ` Fenghua Yu
@ 2019-04-18 6:16 ` Thomas Gleixner
0 siblings, 0 replies; 40+ messages in thread
From: Thomas Gleixner @ 2019-04-18 6:16 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
On Wed, 17 Apr 2019, Fenghua Yu wrote:
> On Thu, Apr 18, 2019 at 01:19:41AM +0200, Thomas Gleixner wrote:
> > On Wed, 17 Apr 2019, Fenghua Yu wrote:
> >
> > > The kernel option clearcpuid currently only takes feature bit which
> > > can be changed from kernel to kernel.
> > >
> > > Extend clearcpuid to use cap flag string, which is defined in
> > > x86_cap_flags[] and won't be changed from kernel to kernel.
> > > And user can easily get the cap flag string from /proc/cpuinfo.
> >
> > If your machine dies because init triggers #AC then please explain how that
> > easily can be read from /proc/cpuinfo and how the sysadmin can figure out
> > what the heck he needs to write on the kernel command line.
> >
> > The whole 'clearcpuid' thing should have never been merged. It's a pure
> > testing/debugging thing. And no, we are not going to proliferate it and
> > extend it for dubious value. Quite the contrary, we should simply rip it
> > out.
>
> So I can remove the four 'clearcpuid' related patches 0018-0021 in the next
> version, right?
Yes please. They are unrelated to this problem and 'noac' is way more admin
friendly than that.
Thanks,
tglx
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v7 19/21] x86/clearcpuid: Apply cleared feature bits that are forced set before
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (17 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 18/21] x86/clearcpuid: Support feature flag string in kernel option clearcpuid Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 20/21] x86/clearcpuid: Clear CPUID bit in CPUID faulting Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 21/21] x86/clearcpuid: Change document for kernel option clearcpuid Fenghua Yu
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Some CPU feature bits are forced set and stored in cpuinfo_x86 before
handling clearcpuid options. To clear those bits from cpuinfo_x86,
apply_forced_cap() is called after handling the options.
Please note, apply_forced_cap() is called twice on boot CPU. But this code
is simple and there is no functionality issue.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpu.h | 2 ++
arch/x86/kernel/cpu/common.c | 5 +++--
arch/x86/kernel/fpu/init.c | 2 ++
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index cd7493f20234..261e8ff3e2fb 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -26,6 +26,8 @@ struct x86_cpu {
struct cpu cpu;
};
+void apply_forced_caps(struct cpuinfo_x86 *c);
+
#ifdef CONFIG_HOTPLUG_CPU
extern int arch_register_cpu(int num);
extern void arch_unregister_cpu(int);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index bbdd69dd4f5f..e1d41405c27b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -758,13 +758,14 @@ void cpu_detect(struct cpuinfo_x86 *c)
}
}
-static void apply_forced_caps(struct cpuinfo_x86 *c)
+void apply_forced_caps(struct cpuinfo_x86 *c)
{
int i;
for (i = 0; i < NCAPINTS + NBUGINTS; i++) {
- c->x86_capability[i] &= ~cpu_caps_cleared[i];
+ /* Bits may be cleared after they are set. */
c->x86_capability[i] |= cpu_caps_set[i];
+ c->x86_capability[i] &= ~cpu_caps_cleared[i];
}
}
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 99b895eea166..9c2801b605e3 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -5,6 +5,7 @@
#include <asm/tlbflush.h>
#include <asm/setup.h>
#include <asm/cmdline.h>
+#include <asm/cpu.h>
#include <linux/sched.h>
#include <linux/sched/task.h>
@@ -261,6 +262,7 @@ static void __init clear_cpuid(void)
bit >= 0 && bit < NCAPINTS * 32)
setup_clear_cpu_cap(bit);
}
+ apply_forced_caps(&boot_cpu_data);
}
/*
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 20/21] x86/clearcpuid: Clear CPUID bit in CPUID faulting
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (18 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 19/21] x86/clearcpuid: Apply cleared feature bits that are forced set before Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
2019-04-17 21:34 ` [PATCH v7 21/21] x86/clearcpuid: Change document for kernel option clearcpuid Fenghua Yu
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
From: Peter Zijlstra <peterz@infradead.org>
After kernel clears a CPUID bit through clearcpuid or other kernel options,
CPUID instruction executed from user space should see the same value for
the bit. The CPUID faulting handler returns the cleared bit to user.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpufeature.h | 4 +++
arch/x86/kernel/cpu/common.c | 2 ++
arch/x86/kernel/cpu/cpuid-deps.c | 52 ++++++++++++++++++++++++++++
arch/x86/kernel/cpu/intel.c | 56 +++++++++++++++++++++++++++++--
arch/x86/kernel/cpu/scattered.c | 17 ++++++++++
arch/x86/kernel/process.c | 3 ++
arch/x86/kernel/traps.c | 11 ++++++
7 files changed, 142 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 823c4ab82e12..53875fd13f5a 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -228,5 +228,9 @@ static __always_inline __pure bool _static_cpu_has(u16 bit)
#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
boot_cpu_data.x86_model
+extern int cpuid_fault;
+u32 scattered_cpuid_mask(u32 leaf, u32 count, enum cpuid_regs_idx reg);
+u32 cpuid_cap_mask(u32 leaf, u32 count, enum cpuid_regs_idx reg);
+
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
#endif /* _ASM_X86_CPUFEATURE_H */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index e1d41405c27b..020597bca252 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1503,6 +1503,8 @@ void print_cpu_info(struct cpuinfo_x86 *c)
pr_cont(")\n");
}
+int cpuid_fault;
+
/*
* clearcpuid= was already parsed in fpu__init_parse_early_param.
* But we need to keep a dummy __setup around otherwise it would
diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index 1a71434f7b46..d42aa4fa3021 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -113,9 +113,61 @@ static void do_clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
{
+ if (boot_cpu_has(feature))
+ cpuid_fault = 1;
do_clear_cpu_cap(c, feature);
}
+u32 cpuid_cap_mask(u32 leaf, u32 count, enum cpuid_regs_idx reg)
+{
+ switch (leaf) {
+ case 0x1:
+ if (reg == CPUID_EDX)
+ return ~cpu_caps_cleared[CPUID_1_EDX];
+ if (reg == CPUID_ECX)
+ return ~cpu_caps_cleared[CPUID_1_ECX];
+ break;
+
+ case 0x6:
+ if (reg == CPUID_EAX)
+ return ~cpu_caps_cleared[CPUID_6_EAX];
+ break;
+
+ case 0x7:
+ if (reg == CPUID_EDX)
+ return ~cpu_caps_cleared[CPUID_7_EDX];
+ if (reg == CPUID_ECX)
+ return ~cpu_caps_cleared[CPUID_7_ECX];
+ if (reg == CPUID_EBX && count == 0)
+ return ~cpu_caps_cleared[CPUID_7_0_EBX];
+ break;
+
+ case 0xD:
+ if (reg == CPUID_EAX)
+ return ~cpu_caps_cleared[CPUID_D_1_EAX];
+ break;
+
+ case 0xF:
+ if (reg == CPUID_EDX) {
+ if (count == 0)
+ return ~cpu_caps_cleared[CPUID_F_0_EDX];
+ if (count == 1)
+ return ~cpu_caps_cleared[CPUID_F_0_EDX];
+ }
+ break;
+
+ case 0x80000007:
+ if (reg == CPUID_EDX) {
+ if (test_bit(X86_FEATURE_CONSTANT_TSC,
+ (unsigned long *)cpu_caps_cleared))
+ return ~(1 << 8);
+ }
+ break;
+ }
+
+ return scattered_cpuid_mask(leaf, count, reg);
+}
+
void setup_clear_cpu_cap(unsigned int feature)
{
do_clear_cpu_cap(NULL, feature);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index f2c04aa36d78..3005a1e802b7 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -19,6 +19,9 @@
#include <asm/microcode_intel.h>
#include <asm/hwcap2.h>
#include <asm/elf.h>
+#include <asm/insn.h>
+#include <asm/insn-eval.h>
+#include <asm/inat.h>
#ifdef CONFIG_X86_64
#include <linux/topology.h>
@@ -649,13 +652,60 @@ static void intel_bsp_resume(struct cpuinfo_x86 *c)
init_intel_energy_perf(c);
}
+bool fixup_cpuid_exception(struct pt_regs *regs)
+{
+ unsigned int leaf, count, eax, ebx, ecx, edx;
+ unsigned long seg_base = 0;
+ unsigned char buf[2];
+ int not_copied;
+
+ if (!cpuid_fault)
+ return false;
+
+ if (test_thread_flag(TIF_NOCPUID))
+ return false;
+
+ if (!user_64bit_mode(regs))
+ seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS);
+
+ if (seg_base == -1L)
+ return false;
+
+ not_copied = copy_from_user(buf, (void __user *)(seg_base + regs->ip),
+ sizeof(buf));
+ if (not_copied)
+ return false;
+
+ if (buf[0] != 0x0F || buf[1] != 0xA2) /* CPUID - OF A2 */
+ return false;
+
+ leaf = regs->ax;
+ count = regs->cx;
+
+ cpuid_count(leaf, count, &eax, &ebx, &ecx, &edx);
+
+ regs->ip += 2;
+ regs->ax = eax & cpuid_cap_mask(leaf, count, CPUID_EAX);
+ regs->bx = ebx & cpuid_cap_mask(leaf, count, CPUID_EBX);
+ regs->cx = ecx & cpuid_cap_mask(leaf, count, CPUID_ECX);
+ regs->dx = edx & cpuid_cap_mask(leaf, count, CPUID_EDX);
+
+ return true;
+}
+
static void init_cpuid_fault(struct cpuinfo_x86 *c)
{
u64 msr;
- if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) {
- if (msr & MSR_PLATFORM_INFO_CPUID_FAULT)
- set_cpu_cap(c, X86_FEATURE_CPUID_FAULT);
+ if (rdmsrl_safe(MSR_PLATFORM_INFO, &msr))
+ return;
+
+ if (msr & MSR_PLATFORM_INFO_CPUID_FAULT) {
+ set_cpu_cap(c, X86_FEATURE_CPUID_FAULT);
+ if (cpuid_fault) {
+ this_cpu_or(msr_misc_features_shadow,
+ MSR_MISC_FEATURES_ENABLES_CPUID_FAULT);
+ }
}
}
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 94aa1c72ca98..353756c27096 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -62,3 +62,20 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c)
set_cpu_cap(c, cb->feature);
}
}
+
+u32 scattered_cpuid_mask(u32 leaf, u32 count, enum cpuid_regs_idx reg)
+{
+ const struct cpuid_bit *cb;
+ u32 mask = ~0U;
+
+ for (cb = cpuid_bits; cb->feature; cb++) {
+ if (cb->level == leaf && cb->sub_leaf == count &&
+ cb->reg == reg) {
+ if (test_bit(cb->feature,
+ (unsigned long *)cpu_caps_cleared))
+ mask &= ~BIT(cb->bit);
+ }
+ }
+
+ return mask;
+}
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 58ac7be52c7a..2b1dfd7ae65d 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -196,6 +196,9 @@ static void set_cpuid_faulting(bool on)
{
u64 msrval;
+ if (cpuid_fault)
+ return;
+
msrval = this_cpu_read(msr_misc_features_shadow);
msrval &= ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
msrval |= (on << MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT);
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c776bc0a47f5..99e9b15c37d0 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -551,6 +551,12 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL);
}
+#ifdef CONFIG_CPU_SUP_INTEL
+extern bool fixup_cpuid_exception(struct pt_regs *regs);
+#else
+static inline bool fixup_cpuid_exception(struct pt_regs *regs) { return false; }
+#endif
+
dotraplinkage void
do_general_protection(struct pt_regs *regs, long error_code)
{
@@ -565,6 +571,11 @@ do_general_protection(struct pt_regs *regs, long error_code)
return;
}
+ if (static_cpu_has(X86_FEATURE_CPUID_FAULT)) {
+ if (user_mode(regs) && fixup_cpuid_exception(regs))
+ return;
+ }
+
if (v8086_mode(regs)) {
local_irq_enable();
handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v7 21/21] x86/clearcpuid: Change document for kernel option clearcpuid
2019-04-17 21:33 [PATCH v7 00/21] x86/split_lock: Enable split lock detection Fenghua Yu
` (19 preceding siblings ...)
2019-04-17 21:34 ` [PATCH v7 20/21] x86/clearcpuid: Clear CPUID bit in CPUID faulting Fenghua Yu
@ 2019-04-17 21:34 ` Fenghua Yu
20 siblings, 0 replies; 40+ messages in thread
From: Fenghua Yu @ 2019-04-17 21:34 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm, netdev, linux-wireless, Fenghua Yu
Since kernel option clearcpuid now supports multiple options and CPU
capability flags, the document needs to be changed.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
.../admin-guide/kernel-parameters.txt | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2b8ee90bb644..0cbeda6d7f16 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -563,17 +563,21 @@
loops can be debugged more effectively on production
systems.
- clearcpuid=BITNUM [X86]
+ clearcpuid=BITNUM | FLAG [X86]
Disable CPUID feature X for the kernel. See
arch/x86/include/asm/cpufeatures.h for the valid bit
- numbers. Note the Linux specific bits are not necessarily
+ numbers or /proc/cpuinfo for valid CPU flags.
+ Multiple options can be used to disable a few features.
+ This prevents the feature from being used by the
+ kernel or shown in /proc/cpuinfo or shown in CPUID
+ called directly by user programs.
+ A few notes:
+ - The Linux specific bits are not necessarily
stable over kernel options, but the vendor specific
ones should be.
- Also note that user programs calling CPUID directly
- or using the feature without checking anything
- will still see it. This just prevents it from
- being used by the kernel or shown in /proc/cpuinfo.
- Also note the kernel might malfunction if you disable
+ - User programs using the feature without checking
+ anything will still use it.
+ - The kernel might malfunction if you disable
some critical bits.
cma=nn[MG]@[start[MG][-end[MG]]]
--
2.19.1
^ permalink raw reply related [flat|nested] 40+ messages in thread