• Kuppuswamy Sathyanarayanan's avatar
    x86/tdx: Add __tdx_module_call() and __tdx_hypercall() helper functions · eb94f1b6
    Kuppuswamy Sathyanarayanan authored
    Guests communicate with VMMs with hypercalls. Historically, these
    are implemented using instructions that are known to cause VMEXITs
    like VMCALL, VMLAUNCH, etc. However, with TDX, VMEXITs no longer
    expose the guest state to the host. This prevents the old hypercall
    mechanisms from working. So, to communicate with VMM, TDX
    specification defines a new instruction called TDCALL.
    
    In a TDX based VM, since the VMM is an untrusted entity, an intermediary
    layer -- TDX module -- facilitates secure communication between the host
    and the guest. TDX module is loaded like a firmware into a special CPU
    mode called SEAM. TDX guests communicate with the TDX module using the
    TDCALL instruction.
    
    A guest uses TDCALL to communicate with both the TDX module and VMM.
    The value of the RAX register when executing the TDCALL instruction is
    used to determine the TDCALL type. A leaf of TDCALL used to communicate
    with the VMM is called TDVMCALL.
    
    Add generic interfaces to communicate with the TDX module and VMM
    (using the TDCALL instruction).
    
    __tdx_module_call()  - Used to communicate with the TDX module (via
    		       TDCALL instruction).
    __tdx_hypercall()    - Used by the guest to request services from
    		       the VMM (via TDVMCALL leaf of TDCALL).
    
    Also define an additional wrapper _tdx_hypercall(), which adds error
    handling support for the TDCALL failure.
    
    The __tdx_module_call() and __tdx_hypercall() helper functions are
    implemented in assembly in a .S file.  The TDCALL ABI requires
    shuffling arguments in and out of registers, which proved to be
    awkward with inline assembly.
    
    Just like syscalls, not all TDVMCALL use cases need to use the same
    number of argument registers. The implementation here picks the current
    worst-case scenario for TDCALL (4 registers). For TDCALLs with fewer
    than 4 arguments, there will end up being a few superfluous (cheap)
    instructions. But, this approach maximizes code reuse.
    
    For registers used by the TDCALL instruction, please check TDX GHCI
    specification, the section titled "TDCALL instruction" and "TDG.VP.VMCALL
    Interface".
    
    Based on previous patch by Sean Christopherson.
    Signed-off-by: default avatarKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
    Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
    Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
    Reviewed-by: default avatarTony Luck <tony.luck@intel.com>
    Reviewed-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
    Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
    Link: https://lkml.kernel.org/r/20220405232939.73860-4-kirill.shutemov@linux.intel.com
    eb94f1b6
Makefile 60 Bytes