Re: [PATCH v2 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-04 Thread Borislav Petkov
On Fri, Dec 01, 2023 at 03:24:48PM -0800, Alexey Makhalov wrote:
> Introducing vmware_hypercall family of functions as a common
> implementation to be used by the VMware guest code and virtual
> device drivers in architecture independent manner.
> 
> By analogy with KVM hypercall API, vmware_hypercallX and
> vmware_hypercall_hb_{out,in} set of functions was added to
> achieve that. Architecture specific implementation should be
> hidden inside.

Pls read section "2) Describe your changes" in
Documentation/process/submitting-patches.rst for more details on how to
formulate your commit messages.

Also, see section "Changelog" in Documentation/process/maintainer-tip.rst

More specifically:

"Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy
to do frotz", as if you are giving orders to the codebase to change
its behaviour."

Thx.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette


[PATCH v2 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-01 Thread Alexey Makhalov
Introducing vmware_hypercall family of functions as a common
implementation to be used by the VMware guest code and virtual
device drivers in architecture independent manner.

By analogy with KVM hypercall API, vmware_hypercallX and
vmware_hypercall_hb_{out,in} set of functions was added to
achieve that. Architecture specific implementation should be
hidden inside.

It will simplify future enhancements in VMware hypercalls such
as SEV-ES and TDX related changes without needs to modify a
caller in device drivers code.

Current implementation extends an idea from commit bac7b4e84323
("x86/vmware: Update platform detection code for VMCALL/VMMCALL
hypercalls") to have a slow, but safe path in VMWARE_HYPERCALL
earlier during the boot when alternatives are not yet applied.
This logic was inherited from VMWARE_CMD from the commit mentioned
above. Default alternative code was optimized by size to reduce
excessive nop alignment once alternatives are applied. Total
default code size is 26 bytes, in worse case (3 bytes alternative)
remaining 23 bytes will be aligned by only 3 long NOP instructions.

Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
Reviewed-by: Jeff Sipek 
---
 arch/x86/include/asm/vmware.h | 262 ++
 arch/x86/kernel/cpu/vmware.c  |  35 ++---
 2 files changed, 220 insertions(+), 77 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 8cabf4a577bf..17091eba68cb 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,69 +40,219 @@
 
 extern u8 vmware_hypercall_mode;
 
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL   \
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
- "inl (%%dx), %%eax",  \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
-
 /*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * The low bandwidth call. The low word of edx is presumed to have OUT bit
+ * set. The high word of edx may contain input data from the caller.
  */
-#define VMWARE_HYPERCALL_HB_OUT
\
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; 
" \
- "rep outsb",  \
+#define VMWARE_HYPERCALL   \
+   ALTERNATIVE_3("cmpb $"  \
+   __stringify(CPUID_VMWARE_FEATURES_ECX_VMMCALL)  \
+   ", %[mode]\n\t" \
+ "jg 2f\n\t"   \
+ "je 1f\n\t"   \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax\n\t"   \
+ "jmp 3f\n\t"  \
+ "1: vmmcall\n\t"  \
+ "jmp 3f\n\t"  \
+ "2: vmcall\n\t"   \
+ "3:\n\t", \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax", X86_FEATURE_HYPERVISOR,  \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
 
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0), "=b" (*out1), "=c" (*out2)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+   uint32_t *ou