1 /* 2 * CPU Microcode Update Driver for Linux 3 * 4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 5 * 2006 Shaohua Li <shaohua.li@intel.com> 6 * 2013-2015 Borislav Petkov <bp@alien8.de> 7 * 8 * This driver allows to upgrade microcode on x86 processors. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 13 * 2 of the License, or (at your option) any later version. 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include <linux/platform_device.h> 19 #include <linux/miscdevice.h> 20 #include <linux/capability.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/mutex.h> 24 #include <linux/cpu.h> 25 #include <linux/fs.h> 26 #include <linux/mm.h> 27 #include <linux/syscore_ops.h> 28 29 #include <asm/microcode.h> 30 #include <asm/processor.h> 31 #include <asm/cpu_device_id.h> 32 #include <asm/perf_event.h> 33 34 MODULE_DESCRIPTION("Microcode Update Driver"); 35 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 36 MODULE_LICENSE("GPL"); 37 38 #define MICROCODE_VERSION "2.00" 39 40 static struct microcode_ops *microcode_ops; 41 42 bool dis_ucode_ldr; 43 module_param(dis_ucode_ldr, bool, 0); 44 45 /* 46 * Synchronization. 47 * 48 * All non cpu-hotplug-callback call sites use: 49 * 50 * - microcode_mutex to synchronize with each other; 51 * - get/put_online_cpus() to synchronize with 52 * the cpu-hotplug-callback call sites. 53 * 54 * We guarantee that only a single cpu is being 55 * updated at any particular moment of time. 56 */ 57 static DEFINE_MUTEX(microcode_mutex); 58 59 struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; 60 EXPORT_SYMBOL_GPL(ucode_cpu_info); 61 62 /* 63 * Operations that are run on a target cpu: 64 */ 65 66 struct cpu_info_ctx { 67 struct cpu_signature *cpu_sig; 68 int err; 69 }; 70 71 static void collect_cpu_info_local(void *arg) 72 { 73 struct cpu_info_ctx *ctx = arg; 74 75 ctx->err = microcode_ops->collect_cpu_info(smp_processor_id(), 76 ctx->cpu_sig); 77 } 78 79 static int collect_cpu_info_on_target(int cpu, struct cpu_signature *cpu_sig) 80 { 81 struct cpu_info_ctx ctx = { .cpu_sig = cpu_sig, .err = 0 }; 82 int ret; 83 84 ret = smp_call_function_single(cpu, collect_cpu_info_local, &ctx, 1); 85 if (!ret) 86 ret = ctx.err; 87 88 return ret; 89 } 90 91 static int collect_cpu_info(int cpu) 92 { 93 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 94 int ret; 95 96 memset(uci, 0, sizeof(*uci)); 97 98 ret = collect_cpu_info_on_target(cpu, &uci->cpu_sig); 99 if (!ret) 100 uci->valid = 1; 101 102 return ret; 103 } 104 105 struct apply_microcode_ctx { 106 int err; 107 }; 108 109 static void apply_microcode_local(void *arg) 110 { 111 struct apply_microcode_ctx *ctx = arg; 112 113 ctx->err = microcode_ops->apply_microcode(smp_processor_id()); 114 } 115 116 static int apply_microcode_on_target(int cpu) 117 { 118 struct apply_microcode_ctx ctx = { .err = 0 }; 119 int ret; 120 121 ret = smp_call_function_single(cpu, apply_microcode_local, &ctx, 1); 122 if (!ret) 123 ret = ctx.err; 124 125 return ret; 126 } 127 128 #ifdef CONFIG_MICROCODE_OLD_INTERFACE 129 static int do_microcode_update(const void __user *buf, size_t size) 130 { 131 int error = 0; 132 int cpu; 133 134 for_each_online_cpu(cpu) { 135 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 136 enum ucode_state ustate; 137 138 if (!uci->valid) 139 continue; 140 141 ustate = microcode_ops->request_microcode_user(cpu, buf, size); 142 if (ustate == UCODE_ERROR) { 143 error = -1; 144 break; 145 } else if (ustate == UCODE_OK) 146 apply_microcode_on_target(cpu); 147 } 148 149 return error; 150 } 151 152 static int microcode_open(struct inode *inode, struct file *file) 153 { 154 return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM; 155 } 156 157 static ssize_t microcode_write(struct file *file, const char __user *buf, 158 size_t len, loff_t *ppos) 159 { 160 ssize_t ret = -EINVAL; 161 162 if ((len >> PAGE_SHIFT) > totalram_pages) { 163 pr_err("too much data (max %ld pages)\n", totalram_pages); 164 return ret; 165 } 166 167 get_online_cpus(); 168 mutex_lock(µcode_mutex); 169 170 if (do_microcode_update(buf, len) == 0) 171 ret = (ssize_t)len; 172 173 if (ret > 0) 174 perf_check_microcode(); 175 176 mutex_unlock(µcode_mutex); 177 put_online_cpus(); 178 179 return ret; 180 } 181 182 static const struct file_operations microcode_fops = { 183 .owner = THIS_MODULE, 184 .write = microcode_write, 185 .open = microcode_open, 186 .llseek = no_llseek, 187 }; 188 189 static struct miscdevice microcode_dev = { 190 .minor = MICROCODE_MINOR, 191 .name = "microcode", 192 .nodename = "cpu/microcode", 193 .fops = µcode_fops, 194 }; 195 196 static int __init microcode_dev_init(void) 197 { 198 int error; 199 200 error = misc_register(µcode_dev); 201 if (error) { 202 pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR); 203 return error; 204 } 205 206 return 0; 207 } 208 209 static void __exit microcode_dev_exit(void) 210 { 211 misc_deregister(µcode_dev); 212 } 213 214 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); 215 MODULE_ALIAS("devname:cpu/microcode"); 216 #else 217 #define microcode_dev_init() 0 218 #define microcode_dev_exit() do { } while (0) 219 #endif 220 221 /* fake device for request_firmware */ 222 static struct platform_device *microcode_pdev; 223 224 static int reload_for_cpu(int cpu) 225 { 226 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 227 enum ucode_state ustate; 228 int err = 0; 229 230 if (!uci->valid) 231 return err; 232 233 ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, true); 234 if (ustate == UCODE_OK) 235 apply_microcode_on_target(cpu); 236 else 237 if (ustate == UCODE_ERROR) 238 err = -EINVAL; 239 return err; 240 } 241 242 static ssize_t reload_store(struct device *dev, 243 struct device_attribute *attr, 244 const char *buf, size_t size) 245 { 246 unsigned long val; 247 int cpu; 248 ssize_t ret = 0, tmp_ret; 249 250 ret = kstrtoul(buf, 0, &val); 251 if (ret) 252 return ret; 253 254 if (val != 1) 255 return size; 256 257 get_online_cpus(); 258 mutex_lock(µcode_mutex); 259 for_each_online_cpu(cpu) { 260 tmp_ret = reload_for_cpu(cpu); 261 if (tmp_ret != 0) 262 pr_warn("Error reloading microcode on CPU %d\n", cpu); 263 264 /* save retval of the first encountered reload error */ 265 if (!ret) 266 ret = tmp_ret; 267 } 268 if (!ret) 269 perf_check_microcode(); 270 mutex_unlock(µcode_mutex); 271 put_online_cpus(); 272 273 if (!ret) 274 ret = size; 275 276 return ret; 277 } 278 279 static ssize_t version_show(struct device *dev, 280 struct device_attribute *attr, char *buf) 281 { 282 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 283 284 return sprintf(buf, "0x%x\n", uci->cpu_sig.rev); 285 } 286 287 static ssize_t pf_show(struct device *dev, 288 struct device_attribute *attr, char *buf) 289 { 290 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 291 292 return sprintf(buf, "0x%x\n", uci->cpu_sig.pf); 293 } 294 295 static DEVICE_ATTR(reload, 0200, NULL, reload_store); 296 static DEVICE_ATTR(version, 0400, version_show, NULL); 297 static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); 298 299 static struct attribute *mc_default_attrs[] = { 300 &dev_attr_version.attr, 301 &dev_attr_processor_flags.attr, 302 NULL 303 }; 304 305 static struct attribute_group mc_attr_group = { 306 .attrs = mc_default_attrs, 307 .name = "microcode", 308 }; 309 310 static void microcode_fini_cpu(int cpu) 311 { 312 microcode_ops->microcode_fini_cpu(cpu); 313 } 314 315 static enum ucode_state microcode_resume_cpu(int cpu) 316 { 317 pr_debug("CPU%d updated upon resume\n", cpu); 318 319 if (apply_microcode_on_target(cpu)) 320 return UCODE_ERROR; 321 322 return UCODE_OK; 323 } 324 325 static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw) 326 { 327 enum ucode_state ustate; 328 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 329 330 if (uci && uci->valid) 331 return UCODE_OK; 332 333 if (collect_cpu_info(cpu)) 334 return UCODE_ERROR; 335 336 /* --dimm. Trigger a delayed update? */ 337 if (system_state != SYSTEM_RUNNING) 338 return UCODE_NFOUND; 339 340 ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, 341 refresh_fw); 342 343 if (ustate == UCODE_OK) { 344 pr_debug("CPU%d updated upon init\n", cpu); 345 apply_microcode_on_target(cpu); 346 } 347 348 return ustate; 349 } 350 351 static enum ucode_state microcode_update_cpu(int cpu) 352 { 353 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 354 355 if (uci->valid) 356 return microcode_resume_cpu(cpu); 357 358 return microcode_init_cpu(cpu, false); 359 } 360 361 static int mc_device_add(struct device *dev, struct subsys_interface *sif) 362 { 363 int err, cpu = dev->id; 364 365 if (!cpu_online(cpu)) 366 return 0; 367 368 pr_debug("CPU%d added\n", cpu); 369 370 err = sysfs_create_group(&dev->kobj, &mc_attr_group); 371 if (err) 372 return err; 373 374 if (microcode_init_cpu(cpu, true) == UCODE_ERROR) 375 return -EINVAL; 376 377 return err; 378 } 379 380 static void mc_device_remove(struct device *dev, struct subsys_interface *sif) 381 { 382 int cpu = dev->id; 383 384 if (!cpu_online(cpu)) 385 return; 386 387 pr_debug("CPU%d removed\n", cpu); 388 microcode_fini_cpu(cpu); 389 sysfs_remove_group(&dev->kobj, &mc_attr_group); 390 } 391 392 static struct subsys_interface mc_cpu_interface = { 393 .name = "microcode", 394 .subsys = &cpu_subsys, 395 .add_dev = mc_device_add, 396 .remove_dev = mc_device_remove, 397 }; 398 399 /** 400 * mc_bp_resume - Update boot CPU microcode during resume. 401 */ 402 static void mc_bp_resume(void) 403 { 404 int cpu = smp_processor_id(); 405 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 406 407 if (uci->valid && uci->mc) 408 microcode_ops->apply_microcode(cpu); 409 else if (!uci->mc) 410 reload_early_microcode(); 411 } 412 413 static struct syscore_ops mc_syscore_ops = { 414 .resume = mc_bp_resume, 415 }; 416 417 static int 418 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) 419 { 420 unsigned int cpu = (unsigned long)hcpu; 421 struct device *dev; 422 423 dev = get_cpu_device(cpu); 424 425 switch (action & ~CPU_TASKS_FROZEN) { 426 case CPU_ONLINE: 427 microcode_update_cpu(cpu); 428 pr_debug("CPU%d added\n", cpu); 429 /* 430 * "break" is missing on purpose here because we want to fall 431 * through in order to create the sysfs group. 432 */ 433 434 case CPU_DOWN_FAILED: 435 if (sysfs_create_group(&dev->kobj, &mc_attr_group)) 436 pr_err("Failed to create group for CPU%d\n", cpu); 437 break; 438 439 case CPU_DOWN_PREPARE: 440 /* Suspend is in progress, only remove the interface */ 441 sysfs_remove_group(&dev->kobj, &mc_attr_group); 442 pr_debug("CPU%d removed\n", cpu); 443 break; 444 445 /* 446 * case CPU_DEAD: 447 * 448 * When a CPU goes offline, don't free up or invalidate the copy of 449 * the microcode in kernel memory, so that we can reuse it when the 450 * CPU comes back online without unnecessarily requesting the userspace 451 * for it again. 452 */ 453 } 454 455 /* The CPU refused to come up during a system resume */ 456 if (action == CPU_UP_CANCELED_FROZEN) 457 microcode_fini_cpu(cpu); 458 459 return NOTIFY_OK; 460 } 461 462 static struct notifier_block mc_cpu_notifier = { 463 .notifier_call = mc_cpu_callback, 464 }; 465 466 #ifdef MODULE 467 /* Autoload on Intel and AMD systems */ 468 static const struct x86_cpu_id __initconst microcode_id[] = { 469 #ifdef CONFIG_MICROCODE_INTEL 470 { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, 471 #endif 472 #ifdef CONFIG_MICROCODE_AMD 473 { X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, }, 474 #endif 475 {} 476 }; 477 MODULE_DEVICE_TABLE(x86cpu, microcode_id); 478 #endif 479 480 static struct attribute *cpu_root_microcode_attrs[] = { 481 &dev_attr_reload.attr, 482 NULL 483 }; 484 485 static struct attribute_group cpu_root_microcode_group = { 486 .name = "microcode", 487 .attrs = cpu_root_microcode_attrs, 488 }; 489 490 static int __init microcode_init(void) 491 { 492 struct cpuinfo_x86 *c = &cpu_data(0); 493 int error; 494 495 if (paravirt_enabled() || dis_ucode_ldr) 496 return -EINVAL; 497 498 if (c->x86_vendor == X86_VENDOR_INTEL) 499 microcode_ops = init_intel_microcode(); 500 else if (c->x86_vendor == X86_VENDOR_AMD) 501 microcode_ops = init_amd_microcode(); 502 else 503 pr_err("no support for this CPU vendor\n"); 504 505 if (!microcode_ops) 506 return -ENODEV; 507 508 microcode_pdev = platform_device_register_simple("microcode", -1, 509 NULL, 0); 510 if (IS_ERR(microcode_pdev)) 511 return PTR_ERR(microcode_pdev); 512 513 get_online_cpus(); 514 mutex_lock(µcode_mutex); 515 516 error = subsys_interface_register(&mc_cpu_interface); 517 if (!error) 518 perf_check_microcode(); 519 mutex_unlock(µcode_mutex); 520 put_online_cpus(); 521 522 if (error) 523 goto out_pdev; 524 525 error = sysfs_create_group(&cpu_subsys.dev_root->kobj, 526 &cpu_root_microcode_group); 527 528 if (error) { 529 pr_err("Error creating microcode group!\n"); 530 goto out_driver; 531 } 532 533 error = microcode_dev_init(); 534 if (error) 535 goto out_ucode_group; 536 537 register_syscore_ops(&mc_syscore_ops); 538 register_hotcpu_notifier(&mc_cpu_notifier); 539 540 pr_info("Microcode Update Driver: v" MICROCODE_VERSION 541 " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); 542 543 return 0; 544 545 out_ucode_group: 546 sysfs_remove_group(&cpu_subsys.dev_root->kobj, 547 &cpu_root_microcode_group); 548 549 out_driver: 550 get_online_cpus(); 551 mutex_lock(µcode_mutex); 552 553 subsys_interface_unregister(&mc_cpu_interface); 554 555 mutex_unlock(µcode_mutex); 556 put_online_cpus(); 557 558 out_pdev: 559 platform_device_unregister(microcode_pdev); 560 return error; 561 562 } 563 module_init(microcode_init); 564 565 static void __exit microcode_exit(void) 566 { 567 struct cpuinfo_x86 *c = &cpu_data(0); 568 569 microcode_dev_exit(); 570 571 unregister_hotcpu_notifier(&mc_cpu_notifier); 572 unregister_syscore_ops(&mc_syscore_ops); 573 574 sysfs_remove_group(&cpu_subsys.dev_root->kobj, 575 &cpu_root_microcode_group); 576 577 get_online_cpus(); 578 mutex_lock(µcode_mutex); 579 580 subsys_interface_unregister(&mc_cpu_interface); 581 582 mutex_unlock(µcode_mutex); 583 put_online_cpus(); 584 585 platform_device_unregister(microcode_pdev); 586 587 microcode_ops = NULL; 588 589 if (c->x86_vendor == X86_VENDOR_AMD) 590 exit_amd_microcode(); 591 592 pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n"); 593 } 594 module_exit(microcode_exit); 595