Skip to content

Commit 11fe909

Browse files
m-browmpe
authored andcommitted
powerpc/powernv: Add OPAL exports attributes to sysfs
New versions of OPAL have a device node /ibm,opal/firmware/exports, each property of which describes a range of memory in OPAL that Linux might want to export to userspace for debugging. This patch adds a sysfs file under 'opal/exports' for each property found there, and makes it read-only by root. Signed-off-by: Matt Brown <[email protected]> [mpe: Drop counting of props, rename to attr, free on sysfs error, c'log] Signed-off-by: Michael Ellerman <[email protected]>
1 parent 687da8f commit 11fe909

File tree

1 file changed

+76
-0
lines changed
  • arch/powerpc/platforms/powernv

1 file changed

+76
-0
lines changed

arch/powerpc/platforms/powernv/opal.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,79 @@ static void opal_export_symmap(void)
595595
pr_warn("Error %d creating OPAL symbols file\n", rc);
596596
}
597597

598+
static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
599+
struct bin_attribute *bin_attr, char *buf,
600+
loff_t off, size_t count)
601+
{
602+
return memory_read_from_buffer(buf, count, &off, bin_attr->private,
603+
bin_attr->size);
604+
}
605+
606+
/*
607+
* opal_export_attrs: creates a sysfs node for each property listed in
608+
* the device-tree under /ibm,opal/firmware/exports/
609+
* All new sysfs nodes are created under /opal/exports/.
610+
* This allows for reserved memory regions (e.g. HDAT) to be read.
611+
* The new sysfs nodes are only readable by root.
612+
*/
613+
static void opal_export_attrs(void)
614+
{
615+
struct bin_attribute *attr;
616+
struct device_node *np;
617+
struct property *prop;
618+
struct kobject *kobj;
619+
u64 vals[2];
620+
int rc;
621+
622+
np = of_find_node_by_path("/ibm,opal/firmware/exports");
623+
if (!np)
624+
return;
625+
626+
/* Create new 'exports' directory - /sys/firmware/opal/exports */
627+
kobj = kobject_create_and_add("exports", opal_kobj);
628+
if (!kobj) {
629+
pr_warn("kobject_create_and_add() of exports failed\n");
630+
return;
631+
}
632+
633+
for_each_property_of_node(np, prop) {
634+
if (!strcmp(prop->name, "name") || !strcmp(prop->name, "phandle"))
635+
continue;
636+
637+
if (of_property_read_u64_array(np, prop->name, &vals[0], 2))
638+
continue;
639+
640+
attr = kmalloc(sizeof(*attr), GFP_KERNEL);
641+
642+
if (attr == NULL) {
643+
pr_warn("Failed kmalloc for bin_attribute!");
644+
continue;
645+
}
646+
647+
attr->attr.name = kstrdup(prop->name, GFP_KERNEL);
648+
attr->attr.mode = 0400;
649+
attr->read = export_attr_read;
650+
attr->private = __va(vals[0]);
651+
attr->size = vals[1];
652+
653+
if (attr->attr.name == NULL) {
654+
pr_warn("Failed kstrdup for bin_attribute attr.name");
655+
kfree(attr);
656+
continue;
657+
}
658+
659+
rc = sysfs_create_bin_file(kobj, attr);
660+
if (rc) {
661+
pr_warn("Error %d creating OPAL sysfs exports/%s file\n",
662+
rc, prop->name);
663+
kfree(attr->attr.name);
664+
kfree(attr);
665+
}
666+
}
667+
668+
of_node_put(np);
669+
}
670+
598671
static void __init opal_dump_region_init(void)
599672
{
600673
void *addr;
@@ -733,6 +806,9 @@ static int __init opal_init(void)
733806
opal_msglog_sysfs_init();
734807
}
735808

809+
/* Export all properties */
810+
opal_export_attrs();
811+
736812
/* Initialize platform devices: IPMI backend, PRD & flash interface */
737813
opal_pdev_init("ibm,opal-ipmi");
738814
opal_pdev_init("ibm,opal-flash");

0 commit comments

Comments
 (0)