// SPDX-License-Identifier: GPL-2.0-only
/*
 * Support for the hypercall interface exposed to protected guests by
 * pKVM.
 *
 * Author: Will Deacon <will@kernel.org>
 * Copyright (C) 2024 Google LLC
 */

#include <linux/arm-smccc.h>
#include <linux/array_size.h>
#include <linux/io.h>
#include <linux/mem_encrypt.h>
#include <linux/mm.h>
#include <linux/pgtable.h>

#include <asm/hypervisor.h>

static size_t pkvm_granule;

static int arm_smccc_do_one_page(u32 func_id, phys_addr_t phys)
{
	phys_addr_t end = phys + PAGE_SIZE;

	while (phys < end) {
		struct arm_smccc_res res;

		arm_smccc_1_1_invoke(func_id, phys, 0, 0, &res);
		if (res.a0 != SMCCC_RET_SUCCESS)
			return -EPERM;

		phys += pkvm_granule;
	}

	return 0;
}

static int __set_memory_range(u32 func_id, unsigned long start, int numpages)
{
	void *addr = (void *)start, *end = addr + numpages * PAGE_SIZE;

	while (addr < end) {
		int err;

		err = arm_smccc_do_one_page(func_id, virt_to_phys(addr));
		if (err)
			return err;

		addr += PAGE_SIZE;
	}

	return 0;
}

static int pkvm_set_memory_encrypted(unsigned long addr, int numpages)
{
	return __set_memory_range(ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID,
				  addr, numpages);
}

static int pkvm_set_memory_decrypted(unsigned long addr, int numpages)
{
	return __set_memory_range(ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID,
				  addr, numpages);
}

static const struct arm64_mem_crypt_ops pkvm_crypt_ops = {
	.encrypt	= pkvm_set_memory_encrypted,
	.decrypt	= pkvm_set_memory_decrypted,
};

static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
				   pgprot_t *prot)
{
	phys_addr_t end;
	pteval_t protval = pgprot_val(*prot);

	/*
	 * We only expect MMIO emulation for regions mapped with device
	 * attributes.
	 */
	if (protval != PROT_DEVICE_nGnRE && protval != PROT_DEVICE_nGnRnE)
		return 0;

	phys = PAGE_ALIGN_DOWN(phys);
	end = phys + PAGE_ALIGN(size);

	while (phys < end) {
		const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID;
		int err;

		err = arm_smccc_do_one_page(func_id, phys);
		if (err)
			return err;

		phys += PAGE_SIZE;
	}

	return 0;
}

void pkvm_init_hyp_services(void)
{
	int i;
	struct arm_smccc_res res;
	const u32 funcs[] = {
		ARM_SMCCC_KVM_FUNC_HYP_MEMINFO,
		ARM_SMCCC_KVM_FUNC_MEM_SHARE,
		ARM_SMCCC_KVM_FUNC_MEM_UNSHARE,
	};

	for (i = 0; i < ARRAY_SIZE(funcs); ++i) {
		if (!kvm_arm_hyp_service_available(funcs[i]))
			return;
	}

	arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID,
			     0, 0, 0, &res);
	if (res.a0 > PAGE_SIZE) /* Includes error codes */
		return;

	pkvm_granule = res.a0;
	arm64_mem_crypt_ops_register(&pkvm_crypt_ops);

	if (kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_MMIO_GUARD))
		arm64_ioremap_prot_hook_register(&mmio_guard_ioremap_hook);
}
