Skip to content

Commit 7e84afe

Browse files
committed
feat: Add Rosetta support for vfkit on Apple Silicon
Enables running x86_64 (Intel) binaries in ARM64 Linux VMs on Apple Silicon Macs using Apple's Rosetta translation layer. Changes: - Add microvm.vfkit.rosetta.enable option to enable Rosetta - Add microvm.vfkit.rosetta.mountTag option (default: "rosetta") - Add microvm.vfkit.rosetta.install option to auto-install Rosetta - Add microvm.vfkit.rosetta.ignoreIfMissing for compatibility - Add rosetta device to vfkit runner when enabled - Validate that Rosetta is only used on aarch64-darwin systems - Create comprehensive documentation with setup instructions - Update options table to document Rosetta option Users must manually mount the Rosetta virtiofs share and configure binfmt in their guest configuration. See doc/src/vfkit-rosetta.md for complete setup instructions.
1 parent 67b66af commit 7e84afe

File tree

5 files changed

+135
-3
lines changed

5 files changed

+135
-3
lines changed

doc/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- [Device pass-through](./devices.md)
99
- [CPU emulation](./cpu-emulation.md)
1010
- [Output options](./output-options.md)
11+
- [Using Rosetta with vfkit (macOS)](./vfkit-rosetta.md)
1112
- [MicroVM options reference ⚙️](./microvm-options.md)
1213
- [Running a MicroVM as a package](./packages.md)
1314
- [Preparing a host for declarative MicroVMs](./host.md)

doc/src/options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ available for customization. These are the most important ones:
1717
| `microvm.forwardPorts` | (qemu user-networking only) TCP/UDP port forwarding |
1818
| `microvm.vfkit.extraArgs` | (vfkit only) Extra arguments to pass to vfkit |
1919
| `microvm.vfkit.logLevel` | (vfkit only) Log level: "debug", "info", or "error" (default: "info") |
20+
| `microvm.vfkit.rosetta.enable` | (vfkit only) Enable Rosetta for running x86_64 binaries on ARM64 (Apple Silicon only) |
2021
| `microvm.kernelParams` | Like `boot.kernelParams` but will not end up in `system.build.toplevel`, saving you rebuilds |
2122
| `microvm.storeOnDisk` | Enables the store on the boot squashfs even in the presence of a share with the host's `/nix/store` |
2223
| `microvm.writableStoreOverlay` | Optional string of the path where all writes to `/nix/store` should go to. |

doc/src/vfkit-rosetta.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Using Rosetta with vfkit on Apple Silicon
2+
3+
Rosetta support enables running x86_64 (Intel) binaries in your ARM64 Linux VM on Apple Silicon Macs. This is useful for running legacy applications or development tools that haven't been ported to ARM yet.
4+
5+
## Requirements
6+
7+
- Apple Silicon (M1/M2/M3/etc.) Mac
8+
- macOS with Rosetta installed
9+
- vfkit hypervisor
10+
11+
## Configuration
12+
13+
Enable Rosetta in your MicroVM configuration:
14+
15+
```nix
16+
{
17+
microvm = {
18+
hypervisor = "vfkit";
19+
20+
vfkit.rosetta = {
21+
enable = true;
22+
# Optional: install Rosetta automatically if missing
23+
install = true;
24+
};
25+
};
26+
}
27+
```
28+
29+
## Guest Setup
30+
31+
After enabling Rosetta, you need to mount the share and configure binfmt in your guest:
32+
33+
```nix
34+
{
35+
# Mount the Rosetta share
36+
fileSystems."/mnt/rosetta" = {
37+
device = "rosetta";
38+
fsType = "virtiofs";
39+
};
40+
41+
# Configure binfmt to use Rosetta for x86_64 binaries
42+
boot.binfmt.registrations.rosetta = {
43+
interpreter = "/mnt/rosetta/rosetta";
44+
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00'';
45+
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
46+
};
47+
}
48+
```
49+
50+
## Testing
51+
52+
Once configured, you can verify Rosetta is working:
53+
54+
```bash
55+
# Inside the VM
56+
uname -m
57+
# Should show: aarch64
58+
59+
# Try running an x86_64 binary (if you have one)
60+
file /path/to/x86_64/binary
61+
# Should show: ELF 64-bit LSB executable, x86-64
62+
63+
/path/to/x86_64/binary
64+
# Should run successfully via Rosetta
65+
```
66+
67+
## Options Reference
68+
69+
| Option | Type | Default | Description |
70+
|--------|------|---------|-------------|
71+
| `microvm.vfkit.rosetta.enable` | bool | `false` | Enable Rosetta support |
72+
| `microvm.vfkit.rosetta.mountTag` | string | `"rosetta"` | Mount tag for the virtiofs share |
73+
| `microvm.vfkit.rosetta.install` | bool | `false` | Auto-install Rosetta if missing |
74+
| `microvm.vfkit.rosetta.ignoreIfMissing` | bool | `false` | Continue if Rosetta unavailable |
75+
76+
## Limitations
77+
78+
- Only works on Apple Silicon Macs (M-series chips)
79+
- vfkit will fail to start on Intel Macs if Rosetta is enabled
80+
- Performance is slower than native ARM64 execution
81+
- Not all x86_64 binaries may work perfectly

