Hyper-V supports 'fast' hypercalls when all parameters are passed through registers. Implement an inline version of a simpliest of these calls: hypercall with one 8-byte input and no output. Proper hypercall input interface (struct hv_hypercall_input) definition is added as well. Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> Acked-by: K. Y. Srinivasan <kys@xxxxxxxxxxxxx> Tested-by: Simon Xiao <sixiao@xxxxxxxxxxxxx> Tested-by: Srikanth Myakam <v-srm@xxxxxxxxxxxxx> --- Change since v3: - Force stack frame in hv_do_fast_hypercall8() [Andy Lutomirski] --- arch/x86/include/asm/mshyperv.h | 41 ++++++++++++++++++++++++++++++++++++++ arch/x86/include/uapi/asm/hyperv.h | 19 ++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index cbbf7db..52b3611 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -217,6 +217,47 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) #endif /* !x86_64 */ } +/* Fast hypercall with 8 bytes of input and no output */ +static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) +{ + union hv_hypercall_input control = {0}; + register void *__sp asm(_ASM_SP); + + control.code = code; + control.fast = 1; +#ifdef CONFIG_X86_64 + { + u64 hv_status; + + __asm__ __volatile__("call *%4" + : "=a" (hv_status), "+r" (__sp), + "+c" (control.as_uint64), "+d" (input1) + : "m" (hv_hypercall_pg) + : "cc", "r8", "r9", "r10", "r11"); + return hv_status; + } +#else + { + u32 hv_status_hi, hv_status_lo; + u32 input1_hi = (u32)(input1 >> 32); + u32 input1_lo = (u32)input1; + + __asm__ __volatile__ ("call *%7" + : "=d"(hv_status_hi), + "=a"(hv_status_lo), + "+c"(input1_lo), + "+r"(__sp) + : "d" (control.as_uint32_hi), + "a" (control.as_uint32_lo), + "b" (input1_hi), + "m" (hv_hypercall_pg) + : "cc", "edi", "esi"); + + return hv_status_lo | ((u64)hv_status_hi << 32); + } +#endif +} + void hyperv_init(void); void hyperv_report_panic(struct pt_regs *regs); bool hv_is_hypercall_page_setup(void); diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index 432df4b..c87e900 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h @@ -256,6 +256,25 @@ #define HV_PROCESSOR_POWER_STATE_C2 2 #define HV_PROCESSOR_POWER_STATE_C3 3 +/* Hypercall interface */ +union hv_hypercall_input { + u64 as_uint64; + struct { + __u32 as_uint32_lo; + __u32 as_uint32_hi; + }; + struct { + __u64 code:16; + __u64 fast:1; + __u64 varhead_size:10; + __u64 reserved1:5; + __u64 rep_count:12; + __u64 reserved2:4; + __u64 rep_start:12; + __u64 reserved3:4; + }; +}; + /* hypercall status code */ #define HV_STATUS_SUCCESS 0 #define HV_STATUS_INVALID_HYPERCALL_CODE 2 -- 2.9.4 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel