powerpc/iommu: Fix multiple issues with IOMMU pools code
There are a number of issues in the recent IOMMU pools code: - On a preempt kernel we might switch CPUs in the middle of building a scatter gather list. When this happens the handle hint passed in no longer falls within the local CPU's pool. Check for this and fall back to the pool hint. - We were missing a spin_unlock/spin_lock in one spot where we switch pools. - We need to provide locking around dart_tlb_invalidate_all and dart_tlb_invalidate_one now that the global lock is gone. Reported-by: Alexander Graf <agraf@suse.de> Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> CC: <stable@kernel.org> [v3.6]
此提交包含在:

提交者
Benjamin Herrenschmidt

父節點
c8adfeccee
當前提交
d900bd7366
@@ -215,7 +215,8 @@ static unsigned long iommu_range_alloc(struct device *dev,
|
||||
spin_lock_irqsave(&(pool->lock), flags);
|
||||
|
||||
again:
|
||||
if ((pass == 0) && handle && *handle)
|
||||
if ((pass == 0) && handle && *handle &&
|
||||
(*handle >= pool->start) && (*handle < pool->end))
|
||||
start = *handle;
|
||||
else
|
||||
start = pool->hint;
|
||||
@@ -236,7 +237,9 @@ again:
|
||||
* but on second pass, start at 0 in pool 0.
|
||||
*/
|
||||
if ((start & mask) >= limit || pass > 0) {
|
||||
spin_unlock(&(pool->lock));
|
||||
pool = &(tbl->pools[0]);
|
||||
spin_lock(&(pool->lock));
|
||||
start = pool->start;
|
||||
} else {
|
||||
start &= mask;
|
||||
|
新增問題並參考
封鎖使用者