|
| 1 | +From a3664422075e1dfbea2ebad5e66b3ced1a16e8b4 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Arthur Sengileyev <arthur.sengileyev@gmail.com> |
| 3 | +Date: Wed, 13 May 2026 18:36:37 +0300 |
| 4 | +Subject: [PATCH] Remove deprecated `_LIMA_QEMU_UEFI_IN_BIOS` feature |
| 5 | + |
| 6 | +This was implemented to support QEMU version before 11.0.0, but since |
| 7 | +there is no LTS releases for QEMU on Windows the minimal version is |
| 8 | +bumped to the one not needing special handling. |
| 9 | + |
| 10 | +Signed-off-by: Arthur Sengileyev <arthur.sengileyev@gmail.com> |
| 11 | +--- |
| 12 | + pkg/driver/qemu/qemu.go | 135 +++--------------- |
| 13 | + pkg/limatype/filenames/filenames.go | 1 - |
| 14 | + .../en/docs/config/environment-variables.md | 11 -- |
| 15 | + 3 files changed, 18 insertions(+), 129 deletions(-) |
| 16 | + |
| 17 | +diff --git a/pkg/driver/qemu/qemu.go b/pkg/driver/qemu/qemu.go |
| 18 | +index 91c0ba13..ddc534a3 100644 |
| 19 | +--- a/pkg/driver/qemu/qemu.go |
| 20 | ++++ b/pkg/driver/qemu/qemu.go |
| 21 | +@@ -9,7 +9,6 @@ import ( |
| 22 | + "encoding/json" |
| 23 | + "errors" |
| 24 | + "fmt" |
| 25 | +- "io" |
| 26 | + "io/fs" |
| 27 | + "os" |
| 28 | + "os/exec" |
| 29 | +@@ -73,6 +72,8 @@ func minimumQemuVersion() (hardMin, softMin semver.Version) { |
| 30 | + // was removed in https://github.com/lima-vm/lima/pull/3491 |
| 31 | + h, s = "7.0.0", "8.2.1" |
| 32 | + } |
| 33 | ++ case "windows": |
| 34 | ++ h, s = "11.0.0", "11.0.0" |
| 35 | + default: |
| 36 | + // hardMin: Untested and maybe does not even work. |
| 37 | + // softMin: Ubuntu 22.04's QEMU. The oldest version that can be easily tested on GitHub Actions. |
| 38 | +@@ -563,14 +564,6 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er |
| 39 | + // This will disable CPU S3/S4 state. |
| 40 | + args = append(args, "-global", "ICH9-LPC.disable_s3=1") |
| 41 | + args = append(args, "-global", "ICH9-LPC.disable_s4=1") |
| 42 | +- case "whpx": |
| 43 | +- if version.LessThan(*semver.New("11.0.0")) { |
| 44 | +- // Older versions of QEMU required disabling `kernel-irqchip` explicitly. |
| 45 | +- // It is not recommended to keep using this with QEMU 11.0.0 and newer. |
| 46 | +- args = appendArgsIfNoConflict(args, "-machine", "q35,accel="+accel+",kernel-irqchip=off") |
| 47 | +- } else { |
| 48 | +- args = appendArgsIfNoConflict(args, "-machine", "q35,accel="+accel) |
| 49 | +- } |
| 50 | + default: |
| 51 | + args = appendArgsIfNoConflict(args, "-machine", "q35,accel="+accel) |
| 52 | + } |
| 53 | +@@ -609,45 +602,26 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er |
| 54 | + noFirmware := *y.Arch == limatype.PPC64LE || *y.Arch == limatype.S390X || legacyBIOS |
| 55 | + if !noFirmware { |
| 56 | + var firmware string |
| 57 | +- firmwareInBios := runtime.GOOS == "windows" && version.LessThan(*semver.New("11.0.0")) |
| 58 | +- if envVar := os.Getenv("_LIMA_QEMU_UEFI_IN_BIOS"); envVar != "" { |
| 59 | +- logrus.Warn("use of deprecated _LIMA_QEMU_UEFI_IN_BIOS") |
| 60 | +- b, err := strconv.ParseBool(envVar) |
| 61 | +- if err != nil { |
| 62 | +- logrus.WithError(err).Warnf("invalid _LIMA_QEMU_UEFI_IN_BIOS value %#q", envVar) |
| 63 | +- } else { |
| 64 | +- firmwareInBios = b |
| 65 | +- } |
| 66 | +- } |
| 67 | +- firmwareInBios = firmwareInBios && *y.Arch == limatype.X8664 |
| 68 | + downloadedFirmware := filepath.Join(cfg.InstanceDir, filenames.QemuEfiCodeFD) |
| 69 | +- firmwareWithVars := filepath.Join(cfg.InstanceDir, filenames.QemuEfiFullFD) |
| 70 | +- if firmwareInBios { |
| 71 | +- if _, stErr := os.Stat(firmwareWithVars); stErr == nil { |
| 72 | +- firmware = firmwareWithVars |
| 73 | +- logrus.Infof("Using existing firmware (%#q)", firmware) |
| 74 | +- } |
| 75 | +- } else { |
| 76 | +- if _, stErr := os.Stat(downloadedFirmware); errors.Is(stErr, os.ErrNotExist) { |
| 77 | +- loop: |
| 78 | +- for _, f := range y.Firmware.Images { |
| 79 | +- switch f.VMType { |
| 80 | +- case "", limatype.QEMU: |
| 81 | +- if f.Arch == *y.Arch { |
| 82 | +- if _, err = fileutils.DownloadFile(ctx, downloadedFirmware, f.File, true, "UEFI code "+f.Location, *y.Arch); err != nil { |
| 83 | +- logrus.WithError(err).Warnf("failed to download %#q", f.Location) |
| 84 | +- continue loop |
| 85 | +- } |
| 86 | +- firmware = downloadedFirmware |
| 87 | +- logrus.Infof("Using firmware %#q (downloaded from %#q)", firmware, f.Location) |
| 88 | +- break loop |
| 89 | ++ if _, stErr := os.Stat(downloadedFirmware); errors.Is(stErr, os.ErrNotExist) { |
| 90 | ++ loop: |
| 91 | ++ for _, f := range y.Firmware.Images { |
| 92 | ++ switch f.VMType { |
| 93 | ++ case "", limatype.QEMU: |
| 94 | ++ if f.Arch == *y.Arch { |
| 95 | ++ if _, err = fileutils.DownloadFile(ctx, downloadedFirmware, f.File, true, "UEFI code "+f.Location, *y.Arch); err != nil { |
| 96 | ++ logrus.WithError(err).Warnf("failed to download %#q", f.Location) |
| 97 | ++ continue loop |
| 98 | + } |
| 99 | ++ firmware = downloadedFirmware |
| 100 | ++ logrus.Infof("Using firmware %#q (downloaded from %#q)", firmware, f.Location) |
| 101 | ++ break loop |
| 102 | + } |
| 103 | + } |
| 104 | +- } else { |
| 105 | +- firmware = downloadedFirmware |
| 106 | +- logrus.Infof("Using existing firmware (%#q)", firmware) |
| 107 | + } |
| 108 | ++ } else { |
| 109 | ++ firmware = downloadedFirmware |
| 110 | ++ logrus.Infof("Using existing firmware (%#q)", firmware) |
| 111 | + } |
| 112 | + if firmware == "" { |
| 113 | + firmware, err = getFirmware(exe, *y.Arch) |
| 114 | +@@ -655,45 +629,9 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er |
| 115 | + return "", nil, err |
| 116 | + } |
| 117 | + logrus.Infof("Using system firmware (%#q)", firmware) |
| 118 | +- if firmwareInBios { |
| 119 | +- firmwareVars, err := getFirmwareVars(exe, *y.Arch) |
| 120 | +- if err != nil { |
| 121 | +- return "", nil, err |
| 122 | +- } |
| 123 | +- logrus.Infof("Using system firmware vars (%#q)", firmwareVars) |
| 124 | +- varsFile, err := os.Open(firmwareVars) |
| 125 | +- if err != nil { |
| 126 | +- return "", nil, err |
| 127 | +- } |
| 128 | +- defer varsFile.Close() |
| 129 | +- codeFile, err := os.Open(firmware) |
| 130 | +- if err != nil { |
| 131 | +- return "", nil, err |
| 132 | +- } |
| 133 | +- defer codeFile.Close() |
| 134 | +- resultFile, err := os.OpenFile(firmwareWithVars, os.O_CREATE|os.O_WRONLY, 0o644) |
| 135 | +- if err != nil { |
| 136 | +- return "", nil, err |
| 137 | +- } |
| 138 | +- defer resultFile.Close() |
| 139 | +- _, err = io.Copy(resultFile, varsFile) |
| 140 | +- if err != nil { |
| 141 | +- return "", nil, err |
| 142 | +- } |
| 143 | +- _, err = io.Copy(resultFile, codeFile) |
| 144 | +- if err != nil { |
| 145 | +- return "", nil, err |
| 146 | +- } |
| 147 | +- firmware = firmwareWithVars |
| 148 | +- } |
| 149 | + } |
| 150 | + if firmware != "" { |
| 151 | +- if firmwareInBios { |
| 152 | +- logrus.Warn("firmware in `-bios` is deprecated, consider upgrading to QEMU supporting `-drive if=pflash`") |
| 153 | +- args = append(args, "-bios", firmware) |
| 154 | +- } else { |
| 155 | +- args = append(args, "-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", firmware)) |
| 156 | +- } |
| 157 | ++ args = append(args, "-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", firmware)) |
| 158 | + } |
| 159 | + } |
| 160 | + |
| 161 | +@@ -1244,43 +1182,6 @@ func getFirmware(qemuExe string, arch limatype.Arch) (string, error) { |
| 162 | + return "", fmt.Errorf("could not find firmware for %#q (hint: try copying the `edk-%s-code.fd` firmware to $HOME/.local/share/qemu/)", arch, qemuArch) |
| 163 | + } |
| 164 | + |
| 165 | +-func getFirmwareVars(qemuExe string, arch limatype.Arch) (string, error) { |
| 166 | +- var targetArch string |
| 167 | +- switch arch { |
| 168 | +- case limatype.X8664: |
| 169 | +- targetArch = "i386" // vars are unified between i386 and x86_64 and normally only former is bundled |
| 170 | +- default: |
| 171 | +- return "", fmt.Errorf("unexpected architecture: %#q", arch) |
| 172 | +- } |
| 173 | +- |
| 174 | +- homeDir, err := os.UserHomeDir() |
| 175 | +- if err != nil { |
| 176 | +- return "", err |
| 177 | +- } |
| 178 | +- |
| 179 | +- binDir := filepath.Dir(qemuExe) // "/usr/local/bin" |
| 180 | +- localDir := filepath.Dir(binDir) // "/usr/local" |
| 181 | +- userLocalDir := filepath.Join(homeDir, ".local") // "$HOME/.local" |
| 182 | +- |
| 183 | +- relativePath := fmt.Sprintf("share/qemu/edk2-%s-vars.fd", qemuEdk2Arch(targetArch)) |
| 184 | +- relativePathWin := fmt.Sprintf("share/edk2-%s-vars.fd", qemuEdk2Arch(targetArch)) |
| 185 | +- candidates := []string{ |
| 186 | +- filepath.Join(userLocalDir, relativePath), // XDG-like |
| 187 | +- filepath.Join(localDir, relativePath), // macOS (homebrew) |
| 188 | +- filepath.Join(binDir, relativePathWin), // Windows installer |
| 189 | +- } |
| 190 | +- |
| 191 | +- logrus.Debugf("firmware vars candidates = %v", candidates) |
| 192 | +- |
| 193 | +- for _, f := range candidates { |
| 194 | +- if _, err := os.Stat(f); err == nil { |
| 195 | +- return f, nil |
| 196 | +- } |
| 197 | +- } |
| 198 | +- |
| 199 | +- return "", fmt.Errorf("could not find firmware vars for %#q", arch) |
| 200 | +-} |
| 201 | +- |
| 202 | + var hasSMEDarwin = sync.OnceValue(func() bool { |
| 203 | + if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" { |
| 204 | + return false |
| 205 | +diff --git a/pkg/limatype/filenames/filenames.go b/pkg/limatype/filenames/filenames.go |
| 206 | +index 87e1e45c..8670b30c 100644 |
| 207 | +--- a/pkg/limatype/filenames/filenames.go |
| 208 | ++++ b/pkg/limatype/filenames/filenames.go |
| 209 | +@@ -69,7 +69,6 @@ const ( |
| 210 | + VzAux = "vz-aux" // macOS guests only |
| 211 | + VzEfi = "vz-efi" // efi variable store |
| 212 | + QemuEfiCodeFD = "qemu-efi-code.fd" // efi code; not always created |
| 213 | +- QemuEfiFullFD = "qemu-efi-full.fd" // concatenated efi vars and code; not always created |
| 214 | + AnsibleInventoryYAML = "ansible-inventory.yaml" |
| 215 | + |
| 216 | + // SocketDir is the default location for forwarded sockets with a relative paths in HostSocket. |
| 217 | +diff --git a/website/content/en/docs/config/environment-variables.md b/website/content/en/docs/config/environment-variables.md |
| 218 | +index 3263387d..373c261e 100644 |
| 219 | +--- a/website/content/en/docs/config/environment-variables.md |
| 220 | ++++ b/website/content/en/docs/config/environment-variables.md |
| 221 | +@@ -147,17 +147,6 @@ This page documents the environment variables used in Lima. |
| 222 | + export LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT=5 |
| 223 | + ``` |
| 224 | + |
| 225 | +-### `_LIMA_QEMU_UEFI_IN_BIOS` |
| 226 | +- |
| 227 | +-- **Description**: Commands QEMU to load x86_64 UEFI images using `-bios` instead of `pflash` drives. |
| 228 | +-- **Default**: `false` on Unix like hosts and `true` on Windows hosts (if QEMU is older than 11.0.0) |
| 229 | +-- **Usage**: |
| 230 | +- ```sh |
| 231 | +- export _LIMA_QEMU_UEFI_IN_BIOS=true |
| 232 | +- ``` |
| 233 | +-- **Note**: This variable is deprecated and is expected to be removed, when minimal supported QEMU version |
| 234 | +- on Windows is adjusted. |
| 235 | +- |
| 236 | + ### `_LIMA_WINDOWS_EXTRA_PATH` |
| 237 | + |
| 238 | + - **Description**: Additional directories which will be added to PATH by `limactl.exe` process to search for tools. |
| 239 | +-- |
| 240 | +2.54.0 |
| 241 | + |
0 commit comments