2 * Copyright (c) 2012 ARM Limited
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.
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.
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.
37 * Authors: Andreas Sandberg
40 #ifndef __CPU_KVM_KVMVM_HH__
41 #define __CPU_KVM_KVMVM_HH__
45 #include "base/addr_range.hh"
46 #include "sim/sim_object.hh"
48 // forward declarations
53 * @defgroup KvmInterrupts KVM Interrupt handling.
55 * These methods control interrupt delivery to the guest system.
59 * @defgroup KvmIoctl KVM low-level ioctl interface.
61 * These methods provide a low-level interface to the underlying KVM
66 * KVM parent interface
68 * The main Kvm object is used to provide functionality that is not
69 * specific to a VM or CPU. For example, it allows checking of the
70 * optional features and creation of VM containers.
77 typedef std::vector<struct kvm_cpuid_entry2> CPUIDVector;
78 typedef std::vector<uint32_t> MSRIndexVector;
84 /** Get the version of the KVM API implemented by the kernel. */
85 int getAPIVersion() const { return apiVersion; }
87 * Get the size of the MMAPed parameter area used to communicate
88 * vCPU parameters between the kernel and userspace. This area,
89 * amongst other things, contains the kvm_run data structure.
91 int getVCPUMMapSize() const { return vcpuMMapSize; }
94 /** Support for KvmVM::setUserMemoryRegion() */
95 bool capUserMemory() const;
96 /** Support for KvmVM::setTSSAddress() */
97 bool capSetTSSAddress() const;
98 /** Support for BaseKvmCPU::setCPUID2 and getSupportedCPUID(). */
99 bool capExtendedCPUID() const;
100 /** Support for BaseKvmCPU::kvmNonMaskableInterrupt(). */
101 bool capUserNMI() const;
104 * Check if coalesced MMIO is supported and which page in the
105 * MMAP'ed structure it stores requests in.
107 * @return Offset (in pages) into the mmap'ed vCPU area where the
108 * MMIO buffer is stored. 0 if unsupported.
110 int capCoalescedMMIO() const;
113 * Support for reading and writing single registers.
115 * @see BaseKvmCPU::getOneReg(), and BaseKvmCPU::setOneReg()
117 bool capOneReg() const;
120 * Support for creating an in-kernel IRQ chip model.
122 * @see KvmVM::createIRQChip()
124 bool capIRQChip() const;
126 /** Support for getting and setting the kvm_vcpu_events structure. */
127 bool capVCPUEvents() const;
129 /** Support for getting and setting the kvm_debugregs structure. */
130 bool capDebugRegs() const;
132 /** Support for getting and setting the x86 XCRs. */
133 bool capXCRs() const;
135 /** Support for getting and setting the kvm_xsave structure. */
136 bool capXSave() const;
140 * Get the CPUID features supported by the hardware and Kvm.
142 * @note Requires capExtendedCPUID().
144 * @return False if the allocation is too small, true on success.
146 bool getSupportedCPUID(struct kvm_cpuid2 &cpuid) const;
149 * Get the CPUID features supported by the hardware and Kvm.
151 * @note Requires capExtendedCPUID().
153 * @note This method uses an internal cache to minimize the number
154 * of calls into the kernel.
156 * @return Reference to cached MSR index list.
158 const CPUIDVector &getSupportedCPUID() const;
161 * Get the MSRs supported by the hardware and Kvm.
163 * @return False if the allocation is too small, true on success.
165 bool getSupportedMSRs(struct kvm_msr_list &msrs) const;
168 * Get the MSRs supported by the hardware and Kvm.
170 * @note This method uses an internal cache to minimize the number
171 * of calls into the kernel.
173 * @return Reference to cached MSR index list.
175 const MSRIndexVector &getSupportedMSRs() const;
179 * Check for the presence of an extension to the KVM API.
181 * The return value depends on the extension, but is always zero
182 * if it is unsupported or positive otherwise. Some extensions use
183 * the return value provide additional data about the extension.
185 * @return 0 if the extension is unsupported, positive integer
188 int checkExtension(int extension) const;
191 * @addtogroup KvmIoctl
195 * Main VM ioctl interface.
197 * @param request KVM request
198 * @param p1 Optional request parameter
200 * @return -1 on error (error number in errno), ioctl dependent
203 int ioctl(int request, long p1) const;
204 int ioctl(int request, void *p1) const {
205 return ioctl(request, (long)p1);
207 int ioctl(int request) const {
208 return ioctl(request, 0L);
213 // This object is a singleton, so prevent instantiation.
218 // Prevent assignment
219 Kvm &operator=(const Kvm &kvm);
222 * Create a KVM Virtual Machine
224 * @return File descriptor pointing to the VM
228 /** KVM VM file descriptor */
230 /** KVM API version */
232 /** Size of the MMAPed vCPU parameter area. */
235 /** Cached vector of supported CPUID entries. */
236 mutable CPUIDVector supportedCPUIDCache;
238 /** Cached vector of supported MSRs. */
239 mutable MSRIndexVector supportedMSRCache;
241 /** Singleton instance */
242 static Kvm *instance;
248 * A KVM VM container normally contains all the CPUs in a shared
249 * memory machine. The VM container handles things like physical
250 * memory and to some extent interrupts. Normally, the VM API is only
251 * used for interrupts when the PIC is emulated by the kernel, which
252 * is a feature we do not use. However, some architectures (notably
253 * ARM) use the VM interface to deliver interrupts to specific CPUs as
256 * VM initialization is a bit different from that of other
257 * SimObjects. When we initialize the VM, we discover all physical
258 * memory mappings in the system. Since AbstractMem::unserialize
259 * re-maps the guests memory, we need to make sure that this is done
260 * after the memory has been re-mapped, but before the vCPUs are
261 * initialized (KVM requires memory mappings to be setup before CPUs
262 * can be created). Normally, we would just initialize the VM in
263 * init() or startup(), however, we can not use init() since this is
264 * called before AbstractMem::unserialize() and we can not use
265 * startup() since it must be called before BaseKvmCPU::startup() and
266 * the simulator framework does not guarantee call order. We therefore
267 * call cpuStartup() from BaseKvmCPU::startup() instead and execute
268 * the initialization code once when the first CPU in the VM is
271 class KvmVM : public SimObject
273 friend class BaseKvmCPU;
276 KvmVM(KvmVMParams *params);
280 * Setup a shared three-page memory region used by the internals
281 * of KVM. This is currently only needed by x86 implementations.
283 * @param tss_address Physical address of the start of the TSS
285 void setTSSAddress(Addr tss_address);
289 * Request coalescing MMIO for a memory range.
291 * @param start Physical start address in guest
292 * @param size Size of the MMIO region
294 void coalesceMMIO(Addr start, int size);
297 * Request coalescing MMIO for a memory range.
299 * @param range Coalesced MMIO range
301 void coalesceMMIO(const AddrRange &range);
305 * @addtogroup KvmInterrupts
309 * Create an in-kernel interrupt controller
311 * @note This functionality depends on Kvm::capIRQChip().
313 void createIRQChip();
316 * Set the status of an IRQ line using KVM_IRQ_LINE.
318 * @note This ioctl is usually only used if the interrupt
319 * controller is emulated by the kernel (i.e., after calling
320 * createIRQChip()). Some architectures (e.g., ARM) use it instead
321 * of BaseKvmCPU::kvmInterrupt().
323 * @param irq Interrupt number
324 * @param high Line level (true for high, false for low)
326 void setIRQLine(uint32_t irq, bool high);
329 * Is in-kernel IRQ chip emulation enabled?
331 bool hasKernelIRQChip() const { return _hasKernelIRQChip; }
334 /** Global KVM interface */
339 * VM CPU initialization code.
341 * This method is called from BaseKvmCPU::startup() when a CPU in
342 * the VM executes its BaseKvmCPU::startup() method. The first
343 * time method is executed on a VM, it calls the delayedStartup()
349 * Delayed initialization, executed once before the first CPU
352 * This method provides a way to do VM initialization once before
353 * the first CPU in a VM starts. It is needed since some resources
354 * (e.g., memory mappings) can change in the normal
355 * SimObject::startup() path. Since the call order of
356 * SimObject::startup() is not guaranteed, we simply defer some
357 * initialization until a CPU is about to start.
359 void delayedStartup();
364 * Setup a region of physical memory in the guest
366 * @param slot KVM memory slot ID (must be unique)
367 * @param host_addr Memory allocation backing the memory
368 * @param guest_addr Address in the guest
369 * @param guest_range Address range used by guest.
370 * @param len Size of the allocation in bytes
371 * @param flags Flags (see the KVM API documentation)
373 void setUserMemoryRegion(uint32_t slot,
374 void *host_addr, Addr guest_addr,
375 uint64_t len, uint32_t flags);
376 void setUserMemoryRegion(uint32_t slot,
377 void *host_addr, AddrRange guest_range,
382 * Create a new vCPU within a VM.
384 * @param vcpuID ID of the new CPU within the VM.
385 * @return File descriptor referencing the CPU.
387 int createVCPU(long vcpuID);
390 * Allocate a new vCPU ID within the VM.
392 * The returned vCPU ID is guaranteed to be unique within the
393 * VM. New IDs are allocated sequentially starting from 0.
395 * @return ID of the new vCPU
400 * @addtogroup KvmIoctl
404 * KVM VM ioctl interface.
406 * @param request KVM VM request
407 * @param p1 Optional request parameter
409 * @return -1 on error (error number in errno), ioctl dependent
412 int ioctl(int request, long p1) const;
413 int ioctl(int request, void *p1) const {
414 return ioctl(request, (long)p1);
416 int ioctl(int request) const {
417 return ioctl(request, 0L);
423 KvmVM(const KvmVM &vm);
424 // Prevent assignment
425 KvmVM &operator=(const KvmVM &vm);
429 /** KVM VM file descriptor */
432 /** Has delayedStartup() already been called? */
435 /** Do we have in-kernel IRQ-chip emulation enabled? */
436 bool _hasKernelIRQChip;
438 /** Next unallocated vCPU ID */