// SPDX-License-Identifier: GPL-2.0-only
/*
 * tboot.c: main implementation of helper functions used by kernel for
 *          runtime support of Intel(R) Trusted Execution Technology
 *
 * Copyright (c) 2006-2009, Intel Corporation
 */

#include <linux/init_task.h>
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/dmar.h>
#include <linux/cpu.h>
#include <linux/pfn.h>
#include <linux/mm.h>
#include <linux/tboot.h>
#include <linux/debugfs.h>

#include <asm/realmode.h>
#include <asm/processor.h>
#include <asm/bootparam.h>
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
#include <asm/proto.h>
#include <asm/setup.h>
#include <asm/e820/api.h>
#include <asm/io.h>

#include "../realmode/rm/wakeup.h"

/* Global pointer to shared data; NULL means no measured launch. */
static struct tboot *tboot __read_mostly;

/* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */
#define AP_WAIT_TIMEOUT		1

#undef pr_fmt
#define pr_fmt(fmt)	"tboot: " fmt

static u8 tboot_uuid[16] __initdata = TBOOT_UUID;

bool tboot_enabled(void)
{
	return tboot != NULL;
}

/* noinline to prevent gcc from warning about dereferencing constant fixaddr */
static noinline __init bool check_tboot_version(void)
{
	if (memcmp(&tboot_uuid, &tboot->uuid, sizeof(tboot->uuid))) {
		pr_warn("tboot at 0x%llx is invalid\n", boot_params.tboot_addr);
		return false;
	}

	if (tboot->version < 5) {
		pr_warn("tboot version is invalid: %u\n", tboot->version);
		return false;
	}

	pr_info("found shared page at phys addr 0x%llx:\n",
		boot_params.tboot_addr);
	pr_debug("version: %d\n", tboot->version);
	pr_debug("log_addr: 0x%08x\n", tboot->log_addr);
	pr_debug("shutdown_entry: 0x%x\n", tboot->shutdown_entry);
	pr_debug("tboot_base: 0x%08x\n", tboot->tboot_base);
	pr_debug("tboot_size: 0x%x\n", tboot->tboot_size);

	return true;
}

void __init tboot_probe(void)
{
	/* Look for valid page-aligned address for shared page. */
	if (!boot_params.tboot_addr)
		return;
	/*
	 * also verify that it is mapped as we expect it before calling
	 * set_fixmap(), to reduce chance of garbage value causing crash
	 */
	if (!e820__mapped_any(boot_params.tboot_addr,
			     boot_params.tboot_addr, E820_TYPE_RESERVED)) {
		pr_warn("non-0 tboot_addr but it is not of type E820_TYPE_RESERVED\n");
		return;
	}

	/* Map and check for tboot UUID. */
	set_fixmap(FIX_TBOOT_BASE, boot_params.tboot_addr);
	tboot = (void *)fix_to_virt(FIX_TBOOT_BASE);
	if (!check_tboot_version())
		tboot = NULL;
}

static pgd_t *tboot_pg_dir;
static struct mm_struct tboot_mm = {
	.mm_rb          = RB_ROOT,
	.pgd            = swapper_pg_dir,
	.mm_users       = ATOMIC_INIT(2),
	.mm_count       = ATOMIC_INIT(1),
	.write_protect_seq = SEQCNT_ZERO(tboot_mm.write_protect_seq),
	MMAP_LOCK_INITIALIZER(init_mm)
	.page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
	.mmlist         = LIST_HEAD_INIT(init_mm.mmlist),
};

static inline void switch_to_tboot_pt(void)
{
	write_cr3(virt_to_phys(tboot_pg_dir));
}

