Re-write bhyve's I/O MMU handling in terms of PCI RIDs
Reviewed by: neel Sponsored by: Sandvine Inc
This commit is contained in:
parent
eabfe8df7a
commit
4df7085933
@ -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, int bus, int slot, int func)
|
||||
amd_iommu_add_device(void *domain, uint16_t rid)
|
||||
{
|
||||
|
||||
printf("amd_iommu_add_device: not implemented\n");
|
||||
}
|
||||
|
||||
static void
|
||||
amd_iommu_remove_device(void *domain, int bus, int slot, int func)
|
||||
amd_iommu_remove_device(void *domain, uint16_t rid)
|
||||
{
|
||||
|
||||
printf("amd_iommu_remove_device: not implemented\n");
|
||||
|
@ -99,6 +99,8 @@ 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 */
|
||||
@ -360,27 +362,24 @@ vtd_disable(void)
|
||||
}
|
||||
|
||||
static void
|
||||
vtd_add_device(void *arg, int bus, int slot, int func)
|
||||
vtd_add_device(void *arg, uint16_t rid)
|
||||
{
|
||||
int idx;
|
||||
uint64_t *ctxp;
|
||||
struct domain *dom = arg;
|
||||
vm_paddr_t pt_paddr;
|
||||
struct vtdmap *vtdmap;
|
||||
|
||||
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);
|
||||
uint8_t bus;
|
||||
|
||||
vtdmap = vtdmaps[0];
|
||||
bus = PCI_RID2BUS(rid);
|
||||
ctxp = ctx_tables[bus];
|
||||
pt_paddr = vtophys(dom->ptp);
|
||||
idx = (slot << 3 | func) * 2;
|
||||
idx = VTD_RID2IDX(rid);
|
||||
|
||||
if (ctxp[idx] & VTD_CTX_PRESENT) {
|
||||
panic("vtd_add_device: device %d/%d/%d is already owned by "
|
||||
"domain %d", bus, slot, func,
|
||||
panic("vtd_add_device: device %x is already owned by "
|
||||
"domain %d", rid,
|
||||
(uint16_t)(ctxp[idx + 1] >> 8));
|
||||
}
|
||||
|
||||
@ -404,19 +403,16 @@ vtd_add_device(void *arg, int bus, int slot, int func)
|
||||
}
|
||||
|
||||
static void
|
||||
vtd_remove_device(void *arg, int bus, int slot, int func)
|
||||
vtd_remove_device(void *arg, uint16_t rid)
|
||||
{
|
||||
int i, idx;
|
||||
uint64_t *ctxp;
|
||||
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);
|
||||
|
||||
bus = PCI_RID2BUS(rid);
|
||||
ctxp = ctx_tables[bus];
|
||||
idx = (slot << 3 | func) * 2;
|
||||
idx = VTD_RID2IDX(rid);
|
||||
|
||||
/*
|
||||
* Order is important. The 'present' bit is must be cleared first.
|
||||
|
@ -109,19 +109,19 @@ IOMMU_REMOVE_MAPPING(void *domain, vm_paddr_t gpa, uint64_t len)
|
||||
}
|
||||
|
||||
static __inline void
|
||||
IOMMU_ADD_DEVICE(void *domain, int bus, int slot, int func)
|
||||
IOMMU_ADD_DEVICE(void *domain, uint16_t rid)
|
||||
{
|
||||
|
||||
if (ops != NULL && iommu_avail)
|
||||
(*ops->add_device)(domain, bus, slot, func);
|
||||
(*ops->add_device)(domain, rid);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
IOMMU_REMOVE_DEVICE(void *domain, int bus, int slot, int func)
|
||||
IOMMU_REMOVE_DEVICE(void *domain, uint16_t rid)
|
||||
{
|
||||
|
||||
if (ops != NULL && iommu_avail)
|
||||
(*ops->remove_device)(domain, bus, slot, func);
|
||||
(*ops->remove_device)(domain, rid);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
@ -196,7 +196,8 @@ iommu_init(void)
|
||||
continue;
|
||||
|
||||
/* everything else belongs to the host domain */
|
||||
iommu_add_device(host_domain, bus, slot, func);
|
||||
iommu_add_device(host_domain,
|
||||
pci_get_rid(dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,17 +264,17 @@ iommu_host_domain(void)
|
||||
}
|
||||
|
||||
void
|
||||
iommu_add_device(void *dom, int bus, int slot, int func)
|
||||
iommu_add_device(void *dom, uint16_t rid)
|
||||
{
|
||||
|
||||
IOMMU_ADD_DEVICE(dom, bus, slot, func);
|
||||
IOMMU_ADD_DEVICE(dom, rid);
|
||||
}
|
||||
|
||||
void
|
||||
iommu_remove_device(void *dom, int bus, int slot, int func)
|
||||
iommu_remove_device(void *dom, uint16_t rid)
|
||||
{
|
||||
|
||||
IOMMU_REMOVE_DEVICE(dom, bus, slot, func);
|
||||
IOMMU_REMOVE_DEVICE(dom, rid);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -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, int bus, int slot, int func);
|
||||
typedef void (*iommu_remove_device_t)(void *dom, int bus, int slot, int func);
|
||||
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_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, int bus, int slot, int func);
|
||||
void iommu_remove_device(void *dom, int bus, int slot, int func);
|
||||
void iommu_add_device(void *dom, uint16_t rid);
|
||||
void iommu_remove_device(void *dom, uint16_t rid);
|
||||
void iommu_invalidate_tlb(void *domain);
|
||||
#endif
|
||||
|
@ -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), bus, slot, func);
|
||||
iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
|
||||
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), bus, slot, func);
|
||||
iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
|
||||
ppt->vm = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user