22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24 #include <linux/kernel.h>
26 #include <linux/slab.h>
29 #include <linux/version.h>
36 .hypercall_page =
NULL,
37 .signal_event_param =
NULL,
38 .signal_event_buffer =
NULL,
44 static int query_hypervisor_info(
void)
50 unsigned int max_leaf;
62 cpuid(op, &eax, &ebx, &ecx, &edx);
72 cpuid(op, &eax, &ebx, &ecx, &edx);
73 pr_info(
"Hyper-V Host OS Build:%d-%d.%d-%d-%d.%d\n",
95 __asm__ __volatile__(
"mov %0, %%r8" : :
"r" (output_address) :
"r8");
96 __asm__ __volatile__(
"call *%3" :
"=a" (hv_status) :
97 "c" (control),
"d" (input_address),
98 "m" (hypercall_page));
104 u32 control_hi = control >> 32;
105 u32 control_lo = control & 0xFFFFFFFF;
106 u32 hv_status_hi = 1;
107 u32 hv_status_lo = 1;
109 u32 input_address_hi = input_address >> 32;
110 u32 input_address_lo = input_address & 0xFFFFFFFF;
112 u32 output_address_hi = output_address >> 32;
113 u32 output_address_lo = output_address & 0xFFFFFFFF;
116 __asm__ __volatile__ (
"call *%8" :
"=d"(hv_status_hi),
117 "=a"(hv_status_lo) :
"d" (control_hi),
118 "a" (control_lo),
"b" (input_address_hi),
119 "c" (input_address_lo),
"D"(output_address_hi),
120 "S"(output_address_lo),
"m" (hypercall_page));
122 return hv_status_lo | ((
u64)hv_status_hi << 32);
135 void *virtaddr =
NULL;
141 max_leaf = query_hypervisor_info();
146 hv_context.
guestid = generate_guest_id(0, LINUX_VERSION_CODE, 0);
166 if (!hypercall_msr.
enable)
180 (
ALIGN((
unsigned long)
193 if (hypercall_msr.
enable) {
237 struct aligned_input {
301 u32 irq_vector = *((
u32 *)(irqarg));
314 pr_err(
"Unable to allocate SYNIC message page\n");
322 pr_err(
"Unable to allocate SYNIC event page\n");
346 shared_sint.
vector = irq_vector;
347 shared_sint.
masked =
false;