Received: by 2002:a05:6a10:8395:0:0:0:0 with SMTP id n21csp615200pxh; Tue, 9 Nov 2021 16:13:19 -0800 (PST) X-Google-Smtp-Source: ABdhPJznirKcp2nJuiFy+Ah75pvHiZnZViSIuclU2/2eMZ4J3ytDYRXQ2fGzXSwYTryw/B3MXoKj X-Received: by 2002:a05:6e02:1845:: with SMTP id b5mr8297585ilv.127.1636503199314; Tue, 09 Nov 2021 16:13:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1636503199; cv=none; d=google.com; s=arc-20160816; b=Be98Wv7IAwNHhvUE1qwolZjKwv8m3W1GXsl38yCjz6dL4kfguza4fCxOWn5hP6hEa5 ffXQJyny1lnvASOhqVLbpTCw6X4Wz+60Vc2hPjNhfVIBSO7z7k1rFTzqG/lSQgo2UqK2 Nmp4yRWK9NMx7zGBd8Vj/4wh6rkbRxUJDQlKe198zRGiximM3WcE8z33Pj8hHH1SQcBS KK+QoCoIoSCg8LhIxXdQQ5e6zPsIhDFZ3A4lXeV2x9d2cevYXXdyo8+M66YfCB+gTZdF ++n0AhHrrY4ZfbGPQnslNMki5l0sy98aMnG4NsZ2gBgO26q654UxoXNgD/8O1tWiLJCl 7FBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=ckvWhlaeZh0x0NLJKMOtA/VOUp/j79R2Yub8deg1/GQ=; b=zf6pVr8aVeKcHzXAe6YIMY/Ca2NJ1qB6neRrr4UwPfN+qeEqLz481u4gI1haFd2RJy +G1792BEK/nPjVrcIaUl89Qq6bCjyeSAOrXS0bcd2s+OhGQd7vGCSqpS4DkcRANftDW2 2yqPW/8/T/YLrVZ3PcVRd2No10X5DxDBseimYua3V5siJGcSkqNX9TiT5LSjCEb5Kze3 MhJQJBU1JBoI1HsN5naBytunwmCfYiinlOvHw0zZaDFxa5Ffmz3walaQja10+nE7lj2h PqI8F2sgIMgz8rkzLViyTJtewWqyMCLR5Wl5EIEQHUJdpNYgDUjy1WbkY7kTJr2RJpOX g8rg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=M0Tzw8Db; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b12si39953587jav.10.2021.11.09.16.13.07; Tue, 09 Nov 2021 16:13:19 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=M0Tzw8Db; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237469AbhKITBf (ORCPT + 97 others); Tue, 9 Nov 2021 14:01:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241264AbhKITBe (ORCPT ); Tue, 9 Nov 2021 14:01:34 -0500 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65C93C061766 for ; Tue, 9 Nov 2021 10:58:48 -0800 (PST) Received: by mail-ed1-x52c.google.com with SMTP id w1so387463edd.10 for ; Tue, 09 Nov 2021 10:58:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=ckvWhlaeZh0x0NLJKMOtA/VOUp/j79R2Yub8deg1/GQ=; b=M0Tzw8DbmvGOUn03GmXXn+YoiDtzteLno0G10yg+aMIFCv37LjlGdQun3A1TplOvvx NYVfn4djLrMqORJ6icc32cQhFKL/66ROcAuNXM2oUKpsWcL2cruvsMc4ImNDXvoB38i3 ysuWxgseDOEcfZfawVyOmqXC1YtVX1TwaKJecFoIQG7nBFko+lrEajhNVFNtzuJKRZAL vFpqcyTqIAWD8/IWJr5txxHEV/c/nSXlr9yGydkbSKO/vh44lTUyGq479r4UrulYKu4b +TJTjzyWvnySTxE8Et8d1RcEAH3Kj4JbpgNDYVxa9H/omGofAgPXh0Jbhn9Gp+x3A4eH mPbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=ckvWhlaeZh0x0NLJKMOtA/VOUp/j79R2Yub8deg1/GQ=; b=452B/WpHSIR1UJtX7vLNSKYBn/Jmlj9vumca0fgMEw8tz7sXDV9RW/zS8Q/VP94vF2 fg+JxSn/CCYQYudVOH4lxNbv+iHnDqN/GemPWoBEUmFh9bJfTfMgFEpiMNU9MGG5GJsZ nlmhvcwZASIKjMqeobF+7QP9Cw+fX64FtljoQwdiPDFSI6oE/uexSYL/7Jh1YDrJ5Kiz LGNczUVugH5WMgjEha+iJZUwaLaxfq5pb9WB4lnCwTxqlJkWvpYOK3eM3qdaDLkUopDb u9DQ8vJE67XJooFREPEj2yYlz1aVdnVrymbcGrPgXDKAnHSQWu5VgGZeMtAI0DK6FddT NVDQ== X-Gm-Message-State: AOAM533VMYImWwXS7+qpuw85WLHPvaKE+1uFPl6VowNurMt/CA6uAOer IYkiA1qt3AjzIvlWjO5DKaQBUaT8ZyPbTC/gLGzo7A== X-Received: by 2002:a05:6402:28e:: with SMTP id l14mr13192912edv.162.1636484326642; Tue, 09 Nov 2021 10:58:46 -0800 (PST) MIME-Version: 1.0 References: <85925a39-37c3-a79a-a084-51f2f291ca9c@intel.com> <472b8dbf-2c55-98c9-39ad-2db32a649a20@intel.com> <649f4de7-3c91-4974-9af7-d981a2bf6224@www.fastmail.com> In-Reply-To: <649f4de7-3c91-4974-9af7-d981a2bf6224@www.fastmail.com> From: Brian Geffon Date: Tue, 9 Nov 2021 13:58:10 -0500 Message-ID: Subject: Re: XSAVE / RDPKRU on Intel 11th Gen Core CPUs To: Andy Lutomirski Cc: Dave Hansen , Thomas Gleixner , Guenter Roeck , Borislav Petkov , stable@vger.kernel.org, "the arch/x86 maintainers" , Linux Kernel Mailing List Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Andy, On Tue, Nov 9, 2021 at 9:58 AM Andy Lutomirski wrote: > Here's an excerpt from an old email that I, perhaps unwisely, sent to Dav= e 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 =3D get_xsave_addr(¤t->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 woul= d > * otherwise load the previous value again. > */ > fpregs_lock(); > if (pk) > pk->pkru =3D 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 se= ries of patches, but the gist of it is that the write_pkru() slow path need= s to set the xfeature bit in the xsave buffer and then do the write. It sh= ould be possible to make a little patch to do just this in a couple lines o= f 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. From e5e184d68ac6ca93c3cd2cc88d61af3260d1c014 Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Tue, 9 Nov 2021 17:08:25 +0000 Subject: [PATCH] x86/fpu: Set XFEATURE_PKRU when writing to pkru On kernels prior to 5.14 the write_pkru path could end up writing to the pkru register without updating the corresponding state. Signed-off-by: Brian Geffon --- arch/x86/include/asm/fpu/internal.h | 22 ++++++++++------------ arch/x86/include/asm/pgtable.h | 5 +++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 16bf4d4a8159..ed2ce7d1afeb 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -564,18 +564,16 @@ static inline void switch_fpu_finish(struct fpu *new_= fpu) * PKRU state is switched eagerly because it needs to be valid befo= re we * return to userland e.g. for a copy_to_user() operation. */ - if (!(current->flags & PF_KTHREAD)) { - /* - * If the PKRU bit in xsave.header.xfeatures is not set, - * then the PKRU component was in init state, which means - * XRSTOR will set PKRU to 0. If the bit is not set then - * get_xsave_addr() will return NULL because the PKRU value - * in memory is not valid. This means pkru_val has to be - * set to 0 and not to init_pkru_value. - */ - pk =3D get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU)= ; - pkru_val =3D pk ? pk->pkru : 0; - } + /* + * If the PKRU bit in xsave.header.xfeatures is not set, + * then the PKRU component was in init state, which means + * XRSTOR will set PKRU to 0. If the bit is not set then + * get_xsave_addr() will return NULL because the PKRU value + * in memory is not valid. This means pkru_val has to be + * set to 0 and not to init_pkru_value. + */ + pk =3D get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU); + pkru_val =3D pk ? pk->pkru : 0; __write_pkru(pkru_val); } diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.= h index b1099f2d9800..d00fc2df4cfe 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -137,18 +137,19 @@ static inline u32 read_pkru(void) static inline void write_pkru(u32 pkru) { struct pkru_state *pk; + struct fpu *fpu =3D ¤t->thread.fpu; if (!boot_cpu_has(X86_FEATURE_OSPKE)) return; - pk =3D get_xsave_addr(¤t->thread.fpu.state.xsave, XFEATURE_PK= RU); - /* * 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. */ + fpu->state.xsave.header.xfeatures |=3D XFEATURE_MASK_PKRU; fpregs_lock(); + pk =3D get_xsave_addr(&fpu->state.xsave, XFEATURE_PKRU); if (pk) pk->pkru =3D pkru; __write_pkru(pkru); --=20 2.34.0.rc0.344.g81b53c2807-goog