diff options
author | Ryan Stone <rstone@FreeBSD.org> | 2014-04-01 15:06:03 +0000 |
---|---|---|
committer | Ryan Stone <rstone@FreeBSD.org> | 2014-04-01 15:06:03 +0000 |
commit | 7036ae46bf60ad64447bc9ab2152256b89dd5e5f (patch) | |
tree | d8994b013bba28481c3b3634fb67dc485b753a1d /sys/amd64/vmm | |
parent | 956ed3830cdee3fe93fa64bb1175cf918327fbb3 (diff) | |
download | src-7036ae46bf60ad64447bc9ab2152256b89dd5e5f.tar.gz src-7036ae46bf60ad64447bc9ab2152256b89dd5e5f.zip |
Notes
Diffstat (limited to 'sys/amd64/vmm')
-rw-r--r-- | sys/amd64/vmm/amd/amdv.c | 4 | ||||
-rw-r--r-- | sys/amd64/vmm/intel/vtd.c | 28 | ||||
-rw-r--r-- | sys/amd64/vmm/io/iommu.c | 19 | ||||
-rw-r--r-- | sys/amd64/vmm/io/iommu.h | 8 | ||||
-rw-r--r-- | sys/amd64/vmm/io/ppt.c | 4 |
5 files changed, 33 insertions, 30 deletions
diff --git a/sys/amd64/vmm/amd/amdv.c b/sys/amd64/vmm/amd/amdv.c index ca639df26f1c..4c88d12bee54 100644 --- a/sys/amd64/vmm/amd/amdv.c +++ b/sys/amd64/vmm/amd/amdv.c @@ -242,14 +242,14 @@ amd_iommu_remove_mapping(void *domain, vm_paddr_t gpa, uint64_t len) } static void -amd_iommu_add_device(void *domain, uint16_t rid) +amd_iommu_add_device(void *domain, int bus, int slot, int func) { printf("amd_iommu_add_device: not implemented\n"); } static void -amd_iommu_remove_device(void *domain, uint16_t rid) +amd_iommu_remove_device(void *domain, int bus, int slot, int func) { printf("amd_iommu_remove_device: not implemented\n"); diff --git a/sys/amd64/vmm/intel/vtd.c b/sys/amd64/vmm/intel/vtd.c index afd715504ca3..ca76ea82ce65 100644 --- a/sys/amd64/vmm/intel/vtd.c +++ b/sys/amd64/vmm/intel/vtd.c @@ -99,8 +99,6 @@ struct vtdmap { #define VTD_PTE_SUPERPAGE (1UL << 7) #define VTD_PTE_ADDR_M (0x000FFFFFFFFFF000UL) -#define VTD_RID2IDX(rid) (((rid) & 0xff) * 2) - struct domain { uint64_t *ptp; /* first level page table page */ int pt_levels; /* number of page table levels */ @@ -362,24 +360,27 @@ vtd_disable(void) } static void -vtd_add_device(void *arg, uint16_t rid) +vtd_add_device(void *arg, int bus, int slot, int func) { int idx; uint64_t *ctxp; struct domain *dom = arg; vm_paddr_t pt_paddr; struct vtdmap *vtdmap; - uint8_t bus; + + if (bus < 0 || bus > PCI_BUSMAX || + slot < 0 || slot > PCI_SLOTMAX || + func < 0 || func > PCI_FUNCMAX) + panic("vtd_add_device: invalid bsf %d/%d/%d", bus, slot, func); vtdmap = vtdmaps[0]; - bus = PCI_RID2BUS(rid); ctxp = ctx_tables[bus]; pt_paddr = vtophys(dom->ptp); - idx = VTD_RID2IDX(rid); + idx = (slot << 3 | func) * 2; if (ctxp[idx] & VTD_CTX_PRESENT) { - panic("vtd_add_device: device %x is already owned by " - "domain %d", rid, + panic("vtd_add_device: device %d/%d/%d is already owned by " + "domain %d", bus, slot, func, (uint16_t)(ctxp[idx + 1] >> 8)); } @@ -403,16 +404,19 @@ vtd_add_device(void *arg, uint16_t rid) } static void -vtd_remove_device(void *arg, uint16_t rid) +vtd_remove_device(void *arg, int bus, int slot, int func) { int i, idx; uint64_t *ctxp; struct vtdmap *vtdmap; - uint8_t bus; - bus = PCI_RID2BUS(rid); + if (bus < 0 || bus > PCI_BUSMAX || + slot < 0 || slot > PCI_SLOTMAX || + func < 0 || func > PCI_FUNCMAX) + panic("vtd_add_device: invalid bsf %d/%d/%d", bus, slot, func); + ctxp = ctx_tables[bus]; - idx = VTD_RID2IDX(rid); + idx = (slot << 3 | func) * 2; /* * Order is important. The 'present' bit is must be cleared first. diff --git a/sys/amd64/vmm/io/iommu.c b/sys/amd64/vmm/io/iommu.c index 9cfc4c2d0150..c4912324c492 100644 --- a/sys/amd64/vmm/io/iommu.c +++ b/sys/amd64/vmm/io/iommu.c @@ -109,19 +109,19 @@ IOMMU_REMOVE_MAPPING(void *domain, vm_paddr_t gpa, uint64_t len) } static __inline void -IOMMU_ADD_DEVICE(void *domain, uint16_t rid) +IOMMU_ADD_DEVICE(void *domain, int bus, int slot, int func) { if (ops != NULL && iommu_avail) - (*ops->add_device)(domain, rid); + (*ops->add_device)(domain, bus, slot, func); } static __inline void -IOMMU_REMOVE_DEVICE(void *domain, uint16_t rid) +IOMMU_REMOVE_DEVICE(void *domain, int bus, int slot, int func) { if (ops != NULL && iommu_avail) - (*ops->remove_device)(domain, rid); + (*ops->remove_device)(domain, bus, slot, func); } static __inline void @@ -196,8 +196,7 @@ iommu_init(void) continue; /* everything else belongs to the host domain */ - iommu_add_device(host_domain, - pci_get_rid(dev)); + iommu_add_device(host_domain, bus, slot, func); } } } @@ -264,17 +263,17 @@ iommu_host_domain(void) } void -iommu_add_device(void *dom, uint16_t rid) +iommu_add_device(void *dom, int bus, int slot, int func) { - IOMMU_ADD_DEVICE(dom, rid); + IOMMU_ADD_DEVICE(dom, bus, slot, func); } void -iommu_remove_device(void *dom, uint16_t rid) +iommu_remove_device(void *dom, int bus, int slot, int func) { - IOMMU_REMOVE_DEVICE(dom, rid); + IOMMU_REMOVE_DEVICE(dom, bus, slot, func); } void diff --git a/sys/amd64/vmm/io/iommu.h b/sys/amd64/vmm/io/iommu.h index 36b44faf135d..d5c1d6ecfa53 100644 --- a/sys/amd64/vmm/io/iommu.h +++ b/sys/amd64/vmm/io/iommu.h @@ -39,8 +39,8 @@ typedef uint64_t (*iommu_create_mapping_t)(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len); typedef uint64_t (*iommu_remove_mapping_t)(void *domain, vm_paddr_t gpa, uint64_t len); -typedef void (*iommu_add_device_t)(void *domain, uint16_t rid); -typedef void (*iommu_remove_device_t)(void *dom, uint16_t rid); +typedef void (*iommu_add_device_t)(void *domain, int bus, int slot, int func); +typedef void (*iommu_remove_device_t)(void *dom, int bus, int slot, int func); typedef void (*iommu_invalidate_tlb_t)(void *dom); struct iommu_ops { @@ -69,7 +69,7 @@ void iommu_destroy_domain(void *dom); void iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, size_t len); void iommu_remove_mapping(void *dom, vm_paddr_t gpa, size_t len); -void iommu_add_device(void *dom, uint16_t rid); -void iommu_remove_device(void *dom, uint16_t rid); +void iommu_add_device(void *dom, int bus, int slot, int func); +void iommu_remove_device(void *dom, int bus, int slot, int func); void iommu_invalidate_tlb(void *domain); #endif diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c index fa7083e2dd69..a7ea091a1ccf 100644 --- a/sys/amd64/vmm/io/ppt.c +++ b/sys/amd64/vmm/io/ppt.c @@ -346,7 +346,7 @@ ppt_assign_device(struct vm *vm, int bus, int slot, int func) return (EBUSY); ppt->vm = vm; - iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev)); + iommu_add_device(vm_iommu_domain(vm), bus, slot, func); return (0); } return (ENOENT); @@ -367,7 +367,7 @@ ppt_unassign_device(struct vm *vm, int bus, int slot, int func) ppt_unmap_mmio(vm, ppt); ppt_teardown_msi(ppt); ppt_teardown_msix(ppt); - iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev)); + iommu_remove_device(vm_iommu_domain(vm), bus, slot, func); ppt->vm = NULL; return (0); } |