Skip to content

Commit 4c4a898

Browse files
committed
Clean up codes for QEMU < 7.0
- QEMU 7.0 is documented as the minimum requirement since 9eb1396 (Dec 2022) - Also clean up the hint for QEMU 8.2.0, as QEMU 8.2.0 users should have already updated QEMU to 8.2.1+ - QEMU 4.0 is still exceptionally allowed on linux/amd64 for the compatibility reason, but not tested - QEMU 6.2 is added to the CI Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
1 parent d7ece61 commit 4c4a898

File tree

4 files changed

+66
-84
lines changed

4 files changed

+66
-84
lines changed

.github/workflows/test.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,34 @@ jobs:
508508
template: templates/default.yaml
509509
- name: Smoke test
510510
run: gomodjail run --go-mod=./go.mod -- limactl start --tty=false
511+
512+
qemu-linux-old:
513+
name: "Smoke tests (QEMU, old Linux host)"
514+
runs-on: ubuntu-22.04 # QEMU 6.2
515+
timeout-minutes: 30
516+
steps:
517+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
518+
with:
519+
# To avoid "failed to load YAML file \"templates/experimental/riscv64.yaml\": can't parse builtin Lima version \"3f3a6f6\": 3f3a6f6 is not in dotted-tri format"
520+
fetch-depth: 0
521+
- uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0
522+
with:
523+
go-version: 1.24.x
524+
- name: Make
525+
run: make
526+
- name: Install
527+
run: sudo make install
528+
- name: Cache image used by templates/default.yaml
529+
uses: ./.github/actions/setup_cache_for_template
530+
with:
531+
template: templates/default.yaml
532+
- name: Install test dependencies
533+
run: |
534+
sudo apt-get update
535+
sudo apt-get install -y --no-install-recommends ovmf qemu-system-x86 qemu-utils
536+
qemu-system-x86_64 --version
537+
sudo modprobe kvm
538+
# `sudo usermod -aG kvm $(whoami)` does not take an effect on GHA
539+
sudo chown $(whoami) /dev/kvm
540+
- name: Smoke test
541+
run: limactl start --tty=false

pkg/qemu/qemu.go

Lines changed: 17 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ import (
3838
"github.com/sirupsen/logrus"
3939
)
4040

41+
// RecommendedQemuVersion is the recommemded QEMU version.
42+
// See commit 8c48cb3eef178914f1b8fffee324aab0c445fec5 .
43+
const RecommendedQemuVersion = "7.1.0"
44+
4145
type Config struct {
4246
Name string
4347
InstanceDir string
@@ -47,11 +51,6 @@ type Config struct {
4751
VirtioGA bool
4852
}
4953

50-
// MinimumQemuVersion is the minimum supported QEMU version.
51-
const (
52-
MinimumQemuVersion = "4.0.0"
53-
)
54-
5554
// EnsureDisk also ensures the kernel and the initrd.
5655
func EnsureDisk(ctx context.Context, cfg Config) error {
5756
diffDisk := filepath.Join(cfg.InstanceDir, filenames.DiffDisk)
@@ -313,9 +312,6 @@ type features struct {
313312
// e.g. "Available CPUs:\n...\nx86 base...\nx86 host...\n...\n"
314313
// Not machine-readable, but checking strings.Contains() should be fine.
315314
CPUHelp []byte
316-
317-
// VersionGEQ7 is true when the QEMU version seems v7.0.0 or later
318-
VersionGEQ7 bool
319315
}
320316

321317
func inspectFeatures(exe, machine string) (*features, error) {
@@ -359,7 +355,6 @@ func inspectFeatures(exe, machine string) (*features, error) {
359355
f.MachineHelp = stderr.Bytes()
360356
}
361357
}
362-
f.VersionGEQ7 = strings.Contains(string(f.MachineHelp), "-7.0")
363358

364359
// Avoid error: "No machine specified, and there is no default"
365360
cmd = exec.Command(exe, "-cpu", "help", "-machine", machine)
@@ -377,56 +372,15 @@ func inspectFeatures(exe, machine string) (*features, error) {
377372
return &f, nil
378373
}
379374

380-
// showDarwinARM64HVFQEMU620Warning shows a warning on M1 macOS when QEMU is older than 6.2.0_1.
381-
//
382-
// See:
383-
// - https://gitlab.com/qemu-project/qemu/-/issues/899
384-
// - https://github.com/Homebrew/homebrew-core/pull/96743
385-
// - https://github.com/lima-vm/lima/issues/712
386-
func showDarwinARM64HVFQEMU620Warning(exe, accel string, features *features) {
387-
if runtime.GOOS != "darwin" {
388-
return
389-
}
390-
if runtime.GOARCH != "arm64" {
391-
return
392-
}
393-
if accel != "hvf" {
394-
return
395-
}
396-
if features.VersionGEQ7 {
397-
return
398-
}
399-
if exeFull, err := exec.LookPath(exe); err == nil {
400-
if exeResolved, err2 := filepath.EvalSymlinks(exeFull); err2 == nil {
401-
if strings.Contains(exeResolved, "Cellar/qemu/6.2.0_") {
402-
// Homebrew's QEMU 6.2.0_1 or later
403-
return
404-
}
405-
}
406-
}
407-
w := "This version of QEMU might not be able to boot recent Linux guests on M1 macOS hosts."
408-
if _, err := exec.LookPath("brew"); err == nil {
409-
w += "Run `brew upgrade` and make sure your QEMU version is 6.2.0_1 or later."
410-
} else {
411-
w += `Reinstall QEMU with the following commits (included in QEMU 7.0.0):
412-
- https://github.com/qemu/qemu/commit/ad99f64f "hvf: arm: Use macros for sysreg shift/masking"
413-
- https://github.com/qemu/qemu/commit/7f6c295c "hvf: arm: Handle unknown ID registers as RES0"
414-
`
415-
w += "See https://github.com/Homebrew/homebrew-core/pull/96743 for the further information."
416-
}
417-
logrus.Warn(w)
418-
}
419-
420375
// adjustMemBytesDarwinARM64HVF adjusts the memory to be <= 3 GiB, only when the following conditions are met:
421376
//
422377
// - Host OS < macOS 12.4
423378
// - Host Arch == arm64
424379
// - Accel == hvf
425-
// - QEMU >= 7.0
426380
//
427381
// This adjustment is required for avoiding host kernel panic. The issue was fixed in macOS 12.4 Beta 1.
428382
// See https://github.com/lima-vm/lima/issues/795 https://gitlab.com/qemu-project/qemu/-/issues/903#note_911000975
429-
func adjustMemBytesDarwinARM64HVF(memBytes int64, accel string, features *features) int64 {
383+
func adjustMemBytesDarwinARM64HVF(memBytes int64, accel string) int64 {
430384
const safeSize = 3 * 1024 * 1024 * 1024 // 3 GiB
431385
if memBytes <= safeSize {
432386
return memBytes
@@ -440,9 +394,6 @@ func adjustMemBytesDarwinARM64HVF(memBytes int64, accel string, features *featur
440394
if accel != "hvf" {
441395
return memBytes
442396
}
443-
if !features.VersionGEQ7 {
444-
return memBytes
445-
}
446397
macOSProductVersion, err := osutil.ProductVersion()
447398
if err != nil {
448399
logrus.Warn(err)
@@ -451,8 +402,8 @@ func adjustMemBytesDarwinARM64HVF(memBytes int64, accel string, features *featur
451402
if !macOSProductVersion.LessThan(*semver.New("12.4.0")) {
452403
return memBytes
453404
}
454-
logrus.Warnf("Reducing the guest memory from %s to %s, to avoid host kernel panic on macOS <= 12.3 with QEMU >= 7.0; "+
455-
"Please update macOS to 12.4 or later, or downgrade QEMU to 6.2; "+
405+
logrus.Warnf("Reducing the guest memory from %s to %s, to avoid host kernel panic on macOS <= 12.3; "+
406+
"Please update macOS to 12.4 or later; "+
456407
"See https://github.com/lima-vm/lima/issues/795 for the further background.",
457408
units.BytesSize(float64(memBytes)), units.BytesSize(float64(safeSize)))
458409
memBytes = safeSize
@@ -500,28 +451,26 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
500451
if version.LessThan(*semver.New(MinimumQemuVersion)) {
501452
logrus.Fatalf("QEMU %v is too old, %v or later required", version, MinimumQemuVersion)
502453
}
454+
if version.LessThan(*semver.New(RecommendedQemuVersion)) {
455+
logrus.Warnf("QEMU %v is too old, %v or later is recommended", version, RecommendedQemuVersion)
456+
}
503457
if y.VMOpts.QEMU.MinimumVersion != nil && version.LessThan(*semver.New(*y.VMOpts.QEMU.MinimumVersion)) {
504458
logrus.Fatalf("QEMU %v is too old, template requires %q or later", version, *y.VMOpts.QEMU.MinimumVersion)
505459
}
506-
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" && version.Equal(*semver.New("8.2.0")) {
507-
logrus.Fatal("QEMU 8.2.0 is no longer supported on ARM Mac due to <https://gitlab.com/qemu-project/qemu/-/issues/1990>. " +
508-
"Please upgrade QEMU to v8.2.1 (or downgrade to v8.1.x).")
509-
}
510460
}
511461

512462
// Architecture
513463
accel := Accel(*y.Arch)
514464
if !strings.Contains(string(features.AccelHelp), accel) {
515465
return "", nil, fmt.Errorf("accelerator %q is not supported by %s", accel, exe)
516466
}
517-
showDarwinARM64HVFQEMU620Warning(exe, accel, features)
518467

519468
// Memory
520469
memBytes, err := units.RAMInBytes(*y.Memory)
521470
if err != nil {
522471
return "", nil, err
523472
}
524-
memBytes = adjustMemBytesDarwinARM64HVF(memBytes, accel, features)
473+
memBytes = adjustMemBytesDarwinARM64HVF(memBytes, accel)
525474
args = appendArgsIfNoConflict(args, "-m", strconv.Itoa(int(memBytes>>20)))
526475

527476
if *y.MountType == limayaml.VIRTIOFS {
@@ -569,14 +518,6 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
569518
}
570519
case limayaml.AARCH64:
571520
machine := "virt,accel=" + accel
572-
// QEMU >= 7.0 requires highmem=off NOT to be set, otherwise fails with "Addressing limited to 32 bits, but memory exceeds it by 1073741824 bytes"
573-
// QEMU < 7.0 requires highmem=off to be set, otherwise fails with "VCPU supports less PA bits (36) than requested by the memory map (40)"
574-
// https://github.com/lima-vm/lima/issues/680
575-
// https://github.com/lima-vm/lima/pull/24
576-
// But when the memory size is <= 3 GiB, we can always set highmem=off.
577-
if !features.VersionGEQ7 || memBytes <= 3*1024*1024*1024 {
578-
machine += ",highmem=off"
579-
}
580521
args = appendArgsIfNoConflict(args, "-machine", machine)
581522
case limayaml.RISCV64:
582523
// https://github.com/tianocore/edk2/blob/edk2-stable202408/OvmfPkg/RiscVVirt/README.md#test
@@ -876,23 +817,15 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
876817
}
877818

878819
switch *y.Arch {
820+
// FIXME: use virtio-gpu on all the architectures
879821
case limayaml.X8664, limayaml.RISCV64:
880822
args = append(args, "-device", "virtio-vga")
881-
args = append(args, "-device", "virtio-keyboard-pci")
882-
args = append(args, "-device", "virtio-"+input+"-pci")
883-
args = append(args, "-device", "qemu-xhci,id=usb-bus")
884-
case limayaml.AARCH64, limayaml.ARMV7L, limayaml.PPC64LE, limayaml.S390X:
885-
if features.VersionGEQ7 {
886-
args = append(args, "-device", "virtio-gpu")
887-
args = append(args, "-device", "virtio-keyboard-pci")
888-
args = append(args, "-device", "virtio-"+input+"-pci")
889-
} else { // kernel panic with virtio and old versions of QEMU
890-
args = append(args, "-vga", "none", "-device", "ramfb")
891-
args = append(args, "-device", "usb-kbd,bus=usb-bus")
892-
args = append(args, "-device", "usb-"+input+",bus=usb-bus")
893-
}
894-
args = append(args, "-device", "qemu-xhci,id=usb-bus")
823+
default:
824+
args = append(args, "-device", "virtio-gpu")
895825
}
826+
args = append(args, "-device", "virtio-keyboard-pci")
827+
args = append(args, "-device", "virtio-"+input+"-pci")
828+
args = append(args, "-device", "qemu-xhci,id=usb-bus")
896829

897830
// Parallel
898831
args = append(args, "-parallel", "none")

pkg/qemu/qemu_linux_amd64.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package qemu
5+
6+
// MinimumQemuVersion is the minimum supported QEMU version.
7+
// This is set to a lower version on linux/amd64 hosts due to a compatibility reason.
8+
// See qemu_others.go for the "real" minimum supported QEMU version.
9+
const MinimumQemuVersion = "4.0.0"

pkg/qemu/qemu_others.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !linux || !amd64
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package qemu
7+
8+
// MinimumQemuVersion is the minimum supported QEMU version.
9+
const MinimumQemuVersion = "7.0.0"

0 commit comments

Comments
 (0)