mirror of https://gitee.com/openkylin/linux.git
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: Yu Zhao <yu.zhao@intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
19c239ce3d
commit
2e824f7924
|
@ -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)
|
||||
ret = dmar_parse_dev_scope((void *)(drhd + 1),
|
||||
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(drhd, &dmar_drhd_units, list) {
|
||||
if (drhd->include_all || dmar_pci_device_match(drhd->devices,
|
||||
drhd->devices_cnt, dev))
|
||||
return 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;
|
||||
|
||||
if (dmar_pci_device_match(dmaru->devices,
|
||||
dmaru->devices_cnt, dev))
|
||||
return dmaru;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue