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:
kfraser@localhost.localdomain committed 2007-04-04 11:57:28 +01:00
1 parent 0031651ad1
commit 8a54eb9690
2 files changed
+12 -121

No files matched your search

+4 -121
View File
@@ -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;
+8
View File
@@ -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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.