1 /*
2  * Error log support on PowerNV.
3  *
4  * Copyright 2013,2014 IBM Corp.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/of.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/fs.h>
17 #include <linux/vmalloc.h>
18 #include <linux/fcntl.h>
19 #include <linux/kobject.h>
20 #include <asm/uaccess.h>
21 #include <asm/opal.h>
22 
23 struct elog_obj {
24 	struct kobject kobj;
25 	struct bin_attribute raw_attr;
26 	uint64_t id;
27 	uint64_t type;
28 	size_t size;
29 	char *buffer;
30 };
31 #define to_elog_obj(x) container_of(x, struct elog_obj, kobj)
32 
33 struct elog_attribute {
34 	struct attribute attr;
35 	ssize_t (*show)(struct elog_obj *elog, struct elog_attribute *attr,
36 			char *buf);
37 	ssize_t (*store)(struct elog_obj *elog, struct elog_attribute *attr,
38 			 const char *buf, size_t count);
39 };
40 #define to_elog_attr(x) container_of(x, struct elog_attribute, attr)
41 
42 static ssize_t elog_id_show(struct elog_obj *elog_obj,
43 			    struct elog_attribute *attr,
44 			    char *buf)
45 {
46 	return sprintf(buf, "0x%llx\n", elog_obj->id);
47 }
48 
49 static const char *elog_type_to_string(uint64_t type)
50 {
51 	switch (type) {
52 	case 0: return "PEL";
53 	default: return "unknown";
54 	}
55 }
56 
57 static ssize_t elog_type_show(struct elog_obj *elog_obj,
58 			      struct elog_attribute *attr,
59 			      char *buf)
60 {
61 	return sprintf(buf, "0x%llx %s\n",
62 		       elog_obj->type,
63 		       elog_type_to_string(elog_obj->type));
64 }
65 
66 static ssize_t elog_ack_show(struct elog_obj *elog_obj,
67 			     struct elog_attribute *attr,
68 			     char *buf)
69 {
70 	return sprintf(buf, "ack - acknowledge log message\n");
71 }
72 
73 static void delay_release_kobj(void *kobj)
74 {
75 	kobject_put((struct kobject *)kobj);
76 }
77 
78 static ssize_t elog_ack_store(struct elog_obj *elog_obj,
79 			      struct elog_attribute *attr,
80 			      const char *buf,
81 			      size_t count)
82 {
83 	opal_send_ack_elog(elog_obj->id);
84 	sysfs_schedule_callback(&elog_obj->kobj, delay_release_kobj,
85 				&elog_obj->kobj, THIS_MODULE);
86 	return count;
87 }
88 
89 static struct elog_attribute id_attribute =
90 	__ATTR(id, 0666, elog_id_show, NULL);
91 static struct elog_attribute type_attribute =
92 	__ATTR(type, 0666, elog_type_show, NULL);
93 static struct elog_attribute ack_attribute =
94 	__ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store);
95 
96 static struct kset *elog_kset;
97 
98 static ssize_t elog_attr_show(struct kobject *kobj,
99 			      struct attribute *attr,
100 			      char *buf)
101 {
102 	struct elog_attribute *attribute;
103 	struct elog_obj *elog;
104 
105 	attribute = to_elog_attr(attr);
106 	elog = to_elog_obj(kobj);
107 
108 	if (!attribute->show)
109 		return -EIO;
110 
111 	return attribute->show(elog, attribute, buf);
112 }
113 
114 static ssize_t elog_attr_store(struct kobject *kobj,
115 			       struct attribute *attr,
116 			       const char *buf, size_t len)
117 {
118 	struct elog_attribute *attribute;
119 	struct elog_obj *elog;
120 
121 	attribute = to_elog_attr(attr);
122 	elog = to_elog_obj(kobj);
123 
124 	if (!attribute->store)
125 		return -EIO;
126 
127 	return attribute->store(elog, attribute, buf, len);
128 }
129 
130 static const struct sysfs_ops elog_sysfs_ops = {
131 	.show = elog_attr_show,
132 	.store = elog_attr_store,
133 };
134 
135 static void elog_release(struct kobject *kobj)
136 {
137 	struct elog_obj *elog;
138 
139 	elog = to_elog_obj(kobj);
140 	kfree(elog->buffer);
141 	kfree(elog);
142 }
143 
144 static struct attribute *elog_default_attrs[] = {
145 	&id_attribute.attr,
146 	&type_attribute.attr,
147 	&ack_attribute.attr,
148 	NULL,
149 };
150 
151 static struct kobj_type elog_ktype = {
152 	.sysfs_ops = &elog_sysfs_ops,
153 	.release = &elog_release,
154 	.default_attrs = elog_default_attrs,
155 };
156 
157 /* Maximum size of a single log on FSP is 16KB */
158 #define OPAL_MAX_ERRLOG_SIZE	16384
159 
160 static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj,
161 			     struct bin_attribute *bin_attr,
162 			     char *buffer, loff_t pos, size_t count)
163 {
164 	int opal_rc;
165 
166 	struct elog_obj *elog = to_elog_obj(kobj);
167 
168 	/* We may have had an error reading before, so let's retry */
169 	if (!elog->buffer) {
170 		elog->buffer = kzalloc(elog->size, GFP_KERNEL);
171 		if (!elog->buffer)
172 			return -EIO;
173 
174 		opal_rc = opal_read_elog(__pa(elog->buffer),
175 					 elog->size, elog->id);
176 		if (opal_rc != OPAL_SUCCESS) {
177 			pr_err("ELOG: log read failed for log-id=%llx\n",
178 			       elog->id);
179 			kfree(elog->buffer);
180 			elog->buffer = NULL;
181 			return -EIO;
182 		}
183 	}
184 
185 	memcpy(buffer, elog->buffer + pos, count);
186 
187 	return count;
188 }
189 
190 static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
191 {
192 	struct elog_obj *elog;
193 	int rc;
194 
195 	elog = kzalloc(sizeof(*elog), GFP_KERNEL);
196 	if (!elog)
197 		return NULL;
198 
199 	elog->kobj.kset = elog_kset;
200 
201 	kobject_init(&elog->kobj, &elog_ktype);
202 
203 	sysfs_bin_attr_init(&elog->raw_attr);
204 
205 	elog->raw_attr.attr.name = "raw";
206 	elog->raw_attr.attr.mode = 0400;
207 	elog->raw_attr.size = size;
208 	elog->raw_attr.read = raw_attr_read;
209 
210 	elog->id = id;
211 	elog->size = size;
212 	elog->type = type;
213 
214 	elog->buffer = kzalloc(elog->size, GFP_KERNEL);
215 
216 	if (elog->buffer) {
217 		rc = opal_read_elog(__pa(elog->buffer),
218 					 elog->size, elog->id);
219 		if (rc != OPAL_SUCCESS) {
220 			pr_err("ELOG: log read failed for log-id=%llx\n",
221 			       elog->id);
222 			kfree(elog->buffer);
223 			elog->buffer = NULL;
224 		}
225 	}
226 
227 	rc = kobject_add(&elog->kobj, NULL, "0x%llx", id);
228 	if (rc) {
229 		kobject_put(&elog->kobj);
230 		return NULL;
231 	}
232 
233 	rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr);
234 	if (rc) {
235 		kobject_put(&elog->kobj);
236 		return NULL;
237 	}
238 
239 	kobject_uevent(&elog->kobj, KOBJ_ADD);
240 
241 	return elog;
242 }
243 
244 static void elog_work_fn(struct work_struct *work)
245 {
246 	size_t elog_size;
247 	uint64_t log_id;
248 	uint64_t elog_type;
249 	int rc;
250 	char name[2+16+1];
251 
252 	rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
253 	if (rc != OPAL_SUCCESS) {
254 		pr_err("ELOG: Opal log read failed\n");
255 		return;
256 	}
257 
258 	BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);
259 
260 	if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
261 		elog_size  =  OPAL_MAX_ERRLOG_SIZE;
262 
263 	sprintf(name, "0x%llx", log_id);
264 
265 	/* we may get notified twice, let's handle
266 	 * that gracefully and not create two conflicting
267 	 * entries.
268 	 */
269 	if (kset_find_obj(elog_kset, name))
270 		return;
271 
272 	create_elog_obj(log_id, elog_size, elog_type);
273 }
274 
275 static DECLARE_WORK(elog_work, elog_work_fn);
276 
277 static int elog_event(struct notifier_block *nb,
278 				unsigned long events, void *change)
279 {
280 	/* check for error log event */
281 	if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
282 		schedule_work(&elog_work);
283 	return 0;
284 }
285 
286 static struct notifier_block elog_nb = {
287 	.notifier_call  = elog_event,
288 	.next           = NULL,
289 	.priority       = 0
290 };
291 
292 int __init opal_elog_init(void)
293 {
294 	int rc = 0;
295 
296 	elog_kset = kset_create_and_add("elog", NULL, opal_kobj);
297 	if (!elog_kset) {
298 		pr_warn("%s: failed to create elog kset\n", __func__);
299 		return -1;
300 	}
301 
302 	rc = opal_notifier_register(&elog_nb);
303 	if (rc) {
304 		pr_err("%s: Can't register OPAL event notifier (%d)\n",
305 		__func__, rc);
306 		return rc;
307 	}
308 
309 	/* We are now ready to pull error logs from opal. */
310 	opal_resend_pending_logs();
311 
312 	return 0;
313 }
314