arch,cpu,base: Make add a virtual method to stutter the PC for KVM. As described in a comment in the base KVM CPU, there needs to be a way to set the next PC of a PCState object to the actual current PC. Since this is the only place that sort of operation is needed and it's a bit of a hack to get around a quirk of calling pseudo instructions in a KVM CPU, we can support it by adding a virtual method for it which is implemented by the ISA specific subclasses of the KVM CPU. Change-Id: Idf390e9c4ffa7398cd08e76846c61cb6da754dce Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52059 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Gabe Black <gabe.black@gmail.com>
diff --git a/src/arch/arm/kvm/arm_cpu.hh b/src/arch/arm/kvm/arm_cpu.hh index 95d5339..a16a095 100644 --- a/src/arch/arm/kvm/arm_cpu.hh +++ b/src/arch/arm/kvm/arm_cpu.hh
@@ -41,6 +41,7 @@ #include <set> #include <vector> +#include "arch/arm/pcstate.hh" #include "cpu/kvm/base.hh" #include "params/ArmKvmCPU.hh" @@ -96,6 +97,11 @@ void updateKvmState(); void updateThreadContext(); + void + stutterPC(PCStateBase &pc) const + { + pc.as<X86ISA::PCState>().setNPC(pc->instAddr()); + } /** * Get a list of registers supported by getOneReg() and setOneReg().
diff --git a/src/arch/arm/kvm/base_cpu.hh b/src/arch/arm/kvm/base_cpu.hh index 3b2beb3..0da4789 100644 --- a/src/arch/arm/kvm/base_cpu.hh +++ b/src/arch/arm/kvm/base_cpu.hh
@@ -40,6 +40,7 @@ #include <vector> +#include "arch/arm/pcstate.hh" #include "cpu/kvm/base.hh" #include "dev/arm/base_gic.hh" @@ -62,6 +63,12 @@ protected: Tick kvmRun(Tick ticks) override; + void + stutterPC(PCStateBase &pc) const override + { + pc.as<ArmISA::PCState>().setNPC(pc.instAddr()); + } + /** Override for synchronizing state in kvm_run */ void ioctlRun() override;
diff --git a/src/arch/x86/kvm/x86_cpu.hh b/src/arch/x86/kvm/x86_cpu.hh index 69390a8..ae41b6b 100644 --- a/src/arch/x86/kvm/x86_cpu.hh +++ b/src/arch/x86/kvm/x86_cpu.hh
@@ -31,6 +31,7 @@ #include <vector> +#include "arch/x86/pcstate.hh" #include "cpu/kvm/base.hh" #include "cpu/kvm/vm.hh" #include "params/X86KvmCPU.hh" @@ -91,6 +92,11 @@ Tick kvmRunDrain() override; uint64_t getHostCycles() const override; + void + stutterPC(PCStateBase &pc) const override + { + pc.as<X86ISA::PCState>().setNPC(pc.instAddr()); + } /** * Methods to access CPUID information using the extended
diff --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc index bda4d0e..79bbf02 100644 --- a/src/cpu/kvm/base.cc +++ b/src/cpu/kvm/base.cc
@@ -1110,8 +1110,10 @@ // // We won't be able to rewind the current PC to the "correct" // value without figuring out how big the current instruction - // is, and that's probably not worth the effort. - tc->setNPC(tc->instAddr()); + // is, and that's probably not worth the effort + std::unique_ptr<PCStateBase> pc(tc->pcState().clone()); + stutterPC(*pc); + tc->pcState(*pc); // We currently assume that there is no need to migrate to a // different event queue when doing local accesses. Currently, they // are only used for m5ops, so it should be a valid assumption.
diff --git a/src/cpu/kvm/base.hh b/src/cpu/kvm/base.hh index 4f40064..449c5db 100644 --- a/src/cpu/kvm/base.hh +++ b/src/cpu/kvm/base.hh
@@ -261,6 +261,15 @@ virtual uint64_t getHostCycles() const; /** + * Modify a PCStatePtr's value so that its next PC is the current PC. + * + * This needs to be implemented in KVM base classes since modifying the + * next PC value is an ISA specific operation. This is only used in + * doMMIOAccess, for reasons explained in a comment there. + */ + virtual void stutterPC(PCStateBase &pc) const = 0; + + /** * Request KVM to run the guest for a given number of ticks. The * method returns the approximate number of ticks executed. *