diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -180,6 +180,14 @@ vm_paddr_t gpa, size_t len, vm_paddr_t hpa); int vm_unmap_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, vm_paddr_t gpa, size_t len); +int vm_mmap_mmio(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len, const vm_paddr_t hpa); +int vm_munmap_mmio(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len); +int vm_mwire_gpa(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len); +int vm_munwire_gpa(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len); int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec); int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -1012,6 +1012,52 @@ return (ioctl(ctx->fd, VM_UNMAP_PPTDEV_MMIO, &pptmmio)); } +/* + * Modifies the second level address translation (SLAT) of the guest memory + * space. + */ +static int +vm_mmodify_slat(struct vmctx *const ctx, const vm_paddr_t gpa, const vm_paddr_t len, + const vm_paddr_t hpa, const enum slat_op_type type) +{ + struct vm_slat_op slat_op = { + .gpa = gpa, + .len = len, + .hpa = hpa, + .type = type, + }; + + return ioctl(ctx->fd, VM_MODIFY_SLAT, &slat_op); +} + +int +vm_mmap_mmio(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len, const vm_paddr_t hpa) +{ + return vm_mmodify_slat(ctx, gpa, len, hpa, VM_MAP_MMIO); +} + +int +vm_munmap_mmio(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len) +{ + return vm_mmodify_slat(ctx, gpa, len, 0, VM_UNMAP_MMIO); +} + +int +vm_mwire_gpa(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len) +{ + return vm_mmodify_slat(ctx, gpa, len, 0, VM_WIRE_GPA); +} + +int +vm_munwire_gpa(struct vmctx *const ctx, const vm_paddr_t gpa, + const vm_paddr_t len) +{ + return vm_mmodify_slat(ctx, gpa, len, 0, VM_UNWIRE_GPA); +} + int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) @@ -1687,7 +1733,7 @@ VM_SET_CAPABILITY, VM_GET_CAPABILITY, VM_BIND_PPTDEV, VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_PPTDEV_MSI, VM_PPTDEV_MSIX, VM_UNMAP_PPTDEV_MMIO, VM_PPTDEV_DISABLE_MSIX, - VM_INJECT_NMI, VM_STATS, VM_STAT_DESC, + VM_MODIFY_SLAT, VM_INJECT_NMI, VM_STATS, VM_STAT_DESC, VM_SET_X2APIC_STATE, VM_GET_X2APIC_STATE, VM_GET_HPET_CAPABILITIES, VM_GET_GPA_PMAP, VM_GLA2GPA, VM_GLA2GPA_NOFAULT, diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -236,6 +236,10 @@ void vm_free_memseg(struct vm *vm, int ident); int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); +int vm_wire_gpa(struct vm *const vm, const vm_paddr_t gpa, + const vm_paddr_t len); +int vm_unwire_gpa(struct vm *const vm, const vm_paddr_t gpa, + const vm_paddr_t len); int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func); int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func); diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h --- a/sys/amd64/include/vmm_dev.h +++ b/sys/amd64/include/vmm_dev.h @@ -146,6 +146,21 @@ size_t len; }; +/* second level address translation */ +enum slat_op_type { + VM_MAP_MMIO, + VM_UNMAP_MMIO, + VM_WIRE_GPA, + VM_UNWIRE_GPA +}; + +struct vm_slat_op { + vm_paddr_t gpa; + vm_paddr_t len; + vm_paddr_t hpa; + enum slat_op_type type; +}; + struct vm_pptdev_msi { int vcpu; int bus; @@ -309,6 +324,7 @@ IOCNUM_PPTDEV_MSIX = 44, IOCNUM_PPTDEV_DISABLE_MSIX = 45, IOCNUM_UNMAP_PPTDEV_MMIO = 46, + IOCNUM_MODIFY_SLAT = 48, /* statistics */ IOCNUM_VM_STATS = 50, @@ -427,6 +443,8 @@ _IOW('v', IOCNUM_PPTDEV_DISABLE_MSIX, struct vm_pptdev) #define VM_UNMAP_PPTDEV_MMIO \ _IOW('v', IOCNUM_UNMAP_PPTDEV_MMIO, struct vm_pptdev_mmio) +#define VM_MODIFY_SLAT \ + _IOW('v', IOCNUM_MODIFY_SLAT, struct vm_slat_op) #define VM_INJECT_NMI \ _IOW('v', IOCNUM_INJECT_NMI, struct vm_nmi) #define VM_STATS \ diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -636,6 +636,20 @@ return (0); } +int +vm_wire_gpa(struct vm *const vm, const vm_paddr_t gpa, const vm_paddr_t len) +{ + return vm_map_wire(&vm->vmspace->vm_map, gpa, gpa + len, + VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); +} + +int +vm_unwire_gpa(struct vm *const vm, const vm_paddr_t gpa, const vm_paddr_t len) +{ + return vm_map_unwire(&vm->vmspace->vm_map, gpa, gpa + len, + VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); +} + /* * Return 'true' if 'gpa' is allocated in the guest address space. * diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -373,6 +373,7 @@ struct vm_capability *vmcap; struct vm_pptdev *pptdev; struct vm_pptdev_mmio *pptmmio; + struct vm_slat_op *slat_op; struct vm_pptdev_msi *pptmsi; struct vm_pptdev_msix *pptmsix; struct vm_nmi *vmnmi; @@ -453,6 +454,7 @@ case VM_MMAP_MEMSEG: case VM_MUNMAP_MEMSEG: case VM_REINIT: + case VM_MODIFY_SLAT: /* * ioctls that operate on the entire virtual machine must * prevent all vcpus from running. @@ -540,6 +542,26 @@ error = ppt_unmap_mmio(sc->vm, pptmmio->bus, pptmmio->slot, pptmmio->func, pptmmio->gpa, pptmmio->len); break; + case VM_MODIFY_SLAT: + slat_op = (struct vm_slat_op *)data; + switch (slat_op->type) { + case VM_MAP_MMIO: + error = vm_map_mmio(sc->vm, slat_op->gpa, slat_op->len, + slat_op->hpa); + break; + case VM_UNMAP_MMIO: + error = vm_unmap_mmio(sc->vm, slat_op->gpa, + slat_op->len); + break; + case VM_WIRE_GPA: + error = vm_wire_gpa(sc->vm, slat_op->gpa, slat_op->len); + break; + case VM_UNWIRE_GPA: + error = vm_unwire_gpa(sc->vm, slat_op->gpa, + slat_op->len); + break; + } + break; case VM_BIND_PPTDEV: pptdev = (struct vm_pptdev *)data; error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot,