Skip to content

Commit 7884578

Browse files
committed
refactor(board): move SEV-specific functions to separate modules
Signed-off-by: Changyuan Lyu <changyuanl@google.com>
1 parent 1e813dd commit 7884578

File tree

6 files changed

+244
-160
lines changed

6 files changed

+244
-160
lines changed

alioth/src/board/board.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#[path = "board_aarch64.rs"]
1717
mod aarch64;
1818
#[cfg(target_arch = "x86_64")]
19-
#[path = "board_x86_64.rs"]
19+
#[path = "board_x86_64/board_x86_64.rs"]
2020
mod x86_64;
2121

2222
#[cfg(target_os = "linux")]
@@ -92,7 +92,7 @@ pub enum Error {
9292
#[snafu(display("Failed to reset PCI devices"))]
9393
ResetPci { source: Box<crate::pci::Error> },
9494
#[snafu(display("Failed to configure firmware"))]
95-
Firmware { error: std::io::Error },
95+
FwCfg { error: std::io::Error },
9696
#[snafu(display("Missing payload"))]
9797
MissingPayload,
9898
#[snafu(display("Failed to notify the VMM thread"))]
@@ -104,6 +104,8 @@ pub enum Error {
104104
#[cfg(target_arch = "x86_64")]
105105
#[snafu(display("Missing CPUID leaf {leaf:x?}"))]
106106
MissingCpuid { leaf: CpuidIn },
107+
#[snafu(display("Firmware error"), context(false))]
108+
Firmware { source: Box<crate::firmware::Error> },
107109
}
108110

109111
type Result<T, E = Error> = std::result::Result<T, E>;
@@ -442,7 +444,7 @@ where
442444
self.create_firmware_data(&init_state)?;
443445
}
444446
self.init_ap(index, vcpu, &vcpus)?;
445-
self.coco_finalize(index, &vcpus)?;
447+
self.coco_finalize(index)?;
446448
self.sync_vcpus(&vcpus)
447449
}
448450

alioth/src/board/board_x86_64.rs renamed to alioth/src/board/board_x86_64/board_x86_64.rs

Lines changed: 31 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,25 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
mod sev;
16+
1517
use std::arch::x86_64::{__cpuid, CpuidResult};
1618
use std::collections::HashMap;
17-
use std::iter::zip;
1819
use std::mem::{offset_of, size_of, size_of_val};
1920
use std::path::Path;
2021
use std::sync::Arc;
21-
use std::sync::atomic::{AtomicU32, Ordering};
22+
use std::sync::atomic::AtomicU32;
2223

2324
use parking_lot::Mutex;
2425
use snafu::ResultExt;
25-
use zerocopy::{FromBytes, FromZeros, IntoBytes};
26+
use zerocopy::{FromZeros, IntoBytes};
2627

2728
use crate::arch::cpuid::CpuidIn;
2829
use crate::arch::layout::{
2930
BIOS_DATA_END, EBDA_END, EBDA_START, IOAPIC_START, MEM_64_START, PORT_ACPI_RESET,
3031
PORT_ACPI_SLEEP_CONTROL, RAM_32_SIZE,
3132
};
3233
use crate::arch::msr::{IA32_MISC_ENABLE, MiscEnable};
33-
use crate::arch::reg::{Reg, SegAccess, SegReg, SegRegVal};
34-
use crate::arch::sev::SnpPageType;
3534
use crate::board::{Board, BoardConfig, CpuTopology, PCIE_MMIO_64_SIZE, Result, VcpuGuard, error};
3635
use crate::device::ioapic::IoApic;
3736
use crate::firmware::acpi::bindings::{
@@ -41,11 +40,6 @@ use crate::firmware::acpi::reg::{FadtReset, FadtSleepControl};
4140
use crate::firmware::acpi::{
4241
AcpiTable, create_fadt, create_madt, create_mcfg, create_rsdp, create_xsdt,
4342
};
44-
use crate::firmware::ovmf::parse_data;
45-
use crate::firmware::ovmf::sev::{
46-
GUID_SEV_ES_RESET_BLOCK, GUID_SEV_METADATA, SevDescType, SevMetaData, SevMetadataDesc,
47-
SnpCpuidFunc, SnpCpuidInfo,
48-
};
4943
use crate::hv::{Coco, Hypervisor, Vcpu, Vm};
5044
use crate::loader::{Executable, InitState, Payload, firmware};
5145
use crate::mem::mapped::ArcMemPages;
@@ -197,88 +191,19 @@ where
197191
encode_x2apic_id(&self.config.cpu.topology, index) as u64
198192
}
199193

