Re: [PATCH RFC] arch/riscv: add proc status (proc/<pid>/status)

From: Deepak Gupta

Date: Wed Oct 22 2025 - 20:38:14 EST


Hi Hienrich,


On Tue, Oct 21, 2025 at 01:13:36PM +0200, Heinrich Schuchardt wrote:
On 10/20/25 20:18, Deepak Gupta wrote:
x86 has proc/<pid>/status to see various runtime characteristics
of running task. Implement same for riscv. This patch implements
status for shadow stack and landing pad state.

Signed-off-by: Deepak Gupta <debug@xxxxxxxxxxxx>
---
This is just a one patch but sending it as RFC with cover letter to seek
feedback. x86 has `arch_proc_pid_thread_features` to enumerate status of
arch thread specific features on runtime. This can be done using prctl
as well but from quick/script perspective `cat /proc/<pid>/status` is more
desirable. In this patch, simply `arch_proc_pid_thread_features` is implemented
for riscv which queries shadow stack and landing pad state and reports back.
Thus it is dependent on riscv user cfi enabling series.

Hello Deepak,

This looks like a valuable addition.

Shouldn't architecture specific fields be in
/proc/<pid>/arch_status and not in /proc/<pid>/status?

Just following what x86 did. I believe shadow stack and landing pad are there
in arm64, x86 and riscv. So probably /proc/<pid>/status is best place.

Please, add a documentation patch adding the RISC-V specific fields to
"3.12 /proc/<pid>/arch_status - Task architecture specific information"
in Documentation/filesystems/proc.rst.

Should you stick to /proc/*/status, please, add the documentation to Documentation/arch/riscv/.

Will do.



If this patch itself is self-standing and good enough, I can roll this patch
as part of riscv user cfi enabling series.

OR

If there is ask for other riscv thread specific features that could be
enumerated in similar fashion, we will need it to be done as separate series
(with `thread_features` added to `thread_info`)

Example output below.

Name: cat
Umask: 0022
State: R (running)
Tgid: 133
Ngid: 0
Pid: 133
PPid: 129
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256
Groups: 0 10
NStgid: 133
NSpid: 133
NSpgid: 133
NSsid: 129
Kthread: 0
VmPeak: 10788 kB
VmSize: 10788 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 1400 kB
VmRSS: 1400 kB
RssAnon: 116 kB
RssFile: 1284 kB
RssShmem: 0 kB
VmData: 92 kB
VmStk: 8324 kB
VmExe: 4 kB
VmLib: 2312 kB
VmPTE: 40 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
THP_enabled: 0
untag_mask: 0xffffffffffffffff
Threads: 1
SigQ: 0/31771
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
Speculation_Store_Bypass: unknown
SpeculationIndirectBranch: unsupported
Cpus_allowed: 3
Cpus_allowed_list: 0-1
Mems_allowed: 1
Mems_allowed_list: 0
voluntary_ctxt_switches: 0
nonvoluntary_ctxt_switches: 3
riscv_thread_features: shstk_enabled lpad_enabled
riscv_thread_features_locked: shstk_unlocked lpad_unlocked
---
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/cpu/Makefile | 1 +
arch/riscv/kernel/cpu/proc.c | 28 ++++++++++++++++++++++++++++
3 files changed, 30 insertions(+)

diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index f60fce69b725..b32c11667d81 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -71,6 +71,7 @@ obj-y += vendor_extensions.o
obj-y += vendor_extensions/
obj-y += probes/
obj-y += tests/
+obj-y += cpu/
obj-$(CONFIG_MMU) += vdso.o vdso/
obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o
diff --git a/arch/riscv/kernel/cpu/Makefile b/arch/riscv/kernel/cpu/Makefile
new file mode 100644
index 000000000000..2b474fb49afe
--- /dev/null
+++ b/arch/riscv/kernel/cpu/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/arch/riscv/kernel/cpu/proc.c b/arch/riscv/kernel/cpu/proc.c
new file mode 100644
index 000000000000..4661190c43d1
--- /dev/null
+++ b/arch/riscv/kernel/cpu/proc.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/smp.h>
+#include <linux/timex.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <asm/usercfi.h>
+
+#ifdef CONFIG_RISCV_USER_CFI
+
+void arch_proc_pid_thread_features(struct seq_file *m, struct task_struct *task)
+{
+ seq_puts(m, "riscv_thread_features:\t");
+ if (is_shstk_enabled(task))
+ seq_puts(m, "shstk_enabled ");

According to Documentation/arch/x86/shstk.rst, x86 is avoiding the '_enabled' postfix here:

x86_Thread_features: shstk wrss

I can follow same and use `shstk`. We don't have `wrss` because
shadow stack is writeable by right instruction (sspush and ssamoswap) in
riscv.


+
+ if (is_indir_lp_enabled(task))
+ seq_puts(m, "lpad_enabled ");

Would you prefer similar here. Just "lpad"?

+
+ seq_putc(m, '\n');
+
+ seq_puts(m, "riscv_thread_features_locked:\t");
+ is_shstk_locked(task) ? seq_puts(m, "shstk_locked ") : seq_puts(m, "shstk_unlocked ");
+ is_indir_lp_locked(task) ? seq_puts(m, "lpad_locked ") : seq_puts(m, "lpad_unlocked ");

Why do we need any entry for an unlocked feature in riscv_thread_features_locked?

absence of "feature_locked" is considered unlocked, then I can drop it.


Best regards

Heinrich

+ seq_putc(m, '\n');
+}
+#endif /* CONFIG_RISCV_USER_CFI */

---
base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
change-id: 20251017-proc_status-df1aedc85c7c
--
- debug