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