1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Sandberg
38 */
39
40#ifndef __CPU_KVM_BASE_HH__
41#define __CPU_KVM_BASE_HH__
42
43#include <pthread.h>
44
45#include <csignal>
46#include <memory>
47#include <queue>
48
49#include "base/statistics.hh"
50#include "cpu/kvm/perfevent.hh"
51#include "cpu/kvm/timer.hh"
52#include "cpu/kvm/vm.hh"
53#include "cpu/base.hh"
54#include "cpu/simple_thread.hh"
55
56/** Signal to use to trigger exits from KVM */
57#define KVM_KICK_SIGNAL SIGRTMIN
58
59// forward declarations
60class ThreadContext;
61struct BaseKvmCPUParams;
62
63/**
64 * Base class for KVM based CPU models
65 *
66 * All architecture specific KVM implementation should inherit from
67 * this class. The most basic CPU models only need to override the
68 * updateKvmState() and updateThreadContext() methods to implement
69 * state synchronization between gem5 and KVM.
70 *
71 * The architecture specific implementation is also responsible for
72 * delivering interrupts into the VM. This is typically done by
73 * overriding tick() and checking the thread context before entering
74 * into the VM. In order to deliver an interrupt, the implementation
75 * then calls KvmVM::setIRQLine() or BaseKvmCPU::kvmInterrupt()
76 * depending on the specifics of the underlying hardware/drivers.
77 */
78class BaseKvmCPU : public BaseCPU
79{
80 public:
81 BaseKvmCPU(BaseKvmCPUParams *params);
82 virtual ~BaseKvmCPU();
83
84 void init() override;
85 void startup() override;
86 void regStats() override;
87
88 void serializeThread(CheckpointOut &cp, ThreadID tid) const override;
89 void unserializeThread(CheckpointIn &cp, ThreadID tid) override;
90
91 DrainState drain() override;
92 void drainResume() override;
93 void notifyFork() override;
94
95 void switchOut() override;
96 void takeOverFrom(BaseCPU *cpu) override;
97
98 void verifyMemoryMode() const override;
99
100 MasterPort &getDataPort() override { return dataPort; }
101 MasterPort &getInstPort() override { return instPort; }
102
103 void wakeup(ThreadID tid = 0) override;
104 void activateContext(ThreadID thread_num) override;
105 void suspendContext(ThreadID thread_num) override;
106 void deallocateContext(ThreadID thread_num);
107 void haltContext(ThreadID thread_num) override;
108
109 long getVCpuID() const { return vcpuID; }
110 ThreadContext *getContext(int tn) override;
111
112 Counter totalInsts() const override;
113 Counter totalOps() const override;
114
115 /**
116 * Callback from KvmCPUPort to transition the CPU out of RunningMMIOPending
117 * when all timing requests have completed.
118 */
119 void finishMMIOPending();
120
121 /** Dump the internal state to the terminal. */
122 virtual void dump() const;
123
124 /**
125 * Force an exit from KVM.
126 *
127 * Send a signal to the thread owning this vCPU to get it to exit
128 * from KVM. Ignored if the vCPU is not executing.
129 */
130 void kick() const { pthread_kill(vcpuThread, KVM_KICK_SIGNAL); }
131
132 /**
133 * A cached copy of a thread's state in the form of a SimpleThread
134 * object.
135 *
136 * Normally the actual thread state is stored in the KVM vCPU. If KVM has
137 * been running this copy is will be out of date. If we recently handled
138 * some events within gem5 that required state to be updated this could be
139 * the most up-to-date copy. When getContext() or updateThreadContext() is
140 * called this copy gets updated. The method syncThreadContext can
141 * be used within a KVM CPU to update the thread context if the
142 * KVM state is dirty (i.e., the vCPU has been run since the last
143 * update).
144 */
145 SimpleThread *thread;
146
147 /** ThreadContext object, provides an interface for external
148 * objects to modify this thread's state.
149 */
150 ThreadContext *tc;
151
152 KvmVM &vm;
153
154 protected:
155 /**
156 *
157 * @dot
158 * digraph {
159 * Idle;
160 * Running;
161 * RunningService;
162 * RunningServiceCompletion;
163 * RunningMMIOPending;
164 *
165 * Idle -> Idle;
166 * Idle -> Running [label="activateContext()", URL="\ref activateContext"];
167 * Running -> Running [label="tick()", URL="\ref tick"];
168 * Running -> RunningService [label="tick()", URL="\ref tick"];
169 * Running -> Idle [label="suspendContext()", URL="\ref suspendContext"];
170 * Running -> Idle [label="drain()", URL="\ref drain"];
171 * Idle -> Running [label="drainResume()", URL="\ref drainResume"];
172 * RunningService -> RunningServiceCompletion [label="handleKvmExit()", URL="\ref handleKvmExit"];
173 * RunningService -> RunningMMIOPending [label="handleKvmExit()", URL="\ref handleKvmExit"];
174 * RunningMMIOPending -> RunningServiceCompletion [label="finishMMIOPending()", URL="\ref finishMMIOPending"];
175 * RunningServiceCompletion -> Running [label="tick()", URL="\ref tick"];
176 * RunningServiceCompletion -> RunningService [label="tick()", URL="\ref tick"];
177 * }
178 * @enddot
179 */
180 enum Status {
181 /** Context not scheduled in KVM.
182 *
183 * The CPU generally enters this state when the guest execute
184 * an instruction that halts the CPU (e.g., WFI on ARM or HLT
185 * on X86) if KVM traps this instruction. Ticks are not
186 * scheduled in this state.
187 *
188 * @see suspendContext()
189 */
190 Idle,
191 /** Running normally.
192 *
193 * This is the normal run state of the CPU. KVM will be
194 * entered next time tick() is called.
195 */
196 Running,
197 /** Requiring service at the beginning of the next cycle.
198 *
199 * The virtual machine has exited and requires service, tick()
200 * will call handleKvmExit() on the next cycle. The next state
201 * after running service is determined in handleKvmExit() and
202 * depends on what kind of service the guest requested:
203 * <ul>
204 * <li>IO/MMIO (Atomic): RunningServiceCompletion
205 * <li>IO/MMIO (Timing): RunningMMIOPending
206 * <li>Halt: Idle
207 * <li>Others: Running
208 * </ul>
209 */
210 RunningService,
211 /** Timing MMIO request in flight or stalled.
212 *
213 * The VM has requested IO/MMIO and we are in timing mode. A timing
214 * request is either stalled (and will be retried with recvReqRetry())
215 * or it is in flight. After the timing request is complete, the CPU
216 * will transition to the RunningServiceCompletion state.
217 */
218 RunningMMIOPending,
219 /** Service completion in progress.
220 *
221 * The VM has requested service that requires KVM to be
222 * entered once in order to get to a consistent state. This
223 * happens in handleKvmExit() or one of its friends after IO
224 * exits. After executing tick(), the CPU will transition into
225 * the Running or RunningService state.
226 */
227 RunningServiceCompletion,
228 };
229
230 /** CPU run state */
231 Status _status;
232
233 /**
234 * Execute the CPU until the next event in the main event queue or
235 * until the guest needs service from gem5.
236 */
237 void tick();
238
239 /**
240 * Get the value of the hardware cycle counter in the guest.
241 *
242 * This method is supposed to return the total number of cycles
243 * executed in hardware mode relative to some arbitrary point in
244 * the past. It's mainly used when estimating the number of cycles
245 * actually executed by the CPU in kvmRun(). The default behavior
246 * of this method is to use the cycles performance counter, but
247 * some architectures may want to use internal registers instead.
248 *
249 * @return Number of host cycles executed relative to an undefined
250 * point in the past.
251 */
252 virtual uint64_t getHostCycles() const;
253
254 /**
255 * Request KVM to run the guest for a given number of ticks. The
256 * method returns the approximate number of ticks executed.
257 *
258 * @note The returned number of ticks can be both larger or
259 * smaller than the requested number of ticks. A smaller number
260 * can, for example, occur when the guest executes MMIO. A larger
261 * number is typically due to performance counter inaccuracies.
262 *
263 * @note This method is virtual in order to allow implementations
264 * to check for architecture specific events (e.g., interrupts)
265 * before entering the VM.
266 *
267 * @note It is the response of the caller (normally tick()) to
268 * make sure that the KVM state is synchronized and that the TC is
269 * invalidated after entering KVM.
270 *
271 * @note This method does not normally cause any state
272 * transitions. However, if it may suspend the CPU by suspending
273 * the thread, which leads to a transition to the Idle state. In
274 * such a case, kvm <i>must not</i> be entered.
275 *
276 * @param ticks Number of ticks to execute, set to 0 to exit
277 * immediately after finishing pending operations.
278 * @return Number of ticks executed (see note)
279 */
280 virtual Tick kvmRun(Tick ticks);
281
282 /**
283 * Request the CPU to run until draining completes.
284 *
285 * This function normally calls kvmRun(0) to make KVM finish
286 * pending MMIO operations. Architecures implementing
287 * archIsDrained() must override this method.
288 *
289 * @see BaseKvmCPU::archIsDrained()
290 *
291 * @return Number of ticks executed
292 */
293 virtual Tick kvmRunDrain();
294
295 /**
296 * Get a pointer to the kvm_run structure containing all the input
297 * and output parameters from kvmRun().
298 */
299 struct kvm_run *getKvmRunState() { return _kvmRun; };
300
301 /**
302 * Retrieve a pointer to guest data stored at the end of the
303 * kvm_run structure. This is mainly used for PIO operations
304 * (KVM_EXIT_IO).
305 *
306 * @param offset Offset as specified by the kvm_run structure
307 * @return Pointer to guest data
308 */
309 uint8_t *getGuestData(uint64_t offset) const {
310 return (uint8_t *)_kvmRun + offset;
311 };
312
313 /**
314 * @addtogroup KvmInterrupts
315 * @{
316 */
317 /**
318 * Send a non-maskable interrupt to the guest
319 *
320 * @note The presence of this call depends on Kvm::capUserNMI().
321 */
322 void kvmNonMaskableInterrupt();
323
324 /**
325 * Send a normal interrupt to the guest
326 *
327 * @note Make sure that ready_for_interrupt_injection in kvm_run
328 * is set prior to calling this function. If not, an interrupt
329 * window must be requested by setting request_interrupt_window in
330 * kvm_run to 1 and restarting the guest.
331 *
332 * @param interrupt Structure describing the interrupt to send
333 */
334 void kvmInterrupt(const struct kvm_interrupt &interrupt);
335
336 /** @} */
337
338 /** @{ */
339 /**
340 * Get/Set the register state of the guest vCPU
341 *
342 * KVM has two different interfaces for accessing the state of the
343 * guest CPU. One interface updates 'normal' registers and one
344 * updates 'special' registers. The distinction between special
345 * and normal registers isn't very clear and is architecture
346 * dependent.
347 */
348 void getRegisters(struct kvm_regs &regs) const;
349 void setRegisters(const struct kvm_regs &regs);
350 void getSpecialRegisters(struct kvm_sregs &regs) const;
351 void setSpecialRegisters(const struct kvm_sregs &regs);
352 /** @} */
353
354 /** @{ */
355 /**
356 * Get/Set the guest FPU/vector state
357 */
358 void getFPUState(struct kvm_fpu &state) const;
359 void setFPUState(const struct kvm_fpu &state);
360 /** @} */
361
362 /** @{ */
363 /**
364 * Get/Set single register using the KVM_(SET|GET)_ONE_REG API.
365 *
366 * @note The presence of this call depends on Kvm::capOneReg().
367 */
368 void setOneReg(uint64_t id, const void *addr);
369 void setOneReg(uint64_t id, uint64_t value) { setOneReg(id, &value); }
370 void setOneReg(uint64_t id, uint32_t value) { setOneReg(id, &value); }
371 void getOneReg(uint64_t id, void *addr) const;
372 uint64_t getOneRegU64(uint64_t id) const {
373 uint64_t value;
374 getOneReg(id, &value);
375 return value;
376 }
377 uint32_t getOneRegU32(uint64_t id) const {
378 uint32_t value;
379 getOneReg(id, &value);
380 return value;
381 }
382 /** @} */
383
384 /**
385 * Get and format one register for printout.
386 *
387 * This function call getOneReg() to retrieve the contents of one
388 * register and automatically formats it for printing.
389 *
390 * @note The presence of this call depends on Kvm::capOneReg().
391 */
392 std::string getAndFormatOneReg(uint64_t id) const;
393
394 /** @{ */
395 /**
396 * Update the KVM state from the current thread context
397 *
398 * The base CPU calls this method before starting the guest CPU
399 * when the contextDirty flag is set. The architecture dependent
400 * CPU implementation is expected to update all guest state
401 * (registers, special registers, and FPU state).
402 */
403 virtual void updateKvmState() = 0;
404
405 /**
406 * Update the current thread context with the KVM state
407 *
408 * The base CPU after the guest updates any of the KVM state. In
409 * practice, this happens after kvmRun is called. The architecture
410 * dependent code is expected to read the state of the guest CPU
411 * and update gem5's thread state.
412 */
413 virtual void updateThreadContext() = 0;
414
415 /**
416 * Update a thread context if the KVM state is dirty with respect
417 * to the cached thread context.
418 */
419 void syncThreadContext();
420
421 /**
422 * Get a pointer to the event queue owning devices.
423 *
424 * Devices always live in a separate device event queue when
425 * running in multi-core mode. We need to temporarily migrate to
426 * this queue when accessing devices. By convention, devices and
427 * the VM use the same event queue.
428 */
429 EventQueue *deviceEventQueue() { return vm.eventQueue(); }
430
431 /**
432 * Update the KVM if the thread context is dirty.
433 */
434 void syncKvmState();
435 /** @} */
436
437 /** @{ */
438 /**
439 * Main kvmRun exit handler, calls the relevant handleKvmExit*
440 * depending on exit type.
441 *
442 * @return Number of ticks spent servicing the exit request
443 */
444 virtual Tick handleKvmExit();
445
446 /**
447 * The guest performed a legacy IO request (out/inp on x86)
448 *
449 * @return Number of ticks spent servicing the IO request
450 */
451 virtual Tick handleKvmExitIO();
452
453 /**
454 * The guest requested a monitor service using a hypercall
455 *
456 * @return Number of ticks spent servicing the hypercall
457 */
458 virtual Tick handleKvmExitHypercall();
459
460 /**
461 * The guest exited because an interrupt window was requested
462 *
463 * The guest exited because an interrupt window was requested
464 * (request_interrupt_window in the kvm_run structure was set to 1
465 * before calling kvmRun) and it is now ready to receive
466 *
467 * @return Number of ticks spent servicing the IRQ
468 */
469 virtual Tick handleKvmExitIRQWindowOpen();
470
471 /**
472 * An unknown architecture dependent error occurred when starting
473 * the vCPU
474 *
475 * The kvm_run data structure contains the hardware error
476 * code. The defaults behavior of this method just prints the HW
477 * error code and panics. Architecture dependent implementations
478 * may want to override this method to provide better,
479 * hardware-aware, error messages.
480 *
481 * @return Number of ticks delay the next CPU tick
482 */
483 virtual Tick handleKvmExitUnknown();
484
485 /**
486 * An unhandled virtualization exception occured
487 *
488 * Some KVM virtualization drivers return unhandled exceptions to
489 * the user-space monitor. This interface is currently only used
490 * by the Intel VMX KVM driver.
491 *
492 * @return Number of ticks delay the next CPU tick
493 */
494 virtual Tick handleKvmExitException();
495
496 /**
497 * KVM failed to start the virtualized CPU
498 *
499 * The kvm_run data structure contains the hardware-specific error
500 * code.
501 *
502 * @return Number of ticks delay the next CPU tick
503 */
504 virtual Tick handleKvmExitFailEntry();
505 /** @} */
506
507 /**
508 * Is the architecture specific code in a state that prevents
509 * draining?
510 *
511 * This method should return false if there are any pending events
512 * in the guest vCPU that won't be carried over to the gem5 state
513 * and thus will prevent correct checkpointing or CPU handover. It
514 * might, for example, check for pending interrupts that have been
515 * passed to the vCPU but not acknowledged by the OS. Architecures
516 * implementing this method <i>must</i> override
517 * kvmRunDrain().
518 *
519 * @see BaseKvmCPU::kvmRunDrain()
520 *
521 * @return true if the vCPU is drained, false otherwise.
522 */
523 virtual bool archIsDrained() const { return true; }
524
525 /**
526 * Inject a memory mapped IO request into gem5
527 *
528 * @param paddr Physical address
529 * @param data Pointer to the source/destination buffer
530 * @param size Memory access size
531 * @param write True if write, False if read
532 * @return Number of ticks spent servicing the memory access
533 */
534 Tick doMMIOAccess(Addr paddr, void *data, int size, bool write);
535
536 /** @{ */
537 /**
538 * Set the signal mask used in kvmRun()
539 *
540 * This method allows the signal mask of the thread executing
541 * kvmRun() to be overridden inside the actual system call. This
542 * allows us to mask timer signals used to force KVM exits while
543 * in gem5.
544 *
545 * The signal mask can be disabled by setting it to NULL.
546 *
547 * @param mask Signals to mask
548 */
549 void setSignalMask(const sigset_t *mask);
550 /** @} */
551
552 /**
553 * @addtogroup KvmIoctl
554 * @{
555 */
556 /**
557 * vCPU ioctl interface.
558 *
559 * @param request KVM vCPU request
560 * @param p1 Optional request parameter
561 *
562 * @return -1 on error (error number in errno), ioctl dependent
563 * value otherwise.
564 */
565 int ioctl(int request, long p1) const;
566 int ioctl(int request, void *p1) const {
567 return ioctl(request, (long)p1);
568 }
569 int ioctl(int request) const {
570 return ioctl(request, 0L);
571 }
572 /** @} */
573
574
575 /**
576 * KVM memory port. Uses default MasterPort behavior and provides an
577 * interface for KVM to transparently submit atomic or timing requests.
578 */
579 class KVMCpuPort : public MasterPort
580 {
581
582 public:
583 KVMCpuPort(const std::string &_name, BaseKvmCPU *_cpu)
584 : MasterPort(_name, _cpu), cpu(_cpu), activeMMIOReqs(0)
585 { }
586 /**
587 * Interface to send Atomic or Timing IO request. Assumes that the pkt
588 * and corresponding req have been dynamically allocated and deletes
589 * them both if the system is in atomic mode.
590 */
591 Tick submitIO(PacketPtr pkt);
592
593 /** Returns next valid state after one or more IO accesses */
594 Status nextIOState() const;
595
596 protected:
597 /** KVM cpu pointer for finishMMIOPending() callback */
598 BaseKvmCPU *cpu;
599
600 /** Pending MMIO packets */
601 std::queue<PacketPtr> pendingMMIOPkts;
602
603 /** Number of MMIO requests in flight */
604 unsigned int activeMMIOReqs;
605
606 bool recvTimingResp(PacketPtr pkt) override;
607
608 void recvReqRetry() override;
609
610 };
611
612 /** Port for data requests */
613 KVMCpuPort dataPort;
614
615 /** Unused dummy port for the instruction interface */
616 KVMCpuPort instPort;
617
618 /**
619 * Be conservative and always synchronize the thread context on
620 * KVM entry/exit.
621 */
622 const bool alwaysSyncTC;
623
624 /**
625 * Is the gem5 context dirty? Set to true to force an update of
626 * the KVM vCPU state upon the next call to kvmRun().
627 */
628 bool threadContextDirty;
629
630 /**
631 * Is the KVM state dirty? Set to true to force an update of
632 * the KVM vCPU state upon the next call to kvmRun().
633 */
634 bool kvmStateDirty;
635
636 /** KVM internal ID of the vCPU */
637 const long vcpuID;
638
639 /** ID of the vCPU thread */
640 pthread_t vcpuThread;
641
642 private:
643 /**
644 * Service MMIO requests in the mmioRing.
645 *
646 *
647 * @return Number of ticks spent servicing the MMIO requests in
648 * the MMIO ring buffer
649 */
650 Tick flushCoalescedMMIO();
651
652 /**
653 * Setup a signal handler to catch the timer signal used to
654 * switch back to the monitor.
655 */
656 void setupSignalHandler();
657
658 /**
659 * Discard a (potentially) pending signal.
660 *
661 * @param signum Signal to discard
662 * @return true if the signal was pending, false otherwise.
663 */
664 bool discardPendingSignal(int signum) const;
665
666 /**
667 * Thread-specific initialization.
668 *
669 * Some KVM-related initialization requires us to know the TID of
670 * the thread that is going to execute our event queue. For
671 * example, when setting up timers, we need to know the TID of the
672 * thread executing in KVM in order to deliver the timer signal to
673 * that thread. This method is called as the first event in this
674 * SimObject's event queue.
675 *
676 * @see startup
677 */
678 void startupThread();
679
680 /** Try to drain the CPU if a drain is pending */
681 bool tryDrain();
682
683 /** Execute the KVM_RUN ioctl */
684 void ioctlRun();
685
686 /** KVM vCPU file descriptor */
687 int vcpuFD;
688 /** Size of MMAPed kvm_run area */
689 int vcpuMMapSize;
690 /**
691 * Pointer to the kvm_run structure used to communicate parameters
692 * with KVM.
693 *
694 * @note This is the base pointer of the MMAPed KVM region. The
695 * first page contains the kvm_run structure. Subsequent pages may
696 * contain other data such as the MMIO ring buffer.
697 */
698 struct kvm_run *_kvmRun;
699 /**
700 * Coalesced MMIO ring buffer. NULL if coalesced MMIO is not
701 * supported.
702 */
703 struct kvm_coalesced_mmio_ring *mmioRing;
704 /** Cached page size of the host */
705 const long pageSize;
706
707 EventFunctionWrapper tickEvent;
708
709 /**
710 * Setup an instruction break if there is one pending.
711 *
712 * Check if there are pending instruction breaks in the CPU's
713 * instruction event queue and schedule an instruction break using
714 * PerfEvent.
715 *
716 * @note This method doesn't currently handle the main system
717 * instruction event queue.
718 */
719 void setupInstStop();
720
721 /** @{ */
722 /** Setup hardware performance counters */
723 void setupCounters();
724
725 /**
726 * Setup the guest instruction counter.
727 *
728 * Setup the guest instruction counter and optionally request a
729 * signal every N instructions executed by the guest. This method
730 * will re-attach the counter if the counter has already been
731 * attached and its sampling settings have changed.
732 *
733 * @param period Signal period, set to 0 to disable signaling.
734 */
735 void setupInstCounter(uint64_t period = 0);
736
737 /** Currently active instruction count breakpoint */
738 uint64_t activeInstPeriod;
739
740 /**
741 * Guest cycle counter.
742 *
743 * This is the group leader of all performance counters measuring
744 * the guest system. It can be used in conjunction with the
745 * PerfKvmTimer (see perfControlledByTimer) to trigger exits from
746 * KVM.
747 */
748 PerfKvmCounter hwCycles;
749
750 /**
751 * Guest instruction counter.
752 *
753 * This counter is typically only used to measure the number of
754 * instructions executed by the guest. However, it can also be
755 * used to trigger exits from KVM if the configuration script
756 * requests an exit after a certain number of instructions.
757 *
758 * @see setupInstBreak
759 * @see scheduleInstStop
760 */
761 PerfKvmCounter hwInstructions;
762
763 /**
764 * Does the runTimer control the performance counters?
765 *
766 * The run timer will automatically enable and disable performance
767 * counters if a PerfEvent-based timer is used to control KVM
768 * exits.
769 */
770 bool perfControlledByTimer;
771 /** @} */
772
773 /**
774 * Timer used to force execution into the monitor after a
775 * specified number of simulation tick equivalents have executed
776 * in the guest. This counter generates the signal specified by
777 * KVM_TIMER_SIGNAL.
778 */
779 std::unique_ptr<BaseKvmTimer> runTimer;
780
781 /** Host factor as specified in the configuration */
782 float hostFactor;
783
784 public:
785 /* @{ */
786 Stats::Scalar numInsts;
787 Stats::Scalar numVMExits;
788 Stats::Scalar numVMHalfEntries;
789 Stats::Scalar numExitSignal;
790 Stats::Scalar numMMIO;
791 Stats::Scalar numCoalescedMMIO;
792 Stats::Scalar numIO;
793 Stats::Scalar numHalt;
794 Stats::Scalar numInterrupts;
795 Stats::Scalar numHypercalls;
796 /* @} */
797
798 /** Number of instructions executed by the CPU */
799 Counter ctrInsts;
800};
801
802#endif