33
33
#include "cpuid.h"
34
34
#include "trace.h"
35
35
36
- #define GHCB_VERSION_MAX 1ULL
36
+ #define GHCB_VERSION_MAX 2ULL
37
+ #define GHCB_VERSION_DEFAULT 2ULL
37
38
#define GHCB_VERSION_MIN 1ULL
38
39
40
+ #define GHCB_HV_FT_SUPPORTED GHCB_HV_FT_SNP
41
+
39
42
/* enable/disable SEV support */
40
43
static bool sev_enabled = true;
41
44
module_param_named (sev , sev_enabled , bool , 0444 );
@@ -49,6 +52,10 @@ static bool sev_es_debug_swap_enabled = true;
49
52
module_param_named (debug_swap , sev_es_debug_swap_enabled , bool , 0444 );
50
53
static u64 sev_supported_vmsa_features ;
51
54
55
+ #define AP_RESET_HOLD_NONE 0
56
+ #define AP_RESET_HOLD_NAE_EVENT 1
57
+ #define AP_RESET_HOLD_MSR_PROTO 2
58
+
52
59
static u8 sev_enc_bit ;
53
60
static DECLARE_RWSEM (sev_deactivate_lock );
54
61
static DEFINE_MUTEX (sev_bitmap_lock );
@@ -262,12 +269,24 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
262
269
if (data -> vmsa_features & ~valid_vmsa_features )
263
270
return - EINVAL ;
264
271
272
+ if (data -> ghcb_version > GHCB_VERSION_MAX || (!es_active && data -> ghcb_version ))
273
+ return - EINVAL ;
274
+
265
275
if (unlikely (sev -> active ))
266
276
return - EINVAL ;
267
277
268
278
sev -> active = true;
269
279
sev -> es_active = es_active ;
270
280
sev -> vmsa_features = data -> vmsa_features ;
281
+ sev -> ghcb_version = data -> ghcb_version ;
282
+
283
+ /*
284
+ * Currently KVM supports the full range of mandatory features defined
285
+ * by version 2 of the GHCB protocol, so default to that for SEV-ES
286
+ * guests created via KVM_SEV_INIT2.
287
+ */
288
+ if (sev -> es_active && !sev -> ghcb_version )
289
+ sev -> ghcb_version = GHCB_VERSION_DEFAULT ;
271
290
272
291
ret = sev_asid_new (sev );
273
292
if (ret )
@@ -301,13 +320,22 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
301
320
{
302
321
struct kvm_sev_init data = {
303
322
.vmsa_features = 0 ,
323
+ .ghcb_version = 0 ,
304
324
};
305
325
unsigned long vm_type ;
306
326
307
327
if (kvm -> arch .vm_type != KVM_X86_DEFAULT_VM )
308
328
return - EINVAL ;
309
329
310
330
vm_type = (argp -> id == KVM_SEV_INIT ? KVM_X86_SEV_VM : KVM_X86_SEV_ES_VM );
331
+
332
+ /*
333
+ * KVM_SEV_ES_INIT has been deprecated by KVM_SEV_INIT2, so it will
334
+ * continue to only ever support the minimal GHCB protocol version.
335
+ */
336
+ if (vm_type == KVM_X86_SEV_ES_VM )
337
+ data .ghcb_version = GHCB_VERSION_MIN ;
338
+
311
339
return __sev_guest_init (kvm , argp , & data , vm_type );
312
340
}
313
341
@@ -2697,6 +2725,8 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
2697
2725
case SVM_VMGEXIT_AP_HLT_LOOP :
2698
2726
case SVM_VMGEXIT_AP_JUMP_TABLE :
2699
2727
case SVM_VMGEXIT_UNSUPPORTED_EVENT :
2728
+ case SVM_VMGEXIT_HV_FEATURES :
2729
+ case SVM_VMGEXIT_TERM_REQUEST :
2700
2730
break ;
2701
2731
default :
2702
2732
reason = GHCB_ERR_INVALID_EVENT ;
@@ -2727,6 +2757,9 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
2727
2757
2728
2758
void sev_es_unmap_ghcb (struct vcpu_svm * svm )
2729
2759
{
2760
+ /* Clear any indication that the vCPU is in a type of AP Reset Hold */
2761
+ svm -> sev_es .ap_reset_hold_type = AP_RESET_HOLD_NONE ;
2762
+
2730
2763
if (!svm -> sev_es .ghcb )
2731
2764
return ;
2732
2765
@@ -2886,6 +2919,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
2886
2919
{
2887
2920
struct vmcb_control_area * control = & svm -> vmcb -> control ;
2888
2921
struct kvm_vcpu * vcpu = & svm -> vcpu ;
2922
+ struct kvm_sev_info * sev = & to_kvm_svm (vcpu -> kvm )-> sev_info ;
2889
2923
u64 ghcb_info ;
2890
2924
int ret = 1 ;
2891
2925
@@ -2896,7 +2930,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
2896
2930
2897
2931
switch (ghcb_info ) {
2898
2932
case GHCB_MSR_SEV_INFO_REQ :
2899
- set_ghcb_msr (svm , GHCB_MSR_SEV_INFO (GHCB_VERSION_MAX ,
2933
+ set_ghcb_msr (svm , GHCB_MSR_SEV_INFO (( __u64 ) sev -> ghcb_version ,
2900
2934
GHCB_VERSION_MIN ,
2901
2935
sev_enc_bit ));
2902
2936
break ;
@@ -2938,6 +2972,28 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
2938
2972
GHCB_MSR_INFO_POS );
2939
2973
break ;
2940
2974
}
2975
+ case GHCB_MSR_AP_RESET_HOLD_REQ :
2976
+ svm -> sev_es .ap_reset_hold_type = AP_RESET_HOLD_MSR_PROTO ;
2977
+ ret = kvm_emulate_ap_reset_hold (& svm -> vcpu );
2978
+
2979
+ /*
2980
+ * Preset the result to a non-SIPI return and then only set
2981
+ * the result to non-zero when delivering a SIPI.
2982
+ */
2983
+ set_ghcb_msr_bits (svm , 0 ,
2984
+ GHCB_MSR_AP_RESET_HOLD_RESULT_MASK ,
2985
+ GHCB_MSR_AP_RESET_HOLD_RESULT_POS );
2986
+
2987
+ set_ghcb_msr_bits (svm , GHCB_MSR_AP_RESET_HOLD_RESP ,
2988
+ GHCB_MSR_INFO_MASK ,
2989
+ GHCB_MSR_INFO_POS );
2990
+ break ;
2991
+ case GHCB_MSR_HV_FT_REQ :
2992
+ set_ghcb_msr_bits (svm , GHCB_HV_FT_SUPPORTED ,
2993
+ GHCB_MSR_HV_FT_MASK , GHCB_MSR_HV_FT_POS );
2994
+ set_ghcb_msr_bits (svm , GHCB_MSR_HV_FT_RESP ,
2995
+ GHCB_MSR_INFO_MASK , GHCB_MSR_INFO_POS );
2996
+ break ;
2941
2997
case GHCB_MSR_TERM_REQ : {
2942
2998
u64 reason_set , reason_code ;
2943
2999
@@ -3037,6 +3093,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
3037
3093
ret = 1 ;
3038
3094
break ;
3039
3095
case SVM_VMGEXIT_AP_HLT_LOOP :
3096
+ svm -> sev_es .ap_reset_hold_type = AP_RESET_HOLD_NAE_EVENT ;
3040
3097
ret = kvm_emulate_ap_reset_hold (vcpu );
3041
3098
break ;
3042
3099
case SVM_VMGEXIT_AP_JUMP_TABLE : {
@@ -3061,6 +3118,19 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
3061
3118
ret = 1 ;
3062
3119
break ;
3063
3120
}
3121
+ case SVM_VMGEXIT_HV_FEATURES :
3122
+ ghcb_set_sw_exit_info_2 (svm -> sev_es .ghcb , GHCB_HV_FT_SUPPORTED );
3123
+
3124
+ ret = 1 ;
3125
+ break ;
3126
+ case SVM_VMGEXIT_TERM_REQUEST :
3127
+ pr_info ("SEV-ES guest requested termination: reason %#llx info %#llx\n" ,
3128
+ control -> exit_info_1 , control -> exit_info_2 );
3129
+ vcpu -> run -> exit_reason = KVM_EXIT_SYSTEM_EVENT ;
3130
+ vcpu -> run -> system_event .type = KVM_SYSTEM_EVENT_SEV_TERM ;
3131
+ vcpu -> run -> system_event .ndata = 1 ;
3132
+ vcpu -> run -> system_event .data [0 ] = control -> ghcb_gpa ;
3133
+ break ;
3064
3134
case SVM_VMGEXIT_UNSUPPORTED_EVENT :
3065
3135
vcpu_unimpl (vcpu ,
3066
3136
"vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n" ,
@@ -3221,11 +3291,14 @@ void sev_init_vmcb(struct vcpu_svm *svm)
3221
3291
3222
3292
void sev_es_vcpu_reset (struct vcpu_svm * svm )
3223
3293
{
3294
+ struct kvm_vcpu * vcpu = & svm -> vcpu ;
3295
+ struct kvm_sev_info * sev = & to_kvm_svm (vcpu -> kvm )-> sev_info ;
3296
+
3224
3297
/*
3225
3298
* Set the GHCB MSR value as per the GHCB specification when emulating
3226
3299
* vCPU RESET for an SEV-ES guest.
3227
3300
*/
3228
- set_ghcb_msr (svm , GHCB_MSR_SEV_INFO (GHCB_VERSION_MAX ,
3301
+ set_ghcb_msr (svm , GHCB_MSR_SEV_INFO (( __u64 ) sev -> ghcb_version ,
3229
3302
GHCB_VERSION_MIN ,
3230
3303
sev_enc_bit ));
3231
3304
}
@@ -3280,15 +3353,31 @@ void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
3280
3353
return ;
3281
3354
}
3282
3355
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 ;
3356
+ /* Subsequent SIPI */
3357
+ switch (svm -> sev_es .ap_reset_hold_type ) {
3358
+ case AP_RESET_HOLD_NAE_EVENT :
3359
+ /*
3360
+ * Return from an AP Reset Hold VMGEXIT, where the guest will
3361
+ * set the CS and RIP. Set SW_EXIT_INFO_2 to a non-zero value.
3362
+ */
3363
+ ghcb_set_sw_exit_info_2 (svm -> sev_es .ghcb , 1 );
3364
+ break ;
3365
+ case AP_RESET_HOLD_MSR_PROTO :
3366
+ /*
3367
+ * Return from an AP Reset Hold VMGEXIT, where the guest will
3368
+ * set the CS and RIP. Set GHCB data field to a non-zero value.
3369
+ */
3370
+ set_ghcb_msr_bits (svm , 1 ,
3371
+ GHCB_MSR_AP_RESET_HOLD_RESULT_MASK ,
3372
+ GHCB_MSR_AP_RESET_HOLD_RESULT_POS );
3290
3373
3291
- ghcb_set_sw_exit_info_2 (svm -> sev_es .ghcb , 1 );
3374
+ set_ghcb_msr_bits (svm , GHCB_MSR_AP_RESET_HOLD_RESP ,
3375
+ GHCB_MSR_INFO_MASK ,
3376
+ GHCB_MSR_INFO_POS );
3377
+ break ;
3378
+ default :
3379
+ break ;
3380
+ }
3292
3381
}
3293
3382
3294
3383
struct page * snp_safe_alloc_page (struct kvm_vcpu * vcpu )
0 commit comments