// SPDX-License-Identifier: GPL-2.0-only
/*
 *  copyright (c) 2006 IBM Corporation
 *  Authored by: Mike D. Day <ncmike@us.ibm.com>
 */

#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/err.h>

#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>

#include <xen/xen.h>
#include <xen/xenbus.h>
#include <xen/interface/xen.h>
#include <xen/interface/version.h>
#ifdef CONFIG_XEN_HAVE_VPMU
#include <xen/interface/xenpmu.h>
#endif

#define HYPERVISOR_ATTR_RO(_name) \
static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name)

#define HYPERVISOR_ATTR_RW(_name) \
static struct hyp_sysfs_attr _name##_attr = __ATTR_RW(_name)

struct hyp_sysfs_attr {
	struct attribute attr;
	ssize_t (*show)(struct hyp_sysfs_attr *, char *);
	ssize_t (*store)(struct hyp_sysfs_attr *, const char *, size_t);
	union {
		void *hyp_attr_data;
		unsigned long hyp_attr_value;
	};
};

static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	return sprintf(buffer, "xen\n");
}

HYPERVISOR_ATTR_RO(type);

static int __init xen_sysfs_type_init(void)
{
	return sysfs_create_file(hypervisor_kobj, &type_attr.attr);
}

static ssize_t guest_type_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	const char *type;

	switch (xen_domain_type) {
	case XEN_NATIVE:
		/* ARM only. */
		type = "Xen";
		break;
	case XEN_PV_DOMAIN:
		type = "PV";
		break;
	case XEN_HVM_DOMAIN:
		type = xen_pvh_domain() ? "PVH" : "HVM";
		break;
	default:
		return -EINVAL;
	}

	return sprintf(buffer, "%s\n", type);
}

HYPERVISOR_ATTR_RO(guest_type);

static int __init xen_sysfs_guest_type_init(void)
{
	return sysfs_create_file(hypervisor_kobj, &guest_type_attr.attr);
}

/* xen version attributes */
static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int version = HYPERVISOR_xen_version(XENVER_version, NULL);
	if (version)
		return sprintf(buffer, "%d\n", version >> 16);
	return -ENODEV;
}

HYPERVISOR_ATTR_RO(major);

static ssize_t minor_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int version = HYPERVISOR_xen_version(XENVER_version, NULL);
	if (version)
		return sprintf(buffer, "%d\n", version & 0xff);
	return -ENODEV;
}

HYPERVISOR_ATTR_RO(minor);

static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	char *extra;

	extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
	if (extra) {
		ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
		if (!ret)
			ret = sprintf(buffer, "%s\n", extra);
		kfree(extra);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(extra);

static struct attribute *version_attrs[] = {
	&major_attr.attr,
	&minor_attr.attr,
	&extra_attr.attr,
	NULL
};

static const struct attribute_group version_group = {
	.name = "version",
	.attrs = version_attrs,
};

static int __init xen_sysfs_version_init(void)
{
	return sysfs_create_group(hypervisor_kobj, &version_group);
}

/* UUID */

static ssize_t uuid_show_fallback(struct hyp_sysfs_attr *attr, char *buffer)
{
	char *vm, *val;
	int ret;
	extern int xenstored_ready;

	if (!xenstored_ready)
		return -EBUSY;

	vm = xenbus_read(XBT_NIL, "vm", "", NULL);
	if (IS_ERR(vm))
		return PTR_ERR(vm);
	val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
	kfree(vm);
	if (IS_ERR(val))
		return PTR_ERR(val);
	ret = sprintf(buffer, "%s\n", val);
	kfree(val);
	return ret;
}

static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	xen_domain_handle_t uuid;
	int ret;
	ret = HYPERVISOR_xen_version(XENVER_guest_handle, uuid);
	if (ret)
		return uuid_show_fallback(attr, buffer);
	ret = sprintf(buffer, "%pU\n", uuid);
	return ret;
}

HYPERVISOR_ATTR_RO(uuid);

static int __init xen_sysfs_uuid_init(void)
{
	return sysfs_create_file(hypervisor_kobj, &uuid_attr.attr);
}

/* xen compilation attributes */

