]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Merge tag 'kvm-x86-svm-6.15' of https://github.com/kvm-x86/linux into HEAD
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 19 Mar 2025 13:10:44 +0000 (09:10 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 19 Mar 2025 13:10:44 +0000 (09:10 -0400)
KVM SVM changes for 6.15

 - Ensure the PSP driver is initialized when both the PSP and KVM modules are
   built-in (the initcall framework doesn't handle dependencies).

 - Use long-term pins when registering encrypted memory regions, so that the
   pages are migrated out of MIGRATE_CMA/ZONE_MOVABLE and don't lead to
   excessive fragmentation.

 - Add macros and helpers for setting GHCB return/error codes.

 - Add support for Idle HLT interception, which elides interception if the vCPU
   has a pending, unmasked virtual IRQ when HLT is executed.

 - Fix a bug in INVPCID emulation where KVM fails to check for a non-canonical
   address.

 - Don't attempt VMRUN for SEV-ES+ guests if the vCPU's VMSA is invalid, e.g.
   because the vCPU was "destroyed" via SNP's AP Creation hypercall.

 - Reject SNP AP Creation if the requested SEV features for the vCPU don't
   match the VM's configured set of features.

 - Misc cleanups

1  2 
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h

index 596167d33544391485b8fb761e33c191672d3f9f,ea50f44a223949ffb87019a17f169e980f828d9e..0bc708ee278877ffa00a26a21e4c948214b4bc8e
@@@ -3911,33 -3876,47 +3876,46 @@@ void sev_snp_init_protected_guest_state
         */
        vmcb_mark_all_dirty(svm->vmcb);
  
-       return 0;
- }
+       if (!VALID_PAGE(svm->sev_es.snp_vmsa_gpa))
+               return;
  
- /*
-  * Invoked as part of svm_vcpu_reset() processing of an init event.
-  */
- void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
- {
-       struct vcpu_svm *svm = to_svm(vcpu);
-       int ret;
+       gfn = gpa_to_gfn(svm->sev_es.snp_vmsa_gpa);
+       svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
  
-       if (!sev_snp_guest(vcpu->kvm))
+       slot = gfn_to_memslot(vcpu->kvm, gfn);
+       if (!slot)
                return;
  
-       mutex_lock(&svm->sev_es.snp_vmsa_mutex);
+       /*
+        * 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, &page, NULL))
+               return;
  
-       if (!svm->sev_es.snp_ap_waiting_for_reset)
-               goto unlock;
+       /*
+        * 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;
  
-       svm->sev_es.snp_ap_waiting_for_reset = false;
+       /* Use the new VMSA */
+       svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
  
-       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 runnable */
 -      vcpu->arch.pv.pv_unhalted = false;
 -      vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
++      kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
  
- unlock:
-       mutex_unlock(&svm->sev_es.snp_vmsa_mutex);
+       /*
+        * 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_page_clean(page);
  }
  
  static int sev_snp_ap_creation(struct vcpu_svm *svm)
Simple merge
Simple merge