200-
fn fill_snp_cpuid(&self, entries: &mut [SnpCpuidFunc]) {
201-
for ((in_, out), dst) in zip(self.arch.cpuids.iter(), entries.iter_mut()) {
202-
dst.eax_in = in_.func;
203-
dst.ecx_in = in_.index.unwrap_or(0);
204-
dst.eax = out.eax;
205-
dst.ebx = out.ebx;
206-
dst.ecx = out.ecx;
207-
dst.edx = out.edx;
208-
if dst.eax_in == 0xd && (dst.ecx_in == 0x0 || dst.ecx_in == 0x1) {
209-
dst.ebx = 0x240;
210-
dst.xcr0_in = 1;
211-
dst.xss_in = 0;
212-
}
213-
}
214-
}
215-
216-
fn parse_sev_es_ap(&self, coco: &Coco, fw: &ArcMemPages) {
217-
match coco {
218-
Coco::AmdSev { policy } if policy.es() => {}
219-
Coco::AmdSnp { .. } => {}
220-
_ => return,
221-
}
222-
let ap_eip = parse_data(fw.as_slice(), &GUID_SEV_ES_RESET_BLOCK).unwrap();
223-
let ap_eip = u32::read_from_bytes(ap_eip).unwrap();
224-
self.arch.sev_ap_eip.store(ap_eip, Ordering::Release);
225-
}
226-
227-
fn update_snp_desc(&self, offset: usize, fw_range: &mut [u8]) -> Result<()> {
228-
let mut cpuid_table = SnpCpuidInfo::new_zeroed();
229-
let ram_bus = self.memory.ram_bus();
230-
let ram = ram_bus.lock_layout();
231-
let (desc, _) = SevMetadataDesc::read_from_prefix(&fw_range[offset..]).unwrap();
232-
let snp_page_type = match desc.type_ {
233-
SevDescType::SNP_DESC_MEM => SnpPageType::UNMEASURED,
234-
SevDescType::SNP_SECRETS => SnpPageType::SECRETS,
235-
SevDescType::CPUID => {
236-
assert!(desc.len as usize >= size_of::<SnpCpuidInfo>());
237-
assert!(cpuid_table.entries.len() >= self.arch.cpuids.len());
238-
cpuid_table.count = self.arch.cpuids.len() as u32;
239-
self.fill_snp_cpuid(&mut cpuid_table.entries);
240-
ram.write_t(desc.base as _, &cpuid_table)?;
241-
SnpPageType::CPUID
242-
}
243-
_ => unimplemented!(),
244-
};
245-
let range_ref = ram.get_slice::<u8>(desc.base as u64, desc.len as u64)?;
246-
let range_bytes =
247-
unsafe { std::slice::from_raw_parts_mut(range_ref.as_ptr() as _, range_ref.len()) };
248-
self.memory
249-
.mark_private_memory(desc.base as _, desc.len as _, true)?;
250-
let mut ret = self
251-
.vm
252-
.snp_launch_update(range_bytes, desc.base as _, snp_page_type);
253-
if ret.is_err() && desc.type_ == SevDescType::CPUID {
254-
let updated_cpuid: SnpCpuidInfo = ram.read_t(desc.base as _)?;
255-
for (set, got) in zip(cpuid_table.entries.iter(), updated_cpuid.entries.iter()) {
256-
if set != got {
257-
log::error!("set {set:#x?}, but firmware expects {got:#x?}");
258-
}
259-
}
260-
ram.write_t(desc.base as _, &updated_cpuid)?;
261-
ret = self
262-
.vm
263-
.snp_launch_update(range_bytes, desc.base as _, snp_page_type);
264-
}
265-
ret?;
266-
Ok(())
267-
}
268-
269194
fn setup_fw_cfg(&self, payload: &Payload) -> Result<()> {
270195
let Some(dev) = &*self.fw_cfg.lock() else {
271196
return Ok(());
272197
};
273198
let mut dev = dev.lock();
274199
if let Some(Executable::Linux(image)) = &payload.executable {
275-
dev.add_kernel_data(image).context(error::Firmware)?;
200+
dev.add_kernel_data(image).context(error::FwCfg)?;
276201
};
277202
if let Some(cmdline) = &payload.cmdline {
278203
dev.add_kernel_cmdline(cmdline.to_owned());
279204
};
280205
if let Some(initramfs) = &payload.initramfs {
281-
dev.add_initramfs_data(initramfs).context(error::Firmware)?;
206+
dev.add_initramfs_data(initramfs).context(error::FwCfg)?;
282207
};
283208
Ok(())
284209
}
@@ -287,34 +212,11 @@ where
287212
let Some(coco) = &self.config.coco else {
288213
return Ok(());
289214
};
290-
self.memory.register_encrypted_pages(fw)?;
291-
self.parse_sev_es_ap(coco, fw);
292215
match coco {
293-
Coco::AmdSev { .. } => {
294-
self.vm.sev_launch_update_data(fw.as_slice_mut())?;
295-
}
296-
Coco::AmdSnp { .. } => {
297-
let fw_range = fw.as_slice_mut();
298-
let metadata_offset_r = parse_data(fw_range, &GUID_SEV_METADATA).unwrap();
299-
let metadata_offset =
300-
fw_range.len() - u32::read_from_bytes(metadata_offset_r).unwrap() as usize;
301-
let (metadata, _) =
302-
SevMetaData::read_from_prefix(&fw_range[metadata_offset..]).unwrap();
303-
let desc_offset = metadata_offset + size_of::<SevMetaData>();
304-
for i in 0..metadata.num_desc as usize {
305-
let offset = desc_offset + i * size_of::<SevMetadataDesc>();
306-
self.update_snp_desc(offset, fw_range)?;
307-
}
308-
let fw_gpa = MEM_64_START - fw_range.len() as u64;
309-
self.memory
310-
.mark_private_memory(fw_gpa, fw_range.len() as _, true)?;
311-
self.vm
312-
.snp_launch_update(fw_range, fw_gpa, SnpPageType::NORMAL)
313-
.unwrap();
314-
}
216+
Coco::AmdSev { policy } => self.setup_sev(fw, *policy),
217+
Coco::AmdSnp { .. } => self.setup_snp(fw),
315218
Coco::IntelTdx { attr } => todo!("Intel TDX {attr:?}"),
316219
}
317-
Ok(())
318220
}
319221

320222
pub fn setup_firmware(&self, fw: &Path, payload: &Payload) -> Result<InitState> {
@@ -325,30 +227,18 @@ where
325227
}
326228

327229
pub fn init_ap(&self, index: u16, vcpu: &mut V::Vcpu, vcpus: &VcpuGuard) -> Result<()> {
328-
match &self.config.coco {
329-
Some(Coco::AmdSev { policy }) if policy.es() => {}
330-
Some(Coco::AmdSnp { .. }) => {}
331-
_ => return Ok(()),
332-
}
333-
self.sync_vcpus(vcpus)?;
334-
if index == 0 {
230+
let Some(coco) = &self.config.coco else {
335231
return Ok(());
232+
};
233+
match coco {
234+
Coco::AmdSev { policy } => {
235+
if policy.es() {
236+
self.sev_init_ap(index, vcpu, vcpus)?;
237+
}
238+
}
239+
Coco::AmdSnp { .. } => self.sev_init_ap(index, vcpu, vcpus)?,
240+
Coco::IntelTdx { attr } => todo!("Intel TDX {attr:?}"),
336241
}
337-
let eip = self.arch.sev_ap_eip.load(Ordering::Acquire);
338-
vcpu.set_regs(&[(Reg::Rip, eip as u64 & 0xffff)])?;
339-
vcpu.set_sregs(
340-
&[],
341-
&[(
342-
SegReg::Cs,
343-
SegRegVal {
344-
selector: 0xf000,
345-
base: eip as u64 & 0xffff_0000,
346-
limit: 0xffff,
347-
access: SegAccess(0x9b),
348-
},
349-
)],
350-
&[],
351-
)?;
352242
Ok(())
353243
}
354244

@@ -442,27 +332,18 @@ where
442332
Ok(())
443333
}
444334

445-
pub fn coco_finalize(&self, index: u16, vcpus: &VcpuGuard) -> Result<()> {
446-
if let Some(coco) = &self.config.coco {
447-
self.sync_vcpus(vcpus)?;
448-
if index == 0 {
449-
match coco {
450-
Coco::AmdSev { policy } => {
451-
if policy.es() {
452-
self.vm.sev_launch_update_vmsa()?;
453-
}
454-
self.vm.sev_launch_measure()?;
455-
self.vm.sev_launch_finish()?;
456-
}
457-
Coco::AmdSnp { .. } => {
458-
self.vm.snp_launch_finish()?;
459-
}
460-
Coco::IntelTdx { attr } => todo!("Intel TDX {attr:?}"),
461-
}
462-
}
463-
self.sync_vcpus(vcpus)?;
335+
pub fn coco_finalize(&self, index: u16) -> Result<()> {
336+
let Some(coco) = &self.config.coco else {
337+
return Ok(());
338+
};
339+
if index != 0 {
340+
return Ok(());
341+
};
342+
match coco {
343+
Coco::AmdSev { policy } => self.sev_finalize(*policy),
344+
Coco::AmdSnp { .. } => self.snp_finalize(),
345+
Coco::IntelTdx { attr } => todo!("Intel TDX {attr:?}"),
464346
}
465-
Ok(())
466347
}
467348

468349
fn patch_dsdt(&self, data: &mut [u8; 352]) {
@@ -556,9 +437,9 @@ where
556437
}
557438
if let Some(fw_cfg) = &*self.fw_cfg.lock() {
558439
let mut dev = fw_cfg.lock();
559-
dev.add_acpi(acpi_table).context(error::Firmware)?;
440+
dev.add_acpi(acpi_table).context(error::FwCfg)?;
560441
let mem_regions = memory.mem_region_entries();
561-
dev.add_e820(&mem_regions).context(error::Firmware)?;
442+
dev.add_e820(&mem_regions).context(error::FwCfg)?;
562443
}
563444
Ok(())
564445
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)