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 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 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 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 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 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 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 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 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 148 static struct kobj_type elog_ktype = { 149 .sysfs_ops = &elog_sysfs_ops, 150 .release = &elog_release, 151 .default_attrs = elog_default_attrs, 152 }; 153 154 /* Maximum size of a single log on FSP is 16KB */ 155 #define OPAL_MAX_ERRLOG_SIZE 16384 156 157 static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj, 158 struct bin_attribute *bin_attr, 159 char *buffer, loff_t pos, size_t count) 160 { 161 int opal_rc; 162 163 struct elog_obj *elog = to_elog_obj(kobj); 164 165 /* We may have had an error reading before, so let's retry */ 166 if (!elog->buffer) { 167 elog->buffer = kzalloc(elog->size, GFP_KERNEL); 168 if (!elog->buffer) 169 return -EIO; 170 171 opal_rc = opal_read_elog(__pa(elog->buffer), 172 elog->size, elog->id); 173 if (opal_rc != OPAL_SUCCESS) { 174 pr_err_ratelimited("ELOG: log read failed for log-id=%llx\n", 175 elog->id); 176 kfree(elog->buffer); 177 elog->buffer = NULL; 178 return -EIO; 179 } 180 } 181 182 memcpy(buffer, elog->buffer + pos, count); 183 184 return count; 185 } 186 187 static void create_elog_obj(uint64_t id, size_t size, uint64_t type) 188 { 189 struct elog_obj *elog; 190 int rc; 191 192 elog = kzalloc(sizeof(*elog), GFP_KERNEL); 193 if (!elog) 194 return; 195 196 elog->kobj.kset = elog_kset; 197 198 kobject_init(&elog->kobj, &elog_ktype); 199 200 sysfs_bin_attr_init(&elog->raw_attr); 201 202 elog->raw_attr.attr.name = "raw"; 203 elog->raw_attr.attr.mode = 0400; 204 elog->raw_attr.size = size; 205 elog->raw_attr.read = raw_attr_read; 206 207 elog->id = id; 208 elog->size = size; 209 elog->type = type; 210 211 elog->buffer = kzalloc(elog->size, GFP_KERNEL); 212 213 if (elog->buffer) { 214 rc = opal_read_elog(__pa(elog->buffer), 215 elog->size, elog->id); 216 if (rc != OPAL_SUCCESS) { 217 pr_err("ELOG: log read failed for log-id=%llx\n", 218 elog->id); 219 kfree(elog->buffer); 220 elog->buffer = NULL; 221 } 222 } 223 224 rc = kobject_add(&elog->kobj, NULL, "0x%llx", id); 225 if (rc) { 226 kobject_put(&elog->kobj); 227 return; 228 } 229 230 /* 231 * As soon as the sysfs file for this elog is created/activated there is 232 * a chance the opal_errd daemon (or any userspace) might read and 233 * acknowledge the elog before kobject_uevent() is called. If that 234 * happens then there is a potential race between 235 * elog_ack_store->kobject_put() and kobject_uevent() which leads to a 236 * use-after-free of a kernfs object resulting in a kernel crash. 237 * 238 * To avoid that, we need to take a reference on behalf of the bin file, 239 * so that our reference remains valid while we call kobject_uevent(). 240 * We then drop our reference before exiting the function, leaving the 241 * bin file to drop the last reference (if it hasn't already). 242 */ 243 244 /* Take a reference for the bin file */ 245 kobject_get(&elog->kobj); 246 rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr); 247 if (rc == 0) { 248 kobject_uevent(&elog->kobj, KOBJ_ADD); 249 } else { 250 /* Drop the reference taken for the bin file */ 251 kobject_put(&elog->kobj); 252 } 253 254 /* Drop our reference */ 255 kobject_put(&elog->kobj); 256 257 return; 258 } 259 260 static irqreturn_t elog_event(int irq, void *data) 261 { 262 __be64 size; 263 __be64 id; 264 __be64 type; 265 uint64_t elog_size; 266 uint64_t log_id; 267 uint64_t elog_type; 268 int rc; 269 char name[2+16+1]; 270 struct kobject *kobj; 271 272 rc = opal_get_elog_size(&id, &size, &type); 273 if (rc != OPAL_SUCCESS) { 274 pr_err("ELOG: OPAL log info read failed\n"); 275 return IRQ_HANDLED; 276 } 277 278 elog_size = be64_to_cpu(size); 279 log_id = be64_to_cpu(id); 280 elog_type = be64_to_cpu(type); 281 282 WARN_ON(elog_size > OPAL_MAX_ERRLOG_SIZE); 283 284 if (elog_size >= OPAL_MAX_ERRLOG_SIZE) 285 elog_size = OPAL_MAX_ERRLOG_SIZE; 286 287 sprintf(name, "0x%llx", log_id); 288 289 /* we may get notified twice, let's handle 290 * that gracefully and not create two conflicting 291 * entries. 292 */ 293 kobj = kset_find_obj(elog_kset, name); 294 if (kobj) { 295 /* Drop reference added by kset_find_obj() */ 296 kobject_put(kobj); 297 return IRQ_HANDLED; 298 } 299 300 create_elog_obj(log_id, elog_size, elog_type); 301 302 return IRQ_HANDLED; 303 } 304 305 int __init opal_elog_init(void) 306 { 307 int rc = 0, irq; 308 309 /* ELOG not supported by firmware */ 310 if (!opal_check_token(OPAL_ELOG_READ)) 311 return -1; 312 313 elog_kset = kset_create_and_add("elog", NULL, opal_kobj); 314 if (!elog_kset) { 315 pr_warn("%s: failed to create elog kset\n", __func__); 316 return -1; 317 } 318 319 irq = opal_event_request(ilog2(OPAL_EVENT_ERROR_LOG_AVAIL)); 320 if (!irq) { 321 pr_err("%s: Can't register OPAL event irq (%d)\n", 322 __func__, irq); 323 return irq; 324 } 325 326 rc = request_threaded_irq(irq, NULL, elog_event, 327 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "opal-elog", NULL); 328 if (rc) { 329 pr_err("%s: Can't request OPAL event irq (%d)\n", 330 __func__, rc); 331 return rc; 332 } 333 334 /* We are now ready to pull error logs from opal. */ 335 if (opal_check_token(OPAL_ELOG_RESEND)) 336 opal_resend_pending_logs(); 337 338 return 0; 339 } 340