// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Hypervisor supplied "24x7" performance counter support
 *
 * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
 * Copyright 2014 IBM Corporation.
 */

#define pr_fmt(fmt) "hv-24x7: " fmt

#include <linux/perf_event.h>
#include <linux/rbtree.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>

#include <asm/cputhreads.h>
#include <asm/firmware.h>
#include <asm/hvcall.h>
#include <asm/io.h>
#include <linux/byteorder/generic.h>

#include <asm/rtas.h>
#include "hv-24x7.h"
#include "hv-24x7-catalog.h"
#include "hv-common.h"

/* Version of the 24x7 hypervisor API that we should use in this machine. */
static int interface_version;

/* Whether we have to aggregate result data for some domains. */
static bool aggregate_result_elements;

static cpumask_t hv_24x7_cpumask;

static bool domain_is_valid(unsigned domain)
{
	switch (domain) {
#define DOMAIN(n, v, x, c)		\
	case HV_PERF_DOMAIN_##n:	\
		/* fall through */
#include "hv-24x7-domains.h"
#undef DOMAIN
		return true;
	default:
		return false;
	}
}

static bool is_physical_domain(unsigned domain)
{
	switch (domain) {
#define DOMAIN(n, v, x, c)		\
	case HV_PERF_DOMAIN_##n:	\
		return c;
#include "hv-24x7-domains.h"
#undef DOMAIN
	default:
		return false;
	}
}

/*
 * The Processor Module Information system parameter allows transferring
 * of certain processor module information from the platform to the OS.
 * Refer PAPR+ document to get parameter token value as '43'.
 */

#define PROCESSOR_MODULE_INFO   43

static u32 phys_sockets;	/* Physical sockets */
static u32 phys_chipspersocket;	/* Physical chips per socket*/
static u32 phys_coresperchip; /* Physical cores per chip */

/*
 * read_24x7_sys_info()
 * Retrieve the number of sockets and chips per socket and cores per
 * chip details through the get-system-parameter rtas call.
 */
void read_24x7_sys_info(void)
{
	const s32 token = rtas_token("ibm,get-system-parameter");
	int call_status;

	/*
	 * Making system parameter: chips and sockets and cores per chip
	 * default to 1.
	 */
	phys_sockets = 1;
	phys_chipspersocket = 1;
	phys_coresperchip = 1;

	do {
		spin_lock(&rtas_data_buf_lock);
		call_status = rtas_call(token, 3, 1, NULL, PROCESSOR_MODULE_INFO,
					__pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
		if (call_status == 0) {
			int ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]);
			int len = be16_to_cpup((__be16 *)&rtas_data_buf[0]);

			if (len >= 8 && ntypes != 0) {
				phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]);
				phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]);
				phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]);
			}
		}
		spin_unlock(&rtas_data_buf_lock);
	} while (rtas_busy_delay(call_status));

	if (call_status != 0) {
		pr_err("Error calling get-system-parameter %d\n",
		       call_status);
	}
}

/* Domains for which more than one result element are returned for each event. */
static bool domain_needs_aggregation(unsigned int domain)
{
	return aggregate_result_elements &&
			(domain == HV_PERF_DOMAIN_PHYS_CORE ||
			 (domain >= HV_PERF_DOMAIN_VCPU_HOME_CORE &&
			  domain <= HV_PERF_DOMAIN_VCPU_REMOTE_NODE));
}

static const char *domain_name(unsigned domain)
{
	if (!domain_is_valid(domain))
		return NULL;

	switch (domain) {
	case HV_PERF_DOMAIN_PHYS_CHIP:		return "Physical Chip";
	case HV_PERF_DOMAIN_PHYS_CORE:		return "Physical Core";
	case HV_PERF_DOMAIN_VCPU_HOME_CORE:	return "VCPU Home Core";
	case HV_PERF_DOMAIN_VCPU_HOME_CHIP:	return "VCPU Home Chip";
	case HV_PERF_DOMAIN_VCPU_HOME_NODE:	return "VCPU Home Node";
	case HV_PERF_DOMAIN_VCPU_REMOTE_NODE:	return "VCPU Remote Node";
	}

	WARN_ON_ONCE(domain);
	return NULL;
}

static bool catalog_entry_domain_is_valid(unsigned domain)
{
	/* POWER8 doesn't support virtual domains. */
	if (interface_version == 1)
		return is_physical_domain(domain);
	else
		return domain_is_valid(domain);
}

/*
 * TODO: Merging events:
 * - Think of the hcall as an interface to a 4d array of counters:
 *   - x = domains
 *   - y = indexes in the domain (core, chip, vcpu, node, etc)
 *   - z = offset into the counter space
 *   - w = lpars (guest vms, "logical partitions")
 * - A single request is: x,y,y_last,z,z_last,w,w_last
 *   - this means we can retrieve a rectangle of counters in y,z for a single x.
 *
 * - Things to consider (ignoring w):
 *   - input  cost_per_request = 16
 *   - output cost_per_result(ys,zs)  = 8 + 8 * ys + ys * zs
 *   - limited number of requests per hcall (must fit into 4K bytes)
 *     - 4k = 16 [buffer header] - 16 [request size] * request_count
 *     - 255 requests per hcall
 *   - sometimes it will be more efficient to read extra data and discard
 */

/*
 * Example usage:
 *  perf stat -e 'hv_24x7/domain=2,offset=8,vcpu=0,lpar=0xffffffff/'
 */

/* u3 0-6, one of HV_24X7_PERF_DOMAIN */
EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
/* u16 */
EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31);
EVENT_DEFINE_RANGE_FORMAT(chip, config, 16, 31);
EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31);
/* u32, see "data_offset" */
EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63);
/* u16 */
EVENT_DEFINE_RANGE_FORMAT(lpar, config1, 0, 15);

EVENT_DEFINE_RANGE(reserved1, config,   4, 15);
EVENT_DEFINE_RANGE(reserved2, config1, 16, 63);
EVENT_DEFINE_RANGE(reserved3, config2,  0, 63);

static struct attribute *format_attrs[] = {
	&format_attr_domain.attr,
	&format_attr_offset.attr,
	&format_attr_core.attr,
	&format_attr_chip.attr,
	&format_attr_vcpu.attr,
	&format_attr_lpar.attr,
	NULL,
};

static struct attribute_group format_group = {
	.name = "format",
	.attrs = format_attrs,
};

static struct attribute_group event_group = {
	.name = "events",
	/* .attrs is set in init */
};

static struct attribute_group event_desc_group = {
	.name = "event_descs",
	/* .attrs is set in init */
};

