diff mbox series

[v2,6/6] x86/vmware: Add TDX hypercall support

Message ID 20231201232452.220355-7-amakhalov@vmware.com
State New
Headers show
Series VMware hypercalls enhancements | expand

Commit Message

Alexey Makhalov Dec. 1, 2023, 11:24 p.m. UTC
VMware hypercalls use I/O port, VMCALL or VMMCALL instructions.
Add __tdx_hypercall path to support TDX guests.

No change in high bandwidth hypercalls, as only low bandwidth
ones are supported for TDX guests.

Co-developed-by: Tim Merrifield <timothym@vmware.com>
Signed-off-by: Tim Merrifield <timothym@vmware.com>
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Nadav Amit <namit@vmware.com>
---
 arch/x86/include/asm/vmware.h | 72 +++++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/vmware.c  |  9 +++++
 2 files changed, 81 insertions(+)

Comments

Borislav Petkov Dec. 4, 2023, 10:31 a.m. UTC | #1
On Fri, Dec 01, 2023 at 03:24:52PM -0800, Alexey Makhalov wrote:
> +#ifdef CONFIG_INTEL_TDX_GUEST
> +/* __tdx_hypercall() is not exported. So, export the wrapper */
> +void vmware_tdx_hypercall_args(struct tdx_module_args *args)
> +{
> +	__tdx_hypercall(args);
> +}
> +EXPORT_SYMBOL_GPL(vmware_tdx_hypercall_args);

