mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:38:03 +00:00
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.
This commit is contained in:
commit
43d97b2ebd
@ -36,6 +36,20 @@
|
||||
#define EFER_FFXSR (1<<_EFER_FFXSR)
|
||||
#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 */
|
||||
#define MSR_IA32_FRED_RSP0 0x1cc /* Level 0 stack pointer */
|
||||
#define MSR_IA32_FRED_RSP1 0x1cd /* Level 1 stack pointer */
|
||||
@ -363,6 +377,12 @@
|
||||
|
||||
#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_LASTBRANCHFROMIP 0x000001db
|
||||
#define MSR_IA32_LASTBRANCHTOIP 0x000001dc
|
||||
@ -1157,15 +1177,6 @@
|
||||
#define MSR_IA32_VMX_VMFUNC 0x00000491
|
||||
#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: */
|
||||
/* - Intel: */
|
||||
#define MSR_IA32_L3_QOS_CFG 0xc81
|
||||
@ -1183,11 +1194,6 @@
|
||||
#define MSR_IA32_SMBA_BW_BASE 0xc0000280
|
||||
#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 */
|
||||
#define MSR_VM_CR 0xc0010114
|
||||
#define MSR_VM_IGNNE 0xc0010115
|
||||
|
@ -122,19 +122,17 @@
|
||||
|
||||
#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 */
|
||||
#define VMFUNC_CONTROL_BIT(x) BIT((VMX_FEATURE_##x & 0x1f) - 28)
|
||||
|
||||
#define VMX_VMFUNC_EPTP_SWITCHING VMFUNC_CONTROL_BIT(EPTP_SWITCHING)
|
||||
#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)
|
||||
{
|
||||
return vmx_basic & GENMASK_ULL(30, 0);
|
||||
@ -145,9 +143,30 @@ static inline u32 vmx_basic_vmcs_size(u64 vmx_basic)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -508,9 +527,10 @@ enum vmcs_field {
|
||||
#define VMX_EPTP_PWL_4 0x18ull
|
||||
#define VMX_EPTP_PWL_5 0x20ull
|
||||
#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_WB 0x6ull
|
||||
#define VMX_EPTP_MT_UC 0x0ull
|
||||
#define VMX_EPTP_MT_WB X86_MEMTYPE_WB
|
||||
#define VMX_EPTP_MT_UC X86_MEMTYPE_UC
|
||||
#define VMX_EPT_READABLE_MASK 0x1ull
|
||||
#define VMX_EPT_WRITABLE_MASK 0x2ull
|
||||
#define VMX_EPT_EXECUTABLE_MASK 0x4ull
|
||||
|
@ -55,6 +55,12 @@
|
||||
|
||||
#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. */
|
||||
#define MTRR_TO_PHYS_WC_OFFSET 1000
|
||||
|
||||
|
@ -54,9 +54,7 @@ struct nested_vmx_msrs {
|
||||
};
|
||||
|
||||
struct vmcs_config {
|
||||
int size;
|
||||
u32 basic_cap;
|
||||
u32 revision_id;
|
||||
u64 basic;
|
||||
u32 pin_based_exec_ctrl;
|
||||
u32 cpu_based_exec_ctrl;
|
||||
u32 cpu_based_2nd_exec_ctrl;
|
||||
@ -76,7 +74,7 @@ extern struct vmx_capability vmx_capability __ro_after_init;
|
||||
|
||||
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)
|
||||
@ -225,7 +223,7 @@ static inline bool cpu_has_vmx_vmfunc(void)
|
||||
static inline bool cpu_has_vmx_shadow_vmcs(void)
|
||||
{
|
||||
/* 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 vmcs_config.cpu_based_2nd_exec_ctrl &
|
||||
@ -367,7 +365,7 @@ static inline bool cpu_has_vmx_invvpid_global(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.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
const u64 feature_and_reserved =
|
||||
/* feature (except bit 48; see below) */
|
||||
BIT_ULL(49) | BIT_ULL(54) | BIT_ULL(55) |
|
||||
/* reserved */
|
||||
BIT_ULL(31) | GENMASK_ULL(47, 45) | GENMASK_ULL(63, 56);
|
||||
const u64 feature_bits = VMX_BASIC_DUAL_MONITOR_TREATMENT |
|
||||
VMX_BASIC_INOUT |
|
||||
VMX_BASIC_TRUE_CTLS;
|
||||
|
||||
const u64 reserved_bits = GENMASK_ULL(63, 56) |
|
||||
GENMASK_ULL(47, 45) |
|
||||
BIT_ULL(31);
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* KVM does not emulate a version of VMX that constrains physical
|
||||
* 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;
|
||||
|
||||
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)
|
||||
|
||||
static int vmx_restore_vmx_misc(struct vcpu_vmx *vmx, u64 data)
|
||||
{
|
||||
const u64 feature_and_reserved_bits =
|
||||
/* feature */
|
||||
BIT_ULL(5) | GENMASK_ULL(8, 6) | BIT_ULL(14) | BIT_ULL(15) |
|
||||
BIT_ULL(28) | BIT_ULL(29) | BIT_ULL(30) |
|
||||
/* reserved */
|
||||
GENMASK_ULL(13, 9) | BIT_ULL(31);
|
||||
const u64 feature_bits = VMX_MISC_SAVE_EFER_LMA |
|
||||
VMX_MISC_ACTIVITY_HLT |
|
||||
VMX_MISC_ACTIVITY_SHUTDOWN |
|
||||
VMX_MISC_ACTIVITY_WAIT_SIPI |
|
||||
VMX_MISC_INTEL_PT |
|
||||
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,
|
||||
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;
|
||||
|
||||
if ((vmx->nested.msrs.pinbased_ctls_high &
|
||||
@ -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 |=
|
||||
MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
|
||||
VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
|
||||
VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE |
|
||||
VMX_MISC_ACTIVITY_HLT |
|
||||
VMX_MISC_ACTIVITY_WAIT_SIPI;
|
||||
@ -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
|
||||
* VMX support of the underlying hardware.
|
||||
*/
|
||||
msrs->basic =
|
||||
VMCS12_REVISION |
|
||||
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_encode_vmcs_info(VMCS12_REVISION, VMCS12_SIZE,
|
||||
X86_MEMTYPE_WB);
|
||||
|
||||
msrs->basic |= VMX_BASIC_TRUE_CTLS;
|
||||
if (cpu_has_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)
|
||||
static inline bool nested_cpu_has_vmwrite_any_field(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
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)
|
||||
|
@ -2605,13 +2605,13 @@ static u64 adjust_vmx_controls64(u64 ctl_opt, u32 msr)
|
||||
static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
|
||||
struct vmx_capability *vmx_cap)
|
||||
{
|
||||
u32 vmx_msr_low, vmx_msr_high;
|
||||
u32 _pin_based_exec_control = 0;
|
||||
u32 _cpu_based_exec_control = 0;
|
||||
u32 _cpu_based_2nd_exec_control = 0;
|
||||
u64 _cpu_based_3rd_exec_control = 0;
|
||||
u32 _vmexit_control = 0;
|
||||
u32 _vmentry_control = 0;
|
||||
u64 basic_msr;
|
||||
u64 misc_msr;
|
||||
int i;
|
||||
|
||||
@ -2734,29 +2734,29 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
|
||||
_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. */
|
||||
if ((vmx_msr_high & 0x1fff) > PAGE_SIZE)
|
||||
if (vmx_basic_vmcs_size(basic_msr) > PAGE_SIZE)
|
||||
return -EIO;
|
||||
|
||||
#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;
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
|
||||
rdmsrl(MSR_IA32_VMX_MISC, misc_msr);
|
||||
|
||||
vmcs_conf->size = vmx_msr_high & 0x1fff;
|
||||
vmcs_conf->basic_cap = vmx_msr_high & ~0x1fff;
|
||||
|
||||
vmcs_conf->revision_id = vmx_msr_low;
|
||||
|
||||
vmcs_conf->basic = basic_msr;
|
||||
vmcs_conf->pin_based_exec_ctrl = _pin_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;
|
||||
@ -2903,13 +2903,13 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags)
|
||||
if (!pages)
|
||||
return NULL;
|
||||
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 */
|
||||
if (kvm_is_using_evmcs())
|
||||
vmcs->hdr.revision_id = KVM_EVMCS_VERSION;
|
||||
else
|
||||
vmcs->hdr.revision_id = vmcs_config.revision_id;
|
||||
vmcs->hdr.revision_id = vmx_basic_vmcs_revision_id(vmcs_config.basic);
|
||||
|
||||
if (shadow)
|
||||
vmcs->hdr.shadow_vmcs = 1;
|
||||
@ -3002,7 +3002,7 @@ static __init int alloc_kvm_area(void)
|
||||
* physical CPU.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -8519,7 +8519,7 @@ __init int vmx_hardware_setup(void)
|
||||
u64 use_timer_freq = 5000ULL * 1000 * 1000;
|
||||
|
||||
cpu_preemption_timer_multi =
|
||||
vmcs_config.misc & VMX_MISC_PREEMPTION_TIMER_RATE_MASK;
|
||||
vmx_misc_preemption_timer_rate(vmcs_config.misc);
|
||||
|
||||
if (tsc_khz)
|
||||
use_timer_freq = (u64)tsc_khz * 1000;
|
||||
|
@ -12295,8 +12295,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(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);
|
||||
|
||||
vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap;
|
||||
@ -12462,6 +12460,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
|
||||
if (!init_event) {
|
||||
vcpu->arch.smbase = 0x30000;
|
||||
|
||||
vcpu->arch.pat = MSR_IA32_CR_PAT_DEFAULT;
|
||||
|
||||
vcpu->arch.msr_misc_features_enables = 0;
|
||||
vcpu->arch.ia32_misc_enable_msr = MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL |
|
||||
MSR_IA32_MISC_ENABLE_BTS_UNAVAIL;
|
||||
|
@ -103,7 +103,8 @@ static inline unsigned int __shrink_ple_window(unsigned int val,
|
||||
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);
|
||||
int kvm_check_nested_events(struct kvm_vcpu *vcpu);
|
||||
|
@ -176,15 +176,6 @@ static inline void set_page_memtype(struct page *pg,
|
||||
}
|
||||
#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)
|
||||
|
||||
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;
|
||||
|
||||
switch (pat_val) {
|
||||
case PAT_UC: cache = CM(UC); cache_mode = "UC "; break;
|
||||
case PAT_WC: cache = CM(WC); cache_mode = "WC "; break;
|
||||
case PAT_WT: cache = CM(WT); cache_mode = "WT "; break;
|
||||
case PAT_WP: cache = CM(WP); cache_mode = "WP "; break;
|
||||
case PAT_WB: cache = CM(WB); cache_mode = "WB "; break;
|
||||
case PAT_UC_MINUS: cache = CM(UC_MINUS); cache_mode = "UC- "; break;
|
||||
case X86_MEMTYPE_UC: cache = CM(UC); cache_mode = "UC "; break;
|
||||
case X86_MEMTYPE_WC: cache = CM(WC); cache_mode = "WC "; break;
|
||||
case X86_MEMTYPE_WT: cache = CM(WT); cache_mode = "WT "; break;
|
||||
case X86_MEMTYPE_WP: cache = CM(WP); cache_mode = "WP "; break;
|
||||
case X86_MEMTYPE_WB: cache = CM(WB); cache_mode = "WB "; break;
|
||||
case X86_MEMTYPE_UC_MINUS: cache = CM(UC_MINUS); cache_mode = "UC- "; break;
|
||||
default: cache = CM(WB); cache_mode = "WB "; break;
|
||||
}
|
||||
|
||||
@ -257,12 +248,6 @@ void pat_cpu_init(void)
|
||||
void __init pat_bp_init(void)
|
||||
{
|
||||
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))
|
||||
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)
|
||||
* NOTE: When WC or WP is used, it is redirected to UC- per
|
||||
* 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)
|
||||
* NOTE: When WT or WP is used, it is redirected to UC- per
|
||||
* 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 {
|
||||
/*
|
||||
* Full PAT support. We put WT in slot 7 to improve
|
||||
@ -356,13 +341,12 @@ void __init pat_bp_init(void)
|
||||
* The reserved slots are unused, but mapped to their
|
||||
* 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;
|
||||
|
||||
init_cache_modes(pat_msr_val);
|
||||
#undef PAT
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(memtype_lock); /* protects memtype accesses */
|
||||
|
Loading…
Reference in New Issue
Block a user