Merge tag 'x86_tdx_for_6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-block.git] / arch / x86 / coco / tdx / tdcall.S
index ad0d51f03cb408eb407deef9db665cda0662550a..6a255e6809bc525690538c17eb284c1f72e3f700 100644 (file)
 /*
  * Bitmasks of exposed registers (with VMM).
  */
+#define TDX_RDX                BIT(2)
+#define TDX_RBX                BIT(3)
+#define TDX_RSI                BIT(6)
+#define TDX_RDI                BIT(7)
+#define TDX_R8         BIT(8)
+#define TDX_R9         BIT(9)
 #define TDX_R10                BIT(10)
 #define TDX_R11                BIT(11)
 #define TDX_R12                BIT(12)
@@ -27,9 +33,9 @@
  * details can be found in TDX GHCI specification, section
  * titled "TDCALL [TDG.VP.VMCALL] leaf".
  */
-#define TDVMCALL_EXPOSE_REGS_MASK      ( TDX_R10 | TDX_R11 | \
-                                         TDX_R12 | TDX_R13 | \
-                                         TDX_R14 | TDX_R15 )
+#define TDVMCALL_EXPOSE_REGS_MASK      \
+       ( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8  | TDX_R9  | \
+         TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 )
 
 .section .noinstr.text, "ax"
 
@@ -126,25 +132,38 @@ SYM_FUNC_START(__tdx_hypercall)
        push %r14
        push %r13
        push %r12
+       push %rbx
+
+       /* Free RDI and RSI to be used as TDVMCALL arguments */
+       movq %rdi, %rax
+       push %rsi
+
+       /* Copy hypercall registers from arg struct: */
+       movq TDX_HYPERCALL_r8(%rax),  %r8
+       movq TDX_HYPERCALL_r9(%rax),  %r9
+       movq TDX_HYPERCALL_r10(%rax), %r10
+       movq TDX_HYPERCALL_r11(%rax), %r11
+       movq TDX_HYPERCALL_r12(%rax), %r12
+       movq TDX_HYPERCALL_r13(%rax), %r13
+       movq TDX_HYPERCALL_r14(%rax), %r14
+       movq TDX_HYPERCALL_r15(%rax), %r15
+       movq TDX_HYPERCALL_rdi(%rax), %rdi
+       movq TDX_HYPERCALL_rsi(%rax), %rsi
+       movq TDX_HYPERCALL_rbx(%rax), %rbx
+       movq TDX_HYPERCALL_rdx(%rax), %rdx
+
+       push %rax
 
        /* Mangle function call ABI into TDCALL ABI: */
        /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */
        xor %eax, %eax
 
-       /* Copy hypercall registers from arg struct: */
-       movq TDX_HYPERCALL_r10(%rdi), %r10
-       movq TDX_HYPERCALL_r11(%rdi), %r11
-       movq TDX_HYPERCALL_r12(%rdi), %r12
-       movq TDX_HYPERCALL_r13(%rdi), %r13
-       movq TDX_HYPERCALL_r14(%rdi), %r14
-       movq TDX_HYPERCALL_r15(%rdi), %r15
-
        movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx
 
        tdcall
 
        /*
-        * RAX==0 indicates a failure of the TDVMCALL mechanism itself and that
+        * RAX!=0 indicates a failure of the TDVMCALL mechanism itself and that
         * something has gone horribly wrong with the TDX module.
         *
         * The return status of the hypercall operation is in a separate
@@ -154,30 +173,46 @@ SYM_FUNC_START(__tdx_hypercall)
        testq %rax, %rax
        jne .Lpanic
 
-       /* TDVMCALL leaf return code is in R10 */
-       movq %r10, %rax
+       pop %rax
 
        /* Copy hypercall result registers to arg struct if needed */
-       testq $TDX_HCALL_HAS_OUTPUT, %rsi
+       testq $TDX_HCALL_HAS_OUTPUT, (%rsp)
        jz .Lout
 
-       movq %r10, TDX_HYPERCALL_r10(%rdi)
-       movq %r11, TDX_HYPERCALL_r11(%rdi)
-       movq %r12, TDX_HYPERCALL_r12(%rdi)
-       movq %r13, TDX_HYPERCALL_r13(%rdi)
-       movq %r14, TDX_HYPERCALL_r14(%rdi)
-       movq %r15, TDX_HYPERCALL_r15(%rdi)
+       movq %r8,  TDX_HYPERCALL_r8(%rax)
+       movq %r9,  TDX_HYPERCALL_r9(%rax)
+       movq %r10, TDX_HYPERCALL_r10(%rax)
+       movq %r11, TDX_HYPERCALL_r11(%rax)
+       movq %r12, TDX_HYPERCALL_r12(%rax)
+       movq %r13, TDX_HYPERCALL_r13(%rax)
+       movq %r14, TDX_HYPERCALL_r14(%rax)
+       movq %r15, TDX_HYPERCALL_r15(%rax)
+       movq %rdi, TDX_HYPERCALL_rdi(%rax)
+       movq %rsi, TDX_HYPERCALL_rsi(%rax)
+       movq %rbx, TDX_HYPERCALL_rbx(%rax)
+       movq %rdx, TDX_HYPERCALL_rdx(%rax)
 .Lout:
+       /* TDVMCALL leaf return code is in R10 */
+       movq %r10, %rax
+
        /*
         * Zero out registers exposed to the VMM to avoid speculative execution
         * with VMM-controlled values. This needs to include all registers
-        * present in TDVMCALL_EXPOSE_REGS_MASK (except R12-R15). R12-R15
-        * context will be restored.
+        * present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which
+        * will be restored.
         */
+       xor %r8d,  %r8d
+       xor %r9d,  %r9d
        xor %r10d, %r10d
        xor %r11d, %r11d
+       xor %rdi,  %rdi
+       xor %rdx,  %rdx
+
+       /* Remove TDX_HCALL_* flags from the stack */
+       pop %rsi
 
        /* Restore callee-saved GPRs as mandated by the x86_64 ABI */
+       pop %rbx
        pop %r12
        pop %r13
        pop %r14