Merge branch 'x86-vmware-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Sep 2019 02:40:24 +0000 (19:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Sep 2019 02:40:24 +0000 (19:40 -0700)
Pull x86 vmware updates from Ingo Molnar:
 "This updates the VMWARE guest driver with support for VMCALL/VMMCALL
  based hypercalls"

* 'x86-vmware-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  input/vmmouse: Update the backdoor call with support for new instructions
  drm/vmwgfx: Update the backdoor call with support for new instructions
  x86/vmware: Add a header file for hypercall definitions
  x86/vmware: Update platform detection code for VMCALL/VMMCALL hypercalls

MAINTAINERS
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/vmware.h [new file with mode: 0644]
arch/x86/kernel/cpu/vmware.c
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
drivers/gpu/drm/vmwgfx/vmwgfx_msg.h
drivers/input/mouse/vmmouse.c

index 49f75d1b7b51a95d1177f6c207b9ecb0e3a1b8dc..2ca0b600d56fe15f89ed77d8cd18d1d728b8b429 100644 (file)
@@ -17193,6 +17193,7 @@ M:      "VMware, Inc." <pv-drivers@vmware.com>
 L:     virtualization@lists.linux-foundation.org
 S:     Supported
 F:     arch/x86/kernel/cpu/vmware.c
+F:     arch/x86/include/asm/vmware.h
 
 VMWARE PVRDMA DRIVER
 M:     Adit Ranadive <aditr@vmware.com>
index 3be4dcb1f80fa41c354d5bf7762dde2af632132a..0652d3eed9bda96828657cba8250cdc9903a2469 100644 (file)
 #define X86_FEATURE_VMMCALL            ( 8*32+15) /* Prefer VMMCALL to VMCALL */
 #define X86_FEATURE_XENPV              ( 8*32+16) /* "" Xen paravirtual guest */
 #define X86_FEATURE_EPT_AD             ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
+#define X86_FEATURE_VMCALL             ( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */
+#define X86_FEATURE_VMW_VMMCALL                ( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE           ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
new file mode 100644 (file)
index 0000000..e00c9e8
--- /dev/null
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+#ifndef _ASM_X86_VMWARE_H
+#define _ASM_X86_VMWARE_H
+
+#include <asm/cpufeatures.h>
+#include <asm/alternative.h>
+
+/*
+ * The hypercall definitions differ in the low word of the %edx argument
+ * in the following way: the old port base interface uses the port
+ * number to distinguish between high- and low bandwidth versions.
+ *
+ * The new vmcall interface instead uses a set of flags to select
+ * bandwidth mode and transfer direction. The flags should be loaded
+ * into %dx by any user and are automatically replaced by the port
+ * number if the VMWARE_HYPERVISOR_PORT method is used.
+ *
+ * In short, new driver code should strictly use the new definition of
+ * %dx content.
+ */
+
+/* Old port-based version */
+#define VMWARE_HYPERVISOR_PORT    "0x5658"
+#define VMWARE_HYPERVISOR_PORT_HB "0x5659"
+
+/* Current vmcall / vmmcall version */
+#define VMWARE_HYPERVISOR_HB   BIT(0)
+#define VMWARE_HYPERVISOR_OUT  BIT(1)
+
+/* The low bandwidth call. The low word of edx is presumed clear. */
+#define VMWARE_HYPERCALL                                               \
+       ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT ", %%dx; inl (%%dx)", \
+                     "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.
+ */
+#define VMWARE_HYPERCALL_HB_OUT                                                \
+       ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT_HB ", %%dx; rep outsb", \
+                     "vmcall", X86_FEATURE_VMCALL,                     \
+                     "vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+/*
+ * The high bandwidth in call. The low word of edx is presumed to have the
+ * HB bit set.
+ */
+#define VMWARE_HYPERCALL_HB_IN                                         \
+       ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT_HB ", %%dx; rep insb", \
+                     "vmcall", X86_FEATURE_VMCALL,                     \
+                     "vmmcall", X86_FEATURE_VMW_VMMCALL)
+#endif
index 3c648476d4fbabf09002690e8855816b428e424a..9735139cfdf86bcdaee7ea29a3ba7ab9a6d99270 100644 (file)
 #include <asm/hypervisor.h>
 #include <asm/timer.h>
 #include <asm/apic.h>
