| From stable+bounces-164649-greg=kroah.com@vger.kernel.org Thu Jul 24 19:07:43 2025 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 24 Jul 2025 13:07:25 -0400 |
| Subject: KVM: VMX: Flush shadow VMCS on emergency reboot |
| To: stable@vger.kernel.org |
| Cc: Chao Gao <chao.gao@intel.com>, Kai Huang <kai.huang@intel.com>, Sean Christopherson <seanjc@google.com>, Sasha Levin <sashal@kernel.org> |
| Message-ID: <20250724170725.1404455-3-sashal@kernel.org> |
| |
| From: Chao Gao <chao.gao@intel.com> |
| |
| [ Upstream commit a0ee1d5faff135e28810f29e0f06328c66f89852 ] |
| |
| Ensure the shadow VMCS cache is evicted during an emergency reboot to |
| prevent potential memory corruption if the cache is evicted after reboot. |
| |
| This issue was identified through code inspection, as __loaded_vmcs_clear() |
| flushes both the normal VMCS and the shadow VMCS. |
| |
| Avoid checking the "launched" state during an emergency reboot, unlike the |
| behavior in __loaded_vmcs_clear(). This is important because reboot NMIs |
| can interfere with operations like copy_shadow_to_vmcs12(), where shadow |
| VMCSes are loaded directly using VMPTRLD. In such cases, if NMIs occur |
| right after the VMCS load, the shadow VMCSes will be active but the |
| "launched" state may not be set. |
| |
| Fixes: 16f5b9034b69 ("KVM: nVMX: Copy processor-specific shadow-vmcs to VMCS12") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Chao Gao <chao.gao@intel.com> |
| Reviewed-by: Kai Huang <kai.huang@intel.com> |
| Link: https://lore.kernel.org/r/20250324140849.2099723-1-chao.gao@intel.com |
| Signed-off-by: Sean Christopherson <seanjc@google.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kvm/vmx/vmx.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -713,8 +713,11 @@ static void vmx_emergency_disable(void) |
| struct loaded_vmcs *v; |
| |
| list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu), |
| - loaded_vmcss_on_cpu_link) |
| + loaded_vmcss_on_cpu_link) { |
| vmcs_clear(v->vmcs); |
| + if (v->shadow_vmcs) |
| + vmcs_clear(v->shadow_vmcs); |
| + } |
| |
| __cpu_emergency_vmxoff(); |
| } |