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