mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
iommu/vt-d: Search for ACPI _DSM method for DMAR hotplug
According to Intel VT-d specification, _DSM method to support DMAR hotplug should exist directly under corresponding ACPI object representing PCI host bridge. But some BIOSes doesn't conform to this, so search for _DSM method in the subtree starting from the ACPI object representing the PCI host bridge. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Reviewed-by: Yijing Wang <wangyijing@huawei.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
6b1972493a
commit
d35165a955
1 changed files with 30 additions and 3 deletions
|
@ -1942,21 +1942,48 @@ static int dmar_hotplug_remove(acpi_handle handle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static acpi_status dmar_get_dsm_handle(acpi_handle handle, u32 lvl,
|
||||
void *context, void **retval)
|
||||
{
|
||||
acpi_handle *phdl = retval;
|
||||
|
||||
if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) {
|
||||
*phdl = handle;
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int dmar_device_hotplug(acpi_handle handle, bool insert)
|
||||
{
|
||||
int ret;
|
||||
acpi_handle tmp = NULL;
|
||||
acpi_status status;
|
||||
|
||||
if (!dmar_in_use())
|
||||
return 0;
|
||||
|
||||
if (!dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD))
|
||||
if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) {
|
||||
tmp = handle;
|
||||
} else {
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
|
||||
ACPI_UINT32_MAX,
|
||||
dmar_get_dsm_handle,
|
||||
NULL, NULL, &tmp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_warn("Failed to locate _DSM method.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
|
||||
down_write(&dmar_global_lock);
|
||||
if (insert)
|
||||
ret = dmar_hotplug_insert(handle);
|
||||
ret = dmar_hotplug_insert(tmp);
|
||||
else
|
||||
ret = dmar_hotplug_remove(handle);
|
||||
ret = dmar_hotplug_remove(tmp);
|
||||
up_write(&dmar_global_lock);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue