From: "Adrian Barnaś" <abarnas@google.com>
To: Ryan Roberts <ryan.roberts@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
David Hildenbrand <david@kernel.org>,
"Mike Rapoport (Microsoft)" <rppt@kernel.org>,
Ard Biesheuvel <ardb@kernel.org>,
Christoph Lameter <cl@gentwo.org>,
Yang Shi <yang@os.amperecomputing.com>,
Brendan Jackman <jackmanb@google.com>
Subject: Re: [RFC PATCH 3/6] arm64: mm: fix restoring linear map permissions on execmem cache clean
Date: Wed, 24 Jun 2026 13:52:25 +0000 [thread overview]
Message-ID: <ajvhGajVO_GFlcrY@google.com> (raw)
In-Reply-To: <751c564b-d6c3-4bd5-a269-e3de89e8cf13@arm.com>
On Fri, Jun 19, 2026 at 09:33:18AM +0100, Ryan Roberts wrote:
>On 18/06/2026 16:05, Ryan Roberts wrote:
>> On 11/06/2026 14:01, Adrian Barnaś wrote:
>>> Strip the read-only attribute from the selected memory range when
>>> restoring the linear map after an execmem cache clean.
>>>
>>> An execmem cache clean is performed when a cache block becomes empty
>>> after unloading a module. When making the memory valid again, the linear
>>> memory alias must also have its read-only attribute cleared.
>>>
>>> Without this change, the linear memory alias remains read-only even
>>> after the execmem cache block itself is freed, which prevents subsequent
>>> allocations from writing to that memory.
>>>
>>> Signed-off-by: Adrian Barnaś <abarnas@google.com>
>>> ---
>>> arch/arm64/mm/pageattr.c | 17 ++++++++++++++++-
>>> 1 file changed, 16 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
>>> index 88720bbba892..eaefdf90b0d5 100644
>>> --- a/arch/arm64/mm/pageattr.c
>>> +++ b/arch/arm64/mm/pageattr.c
>>> @@ -239,6 +239,13 @@ int set_memory_x(unsigned long addr, int numpages)
>>> __pgprot(PTE_PXN));
>>> }
>>>
>>> +static int set_memory_default(unsigned long addr, int numpages)
>>> +{
>>> + return __change_memory_common(addr, PAGE_SIZE * numpages,
>>> + __pgprot(PTE_VALID),
>>> + __pgprot(PTE_RDONLY));
>>
>> This is not sufficient to convert an invalid entry to valid. As well as setting
>> the PTE_VALID bit, you would also need to clear the PTE_PRESENT_INVALID and set
>> PTE_MAYBE_NG.
>>
>> e.g:
>>
>> int set_memory_valid(unsigned long addr, int numpages, int enable)
>> {
>> if (enable)
>> return __change_memory_common(addr, PAGE_SIZE * numpages,
>> __pgprot(PTE_PRESENT_VALID_KERNEL),
>> __pgprot(PTE_PRESENT_INVALID));
>>
Thanks, I will fix that
>>
>>> +}
>>> +
>>> int set_memory_valid(unsigned long addr, int numpages, int enable)
>>> {
>>> if (enable)
>>> @@ -362,7 +369,15 @@ int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
>>> if (!can_set_direct_map())
>>> return 0;
>>>
>>> - return set_memory_valid(addr, nr, valid);
>>> + /*
>>> + * Execmem cache uses this function to reset permissions on linear mapping
>>> + * when freeing unused cache block. On x86 it makes memory RW which is
>>> + * desirable. On ARM64 set_memory_valid() just change valid bit which
>>> + * leave direct mapping read-only so use set_memory_default instead.
>>> + */
>>> +
>>> + return valid ? set_memory_default(addr, nr) :
>>> + set_memory_valid(addr, nr, false);
>>
>> Surely execmem should just be using set_direct_map_default_noflush() if that's
>> the behaviour it wants?
>>
>> I think that the current implementation of set_direct_map_default_noflush()
>> doesn't undo the effects of set_memory_nx() / set_memory_x(). That might be
>> worth checking?
>
>It's also worth mentioning that set_direct_map_valid_noflush() has "noflush" in
>the name, implies it doesn't expect/require any TLB flushing to occur. But the
>implementation will perform tlb flushing for any case that is not just a
>invalid->valid transition (which for the existing impl is the case when
>valid=true and for your changes is never the case - see __change_memory_common).
>
>But execmem doesn't do any tlb flushing so it looks to me like it actually
>requires that set_direct_map_valid_noflush() handles the tlb flushing? All seems
>a bit fishy and probably warrants a cleanup to make things clearer.
>
I think that the clean approach would be to have the `set_direct_map_default`
function (without `noflush`) that does flushing as needed (like the current
one on ARM64). I am not entirely sure but x86 seems to handle permission
faults gracefully while on ARM64 those would cause panics. Is that correct?
>>
>> Thanks,
>> Ryan
>>
>>
>>> }
>>>
>>> #ifdef CONFIG_DEBUG_PAGEALLOC
>>
>
Thanks,
Adrian
next prev parent reply other threads:[~2026-06-24 13:52 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-11 13:01 [RFC PATCH 0/6] arm64: mm: Introducing ROX CACHE to ARM64 systems with bbml2 no abort Adrian Barnaś
2026-06-11 13:01 ` [RFC PATCH 1/6] arm64: mm: explicitly declare module and ftrace execmem regions Adrian Barnaś
2026-06-11 13:36 ` Brendan Jackman
2026-06-11 13:01 ` [RFC PATCH 2/6] arm64: mm: allow huge vmap permission adjustments with bbml2_no_abort Adrian Barnaś
2026-06-18 14:21 ` Ryan Roberts
2026-06-24 13:54 ` Adrian Barnaś
2026-06-11 13:01 ` [RFC PATCH 3/6] arm64: mm: fix restoring linear map permissions on execmem cache clean Adrian Barnaś
2026-06-11 13:54 ` Brendan Jackman
2026-06-12 7:17 ` Mike Rapoport
2026-06-17 15:18 ` Adrian Barnaś
2026-06-17 18:40 ` Mike Rapoport
2026-06-24 13:57 ` Adrian Barnaś
2026-06-18 15:05 ` Ryan Roberts
2026-06-19 8:33 ` Ryan Roberts
2026-06-24 13:52 ` Adrian Barnaś [this message]
2026-06-11 13:01 ` [RFC PATCH 4/6] arm64: mm: add helper to fill execmem with trapping instructions Adrian Barnaś
2026-06-19 10:54 ` Ryan Roberts
2026-06-19 10:58 ` Mike Rapoport
2026-06-11 13:01 ` [RFC PATCH 5/6] arm64: execmem: enable EXECMEM_ROX_CACHE on supported CPUs Adrian Barnaś
2026-06-19 12:09 ` Ryan Roberts
2026-06-11 13:01 ` [RFC PATCH 6/6] arm64: mm: support PMD page coalescing in the linear map Adrian Barnaś
2026-06-19 13:40 ` Ryan Roberts
2026-06-24 14:32 ` Adrian Barnaś
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ajvhGajVO_GFlcrY@google.com \
--to=abarnas@google.com \
--cc=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=cl@gentwo.org \
--cc=david@kernel.org \
--cc=jackmanb@google.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-mm@kvack.org \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=will@kernel.org \
--cc=yang@os.amperecomputing.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.