+#include <asm/vmware.h>
 
 #undef pr_fmt
 #define pr_fmt(fmt)    "vmware: " fmt
 
-#define CPUID_VMWARE_INFO_LEAF 0x40000000
+#define CPUID_VMWARE_INFO_LEAF               0x40000000
+#define CPUID_VMWARE_FEATURES_LEAF           0x40000010
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL    BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL     BIT(1)
+
 #define VMWARE_HYPERVISOR_MAGIC        0x564D5868
-#define VMWARE_HYPERVISOR_PORT 0x5658
 
-#define VMWARE_PORT_CMD_GETVERSION     10
-#define VMWARE_PORT_CMD_GETHZ          45
-#define VMWARE_PORT_CMD_GETVCPU_INFO   68
-#define VMWARE_PORT_CMD_LEGACY_X2APIC  3
-#define VMWARE_PORT_CMD_VCPU_RESERVED  31
+#define VMWARE_CMD_GETVERSION    10
+#define VMWARE_CMD_GETHZ         45
+#define VMWARE_CMD_GETVCPU_INFO  68
+#define VMWARE_CMD_LEGACY_X2APIC  3
+#define VMWARE_CMD_VCPU_RESERVED 31
 
 #define VMWARE_PORT(cmd, eax, ebx, ecx, edx)                           \
        __asm__("inl (%%dx)" :                                          \
-                       "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :    \
-                       "0"(VMWARE_HYPERVISOR_MAGIC),                   \
-                       "1"(VMWARE_PORT_CMD_##cmd),                     \
-                       "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) :    \
-                       "memory");
+               "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :            \
+               "a"(VMWARE_HYPERVISOR_MAGIC),                           \
+               "c"(VMWARE_CMD_##cmd),                                  \
+               "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) :            \
+               "memory")
+
+#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx)                         \
+       __asm__("vmcall" :                                              \
+               "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :            \
+               "a"(VMWARE_HYPERVISOR_MAGIC),                           \
+               "c"(VMWARE_CMD_##cmd),                                  \
+               "d"(0), "b"(UINT_MAX) :                                 \
+               "memory")
+
+#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx)                         \
+       __asm__("vmmcall" :                                             \
+               "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :            \
+               "a"(VMWARE_HYPERVISOR_MAGIC),                           \
+               "c"(VMWARE_CMD_##cmd),                                  \
+               "d"(0), "b"(UINT_MAX) :                                 \
+               "memory")
+
+#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do {               \
+       switch (vmware_hypercall_mode) {                        \
+       case CPUID_VMWARE_FEATURES_ECX_VMCALL:                  \
+               VMWARE_VMCALL(cmd, eax, ebx, ecx, edx);         \
+               break;                                          \
+       case CPUID_VMWARE_FEATURES_ECX_VMMCALL:                 \
+               VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx);        \
+               break;                                          \
+       default:                                                \
+               VMWARE_PORT(cmd, eax, ebx, ecx, edx);           \
+               break;                                          \
+       }                                                       \
+       } while (0)
 
 static unsigned long vmware_tsc_khz __ro_after_init;
+static u8 vmware_hypercall_mode     __ro_after_init;
 
 static inline int __vmware_platform(void)
 {
        uint32_t eax, ebx, ecx, edx;
-       VMWARE_PORT(GETVERSION, eax, ebx, ecx, edx);
+       VMWARE_CMD(GETVERSION, eax, ebx, ecx, edx);
        return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
 }
 
@@ -129,6 +164,10 @@ static void __init vmware_set_capabilities(void)
 {
        setup_force_cpu_cap(X86_FEATURE_CONSTANT_TSC);
        setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+       if (vmware_hypercall_mode == CPUID_VMWARE_FEATURES_ECX_VMCALL)
+               setup_force_cpu_cap(X86_FEATURE_VMCALL);
+       else if (vmware_hypercall_mode == CPUID_VMWARE_FEATURES_ECX_VMMCALL)
+               setup_force_cpu_cap(X86_FEATURE_VMW_VMMCALL);
 }
 
 static void __init vmware_platform_setup(void)
@@ -136,7 +175,7 @@ static void __init vmware_platform_setup(void)
        uint32_t eax, ebx, ecx, edx;
        uint64_t lpj, tsc_khz;
 
