cpu-kvm: refactor x86 fixup before kvm_run

Since kvmRun still does lots of thing before really going to KVM, to
make the fixup more precise, I change ioctlRun to a virtual function and
make the derived class overrides it if needed.

Change-Id: Ifd75decf0a5445a5266398caebd8aac1a5e80c50
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42301
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Yu-hsin Wang
2021-03-05 16:36:25 +08:00
parent 640de810cb
commit bf91a33e2d
3 changed files with 25 additions and 28 deletions

View File

@@ -569,6 +569,8 @@ class BaseKvmCPU : public BaseCPU
}
/** @} */
/** Execute the KVM_RUN ioctl */
virtual void ioctlRun();
/**
* KVM memory port. Uses default RequestPort behavior and provides an
@@ -678,9 +680,6 @@ class BaseKvmCPU : public BaseCPU
/** Try to drain the CPU if a drain is pending */
bool tryDrain();
/** Execute the KVM_RUN ioctl */
void ioctlRun();
/** KVM vCPU file descriptor */
int vcpuFD;
/** Size of MMAPed kvm_run area */

View File

@@ -1225,7 +1225,7 @@ X86KvmCPU::kvmRun(Tick ticks)
if (_status == Idle)
return 0;
else
return kvmRunWrapper(ticks);
return BaseKvmCPU::kvmRun(ticks);
}
Tick
@@ -1245,33 +1245,14 @@ X86KvmCPU::kvmRunDrain()
// Limit the run to 1 millisecond. That is hopefully enough to
// reach an interrupt window. Otherwise, we'll just try again
// later.
return kvmRunWrapper(1 * SimClock::Float::ms);
return BaseKvmCPU::kvmRun(1 * SimClock::Float::ms);
} else {
DPRINTF(Drain, "kvmRunDrain: Delivering pending IO\n");
return kvmRunWrapper(0);
return BaseKvmCPU::kvmRun(0);
}
}
Tick
X86KvmCPU::kvmRunWrapper(Tick ticks)
{
struct kvm_run &kvm_run(*getKvmRunState());
// Synchronize the APIC base and CR8 here since they are present
// in the kvm_run struct, which makes the synchronization really
// cheap.
kvm_run.apic_base = tc->readMiscReg(MISCREG_APIC_BASE);
kvm_run.cr8 = tc->readMiscReg(MISCREG_CR8);
const Tick run_ticks(BaseKvmCPU::kvmRun(ticks));
tc->setMiscReg(MISCREG_APIC_BASE, kvm_run.apic_base);
kvm_run.cr8 = tc->readMiscReg(MISCREG_CR8);
return run_ticks;
}
uint64_t
X86KvmCPU::getHostCycles() const
{
@@ -1404,6 +1385,23 @@ X86KvmCPU::archIsDrained() const
return !pending_events;
}
void
X86KvmCPU::ioctlRun()
{
struct kvm_run &kvm_run(*getKvmRunState());
// Synchronize the APIC base and CR8 here since they are present
// in the kvm_run struct, which makes the synchronization really
// cheap.
kvm_run.apic_base = tc->readMiscReg(MISCREG_APIC_BASE);
kvm_run.cr8 = tc->readMiscReg(MISCREG_CR8);
BaseKvmCPU::ioctlRun();
tc->setMiscReg(MISCREG_APIC_BASE, kvm_run.apic_base);
kvm_run.cr8 = tc->readMiscReg(MISCREG_CR8);
}
static struct kvm_cpuid_entry2
makeKvmCpuid(uint32_t function, uint32_t index,
CpuidResult &result)

View File

@@ -78,9 +78,6 @@ class X86KvmCPU : public BaseKvmCPU
*/
Tick kvmRunDrain() override;
/** Wrapper that synchronizes state in kvm_run */
Tick kvmRunWrapper(Tick ticks);
uint64_t getHostCycles() const override;
/**
@@ -158,6 +155,9 @@ class X86KvmCPU : public BaseKvmCPU
*/
bool archIsDrained() const override;
/** Override for synchronizing state in kvm_run */
void ioctlRun() override;
private:
/**
* Support routines to update the state of the KVM CPU from gem5's