static struct attribute_group event_long_desc_group = {
	.name = "event_long_descs",
	/* .attrs is set in init */
};

static struct kmem_cache *hv_page_cache;

DEFINE_PER_CPU(int, hv_24x7_txn_flags);
DEFINE_PER_CPU(int, hv_24x7_txn_err);

struct hv_24x7_hw {
	struct perf_event *events[255];
};

DEFINE_PER_CPU(struct hv_24x7_hw, hv_24x7_hw);

/*
 * request_buffer and result_buffer are not required to be 4k aligned,
 * but are not allowed to cross any 4k boundary. Aligning them to 4k is
 * the simplest way to ensure that.
 */
#define H24x7_DATA_BUFFER_SIZE	4096
DEFINE_PER_CPU(char, hv_24x7_reqb[H24x7_DATA_BUFFER_SIZE]) __aligned(4096);
DEFINE_PER_CPU(char, hv_24x7_resb[H24x7_DATA_BUFFER_SIZE]) __aligned(4096);

static unsigned int max_num_requests(int interface_version)
{
	return (H24x7_DATA_BUFFER_SIZE - sizeof(struct hv_24x7_request_buffer))
		/ H24x7_REQUEST_SIZE(interface_version);
}

static char *event_name(struct hv_24x7_event_data *ev, int *len)
{
	*len = be16_to_cpu(ev->event_name_len) - 2;
	return (char *)ev->remainder;
}

static char *event_desc(struct hv_24x7_event_data *ev, int *len)
{
	unsigned nl = be16_to_cpu(ev->event_name_len);
	__be16 *desc_len = (__be16 *)(ev->remainder + nl - 2);

	*len = be16_to_cpu(*desc_len) - 2;
	return (char *)ev->remainder + nl;
}

static char *event_long_desc(struct hv_24x7_event_data *ev, int *len)
{
	unsigned nl = be16_to_cpu(ev->event_name_len);
	__be16 *desc_len_ = (__be16 *)(ev->remainder + nl - 2);
	unsigned desc_len = be16_to_cpu(*desc_len_);
	__be16 *long_desc_len = (__be16 *)(ev->remainder + nl + desc_len - 2);

	*len = be16_to_cpu(*long_desc_len) - 2;
	return (char *)ev->remainder + nl + desc_len;
}

static bool event_fixed_portion_is_within(struct hv_24x7_event_data *ev,
					  void *end)
{
	void *start = ev;

	return (start + offsetof(struct hv_24x7_event_data, remainder)) < end;
}

/*
 * Things we don't check:
 *  - padding for desc, name, and long/detailed desc is required to be '\0'
 *    bytes.
 *
 *  Return NULL if we pass end,
 *  Otherwise return the address of the byte just following the event.
 */
static void *event_end(struct hv_24x7_event_data *ev, void *end)
{
	void *start = ev;
	__be16 *dl_, *ldl_;
	unsigned dl, ldl;
	unsigned nl = be16_to_cpu(ev->event_name_len);

	if (nl < 2) {
		pr_debug("%s: name length too short: %d", __func__, nl);
		return NULL;
	}

	if (start + nl > end) {
		pr_debug("%s: start=%p + nl=%u > end=%p",
				__func__, start, nl, end);
		return NULL;
	}

	dl_ = (__be16 *)(ev->remainder + nl - 2);
	if (!IS_ALIGNED((uintptr_t)dl_, 2))
		pr_warn("desc len not aligned %p", dl_);
	dl = be16_to_cpu(*dl_);
	if (dl < 2) {
		pr_debug("%s: desc len too short: %d", __func__, dl);
		return NULL;
	}

	if (start + nl + dl > end) {
		pr_debug("%s: (start=%p + nl=%u + dl=%u)=%p > end=%p",
				__func__, start, nl, dl, start + nl + dl, end);
		return NULL;
	}

	ldl_ = (__be16 *)(ev->remainder + nl + dl - 2);
	if (!IS_ALIGNED((uintptr_t)ldl_, 2))
		pr_warn("long desc len not aligned %p", ldl_);
	ldl = be16_to_cpu(*ldl_);
	if (ldl < 2) {
		pr_debug("%s: long desc len too short (ldl=%u)",
				__func__, ldl);
		return NULL;
	}

	if (start + nl + dl + ldl > end) {
		pr_debug("%s: start=%p + nl=%u + dl=%u + ldl=%u > end=%p",
				__func__, start, nl, dl, ldl, end);
		return NULL;
	}

	return start + nl + dl + ldl;
}

static long h_get_24x7_catalog_page_(unsigned long phys_4096,
				     unsigned long version, unsigned long index)
{
	pr_devel("h_get_24x7_catalog_page(0x%lx, %lu, %lu)",
			phys_4096, version, index);

	WARN_ON(!IS_ALIGNED(phys_4096, 4096));

	return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE,
			phys_4096, version, index);
}

static long h_get_24x7_catalog_page(char page[], u64 version, u32 index)
{
	return h_get_24x7_catalog_page_(virt_to_phys(page),
					version, index);
}

/*
 * Each event we find in the catalog, will have a sysfs entry. Format the
 * data for this sysfs entry based on the event's domain.
 *
 * Events belonging to the Chip domain can only be monitored in that domain.
 * i.e the domain for these events is a fixed/knwon value.
 *
 * Events belonging to the Core domain can be monitored either in the physical
 * core or in one of the virtual CPU domains. So the domain value for these
 * events must be specified by the user (i.e is a required parameter). Format
 * the Core events with 'domain=?' so the perf-tool can error check required
 * parameters.
 *
 * NOTE: For the Core domain events, rather than making domain a required
 *	 parameter we could default it to PHYS_CORE and allowe users to
 *	 override the domain to one of the VCPU domains.
 *
 *	 However, this can make the interface a little inconsistent.
 *
 *	 If we set domain=2 (PHYS_CHIP) and allow user to override this field
 *	 the user may be tempted to also modify the "offset=x" field in which
 *	 can lead to confusing usage. Consider the HPM_PCYC (offset=0x18) and
 *	 HPM_INST (offset=0x20) events. With:
 *
 *		perf stat -e hv_24x7/HPM_PCYC,offset=0x20/
 *
 *	we end up monitoring HPM_INST, while the command line has HPM_PCYC.
 *
 *	By not assigning a default value to the domain for the Core events,
 *	we can have simple guidelines:
 *
 *		- Specifying values for parameters with "=?" is required.
 *
 *		- Specifying (i.e overriding) values for other parameters
 *		  is undefined.
 */
static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain)
{
	const char *sindex;
	const char *lpar;
	const char *domain_str;
	char buf[8];

	switch (domain) {
	case HV_PERF_DOMAIN_PHYS_CHIP:
		snprintf(buf, sizeof(buf), "%d", domain);
		domain_str = buf;
		lpar = "0x0";
		sindex = "chip";
		break;
	case HV_PERF_DOMAIN_PHYS_CORE:
		domain_str = "?";
		lpar = "0x0";
		sindex = "core";
		break;
	default:
		domain_str = "?";
		lpar = "?";
		sindex = "vcpu";
	}

	return kasprintf(GFP_KERNEL,
			"domain=%s,offset=0x%x,%s=?,lpar=%s",
			domain_str,
			be16_to_cpu(event->event_counter_offs) +
				be16_to_cpu(event->event_group_record_offs),
			sindex,
			lpar);
}

/* Avoid trusting fw to NUL terminate strings */
static char *memdup_to_str(char *maybe_str, int max_len, gfp_t gfp)
{
	return kasprintf(gfp, "%.*s", max_len, maybe_str);
}

static ssize_t device_show_string(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct dev_ext_attribute *d;

	d = container_of(attr, struct dev_ext_attribute, attr);

	return sprintf(buf, "%s\n", (char *)d->var);
}

static ssize_t cpumask_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	return cpumap_print_to_pagebuf(true, buf, &hv_24x7_cpumask);
}

static ssize_t sockets_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", phys_sockets);
}

static ssize_t chipspersocket_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", phys_chipspersocket);
}

static ssize_t coresperchip_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", phys_coresperchip);
}

static struct attribute *device_str_attr_create_(char *name, char *str)
{
	struct dev_ext_attribute *attr = kzalloc(sizeof(*attr), GFP_KERNEL);

	if (!attr)
		return NULL;

	sysfs_attr_init(&attr->attr.attr);

	attr->var = str;
	attr->attr.attr.name = name;
	attr->attr.attr.mode = 0444;
	attr->attr.show = device_show_string;

	return &attr->attr.attr;
}

/*
 * Allocate and initialize strings representing event attributes.
 *
 * NOTE: The strings allocated here are never destroyed and continue to
 *	 exist till shutdown. This is to allow us to create as many events
 *	 from the catalog as possible, even if we encounter errors with some.
 *	 In case of changes to error paths in future, these may need to be
 *	 freed by the caller.
 */
static struct attribute *device_str_attr_create(char *name, int name_max,
						int name_nonce,
						char *str, size_t str_max)
{
	char *n;
	char *s = memdup_to_str(str, str_max, GFP_KERNEL);
	struct attribute *a;

	if (!s)
		return NULL;

	if (!name_nonce)
		n = kasprintf(GFP_KERNEL, "%.*s", name_max, name);
	else
		n = kasprintf(GFP_KERNEL, "%.*s__%d", name_max, name,
					name_nonce);
	if (!n)
		goto out_s;

	a = device_str_attr_create_(n, s);
	if (!a)
		goto out_n;

	return a;
out_n:
	kfree(n);
out_s:
	kfree(s);
	return NULL;
}

static struct attribute *event_to_attr(unsigned ix,
				       struct hv_24x7_event_data *event,
				       unsigned domain,
				       int nonce)
{
	int event_name_len;
	char *ev_name, *a_ev_name, *val;
	struct attribute *attr;

	if (!domain_is_valid(domain)) {
		pr_warn("catalog event %u has invalid domain %u\n",
				ix, domain);
		return NULL;
	}

	val = event_fmt(event, domain);
	if (!val)
		return NULL;

	ev_name = event_name(event, &event_name_len);
	if (!nonce)
		a_ev_name = kasprintf(GFP_KERNEL, "%.*s",
				(int)event_name_len, ev_name);
	else
		a_ev_name = kasprintf(GFP_KERNEL, "%.*s__%d",
				(int)event_name_len, ev_name, nonce);

	if (!a_ev_name)
		goto out_val;

	attr = device_str_attr_create_(a_ev_name, val);
	if (!attr)
		goto out_name;

	return attr;
out_name:
	kfree(a_ev_name);
out_val:
	kfree(val);
	return NULL;
}

static struct attribute *event_to_desc_attr(struct hv_24x7_event_data *event,
					    int nonce)
{
	int nl, dl;
	char *name = event_name(event, &nl);
	char *desc = event_desc(event, &dl);

	/* If there isn't a description, don't create the sysfs file */
	if (!dl)
		return NULL;

	return device_str_attr_create(name, nl, nonce, desc, dl);
}

static struct attribute *
event_to_long_desc_attr(struct hv_24x7_event_data *event, int nonce)
{
	int nl, dl;
	char *name = event_name(event, &nl);
	char *desc = event_long_desc(event, &dl);

	/* If there isn't a description, don't create the sysfs file */
	if (!dl)
		return NULL;

	return device_str_attr_create(name, nl, nonce, desc, dl);
}

static int event_data_to_attrs(unsigned ix, struct attribute **attrs,
				   struct hv_24x7_event_data *event, int nonce)
{
	*attrs = event_to_attr(ix, event, event->domain, nonce);
	if (!*attrs)
		return -1;

	return 0;
}

/* */
struct event_uniq {
	struct rb_node node;
	const char *name;
	int nl;
	unsigned ct;
	unsigned domain;
};

static int memord(const void *d1, size_t s1, const void *d2, size_t s2)
{
	if (s1 < s2)
		return 1;
	if (s1 > s2)
		return -1;

	return memcmp(d1, d2, s1);
}

static int ev_uniq_ord(const void *v1, size_t s1, unsigned d1, const void *v2,
		       size_t s2, unsigned d2)
{
	int r = memord(v1, s1, v2, s2);

	if (r)
		return r;
	if (d1 > d2)
		return 1;
	if (d2 > d1)
		return -1;
	return 0;
}

static int event_uniq_add(struct rb_root *root, const char *name, int nl,
			  unsigned domain)
{
	struct rb_node **new = &(root->rb_node), *parent = NULL;
	struct event_uniq *data;

	/* Figure out where to put new node */
	while (*new) {
		struct event_uniq *it;
		int result;

		it = rb_entry(*new, struct event_uniq, node);
		result = ev_uniq_ord(name, nl, domain, it->name, it->nl,
					it->domain);

		parent = *new;
		if (result < 0)
			new = &((*new)->rb_left);
		else if (result > 0)
			new = &((*new)->rb_right);
		else {
			it->ct++;
			pr_info("found a duplicate event %.*s, ct=%u\n", nl,
						name, it->ct);
			return it->ct;
		}
	}

	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	*data = (struct event_uniq) {
		.name = name,
		.nl = nl,
		.ct = 0,
		.domain = domain,
	};

	/* Add new node and rebalance tree. */
	rb_link_node(&data->node, parent, new);
	rb_insert_color(&data->node, root);

	/* data->ct */
	return 0;
}