static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	struct xen_compile_info *info;

	info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
	if (info) {
		ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
		if (!ret)
			ret = sprintf(buffer, "%s\n", info->compiler);
		kfree(info);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(compiler);

static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	struct xen_compile_info *info;

	info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
	if (info) {
		ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
		if (!ret)
			ret = sprintf(buffer, "%s\n", info->compile_by);
		kfree(info);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(compiled_by);

static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	struct xen_compile_info *info;

	info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
	if (info) {
		ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
		if (!ret)
			ret = sprintf(buffer, "%s\n", info->compile_date);
		kfree(info);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(compile_date);

static struct attribute *xen_compile_attrs[] = {
	&compiler_attr.attr,
	&compiled_by_attr.attr,
	&compile_date_attr.attr,
	NULL
};

static const struct attribute_group xen_compilation_group = {
	.name = "compilation",
	.attrs = xen_compile_attrs,
};

static int __init xen_sysfs_compilation_init(void)
{
	return sysfs_create_group(hypervisor_kobj, &xen_compilation_group);
}

/* xen properties info */

static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	char *caps;

	caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
	if (caps) {
		ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
		if (!ret)
			ret = sprintf(buffer, "%s\n", caps);
		kfree(caps);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(capabilities);

static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	char *cset;

	cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
	if (cset) {
		ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
		if (!ret)
			ret = sprintf(buffer, "%s\n", cset);
		kfree(cset);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(changeset);

static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret = -ENOMEM;
	struct xen_platform_parameters *parms;

	parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
	if (parms) {
		ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
					     parms);
		if (!ret)
			ret = sprintf(buffer, "%"PRI_xen_ulong"\n",
				      parms->virt_start);
		kfree(parms);
	}

	return ret;
}

HYPERVISOR_ATTR_RO(virtual_start);

static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret;

	ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
	if (ret > 0)
		ret = sprintf(buffer, "%x\n", ret);

	return ret;
}

HYPERVISOR_ATTR_RO(pagesize);

static ssize_t xen_feature_show(int index, char *buffer)
{
	ssize_t ret;
	struct xen_feature_info info;

	info.submap_idx = index;
	ret = HYPERVISOR_xen_version(XENVER_get_features, &info);
	if (!ret)
		ret = sprintf(buffer, "%08x", info.submap);

	return ret;
}

static ssize_t features_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	ssize_t len;
	int i;

	len = 0;
	for (i = XENFEAT_NR_SUBMAPS-1; i >= 0; i--) {
		int ret = xen_feature_show(i, buffer + len);
		if (ret < 0) {
			if (len == 0)
				len = ret;
			break;
		}
		len += ret;
	}
	if (len > 0)
		buffer[len++] = '\n';

	return len;
}

HYPERVISOR_ATTR_RO(features);

static ssize_t buildid_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	ssize_t ret;
	struct xen_build_id *buildid;

	ret = HYPERVISOR_xen_version(XENVER_build_id, NULL);
	if (ret < 0) {
		if (ret == -EPERM)
			ret = sprintf(buffer, "<denied>");
		return ret;
	}

	buildid = kmalloc(sizeof(*buildid) + ret, GFP_KERNEL);
	if (!buildid)
		return -ENOMEM;

	buildid->len = ret;
	ret = HYPERVISOR_xen_version(XENVER_build_id, buildid);
	if (ret > 0)
		ret = sprintf(buffer, "%s", buildid->buf);
	kfree(buildid);

	return ret;
}

HYPERVISOR_ATTR_RO(buildid);

static struct attribute *xen_properties_attrs[] = {
	&capabilities_attr.attr,
	&changeset_attr.attr,
	&virtual_start_attr.attr,
	&pagesize_attr.attr,
	&features_attr.attr,
	&buildid_attr.attr,
	NULL
};

static const struct attribute_group xen_properties_group = {
	.name = "properties",
	.attrs = xen_properties_attrs,
};

static int __init xen_sysfs_properties_init(void)
{
	return sysfs_create_group(hypervisor_kobj, &xen_properties_group);
}

