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 ---