Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
       [not found] <20260717170036.743149-1-riel@surriel.com>
@ 2026-07-17 17:00 ` Rik van Riel
  2026-07-20 11:57   ` Usama Arif
  0 siblings, 1 reply; 8+ messages in thread
From: Rik van Riel @ 2026-07-17 17:00 UTC (permalink / raw)
  To: linux-kernel, Andrew Morton
  Cc: kernel-team, Rik van Riel, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv

__access_remote_vm() untags the remote address before looking up the VMA,
now without holding the mmap lock. riscv defines untagged_addr_remote() but
not untagged_addr_remote_unlocked(), so it falls back to the generic
version, which untags with untagged_addr().

That reads current->mm, not the target mm, so a remote access to a process
using pointer masking would untag with the wrong mask.

mm->context.pmlen is set only through PR_SET_TAGGED_ADDR_CTRL and is stable
afterwards, so it can be read without the mmap lock, as it already is from
untagged_addr() and mm_untag_mask().

Add untagged_addr_remote_unlocked(), which untags against the target mm,
and annotate context.pmlen accesses with READ_ONCE() and WRITE_ONCE() so
the lockless reads are explicit and KCSAN-clean. untagged_addr_remote()
keeps its mmap_assert_locked() and shares the code.

Assisted-by: Claude:claude-opus-4.8
Signed-off-by: Rik van Riel <riel@surriel.com>
---
 arch/riscv/include/asm/mmu_context.h |  4 ++--
 arch/riscv/include/asm/uaccess.h     | 10 +++++++---
 arch/riscv/kernel/process.c          | 12 +++++++-----
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index dbf27a78df6c..3ce16796e5a2 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -21,7 +21,7 @@ static inline void activate_mm(struct mm_struct *prev,
 			       struct mm_struct *next)
 {
 #ifdef CONFIG_RISCV_ISA_SUPM
-	next->context.pmlen = 0;
+	WRITE_ONCE(next->context.pmlen, 0);
 #endif
 	switch_mm(prev, next, NULL);
 }
@@ -44,7 +44,7 @@ DECLARE_STATIC_KEY_FALSE(use_asid_allocator);
 #define mm_untag_mask mm_untag_mask
 static inline unsigned long mm_untag_mask(struct mm_struct *mm)
 {
-	return -1UL >> mm->context.pmlen;
+	return -1UL >> READ_ONCE(mm->context.pmlen);
 }
 #endif
 
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 5d4ec15584cf..53806e0f7dcf 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -16,7 +16,7 @@
 static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, unsigned long addr)
 {
 	if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM)) {
-		u8 pmlen = mm->context.pmlen;
+		u8 pmlen = READ_ONCE(mm->context.pmlen);
 
 		/* Virtual addresses are sign-extended; physical addresses are zero-extended. */
 		if (IS_ENABLED(CONFIG_MMU))
@@ -33,12 +33,16 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, unsigne
 	(__force __typeof__(addr))__untagged_addr_remote(current->mm, __addr);	\
 })
 
-#define untagged_addr_remote(mm, addr) ({					\
+#define untagged_addr_remote_unlocked(mm, addr) ({				\
 	unsigned long __addr = (__force unsigned long)(addr);			\
-	mmap_assert_locked(mm);							\
 	(__force __typeof__(addr))__untagged_addr_remote(mm, __addr);		\
 })
 
+#define untagged_addr_remote(mm, addr) ({					\
+	mmap_assert_locked(mm);							\
+	untagged_addr_remote_unlocked(mm, addr);				\
+})
+
 #define access_ok(addr, size) likely(__access_ok(untagged_addr(addr), size))
 #else
 #define untagged_addr(addr) (addr)
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index b2df7f72241a..6ae7552fed09 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -357,13 +357,15 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
 	if (mmap_write_lock_killable(mm))
 		return -EINTR;
 
-	if (test_bit(MM_CONTEXT_LOCK_PMLEN, &mm->context.flags) && mm->context.pmlen != pmlen) {
-		mmap_write_unlock(mm);
-		return -EBUSY;
+	if (test_bit(MM_CONTEXT_LOCK_PMLEN, &mm->context.flags)) {
+		if (READ_ONCE(mm->context.pmlen) != pmlen) {
+			mmap_write_unlock(mm);
+			return -EBUSY;
+		}
 	}
 
 	envcfg_update_bits(task, ENVCFG_PMM, pmm);
-	mm->context.pmlen = pmlen;
+	WRITE_ONCE(mm->context.pmlen, pmlen);
 
 	mmap_write_unlock(mm);
 
@@ -394,7 +396,7 @@ long get_tagged_addr_ctrl(struct task_struct *task)
 		break;
 	}
 
-	if (task->mm->context.pmlen)
+	if (READ_ONCE(task->mm->context.pmlen))
 		ret |= PR_TAGGED_ADDR_ENABLE;
 
 	return ret;
-- 
2.53.0-Meta


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-17 17:00 ` [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked() Rik van Riel
@ 2026-07-20 11:57   ` Usama Arif
  2026-07-20 15:08     ` Rik van Riel
  0 siblings, 1 reply; 8+ messages in thread
From: Usama Arif @ 2026-07-20 11:57 UTC (permalink / raw)
  To: Rik van Riel
  Cc: Usama Arif, linux-kernel, Andrew Morton, kernel-team,
	David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	linux-mm, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, linux-riscv

On Fri, 17 Jul 2026 13:00:32 -0400 Rik van Riel <riel@surriel.com> wrote:

> __access_remote_vm() untags the remote address before looking up the VMA,
> now without holding the mmap lock. riscv defines untagged_addr_remote() but

This describes behavior introduced in a later patch, not by this patch.
At this point, __access_remote_vm() still acquires mmap_lock before
untagging the address.

> not untagged_addr_remote_unlocked(), so it falls back to the generic
> version, which untags with untagged_addr().
> 
> That reads current->mm, not the target mm, so a remote access to a process
> using pointer masking would untag with the wrong mask.
> 
> mm->context.pmlen is set only through PR_SET_TAGGED_ADDR_CTRL and is stable
> afterwards, so it can be read without the mmap lock, as it already is from
> untagged_addr() and mm_untag_mask().
>

I think it might not be stable? set_tagged_addr_ctrl() can change it
repeatedly until a CLONE_VM operation sets MM_CONTEXT_LOCK_PMLEN.

> Add untagged_addr_remote_unlocked(), which untags against the target mm,
> and annotate context.pmlen accesses with READ_ONCE() and WRITE_ONCE() so
> the lockless reads are explicit and KCSAN-clean. untagged_addr_remote()
> keeps its mmap_assert_locked() and shares the code.
> 
> Assisted-by: Claude:claude-opus-4.8
> Signed-off-by: Rik van Riel <riel@surriel.com>
> ---
>  arch/riscv/include/asm/mmu_context.h |  4 ++--
>  arch/riscv/include/asm/uaccess.h     | 10 +++++++---
>  arch/riscv/kernel/process.c          | 12 +++++++-----
>  3 files changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
> index dbf27a78df6c..3ce16796e5a2 100644
> --- a/arch/riscv/include/asm/mmu_context.h
> +++ b/arch/riscv/include/asm/mmu_context.h
> @@ -21,7 +21,7 @@ static inline void activate_mm(struct mm_struct *prev,
>  			       struct mm_struct *next)
>  {
>  #ifdef CONFIG_RISCV_ISA_SUPM
> -	next->context.pmlen = 0;
> +	WRITE_ONCE(next->context.pmlen, 0);
>  #endif
>  	switch_mm(prev, next, NULL);
>  }
> @@ -44,7 +44,7 @@ DECLARE_STATIC_KEY_FALSE(use_asid_allocator);
>  #define mm_untag_mask mm_untag_mask
>  static inline unsigned long mm_untag_mask(struct mm_struct *mm)
>  {
> -	return -1UL >> mm->context.pmlen;
> +	return -1UL >> READ_ONCE(mm->context.pmlen);
>  }
>  #endif
>  
> diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
> index 5d4ec15584cf..53806e0f7dcf 100644
> --- a/arch/riscv/include/asm/uaccess.h
> +++ b/arch/riscv/include/asm/uaccess.h
> @@ -16,7 +16,7 @@
>  static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, unsigned long addr)
>  {
>  	if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM)) {
> -		u8 pmlen = mm->context.pmlen;
> +		u8 pmlen = READ_ONCE(mm->context.pmlen);
>  
>  		/* Virtual addresses are sign-extended; physical addresses are zero-extended. */
>  		if (IS_ENABLED(CONFIG_MMU))
> @@ -33,12 +33,16 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, unsigne
>  	(__force __typeof__(addr))__untagged_addr_remote(current->mm, __addr);	\
>  })
>  
> -#define untagged_addr_remote(mm, addr) ({					\
> +#define untagged_addr_remote_unlocked(mm, addr) ({				\
>  	unsigned long __addr = (__force unsigned long)(addr);			\
> -	mmap_assert_locked(mm);							\
>  	(__force __typeof__(addr))__untagged_addr_remote(mm, __addr);		\
>  })
>  
> +#define untagged_addr_remote(mm, addr) ({					\
> +	mmap_assert_locked(mm);							\
> +	untagged_addr_remote_unlocked(mm, addr);				\
> +})
> +
>  #define access_ok(addr, size) likely(__access_ok(untagged_addr(addr), size))
>  #else
>  #define untagged_addr(addr) (addr)
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index b2df7f72241a..6ae7552fed09 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -357,13 +357,15 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
>  	if (mmap_write_lock_killable(mm))
>  		return -EINTR;
>  
> -	if (test_bit(MM_CONTEXT_LOCK_PMLEN, &mm->context.flags) && mm->context.pmlen != pmlen) {
> -		mmap_write_unlock(mm);
> -		return -EBUSY;
> +	if (test_bit(MM_CONTEXT_LOCK_PMLEN, &mm->context.flags)) {
> +		if (READ_ONCE(mm->context.pmlen) != pmlen) {
> +			mmap_write_unlock(mm);
> +			return -EBUSY;
> +		}
>  	}
>  
>  	envcfg_update_bits(task, ENVCFG_PMM, pmm);
> -	mm->context.pmlen = pmlen;
> +	WRITE_ONCE(mm->context.pmlen, pmlen);
>  
>  	mmap_write_unlock(mm);
>  
> @@ -394,7 +396,7 @@ long get_tagged_addr_ctrl(struct task_struct *task)
>  		break;
>  	}
>  
> -	if (task->mm->context.pmlen)
> +	if (READ_ONCE(task->mm->context.pmlen))
>  		ret |= PR_TAGGED_ADDR_ENABLE;
>  
>  	return ret;
> -- 
> 2.53.0-Meta
> 
> 

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-20 11:57   ` Usama Arif
@ 2026-07-20 15:08     ` Rik van Riel
  2026-07-20 16:46       ` Usama Arif
  0 siblings, 1 reply; 8+ messages in thread
