base.hh (9752:a152d7f114b8) | base.hh (9753:b9a742cdd75a) |
---|---|
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 --- 27 unchanged lines hidden (view full) --- 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#ifndef __CPU_KVM_BASE_HH__ 41#define __CPU_KVM_BASE_HH__ 42 43#include <memory> | 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 --- 27 unchanged lines hidden (view full) --- 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#ifndef __CPU_KVM_BASE_HH__ 41#define __CPU_KVM_BASE_HH__ 42 43#include <memory> |
44#include <csignal> |
|
44 45#include "base/statistics.hh" 46#include "cpu/kvm/perfevent.hh" 47#include "cpu/kvm/timer.hh" 48#include "cpu/kvm/vm.hh" 49#include "cpu/base.hh" 50#include "cpu/simple_thread.hh" 51 --- 76 unchanged lines hidden (view full) --- 128 /** ThreadContext object, provides an interface for external 129 * objects to modify this thread's state. 130 */ 131 ThreadContext *tc; 132 133 KvmVM &vm; 134 135 protected: | 45 46#include "base/statistics.hh" 47#include "cpu/kvm/perfevent.hh" 48#include "cpu/kvm/timer.hh" 49#include "cpu/kvm/vm.hh" 50#include "cpu/base.hh" 51#include "cpu/simple_thread.hh" 52 --- 76 unchanged lines hidden (view full) --- 129 /** ThreadContext object, provides an interface for external 130 * objects to modify this thread's state. 131 */ 132 ThreadContext *tc; 133 134 KvmVM &vm; 135 136 protected: |
137 /** 138 * 139 * @dot 140 * digraph { 141 * Idle; 142 * Running; 143 * RunningService; 144 * RunningServiceCompletion; 145 * 146 * Idle -> Idle; 147 * Idle -> Running [label="activateContext()", URL="\ref activateContext"]; 148 * Running -> Running [label="tick()", URL="\ref tick"]; 149 * Running -> RunningService [label="tick()", URL="\ref tick"]; 150 * Running -> Idle [label="suspendContext()", URL="\ref suspendContext"]; 151 * Running -> Idle [label="drain()", URL="\ref drain"]; 152 * Idle -> Running [label="drainResume()", URL="\ref drainResume"]; 153 * RunningService -> RunningServiceCompletion [label="handleKvmExit()", URL="\ref handleKvmExit"]; 154 * RunningServiceCompletion -> Running [label="tick()", URL="\ref tick"]; 155 * RunningServiceCompletion -> RunningService [label="tick()", URL="\ref tick"]; 156 * } 157 * @enddot 158 */ |
|
136 enum Status { | 159 enum Status { |
137 /** Context not scheduled in KVM */ | 160 /** Context not scheduled in KVM. 161 * 162 * The CPU generally enters this state when the guest execute 163 * an instruction that halts the CPU (e.g., WFI on ARM or HLT 164 * on X86) if KVM traps this instruction. Ticks are not 165 * scheduled in this state. 166 * 167 * @see suspendContext() 168 */ |
138 Idle, | 169 Idle, |
139 /** Running normally */ | 170 /** Running normally. 171 * 172 * This is the normal run state of the CPU. KVM will be 173 * entered next time tick() is called. 174 */ |
140 Running, | 175 Running, |
176 /** Requiring service at the beginning of the next cycle. 177 * 178 * The virtual machine has exited and requires service, tick() 179 * will call handleKvmExit() on the next cycle. The next state 180 * after running service is determined in handleKvmExit() and 181 * depends on what kind of service the guest requested: 182 * <ul> 183 * <li>IO/MMIO: RunningServiceCompletion 184 * <li>Halt: Idle 185 * <li>Others: Running 186 * </ul> 187 */ 188 RunningService, 189 /** Service completion in progress. 190 * 191 * The VM has requested service that requires KVM to be 192 * entered once in order to get to a consistent state. This 193 * happens in handleKvmExit() or one of its friends after IO 194 * exits. After executing tick(), the CPU will transition into 195 * the Running or RunningService state. 196 */ 197 RunningServiceCompletion, |
|
141 }; 142 143 /** CPU run state */ 144 Status _status; 145 146 /** 147 * Execute the CPU until the next event in the main event queue or 148 * until the guest needs service from gem5. | 198 }; 199 200 /** CPU run state */ 201 Status _status; 202 203 /** 204 * Execute the CPU until the next event in the main event queue or 205 * until the guest needs service from gem5. |
149 * 150 * @note This method is virtual in order to allow implementations 151 * to check for architecture specific events (e.g., interrupts) 152 * before entering the VM. | |
153 */ | 206 */ |
154 virtual void tick(); | 207 void tick(); |
155 156 /** 157 * Get the value of the hardware cycle counter in the guest. 158 * 159 * This method is supposed to return the total number of cycles 160 * executed in hardware mode relative to some arbitrary point in 161 * the past. It's mainly used when estimating the number of cycles 162 * actually executed by the CPU in kvmRun(). The default behavior --- 9 unchanged lines hidden (view full) --- 172 * Request KVM to run the guest for a given number of ticks. The 173 * method returns the approximate number of ticks executed. 174 * 175 * @note The returned number of ticks can be both larger or 176 * smaller than the requested number of ticks. A smaller number 177 * can, for example, occur when the guest executes MMIO. A larger 178 * number is typically due to performance counter inaccuracies. 179 * | 208 209 /** 210 * Get the value of the hardware cycle counter in the guest. 211 * 212 * This method is supposed to return the total number of cycles 213 * executed in hardware mode relative to some arbitrary point in 214 * the past. It's mainly used when estimating the number of cycles 215 * actually executed by the CPU in kvmRun(). The default behavior --- 9 unchanged lines hidden (view full) --- 225 * Request KVM to run the guest for a given number of ticks. The 226 * method returns the approximate number of ticks executed. 227 * 228 * @note The returned number of ticks can be both larger or 229 * smaller than the requested number of ticks. A smaller number 230 * can, for example, occur when the guest executes MMIO. A larger 231 * number is typically due to performance counter inaccuracies. 232 * |
180 * @param ticks Number of ticks to execute | 233 * @note This method is virtual in order to allow implementations 234 * to check for architecture specific events (e.g., interrupts) 235 * before entering the VM. 236 * 237 * @note It is the response of the caller (normally tick()) to 238 * make sure that the KVM state is synchronized and that the TC is 239 * invalidated after entering KVM. 240 * 241 * @param ticks Number of ticks to execute, set to 0 to exit 242 * immediately after finishing pending operations. |
181 * @return Number of ticks executed (see note) 182 */ | 243 * @return Number of ticks executed (see note) 244 */ |
183 Tick kvmRun(Tick ticks); | 245 virtual Tick kvmRun(Tick ticks); |
184 185 /** | 246 247 /** |
248 * Request the CPU to run until draining completes. 249 * 250 * This function normally calls kvmRun(0) to make KVM finish 251 * pending MMIO operations. Architecures implementing 252 * archIsDrained() must override this method. 253 * 254 * @see BaseKvmCPU::archIsDrained() 255 * 256 * @return Number of ticks executed 257 */ 258 virtual Tick kvmRunDrain(); 259 260 /** |
|
186 * Get a pointer to the kvm_run structure containing all the input 187 * and output parameters from kvmRun(). 188 */ 189 struct kvm_run *getKvmRunState() { return _kvmRun; }; 190 191 /** 192 * Retrieve a pointer to guest data stored at the end of the 193 * kvm_run structure. This is mainly used for PIO operations --- 186 unchanged lines hidden (view full) --- 380 * code. 381 * 382 * @return Number of ticks delay the next CPU tick 383 */ 384 virtual Tick handleKvmExitFailEntry(); 385 /** @} */ 386 387 /** | 261 * Get a pointer to the kvm_run structure containing all the input 262 * and output parameters from kvmRun(). 263 */ 264 struct kvm_run *getKvmRunState() { return _kvmRun; }; 265 266 /** 267 * Retrieve a pointer to guest data stored at the end of the 268 * kvm_run structure. This is mainly used for PIO operations --- 186 unchanged lines hidden (view full) --- 455 * code. 456 * 457 * @return Number of ticks delay the next CPU tick 458 */ 459 virtual Tick handleKvmExitFailEntry(); 460 /** @} */ 461 462 /** |
463 * Is the architecture specific code in a state that prevents 464 * draining? 465 * 466 * This method should return false if there are any pending events 467 * in the guest vCPU that won't be carried over to the gem5 state 468 * and thus will prevent correct checkpointing or CPU handover. It 469 * might, for example, check for pending interrupts that have been 470 * passed to the vCPU but not acknowledged by the OS. Architecures 471 * implementing this method <i>must</i> override 472 * kvmRunDrain(). 473 * 474 * @see BaseKvmCPU::kvmRunDrain() 475 * 476 * @return true if the vCPU is drained, false otherwise. 477 */ 478 virtual bool archIsDrained() const { return true; } 479 480 /** |
|
388 * Inject a memory mapped IO request into gem5 389 * 390 * @param paddr Physical address 391 * @param data Pointer to the source/destination buffer 392 * @param size Memory access size 393 * @param write True if write, False if read 394 * @return Number of ticks spent servicing the memory access 395 */ 396 Tick doMMIOAccess(Addr paddr, void *data, int size, bool write); 397 | 481 * Inject a memory mapped IO request into gem5 482 * 483 * @param paddr Physical address 484 * @param data Pointer to the source/destination buffer 485 * @param size Memory access size 486 * @param write True if write, False if read 487 * @return Number of ticks spent servicing the memory access 488 */ 489 Tick doMMIOAccess(Addr paddr, void *data, int size, bool write); 490 |
491 /** @{ */ 492 /** 493 * Set the signal mask used in kvmRun() 494 * 495 * This method allows the signal mask of the thread executing 496 * kvmRun() to be overridden inside the actual system call. This 497 * allows us to mask timer signals used to force KVM exits while 498 * in gem5. 499 * 500 * The signal mask can be disabled by setting it to NULL. 501 * 502 * @param mask Signals to mask 503 */ 504 void setSignalMask(const sigset_t *mask); 505 /** @} */ |
|
398 399 /** 400 * @addtogroup KvmIoctl 401 * @{ 402 */ 403 /** 404 * vCPU ioctl interface. 405 * --- 88 unchanged lines hidden (view full) --- 494 Tick flushCoalescedMMIO(); 495 496 /** 497 * Setup a signal handler to catch the timer signal used to 498 * switch back to the monitor. 499 */ 500 void setupSignalHandler(); 501 | 506 507 /** 508 * @addtogroup KvmIoctl 509 * @{ 510 */ 511 /** 512 * vCPU ioctl interface. 513 * --- 88 unchanged lines hidden (view full) --- 602 Tick flushCoalescedMMIO(); 603 604 /** 605 * Setup a signal handler to catch the timer signal used to 606 * switch back to the monitor. 607 */ 608 void setupSignalHandler(); 609 |
610 /** 611 * Discard a (potentially) pending signal. 612 * 613 * @param signum Signal to discard 614 * @return true if the signal was pending, false otherwise. 615 */ 616 bool discardPendingSignal(int signum) const; 617 |
|
502 /** Setup hardware performance counters */ 503 void setupCounters(); 504 | 618 /** Setup hardware performance counters */ 619 void setupCounters(); 620 |
621 /** Try to drain the CPU if a drain is pending */ 622 bool tryDrain(); 623 624 /** Execute the KVM_RUN ioctl */ 625 void ioctlRun(); 626 |
|
505 /** KVM vCPU file descriptor */ 506 int vcpuFD; 507 /** Size of MMAPed kvm_run area */ 508 int vcpuMMapSize; 509 /** 510 * Pointer to the kvm_run structure used to communicate parameters 511 * with KVM. 512 * --- 32 unchanged lines hidden (view full) --- 545 * specified number of simulation tick equivalents have executed 546 * in the guest. This counter generates the signal specified by 547 * KVM_TIMER_SIGNAL. 548 */ 549 std::unique_ptr<BaseKvmTimer> runTimer; 550 551 float hostFactor; 552 | 627 /** KVM vCPU file descriptor */ 628 int vcpuFD; 629 /** Size of MMAPed kvm_run area */ 630 int vcpuMMapSize; 631 /** 632 * Pointer to the kvm_run structure used to communicate parameters 633 * with KVM. 634 * --- 32 unchanged lines hidden (view full) --- 667 * specified number of simulation tick equivalents have executed 668 * in the guest. This counter generates the signal specified by 669 * KVM_TIMER_SIGNAL. 670 */ 671 std::unique_ptr<BaseKvmTimer> runTimer; 672 673 float hostFactor; 674 |
675 /** 676 * Drain manager to use when signaling drain completion 677 * 678 * This pointer is non-NULL when draining and NULL otherwise. 679 */ 680 DrainManager *drainManager; 681 |
|
553 public: 554 /* @{ */ 555 Stats::Scalar numInsts; 556 Stats::Scalar numVMExits; 557 Stats::Scalar numMMIO; 558 Stats::Scalar numCoalescedMMIO; 559 Stats::Scalar numIO; 560 Stats::Scalar numHalt; 561 Stats::Scalar numInterrupts; 562 Stats::Scalar numHypercalls; 563 /* @} */ 564 565 /** Number of instructions executed by the CPU */ 566 Counter ctrInsts; 567}; 568 569#endif | 682 public: 683 /* @{ */ 684 Stats::Scalar numInsts; 685 Stats::Scalar numVMExits; 686 Stats::Scalar numMMIO; 687 Stats::Scalar numCoalescedMMIO; 688 Stats::Scalar numIO; 689 Stats::Scalar numHalt; 690 Stats::Scalar numInterrupts; 691 Stats::Scalar numHypercalls; 692 /* @} */ 693 694 /** Number of instructions executed by the CPU */ 695 Counter ctrInsts; 696}; 697 698#endif |