[PATCH] DMA 4GB boundary protection
Jake Moilanen
moilanen at austin.ibm.com
Fri Mar 23 04:47:45 EST 2007
On Thu, 2007-03-22 at 12:53 -0500, Olof Johansson wrote:
> 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.
Yup, I like that better. I'll give it a run.
Jake
More information about the Linuxppc-dev
mailing list