diff options
author | Joerg Roedel <jroedel@suse.de> | 2014-09-09 09:59:37 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-09-25 13:24:52 -0400 |
commit | c50e3247aa2d825e0dc0f4b876ee22d7134d24ca (patch) | |
tree | 3a04c34b5c0e8a1664108d380208082fba0bfd0a | |
parent | 63eaa75e4362ac7981a7e619196a9c75fd03d717 (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.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, | |||
712 | set_iommu_for_device(iommu, devid); | 712 | set_iommu_for_device(iommu, devid); |
713 | } | 713 | } |
714 | 714 | ||
715 | static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) | 715 | static 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: |