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