From: Rik van Riel @ 2026-07-20 15:08 UTC (permalink / raw)
  To: Usama Arif
  Cc: linux-kernel, Andrew Morton, kernel-team, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv

On Mon, 2026-07-20 at 04:57 -0700, Usama Arif wrote:
> On Fri, 17 Jul 2026 13:00:32 -0400 Rik van Riel <riel@surriel.com>
> wrote:
> 
> 
> > 
> > mm->context.pmlen is set only through PR_SET_TAGGED_ADDR_CTRL and
> > is stable
> > afterwards, so it can be read without the mmap lock, as it already
> > is from
> > untagged_addr() and mm_untag_mask().
> > 
> 
> I think it might not be stable? set_tagged_addr_ctrl() can change it
> repeatedly until a CLONE_VM operation sets MM_CONTEXT_LOCK_PMLEN.

You're right, ARM tagged addresses seem to work a
little differently from x86 LAM.

It looks like on ARM with MTE, the top 8 bits of
the virtual address are available as tags, meaning
that address space cannot be used for VMAs.

For purposes of accessing process memory, this
is a little more stable than LAM, because the
number of bits we need to mask out of the address
is always the same when MTE is in use.

At least, I think so. Am I overlooking anything?

I will clean up the changelog like you suggested.

-- 
All Rights Reversed.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-20 15:08     ` Rik van Riel
@ 2026-07-20 16:46       ` Usama Arif
  2026-07-20 17:34         ` Rik van Riel
  0 siblings, 1 reply; 8+ messages in thread
From: Usama Arif @ 2026-07-20 16:46 UTC (permalink / raw)
  To: Rik van Riel
  Cc: linux-kernel, Andrew Morton, kernel-team, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv



On 20/07/2026 16:08, Rik van Riel wrote:
> On Mon, 2026-07-20 at 04:57 -0700, Usama Arif wrote:
>> On Fri, 17 Jul 2026 13:00:32 -0400 Rik van Riel <riel@surriel.com>
>> wrote:
>>
>>
>>>
>>> mm->context.pmlen is set only through PR_SET_TAGGED_ADDR_CTRL and
>>> is stable
>>> afterwards, so it can be read without the mmap lock, as it already
>>> is from
>>> untagged_addr() and mm_untag_mask().
>>>
>>
>> I think it might not be stable? set_tagged_addr_ctrl() can change it
>> repeatedly until a CLONE_VM operation sets MM_CONTEXT_LOCK_PMLEN.
> 
> You're right, ARM tagged addresses seem to work a

ah do you mean RISCV here?

> little differently from x86 LAM.
> 
> It looks like on ARM with MTE, the top 8 bits of
> the virtual address are available as tags, meaning
> that address space cannot be used for VMAs.
> 
> For purposes of accessing process memory, this
> is a little more stable than LAM, because the
> number of bits we need to mask out of the address
> is always the same when MTE is in use.
> 
> At least, I think so. Am I overlooking anything?
> 
> I will clean up the changelog like you suggested.
> 


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-20 16:46       ` Usama Arif
@ 2026-07-20 17:34         ` Rik van Riel
  2026-07-20 18:46           ` Usama Arif
  0 siblings, 1 reply; 8+ messages in thread
