AMD microcode não atualizando

5

Eu instalei recentemente o Gentoo Linux no meu AMD Ryzen 7 1700X. Agora eu enfrento falhas de segmentação durante cargas pesadas de compilação e também reinicia aleatoriamente em um estado ocioso .

Como primeiro passo, verifiquei a versão atual do microcódigo:

grep -m 1 microcode /proc/cpuinfo
microcode       : 0x8001126

No entanto, de acordo com esta tabela , o microcódigo mais recente deve ser 0x08001129. Assim, parece ser uma boa idéia atualizar o microcódigo para a CPU.

Então eu saí =sys-kernel/linux-firmware-20180730 (contendo /lib/firmware/amd-ucode/microcode_amd_fam17h.bin ). Além disso, habilitei as seguintes opções no kernel:

CONFIG_MICROCODE=y
CONFIG_MICROCODE_AMD=y

Após a reinicialização, tentei carregar o microcódigo manualmente (atualização tardia do microcódigo):

echo 1 > /sys/devices/system/cpu/microcode/reload

No entanto, quando faço isso, nenhuma nova linha aparece em dmesg :

dmesg | grep microcode
[    0.465121] microcode: CPU0: patch_level=0x08001126
[    0.465514] microcode: CPU1: patch_level=0x08001126
[    0.465932] microcode: CPU2: patch_level=0x08001126
[    0.466394] microcode: CPU3: patch_level=0x08001126
[    0.466772] microcode: CPU4: patch_level=0x08001126
[    0.467159] microcode: CPU5: patch_level=0x08001126
[    0.467537] microcode: CPU6: patch_level=0x08001126
[    0.467908] microcode: CPU7: patch_level=0x08001126
[    0.468268] microcode: CPU8: patch_level=0x08001126
[    0.468653] microcode: CPU9: patch_level=0x08001126
[    0.468999] microcode: CPU10: patch_level=0x08001126
[    0.469409] microcode: CPU11: patch_level=0x08001126
[    0.469744] microcode: CPU12: patch_level=0x08001126
[    0.470136] microcode: CPU13: patch_level=0x08001126
[    0.470455] microcode: CPU14: patch_level=0x08001126
[    0.470757] microcode: CPU15: patch_level=0x08001126
[    0.471092] microcode: Microcode Update Driver: v2.2.

Eu esperaria algo como microcode: CPU0: new patch_level=0x08001129 . O que estou perdendo aqui? Algum kernel CONFIG_ opção? Posso ativar algum tipo de informação de depuração? Ou melhor ainda - como posso listar a versão do microcódigo fornecida em microcode_amd_fam17h.bin ?

    
por DaBler 07.09.2018 / 14:23

1 resposta

3

Você pode tentar algo assim:

CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_MICROCODE=y
# CONFIG_MICROCODE_INTEL is not set
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_FW_LOADER=y
CONFIG_EXTRA_FIRMWARE="amd-ucode/microcode_amd_fam17h.bin"
CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
# CONFIG_FW_LOADER_USER_HELPER is not set

(Observe que, se você quiser listar mais de um arquivo em CONFIG_EXTRA_FIRMWARE , eles devem ser separados por espaços e seus caminhos devem ser relativos a CONFIG_EXTRA_FIRMWARE_DIR .)

Mas isso possivelmente não funcionará (funciona para mim se estiver usando apenas gráficos e firmware de rede, não tentei usar o firmware da CPU), então tente de outra forma: ignore o valor de CONFIG_EXTRA_FIRMWARE acima (ou seja. não o configure, mas talvez os outros ainda sejam necessários, inseguros) e tente carregar o microcódigo antes colocando o arquivo de microcódigo da CPU no arquivo initramfs, talvez algo assim (no Gentoo):

/etc/kernel/postinst.d/25-glue_cpu_microcode_to_kernel :

#!/bin/bash

bootdir='/bewt'
initramfsfname="initramfs"
initramfs="$( realpath -- "/${bootdir}/${initramfsfname}" )"
vmlinuz="/${bootdir}/kernel"

prepend_microcode () {
  echo "prepending CPU microcode to ${initramfs}"
  local destfirst="/tmp/initrd/"
  local destmc="${destfirst}/kernel/x86/microcode/"
#  mkdir -p "${destmc}"
    install -dm644 "${destmc}"

  #this will replace the symlink /bewt/initramfs (on gentoo) with the file!
  #but this makes genkernel fail as such: 
  #ln: failed to create symbolic link 'initramfs.old' -> '': No such file or directory
  #even though it doesn't touch the .old file!
  # so to fix this, we'll use realpath above!

  ( cp -f "/lib/firmware/amd-ucode/microcode_amd.bin" "${destmc}/AuthenticAMD.bin" && cd "${destfirst}" && find . | cpio -o -H newc > "../ucode.cpio" 2>/dev/null && cd .. && cat "ucode.cpio" "${initramfs}" > "/tmp/${initramfsfname}" && chmod a-rwx "/tmp/${initramfsfname}" && mv -f "/tmp/${initramfsfname}" "${initramfs}" )
    local ec=$?
    if [[ $ec -eq 0 ]]; then
        echo "success."
    else
        #TODO: make errors be red so it's more obvious
        echo "failed!"
    fi
    return $ec
}

prepend_microcode

No entanto genkernel pode (ainda? 3 anos depois) ignorar arquivos em /etc/kernel/postinst.d/ (ou isso só estava acontecendo em 2015 e foi corrigido desde, ou talvez por outras razões), o que significa que você terá que manualmente execute genkernel yourself (para compilar o kernel) e, em seguida, depois disso, execute manualmente todos os scripts presente em /etc/kernel/postinst.d/ , isso parece isso :

echo "!! Running genkernel..." time genkernel all --bootdir="/bewt" --install --symlink --no-splash --no-mountboot --makeopts="-j4 V=0" --no-keymap --lvm --no-mdadm --no-dmraid --no-zfs --no-multipath --no-iscsi --disklabel --luks --no-gpg --no-netboot --no-unionfs --no-firmware --no-integrated-initramfs --compress-initramfs --compress-initrd --compress-initramfs-type=best --loglevel=5 --color --no-mrproper --no-clean --no-postclear --oldconfig ec="$?" if test "$ec" -ne "0"; then echo "!! genkernel failed $ec" exit "$ec" fi echo "!! Done genkernel" list=( 'find /etc/kernel/postinst.d -type f -executable | sort --general-numeric-sort' ) echo "!! Found executables: ${list[@]}" for i in ${list[@]}; do ec="-1" while test "0" -ne "$ec"; do echo "!! Executing: '$i'" time $i ec="$?" echo "!! Exit code: $ec" if test "$ec" -ne "0"; then echo "!! something went wrong, fix it then press Enter to retry executing '$i' or press C-c now." #exit $ec time read -p -s "!! Press Enter to re-execute that or C-c to cancel" fi done done

(nota: o bootdir usado acima é /bewt em vez de /boot , então você pode querer mudar pelo menos isso; também a string microcode_amd.bin acima deve ser substituída pela sua: microcode_amd_fam17h.bin )
Que list= e for acima não são a maneira correta de lidar com nomes de arquivos, a menos que eles não tenham espaços , newlines etc. que é obviamente assumido acima.

Se você quiser dar uma olhada no antigo kernel 4.1.7 .config que fez o carregamento antecipado do cpu-firmware, veja este .

    
por 14.09.2018 / 03:12