Skip to content

Commit d712d43

Browse files
committed
refactor: migrate cpuType to qemu
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent 5622089 commit d712d43

File tree

8 files changed

+99
-106
lines changed

8 files changed

+99
-106
lines changed

pkg/driver/qemu/qemu.go

Lines changed: 63 additions & 1 deletion
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"
@@ -403,6 +404,67 @@ func audioDevice() string {
403404
return "oss"
404405
}
405406

407+
func defaultCPUType() limayaml.CPUType {
408+
// x86_64 + TCG + max was previously unstable until 2021.
409+
// https://bugzilla.redhat.com/show_bug.cgi?id=1999700
410+
// https://bugs.launchpad.net/qemu/+bug/1748296
411+
defaultX8664 := "max"
412+
if runtime.GOOS == "windows" && runtime.GOARCH == "amd64" {
413+
// https://github.com/lima-vm/lima/pull/3487#issuecomment-2846253560
414+
// > #931 intentionally prevented the code from setting it to max when running on Windows,
415+
// > and kept it at qemu64.
416+
//
417+
// TODO: remove this if "max" works with the latest qemu
418+
defaultX8664 = "qemu64"
419+
}
420+
cpuType := map[limayaml.Arch]string{
421+
limayaml.AARCH64: "max",
422+
limayaml.ARMV7L: "max",
423+
limayaml.X8664: defaultX8664,
424+
limayaml.PPC64LE: "max",
425+
limayaml.RISCV64: "max",
426+
limayaml.S390X: "max",
427+
}
428+
for arch := range cpuType {
429+
if limayaml.IsNativeArch(arch) && limayaml.IsAccelOS() {
430+
if limayaml.HasHostCPU() {
431+
cpuType[arch] = "host"
432+
}
433+
}
434+
if arch == limayaml.X8664 && runtime.GOOS == "darwin" {
435+
// disable AVX-512, since it requires trapping instruction faults in guest
436+
// Enterprise Linux requires either v2 (SSE4) or v3 (AVX2), but not yet v4.
437+
cpuType[arch] += ",-avx512vl"
438+
439+
// Disable pdpe1gb on Intel Mac
440+
// https://github.com/lima-vm/lima/issues/1485
441+
// https://stackoverflow.com/a/72863744/5167443
442+
cpuType[arch] += ",-pdpe1gb"
443+
}
444+
}
445+
return cpuType
446+
}
447+
448+
func resolveCPUType(y *limayaml.LimaYAML) string {
449+
cpuType := defaultCPUType()
450+
var overrideCPUType bool
451+
for k, v := range y.VMOpts.QEMU.CPUType {
452+
if !slices.Contains(limayaml.ArchTypes, *y.Arch) {
453+
logrus.Warnf("field `vmOpts.qemu.cpuType` uses unsupported arch %q", k)
454+
continue
455+
}
456+
if v != "" {
457+
overrideCPUType = true
458+
cpuType[k] = v
459+
}
460+
}
461+
if overrideCPUType {
462+
y.VMOpts.QEMU.CPUType = cpuType
463+
}
464+
465+
return cpuType[*y.Arch]
466+
}
467+
406468
func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err error) {
407469
y := cfg.LimaYAML
408470
exe, args, err = Exe(*y.Arch)
@@ -453,7 +515,7 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
453515
}
454516

