# CPU microcode loading - consistency

## depontius

So I've finally decided it's time that I loaded the microcode updates for my CPUs.  Things seem to have settled pretty well and systems don't seem to be getting bricked, any more.  I don't know how much Meltdown/Spectre is being used in the wild, but it just seems like past time to have the best set of mitigations in place.  I already have proper kernels, a newer Firefox that doesn't give away fine-grained timing information, and I believe Chrome is at the same place.

There are three different sets of instruction for microcode updates - Generic, AMD, and Intel.  They're all different.

Actually, the Intel instructions seem to be a superset of the Generic instructions - more options for how to do the job.  The AMD instructions specify one and only one way to do it, which isn't really covered by the Generic instructions.

I'll also state right up front that I don't like the AMD instructions.  They involve a long ugly concatenated configuration line enumerating the microcode, and the microcode will be on top of my GPU microcode that's already there.

I use genkernel - it turns kernel builds into a fire-and-forget process.  Come back a while later and it's all done.  I use the initramfs because it's there, etc, etc, etc.  It's all just easy for me.

I just did the microcode stuff for my Intel-based laptop, and used the "genkernel method".  I'd like to do the same for my AMD systems at home, preferably also getting rid of that big long configuration line for the GPU at the same time.

Is there a reason AMD is so different, or is it because that's the way whoever wrote the documentation did it?

----------

## NeddySeagoon

depontius,

Once upon a time, the module way just worked. Over the last few years, it fails for Intel.

I do build the firmware updater into the kernel and build the firmware into the kernel now.

That works for both Intel and AMD.

----------

## Ant P.

I think you've got it backwards: AMD microcode uses the standard firmware loading mechanism all other drivers do, that's why the embedded firmware line ends up so long. Intel's microcode is the scary one: it's encrypted, uses a non-standard loader, is prone to crashing the system if loaded at the wrong time, and the instructions differ wildly depending on whether your CPU is 32 or 64 bit because they phoned it in when they wrote the driver (and the hardware...)

----------

## depontius

Well this evening I started with my computer, the in-kernel way...

```
CONFIG_PREVENT_FIRMWARE_BUILD=y

CONFIG_FW_LOADER=y

# CONFIG_FIRMWARE_IN_KERNEL is not set

CONFIG_EXTRA_FIRMWARE="radeon/KAVERI_ce.bin radeon/KAVERI_me.bin radeon/KAVERI_mec.bin radeon/KAVERI_pfp.bin radeon/KAVERI_rlc.bin radeon/KAVERI_sdma.bin radeon/BONAIRE_uvd.bin radeon/BONAIRE_vce.bin amd-ucode/microcode_amd_fam15h.bin"

CONFIG_EXTRA_FIRMWARE_DIR="/lib64/firmware"

# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
```

and I see no trace of the microcode loading from dmesg.  I suppose it's possible that it rolled off the top, because dmesg starts with 

```
[    1.313266] cdrom: Uniform CD-ROM driver Revision: 3.20

[    1.313451] sr 2:0:0:0: Attached scsi CD-ROM sr0

[    1.318926]  sda: sda1 sda2 sda3 sda4 sda5 sda6

[    1.319583] sd 0:0:0:0: [sda] Attached SCSI disk

[    1.320754] Freeing unused kernel memory: 1424K

[    1.320758] Write protecting the kernel read-only data: 14336k

[    1.321477] Freeing unused kernel memory: 2020K

[    1.323747] Freeing unused kernel memory: 1160K

[    1.330975] x86/mm: Checked W+X mappings: passed, no W+X pages found.

[    1.330981] rodata_test: all tests were successful
```

However when I run the spectre-meltdown-checker...

