FAILED: patch "[PATCH] x86/sev: Make vTPM SVSM calls preemption-safe" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 6c43c72748fffd29dec15cd1f31e9a32949bc437
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092939-ecard-twirl-6094@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 6c43c72748fffd29dec15cd1f31e9a32949bc437 Mon Sep 17 00:00:00 2001
From: Melody Wang <[email protected]>
Date: Mon, 14 Sep 2026 00:57:17 +0000
Subject: [PATCH] x86/sev: Make vTPM SVSM calls preemption-safe
Two functions in the SVSM vTPM guest implementation do not disable preemption when fetching the SVSM Calling Area Address (CAA).
The SVSM CAA is a per-CPU structure. When a thread is preempted and migrated to a different CPU after fetching the per-CPU CAA, the SVSM call will execute on the new CPU with the original CPU's CAA. Which is wrong.
Move the CAA fetching operation inside svsm_perform_call_protocol() which disables interrupts around the SVSM call and thus runs preemption-safe.
arch/x86/coco/sev/svsm.c +8 -2
@@ -74,6 +74,14 @@ int svsm_perform_call_protocol(struct svsm_call *call) flags =native_local_irq_save (); +/* +* 'caa' is a per-CPU variable. To avoid using a stale or incorrect +* 'caa' if the task is preempted or migrated to another CPU after it +* is fetched, always fetch 'caa' and then issue the SVSM call with +* interrupts disabled. This ensures the correct 'caa' is used. +*/ + call->caa =svsm_get_caa (); + ghcb =__sev_get_ghcb (&state); do {
@@ -321,7 +329,6 @@ int snp_svsm_vtpm_send_command(u8 *buffer) {struct svsm_call call = {}; - call.caa =svsm_get_caa (); call.rax =SVSM_VTPM_CALL (SVSM_VTPM_CMD ); call.rcx =__pa (buffer);
@@ -345,7 +352,6 @@ bool snp_svsm_vtpm_probe(void)if (!snp_vmpl)return false; - call.caa =svsm_get_caa (); call.rax =SVSM_VTPM_CALL (SVSM_VTPM_QUERY );if (svsm_perform_call_protocol (&call))
Sasha Levin
maintainerPATCH 1/5 x86/sev: Move the internal header
From: "Borislav Petkov (AMD)" <[email protected]>
[ Upstream commit c1e8980fabf5d0106992a430284fac28bba053a6 ]
Move the internal header out of the usual include/asm/ include path because having an "internal" header there doesn't really make it internal - quite the opposite - that's the normal arch include path.
So move where it belongs and make it really internal.
No functional changes.
Stable-dep-of: 6c43c72748ff ("x86/sev: Make vTPM SVSM calls preemption-safe")
---
arch/x86/boot/startup/sev-startup.c | 3 ++-
arch/x86/coco/sev/core.c | 3 ++-
arch/x86/{include/asm/sev-internal.h => coco/sev/internal.h} | 0
arch/x86/coco/sev/noinstr.c | 3 ++-
arch/x86/coco/sev/vc-handle.c | 3 ++-
5 files changed, 8 insertions(+), 4 deletions(-)
rename arch/x86/{include/asm/sev-internal.h => coco/sev/internal.h} (100%)arch/x86/boot/startup/sev-startup.c +2 -1
@@ -27,7 +27,6 @@#include <asm/cpu_entry_area.h> #include <asm/stacktrace.h> #include <asm/sev.h> -#include <asm/sev-internal.h> #include <asm/insn-eval.h> #include <asm/fpu/xcr.h> #include <asm/processor.h>
@@ -41,6 +40,8 @@#include <asm/cpuid/api.h> #include <asm/cmdline.h> +#include "../../coco/sev/internal.h" +/* Include code shared with pre-decompression boot stage */ #include "sev-shared.c"
arch/x86/coco/sev/core.c +2 -1
@@ -31,7 +31,6 @@#include <asm/cpu_entry_area.h> #include <asm/stacktrace.h> #include <asm/sev.h> -#include <asm/sev-internal.h> #include <asm/insn-eval.h> #include <asm/fpu/xcr.h> #include <asm/processor.h>
@@ -46,6 +45,8 @@#include <asm/cmdline.h> #include <asm/msr.h> +#include "internal.h" +/* Bitmap of SEV features supported by the hypervisor */ u64 sev_hv_features__ro_after_init ;SYM_PIC_ALIAS (sev_hv_features);
arch/x86/coco/sev/internal.h renamed from arch/x86/include/asm/sev-internal.h +0 -0
arch/x86/coco/sev/noinstr.c +2 -1
@@ -16,7 +16,8 @@#include <asm/msr.h> #include <asm/ptrace.h> #include <asm/sev.h> -#include <asm/sev-internal.h> + +#include "internal.h" static __always_inline bool on_vc_stack(struct pt_regs *regs) {
arch/x86/coco/sev/vc-handle.c +2 -1
@@ -23,7 +23,6 @@#include <asm/init.h> #include <asm/stacktrace.h> #include <asm/sev.h> -#include <asm/sev-internal.h> #include <asm/insn-eval.h> #include <asm/fpu/xcr.h> #include <asm/processor.h>
@@ -35,6 +34,8 @@#include <asm/apic.h> #include <asm/cpuid/api.h> +#include "internal.h" +static enum es_result vc_slow_virt_to_phys (struct ghcb *ghcb,struct es_em_ctxt *ctxt,unsigned long vaddr,phys_addr_t *paddr) {
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/5 x86/sev: Add internal header guards
From: "Borislav Petkov (AMD)" <[email protected]>
[ Upstream commit f01c6489ad6ceb8d06eae0c5123fc6cf39276ff1 ]
All headers need guards ifdeffery.
Stable-dep-of: 6c43c72748ff ("x86/sev: Make vTPM SVSM calls preemption-safe")
--- arch/x86/coco/sev/internal.h | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/coco/sev/internal.h +3 -0
@@ -1,4 +1,6 @@/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __X86_COCO_SEV_INTERNAL_H__ +#define __X86_COCO_SEV_INTERNAL_H__#define DR7_RESET_VALUE 0x400
@@ -85,3 +87,4 @@ enum es_result sev_es_ghcb_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxtu64 get_hv_features (void );const struct snp_cpuid_table *snp_cpuid_get_table (void ); +#endif /* __X86_COCO_SEV_INTERNAL_H__ */
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/5 x86/sev: Carve out the SVSM code into a separate compilation unit
In reply to Sasha LevinFrom: "Borislav Petkov (AMD)" <[email protected]>
[ Upstream commit e21279b73ef6c7d27237912c914f2db0c5a74786 ]
Move the SVSM-related machinery into a separate compilation unit in order to keep sev/core.c slim and "on-topic".
No functional changes.
Stable-dep-of: 6c43c72748ff ("x86/sev: Make vTPM SVSM calls preemption-safe")
--- arch/x86/coco/sev/Makefile | 2 +- arch/x86/coco/sev/core.c | 377 ----------------------------------- arch/x86/coco/sev/internal.h | 29 +++ arch/x86/coco/sev/svsm.c | 362 +++++++++++++++++++++++++++++++++ 4 files changed, 392 insertions(+), 378 deletions(-) create mode 100644 arch/x86/coco/sev/svsm.c
arch/x86/coco/sev/Makefile +1 -1
@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y += core.o noinstr.o vc-handle.o +obj-y += core.o noinstr.o vc-handle.o svsm.o # Clang 14 and older may fail to respect __no_sanitize_undefined when inlining UBSAN_SANITIZE_noinstr.o := n
arch/x86/coco/sev/core.c +0 -377
407 lines not on this page · raw message
arch/x86/coco/sev/internal.h +29 -0
@@ -66,6 +66,9 @@ extern u64 boot_svsm_caa_pa;enum es_result verify_exception_info (struct ghcb *ghcb,struct es_em_ctxt *ctxt);void vc_forward_exception (struct es_em_ctxt *ctxt); +void svsm_pval_pages (struct snp_psc_desc *desc); +int svsm_perform_call_protocol (struct svsm_call *call); +bool snp_svsm_vtpm_probe (void );static inline u64 sev_es_rd_ghcb_msr (void ) {
@@ -87,4 +90,30 @@ enum es_result sev_es_ghcb_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxtu64 get_hv_features (void );const struct snp_cpuid_table *snp_cpuid_get_table (void ); + +static inline struct svsm_ca *svsm_get_caa (void ) +{ +if (sev_cfg.use_cas) +return this_cpu_read (svsm_caa); +else +return rip_rel_ptr (&boot_svsm_ca_page); +} + +static inline u64 svsm_get_caa_pa (void ) +{ +if (sev_cfg.use_cas) +return this_cpu_read (svsm_caa_pa); +else +return boot_svsm_caa_pa; +} + +static inline void __pval_terminate (u64 pfn,bool action,unsigned int page_size, +int ret,u64 svsm_ret) +{ +WARN (1 ,"PVALIDATE failure: pfn: 0x%llx, action: %u, size: %u, ret: %d, svsm_ret: 0x%llx\n" , + pfn, action, page_size, ret, svsm_ret); + +sev_es_terminate (SEV_TERM_SET_LINUX ,GHCB_TERM_PVALIDATE ); +} +#endif /* __X86_COCO_SEV_INTERNAL_H__ */
arch/x86/coco/sev/svsm.c new file +362 -0
362 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/5 x86/sev: Remove redundant ghcbs_initialized checks around __sev_{get,put}_ghcb()
In reply to Sasha LevinFrom: Nikunj A Dadhania <[email protected]>
[ Upstream commit 9d8460a1c7a6b0f2dc6302e5d0f31d4e8c2a7913 ]
After
3645eb7e3915 ("x86/fred: Fix early boot failures on SEV-ES/SNP guests"),
__sev_{get,put}_ghcb() handle the early-boot GHCB fallback internally, making the ghcbs_initialized guards in __set_pages_state() and svsm_perform_call_protocol() redundant.
Remove them.
Also initialize state->ghcb to NULL in the early-boot path of __sev_get_ghcb() so that the ghcb_state is well-defined for all callers, even though __sev_put_ghcb() currently returns early before reading it.
No functional change intended.
Stable-dep-of: 6c43c72748ff ("x86/sev: Make vTPM SVSM calls preemption-safe")
--- arch/x86/coco/sev/core.c | 8 ++------ arch/x86/coco/sev/noinstr.c | 4 +++- arch/x86/coco/sev/svsm.c | 10 ++-------- 3 files changed, 7 insertions(+), 15 deletions(-)
arch/x86/coco/sev/core.c +2 -6
@@ -367,17 +367,13 @@ static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned longlocal_irq_save (flags); -if (sev_cfg.ghcbs_initialized) - ghcb =__sev_get_ghcb (&state); -else - ghcb = boot_ghcb; + ghcb =__sev_get_ghcb (&state);/* Invoke the hypervisor to perform the page state changes */ if (!ghcb ||vmgexit_psc (ghcb, data))sev_es_terminate (SEV_TERM_SET_LINUX ,GHCB_TERM_PSC ); -if (sev_cfg.ghcbs_initialized) -__sev_put_ghcb (&state); +__sev_put_ghcb (&state);local_irq_restore (flags);
arch/x86/coco/sev/noinstr.c +3 -1
@@ -121,8 +121,10 @@ noinstr struct ghcb *__sev_get_ghcb(struct ghcb_state *state)WARN_ON (!irqs_disabled ()); -if (!sev_cfg.ghcbs_initialized) +if (!sev_cfg.ghcbs_initialized) { + state->ghcb =NULL ;return boot_ghcb; + } data =this_cpu_read (runtime_data); ghcb = &data->ghcb_page;
arch/x86/coco/sev/svsm.c +2 -8
@@ -74,20 +74,14 @@ int svsm_perform_call_protocol(struct svsm_call *call) flags =native_local_irq_save (); -if (sev_cfg.ghcbs_initialized) - ghcb =__sev_get_ghcb (&state); -else if (boot_ghcb) - ghcb = boot_ghcb; -else - ghcb =NULL ; + ghcb =__sev_get_ghcb (&state);do { ret = ghcb ?svsm_perform_ghcb_protocol (ghcb, call) :__pi_svsm_perform_msr_protocol (call); }while (ret == -EAGAIN ); -if (sev_cfg.ghcbs_initialized) -__sev_put_ghcb (&state); +__sev_put_ghcb (&state);native_local_irq_restore (flags);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 5/5 x86/sev: Make vTPM SVSM calls preemption-safe
In reply to Sasha LevinFrom: Melody Wang <[email protected]>
[ Upstream commit 6c43c72748fffd29dec15cd1f31e9a32949bc437 ]
Two functions in the SVSM vTPM guest implementation do not disable preemption when fetching the SVSM Calling Area Address (CAA).
The SVSM CAA is a per-CPU structure. When a thread is preempted and migrated to a different CPU after fetching the per-CPU CAA, the SVSM call will execute on the new CPU with the original CPU's CAA. Which is wrong.
Move the CAA fetching operation inside svsm_perform_call_protocol() which disables interrupts around the SVSM call and thus runs preemption-safe.
--- arch/x86/coco/sev/svsm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
arch/x86/coco/sev/svsm.c +8 -2
@@ -74,6 +74,14 @@ int svsm_perform_call_protocol(struct svsm_call *call) flags =native_local_irq_save (); +/* +* 'caa' is a per-CPU variable. To avoid using a stale or incorrect +* 'caa' if the task is preempted or migrated to another CPU after it +* is fetched, always fetch 'caa' and then issue the SVSM call with +* interrupts disabled. This ensures the correct 'caa' is used. +*/ + call->caa =svsm_get_caa (); + ghcb =__sev_get_ghcb (&state); do {
@@ -321,7 +329,6 @@ int snp_svsm_vtpm_send_command(u8 *buffer) {struct svsm_call call = {}; - call.caa =svsm_get_caa (); call.rax =SVSM_VTPM_CALL (SVSM_VTPM_CMD ); call.rcx =__pa (buffer);
@@ -345,7 +352,6 @@ bool snp_svsm_vtpm_probe(void)if (!snp_vmpl)return false; - call.caa =svsm_get_caa (); call.rax =SVSM_VTPM_CALL (SVSM_VTPM_QUERY );if (svsm_perform_call_protocol (&call))
Signature · 1 line
2.53.0