diff --git a/alioth/src/board/board.rs b/alioth/src/board/board.rs index 7ffcc751..0f23395a 100644 --- a/alioth/src/board/board.rs +++ b/alioth/src/board/board.rs @@ -32,6 +32,8 @@ use serde::Deserialize; use serde_aco::Help; use snafu::{ResultExt, Snafu}; +#[cfg(target_arch = "x86_64")] +use crate::arch::cpuid::CpuidIn; #[cfg(target_arch = "x86_64")] use crate::arch::layout::PORT_PCI_ADDRESS; use crate::arch::layout::{ @@ -99,6 +101,9 @@ pub enum Error { PeerFailure, #[snafu(display("Unexpected state: {state:?}, want {want:?}"))] UnexpectedState { state: BoardState, want: BoardState }, + #[cfg(target_arch = "x86_64")] + #[snafu(display("Missing CPUID leaf {leaf:x?}"))] + MissingCpuid { leaf: CpuidIn }, } type Result = std::result::Result; diff --git a/alioth/src/board/board_x86_64.rs b/alioth/src/board/board_x86_64.rs index d4f1a83d..12762c4f 100644 --- a/alioth/src/board/board_x86_64.rs +++ b/alioth/src/board/board_x86_64.rs @@ -87,54 +87,43 @@ impl ArchBoard { 0xb, &[(1, threads_per_core), (2, threads_per_socket)], ); + let leaf0 = CpuidIn { func: 0, index: None, }; - if let Some(func0) = cpuids.get(&leaf0) { - let vendor = [func0.ebx, func0.edx, func0.ecx]; - match vendor.as_bytes() { - b"GenuineIntel" => add_topology( - &mut cpuids, - 0x1f, - &[(1, threads_per_core), (2, threads_per_socket)], - ), - b"AuthenticAMD" => add_topology( - &mut cpuids, - 0x8000_0026, - &[ - (1, threads_per_core), - (2, threads_per_socket), - (3, threads_per_socket), - (4, threads_per_socket), - ], - ), - _ => {} - } + let Some(out) = cpuids.get_mut(&leaf0) else { + return error::MissingCpuid { leaf: leaf0 }.fail(); + }; + let vendor = [out.ebx, out.edx, out.ecx]; + match vendor.as_bytes() { + b"GenuineIntel" => add_topology( + &mut cpuids, + 0x1f, + &[(1, threads_per_core), (2, threads_per_socket)], + ), + b"AuthenticAMD" => add_topology( + &mut cpuids, + 0x8000_0026, + &[ + (1, threads_per_core), + (2, threads_per_socket), + (3, threads_per_socket), + (4, threads_per_socket), + ], + ), + _ => {} } - for (in_, out) in &mut cpuids { - if in_.func == 0x1 { - out.ecx |= (1 << 24) | (1 << 31); - } else if in_.func == 0x8000_001f { - // AMD Volume 3, section E.4.17. - if matches!( - &config.coco, - Some(Coco::AmdSev { .. } | Coco::AmdSnp { .. }) - ) { - let host_ebx = unsafe { __cpuid(in_.func) }.ebx; - // set PhysAddrReduction to 1 - out.ebx = (1 << 6) | (host_ebx & 0x3f); - out.ecx = 0; - out.edx = 0; - } - if let Some(Coco::AmdSev { policy }) = &config.coco { - out.eax = if policy.es() { 0x2 | 0x8 } else { 0x2 }; - } else if let Some(Coco::AmdSnp { .. }) = &config.coco { - out.eax = 0x2 | 0x8 | 0x10; - } - } - } + let leaf1 = CpuidIn { + func: 0x1, + index: None, + }; + let Some(out) = cpuids.get_mut(&leaf1) else { + return error::MissingCpuid { leaf: leaf1 }.fail(); + }; + out.ecx |= (1 << 24) | (1 << 31); + let leaf_8000_0000 = unsafe { __cpuid(0x8000_0000) }; cpuids.insert( CpuidIn { @@ -151,6 +140,30 @@ impl ArchBoard { cpuids.insert(CpuidIn { func, index: None }, host_cpuid); } + if matches!( + &config.coco, + Some(Coco::AmdSev { .. } | Coco::AmdSnp { .. }) + ) { + // AMD Volume 3, section E.4.17. + let leaf = CpuidIn { + func: 0x8000_001f, + index: None, + }; + let Some(out) = cpuids.get_mut(&leaf) else { + return error::MissingCpuid { leaf }.fail(); + }; + let host_ebx = unsafe { __cpuid(leaf.func) }.ebx; + // set PhysAddrReduction to 1 + out.ebx = (1 << 6) | (host_ebx & 0x3f); + out.ecx = 0; + out.edx = 0; + if let Some(Coco::AmdSev { policy }) = &config.coco { + out.eax = if policy.es() { 0x2 | 0x8 } else { 0x2 }; + } else if let Some(Coco::AmdSnp { .. }) = &config.coco { + out.eax = 0x2 | 0x8 | 0x10; + } + } + Ok(Self { cpuids, sev_ap_eip: AtomicU32::new(0), diff --git a/alioth/src/hv/kvm/kvm_x86_64.rs b/alioth/src/hv/kvm/kvm_x86_64.rs index 2691ae22..3b9d5412 100644 --- a/alioth/src/hv/kvm/kvm_x86_64.rs +++ b/alioth/src/hv/kvm/kvm_x86_64.rs @@ -52,6 +52,7 @@ impl Kvm { let mut cpuids: HashMap<_, _> = kvm_cpuid2 .entries .iter() + .filter(|e| e.eax != 0 || e.ebx != 0 || e.ecx != 0 || e.edx != 0) .take(kvm_cpuid2.nent as usize) .map(map_f) .collect();