// SPDX-License-Identifier: GPL-2.0-only
/*
 * Re-map IO memory to kernel address space so that we can access it.
 * This is needed for high PCI addresses that aren't mapped in the
 * 640k-1MB IO memory area on PC's
 *
 * (C) Copyright 1995 1996 Linus Torvalds
 */

#include <linux/memblock.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mmiotrace.h>
#include <linux/cc_platform.h>
#include <linux/efi.h>
#include <linux/pgtable.h>
#include <linux/kmsan.h>

#include <asm/set_memory.h>
#include <asm/e820/api.h>
#include <asm/efi.h>
#include <asm/fixmap.h>
#include <asm/tlbflush.h>
#include <asm/pgalloc.h>
#include <asm/memtype.h>
#include <asm/setup.h>

#include "physaddr.h"

/*
 * Descriptor controlling ioremap() behavior.
 */
struct ioremap_desc {
	unsigned int flags;
};

/*
 * Fix up the linear direct mapping of the kernel to avoid cache attribute
 * conflicts.
 */
int ioremap_change_attr(unsigned long vaddr, unsigned long size,
			enum page_cache_mode pcm)
{
	unsigned long nrpages = size >> PAGE_SHIFT;
	int err;

	switch (pcm) {
	case _PAGE_CACHE_MODE_UC:
	default:
		err = _set_memory_uc(vaddr, nrpages);
		break;
	case _PAGE_CACHE_MODE_WC:
		err = _set_memory_wc(vaddr, nrpages);
		break;
	case _PAGE_CACHE_MODE_WT:
		err = _set_memory_wt(vaddr, nrpages);
		break;
	case _PAGE_CACHE_MODE_WB:
		err = _set_memory_wb(vaddr, nrpages);
		break;
	}

	return err;
}

/* Does the range (or a subset of) contain normal RAM? */
static unsigned int __ioremap_check_ram(struct resource *res)
{
	unsigned long start_pfn, stop_pfn;
	unsigned long i;

	if ((res->flags & IORESOURCE_SYSTEM_RAM) != IORESOURCE_SYSTEM_RAM)
		return 0;

	start_pfn = (res->start + PAGE_SIZE - 1) >> PAGE_SHIFT;
	stop_pfn = (res->end + 1) >> PAGE_SHIFT;
	if (stop_pfn > start_pfn) {
		for (i = 0; i < (stop_pfn - start_pfn); ++i)
			if (pfn_valid(start_pfn + i) &&
			    !PageReserved(pfn_to_page(start_pfn + i)))
				return IORES_MAP_SYSTEM_RAM;
	}

	return 0;
}

/*
 * In a SEV guest, NONE and RESERVED should not be mapped encrypted because
 * there the whole memory is already encrypted.
 */
static unsigned int __ioremap_check_encrypted(struct resource *res)
{
	if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
		return 0;

	switch (res->desc) {
	case IORES_DESC_NONE:
	case IORES_DESC_RESERVED:
		break;
	default:
		return IORES_MAP_ENCRYPTED;
	}

	return 0;
}

/*
 * The EFI runtime services data area is not covered by walk_mem_res(), but must
 * be mapped encrypted when SEV is active.
 */
static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *desc)
{
	if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
		return;

	if (!IS_ENABLED(CONFIG_EFI))
		return;

	if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA ||
	    (efi_mem_type(addr) == EFI_BOOT_SERVICES_DATA &&
	     efi_mem_attributes(addr) & EFI_MEMORY_RUNTIME))
		desc->flags |= IORES_MAP_ENCRYPTED;
}

static int __ioremap_collect_map_flags(struct resource *res, void *arg)
{
	struct ioremap_desc *desc = arg;

	if (!(desc->flags & IORES_MAP_SYSTEM_RAM))
		desc->flags |= __ioremap_check_ram(res);

	if (!(desc->flags & IORES_MAP_ENCRYPTED))
		desc->flags |= __ioremap_check_encrypted(res);

	return ((desc->flags & (IORES_MAP_SYSTEM_RAM | IORES_MAP_ENCRYPTED)) ==
			       (IORES_MAP_SYSTEM_RAM | IORES_MAP_ENCRYPTED));
}

/*
 * To avoid multiple resource walks, this function walks resources marked as
 * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a
 * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES).
 *
 * After that, deal with misc other ranges in __ioremap_check_other() which do
 * not fall into the above category.
 */
static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
				struct ioremap_desc *desc)
{
	u64 start, end;

	start = (u64)addr;
	end = start + size - 1;
	memset(desc, 0, sizeof(struct ioremap_desc));

	walk_mem_res(start, end, desc, __ioremap_collect_map_flags);

	__ioremap_check_other(addr, desc);
}

/*
 * Remap an arbitrary physical address space into the kernel virtual
 * address space. It transparently creates kernel huge I/O mapping when
 * the physical address is aligned by a huge page size (1GB or 2MB) and
 * the requested size is at least the huge page size.
 *
 * NOTE: MTRRs can override PAT memory types with a 4KB granularity.
 * Therefore, the mapping code falls back to use a smaller page toward 4KB
 * when a mapping range is covered by non-WB type of MTRRs.
 *
 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
 * have to convert them into an offset in a page-aligned mapping, but the
 * caller shouldn't need to know that small detail.
 */
static void __iomem *
__ioremap_caller(resource_size_t phys_addr, unsigned long size,
		 enum page_cache_mode pcm, void *caller, bool encrypted)
{
	unsigned long offset, vaddr;
	resource_size_t last_addr;
	const resource_size_t unaligned_phys_addr = phys_addr;
	const unsigned long unaligned_size = size;
	struct ioremap_desc io_desc;
	struct vm_struct *area;
	enum page_cache_mode new_pcm;
	pgprot_t prot;
	int retval;
	void __iomem *ret_addr;

	/* Don't allow wraparound or zero size */
	last_addr = phys_addr + size - 1;
	if (!size || last_addr < phys_addr)
		return NULL;

	if (!phys_addr_valid(phys_addr)) {
		printk(KERN_WARNING "ioremap: invalid physical address %llx\n",
		       (unsigned long long)phys_addr);
		WARN_ON_ONCE(1);
		return NULL;
	}

	__ioremap_check_mem(phys_addr, size, &io_desc);

	/*
	 * Don't allow anybody to remap normal RAM that we're using..
	 */
	if (io_desc.flags & IORES_MAP_SYSTEM_RAM) {
		WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
			  &phys_addr, &last_addr);
		return NULL;
	}

	/*
	 * Mappings have to be page-aligned
	 */
	offset = phys_addr & ~PAGE_MASK;
	phys_addr &= PAGE_MASK;
	size = PAGE_ALIGN(last_addr+1) - phys_addr;

	/*
	 * Mask out any bits not part of the actual physical
	 * address, like memory encryption bits.
	 */
	phys_addr &= PHYSICAL_PAGE_MASK;

	retval = memtype_reserve(phys_addr, (u64)phys_addr + size,
						pcm, &new_pcm);
	if (retval) {
		printk(KERN_ERR "ioremap memtype_reserve failed %d\n", retval);
		return NULL;
	}

	if (pcm != new_pcm) {
		if (!is_new_memtype_allowed(phys_addr, size, pcm, new_pcm)) {
			printk(KERN_ERR
		"ioremap error for 0x%llx-0x%llx, requested 0x%x, got 0x%x\n",
				(unsigned long long)phys_addr,
				(unsigned long long)(phys_addr + size),
				pcm, new_pcm);
			goto err_free_memtype;
		}
		pcm = new_pcm;
	}

	/*
	 * If the page being mapped is in memory and SEV is active then
	 * make sure the memory encryption attribute is enabled in the
	 * resulting mapping.
	 * In TDX guests, memory is marked private by default. If encryption
	 * is not requested (using encrypted), explicitly set decrypt
	 * attribute in all IOREMAPPED memory.
	 */
	prot = PAGE_KERNEL_IO;
	if ((io_desc.flags & IORES_MAP_ENCRYPTED) || encrypted)
		prot = pgprot_encrypted(prot);
	else
		prot = pgprot_decrypted(prot);

	switch (pcm) {
	case _PAGE_CACHE_MODE_UC:
	default:
		prot = __pgprot(pgprot_val(prot) |
				cachemode2protval(_PAGE_CACHE_MODE_UC));
		break;
	case _PAGE_CACHE_MODE_UC_MINUS:
		prot = __pgprot(pgprot_val(prot) |
				cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS));
		break;
	case _PAGE_CACHE_MODE_WC:
		prot = __pgprot(pgprot_val(prot) |
				cachemode2protval(_PAGE_CACHE_MODE_WC));
		break;
	case _PAGE_CACHE_MODE_WT:
		prot = __pgprot(pgprot_val(prot) |
				cachemode2protval(_PAGE_CACHE_MODE_WT));
		break;
	case _PAGE_CACHE_MODE_WB:
		break;
	}

	/*
	 * Ok, go for it..
	 */
	area = get_vm_area_caller(size, VM_IOREMAP, caller);
	if (!area)
		goto err_free_memtype;
	area->phys_addr = phys_addr;
	vaddr = (unsigned long) area->addr;

	if (memtype_kernel_map_sync(phys_addr, size, pcm))
		goto err_free_area;

	if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot))
		goto err_free_area;

	ret_addr = (void __iomem *) (vaddr + offset);
	mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr);

	/*
	 * Check if the request spans more than any BAR in the iomem resource
	 * tree.
	 */
	if (iomem_map_sanity_check(unaligned_phys_addr, unaligned_size))
		pr_warn("caller %pS mapping multiple BARs\n", caller);

	return ret_addr;