static void event_uniq_destroy(struct rb_root *root)
{
	/*
	 * the strings we point to are in the giant block of memory filled by
	 * the catalog, and are freed separately.
	 */
	struct event_uniq *pos, *n;

	rbtree_postorder_for_each_entry_safe(pos, n, root, node)
		kfree(pos);
}


/*
 * ensure the event structure's sizes are self consistent and don't cause us to
 * read outside of the event
 *
 * On success, return the event length in bytes.
 * Otherwise, return -1 (and print as appropriate).
 */
static ssize_t catalog_event_len_validate(struct hv_24x7_event_data *event,
					  size_t event_idx,
					  size_t event_data_bytes,
					  size_t event_entry_count,
					  size_t offset, void *end)
{
	ssize_t ev_len;
	void *ev_end, *calc_ev_end;

	if (offset >= event_data_bytes)
		return -1;

	if (event_idx >= event_entry_count) {
		pr_devel("catalog event data has %zu bytes of padding after last event\n",
				event_data_bytes - offset);
		return -1;
	}

	if (!event_fixed_portion_is_within(event, end)) {
		pr_warn("event %zu fixed portion is not within range\n",
				event_idx);
		return -1;
	}

	ev_len = be16_to_cpu(event->length);

	if (ev_len % 16)
		pr_info("event %zu has length %zu not divisible by 16: event=%pK\n",
				event_idx, ev_len, event);

	ev_end = (__u8 *)event + ev_len;
	if (ev_end > end) {
		pr_warn("event %zu has .length=%zu, ends after buffer end: ev_end=%pK > end=%pK, offset=%zu\n",
				event_idx, ev_len, ev_end, end,
				offset);
		return -1;
	}

	calc_ev_end = event_end(event, end);
	if (!calc_ev_end) {
		pr_warn("event %zu has a calculated length which exceeds buffer length %zu: event=%pK end=%pK, offset=%zu\n",
			event_idx, event_data_bytes, event, end,
			offset);
		return -1;
	}

	if (calc_ev_end > ev_end) {
		pr_warn("event %zu exceeds it's own length: event=%pK, end=%pK, offset=%zu, calc_ev_end=%pK\n",
			event_idx, event, ev_end, offset, calc_ev_end);
		return -1;
	}

	return ev_len;
}

#define MAX_4K (SIZE_MAX / 4096)

static int create_events_from_catalog(struct attribute ***events_,
				      struct attribute ***event_descs_,
				      struct attribute ***event_long_descs_)
{
	long hret;
	size_t catalog_len, catalog_page_len, event_entry_count,
	       event_data_len, event_data_offs,
	       event_data_bytes, junk_events, event_idx, event_attr_ct, i,
	       attr_max, event_idx_last, desc_ct, long_desc_ct;
	ssize_t ct, ev_len;
	uint64_t catalog_version_num;
	struct attribute **events, **event_descs, **event_long_descs;
	struct hv_24x7_catalog_page_0 *page_0 =
		kmem_cache_alloc(hv_page_cache, GFP_KERNEL);
	void *page = page_0;
	void *event_data, *end;
	struct hv_24x7_event_data *event;
	struct rb_root ev_uniq = RB_ROOT;
	int ret = 0;

	if (!page) {
		ret = -ENOMEM;
		goto e_out;
	}

	hret = h_get_24x7_catalog_page(page, 0, 0);
	if (hret) {
		ret = -EIO;
		goto e_free;
	}

	catalog_version_num = be64_to_cpu(page_0->version);
	catalog_page_len = be32_to_cpu(page_0->length);

	if (MAX_4K < catalog_page_len) {
		pr_err("invalid page count: %zu\n", catalog_page_len);
		ret = -EIO;
		goto e_free;
	}

	catalog_len = catalog_page_len * 4096;

	event_entry_count = be16_to_cpu(page_0->event_entry_count);
	event_data_offs   = be16_to_cpu(page_0->event_data_offs);
	event_data_len    = be16_to_cpu(page_0->event_data_len);

	pr_devel("cv %llu cl %zu eec %zu edo %zu edl %zu\n",
			catalog_version_num, catalog_len,
			event_entry_count, event_data_offs, event_data_len);

	if ((MAX_4K < event_data_len)
			|| (MAX_4K < event_data_offs)
			|| (MAX_4K - event_data_offs < event_data_len)) {
		pr_err("invalid event data offs %zu and/or len %zu\n",
				event_data_offs, event_data_len);
		ret = -EIO;
		goto e_free;
	}

	if ((event_data_offs + event_data_len) > catalog_page_len) {
		pr_err("event data %zu-%zu does not fit inside catalog 0-%zu\n",
				event_data_offs,
				event_data_offs + event_data_len,
				catalog_page_len);
		ret = -EIO;
		goto e_free;
	}

	if (SIZE_MAX - 1 < event_entry_count) {
		pr_err("event_entry_count %zu is invalid\n", event_entry_count);
		ret = -EIO;
		goto e_free;
	}

	event_data_bytes = event_data_len * 4096;

	/*
	 * event data can span several pages, events can cross between these
	 * pages. Use vmalloc to make this easier.
	 */
	event_data = vmalloc(event_data_bytes);
	if (!event_data) {
		pr_err("could not allocate event data\n");
		ret = -ENOMEM;
		goto e_free;
	}

	end = event_data + event_data_bytes;

	/*
	 * using vmalloc_to_phys() like this only works if PAGE_SIZE is
	 * divisible by 4096
	 */
	BUILD_BUG_ON(PAGE_SIZE % 4096);

	for (i = 0; i < event_data_len; i++) {
		hret = h_get_24x7_catalog_page_(
				vmalloc_to_phys(event_data + i * 4096),
				catalog_version_num,
				i + event_data_offs);
		if (hret) {
			pr_err("Failed to get event data in page %zu: rc=%ld\n",
			       i + event_data_offs, hret);
			ret = -EIO;
			goto e_event_data;
		}
	}

