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