On 14. 04. 25 13:11, Peter Zijlstra wrote:
What used to be a simple few instructions has turned into a giant mess
(for x86_64). Not only does it use static_branch wrong, it mixes it
with dynamic branches for no apparent reason.

Notably it uses static_branch through an out-of-line function call,
which completely defeats the purpose, since instead of a simple
JMP/NOP site, you get a CALL+RET+TEST+Jcc sequence in return, which is
absolutely idiotic.

Add to that a dynamic test of hyperv_paravisor_present, something
which is set once and never changed.

Replace all this idiocy with a single direct function call to the
right hypercall variant.

Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
---
  arch/x86/hyperv/hv_init.c       |   21 ++++++
  arch/x86/hyperv/ivm.c           |   14 ++++
  arch/x86/include/asm/mshyperv.h |  137 
+++++++++++-----------------------------
  arch/x86/kernel/cpu/mshyperv.c  |   18 +++--
  4 files changed, 88 insertions(+), 102 deletions(-)

--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -35,7 +35,28 @@
  #include <linux/highmem.h>
void *hv_hypercall_pg;
+
+#ifdef CONFIG_X86_64
+u64 hv_pg_hypercall(u64 control, u64 param1, u64 param2)
+{
+       u64 hv_status;
+
+       if (!hv_hypercall_pg)
+               return U64_MAX;
+
+       register u64 __r8 asm("r8") = param2;
+       asm volatile (CALL_NOSPEC
+                     : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                       "+c" (control), "+d" (param1)
+                     : "r" (__r8),

r8 is call-clobbered register, so you should use "+r" (__r8) to properly clobber it:

                        "+c" (control), "+d" (param1), "+r" (__r8)
                      : THUNK_TARGET(hv_hypercall_pg)

+                     : "cc", "memory", "r9", "r10", "r11");
+
+       return hv_status;
+}
+#else
  EXPORT_SYMBOL_GPL(hv_hypercall_pg);
+#endif
union hv_ghcb * __percpu *hv_ghcb_pg; --- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -376,6 +376,20 @@ int hv_snp_boot_ap(u32 cpu, unsigned lon
        return ret;
  }
+u64 hv_snp_hypercall(u64 control, u64 param1, u64 param2)
+{
+       u64 hv_status;
+
+       register u64 __r8 asm("r8") = param2;
+       asm volatile("vmmcall"
+                    : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                      "+c" (control), "+d" (param1)
+                    : "r" (__r8)

Also here:
                        "+c" (control), "+d" (param1), "+r" (__r8)
                      :

+                    : "cc", "memory", "r9", "r10", "r11");
+
+       return hv_status;
+}

Uros.

Reply via email to