	/*
	 * scan the catalog to determine the number of attributes we need, and
	 * verify it at the same time.
	 */
	for (junk_events = 0, event = event_data, event_idx = 0, attr_max = 0;
	     ;
	     event_idx++, event = (void *)event + ev_len) {
		size_t offset = (void *)event - (void *)event_data;
		char *name;
		int nl;

		ev_len = catalog_event_len_validate(event, event_idx,
						    event_data_bytes,
						    event_entry_count,
						    offset, end);
		if (ev_len < 0)
			break;

		name = event_name(event, &nl);

		if (event->event_group_record_len == 0) {
			pr_devel("invalid event %zu (%.*s): group_record_len == 0, skipping\n",
					event_idx, nl, name);
			junk_events++;
			continue;
		}

		if (!catalog_entry_domain_is_valid(event->domain)) {
			pr_info("event %zu (%.*s) has invalid domain %d\n",
					event_idx, nl, name, event->domain);
			junk_events++;
			continue;
		}

		attr_max++;
	}

	event_idx_last = event_idx;
	if (event_idx_last != event_entry_count)
		pr_warn("event buffer ended before listed # of events were parsed (got %zu, wanted %zu, junk %zu)\n",
				event_idx_last, event_entry_count, junk_events);

	events = kmalloc_array(attr_max + 1, sizeof(*events), GFP_KERNEL);
	if (!events) {
		ret = -ENOMEM;
		goto e_event_data;
	}

	event_descs = kmalloc_array(event_idx + 1, sizeof(*event_descs),
				GFP_KERNEL);
	if (!event_descs) {
		ret = -ENOMEM;
		goto e_event_attrs;
	}

	event_long_descs = kmalloc_array(event_idx + 1,
			sizeof(*event_long_descs), GFP_KERNEL);
	if (!event_long_descs) {
		ret = -ENOMEM;
		goto e_event_descs;
	}

	/* Iterate over the catalog filling in the attribute vector */
	for (junk_events = 0, event_attr_ct = 0, desc_ct = 0, long_desc_ct = 0,
				event = event_data, event_idx = 0;
			event_idx < event_idx_last;
			event_idx++, ev_len = be16_to_cpu(event->length),
				event = (void *)event + ev_len) {
		char *name;
		int nl;
		int nonce;
		/*
		 * these are the only "bad" events that are intermixed and that
		 * we can ignore without issue. make sure to skip them here
		 */
		if (event->event_group_record_len == 0)
			continue;
		if (!catalog_entry_domain_is_valid(event->domain))
			continue;

		name  = event_name(event, &nl);
		nonce = event_uniq_add(&ev_uniq, name, nl, event->domain);
		ct    = event_data_to_attrs(event_idx, events + event_attr_ct,
					    event, nonce);
		if (ct < 0) {
			pr_warn("event %zu (%.*s) creation failure, skipping\n",
				event_idx, nl, name);
			junk_events++;
		} else {
			event_attr_ct++;
			event_descs[desc_ct] = event_to_desc_attr(event, nonce);
			if (event_descs[desc_ct])
				desc_ct++;
			event_long_descs[long_desc_ct] =
					event_to_long_desc_attr(event, nonce);
			if (event_long_descs[long_desc_ct])
				long_desc_ct++;
		}
	}

	pr_info("read %zu catalog entries, created %zu event attrs (%zu failures), %zu descs\n",
			event_idx, event_attr_ct, junk_events, desc_ct);

	events[event_attr_ct] = NULL;
	event_descs[desc_ct] = NULL;
	event_long_descs[long_desc_ct] = NULL;

	event_uniq_destroy(&ev_uniq);
	vfree(event_data);
	kmem_cache_free(hv_page_cache, page);

	*events_ = events;
	*event_descs_ = event_descs;
	*event_long_descs_ = event_long_descs;
	return 0;

e_event_descs:
	kfree(event_descs);
e_event_attrs:
	kfree(events);
e_event_data:
	vfree(event_data);
e_free:
	kmem_cache_free(hv_page_cache, page);
e_out:
	*events_ = NULL;
	*event_descs_ = NULL;
	*event_long_descs_ = NULL;
	return ret;
}

static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
			    struct bin_attribute *bin_attr, char *buf,
			    loff_t offset, size_t count)
{
	long hret;
	ssize_t ret = 0;
	size_t catalog_len = 0, catalog_page_len = 0;
	loff_t page_offset = 0;
	loff_t offset_in_page;
	size_t copy_len;
	uint64_t catalog_version_num = 0;
	void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
	struct hv_24x7_catalog_page_0 *page_0 = page;

	if (!page)
		return -ENOMEM;

	hret = h_get_24x7_catalog_page(page, 0, 0);
	if (hret) {
		ret = -EIO;
		goto e_free;
	}

	catalog_version_num = be64_to_cpu(page_0->version);
	catalog_page_len = be32_to_cpu(page_0->length);
	catalog_len = catalog_page_len * 4096;

	page_offset = offset / 4096;
	offset_in_page = offset % 4096;

	if (page_offset >= catalog_page_len)
		goto e_free;

	if (page_offset != 0) {
		hret = h_get_24x7_catalog_page(page, catalog_version_num,
					       page_offset);
		if (hret) {
			ret = -EIO;
			goto e_free;
		}
	}

	copy_len = 4096 - offset_in_page;
	if (copy_len > count)
		copy_len = count;

	memcpy(buf, page+offset_in_page, copy_len);
	ret = copy_len;

e_free:
	if (hret)
		pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:"
		       " rc=%ld\n",
		       catalog_version_num, page_offset, hret);
	kmem_cache_free(hv_page_cache, page);

	pr_devel("catalog_read: offset=%lld(%lld) count=%zu "
			"catalog_len=%zu(%zu) => %zd\n", offset, page_offset,
			count, catalog_len, catalog_page_len, ret);

	return ret;
}

static ssize_t domains_show(struct device *dev, struct device_attribute *attr,
			    char *page)
{
	int d, n, count = 0;
	const char *str;

	for (d = 0; d < HV_PERF_DOMAIN_MAX; d++) {
		str = domain_name(d);
		if (!str)
			continue;

		n = sprintf(page, "%d: %s\n", d, str);
		if (n < 0)
			break;

		count += n;
		page += n;
	}
	return count;
}

#define PAGE_0_ATTR(_name, _fmt, _expr)				\
static ssize_t _name##_show(struct device *dev,			\
			    struct device_attribute *dev_attr,	\
			    char *buf)				\
{								\
	long hret;						\
	ssize_t ret = 0;					\
	void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);	\
	struct hv_24x7_catalog_page_0 *page_0 = page;		\
	if (!page)						\
		return -ENOMEM;					\
	hret = h_get_24x7_catalog_page(page, 0, 0);		\
	if (hret) {						\
		ret = -EIO;					\
		goto e_free;					\
	}							\
	ret = sprintf(buf, _fmt, _expr);			\
e_free:								\
	kmem_cache_free(hv_page_cache, page);			\
	return ret;						\
}								\
static DEVICE_ATTR_RO(_name)

