changeset f02b907bb9e8 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=f02b907bb9e8
description:
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.
diffstat:
src/cpu/kvm/x86_cpu.cc | 51 ++++++++++++++++++++++++++-----------------------
src/cpu/kvm/x86_cpu.hh | 9 ++++---
2 files changed, 32 insertions(+), 28 deletions(-)
diffs (132 lines):
diff -r 1a2f64842044 -r f02b907bb9e8 src/cpu/kvm/x86_cpu.cc
--- a/src/cpu/kvm/x86_cpu.cc Sun Mar 16 17:28:23 2014 +0100
+++ b/src/cpu/kvm/x86_cpu.cc Sun Mar 16 17:30:24 2014 +0100
@@ -690,7 +690,7 @@
FOREACH_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
* MISCREG_RFLAGS here would suffice. In that case you're
@@ -936,16 +936,29 @@
void
X86KvmCPU::updateThreadContext()
{
+ struct kvm_regs regs;
+ struct kvm_sregs sregs;
+
+ getRegisters(regs);
+ getSpecialRegisters(sregs);
+
DPRINTF(KvmContext, "X86KvmCPU::updateThreadContext():\n");
if (DTRACE(KvmContext))
dump();
- updateThreadContextRegs();
- updateThreadContextSRegs();
- if (useXSave)
- updateThreadContextXSave();
- else
- updateThreadContextFPU();
+ updateThreadContextRegs(regs, sregs);
+ updateThreadContextSRegs(sregs);
+ if (useXSave) {
+ struct kvm_xsave xsave;
+ getXSave(xsave);
+
+ updateThreadContextXSave(xsave);
+ } else {
+ struct kvm_fpu fpu;
+ getFPUState(fpu);
+
+ updateThreadContextFPU(fpu);
+ }
updateThreadContextMSRs();
// The M5 misc reg caches some values from other
@@ -955,18 +968,16 @@
}
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)
FOREACH_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
// need some special care when updating them.
@@ -1011,11 +1022,8 @@
}
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()->cr8 == sregs.cr8);
@@ -1070,11 +1078,8 @@
}
void
-X86KvmCPU::updateThreadContextFPU()
+X86KvmCPU::updateThreadContextFPU(const struct kvm_fpu &fpu)
{
- struct kvm_fpu fpu;
- getFPUState(fpu);
-
updateThreadContextFPUCommon(tc, fpu);
tc->setMiscRegNoEffect(MISCREG_FISEG, 0);
@@ -1084,11 +1089,9 @@
}
void
-X86KvmCPU::updateThreadContextXSave()
+X86KvmCPU::updateThreadContextXSave(const struct kvm_xsave &kxsave)
{
- struct kvm_xsave kxsave;
- FXSave &xsave(*(FXSave *)kxsave.region);
- getXSave(kxsave);
+ const FXSave &xsave(*(const FXSave *)kxsave.region);
updateThreadContextFPUCommon(tc, xsave);
diff -r 1a2f64842044 -r f02b907bb9e8 src/cpu/kvm/x86_cpu.hh
--- a/src/cpu/kvm/x86_cpu.hh Sun Mar 16 17:28:23 2014 +0100
+++ b/src/cpu/kvm/x86_cpu.hh Sun Mar 16 17:30:24 2014 +0100
@@ -209,13 +209,14 @@
* @{
*/
/** Update integer registers */
- void updateThreadContextRegs();
+ void updateThreadContextRegs(const struct kvm_regs ®s,
+ const struct kvm_sregs &sregs);
/** Update control registers (CRx, segments, etc.) */
- void updateThreadContextSRegs();
+ void updateThreadContextSRegs(const struct kvm_sregs &sregs);
/** 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 */
- void updateThreadContextXSave();
+ void updateThreadContextXSave(const struct kvm_xsave &kxsave);
/** Update MSR registers */
void updateThreadContextMSRs();
/** @} */
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev