Skip to content

zram + (optionally encrypted) swap support#1

Merged
sosso merged 5 commits into
mainfrom
swap-size-flag
Apr 7, 2026
Merged

zram + (optionally encrypted) swap support#1
sosso merged 5 commits into
mainfrom
swap-size-flag

Conversation

@sosso

@sosso sosso commented Apr 5, 2026

Copy link
Copy Markdown
Member

No description provided.

sosso and others added 5 commits April 4, 2026 23:01
Adds a --swap-size <MB> flag that attaches a virtio block device
formatted as swap. The host creates a sparse file, the guest-init
writes a minimal swap header and calls swapon at boot.

Tested: 512MB RAM VM with 1GB swap survived a 450MB stress-ng
allocation that would otherwise OOM. Swap usage confirmed via
/proc/swaps and pswpin/pswpout counters.

Note: swap is currently unencrypted. Secrets in guest memory can be
paged to the host-side swap.img file. Encrypted swap via dm-crypt
(requires kernel config additions) is planned as a follow-up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Guest-init sets up dm-crypt on the swap block device using a random
256-bit key (aes-xts-plain64) before formatting and enabling swap.
The key exists only in guest kernel memory and is lost when the VM
stops, making swapped data irrecoverable from the host-side swap.img.

Uses device-mapper ioctls directly — no cryptsetup binary needed.
Falls back to unencrypted swap if CONFIG_DM_CRYPT is absent.

Kernel config additions (both arm64 and x86_64):
  CONFIG_MD=y, CONFIG_BLK_DEV_DM=y, CONFIG_DM_CRYPT=y,
  CONFIG_CRYPTO_AES=y, CONFIG_CRYPTO_XTS=y

Tested: wrote 5M copies of a known string in the guest, forced 332MB
to swap, then searched the host-side swap.img — zero plaintext matches.
The raw file contains only ciphertext.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds CONFIG_CRYPTO_AES_ARM64_CE and CONFIG_CRYPTO_AES_ARM64_CE_BLK
to use ARMv8 Crypto Extensions for AES, which Apple Silicon supports.

Benchmark (800M allocation in 512M RAM, 30s stress-ng):
  Encrypted swap (generic AES):  213 bogo ops/s
  Encrypted swap (AES-CE hw):    680 bogo ops/s  (3.2x faster)
  Unencrypted swap:            2,043 bogo ops/s

Encryption overhead drops from ~10x to ~3x vs unencrypted swap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Makes encrypted swap opt-out via --encrypt-swap=false (default: true).
The flag flows through api.Resources -> vm.VMConfig -> kernel cmdline
(matchlock.encrypt_swap=1) -> guest-init.

When disabled, guest-init skips dm-crypt setup and uses the raw block
device directly — ~3x faster swap throughput at the cost of plaintext
secrets on the host filesystem.

Adds docs/swap.md with full design, security analysis, benchmarks,
kernel config requirements, and references to LinuxKit and other
projects that informed the approach.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds zram compressed swap support (CONFIG_ZRAM + CONFIG_LZO). Guest-init
creates a zram0 device at the requested percentage of RAM, with priority
100 (higher than disk swap at -1). The kernel uses zram first for fast
compressed swap, falling back to disk for overflow.

Also adds --encrypt-swap flag (default true, opt-out with =false) and
--zram-pct flag (default 0, opt-in). Both thread through the SDK via
WithSwap(mb, encrypt) and WithZram(pct) builder methods.

Fixes Config.Merge() to propagate SwapSizeMB, EncryptSwap, and ZramPct
(was silently dropping them from SDK RPC requests).

Acceptance tests (8 total, all passing):
  Tier 1 (stock kernel):
  - TestNoSwapByDefault: swap off when not requested
  - TestSwapDiskActive: swap device present, SwapTotal > 0
  - TestSwapPreventsOOM: 800M alloc in 512M VM, pswpout > 0

  Tier 2 (MATCHLOCK_DMCRYPT_KERNEL):
  - TestEncryptedSwapOnDmCrypt: swap on /dev/dm-*, not /dev/vd*
  - TestEncryptedSwapCiphertextOnHost: known string NOT in swap.img
  - TestZramCompressedSwap: /dev/zram0 active, compression ratio > 1.0
  - TestZramPlusDiskSwapLayering: both active, zram priority > disk
  - TestUnencryptedSwapFlagDisablesEncryption: --encrypt-swap=false works

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sosso sosso changed the title Swap size flag zram + (optionally encrypted) swap support Apr 5, 2026
@sosso sosso merged commit 5fd877d into main Apr 7, 2026
4 of 6 checks passed
@sosso sosso deleted the swap-size-flag branch April 7, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant