Skip to content

Commit d916f00

Browse files
tlendackybonzini
authored andcommitted
KVM: SEV: Add support to handle AP reset MSR protocol
Add support for AP Reset Hold being invoked using the GHCB MSR protocol, available in version 2 of the GHCB specification. Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Brijesh Singh <[email protected]> Signed-off-by: Ashish Kalra <[email protected]> Signed-off-by: Michael Roth <[email protected]> Message-ID: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a96cb3b commit d916f00

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

arch/x86/include/asm/sev-common.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@
5454
(((unsigned long)fn) << 32))
5555

5656
/* AP Reset Hold */
57-
#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
58-
#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
57+
#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
58+
#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
59+
#define GHCB_MSR_AP_RESET_HOLD_RESULT_POS 12
60+
#define GHCB_MSR_AP_RESET_HOLD_RESULT_MASK GENMASK_ULL(51, 0)
5961

6062
/* GHCB GPA Register */
6163
#define GHCB_MSR_REG_GPA_REQ 0x012

arch/x86/kvm/svm/sev.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ static bool sev_es_debug_swap_enabled = true;
4949
module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444);
5050
static u64 sev_supported_vmsa_features;
5151

52+
#define AP_RESET_HOLD_NONE 0
53+
#define AP_RESET_HOLD_NAE_EVENT 1
54+
#define AP_RESET_HOLD_MSR_PROTO 2
55+
5256
static u8 sev_enc_bit;
5357
static DECLARE_RWSEM(sev_deactivate_lock);
5458
static DEFINE_MUTEX(sev_bitmap_lock);
@@ -2727,6 +2731,9 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
27272731

27282732
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
27292733
{
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+
27302737
if (!svm->sev_es.ghcb)
27312738
return;
27322739

@@ -2938,6 +2945,22 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
29382945
GHCB_MSR_INFO_POS);
29392946
break;
29402947
}
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;
29412964
case GHCB_MSR_TERM_REQ: {
29422965
u64 reason_set, reason_code;
29432966

@@ -3037,6 +3060,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
30373060
ret = 1;
30383061
break;
30393062
case SVM_VMGEXIT_AP_HLT_LOOP:
3063+
svm->sev_es.ap_reset_hold_type = AP_RESET_HOLD_NAE_EVENT;
30403064
ret = kvm_emulate_ap_reset_hold(vcpu);
30413065
break;
30423066
case SVM_VMGEXIT_AP_JUMP_TABLE: {
@@ -3280,15 +3304,31 @@ void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
32803304
return;
32813305
}
32823306

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);
32903324

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+
}
32923332
}
32933333

32943334
struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)

arch/x86/kvm/svm/svm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ struct vcpu_sev_es_state {
199199
u8 valid_bitmap[16];
200200
struct kvm_host_map ghcb_map;
201201
bool received_first_sipi;
202+
unsigned int ap_reset_hold_type;
202203

203204
/* SEV-ES scratch area support */
204205
u64 sw_scratch;

0 commit comments

Comments
 (0)