From owner-svn-src-head@freebsd.org Thu Feb 22 00:39:26 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C1A7DF1135D; Thu, 22 Feb 2018 00:39:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 75B1D7BC7D; Thu, 22 Feb 2018 00:39:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6C5B51FDBC; Thu, 22 Feb 2018 00:39:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w1M0dQx1011636; Thu, 22 Feb 2018 00:39:26 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1M0dP8d011632; Thu, 22 Feb 2018 00:39:25 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201802220039.w1M0dP8d011632@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 22 Feb 2018 00:39:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329768 - in head: lib/libvmmapi sys/amd64/include sys/amd64/vmm X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: in head: lib/libvmmapi sys/amd64/include sys/amd64/vmm X-SVN-Commit-Revision: 329768 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Feb 2018 00:39:27 -0000 Author: jhb Date: Thu Feb 22 00:39:25 2018 New Revision: 329768 URL: https://svnweb.freebsd.org/changeset/base/329768 Log: Add two new ioctls to bhyve for batch register fetch/store operations. These are a convenience for bhyve's debug server to use a single ioctl for 'g' and 'G' rather than a loop of individual get/set ioctl requests. Reviewed by: grehan MFC after: 2 months Differential Revision: https://reviews.freebsd.org/D14074 Modified: head/lib/libvmmapi/vmmapi.c head/lib/libvmmapi/vmmapi.h head/sys/amd64/include/vmm_dev.h head/sys/amd64/vmm/vmm_dev.c Modified: head/lib/libvmmapi/vmmapi.c ============================================================================== --- head/lib/libvmmapi/vmmapi.c Thu Feb 22 00:36:12 2018 (r329767) +++ head/lib/libvmmapi/vmmapi.c Thu Feb 22 00:39:25 2018 (r329768) @@ -588,6 +588,40 @@ vm_get_register(struct vmctx *ctx, int vcpu, int reg, } int +vm_set_register_set(struct vmctx *ctx, int 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); + return (error); +} + +int +vm_get_register_set(struct vmctx *ctx, int 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); + return (error); +} + +int vm_run(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit) { int error; @@ -1435,6 +1469,7 @@ vm_get_ioctls(size_t *len) VM_ALLOC_MEMSEG, VM_GET_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_GETNEXT, VM_SET_REGISTER, VM_GET_REGISTER, VM_SET_SEGMENT_DESCRIPTOR, VM_GET_SEGMENT_DESCRIPTOR, + VM_SET_REGISTER_SET, VM_GET_REGISTER_SET, VM_INJECT_EXCEPTION, VM_LAPIC_IRQ, VM_LAPIC_LOCAL_IRQ, VM_LAPIC_MSI, VM_IOAPIC_ASSERT_IRQ, VM_IOAPIC_DEASSERT_IRQ, VM_IOAPIC_PULSE_IRQ, VM_IOAPIC_PINCOUNT, VM_ISA_ASSERT_IRQ, Modified: head/lib/libvmmapi/vmmapi.h ============================================================================== --- head/lib/libvmmapi/vmmapi.h Thu Feb 22 00:36:12 2018 (r329767) +++ head/lib/libvmmapi/vmmapi.h Thu Feb 22 00:39:25 2018 (r329768) @@ -127,6 +127,10 @@ int vm_get_seg_desc(struct vmctx *ctx, int vcpu, int r struct seg_desc *seg_desc); int vm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val); int vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *retval); +int vm_set_register_set(struct vmctx *ctx, int vcpu, unsigned int count, + const int *regnums, uint64_t *regvals); +int vm_get_register_set(struct vmctx *ctx, int vcpu, unsigned int count, + const int *regnums, uint64_t *regvals); int vm_run(struct vmctx *ctx, int vcpu, struct vm_exit *ret_vmexit); int vm_suspend(struct vmctx *ctx, enum vm_suspend_how how); int vm_reinit(struct vmctx *ctx); Modified: head/sys/amd64/include/vmm_dev.h ============================================================================== --- head/sys/amd64/include/vmm_dev.h Thu Feb 22 00:36:12 2018 (r329767) +++ head/sys/amd64/include/vmm_dev.h Thu Feb 22 00:39:25 2018 (r329768) @@ -66,6 +66,13 @@ struct vm_seg_desc { /* data or code segment */ struct seg_desc desc; }; +struct vm_register_set { + int cpuid; + unsigned int count; + const int *regnums; /* enum vm_reg_name */ + uint64_t *regvals; +}; + struct vm_run { int cpuid; struct vm_exit vm_exit; @@ -242,6 +249,8 @@ enum { IOCNUM_GET_REGISTER = 21, IOCNUM_SET_SEGMENT_DESCRIPTOR = 22, IOCNUM_GET_SEGMENT_DESCRIPTOR = 23, + IOCNUM_SET_REGISTER_SET = 24, + IOCNUM_GET_REGISTER_SET = 25, /* interrupt injection */ IOCNUM_GET_INTINFO = 28, @@ -312,6 +321,10 @@ enum { _IOW('v', IOCNUM_SET_SEGMENT_DESCRIPTOR, struct vm_seg_desc) #define VM_GET_SEGMENT_DESCRIPTOR \ _IOWR('v', IOCNUM_GET_SEGMENT_DESCRIPTOR, struct vm_seg_desc) +#define VM_SET_REGISTER_SET \ + _IOW('v', IOCNUM_SET_REGISTER_SET, struct vm_register_set) +#define VM_GET_REGISTER_SET \ + _IOWR('v', IOCNUM_GET_REGISTER_SET, struct vm_register_set) #define VM_INJECT_EXCEPTION \ _IOW('v', IOCNUM_INJECT_EXCEPTION, struct vm_exception) #define VM_LAPIC_IRQ \ Modified: head/sys/amd64/vmm/vmm_dev.c ============================================================================== --- head/sys/amd64/vmm/vmm_dev.c Thu Feb 22 00:36:12 2018 (r329767) +++ head/sys/amd64/vmm/vmm_dev.c Thu Feb 22 00:39:25 2018 (r329768) @@ -282,6 +282,36 @@ done: } static int +vm_get_register_set(struct vm *vm, int vcpu, unsigned int count, int *regnum, + uint64_t *regval) +{ + int error, i; + + error = 0; + for (i = 0; i < count; i++) { + error = vm_get_register(vm, vcpu, regnum[i], ®val[i]); + if (error) + break; + } + return (error); +} + +static int +vm_set_register_set(struct vm *vm, int vcpu, unsigned int count, int *regnum, + uint64_t *regval) +{ + int error, i; + + error = 0; + for (i = 0; i < count; i++) { + error = vm_set_register(vm, vcpu, regnum[i], regval[i]); + if (error) + break; + } + return (error); +} + +static int vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, struct thread *td) { @@ -290,6 +320,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t da struct vmmdev_softc *sc; struct vm_register *vmreg; struct vm_seg_desc *vmsegdesc; + struct vm_register_set *vmregset; struct vm_run *vmrun; struct vm_exception *vmexc; struct vm_lapic_irq *vmirq; @@ -315,6 +346,8 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t da struct vm_rtc_time *rtctime; struct vm_rtc_data *rtcdata; struct vm_memmap *mm; + uint64_t *regvals; + int *regnums; sc = vmmdev_lookup2(cdev); if (sc == NULL) @@ -333,6 +366,8 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t da case VM_SET_REGISTER: case VM_GET_SEGMENT_DESCRIPTOR: case VM_SET_SEGMENT_DESCRIPTOR: + case VM_GET_REGISTER_SET: + case VM_SET_REGISTER_SET: case VM_INJECT_EXCEPTION: case VM_GET_CAPABILITY: case VM_SET_CAPABILITY: @@ -545,6 +580,48 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t da error = vm_get_seg_desc(sc->vm, vmsegdesc->cpuid, vmsegdesc->regnum, &vmsegdesc->desc); + break; + case VM_GET_REGISTER_SET: + vmregset = (struct vm_register_set *)data; + if (vmregset->count > VM_REG_LAST) { + error = EINVAL; + break; + } + regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV, + M_WAITOK); + regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV, + M_WAITOK); + error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) * + vmregset->count); + if (error == 0) + error = vm_get_register_set(sc->vm, vmregset->cpuid, + vmregset->count, regnums, regvals); + if (error == 0) + error = copyout(regvals, vmregset->regvals, + sizeof(regvals[0]) * vmregset->count); + free(regvals, M_VMMDEV); + free(regnums, M_VMMDEV); + break; + case VM_SET_REGISTER_SET: + vmregset = (struct vm_register_set *)data; + if (vmregset->count > VM_REG_LAST) { + error = EINVAL; + break; + } + regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV, + M_WAITOK); + regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV, + M_WAITOK); + error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) * + vmregset->count); + if (error == 0) + error = copyin(vmregset->regvals, regvals, + sizeof(regvals[0]) * vmregset->count); + if (error == 0) + error = vm_set_register_set(sc->vm, vmregset->cpuid, + vmregset->count, regnums, regvals); + free(regvals, M_VMMDEV); + free(regnums, M_VMMDEV); break; case VM_GET_CAPABILITY: vmcap = (struct vm_capability *)data;