Received: by 2002:a05:6a10:7420:0:0:0:0 with SMTP id hk32csp563143pxb; Tue, 15 Feb 2022 22:11:08 -0800 (PST) X-Google-Smtp-Source: ABdhPJxr5LJEUzj3hzXovWkrynvGNNEs5zci3CclRfyitqcpfFNlNU66EZxtWwdIqIB6VPy1JW2u X-Received: by 2002:a17:90a:aa0a:b0:1b4:e1e3:9651 with SMTP id k10-20020a17090aaa0a00b001b4e1e39651mr23049pjq.235.1644991867962; Tue, 15 Feb 2022 22:11:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1644991867; cv=none; d=google.com; s=arc-20160816; b=Qg/SCmrf8FS6FZ1CFkOKXuSEh1/Cd7AlHMr8xxcL+Tq6a5U0eSroMNha45cAEPMUYJ ZLltki+6r5duZ1DxAdHCKy5eUqtpMm/VY4X2Suwp3vWzP4/HY12K7gXxnIi5LlqplHCw 8aK0FsdNMyJ5kBaDv37RqG7din7DDF7kkdTm3+A59gsf+rATcIHGC3XZYqfW1s0Eh/4E T70OfRAFa/Xbvc5HxPd/9vp5rVx/So+bAXHfAQ73vLg7S1kD9UwkN/zPbL1skQuBXmuy u6CKkVbeK33r+GVvtgBAyB5zTKWfaSmstfz2PgYl43XXV5PXa5jDtu40GLM5iiCqZhmR S2Xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=SOESlV2s6ZwCllfQeNa8evJBNbO1odv7aNzYs4NXHeE=; b=RoDcD2HYdDOevqXulAmdu5ZzLMBi0O6c/Hhl4NWVNrsWhbyEuoMt11GnIOS8horRdi YV52u/2OLQqGvAUiHKnHPKmUrrgiar2Rk9BDSw45BVckG/qXiE41IsofVXCGy/rPsFs/ En/zAy66eDUL3wBYsctZi6NMRSAa9WmH94PU2qTW2ulEtnQ3LskgA0b8+10puC1k8Au1 zwPow7aW+06YgBy2eh9lOrYUq49XhjQ3M6E0q2eYWvUUVFlhue2GJCD768dwvD3ppg5t aWxrbuhSiZUBXejY0FINdbKWryirY2f3B0Ej2Uc7SYlZfX0394UVBYKoje7Od12jRb86 l3fQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=Gj2Jg9Ia; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 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 lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id 8si34408979pfm.126.2022.02.15.22.11.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Feb 2022 22:11:07 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=Gj2Jg9Ia; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C24E4187171; Tue, 15 Feb 2022 22:11:05 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239703AbiBOVPJ (ORCPT + 99 others); Tue, 15 Feb 2022 16:15:09 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244336AbiBOVPI (ORCPT ); Tue, 15 Feb 2022 16:15:08 -0500 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D41C7EDA8 for ; Tue, 15 Feb 2022 13:14:57 -0800 (PST) Received: by mail-ej1-x631.google.com with SMTP id lw4so16186709ejb.12 for ; Tue, 15 Feb 2022 13:14:57 -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; bh=SOESlV2s6ZwCllfQeNa8evJBNbO1odv7aNzYs4NXHeE=; b=Gj2Jg9IaholauJKgsi2qxw70XeHf2lRTlaQON8YobEMcYWbMg3wXnqfCORFUf1urpD 0vF+eiEdcqtpVPXKmjmC8LZqRwFnxOYz4dAaSB4wDjvt8F4YHbFcnfFTYFMV6v3AUuXX 8cDQmWDO8X1dmJfiyF+mZd2G7Djx+5HIPachZnLdjtB2W5skdyVU9uAH1UJIdUHF/+Ft mrBbIZwSrpiV2W5mMEjt36UYXj/9kqdP3T0ni6kIWQ5AlQ6pbfQ3CrYpRMeOcM84h9t9 toAjzRB1+PVToxIzNics0/psPRNC32ZcnLTvOMwavxSTac6hKaj/jot/Z/XASlm+4ShV ilKQ== 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; bh=SOESlV2s6ZwCllfQeNa8evJBNbO1odv7aNzYs4NXHeE=; b=dTm6AhK10ycXawZIpehWBxcztmNtRzdr4RG86CvrPANkwwXlszaCh4vyK65SN7BtIa cSPDV+C0FgE2eEXAndZz1/pSRhJ4OssPfUuLe2NahbLpK1+ateO5N9ni+NqB7hvA8ZB/ X/l5v+AWls8mIrcHCqvy4DeSDWSuQVp1+hnfOie94913aqrYqVESX5ahJ2nthHUDklkb XR3AD9a1dDQvdfHfljEmYGkU9zz36GG/M4Y+oQrGNcXv98OBi8wKqDz7iqLGALdeuPXR 1zfZBj187BExFbBMDbxdq7GP0JOCiv3MmOSfE0iarUJSvwPGnBMM5TwbLlYM3C+TWKWY 8mhg== X-Gm-Message-State: AOAM531MFnV9Xqvds61jICwyMn1vkod0Ufo7L993DmbSfQLY6cHDZLxL P8QqSoq7NeCLvrjLWoEGo9/IeJwOBTkl3czwlWUsVQ== X-Received: by 2002:a17:906:74d2:: with SMTP id z18mr833705ejl.618.1644959695408; Tue, 15 Feb 2022 13:14:55 -0800 (PST) MIME-Version: 1.0 References: <20220215153644.3654582-1-bgeffon@google.com> <56fc0ced-d8d2-146f-6ca8-b95bd7e0b4f5@intel.com> In-Reply-To: <56fc0ced-d8d2-146f-6ca8-b95bd7e0b4f5@intel.com> From: Guenter Roeck Date: Tue, 15 Feb 2022 13:14:43 -0800 Message-ID: Subject: Re: [PATCH] x86/fpu: Correct pkru/xstate inconsistency To: Dave Hansen Cc: Brian Geffon , Thomas Gleixner , Willis Kung , Borislav Petkov , Andy Lutomirski , "# v4 . 10+" , "the arch/x86 maintainers" , linux-kernel Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.5 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Feb 15, 2022 at 9:13 AM Dave Hansen wrote: > > On 2/15/22 07:36, Brian Geffon wrote: > > There are two issues with PKRU handling prior to 5.13. > > Are you sure both of these issues were introduced by 0cecca9d03c? I'm > surprised that the get_xsave_addr() issue is not older. > > Should this be two patches? > > > The first is that when eagerly switching PKRU we check that current > > Don't forget to write in imperative mood. No "we's", please. > > https://www.kernel.org/doc/html/latest/process/maintainer-tip.html > > This goes for changelogs and comments too. > > > is not a kernel thread as kernel threads will never use PKRU. It's > > possible that this_cpu_read_stable() on current_task (ie. > > get_current()) is returning an old cached value. By forcing the read > > with this_cpu_read() the correct task is used. Without this it's > > possible when switching from a kernel thread to a userspace thread > > that we'll still observe the PF_KTHREAD flag and never restore the > > PKRU. And as a result this issue only occurs when switching from a > > kernel thread to a userspace thread, switching from a non kernel > > thread works perfectly fine because all we consider in that situation > > is the flags from some other non kernel task and the next fpu is > > passed in to switch_fpu_finish(). > > It makes *sense* that there would be a place in the context switch code > where 'current' is wonky, but I never realized this. This seems really > fragile, but *also* trivially detectable. > > Is the PKRU code really the only code to use 'current' in a buggy way > like this? > > > The second issue is when using write_pkru() we only write to the > > xstate when the feature bit is set because get_xsave_addr() returns > > NULL when the feature bit is not set. This is problematic as the CPU > > is free to clear the feature bit when it observes the xstate in the > > init state, this behavior seems to be documented a few places throughout > > the kernel. If the bit was cleared then in write_pkru() we would happily > > write to PKRU without ever updating the xstate, and the FPU restore on > > return to userspace would load the old value agian. > > > ^ again > > It's probably worth noting that the AMD init tracker is a lot more > aggressive than Intel's. On Intel, I think XRSTOR is the only way to > get back to the init state. You're obviously hitting this on AMD. > Brian should correct me here, but I think we have seen this with one specific Intel CPU. Brian, would it make sense to list the affected CPU model(s), or at least the ones where we have observed the problem ? Thanks, Guenter > It's also *very* unlikely that PKRU gets back to a value of 0. I think > we added a selftest for this case in later kernels. > > That helps explain why this bug hung around for so long. > > > diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h > > index 03b3de491b5e..540bda5bdd28 100644 > > --- a/arch/x86/include/asm/fpu/internal.h > > +++ b/arch/x86/include/asm/fpu/internal.h > > @@ -598,7 +598,7 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) > > * PKRU state is switched eagerly because it needs to be valid before we > > * return to userland e.g. for a copy_to_user() operation. > > */ > > - if (!(current->flags & PF_KTHREAD)) { > > + if (!(this_cpu_read(current_task)->flags & PF_KTHREAD)) { > > This really deserves a specific comment. > > > /* > > * If the PKRU bit in xsave.header.xfeatures is not set, > > * then the PKRU component was in init state, which means > > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > > index 9e71bf86d8d0..aa381b530de0 100644 > > --- a/arch/x86/include/asm/pgtable.h > > +++ b/arch/x86/include/asm/pgtable.h > > @@ -140,16 +140,22 @@ static inline void write_pkru(u32 pkru) > > if (!boot_cpu_has(X86_FEATURE_OSPKE)) > > return; > > > > - pk = 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 would > > * otherwise load the previous value again. > > */ > > fpregs_lock(); > > - if (pk) > > - pk->pkru = pkru; > > + /* > > + * The CPU is free to clear the feature bit when the xstate is in the > > + * init state. For this reason, we need to make sure the feature bit is > > + * reset when we're explicitly writing to pkru. If we did not then we > > + * would write to pkru and it would not be saved on a context switch. > > + */ > > + current->thread.fpu.state.xsave.header.xfeatures |= XFEATURE_MASK_PKRU; > > I don't think we need to describe how the init optimization works again. > I'm also not sure it's worth mentioning context switches here. It's a > wider problem than that. Maybe: > > /* > * All fpregs will be XRSTOR'd from this buffer before returning > * to userspace. Ensure that XRSTOR does not init PKRU and that > * get_xsave_addr() will work. > */ > > > + pk = get_xsave_addr(¤t->thread.fpu.state.xsave, XFEATURE_PKRU); > > + BUG_ON(!pk); > > A BUG_ON() a line before a NULL pointer dereference doesn't tend to do > much good. > > > + pk->pkru = pkru; > > __write_pkru(pkru); > > fpregs_unlock(); > > } >