mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-08 12:41:35 +00:00
vmm: tdx: Don't load the kernel the usual way
In case of TDX, if a kernel and/or a command line are provided by the user, they can't be treated the same way as for the non-TDX case. That is why this patch ensures the function load_kernel() is only invoked for the non-TDX case. For the TDX case, whenever TDVF contains a Payload and/or PayloadParam sections, the file provided through --kernel and the parameters provided through --cmdline are copied at the locations specified by each TDVF section. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
2198baa547
commit
3c421593c3
@ -64,6 +64,8 @@ use std::fmt;
|
|||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::io::{Seek, SeekFrom};
|
use std::io::{Seek, SeekFrom};
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
use std::mem;
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
@ -75,9 +77,9 @@ use vm_device::Bus;
|
|||||||
use vm_device::BusDevice;
|
use vm_device::BusDevice;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use vm_memory::Address;
|
use vm_memory::Address;
|
||||||
use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic};
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
use vm_memory::{GuestMemory, GuestMemoryRegion};
|
use vm_memory::{ByteValued, GuestMemory, GuestMemoryRegion};
|
||||||
|
use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic};
|
||||||
use vm_migration::protocol::{Request, Response, Status};
|
use vm_migration::protocol::{Request, Response, Status};
|
||||||
use vm_migration::{
|
use vm_migration::{
|
||||||
protocol::MemoryRangeTable, Migratable, MigratableError, Pausable, Snapshot,
|
protocol::MemoryRangeTable, Migratable, MigratableError, Pausable, Snapshot,
|
||||||
@ -255,10 +257,14 @@ pub enum Error {
|
|||||||
// Failed to copy to memory
|
// Failed to copy to memory
|
||||||
FirmwareLoad(vm_memory::GuestMemoryError),
|
FirmwareLoad(vm_memory::GuestMemoryError),
|
||||||
|
|
||||||
/// Error doing I/O on TDX firmware file
|
/// Error performing I/O on TDX firmware file
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
LoadTdvf(std::io::Error),
|
LoadTdvf(std::io::Error),
|
||||||
|
|
||||||
|
/// Error performing I/O on the payload file
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
LoadPayload(std::io::Error),
|
||||||
|
|
||||||
/// Error parsing TDVF
|
/// Error parsing TDVF
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
ParseTdvf(arch::x86_64::tdx::TdvfError),
|
ParseTdvf(arch::x86_64::tdx::TdvfError),
|
||||||
@ -282,6 +288,10 @@ pub enum Error {
|
|||||||
/// Error finalizing TDX setup
|
/// Error finalizing TDX setup
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
FinalizeTdx(hypervisor::HypervisorVmError),
|
FinalizeTdx(hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
|
/// Invalid payload type
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
InvalidPayloadType,
|
||||||
}
|
}
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
@ -1773,6 +1783,54 @@ impl Vm {
|
|||||||
TdvfSectionType::TdHob => {
|
TdvfSectionType::TdHob => {
|
||||||
hob_offset = Some(section.address);
|
hob_offset = Some(section.address);
|
||||||
}
|
}
|
||||||
|
TdvfSectionType::Payload => {
|
||||||
|
info!("Copying payload to guest memory");
|
||||||
|
if let Some(payload_file) = self.kernel.as_mut() {
|
||||||
|
let payload_size = payload_file
|
||||||
|
.seek(SeekFrom::End(0))
|
||||||
|
.map_err(Error::LoadPayload)?;
|
||||||
|
|
||||||
|
payload_file
|
||||||
|
.seek(SeekFrom::Start(0x1f1))
|
||||||
|
.map_err(Error::LoadPayload)?;
|
||||||
|
|
||||||
|
let mut payload_header = linux_loader::bootparam::setup_header::default();
|
||||||
|
payload_header
|
||||||
|
.as_bytes()
|
||||||
|
.read_from(
|
||||||
|
0,
|
||||||
|
payload_file,
|
||||||
|
mem::size_of::<linux_loader::bootparam::setup_header>(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if payload_header.header != 0x5372_6448 {
|
||||||
|
return Err(Error::InvalidPayloadType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload_header.version < 0x0200)
|
||||||
|
|| ((payload_header.loadflags & 0x1) == 0x0)
|
||||||
|
{
|
||||||
|
return Err(Error::InvalidPayloadType);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload_file
|
||||||
|
.seek(SeekFrom::Start(0))
|
||||||
|
.map_err(Error::LoadPayload)?;
|
||||||
|
mem.read_from(
|
||||||
|
GuestAddress(section.address),
|
||||||
|
payload_file,
|
||||||
|
payload_size as usize,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TdvfSectionType::PayloadParam => {
|
||||||
|
info!("Copying payload parameters to guest memory");
|
||||||
|
let cmdline = self.get_cmdline()?;
|
||||||
|
mem.write_slice(cmdline.as_str().as_bytes(), GuestAddress(section.address))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1965,6 +2023,18 @@ impl Vm {
|
|||||||
Some(rsdp_addr)
|
Some(rsdp_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn entry_point(&mut self) -> Result<Option<EntryPoint>> {
|
||||||
|
Ok(if self.kernel.as_ref().is_some() {
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
if self.config.lock().unwrap().tdx.is_some() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
Some(self.load_kernel()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn boot(&mut self) -> Result<()> {
|
pub fn boot(&mut self) -> Result<()> {
|
||||||
info!("Booting VM");
|
info!("Booting VM");
|
||||||
event!("vm", "booting");
|
event!("vm", "booting");
|
||||||
@ -1977,11 +2047,7 @@ impl Vm {
|
|||||||
current_state.valid_transition(new_state)?;
|
current_state.valid_transition(new_state)?;
|
||||||
|
|
||||||
// Load kernel if configured
|
// Load kernel if configured
|
||||||
let entry_point = if self.kernel.as_ref().is_some() {
|
let entry_point = self.entry_point()?;
|
||||||
Some(self.load_kernel()?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// The initial TDX configuration must be done before the vCPUs are
|
// The initial TDX configuration must be done before the vCPUs are
|
||||||
// created
|
// created
|
||||||
|
Loading…
x
Reference in New Issue
Block a user