err_free_area:
	free_vm_area(area);
err_free_memtype:
	memtype_free(phys_addr, phys_addr + size);
	return NULL;
}

/**
 * ioremap     -   map bus memory into CPU space
 * @phys_addr:    bus address of the memory
 * @size:      size of the resource to map
 *
 * ioremap performs a platform specific sequence of operations to
 * make bus memory CPU accessible via the readb/readw/readl/writeb/
 * writew/writel functions and the other mmio helpers. The returned
 * address is not guaranteed to be usable directly as a virtual
 * address.
 *
 * This version of ioremap ensures that the memory is marked uncachable
 * on the CPU as well as honouring existing caching rules from things like
 * the PCI bus. Note that there are other caches and buffers on many
 * busses. In particular driver authors should read up on PCI writes
 *
 * It's useful if some control registers are in such an area and
 * write combining or read caching is not desirable:
 *
 * Must be freed with iounmap.
 */
void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
{
	/*
	 * Ideally, this should be:
	 *	pat_enabled() ? _PAGE_CACHE_MODE_UC : _PAGE_CACHE_MODE_UC_MINUS;
	 *
	 * Till we fix all X drivers to use ioremap_wc(), we will use
	 * UC MINUS. Drivers that are certain they need or can already
	 * be converted over to strong UC can use ioremap_uc().
	 */
	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;

	return __ioremap_caller(phys_addr, size, pcm,
				__builtin_return_address(0), false);
}
EXPORT_SYMBOL(ioremap);

/**
 * ioremap_uc     -   map bus memory into CPU space as strongly uncachable
 * @phys_addr:    bus address of the memory
 * @size:      size of the resource to map
 *
 * ioremap_uc performs a platform specific sequence of operations to
 * make bus memory CPU accessible via the readb/readw/readl/writeb/
 * writew/writel functions and the other mmio helpers. The returned
 * address is not guaranteed to be usable directly as a virtual
 * address.
 *
 * This version of ioremap ensures that the memory is marked with a strong
 * preference as completely uncachable on the CPU when possible. For non-PAT
 * systems this ends up setting page-attribute flags PCD=1, PWT=1. For PAT
 * systems this will set the PAT entry for the pages as strong UC.  This call
 * will honor existing caching rules from things like the PCI bus. Note that
 * there are other caches and buffers on many busses. In particular driver
 * authors should read up on PCI writes.
 *
 * It's useful if some control registers are in such an area and
 * write combining or read caching is not desirable:
 *
 * Must be freed with iounmap.
 */
void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
{
	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;

	return __ioremap_caller(phys_addr, size, pcm,
				__builtin_return_address(0), false);
}
EXPORT_SYMBOL_GPL(ioremap_uc);

/**
 * ioremap_wc	-	map memory into CPU space write combined
 * @phys_addr:	bus address of the memory
 * @size:	size of the resource to map
 *
 * This version of ioremap ensures that the memory is marked write combining.
 * Write combining allows faster writes to some hardware devices.
 *
 * Must be freed with iounmap.
 */
void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
{
	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
					__builtin_return_address(0), false);
}
EXPORT_SYMBOL(ioremap_wc);

/**
 * ioremap_wt	-	map memory into CPU space write through
 * @phys_addr:	bus address of the memory
 * @size:	size of the resource to map
 *
 * This version of ioremap ensures that the memory is marked write through.
 * Write through stores data into memory while keeping the cache up-to-date.
 *
 * Must be freed with iounmap.
 */
void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
{
	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
					__builtin_return_address(0), false);
}
EXPORT_SYMBOL(ioremap_wt);

void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
{
	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
				__builtin_return_address(0), true);
}
EXPORT_SYMBOL(ioremap_encrypted);

