From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3B2D533C1B4; Thu, 4 Jun 2026 15:29:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780586973; cv=none; b=IyUyr7M/098p8/Dkb7MT6Xy6ouoRkpUEXpNFy+DOastyqzrxPUmctU7spjLFvh1YH2b7FKNsqD3yRo7p4/u0+fK9hefWg+hkt9cMuItJsZYG7FsR8sBuSgjHDtroSqIGA3fAF87TrHP09BI1+2Aj0BiDOq69blrLaqcfP7cpWoA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780586973; c=relaxed/simple; bh=bsr5b2gpdP7Z02h1Njek9qwNAkWcpQjmCyE6Te0xtUY=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=QfSfb2QN/TQjIYnCGmvvJlZrz5ktf0A7Qj9zps+ug+UG412h5m6a3h6VT0QzXPBz38Ip4uuiGeQ6JTeeeumhImce9pckXbOXBXMTy7oGb1TN3QlBnTvPf+83mg4MoR/ekZYblhwe8z6s4BS2aCr+BRtFgEiR0yxBvk9y16bZqzY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=u5tYSEK0; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="u5tYSEK0" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C5F644993; Thu, 4 Jun 2026 08:29:26 -0700 (PDT) Received: from [10.57.95.39] (unknown [10.57.95.39]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DA02C3F86F; Thu, 4 Jun 2026 08:29:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1780586971; bh=bsr5b2gpdP7Z02h1Njek9qwNAkWcpQjmCyE6Te0xtUY=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=u5tYSEK0WD6FzVygVZ2inUsRE7KPNU6aiooHb7WFFytVH7MwdY+o3iH91d3sWJQym G77ajQTrso6CQR5994wgSjTDCEuz6fiiAdnuNQFgcq6pkYJfcMWf+6whcM46UC6c2z 1s46Od/7JFr/FBCHQRzYdrTjrodXGQYEF9NX3838= Message-ID: <9d15479e-e36b-4865-804c-7d93eb339e4e@arm.com> Date: Thu, 4 Jun 2026 16:29:19 +0100 Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v7 20/42] KVM: SEV: Make 'uaddr' parameter optional for KVM_SEV_SNP_LAUNCH_UPDATE Content-Language: en-GB To: ackerleytng@google.com, aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, ira.weiny@intel.com, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Jason Gunthorpe , Vlastimil Babka Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev References: <20260522-gmem-inplace-conversion-v7-0-2f0fae496530@google.com> <20260522-gmem-inplace-conversion-v7-20-2f0fae496530@google.com> From: Suzuki K Poulose In-Reply-To: <20260522-gmem-inplace-conversion-v7-20-2f0fae496530@google.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 23/05/2026 01:18, Ackerley Tng via B4 Relay wrote: > From: Michael Roth > > For vm_memory_attributes=1, in-place conversion/population is not > supported, so the initial contents necessarily must need to come > from a separate src address, which is enforced by the current > implementation. However, for vm_memory_attributes=0, it is possible for > guest memory to be initialized directly from userspace by mmap()'ing the > guest_memfd and writing to it while the corresponding GPA ranges are in > a 'shared' state before converting them to the 'private' state expected > by KVM_SEV_SNP_LAUNCH_UPDATE. > > Update the handling/documentation for KVM_SEV_SNP_LAUNCH_UPDATE to allow > for 'uaddr' to be set to NULL when vm_memory_attributes=0, which > SNP_LAUNCH_UPDATE will then use to determine when it should/shouldn't > copy in data from a separate memory location. Continue to enforce > non-NULL for the original vm_memory_attributes=1 case. > > Signed-off-by: Michael Roth > [Added src_page check in error handling path when the firmware command fails] > [Dropped ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES] > Signed-off-by: Ackerley Tng > --- > Documentation/virt/kvm/x86/amd-memory-encryption.rst | 15 +++++++++++---- > arch/x86/kvm/svm/sev.c | 18 +++++++++++++----- > virt/kvm/kvm_main.c | 1 + > 3 files changed, 25 insertions(+), 9 deletions(-) > > diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Documentation/virt/kvm/x86/amd-memory-encryption.rst > index b2395dd4769de..43085f65b2d85 100644 > --- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst > +++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst > @@ -503,7 +503,8 @@ secrets. > > It is required that the GPA ranges initialized by this command have had the > KVM_MEMORY_ATTRIBUTE_PRIVATE attribute set in advance. See the documentation > -for KVM_SET_MEMORY_ATTRIBUTES for more details on this aspect. > +for KVM_SET_MEMORY_ATTRIBUTES/KVM_SET_MEMORY_ATTRIBUTES2 for more details on > +this aspect. > > Upon success, this command is not guaranteed to have processed the entire > range requested. Instead, the ``gfn_start``, ``uaddr``, and ``len`` fields of > @@ -511,9 +512,15 @@ range requested. Instead, the ``gfn_start``, ``uaddr``, and ``len`` fields of > remaining range that has yet to be processed. The caller should continue > calling this command until those fields indicate the entire range has been > processed, e.g. ``len`` is 0, ``gfn_start`` is equal to the last GFN in the > -range plus 1, and ``uaddr`` is the last byte of the userspace-provided source > -buffer address plus 1. In the case where ``type`` is KVM_SEV_SNP_PAGE_TYPE_ZERO, > -``uaddr`` will be ignored completely. > +range plus 1, and ``uaddr`` (if specified) is the last byte of the > +userspace-provided source buffer address plus 1. > + > +In the case where ``type`` is KVM_SEV_SNP_PAGE_TYPE_ZERO, ``uaddr`` will be > +ignored completely. Otherwise, ``uaddr`` is required if > +kvm.vm_memory_attributes=1 and optional if kvm.vm_memory_attributes=0, since > +in the latter case guest memory can be initialized directly from userspace > +prior to converting it to private and passing the GPA range on to this > +interface. Just to confirm, so the sev_gmem_prepare doesn't destroy the contents in the process of making it "private" ? i.e., the contents of a SNP shared page are preserved while transitioning to "SNP Private" (via RMP update). Suzuki > > Parameters (in): struct kvm_sev_snp_launch_update > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 1a361f08c7a3d..e1dbc827c2807 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -2343,7 +2343,15 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, > int level; > int ret; > > - if (WARN_ON_ONCE(sev_populate_args->type != KVM_SEV_SNP_PAGE_TYPE_ZERO && !src_page)) > + /* > + * For vm_memory_attributes=1, in-place conversion/population is not > + * supported, so the initial contents necessarily need to come from a > + * separate src address. For vm_memory_attributes=0, this isn't > + * necessarily the case, since the pages may have been populated > + * directly from userspace before calling KVM_SEV_SNP_LAUNCH_UPDATE. > + */ > + if (vm_memory_attributes && > + sev_populate_args->type != KVM_SEV_SNP_PAGE_TYPE_ZERO && !src_page) > return -EINVAL; > > ret = snp_lookup_rmpentry((u64)pfn, &assigned, &level); > @@ -2390,7 +2398,7 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, > */ > if (ret && !snp_page_reclaim(kvm, pfn) && > sev_populate_args->type == KVM_SEV_SNP_PAGE_TYPE_CPUID && > - sev_populate_args->fw_error == SEV_RET_INVALID_PARAM) { > + sev_populate_args->fw_error == SEV_RET_INVALID_PARAM && src_page) { > void *src_vaddr = kmap_local_page(src_page); > void *dst_vaddr = kmap_local_pfn(pfn); > > @@ -2423,8 +2431,8 @@ static int snp_launch_update(struct kvm *kvm, struct kvm_sev_cmd *argp) > if (copy_from_user(¶ms, u64_to_user_ptr(argp->data), sizeof(params))) > return -EFAULT; > > - pr_debug("%s: GFN start 0x%llx length 0x%llx type %d flags %d\n", __func__, > - params.gfn_start, params.len, params.type, params.flags); > + pr_debug("%s: GFN start 0x%llx length 0x%llx type %d flags %d src %llx\n", __func__, > + params.gfn_start, params.len, params.type, params.flags, params.uaddr); > > if (!params.len || !PAGE_ALIGNED(params.len) || params.flags || > (params.type != KVM_SEV_SNP_PAGE_TYPE_NORMAL && > @@ -2481,7 +2489,7 @@ static int snp_launch_update(struct kvm *kvm, struct kvm_sev_cmd *argp) > > params.gfn_start += count; > params.len -= count * PAGE_SIZE; > - if (params.type != KVM_SEV_SNP_PAGE_TYPE_ZERO) > + if (src && params.type != KVM_SEV_SNP_PAGE_TYPE_ZERO) > params.uaddr += count * PAGE_SIZE; > > if (copy_to_user(u64_to_user_ptr(argp->data), ¶ms, sizeof(params))) > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > index ba195bb239aaa..3bf212fd99193 100644 > --- a/virt/kvm/kvm_main.c > +++ b/virt/kvm/kvm_main.c > @@ -105,6 +105,7 @@ module_param(allow_unsafe_mappings, bool, 0444); > #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES > bool vm_memory_attributes = true; > module_param(vm_memory_attributes, bool, 0444); > +EXPORT_SYMBOL_FOR_KVM_INTERNAL(vm_memory_attributes); > #endif > DEFINE_STATIC_CALL_RET0(__kvm_get_memory_attributes, kvm_get_memory_attributes_t); > EXPORT_SYMBOL_FOR_KVM_INTERNAL(STATIC_CALL_KEY(__kvm_get_memory_attributes)); >