Backport subject : Userspace pointer masking and tagged address ABI#336
Backport subject : Userspace pointer masking and tagged address ABI#336fangyu0809 wants to merge 10 commits into
Conversation
mainline inclusion from Linux 6.13-rc1 commit 29eedc7 category: feature bugzilla: RVCK-Project#335 -------------------------------- Pointer masking is controlled via a two-bit PMM field, which appears in various CSRs depending on which extensions are implemented. Smmpm adds the field to mseccfg; Smnpm adds the field to menvcfg; Ssnpm adds the field to senvcfg. If the H extension is implemented, Ssnpm also defines henvcfg.PMM and hstatus.HUPMM. Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20241016202814.4061541-4-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.13-rc1 commit 09d6775 category: feature bugzilla: RVCK-Project#335 -------------------------------- RISC-V supports pointer masking with a variable number of tag bits (which is called "PMLEN" in the specification) and which is configured at the next higher privilege level. Wire up the PR_SET_TAGGED_ADDR_CTRL and PR_GET_TAGGED_ADDR_CTRL prctls so userspace can request a lower bound on the number of tag bits and determine the actual number of tag bits. As with arm64's PR_TAGGED_ADDR_ENABLE, the pointer masking configuration is thread-scoped, inherited on clone() and fork() and cleared on execve(). Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Tested-by: Charlie Jenkins <charlie@rivosinc.com> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20241016202814.4061541-5-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.13-rc1 commit 2e17430 category: feature bugzilla: RVCK-Project#335 Backport note: RVCK already contains mm_untag_mask() in arch/riscv/include/asm/mmu_context.h from commit 97644be (riscv/shstk: If needed allocate a new shadow stack on clone), so this backport does not add that hunk again and only adds the remaining pmlen/context locking changes. -------------------------------- When pointer masking is enabled for userspace, the kernel can accept tagged pointers as arguments to some system calls. Allow this by untagging the pointers in access_ok() and the uaccess routines. The uaccess routines must peform untagging in software because U-mode and S-mode have entirely separate pointer masking configurations. In fact, hardware may not even implement pointer masking for S-mode. Since the number of tag bits is variable, untagged_addr_remote() needs to know what PMLEN to use for the remote mm. Therefore, the pointer masking mode must be the same for all threads sharing an mm. Enforce this with a lock flag in the mm context, as x86 does for LAM. The flag gets reset in init_new_context() during fork(), as the new mm is no longer multithreaded. Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Tested-by: Charlie Jenkins <charlie@rivosinc.com> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20241016202814.4061541-6-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.13-rc1 commit 7884448 category: feature bugzilla: RVCK-Project#335 -------------------------------- This allows a tracer to control the ABI of the tracee, as on arm64. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20241016202814.4061541-7-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.13-rc1 commit 7470b5a category: feature bugzilla: RVCK-Project#335 Backport note: RVCK already has local sse and cfi RISC-V selftest targets, and this tree does not have the upstream sigreturn selftest directory. This backport only adds the new abi target while preserving the existing RVCK-local sse/cfi entries and not adding the sigreturn context. -------------------------------- This test covers the behavior of the PR_SET_TAGGED_ADDR_CTRL and PR_GET_TAGGED_ADDR_CTRL prctl() operations, their effects on the userspace ABI, and their effects on the system call ABI. Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Tested-by: Charlie Jenkins <charlie@rivosinc.com> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20241016202814.4061541-8-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.13-rc1 commit 036a140 category: feature bugzilla: RVCK-Project#335 -------------------------------- Add testing for the pointer masking extensions exposed to KVM guests. Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20241016202814.4061541-11-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.9-rc1 commit 9dc3041 category: feature bugzilla: RVCK-Project#335 -------------------------------- There is some code that detects compat mode into a task by checking the flag directly, and other code that check using the helper is_compat_task(). Since the helper already exists, use it instead of checking the flags directly. Signed-off-by: Leonardo Bras <leobras@redhat.com> Link: https://lore.kernel.org/r/20240103160024.70305-4-leobras@redhat.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.9-rc1 commit 4c0b5a4 category: feature bugzilla: RVCK-Project#335 Backport note: The upstream processor.h hunks update the old arch_get_mmap_end()/arch_get_mmap_base() logic, but RVCK already contains the later stable fix f5f235b (upstream commit 2116988) which simplified those macros. Those hunks no longer apply and are intentionally omitted. -------------------------------- Currently several places will test for CONFIG_COMPAT before testing is_compat_task(), probably in order to avoid a run-time test into the task structure. Since is_compat_task() is an inlined function, it would be helpful to add a compile-time test of CONFIG_COMPAT, making sure it always returns zero when the option is not enabled during the kernel build. With this, the compiler is able to understand in build-time that is_compat_task() will always return 0, and optimize-out some of the extra code introduced by the option. This will also allow removing a lot #ifdefs that were introduced, and make the code more clean. Signed-off-by: Leonardo Bras <leobras@redhat.com> Reviewed-by: Guo Ren <guoren@kernel.org> Reviewed-by: Andy Chiu <andy.chiu@sifive.com> Link: https://lore.kernel.org/r/20240103160024.70305-5-leobras@redhat.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.9-rc1 commit 5917ea1 category: feature bugzilla: RVCK-Project#335 -------------------------------- task_user_regset_view() makes use of a function very similar to is_compat_task(), but pointing to a any thread. In arm64 asm/compat.h there is a function very similar to that: is_compat_thread(struct thread_info *thread) Copy this function to riscv asm/compat.h and make use of it into task_user_regset_view(). Also, introduce a compile-time test for CONFIG_COMPAT and simplify the function code by removing the #ifdef. Signed-off-by: Leonardo Bras <leobras@redhat.com> Reviewed-by: Guo Ren <guoren@kernel.org> Reviewed-by: Andy Chiu <andy.chiu@sifive.com> Link: https://lore.kernel.org/r/20240103160024.70305-6-leobras@redhat.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
mainline inclusion from Linux 6.9-rc1 commit 2a8986f category: feature bugzilla: RVCK-Project#335 -------------------------------- In order to have all task compat bit access directly in compat.h, introduce set_compat_task() to set/reset those when needed. Also, since it's only used on an if/else scenario, simplify the macro using it. Signed-off-by: Leonardo Bras <leobras@redhat.com> Reviewed-by: Guo Ren <guoren@kernel.org> Link: https://lore.kernel.org/r/20240103160024.70305-7-leobras@redhat.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
|
开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/29570976688 参数解析结果
测试完成 详细结果:
Kunit Test Result[09:47:57] Testing complete. Ran 482 tests: passed: 465, skipped: 17
Kernel Build Result
Check Patch Result
LAVA Check (qemu)
result: Lava check done!
|
|
请详细提供测试的过程,一来我这里需要验证一下,另外可以考虑以后集成到回归测试中。 |
unicornx
left a comment
There was a problem hiding this comment.
1st review:
通用问题:
commit 的信息和上游原始 commit 不一致,主要体现在你摘取的 commit 看上去不是主线的 commit,譬如主线都会带有 LKML link 信息,但是你丢掉了,我怀疑你是拿的 LKML 的 patch,不是 linus 仓库 master 上的 commit。请检查。
具体到 commit 有以下几个问题
- 对 "riscv: Add support for the tagged address ABI" 这个 commit,我发现原补丁中下面这个你没有pick,是何原因?
+#ifdef CONFIG_RISCV_ISA_SUPM
+#define mm_untag_mask mm_untag_mask
+static inline unsigned long mm_untag_mask(struct mm_struct *mm)
+{
+ return -1UL >> mm->context.pmlen;
+}
+#endif
+如果 backpor 时不是简单的 pick 而是的确有需要改动,需要在 commit message 中做出说明,具体位置就是在
mainline inclusion
from Linux 6.13-rc1
commit 29eedc7d1587f42f33ae209be45c89c424ee9c00
category: feature
bugzilla: https://github.com/RVCK-Project/rvck/issues/335
如果基于原上游补丁有自己的修改,请在这里添加修改的原因和修改方案说明。
--------------------------------
- 对 "riscv: selftests: Add a pointer masking test" 这个 commit。 同理,不是简单的 pick 有改动,请补充说明
我是指
+RISCV_SUBTARGETS ?= abi hwprobe vector mm sse cfi
- 对 "riscv: add compile-time test into is_compat_task()" 这个 commit, 缺少原补丁中对
arch/riscv/include/asm/processor.h的改动,请补充说明。
这里的确是从mail list拿的提交,需要修改一下
mm_untag_mask():本地父提交已存在,来自 97644be
RISCV_SUBTARGETS:只加入 abi,保留 rvck 的 sse cfi,不引入本地不存在的 upstream context sigreturn。
processor.h:rvck 已有后续 stable 修复 f5f235b / upstream 2116988,对应代码已被简化,upstream 4c0b 的两处修改目标不存在。 |
重新编译 selftests |
|
开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/29914895629 参数解析结果
测试完成 详细结果:
Kunit Test Result[11:17:59] Testing complete. Ran 482 tests: passed: 465, skipped: 17
Kernel Build Result
Check Patch Result
LAVA Check (qemu)
result: Lava check done!
|
|
2nd review 针对 “riscv: Add support for the tagged address ABI” 这笔提交,你的 commit message 中的如下描述有个小问题需要改一下 在引用 rvck-6.6 分支上的补丁时,只要引用标题即可,不要引用 commit 的 hashcode。原因是 rvck-6.6 分支每个月会 rebase,导致该分支上的所有 commit 的 hashcode 会发生改变(这是目前 rvck-6.6 分支的管理方式决定的,和主线的 master 不同,主线的 master 上 commit 永远不变的)。所以我们引用时如果用了 hashcode,反而会对以后的人阅读造成困惑,而 commit 的 title 是不变的。所以可以改成如下方式: 我仔细看了一下修改历史,实际上这个问题我不清楚是不是当初 rvck 上合入 "riscv/shstk: If needed allocate a new shadow stack on clone" 的一个 bug,照理当时就应该已经 back port "riscv: Add support for the tagged address ABI" 了。怎么能直接改上游的补丁呢。 其他的 LGTM。 我再找时间测试一下。 |
我构建了 pointer_masking 和 get-reg-list。并将他们复制到 qemu riscv64 上运行 pointer_masking 可以正常 pass,见附件 但 get-reg-list 运行失败, $ ./get-reg-list --config=smnpm
1..0 # SKIP - /dev/kvm not available (errno: 2)
$ ./get-reg-list --config=ssnpm
1..0 # SKIP - /dev/kvm not available (errno: 2)两个问题:
|
是get-reg-list
在Qemu上测试的,编译内核时打开KVM的config |
我用的 rvck 的 defconfig,CONFIG_KVM=y 请问你用的 QEMU 是什么版本,以及启动 QEMU 的选项参数是什么? |
帮忙把你启动qemu的参数,还有你内核启动的log贴一下,我这边check一下。 |
|
发现一个问题,make clean 时 |
看上去我这里暂时找不到可以支持 kvm 的 rv 硬件作为 host 测试 kvm 的特性,kvm 的测试就靠你先测试吧,你先把我提的几个问题先解决了吧。 |
fixed: #335
自测试:
1, pointer_masking self test:
Testing available PMLEN values
ok 1 PMLEN=0 PR_GET_TAGGED_ADDR_CTRL
ok 2 PMLEN=0 constraint
ok 3 PMLEN=0 validity
ok 4 PMLEN=1 PR_GET_TAGGED_ADDR_CTRL
ok 5 PMLEN=1 constraint
ok 6 PMLEN=1 validity
ok 7 PMLEN=2 PR_GET_TAGGED_ADDR_CTRL
ok 8 PMLEN=2 constraint
ok 9 PMLEN=2 validity
...
Testing tagged address ABI
ok 59 PMLEN=0 tagged address ABI
ok 60 PMLEN=7 tagged address ABI
ok 61 PMLEN=16 tagged address ABI
Totals: pass:61 fail:0 xfail:0 xpass:0 skip:0 error:0
2,kvm-get-reg-list smnpm
smnpm: PASS
3,kvm-get-reg-list ssnpm
ssnpm: PASS