kvm: Add support for pseudo-ops on ARM

This changeset adds support for m5 pseudo-ops when running in
kvm-mode. Unfortunately, we can't trap the normal gem5 co-processor
entry in KVM (it doesn't seem to be possible to trap accesses to
non-existing co-processors). We therefore use BZJ instructions to
cause a trap from virtualized mode into gem5. The BZJ instruction is
becomes a normal branch to the gem5 fallback code when running in
simulated mode, which means that this patch does not need to change
the ARM ISA-specific code.

Note: This requires a patched host kernel.
This commit is contained in:
Andreas Sandberg
2013-04-22 13:20:32 -04:00
parent 1c529a4196
commit 33ab8f735d
3 changed files with 88 additions and 107 deletions

View 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;
@@ -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
{

View File

@@ -94,6 +94,8 @@ class ArmKvmCPU : public BaseKvmCPU
void updateKvmState();
void updateThreadContext();
Tick onKvmExitHypercall();
/**
* Get a list of registers supported by getOneReg() and setOneReg().
*/