* Re: [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
[not found] <006001d1d5a8$dd26e1f0$9774a5d0$@alibaba-inc.com>
@ 2016-07-04 4:20 ` Hillf Danton
0 siblings, 0 replies; 8+ messages in thread
From: Hillf Danton @ 2016-07-04 4:20 UTC (permalink / raw)
To: 'Dave Hansen', Dave Hansen; +Cc: linux-kernel, linux-mm
>
> The Intel(R) Xeon Phi(TM) Processor x200 Family (codename: Knights
> Landing) has an erratum where a processor thread setting the Accessed
> or Dirty bits may not do so atomically against its checks for the
> Present bit. This may cause a thread (which is about to page fault)
> to set A and/or D, even though the Present bit had already been
> atomically cleared.
>
> If the PTE is used for storing a swap index or a NUMA migration index,
> the A bit could be misinterpreted as part of the swap type. The stray
> bits being set cause a software-cleared PTE to be interpreted as a
> swap entry. In some cases (like when the swap index ends up being
> for a non-existent swapfile), the kernel detects the stray value
> and WARN()s about it, but there is no guarantee that the kernel can
> always detect it.
>
> When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
> to move the swap PTE format around to avoid these troublesome bits.
> But, 32-bit non-PAE is tight on bits. So, disallow it from running
> on this hardware. I can't imagine anyone wanting to run 32-bit
> on this hardware, but this is the safe thing to do.
>
> ---
<jawoff>
Isn't this work from Mr. Tlb?
>
> b/arch/x86/boot/boot.h | 1 +
> b/arch/x86/boot/cpu.c | 2 ++
> b/arch/x86/boot/cpucheck.c | 32 ++++++++++++++++++++++++++++++++
> b/arch/x86/boot/cpuflags.c | 1 +
> b/arch/x86/boot/cpuflags.h | 1 +
> 5 files changed, 37 insertions(+)
>
> diff -puN arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/boot.h
> --- a/arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.302790241 -0700
> +++ b/arch/x86/boot/boot.h 2016-07-01 10:42:07.311790650 -0700
> @@ -295,6 +295,7 @@ static inline int cmdline_find_option_bo
>
> /* cpu.c, cpucheck.c */
> int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
> +int check_knl_erratum(void);
> int validate_cpu(void);
>
> /* early_serial_console.c */
> diff -puN arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpu.c
> --- a/arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.303790286 -0700
> +++ b/arch/x86/boot/cpu.c 2016-07-01 10:42:07.312790695 -0700
> @@ -93,6 +93,8 @@ int validate_cpu(void)
> show_cap_strs(err_flags);
> putchar('\n');
> return -1;
> + } else if (check_knl_erratum()) {
> + return -1;
> } else {
> return 0;
> }
> diff -puN arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpucheck.c
> --- a/arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.305790377 -0700
> +++ b/arch/x86/boot/cpucheck.c 2016-07-01 10:42:07.312790695 -0700
> @@ -24,6 +24,7 @@
> # include "boot.h"
> #endif
> #include <linux/types.h>
> +#include <asm/intel-family.h>
> #include <asm/processor-flags.h>
> #include <asm/required-features.h>
> #include <asm/msr-index.h>
> @@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *r
> puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own \
> risk!\n"); }
> }
> + if (!err)
> + err = check_knl_erratum();
>
> if (err_flags_ptr)
> *err_flags_ptr = err ? err_flags : NULL;
> @@ -185,3 +188,32 @@ int check_cpu(int *cpu_level_ptr, int *r
>
> return (cpu.level < req_level || err) ? -1 : 0;
> }
> +
> +int check_knl_erratum(void)
s/knl/xeon_knl/ ?
> +{
> + /*
> + * First check for the affected model/family:
> + */
> + if (!is_intel() ||
> + cpu.family != 6 ||
> + cpu.model != INTEL_FAM6_XEON_PHI_KNL)
> + return 0;
> +
> + /*
> + * This erratum affects the Accessed/Dirty bits, and can
> + * cause stray bits to be set in !Present PTEs. We have
> + * enough bits in our 64-bit PTEs (which we have on real
> + * 64-bit mode or PAE) to avoid using these troublesome
> + * bits. But, we do not have enough soace in our 32-bit
> + * PTEs. So, refuse to run on 32-bit non-PAE kernels.
> + */
> + if (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE))
> + return 0;
> +
> + puts("This 32-bit kernel can not run on this processor due\n"
> + "to a processor erratum. Use a 64-bit kernel, or PAE.\n\n");
Give processor name to the scared readers please.
> +
> + return -1;
> +}
> +
> +
> diff -puN arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpuflags.c
> --- a/arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.307790468 -0700
> +++ b/arch/x86/boot/cpuflags.c 2016-07-01 10:42:07.312790695 -0700
> @@ -102,6 +102,7 @@ void get_cpuflags(void)
> cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
> &cpu.flags[0]);
> cpu.level = (tfms >> 8) & 15;
> + cpu.family = cpu.level;
> cpu.model = (tfms >> 4) & 15;
> if (cpu.level >= 6)
> cpu.model += ((tfms >> 16) & 0xf) << 4;
> diff -puN arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpuflags.h
> --- a/arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.308790514 -0700
> +++ b/arch/x86/boot/cpuflags.h 2016-07-01 10:42:07.313790740 -0700
> @@ -6,6 +6,7 @@
>
> struct cpu_features {
> int level; /* Family, or 64 for x86-64 */
> + int family; /* Family, always */
> int model;
> u32 flags[NCAPINTS];
> };
> _
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
@ 2016-07-04 4:20 ` Hillf Danton
0 siblings, 0 replies; 8+ messages in thread
From: Hillf Danton @ 2016-07-04 4:20 UTC (permalink / raw)
To: 'Dave Hansen', Dave Hansen; +Cc: linux-kernel, linux-mm
>
> The Intel(R) Xeon Phi(TM) Processor x200 Family (codename: Knights
> Landing) has an erratum where a processor thread setting the Accessed
> or Dirty bits may not do so atomically against its checks for the
> Present bit. This may cause a thread (which is about to page fault)
> to set A and/or D, even though the Present bit had already been
> atomically cleared.
>
> If the PTE is used for storing a swap index or a NUMA migration index,
> the A bit could be misinterpreted as part of the swap type. The stray
> bits being set cause a software-cleared PTE to be interpreted as a
> swap entry. In some cases (like when the swap index ends up being
> for a non-existent swapfile), the kernel detects the stray value
> and WARN()s about it, but there is no guarantee that the kernel can
> always detect it.
>
> When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
> to move the swap PTE format around to avoid these troublesome bits.
> But, 32-bit non-PAE is tight on bits. So, disallow it from running
> on this hardware. I can't imagine anyone wanting to run 32-bit
> on this hardware, but this is the safe thing to do.
>
> ---
<jawoff>
Isn't this work from Mr. Tlb?
>
> b/arch/x86/boot/boot.h | 1 +
> b/arch/x86/boot/cpu.c | 2 ++
> b/arch/x86/boot/cpucheck.c | 32 ++++++++++++++++++++++++++++++++
> b/arch/x86/boot/cpuflags.c | 1 +
> b/arch/x86/boot/cpuflags.h | 1 +
> 5 files changed, 37 insertions(+)
>
> diff -puN arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/boot.h
> --- a/arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.302790241 -0700
> +++ b/arch/x86/boot/boot.h 2016-07-01 10:42:07.311790650 -0700
> @@ -295,6 +295,7 @@ static inline int cmdline_find_option_bo
>
> /* cpu.c, cpucheck.c */
> int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
> +int check_knl_erratum(void);
> int validate_cpu(void);
>
> /* early_serial_console.c */
> diff -puN arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpu.c
> --- a/arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.303790286 -0700
> +++ b/arch/x86/boot/cpu.c 2016-07-01 10:42:07.312790695 -0700
> @@ -93,6 +93,8 @@ int validate_cpu(void)
> show_cap_strs(err_flags);
> putchar('\n');
> return -1;
> + } else if (check_knl_erratum()) {
> + return -1;
> } else {
> return 0;
> }
> diff -puN arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpucheck.c
> --- a/arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.305790377 -0700
> +++ b/arch/x86/boot/cpucheck.c 2016-07-01 10:42:07.312790695 -0700
> @@ -24,6 +24,7 @@
> # include "boot.h"
> #endif
> #include <linux/types.h>
> +#include <asm/intel-family.h>
> #include <asm/processor-flags.h>
> #include <asm/required-features.h>
> #include <asm/msr-index.h>
> @@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *r
> puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own \
> risk!\n"); }
> }
> + if (!err)
> + err = check_knl_erratum();
>
> if (err_flags_ptr)
> *err_flags_ptr = err ? err_flags : NULL;
> @@ -185,3 +188,32 @@ int check_cpu(int *cpu_level_ptr, int *r
>
> return (cpu.level < req_level || err) ? -1 : 0;
> }
> +
> +int check_knl_erratum(void)
s/knl/xeon_knl/ ?
> +{
> + /*
> + * First check for the affected model/family:
> + */
> + if (!is_intel() ||
> + cpu.family != 6 ||
> + cpu.model != INTEL_FAM6_XEON_PHI_KNL)
> + return 0;
> +
> + /*
> + * This erratum affects the Accessed/Dirty bits, and can
> + * cause stray bits to be set in !Present PTEs. We have
> + * enough bits in our 64-bit PTEs (which we have on real
> + * 64-bit mode or PAE) to avoid using these troublesome
> + * bits. But, we do not have enough soace in our 32-bit
> + * PTEs. So, refuse to run on 32-bit non-PAE kernels.
> + */
> + if (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE))
> + return 0;
> +
> + puts("This 32-bit kernel can not run on this processor due\n"
> + "to a processor erratum. Use a 64-bit kernel, or PAE.\n\n");
Give processor name to the scared readers please.
> +
> + return -1;
> +}
> +
> +
> diff -puN arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpuflags.c
> --- a/arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.307790468 -0700
> +++ b/arch/x86/boot/cpuflags.c 2016-07-01 10:42:07.312790695 -0700
> @@ -102,6 +102,7 @@ void get_cpuflags(void)
> cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
> &cpu.flags[0]);
> cpu.level = (tfms >> 8) & 15;
> + cpu.family = cpu.level;
> cpu.model = (tfms >> 4) & 15;
> if (cpu.level >= 6)
> cpu.model += ((tfms >> 16) & 0xf) << 4;
> diff -puN arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL \
> arch/x86/boot/cpuflags.h
> --- a/arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 \
> 10:42:07.308790514 -0700
> +++ b/arch/x86/boot/cpuflags.h 2016-07-01 10:42:07.313790740 -0700
> @@ -6,6 +6,7 @@
>
> struct cpu_features {
> int level; /* Family, or 64 for x86-64 */
> + int family; /* Family, always */
> int model;
> u32 flags[NCAPINTS];
> };
> _
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
2016-07-04 4:20 ` Hillf Danton
@ 2016-07-06 16:02 ` Dave Hansen
-1 siblings, 0 replies; 8+ messages in thread
From: Dave Hansen @ 2016-07-06 16:02 UTC (permalink / raw)
To: Hillf Danton, Dave Hansen; +Cc: linux-kernel, linux-mm
On 07/03/2016 09:20 PM, Hillf Danton wrote:
...
>> When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
>> to move the swap PTE format around to avoid these troublesome bits.
>> But, 32-bit non-PAE is tight on bits. So, disallow it from running
>> on this hardware. I can't imagine anyone wanting to run 32-bit
>> on this hardware, but this is the safe thing to do.
>
> <jawoff>
>
> Isn't this work from Mr. Tlb?
I have no idea what you mean.
>> + if (!err)
>> + err = check_knl_erratum();
>>
>> if (err_flags_ptr)
>> *err_flags_ptr = err ? err_flags : NULL;
>> @@ -185,3 +188,32 @@ int check_cpu(int *cpu_level_ptr, int *r
>>
>> return (cpu.level < req_level || err) ? -1 : 0;
>> }
>> +
>> +int check_knl_erratum(void)
>
> s/knl/xeon_knl/ ?
Nah. I mean we could say xeon_phi_knl, but I don't think it's worth
worrying too much about a function called in one place and commented
heavily.
>> + puts("This 32-bit kernel can not run on this processor due\n"
>> + "to a processor erratum. Use a 64-bit kernel, or PAE.\n\n");
>
> Give processor name to the scared readers please.
Yeah, that's a pretty good idea. I'll be more explicit.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
@ 2016-07-06 16:02 ` Dave Hansen
0 siblings, 0 replies; 8+ messages in thread
From: Dave Hansen @ 2016-07-06 16:02 UTC (permalink / raw)
To: Hillf Danton, Dave Hansen; +Cc: linux-kernel, linux-mm
On 07/03/2016 09:20 PM, Hillf Danton wrote:
...
>> When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
>> to move the swap PTE format around to avoid these troublesome bits.
>> But, 32-bit non-PAE is tight on bits. So, disallow it from running
>> on this hardware. I can't imagine anyone wanting to run 32-bit
>> on this hardware, but this is the safe thing to do.
>
> <jawoff>
>
> Isn't this work from Mr. Tlb?
I have no idea what you mean.
>> + if (!err)
>> + err = check_knl_erratum();
>>
>> if (err_flags_ptr)
>> *err_flags_ptr = err ? err_flags : NULL;
>> @@ -185,3 +188,32 @@ int check_cpu(int *cpu_level_ptr, int *r
>>
>> return (cpu.level < req_level || err) ? -1 : 0;
>> }
>> +
>> +int check_knl_erratum(void)
>
> s/knl/xeon_knl/ ?
Nah. I mean we could say xeon_phi_knl, but I don't think it's worth
worrying too much about a function called in one place and commented
heavily.
>> + puts("This 32-bit kernel can not run on this processor due\n"
>> + "to a processor erratum. Use a 64-bit kernel, or PAE.\n\n");
>
> Give processor name to the scared readers please.
Yeah, that's a pretty good idea. I'll be more explicit.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
2016-07-08 0:19 [PATCH 0/4] [RFC][v4] Workaround for Xeon Phi PTE A/D bits erratum Dave Hansen
@ 2016-07-08 0:19 ` Dave Hansen
0 siblings, 0 replies; 8+ messages in thread
From: Dave Hansen @ 2016-07-08 0:19 UTC (permalink / raw)
To: linux-kernel
Cc: x86, linux-mm, torvalds, akpm, bp, ak, mhocko, dave.hansen,
Dave Hansen, dave.hansen
From: Dave Hansen <dave.hansen@linux.intel.com>
The Intel(R) Xeon Phi(TM) Processor x200 Family (codename: Knights
Landing) has an erratum where a processor thread setting the Accessed
or Dirty bits may not do so atomically against its checks for the
Present bit. This may cause a thread (which is about to page fault)
to set A and/or D, even though the Present bit had already been
atomically cleared.
These bits are truly "stray". In the case of the Dirty bit, the
thread associated with the stray set was *not* allowed to write to
the page. This means that we do not have to launder the bit(s); we
can simply ignore them.
If the PTE is used for storing a swap index or a NUMA migration index,
the A bit could be misinterpreted as part of the swap type. The stray
bits being set cause a software-cleared PTE to be interpreted as a
swap entry. In some cases (like when the swap index ends up being
for a non-existent swapfile), the kernel detects the stray value
and WARN()s about it, but there is no guarantee that the kernel can
always detect it.
When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
to move the swap PTE format around to avoid these troublesome bits.
But, 32-bit non-PAE is tight on bits. So, disallow it from running
on this hardware. I can't imagine anyone wanting to run 32-bit
non-highmem kernels on this hardware, but disallowing them from
running entirely is surely the safe thing to do.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
---
b/arch/x86/boot/boot.h | 1 +
b/arch/x86/boot/cpu.c | 2 ++
b/arch/x86/boot/cpucheck.c | 33 +++++++++++++++++++++++++++++++++
b/arch/x86/boot/cpuflags.c | 1 +
b/arch/x86/boot/cpuflags.h | 1 +
5 files changed, 38 insertions(+)
diff -puN arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/boot.h
--- a/arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.420785026 -0700
+++ b/arch/x86/boot/boot.h 2016-07-07 17:17:44.430785476 -0700
@@ -295,6 +295,7 @@ static inline int cmdline_find_option_bo
/* cpu.c, cpucheck.c */
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int check_knl_erratum(void);
int validate_cpu(void);
/* early_serial_console.c */
diff -puN arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpu.c
--- a/arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.422785116 -0700
+++ b/arch/x86/boot/cpu.c 2016-07-07 17:17:44.430785476 -0700
@@ -93,6 +93,8 @@ int validate_cpu(void)
show_cap_strs(err_flags);
putchar('\n');
return -1;
+ } else if (check_knl_erratum()) {
+ return -1;
} else {
return 0;
}
diff -puN arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpucheck.c
--- a/arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.423785161 -0700
+++ b/arch/x86/boot/cpucheck.c 2016-07-07 17:17:44.431785520 -0700
@@ -24,6 +24,7 @@
# include "boot.h"
#endif
#include <linux/types.h>
+#include <asm/intel-family.h>
#include <asm/processor-flags.h>
#include <asm/required-features.h>
#include <asm/msr-index.h>
@@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *r
puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n");
}
}
+ if (!err)
+ err = check_knl_erratum();
if (err_flags_ptr)
*err_flags_ptr = err ? err_flags : NULL;
@@ -185,3 +188,33 @@ int check_cpu(int *cpu_level_ptr, int *r
return (cpu.level < req_level || err) ? -1 : 0;
}
+
+int check_knl_erratum(void)
+{
+ /*
+ * First check for the affected model/family:
+ */
+ if (!is_intel() ||
+ cpu.family != 6 ||
+ cpu.model != INTEL_FAM6_XEON_PHI_KNL)
+ return 0;
+
+ /*
+ * This erratum affects the Accessed/Dirty bits, and can
+ * cause stray bits to be set in !Present PTEs. We have
+ * enough bits in our 64-bit PTEs (which we have on real
+ * 64-bit mode or PAE) to avoid using these troublesome
+ * bits. But, we do not have enough space in our 32-bit
+ * PTEs. So, refuse to run on 32-bit non-PAE kernels.
+ */
+ if (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE))
+ return 0;
+
+ puts("This 32-bit kernel can not run on this Xeon Phi x200\n"
+ "processor due to a processor erratum. Use a 64-bit\n"
+ "kernel, or enable PAE in this 32-bit kernel.\n\n");
+
+ return -1;
+}
+
+
diff -puN arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.c
--- a/arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.425785251 -0700
+++ b/arch/x86/boot/cpuflags.c 2016-07-07 17:17:44.431785520 -0700
@@ -102,6 +102,7 @@ void get_cpuflags(void)
cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
&cpu.flags[0]);
cpu.level = (tfms >> 8) & 15;
+ cpu.family = cpu.level;
cpu.model = (tfms >> 4) & 15;
if (cpu.level >= 6)
cpu.model += ((tfms >> 16) & 0xf) << 4;
diff -puN arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.h
--- a/arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.427785341 -0700
+++ b/arch/x86/boot/cpuflags.h 2016-07-07 17:17:44.431785520 -0700
@@ -6,6 +6,7 @@
struct cpu_features {
int level; /* Family, or 64 for x86-64 */
+ int family; /* Family, always */
int model;
u32 flags[NCAPINTS];
};
_
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
@ 2016-07-08 0:19 ` Dave Hansen
0 siblings, 0 replies; 8+ messages in thread
From: Dave Hansen @ 2016-07-08 0:19 UTC (permalink / raw)
To: linux-kernel
Cc: x86, linux-mm, torvalds, akpm, bp, ak, mhocko, dave.hansen,
Dave Hansen, dave.hansen
From: Dave Hansen <dave.hansen@linux.intel.com>
The Intel(R) Xeon Phi(TM) Processor x200 Family (codename: Knights
Landing) has an erratum where a processor thread setting the Accessed
or Dirty bits may not do so atomically against its checks for the
Present bit. This may cause a thread (which is about to page fault)
to set A and/or D, even though the Present bit had already been
atomically cleared.
These bits are truly "stray". In the case of the Dirty bit, the
thread associated with the stray set was *not* allowed to write to
the page. This means that we do not have to launder the bit(s); we
can simply ignore them.
If the PTE is used for storing a swap index or a NUMA migration index,
the A bit could be misinterpreted as part of the swap type. The stray
bits being set cause a software-cleared PTE to be interpreted as a
swap entry. In some cases (like when the swap index ends up being
for a non-existent swapfile), the kernel detects the stray value
and WARN()s about it, but there is no guarantee that the kernel can
always detect it.
When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
to move the swap PTE format around to avoid these troublesome bits.
But, 32-bit non-PAE is tight on bits. So, disallow it from running
on this hardware. I can't imagine anyone wanting to run 32-bit
non-highmem kernels on this hardware, but disallowing them from
running entirely is surely the safe thing to do.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
---
b/arch/x86/boot/boot.h | 1 +
b/arch/x86/boot/cpu.c | 2 ++
b/arch/x86/boot/cpucheck.c | 33 +++++++++++++++++++++++++++++++++
b/arch/x86/boot/cpuflags.c | 1 +
b/arch/x86/boot/cpuflags.h | 1 +
5 files changed, 38 insertions(+)
diff -puN arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/boot.h
--- a/arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.420785026 -0700
+++ b/arch/x86/boot/boot.h 2016-07-07 17:17:44.430785476 -0700
@@ -295,6 +295,7 @@ static inline int cmdline_find_option_bo
/* cpu.c, cpucheck.c */
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int check_knl_erratum(void);
int validate_cpu(void);
/* early_serial_console.c */
diff -puN arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpu.c
--- a/arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.422785116 -0700
+++ b/arch/x86/boot/cpu.c 2016-07-07 17:17:44.430785476 -0700
@@ -93,6 +93,8 @@ int validate_cpu(void)
show_cap_strs(err_flags);
putchar('\n');
return -1;
+ } else if (check_knl_erratum()) {
+ return -1;
} else {
return 0;
}
diff -puN arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpucheck.c
--- a/arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.423785161 -0700
+++ b/arch/x86/boot/cpucheck.c 2016-07-07 17:17:44.431785520 -0700
@@ -24,6 +24,7 @@
# include "boot.h"
#endif
#include <linux/types.h>
+#include <asm/intel-family.h>
#include <asm/processor-flags.h>
#include <asm/required-features.h>
#include <asm/msr-index.h>
@@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *r
puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n");
}
}
+ if (!err)
+ err = check_knl_erratum();
if (err_flags_ptr)
*err_flags_ptr = err ? err_flags : NULL;
@@ -185,3 +188,33 @@ int check_cpu(int *cpu_level_ptr, int *r
return (cpu.level < req_level || err) ? -1 : 0;
}
+
+int check_knl_erratum(void)
+{
+ /*
+ * First check for the affected model/family:
+ */
+ if (!is_intel() ||
+ cpu.family != 6 ||
+ cpu.model != INTEL_FAM6_XEON_PHI_KNL)
+ return 0;
+
+ /*
+ * This erratum affects the Accessed/Dirty bits, and can
+ * cause stray bits to be set in !Present PTEs. We have
+ * enough bits in our 64-bit PTEs (which we have on real
+ * 64-bit mode or PAE) to avoid using these troublesome
+ * bits. But, we do not have enough space in our 32-bit
+ * PTEs. So, refuse to run on 32-bit non-PAE kernels.
+ */
+ if (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE))
+ return 0;
+
+ puts("This 32-bit kernel can not run on this Xeon Phi x200\n"
+ "processor due to a processor erratum. Use a 64-bit\n"
+ "kernel, or enable PAE in this 32-bit kernel.\n\n");
+
+ return -1;
+}
+
+
diff -puN arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.c
--- a/arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.425785251 -0700
+++ b/arch/x86/boot/cpuflags.c 2016-07-07 17:17:44.431785520 -0700
@@ -102,6 +102,7 @@ void get_cpuflags(void)
cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
&cpu.flags[0]);
cpu.level = (tfms >> 8) & 15;
+ cpu.family = cpu.level;
cpu.model = (tfms >> 4) & 15;
if (cpu.level >= 6)
cpu.model += ((tfms >> 16) & 0xf) << 4;
diff -puN arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.h
--- a/arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-07 17:17:44.427785341 -0700
+++ b/arch/x86/boot/cpuflags.h 2016-07-07 17:17:44.431785520 -0700
@@ -6,6 +6,7 @@
struct cpu_features {
int level; /* Family, or 64 for x86-64 */
+ int family; /* Family, always */
int model;
u32 flags[NCAPINTS];
};
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
2016-07-01 17:46 [PATCH 0/4] [RFC][v4] Workaround for Xeon Phi PTE A/D bits erratum Dave Hansen
@ 2016-07-01 17:47 ` Dave Hansen
0 siblings, 0 replies; 8+ messages in thread
From: Dave Hansen @ 2016-07-01 17:47 UTC (permalink / raw)
To: linux-kernel; +Cc: x86, linux-mm, torvalds, akpm, bp, ak, mhocko, Dave Hansen
The Intel(R) Xeon Phi(TM) Processor x200 Family (codename: Knights
Landing) has an erratum where a processor thread setting the Accessed
or Dirty bits may not do so atomically against its checks for the
Present bit. This may cause a thread (which is about to page fault)
to set A and/or D, even though the Present bit had already been
atomically cleared.
If the PTE is used for storing a swap index or a NUMA migration index,
the A bit could be misinterpreted as part of the swap type. The stray
bits being set cause a software-cleared PTE to be interpreted as a
swap entry. In some cases (like when the swap index ends up being
for a non-existent swapfile), the kernel detects the stray value
and WARN()s about it, but there is no guarantee that the kernel can
always detect it.
When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
to move the swap PTE format around to avoid these troublesome bits.
But, 32-bit non-PAE is tight on bits. So, disallow it from running
on this hardware. I can't imagine anyone wanting to run 32-bit
on this hardware, but this is the safe thing to do.
---
b/arch/x86/boot/boot.h | 1 +
b/arch/x86/boot/cpu.c | 2 ++
b/arch/x86/boot/cpucheck.c | 32 ++++++++++++++++++++++++++++++++
b/arch/x86/boot/cpuflags.c | 1 +
b/arch/x86/boot/cpuflags.h | 1 +
5 files changed, 37 insertions(+)
diff -puN arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/boot.h
--- a/arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.302790241 -0700
+++ b/arch/x86/boot/boot.h 2016-07-01 10:42:07.311790650 -0700
@@ -295,6 +295,7 @@ static inline int cmdline_find_option_bo
/* cpu.c, cpucheck.c */
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int check_knl_erratum(void);
int validate_cpu(void);
/* early_serial_console.c */
diff -puN arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpu.c
--- a/arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.303790286 -0700
+++ b/arch/x86/boot/cpu.c 2016-07-01 10:42:07.312790695 -0700
@@ -93,6 +93,8 @@ int validate_cpu(void)
show_cap_strs(err_flags);
putchar('\n');
return -1;
+ } else if (check_knl_erratum()) {
+ return -1;
} else {
return 0;
}
diff -puN arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpucheck.c
--- a/arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.305790377 -0700
+++ b/arch/x86/boot/cpucheck.c 2016-07-01 10:42:07.312790695 -0700
@@ -24,6 +24,7 @@
# include "boot.h"
#endif
#include <linux/types.h>
+#include <asm/intel-family.h>
#include <asm/processor-flags.h>
#include <asm/required-features.h>
#include <asm/msr-index.h>
@@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *r
puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n");
}
}
+ if (!err)
+ err = check_knl_erratum();
if (err_flags_ptr)
*err_flags_ptr = err ? err_flags : NULL;
@@ -185,3 +188,32 @@ int check_cpu(int *cpu_level_ptr, int *r
return (cpu.level < req_level || err) ? -1 : 0;
}
+
+int check_knl_erratum(void)
+{
+ /*
+ * First check for the affected model/family:
+ */
+ if (!is_intel() ||
+ cpu.family != 6 ||
+ cpu.model != INTEL_FAM6_XEON_PHI_KNL)
+ return 0;
+
+ /*
+ * This erratum affects the Accessed/Dirty bits, and can
+ * cause stray bits to be set in !Present PTEs. We have
+ * enough bits in our 64-bit PTEs (which we have on real
+ * 64-bit mode or PAE) to avoid using these troublesome
+ * bits. But, we do not have enough soace in our 32-bit
+ * PTEs. So, refuse to run on 32-bit non-PAE kernels.
+ */
+ if (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE))
+ return 0;
+
+ puts("This 32-bit kernel can not run on this processor due\n"
+ "to a processor erratum. Use a 64-bit kernel, or PAE.\n\n");
+
+ return -1;
+}
+
+
diff -puN arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.c
--- a/arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.307790468 -0700
+++ b/arch/x86/boot/cpuflags.c 2016-07-01 10:42:07.312790695 -0700
@@ -102,6 +102,7 @@ void get_cpuflags(void)
cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
&cpu.flags[0]);
cpu.level = (tfms >> 8) & 15;
+ cpu.family = cpu.level;
cpu.model = (tfms >> 4) & 15;
if (cpu.level >= 6)
cpu.model += ((tfms >> 16) & 0xf) << 4;
diff -puN arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.h
--- a/arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.308790514 -0700
+++ b/arch/x86/boot/cpuflags.h 2016-07-01 10:42:07.313790740 -0700
@@ -6,6 +6,7 @@
struct cpu_features {
int level; /* Family, or 64 for x86-64 */
+ int family; /* Family, always */
int model;
u32 flags[NCAPINTS];
};
_
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum
@ 2016-07-01 17:47 ` Dave Hansen
0 siblings, 0 replies; 8+ messages in thread
From: Dave Hansen @ 2016-07-01 17:47 UTC (permalink / raw)
To: linux-kernel; +Cc: x86, linux-mm, torvalds, akpm, bp, ak, mhocko, Dave Hansen
The Intel(R) Xeon Phi(TM) Processor x200 Family (codename: Knights
Landing) has an erratum where a processor thread setting the Accessed
or Dirty bits may not do so atomically against its checks for the
Present bit. This may cause a thread (which is about to page fault)
to set A and/or D, even though the Present bit had already been
atomically cleared.
If the PTE is used for storing a swap index or a NUMA migration index,
the A bit could be misinterpreted as part of the swap type. The stray
bits being set cause a software-cleared PTE to be interpreted as a
swap entry. In some cases (like when the swap index ends up being
for a non-existent swapfile), the kernel detects the stray value
and WARN()s about it, but there is no guarantee that the kernel can
always detect it.
When we have 64-bit PTEs (64-bit mode or 32-bit PAE), we were able
to move the swap PTE format around to avoid these troublesome bits.
But, 32-bit non-PAE is tight on bits. So, disallow it from running
on this hardware. I can't imagine anyone wanting to run 32-bit
on this hardware, but this is the safe thing to do.
---
b/arch/x86/boot/boot.h | 1 +
b/arch/x86/boot/cpu.c | 2 ++
b/arch/x86/boot/cpucheck.c | 32 ++++++++++++++++++++++++++++++++
b/arch/x86/boot/cpuflags.c | 1 +
b/arch/x86/boot/cpuflags.h | 1 +
5 files changed, 37 insertions(+)
diff -puN arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/boot.h
--- a/arch/x86/boot/boot.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.302790241 -0700
+++ b/arch/x86/boot/boot.h 2016-07-01 10:42:07.311790650 -0700
@@ -295,6 +295,7 @@ static inline int cmdline_find_option_bo
/* cpu.c, cpucheck.c */
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int check_knl_erratum(void);
int validate_cpu(void);
/* early_serial_console.c */
diff -puN arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpu.c
--- a/arch/x86/boot/cpu.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.303790286 -0700
+++ b/arch/x86/boot/cpu.c 2016-07-01 10:42:07.312790695 -0700
@@ -93,6 +93,8 @@ int validate_cpu(void)
show_cap_strs(err_flags);
putchar('\n');
return -1;
+ } else if (check_knl_erratum()) {
+ return -1;
} else {
return 0;
}
diff -puN arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpucheck.c
--- a/arch/x86/boot/cpucheck.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.305790377 -0700
+++ b/arch/x86/boot/cpucheck.c 2016-07-01 10:42:07.312790695 -0700
@@ -24,6 +24,7 @@
# include "boot.h"
#endif
#include <linux/types.h>
+#include <asm/intel-family.h>
#include <asm/processor-flags.h>
#include <asm/required-features.h>
#include <asm/msr-index.h>
@@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *r
puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n");
}
}
+ if (!err)
+ err = check_knl_erratum();
if (err_flags_ptr)
*err_flags_ptr = err ? err_flags : NULL;
@@ -185,3 +188,32 @@ int check_cpu(int *cpu_level_ptr, int *r
return (cpu.level < req_level || err) ? -1 : 0;
}
+
+int check_knl_erratum(void)
+{
+ /*
+ * First check for the affected model/family:
+ */
+ if (!is_intel() ||
+ cpu.family != 6 ||
+ cpu.model != INTEL_FAM6_XEON_PHI_KNL)
+ return 0;
+
+ /*
+ * This erratum affects the Accessed/Dirty bits, and can
+ * cause stray bits to be set in !Present PTEs. We have
+ * enough bits in our 64-bit PTEs (which we have on real
+ * 64-bit mode or PAE) to avoid using these troublesome
+ * bits. But, we do not have enough soace in our 32-bit
+ * PTEs. So, refuse to run on 32-bit non-PAE kernels.
+ */
+ if (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE))
+ return 0;
+
+ puts("This 32-bit kernel can not run on this processor due\n"
+ "to a processor erratum. Use a 64-bit kernel, or PAE.\n\n");
+
+ return -1;
+}
+
+
diff -puN arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.c
--- a/arch/x86/boot/cpuflags.c~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.307790468 -0700
+++ b/arch/x86/boot/cpuflags.c 2016-07-01 10:42:07.312790695 -0700
@@ -102,6 +102,7 @@ void get_cpuflags(void)
cpuid(0x1, &tfms, &ignored, &cpu.flags[4],
&cpu.flags[0]);
cpu.level = (tfms >> 8) & 15;
+ cpu.family = cpu.level;
cpu.model = (tfms >> 4) & 15;
if (cpu.level >= 6)
cpu.model += ((tfms >> 16) & 0xf) << 4;
diff -puN arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL arch/x86/boot/cpuflags.h
--- a/arch/x86/boot/cpuflags.h~knl-strays-40-disallow-non-PAE-32-bit-on-KNL 2016-07-01 10:42:07.308790514 -0700
+++ b/arch/x86/boot/cpuflags.h 2016-07-01 10:42:07.313790740 -0700
@@ -6,6 +6,7 @@
struct cpu_features {
int level; /* Family, or 64 for x86-64 */
+ int family; /* Family, always */
int model;
u32 flags[NCAPINTS];
};
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-07-08 0:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <006001d1d5a8$dd26e1f0$9774a5d0$@alibaba-inc.com>
2016-07-04 4:20 ` [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum Hillf Danton
2016-07-04 4:20 ` Hillf Danton
2016-07-06 16:02 ` Dave Hansen
2016-07-06 16:02 ` Dave Hansen
2016-07-08 0:19 [PATCH 0/4] [RFC][v4] Workaround for Xeon Phi PTE A/D bits erratum Dave Hansen
2016-07-08 0:19 ` [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum Dave Hansen
2016-07-08 0:19 ` Dave Hansen
-- strict thread matches above, loose matches on Subject: below --
2016-07-01 17:46 [PATCH 0/4] [RFC][v4] Workaround for Xeon Phi PTE A/D bits erratum Dave Hansen
2016-07-01 17:47 ` [PATCH 3/4] x86: disallow running with 32-bit PTEs to work around erratum Dave Hansen
2016-07-01 17:47 ` Dave Hansen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.