x86_cpu.cc revision 9886
1/* 2 * Copyright (c) 2013 Andreas Sandberg 3 * All rights reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Andreas Sandberg 29 */ 30 31#include <linux/kvm.h> 32 33#include <algorithm> 34#include <cerrno> 35#include <memory> 36 37#include "arch/x86/regs/msr.hh" 38#include "arch/x86/cpuid.hh" 39#include "arch/x86/utility.hh" 40#include "arch/registers.hh" 41#include "cpu/kvm/base.hh" 42#include "cpu/kvm/x86_cpu.hh" 43#include "debug/Drain.hh" 44#include "debug/Kvm.hh" 45#include "debug/KvmContext.hh" 46#include "debug/KvmIO.hh" 47#include "debug/KvmInt.hh" 48 49using namespace X86ISA; 50 51#define MSR_TSC 0x10 52 53#define IO_PCI_CONF_ADDR 0xCF8 54#define IO_PCI_CONF_DATA_BASE 0xCFC 55 56// Task segment type of an inactive 32-bit or 64-bit task 57#define SEG_SYS_TYPE_TSS_AVAILABLE 9 58// Task segment type of an active 32-bit or 64-bit task 59#define SEG_SYS_TYPE_TSS_BUSY 11 60 61// Non-conforming accessed code segment 62#define SEG_CS_TYPE_ACCESSED 9 63// Non-conforming accessed code segment that can be read 64#define SEG_CS_TYPE_READ_ACCESSED 11 65 66// The lowest bit of the type field for normal segments (code and 67// data) is used to indicate that a segment has been accessed. 68#define SEG_TYPE_BIT_ACCESSED 1 69 70 71#define FOREACH_IREG() \ 72 do { \ 73 APPLY_IREG(rax, INTREG_RAX); \ 74 APPLY_IREG(rbx, INTREG_RBX); \ 75 APPLY_IREG(rcx, INTREG_RCX); \ 76 APPLY_IREG(rdx, INTREG_RDX); \ 77 APPLY_IREG(rsi, INTREG_RSI); \ 78 APPLY_IREG(rdi, INTREG_RDI); \ 79 APPLY_IREG(rsp, INTREG_RSP); \ 80 APPLY_IREG(rbp, INTREG_RBP); \ 81 APPLY_IREG(r8, INTREG_R8); \ 82 APPLY_IREG(r9, INTREG_R9); \ 83 APPLY_IREG(r10, INTREG_R10); \ 84 APPLY_IREG(r11, INTREG_R11); \ 85 APPLY_IREG(r12, INTREG_R12); \ 86 APPLY_IREG(r13, INTREG_R13); \ 87 APPLY_IREG(r14, INTREG_R14); \ 88 APPLY_IREG(r15, INTREG_R15); \ 89 } while(0) 90 91#define FOREACH_SREG() \ 92 do { \ 93 APPLY_SREG(cr0, MISCREG_CR0); \ 94 APPLY_SREG(cr2, MISCREG_CR2); \ 95 APPLY_SREG(cr3, MISCREG_CR3); \ 96 APPLY_SREG(cr4, MISCREG_CR4); \ 97 APPLY_SREG(cr8, MISCREG_CR8); \ 98 APPLY_SREG(efer, MISCREG_EFER); \ 99 APPLY_SREG(apic_base, MISCREG_APIC_BASE); \ 100 } while(0) 101 102#define FOREACH_DREG() \ 103 do { \ 104 APPLY_DREG(db[0], MISCREG_DR0); \ 105 APPLY_DREG(db[1], MISCREG_DR1); \ 106 APPLY_DREG(db[2], MISCREG_DR2); \ 107 APPLY_DREG(db[3], MISCREG_DR3); \ 108 APPLY_DREG(dr6, MISCREG_DR6); \ 109 APPLY_DREG(dr7, MISCREG_DR7); \ 110 } while(0) 111 112#define FOREACH_SEGMENT() \ 113 do { \ 114 APPLY_SEGMENT(cs, MISCREG_CS - MISCREG_SEG_SEL_BASE); \ 115 APPLY_SEGMENT(ds, MISCREG_DS - MISCREG_SEG_SEL_BASE); \ 116 APPLY_SEGMENT(es, MISCREG_ES - MISCREG_SEG_SEL_BASE); \ 117 APPLY_SEGMENT(fs, MISCREG_FS - MISCREG_SEG_SEL_BASE); \ 118 APPLY_SEGMENT(gs, MISCREG_GS - MISCREG_SEG_SEL_BASE); \ 119 APPLY_SEGMENT(ss, MISCREG_SS - MISCREG_SEG_SEL_BASE); \ 120 APPLY_SEGMENT(tr, MISCREG_TR - MISCREG_SEG_SEL_BASE); \ 121 APPLY_SEGMENT(ldt, MISCREG_TSL - MISCREG_SEG_SEL_BASE); \ 122 } while(0) 123 124#define FOREACH_DTABLE() \ 125 do { \ 126 APPLY_DTABLE(gdt, MISCREG_TSG - MISCREG_SEG_SEL_BASE); \ 127 APPLY_DTABLE(idt, MISCREG_IDTR - MISCREG_SEG_SEL_BASE); \ 128 } while(0) 129 130template<typename STRUCT, typename ENTRY> 131static STRUCT *newVarStruct(size_t entries) 132{ 133 return (STRUCT *)operator new(sizeof(STRUCT) + entries * sizeof(ENTRY)); 134} 135 136static void 137dumpKvm(const struct kvm_regs ®s) 138{ 139 inform("KVM register state:\n"); 140 141#define APPLY_IREG(kreg, mreg) \ 142 inform("\t" # kreg ": 0x%llx\n", regs.kreg) 143 144 FOREACH_IREG(); 145 146#undef APPLY_IREG 147 148 inform("\trip: 0x%llx\n", regs.rip); 149 inform("\trflags: 0x%llx\n", regs.rflags); 150} 151 152static void 153dumpKvm(const char *reg_name, const struct kvm_segment &seg) 154{ 155 inform("\t%s: @0x%llx+%x [sel: 0x%x, type: 0x%x]\n" 156 "\t\tpres.: %u, dpl: %u, db: %u, s: %u, l: %u, g: %u, avl: %u, unus.: %u\n", 157 reg_name, 158 seg.base, seg.limit, seg.selector, seg.type, 159 seg.present, seg.dpl, seg.db, seg.s, seg.l, seg.g, seg.avl, seg.unusable); 160} 161 162static void 163dumpKvm(const char *reg_name, const struct kvm_dtable &dtable) 164{ 165 inform("\t%s: @0x%llx+%x\n", 166 reg_name, dtable.base, dtable.limit); 167} 168 169static void 170dumpKvm(const struct kvm_sregs &sregs) 171{ 172#define APPLY_SREG(kreg, mreg) \ 173 inform("\t" # kreg ": 0x%llx\n", sregs.kreg); 174#define APPLY_SEGMENT(kreg, idx) \ 175 dumpKvm(# kreg, sregs.kreg); 176#define APPLY_DTABLE(kreg, idx) \ 177 dumpKvm(# kreg, sregs.kreg); 178 179 inform("Special registers:\n"); 180 FOREACH_SEGMENT(); 181 FOREACH_SREG(); 182 FOREACH_DTABLE(); 183 184 inform("Interrupt Bitmap:"); 185 for (int i = 0; i < KVM_NR_INTERRUPTS; i += 64) 186 inform(" 0x%.8x", sregs.interrupt_bitmap[i / 64]); 187 188#undef APPLY_SREG 189#undef APPLY_SEGMENT 190#undef APPLY_DTABLE 191} 192 193#ifdef KVM_GET_DEBUGREGS 194static void 195dumpKvm(const struct kvm_debugregs ®s) 196{ 197 inform("KVM debug state:\n"); 198 199#define APPLY_DREG(kreg, mreg) \ 200 inform("\t" # kreg ": 0x%llx\n", regs.kreg) 201 202 FOREACH_DREG(); 203 204#undef APPLY_DREG 205 206 inform("\tflags: 0x%llx\n", regs.flags); 207} 208#endif 209 210static void 211dumpKvm(const struct kvm_fpu &fpu) 212{ 213 inform("FPU registers:\n"); 214 inform("\tfcw: 0x%x\n", fpu.fcw); 215 inform("\tfsw: 0x%x\n", fpu.fsw); 216 inform("\tftwx: 0x%x\n", fpu.ftwx); 217 inform("\tlast_opcode: 0x%x\n", fpu.last_opcode); 218 inform("\tlast_ip: 0x%x\n", fpu.last_ip); 219 inform("\tlast_dp: 0x%x\n", fpu.last_dp); 220 inform("\tmxcsr: 0x%x\n", fpu.mxcsr); 221 inform("\tFP Stack:\n"); 222 for (int i = 0; i < 8; ++i) { 223 const bool empty(!((fpu.ftwx >> i) & 0x1)); 224 char hex[33]; 225 for (int j = 0; j < 16; ++j) 226 snprintf(&hex[j*2], 3, "%.2x", fpu.fpr[i][j]); 227 inform("\t\t%i: 0x%s%s\n", i, hex, empty ? " (e)" : ""); 228 } 229 inform("\tXMM registers:\n"); 230 for (int i = 0; i < 16; ++i) { 231 char hex[33]; 232 for (int j = 0; j < 16; ++j) 233 snprintf(&hex[j*2], 3, "%.2x", fpu.xmm[i][j]); 234 inform("\t\t%i: 0x%s\n", i, hex); 235 } 236} 237 238static void 239dumpKvm(const struct kvm_msrs &msrs) 240{ 241 inform("MSRs:\n"); 242 243 for (int i = 0; i < msrs.nmsrs; ++i) { 244 const struct kvm_msr_entry &e(msrs.entries[i]); 245 246 inform("\t0x%x: 0x%x\n", e.index, e.data); 247 } 248} 249 250static void 251dumpKvm(const struct kvm_xcrs ®s) 252{ 253 inform("KVM XCR registers:\n"); 254 255 inform("\tFlags: 0x%x\n", regs.flags); 256 for (int i = 0; i < regs.nr_xcrs; ++i) { 257 inform("\tXCR[0x%x]: 0x%x\n", 258 regs.xcrs[i].xcr, 259 regs.xcrs[i].value); 260 } 261} 262 263static void 264dumpKvm(const struct kvm_xsave &xsave) 265{ 266 inform("KVM XSAVE:\n"); 267 268 Trace::dump((Tick)-1, "xsave.region", 269 xsave.region, sizeof(xsave.region)); 270} 271 272static void 273dumpKvm(const struct kvm_vcpu_events &events) 274{ 275 inform("vCPU events:\n"); 276 277 inform("\tException: [inj: %i, nr: %i, has_ec: %i, ec: %i]\n", 278 events.exception.injected, events.exception.nr, 279 events.exception.has_error_code, events.exception.error_code); 280 281 inform("\tInterrupt: [inj: %i, nr: %i, soft: %i]\n", 282 events.interrupt.injected, events.interrupt.nr, 283 events.interrupt.soft); 284 285 inform("\tNMI: [inj: %i, pending: %i, masked: %i]\n", 286 events.nmi.injected, events.nmi.pending, 287 events.nmi.masked); 288 289 inform("\tSIPI vector: 0x%x\n", events.sipi_vector); 290 inform("\tFlags: 0x%x\n", events.flags); 291} 292 293static bool 294isCanonicalAddress(uint64_t addr) 295{ 296 // x86-64 doesn't currently use the full 64-bit virtual address 297 // space, instead it uses signed 48 bit addresses that are 298 // sign-extended to 64 bits. Such addresses are known as 299 // "canonical". 300 uint64_t upper_half(addr & 0xffff800000000000ULL); 301 return upper_half == 0 || upper_half == 0xffff800000000000; 302} 303 304static void 305checkSeg(const char *name, const int idx, const struct kvm_segment &seg, 306 struct kvm_sregs sregs) 307{ 308 // Check the register base 309 switch (idx) { 310 case MISCREG_TSL: 311 case MISCREG_TR: 312 case MISCREG_FS: 313 case MISCREG_GS: 314 if (!isCanonicalAddress(seg.base)) 315 warn("Illegal %s base: 0x%x\n", name, seg.base); 316 break; 317 318 case MISCREG_SS: 319 case MISCREG_DS: 320 case MISCREG_ES: 321 if (seg.unusable) 322 break; 323 case MISCREG_CS: 324 if (seg.base & 0xffffffff00000000ULL) 325 warn("Illegal %s base: 0x%x\n", name, seg.base); 326 break; 327 } 328 329 // Check the type 330 switch (idx) { 331 case MISCREG_CS: 332 switch (seg.type) { 333 case 3: 334 if (seg.dpl != 0) 335 warn("CS type is 3 but dpl != 0.\n"); 336 break; 337 case 9: 338 case 11: 339 if (seg.dpl != sregs.ss.dpl) 340 warn("CS type is %i but CS DPL != SS DPL\n", seg.type); 341 break; 342 case 13: 343 case 15: 344 if (seg.dpl > sregs.ss.dpl) 345 warn("CS type is %i but CS DPL > SS DPL\n", seg.type); 346 break; 347 default: 348 warn("Illegal CS type: %i\n", seg.type); 349 break; 350 } 351 break; 352 353 case MISCREG_SS: 354 if (seg.unusable) 355 break; 356 switch (seg.type) { 357 case 3: 358 if (sregs.cs.type == 3 && seg.dpl != 0) 359 warn("CS type is 3, but SS DPL is != 0.\n"); 360 /* FALLTHROUGH */ 361 case 7: 362 if (!(sregs.cr0 & 1) && seg.dpl != 0) 363 warn("SS DPL is %i, but CR0 PE is 0\n", seg.dpl); 364 break; 365 default: 366 warn("Illegal SS type: %i\n", seg.type); 367 break; 368 } 369 break; 370 371 case MISCREG_DS: 372 case MISCREG_ES: 373 case MISCREG_FS: 374 case MISCREG_GS: 375 if (seg.unusable) 376 break; 377 if (!(seg.type & 0x1) || 378 ((seg.type & 0x8) && !(seg.type & 0x2))) 379 warn("%s has an illegal type field: %i\n", name, seg.type); 380 break; 381 382 case MISCREG_TR: 383 // TODO: We should check the CPU mode 384 if (seg.type != 3 && seg.type != 11) 385 warn("%s: Illegal segment type (%i)\n", name, seg.type); 386 break; 387 388 case MISCREG_TSL: 389 if (seg.unusable) 390 break; 391 if (seg.type != 2) 392 warn("%s: Illegal segment type (%i)\n", name, seg.type); 393 break; 394 } 395 396 switch (idx) { 397 case MISCREG_SS: 398 case MISCREG_DS: 399 case MISCREG_ES: 400 case MISCREG_FS: 401 case MISCREG_GS: 402 if (seg.unusable) 403 break; 404 case MISCREG_CS: 405 if (!seg.s) 406 warn("%s: S flag not set\n", name); 407 break; 408 409 case MISCREG_TSL: 410 if (seg.unusable) 411 break; 412 case MISCREG_TR: 413 if (seg.s) 414 warn("%s: S flag is set\n", name); 415 break; 416 } 417 418 switch (idx) { 419 case MISCREG_SS: 420 case MISCREG_DS: 421 case MISCREG_ES: 422 case MISCREG_FS: 423 case MISCREG_GS: 424 case MISCREG_TSL: 425 if (seg.unusable) 426 break; 427 case MISCREG_TR: 428 case MISCREG_CS: 429 if (!seg.present) 430 warn("%s: P flag not set\n", name); 431 432 if (((seg.limit & 0xFFF) == 0 && seg.g) || 433 ((seg.limit & 0xFFF00000) != 0 && !seg.g)) { 434 warn("%s limit (0x%x) and g (%i) combination is illegal.\n", 435 name, seg.limit, seg.g); 436 } 437 break; 438 } 439 440 // TODO: Check CS DB 441} 442 443X86KvmCPU::X86KvmCPU(X86KvmCPUParams *params) 444 : BaseKvmCPU(params) 445{ 446 Kvm &kvm(vm.kvm); 447 448 if (!kvm.capSetTSSAddress()) 449 panic("KVM: Missing capability (KVM_CAP_SET_TSS_ADDR)\n"); 450 if (!kvm.capExtendedCPUID()) 451 panic("KVM: Missing capability (KVM_CAP_EXT_CPUID)\n"); 452 if (!kvm.capUserNMI()) 453 warn("KVM: Missing capability (KVM_CAP_USER_NMI)\n"); 454 if (!kvm.capVCPUEvents()) 455 warn("KVM: Missing capability (KVM_CAP_VCPU_EVENTS)\n"); 456 457 haveDebugRegs = kvm.capDebugRegs(); 458 haveXSave = kvm.capXSave(); 459 haveXCRs = kvm.capXCRs(); 460} 461 462X86KvmCPU::~X86KvmCPU() 463{ 464} 465 466void 467X86KvmCPU::startup() 468{ 469 BaseKvmCPU::startup(); 470 471 updateCPUID(); 472 473 io_req.setThreadContext(tc->contextId(), 0); 474 475 // TODO: Do we need to create an identity mapped TSS area? We 476 // should call kvm.vm.setTSSAddress() here in that case. It should 477 // only be needed for old versions of the virtualization 478 // extensions. We should make sure that the identity range is 479 // reserved in the e820 memory map in that case. 480} 481 482void 483X86KvmCPU::dump() 484{ 485 dumpIntRegs(); 486 dumpFpuRegs(); 487 dumpSpecRegs(); 488 dumpDebugRegs(); 489 dumpXCRs(); 490 dumpVCpuEvents(); 491 dumpMSRs(); 492 dumpXSave(); 493} 494 495void 496X86KvmCPU::dumpFpuRegs() const 497{ 498 struct kvm_fpu fpu; 499 getFPUState(fpu); 500 dumpKvm(fpu); 501} 502 503void 504X86KvmCPU::dumpIntRegs() const 505{ 506 struct kvm_regs regs; 507 getRegisters(regs); 508 dumpKvm(regs); 509} 510 511void 512X86KvmCPU::dumpSpecRegs() const 513{ 514 struct kvm_sregs sregs; 515 getSpecialRegisters(sregs); 516 dumpKvm(sregs); 517} 518 519void 520X86KvmCPU::dumpDebugRegs() const 521{ 522 if (haveDebugRegs) { 523#ifdef KVM_GET_DEBUGREGS 524 struct kvm_debugregs dregs; 525 getDebugRegisters(dregs); 526 dumpKvm(dregs); 527#endif 528 } else { 529 inform("Debug registers not supported by kernel.\n"); 530 } 531} 532 533void 534X86KvmCPU::dumpXCRs() const 535{ 536 if (haveXCRs) { 537 struct kvm_xcrs xcrs; 538 getXCRs(xcrs); 539 dumpKvm(xcrs); 540 } else { 541 inform("XCRs not supported by kernel.\n"); 542 } 543} 544 545void 546X86KvmCPU::dumpXSave() const 547{ 548 if (haveXSave) { 549 struct kvm_xsave xsave; 550 getXSave(xsave); 551 dumpKvm(xsave); 552 } else { 553 inform("XSave not supported by kernel.\n"); 554 } 555} 556 557void 558X86KvmCPU::dumpVCpuEvents() const 559{ 560 struct kvm_vcpu_events events; 561 getVCpuEvents(events); 562 dumpKvm(events); 563} 564 565void 566X86KvmCPU::dumpMSRs() const 567{ 568 const Kvm::MSRIndexVector &supported_msrs(vm.kvm.getSupportedMSRs()); 569 std::unique_ptr<struct kvm_msrs> msrs( 570 newVarStruct<struct kvm_msrs, struct kvm_msr_entry>( 571 supported_msrs.size())); 572 573 msrs->nmsrs = supported_msrs.size(); 574 for (int i = 0; i < supported_msrs.size(); ++i) { 575 struct kvm_msr_entry &e(msrs->entries[i]); 576 e.index = supported_msrs[i]; 577 e.reserved = 0; 578 e.data = 0; 579 } 580 getMSRs(*msrs.get()); 581 582 dumpKvm(*msrs.get()); 583} 584 585void 586X86KvmCPU::updateKvmState() 587{ 588 updateKvmStateRegs(); 589 updateKvmStateSRegs(); 590 updateKvmStateFPU(); 591 updateKvmStateMSRs(); 592 593 DPRINTF(KvmContext, "X86KvmCPU::updateKvmState():\n"); 594 if (DTRACE(KvmContext)) 595 dump(); 596} 597 598void 599X86KvmCPU::updateKvmStateRegs() 600{ 601 struct kvm_regs regs; 602 603#define APPLY_IREG(kreg, mreg) regs.kreg = tc->readIntReg(mreg) 604 FOREACH_IREG(); 605#undef APPLY_IREG 606 607 regs.rip = tc->instAddr(); 608 609 /* You might think that setting regs.rflags to the contents 610 * MISCREG_RFLAGS here would suffice. In that case you're 611 * mistaken. We need to reconstruct it from a bunch of ucode 612 * registers and wave a dead chicken over it (aka mask out and set 613 * reserved bits) to get it to work. 614 */ 615 regs.rflags = X86ISA::getRFlags(tc); 616 617 setRegisters(regs); 618} 619 620static inline void 621setKvmSegmentReg(ThreadContext *tc, struct kvm_segment &kvm_seg, 622 const int index) 623{ 624 SegAttr attr(tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(index))); 625 626 kvm_seg.base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(index)); 627 kvm_seg.limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(index)); 628 kvm_seg.selector = tc->readMiscRegNoEffect(MISCREG_SEG_SEL(index)); 629 kvm_seg.type = attr.type; 630 kvm_seg.present = attr.present; 631 kvm_seg.dpl = attr.dpl; 632 kvm_seg.db = attr.defaultSize; 633 kvm_seg.s = attr.system; 634 kvm_seg.l = attr.longMode; 635 kvm_seg.g = attr.granularity; 636 kvm_seg.avl = attr.avl; 637 638 // A segment is unusable when the selector is zero. There is a 639 // attr.unusable flag in gem5, but it seems unused. 640 // 641 // TODO: Are there corner cases where this doesn't work? 642 kvm_seg.unusable = (kvm_seg.selector == 0); 643} 644 645static inline void 646setKvmDTableReg(ThreadContext *tc, struct kvm_dtable &kvm_dtable, 647 const int index) 648{ 649 kvm_dtable.base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(index)); 650 kvm_dtable.limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(index)); 651} 652 653static void 654forceSegAccessed(struct kvm_segment &seg) 655{ 656 // Intel's VMX requires that (some) usable segments are flagged as 657 // 'accessed' (i.e., the lowest bit in the segment type is set) 658 // when entering VMX. This wouldn't necessary be the case even if 659 // gem5 did set the access bits correctly, so we force it to one 660 // in that case. 661 if (!seg.unusable) 662 seg.type |= SEG_TYPE_BIT_ACCESSED; 663} 664 665void 666X86KvmCPU::updateKvmStateSRegs() 667{ 668 struct kvm_sregs sregs; 669 670#define APPLY_SREG(kreg, mreg) sregs.kreg = tc->readMiscRegNoEffect(mreg) 671#define APPLY_SEGMENT(kreg, idx) setKvmSegmentReg(tc, sregs.kreg, idx) 672#define APPLY_DTABLE(kreg, idx) setKvmDTableReg(tc, sregs.kreg, idx) 673 674 FOREACH_SREG(); 675 FOREACH_SEGMENT(); 676 FOREACH_DTABLE(); 677 678#undef APPLY_SREG 679#undef APPLY_SEGMENT 680#undef APPLY_DTABLE 681 682 // Clear the interrupt bitmap 683 memset(&sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); 684 685 // VMX requires CS, SS, DS, ES, FS, and GS to have the accessed 686 // bit in the type field set. 687 forceSegAccessed(sregs.cs); 688 forceSegAccessed(sregs.ss); 689 forceSegAccessed(sregs.ds); 690 forceSegAccessed(sregs.es); 691 forceSegAccessed(sregs.fs); 692 forceSegAccessed(sregs.gs); 693 694 // There are currently some cases where the active task isn't 695 // marked as busy. This is illegal in VMX, so we force it to busy. 696 if (sregs.tr.type == SEG_SYS_TYPE_TSS_AVAILABLE) { 697 hack("tr.type (%i) is not busy. Forcing the busy bit.\n", 698 sregs.tr.type); 699 sregs.tr.type = SEG_SYS_TYPE_TSS_BUSY; 700 } 701 702 // VMX requires the DPL of SS and CS to be the same for 703 // non-conforming code segments. It seems like m5 doesn't set the 704 // DPL of SS correctly when taking interrupts, so we need to fix 705 // that here. 706 if ((sregs.cs.type == SEG_CS_TYPE_ACCESSED || 707 sregs.cs.type == SEG_CS_TYPE_READ_ACCESSED) && 708 sregs.cs.dpl != sregs.ss.dpl) { 709 710 hack("CS.DPL (%i) != SS.DPL (%i): Forcing SS.DPL to %i\n", 711 sregs.cs.dpl, sregs.ss.dpl, sregs.cs.dpl); 712 sregs.ss.dpl = sregs.cs.dpl; 713 } 714 715 // Do checks after fixing up the state to avoid getting excessive 716 // amounts of warnings. 717 RFLAGS rflags_nocc(tc->readMiscReg(MISCREG_RFLAGS)); 718 if (!rflags_nocc.vm) { 719 // Do segment verification if the CPU isn't entering virtual 720 // 8086 mode. We currently assume that unrestricted guest 721 // mode is available. 722 723#define APPLY_SEGMENT(kreg, idx) \ 724 checkSeg(# kreg, idx + MISCREG_SEG_SEL_BASE, sregs.kreg, sregs) 725 726 FOREACH_SEGMENT(); 727#undef APPLY_SEGMENT 728 } 729 730 setSpecialRegisters(sregs); 731} 732void 733X86KvmCPU::updateKvmStateFPU() 734{ 735 warn_once("X86KvmCPU::updateKvmStateFPU not implemented\n"); 736} 737 738void 739X86KvmCPU::updateKvmStateMSRs() 740{ 741 KvmMSRVector msrs; 742 743 const Kvm::MSRIndexVector &indices(getMsrIntersection()); 744 745 for (auto it = indices.cbegin(); it != indices.cend(); ++it) { 746 struct kvm_msr_entry e; 747 748 e.index = *it; 749 e.reserved = 0; 750 e.data = tc->readMiscReg(msrMap.at(*it)); 751 DPRINTF(KvmContext, "Adding MSR: idx: 0x%x, data: 0x%x\n", 752 e.index, e.data); 753 754 msrs.push_back(e); 755 } 756 757 setMSRs(msrs); 758} 759 760void 761X86KvmCPU::updateThreadContext() 762{ 763 DPRINTF(KvmContext, "X86KvmCPU::updateThreadContext():\n"); 764 if (DTRACE(KvmContext)) 765 dump(); 766 767 updateThreadContextRegs(); 768 updateThreadContextSRegs(); 769 updateThreadContextFPU(); 770 updateThreadContextMSRs(); 771 772 // The M5 misc reg caches some values from other 773 // registers. Writing to it with side effects causes it to be 774 // updated from its source registers. 775 tc->setMiscReg(MISCREG_M5_REG, 0); 776} 777 778void 779X86KvmCPU::updateThreadContextRegs() 780{ 781 struct kvm_regs regs; 782 getRegisters(regs); 783 784#define APPLY_IREG(kreg, mreg) tc->setIntReg(mreg, regs.kreg) 785 786 FOREACH_IREG(); 787 788#undef APPLY_IREG 789 790 tc->pcState(PCState(regs.rip)); 791 792 // Flags are spread out across multiple semi-magic registers so we 793 // need some special care when updating them. 794 X86ISA::setRFlags(tc, regs.rflags); 795} 796 797 798inline void 799setContextSegment(ThreadContext *tc, const struct kvm_segment &kvm_seg, 800 const int index) 801{ 802 SegAttr attr(0); 803 804 attr.type = kvm_seg.type; 805 attr.present = kvm_seg.present; 806 attr.dpl = kvm_seg.dpl; 807 attr.defaultSize = kvm_seg.db; 808 attr.system = kvm_seg.s; 809 attr.longMode = kvm_seg.l; 810 attr.granularity = kvm_seg.g; 811 attr.avl = kvm_seg.avl; 812 attr.unusable = kvm_seg.unusable; 813 814 // We need some setMiscReg magic here to keep the effective base 815 // addresses in sync. We need an up-to-date version of EFER, so 816 // make sure this is called after the sregs have been synced. 817 tc->setMiscReg(MISCREG_SEG_BASE(index), kvm_seg.base); 818 tc->setMiscReg(MISCREG_SEG_LIMIT(index), kvm_seg.limit); 819 tc->setMiscReg(MISCREG_SEG_SEL(index), kvm_seg.selector); 820 tc->setMiscReg(MISCREG_SEG_ATTR(index), attr); 821} 822 823inline void 824setContextSegment(ThreadContext *tc, const struct kvm_dtable &kvm_dtable, 825 const int index) 826{ 827 // We need some setMiscReg magic here to keep the effective base 828 // addresses in sync. We need an up-to-date version of EFER, so 829 // make sure this is called after the sregs have been synced. 830 tc->setMiscReg(MISCREG_SEG_BASE(index), kvm_dtable.base); 831 tc->setMiscReg(MISCREG_SEG_LIMIT(index), kvm_dtable.limit); 832} 833 834void 835X86KvmCPU::updateThreadContextSRegs() 836{ 837 struct kvm_sregs sregs; 838 getSpecialRegisters(sregs); 839 840 assert(getKvmRunState()->apic_base == sregs.apic_base); 841 assert(getKvmRunState()->cr8 == sregs.cr8); 842 843#define APPLY_SREG(kreg, mreg) tc->setMiscRegNoEffect(mreg, sregs.kreg) 844#define APPLY_SEGMENT(kreg, idx) setContextSegment(tc, sregs.kreg, idx) 845#define APPLY_DTABLE(kreg, idx) setContextSegment(tc, sregs.kreg, idx) 846 FOREACH_SREG(); 847 FOREACH_SEGMENT(); 848 FOREACH_DTABLE(); 849#undef APPLY_SREG 850#undef APPLY_SEGMENT 851#undef APPLY_DTABLE 852} 853 854void 855X86KvmCPU::updateThreadContextFPU() 856{ 857 warn_once("X86KvmCPU::updateThreadContextFPU not implemented\n"); 858} 859 860void 861X86KvmCPU::updateThreadContextMSRs() 862{ 863 const Kvm::MSRIndexVector &msrs(getMsrIntersection()); 864 865 std::unique_ptr<struct kvm_msrs> kvm_msrs( 866 newVarStruct<struct kvm_msrs, struct kvm_msr_entry>(msrs.size())); 867 struct kvm_msr_entry *entry; 868 869 // Create a list of MSRs to read 870 kvm_msrs->nmsrs = msrs.size(); 871 entry = &kvm_msrs->entries[0]; 872 for (auto it = msrs.cbegin(); it != msrs.cend(); ++it, ++entry) { 873 entry->index = *it; 874 entry->reserved = 0; 875 entry->data = 0; 876 } 877 878 getMSRs(*kvm_msrs.get()); 879 880 // Update M5's state 881 entry = &kvm_msrs->entries[0]; 882 for (int i = 0; i < kvm_msrs->nmsrs; ++i, ++entry) { 883 DPRINTF(KvmContext, "Setting M5 MSR: idx: 0x%x, data: 0x%x\n", 884 entry->index, entry->data); 885 886 tc->setMiscReg(X86ISA::msrMap.at(entry->index), entry->data); 887 } 888} 889 890void 891X86KvmCPU::deliverInterrupts() 892{ 893 syncThreadContext(); 894 895 Fault fault(interrupts->getInterrupt(tc)); 896 interrupts->updateIntrInfo(tc); 897 898 X86Interrupt *x86int(dynamic_cast<X86Interrupt *>(fault.get())); 899 if (x86int) { 900 struct kvm_interrupt kvm_int; 901 kvm_int.irq = x86int->getVector(); 902 903 DPRINTF(KvmInt, "Delivering interrupt: %s (%u)\n", 904 fault->name(), kvm_int.irq); 905 906 kvmInterrupt(kvm_int); 907 } else if (dynamic_cast<NonMaskableInterrupt *>(fault.get())) { 908 DPRINTF(KvmInt, "Delivering NMI\n"); 909 kvmNonMaskableInterrupt(); 910 } else { 911 panic("KVM: Unknown interrupt type\n"); 912 } 913 914} 915 916Tick 917X86KvmCPU::kvmRun(Tick ticks) 918{ 919 struct kvm_run &kvm_run(*getKvmRunState()); 920 921 if (interrupts->checkInterruptsRaw()) { 922 if (kvm_run.ready_for_interrupt_injection) { 923 // KVM claims that it is ready for an interrupt. It might 924 // be lying if we just updated rflags and disabled 925 // interrupts (e.g., by doing a CPU handover). Let's sync 926 // the thread context and check if there are /really/ 927 // interrupts that should be delivered now. 928 syncThreadContext(); 929 if (interrupts->checkInterrupts(tc)) { 930 DPRINTF(KvmInt, 931 "M5 has pending interrupts, delivering interrupt.\n"); 932 933 deliverInterrupts(); 934 } else { 935 DPRINTF(KvmInt, 936 "Interrupt delivery delayed due to KVM confusion.\n"); 937 kvm_run.request_interrupt_window = 1; 938 } 939 } else if (!kvm_run.request_interrupt_window) { 940 DPRINTF(KvmInt, 941 "M5 has pending interrupts, requesting interrupt " 942 "window.\n"); 943 kvm_run.request_interrupt_window = 1; 944 } 945 } else { 946 kvm_run.request_interrupt_window = 0; 947 } 948 949 return kvmRunWrapper(ticks); 950} 951 952Tick 953X86KvmCPU::kvmRunDrain() 954{ 955 struct kvm_run &kvm_run(*getKvmRunState()); 956 957 if (!archIsDrained()) { 958 DPRINTF(Drain, "kvmRunDrain: Architecture code isn't drained\n"); 959 960 // Tell KVM to find a suitable place to deliver interrupts. This 961 // should ensure that pending interrupts have been delivered and 962 // things are reasonably consistent (i.e., no interrupts pending 963 // in the guest). 964 kvm_run.request_interrupt_window = 1; 965 966 // Limit the run to 1 millisecond. That is hopefully enough to 967 // reach an interrupt window. Otherwise, we'll just try again 968 // later. 969 return kvmRunWrapper(1 * SimClock::Float::ms); 970 } else { 971 DPRINTF(Drain, "kvmRunDrain: Delivering pending IO\n"); 972 973 return kvmRunWrapper(0); 974 } 975} 976 977Tick 978X86KvmCPU::kvmRunWrapper(Tick ticks) 979{ 980 struct kvm_run &kvm_run(*getKvmRunState()); 981 982 // Synchronize the APIC base and CR8 here since they are present 983 // in the kvm_run struct, which makes the synchronization really 984 // cheap. 985 kvm_run.apic_base = tc->readMiscReg(MISCREG_APIC_BASE); 986 kvm_run.cr8 = tc->readMiscReg(MISCREG_CR8); 987 988 const Tick run_ticks(BaseKvmCPU::kvmRun(ticks)); 989 990 tc->setMiscReg(MISCREG_APIC_BASE, kvm_run.apic_base); 991 kvm_run.cr8 = tc->readMiscReg(MISCREG_CR8); 992 993 return run_ticks; 994} 995 996uint64_t 997X86KvmCPU::getHostCycles() const 998{ 999 return getMSR(MSR_TSC); 1000} 1001 1002void 1003X86KvmCPU::handleIOMiscReg32(int miscreg) 1004{ 1005 struct kvm_run &kvm_run(*getKvmRunState()); 1006 const uint16_t port(kvm_run.io.port); 1007 1008 assert(kvm_run.exit_reason == KVM_EXIT_IO); 1009 1010 if (kvm_run.io.size != 4) { 1011 panic("Unexpected IO size (%u) for address 0x%x.\n", 1012 kvm_run.io.size, port); 1013 } 1014 1015 if (kvm_run.io.count != 1) { 1016 panic("Unexpected IO count (%u) for address 0x%x.\n", 1017 kvm_run.io.count, port); 1018 } 1019 1020 uint32_t *data((uint32_t *)getGuestData(kvm_run.io.data_offset)); 1021 if (kvm_run.io.direction == KVM_EXIT_IO_OUT) 1022 tc->setMiscReg(miscreg, *data); 1023 else 1024 *data = tc->readMiscRegNoEffect(miscreg); 1025} 1026 1027Tick 1028X86KvmCPU::handleKvmExitIO() 1029{ 1030 struct kvm_run &kvm_run(*getKvmRunState()); 1031 bool isWrite(kvm_run.io.direction == KVM_EXIT_IO_OUT); 1032 unsigned char *guestData(getGuestData(kvm_run.io.data_offset)); 1033 Tick delay(0); 1034 uint16_t port(kvm_run.io.port); 1035 Addr pAddr; 1036 const int count(kvm_run.io.count); 1037 1038 assert(kvm_run.io.direction == KVM_EXIT_IO_IN || 1039 kvm_run.io.direction == KVM_EXIT_IO_OUT); 1040 1041 DPRINTF(KvmIO, "KVM-x86: Handling IO instruction (%s) (port: 0x%x)\n", 1042 (isWrite ? "out" : "in"), kvm_run.io.port); 1043 1044 /* Vanilla gem5 handles PCI discovery in the TLB(!). Since we 1045 * don't use the TLB component, we need to intercept and handle 1046 * the PCI configuration space IO ports here. 1047 * 1048 * The IO port PCI discovery mechanism uses one address register 1049 * and one data register. We map the address register to a misc 1050 * reg and use that to re-route data register accesses to the 1051 * right location in the PCI configuration space. 1052 */ 1053 if (port == IO_PCI_CONF_ADDR) { 1054 handleIOMiscReg32(MISCREG_PCI_CONFIG_ADDRESS); 1055 return 0; 1056 } else if ((port & ~0x3) == IO_PCI_CONF_DATA_BASE) { 1057 Addr pciConfigAddr(tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS)); 1058 if (pciConfigAddr & 0x80000000) { 1059 pAddr = X86ISA::x86PciConfigAddress((pciConfigAddr & 0x7ffffffc) | 1060 (port & 0x3)); 1061 } else { 1062 pAddr = X86ISA::x86IOAddress(port); 1063 } 1064 } else { 1065 pAddr = X86ISA::x86IOAddress(port); 1066 } 1067 1068 io_req.setPhys(pAddr, kvm_run.io.size, Request::UNCACHEABLE, 1069 dataMasterId()); 1070 1071 const MemCmd cmd(isWrite ? MemCmd::WriteReq : MemCmd::ReadReq); 1072 for (int i = 0; i < count; ++i) { 1073 Packet pkt(&io_req, cmd); 1074 1075 pkt.dataStatic(guestData); 1076 delay += dataPort.sendAtomic(&pkt); 1077 1078 guestData += kvm_run.io.size; 1079 } 1080 1081 return delay; 1082} 1083 1084Tick 1085X86KvmCPU::handleKvmExitIRQWindowOpen() 1086{ 1087 // We don't need to do anything here since this is caught the next 1088 // time we execute kvmRun(). We still overload the exit event to 1089 // silence the warning about an unhandled exit event. 1090 return 0; 1091} 1092 1093bool 1094X86KvmCPU::archIsDrained() const 1095{ 1096 struct kvm_vcpu_events events; 1097 1098 getVCpuEvents(events); 1099 1100 // We could probably handle this in a by re-inserting interrupts 1101 // that are pending into gem5 on a drain. However, that would 1102 // probably be tricky to do reliably, so we'll just prevent a 1103 // drain if there is anything pending in the 1104 // guest. X86KvmCPU::kvmRunDrain() minimizes the amount of code 1105 // executed in the guest by requesting an interrupt window if 1106 // there are pending interrupts. 1107 const bool pending_events(events.exception.injected || 1108 events.interrupt.injected || 1109 events.nmi.injected || events.nmi.pending); 1110 1111 if (pending_events) { 1112 DPRINTF(Drain, "archIsDrained: Pending events: %s %s %s %s\n", 1113 events.exception.injected ? "exception" : "", 1114 events.interrupt.injected ? "interrupt" : "", 1115 events.nmi.injected ? "nmi[i]" : "", 1116 events.nmi.pending ? "nmi[p]" : ""); 1117 } 1118 1119 return !pending_events; 1120} 1121 1122static struct kvm_cpuid_entry2 1123makeKvmCpuid(uint32_t function, uint32_t index, 1124 CpuidResult &result) 1125{ 1126 struct kvm_cpuid_entry2 e; 1127 e.function = function; 1128 e.index = index; 1129 e.flags = 0; 1130 e.eax = (uint32_t)result.rax; 1131 e.ebx = (uint32_t)result.rbx; 1132 e.ecx = (uint32_t)result.rcx; 1133 e.edx = (uint32_t)result.rdx; 1134 1135 return e; 1136} 1137 1138void 1139X86KvmCPU::updateCPUID() 1140{ 1141 Kvm::CPUIDVector m5_supported; 1142 1143 /* TODO: We currently don't support any of the functions that 1144 * iterate through data structures in the CPU using an index. It's 1145 * currently not a problem since M5 doesn't expose any of them at 1146 * the moment. 1147 */ 1148 1149 /* Basic features */ 1150 CpuidResult func0; 1151 X86ISA::doCpuid(tc, 0x0, 0, func0); 1152 for (uint32_t function = 0; function <= func0.rax; ++function) { 1153 CpuidResult cpuid; 1154 uint32_t idx(0); 1155 1156 X86ISA::doCpuid(tc, function, idx, cpuid); 1157 m5_supported.push_back(makeKvmCpuid(function, idx, cpuid)); 1158 } 1159 1160 /* Extended features */ 1161 CpuidResult efunc0; 1162 X86ISA::doCpuid(tc, 0x80000000, 0, efunc0); 1163 for (uint32_t function = 0x80000000; function <= efunc0.rax; ++function) { 1164 CpuidResult cpuid; 1165 uint32_t idx(0); 1166 1167 X86ISA::doCpuid(tc, function, idx, cpuid); 1168 m5_supported.push_back(makeKvmCpuid(function, idx, cpuid)); 1169 } 1170 1171 setCPUID(m5_supported); 1172} 1173 1174void 1175X86KvmCPU::setCPUID(const struct kvm_cpuid2 &cpuid) 1176{ 1177 if (ioctl(KVM_SET_CPUID2, (void *)&cpuid) == -1) 1178 panic("KVM: Failed to set guest CPUID2 (errno: %i)\n", 1179 errno); 1180} 1181 1182void 1183X86KvmCPU::setCPUID(const Kvm::CPUIDVector &cpuid) 1184{ 1185 std::unique_ptr<struct kvm_cpuid2> kvm_cpuid( 1186 newVarStruct<struct kvm_cpuid2, struct kvm_cpuid_entry2>(cpuid.size())); 1187 1188 kvm_cpuid->nent = cpuid.size(); 1189 std::copy(cpuid.begin(), cpuid.end(), kvm_cpuid->entries); 1190 1191 setCPUID(*kvm_cpuid); 1192} 1193 1194void 1195X86KvmCPU::setMSRs(const struct kvm_msrs &msrs) 1196{ 1197 if (ioctl(KVM_SET_MSRS, (void *)&msrs) == -1) 1198 panic("KVM: Failed to set guest MSRs (errno: %i)\n", 1199 errno); 1200} 1201 1202void 1203X86KvmCPU::setMSRs(const KvmMSRVector &msrs) 1204{ 1205 std::unique_ptr<struct kvm_msrs> kvm_msrs( 1206 newVarStruct<struct kvm_msrs, struct kvm_msr_entry>(msrs.size())); 1207 1208 kvm_msrs->nmsrs = msrs.size(); 1209 std::copy(msrs.begin(), msrs.end(), kvm_msrs->entries); 1210 1211 setMSRs(*kvm_msrs); 1212} 1213 1214void 1215X86KvmCPU::getMSRs(struct kvm_msrs &msrs) const 1216{ 1217 if (ioctl(KVM_GET_MSRS, (void *)&msrs) == -1) 1218 panic("KVM: Failed to get guest MSRs (errno: %i)\n", 1219 errno); 1220} 1221 1222 1223void 1224X86KvmCPU::setMSR(uint32_t index, uint64_t value) 1225{ 1226 std::unique_ptr<struct kvm_msrs> kvm_msrs( 1227 newVarStruct<struct kvm_msrs, struct kvm_msr_entry>(1)); 1228 struct kvm_msr_entry &entry(kvm_msrs->entries[0]); 1229 1230 kvm_msrs->nmsrs = 1; 1231 entry.index = index; 1232 entry.reserved = 0; 1233 entry.data = value; 1234 1235 setMSRs(*kvm_msrs.get()); 1236} 1237 1238uint64_t 1239X86KvmCPU::getMSR(uint32_t index) const 1240{ 1241 std::unique_ptr<struct kvm_msrs> kvm_msrs( 1242 newVarStruct<struct kvm_msrs, struct kvm_msr_entry>(1)); 1243 struct kvm_msr_entry &entry(kvm_msrs->entries[0]); 1244 1245 kvm_msrs->nmsrs = 1; 1246 entry.index = index; 1247 entry.reserved = 0; 1248 entry.data = 0; 1249 1250 getMSRs(*kvm_msrs.get()); 1251 return entry.data; 1252} 1253 1254const Kvm::MSRIndexVector & 1255X86KvmCPU::getMsrIntersection() const 1256{ 1257 if (cachedMsrIntersection.empty()) { 1258 const Kvm::MSRIndexVector &kvm_msrs(vm.kvm.getSupportedMSRs()); 1259 1260 DPRINTF(Kvm, "kvm-x86: Updating MSR intersection\n"); 1261 for (auto it = kvm_msrs.cbegin(); it != kvm_msrs.cend(); ++it) { 1262 if (X86ISA::msrMap.find(*it) != X86ISA::msrMap.end()) { 1263 cachedMsrIntersection.push_back(*it); 1264 DPRINTF(Kvm, "kvm-x86: Adding MSR 0x%x\n", *it); 1265 } else { 1266 warn("kvm-x86: MSR (0x%x) unsupported by gem5. Skipping.\n", 1267 *it); 1268 } 1269 } 1270 } 1271 1272 return cachedMsrIntersection; 1273} 1274 1275void 1276X86KvmCPU::getDebugRegisters(struct kvm_debugregs ®s) const 1277{ 1278#ifdef KVM_GET_DEBUGREGS 1279 if (ioctl(KVM_GET_DEBUGREGS, ®s) == -1) 1280 panic("KVM: Failed to get guest debug registers\n"); 1281#else 1282 panic("KVM: Unsupported getDebugRegisters call.\n"); 1283#endif 1284} 1285 1286void 1287X86KvmCPU::setDebugRegisters(const struct kvm_debugregs ®s) 1288{ 1289#ifdef KVM_SET_DEBUGREGS 1290 if (ioctl(KVM_SET_DEBUGREGS, (void *)®s) == -1) 1291 panic("KVM: Failed to set guest debug registers\n"); 1292#else 1293 panic("KVM: Unsupported setDebugRegisters call.\n"); 1294#endif 1295} 1296 1297void 1298X86KvmCPU::getXCRs(struct kvm_xcrs ®s) const 1299{ 1300 if (ioctl(KVM_GET_XCRS, ®s) == -1) 1301 panic("KVM: Failed to get guest debug registers\n"); 1302} 1303 1304void 1305X86KvmCPU::setXCRs(const struct kvm_xcrs ®s) 1306{ 1307 if (ioctl(KVM_SET_XCRS, (void *)®s) == -1) 1308 panic("KVM: Failed to set guest debug registers\n"); 1309} 1310 1311void 1312X86KvmCPU::getXSave(struct kvm_xsave &xsave) const 1313{ 1314 if (ioctl(KVM_GET_XSAVE, &xsave) == -1) 1315 panic("KVM: Failed to get guest debug registers\n"); 1316} 1317 1318void 1319X86KvmCPU::setXSave(const struct kvm_xsave &xsave) 1320{ 1321 if (ioctl(KVM_SET_XSAVE, (void *)&xsave) == -1) 1322 panic("KVM: Failed to set guest debug registers\n"); 1323} 1324 1325 1326void 1327X86KvmCPU::getVCpuEvents(struct kvm_vcpu_events &events) const 1328{ 1329 if (ioctl(KVM_GET_VCPU_EVENTS, &events) == -1) 1330 panic("KVM: Failed to get guest debug registers\n"); 1331} 1332 1333void 1334X86KvmCPU::setVCpuEvents(const struct kvm_vcpu_events &events) 1335{ 1336 if (ioctl(KVM_SET_VCPU_EVENTS, (void *)&events) == -1) 1337 panic("KVM: Failed to set guest debug registers\n"); 1338} 1339 1340X86KvmCPU * 1341X86KvmCPUParams::create() 1342{ 1343 return new X86KvmCPU(this); 1344} 1345