void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
{
	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
				__builtin_return_address(0), false);
}
EXPORT_SYMBOL(ioremap_cache);

void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
				unsigned long prot_val)
{
	return __ioremap_caller(phys_addr, size,
				pgprot2cachemode(__pgprot(prot_val)),
				__builtin_return_address(0), false);
}
EXPORT_SYMBOL(ioremap_prot);

/**
 * iounmap - Free a IO remapping
 * @addr: virtual address from ioremap_*
 *
 * Caller must ensure there is only one unmapping for the same pointer.
 */
void iounmap(volatile void __iomem *addr)
{
	struct vm_struct *p, *o;

	if ((void __force *)addr <= high_memory)
		return;

	/*
	 * The PCI/ISA range special-casing was removed from __ioremap()
	 * so this check, in theory, can be removed. However, there are
	 * cases where iounmap() is called for addresses not obtained via
	 * ioremap() (vga16fb for example). Add a warning so that these
	 * cases can be caught and fixed.
	 */
	if ((void __force *)addr >= phys_to_virt(ISA_START_ADDRESS) &&
	    (void __force *)addr < phys_to_virt(ISA_END_ADDRESS)) {
		WARN(1, "iounmap() called for ISA range not obtained using ioremap()\n");
		return;
	}

	mmiotrace_iounmap(addr);

	addr = (volatile void __iomem *)
		(PAGE_MASK & (unsigned long __force)addr);

	/* Use the vm area unlocked, assuming the caller
	   ensures there isn't another iounmap for the same address
	   in parallel. Reuse of the virtual address is prevented by
	   leaving it in the global lists until we're done with it.
	   cpa takes care of the direct mappings. */
	p = find_vm_area((void __force *)addr);

	if (!p) {
		printk(KERN_ERR "iounmap: bad address %p\n", addr);
		dump_stack();
		return;
	}

	kmsan_iounmap_page_range((unsigned long)addr,
		(unsigned long)addr + get_vm_area_size(p));
	memtype_free(p->phys_addr, p->phys_addr + get_vm_area_size(p));

	/* Finally remove it */
	o = remove_vm_area((void __force *)addr);
	BUG_ON(p != o || o == NULL);
	kfree(p);
}
EXPORT_SYMBOL(iounmap);

/*
 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
 * access
 */
void *xlate_dev_mem_ptr(phys_addr_t phys)
{
	unsigned long start  = phys &  PAGE_MASK;
	unsigned long offset = phys & ~PAGE_MASK;
	void *vaddr;

	/* memremap() maps if RAM, otherwise falls back to ioremap() */
	vaddr = memremap(start, PAGE_SIZE, MEMREMAP_WB);

	/* Only add the offset on success and return NULL if memremap() failed */
	if (vaddr)
		vaddr += offset;

	return vaddr;
}

void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
{
	memunmap((void *)((unsigned long)addr & PAGE_MASK));
}

#ifdef CONFIG_AMD_MEM_ENCRYPT
/*
 * Examine the physical address to determine if it is an area of memory
 * that should be mapped decrypted.  If the memory is not part of the
 * kernel usable area it was accessed and created decrypted, so these
 * areas should be mapped decrypted. And since the encryption key can
 * change across reboots, persistent memory should also be mapped
 * decrypted.
 *
 * If SEV is active, that implies that BIOS/UEFI also ran encrypted so
 * only persistent memory should be mapped decrypted.
 */
static bool memremap_should_map_decrypted(resource_size_t phys_addr,
					  unsigned long size)
{
	int is_pmem;

	/*
	 * Check if the address is part of a persistent memory region.
	 * This check covers areas added by E820, EFI and ACPI.
	 */
	is_pmem = region_intersects(phys_addr, size, IORESOURCE_MEM,
				    IORES_DESC_PERSISTENT_MEMORY);
	if (is_pmem != REGION_DISJOINT)
		return true;

	/*
	 * Check if the non-volatile attribute is set for an EFI
	 * reserved area.
	 */
	if (efi_enabled(EFI_BOOT)) {
		switch (efi_mem_type(phys_addr)) {
		case EFI_RESERVED_TYPE:
			if (efi_mem_attributes(phys_addr) & EFI_MEMORY_NV)
				return true;
			break;
		default:
			break;
		}
	}

	/* Check if the address is outside kernel usable area */
	switch (e820__get_entry_type(phys_addr, phys_addr + size - 1)) {
	case E820_TYPE_RESERVED:
	case E820_TYPE_ACPI:
	case E820_TYPE_NVS:
	case E820_TYPE_UNUSABLE:
		/* For SEV, these areas are encrypted */
		if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
			break;
		fallthrough;

	case E820_TYPE_PRAM:
		return true;
	default:
		break;
	}

	return false;
}