static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
			  pgprot_t prot)
{
	pgd_t *pgd;
	p4d_t *p4d;
	pud_t *pud;
	pmd_t *pmd;
	pte_t *pte;

	pgd = pgd_offset(&tboot_mm, vaddr);
	p4d = p4d_alloc(&tboot_mm, pgd, vaddr);
	if (!p4d)
		return -1;
	pud = pud_alloc(&tboot_mm, p4d, vaddr);
	if (!pud)
		return -1;
	pmd = pmd_alloc(&tboot_mm, pud, vaddr);
	if (!pmd)
		return -1;
	pte = pte_alloc_map(&tboot_mm, pmd, vaddr);
	if (!pte)
		return -1;
	set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
	pte_unmap(pte);

	/*
	 * PTI poisons low addresses in the kernel page tables in the
	 * name of making them unusable for userspace.  To execute
	 * code at such a low address, the poison must be cleared.
	 *
	 * Note: 'pgd' actually gets set in p4d_alloc() _or_
	 * pud_alloc() depending on 4/5-level paging.
	 */
	pgd->pgd &= ~_PAGE_NX;

	return 0;
}

static int map_tboot_pages(unsigned long vaddr, unsigned long start_pfn,
			   unsigned long nr)
{
	/* Reuse the original kernel mapping */
	tboot_pg_dir = pgd_alloc(&tboot_mm);
	if (!tboot_pg_dir)
		return -1;

	for (; nr > 0; nr--, vaddr += PAGE_SIZE, start_pfn++) {
		if (map_tboot_page(vaddr, start_pfn, PAGE_KERNEL_EXEC))
			return -1;
	}

	return 0;
}

static void tboot_create_trampoline(void)
{
	u32 map_base, map_size;

	/* Create identity map for tboot shutdown code. */
	map_base = PFN_DOWN(tboot->tboot_base);
	map_size = PFN_UP(tboot->tboot_size);
	if (map_tboot_pages(map_base << PAGE_SHIFT, map_base, map_size))
		panic("tboot: Error mapping tboot pages (mfns) @ 0x%x, 0x%x\n",
		      map_base, map_size);
}

#ifdef CONFIG_ACPI_SLEEP

static void add_mac_region(phys_addr_t start, unsigned long size)
{
	struct tboot_mac_region *mr;
	phys_addr_t end = start + size;

	if (tboot->num_mac_regions >= MAX_TB_MAC_REGIONS)
		panic("tboot: Too many MAC regions\n");

	if (start && size) {
		mr = &tboot->mac_regions[tboot->num_mac_regions++];
		mr->start = round_down(start, PAGE_SIZE);
		mr->size  = round_up(end, PAGE_SIZE) - mr->start;
	}
}

static int tboot_setup_sleep(void)
{
	int i;

	tboot->num_mac_regions = 0;

	for (i = 0; i < e820_table->nr_entries; i++) {
		if ((e820_table->entries[i].type != E820_TYPE_RAM)
		 && (e820_table->entries[i].type != E820_TYPE_RESERVED_KERN))
			continue;

		add_mac_region(e820_table->entries[i].addr, e820_table->entries[i].size);
	}

	tboot->acpi_sinfo.kernel_s3_resume_vector =
		real_mode_header->wakeup_start;

	return 0;
}

#else /* no CONFIG_ACPI_SLEEP */

static int tboot_setup_sleep(void)
{
	/* S3 shutdown requested, but S3 not supported by the kernel... */
	BUG();
	return -1;
}

#endif

void tboot_shutdown(u32 shutdown_type)
{
	void (*shutdown)(void);

	if (!tboot_enabled())
		return;

	/*
	 * if we're being called before the 1:1 mapping is set up then just
	 * return and let the normal shutdown happen; this should only be
	 * due to very early panic()
	 */
	if (!tboot_pg_dir)
		return;

	/* if this is S3 then set regions to MAC */
	if (shutdown_type == TB_SHUTDOWN_S3)
		if (tboot_setup_sleep())
			return;

	tboot->shutdown_type = shutdown_type;

	switch_to_tboot_pt();

	shutdown = (void(*)(void))(unsigned long)tboot->shutdown_entry;
	shutdown();

	/* should not reach here */
	while (1)
		halt();
}

