x86_cpu.cc (9883:7e0dff1c165b) | x86_cpu.cc (9884:d1a5e147e72d) |
---|---|
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; --- 261 unchanged lines hidden (view full) --- 270 inform("\tNMI: [inj: %i, pending: %i, masked: %i]\n", 271 events.nmi.injected, events.nmi.pending, 272 events.nmi.masked); 273 274 inform("\tSIPI vector: 0x%x\n", events.sipi_vector); 275 inform("\tFlags: 0x%x\n", events.flags); 276} 277 | 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; --- 261 unchanged lines hidden (view full) --- 270 inform("\tNMI: [inj: %i, pending: %i, masked: %i]\n", 271 events.nmi.injected, events.nmi.pending, 272 events.nmi.masked); 273 274 inform("\tSIPI vector: 0x%x\n", events.sipi_vector); 275 inform("\tFlags: 0x%x\n", events.flags); 276} 277 |
278static bool 279isCanonicalAddress(uint64_t addr) 280{ 281 // x86-64 doesn't currently use the full 64-bit virtual address 282 // space, instead it uses signed 48 bit addresses that are 283 // sign-extended to 64 bits. Such addresses are known as 284 // "canonical". 285 uint64_t upper_half(addr & 0xffff800000000000ULL); 286 return upper_half == 0 || upper_half == 0xffff800000000000; 287} 288 289static void 290checkSeg(const char *name, const int idx, const struct kvm_segment &seg, 291 struct kvm_sregs sregs) 292{ 293 // Check the register base 294 switch (idx) { 295 case MISCREG_TSL: 296 case MISCREG_TR: 297 case MISCREG_FS: 298 case MISCREG_GS: 299 if (!isCanonicalAddress(seg.base)) 300 warn("Illegal %s base: 0x%x\n", name, seg.base); 301 break; 302 303 case MISCREG_SS: 304 case MISCREG_DS: 305 case MISCREG_ES: 306 if (seg.unusable) 307 break; 308 case MISCREG_CS: 309 if (seg.base & 0xffffffff00000000ULL) 310 warn("Illegal %s base: 0x%x\n", name, seg.base); 311 break; 312 } 313 314 // Check the type 315 switch (idx) { 316 case MISCREG_CS: 317 switch (seg.type) { 318 case 3: 319 if (seg.dpl != 0) 320 warn("CS type is 3 but dpl != 0.\n"); 321 break; 322 case 9: 323 case 11: 324 if (seg.dpl != sregs.ss.dpl) 325 warn("CS type is %i but CS DPL != SS DPL\n", seg.type); 326 break; 327 case 13: 328 case 15: 329 if (seg.dpl > sregs.ss.dpl) 330 warn("CS type is %i but CS DPL > SS DPL\n", seg.type); 331 break; 332 default: 333 warn("Illegal CS type: %i\n", seg.type); 334 break; 335 } 336 break; 337 338 case MISCREG_SS: 339 if (seg.unusable) 340 break; 341 switch (seg.type) { 342 case 3: 343 if (sregs.cs.type == 3 && seg.dpl != 0) 344 warn("CS type is 3, but SS DPL is != 0.\n"); 345 /* FALLTHROUGH */ 346 case 7: 347 if (!(sregs.cr0 & 1) && seg.dpl != 0) 348 warn("SS DPL is %i, but CR0 PE is 0\n", seg.dpl); 349 break; 350 default: 351 warn("Illegal SS type: %i\n", seg.type); 352 break; 353 } 354 break; 355 356 case MISCREG_DS: 357 case MISCREG_ES: 358 case MISCREG_FS: 359 case MISCREG_GS: 360 if (seg.unusable) 361 break; 362 if (!(seg.type & 0x1) || 363 ((seg.type & 0x8) && !(seg.type & 0x2))) 364 warn("%s has an illegal type field: %i\n", name, seg.type); 365 break; 366 367 case MISCREG_TR: 368 // TODO: We should check the CPU mode 369 if (seg.type != 3 && seg.type != 11) 370 warn("%s: Illegal segment type (%i)\n", name, seg.type); 371 break; 372 373 case MISCREG_TSL: 374 if (seg.unusable) 375 break; 376 if (seg.type != 2) 377 warn("%s: Illegal segment type (%i)\n", name, seg.type); 378 break; 379 } 380 381 switch (idx) { 382 case MISCREG_SS: 383 case MISCREG_DS: 384 case MISCREG_ES: 385 case MISCREG_FS: 386 case MISCREG_GS: 387 if (seg.unusable) 388 break; 389 case MISCREG_CS: 390 if (!seg.s) 391 warn("%s: S flag not set\n", name); 392 break; 393 394 case MISCREG_TSL: 395 if (seg.unusable) 396 break; 397 case MISCREG_TR: 398 if (seg.s) 399 warn("%s: S flag is set\n", name); 400 break; 401 } 402 403 switch (idx) { 404 case MISCREG_SS: 405 case MISCREG_DS: 406 case MISCREG_ES: 407 case MISCREG_FS: 408 case MISCREG_GS: 409 case MISCREG_TSL: 410 if (seg.unusable) 411 break; 412 case MISCREG_TR: 413 case MISCREG_CS: 414 if (!seg.present) 415 warn("%s: P flag not set\n", name); 416 417 if (((seg.limit & 0xFFF) == 0 && seg.g) || 418 ((seg.limit & 0xFFF00000) != 0 && !seg.g)) { 419 warn("%s limit (0x%x) and g (%i) combination is illegal.\n", 420 name, seg.limit, seg.g); 421 } 422 break; 423 } 424 425 // TODO: Check CS DB 426} 427 |
|
278X86KvmCPU::X86KvmCPU(X86KvmCPUParams *params) 279 : BaseKvmCPU(params) 280{ 281 Kvm &kvm(vm.kvm); 282 283 if (!kvm.capSetTSSAddress()) 284 panic("KVM: Missing capability (KVM_CAP_SET_TSS_ADDR)\n"); 285 if (!kvm.capExtendedCPUID()) --- 214 unchanged lines hidden (view full) --- 500 501#undef APPLY_SREG 502#undef APPLY_SEGMENT 503#undef APPLY_DTABLE 504 505 // Clear the interrupt bitmap 506 memset(&sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); 507 | 428X86KvmCPU::X86KvmCPU(X86KvmCPUParams *params) 429 : BaseKvmCPU(params) 430{ 431 Kvm &kvm(vm.kvm); 432 433 if (!kvm.capSetTSSAddress()) 434 panic("KVM: Missing capability (KVM_CAP_SET_TSS_ADDR)\n"); 435 if (!kvm.capExtendedCPUID()) --- 214 unchanged lines hidden (view full) --- 650 651#undef APPLY_SREG 652#undef APPLY_SEGMENT 653#undef APPLY_DTABLE 654 655 // Clear the interrupt bitmap 656 memset(&sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); 657 |
658 RFLAGS rflags_nocc(tc->readMiscReg(MISCREG_RFLAGS)); 659 if (!rflags_nocc.vm) { 660 // Do segment verification if the CPU isn't entering virtual 661 // 8086 mode. We currently assume that unrestricted guest 662 // mode is available. 663 664#define APPLY_SEGMENT(kreg, idx) \ 665 checkSeg(# kreg, idx + MISCREG_SEG_SEL_BASE, sregs.kreg, sregs) 666 667 FOREACH_SEGMENT(); 668#undef APPLY_SEGMENT 669 } |
|
508 setSpecialRegisters(sregs); 509} 510void 511X86KvmCPU::updateKvmStateFPU() 512{ 513 warn_once("X86KvmCPU::updateKvmStateFPU not implemented\n"); 514} 515 --- 607 unchanged lines hidden --- | 670 setSpecialRegisters(sregs); 671} 672void 673X86KvmCPU::updateKvmStateFPU() 674{ 675 warn_once("X86KvmCPU::updateKvmStateFPU not implemented\n"); 676} 677 --- 607 unchanged lines hidden --- |