diff options
Diffstat (limited to 'lib/libvmmapi/vmmapi.c')
-rw-r--r-- | lib/libvmmapi/vmmapi.c | 290 |
1 files changed, 162 insertions, 128 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 451d679dbbba..2d0cc21aeb25 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include <machine/vmm_snapshot.h> #include "vmmapi.h" +#include "internal.h" #define MB (1024 * 1024UL) #define GB (1024 * 1024 * 1024UL) @@ -163,6 +164,29 @@ vm_destroy(struct vmctx *vm) free(vm); } +struct vcpu * +vm_vcpu_open(struct vmctx *ctx, int vcpuid) +{ + struct vcpu *vcpu; + + vcpu = malloc(sizeof(*vcpu)); + vcpu->ctx = ctx; + vcpu->vcpuid = vcpuid; + return (vcpu); +} + +void +vm_vcpu_close(struct vcpu *vcpu) +{ + free(vcpu); +} + +int +vcpu_id(struct vcpu *vcpu) +{ + return (vcpu->vcpuid); +} + int vm_parse_memsize(const char *opt, size_t *ret_memsize) { @@ -578,36 +602,46 @@ done: return (ptr); } +static int +vcpu_ioctl(struct vcpu *vcpu, u_long cmd, void *arg) +{ + /* + * XXX: fragile, handle with care + * Assumes that the first field of the ioctl data + * is the vcpuid. + */ + *(int *)arg = vcpu->vcpuid; + return (ioctl(vcpu->ctx->fd, cmd, arg)); +} + int -vm_set_desc(struct vmctx *ctx, int vcpu, int reg, +vm_set_desc(struct vcpu *vcpu, int reg, uint64_t base, uint32_t limit, uint32_t access) { int error; struct vm_seg_desc vmsegdesc; bzero(&vmsegdesc, sizeof(vmsegdesc)); - vmsegdesc.cpuid = vcpu; vmsegdesc.regnum = reg; vmsegdesc.desc.base = base; vmsegdesc.desc.limit = limit; vmsegdesc.desc.access = access; - error = ioctl(ctx->fd, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc); + error = vcpu_ioctl(vcpu, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc); return (error); } int -vm_get_desc(struct vmctx *ctx, int vcpu, int reg, - uint64_t *base, uint32_t *limit, uint32_t *access) +vm_get_desc(struct vcpu *vcpu, int reg, uint64_t *base, uint32_t *limit, + uint32_t *access) { int error; struct vm_seg_desc vmsegdesc; bzero(&vmsegdesc, sizeof(vmsegdesc)); - vmsegdesc.cpuid = vcpu; vmsegdesc.regnum = reg; - error = ioctl(ctx->fd, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc); + error = vcpu_ioctl(vcpu, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc); if (error == 0) { *base = vmsegdesc.desc.base; *limit = vmsegdesc.desc.limit; @@ -617,89 +651,84 @@ vm_get_desc(struct vmctx *ctx, int vcpu, int reg, } int -vm_get_seg_desc(struct vmctx *ctx, int vcpu, int reg, struct seg_desc *seg_desc) +vm_get_seg_desc(struct vcpu *vcpu, int reg, struct seg_desc *seg_desc) { int error; - error = vm_get_desc(ctx, vcpu, reg, &seg_desc->base, &seg_desc->limit, + error = vm_get_desc(vcpu, reg, &seg_desc->base, &seg_desc->limit, &seg_desc->access); return (error); } int -vm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val) +vm_set_register(struct vcpu *vcpu, int reg, uint64_t val) { int error; struct vm_register vmreg; bzero(&vmreg, sizeof(vmreg)); - vmreg.cpuid = vcpu; vmreg.regnum = reg; vmreg.regval = val; - error = ioctl(ctx->fd, VM_SET_REGISTER, &vmreg); + error = vcpu_ioctl(vcpu, VM_SET_REGISTER, &vmreg); return (error); } int -vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *ret_val) +vm_get_register(struct vcpu *vcpu, int reg, uint64_t *ret_val) { int error; struct vm_register vmreg; bzero(&vmreg, sizeof(vmreg)); - vmreg.cpuid = vcpu; vmreg.regnum = reg; - error = ioctl(ctx->fd, VM_GET_REGISTER, &vmreg); + error = vcpu_ioctl(vcpu, VM_GET_REGISTER, &vmreg); *ret_val = vmreg.regval; return (error); } int -vm_set_register_set(struct vmctx *ctx, int vcpu, unsigned int count, +vm_set_register_set(struct vcpu *vcpu, unsigned int count, const int *regnums, uint64_t *regvals) { int error; struct vm_register_set vmregset; bzero(&vmregset, sizeof(vmregset)); - vmregset.cpuid = vcpu; vmregset.count = count; vmregset.regnums = regnums; vmregset.regvals = regvals; - error = ioctl(ctx->fd, VM_SET_REGISTER_SET, &vmregset); + error = vcpu_ioctl(vcpu, VM_SET_REGISTER_SET, &vmregset); return (error); } int -vm_get_register_set(struct vmctx *ctx, int vcpu, unsigned int count, +vm_get_register_set(struct vcpu *vcpu, unsigned int count, const int *regnums, uint64_t *regvals) { int error; struct vm_register_set vmregset; bzero(&vmregset, sizeof(vmregset)); - vmregset.cpuid = vcpu; vmregset.count = count; vmregset.regnums = regnums; vmregset.regvals = regvals; - error = ioctl(ctx->fd, VM_GET_REGISTER_SET, &vmregset); + error = vcpu_ioctl(vcpu, VM_GET_REGISTER_SET, &vmregset); return (error); } int -vm_run(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit) +vm_run(struct vcpu *vcpu, struct vm_exit *vmexit) { int error; struct vm_run vmrun; bzero(&vmrun, sizeof(vmrun)); - vmrun.cpuid = vcpu; - error = ioctl(ctx->fd, VM_RUN, &vmrun); + error = vcpu_ioctl(vcpu, VM_RUN, &vmrun); bcopy(&vmrun.vm_exit, vmexit, sizeof(struct vm_exit)); return (error); } @@ -722,18 +751,17 @@ vm_reinit(struct vmctx *ctx) } int -vm_inject_exception(struct vmctx *ctx, int vcpu, int vector, int errcode_valid, +vm_inject_exception(struct vcpu *vcpu, int vector, int errcode_valid, uint32_t errcode, int restart_instruction) { struct vm_exception exc; - exc.cpuid = vcpu; exc.vector = vector; exc.error_code = errcode; exc.error_code_valid = errcode_valid; exc.restart_instruction = restart_instruction; - return (ioctl(ctx->fd, VM_INJECT_EXCEPTION, &exc)); + return (vcpu_ioctl(vcpu, VM_INJECT_EXCEPTION, &exc)); } int @@ -747,27 +775,25 @@ vm_apicid2vcpu(struct vmctx *ctx __unused, int apicid) } int -vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector) +vm_lapic_irq(struct vcpu *vcpu, int vector) { struct vm_lapic_irq vmirq; bzero(&vmirq, sizeof(vmirq)); - vmirq.cpuid = vcpu; vmirq.vector = vector; - return (ioctl(ctx->fd, VM_LAPIC_IRQ, &vmirq)); + return (vcpu_ioctl(vcpu, VM_LAPIC_IRQ, &vmirq)); } int -vm_lapic_local_irq(struct vmctx *ctx, int vcpu, int vector) +vm_lapic_local_irq(struct vcpu *vcpu, int vector) { struct vm_lapic_irq vmirq; bzero(&vmirq, sizeof(vmirq)); - vmirq.cpuid = vcpu; vmirq.vector = vector; - return (ioctl(ctx->fd, VM_LAPIC_LOCAL_IRQ, &vmirq)); + return (vcpu_ioctl(vcpu, VM_LAPIC_LOCAL_IRQ, &vmirq)); } int @@ -823,11 +849,10 @@ vm_ioapic_pincount(struct vmctx *ctx, int *pincount) } int -vm_readwrite_kernemu_device(struct vmctx *ctx, int vcpu, vm_paddr_t gpa, +vm_readwrite_kernemu_device(struct vcpu *vcpu, vm_paddr_t gpa, bool write, int size, uint64_t *value) { struct vm_readwrite_kernemu_device irp = { - .vcpuid = vcpu, .access_width = fls(size) - 1, .gpa = gpa, .value = write ? *value : ~0ul, @@ -835,7 +860,7 @@ vm_readwrite_kernemu_device(struct vmctx *ctx, int vcpu, vm_paddr_t gpa, long cmd = (write ? VM_SET_KERNEMU_DEV : VM_GET_KERNEMU_DEV); int rc; - rc = ioctl(ctx->fd, cmd, &irp); + rc = vcpu_ioctl(vcpu, cmd, &irp); if (rc == 0 && !write) *value = irp.value; return (rc); @@ -891,14 +916,13 @@ vm_isa_set_irq_trigger(struct vmctx *ctx, int atpic_irq, } int -vm_inject_nmi(struct vmctx *ctx, int vcpu) +vm_inject_nmi(struct vcpu *vcpu) { struct vm_nmi vmnmi; bzero(&vmnmi, sizeof(vmnmi)); - vmnmi.cpuid = vcpu; - return (ioctl(ctx->fd, VM_INJECT_NMI, &vmnmi)); + return (vcpu_ioctl(vcpu, VM_INJECT_NMI, &vmnmi)); } static const char *capstrmap[] = { @@ -933,32 +957,29 @@ vm_capability_type2name(int type) } int -vm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, - int *retval) +vm_get_capability(struct vcpu *vcpu, enum vm_cap_type cap, int *retval) { int error; struct vm_capability vmcap; bzero(&vmcap, sizeof(vmcap)); - vmcap.cpuid = vcpu; vmcap.captype = cap; - error = ioctl(ctx->fd, VM_GET_CAPABILITY, &vmcap); + error = vcpu_ioctl(vcpu, VM_GET_CAPABILITY, &vmcap); *retval = vmcap.capval; return (error); } int -vm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val) +vm_set_capability(struct vcpu *vcpu, enum vm_cap_type cap, int val) { struct vm_capability vmcap; bzero(&vmcap, sizeof(vmcap)); - vmcap.cpuid = vcpu; vmcap.captype = cap; vmcap.capval = val; - return (ioctl(ctx->fd, VM_SET_CAPABILITY, &vmcap)); + return (vcpu_ioctl(vcpu, VM_SET_CAPABILITY, &vmcap)); } int @@ -1021,13 +1042,12 @@ vm_unmap_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, } int -vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, +vm_setup_pptdev_msi(struct vmctx *ctx, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { struct vm_pptdev_msi pptmsi; bzero(&pptmsi, sizeof(pptmsi)); - pptmsi.vcpu = vcpu; pptmsi.bus = bus; pptmsi.slot = slot; pptmsi.func = func; @@ -1039,13 +1059,12 @@ vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, } int -vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, +vm_setup_pptdev_msix(struct vmctx *ctx, int bus, int slot, int func, int idx, uint64_t addr, uint64_t msg, uint32_t vector_control) { struct vm_pptdev_msix pptmsix; bzero(&pptmsix, sizeof(pptmsix)); - pptmsix.vcpu = vcpu; pptmsix.bus = bus; pptmsix.slot = slot; pptmsix.func = func; @@ -1071,7 +1090,7 @@ vm_disable_pptdev_msix(struct vmctx *ctx, int bus, int slot, int func) } uint64_t * -vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, +vm_get_stats(struct vcpu *vcpu, struct timeval *ret_tv, int *ret_entries) { static _Thread_local uint64_t *stats_buf; @@ -1082,11 +1101,10 @@ vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, bool have_stats; have_stats = false; - vmstats.cpuid = vcpu; count = 0; for (index = 0;; index += nitems(vmstats.statbuf)) { vmstats.index = index; - if (ioctl(ctx->fd, VM_STATS, &vmstats) != 0) + if (vcpu_ioctl(vcpu, VM_STATS, &vmstats) != 0) break; if (stats_count < index + vmstats.num_entries) { new_stats = realloc(stats_buf, @@ -1129,30 +1147,28 @@ vm_get_stat_desc(struct vmctx *ctx, int index) } int -vm_get_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state *state) +vm_get_x2apic_state(struct vcpu *vcpu, enum x2apic_state *state) { int error; struct vm_x2apic x2apic; bzero(&x2apic, sizeof(x2apic)); - x2apic.cpuid = vcpu; - error = ioctl(ctx->fd, VM_GET_X2APIC_STATE, &x2apic); + error = vcpu_ioctl(vcpu, VM_GET_X2APIC_STATE, &x2apic); *state = x2apic.state; return (error); } int -vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state state) +vm_set_x2apic_state(struct vcpu *vcpu, enum x2apic_state state) { int error; struct vm_x2apic x2apic; bzero(&x2apic, sizeof(x2apic)); - x2apic.cpuid = vcpu; x2apic.state = state; - error = ioctl(ctx->fd, VM_SET_X2APIC_STATE, &x2apic); + error = vcpu_ioctl(vcpu, VM_SET_X2APIC_STATE, &x2apic); return (error); } @@ -1162,7 +1178,7 @@ vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state state) * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT */ int -vcpu_reset(struct vmctx *vmctx, int vcpu) +vcpu_reset(struct vcpu *vcpu) { int error; uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; @@ -1172,12 +1188,12 @@ vcpu_reset(struct vmctx *vmctx, int vcpu) zero = 0; rflags = 0x2; - error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); + error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS, rflags); if (error) goto done; rip = 0xfff0; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, rip)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RIP, rip)) != 0) goto done; /* @@ -1186,17 +1202,17 @@ vcpu_reset(struct vmctx *vmctx, int vcpu) * guests like Windows. */ cr0 = CR0_NE; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR0, cr0)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR2, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR2, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR3, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR3, zero)) != 0) goto done; cr4 = 0; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, cr4)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR4, cr4)) != 0) goto done; /* @@ -1205,13 +1221,13 @@ vcpu_reset(struct vmctx *vmctx, int vcpu) desc_base = 0xffff0000; desc_limit = 0xffff; desc_access = 0x0093; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS, + error = vm_set_desc(vcpu, VM_REG_GUEST_CS, desc_base, desc_limit, desc_access); if (error) goto done; sel = 0xf000; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_CS, sel)) != 0) goto done; /* @@ -1220,91 +1236,91 @@ vcpu_reset(struct vmctx *vmctx, int vcpu) desc_base = 0; desc_limit = 0xffff; desc_access = 0x0093; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS, + error = vm_set_desc(vcpu, VM_REG_GUEST_SS, desc_base, desc_limit, desc_access); if (error) goto done; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS, + error = vm_set_desc(vcpu, VM_REG_GUEST_DS, desc_base, desc_limit, desc_access); if (error) goto done; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES, + error = vm_set_desc(vcpu, VM_REG_GUEST_ES, desc_base, desc_limit, desc_access); if (error) goto done; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS, + error = vm_set_desc(vcpu, VM_REG_GUEST_FS, desc_base, desc_limit, desc_access); if (error) goto done; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS, + error = vm_set_desc(vcpu, VM_REG_GUEST_GS, desc_base, desc_limit, desc_access); if (error) goto done; sel = 0; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_SS, sel)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_DS, sel)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_ES, sel)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_FS, sel)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_GS, sel)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_EFER, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_EFER, zero)) != 0) goto done; /* General purpose registers */ rdx = 0xf00; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RAX, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RAX, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBX, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBX, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RCX, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RCX, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDX, rdx)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDX, rdx)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSI, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSI, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDI, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDI, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBP, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBP, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSP, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R8, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R8, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R9, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R9, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R10, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R10, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R11, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R11, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R12, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R12, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R13, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R13, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R14, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R14, zero)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_R15, zero)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_R15, zero)) != 0) goto done; /* GDTR, IDTR */ desc_base = 0; desc_limit = 0xffff; desc_access = 0; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR, + error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR, desc_base, desc_limit, desc_access); if (error != 0) goto done; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_IDTR, + error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR, desc_base, desc_limit, desc_access); if (error != 0) goto done; @@ -1313,35 +1329,35 @@ vcpu_reset(struct vmctx *vmctx, int vcpu) desc_base = 0; desc_limit = 0xffff; desc_access = 0x0000008b; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); + error = vm_set_desc(vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); if (error) goto done; sel = 0; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, sel)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_TR, sel)) != 0) goto done; /* LDTR */ desc_base = 0; desc_limit = 0xffff; desc_access = 0x00000082; - error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base, + error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR, desc_base, desc_limit, desc_access); if (error) goto done; sel = 0; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0) + if ((error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, 0)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DR6, + if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR6, 0xffff0ff0)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DR7, 0x400)) != + if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR7, 0x400)) != 0) goto done; - if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_INTR_SHADOW, + if ((error = vm_set_register(vcpu, VM_REG_GUEST_INTR_SHADOW, zero)) != 0) goto done; @@ -1384,19 +1400,18 @@ vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities) } int -vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, +vm_gla2gpa(struct vcpu *vcpu, struct vm_guest_paging *paging, uint64_t gla, int prot, uint64_t *gpa, int *fault) { struct vm_gla2gpa gg; int error; bzero(&gg, sizeof(struct vm_gla2gpa)); - gg.vcpuid = vcpu; gg.prot = prot; gg.gla = gla; gg.paging = *paging; - error = ioctl(ctx->fd, VM_GLA2GPA, &gg); + error = vcpu_ioctl(vcpu, VM_GLA2GPA, &gg); if (error == 0) { *fault = gg.fault; *gpa = gg.gpa; @@ -1405,19 +1420,18 @@ vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, } int -vm_gla2gpa_nofault(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, +vm_gla2gpa_nofault(struct vcpu *vcpu, struct vm_guest_paging *paging, uint64_t gla, int prot, uint64_t *gpa, int *fault) { struct vm_gla2gpa gg; int error; bzero(&gg, sizeof(struct vm_gla2gpa)); - gg.vcpuid = vcpu; gg.prot = prot; gg.gla = gla; gg.paging = *paging; - error = ioctl(ctx->fd, VM_GLA2GPA_NOFAULT, &gg); + error = vcpu_ioctl(vcpu, VM_GLA2GPA_NOFAULT, &gg); if (error == 0) { *fault = gg.fault; *gpa = gg.gpa; @@ -1430,7 +1444,7 @@ vm_gla2gpa_nofault(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, #endif int -vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, +vm_copy_setup(struct vcpu *vcpu, struct vm_guest_paging *paging, uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt, int *fault) { @@ -1445,14 +1459,14 @@ vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, while (len) { assert(iovcnt > 0); - error = vm_gla2gpa(ctx, vcpu, paging, gla, prot, &gpa, fault); + error = vm_gla2gpa(vcpu, paging, gla, prot, &gpa, fault); if (error || *fault) return (error); off = gpa & PAGE_MASK; n = MIN(len, PAGE_SIZE - off); - va = vm_map_gpa(ctx, gpa, n); + va = vm_map_gpa(vcpu->ctx, gpa, n); if (va == NULL) return (EFAULT); @@ -1554,50 +1568,70 @@ vm_debug_cpus(struct vmctx *ctx, cpuset_t *cpus) } int -vm_activate_cpu(struct vmctx *ctx, int vcpu) +vm_activate_cpu(struct vcpu *vcpu) { struct vm_activate_cpu ac; int error; bzero(&ac, sizeof(struct vm_activate_cpu)); - ac.vcpuid = vcpu; - error = ioctl(ctx->fd, VM_ACTIVATE_CPU, &ac); + error = vcpu_ioctl(vcpu, VM_ACTIVATE_CPU, &ac); return (error); } int -vm_suspend_cpu(struct vmctx *ctx, int vcpu) +vm_suspend_all_cpus(struct vmctx *ctx) { struct vm_activate_cpu ac; int error; bzero(&ac, sizeof(struct vm_activate_cpu)); - ac.vcpuid = vcpu; + ac.vcpuid = -1; error = ioctl(ctx->fd, VM_SUSPEND_CPU, &ac); return (error); } int -vm_resume_cpu(struct vmctx *ctx, int vcpu) +vm_suspend_cpu(struct vcpu *vcpu) +{ + struct vm_activate_cpu ac; + int error; + + bzero(&ac, sizeof(struct vm_activate_cpu)); + error = vcpu_ioctl(vcpu, VM_SUSPEND_CPU, &ac); + return (error); +} + +int +vm_resume_cpu(struct vcpu *vcpu) +{ + struct vm_activate_cpu ac; + int error; + + bzero(&ac, sizeof(struct vm_activate_cpu)); + error = vcpu_ioctl(vcpu, VM_RESUME_CPU, &ac); + return (error); +} + +int +vm_resume_all_cpus(struct vmctx *ctx) { struct vm_activate_cpu ac; int error; bzero(&ac, sizeof(struct vm_activate_cpu)); - ac.vcpuid = vcpu; + ac.vcpuid = -1; error = ioctl(ctx->fd, VM_RESUME_CPU, &ac); return (error); } int -vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *info1, uint64_t *info2) +vm_get_intinfo(struct vcpu *vcpu, uint64_t *info1, uint64_t *info2) { struct vm_intinfo vmii; int error; bzero(&vmii, sizeof(struct vm_intinfo)); - vmii.vcpuid = vcpu; - error = ioctl(ctx->fd, VM_GET_INTINFO, &vmii); + error = vcpu_ioctl(vcpu, VM_GET_INTINFO, &vmii); if (error == 0) { *info1 = vmii.info1; *info2 = vmii.info2; @@ -1606,15 +1640,14 @@ vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *info1, uint64_t *info2) } int -vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t info1) +vm_set_intinfo(struct vcpu *vcpu, uint64_t info1) { struct vm_intinfo vmii; int error; bzero(&vmii, sizeof(struct vm_intinfo)); - vmii.vcpuid = vcpu; vmii.info1 = info1; - error = ioctl(ctx->fd, VM_SET_INTINFO, &vmii); + error = vcpu_ioctl(vcpu, VM_SET_INTINFO, &vmii); return (error); } @@ -1671,10 +1704,11 @@ vm_rtc_gettime(struct vmctx *ctx, time_t *secs) } int -vm_restart_instruction(struct vmctx *ctx, int vcpu) +vm_restart_instruction(struct vcpu *vcpu) { + int arg; - return (ioctl(ctx->fd, VM_RESTART_INSTRUCTION, &vcpu)); + return (vcpu_ioctl(vcpu, VM_RESTART_INSTRUCTION, &arg)); } int |