static void tboot_copy_fadt(const struct acpi_table_fadt *fadt)
{
#define TB_COPY_GAS(tbg, g)			\
	tbg.space_id     = g.space_id;		\
	tbg.bit_width    = g.bit_width;		\
	tbg.bit_offset   = g.bit_offset;	\
	tbg.access_width = g.access_width;	\
	tbg.address      = g.address;

	TB_COPY_GAS(tboot->acpi_sinfo.pm1a_cnt_blk, fadt->xpm1a_control_block);
	TB_COPY_GAS(tboot->acpi_sinfo.pm1b_cnt_blk, fadt->xpm1b_control_block);
	TB_COPY_GAS(tboot->acpi_sinfo.pm1a_evt_blk, fadt->xpm1a_event_block);
	TB_COPY_GAS(tboot->acpi_sinfo.pm1b_evt_blk, fadt->xpm1b_event_block);

	/*
	 * We need phys addr of waking vector, but can't use virt_to_phys() on
	 * &acpi_gbl_FACS because it is ioremap'ed, so calc from FACS phys
	 * addr.
	 */
	tboot->acpi_sinfo.wakeup_vector = fadt->facs +
		offsetof(struct acpi_table_facs, firmware_waking_vector);
}

static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
{
	static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = {
		/* S0,1,2: */ -1, -1, -1,
		/* S3: */ TB_SHUTDOWN_S3,
		/* S4: */ TB_SHUTDOWN_S4,
		/* S5: */ TB_SHUTDOWN_S5 };

	if (!tboot_enabled())
		return 0;

	tboot_copy_fadt(&acpi_gbl_FADT);
	tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control;
	tboot->acpi_sinfo.pm1b_cnt_val = pm1b_control;
	/* we always use the 32b wakeup vector */
	tboot->acpi_sinfo.vector_width = 32;

	if (sleep_state >= ACPI_S_STATE_COUNT ||
	    acpi_shutdown_map[sleep_state] == -1) {
		pr_warn("unsupported sleep state 0x%x\n", sleep_state);
		return -1;
	}

	tboot_shutdown(acpi_shutdown_map[sleep_state]);
	return 0;
}

static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b)
{
	if (!tboot_enabled())
		return 0;

	pr_warn("tboot is not able to suspend on platforms with reduced hardware sleep (ACPIv5)");
	return -ENODEV;
}

static atomic_t ap_wfs_count;

static int tboot_wait_for_aps(int num_aps)
{
	unsigned long timeout;

	timeout = AP_WAIT_TIMEOUT*HZ;
	while (atomic_read((atomic_t *)&tboot->num_in_wfs) != num_aps &&
	       timeout) {
		mdelay(1);
		timeout--;
	}

	if (timeout)
		pr_warn("tboot wait for APs timeout\n");

	return !(atomic_read((atomic_t *)&tboot->num_in_wfs) == num_aps);
}

static int tboot_dying_cpu(unsigned int cpu)
{
	atomic_inc(&ap_wfs_count);
	if (num_online_cpus() == 1) {
		if (tboot_wait_for_aps(atomic_read(&ap_wfs_count)))
			return -EBUSY;
	}
	return 0;
}

#ifdef CONFIG_DEBUG_FS

#define TBOOT_LOG_UUID	{ 0x26, 0x25, 0x19, 0xc0, 0x30, 0x6b, 0xb4, 0x4d, \
			  0x4c, 0x84, 0xa3, 0xe9, 0x53, 0xb8, 0x81, 0x74 }

#define TBOOT_SERIAL_LOG_ADDR	0x60000
#define TBOOT_SERIAL_LOG_SIZE	0x08000
#define LOG_MAX_SIZE_OFF	16
#define LOG_BUF_OFF		24

static uint8_t tboot_log_uuid[16] = TBOOT_LOG_UUID;

static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
{
	void __iomem *log_base;
	u8 log_uuid[16];
	u32 max_size;
	void *kbuf;
	int ret = -EFAULT;

	log_base = ioremap(TBOOT_SERIAL_LOG_ADDR, TBOOT_SERIAL_LOG_SIZE);
	if (!log_base)
		return ret;

	memcpy_fromio(log_uuid, log_base, sizeof(log_uuid));
	if (memcmp(&tboot_log_uuid, log_uuid, sizeof(log_uuid)))
		goto err_iounmap;

	max_size = readl(log_base + LOG_MAX_SIZE_OFF);
	if (*ppos >= max_size) {
		ret = 0;
		goto err_iounmap;
	}

	if (*ppos + count > max_size)
		count = max_size - *ppos;

	kbuf = kmalloc(count, GFP_KERNEL);
	if (!kbuf) {
		ret = -ENOMEM;
		goto err_iounmap;
	}

	memcpy_fromio(kbuf, log_base + LOG_BUF_OFF + *ppos, count);
	if (copy_to_user(user_buf, kbuf, count))
		goto err_kfree;

	*ppos += count;

	ret = count;

err_kfree:
	kfree(kbuf);

err_iounmap:
	iounmap(log_base);

	return ret;
}

