aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorJoerg Roedel <joro@8bytes.org>2013-04-09 10:35:28 -0400
committerJoerg Roedel <joro@8bytes.org>2013-04-19 14:52:17 -0400
commit440e899805411d827d4fcce9eb37bf2417c812db (patch)
tree0316e0431180fd838a4ad02b22873a1ca2c0c452 /drivers/iommu
parent235dacbc795bb7ccf69db8ad9ff1587314cf857d (diff)
iommu/amd: Add ioapic and hpet ivrs override
Add two new kernel commandline parameters ivrs_ioapic and ivrs_hpet to override the Id->DeviceId mapping from the IVRS ACPI table. This can be used to work around broken BIOSes to get interrupt remapping working on AMD systems. Tested-by: Borislav Petkov <bp@suse.de> Tested-by: Suravee Suthikulanit <suravee.suthikulpanit@amd.com> Reviewed-by: Shuah Khan <shuahkhan@gmail.com> Signed-off-by: Joerg Roedel <joro@8bytes.org>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/amd_iommu_init.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 2a3b1b174d5e..030d6abf31e7 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2145,8 +2145,68 @@ static int __init parse_amd_iommu_options(char *str)
2145 return 1; 2145 return 1;
2146} 2146}
2147 2147
2148__setup("amd_iommu_dump", parse_amd_iommu_dump); 2148static int __init parse_ivrs_ioapic(char *str)
2149__setup("amd_iommu=", parse_amd_iommu_options); 2149{
2150 unsigned int bus, dev, fn;
2151 int ret, id, i;
2152 u16 devid;
2153
2154 ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
2155
2156 if (ret != 4) {
2157 pr_err("AMD-Vi: Invalid command line: ivrs_ioapic%s\n", str);
2158 return 1;
2159 }
2160
2161 if (early_ioapic_map_size == EARLY_MAP_SIZE) {
2162 pr_err("AMD-Vi: Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
2163 str);
2164 return 1;
2165 }
2166
2167 devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
2168
2169 i = early_ioapic_map_size++;
2170 early_ioapic_map[i].id = id;
2171 early_ioapic_map[i].devid = devid;
2172 early_ioapic_map[i].cmd_line = true;
2173
2174 return 1;
2175}
2176
2177static int __init parse_ivrs_hpet(char *str)
2178{
2179 unsigned int bus, dev, fn;
2180 int ret, id, i;
2181 u16 devid;
2182
2183 ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
2184
2185 if (ret != 4) {
2186 pr_err("AMD-Vi: Invalid command line: ivrs_hpet%s\n", str);
2187 return 1;
2188 }
2189
2190 if (early_hpet_map_size == EARLY_MAP_SIZE) {
2191 pr_err("AMD-Vi: Early HPET map overflow - ignoring ivrs_hpet%s\n",
2192 str);
2193 return 1;
2194 }
2195
2196 devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
2197
2198 i = early_hpet_map_size++;
2199 early_hpet_map[i].id = id;
2200 early_hpet_map[i].devid = devid;
2201 early_hpet_map[i].cmd_line = true;
2202
2203 return 1;
2204}
2205
2206__setup("amd_iommu_dump", parse_amd_iommu_dump);
2207__setup("amd_iommu=", parse_amd_iommu_options);
2208__setup("ivrs_ioapic", parse_ivrs_ioapic);
2209__setup("ivrs_hpet", parse_ivrs_hpet);
2150 2210
2151IOMMU_INIT_FINISH(amd_iommu_detect, 2211IOMMU_INIT_FINISH(amd_iommu_detect,
2152 gart_iommu_hole_init, 2212 gart_iommu_hole_init,