```
# /local/dale/spectre-meltdown-checker.sh 

Spectre and Meltdown mitigation detection tool v0.13

Checking vulnerabilities against Linux 4.15.12-gentoo #1 SMP Thu Mar 22 18:06:27 EDT 2018 x86_64

CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1'

* Kernel compiled with LFENCE opcode inserted at the proper places:  UNKNOWN  (couldn't find your kernel image in /boot, if you used netboot, this is normal)

> STATUS:  UNKNOWN 

CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2'

* Mitigation 1

*   Hardware (CPU microcode) support for mitigation:  NO 

*   Kernel support for IBRS:  NO 

*   IBRS enabled for Kernel space:  NO 

*   IBRS enabled for User space:  NO 

* Mitigation 2

*   Kernel compiled with retpolines:  YES 

> STATUS:  NOT VULNERABLE  (your CPU is not vulnerable as per the vendor)

CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3'

* Kernel supports Page Table Isolation (PTI):  NO 

* PTI enabled and active:  NO 

> STATUS:  NOT VULNERABLE  (your CPU is not vulnerable as per the vendor)
```

I'm not sure why it can't find my running kernel image, because I mounted /boot before running the command.  Because I use rEFInd I do have to rename the kernel image, so maybe that's the problem.  However it doesn't see the microcode support, and it did on my Intel laptop.

----------

## ct85711

Well, the first thing to check to ensure you are using the correct kernel, is looking at uname -a...  If it's a new kernel version, it should show that version, if it was a rebuild it would have a #2 (may be higher than 2, depending on how many times you recompiled it).

Otherwise, if you have CONFIG_IKCONFIG_PROC set in your kernel, you can grep your running kernel's config to make sure it have the firmware set.  Grepping the config at /usr/src/linux does not necessarily mean you are checking the running kernel's config.

----------

## depontius

```
$ uname -a

Linux localhost 4.15.12-gentoo #1 SMP Thu Mar 22 18:06:27 EDT 2018 x86_64 AMD A10-7850K APU with Radeon(TM) R7 Graphics AuthenticAMD GNU/Linux

$ cp /proc/config.gz /tmp

$ cd /tmp

$ gunzip config.gz 

$ grep radeon config 

CONFIG_EXTRA_FIRMWARE="radeon/KAVERI_ce.bin radeon/KAVERI_me.bin radeon/KAVERI_mec.bin radeon/KAVERI_pfp.bin radeon/KAVERI_rlc.bin radeon/KAVERI_sdma.bin radeo/BONAIRE_uvd.bin radeon/BONAIRE_vce.bin amd-ucode/microcode_amd_fam15h.bin"

$ 
```

Has anyone else run spectre-meltdown-checker.sh before and after doing the microcode thing?

----------

## Hu

 *depontius wrote:*   

> and I see no trace of the microcode loading from dmesg.  I suppose it's possible that it rolled off the top, because dmesg starts with 
> 
> ```
> [    1.313266] cdrom: Uniform CD-ROM driver Revision: 3.20
> ```
> ...

 In other threads here where people have reported using microcode, it appears to be the very first message printed, before anything else, and right at time 0.00000 before the timer starts ticking.  Based on your output shown, if you got a message about microcode, it definitely would have scrolled off by now.

----------

## theotherjoe

depontius, 

additionally check the following options in your .config

```
...

#

# Performance monitoring

#

...

CONFIG_MICROCODE=y

# CONFIG_MICROCODE_INTEL is not set

CONFIG_MICROCODE_AMD=y

CONFIG_MICROCODE_OLD_INTERFACE=y

...

```

edit: the microcode update will show up in dmesg output similar to the following:

```
...

[    3.922996] microcode: microcode updated early to new patch_level=0x0600084f

[    3.924670] microcode: CPU0: patch_level=0x0600084f

[    3.926327] microcode: CPU1: patch_level=0x0600084f

[    3.927914] microcode: CPU2: patch_level=0x0600084f

[    3.929493] microcode: CPU3: patch_level=0x0600084f

[    3.931382] microcode: CPU4: patch_level=0x0600084f

[    3.932886] microcode: CPU5: patch_level=0x0600084f

[    3.934368] microcode: Microcode Update Driver: v2.2.

...

```

----------

## Ant P.

Here's what my kernel says, this is the closest hardware I have to yours...

