// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
 * Author: Joerg Roedel <jroedel@suse.de>
 *         Leo Duran <leo.duran@amd.com>
 */

#define pr_fmt(fmt)     "AMD-Vi: " fmt
#define dev_fmt(fmt)    pr_fmt(fmt)

#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
#include <linux/msi.h>
#include <linux/irq.h>
#include <linux/amd-iommu.h>
#include <linux/export.h>
#include <linux/kmemleak.h>
#include <linux/cc_platform.h>
#include <linux/iopoll.h>
#include <asm/pci-direct.h>
#include <asm/iommu.h>
#include <asm/apic.h>
#include <asm/gart.h>
#include <asm/x86_init.h>
#include <asm/io_apic.h>
#include <asm/irq_remapping.h>
#include <asm/set_memory.h>
#include <asm/sev.h>

#include <linux/crash_dump.h>

#include "amd_iommu.h"
#include "../irq_remapping.h"
#include "../iommu-pages.h"

/*
 * definitions for the ACPI scanning code
 */
#define IVRS_HEADER_LENGTH 48

#define ACPI_IVHD_TYPE_MAX_SUPPORTED	0x40
#define ACPI_IVMD_TYPE_ALL              0x20
#define ACPI_IVMD_TYPE                  0x21
#define ACPI_IVMD_TYPE_RANGE            0x22

#define IVHD_DEV_ALL                    0x01
#define IVHD_DEV_SELECT                 0x02
#define IVHD_DEV_SELECT_RANGE_START     0x03
#define IVHD_DEV_RANGE_END              0x04
#define IVHD_DEV_ALIAS                  0x42
#define IVHD_DEV_ALIAS_RANGE            0x43
#define IVHD_DEV_EXT_SELECT             0x46
#define IVHD_DEV_EXT_SELECT_RANGE       0x47
#define IVHD_DEV_SPECIAL		0x48
#define IVHD_DEV_ACPI_HID		0xf0

#define UID_NOT_PRESENT                 0
#define UID_IS_INTEGER                  1
#define UID_IS_CHARACTER                2

#define IVHD_SPECIAL_IOAPIC		1
#define IVHD_SPECIAL_HPET		2

#define IVHD_FLAG_HT_TUN_EN_MASK        0x01
#define IVHD_FLAG_PASSPW_EN_MASK        0x02
#define IVHD_FLAG_RESPASSPW_EN_MASK     0x04
#define IVHD_FLAG_ISOC_EN_MASK          0x08

#define IVMD_FLAG_EXCL_RANGE            0x08
#define IVMD_FLAG_IW                    0x04
#define IVMD_FLAG_IR                    0x02
#define IVMD_FLAG_UNITY_MAP             0x01

#define ACPI_DEVFLAG_INITPASS           0x01
#define ACPI_DEVFLAG_EXTINT             0x02
#define ACPI_DEVFLAG_NMI                0x04
#define ACPI_DEVFLAG_SYSMGT1            0x10
#define ACPI_DEVFLAG_SYSMGT2            0x20
#define ACPI_DEVFLAG_LINT0              0x40
#define ACPI_DEVFLAG_LINT1              0x80
#define ACPI_DEVFLAG_ATSDIS             0x10000000

#define IVRS_GET_SBDF_ID(seg, bus, dev, fn)	(((seg & 0xffff) << 16) | ((bus & 0xff) << 8) \
						 | ((dev & 0x1f) << 3) | (fn & 0x7))

/*
 * ACPI table definitions
 *
 * These data structures are laid over the table to parse the important values
 * out of it.
 */

/*
 * structure describing one IOMMU in the ACPI table. Typically followed by one
 * or more ivhd_entrys.
 */
struct ivhd_header {
	u8 type;
	u8 flags;
	u16 length;
	u16 devid;
	u16 cap_ptr;
	u64 mmio_phys;
	u16 pci_seg;
	u16 info;
	u32 efr_attr;

	/* Following only valid on IVHD type 11h and 40h */
	u64 efr_reg; /* Exact copy of MMIO_EXT_FEATURES */
	u64 efr_reg2;
} __attribute__((packed));

/*
 * A device entry describing which devices a specific IOMMU translates and
 * which requestor ids they use.
 */
struct ivhd_entry {
	u8 type;
	u16 devid;
	u8 flags;
	struct_group(ext_hid,
		u32 ext;
		u32 hidh;
	);
	u64 cid;
	u8 uidf;
	u8 uidl;
	u8 uid;
} __attribute__((packed));

int amd_iommu_evtlog_size = EVTLOG_SIZE_DEF;
int amd_iommu_pprlog_size = PPRLOG_SIZE_DEF;

/*
 * An AMD IOMMU memory definition structure. It defines things like exclusion
 * ranges for devices and regions that should be unity mapped.
 */
struct ivmd_header {
	u8 type;
	u8 flags;
	u16 length;
	u16 devid;
	u16 aux;
	u16 pci_seg;
	u8  resv[6];
	u64 range_start;
	u64 range_length;
} __attribute__((packed));

bool amd_iommu_dump;
bool amd_iommu_irq_remap __read_mostly;

enum protection_domain_mode amd_iommu_pgtable = PD_MODE_V1;
/* Host page table level */
u8 amd_iommu_hpt_level;
/* Guest page table level */
int amd_iommu_gpt_level = PAGE_MODE_4_LEVEL;

int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;

static bool amd_iommu_detected;
static bool amd_iommu_disabled __initdata;
static bool amd_iommu_force_enable __initdata;
static bool amd_iommu_irtcachedis;
static int amd_iommu_target_ivhd_type;

/* Global EFR and EFR2 registers */
u64 amd_iommu_efr;
u64 amd_iommu_efr2;

/* Host (v1) page table is not supported*/
bool amd_iommu_hatdis;

/* SNP is enabled on the system? */
bool amd_iommu_snp_en;
EXPORT_SYMBOL(amd_iommu_snp_en);

LIST_HEAD(amd_iommu_pci_seg_list);	/* list of all PCI segments */
LIST_HEAD(amd_iommu_list);		/* list of all AMD IOMMUs in the system */
LIST_HEAD(amd_ivhd_dev_flags_list);	/* list of all IVHD device entry settings */

/* Number of IOMMUs present in the system */
static int amd_iommus_present;

/* IOMMUs have a non-present cache? */
bool amd_iommu_np_cache __read_mostly;
bool amd_iommu_iotlb_sup __read_mostly = true;

static bool amd_iommu_pc_present __read_mostly;
bool amdr_ivrs_remap_support __read_mostly;

bool amd_iommu_force_isolation __read_mostly;

unsigned long amd_iommu_pgsize_bitmap __ro_after_init = AMD_IOMMU_PGSIZES;

enum iommu_init_state {
	IOMMU_START_STATE,
	IOMMU_IVRS_DETECTED,
	IOMMU_ACPI_FINISHED,
	IOMMU_ENABLED,
	IOMMU_PCI_INIT,
	IOMMU_INTERRUPTS_EN,
	IOMMU_INITIALIZED,
	IOMMU_NOT_FOUND,
	IOMMU_INIT_ERROR,
	IOMMU_CMDLINE_DISABLED,
};

/* Early ioapic and hpet maps from kernel command line */
#define EARLY_MAP_SIZE		4
static struct devid_map __initdata early_ioapic_map[EARLY_MAP_SIZE];
static struct devid_map __initdata early_hpet_map[EARLY_MAP_SIZE];
static struct acpihid_map_entry __initdata early_acpihid_map[EARLY_MAP_SIZE];

static int __initdata early_ioapic_map_size;
static int __initdata early_hpet_map_size;
static int __initdata early_acpihid_map_size;

static bool __initdata cmdline_maps;

static enum iommu_init_state init_state = IOMMU_START_STATE;

static int amd_iommu_enable_interrupts(void);
static void init_device_table_dma(struct amd_iommu_pci_seg *pci_seg);

static bool amd_iommu_pre_enabled = true;

static u32 amd_iommu_ivinfo __initdata;

bool translation_pre_enabled(struct amd_iommu *iommu)
{
	return (iommu->flags & AMD_IOMMU_FLAG_TRANS_PRE_ENABLED);
}

static void clear_translation_pre_enabled(struct amd_iommu *iommu)
{
	iommu->flags &= ~AMD_IOMMU_FLAG_TRANS_PRE_ENABLED;
}

static void init_translation_status(struct amd_iommu *iommu)
{
	u64 ctrl;

	ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
	if (ctrl & (1<<CONTROL_IOMMU_EN))
		iommu->flags |= AMD_IOMMU_FLAG_TRANS_PRE_ENABLED;
}

int amd_iommu_get_num_iommus(void)
{
	return amd_iommus_present;
}

bool amd_iommu_ht_range_ignore(void)
{
	return check_feature2(FEATURE_HT_RANGE_IGNORE);
}

/*
 * Iterate through all the IOMMUs to get common EFR
 * masks among all IOMMUs and warn if found inconsistency.
 */
static __init void get_global_efr(void)
{
	struct amd_iommu *iommu;

	for_each_iommu(iommu) {
		u64 tmp = iommu->features;
		u64 tmp2 = iommu->features2;

		if (list_is_first(&iommu->list, &amd_iommu_list)) {
			amd_iommu_efr = tmp;
			amd_iommu_efr2 = tmp2;
			continue;
		}

		if (amd_iommu_efr == tmp &&
		    amd_iommu_efr2 == tmp2)
			continue;

		pr_err(FW_BUG
		       "Found inconsistent EFR/EFR2 %#llx,%#llx (global %#llx,%#llx) on iommu%d (%04x:%02x:%02x.%01x).\n",
		       tmp, tmp2, amd_iommu_efr, amd_iommu_efr2,
		       iommu->index, iommu->pci_seg->id,
		       PCI_BUS_NUM(iommu->devid), PCI_SLOT(iommu->devid),
		       PCI_FUNC(iommu->devid));

		amd_iommu_efr &= tmp;
		amd_iommu_efr2 &= tmp2;
	}

	pr_info("Using global IVHD EFR:%#llx, EFR2:%#llx\n", amd_iommu_efr, amd_iommu_efr2);
}

/*
 * For IVHD type 0x11/0x40, EFR is also available via IVHD.
 * Default to IVHD EFR since it is available sooner
 * (i.e. before PCI init).
 */
static void __init early_iommu_features_init(struct amd_iommu *iommu,
					     struct ivhd_header *h)
{
	if (amd_iommu_ivinfo & IOMMU_IVINFO_EFRSUP) {
		iommu->features = h->efr_reg;
		iommu->features2 = h->efr_reg2;
	}
	if (amd_iommu_ivinfo & IOMMU_IVINFO_DMA_REMAP)
		amdr_ivrs_remap_support = true;
}

/* Access to l1 and l2 indexed register spaces */

static u32 iommu_read_l1(struct amd_iommu *iommu, u16 l1, u8 address)
{
	u32 val;

	pci_write_config_dword(iommu->dev, 0xf8, (address | l1 << 16));
	pci_read_config_dword(iommu->dev, 0xfc, &val);
	return val;
}

static void iommu_write_l1(struct amd_iommu *iommu, u16 l1, u8 address, u32 val)
{
	pci_write_config_dword(iommu->dev, 0xf8, (address | l1 << 16 | 1 << 31));
	pci_write_config_dword(iommu->dev, 0xfc, val);
	pci_write_config_dword(iommu->dev, 0xf8, (address | l1 << 16));
}

static u32 iommu_read_l2(struct amd_iommu *iommu, u8 address)
{
	u32 val;

	pci_write_config_dword(iommu->dev, 0xf0, address);
	pci_read_config_dword(iommu->dev, 0xf4, &val);
	return val;
}

static void iommu_write_l2(struct amd_iommu *iommu, u8 address, u32 val)
{
	pci_write_config_dword(iommu->dev, 0xf0, (address | 1 << 8));
	pci_write_config_dword(iommu->dev, 0xf4, val);
}

/****************************************************************************
 *
 * AMD IOMMU MMIO register space handling functions
 *
 * These functions are used to program the IOMMU device registers in
 * MMIO space required for that driver.
 *
 ****************************************************************************/

/*
 * This function set the exclusion range in the IOMMU. DMA accesses to the
 * exclusion range are passed through untranslated
 */
static void iommu_set_exclusion_range(struct amd_iommu *iommu)
{
	u64 start = iommu->exclusion_start & PAGE_MASK;
	u64 limit = (start + iommu->exclusion_length - 1) & PAGE_MASK;
	u64 entry;

	if (!iommu->exclusion_start)
		return;

	entry = start | MMIO_EXCL_ENABLE_MASK;
	memcpy_toio(iommu->mmio_base + MMIO_EXCL_BASE_OFFSET,
			&entry, sizeof(entry));

	entry = limit;
	memcpy_toio(iommu->mmio_base + MMIO_EXCL_LIMIT_OFFSET,
			&entry, sizeof(entry));
}

static void iommu_set_cwwb_range(struct amd_iommu *iommu)
{
	u64 start = iommu_virt_to_phys((void *)iommu->cmd_sem);
	u64 entry = start & PM_ADDR_MASK;

	if (!check_feature(FEATURE_SNP))
		return;

	/* Note:
	 * Re-purpose Exclusion base/limit registers for Completion wait
	 * write-back base/limit.
	 */
	memcpy_toio(iommu->mmio_base + MMIO_EXCL_BASE_OFFSET,
		    &entry, sizeof(entry));

	/* Note:
	 * Default to 4 Kbytes, which can be specified by setting base
	 * address equal to the limit address.
	 */
	memcpy_toio(iommu->mmio_base + MMIO_EXCL_LIMIT_OFFSET,
		    &entry, sizeof(entry));
}

/* Programs the physical address of the device table into the IOMMU hardware */
static void iommu_set_device_table(struct amd_iommu *iommu)
{
	u64 entry;
	u32 dev_table_size = iommu->pci_seg->dev_table_size;
	void *dev_table = (void *)get_dev_table(iommu);

	BUG_ON(iommu->mmio_base == NULL);

	if (is_kdump_kernel())
		return;

	entry = iommu_virt_to_phys(dev_table);
	entry |= (dev_table_size >> 12) - 1;
	memcpy_toio(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET,
			&entry, sizeof(entry));
}

static void iommu_feature_set(struct amd_iommu *iommu, u64 val, u64 mask, u8 shift)
{
	u64 ctrl;

	ctrl = readq(iommu->mmio_base +  MMIO_CONTROL_OFFSET);
	mask <<= shift;
	ctrl &= ~mask;
	ctrl |= (val << shift) & mask;
	writeq(ctrl, iommu->mmio_base +  MMIO_CONTROL_OFFSET);
}

/* Generic functions to enable/disable certain features of the IOMMU. */
void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
{
	iommu_feature_set(iommu, 1ULL, 1ULL, bit);
}

static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
{
	iommu_feature_set(iommu, 0ULL, 1ULL, bit);
}

/* Function to enable the hardware */
static void iommu_enable(struct amd_iommu *iommu)
{
	iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
}

static void iommu_disable(struct amd_iommu *iommu)
{
	if (!iommu->mmio_base)
		return;

	/* Disable command buffer */
	iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);

	/* Disable event logging and event interrupts */
	iommu_feature_disable(iommu, CONTROL_EVT_INT_EN);
	iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);

	/* Disable IOMMU GA_LOG */
	iommu_feature_disable(iommu, CONTROL_GALOG_EN);
	iommu_feature_disable(iommu, CONTROL_GAINT_EN);

	/* Disable IOMMU PPR logging */
	iommu_feature_disable(iommu, CONTROL_PPRLOG_EN);
	iommu_feature_disable(iommu, CONTROL_PPRINT_EN);

	/* Disable IOMMU hardware itself */
	iommu_feature_disable(iommu, CONTROL_IOMMU_EN);

	/* Clear IRTE cache disabling bit */
	iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS);
}

/*
 * mapping and unmapping functions for the IOMMU MMIO space. Each AMD IOMMU in
 * the system has one.
 */
static u8 __iomem * __init iommu_map_mmio_space(u64 address, u64 end)
{
	if (!request_mem_region(address, end, "amd_iommu")) {
		pr_err("Can not reserve memory region %llx-%llx for mmio\n",
			address, end);
		pr_err("This is a BIOS bug. Please contact your hardware vendor\n");
		return NULL;
	}

	return (u8 __iomem *)ioremap(address, end);
}

static void __init iommu_unmap_mmio_space(struct amd_iommu *iommu)
{
	if (iommu->mmio_base)
		iounmap(iommu->mmio_base);
	release_mem_region(iommu->mmio_phys, iommu->mmio_phys_end);
}

static inline u32 get_ivhd_header_size(struct ivhd_header *h)
{
	u32 size = 0;

	switch (h->type) {
	case 0x10:
		size = 24;
		break;
	case 0x11:
	case 0x40:
		size = 40;
		break;
	}
	return size;
}

/****************************************************************************
 *
 * The functions below belong to the first pass of AMD IOMMU ACPI table
 * parsing. In this pass we try to find out the highest device id this
 * code has to handle. Upon this information the size of the shared data
 * structures is determined later.
 *
 ****************************************************************************/

/*
 * This function calculates the length of a given IVHD entry
 */
static inline int ivhd_entry_length(u8 *ivhd)
{
	u32 type = ((struct ivhd_entry *)ivhd)->type;

	if (type < 0x80) {
		return 0x04 << (*ivhd >> 6);
	} else if (type == IVHD_DEV_ACPI_HID) {
		/* For ACPI_HID, offset 21 is uid len */
		return *((u8 *)ivhd + 21) + 22;
	}
	return 0;
}

/*
 * After reading the highest device id from the IOMMU PCI capability header
 * this function looks if there is a higher device id defined in the ACPI table
 */
static int __init find_last_devid_from_ivhd(struct ivhd_header *h)
{
	u8 *p = (void *)h, *end = (void *)h;
	struct ivhd_entry *dev;
	int last_devid = -EINVAL;

	u32 ivhd_size = get_ivhd_header_size(h);

	if (!ivhd_size) {
		pr_err("Unsupported IVHD type %#x\n", h->type);
		return -EINVAL;
	}

	p += ivhd_size;
	end += h->length;

	while (p < end) {
		dev = (struct ivhd_entry *)p;
		switch (dev->type) {
		case IVHD_DEV_ALL:
			/* Use maximum BDF value for DEV_ALL */
			return 0xffff;
		case IVHD_DEV_SELECT:
		case IVHD_DEV_RANGE_END:
		case IVHD_DEV_ALIAS:
		case IVHD_DEV_EXT_SELECT:
			/* all the above subfield types refer to device ids */
			if (dev->devid > last_devid)
				last_devid = dev->devid;
			break;
		default:
			break;
		}
		p += ivhd_entry_length(p);
	}

	WARN_ON(p != end);

	return last_devid;
}

static int __init check_ivrs_checksum(struct acpi_table_header *table)
{
	int i;
	u8 checksum = 0, *p = (u8 *)table;

	for (i = 0; i < table->length; ++i)
		checksum += p[i];
	if (checksum != 0) {
		/* ACPI table corrupt */
		pr_err(FW_BUG "IVRS invalid checksum\n");
		return -ENODEV;
	}

	return 0;
}

/*
 * Iterate over all IVHD entries in the ACPI table and find the highest device
 * id which we need to handle. This is the first of three functions which parse
 * the ACPI table. So we check the checksum here.
 */
static int __init find_last_devid_acpi(struct acpi_table_header *table, u16 pci_seg)
{
	u8 *p = (u8 *)table, *end = (u8 *)table;
	struct ivhd_header *h;
	int last_devid, last_bdf = 0;

	p += IVRS_HEADER_LENGTH;

	end += table->length;
	while (p < end) {
		h = (struct ivhd_header *)p;
		if (h->pci_seg == pci_seg &&
		    h->type == amd_iommu_target_ivhd_type) {
			last_devid = find_last_devid_from_ivhd(h);

			if (last_devid < 0)
				return -EINVAL;
			if (last_devid > last_bdf)
				last_bdf = last_devid;
		}
		p += h->length;
	}
	WARN_ON(p != end);

	return last_bdf;
}

/****************************************************************************
 *
 * The following functions belong to the code path which parses the ACPI table
 * the second time. In this ACPI parsing iteration we allocate IOMMU specific
 * data structures, initialize the per PCI segment device/alias/rlookup table
 * and also basically initialize the hardware.
 *
 ****************************************************************************/

/* Allocate per PCI segment device table */
static inline int __init alloc_dev_table(struct amd_iommu_pci_seg *pci_seg)
{
	pci_seg->dev_table = iommu_alloc_pages_sz(GFP_KERNEL | GFP_DMA32,
						  pci_seg->dev_table_size);
	if (!pci_seg->dev_table)
		return -ENOMEM;

	return 0;
}

static inline void free_dev_table(struct amd_iommu_pci_seg *pci_seg)
{
	if (is_kdump_kernel())
		memunmap((void *)pci_seg->dev_table);
	else
		iommu_free_pages(pci_seg->dev_table);
	pci_seg->dev_table = NULL;
}

/* Allocate per PCI segment IOMMU rlookup table. */
static inline int __init alloc_rlookup_table(struct amd_iommu_pci_seg *pci_seg)
{
	pci_seg->rlookup_table = kvzalloc_objs(*pci_seg->rlookup_table,
					       pci_seg->last_bdf + 1);
	if (pci_seg->rlookup_table == NULL)
		return -ENOMEM;

	return 0;
}

static inline void free_rlookup_table(struct amd_iommu_pci_seg *pci_seg)
{
	kvfree(pci_seg->rlookup_table);
	pci_seg->rlookup_table = NULL;
}

static inline int __init alloc_irq_lookup_table(struct amd_iommu_pci_seg *pci_seg)
{
	pci_seg->irq_lookup_table = kvzalloc_objs(*pci_seg->irq_lookup_table,
						  pci_seg->last_bdf + 1);
	if (pci_seg->irq_lookup_table == NULL)
		return -ENOMEM;

	return 0;
}

static inline void free_irq_lookup_table(struct amd_iommu_pci_seg *pci_seg)
{
	kvfree(pci_seg->irq_lookup_table);
	pci_seg->irq_lookup_table = NULL;
}

static int __init alloc_alias_table(struct amd_iommu_pci_seg *pci_seg)
{
	int i;

	pci_seg->alias_table = kvmalloc_objs(*pci_seg->alias_table,
					     pci_seg->last_bdf + 1);
	if (!pci_seg->alias_table)
		return -ENOMEM;

	/*
	 * let all alias entries point to itself
	 */
	for (i = 0; i <= pci_seg->last_bdf; ++i)
		pci_seg->alias_table[i] = i;

	return 0;
}

static void __init free_alias_table(struct amd_iommu_pci_seg *pci_seg)
{
	kvfree(pci_seg->alias_table);
	pci_seg->alias_table = NULL;
}

static inline void *iommu_memremap(unsigned long paddr, size_t size)
{
	phys_addr_t phys;

	if (!paddr)
		return NULL;

	/*
	 * Obtain true physical address in kdump kernel when SME is enabled.
	 * Currently, previous kernel with SME enabled and kdump kernel
	 * with SME support disabled is not supported.
	 */
	phys = __sme_clr(paddr);

	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
		return (__force void *)ioremap_encrypted(phys, size);
	else
		return memremap(phys, size, MEMREMAP_WB);
}

/*
 * Allocates the command buffer. This buffer is per AMD IOMMU. We can
 * write commands to that buffer later and the IOMMU will execute them
 * asynchronously
 */
static int __init alloc_command_buffer(struct amd_iommu *iommu)
{
	iommu->cmd_buf = iommu_alloc_pages_sz(GFP_KERNEL, CMD_BUFFER_SIZE);

	return iommu->cmd_buf ? 0 : -ENOMEM;
}

/*
 * Interrupt handler has processed all pending events and adjusted head
 * and tail pointer. Reset overflow mask and restart logging again.
 */
void amd_iommu_restart_log(struct amd_iommu *iommu, const char *evt_type,
			   u8 cntrl_intr, u8 cntrl_log,
			   u32 status_run_mask, u32 status_overflow_mask)
{
	u32 status;

	status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
	if (status & status_run_mask)
		return;

	pr_info_ratelimited("IOMMU %s log restarting\n", evt_type);

	iommu_feature_disable(iommu, cntrl_log);
	iommu_feature_disable(iommu, cntrl_intr);

	writel(status_overflow_mask, iommu->mmio_base + MMIO_STATUS_OFFSET);

	iommu_feature_enable(iommu, cntrl_intr);
	iommu_feature_enable(iommu, cntrl_log);
}

/*
 * This function restarts event logging in case the IOMMU experienced
 * an event log buffer overflow.
 */
void amd_iommu_restart_event_logging(struct amd_iommu *iommu)
{
	amd_iommu_restart_log(iommu, "Event", CONTROL_EVT_INT_EN,
			      CONTROL_EVT_LOG_EN, MMIO_STATUS_EVT_RUN_MASK,
			      MMIO_STATUS_EVT_OVERFLOW_MASK);
}

/*
 * This function restarts event logging in case the IOMMU experienced
 * GA log overflow.
 */
void amd_iommu_restart_ga_log(struct amd_iommu *iommu)
{
	amd_iommu_restart_log(iommu, "GA", CONTROL_GAINT_EN,
			      CONTROL_GALOG_EN, MMIO_STATUS_GALOG_RUN_MASK,
			      MMIO_STATUS_GALOG_OVERFLOW_MASK);
}

/*
 * This function resets the command buffer if the IOMMU stopped fetching
 * commands from it.
 */
static void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu)
{
	iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);

	writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
	writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
	iommu->cmd_buf_head = 0;
	iommu->cmd_buf_tail = 0;

	iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
}

/*
 * This function writes the command buffer address to the hardware and
 * enables it.
 */
static void iommu_enable_command_buffer(struct amd_iommu *iommu)
{
	u64 entry;

	BUG_ON(iommu->cmd_buf == NULL);

	if (!is_kdump_kernel()) {
		/*
		 * Command buffer is re-used for kdump kernel and setting
		 * of MMIO register is not required.
		 */
		entry = iommu_virt_to_phys(iommu->cmd_buf);
		entry |= MMIO_CMD_SIZE_512;
		memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
			    &entry, sizeof(entry));
	}

	amd_iommu_reset_cmd_buffer(iommu);
}

/*
 * This function disables the command buffer
 */
static void iommu_disable_command_buffer(struct amd_iommu *iommu)
{
	iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);
}

static void __init free_command_buffer(struct amd_iommu *iommu)
{
	iommu_free_pages(iommu->cmd_buf);
}

void *__init iommu_alloc_4k_pages(struct amd_iommu *iommu, gfp_t gfp,
				  size_t size)
{
	int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE;
	void *buf;

	size = PAGE_ALIGN(size);
	buf = iommu_alloc_pages_node_sz(nid, gfp, size);
	if (!buf)
		return NULL;
	if (check_feature(FEATURE_SNP) &&
	    set_memory_4k((unsigned long)buf, size / PAGE_SIZE)) {
		iommu_free_pages(buf);
		return NULL;
	}

	return buf;
}

/* allocates the memory where the IOMMU will log its events to */
static int __init alloc_event_buffer(void)
{
	struct amd_iommu *iommu;

	for_each_iommu(iommu) {
		iommu->evt_buf = iommu_alloc_4k_pages(iommu, GFP_KERNEL,
						      amd_iommu_evtlog_size);
		if (!iommu->evt_buf)
			return -ENOMEM;
	}

	return 0;
}

static void iommu_enable_event_buffer(void)
{
	struct amd_iommu *iommu;
	u64 entry;

	for_each_iommu(iommu) {
		BUG_ON(iommu->evt_buf == NULL);

		if (!is_kdump_kernel()) {
			/*
			 * Event buffer is re-used for kdump kernel and setting
			 * of MMIO register is not required.
			 */
			entry = iommu_virt_to_phys(iommu->evt_buf);
			entry |= (amd_iommu_evtlog_size == EVTLOG_SIZE_DEF) ?
				EVTLOG_LEN_MASK_DEF : EVTLOG_LEN_MASK_MAX;

			memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET,
				    &entry, sizeof(entry));
		}

		/* set head and tail to zero manually */
		writel(0x00, iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);
		writel(0x00, iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);

		iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
	}
}

/*
 * This function disables the event log buffer
 */
static void iommu_disable_event_buffer(struct amd_iommu *iommu)
{
	iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);
}

static void __init free_event_buffer(struct amd_iommu *iommu)
{
	iommu_free_pages(iommu->evt_buf);
}

static void free_ga_log(struct amd_iommu *iommu)
{
#ifdef CONFIG_IRQ_REMAP
	iommu_free_pages(iommu->ga_log);
	iommu_free_pages(iommu->ga_log_tail);
#endif
}

#ifdef CONFIG_IRQ_REMAP
static int iommu_ga_log_enable(struct amd_iommu *iommu)
{
	u32 status, i;
	u64 entry;

	if (!iommu->ga_log)
		return -EINVAL;

	entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
	memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
		    &entry, sizeof(entry));
	entry = (iommu_virt_to_phys(iommu->ga_log_tail) &
		 (BIT_ULL(52)-1)) & ~7ULL;
	memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
		    &entry, sizeof(entry));
	writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
	writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET);


	iommu_feature_enable(iommu, CONTROL_GAINT_EN);
	iommu_feature_enable(iommu, CONTROL_GALOG_EN);

	for (i = 0; i < MMIO_STATUS_TIMEOUT; ++i) {
		status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
		if (status & (MMIO_STATUS_GALOG_RUN_MASK))
			break;
		udelay(10);
	}

	if (WARN_ON(i >= MMIO_STATUS_TIMEOUT))
		return -EINVAL;

	return 0;
}

static int iommu_init_ga_log(struct amd_iommu *iommu)
{
	int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE;

	if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
		return 0;

	iommu->ga_log = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, GA_LOG_SIZE);
	if (!iommu->ga_log)
		goto err_out;

	iommu->ga_log_tail = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, 8);
	if (!iommu->ga_log_tail)
		goto err_out;

	return 0;
err_out:
	free_ga_log(iommu);
	return -EINVAL;
}
#endif /* CONFIG_IRQ_REMAP */

