Received: by 2002:a05:7412:3b8b:b0:fc:a2b0:25d7 with SMTP id nd11csp1132205rdb; Fri, 9 Feb 2024 11:10:49 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXLw+wZICCoSrXODLUvu81gkoLg8MoyyWkbMInKdrYonMbrWZBdZQryA5CImYhlCS8MpVXF6Kl54zsB/YE1Omg1uM1QF75ly6AjMBBQlA== X-Google-Smtp-Source: AGHT+IEX/gRLbyAhTiRA56TbbZ1lA5XmYHtRbZwZkcDBzEt8EwyPWHUwc5LXmxmErYHTD2SRnLLs X-Received: by 2002:a17:90b:364b:b0:296:2f49:6c04 with SMTP id nh11-20020a17090b364b00b002962f496c04mr2171168pjb.19.1707505849256; Fri, 09 Feb 2024 11:10:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707505849; cv=pass; d=google.com; s=arc-20160816; b=L9tTNItMdAEFBJpwYDLojfO4gEbiKV4LGtKgOaTL9fyYg+cZIIdlo4t4HsdpuBatLb FRSf8M4c/2DfbGoAHEpqoS42MU0XXs/tgGKWtspQd7tRSsH0qdWCdqsMfuraMfZQrSxP w6NQ+jwB5w4q8SYw6FpHhdG59DKrhw6noqySBi+tTQniTsEwnLYvx7ytW5EF8X9Ax9hA PBYJbwM4D3+5ovGpjvk8BRHQXpxC9nlUAzSEZ833PQG2XyWLGYdSTpislstfcOLNPzjH QRr9tqOYIFk6+n9fDLi4e7KY7tdRKCYEHBkOIBQgvoHNE6lvT1OP8Zp8vE5UI+f2k2E2 +zvQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=KMuM2iDsKyRXLwOQwCqQqqcOLqtJ/Pinx6UZ/VSyKIk=; fh=1eVUvhDemRXBrO8cD3UgCbP/f8Vvse9RerlamifpZKQ=; b=p4NcRwx9HQVeZpeWC5Qbs89bEAMx/4idrlUrfbcu2wmNI59blF+Ud/9Iw4wkho3+yI iubDcz4027dFUm0Rxha6omQXOplj9OtK/9A1V1HyZiEJKNSSPNxQSwCoQzsZkx5PN0Vk o8RgYdCz8QwZwj3SItedbO5/yI2HGM4DPHDgDH7FzydBLzXkWfLhXlzGd4MIcZXYm51R wBkGZC+6HW9UatoGPdHXNXGe38cyzlp1X4k5oHY6BMWyu+vqOQCTThcoCybCzCPq72d1 +FzStLEl9p/LIDXDr+VGMrinAkE8sKz2v21GhEdUExMlEug8HQxmVas6QpHwAouLqsA6 2KOA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="ZGeOLb/K"; arc=pass (i=1 spf=pass spfdomain=redhat.com dkim=pass dkdomain=redhat.com dmarc=pass fromdomain=redhat.com); spf=pass (google.com: domain of linux-kernel+bounces-59814-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-59814-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com X-Forwarded-Encrypted: i=2; AJvYcCX1DZQI5lX5PcGsS4sTqkjwF6Qb2tONZOjSfHeI9lRI2ZkMyc3HiywmzEoSPulpfPsv9WCyLOOsb/IX2Lt/zgCwYKctWGcs6xiRx0EWZw== Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id ee15-20020a17090afc4f00b00296c2bf8a6fsi2129628pjb.147.2024.02.09.11.10.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Feb 2024 11:10:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-59814-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="ZGeOLb/K"; arc=pass (i=1 spf=pass spfdomain=redhat.com dkim=pass dkdomain=redhat.com dmarc=pass fromdomain=redhat.com); spf=pass (google.com: domain of linux-kernel+bounces-59814-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-59814-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.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 sy.mirrors.kernel.org (Postfix) with ESMTPS id 34F83B2CE41 for ; Fri, 9 Feb 2024 18:40:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5C64B129A62; Fri, 9 Feb 2024 18:37:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZGeOLb/K" Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF15E80C16 for ; Fri, 9 Feb 2024 18:37:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707503873; cv=none; b=In5ELqw7fVqazgpigZ0aJebM2oFBAI416How0sLm56hfM/Bzp5t5PJWIbZOQYtL5RXWGtSkj0/U0NdlZNB4XcsQepXeP6VCmgHMDf4LgJOTWAFM3Dysh/Vkmmdq73LI37UQzb3OWzjZY2sizgaj1GguxBa/pwyaGu0VjMilaIS0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707503873; c=relaxed/simple; bh=Gv/Kr8TOzPt0rp3aa81lJO/6g/pp+CHZVu5w3lMoNB8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=lOKLVCkZNb/Mkpz4PNaIcM98cdnFU7HVBwNERsrN/9ZI/bEpddwvfm+ndZZoq6duMFKSFa0glA8GfGt1rYVS0IqFZWiG3Jq/0JDx8bg+UvGrjWmIG8V3mAb1a3tmhFfs9DF1UDrCVhE2Tu/+2RuQFWmRF31fmh5D0Ka6T7BfBeM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZGeOLb/K; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1707503869; h=from:from: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; bh=KMuM2iDsKyRXLwOQwCqQqqcOLqtJ/Pinx6UZ/VSyKIk=; b=ZGeOLb/Kp+BtG0RLNLDxCXXSGaOqNtmxOtuv1I9r2uVZe6PnP1Wzgii3AMNB37J5AKo0Ve 2M1meFxLSeBwqKve7ZBypRvJ3VslpeY7KQq+tnEEHvC4+sPV1yZP84G1oiQuQw1w9bV2sD 9IkLrU+P0q0uNsUsameEY4B+1k8POes= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-223-Z88hIqB6NMWbVDBrYewrdA-1; Fri, 09 Feb 2024 13:37:46 -0500 X-MC-Unique: Z88hIqB6NMWbVDBrYewrdA-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DD37810665A0; Fri, 9 Feb 2024 18:37:45 +0000 (UTC) Received: from virtlab511.virt.lab.eng.bos.redhat.com (virtlab511.virt.lab.eng.bos.redhat.com [10.19.152.198]) by smtp.corp.redhat.com (Postfix) with ESMTP id AF969492BC6; Fri, 9 Feb 2024 18:37:45 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: seanjc@google.com, michael.roth@amd.com, aik@amd.com, isaku.yamahata@intel.com Subject: [PATCH 09/10] KVM: SEV: introduce KVM_SEV_INIT2 operation Date: Fri, 9 Feb 2024 13:37:41 -0500 Message-Id: <20240209183743.22030-10-pbonzini@redhat.com> In-Reply-To: <20240209183743.22030-1-pbonzini@redhat.com> References: <20240209183743.22030-1-pbonzini@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 The idea that no parameter would ever be necessary when enabling SEV or SEV-ES for a VM was decidedly optimistic. In fact, in some sense it's already a parameter whether SEV or SEV-ES is desired. Another possible source of variability is the desired set of VMSA features, as that affects the measurement of the VM's initial state and cannot be changed arbitrarily by the hypervisor. Create a new sub-operation for KVM_MEM_ENCRYPT_OP that can take a struct, and put the new op to work by including the VMSA features as a field of the struct. The existing KVM_SEV_INIT and KVM_SEV_ES_INIT use the full set of supported VMSA features for backwards compatibility. The struct also includes the usual bells and whistles for future extensibility: a flags field that must be zero for now, and some padding at the end. Signed-off-by: Paolo Bonzini --- .../virt/kvm/x86/amd-memory-encryption.rst | 41 ++++++++++++++-- arch/x86/include/uapi/asm/kvm.h | 10 ++++ arch/x86/kvm/svm/sev.c | 48 +++++++++++++++++-- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Documentation/virt/kvm/x86/amd-memory-encryption.rst index 5ed11bc16b96..a4291e7bd8ed 100644 --- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst +++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst @@ -75,15 +75,50 @@ are defined in ````. KVM implements the following commands to support common lifecycle events of SEV guests, such as launching, running, snapshotting, migrating and decommissioning. -1. KVM_SEV_INIT ---------------- +1. KVM_SEV_INIT2 +---------------- -The KVM_SEV_INIT command is used by the hypervisor to initialize the SEV platform +The KVM_SEV_INIT2 command is used by the hypervisor to initialize the SEV platform context. In a typical workflow, this command should be the first command issued. +For this command to be accepted, either KVM_X86_SEV_VM or KVM_X86_SEV_ES_VM +must have been passed to the KVM_CREATE_VM ioctl. A virtual machine created +with those machine types in turn cannot be run until KVM_SEV_INIT2 is invoked. + +Parameters: struct kvm_sev_init (in) Returns: 0 on success, -negative on error +:: + + struct struct kvm_sev_init { + __u32 flags; /* must be 0 */ + __u64 vmsa_features; /* initial value of features field in VMSA */ + __u32 pad[8]; + }; + +It is an error if the hypervisor does not support any of the bits that +are set in ``flags`` or ``vmsa_features``. + +This command replaces the deprecated KVM_SEV_INIT and KVM_SEV_ES_INIT commands. +The commands did not have any parameters (the ```data``` field was unused) and +only work for the KVM_X86_DEFAULT_VM machine type (0). + +They behave as if: + +* the VM type is KVM_X86_SEV_VM for KVM_SEV_INIT, or KVM_X86_SEV_ES_VM for + KVM_SEV_ES_INIT + +* the ``flags`` field of ``struct kvm_sev_init`` is set to zero + +* the ``vmsa_features`` field of ``struct kvm_sev_init`` is set to all features + supported by the hypervisor (as returned by ``KVM_GET_DEVICE_ATTR`` when + passed group 0 and attribute id ``KVM_X86_SEV_VMSA_FEATURES``). + +If the ``KVM_X86_SEV_VMSA_FEATURES`` attribute does not exist, the hypervisor only +supports KVM_SEV_INIT and KVM_SEV_ES_INIT. In that case the set of VMSA features is +undefined. + 2. KVM_SEV_LAUNCH_START ----------------------- diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 7c46e96cfe62..6baf18335c7b 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -683,6 +683,9 @@ enum sev_cmd_id { /* Guest Migration Extension */ KVM_SEV_SEND_CANCEL, + /* Second time is the charm; improved versions of the above ioctls. */ + KVM_SEV_INIT2, + KVM_SEV_NR_MAX, }; @@ -694,6 +697,13 @@ struct kvm_sev_cmd { __u32 sev_fd; }; +struct kvm_sev_init { + __u32 vm_type; + __u32 flags; + __u64 vmsa_features; + __u32 pad[8]; +}; + struct kvm_sev_launch_start { __u32 handle; __u32 policy; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index acf5c45ef14e..78c52764453f 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -252,7 +252,9 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) sev_decommission(handle); } -static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) +static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp, + struct kvm_sev_init *data, + unsigned long vm_type) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; int asid, ret; @@ -260,7 +262,10 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) if (kvm->created_vcpus) return -EINVAL; - if (kvm->arch.vm_type != KVM_X86_DEFAULT_VM) + if (data->flags) + return -EINVAL; + + if (data->vmsa_features & ~sev_supported_vmsa_features) return -EINVAL; ret = -EBUSY; @@ -268,8 +273,8 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; sev->active = true; - sev->es_active = argp->id == KVM_SEV_ES_INIT; - sev->vmsa_features = sev_supported_vmsa_features; + sev->es_active = (vm_type & __KVM_X86_PROTECTED_STATE_TYPE) != 0; + sev->vmsa_features = data->vmsa_features; asid = sev_asid_new(sev); if (asid < 0) @@ -298,6 +303,38 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; } +static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + struct kvm_sev_init data = { + .vmsa_features = sev_supported_vmsa_features, + }; + unsigned long vm_type; + + if (kvm->arch.vm_type != KVM_X86_DEFAULT_VM) + return -EINVAL; + + vm_type = (argp->id == KVM_SEV_INIT ? KVM_X86_SEV_VM : KVM_X86_SEV_ES_VM); + return __sev_guest_init(kvm, argp, &data, vm_type); +} + +static int sev_guest_init2(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; + struct kvm_sev_init data; + + if (!sev->need_init) + return -EINVAL; + + if (kvm->arch.vm_type != KVM_X86_SEV_VM && + kvm->arch.vm_type != KVM_X86_SEV_ES_VM) + return -EINVAL; + + if (copy_from_user(&data, (void __user *)(uintptr_t)argp->data, sizeof(data))) + return -EFAULT; + + return __sev_guest_init(kvm, argp, &data, kvm->arch.vm_type); +} + static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) { struct sev_data_activate activate; @@ -1915,6 +1952,9 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp) case KVM_SEV_INIT: r = sev_guest_init(kvm, &sev_cmd); break; + case KVM_SEV_INIT2: + r = sev_guest_init2(kvm, &sev_cmd); + break; case KVM_SEV_LAUNCH_START: r = sev_launch_start(kvm, &sev_cmd); break; -- 2.39.0