Skip to content

Commit 075fde5

Browse files
Merge patch series "riscv: Userspace pointer masking and tagged address ABI"
Samuel Holland <samuel.holland@sifive.com> says: RISC-V defines three extensions for pointer masking[1]: - Smmpm: configured in M-mode, affects M-mode - Smnpm: configured in M-mode, affects the next lower mode (S or U-mode) - Ssnpm: configured in S-mode, affects the next lower mode (VS, VU, or U-mode) This series adds support for configuring Smnpm or Ssnpm (depending on which privilege mode the kernel is running in) to allow pointer masking in userspace (VU or U-mode), extending the PR_SET_TAGGED_ADDR_CTRL API from arm64. Unlike arm64 TBI, userspace pointer masking is not enabled by default on RISC-V. Additionally, the tag width (referred to as PMLEN) is variable, so userspace needs to ask the kernel for a specific tag width, which is interpreted as a lower bound on the number of tag bits. This series also adds support for a tagged address ABI similar to arm64 and x86. Since accesses from the kernel to user memory use the kernel's pointer masking configuration, not the user's, the kernel must untag user pointers in software before dereferencing them. And since the tag width is variable, as with LAM on x86, it must be kept the same across all threads in a process so untagged_addr_remote() can work. [1]: https://github.com/riscv/riscv-j-extension/raw/d70011dde6c2/zjpm-spec.pdf * b4-shazam-merge: KVM: riscv: selftests: Add Smnpm and Ssnpm to get-reg-list test RISC-V: KVM: Allow Smnpm and Ssnpm extensions for guests riscv: hwprobe: Export the Supm ISA extension riscv: selftests: Add a pointer masking test riscv: Allow ptrace control of the tagged address ABI riscv: Add support for the tagged address ABI riscv: Add support for userspace pointer masking riscv: Add CSR definitions for pointer masking riscv: Add ISA extension parsing for pointer masking dt-bindings: riscv: Add pointer masking ISA extensions Link: https://lore.kernel.org/r/20241016202814.4061541-1-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2 parents ce16531 + 036a140 commit 075fde5

File tree

25 files changed

+712
-7
lines changed

25 files changed

+712
-7
lines changed

