Drivers: hv: Provide arch-neutral implementation of get_vtl()

To run in the VTL mode, Hyper-V drivers have to know what
VTL the system boots in, and the arm64/hyperv code does not
have the means to compute that.

Refactor the code to hoist the function that detects VTL,
make it arch-neutral to be able to employ it to get the VTL
on arm64.

Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Link: https://lore.kernel.org/r/20250428210742.435282-5-romank@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <20250428210742.435282-5-romank@linux.microsoft.com>
This commit is contained in:
Roman Kisel 2025-04-28 14:07:35 -07:00 committed by Wei Liu
parent f41ceff174
commit e7e6902fbd
4 changed files with 38 additions and 35 deletions

View File

@ -390,40 +390,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
old_setup_percpu_clockev(); old_setup_percpu_clockev();
} }
#if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
static u8 __init get_vtl(void)
{
u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
struct hv_input_get_vp_registers *input;
struct hv_output_get_vp_registers *output;
unsigned long flags;
u64 ret;
local_irq_save(flags);
input = *this_cpu_ptr(hyperv_pcpu_input_arg);
output = *this_cpu_ptr(hyperv_pcpu_output_arg);
memset(input, 0, struct_size(input, names, 1));
input->partition_id = HV_PARTITION_ID_SELF;
input->vp_index = HV_VP_INDEX_SELF;
input->input_vtl.as_uint8 = 0;
input->names[0] = HV_REGISTER_VSM_VP_STATUS;
ret = hv_do_hypercall(control, input, output);
if (hv_result_success(ret)) {
ret = output->values[0].reg8 & HV_X64_VTL_MASK;
} else {
pr_err("Failed to get VTL(error: %lld) exiting...\n", ret);
BUG();
}
local_irq_restore(flags);
return ret;
}
#else
static inline u8 get_vtl(void) { return 0; }
#endif
/* /*
* This function is to be invoked early in the boot sequence after the * This function is to be invoked early in the boot sequence after the
* hypervisor has been detected. * hypervisor has been detected.

View File

@ -317,6 +317,37 @@ void __init hv_get_partition_id(void)
pr_err("Hyper-V: failed to get partition ID: %#x\n", pr_err("Hyper-V: failed to get partition ID: %#x\n",
hv_result(status)); hv_result(status));
} }
#if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
u8 __init get_vtl(void)
{
u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
struct hv_input_get_vp_registers *input;
struct hv_output_get_vp_registers *output;
unsigned long flags;
u64 ret;
local_irq_save(flags);
input = *this_cpu_ptr(hyperv_pcpu_input_arg);
output = *this_cpu_ptr(hyperv_pcpu_output_arg);
memset(input, 0, struct_size(input, names, 1));
input->partition_id = HV_PARTITION_ID_SELF;
input->vp_index = HV_VP_INDEX_SELF;
input->input_vtl.as_uint8 = 0;
input->names[0] = HV_REGISTER_VSM_VP_STATUS;
ret = hv_do_hypercall(control, input, output);
if (hv_result_success(ret)) {
ret = output->values[0].reg8 & HV_VTL_MASK;
} else {
pr_err("Failed to get VTL(error: %lld) exiting...\n", ret);
BUG();
}
local_irq_restore(flags);
return ret;
}
#endif
int __init hv_common_init(void) int __init hv_common_init(void)
{ {

View File

@ -378,4 +378,10 @@ static inline int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u3
} }
#endif /* CONFIG_MSHV_ROOT */ #endif /* CONFIG_MSHV_ROOT */
#if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
u8 __init get_vtl(void);
#else
static inline u8 get_vtl(void) { return 0; }
#endif
#endif #endif

View File

@ -1228,7 +1228,7 @@ struct hv_send_ipi { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI */
u64 cpu_mask; u64 cpu_mask;
} __packed; } __packed;
#define HV_X64_VTL_MASK GENMASK(3, 0) #define HV_VTL_MASK GENMASK(3, 0)
/* Hyper-V memory host visibility */ /* Hyper-V memory host visibility */
enum hv_mem_host_visibility { enum hv_mem_host_visibility {