On Fri, 14 Feb 2025 19:46:22 +0000 Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > On Wed, Feb 05, 2025 at 04:17:21PM -0700, Alex Williamson wrote: > > + if (is_invalid_reserved_pfn(*pfn)) { > > + unsigned long epfn; > > + > > + epfn = (((*pfn << PAGE_SHIFT) + ~pgmask + 1) > > + & pgmask) >> PAGE_SHIFT; > > + ret = min_t(int, npages, epfn - *pfn); > > You've really made life hard for yourself by passing around a page mask > instead of an order (ie 0/PMD_ORDER/PUD_ORDER). Why not: > > epfn = round_up(*pfn + 1, 1 << order); > > Although if you insist on passing around a mask, this could be: > > unsigned long sz = (~pgmask >> PAGE_SHIFT) + 1; > unsigned long epfn = round_up(*pfn + 1, sz) > Hey Willy! I was wishing I had an order, but I didn't want to mangle follow_pfnmap_start() and follow_pfnmap_setup() too much. Currently the latter is doing: args->pfn = pfn_base + ((args->address & ~addr_mask) >> PAGE_SHIFT); If follow_pfnmap_start() passed an order, this would need to change to something equivalent to: args->pfn = pfn_base + ((args->address >> PAGE_SHIFT) & ((1UL << order) - 1)); Looks pretty ugly as well, so maybe I'm just shifting the ugliness around, or maybe someone can spot a more elegant representation. Thanks, Alex