base.hh (11151:ca4ea9b5c052) base.hh (11168:f98eb2da15a4)
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
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;
87 void serializeThread(CheckpointOut &cp, ThreadID tid) const override;
88 void unserializeThread(CheckpointIn &cp, ThreadID tid) override;
91
89
92 DrainState drain() M5_ATTR_OVERRIDE;
93 void drainResume() M5_ATTR_OVERRIDE;
90 DrainState drain() override;
91 void drainResume() override;
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
92
93 void switchOut();
94 void takeOverFrom(BaseCPU *cpu);
95
96 void verifyMemoryMode() const;
97
98 MasterPort &getDataPort() { return dataPort; }
99 MasterPort &getInstPort() { return instPort; }
100
103 void wakeup(ThreadID tid = 0) M5_ATTR_OVERRIDE;
101 void wakeup(ThreadID tid = 0) override;
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 &regs) const;
330 void setRegisters(const struct kvm_regs &regs);
331 void getSpecialRegisters(struct kvm_sregs &regs) const;
332 void setSpecialRegisters(const struct kvm_sregs &regs);
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 public:
753 /* @{ */
754 Stats::Scalar numInsts;
755 Stats::Scalar numVMExits;
756 Stats::Scalar numVMHalfEntries;
757 Stats::Scalar numExitSignal;
758 Stats::Scalar numMMIO;
759 Stats::Scalar numCoalescedMMIO;
760 Stats::Scalar numIO;
761 Stats::Scalar numHalt;
762 Stats::Scalar numInterrupts;
763 Stats::Scalar numHypercalls;
764 /* @} */
765
766 /** Number of instructions executed by the CPU */
767 Counter ctrInsts;
768};
769
770#endif
102 void activateContext(ThreadID thread_num);
103 void suspendContext(ThreadID thread_num);
104 void deallocateContext(ThreadID thread_num);
105 void haltContext(ThreadID thread_num);
106
107 ThreadContext *getContext(int tn);
108
109 Counter totalInsts() const;
110 Counter totalOps() const;
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 &regs) const;
328 void setRegisters(const struct kvm_regs &regs);
329 void getSpecialRegisters(struct kvm_sregs &regs) const;
330 void setSpecialRegisters(const struct kvm_sregs &regs);
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