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