```
~ # dmesg | ack microcode

[    5.009472] microcode: microcode updated early to new patch_level=0x05000029

[    5.009557] microcode: CPU0: patch_level=0x05000029

[    5.009572] microcode: CPU1: patch_level=0x05000029

[    5.009717] microcode: Microcode Update Driver: v2.2.

~ # grep '' /sys/devices/system/cpu/vulnerabilities/*

/sys/devices/system/cpu/vulnerabilities/meltdown:Not affected

/sys/devices/system/cpu/vulnerabilities/spectre_v1:Mitigation: __user pointer sanitization

/sys/devices/system/cpu/vulnerabilities/spectre_v2:Mitigation: Full AMD retpoline

~ # lscpu

Architecture:        x86_64

CPU op-mode(s):      32-bit, 64-bit

Byte Order:          Little Endian

CPU(s):              2

On-line CPU(s) list: 0,1

Thread(s) per core:  1

Core(s) per socket:  2

Socket(s):           1

Vendor ID:           AuthenticAMD

CPU family:          20

Model:               1

Model name:          AMD E-350 Processor

Stepping:            0

CPU MHz:             928.796

CPU max MHz:         1600.0000

CPU min MHz:         800.0000

BogoMIPS:            3201.12

Virtualization:      AMD-V

L1d cache:           32K

L1i cache:           32K

L2 cache:            512K

Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf pni monitor ssse3 cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch ibs skinit wdt hw_pstate vmmcall arat npt lbrv svm_lock nrip_save pausefilter

~ # zegrep '^[^#].*(FIRMWARE|MICROCODE)' /proc/config.gz

CONFIG_MICROCODE=y

CONFIG_MICROCODE_AMD=y

CONFIG_MICROCODE_OLD_INTERFACE=y

CONFIG_PREVENT_FIRMWARE_BUILD=y

CONFIG_EXTRA_FIRMWARE="radeon/PALM_me.bin radeon/PALM_pfp.bin radeon/SUMO_uvd.bin radeon/SUMO_rlc.bin amd-ucode/microcode_amd.bin rtl_nic/rtl8168e-2.fw regulatory.db"

CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"

CONFIG_FIRMWARE_MEMMAP=y
```

And the spectre-meltdown-checker.sh output (with the angry fruit salad colours preserved for authenticity  :Wink:  ):

 *Quote:*   

> ~ # bash ~ant/spectre-meltdown-checker.sh
> 
> Spectre and Meltdown mitigation detection tool v0.13
> 
> Checking vulnerabilities against Linux 4.15.12-zen-413672-gea387c808407 #31 ZEN SMP PREEMPT Thu Mar 22 23:07:37 GMT 2018 x86_64
> ...

 

----------

## NeddySeagoon

depontius,

amd-ucode/microcode_amd_fam15h.bin is only half the microcode.

You also need  amd-ucode/microcode_amd.bin.

```
CONFIG_MICROCODE_AMD=y

CONFIG_MICROCODE_OLD_INTERFACE=y

CONFIG_EXTRA_FIRMWARE="amdgpu/polaris11_ce.bin amdgpu/polaris11_ce_2.bin amdgpu/polaris11_mc.bin amdgpu/polaris11_me_2.bin amdgpu/polaris11_me.bin amdgpu/polaris11_mec2.bin amdgpu/polaris11_mec2_2.bin  amdgpu/polaris11_mec.bin amdgpu/polaris11_mec_2.bin amdgpu/polaris11_pfp.bin amdgpu/polaris11_pfp_2.bin amdgpu/polaris11_rlc.bin amdgpu/polaris11_sdma1.bin amdgpu/polaris11_sdma.bin amdgpu/polaris11_smc.bin amdgpu/polaris11_smc_sk.bin amdgpu/polaris11_uvd.bin amdgpu/polaris11_vce.bin amd-ucode/microcode_amd.bin amd-ucode/microcode_amd_fam15h.bin amd-ucode/microcode_amd_fam16h.bin "
```

The amd-ucode/microcode_amd_fam16h.bin is not required for my Phenom II.

```
$ dmesg | grep micro

[    3.042949] microcode: microcode updated early to new patch_level=0x010000dc

[    3.044652] microcode: CPU0: patch_level=0x010000dc

[    3.046347] microcode: CPU1: patch_level=0x010000dc

[    3.048015] microcode: CPU2: patch_level=0x010000dc

[    3.049665] microcode: CPU3: patch_level=0x010000dc

[    3.051367] microcode: CPU4: patch_level=0x010000dc

[    3.052989] microcode: CPU5: patch_level=0x010000dc

[    3.054578] microcode: Microcode Update Driver: v2.2.
```

