50#include "debug/Checkpoint.hh"
51#include "debug/Drain.hh"
52#include "debug/Kvm.hh"
53#include "debug/KvmIO.hh"
54#include "debug/KvmRun.hh"
55#include "params/BaseKvmCPU.hh"
60#define PAGE_SIZE pageSize
69 dataPort(
name() +
".dcache_port", this),
70 instPort(
name() +
".icache_port", this),
71 alwaysSyncTC(params.alwaysSyncTC),
72 threadContextDirty(true),
74 usePerf(params.usePerf),
75 vcpuID(-1), vcpuFD(-1), vcpuMMapSize(0),
76 _kvmRun(NULL), mmioRing(NULL),
77 pageSize(sysconf(_SC_PAGE_SIZE)),
78 tickEvent([this]{
tick(); },
"BaseKvmCPU tick",
82 hwInstructions(
nullptr),
83 perfControlledByTimer(params.usePerfOverflow),
84 hostFactor(params.hostFactor), stats(
this),
88 panic(
"KVM: Failed to determine host page size (%i)\n",
92 thread =
new SimpleThread(
this, 0, params.system, params.mmu,
93 params.isa[0], params.decoder[0]);
96 params.workload[0], params.mmu,
97 params.isa[0], params.decoder[0]);
100 tc = thread->getTC();
101 threadContexts.push_back(tc);
103 if ((!usePerf) && perfControlledByTimer) {
104 panic(
"KVM: invalid combination of parameters: cannot use "
105 "perfControlledByTimer without usePerf\n");
110 hwCycles = std::unique_ptr<PerfKvmCounter>(
new PerfKvmCounter());
111 hwInstructions = std::unique_ptr<PerfKvmCounter>(
new PerfKvmCounter());
113 inform(
"Using KVM CPU without perf. The stats related to the number "
114 "of cycles and instructions executed by the KVM CPU will not "
115 "be updated. The stats should not be used for performance "
139 const BaseKvmCPUParams &
p =
140 dynamic_cast<const BaseKvmCPUParams &
>(
params());
159 PROT_READ | PROT_WRITE, MAP_SHARED,
162 panic(
"KVM: Failed to map run data structure\n");
168 if (!
p.useCoalescedMMIO) {
169 inform(
"KVM: Coalesced MMIO disabled by config.\n");
170 }
else if (mmioOffset) {
171 inform(
"KVM: Coalesced IO available\n");
172 mmioRing = (
struct kvm_coalesced_mmio_ring *)(
175 inform(
"KVM: Coalesced not supported by host OS\n");
193 if (cpu->system->isAtomicMode()) {
194 Tick delay = sendAtomic(pkt);
198 if (pendingMMIOPkts.empty() && sendTimingReq(pkt)) {
201 pendingMMIOPkts.push(pkt);
211 DPRINTF(KvmIO,
"KVM: Finished timing request\n");
218 if (!(activeMMIOReqs || pendingMMIOPkts.size())) {
219 DPRINTF(KvmIO,
"KVM: Finished all outstanding timing requests\n");
220 cpu->finishMMIOPending();
228 DPRINTF(KvmIO,
"KVM: Retry for timing request\n");
230 assert(pendingMMIOPkts.size());
235 while (pendingMMIOPkts.size() && sendTimingReq(pendingMMIOPkts.front())) {
236 pendingMMIOPkts.pop();
258 const BaseKvmCPUParams &
p =
259 dynamic_cast<const BaseKvmCPUParams &
>(
params());
269 if (
p.usePerfOverflow) {
282 : statistics::
Group(parent),
283 ADD_STAT(numVMExits, statistics::units::Count::get(),
284 "total number of KVM exits"),
285 ADD_STAT(numVMHalfEntries, statistics::units::Count::get(),
286 "number of KVM entries to finalize pending operations"),
287 ADD_STAT(numExitSignal, statistics::units::Count::get(),
288 "exits due to signal delivery"),
289 ADD_STAT(numMMIO, statistics::units::Count::get(),
290 "number of VM exits due to memory mapped IO"),
291 ADD_STAT(numCoalescedMMIO, statistics::units::Count::get(),
292 "number of coalesced memory mapped IO requests"),
293 ADD_STAT(numIO, statistics::units::Count::get(),
294 "number of VM exits due to legacy IO"),
295 ADD_STAT(numHalt, statistics::units::Count::get(),
296 "number of VM exits due to wait for interrupt instructions"),
297 ADD_STAT(numInterrupts, statistics::units::Count::get(),
298 "number of interrupts delivered"),
299 ADD_STAT(numHypercalls, statistics::units::Count::get(),
"number of hypercalls")
306 if (debug::Checkpoint) {
307 DPRINTF(Checkpoint,
"KVM: Serializing thread %i:\n", tid);
319 DPRINTF(Checkpoint,
"KVM: Unserialize thread %i:\n", tid);
333 DPRINTF(Drain,
"BaseKvmCPU::drain\n");
377 DPRINTF(Drain,
"KVM CPU is waiting for service completion, "
378 "requesting drain.\n");
383 DPRINTF(Drain,
"KVM CPU is waiting for timing accesses to complete, "
384 "requesting drain.\n");
389 DPRINTF(Drain,
"KVM CPU is waiting for service, requesting drain.\n");
393 panic(
"KVM: Unhandled CPU state in drain()\n");
438 warn(
"kvm CPU: notifyFork failed to close vcpuFD\n");
493 fatal(
"The KVM-based CPUs requires the memory system to be in the "
494 "'noncaching' mode.\n");
519 DPRINTF(
Kvm,
"ActivateContext %d\n", thread_num);
521 assert(thread_num == 0);
538 DPRINTF(
Kvm,
"SuspendContext %d\n", thread_num);
540 assert(thread_num == 0);
591 hack_once(
"Pretending totalOps is equivalent to totalInsts()\n");
598 inform(
"State dumping not implemented.");
619 const uint64_t nextInstEvent(
620 queue.empty() ?
MaxTick : queue.nextTick());
623 const Tick ticksToExecute(
636 if (ticksToExecute > 0)
639 DPRINTF(KvmRun,
"Entering KVM...\n");
647 delay =
kvmRun(ticksToExecute);
666 if (
_kvmRun->exit_reason != KVM_EXIT_INTR) {
683 panic(
"BaseKvmCPU entered tick() in an illegal state (%i)\n",
724 "Trying to run a KVM CPU in a forked child process. "
725 "This is not supported.\n");
726 DPRINTF(KvmRun,
"KVM: Executing for %i ticks\n", ticks);
732 DPRINTF(KvmRun,
"KVM: Delivering IO without full guest entry\n");
763 if (ticks < runTimer->resolution()) {
764 DPRINTF(KvmRun,
"KVM: Adjusting tick count (%i -> %i)\n",
772 uint64_t baseInstrs = 0;
800 const uint64_t hostCyclesExecuted(
getHostCycles() - baseCycles);
801 const uint64_t simCyclesExecuted(hostCyclesExecuted *
hostFactor);
802 uint64_t instsExecuted = 0;
806 ticksExecuted =
runTimer->ticksFromHostCycles(hostCyclesExecuted);
815 "KVM: Executed %i instructions in %i cycles "
816 "(%i ticks, sim cycles: %i).\n",
817 instsExecuted, hostCyclesExecuted, ticksExecuted, simCyclesExecuted);
829 if (
ioctl(KVM_NMI) == -1)
830 panic(
"KVM: Failed to deliver NMI to virtual CPU\n");
837 if (
ioctl(KVM_INTERRUPT, (
void *)&interrupt) == -1)
838 panic(
"KVM: Failed to deliver interrupt to virtual CPU\n");
844 if (
ioctl(KVM_GET_REGS, ®s) == -1)
845 panic(
"KVM: Failed to get guest registers\n");
851 if (
ioctl(KVM_SET_REGS, (
void *)®s) == -1)
852 panic(
"KVM: Failed to set guest registers\n");
858 if (
ioctl(KVM_GET_SREGS, ®s) == -1)
859 panic(
"KVM: Failed to get guest special registers\n");
865 if (
ioctl(KVM_SET_SREGS, (
void *)®s) == -1)
866 panic(
"KVM: Failed to set guest special registers\n");
873 panic(
"KVM: Failed to get guest FPU state\n");
880 panic(
"KVM: Failed to set guest FPU state\n");
887#ifdef KVM_SET_ONE_REG
888 struct kvm_one_reg
reg;
892 if (
ioctl(KVM_SET_ONE_REG, &
reg) == -1) {
893 panic(
"KVM: Failed to set register (0x%x) value (errno: %i)\n",
897 panic(
"KVM_SET_ONE_REG is unsupported on this platform.\n");
904#ifdef KVM_GET_ONE_REG
905 struct kvm_one_reg
reg;
909 if (
ioctl(KVM_GET_ONE_REG, &
reg) == -1) {
910 panic(
"KVM: Failed to get register (0x%x) value (errno: %i)\n",
914 panic(
"KVM_GET_ONE_REG is unsupported on this platform.\n");
921#ifdef KVM_GET_ONE_REG
922 std::ostringstream
ss;
924 ss.setf(std::ios::hex, std::ios::basefield);
925 ss.setf(std::ios::showbase);
926#define HANDLE_INTTYPE(len) \
927 case KVM_REG_SIZE_U ## len: { \
928 uint ## len ## _t value; \
929 getOneReg(id, &value); \
933#define HANDLE_ARRAY(len) \
934 case KVM_REG_SIZE_U ## len: { \
935 uint8_t value[len / 8]; \
936 getOneReg(id, value); \
937 ccprintf(ss, "[0x%x", value[0]); \
938 for (int i = 1; i < len / 8; ++i) \
939 ccprintf(ss, ", 0x%x", value[i]); \
943 switch (
id & KVM_REG_SIZE_MASK) {
961 panic(
"KVM_GET_ONE_REG is unsupported on this platform.\n");
992 DPRINTF(KvmRun,
"handleKvmExit (exit_reason: %i)\n",
_kvmRun->exit_reason);
998 switch (
_kvmRun->exit_reason) {
999 case KVM_EXIT_UNKNOWN:
1002 case KVM_EXIT_EXCEPTION:
1013 case KVM_EXIT_HYPERCALL:
1031 DPRINTF(KvmIO,
"KVM: Handling MMIO (w: %u, addr: 0x%x, len: %u)\n",
1045 case KVM_EXIT_IRQ_WINDOW_OPEN:
1048 case KVM_EXIT_FAIL_ENTRY:
1056 case KVM_EXIT_INTERNAL_ERROR:
1057 panic(
"KVM: Internal error (suberror: %u)\n",
1062 panic(
"KVM: Unexpected exit (exit_reason: %u)\n",
_kvmRun->exit_reason);
1069 panic(
"KVM: Unhandled guest IO (dir: %i, size: %i, port: 0x%x, count: %i)\n",
1077 panic(
"KVM: Unhandled hypercall\n");
1083 warn(
"KVM: Unhandled IRQ window.\n");
1092 panic(
"KVM: Unknown error when starting vCPU (hw reason: 0x%llx)\n",
1093 _kvmRun->hw.hardware_exit_reason);
1100 panic(
"KVM: Got exception when starting vCPU "
1101 "(exception: %u, error_code: %u)\n",
1109 panic(
"KVM: Failed to enter virtualized mode (hw reason: 0x%llx)\n",
1110 _kvmRun->fail_entry.hardware_entry_failure_reason);
1119 RequestPtr mmio_req = std::make_shared<Request>(
1130 warn(
"Finalization of MMIO address failed: %s\n", fault->name());
1135 pkt->dataStatic(
data);
1137 if (mmio_req->isLocalAccess()) {
1152 const Cycles ipr_delay = mmio_req->localAccessor(
tc, pkt);
1168 std::unique_ptr<
struct kvm_signal_mask, void(*)(
void *
p)>
1169 kvm_mask(
nullptr, [](
void *
p) {
operator delete(
p); });
1172 kvm_mask.reset((
struct kvm_signal_mask *)
operator new(
1173 sizeof(
struct kvm_signal_mask) + sizeof(*
mask)));
1177 assert(
sizeof(*
mask) >= 8);
1179 memcpy(kvm_mask->sigset,
mask, kvm_mask->len);
1182 if (
ioctl(KVM_SET_SIGNAL_MASK, (
void *)kvm_mask.get()) == -1)
1183 panic(
"KVM: Failed to set vCPU signal mask (errno: %i)\n",
1191 panic(
"KVM: CPU ioctl called before initialization\n");
1193 return ::ioctl(
vcpuFD, request, p1);
1202 DPRINTF(KvmIO,
"KVM: Flushing the coalesced MMIO ring buffer\n");
1208 struct kvm_coalesced_mmio &ent(
1211 DPRINTF(KvmIO,
"KVM: Handling coalesced MMIO (addr: 0x%x, len: %u)\n",
1212 ent.phys_addr, ent.len);
1215 ticks +=
doMMIOAccess(ent.phys_addr, ent.data, ent.len,
true);
1241 struct sigaction
sa;
1243 memset(&
sa, 0,
sizeof(
sa));
1245 sa.sa_flags = SA_SIGINFO | SA_RESTART;
1247 panic(
"KVM: Failed to setup vCPU timer signal handler\n");
1250 if (pthread_sigmask(SIG_BLOCK, NULL, &sigset) == -1)
1251 panic(
"KVM: Failed get signal mask\n");
1263 if (pthread_sigmask(SIG_SETMASK, &sigset, NULL) == -1)
1264 panic(
"KVM: Failed mask the KVM control signals\n");
1270 int discardedSignal;
1274 struct timespec timeout;
1276 timeout.tv_nsec = 0;
1279 sigemptyset(&sigset);
1280 sigaddset(&sigset, signum);
1283 discardedSignal = sigtimedwait(&sigset, NULL, &timeout);
1284 }
while (discardedSignal == -1 && errno == EINTR);
1286 if (discardedSignal == signum)
1288 else if (discardedSignal == -1 && errno == EAGAIN)
1291 panic(
"Unexpected return value from sigtimedwait: %i (errno: %i)\n",
1292 discardedSignal, errno);
1298 DPRINTF(
Kvm,
"Attaching cycle counter...\n");
1300 PERF_COUNT_HW_CPU_CYCLES);
1339 DPRINTF(Drain,
"tryDrain: Architecture code is not ready.\n");
1345 "tryDrain: CPU transitioned into the Idle state, drain done\n");
1349 DPRINTF(Drain,
"tryDrain: CPU not ready.\n");
1357 if (
ioctl(KVM_RUN) == -1) {
1359 panic(
"KVM: Failed to start virtual CPU (errno: %i)\n",
1391 PERF_COUNT_HW_INSTRUCTIONS);
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
std::vector< std::unique_ptr< CommitCPUStats > > commitStats
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
void startup() override
startup() is the final initialization call before simulation.
virtual void switchOut()
Prepare for another CPU to take over execution.
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
std::vector< ThreadContext * > threadContexts
bool switchedOut() const
Determine if the CPU is switched out.
std::queue< PacketPtr > pendingMMIOPkts
Pending MMIO packets.
Status nextIOState() const
Returns next valid state after one or more IO accesses.
Tick submitIO(PacketPtr pkt)
Interface to send Atomic or Timing IO request.
void recvReqRetry() override
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
unsigned int activeMMIOReqs
Number of MMIO requests in flight.
virtual void dump() const
Dump the internal state to the terminal.
int vcpuFD
KVM vCPU file descriptor.
void finishMMIOPending()
Callback from KvmCPUPort to transition the CPU out of RunningMMIOPending when all timing requests hav...
Status _status
CPU run state.
uint64_t activeInstPeriod
Currently active instruction count breakpoint.
virtual void updateKvmState()=0
Update the KVM state from the current thread context.
struct kvm_coalesced_mmio_ring * mmioRing
Coalesced MMIO ring buffer.
virtual Tick handleKvmExitHypercall()
The guest requested a monitor service using a hypercall.
long vcpuID
KVM internal ID of the vCPU.
void drainResume() override
Resume execution after a successful drain.
void getSpecialRegisters(struct kvm_sregs ®s) const
virtual void updateThreadContext()=0
Update the current thread context with the KVM state.
void takeOverFrom(BaseCPU *cpu) override
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
virtual uint64_t getHostCycles() const
Get the value of the hardware cycle counter in the guest.
Counter totalInsts() const override
void getOneReg(uint64_t id, void *addr) const
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
const bool alwaysSyncTC
Be conservative and always synchronize the thread context on KVM entry/exit.
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
virtual Tick handleKvmExitIRQWindowOpen()
The guest exited because an interrupt window was requested.
void setSignalMask(const sigset_t *mask)
Set the signal mask used in kvmRun()
void notifyFork() override
Notify a child process of a fork.
int vcpuMMapSize
Size of MMAPed kvm_run area.
void syncKvmState()
Update the KVM if the thread context is dirty.
bool tryDrain()
Try to drain the CPU if a drain is pending.
void setRegisters(const struct kvm_regs ®s)
BaseKvmCPU(const BaseKvmCPUParams ¶ms)
virtual Tick handleKvmExitException()
An unhandled virtualization exception occured.
void kick() const
Force an exit from KVM.
@ Running
Running normally.
@ Idle
Context not scheduled in KVM.
@ RunningMMIOPending
Timing MMIO request in flight or stalled.
@ RunningService
Requiring service at the beginning of the next cycle.
@ RunningServiceCompletion
Service completion in progress.
void deallocateContext(ThreadID thread_num)
void getRegisters(struct kvm_regs ®s) const
Get/Set the register state of the guest vCPU.
void setupSignalHandler()
Setup a signal handler to catch the timer signal used to switch back to the monitor.
void setSpecialRegisters(const struct kvm_sregs ®s)
ThreadContext * getContext(int tn) override
Given a thread num get tho thread context for it.
bool usePerf
True if using perf; False otherwise.
virtual Tick handleKvmExitIO()
The guest performed a legacy IO request (out/inp on x86)
std::string getAndFormatOneReg(uint64_t id) const
Get and format one register for printout.
gem5::BaseKvmCPU::StatGroup stats
virtual Tick handleKvmExit()
Main kvmRun exit handler, calls the relevant handleKvmExit* depending on exit type.
void syncThreadContext()
Update a thread context if the KVM state is dirty with respect to the cached thread context.
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Tick doMMIOAccess(Addr paddr, void *data, int size, bool write)
Inject a memory mapped IO request into gem5.
void wakeup(ThreadID tid=0) override
void startup() override
startup() is the final initialization call before simulation.
Counter totalOps() const override
Tick flushCoalescedMMIO()
Service MMIO requests in the mmioRing.
std::unique_ptr< PerfKvmCounter > hwInstructions
Guest instruction counter.
EventFunctionWrapper tickEvent
bool perfControlledByTimer
Does the runTimer control the performance counters?
virtual Tick kvmRun(Tick ticks)
Request KVM to run the guest for a given number of ticks.
void setupInstStop()
Setup an instruction break if there is one pending.
bool discardPendingSignal(int signum) const
Discard a (potentially) pending signal.
virtual Tick kvmRunDrain()
Request the CPU to run until draining completes.
virtual Tick handleKvmExitFailEntry()
KVM failed to start the virtualized CPU.
void switchOut() override
Prepare for another CPU to take over execution.
void restartEqThread()
Thread-specific initialization.
void setupCounters()
Setup hardware performance counters.
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
Serialize a single thread.
void setupInstCounter(uint64_t period=0)
Setup the guest instruction counter.
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
void tick()
Execute the CPU until the next event in the main event queue or until the guest needs service from ge...
virtual bool archIsDrained() const
Is the architecture specific code in a state that prevents draining?
struct kvm_run * _kvmRun
Pointer to the kvm_run structure used to communicate parameters with KVM.
std::unique_ptr< PerfKvmCounter > hwCycles
Guest cycle counter.
void setOneReg(uint64_t id, const void *addr)
Get/Set single register using the KVM_(SET|GET)_ONE_REG API.
std::unique_ptr< BaseKvmTimer > runTimer
Timer used to force execution into the monitor after a specified number of simulation tick equivalent...
KVMCpuPort dataPort
Port for data requests.
SimpleThread * thread
A cached copy of a thread's state in the form of a SimpleThread object.
void setFPUState(const struct kvm_fpu &state)
virtual Tick handleKvmExitUnknown()
An unknown architecture dependent error occurred when starting the vCPU.
void getFPUState(struct kvm_fpu &state) const
Get/Set the guest FPU/vector state.
void haltContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now halted.
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...
EventQueue * deviceEventQueue()
Get a pointer to the event queue owning devices.
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
bool threadContextDirty
Is the gem5 context dirty? Set to true to force an update of the KVM vCPU state upon the next call to...
const long pageSize
Cached page size of the host.
pthread_t vcpuThread
ID of the vCPU thread.
Counter ctrInsts
Number of instructions executed by the CPU.
float hostFactor
Host factor as specified in the configuration.
ThreadContext * tc
ThreadContext object, provides an interface for external objects to modify this thread's state.
virtual void ioctlRun()
Execute the KVM_RUN ioctl.
virtual void stutterPC(PCStateBase &pc) const =0
Modify a PCStatePtr's value so that its next PC is the current PC.
virtual Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc, Mode mode) const
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
int createVCPU(long vcpuID)
Create a new vCPU within a VM.
Kvm * kvm
Global KVM interface.
long allocVCPUID()
Allocate a new vCPU ID within the VM.
void cpuStartup()
VM CPU initialization code.
int getVCPUMMapSize() const
Get the size of the MMAPed parameter area used to communicate vCPU parameters between the kernel and ...
int capCoalescedMMIO() const
Check if coalesced MMIO is supported and which page in the MMAP'ed structure it stores requests in.
virtual std::string name() const
virtual PCStateBase * clone() const =0
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
PerfEvent counter configuration.
PerfKvmCounterConfig & samplePeriod(uint64_t period)
Set the initial sample period (overflow count) of an event.
PerfKvmCounterConfig & disabled(bool val)
Don't start the performance counter automatically when attaching it.
PerfKvmCounterConfig & exclude_host(bool val)
Exclude the events from the host (i.e., only include events from the guest system).
PerfKvmCounterConfig & exclude_hv(bool val)
Exclude the hyper visor (i.e., only include events from the guest system).
PerfKvmCounterConfig & pinned(bool val)
Force the group to be on the active all the time (i.e., disallow multiplexing).
PerfKvmCounterConfig & wakeupEvents(uint32_t events)
Set the number of samples that need to be triggered before reporting data as being available on the p...
PerfEvent based timer using the host's CPU cycle counter.
Timer based on standard POSIX timers.
@ UNCACHEABLE
The request is to an uncacheable address.
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
int threadId() const override
void serialize(CheckpointOut &cp) const override
Serialize an object.
Status status() const override
void suspend() override
Set the status to Suspended.
void activate() override
Set the status to Active.
EventQueue comInstEventQueue
An instruction-based event queue.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
KvmVM * getKvmVM() const
Get a pointer to the Kernel Virtual Machine (KVM) SimObject, if present.
bool bypassCaches() const
Should caches be bypassed?
ThreadContext is the external interface to all thread state for anything outside of the CPU.
@ Halted
Permanently shut down.
@ Suspended
Temporarily inactive.
virtual const PCStateBase & pcState() const =0
virtual Status status() const =0
virtual BaseMMU * getMMUPtr()=0
virtual ContextID contextId() const =0
#define KVM_KICK_SIGNAL
Signal to use to trigger exits from KVM.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void kvmInterrupt(const struct kvm_interrupt &interrupt)
Send a normal interrupt to the guest.
void kvmNonMaskableInterrupt()
Send a non-maskable interrupt to the guest.
int ioctl(int request, long p1) const
vCPU ioctl interface.
void signalDrainDone() const
Signal that an object is drained.
DrainState drainState() const
Return the current drain state of an object.
DrainState
Object drain/handover states.
@ Draining
Draining buffers pending serialization/handover.
@ Drained
Buffers drained, ready for serialization/handover.
void deschedule(Event &event)
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
bool empty() const
Returns true if no events are queued.
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
EventQueue * eventQueue() const
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define fatal(...)
This implements a cprintf based fatal() function.
const Params & params() const
double Counter
All counters are of 64-bit values.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
std::shared_ptr< Request > RequestPtr
static void onKickSignal(int signo, siginfo_t *si, void *data)
Dummy handler for KVM kick signals.
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
uint64_t Tick
Tick count type.
EventQueue * curEventQueue()
constexpr decltype(nullptr) NoFault
statistics::Scalar numInsts
statistics::Scalar numCycles
statistics::Scalar numExitSignal
StatGroup(statistics::Group *parent)
statistics::Scalar numHypercalls
statistics::Scalar numHalt
statistics::Scalar numVMHalfEntries
statistics::Scalar numMMIO
statistics::Scalar numCoalescedMMIO
statistics::Scalar numInterrupts
statistics::Scalar numVMExits
Tick lastSuspend
Last time suspend was called on this thread.
Tick lastActivate
Last time activate was called on this thread.
const std::string & name()