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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -94,6 +94,8 @@ class ArmKvmCPU : public BaseKvmCPU
|
||||
void updateKvmState();
|
||||
void updateThreadContext();
|
||||
|
||||
Tick onKvmExitHypercall();
|
||||
|
||||
/**
|
||||
* Get a list of registers supported by getOneReg() and setOneReg().
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user