lkml.org 
[lkml]   [2021]   [Dec]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 22/40] x86/sev: move MSR-based VMGEXITs for CPUID to helper
    Date
    From: Michael Roth <michael.roth@amd.com>

    This code will also be used later for SEV-SNP-validated CPUID code in
    some cases, so move it to a common helper.

    Signed-off-by: Michael Roth <michael.roth@amd.com>
    Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
    ---
    arch/x86/kernel/sev-shared.c | 84 +++++++++++++++++++++++++-----------
    1 file changed, 58 insertions(+), 26 deletions(-)

    diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
    index 3aaef1a18ffe..d89481b31022 100644
    --- a/arch/x86/kernel/sev-shared.c
    +++ b/arch/x86/kernel/sev-shared.c
    @@ -194,6 +194,58 @@ enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, bool set_ghcb_msr,
    return verify_exception_info(ghcb, ctxt);
    }

    +static int sev_cpuid_hv(u32 func, u32 subfunc, u32 *eax, u32 *ebx,
    + u32 *ecx, u32 *edx)
    +{
    + u64 val;
    +
    + if (eax) {
    + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(func, GHCB_CPUID_REQ_EAX));
    + VMGEXIT();
    + val = sev_es_rd_ghcb_msr();
    +
    + if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    + return -EIO;
    +
    + *eax = (val >> 32);
    + }
    +
    + if (ebx) {
    + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(func, GHCB_CPUID_REQ_EBX));
    + VMGEXIT();
    + val = sev_es_rd_ghcb_msr();
    +
    + if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    + return -EIO;
    +
    + *ebx = (val >> 32);
    + }
    +
    + if (ecx) {
    + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(func, GHCB_CPUID_REQ_ECX));
    + VMGEXIT();
    + val = sev_es_rd_ghcb_msr();
    +
    + if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    + return -EIO;
    +
    + *ecx = (val >> 32);
    + }
    +
    + if (edx) {
    + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(func, GHCB_CPUID_REQ_EDX));
    + VMGEXIT();
    + val = sev_es_rd_ghcb_msr();
    +
    + if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    + return -EIO;
    +
    + *edx = (val >> 32);
    + }
    +
    + return 0;
    +}
    +
    /*
    * Boot VC Handler - This is the first VC handler during boot, there is no GHCB
    * page yet, so it only supports the MSR based communication with the
    @@ -202,39 +254,19 @@ enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, bool set_ghcb_msr,
    void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
    {
    unsigned int fn = lower_bits(regs->ax, 32);
    - unsigned long val;
    + u32 eax, ebx, ecx, edx;

    /* Only CPUID is supported via MSR protocol */
    if (exit_code != SVM_EXIT_CPUID)
    goto fail;

    - sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EAX));
    - VMGEXIT();
    - val = sev_es_rd_ghcb_msr();
    - if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    + if (sev_cpuid_hv(fn, 0, &eax, &ebx, &ecx, &edx))
    goto fail;
    - regs->ax = val >> 32;

    - sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EBX));
    - VMGEXIT();
    - val = sev_es_rd_ghcb_msr();
    - if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    - goto fail;
    - regs->bx = val >> 32;
    -
    - sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_ECX));
    - VMGEXIT();
    - val = sev_es_rd_ghcb_msr();
    - if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    - goto fail;
    - regs->cx = val >> 32;
    -
    - sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EDX));
    - VMGEXIT();
    - val = sev_es_rd_ghcb_msr();
    - if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
    - goto fail;
    - regs->dx = val >> 32;
    + regs->ax = eax;
    + regs->bx = ebx;
    + regs->cx = ecx;
    + regs->dx = edx;

    /*
    * This is a VC handler and the #VC is only raised when SEV-ES is
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-12-10 16:46    [W:4.055 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site