Re: [PATCH v6 17/25] KVM: VMX: Introduce CET VMCS fields and control bits

From: Maxim Levitsky
Date: Tue Oct 31 2023 - 13:53:40 EST


On Thu, 2023-09-14 at 02:33 -0400, Yang Weijiang wrote:
> Control-flow Enforcement Technology (CET) is a kind of CPU feature used
> to prevent Return/CALL/Jump-Oriented Programming (ROP/COP/JOP) attacks.
> It provides two sub-features(SHSTK,IBT) to defend against ROP/COP/JOP
> style control-flow subversion attacks.
>
> Shadow Stack (SHSTK):
> A shadow stack is a second stack used exclusively for control transfer
> operations. The shadow stack is separate from the data/normal stack and
> can be enabled individually in user and kernel mode. When shadow stack
> is enabled, CALL pushes the return address on both the data and shadow
> stack. RET pops the return address from both stacks and compares them.
> If the return addresses from the two stacks do not match, the processor
> generates a #CP.
>
> Indirect Branch Tracking (IBT):
> IBT introduces instruction(ENDBRANCH)to mark valid target addresses of
> indirect branches (CALL, JMP etc...). If an indirect branch is executed
> and the next instruction is _not_ an ENDBRANCH, the processor generates
> a #CP. These instruction behaves as a NOP on platforms that have no CET.
>
> Several new CET MSRs are defined to support CET:
> MSR_IA32_{U,S}_CET: CET settings for {user,supervisor} CET respectively.
>
> MSR_IA32_PL{0,1,2,3}_SSP: SHSTK pointer linear address for CPL{0,1,2,3}.
>
> MSR_IA32_INT_SSP_TAB: Linear address of SHSTK pointer table, whose entry
> is indexed by IST of interrupt gate desc.
>
> Two XSAVES state bits are introduced for CET:
> IA32_XSS:[bit 11]: Control saving/restoring user mode CET states
> IA32_XSS:[bit 12]: Control saving/restoring supervisor mode CET states.
>
> Six VMCS fields are introduced for CET:
> {HOST,GUEST}_S_CET: Stores CET settings for kernel mode.
> {HOST,GUEST}_SSP: Stores current active SSP.
> {HOST,GUEST}_INTR_SSP_TABLE: Stores current active MSR_IA32_INT_SSP_TAB.
>
> On Intel platforms, two additional bits are defined in VM_EXIT and VM_ENTRY
> control fields:
> If VM_EXIT_LOAD_CET_STATE = 1, host CET states are loaded from following
> VMCS fields at VM-Exit:
> HOST_S_CET
> HOST_SSP
> HOST_INTR_SSP_TABLE
>
> If VM_ENTRY_LOAD_CET_STATE = 1, guest CET states are loaded from following
> VMCS fields at VM-Entry:
> GUEST_S_CET
> GUEST_SSP
> GUEST_INTR_SSP_TABLE
>
> Reviewed-by: Chao Gao <chao.gao@xxxxxxxxx>
> Co-developed-by: Zhang Yi Z <yi.z.zhang@xxxxxxxxxxxxxxx>
> Signed-off-by: Zhang Yi Z <yi.z.zhang@xxxxxxxxxxxxxxx>
> Signed-off-by: Yang Weijiang <weijiang.yang@xxxxxxxxx>
> ---
> arch/x86/include/asm/vmx.h | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
> index 0e73616b82f3..451fd4f4fedc 100644
> --- a/arch/x86/include/asm/vmx.h
> +++ b/arch/x86/include/asm/vmx.h
> @@ -104,6 +104,7 @@
> #define VM_EXIT_CLEAR_BNDCFGS 0x00800000
> #define VM_EXIT_PT_CONCEAL_PIP 0x01000000
> #define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000
> +#define VM_EXIT_LOAD_CET_STATE 0x10000000
Bit 28, matches PRM.
>
> #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff
>
> @@ -117,6 +118,7 @@
> #define VM_ENTRY_LOAD_BNDCFGS 0x00010000
> #define VM_ENTRY_PT_CONCEAL_PIP 0x00020000
> #define VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000
> +#define VM_ENTRY_LOAD_CET_STATE 0x00100000
Bit 20, matches PRM.


I wish we redefine these masks with BIT_ULL(n) macros for the sake of
having less chance of a mistake. Patches to refactor this are welcome!

>
> #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff
>
> @@ -345,6 +347,9 @@ enum vmcs_field {
> GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,
> GUEST_SYSENTER_ESP = 0x00006824,
> GUEST_SYSENTER_EIP = 0x00006826,
> + GUEST_S_CET = 0x00006828,
> + GUEST_SSP = 0x0000682a,
> + GUEST_INTR_SSP_TABLE = 0x0000682c,
Matches the PRM.

> HOST_CR0 = 0x00006c00,
> HOST_CR3 = 0x00006c02,
> HOST_CR4 = 0x00006c04,
> @@ -357,6 +362,9 @@ enum vmcs_field {
> HOST_IA32_SYSENTER_EIP = 0x00006c12,
> HOST_RSP = 0x00006c14,
> HOST_RIP = 0x00006c16,

> + HOST_S_CET = 0x00006c18,
> + HOST_SSP = 0x00006c1a,
> + HOST_INTR_SSP_TABLE = 0x00006c1c
Matches the PRM as well.


Reviewed-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx>

Best regards,
Maxim Levitsky



> };
>
> /*