base.hh revision 9752
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 <memory>
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
52/** Signal to use to trigger time-based exits from KVM */
53#define KVM_TIMER_SIGNAL SIGRTMIN
54
55// forward declarations
56class ThreadContext;
57struct BaseKvmCPUParams;
58
59/**
60 * Base class for KVM based CPU models
61 *
62 * All architecture specific KVM implementation should inherit from
63 * this class. The most basic CPU models only need to override the
64 * updateKvmState() and updateThreadContext() methods to implement
65 * state synchronization between gem5 and KVM.
66 *
67 * The architecture specific implementation is also responsible for
68 * delivering interrupts into the VM. This is typically done by
69 * overriding tick() and checking the thread context before entering
70 * into the VM. In order to deliver an interrupt, the implementation
71 * then calls KvmVM::setIRQLine() or BaseKvmCPU::kvmInterrupt()
72 * depending on the specifics of the underlying hardware/drivers.
73 */
74class BaseKvmCPU : public BaseCPU
75{
76  public:
77    BaseKvmCPU(BaseKvmCPUParams *params);
78    virtual ~BaseKvmCPU();
79
80    void init();
81    void startup();
82    void regStats();
83
84    void serializeThread(std::ostream &os, ThreadID tid);
85    void unserializeThread(Checkpoint *cp, const std::string &section,
86                           ThreadID tid);
87
88    unsigned int drain(DrainManager *dm);
89    void drainResume();
90
91    void switchOut();
92    void takeOverFrom(BaseCPU *cpu);
93
94    void verifyMemoryMode() const;
95
96    MasterPort &getDataPort() { return dataPort; }
97    MasterPort &getInstPort() { return instPort; }
98
99    void wakeup();
100    void activateContext(ThreadID thread_num, Cycles delay);
101    void suspendContext(ThreadID thread_num);
102    void deallocateContext(ThreadID thread_num);
103    void haltContext(ThreadID thread_num);
104
105    ThreadContext *getContext(int tn);
106
107    Counter totalInsts() const;
108    Counter totalOps() const;
109
110    /** Dump the internal state to the terminal. */
111    virtual void dump();
112
113    /**
114     * A cached copy of a thread's state in the form of a SimpleThread
115     * object.
116     *
117     * Normally the actual thread state is stored in the KVM vCPU. If KVM has
118     * been running this copy is will be out of date. If we recently handled
119     * some events within gem5 that required state to be updated this could be
120     * the most up-to-date copy. When getContext() or updateThreadContext() is
121     * called this copy gets updated.  The method syncThreadContext can
122     * be used within a KVM CPU to update the thread context if the
123     * KVM state is dirty (i.e., the vCPU has been run since the last
124     * update).
125     */
126    SimpleThread *thread;
127
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:
136    enum Status {
137        /** Context not scheduled in KVM */
138        Idle,
139        /** Running normally */
140        Running,
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.
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     */
154    virtual 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
163     * of this method is to use the cycles performance counter, but
164     * some architectures may want to use internal registers instead.
165     *
166     * @return Number of host cycles executed relative to an undefined
167     * point in the past.
168     */
169    virtual uint64_t getHostCycles() const;
170
171    /**
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     *
180     * @param ticks Number of ticks to execute
181     * @return Number of ticks executed (see note)
182     */
183    Tick kvmRun(Tick ticks);
184
185    /**
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
194     * (KVM_EXIT_IO).
195     *
196     * @param offset Offset as specified by the kvm_run structure
197     * @return Pointer to guest data
198     */
199    uint8_t *getGuestData(uint64_t offset) const {
200        return (uint8_t *)_kvmRun + offset;
201    };
202
203    /**
204     * @addtogroup KvmInterrupts
205     * @{
206     */
207    /**
208     * Send a non-maskable interrupt to the guest
209     *
210     * @note The presence of this call depends on Kvm::capUserNMI().
211     */
212    void kvmNonMaskableInterrupt();
213
214    /**
215     * Send a normal interrupt to the guest
216     *
217     * @note Make sure that ready_for_interrupt_injection in kvm_run
218     * is set prior to calling this function. If not, an interrupt
219     * window must be requested by setting request_interrupt_window in
220     * kvm_run to 1 and restarting the guest.
221     *
222     * @param interrupt Structure describing the interrupt to send
223     */
224    void kvmInterrupt(const struct kvm_interrupt &interrupt);
225
226    /** @} */
227
228    /** @{ */
229    /**
230     * Get/Set the register state of the guest vCPU
231     *
232     * KVM has two different interfaces for accessing the state of the
233     * guest CPU. One interface updates 'normal' registers and one
234     * updates 'special' registers. The distinction between special
235     * and normal registers isn't very clear and is architecture
236     * dependent.
237     */
238    void getRegisters(struct kvm_regs &regs) const;
239    void setRegisters(const struct kvm_regs &regs);
240    void getSpecialRegisters(struct kvm_sregs &regs) const;
241    void setSpecialRegisters(const struct kvm_sregs &regs);
242    /** @} */
243
244    /** @{ */
245    /**
246     * Get/Set the guest FPU/vector state
247     */
248    void getFPUState(struct kvm_fpu &state) const;
249    void setFPUState(const struct kvm_fpu &state);
250    /** @} */
251
252    /** @{ */
253    /**
254     * Get/Set single register using the KVM_(SET|GET)_ONE_REG API.
255     *
256     * @note The presence of this call depends on Kvm::capOneReg().
257     */
258    void setOneReg(uint64_t id, const void *addr);
259    void setOneReg(uint64_t id, uint64_t value) { setOneReg(id, &value); }
260    void setOneReg(uint64_t id, uint32_t value) { setOneReg(id, &value); }
261    void getOneReg(uint64_t id, void *addr) const;
262    uint64_t getOneRegU64(uint64_t id) const {
263        uint64_t value;
264        getOneReg(id, &value);
265        return value;
266    }
267    uint32_t getOneRegU32(uint64_t id) const {
268        uint32_t value;
269        getOneReg(id, &value);
270        return value;
271    }
272    /** @} */
273
274    /**
275     * Get and format one register for printout.
276     *
277     * This function call getOneReg() to retrieve the contents of one
278     * register and automatically formats it for printing.
279     *
280     * @note The presence of this call depends on Kvm::capOneReg().
281     */
282    std::string getAndFormatOneReg(uint64_t id) const;
283
284    /** @{ */
285    /**
286     * Update the KVM state from the current thread context
287     *
288     * The base CPU calls this method before starting the guest CPU
289     * when the contextDirty flag is set. The architecture dependent
290     * CPU implementation is expected to update all guest state
291     * (registers, special registers, and FPU state).
292     */
293    virtual void updateKvmState() = 0;
294
295    /**
296     * Update the current thread context with the KVM state
297     *
298     * The base CPU after the guest updates any of the KVM state. In
299     * practice, this happens after kvmRun is called. The architecture
300     * dependent code is expected to read the state of the guest CPU
301     * and update gem5's thread state.
302     */
303    virtual void updateThreadContext() = 0;
304
305    /**
306     * Update a thread context if the KVM state is dirty with respect
307     * to the cached thread context.
308     */
309    void syncThreadContext();
310
311    /**
312     * Update the KVM if the thread context is dirty.
313     */
314    void syncKvmState();
315    /** @} */
316
317    /** @{ */
318    /**
319     * Main kvmRun exit handler, calls the relevant handleKvmExit*
320     * depending on exit type.
321     *
322     * @return Number of ticks spent servicing the exit request
323     */
324    virtual Tick handleKvmExit();
325
326    /**
327     * The guest performed a legacy IO request (out/inp on x86)
328     *
329     * @return Number of ticks spent servicing the IO request
330     */
331    virtual Tick handleKvmExitIO();
332
333    /**
334     * The guest requested a monitor service using a hypercall
335     *
336     * @return Number of ticks spent servicing the hypercall
337     */
338    virtual Tick handleKvmExitHypercall();
339
340    /**
341     * The guest exited because an interrupt window was requested
342     *
343     * The guest exited because an interrupt window was requested
344     * (request_interrupt_window in the kvm_run structure was set to 1
345     * before calling kvmRun) and it is now ready to receive
346     *
347     * @return Number of ticks spent servicing the IRQ
348     */
349    virtual Tick handleKvmExitIRQWindowOpen();
350
351    /**
352     * An unknown architecture dependent error occurred when starting
353     * the vCPU
354     *
355     * The kvm_run data structure contains the hardware error
356     * code. The defaults behavior of this method just prints the HW
357     * error code and panics. Architecture dependent implementations
358     * may want to override this method to provide better,
359     * hardware-aware, error messages.
360     *
361     * @return Number of ticks delay the next CPU tick
362     */
363    virtual Tick handleKvmExitUnknown();
364
365    /**
366     * An unhandled virtualization exception occured
367     *
368     * Some KVM virtualization drivers return unhandled exceptions to
369     * the user-space monitor. This interface is currently only used
370     * by the Intel VMX KVM driver.
371     *
372     * @return Number of ticks delay the next CPU tick
373     */
374    virtual Tick handleKvmExitException();
375
376    /**
377     * KVM failed to start the virtualized CPU
378     *
379     * The kvm_run data structure contains the hardware-specific error
380     * code.
381     *
382     * @return Number of ticks delay the next CPU tick
383     */
384    virtual Tick handleKvmExitFailEntry();
385    /** @} */
386
387    /**
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
398
399    /**
400     * @addtogroup KvmIoctl
401     * @{
402     */
403    /**
404     * vCPU ioctl interface.
405     *
406     * @param request KVM vCPU request
407     * @param p1 Optional request parameter
408     *
409     * @return -1 on error (error number in errno), ioctl dependent
410     * value otherwise.
411     */
412    int ioctl(int request, long p1) const;
413    int ioctl(int request, void *p1) const {
414        return ioctl(request, (long)p1);
415    }
416    int ioctl(int request) const {
417        return ioctl(request, 0L);
418    }
419    /** @} */
420
421
422    /**
423     * KVM memory port. Uses the default MasterPort behavior, but
424     * panics on timing accesses.
425     */
426    class KVMCpuPort : public MasterPort
427    {
428
429      public:
430        KVMCpuPort(const std::string &_name, BaseKvmCPU *_cpu)
431            : MasterPort(_name, _cpu)
432        { }
433
434      protected:
435        bool recvTimingResp(PacketPtr pkt)
436        {
437            panic("The KVM CPU doesn't expect recvTimingResp!\n");
438            return true;
439        }
440
441        void recvRetry()
442        {
443            panic("The KVM CPU doesn't expect recvRetry!\n");
444        }
445
446    };
447
448    /** Port for data requests */
449    KVMCpuPort dataPort;
450
451    /** Unused dummy port for the instruction interface */
452    KVMCpuPort instPort;
453
454    /** Pre-allocated MMIO memory request */
455    Request mmio_req;
456
457    /**
458     * Is the gem5 context dirty? Set to true to force an update of
459     * the KVM vCPU state upon the next call to kvmRun().
460     */
461    bool threadContextDirty;
462
463    /**
464     * Is the KVM state dirty? Set to true to force an update of
465     * the KVM vCPU state upon the next call to kvmRun().
466     */
467    bool kvmStateDirty;
468
469    /** KVM internal ID of the vCPU */
470    const long vcpuID;
471
472  private:
473    struct TickEvent : public Event
474    {
475        BaseKvmCPU &cpu;
476
477        TickEvent(BaseKvmCPU &c)
478            : Event(CPU_Tick_Pri), cpu(c) {}
479
480        void process() { cpu.tick(); }
481
482        const char *description() const {
483            return "BaseKvmCPU tick";
484        }
485    };
486
487    /**
488     * Service MMIO requests in the mmioRing.
489     *
490     *
491     * @return Number of ticks spent servicing the MMIO requests in
492     * the MMIO ring buffer
493     */
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
502    /** Setup hardware performance counters */
503    void setupCounters();
504
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     *
513     * @note This is the base pointer of the MMAPed KVM region. The
514     * first page contains the kvm_run structure. Subsequent pages may
515     * contain other data such as the MMIO ring buffer.
516     */
517    struct kvm_run *_kvmRun;
518    /**
519     * Coalesced MMIO ring buffer. NULL if coalesced MMIO is not
520     * supported.
521     */
522    struct kvm_coalesced_mmio_ring *mmioRing;
523    /** Cached page size of the host */
524    const long pageSize;
525
526    TickEvent tickEvent;
527
528    /** @{ */
529    /** Guest performance counters */
530    PerfKvmCounter hwCycles;
531    PerfKvmCounter hwInstructions;
532    /** @} */
533
534    /**
535     * Does the runTimer control the performance counters?
536     *
537     * The run timer will automatically enable and disable performance
538     * counters if a PerfEvent-based timer is used to control KVM
539     * exits.
540     */
541    bool perfControlledByTimer;
542
543    /**
544     * Timer used to force execution into the monitor after a
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
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
570