-       VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+       VMWARE_CMD(GETHZ, eax, ebx, ecx, edx);
 
        if (ebx != UINT_MAX) {
                lpj = tsc_khz = eax | (((uint64_t)ebx) << 32);
@@ -174,10 +213,21 @@ static void __init vmware_platform_setup(void)
        vmware_set_capabilities();
 }
 
+static u8 vmware_select_hypercall(void)
+{
+       int eax, ebx, ecx, edx;
+
+       cpuid(CPUID_VMWARE_FEATURES_LEAF, &eax, &ebx, &ecx, &edx);
+       return (ecx & (CPUID_VMWARE_FEATURES_ECX_VMMCALL |
+                      CPUID_VMWARE_FEATURES_ECX_VMCALL));
+}
+
 /*
  * While checking the dmi string information, just checking the product
  * serial key should be enough, as this will always have a VMware
  * specific string when running under VMware hypervisor.
+ * If !boot_cpu_has(X86_FEATURE_HYPERVISOR), vmware_hypercall_mode
+ * intentionally defaults to 0.
  */
 static uint32_t __init vmware_platform(void)
 {
@@ -187,8 +237,16 @@ static uint32_t __init vmware_platform(void)
 
                cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0],
                      &hyper_vendor_id[1], &hyper_vendor_id[2]);
-               if (!memcmp(hyper_vendor_id, "VMwareVMware", 12))
+               if (!memcmp(hyper_vendor_id, "VMwareVMware", 12)) {
+                       if (eax >= CPUID_VMWARE_FEATURES_LEAF)
+                               vmware_hypercall_mode =
+                                       vmware_select_hypercall();
+
+                       pr_info("hypercall mode: 0x%02x\n",
+                               (unsigned int) vmware_hypercall_mode);
+
                        return CPUID_VMWARE_INFO_LEAF;
+               }
        } else if (dmi_available && dmi_name_in_serial("VMware") &&
                   __vmware_platform())
                return 1;
@@ -200,9 +258,9 @@ static uint32_t __init vmware_platform(void)
 static bool __init vmware_legacy_x2apic_available(void)
 {
        uint32_t eax, ebx, ecx, edx;
-       VMWARE_PORT(GETVCPU_INFO, eax, ebx, ecx, edx);
-       return (eax & (1 << VMWARE_PORT_CMD_VCPU_RESERVED)) == 0 &&
-              (eax & (1 << VMWARE_PORT_CMD_LEGACY_X2APIC)) != 0;
+       VMWARE_CMD(GETVCPU_INFO, eax, ebx, ecx, edx);
+       return (eax & (1 << VMWARE_CMD_VCPU_RESERVED)) == 0 &&
+              (eax & (1 << VMWARE_CMD_LEGACY_X2APIC)) != 0;
 }
 
 const __initconst struct hypervisor_x86 x86_hyper_vmware = {
index 0af048d1a8156acfdb24af337f3b3479c4bb1004..0c647be81ab01b697db78e84e2e481d1152c16b6 100644 (file)
@@ -46,8 +46,6 @@
 #define RETRIES                 3
 
 #define VMW_HYPERVISOR_MAGIC    0x564D5868
-#define VMW_HYPERVISOR_PORT     0x5658
-#define VMW_HYPERVISOR_HB_PORT  0x5659
 
 #define VMW_PORT_CMD_MSG        30
 #define VMW_PORT_CMD_HB_MSG     0
@@ -93,7 +91,7 @@ static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
 
        VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
                (protocol | GUESTMSG_FLAG_COOKIE), si, di,
-               VMW_HYPERVISOR_PORT,
+               0,
                VMW_HYPERVISOR_MAGIC,
                eax, ebx, ecx, edx, si, di);
 
@@ -126,7 +124,7 @@ static int vmw_close_channel(struct rpc_channel *channel)
 
        VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
                0, si, di,
-               (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
+               channel->channel_id << 16,
                VMW_HYPERVISOR_MAGIC,
                eax, ebx, ecx, edx, si, di);
 
@@ -160,7 +158,8 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
                VMW_PORT_HB_OUT(
                        (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
                        msg_len, si, di,
-                       VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
+                       VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) |
+                       VMWARE_HYPERVISOR_OUT,
                        VMW_HYPERVISOR_MAGIC, bp,
                        eax, ebx, ecx, edx, si, di);
 
