@@ -648,7 +648,8 @@ static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
648648 ghcb_set_rdx (ghcb , regs -> dx );
649649 }
650650
651- ret = sev_es_ghcb_hv_call (ghcb , ctxt , SVM_EXIT_MSR , exit_info_1 , 0 );
651+ ret = sev_es_ghcb_hv_call (ghcb , true, ctxt , SVM_EXIT_MSR ,
652+ exit_info_1 , 0 );
652653
653654 if ((ret == ES_OK ) && (!exit_info_1 )) {
654655 regs -> ax = ghcb -> save .rax ;
@@ -867,7 +868,7 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
867868
868869 ghcb_set_sw_scratch (ghcb , ghcb_pa + offsetof(struct ghcb , shared_buffer ));
869870
870- return sev_es_ghcb_hv_call (ghcb , ctxt , exit_code , exit_info_1 , exit_info_2 );
871+ return sev_es_ghcb_hv_call (ghcb , true, ctxt , exit_code , exit_info_1 , exit_info_2 );
871872}
872873
873874static enum es_result vc_handle_mmio_twobyte_ops (struct ghcb * ghcb ,
@@ -1117,7 +1118,7 @@ static enum es_result vc_handle_dr7_write(struct ghcb *ghcb,
11171118
11181119 /* Using a value of 0 for ExitInfo1 means RAX holds the value */
11191120 ghcb_set_rax (ghcb , val );
1120- ret = sev_es_ghcb_hv_call (ghcb , ctxt , SVM_EXIT_WRITE_DR7 , 0 , 0 );
1121+ ret = sev_es_ghcb_hv_call (ghcb , true, ctxt , SVM_EXIT_WRITE_DR7 , 0 , 0 );
11211122 if (ret != ES_OK )
11221123 return ret ;
11231124
@@ -1147,7 +1148,7 @@ static enum es_result vc_handle_dr7_read(struct ghcb *ghcb,
11471148static enum es_result vc_handle_wbinvd (struct ghcb * ghcb ,
11481149 struct es_em_ctxt * ctxt )
11491150{
1150- return sev_es_ghcb_hv_call (ghcb , ctxt , SVM_EXIT_WBINVD , 0 , 0 );
1151+ return sev_es_ghcb_hv_call (ghcb , true, ctxt , SVM_EXIT_WBINVD , 0 , 0 );
11511152}
11521153
11531154static enum es_result vc_handle_rdpmc (struct ghcb * ghcb , struct es_em_ctxt * ctxt )
@@ -1156,7 +1157,7 @@ static enum es_result vc_handle_rdpmc(struct ghcb *ghcb, struct es_em_ctxt *ctxt
11561157
11571158 ghcb_set_rcx (ghcb , ctxt -> regs -> cx );
11581159
1159- ret = sev_es_ghcb_hv_call (ghcb , ctxt , SVM_EXIT_RDPMC , 0 , 0 );
1160+ ret = sev_es_ghcb_hv_call (ghcb , true, ctxt , SVM_EXIT_RDPMC , 0 , 0 );
11601161 if (ret != ES_OK )
11611162 return ret ;
11621163
@@ -1197,7 +1198,7 @@ static enum es_result vc_handle_vmmcall(struct ghcb *ghcb,
11971198 if (x86_platform .hyper .sev_es_hcall_prepare )
11981199 x86_platform .hyper .sev_es_hcall_prepare (ghcb , ctxt -> regs );
11991200
1200- ret = sev_es_ghcb_hv_call (ghcb , ctxt , SVM_EXIT_VMMCALL , 0 , 0 );
1201+ ret = sev_es_ghcb_hv_call (ghcb , true, ctxt , SVM_EXIT_VMMCALL , 0 , 0 );
12011202 if (ret != ES_OK )
12021203 return ret ;
12031204
@@ -1319,13 +1320,26 @@ static __always_inline void vc_forward_exception(struct es_em_ctxt *ctxt)
13191320 }
13201321}
13211322
1322- static __always_inline bool on_vc_fallback_stack ( struct pt_regs * regs )
1323+ static __always_inline bool is_vc2_stack ( unsigned long sp )
13231324{
1324- unsigned long sp = (unsigned long )regs ;
1325-
13261325 return (sp >= __this_cpu_ist_bottom_va (VC2 ) && sp < __this_cpu_ist_top_va (VC2 ));
13271326}
13281327
1328+ static __always_inline bool vc_from_invalid_context (struct pt_regs * regs )
1329+ {
1330+ unsigned long sp , prev_sp ;
1331+
1332+ sp = (unsigned long )regs ;
1333+ prev_sp = regs -> sp ;
1334+
1335+ /*
1336+ * If the code was already executing on the VC2 stack when the #VC
1337+ * happened, let it proceed to the normal handling routine. This way the
1338+ * code executing on the VC2 stack can cause #VC exceptions to get handled.
1339+ */
1340+ return is_vc2_stack (sp ) && !is_vc2_stack (prev_sp );
1341+ }
1342+
13291343static bool vc_raw_handle_exception (struct pt_regs * regs , unsigned long error_code )
13301344{
13311345 struct ghcb_state state ;
@@ -1406,7 +1420,7 @@ DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_communication)
14061420 * But keep this here in case the noinstr annotations are violated due
14071421 * to bug elsewhere.
14081422 */
1409- if (unlikely (on_vc_fallback_stack (regs ))) {
1423+ if (unlikely (vc_from_invalid_context (regs ))) {
14101424 instrumentation_begin ();
14111425 panic ("Can't handle #VC exception from unsupported context\n" );
14121426 instrumentation_end ();
0 commit comments