Re: x86/fpu/xsave: protection key test failures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 5/26/21 8:25 AM, Babu Moger wrote:
> On 5/25/21 7:20 PM, Dave Hansen wrote:
>> On 5/25/21 5:03 PM, Babu Moger wrote:
>>>> What values do PKRU and the shadow have when the test fails?  Is PKRU 0?
>>> It goes back to default value 0x55555554. The test is expecting it to be
>>> 0. Printed them below.
>>>
>>> test_ptrace_of_child()::1346, pkey_reg: 0x0000000055555554 shadow:
>>> 0000000000000000
>>> protection_keys_64: pkey-helpers.h:127: _read_pkey_reg: Assertion
>>> `pkey_reg == shadow_pkey_reg' failed.
>> That's backwards (shadow vs pkru) from what I was expecting.
>>
>> Can you turn on all the debuging?
>>
>> Just compile with -DDEBUG_LEVEL=5
> 
> Copied the logs at https://pastebin.com/gtQiHg8Q

Well, it's a bit backwards from what I'm expecting.  The PKRU=0 value
*WAS* legitimate because all of the pkeys got allocated and their
disable bits cleared.

I think Andy was close when he was blaming:

> static inline void write_pkru(u32 pkru)
> {
...
>         pk = get_xsave_addr(&current->thread.fpu.state.xsave, XFEATURE_PKRU);
...
>         if (pk)
>                 pk->pkru = pkru;
>         __write_pkru(pkru);
> }

But that can't be it because PKRU ended up with 0x55555554.  Something
must have been writing 'init_pkru_value'.

switch_fpu_finish() does that:

> static inline void switch_fpu_finish(struct fpu *new_fpu)
> {
>         u32 pkru_val = init_pkru_value;
...
>         if (current->mm) {
>                 pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU);
>                 if (pk)
>                         pkru_val = pk->pkru;
>         }
>         __write_pkru(pkru_val);
...
> }

If 'new_fpu' had XSTATE_BV[PKRU]=0 then we'd have pk=NULL and 'pkru_val'
would still have 'init_pkru_value'.  *Then*, we'd have a shadow=0x0 and
pkru=0x55555554.  It would also only trigger if the hardware has an init
tracker that fires when wrpkru(0).  Intel doesn't do that.  AMD must.

Anyway, I need to think about this a bit more.  But, an entirely
guaranteed to be 100% untested patch is attached.  I'm *NOT* confident
this is the right fix.

I don't have much AMD hardware laying around, so testing would be
appreciated.
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
index 8d33ad8..21402eb 100644
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -582,6 +582,8 @@ static inline void switch_fpu_finish(struct fpu *new_fpu)
 		pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU);
 		if (pk)
 			pkru_val = pk->pkru;
+		else
+			pkru_val = 0x0;
 	}
 	__write_pkru(pkru_val);
 

[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux