[PATCH v3 11/20] i386/cpu: Enable xsave support for CET states

Zhao Liu posted 20 patches 3 months, 2 weeks ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Cornelia Huck <cohuck@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Zhao Liu <zhao1.liu@intel.com>, Marcelo Tosatti <mtosatti@redhat.com>
There is a newer version of this series
[PATCH v3 11/20] i386/cpu: Enable xsave support for CET states
Posted by Zhao Liu 3 months, 2 weeks ago
From: Yang Weijiang <weijiang.yang@intel.com>

Add CET_U/S bits in xstate area and report support in xstate
feature mask.
MSR_XSS[bit 11] corresponds to CET user mode states.
MSR_XSS[bit 12] corresponds to CET supervisor mode states.

CET Shadow Stack(SHSTK) and Indirect Branch Tracking(IBT) features
are enumerated via CPUID.(EAX=07H,ECX=0H):ECX[7] and EDX[20]
respectively, two features share the same state bits in XSS, so
if either of the features is enabled, set CET_U and CET_S bits
together.

Tested-by: Farrah Chen <farrah.chen@intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
Co-developed-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
Changes Since v2:
 - Rename XSavesCETU/XSavesCETS to XSaveCETU/XSaveCETS.
 - Refine the comments.
 - Drop ".offset = 0" and its comment.
 - Re-describe xstate dependencies via features array.
 - Drop "cet-u" & "cet-s" enumeration from FEAT_XSAVE_XSS_LO's
   feat_name array sicne currently xsave doesn't use named features.
---
 target/i386/cpu.c | 14 ++++++++++++++
 target/i386/cpu.h | 26 +++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b01729ad36d2..0bb65e8c5321 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2078,6 +2078,20 @@ ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] = {
             { FEAT_7_0_ECX,         CPUID_7_0_ECX_PKU },
         },
     },
