On Tue, Feb 28, 2023 at 6:47 AM Mateusz Guzik wrote: > > Personally I would only touch it as a result of losing a bet (and I'm > not taking any with this in play), but that's just my $0.05 (adjusted > for inflation). Heh. I took that as a challenge. It wasn't actually all that bad (famous last words). For type safety reasons I decided to use a struct wrapper typedef struct { u64 val; } kernel_cap_t; to avoid any nasty silent integer value conversions. But then it was literally just a matter of cleaning up some of the insanity. I think the fs/proc/array.c modification is an example of just how bad things used to be: --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -300,13 +300,8 @@ static inline void task_sig(struct seq_file *m, static void render_cap_t(struct seq_file *m, const char *header, kernel_cap_t *a) { - unsigned __capi; - seq_puts(m, header); - CAP_FOR_EACH_U32(__capi) { - seq_put_hex_ll(m, NULL, - a->cap[CAP_LAST_U32 - __capi], 8); - } + seq_put_hex_ll(m, NULL, a->val, 16); seq_putc(m, '\n'); } note how the code literally did that odd CAP_LAST_U32 - __capi in there just to get the natural "high word first" that is exactly what you get if you just print out the value as a hex number. Now, the actual user mode conversions still exist, but even those often got simplified. Have I actually *tested* this? Of course not. I'm lazy, and everything I write obviously always works on the first try anyway, so why should I? So take this patch with a healthy dose of salt, but it looks sane to me, and it does build cleanly (and with our type system, that actually does say quite a lot). This actually looks sane enough that I might even boot it. Call me crazy. Linus