Received: by 2002:a05:6a10:9afc:0:0:0:0 with SMTP id t28csp2261095pxm; Fri, 4 Mar 2022 12:33:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJyaZSvO+XTpkFG/uSejXpVFEly+B4YOcf86XgvFCw/aqQKI3MDpG9uO7FCQAvVm3zSGPoS+ X-Received: by 2002:a17:90a:fd98:b0:1be:eef1:ef40 with SMTP id cx24-20020a17090afd9800b001beeef1ef40mr395181pjb.143.1646426034234; Fri, 04 Mar 2022 12:33:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646426034; cv=none; d=google.com; s=arc-20160816; b=C9wazMKOw9HjEgdetHCi5RO4G6oeCkFtRbqQdv1okPfsFDd8tuKVI6iejhV3g8nFNf u9L6TfmoBz7fdYquppSXCkkSG0vnPVpVShQtSX+u9NzEHZetpvtLxo3br3lrjJQdgp4f ts9TClWaL71YUpJUmZphUu6EKrqJy//mSsuqshcT7Da+9VVC2C59FgA/h4T8xN8W1eGd L2h4o0kDiqhLPngbsthOAqkzOhtKfS0rjizmm3HVlAZFGEYw5CViotSQ3toR+A2RmYwG 562BIOgdGWZbwpmnVujNEjMBkV+zpWYeN53uv7paITDAOMymr+POFbepL8C4XQHMAn+n MutA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=efllBfn2kx3rlIyA0hgqjwtR8JqMPAB5GJtkDM28KV8=; b=qKnaue5+bm14ek5CHuic1oTv5IC2aG+FdNQl1oZD+NOsFWYzZ72FvF1MEoJ7UeOgVv NgY1WfkIqT7GrvaY4WaiRPmrC94URHxcUxMmHzgOQhKYaUCbIbvO7ydNe2TKHa37aU3B ZsxXwnIwsULTFWX2mELU+WOdG7y25RFd3VUyHCn4zei9SkRBu6tqyjWfaUs+j2jdU6VR tVSkqlOCdMsAgrpEVUCe60mqHsv+0xEAXtliJYmN6s4HN0ay2kHld7yj9GtjwTxtw5YV l+6w2Zsb7w51nSQCK3c/UbJ8b839/AabVd/y6Dq3ouMYOMZ3R0raSSfGHgAGe0qLDjd6 nCzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=j8p2cr7e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f29-20020a63101d000000b003658523c918si5736909pgl.781.2022.03.04.12.33.39; Fri, 04 Mar 2022 12:33:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=j8p2cr7e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229908AbiCDUdu (ORCPT + 99 others); Fri, 4 Mar 2022 15:33:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230011AbiCDUcV (ORCPT ); Fri, 4 Mar 2022 15:32:21 -0500 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B0741E7453; Fri, 4 Mar 2022 12:31:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1646425892; x=1677961892; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=drnBLG1sSQgTJROEhefPJucJ7IehUS/WFdesWGynUpY=; b=j8p2cr7elIuU2o+HGUaUqkcp1kOe9yJ1KAKti3FBF/VMeW8+0+N7BsaW od7RjfULPXF3v1d4iCxeLmdbD75jlapLFJMrY33GS0BJeqTZAzMc6sKNf YVOph+yf4Cz19kdmorsz89+Tfd1DL7v622/joFkp9yiSKzODqzaedI442 oBDc9NMBhlbNGqK0MGS2oTfHYtZg91hYyhDVWamkfKD2DOOynzvnjH/9H GDK3jY5BkzAqcuhMBDax2RkxV23uk9W71CaT84Wn4zYTnwoZcBf4gNkmo 6lBT+BV3DfLGzF2LzbeyFnbxK+4BNhMHCnTOuFRTaE17S0ki8BZXXp8KH A==; X-IronPort-AV: E=McAfee;i="6200,9189,10276"; a="251624273" X-IronPort-AV: E=Sophos;i="5.90,156,1643702400"; d="scan'208";a="251624273" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2022 11:50:35 -0800 X-IronPort-AV: E=Sophos;i="5.90,156,1643702400"; d="scan'208";a="552344479" Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2022 11:50:35 -0800 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , Jim Mattson , erdemaktas@google.com, Connor Kuehl , Sean Christopherson Subject: [RFC PATCH v5 072/104] KVM: TDX: handle vcpu migration over logical processor Date: Fri, 4 Mar 2022 11:49:28 -0800 Message-Id: <3dd2729b27d1db696c61c7f7acf5a2c8ecaa1502.1646422845.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Isaku Yamahata For vcpu migration, in the case of VMX, VCMS is flushed on the source pcpu, and load it on the target pcpu. There are corresponding TDX SEAMCALL APIs, call them on vcpu migration. The logic is mostly same as VMX except the TDX SEAMCALLs are used. Signed-off-by: Isaku Yamahata --- arch/x86/kvm/vmx/main.c | 20 +++++++++++++-- arch/x86/kvm/vmx/tdx.c | 51 ++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/x86_ops.h | 2 ++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index f9d43f2de145..2cd5ba0e8788 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -121,6 +121,14 @@ static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu) return vmx_vcpu_run(vcpu); } +static void vt_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + if (is_td_vcpu(vcpu)) + return tdx_vcpu_load(vcpu, cpu); + + return vmx_vcpu_load(vcpu, cpu); +} + static void vt_flush_tlb_all(struct kvm_vcpu *vcpu) { if (is_td_vcpu(vcpu)) @@ -162,6 +170,14 @@ static void vt_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, vmx_load_mmu_pgd(vcpu, root_hpa, pgd_level); } +static void vt_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ + if (is_td_vcpu(vcpu)) + return; + + vmx_sched_in(vcpu, cpu); +} + static int vt_mem_enc_op(struct kvm *kvm, void __user *argp) { if (!is_td(kvm)) @@ -199,7 +215,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = { .vcpu_reset = vt_vcpu_reset, .prepare_guest_switch = vt_prepare_switch_to_guest, - .vcpu_load = vmx_vcpu_load, + .vcpu_load = vt_vcpu_load, .vcpu_put = vt_vcpu_put, .update_exception_bitmap = vmx_update_exception_bitmap, @@ -285,7 +301,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = { .request_immediate_exit = vmx_request_immediate_exit, - .sched_in = vmx_sched_in, + .sched_in = vt_sched_in, .cpu_dirty_log_size = PML_ENTITY_NUM, .update_cpu_dirty_logging = vmx_update_cpu_dirty_logging, diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 37cf7d43435d..a6b1a8ce888d 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -85,6 +85,18 @@ static inline bool is_td_finalized(struct kvm_tdx *kvm_tdx) return kvm_tdx->finalized; } +static inline void tdx_disassociate_vp(struct kvm_vcpu *vcpu) +{ + /* + * Ensure tdx->cpu_list is updated is before setting vcpu->cpu to -1, + * otherwise, a different CPU can see vcpu->cpu = -1 and add the vCPU + * to its list before its deleted from this CPUs list. + */ + smp_wmb(); + + vcpu->cpu = -1; +} + static void tdx_clear_page(unsigned long page) { const void *zero_page = (const void *) __va(page_to_phys(ZERO_PAGE(0))); @@ -155,6 +167,39 @@ static void tdx_reclaim_td_page(struct tdx_td_page *page) free_page(page->va); } +static void tdx_flush_vp(void *arg) +{ + struct kvm_vcpu *vcpu = arg; + u64 err; + + /* Task migration can race with CPU offlining. */ + if (vcpu->cpu != raw_smp_processor_id()) + return; + + /* + * No need to do TDH_VP_FLUSH if the vCPU hasn't been initialized. The + * list tracking still needs to be updated so that it's correct if/when + * the vCPU does get initialized. + */ + if (is_td_vcpu_created(to_tdx(vcpu))) { + err = tdh_vp_flush(to_tdx(vcpu)->tdvpr.pa); + if (unlikely(err && err != TDX_VCPU_NOT_ASSOCIATED)) { + if (WARN_ON_ONCE(err)) + pr_tdx_error(TDH_VP_FLUSH, err, NULL); + } + } + + tdx_disassociate_vp(vcpu); +} + +static void tdx_flush_vp_on_cpu(struct kvm_vcpu *vcpu) +{ + if (unlikely(vcpu->cpu == -1)) + return; + + smp_call_function_single(vcpu->cpu, tdx_flush_vp, vcpu, 1); +} + static int tdx_do_tdh_phymem_cache_wb(void *param) { u64 err = 0; @@ -425,6 +470,12 @@ int tdx_vcpu_create(struct kvm_vcpu *vcpu) return ret; } +void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + if (vcpu->cpu != cpu) + tdx_flush_vp_on_cpu(vcpu); +} + void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) { struct vcpu_tdx *tdx = to_tdx(vcpu); diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index 8b871c5f52cf..ceafd6e18f4e 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -143,6 +143,7 @@ void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu); void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu); void tdx_vcpu_put(struct kvm_vcpu *vcpu); +void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu); int tdx_vm_ioctl(struct kvm *kvm, void __user *argp); int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp); @@ -166,6 +167,7 @@ static inline void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) {} static inline fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu) { return EXIT_FASTPATH_NONE; } static inline void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) {} static inline void tdx_vcpu_put(struct kvm_vcpu *vcpu) {} +static inline void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) {} static inline int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOPNOTSUPP; } static inline int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; } -- 2.25.1