debuggers.hg
changeset 18064:27aaff984b36
vt-d: Fixup when mapping devices on non-PCIe buses
The source-id for transactions on non-PCIe buses seem to originate
from devfn=0 on the secondary bus behind the bridge. Map that ID as
well when assigning the device. The ID to use in these scenarios is
not particularly well documented anywhere.
Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
The source-id for transactions on non-PCIe buses seem to originate
from devfn=0 on the secondary bus behind the bridge. Map that ID as
well when assigning the device. The ID to use in these scenarios is
not particularly well documented anywhere.
Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Thu Jul 10 17:33:23 2008 +0100 (2008-07-10) |
parents | 07c7aef164cf |
children | b41e07aa555a |
files | xen/drivers/passthrough/vtd/iommu.c |
line diff
1.1 --- a/xen/drivers/passthrough/vtd/iommu.c Thu Jul 10 17:29:06 2008 +0100 1.2 +++ b/xen/drivers/passthrough/vtd/iommu.c Thu Jul 10 17:33:23 2008 +0100 1.3 @@ -1186,9 +1186,10 @@ int pdev_type(u8 bus, u8 devfn) 1.4 #define MAX_BUSES 256 1.5 static struct { u8 map, bus, devfn; } bus2bridge[MAX_BUSES]; 1.6 1.7 -static int find_pcie_endpoint(u8 *bus, u8 *devfn) 1.8 +static int find_pcie_endpoint(u8 *bus, u8 *devfn, u8 *secbus) 1.9 { 1.10 int cnt = 0; 1.11 + *secbus = *bus; 1.12 1.13 if ( *bus == 0 ) 1.14 /* assume integrated PCI devices in RC have valid requester-id */ 1.15 @@ -1199,6 +1200,7 @@ static int find_pcie_endpoint(u8 *bus, u 1.16 1.17 while ( bus2bridge[*bus].map ) 1.18 { 1.19 + *secbus = *bus; 1.20 *devfn = bus2bridge[*bus].devfn; 1.21 *bus = bus2bridge[*bus].bus; 1.22 if ( cnt++ >= MAX_BUSES ) 1.23 @@ -1214,6 +1216,7 @@ static int domain_context_mapping(struct 1.24 int ret = 0; 1.25 u16 sec_bus, sub_bus, ob, odf; 1.26 u32 type; 1.27 + u8 secbus; 1.28 1.29 drhd = acpi_find_matched_drhd_unit(bus, devfn); 1.30 if ( !drhd ) 1.31 @@ -1254,7 +1257,7 @@ static int domain_context_mapping(struct 1.32 bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); 1.33 1.34 ob = bus; odf = devfn; 1.35 - if ( !find_pcie_endpoint(&bus, &devfn) ) 1.36 + if ( !find_pcie_endpoint(&bus, &devfn, &secbus) ) 1.37 { 1.38 gdprintk(XENLOG_WARNING VTDPREFIX, "domain_context_mapping:invalid"); 1.39 break; 1.40 @@ -1265,7 +1268,17 @@ static int domain_context_mapping(struct 1.41 "domain_context_mapping:map: bdf = %x:%x.%x -> %x:%x.%x\n", 1.42 ob, PCI_SLOT(odf), PCI_FUNC(odf), 1.43 bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); 1.44 + 1.45 ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn); 1.46 + if ( secbus != bus ) 1.47 + /* 1.48 + * The source-id for transactions on non-PCIe buses seem 1.49 + * to originate from devfn=0 on the secondary bus behind 1.50 + * the bridge. Map that id as well. The id to use in 1.51 + * these scanarios is not particularly well documented 1.52 + * anywhere. 1.53 + */ 1.54 + domain_context_mapping_one(domain, drhd->iommu, secbus, 0); 1.55 break; 1.56 1.57 default: 1.58 @@ -1313,6 +1326,7 @@ static int domain_context_unmap(u8 bus, 1.59 u16 sec_bus, sub_bus; 1.60 int ret = 0; 1.61 u32 type; 1.62 + u8 secbus; 1.63 1.64 drhd = acpi_find_matched_drhd_unit(bus, devfn); 1.65 if ( !drhd ) 1.66 @@ -1337,8 +1351,10 @@ static int domain_context_unmap(u8 bus, 1.67 break; 1.68 1.69 case DEV_TYPE_PCI: 1.70 - if ( find_pcie_endpoint(&bus, &devfn) ) 1.71 + if ( find_pcie_endpoint(&bus, &devfn, &secbus) ) 1.72 ret = domain_context_unmap_one(drhd->iommu, bus, devfn); 1.73 + if ( bus != secbus ) 1.74 + domain_context_unmap_one(drhd->iommu, secbus, 0); 1.75 break; 1.76 1.77 default: 1.78 @@ -1776,7 +1792,8 @@ int intel_iommu_assign_device(struct dom 1.79 1.80 static int intel_iommu_group_id(u8 bus, u8 devfn) 1.81 { 1.82 - if ( !bus2bridge[bus].map || find_pcie_endpoint(&bus, &devfn) ) 1.83 + u8 secbus; 1.84 + if ( !bus2bridge[bus].map || find_pcie_endpoint(&bus, &devfn, &secbus) ) 1.85 return PCI_BDF2(bus, devfn); 1.86 else 1.87 return -1;