mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-26 15:31:35 +00:00
hv: intercept IA32_PAT MSR
Preparing for emulating guest's CR0.CD and CR0.NW bits: - Intercept both rdmsr and wrmsr for IA32_PAT - Track guest's IA32_PAT MSR with vcpu.arch_vcpu.contexts.ia32_pat Signed-off-by: Zide Chen <zide.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
873e90cd9a
commit
6801d826e2
@ -13,6 +13,7 @@ static const uint32_t emulated_msrs[] = {
|
||||
MSR_IA32_BIOS_UPDT_TRIG, /* Enable MSR_IA32_BIOS_UPDT_TRIG */
|
||||
MSR_IA32_BIOS_SIGN_ID, /* Enable MSR_IA32_BIOS_SIGN_ID */
|
||||
MSR_IA32_TIME_STAMP_COUNTER,
|
||||
MSR_IA32_PAT,
|
||||
|
||||
/* following MSR not emulated now */
|
||||
/*
|
||||
@ -205,6 +206,11 @@ int rdmsr_vmexit_handler(struct vcpu *vcpu)
|
||||
v = exec_vmread(VMX_GUEST_IA32_SYSENTER_EIP);
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_PAT:
|
||||
{
|
||||
v = vmx_rdmsr_pat(vcpu);
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_TSC_AUX:
|
||||
{
|
||||
v = vcpu->arch_vcpu.msr_tsc_aux;
|
||||
@ -330,6 +336,11 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu)
|
||||
exec_vmwrite(VMX_GUEST_IA32_SYSENTER_EIP, v);
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_PAT:
|
||||
{
|
||||
vmx_wrmsr_pat(vcpu, v);
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_GS_BASE:
|
||||
{
|
||||
exec_vmwrite(VMX_GUEST_GS_BASE, v);
|
||||
|
@ -299,7 +299,40 @@ static void init_cr0_cr4_host_mask(__unused struct vcpu *vcpu)
|
||||
exec_vmwrite(VMX_CR4_MASK, cr4_host_mask);
|
||||
/* Output CR4 mask value */
|
||||
pr_dbg("CR4 mask value: 0x%x", cr4_host_mask);
|
||||
}
|
||||
|
||||
uint64_t vmx_rdmsr_pat(struct vcpu *vcpu)
|
||||
{
|
||||
struct run_context *context =
|
||||
&vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context];
|
||||
|
||||
/*
|
||||
* note: if context->cr0.CD is set, the actual value in guest's
|
||||
* IA32_PAT MSR is PAT_ALL_UC_VALUE, which may be different from
|
||||
* the saved value context->ia32_pat
|
||||
*/
|
||||
return context->ia32_pat;
|
||||
}
|
||||
|
||||
int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value)
|
||||
{
|
||||
uint32_t field, i;
|
||||
struct run_context *context =
|
||||
&vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
field = (value >> (i * 8)) & 0xffU;
|
||||
if ((PAT_MEM_TYPE_INVALID(field) ||
|
||||
(PAT_FIELD_RSV_BITS & field) != 0U)) {
|
||||
pr_err("invalid guest IA32_PAT: 0x%016llx", value);
|
||||
vcpu_inject_gp(vcpu, 0);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
context->ia32_pat = value;
|
||||
exec_vmwrite(VMX_GUEST_IA32_PAT_FULL, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -875,6 +908,7 @@ static void init_guest_state(struct vcpu *vcpu)
|
||||
value32);
|
||||
|
||||
value64 = PAT_POWER_ON_VALUE;
|
||||
cur_context->ia32_pat = value64;
|
||||
exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, value64);
|
||||
pr_dbg("VMX_GUEST_IA32_PAT: 0x%016llx ",
|
||||
value64);
|
||||
|
@ -28,6 +28,7 @@ enum {
|
||||
IDX_BIOS_UPDT_TRIG,
|
||||
IDX_BIOS_SIGN_ID,
|
||||
IDX_TSC,
|
||||
IDX_PAT,
|
||||
|
||||
IDX_MAX_MSR
|
||||
};
|
||||
|
@ -509,6 +509,15 @@
|
||||
#define PAT_MEM_TYPE_WP 0x05U /* write protected */
|
||||
#define PAT_MEM_TYPE_WB 0x06U /* writeback */
|
||||
#define PAT_MEM_TYPE_UCM 0x07U /* uncached minus */
|
||||
#define PAT_MEM_TYPE_INVALID(x) (((x) != PAT_MEM_TYPE_UC) && \
|
||||
((x) != PAT_MEM_TYPE_WC) && \
|
||||
((x) != PAT_MEM_TYPE_WT) && \
|
||||
((x) != PAT_MEM_TYPE_WP) && \
|
||||
((x) != PAT_MEM_TYPE_WB) && \
|
||||
((x) != PAT_MEM_TYPE_UCM))
|
||||
|
||||
/* 5 high-order bits in every field are reserved */
|
||||
#define PAT_FIELD_RSV_BITS (0xF8U)
|
||||
|
||||
/* MTRR memory type definitions */
|
||||
#define MTRR_MEM_TYPE_UC 0x00U /* uncached */
|
||||
|
@ -414,6 +414,9 @@ int vmx_restart(uint16_t pcpu_id);
|
||||
int exec_vmclear(void *addr);
|
||||
int exec_vmptrld(void *addr);
|
||||
|
||||
uint64_t vmx_rdmsr_pat(struct vcpu *vcpu);
|
||||
int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value);
|
||||
|
||||
int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0);
|
||||
int vmx_write_cr3(struct vcpu *vcpu, uint64_t cr3);
|
||||
int vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4);
|
||||
|
Loading…
Reference in New Issue
Block a user