mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-07 00:59:06 +00:00
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>
This commit is contained in:
parent
235dacbc79
commit
440e899805
1 changed files with 62 additions and 2 deletions
|
@ -2145,8 +2145,68 @@ static int __init parse_amd_iommu_options(char *str)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init parse_ivrs_ioapic(char *str)
|
||||||
|
{
|
||||||
|
unsigned int bus, dev, fn;
|
||||||
|
int ret, id, i;
|
||||||
|
u16 devid;
|
||||||
|
|
||||||
|
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
|
||||||
|
|
||||||
|
if (ret != 4) {
|
||||||
|
pr_err("AMD-Vi: Invalid command line: ivrs_ioapic%s\n", str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (early_ioapic_map_size == EARLY_MAP_SIZE) {
|
||||||
|
pr_err("AMD-Vi: Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
|
||||||
|
str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
|
||||||
|
|
||||||
|
i = early_ioapic_map_size++;
|
||||||
|
early_ioapic_map[i].id = id;
|
||||||
|
early_ioapic_map[i].devid = devid;
|
||||||
|
early_ioapic_map[i].cmd_line = true;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init parse_ivrs_hpet(char *str)
|
||||||
|
{
|
||||||
|
unsigned int bus, dev, fn;
|
||||||
|
int ret, id, i;
|
||||||
|
u16 devid;
|
||||||
|
|
||||||
|
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
|
||||||
|
|
||||||
|
if (ret != 4) {
|
||||||
|
pr_err("AMD-Vi: Invalid command line: ivrs_hpet%s\n", str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (early_hpet_map_size == EARLY_MAP_SIZE) {
|
||||||
|
pr_err("AMD-Vi: Early HPET map overflow - ignoring ivrs_hpet%s\n",
|
||||||
|
str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
|
||||||
|
|
||||||
|
i = early_hpet_map_size++;
|
||||||
|
early_hpet_map[i].id = id;
|
||||||
|
early_hpet_map[i].devid = devid;
|
||||||
|
early_hpet_map[i].cmd_line = true;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
__setup("amd_iommu_dump", parse_amd_iommu_dump);
|
__setup("amd_iommu_dump", parse_amd_iommu_dump);
|
||||||
__setup("amd_iommu=", parse_amd_iommu_options);
|
__setup("amd_iommu=", parse_amd_iommu_options);
|
||||||
|
__setup("ivrs_ioapic", parse_ivrs_ioapic);
|
||||||
|
__setup("ivrs_hpet", parse_ivrs_hpet);
|
||||||
|
|
||||||
IOMMU_INIT_FINISH(amd_iommu_detect,
|
IOMMU_INIT_FINISH(amd_iommu_detect,
|
||||||
gart_iommu_hole_init,
|
gart_iommu_hole_init,
|
||||||
|
|
Loading…
Reference in a new issue