mirror of
https://github.com/acidanthera/audk.git
synced 2025-08-20 17:18:11 +02:00
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4572 According to section 3.2 of the [GHCI] spec, if the return status of MapGPA is "TDG.VP.VMCALL_RETRY", TD must retry this operation for the pages in the region starting at the GPA specified in R11. Currently, TDVF has not handled the retry results and always clears the R11 on unsuccessful return status. For this, the TdVmcall needs to output the value of R11 on unsuccessful return status to handle the retry results of MapGPA. Reference: [GHCI]: TDX Guest-Host-Communication Interface v1.0 https://cdrdv2.intel.com/v1/dl/getContent/726790 Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Michael Roth <michael.roth@amd.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> Signed-off-by: Ceping Sun <cepingx.sun@intel.com>
144 lines
3.0 KiB
NASM
144 lines
3.0 KiB
NASM
;------------------------------------------------------------------------------
|
|
;*
|
|
;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
|
|
;* SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
;*
|
|
;*
|
|
;------------------------------------------------------------------------------
|
|
|
|
DEFAULT REL
|
|
SECTION .text
|
|
|
|
%define TDVMCALL_EXPOSE_REGS_MASK 0xffec
|
|
%define TDVMCALL 0x0
|
|
|
|
%macro tdcall 0
|
|
db 0x66,0x0f,0x01,0xcc
|
|
%endmacro
|
|
|
|
%macro tdcall_push_regs 0
|
|
push rbp
|
|
mov rbp, rsp
|
|
push r15
|
|
push r14
|
|
push r13
|
|
push r12
|
|
push rbx
|
|
push rsi
|
|
push rdi
|
|
%endmacro
|
|
|
|
%macro tdcall_pop_regs 0
|
|
pop rdi
|
|
pop rsi
|
|
pop rbx
|
|
pop r12
|
|
pop r13
|
|
pop r14
|
|
pop r15
|
|
pop rbp
|
|
%endmacro
|
|
|
|
%define number_of_regs_pushed 8
|
|
%define number_of_parameters 4
|
|
|
|
;
|
|
; Keep these in sync for push_regs/pop_regs, code below
|
|
; uses them to find 5th or greater parameters
|
|
;
|
|
%define first_variable_on_stack_offset \
|
|
((number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8)
|
|
%define second_variable_on_stack_offset \
|
|
((first_variable_on_stack_offset) + 8)
|
|
|
|
%macro tdcall_regs_preamble 2
|
|
mov rax, %1
|
|
|
|
xor rcx, rcx
|
|
mov ecx, %2
|
|
|
|
; R10 = 0 (standard TDVMCALL)
|
|
|
|
xor r10d, r10d
|
|
|
|
; Zero out unused (for standard TDVMCALL) registers to avoid leaking
|
|
; secrets to the VMM.
|
|
|
|
xor ebx, ebx
|
|
xor esi, esi
|
|
xor edi, edi
|
|
|
|
xor edx, edx
|
|
xor ebp, ebp
|
|
xor r8d, r8d
|
|
xor r9d, r9d
|
|
%endmacro
|
|
|
|
%macro tdcall_regs_postamble 0
|
|
xor ebx, ebx
|
|
xor esi, esi
|
|
xor edi, edi
|
|
|
|
xor ecx, ecx
|
|
xor edx, edx
|
|
xor r8d, r8d
|
|
xor r9d, r9d
|
|
xor r10d, r10d
|
|
xor r11d, r11d
|
|
%endmacro
|
|
|
|
;------------------------------------------------------------------------------
|
|
; 0 => RAX = TDCALL leaf
|
|
; M => RCX = TDVMCALL register behavior
|
|
; 1 => R10 = standard vs. vendor
|
|
; RDI => R11 = TDVMCALL function / nr
|
|
; RSI = R12 = p1
|
|
; RDX => R13 = p2
|
|
; RCX => R14 = p3
|
|
; R8 => R15 = p4
|
|
|
|
; UINT64
|
|
; EFIAPI
|
|
; TdVmCall (
|
|
; UINT64 Leaf, // Rcx
|
|
; UINT64 P1, // Rdx
|
|
; UINT64 P2, // R8
|
|
; UINT64 P3, // R9
|
|
; UINT64 P4, // rsp + 0x28
|
|
; UINT64 *Val // rsp + 0x30
|
|
; )
|
|
global ASM_PFX(TdVmCall)
|
|
ASM_PFX(TdVmCall):
|
|
tdcall_push_regs
|
|
|
|
mov r11, rcx
|
|
mov r12, rdx
|
|
mov r13, r8
|
|
mov r14, r9
|
|
mov r15, [rsp + first_variable_on_stack_offset ]
|
|
|
|
tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
|
|
|
|
tdcall
|
|
|
|
; ignore return dataif TDCALL reports failure.
|
|
test rax, rax
|
|
jnz .no_return_data
|
|
|
|
; Propagate TDVMCALL success/failure to return value.
|
|
mov rax, r10
|
|
|
|
; Retrieve the Val pointer.
|
|
mov r9, [rsp + second_variable_on_stack_offset ]
|
|
test r9, r9
|
|
jz .no_return_data
|
|
|
|
; Propagate TDVMCALL output value to output param
|
|
mov [r9], r11
|
|
.no_return_data:
|
|
tdcall_regs_postamble
|
|
|
|
tdcall_pop_regs
|
|
|
|
ret
|