lib/runners/vfkit.nix

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ let
1515
inherit (microvmConfig)
1616
hostName vcpu mem user interfaces volumes shares socket
1717
storeOnDisk kernel initrdPath storeDisk kernelParams
18-
balloon devices credentialFiles vsock graphics;
18+
devices credentialFiles vsock graphics;
1919

20-
inherit (microvmConfig.vfkit) extraArgs logLevel;
20+
inherit (microvmConfig.vfkit) extraArgs logLevel rosetta;
2121

2222
volumesWithLetters = withDriveLetters microvmConfig;
2323

@@ -69,7 +69,16 @@ let
6969
throw "vfkit does not support macvtap networking on macOS. Use type = \"user\" for NAT networking."
7070
else
7171
throw "Unknown network interface type: ${type}"
72-
) interfaces);
72+
) interfaces)
73+
++
74+
lib.optionals rosetta.enable (
75+
let
76+
rosettaArgs = "rosetta,mountTag=${rosetta.mountTag}"
77+
+ lib.optionalString rosetta.install ",install"
78+
+ lib.optionalString rosetta.ignoreIfMissing ",ignoreIfMissing";
79+
in
80+
[ "--device" rosettaArgs ]
81+
);
7382

7483
allArgsWithoutSocket = [
7584
"${vfkit}/bin/vfkit"
@@ -103,6 +112,8 @@ in
103112
then throw "vfkit does not support changing user"
104113
else if balloon
105114
then throw "vfkit does not support memory ballooning"
115+
else if rosetta.enable && !vmHostPackages.stdenv.hostPlatform.isAarch64
116+
then throw "Rosetta requires Apple Silicon (aarch64-darwin). Current host: ${system}"
106117
else if devices != []
107118
then throw "vfkit does not support device passthrough"
108119
else if credentialFiles != {}

nixos-modules/microvm/options.nix

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,44 @@ in
602602
description = "vfkit log level.";
603603
};
604604

605+
vfkit.rosetta = {
606+
enable = mkOption {
607+
type = types.bool;
608+
default = false;
609+
description = ''
610+
Enable Rosetta support for running x86_64 binaries in ARM64 Linux VMs.
611+
Only works on Apple Silicon (ARM) Macs.
612+
613+
After enabling, you must mount the rosetta share and configure binfmt
614+
in your guest configuration. See the vfkit documentation for details.
615+
'';
616+
};
617+
618+
mountTag = mkOption {
619+
type = types.str;
620+
default = "rosetta";
621+
description = "Mount tag for the Rosetta virtiofs share.";
622+
};
623+
624+
install = mkOption {
625+
type = types.bool;
626+
default = false;
627+
description = ''
628+
Automatically install Rosetta if missing.
629+
If false and Rosetta is not installed, vfkit will fail to start.
630+
'';
631+
};
632+
633+
ignoreIfMissing = mkOption {
634+
type = types.bool;
635+
default = false;
636+
description = ''
637+
Continue execution even if Rosetta installation fails or is unavailable.
638+
Useful for configurations that should work on both ARM and Intel Macs.
639+
'';
640+
};
641+
};
642+
605643
prettyProcnames = mkOption {
606644
type = types.bool;
607645
default = true;

0 commit comments

Comments
 (0)