1/*
2 * Copyright 2014 Google, Inc.
3 * Copyright (c) 2012, 2015 ARM Limited
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are
17 * met: redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer;
19 * redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution;
22 * neither the name of the copyright holders nor the names of its
23 * contributors may be used to endorse or promote products derived from
24 * this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * Authors: Andreas Sandberg
39 */
40
41#ifndef __CPU_KVM_KVMVM_HH__
42#define __CPU_KVM_KVMVM_HH__
43
44#include <vector>
45
46#include "base/addr_range.hh"
47#include "sim/sim_object.hh"
48
49// forward declarations
50struct KvmVMParams;
51class BaseKvmCPU;
52class System;
53
54/**
55 * @defgroup KvmInterrupts KVM Interrupt handling.
56 *
57 * These methods control interrupt delivery to the guest system.
58 */
59
60/**
61 * @defgroup KvmIoctl KVM low-level ioctl interface.
62 *
63 * These methods provide a low-level interface to the underlying KVM
64 * layer.
65 */
66
67/**
68 * KVM parent interface
69 *
70 * The main Kvm object is used to provide functionality that is not
71 * specific to a VM or CPU. For example, it allows checking of the
72 * optional features and creation of VM containers.
73 */
74class Kvm
75{
76    friend class KvmVM;
77
78  public:
79    virtual ~Kvm();
80
81    Kvm *create();
82
83    /** Get the version of the KVM API implemented by the kernel. */
84    int getAPIVersion() const { return apiVersion; }
85    /**
86     * Get the size of the MMAPed parameter area used to communicate
87     * vCPU parameters between the kernel and userspace. This area,
88     * amongst other things, contains the kvm_run data structure.
89     */
90    int getVCPUMMapSize() const { return vcpuMMapSize; }
91
92    /** @{ */
93    /** Support for KvmVM::setUserMemoryRegion() */
94    bool capUserMemory() const;
95    /** Support for KvmVM::setTSSAddress() */
96    bool capSetTSSAddress() const;
97    /** Support for BaseKvmCPU::setCPUID2 and getSupportedCPUID(). */
98    bool capExtendedCPUID() const;
99    /** Support for BaseKvmCPU::kvmNonMaskableInterrupt(). */
100    bool capUserNMI() const;
101
102    /**
103     * Check if coalesced MMIO is supported and which page in the
104     * MMAP'ed structure it stores requests in.
105     *
106     * @return Offset (in pages) into the mmap'ed vCPU area where the
107     * MMIO buffer is stored. 0 if unsupported.
108     */
109    int capCoalescedMMIO() const;
110
111    /**
112     * Attempt to determine how many memory slots are available. If it can't
113     * be determined, this function returns 0.
114     */
115    int capNumMemSlots() const;
116
117    /**
118     * Support for reading and writing single registers.
119     *
120     * @see BaseKvmCPU::getOneReg(), and BaseKvmCPU::setOneReg()
121     */
122    bool capOneReg() const;
123
124    /**
125     * Support for creating an in-kernel IRQ chip model.
126     *
127     * @see KvmVM::createIRQChip()
128     */
129    bool capIRQChip() const;
130
131    /** Support for getting and setting the kvm_vcpu_events structure. */
132    bool capVCPUEvents() const;
133
134    /** Support for getting and setting the kvm_debugregs structure. */
135    bool capDebugRegs() const;
136
137    /** Support for getting and setting the x86 XCRs. */
138    bool capXCRs() const;
139
140    /** Support for getting and setting the kvm_xsave structure. */
141    bool capXSave() const;
142    /** @} */
143
144#if defined(__i386__) || defined(__x86_64__)
145  public: // x86-specific
146    /**
147     * @{
148     * @name X86-specific APIs
149     */
150
151    typedef std::vector<struct kvm_cpuid_entry2> CPUIDVector;
152    typedef std::vector<uint32_t> MSRIndexVector;
153
154    /**
155     * Get the CPUID features supported by the hardware and Kvm.
156     *
157     * @note Requires capExtendedCPUID().
158     *
159     * @return False if the allocation is too small, true on success.
160     */
161    bool getSupportedCPUID(struct kvm_cpuid2 &cpuid) const;
162
163    /**
164     * Get the CPUID features supported by the hardware and Kvm.
165     *
166     * @note Requires capExtendedCPUID().
167     *
168     * @note This method uses an internal cache to minimize the number
169     * of calls into the kernel.
170     *
171     * @return Reference to cached MSR index list.
172     */
173    const CPUIDVector &getSupportedCPUID() const;
174
175    /**
176     * Get the MSRs supported by the hardware and Kvm.
177     *
178     * @return False if the allocation is too small, true on success.
179     */
180    bool getSupportedMSRs(struct kvm_msr_list &msrs) const;
181
182    /**
183     * Get the MSRs supported by the hardware and Kvm.
184     *
185     * @note This method uses an internal cache to minimize the number
186     * of calls into the kernel.
187     *
188     * @return Reference to cached MSR index list.
189     */
190    const MSRIndexVector &getSupportedMSRs() const;
191
192  private: // x86-specific
193    /** Cached vector of supported CPUID entries. */
194    mutable CPUIDVector supportedCPUIDCache;
195
196    /** Cached vector of supported MSRs. */
197    mutable MSRIndexVector supportedMSRCache;
198
199
200    /** @} */
201#endif
202
203  protected:
204    /**
205     * Check for the presence of an extension to the KVM API.
206     *
207     * The return value depends on the extension, but is always zero
208     * if it is unsupported or positive otherwise. Some extensions use
209     * the return value provide additional data about the extension.
210     *
211     * @return 0 if the extension is unsupported, positive integer
212     * otherwise.
213     */
214    int checkExtension(int extension) const;
215
216    /**
217     * @addtogroup KvmIoctl
218     * @{
219     */
220    /**
221     * Main VM ioctl interface.
222     *
223     * @param request KVM request
224     * @param p1 Optional request parameter
225     *
226     * @return -1 on error (error number in errno), ioctl dependent
227     * value otherwise.
228     */
229    int ioctl(int request, long p1) const;
230    int ioctl(int request, void *p1) const {
231        return ioctl(request, (long)p1);
232    }
233    int ioctl(int request) const {
234        return ioctl(request, 0L);
235    }
236    /** @} */
237
238  private:
239    // This object is a singleton, so prevent instantiation.
240    Kvm();
241
242    // Prevent copying
243    Kvm(const Kvm &kvm);
244    // Prevent assignment
245    Kvm &operator=(const Kvm &kvm);
246
247    /**
248     * Create a KVM Virtual Machine
249     *
250     * @return File descriptor pointing to the VM
251     */
252    int createVM();
253
254    /** KVM VM file descriptor */
255    int kvmFD;
256    /** KVM API version */
257    int apiVersion;
258    /** Size of the MMAPed vCPU parameter area. */
259    int vcpuMMapSize;
260
261    /** Singleton instance */
262    static Kvm *instance;
263};
264
265/**
266 * KVM VM container
267 *
268 * A KVM VM container normally contains all the CPUs in a shared
269 * memory machine. The VM container handles things like physical
270 * memory and to some extent interrupts. Normally, the VM API is only
271 * used for interrupts when the PIC is emulated by the kernel, which
272 * is a feature we do not use. However, some architectures (notably
273 * ARM) use the VM interface to deliver interrupts to specific CPUs as
274 * well.
275 *
276 * VM initialization is a bit different from that of other
277 * SimObjects. When we initialize the VM, we discover all physical
278 * memory mappings in the system. Since AbstractMem::unserialize
279 * re-maps the guests memory, we need to make sure that this is done
280 * after the memory has been re-mapped, but before the vCPUs are
281 * initialized (KVM requires memory mappings to be setup before CPUs
282 * can be created). Normally, we would just initialize the VM in
283 * init() or startup(), however, we can not use init() since this is
284 * called before AbstractMem::unserialize() and we can not use
285 * startup() since it must be called before BaseKvmCPU::startup() and
286 * the simulator framework does not guarantee call order. We therefore
287 * call cpuStartup() from BaseKvmCPU::startup() instead and execute
288 * the initialization code once when the first CPU in the VM is
289 * starting.
290 */
291class KvmVM : public SimObject
292{
293    friend class BaseKvmCPU;
294
295  public:
296    KvmVM(KvmVMParams *params);
297    virtual ~KvmVM();
298
299    void notifyFork();
300
301    /**
302     * Setup a shared three-page memory region used by the internals
303     * of KVM. This is currently only needed by x86 implementations.
304     *
305     * @param tss_address Physical address of the start of the TSS
306     */
307    void setTSSAddress(Addr tss_address);
308
309    /** @{ */
310    /**
311     * Request coalescing MMIO for a memory range.
312     *
313     * @param start Physical start address in guest
314     * @param size Size of the MMIO region
315     */
316    void coalesceMMIO(Addr start, int size);
317
318    /**
319     * Request coalescing MMIO for a memory range.
320     *
321     * @param range Coalesced MMIO range
322     */
323    void coalesceMMIO(const AddrRange &range);
324    /** @} */
325
326    /**
327     * @addtogroup KvmInterrupts
328     * @{
329     */
330    /**
331     * Create an in-kernel interrupt  controller
332     *
333     * @note This functionality depends on Kvm::capIRQChip().
334     */
335    void createIRQChip();
336
337    /**
338     * Set the status of an IRQ line using KVM_IRQ_LINE.
339     *
340     * @note This ioctl is usually only used if the interrupt
341     * controller is emulated by the kernel (i.e., after calling
342     * createIRQChip()). Some architectures (e.g., ARM) use it instead
343     * of BaseKvmCPU::kvmInterrupt().
344     *
345     * @param irq Interrupt number
346     * @param high Line level (true for high, false for low)
347     */
348    void setIRQLine(uint32_t irq, bool high);
349
350    /**
351     * Is in-kernel IRQ chip emulation enabled?
352     */
353    bool hasKernelIRQChip() const { return _hasKernelIRQChip; }
354
355    /**
356     * Tell the VM and VCPUs to use an in-kernel IRQ chip for
357     * interrupt delivery.
358     *
359     * @note This is set automatically if the IRQ chip is created
360     * using the KvmVM::createIRQChip() API.
361     */
362    void enableKernelIRQChip() { _hasKernelIRQChip = true; }
363    /** @} */
364
365    struct MemSlot
366    {
367        MemSlot(uint32_t _num) : num(_num)
368        {}
369        MemSlot() : num(-1)
370        {}
371
372        int32_t num;
373    };
374
375    /**
376     *  Allocate a memory slot within the VM.
377     */
378    const MemSlot allocMemSlot(uint64_t size);
379
380    /**
381     * Setup a region of physical memory in the guest
382     *
383     * @param slot KVM memory slot ID returned by allocMemSlot
384     * @param host_addr Memory allocation backing the memory
385     * @param guest_addr Address in the guest
386     * @param flags Flags (see the KVM API documentation)
387     */
388    void setupMemSlot(const MemSlot slot, void *host_addr, Addr guest_addr,
389                      uint32_t flags);
390
391    /**
392     * Disable a memory slot.
393     */
394    void disableMemSlot(const MemSlot slot);
395
396    /**
397     *  Free a previously allocated memory slot.
398     */
399    void freeMemSlot(const MemSlot slot);
400
401    /**
402     * Create an in-kernel device model.
403     *
404     * @param type Device type (KVM_DEV_TYPE_xxx)
405     * @param flags Creation flags (KVM_CREATE_DEVICE_xxx)
406     * @return Device file descriptor
407     */
408    int createDevice(uint32_t type, uint32_t flags = 0);
409
410    /** Global KVM interface */
411    Kvm *kvm;
412
413    /**
414     * Initialize system pointer. Invoked by system object.
415     */
416    void setSystem(System *s);
417
418    /**
419      * Get the VCPUID for a given context
420      */
421    long contextIdToVCpuId(ContextID ctx) const;
422
423#if defined(__aarch64__)
424  public: // ARM-specific
425    /**
426     * Ask the kernel for the preferred CPU target to simulate.
427     *
428     * When creating an ARM vCPU in Kvm, we need to initialize it with
429     * a call to BaseArmKvmCPU::kvmArmVCpuInit(). When calling this
430     * function, we need to know what type of CPU the host has. This
431     * call sets up the kvm_vcpu_init structure with the values the
432     * kernel wants.
433     *
434     * @param[out] target Target structure to initialize.
435     */
436    void kvmArmPreferredTarget(struct kvm_vcpu_init &target) const;
437
438#endif
439
440  protected:
441    /**
442     * VM CPU initialization code.
443     *
444     * This method is called from BaseKvmCPU::startup() when a CPU in
445     * the VM executes its BaseKvmCPU::startup() method. The first
446     * time method is executed on a VM, it calls the delayedStartup()
447     * method.
448     */
449    void cpuStartup();
450
451    /**
452     * Delayed initialization, executed once before the first CPU
453     * starts.
454     *
455     * This method provides a way to do VM initialization once before
456     * the first CPU in a VM starts. It is needed since some resources
457     * (e.g., memory mappings) can change in the normal
458     * SimObject::startup() path. Since the call order of
459     * SimObject::startup() is not guaranteed, we simply defer some
460     * initialization until a CPU is about to start.
461     */
462    void delayedStartup();
463
464
465    /** @{ */
466    /**
467     * Setup a region of physical memory in the guest
468     *
469     * @param slot KVM memory slot ID (must be unique)
470     * @param host_addr Memory allocation backing the memory
471     * @param guest_addr Address in the guest
472     * @param len Size of the allocation in bytes
473     * @param flags Flags (see the KVM API documentation)
474     */
475    void setUserMemoryRegion(uint32_t slot,
476                             void *host_addr, Addr guest_addr,
477                             uint64_t len, uint32_t flags);
478    /** @} */
479
480    /**
481     * Create a new vCPU within a VM.
482     *
483     * @param vcpuID ID of the new CPU within the VM.
484     * @return File descriptor referencing the CPU.
485     */
486    int createVCPU(long vcpuID);
487
488    /**
489     * Allocate a new vCPU ID within the VM.
490     *
491     * The returned vCPU ID is guaranteed to be unique within the
492     * VM. New IDs are allocated sequentially starting from 0.
493     *
494     * @return ID of the new vCPU
495     */
496    long allocVCPUID();
497
498    /**
499     * @addtogroup KvmIoctl
500     * @{
501     */
502    /**
503     * KVM VM ioctl interface.
504     *
505     * @param request KVM VM request
506     * @param p1 Optional request parameter
507     *
508     * @return -1 on error (error number in errno), ioctl dependent
509     * value otherwise.
510     */
511    int ioctl(int request, long p1) const;
512    int ioctl(int request, void *p1) const {
513        return ioctl(request, (long)p1);
514    }
515    int ioctl(int request) const {
516        return ioctl(request, 0L);
517    }
518    /**@}*/
519
520  private:
521    // Prevent copying
522    KvmVM(const KvmVM &vm);
523    // Prevent assignment
524    KvmVM &operator=(const KvmVM &vm);
525
526    System *system;
527
528    /** KVM VM file descriptor */
529    int vmFD;
530
531    /** Has delayedStartup() already been called? */
532    bool started;
533
534    /** Do we have in-kernel IRQ-chip emulation enabled? */
535    bool _hasKernelIRQChip;
536
537    /** Next unallocated vCPU ID */
538    long nextVCPUID;
539
540    /**
541     *  Structures tracking memory slots.
542     */
543    class MemorySlot
544    {
545      public:
546        uint64_t size;
547        uint32_t slot;
548        bool active;
549    };
550    std::vector<MemorySlot> memorySlots;
551    uint32_t maxMemorySlot;
552};
553
554#endif
555