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 Port &getDataPort() override { return dataPort; } 101 Port &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 ®s) const; 349 void setRegisters(const struct kvm_regs ®s); 350 void getSpecialRegisters(struct kvm_sregs ®s) const; 351 void setSpecialRegisters(const struct kvm_sregs ®s); 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 803