@@ -181,7 +180,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
 
                VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
                         word, si, di,
-                        VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
+                        channel->channel_id << 16,
                         VMW_HYPERVISOR_MAGIC,
                         eax, ebx, ecx, edx, si, di);
        }
@@ -213,7 +212,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
                VMW_PORT_HB_IN(
                        (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
                        reply_len, si, di,
-                       VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
+                       VMWARE_HYPERVISOR_HB | (channel->channel_id << 16),
                        VMW_HYPERVISOR_MAGIC, bp,
                        eax, ebx, ecx, edx, si, di);
 
@@ -230,7 +229,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
 
                VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16),
                         MESSAGE_STATUS_SUCCESS, si, di,
-                        VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
+                        channel->channel_id << 16,
                         VMW_HYPERVISOR_MAGIC,
                         eax, ebx, ecx, edx, si, di);
 
@@ -269,7 +268,7 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
 
                VMW_PORT(VMW_PORT_CMD_SENDSIZE,
                        msg_len, si, di,
-                       VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
+                       channel->channel_id << 16,
                        VMW_HYPERVISOR_MAGIC,
                        eax, ebx, ecx, edx, si, di);
 
@@ -327,7 +326,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
 
                VMW_PORT(VMW_PORT_CMD_RECVSIZE,
                        0, si, di,
-                       (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
+                       channel->channel_id << 16,
                        VMW_HYPERVISOR_MAGIC,
                        eax, ebx, ecx, edx, si, di);
 
@@ -371,7 +370,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
 
                VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
                        MESSAGE_STATUS_SUCCESS, si, di,
-                       (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
+                       channel->channel_id << 16,
                        VMW_HYPERVISOR_MAGIC,
                        eax, ebx, ecx, edx, si, di);
 
index 4907e50fb20a23a6d6ca6b88bf0b52354564c7b1..f685c7071decdd9c7affb75cc7bf93184c0721ea 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef _VMWGFX_MSG_H
 #define _VMWGFX_MSG_H
 
+#include <asm/vmware.h>
 
 /**
  * Hypervisor-specific bi-directional communication channel.  Should never
@@ -44,7 +45,7 @@
  * @in_ebx: [IN] Message Len, through EBX
  * @in_si: [IN] Input argument through SI, set to 0 if not used
  * @in_di: [IN] Input argument through DI, set ot 0 if not used
- * @port_num: [IN] port number + [channel id]
+ * @flags: [IN] hypercall flags + [channel id]
  * @magic: [IN] hypervisor magic value
  * @eax: [OUT] value of EAX register
  * @ebx: [OUT] e.g. status from an HB message status command
  * @di:  [OUT]
  */
 #define VMW_PORT(cmd, in_ebx, in_si, in_di,    \
-                port_num, magic,               \
+                flags, magic,          \
                 eax, ebx, ecx, edx, si, di)    \
 ({                                             \
-       asm volatile ("inl %%dx, %%eax;" :      \
+       asm volatile (VMWARE_HYPERCALL :        \
                "=a"(eax),                      \
                "=b"(ebx),                      \
                "=c"(ecx),                      \
@@ -67,7 +68,7 @@
                "a"(magic),                     \
                "b"(in_ebx),                    \
                "c"(cmd),                       \
-               "d"(port_num),                  \
+               "d"(flags),                     \
                "S"(in_si),                     \
                "D"(in_di) :                    \
                "memory");                      \
@@ -85,7 +86,7 @@
  * @in_ecx: [IN] Message Len, through ECX
  * @in_si: [IN] Input argument through SI, set to 0 if not used
  * @in_di: [IN] Input argument through DI, set to 0 if not used
- * @port_num: [IN] port number + [channel id]
+ * @flags: [IN] hypercall flags + [channel id]
  * @magic: [IN] hypervisor magic value
  * @bp:  [IN]
  * @eax: [OUT] value of EAX register
 #ifdef __x86_64__
 
 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,     \
-                       port_num, magic, bp,            \
+                       flags, magic, bp,               \
                        eax, ebx, ecx, edx, si, di)     \
 ({                                                     \
        asm volatile ("push %%rbp;"                     \
                "mov %12, %%rbp;"                       \
-               "rep outsb;"                            \
+               VMWARE_HYPERCALL_HB_OUT                 \
                "pop %%rbp;" :                          \
                "=a"(eax),                              \
                "=b"(ebx),                              \
                "a"(magic),                             \
                "b"(cmd),                               \
                "c"(in_ecx),                            \
-               "d"(port_num),                          \
+               "d"(flags),                             \
                "S"(in_si),                             \
                "D"(in_di),                             \
                "r"(bp) :                               \
 
 
 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,      \
-                      port_num, magic, bp,             \
+                      flags, magic, bp,                \
                       eax, ebx, ecx, edx, si, di)      \
 ({                                                     \
        asm volatile ("push %%rbp;"                     \
                "mov %12, %%rbp;"                       \
-               "rep insb;"                             \
+               VMWARE_HYPERCALL_HB_IN                  \
                "pop %%rbp" :                           \
                "=a"(eax),                              \
                "=b"(ebx),                              \
                "a"(magic),                             \
                "b"(cmd),                               \
                "c"(in_ecx),                            \
-               "d"(port_num),                          \
+               "d"(flags),                             \
                "S"(in_si),                             \
                "D"(in_di),                             \
                "r"(bp) :                               \
  * just pushed it.
  */
 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,     \
-                       port_num, magic, bp,            \
+                       flags, magic, bp,               \
                        eax, ebx, ecx, edx, si, di)     \
 ({                                                     \
        asm volatile ("push %12;"                       \
                "push %%ebp;"                           \
                "mov 0x04(%%esp), %%ebp;"               \
-               "rep outsb;"                            \
+               VMWARE_HYPERCALL_HB_OUT                 \
                "pop %%ebp;"                            \
                "add $0x04, %%esp;" :                   \
                "=a"(eax),                              \
                "a"(magic),                             \
                "b"(cmd),                               \
                "c"(in_ecx),                            \
-               "d"(port_num),                          \
+               "d"(flags),                             \
                "S"(in_si),                             \
                "D"(in_di),                             \
                "m"(bp) :                               \
 
 
 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,      \
-                      port_num, magic, bp,             \
+                      flags, magic, bp,                \
                       eax, ebx, ecx, edx, si, di)      \
 ({                                                     \
        asm volatile ("push %12;"                       \
                "push %%ebp;"                           \
                "mov 0x04(%%esp), %%ebp;"               \
-               "rep insb;"                             \
+               VMWARE_HYPERCALL_HB_IN                  \
                "pop %%ebp;"                            \
                "add $0x04, %%esp;" :                   \
                "=a"(eax),                              \
                "a"(magic),                             \
                "b"(cmd),                               \
                "c"(in_ecx),                            \
-               "d"(port_num),                          \
+               "d"(flags),                             \
                "S"(in_si),                             \
                "D"(in_di),                             \
                "m"(bp) :                               \
index 871e5b5ab129d9d5b4614c6992cfdc8d2e7a33ae..148245c69be75fbd4e97f7cf239eaf3bca61cde6 100644 (file)
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <asm/hypervisor.h>
+#include <asm/vmware.h>
 
 #include "psmouse.h"
 #include "vmmouse.h"
 
 #define VMMOUSE_PROTO_MAGIC                    0x564D5868U
-#define VMMOUSE_PROTO_PORT                     0x5658
 
 /*
  * Main commands supported by the vmmouse hypervisor port.
@@ -84,7 +84,7 @@ struct vmmouse_data {
 #define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)  \
 ({                                                     \
        unsigned long __dummy1, __dummy2;               \
-       __asm__ __volatile__ ("inl %%dx" :              \
+       __asm__ __volatile__ (VMWARE_HYPERCALL :        \
                "=a"(out1),                             \
                "=b"(out2),                             \
                "=c"(out3),                             \
@@ -94,7 +94,7 @@ struct vmmouse_data {
                "a"(VMMOUSE_PROTO_MAGIC),               \
                "b"(in1),                               \
                "c"(VMMOUSE_PROTO_CMD_##cmd),           \
-               "d"(VMMOUSE_PROTO_PORT) :               \
+               "d"(0) :                                \
                "memory");                              \
 })