RE: [PATCH 2/7] x86/hyper-v: fast hypercall implementation

2017-04-07 Thread Jork Loeser
> -Original Message-
> From: Vitaly Kuznetsov [mailto:vkuzn...@redhat.com]
> Sent: Friday, April 7, 2017 04:27
> To: de...@linuxdriverproject.org; x...@kernel.org
> Cc: linux-ker...@vger.kernel.org; KY Srinivasan ;
> Haiyang Zhang ; Stephen Hemminger
> ; Thomas Gleixner ; Ingo
> Molnar ; H. Peter Anvin ; Steven
> Rostedt ; Jork Loeser 
> Subject: [PATCH 2/7] x86/hyper-v: fast hypercall implementation
 
> diff --git a/arch/x86/include/asm/mshyperv.h
> b/arch/x86/include/asm/mshyperv.h index 331e834..9a5f58b 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -216,6 +216,43 @@ 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};
> +
> + control.code = code;
> + control.fast = 1;
> +#ifdef CONFIG_X86_64
> + {
> + u64 hv_status;
> +
> + __asm__ __volatile__("call *%3"
> +  : "=a" (hv_status)
> +  : "c" (control.as_uint64), "d" (input1),
> +"m" (hv_hypercall_pg)
> +  : "cc", "r8", "%r9", "%r10", "%r11");
> + return hv_status;
Clobber memory (are there such fast hypercalls)?

> + }
> +#else
> + {
> + u32 hv_status_hi, hv_status_lo;
> +
> + __asm__ __volatile__ ("call *%6"
> +   : "=d"(hv_status_hi),
> + "=a"(hv_status_lo) :
> + "d" (control.as_uint32_hi),
> + "a" (control.as_uint32_lo),
> + "c" ((u32)input1),
> + "b" ((u32)(input1 >> 32)),
> + "m" (hv_hypercall_pg)
> +   : "cc");
> +
> + return hv_status_lo | ((u64)hv_status_hi << 32);
> + }
> +#endif
Please clobber ECX, EDI and ESI for x86. Clobber memory as well?
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 2/7] x86/hyper-v: fast hypercall implementation

2017-04-08 Thread KY Srinivasan


> -Original Message-
> From: Vitaly Kuznetsov [mailto:vkuzn...@redhat.com]
> Sent: Friday, April 7, 2017 4:27 AM
> To: de...@linuxdriverproject.org; x...@kernel.org
> Cc: linux-ker...@vger.kernel.org; KY Srinivasan ;
> Haiyang Zhang ; Stephen Hemminger
> ; Thomas Gleixner ; Ingo
> Molnar ; H. Peter Anvin ; Steven
> Rostedt ; Jork Loeser 
> Subject: [PATCH 2/7] x86/hyper-v: fast hypercall implementation
> 
> 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 
> ---
>  arch/x86/include/asm/mshyperv.h| 37
> +
>  arch/x86/include/uapi/asm/hyperv.h | 19 +++
>  2 files changed, 56 insertions(+)
> 
> diff --git a/arch/x86/include/asm/mshyperv.h
> b/arch/x86/include/asm/mshyperv.h
> index 331e834..9a5f58b 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -216,6 +216,43 @@ 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};

