Bump version to v1.1.1

- Fix .vmsn hang: use mmap instead of fs::read for metadata parsing,
  avoiding multi-GB allocation on embedded memory snapshots
- Reduce EPT scan budget (4GB cap, 1GB gap limit) for faster bail-out
  on non-VBS VMs (70s → 10s on 16GB snapshot)
This commit is contained in:
NK
2026-03-16 18:05:57 +01:00
parent f6001f8a0b
commit 9014a3f2ef
4 changed files with 11 additions and 7 deletions
Generated
+1 -1
View File
@@ -635,7 +635,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "vmkatz"
version = "1.0.0"
version = "1.1.1"
dependencies = [
"aes",
"anyhow",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "vmkatz"
version = "1.1.0"
version = "1.1.1"
edition = "2021"
license = "MIT"
+5 -4
View File
@@ -340,15 +340,16 @@ pub fn find_ept_candidates<P: PhysicalMemory>(l1: &P) -> Result<Vec<EptCandidate
// Scan budget: if no candidates found after scanning a portion of L1, give up.
// EPT PML4 tables are placed by the hypervisor in the lower portion of L1 memory.
// For genuine VBS VMs, candidates appear within the first few GB.
// Small VMs (<2GB) can't run VBS, so reduce budget to 25%.
// Cap at 4GB — scanning more is wasteful since EPTs live in low memory.
const MAX_SCAN_BUDGET: u64 = 4 * 1024 * 1024 * 1024;
let scan_budget = if l1_size < 2 * 1024 * 1024 * 1024 {
l1_size / 4
} else {
l1_size / 2
(l1_size / 4).min(MAX_SCAN_BUDGET)
};
let mut pages_since_last_candidate: u64 = 0;
// Also give up if we've scanned 2M pages (8GB) without finding a candidate.
const PAGES_WITHOUT_CANDIDATE_LIMIT: u64 = 2_000_000;
// Give up if we've scanned 256K pages (1GB) without finding a candidate.
const PAGES_WITHOUT_CANDIDATE_LIMIT: u64 = 256_000;
let mut addr: u64 = 0;
while addr < l1_size {
+4 -1
View File
@@ -166,7 +166,10 @@ impl VmwareLayer {
/// Parse a .vmsn file and return (regions, tags).
fn parse_vmsn_metadata(vmsn_path: &Path) -> Result<(Vec<MemoryRegion>, Vec<Tag>)> {
let vmsn_data = fs::read(vmsn_path)?;
// Memory-map instead of fs::read to avoid loading the entire multi-GB
// snapshot into memory — only the header/tag pages get paged in.
let vmsn_file = fs::File::open(vmsn_path)?;
let vmsn_data = unsafe { Mmap::map(&vmsn_file)? };
let (hdr, groups) = header::parse_vmsn(&vmsn_data)?;
log::info!(