diff options
Diffstat (limited to 'usr.sbin/bhyve/inout.c')
-rw-r--r-- | usr.sbin/bhyve/inout.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/usr.sbin/bhyve/inout.c b/usr.sbin/bhyve/inout.c index fe9e0d8..1041a59 100644 --- a/usr.sbin/bhyve/inout.c +++ b/usr.sbin/bhyve/inout.c @@ -154,31 +154,28 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) /* Limit number of back-to-back in/out emulations to 16 */ iterations = MIN(count, 16); while (iterations > 0) { + assert(retval == 0); if (vie_calculate_gla(vis->paging.cpu_mode, vis->seg_name, &vis->seg_desc, index, bytes, addrsize, prot, &gla)) { - error = vm_inject_exception2(ctx, vcpu, - IDT_GP, 0); - assert(error == 0); - retval = INOUT_RESTART; + vm_inject_gp(ctx, vcpu); break; } - error = vm_gla2gpa(ctx, vcpu, &vis->paging, gla, bytes, - prot, iov, nitems(iov)); - assert(error == 0 || error == 1 || error == -1); - if (error) { - retval = (error == 1) ? INOUT_RESTART : - INOUT_ERROR; + error = vm_copy_setup(ctx, vcpu, &vis->paging, gla, + bytes, prot, iov, nitems(iov)); + if (error == -1) { + retval = -1; /* Unrecoverable error */ + break; + } else if (error == 1) { + retval = 0; /* Resume guest to handle fault */ break; } if (vie_alignment_check(vis->paging.cpl, bytes, vis->cr0, vis->rflags, gla)) { - error = vm_inject_exception2(ctx, vcpu, - IDT_AC, 0); - assert(error == 0); - return (INOUT_RESTART); + vm_inject_ac(ctx, vcpu, 0); + break; } val = 0; @@ -217,8 +214,8 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) } /* Restart the instruction if more iterations remain */ - if (retval == INOUT_OK && count != 0) - retval = INOUT_RESTART; + if (retval == 0 && count != 0) + vmexit->inst_length = 0; } else { if (!in) { val = vmexit->u.inout.eax & vie_size2mask(bytes); |