lkml.org 
[lkml]   [2023]   [Apr]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH V4 03/17] x86/hyperv: Set Virtual Trust Level in VMBus init message
    Date
    From: Tianyu Lan <tiala@microsoft.com>

    sev-snp guest provides vtl(Virtual Trust Level) and
    get it from hyperv hvcall via HVCALL_GET_VP_REGISTERS.
    Set target vtl in the VMBus init message.

    Signed-off-by: Tianyu Lan <tiala@microsoft.com>
    ---
    Change since RFC v3:
    * Use the standard helper functions to check hypercall result
    * Fix coding style

    Change since RFC v2:
    * Rename get_current_vtl() to get_vtl()
    * Fix some coding style issues
    ---
    arch/x86/hyperv/hv_init.c | 36 ++++++++++++++++++++++++++++++
    arch/x86/include/asm/hyperv-tlfs.h | 7 ++++++
    drivers/hv/connection.c | 1 +
    include/asm-generic/mshyperv.h | 2 ++
    include/linux/hyperv.h | 4 ++--
    5 files changed, 48 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
    index 9f3e2d71d015..7602db5ad4aa 100644
    --- a/arch/x86/hyperv/hv_init.c
    +++ b/arch/x86/hyperv/hv_init.c
    @@ -384,6 +384,40 @@ static void __init hv_get_partition_id(void)
    local_irq_restore(flags);
    }

    +static u8 __init get_vtl(void)
    +{
    + u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
    + struct hv_get_vp_registers_input *input;
    + struct hv_get_vp_registers_output *output;
    + u64 vtl = 0;
    + u64 ret;
    + unsigned long flags;
    +
    + local_irq_save(flags);
    + input = *(struct hv_get_vp_registers_input **)this_cpu_ptr(hyperv_pcpu_input_arg);
    + output = (struct hv_get_vp_registers_output *)input;
    + if (!input) {
    + local_irq_restore(flags);
    + goto done;
    + }
    +
    + memset(input, 0, sizeof(*input) + sizeof(input->element[0]));
    + input->header.partitionid = HV_PARTITION_ID_SELF;
    + input->header.vpindex = HV_VP_INDEX_SELF;
    + input->header.inputvtl = 0;
    + input->element[0].name0 = HV_X64_REGISTER_VSM_VP_STATUS;
    +
    + ret = hv_do_hypercall(control, input, output);
    + if (hv_result_success(ret))
    + vtl = output->as64.low & HV_X64_VTL_MASK;
    + else
    + pr_err("Hyper-V: failed to get VTL!");
    + local_irq_restore(flags);
    +
    +done:
    + return vtl;
    +}
    +
    /*
    * This function is to be invoked early in the boot sequence after the
    * hypervisor has been detected.
    @@ -512,6 +546,8 @@ void __init hyperv_init(void)
    /* Query the VMs extended capability once, so that it can be cached. */
    hv_query_ext_cap(0);

    + /* Find the VTL */
    + ms_hyperv.vtl = get_vtl();
    return;

    clean_guest_os_id:
    diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
    index b4fb75bd1013..3d3f014976e8 100644
    --- a/arch/x86/include/asm/hyperv-tlfs.h
    +++ b/arch/x86/include/asm/hyperv-tlfs.h
    @@ -301,6 +301,13 @@ enum hv_isolation_type {
    #define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT
    #define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC

    +/*
    + * Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and
    + * there is not associated MSR address.
    + */
    +#define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003
    +#define HV_X64_VTL_MASK GENMASK(3, 0)
    +
    /* Hyper-V memory host visibility */
    enum hv_mem_host_visibility {
    VMBUS_PAGE_NOT_VISIBLE = 0,
    diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
    index f670cfd2e056..e4c39f4016ad 100644
    --- a/drivers/hv/connection.c
    +++ b/drivers/hv/connection.c
    @@ -98,6 +98,7 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
    */
    if (version >= VERSION_WIN10_V5) {
    msg->msg_sint = VMBUS_MESSAGE_SINT;
    + msg->msg_vtl = ms_hyperv.vtl;
    vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID_4;
    } else {
    msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
    diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
    index afcd9ae9588c..f91fb06634f0 100644
    --- a/include/asm-generic/mshyperv.h
    +++ b/include/asm-generic/mshyperv.h
    @@ -48,6 +48,7 @@ struct ms_hyperv_info {
    };
    };
    u64 shared_gpa_boundary;
    + u8 vtl;
    };
    extern struct ms_hyperv_info ms_hyperv;
    extern bool hv_nested;
    @@ -58,6 +59,7 @@ extern void * __percpu *hyperv_pcpu_output_arg;
    extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
    extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
    extern bool hv_isolation_type_snp(void);
    +extern bool hv_isolation_type_en_snp(void);

    /* Helper functions that provide a consistent pattern for checking Hyper-V hypercall status. */
    static inline int hv_result(u64 status)
    diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
    index bfbc37ce223b..1f2bfec4abde 100644
    --- a/include/linux/hyperv.h
    +++ b/include/linux/hyperv.h
    @@ -665,8 +665,8 @@ struct vmbus_channel_initiate_contact {
    u64 interrupt_page;
    struct {
    u8 msg_sint;
    - u8 padding1[3];
    - u32 padding2;
    + u8 msg_vtl;
    + u8 reserved[6];
    };
    };
    u64 monitor_page1;
    --
    2.25.1
    \
     
     \ /
      Last update: 2023-04-03 19:45    [W:2.511 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site