]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
KVM: SVM: Add AP_JUMP_TABLE support in prep for AP booting
authorTom Lendacky <thomas.lendacky@amd.com>
Tue, 15 Dec 2020 17:44:07 +0000 (12:44 -0500)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 15 Dec 2020 17:47:53 +0000 (12:47 -0500)
The GHCB specification requires the hypervisor to save the address of an
AP Jump Table so that, for example, vCPUs that have been parked by UEFI
can be started by the OS. Provide support for the AP Jump Table set/get
exit code.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.h

index 6eb097714d43f8bc8f161d4cf1609301ad11045f..8b5ef0fe4490178d0f038b6c254405e3d6259a47 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/trace_events.h>
 #include <asm/fpu/internal.h>
 
+#include <asm/trapnr.h>
+
 #include "x86.h"
 #include "svm.h"
 #include "cpuid.h"
@@ -1559,6 +1561,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
                        goto vmgexit_err;
                break;
        case SVM_VMGEXIT_NMI_COMPLETE:
+       case SVM_VMGEXIT_AP_JUMP_TABLE:
        case SVM_VMGEXIT_UNSUPPORTED_EVENT:
                break;
        default:
@@ -1883,6 +1886,31 @@ int sev_handle_vmgexit(struct vcpu_svm *svm)
        case SVM_VMGEXIT_NMI_COMPLETE:
                ret = svm_invoke_exit_handler(svm, SVM_EXIT_IRET);
                break;
+       case SVM_VMGEXIT_AP_JUMP_TABLE: {
+               struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info;
+
+               switch (control->exit_info_1) {
+               case 0:
+                       /* Set AP jump table address */
+                       sev->ap_jump_table = control->exit_info_2;
+                       break;
+               case 1:
+                       /* Get AP jump table address */
+                       ghcb_set_sw_exit_info_2(ghcb, sev->ap_jump_table);
+                       break;
+               default:
+                       pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n",
+                              control->exit_info_1);
+                       ghcb_set_sw_exit_info_1(ghcb, 1);
+                       ghcb_set_sw_exit_info_2(ghcb,
+                                               X86_TRAP_UD |
+                                               SVM_EVTINJ_TYPE_EXEPT |
+                                               SVM_EVTINJ_VALID);
+               }
+
+               ret = 1;
+               break;
+       }
        case SVM_VMGEXIT_UNSUPPORTED_EVENT:
                vcpu_unimpl(&svm->vcpu,
                            "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n",
index a5067f776ce0c4e64a8822a57dc35998c0dbb9ed..5431e6335e2e8d3ba69cae3a6f71e7ecaafdd32a 100644 (file)
@@ -78,6 +78,7 @@ struct kvm_sev_info {
        int fd;                 /* SEV device fd */
        unsigned long pages_locked; /* Number of pages locked */
        struct list_head regions_list;  /* List of registered regions */
+       u64 ap_jump_table;      /* SEV-ES AP Jump Table address */
 };
 
 struct kvm_svm {