From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 EB68D24337D; Wed, 23 Jul 2025 17:54:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293282; cv=none; b=vGIGnIawMNA4Y0Ap+fjuk64JkxknUahfg/KcTnhg4Yo/75LM4swwkA3VD1bCBUyttYCeZp1l6eKLw0MzSEwEwELs21Na6Z6qfkGA5mMYZz5WGV5V8EtpWIo+wftcllzbZw9ipV1Q6MG9kQ8+xL2dDOI0jtBWFA0YoPPSPI7PLC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293282; c=relaxed/simple; bh=uKFKtuUxAkKG3f5bc9mwH9YIehY5Z93I+Y2FSYl8zM0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Xv3BXjxvSSqd+BJ4aoFS0Bf6HQ+uF0M3VJ0lTZvzz8XYiahmp7yvEu6wB49th+foxqxCqgDRclQJXgW4aYX/difn1GO/AAYLr/JkCLCMQEEPSRgdejFAwaW9LOGM3gSKmsVVR0oRtfZpu4iPhz1RwlVjqItoa9dG2QpoTmu/+BA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=Vy/4df+6; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="Vy/4df+6" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxp1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:46 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxp1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293227; bh=hemCn90KBQZPWPg97p57m0nDW+enGor0ghJKArAnWs0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vy/4df+6GYdPa/Nzlzj2fGFUTk2xPt6DZ+l6SHyMF9dz3zW2zlBhCKUiXOofDJvAm qL+yr4kI8XLvEmLmljGmuAQ93ShihBTmk52lewM6CfIWUtMKhQRX4DwGGgsNyzH7TA Ayjunw3b+1543YONJROp6f6ObNTxAw6pTkrM1A+YQ92/PFU80flFBjjXDYWNYTA5mP uashUiRXZWwEM/2j7lq5+FdOXrHTFW5cEMn+fPhYwvYA2JY+dxC34zqSm6LV328COt nps/G2bV2mKEwz0ZA3190F3f2Uehy0PpBImP+JOZ81uqTaZXcP//5M30C06kZ4Ad7e eJsUuVPu1wxbA== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 01/23] KVM: VMX: Add support for the secondary VM exit controls Date: Wed, 23 Jul 2025 10:53:19 -0700 Message-ID: <20250723175341.1284463-2-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Always load the secondary VM exit controls to prepare for FRED enabling. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Changes in v4: * Fix clearing VM_EXIT_ACTIVATE_SECONDARY_CONTROLS (Chao Gao). * Check VM exit/entry consistency based on the new macro from Sean Christopherson. Change in v3: * Do FRED controls consistency checks in the VM exit/entry consistency check framework (Sean Christopherson). Change in v2: * Always load the secondary VM exit controls (Sean Christopherson). --- arch/x86/include/asm/msr-index.h | 1 + arch/x86/include/asm/vmx.h | 3 +++ arch/x86/kvm/vmx/capabilities.h | 9 ++++++++- arch/x86/kvm/vmx/vmcs.h | 1 + arch/x86/kvm/vmx/vmx.c | 29 +++++++++++++++++++++++++++-- arch/x86/kvm/vmx/vmx.h | 7 ++++++- 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index c29127ac626a..d7667980ca2c 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1201,6 +1201,7 @@ #define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 #define MSR_IA32_VMX_VMFUNC 0x00000491 #define MSR_IA32_VMX_PROCBASED_CTLS3 0x00000492 +#define MSR_IA32_VMX_EXIT_CTLS2 0x00000493 =20 /* Resctrl MSRs: */ /* - Intel: */ diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index cca7d6641287..97f7e0545534 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -106,6 +106,7 @@ #define VM_EXIT_CLEAR_BNDCFGS 0x00800000 #define VM_EXIT_PT_CONCEAL_PIP 0x01000000 #define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 +#define VM_EXIT_ACTIVATE_SECONDARY_CONTROLS 0x80000000 =20 #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff =20 @@ -259,6 +260,8 @@ enum vmcs_field { SHARED_EPT_POINTER =3D 0x0000203C, PID_POINTER_TABLE =3D 0x00002042, PID_POINTER_TABLE_HIGH =3D 0x00002043, + SECONDARY_VM_EXIT_CONTROLS =3D 0x00002044, + SECONDARY_VM_EXIT_CONTROLS_HIGH =3D 0x00002045, GUEST_PHYSICAL_ADDRESS =3D 0x00002400, GUEST_PHYSICAL_ADDRESS_HIGH =3D 0x00002401, VMCS_LINK_POINTER =3D 0x00002800, diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index 5316c27f6099..7cdc855f8968 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -58,8 +58,9 @@ struct vmcs_config { u32 cpu_based_exec_ctrl; u32 cpu_based_2nd_exec_ctrl; u64 cpu_based_3rd_exec_ctrl; - u32 vmexit_ctrl; u32 vmentry_ctrl; + u32 vmexit_ctrl; + u64 vmexit_2nd_ctrl; u64 misc; struct nested_vmx_msrs nested; }; @@ -135,6 +136,12 @@ static inline bool cpu_has_tertiary_exec_ctrls(void) CPU_BASED_ACTIVATE_TERTIARY_CONTROLS; } =20 +static inline bool cpu_has_secondary_vmexit_ctrls(void) +{ + return vmcs_config.vmexit_ctrl & + VM_EXIT_ACTIVATE_SECONDARY_CONTROLS; +} + static inline bool cpu_has_vmx_virtualize_apic_accesses(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h index b25625314658..ae152a9d1963 100644 --- a/arch/x86/kvm/vmx/vmcs.h +++ b/arch/x86/kvm/vmx/vmcs.h @@ -47,6 +47,7 @@ struct vmcs_host_state { struct vmcs_controls_shadow { u32 vm_entry; u32 vm_exit; + u64 secondary_vm_exit; u32 pin; u32 exec; u32 secondary_exec; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index aa157fe5b7b3..85632de1dddb 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2565,8 +2565,9 @@ static int setup_vmcs_config(struct vmcs_config *vmcs= _conf, u32 _cpu_based_exec_control =3D 0; u32 _cpu_based_2nd_exec_control =3D 0; u64 _cpu_based_3rd_exec_control =3D 0; - u32 _vmexit_control =3D 0; u32 _vmentry_control =3D 0; + u32 _vmexit_control =3D 0; + u64 _vmexit2_control =3D 0; u64 basic_msr; u64 misc_msr; =20 @@ -2586,6 +2587,12 @@ static int setup_vmcs_config(struct vmcs_config *vmc= s_conf, { VM_ENTRY_LOAD_IA32_RTIT_CTL, VM_EXIT_CLEAR_IA32_RTIT_CTL }, }; =20 + struct { + u32 entry_control; + u64 exit_control; + } const vmcs_entry_exit2_pairs[] =3D { + }; + memset(vmcs_conf, 0, sizeof(*vmcs_conf)); =20 if (adjust_vmx_controls(KVM_REQUIRED_VMX_CPU_BASED_VM_EXEC_CONTROL, @@ -2672,10 +2679,19 @@ static int setup_vmcs_config(struct vmcs_config *vm= cs_conf, &_vmentry_control)) return -EIO; =20 + if (_vmexit_control & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) + _vmexit2_control =3D + adjust_vmx_controls64(KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS, + MSR_IA32_VMX_EXIT_CTLS2); + if (vmx_check_entry_exit_pairs(vmcs_entry_exit_pairs, _vmentry_control, _vmexit_control)) return -EIO; =20 + if (vmx_check_entry_exit_pairs(vmcs_entry_exit2_pairs, + _vmentry_control, _vmexit2_control)) + return -EIO; + /* * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they * can't be used due to an errata where VM Exit may incorrectly clear @@ -2724,8 +2740,9 @@ static int setup_vmcs_config(struct vmcs_config *vmcs= _conf, vmcs_conf->cpu_based_exec_ctrl =3D _cpu_based_exec_control; vmcs_conf->cpu_based_2nd_exec_ctrl =3D _cpu_based_2nd_exec_control; vmcs_conf->cpu_based_3rd_exec_ctrl =3D _cpu_based_3rd_exec_control; - vmcs_conf->vmexit_ctrl =3D _vmexit_control; vmcs_conf->vmentry_ctrl =3D _vmentry_control; + vmcs_conf->vmexit_ctrl =3D _vmexit_control; + vmcs_conf->vmexit_2nd_ctrl =3D _vmexit2_control; vmcs_conf->misc =3D misc_msr; =20 #if IS_ENABLED(CONFIG_HYPERV) @@ -4340,6 +4357,11 @@ static u32 vmx_vmexit_ctrl(void) ~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | VM_EXIT_LOAD_IA32_EFER); } =20 +static u64 vmx_secondary_vmexit_ctrl(void) +{ + return vmcs_config.vmexit_2nd_ctrl; +} + void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx =3D to_vmx(vcpu); @@ -4688,6 +4710,9 @@ static void init_vmcs(struct vcpu_vmx *vmx) =20 vm_exit_controls_set(vmx, vmx_vmexit_ctrl()); =20 + if (cpu_has_secondary_vmexit_ctrls()) + secondary_vm_exit_controls_set(vmx, vmx_secondary_vmexit_ctrl()); + /* 22.2.1, 20.8.1 */ vm_entry_controls_set(vmx, vmx_vmentry_ctrl()); =20 diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index d3389baf3ab3..20194412bed3 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -506,7 +506,11 @@ static inline u8 vmx_get_rvi(void) VM_EXIT_LOAD_IA32_EFER | \ VM_EXIT_CLEAR_BNDCFGS | \ VM_EXIT_PT_CONCEAL_PIP | \ - VM_EXIT_CLEAR_IA32_RTIT_CTL) + VM_EXIT_CLEAR_IA32_RTIT_CTL | \ + VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) + +#define KVM_REQUIRED_VMX_SECONDARY_VM_EXIT_CONTROLS (0) +#define KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS (0) =20 #define KVM_REQUIRED_VMX_PIN_BASED_VM_EXEC_CONTROL \ (PIN_BASED_EXT_INTR_MASK | \ @@ -611,6 +615,7 @@ static __always_inline void lname##_controls_clearbit(s= truct vcpu_vmx *vmx, u##b } BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS, 32) BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS, 32) +BUILD_CONTROLS_SHADOW(secondary_vm_exit, SECONDARY_VM_EXIT_CONTROLS, 64) BUILD_CONTROLS_SHADOW(pin, PIN_BASED_VM_EXEC_CONTROL, 32) BUILD_CONTROLS_SHADOW(exec, CPU_BASED_VM_EXEC_CONTROL, 32) BUILD_CONTROLS_SHADOW(secondary_exec, SECONDARY_VM_EXEC_CONTROL, 32) --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 7A69523D288; Wed, 23 Jul 2025 17:54:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293282; cv=none; b=TvAXGg01ALTYN7M9HzeOMcdA4ZRBZQj3VCEswUwrSkXjtY4j9/gIFgiL0LegFEZ9GhPFa4hPuqmsLpkznLWOBOdwdJJGrFJRHP1kpdeQFG/NXMu1e8VYstFCtEQ2V0IGB1eVoXF5u7wZNG77YxSwMn9lr5QKjoNU+Jldg1HFJwo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293282; c=relaxed/simple; bh=/gutJcM4arTMByvbZfk3KluI2+D980tBXtJ5GhFHKZ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nKjxDjZgguCCNtRJ5QC27xMF7J62D0miXP+QHrtAKroF4S4mcIprgQfmQnXn2/GyK9k312jT1M5G1Z8vMPRW2KjCj+3cKeVUwgDkRxjMiSSLrj+TKzr+nMlQm04EdjaQ0HWgOcvl0Rk1BfgtuBUvxZ9cuIYRO2IePhPKddZwLHc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=mSZK8gnI; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="mSZK8gnI" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxq1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:47 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxq1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293228; bh=GJkPKHhxeHZQ2rloiYOXgmmG+qEVAmh+lbVKbqnN2ts=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mSZK8gnIvlS3ck43HMHNXsdBBJaeF7Brl8Coo0nIcMAhMKzJAdWZKp7Pe0b1V/3Ny GvKEUqQ7iNqzE87Lwt0X/B0P76Z3Vv3Hbu3u9oxb2RZmEgPfAMbCZA3laq680WGFIo l3ILhK/iL5/35l9gi8oaPOP1KTm/EKd0f669vgrOPUhsFkfHwfqedWh+9wMlhFykDW ONeV2Dbbhj5rQt8Rvm8rtn67XOvevTXik16IK7blGeBZOpTILfvvHtEJoUIM4pWsVE 6UfUL/za/h/SRVy2Icbk1fZQ9rVSB6TYBaXVpoB3AFPZ3F51MItt7gqr+La/0MLr4C GK9nlxaisOmXw== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 02/23] KVM: VMX: Initialize VM entry/exit FRED controls in vmcs_config Date: Wed, 23 Jul 2025 10:53:20 -0700 Message-ID: <20250723175341.1284463-3-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Setup VM entry/exit FRED controls in the global vmcs_config for proper FRED VMCS fields management: 1) load guest FRED state upon VM entry. 2) save guest FRED state during VM exit. 3) load host FRED state during VM exit. Also add FRED control consistency checks to the existing VM entry/exit consistency check framework. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo Reviewed-by: Chao Gao --- Change in v5: * Remove the pair VM_ENTRY_LOAD_IA32_FRED/VM_EXIT_ACTIVATE_SECONDARY_CONTRO= LS, since the secondary VM exit controls are unconditionally enabled anyway, = and there are features other than FRED needing it (Chao Gao). * Add TB from Xuelian Guo. Change in v4: * Do VM exit/entry consistency checks using the new macro from Sean Christopherson. Changes in v3: * Add FRED control consistency checks to the existing VM entry/exit consistency check framework (Sean Christopherson). * Just do the unnecessary FRED state load/store on every VM entry/exit (Sean Christopherson). --- arch/x86/include/asm/vmx.h | 4 ++++ arch/x86/kvm/vmx/vmx.c | 2 ++ arch/x86/kvm/vmx/vmx.h | 7 +++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 97f7e0545534..1879de94457d 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -108,6 +108,9 @@ #define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 #define VM_EXIT_ACTIVATE_SECONDARY_CONTROLS 0x80000000 =20 +#define SECONDARY_VM_EXIT_SAVE_IA32_FRED BIT_ULL(0) +#define SECONDARY_VM_EXIT_LOAD_IA32_FRED BIT_ULL(1) + #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff =20 #define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004 @@ -120,6 +123,7 @@ #define VM_ENTRY_LOAD_BNDCFGS 0x00010000 #define VM_ENTRY_PT_CONCEAL_PIP 0x00020000 #define VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000 +#define VM_ENTRY_LOAD_IA32_FRED 0x00800000 =20 #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff =20 diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 85632de1dddb..463fc4a65788 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2591,6 +2591,8 @@ static int setup_vmcs_config(struct vmcs_config *vmcs= _conf, u32 entry_control; u64 exit_control; } const vmcs_entry_exit2_pairs[] =3D { + { VM_ENTRY_LOAD_IA32_FRED, + SECONDARY_VM_EXIT_SAVE_IA32_FRED | SECONDARY_VM_EXIT_LOAD_IA32_FRED }, }; =20 memset(vmcs_conf, 0, sizeof(*vmcs_conf)); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 20194412bed3..32829f98af2f 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -484,7 +484,8 @@ static inline u8 vmx_get_rvi(void) VM_ENTRY_LOAD_IA32_EFER | \ VM_ENTRY_LOAD_BNDCFGS | \ VM_ENTRY_PT_CONCEAL_PIP | \ - VM_ENTRY_LOAD_IA32_RTIT_CTL) + VM_ENTRY_LOAD_IA32_RTIT_CTL | \ + VM_ENTRY_LOAD_IA32_FRED) =20 #define __KVM_REQUIRED_VMX_VM_EXIT_CONTROLS \ (VM_EXIT_SAVE_DEBUG_CONTROLS | \ @@ -510,7 +511,9 @@ static inline u8 vmx_get_rvi(void) VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) =20 #define KVM_REQUIRED_VMX_SECONDARY_VM_EXIT_CONTROLS (0) -#define KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS (0) +#define KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS \ + (SECONDARY_VM_EXIT_SAVE_IA32_FRED | \ + SECONDARY_VM_EXIT_LOAD_IA32_FRED) =20 #define KVM_REQUIRED_VMX_PIN_BASED_VM_EXEC_CONTROL \ (PIN_BASED_EXT_INTR_MASK | \ --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 011B8223704; Wed, 23 Jul 2025 17:54:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293280; cv=none; b=UJ+ZHUexibZ6Bdzuz68Dq8boI4gwaSdz2zfX52+FAWMKReChOd8MK4APwh4a1xEWTMm4q0ZqC30Yb+v+ARV2JQm9drqWn5IrHCdTxXmL6uLOxn0oQV79zbfaaqpQ+fI6M4K3p8LdjjId+cujc2sk7sjzrzGqVd2UNL5mEBjAx7U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293280; c=relaxed/simple; bh=cIId5kcAjZVRwjWCEwIG02N9gFcnlWs3CphxzwwvPHk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X6MaqZ0Gihbq9e/j9OzJTg6Gl8X5mPDt+gf4in4G3X9ENr8T2JDJvcMZWDDBMvmWmKoExKJnj2lOBG83i5mCy2mPteTp1Lk/nXDpjJlxqHx61vAIKy8Re1+6W+2Zp3Nha+KoflBN8RAkiGMl2gVvYg1vmHHvk0L7nJoOG6V5oSw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=SBG5DkO3; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="SBG5DkO3" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxr1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:48 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxr1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293229; bh=ezk0SHtbQQhiYpEbIX5qyLWNRlt8kAg5n8VSrXZq8vA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SBG5DkO3dKiHcTN75kdVqAXWeltE94c7xBGWTKYJvw/yS2O39DTLlnwCB5AWSfR0O UHpFDiDCe7lnxhMPqFPCocHavFsj/RYgi+yF5wOGHOB3RxP//ubMVDp+FAGLtLqmXm pD0DYchlwuKkWC9U5wPR1rT7hmGjBnV3N6E3wOInhZ4NLaZzuGxnOR5rz7snb/Nx00 Qu7hbQvHhYZxYrJEFCufscaoqsK+jE4lKAmo0NSo6gN51Sm5WVo0zH+RJui2wlWhcB U4rCtufoAnV7W2vXxh/Tw/03BEcp7QqHSeDsWCjIg+bgxJfgndjL7qMEIzGRk/hfHn 7DNLbpbkZET9w== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 03/23] KVM: VMX: Disable FRED if FRED consistency checks fail Date: Wed, 23 Jul 2025 10:53:21 -0700 Message-ID: <20250723175341.1284463-4-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Do not virtualize FRED if FRED consistency checks fail. Either on broken hardware, or when run KVM on top of another hypervisor before the underlying hypervisor implements nested FRED correctly. Suggested-by: Chao Gao Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Reviewed-by: Chao Gao Tested-by: Shan Kang Tested-by: Xuelian Guo --- Changes in v5: * Drop the cpu_feature_enabled() in cpu_has_vmx_fred() (Sean). * Add TB from Xuelian Guo. Change in v4: * Call out the reason why not check FRED VM-exit controls in cpu_has_vmx_fred() (Chao Gao). --- arch/x86/kvm/vmx/capabilities.h | 10 ++++++++++ arch/x86/kvm/vmx/vmx.c | 3 +++ 2 files changed, 13 insertions(+) diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index 7cdc855f8968..76c69685b9be 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -399,6 +399,16 @@ static inline bool vmx_pebs_supported(void) return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept; } =20 +static inline bool cpu_has_vmx_fred(void) +{ + /* + * setup_vmcs_config() guarantees FRED VM-entry/exit controls + * are either all set or none. So, no need to check FRED VM-exit + * controls. + */ + return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_FRED); +} + static inline bool cpu_has_notify_vmexit(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 463fc4a65788..c893ea2db9de 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7883,6 +7883,9 @@ static __init void vmx_set_cpu_caps(void) kvm_cpu_cap_check_and_set(X86_FEATURE_DTES64); } =20 + if (!cpu_has_vmx_fred()) + kvm_cpu_cap_clear(X86_FEATURE_FRED); + if (!enable_pmu) kvm_cpu_cap_clear(X86_FEATURE_PDCM); kvm_caps.supported_perf_cap =3D vmx_get_perf_capabilities(); --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 EB6F4243387; Wed, 23 Jul 2025 17:54:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293282; cv=none; b=g8ZTpomRHM5J9O1hl3hY9vFI6M152tfdcKd5qNKAMtPu/kTn8njhe3T1zSrr40IQ61e4BHoIRjdiWZ3ketokVKWydCY3xNdnG5eFyhhmW3DsBBXlR6k5PnXLcfK6hHvYKTt3wvwZzE/AN0Szux/vBdsPUzDo0MWFp/xCkPOAhl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293282; c=relaxed/simple; bh=Y9dXsRrgWme/Psx4ALMo1EVrCJB0pqVZzUs8S2+582s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jd9Fu3C6vh3nF07sgnyGPqQVkvTFsfd3lLoLy5XZBw7EDXGj9BnqATBg7KRmmgpFQGzWpX0teUERLDquO/c8fMTOumdBPTUMIvfUdiS1eI+4zY8Bg3VZo4oozvHPuRgxZ0Z8GPGEqWPW4FYj6OcgeGGeKEnQIWO2Kv6bATHdGho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=DRwfDCM/; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="DRwfDCM/" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxs1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:49 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxs1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293229; bh=zWmv1h33/Y4aVP2ROh/ukXxbHw+ez10mA/TACx32Rmo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DRwfDCM/WYq6OI6VfHvrw4cIROJug08++6mq8FURDipFVJ5evAXpi6BVW+QtSlFdl 9+KeKxjXAsxmAVXzPHiJTvw5ELxUOymXSn51j91dhRzG5wKBmw6w8UYv/q5oa+KDqt qPis5HOztDddWxe+NMb6LBa04e0pgaT5pO7tEk75zxCYeX5O6mp4lM/Ld+FqdW4BMG hrSSXNTZJqqwNKXPU89ANb+K4pCNqqyuhndVpo4nainZ9WOsQjZYuUKfIzajdD6GQw 1fx1DoncpOnylhL8G2O3TKE54qNJ3J26PpNnPsPssB0w4r5PjMlsA4DQ8KusB2qWoy OxnyampBwMZ3A== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 04/23] x86/cea: Export an API to get per CPU exception stacks for KVM to use Date: Wed, 23 Jul 2025 10:53:22 -0700 Message-ID: <20250723175341.1284463-5-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" FRED introduced new fields in the host-state area of the VMCS for stack levels 1->3 (HOST_IA32_FRED_RSP[123]), each respectively corresponding to per CPU exception stacks for #DB, NMI and #DF. KVM must populate these each time a vCPU is loaded onto a CPU. Convert the __this_cpu_ist_{top,bottom}_va() macros into real functions and export __this_cpu_ist_top_va(). Suggested-by: Christoph Hellwig Suggested-by: Dave Hansen Signed-off-by: Xin Li (Intel) Tested-by: Xuelian Guo --- Change in v5: * Export accessor instead of data (Christoph Hellwig). * Add TB from Xuelian Guo. Change in v4: * Rewrite the change log and add comments to the export (Dave Hansen). --- arch/x86/coco/sev/sev-nmi.c | 4 ++-- arch/x86/coco/sev/vc-handle.c | 2 +- arch/x86/include/asm/cpu_entry_area.h | 17 ++++------------- arch/x86/kernel/cpu/common.c | 10 +++++----- arch/x86/kernel/fred.c | 6 +++--- arch/x86/kernel/traps.c | 2 +- arch/x86/mm/cpu_entry_area.c | 21 +++++++++++++++++++++ arch/x86/mm/fault.c | 2 +- 8 files changed, 38 insertions(+), 26 deletions(-) diff --git a/arch/x86/coco/sev/sev-nmi.c b/arch/x86/coco/sev/sev-nmi.c index d8dfaddfb367..73e34ad7a1a9 100644 --- a/arch/x86/coco/sev/sev-nmi.c +++ b/arch/x86/coco/sev/sev-nmi.c @@ -30,7 +30,7 @@ static __always_inline bool on_vc_stack(struct pt_regs *r= egs) if (ip_within_syscall_gap(regs)) return false; =20 - return ((sp >=3D __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_to= p_va(VC))); + return ((sp >=3D __this_cpu_ist_bottom_va(ESTACK_VC)) && (sp < __this_cpu= _ist_top_va(ESTACK_VC))); } =20 /* @@ -82,7 +82,7 @@ void noinstr __sev_es_ist_exit(void) /* Read IST entry */ ist =3D __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]); =20 - if (WARN_ON(ist =3D=3D __this_cpu_ist_top_va(VC))) + if (WARN_ON(ist =3D=3D __this_cpu_ist_top_va(ESTACK_VC))) return; =20 /* Read back old IST entry and write it to the TSS */ diff --git a/arch/x86/coco/sev/vc-handle.c b/arch/x86/coco/sev/vc-handle.c index 0989d98da130..a6e274f2a135 100644 --- a/arch/x86/coco/sev/vc-handle.c +++ b/arch/x86/coco/sev/vc-handle.c @@ -851,7 +851,7 @@ static enum es_result vc_handle_exitcode(struct es_em_c= txt *ctxt, =20 static __always_inline bool is_vc2_stack(unsigned long sp) { - return (sp >=3D __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_= va(VC2)); + return (sp >=3D __this_cpu_ist_bottom_va(ESTACK_VC2) && sp < __this_cpu_i= st_top_va(ESTACK_VC2)); } =20 static __always_inline bool vc_from_invalid_context(struct pt_regs *regs) diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/c= pu_entry_area.h index 462fc34f1317..8e17f0ca74e6 100644 --- a/arch/x86/include/asm/cpu_entry_area.h +++ b/arch/x86/include/asm/cpu_entry_area.h @@ -46,7 +46,7 @@ struct cea_exception_stacks { * The exception stack ordering in [cea_]exception_stacks */ enum exception_stack_ordering { - ESTACK_DF, + ESTACK_DF =3D 0, ESTACK_NMI, ESTACK_DB, ESTACK_MCE, @@ -58,18 +58,15 @@ enum exception_stack_ordering { #define CEA_ESTACK_SIZE(st) \ sizeof(((struct cea_exception_stacks *)0)->st## _stack) =20 -#define CEA_ESTACK_BOT(ceastp, st) \ - ((unsigned long)&(ceastp)->st## _stack) - -#define CEA_ESTACK_TOP(ceastp, st) \ - (CEA_ESTACK_BOT(ceastp, st) + CEA_ESTACK_SIZE(st)) - #define CEA_ESTACK_OFFS(st) \ offsetof(struct cea_exception_stacks, st## _stack) =20 #define CEA_ESTACK_PAGES \ (sizeof(struct cea_exception_stacks) / PAGE_SIZE) =20 +extern unsigned long __this_cpu_ist_top_va(enum exception_stack_ordering s= tack); +extern unsigned long __this_cpu_ist_bottom_va(enum exception_stack_orderin= g stack); + #endif =20 #ifdef CONFIG_X86_32 @@ -144,10 +141,4 @@ static __always_inline struct entry_stack *cpu_entry_s= tack(int cpu) return &get_cpu_entry_area(cpu)->entry_stack_page.stack; } =20 -#define __this_cpu_ist_top_va(name) \ - CEA_ESTACK_TOP(__this_cpu_read(cea_exception_stacks), name) - -#define __this_cpu_ist_bottom_va(name) \ - CEA_ESTACK_BOT(__this_cpu_read(cea_exception_stacks), name) - #endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index fb50c1dd53ef..6fedd1b30e99 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2306,12 +2306,12 @@ static inline void setup_getcpu(int cpu) static inline void tss_setup_ist(struct tss_struct *tss) { /* Set up the per-CPU TSS IST stacks */ - tss->x86_tss.ist[IST_INDEX_DF] =3D __this_cpu_ist_top_va(DF); - tss->x86_tss.ist[IST_INDEX_NMI] =3D __this_cpu_ist_top_va(NMI); - tss->x86_tss.ist[IST_INDEX_DB] =3D __this_cpu_ist_top_va(DB); - tss->x86_tss.ist[IST_INDEX_MCE] =3D __this_cpu_ist_top_va(MCE); + tss->x86_tss.ist[IST_INDEX_DF] =3D __this_cpu_ist_top_va(ESTACK_DF); + tss->x86_tss.ist[IST_INDEX_NMI] =3D __this_cpu_ist_top_va(ESTACK_NMI); + tss->x86_tss.ist[IST_INDEX_DB] =3D __this_cpu_ist_top_va(ESTACK_DB); + tss->x86_tss.ist[IST_INDEX_MCE] =3D __this_cpu_ist_top_va(ESTACK_MCE); /* Only mapped when SEV-ES is active */ - tss->x86_tss.ist[IST_INDEX_VC] =3D __this_cpu_ist_top_va(VC); + tss->x86_tss.ist[IST_INDEX_VC] =3D __this_cpu_ist_top_va(ESTACK_VC); } #else /* CONFIG_X86_64 */ static inline void tss_setup_ist(struct tss_struct *tss) { } diff --git a/arch/x86/kernel/fred.c b/arch/x86/kernel/fred.c index 816187da3a47..06d944a3d051 100644 --- a/arch/x86/kernel/fred.c +++ b/arch/x86/kernel/fred.c @@ -87,7 +87,7 @@ void cpu_init_fred_rsps(void) FRED_STKLVL(X86_TRAP_DF, FRED_DF_STACK_LEVEL)); =20 /* The FRED equivalents to IST stacks... */ - wrmsrq(MSR_IA32_FRED_RSP1, __this_cpu_ist_top_va(DB)); - wrmsrq(MSR_IA32_FRED_RSP2, __this_cpu_ist_top_va(NMI)); - wrmsrq(MSR_IA32_FRED_RSP3, __this_cpu_ist_top_va(DF)); + wrmsrq(MSR_IA32_FRED_RSP1, __this_cpu_ist_top_va(ESTACK_DB)); + wrmsrq(MSR_IA32_FRED_RSP2, __this_cpu_ist_top_va(ESTACK_NMI)); + wrmsrq(MSR_IA32_FRED_RSP3, __this_cpu_ist_top_va(ESTACK_DF)); } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 36354b470590..5c9c5ebf5e73 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -954,7 +954,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_= off_ist(struct pt_regs *r =20 if (!get_stack_info_noinstr(stack, current, &info) || info.type =3D=3D ST= ACK_TYPE_ENTRY || info.type > STACK_TYPE_EXCEPTION_LAST) - sp =3D __this_cpu_ist_top_va(VC2); + sp =3D __this_cpu_ist_top_va(ESTACK_VC2); =20 sync: /* diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c index 575f863f3c75..eedaf103c8ad 100644 --- a/arch/x86/mm/cpu_entry_area.c +++ b/arch/x86/mm/cpu_entry_area.c @@ -18,6 +18,27 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_pa= ge, entry_stack_storage) static DEFINE_PER_CPU_PAGE_ALIGNED(struct exception_stacks, exception_stac= ks); DEFINE_PER_CPU(struct cea_exception_stacks*, cea_exception_stacks); =20 +/* + * FRED introduced new fields in the host-state area of the VMCS for + * stack levels 1->3 (HOST_IA32_FRED_RSP[123]), each respectively + * corresponding to per CPU stacks for #DB, NMI and #DF. KVM must + * populate these each time a vCPU is loaded onto a CPU. + * + * Called from entry code, so must be noinstr. + */ +noinstr unsigned long __this_cpu_ist_top_va(enum exception_stack_ordering = stack) +{ + unsigned long base =3D (unsigned long)&(__this_cpu_read(cea_exception_sta= cks)->DF_stack); + return base + EXCEPTION_STKSZ + stack * (EXCEPTION_STKSZ + PAGE_SIZE); +} +EXPORT_SYMBOL(__this_cpu_ist_top_va); + +noinstr unsigned long __this_cpu_ist_bottom_va(enum exception_stack_orderi= ng stack) +{ + unsigned long base =3D (unsigned long)&(__this_cpu_read(cea_exception_sta= cks)->DF_stack); + return base + stack * (EXCEPTION_STKSZ + PAGE_SIZE); +} + static DEFINE_PER_CPU_READ_MOSTLY(unsigned long, _cea_offset); =20 static __always_inline unsigned int cea_offset(unsigned int cpu) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 998bd807fc7b..1804eb86cc14 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -671,7 +671,7 @@ page_fault_oops(struct pt_regs *regs, unsigned long err= or_code, * and then double-fault, though, because we're likely to * break the console driver and lose most of the stack dump. */ - call_on_stack(__this_cpu_ist_top_va(DF) - sizeof(void*), + call_on_stack(__this_cpu_ist_top_va(ESTACK_DF) - sizeof(void*), handle_stack_overflow, ASM_CALL_ARG3, , [arg1] "r" (regs), [arg2] "r" (address), [arg3] "r" (&info)); --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 71FC51EE03B; Wed, 23 Jul 2025 17:54:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293257; cv=none; b=aRJzz6XdghH1oHoSVlJJX1yA1jFYDy/mcg5el+S/qReHW+xVS9tAMDbXj9UNk5O4IQ35Z5pH80OQPtaq0jrrmQVnl90i4Rzt6vlNS0xtjkwzP/TouJ1WvK+rCFYDbbBE1Vof5UsktsOH7CkY3LjJtdTD9xkXbnBaUSKi0igASm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293257; c=relaxed/simple; bh=aWYOhMVY+0LqjUojDgZy7kPOvnM+/mxfdv2uRv5JdiE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jMMLBFOTGoeQ5oQ5QfumqhRaEfwgEn9RnKX0KU+oRcUGq+pzBTUp+owgxqW+46dJK/rgLtdaU2yA/9NYYD7oh8WFme5gDDgmeB1lek6Yrh0bQ2OGJakpPhG7vEOAhMVEl6o7lqCUwMWC4jZmqZ7XTijLyqOcuigN1kDpknDrMyc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=LKmUdSBg; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="LKmUdSBg" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxt1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:50 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxt1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293230; bh=/EBeMK7ZSqzkS+JM5rRpzF6dDvDDWpq+RlSEiWex4Mo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LKmUdSBgHid/JUsdhkXnKlxY9oQLaj9h3hn7cRe9NzmCk1H2vroNbzA5vW16MofiT 0qzcLpnWXrPlQNGcUrlaP8+fBl6TdOfd/CiOtYvxIxAFs5DQxu2GwHd4cRXb0aupGR 24xYiQwHufIXK+gJU8Ue8DqFUk+OSOPOE7iWuM2amhrokutC3aeHFd0ksOPyZN+FDt GuLkmNG5G6lqRJPHO5uJtM5X/3Yw4WURdJTLFuQLecuFURtZWjWCknRI5aPHONvAHd FNOpc3yBPlgmKjCS5/dA4oGmQ2SPNIPoDOIcCmTBePrIFZT1Lk8ZXJwHz2W02Zgpzc BFsGWBKGDFttg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 05/23] KVM: VMX: Fix an indentation Date: Wed, 23 Jul 2025 10:53:23 -0700 Message-ID: <20250723175341.1284463-6-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix an indentation by replacing 8 spaces with a tab. While at it, add empty lines before and after for better readability. Signed-off-by: Xin Li (Intel) --- arch/x86/kvm/vmx/vmx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index c893ea2db9de..6e9799a80d25 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8555,7 +8555,9 @@ __init int vmx_hardware_setup(void) */ if (!static_cpu_has(X86_FEATURE_SELFSNOOP)) kvm_caps.supported_quirks &=3D ~KVM_X86_QUIRK_IGNORE_GUEST_PAT; - kvm_caps.inapplicable_quirks &=3D ~KVM_X86_QUIRK_IGNORE_GUEST_PAT; + + kvm_caps.inapplicable_quirks &=3D ~KVM_X86_QUIRK_IGNORE_GUEST_PAT; + return r; } =20 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 3D81D23BCFD; Wed, 23 Jul 2025 17:54:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293267; cv=none; b=rCphe+Gtej9LI9+248Ed+BBO9JOR2OYDUOXF4ncGRuA01BUR8cd8jekfx8hO8hxfTIx+VHAL4JL/WCcuO+XJRMuorJ4PMsahBhnhq6LVR2zra9eIkc2D6Kj5HoH1lyYUVhnvvC1W0SOIVfpiSOFUpVXSKuTTrd0dBlPOe3AItCg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293267; c=relaxed/simple; bh=JI71nXJ2edQctu5MF5v8+WKX4gDfIIMH+NHO7tmi8LA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RqakJMlqkVp3W9wFXqxqbaDxmvReXLR3+9/u5KF/lDEPQavy7qi8kBRUPh4yZ+tg+YxXsLmEINuLBW7hs8VB6eU7lznTskI7WG2tSPTyIJ6ykz51hjRZ1Z0TpFARYcPrPeL+TF2UCueIJrBL/szrbu05PlxObTaP9//43zyTzCc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=od9YVU5d; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="od9YVU5d" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxu1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:51 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxu1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293231; bh=WQTdarerVwdMqaoEv3y99aXLoiN/WOKgs/Dujepx7uE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=od9YVU5diEJviCL4vNOjh1ItS2tDyoPWC30+m4nM6GdLWBSyTMsnNH/+mKfM01iaU 1cZac+YEMfPDQMnQJVwko0zjaqeuL1/hepZbkrDI8BnG2volXyBXL1bi6TL3lXbnZX D2DsZP+HoW3zvVJYxJD8QHsUG6fflxsEWkUm3rFRLX+TD7IjeIX27Es+Mx8tJfpPK1 8MdOL9GKt8EhKwBDuiaiQUGAKQI/bZnX+dfSJoqqW+12/OblmGvqmALwrDlH8fr2Dn IfdM2ZFtwyIQ2minkvU1wSoMJiXzv2GI8YDI6UW7tROSYWMK5hkO8VVCEZGrGWcDtO m2bz/DsbXXGhQ== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 06/23] KVM: VMX: Initialize VMCS FRED fields Date: Wed, 23 Jul 2025 10:53:24 -0700 Message-ID: <20250723175341.1284463-7-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Initialize host VMCS FRED fields with host FRED MSRs' value and guest VMCS FRED fields to 0. FRED CPU state is managed in 9 new FRED MSRs: IA32_FRED_CONFIG, IA32_FRED_STKLVLS, IA32_FRED_RSP0, IA32_FRED_RSP1, IA32_FRED_RSP2, IA32_FRED_RSP3, IA32_FRED_SSP1, IA32_FRED_SSP2, IA32_FRED_SSP3, as well as a few existing CPU registers and MSRs: CR4.FRED, IA32_STAR, IA32_KERNEL_GS_BASE, IA32_PL0_SSP (also known as IA32_FRED_SSP0). CR4, IA32_KERNEL_GS_BASE and IA32_STAR are already well managed. Except IA32_FRED_RSP0 and IA32_FRED_SSP0, all other FRED CPU state MSRs have corresponding VMCS fields in both the host-state and guest-state areas. So KVM just needs to initialize them, and with proper VM entry/exit FRED controls, a FRED CPU will keep tracking host and guest FRED CPU state in VMCS automatically. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Change in v4: * Initialize host SSP[1-3] to 0s in vmx_set_constant_host_state() because Linux doesn't support kernel shadow stacks (Chao Gao). Change in v3: * Use structure kvm_host_values to keep host fred config & stack levels (Sean Christopherson). Changes in v2: * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() to decouple KVM's capability to virtualize a feature and host's enabling of a feature (Chao Gao). * Move guest FRED state init into __vmx_vcpu_reset() (Chao Gao). --- arch/x86/include/asm/vmx.h | 32 ++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 36 ++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.h | 3 +++ 3 files changed, 71 insertions(+) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 1879de94457d..6dd7e79b098c 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -290,12 +290,44 @@ enum vmcs_field { GUEST_BNDCFGS_HIGH =3D 0x00002813, GUEST_IA32_RTIT_CTL =3D 0x00002814, GUEST_IA32_RTIT_CTL_HIGH =3D 0x00002815, + GUEST_IA32_FRED_CONFIG =3D 0x0000281a, + GUEST_IA32_FRED_CONFIG_HIGH =3D 0x0000281b, + GUEST_IA32_FRED_RSP1 =3D 0x0000281c, + GUEST_IA32_FRED_RSP1_HIGH =3D 0x0000281d, + GUEST_IA32_FRED_RSP2 =3D 0x0000281e, + GUEST_IA32_FRED_RSP2_HIGH =3D 0x0000281f, + GUEST_IA32_FRED_RSP3 =3D 0x00002820, + GUEST_IA32_FRED_RSP3_HIGH =3D 0x00002821, + GUEST_IA32_FRED_STKLVLS =3D 0x00002822, + GUEST_IA32_FRED_STKLVLS_HIGH =3D 0x00002823, + GUEST_IA32_FRED_SSP1 =3D 0x00002824, + GUEST_IA32_FRED_SSP1_HIGH =3D 0x00002825, + GUEST_IA32_FRED_SSP2 =3D 0x00002826, + GUEST_IA32_FRED_SSP2_HIGH =3D 0x00002827, + GUEST_IA32_FRED_SSP3 =3D 0x00002828, + GUEST_IA32_FRED_SSP3_HIGH =3D 0x00002829, HOST_IA32_PAT =3D 0x00002c00, HOST_IA32_PAT_HIGH =3D 0x00002c01, HOST_IA32_EFER =3D 0x00002c02, HOST_IA32_EFER_HIGH =3D 0x00002c03, HOST_IA32_PERF_GLOBAL_CTRL =3D 0x00002c04, HOST_IA32_PERF_GLOBAL_CTRL_HIGH =3D 0x00002c05, + HOST_IA32_FRED_CONFIG =3D 0x00002c08, + HOST_IA32_FRED_CONFIG_HIGH =3D 0x00002c09, + HOST_IA32_FRED_RSP1 =3D 0x00002c0a, + HOST_IA32_FRED_RSP1_HIGH =3D 0x00002c0b, + HOST_IA32_FRED_RSP2 =3D 0x00002c0c, + HOST_IA32_FRED_RSP2_HIGH =3D 0x00002c0d, + HOST_IA32_FRED_RSP3 =3D 0x00002c0e, + HOST_IA32_FRED_RSP3_HIGH =3D 0x00002c0f, + HOST_IA32_FRED_STKLVLS =3D 0x00002c10, + HOST_IA32_FRED_STKLVLS_HIGH =3D 0x00002c11, + HOST_IA32_FRED_SSP1 =3D 0x00002c12, + HOST_IA32_FRED_SSP1_HIGH =3D 0x00002c13, + HOST_IA32_FRED_SSP2 =3D 0x00002c14, + HOST_IA32_FRED_SSP2_HIGH =3D 0x00002c15, + HOST_IA32_FRED_SSP3 =3D 0x00002c16, + HOST_IA32_FRED_SSP3_HIGH =3D 0x00002c17, PIN_BASED_VM_EXEC_CONTROL =3D 0x00004000, CPU_BASED_VM_EXEC_CONTROL =3D 0x00004002, EXCEPTION_BITMAP =3D 0x00004004, diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6e9799a80d25..58017bdf2ff0 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1447,6 +1447,15 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int c= pu) (unsigned long)(cpu_entry_stack(cpu) + 1)); } =20 + /* Per-CPU FRED MSRs */ + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { +#ifdef CONFIG_X86_64 + vmcs_write64(HOST_IA32_FRED_RSP1, __this_cpu_ist_top_va(ESTACK_DB)); + vmcs_write64(HOST_IA32_FRED_RSP2, __this_cpu_ist_top_va(ESTACK_NMI)); + vmcs_write64(HOST_IA32_FRED_RSP3, __this_cpu_ist_top_va(ESTACK_DF)); +#endif + } + vmx->loaded_vmcs->cpu =3D cpu; } } @@ -4256,6 +4265,17 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vm= x) */ vmcs_write16(HOST_DS_SELECTOR, 0); vmcs_write16(HOST_ES_SELECTOR, 0); + + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { + /* FRED CONFIG and STKLVLS are the same on all CPUs */ + vmcs_write64(HOST_IA32_FRED_CONFIG, kvm_host.fred_config); + vmcs_write64(HOST_IA32_FRED_STKLVLS, kvm_host.fred_stklvls); + + /* Linux doesn't support kernel shadow stacks, thus SSPs are 0s */ + vmcs_write64(HOST_IA32_FRED_SSP1, 0); + vmcs_write64(HOST_IA32_FRED_SSP2, 0); + vmcs_write64(HOST_IA32_FRED_SSP3, 0); + } #else vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ @@ -4758,6 +4778,17 @@ static void init_vmcs(struct vcpu_vmx *vmx) } =20 vmx_setup_uret_msrs(vmx); + + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { + vmcs_write64(GUEST_IA32_FRED_CONFIG, 0); + vmcs_write64(GUEST_IA32_FRED_RSP1, 0); + vmcs_write64(GUEST_IA32_FRED_RSP2, 0); + vmcs_write64(GUEST_IA32_FRED_RSP3, 0); + vmcs_write64(GUEST_IA32_FRED_STKLVLS, 0); + vmcs_write64(GUEST_IA32_FRED_SSP1, 0); + vmcs_write64(GUEST_IA32_FRED_SSP2, 0); + vmcs_write64(GUEST_IA32_FRED_SSP3, 0); + } } =20 static void __vmx_vcpu_reset(struct kvm_vcpu *vcpu) @@ -8558,6 +8589,11 @@ __init int vmx_hardware_setup(void) =20 kvm_caps.inapplicable_quirks &=3D ~KVM_X86_QUIRK_IGNORE_GUEST_PAT; =20 + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { + rdmsrl(MSR_IA32_FRED_CONFIG, kvm_host.fred_config); + rdmsrl(MSR_IA32_FRED_STKLVLS, kvm_host.fred_stklvls); + } + return r; } =20 diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index bcfd9b719ada..b0017a0f75fa 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -51,6 +51,9 @@ struct kvm_host_values { u64 xcr0; u64 xss; u64 arch_capabilities; + + u64 fred_config; + u64 fred_stklvls; }; =20 void kvm_spurious_fault(void); --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 67C0E239E76; Wed, 23 Jul 2025 17:54:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293266; cv=none; b=W3+GKBChJggZDZkPNoKIh7Lov4Y1X+KVuWUReU4t0Z0Rw0cvodr+GrCZ0jSb1+S5ObNqVZA1tBbx+oRd6T1Nx5L0XIlk5om6RY8mJxqup/oEtL/X/DNAUJUN62PkaCwrehN/3dWawBGwvBob2aUMYhTnNU4lxiz4LCdOs2Ot+Jw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293266; c=relaxed/simple; bh=vAqHRHWQXZ7ZM5XEy0qCffELvyIz8o5oWBCIEU4gYG4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M33LSyiXS98GlZzcxmNEBaOS2ZfmTJ7JuWlWPPDMAcJdmsSenjEdeMqlBFaM1/5qdEdrxuJrHlX7I8XfVXDf4hb8IFnIEQbOmNSvslChGe8ltZofXRpnDQZ4twOqMXHomqBOZUIVG51d6yJeI13eAW1Ij7fsOZr2zeIRZCCnaH0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=G7i/Eh4H; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="G7i/Eh4H" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxv1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:52 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxv1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293232; bh=WgbmsEpI3obK2UgbjujDyGoEWsCZP0mLrCSQll4/LVw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G7i/Eh4H3/l+y20QSINQig1hO++x1PbVlyHpWxpriJe9YsjbS0jKYytAA2ZRaNKRB tMGXhtfoiq4VRNPygiq1H3vILSxY7tbhDIsihZf5urcH2n3TuAb2EVcSO2ov5IFDWh /dpFc9xqjEB4p7KG+1YSi78sdLl2wglnaMGboTkfalQ+52iYPDRYr2SCIO8Rz9vXHQ 63a5YU63C+QOlvRViMB4I+JGt7ktaUlnfu41wVsw7E7ltBhLQHosVsDlnj/Q1vVUOR 6iSM5bzy+3t5hpJSFy6pLfpMkJev6Evcnxhs/Wnw1AOtEz1rSpVyGGk4+HJeu6iyE8 62hhD0ccSANsA== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 07/23] KVM: VMX: Set FRED MSR intercepts Date: Wed, 23 Jul 2025 10:53:25 -0700 Message-ID: <20250723175341.1284463-8-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li On a userspace MSR filter change, set FRED MSR intercepts. 8 FRED MSRs, i.e., MSR_IA32_FRED_RSP[123], MSR_IA32_FRED_STKLVLS, MSR_IA32_FRED_SSP[123] and MSR_IA32_FRED_CONFIG, are all safe to be passthrough, because they all have a pair of corresponding host and guest VMCS fields. Both MSR_IA32_FRED_RSP0 and MSR_IA32_FRED_SSP0 are dedicated for userspace event delivery only, IOW they are NOT used in any kernel event delivery and the execution of ERETS. Thus KVM can run safely with guest values in the two MSRs. As a result, save and restore of their guest values are deferred until vCPU context switch and their host values are restored upon host returning to userspace. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Changes in v5: * Skip execution of vmx_set_intercept_for_fred_msr() if FRED is not available or enabled (Sean). * Use 'set' instead of 'flag' as the variable name to indicate whether MSR interception should be enabled (Sean). * Add TB from Xuelian Guo. --- arch/x86/kvm/vmx/vmx.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 58017bdf2ff0..4cdc2a0c1465 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4096,6 +4096,37 @@ void pt_update_intercept_for_msr(struct kvm_vcpu *vc= pu) } } =20 +static void vmx_set_intercept_for_fred_msr(struct kvm_vcpu *vcpu) +{ + bool set =3D !guest_cpu_cap_has(vcpu, X86_FEATURE_FRED); + + if (!kvm_cpu_cap_has(X86_FEATURE_FRED)) + return; + + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP1, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP2, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP3, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_STKLVLS, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP1, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP2, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP3, MSR_TYPE_RW, set); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_CONFIG, MSR_TYPE_RW, set); + + /* + * IA32_FRED_RSP0 and IA32_PL0_SSP (a.k.a. IA32_FRED_SSP0) are only used + * for delivering events when running userspace, while KVM always runs in + * kernel mode (the CPL is always 0 after any VM exit), thus KVM can run + * safely with guest IA32_FRED_RSP0 and IA32_PL0_SSP. + * + * As a result, no need to intercept IA32_FRED_RSP0 and IA32_PL0_SSP. + * + * Note, save and restore of IA32_PL0_SSP belong to CET supervisor context + * management no matter whether FRED is enabled or not. So leave its + * state management to CET code. + */ + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP0, MSR_TYPE_RW, set); +} + void vmx_recalc_msr_intercepts(struct kvm_vcpu *vcpu) { if (!cpu_has_vmx_msr_bitmap()) @@ -4143,6 +4174,8 @@ void vmx_recalc_msr_intercepts(struct kvm_vcpu *vcpu) vmx_set_intercept_for_msr(vcpu, MSR_IA32_FLUSH_CMD, MSR_TYPE_W, !guest_cpu_cap_has(vcpu, X86_FEATURE_FLUSH_L1D)); =20 + vmx_set_intercept_for_fred_msr(vcpu); + /* * x2APIC and LBR MSR intercepts are modified on-demand and cannot be * filtered by userspace. --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 50787C2E0; Wed, 23 Jul 2025 17:54:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293257; cv=none; b=B6zGKagJZVw5jBcnr5DlC7Z5n3DI8nb2Sras7nB4XY7as8lGgUIt0yW8zFwgGOCc3GjQMF235lfRP50HQEhxenk6M7oR6Z1vY8e0K/GfGHGI3sJO58/nDYlFOinsR6eYm0iFYj+u6lGN2PNIkVVfCC7T0M3uhqRfmEMVwSP93Bg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293257; c=relaxed/simple; bh=bN6iMZJxULyWw8fM0bBE7z0gcBIpEuKUfw8wO8UJldY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tbzHaFRtQI8AILzV2xLlGqohXCbsdEkaFhDh9PcYZzr+S47IxNiFQQ11GpGrocQY9l8WVDK61LB7qceZwnohWYkG4GNjNDb9dX/XSCm69fHj8lriQinWONUxzmVx2VUbv4+JwZL3fn0SWoN0gnWMgo9sjxoZO45HqISIYc4r3lI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=gG3vQoKN; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="gG3vQoKN" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxw1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:52 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxw1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293233; bh=DKIu6ocFBDeeS216dlD/91z8SZPrsdeaVqLdFbg9kFY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gG3vQoKNXNW+sikXSNjgLOXOmPsiJVr2hOKuBgnfmuQDHB0jMx1LHze4QvL6W2Gi0 7uuwExpSHTPCP4NfTa9qp7zw4+/vkWHiBIGSi9pIz4WCg+suGQFb+TFbMA6p2sCoaP 9qIA8j8JyNICPY1A4946Ct0Lz7WsvSq8KUDDgH7U/BPxiKkUWt+oqLzQVaqa291+jF qJ04V6lIqsqw81msQ2m1LGyajeLY10fEvxxdY9NcDwl1RASTeKKz65UOrfpbQD5GQt TsrjfI7LEaG0cPjDSEiBR9ZdSB13NSTAeBnOmsHu6GY8Q4IHjeRsqSv8MESEw7W3la 0nYvV39u7StMg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 08/23] KVM: VMX: Save/restore guest FRED RSP0 Date: Wed, 23 Jul 2025 10:53:26 -0700 Message-ID: <20250723175341.1284463-9-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Save guest FRED RSP0 in vmx_prepare_switch_to_host() and restore it in vmx_prepare_switch_to_guest() because MSR_IA32_FRED_RSP0 is passed through to the guest, thus is volatile/unknown. Note, host FRED RSP0 is restored in arch_exit_to_user_mode_prepare(), regardless of whether it is modified in KVM. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Changes in v5: * Remove the cpu_feature_enabled() check when set/get guest MSR_IA32_FRED_RSP0, as guest_cpu_cap_has() should suffice (Sean). * Add a comment when synchronizing current MSR_IA32_FRED_RSP0 MSR to the kernel's local cache, because its handling is different from the MSR_KERNEL_GS_BASE handling (Sean). * Add TB from Xuelian Guo. Changes in v3: * KVM only needs to save/restore guest FRED RSP0 now as host FRED RSP0 is restored in arch_exit_to_user_mode_prepare() (Sean Christopherson). Changes in v2: * Don't use guest_cpuid_has() in vmx_prepare_switch_to_{host,guest}(), which are called from IRQ-disabled context (Chao Gao). * Reset msr_guest_fred_rsp0 in __vmx_vcpu_reset() (Chao Gao). --- arch/x86/kvm/vmx/vmx.c | 14 ++++++++++++++ arch/x86/kvm/vmx/vmx.h | 1 + 2 files changed, 15 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 4cdc2a0c1465..1e58d61dc021 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1293,6 +1293,10 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vc= pu) } =20 wrmsrq(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); + + if (guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) + wrmsrns(MSR_IA32_FRED_RSP0, vmx->msr_guest_fred_rsp0); + #else savesegment(fs, fs_sel); savesegment(gs, gs_sel); @@ -1337,6 +1341,16 @@ static void vmx_prepare_switch_to_host(struct vcpu_v= mx *vmx) invalidate_tss_limit(); #ifdef CONFIG_X86_64 wrmsrq(MSR_KERNEL_GS_BASE, vmx->vt.msr_host_kernel_gs_base); + + if (guest_cpu_cap_has(&vmx->vcpu, X86_FEATURE_FRED)) { + vmx->msr_guest_fred_rsp0 =3D read_msr(MSR_IA32_FRED_RSP0); + /* + * Synchronize the current value in hardware to the kernel's + * local cache. The desired host RSP0 will be set when the + * CPU exits to userspace (RSP0 is a per-task value). + */ + fred_sync_rsp0(vmx->msr_guest_fred_rsp0); + } #endif load_fixmap_gdt(raw_smp_processor_id()); vmx->vt.guest_state_loaded =3D false; diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 32829f98af2f..617cbec5c9b3 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -224,6 +224,7 @@ struct vcpu_vmx { bool guest_uret_msrs_loaded; #ifdef CONFIG_X86_64 u64 msr_guest_kernel_gs_base; + u64 msr_guest_fred_rsp0; #endif =20 u64 spec_ctrl; --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 D4CC32367CB; Wed, 23 Jul 2025 17:54:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293264; cv=none; b=Ke/g1Q5AwiXytz0xjOyCz1KIrXcVhdajyW0qGK/Aw4pvhI32p/wlct7zxaieeQFB5p3/0uhIRBv0QFPkKDPSObtLcSIwM4+nyoLIY4ebEo5pLJpP2JhWJjTZHsCTVw5uZLzzisgnFSEhAN1wDF1jXAVrsPwt0dBjnsjMIeOcsc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293264; c=relaxed/simple; bh=nx+dM1oAmgKShxYD34/rKstbrQTJJ02Iouc+nLSEfzk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WpmfBU0dQl8QXzwVTx+XiY+NOnzNFzXCIn34/MTmqNlg9D4P0iUUmtEHtLzLWAj39YD6gc5Lye0Uc6cY+A8haU1iW+aEiVauMCiVlPXmLt3mKMD752aU/oLavfujcKeWis7rZkNJ8Dyt0i5jkBrXDnbtjc/K4F7Hfr4fd99dcJk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=vqCMaCrf; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="vqCMaCrf" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrfxx1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:53 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrfxx1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293234; bh=i+ns0F2Ex+xQMQzvK4DIkApu0w0I3TMwsyhuQp7IOIY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vqCMaCrfuK3EFBb44a6prpg8hUMjSWnSTZOAmZS6HL+dFxlE42uMGgCrBbVJiGWiv qNJqZQ81Etg6DF4y51EGvp97F/8suMJKDu1hDoh2+5KpKHb6ut5nbpznXoenVXZgqa DKlEis3ly8fec0DXDBB/q3frl8dRGOtgKlHiQn6G7iagDUvr7lbKKFZYdcrOMYtnV+ ETkU3ASxbPwn9qMAXncgiB5qBo3Hy2PPXc/22wFVUAWateG5kWomd319cKX/o9Fup+ XhsmunL4UmzU3rh5MuidZio1RlK59vSRLodD1KJGEhMwXYt36COyZ73yRMY6yaSB6L /qQIcT52trHfw== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 09/23] KVM: VMX: Add host MSR read/write helpers to streamline preemption logic Date: Wed, 23 Jul 2025 10:53:27 -0700 Message-ID: <20250723175341.1284463-10-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Sean Christopherson Introduce helper functions for host MSR access to centralize and simplify preemption handling. This improves code readability and reduces duplicatio= n, laying the groundwork for a cleaner implementation of FRED RSP0 access functions in the following patch. Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) --- arch/x86/kvm/vmx/vmx.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 1e58d61dc021..53dce136e24b 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1358,22 +1358,35 @@ static void vmx_prepare_switch_to_host(struct vcpu_= vmx *vmx) } =20 #ifdef CONFIG_X86_64 -static u64 vmx_read_guest_kernel_gs_base(struct vcpu_vmx *vmx) +static u64 vmx_read_guest_host_msr(struct vcpu_vmx *vmx, u32 msr, u64 *cac= he) { preempt_disable(); if (vmx->vt.guest_state_loaded) - rdmsrq(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); + *cache =3D read_msr(msr); preempt_enable(); - return vmx->msr_guest_kernel_gs_base; + return *cache; } =20 -static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data) +static void vmx_write_guest_host_msr(struct vcpu_vmx *vmx, u32 msr, u64 da= ta, + u64 *cache) { preempt_disable(); if (vmx->vt.guest_state_loaded) - wrmsrq(MSR_KERNEL_GS_BASE, data); + wrmsrns(msr, data); preempt_enable(); - vmx->msr_guest_kernel_gs_base =3D data; + *cache =3D data; +} + +static u64 vmx_read_guest_kernel_gs_base(struct vcpu_vmx *vmx) +{ + return vmx_read_guest_host_msr(vmx, MSR_KERNEL_GS_BASE, + &vmx->msr_guest_kernel_gs_base); +} + +static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data) +{ + vmx_write_guest_host_msr(vmx, MSR_KERNEL_GS_BASE, data, + &vmx->msr_guest_kernel_gs_base); } #endif =20 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 A1C94247DE1; Wed, 23 Jul 2025 17:54:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293285; cv=none; b=kSvgWU+hSbgaFC46pB12w4+UqsnrzUiykUnEAIQHXcZdVGdZm8stkyo+oZtSox4lg61CKch6vrA3qoDSr+9LjFvVc+PlbsFg+UGuXF76twvFZlj/gJI/jFlNkQFB+zLzIlmEAjBgcRMU/lGsSpf/25IpRg4UY6Cg7xZZ6W4jS2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293285; c=relaxed/simple; bh=cAkS9B7sQ6Q4fMNM8C2U2UQnUsMw1QYVDgTlHwoKFkk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LlqWKUMg8RvIjp9M4pJXBGrBBL9dDpUAoJdRjetth8pEzfVXrN/m1FryxT1q1tVI4McdV+JPmUuHtkznev7hZQ4wvmqlLPX+vBqQ2dCN4K1HVxLp8uHY/UZKxYReAt+ZvzSHGn4V8yzcGfrHXZHou+DHzasWXAwZ4VbC1vmROSI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=IDVf7jQs; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="IDVf7jQs" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf001284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:54 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf001284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293235; bh=vAH6XFDgf2g1Xi+hKsymZubWXlznbyb6kDUSvmyxflg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IDVf7jQsRw8+nvq9T8f+ZkBjar7HTW4xRVCkc19n3Uin75xq+3DPoBt5TPBLR96+B nqb8OlnalZkDVPL711DfX8b9WWlhbIWfRaa6Vbg5Ac/VKJWGU9QuAiGCa0qlUibJeq pz9X5LHTsN8DP2aFpZd0r7gpiF0PgeCg9iAHxkeG4l6VSkxSvdWyI85eJsE5+aFgEh KxOejQY91wLbo9dn8Ut3XrNImfwXAwOUGk3BJC2U+lKsBqM8PkJlk7AuRfOPbQe/aL Tp3XnYUAza1bn5o6r+u85BcznmRtndU+503E+YiYj67kwB6yYsnFZ1kySiuGZz5Dk+ x6I0QmZ27Hu+Q== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 10/23] KVM: VMX: Add support for FRED context save/restore Date: Wed, 23 Jul 2025 10:53:28 -0700 Message-ID: <20250723175341.1284463-11-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Handle FRED MSR access requests, allowing FRED context to be set/get from both host and guest. During VM save/restore and live migration, FRED context needs to be saved/restored, which requires FRED MSRs to be accessed from userspace, e.g., Qemu. Note, handling of MSR_IA32_FRED_SSP0, i.e., MSR_IA32_PL0_SSP, is not added yet, which is done in the KVM CET patch set. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Use the newly added guest MSR read/write helpers (Sean). * Check the size of fred_msr_vmcs_fields[] using static_assert() (Sean). * Rewrite setting FRED MSRs to make it much easier to read (Sean). * Add TB from Xuelian Guo. Changes since v2: * Add a helper to convert FRED MSR index to VMCS field encoding to make the code more compact (Chao Gao). * Get rid of the "host_initiated" check because userspace has to set CPUID before MSRs (Chao Gao & Sean Christopherson). * Address a few cleanup comments (Sean Christopherson). Changes since v1: * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() (Chao Gao). * Fail host requested FRED MSRs access if KVM cannot virtualize FRED (Chao Gao). * Handle the case FRED MSRs are valid but KVM cannot virtualize FRED (Chao Gao). * Add sanity checks when writing to FRED MSRs. --- arch/x86/kvm/vmx/vmx.c | 45 ++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 53dce136e24b..fd995787b6cf 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1388,6 +1388,18 @@ static void vmx_write_guest_kernel_gs_base(struct vc= pu_vmx *vmx, u64 data) vmx_write_guest_host_msr(vmx, MSR_KERNEL_GS_BASE, data, &vmx->msr_guest_kernel_gs_base); } + +static u64 vmx_read_guest_fred_rsp0(struct vcpu_vmx *vmx) +{ + return vmx_read_guest_host_msr(vmx, MSR_IA32_FRED_RSP0, + &vmx->msr_guest_fred_rsp0); +} + +static void vmx_write_guest_fred_rsp0(struct vcpu_vmx *vmx, u64 data) +{ + vmx_write_guest_host_msr(vmx, MSR_IA32_FRED_RSP0, data, + &vmx->msr_guest_fred_rsp0); +} #endif =20 static void grow_ple_window(struct kvm_vcpu *vcpu) @@ -1989,6 +2001,27 @@ int vmx_get_feature_msr(u32 msr, u64 *data) } } =20 +#ifdef CONFIG_X86_64 +static const u32 fred_msr_vmcs_fields[] =3D { + GUEST_IA32_FRED_RSP1, + GUEST_IA32_FRED_RSP2, + GUEST_IA32_FRED_RSP3, + GUEST_IA32_FRED_STKLVLS, + GUEST_IA32_FRED_SSP1, + GUEST_IA32_FRED_SSP2, + GUEST_IA32_FRED_SSP3, + GUEST_IA32_FRED_CONFIG, +}; + +static_assert(MSR_IA32_FRED_CONFIG - MSR_IA32_FRED_RSP1 =3D=3D + ARRAY_SIZE(fred_msr_vmcs_fields) - 1); + +static u32 fred_msr_to_vmcs(u32 msr) +{ + return fred_msr_vmcs_fields[msr - MSR_IA32_FRED_RSP1]; +} +#endif + /* * Reads an msr value (of 'msr_info->index') into 'msr_info->data'. * Returns 0 on success, non-0 otherwise. @@ -2011,6 +2044,12 @@ int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_da= ta *msr_info) case MSR_KERNEL_GS_BASE: msr_info->data =3D vmx_read_guest_kernel_gs_base(vmx); break; + case MSR_IA32_FRED_RSP0: + msr_info->data =3D vmx_read_guest_fred_rsp0(vmx); + break; + case MSR_IA32_FRED_RSP1 ... MSR_IA32_FRED_CONFIG: + msr_info->data =3D vmcs_read64(fred_msr_to_vmcs(msr_info->index)); + break; #endif case MSR_EFER: return kvm_get_msr_common(vcpu, msr_info); @@ -2234,6 +2273,12 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_da= ta *msr_info) vmx_update_exception_bitmap(vcpu); } break; + case MSR_IA32_FRED_RSP0: + vmx_write_guest_fred_rsp0(vmx, data); + break; + case MSR_IA32_FRED_RSP1 ... MSR_IA32_FRED_CONFIG: + vmcs_write64(fred_msr_to_vmcs(msr_index), data); + break; #endif case MSR_IA32_SYSENTER_CS: if (is_guest_mode(vcpu)) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a1c49bc681c4..ae23a3470ecd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -323,6 +323,9 @@ static const u32 msrs_to_save_base[] =3D { MSR_STAR, #ifdef CONFIG_X86_64 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, + MSR_IA32_FRED_RSP0, MSR_IA32_FRED_RSP1, MSR_IA32_FRED_RSP2, + MSR_IA32_FRED_RSP3, MSR_IA32_FRED_STKLVLS, MSR_IA32_FRED_SSP1, + MSR_IA32_FRED_SSP2, MSR_IA32_FRED_SSP3, MSR_IA32_FRED_CONFIG, #endif MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, MSR_IA32_FEAT_CTL, MSR_IA32_BNDCFGS, MSR_TSC_AUX, @@ -1870,6 +1873,37 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 = index, u64 data, =20 data =3D (u32)data; break; + case MSR_IA32_FRED_STKLVLS: + if (!guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) + return 1; + break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_RSP3: + case MSR_IA32_FRED_SSP1 ... MSR_IA32_FRED_CONFIG: + u64 reserved_bits =3D 0; + + if (!guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) + return 1; + + if (is_noncanonical_msr_address(data, vcpu)) + return 1; + + switch (index) { + case MSR_IA32_FRED_CONFIG: + reserved_bits =3D BIT_ULL(11) | GENMASK_ULL(5, 4) | BIT_ULL(2); + break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_RSP3: + reserved_bits =3D GENMASK_ULL(5, 0); + break; + case MSR_IA32_FRED_SSP1 ... MSR_IA32_FRED_SSP3: + reserved_bits =3D GENMASK_ULL(2, 0); + break; + default: + WARN_ON_ONCE(1); + return 1; + } + if (data & reserved_bits) + return 1; + break; } =20 msr.data =3D data; @@ -1914,6 +1948,10 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, = u64 *data, !guest_cpu_cap_has(vcpu, X86_FEATURE_RDPID)) return 1; break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: + if (!guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) + return 1; + break; } =20 msr.index =3D index; @@ -7365,6 +7403,10 @@ static void kvm_probe_msr_to_save(u32 msr_index) if (!(kvm_get_arch_capabilities() & ARCH_CAP_TSX_CTRL_MSR)) return; break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: + if (!kvm_cpu_cap_has(X86_FEATURE_FRED)) + return; + break; default: break; } --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 AF05A24676B; Wed, 23 Jul 2025 17:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; cv=none; b=DSi+KqrLiZH9JNLxCWOkjc49CRPUfL27UWfpo034rVGW6Jc5Zf/M9MCUlKzHR3PNu0TkDh8zzSdqVprxpz66N5roZbEIzzIaM/YES9NqSiXigD8gOde0dPRtWrHoPBzOoNdxbzuHHmq2kTeXwEdZRVwGT72mXF/mDpDyhqpADl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; c=relaxed/simple; bh=W5o/OUKop7lpPijc+jePVwalOlSLc5kpKcUB/E+lIzA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GAOrr8kAWeBWzxY6es5OWs5KZXW7fy6RyLxaRNx+cr8JUkK85+Yoz+0JsPjHWXz+NCvKfdFDVgHitUOGMs8zp7SYHiGO8YSwY1Jzsb44Sz01bO8sidf5mLDLHqirHq+Q9xAeHak7YKa6XhWu9Ri7xvU6Hy2Sj6oWDd0u2jdN5ls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=k00OOPEB; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="k00OOPEB" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf011284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:55 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf011284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293236; bh=wxUSqO5rVkPGALqMssLFUw98Nnali0t1xB3+MDyXIlA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k00OOPEBKIz62NSnQcMA8sPN9ZWRgUnqEc6omi7PYHhb2qy4xmfXO59JBQA8OLnZA COnM52gQOu0iK9dhW98heR/mVAj1fmrSCCczgJ0+M4bEYVn+Yokxid6SSPwTL/EzKS HPuEFRamKRmOdyaWGXbnl61piRCxYd9/M1pdkGiTVbOH5vVuYNSW1Qme+tynJokuQx WBWTqxn/0ECFiKzyt80yuEaZrjMETRvWidN6QZ0Xe9iUmDRL18MEQ1JkxhwioLqe0L MaMNwxs5aC4qNsJLt2zrkqbztNNEcap5X4NSGvu/UtVt6Ee6QnbB1pbBKXDU9faqIL goe0TqjjPMPQg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 11/23] KVM: x86: Add a helper to detect if FRED is enabled for a vCPU Date: Wed, 23 Jul 2025 10:53:29 -0700 Message-ID: <20250723175341.1284463-12-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Signed-off-by: Xin Li [ Sean: removed the "kvm_" prefix from the function name ] Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. --- arch/x86/kvm/kvm_cache_regs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index 36a8786db291..31b446b6cbd7 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -204,6 +204,21 @@ static __always_inline bool kvm_is_cr4_bit_set(struct = kvm_vcpu *vcpu, return !!kvm_read_cr4_bits(vcpu, cr4_bit); } =20 +/* + * It's enough to check just CR4.FRED (X86_CR4_FRED) to tell if + * a vCPU is running with FRED enabled, because: + * 1) CR4.FRED can be set to 1 only _after_ IA32_EFER.LMA =3D 1. + * 2) To leave IA-32e mode, CR4.FRED must be cleared first. + */ +static inline bool is_fred_enabled(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_X86_64 + return kvm_is_cr4_bit_set(vcpu, X86_CR4_FRED); +#else + return false; +#endif +} + static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu) { if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3)) --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 9C56B2459F9; Wed, 23 Jul 2025 17:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; cv=none; b=Pmc6aRlfrNuHPSaLIQKEe9dKjH5NIvYNyKQV5Guf8qISXiRciUlA5GIcaGYtWqsTcqwItQAoypnzfF0r8ar6QlX/vP2+JagL1xN9jcybToEkSgrWoDIWYdgWHHIhtmFAC4vKk0rbXjj5LeNhF0Ko2wnH4MF/X/yf1PapzxbwgUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; c=relaxed/simple; bh=+eebK/oHMIrJr9kZQZLcJg2RmzC2eVGecME/s28802c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sCrIC/j/oFWxCtLZxHeiehf6JywfI4ROqqkLz5vFHitIMr6lsIGtKklHCMM/fwXXEmTK7Sff2FDDvGKVESUQg+9gl+ubQOUff+Y0bQBJdyVqQUmFibggOlwZnaAzXHtiLa+2rXLNaTA7TIub6zfLpDdrvBK7ZQvmlmi/nAeGj1U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=Gg0ZT3yT; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="Gg0ZT3yT" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf021284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:56 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf021284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293237; bh=FGN7iwJJ0bphcccpjmh5zMSV66q3BWgu6u0TKGJrFLY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gg0ZT3yTqvJGMjkG3PD8L8rFrvZ1AYTxgcxYf6wPlzk4TWt1QgixxOxMicopWml4A AEtI6kz5sRf43BpP5p8isicgaYFSyIP/kTLDLBAkiKB6H//7QkCCUfJpX02p6jdBkK e/PNvnYmamw5W0CBXOLVx3E1LidlTn0iiH77PHCEu+evIW2CZFzizJo+3rJLx4B7Fz +rB/SvU1ugOL8FfZn+XIBFY2EEDt0V5ySU1goG82GO8ApODHGRAmwHcSzBOLyaTw/a m/HEvPQWFI8DaXR8gh+JGCSgjwaoNpvkIc/3qfn/sFu/OEbdcnZrm6kMO2GcLwvRBp FrFhFjSzTRKnw== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 12/23] KVM: VMX: Virtualize FRED event_data Date: Wed, 23 Jul 2025 10:53:30 -0700 Message-ID: <20250723175341.1284463-13-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Set injected-event data when injecting a #PF, #DB, or #NM caused by extended feature disable using FRED event delivery, and save original-event data for being used as injected-event data. Unlike IDT using some extra CPU register as part of an event context, e.g., %cr2 for #PF, FRED saves a complete event context in its stack frame, e.g., FRED saves the faulting linear address of a #PF into the event data field defined in its stack frame. Thus a new VMX control field called injected-event data is added to provide the event data that will be pushed into a FRED stack frame for VM entries that inject an event using FRED event delivery. In addition, a new VM exit information field called original-event data is added to store the event data that would have saved into a FRED stack frame for VM exits that occur during FRED event delivery. After such a VM exit is handled to allow the original-event to be delivered, the data in the original-event data VMCS field needs to be set into the injected-event data VMCS field for the injection of the original event. Signed-off-by: Xin Li [ Sean: reworked event data injection for nested ] Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Change in v3: * Rework event data injection for nested (Chao Gao & Sean Christopherson). Changes in v2: * Document event data should be equal to CR2/DR6/IA32_XFD_ERR instead of using WARN_ON() (Chao Gao). * Zero event data if a #NM was not caused by extended feature disable (Chao Gao). --- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/asm/vmx.h | 4 ++++ arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/vmx/vmx.c | 22 ++++++++++++++++++---- arch/x86/kvm/x86.c | 16 +++++++++++++++- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index f19a76d3ca0e..0509b015513c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -756,6 +756,7 @@ struct kvm_queued_exception { u32 error_code; unsigned long payload; bool has_payload; + u64 event_data; }; =20 /* @@ -2200,7 +2201,7 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsig= ned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_c= ode); void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned lo= ng payload); void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code); + bool has_error_code, u32 error_code, u64 event_data); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fa= ult); void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 6dd7e79b098c..cf697b7c5d34 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -266,8 +266,12 @@ enum vmcs_field { PID_POINTER_TABLE_HIGH =3D 0x00002043, SECONDARY_VM_EXIT_CONTROLS =3D 0x00002044, SECONDARY_VM_EXIT_CONTROLS_HIGH =3D 0x00002045, + INJECTED_EVENT_DATA =3D 0x00002052, + INJECTED_EVENT_DATA_HIGH =3D 0x00002053, GUEST_PHYSICAL_ADDRESS =3D 0x00002400, GUEST_PHYSICAL_ADDRESS_HIGH =3D 0x00002401, + ORIGINAL_EVENT_DATA =3D 0x00002404, + ORIGINAL_EVENT_DATA_HIGH =3D 0x00002405, VMCS_LINK_POINTER =3D 0x00002800, VMCS_LINK_POINTER_HIGH =3D 0x00002801, GUEST_IA32_DEBUGCTL =3D 0x00002802, diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index d9931c6c4bc6..932a6525c014 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4144,7 +4144,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *= vcpu) =20 kvm_requeue_exception(vcpu, vector, exitintinfo & SVM_EXITINTINFO_VALID_ERR, - error_code); + error_code, 0); break; } case SVM_EXITINTINFO_TYPE_INTR: diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index fd995787b6cf..15fb205f2e73 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1862,6 +1862,9 @@ void vmx_inject_exception(struct kvm_vcpu *vcpu) =20 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); =20 + if (is_fred_enabled(vcpu)) + vmcs_write64(INJECTED_EVENT_DATA, ex->event_data); + vmx_clear_hlt(vcpu); } =20 @@ -7166,7 +7169,8 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx = *vmx) static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu, u32 idt_vectoring_info, int instr_len_field, - int error_code_field) + int error_code_field, + int event_data_field) { u8 vector; int type; @@ -7201,13 +7205,17 @@ static void __vmx_complete_interrupts(struct kvm_vc= pu *vcpu, fallthrough; case INTR_TYPE_HARD_EXCEPTION: { u32 error_code =3D 0; + u64 event_data =3D 0; =20 if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) error_code =3D vmcs_read32(error_code_field); + if (is_fred_enabled(vcpu)) + event_data =3D vmcs_read64(event_data_field); =20 kvm_requeue_exception(vcpu, vector, idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK, - error_code); + error_code, + event_data); break; } case INTR_TYPE_SOFT_INTR: @@ -7225,7 +7233,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *= vmx) { __vmx_complete_interrupts(&vmx->vcpu, vmx->idt_vectoring_info, VM_EXIT_INSTRUCTION_LEN, - IDT_VECTORING_ERROR_CODE); + IDT_VECTORING_ERROR_CODE, + ORIGINAL_EVENT_DATA); } =20 void vmx_cancel_injection(struct kvm_vcpu *vcpu) @@ -7233,7 +7242,8 @@ void vmx_cancel_injection(struct kvm_vcpu *vcpu) __vmx_complete_interrupts(vcpu, vmcs_read32(VM_ENTRY_INTR_INFO_FIELD), VM_ENTRY_INSTRUCTION_LEN, - VM_ENTRY_EXCEPTION_ERROR_CODE); + VM_ENTRY_EXCEPTION_ERROR_CODE, + INJECTED_EVENT_DATA); =20 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); } @@ -7382,6 +7392,10 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_v= cpu *vcpu, =20 vmx_disable_fb_clear(vmx); =20 + /* + * Note, even though FRED delivers the faulting linear address via the + * event data field on the stack, CR2 is still updated. + */ if (vcpu->arch.cr2 !=3D native_read_cr2()) native_write_cr2(vcpu->arch.cr2); =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ae23a3470ecd..0ba907d8071b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -796,9 +796,22 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vc= pu, * breakpoint), it is reserved and must be zero in DR6. */ vcpu->arch.dr6 &=3D ~BIT(12); + + /* + * FRED #DB event data matches DR6, but follows the polarity of + * VMX's pending debug exceptions, not DR6. + */ + ex->event_data =3D ex->payload & ~BIT(12); + break; + case NM_VECTOR: + ex->event_data =3D ex->payload; break; case PF_VECTOR: vcpu->arch.cr2 =3D ex->payload; + ex->event_data =3D ex->payload; + break; + default: + ex->event_data =3D 0; break; } =20 @@ -906,7 +919,7 @@ static void kvm_queue_exception_e_p(struct kvm_vcpu *vc= pu, unsigned nr, } =20 void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code) + bool has_error_code, u32 error_code, u64 event_data) { =20 /* @@ -931,6 +944,7 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsig= ned int nr, vcpu->arch.exception.error_code =3D error_code; vcpu->arch.exception.has_payload =3D false; vcpu->arch.exception.payload =3D 0; + vcpu->arch.exception.event_data =3D event_data; } EXPORT_SYMBOL_GPL(kvm_requeue_exception); =20 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 5D59824678A; Wed, 23 Jul 2025 17:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293286; cv=none; b=LKVv3yaPcmy5uqvBJoyhZkyn9OoT8q8IEroUtSi8YewrDwsM/RGjnFxrP0o59G99NJ7fFjHort42JRBGCVtO8KZIxXoLk/OkG+wCtt0X00qrGdJIkkIcnnNgMRpgICCq9m5GWPrvSG8wuDcZ9KF9DImTXDXGSe0WUoDhhbsYWCk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293286; c=relaxed/simple; bh=uMyIVw+5368zTKeJRFejCWyZyyjVWbPoVGfe3KqQ1a0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MV2SYivi65h5kUaegLymoHSAn+QnKgvztQ0xDkBdVHF6YpkHvUqvSKmqPoaXfrks3k708ePK8zL1+ScNhCg+gggk+iUrHCIbj4u3bD48QRjVCrrYi+8Kuju80It2peL4XzorZRNBuLuGQYoQXjrY7v+eFh7ED3Lv58UlsXmO3s4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=uAQwAjz+; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="uAQwAjz+" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf031284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:57 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf031284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293238; bh=SMEiDwsRemHvExam1VO7iukkYCbw+RANEnDjg4dYLI0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uAQwAjz+wge4/BWnySbeKxZgmkGxYhO4snB+sTNyW4qteobWTvuI9/o2rSGNq85kU X+apihuLJmJHVukwXaLP9a2z/wuhQoiVvzj8MqiBdywSLgm9I2Ltz06QqX+dG8xFUi q+oFCh0ztdmXFqiMUdefNZRZ9MOKen+bRdgw7NGRHRiGrUbWNTdAgdk5aSNsnOMlpH oS/wdTw2PbWkStyDp/txiVTmeCznrPBtdZGopBBuxhnAU4Rk4J/mlo4jha5MF3MlOz yHMM9VOEIo47HoCfH/w6Dp9JIrzF/PYBQwV42PGdJfz0hEVHeCpKqaEe8XiSTMcAF1 gIPBQ0Gs4/uyA== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 13/23] KVM: VMX: Virtualize FRED nested exception tracking Date: Wed, 23 Jul 2025 10:53:31 -0700 Message-ID: <20250723175341.1284463-14-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Set the VMX nested exception bit in VM-entry interruption information field when injecting a nested exception using FRED event delivery to ensure: 1) A nested exception is injected on a correct stack level. 2) The nested bit defined in FRED stack frame is set. The event stack level used by FRED event delivery depends on whether the event was a nested exception encountered during delivery of an earlier event, because a nested exception is "regarded" as happening on ring 0. E.g., when #PF is configured to use stack level 1 in IA32_FRED_STKLVLS MSR: - nested #PF will be delivered on the stack pointed by IA32_FRED_RSP1 MSR when encountered in ring 3 and ring 0. - normal #PF will be delivered on the stack pointed by IA32_FRED_RSP0 MSR when encountered in ring 3. The VMX nested-exception support ensures a correct event stack level is chosen when a VM entry injects a nested exception. Signed-off-by: Xin Li [ Sean: reworked kvm_requeue_exception() to simply the code changes ] Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Change in v4: * Move the check is_fred_enable() from kvm_multiple_exception() to vmx_inject_exception() thus avoid bleeding FRED details into kvm_multiple_exception() (Chao Gao). Change in v3: * Rework kvm_requeue_exception() to simply the code changes (Sean Christopherson). Change in v2: * Set the nested flag when there is an original interrupt (Chao Gao). --- arch/x86/include/asm/kvm_host.h | 4 +++- arch/x86/include/asm/vmx.h | 5 ++++- arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/vmx/vmx.c | 6 +++++- arch/x86/kvm/x86.c | 13 ++++++++++++- arch/x86/kvm/x86.h | 1 + 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 0509b015513c..04fa24ed1594 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -756,6 +756,7 @@ struct kvm_queued_exception { u32 error_code; unsigned long payload; bool has_payload; + bool nested; u64 event_data; }; =20 @@ -2201,7 +2202,8 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsig= ned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_c= ode); void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned lo= ng payload); void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code, u64 event_data); + bool has_error_code, u32 error_code, bool nested, + u64 event_data); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fa= ult); void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index cf697b7c5d34..15e04a486dd8 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -137,6 +137,7 @@ #define VMX_BASIC_DUAL_MONITOR_TREATMENT BIT_ULL(49) #define VMX_BASIC_INOUT BIT_ULL(54) #define VMX_BASIC_TRUE_CTLS BIT_ULL(55) +#define VMX_BASIC_NESTED_EXCEPTION BIT_ULL(58) =20 static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic) { @@ -433,13 +434,15 @@ enum vmcs_field { #define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */ #define INTR_INFO_DELIVER_CODE_MASK 0x800 /* 11 */ #define INTR_INFO_UNBLOCK_NMI 0x1000 /* 12 */ +#define INTR_INFO_NESTED_EXCEPTION_MASK 0x2000 /* 13 */ #define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ -#define INTR_INFO_RESVD_BITS_MASK 0x7ffff000 +#define INTR_INFO_RESVD_BITS_MASK 0x7fffd000 =20 #define VECTORING_INFO_VECTOR_MASK INTR_INFO_VECTOR_MASK #define VECTORING_INFO_TYPE_MASK INTR_INFO_INTR_TYPE_MASK #define VECTORING_INFO_DELIVER_CODE_MASK INTR_INFO_DELIVER_CODE_MASK #define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK +#define VECTORING_INFO_NESTED_EXCEPTION_MASK INTR_INFO_NESTED_EXCEPTION_MA= SK =20 #define INTR_TYPE_EXT_INTR (EVENT_TYPE_EXTINT << 8) /* external interrupt= */ #define INTR_TYPE_RESERVED (EVENT_TYPE_RESERVED << 8) /* reserved */ diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 932a6525c014..4490be40a7ee 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4144,7 +4144,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *= vcpu) =20 kvm_requeue_exception(vcpu, vector, exitintinfo & SVM_EXITINTINFO_VALID_ERR, - error_code, 0); + error_code, false, 0); break; } case SVM_EXITINTINFO_TYPE_INTR: diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 15fb205f2e73..0ca01980295e 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1857,8 +1857,11 @@ void vmx_inject_exception(struct kvm_vcpu *vcpu) vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, vmx->vcpu.arch.event_exit_inst_len); intr_info |=3D INTR_TYPE_SOFT_EXCEPTION; - } else + } else { intr_info |=3D INTR_TYPE_HARD_EXCEPTION; + if (ex->nested && is_fred_enabled(vcpu)) + intr_info |=3D INTR_INFO_NESTED_EXCEPTION_MASK; + } =20 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); =20 @@ -7215,6 +7218,7 @@ static void __vmx_complete_interrupts(struct kvm_vcpu= *vcpu, kvm_requeue_exception(vcpu, vector, idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK, error_code, + idt_vectoring_info & VECTORING_INFO_NESTED_EXCEPTION_MASK, event_data); break; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0ba907d8071b..1632ece82a85 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -860,6 +860,10 @@ static void kvm_multiple_exception(struct kvm_vcpu *vc= pu, unsigned int nr, vcpu->arch.exception.pending =3D true; vcpu->arch.exception.injected =3D false; =20 + vcpu->arch.exception.nested =3D vcpu->arch.exception.nested || + vcpu->arch.nmi_injected || + vcpu->arch.interrupt.injected; + vcpu->arch.exception.has_error_code =3D has_error; vcpu->arch.exception.vector =3D nr; vcpu->arch.exception.error_code =3D error_code; @@ -889,8 +893,13 @@ static void kvm_multiple_exception(struct kvm_vcpu *vc= pu, unsigned int nr, vcpu->arch.exception.injected =3D false; vcpu->arch.exception.pending =3D false; =20 + /* #DF is NOT a nested event, per its definition. */ + vcpu->arch.exception.nested =3D false; + kvm_queue_exception_e(vcpu, DF_VECTOR, 0); } else { + vcpu->arch.exception.nested =3D true; + /* replace previous exception with a new one in a hope that instruction re-execution will regenerate lost exception */ @@ -919,7 +928,8 @@ static void kvm_queue_exception_e_p(struct kvm_vcpu *vc= pu, unsigned nr, } =20 void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code, u64 event_data) + bool has_error_code, u32 error_code, bool nested, + u64 event_data) { =20 /* @@ -944,6 +954,7 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsig= ned int nr, vcpu->arch.exception.error_code =3D error_code; vcpu->arch.exception.has_payload =3D false; vcpu->arch.exception.payload =3D 0; + vcpu->arch.exception.nested =3D nested; vcpu->arch.exception.event_data =3D event_data; } EXPORT_SYMBOL_GPL(kvm_requeue_exception); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index b0017a0f75fa..a573f6079ba7 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -187,6 +187,7 @@ static inline void kvm_clear_exception_queue(struct kvm= _vcpu *vcpu) { vcpu->arch.exception.pending =3D false; vcpu->arch.exception.injected =3D false; + vcpu->arch.exception.nested =3D false; vcpu->arch.exception_vmexit.pending =3D false; } =20 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 04149223716; Wed, 23 Jul 2025 17:54:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293280; cv=none; b=rAC/a0TWXFNlx75T4eSAKuMK/71gIeo135x2u77ktrxzodeD8L65ktSPJ6/3DXAPB9xO1ngaGzK4JVXanmycLeDP34sOpRA+L7mSsH76xw9G8pRuiT5cmXfMUliP8bNE2IDvFqgHbmEdSwx+olOoADD5Psxn6Wnzz7/L7CMDKp0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293280; c=relaxed/simple; bh=OtaJdQ6YU5sudx4rdyWNuFiwthEfXyw757uGSlQhjik=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lPsK/Dq0Todk/0H5+hIqYOw7wwb4TEsjBQMjDM3hQRp8SVNC0LpKllpubery9o4txLgW0JdHr781sKycXS8qhA9aFHQooEjjH/4L76Ozz1+ILWg66GplemYbuHAQfk+VP2ZbputeSY053Uw8h6hXorYi3l6mJ+ipUe2iej9AM38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=DWKghVmB; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="DWKghVmB" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf041284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:58 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf041284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293239; bh=PRDEVgITCbLDQ0vEC4YA8ZSuHVrrepoHdheuw6N1oO4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DWKghVmBzOls6+AmwBbwFdeUqVjq/h+q5/qWoxf5Xoeojf2vJ+wWNNJHIIkhVLR3V l8NIXaZ1DD4zxulVA7lj7zW1dAKJ1tacX/mpECPzjpoDix9zG3cToFWxb+BtpL/MIn wl/FUtCkMjpgK6+2KVdyPYqykAONkd/6pmKG+MGk6Yh4CUQHkDpu/Ly/pNK6QVeehF FZlmE0PfAT5QNfk9jwXfLhbvs0AytUz3Wk0DIUrlfcpjDCz6Vj2cle+SiLTM8x3gwl aqbsx4MP/snmzbjYRDwT1jGzUiUsYqtN/cvOBmhAFhtkhPTYGxiRMRJRR/d9AmJd1T 5mIv5AwXh3ozw== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 14/23] Documentation: kvm: Fix a section number typo Date: Wed, 23 Jul 2025 10:53:32 -0700 Message-ID: <20250723175341.1284463-15-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The previous section is 7.41, thus this should be 7.42. Signed-off-by: Xin Li (Intel) --- Documentation/virt/kvm/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index f8cb0b18b6be..b3a54ac0d653 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8622,7 +8622,7 @@ ENOSYS for the others. When enabled, KVM will exit to userspace with KVM_EXIT_SYSTEM_EVENT of type KVM_SYSTEM_EVENT_SUSPEND to process the guest suspend request. =20 -7.37 KVM_CAP_ARM_WRITABLE_IMP_ID_REGS +7.42 KVM_CAP_ARM_WRITABLE_IMP_ID_REGS ------------------------------------- =20 :Architectures: arm64 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 74D902459DC; Wed, 23 Jul 2025 17:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; cv=none; b=En/VFtcooWsdHJgUFbBn6E1KBGU5aS0swRkEcNyHGr/n7jpFBCAikom3klx2KK53RiH9t51DHLx45mPr8UUZevsijJvJOIP35H7WuqgmCl7KIVkJxNhJBXffDiPaL4G+Ahw76VTYKN8nnYIhHd3iLmiWZqT79uius2Y0HWvkFgQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; c=relaxed/simple; bh=IV5pBjyRildLfoLnMALqZxILjyyywpvRP6k4ECEfhCA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T1pvSmGrLxqHtCAsRROtG6cjZywmgGpNW/4eCxJZGXG2K/EeWfJdgqvzx2DtE/bwTw0/l0ajInNWblCMM67fsWAHKBWdMDxdrT0CzDcG9SNb8cJnAMTX2G7T59FzPHDKnaJ7atwXTuJ6BEKEUOf1phCLHz/J2SedF+zcK4wcR+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=s3FkDDZy; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="s3FkDDZy" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf051284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:53:59 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf051284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293240; bh=uFGj8W35wSQJhE7ybCY8aC7SSmWCIrianrj8WFoDNCk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=s3FkDDZydY4oKATSNgy21DbL5FXblqj3HG2mgAC6zRvItKO8oJXf1ESCwbfuSWqWp dzR6IDNHtZN4iHqJRW2NDPh1UsC5GJKNQ4+Xo0SBtTfbYqYA5HW6n2fWricvpnuKqD APNiPgIhn5iSX6fqx3208Di0g88kMddXJw9nj2yy1f4/nb+9qky19WVgEqRnoKzLla K+m2mrfnSxD8oBSTfRW3c32eOfoGDkxi8BzQ7VOoQ8Eq9tDuUv6zxeZXzq2XxWqyif tEYvMiHHHq348xec0rwwjYSkC9jV+aPMczmrxWNwJnAERZbc8+R3M59hurMoxRtxO+ 7FHJyDpTSBNjg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 15/23] KVM: x86: Save/restore the nested flag of an exception Date: Wed, 23 Jul 2025 10:53:33 -0700 Message-ID: <20250723175341.1284463-16-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Save/restore the nested flag of an exception during VM save/restore and live migration to ensure a correct event stack level is chosen when a nested exception is injected through FRED event delivery. Signed-off-by: Xin Li (Intel) Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Change in v4: * Add live migration support for exception nested flag (Chao Gao). --- Documentation/virt/kvm/api.rst | 19 +++++++++++++++++++ arch/x86/include/asm/kvm_host.h | 1 + arch/x86/include/uapi/asm/kvm.h | 4 +++- arch/x86/kvm/x86.c | 19 ++++++++++++++++++- include/uapi/linux/kvm.h | 1 + 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index b3a54ac0d653..756cd19a76e4 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1184,6 +1184,10 @@ The following bits are defined in the flags field: fields contain a valid state. This bit will be set whenever KVM_CAP_EXCEPTION_PAYLOAD is enabled. =20 +- KVM_VCPUEVENT_VALID_NESTED_FLAG may be set to inform that the + exception is a nested exception. This bit will be set whenever + KVM_CAP_EXCEPTION_NESTED_FLAG is enabled. + - KVM_VCPUEVENT_VALID_TRIPLE_FAULT may be set to signal that the triple_fault_pending field contains a valid state. This bit will be set whenever KVM_CAP_X86_TRIPLE_FAULT_EVENT is enabled. @@ -1283,6 +1287,10 @@ can be set in the flags field to signal that the exception_has_payload, exception_payload, and exception.pending fields contain a valid state and shall be written into the VCPU. =20 +If KVM_CAP_EXCEPTION_NESTED_FLAG is enabled, KVM_VCPUEVENT_VALID_NESTED_FL= AG +can be set in the flags field to inform that the exception is a nested +exception and exception_is_nested shall be written into the VCPU. + If KVM_CAP_X86_TRIPLE_FAULT_EVENT is enabled, KVM_VCPUEVENT_VALID_TRIPLE_F= AULT can be set in flags field to signal that the triple_fault field contains a valid state and shall be written into the VCPU. @@ -8651,6 +8659,17 @@ given VM. When this capability is enabled, KVM resets the VCPU when setting MP_STATE_INIT_RECEIVED through IOCTL. The original MP_STATE is preserved. =20 +7.44 KVM_CAP_EXCEPTION_NESTED_FLAG +---------------------------------- + +:Architectures: x86 +:Parameters: args[0] whether feature should be enabled or not + +With this capability enabled, an exception is save/restored with the +additional information of whether it was nested or not. FRED event +delivery uses this information to ensure a correct event stack level +is chosen when a VM entry injects a nested exception. + 8. Other capabilities. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 04fa24ed1594..8e8d4ba77afc 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1465,6 +1465,7 @@ struct kvm_arch { bool has_mapped_host_mmio; bool guest_can_read_msr_platform_info; bool exception_payload_enabled; + bool exception_nested_flag_enabled; =20 bool triple_fault_event; =20 diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index e019111e2150..cc566215837e 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -326,6 +326,7 @@ struct kvm_reinject_control { #define KVM_VCPUEVENT_VALID_SMM 0x00000008 #define KVM_VCPUEVENT_VALID_PAYLOAD 0x00000010 #define KVM_VCPUEVENT_VALID_TRIPLE_FAULT 0x00000020 +#define KVM_VCPUEVENT_VALID_NESTED_FLAG 0x00000040 =20 /* Interrupt shadow states */ #define KVM_X86_SHADOW_INT_MOV_SS 0x01 @@ -363,7 +364,8 @@ struct kvm_vcpu_events { struct { __u8 pending; } triple_fault; - __u8 reserved[26]; + __u8 reserved[25]; + __u8 exception_is_nested; __u8 exception_has_payload; __u64 exception_payload; }; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1632ece82a85..daaddd59d97d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4753,6 +4753,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, lon= g ext) case KVM_CAP_GET_MSR_FEATURES: case KVM_CAP_MSR_PLATFORM_INFO: case KVM_CAP_EXCEPTION_PAYLOAD: + case KVM_CAP_EXCEPTION_NESTED_FLAG: case KVM_CAP_X86_TRIPLE_FAULT_EVENT: case KVM_CAP_SET_GUEST_DEBUG: case KVM_CAP_LAST_CPU: @@ -5497,6 +5498,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct= kvm_vcpu *vcpu, events->exception.error_code =3D ex->error_code; events->exception_has_payload =3D ex->has_payload; events->exception_payload =3D ex->payload; + events->exception_is_nested =3D ex->nested; =20 events->interrupt.injected =3D vcpu->arch.interrupt.injected && !vcpu->arch.interrupt.soft; @@ -5522,6 +5524,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct= kvm_vcpu *vcpu, | KVM_VCPUEVENT_VALID_SMM); if (vcpu->kvm->arch.exception_payload_enabled) events->flags |=3D KVM_VCPUEVENT_VALID_PAYLOAD; + if (vcpu->kvm->arch.exception_nested_flag_enabled) + events->flags |=3D KVM_VCPUEVENT_VALID_NESTED_FLAG; if (vcpu->kvm->arch.triple_fault_event) { events->triple_fault.pending =3D kvm_test_request(KVM_REQ_TRIPLE_FAULT, = vcpu); events->flags |=3D KVM_VCPUEVENT_VALID_TRIPLE_FAULT; @@ -5536,7 +5540,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct = kvm_vcpu *vcpu, | KVM_VCPUEVENT_VALID_SHADOW | KVM_VCPUEVENT_VALID_SMM | KVM_VCPUEVENT_VALID_PAYLOAD - | KVM_VCPUEVENT_VALID_TRIPLE_FAULT)) + | KVM_VCPUEVENT_VALID_TRIPLE_FAULT + | KVM_VCPUEVENT_VALID_NESTED_FLAG)) return -EINVAL; =20 if (events->flags & KVM_VCPUEVENT_VALID_PAYLOAD) { @@ -5551,6 +5556,13 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct= kvm_vcpu *vcpu, events->exception_has_payload =3D 0; } =20 + if (events->flags & KVM_VCPUEVENT_VALID_NESTED_FLAG) { + if (!vcpu->kvm->arch.exception_nested_flag_enabled) + return -EINVAL; + } else { + events->exception_is_nested =3D 0; + } + if ((events->exception.injected || events->exception.pending) && (events->exception.nr > 31 || events->exception.nr =3D=3D NMI_VECTOR)) return -EINVAL; @@ -5576,6 +5588,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct = kvm_vcpu *vcpu, vcpu->arch.exception.error_code =3D events->exception.error_code; vcpu->arch.exception.has_payload =3D events->exception_has_payload; vcpu->arch.exception.payload =3D events->exception_payload; + vcpu->arch.exception.nested =3D events->exception_is_nested; =20 vcpu->arch.interrupt.injected =3D events->interrupt.injected; vcpu->arch.interrupt.nr =3D events->interrupt.nr; @@ -6561,6 +6574,10 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, kvm->arch.exception_payload_enabled =3D cap->args[0]; r =3D 0; break; + case KVM_CAP_EXCEPTION_NESTED_FLAG: + kvm->arch.exception_nested_flag_enabled =3D cap->args[0]; + r =3D 0; + break; case KVM_CAP_X86_TRIPLE_FAULT_EVENT: kvm->arch.triple_fault_event =3D cap->args[0]; r =3D 0; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index aeb2ca10b190..b2f2f5bcf712 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -961,6 +961,7 @@ struct kvm_enable_cap { #define KVM_CAP_ARM_EL2 240 #define KVM_CAP_ARM_EL2_E2H0 241 #define KVM_CAP_RISCV_MP_STATE_RESET 242 +#define KVM_CAP_EXCEPTION_NESTED_FLAG 243 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 0AEAE22CBE6; Wed, 23 Jul 2025 17:54:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293261; cv=none; b=dhA46eS/DDMP1t3iJikuamuqi29kSnBSGsGkG1JIx6JwmIcjsV9zHFjZVdDsiROqmcTIDqxhwd57po5ASMjJKEPtvZsgLGhH2cCwbNKNRgA1o2ZiGGFXPZjS+5fsAEFVEFTMve5BJL+f1PGPBgYtpCxCo2xjDLs6sqsL2++ek0U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293261; c=relaxed/simple; bh=2TyfVb5NWoLz0GzMyEcofpBwEtaePovaJCJXs/9B8uY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e5HrHBj7Vz2WkqOtmlEcmIogd7z7NA3OFYiMdUMEcPuc9w9HwTV7LkXr8W+/5blK/HM7yqczcnvQ9ZNdlVUkiaLCQjXw3DP2VE6r7W87t3gzVpeogi4J8Tn4mPo3vYmA+HmEeSYb6Z764fzlwYiM/NwrWS8hrFy5NioEe9ydDcM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=UrZaDzKH; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="UrZaDzKH" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf061284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:00 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf061284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293241; bh=62h60ISMF6N+mZatzpXWdS4PjakRmhWqSbMYln3oONs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UrZaDzKHrr+whGR2XJxmJ1KhYCZ/TvEirK6FwpD7XfZxtAGA3DTS1vZ9fUxWGbjI4 BAzLn2FAtxcjT4MuVvuYTd3sjFC39pPe4DmoPhV18v6cjgB4xMS1DBa+RvePTS1Hyg f5VIllUBi6Db5giaUrYuJA8uO5QqBWB7h20qTPnsaksDbFxsomqOuqkhH/m2KmTIh4 n+qf7fs/xqWnFNB/m0GUZVx88TGqDwTZIN+0aiw/AzqHTG4h7oaTz1LSPSHJqRclQT qYKBhEf9X9GAooPsJ7Em7DCOIl4VJUlLjkwJo+/zj1wRqWj5CgZoCSU3uWnkjzLjxA Ao7lCEKDKALpA== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 16/23] KVM: x86: Mark CR4.FRED as not reserved Date: Wed, 23 Jul 2025 10:53:34 -0700 Message-ID: <20250723175341.1284463-17-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when guest cpu cap has FRED, i.e., 1) All of FRED KVM support is in place. 2) Guest enumerates FRED. Otherwise it is still a reserved bit. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Change in v4: * Rebase on top of "guest_cpu_cap". Change in v3: * Don't allow CR4.FRED=3D1 before all of FRED KVM support is in place (Sean Christopherson). --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/x86.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 8e8d4ba77afc..0805ad9ccf97 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -142,7 +142,7 @@ | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \ | X86_CR4_SMAP | X86_CR4_PKE | X86_CR4_UMIP \ - | X86_CR4_LAM_SUP)) + | X86_CR4_LAM_SUP | X86_CR4_FRED)) =20 #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) =20 diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index a573f6079ba7..aff93c5b2484 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -672,6 +672,8 @@ static inline bool __kvm_is_valid_cr4(struct kvm_vcpu *= vcpu, unsigned long cr4) __reserved_bits |=3D X86_CR4_PCIDE; \ if (!__cpu_has(__c, X86_FEATURE_LAM)) \ __reserved_bits |=3D X86_CR4_LAM_SUP; \ + if (!__cpu_has(__c, X86_FEATURE_FRED)) \ + __reserved_bits |=3D X86_CR4_FRED; \ __reserved_bits; \ }) =20 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 DC9B6224B07; Wed, 23 Jul 2025 17:54:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293281; cv=none; b=OVLYahInWzCMXo5bC24tZMtayTHbLB6OeY6NSV/GI/EurQLjGGOLY5Um4sP26rWZ3x+yyaRpo475hHfK1bmwL4oTrD9yvyUBfuW18xe2rSpjyQxIrtwshpYlsrMjtsbwOKOi49L8IKXkI1VgibkqjCTMjE6OMZ7OM028/85YUUY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293281; c=relaxed/simple; bh=j21WdZ+wd9RRAfQbWDIOAbgnrsMuOoAXcfqQaZ4HBso=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oCKBUzW9/Uv+YiG9NgALjnH6O38lINFnPwulRi7JhCYiXTLaltTy5ZlOPdPNeVifHICirsJVvxDj9koCYUQ9l//ENcD+UlYudYzo9PBvSd69tifXQhB6dKqvf0lvLEX4SBOl8GF/G3xnHUB5LVWAkS1hMgS3jvuH/gM4r11aCvM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=mUTjzNyC; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="mUTjzNyC" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf071284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:01 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf071284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293242; bh=9sTk7GlM4pzW7YhSsUUJXP4SlDFbJfiCcxa4ExZ1RRI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mUTjzNyCZN1hd65haVrsxkh3LldR8mOeRfbRQvl84kfF0MBlRb1wD1SSQT5Lsx1+W GcrmCv0tAWK3UE/kx7h9biuT8lI4/nY+308ugxtInVz1CO0BdUUuzKWlT+vxLjDbna JSnKa7J/0Gq4zkyq+v9weP46y6BWoGLA2PaTsyDLebqjMMZ2iVLQKd0hznrBe4s0QT L5OJA98fPYUfez226nhyljp9yOaSMTff4vDsdTBpv+KU4fzuLYhOZC9kGlyzkw2HCL QmKJtsI3urjc9cyRYhWHSCIAn1f/EzGAgRueze43FAc18vrhaS/MNWszeddcVJuh2v rdKcw4dO1DgvA== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 17/23] KVM: VMX: Dump FRED context in dump_vmcs() Date: Wed, 23 Jul 2025 10:53:35 -0700 Message-ID: <20250723175341.1284463-18-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Add FRED related VMCS fields to dump_vmcs() to dump FRED context. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Changes in v5: * Read guest FRED RSP0 with vmx_read_guest_fred_rsp0() (Sean). * Add TB from Xuelian Guo. Change in v3: * Use (vmentry_ctrl & VM_ENTRY_LOAD_IA32_FRED) instead of is_fred_enabled() (Chao Gao). Changes in v2: * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() (Chao Gao). * Dump guest FRED states only if guest has FRED enabled (Nikolay Borisov). --- arch/x86/kvm/vmx/vmx.c | 43 +++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 0ca01980295e..90f0573c8187 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1400,6 +1400,9 @@ static void vmx_write_guest_fred_rsp0(struct vcpu_vmx= *vmx, u64 data) vmx_write_guest_host_msr(vmx, MSR_IA32_FRED_RSP0, data, &vmx->msr_guest_fred_rsp0); } +#else +/* To make sure dump_vmcs() compile on 32-bit */ +static u64 vmx_read_guest_fred_rsp0(struct vcpu_vmx *vmx) { return 0; } #endif =20 static void grow_ple_window(struct kvm_vcpu *vcpu) @@ -6343,7 +6346,7 @@ void dump_vmcs(struct kvm_vcpu *vcpu) struct vcpu_vmx *vmx =3D to_vmx(vcpu); u32 vmentry_ctl, vmexit_ctl; u32 cpu_based_exec_ctrl, pin_based_exec_ctrl, secondary_exec_control; - u64 tertiary_exec_control; + u64 tertiary_exec_control, secondary_vmexit_ctl; unsigned long cr4; int efer_slot; =20 @@ -6354,6 +6357,8 @@ void dump_vmcs(struct kvm_vcpu *vcpu) =20 vmentry_ctl =3D vmcs_read32(VM_ENTRY_CONTROLS); vmexit_ctl =3D vmcs_read32(VM_EXIT_CONTROLS); + secondary_vmexit_ctl =3D cpu_has_secondary_vmexit_ctrls() ? + vmcs_read64(SECONDARY_VM_EXIT_CONTROLS) : 0; cpu_based_exec_ctrl =3D vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); pin_based_exec_ctrl =3D vmcs_read32(PIN_BASED_VM_EXEC_CONTROL); cr4 =3D vmcs_readl(GUEST_CR4); @@ -6400,6 +6405,16 @@ void dump_vmcs(struct kvm_vcpu *vcpu) vmx_dump_sel("LDTR:", GUEST_LDTR_SELECTOR); vmx_dump_dtsel("IDTR:", GUEST_IDTR_LIMIT); vmx_dump_sel("TR: ", GUEST_TR_SELECTOR); + if (vmentry_ctl & VM_ENTRY_LOAD_IA32_FRED) + pr_err("FRED guest: config=3D0x%016llx, stack_levels=3D0x%016llx\n" + "RSP0=3D0x%016llx, RSP1=3D0x%016llx\n" + "RSP2=3D0x%016llx, RSP3=3D0x%016llx\n", + vmcs_read64(GUEST_IA32_FRED_CONFIG), + vmcs_read64(GUEST_IA32_FRED_STKLVLS), + vmx_read_guest_fred_rsp0(vmx), + vmcs_read64(GUEST_IA32_FRED_RSP1), + vmcs_read64(GUEST_IA32_FRED_RSP2), + vmcs_read64(GUEST_IA32_FRED_RSP3)); efer_slot =3D vmx_find_loadstore_msr_slot(&vmx->msr_autoload.guest, MSR_E= FER); if (vmentry_ctl & VM_ENTRY_LOAD_IA32_EFER) pr_err("EFER=3D 0x%016llx\n", vmcs_read64(GUEST_IA32_EFER)); @@ -6447,6 +6462,16 @@ void dump_vmcs(struct kvm_vcpu *vcpu) vmcs_readl(HOST_TR_BASE)); pr_err("GDTBase=3D%016lx IDTBase=3D%016lx\n", vmcs_readl(HOST_GDTR_BASE), vmcs_readl(HOST_IDTR_BASE)); + if (vmexit_ctl & SECONDARY_VM_EXIT_LOAD_IA32_FRED) + pr_err("FRED host: config=3D0x%016llx, stack_levels=3D0x%016llx\n" + "RSP0=3D0x%016lx, RSP1=3D0x%016llx\n" + "RSP2=3D0x%016llx, RSP3=3D0x%016llx\n", + vmcs_read64(HOST_IA32_FRED_CONFIG), + vmcs_read64(HOST_IA32_FRED_STKLVLS), + (unsigned long)task_stack_page(current) + THREAD_SIZE, + vmcs_read64(HOST_IA32_FRED_RSP1), + vmcs_read64(HOST_IA32_FRED_RSP2), + vmcs_read64(HOST_IA32_FRED_RSP3)); pr_err("CR0=3D%016lx CR3=3D%016lx CR4=3D%016lx\n", vmcs_readl(HOST_CR0), vmcs_readl(HOST_CR3), vmcs_readl(HOST_CR4)); @@ -6468,25 +6493,29 @@ void dump_vmcs(struct kvm_vcpu *vcpu) pr_err("*** Control State ***\n"); pr_err("CPUBased=3D0x%08x SecondaryExec=3D0x%08x TertiaryExec=3D0x%016llx= \n", cpu_based_exec_ctrl, secondary_exec_control, tertiary_exec_control= ); - pr_err("PinBased=3D0x%08x EntryControls=3D%08x ExitControls=3D%08x\n", - pin_based_exec_ctrl, vmentry_ctl, vmexit_ctl); + pr_err("PinBased=3D0x%08x EntryControls=3D0x%08x\n", + pin_based_exec_ctrl, vmentry_ctl); + pr_err("ExitControls=3D0x%08x SecondaryExitControls=3D0x%016llx\n", + vmexit_ctl, secondary_vmexit_ctl); pr_err("ExceptionBitmap=3D%08x PFECmask=3D%08x PFECmatch=3D%08x\n", vmcs_read32(EXCEPTION_BITMAP), vmcs_read32(PAGE_FAULT_ERROR_CODE_MASK), vmcs_read32(PAGE_FAULT_ERROR_CODE_MATCH)); - pr_err("VMEntry: intr_info=3D%08x errcode=3D%08x ilen=3D%08x\n", + pr_err("VMEntry: intr_info=3D%08x errcode=3D%08x ilen=3D%08x event_data= =3D%016llx\n", vmcs_read32(VM_ENTRY_INTR_INFO_FIELD), vmcs_read32(VM_ENTRY_EXCEPTION_ERROR_CODE), - vmcs_read32(VM_ENTRY_INSTRUCTION_LEN)); + vmcs_read32(VM_ENTRY_INSTRUCTION_LEN), + kvm_cpu_cap_has(X86_FEATURE_FRED) ? vmcs_read64(INJECTED_EVENT_DAT= A) : 0); pr_err("VMExit: intr_info=3D%08x errcode=3D%08x ilen=3D%08x\n", vmcs_read32(VM_EXIT_INTR_INFO), vmcs_read32(VM_EXIT_INTR_ERROR_CODE), vmcs_read32(VM_EXIT_INSTRUCTION_LEN)); pr_err(" reason=3D%08x qualification=3D%016lx\n", vmcs_read32(VM_EXIT_REASON), vmcs_readl(EXIT_QUALIFICATION)); - pr_err("IDTVectoring: info=3D%08x errcode=3D%08x\n", + pr_err("IDTVectoring: info=3D%08x errcode=3D%08x event_data=3D%016llx\n", vmcs_read32(IDT_VECTORING_INFO_FIELD), - vmcs_read32(IDT_VECTORING_ERROR_CODE)); + vmcs_read32(IDT_VECTORING_ERROR_CODE), + kvm_cpu_cap_has(X86_FEATURE_FRED) ? vmcs_read64(ORIGINAL_EVENT_DAT= A) : 0); pr_err("TSC Offset =3D 0x%016llx\n", vmcs_read64(TSC_OFFSET)); if (secondary_exec_control & SECONDARY_EXEC_TSC_SCALING) pr_err("TSC Multiplier =3D 0x%016llx\n", --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 49137239E61; Wed, 23 Jul 2025 17:54:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293265; cv=none; b=GaqSSbfC9F0L32oOXrhY+MU+dDozGg7smux0RIlTyjwuo4OX0sRRxAjUuRm775YEMAAdFwe3LHClVtzdt0388bFA3XfxRpp3kuRAim2OJxEDBzleol6WQivArJ8wN1zFyB16bsw6XJ/6/T7QEN6k/5buHYlHX0mfr3zgCCA4RUQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293265; c=relaxed/simple; bh=hHS4T4xizHF1v5opf01KtrsUhPUdZsbEgyf10Bk/Ppk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KSFjMTEcCiFHLpvfEV/ceH8t70MggJ6888dW+9Gn+lXd94+GNEncOC+ydj6d8jLlJWJngkGWFqkF9p1W2VBno5mzvXfIWgXvG6k8YqnUFOhgO9mk7n8D7khgtIHbyblYUCPKYCA1JOh6/rtdof6cr2ofpB+S2Nn15QdSLrkmHlQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=UFsrrf8u; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="UFsrrf8u" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf081284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:02 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf081284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293243; bh=dxRY8GwK+pkOBhljZWvpX9p8RnJIOV8DEDDL8qeM9LE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UFsrrf8u83GGvS2vrmpFCTlwEw+oxXNe2eVKHxBC8IhMMhMKF/RtU7Ze8V6uagsMD eiNJDPMBc9cvQjLAVdpQjoowUaN85+2oOrijcNH2IIbdG7Q21Gmojk9bDj1puhuMXl 84jAzmHdMQ56bc/WlLvO88/vgL4JxeJRQzb9EiW0LATgDy7kSRZWhjQBVjJI5BThq+ DpwYnTDwYTczFumBjBjzb1kf53wIRL8goH0X7VrnZq9HiIGFC+lQ/Ah/kGsMhaaphZ 2jokVGKpHtyEdUbZW9jl0fFFHJipDJt6BZIMnhKXPX9ThTRX7erytyRhojz9fWq3/j k5sIXEKYN9KYg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 18/23] KVM: x86: Advertise support for FRED Date: Wed, 23 Jul 2025 10:53:36 -0700 Message-ID: <20250723175341.1284463-19-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Advertise support for FRED to userspace after changes required to enable FRED in a KVM guest are in place. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Don't advertise FRED/LKGS together, LKGS can be advertised as an independent feature (Sean). * Add TB from Xuelian Guo. --- arch/x86/kvm/cpuid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index e2836a255b16..d2dd6beb4376 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -979,6 +979,7 @@ void kvm_set_cpu_caps(void) F(FSRS), F(FSRC), F(WRMSRNS), + X86_64_F(FRED), X86_64_F(LKGS), F(AMX_FP16), F(AVX_IFMA), --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 76D962459E3; Wed, 23 Jul 2025 17:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; cv=none; b=WY0QIjuAcKOJehyNU03F7MbtgJPRReIlOAdAb6Ze+LfoYoNUUmdcvctwUE/54FD2OzrZZEhnLe3DnvIZwcOIPJj/gdUDybldI3rzsuoGlaYpLhRLsQdARtzGfVJq1eod0ZSobw9qY4+fMcGNBzgr02c3ToVckv2wGcMXpVmHnc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; c=relaxed/simple; bh=yLJafNzCIkr8cm+K3MVGzcF9qeCDkcZ8/ki+sxYq0Wk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XXcxFVGG7+dI+8FDQJ39fGITzzOofleH4h8lQi8dajx9BA+RUx81pp7laYKcRlLmdDG0Cl31Hfgggm10h6N76H/rWEmLw3yjWfUBECslIoTCO0q5Q7CrN/KMsmc5t9E5Yu2hExzdx9kabKrdZbcvtuZYc7lgbEoHd3+0+xX38aI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=cCqFPoUX; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="cCqFPoUX" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf091284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:03 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf091284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293244; bh=os4Ok/VLeBI2u8zU4x1IGR71AhGTmdvxIlIpHFI3iCo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cCqFPoUXEb3OWe9NteIcsWCfXcW9OzVYhOY4iVtzC2kVR3QdaxspfMLCBgo5lfp1Z 8F0uN5aR/9SBgyX61Z+2eofZjf/85C14Tt8EdQtAYCjYUQxNdAOTXhGv6QEJlYzugz JH7WQflIEzNw2iKD6Mx50D22VIlYI3wQJ+WHbPB346Gr6w9Uo6WkAdWTNg6pPvoIe7 JPqseMOOj6FnpbBjNDidBGJpOiSDE6RP5rJrnZ/cd9tUUm+NV3vGr4dDS5IEZnYFB0 KIbHsmzXpTpD5JB/wXXp//zfCXlWQcvOsBOMbScaXo8VwPMj6hONapwKac5kfOoMl8 Thj1yXjynN5Pg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 19/23] KVM: nVMX: Add support for the secondary VM exit controls Date: Wed, 23 Jul 2025 10:53:37 -0700 Message-ID: <20250723175341.1284463-20-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Enable the secondary VM exit controls to prepare for nested FRED. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Changes in v5: * Allow writing MSR_IA32_VMX_EXIT_CTLS2 (Sean). * Add TB from Xuelian Guo. Change in v3: * Read secondary VM exit controls from vmcs_conf insteasd of the hardware MSR MSR_IA32_VMX_EXIT_CTLS2 to avoid advertising features to L1 that KVM itself doesn't support, e.g. because the expected entry+exit pairs aren't supported. (Sean Christopherson) --- Documentation/virt/kvm/x86/nested-vmx.rst | 1 + arch/x86/kvm/vmx/capabilities.h | 1 + arch/x86/kvm/vmx/nested.c | 25 ++++++++++++++++++++++- arch/x86/kvm/vmx/vmcs12.c | 1 + arch/x86/kvm/vmx/vmcs12.h | 2 ++ arch/x86/kvm/x86.h | 2 +- 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Documentation/virt/kvm/x86/nested-vmx.rst b/Documentation/virt= /kvm/x86/nested-vmx.rst index ac2095d41f02..e64ef231f310 100644 --- a/Documentation/virt/kvm/x86/nested-vmx.rst +++ b/Documentation/virt/kvm/x86/nested-vmx.rst @@ -217,6 +217,7 @@ struct shadow_vmcs is ever changed. u16 host_fs_selector; u16 host_gs_selector; u16 host_tr_selector; + u64 secondary_vm_exit_controls; }; =20 =20 diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index 76c69685b9be..6d446574d770 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -37,6 +37,7 @@ struct nested_vmx_msrs { u32 pinbased_ctls_high; u32 exit_ctls_low; u32 exit_ctls_high; + u64 secondary_exit_ctls; u32 entry_ctls_low; u32 entry_ctls_high; u32 misc_low; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index b8ea1969113d..4405d176cf74 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -1512,6 +1512,11 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_i= ndex, u64 data) return -EINVAL; vmx->nested.msrs.vmfunc_controls =3D data; return 0; + case MSR_IA32_VMX_EXIT_CTLS2: + if (data & ~vmcs_config.nested.secondary_exit_ctls) + return -EINVAL; + vmx->nested.msrs.secondary_exit_ctls =3D data; + return 0; default: /* * The rest of the VMX capability MSRs do not support restore. @@ -1551,6 +1556,9 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32= msr_index, u64 *pdata) if (msr_index =3D=3D MSR_IA32_VMX_EXIT_CTLS) *pdata |=3D VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; break; + case MSR_IA32_VMX_EXIT_CTLS2: + *pdata =3D msrs->secondary_exit_ctls; + break; case MSR_IA32_VMX_TRUE_ENTRY_CTLS: case MSR_IA32_VMX_ENTRY_CTLS: *pdata =3D vmx_control_msr( @@ -2501,6 +2509,11 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vm= x, struct loaded_vmcs *vmcs0 exec_control &=3D ~VM_EXIT_LOAD_IA32_EFER; vm_exit_controls_set(vmx, exec_control); =20 + if (exec_control & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + exec_control =3D __secondary_vm_exit_controls_get(vmcs01); + secondary_vm_exit_controls_set(vmx, exec_control); + } + /* * Interrupt/Exception Fields */ @@ -7029,7 +7042,7 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_co= nfig *vmcs_conf, VM_EXIT_HOST_ADDR_SPACE_SIZE | #endif VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT | - VM_EXIT_CLEAR_BNDCFGS; + VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_ACTIVATE_SECONDARY_CONTROLS; msrs->exit_ctls_high |=3D VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | @@ -7038,6 +7051,16 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_c= onfig *vmcs_conf, =20 /* We support free control of debug control saving. */ msrs->exit_ctls_low &=3D ~VM_EXIT_SAVE_DEBUG_CONTROLS; + + if (msrs->exit_ctls_high & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + msrs->secondary_exit_ctls =3D vmcs_conf->vmexit_2nd_ctrl; + /* + * As the secondary VM exit control is always loaded, do not + * advertise any feature in it to nVMX until its nVMX support + * is ready. + */ + msrs->secondary_exit_ctls &=3D 0; + } } =20 static void nested_vmx_setup_entry_ctls(struct vmcs_config *vmcs_conf, diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index 106a72c923ca..9fac24fd5b4b 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -66,6 +66,7 @@ const unsigned short vmcs12_field_offsets[] =3D { FIELD64(HOST_IA32_PAT, host_ia32_pat), FIELD64(HOST_IA32_EFER, host_ia32_efer), FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl), + FIELD64(SECONDARY_VM_EXIT_CONTROLS, secondary_vm_exit_controls), FIELD(PIN_BASED_VM_EXEC_CONTROL, pin_based_vm_exec_control), FIELD(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control), FIELD(EXCEPTION_BITMAP, exception_bitmap), diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 56fd150a6f24..1fe3ed9108aa 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -185,6 +185,7 @@ struct __packed vmcs12 { u16 host_gs_selector; u16 host_tr_selector; u16 guest_pml_index; + u64 secondary_vm_exit_controls; }; =20 /* @@ -360,6 +361,7 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_gs_selector, 992); CHECK_OFFSET(host_tr_selector, 994); CHECK_OFFSET(guest_pml_index, 996); + CHECK_OFFSET(secondary_vm_exit_controls, 998); } =20 extern const unsigned short vmcs12_field_offsets[]; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index aff93c5b2484..bdd37bce0bc9 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -94,7 +94,7 @@ do { \ * associated feature that KVM supports for nested virtualization. */ #define KVM_FIRST_EMULATED_VMX_MSR MSR_IA32_VMX_BASIC -#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_VMFUNC +#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_EXIT_CTLS2 =20 #define KVM_DEFAULT_PLE_GAP 128 #define KVM_VMX_DEFAULT_PLE_WINDOW 4096 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 7EB6521171B; Wed, 23 Jul 2025 17:54:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293259; cv=none; b=RPFWcsn3F9poDHEOo49+C343zxLC9dCjSmQetYQwzIEkWaNfaGk5QiirZP5Nnha1CQVTkBGB7HS9yox7uEoMiYvlghFO8SvZtSjPApd7EYPM4o8ZoPisG6oz1TlFHZEheNaOCtES5dHspK2ybZd6Q9PiiKHfdjBf4g886mRejww= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293259; c=relaxed/simple; bh=j4c5sJkASIzUOOYHbPsuGTHky14WODdjNudXy7a1za8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q3NAeaAK99TbEkcEoFYHd7puV34wSlMsfxY1GkyVPJac5ybItNMmsvr/dTrpOcAzsv+YtRT9iYOhsGNzMfKBL/y56uemIkMjoH8OTxFhd/A33ya+K96H8DtejDBXoGwaaN8PoQz7l+Kf+BmHmaJcq/RLA4C1ieem5KW3GB2/Pp0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=LVEnzYVj; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="LVEnzYVj" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf0A1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:04 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf0A1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293245; bh=WNDTqyryleKBN956EIW3NWLsuJYJhHWMm1VSzyo4gvo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LVEnzYVjRooQV+/JPOJwgUju0SdrgRcHib2+vujCMW2tZFUxP4wTTPU2I78IgP2gT 6vMlEGwmMhpIvKDmUWBNGAm6iyFuj1WvwiEIMR1ofoQ/DG+OMUqaPnZyvxWAAXyoHi DJN+uPa6Guy6xNGJRFvj88v9GMKmcivoVgHy30/ewpLuB+rM8lWDr731OJAXCL/Yl4 9M4jUoE/XnWoiP/gm4o9XGg7hoa+TQnwjX/1UAK+d9ZU6mGFqphZ7EJUXb6tRRSEWH yIHuzoh1+Hr8la9xksBuKER0K8gagOjquStPBrEwpvIon6hkSxpJuWEw0+EZco5Tt7 8kMmfL57llEDg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 20/23] KVM: nVMX: Add FRED VMCS fields to nested VMX context handling Date: Wed, 23 Jul 2025 10:53:38 -0700 Message-ID: <20250723175341.1284463-21-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Extend nested VMX context management to include FRED-related VMCS fields. This enables proper handling of FRED state during nested virtualization. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Changes in v4: * Advertise VMX nested exception as if the CPU supports it (Chao Gao). * Split FRED state management controls (Chao Gao). Changes in v3: * Add and use nested_cpu_has_fred(vmcs12) because vmcs02 should be set from vmcs12 if and only if the field is enabled in L1's VMX config (Sean Christopherson). * Fix coding style issues (Sean Christopherson). Changes in v2: * Remove hyperv TLFS related changes (Jeremi Piotrowski). * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() (Chao Gao). --- Documentation/virt/kvm/x86/nested-vmx.rst | 18 +++++ arch/x86/kvm/vmx/capabilities.h | 5 ++ arch/x86/kvm/vmx/nested.c | 83 ++++++++++++++++++++++- arch/x86/kvm/vmx/nested.h | 22 ++++++ arch/x86/kvm/vmx/vmcs12.c | 18 +++++ arch/x86/kvm/vmx/vmcs12.h | 36 ++++++++++ arch/x86/kvm/vmx/vmcs_shadow_fields.h | 4 ++ 7 files changed, 184 insertions(+), 2 deletions(-) diff --git a/Documentation/virt/kvm/x86/nested-vmx.rst b/Documentation/virt= /kvm/x86/nested-vmx.rst index e64ef231f310..87fa9f3877ab 100644 --- a/Documentation/virt/kvm/x86/nested-vmx.rst +++ b/Documentation/virt/kvm/x86/nested-vmx.rst @@ -218,6 +218,24 @@ struct shadow_vmcs is ever changed. u16 host_gs_selector; u16 host_tr_selector; u64 secondary_vm_exit_controls; + u64 guest_ia32_fred_config; + u64 guest_ia32_fred_rsp1; + u64 guest_ia32_fred_rsp2; + u64 guest_ia32_fred_rsp3; + u64 guest_ia32_fred_stklvls; + u64 guest_ia32_fred_ssp1; + u64 guest_ia32_fred_ssp2; + u64 guest_ia32_fred_ssp3; + u64 host_ia32_fred_config; + u64 host_ia32_fred_rsp1; + u64 host_ia32_fred_rsp2; + u64 host_ia32_fred_rsp3; + u64 host_ia32_fred_stklvls; + u64 host_ia32_fred_ssp1; + u64 host_ia32_fred_ssp2; + u64 host_ia32_fred_ssp3; + u64 injected_event_data; + u64 original_event_data; }; =20 =20 diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index 6d446574d770..cf7c93c33a98 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -78,6 +78,11 @@ static inline bool cpu_has_vmx_basic_inout(void) return vmcs_config.basic & VMX_BASIC_INOUT; } =20 +static inline bool cpu_has_vmx_nested_exception(void) +{ + return vmcs_config.basic & VMX_BASIC_NESTED_EXCEPTION; +} + static inline bool cpu_has_virtual_nmis(void) { return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS && diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 4405d176cf74..30d2de1243ef 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -705,6 +705,12 @@ static inline bool nested_vmx_prepare_msr_bitmap(struc= t kvm_vcpu *vcpu, =20 nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, MSR_KERNEL_GS_BASE, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_FRED_RSP0, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_FRED_SSP0, MSR_TYPE_RW); #endif nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, MSR_IA32_SPEC_CTRL, MSR_TYPE_RW); @@ -1272,9 +1278,11 @@ static int vmx_restore_vmx_basic(struct vcpu_vmx *vm= x, u64 data) { const u64 feature_bits =3D VMX_BASIC_DUAL_MONITOR_TREATMENT | VMX_BASIC_INOUT | - VMX_BASIC_TRUE_CTLS; + VMX_BASIC_TRUE_CTLS | + VMX_BASIC_NESTED_EXCEPTION; =20 - const u64 reserved_bits =3D GENMASK_ULL(63, 56) | + const u64 reserved_bits =3D GENMASK_ULL(63, 59) | + GENMASK_ULL(57, 56) | GENMASK_ULL(47, 45) | BIT_ULL(31); =20 @@ -2526,6 +2534,8 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx= , struct loaded_vmcs *vmcs0 vmcs12->vm_entry_instruction_len); vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, vmcs12->guest_interruptibility_info); + if (cpu_has_vmx_fred()) + vmcs_write64(INJECTED_EVENT_DATA, vmcs12->injected_event_data); vmx->loaded_vmcs->nmi_known_unmasked =3D !(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_NMI); } else { @@ -2578,6 +2588,17 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx= , struct vmcs12 *vmcs12) vmcs_writel(GUEST_IDTR_BASE, vmcs12->guest_idtr_base); =20 vmx_segment_cache_clear(vmx); + + if (nested_cpu_load_guest_fred_states(vmcs12)) { + vmcs_write64(GUEST_IA32_FRED_CONFIG, vmcs12->guest_ia32_fred_config); + vmcs_write64(GUEST_IA32_FRED_RSP1, vmcs12->guest_ia32_fred_rsp1); + vmcs_write64(GUEST_IA32_FRED_RSP2, vmcs12->guest_ia32_fred_rsp2); + vmcs_write64(GUEST_IA32_FRED_RSP3, vmcs12->guest_ia32_fred_rsp3); + vmcs_write64(GUEST_IA32_FRED_STKLVLS, vmcs12->guest_ia32_fred_stklvls); + vmcs_write64(GUEST_IA32_FRED_SSP1, vmcs12->guest_ia32_fred_ssp1); + vmcs_write64(GUEST_IA32_FRED_SSP2, vmcs12->guest_ia32_fred_ssp2); + vmcs_write64(GUEST_IA32_FRED_SSP3, vmcs12->guest_ia32_fred_ssp3); + } } =20 if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & @@ -3864,6 +3885,8 @@ static void vmcs12_save_pending_event(struct kvm_vcpu= *vcpu, u32 idt_vectoring; unsigned int nr; =20 + vmcs12->original_event_data =3D 0; + /* * Per the SDM, VM-Exits due to double and triple faults are never * considered to occur during event delivery, even if the double/triple @@ -3902,6 +3925,13 @@ static void vmcs12_save_pending_event(struct kvm_vcp= u *vcpu, vcpu->arch.exception.error_code; } =20 + if ((vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) && + (vmcs12->guest_cr4 & X86_CR4_FRED) && + (vcpu->arch.exception.nested)) + idt_vectoring |=3D VECTORING_INFO_NESTED_EXCEPTION_MASK; + + vmcs12->original_event_data =3D vcpu->arch.exception.event_data; + vmcs12->idt_vectoring_info_field =3D idt_vectoring; } else if (vcpu->arch.nmi_injected) { vmcs12->idt_vectoring_info_field =3D @@ -4482,6 +4512,14 @@ static bool is_vmcs12_ext_field(unsigned long field) case GUEST_TR_BASE: case GUEST_GDTR_BASE: case GUEST_IDTR_BASE: + case GUEST_IA32_FRED_CONFIG: + case GUEST_IA32_FRED_RSP1: + case GUEST_IA32_FRED_RSP2: + case GUEST_IA32_FRED_RSP3: + case GUEST_IA32_FRED_STKLVLS: + case GUEST_IA32_FRED_SSP1: + case GUEST_IA32_FRED_SSP2: + case GUEST_IA32_FRED_SSP3: case GUEST_PENDING_DBG_EXCEPTIONS: case GUEST_BNDCFGS: return true; @@ -4531,6 +4569,18 @@ static void sync_vmcs02_to_vmcs12_rare(struct kvm_vc= pu *vcpu, vmcs12->guest_tr_base =3D vmcs_readl(GUEST_TR_BASE); vmcs12->guest_gdtr_base =3D vmcs_readl(GUEST_GDTR_BASE); vmcs12->guest_idtr_base =3D vmcs_readl(GUEST_IDTR_BASE); + + if (nested_cpu_save_guest_fred_states(vmcs12)) { + vmcs12->guest_ia32_fred_config =3D vmcs_read64(GUEST_IA32_FRED_CONFIG); + vmcs12->guest_ia32_fred_rsp1 =3D vmcs_read64(GUEST_IA32_FRED_RSP1); + vmcs12->guest_ia32_fred_rsp2 =3D vmcs_read64(GUEST_IA32_FRED_RSP2); + vmcs12->guest_ia32_fred_rsp3 =3D vmcs_read64(GUEST_IA32_FRED_RSP3); + vmcs12->guest_ia32_fred_stklvls =3D vmcs_read64(GUEST_IA32_FRED_STKLVLS); + vmcs12->guest_ia32_fred_ssp1 =3D vmcs_read64(GUEST_IA32_FRED_SSP1); + vmcs12->guest_ia32_fred_ssp2 =3D vmcs_read64(GUEST_IA32_FRED_SSP2); + vmcs12->guest_ia32_fred_ssp3 =3D vmcs_read64(GUEST_IA32_FRED_SSP3); + } + vmcs12->guest_pending_dbg_exceptions =3D vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); =20 @@ -4684,6 +4734,21 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, st= ruct vmcs12 *vmcs12, =20 vmcs12->vm_exit_intr_info =3D exit_intr_info; vmcs12->vm_exit_instruction_len =3D exit_insn_len; + + /* + * When there is a valid original event, the exiting event is a nested + * event during delivery of the earlier original event. + * + * FRED event delivery reflects this relationship by setting the value + * of the nested exception bit of VM-exit interruption information + * (aka exiting-event identification) to that of the valid bit of the + * IDT-vectoring information (aka original-event identification). + */ + if ((vmcs12->idt_vectoring_info_field & VECTORING_INFO_VALID_MASK) && + (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) && + (vmcs12->guest_cr4 & X86_CR4_FRED)) + vmcs12->vm_exit_intr_info |=3D INTR_INFO_NESTED_EXCEPTION_MASK; + vmcs12->vmx_instruction_info =3D vmcs_read32(VMX_INSTRUCTION_INFO); =20 /* @@ -4761,6 +4826,17 @@ static void load_vmcs12_host_state(struct kvm_vcpu *= vcpu, vmcs_write32(GUEST_IDTR_LIMIT, 0xFFFF); vmcs_write32(GUEST_GDTR_LIMIT, 0xFFFF); =20 + if (nested_cpu_load_host_fred_states(vmcs12)) { + vmcs_write64(GUEST_IA32_FRED_CONFIG, vmcs12->host_ia32_fred_config); + vmcs_write64(GUEST_IA32_FRED_RSP1, vmcs12->host_ia32_fred_rsp1); + vmcs_write64(GUEST_IA32_FRED_RSP2, vmcs12->host_ia32_fred_rsp2); + vmcs_write64(GUEST_IA32_FRED_RSP3, vmcs12->host_ia32_fred_rsp3); + vmcs_write64(GUEST_IA32_FRED_STKLVLS, vmcs12->host_ia32_fred_stklvls); + vmcs_write64(GUEST_IA32_FRED_SSP1, vmcs12->host_ia32_fred_ssp1); + vmcs_write64(GUEST_IA32_FRED_SSP2, vmcs12->host_ia32_fred_ssp2); + vmcs_write64(GUEST_IA32_FRED_SSP3, vmcs12->host_ia32_fred_ssp3); + } + /* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) vmcs_write64(GUEST_BNDCFGS, 0); @@ -7228,6 +7304,9 @@ static void nested_vmx_setup_basic(struct nested_vmx_= msrs *msrs) msrs->basic |=3D VMX_BASIC_TRUE_CTLS; if (cpu_has_vmx_basic_inout()) msrs->basic |=3D VMX_BASIC_INOUT; + + if (cpu_has_vmx_nested_exception()) + msrs->basic |=3D VMX_BASIC_NESTED_EXCEPTION; } =20 static void nested_vmx_setup_cr_fixed(struct nested_vmx_msrs *msrs) diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h index 6eedcfc91070..c6b69699e28e 100644 --- a/arch/x86/kvm/vmx/nested.h +++ b/arch/x86/kvm/vmx/nested.h @@ -249,6 +249,11 @@ static inline bool nested_cpu_has_save_preemption_time= r(struct vmcs12 *vmcs12) VM_EXIT_SAVE_VMX_PREEMPTION_TIMER; } =20 +static inline bool nested_cpu_has_secondary_vm_exit_controls(struct vmcs12= *vmcs12) +{ + return vmcs12->vm_exit_controls & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS; +} + static inline bool nested_exit_on_nmi(struct kvm_vcpu *vcpu) { return nested_cpu_has_nmi_exiting(get_vmcs12(vcpu)); @@ -269,6 +274,23 @@ static inline bool nested_cpu_has_encls_exit(struct vm= cs12 *vmcs12) return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENCLS_EXITING); } =20 +static inline bool nested_cpu_load_guest_fred_states(struct vmcs12 *vmcs12) +{ + return vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_FRED; +} + +static inline bool nested_cpu_save_guest_fred_states(struct vmcs12 *vmcs12) +{ + return nested_cpu_has_secondary_vm_exit_controls(vmcs12) && + vmcs12->secondary_vm_exit_controls & SECONDARY_VM_EXIT_SAVE_IA32_F= RED; +} + +static inline bool nested_cpu_load_host_fred_states(struct vmcs12 *vmcs12) +{ + return nested_cpu_has_secondary_vm_exit_controls(vmcs12) && + vmcs12->secondary_vm_exit_controls & SECONDARY_VM_EXIT_LOAD_IA32_F= RED; +} + /* * if fixed0[i] =3D=3D 1: val[i] must be 1 * if fixed1[i] =3D=3D 0: val[i] must be 0 diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index 9fac24fd5b4b..5fa63326deba 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -67,6 +67,24 @@ const unsigned short vmcs12_field_offsets[] =3D { FIELD64(HOST_IA32_EFER, host_ia32_efer), FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl), FIELD64(SECONDARY_VM_EXIT_CONTROLS, secondary_vm_exit_controls), + FIELD64(INJECTED_EVENT_DATA, injected_event_data), + FIELD64(ORIGINAL_EVENT_DATA, original_event_data), + FIELD64(GUEST_IA32_FRED_CONFIG, guest_ia32_fred_config), + FIELD64(GUEST_IA32_FRED_RSP1, guest_ia32_fred_rsp1), + FIELD64(GUEST_IA32_FRED_RSP2, guest_ia32_fred_rsp2), + FIELD64(GUEST_IA32_FRED_RSP3, guest_ia32_fred_rsp3), + FIELD64(GUEST_IA32_FRED_STKLVLS, guest_ia32_fred_stklvls), + FIELD64(GUEST_IA32_FRED_SSP1, guest_ia32_fred_ssp1), + FIELD64(GUEST_IA32_FRED_SSP2, guest_ia32_fred_ssp2), + FIELD64(GUEST_IA32_FRED_SSP3, guest_ia32_fred_ssp3), + FIELD64(HOST_IA32_FRED_CONFIG, host_ia32_fred_config), + FIELD64(HOST_IA32_FRED_RSP1, host_ia32_fred_rsp1), + FIELD64(HOST_IA32_FRED_RSP2, host_ia32_fred_rsp2), + FIELD64(HOST_IA32_FRED_RSP3, host_ia32_fred_rsp3), + FIELD64(HOST_IA32_FRED_STKLVLS, host_ia32_fred_stklvls), + FIELD64(HOST_IA32_FRED_SSP1, host_ia32_fred_ssp1), + FIELD64(HOST_IA32_FRED_SSP2, host_ia32_fred_ssp2), + FIELD64(HOST_IA32_FRED_SSP3, host_ia32_fred_ssp3), FIELD(PIN_BASED_VM_EXEC_CONTROL, pin_based_vm_exec_control), FIELD(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control), FIELD(EXCEPTION_BITMAP, exception_bitmap), diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 1fe3ed9108aa..f2a33d7007c9 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -186,6 +186,24 @@ struct __packed vmcs12 { u16 host_tr_selector; u16 guest_pml_index; u64 secondary_vm_exit_controls; + u64 guest_ia32_fred_config; + u64 guest_ia32_fred_rsp1; + u64 guest_ia32_fred_rsp2; + u64 guest_ia32_fred_rsp3; + u64 guest_ia32_fred_stklvls; + u64 guest_ia32_fred_ssp1; + u64 guest_ia32_fred_ssp2; + u64 guest_ia32_fred_ssp3; + u64 host_ia32_fred_config; + u64 host_ia32_fred_rsp1; + u64 host_ia32_fred_rsp2; + u64 host_ia32_fred_rsp3; + u64 host_ia32_fred_stklvls; + u64 host_ia32_fred_ssp1; + u64 host_ia32_fred_ssp2; + u64 host_ia32_fred_ssp3; + u64 injected_event_data; + u64 original_event_data; }; =20 /* @@ -362,6 +380,24 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_tr_selector, 994); CHECK_OFFSET(guest_pml_index, 996); CHECK_OFFSET(secondary_vm_exit_controls, 998); + CHECK_OFFSET(guest_ia32_fred_config, 1006); + CHECK_OFFSET(guest_ia32_fred_rsp1, 1014); + CHECK_OFFSET(guest_ia32_fred_rsp2, 1022); + CHECK_OFFSET(guest_ia32_fred_rsp3, 1030); + CHECK_OFFSET(guest_ia32_fred_stklvls, 1038); + CHECK_OFFSET(guest_ia32_fred_ssp1, 1046); + CHECK_OFFSET(guest_ia32_fred_ssp2, 1054); + CHECK_OFFSET(guest_ia32_fred_ssp3, 1062); + CHECK_OFFSET(host_ia32_fred_config, 1070); + CHECK_OFFSET(host_ia32_fred_rsp1, 1078); + CHECK_OFFSET(host_ia32_fred_rsp2, 1086); + CHECK_OFFSET(host_ia32_fred_rsp3, 1094); + CHECK_OFFSET(host_ia32_fred_stklvls, 1102); + CHECK_OFFSET(host_ia32_fred_ssp1, 1110); + CHECK_OFFSET(host_ia32_fred_ssp2, 1118); + CHECK_OFFSET(host_ia32_fred_ssp3, 1126); + CHECK_OFFSET(injected_event_data, 1134); + CHECK_OFFSET(original_event_data, 1142); } =20 extern const unsigned short vmcs12_field_offsets[]; diff --git a/arch/x86/kvm/vmx/vmcs_shadow_fields.h b/arch/x86/kvm/vmx/vmcs_= shadow_fields.h index cad128d1657b..da338327c2b3 100644 --- a/arch/x86/kvm/vmx/vmcs_shadow_fields.h +++ b/arch/x86/kvm/vmx/vmcs_shadow_fields.h @@ -74,6 +74,10 @@ SHADOW_FIELD_RW(HOST_GS_BASE, host_gs_base) /* 64-bit */ SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS, guest_physical_address) SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS_HIGH, guest_physical_address) +SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA, original_event_data) +SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA_HIGH, original_event_data) +SHADOW_FIELD_RW(INJECTED_EVENT_DATA, injected_event_data) +SHADOW_FIELD_RW(INJECTED_EVENT_DATA_HIGH, injected_event_data) =20 #undef SHADOW_FIELD_RO #undef SHADOW_FIELD_RW --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 3297324418D; Wed, 23 Jul 2025 17:54:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293283; cv=none; b=LyyCXlINVwGemjraAP+XzOiDBRWdwUNkYj5JRQAlQnc9mB+hSOu4TK4FO2ujRGNEQ/aWjCv4bPo33iwmbo0F058lYrxJ8GT8rMrUpheff80f+BjhKiZEoIheQDkebi/OxBB8MU07WqTL99c2re/QFQUJx5JzVtSzoKeCginQ6JQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293283; c=relaxed/simple; bh=O+qfavYKJv5iWUZTQ2uqTtRgKKTYjV8vuHOkwfS7QDc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X7mne9Dvi7xQCD2fmWRtVRlFa28OFV+MBRScB1Gkf6c5+1NVO7NjmyQ/wBPdX8pOSBtgRXn3csNStxv//j5KREqpCch/DbPFZ7+ispSTkVLvZ3tfTAMwgDzXqYvQKw4x7A0GsLYTedmQ3+PPTXjJpoxnQltSfGHbDfNycGKdY6k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=dpMTe6Mv; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="dpMTe6Mv" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf0B1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:05 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf0B1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293245; bh=018Q97OXZzIS4qBkIRJzyl3XH/UjDMLrNTbYlNvCC0E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dpMTe6MvRoHSq4lYGjIviafdwU5vqAL1Ohbbz3J4aNx+aikG3U5ZeBGqruScrxuFK V/fNCjQV7MAF8SQHZ79FLeL8U4S5ytXrz+pht31i0RKFhW70eP6jzd6llIT2NIJMvO qtdf9bTDqUZXa2iIIbJT9vItlYcUb0FJu44hQNCwtZMOWhnipNaiJ38UwESAaJ3nUg 35zJtfP+kAhQrtk0v90df/5/Np+P+5K68bADhFJFLmzVNEIvYCKBOpm7qnalH6vNH7 h5WKj4AMi+So/DZ4oasM3yNpK1z/4NkKhtCM0JS0sSrNzw1vbt0PQh512F8dQWemZn Z9zoMVkigQH9Q== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 21/23] KVM: nVMX: Add FRED-related VMCS field checks Date: Wed, 23 Jul 2025 10:53:39 -0700 Message-ID: <20250723175341.1284463-22-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li As with real hardware, nested VMX validates various VMCS fields, including control and guest/host state fields. This patch adds checks for FRED-relat= ed VMCS fields to support nested FRED functionality. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. --- arch/x86/kvm/vmx/nested.c | 80 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 30d2de1243ef..d215e5ade5ef 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2966,6 +2966,8 @@ static int nested_check_vm_entry_controls(struct kvm_= vcpu *vcpu, struct vmcs12 *vmcs12) { struct vcpu_vmx *vmx =3D to_vmx(vcpu); + bool fred_enabled =3D (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) && + (vmcs12->guest_cr4 & X86_CR4_FRED); =20 if (CC(!vmx_control_verify(vmcs12->vm_entry_controls, vmx->nested.msrs.entry_ctls_low, @@ -2984,6 +2986,7 @@ static int nested_check_vm_entry_controls(struct kvm_= vcpu *vcpu, u32 intr_type =3D intr_info & INTR_INFO_INTR_TYPE_MASK; bool has_error_code =3D intr_info & INTR_INFO_DELIVER_CODE_MASK; bool should_have_error_code; + bool has_nested_exception =3D vmx->nested.msrs.basic & VMX_BASIC_NESTED_= EXCEPTION; bool urg =3D nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST); bool prot_mode =3D !urg || vmcs12->guest_cr0 & X86_CR0_PE; @@ -2997,7 +3000,9 @@ static int nested_check_vm_entry_controls(struct kvm_= vcpu *vcpu, /* VM-entry interruption-info field: vector */ if (CC(intr_type =3D=3D INTR_TYPE_NMI_INTR && vector !=3D NMI_VECTOR) || CC(intr_type =3D=3D INTR_TYPE_HARD_EXCEPTION && vector > 31) || - CC(intr_type =3D=3D INTR_TYPE_OTHER_EVENT && vector !=3D 0)) + CC(intr_type =3D=3D INTR_TYPE_OTHER_EVENT && + ((!fred_enabled && vector > 0) || + (fred_enabled && vector > 2)))) return -EINVAL; =20 /* VM-entry interruption-info field: deliver error code */ @@ -3016,6 +3021,15 @@ static int nested_check_vm_entry_controls(struct kvm= _vcpu *vcpu, if (CC(intr_info & INTR_INFO_RESVD_BITS_MASK)) return -EINVAL; =20 + /* + * When the CPU enumerates VMX nested-exception support, bit 13 + * (set to indicate a nested exception) of the intr info field + * may have value 1. Otherwise bit 13 is reserved. + */ + if (CC(!has_nested_exception && + (intr_info & INTR_INFO_NESTED_EXCEPTION_MASK))) + return -EINVAL; + /* VM-entry instruction length */ switch (intr_type) { case INTR_TYPE_SOFT_EXCEPTION: @@ -3025,6 +3039,12 @@ static int nested_check_vm_entry_controls(struct kvm= _vcpu *vcpu, CC(vmcs12->vm_entry_instruction_len =3D=3D 0 && CC(!nested_cpu_has_zero_length_injection(vcpu)))) return -EINVAL; + break; + case INTR_TYPE_OTHER_EVENT: + if (fred_enabled && (vector =3D=3D 1 || vector =3D=3D 2)) + if (CC(vmcs12->vm_entry_instruction_len > 15)) + return -EINVAL; + break; } } =20 @@ -3098,9 +3118,30 @@ static int nested_vmx_check_host_state(struct kvm_vc= pu *vcpu, if (ia32e) { if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) return -EINVAL; + if (vmcs12->vm_exit_controls & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS && + vmcs12->secondary_vm_exit_controls & SECONDARY_VM_EXIT_LOAD_IA32_FRE= D) { + /* Bit 11, bits 5:4, and bit 2 of the IA32_FRED_CONFIG must be zero */ + if (CC(vmcs12->host_ia32_fred_config & + (BIT_ULL(11) | GENMASK_ULL(5, 4) | BIT_ULL(2))) || + CC(vmcs12->host_ia32_fred_rsp1 & GENMASK_ULL(5, 0)) || + CC(vmcs12->host_ia32_fred_rsp2 & GENMASK_ULL(5, 0)) || + CC(vmcs12->host_ia32_fred_rsp3 & GENMASK_ULL(5, 0)) || + CC(vmcs12->host_ia32_fred_ssp1 & GENMASK_ULL(2, 0)) || + CC(vmcs12->host_ia32_fred_ssp2 & GENMASK_ULL(2, 0)) || + CC(vmcs12->host_ia32_fred_ssp3 & GENMASK_ULL(2, 0)) || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_config & PAGE= _MASK, vcpu)) || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_rsp1, vcpu)) = || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_rsp2, vcpu)) = || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_rsp3, vcpu)) = || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_ssp1, vcpu)) = || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_ssp2, vcpu)) = || + CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_ssp3, vcpu))) + return -EINVAL; + } } else { if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || CC(vmcs12->host_cr4 & X86_CR4_PCIDE) || + CC(vmcs12->host_cr4 & X86_CR4_FRED) || CC((vmcs12->host_rip) >> 32)) return -EINVAL; } @@ -3245,6 +3286,43 @@ static int nested_vmx_check_guest_state(struct kvm_v= cpu *vcpu, CC((vmcs12->guest_bndcfgs & MSR_IA32_BNDCFGS_RSVD)))) return -EINVAL; =20 + if (ia32e) { + if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_FRED) { + /* Bit 11, bits 5:4, and bit 2 of the IA32_FRED_CONFIG must be zero */ + if (CC(vmcs12->guest_ia32_fred_config & + (BIT_ULL(11) | GENMASK_ULL(5, 4) | BIT_ULL(2))) || + CC(vmcs12->guest_ia32_fred_rsp1 & GENMASK_ULL(5, 0)) || + CC(vmcs12->guest_ia32_fred_rsp2 & GENMASK_ULL(5, 0)) || + CC(vmcs12->guest_ia32_fred_rsp3 & GENMASK_ULL(5, 0)) || + CC(vmcs12->guest_ia32_fred_ssp1 & GENMASK_ULL(2, 0)) || + CC(vmcs12->guest_ia32_fred_ssp2 & GENMASK_ULL(2, 0)) || + CC(vmcs12->guest_ia32_fred_ssp3 & GENMASK_ULL(2, 0)) || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_config & PAG= E_MASK, vcpu)) || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_rsp1, vcpu))= || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_rsp2, vcpu))= || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_rsp3, vcpu))= || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_ssp1, vcpu))= || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_ssp2, vcpu))= || + CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_ssp3, vcpu))) + return -EINVAL; + } + if (vmcs12->guest_cr4 & X86_CR4_FRED) { + unsigned int ss_dpl =3D VMX_AR_DPL(vmcs12->guest_ss_ar_bytes); + if (CC(ss_dpl =3D=3D 1 || ss_dpl =3D=3D 2)) + return -EINVAL; + if (ss_dpl =3D=3D 0 && + CC(!(vmcs12->guest_cs_ar_bytes & VMX_AR_L_MASK))) + return -EINVAL; + if (ss_dpl =3D=3D 3 && + (CC(vmcs12->guest_rflags & X86_EFLAGS_IOPL) || + CC(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_STI))) + return -EINVAL; + } + } else { + if (CC(vmcs12->guest_cr4 & X86_CR4_FRED)) + return -EINVAL; + } + if (nested_check_guest_non_reg_state(vmcs12)) return -EINVAL; =20 --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 6D42D228CBE; Wed, 23 Jul 2025 17:54:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293261; cv=none; b=QjIzMc8ZTOFYWSxtTzrsEhKSuhaYo/3SjFcVC/kxQenfZVb6GsC1g6yXeIHhtm2n5SxY68TBOiKXQDym+ntaloGcTATtuo/cPRaCFV4QgdK0WB9SaoTwubOEMxNRpVD+4tF0asEc00lADhIafMT6Otn9loBvooQLk0FbPiCK3U4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293261; c=relaxed/simple; bh=zZDkl2sEj8bbirzJKmx0Quse7t3V4jW1l9acGjfFwwI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u7fanNcTibd/3aqfLxRmGUkGMLZ0ibrpK9JPgNjeP/e2m9crJcrhbEiiniSBEc14AB4Cmc4rfZNkn1QQEypWqO3FNWHJLPNYWnI0A1zr4GU9PCUbpLCb+nsoCwcl9PXun6UZCS8fLJWFGeq1LecGv4TcncYUcxm6s8Yrd4i6oBk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=dy4PbUMO; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="dy4PbUMO" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf0C1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:06 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf0C1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293246; bh=CDamqBzQwv1MD5nS57D4yPDft2aOSRkKHs3w7oljxxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dy4PbUMOoWrK3Bd5KAKcGBcKTtaMXvSDbMnHG8Lwwe92D5u0IC/eM/4YuyZelZIWM UcXtFXVw66Mb8KrhyBM4TRMZ6tTSwi0F2stVzpCqfOSnJi6o55CVprKwTsGBOsLVHd D/oDcjSoimP0NStv3aMHTbiebpdDKMHZnYP3si6dSIHaSb/5AoZv30Ncifu3K1FdQb VWNgFYKzY9/Ej3G7EgGpRhsjS93oC8Pdmk5c9u0sIeddNdfYwl5nEA5Ym0M+jh8w2s K1lMQmKQGI3Bep42OeuiL9QbsME7Yf6kk3C0yl65gsJz+XD3NhY6SeHf/P+leNDoYZ a/3RV9MXxgI6g== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 22/23] KVM: nVMX: Allow VMX FRED controls Date: Wed, 23 Jul 2025 10:53:40 -0700 Message-ID: <20250723175341.1284463-23-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Allow nVMX FRED controls as nested FRED support is in place. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. --- arch/x86/kvm/vmx/nested.c | 6 ++++-- arch/x86/kvm/vmx/vmx.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index d215e5ade5ef..3554701ec43b 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -7213,7 +7213,8 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_co= nfig *vmcs_conf, * advertise any feature in it to nVMX until its nVMX support * is ready. */ - msrs->secondary_exit_ctls &=3D 0; + msrs->secondary_exit_ctls &=3D SECONDARY_VM_EXIT_SAVE_IA32_FRED | + SECONDARY_VM_EXIT_LOAD_IA32_FRED; } } =20 @@ -7228,7 +7229,8 @@ static void nested_vmx_setup_entry_ctls(struct vmcs_c= onfig *vmcs_conf, #ifdef CONFIG_X86_64 VM_ENTRY_IA32E_MODE | #endif - VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS; + VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS | + VM_ENTRY_LOAD_IA32_FRED; msrs->entry_ctls_high |=3D (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER | VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 90f0573c8187..3cd860ea1577 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7854,6 +7854,7 @@ static void nested_vmx_cr_fixed1_bits_update(struct k= vm_vcpu *vcpu) =20 entry =3D kvm_find_cpuid_entry_index(vcpu, 0x7, 1); cr4_fixed1_update(X86_CR4_LAM_SUP, eax, feature_bit(LAM)); + cr4_fixed1_update(X86_CR4_FRED, eax, feature_bit(FRED)); =20 #undef cr4_fixed1_update } --=20 2.50.1 From nobody Mon Oct 6 06:29:01 2025 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 3A1F623182D; Wed, 23 Jul 2025 17:54:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293263; cv=none; b=iZZI7sBjbCqd9a4OmdNEY6YL4RsJ6Xv17KdsPYZyypXPuMWgHyWEwi7t9hLf/iBD9CMmOTws0j8ejrtPfSm4TkMWdo+m5+RckF4FkorypDuc+yu1MeSoW/v8FtXmvwto5cKz5hu3TxUf9IGQlDZmqEKXAWo8iX/n7Kd1+oIJOeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293263; c=relaxed/simple; bh=9A4Q42upgg66IrTK5yoJS98/5wWKyZ4SWNrLAsUlKtQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Mo78LsgGHkhvWyZmqG0jT+z2oDekDYnhS535AqppOKRBYxBR1dAw6OJqV/sliI3j9QrBS4ODRccgMhNvCw/tpGsxiLNHs1jXeObvyVIMh7UCMAAHwH8iiui2cU0ZUUdpoLGhlztwOAwrqewl7UoUFEJvBQcL5SLBpb5s4nlEwoA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=jyV49IEG; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="jyV49IEG" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf0D1284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:07 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf0D1284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293247; bh=cB0qFffZfZC4uW/TD2Ynm34XI3kmi421N2abXu5XwFg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jyV49IEGEIlnRGMT9Zfu5K7CNCpzQigjLdBDAWcOFss9/r6pwSQXuE/2dPnNrhoXP eGTGSNZ0lgBiV3BzYEfaMX/hKcG58T+sxTp/l+QN0qyfpgaXlWpUHuK8DkMViWkXMB xlBmIdlx7rpghmV+LhJdKQ7M7qAqwGKMI7YkJ3JO2QdntpJzFkPM2vv80swDBaYsDN Sha4+5ituj4Uv0XyL384aFHIIx1i/Ftd5Jb22ukR2bbUMCoOWwbrkA0A1V1/cevrur x9ZesNd5+eM62GZvGtjMNLCnfEfTgm+kQiSxzbYC2bRuh3RYwF88fbCXniDYyZxrUG U6c3QLL+esGnA== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 23/23] KVM: nVMX: Add prerequisites to SHADOW_FIELD_R[OW] macros Date: Wed, 23 Jul 2025 10:53:41 -0700 Message-ID: <20250723175341.1284463-24-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xin Li Add VMX feature checks before accessing VMCS fields via SHADOW_FIELD_R[OW] macros, as some fields may not be supported on all CPUs. Functions like copy_shadow_to_vmcs12() and copy_vmcs12_to_shadow() access VMCS fields that may not exist on certain hardware, such as INJECTED_EVENT_DATA. To avoid VMREAD/VMWRITE warnings, skip syncing fields tied to unsupported VMX features. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Change in v5: * Add TB from Xuelian Guo. Change since v2: * Add __SHADOW_FIELD_R[OW] for better readability or maintability (Sean). --- arch/x86/kvm/vmx/nested.c | 79 +++++++++++++++++++-------- arch/x86/kvm/vmx/vmcs_shadow_fields.h | 41 +++++++++----- 2 files changed, 83 insertions(+), 37 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 3554701ec43b..72c23f7267d3 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -55,14 +55,14 @@ struct shadow_vmcs_field { u16 offset; }; static struct shadow_vmcs_field shadow_read_only_fields[] =3D { -#define SHADOW_FIELD_RO(x, y) { x, offsetof(struct vmcs12, y) }, +#define __SHADOW_FIELD_RO(x, y, c) { x, offsetof(struct vmcs12, y) }, #include "vmcs_shadow_fields.h" }; static int max_shadow_read_only_fields =3D ARRAY_SIZE(shadow_read_only_fields); =20 static struct shadow_vmcs_field shadow_read_write_fields[] =3D { -#define SHADOW_FIELD_RW(x, y) { x, offsetof(struct vmcs12, y) }, +#define __SHADOW_FIELD_RW(x, y, c) { x, offsetof(struct vmcs12, y) }, #include "vmcs_shadow_fields.h" }; static int max_shadow_read_write_fields =3D @@ -85,6 +85,17 @@ static void init_vmcs_shadow_fields(void) pr_err("Missing field from shadow_read_only_field %x\n", field + 1); =20 + switch (field) { +#define __SHADOW_FIELD_RO(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#include "vmcs_shadow_fields.h" + default: + break; + } + clear_bit(field, vmx_vmread_bitmap); if (field & 1) #ifdef CONFIG_X86_64 @@ -110,24 +121,13 @@ static void init_vmcs_shadow_fields(void) field <=3D GUEST_TR_AR_BYTES, "Update vmcs12_write_any() to drop reserved bits from AR_BYTES"); =20 - /* - * PML and the preemption timer can be emulated, but the - * processor cannot vmwrite to fields that don't exist - * on bare metal. - */ switch (field) { - case GUEST_PML_INDEX: - if (!cpu_has_vmx_pml()) - continue; - break; - case VMX_PREEMPTION_TIMER_VALUE: - if (!cpu_has_vmx_preemption_timer()) - continue; - break; - case GUEST_INTR_STATUS: - if (!cpu_has_vmx_apicv()) - continue; +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ break; +#include "vmcs_shadow_fields.h" default: break; } @@ -1617,8 +1617,8 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32= msr_index, u64 *pdata) /* * Copy the writable VMCS shadow fields back to the VMCS12, in case they h= ave * been modified by the L1 guest. Note, "writable" in this context means - * "writable by the guest", i.e. tagged SHADOW_FIELD_RW; the set of - * fields tagged SHADOW_FIELD_RO may or may not align with the "read-only" + * "writable by the guest", i.e. tagged __SHADOW_FIELD_RW; the set of + * fields tagged __SHADOW_FIELD_RO may or may not align with the "read-onl= y" * VM-exit information fields (which are actually writable if the vCPU is * configured to support "VMWRITE to any supported field in the VMCS"). */ @@ -1639,6 +1639,18 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *v= mx) =20 for (i =3D 0; i < max_shadow_read_write_fields; i++) { field =3D shadow_read_write_fields[i]; + + switch (field.encoding) { +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#include "vmcs_shadow_fields.h" + default: + break; + } + val =3D __vmcs_readl(field.encoding); vmcs12_write_any(vmcs12, field.encoding, field.offset, val); } @@ -1673,6 +1685,23 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *v= mx) for (q =3D 0; q < ARRAY_SIZE(fields); q++) { for (i =3D 0; i < max_fields[q]; i++) { field =3D fields[q][i]; + + switch (field.encoding) { +#define __SHADOW_FIELD_RO(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#include "vmcs_shadow_fields.h" + default: + break; + } + val =3D vmcs12_read_any(vmcs12, field.encoding, field.offset); __vmcs_writel(field.encoding, val); @@ -5815,9 +5844,10 @@ static int handle_vmread(struct kvm_vcpu *vcpu) static bool is_shadow_field_rw(unsigned long field) { switch (field) { -#define SHADOW_FIELD_RW(x, y) case x: +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + return c; #include "vmcs_shadow_fields.h" - return true; default: break; } @@ -5827,9 +5857,10 @@ static bool is_shadow_field_rw(unsigned long field) static bool is_shadow_field_ro(unsigned long field) { switch (field) { -#define SHADOW_FIELD_RO(x, y) case x: +#define __SHADOW_FIELD_RO(x, y, c) \ + case x: \ + return c; #include "vmcs_shadow_fields.h" - return true; default: break; } diff --git a/arch/x86/kvm/vmx/vmcs_shadow_fields.h b/arch/x86/kvm/vmx/vmcs_= shadow_fields.h index da338327c2b3..607945ada35f 100644 --- a/arch/x86/kvm/vmx/vmcs_shadow_fields.h +++ b/arch/x86/kvm/vmx/vmcs_shadow_fields.h @@ -1,14 +1,17 @@ -#if !defined(SHADOW_FIELD_RO) && !defined(SHADOW_FIELD_RW) +#if !defined(__SHADOW_FIELD_RO) && !defined(__SHADOW_FIELD_RW) BUILD_BUG_ON(1) #endif =20 -#ifndef SHADOW_FIELD_RO -#define SHADOW_FIELD_RO(x, y) +#ifndef __SHADOW_FIELD_RO +#define __SHADOW_FIELD_RO(x, y, c) #endif -#ifndef SHADOW_FIELD_RW -#define SHADOW_FIELD_RW(x, y) +#ifndef __SHADOW_FIELD_RW +#define __SHADOW_FIELD_RW(x, y, c) #endif =20 +#define SHADOW_FIELD_RO(x, y) __SHADOW_FIELD_RO(x, y, true) +#define SHADOW_FIELD_RW(x, y) __SHADOW_FIELD_RW(x, y, true) + /* * We do NOT shadow fields that are modified when L0 * traps and emulates any vmx instruction (e.g. VMPTRLD, @@ -32,8 +35,12 @@ BUILD_BUG_ON(1) */ =20 /* 16-bits */ -SHADOW_FIELD_RW(GUEST_INTR_STATUS, guest_intr_status) -SHADOW_FIELD_RW(GUEST_PML_INDEX, guest_pml_index) +__SHADOW_FIELD_RW(GUEST_INTR_STATUS, guest_intr_status, cpu_has_vmx_apicv(= )) +/* + * PML can be emulated, but the processor cannot vmwrite to the VMCS field + * GUEST_PML_INDEX that doesn't exist on bare metal. + */ +__SHADOW_FIELD_RW(GUEST_PML_INDEX, guest_pml_index, cpu_has_vmx_pml()) SHADOW_FIELD_RW(HOST_FS_SELECTOR, host_fs_selector) SHADOW_FIELD_RW(HOST_GS_SELECTOR, host_gs_selector) =20 @@ -41,9 +48,9 @@ SHADOW_FIELD_RW(HOST_GS_SELECTOR, host_gs_selector) SHADOW_FIELD_RO(VM_EXIT_REASON, vm_exit_reason) SHADOW_FIELD_RO(VM_EXIT_INTR_INFO, vm_exit_intr_info) SHADOW_FIELD_RO(VM_EXIT_INSTRUCTION_LEN, vm_exit_instruction_len) +SHADOW_FIELD_RO(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code) SHADOW_FIELD_RO(IDT_VECTORING_INFO_FIELD, idt_vectoring_info_field) SHADOW_FIELD_RO(IDT_VECTORING_ERROR_CODE, idt_vectoring_error_code) -SHADOW_FIELD_RO(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code) SHADOW_FIELD_RO(GUEST_CS_AR_BYTES, guest_cs_ar_bytes) SHADOW_FIELD_RO(GUEST_SS_AR_BYTES, guest_ss_ar_bytes) SHADOW_FIELD_RW(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control) @@ -54,7 +61,12 @@ SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD, vm_entry_intr_= info_field) SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN, vm_entry_instruction_len) SHADOW_FIELD_RW(TPR_THRESHOLD, tpr_threshold) SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO, guest_interruptibility_info) -SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE, vmx_preemption_timer_value) +/* + * The preemption timer can be emulated, but the processor cannot vmwrite = to + * the VMCS field VMX_PREEMPTION_TIMER_VALUE that doesn't exist on bare me= tal. + */ +__SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE, vmx_preemption_timer_value, + cpu_has_vmx_preemption_timer()) =20 /* Natural width */ SHADOW_FIELD_RO(EXIT_QUALIFICATION, exit_qualification) @@ -74,10 +86,13 @@ SHADOW_FIELD_RW(HOST_GS_BASE, host_gs_base) /* 64-bit */ SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS, guest_physical_address) SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS_HIGH, guest_physical_address) -SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA, original_event_data) -SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA_HIGH, original_event_data) -SHADOW_FIELD_RW(INJECTED_EVENT_DATA, injected_event_data) -SHADOW_FIELD_RW(INJECTED_EVENT_DATA_HIGH, injected_event_data) +__SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA, original_event_data, cpu_has_vmx_fr= ed()) +__SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA_HIGH, original_event_data, cpu_has_v= mx_fred()) +__SHADOW_FIELD_RW(INJECTED_EVENT_DATA, injected_event_data, cpu_has_vmx_fr= ed()) +__SHADOW_FIELD_RW(INJECTED_EVENT_DATA_HIGH, injected_event_data, cpu_has_v= mx_fred()) =20 #undef SHADOW_FIELD_RO #undef SHADOW_FIELD_RW + +#undef __SHADOW_FIELD_RO +#undef __SHADOW_FIELD_RW --=20 2.50.1