vm.hh revision 10605:8fc6e7a835d1
12SN/A/*
21762SN/A * Copyright 2014 Google, Inc.
32SN/A * Copyright (c) 2012 ARM Limited
42SN/A * All rights reserved
52SN/A *
62SN/A * The license below extends only to copyright in the software and shall
72SN/A * not be construed as granting a license to any other intellectual
82SN/A * property including but not limited to intellectual property relating
92SN/A * to a hardware implementation of the functionality of the software
102SN/A * licensed hereunder.  You may use the software subject to the license
112SN/A * terms below provided that you ensure that this notice is replicated
122SN/A * unmodified and in its entirety in all distributions of the software,
132SN/A * modified or unmodified, in source code or in binary form.
142SN/A *
152SN/A * Redistribution and use in source and binary forms, with or without
162SN/A * modification, are permitted provided that the following conditions are
172SN/A * met: redistributions of source code must retain the above copyright
182SN/A * notice, this list of conditions and the following disclaimer;
192SN/A * redistributions in binary form must reproduce the above copyright
202SN/A * notice, this list of conditions and the following disclaimer in the
212SN/A * documentation and/or other materials provided with the distribution;
222SN/A * neither the name of the copyright holders nor the names of its
232SN/A * contributors may be used to endorse or promote products derived from
242SN/A * this software without specific prior written permission.
252SN/A *
262SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
272665SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
282665SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
311722SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
332SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
342SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3511264Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3611264Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
372SN/A *
382SN/A * Authors: Andreas Sandberg
3911168SN/A */
402SN/A
418229SN/A#ifndef __CPU_KVM_KVMVM_HH__
428229SN/A#define __CPU_KVM_KVMVM_HH__
438229SN/A
4456SN/A#include <vector>
452SN/A
462SN/A#include "base/addr_range.hh"
472SN/A#include "sim/sim_object.hh"
481722SN/A
492SN/A// forward declarations
502SN/Astruct KvmVMParams;
512SN/Aclass System;
522SN/A
532SN/A/**
542SN/A * @defgroup KvmInterrupts KVM Interrupt handling.
552SN/A *
562SN/A * These methods control interrupt delivery to the guest system.
575034SN/A */
585034SN/A
592SN/A/**
602SN/A * @defgroup KvmIoctl KVM low-level ioctl interface.
619533SN/A *
622SN/A * These methods provide a low-level interface to the underlying KVM
639533SN/A * layer.
649533SN/A */
659533SN/A
669533SN/A/**
672SN/A * KVM parent interface
682SN/A *
691722SN/A * The main Kvm object is used to provide functionality that is not
702SN/A * specific to a VM or CPU. For example, it allows checking of the
712SN/A * optional features and creation of VM containers.
722SN/A */
732SN/Aclass Kvm
742SN/A{
752SN/A    friend class KvmVM;
762SN/A
772SN/A  public:
789533SN/A    typedef std::vector<struct kvm_cpuid_entry2> CPUIDVector;
792SN/A    typedef std::vector<uint32_t> MSRIndexVector;
802SN/A
815034SN/A    virtual ~Kvm();
825034SN/A
832SN/A    Kvm *create();
842SN/A
8511361Sandreas@sandberg.pp.se    /** Get the version of the KVM API implemented by the kernel. */
8611361Sandreas@sandberg.pp.se    int getAPIVersion() const { return apiVersion; }
872SN/A    /**
882SN/A     * Get the size of the MMAPed parameter area used to communicate
892SN/A     * vCPU parameters between the kernel and userspace. This area,
9011442Sandreas.hansson@arm.com     * amongst other things, contains the kvm_run data structure.
912SN/A     */
9211442Sandreas.hansson@arm.com    int getVCPUMMapSize() const { return vcpuMMapSize; }
9311442Sandreas.hansson@arm.com
942SN/A    /** @{ */
952SN/A    /** Support for KvmVM::setUserMemoryRegion() */
961722SN/A    bool capUserMemory() const;
972SN/A    /** Support for KvmVM::setTSSAddress() */
982SN/A    bool capSetTSSAddress() const;
992SN/A    /** Support for BaseKvmCPU::setCPUID2 and getSupportedCPUID(). */
1002SN/A    bool capExtendedCPUID() const;
1012SN/A    /** Support for BaseKvmCPU::kvmNonMaskableInterrupt(). */
1022SN/A    bool capUserNMI() const;
1032SN/A
1042SN/A    /**
1052SN/A     * Check if coalesced MMIO is supported and which page in the
1062SN/A     * MMAP'ed structure it stores requests in.
1072SN/A     *
1082SN/A     * @return Offset (in pages) into the mmap'ed vCPU area where the
1096227SN/A     * MMIO buffer is stored. 0 if unsupported.
1106227SN/A     */
1112SN/A    int capCoalescedMMIO() const;
1122SN/A
1132SN/A    /**
1142SN/A     * Attempt to determine how many memory slots are available. If it can't
1152SN/A     * be determined, this function returns 0.
11611168SN/A     */
1172SN/A    int capNumMemSlots() const;
1182SN/A
1192SN/A    /**
1202SN/A     * Support for reading and writing single registers.
1212SN/A     *
1222SN/A     * @see BaseKvmCPU::getOneReg(), and BaseKvmCPU::setOneReg()
1232SN/A     */
1245034SN/A    bool capOneReg() const;
1255034SN/A
1262SN/A    /**
1272SN/A     * Support for creating an in-kernel IRQ chip model.
12811361Sandreas@sandberg.pp.se     *
12911361Sandreas@sandberg.pp.se     * @see KvmVM::createIRQChip()
1308737SN/A     */
131259SN/A    bool capIRQChip() const;
13210905SN/A
13310905SN/A    /** Support for getting and setting the kvm_vcpu_events structure. */
1342SN/A    bool capVCPUEvents() const;
13510905SN/A
13611168SN/A    /** Support for getting and setting the kvm_debugregs structure. */
13711168SN/A    bool capDebugRegs() const;
1382SN/A
13911169SN/A    /** Support for getting and setting the x86 XCRs. */
1402SN/A    bool capXCRs() const;
14111169SN/A
14211169SN/A    /** Support for getting and setting the kvm_xsave structure. */
1432SN/A    bool capXSave() const;
1442SN/A    /** @} */
1459554SN/A
1469554SN/A    /**
1479554SN/A     * Get the CPUID features supported by the hardware and Kvm.
1489554SN/A     *
1499554SN/A     * @note Requires capExtendedCPUID().
1509554SN/A     *
1519554SN/A     * @return False if the allocation is too small, true on success.
1529554SN/A     */
1539554SN/A    bool getSupportedCPUID(struct kvm_cpuid2 &cpuid) const;
1549554SN/A
1559554SN/A    /**
1569554SN/A     * Get the CPUID features supported by the hardware and Kvm.
1579554SN/A     *
1589554SN/A     * @note Requires capExtendedCPUID().
1599554SN/A     *
1609554SN/A     * @note This method uses an internal cache to minimize the number
16111264Sandreas.sandberg@arm.com     * of calls into the kernel.
162     *
163     * @return Reference to cached MSR index list.
164     */
165    const CPUIDVector &getSupportedCPUID() const;
166
167    /**
168     * Get the MSRs supported by the hardware and Kvm.
169     *
170     * @return False if the allocation is too small, true on success.
171     */
172    bool getSupportedMSRs(struct kvm_msr_list &msrs) const;
173
174    /**
175     * Get the MSRs supported by the hardware and Kvm.
176     *
177     * @note This method uses an internal cache to minimize the number
178     * of calls into the kernel.
179     *
180     * @return Reference to cached MSR index list.
181     */
182    const MSRIndexVector &getSupportedMSRs() const;
183
184  protected:
185    /**
186     * Check for the presence of an extension to the KVM API.
187     *
188     * The return value depends on the extension, but is always zero
189     * if it is unsupported or positive otherwise. Some extensions use
190     * the return value provide additional data about the extension.
191     *
192     * @return 0 if the extension is unsupported, positive integer
193     * otherwise.
194     */
195    int checkExtension(int extension) const;
196
197    /**
198     * @addtogroup KvmIoctl
199     * @{
200     */
201    /**
202     * Main VM ioctl interface.
203     *
204     * @param request KVM request
205     * @param p1 Optional request parameter
206     *
207     * @return -1 on error (error number in errno), ioctl dependent
208     * value otherwise.
209     */
210    int ioctl(int request, long p1) const;
211    int ioctl(int request, void *p1) const {
212        return ioctl(request, (long)p1);
213    }
214    int ioctl(int request) const {
215        return ioctl(request, 0L);
216    }
217    /** @} */
218
219  private:
220    // This object is a singleton, so prevent instantiation.
221    Kvm();
222
223    // Prevent copying
224    Kvm(const Kvm &kvm);
225    // Prevent assignment
226    Kvm &operator=(const Kvm &kvm);
227
228    /**
229     * Create a KVM Virtual Machine
230     *
231     * @return File descriptor pointing to the VM
232     */
233    int createVM();
234
235    /** KVM VM file descriptor */
236    int kvmFD;
237    /** KVM API version */
238    int apiVersion;
239    /** Size of the MMAPed vCPU parameter area. */
240    int vcpuMMapSize;
241
242    /** Cached vector of supported CPUID entries. */
243    mutable CPUIDVector supportedCPUIDCache;
244
245    /** Cached vector of supported MSRs. */
246    mutable MSRIndexVector supportedMSRCache;
247
248    /** Singleton instance */
249    static Kvm *instance;
250};
251
252/**
253 * KVM VM container
254 *
255 * A KVM VM container normally contains all the CPUs in a shared
256 * memory machine. The VM container handles things like physical
257 * memory and to some extent interrupts. Normally, the VM API is only
258 * used for interrupts when the PIC is emulated by the kernel, which
259 * is a feature we do not use. However, some architectures (notably
260 * ARM) use the VM interface to deliver interrupts to specific CPUs as
261 * well.
262 *
263 * VM initialization is a bit different from that of other
264 * SimObjects. When we initialize the VM, we discover all physical
265 * memory mappings in the system. Since AbstractMem::unserialize
266 * re-maps the guests memory, we need to make sure that this is done
267 * after the memory has been re-mapped, but before the vCPUs are
268 * initialized (KVM requires memory mappings to be setup before CPUs
269 * can be created). Normally, we would just initialize the VM in
270 * init() or startup(), however, we can not use init() since this is
271 * called before AbstractMem::unserialize() and we can not use
272 * startup() since it must be called before BaseKvmCPU::startup() and
273 * the simulator framework does not guarantee call order. We therefore
274 * call cpuStartup() from BaseKvmCPU::startup() instead and execute
275 * the initialization code once when the first CPU in the VM is
276 * starting.
277 */
278class KvmVM : public SimObject
279{
280    friend class BaseKvmCPU;
281
282  public:
283    KvmVM(KvmVMParams *params);
284    virtual ~KvmVM();
285
286    /**
287     * Setup a shared three-page memory region used by the internals
288     * of KVM. This is currently only needed by x86 implementations.
289     *
290     * @param tss_address Physical address of the start of the TSS
291     */
292    void setTSSAddress(Addr tss_address);
293
294    /** @{ */
295    /**
296     * Request coalescing MMIO for a memory range.
297     *
298     * @param start Physical start address in guest
299     * @param size Size of the MMIO region
300     */
301    void coalesceMMIO(Addr start, int size);
302
303    /**
304     * Request coalescing MMIO for a memory range.
305     *
306     * @param range Coalesced MMIO range
307     */
308    void coalesceMMIO(const AddrRange &range);
309    /** @} */
310
311    /**
312     * @addtogroup KvmInterrupts
313     * @{
314     */
315    /**
316     * Create an in-kernel interrupt  controller
317     *
318     * @note This functionality depends on Kvm::capIRQChip().
319     */
320    void createIRQChip();
321
322    /**
323     * Set the status of an IRQ line using KVM_IRQ_LINE.
324     *
325     * @note This ioctl is usually only used if the interrupt
326     * controller is emulated by the kernel (i.e., after calling
327     * createIRQChip()). Some architectures (e.g., ARM) use it instead
328     * of BaseKvmCPU::kvmInterrupt().
329     *
330     * @param irq Interrupt number
331     * @param high Line level (true for high, false for low)
332     */
333    void setIRQLine(uint32_t irq, bool high);
334
335    /**
336     * Is in-kernel IRQ chip emulation enabled?
337     */
338    bool hasKernelIRQChip() const { return _hasKernelIRQChip; }
339    /** @} */
340
341    struct MemSlot
342    {
343        MemSlot(uint32_t _num) : num(_num)
344        {}
345        MemSlot() : num(-1)
346        {}
347
348        int32_t num;
349    };
350
351    /**
352     *  Allocate a memory slot within the VM.
353     */
354    const MemSlot allocMemSlot(uint64_t size);
355
356    /**
357     * Setup a region of physical memory in the guest
358     *
359     * @param slot KVM memory slot ID returned by allocMemSlot
360     * @param host_addr Memory allocation backing the memory
361     * @param guest_addr Address in the guest
362     * @param flags Flags (see the KVM API documentation)
363     */
364    void setupMemSlot(const MemSlot slot, void *host_addr, Addr guest_addr,
365                      uint32_t flags);
366
367    /**
368     * Disable a memory slot.
369     */
370    void disableMemSlot(const MemSlot slot);
371
372    /**
373     *  Free a previously allocated memory slot.
374     */
375    void freeMemSlot(const MemSlot slot);
376
377    /** Global KVM interface */
378    Kvm kvm;
379
380  protected:
381    /**
382     * VM CPU initialization code.
383     *
384     * This method is called from BaseKvmCPU::startup() when a CPU in
385     * the VM executes its BaseKvmCPU::startup() method. The first
386     * time method is executed on a VM, it calls the delayedStartup()
387     * method.
388     */
389    void cpuStartup();
390
391    /**
392     * Delayed initialization, executed once before the first CPU
393     * starts.
394     *
395     * This method provides a way to do VM initialization once before
396     * the first CPU in a VM starts. It is needed since some resources
397     * (e.g., memory mappings) can change in the normal
398     * SimObject::startup() path. Since the call order of
399     * SimObject::startup() is not guaranteed, we simply defer some
400     * initialization until a CPU is about to start.
401     */
402    void delayedStartup();
403
404
405    /** @{ */
406    /**
407     * Setup a region of physical memory in the guest
408     *
409     * @param slot KVM memory slot ID (must be unique)
410     * @param host_addr Memory allocation backing the memory
411     * @param guest_addr Address in the guest
412     * @param len Size of the allocation in bytes
413     * @param flags Flags (see the KVM API documentation)
414     */
415    void setUserMemoryRegion(uint32_t slot,
416                             void *host_addr, Addr guest_addr,
417                             uint64_t len, uint32_t flags);
418    /** @} */
419
420    /**
421     * Create a new vCPU within a VM.
422     *
423     * @param vcpuID ID of the new CPU within the VM.
424     * @return File descriptor referencing the CPU.
425     */
426    int createVCPU(long vcpuID);
427
428    /**
429     * Allocate a new vCPU ID within the VM.
430     *
431     * The returned vCPU ID is guaranteed to be unique within the
432     * VM. New IDs are allocated sequentially starting from 0.
433     *
434     * @return ID of the new vCPU
435     */
436    long allocVCPUID();
437
438    /**
439     * @addtogroup KvmIoctl
440     * @{
441     */
442    /**
443     * KVM VM ioctl interface.
444     *
445     * @param request KVM VM request
446     * @param p1 Optional request parameter
447     *
448     * @return -1 on error (error number in errno), ioctl dependent
449     * value otherwise.
450     */
451    int ioctl(int request, long p1) const;
452    int ioctl(int request, void *p1) const {
453        return ioctl(request, (long)p1);
454    }
455    int ioctl(int request) const {
456        return ioctl(request, 0L);
457    }
458    /**@}*/
459
460  private:
461    // Prevent copying
462    KvmVM(const KvmVM &vm);
463    // Prevent assignment
464    KvmVM &operator=(const KvmVM &vm);
465
466    System *system;
467
468    /** KVM VM file descriptor */
469    const int vmFD;
470
471    /** Has delayedStartup() already been called? */
472    bool started;
473
474    /** Do we have in-kernel IRQ-chip emulation enabled? */
475    bool _hasKernelIRQChip;
476
477    /** Next unallocated vCPU ID */
478    long nextVCPUID;
479
480    /**
481     *  Structures tracking memory slots.
482     */
483    class MemorySlot
484    {
485      public:
486        uint64_t size;
487        uint32_t slot;
488        bool active;
489    };
490    std::vector<MemorySlot> memorySlots;
491    uint32_t maxMemorySlot;
492};
493
494#endif
495