1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * Error log support on PowerNV.
4   *
5   * Copyright 2013,2014 IBM Corp.
6   */
7  #include <linux/kernel.h>
8  #include <linux/init.h>
9  #include <linux/interrupt.h>
10  #include <linux/of.h>
11  #include <linux/slab.h>
12  #include <linux/sysfs.h>
13  #include <linux/fs.h>
14  #include <linux/vmalloc.h>
15  #include <linux/fcntl.h>
16  #include <linux/kobject.h>
17  #include <linux/uaccess.h>
18  #include <asm/opal.h>
19  
20  struct elog_obj {
21  	struct kobject kobj;
22  	struct bin_attribute raw_attr;
23  	uint64_t id;
24  	uint64_t type;
25  	size_t size;
26  	char *buffer;
27  };
28  #define to_elog_obj(x) container_of(x, struct elog_obj, kobj)
29  
30  struct elog_attribute {
31  	struct attribute attr;
32  	ssize_t (*show)(struct elog_obj *elog, struct elog_attribute *attr,
33  			char *buf);
34  	ssize_t (*store)(struct elog_obj *elog, struct elog_attribute *attr,
35  			 const char *buf, size_t count);
36  };
37  #define to_elog_attr(x) container_of(x, struct elog_attribute, attr)
38  
elog_id_show(struct elog_obj * elog_obj,struct elog_attribute * attr,char * buf)39  static ssize_t elog_id_show(struct elog_obj *elog_obj,
40  			    struct elog_attribute *attr,
41  			    char *buf)
42  {
43  	return sprintf(buf, "0x%llx\n", elog_obj->id);
44  }
45  
elog_type_to_string(uint64_t type)46  static const char *elog_type_to_string(uint64_t type)
47  {
48  	switch (type) {
49  	case 0: return "PEL";
50  	default: return "unknown";
51  	}
52  }
53  
elog_type_show(struct elog_obj * elog_obj,struct elog_attribute * attr,char * buf)54  static ssize_t elog_type_show(struct elog_obj *elog_obj,
55  			      struct elog_attribute *attr,
56  			      char *buf)
57  {
58  	return sprintf(buf, "0x%llx %s\n",
59  		       elog_obj->type,
60  		       elog_type_to_string(elog_obj->type));
61  }
62  
elog_ack_show(struct elog_obj * elog_obj,struct elog_attribute * attr,char * buf)63  static ssize_t elog_ack_show(struct elog_obj *elog_obj,
64  			     struct elog_attribute *attr,
65  			     char *buf)
66  {
67  	return sprintf(buf, "ack - acknowledge log message\n");
68  }
69  
elog_ack_store(struct elog_obj * elog_obj,struct elog_attribute * attr,const char * buf,size_t count)70  static ssize_t elog_ack_store(struct elog_obj *elog_obj,
71  			      struct elog_attribute *attr,
72  			      const char *buf,
73  			      size_t count)
74  {
75  	/*
76  	 * Try to self remove this attribute. If we are successful,
77  	 * delete the kobject itself.
78  	 */
79  	if (sysfs_remove_file_self(&elog_obj->kobj, &attr->attr)) {
80  		opal_send_ack_elog(elog_obj->id);
81  		kobject_put(&elog_obj->kobj);
82  	}
83  	return count;
84  }
85  
86  static struct elog_attribute id_attribute =
87  	__ATTR(id, 0444, elog_id_show, NULL);
88  static struct elog_attribute type_attribute =
89  	__ATTR(type, 0444, elog_type_show, NULL);
90  static struct elog_attribute ack_attribute =
91  	__ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store);
92  
93  static struct kset *elog_kset;
94  
elog_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)95  static ssize_t elog_attr_show(struct kobject *kobj,
96  			      struct attribute *attr,
97  			      char *buf)
98  {
99  	struct elog_attribute *attribute;
100  	struct elog_obj *elog;
101  
102  	attribute = to_elog_attr(attr);
103  	elog = to_elog_obj(kobj);
104  
105  	if (!attribute->show)
106  		return -EIO;
107  
108  	return attribute->show(elog, attribute, buf);
109  }
110  
elog_attr_store(struct kobject * kobj,struct attribute * attr,const char * buf,size_t len)111  static ssize_t elog_attr_store(struct kobject *kobj,
112  			       struct attribute *attr,
113  			       const char *buf, size_t len)
114  {
115  	struct elog_attribute *attribute;
116  	struct elog_obj *elog;
117  
118  	attribute = to_elog_attr(attr);
119  	elog = to_elog_obj(kobj);
120  
121  	if (!attribute->store)
122  		return -EIO;
123  
124  	return attribute->store(elog, attribute, buf, len);
125  }
126  
127  static const struct sysfs_ops elog_sysfs_ops = {
128  	.show = elog_attr_show,
129  	.store = elog_attr_store,
130  };
131  
elog_release(struct kobject * kobj)132  static void elog_release(struct kobject *kobj)
133  {
134  	struct elog_obj *elog;
135  
136  	elog = to_elog_obj(kobj);
137  	kfree(elog->buffer);
138  	kfree(elog);
139  }
140  
141  static struct attribute *elog_default_attrs[] = {
142  	&id_attribute.attr,
143  	&type_attribute.attr,
144  	&ack_attribute.attr,
145  	NULL,
146  };
147  ATTRIBUTE_GROUPS(elog_default);
148  
149  static const struct kobj_type elog_ktype = {
150  	.sysfs_ops = &elog_sysfs_ops,
151  	.release = &elog_release,
152  	.default_groups = elog_default_groups,
153  };
154  
155  /* Maximum size of a single log on FSP is 16KB */
156  #define OPAL_MAX_ERRLOG_SIZE	16384
157  
raw_attr_read(struct file * filep,struct kobject * kobj,struct bin_attribute * bin_attr,char * buffer,loff_t pos,size_t count)158  static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj,
159  			     struct bin_attribute *bin_attr,
160  			     char *buffer, loff_t pos, size_t count)
161  {
162  	int opal_rc;
163  
164  	struct elog_obj *elog = to_elog_obj(kobj);
165  
166  	/* We may have had an error reading before, so let's retry */
167  	if (!elog->buffer) {
168  		elog->buffer = kzalloc(elog->size, GFP_KERNEL);
169  		if (!elog->buffer)
170  			return -EIO;
171  
172  		opal_rc = opal_read_elog(__pa(elog->buffer),
173  					 elog->size, elog->id);
174  		if (opal_rc != OPAL_SUCCESS) {
175  			pr_err_ratelimited("ELOG: log read failed for log-id=%llx\n",
176  					   elog->id);
177  			kfree(elog->buffer);
178  			elog->buffer = NULL;
179  			return -EIO;
180  		}
181  	}
182  
183  	memcpy(buffer, elog->buffer + pos, count);
184  
185  	return count;
186  }
187  
create_elog_obj(uint64_t id,size_t size,uint64_t type)188  static void create_elog_obj(uint64_t id, size_t size, uint64_t type)
189  {
190  	struct elog_obj *elog;
191  	int rc;
192  
193  	elog = kzalloc(sizeof(*elog), GFP_KERNEL);
194  	if (!elog)
195  		return;
196  
197  	elog->kobj.kset = elog_kset;
198  
199  	kobject_init(&elog->kobj, &elog_ktype);
200  
201  	sysfs_bin_attr_init(&elog->raw_attr);
202  
203  	elog->raw_attr.attr.name = "raw";
204  	elog->raw_attr.attr.mode = 0400;
205  	elog->raw_attr.size = size;
206  	elog->raw_attr.read = raw_attr_read;
207  
208  	elog->id = id;
209  	elog->size = size;
210  	elog->type = type;
211  
212  	elog->buffer = kzalloc(elog->size, GFP_KERNEL);
213  
214  	if (elog->buffer) {
215  		rc = opal_read_elog(__pa(elog->buffer),
216  					 elog->size, elog->id);
217  		if (rc != OPAL_SUCCESS) {
218  			pr_err("ELOG: log read failed for log-id=%llx\n",
219  			       elog->id);
220  			kfree(elog->buffer);
221  			elog->buffer = NULL;
222  		}
223  	}
224  
225  	rc = kobject_add(&elog->kobj, NULL, "0x%llx", id);
226  	if (rc) {
227  		kobject_put(&elog->kobj);
228  		return;
229  	}
230  
231  	/*
232  	 * As soon as the sysfs file for this elog is created/activated there is
233  	 * a chance the opal_errd daemon (or any userspace) might read and
234  	 * acknowledge the elog before kobject_uevent() is called. If that
235  	 * happens then there is a potential race between
236  	 * elog_ack_store->kobject_put() and kobject_uevent() which leads to a
237  	 * use-after-free of a kernfs object resulting in a kernel crash.
238  	 *
239  	 * To avoid that, we need to take a reference on behalf of the bin file,
240  	 * so that our reference remains valid while we call kobject_uevent().
241  	 * We then drop our reference before exiting the function, leaving the
242  	 * bin file to drop the last reference (if it hasn't already).
243  	 */
244  
245  	/* Take a reference for the bin file */
246  	kobject_get(&elog->kobj);
247  	rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr);
248  	if (rc == 0) {
249  		kobject_uevent(&elog->kobj, KOBJ_ADD);
250  	} else {
251  		/* Drop the reference taken for the bin file */
252  		kobject_put(&elog->kobj);
253  	}
254  
255  	/* Drop our reference */
256  	kobject_put(&elog->kobj);
257  
258  	return;
259  }
260  
elog_event(int irq,void * data)261  static irqreturn_t elog_event(int irq, void *data)
262  {
263  	__be64 size;
264  	__be64 id;
265  	__be64 type;
266  	uint64_t elog_size;
267  	uint64_t log_id;
268  	uint64_t elog_type;
269  	int rc;
270  	char name[2+16+1];
271  	struct kobject *kobj;
272  
273  	rc = opal_get_elog_size(&id, &size, &type);
274  	if (rc != OPAL_SUCCESS) {
275  		pr_err("ELOG: OPAL log info read failed\n");
276  		return IRQ_HANDLED;
277  	}
278  
279  	elog_size = be64_to_cpu(size);
280  	log_id = be64_to_cpu(id);
281  	elog_type = be64_to_cpu(type);
282  
283  	WARN_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);
284  
285  	if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
286  		elog_size  =  OPAL_MAX_ERRLOG_SIZE;
287  
288  	sprintf(name, "0x%llx", log_id);
289  
290  	/* we may get notified twice, let's handle
291  	 * that gracefully and not create two conflicting
292  	 * entries.
293  	 */
294  	kobj = kset_find_obj(elog_kset, name);
295  	if (kobj) {
296  		/* Drop reference added by kset_find_obj() */
297  		kobject_put(kobj);
298  		return IRQ_HANDLED;
299  	}
300  
301  	create_elog_obj(log_id, elog_size, elog_type);
302  
303  	return IRQ_HANDLED;
304  }
305  
opal_elog_init(void)306  int __init opal_elog_init(void)
307  {
308  	int rc = 0, irq;
309  
310  	/* ELOG not supported by firmware */
311  	if (!opal_check_token(OPAL_ELOG_READ))
312  		return -1;
313  
314  	elog_kset = kset_create_and_add("elog", NULL, opal_kobj);
315  	if (!elog_kset) {
316  		pr_warn("%s: failed to create elog kset\n", __func__);
317  		return -1;
318  	}
319  
320  	irq = opal_event_request(ilog2(OPAL_EVENT_ERROR_LOG_AVAIL));
321  	if (!irq) {
322  		pr_err("%s: Can't register OPAL event irq (%d)\n",
323  		       __func__, irq);
324  		return irq;
325  	}
326  
327  	rc = request_threaded_irq(irq, NULL, elog_event,
328  			IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "opal-elog", NULL);
329  	if (rc) {
330  		pr_err("%s: Can't request OPAL event irq (%d)\n",
331  		       __func__, rc);
332  		return rc;
333  	}
334  
335  	/* We are now ready to pull error logs from opal. */
336  	if (opal_check_token(OPAL_ELOG_RESEND))
337  		opal_resend_pending_logs();
338  
339  	return 0;
340  }
341