static int __init alloc_cwwb_sem(struct amd_iommu *iommu)
{
	iommu->cmd_sem = iommu_alloc_4k_pages(iommu, GFP_KERNEL, 1);
	if (!iommu->cmd_sem)
		return -ENOMEM;
	iommu->cmd_sem_paddr = iommu_virt_to_phys((void *)iommu->cmd_sem);
	return 0;
}

static int __init remap_event_buffer(void)
{
	struct amd_iommu *iommu;
	u64 paddr;

	pr_info_once("Re-using event buffer from the previous kernel\n");
	for_each_iommu(iommu) {
		paddr = readq(iommu->mmio_base + MMIO_EVT_BUF_OFFSET) & PM_ADDR_MASK;
		iommu->evt_buf = iommu_memremap(paddr, amd_iommu_evtlog_size);
		if (!iommu->evt_buf)
			return -ENOMEM;
	}

	return 0;
}

static int __init remap_command_buffer(struct amd_iommu *iommu)
{
	u64 paddr;

	pr_info_once("Re-using command buffer from the previous kernel\n");
	paddr = readq(iommu->mmio_base + MMIO_CMD_BUF_OFFSET) & PM_ADDR_MASK;
	iommu->cmd_buf = iommu_memremap(paddr, CMD_BUFFER_SIZE);

	return iommu->cmd_buf ? 0 : -ENOMEM;
}

static int __init remap_or_alloc_cwwb_sem(struct amd_iommu *iommu)
{
	u64 paddr;

	if (check_feature(FEATURE_SNP)) {
		/*
		 * When SNP is enabled, the exclusion base register is used for the
		 * completion wait buffer (CWB) address. Read and re-use it.
		 */
		pr_info_once("Re-using CWB buffers from the previous kernel\n");
		paddr = readq(iommu->mmio_base + MMIO_EXCL_BASE_OFFSET) & PM_ADDR_MASK;
		iommu->cmd_sem = iommu_memremap(paddr, PAGE_SIZE);
		if (!iommu->cmd_sem)
			return -ENOMEM;
		iommu->cmd_sem_paddr = paddr;
	} else {
		return alloc_cwwb_sem(iommu);
	}

	return 0;
}

static int __init alloc_iommu_buffers(struct amd_iommu *iommu)
{
	int ret;

	/*
	 * Reuse/Remap the previous kernel's allocated completion wait
	 * command and event buffers for kdump boot.
	 */
	if (is_kdump_kernel()) {
		ret = remap_or_alloc_cwwb_sem(iommu);
		if (ret)
			return ret;

		ret = remap_command_buffer(iommu);
		if (ret)
			return ret;
	} else {
		ret = alloc_cwwb_sem(iommu);
		if (ret)
			return ret;

		ret = alloc_command_buffer(iommu);
		if (ret)
			return ret;
	}

	return 0;
}

static void __init free_cwwb_sem(struct amd_iommu *iommu)
{
	if (iommu->cmd_sem)
		iommu_free_pages((void *)iommu->cmd_sem);
}
static void __init unmap_cwwb_sem(struct amd_iommu *iommu)
{
	if (iommu->cmd_sem) {
		if (check_feature(FEATURE_SNP))
			memunmap((void *)iommu->cmd_sem);
		else
			iommu_free_pages((void *)iommu->cmd_sem);
	}
}

static void __init unmap_command_buffer(struct amd_iommu *iommu)
{
	memunmap((void *)iommu->cmd_buf);
}

static void __init unmap_event_buffer(struct amd_iommu *iommu)
{
	memunmap(iommu->evt_buf);
}

static void __init free_iommu_buffers(struct amd_iommu *iommu)
{
	if (is_kdump_kernel()) {
		unmap_cwwb_sem(iommu);
		unmap_command_buffer(iommu);
		unmap_event_buffer(iommu);
	} else {
		free_cwwb_sem(iommu);
		free_command_buffer(iommu);
		free_event_buffer(iommu);
	}
}

static void iommu_enable_xt(struct amd_iommu *iommu)
{
#ifdef CONFIG_IRQ_REMAP
	/*
	 * XT mode (32-bit APIC destination ID) requires
	 * GA mode (128-bit IRTE support) as a prerequisite.
	 */
	if (AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir) &&
	    amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
		iommu_feature_enable(iommu, CONTROL_XT_EN);
#endif /* CONFIG_IRQ_REMAP */
}

static void iommu_enable_gt(struct amd_iommu *iommu)
{
	if (!check_feature(FEATURE_GT))
		return;

	iommu_feature_enable(iommu, CONTROL_GT_EN);

	/*
	 * This feature needs to be enabled prior to a call
	 * to iommu_snp_enable(). Since this function is called
	 * in early_enable_iommu(), it is safe to enable here.
	 */
	if (check_feature2(FEATURE_GCR3TRPMODE))
		iommu_feature_enable(iommu, CONTROL_GCR3TRPMODE);
}

/* sets a specific bit in the device table entry. */
static void set_dte_bit(struct dev_table_entry *dte, u8 bit)
{
	int i = (bit >> 6) & 0x03;
	int _bit = bit & 0x3f;

	dte->data[i] |= (1UL << _bit);
}

static bool __reuse_device_table(struct amd_iommu *iommu)
{
	struct amd_iommu_pci_seg *pci_seg = iommu->pci_seg;
	struct dev_table_entry *old_dev_tbl_entry;
	u32 lo, hi, old_devtb_size, devid;
	phys_addr_t old_devtb_phys;
	u16 dom_id;
	bool dte_v;
	u64 entry;

	/* Each IOMMU use separate device table with the same size */
	lo = readl(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET);
	hi = readl(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET + 4);
	entry = (((u64) hi) << 32) + lo;

	old_devtb_size = ((entry & ~PAGE_MASK) + 1) << 12;
	if (old_devtb_size != pci_seg->dev_table_size) {
		pr_err("The device table size of IOMMU:%d is not expected!\n",
			iommu->index);
		return false;
	}

	/*
	 * When SME is enabled in the first kernel, the entry includes the
	 * memory encryption mask(sme_me_mask), we must remove the memory
	 * encryption mask to obtain the true physical address in kdump kernel.
	 */
	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

	if (old_devtb_phys >= 0x100000000ULL) {
		pr_err("The address of old device table is above 4G, not trustworthy!\n");
		return false;
	}

	/*
	 * Re-use the previous kernel's device table for kdump.
	 */
	pci_seg->old_dev_tbl_cpy = iommu_memremap(old_devtb_phys, pci_seg->dev_table_size);
	if (pci_seg->old_dev_tbl_cpy == NULL) {
		pr_err("Failed to remap memory for reusing old device table!\n");
		return false;
	}

	for (devid = 0; devid <= pci_seg->last_bdf; devid++) {
		old_dev_tbl_entry = &pci_seg->old_dev_tbl_cpy[devid];
		dte_v = FIELD_GET(DTE_FLAG_V, old_dev_tbl_entry->data[0]);
		dom_id = FIELD_GET(DTE_DOMID_MASK, old_dev_tbl_entry->data[1]);

		if (!dte_v || !dom_id)
			continue;
		/*
		 * ID reservation can fail with -ENOSPC when there
		 * are multiple devices present in the same domain,
		 * hence check only for -ENOMEM.
		 */
		if (amd_iommu_pdom_id_reserve(dom_id, GFP_KERNEL) == -ENOMEM)
			return false;
	}

	return true;
}

static bool reuse_device_table(void)
{
	struct amd_iommu *iommu;
	struct amd_iommu_pci_seg *pci_seg;

	if (!amd_iommu_pre_enabled)
		return false;

	pr_warn("Translation is already enabled - trying to reuse translation structures\n");

	/*
	 * All IOMMUs within PCI segment shares common device table.
	 * Hence reuse device table only once per PCI segment.
	 */
	for_each_pci_segment(pci_seg) {
		for_each_iommu(iommu) {
			if (pci_seg->id != iommu->pci_seg->id)
				continue;
			if (!__reuse_device_table(iommu))
				return false;
			break;
		}
	}

	return true;
}

struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid)
{
	struct ivhd_dte_flags *e;
	unsigned int best_len = UINT_MAX;
	struct dev_table_entry *dte = NULL;

	for_each_ivhd_dte_flags(e) {
		/*
		 * Need to go through the whole list to find the smallest range,
		 * which contains the devid.
		 */
		if ((e->segid == segid) &&
		    (e->devid_first <= devid) && (devid <= e->devid_last)) {
			unsigned int len = e->devid_last - e->devid_first;

			if (len < best_len) {
				dte = &(e->dte);
				best_len = len;
			}
		}
	}
	return dte;
}

static bool search_ivhd_dte_flags(u16 segid, u16 first, u16 last)
{
	struct ivhd_dte_flags *e;

	for_each_ivhd_dte_flags(e) {
		if ((e->segid == segid) &&
		    (e->devid_first == first) &&
		    (e->devid_last == last))
			return true;
	}
	return false;
}

/*
 * This function takes the device specific flags read from the ACPI
 * table and sets up the device table entry with that information
 */
static void __init
set_dev_entry_from_acpi_range(struct amd_iommu *iommu, u16 first, u16 last,
			      u32 flags, u32 ext_flags)
{
	int i;
	struct dev_table_entry dte = {};

	/* Parse IVHD DTE setting flags and store information */
	if (flags) {
		struct ivhd_dte_flags *d;

		if (search_ivhd_dte_flags(iommu->pci_seg->id, first, last))
			return;

		d = kzalloc_obj(struct ivhd_dte_flags);
		if (!d)
			return;

		pr_debug("%s: devid range %#x:%#x\n", __func__, first, last);

		if (flags & ACPI_DEVFLAG_INITPASS)
			set_dte_bit(&dte, DEV_ENTRY_INIT_PASS);
		if (flags & ACPI_DEVFLAG_EXTINT)
			set_dte_bit(&dte, DEV_ENTRY_EINT_PASS);
		if (flags & ACPI_DEVFLAG_NMI)
			set_dte_bit(&dte, DEV_ENTRY_NMI_PASS);
		if (flags & ACPI_DEVFLAG_SYSMGT1)
			set_dte_bit(&dte, DEV_ENTRY_SYSMGT1);
		if (flags & ACPI_DEVFLAG_SYSMGT2)
			set_dte_bit(&dte, DEV_ENTRY_SYSMGT2);
		if (flags & ACPI_DEVFLAG_LINT0)
			set_dte_bit(&dte, DEV_ENTRY_LINT0_PASS);
		if (flags & ACPI_DEVFLAG_LINT1)
			set_dte_bit(&dte, DEV_ENTRY_LINT1_PASS);

		/* Apply erratum 63, which needs info in initial_dte */
		if (FIELD_GET(DTE_DATA1_SYSMGT_MASK, dte.data[1]) == 0x1)
			dte.data[0] |= DTE_FLAG_IW;

		memcpy(&d->dte, &dte, sizeof(dte));
		d->segid = iommu->pci_seg->id;
		d->devid_first = first;
		d->devid_last = last;
		list_add_tail(&d->list, &amd_ivhd_dev_flags_list);
	}

	for (i = first; i <= last; i++)  {
		if (flags) {
			struct dev_table_entry *dev_table = get_dev_table(iommu);

			memcpy(&dev_table[i], &dte, sizeof(dte));
		}
		amd_iommu_set_rlookup_table(iommu, i);
	}
}

static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
					   u16 devid, u32 flags, u32 ext_flags)
{
	set_dev_entry_from_acpi_range(iommu, devid, devid, flags, ext_flags);
}

int __init add_special_device(u8 type, u8 id, u32 *devid, bool cmd_line)
{
	struct devid_map *entry;
	struct list_head *list;

	if (type == IVHD_SPECIAL_IOAPIC)
		list = &ioapic_map;
	else if (type == IVHD_SPECIAL_HPET)
		list = &hpet_map;
	else
		return -EINVAL;

	list_for_each_entry(entry, list, list) {
		if (!(entry->id == id && entry->cmd_line))
			continue;

		pr_info("Command-line override present for %s id %d - ignoring\n",
			type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id);

		*devid = entry->devid;

		return 0;
	}

	entry = kzalloc_obj(*entry);
	if (!entry)
		return -ENOMEM;

	entry->id	= id;
	entry->devid	= *devid;
	entry->cmd_line	= cmd_line;

	list_add_tail(&entry->list, list);

	return 0;
}

static int __init add_acpi_hid_device(u8 *hid, u8 *uid, u32 *devid,
				      bool cmd_line)
{
	struct acpihid_map_entry *entry;
	struct list_head *list = &acpihid_map;

	list_for_each_entry(entry, list, list) {
		if (strcmp(entry->hid, hid) ||
		    (*uid && *entry->uid && strcmp(entry->uid, uid)) ||
		    !entry->cmd_line)
			continue;

		pr_info("Command-line override for hid:%s uid:%s\n",
			hid, uid);
		*devid = entry->devid;
		return 0;
	}

	entry = kzalloc_obj(*entry);
	if (!entry)
		return -ENOMEM;

	memcpy(entry->uid, uid, strlen(uid));
	memcpy(entry->hid, hid, strlen(hid));
	entry->devid = *devid;
	entry->cmd_line	= cmd_line;
	entry->root_devid = (entry->devid & (~0x7));

	pr_info("%s, add hid:%s, uid:%s, rdevid:%#x\n",
		entry->cmd_line ? "cmd" : "ivrs",
		entry->hid, entry->uid, entry->root_devid);

	list_add_tail(&entry->list, list);
	return 0;
}

static int __init add_early_maps(void)
{
	int i, ret;

	for (i = 0; i < early_ioapic_map_size; ++i) {
		ret = add_special_device(IVHD_SPECIAL_IOAPIC,
					 early_ioapic_map[i].id,
					 &early_ioapic_map[i].devid,
					 early_ioapic_map[i].cmd_line);
		if (ret)
			return ret;
	}

	for (i = 0; i < early_hpet_map_size; ++i) {
		ret = add_special_device(IVHD_SPECIAL_HPET,
					 early_hpet_map[i].id,
					 &early_hpet_map[i].devid,
					 early_hpet_map[i].cmd_line);
		if (ret)
			return ret;
	}

	for (i = 0; i < early_acpihid_map_size; ++i) {
		ret = add_acpi_hid_device(early_acpihid_map[i].hid,
					  early_acpihid_map[i].uid,
					  &early_acpihid_map[i].devid,
					  early_acpihid_map[i].cmd_line);
		if (ret)
			return ret;
	}

	return 0;
}

/*
 * Takes a pointer to an AMD IOMMU entry in the ACPI table and
 * initializes the hardware and our data structures with it.
 */
static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
					struct ivhd_header *h)
{
	u8 *p = (u8 *)h;
	u8 *end = p, flags = 0;
	u16 devid = 0, devid_start = 0, devid_to = 0, seg_id;
	u32 dev_i, ext_flags = 0;
	bool alias = false;
	struct ivhd_entry *e;
	struct amd_iommu_pci_seg *pci_seg = iommu->pci_seg;
	u32 ivhd_size;
	int ret;


	ret = add_early_maps();
	if (ret)
		return ret;

	amd_iommu_apply_ivrs_quirks();

	/*
	 * First save the recommended feature enable bits from ACPI
	 */
	iommu->acpi_flags = h->flags;

	/*
	 * Done. Now parse the device entries
	 */
	ivhd_size = get_ivhd_header_size(h);
	if (!ivhd_size) {
		pr_err("Unsupported IVHD type %#x\n", h->type);
		return -EINVAL;
	}

	p += ivhd_size;

	end += h->length;


	while (p < end) {
		e = (struct ivhd_entry *)p;
		seg_id = pci_seg->id;

		switch (e->type) {
		case IVHD_DEV_ALL:

			DUMP_printk("  DEV_ALL\t\t\tsetting: %#02x\n", e->flags);
			set_dev_entry_from_acpi_range(iommu, 0, pci_seg->last_bdf, e->flags, 0);
			break;
		case IVHD_DEV_SELECT:

			DUMP_printk("  DEV_SELECT\t\t\tdevid: %04x:%02x:%02x.%x flags: %#02x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags);

			devid = e->devid;
			set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
			break;
		case IVHD_DEV_SELECT_RANGE_START:

			DUMP_printk("  DEV_SELECT_RANGE_START\tdevid: %04x:%02x:%02x.%x flags: %#02x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags);

			devid_start = e->devid;
			flags = e->flags;
			ext_flags = 0;
			alias = false;
			break;
		case IVHD_DEV_ALIAS:

			DUMP_printk("  DEV_ALIAS\t\t\tdevid: %04x:%02x:%02x.%x flags: %#02x devid_to: %02x:%02x.%x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags,
				    PCI_BUS_NUM(e->ext >> 8),
				    PCI_SLOT(e->ext >> 8),
				    PCI_FUNC(e->ext >> 8));

			devid = e->devid;
			devid_to = e->ext >> 8;
			set_dev_entry_from_acpi(iommu, devid   , e->flags, 0);
			set_dev_entry_from_acpi(iommu, devid_to, e->flags, 0);
			pci_seg->alias_table[devid] = devid_to;
			break;
		case IVHD_DEV_ALIAS_RANGE:

			DUMP_printk("  DEV_ALIAS_RANGE\t\tdevid: %04x:%02x:%02x.%x flags: %#02x devid_to: %04x:%02x:%02x.%x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags,
				    seg_id, PCI_BUS_NUM(e->ext >> 8),
				    PCI_SLOT(e->ext >> 8),
				    PCI_FUNC(e->ext >> 8));

			devid_start = e->devid;
			flags = e->flags;
			devid_to = e->ext >> 8;
			ext_flags = 0;
			alias = true;
			break;
		case IVHD_DEV_EXT_SELECT:

			DUMP_printk("  DEV_EXT_SELECT\t\tdevid: %04x:%02x:%02x.%x flags: %#02x ext: %08x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags, e->ext);

			devid = e->devid;
			set_dev_entry_from_acpi(iommu, devid, e->flags,
						e->ext);
			break;
		case IVHD_DEV_EXT_SELECT_RANGE:

			DUMP_printk("  DEV_EXT_SELECT_RANGE\tdevid: %04x:%02x:%02x.%x flags: %#02x ext: %08x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid),
				    e->flags, e->ext);

			devid_start = e->devid;
			flags = e->flags;
			ext_flags = e->ext;
			alias = false;
			break;
		case IVHD_DEV_RANGE_END:

			DUMP_printk("  DEV_RANGE_END\t\tdevid: %04x:%02x:%02x.%x\n",
				    seg_id, PCI_BUS_NUM(e->devid),
				    PCI_SLOT(e->devid),
				    PCI_FUNC(e->devid));

			devid = e->devid;
			if (alias) {
				for (dev_i = devid_start; dev_i <= devid; ++dev_i)
					pci_seg->alias_table[dev_i] = devid_to;
				set_dev_entry_from_acpi(iommu, devid_to, flags, ext_flags);
			}
			set_dev_entry_from_acpi_range(iommu, devid_start, devid, flags, ext_flags);
			break;
		case IVHD_DEV_SPECIAL: {
			u8 handle, type;
			const char *var;
			u32 devid;
			int ret;

			handle = e->ext & 0xff;
			devid = PCI_SEG_DEVID_TO_SBDF(seg_id, (e->ext >> 8));
			type   = (e->ext >> 24) & 0xff;

			if (type == IVHD_SPECIAL_IOAPIC)
				var = "IOAPIC";
			else if (type == IVHD_SPECIAL_HPET)
				var = "HPET";
			else
				var = "UNKNOWN";

			DUMP_printk("  DEV_SPECIAL(%s[%d])\t\tdevid: %04x:%02x:%02x.%x, flags: %#02x\n",
				    var, (int)handle,
				    seg_id, PCI_BUS_NUM(devid),
				    PCI_SLOT(devid),
				    PCI_FUNC(devid),
				    e->flags);

			ret = add_special_device(type, handle, &devid, false);
			if (ret)
				return ret;

			/*
			 * add_special_device might update the devid in case a
			 * command-line override is present. So call
			 * set_dev_entry_from_acpi after add_special_device.
			 */
			set_dev_entry_from_acpi(iommu, devid, e->flags, 0);

			break;
		}
		case IVHD_DEV_ACPI_HID: {
			u32 devid;
			u8 hid[ACPIHID_HID_LEN];
			u8 uid[ACPIHID_UID_LEN];
			int ret;

			if (h->type != 0x40) {
				pr_err(FW_BUG "Invalid IVHD device type %#x\n",
				       e->type);
				break;
			}

			BUILD_BUG_ON(sizeof(e->ext_hid) != ACPIHID_HID_LEN - 1);
			memcpy(hid, &e->ext_hid, ACPIHID_HID_LEN - 1);
			hid[ACPIHID_HID_LEN - 1] = '\0';

			if (!(*hid)) {
				pr_err(FW_BUG "Invalid HID.\n");
				break;
			}

			uid[0] = '\0';
			switch (e->uidf) {
			case UID_NOT_PRESENT:

				if (e->uidl != 0)
					pr_warn(FW_BUG "Invalid UID length.\n");

				break;
			case UID_IS_INTEGER:

				sprintf(uid, "%d", e->uid);

				break;
			case UID_IS_CHARACTER:

				memcpy(uid, &e->uid, e->uidl);
				uid[e->uidl] = '\0';

				break;
			default:
				break;
			}

			devid = PCI_SEG_DEVID_TO_SBDF(seg_id, e->devid);
			DUMP_printk("  DEV_ACPI_HID(%s[%s])\t\tdevid: %04x:%02x:%02x.%x, flags: %#02x\n",
				    hid, uid, seg_id,
				    PCI_BUS_NUM(devid),
				    PCI_SLOT(devid),
				    PCI_FUNC(devid),
				    e->flags);

			flags = e->flags;

			ret = add_acpi_hid_device(hid, uid, &devid, false);
			if (ret)
				return ret;

			/*
			 * add_special_device might update the devid in case a
			 * command-line override is present. So call
			 * set_dev_entry_from_acpi after add_special_device.
			 */
			set_dev_entry_from_acpi(iommu, devid, e->flags, 0);

			break;
		}
		default:
			break;
		}

		p += ivhd_entry_length(p);
	}

	return 0;
}

/* Allocate PCI segment data structure */
static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id,
					  struct acpi_table_header *ivrs_base)
{
	struct amd_iommu_pci_seg *pci_seg;
	int last_bdf;

	/*
	 * First parse ACPI tables to find the largest Bus/Dev/Func we need to
	 * handle in this PCI segment. Upon this information the shared data
	 * structures for the PCI segments in the system will be allocated.
	 */
	last_bdf = find_last_devid_acpi(ivrs_base, id);
	if (last_bdf < 0)
		return NULL;

	pci_seg = kzalloc_obj(struct amd_iommu_pci_seg);
	if (pci_seg == NULL)
		return NULL;

	pci_seg->last_bdf = last_bdf;
	DUMP_printk("PCI segment : 0x%0x, last bdf : 0x%04x\n", id, last_bdf);
	pci_seg->dev_table_size =
		max(roundup_pow_of_two((last_bdf + 1) * DEV_TABLE_ENTRY_SIZE),
		    SZ_4K);

	pci_seg->id = id;
	init_llist_head(&pci_seg->dev_data_list);
	INIT_LIST_HEAD(&pci_seg->unity_map);
	list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list);

	if (alloc_dev_table(pci_seg))
		goto err_free_pci_seg;
	if (alloc_alias_table(pci_seg))
		goto err_free_dev_table;
	if (alloc_rlookup_table(pci_seg))
		goto err_free_alias_table;

	return pci_seg;

err_free_alias_table:
	free_alias_table(pci_seg);
err_free_dev_table:
	free_dev_table(pci_seg);
err_free_pci_seg:
	list_del(&pci_seg->list);
	kfree(pci_seg);
	return NULL;
}

static struct amd_iommu_pci_seg *__init get_pci_segment(u16 id,
					struct acpi_table_header *ivrs_base)
{
	struct amd_iommu_pci_seg *pci_seg;

	for_each_pci_segment(pci_seg) {
		if (pci_seg->id == id)
			return pci_seg;
	}

	return alloc_pci_segment(id, ivrs_base);
}

static void __init free_pci_segments(void)
{
	struct amd_iommu_pci_seg *pci_seg, *next;

	for_each_pci_segment_safe(pci_seg, next) {
		list_del(&pci_seg->list);
		free_irq_lookup_table(pci_seg);
		free_rlookup_table(pci_seg);
		free_alias_table(pci_seg);
		free_dev_table(pci_seg);
		kfree(pci_seg);
	}
}

static void __init free_sysfs(struct amd_iommu *iommu)
{
	if (iommu->iommu.dev) {
		iommu_device_unregister(&iommu->iommu);
		iommu_device_sysfs_remove(&iommu->iommu);
	}
}

static void __init free_iommu_one(struct amd_iommu *iommu)
{
	free_sysfs(iommu);
	free_iommu_buffers(iommu);
	amd_iommu_free_ppr_log(iommu);
	free_ga_log(iommu);
	iommu_unmap_mmio_space(iommu);
	amd_iommu_iopf_uninit(iommu);
}

static void __init free_iommu_all(void)
{
	struct amd_iommu *iommu, *next;

	for_each_iommu_safe(iommu, next) {
		list_del(&iommu->list);
		free_iommu_one(iommu);
		kfree(iommu);
	}
}

/*
 * Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations)
 * Workaround:
 *     BIOS should disable L2B micellaneous clock gating by setting
 *     L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b
 */
static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
{
	u32 value;

	if ((boot_cpu_data.x86 != 0x15) ||
	    (boot_cpu_data.x86_model < 0x10) ||
	    (boot_cpu_data.x86_model > 0x1f))
		return;

	pci_write_config_dword(iommu->dev, 0xf0, 0x90);
	pci_read_config_dword(iommu->dev, 0xf4, &value);

	if (value & BIT(2))
		return;

	/* Select NB indirect register 0x90 and enable writing */
	pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8));

	pci_write_config_dword(iommu->dev, 0xf4, value | 0x4);
	pci_info(iommu->dev, "Applying erratum 746 workaround\n");

	/* Clear the enable writing bit */
	pci_write_config_dword(iommu->dev, 0xf0, 0x90);
}

/*
 * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission)
 * Workaround:
 *     BIOS should enable ATS write permission check by setting
 *     L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b
 */
static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
{
	u32 value;

	if ((boot_cpu_data.x86 != 0x15) ||
	    (boot_cpu_data.x86_model < 0x30) ||
	    (boot_cpu_data.x86_model > 0x3f))
		return;

	/* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */
	value = iommu_read_l2(iommu, 0x47);

	if (value & BIT(0))
		return;

	/* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */
	iommu_write_l2(iommu, 0x47, value | BIT(0));

	pci_info(iommu->dev, "Applying ATS write check workaround\n");
}

/*
 * This function glues the initialization function for one IOMMU
 * together and also allocates the command buffer and programs the
 * hardware. It does NOT enable the IOMMU. This is done afterwards.
 */
static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h,
				 struct acpi_table_header *ivrs_base)
{
	struct amd_iommu_pci_seg *pci_seg;

	pci_seg = get_pci_segment(h->pci_seg, ivrs_base);
	if (pci_seg == NULL)
		return -ENOMEM;
	iommu->pci_seg = pci_seg;

	raw_spin_lock_init(&iommu->lock);
	iommu->cmd_sem_val = 0;

	/* Add IOMMU to internal data structures */
	list_add_tail(&iommu->list, &amd_iommu_list);
	iommu->index = amd_iommus_present++;

	if (unlikely(iommu->index >= MAX_IOMMUS)) {
		WARN(1, "System has more IOMMUs than supported by this driver\n");
		return -ENOSYS;
	}

	/*
	 * Copy data from ACPI table entry to the iommu struct
	 */
	iommu->devid   = h->devid;
	iommu->cap_ptr = h->cap_ptr;
	iommu->mmio_phys = h->mmio_phys;

	switch (h->type) {
	case 0x10:
		/* Check if IVHD EFR contains proper max banks/counters */
		if ((h->efr_attr != 0) &&
		    ((h->efr_attr & (0xF << 13)) != 0) &&
		    ((h->efr_attr & (0x3F << 17)) != 0))
			iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
		else
			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;

		/* GAM requires GA mode. */
		if ((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0)
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
		break;
	case 0x11:
	case 0x40:
		if (h->efr_reg & (1 << 9))
			iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
		else
			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;

		/* XT and GAM require GA mode. */
		if ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0) {
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
			break;
		}

		if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT))
			amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;

		if (h->efr_attr & BIT(IOMMU_IVHD_ATTR_HATDIS_SHIFT)) {
			pr_warn_once("Host Address Translation is not supported.\n");
			amd_iommu_hatdis = true;
		}

		early_iommu_features_init(iommu, h);

		break;
	default:
		return -EINVAL;
	}

	iommu->mmio_base = iommu_map_mmio_space(iommu->mmio_phys,
						iommu->mmio_phys_end);
	if (!iommu->mmio_base)
		return -ENOMEM;

	return init_iommu_from_acpi(iommu, h);
}

static int __init init_iommu_one_late(struct amd_iommu *iommu)
{
	int ret;

	ret = alloc_iommu_buffers(iommu);
	if (ret)
		return ret;

	iommu->int_enabled = false;

	init_translation_status(iommu);
	if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
		iommu_disable(iommu);
		clear_translation_pre_enabled(iommu);
		pr_warn("Translation was enabled for IOMMU:%d but we are not in kdump mode\n",
			iommu->index);
	}
	if (amd_iommu_pre_enabled)
		amd_iommu_pre_enabled = translation_pre_enabled(iommu);

	if (amd_iommu_irq_remap) {
		ret = amd_iommu_create_irq_domain(iommu);
		if (ret)
			return ret;
	}

	/*
	 * Make sure IOMMU is not considered to translate itself. The IVRS
	 * table tells us so, but this is a lie!
	 */
	iommu->pci_seg->rlookup_table[iommu->devid] = NULL;

	return 0;
}

/**
 * get_highest_supported_ivhd_type - Look up the appropriate IVHD type
 * @ivrs: Pointer to the IVRS header
 *
 * This function search through all IVDB of the maximum supported IVHD
 */
