1b4dd4f6eSThomas Hellstrom /* SPDX-License-Identifier: GPL-2.0 or MIT */ 2b4dd4f6eSThomas Hellstrom #ifndef _ASM_X86_VMWARE_H 3b4dd4f6eSThomas Hellstrom #define _ASM_X86_VMWARE_H 4b4dd4f6eSThomas Hellstrom 5b4dd4f6eSThomas Hellstrom #include <asm/cpufeatures.h> 6b4dd4f6eSThomas Hellstrom #include <asm/alternative.h> 7*6fee2a0bSThomas Hellstrom #include <linux/stringify.h> 8b4dd4f6eSThomas Hellstrom 9b4dd4f6eSThomas Hellstrom /* 10b4dd4f6eSThomas Hellstrom * The hypercall definitions differ in the low word of the %edx argument 11b4dd4f6eSThomas Hellstrom * in the following way: the old port base interface uses the port 12b4dd4f6eSThomas Hellstrom * number to distinguish between high- and low bandwidth versions. 13b4dd4f6eSThomas Hellstrom * 14b4dd4f6eSThomas Hellstrom * The new vmcall interface instead uses a set of flags to select 15b4dd4f6eSThomas Hellstrom * bandwidth mode and transfer direction. The flags should be loaded 16b4dd4f6eSThomas Hellstrom * into %dx by any user and are automatically replaced by the port 17b4dd4f6eSThomas Hellstrom * number if the VMWARE_HYPERVISOR_PORT method is used. 18b4dd4f6eSThomas Hellstrom * 19b4dd4f6eSThomas Hellstrom * In short, new driver code should strictly use the new definition of 20b4dd4f6eSThomas Hellstrom * %dx content. 21b4dd4f6eSThomas Hellstrom */ 22b4dd4f6eSThomas Hellstrom 23b4dd4f6eSThomas Hellstrom /* Old port-based version */ 24*6fee2a0bSThomas Hellstrom #define VMWARE_HYPERVISOR_PORT 0x5658 25*6fee2a0bSThomas Hellstrom #define VMWARE_HYPERVISOR_PORT_HB 0x5659 26b4dd4f6eSThomas Hellstrom 27b4dd4f6eSThomas Hellstrom /* Current vmcall / vmmcall version */ 28b4dd4f6eSThomas Hellstrom #define VMWARE_HYPERVISOR_HB BIT(0) 29b4dd4f6eSThomas Hellstrom #define VMWARE_HYPERVISOR_OUT BIT(1) 30b4dd4f6eSThomas Hellstrom 31b4dd4f6eSThomas Hellstrom /* The low bandwidth call. The low word of edx is presumed clear. */ 32b4dd4f6eSThomas Hellstrom #define VMWARE_HYPERCALL \ 33*6fee2a0bSThomas Hellstrom ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \ 34db633a4eSThomas Hellstrom "inl (%%dx), %%eax", \ 35b4dd4f6eSThomas Hellstrom "vmcall", X86_FEATURE_VMCALL, \ 36b4dd4f6eSThomas Hellstrom "vmmcall", X86_FEATURE_VMW_VMMCALL) 37b4dd4f6eSThomas Hellstrom 38b4dd4f6eSThomas Hellstrom /* 39b4dd4f6eSThomas Hellstrom * The high bandwidth out call. The low word of edx is presumed to have the 40b4dd4f6eSThomas Hellstrom * HB and OUT bits set. 41b4dd4f6eSThomas Hellstrom */ 42b4dd4f6eSThomas Hellstrom #define VMWARE_HYPERCALL_HB_OUT \ 43*6fee2a0bSThomas Hellstrom ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \ 44*6fee2a0bSThomas Hellstrom "rep outsb", \ 45b4dd4f6eSThomas Hellstrom "vmcall", X86_FEATURE_VMCALL, \ 46b4dd4f6eSThomas Hellstrom "vmmcall", X86_FEATURE_VMW_VMMCALL) 47b4dd4f6eSThomas Hellstrom 48b4dd4f6eSThomas Hellstrom /* 49b4dd4f6eSThomas Hellstrom * The high bandwidth in call. The low word of edx is presumed to have the 50b4dd4f6eSThomas Hellstrom * HB bit set. 51b4dd4f6eSThomas Hellstrom */ 52b4dd4f6eSThomas Hellstrom #define VMWARE_HYPERCALL_HB_IN \ 53*6fee2a0bSThomas Hellstrom ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \ 54*6fee2a0bSThomas Hellstrom "rep insb", \ 55b4dd4f6eSThomas Hellstrom "vmcall", X86_FEATURE_VMCALL, \ 56b4dd4f6eSThomas Hellstrom "vmmcall", X86_FEATURE_VMW_VMMCALL) 57b4dd4f6eSThomas Hellstrom #endif 58