/*
 * Examine the physical address to determine if it is EFI data. Check
 * it against the boot params structure and EFI tables and memory types.
 */
static bool memremap_is_efi_data(resource_size_t phys_addr,
				 unsigned long size)
{
	u64 paddr;

	/* Check if the address is part of EFI boot/runtime data */
	if (!efi_enabled(EFI_BOOT))
		return false;

	paddr = boot_params.efi_info.efi_memmap_hi;
	paddr <<= 32;
	paddr |= boot_params.efi_info.efi_memmap;
	if (phys_addr == paddr)
		return true;

	paddr = boot_params.efi_info.efi_systab_hi;
	paddr <<= 32;
	paddr |= boot_params.efi_info.efi_systab;
	if (phys_addr == paddr)
		return true;

	if (efi_is_table_address(phys_addr))
		return true;

	switch (efi_mem_type(phys_addr)) {
	case EFI_BOOT_SERVICES_DATA:
	case EFI_RUNTIME_SERVICES_DATA:
		return true;
	default:
		break;
	}

	return false;
}

/*
 * Examine the physical address to determine if it is boot data by checking
 * it against the boot params setup_data chain.
 */
static bool memremap_is_setup_data(resource_size_t phys_addr,
				   unsigned long size)
{
	struct setup_indirect *indirect;
	struct setup_data *data;
	u64 paddr, paddr_next;

	paddr = boot_params.hdr.setup_data;
	while (paddr) {
		unsigned int len;

		if (phys_addr == paddr)
			return true;

		data = memremap(paddr, sizeof(*data),
				MEMREMAP_WB | MEMREMAP_DEC);
		if (!data) {
			pr_warn("failed to memremap setup_data entry\n");
			return false;
		}

		paddr_next = data->next;
		len = data->len;

		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
			memunmap(data);
			return true;
		}

		if (data->type == SETUP_INDIRECT) {
			memunmap(data);
			data = memremap(paddr, sizeof(*data) + len,
					MEMREMAP_WB | MEMREMAP_DEC);
			if (!data) {
				pr_warn("failed to memremap indirect setup_data\n");
				return false;
			}

			indirect = (struct setup_indirect *)data->data;

			if (indirect->type != SETUP_INDIRECT) {
				paddr = indirect->addr;
				len = indirect->len;
			}
		}

		memunmap(data);

		if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
			return true;

		paddr = paddr_next;
	}

	return false;
}

/*
 * Examine the physical address to determine if it is boot data by checking
 * it against the boot params setup_data chain (early boot version).
 */
static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
						unsigned long size)
{
	struct setup_indirect *indirect;
	struct setup_data *data;
	u64 paddr, paddr_next;

	paddr = boot_params.hdr.setup_data;
	while (paddr) {
		unsigned int len, size;

		if (phys_addr == paddr)
			return true;

		data = early_memremap_decrypted(paddr, sizeof(*data));
		if (!data) {
			pr_warn("failed to early memremap setup_data entry\n");
			return false;
		}

		size = sizeof(*data);

		paddr_next = data->next;
		len = data->len;

		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
			early_memunmap(data, sizeof(*data));
			return true;
		}

		if (data->type == SETUP_INDIRECT) {
			size += len;
			early_memunmap(data, sizeof(*data));
			data = early_memremap_decrypted(paddr, size);
			if (!data) {
				pr_warn("failed to early memremap indirect setup_data\n");
				return false;
			}

			indirect = (struct setup_indirect *)data->data;

			if (indirect->type != SETUP_INDIRECT) {
				paddr = indirect->addr;
				len = indirect->len;
			}
		}

		early_memunmap(data, size);

		if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
			return true;

		paddr = paddr_next;
	}

	return false;
}

/*
 * Architecture function to determine if RAM remap is allowed. By default, a
 * RAM remap will map the data as encrypted. Determine if a RAM remap should
 * not be done so that the data will be mapped decrypted.
 */
bool arch_memremap_can_ram_remap(resource_size_t phys_addr, unsigned long size,
				 unsigned long flags)
{
	if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
		return true;

	if (flags & MEMREMAP_ENC)
		return true;

	if (flags & MEMREMAP_DEC)
		return false;

	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
		if (memremap_is_setup_data(phys_addr, size) ||
		    memremap_is_efi_data(phys_addr, size))
			return false;
	}

	return !memremap_should_map_decrypted(phys_addr, size);
}

