2021-04-17 00:44:44

by Joseph Salisbury

[permalink] [raw]
Subject: [PATCH 1/2] x86/hyperv: Move hv_do_rep_hypercall to asm-generic

From: Joseph Salisbury <[email protected]>

This patch makes no functional changes. It simply moves hv_do_rep_hypercall()
out of arch/x86/include/asm/mshyperv.h and into asm-generic/mshyperv.h

hv_do_rep_hypercall() is architecture independent, so it makes sense that it
should be in the architecture independent mshyperv.h, not in the x86-specific
mshyperv.h.

This is done in preperation for a follow up patch which creates a consistent
pattern for checking Hyper-V hypercall status.

Signed-off-by: Joseph Salisbury <[email protected]>
---
arch/x86/include/asm/mshyperv.h | 32 --------------------------------
include/asm-generic/mshyperv.h | 31 +++++++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index ccf60a809a17..bfc98b490f07 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -189,38 +189,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
return hv_status;
}

-/*
- * Rep hypercalls. Callers of this functions are supposed to ensure that
- * rep_count and varhead_size comply with Hyper-V hypercall definition.
- */
-static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
- void *input, void *output)
-{
- u64 control = code;
- u64 status;
- u16 rep_comp;
-
- control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
- control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
-
- do {
- status = hv_do_hypercall(control, input, output);
- if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
- return status;
-
- /* Bits 32-43 of status have 'Reps completed' data. */
- rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
- HV_HYPERCALL_REP_COMP_OFFSET;
-
- control &= ~HV_HYPERCALL_REP_START_MASK;
- control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
-
- touch_nmi_watchdog();
- } while (rep_comp < rep_count);
-
- return status;
-}
-
extern struct hv_vp_assist_page **hv_vp_assist_page;

static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index dff58a3db5d5..a5246a6ea02d 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -41,6 +41,37 @@ extern struct ms_hyperv_info ms_hyperv;
extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);

+/*
+ * Rep hypercalls. Callers of this functions are supposed to ensure that
+ * rep_count and varhead_size comply with Hyper-V hypercall definition.
+ */
+static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
+ void *input, void *output)
+{
+ u64 control = code;
+ u64 status;
+ u16 rep_comp;
+
+ control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
+ control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
+
+ do {
+ status = hv_do_hypercall(control, input, output);
+ if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
+ return status;
+
+ /* Bits 32-43 of status have 'Reps completed' data. */
+ rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
+ HV_HYPERCALL_REP_COMP_OFFSET;
+
+ control &= ~HV_HYPERCALL_REP_START_MASK;
+ control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
+
+ touch_nmi_watchdog();
+ } while (rep_comp < rep_count);
+
+ return status;
+}

/* Generate the guest OS identifier as described in the Hyper-V TLFS */
static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version,
--
2.17.1


2021-04-18 13:12:21

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH 1/2] x86/hyperv: Move hv_do_rep_hypercall to asm-generic

On Fri, Apr 16, 2021 at 05:43:02PM -0700, Joseph Salisbury wrote:
> From: Joseph Salisbury <[email protected]>
>
> This patch makes no functional changes. It simply moves hv_do_rep_hypercall()
> out of arch/x86/include/asm/mshyperv.h and into asm-generic/mshyperv.h
>
> hv_do_rep_hypercall() is architecture independent, so it makes sense that it
> should be in the architecture independent mshyperv.h, not in the x86-specific
> mshyperv.h.
>
> This is done in preperation for a follow up patch which creates a consistent
> pattern for checking Hyper-V hypercall status.
>
> Signed-off-by: Joseph Salisbury <[email protected]>
> ---
[...]
> +static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
> + void *input, void *output)
> +{
> + u64 control = code;
> + u64 status;
> + u16 rep_comp;
> +
> + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
> + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
> +
> + do {
> + status = hv_do_hypercall(control, input, output);
> + if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
> + return status;
> +
> + /* Bits 32-43 of status have 'Reps completed' data. */
> + rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
> + HV_HYPERCALL_REP_COMP_OFFSET;
> +
> + control &= ~HV_HYPERCALL_REP_START_MASK;
> + control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
> +
> + touch_nmi_watchdog();

This seems to be missing in Arm. Does it compile?

Wei.

> + } while (rep_comp < rep_count);
> +
> + return status;
> +}
>
> /* Generate the guest OS identifier as described in the Hyper-V TLFS */
> static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version,
> --
> 2.17.1
>

2021-04-18 14:44:27

by Michael Kelley (LINUX)

[permalink] [raw]
Subject: RE: [PATCH 1/2] x86/hyperv: Move hv_do_rep_hypercall to asm-generic

From: Wei Liu <[email protected]> Sent: Sunday, April 18, 2021 6:09 AM
> On Fri, Apr 16, 2021 at 05:43:02PM -0700, Joseph Salisbury wrote:
> > From: Joseph Salisbury <[email protected]>
> >
> > This patch makes no functional changes. It simply moves hv_do_rep_hypercall()
> > out of arch/x86/include/asm/mshyperv.h and into asm-generic/mshyperv.h
> >
> > hv_do_rep_hypercall() is architecture independent, so it makes sense that it
> > should be in the architecture independent mshyperv.h, not in the x86-specific
> > mshyperv.h.
> >
> > This is done in preperation for a follow up patch which creates a consistent
> > pattern for checking Hyper-V hypercall status.
> >
> > Signed-off-by: Joseph Salisbury <[email protected]>
> > ---
> [...]
> > +static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
> > + void *input, void *output)
> > +{
> > + u64 control = code;
> > + u64 status;
> > + u16 rep_comp;
> > +
> > + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
> > + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
> > +
> > + do {
> > + status = hv_do_hypercall(control, input, output);
> > + if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
> > + return status;
> > +
> > + /* Bits 32-43 of status have 'Reps completed' data. */
> > + rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
> > + HV_HYPERCALL_REP_COMP_OFFSET;
> > +
> > + control &= ~HV_HYPERCALL_REP_START_MASK;
> > + control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
> > +
> > + touch_nmi_watchdog();
>
> This seems to be missing in Arm. Does it compile?
>
> Wei.

touch_nmi_watchdog() is defined as "static inline" in include/linux/nmi.h. So
it should be present in all architectures. It calls arch_touch_nmi_watchdog,
which is an empty function if CONFIG_HAVE_NMI_WATCHDOG is not defined,
as is the case on ARM64.

Michael

>
> > + } while (rep_comp < rep_count);
> > +
> > + return status;
> > +}
> >
> > /* Generate the guest OS identifier as described in the Hyper-V TLFS */
> > static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version,
> > --
> > 2.17.1
> >

2021-04-18 15:39:10

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH 1/2] x86/hyperv: Move hv_do_rep_hypercall to asm-generic

On Sun, Apr 18, 2021 at 02:42:55PM +0000, Michael Kelley wrote:
> From: Wei Liu <[email protected]> Sent: Sunday, April 18, 2021 6:09 AM
> > On Fri, Apr 16, 2021 at 05:43:02PM -0700, Joseph Salisbury wrote:
> > > From: Joseph Salisbury <[email protected]>
> > >
> > > This patch makes no functional changes. It simply moves hv_do_rep_hypercall()
> > > out of arch/x86/include/asm/mshyperv.h and into asm-generic/mshyperv.h
> > >
> > > hv_do_rep_hypercall() is architecture independent, so it makes sense that it
> > > should be in the architecture independent mshyperv.h, not in the x86-specific
> > > mshyperv.h.
> > >
> > > This is done in preperation for a follow up patch which creates a consistent
> > > pattern for checking Hyper-V hypercall status.
> > >
> > > Signed-off-by: Joseph Salisbury <[email protected]>
> > > ---
> > [...]
> > > +static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
> > > + void *input, void *output)
> > > +{
> > > + u64 control = code;
> > > + u64 status;
> > > + u16 rep_comp;
> > > +
> > > + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
> > > + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
> > > +
> > > + do {
> > > + status = hv_do_hypercall(control, input, output);
> > > + if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
> > > + return status;
> > > +
> > > + /* Bits 32-43 of status have 'Reps completed' data. */
> > > + rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
> > > + HV_HYPERCALL_REP_COMP_OFFSET;
> > > +
> > > + control &= ~HV_HYPERCALL_REP_START_MASK;
> > > + control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
> > > +
> > > + touch_nmi_watchdog();
> >
> > This seems to be missing in Arm. Does it compile?
> >
> > Wei.
>
> touch_nmi_watchdog() is defined as "static inline" in include/linux/nmi.h. So
> it should be present in all architectures. It calls arch_touch_nmi_watchdog,
> which is an empty function if CONFIG_HAVE_NMI_WATCHDOG is not defined,
> as is the case on ARM64.

I see. I couldn't find arch_touch_nmi_watchdog on Arm but missed the
stub function. Thanks for the information.

Wei.

2021-04-20 21:26:07

by Michael Kelley (LINUX)

[permalink] [raw]
Subject: RE: [PATCH 1/2] x86/hyperv: Move hv_do_rep_hypercall to asm-generic

From: Joseph Salisbury <[email protected]> Sent: Friday, April 16, 2021 5:43 PM
>
> This patch makes no functional changes. It simply moves hv_do_rep_hypercall()
> out of arch/x86/include/asm/mshyperv.h and into asm-generic/mshyperv.h
>
> hv_do_rep_hypercall() is architecture independent, so it makes sense that it
> should be in the architecture independent mshyperv.h, not in the x86-specific
> mshyperv.h.
>
> This is done in preperation for a follow up patch which creates a consistent
> pattern for checking Hyper-V hypercall status.
>
> Signed-off-by: Joseph Salisbury <[email protected]>
> ---
> arch/x86/include/asm/mshyperv.h | 32 --------------------------------
> include/asm-generic/mshyperv.h | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 31 insertions(+), 32 deletions(-)
>
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index ccf60a809a17..bfc98b490f07 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -189,38 +189,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64
> input2)
> return hv_status;
> }
>
> -/*
> - * Rep hypercalls. Callers of this functions are supposed to ensure that
> - * rep_count and varhead_size comply with Hyper-V hypercall definition.
> - */
> -static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
> - void *input, void *output)
> -{
> - u64 control = code;
> - u64 status;
> - u16 rep_comp;
> -
> - control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
> - control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
> -
> - do {
> - status = hv_do_hypercall(control, input, output);
> - if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
> - return status;
> -
> - /* Bits 32-43 of status have 'Reps completed' data. */
> - rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
> - HV_HYPERCALL_REP_COMP_OFFSET;
> -
> - control &= ~HV_HYPERCALL_REP_START_MASK;
> - control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
> -
> - touch_nmi_watchdog();
> - } while (rep_comp < rep_count);
> -
> - return status;
> -}
> -
> extern struct hv_vp_assist_page **hv_vp_assist_page;
>
> static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index dff58a3db5d5..a5246a6ea02d 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -41,6 +41,37 @@ extern struct ms_hyperv_info ms_hyperv;
> extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
> extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
>
> +/*
> + * Rep hypercalls. Callers of this functions are supposed to ensure that
> + * rep_count and varhead_size comply with Hyper-V hypercall definition.
> + */
> +static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
> + void *input, void *output)
> +{
> + u64 control = code;
> + u64 status;
> + u16 rep_comp;
> +
> + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
> + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
> +
> + do {
> + status = hv_do_hypercall(control, input, output);
> + if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
> + return status;
> +
> + /* Bits 32-43 of status have 'Reps completed' data. */
> + rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
> + HV_HYPERCALL_REP_COMP_OFFSET;
> +
> + control &= ~HV_HYPERCALL_REP_START_MASK;
> + control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
> +
> + touch_nmi_watchdog();
> + } while (rep_comp < rep_count);
> +
> + return status;
> +}
>
> /* Generate the guest OS identifier as described in the Hyper-V TLFS */
> static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version,
> --
> 2.17.1

Reviewed-by: Michael Kelley <[email protected]>