Skip to content

Commit cb9025b

Browse files
NunoDasNeveschessturo
authored andcommitted
mshyperv: Introduce hv_get_hypervisor_version function
Introduce x86_64 and arm64 functions to get the hypervisor version information and store it in a structure for simpler parsing. Use the new function to get and parse the version at boot time. While at it, move the printing code to hv_common_init() so it is not duplicated. Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com> Acked-by: Wei Liu <wei.liu@kernel.org> Reviewed-by: Michael Kelley <mhklinux@outlook.com> [ Fix merge conflict with feature/arm64-hyperv-synthetic-clocks-timers/6.6 ] Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
1 parent e83b589 commit cb9025b

5 files changed

Lines changed: 55 additions & 29 deletions

File tree

arch/arm64/hyperv/mshyperv.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@
1919

2020
static bool hyperv_initialized;
2121

22+
int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
23+
{
24+
hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
25+
(struct hv_get_vp_registers_output *)info);
26+
27+
return 0;
28+
}
29+
2230
void __init hyperv_early_init(void)
2331
{
2432
struct hv_get_vp_registers_output result;
25-
u32 a, b, c, d;
2633
u64 guest_id;
2734

2835
/*
@@ -53,15 +60,6 @@ void __init hyperv_early_init(void)
5360
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
5461
ms_hyperv.misc_features);
5562

56-
/* Get information about the Hyper-V host version */
57-
hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
58-
a = result.as32.a;
59-
b = result.as32.b;
60-
c = result.as32.c;
61-
d = result.as32.d;
62-
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
63-
b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24);
64-
6563
hyperv_initialized = true;
6664
}
6765

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,24 @@ static void __init reduced_hw_init(void)
403403
x86_init.irqs.pre_vector_init = x86_init_noop;
404404
}
405405

406+
int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
407+
{
408+
unsigned int hv_max_functions;
409+
410+
hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
411+
if (hv_max_functions < HYPERV_CPUID_VERSION) {
412+
pr_err("%s: Could not detect Hyper-V version\n", __func__);
413+
return -ENODEV;
414+
}
415+
416+
cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, &info->edx);
417+
418+
return 0;
419+
}
420+
406421
static void __init ms_hyperv_init_platform(void)
407422
{
408423
int hv_max_functions_eax;
409-
int hv_host_info_eax;
410-
int hv_host_info_ebx;
411-
int hv_host_info_ecx;
412-
int hv_host_info_edx;
413424

414425
#ifdef CONFIG_PARAVIRT
415426
pv_info.name = "Hyper-V";
@@ -460,21 +471,6 @@ static void __init ms_hyperv_init_platform(void)
460471
pr_info("Hyper-V: running on a nested hypervisor\n");
461472
}
462473

463-
/*
464-
* Extract host information.
465-
*/
466-
if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
467-
hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
468-
hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
469-
hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
470-
hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
471-
472-
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
473-
hv_host_info_ebx >> 16, hv_host_info_ebx & 0xFFFF,
474-
hv_host_info_eax, hv_host_info_edx & 0xFFFFFF,
475-
hv_host_info_ecx, hv_host_info_edx >> 24);
476-
}
477-
478474
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
479475
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
480476
x86_platform.calibrate_tsc = hv_get_tsc_khz;

drivers/hv/hv_common.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,14 @@ static void hv_kmsg_dump_register(void)
281281
int __init hv_common_init(void)
282282
{
283283
int i;
284+
union hv_hypervisor_version_info version;
285+
286+
/* Get information about the Hyper-V host version */
287+
if (!hv_get_hypervisor_version(&version))
288+
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
289+
version.major_version, version.minor_version,
290+
version.build_number, version.service_number,
291+
version.service_pack, version.service_branch);
284292

285293
if (hv_is_isolation_supported())
286294
sysctl_record_panic_msg = 0;

include/asm-generic/hyperv-tlfs.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,29 @@ struct hv_input_unmap_device_interrupt {
817817
#define HV_SOURCE_SHADOW_NONE 0x0
818818
#define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1
819819

820+
/*
821+
* Version info reported by hypervisor
822+
*/
823+
union hv_hypervisor_version_info {
824+
struct {
825+
u32 build_number;
826+
827+
u32 minor_version : 16;
828+
u32 major_version : 16;
829+
830+
u32 service_pack;
831+
832+
u32 service_number : 24;
833+
u32 service_branch : 8;
834+
};
835+
struct {
836+
u32 eax;
837+
u32 ebx;
838+
u32 ecx;
839+
u32 edx;
840+
};
841+
};
842+
820843
/*
821844
* The whole argument should fit in a page to be able to pass to the hypervisor
822845
* in one hypercall.

include/asm-generic/mshyperv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ static inline int cpumask_to_vpset_skip(struct hv_vpset *vpset,
275275
return __cpumask_to_vpset(vpset, cpus, func);
276276
}
277277

278+
int hv_get_hypervisor_version(union hv_hypervisor_version_info *info);
278279
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die);
279280
bool hv_is_hyperv_initialized(void);
280281
bool hv_is_hibernation_supported(void);

0 commit comments

Comments
 (0)