/*
 * Architecture override of __weak function to adjust the protection attributes
 * used when remapping memory. By default, early_memremap() will map the data
 * as encrypted. Determine if an encrypted mapping should not be done and set
 * the appropriate protection attributes.
 */
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
					     unsigned long size,
					     pgprot_t prot)
{
	bool encrypted_prot;

	if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT))
		return prot;

	encrypted_prot = true;

	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
		if (early_memremap_is_setup_data(phys_addr, size) ||
		    memremap_is_efi_data(phys_addr, size))
			encrypted_prot = false;
	}

	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
		encrypted_prot = false;

	return encrypted_prot ? pgprot_encrypted(prot)
			      : pgprot_decrypted(prot);
}

bool phys_mem_access_encrypted(unsigned long phys_addr, unsigned long size)
{
	return arch_memremap_can_ram_remap(phys_addr, size, 0);
}

/* Remap memory with encryption */
void __init *early_memremap_encrypted(resource_size_t phys_addr,
				      unsigned long size)
{
	return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_ENC);
}

/*
 * Remap memory with encryption and write-protected - cannot be called
 * before pat_init() is called
 */
void __init *early_memremap_encrypted_wp(resource_size_t phys_addr,
					 unsigned long size)
{
	if (!x86_has_pat_wp())
		return NULL;
	return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_ENC_WP);
}

/* Remap memory without encryption */
void __init *early_memremap_decrypted(resource_size_t phys_addr,
				      unsigned long size)
{
	return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC);
}

/*
 * Remap memory without encryption and write-protected - cannot be called
 * before pat_init() is called
 */
void __init *early_memremap_decrypted_wp(resource_size_t phys_addr,
					 unsigned long size)
{
	if (!x86_has_pat_wp())
		return NULL;
	return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC_WP);
}
#endif	/* CONFIG_AMD_MEM_ENCRYPT */

static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;

static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
{
	/* Don't assume we're using swapper_pg_dir at this point */
	pgd_t *base = __va(read_cr3_pa());
	pgd_t *pgd = &base[pgd_index(addr)];
	p4d_t *p4d = p4d_offset(pgd, addr);
	pud_t *pud = pud_offset(p4d, addr);
	pmd_t *pmd = pmd_offset(pud, addr);

	return pmd;
}

static inline pte_t * __init early_ioremap_pte(unsigned long addr)
{
	return &bm_pte[pte_index(addr)];
}

bool __init is_early_ioremap_ptep(pte_t *ptep)
{
	return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)];
}

void __init early_ioremap_init(void)
{
	pmd_t *pmd;

#ifdef CONFIG_X86_64
	BUILD_BUG_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1));
#else
	WARN_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1));
#endif

	early_ioremap_setup();

	pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
	memset(bm_pte, 0, sizeof(bm_pte));
	pmd_populate_kernel(&init_mm, pmd, bm_pte);

	/*
	 * The boot-ioremap range spans multiple pmds, for which
	 * we are not prepared:
	 */
#define __FIXADDR_TOP (-PAGE_SIZE)
	BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
		     != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
#undef __FIXADDR_TOP
	if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
		WARN_ON(1);
		printk(KERN_WARNING "pmd %p != %p\n",
		       pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
		printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
			fix_to_virt(FIX_BTMAP_BEGIN));
		printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END):   %08lx\n",
			fix_to_virt(FIX_BTMAP_END));

		printk(KERN_WARNING "FIX_BTMAP_END:       %d\n", FIX_BTMAP_END);
		printk(KERN_WARNING "FIX_BTMAP_BEGIN:     %d\n",
		       FIX_BTMAP_BEGIN);
	}
}

void __init __early_set_fixmap(enum fixed_addresses idx,
			       phys_addr_t phys, pgprot_t flags)
{
	unsigned long addr = __fix_to_virt(idx);
	pte_t *pte;

	if (idx >= __end_of_fixed_addresses) {
		BUG();
		return;
	}
	pte = early_ioremap_pte(addr);

	/* Sanitize 'prot' against any unsupported bits: */
	pgprot_val(flags) &= __supported_pte_mask;

	if (pgprot_val(flags))
		set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
	else
		pte_clear(&init_mm, addr, pte);
	flush_tlb_one_kernel(addr);
}
