SVM fixes

This commit is contained in:
Stanislav Shwartsman 2011-12-31 13:58:55 +00:00
parent fe6741d84d
commit 3c0d712146
4 changed files with 48 additions and 8 deletions

View File

@ -428,6 +428,11 @@ enum {
#define BX_MSR_KERNELGSBASE 0xc0000102
#define BX_MSR_TSC_AUX 0xc0000103
#define BX_SVM_VM_CR_MSR 0xc0010114
#define BX_SVM_IGNNE_MSR 0xc0010115
#define BX_SVM_SMM_CTL_MSR 0xc0010116
#define BX_SVM_HSAVE_PA_MSR 0xc0010117
#define BX_MODE_IA32_REAL 0x0 // CR0.PE=0 |
#define BX_MODE_IA32_V8086 0x1 // CR0.PE=1, EFLAGS.VM=1 | EFER.LMA=0
#define BX_MODE_IA32_PROTECTED 0x2 // CR0.PE=1, EFLAGS.VM=0 |
@ -662,6 +667,10 @@ typedef struct
Bit32u ia32_feature_ctrl;
#endif
#if BX_SUPPORT_SVM
Bit64u svm_hsave_pa;
#endif
/* TODO finish of the others */
} bx_regs_msr_t;
#endif

View File

@ -57,7 +57,9 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
}
#if BX_SUPPORT_SVM
if (SVM_DR_WRITE_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_WRITE + i->nnn());
if (BX_CPU_THIS_PTR in_svm_guest) {
if (SVM_DR_WRITE_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_WRITE + i->nnn());
}
#endif
invalidate_prefetch_q();
@ -166,7 +168,9 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RdDd(bxInstruction_c *i)
}
#if BX_SUPPORT_SVM
if (SVM_DR_READ_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_READ + i->nnn());
if (BX_CPU_THIS_PTR in_svm_guest) {
if (SVM_DR_READ_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_READ + i->nnn());
}
#endif
/* This instruction is always treated as a register-to-register,
@ -242,7 +246,9 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
}
#if BX_SUPPORT_SVM
if (SVM_DR_WRITE_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_WRITE + i->nnn());
if (BX_CPU_THIS_PTR in_svm_guest) {
if (SVM_DR_WRITE_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_WRITE + i->nnn());
}
#endif
invalidate_prefetch_q();
@ -352,7 +358,9 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
}
#if BX_SUPPORT_SVM
if (SVM_DR_READ_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_READ + i->nnn());
if (BX_CPU_THIS_PTR in_svm_guest) {
if (SVM_DR_READ_INTERCEPTED(i->nnn())) Svm_Vmexit(SVM_VMEXIT_DR0_READ + i->nnn());
}
#endif
/* This instruction is always treated as a register-to-register,

View File

@ -227,6 +227,16 @@ bx_bool BX_CPP_AttrRegparmN(2) BX_CPU_C::rdmsr(Bit32u index, Bit64u *msr)
val64 = BX_CPU_THIS_PTR efer.get32();
break;
#if BX_SUPPORT_SVM
case BX_SVM_HSAVE_PA_MSR:
if (! bx_cpuid_support_svm()) {
BX_ERROR(("RDMSR SVM_HSAVE_PA_MSR: SVM support not enabled !"));
return handle_unknown_rdmsr(index, msr);
}
val64 = BX_CPU_THIS_PTR msr.svm_hsave_pa;
break;
#endif
case BX_MSR_STAR:
if ((BX_CPU_THIS_PTR efer_suppmask & BX_EFER_SCE_MASK) == 0) {
BX_ERROR(("RDMSR MSR_STAR: SYSCALL/SYSRET support not enabled !"));
@ -643,6 +653,19 @@ bx_bool BX_CPP_AttrRegparmN(2) BX_CPU_C::wrmsr(Bit32u index, Bit64u val_64)
return 0;
#endif
#if BX_SUPPORT_SVM
case BX_SVM_HSAVE_PA_MSR:
if (! bx_cpuid_support_svm()) {
BX_ERROR(("WRMSR SVM_HSAVE_PA_MSR: SVM support not enabled !"));
return handle_unknown_wrmsr(index, val_64);
}
if ((val_64 & 0xfff) != 0 || ! IsValidPhyAddr(val_64)) {
BX_ERROR(("WRMSR SVM_HSAVE_PA_MSR: invalid or not page aligned physical address !"));
}
BX_CPU_THIS_PTR msr.svm_hsave_pa = val_64;
break;
#endif
case BX_MSR_EFER:
if (! SetEFER(val_64)) return 0;
break;

View File

@ -433,7 +433,7 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckGuestState(void)
}
if (! guest.sregs[BX_SEG_REG_SS].cache.valid || ! guest.sregs[BX_SEG_REG_SS].selector.value) {
if (! guest.efer.get_LME()) {
if (! guest.efer.get_LMA()) {
BX_ERROR(("VMRUN: VMCB null stack segment in 32-bit mode"));
return 0;
}
@ -539,13 +539,13 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckGuestState(void)
void BX_CPU_C::Svm_Vmexit(int reason)
{
BX_ERROR(("SVM VMEXIT reason=%d", reason));
if (!BX_CPU_THIS_PTR in_svm_guest) {
if (reason != SVM_VMEXIT_INVALID)
BX_PANIC(("PANIC: VMEXIT not in SVM guest mode !"));
BX_PANIC(("PANIC: VMEXIT %d not in SVM guest mode !", reason));
}
BX_ERROR(("SVM VMEXIT reason=%d", reason));
// VMEXITs are FAULT-like: restore RIP/RSP to value before VMEXIT occurred
RIP = BX_CPU_THIS_PTR prev_rip;
if (BX_CPU_THIS_PTR speculative_rsp)