Message ID | 20240228024147.41573-3-seanjc@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-84428-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp3098463dyb; Tue, 27 Feb 2024 18:42:50 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWZfQVMS2vJKWG59U0N5uDyJvrK45pYt+1diKrK+ohVVj7uUlrlhu2BR+SM52ZIN++SaWZD+kzvjf4jzthB822OQClhyQ== X-Google-Smtp-Source: AGHT+IGOZXGitIrH13OccE7DohPQ//1Vk01s3Z/dxvbh83i52fLRmTUjhIjupKlrlvvozXPVY+ZJ X-Received: by 2002:a17:902:bd8a:b0:1dc:2d65:5fd1 with SMTP id q10-20020a170902bd8a00b001dc2d655fd1mr11986814pls.2.1709088169988; Tue, 27 Feb 2024 18:42:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709088169; cv=pass; d=google.com; s=arc-20160816; b=nY/CKsCOJKBk0qbyyPARkjP9Ekofzm2RRHKW8J9PGLeRpoiws9lzk6SZFkU6igNdps rrkrX2oCvm6gj2tllD5vVu+0FOK/3r5ZC8Mi+x88HygGBIMBxO1NAbPPCoHm+ZLjIJrJ K2G9DqsI4OGsn1xp3IpDludRFE1/Y6dWQYxZLrZVrJBsyKC0bNs9dkenI+q9eSPyyWqI aBh3LbNAHqvu1++On0d2QVzyLUC27a7tTogvjDFMGVuNZJ3lNJin8jHUTPhUm3JnweTo ao7LpJPN2ueO5Jj5jRxp0LHlrRAO4/r8R8VRCpe2iyppFjlBV19l51xiR4IyBLmDHGRw hMpw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :reply-to:dkim-signature; bh=SB7VJZrxLLlFGrRBdKBxwQcdc7hfIE4p4aRvNnIMDrw=; fh=ogYHV1zkfEwixpRohZ+4VJit8jHFZvYABvCYvsYCe2k=; b=PsoUg0VP/eC/Rpjsss0fKcUJelostk9RD69NA5zqLGwO9S8A+J6Z5jeDTA4lnM3mnf d/5Dc7eLOeYaw6NxglRayo2c6fTEFBq56J5MTsyj7ofkTc+zxALeYOSy+JHF4SSZAwsP JcgkpRHkUawzAVePzPI4MRaAUToEdnPdEL0gkHc6UkkkzrdQup8k9FqBeZw2xTwJrItJ 4s+O+qQIwvRcItvUzCL/LR7PKHPH2EDbEOcOGmgSb263S9Ci0Crh98Rbw+2L6QUPDZgv uTeMsh8NkWIAzWYBGlM7xli8XMfxxTkShrFBI26EAF3L3qjGXycFO7k15rSchiZgw9cL f6Tw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=20r5g6XC; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-84428-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-84428-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id h18-20020a170902f55200b001dcb306f032si2552150plf.118.2024.02.27.18.42.49 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Feb 2024 18:42:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-84428-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=20r5g6XC; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-84428-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-84428-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id C67C5287B2C for <ouuuleilei@gmail.com>; Wed, 28 Feb 2024 02:42:49 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9C8A820DFF; Wed, 28 Feb 2024 02:42:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="20r5g6XC" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 837441F95A for <linux-kernel@vger.kernel.org>; Wed, 28 Feb 2024 02:41:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709088117; cv=none; b=efQ9DhFg7AHb+vMN0FkCf4KjK/vWxh/+j+kzLut31ip0ptUG35ZWtC5kdftafdJZXJMf9dNgVjzxP//Z7ljL2XCJN5d1vDv7pTrFV+PCesccwrCz5t2hR4dx3omggobMhMGZjm5J2MMbbaaxR80Lkvwq7pFiq5rJfUVFv406xZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709088117; c=relaxed/simple; bh=Pbt+JF3UA/8dMtWQFjeGy4m6XEf0EGAmPbiziPcskhM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=stoRyUFRaPbPnb0x9uC2mhJOuzmuKuaNg2MYxkGkBttR8kAZAVVFqWa2PjsrCDYRd5G3upgPuRz2uq2Hq3nB+NN/646AnXRdjYdXnWzXRqlu+OJJpIvL32NQCSkWU8a34Xuhi/WoXz/d6muXtW64NgYjYrucs2f6ReeH8rY8vR4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=20r5g6XC; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dcc58cddb50so8337985276.0 for <linux-kernel@vger.kernel.org>; Tue, 27 Feb 2024 18:41:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709088114; x=1709692914; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=SB7VJZrxLLlFGrRBdKBxwQcdc7hfIE4p4aRvNnIMDrw=; b=20r5g6XCXbfOojC6XcQ3lbgZbmsVRuzdMnK74272/AuKfYcHfkoxYhRmYKiof3oA5G usWiH9uzdGmmYy3pJYmZiNg5bOvkc9X6fAGEKBgCBk6jm8jIn3XxKgN9zFwWr4Il72Cr i+Rt3+bSBq237oLQNfQs6Wt9l6lXEqafihoS3xxede4iDo/RY9OxrRrtpzmcA9ASg5ty IFGDSXAbtKotgxYG/wYhbYEubMn1m6grdZ9wteY52qU75P/+fNUz0FDaAuTVVNU9HE9b yITaGc38ktCzMWrtBRXy4HEyuxqUeMlHT3/A1YiVSjtt/euafEHkY4vK0UaFdAVr7fZ0 FKng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709088114; x=1709692914; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=SB7VJZrxLLlFGrRBdKBxwQcdc7hfIE4p4aRvNnIMDrw=; b=WOJKGj5SlqK4dvYCJnoxvttIf8ZUBKKB13mszgFPCqQ4lWr2QBd8Aa1p02cjXegoAy qU7C6cK7xZIuy5s5hsPhTygmoft1hf87FvpIkzsDQsV6M1WBsYp7EOyCPCROeGCV7f6g Joy7i1PEkhWZVWS0iXPqiFj1fY39Aytf/9hHxDYy/6Kcu+EgWx2hqqLDC+y4Revuq46z wJxb45O2AIeLnpmklJH8l/gNtQimEMh3T9v7pIhuoHJu0OLmuVpMKqcQ2ZDA2+oU+s3I lqHIMI+RE73wxw6dhaOugq9xo0K00dNovCF9oYSNgNq3nZ5fM7PL9rH0IVtuzYruqQ1h DtYg== X-Forwarded-Encrypted: i=1; AJvYcCVYfR/gNB/hx0N6BUCThFRS/Ojtboj8dwX0evJA8gR/cFmxlitpO2ES44+kx0m4kiNODYPl7j6YwfK6KDwj/HdPdYVTn2/H7kjfRx+z X-Gm-Message-State: AOJu0YwHRKAcown519W4sXVebu5v5Y8/bGXjBKLsmduZ48vpjV/jolWP i+qxoRUQD93+t/vgHxLegVh+6z0gyFMLHDoE/1Kyf3rjJlD1RJ51Q1SYJojmgFJeSiwfezoe+gG Y6g== X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a25:21c1:0:b0:dcc:e1a6:aca9 with SMTP id h184-20020a2521c1000000b00dcce1a6aca9mr381616ybh.9.1709088114564; Tue, 27 Feb 2024 18:41:54 -0800 (PST) Reply-To: Sean Christopherson <seanjc@google.com> Date: Tue, 27 Feb 2024 18:41:33 -0800 In-Reply-To: <20240228024147.41573-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> Mime-Version: 1.0 References: <20240228024147.41573-1-seanjc@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240228024147.41573-3-seanjc@google.com> Subject: [PATCH 02/16] KVM: x86: Remove separate "bit" defines for page fault error code masks From: Sean Christopherson <seanjc@google.com> To: Sean Christopherson <seanjc@google.com>, Paolo Bonzini <pbonzini@redhat.com> Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yan Zhao <yan.y.zhao@intel.com>, Isaku Yamahata <isaku.yamahata@intel.com>, Michael Roth <michael.roth@amd.com>, Yu Zhang <yu.c.zhang@linux.intel.com>, Chao Peng <chao.p.peng@linux.intel.com>, Fuad Tabba <tabba@google.com>, David Matlack <dmatlack@google.com> Content-Type: text/plain; charset="UTF-8" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792108836464927099 X-GMAIL-MSGID: 1792108836464927099 |
Series |
KVM: x86/mmu: Page fault and MMIO cleanups
|
|
Commit Message
Sean Christopherson
Feb. 28, 2024, 2:41 a.m. UTC
Open code the bit number directly in the PFERR_* masks and drop the
intermediate PFERR_*_BIT defines, as having to bounce through two macros
just to see which flag corresponds to which bit is quite annoying, as is
having to define two macros just to add recognition of a new flag.
Use ilog2() to derive the bit in permission_fault(), the one function that
actually needs the bit number (it does clever shifting to manipulate flags
in order to avoid conditional branches).
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/kvm_host.h | 32 ++++++++++----------------------
arch/x86/kvm/mmu.h | 4 ++--
2 files changed, 12 insertions(+), 24 deletions(-)
Comments
On Wed, Feb 28, 2024 at 3:46 AM Sean Christopherson <seanjc@google.com> wrote: > > Open code the bit number directly in the PFERR_* masks and drop the > intermediate PFERR_*_BIT defines, as having to bounce through two macros > just to see which flag corresponds to which bit is quite annoying, as is > having to define two macros just to add recognition of a new flag. > > Use ilog2() to derive the bit in permission_fault(), the one function that > actually needs the bit number (it does clever shifting to manipulate flags > in order to avoid conditional branches). > > No functional change intended. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/include/asm/kvm_host.h | 32 ++++++++++---------------------- > arch/x86/kvm/mmu.h | 4 ++-- > 2 files changed, 12 insertions(+), 24 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index aaf5a25ea7ed..88cc523bafa8 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -254,28 +254,16 @@ enum x86_intercept_stage; > KVM_GUESTDBG_INJECT_DB | \ > KVM_GUESTDBG_BLOCKIRQ) > > - > -#define PFERR_PRESENT_BIT 0 > -#define PFERR_WRITE_BIT 1 > -#define PFERR_USER_BIT 2 > -#define PFERR_RSVD_BIT 3 > -#define PFERR_FETCH_BIT 4 > -#define PFERR_PK_BIT 5 > -#define PFERR_SGX_BIT 15 > -#define PFERR_GUEST_FINAL_BIT 32 > -#define PFERR_GUEST_PAGE_BIT 33 > -#define PFERR_IMPLICIT_ACCESS_BIT 48 > - > -#define PFERR_PRESENT_MASK BIT(PFERR_PRESENT_BIT) > -#define PFERR_WRITE_MASK BIT(PFERR_WRITE_BIT) > -#define PFERR_USER_MASK BIT(PFERR_USER_BIT) > -#define PFERR_RSVD_MASK BIT(PFERR_RSVD_BIT) > -#define PFERR_FETCH_MASK BIT(PFERR_FETCH_BIT) > -#define PFERR_PK_MASK BIT(PFERR_PK_BIT) > -#define PFERR_SGX_MASK BIT(PFERR_SGX_BIT) > -#define PFERR_GUEST_FINAL_MASK BIT_ULL(PFERR_GUEST_FINAL_BIT) > -#define PFERR_GUEST_PAGE_MASK BIT_ULL(PFERR_GUEST_PAGE_BIT) > -#define PFERR_IMPLICIT_ACCESS BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT) > +#define PFERR_PRESENT_MASK BIT(0) > +#define PFERR_WRITE_MASK BIT(1) > +#define PFERR_USER_MASK BIT(2) > +#define PFERR_RSVD_MASK BIT(3) > +#define PFERR_FETCH_MASK BIT(4) > +#define PFERR_PK_MASK BIT(5) > +#define PFERR_SGX_MASK BIT(15) > +#define PFERR_GUEST_FINAL_MASK BIT_ULL(32) > +#define PFERR_GUEST_PAGE_MASK BIT_ULL(33) > +#define PFERR_IMPLICIT_ACCESS BIT_ULL(48) > > #define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \ > PFERR_WRITE_MASK | \ > diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h > index 60f21bb4c27b..e8b620a85627 100644 > --- a/arch/x86/kvm/mmu.h > +++ b/arch/x86/kvm/mmu.h > @@ -213,7 +213,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, > */ > u64 implicit_access = access & PFERR_IMPLICIT_ACCESS; > bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC; > - int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1; > + int index = (pfec + (not_smap << ilog2(PFERR_RSVD_MASK))) >> 1; Just use "(pfec + (not_smap ? PFERR_RSVD_MASK : 0)) >> 1". Likewise below, "pte_access & PT_USER_MASK ? PFERR_RSVD_MASK : 0"/ No need to even check what the compiler produces, it will be either exactly the same code or a bunch of cmov instructions. Paolo > u32 errcode = PFERR_PRESENT_MASK; > bool fault; > > @@ -235,7 +235,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, > > /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ > offset = (pfec & ~1) + > - ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT)); > + ((pte_access & PT_USER_MASK) << (ilog2(PFERR_RSVD_MASK) - PT_USER_SHIFT)); > > pkru_bits &= mmu->pkru_mask >> offset; > errcode |= -pkru_bits & PFERR_PK_MASK; > -- > 2.44.0.278.ge034bb2e1d-goog >
I remember I read somewhere suggesting not to change the headers in selftest. Just double-check if there is requirement to edit tools/testing/selftests/kvm/include/x86_64/processor.h. Dongli Zhang On 2/27/24 18:41, Sean Christopherson wrote: > Open code the bit number directly in the PFERR_* masks and drop the > intermediate PFERR_*_BIT defines, as having to bounce through two macros > just to see which flag corresponds to which bit is quite annoying, as is > having to define two macros just to add recognition of a new flag. > > Use ilog2() to derive the bit in permission_fault(), the one function that > actually needs the bit number (it does clever shifting to manipulate flags > in order to avoid conditional branches). > > No functional change intended. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/include/asm/kvm_host.h | 32 ++++++++++---------------------- > arch/x86/kvm/mmu.h | 4 ++-- > 2 files changed, 12 insertions(+), 24 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index aaf5a25ea7ed..88cc523bafa8 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -254,28 +254,16 @@ enum x86_intercept_stage; > KVM_GUESTDBG_INJECT_DB | \ > KVM_GUESTDBG_BLOCKIRQ) > > - > -#define PFERR_PRESENT_BIT 0 > -#define PFERR_WRITE_BIT 1 > -#define PFERR_USER_BIT 2 > -#define PFERR_RSVD_BIT 3 > -#define PFERR_FETCH_BIT 4 > -#define PFERR_PK_BIT 5 > -#define PFERR_SGX_BIT 15 > -#define PFERR_GUEST_FINAL_BIT 32 > -#define PFERR_GUEST_PAGE_BIT 33 > -#define PFERR_IMPLICIT_ACCESS_BIT 48 > - > -#define PFERR_PRESENT_MASK BIT(PFERR_PRESENT_BIT) > -#define PFERR_WRITE_MASK BIT(PFERR_WRITE_BIT) > -#define PFERR_USER_MASK BIT(PFERR_USER_BIT) > -#define PFERR_RSVD_MASK BIT(PFERR_RSVD_BIT) > -#define PFERR_FETCH_MASK BIT(PFERR_FETCH_BIT) > -#define PFERR_PK_MASK BIT(PFERR_PK_BIT) > -#define PFERR_SGX_MASK BIT(PFERR_SGX_BIT) > -#define PFERR_GUEST_FINAL_MASK BIT_ULL(PFERR_GUEST_FINAL_BIT) > -#define PFERR_GUEST_PAGE_MASK BIT_ULL(PFERR_GUEST_PAGE_BIT) > -#define PFERR_IMPLICIT_ACCESS BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT) > +#define PFERR_PRESENT_MASK BIT(0) > +#define PFERR_WRITE_MASK BIT(1) > +#define PFERR_USER_MASK BIT(2) > +#define PFERR_RSVD_MASK BIT(3) > +#define PFERR_FETCH_MASK BIT(4) > +#define PFERR_PK_MASK BIT(5) > +#define PFERR_SGX_MASK BIT(15) > +#define PFERR_GUEST_FINAL_MASK BIT_ULL(32) > +#define PFERR_GUEST_PAGE_MASK BIT_ULL(33) > +#define PFERR_IMPLICIT_ACCESS BIT_ULL(48) > > #define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \ > PFERR_WRITE_MASK | \ > diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h > index 60f21bb4c27b..e8b620a85627 100644 > --- a/arch/x86/kvm/mmu.h > +++ b/arch/x86/kvm/mmu.h > @@ -213,7 +213,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, > */ > u64 implicit_access = access & PFERR_IMPLICIT_ACCESS; > bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC; > - int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1; > + int index = (pfec + (not_smap << ilog2(PFERR_RSVD_MASK))) >> 1; > u32 errcode = PFERR_PRESENT_MASK; > bool fault; > > @@ -235,7 +235,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, > > /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ > offset = (pfec & ~1) + > - ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT)); > + ((pte_access & PT_USER_MASK) << (ilog2(PFERR_RSVD_MASK) - PT_USER_SHIFT)); > > pkru_bits &= mmu->pkru_mask >> offset; > errcode |= -pkru_bits & PFERR_PK_MASK;
On Thu, Feb 29, 2024, Dongli Zhang wrote: > I remember I read somewhere suggesting not to change the headers in selftest. The "suggestion" is to not update the headers that perf tooling copies verbatim from the kernel, e.g. tools/include/uapi/linux/kvm.h. The duplicates in tools/ aren't used by KVM selftests, it's purely perf that needs identical copies from the kernel tree, so I strongly prefer to leave it to the perf folks to deal with synchronizing the headers as needed. > Just double-check if there is requirement to edit > tools/testing/selftests/kvm/include/x86_64/processor.h. This header is a KVM selftests specific header that is independent from the kernel headers. It does have _some_ copy+paste, mostly for architecturally defined bits and bobs, but it's not a straight copy of any kernel header. That said, yes, I think we should also clean up x86_64/processor.h. That can be done in a one-off standalone patch though.
On Thu, Feb 29, 2024, Paolo Bonzini wrote: > On Wed, Feb 28, 2024 at 3:46 AM Sean Christopherson <seanjc@google.com> wrote: > > diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h > > index 60f21bb4c27b..e8b620a85627 100644 > > --- a/arch/x86/kvm/mmu.h > > +++ b/arch/x86/kvm/mmu.h > > @@ -213,7 +213,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, > > */ > > u64 implicit_access = access & PFERR_IMPLICIT_ACCESS; > > bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC; > > - int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1; > > + int index = (pfec + (not_smap << ilog2(PFERR_RSVD_MASK))) >> 1; > > Just use "(pfec + (not_smap ? PFERR_RSVD_MASK : 0)) >> 1". > > Likewise below, "pte_access & PT_USER_MASK ? PFERR_RSVD_MASK : 0"/ > > No need to even check what the compiler produces, it will be either > exactly the same code or a bunch of cmov instructions. I couldn't resist :-) The second one generates identical code, but for this one: int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1; gcc generates almost bizarrely different code in the call from vcpu_mmio_gva_to_gpa(). clang is clever enough to realize "pfec" can only contain USER_MASK and/or WRITE_MASK, and so does a ton of dead code elimination and other optimizations. But for some reason, gcc doesn't appear to realize that, and generates a MOVSX when computing "index", i.e. sign-extends the result of the ADD (at least, I think that's what it's doing). There's no actual bug today, and the vcpu_mmio_gva_to_gpa() path is super safe since KVM fully controls the error code. But the call from FNAME(walk_addr_generic) uses a _much_ more dynamic error code. If an error code with unexpected bits set managed to get into permission_fault(), I'm pretty sure we'd end up with out-of-bounds accesses. KVM sanity checks that PK and RSVD aren't set, WARN_ON(pfec & (PFERR_PK_MASK | PFERR_RSVD_MASK)); but KVM unnecessarily uses an ADD instead of OR, here int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1; and here /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ offset = (pfec & ~1) + ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT)); i.e. if the WARN fired, KVM would generate completely unexpected values due to adding two RSVD bit flags. And if _really_ unexpected flags make their way into permission_fault(), e.g. the upcoming RMP flag (bit 31) or Intel's SGX flag (bit 15), then the use of index fault = (mmu->permissions[index] >> pte_access) & 1; could generate a read waaaya outside of the array. It can't/shouldn't happen in practice since KVM shouldn't be trying to emulate RMP violations or faults in SGX enclaves, but it's unnecessarily dangerous. Long story short, I think we should get to the below (I'll post a separate series, assuming I'm not missing something). unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu); unsigned int pfec = access & (PFERR_PRESENT_MASK | PFERR_WRITE_MASK | PFERR_USER_MASK | PFERR_FETCH_MASK); /* * For explicit supervisor accesses, SMAP is disabled if EFLAGS.AC = 1. * For implicit supervisor accesses, SMAP cannot be overridden. * * SMAP works on supervisor accesses only, and not_smap can * be set or not set when user access with neither has any bearing * on the result. * * We put the SMAP checking bit in place of the PFERR_RSVD_MASK bit; * this bit will always be zero in pfec, but it will be one in index * if SMAP checks are being disabled. */ u64 implicit_access = access & PFERR_IMPLICIT_ACCESS; bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC; int index = (pfec | (not_smap ? PFERR_RSVD_MASK : 0)) >> 1; u32 errcode = PFERR_PRESENT_MASK; bool fault; kvm_mmu_refresh_passthrough_bits(vcpu, mmu); fault = (mmu->permissions[index] >> pte_access) & 1; /* * Sanity check that no bits are set in the legacy #PF error code * (bits 31:0) other than the supported permission bits (see above). */ WARN_ON_ONCE(pfec != (unsigned int)access); if (unlikely(mmu->pkru_mask)) { u32 pkru_bits, offset; /* * PKRU defines 32 bits, there are 16 domains and 2 * attribute bits per domain in pkru. pte_pkey is the * index of the protection domain, so pte_pkey * 2 is * is the index of the first bit for the domain. */ pkru_bits = (vcpu->arch.pkru >> (pte_pkey * 2)) & 3; /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ offset = (pfec & ~1) | (pte_access & PT_USER_MASK ? PFERR_RSVD_MASK : 0); pkru_bits &= mmu->pkru_mask >> offset; errcode |= -pkru_bits & PFERR_PK_MASK; fault |= (pkru_bits != 0); } return -(u32)fault & errcode;
On Thu, Feb 29, 2024 at 7:40 PM Sean Christopherson <seanjc@google.com> wrote: > Long story short, I think we should get to the below (I'll post a separate series, > assuming I'm not missing something). > > unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu); > unsigned int pfec = access & (PFERR_PRESENT_MASK | > PFERR_WRITE_MASK | > PFERR_USER_MASK | > PFERR_FETCH_MASK); > > /* > * For explicit supervisor accesses, SMAP is disabled if EFLAGS.AC = 1. > * For implicit supervisor accesses, SMAP cannot be overridden. > * > * SMAP works on supervisor accesses only, and not_smap can > * be set or not set when user access with neither has any bearing > * on the result. > * > * We put the SMAP checking bit in place of the PFERR_RSVD_MASK bit; > * this bit will always be zero in pfec, but it will be one in index > * if SMAP checks are being disabled. > */ > u64 implicit_access = access & PFERR_IMPLICIT_ACCESS; > bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC; > int index = (pfec | (not_smap ? PFERR_RSVD_MASK : 0)) >> 1; > u32 errcode = PFERR_PRESENT_MASK; > bool fault; Sounds good. The whole series is Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> apart from the small nits that were pointed out here and there. Paolo
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index aaf5a25ea7ed..88cc523bafa8 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -254,28 +254,16 @@ enum x86_intercept_stage; KVM_GUESTDBG_INJECT_DB | \ KVM_GUESTDBG_BLOCKIRQ) - -#define PFERR_PRESENT_BIT 0 -#define PFERR_WRITE_BIT 1 -#define PFERR_USER_BIT 2 -#define PFERR_RSVD_BIT 3 -#define PFERR_FETCH_BIT 4 -#define PFERR_PK_BIT 5 -#define PFERR_SGX_BIT 15 -#define PFERR_GUEST_FINAL_BIT 32 -#define PFERR_GUEST_PAGE_BIT 33 -#define PFERR_IMPLICIT_ACCESS_BIT 48 - -#define PFERR_PRESENT_MASK BIT(PFERR_PRESENT_BIT) -#define PFERR_WRITE_MASK BIT(PFERR_WRITE_BIT) -#define PFERR_USER_MASK BIT(PFERR_USER_BIT) -#define PFERR_RSVD_MASK BIT(PFERR_RSVD_BIT) -#define PFERR_FETCH_MASK BIT(PFERR_FETCH_BIT) -#define PFERR_PK_MASK BIT(PFERR_PK_BIT) -#define PFERR_SGX_MASK BIT(PFERR_SGX_BIT) -#define PFERR_GUEST_FINAL_MASK BIT_ULL(PFERR_GUEST_FINAL_BIT) -#define PFERR_GUEST_PAGE_MASK BIT_ULL(PFERR_GUEST_PAGE_BIT) -#define PFERR_IMPLICIT_ACCESS BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT) +#define PFERR_PRESENT_MASK BIT(0) +#define PFERR_WRITE_MASK BIT(1) +#define PFERR_USER_MASK BIT(2) +#define PFERR_RSVD_MASK BIT(3) +#define PFERR_FETCH_MASK BIT(4) +#define PFERR_PK_MASK BIT(5) +#define PFERR_SGX_MASK BIT(15) +#define PFERR_GUEST_FINAL_MASK BIT_ULL(32) +#define PFERR_GUEST_PAGE_MASK BIT_ULL(33) +#define PFERR_IMPLICIT_ACCESS BIT_ULL(48) #define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \ PFERR_WRITE_MASK | \ diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 60f21bb4c27b..e8b620a85627 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -213,7 +213,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, */ u64 implicit_access = access & PFERR_IMPLICIT_ACCESS; bool not_smap = ((rflags & X86_EFLAGS_AC) | implicit_access) == X86_EFLAGS_AC; - int index = (pfec + (not_smap << PFERR_RSVD_BIT)) >> 1; + int index = (pfec + (not_smap << ilog2(PFERR_RSVD_MASK))) >> 1; u32 errcode = PFERR_PRESENT_MASK; bool fault; @@ -235,7 +235,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ offset = (pfec & ~1) + - ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT)); + ((pte_access & PT_USER_MASK) << (ilog2(PFERR_RSVD_MASK) - PT_USER_SHIFT)); pkru_bits &= mmu->pkru_mask >> offset; errcode |= -pkru_bits & PFERR_PK_MASK;