static u8 get_highest_supported_ivhd_type(struct acpi_table_header *ivrs)
{
	u8 *base = (u8 *)ivrs;
	struct ivhd_header *ivhd = (struct ivhd_header *)
					(base + IVRS_HEADER_LENGTH);
	u8 last_type = ivhd->type;
	u16 devid = ivhd->devid;

	while (((u8 *)ivhd - base < ivrs->length) &&
	       (ivhd->type <= ACPI_IVHD_TYPE_MAX_SUPPORTED)) {
		u8 *p = (u8 *) ivhd;

		if (ivhd->devid == devid)
			last_type = ivhd->type;
		ivhd = (struct ivhd_header *)(p + ivhd->length);
	}

	return last_type;
}

/*
 * Iterates over all IOMMU entries in the ACPI table, allocates the
 * IOMMU structure and initializes it with init_iommu_one()
 */
static int __init init_iommu_all(struct acpi_table_header *table)
{
	u8 *p = (u8 *)table, *end = (u8 *)table;
	struct ivhd_header *h;
	struct amd_iommu *iommu;
	int ret;

	end += table->length;
	p += IVRS_HEADER_LENGTH;

	/* Phase 1: Process all IVHD blocks */
	while (p < end) {
		h = (struct ivhd_header *)p;
		if (*p == amd_iommu_target_ivhd_type) {

			DUMP_printk("device: %04x:%02x:%02x.%01x cap: %04x "
				    "flags: %01x info %04x\n",
				    h->pci_seg, PCI_BUS_NUM(h->devid),
				    PCI_SLOT(h->devid), PCI_FUNC(h->devid),
				    h->cap_ptr, h->flags, h->info);
			DUMP_printk("       mmio-addr: %016llx\n",
				    h->mmio_phys);

			iommu = kzalloc_obj(struct amd_iommu);
			if (iommu == NULL)
				return -ENOMEM;

			ret = init_iommu_one(iommu, h, table);
			if (ret)
				return ret;
		}
		p += h->length;

	}
	WARN_ON(p != end);

	/* Phase 2 : Early feature support check */
	get_global_efr();

	/* Phase 3 : Enabling IOMMU features */
	for_each_iommu(iommu) {
		ret = init_iommu_one_late(iommu);
		if (ret)
			return ret;
	}

	return 0;
}

static void init_iommu_perf_ctr(struct amd_iommu *iommu)
{
	u64 val;
	struct pci_dev *pdev = iommu->dev;

	if (!check_feature(FEATURE_PC))
		return;

	amd_iommu_pc_present = true;

	pci_info(pdev, "IOMMU performance counters supported\n");

	val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET);
	iommu->max_banks = (u8) ((val >> 12) & 0x3f);
	iommu->max_counters = (u8) ((val >> 7) & 0xf);

	return;
}

static ssize_t amd_iommu_show_cap(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct amd_iommu *iommu = dev_to_amd_iommu(dev);
	return sysfs_emit(buf, "%x\n", iommu->cap);
}
static DEVICE_ATTR(cap, S_IRUGO, amd_iommu_show_cap, NULL);

static ssize_t amd_iommu_show_features(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{
	return sysfs_emit(buf, "%llx:%llx\n", amd_iommu_efr, amd_iommu_efr2);
}
static DEVICE_ATTR(features, S_IRUGO, amd_iommu_show_features, NULL);

static struct attribute *amd_iommu_attrs[] = {
	&dev_attr_cap.attr,
	&dev_attr_features.attr,
	NULL,
};

static struct attribute_group amd_iommu_group = {
	.name = "amd-iommu",
	.attrs = amd_iommu_attrs,
};

static const struct attribute_group *amd_iommu_groups[] = {
	&amd_iommu_group,
	NULL,
};

/*
 * Note: IVHD 0x11 and 0x40 also contains exact copy
 * of the IOMMU Extended Feature Register [MMIO Offset 0030h].
 * Default to EFR in IVHD since it is available sooner (i.e. before PCI init).
 */
static void __init late_iommu_features_init(struct amd_iommu *iommu)
{
	u64 features, features2;

	if (!(iommu->cap & (1 << IOMMU_CAP_EFR)))
		return;

	/* read extended feature bits */
	features = readq(iommu->mmio_base + MMIO_EXT_FEATURES);
	features2 = readq(iommu->mmio_base + MMIO_EXT_FEATURES2);

	if (!amd_iommu_efr) {
		amd_iommu_efr = features;
		amd_iommu_efr2 = features2;
		return;
	}

	/*
	 * Sanity check and warn if EFR values from
	 * IVHD and MMIO conflict.
	 */
	if (features != amd_iommu_efr ||
	    features2 != amd_iommu_efr2) {
		pr_warn(FW_WARN
			"EFR mismatch. Use IVHD EFR (%#llx : %#llx), EFR2 (%#llx : %#llx).\n",
			features, amd_iommu_efr,
			features2, amd_iommu_efr2);
	}
}

static int __init iommu_init_pci(struct amd_iommu *iommu)
{
	int cap_ptr = iommu->cap_ptr;
	int ret;

	iommu->dev = pci_get_domain_bus_and_slot(iommu->pci_seg->id,
						 PCI_BUS_NUM(iommu->devid),
						 iommu->devid & 0xff);
	if (!iommu->dev)
		return -ENODEV;

	/* ACPI _PRT won't have an IRQ for IOMMU */
	iommu->dev->irq_managed = 1;

	pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
			      &iommu->cap);

	if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
		amd_iommu_iotlb_sup = false;

	late_iommu_features_init(iommu);

	if (check_feature(FEATURE_GT)) {
		int glxval;
		u64 pasmax;

		pasmax = FIELD_GET(FEATURE_PASMAX, amd_iommu_efr);
		iommu->iommu.max_pasids = (1 << (pasmax + 1)) - 1;

		BUG_ON(iommu->iommu.max_pasids & ~PASID_MASK);

		glxval = FIELD_GET(FEATURE_GLX, amd_iommu_efr);

		if (amd_iommu_max_glx_val == -1)
			amd_iommu_max_glx_val = glxval;
		else
			amd_iommu_max_glx_val = min(amd_iommu_max_glx_val, glxval);

		iommu_enable_gt(iommu);
	}

	if (check_feature(FEATURE_PPR) && amd_iommu_alloc_ppr_log(iommu))
		return -ENOMEM;

	if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) {
		pr_info("Using strict mode due to virtualization\n");
		iommu_set_dma_strict();
		amd_iommu_np_cache = true;
	}

	init_iommu_perf_ctr(iommu);

	if (is_rd890_iommu(iommu->dev)) {
		int i, j;

		iommu->root_pdev =
			pci_get_domain_bus_and_slot(iommu->pci_seg->id,
						    iommu->dev->bus->number,
						    PCI_DEVFN(0, 0));

		/*
		 * Some rd890 systems may not be fully reconfigured by the
		 * BIOS, so it's necessary for us to store this information so
		 * it can be reprogrammed on resume
		 */
		pci_read_config_dword(iommu->dev, iommu->cap_ptr + 4,
				&iommu->stored_addr_lo);
		pci_read_config_dword(iommu->dev, iommu->cap_ptr + 8,
				&iommu->stored_addr_hi);

		/* Low bit locks writes to configuration space */
		iommu->stored_addr_lo &= ~1;

		for (i = 0; i < 6; i++)
			for (j = 0; j < 0x12; j++)
				iommu->stored_l1[i][j] = iommu_read_l1(iommu, i, j);

		for (i = 0; i < 0x83; i++)
			iommu->stored_l2[i] = iommu_read_l2(iommu, i);
	}

	amd_iommu_erratum_746_workaround(iommu);
	amd_iommu_ats_write_check_workaround(iommu);

	ret = iommu_device_sysfs_add(&iommu->iommu, &iommu->dev->dev,
			       amd_iommu_groups, "ivhd%d", iommu->index);
	if (ret)
		return ret;

	/*
	 * Allocate per IOMMU IOPF queue here so that in attach device path,
	 * PRI capable device can be added to IOPF queue
	 */
	if (amd_iommu_gt_ppr_supported()) {
		ret = amd_iommu_iopf_init(iommu);
		if (ret)
			return ret;
	}

	ret = iommu_device_register(&iommu->iommu, &amd_iommu_ops, NULL);
	if (ret || amd_iommu_pgtable == PD_MODE_NONE) {
		/*
		 * Remove sysfs if DMA translation is not supported by the
		 * IOMMU. Do not return an error to enable IRQ remapping
		 * in state_next(), DTE[V, TV] must eventually be set to 0.
		 */
		iommu_device_sysfs_remove(&iommu->iommu);
	}

	return pci_enable_device(iommu->dev);
}

static void print_iommu_info(void)
{
	int i;
	static const char * const feat_str[] = {
		"PreF", "PPR", "X2APIC", "NX", "GT", "[5]",
		"IA", "GA", "HE", "PC"
	};

	if (amd_iommu_efr) {
		pr_info("Extended features (%#llx, %#llx):", amd_iommu_efr, amd_iommu_efr2);

		for (i = 0; i < ARRAY_SIZE(feat_str); ++i) {
			if (check_feature(1ULL << i))
				pr_cont(" %s", feat_str[i]);
		}

		if (check_feature(FEATURE_GAM_VAPIC))
			pr_cont(" GA_vAPIC");

		if (check_feature(FEATURE_SNP))
			pr_cont(" SNP");

		if (check_feature2(FEATURE_SEVSNPIO_SUP))
			pr_cont(" SEV-TIO");

		pr_cont("\n");
	}

	if (irq_remapping_enabled) {
		pr_info("Interrupt remapping enabled\n");
		if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
			pr_info("X2APIC enabled\n");
	}
	if (amd_iommu_pgtable == PD_MODE_V2) {
		pr_info("V2 page table enabled (Paging mode : %d level)\n",
			amd_iommu_gpt_level);
	}
}

static int __init amd_iommu_init_pci(void)
{
	struct amd_iommu *iommu;
	struct amd_iommu_pci_seg *pci_seg;
	int ret;

	/* Init global identity domain before registering IOMMU */
	amd_iommu_init_identity_domain();

	for_each_iommu(iommu) {
		ret = iommu_init_pci(iommu);
		if (ret) {
			pr_err("IOMMU%d: Failed to initialize IOMMU Hardware (error=%d)!\n",
			       iommu->index, ret);
			goto out;
		}
		/* Need to setup range after PCI init */
		iommu_set_cwwb_range(iommu);
	}

	/*
	 * Order is important here to make sure any unity map requirements are
	 * fulfilled. The unity mappings are created and written to the device
	 * table during the iommu_init_pci() call.
	 *
	 * After that we call init_device_table_dma() to make sure any
	 * uninitialized DTE will block DMA, and in the end we flush the caches
	 * of all IOMMUs to make sure the changes to the device table are
	 * active.
	 */
	for_each_pci_segment(pci_seg)
		init_device_table_dma(pci_seg);

	for_each_iommu(iommu)
		amd_iommu_flush_all_caches(iommu);

	print_iommu_info();

out:
	return ret;
}

/****************************************************************************
 *
 * The following functions initialize the MSI interrupts for all IOMMUs
 * in the system. It's a bit challenging because there could be multiple
 * IOMMUs per PCI BDF but we can call pci_enable_msi(x) only once per
 * pci_dev.
 *
 ****************************************************************************/

static int iommu_setup_msi(struct amd_iommu *iommu)
{
	int r;

	r = pci_enable_msi(iommu->dev);
	if (r)
		return r;

	r = request_threaded_irq(iommu->dev->irq, NULL, amd_iommu_int_thread,
				 IRQF_ONESHOT, "AMD-Vi", iommu);
	if (r) {
		pci_disable_msi(iommu->dev);
		return r;
	}

	return 0;
}

union intcapxt {
	u64	capxt;
	struct {
		u64	reserved_0		:  2,
			dest_mode_logical	:  1,
			reserved_1		:  5,
			destid_0_23		: 24,
			vector			:  8,
			reserved_2		: 16,
			destid_24_31		:  8;
	};
} __attribute__ ((packed));


static struct irq_chip intcapxt_controller;

static int intcapxt_irqdomain_activate(struct irq_domain *domain,
				       struct irq_data *irqd, bool reserve)
{
	return 0;
}

static void intcapxt_irqdomain_deactivate(struct irq_domain *domain,
					  struct irq_data *irqd)
{
}


static int intcapxt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
				    unsigned int nr_irqs, void *arg)
{
	struct irq_alloc_info *info = arg;
	int i, ret;

	if (!info || info->type != X86_IRQ_ALLOC_TYPE_AMDVI)
		return -EINVAL;

	ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
	if (ret < 0)
		return ret;

	for (i = virq; i < virq + nr_irqs; i++) {
		struct irq_data *irqd = irq_domain_get_irq_data(domain, i);

		irqd->chip = &intcapxt_controller;
		irqd->hwirq = info->hwirq;
		irqd->chip_data = info->data;
		__irq_set_handler(i, handle_edge_irq, 0, "edge");
	}

	return ret;
}

static void intcapxt_irqdomain_free(struct irq_domain *domain, unsigned int virq,
				    unsigned int nr_irqs)
{
	irq_domain_free_irqs_top(domain, virq, nr_irqs);
}


static void intcapxt_unmask_irq(struct irq_data *irqd)
{
	struct amd_iommu *iommu = irqd->chip_data;
	struct irq_cfg *cfg = irqd_cfg(irqd);
	union intcapxt xt;

	xt.capxt = 0ULL;
	xt.dest_mode_logical = apic->dest_mode_logical;
	xt.vector = cfg->vector;
	xt.destid_0_23 = cfg->dest_apicid & GENMASK(23, 0);
	xt.destid_24_31 = cfg->dest_apicid >> 24;

	writeq(xt.capxt, iommu->mmio_base + irqd->hwirq);
}

static void intcapxt_mask_irq(struct irq_data *irqd)
{
	struct amd_iommu *iommu = irqd->chip_data;

	writeq(0, iommu->mmio_base + irqd->hwirq);
}


static int intcapxt_set_affinity(struct irq_data *irqd,
				 const struct cpumask *mask, bool force)
{
	struct irq_data *parent = irqd->parent_data;
	int ret;

	ret = parent->chip->irq_set_affinity(parent, mask, force);
	if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE)
		return ret;
	return 0;
}

static int intcapxt_set_wake(struct irq_data *irqd, unsigned int on)
{
	return on ? -EOPNOTSUPP : 0;
}

static struct irq_chip intcapxt_controller = {
	.name			= "IOMMU-MSI",
	.irq_unmask		= intcapxt_unmask_irq,
	.irq_mask		= intcapxt_mask_irq,
	.irq_ack		= irq_chip_ack_parent,
	.irq_retrigger		= irq_chip_retrigger_hierarchy,
	.irq_set_affinity       = intcapxt_set_affinity,
	.irq_set_wake		= intcapxt_set_wake,
	.flags			= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_MOVE_DEFERRED,
};

static const struct irq_domain_ops intcapxt_domain_ops = {
	.alloc			= intcapxt_irqdomain_alloc,
	.free			= intcapxt_irqdomain_free,
	.activate		= intcapxt_irqdomain_activate,
	.deactivate		= intcapxt_irqdomain_deactivate,
};


static struct irq_domain *iommu_irqdomain;

static struct irq_domain *iommu_get_irqdomain(void)
{
	struct fwnode_handle *fn;

	/* No need for locking here (yet) as the init is single-threaded */
	if (iommu_irqdomain)
		return iommu_irqdomain;

	fn = irq_domain_alloc_named_fwnode("AMD-Vi-MSI");
	if (!fn)
		return NULL;

	iommu_irqdomain = irq_domain_create_hierarchy(x86_vector_domain, 0, 0,
						      fn, &intcapxt_domain_ops,
						      NULL);
	if (!iommu_irqdomain)
		irq_domain_free_fwnode(fn);

	return iommu_irqdomain;
}

static int __iommu_setup_intcapxt(struct amd_iommu *iommu, const char *devname,
				  int hwirq, irq_handler_t thread_fn)
{
	struct irq_domain *domain;
	struct irq_alloc_info info;
	int irq, ret;
	int node = dev_to_node(&iommu->dev->dev);

	domain = iommu_get_irqdomain();
	if (!domain)
		return -ENXIO;

	init_irq_alloc_info(&info, NULL);
	info.type = X86_IRQ_ALLOC_TYPE_AMDVI;
	info.data = iommu;
	info.hwirq = hwirq;

	irq = irq_domain_alloc_irqs(domain, 1, node, &info);
	if (irq < 0) {
		irq_domain_remove(domain);
		return irq;
	}

	ret = request_threaded_irq(irq, NULL, thread_fn, IRQF_ONESHOT, devname,
				   iommu);
	if (ret) {
		irq_domain_free_irqs(irq, 1);
		irq_domain_remove(domain);
		return ret;
	}

	return 0;
}

static int iommu_setup_intcapxt(struct amd_iommu *iommu)
{
	int ret;

	snprintf(iommu->evt_irq_name, sizeof(iommu->evt_irq_name),
		 "AMD-Vi%d-Evt", iommu->index);
	ret = __iommu_setup_intcapxt(iommu, iommu->evt_irq_name,
				     MMIO_INTCAPXT_EVT_OFFSET,
				     amd_iommu_int_thread_evtlog);
	if (ret)
		return ret;

	snprintf(iommu->ppr_irq_name, sizeof(iommu->ppr_irq_name),
		 "AMD-Vi%d-PPR", iommu->index);
	ret = __iommu_setup_intcapxt(iommu, iommu->ppr_irq_name,
				     MMIO_INTCAPXT_PPR_OFFSET,
				     amd_iommu_int_thread_pprlog);
	if (ret)
		return ret;

#ifdef CONFIG_IRQ_REMAP
	snprintf(iommu->ga_irq_name, sizeof(iommu->ga_irq_name),
		 "AMD-Vi%d-GA", iommu->index);
	ret = __iommu_setup_intcapxt(iommu, iommu->ga_irq_name,
				     MMIO_INTCAPXT_GALOG_OFFSET,
				     amd_iommu_int_thread_galog);
#endif

	return ret;
}

static int iommu_init_irq(struct amd_iommu *iommu)
{
	int ret;

	if (iommu->int_enabled)
		goto enable_faults;

	if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
		ret = iommu_setup_intcapxt(iommu);
	else if (iommu->dev->msi_cap)
		ret = iommu_setup_msi(iommu);
	else
		ret = -ENODEV;

	if (ret)
		return ret;

	iommu->int_enabled = true;
enable_faults:

	if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
		iommu_feature_enable(iommu, CONTROL_INTCAPXT_EN);

	iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);

	return 0;
}

/****************************************************************************
 *
 * The next functions belong to the third pass of parsing the ACPI
 * table. In this last pass the memory mapping requirements are
 * gathered (like exclusion and unity mapping ranges).
 *
 ****************************************************************************/

static void __init free_unity_maps(void)
{
	struct unity_map_entry *entry, *next;
	struct amd_iommu_pci_seg *p, *pci_seg;

	for_each_pci_segment_safe(pci_seg, p) {
		list_for_each_entry_safe(entry, next, &pci_seg->unity_map, list) {
			list_del(&entry->list);
			kfree(entry);
		}
	}
}

/* called for unity map ACPI definition */
static int __init init_unity_map_range(struct ivmd_header *m,
				       struct acpi_table_header *ivrs_base)
{
	struct unity_map_entry *e = NULL;
	struct amd_iommu_pci_seg *pci_seg;
	char *s;

	pci_seg = get_pci_segment(m->pci_seg, ivrs_base);
	if (pci_seg == NULL)
		return -ENOMEM;

	e = kzalloc_obj(*e);
	if (e == NULL)
		return -ENOMEM;

	switch (m->type) {
	default:
		kfree(e);
		return 0;
	case ACPI_IVMD_TYPE:
		s = "IVMD_TYPEi\t\t\t";
		e->devid_start = e->devid_end = m->devid;
		break;
	case ACPI_IVMD_TYPE_ALL:
		s = "IVMD_TYPE_ALL\t\t";
		e->devid_start = 0;
		e->devid_end = pci_seg->last_bdf;
		break;
	case ACPI_IVMD_TYPE_RANGE:
		s = "IVMD_TYPE_RANGE\t\t";
		e->devid_start = m->devid;
		e->devid_end = m->aux;
		break;
	}
	e->address_start = PAGE_ALIGN(m->range_start);
	e->address_end = e->address_start + PAGE_ALIGN(m->range_length);
	e->prot = m->flags >> 1;

	/*
	 * Treat per-device exclusion ranges as r/w unity-mapped regions
	 * since some buggy BIOSes might lead to the overwritten exclusion
	 * range (exclusion_start and exclusion_length members). This
	 * happens when there are multiple exclusion ranges (IVMD entries)
	 * defined in ACPI table.
	 */
	if (m->flags & IVMD_FLAG_EXCL_RANGE)
		e->prot = (IVMD_FLAG_IW | IVMD_FLAG_IR) >> 1;

	DUMP_printk("%s devid_start: %04x:%02x:%02x.%x devid_end: "
		    "%04x:%02x:%02x.%x range_start: %016llx range_end: %016llx"
		    " flags: %x\n", s, m->pci_seg,
		    PCI_BUS_NUM(e->devid_start), PCI_SLOT(e->devid_start),
		    PCI_FUNC(e->devid_start), m->pci_seg,
		    PCI_BUS_NUM(e->devid_end),
		    PCI_SLOT(e->devid_end), PCI_FUNC(e->devid_end),
		    e->address_start, e->address_end, m->flags);

	list_add_tail(&e->list, &pci_seg->unity_map);

	return 0;
}

/* iterates over all memory definitions we find in the ACPI table */
static int __init init_memory_definitions(struct acpi_table_header *table)
{
	u8 *p = (u8 *)table, *end = (u8 *)table;
	struct ivmd_header *m;

	end += table->length;
	p += IVRS_HEADER_LENGTH;

	while (p < end) {
		m = (struct ivmd_header *)p;
		if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
			init_unity_map_range(m, table);

		p += m->length;
	}

	return 0;
}

/*
 * Init the device table to not allow DMA access for devices
 */
static void init_device_table_dma(struct amd_iommu_pci_seg *pci_seg)
{
	u32 devid;
	struct dev_table_entry *dev_table = pci_seg->dev_table;

	if (!dev_table || amd_iommu_pgtable == PD_MODE_NONE)
		return;

	for (devid = 0; devid <= pci_seg->last_bdf; ++devid) {
		set_dte_bit(&dev_table[devid], DEV_ENTRY_VALID);
		if (!amd_iommu_snp_en)
			set_dte_bit(&dev_table[devid], DEV_ENTRY_TRANSLATION);
	}
}

static void __init uninit_device_table_dma(struct amd_iommu_pci_seg *pci_seg)
{
	u32 devid;
	struct dev_table_entry *dev_table = pci_seg->dev_table;

	if (dev_table == NULL)
		return;

	for (devid = 0; devid <= pci_seg->last_bdf; ++devid) {
		dev_table[devid].data[0] = 0ULL;
		dev_table[devid].data[1] = 0ULL;
	}
}

static void init_device_table(void)
{
	struct amd_iommu_pci_seg *pci_seg;
	u32 devid;

	if (!amd_iommu_irq_remap)
		return;

	for_each_pci_segment(pci_seg) {
		for (devid = 0; devid <= pci_seg->last_bdf; ++devid)
			set_dte_bit(&pci_seg->dev_table[devid], DEV_ENTRY_IRQ_TBL_EN);
	}
}

static void iommu_init_flags(struct amd_iommu *iommu)
{
	iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
		iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
		iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);

	iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ?
		iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
		iommu_feature_disable(iommu, CONTROL_PASSPW_EN);

	iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
		iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
		iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);

	iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ?
		iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
		iommu_feature_disable(iommu, CONTROL_ISOC_EN);

	/*
	 * make IOMMU memory accesses cache coherent
	 */
	iommu_feature_enable(iommu, CONTROL_COHERENT_EN);

	/* Set IOTLB invalidation timeout to 1s */
	iommu_feature_set(iommu, CTRL_INV_TO_1S, CTRL_INV_TO_MASK, CONTROL_INV_TIMEOUT);

	/* Enable Enhanced Peripheral Page Request Handling */
	if (check_feature(FEATURE_EPHSUP))
		iommu_feature_enable(iommu, CONTROL_EPH_EN);
}

static void iommu_apply_resume_quirks(struct amd_iommu *iommu)
{
	int i, j;
	u32 ioc_feature_control;
	struct pci_dev *pdev = iommu->root_pdev;

	/* RD890 BIOSes may not have completely reconfigured the iommu */
	if (!is_rd890_iommu(iommu->dev) || !pdev)
		return;

	/*
	 * First, we need to ensure that the iommu is enabled. This is
	 * controlled by a register in the northbridge
	 */

	/* Select Northbridge indirect register 0x75 and enable writing */
	pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7));
	pci_read_config_dword(pdev, 0x64, &ioc_feature_control);

	/* Enable the iommu */
	if (!(ioc_feature_control & 0x1))
		pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1);

	/* Restore the iommu BAR */
	pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4,
			       iommu->stored_addr_lo);
	pci_write_config_dword(iommu->dev, iommu->cap_ptr + 8,
			       iommu->stored_addr_hi);

	/* Restore the l1 indirect regs for each of the 6 l1s */
	for (i = 0; i < 6; i++)
		for (j = 0; j < 0x12; j++)
			iommu_write_l1(iommu, i, j, iommu->stored_l1[i][j]);

	/* Restore the l2 indirect regs */
	for (i = 0; i < 0x83; i++)
		iommu_write_l2(iommu, i, iommu->stored_l2[i]);

	/* Lock PCI setup registers */
	pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4,
			       iommu->stored_addr_lo | 1);
}

static void iommu_enable_ga(struct amd_iommu *iommu)
{
#ifdef CONFIG_IRQ_REMAP
	switch (amd_iommu_guest_ir) {
	case AMD_IOMMU_GUEST_IR_VAPIC:
	case AMD_IOMMU_GUEST_IR_LEGACY_GA:
		iommu_feature_enable(iommu, CONTROL_GA_EN);
		iommu->irte_ops = &irte_128_ops;
		break;
	default:
		iommu->irte_ops = &irte_32_ops;
		break;
	}
#endif
}

static void iommu_disable_irtcachedis(struct amd_iommu *iommu)
{
	iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS);
}

static void iommu_enable_irtcachedis(struct amd_iommu *iommu)
{
	u64 ctrl;

	if (!amd_iommu_irtcachedis)
		return;

	/*
	 * Note:
	 * The support for IRTCacheDis feature is dertermined by
	 * checking if the bit is writable.
	 */
	iommu_feature_enable(iommu, CONTROL_IRTCACHEDIS);
	ctrl = readq(iommu->mmio_base +  MMIO_CONTROL_OFFSET);
	ctrl &= (1ULL << CONTROL_IRTCACHEDIS);
	if (ctrl)
		iommu->irtcachedis_enabled = true;
	pr_info("iommu%d (%#06x) : IRT cache is %s\n",
		iommu->index, iommu->devid,
		iommu->irtcachedis_enabled ? "disabled" : "enabled");
}

static void iommu_enable_2k_int(struct amd_iommu *iommu)
{
	if (!FEATURE_NUM_INT_REMAP_SUP_2K(amd_iommu_efr2))
		return;

	iommu_feature_set(iommu,
			  CONTROL_NUM_INT_REMAP_MODE_2K,
			  CONTROL_NUM_INT_REMAP_MODE_MASK,
			  CONTROL_NUM_INT_REMAP_MODE);
}

static void early_enable_iommu(struct amd_iommu *iommu)
{
	iommu_disable(iommu);
	iommu_init_flags(iommu);
	iommu_set_device_table(iommu);
	iommu_enable_command_buffer(iommu);
	iommu_set_exclusion_range(iommu);
	iommu_enable_gt(iommu);
	iommu_enable_ga(iommu);
	iommu_enable_xt(iommu);
	iommu_enable_irtcachedis(iommu);
	iommu_enable_2k_int(iommu);
	iommu_enable(iommu);
	amd_iommu_flush_all_caches(iommu);
}

/*
 * This function finally enables all IOMMUs found in the system after
 * they have been initialized.
 *
 * Or if in kdump kernel and IOMMUs are all pre-enabled, try to reuse
 * the old content of device table entries. Not this case or reuse failed,
 * just continue as normal kernel does.
 */
static void early_enable_iommus(void)
{
	struct amd_iommu *iommu;
	struct amd_iommu_pci_seg *pci_seg;

	if (!reuse_device_table()) {
		/*
		 * If come here because of failure in reusing device table from old
		 * kernel with all IOMMUs enabled, print error message and try to
		 * free allocated old_dev_tbl_cpy.
		 */
		if (amd_iommu_pre_enabled) {
			pr_err("Failed to reuse DEV table from previous kernel.\n");
			/*
			 * Bail out early if unable to remap/reuse DEV table from
			 * previous kernel if SNP enabled as IOMMU commands will
			 * time out without DEV table and cause kdump boot panic.
			 */
			BUG_ON(check_feature(FEATURE_SNP));
		}

		for_each_pci_segment(pci_seg) {
			if (pci_seg->old_dev_tbl_cpy != NULL) {
				memunmap((void *)pci_seg->old_dev_tbl_cpy);
				pci_seg->old_dev_tbl_cpy = NULL;
			}
		}

		for_each_iommu(iommu) {
			clear_translation_pre_enabled(iommu);
			early_enable_iommu(iommu);
		}
	} else {
		pr_info("Reused DEV table from previous kernel.\n");

		for_each_pci_segment(pci_seg) {
			iommu_free_pages(pci_seg->dev_table);
			pci_seg->dev_table = pci_seg->old_dev_tbl_cpy;
		}

		for_each_iommu(iommu) {
			iommu_disable_command_buffer(iommu);
			iommu_disable_event_buffer(iommu);
			iommu_disable_irtcachedis(iommu);
			iommu_enable_command_buffer(iommu);
			iommu_enable_ga(iommu);
			iommu_enable_xt(iommu);
			iommu_enable_irtcachedis(iommu);
			iommu_enable_2k_int(iommu);
			iommu_set_device_table(iommu);
			amd_iommu_flush_all_caches(iommu);
		}
	}
}

static void enable_iommus_ppr(void)
{
	struct amd_iommu *iommu;

	if (!amd_iommu_gt_ppr_supported())
		return;

	for_each_iommu(iommu)
		amd_iommu_enable_ppr_log(iommu);
}

static void enable_iommus_vapic(void)
{
#ifdef CONFIG_IRQ_REMAP
	u32 status, i;
	struct amd_iommu *iommu;

	for_each_iommu(iommu) {
		/*
		 * Disable GALog if already running. It could have been enabled
		 * in the previous boot before kdump.
		 */
		status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
		if (!(status & MMIO_STATUS_GALOG_RUN_MASK))
			continue;

		iommu_feature_disable(iommu, CONTROL_GALOG_EN);
		iommu_feature_disable(iommu, CONTROL_GAINT_EN);

		/*
		 * Need to set and poll check the GALOGRun bit to zero before
		 * we can set/ modify GA Log registers safely.
		 */
		for (i = 0; i < MMIO_STATUS_TIMEOUT; ++i) {
			status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
			if (!(status & MMIO_STATUS_GALOG_RUN_MASK))
				break;
			udelay(10);
		}

		if (WARN_ON(i >= MMIO_STATUS_TIMEOUT))
			return;
	}

	if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) &&
	    !check_feature(FEATURE_GAM_VAPIC)) {
		amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
		return;
	}

	if (amd_iommu_snp_en &&
	    !FEATURE_SNPAVICSUP_GAM(amd_iommu_efr2)) {
		pr_warn("Force to disable Virtual APIC due to SNP\n");
		amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
		return;
	}

	/* Enabling GAM and SNPAVIC support */
	for_each_iommu(iommu) {
		if (iommu_init_ga_log(iommu) ||
		    iommu_ga_log_enable(iommu))
			return;

		iommu_feature_enable(iommu, CONTROL_GAM_EN);
		if (amd_iommu_snp_en)
			iommu_feature_enable(iommu, CONTROL_SNPAVIC_EN);
	}

	amd_iommu_irq_ops.capability |= (1 << IRQ_POSTING_CAP);
	pr_info("Virtual APIC enabled\n");
#endif
}

static void disable_iommus(void)
{
	struct amd_iommu *iommu;

	for_each_iommu(iommu)
		iommu_disable(iommu);

#ifdef CONFIG_IRQ_REMAP
	if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
		amd_iommu_irq_ops.capability &= ~(1 << IRQ_POSTING_CAP);
#endif
}

/*
 * Suspend/Resume support
 * disable suspend until real resume implemented
 */

static void amd_iommu_resume(void *data)
{
	struct amd_iommu *iommu;

	for_each_iommu(iommu)
		iommu_apply_resume_quirks(iommu);

	/* re-load the hardware */
	for_each_iommu(iommu)
		early_enable_iommu(iommu);

	iommu_enable_event_buffer();
	amd_iommu_enable_interrupts();
}

static int amd_iommu_suspend(void *data)
{
	/* disable IOMMUs to go out of the way for BIOS */
	disable_iommus();

	return 0;
}

static const struct syscore_ops amd_iommu_syscore_ops = {
	.suspend = amd_iommu_suspend,
	.resume = amd_iommu_resume,
};

static struct syscore amd_iommu_syscore = {
	.ops = &amd_iommu_syscore_ops,
};

static void __init free_iommu_resources(void)
{
	free_iommu_all();
	free_pci_segments();
}

/* SB IOAPIC is always on this device in AMD systems */
#define IOAPIC_SB_DEVID		((0x00 << 8) | PCI_DEVFN(0x14, 0))

static bool __init check_ioapic_information(void)
{
	const char *fw_bug = FW_BUG;
	bool ret, has_sb_ioapic;
	int idx;

	has_sb_ioapic = false;
	ret           = false;

	/*
	 * If we have map overrides on the kernel command line the
	 * messages in this function might not describe firmware bugs
	 * anymore - so be careful
	 */
	if (cmdline_maps)
		fw_bug = "";

	for (idx = 0; idx < nr_ioapics; idx++) {
		int devid, id = mpc_ioapic_id(idx);

		devid = get_ioapic_devid(id);
		if (devid < 0) {
			pr_err("%s: IOAPIC[%d] not in IVRS table\n",
				fw_bug, id);
			ret = false;
		} else if (devid == IOAPIC_SB_DEVID) {
			has_sb_ioapic = true;
			ret           = true;
		}
	}

	if (!has_sb_ioapic) {
		/*
		 * We expect the SB IOAPIC to be listed in the IVRS
		 * table. The system timer is connected to the SB IOAPIC
		 * and if we don't have it in the list the system will
		 * panic at boot time.  This situation usually happens
		 * when the BIOS is buggy and provides us the wrong
		 * device id for the IOAPIC in the system.
		 */
		pr_err("%s: No southbridge IOAPIC found\n", fw_bug);
	}

	if (!ret)
		pr_err("Disabling interrupt remapping\n");

	return ret;
}

static void __init free_dma_resources(void)
{
	amd_iommu_pdom_id_destroy();
	free_unity_maps();
}

static void __init ivinfo_init(void *ivrs)
{
	amd_iommu_ivinfo = *((u32 *)(ivrs + IOMMU_IVINFO_OFFSET));
}

/*
 * This is the hardware init function for AMD IOMMU in the system.
 * This function is called either from amd_iommu_init or from the interrupt
 * remapping setup code.
 *
 * This function basically parses the ACPI table for AMD IOMMU (IVRS)
 * four times:
 *
 *	1 pass) Discover the most comprehensive IVHD type to use.
 *
 *	2 pass) Find the highest PCI device id the driver has to handle.
 *		Upon this information the size of the data structures is
 *		determined that needs to be allocated.
 *
 *	3 pass) Initialize the data structures just allocated with the
 *		information in the ACPI table about available AMD IOMMUs
 *		in the system. It also maps the PCI devices in the
 *		system to specific IOMMUs
 *
 *	4 pass) After the basic data structures are allocated and
 *		initialized we update them with information about memory
 *		remapping requirements parsed out of the ACPI table in
 *		this last pass.
 *
 * After everything is set up the IOMMUs are enabled and the necessary
 * hotplug and suspend notifiers are registered.
 */
static int __init early_amd_iommu_init(void)
{
	struct acpi_table_header *ivrs_base;
	int ret;
	acpi_status status;
	u8 efr_hats;

	if (!amd_iommu_detected)
		return -ENODEV;

	status = acpi_get_table("IVRS", 0, &ivrs_base);
	if (status == AE_NOT_FOUND)
		return -ENODEV;
	else if (ACPI_FAILURE(status)) {
		const char *err = acpi_format_exception(status);
		pr_err("IVRS table error: %s\n", err);
		return -EINVAL;
	}

	if (!boot_cpu_has(X86_FEATURE_CX16)) {
		pr_err("Failed to initialize. The CMPXCHG16B feature is required.\n");
		ret = -EINVAL;
		goto out;
	}

	/*
	 * Validate checksum here so we don't need to do it when
	 * we actually parse the table
	 */
	ret = check_ivrs_checksum(ivrs_base);
	if (ret)
		goto out;

	ivinfo_init(ivrs_base);

	amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
	DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);

	/*
	 * now the data structures are allocated and basically initialized
	 * start the real acpi table scan
	 */
	ret = init_iommu_all(ivrs_base);
	if (ret)
		goto out;

	/* 5 level guest page table */
	if (cpu_feature_enabled(X86_FEATURE_LA57) &&
	    FIELD_GET(FEATURE_GATS, amd_iommu_efr) == GUEST_PGTABLE_5_LEVEL)
		amd_iommu_gpt_level = PAGE_MODE_5_LEVEL;

	efr_hats = FIELD_GET(FEATURE_HATS, amd_iommu_efr);
	if (efr_hats != 0x3) {
		/*
		 * efr[HATS] bits specify the maximum host translation level
		 * supported, with LEVEL 4 being initial max level.
		 */
		amd_iommu_hpt_level = efr_hats + PAGE_MODE_4_LEVEL;
	} else {
		pr_warn_once(FW_BUG "Disable host address translation due to invalid translation level (%#x).\n",
			     efr_hats);
		amd_iommu_hatdis = true;
	}

	if (amd_iommu_pgtable == PD_MODE_V2) {
		if (!amd_iommu_v2_pgtbl_supported()) {
			pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
			amd_iommu_pgtable = PD_MODE_V1;
		}
	}

	if (amd_iommu_hatdis) {
		/*
		 * Host (v1) page table is not available. Attempt to use
		 * Guest (v2) page table.
		 */
		if (amd_iommu_v2_pgtbl_supported())
			amd_iommu_pgtable = PD_MODE_V2;
		else
			amd_iommu_pgtable = PD_MODE_NONE;
	}

	/* Disable any previously enabled IOMMUs */
	if (!is_kdump_kernel() || amd_iommu_disabled)
		disable_iommus();

	if (amd_iommu_irq_remap)
		amd_iommu_irq_remap = check_ioapic_information();

	if (amd_iommu_irq_remap) {
		struct amd_iommu_pci_seg *pci_seg;
		ret = -ENOMEM;
		for_each_pci_segment(pci_seg) {
			if (alloc_irq_lookup_table(pci_seg))
				goto out;
		}
	}

	ret = init_memory_definitions(ivrs_base);
	if (ret)
		goto out;

	/* init the device table */
	init_device_table();

out:
	/* Don't leak any ACPI memory */
	acpi_put_table(ivrs_base);

	return ret;
}

static int amd_iommu_enable_interrupts(void)
{
	struct amd_iommu *iommu;
	int ret = 0;

	for_each_iommu(iommu) {
		ret = iommu_init_irq(iommu);
		if (ret)
			goto out;
	}

	/*
	 * Interrupt handler is ready to process interrupts. Enable
	 * PPR and GA log interrupt for all IOMMUs.
	 */
	enable_iommus_vapic();
	enable_iommus_ppr();

out:
	return ret;
}

static bool __init detect_ivrs(void)
{
	struct acpi_table_header *ivrs_base;
	acpi_status status;
	int i;

	status = acpi_get_table("IVRS", 0, &ivrs_base);
	if (status == AE_NOT_FOUND)
		return false;
	else if (ACPI_FAILURE(status)) {
		const char *err = acpi_format_exception(status);
		pr_err("IVRS table error: %s\n", err);
		return false;
	}

	acpi_put_table(ivrs_base);

	if (amd_iommu_force_enable)
		goto out;

	/* Don't use IOMMU if there is Stoney Ridge graphics */
	for (i = 0; i < 32; i++) {
		u32 pci_id;

		pci_id = read_pci_config(0, i, 0, 0);
		if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) {
			pr_info("Disable IOMMU on Stoney Ridge\n");
			return false;
		}
	}

out:
	/* Make sure ACS will be enabled during PCI probe */
	pci_request_acs();

	return true;
}

static __init void iommu_snp_enable(void)
{
#ifdef CONFIG_KVM_AMD_SEV
	if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
		return;
	/*
	 * The SNP support requires that IOMMU must be enabled, and is
	 * configured with V1 page table (DTE[Mode] = 0 is not supported).
	 */
	if (no_iommu || iommu_default_passthrough()) {
		pr_warn("SNP: IOMMU disabled or configured in passthrough mode, SNP cannot be supported.\n");
		goto disable_snp;
	}

	if (amd_iommu_pgtable != PD_MODE_V1) {
		pr_warn("SNP: IOMMU is configured with V2 page table mode, SNP cannot be supported.\n");
		goto disable_snp;
	}

	amd_iommu_snp_en = check_feature(FEATURE_SNP);
	if (!amd_iommu_snp_en) {
		pr_warn("SNP: IOMMU SNP feature not enabled, SNP cannot be supported.\n");
		goto disable_snp;
	}

	/*
	 * Enable host SNP support once SNP support is checked on IOMMU.
	 */
	if (snp_rmptable_init()) {
		pr_warn("SNP: RMP initialization failed, SNP cannot be supported.\n");
		goto disable_snp;
	}

	pr_info("IOMMU SNP support enabled.\n");
	return;

disable_snp:
	cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
#endif
}

static void amd_iommu_apply_erratum_snp(void)
{
#ifdef CONFIG_KVM_AMD_SEV
	if (!amd_iommu_snp_en)
		return;

	/* Errata fix for Family 0x19 */
	if (boot_cpu_data.x86 != 0x19)
		return;

	/* Set event log buffer size to max */
	amd_iommu_evtlog_size = EVTLOG_SIZE_MAX;
	pr_info("Applying erratum: Increase Event log size to 0x%x\n",
		amd_iommu_evtlog_size);

	/*
	 * Set PPR log buffer size to max.
	 * (Family 0x19, model < 0x10 doesn't support PPR when SNP is enabled).
	 */
	if (boot_cpu_data.x86_model >= 0x10) {
		amd_iommu_pprlog_size = PPRLOG_SIZE_MAX;
		pr_info("Applying erratum: Increase PPR log size to 0x%x\n",
			amd_iommu_pprlog_size);
	}
#endif
}

/****************************************************************************
 *
 * AMD IOMMU Initialization State Machine
 *
 ****************************************************************************/

static int __init state_next(void)
{
	int ret = 0;

	switch (init_state) {
	case IOMMU_START_STATE:
		if (!detect_ivrs()) {
			init_state	= IOMMU_NOT_FOUND;
			ret		= -ENODEV;
		} else {
			init_state	= IOMMU_IVRS_DETECTED;
		}
		break;
	case IOMMU_IVRS_DETECTED:
		if (amd_iommu_disabled) {
			init_state = IOMMU_CMDLINE_DISABLED;
			ret = -EINVAL;
		} else {
			ret = early_amd_iommu_init();
			init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED;
		}
		break;
	case IOMMU_ACPI_FINISHED:
		early_enable_iommus();
		x86_platform.iommu_shutdown = disable_iommus;
		init_state = IOMMU_ENABLED;
		break;
	case IOMMU_ENABLED:
		register_syscore(&amd_iommu_syscore);
		iommu_snp_enable();

		amd_iommu_apply_erratum_snp();

		/* Allocate/enable event log buffer */
		if (is_kdump_kernel())
			ret = remap_event_buffer();
		else
			ret = alloc_event_buffer();

		if (ret) {
			init_state = IOMMU_INIT_ERROR;
			break;
		}
		iommu_enable_event_buffer();

		ret = amd_iommu_init_pci();
		init_state = ret ? IOMMU_INIT_ERROR : IOMMU_PCI_INIT;
		break;
	case IOMMU_PCI_INIT:
		ret = amd_iommu_enable_interrupts();
		init_state = ret ? IOMMU_INIT_ERROR : IOMMU_INTERRUPTS_EN;
		break;
	case IOMMU_INTERRUPTS_EN:
		init_state = IOMMU_INITIALIZED;
		break;
	case IOMMU_INITIALIZED:
		/* Nothing to do */
		break;
	case IOMMU_NOT_FOUND:
	case IOMMU_INIT_ERROR:
	case IOMMU_CMDLINE_DISABLED:
		/* Error states => do nothing */
		ret = -EINVAL;
		break;
	default:
		/* Unknown state */
		BUG();
	}

	if (ret) {
		free_dma_resources();
		if (!irq_remapping_enabled) {
			disable_iommus();
			free_iommu_resources();
		} else {
			struct amd_iommu *iommu;
			struct amd_iommu_pci_seg *pci_seg;

			for_each_pci_segment(pci_seg)
				uninit_device_table_dma(pci_seg);

			for_each_iommu(iommu)
				amd_iommu_flush_all_caches(iommu);
		}
	}
	return ret;
}

static int __init iommu_go_to_state(enum iommu_init_state state)
{
	int ret = -EINVAL;

	while (init_state != state) {
		if (init_state == IOMMU_NOT_FOUND         ||
		    init_state == IOMMU_INIT_ERROR        ||
		    init_state == IOMMU_CMDLINE_DISABLED)
			break;
		ret = state_next();
	}

	/*
	 * SNP platform initilazation requires IOMMUs to be fully configured.
	 * If the SNP support on IOMMUs has NOT been checked, simply mark SNP
	 * as unsupported. If the SNP support on IOMMUs has been checked and
	 * host SNP support enabled but RMP enforcement has not been enabled
	 * in IOMMUs, then the system is in a half-baked state, but can limp
	 * along as all memory should be Hypervisor-Owned in the RMP. WARN,
	 * but leave SNP as "supported" to avoid confusing the kernel.
	 */
	if (ret && cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
	    !WARN_ON_ONCE(amd_iommu_snp_en))
		cc_platform_clear(CC_ATTR_HOST_SEV_SNP);

	return ret;
}

#ifdef CONFIG_IRQ_REMAP
int __init amd_iommu_prepare(void)
{
	int ret;

	amd_iommu_irq_remap = true;

	ret = iommu_go_to_state(IOMMU_ACPI_FINISHED);
	if (ret) {
		amd_iommu_irq_remap = false;
		return ret;
	}

	return amd_iommu_irq_remap ? 0 : -ENODEV;
}

int __init amd_iommu_enable(void)
{
	int ret;

	ret = iommu_go_to_state(IOMMU_ENABLED);
	if (ret)
		return ret;

	irq_remapping_enabled = 1;
	return amd_iommu_xt_mode;
}

void amd_iommu_disable(void)
{
	amd_iommu_suspend(NULL);
}

int amd_iommu_reenable(int mode)
{
	amd_iommu_resume(NULL);

	return 0;
}

int amd_iommu_enable_faulting(unsigned int cpu)
{
	/* We enable MSI later when PCI is initialized */
	return 0;
}
#endif

/*
 * This is the core init function for AMD IOMMU hardware in the system.
 * This function is called from the generic x86 DMA layer initialization
 * code.
 */
static int __init amd_iommu_init(void)
{
	int ret;

	ret = iommu_go_to_state(IOMMU_INITIALIZED);
#ifdef CONFIG_GART_IOMMU
	if (ret && list_empty(&amd_iommu_list)) {
		/*
		 * We failed to initialize the AMD IOMMU - try fallback
		 * to GART if possible.
		 */
		gart_iommu_init();
	}
#endif

	if (!ret)
		amd_iommu_debugfs_setup();

	return ret;
}

static bool amd_iommu_sme_check(void)
{
	if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT) ||
	    (boot_cpu_data.x86 != 0x17))
		return true;

	/* For Fam17h, a specific level of support is required */
	if (boot_cpu_data.microcode >= 0x08001205)
		return true;

	if ((boot_cpu_data.microcode >= 0x08001126) &&
	    (boot_cpu_data.microcode <= 0x080011ff))
		return true;

	pr_notice("IOMMU not currently supported when SME is active\n");

	return false;
}

/****************************************************************************
 *
 * Early detect code. This code runs at IOMMU detection time in the DMA
 * layer. It just looks if there is an IVRS ACPI table to detect AMD
 * IOMMUs
 *
 ****************************************************************************/
void __init amd_iommu_detect(void)
{
	int ret;

	if (no_iommu || (iommu_detected && !gart_iommu_aperture))
		goto disable_snp;

	if (!amd_iommu_sme_check())
		goto disable_snp;

	ret = iommu_go_to_state(IOMMU_IVRS_DETECTED);
	if (ret)
		goto disable_snp;

	amd_iommu_detected = true;
	iommu_detected = 1;
	x86_init.iommu.iommu_init = amd_iommu_init;
	return;

disable_snp:
	if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
		cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
}

/****************************************************************************
 *
 * Parsing functions for the AMD IOMMU specific kernel command line
 * options.
 *
 ****************************************************************************/

static int __init parse_amd_iommu_dump(char *str)
{
	amd_iommu_dump = true;

	return 1;
}

static int __init parse_amd_iommu_intr(char *str)
{
	for (; *str; ++str) {
		if (strncmp(str, "legacy", 6) == 0) {
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
			break;
		}
		if (strncmp(str, "vapic", 5) == 0) {
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
			break;
		}
	}
	return 1;
}

static int __init parse_amd_iommu_options(char *str)
{
	if (!str)
		return -EINVAL;

	while (*str) {
		if (strncmp(str, "fullflush", 9) == 0) {
			pr_warn("amd_iommu=fullflush deprecated; use iommu.strict=1 instead\n");
			iommu_set_dma_strict();
		} else if (strncmp(str, "force_enable", 12) == 0) {
			amd_iommu_force_enable = true;
		} else if (strncmp(str, "off", 3) == 0) {
			amd_iommu_disabled = true;
		} else if (strncmp(str, "force_isolation", 15) == 0) {
			amd_iommu_force_isolation = true;
		} else if (strncmp(str, "pgtbl_v1", 8) == 0) {
			amd_iommu_pgtable = PD_MODE_V1;
		} else if (strncmp(str, "pgtbl_v2", 8) == 0) {
			amd_iommu_pgtable = PD_MODE_V2;
		} else if (strncmp(str, "irtcachedis", 11) == 0) {
			amd_iommu_irtcachedis = true;
		} else if (strncmp(str, "nohugepages", 11) == 0) {
			pr_info("Restricting V1 page-sizes to 4KiB");
			amd_iommu_pgsize_bitmap = AMD_IOMMU_PGSIZES_4K;
		} else if (strncmp(str, "v2_pgsizes_only", 15) == 0) {
			pr_info("Restricting V1 page-sizes to 4KiB/2MiB/1GiB");
			amd_iommu_pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
		} else {
			pr_notice("Unknown option - '%s'\n", str);
		}

		str += strcspn(str, ",");
		while (*str == ',')
			str++;
	}

	return 1;
}

static int __init parse_ivrs_ioapic(char *str)
{
	u32 seg = 0, bus, dev, fn;
	int id, i;
	u32 devid;

	if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
	    sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
		goto found;

	if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
	    sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
		pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n",
			str, id, seg, bus, dev, fn);
		goto found;
	}

	pr_err("Invalid command line: ivrs_ioapic%s\n", str);
	return 1;

found:
	if (early_ioapic_map_size == EARLY_MAP_SIZE) {
		pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
			str);
		return 1;
	}

	devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);

	cmdline_maps			= true;
	i				= early_ioapic_map_size++;
	early_ioapic_map[i].id		= id;
	early_ioapic_map[i].devid	= devid;
	early_ioapic_map[i].cmd_line	= true;

	return 1;
}

static int __init parse_ivrs_hpet(char *str)
{
	u32 seg = 0, bus, dev, fn;
	int id, i;
	u32 devid;

	if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
	    sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
		goto found;

	if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
	    sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
		pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n",
			str, id, seg, bus, dev, fn);
		goto found;
	}

	pr_err("Invalid command line: ivrs_hpet%s\n", str);
	return 1;

found:
	if (early_hpet_map_size == EARLY_MAP_SIZE) {
		pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n",
			str);
		return 1;
	}

	devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);

	cmdline_maps			= true;
	i				= early_hpet_map_size++;
	early_hpet_map[i].id		= id;
	early_hpet_map[i].devid		= devid;
	early_hpet_map[i].cmd_line	= true;

	return 1;
}

#define ACPIID_LEN (ACPIHID_UID_LEN + ACPIHID_HID_LEN)

static int __init parse_ivrs_acpihid(char *str)
{
	u32 seg = 0, bus, dev, fn;
	char *hid, *uid, *p, *addr;
	char acpiid[ACPIID_LEN + 1] = { }; /* size with NULL terminator */
	int i;

	addr = strchr(str, '@');
	if (!addr) {
		addr = strchr(str, '=');
		if (!addr)
			goto not_found;

		++addr;

		if (strlen(addr) > ACPIID_LEN)
			goto not_found;

		if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
		    sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
			pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
				str, acpiid, seg, bus, dev, fn);
			goto found;
		}
		goto not_found;
	}

	/* We have the '@', make it the terminator to get just the acpiid */
	*addr++ = 0;

	if (strlen(str) > ACPIID_LEN)
		goto not_found;

	if (sscanf(str, "=%s", acpiid) != 1)
		goto not_found;

	if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 ||
	    sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4)
		goto found;

not_found:
	pr_err("Invalid command line: ivrs_acpihid%s\n", str);
	return 1;

found:
	p = acpiid;
	hid = strsep(&p, ":");
	uid = p;

	if (!hid || !(*hid) || !uid) {
		pr_err("Invalid command line: hid or uid\n");
		return 1;
	}

	/*
	 * Ignore leading zeroes after ':', so e.g., AMDI0095:00
	 * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match
	 */
	while (*uid == '0' && *(uid + 1))
		uid++;

	if (strlen(hid) >= ACPIHID_HID_LEN) {
		pr_err("Invalid command line: hid is too long\n");
		return 1;
	} else if (strlen(uid) >= ACPIHID_UID_LEN) {
		pr_err("Invalid command line: uid is too long\n");
		return 1;
	}

	i = early_acpihid_map_size++;
	memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
	memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
	early_acpihid_map[i].devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
	early_acpihid_map[i].cmd_line	= true;

	return 1;
}

__setup("amd_iommu_dump",	parse_amd_iommu_dump);
__setup("amd_iommu=",		parse_amd_iommu_options);
__setup("amd_iommu_intr=",	parse_amd_iommu_intr);
__setup("ivrs_ioapic",		parse_ivrs_ioapic);
__setup("ivrs_hpet",		parse_ivrs_hpet);
__setup("ivrs_acpihid",		parse_ivrs_acpihid);

bool amd_iommu_pasid_supported(void)
{
	/* CPU page table size should match IOMMU guest page table size */
	if (cpu_feature_enabled(X86_FEATURE_LA57) &&
	    amd_iommu_gpt_level != PAGE_MODE_5_LEVEL)
		return false;

	/*
	 * Since DTE[Mode]=0 is prohibited on SNP-enabled system
	 * (i.e. EFR[SNPSup]=1), IOMMUv2 page table cannot be used without
	 * setting up IOMMUv1 page table.
	 */
	return amd_iommu_gt_ppr_supported() && !amd_iommu_snp_en;
}

struct amd_iommu *get_amd_iommu(unsigned int idx)
{
	unsigned int i = 0;
	struct amd_iommu *iommu;

	for_each_iommu(iommu)
		if (i++ == idx)
			return iommu;
	return NULL;
}

/****************************************************************************
 *
 * IOMMU EFR Performance Counter support functionality. This code allows
 * access to the IOMMU PC functionality.
 *
 ****************************************************************************/

u8 amd_iommu_pc_get_max_banks(unsigned int idx)
{
	struct amd_iommu *iommu = get_amd_iommu(idx);

	if (iommu)
		return iommu->max_banks;

	return 0;
}

bool amd_iommu_pc_supported(void)
{
	return amd_iommu_pc_present;
}

u8 amd_iommu_pc_get_max_counters(unsigned int idx)
{
	struct amd_iommu *iommu = get_amd_iommu(idx);

	if (iommu)
		return iommu->max_counters;

	return 0;
}

static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
				u8 fxn, u64 *value, bool is_write)
{
	u32 offset;
	u32 max_offset_lim;

	/* Make sure the IOMMU PC resource is available */
	if (!amd_iommu_pc_present)
		return -ENODEV;

	/* Check for valid iommu and pc register indexing */
	if (WARN_ON(!iommu || (fxn > 0x28) || (fxn & 7)))
		return -ENODEV;

	offset = (u32)(((0x40 | bank) << 12) | (cntr << 8) | fxn);

	/* Limit the offset to the hw defined mmio region aperture */
	max_offset_lim = (u32)(((0x40 | iommu->max_banks) << 12) |
				(iommu->max_counters << 8) | 0x28);
	if ((offset < MMIO_CNTR_REG_OFFSET) ||
	    (offset > max_offset_lim))
		return -EINVAL;

	if (is_write) {
		u64 val = *value & GENMASK_ULL(47, 0);

		writel((u32)val, iommu->mmio_base + offset);
		writel((val >> 32), iommu->mmio_base + offset + 4);
	} else {
		*value = readl(iommu->mmio_base + offset + 4);
		*value <<= 32;
		*value |= readl(iommu->mmio_base + offset);
		*value &= GENMASK_ULL(47, 0);
	}

	return 0;
}

int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn, u64 *value)
{
	if (!iommu)
		return -EINVAL;

	return iommu_pc_get_set_reg(iommu, bank, cntr, fxn, value, false);
}

int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn, u64 *value)
{
	if (!iommu)
		return -EINVAL;

	return iommu_pc_get_set_reg(iommu, bank, cntr, fxn, value, true);
}

#ifdef CONFIG_KVM_AMD_SEV
static int iommu_page_make_shared(void *page)
{
	unsigned long paddr, pfn;

	paddr = iommu_virt_to_phys(page);
	/* Cbit maybe set in the paddr */
	pfn = __sme_clr(paddr) >> PAGE_SHIFT;

	if (!(pfn % PTRS_PER_PMD)) {
		int ret, level;
		bool assigned;

		ret = snp_lookup_rmpentry(pfn, &assigned, &level);
		if (ret) {
			pr_warn("IOMMU PFN %lx RMP lookup failed, ret %d\n", pfn, ret);
			return ret;
		}

		if (!assigned) {
			pr_warn("IOMMU PFN %lx not assigned in RMP table\n", pfn);
			return -EINVAL;
		}

		if (level > PG_LEVEL_4K) {
			ret = psmash(pfn);
			if (!ret)
				goto done;

			pr_warn("PSMASH failed for IOMMU PFN %lx huge RMP entry, ret: %d, level: %d\n",
				pfn, ret, level);
			return ret;
		}
	}

done:
	return rmp_make_shared(pfn, PG_LEVEL_4K);
}

static int iommu_make_shared(void *va, size_t size)
{
	void *page;
	int ret;

	if (!va)
		return 0;

	for (page = va; page < (va + size); page += PAGE_SIZE) {
		ret = iommu_page_make_shared(page);
		if (ret)
			return ret;
	}

	return 0;
}

int amd_iommu_snp_disable(void)
{
	struct amd_iommu *iommu;
	int ret;

	if (!amd_iommu_snp_en)
		return 0;

	for_each_iommu(iommu) {
		ret = iommu_make_shared(iommu->evt_buf, amd_iommu_evtlog_size);
		if (ret)
			return ret;

		ret = iommu_make_shared(iommu->ppr_log, amd_iommu_pprlog_size);
		if (ret)
			return ret;

		ret = iommu_make_shared((void *)iommu->cmd_sem, PAGE_SIZE);
		if (ret)
			return ret;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(amd_iommu_snp_disable);

bool amd_iommu_sev_tio_supported(void)
{
	return check_feature2(FEATURE_SEVSNPIO_SUP);
}
EXPORT_SYMBOL_GPL(amd_iommu_sev_tio_supported);
#endif
