[RFC PATCH V2 05/18] x86/hyperv: Get Virtual Trust Level via hvcall

From: Tianyu Lan
Date: Fri Nov 18 2022 - 22:48:03 EST


From: Tianyu Lan <tiala@xxxxxxxxxxxxx>

sev-snp guest provides vtl(Virtual Trust Level) and get it from
hyperv hvcall via HVCALL_GET_VP_REGISTERS.

Signed-off-by: Tianyu Lan <tiala@xxxxxxxxxxxxx>
---
arch/x86/hyperv/hv_init.c | 35 ++++++++++++++++++++++++++++++++++
include/asm-generic/mshyperv.h | 2 ++
2 files changed, 37 insertions(+)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 4600c5941957..5b919d4d24c0 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -390,6 +390,39 @@ static void __init hv_get_partition_id(void)
local_irq_restore(flags);
}

+static u8 __init get_current_vtl(void)
+{
+ u64 control = ((u64)1 << HV_HYPERCALL_REP_COMP_OFFSET) | HVCALL_GET_VP_REGISTERS;
+ struct hv_get_vp_registers_input *input = NULL;
+ struct hv_get_vp_registers_output *output = NULL;
+ u8 vtl = 0;
+ int 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 || !output) {
+ pr_err("Hyper-V: cannot allocate a shared page!");
+ goto done;
+ }
+
+ memset(input, 0, sizeof(*input) + sizeof(input->element[0]));
+ input->header.partitionid = HV_PARTITION_ID_SELF;
+ input->header.inputvtl = 0;
+ input->element[0].name0 = 0x000D0003;
+
+ ret = hv_do_hypercall(control, input, output);
+ if (ret == 0)
+ vtl = output->as64.low & 0xf;
+ else
+ pr_err("Hyper-V: failed to get the current 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.
@@ -527,6 +560,8 @@ void __init hyperv_init(void)
if (hv_is_isolation_supported())
swiotlb_update_mem_attributes();
#endif
+ /* Find the current VTL */
+ ms_hyperv.vtl = get_current_vtl();

return;

diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index bfb9eb9d7215..68133de044ec 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -46,6 +46,7 @@ struct ms_hyperv_info {
};
};
u64 shared_gpa_boundary;
+ u8 vtl;
};
extern struct ms_hyperv_info ms_hyperv;

@@ -55,6 +56,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)
--
2.25.1