From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 DC9C91F7586 for ; Thu, 24 Jul 2025 17:07:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753376852; cv=none; b=GHh8ccbVZiO7lbQJ6XZzP/9HuPj8TTFkY6MdpAhMH9Z6R1SsPSsOZ824HyHOawkMpsXbNspFOpLObBYgFwQUm8ZlPRlj56t+xzX5I55uiNvgjpJ/JfHGtN8fC0Ru+tqk0h2RQJBfDmesClP10YbVECeXrn3YmX68cG+/UKKwc1Q= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753376852; c=relaxed/simple; bh=m8fxeVi0BvoM1Jw4rYSy8k4ELezpE7ppQC33LCeKdq0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BaAbZWUNK/x1vSbiq5ksfCzZMaf+cdJW92svxQrNhBhq0fzuqIUTpg2lSBUWEm7cPatNHkTv2rCy8mWdKoxr59nR861Ny3OYc31Y+ntycUVmlcGz1yO7egPfcvmUxCR0Vl9qHc36aW2517RjIHG2VQn7NrObiYbFq7IXbFThilo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=T0YZBI2L; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="T0YZBI2L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2642C4CEED; Thu, 24 Jul 2025 17:07:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753376852; bh=m8fxeVi0BvoM1Jw4rYSy8k4ELezpE7ppQC33LCeKdq0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T0YZBI2LwAEJ9wDzbXza19eZF2YJnVFWeP2bi/j45+QNWsX4TqubjLLUimwrdRVIB S9dIdu2nDPvNYUjcEEoVBvsnm7qGOcptcdQFvOOuh72Kr3YNNxHpHbJVK3qPtM9xl9 PDvwws4701Q3b39robKBM0fInT7K66sq1Z98/vgGJg0lmoeagKuM3jf9EgLk2EOpFr YCsQZeDkSlFroGj4Njt4VKWTrsxDXGhcGVgnJXJ8ydgvvKvAxZDEdEIdKM0cfUp1/p rrBSST8cemIN2iNdssIx93Vp4BMQOSF3qaEy9rBJ8KCafsgE9MkXt15he5LlONF7uy Dm+sDqUL5C/dw== From: Sasha Levin To: stable@vger.kernel.org Cc: Sean Christopherson , Kai Huang , Sasha Levin Subject: [PATCH 6.1.y 1/3] x86/reboot: Harden virtualization hooks for emergency reboot Date: Thu, 24 Jul 2025 13:07:23 -0400 Message-Id: <20250724170725.1404455-1-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <2025062034-chastise-wrecking-9a12@gregkh> References: <2025062034-chastise-wrecking-9a12@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Sean Christopherson [ Upstream commit 5e408396c60cd0f0b53a43713016b6d6af8d69e0 ] Provide dedicated helpers to (un)register virt hooks used during an emergency crash/reboot, and WARN if there is an attempt to overwrite the registered callback, or an attempt to do an unpaired unregister. Opportunsitically use rcu_assign_pointer() instead of RCU_INIT_POINTER(), mainly so that the set/unset paths are more symmetrical, but also because any performance gains from using RCU_INIT_POINTER() are meaningless for this code. Reviewed-by: Kai Huang Link: https://lore.kernel.org/r/20230721201859.2307736-3-seanjc@google.com Signed-off-by: Sean Christopherson Stable-dep-of: a0ee1d5faff1 ("KVM: VMX: Flush shadow VMCS on emergency reboot") Signed-off-by: Sasha Levin --- arch/x86/include/asm/reboot.h | 5 +++-- arch/x86/kernel/reboot.c | 30 ++++++++++++++++++++++++------ arch/x86/kvm/vmx/vmx.c | 6 ++---- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index 2551baec927d2..d9a38d379d182 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -25,8 +25,9 @@ void __noreturn machine_real_restart(unsigned int type); #define MRR_BIOS 0 #define MRR_APM 1 -typedef void crash_vmclear_fn(void); -extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; +typedef void (cpu_emergency_virt_cb)(void); +void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); +void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); void cpu_emergency_disable_virtualization(void); typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index d9dbcd1cf75f8..635995e7a704a 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -794,17 +794,35 @@ void machine_crash_shutdown(struct pt_regs *regs) * * protected by rcu. */ -crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; -EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss); +static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; + +void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) +{ + if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback))) + return; + + rcu_assign_pointer(cpu_emergency_virt_callback, callback); +} +EXPORT_SYMBOL_GPL(cpu_emergency_register_virt_callback); + +void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) +{ + if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback) != callback)) + return; + + rcu_assign_pointer(cpu_emergency_virt_callback, NULL); + synchronize_rcu(); +} +EXPORT_SYMBOL_GPL(cpu_emergency_unregister_virt_callback); static inline void cpu_crash_vmclear_loaded_vmcss(void) { - crash_vmclear_fn *do_vmclear_operation = NULL; + cpu_emergency_virt_cb *callback; rcu_read_lock(); - do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); - if (do_vmclear_operation) - do_vmclear_operation(); + callback = rcu_dereference(cpu_emergency_virt_callback); + if (callback) + callback(); rcu_read_unlock(); } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index fbe26b88f7312..aef2f09718b57 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8554,8 +8554,7 @@ static void __vmx_exit(void) { allow_smaller_maxphyaddr = false; - RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); - synchronize_rcu(); + cpu_emergency_unregister_virt_callback(crash_vmclear_local_loaded_vmcss); vmx_cleanup_l1d_flush(); } @@ -8629,8 +8628,7 @@ static int __init vmx_init(void) pi_init_cpu(cpu); } - rcu_assign_pointer(crash_vmclear_loaded_vmcss, - crash_vmclear_local_loaded_vmcss); + cpu_emergency_register_virt_callback(crash_vmclear_local_loaded_vmcss); vmx_check_vmcs12_offsets(); -- 2.39.5