Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp2683629rwd; Sun, 28 May 2023 22:08:36 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7VTmdk2mZNgkxH6C9S66ljhNTojLqREuiFuB4VHZ1xIwyAu2OUVPj8ymOubHogtyo40eII X-Received: by 2002:a05:6a20:3d88:b0:10b:7b22:cbf1 with SMTP id s8-20020a056a203d8800b0010b7b22cbf1mr9211398pzi.7.1685336916107; Sun, 28 May 2023 22:08:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685336916; cv=none; d=google.com; s=arc-20160816; b=qqJNh4UmoQCihsbBSLyUBz678vSMiqb3hveaLWCmCDJdUPmnfaXTMGPb4SQhqORkAC 1epNAvf/eMeqU3MaA31Jue4KkKsNI8KmFLvxsYaX5APC9l15G6fa8EX75jwcooos5D9/ qvks0UYo549UqzpcI5o8iCzDhMn2l+JjPU5WAw6ASD8mnojufLGFIJhuSJm4NJUIkzdB 8YN2lS3MeVqah32udADcM88L2Ic0yQIt3+/5zGHcK62Khtgu80FGctIyVDy+JFSN/O70 3hrP5XQ7/irFhzoeeIYh98YeaVwxxtNUiP5qz0pdGhLgRDIyG4oaYfagqchgWaxkTSzf 6o5w== 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=gHNphz+R+pDEMtuPPI58rif0nlCU8ZDouFddTjtyhug=; b=WU2/aGbADJt4smzXWRW+orbSbA7QX/M0zd4AeM0wuDmK7ElvCTaE+reB5tD/hnSAtV 2ADln1b62pgZje5Jsfvg58v7KLWHjii7MY3S0YS11RhcHYEwOH2hEEAy2Zi7qLKXTULn rTgl6tueV6x2PW4fmbbJTny8rC0SghnnPlwCmq0bIpTJcmCEhLc1QjJ95W1fROwdFfb4 OZvf7MMokOdc2YcoPaltsDnsf9SJMEqD1MsliRyOTmwQDHhNFXM2os4fqXmUxVKiivat OS/fxzaI3VljGXOLIeWnBvU2gfqgkQNr0Q0TLNN0nsA91GUsV+US9Bb/mhuIaTR92pJp OiCw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=iVs96E8l; 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 s20-20020a63af54000000b0051b9a1e823csi8665759pgo.137.2023.05.28.22.08.23; Sun, 28 May 2023 22:08:36 -0700 (PDT) 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=iVs96E8l; 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 S231719AbjE2EWs (ORCPT + 99 others); Mon, 29 May 2023 00:22:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231552AbjE2EVX (ORCPT ); Mon, 29 May 2023 00:21:23 -0400 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9533E118; Sun, 28 May 2023 21:21:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1685334061; x=1716870061; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0eS6q+l/MQcTP9tLVF7ElmsXaN+vWcH1D4sZwF9MDHA=; b=iVs96E8lSB3ZkC1y2Loqj0RZCTjxyI8cmYi8H2YpBFi3GkCOZOxQwsiu acawq9KrL6iayo8lqd/awXTmZICdyUujO3MeMuZgOIMT4hJTFbDMieEBO bPSZUK0ZtGdWL5BdEStG9sF4dTPGY1RUhNpNlK1R9viYqkxFi6eNX5pk4 969gajnTzYAg/wi2jYEtVLeGdWcnIaehWbt5UPqJEwKHiH16zNvCzz8TN bF7fVVxnPk9IjI5ktJf69cSuoPYPudJNYBhYq3c5cv1gsEBrVnD1Tjh4P Yzi+uaUUfNrwjaC+D1+JFZ88ZyW0q537WdkAJFUWZ9SKTmQA3PguPnT33 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10724"; a="418094358" X-IronPort-AV: E=Sophos;i="6.00,200,1681196400"; d="scan'208";a="418094358" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 May 2023 21:20:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10724"; a="683419366" X-IronPort-AV: E=Sophos;i="6.00,200,1681196400"; d="scan'208";a="683419366" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 May 2023 21:20:58 -0700 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 , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com Subject: [PATCH v14 024/113] KVM: TDX: allocate/free TDX vcpu structure Date: Sun, 28 May 2023 21:19:06 -0700 Message-Id: <05b9d934997fc21c28ac52aed874e4b3848aa88f.1685333727.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=-4.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, 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 The next step of TDX guest creation is to create vcpu. Allocate TDX vcpu structures, initialize it that doesn't require TDX SEAMCALL. TDX specific vcpu initialization will be implemented as independent KVM_TDX_INIT_VCPU so that when error occurs it's easy to determine which component has the issue, KVM or TDX. Signed-off-by: Isaku Yamahata --- Changes v11 -> v12: - add more comments in tdx_vcpu_reset(). - use KVM_BUG_ON() Changes v10 -> v11: - NULL check of kvmalloc_array() in tdx_vcpu_reset. Move it to tdx_vcpu_create() --- arch/x86/kvm/vmx/main.c | 44 ++++++++++++++++++++++++++++++++++---- arch/x86/kvm/vmx/tdx.c | 44 ++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/x86_ops.h | 10 +++++++++ arch/x86/kvm/x86.c | 2 ++ 4 files changed, 96 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index fd49e931f6bb..612f3eb9e422 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -98,6 +98,42 @@ static void vt_vm_free(struct kvm *kvm) tdx_vm_free(kvm); } +static int vt_vcpu_precreate(struct kvm *kvm) +{ + if (is_td(kvm)) + return 0; + + return vmx_vcpu_precreate(kvm); +} + +static int vt_vcpu_create(struct kvm_vcpu *vcpu) +{ + if (is_td_vcpu(vcpu)) + return tdx_vcpu_create(vcpu); + + return vmx_vcpu_create(vcpu); +} + +static void vt_vcpu_free(struct kvm_vcpu *vcpu) +{ + if (is_td_vcpu(vcpu)) { + tdx_vcpu_free(vcpu); + return; + } + + vmx_vcpu_free(vcpu); +} + +static void vt_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) +{ + if (is_td_vcpu(vcpu)) { + tdx_vcpu_reset(vcpu, init_event); + return; + } + + vmx_vcpu_reset(vcpu, init_event); +} + static int vt_mem_enc_ioctl(struct kvm *kvm, void __user *argp) { if (!is_td(kvm)) @@ -138,10 +174,10 @@ struct kvm_x86_ops vt_x86_ops __initdata = { .vm_destroy = vt_vm_destroy, .vm_free = vt_vm_free, - .vcpu_precreate = vmx_vcpu_precreate, - .vcpu_create = vmx_vcpu_create, - .vcpu_free = vmx_vcpu_free, - .vcpu_reset = vmx_vcpu_reset, + .vcpu_precreate = vt_vcpu_precreate, + .vcpu_create = vt_vcpu_create, + .vcpu_free = vt_vcpu_free, + .vcpu_reset = vt_vcpu_reset, .prepare_switch_to_guest = vmx_prepare_switch_to_guest, .vcpu_load = vmx_vcpu_load, diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 646fbf2b630e..2903b37c0c28 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -315,6 +315,50 @@ int tdx_vm_init(struct kvm *kvm) return 0; } +int tdx_vcpu_create(struct kvm_vcpu *vcpu) +{ + /* + * On cpu creation, cpuid entry is blank. Forcibly enable + * X2APIC feature to allow X2APIC. + * Because vcpu_reset() can't return error, allocation is done here. + */ + WARN_ON_ONCE(vcpu->arch.cpuid_entries); + WARN_ON_ONCE(vcpu->arch.cpuid_nent); + + /* TDX only supports x2APIC, which requires an in-kernel local APIC. */ + if (!vcpu->arch.apic) + return -EINVAL; + + fpstate_set_confidential(&vcpu->arch.guest_fpu); + + vcpu->arch.efer = EFER_SCE | EFER_LME | EFER_LMA | EFER_NX; + + vcpu->arch.cr0_guest_owned_bits = -1ul; + vcpu->arch.cr4_guest_owned_bits = -1ul; + + vcpu->arch.tsc_offset = to_kvm_tdx(vcpu->kvm)->tsc_offset; + vcpu->arch.l1_tsc_offset = vcpu->arch.tsc_offset; + vcpu->arch.guest_state_protected = + !(to_kvm_tdx(vcpu->kvm)->attributes & TDX_TD_ATTRIBUTE_DEBUG); + + return 0; +} + +void tdx_vcpu_free(struct kvm_vcpu *vcpu) +{ + /* This is stub for now. More logic will come. */ +} + +void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) +{ + + /* Ignore INIT silently because TDX doesn't support INIT event. */ + if (init_event) + return; + + /* This is stub for now. More logic will come here. */ +} + static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd) { struct kvm_tdx_capabilities __user *user_caps; diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index b13774ee94a0..8229277a8a54 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -145,7 +145,12 @@ int tdx_vm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap); int tdx_vm_init(struct kvm *kvm); void tdx_mmu_release_hkid(struct kvm *kvm); void tdx_vm_free(struct kvm *kvm); + int tdx_vm_ioctl(struct kvm *kvm, void __user *argp); + +int tdx_vcpu_create(struct kvm_vcpu *vcpu); +void tdx_vcpu_free(struct kvm_vcpu *vcpu); +void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); #else static inline int tdx_hardware_setup(struct kvm_x86_ops *x86_ops) { return -ENOSYS; } static inline void tdx_hardware_unsetup(void) {} @@ -156,7 +161,12 @@ static inline int tdx_vm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) static inline int tdx_vm_init(struct kvm *kvm) { return -EOPNOTSUPP; } static inline void tdx_mmu_release_hkid(struct kvm *kvm) {} static inline void tdx_vm_free(struct kvm *kvm) {} + static inline int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOPNOTSUPP; } + +static inline int tdx_vcpu_create(struct kvm_vcpu *vcpu) { return -EOPNOTSUPP; } +static inline void tdx_vcpu_free(struct kvm_vcpu *vcpu) {} +static inline void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) {} #endif #endif /* __KVM_X86_VMX_X86_OPS_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3b7b90d3499a..f0984f0aa18e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -498,6 +498,7 @@ int kvm_set_apic_base(struct kvm_vcpu *vcpu, struct msr_data *msr_info) kvm_recalculate_apic_map(vcpu->kvm); return 0; } +EXPORT_SYMBOL_GPL(kvm_set_apic_base); /* * Handle a fault on a hardware virtualization (VMX or SVM) instruction. @@ -12262,6 +12263,7 @@ bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu) { return vcpu->kvm->arch.bsp_vcpu_id == vcpu->vcpu_id; } +EXPORT_SYMBOL_GPL(kvm_vcpu_is_reset_bsp); bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu) { -- 2.25.1