These macros will be used by multiple VMWare modules for handling host communication. v2: * Keeping only the minimal common platform defines * added vmware_platform() check function v3: * Added new field to handle different hypervisor magic values Signed-off-by: Sinclair Yeh <syeh at vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com> Reviewed-by: Alok N Kataria <akataria at vmware.com> Cc: Thomas Gleixner <tglx at linutronix.de> Cc: Ingo Molnar <mingo at redhat.com> Cc: "H. Peter Anvin" <hpa at zytor.com> Cc: Alok Kataria <akataria at vmware.com> Cc: linux-kernel at vger.kernel.org Cc: virtualization at lists.linux-foundation.org Cc: Xavier Deguillard <xdeguillard at vmware.com> --- arch/x86/include/asm/vmware.h | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 arch/x86/include/asm/vmware.h diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h new file mode 100644 index 0000000..32bf99b --- /dev/null +++ b/arch/x86/include/asm/vmware.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2015, VMware, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * Based on code from vmware.c and vmmouse.c. + * Author: + * Sinclair Yeh <syeh at vmware.com> + */ +#ifndef _ASM_X86_VMWARE_H +#define _ASM_X86_VMWARE_H + + +/** + * Hypervisor-specific bi-directional communication channel. Should never + * execute on bare metal hardware. The caller must make sure to check for + * supported hypervisor before using these macros. + * + * Several of the parameters are both input and output and must be initialized. + * + * @in1: [IN] Message Len or Message Cmd (HB) + * @in2: [IN] Message Len (HB) or Message Cmd + * @port_num: [IN] port number + [channel id] + * @magic: [IN] hypervisor magic value + * @eax: [OUT] value of EAX register + * @ebx: [OUT] e.g. status from an HB message status command + * @ecx: [OUT] e.g. status from a non-HB message status command + * @edx: [OUT] e.g. channel id + * @si: [INOUT] set to 0 if not used + * @di: [INOUT] set to 0 if not used + * @bp: [INOUT] set to 0 if not used + */ +#define VMW_PORT(in1, in2, port_num, magic, eax, ebx, ecx, edx, si, di) \ +({ \ + __asm__ __volatile__ ("inl %%dx" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(in1), \ + "c"(in2), \ + "d"(port_num), \ + "S"(si), \ + "D"(di) : \ + "memory"); \ +}) + + +#define VMW_PORT_HB_OUT(in1, in2, port_num, magic, \ + eax, ebx, ecx, edx, si, di, bp) \ +({ \ + __asm__ __volatile__ ("movq %13, %%rbp;" \ + "cld; rep outsb; " \ + "movq %%rbp, %6" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di), \ + "=r"(bp) : \ + "a"(magic), \ + "b"(in1), \ + "c"(in2), \ + "d"(port_num), \ + "S"(si), \ + "D"(di), \ + "r"(bp) : \ + "memory", "cc"); \ +}) + + +#define VMW_PORT_HB_IN(in1, in2, port_num, magic, \ + eax, ebx, ecx, edx, si, di, bp) \ +({ \ + __asm__ __volatile__ ("push %%rbp; movq %13, %%rbp;" \ + "cld; rep insb; " \ + "movq %%rbp, %6;pop %%rbp" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di), \ + "=r"(bp) : \ + "a"(magic), \ + "b"(in1), \ + "c"(in2), \ + "d"(port_num), \ + "S"(si), \ + "D"(di), \ + "r"(bp) : \ + "memory", "cc"); \ +}) + + +#endif + -- 1.9.1
Sinclair Yeh
2015-Dec-01 22:18 UTC
[PATCH 2/6] x86: Update vmware.c to use the common VMW_PORT macros
v2: Instead of replacing all existing instances of VMWARE_PORT with VMW_PORT, update VMWARE_PORT to use the new VMW_PORT. v3: Using updated VMWARE_PORT() macro, which needs hypervisor magic in the parameter Signed-off-by: Sinclair Yeh <syeh at vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com> Reviewed-by: Alok N Kataria <akataria at vmware.com> Cc: Thomas Gleixner <tglx at linutronix.de> Cc: Ingo Molnar <mingo at redhat.com> Cc: "H. Peter Anvin" <hpa at zytor.com> Cc: pv-drivers at vmware.com Cc: virtualization at lists.linux-foundation.org Cc: linux-kernel at vger.kernel.org --- arch/x86/kernel/cpu/vmware.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 628a059..1837f66 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -26,6 +26,7 @@ #include <asm/div64.h> #include <asm/x86_init.h> #include <asm/hypervisor.h> +#include <asm/vmware.h> #define CPUID_VMWARE_INFO_LEAF 0x40000000 #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 @@ -37,13 +38,14 @@ #define VMWARE_PORT_CMD_LEGACY_X2APIC 3 #define VMWARE_PORT_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"); +#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ +({ \ + unsigned long __si = 0, __di = 0; \ + VMW_PORT(UINT_MAX, VMWARE_PORT_CMD_##cmd, VMWARE_HYPERVISOR_PORT, \ + VMWARE_HYPERVISOR_MAGIC, \ + eax, ebx, ecx, edx, __si, __di); \ +}) + static inline int __vmware_platform(void) { -- 1.9.1
Sinclair Yeh
2015-Dec-01 22:18 UTC
[PATCH 3/6] Input: Update vmmouse.c to use the common VMW_PORT macros
v2: Instead of replacing existing VMMOUSE defines, only modify enough to use the new VMW_PORT define. v3: Use updated VMWARE_PORT() which requires hypervisor magic as an added parameter Signed-off-by: Sinclair Yeh <syeh at vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com> Reviewed-by: Alok N Kataria <akataria at vmware.com> Cc: pv-drivers at vmware.com Cc: linux-graphics-maintainer at vmware.com Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com> Cc: Arnd Bergmann <arnd at arndb.de> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org> Cc: linux-kernel at vger.kernel.org Cc: virtualization at lists.linux-foundation.org Cc: linux-input at vger.kernel.org --- drivers/input/mouse/vmmouse.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c index e272f06..d34e3e4 100644 --- a/drivers/input/mouse/vmmouse.c +++ b/drivers/input/mouse/vmmouse.c @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <asm/hypervisor.h> +#include <asm/vmware.h> #include "psmouse.h" #include "vmmouse.h" @@ -84,21 +85,12 @@ struct vmmouse_data { * implementing the vmmouse protocol. Should never execute on * bare metal hardware. */ -#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ -({ \ - unsigned long __dummy1, __dummy2; \ - __asm__ __volatile__ ("inl %%dx" : \ - "=a"(out1), \ - "=b"(out2), \ - "=c"(out3), \ - "=d"(out4), \ - "=S"(__dummy1), \ - "=D"(__dummy2) : \ - "a"(VMMOUSE_PROTO_MAGIC), \ - "b"(in1), \ - "c"(VMMOUSE_PROTO_CMD_##cmd), \ - "d"(VMMOUSE_PROTO_PORT) : \ - "memory"); \ +#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ +({ \ + unsigned long __dummy1 = 0, __dummy2 = 0; \ + VMW_PORT(in1, VMMOUSE_PROTO_CMD_##cmd, VMMOUSE_PROTO_PORT, \ + VMMOUSE_PROTO_MAGIC, \ + out1, out2, out3, out4, __dummy1, __dummy2); \ }) /** -- 1.9.1
Port reservation is not required. Furthermore, this port is shared by other VMware services for host-side communication. Signed-off-by: Sinclair Yeh <syeh at vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com> Cc: pv-drivers at vmware.com Cc: linux-graphics-maintainer at vmware.com Cc: virtualization at lists.linux-foundation.org Cc: linux-kernel at vger.kernel.org --- drivers/input/mouse/vmmouse.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c index d34e3e4..9109d54 100644 --- a/drivers/input/mouse/vmmouse.c +++ b/drivers/input/mouse/vmmouse.c @@ -347,16 +347,10 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties) return -ENXIO; } - if (!request_region(VMMOUSE_PROTO_PORT, 4, "vmmouse")) { - psmouse_dbg(psmouse, "VMMouse port in use.\n"); - return -EBUSY; - } - /* Check if the device is present */ response = ~VMMOUSE_PROTO_MAGIC; VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2); if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU) { - release_region(VMMOUSE_PROTO_PORT, 4); return -ENXIO; } @@ -366,8 +360,6 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties) psmouse->model = version; } - release_region(VMMOUSE_PROTO_PORT, 4); - return 0; } @@ -386,7 +378,6 @@ static void vmmouse_disconnect(struct psmouse *psmouse) psmouse_reset(psmouse); input_unregister_device(priv->abs_dev); kfree(priv); - release_region(VMMOUSE_PROTO_PORT, 4); } /** @@ -430,15 +421,10 @@ int vmmouse_init(struct psmouse *psmouse) struct input_dev *rel_dev = psmouse->dev, *abs_dev; int error; - if (!request_region(VMMOUSE_PROTO_PORT, 4, "vmmouse")) { - psmouse_dbg(psmouse, "VMMouse port in use.\n"); - return -EBUSY; - } - psmouse_reset(psmouse); error = vmmouse_enable(psmouse); if (error) - goto release_region; + return error; priv = kzalloc(sizeof(*priv), GFP_KERNEL); abs_dev = input_allocate_device(); @@ -493,8 +479,5 @@ init_fail: kfree(priv); psmouse->private = NULL; -release_region: - release_region(VMMOUSE_PROTO_PORT, 4); - return error; } -- 1.9.1
Sinclair Yeh
2015-Dec-01 22:18 UTC
[PATCH 6/6] VMware balloon: Update vmw_balloon.c to use the VMW_PORT macro
Signed-off-by: Sinclair Yeh <syeh at vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com> Reviewed-by: Alok N Kataria <akataria at vmware.com> Cc: pv-drivers at vmware.com Cc: Xavier Deguillard <xdeguillard at vmware.com> Cc: linux-kernel at vger.kernel.org Cc: virtualization at lists.linux-foundation.org --- drivers/misc/vmw_balloon.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index ffb5634..90a0d07 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -43,6 +43,7 @@ #include <linux/debugfs.h> #include <linux/seq_file.h> #include <asm/hypervisor.h> +#include <asm/vmware.h> MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver"); @@ -142,23 +143,17 @@ enum vmwballoon_capabilities { #define VMW_BALLOON_SUCCESS_WITH_CAPABILITIES (0x03000000) -#define VMWARE_BALLOON_CMD(cmd, data, result) \ -({ \ - unsigned long __status, __dummy1, __dummy2; \ - __asm__ __volatile__ ("inl %%dx" : \ - "=a"(__status), \ - "=c"(__dummy1), \ - "=d"(__dummy2), \ - "=b"(result) : \ - "0"(VMW_BALLOON_HV_MAGIC), \ - "1"(VMW_BALLOON_CMD_##cmd), \ - "2"(VMW_BALLOON_HV_PORT), \ - "3"(data) : \ - "memory"); \ - if (VMW_BALLOON_CMD_##cmd == VMW_BALLOON_CMD_START) \ - result = __dummy1; \ - result &= -1UL; \ - __status & -1UL; \ +#define VMWARE_BALLOON_CMD(cmd, data, result) \ +({ \ + unsigned long __status, __dummy1, __dummy2; \ + unsigned long __si = 0, __di = 0; \ + VMW_PORT(data, VMW_BALLOON_CMD_##cmd, VMW_BALLOON_HV_PORT, \ + VMW_BALLOON_HV_MAGIC, \ + __status, result, __dummy1, __dummy2, __si, __di);\ + if (VMW_BALLOON_CMD_##cmd == VMW_BALLOON_CMD_START) \ + result = __dummy1; \ + result &= -1UL; \ + __status & -1UL; \ }) #ifdef CONFIG_DEBUG_FS -- 1.9.1
Dmitry Torokhov
2015-Dec-01 22:24 UTC
[PATCH 3/6] Input: Update vmmouse.c to use the common VMW_PORT macros
On Tue, Dec 01, 2015 at 02:18:49PM -0800, Sinclair Yeh wrote:> v2: > Instead of replacing existing VMMOUSE defines, only modify enough > to use the new VMW_PORT define. > > v3: > Use updated VMWARE_PORT() which requires hypervisor magic as an added > parameter > > Signed-off-by: Sinclair Yeh <syeh at vmware.com> > Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com> > Reviewed-by: Alok N Kataria <akataria at vmware.com> > Cc: pv-drivers at vmware.com > Cc: linux-graphics-maintainer at vmware.com > Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com> > Cc: Arnd Bergmann <arnd at arndb.de> > Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org> > Cc: linux-kernel at vger.kernel.org > Cc: virtualization at lists.linux-foundation.org > Cc: linux-input at vger.kernel.org > --- > drivers/input/mouse/vmmouse.c | 22 +++++++--------------- > 1 file changed, 7 insertions(+), 15 deletions(-) > > diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c > index e272f06..d34e3e4 100644 > --- a/drivers/input/mouse/vmmouse.c > +++ b/drivers/input/mouse/vmmouse.c > @@ -19,6 +19,7 @@ > #include <linux/slab.h> > #include <linux/module.h> > #include <asm/hypervisor.h> > +#include <asm/vmware.h> > > #include "psmouse.h" > #include "vmmouse.h" > @@ -84,21 +85,12 @@ struct vmmouse_data { > * implementing the vmmouse protocol. Should never execute on > * bare metal hardware. > */ > -#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ > -({ \ > - unsigned long __dummy1, __dummy2; \ > - __asm__ __volatile__ ("inl %%dx" : \ > - "=a"(out1), \ > - "=b"(out2), \ > - "=c"(out3), \ > - "=d"(out4), \ > - "=S"(__dummy1), \ > - "=D"(__dummy2) : \ > - "a"(VMMOUSE_PROTO_MAGIC), \ > - "b"(in1), \ > - "c"(VMMOUSE_PROTO_CMD_##cmd), \ > - "d"(VMMOUSE_PROTO_PORT) : \ > - "memory"); \ > +#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ > +({ \ > + unsigned long __dummy1 = 0, __dummy2 = 0; \Why do we need to initialize dummies?> + VMW_PORT(in1, VMMOUSE_PROTO_CMD_##cmd, VMMOUSE_PROTO_PORT, \ > + VMMOUSE_PROTO_MAGIC, \ > + out1, out2, out3, out4, __dummy1, __dummy2); \ > }) >Thanks. -- Dmitry
Hi Sinclair, On Tue, Dec 1, 2015 at 2:18 PM, Sinclair Yeh <syeh at vmware.com> wrote:> Port reservation is not required.You need to expand on why we do not need to reserve port.> Furthermore, this port is shared > by other VMware services for host-side communication.What services would that be? Do they reserve the port? Thanks. -- Dmitry
Xavier Deguillard
2015-Dec-01 22:32 UTC
[PATCH 1/6] x86: Add VMWare Host Communication Macros
Hey Sinclair, On Tue, Dec 01, 2015 at 02:18:47PM -0800, Sinclair Yeh wrote:> +/** > + * Hypervisor-specific bi-directional communication channel. Should never > + * execute on bare metal hardware. The caller must make sure to check for > + * supported hypervisor before using these macros. > + * > + * Several of the parameters are both input and output and must be initialized. > + * > + * @in1: [IN] Message Len or Message Cmd (HB) > + * @in2: [IN] Message Len (HB) or Message CmdCan you make in1 always be the "Message Cmd" and in2 always be the "Message len"?> + * @port_num: [IN] port number + [channel id] > + * @magic: [IN] hypervisor magic value > + * @eax: [OUT] value of EAX register > + * @ebx: [OUT] e.g. status from an HB message status command > + * @ecx: [OUT] e.g. status from a non-HB message status command > + * @edx: [OUT] e.g. channel id > + * @si: [INOUT] set to 0 if not used > + * @di: [INOUT] set to 0 if not used > + * @bp: [INOUT] set to 0 if not used > + */ > +#define VMW_PORT(in1, in2, port_num, magic, eax, ebx, ecx, edx, si, di) \ > +({ \ > + __asm__ __volatile__ ("inl %%dx" : \Are those '\' aligned in the code?> + > +#define VMW_PORT_HB_OUT(in1, in2, port_num, magic, \ > + eax, ebx, ecx, edx, si, di, bp) \ > +({ \ > + __asm__ __volatile__ ("movq %13, %%rbp;" \Same here.> + > +#define VMW_PORT_HB_IN(in1, in2, port_num, magic, \ > + eax, ebx, ecx, edx, si, di, bp) \ > +({ \ > + __asm__ __volatile__ ("push %%rbp; movq %13, %%rbp;" \Same. Xavier
Xavier Deguillard
2015-Dec-01 22:38 UTC
[PATCH 6/6] VMware balloon: Update vmw_balloon.c to use the VMW_PORT macro
Hey Sinclair, On Tue, Dec 01, 2015 at 02:18:52PM -0800, Sinclair Yeh wrote:> +#define VMWARE_BALLOON_CMD(cmd, data, result) \ > +({ \ > + unsigned long __status, __dummy1, __dummy2; \ > + unsigned long __si = 0, __di = 0; \ > + VMW_PORT(data, VMW_BALLOON_CMD_##cmd, VMW_BALLOON_HV_PORT, \ > + VMW_BALLOON_HV_MAGIC, \ > + __status, result, __dummy1, __dummy2, __si, __di);\ > + if (VMW_BALLOON_CMD_##cmd == VMW_BALLOON_CMD_START) \ > + result = __dummy1; \ > + result &= -1UL; \ > + __status & -1UL; \ > })You need to indent the '\' with tabs only, and it looks like spaces are present here (which is also why they don't look aligned). Other than that I'm good with this: Acked-by: Xavier Deguillard <xdeguillard at vmware.com> Xavier
H. Peter Anvin
2015-Dec-01 22:49 UTC
[PATCH 1/6] x86: Add VMWare Host Communication Macros
On 12/01/15 14:18, Sinclair Yeh wrote:> These macros will be used by multiple VMWare modules for handling > host communication.> + __asm__ __volatile__ ("inl %%dx" : \This is odd at best; the standard assembly form of this instruction is: inl (%dx),%eax Also, we don't need the underscored forms of asm and volatile for kernel code.> + __asm__ __volatile__ ("movq %13, %%rbp;" \ > + "cld; rep outsb; " \ > + "movq %%rbp, %6" : \cld shouldn't be necessary here, DF=0 is part of the normal ABI environment. You also don't save/restore %rbp here, but you do below? Seems very odd. It might be better do so something like: +#define VMW_PORT_HB_OUT(in1, in2, port_num, magic, \ + eax, ebx, ecx, edx, si, di, bp) \ +({ \ + __asm__ __volatile__ ("xchgq %6, %%rbp;" \ + "cld; rep outsb; " \ + "xchgq %%rbp, %6" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "+S"(si), \ + "+D"(di), \ + "+r"(bp) : \ + "a"(magic), \ + "b"(in1), \ + "c"(in2), \ + "d"(port_num) : \ + "memory", "cc"); \ +})
Greg Kroah-Hartman
2015-Dec-02 00:01 UTC
[PATCH 3/6] Input: Update vmmouse.c to use the common VMW_PORT macros
On Tue, Dec 01, 2015 at 02:18:49PM -0800, Sinclair Yeh wrote:> v2: > Instead of replacing existing VMMOUSE defines, only modify enough > to use the new VMW_PORT define. > > v3: > Use updated VMWARE_PORT() which requires hypervisor magic as an added > parameterWhy are these here and not below the --- line? And no changelog text at all? Not acceptable :( greg k-h
Thanks Peter. On Tue, Dec 01, 2015 at 02:49:11PM -0800, H. Peter Anvin wrote:> On 12/01/15 14:18, Sinclair Yeh wrote: > > These macros will be used by multiple VMWare modules for handling > > host communication. > > > + __asm__ __volatile__ ("inl %%dx" : \ > > This is odd at best; the standard assembly form of this instruction is: > > inl (%dx),%eaxOk, I'm not sure why this worked and compiled before. Fixed.> > Also, we don't need the underscored forms of asm and volatile for kernel > code. > > > + __asm__ __volatile__ ("movq %13, %%rbp;" \ > > + "cld; rep outsb; " \ > > + "movq %%rbp, %6" : \ > > cld shouldn't be necessary here, DF=0 is part of the normal ABI environment. > > You also don't save/restore %rbp here, but you do below? Seems very odd.Good catch. Fixed.> > It might be better do so something like: > > +#define VMW_PORT_HB_OUT(in1, in2, port_num, magic, \ > + eax, ebx, ecx, edx, si, di, bp) \ > +({ \ > + __asm__ __volatile__ ("xchgq %6, %%rbp;" \ > + "cld; rep outsb; " \ > + "xchgq %%rbp, %6" : \ > + "=a"(eax), \ > + "=b"(ebx), \ > + "=c"(ecx), \ > + "=d"(edx), \ > + "+S"(si), \ > + "+D"(di), \ > + "+r"(bp) : \ > + "a"(magic), \ > + "b"(in1), \ > + "c"(in2), \ > + "d"(port_num) : \ > + "memory", "cc"); \ > +})This is great. Changed. Updated patch set incoming. Sinclair