lkml.org 
[lkml]   [2024]   [Apr]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v13 06/26] KVM: SEV: Add support to handle AP reset MSR protocol
    Date
    From: Tom Lendacky <thomas.lendacky@amd.com>

    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 <thomas.lendacky@amd.com>
    Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
    Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
    Signed-off-by: Michael Roth <michael.roth@amd.com>
    ---
    arch/x86/include/asm/sev-common.h | 6 ++--
    arch/x86/kvm/svm/sev.c | 56 ++++++++++++++++++++++++++-----
    arch/x86/kvm/svm/svm.h | 1 +
    3 files changed, 53 insertions(+), 10 deletions(-)

    diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
    index b463fcbd4b90..01261f7054ad 100644
    --- a/arch/x86/include/asm/sev-common.h
    +++ b/arch/x86/include/asm/sev-common.h
    @@ -54,8 +54,10 @@
    (((unsigned long)fn) << 32))

    /* AP Reset Hold */
    -#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
    -#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
    +#define GHCB_MSR_AP_RESET_HOLD_REQ 0x006
    +#define GHCB_MSR_AP_RESET_HOLD_RESP 0x007
    +#define GHCB_MSR_AP_RESET_HOLD_RESULT_POS 12
    +#define GHCB_MSR_AP_RESET_HOLD_RESULT_MASK GENMASK_ULL(51, 0)

    /* GHCB GPA Register */
    #define GHCB_MSR_REG_GPA_REQ 0x012
    diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
    index 598d78b4107f..6e31cb408dd8 100644
    --- a/arch/x86/kvm/svm/sev.c
    +++ b/arch/x86/kvm/svm/sev.c
    @@ -49,6 +49,10 @@ static bool sev_es_debug_swap_enabled = true;
    module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444);
    static u64 sev_supported_vmsa_features;

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

    void sev_es_unmap_ghcb(struct vcpu_svm *svm)
    {
    + /* Clear any indication that the vCPU is in a type of AP Reset Hold */
    + svm->sev_es.ap_reset_hold_type = AP_RESET_HOLD_NONE;
    +
    if (!svm->sev_es.ghcb)
    return;

    @@ -2938,6 +2945,22 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
    GHCB_MSR_INFO_POS);
    break;
    }
    + case GHCB_MSR_AP_RESET_HOLD_REQ:
    + svm->sev_es.ap_reset_hold_type = AP_RESET_HOLD_MSR_PROTO;
    + ret = kvm_emulate_ap_reset_hold(&svm->vcpu);
    +
    + /*
    + * Preset the result to a non-SIPI return and then only set
    + * the result to non-zero when delivering a SIPI.
    + */
    + set_ghcb_msr_bits(svm, 0,
    + GHCB_MSR_AP_RESET_HOLD_RESULT_MASK,
    + GHCB_MSR_AP_RESET_HOLD_RESULT_POS);
    +
    + set_ghcb_msr_bits(svm, GHCB_MSR_AP_RESET_HOLD_RESP,
    + GHCB_MSR_INFO_MASK,
    + GHCB_MSR_INFO_POS);
    + break;
    case GHCB_MSR_TERM_REQ: {
    u64 reason_set, reason_code;

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

    - /*
    - * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where
    - * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a
    - * non-zero value.
    - */
    - if (!svm->sev_es.ghcb)
    - return;
    + /* Subsequent SIPI */
    + switch (svm->sev_es.ap_reset_hold_type) {
    + case AP_RESET_HOLD_NAE_EVENT:
    + /*
    + * Return from an AP Reset Hold VMGEXIT, where the guest will
    + * set the CS and RIP. Set SW_EXIT_INFO_2 to a non-zero value.
    + */
    + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 1);
    + break;
    + case AP_RESET_HOLD_MSR_PROTO:
    + /*
    + * Return from an AP Reset Hold VMGEXIT, where the guest will
    + * set the CS and RIP. Set GHCB data field to a non-zero value.
    + */
    + set_ghcb_msr_bits(svm, 1,
    + GHCB_MSR_AP_RESET_HOLD_RESULT_MASK,
    + GHCB_MSR_AP_RESET_HOLD_RESULT_POS);

    - ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 1);
    + set_ghcb_msr_bits(svm, GHCB_MSR_AP_RESET_HOLD_RESP,
    + GHCB_MSR_INFO_MASK,
    + GHCB_MSR_INFO_POS);
    + break;
    + default:
    + break;
    + }
    }

    struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
    diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
    index 323901782547..6fd0f5862681 100644
    --- a/arch/x86/kvm/svm/svm.h
    +++ b/arch/x86/kvm/svm/svm.h
    @@ -199,6 +199,7 @@ struct vcpu_sev_es_state {
    u8 valid_bitmap[16];
    struct kvm_host_map ghcb_map;
    bool received_first_sipi;
    + unsigned int ap_reset_hold_type;

    /* SEV-ES scratch area support */
    u64 sw_scratch;
    --
    2.25.1

    \
     
     \ /
      Last update: 2024-05-27 16:46    [W:6.058 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site