----------

## albright

about the scrolling off, /var/log/dmesg is complete

----------

## depontius

 *NeddySeagoon wrote:*   

> depontius,
> 
> amd-ucode/microcode_amd_fam15h.bin is only half the microcode.
> 
> You also need  amd-ucode/microcode_amd.bin.

 

That's not what the web page said:

```
You may want to only include the firmware suitable to your CPU family. To find it you can look at /proc/cpuinfo, which gives the decimal number:

grep -F -m 1 "cpu family" /proc/cpuinfo

cpu family      : 23

Now include only the one firmware blob for the given cpu family number: 
```

But I went ahead and followed your suggestion anyway.  No change.  I've just added the "microcode=yes" to genkernel.conf and am rebuilding.  At the moment I only have one remote session, so I can't check /var/log/dmesg.  I will when the new kernel is done.  I also just realized that I don't see any messages about the radeon microcode loading either, but I know or at least presume that that's working because my video works.

I checked the /sys/devices/system/cpu/vulnerabilities as Ant P suggests, and only have "minimal AMD retpoline", which is what I'd expect having only the kernel fixes and not compiler or microcode fixes.

----------

## NeddySeagoon

depontius,

The Radeon microcode used to only be required for 3D hardware acceleration.

There are no messages in dmesg about radeon microcode unless its missing, so no news is good news.

AMD claim that no microcode changes are required and that they are not vulnerable to meltdown.

I get 

```
$ cat  /sys/devices/system/cpu/vulnerabilities/*

Not affected

Mitigation: __user pointer sanitization

Mitigation: Full AMD retpoline
```

Thats with a 4.16-rc3 kernel and gcc-7.3.0

----------

## depontius

I get the same as you except:

```
$ cat  /sys/devices/system/cpu/vulnerabilities/*

Not affected

Mitigation: __user pointer sanitization

Mitigation: Minimal AMD ASM retpoline
```

So we're different on spectre_v2.  I know I got the ASM retpoline from my ~arch kernel and the correct options.  Are you adding microcode updates, or do you have a ~arch compiler?

----------

## NeddySeagoon

depontius,

Full AMD retpoline requires at least gcc-7.3.x.  Yes, its still ~arch. 

Minimal AMD ASM retpoline meats that the kernel assembler code has been fixed but the kernel has been built with a compiler that is not retpoline aware.

----------

## depontius

NeddySeagoon,

Are you running stock out of portage, or did you have to go outside, apply patches, etc.  I've been thinking of moving to gcc-7.3 for just this reason, but there isn't that much on the forums about it yet, especially compared to gcc-7.2.  At this point I see gcc-7.2 as mostly an exercise in using electricity.

----------

## NeddySeagoon

depontius,

Its stock out of portage. 

```
*  sys-devel/gcc

      Latest version available: 7.3.0-r1

      Latest version installed: 7.3.0
```

----------

## depontius

NeddySeagoon,

I see that I already have binutils-2.29-r1 installed, which should be sufficient, and binutils-2.30 is available.

Did you have to manually apply any spectre patches?  (Some have, but I'm not sure what gcc level that was against.)

Did you have any problems recompiling your system?  From what I've read, it sounds pretty safe, though not 100%, of course.

----------

## P.Kosunen

 *depontius wrote:*   

> 
> 
> ```
> $ cp /proc/config.gz /tmp
> 
> ...

 

Why not just:

```
zgrep radeon /proc/config.gz
```

?

----------

## NeddySeagoon

depontius,

There are no manual patches. The kernel build system uses retpoline if the compiler supports it.

That requires gcc-7.3.

I have rebuilt my system with   

```
CFLAGS=  "-march=native -mindirect-branch=thunk -O2 -pipe"

CXXFLAGS="-march=native -mindirect-branch=thunk -O2 -pipe"
```

to fix userspace too but 

a) I'm not sure that's correct

b) I'm not totally convinced its required.

On a 32 bit system, that is already well past its useful life, the performance hit makes it almost unusable.

----------

