core.c 16.8 KB
Newer Older
P
Peter Oruba 已提交
1
/*
2
 * CPU Microcode Update Driver for Linux
P
Peter Oruba 已提交
3
 *
A
Andrew Morton 已提交
4
 * Copyright (C) 2000-2006 Tigran Aivazian <aivazian.tigran@gmail.com>
5
 *	      2006	Shaohua Li <shaohua.li@intel.com>
6
 *	      2013-2016	Borislav Petkov <bp@alien8.de>
P
Peter Oruba 已提交
7
 *
8 9 10 11 12 13
 * X86 CPU microcode early update for Linux:
 *
 *	Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
 *			   H Peter Anvin" <hpa@zytor.com>
 *		  (C) 2015 Borislav Petkov <bp@alien8.de>
 *
14
 * This driver allows to upgrade microcode on x86 processors.
P
Peter Oruba 已提交
15
 *
16 17 18 19
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
P
Peter Oruba 已提交
20
 */
21

22
#define pr_fmt(fmt) "microcode: " fmt
23

I
Ingo Molnar 已提交
24
#include <linux/platform_device.h>
25
#include <linux/syscore_ops.h>
I
Ingo Molnar 已提交
26
#include <linux/miscdevice.h>
27
#include <linux/capability.h>
28
#include <linux/firmware.h>
I
Ingo Molnar 已提交
29
#include <linux/kernel.h>
P
Peter Oruba 已提交
30 31
#include <linux/mutex.h>
#include <linux/cpu.h>
I
Ingo Molnar 已提交
32 33
#include <linux/fs.h>
#include <linux/mm.h>
P
Peter Oruba 已提交
34

35
#include <asm/microcode_intel.h>
36
#include <asm/cpu_device_id.h>
37
#include <asm/microcode_amd.h>
38
#include <asm/perf_event.h>
39 40 41
#include <asm/microcode.h>
#include <asm/processor.h>
#include <asm/cmdline.h>
42
#include <asm/setup.h>
P
Peter Oruba 已提交
43

44
#define DRIVER_VERSION	"2.2"
P
Peter Oruba 已提交
45

I
Ingo Molnar 已提交
46
static struct microcode_ops	*microcode_ops;
47
static bool dis_ucode_ldr = true;
48

49 50
bool initrd_gone;

51 52
LIST_HEAD(microcode_cache);

53 54 55 56 57 58 59 60 61 62 63 64
/*
 * Synchronization.
 *
 * All non cpu-hotplug-callback call sites use:
 *
 * - microcode_mutex to synchronize with each other;
 * - get/put_online_cpus() to synchronize with
 *   the cpu-hotplug-callback call sites.
 *
 * We guarantee that only a single cpu is being
 * updated at any particular moment of time.
 */
65
static DEFINE_MUTEX(microcode_mutex);
P
Peter Oruba 已提交
66

I
Ingo Molnar 已提交
67
struct ucode_cpu_info		ucode_cpu_info[NR_CPUS];
P
Peter Oruba 已提交
68

69 70 71 72 73
struct cpu_info_ctx {
	struct cpu_signature	*cpu_sig;
	int			err;
};

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/*
 * Those patch levels cannot be updated to newer ones and thus should be final.
 */
static u32 final_levels[] = {
	0x01000098,
	0x0100009f,
	0x010000af,
	0, /* T-101 terminator */
};

/*
 * Check the current patch level on this CPU.
 *
 * Returns:
 *  - true: if update should stop
 *  - false: otherwise
 */
static bool amd_check_current_patch_level(void)
{
	u32 lvl, dummy, i;
	u32 *levels;

	native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);

	if (IS_ENABLED(CONFIG_X86_32))
		levels = (u32 *)__pa_nodebug(&final_levels);
	else
		levels = final_levels;

	for (i = 0; levels[i]; i++) {
		if (lvl == levels[i])
			return true;
	}
	return false;
}

110 111
static bool __init check_loader_disabled_bsp(void)
{
112 113
	static const char *__dis_opt_str = "dis_ucode_ldr";

114 115
#ifdef CONFIG_X86_32
	const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
116
	const char *option  = (const char *)__pa_nodebug(__dis_opt_str);
117 118 119 120
	bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr);

#else /* CONFIG_X86_64 */
	const char *cmdline = boot_command_line;
121
	const char *option  = __dis_opt_str;
122 123 124
	bool *res = &dis_ucode_ldr;
#endif

125 126 127 128 129
	/*
	 * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
	 * completely accurate as xen pv guests don't see that CPUID bit set but
	 * that's good enough as they don't land on the BSP path anyway.
	 */
130
	if (native_cpuid_ecx(1) & BIT(31))
131 132
		return *res;

133 134 135 136 137
	if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
		if (amd_check_current_patch_level())
			return *res;
	}

138 139
	if (cmdline_find_option_bool(cmdline, option) <= 0)
		*res = false;
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164

	return *res;
}

extern struct builtin_fw __start_builtin_fw[];
extern struct builtin_fw __end_builtin_fw[];

bool get_builtin_firmware(struct cpio_data *cd, const char *name)
{
#ifdef CONFIG_FW_LOADER
	struct builtin_fw *b_fw;

	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
		if (!strcmp(name, b_fw->name)) {
			cd->size = b_fw->size;
			cd->data = b_fw->data;
			return true;
		}
	}
#endif
	return false;
}

void __init load_ucode_bsp(void)
{
165
	unsigned int cpuid_1_eax;
166
	bool intel = true;
167

168
	if (!have_cpuid_p())
169 170
		return;

171
	cpuid_1_eax = native_cpuid_eax(1);
172

173
	switch (x86_cpuid_vendor()) {
174
	case X86_VENDOR_INTEL:
175 176
		if (x86_family(cpuid_1_eax) < 6)
			return;
177
		break;
178

179
	case X86_VENDOR_AMD:
180 181 182
		if (x86_family(cpuid_1_eax) < 0x10)
			return;
		intel = false;
183
		break;
184

185
	default:
186
		return;
187
	}
188 189 190 191 192 193 194 195

	if (check_loader_disabled_bsp())
		return;

	if (intel)
		load_ucode_intel_bsp();
	else
		load_ucode_amd_bsp(cpuid_1_eax);
196 197 198 199 200 201 202 203 204 205 206 207 208
}

static bool check_loader_disabled_ap(void)
{
#ifdef CONFIG_X86_32
	return *((bool *)__pa_nodebug(&dis_ucode_ldr));
#else
	return dis_ucode_ldr;
#endif
}

void load_ucode_ap(void)
{
209
	unsigned int cpuid_1_eax;
210 211 212 213

	if (check_loader_disabled_ap())
		return;

214
	cpuid_1_eax = native_cpuid_eax(1);
215

216
	switch (x86_cpuid_vendor()) {
217
	case X86_VENDOR_INTEL:
218
		if (x86_family(cpuid_1_eax) >= 6)
219 220 221
			load_ucode_intel_ap();
		break;
	case X86_VENDOR_AMD:
222 223
		if (x86_family(cpuid_1_eax) >= 0x10)
			load_ucode_amd_ap(cpuid_1_eax);
224 225 226 227 228 229
		break;
	default:
		break;
	}
}

