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 426DAC54E5D for ; Mon, 18 Mar 2024 21:02:24 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CEF996B0098; Mon, 18 Mar 2024 17:02:23 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C77816B0099; Mon, 18 Mar 2024 17:02:23 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AF1AA6B009A; Mon, 18 Mar 2024 17:02:23 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 9AA396B0098 for ; Mon, 18 Mar 2024 17:02:23 -0400 (EDT) Received: from smtpin30.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 605461608ED for ; Mon, 18 Mar 2024 21:02:23 +0000 (UTC) X-FDA: 81911382966.30.B6C586E Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) by imf20.hostedemail.com (Postfix) with ESMTP id 444D81C0016 for ; Mon, 18 Mar 2024 21:02:21 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=thiXWPex; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf20.hostedemail.com: domain of pgonda@google.com designates 209.85.208.50 as permitted sender) smtp.mailfrom=pgonda@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1710795741; 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:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=O5gZjTRSl4x8yAd+Qw3jrLTaZ/uMFzSSgIEwAnGQaeg=; b=ewoX3pCbAcfDES8TNOKSKv8d29Fz8hYYgrfDJfLw1i1FW/w0zbmlhLDQD8kFUM6hYjEM0G 6/tiVnhqEboG3QotbRfgsVsPtOa6Tz8iuENYP3jGfM3ZFSXG2Qmhovwthxz+EECXD+QEmX ftvL2rgz5qiUell8DqWWSnFRZTs4/ys= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=thiXWPex; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf20.hostedemail.com: domain of pgonda@google.com designates 209.85.208.50 as permitted sender) smtp.mailfrom=pgonda@google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1710795741; a=rsa-sha256; cv=none; b=8FEuZaG1Gc7LojDGLnzqjmwOCsEi8UC0PY8+rSyeRWPHurUmpB/iPec/NvyUDSfYiavnF/ ZTQi2jTyejUHXFqqmWM3awvEBaNqaUyltYYH7tyFlJFwSHU42+gSHt24Aw/60/Aq/14pS+ VUbDZsgRKOcE6KMOX4OhJrY2OlaPoZQ= Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-5687ebddd8eso5324a12.0 for ; Mon, 18 Mar 2024 14:02:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1710795740; x=1711400540; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=O5gZjTRSl4x8yAd+Qw3jrLTaZ/uMFzSSgIEwAnGQaeg=; b=thiXWPex0JUU3QsXbVZHOEW9VsIoIfYR9DoMKqhRQXKI6N490IJ5PURfEZ948a+Eiw 9HEf2e09e0vCSYl2P6UtagaF11+0A6ji9BmHETHnOBM0EdySQKLCSAvjHeQ1whcmz24v O8hiN9Jg8E6mmFy+cwHwBX0JHn/YJepnom0bCPOiiKHHRHYnZox50/72KXbi0dgnYrXZ dsFpuHfYA+RGVCRoBF1+uulEoinK3+ILmbkX3gdttBDmhDK9s+DjHfuirFKl6GHNf8Y/ oeLspYk6AVi9uU5are2JSBjKqhgYGGqcHYvD9FoflRyV6Q/ONiHd1b03clPwcfcp0jws yZkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710795740; x=1711400540; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=O5gZjTRSl4x8yAd+Qw3jrLTaZ/uMFzSSgIEwAnGQaeg=; b=g28cQvrKg0y0up6R6QOTKdVEmJDRFKHfx8VwTwKTJEDnUdTuPhHOJMRqYJ4zTObVX7 UbWCVFk3lGhXF1go4sjOrZl8A6m9ZnLPias8X9a0gNEw/DNNTncsxRs1amv8SwZvZqGR NrX6SGj31CTypmWmvh/6f5cMyMGY+8qMxaURWo60weWgc6yvsnhlxYA4Sf8KJjxpVVHv wznl1vpKwLLQUxVHT006hrSIlvZxGIYcv5Z11OGQqBB5AH0gZ1oc8WRfJSWAfz2oV2Za vq5APJFSwq/B41x0t6IbANZvXcQusXEr9Nwv3IwEs0oWXMpHPm31iTyp3BytX2FFoYb5 aClw== X-Forwarded-Encrypted: i=1; AJvYcCUk2qSwhd1/E+156kDlCfHXnTWMihwpxBSN6ZCbUbZa4BLagugUOGfHC/eeJReO3noAxD0tumytFXKcQyaNpPIo0ZU= X-Gm-Message-State: AOJu0Yxm0vTrGaOJAfz1VDEUgfq/i4H52FiI2QRsjaF9x8t4aasDfYNf 4GwrHfQSDr5lGzLCp2XkP7AE0M2oXuw5DjmcbzjEt/vcjZaAo/AkbM5juraUkHQDR0kDY0Ofl6w HyrGS600t83x/0hun/hoX49MSa+u818Oqi4IV X-Google-Smtp-Source: AGHT+IFivxti4l4UI/CAm+HxOzS2U25vJiH0+czbF7e4DZfoW53/wo+Dx8ivStQaqHTTVwkli/GuvoWdN+oEvPRUZQE= X-Received: by 2002:aa7:c3d0:0:b0:568:ce1e:94e5 with SMTP id l16-20020aa7c3d0000000b00568ce1e94e5mr17596edr.5.1710795739649; Mon, 18 Mar 2024 14:02:19 -0700 (PDT) MIME-Version: 1.0 References: <20231230172351.574091-1-michael.roth@amd.com> <20231230172351.574091-19-michael.roth@amd.com> In-Reply-To: <20231230172351.574091-19-michael.roth@amd.com> From: Peter Gonda Date: Mon, 18 Mar 2024 15:02:04 -0600 Message-ID: Subject: Re: [PATCH v11 18/35] KVM: SEV: Add KVM_SEV_SNP_LAUNCH_UPDATE command To: Michael Roth Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, linux-mm@kvack.org, linux-crypto@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, tglx@linutronix.de, mingo@redhat.com, jroedel@suse.de, thomas.lendacky@amd.com, hpa@zytor.com, ardb@kernel.org, pbonzini@redhat.com, seanjc@google.com, vkuznets@redhat.com, jmattson@google.com, luto@kernel.org, dave.hansen@linux.intel.com, slp@redhat.com, peterz@infradead.org, srinivas.pandruvada@linux.intel.com, rientjes@google.com, dovmurik@linux.ibm.com, tobin@ibm.com, bp@alien8.de, vbabka@suse.cz, kirill@shutemov.name, ak@linux.intel.com, tony.luck@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com, alpergun@google.com, jarkko@kernel.org, ashish.kalra@amd.com, nikunj.dadhania@amd.com, pankaj.gupta@amd.com, liam.merwick@oracle.com, zhi.a.wang@intel.com, Brijesh Singh Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 444D81C0016 X-Rspam-User: X-Rspamd-Server: rspam05 X-Stat-Signature: uq4931swwt6n61z1qzjsir8co119g8yi X-HE-Tag: 1710795741-171770 X-HE-Meta: U2FsdGVkX1/wypPvIC5Ckptsgmo0t6NP1MSNMdSgguslE+E7IKgTmS18js5mLauhOMDUSj4G86HPybisUA9PWn7sqPaCWqAg8vA3aA5QMIcuNTWzQzgDl30pstc1BUj8f+4j0b8uFeoHLh/uJJ7eym0PBUZqCvA/rtN1/SV/S3EniY0h1sT4LTUNsag7TO9UNhAXJ0Jf0CRlyAecj2Pbk05bqzvv0HWtxfhBA6KJckY3uqyihbpJgOCFLKt3ITe/hOaYCN21i0T0m9EKV10DU9hL0vTS0RPp8DWs5FRT5MwRoWiMp17/2kXDoyf2Gm6M/LLUliuVCr7Wm5OafGsxcWW4O9/lgcwSl6MlAxlhpZ68/r+KO/CHaDlNTrSR3OmarYZUC0XbPDlS6TvIfhodFaxVhBE1VDEsRCa5mnXCmbvloymXtOMje4E+LmM+IRE8UIYdBZjaI4mf0ZGpR7JpUp2fqMQU2NSXzVFh3BBMOMrE4lqHb3taSDKoIL7McbefXJLk4NPFOZ1yCzD7ivD3IlFGEubkpmHe3nf4o+ZS6g/dav4qbrhNr/wWhXugbFG0reJzhZtoPzqC6zMZHpp+vCbpu54zeA/rKX19/SgLeuMDxwXi9eYd6J6Npuv45kiIKru8vd6B9ShfH5uUmB8hVGPqdyZDoTyVQl25tv1k4ZxhsxJLlUYv+rQOboNL0FIEn8UGh6KX9+YFW/GWzyv9pD99JNHOfL/+z9Xe+pH6L8vIR0H6L22G48LX7gAU2mnDBx6S6S/z9dwdefKnb5GffqatLKnBfldXzWqSorktxYMfoL1tRyIjBrWPeNGiKTwlhw68hSF/0YV8M3EBTDnQWEBi+alGrb8ODyDPlCJuQOESLdWyTapdxbglezEr33NQ/POk3dAY/Es6RQToC9PM/mta+0tXLsHbyBUtjznpgrvKvDZ2HCtuRxDWoG6SxTE6pIMURn7Snue9jpgWR+7 HFWGgK1n Kud+YT4FN1rjUa66F4T4yUuhr0K3vBYtFYKDtnY/V7M51UlYUQajTeQWeZsXO1/KGjZB0l8sIYLwQ9bvR3OI7RcFcv9lE4ZQx9Vys0RebzE+HzLlUt1IJBFm+WzNunjnxrLJYwQcqz7npE8q5viCgno1eNkA3TpLiJRWnG7PPQzrN2E8OxFBUOy4TeHATzmwkJzq6ntuRyEiT+SiMwR4bFxCQkajlWK1A4MX3jCkrUHRjRWqUfXfj+nFZOS8EnamPKIeWDZkLGy/KGwlRLfJOfaIuIeCqBQE9ELkN1zZ8/xZ2roM= 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: List-Subscribe: List-Unsubscribe: On Sat, Dec 30, 2023 at 10:27=E2=80=AFAM Michael Roth wrote: > > From: Brijesh Singh > > The KVM_SEV_SNP_LAUNCH_UPDATE command can be used to insert data into > the guest's memory. The data is encrypted with the cryptographic context > created with the KVM_SEV_SNP_LAUNCH_START. > > In addition to the inserting data, it can insert a two special pages > into the guests memory: the secrets page and the CPUID page. > > While terminating the guest, reclaim the guest pages added in the RMP > table. If the reclaim fails, then the page is no longer safe to be > released back to the system and leak them. > > For more information see the SEV-SNP specification. > > Co-developed-by: Michael Roth > Signed-off-by: Michael Roth > Signed-off-by: Brijesh Singh > Signed-off-by: Ashish Kalra > --- > .../virt/kvm/x86/amd-memory-encryption.rst | 28 +++ > arch/x86/kvm/svm/sev.c | 181 ++++++++++++++++++ > include/uapi/linux/kvm.h | 19 ++ > 3 files changed, 228 insertions(+) > > diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Docum= entation/virt/kvm/x86/amd-memory-encryption.rst > index b1beb2fe8766..d4325b26724c 100644 > --- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst > +++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst > @@ -485,6 +485,34 @@ Returns: 0 on success, -negative on error > > See the SEV-SNP specification for further detail on the launch input. > > +20. KVM_SNP_LAUNCH_UPDATE > +------------------------- > + > +The KVM_SNP_LAUNCH_UPDATE is used for encrypting a memory region. It als= o > +calculates a measurement of the memory contents. The measurement is a si= gnature > +of the memory contents that can be sent to the guest owner as an attesta= tion > +that the memory was encrypted correctly by the firmware. Nit: The measurement is a rolling hash of all the launch updated pages and their metadata. The attestation quote contains a signature of information about the SNP VM including this measurement. Also technically the attestation doesn't confirm to the guest owner the memory was encrypted correctly, I don't think we can cryptographically prove that. But the attestation does provide the guest owner confirmation about the exact steps the ASP took in creating the SNP VMs initial memory context. If the ASP firmware is bug free and follows the spec, your 'memory was encrypted correctly by the firmware' line is implied. > + > +Parameters (in): struct kvm_snp_launch_update > + > +Returns: 0 on success, -negative on error > + > +:: > + > + struct kvm_sev_snp_launch_update { > + __u64 start_gfn; /* Guest page number to start fr= om. */ > + __u64 uaddr; /* userspace address need to be = encrypted */ > + __u32 len; /* length of memory region */ > + __u8 imi_page; /* 1 if memory is part of the IM= I */ > + __u8 page_type; /* page type */ > + __u8 vmpl3_perms; /* VMPL3 permission mask */ > + __u8 vmpl2_perms; /* VMPL2 permission mask */ > + __u8 vmpl1_perms; /* VMPL1 permission mask */ > + }; > + > +See the SEV-SNP spec for further details on how to build the VMPL permis= sion > +mask and page type. > + > References > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index e2f4d4bc125c..d60209e6e68b 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -245,6 +245,36 @@ static void sev_decommission(unsigned int handle) > sev_guest_decommission(&decommission, NULL); > } > > +static int snp_page_reclaim(u64 pfn) > +{ > + struct sev_data_snp_page_reclaim data =3D {0}; > + int err, rc; > + > + data.paddr =3D __sme_set(pfn << PAGE_SHIFT); > + rc =3D sev_do_cmd(SEV_CMD_SNP_PAGE_RECLAIM, &data, &err); > + if (rc) { > + /* > + * If the reclaim failed, then page is no longer safe > + * to use. > + */ > + snp_leak_pages(pfn, 1); > + } > + > + return rc; > +} > + > +static int host_rmp_make_shared(u64 pfn, enum pg_level level, bool leak) > +{ > + int rc; > + > + rc =3D rmp_make_shared(pfn, level); > + if (rc && leak) > + snp_leak_pages(pfn, > + page_level_size(level) >> PAGE_SHIFT); > + > + return rc; > +} > + > static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) > { > struct sev_data_deactivate deactivate; > @@ -1990,6 +2020,154 @@ static int snp_launch_start(struct kvm *kvm, stru= ct kvm_sev_cmd *argp) > return rc; > } > > +static int snp_launch_update_gfn_handler(struct kvm *kvm, > + struct kvm_gfn_range *range, > + void *opaque) > +{ > + struct kvm_sev_info *sev =3D &to_kvm_svm(kvm)->sev_info; > + struct kvm_memory_slot *memslot =3D range->slot; > + struct sev_data_snp_launch_update data =3D {0}; > + struct kvm_sev_snp_launch_update params; > + struct kvm_sev_cmd *argp =3D opaque; > + int *error =3D &argp->error; > + int i, n =3D 0, ret =3D 0; > + unsigned long npages; > + kvm_pfn_t *pfns; > + gfn_t gfn; > + > + if (!kvm_slot_can_be_private(memslot)) { > + pr_err("SEV-SNP requires private memory support via guest= _memfd.\n"); > + return -EINVAL; > + } > + > + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data,= sizeof(params))) { > + pr_err("Failed to copy user parameters for SEV-SNP launch= .\n"); > + return -EFAULT; > + } > + > + data.gctx_paddr =3D __psp_pa(sev->snp_context); > + > + npages =3D range->end - range->start; > + pfns =3D kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL_ACCOUNT= ); > + if (!pfns) > + return -ENOMEM; > + > + pr_debug("%s: GFN range 0x%llx-0x%llx, type %d\n", __func__, > + range->start, range->end, params.page_type); > + > + for (gfn =3D range->start, i =3D 0; gfn < range->end; gfn++, i++)= { > + int order, level; > + bool assigned; > + void *kvaddr; > + > + ret =3D __kvm_gmem_get_pfn(kvm, memslot, gfn, &pfns[i], &= order, false); > + if (ret) > + goto e_release; > + > + n++; > + ret =3D snp_lookup_rmpentry((u64)pfns[i], &assigned, &lev= el); > + if (ret || assigned) { > + pr_err("Failed to ensure GFN 0x%llx is in initial= shared state, ret: %d, assigned: %d\n", > + gfn, ret, assigned); > + return -EFAULT; > + } > + > + kvaddr =3D pfn_to_kaddr(pfns[i]); > + if (!virt_addr_valid(kvaddr)) { > + pr_err("Invalid HVA 0x%llx for GFN 0x%llx\n", (ui= nt64_t)kvaddr, gfn); > + ret =3D -EINVAL; > + goto e_release; > + } > + > + ret =3D kvm_read_guest_page(kvm, gfn, kvaddr, 0, PAGE_SIZ= E); > + if (ret) { > + pr_err("Guest read failed, ret: 0x%x\n", ret); Should these be pr_debugs()? This could get noisy. > + goto e_release; > + } > + > + ret =3D rmp_make_private(pfns[i], gfn << PAGE_SHIFT, PG_L= EVEL_4K, > + sev_get_asid(kvm), true); > + if (ret) { > + ret =3D -EFAULT; > + goto e_release; > + } > + > + data.address =3D __sme_set(pfns[i] << PAGE_SHIFT); > + data.page_size =3D PG_LEVEL_TO_RMP(PG_LEVEL_4K); > + data.page_type =3D params.page_type; > + data.vmpl3_perms =3D params.vmpl3_perms; > + data.vmpl2_perms =3D params.vmpl2_perms; > + data.vmpl1_perms =3D params.vmpl1_perms; > + ret =3D __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_LAUNCH_= UPDATE, > + &data, error); > + if (ret) { > + pr_err("SEV-SNP launch update failed, ret: 0x%x, = fw_error: 0x%x\n", > + ret, *error); > + snp_page_reclaim(pfns[i]); > + > + /* > + * When invalid CPUID function entries are detect= ed, the firmware > + * corrects these entries for debugging purpose a= nd leaves the > + * page unencrypted so it can be provided users f= or debugging > + * and error-reporting. > + * > + * Copy the corrected CPUID page back to shared m= emory so > + * userpsace can retrieve this information. Typo: userpsace