Uuuh, lovely. I'd like to see what the TDX folks think about this
export first.
kernel test robot Dec. 5, 2023, 7:57 p.m. UTC | #2
Hi Alexey,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on dtor-input/next dtor-input/for-linus linus/master v6.7-rc4 next-20231205]
[cannot apply to tip/x86/vmware]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alexey-Makhalov/x86-vmware-Move-common-macros-to-vmware-h/20231202-072821
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20231201232452.220355-7-amakhalov%40vmware.com
patch subject: [PATCH v2 6/6] x86/vmware: Add TDX hypercall support
config: x86_64-buildonly-randconfig-003-20231203 (https://download.01.org/0day-ci/archive/20231206/202312060350.Paq0JYin-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231206/202312060350.Paq0JYin-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312060350.Paq0JYin-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h:38,
                    from drivers/gpu/drm/vmwgfx/vmwgfx_msg.c:37:
>> arch/x86/include/asm/vmware.h:46:46: warning: 'struct tdx_module_args' declared inside parameter list will not be visible outside of this definition or declaration
      46 | extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
         |                                              ^~~~~~~~~~~~~~~
   arch/x86/include/asm/vmware.h: In function 'vmware_tdx_hypercall':
>> arch/x86/include/asm/vmware.h:61:9: error: variable 'args' has initializer but incomplete type
      61 |  struct tdx_module_args args = {
         |         ^~~~~~~~~~~~~~~
>> arch/x86/include/asm/vmware.h:62:4: error: 'struct tdx_module_args' has no member named 'r10'
      62 |   .r10 = VMWARE_TDX_VENDOR_LEAF,
         |    ^~~
>> arch/x86/include/asm/vmware.h:43:32: warning: excess elements in struct initializer
      43 | #define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL
         |                                ^~~~~~~~~~~~~~
   arch/x86/include/asm/vmware.h:62:10: note: in expansion of macro 'VMWARE_TDX_VENDOR_LEAF'
      62 |   .r10 = VMWARE_TDX_VENDOR_LEAF,
         |          ^~~~~~~~~~~~~~~~~~~~~~
   arch/x86/include/asm/vmware.h:43:32: note: (near initialization for 'args')
      43 | #define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL
         |                                ^~~~~~~~~~~~~~
   arch/x86/include/asm/vmware.h:62:10: note: in expansion of macro 'VMWARE_TDX_VENDOR_LEAF'
      62 |   .r10 = VMWARE_TDX_VENDOR_LEAF,
         |          ^~~~~~~~~~~~~~~~~~~~~~
>> arch/x86/include/asm/vmware.h:63:4: error: 'struct tdx_module_args' has no member named 'r11'
      63 |   .r11 = VMWARE_TDX_HCALL_FUNC,
         |    ^~~
   arch/x86/include/asm/vmware.h:44:32: warning: excess elements in struct initializer
      44 | #define VMWARE_TDX_HCALL_FUNC  1
         |                                ^
   arch/x86/include/asm/vmware.h:63:10: note: in expansion of macro 'VMWARE_TDX_HCALL_FUNC'
      63 |   .r11 = VMWARE_TDX_HCALL_FUNC,
         |          ^~~~~~~~~~~~~~~~~~~~~
   arch/x86/include/asm/vmware.h:44:32: note: (near initialization for 'args')
      44 | #define VMWARE_TDX_HCALL_FUNC  1
         |                                ^
   arch/x86/include/asm/vmware.h:63:10: note: in expansion of macro 'VMWARE_TDX_HCALL_FUNC'
      63 |   .r11 = VMWARE_TDX_HCALL_FUNC,
         |          ^~~~~~~~~~~~~~~~~~~~~
>> arch/x86/include/asm/vmware.h:64:4: error: 'struct tdx_module_args' has no member named 'r12'
      64 |   .r12 = VMWARE_HYPERVISOR_MAGIC,
         |    ^~~
   arch/x86/include/asm/vmware.h:31:34: warning: excess elements in struct initializer
      31 | #define VMWARE_HYPERVISOR_MAGIC  0x564D5868U
         |                                  ^~~~~~~~~~~
   arch/x86/include/asm/vmware.h:64:10: note: in expansion of macro 'VMWARE_HYPERVISOR_MAGIC'
      64 |   .r12 = VMWARE_HYPERVISOR_MAGIC,
         |          ^~~~~~~~~~~~~~~~~~~~~~~
   arch/x86/include/asm/vmware.h:31:34: note: (near initialization for 'args')
      31 | #define VMWARE_HYPERVISOR_MAGIC  0x564D5868U
         |                                  ^~~~~~~~~~~
   arch/x86/include/asm/vmware.h:64:10: note: in expansion of macro 'VMWARE_HYPERVISOR_MAGIC'
      64 |   .r12 = VMWARE_HYPERVISOR_MAGIC,
         |          ^~~~~~~~~~~~~~~~~~~~~~~
>> arch/x86/include/asm/vmware.h:65:4: error: 'struct tdx_module_args' has no member named 'r13'
      65 |   .r13 = cmd,
         |    ^~~
   arch/x86/include/asm/vmware.h:65:10: warning: excess elements in struct initializer
      65 |   .r13 = cmd,
         |          ^~~
   arch/x86/include/asm/vmware.h:65:10: note: (near initialization for 'args')
>> arch/x86/include/asm/vmware.h:66:4: error: 'struct tdx_module_args' has no member named 'rbx'
      66 |   .rbx = in1,
         |    ^~~
   arch/x86/include/asm/vmware.h:66:10: warning: excess elements in struct initializer
      66 |   .rbx = in1,
         |          ^~~
   arch/x86/include/asm/vmware.h:66:10: note: (near initialization for 'args')
>> arch/x86/include/asm/vmware.h:67:4: error: 'struct tdx_module_args' has no member named 'rdx'
      67 |   .rdx = in3,
         |    ^~~
   arch/x86/include/asm/vmware.h:67:10: warning: excess elements in struct initializer
      67 |   .rdx = in3,
         |          ^~~
   arch/x86/include/asm/vmware.h:67:10: note: (near initialization for 'args')
>> arch/x86/include/asm/vmware.h:68:4: error: 'struct tdx_module_args' has no member named 'rsi'
      68 |   .rsi = in4,
         |    ^~~
   arch/x86/include/asm/vmware.h:68:10: warning: excess elements in struct initializer
      68 |   .rsi = in4,
         |          ^~~
   arch/x86/include/asm/vmware.h:68:10: note: (near initialization for 'args')
>> arch/x86/include/asm/vmware.h:69:4: error: 'struct tdx_module_args' has no member named 'rdi'
      69 |   .rdi = in5,
         |    ^~~
   arch/x86/include/asm/vmware.h:69:10: warning: excess elements in struct initializer
      69 |   .rdi = in5,
         |          ^~~
   arch/x86/include/asm/vmware.h:69:10: note: (near initialization for 'args')
>> arch/x86/include/asm/vmware.h:70:4: error: 'struct tdx_module_args' has no member named 'r14'
      70 |   .r14 = in6,
         |    ^~~
   arch/x86/include/asm/vmware.h:70:10: warning: excess elements in struct initializer
      70 |   .r14 = in6,
         |          ^~~
   arch/x86/include/asm/vmware.h:70:10: note: (near initialization for 'args')
>> arch/x86/include/asm/vmware.h:61:25: error: storage size of 'args' isn't known
      61 |  struct tdx_module_args args = {
         |                         ^~~~
>> arch/x86/include/asm/vmware.h:61:25: warning: unused variable 'args' [-Wunused-variable]


vim +/args +61 arch/x86/include/asm/vmware.h

    42	
  > 43	#define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL
    44	#define VMWARE_TDX_HCALL_FUNC  1
    45	
  > 46	extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
    47	
    48	/*
    49	 * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of
    50	 * rbp (arg6) is discouraged by the TDX specification. Therefore, we
    51	 * remap those registers to r12, r13 and r14, respectively.
    52	 */
    53	static inline
    54	unsigned long vmware_tdx_hypercall(unsigned long cmd, unsigned long in1,
    55					   unsigned long in3, unsigned long in4,
    56					   unsigned long in5, unsigned long in6,
    57					   uint32_t *out1, uint32_t *out2,
    58					   uint32_t *out3, uint32_t *out4,
    59					   uint32_t *out5, uint32_t *out6)
    60	{
  > 61		struct tdx_module_args args = {
  > 62			.r10 = VMWARE_TDX_VENDOR_LEAF,
  > 63			.r11 = VMWARE_TDX_HCALL_FUNC,
  > 64			.r12 = VMWARE_HYPERVISOR_MAGIC,
  > 65			.r13 = cmd,
  > 66			.rbx = in1,
  > 67			.rdx = in3,
  > 68			.rsi = in4,
  > 69			.rdi = in5,
  > 70			.r14 = in6,
    71		};
    72	
    73		vmware_tdx_hypercall_args(&args);
    74	
    75		if (out1)
    76			*out1 = args.rbx;
    77		if (out2)
    78			*out2 = args.r13;
    79		if (out3)
    80			*out3 = args.rdx;
    81		if (out4)
    82			*out4 = args.rsi;
    83		if (out5)
    84			*out5 = args.rdi;
    85		if (out6)
    86			*out6 = args.r14;
    87	
    88		return args.r12;
    89	}
    90
kernel test robot Dec. 5, 2023, 9:04 p.m. UTC | #3
Hi Alexey,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on dtor-input/next dtor-input/for-linus linus/master v6.7-rc4 next-20231205]
[cannot apply to tip/x86/vmware]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alexey-Makhalov/x86-vmware-Move-common-macros-to-vmware-h/20231202-072821
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20231201232452.220355-7-amakhalov%40vmware.com
patch subject: [PATCH v2 6/6] x86/vmware: Add TDX hypercall support
config: i386-buildonly-randconfig-005-20231202 (https://download.01.org/0day-ci/archive/20231206/202312060432.8e2xdh6F-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231206/202312060432.8e2xdh6F-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312060432.8e2xdh6F-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/vmwgfx/vmwgfx_msg.c:37:
   In file included from drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h:38:
>> arch/x86/include/asm/vmware.h:46:46: warning: declaration of 'struct tdx_module_args' will not be visible outside of this function [-Wvisibility]
   extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
                                                ^
>> arch/x86/include/asm/vmware.h:61:25: error: variable has incomplete type 'struct tdx_module_args'
           struct tdx_module_args args = {
                                  ^
   arch/x86/include/asm/vmware.h:61:9: note: forward declaration of 'struct tdx_module_args'
           struct tdx_module_args args = {
                  ^
   1 warning and 1 error generated.


vim +61 arch/x86/include/asm/vmware.h

    45	
  > 46	extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
    47	
    48	/*
    49	 * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of
    50	 * rbp (arg6) is discouraged by the TDX specification. Therefore, we
    51	 * remap those registers to r12, r13 and r14, respectively.
    52	 */
    53	static inline
    54	unsigned long vmware_tdx_hypercall(unsigned long cmd, unsigned long in1,
    55					   unsigned long in3, unsigned long in4,
    56					   unsigned long in5, unsigned long in6,
    57					   uint32_t *out1, uint32_t *out2,
    58					   uint32_t *out3, uint32_t *out4,
    59					   uint32_t *out5, uint32_t *out6)
    60	{
  > 61		struct tdx_module_args args = {
    62			.r10 = VMWARE_TDX_VENDOR_LEAF,
    63			.r11 = VMWARE_TDX_HCALL_FUNC,
    64			.r12 = VMWARE_HYPERVISOR_MAGIC,
    65			.r13 = cmd,
    66			.rbx = in1,
    67			.rdx = in3,
    68			.rsi = in4,
    69			.rdi = in5,
    70			.r14 = in6,
    71		};
    72	
    73		vmware_tdx_hypercall_args(&args);
    74	
    75		if (out1)
    76			*out1 = args.rbx;
    77		if (out2)
    78			*out2 = args.r13;
    79		if (out3)
    80			*out3 = args.rdx;
    81		if (out4)
    82			*out4 = args.rsi;
    83		if (out5)
    84			*out5 = args.rdi;
    85		if (out6)
    86			*out6 = args.r14;
    87	
    88		return args.r12;
    89	}
    90
Dave Hansen Dec. 5, 2023, 9:24 p.m. UTC | #4
On 12/4/23 02:31, Borislav Petkov wrote:
> On Fri, Dec 01, 2023 at 03:24:52PM -0800, Alexey Makhalov wrote:
>> +#ifdef CONFIG_INTEL_TDX_GUEST
>> +/* __tdx_hypercall() is not exported. So, export the wrapper */
>> +void vmware_tdx_hypercall_args(struct tdx_module_args *args)
>> +{
>> +	__tdx_hypercall(args);
>> +}
>> +EXPORT_SYMBOL_GPL(vmware_tdx_hypercall_args);
> Uuuh, lovely. I'd like to see what the TDX folks think about this
> export first.

I don't really like it much.  This does a generic thing (make a TDX
hypercall) with a specific name ("vmware_").  If you want to make an
argument that a certain chunk of the __tdx_hypercall() space is just for
VMWare and you also add a VMWare-specific check and then export *that*,
it might be acceptable.

But I don't want random modules able to make random, unrestricted TDX
hypercalls.  That's asking for trouble.
Alexey Makhalov Dec. 5, 2023, 9:41 p.m. UTC | #5
On 12/5/23 1:24 PM, Dave Hansen wrote:
> On 12/4/23 02:31, Borislav Petkov wrote:
>> On Fri, Dec 01, 2023 at 03:24:52PM -0800, Alexey Makhalov wrote:
>>> +#ifdef CONFIG_INTEL_TDX_GUEST
>>> +/* __tdx_hypercall() is not exported. So, export the wrapper */
>>> +void vmware_tdx_hypercall_args(struct tdx_module_args *args)
>>> +{
>>> +	__tdx_hypercall(args);
>>> +}
>>> +EXPORT_SYMBOL_GPL(vmware_tdx_hypercall_args);
>> Uuuh, lovely. I'd like to see what the TDX folks think about this
>> export first.
> 
> I don't really like it much.  This does a generic thing (make a TDX
> hypercall) with a specific name ("vmware_").  If you want to make an
> argument that a certain chunk of the __tdx_hypercall() space is just for
> VMWare and you also add a VMWare-specific check and then export *that*,
> it might be acceptable.
> 
> But I don't want random modules able to make random, unrestricted TDX
> hypercalls.  That's asking for trouble.

Considering exporting of __tdx_hypercall for random modules is not an 
option, what VMware specific checks you are suggesting?
Tim Merrifield Dec. 5, 2023, 10:43 p.m. UTC | #6
Hi Dave and Alexey,

Regarding VMware-specific checks, it may be beneficial to add some
additional checks
such as ensuring that the hypervisor vendor is VMware,
r12==VMWARE_HYPERVISOR_MAGIC,
r10==VMWARE_TDX_VENDOR_LEAF, r11==VMWARE_TDX_HCALL_FUNC and r13 (command) is
restricted to those few commands we expect to be invoked from the
kernel or drivers by VMware-specific
code.

If we add these checks, would folks be OK with exporting this function?


On Tue, Dec 5, 2023 at 3:41 PM Alexey Makhalov
<alexey.makhalov@broadcom.com> wrote:
>
>
>
> On 12/5/23 1:24 PM, Dave Hansen wrote:
> > On 12/4/23 02:31, Borislav Petkov wrote:
> >> On Fri, Dec 01, 2023 at 03:24:52PM -0800, Alexey Makhalov wrote:
> >>> +#ifdef CONFIG_INTEL_TDX_GUEST
> >>> +/* __tdx_hypercall() is not exported. So, export the wrapper */
> >>> +void vmware_tdx_hypercall_args(struct tdx_module_args *args)
> >>> +{
> >>> +   __tdx_hypercall(args);
> >>> +}
> >>> +EXPORT_SYMBOL_GPL(vmware_tdx_hypercall_args);
> >> Uuuh, lovely. I'd like to see what the TDX folks think about this
> >> export first.
> >
> > I don't really like it much.  This does a generic thing (make a TDX
> > hypercall) with a specific name ("vmware_").  If you want to make an
> > argument that a certain chunk of the __tdx_hypercall() space is just for
> > VMWare and you also add a VMWare-specific check and then export *that*,
> > it might be acceptable.
> >
> > But I don't want random modules able to make random, unrestricted TDX
> > hypercalls.  That's asking for trouble.
>
> Considering exporting of __tdx_hypercall for random modules is not an
> option, what VMware specific checks you are suggesting?
>
> --
> This electronic communication and the information and any files transmitted
> with it, or attached to it, are confidential and are intended solely for
> the use of the individual or entity to whom it is addressed and may contain
> information that is confidential, legally privileged, protected by privacy
> laws, or otherwise restricted from disclosure to anyone else. If you are
> not the intended recipient or the person responsible for delivering the
> e-mail to the intended recipient, you are hereby notified that any use,
> copying, distributing, dissemination, forwarding, printing, or copying of
> this e-mail is strictly prohibited. If you received this e-mail in error,
> please return the e-mail to the sender, delete it from your computer, and
> destroy any printed copy of it.
Dave Hansen Dec. 5, 2023, 11:03 p.m. UTC | #7
On 12/5/23 13:41, Alexey Makhalov wrote:
>> I don't really like it much.  This does a generic thing (make a TDX
>> hypercall) with a specific name ("vmware_").  If you want to make an
>> argument that a certain chunk of the __tdx_hypercall() space is just for
>> VMWare and you also add a VMWare-specific check and then export *that*,
>> it might be acceptable.
>>
>> But I don't want random modules able to make random, unrestricted TDX
>> hypercalls.  That's asking for trouble.
> 
> Considering exporting of __tdx_hypercall for random modules is not an
> option, what VMware specific checks you are suggesting?

Make sure it can only be called running on VMWare guests.  A check for
X86_HYPER_VMWARE seems simple enough.

Second, unless the space is *HUGE*, you want to be exporting things like
__vmware_platform() or vmware_legacy_x2apic_available(), *NOT* the
underlying hypercall functions.

We want to make sure that the interfaces are well defined and bounded.
Alexey Makhalov Dec. 6, 2023, 12:11 a.m. UTC | #8
On 12/5/23 3:03 PM, Dave Hansen wrote:
> On 12/5/23 13:41, Alexey Makhalov wrote:
>>> I don't really like it much.  This does a generic thing (make a TDX
>>> hypercall) with a specific name ("vmware_").  If you want to make an
>>> argument that a certain chunk of the __tdx_hypercall() space is just for
>>> VMWare and you also add a VMWare-specific check and then export *that*,
>>> it might be acceptable.
>>>
>>> But I don't want random modules able to make random, unrestricted TDX
>>> hypercalls.  That's asking for trouble.
>>
>> Considering exporting of __tdx_hypercall for random modules is not an
>> option, what VMware specific checks you are suggesting?
> 
> Make sure it can only be called running on VMWare guests.  A check for
> X86_HYPER_VMWARE seems simple enough.
> 
> Second, unless the space is *HUGE*, you want to be exporting things like
> __vmware_platform() or vmware_legacy_x2apic_available(), *NOT* the
> underlying hypercall functions.
> 
> We want to make sure that the interfaces are well defined and bounded.

