From a2be16873c1a415f710d0aeba2a6e8f6a2ac4720 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Fri, 27 Dec 2019 13:02:30 +0000 Subject: [PATCH] VMX: save guest CET state to VMCS on vmexit --- bochs/cpu/cet.cc | 2 +- bochs/cpu/segment_ctrl.cc | 2 ++ bochs/cpu/svm.cc | 5 ++--- bochs/cpu/vmx.cc | 9 ++++++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/bochs/cpu/cet.cc b/bochs/cpu/cet.cc index 8c18c589f..125d8c487 100644 --- a/bochs/cpu/cet.cc +++ b/bochs/cpu/cet.cc @@ -50,7 +50,7 @@ bx_bool is_invalid_cet_control(bx_address val) bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::ShadowStackEnabled(unsigned cpl) { return BX_CPU_THIS_PTR cr4.get_CET() && protected_mode() && - BX_CPU_THIS_PTR msr.ia32_cet_control[cpl==3] & BX_CET_SHADOW_STACK_ENABLED; + BX_CPU_THIS_PTR msr.ia32_cet_control[cpl==3] & BX_CET_SHADOW_STACK_ENABLED; } bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::ShadowStackWriteEnabled(unsigned cpl) diff --git a/bochs/cpu/segment_ctrl.cc b/bochs/cpu/segment_ctrl.cc index e9b667f56..15ba56d5b 100644 --- a/bochs/cpu/segment_ctrl.cc +++ b/bochs/cpu/segment_ctrl.cc @@ -25,6 +25,8 @@ #include "cpu.h" #define LOG_THIS BX_CPU_THIS_PTR +const char *segname[] = { "ES", "CS", "SS", "DS", "FS", "GS" }; + void BX_CPP_AttrRegparmN(2) BX_CPU_C::load_segw(bxInstruction_c *i, unsigned seg) { bx_address eaddr = BX_CPU_RESOLVE_ADDR(i); diff --git a/bochs/cpu/svm.cc b/bochs/cpu/svm.cc index 91701a558..74fff4c46 100644 --- a/bochs/cpu/svm.cc +++ b/bochs/cpu/svm.cc @@ -30,8 +30,7 @@ #include "decoder/ia_opcodes.h" -// for debugging and save/restore -static const char *svm_segname[] = { "ES", "CS", "SS", "DS", "FS", "GS", "GDTR", "LDTR", "IDTR", "TR" }; +extern const char *segname[]; // When loading segment bases from the VMCB or the host save area // (on VMRUN or #VMEXIT), segment bases are canonicalized (i.e. @@ -1253,7 +1252,7 @@ void BX_CPU_C::register_svm_state(bx_param_c *parent) for(unsigned n=0; n<4; n++) { bx_segment_reg_t *segment = &BX_CPU_THIS_PTR vmcb.host_state.sregs[n]; - bx_list_c *sreg = new bx_list_c(host, svm_segname[n]); + bx_list_c *sreg = new bx_list_c(host, segname[n]); BXRS_HEX_PARAM_FIELD(sreg, selector, segment->selector.value); BXRS_HEX_PARAM_FIELD(sreg, valid, segment->cache.valid); BXRS_PARAM_BOOL(sreg, p, segment->cache.p); diff --git a/bochs/cpu/vmx.cc b/bochs/cpu/vmx.cc index ad38e2f0b..c564fbae9 100644 --- a/bochs/cpu/vmx.cc +++ b/bochs/cpu/vmx.cc @@ -41,6 +41,8 @@ extern bx_bool isValidMSR_PAT(Bit64u pat_msr); extern bx_bool is_invalid_cet_control(bx_address val); #endif +extern const char *segname[]; + //////////////////////////////////////////////////////////// // VMEXIT reasons for BX prints //////////////////////////////////////////////////////////// @@ -1295,7 +1297,6 @@ BX_CPP_INLINE bx_bool IsLimitAccessRightsConsistent(Bit32u limit, Bit32u ar) Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification) { - static const char *segname[] = { "ES", "CS", "SS", "DS", "FS", "GS" }; int n; VMCS_GUEST_STATE guest; @@ -2308,6 +2309,12 @@ void BX_CPU_C::VMexitSaveGuestState(void) VMwrite_natural(VMCS_GUEST_RSP, RSP); VMwrite_natural(VMCS_GUEST_RFLAGS, read_eflags()); +#if BX_SUPPORT_CET + VMwrite_natural(VMCS_GUEST_IA32_S_CET, BX_CPU_THIS_PTR msr.ia32_cet_control[0]); + VMwrite_natural(VMCS_GUEST_INTERRUPT_SSP_TABLE_ADDR, BX_CPU_THIS_PTR msr.ia32_interrupt_ssp_table); + VMwrite_natural(VMCS_GUEST_SSP, SSP); +#endif + for (n=0; n<6; n++) { Bit32u selector = BX_CPU_THIS_PTR sregs[n].selector.value; bx_bool invalid = !BX_CPU_THIS_PTR sregs[n].cache.valid;