+    [XSTATE_CET_U_BIT] = {
+        .size = sizeof(XSaveCETU),
+        .features = {
+            { FEAT_7_0_ECX,         CPUID_7_0_ECX_CET_SHSTK },
+            { FEAT_7_0_EDX,         CPUID_7_0_EDX_CET_IBT },
+        },
+    },
+    [XSTATE_CET_S_BIT] = {
+        .size = sizeof(XSaveCETS),
+        .features = {
+            { FEAT_7_0_ECX,         CPUID_7_0_ECX_CET_SHSTK },
+            { FEAT_7_0_EDX,         CPUID_7_0_EDX_CET_IBT },
+        },
+    },
     [XSTATE_ARCH_LBR_BIT] = {
         .size = sizeof(XSaveArchLBR),
         .features = {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 6537affcf067..7584cddb5917 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -589,6 +589,8 @@ typedef enum X86Seg {
 #define XSTATE_Hi16_ZMM_BIT             7
 #define XSTATE_PT_BIT                   8
 #define XSTATE_PKRU_BIT                 9
+#define XSTATE_CET_U_BIT                11
+#define XSTATE_CET_S_BIT                12
 #define XSTATE_ARCH_LBR_BIT             15
 #define XSTATE_XTILE_CFG_BIT            17
 #define XSTATE_XTILE_DATA_BIT           18
@@ -603,6 +605,8 @@ typedef enum X86Seg {
 #define XSTATE_Hi16_ZMM_MASK            (1ULL << XSTATE_Hi16_ZMM_BIT)
 #define XSTATE_PT_MASK                  (1ULL << XSTATE_PT_BIT)
 #define XSTATE_PKRU_MASK                (1ULL << XSTATE_PKRU_BIT)
+#define XSTATE_CET_U_MASK               (1ULL << XSTATE_CET_U_BIT)
+#define XSTATE_CET_S_MASK               (1ULL << XSTATE_CET_S_BIT)
 #define XSTATE_ARCH_LBR_MASK            (1ULL << XSTATE_ARCH_LBR_BIT)
 #define XSTATE_XTILE_CFG_MASK           (1ULL << XSTATE_XTILE_CFG_BIT)
 #define XSTATE_XTILE_DATA_MASK          (1ULL << XSTATE_XTILE_DATA_BIT)
@@ -625,7 +629,8 @@ typedef enum X86Seg {
                                  XSTATE_XTILE_CFG_MASK | XSTATE_XTILE_DATA_MASK)
 
 /* CPUID feature bits available in XSS */
-#define CPUID_XSTATE_XSS_MASK    (XSTATE_ARCH_LBR_MASK)
+#define CPUID_XSTATE_XSS_MASK   (XSTATE_ARCH_LBR_MASK | XSTATE_CET_U_MASK | \
+                                 XSTATE_CET_S_MASK)
 
 #define CPUID_XSTATE_MASK       (CPUID_XSTATE_XCR0_MASK | CPUID_XSTATE_XSS_MASK)
 
@@ -904,6 +909,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
 #define CPUID_7_0_ECX_WAITPKG           (1U << 5)
 /* Additional AVX-512 Vector Byte Manipulation Instruction */
 #define CPUID_7_0_ECX_AVX512_VBMI2      (1U << 6)
+/* Control-flow enforcement technology: shadow stack */
+#define CPUID_7_0_ECX_CET_SHSTK         (1U << 7)
 /* Galois Field New Instructions */
 #define CPUID_7_0_ECX_GFNI              (1U << 8)
 /* Vector AES Instructions */
@@ -951,6 +958,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
 #define CPUID_7_0_EDX_TSX_LDTRK         (1U << 16)
 /* Architectural LBRs */
 #define CPUID_7_0_EDX_ARCH_LBR          (1U << 19)
+/* Control-flow enforcement technology: indirect branch tracking */
+#define CPUID_7_0_EDX_CET_IBT           (1U << 20)
 /* AMX_BF16 instruction */
 #define CPUID_7_0_EDX_AMX_BF16          (1U << 22)
 /* AVX512_FP16 instruction */
@@ -1737,6 +1746,19 @@ typedef struct XSavePKRU {
     uint32_t padding;
 } XSavePKRU;
 
+/* Ext. save area 11: CET_U state */
+typedef struct XSaveCETU {
+    uint64_t u_cet;
+    uint64_t pl3_ssp;
+} XSaveCETU;
+
+/* Ext. save area 12: CET_S state */
+typedef struct XSaveCETS {
+    uint64_t pl0_ssp;
+    uint64_t pl1_ssp;
+    uint64_t pl2_ssp;
+} XSaveCETS;
+
 /* Ext. save area 15: Arch LBR state */
 typedef struct XSaveArchLBR {
     uint64_t lbr_ctl;
@@ -1764,6 +1786,8 @@ QEMU_BUILD_BUG_ON(sizeof(XSaveOpmask) != 0x40);
 QEMU_BUILD_BUG_ON(sizeof(XSaveZMM_Hi256) != 0x200);
 QEMU_BUILD_BUG_ON(sizeof(XSaveHi16_ZMM) != 0x400);
 QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8);
+QEMU_BUILD_BUG_ON(sizeof(XSaveCETU) != 0x10);
+QEMU_BUILD_BUG_ON(sizeof(XSaveCETS) != 0x18);
 QEMU_BUILD_BUG_ON(sizeof(XSaveArchLBR) != 0x328);
 QEMU_BUILD_BUG_ON(sizeof(XSaveXTILECFG) != 0x40);
 QEMU_BUILD_BUG_ON(sizeof(XSaveXTILEDATA) != 0x2000);
-- 
2.34.1
Re: [PATCH v3 11/20] i386/cpu: Enable xsave support for CET states
Posted by Chao Gao 3 months, 1 week ago
On Fri, Oct 24, 2025 at 02:56:23PM +0800, Zhao Liu wrote:
>From: Yang Weijiang <weijiang.yang@intel.com>
>
>Add CET_U/S bits in xstate area and report support in xstate
>feature mask.
>MSR_XSS[bit 11] corresponds to CET user mode states.
>MSR_XSS[bit 12] corresponds to CET supervisor mode states.
>
>CET Shadow Stack(SHSTK) and Indirect Branch Tracking(IBT) features
>are enumerated via CPUID.(EAX=07H,ECX=0H):ECX[7] and EDX[20]
>respectively, two features share the same state bits in XSS, so
>if either of the features is enabled, set CET_U and CET_S bits
>together.
>
>Tested-by: Farrah Chen <farrah.chen@intel.com>
>Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>Co-developed-by: Chao Gao <chao.gao@intel.com>
>Signed-off-by: Chao Gao <chao.gao@intel.com>
>Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
>Signed-off-by: Zhao Liu <zhao1.liu@intel.com>

It just occurred to me that KVM_GET/SET_XSAVE don't save/restore supervisor
states. Supervisor states need to be saved/restored via MSR APIs. So, there
is no need to add supervisor states (including ARCH_LBR states) to
x86_ext_save_areas[].
Re: [PATCH v3 11/20] i386/cpu: Enable xsave support for CET states
Posted by Xiaoyao Li 3 months, 1 week ago
On 10/29/2025 12:58 PM, Chao Gao wrote:
> On Fri, Oct 24, 2025 at 02:56:23PM +0800, Zhao Liu wrote:
>> From: Yang Weijiang <weijiang.yang@intel.com>
>>
>> Add CET_U/S bits in xstate area and report support in xstate
>> feature mask.
>> MSR_XSS[bit 11] corresponds to CET user mode states.
>> MSR_XSS[bit 12] corresponds to CET supervisor mode states.
>>
>> CET Shadow Stack(SHSTK) and Indirect Branch Tracking(IBT) features
>> are enumerated via CPUID.(EAX=07H,ECX=0H):ECX[7] and EDX[20]
>> respectively, two features share the same state bits in XSS, so
>> if either of the features is enabled, set CET_U and CET_S bits
>> together.
>>
>> Tested-by: Farrah Chen <farrah.chen@intel.com>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> Co-developed-by: Chao Gao <chao.gao@intel.com>
>> Signed-off-by: Chao Gao <chao.gao@intel.com>
>> Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
>> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> 
> It just occurred to me that KVM_GET/SET_XSAVE don't save/restore supervisor
> states. Supervisor states need to be saved/restored via MSR APIs. So, there
> is no need to add supervisor states (including ARCH_LBR states) to
> x86_ext_save_areas[].

x86_ext_save_areas[] is not used only for xsave state, it's also used 
for the setup of xsave features, i.e., CPUID leaf 0xD.

And you did catch the missing part of this series, it lacks the 
save/restore of CET XSAVE state in 
x86_cpu_xsave_all_areas()/x86_cpu_xrstor_all_areas()
Re: [PATCH v3 11/20] i386/cpu: Enable xsave support for CET states
Posted by Zhao Liu 3 months, 1 week ago
> > It just occurred to me that KVM_GET/SET_XSAVE don't save/restore supervisor
> > states. Supervisor states need to be saved/restored via MSR APIs. So, there
> > is no need to add supervisor states (including ARCH_LBR states) to
> > x86_ext_save_areas[].
> 
> x86_ext_save_areas[] is not used only for xsave state, it's also used for
> the setup of xsave features, i.e., CPUID leaf 0xD.

Yes. And it can also maintain dependencies.

> And you did catch the missing part of this series, it lacks the save/restore
> of CET XSAVE state in x86_cpu_xsave_all_areas()/x86_cpu_xrstor_all_areas()

Not a missing part. CET's xstates contain CET related MSRs and actually
is saved/restored via MSR ioctls, not KVM_GET/SET_XSAVE.

Regards,
Zhao
Re: [PATCH v3 11/20] i386/cpu: Enable xsave support for CET states
Posted by Xiaoyao Li 3 months, 2 weeks ago
On 10/24/2025 2:56 PM, Zhao Liu wrote:
> From: Yang Weijiang <weijiang.yang@intel.com>
> 
> Add CET_U/S bits in xstate area and report support in xstate
> feature mask.
> MSR_XSS[bit 11] corresponds to CET user mode states.
> MSR_XSS[bit 12] corresponds to CET supervisor mode states.
> 
> CET Shadow Stack(SHSTK) and Indirect Branch Tracking(IBT) features
> are enumerated via CPUID.(EAX=07H,ECX=0H):ECX[7] and EDX[20]
> respectively, two features share the same state bits in XSS, so
> if either of the features is enabled, set CET_U and CET_S bits
> together.
> 
> Tested-by: Farrah Chen <farrah.chen@intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> Co-developed-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>