Skip to content

Commit a68a2c7

Browse files
committed
Hyper-V: Support for querying extended capabilities
This patch adds support for querying extended Hyper-V capabilities using the extended hypercall. Signed-off-by: Sunil Muthuswamy <[email protected]> TAG_MSFT: wsl
1 parent f5d8319 commit a68a2c7

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

arch/arm64/hyperv/hv_core.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,15 @@ static int __init hyperv_init(struct acpi_table_header *table)
159159
/* Get the features and hints from Hyper-V */
160160
hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
161161
ms_hyperv.features = result.as32.a;
162+
ms_hyperv.priv_high = result.as32.b;
162163
ms_hyperv.misc_features = result.as32.c;
163164

164165
hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
165166
ms_hyperv.hints = result.as32.a;
166167

167-
pr_info("Hyper-V: Features 0x%x, hints 0x%x, misc 0x%x\n",
168-
ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features);
168+
pr_info("Hyper-V: Features 0x%x, privilege high: 0x%x, hints 0x%x, misc 0x%x\n",
169+
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
170+
ms_hyperv.misc_features);
169171

170172
/*
171173
* Allocate the per-CPU state for the hypercall input arg.

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,13 @@ static void __init ms_hyperv_init_platform(void)
225225
* Extract the features and hints
226226
*/
227227
ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
228+
ms_hyperv.priv_high = cpuid_ebx(HYPERV_CPUID_FEATURES);
228229
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
229230
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
230231

231-
pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n",
232-
ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features);
232+
pr_info("Hyper-V: features 0x%x, privilege high: 0x%x, hints 0x%x, misc 0x%x\n",
233+
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
234+
ms_hyperv.misc_features);
233235

234236
ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS);
235237
ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS);

include/asm-generic/hyperv-tlfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#define HV_ACCESS_STATS BIT(8)
9090
#define HV_DEBUGGING BIT(11)
9191
#define HV_CPU_POWER_MANAGEMENT BIT(12)
92+
#define HV_ENABLE_EXTENDED_HYPERCALLS BIT(20)
9293

9394

9495
/*
@@ -151,6 +152,7 @@ struct ms_hyperv_tsc_page {
151152
#define HVCALL_RETARGET_INTERRUPT 0x007e
152153
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
153154
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
155+
#define HVCALL_QUERY_CAPABILITIES 0x8001
154156

155157
#define HV_FLUSH_ALL_PROCESSORS BIT(0)
156158
#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)

include/asm-generic/mshyperv.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
struct ms_hyperv_info {
3030
u32 features;
31+
u32 priv_high;
3132
u32 misc_features;
3233
u32 hints;
3334
u32 nested_features;
@@ -217,6 +218,35 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
217218

218219
return status;
219220
}
221+
222+
static inline bool hyperv_query_ext_cap(u64 cap_to_query)
223+
{
224+
u64 *cap;
225+
unsigned long flags;
226+
u64 status;
227+
228+
/*
229+
* Querying extended capabilities is done via an extended hypercall.
230+
* Check if the partition supports extended hypercall, first.
231+
*/
232+
if (!(ms_hyperv.priv_high & HV_ENABLE_EXTENDED_HYPERCALLS)) {
233+
pr_info("Hyper-V doesn't support extended hypercalls\n");
234+
return 0;
235+
}
236+
237+
local_irq_save(flags);
238+
cap = *(u64 **)this_cpu_ptr(hyperv_pcpu_input_arg);
239+
status = hv_do_hypercall(HVCALL_QUERY_CAPABILITIES, NULL, cap)
240+
& HV_HYPERCALL_RESULT_MASK;
241+
local_irq_restore(flags);
242+
if (status != HV_STATUS_SUCCESS) {
243+
pr_err("Extended cap query hypercall failed: 0x%llx\n", status);
244+
return 0;
245+
}
246+
247+
return (*cap & cap_to_query);
248+
}
249+
220250
#endif
221251

222252
#endif

0 commit comments

Comments
 (0)