x86/amd-iommu: Fix NULL pointer dereference in __detach_device()
authorJoerg Roedel <joerg.roedel@amd.com>
Fri, 22 Jan 2010 15:45:31 +0000 (16:45 +0100)
committerJoerg Roedel <joerg.roedel@amd.com>
Fri, 22 Jan 2010 16:32:31 +0000 (17:32 +0100)
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>
arch/x86/kernel/amd_iommu.c

index c2ccbd7b862f4c3c082832e62a6870661305ec8d..4478a48198a844902f70d52514fbbe9f178140f8 100644 (file)
@@ -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 *alias_data;
+       struct protection_domain *domain;
        unsigned long flags;
 
        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) {
                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))
                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