Documentation/arch/riscv/hwprobe.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ The following keys are defined:
239239
ratified in commit 98918c844281 ("Merge pull request #1217 from
240240
riscv/zawrs") of riscv-isa-manual.
241241

242+
* :c:macro:`RISCV_HWPROBE_EXT_SUPM`: The Supm extension is supported as
243+
defined in version 1.0 of the RISC-V Pointer Masking extensions.
244+
242245
* :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated. Returns similar values to
243246
:c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
244247
mistakenly classified as a bitmask rather than a value.

Documentation/arch/riscv/uabi.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,19 @@ Misaligned accesses
6868
Misaligned scalar accesses are supported in userspace, but they may perform
6969
poorly. Misaligned vector accesses are only supported if the Zicclsm extension
7070
is supported.
71+
72+
Pointer masking
73+
---------------
74+
75+
Support for pointer masking in userspace (the Supm extension) is provided via
76+
the ``PR_SET_TAGGED_ADDR_CTRL`` and ``PR_GET_TAGGED_ADDR_CTRL`` ``prctl()``
77+
operations. Pointer masking is disabled by default. To enable it, userspace
78+
must call ``PR_SET_TAGGED_ADDR_CTRL`` with the ``PR_PMLEN`` field set to the
79+
number of mask/tag bits needed by the application. ``PR_PMLEN`` is interpreted
80+
as a lower bound; if the kernel is unable to satisfy the request, the
81+
``PR_SET_TAGGED_ADDR_CTRL`` operation will fail. The actual number of tag bits
82+
is returned in ``PR_PMLEN`` by the ``PR_GET_TAGGED_ADDR_CTRL`` operation.
83+
84+
Additionally, when pointer masking is enabled (``PR_PMLEN`` is greater than 0),
85+
a tagged address ABI is supported, with the same interface and behavior as
86+
documented for AArch64 (Documentation/arch/arm64/tagged-address-abi.rst).

Documentation/devicetree/bindings/riscv/extensions.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,18 @@ properties:
128128
changes to interrupts as frozen at commit ccbddab ("Merge pull
129129
request #42 from riscv/jhauser-2023-RC4") of riscv-aia.
130130
131+
- const: smmpm
132+
description: |
133+
The standard Smmpm extension for M-mode pointer masking as
134+
ratified at commit d70011dde6c2 ("Update to ratified state")
135+
of riscv-j-extension.
136+
137+
- const: smnpm
138+
description: |
139+
The standard Smnpm extension for next-mode pointer masking as
140+
ratified at commit d70011dde6c2 ("Update to ratified state")
141+
of riscv-j-extension.
142+
131143
- const: smstateen
132144
description: |
133145
The standard Smstateen extension for controlling access to CSRs
@@ -147,6 +159,12 @@ properties:
147159
and mode-based filtering as ratified at commit 01d1df0 ("Add ability
148160
to manually trigger workflow. (#2)") of riscv-count-overflow.
149161
162+
- const: ssnpm
163+
description: |
164+
The standard Ssnpm extension for next-mode pointer masking as
165+
ratified at commit d70011dde6c2 ("Update to ratified state")
166+
of riscv-j-extension.
167+
150168
- const: sstc
151169
description: |
152170
The standard Sstc supervisor-level extension for time compare as

arch/riscv/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,17 @@ config RISCV_ISA_C
531531

532532
If you don't know what to do here, say Y.
533533

534+
config RISCV_ISA_SUPM
535+
bool "Supm extension for userspace pointer masking"
536+
depends on 64BIT
537+
default y
538+
help
539+
Add support for pointer masking in userspace (Supm) when the
540+
underlying hardware extension (Smnpm or Ssnpm) is detected at boot.
541+
542+
If this option is disabled, userspace will be unable to use
543+
the prctl(PR_{SET,GET}_TAGGED_ADDR_CTRL) API.
544+
534545
config RISCV_ISA_SVNAPOT
535546
bool "Svnapot extension support for supervisor mode NAPOT pages"
536547
depends on 64BIT && MMU

arch/riscv/include/asm/csr.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@
119119

120120
/* HSTATUS flags */
121121
#ifdef CONFIG_64BIT
122+
#define HSTATUS_HUPMM _AC(0x3000000000000, UL)
123+
#define HSTATUS_HUPMM_PMLEN_0 _AC(0x0000000000000, UL)
124+
#define HSTATUS_HUPMM_PMLEN_7 _AC(0x2000000000000, UL)
125+
#define HSTATUS_HUPMM_PMLEN_16 _AC(0x3000000000000, UL)
122126
#define HSTATUS_VSXL _AC(0x300000000, UL)
123127
#define HSTATUS_VSXL_SHIFT 32
124128
#endif
@@ -195,6 +199,10 @@
195199
/* xENVCFG flags */
196200
#define ENVCFG_STCE (_AC(1, ULL) << 63)
197201
#define ENVCFG_PBMTE (_AC(1, ULL) << 62)
202+
#define ENVCFG_PMM (_AC(0x3, ULL) << 32)
203+
#define ENVCFG_PMM_PMLEN_0 (_AC(0x0, ULL) << 32)
204+
#define ENVCFG_PMM_PMLEN_7 (_AC(0x2, ULL) << 32)
205+
#define ENVCFG_PMM_PMLEN_16 (_AC(0x3, ULL) << 32)
198206
#define ENVCFG_CBZE (_AC(1, UL) << 7)
199207
#define ENVCFG_CBCFE (_AC(1, UL) << 6)
200208
#define ENVCFG_CBIE_SHIFT 4
@@ -216,6 +224,12 @@
216224
#define SMSTATEEN0_SSTATEEN0_SHIFT 63
217225
#define SMSTATEEN0_SSTATEEN0 (_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT)
218226

227+
/* mseccfg bits */
228+
#define MSECCFG_PMM ENVCFG_PMM
229+
#define MSECCFG_PMM_PMLEN_0 ENVCFG_PMM_PMLEN_0
230+
#define MSECCFG_PMM_PMLEN_7 ENVCFG_PMM_PMLEN_7
231+
#define MSECCFG_PMM_PMLEN_16 ENVCFG_PMM_PMLEN_16
232+
219233
/* symbolic CSR names: */
220234
#define CSR_CYCLE 0xc00
221235
#define CSR_TIME 0xc01
@@ -382,6 +396,8 @@
382396
#define CSR_MIP 0x344
383397
#define CSR_PMPCFG0 0x3a0
384398
#define CSR_PMPADDR0 0x3b0
399+
#define CSR_MSECCFG 0x747
400+
#define CSR_MSECCFGH 0x757
385401
#define CSR_MVENDORID 0xf11
386402
#define CSR_MARCHID 0xf12
387403
#define CSR_MIMPID 0xf13

arch/riscv/include/asm/hwcap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
#define RISCV_ISA_EXT_ZCMOP 84
9494
#define RISCV_ISA_EXT_ZAWRS 85
9595
#define RISCV_ISA_EXT_SVVPTC 86
96+
#define RISCV_ISA_EXT_SMMPM 87
97+
#define RISCV_ISA_EXT_SMNPM 88
98+
#define RISCV_ISA_EXT_SSNPM 89
9699

97100
#define RISCV_ISA_EXT_XLINUXENVCFG 127
98101

@@ -101,8 +104,10 @@
101104

102105
#ifdef CONFIG_RISCV_M_MODE
103106
#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SMAIA
107+
#define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SMNPM
104108
#else
105109
#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SSAIA
110+
#define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SSNPM
106111
#endif
107112

108113
#endif /* _ASM_RISCV_HWCAP_H */

arch/riscv/include/asm/mmu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,16 @@ typedef struct {
2525
#ifdef CONFIG_BINFMT_ELF_FDPIC
2626
unsigned long exec_fdpic_loadmap;
2727
unsigned long interp_fdpic_loadmap;
28+
#endif
29+
unsigned long flags;
30+
#ifdef CONFIG_RISCV_ISA_SUPM
31+
u8 pmlen;
2832
#endif
2933
} mm_context_t;
3034

35+
/* Lock the pointer masking mode because this mm is multithreaded */
36+
#define MM_CONTEXT_LOCK_PMLEN 0
37+
3138
#define cntx2asid(cntx) ((cntx) & SATP_ASID_MASK)
3239
#define cntx2version(cntx) ((cntx) & ~SATP_ASID_MASK)
3340

arch/riscv/include/asm/mmu_context.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
2020
static inline void activate_mm(struct mm_struct *prev,
2121
struct mm_struct *next)
2222
{
23+
#ifdef CONFIG_RISCV_ISA_SUPM
24+
next->context.pmlen = 0;
25+
#endif
2326
switch_mm(prev, next, NULL);
2427
}
2528

@@ -30,11 +33,21 @@ static inline int init_new_context(struct task_struct *tsk,
3033
#ifdef CONFIG_MMU
3134
atomic_long_set(&mm->context.id, 0);
3235
#endif
36+
if (IS_ENABLED(CONFIG_RISCV_ISA_SUPM))
37+
clear_bit(MM_CONTEXT_LOCK_PMLEN, &mm->context.flags);
3338
return 0;
3439
}
3540

3641
DECLARE_STATIC_KEY_FALSE(use_asid_allocator);
3742

43+
#ifdef CONFIG_RISCV_ISA_SUPM
44+
#define mm_untag_mask mm_untag_mask
45+
static inline unsigned long mm_untag_mask(struct mm_struct *mm)
46+
{
47+
return -1UL >> mm->context.pmlen;
48+
}
49+
#endif
50+
3851
#include <asm-generic/mmu_context.h>
3952

4053
#endif /* _ASM_RISCV_MMU_CONTEXT_H */

arch/riscv/include/asm/processor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,14 @@ extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
178178
#define RISCV_SET_ICACHE_FLUSH_CTX(arg1, arg2) riscv_set_icache_flush_ctx(arg1, arg2)
179179
extern int riscv_set_icache_flush_ctx(unsigned long ctx, unsigned long per_thread);
180180

181+
#ifdef CONFIG_RISCV_ISA_SUPM
182+
/* PR_{SET,GET}_TAGGED_ADDR_CTRL prctl */
183+
long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg);
184+
long get_tagged_addr_ctrl(struct task_struct *task);
185+
#define SET_TAGGED_ADDR_CTRL(arg) set_tagged_addr_ctrl(current, arg)
186+
#define GET_TAGGED_ADDR_CTRL() get_tagged_addr_ctrl(current)
187+
#endif
188+
181189
#endif /* __ASSEMBLY__ */
182190

183191
#endif /* _ASM_RISCV_PROCESSOR_H */

arch/riscv/include/asm/switch_to.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ static __always_inline bool has_fpu(void) { return false; }
7070
#define __switch_to_fpu(__prev, __next) do { } while (0)
7171
#endif
7272

73+
static inline void envcfg_update_bits(struct task_struct *task,
74+
unsigned long mask, unsigned long val)
75+
{
76+
unsigned long envcfg;
77+
78+
envcfg = (task->thread.envcfg & ~mask) | val;
79+
task->thread.envcfg = envcfg;
80+
if (task == current)
81+
csr_write(CSR_ENVCFG, envcfg);
82+
}
83+
7384
static inline void __switch_to_envcfg(struct task_struct *next)
7485
{
7586
asm volatile (ALTERNATIVE("nop", "csrw " __stringify(CSR_ENVCFG) ", %0",

0 commit comments

Comments
 (0)