--- a/sys/dev/drm/include/linux/scatterlist.h +++ b/sys/dev/drm/include/linux/scatterlist.h @@ -259,10 +259,24 @@ ++iter->sg_pgoffset; while (iter->sg_pgoffset >= pgcount) { + /* + * Hard-stop once the caller's entry budget (nents) is + * exhausted. The old `--maxents ... == 0' test left + * iter->sg pointing at the out-of-budget entry and then + * underflowed the unsigned counter to UINT_MAX, permanently + * disarming the budget: iteration then ran to the physical + * SG_END of the table (across chained chunks), processing + * entries the caller never declared. Linux semantics + * (__sg_page_iter_next) stop at nents. + */ + if (iter->maxents <= 1) { + iter->sg = NULL; + return; + } iter->sg_pgoffset -= pgcount; sg = sg_next(sg); --iter->maxents; - if (sg == NULL || iter->maxents == 0) + if (sg == NULL) break; pgcount = (sg->offset + sg->length + PAGE_MASK) >> PAGE_SHIFT; }