[v7] powerpc/powernv: add hdat attribute to sysfs

Andrew Donnellan andrew.donnellan at au1.ibm.com
Thu Mar 23 12:12:28 AEDT 2017


On 23/03/17 09:27, Matt Brown wrote:
> The HDAT data area is consumed by skiboot and turned into a device-tree.
> In some cases we would like to look directly at the HDAT, so this patch
> adds a sysfs node to allow it to be viewed.  This is not possible through
> /dev/mem as it is reserved memory which is stopped by the /dev/mem filter.
>
> Signed-off-by: Matt Brown <matthew.brown.dev at gmail.com>

Reviewed-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>

> ---
> Changelog:
>
> v7:	
> 	- moved exported_attrs and attr_name into opal_export_attrs
> ---
>  arch/powerpc/platforms/powernv/opal.c | 84 +++++++++++++++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
>
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index 2822935..b8f057f 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -604,6 +604,87 @@ static void opal_export_symmap(void)
>  		pr_warn("Error %d creating OPAL symbols file\n", rc);
>  }
>
> +static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
> +			     struct bin_attribute *bin_attr, char *buf,
> +			     loff_t off, size_t count)
> +{
> +	return memory_read_from_buffer(buf, count, &off, bin_attr->private,
> +				       bin_attr->size);
> +}
> +
> +/*
> + * opal_export_attrs: creates a sysfs node for each property listed in
> + * the device-tree under /ibm,opal/firmware/exports/
> + * All new sysfs nodes are created under /opal/exports/.
> + * This allows for reserved memory regions (e.g. HDAT) to be read.
> + * The new sysfs nodes are only readable by root.
> + */
> +static void opal_export_attrs(void)
> +{
> +	/* /sys/firmware/opal/exports */
> +	struct kobject *opal_export_kobj;
> +	struct bin_attribute *exported_attrs;
> +	char **attr_name;
> +
> +	struct bin_attribute *attr_tmp;
> +	const __be64 *syms;
> +	unsigned int size;
> +	struct device_node *fw;
> +	struct property *prop;
> +	int rc;
> +	int attr_count = 0;
> +	int n = 0;
> +
> +	/* Create new 'exports' directory */
> +	opal_export_kobj = kobject_create_and_add("exports", opal_kobj);
> +	if (!opal_export_kobj) {
> +		pr_warn("kobject_create_and_add opal_exports failed\n");
> +		return;
> +	}
> +
> +	fw = of_find_node_by_path("/ibm,opal/firmware/exports");
> +	if (!fw)
> +		return;
> +
> +	for (prop = fw->properties; prop != NULL; prop = prop->next)
> +		attr_count++;
> +
> +	if (attr_count > 2) {
> +		exported_attrs = kzalloc(sizeof(exported_attrs)*(attr_count-2),
> +				GFP_KERNEL);
> +		attr_name = kzalloc(sizeof(char *)*(attr_count-2), GFP_KERNEL);
> +	}
> +
> +	for_each_property_of_node(fw, prop) {
> +
> +		attr_name[n] = kstrdup(prop->name, GFP_KERNEL);
> +		syms = of_get_property(fw, attr_name[n], &size);
> +
> +		if (!strcmp(attr_name[n], "name") ||
> +				!strcmp(attr_name[n], "phandle"))
> +			continue;
> +
> +		if (!syms || size != 2 * sizeof(__be64))
> +			continue;
> +
> +		attr_tmp = &exported_attrs[n];
> +		attr_tmp->attr.name = attr_name[n];
> +		attr_tmp->attr.mode = 0400;
> +		attr_tmp->read = export_attr_read;
> +		attr_tmp->private = __va(be64_to_cpu(syms[0]));
> +		attr_tmp->size = be64_to_cpu(syms[1]);
> +
> +		rc = sysfs_create_bin_file(opal_export_kobj, attr_tmp);
> +		if (rc)
> +			pr_warn("Error %d creating OPAL sysfs exports/%s file\n",
> +					rc, attr_name[n]);
> +		n++;
> +	}
> +
> +	of_node_put(fw);
> +
> +}
> +
>  static void __init opal_dump_region_init(void)
>  {
>  	void *addr;
> @@ -742,6 +823,9 @@ static int __init opal_init(void)
>  		opal_msglog_sysfs_init();
>  	}
>
> +	/* Export all properties */
> +	opal_export_attrs();
> +
>  	/* Initialize platform devices: IPMI backend, PRD & flash interface */
>  	opal_pdev_init("ibm,opal-ipmi");
>  	opal_pdev_init("ibm,opal-flash");
>

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan at au1.ibm.com  IBM Australia Limited



More information about the Linuxppc-dev mailing list