aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--arch/ia64/include/asm/iommu.h2
-rw-r--r--arch/ia64/kernel/pci-dma.c1
-rw-r--r--arch/x86/include/asm/iommu.h1
-rw-r--r--arch/x86/kernel/pci-dma.c11
-rw-r--r--drivers/iommu/amd_iommu.c10
-rw-r--r--drivers/iommu/intel-iommu.c3
7 files changed, 30 insertions, 2 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a0c5c5f4fce6..e1b6e4469845 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1059,7 +1059,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1059 nomerge 1059 nomerge
1060 forcesac 1060 forcesac
1061 soft 1061 soft
1062 pt [x86, IA-64] 1062 pt [x86, IA-64]
1063 group_mf [x86, IA-64]
1064
1063 1065
1064 io7= [HW] IO7 for Marvel based alpha systems 1066 io7= [HW] IO7 for Marvel based alpha systems
1065 See comment before marvel_specify_io7 in 1067 See comment before marvel_specify_io7 in
diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h
index 105c93b00b1b..b6a809fa2995 100644
--- a/arch/ia64/include/asm/iommu.h
+++ b/arch/ia64/include/asm/iommu.h
@@ -11,10 +11,12 @@ extern void no_iommu_init(void);
11extern int force_iommu, no_iommu; 11extern int force_iommu, no_iommu;
12extern int iommu_pass_through; 12extern int iommu_pass_through;
13extern int iommu_detected; 13extern int iommu_detected;
14extern int iommu_group_mf;
14#else 15#else
15#define iommu_pass_through (0) 16#define iommu_pass_through (0)
16#define no_iommu (1) 17#define no_iommu (1)
17#define iommu_detected (0) 18#define iommu_detected (0)
19#define iommu_group_mf (0)
18#endif 20#endif
19extern void iommu_dma_init(void); 21extern void iommu_dma_init(void);
20extern void machvec_init(const char *name); 22extern void machvec_init(const char *name);
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index c16162c70860..eb1175720050 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -33,6 +33,7 @@ int force_iommu __read_mostly;
33#endif 33#endif
34 34
35int iommu_pass_through; 35int iommu_pass_through;
36int iommu_group_mf;
36 37
37/* Dummy device used for NULL arguments (normally ISA). Better would 38/* Dummy device used for NULL arguments (normally ISA). Better would
38 be probably a smaller DMA mask, but this is bug-to-bug compatible 39 be probably a smaller DMA mask, but this is bug-to-bug compatible
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index 345c99cef152..dffc38ee6255 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -5,6 +5,7 @@ extern struct dma_map_ops nommu_dma_ops;
5extern int force_iommu, no_iommu; 5extern int force_iommu, no_iommu;
6extern int iommu_detected; 6extern int iommu_detected;
7extern int iommu_pass_through; 7extern int iommu_pass_through;
8extern int iommu_group_mf;
8 9
9/* 10 seconds */ 10/* 10 seconds */
10#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) 11#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 80dc793b3f63..1c4d769e21ea 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -45,6 +45,15 @@ int iommu_detected __read_mostly = 0;
45 */ 45 */
46int iommu_pass_through __read_mostly; 46int iommu_pass_through __read_mostly;
47 47
48/*
49 * Group multi-function PCI devices into a single device-group for the
50 * iommu_device_group interface. This tells the iommu driver to pretend
51 * it cannot distinguish between functions of a device, exposing only one
52 * group for the device. Useful for disallowing use of individual PCI
53 * functions from userspace drivers.
54 */
55int iommu_group_mf __read_mostly;
56
48extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; 57extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
49 58
50/* Dummy device used for NULL arguments (normally ISA). */ 59/* Dummy device used for NULL arguments (normally ISA). */
@@ -169,6 +178,8 @@ static __init int iommu_setup(char *p)
169#endif 178#endif
170 if (!strncmp(p, "pt", 2)) 179 if (!strncmp(p, "pt", 2))
171 iommu_pass_through = 1; 180 iommu_pass_through = 1;
181 if (!strncmp(p, "group_mf", 8))
182 iommu_group_mf = 1;
172 183
173 gart_parse_options(p); 184 gart_parse_options(p);
174 185
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 1d82b631d09c..6f7553684c1e 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2776,11 +2776,19 @@ static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
2776static int amd_iommu_device_group(struct device *dev, unsigned int *groupid) 2776static int amd_iommu_device_group(struct device *dev, unsigned int *groupid)
2777{ 2777{
2778 struct iommu_dev_data *dev_data = dev->archdata.iommu; 2778 struct iommu_dev_data *dev_data = dev->archdata.iommu;
2779 struct pci_dev *pdev = to_pci_dev(dev);
2780 u16 devid;
2779 2781
2780 if (!dev_data) 2782 if (!dev_data)
2781 return -ENODEV; 2783 return -ENODEV;
2782 2784
2783 *groupid = amd_iommu_alias_table[dev_data->devid]; 2785 if (pdev->is_virtfn || !iommu_group_mf)
2786 devid = dev_data->devid;
2787 else
2788 devid = calc_devid(pdev->bus->number,
2789 PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
2790
2791 *groupid = amd_iommu_alias_table[devid];
2784 2792
2785 return 0; 2793 return 0;
2786} 2794}
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 39ca6bb17e13..9ef16d664a99 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4100,6 +4100,9 @@ static int intel_iommu_device_group(struct device *dev, unsigned int *groupid)
4100 } 4100 }
4101 } 4101 }
4102 4102
4103 if (!pdev->is_virtfn && iommu_group_mf)
4104 id.pci.devfn = PCI_DEVFN(PCI_SLOT(id.pci.devfn), 0);
4105
4103 *groupid = id.group; 4106 *groupid = id.group;
4104 4107
4105 return 0; 4108 return 0;