Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 Apr 2014 14:54:44 +0000 (UTC)
From:      Ryan Stone <rstone@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r264003 - in head/sys/amd64/vmm: amd intel io
Message-ID:  <201404011454.s31EsiA0027723@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rstone
Date: Tue Apr  1 14:54:43 2014
New Revision: 264003
URL: http://svnweb.freebsd.org/changeset/base/264003

Log:
  Re-write bhyve's I/O MMU handling in terms of PCI RIDs
  
  Reviewed by:	neel
  Sponsored by:	Sandvine Inc

Modified:
  head/sys/amd64/vmm/amd/amdv.c
  head/sys/amd64/vmm/intel/vtd.c
  head/sys/amd64/vmm/io/iommu.c
  head/sys/amd64/vmm/io/iommu.h
  head/sys/amd64/vmm/io/ppt.c

Modified: head/sys/amd64/vmm/amd/amdv.c
==============================================================================
--- head/sys/amd64/vmm/amd/amdv.c	Tue Apr  1 14:51:45 2014	(r264002)
+++ head/sys/amd64/vmm/amd/amdv.c	Tue Apr  1 14:54:43 2014	(r264003)
@@ -242,14 +242,14 @@ amd_iommu_remove_mapping(void *domain, v
 }
 
 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");

Modified: head/sys/amd64/vmm/intel/vtd.c
==============================================================================
--- head/sys/amd64/vmm/intel/vtd.c	Tue Apr  1 14:51:45 2014	(r264002)
+++ head/sys/amd64/vmm/intel/vtd.c	Tue Apr  1 14:54:43 2014	(r264003)
@@ -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 s
 }
 
 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.

Modified: head/sys/amd64/vmm/io/iommu.c
==============================================================================
--- head/sys/amd64/vmm/io/iommu.c	Tue Apr  1 14:51:45 2014	(r264002)
+++ head/sys/amd64/vmm/io/iommu.c	Tue Apr  1 14:54:43 2014	(r264003)
@@ -109,19 +109,19 @@ IOMMU_REMOVE_MAPPING(void *domain, vm_pa
 }
 
 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

Modified: head/sys/amd64/vmm/io/iommu.h
==============================================================================
--- head/sys/amd64/vmm/io/iommu.h	Tue Apr  1 14:51:45 2014	(r264002)
+++ head/sys/amd64/vmm/io/iommu.h	Tue Apr  1 14:54:43 2014	(r264003)
@@ -39,8 +39,8 @@ typedef uint64_t (*iommu_create_mapping_
 					   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

Modified: head/sys/amd64/vmm/io/ppt.c
==============================================================================
--- head/sys/amd64/vmm/io/ppt.c	Tue Apr  1 14:51:45 2014	(r264002)
+++ head/sys/amd64/vmm/io/ppt.c	Tue Apr  1 14:54:43 2014	(r264003)
@@ -346,7 +346,7 @@ ppt_assign_device(struct vm *vm, int bus
 			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 b
 		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);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404011454.s31EsiA0027723>