linux/arch/x86/coco/tdx/tdx.c

// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2021-2022 Intel Corporation */

#undef pr_fmt
#define pr_fmt(fmt)

#include <linux/cpufeature.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/kexec.h>
#include <asm/coco.h>
#include <asm/tdx.h>
#include <asm/vmx.h>
#include <asm/ia32.h>
#include <asm/insn.h>
#include <asm/insn-eval.h>
#include <asm/pgtable.h>
#include <asm/set_memory.h>

/* MMIO direction */
#define EPT_READ
#define EPT_WRITE

/* Port I/O direction */
#define PORT_READ
#define PORT_WRITE

/* See Exit Qualification for I/O Instructions in VMX documentation */
#define VE_IS_IO_IN(e)
#define VE_GET_IO_SIZE(e)
#define VE_GET_PORT_NUM(e)
#define VE_IS_IO_STRING(e)

#define ATTR_DEBUG
#define ATTR_SEPT_VE_DISABLE

/* TDX Module call error codes */
#define TDCALL_RETURN_CODE(a)
#define TDCALL_INVALID_OPERAND

#define TDREPORT_SUBTYPE_0

static atomic_long_t nr_shared;

/* Called from __tdx_hypercall() for unrecoverable failure */
noinstr void __noreturn __tdx_hypercall_failed(void)
{}

#ifdef CONFIG_KVM_GUEST
long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,
		       unsigned long p3, unsigned long p4)
{}
EXPORT_SYMBOL_GPL();
#endif

/*
 * Used for TDX guests to make calls directly to the TD module.  This
 * should only be used for calls that have no legitimate reason to fail
 * or where the kernel can not survive the call failing.
 */
static inline void tdcall(u64 fn, struct tdx_module_args *args)
{}

/**
 * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT
 *                           subtype 0) using TDG.MR.REPORT TDCALL.
 * @reportdata: Address of the input buffer which contains user-defined
 *              REPORTDATA to be included into TDREPORT.
 * @tdreport: Address of the output buffer to store TDREPORT.
 *
 * Refer to section titled "TDG.MR.REPORT leaf" in the TDX Module
 * v1.0 specification for more information on TDG.MR.REPORT TDCALL.
 * It is used in the TDX guest driver module to get the TDREPORT0.
 *
 * Return 0 on success, -EINVAL for invalid operands, or -EIO on
 * other TDCALL failures.
 */
int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport)
{}
EXPORT_SYMBOL_GPL();

/**
 * tdx_hcall_get_quote() - Wrapper to request TD Quote using GetQuote
 *                         hypercall.
 * @buf: Address of the directly mapped shared kernel buffer which
 *       contains TDREPORT. The same buffer will be used by VMM to
 *       store the generated TD Quote output.
 * @size: size of the tdquote buffer (4KB-aligned).
 *
 * Refer to section titled "TDG.VP.VMCALL<GetQuote>" in the TDX GHCI
 * v1.0 specification for more information on GetQuote hypercall.
 * It is used in the TDX guest driver module to get the TD Quote.
 *
 * Return 0 on success or error code on failure.
 */
u64 tdx_hcall_get_quote(u8 *buf, size_t size)
{}
EXPORT_SYMBOL_GPL();

static void __noreturn tdx_panic(const char *msg)
{}

static void tdx_parse_tdinfo(u64 *cc_mask)
{}

/*
 * The TDX module spec states that #VE may be injected for a limited set of
 * reasons:
 *
 *  - Emulation of the architectural #VE injection on EPT violation;
 *
 *  - As a result of guest TD execution of a disallowed instruction,
 *    a disallowed MSR access, or CPUID virtualization;
 *
 *  - A notification to the guest TD about anomalous behavior;
 *
 * The last one is opt-in and is not used by the kernel.
 *
 * The Intel Software Developer's Manual describes cases when instruction
 * length field can be used in section "Information for VM Exits Due to
 * Instruction Execution".
 *
 * For TDX, it ultimately means GET_VEINFO provides reliable instruction length
 * information if #VE occurred due to instruction execution, but not for EPT
 * violations.
 */
static int ve_instr_len(struct ve_info *ve)
{}

static u64 __cpuidle __halt(const bool irq_disabled)
{}

static int handle_halt(struct ve_info *ve)
{}

void __cpuidle tdx_safe_halt(void)
{}

static int read_msr(struct pt_regs *regs, struct ve_info *ve)
{}

static int write_msr(struct pt_regs *regs, struct ve_info *ve)
{}

static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
{}

static bool mmio_read(int size, unsigned long addr, unsigned long *val)
{}

static bool mmio_write(int size, unsigned long addr, unsigned long val)
{}

static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
{}

static bool handle_in(struct pt_regs *regs, int size, int port)
{}

static bool handle_out(struct pt_regs *regs, int size, int port)
{}

/*
 * Emulate I/O using hypercall.
 *
 * Assumes the IO instruction was using ax, which is enforced
 * by the standard io.h macros.
 *
 * Return True on success or False on failure.
 */
static int handle_io(struct pt_regs *regs, struct ve_info *ve)
{}

/*
 * Early #VE exception handler. Only handles a subset of port I/O.
 * Intended only for earlyprintk. If failed, return false.
 */
__init bool tdx_early_handle_ve(struct pt_regs *regs)
{}

void tdx_get_ve_info(struct ve_info *ve)
{}

/*
 * Handle the user initiated #VE.
 *
 * On success, returns the number of bytes RIP should be incremented (>=0)
 * or -errno on error.
 */
static int virt_exception_user(struct pt_regs *regs, struct ve_info *ve)
{}

static inline bool is_private_gpa(u64 gpa)
{}

/*
 * Handle the kernel #VE.
 *
 * On success, returns the number of bytes RIP should be incremented (>=0)
 * or -errno on error.
 */
static int virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve)
{}

bool tdx_handle_virt_exception(struct pt_regs *regs, struct ve_info *ve)
{}

static bool tdx_tlb_flush_required(bool private)
{}

static bool tdx_cache_flush_required(void)
{}

/*
 * Notify the VMM about page mapping conversion. More info about ABI
 * can be found in TDX Guest-Host-Communication Interface (GHCI),
 * section "TDG.VP.VMCALL<MapGPA>".
 */
static bool tdx_map_gpa(phys_addr_t start, phys_addr_t end, bool enc)
{}

/*
 * Inform the VMM of the guest's intent for this physical page: shared with
 * the VMM or private to the guest.  The VMM is expected to change its mapping
 * of the page in response.
 */
static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
{}

static int tdx_enc_status_change_prepare(unsigned long vaddr, int numpages,
					 bool enc)
{}

static int tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
					 bool enc)
{}

/* Stop new private<->shared conversions */
static void tdx_kexec_begin(void)
{}

/* Walk direct mapping and convert all shared memory back to private */
static void tdx_kexec_finish(void)
{}

void __init tdx_early_init(void)
{}