[PATCH] DMA 4GB boundary protection
Olof Johansson
olof at lixom.net
Fri Mar 23 04:53:24 EST 2007
On Wed, Mar 21, 2007 at 04:05:48PM -0500, Jake Moilanen wrote:
> @@ -480,6 +495,21 @@ struct iommu_table *iommu_init_table(str
> ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
> #endif
>
> + /*
> + * DMA cannot cross 4 GB boundary. Mark first entry of each 4
> + * GB chunk as reserved.
> + */
> + if (protect4gb) {
> + start_addr = tbl->it_offset << IOMMU_PAGE_SHIFT;
> + /* go up to next 4GB boundary */
> + start_addr = (start_addr + 0x00000000ffffffffl) >> 32;
> + end_addr = (tbl->it_offset + tbl->it_size) << IOMMU_PAGE_SHIFT;
> + for (index = start_addr; index < end_addr; index += (1l << 32)) {
> + /* Reserve 4GB entry */
> + __set_bit((index >> IOMMU_PAGE_SHIFT) - tbl->it_offset,
> tbl->it_map);
> + }
> + }
> +
This is done a bit more complicated than it has to be. The >> 32 is a
red flag as well.
I would also like it to be the last page in the range, not the first
(since otherwise you'll reserve even if the window is less than 4GB.
Something like (untested):
entries_per_4g = 0x100000000 >> IOMMU_PAGE_SHIFT;
/* Mark the last bit before a 4GB boundary as used */
start_index = tbl->it_offset | (entries_per_4g - 1);
end_index = tbl->it_offset + tbl->it_size;
for (index = start_index; index < end_index; index += entries_per_4g)
__set_bit(index, tbl->it_map);
Is easier to follow.
-Olof
More information about the Linuxppc-dev
mailing list