[v2] x86: Add PTWRITE feature detection [BZ #27346]

Message ID CAMe9rOpUb-RvQz7XKQHSr1rEx=C6YnQ+5nSL-+99Li12=t4uMA@mail.gmail.com
State Committed
Headers
Series [v2] x86: Add PTWRITE feature detection [BZ #27346] |

Commit Message

H.J. Lu Feb. 7, 2021, 3:26 p.m. UTC
  On Sun, Feb 7, 2021 at 2:10 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu via Libc-alpha:
>
> > 1. Add CPUID_INDEX_14 for CPUID leaf 0x14 to detect PTWRITE feature in
> > EBX of CPUID leaf 0x14.
>
> The processor manual suggests that index 0x14h has subleaves, so should
> this be CPUID_INDEX_14_ECX_0?

Good idea.  Fixed.

> The bit position looks correct to me, and copying it from the feature
> bits to the usable bits also appears to be correct.  (I assume the
> instruction is a NOP if not enabled by the kernel.)
>

I think so since operand passed to PTWRITE should be valid.

Here is the updated patch.  OK for master?

Thanks.
  

Comments

Florian Weimer Feb. 7, 2021, 3:42 p.m. UTC | #1
* H. J. Lu:

> Here is the updated patch.  OK for master?

Looks good to me.

Thanks,
Florian
  

Patch

From 7234b7a9a6bca7443900a44996c324cc354284c5 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 4 Feb 2021 10:39:34 -0800
Subject: [PATCH v2] x86: Add PTWRITE feature detection [BZ #27346]

1. Add CPUID_INDEX_14_ECX_0 for CPUID leaf 0x14 to detect PTWRITE feature
in EBX of CPUID leaf 0x14 with ECX == 0.
2. Add PTWRITE detection to CPU feature tests.
3. Add 2 static CPU feature tests.
---
 manual/platform.texi                           |  3 +++
 sysdeps/x86/Makefile                           |  7 +++++--
 sysdeps/x86/bits/platform/x86.h                | 11 +++++++++--
 sysdeps/x86/cpu-features.c                     |  8 ++++++++
 sysdeps/x86/include/cpu-features.h             | 17 ++++++++++++++++-
 sysdeps/x86/tst-cpu-features-cpuinfo-static.c  |  1 +
 sysdeps/x86/tst-cpu-features-cpuinfo.c         |  1 +
 sysdeps/x86/tst-cpu-features-supports-static.c |  1 +
 sysdeps/x86/tst-cpu-features-supports.c        |  1 +
 sysdeps/x86/tst-get-cpu-features.c             |  2 ++
 10 files changed, 47 insertions(+), 5 deletions(-)
 create mode 100644 sysdeps/x86/tst-cpu-features-cpuinfo-static.c
 create mode 100644 sysdeps/x86/tst-cpu-features-supports-static.c

diff --git a/manual/platform.texi b/manual/platform.texi
index 6caf68d796..a0b204b099 100644
--- a/manual/platform.texi
+++ b/manual/platform.texi
@@ -487,6 +487,9 @@  extended state management using XSAVE/XRSTOR.
 @item
 @code{PSN} -- Processor Serial Number.
 
+@item
+@code{PTWRITE} -- PTWRITE instruction.
+
 @item
 @code{RDPID} -- RDPID instruction.
 
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index dd82674342..e1f9379fd8 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -8,8 +8,11 @@  sysdep-dl-routines += dl-get-cpu-features
 sysdep_headers += sys/platform/x86.h
 
 tests += tst-get-cpu-features tst-get-cpu-features-static \
-	 tst-cpu-features-cpuinfo tst-cpu-features-supports
-tests-static += tst-get-cpu-features-static
+	 tst-cpu-features-cpuinfo tst-cpu-features-cpuinfo-static \
+	 tst-cpu-features-supports tst-cpu-features-supports-static
+tests-static += tst-get-cpu-features-static \
+		tst-cpu-features-cpuinfo-static \
+		tst-cpu-features-supports-static
 ifeq (yes,$(have-ifunc))
 tests += \
   tst-ifunc-isa-1 \
diff --git a/sysdeps/x86/bits/platform/x86.h b/sysdeps/x86/bits/platform/x86.h
index dd59224b7f..fe08d8a1b6 100644
--- a/sysdeps/x86/bits/platform/x86.h
+++ b/sysdeps/x86/bits/platform/x86.h
@@ -29,7 +29,8 @@  enum
   CPUID_INDEX_80000007,
   CPUID_INDEX_80000008,
   CPUID_INDEX_7_ECX_1,
-  CPUID_INDEX_19
+  CPUID_INDEX_19,
+  CPUID_INDEX_14_ECX_0
 };
 
 struct cpuid_feature
@@ -295,5 +296,11 @@  enum
        + cpuid_register_index_ebx * 8 * sizeof (unsigned int)),
 
   x86_cpu_AESKLE		= x86_cpu_index_19_ebx,
-  x86_cpu_WIDE_KL		= x86_cpu_index_19_ebx + 2
+  x86_cpu_WIDE_KL		= x86_cpu_index_19_ebx + 2,
+
+  x86_cpu_index_14_ecx_0_ebx
+    = (CPUID_INDEX_14_ECX_0 * 8 * 4 * sizeof (unsigned int)
+       + cpuid_register_index_ebx * 8 * sizeof (unsigned int)),
+
+  x86_cpu_PTWRITE		= x86_cpu_index_14_ecx_0_ebx + 4
 };
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 7996ed0cd2..d7248cbb45 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -97,6 +97,7 @@  update_usable (struct cpu_features *cpu_features)
   CPU_FEATURE_SET_USABLE (cpu_features, FZLRM);
   CPU_FEATURE_SET_USABLE (cpu_features, FSRS);
   CPU_FEATURE_SET_USABLE (cpu_features, FSRCS);