static const struct file_operations tboot_log_fops = {
	.read	= tboot_log_read,
	.llseek	= default_llseek,
};

#endif /* CONFIG_DEBUG_FS */

static __init int tboot_late_init(void)
{
	if (!tboot_enabled())
		return 0;

	tboot_create_trampoline();

	atomic_set(&ap_wfs_count, 0);
	cpuhp_setup_state(CPUHP_AP_X86_TBOOT_DYING, "x86/tboot:dying", NULL,
			  tboot_dying_cpu);
#ifdef CONFIG_DEBUG_FS
	debugfs_create_file("tboot_log", S_IRUSR,
			arch_debugfs_dir, NULL, &tboot_log_fops);
#endif

	acpi_os_set_prepare_sleep(&tboot_sleep);
	acpi_os_set_prepare_extended_sleep(&tboot_extended_sleep);
	return 0;
}

late_initcall(tboot_late_init);

/*
 * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE)
 */

#define TXT_PUB_CONFIG_REGS_BASE       0xfed30000
#define TXT_PRIV_CONFIG_REGS_BASE      0xfed20000

/* # pages for each config regs space - used by fixmap */
#define NR_TXT_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE -                \
				  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)

/* offsets from pub/priv config space */
#define TXTCR_HEAP_BASE             0x0300
#define TXTCR_HEAP_SIZE             0x0308

#define SHA1_SIZE      20

struct sha1_hash {
	u8 hash[SHA1_SIZE];
};

struct sinit_mle_data {
	u32               version;             /* currently 6 */
	struct sha1_hash  bios_acm_id;
	u32               edx_senter_flags;
	u64               mseg_valid;
	struct sha1_hash  sinit_hash;
	struct sha1_hash  mle_hash;
	struct sha1_hash  stm_hash;
	struct sha1_hash  lcp_policy_hash;
	u32               lcp_policy_control;
	u32               rlp_wakeup_addr;
	u32               reserved;
	u32               num_mdrs;
	u32               mdrs_off;
	u32               num_vtd_dmars;
	u32               vtd_dmars_off;
} __packed;

struct acpi_table_header *tboot_get_dmar_table(struct acpi_table_header *dmar_tbl)
{
	void *heap_base, *heap_ptr, *config;

	if (!tboot_enabled())
		return dmar_tbl;

	/*
	 * ACPI tables may not be DMA protected by tboot, so use DMAR copy
	 * SINIT saved in SinitMleData in TXT heap (which is DMA protected)
	 */

	/* map config space in order to get heap addr */
	config = ioremap(TXT_PUB_CONFIG_REGS_BASE, NR_TXT_CONFIG_PAGES *
			 PAGE_SIZE);
	if (!config)
		return NULL;

	/* now map TXT heap */
	heap_base = ioremap(*(u64 *)(config + TXTCR_HEAP_BASE),
			    *(u64 *)(config + TXTCR_HEAP_SIZE));
	iounmap(config);
	if (!heap_base)
		return NULL;

	/* walk heap to SinitMleData */
	/* skip BiosData */
	heap_ptr = heap_base + *(u64 *)heap_base;
	/* skip OsMleData */
	heap_ptr += *(u64 *)heap_ptr;
	/* skip OsSinitData */
	heap_ptr += *(u64 *)heap_ptr;
	/* now points to SinitMleDataSize; set to SinitMleData */
	heap_ptr += sizeof(u64);
	/* get addr of DMAR table */
	dmar_tbl = (struct acpi_table_header *)(heap_ptr +
		   ((struct sinit_mle_data *)heap_ptr)->vtd_dmars_off -
		   sizeof(u64));

	/* don't unmap heap because dmar.c needs access to this */

	return dmar_tbl;
}
