All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] KVM: x86/SVM: Fixes for AMD ERAPS virtualization
@ 2026-07-17 23:05 Jim Mattson
  2026-07-17 23:05 ` [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() Jim Mattson
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Jim Mattson @ 2026-07-17 23:05 UTC (permalink / raw)
  To: jmattson; +Cc: amit.shah, kvm, pbonzini, seanjc, venkateshs, yosry

This series fixes three issues in KVM's virtualization of Enhanced Return
Address Predictor Security (ERAPS):

Patch 1 adds ALLOW_LARGER_RAP configuration to svm_vcpu_after_set_cpuid()
so that the BSP will be properly configured. The ALLOW_LARGER_RAP
configuration in init_vmcb() is retained to restore the bit after the VMCB
is cleared on the VCPU triple fault path.

Patch 2 moves ERAPS dirty tracking into svm_flush_tlb_asid(). AMD ERAPS
architecturally requires clearing the Return Address Predictor (RAP/RSB) on
all implicit TLB invalidations. Centralizing dirty tracking in
svm_flush_tlb_asid() ensures that local/current ASID flushes
(e.g. same-value CR3 reloads under shadow paging, CR4.PAE/SMEP toggles,
single-context INVPCID) correctly mark ERAPS dirty and clear the RAP on the
next VMRUN.

Patch 3 adds a KVM_REQ_TLB_FLUSH_GUEST request to kvm_mtrr_set_msr() when
MTRR MSRs are written via WRMSR. Per AMD APM and Intel SDM, MTRR writes are
implicit TLB invalidations. Requesting a guest TLB flush restores x86
architectural compliance and ensures ERAPS RAP clearing on MTRR writes.

v1 -> v2:

* Restored the ALLOW_LARGER_RAP configuration in init_vmcb() [Sashiko]

v1: https://lore.kernel.org/kvm/20260716232524.2092085-1-jmattson@google.com/

Jim Mattson (3):
  KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid()
  KVM: SVM: Dirty ERAPS register on all ASID TLB flushes
  KVM: x86: Flush guest TLB on MTRR MSR writes

 arch/x86/kvm/mtrr.c    |  1 +
 arch/x86/kvm/svm/svm.c | 16 ++++++++--------
 2 files changed, 9 insertions(+), 8 deletions(-)


base-commit: 58717b2a1365d06c8c64b72aa948541b53fe31eb
-- 
2.55.0.229.g6434b31f56-goog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid()
  2026-07-17 23:05 [PATCH v2 0/3] KVM: x86/SVM: Fixes for AMD ERAPS virtualization Jim Mattson
@ 2026-07-17 23:05 ` Jim Mattson
  2026-07-20 15:52   ` Sean Christopherson
  2026-07-17 23:05 ` [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes Jim Mattson
  2026-07-17 23:05 ` [PATCH v2 3/3] KVM: x86: Flush guest TLB on MTRR MSR writes Jim Mattson
  2 siblings, 1 reply; 9+ messages in thread
From: Jim Mattson @ 2026-07-17 23:05 UTC (permalink / raw)
  To: jmattson; +Cc: amit.shah, kvm, pbonzini, seanjc, venkateshs, yosry

On initial vCPU creation, init_vmcb() is called before userspace configures
guest CPUID via KVM_SET_CPUID2. Consequently, ERAP_CONTROL_ALLOW_LARGER_RAP
is never set during initial vCPU creation. If an AP later receives an INIT
signal after CPUID has been set, init_vmcb() would set the bit for that AP,
but the BSP would be left with ALLOW_LARGER_RAP clear.

Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() to handle the BSP.

Keep the code in init_vmcb() to restore ALLOW_LARGER_RAP after the VMCB has
been cleared on the VCPU triple-fault reset path.

Fixes: db5e82496492 ("KVM: SVM: Virtualize and advertise support for ERAPS")
Assisted-by: Gemini:Gemini-Next
Signed-off-by: Jim Mattson <jmattson@google.com>
---
 arch/x86/kvm/svm/svm.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 4d2bacd00ec4..bf868da14cd2 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4736,6 +4736,11 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 	if (guest_cpuid_is_intel_compatible(vcpu))
 		guest_cpu_cap_clear(vcpu, X86_FEATURE_V_VMSAVE_VMLOAD);
 
+	if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS))
+		svm->vmcb01.ptr->control.erap_ctl |= ERAP_CONTROL_ALLOW_LARGER_RAP;
+	else
+		svm->vmcb01.ptr->control.erap_ctl &= ~ERAP_CONTROL_ALLOW_LARGER_RAP;
+
 	if (is_sev_guest(vcpu))
 		sev_vcpu_after_set_cpuid(svm);
 }
-- 
2.55.0.229.g6434b31f56-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes
  2026-07-17 23:05 [PATCH v2 0/3] KVM: x86/SVM: Fixes for AMD ERAPS virtualization Jim Mattson
  2026-07-17 23:05 ` [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() Jim Mattson
@ 2026-07-17 23:05 ` Jim Mattson
  2026-07-20 15:33   ` Sean Christopherson
  2026-07-17 23:05 ` [PATCH v2 3/3] KVM: x86: Flush guest TLB on MTRR MSR writes Jim Mattson
  2 siblings, 1 reply; 9+ messages in thread
From: Jim Mattson @ 2026-07-17 23:05 UTC (permalink / raw)
  To: jmattson; +Cc: amit.shah, kvm, pbonzini, seanjc, venkateshs, yosry

Per the AMD APM, ERAPS clears the Return Address Predictor (RAP/RSB) on all
implicit TLB invalidations (e.g. modifying certain CR[04] bits).

Move kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS) into
svm_flush_tlb_asid() so that any ASID-level TLB flush marks ERAPS dirty.
Centralizing the ERAPS dirty call in svm_flush_tlb_asid() ensures that all
ASID flushes (flush_tlb_current, flush_tlb_all, flush_tlb_guest) properly
set ERAP_CONTROL_CLEAR_RAP on the next VMRUN.

Remove the now redundant svm_flush_tlb_guest() wrapper.

Fixes: db5e82496492 ("KVM: SVM: Virtualize and advertise support for ERAPS")
Assisted-by: Gemini:Gemini-Next
Signed-off-by: Jim Mattson <jmattson@google.com>
---
 arch/x86/kvm/svm/svm.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index bf868da14cd2..f2fdca341dac 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4171,6 +4171,8 @@ static void svm_flush_tlb_asid(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS);
+
 	/*
 	 * Unlike VMX, SVM doesn't provide a way to flush only NPT TLB entries.
 	 * A TLB flush for the current ASID flushes both "host" and "guest" TLB
@@ -4229,13 +4231,6 @@ static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)
 	invlpga(gva, svm->vmcb->control.asid);
 }
 
-static void svm_flush_tlb_guest(struct kvm_vcpu *vcpu)
-{
-	kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS);
-
-	svm_flush_tlb_asid(vcpu);
-}
-
 static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -5383,7 +5378,7 @@ struct kvm_x86_ops svm_x86_ops __initdata = {
 	.flush_tlb_all = svm_flush_tlb_all,
 	.flush_tlb_current = svm_flush_tlb_current,
 	.flush_tlb_gva = svm_flush_tlb_gva,
-	.flush_tlb_guest = svm_flush_tlb_guest,
+	.flush_tlb_guest = svm_flush_tlb_asid,
 
 	.vcpu_pre_run = svm_vcpu_pre_run,
 	.vcpu_run = svm_vcpu_run,
-- 
2.55.0.229.g6434b31f56-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] KVM: x86: Flush guest TLB on MTRR MSR writes
  2026-07-17 23:05 [PATCH v2 0/3] KVM: x86/SVM: Fixes for AMD ERAPS virtualization Jim Mattson
  2026-07-17 23:05 ` [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() Jim Mattson
  2026-07-17 23:05 ` [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes Jim Mattson
@ 2026-07-17 23:05 ` Jim Mattson
  2026-07-20 15:46   ` Sean Christopherson
  2 siblings, 1 reply; 9+ messages in thread
From: Jim Mattson @ 2026-07-17 23:05 UTC (permalink / raw)
  To: jmattson; +Cc: amit.shah, kvm, pbonzini, seanjc, venkateshs, yosry

Per both the AMD APM and the Intel SDM, writing to an MTRR with WRMSR is an
implicit TLB invalidation that invalidates all TLB entries (including
global entries). [The APM uses the word, "update," which could be construed
to mean "modify," but it is unclear.]

Previously, kvm_mtrr_set_msr() stored the updated MTRR state without
requesting a TLB flush. This broke x86 architectural compliance by leaving
existing TLB entries in hardware. Additionally, on AMD CPUs supporting
ERAPS, omitting the TLB flush request meant VCPU_REG_ERAPS was never
dirtied on MTRR writes, leaving the Return Address Predictor (RAP/RSB)
uncleared.

Issue a KVM_REQ_TLB_FLUSH_GUEST request on every MTRR MSR write to match
x86 architectural semantics.

Fixes: 9ba075a664df ("KVM: MTRR support")
Assisted-by: Gemini:Gemini-Next
Signed-off-by: Jim Mattson <jmattson@google.com>
---
 arch/x86/kvm/mtrr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
index 6f74e2b27c1e..ca5e5c7f7022 100644
--- a/arch/x86/kvm/mtrr.c
+++ b/arch/x86/kvm/mtrr.c
@@ -105,6 +105,7 @@ int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 		return 1;
 
 	*mtrr = data;
+	kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
 	return 0;
 }
 
-- 
2.55.0.229.g6434b31f56-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes
  2026-07-17 23:05 ` [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes Jim Mattson
@ 2026-07-20 15:33   ` Sean Christopherson
  2026-07-20 16:41     ` Jim Mattson
  0 siblings, 1 reply; 9+ messages in thread
From: Sean Christopherson @ 2026-07-20 15:33 UTC (permalink / raw)
  To: Jim Mattson; +Cc: amit.shah, kvm, pbonzini, venkateshs, yosry

On Fri, Jul 17, 2026, Jim Mattson wrote:
> Per the AMD APM, ERAPS clears the Return Address Predictor (RAP/RSB) on all
> implicit TLB invalidations (e.g. modifying certain CR[04] bits).
> 
> Move kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS) into
> svm_flush_tlb_asid() so that any ASID-level TLB flush marks ERAPS dirty.

NAK, the whole point of KVM_REQ_TLB_FLUSH_GUEST is emulate TLB invalidations in
the guest's domain.  If we're missing KVM_REQ_TLB_FLUSH_GUEST requests, fix those.

I think we're missing a clear on the MOV CR3 flush when TDP is disabled?  Beyond
that, nothing jumps out.

diff --git arch/x86/kvm/x86.c arch/x86/kvm/x86.c
index 11017f49b94a..39b1e79df6c9 100644
--- arch/x86/kvm/x86.c
+++ arch/x86/kvm/x86.c
@@ -755,10 +755,16 @@ void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid)
         * also via the emulator.  KVM's TDP page tables are not in the scope of
         * the invalidation, but the guest's TLB entries need to be flushed as
         * the CPU may have cached entries in its TLB for the target PCID.
+        *
+        * When ERAPS is supported, invalidating a specific PCID clears the RAP
+        * (Return Address Predicator).  KVM flushes the RAP when emulating a
+        * full guest TLB flush, so only the !TDP case needs to be handled here.
         */
        if (unlikely(tdp_enabled)) {
                kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
                return;
+       } else if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS)) {
+               kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS);
        }
 
        /*
@@ -10740,13 +10746,6 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva)
                        return 1;
                }
 
-               /*
-                * When ERAPS is supported, invalidating a specific PCID clears
-                * the RAP (Return Address Predicator).
-                */
-               if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS))
-                       kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS);
-
                kvm_invalidate_pcid(vcpu, operand.pcid);
                return kvm_skip_emulated_instruction(vcpu);
 