Defining the hyper-call arguments on the stack can be problematic
if CONFIG_VMAP_STACK is defined - since we are passing the guest
physical address to the hypervisor, we cannot have the arguments
straddle a page boundary.
We have dealt with this issue currently by making sure the arguments are
never on the stack via different means. Perhaps, we can allocate memory
on a per-cpu basis that can be used for this purpose. In fact, this is what I 
have done
for the   hv_post_message hypercall. We can just rename that page and use it in 
all
hypercalls - we can just allocate two pages on a per-CPU basis for this purpose
(for input and output parameters).
> +
> + control.code = code;
> + control.fast = 1;
> +#ifdef CONFIG_X86_64
> + {
> + u64 hv_status;
> +
> + __asm__ __volatile__("call *%3"
> +  : "=a" (hv_status)
> +  : "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;
> +
> + __asm__ __volatile__ ("call *%6"
> +   : "=d"(hv_status_hi),
> + "=a"(hv_status_lo) :
> + "d" (control.as_uint32_hi),
> + "a" (control.as_uint32_lo),
> + "c" ((u32)input1),
> + "b" ((u32)(input1 >> 32)),
> + "m" (hv_hypercall_pg)
> +   : "cc");
> +
> + 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_SUCCESS0
>  #define HV_STATUS_INVALID_HYPERCALL_CODE 2
> --
> 2.9.3

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/7] x86/hyper-v: fast hypercall implementation

2017-04-10 Thread Vitaly Kuznetsov
KY Srinivasan  writes:

>> -Original Message-
>> From: Vitaly Kuznetsov [mailto:vkuzn...@redhat.com]
>> Sent: Friday, April 7, 2017 4:27 AM
>> To: de...@linuxdriverproject.org; x...@kernel.org
>> Cc: linux-ker...@vger.kernel.org; KY Srinivasan ;
>> Haiyang Zhang ; Stephen Hemminger
>> ; Thomas Gleixner ; Ingo
>> Molnar ; H. Peter Anvin ; Steven
>> Rostedt ; Jork Loeser 
>> Subject: [PATCH 2/7] x86/hyper-v: fast hypercall implementation
>> 
>> 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 
>> ---
>>  arch/x86/include/asm/mshyperv.h| 37
>> +
>>  arch/x86/include/uapi/asm/hyperv.h | 19 +++
>>  2 files changed, 56 insertions(+)
>> 
>> diff --git a/arch/x86/include/asm/mshyperv.h
>> b/arch/x86/include/asm/mshyperv.h
>> index 331e834..9a5f58b 100644
>> --- a/arch/x86/include/asm/mshyperv.h
>> +++ b/arch/x86/include/asm/mshyperv.h
>> @@ -216,6 +216,43 @@ 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};
>
> Defining the hyper-call arguments on the stack can be problematic
> if CONFIG_VMAP_STACK is defined - since we are passing the guest
> physical address to the hypervisor, we cannot have the arguments
> straddle a page boundary.
> We have dealt with this issue currently by making sure the arguments are
> never on the stack via different means. Perhaps, we can allocate memory
> on a per-cpu basis that can be used for this purpose. In fact, this is what I 
> have done
> for the   hv_post_message hypercall. We can just rename that page and use it 
> in all
> hypercalls - we can just allocate two pages on a per-CPU basis for this 
> purpose
> (for input and output parameters).

This is fast hypercall and not the normal one - we pass control to
register so we're fine here (and I'd actually expect the compiler to put
it to the propper register in the first place.


>> +
>> +control.code = code;
>> +control.fast = 1;
>> +#ifdef CONFIG_X86_64
>> +{
>> +u64 hv_status;
>> +
>> +__asm__ __volatile__("call *%3"
>> + : "=a" (hv_status)
>> + : "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;
>> +
>> +__asm__ __volatile__ ("call *%6"
>> +  : "=d"(hv_status_hi),
>> +"=a"(hv_status_lo) :
>> +"d" (control.as_uint32_hi),
>> +"a" (control.as_uint32_lo),
>> +"c" ((u32)input1),
>> +"b" ((u32)(input1 >> 32)),
>> +"m" (hv_hypercall_pg)
>> +  : "cc");
>> +
>> +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_CODE2
>> --
>> 2.9.3

-- 
  Vitaly
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/7] x86/hyper-v: fast hypercall implementation

2017-04-10 Thread Vitaly Kuznetsov
Jork Loeser  writes:

>> -Original Message-
>> From: Vitaly Kuznetsov [mailto:vkuzn...@redhat.com]
>> Sent: Friday, April 7, 2017 04:27
>> To: de...@linuxdriverproject.org; x...@kernel.org
>> Cc: linux-ker...@vger.kernel.org; KY Srinivasan ;
>> Haiyang Zhang ; Stephen Hemminger
>> ; Thomas Gleixner ; Ingo
>> Molnar ; H. Peter Anvin ; Steven
>> Rostedt ; Jork Loeser 
>> Subject: [PATCH 2/7] x86/hyper-v: fast hypercall implementation
>
>> diff --git a/arch/x86/include/asm/mshyperv.h
>> b/arch/x86/include/asm/mshyperv.h index 331e834..9a5f58b 100644
>> --- a/arch/x86/include/asm/mshyperv.h
>> +++ b/arch/x86/include/asm/mshyperv.h
>> @@ -216,6 +216,43 @@ 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};
>> +
>> +control.code = code;
>> +control.fast = 1;
>> +#ifdef CONFIG_X86_64
>> +{
>> +u64 hv_status;
>> +
>> +__asm__ __volatile__("call *%3"
>> + : "=a" (hv_status)
>> + : "c" (control.as_uint64), "d" (input1),
>> +   "m" (hv_hypercall_pg)
>> + : "cc", "r8", "%r9", "%r10", "%r11");
>> +return hv_status;
> Clobber memory (are there such fast hypercalls)?
>

Hm, I was under an impression fast hypercalls have no output or put the
output in XMM* registers and we don't use them for now. Why clobbering
memory?

>> +}
>> +#else
>> +{
>> +u32 hv_status_hi, hv_status_lo;
>> +
>> +__asm__ __volatile__ ("call *%6"
>> +  : "=d"(hv_status_hi),
>> +"=a"(hv_status_lo) :
>> +"d" (control.as_uint32_hi),
>> +"a" (control.as_uint32_lo),
>> +"c" ((u32)input1),
>> +"b" ((u32)(input1 >> 32)),
>> +"m" (hv_hypercall_pg)
>> +  : "cc");
>> +
>> +return hv_status_lo | ((u64)hv_status_hi << 32);
>> +}
>> +#endif
> Please clobber ECX, EDI and ESI for x86. Clobber memory as well?

