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 sysfs_emit(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 sysfs_emit(buf, "0x%llx %s\n", elog_obj->type, 59 elog_type_to_string(elog_obj->type)); 60 } 61 62 static ssize_t elog_ack_show(struct elog_obj *elog_obj, 63 struct elog_attribute *attr, 64 char *buf) 65 { 66 return sysfs_emit(buf, "ack - acknowledge log message\n"); 67 } 68 69 static ssize_t elog_ack_store(struct elog_obj *elog_obj, 70 struct elog_attribute *attr, 71 const char *buf, 72 size_t count) 73 { 74 /* 75 * Try to self remove this attribute. If we are successful, 76 * delete the kobject itself. 77 */ 78 if (sysfs_remove_file_self(&elog_obj->kobj, &attr->attr)) { 79 opal_send_ack_elog(elog_obj->id); 80 kobject_put(&elog_obj->kobj); 81 } 82 return count; 83 } 84 85 static struct elog_attribute id_attribute = 86 __ATTR(id, 0444, elog_id_show, NULL); 87 static struct elog_attribute type_attribute = 88 __ATTR(type, 0444, elog_type_show, NULL); 89 static struct elog_attribute ack_attribute = 90 __ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store); 91 92 static struct kset *elog_kset; 93 94 static ssize_t elog_attr_show(struct kobject *kobj, 95 struct attribute *attr, 96 char *buf) 97 { 98 struct elog_attribute *attribute; 99 struct elog_obj *elog; 100 101 attribute = to_elog_attr(attr); 102 elog = to_elog_obj(kobj); 103 104 if (!attribute->show) 105 return -EIO; 106 107 return attribute->show(elog, attribute, buf); 108 } 109 110 static ssize_t elog_attr_store(struct kobject *kobj, 111 struct attribute *attr, 112 const char *buf, size_t len) 113 { 114 struct elog_attribute *attribute; 115 struct elog_obj *elog; 116 117 attribute = to_elog_attr(attr); 118 elog = to_elog_obj(kobj); 119 120 if (!attribute->store) 121 return -EIO; 122 123 return attribute->store(elog, attribute, buf, len); 124 } 125 126 static const struct sysfs_ops elog_sysfs_ops = { 127 .show = elog_attr_show, 128 .store = elog_attr_store, 129 }; 130 131 static void elog_release(struct kobject *kobj) 132 { 133 struct elog_obj *elog; 134 135 elog = to_elog_obj(kobj); 136 kfree(elog->buffer); 137 kfree(elog); 138 } 139 140 static struct attribute *elog_default_attrs[] = { 141 &id_attribute.attr, 142 &type_attribute.attr, 143 &ack_attribute.attr, 144 NULL, 145 }; 146 ATTRIBUTE_GROUPS(elog_default); 147 148 static const struct kobj_type elog_ktype = { 149 .sysfs_ops = &elog_sysfs_ops, 150 .release = &elog_release, 151 .default_groups = elog_default_groups, 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 const 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_obj(*elog); 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