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.
*