42 #include <linux/kvm.h>
43 #include <sys/ioctl.h>
51 #include "arch/mmapped_ipr.hh"
52 #include "arch/utility.hh"
53 #include "debug/Checkpoint.hh"
54 #include "debug/Drain.hh"
55 #include "debug/Kvm.hh"
56 #include "debug/KvmIO.hh"
57 #include "debug/KvmRun.hh"
58 #include "params/BaseKvmCPU.hh"
63 #define PAGE_SIZE pageSize
69 dataPort(
name() +
".dcache_port", this),
70 instPort(
name() +
".icache_port", this),
71 alwaysSyncTC(params->alwaysSyncTC),
72 threadContextDirty(true),
74 vcpuID(
vm.allocVCPUID()), vcpuFD(-1), vcpuMMapSize(0),
75 _kvmRun(NULL), mmioRing(NULL),
76 pageSize(sysconf(_SC_PAGE_SIZE)),
79 perfControlledByTimer(params->usePerfOverflow),
80 hostFactor(params->hostFactor),
84 panic(
"KVM: Failed to determine host page size (%i)\n",
92 params->workload[0], params->itb,
93 params->dtb, params->isa[0]);
97 threadContexts.push_back(
tc);
113 fatal(
"KVM: Multithreading not supported");
125 const BaseKvmCPUParams *
const p(
126 dynamic_cast<const BaseKvmCPUParams *>(params()));
145 PROT_READ | PROT_WRITE, MAP_SHARED,
148 panic(
"KVM: Failed to map run data structure\n");
154 if (!p->useCoalescedMMIO) {
155 inform(
"KVM: Coalesced MMIO disabled by config.\n");
156 }
else if (mmioOffset) {
157 inform(
"KVM: Coalesced IO available\n");
158 mmioRing = (
struct kvm_coalesced_mmio_ring *)(
161 inform(
"KVM: Coalesced not supported by host OS\n");
169 schedule(startupEvent,
curTick());
182 if (cpu->system->isAtomicMode()) {
183 Tick delay = sendAtomic(pkt);
188 if (pendingMMIOPkts.empty() && sendTimingReq(pkt)) {
191 pendingMMIOPkts.push(pkt);
201 DPRINTF(KvmIO,
"KVM: Finished timing request\n");
209 if (!(activeMMIOReqs || pendingMMIOPkts.size())) {
210 DPRINTF(KvmIO,
"KVM: Finished all outstanding timing requests\n");
211 cpu->finishMMIOPending();
219 DPRINTF(KvmIO,
"KVM: Retry for timing request\n");
221 assert(pendingMMIOPkts.size());
226 while (pendingMMIOPkts.size() && sendTimingReq(pendingMMIOPkts.front())) {
227 pendingMMIOPkts.pop();
249 const BaseKvmCPUParams *
const p(
250 dynamic_cast<const BaseKvmCPUParams *>(params()));
260 if (p->usePerfOverflow)
275 using namespace Stats;
281 .
desc(
"Number of instructions committed")
286 .
desc(
"total number of KVM exits")
291 .
desc(
"number of KVM entries to finalize pending operations")
296 .
desc(
"exits due to signal delivery")
301 .
desc(
"number of VM exits due to memory mapped IO")
306 .
desc(
"number of coalesced memory mapped IO requests")
311 .
desc(
"number of VM exits due to legacy IO")
316 .
desc(
"number of VM exits due to wait for interrupt instructions")
321 .
desc(
"number of interrupts delivered")
326 .
desc(
"number of hypercalls")
334 DPRINTF(Checkpoint,
"KVM: Serializing thread %i:\n", tid);
346 DPRINTF(Checkpoint,
"KVM: Unserialize thread %i:\n", tid);
360 DPRINTF(Drain,
"BaseKvmCPU::drain\n");
397 DPRINTF(Drain,
"KVM CPU is waiting for service completion, "
398 "requesting drain.\n");
403 DPRINTF(Drain,
"KVM CPU is waiting for timing accesses to complete, "
404 "requesting drain.\n");
409 DPRINTF(Drain,
"KVM CPU is waiting for service, requesting drain.\n");
413 panic(
"KVM: Unhandled CPU state in drain()\n");
451 warn(
"kvm CPU: notifyFork failed to close vcpuFD\n");
469 BaseCPU::switchOut();
490 assert(threadContexts.size() == 1);
503 if (!(
system->bypassCaches())) {
504 fatal(
"The KVM-based CPUs requires the memory system to be in the "
505 "'noncaching' mode.\n");
530 DPRINTF(
Kvm,
"ActivateContext %d\n", thread_num);
532 assert(thread_num == 0);
548 DPRINTF(
Kvm,
"SuspendContext %d\n", thread_num);
550 assert(thread_num == 0);
600 hack_once(
"Pretending totalOps is equivalent to totalInsts()\n");
607 inform(
"State dumping not implemented.");
627 const uint64_t nextInstEvent(
628 !comInstEventQueue[0]->empty() ?
629 comInstEventQueue[0]->nextTick() : UINT64_MAX);
632 const Tick ticksToExecute(
645 if (ticksToExecute > 0)
648 DPRINTF(KvmRun,
"Entering KVM...\n");
656 delay =
kvmRun(ticksToExecute);
675 if (
_kvmRun->exit_reason != KVM_EXIT_INTR) {
685 comInstEventQueue[0]->serviceEvents(
ctrInsts);
686 system->instEventQueue.serviceEvents(
system->totalNumInsts);
693 panic(
"BaseKvmCPU entered tick() in an illegal state (%i)\n",
699 schedule(
tickEvent, clockEdge(ticksToCycles(delay)));
727 "Trying to run a KVM CPU in a forked child process. "
728 "This is not supported.\n");
729 DPRINTF(KvmRun,
"KVM: Executing for %i ticks\n", ticks);
735 DPRINTF(KvmRun,
"KVM: Delivering IO without full guest entry\n");
756 ticksExecuted = clockPeriod();
766 if (ticks < runTimer->resolution()) {
767 DPRINTF(KvmRun,
"KVM: Adjusting tick count (%i -> %i)\n",
798 const uint64_t hostCyclesExecuted(
getHostCycles() - baseCycles);
799 const uint64_t simCyclesExecuted(hostCyclesExecuted *
hostFactor);
801 ticksExecuted =
runTimer->ticksFromHostCycles(hostCyclesExecuted);
804 numCycles += simCyclesExecuted;;
807 system->totalNumInsts += instsExecuted;
810 "KVM: Executed %i instructions in %i cycles "
811 "(%i ticks, sim cycles: %i).\n",
812 instsExecuted, hostCyclesExecuted, ticksExecuted, simCyclesExecuted);
824 if (
ioctl(KVM_NMI) == -1)
825 panic(
"KVM: Failed to deliver NMI to virtual CPU\n");
832 if (
ioctl(KVM_INTERRUPT, (
void *)&interrupt) == -1)
833 panic(
"KVM: Failed to deliver interrupt to virtual CPU\n");
839 if (
ioctl(KVM_GET_REGS, ®s) == -1)
840 panic(
"KVM: Failed to get guest registers\n");
846 if (
ioctl(KVM_SET_REGS, (
void *)®s) == -1)
847 panic(
"KVM: Failed to set guest registers\n");
853 if (
ioctl(KVM_GET_SREGS, ®s) == -1)
854 panic(
"KVM: Failed to get guest special registers\n");
860 if (
ioctl(KVM_SET_SREGS, (
void *)®s) == -1)
861 panic(
"KVM: Failed to set guest special registers\n");
867 if (
ioctl(KVM_GET_FPU, &state) == -1)
868 panic(
"KVM: Failed to get guest FPU state\n");
874 if (
ioctl(KVM_SET_FPU, (
void *)&state) == -1)
875 panic(
"KVM: Failed to set guest FPU state\n");
882 #ifdef KVM_SET_ONE_REG
883 struct kvm_one_reg reg;
885 reg.addr = (uint64_t)addr;
887 if (
ioctl(KVM_SET_ONE_REG, ®) == -1) {
888 panic(
"KVM: Failed to set register (0x%x) value (errno: %i)\n",
892 panic(
"KVM_SET_ONE_REG is unsupported on this platform.\n");
899 #ifdef KVM_GET_ONE_REG
900 struct kvm_one_reg reg;
902 reg.addr = (uint64_t)addr;
904 if (
ioctl(KVM_GET_ONE_REG, ®) == -1) {
905 panic(
"KVM: Failed to get register (0x%x) value (errno: %i)\n",
909 panic(
"KVM_GET_ONE_REG is unsupported on this platform.\n");
916 #ifdef KVM_GET_ONE_REG
917 std::ostringstream
ss;
919 ss.setf(std::ios::hex, std::ios::basefield);
920 ss.setf(std::ios::showbase);
921 #define HANDLE_INTTYPE(len) \
922 case KVM_REG_SIZE_U ## len: { \
923 uint ## len ## _t value; \
924 getOneReg(id, &value); \
928 #define HANDLE_ARRAY(len) \
929 case KVM_REG_SIZE_U ## len: { \
930 uint8_t value[len / 8]; \
931 getOneReg(id, value); \
932 ccprintf(ss, "[0x%x", value[0]); \
933 for (int i = 1; i < len / 8; ++i) \
934 ccprintf(ss, ", 0x%x", value[i]); \
938 switch (
id & KVM_REG_SIZE_MASK) {
951 #undef HANDLE_INTTYPE
956 panic(
"KVM_GET_ONE_REG is unsupported on this platform.\n");
987 DPRINTF(KvmRun,
"handleKvmExit (exit_reason: %i)\n",
_kvmRun->exit_reason);
993 switch (
_kvmRun->exit_reason) {
994 case KVM_EXIT_UNKNOWN:
997 case KVM_EXIT_EXCEPTION:
1008 case KVM_EXIT_HYPERCALL:
1026 DPRINTF(KvmIO,
"KVM: Handling MMIO (w: %u, addr: 0x%x, len: %u)\n",
1040 case KVM_EXIT_IRQ_WINDOW_OPEN:
1043 case KVM_EXIT_FAIL_ENTRY:
1051 case KVM_EXIT_INTERNAL_ERROR:
1052 panic(
"KVM: Internal error (suberror: %u)\n",
1057 panic(
"KVM: Unexpected exit (exit_reason: %u)\n",
_kvmRun->exit_reason);
1064 panic(
"KVM: Unhandled guest IO (dir: %i, size: %i, port: 0x%x, count: %i)\n",
1072 panic(
"KVM: Unhandled hypercall\n");
1078 warn(
"KVM: Unhandled IRQ window.\n");
1087 panic(
"KVM: Unknown error when starting vCPU (hw reason: 0x%llx)\n",
1088 _kvmRun->hw.hardware_exit_reason);
1095 panic(
"KVM: Got exception when starting vCPU "
1096 "(exception: %u, error_code: %u)\n",
1104 panic(
"KVM: Failed to enter virtualized mode (hw reason: 0x%llx)\n",
1105 _kvmRun->fail_entry.hardware_entry_failure_reason);
1124 warn(
"Finalization of MMIO address failed: %s\n", fault->name());
1135 const Cycles ipr_delay(write ?
1141 return clockPeriod() * ipr_delay;
1155 std::unique_ptr<struct kvm_signal_mask> kvm_mask;
1158 kvm_mask.reset((
struct kvm_signal_mask *)
operator new(
1159 sizeof(
struct kvm_signal_mask) +
sizeof(*mask)));
1163 assert(
sizeof(*mask) >= 8);
1165 memcpy(kvm_mask->sigset, mask, kvm_mask->len);
1168 if (
ioctl(KVM_SET_SIGNAL_MASK, (
void *)kvm_mask.get()) == -1)
1169 panic(
"KVM: Failed to set vCPU signal mask (errno: %i)\n",
1177 panic(
"KVM: CPU ioctl called before initialization\n");
1179 return ::ioctl(
vcpuFD, request, p1);
1188 DPRINTF(KvmIO,
"KVM: Flushing the coalesced MMIO ring buffer\n");
1194 struct kvm_coalesced_mmio &ent(
1197 DPRINTF(KvmIO,
"KVM: Handling coalesced MMIO (addr: 0x%x, len: %u)\n",
1198 ent.phys_addr, ent.len);
1201 ticks +=
doMMIOAccess(ent.phys_addr, ent.data, ent.len,
true);
1227 struct sigaction sa;
1229 memset(&sa, 0,
sizeof(sa));
1231 sa.sa_flags = SA_SIGINFO | SA_RESTART;
1233 panic(
"KVM: Failed to setup vCPU timer signal handler\n");
1236 if (pthread_sigmask(SIG_BLOCK, NULL, &sigset) == -1)
1237 panic(
"KVM: Failed get signal mask\n");
1249 if (pthread_sigmask(SIG_SETMASK, &sigset, NULL) == -1)
1250 panic(
"KVM: Failed mask the KVM control signals\n");
1256 int discardedSignal;
1260 struct timespec timeout;
1262 timeout.tv_nsec = 0;
1265 sigemptyset(&sigset);
1266 sigaddset(&sigset, signum);
1269 discardedSignal = sigtimedwait(&sigset, NULL, &timeout);
1270 }
while (discardedSignal == -1 && errno == EINTR);
1272 if (discardedSignal == signum)
1274 else if (discardedSignal == -1 && errno == EAGAIN)
1277 panic(
"Unexpected return value from sigtimedwait: %i (errno: %i)\n",
1278 discardedSignal, errno);
1284 DPRINTF(
Kvm,
"Attaching cycle counter...\n");
1286 PERF_COUNT_HW_CPU_CYCLES);
1319 DPRINTF(Drain,
"tryDrain: Architecture code is not ready.\n");
1325 "tryDrain: CPU transitioned into the Idle state, drain done\n");
1329 DPRINTF(Drain,
"tryDrain: CPU not ready.\n");
1337 if (
ioctl(KVM_RUN) == -1) {
1339 panic(
"KVM: Failed to start virtual CPU (errno: %i)\n",
1347 if (comInstEventQueue[0]->empty()) {
1350 const uint64_t next(comInstEventQueue[0]->nextTick());
1366 PERF_COUNT_HW_INSTRUCTIONS);
void detach()
Detach a counter from PerfEvent.
void tick()
Execute the CPU until the next event in the main event queue or until the guest needs service from ge...
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void setupCounters()
Setup hardware performance counters.
PerfKvmCounterConfig & pinned(bool val)
Force the group to be on the active all the time (i.e., disallow multiplexing).
void finishMMIOPending()
Callback from KvmCPUPort to transition the CPU out of RunningMMIOPending when all timing requests hav...
Counter ctrInsts
Number of instructions executed by the CPU.
decltype(nullptr) constexpr NoFault
Cycles is a wrapper class for representing cycle counts, i.e.
uint64_t activeInstPeriod
Currently active instruction count breakpoint.
Timing MMIO request in flight or stalled.
Tick lastActivate
Last time activate was called on this thread.
const std::string & name()
virtual void updateThreadContext()=0
Update the current thread context with the KVM state.
DrainState
Object drain/handover states.
virtual Tick handleKvmExitIO()
The guest performed a legacy IO request (out/inp on x86)
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the slave port.
Tick submitIO(PacketPtr pkt)
Interface to send Atomic or Timing IO request.
void setStatus(Status newStatus)
uint64_t read() const
Read the current value of a counter.
bool threadContextDirty
Is the gem5 context dirty? Set to true to force an update of the KVM vCPU state upon the next call to...
bool perfControlledByTimer
Does the runTimer control the performance counters?
void notifyFork() override
virtual Tick kvmRun(Tick ticks)
Request KVM to run the guest for a given number of ticks.
void cpuStartup()
VM CPU initialization code.
Tick lastSuspend
Last time suspend was called on this thread.
std::unique_ptr< BaseKvmTimer > runTimer
Timer used to force execution into the monitor after a specified number of simulation tick equivalent...
ThreadContext * tc
ThreadContext object, provides an interface for external objects to modify this thread's state...
void kvmNonMaskableInterrupt()
Send a non-maskable interrupt to the guest.
bool scheduled() const
Determine if the current event is scheduled.
bool isMmappedIpr() const
void enableSignals(pid_t tid, int signal)
Enable signal delivery to a thread on counter overflow.
virtual Tick handleKvmExitIRQWindowOpen()
The guest exited because an interrupt window was requested.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
void verifyMemoryMode() const override
void activate()
Set the status to Active.
void wakeup(ThreadID tid=0) override
void setContext(ContextID context_id)
Set up Context numbers.
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
float hostFactor
Host factor as specified in the configuration.
bool tryDrain()
Try to drain the CPU if a drain is pending.
Counter totalInsts() const override
Stats::Scalar numExitSignal
virtual Tick kvmRunDrain()
Request the CPU to run until draining completes.
int createVCPU(long vcpuID)
Create a new vCPU within a VM.
Base class for KVM based CPU models.
Tick flushCoalescedMMIO()
Service MMIO requests in the mmioRing.
DrainState drain() override
Cycles handleIprRead(ThreadContext *xc, Packet *pkt)
Helper function to handle IPRs when the target architecture doesn't need its own IPR handling...
Cycles handleIprWrite(ThreadContext *xc, Packet *pkt)
Helper function to handle IPRs when the target architecture doesn't need its own IPR handling...
ThreadContext is the external interface to all thread state for anything outside of the CPU...
const long vcpuID
KVM internal ID of the vCPU.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
void recvReqRetry() override
Called by the slave port if sendTimingReq was called on this master port (causing recvTimingReq to be...
virtual void updateKvmState()=0
Update the KVM state from the current thread context.
void suspend()
Set the status to Suspended.
void activateContext(ThreadID thread_num) override
Stats::Scalar numInterrupts
#define KVM_KICK_SIGNAL
Signal to use to trigger exits from KVM.
PerfKvmCounterConfig & wakeupEvents(uint32_t events)
Set the number of samples that need to be triggered before reporting data as being available on the p...
bool discardPendingSignal(int signum) const
Discard a (potentially) pending signal.
void setSpecialRegisters(const struct kvm_sregs ®s)
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
void setupSignalHandler()
Setup a signal handler to catch the timer signal used to switch back to the monitor.
Tick curTick()
The current simulated tick.
Temporarily migrate execution to a different event queue.
int vcpuMMapSize
Size of MMAPed kvm_run area.
virtual Tick handleKvmExitFailEntry()
KVM failed to start the virtualized CPU.
void drainResume() override
struct kvm_run * _kvmRun
Pointer to the kvm_run structure used to communicate parameters with KVM.
void syncKvmState()
Update the KVM if the thread context is dirty.
ThreadContext * getContext(int tn) override
void takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
Copy state between thread contexts in preparation for CPU handover.
void setOneReg(uint64_t id, const void *addr)
Get/Set single register using the KVM_(SET|GET)_ONE_REG API.
uint64_t Tick
Tick count type.
void initCPU(ThreadContext *tc, int cpuId)
virtual TheISA::TLB * getDTBPtr()=0
const bool alwaysSyncTC
Be conservative and always synchronize the thread context on KVM entry/exit.
void deallocateContext(ThreadID thread_num)
void takeOverFrom(BaseCPU *cpu) override
struct kvm_coalesced_mmio_ring * mmioRing
Coalesced MMIO ring buffer.
The request is to an uncacheable address.
EventQueue * curEventQueue()
pthread_t vcpuThread
ID of the vCPU thread.
const RequestPtr req
A pointer to the original request.
PerfKvmCounterConfig & samplePeriod(uint64_t period)
Set the initial sample period (overflow count) of an event.
bool kvmStateDirty
Is the KVM state dirty? Set to true to force an update of the KVM vCPU state upon the next call to kv...
PerfKvmCounter hwInstructions
Guest instruction counter.
PerfKvmCounter hwCycles
Guest cycle counter.
Service completion in progress.
Requiring service at the beginning of the next cycle.
virtual Tick handleKvmExitException()
An unhandled virtualization exception occured.
void setSignalMask(const sigset_t *mask)
Set the signal mask used in kvmRun()
Stats::Scalar numVMHalfEntries
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
void attach(PerfKvmCounterConfig &config, pid_t tid)
Attach a counter.
Draining buffers pending serialization/handover.
virtual bool archIsDrained() const
Is the architecture specific code in a state that prevents draining?
int64_t Counter
Statistics counter type.
void setupInstStop()
Setup an instruction break if there is one pending.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
EventQueue * eventQueue() const
Status _status
CPU run state.
void kvmInterrupt(const struct kvm_interrupt &interrupt)
Send a normal interrupt to the guest.
Stats::Scalar numHypercalls
BaseKvmCPU(BaseKvmCPUParams *params)
void setFPUState(const struct kvm_fpu &state)
PerfKvmCounterConfig & exclude_host(bool val)
Exclude the events from the host (i.e., only include events from the guest system).
std::queue< PacketPtr > pendingMMIOPkts
Pending MMIO packets.
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
int16_t ThreadID
Thread index/ID type.
const long pageSize
Cached page size of the host.
PerfKvmCounterConfig & disabled(bool val)
Don't start the performance counter automatically when attaching it.
static void onKickSignal(int signo, siginfo_t *si, void *data)
Dummy handler for KVM kick signals.
PerfKvmCounterConfig & exclude_hv(bool val)
Exclude the hyper visor (i.e., only include events from the guest system).
KVMCpuPort dataPort
Port for data requests.
void ioctlRun()
Execute the KVM_RUN ioctl.
std::ostream CheckpointOut
void kick() const
Force an exit from KVM.
PerfEvent counter configuration.
int vcpuFD
KVM vCPU file descriptor.
void setRegisters(const struct kvm_regs ®s)
void getOneReg(uint64_t id, void *addr) const
std::string getAndFormatOneReg(uint64_t id) const
Get and format one register for printout.
void setupInstCounter(uint64_t period=0)
Setup the guest instruction counter.
virtual void dump() const
Dump the internal state to the terminal.
int capCoalescedMMIO() const
Check if coalesced MMIO is supported and which page in the MMAP'ed structure it stores requests in...
virtual int contextId() const =0
void stop()
Stop counting.
void suspendContext(ThreadID thread_num) override
virtual Tick handleKvmExitHypercall()
The guest requested a monitor service using a hypercall.
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
virtual uint64_t getHostCycles() const
Get the value of the hardware cycle counter in the guest.
virtual Status status() const =0
Kvm * kvm
Global KVM interface.
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Status nextIOState() const
Returns next valid state after one or more IO accesses.
void serialize(CheckpointOut &cp) const override
Serialize an object.
Context not scheduled in KVM.
Counter totalOps() const override
virtual Tick handleKvmExitUnknown()
An unknown architecture dependent error occurred when starting the vCPU.
SimpleThread * thread
A cached copy of a thread's state in the form of a SimpleThread object.
void start()
Start counting.
int getVCPUMMapSize() const
Get the size of the MMAPed parameter area used to communicate vCPU parameters between the kernel and ...
void getFPUState(struct kvm_fpu &state) const
Get/Set the guest FPU/vector state.
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
Temporarily release the event queue service lock.
void switchOut() override
void getRegisters(struct kvm_regs ®s) const
Get/Set the register state of the guest vCPU.
bool attached() const
Check if a counter is attached.
virtual void initMemProxies(ThreadContext *tc)=0
Initialise the physical and virtual port proxies and tie them to the data port of the CPU...
virtual Tick handleKvmExit()
Main kvmRun exit handler, calls the relevant handleKvmExit* depending on exit type.
std::shared_ptr< FaultBase > Fault
unsigned int activeMMIOReqs
Number of MMIO requests in flight.
Tick doMMIOAccess(Addr paddr, void *data, int size, bool write)
Inject a memory mapped IO request into gem5.
Timer based on standard POSIX timers.
Stats::Scalar numCoalescedMMIO
PerfEvent based timer using the host's CPU cycle counter.
const FlagsType init
This Stat is Initialized.
void startupThread()
Thread-specific initialization.
void syncThreadContext()
Update a thread context if the KVM state is dirty with respect to the cached thread context...
void haltContext(ThreadID thread_num) override
ProbePointArg< PacketInfo > Packet
Packet probe point.
void getSpecialRegisters(struct kvm_sregs ®s) const
int ioctl(int request, long p1) const
vCPU ioctl interface.