blob: d31ee40f7a6e7a1f22e0b674a3505b456034489d [file] [log] [blame]
Joel Stanley6a0ced92017-05-03 13:41:44 +09301From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Matt Brown <matthew.brown.dev@gmail.com>
3Date: Thu, 30 Mar 2017 10:28:01 +1100
4Subject: [PATCH 3/4] powerpc/powernv: Add OPAL exports attributes to sysfs
5
6New versions of OPAL have a device node /ibm,opal/firmware/exports, each
7property of which describes a range of memory in OPAL that Linux might
8want to export to userspace for debugging.
9
10This patch adds a sysfs file under 'opal/exports' for each property
11found there, and makes it read-only by root.
12
13Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
14[mpe: Drop counting of props, rename to attr, free on sysfs error, c'log]
15Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
16(cherry picked from commit 11fe909d236263f62808dc3c73caf798e026d7aa)
17Signed-off-by: Joel Stanley <joel@jms.id.au>
18
19Signed-off-by: Joel Stanley <joel@jms.id.au>
20---
21 arch/powerpc/platforms/powernv/opal.c | 76 +++++++++++++++++++++++++++++++++++
22 1 file changed, 76 insertions(+)
23
24diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
25index e0f856bfbfe8..25ea8f6fe7f8 100644
26--- a/arch/powerpc/platforms/powernv/opal.c
27+++ b/arch/powerpc/platforms/powernv/opal.c
28@@ -595,6 +595,79 @@ static void opal_export_symmap(void)
29 pr_warn("Error %d creating OPAL symbols file\n", rc);
30 }
31
32+static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
33+ struct bin_attribute *bin_attr, char *buf,
34+ loff_t off, size_t count)
35+{
36+ return memory_read_from_buffer(buf, count, &off, bin_attr->private,
37+ bin_attr->size);
38+}
39+
40+/*
41+ * opal_export_attrs: creates a sysfs node for each property listed in
42+ * the device-tree under /ibm,opal/firmware/exports/
43+ * All new sysfs nodes are created under /opal/exports/.
44+ * This allows for reserved memory regions (e.g. HDAT) to be read.
45+ * The new sysfs nodes are only readable by root.
46+ */
47+static void opal_export_attrs(void)
48+{
49+ struct bin_attribute *attr;
50+ struct device_node *np;
51+ struct property *prop;
52+ struct kobject *kobj;
53+ u64 vals[2];
54+ int rc;
55+
56+ np = of_find_node_by_path("/ibm,opal/firmware/exports");
57+ if (!np)
58+ return;
59+
60+ /* Create new 'exports' directory - /sys/firmware/opal/exports */
61+ kobj = kobject_create_and_add("exports", opal_kobj);
62+ if (!kobj) {
63+ pr_warn("kobject_create_and_add() of exports failed\n");
64+ return;
65+ }
66+
67+ for_each_property_of_node(np, prop) {
68+ if (!strcmp(prop->name, "name") || !strcmp(prop->name, "phandle"))
69+ continue;
70+
71+ if (of_property_read_u64_array(np, prop->name, &vals[0], 2))
72+ continue;
73+
74+ attr = kmalloc(sizeof(*attr), GFP_KERNEL);
75+
76+ if (attr == NULL) {
77+ pr_warn("Failed kmalloc for bin_attribute!");
78+ continue;
79+ }
80+
81+ attr->attr.name = kstrdup(prop->name, GFP_KERNEL);
82+ attr->attr.mode = 0400;
83+ attr->read = export_attr_read;
84+ attr->private = __va(vals[0]);
85+ attr->size = vals[1];
86+
87+ if (attr->attr.name == NULL) {
88+ pr_warn("Failed kstrdup for bin_attribute attr.name");
89+ kfree(attr);
90+ continue;
91+ }
92+
93+ rc = sysfs_create_bin_file(kobj, attr);
94+ if (rc) {
95+ pr_warn("Error %d creating OPAL sysfs exports/%s file\n",
96+ rc, prop->name);
97+ kfree(attr->attr.name);
98+ kfree(attr);
99+ }
100+ }
101+
102+ of_node_put(np);
103+}
104+
105 static void __init opal_dump_region_init(void)
106 {
107 void *addr;
108@@ -733,6 +806,9 @@ static int __init opal_init(void)
109 opal_msglog_sysfs_init();
110 }
111
112+ /* Export all properties */
113+ opal_export_attrs();
114+
115 /* Initialize platform devices: IPMI backend, PRD & flash interface */
116 opal_pdev_init("ibm,opal-ipmi");
117 opal_pdev_init("ibm,opal-flash");
118--
1192.11.0
120