From 2ee00297492b6ef2f96f91a2f415166ff2bd16f3 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Thu, 4 Aug 2011 19:02:49 +0000 Subject: [PATCH] extract ffxsr support to separate CPU feature --- bochs/cpu/cpu.h | 1 + bochs/cpu/cpuid.h | 1 + bochs/cpu/crregs.cc | 4 ++-- bochs/cpu/crregs.h | 6 ++---- bochs/cpu/generic_cpuid.cc | 42 ++++++++++++++++++++++++-------------- bochs/cpu/init.cc | 4 ++++ bochs/cpu/smm.cc | 6 +++--- bochs/cpu/vmx.cc | 4 ++-- 8 files changed, 42 insertions(+), 26 deletions(-) diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 291892c02..b8246c4bb 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -900,6 +900,7 @@ public: // for now... #if BX_SUPPORT_X86_64 bx_efer_t efer; + Bit32u efer_suppmask; #endif #if BX_CPU_LEVEL >= 6 diff --git a/bochs/cpu/cpuid.h b/bochs/cpu/cpuid.h index 77d63b005..f0967a48e 100644 --- a/bochs/cpu/cpuid.h +++ b/bochs/cpu/cpuid.h @@ -106,6 +106,7 @@ typedef bx_cpuid_t* (*bx_create_cpuid_method)(BX_CPU_C *cpu); #define BX_CPU_1G_PAGES (1 << 9) /* 1Gb pages support */ #define BX_CPU_PCID (1 << 10) /* PCID pages support */ #define BX_CPU_SMEP (1 << 11) /* SMEP support */ +#define BX_CPU_FFXSR (1 << 12) /* EFER.FFXSR support */ // CPUID defines - STD features CPUID[0x00000001].EDX // ---------------------------- diff --git a/bochs/cpu/crregs.cc b/bochs/cpu/crregs.cc index 928757f0d..b911fcc6b 100644 --- a/bochs/cpu/crregs.cc +++ b/bochs/cpu/crregs.cc @@ -1213,7 +1213,7 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR3(bx_address val) #if BX_SUPPORT_X86_64 bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetEFER(bx_address val_64) { - if (val_64 & ~BX_EFER_SUPPORTED_BITS) { + if (val_64 & ~((Bit64u) BX_CPU_THIS_PTR efer_suppmask)) { BX_ERROR(("SetEFER: attempt to set reserved bits of EFER MSR !")); return 0; } @@ -1228,7 +1228,7 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetEFER(bx_address val_64) return 0; } - BX_CPU_THIS_PTR efer.set32((val32 & BX_EFER_SUPPORTED_BITS & ~BX_EFER_LMA_MASK) + BX_CPU_THIS_PTR efer.set32((val32 & BX_CPU_THIS_PTR efer_suppmask & ~BX_EFER_LMA_MASK) | (BX_CPU_THIS_PTR efer.get32() & BX_EFER_LMA_MASK)); // keep LMA untouched return 1; diff --git a/bochs/cpu/crregs.h b/bochs/cpu/crregs.h index 0c3f88d9f..20524d8de 100644 --- a/bochs/cpu/crregs.h +++ b/bochs/cpu/crregs.h @@ -189,6 +189,8 @@ struct bx_dr7_t { #define BX_EFER_LME_MASK (1 << 8) #define BX_EFER_LMA_MASK (1 << 10) #define BX_EFER_NXE_MASK (1 << 11) +#define BX_EFER_SVME_MASK (1 << 12) +#define BX_EFER_LMSLE_MASK (1 << 13) #define BX_EFER_FFXSR_MASK (1 << 14) struct bx_efer_t { @@ -206,10 +208,6 @@ struct bx_efer_t { BX_CPP_INLINE void set32(Bit32u val) { val32 = val; } }; -#define BX_EFER_SUPPORTED_BITS \ - ((Bit64u) (BX_EFER_SCE_MASK | BX_EFER_LME_MASK | \ - BX_EFER_LMA_MASK | BX_EFER_NXE_MASK | BX_EFER_FFXSR_MASK)) - #endif #if BX_CPU_LEVEL >= 6 diff --git a/bochs/cpu/generic_cpuid.cc b/bochs/cpu/generic_cpuid.cc index 6711bcd84..8995d9d3b 100644 --- a/bochs/cpu/generic_cpuid.cc +++ b/bochs/cpu/generic_cpuid.cc @@ -840,6 +840,8 @@ void bx_generic_cpuid_t::init_cpu_extensions_bitmask(void) features_bitmask |= BX_CPU_SMEP; #if BX_SUPPORT_X86_64 + features_bitmask |= BX_CPU_FFXSR; + static bx_bool pcid_enabled = SIM->get_param_bool(BXPN_CPUID_PCID)->get(); if (pcid_enabled) features_bitmask |= BX_CPU_PCID; @@ -1156,24 +1158,34 @@ Bit32u bx_generic_cpuid_t::get_std2_cpuid_features(void) const Bit32u bx_generic_cpuid_t::get_ext2_cpuid_features(void) const { // ECX: - // [0:0] LAHF/SAHF instructions support in 64-bit mode - // [1:1] CMP_Legacy: Core multi-processing legacy mode (AMD) - // [2:2] SVM: Secure Virtual Machine (AMD) - // [3:3] Extended APIC Space - // [4:4] AltMovCR8: LOCK MOV CR0 means MOV CR8 - // [5:5] LZCNT: LZCNT instruction support - // [6:6] SSE4A: SSE4A Instructions support (deprecated?) - // [7:7] Misaligned SSE support - // [8:8] PREFETCHW: PREFETCHW instruction support - // [9:9] OSVW: OS visible workarounds (AMD) - // [11:10] reserved - // [12:12] SKINIT support - // [13:13] WDT: Watchdog timer support - // [31:14] reserved + // [0:0] LAHF/SAHF instructions support in 64-bit mode + // [1:1] CMP_Legacy: Core multi-processing legacy mode (AMD) + // [2:2] SVM: Secure Virtual Machine (AMD) + // [3:3] Extended APIC Space + // [4:4] AltMovCR8: LOCK MOV CR0 means MOV CR8 + // [5:5] LZCNT: LZCNT instruction support + // [6:6] SSE4A: SSE4A Instructions support (deprecated?) + // [7:7] Misaligned SSE support + // [8:8] PREFETCHW: PREFETCHW instruction support + // [9:9] OSVW: OS visible workarounds (AMD) + // [10:10] IBS: Instruction based sampling + // [11:11] XOP: Extended Operations Support and XOP Prefix + // [12:12] SKINIT support + // [13:13] WDT: Watchdog timer support + // [14:14] reserved + // [15:15] LWP: Light weight profiling + // [16:16] FMA4: Four-operand FMA instructions support + // [18:17] reserved + // [19:19] NodeId: Indicates support for NodeId MSR (0xc001100c) + // [20:20] reserved + // [21:21] TBM: trailing bit manipulation instruction support + // [22:22] Topology extensions support + // [31:23] reserved + Bit32u features = 0; #if BX_SUPPORT_X86_64 - features |= BX_CPUID_EXT2_LAHF_SAHF; + features |= BX_CPUID_EXT2_LAHF_SAHF | BX_CPUID_EXT2_PREFETCHW; #endif #if BX_SUPPORT_MISALIGNED_SSE features |= BX_CPUID_EXT2_MISALIGNED_SSE; diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index a1366f9c6..a5c7efcb0 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -950,6 +950,10 @@ void BX_CPU_C::reset(unsigned source) #endif #if BX_SUPPORT_X86_64 BX_CPU_THIS_PTR efer.set32(0); + BX_CPU_THIS_PTR efer_suppmask = (BX_EFER_SCE_MASK | BX_EFER_LME_MASK | + BX_EFER_LMA_MASK | BX_EFER_NXE_MASK); + if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_FFXSR)) + BX_CPU_THIS_PTR efer_suppmask |= BX_EFER_FFXSR_MASK; BX_CPU_THIS_PTR msr.star = 0; BX_CPU_THIS_PTR msr.lstar = 0; diff --git a/bochs/cpu/smm.cc b/bochs/cpu/smm.cc index 27546422f..3568837f6 100644 --- a/bochs/cpu/smm.cc +++ b/bochs/cpu/smm.cc @@ -569,12 +569,12 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state) return 0; } - if (temp_efer & ~BX_EFER_SUPPORTED_BITS) { - BX_PANIC(("SMM restore: Attemp to set EFER reserved bits: 0x%08x !", temp_efer)); + if (temp_efer & ~((Bit64u) BX_CPU_THIS_PTR efer_suppmask)) { + BX_PANIC(("SMM restore: Attempt to set EFER reserved bits: 0x%08x !", temp_efer)); return 0; } - BX_CPU_THIS_PTR efer.set32(temp_efer & BX_EFER_SUPPORTED_BITS); + BX_CPU_THIS_PTR efer.set32(temp_efer & BX_CPU_THIS_PTR efer_suppmask); if (BX_CPU_THIS_PTR efer.get_LMA()) { if (temp_eflags & EFlagsVMMask) { diff --git a/bochs/cpu/vmx.cc b/bochs/cpu/vmx.cc index f78aa1595..6c3b4f929 100644 --- a/bochs/cpu/vmx.cc +++ b/bochs/cpu/vmx.cc @@ -807,7 +807,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckHostState(void) #if BX_SUPPORT_VMX >= 2 if (vmexit_ctrls & VMX_VMEXIT_CTRL1_LOAD_EFER_MSR) { host_state->efer_msr = VMread64(VMCS_64BIT_HOST_IA32_EFER); - if (host_state->efer_msr & ~BX_EFER_SUPPORTED_BITS) { + if (host_state->efer_msr & ~((Bit64u) BX_CPU_THIS_PTR efer_suppmask)) { BX_ERROR(("VMFAIL: VMCS host EFER reserved bits set !")); return VMXERR_VMENTRY_INVALID_VM_HOST_STATE_FIELD; } @@ -1320,7 +1320,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification) #if BX_SUPPORT_VMX >= 2 && BX_SUPPORT_X86_64 if (vmentry_ctrls & VMX_VMENTRY_CTRL1_LOAD_EFER_MSR) { guest.efer_msr = VMread64(VMCS_64BIT_GUEST_IA32_EFER); - if (guest.efer_msr & ~BX_EFER_SUPPORTED_BITS) { + if (guest.efer_msr & ~((Bit64u) BX_CPU_THIS_PTR efer_suppmask)) { BX_ERROR(("VMENTER FAIL: VMCS guest EFER reserved bits set !")); return VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE; }