| 650 | } |
| 651 | |
| 652 | static enum vm_cpu_mode |
| 653 | svm_vcpu_mode(struct vmcb *vmcb) |
| 654 | { |
| 655 | struct vmcb_segment seg; |
| 656 | struct vmcb_state *state; |
| 657 | int error; |
| 658 | |
| 659 | state = &vmcb->state; |
| 660 | |
| 661 | if (state->efer & EFER_LMA) { |
| 662 | error = vmcb_seg(vmcb, VM_REG_GUEST_CS, &seg); |
| 663 | KASSERT(error == 0, ("%s: vmcb_seg(cs) error %d", __func__, |
| 664 | error)); |
| 665 | |
| 666 | /* |
| 667 | * Section 4.8.1 for APM2, check if Code Segment has |
| 668 | * Long attribute set in descriptor. |
| 669 | */ |
| 670 | if (seg.attrib & VMCB_CS_ATTRIB_L) |
| 671 | return (CPU_MODE_64BIT); |
| 672 | else |
| 673 | return (CPU_MODE_COMPATIBILITY); |
| 674 | } else if (state->cr0 & CR0_PE) { |
| 675 | return (CPU_MODE_PROTECTED); |
| 676 | } else { |
| 677 | return (CPU_MODE_REAL); |
| 678 | } |
| 679 | } |
| 680 | |
| 681 | static enum vm_paging_mode |
| 682 | svm_paging_mode(uint64_t cr0, uint64_t cr4, uint64_t efer) |
no test coverage detected