diff options
author | D Scott Phillips <scottph@FreeBSD.org> | 2021-03-18 16:08:52 +0000 |
---|---|---|
committer | Ka Ho Ng <khng@FreeBSD.org> | 2021-03-19 03:04:36 +0000 |
commit | f8a6ec2d572758da6cfd29fcb4ecf4430463661d (patch) | |
tree | c93d10a65c730272291273d46688fcff2ed8dcb0 /lib/libvmmapi/vmmapi.c | |
parent | 621b5090487de9fed1b503769702a9a2a27cc7bb (diff) | |
download | src-f8a6ec2d572758da6cfd29fcb4ecf4430463661d.tar.gz src-f8a6ec2d572758da6cfd29fcb4ecf4430463661d.zip |
bhyve: support relocating fbuf and passthru data BARs
We want to allow the UEFI firmware to enumerate and assign
addresses to PCI devices so we can boot from NVMe[1]. Address
assignment of PCI BARs is properly handled by the PCI emulation
code in general, but a few specific cases need additional support.
fbuf and passthru map additional objects into the guest physical
address space and so need to handle address updates. Here we add a
callback to emulated PCI devices to inform them of a BAR
configuration change. fbuf and passthru then watch for these BAR
changes and relocate the frame buffer memory segment and passthru
device mmio area respectively.
We also add new VM_MUNMAP_MEMSEG and VM_UNMAP_PPTDEV_MMIO ioctls
to vmm(4) to facilitate the unmapping needed for addres updates.
[1]: https://github.com/freebsd/uefi-edk2/pull/9/
Originally by: scottph
MFC After: 1 week
Sponsored by: Intel Corporation
Reviewed by: grehan
Approved by: philip (mentor)
Differential Revision: https://reviews.freebsd.org/D24066
Diffstat (limited to 'lib/libvmmapi/vmmapi.c')
-rw-r--r-- | lib/libvmmapi/vmmapi.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 7d46a85b1cd5..7faa2fc545ea 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -252,6 +252,19 @@ vm_get_guestmem_from_ctx(struct vmctx *ctx, char **guest_baseaddr, } int +vm_munmap_memseg(struct vmctx *ctx, vm_paddr_t gpa, size_t len) +{ + struct vm_munmap munmap; + int error; + + munmap.gpa = gpa; + munmap.len = len; + + error = ioctl(ctx->fd, VM_MUNMAP_MEMSEG, &munmap); + return (error); +} + +int vm_mmap_getnext(struct vmctx *ctx, vm_paddr_t *gpa, int *segid, vm_ooffset_t *segoff, size_t *len, int *prot, int *flags) { @@ -981,6 +994,22 @@ vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, } int +vm_unmap_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, + vm_paddr_t gpa, size_t len) +{ + struct vm_pptdev_mmio pptmmio; + + bzero(&pptmmio, sizeof(pptmmio)); + pptmmio.bus = bus; + pptmmio.slot = slot; + pptmmio.func = func; + pptmmio.gpa = gpa; + pptmmio.len = len; + + return (ioctl(ctx->fd, VM_UNMAP_PPTDEV_MMIO, &pptmmio)); +} + +int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { @@ -1644,7 +1673,7 @@ vm_get_ioctls(size_t *len) /* keep in sync with machine/vmm_dev.h */ static const cap_ioctl_t vm_ioctl_cmds[] = { VM_RUN, VM_SUSPEND, VM_REINIT, VM_ALLOC_MEMSEG, VM_GET_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_MEMSEG, - VM_MMAP_GETNEXT, VM_SET_REGISTER, VM_GET_REGISTER, + VM_MMAP_GETNEXT, VM_MUNMAP_MEMSEG, VM_SET_REGISTER, VM_GET_REGISTER, VM_SET_SEGMENT_DESCRIPTOR, VM_GET_SEGMENT_DESCRIPTOR, VM_SET_REGISTER_SET, VM_GET_REGISTER_SET, VM_SET_KERNEMU_DEV, VM_GET_KERNEMU_DEV, @@ -1654,7 +1683,7 @@ vm_get_ioctls(size_t *len) VM_ISA_DEASSERT_IRQ, VM_ISA_PULSE_IRQ, VM_ISA_SET_IRQ_TRIGGER, VM_SET_CAPABILITY, VM_GET_CAPABILITY, VM_BIND_PPTDEV, VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_PPTDEV_MSI, - VM_PPTDEV_MSIX, VM_PPTDEV_DISABLE_MSIX, + VM_PPTDEV_MSIX, VM_UNMAP_PPTDEV_MMIO, VM_PPTDEV_DISABLE_MSIX, 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, |