PAGE_0_ATTR(catalog_version, "%lld\n",
		(unsigned long long)be64_to_cpu(page_0->version));
PAGE_0_ATTR(catalog_len, "%lld\n",
		(unsigned long long)be32_to_cpu(page_0->length) * 4096);
static BIN_ATTR_RO(catalog, 0/* real length varies */);
static DEVICE_ATTR_RO(domains);
static DEVICE_ATTR_RO(sockets);
static DEVICE_ATTR_RO(chipspersocket);
static DEVICE_ATTR_RO(coresperchip);
static DEVICE_ATTR_RO(cpumask);

static struct bin_attribute *if_bin_attrs[] = {
	&bin_attr_catalog,
	NULL,
};

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

static struct attribute_group cpumask_attr_group = {
	.attrs = cpumask_attrs,
};

static struct attribute *if_attrs[] = {
	&dev_attr_catalog_len.attr,
	&dev_attr_catalog_version.attr,
	&dev_attr_domains.attr,
	&dev_attr_sockets.attr,
	&dev_attr_chipspersocket.attr,
	&dev_attr_coresperchip.attr,
	NULL,
};

static struct attribute_group if_group = {
	.name = "interface",
	.bin_attrs = if_bin_attrs,
	.attrs = if_attrs,
};

static const struct attribute_group *attr_groups[] = {
	&format_group,
	&event_group,
	&event_desc_group,
	&event_long_desc_group,
	&if_group,
	&cpumask_attr_group,
	NULL,
};

/*
 * Start the process for a new H_GET_24x7_DATA hcall.
 */
static void init_24x7_request(struct hv_24x7_request_buffer *request_buffer,
			      struct hv_24x7_data_result_buffer *result_buffer)
{

	memset(request_buffer, 0, H24x7_DATA_BUFFER_SIZE);
	memset(result_buffer, 0, H24x7_DATA_BUFFER_SIZE);

	request_buffer->interface_version = interface_version;
	/* memset above set request_buffer->num_requests to 0 */
}

/*
 * Commit (i.e perform) the H_GET_24x7_DATA hcall using the data collected
 * by 'init_24x7_request()' and 'add_event_to_24x7_request()'.
 */
static int make_24x7_request(struct hv_24x7_request_buffer *request_buffer,
			     struct hv_24x7_data_result_buffer *result_buffer)
{
	long ret;

	/*
	 * NOTE: Due to variable number of array elements in request and
	 *	 result buffer(s), sizeof() is not reliable. Use the actual
	 *	 allocated buffer size, H24x7_DATA_BUFFER_SIZE.
	 */
	ret = plpar_hcall_norets(H_GET_24X7_DATA,
			virt_to_phys(request_buffer), H24x7_DATA_BUFFER_SIZE,
			virt_to_phys(result_buffer),  H24x7_DATA_BUFFER_SIZE);

	if (ret) {
		struct hv_24x7_request *req;

		req = request_buffer->requests;
		pr_notice_ratelimited("hcall failed: [%d %#x %#x %d] => ret 0x%lx (%ld) detail=0x%x failing ix=%x\n",
				      req->performance_domain, req->data_offset,
				      req->starting_ix, req->starting_lpar_ix,
				      ret, ret, result_buffer->detailed_rc,
				      result_buffer->failing_request_ix);
		return -EIO;
	}

	return 0;
}

/*
 * Add the given @event to the next slot in the 24x7 request_buffer.
 *
 * Note that H_GET_24X7_DATA hcall allows reading several counters'
 * values in a single HCALL. We expect the caller to add events to the
 * request buffer one by one, make the HCALL and process the results.
 */
static int add_event_to_24x7_request(struct perf_event *event,
				struct hv_24x7_request_buffer *request_buffer)
{
	u16 idx;
	int i;
	size_t req_size;
	struct hv_24x7_request *req;

	if (request_buffer->num_requests >=
	    max_num_requests(request_buffer->interface_version)) {
		pr_devel("Too many requests for 24x7 HCALL %d\n",
				request_buffer->num_requests);
		return -EINVAL;
	}

	switch (event_get_domain(event)) {
	case HV_PERF_DOMAIN_PHYS_CHIP:
		idx = event_get_chip(event);
		break;
	case HV_PERF_DOMAIN_PHYS_CORE:
		idx = event_get_core(event);
		break;
	default:
		idx = event_get_vcpu(event);
	}

	req_size = H24x7_REQUEST_SIZE(request_buffer->interface_version);

	i = request_buffer->num_requests++;
	req = (void *) request_buffer->requests + i * req_size;

	req->performance_domain = event_get_domain(event);
	req->data_size = cpu_to_be16(8);
	req->data_offset = cpu_to_be32(event_get_offset(event));
	req->starting_lpar_ix = cpu_to_be16(event_get_lpar(event));
	req->max_num_lpars = cpu_to_be16(1);
	req->starting_ix = cpu_to_be16(idx);
	req->max_ix = cpu_to_be16(1);

	if (request_buffer->interface_version > 1) {
		if (domain_needs_aggregation(req->performance_domain))
			req->max_num_thread_groups = -1;
		else if (req->performance_domain != HV_PERF_DOMAIN_PHYS_CHIP) {
			req->starting_thread_group_ix = idx % 2;
			req->max_num_thread_groups = 1;
		}
	}

	return 0;
}

/**
 * get_count_from_result - get event count from all result elements in result
 *
 * If the event corresponding to this result needs aggregation of the result
 * element values, then this function does that.
 *
 * @event:	Event associated with @res.
 * @resb:	Result buffer containing @res.
 * @res:	Result to work on.
 * @countp:	Output variable containing the event count.
 * @next:	Optional output variable pointing to the next result in @resb.
 */
static int get_count_from_result(struct perf_event *event,
				 struct hv_24x7_data_result_buffer *resb,
				 struct hv_24x7_result *res, u64 *countp,
				 struct hv_24x7_result **next)
{
	u16 num_elements = be16_to_cpu(res->num_elements_returned);
	u16 data_size = be16_to_cpu(res->result_element_data_size);
	unsigned int data_offset;
	void *element_data;
	int i;
	u64 count;

	/*
	 * We can bail out early if the result is empty.
	 */
	if (!num_elements) {
		pr_debug("Result of request %hhu is empty, nothing to do\n",
			 res->result_ix);

		if (next)
			*next = (struct hv_24x7_result *) res->elements;

		return -ENODATA;
	}