From: Rik van Riel @ 2026-07-20 17:34 UTC (permalink / raw)
  To: Usama Arif
  Cc: linux-kernel, Andrew Morton, kernel-team, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv

On Mon, 2026-07-20 at 17:46 +0100, Usama Arif wrote:
> 
> 
> On 20/07/2026 16:08, Rik van Riel wrote:
> > On Mon, 2026-07-20 at 04:57 -0700, Usama Arif wrote:
> > > On Fri, 17 Jul 2026 13:00:32 -0400 Rik van Riel
> > > <riel@surriel.com>
> > > wrote:
> > > 
> > > 
> > > > 
> > > > mm->context.pmlen is set only through PR_SET_TAGGED_ADDR_CTRL
> > > > and
> > > > is stable
> > > > afterwards, so it can be read without the mmap lock, as it
> > > > already
> > > > is from
> > > > untagged_addr() and mm_untag_mask().
> > > > 
> > > 
> > > I think it might not be stable? set_tagged_addr_ctrl() can change
> > > it
> > > repeatedly until a CLONE_VM operation sets MM_CONTEXT_LOCK_PMLEN.
> > 
> > You're right, ARM tagged addresses seem to work a
> 
> ah do you mean RISCV here?

Ugh, I looked at the wrong one.  RISCV is like
x86, with a dynamic (though a limited number
of options?) mask.

Having said that, won't a process have all of
its VMAs in the masked-off area, so coming in
from a remote process to a valid memory address
should already give us a valid address?