@@ -10760,11 +10759,6 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva)
 
                fallthrough;
        case INVPCID_TYPE_ALL_INCL_GLOBAL:
-               /*
-                * Don't bother marking VCPU_REG_ERAPS dirty, SVM will take
-                * care of doing so when emulating the full guest TLB flush
-                * (the RAP is cleared on all implicit TLB flushes).
-                */
                kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
                return kvm_skip_emulated_instruction(vcpu);
 


> Centralizing the ERAPS dirty call in svm_flush_tlb_asid() ensures that all
> ASID flushes (flush_tlb_current, flush_tlb_all, flush_tlb_guest) properly
> set ERAP_CONTROL_CLEAR_RAP on the next VMRUN.
> 
> Remove the now redundant svm_flush_tlb_guest() wrapper.
> 
> Fixes: db5e82496492 ("KVM: SVM: Virtualize and advertise support for ERAPS")
> Assisted-by: Gemini:Gemini-Next
> Signed-off-by: Jim Mattson <jmattson@google.com>
> ---
>  arch/x86/kvm/svm/svm.c | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index bf868da14cd2..f2fdca341dac 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4171,6 +4171,8 @@ static void svm_flush_tlb_asid(struct kvm_vcpu *vcpu)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
>  
> +	kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS);
> +
>  	/*
>  	 * Unlike VMX, SVM doesn't provide a way to flush only NPT TLB entries.
>  	 * A TLB flush for the current ASID flushes both "host" and "guest" TLB
> @@ -4229,13 +4231,6 @@ static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)
>  	invlpga(gva, svm->vmcb->control.asid);
>  }
>  
> -static void svm_flush_tlb_guest(struct kvm_vcpu *vcpu)
> -{
> -	kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS);
> -
> -	svm_flush_tlb_asid(vcpu);
> -}
> -
>  static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
> @@ -5383,7 +5378,7 @@ struct kvm_x86_ops svm_x86_ops __initdata = {
>  	.flush_tlb_all = svm_flush_tlb_all,
>  	.flush_tlb_current = svm_flush_tlb_current,
>  	.flush_tlb_gva = svm_flush_tlb_gva,
> -	.flush_tlb_guest = svm_flush_tlb_guest,
> +	.flush_tlb_guest = svm_flush_tlb_asid,
>  
>  	.vcpu_pre_run = svm_vcpu_pre_run,
>  	.vcpu_run = svm_vcpu_run,
> -- 
> 2.55.0.229.g6434b31f56-goog
> 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] KVM: x86: Flush guest TLB on MTRR MSR writes
  2026-07-17 23:05 ` [PATCH v2 3/3] KVM: x86: Flush guest TLB on MTRR MSR writes Jim Mattson
@ 2026-07-20 15:46   ` Sean Christopherson
  0 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2026-07-20 15:46 UTC (permalink / raw)
  To: Jim Mattson; +Cc: amit.shah, kvm, pbonzini, venkateshs, yosry

On Fri, Jul 17, 2026, Jim Mattson wrote:
> Per both the AMD APM and the Intel SDM, writing to an MTRR with WRMSR is an
> implicit TLB invalidation that invalidates all TLB entries (including
> global entries). [The APM uses the word, "update," which could be construed
> to mean "modify," but it is unclear.]

Yeesh, the SDM isn't very helpful.  Under the description of WRMSR, it very clearly
says:

  When the WRMSR instruction is used to write to an MTRR, the TLBs are invalidated.

But then in the recommended pseudocode, the SDM says software should flush TLBs:

  pre_mtrr_change()
    BEGIN
      disable interrupts;
      Save current value of CR4;
      disable and flush caches;
      flush TLBs;
      disable MTRRs;
      IF multiprocessing
        THEN maintain consistency through IPIs;
      FI;
    END
  
  post_mtrr_change()
    BEGIN
      flush caches and TLBs;
      enable MTRRs;
      enable caches;
      restore value of CR4;
      enable interrupts;
    END

> Previously, kvm_mtrr_set_msr() stored the updated MTRR state without
> requesting a TLB flush. This broke x86 architectural compliance by leaving
> existing TLB entries in hardware. Additionally, on AMD CPUs supporting
> ERAPS, omitting the TLB flush request meant VCPU_REG_ERAPS was never
> dirtied on MTRR writes, leaving the Return Address Predictor (RAP/RSB)
> uncleared.

Heh, Andy Cooper even pointed out the implicit flushes on MTRR writes[1], and no
one noticed KVM was missing that specific flush.  I mention that mostly because
the context of that thread was asking AMD to drop the statement that the RAP is
cleared on writes to "other model specific MSRs, see NDA docs", so that hypervisors
wouldn't have to clear the RAP on every WRMSR.

AMD updated their documentation[2] to say that clears on MSR writes are considered
microarchitectural, but this patch and the above blurb are still accurate because
MTRR writes are covered by the "implicit TLB flush" clause, not the generic WRMSR
clause.

[1] https://lore.kernel.org/all/1c76cb00-1fe1-4fd0-b7b9-86ddca6115ba@citrix.com
[2] https://lore.kernel.org/all/08826b5879e2d9c354424279763d3ce5556f44cc.camel@amd.com

> Issue a KVM_REQ_TLB_FLUSH_GUEST request on every MTRR MSR write to match
> x86 architectural semantics.
> 
> Fixes: 9ba075a664df ("KVM: MTRR support")
> Assisted-by: Gemini:Gemini-Next
> Signed-off-by: Jim Mattson <jmattson@google.com>
> ---
>  arch/x86/kvm/mtrr.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
> index 6f74e2b27c1e..ca5e5c7f7022 100644
> --- a/arch/x86/kvm/mtrr.c
> +++ b/arch/x86/kvm/mtrr.c
> @@ -105,6 +105,7 @@ int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
>  		return 1;
>  
>  	*mtrr = data;
> +	kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
>  	return 0;
>  }
>  
> -- 
> 2.55.0.229.g6434b31f56-goog
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid()
  2026-07-17 23:05 ` [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() Jim Mattson
@ 2026-07-20 15:52   ` Sean Christopherson
  2026-07-20 16:12     ` Sean Christopherson
  0 siblings, 1 reply; 9+ messages in thread
From: Sean Christopherson @ 2026-07-20 15:52 UTC (permalink / raw)
  To: Jim Mattson; +Cc: amit.shah, kvm, pbonzini, venkateshs, yosry

On Fri, Jul 17, 2026, Jim Mattson wrote:
> On initial vCPU creation, init_vmcb() is called before userspace configures
> guest CPUID via KVM_SET_CPUID2. Consequently, ERAP_CONTROL_ALLOW_LARGER_RAP
> is never set during initial vCPU creation. If an AP later receives an INIT
> signal after CPUID has been set, init_vmcb() would set the bit for that AP,
> but the BSP would be left with ALLOW_LARGER_RAP clear.
> 
> Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() to handle the BSP.
> 
> Keep the code in init_vmcb() to restore ALLOW_LARGER_RAP after the VMCB has
> been cleared on the VCPU triple-fault reset path.
> 
> Fixes: db5e82496492 ("KVM: SVM: Virtualize and advertise support for ERAPS")
> Assisted-by: Gemini:Gemini-Next
> Signed-off-by: Jim Mattson <jmattson@google.com>
> ---
>  arch/x86/kvm/svm/svm.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 4d2bacd00ec4..bf868da14cd2 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4736,6 +4736,11 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
>  	if (guest_cpuid_is_intel_compatible(vcpu))
>  		guest_cpu_cap_clear(vcpu, X86_FEATURE_V_VMSAVE_VMLOAD);
>  
> +	if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS))
> +		svm->vmcb01.ptr->control.erap_ctl |= ERAP_CONTROL_ALLOW_LARGER_RAP;
> +	else
> +		svm->vmcb01.ptr->control.erap_ctl &= ~ERAP_CONTROL_ALLOW_LARGER_RAP;

If we handle ERAPS here, can't we drop the code in init_vmcb()?  In the context
of PML enablement, AMD is updating the APM to clarify that the control area remains
valid after shutdown, i.e. KVM doesn't need to re-initialize erap_ctl when
synthesizing INIT from shutdown_interception().

  "After an intercepted shutdown, the VMCB control area is valid (with the
   exception of offsets 60h, 61h, and 68h) and the VMCB state save area is
   undefined."

https://lore.kernel.org/all/6688fe2e-c723-404a-80e1-3f4c5f5cc4c6@amd.com


> +
>  	if (is_sev_guest(vcpu))
>  		sev_vcpu_after_set_cpuid(svm);
>  }
> -- 
> 2.55.0.229.g6434b31f56-goog
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid()
  2026-07-20 15:52   ` Sean Christopherson
@ 2026-07-20 16:12     ` Sean Christopherson
  0 siblings, 0 replies; 9+ messages in thread
From: Sean Christopherson @ 2026-07-20 16:12 UTC (permalink / raw)
  To: Jim Mattson; +Cc: amit.shah, kvm, pbonzini, venkateshs, yosry

On Mon, Jul 20, 2026, Sean Christopherson wrote:
> On Fri, Jul 17, 2026, Jim Mattson wrote:
> > On initial vCPU creation, init_vmcb() is called before userspace configures
> > guest CPUID via KVM_SET_CPUID2. Consequently, ERAP_CONTROL_ALLOW_LARGER_RAP
> > is never set during initial vCPU creation. If an AP later receives an INIT
> > signal after CPUID has been set, init_vmcb() would set the bit for that AP,
> > but the BSP would be left with ALLOW_LARGER_RAP clear.
> > 
> > Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() to handle the BSP.
> > 
> > Keep the code in init_vmcb() to restore ALLOW_LARGER_RAP after the VMCB has
> > been cleared on the VCPU triple-fault reset path.
> > 
> > Fixes: db5e82496492 ("KVM: SVM: Virtualize and advertise support for ERAPS")
> > Assisted-by: Gemini:Gemini-Next
> > Signed-off-by: Jim Mattson <jmattson@google.com>
> > ---
> >  arch/x86/kvm/svm/svm.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> > index 4d2bacd00ec4..bf868da14cd2 100644
> > --- a/arch/x86/kvm/svm/svm.c
> > +++ b/arch/x86/kvm/svm/svm.c
> > @@ -4736,6 +4736,11 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
> >  	if (guest_cpuid_is_intel_compatible(vcpu))
> >  		guest_cpu_cap_clear(vcpu, X86_FEATURE_V_VMSAVE_VMLOAD);
> >  
> > +	if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS))
> > +		svm->vmcb01.ptr->control.erap_ctl |= ERAP_CONTROL_ALLOW_LARGER_RAP;
> > +	else
> > +		svm->vmcb01.ptr->control.erap_ctl &= ~ERAP_CONTROL_ALLOW_LARGER_RAP;
> 
> If we handle ERAPS here, can't we drop the code in init_vmcb()?  In the context
> of PML enablement, AMD is updating the APM to clarify that the control area remains
> valid after shutdown, i.e. KVM doesn't need to re-initialize erap_ctl when
> synthesizing INIT from shutdown_interception().
> 
>   "After an intercepted shutdown, the VMCB control area is valid (with the
>    exception of offsets 60h, 61h, and 68h) and the VMCB state save area is
>    undefined."
> 
> https://lore.kernel.org/all/6688fe2e-c723-404a-80e1-3f4c5f5cc4c6@amd.com

LOL, nice, I just saw the Sashiko report from v1.  I think the way to handle this
is to go with this version, and then rework shutdown_interception() as part of PML
enablement to not clear the entire page, only the contents that may be corrupted.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes
  2026-07-20 15:33   ` Sean Christopherson
@ 2026-07-20 16:41     ` Jim Mattson
  0 siblings, 0 replies; 9+ messages in thread
From: Jim Mattson @ 2026-07-20 16:41 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: amit.shah, kvm, pbonzini, venkateshs, yosry

On Mon, Jul 20, 2026 at 8:33 AM Sean Christopherson <seanjc@google.com> wrote:
>
> On Fri, Jul 17, 2026, Jim Mattson wrote:
> > Per the AMD APM, ERAPS clears the Return Address Predictor (RAP/RSB) on all
> > implicit TLB invalidations (e.g. modifying certain CR[04] bits).
> >
> > Move kvm_register_mark_dirty(vcpu, VCPU_REG_ERAPS) into
> > svm_flush_tlb_asid() so that any ASID-level TLB flush marks ERAPS dirty.
>
> NAK, the whole point of KVM_REQ_TLB_FLUSH_GUEST is emulate TLB invalidations in
> the guest's domain.  If we're missing KVM_REQ_TLB_FLUSH_GUEST requests, fix those.
>
> I think we're missing a clear on the MOV CR3 flush when TDP is disabled?  Beyond
> that, nothing jumps out.

Yes, I think that's it.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-07-20 16:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-17 23:05 [PATCH v2 0/3] KVM: x86/SVM: Fixes for AMD ERAPS virtualization Jim Mattson
2026-07-17 23:05 ` [PATCH v2 1/3] KVM: SVM: Configure ALLOW_LARGER_RAP in svm_vcpu_after_set_cpuid() Jim Mattson
2026-07-20 15:52   ` Sean Christopherson
2026-07-20 16:12     ` Sean Christopherson
2026-07-17 23:05 ` [PATCH v2 2/3] KVM: SVM: Dirty ERAPS register on all ASID TLB flushes Jim Mattson
2026-07-20 15:33   ` Sean Christopherson
2026-07-20 16:41     ` Jim Mattson
2026-07-17 23:05 ` [PATCH v2 3/3] KVM: x86: Flush guest TLB on MTRR MSR writes Jim Mattson
2026-07-20 15:46   ` Sean Christopherson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.