tdxcall.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include <asm/asm-offsets.h>
  3. #include <asm/tdx.h>
  4. /*
  5. * TDCALL and SEAMCALL are supported in Binutils >= 2.36.
  6. */
  7. #define tdcall .byte 0x66,0x0f,0x01,0xcc
  8. #define seamcall .byte 0x66,0x0f,0x01,0xcf
  9. /*
  10. * TDX_MODULE_CALL - common helper macro for both
  11. * TDCALL and SEAMCALL instructions.
  12. *
  13. * TDCALL - used by TDX guests to make requests to the
  14. * TDX module and hypercalls to the VMM.
  15. * SEAMCALL - used by TDX hosts to make requests to the
  16. * TDX module.
  17. */
  18. .macro TDX_MODULE_CALL host:req
  19. /*
  20. * R12 will be used as temporary storage for struct tdx_module_output
  21. * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL
  22. * services supported by this function, it can be reused.
  23. */
  24. /* Callee saved, so preserve it */
  25. push %r12
  26. /*
  27. * Push output pointer to stack.
  28. * After the operation, it will be fetched into R12 register.
  29. */
  30. push %r9
  31. /* Mangle function call ABI into TDCALL/SEAMCALL ABI: */
  32. /* Move Leaf ID to RAX */
  33. mov %rdi, %rax
  34. /* Move input 4 to R9 */
  35. mov %r8, %r9
  36. /* Move input 3 to R8 */
  37. mov %rcx, %r8
  38. /* Move input 1 to RCX */
  39. mov %rsi, %rcx
  40. /* Leave input param 2 in RDX */
  41. .if \host
  42. seamcall
  43. /*
  44. * SEAMCALL instruction is essentially a VMExit from VMX root
  45. * mode to SEAM VMX root mode. VMfailInvalid (CF=1) indicates
  46. * that the targeted SEAM firmware is not loaded or disabled,
  47. * or P-SEAMLDR is busy with another SEAMCALL. %rax is not
  48. * changed in this case.
  49. *
  50. * Set %rax to TDX_SEAMCALL_VMFAILINVALID for VMfailInvalid.
  51. * This value will never be used as actual SEAMCALL error code as
  52. * it is from the Reserved status code class.
  53. */
  54. jnc .Lno_vmfailinvalid
  55. mov $TDX_SEAMCALL_VMFAILINVALID, %rax
  56. .Lno_vmfailinvalid:
  57. .else
  58. tdcall
  59. .endif
  60. /*
  61. * Fetch output pointer from stack to R12 (It is used
  62. * as temporary storage)
  63. */
  64. pop %r12
  65. /*
  66. * Since this macro can be invoked with NULL as an output pointer,
  67. * check if caller provided an output struct before storing output
  68. * registers.
  69. *
  70. * Update output registers, even if the call failed (RAX != 0).
  71. * Other registers may contain details of the failure.
  72. */
  73. test %r12, %r12
  74. jz .Lno_output_struct
  75. /* Copy result registers to output struct: */
  76. movq %rcx, TDX_MODULE_rcx(%r12)
  77. movq %rdx, TDX_MODULE_rdx(%r12)
  78. movq %r8, TDX_MODULE_r8(%r12)
  79. movq %r9, TDX_MODULE_r9(%r12)
  80. movq %r10, TDX_MODULE_r10(%r12)
  81. movq %r11, TDX_MODULE_r11(%r12)
  82. .Lno_output_struct:
  83. /* Restore the state of R12 register */
  84. pop %r12
  85. .endm