diff options
| author | Dmitry Torokhov <[email protected]> | 2023-05-01 15:20:08 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-05-01 15:20:08 -0700 | 
| commit | 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e (patch) | |
| tree | d57f3a63479a07b4e0cece029886e76e04feb984 /drivers/xen/sys-hypervisor.c | |
| parent | 5dc63e56a9cf8df0b59c234a505a1653f1bdf885 (diff) | |
| parent | 53bea86b5712c7491bb3dae12e271666df0a308c (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.4 merge window.
Diffstat (limited to 'drivers/xen/sys-hypervisor.c')
| -rw-r--r-- | drivers/xen/sys-hypervisor.c | 71 | 
1 files changed, 66 insertions, 5 deletions
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index fcb0792f090e..2f880374b463 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c @@ -31,7 +31,10 @@ 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); -	void *hyp_attr_data; +	union { +		void *hyp_attr_data; +		unsigned long hyp_attr_value; +	};  };  static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer) @@ -399,6 +402,60 @@ 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; @@ -539,18 +596,22 @@ static int __init hyper_sysfs_init(void)  	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_properties_group); -			goto prop_out; +			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: @@ -594,7 +655,7 @@ static const struct sysfs_ops hyp_sysfs_ops = {  	.store = hyp_sysfs_store,  }; -static struct kobj_type hyp_sysfs_kobj_type = { +static const struct kobj_type hyp_sysfs_kobj_type = {  	.sysfs_ops = &hyp_sysfs_ops,  };  |