FreeBSD/sys/amd64/vmm/amd/svm.c
/*
 * Handle guest I/O intercept.
 */
Handle guest I/O intercept.
Handle guest I / O intercept .
static int
svm_handle_io(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
{
	struct vmcb_ctrl *ctrl;
	struct vmcb_state *state;
	struct svm_regctx *regs;
	struct vm_inout_str *vis;
	uint64_t info1;
	int inout_string;
	state = svm_get_vmcb_state(svm_sc, vcpu);
	ctrl  = svm_get_vmcb_ctrl(svm_sc, vcpu);
	regs  = svm_get_guest_regctx(svm_sc, vcpu);
	info1 = ctrl->exitinfo1;
	inout_string = info1 & BIT(2) ? 1 : 0;
	if (inout_string && !decode_assist())
		return (UNHANDLED);
	vmexit->exitcode 	= VM_EXITCODE_INOUT;
	vmexit->u.inout.in 	= (info1 & BIT(0)) ? 1 : 0;
	vmexit->u.inout.string 	= inout_string;
	vmexit->u.inout.rep 	= (info1 & BIT(3)) ? 1 : 0;
	vmexit->u.inout.bytes 	= (info1 >> 4) & 0x7;
	vmexit->u.inout.port 	= (uint16_t)(info1 >> 16);
	vmexit->u.inout.eax 	= (uint32_t)(state->rax);
	if (inout_string) {
		vmexit->exitcode = VM_EXITCODE_INOUT_STR;
		vis = &vmexit->u.inout_str;
		svm_paging_info(svm_get_vmcb(svm_sc, vcpu), &vis->paging);
		vis->rflags = state->rflags;
		vis->cr0 = state->cr0;
		vis->index = svm_inout_str_index(regs, vmexit->u.inout.in);
		vis->count = svm_inout_str_count(regs, vmexit->u.inout.rep);
		vis->addrsize = svm_inout_str_addrsize(info1);
		svm_inout_str_seginfo(svm_sc, vcpu, info1,
		    vmexit->u.inout.in, vis);
	}
	return (UNHANDLED);
}
static int svm_handle_io ( struct svm_softc * svm_sc , int vcpu , struct vm_exit * vmexit ) { struct vmcb_ctrl * ctrl ; struct vmcb_state * state ; struct svm_regctx * regs ; struct vm_inout_str * vis ; uint64_t info1 ; int inout_string ; state = svm_get_vmcb_state ( svm_sc , vcpu ) ; ctrl = svm_get_vmcb_ctrl ( svm_sc , vcpu ) ; regs = svm_get_guest_regctx ( svm_sc , vcpu ) ; info1 = ctrl -> exitinfo1 ; inout_string = info1 & BIT ( 2 ) ? 1 : 0 ; if ( inout_string && ! decode_assist ( ) ) return ( UNHANDLED ) ; vmexit -> exitcode = VM_EXITCODE_INOUT ; vmexit -> u . inout . in = ( info1 & BIT ( 0 ) ) ? 1 : 0 ; vmexit -> u . inout . string = inout_string ; vmexit -> u . inout . rep = ( info1 & BIT ( 3 ) ) ? 1 : 0 ; vmexit -> u . inout . bytes = ( info1 >> 4 ) & 0x7 ; vmexit -> u . inout . port = ( uint16_t ) ( info1 >> 16 ) ; vmexit -> u . inout . eax = ( uint32_t ) ( state -> rax ) ; if ( inout_string ) { vmexit -> exitcode = VM_EXITCODE_INOUT_STR ; vis = & vmexit -> u . inout_str ; svm_paging_info ( svm_get_vmcb ( svm_sc , vcpu ) , & vis -> paging ) ; vis -> rflags = state -> rflags ; vis -> cr0 = state -> cr0 ; vis -> index = svm_inout_str_index ( regs , vmexit -> u . inout . in ) ; vis -> count = svm_inout_str_count ( regs , vmexit -> u . inout . rep ) ; vis -> addrsize = svm_inout_str_addrsize ( info1 ) ; svm_inout_str_seginfo ( svm_sc , vcpu , info1 , vmexit -> u . inout . in , vis ) ; } return ( UNHANDLED ) ; }
Handle guest I/O intercept.
Handle guest I / O intercept .
/*
	 * The effective segment number in EXITINFO1[12:10] is populated
	 * only if the processor has the DecodeAssist capability.
	 *
	 * XXX this is not specified explicitly in APMv2 but can be verified
	 * empirically.
	 */