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:
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user