Thanks Dave and Tim for your suggestions. I followed Dave recommendation 
to have a simple check for X86_HYPER_VMWARE.

Please review patch 6, which I'll send shortly.

Thanks,
--Alexey
diff mbox series

Patch

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 17091eba68cb..cd58ff8ef1af 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,6 +40,54 @@ 
 
 extern u8 vmware_hypercall_mode;
 
+#define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL
+#define VMWARE_TDX_HCALL_FUNC  1
+
+extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
+
+/*
+ * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of
+ * rbp (arg6) is discouraged by the TDX specification. Therefore, we
+ * remap those registers to r12, r13 and r14, respectively.
+ */
+static inline
+unsigned long vmware_tdx_hypercall(unsigned long cmd, unsigned long in1,
+				   unsigned long in3, unsigned long in4,
+				   unsigned long in5, unsigned long in6,
+				   uint32_t *out1, uint32_t *out2,
+				   uint32_t *out3, uint32_t *out4,
+				   uint32_t *out5, uint32_t *out6)
+{
+	struct tdx_module_args args = {
+		.r10 = VMWARE_TDX_VENDOR_LEAF,
+		.r11 = VMWARE_TDX_HCALL_FUNC,
+		.r12 = VMWARE_HYPERVISOR_MAGIC,
+		.r13 = cmd,
+		.rbx = in1,
+		.rdx = in3,
+		.rsi = in4,
+		.rdi = in5,
+		.r14 = in6,
+	};
+
+	vmware_tdx_hypercall_args(&args);
+
+	if (out1)
+		*out1 = args.rbx;
+	if (out2)
+		*out2 = args.r13;
+	if (out3)
+		*out3 = args.rdx;
+	if (out4)
+		*out4 = args.rsi;
+	if (out5)
+		*out5 = args.rdi;
+	if (out6)
+		*out6 = args.r14;
+
+	return args.r12;
+}
+
 /*
  * 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.
@@ -67,6 +115,10 @@  unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
 {
 	unsigned long out0;
 
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, NULL, NULL,
+					    NULL, NULL, NULL, NULL);
+
 	asm_inline volatile (VMWARE_HYPERCALL
 		: "=a" (out0)
 		: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -85,6 +137,10 @@  unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
 {
 	unsigned long out0;
 
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2,
+					    NULL, NULL, NULL, NULL);
+
 	asm_inline volatile (VMWARE_HYPERCALL
 		: "=a" (out0), "=b" (*out1), "=c" (*out2)
 		: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -104,6 +160,10 @@  unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
 {
 	unsigned long out0;
 
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2,
+					    out3, NULL, NULL, NULL);
+
 	asm_inline volatile (VMWARE_HYPERCALL
 		: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
 		: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -123,6 +183,10 @@  unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
 {
 	unsigned long out0;
 
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, 0, NULL,
+					    out2, NULL, NULL, NULL, NULL);
+
 	asm_inline volatile (VMWARE_HYPERCALL
 		: "=a" (out0), "=c" (*out2)
 		: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -145,6 +209,10 @@  unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
 {
 	unsigned long out0;
 
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, in3, 0, 0, 0, NULL, out2,
+					    out3, out4, out5, NULL);
+
 	asm_inline volatile (VMWARE_HYPERCALL
 		: "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
 		  "=D" (*out5)
@@ -166,6 +234,10 @@  unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
 {
 	unsigned long out0;
 
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, 0, out1,
+					    out2, out3, NULL, NULL, NULL);
+
 	asm_inline volatile (VMWARE_HYPERCALL
 		: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
 		: [port] "i" (VMWARE_HYPERVISOR_PORT),
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 3aa1adaed18f..0207e8ced92c 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -428,6 +428,15 @@  static bool __init vmware_legacy_x2apic_available(void)
 		(eax & BIT(VCPU_LEGACY_X2APIC));
 }
 
+#ifdef CONFIG_INTEL_TDX_GUEST
+/* __tdx_hypercall() is not exported. So, export the wrapper */
+void vmware_tdx_hypercall_args(struct tdx_module_args *args)
+{
+	__tdx_hypercall(args);
+}
+EXPORT_SYMBOL_GPL(vmware_tdx_hypercall_args);
+#endif
+
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb,
 					struct pt_regs *regs)