IOMMU: add option to specify devices behaving like ones using phantom functions

At least certain Marvell SATA controllers are known to issue bus master
requests with a non-zero function as origin, despite themselves being
single function devices.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: "Zhang, Xiantao" <xiantao.zhang@intel.com>
This commit is contained in:
Jan Beulich committed 2013-01-07 12:58:09 +01:00
1 parent c9af51eb96
commit 4e3c592c93
2 files changed
+67

No files matched your search

+10
View File
@@ -703,6 +703,16 @@ Defaults to booting secondary processors.
Default: `on`
### pci-phantom
> `=[<seg>:]<bus>:<device>,<stride>`
Mark a group of PCI devices as using phantom functions without actually
advertising so, so the IOMMU can create translation contexts for them.
All numbers specified must be hexadecimal ones.
This option can be specified more than once (up to 8 times at present).
### ple\_gap
> `= <integer>`
+57
View File
@@ -121,6 +121,49 @@ const unsigned long *pci_get_ro_map(u16 seg)
return pseg ? pseg->ro_map : NULL;
}
static struct phantom_dev {
u16 seg;
u8 bus, slot, stride;
} phantom_devs[8];
static unsigned int nr_phantom_devs;
static void __init parse_phantom_dev(char *str) {
const char *s = str;
struct phantom_dev phantom;
if ( !s || !*s || nr_phantom_devs >= ARRAY_SIZE(phantom_devs) )
return;
phantom.seg = simple_strtol(s, &s, 16);
if ( *s != ':' )
return;
phantom.bus = simple_strtol(s + 1, &s, 16);
if ( *s == ',' )
{
phantom.slot = phantom.bus;
phantom.bus = phantom.seg;
phantom.seg = 0;
}
else if ( *s == ':' )
phantom.slot = simple_strtol(s + 1, &s, 16);
else
return;
if ( *s != ',' )
return;
switch ( phantom.stride = simple_strtol(s + 1, &s, 0) )
{
case 1: case 2: case 4:
if ( *s )
default:
return;
}
phantom_devs[nr_phantom_devs++] = phantom;
}
custom_param("pci-phantom", parse_phantom_dev);
static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
{
struct pci_dev *pdev;
@@ -181,6 +224,20 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
if ( PCI_FUNC(devfn) >= pdev->phantom_stride )
pdev->phantom_stride = 0;
}
else
{
unsigned int i;
for ( i = 0; i < nr_phantom_devs; ++i )
if ( phantom_devs[i].seg == pseg->nr &&
phantom_devs[i].bus == bus &&
phantom_devs[i].slot == PCI_SLOT(devfn) &&
phantom_devs[i].stride > PCI_FUNC(devfn) )
{
pdev->phantom_stride = phantom_devs[i].stride;
break;
}
}
break;
case DEV_TYPE_PCI:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.