	/*
	 * Since we always specify 1 as the maximum for the smallest resource
	 * we're requesting, there should to be only one element per result.
	 * Except when an event needs aggregation, in which case there are more.
	 */
	if (num_elements != 1 &&
	    !domain_needs_aggregation(event_get_domain(event))) {
		pr_err("Error: result of request %hhu has %hu elements\n",
		       res->result_ix, num_elements);

		return -EIO;
	}

	if (data_size != sizeof(u64)) {
		pr_debug("Error: result of request %hhu has data of %hu bytes\n",
			 res->result_ix, data_size);

		return -ENOTSUPP;
	}

	if (resb->interface_version == 1)
		data_offset = offsetof(struct hv_24x7_result_element_v1,
				       element_data);
	else
		data_offset = offsetof(struct hv_24x7_result_element_v2,
				       element_data);

	/* Go through the result elements in the result. */
	for (i = count = 0, element_data = res->elements + data_offset;
	     i < num_elements;
	     i++, element_data += data_size + data_offset)
		count += be64_to_cpu(*((u64 *) element_data));

	*countp = count;

	/* The next result is after the last result element. */
	if (next)
		*next = element_data - data_offset;

	return 0;
}

static int single_24x7_request(struct perf_event *event, u64 *count)
{
	int ret;
	struct hv_24x7_request_buffer *request_buffer;
	struct hv_24x7_data_result_buffer *result_buffer;

	BUILD_BUG_ON(sizeof(*request_buffer) > 4096);
	BUILD_BUG_ON(sizeof(*result_buffer) > 4096);

	request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
	result_buffer = (void *)get_cpu_var(hv_24x7_resb);

	init_24x7_request(request_buffer, result_buffer);

	ret = add_event_to_24x7_request(event, request_buffer);
	if (ret)
		goto out;

	ret = make_24x7_request(request_buffer, result_buffer);
	if (ret)
		goto out;

	/* process result from hcall */
	ret = get_count_from_result(event, result_buffer,
				    result_buffer->results, count, NULL);

out:
	put_cpu_var(hv_24x7_reqb);
	put_cpu_var(hv_24x7_resb);
	return ret;
}


static int h_24x7_event_init(struct perf_event *event)
{
	struct hv_perf_caps caps;
	unsigned domain;
	unsigned long hret;
	u64 ct;

	/* Not our event */
	if (event->attr.type != event->pmu->type)
		return -ENOENT;

	/* Unused areas must be 0 */
	if (event_get_reserved1(event) ||
	    event_get_reserved2(event) ||
	    event_get_reserved3(event)) {
		pr_devel("reserved set when forbidden 0x%llx(0x%llx) 0x%llx(0x%llx) 0x%llx(0x%llx)\n",
				event->attr.config,
				event_get_reserved1(event),
				event->attr.config1,
				event_get_reserved2(event),
				event->attr.config2,
				event_get_reserved3(event));
		return -EINVAL;
	}

	/* no branch sampling */
	if (has_branch_stack(event))
		return -EOPNOTSUPP;

	/* offset must be 8 byte aligned */
	if (event_get_offset(event) % 8) {
		pr_devel("bad alignment\n");
		return -EINVAL;
	}

	domain = event_get_domain(event);
	if (domain  == 0 || domain >= HV_PERF_DOMAIN_MAX) {
		pr_devel("invalid domain %d\n", domain);
		return -EINVAL;
	}

	hret = hv_perf_caps_get(&caps);
	if (hret) {
		pr_devel("could not get capabilities: rc=%ld\n", hret);
		return -EIO;
	}

	/* Physical domains & other lpars require extra capabilities */
	if (!caps.collect_privileged && (is_physical_domain(domain) ||
		(event_get_lpar(event) != event_get_lpar_max()))) {
		pr_devel("hv permissions disallow: is_physical_domain:%d, lpar=0x%llx\n",
				is_physical_domain(domain),
				event_get_lpar(event));
		return -EACCES;
	}

	/* Get the initial value of the counter for this event */
	if (single_24x7_request(event, &ct)) {
		pr_devel("test hcall failed\n");
		return -EIO;
	}
	(void)local64_xchg(&event->hw.prev_count, ct);

	return 0;
}

static u64 h_24x7_get_value(struct perf_event *event)
{
	u64 ct;

	if (single_24x7_request(event, &ct))
		/* We checked this in event init, shouldn't fail here... */
		return 0;

	return ct;
}

static void update_event_count(struct perf_event *event, u64 now)
{
	s64 prev;

	prev = local64_xchg(&event->hw.prev_count, now);
	local64_add(now - prev, &event->count);
}

static void h_24x7_event_read(struct perf_event *event)
{
	u64 now;
	struct hv_24x7_request_buffer *request_buffer;
	struct hv_24x7_hw *h24x7hw;
	int txn_flags;

	txn_flags = __this_cpu_read(hv_24x7_txn_flags);

	/*
	 * If in a READ transaction, add this counter to the list of
	 * counters to read during the next HCALL (i.e commit_txn()).
	 * If not in a READ transaction, go ahead and make the HCALL
	 * to read this counter by itself.
	 */

	if (txn_flags & PERF_PMU_TXN_READ) {
		int i;
		int ret;

		if (__this_cpu_read(hv_24x7_txn_err))
			return;

		request_buffer = (void *)get_cpu_var(hv_24x7_reqb);

		ret = add_event_to_24x7_request(event, request_buffer);
		if (ret) {
			__this_cpu_write(hv_24x7_txn_err, ret);
		} else {
			/*
			 * Associate the event with the HCALL request index,
			 * so ->commit_txn() can quickly find/update count.
			 */
			i = request_buffer->num_requests - 1;

			h24x7hw = &get_cpu_var(hv_24x7_hw);
			h24x7hw->events[i] = event;
			put_cpu_var(h24x7hw);
		}

		put_cpu_var(hv_24x7_reqb);
	} else {
		now = h_24x7_get_value(event);
		update_event_count(event, now);
	}
}

static void h_24x7_event_start(struct perf_event *event, int flags)
{
	if (flags & PERF_EF_RELOAD)
		local64_set(&event->hw.prev_count, h_24x7_get_value(event));
}

static void h_24x7_event_stop(struct perf_event *event, int flags)
{
	h_24x7_event_read(event);
}

static int h_24x7_event_add(struct perf_event *event, int flags)
{
	if (flags & PERF_EF_START)
		h_24x7_event_start(event, flags);

	return 0;
}

/*
 * 24x7 counters only support READ transactions. They are
 * always counting and dont need/support ADD transactions.
 * Cache the flags, but otherwise ignore transactions that
 * are not PERF_PMU_TXN_READ.
 */
