kvm: x86: Adjust PC to remove the CS segment base address
gem5 seems to store the PC as RIP+CS_BASE. This is not what KVM expects, so we need to subtract CS_BASE prior to transferring the PC into KVM. This changeset adds the necessary PC manipulation and refactors thread context updates slightly to avoid reading registers multiple times from KVM. --HG-- extra : rebase_source : 3f0569dca06a1fcd8694925f75c8918d954ada44
This commit is contained in:
parent
f791e7b313
commit
5db547bca4
2 changed files with 32 additions and 28 deletions
|
@ -690,7 +690,7 @@ X86KvmCPU::updateKvmStateRegs()
|
||||||
FOREACH_IREG();
|
FOREACH_IREG();
|
||||||
#undef APPLY_IREG
|
#undef APPLY_IREG
|
||||||
|
|
||||||
regs.rip = tc->instAddr();
|
regs.rip = tc->instAddr() - tc->readMiscReg(MISCREG_CS_BASE);
|
||||||
|
|
||||||
/* You might think that setting regs.rflags to the contents
|
/* You might think that setting regs.rflags to the contents
|
||||||
* MISCREG_RFLAGS here would suffice. In that case you're
|
* MISCREG_RFLAGS here would suffice. In that case you're
|
||||||
|
@ -936,16 +936,29 @@ X86KvmCPU::updateKvmStateMSRs()
|
||||||
void
|
void
|
||||||
X86KvmCPU::updateThreadContext()
|
X86KvmCPU::updateThreadContext()
|
||||||
{
|
{
|
||||||
|
struct kvm_regs regs;
|
||||||
|
struct kvm_sregs sregs;
|
||||||
|
|
||||||
|
getRegisters(regs);
|
||||||
|
getSpecialRegisters(sregs);
|
||||||
|
|
||||||
DPRINTF(KvmContext, "X86KvmCPU::updateThreadContext():\n");
|
DPRINTF(KvmContext, "X86KvmCPU::updateThreadContext():\n");
|
||||||
if (DTRACE(KvmContext))
|
if (DTRACE(KvmContext))
|
||||||
dump();
|
dump();
|
||||||
|
|
||||||
updateThreadContextRegs();
|
updateThreadContextRegs(regs, sregs);
|
||||||
updateThreadContextSRegs();
|
updateThreadContextSRegs(sregs);
|
||||||
if (useXSave)
|
if (useXSave) {
|
||||||
updateThreadContextXSave();
|
struct kvm_xsave xsave;
|
||||||
else
|
getXSave(xsave);
|
||||||
updateThreadContextFPU();
|
|
||||||
|
updateThreadContextXSave(xsave);
|
||||||
|
} else {
|
||||||
|
struct kvm_fpu fpu;
|
||||||
|
getFPUState(fpu);
|
||||||
|
|
||||||
|
updateThreadContextFPU(fpu);
|
||||||
|
}
|
||||||
updateThreadContextMSRs();
|
updateThreadContextMSRs();
|
||||||
|
|
||||||
// The M5 misc reg caches some values from other
|
// The M5 misc reg caches some values from other
|
||||||
|
@ -955,18 +968,16 @@ X86KvmCPU::updateThreadContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86KvmCPU::updateThreadContextRegs()
|
X86KvmCPU::updateThreadContextRegs(const struct kvm_regs ®s,
|
||||||
|
const struct kvm_sregs &sregs)
|
||||||
{
|
{
|
||||||
struct kvm_regs regs;
|
|
||||||
getRegisters(regs);
|
|
||||||
|
|
||||||
#define APPLY_IREG(kreg, mreg) tc->setIntReg(mreg, regs.kreg)
|
#define APPLY_IREG(kreg, mreg) tc->setIntReg(mreg, regs.kreg)
|
||||||
|
|
||||||
FOREACH_IREG();
|
FOREACH_IREG();
|
||||||
|
|
||||||
#undef APPLY_IREG
|
#undef APPLY_IREG
|
||||||
|
|
||||||
tc->pcState(PCState(regs.rip));
|
tc->pcState(PCState(regs.rip + sregs.cs.base));
|
||||||
|
|
||||||
// Flags are spread out across multiple semi-magic registers so we
|
// Flags are spread out across multiple semi-magic registers so we
|
||||||
// need some special care when updating them.
|
// need some special care when updating them.
|
||||||
|
@ -1011,11 +1022,8 @@ setContextSegment(ThreadContext *tc, const struct kvm_dtable &kvm_dtable,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86KvmCPU::updateThreadContextSRegs()
|
X86KvmCPU::updateThreadContextSRegs(const struct kvm_sregs &sregs)
|
||||||
{
|
{
|
||||||
struct kvm_sregs sregs;
|
|
||||||
getSpecialRegisters(sregs);
|
|
||||||
|
|
||||||
assert(getKvmRunState()->apic_base == sregs.apic_base);
|
assert(getKvmRunState()->apic_base == sregs.apic_base);
|
||||||
assert(getKvmRunState()->cr8 == sregs.cr8);
|
assert(getKvmRunState()->cr8 == sregs.cr8);
|
||||||
|
|
||||||
|
@ -1070,11 +1078,8 @@ updateThreadContextFPUCommon(ThreadContext *tc, const T &fpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86KvmCPU::updateThreadContextFPU()
|
X86KvmCPU::updateThreadContextFPU(const struct kvm_fpu &fpu)
|
||||||
{
|
{
|
||||||
struct kvm_fpu fpu;
|
|
||||||
getFPUState(fpu);
|
|
||||||
|
|
||||||
updateThreadContextFPUCommon(tc, fpu);
|
updateThreadContextFPUCommon(tc, fpu);
|
||||||
|
|
||||||
tc->setMiscRegNoEffect(MISCREG_FISEG, 0);
|
tc->setMiscRegNoEffect(MISCREG_FISEG, 0);
|
||||||
|
@ -1084,11 +1089,9 @@ X86KvmCPU::updateThreadContextFPU()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86KvmCPU::updateThreadContextXSave()
|
X86KvmCPU::updateThreadContextXSave(const struct kvm_xsave &kxsave)
|
||||||
{
|
{
|
||||||
struct kvm_xsave kxsave;
|
const FXSave &xsave(*(const FXSave *)kxsave.region);
|
||||||
FXSave &xsave(*(FXSave *)kxsave.region);
|
|
||||||
getXSave(kxsave);
|
|
||||||
|
|
||||||
updateThreadContextFPUCommon(tc, xsave);
|
updateThreadContextFPUCommon(tc, xsave);
|
||||||
|
|
||||||
|
|
|
@ -209,13 +209,14 @@ class X86KvmCPU : public BaseKvmCPU
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Update integer registers */
|
/** Update integer registers */
|
||||||
void updateThreadContextRegs();
|
void updateThreadContextRegs(const struct kvm_regs ®s,
|
||||||
|
const struct kvm_sregs &sregs);
|
||||||
/** Update control registers (CRx, segments, etc.) */
|
/** Update control registers (CRx, segments, etc.) */
|
||||||
void updateThreadContextSRegs();
|
void updateThreadContextSRegs(const struct kvm_sregs &sregs);
|
||||||
/** Update FPU and SIMD registers using the legacy API */
|
/** Update FPU and SIMD registers using the legacy API */
|
||||||
void updateThreadContextFPU();
|
void updateThreadContextFPU(const struct kvm_fpu &fpu);
|
||||||
/** Update FPU and SIMD registers using the XSave API */
|
/** Update FPU and SIMD registers using the XSave API */
|
||||||
void updateThreadContextXSave();
|
void updateThreadContextXSave(const struct kvm_xsave &kxsave);
|
||||||
/** Update MSR registers */
|
/** Update MSR registers */
|
||||||
void updateThreadContextMSRs();
|
void updateThreadContextMSRs();
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
Loading…
Reference in a new issue