455517
// CPU
456-
cpu := y.CPUType[*y.Arch]
518+
cpu := resolveCPUType(y)
457519
if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" {
458520
switch {
459521
case strings.HasPrefix(cpu, "host"), strings.HasPrefix(cpu, "max"):

pkg/driver/vz/vz_driver_darwin.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,6 @@ func (l *LimaVzDriver) Validate() error {
124124
return fmt.Errorf("unsupported arch: %q", *l.Instance.Config.Arch)
125125
}
126126

127-
for k, v := range l.Instance.Config.CPUType {
128-
if v != "" {
129-
logrus.Warnf("vmType %s: ignoring cpuType[%q]: %q", *l.Instance.Config.VMType, k, v)
130-
}
131-
}
132-
133127
for i, image := range l.Instance.Config.Images {
134128
if unknown := reflectutil.UnknownNonEmptyFields(image, "File", "Kernel", "Initrd"); len(unknown) > 0 {
135129
logrus.Warnf("vmType %s: ignoring images[%d]: %+v", *l.Instance.Config.VMType, i, unknown)

pkg/limayaml/defaults.go

Lines changed: 16 additions & 60 deletions
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

@@ -292,28 +251,25 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
292251
}
293252
}
294253

295-
cpuType := defaultCPUType()
296-
var overrideCPUType bool
297-
for k, v := range d.CPUType {
298-
if v != "" {
299-
overrideCPUType = true
300-
cpuType[k] = v
301-
}
254+
if y.VMOpts.QEMU.CPUType == nil {
255+
y.VMOpts.QEMU.CPUType = CPUType{}
302256
}
303-
for k, v := range y.CPUType {
304-
if v != "" {
305-
overrideCPUType = true
306-
cpuType[k] = v
257+
// TODO: This check should be removed when we completely eliminate `CPUType` from limayaml.
258+
if len(y.CPUType) > 0 {
259+
if warn {
260+
logrus.Warn("The top-level `cpuType` field is deprecated and will be removed in a future release. Please migrate to `vmOpts.qemu.cpuType`.")
307261
}
308-
}
309-
for k, v := range o.CPUType {
310-
if v != "" {
311-
overrideCPUType = true
312-
cpuType[k] = v
262+
for arch, v := range y.CPUType {
263+
if v == "" {
264+
continue
265+
}
266+
if existing, ok := y.VMOpts.QEMU.CPUType[arch]; ok && existing != "" && existing != v {
267+
logrus.Warnf("Conflicting cpuType for arch %q: top-level=%q, vmOpts.qemu=%q; using vmOpts.qemu value", arch, v, existing)
268+
continue
269+
}
270+
y.VMOpts.QEMU.CPUType[arch] = v
313271
}
314-
}
315-
if *y.VMType == QEMU || overrideCPUType {
316-
y.CPUType = cpuType
272+
y.CPUType = nil
317273
}
318274

319275
if y.CPUs == nil {

pkg/limayaml/defaults_test.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ func TestFillDefault(t *testing.T) {
7979
VMType: &defaultVMType,
8080
OS: ptr.Of(LINUX),
8181
Arch: ptr.Of(arch),
82-
CPUType: defaultCPUType(),
8382
CPUs: ptr.Of(defaultCPUs()),
8483
Memory: ptr.Of(defaultMemoryAsString()),
8584
Disk: ptr.Of(defaultDiskSizeAsString()),
@@ -339,14 +338,6 @@ func TestFillDefault(t *testing.T) {
339338
VMType: ptr.Of("vz"),
340339
OS: ptr.Of("unknown"),
341340
Arch: ptr.Of("unknown"),
342-
CPUType: CPUType{
343-
AARCH64: "arm64",
344-
ARMV7L: "armhf",
345-
X8664: "amd64",
346-
PPC64LE: "ppc64le",
347-
RISCV64: "riscv64",
348-
S390X: "s390x",
349-
},
350341
CPUs: ptr.Of(7),
351342
Memory: ptr.Of("5GiB"),
352343
Disk: ptr.Of("105GiB"),
@@ -559,14 +550,6 @@ func TestFillDefault(t *testing.T) {
559550
VMType: ptr.Of("qemu"),
560551
OS: ptr.Of(LINUX),
561552
Arch: ptr.Of(arch),
562-
CPUType: CPUType{
563-
AARCH64: "uber-arm",
564-
ARMV7L: "armv8",
565-
X8664: "pentium",
566-
PPC64LE: "power10",
567-
RISCV64: "sifive-u54",
568-
S390X: "z14",
569-
},
570553
CPUs: ptr.Of(12),
571554
Memory: ptr.Of("7GiB"),
572555
Disk: ptr.Of("117GiB"),

pkg/limayaml/limayaml.go

Lines changed: 9 additions & 7 deletions
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"`
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,omitempty" json:"images,omitempty" jsonschema:"nullable"`
13+
Base BaseTemplates `yaml:"base,omitempty" json:"base,omitempty"`
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,omitempty" json:"images,omitempty" jsonschema:"nullable"`
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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,6 @@ func Validate(y *LimaYAML, warn bool) error {
102102
}
103103
}
104104

105-
for arch := range y.CPUType {
106-
if !slices.Contains(ArchTypes, arch) {
107-
errs = errors.Join(errs, fmt.Errorf("field `cpuType` uses unsupported arch %q", arch))
108-
}
109-
}
110-
111105
if *y.CPUs == 0 {
112106
errs = errors.Join(errs, errors.New("field `cpus` must be set"))
113107
}

pkg/store/instance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func Inspect(instName string) (*Instance, error) {
9696
inst.Config = y
9797
inst.Arch = *y.Arch
9898
inst.VMType = *y.VMType
99-
inst.CPUType = y.CPUType[*y.Arch]
99+
inst.CPUType = y.VMOpts.QEMU.CPUType[*y.Arch]
100100
inst.SSHAddress = "127.0.0.1"
101101
inst.SSHLocalPort = *y.SSH.LocalPort // maybe 0
102102
inst.SSHConfigFile = filepath.Join(instDir, filenames.SSHConfig)

templates/default.yaml

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

326335
# OS: "Linux".
327336
# 🟢 Builtin default: "Linux"
328337
os: null
329338

330-
# Specify desired QEMU CPU type for each arch.
331-
# You can see what options are available for host emulation with: `qemu-system-$(arch) -cpu help`.
332-
# Setting of instructions is supported like this: "qemu64,+ssse3".
333-
# 🟢 Builtin default: hard-coded arch map with type (see the output of `limactl info | jq .defaultTemplate.cpuType`)
339+
# DEPRECATED: Use vmOpts.qemu.cpuType instead. See the vmOpts.qemu.cpuType section above for configuration.
334340
cpuType:
335-
# aarch64: "max" # (or "host" when running on aarch64 host)
336-
# armv7l: "max" # (or "host" when running on armv7l host)
337-
# riscv64: "max" # (or "host" when running on riscv64 host)
338-
# x86_64: "max" # (or "host" when running on x86_64 host; additional options are appended on Intel Mac)
339341

340342
rosetta:
341343
# Enable Rosetta inside the VM; needs `vmType: vz`

0 commit comments

Comments
 (0)