* Handle guest I/O intercept. */
| 770 | * Handle guest I/O intercept. |
| 771 | */ |
| 772 | static int |
| 773 | svm_handle_io(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit) |
| 774 | { |
| 775 | struct vmcb_ctrl *ctrl; |
| 776 | struct vmcb_state *state; |
| 777 | struct svm_regctx *regs; |
| 778 | struct vm_inout_str *vis; |
| 779 | uint64_t info1; |
| 780 | int inout_string; |
| 781 | |
| 782 | state = svm_get_vmcb_state(svm_sc, vcpu); |
| 783 | ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu); |
| 784 | regs = svm_get_guest_regctx(svm_sc, vcpu); |
| 785 | |
| 786 | info1 = ctrl->exitinfo1; |
| 787 | inout_string = info1 & BIT(2) ? 1 : 0; |
| 788 | |
| 789 | /* |
| 790 | * The effective segment number in EXITINFO1[12:10] is populated |
| 791 | * only if the processor has the DecodeAssist capability. |
| 792 | * |
| 793 | * XXX this is not specified explicitly in APMv2 but can be verified |
| 794 | * empirically. |
| 795 | */ |
| 796 | if (inout_string && !decode_assist()) |
| 797 | return (UNHANDLED); |
| 798 | |
| 799 | vmexit->exitcode = VM_EXITCODE_INOUT; |
| 800 | vmexit->u.inout.in = (info1 & BIT(0)) ? 1 : 0; |
| 801 | vmexit->u.inout.string = inout_string; |
| 802 | vmexit->u.inout.rep = (info1 & BIT(3)) ? 1 : 0; |
| 803 | vmexit->u.inout.bytes = (info1 >> 4) & 0x7; |
| 804 | vmexit->u.inout.port = (uint16_t)(info1 >> 16); |
| 805 | vmexit->u.inout.eax = (uint32_t)(state->rax); |
| 806 | |
| 807 | if (inout_string) { |
| 808 | vmexit->exitcode = VM_EXITCODE_INOUT_STR; |
| 809 | vis = &vmexit->u.inout_str; |
| 810 | svm_paging_info(svm_get_vmcb(svm_sc, vcpu), &vis->paging); |
| 811 | vis->rflags = state->rflags; |
| 812 | vis->cr0 = state->cr0; |
| 813 | vis->index = svm_inout_str_index(regs, vmexit->u.inout.in); |
| 814 | vis->count = svm_inout_str_count(regs, vmexit->u.inout.rep); |
| 815 | vis->addrsize = svm_inout_str_addrsize(info1); |
| 816 | svm_inout_str_seginfo(svm_sc, vcpu, info1, |
| 817 | vmexit->u.inout.in, vis); |
| 818 | } |
| 819 | |
| 820 | return (UNHANDLED); |
| 821 | } |
| 822 | |
| 823 | static int |
| 824 | npf_fault_type(uint64_t exitinfo1) |
no test coverage detected