@@ -49,6 +49,10 @@ static bool sev_es_debug_swap_enabled = true;
49
49
module_param_named (debug_swap , sev_es_debug_swap_enabled , bool , 0444 );
50
50
static u64 sev_supported_vmsa_features ;
51
51
52
+ #define AP_RESET_HOLD_NONE 0
53
+ #define AP_RESET_HOLD_NAE_EVENT 1
54
+ #define AP_RESET_HOLD_MSR_PROTO 2
55
+
52
56
static u8 sev_enc_bit ;
53
57
static DECLARE_RWSEM (sev_deactivate_lock );
54
58
static DEFINE_MUTEX (sev_bitmap_lock );
@@ -2727,6 +2731,9 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
2727
2731
2728
2732
void sev_es_unmap_ghcb (struct vcpu_svm * svm )
2729
2733
{
2734
+ /* Clear any indication that the vCPU is in a type of AP Reset Hold */
2735
+ svm -> sev_es .ap_reset_hold_type = AP_RESET_HOLD_NONE ;
2736
+
2730
2737
if (!svm -> sev_es .ghcb )
2731
2738
return ;
2732
2739
@@ -2938,6 +2945,22 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
2938
2945
GHCB_MSR_INFO_POS );
2939
2946
break ;
2940
2947
}
2948
+ case GHCB_MSR_AP_RESET_HOLD_REQ :
2949
+ svm -> sev_es .ap_reset_hold_type = AP_RESET_HOLD_MSR_PROTO ;
2950
+ ret = kvm_emulate_ap_reset_hold (& svm -> vcpu );
2951
+
2952
+ /*
2953
+ * Preset the result to a non-SIPI return and then only set
2954
+ * the result to non-zero when delivering a SIPI.
2955
+ */
2956
+ set_ghcb_msr_bits (svm , 0 ,
2957
+ GHCB_MSR_AP_RESET_HOLD_RESULT_MASK ,
2958
+ GHCB_MSR_AP_RESET_HOLD_RESULT_POS );
2959
+
2960
+ set_ghcb_msr_bits (svm , GHCB_MSR_AP_RESET_HOLD_RESP ,
2961
+ GHCB_MSR_INFO_MASK ,
2962
+ GHCB_MSR_INFO_POS );
2963
+ break ;
2941
2964
case GHCB_MSR_TERM_REQ : {
2942
2965
u64 reason_set , reason_code ;
2943
2966
@@ -3037,6 +3060,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
3037
3060
ret = 1 ;
3038
3061
break ;
3039
3062
case SVM_VMGEXIT_AP_HLT_LOOP :
3063
+ svm -> sev_es .ap_reset_hold_type = AP_RESET_HOLD_NAE_EVENT ;
3040
3064
ret = kvm_emulate_ap_reset_hold (vcpu );
3041
3065
break ;
3042
3066
case SVM_VMGEXIT_AP_JUMP_TABLE : {
@@ -3280,15 +3304,31 @@ void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
3280
3304
return ;
3281
3305
}
3282
3306
3283
- /*
3284
- * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where
3285
- * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a
3286
- * non-zero value.
3287
- */
3288
- if (!svm -> sev_es .ghcb )
3289
- return ;
3307
+ /* Subsequent SIPI */
3308
+ switch (svm -> sev_es .ap_reset_hold_type ) {
3309
+ case AP_RESET_HOLD_NAE_EVENT :
3310
+ /*
3311
+ * Return from an AP Reset Hold VMGEXIT, where the guest will
3312
+ * set the CS and RIP. Set SW_EXIT_INFO_2 to a non-zero value.
3313
+ */
3314
+ ghcb_set_sw_exit_info_2 (svm -> sev_es .ghcb , 1 );
3315
+ break ;
3316
+ case AP_RESET_HOLD_MSR_PROTO :
3317
+ /*
3318
+ * Return from an AP Reset Hold VMGEXIT, where the guest will
3319
+ * set the CS and RIP. Set GHCB data field to a non-zero value.
3320
+ */
3321
+ set_ghcb_msr_bits (svm , 1 ,
3322
+ GHCB_MSR_AP_RESET_HOLD_RESULT_MASK ,
3323
+ GHCB_MSR_AP_RESET_HOLD_RESULT_POS );
3290
3324
3291
- ghcb_set_sw_exit_info_2 (svm -> sev_es .ghcb , 1 );
3325
+ set_ghcb_msr_bits (svm , GHCB_MSR_AP_RESET_HOLD_RESP ,
3326
+ GHCB_MSR_INFO_MASK ,
3327
+ GHCB_MSR_INFO_POS );
3328
+ break ;
3329
+ default :
3330
+ break ;
3331
+ }
3292
3332
}
3293
3333
3294
3334
struct page * snp_safe_alloc_page (struct kvm_vcpu * vcpu )
0 commit comments