#define FLAG_UNAME "unknown"
#define FLAG_UNAME_FMT FLAG_UNAME "%02u"
#define FLAG_UNAME_MAX sizeof(FLAG_UNAME "XX")
#define FLAG_COUNT (sizeof(xen_start_flags) * BITS_PER_BYTE)
static_assert(sizeof(xen_start_flags) <=
	      sizeof_field(struct hyp_sysfs_attr, hyp_attr_value));

static ssize_t flag_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	char *p = buffer;

	*p++ = '0' + ((xen_start_flags & attr->hyp_attr_value) != 0);
	*p++ = '\n';
	return p - buffer;
}

#define FLAG_NODE(flag, node)				\
	[ilog2(flag)] = {				\
		.attr = { .name = #node, .mode = 0444 },\
		.show = flag_show,			\
		.hyp_attr_value = flag			\
	}

/*
 * Add new, known flags here.  No other changes are required, but
 * note that each known flag wastes one entry in flag_unames[].
 * The code/complexity machinations to avoid this isn't worth it
 * for a few entries, but keep it in mind.
 */
static struct hyp_sysfs_attr flag_attrs[FLAG_COUNT] = {
	FLAG_NODE(SIF_PRIVILEGED, privileged),
	FLAG_NODE(SIF_INITDOMAIN, initdomain)
};
static struct attribute_group xen_flags_group = {
	.name = "start_flags",
	.attrs = (struct attribute *[FLAG_COUNT + 1]){}
};
static char flag_unames[FLAG_COUNT][FLAG_UNAME_MAX];

static int __init xen_sysfs_flags_init(void)
{
	for (unsigned fnum = 0; fnum != FLAG_COUNT; fnum++) {
		if (likely(flag_attrs[fnum].attr.name == NULL)) {
			sprintf(flag_unames[fnum], FLAG_UNAME_FMT, fnum);
			flag_attrs[fnum].attr.name = flag_unames[fnum];
			flag_attrs[fnum].attr.mode = 0444;
			flag_attrs[fnum].show = flag_show;
			flag_attrs[fnum].hyp_attr_value = 1 << fnum;
		}
		xen_flags_group.attrs[fnum] = &flag_attrs[fnum].attr;
	}
	return sysfs_create_group(hypervisor_kobj, &xen_flags_group);
}

#ifdef CONFIG_XEN_HAVE_VPMU
struct pmu_mode {
	const char *name;
	uint32_t mode;
};

static struct pmu_mode pmu_modes[] = {
	{"off", XENPMU_MODE_OFF},
	{"self", XENPMU_MODE_SELF},
	{"hv", XENPMU_MODE_HV},
	{"all", XENPMU_MODE_ALL}
};

static ssize_t pmu_mode_store(struct hyp_sysfs_attr *attr,
			      const char *buffer, size_t len)
{
	int ret;
	struct xen_pmu_params xp;
	int i;

	for (i = 0; i < ARRAY_SIZE(pmu_modes); i++) {
		if (strncmp(buffer, pmu_modes[i].name, len - 1) == 0) {
			xp.val = pmu_modes[i].mode;
			break;
		}
	}

	if (i == ARRAY_SIZE(pmu_modes))
		return -EINVAL;

	xp.version.maj = XENPMU_VER_MAJ;
	xp.version.min = XENPMU_VER_MIN;
	ret = HYPERVISOR_xenpmu_op(XENPMU_mode_set, &xp);
	if (ret)
		return ret;

	return len;
}

static ssize_t pmu_mode_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret;
	struct xen_pmu_params xp;
	int i;
	uint32_t mode;

	xp.version.maj = XENPMU_VER_MAJ;
	xp.version.min = XENPMU_VER_MIN;
	ret = HYPERVISOR_xenpmu_op(XENPMU_mode_get, &xp);
	if (ret)
		return ret;

	mode = (uint32_t)xp.val;
	for (i = 0; i < ARRAY_SIZE(pmu_modes); i++) {
		if (mode == pmu_modes[i].mode)
			return sprintf(buffer, "%s\n", pmu_modes[i].name);
	}

	return -EINVAL;
}
HYPERVISOR_ATTR_RW(pmu_mode);

