> On Sep 2, 2020, at 3:13 PM, Yu, Yu-cheng <yu-cheng.yu@xxxxxxxxx> wrote: > > On 9/2/2020 1:03 PM, Jann Horn wrote: >>> On Tue, Aug 25, 2020 at 2:30 AM Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> wrote: >>> Add REGSET_CET64/REGSET_CET32 to get/set CET MSRs: >>> >>> IA32_U_CET (user-mode CET settings) and >>> IA32_PL3_SSP (user-mode Shadow Stack) >> [...] >>> diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c >> [...] >>> +int cetregs_get(struct task_struct *target, const struct user_regset *regset, >>> + struct membuf to) >>> +{ >>> + struct fpu *fpu = &target->thread.fpu; >>> + struct cet_user_state *cetregs; >>> + >>> + if (!boot_cpu_has(X86_FEATURE_SHSTK)) >>> + return -ENODEV; >>> + >>> + fpu__prepare_read(fpu); >>> + cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_CET_USER); >>> + if (!cetregs) >>> + return -EFAULT; >> Can this branch ever be hit without a kernel bug? If yes, I think >> -EFAULT is probably a weird error code to choose here. If no, this >> should probably use WARN_ON(). Same thing in cetregs_set(). > > When a thread is not CET-enabled, its CET state does not exist. I looked at EFAULT, and it means "Bad address". Maybe this can be ENODEV, which means "No such device"? > > [...] > >>> @@ -1284,6 +1293,13 @@ static struct user_regset x86_32_regsets[] __ro_after_init = { >> [...] >>> + [REGSET_CET32] = { >>> + .core_note_type = NT_X86_CET, >>> + .n = sizeof(struct cet_user_state) / sizeof(u64), >>> + .size = sizeof(u64), .align = sizeof(u64), >>> + .active = cetregs_active, .regset_get = cetregs_get, >>> + .set = cetregs_set >>> + }, >>> }; >> Why are there different identifiers for 32-bit CET and 64-bit CET when >> they operate on the same structs and have the same handlers? If >> there's a good reason for that, the commit message should probably >> point that out. > > Yes, the reason for two regsets is that fill_note_info() does not expect any holes in a regsets. I will put this in the commit log. > > Perhaps we could fix that instead?