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