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