Skip to content

Commit

Permalink
Fix #47: Enable hardware acceleration for Linux hosts (KVM)
Browse files Browse the repository at this point in the history
GitHub Linux runners have been upgraded [1] and now hardware accelerated
nested virtualization is available.

This also removes most logic around accelerators, since QEMU can pick
the best one out of several specified.

[1] https://github.blog/2024-01-17-github-hosted-runners-double-the-power-for-open-source/
  • Loading branch information
jacob-carlborg committed Feb 18, 2024
1 parent e99ff3c commit 4f2e32a
Show file tree
Hide file tree
Showing 17 changed files with 39 additions and 75 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add support for FreeBSD 14.0 ([#74](https://github.com/cross-platform-actions/action/issues/74))
- Add post run step that prints the VM output
- Support hardware accelerated virtualization on Linux runners ([#47](https://github.com/cross-platform-actions/action/issues/47))

### Fixed
- OpenBSD VM fails during "Initializing VM" with QEMU on macOS ([#73](https://github.com/cross-platform-actions/action/issues/73))
Expand Down
43 changes: 16 additions & 27 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,13 @@ they can run.
| **Linux** |||||
| **macos-10.15**, **macos-11**, **macos-12** |||||

macOS runners are, in general, preferred. They support hardware accelerated
nested virtualization, making them significantly faster than the Linux runners.
This only applies when the runner architecture and the guest architecture are
the same, in this case `x86-64`.
In general the Ubuntu runners are the preferred choice. Both macOS and Ubuntu
runners support hardware accelerated nested virtualization. But the Ubuntu
runners have more resources and therefore better performance. Hardware
acceleration only applies when the runner architecture and the guest
architecture are the same, in this case `x86-64`. `macos-14` runners which run
on Apple Silicon does not support hardware accelerated nested virtualization
and are not supported at all.

## `Linux on Non-x86 Architectures`

Expand Down
2 changes: 0 additions & 2 deletions spec/operating_systems/freebsd/freebsd.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import FreeBsd from '../../../src/operating_systems/freebsd/freebsd'
import hostModule from '../../../src/host'
import * as arch from '../../../src/architecture'
import * as os from '../../../src/operating_systems/kind'
import {Accelerator} from '../../../src/vm'
import * as hypervisor from '../../../src/hypervisor'
import {Input} from '../../../src/action/input'
import {Host} from '../../../src/host'
Expand Down Expand Up @@ -55,7 +54,6 @@ describe('FreeBSD OperatingSystem', () => {
...config,
ssHostPort: 2847,
cpu: 'max',
accelerator: Accelerator.tcg,
machineType: 'q35',
uuid: '864ED7F0-7876-4AA7-8511-816FABCFA87F',
firmware: `${firmwareDirectory}/share/qemu/bios-256k.bin`
Expand Down
2 changes: 0 additions & 2 deletions spec/operating_systems/freebsd/qemu_vm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {QemuVm} from '../../../src/operating_systems/freebsd/qemu_vm'
import * as arch from '../../../src/architecture'
import {host} from '../../../src/host'
import * as os from '../../../src/operating_systems/kind'
import {Accelerator} from '../../../src/vm'
import '../../../src/operating_systems/freebsd/freebsd'
import {Input} from '../../../src/action/input'

Expand All @@ -25,7 +24,6 @@ describe('FreeBSD QemuVm', () => {
diskImage: '',
ssHostPort: ssHostPort,
cpu: '',
accelerator: Accelerator.tcg,
machineType: '',
uuid: '',
resourcesDiskImage: '',
Expand Down
3 changes: 0 additions & 3 deletions spec/operating_systems/netbsd/netbsd.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import NetBsd from '../../../src/operating_systems/netbsd/netbsd'
import * as hostModule from '../../../src/host'
import * as arch from '../../../src/architecture'
import * as os from '../../../src/operating_systems/kind'
import {Accelerator} from '../../../src/vm'
import HostQemu from '../../../src/host_qemu'
import * as hypervisor from '../../../src/hypervisor'
import * as qemu from '../../../src/qemu_vm'
Expand Down Expand Up @@ -82,7 +81,6 @@ describe('NetBSD OperatingSystem', () => {
...config,
ssHostPort: 2847,
cpu: 'max',
accelerator: Accelerator.tcg,
machineType: 'q35',
uuid: '864ED7F0-7876-4AA7-8511-816FABCFA87F',
firmware: `${firmwareDirectory}/share/qemu/bios-256k.bin`
Expand Down Expand Up @@ -150,7 +148,6 @@ describe('NetBSD OperatingSystem', () => {
...config,
ssHostPort: 2847,
cpu: 'max',
accelerator: Accelerator.hvf,
machineType: 'q35',
uuid: '864ED7F0-7876-4AA7-8511-816FABCFA87F',
firmware: `${firmwareDirectory}/share/qemu/bios-256k.bin`
Expand Down
2 changes: 0 additions & 2 deletions spec/operating_systems/netbsd/qemu_vm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {Vm} from '../../../src/operating_systems/netbsd/qemu_vm'
import * as arch from '../../../src/architecture'
import {host} from '../../../src/host'
import * as os from '../../../src/operating_systems/kind'
import {Accelerator} from '../../../src/vm'
import '../../../src/operating_systems/netbsd/netbsd'
import {Input} from '../../../src/action/input'

Expand All @@ -25,7 +24,6 @@ describe('NetBSD QemuVm', () => {
diskImage: '',
ssHostPort: ssHostPort,
cpu: '',
accelerator: Accelerator.tcg,
machineType: '',
uuid: '',
resourcesDiskImage: '',
Expand Down
10 changes: 0 additions & 10 deletions src/architecture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {ResourceUrls} from './operating_systems/resource_urls'
import * as os from './operating_systems/kind'
import OpenBsd from './operating_systems/openbsd/openbsd'
import {getOrThrow, getOrDefaultOrThrow} from './utility'
import * as vm from './vm'

export enum Kind {
arm64,
Expand Down Expand Up @@ -50,7 +49,6 @@ export abstract class Architecture {
abstract get resourceUrl(): string
abstract get cpu(): string
abstract get machineType(): string
abstract get accelerator(): vm.Accelerator
abstract get hypervisor(): hypervisor.Hypervisor
abstract get efiHypervisor(): hypervisor.Hypervisor

Expand Down Expand Up @@ -100,10 +98,6 @@ export abstract class Architecture {
return 'virt'
}

override get accelerator(): vm.Accelerator {
return vm.Accelerator.tcg
}

override get hypervisor(): hypervisor.Hypervisor {
return new hypervisor.Qemu()
}
Expand Down Expand Up @@ -147,10 +141,6 @@ export abstract class Architecture {
return 'q35'
}

override get accelerator(): vm.Accelerator {
return this.hostQemu.accelerator
}

override get hypervisor(): hypervisor.Hypervisor {
return this.selectedHypervisor
}
Expand Down
11 changes: 0 additions & 11 deletions src/host_qemu.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import {Accelerator} from './vm'

// Contains host specific QEMU properties
export default abstract class HostQemu {
abstract get cpu(): string
abstract get accelerator(): Accelerator

static readonly LinuxHostQemu = class extends HostQemu {
override get accelerator(): Accelerator {
return Accelerator.tcg
}

override get cpu(): string {
return 'max'
}
}

static readonly MacosHostQemu = class extends HostQemu {
override get accelerator(): Accelerator {
return Accelerator.hvf
}

override get cpu(): string {
return 'max'
}
Expand Down
1 change: 0 additions & 1 deletion src/operating_systems/freebsd/freebsd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export default class FreeBsd extends os.OperatingSystem {

// qemu
cpu: this.architecture.cpu,
accelerator: this.architecture.accelerator,
machineType: this.architecture.machineType,

// xhyve
Expand Down
1 change: 0 additions & 1 deletion src/operating_systems/netbsd/netbsd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export default class NetBsd extends Qemu {

// qemu
cpu: this.architecture.cpu,
accelerator: this.architecture.accelerator,
machineType: this.architecture.machineType,

// xhyve
Expand Down
1 change: 0 additions & 1 deletion src/operating_systems/openbsd/openbsd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export default class OpenBsd extends os.OperatingSystem {

// qemu
cpu: this.architecture.cpu,
accelerator: this.architecture.accelerator,
machineType: this.architecture.machineType,

// xhyve
Expand Down
6 changes: 6 additions & 0 deletions src/operating_systems/openbsd/qemu_vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export class QemuVm extends Vm {
protected override get netDevive(): string {
return this.architecture.networkDevice
}

protected override get accelerators(): string[] {
return this.input.version.startsWith('6')
? ['hvf', 'tcg'] // KVM doesn't work with versions older than 7.0
: ['hvf', 'kvm', 'tcg']
}
}

export class QemuVmX86_64 extends QemuVm {
Expand Down
8 changes: 6 additions & 2 deletions src/qemu_vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export abstract class Vm extends vm.Vm {
}

override get command(): string[] {
const accel = vm.Accelerator[this.configuration.accelerator]
const accelerators = this.accelerators.join(':')

// prettier-ignore
return [
this.hypervisorPath.toString(),
'-daemonize',
'-machine', `type=${this.configuration.machineType},accel=${accel}`,
'-machine', `type=${this.configuration.machineType},accel=${accelerators}`,
'-cpu', this.cpuFlagValue,
'-smp', this.configuration.cpuCount.toString(),
'-m', this.configuration.memory,
Expand Down Expand Up @@ -85,6 +85,10 @@ export abstract class Vm extends vm.Vm {
return ['-bios', this.configuration.firmware!.toString()]
}

protected get accelerators(): string[] {
return ['hvf', 'kvm', 'tcg']
}

private get netdev(): string {
return [
'user',
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const version = {
openbsd: 'v0.7.0'
},

resources: 'v0.10.0'
resources: 'v0.11.0'
}

export default version

0 comments on commit 4f2e32a

Please sign in to comment.