+  CPU_FEATURE_SET_USABLE (cpu_features, PTWRITE);
 
   /* Can we call xgetbv?  */
   if (CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
@@ -359,6 +360,13 @@  get_common_indices (struct cpu_features *cpu_features,
 		   cpu_features->features[CPUID_INDEX_D_ECX_1].cpuid.ecx,
 		   cpu_features->features[CPUID_INDEX_D_ECX_1].cpuid.edx);
 
+  if (cpu_features->basic.max_cpuid >= 0x14)
+    __cpuid_count (0x14, 0,
+		   cpu_features->features[CPUID_INDEX_14_ECX_0].cpuid.eax,
+		   cpu_features->features[CPUID_INDEX_14_ECX_0].cpuid.ebx,
+		   cpu_features->features[CPUID_INDEX_14_ECX_0].cpuid.ecx,
+		   cpu_features->features[CPUID_INDEX_14_ECX_0].cpuid.edx);
+
   if (cpu_features->basic.max_cpuid >= 0x19)
     __cpuid_count (0x19, 0,
 		   cpu_features->features[CPUID_INDEX_19].cpuid.eax,
diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
index 475e877294..dabe6b9d86 100644
--- a/sysdeps/x86/include/cpu-features.h
+++ b/sysdeps/x86/include/cpu-features.h
@@ -29,7 +29,7 @@ 
 
 enum
 {
-  CPUID_INDEX_MAX = CPUID_INDEX_19 + 1
+  CPUID_INDEX_MAX = CPUID_INDEX_14_ECX_0 + 1
 };
 
 enum
@@ -307,6 +307,11 @@  enum
 #define bit_cpu_AESKLE		(1u << 0)
 #define bit_cpu_WIDE_KL		(1u << 2)
 
+/* CPUID_INDEX_14_ECX_0.  */
+
+/* EBX.  */
+#define bit_cpu_PTWRITE		(1u << 4)
+
 /* CPUID_INDEX_1.  */
 
 /* ECX.  */
@@ -532,6 +537,11 @@  enum
 #define index_cpu_AESKLE	CPUID_INDEX_19
 #define index_cpu_WIDE_KL	CPUID_INDEX_19
 
+/* CPUID_INDEX_14_ECX_0.  */
+
+/* EBX.  */
+#define index_cpu_PTWRITE	CPUID_INDEX_14_ECX_0
+
 /* CPUID_INDEX_1.  */
 
 /* ECX.  */
@@ -757,6 +767,11 @@  enum
 #define reg_AESKLE		ebx
 #define reg_WIDE_KL		ebx
 
+/* CPUID_INDEX_14_ECX_0.  */
+
+/* EBX.  */
+#define reg_PTWRITE		ebx
+
 /* PREFERRED_FEATURE_INDEX_1.  */
 #define bit_arch_I586				(1u << 0)
 #define bit_arch_I686				(1u << 1)
diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo-static.c b/sysdeps/x86/tst-cpu-features-cpuinfo-static.c
new file mode 100644
index 0000000000..993a1a95f7
--- /dev/null
+++ b/sysdeps/x86/tst-cpu-features-cpuinfo-static.c
@@ -0,0 +1 @@ 
+#include "tst-cpu-features-cpuinfo.c"
diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c
index 95cefb5738..3f1150a329 100644
--- a/sysdeps/x86/tst-cpu-features-cpuinfo.c
+++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c
@@ -198,6 +198,7 @@  do_test (int argc, char **argv)
   fails += CHECK_PROC (popcnt, POPCNT);
   fails += CHECK_PROC (3dnowprefetch, PREFETCHW);
   fails += CHECK_PROC (prefetchwt1, PREFETCHWT1);
+  fails += CHECK_PROC (ptwrite, PTWRITE);
   fails += CHECK_PROC (pse, PSE);
   fails += CHECK_PROC (pse36, PSE_36);
   fails += CHECK_PROC (psn, PSN);
diff --git a/sysdeps/x86/tst-cpu-features-supports-static.c b/sysdeps/x86/tst-cpu-features-supports-static.c
new file mode 100644
index 0000000000..38f4046bb8
--- /dev/null
+++ b/sysdeps/x86/tst-cpu-features-supports-static.c
@@ -0,0 +1 @@ 
+#include "tst-cpu-features-supports.c"
diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c
index 79d803eb29..ce78a7d8bc 100644
--- a/sysdeps/x86/tst-cpu-features-supports.c
+++ b/sysdeps/x86/tst-cpu-features-supports.c
@@ -149,6 +149,7 @@  do_test (int argc, char **argv)
   fails += CHECK_SUPPORTS (popcnt, POPCNT);
 #if __GNUC_PREREQ (11, 0)
   fails += CHECK_SUPPORTS (prefetchwt1, PREFETCHWT1);
+  fails += CHECK_SUPPORTS (ptwrite, PTWRITE);
   fails += CHECK_SUPPORTS (rdpid, RDPID);
   fails += CHECK_SUPPORTS (rdrnd, RDRAND);
   fails += CHECK_SUPPORTS (rdseed, RDSEED);
diff --git a/sysdeps/x86/tst-get-cpu-features.c b/sysdeps/x86/tst-get-cpu-features.c
index b5e7f6e7b0..583e1e6d49 100644
--- a/sysdeps/x86/tst-get-cpu-features.c
+++ b/sysdeps/x86/tst-get-cpu-features.c
@@ -203,6 +203,7 @@  do_test (void)
   CHECK_CPU_FEATURE (LAM);
   CHECK_CPU_FEATURE (AESKLE);
   CHECK_CPU_FEATURE (WIDE_KL);
+  CHECK_CPU_FEATURE (PTWRITE);
 
   printf ("Usable CPU features:\n");
   CHECK_CPU_FEATURE_USABLE (SSE3);
@@ -364,6 +365,7 @@  do_test (void)
   CHECK_CPU_FEATURE_USABLE (FSRCS);
   CHECK_CPU_FEATURE_USABLE (AESKLE);
   CHECK_CPU_FEATURE_USABLE (WIDE_KL);
+  CHECK_CPU_FEATURE_USABLE (PTWRITE);
 
   return 0;
 }
-- 
2.29.2