-- 
All Rights Reversed.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-20 17:34         ` Rik van Riel
@ 2026-07-20 18:46           ` Usama Arif
  2026-07-20 19:21             ` Rik van Riel
  0 siblings, 1 reply; 8+ messages in thread
From: Usama Arif @ 2026-07-20 18:46 UTC (permalink / raw)
  To: Rik van Riel
  Cc: linux-kernel, Andrew Morton, kernel-team, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv



On 20/07/2026 18:34, Rik van Riel wrote:
> On Mon, 2026-07-20 at 17:46 +0100, Usama Arif wrote:
>>
>>
>> On 20/07/2026 16:08, Rik van Riel wrote:
>>> On Mon, 2026-07-20 at 04:57 -0700, Usama Arif wrote:
>>>> On Fri, 17 Jul 2026 13:00:32 -0400 Rik van Riel
>>>> <riel@surriel.com>
>>>> wrote:
>>>>
>>>>
>>>>>
>>>>> mm->context.pmlen is set only through PR_SET_TAGGED_ADDR_CTRL
>>>>> and
>>>>> is stable
>>>>> afterwards, so it can be read without the mmap lock, as it
>>>>> already
>>>>> is from
>>>>> untagged_addr() and mm_untag_mask().
>>>>>
>>>>
>>>> I think it might not be stable? set_tagged_addr_ctrl() can change
>>>> it
>>>> repeatedly until a CLONE_VM operation sets MM_CONTEXT_LOCK_PMLEN.
>>>
>>> You're right, ARM tagged addresses seem to work a
>>
>> ah do you mean RISCV here?
> 
> Ugh, I looked at the wrong one.  RISCV is like
> x86, with a dynamic (though a limited number
> of options?) mask.
> 
> Having said that, won't a process have all of
> its VMAs in the masked-off area, so coming in
> from a remote process to a valid memory address
> should already give us a valid address?
> 

So my understanding from exploring this code is, and hopefully someone
in CC from riscv can correct me, for example:

Tagged pointer:  0xabcd000012345678
PMLEN 16:        0x0000000012345678
PMLEN 7:         0xffcd000012345678

The target VMA might be at 0x12345678, but applying PMLEN 7
to that tagged pointer does not produce that address.

Previously, the order was:

Take mmap read lock.
Read pmlen.
Untag the address.
Look up the VMA.

Changing PMLEN takes the mmap write lock. The read and write
operations were therefore serialized.

The new order is:

Read pmlen without mmap lock.
Untag the address.
Attempt the per-VMA lookup.
Possibly take mmap lock later.
Continue using the already-untagged address.

A concurrent PMLEN change can occur between those operations?



_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-20 18:46           ` Usama Arif
@ 2026-07-20 19:21             ` Rik van Riel
  2026-07-20 19:39               ` Usama Arif
  0 siblings, 1 reply; 8+ messages in thread
From: Rik van Riel @ 2026-07-20 19:21 UTC (permalink / raw)
  To: Usama Arif
  Cc: linux-kernel, Andrew Morton, kernel-team, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv

On Mon, 2026-07-20 at 19:46 +0100, Usama Arif wrote:
> 
> So my understanding from exploring this code is, and hopefully
> someone
> in CC from riscv can correct me, for example:
> 
> Tagged pointer:  0xabcd000012345678
> PMLEN 16:        0x0000000012345678
> PMLEN 7:         0xffcd000012345678
> 
> The target VMA might be at 0x12345678, but applying PMLEN 7
> to that tagged pointer does not produce that address.
> 
> Previously, the order was:
> 
> Take mmap read lock.
> Read pmlen.
> Untag the address.
> Look up the VMA.
> 
> Changing PMLEN takes the mmap write lock. The read and write
> operations were therefore serialized.
> 
> The new order is:
> 
> Read pmlen without mmap lock.
> Untag the address.
> Attempt the per-VMA lookup.
> Possibly take mmap lock later.
> Continue using the already-untagged address.
> 
> A concurrent PMLEN change can occur between those operations?

I suppose it could, but what are the possible outcomes here?

