Re: [PATCH 0/5] x86/ftrace: Cure boot time W+X mapping

From: Linus Torvalds
Date: Wed Oct 26 2022 - 14:00:03 EST


On Wed, Oct 26, 2022 at 12:15 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
>
> Right, and we have it all over the place. Something like the below
> perhaps? I'll feed it to the robots, see if something breaks.

I was nodding along with the patches like this:

> - set_memory_ro(base, pages);
> - set_memory_x(base, pages);
> + set_memory_rox(base, pages);

but then I got to this part:

> +static inline int set_memory_rox(unsigned long addr, int numpages)
> +{
> + int ret = set_memory_ro(addr, numpages);
> + if (ret)
> + return ret;
> + return set_memory_x(addr, numpages);
> +}

and that's when I went "no, I really meant make it one single call".

set_memory_ro() and set_memory_x() basically end up doing the exact
same thing, just with different bits. So it's not only silly to have
the callers do two different calls, it's silly to have the
*implementation* do two different scans of the page tables and page
merging/splitting.

I think in the case of x86, the set_memory_rox() function would
basically just be

int set_memory_rox(unsigned long addr, int numpages)
{
pgprot_t clr = __pgprot(_PAGE_RW);
pgprot_t set = { 0 };

if (__supported_pte_mask & _PAGE_NX)
set.pgprot |= _PAGE_NX;

return change_page_attr_set_clr(&addr, numpages, set, clr, 0, NULL);
}

or something close to that. (NOTE! The above was cobbled together in
the MUA, hasn't seen a compiler much less been booted, and might be
completely broken for some reason - it's meant to be the concept, not
some kind of final word).

IOW, the whole "set_rox" is really just a _single_
change_page_attr_set_clr() call.

Maybe you meant to do that, and this patch was just prep-work for the
arch code being the second stage?

Linus