sev.rs0.00%
1
// Copyright 2026 Google LLC2
//3
// Licensed under the Apache License, Version 2.0 (the "License");4
// you may not use this file except in compliance with the License.5
// You may obtain a copy of the License at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// distributed under the License is distributed on an "AS IS" BASIS,11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12
// See the License for the specific language governing permissions and13
// limitations under the License.14
15
use std::os::fd::{AsFd, AsRawFd};16
17
use snafu::ResultExt;18
19
use crate::arch::sev::{SevPolicy, SevStatus, SnpPageType, SnpPolicy};20
use crate::hv::kvm::KvmVm;21
use crate::hv::{Result, error};22
use crate::sys::kvm::{KvmCap, KvmHypercall, kvm_memory_encrypt_op};23
use crate::sys::sev::{24
KvmSevCmd, KvmSevCmdId, KvmSevInit, KvmSevLaunchMeasure, KvmSevLaunchStart,25
KvmSevLaunchUpdateData, KvmSevSnpLaunchFinish, KvmSevSnpLaunchStart, KvmSevSnpLaunchUpdate,26
};27
28
impl KvmVm {29
fn sev_op<T>(&self, cmd: KvmSevCmdId, data: Option<&mut T>) -> Result<()> {30
let Some(sev_fd) = &self.vm.arch.sev_fd else {31
unreachable!("SevFd is not initialized")32
};33
let mut req = KvmSevCmd {34
sev_fd: sev_fd.as_fd().as_raw_fd() as u32,35
data: match data {36
Some(p) => p as *mut T as _,37
None => 0,38
},39
id: cmd,40
error: SevStatus::SUCCESS,41
};42
unsafe { kvm_memory_encrypt_op(&self.vm.fd, &mut req) }.context(error::MemEncrypt)?;43
if req.error != SevStatus::SUCCESS {44
return error::SevErr { code: req.error }.fail();45
}46
Ok(())47
}48
49
pub fn sev_init(&self, policy: SevPolicy) -> Result<()> {50
if policy.es() {51
self.sev_op::<()>(KvmSevCmdId::ES_INIT, None)52
} else {53
self.sev_op::<()>(KvmSevCmdId::INIT, None)54
}55
}56
57
pub fn snp_init(&self) -> Result<()> {58
let map_gpa_range = 1 << KvmHypercall::MAP_GPA_RANGE.raw();59
self.vm.enable_cap(KvmCap::EXIT_HYPERCALL, map_gpa_range)?;60
let mut init = KvmSevInit::default();61
self.sev_op(KvmSevCmdId::INIT2, Some(&mut init))62
}63
64
pub fn sev_launch_start(&self, policy: SevPolicy) -> Result<()> {65
let mut start = KvmSevLaunchStart {66
policy,67
..Default::default()68
};69
self.sev_op(KvmSevCmdId::LAUNCH_START, Some(&mut start))?;70
Ok(())71
}72
73
pub fn sev_launch_update_data(&self, range: &mut [u8]) -> Result<()> {74
let mut update_data = KvmSevLaunchUpdateData {75
uaddr: range.as_mut_ptr() as u64,76
len: range.len() as u32,77
};78
self.sev_op(KvmSevCmdId::LAUNCH_UPDATE_DATA, Some(&mut update_data))?;79
Ok(())80
}81
82
pub fn sev_launch_update_vmsa(&self) -> Result<()> {83
self.sev_op::<()>(KvmSevCmdId::LAUNCH_UPDATE_VMSA, None)?;84
Ok(())85
}86
87
pub fn sev_launch_measure(&self) -> Result<Vec<u8>> {88
let mut empty = KvmSevLaunchMeasure { uaddr: 0, len: 0 };89
let _ = self.sev_op(KvmSevCmdId::LAUNCH_MEASURE, Some(&mut empty));90
assert_ne!(empty.len, 0);91
let mut buf = vec![0u8; empty.len as usize];92
let mut measure = KvmSevLaunchMeasure {93
uaddr: buf.as_mut_ptr() as u64,94
len: buf.len() as u32,95
};96
self.sev_op(KvmSevCmdId::LAUNCH_MEASURE, Some(&mut measure))?;97
Ok(buf)98
}99
100
pub fn sev_launch_finish(&self) -> Result<()> {101
self.sev_op::<()>(KvmSevCmdId::LAUNCH_FINISH, None)?;102
Ok(())103
}104
105
pub fn snp_launch_start(&self, policy: SnpPolicy) -> Result<()> {106
let mut start = KvmSevSnpLaunchStart {107
policy,108
..Default::default()109
};110
self.sev_op(KvmSevCmdId::SNP_LAUNCH_START, Some(&mut start))?;111
Ok(())112
}113
114
pub fn snp_launch_update(&self, range: &mut [u8], gpa: u64, type_: SnpPageType) -> Result<()> {115
let mut update = KvmSevSnpLaunchUpdate {116
uaddr: range.as_mut_ptr() as _,117
len: range.len() as _,118
gfn_start: gpa >> 12,119
type_,120
..Default::default()121
};122
self.sev_op(KvmSevCmdId::SNP_LAUNCH_UPDATE, Some(&mut update))?;123
Ok(())124
}125
126
pub fn snp_launch_finish(&self) -> Result<()> {127
let mut finish = KvmSevSnpLaunchFinish::default();128
self.sev_op(KvmSevCmdId::SNP_LAUNCH_FINISH, Some(&mut finish))?;129
Ok(())130
}131
}132