static void h_24x7_event_start_txn(struct pmu *pmu, unsigned int flags)
{
	struct hv_24x7_request_buffer *request_buffer;
	struct hv_24x7_data_result_buffer *result_buffer;

	/* We should not be called if we are already in a txn */
	WARN_ON_ONCE(__this_cpu_read(hv_24x7_txn_flags));

	__this_cpu_write(hv_24x7_txn_flags, flags);
	if (flags & ~PERF_PMU_TXN_READ)
		return;

	request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
	result_buffer = (void *)get_cpu_var(hv_24x7_resb);

	init_24x7_request(request_buffer, result_buffer);

	put_cpu_var(hv_24x7_resb);
	put_cpu_var(hv_24x7_reqb);
}

/*
 * Clean up transaction state.
 *
 * NOTE: Ignore state of request and result buffers for now.
 *	 We will initialize them during the next read/txn.
 */
static void reset_txn(void)
{
	__this_cpu_write(hv_24x7_txn_flags, 0);
	__this_cpu_write(hv_24x7_txn_err, 0);
}

/*
 * 24x7 counters only support READ transactions. They are always counting
 * and dont need/support ADD transactions. Clear ->txn_flags but otherwise
 * ignore transactions that are not of type PERF_PMU_TXN_READ.
 *
 * For READ transactions, submit all pending 24x7 requests (i.e requests
 * that were queued by h_24x7_event_read()), to the hypervisor and update
 * the event counts.
 */
static int h_24x7_event_commit_txn(struct pmu *pmu)
{
	struct hv_24x7_request_buffer *request_buffer;
	struct hv_24x7_data_result_buffer *result_buffer;
	struct hv_24x7_result *res, *next_res;
	u64 count;
	int i, ret, txn_flags;
	struct hv_24x7_hw *h24x7hw;

	txn_flags = __this_cpu_read(hv_24x7_txn_flags);
	WARN_ON_ONCE(!txn_flags);

	ret = 0;
	if (txn_flags & ~PERF_PMU_TXN_READ)
		goto out;

	ret = __this_cpu_read(hv_24x7_txn_err);
	if (ret)
		goto out;

	request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
	result_buffer = (void *)get_cpu_var(hv_24x7_resb);

	ret = make_24x7_request(request_buffer, result_buffer);
	if (ret)
		goto put_reqb;

	h24x7hw = &get_cpu_var(hv_24x7_hw);

	/* Go through results in the result buffer to update event counts. */
	for (i = 0, res = result_buffer->results;
	     i < result_buffer->num_results; i++, res = next_res) {
		struct perf_event *event = h24x7hw->events[res->result_ix];

		ret = get_count_from_result(event, result_buffer, res, &count,
					    &next_res);
		if (ret)
			break;

		update_event_count(event, count);
	}

	put_cpu_var(hv_24x7_hw);

put_reqb:
	put_cpu_var(hv_24x7_resb);
	put_cpu_var(hv_24x7_reqb);
out:
	reset_txn();
	return ret;
}

/*
 * 24x7 counters only support READ transactions. They are always counting
 * and dont need/support ADD transactions. However, regardless of type
 * of transaction, all we need to do is cleanup, so we don't have to check
 * the type of transaction.
 */
static void h_24x7_event_cancel_txn(struct pmu *pmu)
{
	WARN_ON_ONCE(!__this_cpu_read(hv_24x7_txn_flags));
	reset_txn();
}

static struct pmu h_24x7_pmu = {
	.task_ctx_nr = perf_invalid_context,

	.name = "hv_24x7",
	.attr_groups = attr_groups,
	.event_init  = h_24x7_event_init,
	.add         = h_24x7_event_add,
	.del         = h_24x7_event_stop,
	.start       = h_24x7_event_start,
	.stop        = h_24x7_event_stop,
	.read        = h_24x7_event_read,
	.start_txn   = h_24x7_event_start_txn,
	.commit_txn  = h_24x7_event_commit_txn,
	.cancel_txn  = h_24x7_event_cancel_txn,
	.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
};

static int ppc_hv_24x7_cpu_online(unsigned int cpu)
{
	if (cpumask_empty(&hv_24x7_cpumask))
		cpumask_set_cpu(cpu, &hv_24x7_cpumask);

	return 0;
}

static int ppc_hv_24x7_cpu_offline(unsigned int cpu)
{
	int target;

	/* Check if exiting cpu is used for collecting 24x7 events */
	if (!cpumask_test_and_clear_cpu(cpu, &hv_24x7_cpumask))
		return 0;

	/* Find a new cpu to collect 24x7 events */
	target = cpumask_last(cpu_active_mask);

	if (target < 0 || target >= nr_cpu_ids) {
		pr_err("hv_24x7: CPU hotplug init failed\n");
		return -1;
	}

	/* Migrate 24x7 events to the new target */
	cpumask_set_cpu(target, &hv_24x7_cpumask);
	perf_pmu_migrate_context(&h_24x7_pmu, cpu, target);

	return 0;
}

static int hv_24x7_cpu_hotplug_init(void)
{
	return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_HV_24x7_ONLINE,
			  "perf/powerpc/hv_24x7:online",
			  ppc_hv_24x7_cpu_online,
			  ppc_hv_24x7_cpu_offline);
}

static int hv_24x7_init(void)
{
	int r;
	unsigned long hret;
	struct hv_perf_caps caps;

	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
		pr_debug("not a virtualized system, not enabling\n");
		return -ENODEV;
	} else if (!cur_cpu_spec->oprofile_cpu_type)
		return -ENODEV;

	/* POWER8 only supports v1, while POWER9 only supports v2. */
	if (!strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8"))
		interface_version = 1;
	else {
		interface_version = 2;

		/* SMT8 in POWER9 needs to aggregate result elements. */
		if (threads_per_core == 8)
			aggregate_result_elements = true;
	}

	hret = hv_perf_caps_get(&caps);
	if (hret) {
		pr_debug("could not obtain capabilities, not enabling, rc=%ld\n",
				hret);
		return -ENODEV;
	}

	hv_page_cache = kmem_cache_create("hv-page-4096", 4096, 4096, 0, NULL);
	if (!hv_page_cache)
		return -ENOMEM;

	/* sampling not supported */
	h_24x7_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;

	r = create_events_from_catalog(&event_group.attrs,
				   &event_desc_group.attrs,
				   &event_long_desc_group.attrs);

	if (r)
		return r;

	/* init cpuhotplug */
	r = hv_24x7_cpu_hotplug_init();
	if (r)
		return r;

	r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1);
	if (r)
		return r;

	read_24x7_sys_info();

	return 0;
}

device_initcall(hv_24x7_init);