- We fail to untag the address, the vma lookup
  fails, and we fail to access memory.

- The address is already untagged, maps to a
  VMA, and the access succeeds.

Are there any others?

The VMAs of the process need to be in the bottom
part of the address space, right? The part where
untagged addresses sit.

For things like /proc/<pid>/cmdline we should
automatically get an address without any of the
high bits set.

For things like ptrace peek / poke, BPF process
accesses, and others, I really do not know if
those could get tagged addresses...

What are the failures we need to protect against?

What if something comes in with a tagged address,
but the process disables tagging while that
something waits for the mmap_lock?

Does that reproduce the failure case, without
any locking changes?
> 

> 

-- 
All Rights Reversed.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked()
  2026-07-20 19:21             ` Rik van Riel
@ 2026-07-20 19:39               ` Usama Arif
  0 siblings, 0 replies; 8+ messages in thread
From: Usama Arif @ 2026-07-20 19:39 UTC (permalink / raw)
  To: Rik van Riel
  Cc: linux-kernel, Andrew Morton, kernel-team, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, linux-mm, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv



On 20/07/2026 20:21, Rik van Riel wrote:
> On Mon, 2026-07-20 at 19:46 +0100, Usama Arif wrote:
>>
>> So my understanding from exploring this code is, and hopefully
>> someone
>> in CC from riscv can correct me, for example:
>>
>> Tagged pointer:  0xabcd000012345678
>> PMLEN 16:        0x0000000012345678
>> PMLEN 7:         0xffcd000012345678
>>
>> The target VMA might be at 0x12345678, but applying PMLEN 7
>> to that tagged pointer does not produce that address.
>>
>> Previously, the order was:
>>
>> Take mmap read lock.
>> Read pmlen.
>> Untag the address.
>> Look up the VMA.
>>
>> Changing PMLEN takes the mmap write lock. The read and write
>> operations were therefore serialized.
>>
>> The new order is:
>>
>> Read pmlen without mmap lock.
>> Untag the address.
>> Attempt the per-VMA lookup.
>> Possibly take mmap lock later.
>> Continue using the already-untagged address.
>>
>> A concurrent PMLEN change can occur between those operations?
> 
> I suppose it could, but what are the possible outcomes here?
> 
> - We fail to untag the address, the vma lookup
>   fails, and we fail to access memory.
> 
> - The address is already untagged, maps to a
>   VMA, and the access succeeds.
> 
> Are there any others?
> 
> The VMAs of the process need to be in the bottom
> part of the address space, right? The part where
> untagged addresses sit.
> 
> For things like /proc/<pid>/cmdline we should
> automatically get an address without any of the
> high bits set.
> 
> For things like ptrace peek / poke, BPF process
> accesses, and others, I really do not know if
> those could get tagged addresses...
> 
> What are the failures we need to protect against?
> 
> What if something comes in with a tagged address,
> but the process disables tagging while that
> something waits for the mmap_lock?

So I think the above question is what needs to be
answered.
A tagged pointer can become invalid if PMLEN changes
before the old mmap-locked lookup too.
The mmap lock only defined whether the lookup observed
the old or new mode.

For VMA as you said, it should be ok. I don't know about
others. I think it would be best to get input from
RISC-V folks for this. Hopefully its ok..
If it is ok, then all that would be need to be done
is to just remove in the commit message that pmlen
is stable.

> 
> Does that reproduce the failure case, without
> any locking changes?




_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-07-20 19:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260717170036.743149-1-riel@surriel.com>
2026-07-17 17:00 ` [PATCH RFC v3 2/6] riscv/mm: add untagged_addr_remote_unlocked() Rik van Riel
2026-07-20 11:57   ` Usama Arif
2026-07-20 15:08     ` Rik van Riel
2026-07-20 16:46       ` Usama Arif
2026-07-20 17:34         ` Rik van Riel
2026-07-20 18:46           ` Usama Arif
2026-07-20 19:21             ` Rik van Riel
2026-07-20 19:39               ` Usama Arif

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox