Skip to content

Commit 3ee6999

Browse files
committed
refactor: migrate cpuType to qemu
Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
1 parent 1f787fb commit 3ee6999

File tree

8 files changed

+107
-92
lines changed

8 files changed

+107
-92
lines changed

pkg/limayaml/defaults.go

+16-60
Original file line numberDiff line numberDiff line change
@@ -60,47 +60,6 @@ var (
6060
currentUser = Must(user.Current())
6161
)
6262

63-
func defaultCPUType() CPUType {
64-
// x86_64 + TCG + max was previously unstable until 2021.
65-
// https://bugzilla.redhat.com/show_bug.cgi?id=1999700
66-
// https://bugs.launchpad.net/qemu/+bug/1748296
67-
defaultX8664 := "max"
68-
if runtime.GOOS == "windows" && runtime.GOARCH == "amd64" {
69-
// https://github.com/lima-vm/lima/pull/3487#issuecomment-2846253560
70-
// > #931 intentionally prevented the code from setting it to max when running on Windows,
71-
// > and kept it at qemu64.
72-
//
73-
// TODO: remove this if "max" works with the latest qemu
74-
defaultX8664 = "qemu64"
75-
}
76-
cpuType := map[Arch]string{
77-
AARCH64: "max",
78-
ARMV7L: "max",
79-
X8664: defaultX8664,
80-
PPC64LE: "max",
81-
RISCV64: "max",
82-
S390X: "max",
83-
}
84-
for arch := range cpuType {
85-
if IsNativeArch(arch) && IsAccelOS() {
86-
if HasHostCPU() {
87-
cpuType[arch] = "host"
88-
}
89-
}
90-
if arch == X8664 && runtime.GOOS == "darwin" {
91-
// disable AVX-512, since it requires trapping instruction faults in guest
92-
// Enterprise Linux requires either v2 (SSE4) or v3 (AVX2), but not yet v4.
93-
cpuType[arch] += ",-avx512vl"
94-
95-
// Disable pdpe1gb on Intel Mac
96-
// https://github.com/lima-vm/lima/issues/1485
97-
// https://stackoverflow.com/a/72863744/5167443
98-
cpuType[arch] += ",-pdpe1gb"
99-
}
100-
}
101-
return cpuType
102-
}
103-
10463
//go:embed containerd.yaml
10564
var defaultContainerdYAML []byte
10665

@@ -312,28 +271,25 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
312271
}
313272
}
314273

315-
cpuType := defaultCPUType()
316-
var overrideCPUType bool
317-
for k, v := range d.CPUType {
318-
if v != "" {
319-
overrideCPUType = true
320-
cpuType[k] = v
321-
}
274+
if y.VMOpts.QEMU.CPUType == nil {
275+
y.VMOpts.QEMU.CPUType = CPUType{}
322276
}
323-
for k, v := range y.CPUType {
324-
if v != "" {
325-
overrideCPUType = true
326-
cpuType[k] = v
277+
// TODO: This check should be removed when we completely eliminate `CPUType` from limayaml.
278+
if len(y.CPUType) > 0 {
279+
if warn {
280+
logrus.Warn("The top-level `cpuType` field is deprecated and will be removed in a future release. Please migrate to `vmOpts.qemu.cpuType`.")
327281
}
328-
}
329-
for k, v := range o.CPUType {
330-
if v != "" {
331-
overrideCPUType = true
332-
cpuType[k] = v
282+
for arch, v := range y.CPUType {
283+
if v == "" {
284+
continue
285+
}
286+
if existing, ok := y.VMOpts.QEMU.CPUType[arch]; ok && existing != "" && existing != v {
287+
logrus.Warnf("Conflicting cpuType for arch %q: top-level=%q, vmOpts.qemu=%q; using vmOpts.qemu value", arch, v, existing)
288+
continue
289+
}
290+
y.VMOpts.QEMU.CPUType[arch] = v
333291
}
334-
}
335-
if *y.VMType == QEMU || overrideCPUType {
336-
y.CPUType = cpuType
292+
y.CPUType = nil
337293
}
338294

339295
if y.CPUs == nil {

pkg/limayaml/defaults_test.go

-17
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ func TestFillDefault(t *testing.T) {
7878
VMType: &defaultVMType,
7979
OS: ptr.Of(LINUX),
8080
Arch: ptr.Of(arch),
81-
CPUType: defaultCPUType(),
8281
CPUs: ptr.Of(defaultCPUs()),
8382
Memory: ptr.Of(defaultMemoryAsString()),
8483
Disk: ptr.Of(defaultDiskSizeAsString()),
@@ -338,14 +337,6 @@ func TestFillDefault(t *testing.T) {
338337
VMType: ptr.Of("vz"),
339338
OS: ptr.Of("unknown"),
340339
Arch: ptr.Of("unknown"),
341-
CPUType: CPUType{
342-
AARCH64: "arm64",
343-
ARMV7L: "armhf",
344-
X8664: "amd64",
345-
PPC64LE: "ppc64le",
346-
RISCV64: "riscv64",
347-
S390X: "s390x",
348-
},
349340
CPUs: ptr.Of(7),
350341
Memory: ptr.Of("5GiB"),
351342
Disk: ptr.Of("105GiB"),
@@ -558,14 +549,6 @@ func TestFillDefault(t *testing.T) {
558549
VMType: ptr.Of("qemu"),
559550
OS: ptr.Of(LINUX),
560551
Arch: ptr.Of(arch),
561-
CPUType: CPUType{
562-
AARCH64: "uber-arm",
563-
ARMV7L: "armv8",
564-
X8664: "pentium",
565-
PPC64LE: "power10",
566-
RISCV64: "sifive-u54",
567-
S390X: "z14",
568-
},
569552
CPUs: ptr.Of(12),
570553
Memory: ptr.Of("7GiB"),
571554
Disk: ptr.Of("117GiB"),

pkg/limayaml/limayaml.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ import (
1010
)
1111

1212
type LimaYAML struct {
13-
Base BaseTemplates `yaml:"base,omitempty" json:"base,omitempty" jsonschema:"nullable"`
14-
MinimumLimaVersion *string `yaml:"minimumLimaVersion,omitempty" json:"minimumLimaVersion,omitempty" jsonschema:"nullable"`
15-
VMType *VMType `yaml:"vmType,omitempty" json:"vmType,omitempty" jsonschema:"nullable"`
16-
VMOpts VMOpts `yaml:"vmOpts,omitempty" json:"vmOpts,omitempty"`
17-
OS *OS `yaml:"os,omitempty" json:"os,omitempty" jsonschema:"nullable"`
18-
Arch *Arch `yaml:"arch,omitempty" json:"arch,omitempty" jsonschema:"nullable"`
19-
Images []Image `yaml:"images" json:"images"` // REQUIRED
13+
Base BaseTemplates `yaml:"base,omitempty" json:"base,omitempty" jsonschema:"nullable"`
14+
MinimumLimaVersion *string `yaml:"minimumLimaVersion,omitempty" json:"minimumLimaVersion,omitempty" jsonschema:"nullable"`
15+
VMType *VMType `yaml:"vmType,omitempty" json:"vmType,omitempty" jsonschema:"nullable"`
16+
VMOpts VMOpts `yaml:"vmOpts,omitempty" json:"vmOpts,omitempty"`
17+
OS *OS `yaml:"os,omitempty" json:"os,omitempty" jsonschema:"nullable"`
18+
Arch *Arch `yaml:"arch,omitempty" json:"arch,omitempty" jsonschema:"nullable"`
19+
Images []Image `yaml:"images" json:"images"` // REQUIRED
20+
// Deprecated: Use VMOpts.Qemu.CPUType instead.
2021
CPUType CPUType `yaml:"cpuType,omitempty" json:"cpuType,omitempty" jsonschema:"nullable"`
2122
CPUs *int `yaml:"cpus,omitempty" json:"cpus,omitempty" jsonschema:"nullable"`
2223
Memory *string `yaml:"memory,omitempty" json:"memory,omitempty" jsonschema:"nullable"` // go-units.RAMInBytes
@@ -111,6 +112,7 @@ type VMOpts struct {
111112

112113
type QEMUOpts struct {
113114
MinimumVersion *string `yaml:"minimumVersion,omitempty" json:"minimumVersion,omitempty" jsonschema:"nullable"`
115+
CPUType CPUType `yaml:"cpuType,omitempty" json:"cpuType,omitempty" jsonschema:"nullable"`
114116
}
115117

116118
type Rosetta struct {

pkg/limayaml/validate.go

-6
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,6 @@ func Validate(y *LimaYAML, warn bool) error {
119119
}
120120
}
121121

122-
for arch := range y.CPUType {
123-
if !slices.Contains(ArchTypes, arch) {
124-
return fmt.Errorf("field `cpuType` uses unsupported arch %q", arch)
125-
}
126-
}
127-
128122
if *y.CPUs == 0 {
129123
return errors.New("field `cpus` must be set")
130124
}

pkg/qemu/qemu.go

+63-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"path/filepath"
1717
"regexp"
1818
"runtime"
19+
"slices"
1920
"strconv"
2021
"strings"
2122
"time"
@@ -480,6 +481,67 @@ func audioDevice() string {
480481
return "oss"
481482
}
482483

484+
func defaultCPUType() limayaml.CPUType {
485+
// x86_64 + TCG + max was previously unstable until 2021.
486+
// https://bugzilla.redhat.com/show_bug.cgi?id=1999700
487+
// https://bugs.launchpad.net/qemu/+bug/1748296
488+
defaultX8664 := "max"
489+
if runtime.GOOS == "windows" && runtime.GOARCH == "amd64" {
490+
// https://github.com/lima-vm/lima/pull/3487#issuecomment-2846253560
491+
// > #931 intentionally prevented the code from setting it to max when running on Windows,
492+
// > and kept it at qemu64.
493+
//
494+
// TODO: remove this if "max" works with the latest qemu
495+
defaultX8664 = "qemu64"
496+
}
497+
cpuType := map[limayaml.Arch]string{
498+
limayaml.AARCH64: "max",
499+
limayaml.ARMV7L: "max",
500+
limayaml.X8664: defaultX8664,
501+
limayaml.PPC64LE: "max",
502+
limayaml.RISCV64: "max",
503+
limayaml.S390X: "max",
504+
}
505+
for arch := range cpuType {
506+
if limayaml.IsNativeArch(arch) && limayaml.IsAccelOS() {
507+
if limayaml.HasHostCPU() {
508+
cpuType[arch] = "host"
509+
}
510+
}
511+
if arch == limayaml.X8664 && runtime.GOOS == "darwin" {
512+
// disable AVX-512, since it requires trapping instruction faults in guest
513+
// Enterprise Linux requires either v2 (SSE4) or v3 (AVX2), but not yet v4.
514+
cpuType[arch] += ",-avx512vl"
515+
516+
// Disable pdpe1gb on Intel Mac
517+
// https://github.com/lima-vm/lima/issues/1485
518+
// https://stackoverflow.com/a/72863744/5167443
519+
cpuType[arch] += ",-pdpe1gb"
520+
}
521+
}
522+
return cpuType
523+
}
524+
525+
func resolveCPUType(y *limayaml.LimaYAML) string {
526+
cpuType := defaultCPUType()
527+
var overrideCPUType bool
528+
for k, v := range y.VMOpts.QEMU.CPUType {
529+
if !slices.Contains(limayaml.ArchTypes, *y.Arch) {
530+
logrus.Warnf("field `vmOpts.qemu.cpuType` uses unsupported arch %q", k)
531+
continue
532+
}
533+
if v != "" {
534+
overrideCPUType = true
535+
cpuType[k] = v
536+
}
537+
}
538+
if overrideCPUType {
539+
y.VMOpts.QEMU.CPUType = cpuType
540+
}
541+
542+
return cpuType[*y.Arch]
543+
}
544+
483545
func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err error) {
484546
y := cfg.LimaYAML
485547
exe, args, err = Exe(*y.Arch)
@@ -531,7 +593,7 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
531593
}
532594

533595
// CPU
534-
cpu := y.CPUType[*y.Arch]
596+
cpu := resolveCPUType(y)
535597
if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" {
536598
switch {
537599
case strings.HasPrefix(cpu, "host"), strings.HasPrefix(cpu, "max"):

pkg/store/instance.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func Inspect(instName string) (*Instance, error) {
9595
inst.Config = y
9696
inst.Arch = *y.Arch
9797
inst.VMType = *y.VMType
98-
inst.CPUType = y.CPUType[*y.Arch]
98+
inst.CPUType = resolveCPUType(y)
9999
inst.SSHAddress = "127.0.0.1"
100100
inst.SSHLocalPort = *y.SSH.LocalPort // maybe 0
101101
inst.SSHConfigFile = filepath.Join(instDir, filenames.SSHConfig)
@@ -184,6 +184,13 @@ func Inspect(instName string) (*Instance, error) {
184184
return inst, nil
185185
}
186186

187+
func resolveCPUType(y *limayaml.LimaYAML) string {
188+
if len(y.VMOpts.QEMU.CPUType) == 0 {
189+
return y.CPUType[*y.Arch]
190+
}
191+
return y.VMOpts.QEMU.CPUType[*y.Arch]
192+
}
193+
187194
func inspectStatusWithPIDFiles(instDir string, inst *Instance, y *limayaml.LimaYAML) {
188195
var err error
189196
inst.DriverPID, err = ReadPIDFile(filepath.Join(instDir, filenames.PIDFile(*y.VMType)))

pkg/vz/vz_driver_darwin.go

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ func (l *LimaVzDriver) Validate() error {
107107
return fmt.Errorf("unsupported arch: %q", *l.Instance.Config.Arch)
108108
}
109109

110+
// TODO: This check should be removed when we completely eliminate `CPUType` from limayaml.
110111
for k, v := range l.Instance.Config.CPUType {
111112
if v != "" {
112113
logrus.Warnf("vmType %s: ignoring cpuType[%q]: %q", *l.Instance.Config.VMType, k, v)

templates/default.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,21 @@ vmOpts:
324324
# Will be ignored if the vmType is not "qemu"
325325
# 🟢 Builtin default: not set
326326
minimumVersion: null
327+
# Specify desired QEMU CPU type for each arch.
328+
# You can see what options are available for host emulation with: `qemu-system-$(arch) -cpu help`.
329+
# Setting of instructions is supported like this: "qemu64,+ssse3".
330+
# 🟢 Builtin default: hard-coded arch map with type (see the output of `limactl info | jq .defaultTemplate.cpuType`)
331+
cpuType:
332+
# aarch64: "max" # (or "host" when running on aarch64 host)
333+
# armv7l: "max" # (or "host" when running on armv7l host)
334+
# riscv64: "max" # (or "host" when running on riscv64 host)
335+
# x86_64: "max" # (or "host" when running on x86_64 host; additional options are appended on Intel Mac)
327336

328337
# OS: "Linux".
329338
# 🟢 Builtin default: "Linux"
330339
os: null
331340

341+
# DEPRECATED: Use vmOpts.qemu.cpuType instead.
332342
# Specify desired QEMU CPU type for each arch.
333343
# You can see what options are available for host emulation with: `qemu-system-$(arch) -cpu help`.
334344
# Setting of instructions is supported like this: "qemu64,+ssse3".

0 commit comments

Comments
 (0)