* FAILED: patch "[PATCH] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is" failed to apply to 6.12-stable tree
@ 2026-08-31 12:25 gregkh
2026-08-31 21:10 ` [PATCH 6.12.y 1/3] KVM: SEV: Make it more obvious when KVM is writing back the current PSC index Sasha Levin
0 siblings, 1 reply; 8+ messages in thread
From: gregkh @ 2026-08-31 12:25 UTC (permalink / raw)
To: seanjc, michael.roth; +Cc: stable
The patch below does not apply to the 6.12-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 <stable@vger.kernel.org>.
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.12.y
git checkout FETCH_HEAD
git cherry-pick -x 98ade8c48c28c227fe2e80e545ff0c57cd4712a3
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026083135-thud-surplus-53de@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 98ade8c48c28c227fe2e80e545ff0c57cd4712a3 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <seanjc@google.com>
Date: Thu, 9 Jul 2026 13:49:33 -0700
Subject: [PATCH] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is
unusable
Always mark the vCPU as RUNNABLE after responding to AP_CREATE, even if the
guest-specified VMSA is unusable, e.g. isn't backed by a memslot or doesn't
have a backing guest_memfd page. If the VMSA is unusable, leaving the vCPU
in a non-running state will effectively hang the vCPU instead of reporting
an error to userspace. This will also allow retrying the VMSA load in the
future, to fix a bug where KVM doesn't honor guest_memfd invalidation
events, e.g. if AP_CREATION races with PUNCH_HOLE.
Cc: stable@vger.kernel.org # 6.12.x
Reviewed-by: Michael Roth <michael.roth@amd.com>
Link: https://patch.msgid.link/20260709204948.1988414-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index d8ed00f76aa3..30792adcfc8e 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -4028,9 +4028,6 @@ static void sev_snp_reload_vmsa(struct kvm_vcpu *vcpu, gpa_t gpa)
svm->sev_es.snp_guest_vmsa_gpa = gpa;
svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
- /* Mark the vCPU as runnable */
- kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
-
/*
* gmem pages aren't currently migratable, but if this ever changes
* then care should be taken to ensure svm->sev_es.vmsa is pinned
@@ -4062,6 +4059,15 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
sev_snp_reload_vmsa(vcpu, gpa);
+
+ /*
+ * Mark the vCPU as runnable for CREATE requests, indicated by a valid
+ * VMSA GPA, even if installing the VMSA failed, so that KVM_RUN will
+ * fail instead of blocking indefinitely and hanging the vCPU, e.g. if
+ * the backing guest_memfd page is unavailable.
+ */
+ if (VALID_PAGE(gpa))
+ kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
}
static int sev_snp_ap_creation(struct vcpu_svm *svm)
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.12.y 1/3] KVM: SEV: Make it more obvious when KVM is writing back the current PSC index
2026-08-31 12:25 FAILED: patch "[PATCH] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is" failed to apply to 6.12-stable tree gregkh
@ 2026-08-31 21:10 ` Sasha Levin
2026-08-31 21:10 ` [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata Sasha Levin
2026-08-31 21:10 ` [PATCH 6.12.y 3/3] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable Sasha Levin
0 siblings, 2 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-31 21:10 UTC (permalink / raw)
To: stable
Cc: Sean Christopherson, Tom Lendacky, Michael Roth, Paolo Bonzini,
Sasha Levin
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 17d62e0b157f262dd8c7586cb882ece72a5b10c2 ]
Increment the guest-visible "cur_entry" index outside of the for-loop
when processing Page State Change entries, and add a comment to make it
more obvious which code is operating on trusted data, and which code is
touching guest-accessible data.
No functional change intended.
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260501202250.2115252-12-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20260529183549.1104619-12-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Stable-dep-of: 98ade8c48c28 ("KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/sev.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index a6971cd236bed..e5587675cf9ec 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3821,7 +3821,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
}
/* Find the start of the next range which needs processing. */
- for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) {
+ for (idx = idx_start; idx <= idx_end; idx++) {
entry_start = READ_ONCE(entries[idx]);
gfn = entry_start.gfn;
@@ -3848,6 +3848,14 @@ static int snp_begin_psc(struct vcpu_svm *svm)
if (npages)
break;
+
+ /*
+ * Increment the guest-visible index to communicate the current
+ * entry back to the guest, e.g. in case of failure. No need
+ * for READ_ONCE() as KVM doesn't consume the field, i.e. a
+ * misbehaving guest can only break itself.
+ */
+ hdr->cur_entry++;
}
if (idx > idx_end) {
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata
2026-08-31 21:10 ` [PATCH 6.12.y 1/3] KVM: SEV: Make it more obvious when KVM is writing back the current PSC index Sasha Levin
@ 2026-08-31 21:10 ` Sasha Levin
2026-09-01 19:01 ` Sean Christopherson
2026-08-31 21:10 ` [PATCH 6.12.y 3/3] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable Sasha Levin
1 sibling, 1 reply; 8+ messages in thread
From: Sasha Levin @ 2026-08-31 21:10 UTC (permalink / raw)
To: stable; +Cc: Sean Christopherson, Tom Lendacky, Paolo Bonzini, Sasha Levin
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 00b9744a3688758c5c492756d08a1cd599a76965 ]
Add a "psc" struct to vcpu_sev_es_state to avoid having to prefix all of
the fields with "psc_".
Take advantage of the code churn to opportunistically rename local
variables to "guest_psc" to make it more obvious that the buffer is guest
data, and more importantly, guest accessible!
Opportunistically rename inflight => batch_size as well, because there can
really only be one operation in-flight (per-vCPU), i.e. "inflight" _looks_
like a boolean, but in actuality is an integer tracking how many pages are
being handled by the current operation.
No functional change intended.
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260501202250.2115252-13-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20260529183549.1104619-13-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
For the 6.12 backport, retain the existing GHCB response write because the
newer VMGEXIT response helper is not available. Also fold in the VMSA GPA
tracking and helper refactoring needed by the dependent AP_CREATE fix,
adapting them to the 6.12 gmem and MP-state APIs and existing reset hook
without adding a new function.
Stable-dep-of: 98ade8c48c28 ("KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/sev.c | 162 ++++++++++++++++++++---------------------
arch/x86/kvm/svm/svm.c | 2 +
arch/x86/kvm/svm/svm.h | 11 ++-
3 files changed, 87 insertions(+), 88 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index e5587675cf9ec..7be27b481ca22 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3726,17 +3726,14 @@ static int snp_begin_psc(struct vcpu_svm *svm);
static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret)
{
- svm->sev_es.psc_inflight = 0;
- svm->sev_es.psc_idx = 0;
- svm->sev_es.psc_2m = false;
+ memset(&svm->sev_es.psc, 0, sizeof(svm->sev_es.psc));
ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, psc_ret);
}
static void __snp_complete_one_psc(struct vcpu_svm *svm)
{
- struct psc_buffer *psc = svm->sev_es.ghcb_sa;
- struct psc_entry *entries = psc->entries;
- struct psc_hdr *hdr = &psc->hdr;
+ struct vcpu_sev_es_state *sev_es = &svm->sev_es;
+ struct psc_buffer *guest_psc = sev_es->ghcb_sa;
__u16 idx;
/*
@@ -3744,14 +3741,14 @@ static void __snp_complete_one_psc(struct vcpu_svm *svm)
* corresponding entries in the guest's PSC buffer and zero out the
* count of in-flight PSC entries.
*/
- for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
- svm->sev_es.psc_inflight--, idx++) {
- struct psc_entry entry = READ_ONCE(entries[idx]);
+ for (idx = sev_es->psc.cur_idx; sev_es->psc.batch_size;
+ sev_es->psc.batch_size--, idx++) {
+ struct psc_entry entry = READ_ONCE(guest_psc->entries[idx]);
- entries[idx].cur_page = entry.pagesize ? 512 : 1;
+ guest_psc->entries[idx].cur_page = entry.pagesize ? 512 : 1;
}
- hdr->cur_entry = idx;
+ guest_psc->hdr.cur_entry = idx;
}
static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
@@ -3772,10 +3769,8 @@ static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
static int snp_begin_psc(struct vcpu_svm *svm)
{
struct vcpu_sev_es_state *sev_es = &svm->sev_es;
- struct psc_buffer *psc = sev_es->ghcb_sa;
- struct psc_entry *entries = psc->entries;
+ struct psc_buffer *guest_psc = sev_es->ghcb_sa;
struct kvm_vcpu *vcpu = &svm->vcpu;
- struct psc_hdr *hdr = &psc->hdr;
struct psc_entry entry_start;
u16 idx, idx_start, idx_end, max_nr_entries;
int npages;
@@ -3802,7 +3797,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
next_range:
/* There should be no other PSCs in-flight at this point. */
- if (WARN_ON_ONCE(svm->sev_es.psc_inflight)) {
+ if (WARN_ON_ONCE(svm->sev_es.psc.batch_size)) {
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
return 1;
}
@@ -3812,8 +3807,8 @@ static int snp_begin_psc(struct vcpu_svm *svm)
* validation, so take care to only use validated copies of values used
* for things like array indexing.
*/
- idx_start = READ_ONCE(hdr->cur_entry);
- idx_end = READ_ONCE(hdr->end_entry);
+ idx_start = READ_ONCE(guest_psc->hdr.cur_entry);
+ idx_end = READ_ONCE(guest_psc->hdr.end_entry);
if (idx_end >= max_nr_entries) {
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
@@ -3822,7 +3817,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
/* Find the start of the next range which needs processing. */
for (idx = idx_start; idx <= idx_end; idx++) {
- entry_start = READ_ONCE(entries[idx]);
+ entry_start = READ_ONCE(guest_psc->entries[idx]);
gfn = entry_start.gfn;
huge = entry_start.pagesize;
@@ -3855,7 +3850,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
* for READ_ONCE() as KVM doesn't consume the field, i.e. a
* misbehaving guest can only break itself.
*/
- hdr->cur_entry++;
+ guest_psc->hdr.cur_entry++;
}
if (idx > idx_end) {
@@ -3864,9 +3859,9 @@ static int snp_begin_psc(struct vcpu_svm *svm)
return 1;
}
- svm->sev_es.psc_2m = huge;
- svm->sev_es.psc_idx = idx;
- svm->sev_es.psc_inflight = 1;
+ sev_es->psc.is_2m = huge;
+ sev_es->psc.cur_idx = idx;
+ sev_es->psc.batch_size = 1;
/*
* Find all subsequent PSC entries that contain adjacent GPA
@@ -3874,14 +3869,14 @@ static int snp_begin_psc(struct vcpu_svm *svm)
* KVM_HC_MAP_GPA_RANGE exit.
*/
while (++idx <= idx_end) {
- struct psc_entry entry = READ_ONCE(entries[idx]);
+ struct psc_entry entry = READ_ONCE(guest_psc->entries[idx]);
if (entry.operation != entry_start.operation ||
entry.gfn != entry_start.gfn + npages ||
entry.cur_page || !!entry.pagesize != huge)
break;
- svm->sev_es.psc_inflight++;
+ sev_es->psc.batch_size++;
npages += huge ? 512 : 1;
}
@@ -3916,71 +3911,66 @@ static int snp_begin_psc(struct vcpu_svm *svm)
BUG();
}
-static int __sev_snp_update_protected_guest_state(struct kvm_vcpu *vcpu)
+/* kvm_set_mp_state() was introduced after 6.12. */
+#define kvm_set_mp_state(vcpu, state) ((vcpu)->arch.mp_state = (state))
+
+static void sev_snp_reload_vmsa(struct kvm_vcpu *vcpu, gpa_t gpa)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ struct kvm_memory_slot *slot;
+ gfn_t gfn = gpa_to_gfn(gpa);
+ kvm_pfn_t pfn;
- WARN_ON(!mutex_is_locked(&svm->sev_es.snp_vmsa_mutex));
+ lockdep_assert_held(&svm->sev_es.snp_vmsa_mutex);
- /* Mark the vCPU as offline and not runnable */
- vcpu->arch.pv.pv_unhalted = false;
- vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
-
- /* Clear use of the VMSA */
+ /* Clear use of the VMSA. */
svm->vmcb->control.vmsa_pa = INVALID_PAGE;
+ svm->sev_es.snp_guest_vmsa_gpa = INVALID_PAGE;
- if (VALID_PAGE(svm->sev_es.snp_vmsa_gpa)) {
- gfn_t gfn = gpa_to_gfn(svm->sev_es.snp_vmsa_gpa);
- struct kvm_memory_slot *slot;
- kvm_pfn_t pfn;
-
- slot = gfn_to_memslot(vcpu->kvm, gfn);
- if (!slot)
- return -EINVAL;
+ /*
+ * When replacing the VMSA during SEV-SNP AP creation,
+ * mark the VMCB dirty so that full state is always reloaded.
+ */
+ vmcb_mark_all_dirty(svm->vmcb);
- /*
- * The new VMSA will be private memory guest memory, so
- * retrieve the PFN from the gmem backend.
- */
- if (kvm_gmem_get_pfn(vcpu->kvm, slot, gfn, &pfn, NULL))
- return -EINVAL;
+ if (!VALID_PAGE(gpa))
+ return;
- /*
- * From this point forward, the VMSA will always be a
- * guest-mapped page rather than the initial one allocated
- * by KVM in svm->sev_es.vmsa. In theory, svm->sev_es.vmsa
- * could be free'd and cleaned up here, but that involves
- * cleanups like wbinvd_on_all_cpus() which would ideally
- * be handled during teardown rather than guest boot.
- * Deferring that also allows the existing logic for SEV-ES
- * VMSAs to be re-used with minimal SNP-specific changes.
- */
- svm->sev_es.snp_has_guest_vmsa = true;
+ slot = gfn_to_memslot(vcpu->kvm, gfn);
+ if (!slot)
+ return;
- /* Use the new VMSA */
- svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
+ /*
+ * The new VMSA will be private memory guest memory, so retrieve the
+ * PFN from the gmem backend.
+ */
+ if (kvm_gmem_get_pfn(vcpu->kvm, slot, gfn, &pfn, NULL))
+ return;
- /* Mark the vCPU as runnable */
- vcpu->arch.pv.pv_unhalted = false;
- vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+ /*
+ * From this point forward, the VMSA will always be a guest-mapped page
+ * rather than the initial one allocated by KVM in svm->sev_es.vmsa. In
+ * theory, svm->sev_es.vmsa could be free'd and cleaned up here, but
+ * that involves cleanups like flushing caches, which would ideally be
+ * handled during teardown rather than guest boot. Deferring that also
+ * allows the existing logic for SEV-ES VMSAs to be re-used with minimal
+ * SNP-specific changes.
+ */
+ svm->sev_es.snp_has_guest_vmsa = true;
- svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
+ /* Use the new VMSA */
+ svm->sev_es.snp_guest_vmsa_gpa = gpa;
+ svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
- /*
- * gmem pages aren't currently migratable, but if this ever
- * changes then care should be taken to ensure
- * svm->sev_es.vmsa is pinned through some other means.
- */
- kvm_release_pfn_clean(pfn);
- }
+ /* Mark the vCPU as runnable */
+ kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
/*
- * When replacing the VMSA during SEV-SNP AP creation,
- * mark the VMCB dirty so that full state is always reloaded.
+ * gmem pages aren't currently migratable, but if this ever changes
+ * then care should be taken to ensure svm->sev_es.vmsa is pinned
+ * through some other means.
*/
- vmcb_mark_all_dirty(svm->vmcb);
-
- return 0;
+ kvm_release_pfn_clean(pfn);
}
/*
@@ -3989,26 +3979,30 @@ static int __sev_snp_update_protected_guest_state(struct kvm_vcpu *vcpu)
void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- int ret;
+ gpa_t gpa;
if (!sev_snp_guest(vcpu->kvm))
return;
- mutex_lock(&svm->sev_es.snp_vmsa_mutex);
+ guard(mutex)(&svm->sev_es.snp_vmsa_mutex);
if (!svm->sev_es.snp_ap_waiting_for_reset)
- goto unlock;
+ return;
svm->sev_es.snp_ap_waiting_for_reset = false;
- ret = __sev_snp_update_protected_guest_state(vcpu);
- if (ret)
- vcpu_unimpl(vcpu, "snp: AP state update on init failed\n");
+ /* Mark the vCPU as offline and not runnable */
+ vcpu->arch.pv.pv_unhalted = false;
+ kvm_set_mp_state(vcpu, KVM_MP_STATE_HALTED);
-unlock:
- mutex_unlock(&svm->sev_es.snp_vmsa_mutex);
+ gpa = svm->sev_es.snp_pending_vmsa_gpa;
+ svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
+
+ sev_snp_reload_vmsa(vcpu, gpa);
}
+#undef kvm_set_mp_state
+
static int sev_snp_ap_creation(struct vcpu_svm *svm)
{
struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info;
@@ -4085,10 +4079,10 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
goto out;
}
- target_svm->sev_es.snp_vmsa_gpa = svm->vmcb->control.exit_info_2;
+ target_svm->sev_es.snp_pending_vmsa_gpa = svm->vmcb->control.exit_info_2;
break;
case SVM_VMGEXIT_AP_DESTROY:
- target_svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
+ target_svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
break;
default:
vcpu_unimpl(vcpu, "vmgexit: invalid AP creation request [%#x] from guest\n",
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 44819d9470dcf..48a2d5c42f233 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1473,6 +1473,8 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu)
if (vmsa_page)
svm->sev_es.vmsa = page_address(vmsa_page);
+ svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
+ svm->sev_es.snp_guest_vmsa_gpa = INVALID_PAGE;
svm->guest_state_loaded = false;
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index c34cd7f1408fc..725d5cf237c4f 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -231,14 +231,17 @@ struct vcpu_sev_es_state {
bool ghcb_sa_free;
/* SNP Page-State-Change buffer entries currently being processed */
- u16 psc_idx;
- u16 psc_inflight;
- bool psc_2m;
+ struct {
+ u16 cur_idx;
+ u16 batch_size;
+ bool is_2m;
+ } psc;
u64 ghcb_registered_gpa;
struct mutex snp_vmsa_mutex; /* Used to handle concurrent updates of VMSA. */
- gpa_t snp_vmsa_gpa;
+ gpa_t snp_pending_vmsa_gpa;
+ gpa_t snp_guest_vmsa_gpa;
bool snp_ap_waiting_for_reset;
bool snp_has_guest_vmsa;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.12.y 3/3] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable
2026-08-31 21:10 ` [PATCH 6.12.y 1/3] KVM: SEV: Make it more obvious when KVM is writing back the current PSC index Sasha Levin
2026-08-31 21:10 ` [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata Sasha Levin
@ 2026-08-31 21:10 ` Sasha Levin
1 sibling, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-31 21:10 UTC (permalink / raw)
To: stable; +Cc: Sean Christopherson, Michael Roth, Sasha Levin
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 98ade8c48c28c227fe2e80e545ff0c57cd4712a3 ]
Always mark the vCPU as RUNNABLE after responding to AP_CREATE, even if the
guest-specified VMSA is unusable, e.g. isn't backed by a memslot or doesn't
have a backing guest_memfd page. If the VMSA is unusable, leaving the vCPU
in a non-running state will effectively hang the vCPU instead of reporting
an error to userspace. This will also allow retrying the VMSA load in the
future, to fix a bug where KVM doesn't honor guest_memfd invalidation
events, e.g. if AP_CREATION races with PUNCH_HOLE.
Cc: stable@vger.kernel.org # 6.12.x
Reviewed-by: Michael Roth <michael.roth@amd.com>
Link: https://patch.msgid.link/20260709204948.1988414-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/sev.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 7be27b481ca22..bf89f4d6e2e78 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3962,9 +3962,6 @@ static void sev_snp_reload_vmsa(struct kvm_vcpu *vcpu, gpa_t gpa)
svm->sev_es.snp_guest_vmsa_gpa = gpa;
svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
- /* Mark the vCPU as runnable */
- kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
-
/*
* gmem pages aren't currently migratable, but if this ever changes
* then care should be taken to ensure svm->sev_es.vmsa is pinned
@@ -3999,6 +3996,15 @@ void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
sev_snp_reload_vmsa(vcpu, gpa);
+
+ /*
+ * Mark the vCPU as runnable for CREATE requests, indicated by a valid
+ * VMSA GPA, even if installing the VMSA failed, so that KVM_RUN will
+ * fail instead of blocking indefinitely and hanging the vCPU, e.g. if
+ * the backing guest_memfd page is unavailable.
+ */
+ if (VALID_PAGE(gpa))
+ kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
}
#undef kvm_set_mp_state
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata
2026-08-31 21:10 ` [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata Sasha Levin
@ 2026-09-01 19:01 ` Sean Christopherson
2026-09-02 22:14 ` Sasha Levin
0 siblings, 1 reply; 8+ messages in thread
From: Sean Christopherson @ 2026-09-01 19:01 UTC (permalink / raw)
To: Sasha Levin; +Cc: stable, Tom Lendacky, Paolo Bonzini
On Mon, Aug 31, 2026, Sasha Levin wrote:
> From: Sean Christopherson <seanjc@google.com>
>
> [ Upstream commit 00b9744a3688758c5c492756d08a1cd599a76965 ]
>
> Add a "psc" struct to vcpu_sev_es_state to avoid having to prefix all of
> the fields with "psc_".
>
> Take advantage of the code churn to opportunistically rename local
> variables to "guest_psc" to make it more obvious that the buffer is guest
> data, and more importantly, guest accessible!
>
> Opportunistically rename inflight => batch_size as well, because there can
> really only be one operation in-flight (per-vCPU), i.e. "inflight" _looks_
> like a boolean, but in actuality is an integer tracking how many pages are
> being handled by the current operation.
>
> No functional change intended.
>
> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> Message-ID: <20260501202250.2115252-13-seanjc@google.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> Message-ID: <20260529183549.1104619-13-pbonzini@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> For the 6.12 backport, retain the existing GHCB response write because the
> newer VMGEXIT response helper is not available. Also fold in the VMSA GPA
> tracking and helper refactoring needed by the dependent AP_CREATE fix,
> adapting them to the 6.12 gmem and MP-state APIs and existing reset hook
> without adding a new function.
NAK.
As the first sentence says, grabbing 00b9744a3688 ("KVM: SEV: Add an anonymous
"psc" struct to track current PSC metadata") only requires handling a superficial
syntactic conflict. This mixes in pieces of d1a3c2162334 ("KVM: SEV: Forcefully
invalidate SNP VMSA if its backing gmem page is zapped"), and *that* is the
commit that's by far the most interesting. I.e. pretty much all of this is
leading up to that commit, not these intermediate commits.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata
2026-09-01 19:01 ` Sean Christopherson
@ 2026-09-02 22:14 ` Sasha Levin
2026-09-04 0:23 ` Sean Christopherson
0 siblings, 1 reply; 8+ messages in thread
From: Sasha Levin @ 2026-09-02 22:14 UTC (permalink / raw)
To: Sean Christopherson; +Cc: Sasha Levin, stable, Tom Lendacky, Paolo Bonzini
> NAK.
>
> As the first sentence says, grabbing 00b9744a3688 ("KVM: SEV: Add an
> anonymous "psc" struct to track current PSC metadata") only requires
> handling a superficial syntactic conflict. This mixes in pieces of
> d1a3c2162334 ("KVM: SEV: Forcefully invalidate SNP VMSA if its backing
> gmem page is zapped"), and *that* is the commit that's by far the most
> interesting. I.e. pretty much all of this is leading up to that commit,
> not these intermediate commits.
Yes, this is a complex one :(
How do you see this series then? it's a lot to backport, but if you're okay
with it...
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata
2026-09-02 22:14 ` Sasha Levin
@ 2026-09-04 0:23 ` Sean Christopherson
2026-09-06 13:32 ` Sasha Levin
0 siblings, 1 reply; 8+ messages in thread
From: Sean Christopherson @ 2026-09-04 0:23 UTC (permalink / raw)
To: Sasha Levin; +Cc: stable, Tom Lendacky, Paolo Bonzini
On Wed, Sep 02, 2026, Sasha Levin wrote:
> > NAK.
> >
> > As the first sentence says, grabbing 00b9744a3688 ("KVM: SEV: Add an
> > anonymous "psc" struct to track current PSC metadata") only requires
> > handling a superficial syntactic conflict. This mixes in pieces of
> > d1a3c2162334 ("KVM: SEV: Forcefully invalidate SNP VMSA if its backing
> > gmem page is zapped"), and *that* is the commit that's by far the most
> > interesting. I.e. pretty much all of this is leading up to that commit,
> > not these intermediate commits.
>
> Yes, this is a complex one :(
>
> How do you see this series then? it's a lot to backport, but if you're okay
> with it...
Ya, backport the whole thing up through d1a3c2162334. It's a lot of patches, but
IMO the risk of breaking something by trying to trim down the backport is
significantly higher than the risk of those backports.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata
2026-09-04 0:23 ` Sean Christopherson
@ 2026-09-06 13:32 ` Sasha Levin
0 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-09-06 13:32 UTC (permalink / raw)
To: Sean Christopherson; +Cc: Sasha Levin, stable, Tom Lendacky, Paolo Bonzini
> Ya, backport the whole thing up through d1a3c2162334. It's a lot of
> patches, but IMO the risk of breaking something by trying to trim down
> the backport is significantly higher than
Tried exactly that on 6.12.y. 9 of the 10 commits (through 42a39ad5d592
onward) landed clean, plus one extra prerequisite you didn't list,
d6c840adfebc ("KVM: x86/mmu: Rename .private_max_mapping_level() to
.gmem_max_mapping_level()") built clean on x86_64 and aarch64.
The actual fix, d1a3c2162334 ("KVM: SEV: Forcefully invalidate SNP VMSA
if its backing gmem page is zapped"), doesn't land on top of that
though: even with the rename in place it conflicts in kvm-x86-ops.h,
kvm_host.h, sev.c and svm.h, and resolving it means introducing the new
CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE plumbing rather than a minor
context fixup.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-06 13:33 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 12:25 FAILED: patch "[PATCH] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is" failed to apply to 6.12-stable tree gregkh
2026-08-31 21:10 ` [PATCH 6.12.y 1/3] KVM: SEV: Make it more obvious when KVM is writing back the current PSC index Sasha Levin
2026-08-31 21:10 ` [PATCH 6.12.y 2/3] KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata Sasha Levin
2026-09-01 19:01 ` Sean Christopherson
2026-09-02 22:14 ` Sasha Levin
2026-09-04 0:23 ` Sean Christopherson
2026-09-06 13:32 ` Sasha Levin
2026-08-31 21:10 ` [PATCH 6.12.y 3/3] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox