/*
 * Copyright (C) 2013 Advanced Micro Devices, Inc.
 *
 * Author: Steven Kinney <Steven.Kinney@amd.com>
 * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
 *
 * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#define pr_fmt(fmt)	"perf/amd_iommu: " fmt

#include <linux/perf_event.h>
#include <linux/init.h>
#include <linux/cpumask.h>
#include <linux/slab.h>

#include "../perf_event.h"
#include "iommu.h"

#define COUNTER_SHIFT		16

/* iommu pmu conf masks */
#define GET_CSOURCE(x)     ((x)->conf & 0xFFULL)
#define GET_DEVID(x)       (((x)->conf >> 8)  & 0xFFFFULL)
#define GET_DOMID(x)       (((x)->conf >> 24) & 0xFFFFULL)
#define GET_PASID(x)       (((x)->conf >> 40) & 0xFFFFFULL)

/* iommu pmu conf1 masks */
#define GET_DEVID_MASK(x)  ((x)->conf1  & 0xFFFFULL)
#define GET_DOMID_MASK(x)  (((x)->conf1 >> 16) & 0xFFFFULL)
#define GET_PASID_MASK(x)  (((x)->conf1 >> 32) & 0xFFFFFULL)

#define IOMMU_NAME_SIZE 16

struct perf_amd_iommu {
	struct list_head list;
	struct pmu pmu;
	struct amd_iommu *iommu;
	char name[IOMMU_NAME_SIZE];
	u8 max_banks;
	u8 max_counters;
	u64 cntr_assign_mask;
	raw_spinlock_t lock;
};

static LIST_HEAD(perf_amd_iommu_list);

/*---------------------------------------------
 * sysfs format attributes
 *---------------------------------------------*/
PMU_FORMAT_ATTR(csource,    "config:0-7");
PMU_FORMAT_ATTR(devid,      "config:8-23");
PMU_FORMAT_ATTR(domid,      "config:24-39");
PMU_FORMAT_ATTR(pasid,      "config:40-59");
PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
PMU_FORMAT_ATTR(domid_mask, "config1:16-31");
PMU_FORMAT_ATTR(pasid_mask, "config1:32-51");

static struct attribute *iommu_format_attrs[] = {
	&format_attr_csource.attr,
	&format_attr_devid.attr,
	&format_attr_pasid.attr,
	&format_attr_domid.attr,
	&format_attr_devid_mask.attr,
	&format_attr_pasid_mask.attr,
	&format_attr_domid_mask.attr,
	NULL,
};

static struct attribute_group amd_iommu_format_group = {
	.name = "format",
	.attrs = iommu_format_attrs,
};

/*---------------------------------------------
 * sysfs events attributes
 *---------------------------------------------*/
static struct attribute_group amd_iommu_events_group = {
	.name = "events",
};

struct amd_iommu_event_desc {
	struct kobj_attribute attr;
	const char *event;
};

static ssize_t _iommu_event_show(struct kobject *kobj,
				struct kobj_attribute *attr, char *buf)
{
	struct amd_iommu_event_desc *event =
		container_of(attr, struct amd_iommu_event_desc, attr);
	return sprintf(buf, "%s\n", event->event);
}

#define AMD_IOMMU_EVENT_DESC(_name, _event)			\
{								\
	.attr  = __ATTR(_name, 0444, _iommu_event_show, NULL),	\
	.event = _event,					\
}

static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
	AMD_IOMMU_EVENT_DESC(mem_pass_untrans,        "csource=0x01"),
	AMD_IOMMU_EVENT_DESC(mem_pass_pretrans,       "csource=0x02"),
	AMD_IOMMU_EVENT_DESC(mem_pass_excl,           "csource=0x03"),
	AMD_IOMMU_EVENT_DESC(mem_target_abort,        "csource=0x04"),
	AMD_IOMMU_EVENT_DESC(mem_trans_total,         "csource=0x05"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit,   "csource=0x06"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis,   "csource=0x07"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit,   "csource=0x08"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis,   "csource=0x09"),
	AMD_IOMMU_EVENT_DESC(mem_dte_hit,             "csource=0x0a"),
	AMD_IOMMU_EVENT_DESC(mem_dte_mis,             "csource=0x0b"),
	AMD_IOMMU_EVENT_DESC(page_tbl_read_tot,       "csource=0x0c"),
	AMD_IOMMU_EVENT_DESC(page_tbl_read_nst,       "csource=0x0d"),
	AMD_IOMMU_EVENT_DESC(page_tbl_read_gst,       "csource=0x0e"),
	AMD_IOMMU_EVENT_DESC(int_dte_hit,             "csource=0x0f"),
	AMD_IOMMU_EVENT_DESC(int_dte_mis,             "csource=0x10"),
	AMD_IOMMU_EVENT_DESC(cmd_processed,           "csource=0x11"),
	AMD_IOMMU_EVENT_DESC(cmd_processed_inv,       "csource=0x12"),
	AMD_IOMMU_EVENT_DESC(tlb_inv,                 "csource=0x13"),
	AMD_IOMMU_EVENT_DESC(ign_rd_wr_mmio_1ff8h,    "csource=0x14"),
	AMD_IOMMU_EVENT_DESC(vapic_int_non_guest,     "csource=0x15"),
	AMD_IOMMU_EVENT_DESC(vapic_int_guest,         "csource=0x16"),
	AMD_IOMMU_EVENT_DESC(smi_recv,                "csource=0x17"),
	AMD_IOMMU_EVENT_DESC(smi_blk,                 "csource=0x18"),
	{ /* end: all zeroes */ },
};

/*---------------------------------------------
 * sysfs cpumask attributes
 *---------------------------------------------*/
static cpumask_t iommu_cpumask;

static ssize_t _iommu_cpumask_show(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask);
}
static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);

static struct attribute *iommu_cpumask_attrs[] = {
	&dev_attr_cpumask.attr,
	NULL,
};

static struct attribute_group amd_iommu_cpumask_group = {
	.attrs = iommu_cpumask_attrs,
};

/*---------------------------------------------*/

static int get_next_avail_iommu_bnk_cntr(struct perf_event *event)
{
	struct perf_amd_iommu *piommu = container_of(event->pmu, struct perf_amd_iommu, pmu);
	int max_cntrs = piommu->max_counters;
	int max_banks = piommu->max_banks;
	u32 shift, bank, cntr;
	unsigned long flags;
	int retval;

	raw_spin_lock_irqsave(&piommu->lock, flags);

	for (bank = 0, shift = 0; bank < max_banks; bank++) {
		for (cntr = 0; cntr < max_cntrs; cntr++) {
			shift = bank + (bank*3) + cntr;
			if (piommu->cntr_assign_mask & BIT_ULL(shift)) {
				continue;
			} else {
				piommu->cntr_assign_mask |= BIT_ULL(shift);
				event->hw.iommu_bank = bank;
				event->hw.iommu_cntr = cntr;
				retval = 0;
				goto out;
			}
		}
	}
	retval = -ENOSPC;
out:
	raw_spin_unlock_irqrestore(&piommu->lock, flags);
	return retval;
}

static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
					u8 bank, u8 cntr)
{
	unsigned long flags;
	int max_banks, max_cntrs;
	int shift = 0;

	max_banks = perf_iommu->max_banks;
	max_cntrs = perf_iommu->max_counters;

	if ((bank > max_banks) || (cntr > max_cntrs))
		return -EINVAL;

	shift = bank + cntr + (bank*3);

	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
	perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);

	return 0;
}

static int perf_iommu_event_init(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;

	/* test the event attr type check for PMU enumeration */
	if (event->attr.type != event->pmu->type)
		return -ENOENT;

	/*
	 * IOMMU counters are shared across all cores.
	 * Therefore, it does not support per-process mode.
	 * Also, it does not support event sampling mode.
	 */
	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
		return -EINVAL;

	/* IOMMU counters do not have usr/os/guest/host bits */
	if (event->attr.exclude_user || event->attr.exclude_kernel ||
	    event->attr.exclude_host || event->attr.exclude_guest)
		return -EINVAL;

	if (event->cpu < 0)
		return -EINVAL;

	/* update the hw_perf_event struct with the iommu config data */
	hwc->conf  = event->attr.config;
	hwc->conf1 = event->attr.config1;

	return 0;
}

static inline struct amd_iommu *perf_event_2_iommu(struct perf_event *ev)
{
	return (container_of(ev->pmu, struct perf_amd_iommu, pmu))->iommu;
}

static void perf_iommu_enable_event(struct perf_event *ev)
{
	struct amd_iommu *iommu = perf_event_2_iommu(ev);
	struct hw_perf_event *hwc = &ev->hw;
	u8 bank = hwc->iommu_bank;
	u8 cntr = hwc->iommu_cntr;
	u64 reg = 0ULL;

	reg = GET_CSOURCE(hwc);
	amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_COUNTER_SRC_REG, &reg);

	reg = GET_DEVID_MASK(hwc);
	reg = GET_DEVID(hwc) | (reg << 32);
	if (reg)
		reg |= BIT(31);
	amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_DEVID_MATCH_REG, &reg);

	reg = GET_PASID_MASK(hwc);
	reg = GET_PASID(hwc) | (reg << 32);
	if (reg)
		reg |= BIT(31);
	amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_PASID_MATCH_REG, &reg);

	reg = GET_DOMID_MASK(hwc);
	reg = GET_DOMID(hwc) | (reg << 32);
	if (reg)
		reg |= BIT(31);
	amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_DOMID_MATCH_REG, &reg);
}

static void perf_iommu_disable_event(struct perf_event *event)
{
	struct amd_iommu *iommu = perf_event_2_iommu(event);
	struct hw_perf_event *hwc = &event->hw;
	u64 reg = 0ULL;

	amd_iommu_pc_set_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr,
			     IOMMU_PC_COUNTER_SRC_REG, &reg);
}

static void perf_iommu_start(struct perf_event *event, int flags)
{
	struct hw_perf_event *hwc = &event->hw;

	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
		return;

	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
	hwc->state = 0;

	if (flags & PERF_EF_RELOAD) {
		u64 prev_raw_count = local64_read(&hwc->prev_count);
		struct amd_iommu *iommu = perf_event_2_iommu(event);

		amd_iommu_pc_set_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr,
				     IOMMU_PC_COUNTER_REG, &prev_raw_count);
	}

	perf_iommu_enable_event(event);
	perf_event_update_userpage(event);

}

static void perf_iommu_read(struct perf_event *event)
{
	u64 count, prev, delta;
	struct hw_perf_event *hwc = &event->hw;
	struct amd_iommu *iommu = perf_event_2_iommu(event);

	if (amd_iommu_pc_get_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr,
				 IOMMU_PC_COUNTER_REG, &count))
		return;

	/* IOMMU pc counter register is only 48 bits */
	count &= GENMASK_ULL(47, 0);

	prev = local64_read(&hwc->prev_count);
	if (local64_cmpxchg(&hwc->prev_count, prev, count) != prev)
		return;

	/* Handle 48-bit counter overflow */
	delta = (count << COUNTER_SHIFT) - (prev << COUNTER_SHIFT);
	delta >>= COUNTER_SHIFT;
	local64_add(delta, &event->count);
}

static void perf_iommu_stop(struct perf_event *event, int flags)
{
	struct hw_perf_event *hwc = &event->hw;

	if (hwc->state & PERF_HES_UPTODATE)
		return;

	perf_iommu_disable_event(event);
	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
	hwc->state |= PERF_HES_STOPPED;

	if (hwc->state & PERF_HES_UPTODATE)
		return;

	perf_iommu_read(event);
	hwc->state |= PERF_HES_UPTODATE;
}

static int perf_iommu_add(struct perf_event *event, int flags)
{
	int retval;

	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;

	/* request an iommu bank/counter */
	retval = get_next_avail_iommu_bnk_cntr(event);
	if (retval)
		return retval;

	if (flags & PERF_EF_START)
		perf_iommu_start(event, PERF_EF_RELOAD);

	return 0;
}

static void perf_iommu_del(struct perf_event *event, int flags)
{
	struct hw_perf_event *hwc = &event->hw;
	struct perf_amd_iommu *perf_iommu =
			container_of(event->pmu, struct perf_amd_iommu, pmu);

	perf_iommu_stop(event, PERF_EF_UPDATE);

	/* clear the assigned iommu bank/counter */
	clear_avail_iommu_bnk_cntr(perf_iommu,
				   hwc->iommu_bank, hwc->iommu_cntr);

	perf_event_update_userpage(event);
}

static __init int _init_events_attrs(void)
{
	int i = 0, j;
	struct attribute **attrs;

	while (amd_iommu_v2_event_descs[i].attr.attr.name)
		i++;

	attrs = kzalloc(sizeof(struct attribute **) * (i + 1), GFP_KERNEL);
	if (!attrs)
		return -ENOMEM;

	for (j = 0; j < i; j++)
		attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;

	amd_iommu_events_group.attrs = attrs;
	return 0;
}

const struct attribute_group *amd_iommu_attr_groups[] = {
	&amd_iommu_format_group,
	&amd_iommu_cpumask_group,
	&amd_iommu_events_group,
	NULL,
};

static struct pmu iommu_pmu = {
	.event_init	= perf_iommu_event_init,
	.add		= perf_iommu_add,
	.del		= perf_iommu_del,
	.start		= perf_iommu_start,
	.stop		= perf_iommu_stop,
	.read		= perf_iommu_read,
	.task_ctx_nr	= perf_invalid_context,
	.attr_groups	= amd_iommu_attr_groups,
};

static __init int init_one_iommu(unsigned int idx)
{
	struct perf_amd_iommu *perf_iommu;
	int ret;

	perf_iommu = kzalloc(sizeof(struct perf_amd_iommu), GFP_KERNEL);
	if (!perf_iommu)
		return -ENOMEM;

	raw_spin_lock_init(&perf_iommu->lock);

	perf_iommu->pmu          = iommu_pmu;
	perf_iommu->iommu        = get_amd_iommu(idx);
	perf_iommu->max_banks    = amd_iommu_pc_get_max_banks(idx);
	perf_iommu->max_counters = amd_iommu_pc_get_max_counters(idx);

	if (!perf_iommu->iommu ||
	    !perf_iommu->max_banks ||
	    !perf_iommu->max_counters) {
		kfree(perf_iommu);
		return -EINVAL;
	}

	snprintf(perf_iommu->name, IOMMU_NAME_SIZE, "amd_iommu_%u", idx);

	ret = perf_pmu_register(&perf_iommu->pmu, perf_iommu->name, -1);
	if (!ret) {
		pr_info("Detected AMD IOMMU #%d (%d banks, %d counters/bank).\n",
			idx, perf_iommu->max_banks, perf_iommu->max_counters);
		list_add_tail(&perf_iommu->list, &perf_amd_iommu_list);
	} else {
		pr_warn("Error initializing IOMMU %d.\n", idx);
		kfree(perf_iommu);
	}
	return ret;
}

static __init int amd_iommu_pc_init(void)
{
	unsigned int i, cnt = 0;
	int ret;

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

	ret = _init_events_attrs();
	if (ret)
		return ret;

	/*
	 * An IOMMU PMU is specific to an IOMMU, and can function independently.
	 * So we go through all IOMMUs and ignore the one that fails init
	 * unless all IOMMU are failing.
	 */
	for (i = 0; i < amd_iommu_get_num_iommus(); i++) {
		ret = init_one_iommu(i);
		if (!ret)
			cnt++;
	}

	if (!cnt) {
		kfree(amd_iommu_events_group.attrs);
		return -ENODEV;
	}

	/* Init cpumask attributes to only core 0 */
	cpumask_set_cpu(0, &iommu_cpumask);
	return 0;
}

device_initcall(amd_iommu_pc_init);
