x86/sev: Carve out HV call's return value verification
authorBorislav Petkov <bp@suse.de>
Fri, 1 Oct 2021 09:41:05 +0000 (11:41 +0200)
committerBorislav Petkov <bp@suse.de>
Tue, 19 Oct 2021 11:54:47 +0000 (13:54 +0200)
Carve out the verification of the HV call return value into a separate
helper and make it more readable.

No functional changes.

Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/YVbYWz%2B8J7iMTJjc@zn.tnic
arch/x86/kernel/sev-shared.c

index bf1033a62e4806a64a430075fc5b06540f554010..4579c38a11c4df5f1307edd980e575f28df63010 100644 (file)
@@ -94,25 +94,15 @@ static void vc_finish_insn(struct es_em_ctxt *ctxt)
        ctxt->regs->ip += ctxt->insn.length;
 }
 
-static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
-                                         struct es_em_ctxt *ctxt,
-                                         u64 exit_code, u64 exit_info_1,
-                                         u64 exit_info_2)
+static enum es_result verify_exception_info(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
 {
-       enum es_result ret;
+       u32 ret;
 
-       /* Fill in protocol and format specifiers */
-       ghcb->protocol_version = GHCB_PROTOCOL_MAX;
-       ghcb->ghcb_usage       = GHCB_DEFAULT_USAGE;
+       ret = ghcb->save.sw_exit_info_1 & GENMASK_ULL(31, 0);
+       if (!ret)
+               return ES_OK;
 
-       ghcb_set_sw_exit_code(ghcb, exit_code);
-       ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
-       ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
-
-       sev_es_wr_ghcb_msr(__pa(ghcb));
-       VMGEXIT();
-
-       if ((ghcb->save.sw_exit_info_1 & 0xffffffff) == 1) {
+       if (ret == 1) {
                u64 info = ghcb->save.sw_exit_info_2;
                unsigned long v;
 
@@ -124,19 +114,34 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
                    ((v == X86_TRAP_GP) || (v == X86_TRAP_UD)) &&
                    ((info & SVM_EVTINJ_TYPE_MASK) == SVM_EVTINJ_TYPE_EXEPT)) {
                        ctxt->fi.vector = v;
+
                        if (info & SVM_EVTINJ_VALID_ERR)
                                ctxt->fi.error_code = info >> 32;
-                       ret = ES_EXCEPTION;
-               } else {
-                       ret = ES_VMM_ERROR;
+
+                       return ES_EXCEPTION;
                }
-       } else if (ghcb->save.sw_exit_info_1 & 0xffffffff) {
-               ret = ES_VMM_ERROR;
-       } else {
-               ret = ES_OK;
        }
 
-       return ret;
+       return ES_VMM_ERROR;
+}
+
+static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
+                                         struct es_em_ctxt *ctxt,
+                                         u64 exit_code, u64 exit_info_1,
+                                         u64 exit_info_2)
+{
+       /* Fill in protocol and format specifiers */
+       ghcb->protocol_version = GHCB_PROTOCOL_MAX;
+       ghcb->ghcb_usage       = GHCB_DEFAULT_USAGE;
+
+       ghcb_set_sw_exit_code(ghcb, exit_code);
+       ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
+       ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
+
+       sev_es_wr_ghcb_msr(__pa(ghcb));
+       VMGEXIT();
+
+       return verify_exception_info(ghcb, ctxt);
 }
 
 /*