Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e824f79 authored by Yu Zhao's avatar Yu Zhao Committed by Joerg Roedel
Browse files

VT-d: fix segment number being ignored when searching DRHD



On platforms with multiple PCI segments, any of the segments can have a DRHD
with INCLUDE_PCI_ALL flag. So need to check the DRHD's segment number against
the PCI device's when searching its DRHD.

Signed-off-by: default avatarYu Zhao <yu.zhao@intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent 19c239ce
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
@@ -191,26 +191,17 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru)
{
	struct acpi_dmar_hardware_unit *drhd;
	static int include_all;
	int ret = 0;

	drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;

	if (!dmaru->include_all)
	if (dmaru->include_all)
		return 0;

	ret = dmar_parse_dev_scope((void *)(drhd + 1),
				((void *)drhd) + drhd->header.length,
				&dmaru->devices_cnt, &dmaru->devices,
				drhd->segment);
	else {
		/* Only allow one INCLUDE_ALL */
		if (include_all) {
			printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL "
				"device scope is allowed\n");
			ret = -EINVAL;
		}
		include_all = 1;
	}

	if (ret) {
		list_del(&dmaru->list);
		kfree(dmaru);
@@ -384,12 +375,21 @@ int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
struct dmar_drhd_unit *
dmar_find_matched_drhd_unit(struct pci_dev *dev)
{
	struct dmar_drhd_unit *drhd = NULL;
	struct dmar_drhd_unit *dmaru = NULL;
	struct acpi_dmar_hardware_unit *drhd;

	list_for_each_entry(dmaru, &dmar_drhd_units, list) {
		drhd = container_of(dmaru->hdr,
				    struct acpi_dmar_hardware_unit,
				    header);

		if (dmaru->include_all &&
		    drhd->segment == pci_domain_nr(dev->bus))
			return dmaru;

	list_for_each_entry(drhd, &dmar_drhd_units, list) {
		if (drhd->include_all || dmar_pci_device_match(drhd->devices,
						drhd->devices_cnt, dev))
			return drhd;
		if (dmar_pci_device_match(dmaru->devices,
					  dmaru->devices_cnt, dev))
			return dmaru;
	}

	return NULL;