Commit a45627ba authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Joerg Roedel
Browse files

iommu/amd: Include PCI segment ID when initialize IOMMU



Extend current device ID variables to 32-bit to include the 16-bit
segment ID when parsing device information from IVRS table to initialize
each IOMMU.

Co-developed-by: default avatarVasant Hegde <vasant.hegde@amd.com>
Signed-off-by: default avatarVasant Hegde <vasant.hegde@amd.com>
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Link: https://lore.kernel.org/r/20220706113825.25582-31-vasant.hegde@amd.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent bf87972c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ static inline int get_pci_sbdf_id(struct pci_dev *pdev)

extern bool translation_pre_enabled(struct amd_iommu *iommu);
extern bool amd_iommu_is_attach_deferred(struct device *dev);
extern int __init add_special_device(u8 type, u8 id, u16 *devid,
extern int __init add_special_device(u8 type, u8 id, u32 *devid,
				     bool cmd_line);

#ifdef CONFIG_DMI
+3 −3
Original line number Diff line number Diff line
@@ -744,8 +744,8 @@ struct acpihid_map_entry {
	struct list_head list;
	u8 uid[ACPIHID_UID_LEN];
	u8 hid[ACPIHID_HID_LEN];
	u16 devid;
	u16 root_devid;
	u32 devid;
	u32 root_devid;
	bool cmd_line;
	struct iommu_group *group;
};
@@ -753,7 +753,7 @@ struct acpihid_map_entry {
struct devid_map {
	struct list_head list;
	u8 id;
	u16 devid;
	u32 devid;
	bool cmd_line;
};

+29 −27
Original line number Diff line number Diff line
@@ -1148,7 +1148,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
	amd_iommu_set_rlookup_table(iommu, devid);
}

int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
int __init add_special_device(u8 type, u8 id, u32 *devid, bool cmd_line)
{
	struct devid_map *entry;
	struct list_head *list;
@@ -1185,7 +1185,7 @@ int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
	return 0;
}

static int __init add_acpi_hid_device(u8 *hid, u8 *uid, u16 *devid,
static int __init add_acpi_hid_device(u8 *hid, u8 *uid, u32 *devid,
				      bool cmd_line)
{
	struct acpihid_map_entry *entry;
@@ -1264,7 +1264,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
{
	u8 *p = (u8 *)h;
	u8 *end = p, flags = 0;
	u16 devid = 0, devid_start = 0, devid_to = 0;
	u16 devid = 0, devid_start = 0, devid_to = 0, seg_id;
	u32 dev_i, ext_flags = 0;
	bool alias = false;
	struct ivhd_entry *e;
@@ -1300,6 +1300,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,

	while (p < end) {
		e = (struct ivhd_entry *)p;
		seg_id = pci_seg->id;

		switch (e->type) {
		case IVHD_DEV_ALL:

@@ -1310,9 +1312,9 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
			break;
		case IVHD_DEV_SELECT:

			DUMP_printk("  DEV_SELECT\t\t\t devid: %02x:%02x.%x "
			DUMP_printk("  DEV_SELECT\t\t\t devid: %04x:%02x:%02x.%x "
				    "flags: %02x\n",
				    PCI_BUS_NUM(e->devid),
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags);
@@ -1323,8 +1325,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
		case IVHD_DEV_SELECT_RANGE_START:

			DUMP_printk("  DEV_SELECT_RANGE_START\t "
				    "devid: %02x:%02x.%x flags: %02x\n",
				    PCI_BUS_NUM(e->devid),
				    "devid: %04x:%02x:%02x.%x flags: %02x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags);
@@ -1336,9 +1338,9 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
			break;
		case IVHD_DEV_ALIAS:

			DUMP_printk("  DEV_ALIAS\t\t\t devid: %02x:%02x.%x "
			DUMP_printk("  DEV_ALIAS\t\t\t devid: %04x:%02x:%02x.%x "
				    "flags: %02x devid_to: %02x:%02x.%x\n",
				    PCI_BUS_NUM(e->devid),
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags,
@@ -1355,13 +1357,13 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
		case IVHD_DEV_ALIAS_RANGE:

			DUMP_printk("  DEV_ALIAS_RANGE\t\t "
				    "devid: %02x:%02x.%x flags: %02x "
				    "devid_to: %02x:%02x.%x\n",
				    PCI_BUS_NUM(e->devid),
				    "devid: %04x:%02x:%02x.%x flags: %02x "
				    "devid_to: %04x:%02x:%02x.%x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags,
				    PCI_BUS_NUM(e->ext >> 8),
				    seg_id, PCI_BUS_NUM(e->ext >> 8),
				    PCI_SLOT(e->ext >> 8),
				    PCI_FUNC(e->ext >> 8));

@@ -1373,9 +1375,9 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
			break;
		case IVHD_DEV_EXT_SELECT:

			DUMP_printk("  DEV_EXT_SELECT\t\t devid: %02x:%02x.%x "
			DUMP_printk("  DEV_EXT_SELECT\t\t devid: %04x:%02x:%02x.%x "
				    "flags: %02x ext: %08x\n",
				    PCI_BUS_NUM(e->devid),
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags, e->ext);
@@ -1387,8 +1389,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
		case IVHD_DEV_EXT_SELECT_RANGE:

			DUMP_printk("  DEV_EXT_SELECT_RANGE\t devid: "
				    "%02x:%02x.%x flags: %02x ext: %08x\n",
				    PCI_BUS_NUM(e->devid),
				    "%04x:%02x:%02x.%x flags: %02x ext: %08x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags, e->ext);
@@ -1400,8 +1402,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
			break;
		case IVHD_DEV_RANGE_END:

			DUMP_printk("  DEV_RANGE_END\t\t devid: %02x:%02x.%x\n",
				    PCI_BUS_NUM(e->devid),
			DUMP_printk("  DEV_RANGE_END\t\t devid: %04x:%02x:%02x.%x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid));

@@ -1419,11 +1421,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
		case IVHD_DEV_SPECIAL: {
			u8 handle, type;
			const char *var;
			u16 devid;
			u32 devid;
			int ret;

			handle = e->ext & 0xff;
			devid  = (e->ext >>  8) & 0xffff;
			devid = PCI_SEG_DEVID_TO_SBDF(seg_id, (e->ext >> 8));
			type   = (e->ext >> 24) & 0xff;

			if (type == IVHD_SPECIAL_IOAPIC)
@@ -1433,9 +1435,9 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
			else
				var = "UNKNOWN";

			DUMP_printk("  DEV_SPECIAL(%s[%d])\t\tdevid: %02x:%02x.%x\n",
			DUMP_printk("  DEV_SPECIAL(%s[%d])\t\tdevid: %04x:%02x:%02x.%x\n",
				    var, (int)handle,
				    PCI_BUS_NUM(devid),
				    seg_id, PCI_BUS_NUM(devid),
				    PCI_SLOT(devid),
				    PCI_FUNC(devid));

@@ -1453,7 +1455,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
			break;
		}
		case IVHD_DEV_ACPI_HID: {
			u16 devid;
			u32 devid;
			u8 hid[ACPIHID_HID_LEN];
			u8 uid[ACPIHID_UID_LEN];
			int ret;
@@ -1496,9 +1498,9 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
				break;
			}

			devid = e->devid;
			DUMP_printk("  DEV_ACPI_HID(%s[%s])\t\tdevid: %02x:%02x.%x\n",
				    hid, uid,
			devid = PCI_SEG_DEVID_TO_SBDF(seg_id, e->devid);
			DUMP_printk("  DEV_ACPI_HID(%s[%s])\t\tdevid: %04x:%02x:%02x.%x\n",
				    hid, uid, seg_id,
				    PCI_BUS_NUM(devid),
				    PCI_SLOT(devid),
				    PCI_FUNC(devid));
+2 −2
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@

struct ivrs_quirk_entry {
	u8 id;
	u16 devid;
	u32 devid;
};

enum {
@@ -49,7 +49,7 @@ static int __init ivrs_ioapic_quirk_cb(const struct dmi_system_id *d)
	const struct ivrs_quirk_entry *i;

	for (i = d->driver_data; i->id != 0 && i->devid != 0; i++)
		add_special_device(IVHD_SPECIAL_IOAPIC, i->id, (u16 *)&i->devid, 0);
		add_special_device(IVHD_SPECIAL_IOAPIC, i->id, (u32 *)&i->devid, 0);

	return 0;
}