From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4F2EC43217 for ; Wed, 16 Nov 2022 22:13:13 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6BCDA8E0001; Wed, 16 Nov 2022 17:13:13 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 66C166B007B; Wed, 16 Nov 2022 17:13:13 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 533808E0001; Wed, 16 Nov 2022 17:13:13 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 3E92C6B0078 for ; Wed, 16 Nov 2022 17:13:13 -0500 (EST) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 16F4EA0BC5 for ; Wed, 16 Nov 2022 22:13:13 +0000 (UTC) X-FDA: 80140707066.19.24A5EEA Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) by imf08.hostedemail.com (Postfix) with ESMTP id AE476160008 for ; Wed, 16 Nov 2022 22:13:12 +0000 (UTC) Received: by mail-pf1-f178.google.com with SMTP id z26so18801492pff.1 for ; Wed, 16 Nov 2022 14:13:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=LEALi84Ium1ZlWZzXz+cwmcGDIY43dRDsmFo60UxT98=; b=ahJ8bsoBVgCCr8jscmazuErp1mcQI1GMVSN2Oxb3HpXUz+ero20SbhLgGY9RN/H+xD tFV3t/zAOJii91OWn9GYaKLEyrD3W909tKm2iGNsxzCbCGxYeFicSe43FkMw3GrxNaZ4 QEGWUsO8rKh/1aRQGDInDmRqtr1Uh9x4T4xE6Uyjgq8L1s43VxjHes14Oqogismgc+Hz hM+9p0PlJEfu2Vm2j+80XeoERr1jltAIVvqBvqBzdoq18EHFXEu2PM8hqeKwoj0zSd5c QktiEetb5wdRlA9m0xLmXCpLd9EkKJQux+HW3MyXNOrVpvVh4V4725vD5tPgEwbYQN7X nxHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=LEALi84Ium1ZlWZzXz+cwmcGDIY43dRDsmFo60UxT98=; b=ILf5ZFA5J+Y8eICI/7h2kTd8rNyKOyd2x81XnX4hLl2wRmIlEcp0ipMnwLjCl1AfbB D/RLTuCwu44zXE2WI5LjALq+ntkuIKTnK9ymsCAeWWNm2gWuCoJewnnzWVJHI1dopgpH HQyMnLO1pW3c+hobcKC/tRBXUNZNXaqyeiATeyPnyEqPm8Uf7vwJMB5DjIFklRWv1EYE 1hEjDW8/0n47dN4tP8XClk7XJQEbwSfrJqTZEHbBx3fnhUutB52zm9yrZyacV4Rcm4Oh ByBWsLDSjTOAeNudRtzPBorkxdWMAxoNcyR1P9y0JoKHVDJJAx6EXrQvGDO+PkLu77o+ A/FA== X-Gm-Message-State: ANoB5pk9FM+JFK2xPE49Oohn57BWw0AfOhJEAP9nVJWqp6GtM10oKXKB HH8WBih8eW3M4BS8BfkZe8jq2Q== X-Google-Smtp-Source: AA0mqf6tUAmTqse/Fkst1piL5RNn0zRmV8+vRAL9N/G2uaYzEal3MxGusaZa1JYBear3ieq3f8Blvg== X-Received: by 2002:a63:454e:0:b0:476:cdb8:28fd with SMTP id u14-20020a63454e000000b00476cdb828fdmr7485375pgk.358.1668636791454; Wed, 16 Nov 2022 14:13:11 -0800 (PST) Received: from google.com (7.104.168.34.bc.googleusercontent.com. [34.168.104.7]) by smtp.gmail.com with ESMTPSA id h4-20020a170902680400b0017b264a2d4asm12676465plk.44.2022.11.16.14.13.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Nov 2022 14:13:11 -0800 (PST) Date: Wed, 16 Nov 2022 22:13:07 +0000 From: Sean Christopherson To: Ackerley Tng Cc: chao.p.peng@linux.intel.com, aarcange@redhat.com, ak@linux.intel.com, akpm@linux-foundation.org, bfields@fieldses.org, bp@alien8.de, corbet@lwn.net, dave.hansen@intel.com, david@redhat.com, ddutile@redhat.com, dhildenb@redhat.com, hpa@zytor.com, hughd@google.com, jlayton@kernel.org, jmattson@google.com, joro@8bytes.org, jun.nakajima@intel.com, kirill.shutemov@linux.intel.com, kvm@vger.kernel.org, linux-api@vger.kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, luto@kernel.org, mail@maciej.szmigiero.name, mhocko@suse.com, michael.roth@amd.com, mingo@redhat.com, pbonzini@redhat.com, qemu-devel@nongnu.org, qperret@google.com, rppt@kernel.org, shuah@kernel.org, songmuchun@bytedance.com, steven.price@arm.com, tabba@google.com, tglx@linutronix.de, vannapurve@google.com, vbabka@suse.cz, vkuznets@redhat.com, wanpengli@tencent.com, wei.w.wang@intel.com, x86@kernel.org, yu.c.zhang@linux.intel.com Subject: Re: [PATCH v9 7/8] KVM: Handle page fault for private memory Message-ID: References: <20221025151344.3784230-8-chao.p.peng@linux.intel.com> <20221116205025.1510291-1-ackerleytng@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20221116205025.1510291-1-ackerleytng@google.com> ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1668636792; a=rsa-sha256; cv=none; b=SKnQEOdedUVmtv5Cv9bvmlh4Nl98eD4cYmlfbFoWcJcoDMRJv/sq7ADLQYZxt80ZbU1kAs HbqboScVf6fZFT+6mgoLLgCQSjhHxfOEdEGiBz4idW7MDbYeYm0AkUsC7eeCB5aweg4iz0 6JX9BKWawiNYR1XrYhroNmX0j+8Ddwk= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=ahJ8bsoB; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of seanjc@google.com designates 209.85.210.178 as permitted sender) smtp.mailfrom=seanjc@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1668636792; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=LEALi84Ium1ZlWZzXz+cwmcGDIY43dRDsmFo60UxT98=; b=LKJko9MqdlI439RRoPPmq8z9M7y2oA4JYVJrNTc8pTKylftkTbD2Pi4N+eAAxXBDY9HEte JuAElKDPQ1htbXIZiSGKiZwh/s7M2iDY2PSDyivaB6Y9DErBYW1OPbp+lWym1n4QQRMkmN EkJ4sK+JFXmDwuAThwgkpOUYBcYK8ik= X-Rspam-User: Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=ahJ8bsoB; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of seanjc@google.com designates 209.85.210.178 as permitted sender) smtp.mailfrom=seanjc@google.com X-Rspamd-Server: rspam02 X-Stat-Signature: x1iz5thja5kqdzcgbfh16p6bspu3tmih X-Rspamd-Queue-Id: AE476160008 X-HE-Tag: 1668636792-500511 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Wed, Nov 16, 2022, Ackerley Tng wrote: > >@@ -4173,6 +4203,22 @@ static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) > > return RET_PF_EMULATE; > > } > > > >+ if (kvm_slot_can_be_private(slot) && > >+ fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) { > >+ vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT; > >+ if (fault->is_private) > >+ vcpu->run->memory.flags = KVM_MEMORY_EXIT_FLAG_PRIVATE; > >+ else > >+ vcpu->run->memory.flags = 0; > >+ vcpu->run->memory.padding = 0; > >+ vcpu->run->memory.gpa = fault->gfn << PAGE_SHIFT; > >+ vcpu->run->memory.size = PAGE_SIZE; > >+ return RET_PF_USER; > >+ } > >+ > >+ if (fault->is_private) > >+ return kvm_faultin_pfn_private(fault); > >+ > > Since each memslot may also not be backed by restricted memory, we > should also check if the memslot has been set up for private memory > with > > if (fault->is_private && kvm_slot_can_be_private(slot)) > return kvm_faultin_pfn_private(fault); > > Without this check, restrictedmem_get_page will get called with NULL > in slot->restricted_file, which causes a NULL pointer dereference. Hmm, silently skipping the faultin would result in KVM faulting in the shared portion of the memslot, and I believe would end up mapping that pfn as private, i.e. would map a non-UPM PFN as a private mapping. For TDX and SNP, that would be double ungood as it would let the host access memory that is mapped private, i.e. lead to #MC or #PF(RMP) in the host. I believe the correct solution is to drop the "can be private" check from the above check, and instead handle that in kvm_faultin_pfn_private(). That would fix another bug, e.g. if the fault is shared, the slot can't be private, but for whatever reason userspace marked the gfn as private. Even though KVM might be able service the fault, the correct thing to do in that case is to exit to userspace. E.g. --- arch/x86/kvm/mmu/mmu.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 10017a9f26ee..e2ac8873938e 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4158,11 +4158,29 @@ static inline u8 order_to_level(int order) return PG_LEVEL_4K; } -static int kvm_faultin_pfn_private(struct kvm_page_fault *fault) +static int kvm_do_memory_fault_exit(struct kvm_vcpu *vcpu, + struct kvm_page_fault *fault) +{ + vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT; + if (fault->is_private) + vcpu->run->memory.flags = KVM_MEMORY_EXIT_FLAG_PRIVATE; + else + vcpu->run->memory.flags = 0; + vcpu->run->memory.padding = 0; + vcpu->run->memory.gpa = fault->gfn << PAGE_SHIFT; + vcpu->run->memory.size = PAGE_SIZE; + return RET_PF_USER; +} + +static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu, + struct kvm_page_fault *fault) { int order; struct kvm_memory_slot *slot = fault->slot; + if (kvm_slot_can_be_private(slot)) + return kvm_do_memory_fault_exit(vcpu, fault); + if (kvm_restricted_mem_get_pfn(slot, fault->gfn, &fault->pfn, &order)) return RET_PF_RETRY; @@ -4203,21 +4221,11 @@ static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) return RET_PF_EMULATE; } - if (kvm_slot_can_be_private(slot) && - fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) { - vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT; - if (fault->is_private) - vcpu->run->memory.flags = KVM_MEMORY_EXIT_FLAG_PRIVATE; - else - vcpu->run->memory.flags = 0; - vcpu->run->memory.padding = 0; - vcpu->run->memory.gpa = fault->gfn << PAGE_SHIFT; - vcpu->run->memory.size = PAGE_SIZE; - return RET_PF_USER; - } + if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) + return kvm_do_memory_fault_exit(vcpu, fault); if (fault->is_private) - return kvm_faultin_pfn_private(fault); + return kvm_faultin_pfn_private(vcpu, fault); async = false; fault->pfn = __gfn_to_pfn_memslot(slot, fault->gfn, false, &async, base-commit: 969d761bb7b8654605937f31ae76123dcb7f15a3 --