mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
hvm svm: Avoid intercepts when accessing a number of architectural MSRs.
1. Removes intercept of guest-specific MSRs
MSR_IA32_SYSENTER_{CS,ESP,EIP}, MSR_{L,C,}STAR, MSR_SYSCALL_MASK,
MSR_SHADOW_GS_BASE.
2. Removes code to deal with those intercepts, as well as the
FS/GS-base. Since long_mode_do_msr_read now became essentially a
switch of a single case + default, I removed the entire function and
inlined the remaining single case-statement into the original
MSR-access function.
Signed-off-by: Mats Petersson <mats.petersson@amd.com>
This commit is contained in:
1 parent
0031651ad1
commit
8a54eb9690
2 files changed
+12
-121
No files matched your search
+4
-121
@@ -131,66 +131,6 @@ static void svm_store_cpu_guest_regs(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
|
||||
{
|
||||
u64 msr_content = 0;
|
||||
struct vcpu *v = current;
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
switch ((u32)regs->ecx)
|
||||
{
|
||||
case MSR_EFER:
|
||||
msr_content = v->arch.hvm_svm.cpu_shadow_efer;
|
||||
break;
|
||||
|
||||
#ifdef __x86_64__
|
||||
case MSR_FS_BASE:
|
||||
msr_content = vmcb->fs.base;
|
||||
goto check_long_mode;
|
||||
|
||||
case MSR_GS_BASE:
|
||||
msr_content = vmcb->gs.base;
|
||||
goto check_long_mode;
|
||||
|
||||
case MSR_SHADOW_GS_BASE:
|
||||
msr_content = vmcb->kerngsbase;
|
||||
check_long_mode:
|
||||
if ( !svm_long_mode_enabled(v) )
|
||||
{
|
||||
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MSR_STAR:
|
||||
msr_content = vmcb->star;
|
||||
break;
|
||||
|
||||
case MSR_LSTAR:
|
||||
msr_content = vmcb->lstar;
|
||||
break;
|
||||
|
||||
case MSR_CSTAR:
|
||||
msr_content = vmcb->cstar;
|
||||
break;
|
||||
|
||||
case MSR_SYSCALL_MASK:
|
||||
msr_content = vmcb->sfmask;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_2, "msr_content: %"PRIx64"\n",
|
||||
msr_content);
|
||||
|
||||
regs->eax = (u32)(msr_content >> 0);
|
||||
regs->edx = (u32)(msr_content >> 32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
|
||||
{
|
||||
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
|
||||
@@ -242,52 +182,12 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
|
||||
|
||||
break;
|
||||
|
||||
#ifdef __x86_64__
|
||||
case MSR_FS_BASE:
|
||||
case MSR_GS_BASE:
|
||||
case MSR_SHADOW_GS_BASE:
|
||||
if ( !svm_long_mode_enabled(v) )
|
||||
goto gp_fault;
|
||||
|
||||
if ( !is_canonical_address(msr_content) )
|
||||
goto uncanonical_address;
|
||||
|
||||
if ( ecx == MSR_FS_BASE )
|
||||
vmcb->fs.base = msr_content;
|
||||
else if ( ecx == MSR_GS_BASE )
|
||||
vmcb->gs.base = msr_content;
|
||||
else
|
||||
vmcb->kerngsbase = msr_content;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MSR_STAR:
|
||||
vmcb->star = msr_content;
|
||||
break;
|
||||
|
||||
case MSR_LSTAR:
|
||||
case MSR_CSTAR:
|
||||
if ( !is_canonical_address(msr_content) )
|
||||
goto uncanonical_address;
|
||||
|
||||
if ( ecx == MSR_LSTAR )
|
||||
vmcb->lstar = msr_content;
|
||||
else
|
||||
vmcb->cstar = msr_content;
|
||||
break;
|
||||
|
||||
case MSR_SYSCALL_MASK:
|
||||
vmcb->sfmask = msr_content;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
uncanonical_address:
|
||||
HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
|
||||
gp_fault:
|
||||
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
|
||||
return 0;
|
||||
@@ -2013,22 +1913,14 @@ static inline void svm_do_msr_access(
|
||||
case MSR_IA32_TIME_STAMP_COUNTER:
|
||||
msr_content = hvm_get_guest_time(v);
|
||||
break;
|
||||
case MSR_IA32_SYSENTER_CS:
|
||||
msr_content = vmcb->sysenter_cs;
|
||||
break;
|
||||
case MSR_IA32_SYSENTER_ESP:
|
||||
msr_content = vmcb->sysenter_esp;
|
||||
break;
|
||||
case MSR_IA32_SYSENTER_EIP:
|
||||
msr_content = vmcb->sysenter_eip;
|
||||
break;
|
||||
case MSR_IA32_APICBASE:
|
||||
msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
|
||||
break;
|
||||
default:
|
||||
if (long_mode_do_msr_read(regs))
|
||||
goto done;
|
||||
case MSR_EFER:
|
||||
msr_content = v->arch.hvm_svm.cpu_shadow_efer;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) ||
|
||||
rdmsr_safe(ecx, eax, edx) == 0 )
|
||||
{
|
||||
@@ -2061,15 +1953,6 @@ static inline void svm_do_msr_access(
|
||||
hvm_set_guest_time(v, msr_content);
|
||||
pt_reset(v);
|
||||
break;
|
||||
case MSR_IA32_SYSENTER_CS:
|
||||
vmcb->sysenter_cs = msr_content;
|
||||
break;
|
||||
case MSR_IA32_SYSENTER_ESP:
|
||||
vmcb->sysenter_esp = msr_content;
|
||||
break;
|
||||
case MSR_IA32_SYSENTER_EIP:
|
||||
vmcb->sysenter_eip = msr_content;
|
||||
break;
|
||||
case MSR_IA32_APICBASE:
|
||||
vlapic_msr_set(vcpu_vlapic(v), msr_content);
|
||||
break;
|
||||
|
||||
@@ -141,6 +141,14 @@ static int construct_vmcb(struct vcpu *v)
|
||||
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_FS_BASE);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_GS_BASE);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_SHADOW_GS_BASE);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_CSTAR);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_LSTAR);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_STAR);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_SYSCALL_MASK);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_IA32_SYSENTER_CS);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_IA32_SYSENTER_ESP);
|
||||
disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_IA32_SYSENTER_EIP);
|
||||
|
||||
vmcb->msrpm_base_pa = (u64)virt_to_maddr(arch_svm->msrpm);
|
||||
vmcb->iopm_base_pa = (u64)virt_to_maddr(hvm_io_bitmap);
|
||||
|
||||