Message ID | 20231108183003.5981-10-xin3.li@intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:aa0b:0:b0:403:3b70:6f57 with SMTP id k11csp1124527vqo; Wed, 8 Nov 2023 11:03:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IHBMM7oS+GsiHCVgubB3hX08dsWhqZMV/0klkGVezW6iS2nuW1YP3B8xsoDPMHcGwYeYZPo X-Received: by 2002:a17:902:e80f:b0:1cc:4559:f5 with SMTP id u15-20020a170902e80f00b001cc455900f5mr3604453plg.14.1699470197541; Wed, 08 Nov 2023 11:03:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699470197; cv=none; d=google.com; s=arc-20160816; b=GTGh16y4A+ZDyo7FjPuhll8Lvogpyam2iQ3DFi8dwW+gLLhgpRxuEM1knt36homJUY YleZ5NoNHttP+BOE7JUHrdwrr3Rfyn7K9Ee+Dpwlq3YtBW3kb5LfSMKjWoGehiV12197 MeNAR3Vds4ncnGJdMGs2ZrPLhVxfHXOy+CS6dn45fqf6tvW76rKfT/XibEPZ2EFXHuNx mXHAS8a4fb9QN9NN1+4p28UQC/+MWx6YmCUFxB3urCgVccRJQKTiutHy3kuwLNbMc0oP YH2wqYyYUrHFAP913pvWmGYnZxlyskpcUs/5e277oqnINBNGmMMWIQ37+K05cOwS2e7R 1NlA== 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=6BYffizazUKlfOZ9boKvfWSWujAgMw3rFrye2dWL6kY=; fh=jyCs2STAghiemYCMqutk2CMon3BCEX6sSSqaVLqDaaU=; b=F2le62Jn4tk8nr+AT5Fc1L8stddG0ArdsB21ImMKftgUI1BOUMMSKxsYfOdOEsJmNE d6ZZhWWjJZTzVAMMOyh5kzLV6bdtyFlfq0rkvoRrDhaQCeFYLoTqQQkKSqaZQ9XAMRC1 qQi3QMPjoXUesYDYrZFSKglsN4ZAXtMIFj2GKYsQ8+FxH2hc7UM+tvyzxZIinHKjpBRb 9zWDYFxqQiklxU2LTZHIW6OpT+H6tCOlGpCRIfQVNgddXgCfZn7kmKbo4ndq2XEITpRI RwgAGvPp7QpRSi83H6+j4mR/mSOSRGhPY1ZV6qSTb3eVI24MljUVkyJ+OxwDLyFZs2a2 PXSg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JgSRSeJZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from fry.vger.email (fry.vger.email. [23.128.96.38]) by mx.google.com with ESMTPS id ky13-20020a170902f98d00b001cc692bf120si2700318plb.61.2023.11.08.11.03.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Nov 2023 11:03:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) client-ip=23.128.96.38; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JgSRSeJZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 0926F83A9FAD; Wed, 8 Nov 2023 11:03:03 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233309AbjKHTAu (ORCPT <rfc822;jaysivo@gmail.com> + 32 others); Wed, 8 Nov 2023 14:00:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232367AbjKHTAY (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 8 Nov 2023 14:00:24 -0500 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CA612118; Wed, 8 Nov 2023 11:00:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699470022; x=1731006022; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=g73pajj6LcG0nirmtYAP2EfGJEvaHaj/eDWN0wShpq4=; b=JgSRSeJZO319GMkkVM5oF00rMVvF1+b1e4gSCMAWyr9eNy6gQM4FSv98 f3foPHOsjnEAGdUkZUZTk1Mtc1I/bXGHXbPbium5xt7BMz37nFLarWK41 kjL8xFP2jkx9+T4jcB/AYxuGeywMT4p/sZhH0ajQoDsRyrU0S50tVMmB8 rwR7sjGb/JhfJSHLs1SpCN5eS5n0IycTcPmpEgLJW/Qu1cDF44rVLWb9L bW+rYn2mfI5aMTxsOra26YDgeZoL64BM9OLT1+8oNxtN/4M7VsfipUScS 6V6xHWyxvglwVRWGCRZ44oRVg3WrIi9r8dX/AMY//YyhefS2q/94oahb8 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10888"; a="8486310" X-IronPort-AV: E=Sophos;i="6.03,287,1694761200"; d="scan'208";a="8486310" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Nov 2023 11:00:21 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.03,287,1694761200"; d="scan'208";a="10892452" Received: from unknown (HELO fred..) ([172.25.112.68]) by orviesa001.jf.intel.com with ESMTP; 08 Nov 2023 11:00:20 -0800 From: Xin Li <xin3.li@intel.com> To: kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: seanjc@google.com, pbonzini@redhat.com, corbet@lwn.net, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, vkuznets@redhat.com, peterz@infradead.org, ravi.v.shankar@intel.com Subject: [PATCH v1 09/23] KVM: VMX: Switch FRED RSP0 between host and guest Date: Wed, 8 Nov 2023 10:29:49 -0800 Message-ID: <20231108183003.5981-10-xin3.li@intel.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231108183003.5981-1-xin3.li@intel.com> References: <20231108183003.5981-1-xin3.li@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Wed, 08 Nov 2023 11:03:03 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782023661861008017 X-GMAIL-MSGID: 1782023661861008017 |
Series |
Enable FRED with KVM VMX
|
|
Commit Message
Li, Xin3
Nov. 8, 2023, 6:29 p.m. UTC
Switch MSR_IA32_FRED_RSP0 between host and guest in vmx_prepare_switch_to_{host,guest}(). MSR_IA32_FRED_RSP0 is used during ring 3 event delivery only, thus KVM, running on ring 0, can run safely with guest FRED RSP0, i.e., no need to switch between host/guest FRED RSP0 during VM entry and exit. KVM should switch to host FRED RSP0 before returning to user level, and switch to guest FRED RSP0 before entering guest mode. Tested-by: Shan Kang <shan.kang@intel.com> Signed-off-by: Xin Li <xin3.li@intel.com> --- arch/x86/kvm/vmx/vmx.c | 17 +++++++++++++++++ arch/x86/kvm/vmx/vmx.h | 2 ++ 2 files changed, 19 insertions(+)
Comments
On Wed, Nov 08, 2023 at 10:29:49AM -0800, Xin Li wrote: >Switch MSR_IA32_FRED_RSP0 between host and guest in >vmx_prepare_switch_to_{host,guest}(). > >MSR_IA32_FRED_RSP0 is used during ring 3 event delivery only, thus >KVM, running on ring 0, can run safely with guest FRED RSP0, i.e., >no need to switch between host/guest FRED RSP0 during VM entry and >exit. > >KVM should switch to host FRED RSP0 before returning to user level, >and switch to guest FRED RSP0 before entering guest mode. > >Tested-by: Shan Kang <shan.kang@intel.com> >Signed-off-by: Xin Li <xin3.li@intel.com> >--- > arch/x86/kvm/vmx/vmx.c | 17 +++++++++++++++++ > arch/x86/kvm/vmx/vmx.h | 2 ++ > 2 files changed, 19 insertions(+) > >diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c >index 41772ecdd368..d00ab9d4c93e 100644 >--- a/arch/x86/kvm/vmx/vmx.c >+++ b/arch/x86/kvm/vmx/vmx.c >@@ -1344,6 +1344,17 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) > } > > wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); >+ >+ if (cpu_feature_enabled(X86_FEATURE_FRED) && >+ guest_cpuid_has(vcpu, X86_FEATURE_FRED)) { >+ /* >+ * MSR_IA32_FRED_RSP0 is top of task stack, which never changes. >+ * Thus it should be initialized only once. >+ */ >+ if (unlikely(vmx->msr_host_fred_rsp0 == 0)) >+ vmx->msr_host_fred_rsp0 = read_msr(MSR_IA32_FRED_RSP0); >+ wrmsrl(MSR_IA32_FRED_RSP0, vmx->msr_guest_fred_rsp0); >+ } > #else > savesegment(fs, fs_sel); > savesegment(gs, gs_sel); >@@ -1388,6 +1399,12 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) > invalidate_tss_limit(); > #ifdef CONFIG_X86_64 > wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); >+ >+ if (cpu_feature_enabled(X86_FEATURE_FRED) && >+ guest_cpuid_has(&vmx->vcpu, X86_FEATURE_FRED)) { IIUC, vmx_prepare_switch_to_host() is called from IRQ-disabled context. using guest_cpuid_has() in this context is not desired, see lockdep_assert_irqs_enabled() in cpuid_entry2_find(). >+ vmx->msr_guest_fred_rsp0 = read_msr(MSR_IA32_FRED_RSP0); >+ wrmsrl(MSR_IA32_FRED_RSP0, vmx->msr_host_fred_rsp0); >+ } > #endif > load_fixmap_gdt(raw_smp_processor_id()); > vmx->guest_state_loaded = false; >diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h >index f8c02bd37069..328a3447f064 100644 >--- a/arch/x86/kvm/vmx/vmx.h >+++ b/arch/x86/kvm/vmx/vmx.h >@@ -276,6 +276,8 @@ struct vcpu_vmx { > #ifdef CONFIG_X86_64 > u64 msr_host_kernel_gs_base; > u64 msr_guest_kernel_gs_base; >+ u64 msr_host_fred_rsp0; >+ u64 msr_guest_fred_rsp0; resetting guest fred rsp0 to 0 during vcpu reset is missing. > #endif > > u64 spec_ctrl; >-- >2.42.0 > >
> >+ if (cpu_feature_enabled(X86_FEATURE_FRED) && > >+ guest_cpuid_has(&vmx->vcpu, X86_FEATURE_FRED)) { > > IIUC, vmx_prepare_switch_to_host() is called from IRQ-disabled context. using > guest_cpuid_has() in this context is not desired, see > lockdep_assert_irqs_enabled() in cpuid_entry2_find(). Nice catch! Anyway it's a bad idea to do a search call here, let me find a better way for all FRED CPUID checks. > >diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index > >f8c02bd37069..328a3447f064 100644 > >--- a/arch/x86/kvm/vmx/vmx.h > >+++ b/arch/x86/kvm/vmx/vmx.h > >@@ -276,6 +276,8 @@ struct vcpu_vmx { > > #ifdef CONFIG_X86_64 > > u64 msr_host_kernel_gs_base; > > u64 msr_guest_kernel_gs_base; > >+ u64 msr_host_fred_rsp0; > >+ u64 msr_guest_fred_rsp0; > > resetting guest fred rsp0 to 0 during vcpu reset is missing. hmm, I assume it gets the same treatment as guest_kernel_gs_base. It seems we don't reset guest_kernel_gs_base. No?
>> >diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index >> >f8c02bd37069..328a3447f064 100644 >> >--- a/arch/x86/kvm/vmx/vmx.h >> >+++ b/arch/x86/kvm/vmx/vmx.h >> >@@ -276,6 +276,8 @@ struct vcpu_vmx { >> > #ifdef CONFIG_X86_64 >> > u64 msr_host_kernel_gs_base; >> > u64 msr_guest_kernel_gs_base; >> >+ u64 msr_host_fred_rsp0; >> >+ u64 msr_guest_fred_rsp0; >> >> resetting guest fred rsp0 to 0 during vcpu reset is missing. > >hmm, I assume it gets the same treatment as guest_kernel_gs_base. > >It seems we don't reset guest_kernel_gs_base. No? Yes. But for fred MSRs, FRED spec clearly says their RESET values are 0s. for kernel_gs_base MSR, looks there is no such description in SDM.
> >> >diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index > >> >f8c02bd37069..328a3447f064 100644 > >> >--- a/arch/x86/kvm/vmx/vmx.h > >> >+++ b/arch/x86/kvm/vmx/vmx.h > >> >@@ -276,6 +276,8 @@ struct vcpu_vmx { > >> > #ifdef CONFIG_X86_64 > >> > u64 msr_host_kernel_gs_base; > >> > u64 msr_guest_kernel_gs_base; > >> >+ u64 msr_host_fred_rsp0; > >> >+ u64 msr_guest_fred_rsp0; > >> > >> resetting guest fred rsp0 to 0 during vcpu reset is missing. > > > >hmm, I assume it gets the same treatment as guest_kernel_gs_base. > > > >It seems we don't reset guest_kernel_gs_base. No? > > Yes. But for fred MSRs, FRED spec clearly says their RESET values > are 0s. for kernel_gs_base MSR, looks there is no such description > in SDM. Right, maybe better to set both to 0s.
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 41772ecdd368..d00ab9d4c93e 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1344,6 +1344,17 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) } wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); + + if (cpu_feature_enabled(X86_FEATURE_FRED) && + guest_cpuid_has(vcpu, X86_FEATURE_FRED)) { + /* + * MSR_IA32_FRED_RSP0 is top of task stack, which never changes. + * Thus it should be initialized only once. + */ + if (unlikely(vmx->msr_host_fred_rsp0 == 0)) + vmx->msr_host_fred_rsp0 = read_msr(MSR_IA32_FRED_RSP0); + wrmsrl(MSR_IA32_FRED_RSP0, vmx->msr_guest_fred_rsp0); + } #else savesegment(fs, fs_sel); savesegment(gs, gs_sel); @@ -1388,6 +1399,12 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) invalidate_tss_limit(); #ifdef CONFIG_X86_64 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); + + if (cpu_feature_enabled(X86_FEATURE_FRED) && + guest_cpuid_has(&vmx->vcpu, X86_FEATURE_FRED)) { + vmx->msr_guest_fred_rsp0 = read_msr(MSR_IA32_FRED_RSP0); + wrmsrl(MSR_IA32_FRED_RSP0, vmx->msr_host_fred_rsp0); + } #endif load_fixmap_gdt(raw_smp_processor_id()); vmx->guest_state_loaded = false; diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index f8c02bd37069..328a3447f064 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -276,6 +276,8 @@ struct vcpu_vmx { #ifdef CONFIG_X86_64 u64 msr_host_kernel_gs_base; u64 msr_guest_kernel_gs_base; + u64 msr_host_fred_rsp0; + u64 msr_guest_fred_rsp0; #endif u64 spec_ctrl;