kvm: x86: Fix segment registers to make them VMX compatible
[gem5.git] / src / cpu / kvm / arm_cpu.cc
index d1082c53e8d4955d858b62a1c12f655cd6c6e410..b0b43d347d44cb25ad334fe98bf908b08d979bfc 100644 (file)
@@ -49,6 +49,7 @@
 #include "debug/Kvm.hh"
 #include "debug/KvmContext.hh"
 #include "debug/KvmInt.hh"
+#include "sim/pseudo_inst.hh"
 
 using namespace ArmISA;
 
@@ -265,8 +266,8 @@ ArmKvmCPU::startup()
     kvmArmVCpuInit(KVM_ARM_TARGET_CORTEX_A15);
 }
 
-void
-ArmKvmCPU::tick()
+Tick
+ArmKvmCPU::kvmRun(Tick ticks)
 {
     bool simFIQ(interrupts->checkRaw(INT_FIQ));
     bool simIRQ(interrupts->checkRaw(INT_IRQ));
@@ -282,7 +283,7 @@ ArmKvmCPU::tick()
         vm.setIRQLine(INTERRUPT_VCPU_IRQ(vcpuID), simIRQ);
     }
 
-    BaseKvmCPU::tick();
+    return BaseKvmCPU::kvmRun(ticks);
 }
 
 void
@@ -310,6 +311,26 @@ ArmKvmCPU::updateThreadContext()
     updateTCStateMisc();
 }
 
+Tick
+ArmKvmCPU::onKvmExitHypercall()
+{
+    ThreadContext *tc(getContext(0));
+    const uint32_t reg_ip(tc->readIntRegFlat(INTREG_R12));
+    const uint8_t func((reg_ip >> 8) & 0xFF);
+    const uint8_t subfunc(reg_ip & 0xFF);
+
+    DPRINTF(Kvm, "KVM Hypercall: 0x%x/0x%x\n", func, subfunc);
+    const uint64_t ret(PseudoInst::pseudoInst(getContext(0), func, subfunc));
+
+    // Just set the return value using the KVM API instead of messing
+    // with the context. We could have used the context, but that
+    // would have required us to request a full context sync.
+    setOneReg(REG_CORE32(usr_regs.ARM_r0), ret & 0xFFFFFFFF);
+    setOneReg(REG_CORE32(usr_regs.ARM_r1), (ret >> 32) & 0xFFFFFFFF);
+
+    return 0;
+}
+
 const ArmKvmCPU::RegIndexVector &
 ArmKvmCPU::getRegList() const
 {