diff options
author | Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com> | 2011-09-19 23:07:24 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-09-22 20:27:03 -0400 |
commit | d12b524f8b2f4e45cabe8bc1501e8b967d543111 (patch) | |
tree | f19127f7d644ed9f009466aad57bceb8e0404f15 /arch/powerpc/kernel/iommu.c | |
parent | 25c29f9e3242071bca1bee7ad919baf1888ae436 (diff) |
powerpc: Reserve iommu page 0
Some devices have a dma-window that starts at the address 0. This allows
DMA addresses to be mapped to this address and returned to drivers as a
valid DMA address. Some drivers may not behave well in this case, since
the address 0 is considered an error or not allocated.
The solution to avoid this kind of error from happening is reserve the
page addressed as 0 so it cannot be allocated for a DMA mapping.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/iommu.c')
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 961bb03413f3..0cfcf98aafca 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -501,6 +501,14 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
501 | tbl->it_map = page_address(page); | 501 | tbl->it_map = page_address(page); |
502 | memset(tbl->it_map, 0, sz); | 502 | memset(tbl->it_map, 0, sz); |
503 | 503 | ||
504 | /* | ||
505 | * Reserve page 0 so it will not be used for any mappings. | ||
506 | * This avoids buggy drivers that consider page 0 to be invalid | ||
507 | * to crash the machine or even lose data. | ||
508 | */ | ||
509 | if (tbl->it_offset == 0) | ||
510 | set_bit(0, tbl->it_map); | ||
511 | |||
504 | tbl->it_hint = 0; | 512 | tbl->it_hint = 0; |
505 | tbl->it_largehint = tbl->it_halfpoint; | 513 | tbl->it_largehint = tbl->it_halfpoint; |
506 | spin_lock_init(&tbl->it_lock); | 514 | spin_lock_init(&tbl->it_lock); |