230
static int __init save_microcode_in_initrd(void)
231 232
{
	struct cpuinfo_x86 *c = &boot_cpu_data;
233
	int ret = -EINVAL;
234 235 236 237

	switch (c->x86_vendor) {
	case X86_VENDOR_INTEL:
		if (c->x86 >= 6)
238
			ret = save_microcode_in_initrd_intel();
239 240 241
		break;
	case X86_VENDOR_AMD:
		if (c->x86 >= 0x10)
242
			ret = save_microcode_in_initrd_amd(cpuid_eax(1));
243 244 245 246 247
		break;
	default:
		break;
	}

248 249 250
	initrd_gone = true;

	return ret;
251 252
}

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa)
{
#ifdef CONFIG_BLK_DEV_INITRD
	unsigned long start = 0;
	size_t size;

#ifdef CONFIG_X86_32
	struct boot_params *params;

	if (use_pa)
		params = (struct boot_params *)__pa_nodebug(&boot_params);
	else
		params = &boot_params;

	size = params->hdr.ramdisk_size;

	/*
	 * Set start only if we have an initrd image. We cannot use initrd_start
	 * because it is not set that early yet.
	 */
	if (size)
		start = params->hdr.ramdisk_image;

# else /* CONFIG_X86_64 */
	size  = (unsigned long)boot_params.ext_ramdisk_size << 32;
	size |= boot_params.hdr.ramdisk_size;

	if (size) {
		start  = (unsigned long)boot_params.ext_ramdisk_image << 32;
		start |= boot_params.hdr.ramdisk_image;

		start += PAGE_OFFSET;
	}
# endif

	/*
289 290 291 292
	 * Fixup the start address: after reserve_initrd() runs, initrd_start
	 * has the virtual address of the beginning of the initrd. It also
	 * possibly relocates the ramdisk. In either case, initrd_start contains
	 * the updated address so use that instead.
293 294 295
	 *
	 * initrd_gone is for the hotplug case where we've thrown out initrd
	 * already.
296
	 */
297 298 299 300 301
	if (!use_pa) {
		if (initrd_gone)
			return (struct cpio_data){ NULL, 0, "" };
		if (initrd_start)
			start = initrd_start;
302 303 304 305 306 307 308 309 310 311 312
	} else {
		/*
		 * The picture with physical addresses is a bit different: we
		 * need to get the *physical* address to which the ramdisk was
		 * relocated, i.e., relocated_ramdisk (not initrd_start) and
		 * since we're running from physical addresses, we need to access
		 * relocated_ramdisk through its *physical* address too.
		 */
		u64 *rr = (u64 *)__pa_nodebug(&relocated_ramdisk);
		if (*rr)
			start = *rr;
313
	}
314 315 316 317 318 319 320

	return find_cpio_data(path, (void *)start, size, NULL);
#else /* !CONFIG_BLK_DEV_INITRD */
	return (struct cpio_data){ NULL, 0, "" };
#endif
}

321 322 323 324
void reload_early_microcode(void)
{
	int vendor, family;

325 326
	vendor = x86_cpuid_vendor();
	family = x86_cpuid_family();
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

	switch (vendor) {
	case X86_VENDOR_INTEL:
		if (family >= 6)
			reload_ucode_intel();
		break;
	case X86_VENDOR_AMD:
		if (family >= 0x10)
			reload_ucode_amd();
		break;
	default:
		break;
	}
}

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
static void collect_cpu_info_local(void *arg)
{
	struct cpu_info_ctx *ctx = arg;

	ctx->err = microcode_ops->collect_cpu_info(smp_processor_id(),
						   ctx->cpu_sig);
}

static int collect_cpu_info_on_target(int cpu, struct cpu_signature *cpu_sig)
{
	struct cpu_info_ctx ctx = { .cpu_sig = cpu_sig, .err = 0 };
	int ret;

	ret = smp_call_function_single(cpu, collect_cpu_info_local, &ctx, 1);
	if (!ret)
		ret = ctx.err;

	return ret;
}

static int collect_cpu_info(int cpu)
{
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
	int ret;

	memset(uci, 0, sizeof(*uci));

	ret = collect_cpu_info_on_target(cpu, &uci->cpu_sig);
	if (!ret)
		uci->valid = 1;

	return ret;
}

struct apply_microcode_ctx {
377
	enum ucode_state err;
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
};

static void apply_microcode_local(void *arg)
{
	struct apply_microcode_ctx *ctx = arg;

	ctx->err = microcode_ops->apply_microcode(smp_processor_id());
}

static int apply_microcode_on_target(int cpu)
{
	struct apply_microcode_ctx ctx = { .err = 0 };
	int ret;

	ret = smp_call_function_single(cpu, apply_microcode_local, &ctx, 1);
	if (!ret)
		ret = ctx.err;

	return ret;
}

P
Peter Oruba 已提交
399
#ifdef CONFIG_MICROCODE_OLD_INTERFACE
D
Dmitry Adamushko 已提交
400
static int do_microcode_update(const void __user *buf, size_t size)
P
Peter Oruba 已提交
401 402 403
{
	int error = 0;
	int cpu;
404

D
Dmitry Adamushko 已提交
405 406
	for_each_online_cpu(cpu) {
		struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
407
		enum ucode_state ustate;
D
Dmitry Adamushko 已提交
408 409 410

		if (!uci->valid)
			continue;
411

412 413 414 415 416 417
		ustate = microcode_ops->request_microcode_user(cpu, buf, size);
		if (ustate == UCODE_ERROR) {
			error = -1;
			break;
		} else if (ustate == UCODE_OK)
			apply_microcode_on_target(cpu);
P
Peter Oruba 已提交
418
	}
419

P
Peter Oruba 已提交
420 421 422
	return error;
}

423
static int microcode_open(struct inode *inode, struct file *file)
P
Peter Oruba 已提交
424
{
425
	return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
P
Peter Oruba 已提交
426 427
}

428 429
static ssize_t microcode_write(struct file *file, const char __user *buf,
			       size_t len, loff_t *ppos)
P
Peter Oruba 已提交
430
{
431
	ssize_t ret = -EINVAL;
P
Peter Oruba 已提交
432

433
	if ((len >> PAGE_SHIFT) > totalram_pages) {
434
		pr_err("too much data (max %ld pages)\n", totalram_pages);
435
		return ret;
P
Peter Oruba 已提交
436 437 438 439 440
	}

	get_online_cpus();
	mutex_lock(&microcode_mutex);

441
	if (do_microcode_update(buf, len) == 0)
P
Peter Oruba 已提交
442 443
		ret = (ssize_t)len;

444 445 446
	if (ret > 0)
		perf_check_microcode();

P
Peter Oruba 已提交
447 448 449 450 451 452 453
	mutex_unlock(&microcode_mutex);
	put_online_cpus();

	return ret;
}

static const struct file_operations microcode_fops = {
454 455 456
	.owner			= THIS_MODULE,
	.write			= microcode_write,
	.open			= microcode_open,
457
	.llseek		= no_llseek,
P
Peter Oruba 已提交
458 459 460
};

static struct miscdevice microcode_dev = {
461 462
	.minor			= MICROCODE_MINOR,
	.name			= "microcode",
463
	.nodename		= "cpu/microcode",
464
	.fops			= &microcode_fops,
P
Peter Oruba 已提交
465 466
};

467
static int __init microcode_dev_init(void)
P
Peter Oruba 已提交
468 469 470 471 472
{
	int error;

	error = misc_register(&microcode_dev);
	if (error) {
473
		pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR);
P
Peter Oruba 已提交
474 475 476 477 478 479
		return error;
	}

	return 0;
}

480
static void __exit microcode_dev_exit(void)
P
Peter Oruba 已提交
481 482 483 484
{
	misc_deregister(&microcode_dev);
}
#else
I
Ingo Molnar 已提交
485 486
#define microcode_dev_init()	0
#define microcode_dev_exit()	do { } while (0)
P
Peter Oruba 已提交
487 488 489
#endif

/* fake device for request_firmware */
I
Ingo Molnar 已提交
490
static struct platform_device	*microcode_pdev;
P
Peter Oruba 已提交
491

492
static enum ucode_state reload_for_cpu(int cpu)
493
{
494
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
495
	enum ucode_state ustate;
496

497
	if (!uci->valid)
498
		return UCODE_OK;
499

500
	ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, true);
501 502 503 504
	if (ustate != UCODE_OK)
		return ustate;

	return apply_microcode_on_target(cpu);
505 506
}

507 508
static ssize_t reload_store(struct device *dev,
			    struct device_attribute *attr,
509
			    const char *buf, size_t size)
P
Peter Oruba 已提交
510
{
511
	enum ucode_state tmp_ret = UCODE_OK;
512
	bool do_callback = false;
513
	unsigned long val;
514
	ssize_t ret = 0;
515 516
	int cpu;

517 518 519
	ret = kstrtoul(buf, 0, &val);
	if (ret)
		return ret;
520

521 522 523 524
	if (val != 1)
		return size;

	get_online_cpus();
525
	mutex_lock(&microcode_mutex);
526 527
	for_each_online_cpu(cpu) {
		tmp_ret = reload_for_cpu(cpu);
528
		if (tmp_ret > UCODE_NFOUND) {
529 530
			pr_warn("Error reloading microcode on CPU %d\n", cpu);

531 532 533 534
			/* set retval for the first encountered reload error */
			if (!ret)
				ret = -EINVAL;
		}
535 536 537

		if (tmp_ret == UCODE_UPDATED)
			do_callback = true;
P
Peter Oruba 已提交
538
	}
539

540 541
	if (!ret && do_callback)
		microcode_check();
542

543
	mutex_unlock(&microcode_mutex);
544
	put_online_cpus();
545 546 547 548 549

	if (!ret)
		ret = size;

	return ret;
P
Peter Oruba 已提交
550 551
}

552 553
static ssize_t version_show(struct device *dev,
			struct device_attribute *attr, char *buf)
P
Peter Oruba 已提交
554 555 556
{
	struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;

557
	return sprintf(buf, "0x%x\n", uci->cpu_sig.rev);
P
Peter Oruba 已提交
558 559
}

560 561
static ssize_t pf_show(struct device *dev,
			struct device_attribute *attr, char *buf)
P
Peter Oruba 已提交
562 563 564
{
	struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;

565
	return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
P
Peter Oruba 已提交
566 567
}

J
Joe Perches 已提交
568
static DEVICE_ATTR_WO(reload);
569 570
static DEVICE_ATTR(version, 0400, version_show, NULL);
static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
P
Peter Oruba 已提交
571 572

static struct attribute *mc_default_attrs[] = {
573 574
	&dev_attr_version.attr,
	&dev_attr_processor_flags.attr,
P
Peter Oruba 已提交
575 576 577
	NULL
};

578
static const struct attribute_group mc_attr_group = {
579 580
	.attrs			= mc_default_attrs,
	.name			= "microcode",
P
Peter Oruba 已提交
581 582
};

583
static void microcode_fini_cpu(int cpu)
584
{
585 586
	if (microcode_ops->microcode_fini_cpu)
		microcode_ops->microcode_fini_cpu(cpu);
587 588
}

589
static enum ucode_state microcode_resume_cpu(int cpu)
590
{
591 592
	if (apply_microcode_on_target(cpu))
		return UCODE_ERROR;
593

594 595
	pr_debug("CPU%d updated upon resume\n", cpu);

596
	return UCODE_OK;
597 598
}

599
static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
600
{
601
	enum ucode_state ustate;
602 603
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;

604
	if (uci->valid)
605
		return UCODE_OK;
606

607 608
	if (collect_cpu_info(cpu))
		return UCODE_ERROR;
609

610 611 612
	/* --dimm. Trigger a delayed update? */
	if (system_state != SYSTEM_RUNNING)
		return UCODE_NFOUND;
613

614 615
	ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev,
						     refresh_fw);
616

617
	if (ustate == UCODE_OK) {
618
		pr_debug("CPU%d updated upon init\n", cpu);
619
		apply_microcode_on_target(cpu);
620 621
	}

622
	return ustate;
623 624
}

625
static enum ucode_state microcode_update_cpu(int cpu)
626
{
627
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
628

629 630 631
	/* Refresh CPU microcode revision after resume. */
	collect_cpu_info(cpu);

632
	if (uci->valid)
633
		return microcode_resume_cpu(cpu);
634

635
	return microcode_init_cpu(cpu, false);
636 637
}

638
static int mc_device_add(struct device *dev, struct subsys_interface *sif)
P
Peter Oruba 已提交
639
{
640
	int err, cpu = dev->id;
P
Peter Oruba 已提交
641 642 643 644

	if (!cpu_online(cpu))
		return 0;

645
	pr_debug("CPU%d added\n", cpu);
P
Peter Oruba 已提交
646

647
	err = sysfs_create_group(&dev->kobj, &mc_attr_group);
P
Peter Oruba 已提交
648 649 650
	if (err)
		return err;

651
	if (microcode_init_cpu(cpu, true) == UCODE_ERROR)
652
		return -EINVAL;
653 654

	return err;
P
Peter Oruba 已提交
655 656
}

657
static void mc_device_remove(struct device *dev, struct subsys_interface *sif)
P
Peter Oruba 已提交
658
{
659
	int cpu = dev->id;
P
Peter Oruba 已提交
660 661

	if (!cpu_online(cpu))
662
		return;
P
Peter Oruba 已提交
663

664
	pr_debug("CPU%d removed\n", cpu);
665
	microcode_fini_cpu(cpu);
666
	sysfs_remove_group(&dev->kobj, &mc_attr_group);
P
Peter Oruba 已提交
667 668
}

669 670 671 672 673
static struct subsys_interface mc_cpu_interface = {
	.name			= "microcode",
	.subsys			= &cpu_subsys,
	.add_dev		= mc_device_add,
	.remove_dev		= mc_device_remove,
674 675 676 677 678 679
};

/**
 * mc_bp_resume - Update boot CPU microcode during resume.
 */
static void mc_bp_resume(void)
P
Peter Oruba 已提交
680
{
681
	int cpu = smp_processor_id();
682
	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
P
Peter Oruba 已提交
683

684 685
	if (uci->valid && uci->mc)
		microcode_ops->apply_microcode(cpu);
686
	else if (!uci->mc)
687
		reload_early_microcode();
P
Peter Oruba 已提交
688 689
}

690 691
static struct syscore_ops mc_syscore_ops = {
	.resume			= mc_bp_resume,
P
Peter Oruba 已提交
692 693
};

694
static int mc_cpu_online(unsigned int cpu)
P
Peter Oruba 已提交
695
{
696
	struct device *dev;
P
Peter Oruba 已提交
697

698
	dev = get_cpu_device(cpu);
699 700
	microcode_update_cpu(cpu);
	pr_debug("CPU%d added\n", cpu);
701

702 703 704 705
	if (sysfs_create_group(&dev->kobj, &mc_attr_group))
		pr_err("Failed to create group for CPU%d\n", cpu);
	return 0;
}
706

707 708 709
static int mc_cpu_down_prep(unsigned int cpu)
{
	struct device *dev;
710

711 712 713 714
	dev = get_cpu_device(cpu);
	/* Suspend is in progress, only remove the interface */
	sysfs_remove_group(&dev->kobj, &mc_attr_group);
	pr_debug("CPU%d removed\n", cpu);
715

716
	return 0;
P
Peter Oruba 已提交
717 718
}

719 720 721 722 723
static struct attribute *cpu_root_microcode_attrs[] = {
	&dev_attr_reload.attr,
	NULL
};

724
static const struct attribute_group cpu_root_microcode_group = {
725 726 727 728
	.name  = "microcode",
	.attrs = cpu_root_microcode_attrs,
};

729
int __init microcode_init(void)
P
Peter Oruba 已提交
730
{
731
	struct cpuinfo_x86 *c = &boot_cpu_data;
P
Peter Oruba 已提交
732 733
	int error;

734
	if (dis_ucode_ldr)
735
		return -EINVAL;
736

737 738
	if (c->x86_vendor == X86_VENDOR_INTEL)
		microcode_ops = init_intel_microcode();
P
Peter Oruba 已提交
739
	else if (c->x86_vendor == X86_VENDOR_AMD)
740
		microcode_ops = init_amd_microcode();
741
	else
742
		pr_err("no support for this CPU vendor\n");
743 744

	if (!microcode_ops)
745
		return -ENODEV;
P
Peter Oruba 已提交
746 747 748

	microcode_pdev = platform_device_register_simple("microcode", -1,
							 NULL, 0);
749
	if (IS_ERR(microcode_pdev))
P
Peter Oruba 已提交
750 751 752
		return PTR_ERR(microcode_pdev);

	get_online_cpus();
753 754
	mutex_lock(&microcode_mutex);

755
	error = subsys_interface_register(&mc_cpu_interface);
756 757
	if (!error)
		perf_check_microcode();
758
	mutex_unlock(&microcode_mutex);
P
Peter Oruba 已提交
759
	put_online_cpus();
760

761 762
	if (error)
		goto out_pdev;
P
Peter Oruba 已提交
763

764 765 766 767 768 769 770 771
	error = sysfs_create_group(&cpu_subsys.dev_root->kobj,
				   &cpu_root_microcode_group);

	if (error) {
		pr_err("Error creating microcode group!\n");
		goto out_driver;
	}

772 773
	error = microcode_dev_init();
	if (error)
774
		goto out_ucode_group;
775

776
	register_syscore_ops(&mc_syscore_ops);
777 778
	cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
				  mc_cpu_online, mc_cpu_down_prep);
P
Peter Oruba 已提交
779

780
	pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION);
P
Peter Oruba 已提交
781

P
Peter Oruba 已提交
782
	return 0;
783

784 785 786 787 788
 out_ucode_group:
	sysfs_remove_group(&cpu_subsys.dev_root->kobj,
			   &cpu_root_microcode_group);

 out_driver:
789 790 791
	get_online_cpus();
	mutex_lock(&microcode_mutex);

792
	subsys_interface_unregister(&mc_cpu_interface);
793 794 795 796

	mutex_unlock(&microcode_mutex);
	put_online_cpus();

797
 out_pdev:
798 799 800
	platform_device_unregister(microcode_pdev);
	return error;

P
Peter Oruba 已提交
801
}
802
fs_initcall(save_microcode_in_initrd);
803
late_initcall(microcode_init);