diff options
Diffstat (limited to 'sys/amd64/vmm/io/ppt.c')
-rw-r--r-- | sys/amd64/vmm/io/ppt.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c index 6bcd8f78bbab..3451e91d9de1 100644 --- a/sys/amd64/vmm/io/ppt.c +++ b/sys/amd64/vmm/io/ppt.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2011 NetApp, Inc. * All rights reserved. @@ -24,13 +24,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -182,7 +177,9 @@ ppt_detach(device_t dev) num_pptdevs--; TAILQ_REMOVE(&pptdev_list, ppt, next); pci_disable_busmaster(dev); - iommu_add_device(iommu_host_domain(), pci_get_rid(dev)); + + if (iommu_host_domain() != NULL) + iommu_add_device(iommu_host_domain(), pci_get_rid(dev)); return (0); } @@ -439,6 +436,23 @@ ppt_unassign_all(struct vm *vm) return (0); } +static bool +ppt_valid_bar_mapping(struct pptdev *ppt, vm_paddr_t hpa, size_t len) +{ + struct pci_map *pm; + pci_addr_t base, size; + + for (pm = pci_first_bar(ppt->dev); pm != NULL; pm = pci_next_bar(pm)) { + if (!PCI_BAR_MEM(pm->pm_value)) + continue; + base = pm->pm_value & PCIM_BAR_MEM_BASE; + size = (pci_addr_t)1 << pm->pm_size; + if (hpa >= base && hpa + len <= base + size) + return (true); + } + return (false); +} + int ppt_map_mmio(struct vm *vm, int bus, int slot, int func, vm_paddr_t gpa, size_t len, vm_paddr_t hpa) @@ -447,10 +461,17 @@ ppt_map_mmio(struct vm *vm, int bus, int slot, int func, struct pptseg *seg; struct pptdev *ppt; + if (len % PAGE_SIZE != 0 || len == 0 || gpa % PAGE_SIZE != 0 || + hpa % PAGE_SIZE != 0 || gpa + len < gpa || hpa + len < hpa) + return (EINVAL); + error = ppt_find(vm, bus, slot, func, &ppt); if (error) return (error); + if (!ppt_valid_bar_mapping(ppt, hpa, len)) + return (EINVAL); + for (i = 0; i < MAX_MMIOSEGS; i++) { seg = &ppt->mmio[i]; if (seg->len == 0) { @@ -520,7 +541,7 @@ pptintr(void *arg) } int -ppt_setup_msi(struct vm *vm, int vcpu, int bus, int slot, int func, +ppt_setup_msi(struct vm *vm, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { int i, rid, flags; @@ -613,7 +634,7 @@ ppt_setup_msi(struct vm *vm, int vcpu, int bus, int slot, int func, } int -ppt_setup_msix(struct vm *vm, int vcpu, int bus, int slot, int func, +ppt_setup_msix(struct vm *vm, int bus, int slot, int func, int idx, uint64_t addr, uint64_t msg, uint32_t vector_control) { struct pptdev *ppt; |