diff options
author | Joerg Roedel <jroedel@suse.de> | 2014-09-09 15:59:37 +0200 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-09-25 19:24:52 +0200 |
commit | c50e3247aa2d825e0dc0f4b876ee22d7134d24ca (patch) | |
tree | 3a04c34b5c0e8a1664108d380208082fba0bfd0a /drivers/iommu | |
parent | amd_iommu: do not dereference a NULL pointer address. (diff) | |
download | linux-c50e3247aa2d825e0dc0f4b876ee22d7134d24ca.tar.xz linux-c50e3247aa2d825e0dc0f4b876ee22d7134d24ca.zip |
iommu/amd: Fix devid mapping for ivrs_ioapic override
When the device id for an IOAPIC is overridden on the kernel
command line, the iommu driver has to make sure it sets up a
DTE for this device id.
Reported-by: Su Friendy <friendy.su@sony.com.cn>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 3783e0b44df6..b0522f15730f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -712,7 +712,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu, set_iommu_for_device(iommu, devid); } -static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) +static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line) { struct devid_map *entry; struct list_head *list; @@ -731,6 +731,8 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) pr_info("AMD-Vi: Command-line override present for %s id %d - ignoring\n", type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id); + *devid = entry->devid; + return 0; } @@ -739,7 +741,7 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) return -ENOMEM; entry->id = id; - entry->devid = devid; + entry->devid = *devid; entry->cmd_line = cmd_line; list_add_tail(&entry->list, list); @@ -754,7 +756,7 @@ static int __init add_early_maps(void) for (i = 0; i < early_ioapic_map_size; ++i) { ret = add_special_device(IVHD_SPECIAL_IOAPIC, early_ioapic_map[i].id, - early_ioapic_map[i].devid, + &early_ioapic_map[i].devid, early_ioapic_map[i].cmd_line); if (ret) return ret; @@ -763,7 +765,7 @@ static int __init add_early_maps(void) for (i = 0; i < early_hpet_map_size; ++i) { ret = add_special_device(IVHD_SPECIAL_HPET, early_hpet_map[i].id, - early_hpet_map[i].devid, + &early_hpet_map[i].devid, early_hpet_map[i].cmd_line); if (ret) return ret; @@ -978,10 +980,17 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, PCI_SLOT(devid), PCI_FUNC(devid)); - set_dev_entry_from_acpi(iommu, devid, e->flags, 0); - ret = add_special_device(type, handle, devid, false); + ret = add_special_device(type, handle, &devid, false); if (ret) return ret; + + /* + * add_special_device might update the devid in case a + * command-line override is present. So call + * set_dev_entry_from_acpi after add_special_device. + */ + set_dev_entry_from_acpi(iommu, devid, e->flags, 0); + break; } default: |