kernel: kernel_boot reads microcode from each initramfs image (issue 1977, L6)
Replaces the state record read (root's 0700) with images_with_microcode per /boot/initramfs-*.img: true when the first 64 KiB hold a path under kernel/x86/microcode/; an unreadable image goes to image_errors with its error. Test: 1977/AC5. Builds: L6 (issue 1977 note 3)
This commit is contained in:
@@ -4,6 +4,8 @@ package main
|
||||
// whether the fallback kernel is on the menu (novox/hq ADR 0508 §9, issue 1841). Reads only.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@@ -25,28 +27,48 @@ type BootState struct {
|
||||
BootFreeKiB int64 `json:"boot_free_kib"`
|
||||
// MicrocodeRevision is the revision the CPU runs, the first "microcode" line of /proc/cpuinfo ("" when it has none).
|
||||
MicrocodeRevision string `json:"microcode_revision"`
|
||||
// ImagesBuiltWithMicrocode is true when the initramfs images were last built with the microcode drop-in as it is now
|
||||
// (novox/hq issue 1977).
|
||||
ImagesBuiltWithMicrocode bool `json:"images_built_with_microcode"`
|
||||
// ImagesWithMicrocode is, per /boot/initramfs-*.img, whether the image's early uncompressed cpio (its first 64 KiB)
|
||||
// holds a path under kernel/x86/microcode/ (novox/hq issue 1977).
|
||||
ImagesWithMicrocode map[string]bool `json:"images_with_microcode"`
|
||||
// ImageErrors names each image that could not be read and why: such an image is in no verdict above.
|
||||
ImageErrors []ImageError `json:"image_errors"`
|
||||
}
|
||||
|
||||
// stateDir is the module's own directory on the machine, where the initramfs script records the drop-in it built with.
|
||||
const stateDir = "var/lib/mesh-kernel"
|
||||
|
||||
const microcodeDropIn = "etc/mkinitcpio.conf.d/mesh-microcode.conf"
|
||||
// ImageError is an initramfs image that could not be read.
|
||||
type ImageError struct {
|
||||
Image string `json:"image"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
var cpuMicrocode = regexp.MustCompile(`(?m)^microcode\s*:\s*(\S+)`)
|
||||
|
||||
// microcode reads the revision the CPU runs and whether the images carry the drop-in as it is now.
|
||||
// microcode reads the revision the CPU runs and which initramfs images carry microcode.
|
||||
func (m *Machine) microcode(b *BootState) {
|
||||
b.ImagesWithMicrocode = map[string]bool{}
|
||||
b.ImageErrors = []ImageError{}
|
||||
if raw, err := m.read("proc/cpuinfo"); err == nil {
|
||||
if r := cpuMicrocode.FindStringSubmatch(raw); r != nil {
|
||||
b.MicrocodeRevision = r[1]
|
||||
}
|
||||
}
|
||||
built, err := m.read(stateDir + "/initramfs-built")
|
||||
now, err2 := m.read(microcodeDropIn)
|
||||
b.ImagesBuiltWithMicrocode = err == nil && err2 == nil && built == now
|
||||
images, _ := filepath.Glob(m.path("boot/initramfs-*.img"))
|
||||
sort.Strings(images)
|
||||
for _, img := range images {
|
||||
name := filepath.Base(img)
|
||||
f, err := os.Open(img)
|
||||
if err != nil {
|
||||
b.ImageErrors = append(b.ImageErrors, ImageError{name, err.Error()})
|
||||
continue
|
||||
}
|
||||
head := make([]byte, 64*1024)
|
||||
n, err := io.ReadFull(f, head)
|
||||
f.Close()
|
||||
if err != nil && err != io.ErrUnexpectedEOF && err != io.EOF {
|
||||
b.ImageErrors = append(b.ImageErrors, ImageError{name, err.Error()})
|
||||
continue
|
||||
}
|
||||
b.ImagesWithMicrocode[name] = bytes.Contains(head[:n], []byte("kernel/x86/microcode/"))
|
||||
}
|
||||
}
|
||||
|
||||
var grubKernel = regexp.MustCompile(`(?m)^\s*linux\s+(?:/boot)?/(vmlinuz-\S+)`)
|
||||
|
||||
Reference in New Issue
Block a user