Re: XSAVE / RDPKRU on Intel 11th Gen Core CPUs

From: Brian Geffon
Date: Tue Nov 09 2021 - 13:58:53 EST


Hi Andy,

On Tue, Nov 9, 2021 at 9:58 AM Andy Lutomirski <luto@xxxxxxxxxx> wrote:
> Here's an excerpt from an old email that I, perhaps unwisely, sent to Dave but not to a public list:
>
> static inline void write_pkru(u32 pkru)
> {
> struct pkru_state *pk;
>
> if (!boot_cpu_has(X86_FEATURE_OSPKE))
> return;
>
> pk = get_xsave_addr(&current->thread.fpu.state.xsave,
> XFEATURE_PKRU);
>
> /*
> * The PKRU value in xstate needs to be in sync with the value
> that is
> * written to the CPU. The FPU restore on return to userland would
> * otherwise load the previous value again.
> */
> fpregs_lock();
> if (pk)
> pk->pkru = pkru;
>
> ^^^
> else we just write to the PKRU register but leave XINUSE[PKRU] clear on
> return to usermode? That seems... unwise.
>
> __write_pkru(pkru);
> fpregs_unlock();
> }
>
> I bet you're hitting exactly this bug. The fix ended up being a whole series of patches, but the gist of it is that the write_pkru() slow path needs to set the xfeature bit in the xsave buffer and then do the write. It should be possible to make a little patch to do just this in a couple lines of code.

I think you've got the right idea, the following patch does seem to
fix the problem on this CPU, this is based on 5.13. It seems the
changes to asm/pgtable.h were not enough, I also had to modify
fpu/internal.h to get it working properly.