Skip to content

Commit c5994cd

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 b632632 commit c5994cd

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
@@ -347,13 +347,24 @@ static void __init reduced_hw_init(void)
347347
x86_init.irqs.pre_vector_init = x86_init_noop;
348348
}
349349

350+
int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
351+
{
352+
unsigned int hv_max_functions;
353+
354+
hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
355+
if (hv_max_functions < HYPERV_CPUID_VERSION) {
356+
pr_err("%s: Could not detect Hyper-V version\n", __func__);
357+
return -ENODEV;
358+
}
359+
360+
cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, &info->edx);
361+
362+
return 0;
363+
}
364+
350365
static void __init ms_hyperv_init_platform(void)
351366
{
352367
int hv_max_functions_eax;
353-
int hv_host_info_eax;
354-
int hv_host_info_ebx;
355-
int hv_host_info_ecx;
356-
int hv_host_info_edx;
357368

358369
#ifdef CONFIG_PARAVIRT
359370
pv_info.name = "Hyper-V";
@@ -404,21 +415,6 @@ static void __init ms_hyperv_init_platform(void)
404415
pr_info("Hyper-V: running on a nested hypervisor\n");
405416
}
406417

407-
/*
408-
* Extract host information.
409-
*/
410-
if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
411-
hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
412-
hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
413-
hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
414-
hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
415-
416-
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
417-
hv_host_info_ebx >> 16, hv_host_info_ebx & 0xFFFF,
418-
hv_host_info_eax, hv_host_info_edx & 0xFFFFFF,
419-
hv_host_info_ecx, hv_host_info_edx >> 24);
420-
}
421-
422418
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
423419
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
424420
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
@@ -279,6 +279,14 @@ static void hv_kmsg_dump_register(void)
279279
int __init hv_common_init(void)
280280
{
281281
int i;
282+
union hv_hypervisor_version_info version;
283+
284+
/* Get information about the Hyper-V host version */
285+
if (!hv_get_hypervisor_version(&version))
286+
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
287+
version.major_version, version.minor_version,
288+
version.build_number, version.service_number,
289+
version.service_pack, version.service_branch);
282290

283291
if (hv_is_isolation_supported())
284292
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
@@ -787,6 +787,29 @@ struct hv_input_unmap_device_interrupt {
787787
#define HV_SOURCE_SHADOW_NONE 0x0
788788
#define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1
789789

790+
/*
791+
* Version info reported by hypervisor
792+
*/
793+
union hv_hypervisor_version_info {
794+
struct {
795+
u32 build_number;
796+
797+
u32 minor_version : 16;
798+
u32 major_version : 16;
799+
800+
u32 service_pack;
801+
802+
u32 service_number : 24;
803+
u32 service_branch : 8;
804+
};
805+
struct {
806+
u32 eax;
807+
u32 ebx;
808+
u32 ecx;
809+
u32 edx;
810+
};
811+
};
812+
790813
/*
791814
* The whole argument should fit in a page to be able to pass to the hypervisor
792815
* 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)