x86/amd-iommu: Fix NULL pointer dereference in __detach_device()
In the __detach_device function the reference count for a device-domain binding may become zero. This results in the device being removed from the domain and dev_data->domain will be NULL. This is bad because this pointer is dereferenced when trying to unlock the domain->lock. This patch fixes the issue by keeping the domain in a seperate variable. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
@@ -1489,11 +1489,14 @@ static void __detach_device(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct iommu_dev_data *dev_data = get_dev_data(dev);
|
struct iommu_dev_data *dev_data = get_dev_data(dev);
|
||||||
struct iommu_dev_data *alias_data;
|
struct iommu_dev_data *alias_data;
|
||||||
|
struct protection_domain *domain;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
BUG_ON(!dev_data->domain);
|
BUG_ON(!dev_data->domain);
|
||||||
|
|
||||||
spin_lock_irqsave(&dev_data->domain->lock, flags);
|
domain = dev_data->domain;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&domain->lock, flags);
|
||||||
|
|
||||||
if (dev_data->alias != dev) {
|
if (dev_data->alias != dev) {
|
||||||
alias_data = get_dev_data(dev_data->alias);
|
alias_data = get_dev_data(dev_data->alias);
|
||||||
@@ -1504,7 +1507,7 @@ static void __detach_device(struct device *dev)
|
|||||||
if (atomic_dec_and_test(&dev_data->bind))
|
if (atomic_dec_and_test(&dev_data->bind))
|
||||||
do_detach(dev);
|
do_detach(dev);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev_data->domain->lock, flags);
|
spin_unlock_irqrestore(&domain->lock, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we run in passthrough mode the device must be assigned to the
|
* If we run in passthrough mode the device must be assigned to the
|
||||||
|
Reference in New Issue
Block a user