From nobody Mon Apr 20 01:11:07 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07CB3C43334 for ; Thu, 23 Jun 2022 18:34:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234589AbiFWSeZ (ORCPT ); Thu, 23 Jun 2022 14:34:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237492AbiFWScy (ORCPT ); Thu, 23 Jun 2022 14:32:54 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 00F27D1917 for ; Thu, 23 Jun 2022 10:34:18 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id a10-20020a170902ecca00b0016a50049af0so2292684plh.10 for ; Thu, 23 Jun 2022 10:34:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:message-id:mime-version:subject:from:to:cc; bh=YzBiLCY4klTYtqAR87IAA6VD+HxSLPVS13bS8WvciXc=; b=sKnXVkJcT/HWTdp8+iZMbVnsW11LhtEvgOwL4zayP6rwcEwEVSw5XjC4Pc6bVQggsu CWbJgUKzOLz7sYZMfFaw3MKvLlkoX6OZ6GS4bewHNc0TZBqwpNGuy5a0WMEi7EetJlhd NycAp0WSqSK9tX9WTMon+6/phpGY2LodBWt7jf1LKijODwfjN0eSpMiqjgRmKBJf6N0r oeUG90uhZQWqp5yG8KrsoDcjaAKENVm2KRA4r6jgeW8v5HoRLPD6BX1tFihCkxBDRJGr 0C3E8b7LDbjhzIXXlMIGtnv53sq3giEH62PsnQ676AVr4EBflodtXY9U+FPCRLlB34AG /ZDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=YzBiLCY4klTYtqAR87IAA6VD+HxSLPVS13bS8WvciXc=; b=QdCuSmEhV/A0M255gM/TRPEKvyVV05Hd42KOzZAuLP/pNEc1Rcy26Z0iYRxSGH/IZo ETBsU9mU1t2OUAVRx33tSXM8bLh18TJ65E4ePHkmDL49m655C90eHgOgeWr+tz830f86 qYH5dkuAFccjxP0iN4DCLblkQntG3tb+r5lvChJvhjVzazPV4McJhZdaTkVxGrGaDOBG rd4PJQenphHgEjZBwfuCPVTaNAZacvympxjKu6QXw34jr0tQ9JO0eshn/uZmV8gds78E uJE6714UmxLq6LfSXKcBicYjD4Dp8K9e7GhtHleEnSB16m5xa1KU71XeomFDYOn2qC98 AESA== X-Gm-Message-State: AJIora/aIHQqWTXPDB5uKsV+J/bnT9UmTWEy6FFFysusqQ+e8Ot6Avnt BCpFlzP/aGQ+OprEHRSWaIv1mej6WpI= X-Google-Smtp-Source: AGRyM1s7DibOnE7Mbl6KtMM0c/TJRvFVMdwV6LfruY9B46xoaSSmTP191nkYGoiaR70UiIkHPnHJKO9AUic= X-Received: from pgonda1.kir.corp.google.com ([2620:15c:29:203:9b6a:a8a1:3593:35c2]) (user=pgonda job=sendgmr) by 2002:a05:6a00:1683:b0:4f7:e497:6a55 with SMTP id k3-20020a056a00168300b004f7e4976a55mr41576663pfc.21.1656005652667; Thu, 23 Jun 2022 10:34:12 -0700 (PDT) Date: Thu, 23 Jun 2022 10:34:06 -0700 Message-Id: <20220623173406.744645-1-pgonda@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.37.0.rc0.104.g0611611a94-goog Subject: [PATCH V2] KVM: SEV: Init target VMCBs in sev_migrate_from From: Peter Gonda To: kvm@vger.kernel.org Cc: Peter Gonda , Sean Christopherson , Marc Orr , Paolo Bonzini , Tom Lendacky , linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The target VMCBs during an intra-host migration need to correctly setup for running SEV and SEV-ES guests. Add sev_init_vmcb() function and make sev_es_init_vmcb() static. sev_init_vmcb() uses the now private function to init SEV-ES guests VMCBs when needed. Fixes: 0b020f5af092 ("KVM: SEV: Add support for SEV-ES intra host migration= ") Fixes: b56639318bb2 ("KVM: SEV: Add support for SEV intra host migration") Signed-off-by: Peter Gonda Suggested-by: Sean Christopherson Cc: Marc Orr Cc: Paolo Bonzini Cc: Sean Christopherson Cc: Tom Lendacky Cc: kvm@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- V2 * Refactor of sev_es_init_vmcb() and sev_migrate_from suggested by Sean. --- arch/x86/kvm/svm/sev.c | 68 ++++++++++++++++++++++++++++-------------- arch/x86/kvm/svm/svm.c | 11 ++----- arch/x86/kvm/svm/svm.h | 2 +- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 309bcdb2f929..d45868031954 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -1662,19 +1662,24 @@ static void sev_migrate_from(struct kvm *dst_kvm, s= truct kvm *src_kvm) { struct kvm_sev_info *dst =3D &to_kvm_svm(dst_kvm)->sev_info; struct kvm_sev_info *src =3D &to_kvm_svm(src_kvm)->sev_info; + struct kvm_vcpu *dst_vcpu, *src_vcpu; + struct vcpu_svm *dst_svm, *src_svm; struct kvm_sev_info *mirror; + unsigned long i; =20 dst->active =3D true; dst->asid =3D src->asid; dst->handle =3D src->handle; dst->pages_locked =3D src->pages_locked; dst->enc_context_owner =3D src->enc_context_owner; + dst->es_active =3D src->es_active; =20 src->asid =3D 0; src->active =3D false; src->handle =3D 0; src->pages_locked =3D 0; src->enc_context_owner =3D NULL; + src->es_active =3D false; =20 list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_lis= t); =20 @@ -1701,26 +1706,21 @@ static void sev_migrate_from(struct kvm *dst_kvm, s= truct kvm *src_kvm) list_del(&src->mirror_entry); list_add_tail(&dst->mirror_entry, &owner_sev_info->mirror_vms); } -} =20 -static int sev_es_migrate_from(struct kvm *dst, struct kvm *src) -{ - unsigned long i; - struct kvm_vcpu *dst_vcpu, *src_vcpu; - struct vcpu_svm *dst_svm, *src_svm; + kvm_for_each_vcpu(i, dst_vcpu, dst_kvm) { + dst_svm =3D to_svm(dst_vcpu); =20 - if (atomic_read(&src->online_vcpus) !=3D atomic_read(&dst->online_vcpus)) - return -EINVAL; + sev_init_vmcb(dst_svm); =20 - kvm_for_each_vcpu(i, src_vcpu, src) { - if (!src_vcpu->arch.guest_state_protected) - return -EINVAL; - } + if (!dst->es_active) + continue; =20 - kvm_for_each_vcpu(i, src_vcpu, src) { + /* + * Note, the source is not required to have the same number of + * vCPUs as the destination when migrating a vanilla SEV VM. + */ + src_vcpu =3D kvm_get_vcpu(dst_kvm, i); src_svm =3D to_svm(src_vcpu); - dst_vcpu =3D kvm_get_vcpu(dst, i); - dst_svm =3D to_svm(dst_vcpu); =20 /* * Transfer VMSA and GHCB state to the destination. Nullify and @@ -1737,8 +1737,23 @@ static int sev_es_migrate_from(struct kvm *dst, stru= ct kvm *src) src_svm->vmcb->control.vmsa_pa =3D INVALID_PAGE; src_vcpu->arch.guest_state_protected =3D false; } - to_kvm_svm(src)->sev_info.es_active =3D false; - to_kvm_svm(dst)->sev_info.es_active =3D true; +} + +static int sev_check_source_vcpus(struct kvm *dst, struct kvm *src) +{ + struct kvm_vcpu *src_vcpu; + unsigned long i; + + if (!sev_es_guest(src)) + return 0; + + if (atomic_read(&src->online_vcpus) !=3D atomic_read(&dst->online_vcpus)) + return -EINVAL; + + kvm_for_each_vcpu(i, src_vcpu, src) { + if (!src_vcpu->arch.guest_state_protected) + return -EINVAL; + } =20 return 0; } @@ -1786,11 +1801,9 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, un= signed int source_fd) if (ret) goto out_dst_vcpu; =20 - if (sev_es_guest(source_kvm)) { - ret =3D sev_es_migrate_from(kvm, source_kvm); - if (ret) - goto out_source_vcpu; - } + ret =3D sev_check_source_vcpus(kvm, source_kvm); + if (ret) + goto out_source_vcpu; =20 sev_migrate_from(kvm, source_kvm); kvm_vm_dead(source_kvm); @@ -2911,7 +2924,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, = unsigned int port, int in) count, in); } =20 -void sev_es_init_vmcb(struct vcpu_svm *svm) +static void sev_es_init_vmcb(struct vcpu_svm *svm) { struct kvm_vcpu *vcpu =3D &svm->vcpu; =20 @@ -2964,6 +2977,15 @@ void sev_es_init_vmcb(struct vcpu_svm *svm) } } =20 +void sev_init_vmcb(struct vcpu_svm *svm) +{ + svm->vmcb->control.nested_ctl |=3D SVM_NESTED_CTL_SEV_ENABLE; + clr_exception_intercept(svm, UD_VECTOR); + + if (sev_es_guest(svm->vcpu.kvm)) + sev_es_init_vmcb(svm); +} + void sev_es_vcpu_reset(struct vcpu_svm *svm) { /* diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 136298cfb3fb..3c0e581676c3 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1259,15 +1259,8 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm->vmcb->control.int_ctl |=3D V_GIF_ENABLE_MASK; } =20 - if (sev_guest(vcpu->kvm)) { - svm->vmcb->control.nested_ctl |=3D SVM_NESTED_CTL_SEV_ENABLE; - clr_exception_intercept(svm, UD_VECTOR); - - if (sev_es_guest(vcpu->kvm)) { - /* Perform SEV-ES specific VMCB updates */ - sev_es_init_vmcb(svm); - } - } + if (sev_guest(vcpu->kvm)) + sev_init_vmcb(svm); =20 svm_hv_init_vmcb(vmcb); init_vmcb_after_set_cpuid(vcpu); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index d51de3c9264a..0897ce8a4863 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -649,10 +649,10 @@ void __init sev_set_cpu_caps(void); void __init sev_hardware_setup(void); void sev_hardware_unsetup(void); int sev_cpu_init(struct svm_cpu_data *sd); +void sev_init_vmcb(struct vcpu_svm *svm); void sev_free_vcpu(struct kvm_vcpu *vcpu); int sev_handle_vmgexit(struct kvm_vcpu *vcpu); int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, in= t in); -void sev_es_init_vmcb(struct vcpu_svm *svm); void sev_es_vcpu_reset(struct vcpu_svm *svm); void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); void sev_es_prepare_switch_to_guest(struct sev_es_save_area *hostsa); --=20 2.37.0.rc0.104.g0611611a94-goog