@@ -47,10 +47,42 @@ type Config struct {
47
47
VirtioGA bool
48
48
}
49
49
50
- // MinimumQemuVersion is the minimum supported QEMU version.
51
- const (
52
- MinimumQemuVersion = "4.0.0"
53
- )
50
+ // minimumQemuVersion returns hardMin and softMin.
51
+ //
52
+ // hardMin is the hard minimum version of QEMU.
53
+ // The driver immediately returns the error when QEMU is older than this version.
54
+ //
55
+ // softMin is the oldest recommended version of QEMU.
56
+ // softMin must be >= hardMin.
57
+ //
58
+ // When updating this function, make sure to update
59
+ // `website/content/en/docs/config/vmtype.md` too.
60
+ func minimumQemuVersion () (hardMin , softMin semver.Version ) {
61
+ var h , s string
62
+ switch runtime .GOOS {
63
+ case "darwin" :
64
+ switch runtime .GOARCH {
65
+ case "arm64" :
66
+ // https://gitlab.com/qemu-project/qemu/-/issues/1990
67
+ h , s = "8.2.1" , "8.2.1"
68
+ default :
69
+ // The code specific to QEMU < 7.0 on macOS (https://github.com/lima-vm/lima/pull/703)
70
+ // was removed in https://github.com/lima-vm/lima/pull/3491
71
+ h , s = "7.0.0" , "8.2.1"
72
+ }
73
+ default :
74
+ // hardMin: Untested and maybe does not even work.
75
+ // softMin: Ubuntu 22.04's QEMU. The oldest version that can be easily tested on GitHub Actions.
76
+ h , s = "4.0.0" , "6.2.0"
77
+ }
78
+ hardMin , softMin = * semver .New (h ), * semver .New (s )
79
+ if softMin .LessThan (hardMin ) {
80
+ // NOTREACHED
81
+ logrus .Fatalf ("internal error: QEMU: soft minimum version %v must be >= hard minimum version %v" ,
82
+ softMin , hardMin )
83
+ }
84
+ return hardMin , softMin
85
+ }
54
86
55
87
// EnsureDisk also ensures the kernel and the initrd.
56
88
func EnsureDisk (ctx context.Context , cfg Config ) error {
@@ -287,9 +319,6 @@ type features struct {
287
319
// e.g. "Available CPUs:\n...\nx86 base...\nx86 host...\n...\n"
288
320
// Not machine-readable, but checking strings.Contains() should be fine.
289
321
CPUHelp []byte
290
-
291
- // VersionGEQ7 is true when the QEMU version seems v7.0.0 or later
292
- VersionGEQ7 bool
293
322
}
294
323
295
324
func inspectFeatures (exe , machine string ) (* features , error ) {
@@ -333,7 +362,6 @@ func inspectFeatures(exe, machine string) (*features, error) {
333
362
f .MachineHelp = stderr .Bytes ()
334
363
}
335
364
}
336
- f .VersionGEQ7 = strings .Contains (string (f .MachineHelp ), "-7.0" )
337
365
338
366
// Avoid error: "No machine specified, and there is no default"
339
367
cmd = exec .Command (exe , "-cpu" , "help" , "-machine" , machine )
@@ -351,56 +379,15 @@ func inspectFeatures(exe, machine string) (*features, error) {
351
379
return & f , nil
352
380
}
353
381
354
- // showDarwinARM64HVFQEMU620Warning shows a warning on M1 macOS when QEMU is older than 6.2.0_1.
355
- //
356
- // See:
357
- // - https://gitlab.com/qemu-project/qemu/-/issues/899
358
- // - https://github.com/Homebrew/homebrew-core/pull/96743
359
- // - https://github.com/lima-vm/lima/issues/712
360
- func showDarwinARM64HVFQEMU620Warning (exe , accel string , features * features ) {
361
- if runtime .GOOS != "darwin" {
362
- return
363
- }
364
- if runtime .GOARCH != "arm64" {
365
- return
366
- }
367
- if accel != "hvf" {
368
- return
369
- }
370
- if features .VersionGEQ7 {
371
- return
372
- }
373
- if exeFull , err := exec .LookPath (exe ); err == nil {
374
- if exeResolved , err2 := filepath .EvalSymlinks (exeFull ); err2 == nil {
375
- if strings .Contains (exeResolved , "Cellar/qemu/6.2.0_" ) {
376
- // Homebrew's QEMU 6.2.0_1 or later
377
- return
378
- }
379
- }
380
- }
381
- w := "This version of QEMU might not be able to boot recent Linux guests on M1 macOS hosts."
382
- if _ , err := exec .LookPath ("brew" ); err == nil {
383
- w += "Run `brew upgrade` and make sure your QEMU version is 6.2.0_1 or later."
384
- } else {
385
- w += `Reinstall QEMU with the following commits (included in QEMU 7.0.0):
386
- - https://github.com/qemu/qemu/commit/ad99f64f "hvf: arm: Use macros for sysreg shift/masking"
387
- - https://github.com/qemu/qemu/commit/7f6c295c "hvf: arm: Handle unknown ID registers as RES0"
388
- `
389
- w += "See https://github.com/Homebrew/homebrew-core/pull/96743 for the further information."
390
- }
391
- logrus .Warn (w )
392
- }
393
-
394
382
// adjustMemBytesDarwinARM64HVF adjusts the memory to be <= 3 GiB, only when the following conditions are met:
395
383
//
396
384
// - Host OS < macOS 12.4
397
385
// - Host Arch == arm64
398
386
// - Accel == hvf
399
- // - QEMU >= 7.0
400
387
//
401
388
// This adjustment is required for avoiding host kernel panic. The issue was fixed in macOS 12.4 Beta 1.
402
389
// See https://github.com/lima-vm/lima/issues/795 https://gitlab.com/qemu-project/qemu/-/issues/903#note_911000975
403
- func adjustMemBytesDarwinARM64HVF (memBytes int64 , accel string , features * features ) int64 {
390
+ func adjustMemBytesDarwinARM64HVF (memBytes int64 , accel string ) int64 {
404
391
const safeSize = 3 * 1024 * 1024 * 1024 // 3 GiB
405
392
if memBytes <= safeSize {
406
393
return memBytes
@@ -414,9 +401,6 @@ func adjustMemBytesDarwinARM64HVF(memBytes int64, accel string, features *featur
414
401
if accel != "hvf" {
415
402
return memBytes
416
403
}
417
- if ! features .VersionGEQ7 {
418
- return memBytes
419
- }
420
404
macOSProductVersion , err := osutil .ProductVersion ()
421
405
if err != nil {
422
406
logrus .Warn (err )
@@ -425,8 +409,8 @@ func adjustMemBytesDarwinARM64HVF(memBytes int64, accel string, features *featur
425
409
if ! macOSProductVersion .LessThan (* semver .New ("12.4.0" )) {
426
410
return memBytes
427
411
}
428
- logrus .Warnf ("Reducing the guest memory from %s to %s, to avoid host kernel panic on macOS <= 12.3 with QEMU >= 7.0 ; " +
429
- "Please update macOS to 12.4 or later, or downgrade QEMU to 6.2 ; " +
412
+ logrus .Warnf ("Reducing the guest memory from %s to %s, to avoid host kernel panic on macOS <= 12.3; " +
413
+ "Please update macOS to 12.4 or later; " +
430
414
"See https://github.com/lima-vm/lima/issues/795 for the further background." ,
431
415
units .BytesSize (float64 (memBytes )), units .BytesSize (float64 (safeSize )))
432
416
memBytes = safeSize
@@ -471,31 +455,30 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
471
455
logrus .WithError (err ).Warning ("Failed to detect QEMU version" )
472
456
} else {
473
457
logrus .Debugf ("QEMU version %s detected" , version .String ())
474
- if version .LessThan (* semver .New (MinimumQemuVersion )) {
475
- logrus .Fatalf ("QEMU %v is too old, %v or later required" , version , MinimumQemuVersion )
458
+ hardMin , softMin := minimumQemuVersion ()
459
+ if version .LessThan (hardMin ) {
460
+ logrus .Fatalf ("QEMU %v is too old, %v or later required" , version , hardMin )
461
+ }
462
+ if version .LessThan (softMin ) {
463
+ logrus .Warnf ("QEMU %v is too old, %v or later is recommended" , version , softMin )
476
464
}
477
465
if y .VMOpts .QEMU .MinimumVersion != nil && version .LessThan (* semver .New (* y .VMOpts .QEMU .MinimumVersion )) {
478
466
logrus .Fatalf ("QEMU %v is too old, template requires %q or later" , version , * y .VMOpts .QEMU .MinimumVersion )
479
467
}
480
- if runtime .GOOS == "darwin" && runtime .GOARCH == "arm64" && version .Equal (* semver .New ("8.2.0" )) {
481
- logrus .Fatal ("QEMU 8.2.0 is no longer supported on ARM Mac due to <https://gitlab.com/qemu-project/qemu/-/issues/1990>. " +
482
- "Please upgrade QEMU to v8.2.1 (or downgrade to v8.1.x)." )
483
- }
484
468
}
485
469
486
470
// Architecture
487
471
accel := Accel (* y .Arch )
488
472
if ! strings .Contains (string (features .AccelHelp ), accel ) {
489
473
return "" , nil , fmt .Errorf ("accelerator %q is not supported by %s" , accel , exe )
490
474
}
491
- showDarwinARM64HVFQEMU620Warning (exe , accel , features )
492
475
493
476
// Memory
494
477
memBytes , err := units .RAMInBytes (* y .Memory )
495
478
if err != nil {
496
479
return "" , nil , err
497
480
}
498
- memBytes = adjustMemBytesDarwinARM64HVF (memBytes , accel , features )
481
+ memBytes = adjustMemBytesDarwinARM64HVF (memBytes , accel )
499
482
args = appendArgsIfNoConflict (args , "-m" , strconv .Itoa (int (memBytes >> 20 )))
500
483
501
484
if * y .MountType == limayaml .VIRTIOFS {
@@ -543,14 +526,6 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
543
526
}
544
527
case limayaml .AARCH64 :
545
528
machine := "virt,accel=" + accel
546
- // 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"
547
- // 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)"
548
- // https://github.com/lima-vm/lima/issues/680
549
- // https://github.com/lima-vm/lima/pull/24
550
- // But when the memory size is <= 3 GiB, we can always set highmem=off.
551
- if ! features .VersionGEQ7 || memBytes <= 3 * 1024 * 1024 * 1024 {
552
- machine += ",highmem=off"
553
- }
554
529
args = appendArgsIfNoConflict (args , "-machine" , machine )
555
530
case limayaml .RISCV64 :
556
531
// https://github.com/tianocore/edk2/blob/edk2-stable202408/OvmfPkg/RiscVVirt/README.md#test
@@ -850,23 +825,15 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
850
825
}
851
826
852
827
switch * y .Arch {
828
+ // FIXME: use virtio-gpu on all the architectures
853
829
case limayaml .X8664 , limayaml .RISCV64 :
854
830
args = append (args , "-device" , "virtio-vga" )
855
- args = append (args , "-device" , "virtio-keyboard-pci" )
856
- args = append (args , "-device" , "virtio-" + input + "-pci" )
857
- args = append (args , "-device" , "qemu-xhci,id=usb-bus" )
858
- case limayaml .AARCH64 , limayaml .ARMV7L , limayaml .PPC64LE , limayaml .S390X :
859
- if features .VersionGEQ7 {
860
- args = append (args , "-device" , "virtio-gpu" )
861
- args = append (args , "-device" , "virtio-keyboard-pci" )
862
- args = append (args , "-device" , "virtio-" + input + "-pci" )
863
- } else { // kernel panic with virtio and old versions of QEMU
864
- args = append (args , "-vga" , "none" , "-device" , "ramfb" )
865
- args = append (args , "-device" , "usb-kbd,bus=usb-bus" )
866
- args = append (args , "-device" , "usb-" + input + ",bus=usb-bus" )
867
- }
868
- args = append (args , "-device" , "qemu-xhci,id=usb-bus" )
831
+ default :
832
+ args = append (args , "-device" , "virtio-gpu" )
869
833
}
834
+ args = append (args , "-device" , "virtio-keyboard-pci" )
835
+ args = append (args , "-device" , "virtio-" + input + "-pci" )
836
+ args = append (args , "-device" , "qemu-xhci,id=usb-bus" )
870
837
871
838
// Parallel
872
839
args = append (args , "-parallel" , "none" )
0 commit comments