aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2014-09-09 09:59:37 -0400
committerJoerg Roedel <jroedel@suse.de>2014-09-25 13:24:52 -0400
commitc50e3247aa2d825e0dc0f4b876ee22d7134d24ca (patch)
tree3a04c34b5c0e8a1664108d380208082fba0bfd0a
parent63eaa75e4362ac7981a7e619196a9c75fd03d717 (diff)
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>
-rw-r--r--drivers/iommu/amd_iommu_init.c21
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,
712 set_iommu_for_device(iommu, devid); 712 set_iommu_for_device(iommu, devid);
713} 713}
714 714
715static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) 715static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
716{ 716{
717 struct devid_map *entry; 717 struct devid_map *entry;
718 struct list_head *list; 718 struct list_head *list;
@@ -731,6 +731,8 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line)
731 pr_info("AMD-Vi: Command-line override present for %s id %d - ignoring\n", 731 pr_info("AMD-Vi: Command-line override present for %s id %d - ignoring\n",
732 type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id); 732 type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id);
733 733
734 *devid = entry->devid;
735
734 return 0; 736 return 0;
735 } 737 }
736 738
@@ -739,7 +741,7 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line)
739 return -ENOMEM; 741 return -ENOMEM;
740 742
741 entry->id = id; 743 entry->id = id;
742 entry->devid = devid; 744 entry->devid = *devid;
743 entry->cmd_line = cmd_line; 745 entry->cmd_line = cmd_line;
744 746
745 list_add_tail(&entry->list, list); 747 list_add_tail(&entry->list, list);
@@ -754,7 +756,7 @@ static int __init add_early_maps(void)
754 for (i = 0; i < early_ioapic_map_size; ++i) { 756 for (i = 0; i < early_ioapic_map_size; ++i) {
755 ret = add_special_device(IVHD_SPECIAL_IOAPIC, 757 ret = add_special_device(IVHD_SPECIAL_IOAPIC,
756 early_ioapic_map[i].id, 758 early_ioapic_map[i].id,
757 early_ioapic_map[i].devid, 759 &early_ioapic_map[i].devid,
758 early_ioapic_map[i].cmd_line); 760 early_ioapic_map[i].cmd_line);
759 if (ret) 761 if (ret)
760 return ret; 762 return ret;
@@ -763,7 +765,7 @@ static int __init add_early_maps(void)
763 for (i = 0; i < early_hpet_map_size; ++i) { 765 for (i = 0; i < early_hpet_map_size; ++i) {
764 ret = add_special_device(IVHD_SPECIAL_HPET, 766 ret = add_special_device(IVHD_SPECIAL_HPET,
765 early_hpet_map[i].id, 767 early_hpet_map[i].id,
766 early_hpet_map[i].devid, 768 &early_hpet_map[i].devid,
767 early_hpet_map[i].cmd_line); 769 early_hpet_map[i].cmd_line);
768 if (ret) 770 if (ret)
769 return ret; 771 return ret;
@@ -978,10 +980,17 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
978 PCI_SLOT(devid), 980 PCI_SLOT(devid),
979 PCI_FUNC(devid)); 981 PCI_FUNC(devid));
980 982
981 set_dev_entry_from_acpi(iommu, devid, e->flags, 0); 983 ret = add_special_device(type, handle, &devid, false);
982 ret = add_special_device(type, handle, devid, false);
983 if (ret) 984 if (ret)
984 return ret; 985 return ret;
986
987 /*
988 * add_special_device might update the devid in case a
989 * command-line override is present. So call
990 * set_dev_entry_from_acpi after add_special_device.
991 */
992 set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
993
985 break; 994 break;
986 } 995 }
987 default: 996 default: