Message ID | 20231103224402.347278-1-seanjc@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:8f47:0:b0:403:3b70:6f57 with SMTP id j7csp1351004vqu; Fri, 3 Nov 2023 15:44:19 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGn/2eG0HlAhJf81f60upqFWjAz5zs/TQkcoB5d1vTGCct7onJvu32yHLibGvWJ8FPI9Hpi X-Received: by 2002:a05:6300:800a:b0:180:f0ed:2992 with SMTP id an10-20020a056300800a00b00180f0ed2992mr14048766pzc.51.1699051458918; Fri, 03 Nov 2023 15:44:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1699051458; cv=none; d=google.com; s=arc-20160816; b=bh4icDvh4MBXCV+YMmPn8QVs5ENPqxtJYnln+bepMwGnGNmqTdRl5ef/B49TntXQGd Jy1LuSFXD7dB85WO0mgjHt+DxPloCaWjPkXzx7IkRcdiEcN9d6M5kQYwaSdgpu4SjuqQ 8+pYmXYToW9xReCanBWOQojGAT2BWXIlVur6ex91KE6wiIkd/L4eBW8f5xD/cYwy8gC/ P36q40aPIu0fH5JtCk1/dFfO8aAphG8E/orGsUdD/awMb8t0BVG0QxY2Lp1oD/EpkwCT Jfl70quWkgny770R3/rTavs/hc2AkjXmqCNV+3utHnVSpLlvIC480CZCr+cGNF+ype4f cBFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:mime-version:date :reply-to:dkim-signature; bh=VHUs19MXg68FJ/UikGSWl1xtUmfy1ZNYmGDVs0epASU=; fh=se+xcgb5U3yYRyXvKnJtB8t0HH1w/VbX0S6YMNVPeI0=; b=ki8E1Z8fUaky++mqgqRM8ZQxiUY0gBaBZAe5XBgUGjWJYnTwIUv9O4PcQn8sQpbBYs yTYHEpA2LD2FIoegB1GWhqnIZRnDbsZDxrPrEA2fjTRP9e9nHN/9Gkc0sEGag5e9OpQF XQlRcm/sIjJpaUjku86wQkKsD1ZyOcvCa1nL1LjzCDIia491AcoMI5BFZFXaK7/HWjqj vMKqMFsalCavuG/tjQ4FPkrrbt1qC8PvA6HkGsklQg4Oevxqg5EK1hjvVUzWuD9+ByN4 eQFk3DbnX9l93eoteCI5aeC1ljiM1w4yJ2FNigWsZ3KZnd/Gj0LtG5fg/n+sfmM0B0Wl mQ2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=eRdP5MYT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 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 snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id cm6-20020a17090afa0600b0026821262c7csi2565395pjb.116.2023.11.03.15.44.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Nov 2023 15:44:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=eRdP5MYT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 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 (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id EBD1F8312FAF; Fri, 3 Nov 2023 15:44:17 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345700AbjKCWoK (ORCPT <rfc822;heyuhang3455@gmail.com> + 35 others); Fri, 3 Nov 2023 18:44:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345174AbjKCWoJ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 3 Nov 2023 18:44:09 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F995D6D for <linux-kernel@vger.kernel.org>; Fri, 3 Nov 2023 15:44:06 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5a9012ab0adso36502087b3.1 for <linux-kernel@vger.kernel.org>; Fri, 03 Nov 2023 15:44:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1699051445; x=1699656245; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:reply-to:from:to:cc :subject:date:message-id:reply-to; bh=VHUs19MXg68FJ/UikGSWl1xtUmfy1ZNYmGDVs0epASU=; b=eRdP5MYTex7drFSvnL8KqbMuun5bFCt9F19Ie+gn87Sws08TPDik6fMEhpWDYHc+Tq zj1nW1YWspv3f5JvTv1gOvybTkExyY/sczl0YsQXlTbrNl6tnb6AKVRANhaKdQGG+iVg VOPV+IGfWF7Is5mFbH9KuY2/7GQMN+uLeHlxXxK4etRrzBtwGPq13ju0tatp0KEqpcqq luPgfWcMtusTndj7JjPY/IgwxqxvIUdRzBZNemKtxs+1rQ9ZC9YBZ9XLdGPmlj0tlQ4Q Rb0QZnAeePkNn/31ORt4eC/8YJXMcosXX5awUpGrPE9kJaL/SFDBvAPuSssBGFwUE1ez y47g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699051445; x=1699656245; h=cc:to:from:subject:message-id:mime-version:date:reply-to :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=VHUs19MXg68FJ/UikGSWl1xtUmfy1ZNYmGDVs0epASU=; b=JDkNjBTlniRcJoOHFQafoP8vhYc0DqpYzbAFy8PnV9AEhmwq75jpTvgMwnGzjXiriE aIs1ehpq42L3P2928uzfz8Dhoo25JOvTP7ds2apPAeXfKKlpG1V8ICDTRb75Mz/xys5p fsmibYevCVgd6ImRO5BMOHnyRHIgdFo+mXMjucUIkgcpVQHfEjrDc9VO440q/lh9nvEx ugK1mR7t8IzKf5uSprF2dHT0jNUpOfpAv1E0MLNvtyql+vYpJapT61mnWfUKOFVCe3DK 6rwXRedW0A4y+l/567rlBNU6KU7JHiD+zUmE15yZ7PULpiSUFSmrbW5+BQUAYP3mCCVr tS7g== X-Gm-Message-State: AOJu0YzL/mVurRK1Hjd3ds9zQ/sklIBhOcqLB9myLe//mj0VdplgY4ye XLzf2GfDI5z/Fz+gHbkjwTNA8n32Lwc= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a81:a056:0:b0:59b:ca80:919a with SMTP id x83-20020a81a056000000b0059bca80919amr78967ywg.0.1699051445462; Fri, 03 Nov 2023 15:44:05 -0700 (PDT) Reply-To: Sean Christopherson <seanjc@google.com> Date: Fri, 3 Nov 2023 15:44:02 -0700 Mime-Version: 1.0 X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog Message-ID: <20231103224402.347278-1-seanjc@google.com> Subject: [PATCH] x86/fpu/xstate: Always preserve non-user xfeatures/flags in __state_perm From: Sean Christopherson <seanjc@google.com> To: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>, Dave Hansen <dave.hansen@linux.intel.com>, x86@kernel.org Cc: linux-kernel@vger.kernel.org, Maxim Levitsky <mlevitsk@redhat.com>, Weijiang Yang <weijiang.yang@intel.com>, Dave Hansen <dave.hansen@intel.com>, Paolo Bonzini <pbonzini@redhat.com>, Peter Zijlstra <peterz@infradead.org>, Chao Gao <chao.gao@intel.com>, Rick Edgecombe <rick.p.edgecombe@intel.com>, John Allen <john.allen@amd.com>, kvm@vger.kernel.org, Sean Christopherson <seanjc@google.com> Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=ham 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Fri, 03 Nov 2023 15:44:18 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781584582658465805 X-GMAIL-MSGID: 1781584582658465805 |
Series |
x86/fpu/xstate: Always preserve non-user xfeatures/flags in __state_perm
|
|
Commit Message
Sean Christopherson
Nov. 3, 2023, 10:44 p.m. UTC
When granting userspace or a KVM guest access to an xfeature, preserve the
entity's existing supervisor and software-defined permissions as tracked
by __state_perm, i.e. use __state_perm to track *all* permissions even
though all supported supervisor xfeatures are granted to all FPUs and
FPU_GUEST_PERM_LOCKED disallows changing permissions.
Effectively clobbering supervisor permissions results in inconsistent
behavior, as xstate_get_group_perm() will report supervisor features for
process that do NOT request access to dynamic user xfeatures, whereas any
and all supervisor features will be absent from the set of permissions for
any process that is granted access to one or more dynamic xfeatures (which
right now means AMX).
The inconsistency isn't problematic because fpu_xstate_prctl() already
strips out everything except user xfeatures:
case ARCH_GET_XCOMP_PERM:
/*
* Lockless snapshot as it can also change right after the
* dropping the lock.
*/
permitted = xstate_get_host_group_perm();
permitted &= XFEATURE_MASK_USER_SUPPORTED;
return put_user(permitted, uptr);
case ARCH_GET_XCOMP_GUEST_PERM:
permitted = xstate_get_guest_group_perm();
permitted &= XFEATURE_MASK_USER_SUPPORTED;
return put_user(permitted, uptr);
and similarly KVM doesn't apply the __state_perm to supervisor states
(kvm_get_filtered_xcr0() incorporates xstate_get_guest_group_perm()):
case 0xd: {
u64 permitted_xcr0 = kvm_get_filtered_xcr0();
u64 permitted_xss = kvm_caps.supported_xss;
But if KVM in particular were to ever change, dropping supervisor
permissions would result in subtle bugs in KVM's reporting of supported
CPUID settings. And the above behavior also means that having supervisor
xfeatures in __state_perm is correctly handled by all users.
Dropping supervisor permissions also creates another landmine for KVM. If
more dynamic user xfeatures are ever added, requesting access to multiple
xfeatures in separate ARCH_REQ_XCOMP_GUEST_PERM calls will result in the
second invocation of __xstate_request_perm() computing the wrong ksize, as
as the mask passed to xstate_calculate_size() would not contain *any*
supervisor features.
Commit 781c64bfcb73 ("x86/fpu/xstate: Handle supervisor states in XSTATE
permissions") fudged around the size issue for userspace FPUs, but for
reasons unknown skipped guest FPUs. Lack of a fix for KVM "works" only
because KVM doesn't yet support virtualizing features that have supervisor
xfeatures, i.e. as of today, KVM guest FPUs will never need the relevant
xfeatures.
Simply extending the hack-a-fix for guests would temporarily solve the
ksize issue, but wouldn't address the inconsistency issue and would leave
another lurking pitfall for KVM. KVM support for virtualizing CET will
likely add CET_KERNEL as a guest-only xfeature, i.e. CET_KERNEL will not
be set in xfeatures_mask_supervisor() and would again be dropped when
granting access to dynamic xfeatures.
Note, the existing clobbering behavior is rather subtle. The @permitted
parameter to __xstate_request_perm() comes from:
permitted = xstate_get_group_perm(guest);
which is either fpu->guest_perm.__state_perm or fpu->perm.__state_perm,
where __state_perm is initialized to:
fpu->perm.__state_perm = fpu_kernel_cfg.default_features;
and copied to the guest side of things:
/* Same defaults for guests */
fpu->guest_perm = fpu->perm;
fpu_kernel_cfg.default_features contains everything except the dynamic
xfeatures, i.e. everything except XFEATURE_MASK_XTILE_DATA:
fpu_kernel_cfg.default_features = fpu_kernel_cfg.max_features;
fpu_kernel_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC;
When __xstate_request_perm() restricts the local "mask" variable to
compute the user state size:
mask &= XFEATURE_MASK_USER_SUPPORTED;
usize = xstate_calculate_size(mask, false);
it subtly overwrites the target __state_perm with "mask" containing only
user xfeatures:
perm = guest ? &fpu->guest_perm : &fpu->perm;
/* Pairs with the READ_ONCE() in xstate_get_group_perm() */
WRITE_ONCE(perm->__state_perm, mask);
Cc: Maxim Levitsky <mlevitsk@redhat.com>
Cc: Weijiang Yang <weijiang.yang@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Chao Gao <chao.gao@intel.com>
Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: John Allen <john.allen@amd.com>
Cc: kvm@vger.kernel.org
Link: https://lore.kernel.org/all/ZTqgzZl-reO1m01I@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
Note, I haven't tested the PASID side of things, so someone with more know-how
definitely needs to take this for a spin.
arch/x86/kernel/fpu/xstate.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
base-commit: 45b890f7689eb0aba454fc5831d2d79763781677
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index ef6906107c54..73f6bc00d178 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -1601,16 +1601,20 @@ static int __xstate_request_perm(u64 permitted, u64 requested, bool guest) if ((permitted & requested) == requested) return 0; - /* Calculate the resulting kernel state size */ + /* + * Calculate the resulting kernel state size. Note, @permitted also + * contains supervisor xfeatures even though supervisor are always + * permitted for kernel and guest FPUs, and never permitted for user + * FPUs. + */ mask = permitted | requested; - /* Take supervisor states into account on the host */ - if (!guest) - mask |= xfeatures_mask_supervisor(); ksize = xstate_calculate_size(mask, compacted); - /* Calculate the resulting user state size */ - mask &= XFEATURE_MASK_USER_SUPPORTED; - usize = xstate_calculate_size(mask, false); + /* + * Calculate the resulting user state size. Take care not to clobber + * the supervisor xfeatures in the new mask! + */ + usize = xstate_calculate_size(mask & XFEATURE_MASK_USER_SUPPORTED, false); if (!guest) { ret = validate_sigaltstack(usize);