]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: SVM: Update dump_ghcb() to use the GHCB snapshot fields
authorTom Lendacky <thomas.lendacky@amd.com>
Mon, 28 Apr 2025 18:55:31 +0000 (13:55 -0500)
committerSean Christopherson <seanjc@google.com>
Fri, 2 May 2025 20:39:33 +0000 (13:39 -0700)
Commit 4e15a0ddc3ff ("KVM: SEV: snapshot the GHCB before accessing it")
updated the SEV code to take a snapshot of the GHCB before using it. But
the dump_ghcb() function wasn't updated to use the snapshot locations.
This results in incorrect output from dump_ghcb() for the "is_valid" and
"valid_bitmap" fields.

Update dump_ghcb() to use the proper locations.

Fixes: 4e15a0ddc3ff ("KVM: SEV: snapshot the GHCB before accessing it")
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
Link: https://lore.kernel.org/r/8f03878443681496008b1b37b7c4bf77a342b459.1745866531.git.thomas.lendacky@amd.com
[sean: add comment and snapshot qualifier]
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/sev.c

index 0bc708ee278877ffa00a26a21e4c948214b4bc8e..a7a7dc5073363bafc436f304cb75f186fb564078 100644 (file)
@@ -3173,9 +3173,14 @@ skip_vmsa_free:
                kvfree(svm->sev_es.ghcb_sa);
 }
 
+static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control)
+{
+       return (((u64)control->exit_code_hi) << 32) | control->exit_code;
+}
+
 static void dump_ghcb(struct vcpu_svm *svm)
 {
-       struct ghcb *ghcb = svm->sev_es.ghcb;
+       struct vmcb_control_area *control = &svm->vmcb->control;
        unsigned int nbits;
 
        /* Re-use the dump_invalid_vmcb module parameter */
@@ -3184,18 +3189,24 @@ static void dump_ghcb(struct vcpu_svm *svm)
                return;
        }
 
-       nbits = sizeof(ghcb->save.valid_bitmap) * 8;
+       nbits = sizeof(svm->sev_es.valid_bitmap) * 8;
 
-       pr_err("GHCB (GPA=%016llx):\n", svm->vmcb->control.ghcb_gpa);
+       /*
+        * Print KVM's snapshot of the GHCB values that were (unsuccessfully)
+        * used to handle the exit.  If the guest has since modified the GHCB
+        * itself, dumping the raw GHCB won't help debug why KVM was unable to
+        * handle the VMGEXIT that KVM observed.
+        */
+       pr_err("GHCB (GPA=%016llx) snapshot:\n", svm->vmcb->control.ghcb_gpa);
        pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_code",
-              ghcb->save.sw_exit_code, ghcb_sw_exit_code_is_valid(ghcb));
+              kvm_ghcb_get_sw_exit_code(control), kvm_ghcb_sw_exit_code_is_valid(svm));
        pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_1",
-              ghcb->save.sw_exit_info_1, ghcb_sw_exit_info_1_is_valid(ghcb));
+              control->exit_info_1, kvm_ghcb_sw_exit_info_1_is_valid(svm));
        pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_2",
-              ghcb->save.sw_exit_info_2, ghcb_sw_exit_info_2_is_valid(ghcb));
+              control->exit_info_2, kvm_ghcb_sw_exit_info_2_is_valid(svm));
        pr_err("%-20s%016llx is_valid: %u\n", "sw_scratch",
-              ghcb->save.sw_scratch, ghcb_sw_scratch_is_valid(ghcb));
-       pr_err("%-20s%*pb\n", "valid_bitmap", nbits, ghcb->save.valid_bitmap);
+              svm->sev_es.sw_scratch, kvm_ghcb_sw_scratch_is_valid(svm));
+       pr_err("%-20s%*pb\n", "valid_bitmap", nbits, svm->sev_es.valid_bitmap);
 }
 
 static void sev_es_sync_to_ghcb(struct vcpu_svm *svm)
@@ -3266,11 +3277,6 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
        memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
 }
 
-static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control)
-{
-       return (((u64)control->exit_code_hi) << 32) | control->exit_code;
-}
-
 static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
 {
        struct vmcb_control_area *control = &svm->vmcb->control;