x86/hyperv: Add an interface to do nested hypercalls
authorJinank Jain <jinankjain@linux.microsoft.com>
Mon, 2 Jan 2023 07:12:53 +0000 (07:12 +0000)
committerWei Liu <wei.liu@kernel.org>
Tue, 17 Jan 2023 13:37:19 +0000 (13:37 +0000)
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 privileged 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@linux.microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/24f9d46d5259a688113e6e5e69e21002647f4949.1672639707.git.jinankjain@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
arch/x86/include/asm/hyperv-tlfs.h
arch/x86/include/asm/mshyperv.h
include/asm-generic/hyperv-tlfs.h

index 271d081dc2513c11cb50f2f3919658a29ad219f7..566ac26239bacc1e6dc1d7bccb30d69e267d93f1 100644 (file)
@@ -382,7 +382,8 @@ struct hv_nested_enlightenments_control {
                __u32 reserved:31;
        } features;
        struct {
-               __u32 reserved;
+               __u32 inter_partition_comm:1;
+               __u32 reserved:31;
        } hypercallControls;
 } __packed;
 
index e3e91b4f299c7eaced5a85c2363f127b907fa8d0..15ac2d03ac59bdc074b8a17f231ab61e5177c6fc 100644 (file)
@@ -72,10 +72,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, u64 input1)
 {
-       u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT;
+       u64 hv_status;
 
 #ifdef CONFIG_X86_64
        {
@@ -103,10 +109,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, 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, 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, u64 input1, u64 input2)
 {
-       u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT;
+       u64 hv_status;
 
 #ifdef CONFIG_X86_64
        {
@@ -137,6 +157,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, 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, 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)
index e29ccabf2e09de80381373a717d90c2675624d80..b870983596b93b77340cb1115d8a73578e3eaf23 100644 (file)
@@ -194,6 +194,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_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)