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 E1D14C7EE23 for ; Thu, 2 Mar 2023 00:02:55 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1577E6B0071; Wed, 1 Mar 2023 19:02:55 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 111316B0073; Wed, 1 Mar 2023 19:02:55 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EC2F46B0074; Wed, 1 Mar 2023 19:02:54 -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 DB0E56B0071 for ; Wed, 1 Mar 2023 19:02:54 -0500 (EST) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id A0D03C0A28 for ; Thu, 2 Mar 2023 00:02:54 +0000 (UTC) X-FDA: 80522007468.15.A0E62B3 Received: from mail-lj1-f182.google.com (mail-lj1-f182.google.com [209.85.208.182]) by imf16.hostedemail.com (Postfix) with ESMTP id 898F6180013 for ; Thu, 2 Mar 2023 00:02:52 +0000 (UTC) Authentication-Results: imf16.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=dNvQTh8k; spf=pass (imf16.hostedemail.com: domain of zhi.wang.linux@gmail.com designates 209.85.208.182 as permitted sender) smtp.mailfrom=zhi.wang.linux@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1677715372; 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=+mEYUoqzkV4y6vsMO1Tnsa6bn7KUqmY0W5AVOdUCN8g=; b=w4XYBYPC8TLv0rjD8DX68gso5kduPW71L8naU56I7UP/xwgIA6FlWz0zP95v2vZL6Nj/ZI BdAyGJNmw7X9jDG19FWwl5OhaBwjrABXEAxbr7H+m83UiASnDyDElc2WFoJzfRp0jN20Eq KMbkhUE4lXoputyyNnNqvSKKd8tO+BE= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=dNvQTh8k; spf=pass (imf16.hostedemail.com: domain of zhi.wang.linux@gmail.com designates 209.85.208.182 as permitted sender) smtp.mailfrom=zhi.wang.linux@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1677715372; a=rsa-sha256; cv=none; b=sGnoqaAraMaVasZkFxgp4OgyGNBNd2zFDsVWI8TCEjep+0Ifd7Qdhz3rvbdAkXQ92PNy1c K3zbE+pvYd06ILfUrdHpsDdQ8bMwh9+YgtdwQaD/0kW5OS208J4oTCBQSKwgTsNH/2os8/ lkqQWHg1i/Z2YtRyXPkTQ38op5giojw= Received: by mail-lj1-f182.google.com with SMTP id by8so15856015ljb.7 for ; Wed, 01 Mar 2023 16:02:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1677715371; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=+mEYUoqzkV4y6vsMO1Tnsa6bn7KUqmY0W5AVOdUCN8g=; b=dNvQTh8k3DnN0lwNU0AYKg+hLxSqZa0EsGqc8+Z5Bqudjprv9CWoBml91KkNT6PUbO ruojlGrNqFgiBQwuLiuvPhXCfCfpxZAiVR1+7DnrLVZV/SDJfBZsgTbM5t32cm2edvwK 679Obb1Wh/fTJg/LeEdLZYOQSrCi23VyT6WfYbs5X7ZUq2JPNhQyQAwaxUGtjgI+nKkQ 1lvbWOzxoBPj0ZhY4N7/3lpUEDQZnbeBgyCHXpJWf298ODDpVmMiVtH/KAkudDLV43Dr 9McqHU09OPXl0PEvUWq08TBwk5na5mruZxmZTl8y3NQKTuPPx4J5ye6DwtjEgszg71fC vM2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677715371; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+mEYUoqzkV4y6vsMO1Tnsa6bn7KUqmY0W5AVOdUCN8g=; b=qEg1VTJDmc2xXjj0s5GNZhchMMwHcI0HpbbuCaY4UXm4yhF8bJPk/pzbCbhxvBzWSr cm4nmu+DvX+v6rUvY7ZRa/6iNTtVjUl5Vc9f0wtwPPdjJl/1VmAW8yeppB0j78469yOM 64pzstIlA3uDjlvV7MJq1/E5NZbQJR3Usv6WihIem5JKag/VFN17uwaSLWoZN01mlONK 2w7ZAC4BM1+DejInBIRo56s7kreAEABMhwI3n2f6bEKj4+6B5W9SZT+WIaRiqWI6MOdS YpaIpMBHNUK87V09x9d/NwQMlyl0ZvgOom23uFKc2kB4lviCCRMayW36cdU6AnpXHAml xKGg== X-Gm-Message-State: AO0yUKXEmwh7NqcvVeC71gQMsbehUOPz1Atyf08Dd7eycopEPKWBCGgc IA2hTBovDDWqH+jcPNDIV7E= X-Google-Smtp-Source: AK7set/1liEDyyq962/VgpuqfVI283EUk4PS3DgsvEElOZ+Q4nC8n4n5DK3006LuS6BXBNGSvSfclw== X-Received: by 2002:a2e:960d:0:b0:295:9d09:680d with SMTP id v13-20020a2e960d000000b002959d09680dmr2143470ljh.0.1677715370579; Wed, 01 Mar 2023 16:02:50 -0800 (PST) Received: from localhost (88-115-161-74.elisa-laajakaista.fi. [88.115.161.74]) by smtp.gmail.com with ESMTPSA id p17-20020a2eb991000000b00295b1ad177csm1656830ljp.68.2023.03.01.16.02.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Mar 2023 16:02:48 -0800 (PST) Date: Thu, 2 Mar 2023 02:02:45 +0200 From: Zhi Wang To: Michael Roth Cc: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Dionna Glaze Subject: Re: [PATCH RFC v8 54/56] x86/sev: Add KVM commands for instance certs Message-ID: <20230302020245.00006f57@gmail.com> In-Reply-To: <20230220183847.59159-55-michael.roth@amd.com> References: <20230220183847.59159-1-michael.roth@amd.com> <20230220183847.59159-55-michael.roth@amd.com> X-Mailer: Claws Mail 4.1.0 (GTK 3.24.33; x86_64-w64-mingw32) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: 898F6180013 X-Stat-Signature: g11umk5uxog9sk6znjtbagnej94yiw6m X-Rspam-User: X-HE-Tag: 1677715372-695259 X-HE-Meta: U2FsdGVkX1+wzymFaOnodD4vDy4h83lm8ppcUTuQ1sJ+9Zdi7g0zxhjdaXbRzNTlZ2MmAZV5D0HtF/L0N/2xPs30fyohAZ4k9h2XOSnVuqwRzWG3PFt3xzOMToMa0pqziHDBIp2TPToXisFTjuAV9Z/QeMFYwHdVxe5gg5Oepomq7oBUJj6iHEiKMHkiDJ1Ddawx3t3xclD3jVQAVoyy01izHn8nRbCXTYOgT5ik56o1pL9SsJ/QuGyznAg2llcit6Z0VU4GMZQL7U0NHmAjnIbVTWxtk06TT68apmVqCFFoRXWzlcPY6+XllMUONrhR7oYu9MAraKO1GUKvHOjFnpdv2lY0zO5Xm6fhRsCN7nd5R23fQW18tGhj11Immr6MvlAgoa0VIpFFQWkm1+z7C6y6lrHV+5Vc7h2yDFICjIxpeIdCpPvalfphtPOvAe/pI6pkO0NLoMWJgl5HJi0X7a6J0NIDaEHR255ORvZ9G232wQLDhCnsViJjAXYrYbWGaNIj035YMwi8sdEDu0IPtAygWTGeyWpkALzQ7i3q9SbkDcNza7KBWi4vXhfQJ+PsumHAHbxq3HAq9ajwchwdPn/GeA5yOrKsKt+OY/9mdRwAlkFDLktGcKILH1Dm0nyWJFaLsfUIf+zPfBj0yMBAjdCqs+1hH2nHbMCOSlbc+OTd70k+MUf7xULrBqjk9HxXf6pGF2vhGweDGmLJumsJa+kC4q0rBh2Ay+DCsapCSI476z2Q46Mjf9g1RFOrH17DbnomZpw9jAEaeyLrA/Aw2VjZIqe35BES19iz0fuLyBpYVzCDx6JiFSp9QE/GS3cWer0FQjWMErL4pE5Yv0uKsS48ZE6Xmd5cH2My9VngcCoxwjWRrNOsPotRXTRlLCpdyfRAam6xQG/5vZ0kt7YMizcodIf8Mte1qxdbsV0RP9AnuIyZKQV2p1U50h5Y0IkFbgE23IyZABnI2dhC/tC qyVO+5lC HX+a68ge9qRynB7A9Tm//qJoI6RBPzTdiszHxbyogpHjGXKrwVY1S/Wvf5bRo1SbJQvnOfHAx4CGaGp+axPiIRlngrZxejM8aeOBMdPvP3pPSlCTpL7cHC8v3kzO0TttQypJnyMbOz+leBkIZf956dRRTQHf3amMwnWxX+/BFSrfZA49fQD/5K96hgDN0LaFh+ImK/Y+SoyZWEFBAO1utXgmsPukX3eGbDKc59AknvcSaJ7lvafMkk7SP2V8X4aKv7v8lE3goaK/BtRLbWwcY8gJFcJuCDPZUzdcIJ1ugfSMwXZWQ78hpHsyCq8rA/MIvQSG8WzmKjOSlk5j3X6E3eSqSqIW0ik6Qnbyv+VQHtHcmOzcWVzyJoJfvNu+imWD7vwg8bimfhwaF+bDEs312p+uBkG8fBlGfmJHa0CVxryOivXZJfltFkPjckkgTvMRGbMZXTGHmLjsgRRAoQHHbkgJKf/31o6nD7QWu6zK1/XdPVmKx9T/Nl9NP4jrl/PnwIpwYZTI+K2ooxYtgvDwJUJYOyF0BEPcZRH0A2LIeHDwuOD0= 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 Mon, 20 Feb 2023 12:38:45 -0600 Michael Roth wrote: In the host-wide certificates installing/uninstalling, a lock is to prevent the racing between cert upload/download path and the handling of guest request path. Guess we need a similar lock to prevent the racing between snp_{set,get}_instance_certs() and snp_handle_ext_guest_request(). This patch and PATCH 27 are focusing on cert from different sources. It would be better to abstract. With the functions and data structure of cert, the cert installing/uninstalling, checks, expectation of the output buffer can be unified. Then we don't need mostly duplicate routines in two different paths. > From: Dionna Glaze > > The /dev/sev device has the ability to store host-wide certificates for > the key used by the AMD-SP for SEV-SNP attestation report signing, > but for hosts that want to specify additional certificates that are > specific to the image launched in a VM, a different way is needed to > communicate those certificates. > > Add two new KVM ioctl to handle this: KVM_SEV_SNP_{GET,SET}_CERTS > > The certificates that are set with this command are expected to follow > the same format as the host certificates, but that format is opaque > to the kernel. > > The new behavior for custom certificates is that the extended guest > request command will now return the overridden certificates if they > were installed for the instance. The error condition for a too small > data buffer is changed to return the overridden certificate data size > if there is an overridden certificate set installed. > > Setting a 0 length certificate returns the system state to only return > the host certificates on an extended guest request. > > Also increase the SEV_FW_BLOB_MAX_SIZE another 4K page to allow space > for an extra certificate. > > Cc: Tom Lendacky > Cc: Paolo Bonzini > > Signed-off-by: Dionna Glaze > Signed-off-by: Ashish Kalra > [mdr: remove used of "we" and "this patch" in commit log] > Signed-off-by: Michael Roth > --- > arch/x86/kvm/svm/sev.c | 111 ++++++++++++++++++++++++++++++++++++++- > arch/x86/kvm/svm/svm.h | 1 + > include/linux/psp-sev.h | 2 +- > include/uapi/linux/kvm.h | 12 +++++ > 4 files changed, 123 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 70d5650d8d95..18b64b7005e7 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -2089,6 +2089,7 @@ static void *snp_context_create(struct kvm *kvm, struct kvm_sev_cmd *argp) > goto e_free; > > sev->snp_certs_data = certs_data; > + sev->snp_certs_len = 0; > > return context; > Better to move the fix to PATCH 45. > @@ -2404,6 +2405,86 @@ static int snp_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp) > return ret; > } > > +static int snp_get_instance_certs(struct kvm *kvm, struct kvm_sev_cmd *argp) > +{ > + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; > + struct kvm_sev_snp_get_certs params; > + > + if (!sev_snp_guest(kvm)) > + return -ENOTTY; > + > + if (!sev->snp_context) > + return -EINVAL; > + > + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, > + sizeof(params))) > + return -EFAULT; > + > + /* No instance certs set. */ > + if (!sev->snp_certs_len) > + return -ENOENT; > + > + if (params.certs_len < sev->snp_certs_len) { > + /* Output buffer too small. Return the required size. */ > + params.certs_len = sev->snp_certs_len; > + > + if (copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms, > + sizeof(params))) > + return -EFAULT; > + > + return -EINVAL; > + } > + > + if (copy_to_user((void __user *)(uintptr_t)params.certs_uaddr, > + sev->snp_certs_data, sev->snp_certs_len)) > + return -EFAULT; > + > + return 0; > +} > + > +static int snp_set_instance_certs(struct kvm *kvm, struct kvm_sev_cmd *argp) > +{ > + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; > + unsigned long length = SEV_FW_BLOB_MAX_SIZE; > + void *to_certs = sev->snp_certs_data; > + struct kvm_sev_snp_set_certs params; > + > + if (!sev_snp_guest(kvm)) > + return -ENOTTY; > + > + if (!sev->snp_context) > + return -EINVAL; > + > + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, > + sizeof(params))) > + return -EFAULT; > + > + if (params.certs_len > SEV_FW_BLOB_MAX_SIZE) > + return -EINVAL; > + > + /* > + * Setting a length of 0 is the same as "uninstalling" instance- > + * specific certificates. > + */ > + if (params.certs_len == 0) { > + sev->snp_certs_len = 0; > + return 0; > + } > + > + /* Page-align the length */ > + length = (params.certs_len + PAGE_SIZE - 1) & PAGE_MASK; > + > + if (copy_from_user(to_certs, > + (void __user *)(uintptr_t)params.certs_uaddr, > + params.certs_len)) { > + return -EFAULT; > + } > + > + sev->snp_certs_len = length; > + > + return 0; > +} > + > int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp) > { > struct kvm_sev_cmd sev_cmd; > @@ -2503,6 +2584,12 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp) > case KVM_SEV_SNP_LAUNCH_FINISH: > r = snp_launch_finish(kvm, &sev_cmd); > break; > + case KVM_SEV_SNP_GET_CERTS: > + r = snp_get_instance_certs(kvm, &sev_cmd); > + break; > + case KVM_SEV_SNP_SET_CERTS: > + r = snp_set_instance_certs(kvm, &sev_cmd); > + break; > default: > r = -EINVAL; > goto out; > @@ -3550,8 +3637,28 @@ static void snp_handle_ext_guest_request(struct vcpu_svm *svm, gpa_t req_gpa, gp > if (rc) > goto unlock; > > - rc = snp_guest_ext_guest_request(&req, (unsigned long)sev->snp_certs_data, > - &data_npages, &err); > + /* > + * If the VMM has overridden the certs, then change the error message > + * if the size is inappropriate for the override. Otherwise, use a > + * regular guest request and copy back the instance certs. > + */ > + if (sev->snp_certs_len) { > + if ((data_npages << PAGE_SHIFT) < sev->snp_certs_len) { > + rc = -EINVAL; > + err = SNP_GUEST_REQ_INVALID_LEN; > + goto datalen; > + } > + rc = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &req, > + (int *)&err); > + } else { > + rc = snp_guest_ext_guest_request(&req, > + (unsigned long)sev->snp_certs_data, > + &data_npages, &err); > + } > +datalen: > + if (sev->snp_certs_len) > + data_npages = sev->snp_certs_len >> PAGE_SHIFT; > + > if (rc) { > /* > * If buffer length is small then return the expected > diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h > index 221b38d3c845..dced46559508 100644 > --- a/arch/x86/kvm/svm/svm.h > +++ b/arch/x86/kvm/svm/svm.h > @@ -94,6 +94,7 @@ struct kvm_sev_info { > u64 snp_init_flags; > void *snp_context; /* SNP guest context page */ > void *snp_certs_data; > + unsigned int snp_certs_len; /* Size of instance override for certs */ > struct mutex guest_req_lock; /* Lock for guest request handling */ > > u64 sev_features; /* Features set at VMSA creation */ > diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h > index 92116e2b74fd..3b28b78938f6 100644 > --- a/include/linux/psp-sev.h > +++ b/include/linux/psp-sev.h > @@ -22,7 +22,7 @@ > #define __psp_pa(x) __pa(x) > #endif > > -#define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ > +#define SEV_FW_BLOB_MAX_SIZE 0x5000 /* 20KB */ > > /** > * SEV platform state > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 6e684bf5f723..ad7e24e43547 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -1928,6 +1928,8 @@ enum sev_cmd_id { > KVM_SEV_SNP_LAUNCH_START, > KVM_SEV_SNP_LAUNCH_UPDATE, > KVM_SEV_SNP_LAUNCH_FINISH, > + KVM_SEV_SNP_GET_CERTS, > + KVM_SEV_SNP_SET_CERTS, > > KVM_SEV_NR_MAX, > }; > @@ -2075,6 +2077,16 @@ struct kvm_sev_snp_launch_finish { > __u8 pad[6]; > }; > > +struct kvm_sev_snp_get_certs { > + __u64 certs_uaddr; > + __u64 certs_len; > +}; > + > +struct kvm_sev_snp_set_certs { > + __u64 certs_uaddr; > + __u64 certs_len; > +}; > + > #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) > #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) > #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)