Ejemplo n.º 1
0
static int
vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
{
	int error;
	int bytes, port, in, out, string;
	int vcpu;

	vcpu = *pvcpu;

	port = vme->u.inout.port;
	bytes = vme->u.inout.bytes;
	string = vme->u.inout.string;
	in = vme->u.inout.in;
	out = !in;

        /* Extra-special case of host notifications */
        if (out && port == GUEST_NIO_PORT) {
                error = vmexit_handle_notify(ctx, vme, pvcpu, vme->u.inout.eax);
		return (error);
	}

	error = emulate_inout(ctx, vcpu, vme, strictio);
	if (error) {
		fprintf(stderr, "Unhandled %s%c 0x%04x at 0x%lx\n",
		    in ? "in" : "out",
		    bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'),
		    port, vmexit->rip);
		return (VMEXIT_ABORT);
	} else {
		return (VMEXIT_CONTINUE);
	}
}
Ejemplo n.º 2
0
static int
vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
{
	int error;
	int bytes, port, in, out;
	uint32_t eax;
	int vcpu;

	vcpu = *pvcpu;

	port = vme->u.inout.port;
	bytes = vme->u.inout.bytes;
	eax = vme->u.inout.eax;
	in = vme->u.inout.in;
	out = !in;

	/* We don't deal with these */
	if (vme->u.inout.string || vme->u.inout.rep)
		return (VMEXIT_ABORT);

	/* Special case of guest reset */
	if (out && port == 0x64 && (uint8_t)eax == 0xFE)
		return (vmexit_catch_reset());

        /* Extra-special case of host notifications */
        if (out && port == GUEST_NIO_PORT)
                return (vmexit_handle_notify(ctx, vme, pvcpu, eax));

	error = emulate_inout(ctx, vcpu, in, port, bytes, &eax, strictio);
	if (error == INOUT_OK && in)
		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, eax);

	switch (error) {
	case INOUT_OK:
		return (VMEXIT_CONTINUE);
	case INOUT_RESET:
		return (VMEXIT_RESET);
	case INOUT_POWEROFF:
		return (VMEXIT_POWEROFF);
	default:
		fprintf(stderr, "Unhandled %s%c 0x%04x\n",
			in ? "in" : "out",
			bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), port);
		return (vmexit_catch_inout());
	}
}
Ejemplo n.º 3
0
static void
vmexit_inout(struct vmctx *ctx, struct vhm_request *vhm_req, int *pvcpu)
{
	int error;
	int bytes, port, in;

	port = vhm_req->reqs.pio_request.address;
	bytes = vhm_req->reqs.pio_request.size;
	in = (vhm_req->reqs.pio_request.direction == REQUEST_READ);

	error = emulate_inout(ctx, pvcpu, &vhm_req->reqs.pio_request);
	if (error) {
		fprintf(stderr, "Unhandled %s%c 0x%04x\n",
				in ? "in" : "out",
				bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'),
				port);

		if (in) {
			vhm_req->reqs.pio_request.value = VHM_REQ_PIO_INVAL;
		}
	}
}