Commit 43d97b2e authored by Paolo Bonzini's avatar Paolo Bonzini

Merge tag 'kvm-x86-pat_vmx_msrs-6.12' of https://github.com/kvm-x86/linux into HEAD

KVM VMX and x86 PAT MSR macro cleanup for 6.12:

 - Add common defines for the x86 architectural memory types, i.e. the types
   that are shared across PAT, MTRRs, VMCSes, and EPTPs.

 - Clean up the various VMX MSR macros to make the code self-documenting
   (inasmuch as possible), and to make it less painful to add new macros.
parents 5d55a052 566975f6
...@@ -36,6 +36,20 @@ ...@@ -36,6 +36,20 @@
#define EFER_FFXSR (1<<_EFER_FFXSR) #define EFER_FFXSR (1<<_EFER_FFXSR)
#define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS) #define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS)
/*
* Architectural memory types that are common to MTRRs, PAT, VMX MSRs, etc.
* Most MSRs support/allow only a subset of memory types, but the values
* themselves are common across all relevant MSRs.
*/
#define X86_MEMTYPE_UC 0ull /* Uncacheable, a.k.a. Strong Uncacheable */
#define X86_MEMTYPE_WC 1ull /* Write Combining */
/* RESERVED 2 */
/* RESERVED 3 */
#define X86_MEMTYPE_WT 4ull /* Write Through */
#define X86_MEMTYPE_WP 5ull /* Write Protected */
#define X86_MEMTYPE_WB 6ull /* Write Back */
#define X86_MEMTYPE_UC_MINUS 7ull /* Weak Uncacheabled (PAT only) */
/* FRED MSRs */ /* FRED MSRs */
#define MSR_IA32_FRED_RSP0 0x1cc /* Level 0 stack pointer */ #define MSR_IA32_FRED_RSP0 0x1cc /* Level 0 stack pointer */
#define MSR_IA32_FRED_RSP1 0x1cd /* Level 1 stack pointer */ #define MSR_IA32_FRED_RSP1 0x1cd /* Level 1 stack pointer */
...@@ -363,6 +377,12 @@ ...@@ -363,6 +377,12 @@
#define MSR_IA32_CR_PAT 0x00000277 #define MSR_IA32_CR_PAT 0x00000277
#define PAT_VALUE(p0, p1, p2, p3, p4, p5, p6, p7) \
((X86_MEMTYPE_ ## p0) | (X86_MEMTYPE_ ## p1 << 8) | \
(X86_MEMTYPE_ ## p2 << 16) | (X86_MEMTYPE_ ## p3 << 24) | \
(X86_MEMTYPE_ ## p4 << 32) | (X86_MEMTYPE_ ## p5 << 40) | \
(X86_MEMTYPE_ ## p6 << 48) | (X86_MEMTYPE_ ## p7 << 56))
#define MSR_IA32_DEBUGCTLMSR 0x000001d9 #define MSR_IA32_DEBUGCTLMSR 0x000001d9
#define MSR_IA32_LASTBRANCHFROMIP 0x000001db #define MSR_IA32_LASTBRANCHFROMIP 0x000001db
#define MSR_IA32_LASTBRANCHTOIP 0x000001dc #define MSR_IA32_LASTBRANCHTOIP 0x000001dc
...@@ -1157,15 +1177,6 @@ ...@@ -1157,15 +1177,6 @@
#define MSR_IA32_VMX_VMFUNC 0x00000491 #define MSR_IA32_VMX_VMFUNC 0x00000491
#define MSR_IA32_VMX_PROCBASED_CTLS3 0x00000492 #define MSR_IA32_VMX_PROCBASED_CTLS3 0x00000492
/* VMX_BASIC bits and bitmasks */
#define VMX_BASIC_VMCS_SIZE_SHIFT 32
#define VMX_BASIC_TRUE_CTLS (1ULL << 55)
#define VMX_BASIC_64 0x0001000000000000LLU
#define VMX_BASIC_MEM_TYPE_SHIFT 50
#define VMX_BASIC_MEM_TYPE_MASK 0x003c000000000000LLU
#define VMX_BASIC_MEM_TYPE_WB 6LLU
#define VMX_BASIC_INOUT 0x0040000000000000LLU
/* Resctrl MSRs: */ /* Resctrl MSRs: */
/* - Intel: */ /* - Intel: */
#define MSR_IA32_L3_QOS_CFG 0xc81 #define MSR_IA32_L3_QOS_CFG 0xc81
...@@ -1183,11 +1194,6 @@ ...@@ -1183,11 +1194,6 @@
#define MSR_IA32_SMBA_BW_BASE 0xc0000280 #define MSR_IA32_SMBA_BW_BASE 0xc0000280
#define MSR_IA32_EVT_CFG_BASE 0xc0000400 #define MSR_IA32_EVT_CFG_BASE 0xc0000400
/* MSR_IA32_VMX_MISC bits */
#define MSR_IA32_VMX_MISC_INTEL_PT (1ULL << 14)
#define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F
/* AMD-V MSRs */ /* AMD-V MSRs */
#define MSR_VM_CR 0xc0010114 #define MSR_VM_CR 0xc0010114
#define MSR_VM_IGNNE 0xc0010115 #define MSR_VM_IGNNE 0xc0010115
......
...@@ -122,19 +122,17 @@ ...@@ -122,19 +122,17 @@
#define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff
#define VMX_MISC_PREEMPTION_TIMER_RATE_MASK 0x0000001f
#define VMX_MISC_SAVE_EFER_LMA 0x00000020
#define VMX_MISC_ACTIVITY_HLT 0x00000040
#define VMX_MISC_ACTIVITY_WAIT_SIPI 0x00000100
#define VMX_MISC_ZERO_LEN_INS 0x40000000
#define VMX_MISC_MSR_LIST_MULTIPLIER 512
/* VMFUNC functions */ /* VMFUNC functions */
#define VMFUNC_CONTROL_BIT(x) BIT((VMX_FEATURE_##x & 0x1f) - 28) #define VMFUNC_CONTROL_BIT(x) BIT((VMX_FEATURE_##x & 0x1f) - 28)
#define VMX_VMFUNC_EPTP_SWITCHING VMFUNC_CONTROL_BIT(EPTP_SWITCHING) #define VMX_VMFUNC_EPTP_SWITCHING VMFUNC_CONTROL_BIT(EPTP_SWITCHING)
#define VMFUNC_EPTP_ENTRIES 512 #define VMFUNC_EPTP_ENTRIES 512
#define VMX_BASIC_32BIT_PHYS_ADDR_ONLY BIT_ULL(48)
#define VMX_BASIC_DUAL_MONITOR_TREATMENT BIT_ULL(49)
#define VMX_BASIC_INOUT BIT_ULL(54)
#define VMX_BASIC_TRUE_CTLS BIT_ULL(55)
static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic) static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic)
{ {
return vmx_basic & GENMASK_ULL(30, 0); return vmx_basic & GENMASK_ULL(30, 0);
...@@ -145,9 +143,30 @@ static inline u32 vmx_basic_vmcs_size(u64 vmx_basic) ...@@ -145,9 +143,30 @@ static inline u32 vmx_basic_vmcs_size(u64 vmx_basic)
return (vmx_basic & GENMASK_ULL(44, 32)) >> 32; return (vmx_basic & GENMASK_ULL(44, 32)) >> 32;
} }
static inline u32 vmx_basic_vmcs_mem_type(u64 vmx_basic)
{
return (vmx_basic & GENMASK_ULL(53, 50)) >> 50;
}
static inline u64 vmx_basic_encode_vmcs_info(u32 revision, u16 size, u8 memtype)
{
return revision | ((u64)size << 32) | ((u64)memtype << 50);
}
#define VMX_MISC_SAVE_EFER_LMA BIT_ULL(5)
#define VMX_MISC_ACTIVITY_HLT BIT_ULL(6)
#define VMX_MISC_ACTIVITY_SHUTDOWN BIT_ULL(7)
#define VMX_MISC_ACTIVITY_WAIT_SIPI BIT_ULL(8)
#define VMX_MISC_INTEL_PT BIT_ULL(14)
#define VMX_MISC_RDMSR_IN_SMM BIT_ULL(15)
#define VMX_MISC_VMXOFF_BLOCK_SMI BIT_ULL(28)
#define VMX_MISC_VMWRITE_SHADOW_RO_FIELDS BIT_ULL(29)
#define VMX_MISC_ZERO_LEN_INS BIT_ULL(30)
#define VMX_MISC_MSR_LIST_MULTIPLIER 512
static inline int vmx_misc_preemption_timer_rate(u64 vmx_misc) static inline int vmx_misc_preemption_timer_rate(u64 vmx_misc)
{ {
return vmx_misc & VMX_MISC_PREEMPTION_TIMER_RATE_MASK; return vmx_misc & GENMASK_ULL(4, 0);
} }
static inline int vmx_misc_cr3_count(u64 vmx_misc) static inline int vmx_misc_cr3_count(u64 vmx_misc)
...@@ -508,9 +527,10 @@ enum vmcs_field { ...@@ -508,9 +527,10 @@ enum vmcs_field {
#define VMX_EPTP_PWL_4 0x18ull #define VMX_EPTP_PWL_4 0x18ull
#define VMX_EPTP_PWL_5 0x20ull #define VMX_EPTP_PWL_5 0x20ull
#define VMX_EPTP_AD_ENABLE_BIT (1ull << 6) #define VMX_EPTP_AD_ENABLE_BIT (1ull << 6)
/* The EPTP memtype is encoded in bits 2:0, i.e. doesn't need to be shifted. */
#define VMX_EPTP_MT_MASK 0x7ull #define VMX_EPTP_MT_MASK 0x7ull
#define VMX_EPTP_MT_WB 0x6ull #define VMX_EPTP_MT_WB X86_MEMTYPE_WB
#define VMX_EPTP_MT_UC 0x0ull #define VMX_EPTP_MT_UC X86_MEMTYPE_UC
#define VMX_EPT_READABLE_MASK 0x1ull #define VMX_EPT_READABLE_MASK 0x1ull
#define VMX_EPT_WRITABLE_MASK 0x2ull #define VMX_EPT_WRITABLE_MASK 0x2ull
#define VMX_EPT_EXECUTABLE_MASK 0x4ull #define VMX_EPT_EXECUTABLE_MASK 0x4ull
......
...@@ -55,6 +55,12 @@ ...@@ -55,6 +55,12 @@
#include "mtrr.h" #include "mtrr.h"
static_assert(X86_MEMTYPE_UC == MTRR_TYPE_UNCACHABLE);
static_assert(X86_MEMTYPE_WC == MTRR_TYPE_WRCOMB);
static_assert(X86_MEMTYPE_WT == MTRR_TYPE_WRTHROUGH);
static_assert(X86_MEMTYPE_WP == MTRR_TYPE_WRPROT);
static_assert(X86_MEMTYPE_WB == MTRR_TYPE_WRBACK);
/* arch_phys_wc_add returns an MTRR register index plus this offset. */ /* arch_phys_wc_add returns an MTRR register index plus this offset. */
#define MTRR_TO_PHYS_WC_OFFSET 1000 #define MTRR_TO_PHYS_WC_OFFSET 1000
......
...@@ -54,9 +54,7 @@ struct nested_vmx_msrs { ...@@ -54,9 +54,7 @@ struct nested_vmx_msrs {
}; };
struct vmcs_config { struct vmcs_config {
int size; u64 basic;
u32 basic_cap;
u32 revision_id;
u32 pin_based_exec_ctrl; u32 pin_based_exec_ctrl;
u32 cpu_based_exec_ctrl; u32 cpu_based_exec_ctrl;
u32 cpu_based_2nd_exec_ctrl; u32 cpu_based_2nd_exec_ctrl;
...@@ -76,7 +74,7 @@ extern struct vmx_capability vmx_capability __ro_after_init; ...@@ -76,7 +74,7 @@ extern struct vmx_capability vmx_capability __ro_after_init;
static inline bool cpu_has_vmx_basic_inout(void) static inline bool cpu_has_vmx_basic_inout(void)
{ {
return (((u64)vmcs_config.basic_cap << 32) & VMX_BASIC_INOUT); return vmcs_config.basic & VMX_BASIC_INOUT;
} }
static inline bool cpu_has_virtual_nmis(void) static inline bool cpu_has_virtual_nmis(void)
...@@ -225,7 +223,7 @@ static inline bool cpu_has_vmx_vmfunc(void) ...@@ -225,7 +223,7 @@ static inline bool cpu_has_vmx_vmfunc(void)
static inline bool cpu_has_vmx_shadow_vmcs(void) static inline bool cpu_has_vmx_shadow_vmcs(void)
{ {
/* check if the cpu supports writing r/o exit information fields */ /* check if the cpu supports writing r/o exit information fields */
if (!(vmcs_config.misc & MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS)) if (!(vmcs_config.misc & VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
return false; return false;
return vmcs_config.cpu_based_2nd_exec_ctrl & return vmcs_config.cpu_based_2nd_exec_ctrl &
...@@ -367,7 +365,7 @@ static inline bool cpu_has_vmx_invvpid_global(void) ...@@ -367,7 +365,7 @@ static inline bool cpu_has_vmx_invvpid_global(void)
static inline bool cpu_has_vmx_intel_pt(void) static inline bool cpu_has_vmx_intel_pt(void)
{ {
return (vmcs_config.misc & MSR_IA32_VMX_MISC_INTEL_PT) && return (vmcs_config.misc & VMX_MISC_INTEL_PT) &&
(vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) && (vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) &&
(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL); (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
} }
......
...@@ -1251,21 +1251,32 @@ static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask) ...@@ -1251,21 +1251,32 @@ static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask)
static int vmx_restore_vmx_basic(struct vcpu_vmx *vmx, u64 data) static int vmx_restore_vmx_basic(struct vcpu_vmx *vmx, u64 data)
{ {
const u64 feature_and_reserved = const u64 feature_bits = VMX_BASIC_DUAL_MONITOR_TREATMENT |
/* feature (except bit 48; see below) */ VMX_BASIC_INOUT |
BIT_ULL(49) | BIT_ULL(54) | BIT_ULL(55) | VMX_BASIC_TRUE_CTLS;
/* reserved */
BIT_ULL(31) | GENMASK_ULL(47, 45) | GENMASK_ULL(63, 56); const u64 reserved_bits = GENMASK_ULL(63, 56) |
GENMASK_ULL(47, 45) |
BIT_ULL(31);
u64 vmx_basic = vmcs_config.nested.basic; u64 vmx_basic = vmcs_config.nested.basic;
if (!is_bitwise_subset(vmx_basic, data, feature_and_reserved)) BUILD_BUG_ON(feature_bits & reserved_bits);
/*
* Except for 32BIT_PHYS_ADDR_ONLY, which is an anti-feature bit (has
* inverted polarity), the incoming value must not set feature bits or
* reserved bits that aren't allowed/supported by KVM. Fields, i.e.
* multi-bit values, are explicitly checked below.
*/
if (!is_bitwise_subset(vmx_basic, data, feature_bits | reserved_bits))
return -EINVAL; return -EINVAL;
/* /*
* KVM does not emulate a version of VMX that constrains physical * KVM does not emulate a version of VMX that constrains physical
* addresses of VMX structures (e.g. VMCS) to 32-bits. * addresses of VMX structures (e.g. VMCS) to 32-bits.
*/ */
if (data & BIT_ULL(48)) if (data & VMX_BASIC_32BIT_PHYS_ADDR_ONLY)
return -EINVAL; return -EINVAL;
if (vmx_basic_vmcs_revision_id(vmx_basic) != if (vmx_basic_vmcs_revision_id(vmx_basic) !=
...@@ -1334,16 +1345,29 @@ vmx_restore_control_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data) ...@@ -1334,16 +1345,29 @@ vmx_restore_control_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data)
static int vmx_restore_vmx_misc(struct vcpu_vmx *vmx, u64 data) static int vmx_restore_vmx_misc(struct vcpu_vmx *vmx, u64 data)
{ {
const u64 feature_and_reserved_bits = const u64 feature_bits = VMX_MISC_SAVE_EFER_LMA |
/* feature */ VMX_MISC_ACTIVITY_HLT |
BIT_ULL(5) | GENMASK_ULL(8, 6) | BIT_ULL(14) | BIT_ULL(15) | VMX_MISC_ACTIVITY_SHUTDOWN |
BIT_ULL(28) | BIT_ULL(29) | BIT_ULL(30) | VMX_MISC_ACTIVITY_WAIT_SIPI |
/* reserved */ VMX_MISC_INTEL_PT |
GENMASK_ULL(13, 9) | BIT_ULL(31); VMX_MISC_RDMSR_IN_SMM |
VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
VMX_MISC_VMXOFF_BLOCK_SMI |
VMX_MISC_ZERO_LEN_INS;
const u64 reserved_bits = BIT_ULL(31) | GENMASK_ULL(13, 9);
u64 vmx_misc = vmx_control_msr(vmcs_config.nested.misc_low, u64 vmx_misc = vmx_control_msr(vmcs_config.nested.misc_low,
vmcs_config.nested.misc_high); vmcs_config.nested.misc_high);
if (!is_bitwise_subset(vmx_misc, data, feature_and_reserved_bits)) BUILD_BUG_ON(feature_bits & reserved_bits);
/*
* The incoming value must not set feature bits or reserved bits that
* aren't allowed/supported by KVM. Fields, i.e. multi-bit values, are
* explicitly checked below.
*/
if (!is_bitwise_subset(vmx_misc, data, feature_bits | reserved_bits))
return -EINVAL; return -EINVAL;
if ((vmx->nested.msrs.pinbased_ctls_high & if ((vmx->nested.msrs.pinbased_ctls_high &
...@@ -7051,7 +7075,7 @@ static void nested_vmx_setup_misc_data(struct vmcs_config *vmcs_conf, ...@@ -7051,7 +7075,7 @@ static void nested_vmx_setup_misc_data(struct vmcs_config *vmcs_conf,
{ {
msrs->misc_low = (u32)vmcs_conf->misc & VMX_MISC_SAVE_EFER_LMA; msrs->misc_low = (u32)vmcs_conf->misc & VMX_MISC_SAVE_EFER_LMA;
msrs->misc_low |= msrs->misc_low |=
MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS | VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE | VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE |
VMX_MISC_ACTIVITY_HLT | VMX_MISC_ACTIVITY_HLT |
VMX_MISC_ACTIVITY_WAIT_SIPI; VMX_MISC_ACTIVITY_WAIT_SIPI;
...@@ -7066,12 +7090,10 @@ static void nested_vmx_setup_basic(struct nested_vmx_msrs *msrs) ...@@ -7066,12 +7090,10 @@ static void nested_vmx_setup_basic(struct nested_vmx_msrs *msrs)
* guest, and the VMCS structure we give it - not about the * guest, and the VMCS structure we give it - not about the
* VMX support of the underlying hardware. * VMX support of the underlying hardware.
*/ */
msrs->basic = msrs->basic = vmx_basic_encode_vmcs_info(VMCS12_REVISION, VMCS12_SIZE,
VMCS12_REVISION | X86_MEMTYPE_WB);
VMX_BASIC_TRUE_CTLS |
((u64)VMCS12_SIZE << VMX_BASIC_VMCS_SIZE_SHIFT) |
(VMX_BASIC_MEM_TYPE_WB << VMX_BASIC_MEM_TYPE_SHIFT);
msrs->basic |= VMX_BASIC_TRUE_CTLS;
if (cpu_has_vmx_basic_inout()) if (cpu_has_vmx_basic_inout())
msrs->basic |= VMX_BASIC_INOUT; msrs->basic |= VMX_BASIC_INOUT;
} }
......
...@@ -109,7 +109,7 @@ static inline unsigned nested_cpu_vmx_misc_cr3_count(struct kvm_vcpu *vcpu) ...@@ -109,7 +109,7 @@ static inline unsigned nested_cpu_vmx_misc_cr3_count(struct kvm_vcpu *vcpu)
static inline bool nested_cpu_has_vmwrite_any_field(struct kvm_vcpu *vcpu) static inline bool nested_cpu_has_vmwrite_any_field(struct kvm_vcpu *vcpu)
{ {
return to_vmx(vcpu)->nested.msrs.misc_low & return to_vmx(vcpu)->nested.msrs.misc_low &
MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS; VMX_MISC_VMWRITE_SHADOW_RO_FIELDS;
} }
static inline bool nested_cpu_has_zero_length_injection(struct kvm_vcpu *vcpu) static inline bool nested_cpu_has_zero_length_injection(struct kvm_vcpu *vcpu)
......
...@@ -2605,13 +2605,13 @@ static u64 adjust_vmx_controls64(u64 ctl_opt, u32 msr) ...@@ -2605,13 +2605,13 @@ static u64 adjust_vmx_controls64(u64 ctl_opt, u32 msr)
static int setup_vmcs_config(struct vmcs_config *vmcs_conf, static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
struct vmx_capability *vmx_cap) struct vmx_capability *vmx_cap)
{ {
u32 vmx_msr_low, vmx_msr_high;
u32 _pin_based_exec_control = 0; u32 _pin_based_exec_control = 0;
u32 _cpu_based_exec_control = 0; u32 _cpu_based_exec_control = 0;
u32 _cpu_based_2nd_exec_control = 0; u32 _cpu_based_2nd_exec_control = 0;
u64 _cpu_based_3rd_exec_control = 0; u64 _cpu_based_3rd_exec_control = 0;
u32 _vmexit_control = 0; u32 _vmexit_control = 0;
u32 _vmentry_control = 0; u32 _vmentry_control = 0;
u64 basic_msr;
u64 misc_msr; u64 misc_msr;
int i; int i;
...@@ -2734,29 +2734,29 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf, ...@@ -2734,29 +2734,29 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
_vmexit_control &= ~x_ctrl; _vmexit_control &= ~x_ctrl;
} }
rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high); rdmsrl(MSR_IA32_VMX_BASIC, basic_msr);
/* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */ /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
if ((vmx_msr_high & 0x1fff) > PAGE_SIZE) if (vmx_basic_vmcs_size(basic_msr) > PAGE_SIZE)
return -EIO; return -EIO;
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
/* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */ /*
if (vmx_msr_high & (1u<<16)) * KVM expects to be able to shove all legal physical addresses into
* VMCS fields for 64-bit kernels, and per the SDM, "This bit is always
* 0 for processors that support Intel 64 architecture".
*/
if (basic_msr & VMX_BASIC_32BIT_PHYS_ADDR_ONLY)
return -EIO; return -EIO;
#endif #endif
/* Require Write-Back (WB) memory type for VMCS accesses. */ /* Require Write-Back (WB) memory type for VMCS accesses. */
if (((vmx_msr_high >> 18) & 15) != 6) if (vmx_basic_vmcs_mem_type(basic_msr) != X86_MEMTYPE_WB)
return -EIO; return -EIO;
rdmsrl(MSR_IA32_VMX_MISC, misc_msr); rdmsrl(MSR_IA32_VMX_MISC, misc_msr);
vmcs_conf->size = vmx_msr_high & 0x1fff; vmcs_conf->basic = basic_msr;
vmcs_conf->basic_cap = vmx_msr_high & ~0x1fff;
vmcs_conf->revision_id = vmx_msr_low;
vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control; vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control;
vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control; vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control;
vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control; vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control;
...@@ -2903,13 +2903,13 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags) ...@@ -2903,13 +2903,13 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags)
if (!pages) if (!pages)
return NULL; return NULL;
vmcs = page_address(pages); vmcs = page_address(pages);
memset(vmcs, 0, vmcs_config.size); memset(vmcs, 0, vmx_basic_vmcs_size(vmcs_config.basic));
/* KVM supports Enlightened VMCS v1 only */ /* KVM supports Enlightened VMCS v1 only */
if (kvm_is_using_evmcs()) if (kvm_is_using_evmcs())
vmcs->hdr.revision_id = KVM_EVMCS_VERSION; vmcs->hdr.revision_id = KVM_EVMCS_VERSION;
else else
vmcs->hdr.revision_id = vmcs_config.revision_id; vmcs->hdr.revision_id = vmx_basic_vmcs_revision_id(vmcs_config.basic);
if (shadow) if (shadow)
vmcs->hdr.shadow_vmcs = 1; vmcs->hdr.shadow_vmcs = 1;
...@@ -3002,7 +3002,7 @@ static __init int alloc_kvm_area(void) ...@@ -3002,7 +3002,7 @@ static __init int alloc_kvm_area(void)
* physical CPU. * physical CPU.
*/ */
if (kvm_is_using_evmcs()) if (kvm_is_using_evmcs())
vmcs->hdr.revision_id = vmcs_config.revision_id; vmcs->hdr.revision_id = vmx_basic_vmcs_revision_id(vmcs_config.basic);
per_cpu(vmxarea, cpu) = vmcs; per_cpu(vmxarea, cpu) = vmcs;
} }
...@@ -8519,7 +8519,7 @@ __init int vmx_hardware_setup(void) ...@@ -8519,7 +8519,7 @@ __init int vmx_hardware_setup(void)
u64 use_timer_freq = 5000ULL * 1000 * 1000; u64 use_timer_freq = 5000ULL * 1000 * 1000;
cpu_preemption_timer_multi = cpu_preemption_timer_multi =
vmcs_config.misc & VMX_MISC_PREEMPTION_TIMER_RATE_MASK; vmx_misc_preemption_timer_rate(vmcs_config.misc);
if (tsc_khz) if (tsc_khz)
use_timer_freq = (u64)tsc_khz * 1000; use_timer_freq = (u64)tsc_khz * 1000;
......
...@@ -12295,8 +12295,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) ...@@ -12295,8 +12295,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
vcpu->arch.reserved_gpa_bits = kvm_vcpu_reserved_gpa_bits_raw(vcpu); vcpu->arch.reserved_gpa_bits = kvm_vcpu_reserved_gpa_bits_raw(vcpu);
vcpu->arch.pat = MSR_IA32_CR_PAT_DEFAULT;
kvm_async_pf_hash_reset(vcpu); kvm_async_pf_hash_reset(vcpu);
vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap; vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap;
...@@ -12462,6 +12460,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) ...@@ -12462,6 +12460,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
if (!init_event) { if (!init_event) {
vcpu->arch.smbase = 0x30000; vcpu->arch.smbase = 0x30000;
vcpu->arch.pat = MSR_IA32_CR_PAT_DEFAULT;
vcpu->arch.msr_misc_features_enables = 0; vcpu->arch.msr_misc_features_enables = 0;
vcpu->arch.ia32_misc_enable_msr = MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL | vcpu->arch.ia32_misc_enable_msr = MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL |
MSR_IA32_MISC_ENABLE_BTS_UNAVAIL; MSR_IA32_MISC_ENABLE_BTS_UNAVAIL;
......
...@@ -103,7 +103,8 @@ static inline unsigned int __shrink_ple_window(unsigned int val, ...@@ -103,7 +103,8 @@ static inline unsigned int __shrink_ple_window(unsigned int val,
return max(val, min); return max(val, min);
} }
#define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL #define MSR_IA32_CR_PAT_DEFAULT \
PAT_VALUE(WB, WT, UC_MINUS, UC, WB, WT, UC_MINUS, UC)
void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu); void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu);
int kvm_check_nested_events(struct kvm_vcpu *vcpu); int kvm_check_nested_events(struct kvm_vcpu *vcpu);
......
...@@ -176,15 +176,6 @@ static inline void set_page_memtype(struct page *pg, ...@@ -176,15 +176,6 @@ static inline void set_page_memtype(struct page *pg,
} }
#endif #endif
enum {
PAT_UC = 0, /* uncached */
PAT_WC = 1, /* Write combining */
PAT_WT = 4, /* Write Through */
PAT_WP = 5, /* Write Protected */
PAT_WB = 6, /* Write Back (default) */
PAT_UC_MINUS = 7, /* UC, but can be overridden by MTRR */
};
#define CM(c) (_PAGE_CACHE_MODE_ ## c) #define CM(c) (_PAGE_CACHE_MODE_ ## c)
static enum page_cache_mode __init pat_get_cache_mode(unsigned int pat_val, static enum page_cache_mode __init pat_get_cache_mode(unsigned int pat_val,
...@@ -194,12 +185,12 @@ static enum page_cache_mode __init pat_get_cache_mode(unsigned int pat_val, ...@@ -194,12 +185,12 @@ static enum page_cache_mode __init pat_get_cache_mode(unsigned int pat_val,
char *cache_mode; char *cache_mode;
switch (pat_val) { switch (pat_val) {
case PAT_UC: cache = CM(UC); cache_mode = "UC "; break; case X86_MEMTYPE_UC: cache = CM(UC); cache_mode = "UC "; break;
case PAT_WC: cache = CM(WC); cache_mode = "WC "; break; case X86_MEMTYPE_WC: cache = CM(WC); cache_mode = "WC "; break;
case PAT_WT: cache = CM(WT); cache_mode = "WT "; break; case X86_MEMTYPE_WT: cache = CM(WT); cache_mode = "WT "; break;
case PAT_WP: cache = CM(WP); cache_mode = "WP "; break; case X86_MEMTYPE_WP: cache = CM(WP); cache_mode = "WP "; break;
case PAT_WB: cache = CM(WB); cache_mode = "WB "; break; case X86_MEMTYPE_WB: cache = CM(WB); cache_mode = "WB "; break;
case PAT_UC_MINUS: cache = CM(UC_MINUS); cache_mode = "UC- "; break; case X86_MEMTYPE_UC_MINUS: cache = CM(UC_MINUS); cache_mode = "UC- "; break;
default: cache = CM(WB); cache_mode = "WB "; break; default: cache = CM(WB); cache_mode = "WB "; break;
} }
...@@ -257,12 +248,6 @@ void pat_cpu_init(void) ...@@ -257,12 +248,6 @@ void pat_cpu_init(void)
void __init pat_bp_init(void) void __init pat_bp_init(void)
{ {
struct cpuinfo_x86 *c = &boot_cpu_data; struct cpuinfo_x86 *c = &boot_cpu_data;
#define PAT(p0, p1, p2, p3, p4, p5, p6, p7) \
(((u64)PAT_ ## p0) | ((u64)PAT_ ## p1 << 8) | \
((u64)PAT_ ## p2 << 16) | ((u64)PAT_ ## p3 << 24) | \
((u64)PAT_ ## p4 << 32) | ((u64)PAT_ ## p5 << 40) | \
((u64)PAT_ ## p6 << 48) | ((u64)PAT_ ## p7 << 56))
if (!IS_ENABLED(CONFIG_X86_PAT)) if (!IS_ENABLED(CONFIG_X86_PAT))
pr_info_once("x86/PAT: PAT support disabled because CONFIG_X86_PAT is disabled in the kernel.\n"); pr_info_once("x86/PAT: PAT support disabled because CONFIG_X86_PAT is disabled in the kernel.\n");
...@@ -293,7 +278,7 @@ void __init pat_bp_init(void) ...@@ -293,7 +278,7 @@ void __init pat_bp_init(void)
* NOTE: When WC or WP is used, it is redirected to UC- per * NOTE: When WC or WP is used, it is redirected to UC- per
* the default setup in __cachemode2pte_tbl[]. * the default setup in __cachemode2pte_tbl[].
*/ */
pat_msr_val = PAT(WB, WT, UC_MINUS, UC, WB, WT, UC_MINUS, UC); pat_msr_val = PAT_VALUE(WB, WT, UC_MINUS, UC, WB, WT, UC_MINUS, UC);
} }
/* /*
...@@ -328,7 +313,7 @@ void __init pat_bp_init(void) ...@@ -328,7 +313,7 @@ void __init pat_bp_init(void)
* NOTE: When WT or WP is used, it is redirected to UC- per * NOTE: When WT or WP is used, it is redirected to UC- per
* the default setup in __cachemode2pte_tbl[]. * the default setup in __cachemode2pte_tbl[].
*/ */
pat_msr_val = PAT(WB, WC, UC_MINUS, UC, WB, WC, UC_MINUS, UC); pat_msr_val = PAT_VALUE(WB, WC, UC_MINUS, UC, WB, WC, UC_MINUS, UC);
} else { } else {
/* /*
* Full PAT support. We put WT in slot 7 to improve * Full PAT support. We put WT in slot 7 to improve
...@@ -356,13 +341,12 @@ void __init pat_bp_init(void) ...@@ -356,13 +341,12 @@ void __init pat_bp_init(void)
* The reserved slots are unused, but mapped to their * The reserved slots are unused, but mapped to their
* corresponding types in the presence of PAT errata. * corresponding types in the presence of PAT errata.
*/ */
pat_msr_val = PAT(WB, WC, UC_MINUS, UC, WB, WP, UC_MINUS, WT); pat_msr_val = PAT_VALUE(WB, WC, UC_MINUS, UC, WB, WP, UC_MINUS, WT);
} }
memory_caching_control |= CACHE_PAT; memory_caching_control |= CACHE_PAT;
init_cache_modes(pat_msr_val); init_cache_modes(pat_msr_val);
#undef PAT
} }
static DEFINE_SPINLOCK(memtype_lock); /* protects memtype accesses */ static DEFINE_SPINLOCK(memtype_lock); /* protects memtype accesses */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment