From: Jinank Jain <jinankjain@xxxxxxxxxxxxxxxxxxx> Sent: Wednesday, November 2, 2022 9:36 AM > > According to TLFS, in order to communicate to L0 hypervisor there needs > to be an additional bit set in the control register. This communication > is required to perform priviledged instructions which can only be > performed by L0 hypervisor. An example of that could be setting up the > VMBus infrastructure. > > Signed-off-by: Jinank Jain <jinankjain@xxxxxxxxxxxxxxxxxxx> > --- > arch/x86/include/asm/hyperv-tlfs.h | 3 ++- > arch/x86/include/asm/mshyperv.h | 42 +++++++++++++++++++++++++++--- > include/asm-generic/hyperv-tlfs.h | 1 + > include/asm-generic/mshyperv.h | 1 + > 4 files changed, 42 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h > index 0319091e2019..fd066226f12b 100644 > --- a/arch/x86/include/asm/hyperv-tlfs.h > +++ b/arch/x86/include/asm/hyperv-tlfs.h > @@ -380,7 +380,8 @@ struct hv_nested_enlightenments_control { > __u32 reserved:31; > } features; > struct { > - __u32 reserved; > + __u32 inter_partition_comm:1; > + __u32 reserved:31; > } hypercallControls; > } __packed; > > diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h > index 415289757428..451d8c3ab63b 100644 > --- a/arch/x86/include/asm/mshyperv.h > +++ b/arch/x86/include/asm/mshyperv.h > @@ -74,10 +74,16 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void > *output) > return hv_status; > } > > +/* Hypercall to the L0 hypervisor */ > +static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output) > +{ > + return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output); > +} > + > /* Fast hypercall with 8 bytes of input and no output */ > -static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) > +static inline u64 _hv_do_fast_hypercall8(u64 control, u16 code, u64 input1) > { > - u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT; > + u64 hv_status; > > #ifdef CONFIG_X86_64 > { > @@ -105,10 +111,24 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) > return hv_status; > } > > +static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) > +{ > + u64 control = (u64)code | HV_HYPERCALL_FAST_BIT; > + > + return _hv_do_fast_hypercall8(control, code, input1); > +} > + > +static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1) > +{ > + u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED; > + > + return _hv_do_fast_hypercall8(control, code, input1); > +} > + > /* Fast hypercall with 16 bytes of input */ > -static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2) > +static inline u64 _hv_do_fast_hypercall16(u64 control, u16 code, u64 input1, u64 input2) > { > - u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT; > + u64 hv_status; > > #ifdef CONFIG_X86_64 > { > @@ -139,6 +159,20 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2) > return hv_status; > } > > +static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2) > +{ > + u64 control = (u64)code | HV_HYPERCALL_FAST_BIT; > + > + return _hv_do_fast_hypercall16(control, code, input1, input2); > +} > + > +static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2) > +{ > + u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED; > + > + return _hv_do_fast_hypercall16(control, code, input1, input2); > +} > + > 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/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h > index fdce7a4cfc6f..c67836dd8468 100644 > --- a/include/asm-generic/hyperv-tlfs.h > +++ b/include/asm-generic/hyperv-tlfs.h > @@ -185,6 +185,7 @@ enum HV_GENERIC_SET_FORMAT { > #define HV_HYPERCALL_VARHEAD_OFFSET 17 > #define HV_HYPERCALL_VARHEAD_MASK GENMASK_ULL(26, 17) > #define HV_HYPERCALL_RSVD0_MASK GENMASK_ULL(31, 27) > +#define HV_HYPERCALL_NESTED BIT(31) Since it is used with a bunch of other u64 values, the above should probably be BIT_ULL(31). > #define HV_HYPERCALL_REP_COMP_OFFSET 32 > #define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32) > #define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32) > diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h > index bfb9eb9d7215..a2524d96ce2d 100644 > --- a/include/asm-generic/mshyperv.h > +++ b/include/asm-generic/mshyperv.h > @@ -53,6 +53,7 @@ extern void * __percpu *hyperv_pcpu_input_arg; > extern void * __percpu *hyperv_pcpu_output_arg; > > extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr); > +extern u64 hv_do_nested_hypercall(u64 control, void *inputaddr, void *outputaddr); Is this needed? hv_do_nested_hypercall() is implemented as a static inline function in the x86-specific version of mshyperv.h, so this seems duplicative. But maybe I'm missing something .... > extern u64 hv_do_fast_hypercall8(u16 control, u64 input8); > extern bool hv_isolation_type_snp(void); > > -- > 2.25.1