static ssize_t pmu_features_store(struct hyp_sysfs_attr *attr,
				  const char *buffer, size_t len)
{
	int ret;
	uint32_t features;
	struct xen_pmu_params xp;

	ret = kstrtou32(buffer, 0, &features);
	if (ret)
		return ret;

	xp.val = features;
	xp.version.maj = XENPMU_VER_MAJ;
	xp.version.min = XENPMU_VER_MIN;
	ret = HYPERVISOR_xenpmu_op(XENPMU_feature_set, &xp);
	if (ret)
		return ret;

	return len;
}

static ssize_t pmu_features_show(struct hyp_sysfs_attr *attr, char *buffer)
{
	int ret;
	struct xen_pmu_params xp;

	xp.version.maj = XENPMU_VER_MAJ;
	xp.version.min = XENPMU_VER_MIN;
	ret = HYPERVISOR_xenpmu_op(XENPMU_feature_get, &xp);
	if (ret)
		return ret;

	return sprintf(buffer, "0x%x\n", (uint32_t)xp.val);
}
HYPERVISOR_ATTR_RW(pmu_features);

static struct attribute *xen_pmu_attrs[] = {
	&pmu_mode_attr.attr,
	&pmu_features_attr.attr,
	NULL
};

static const struct attribute_group xen_pmu_group = {
	.name = "pmu",
	.attrs = xen_pmu_attrs,
};

static int __init xen_sysfs_pmu_init(void)
{
	return sysfs_create_group(hypervisor_kobj, &xen_pmu_group);
}
#endif

static int __init hyper_sysfs_init(void)
{
	int ret;

	if (!xen_domain())
		return -ENODEV;

	ret = xen_sysfs_type_init();
	if (ret)
		goto out;
	ret = xen_sysfs_guest_type_init();
	if (ret)
		goto guest_type_out;
	ret = xen_sysfs_version_init();
	if (ret)
		goto version_out;
	ret = xen_sysfs_compilation_init();
	if (ret)
		goto comp_out;
	ret = xen_sysfs_uuid_init();
	if (ret)
		goto uuid_out;
	ret = xen_sysfs_properties_init();
	if (ret)
		goto prop_out;
	ret = xen_sysfs_flags_init();
	if (ret)
		goto flags_out;
#ifdef CONFIG_XEN_HAVE_VPMU
	if (xen_initial_domain()) {
		ret = xen_sysfs_pmu_init();
		if (ret) {
			sysfs_remove_group(hypervisor_kobj, &xen_flags_group);
			goto flags_out;
		}
	}
#endif
	goto out;

flags_out:
	sysfs_remove_group(hypervisor_kobj, &xen_properties_group);
prop_out:
	sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr);
uuid_out:
	sysfs_remove_group(hypervisor_kobj, &xen_compilation_group);
comp_out:
	sysfs_remove_group(hypervisor_kobj, &version_group);
version_out:
	sysfs_remove_file(hypervisor_kobj, &guest_type_attr.attr);
guest_type_out:
	sysfs_remove_file(hypervisor_kobj, &type_attr.attr);
out:
	return ret;
}
device_initcall(hyper_sysfs_init);

static ssize_t hyp_sysfs_show(struct kobject *kobj,
			      struct attribute *attr,
			      char *buffer)
{
	struct hyp_sysfs_attr *hyp_attr;
	hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr);
	if (hyp_attr->show)
		return hyp_attr->show(hyp_attr, buffer);
	return 0;
}

static ssize_t hyp_sysfs_store(struct kobject *kobj,
			       struct attribute *attr,
			       const char *buffer,
			       size_t len)
{
	struct hyp_sysfs_attr *hyp_attr;
	hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr);
	if (hyp_attr->store)
		return hyp_attr->store(hyp_attr, buffer, len);
	return 0;
}

static const struct sysfs_ops hyp_sysfs_ops = {
	.show = hyp_sysfs_show,
	.store = hyp_sysfs_store,
};

static const struct kobj_type hyp_sysfs_kobj_type = {
	.sysfs_ops = &hyp_sysfs_ops,
};

static int __init hypervisor_subsys_init(void)
{
	if (!xen_domain())
		return -ENODEV;

	hypervisor_kobj->ktype = &hyp_sysfs_kobj_type;
	return 0;
}
device_initcall(hypervisor_subsys_init);