ECX is already in listed in inputs (lower part of input1) so it's
automatically clobbered. I'll add EDI and ESI to clobbers here, thanks!

-- 
  Vitaly
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/7] x86/hyper-v: fast hypercall implementation

2017-04-10 Thread Vitaly Kuznetsov
Vitaly Kuznetsov  writes:

> Jork Loeser  writes:
>

[snip]

>
>>> +   }
>>> +#else
>>> +   {
>>> +   u32 hv_status_hi, hv_status_lo;
>>> +
>>> +   __asm__ __volatile__ ("call *%6"
>>> + : "=d"(hv_status_hi),
>>> +   "=a"(hv_status_lo) :
>>> +   "d" (control.as_uint32_hi),
>>> +   "a" (control.as_uint32_lo),
>>> +   "c" ((u32)input1),
>>> +   "b" ((u32)(input1 >> 32)),
>>> +   "m" (hv_hypercall_pg)
>>> + : "cc");
>>> +
>>> +   return hv_status_lo | ((u64)hv_status_hi << 32);
>>> +   }
>>> +#endif
>> Please clobber ECX, EDI and ESI for x86. Clobber memory as well?
>
> ECX is already in listed in inputs (lower part of input1) so it's
> automatically clobbered. I'll add EDI and ESI to clobbers here, thanks!

Oh, I see what you mean - hypervisor is allowed to write to ecx too, we
need to pass it with '+'. Will do, thanks!

-- 
  Vitaly
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 2/7] x86/hyper-v: fast hypercall implementation

2017-04-10 Thread Jork Loeser
> -Original Message-
> From: Vitaly Kuznetsov [mailto:vkuzn...@redhat.com]

> Vitaly Kuznetsov  writes:
> 
> > Jork Loeser  writes:
> >
> 
> [snip]
> 
> >
> >>> + }
> >>> +#else
> >>> + {
> >>> + u32 hv_status_hi, hv_status_lo;
> >>> +
> >>> + __asm__ __volatile__ ("call *%6"
> >>> +   : "=d"(hv_status_hi),
> >>> + "=a"(hv_status_lo) :
> >>> + "d" (control.as_uint32_hi),
> >>> + "a" (control.as_uint32_lo),
> >>> + "c" ((u32)input1),
> >>> + "b" ((u32)(input1 >> 32)),
> >>> + "m" (hv_hypercall_pg)
> >>> +   : "cc");
> >>> +
> >>> + return hv_status_lo | ((u64)hv_status_hi << 32);
> >>> + }
> >>> +#endif
> >> Please clobber ECX, EDI and ESI for x86. Clobber memory as well?
> >
> > ECX is already in listed in inputs (lower part of input1) so it's
> > automatically clobbered. I'll add EDI and ESI to clobbers here, thanks!
> 
> Oh, I see what you mean - hypervisor is allowed to write to ecx too, we need
> to pass it with '+'. Will do, thanks!

Yes, thank you Vitaly!

As for memory clobber, we would want that if there were hypercalls that modify 
memory and can issued via the "fast" ABI. If there are not, we are fine. 

Regards,
Jork
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel