mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: Preserve SEV-SNP IGVM load ordering
Preserve the original IGVM import order for KVM SNP launch updates. The launch digest is order-sensitive, so only coalesce adjacent pages that already share the same page type and size. MSHV continues to sort by GPA for hypercall batching. Signed-off-by: Kevin Hui <kevinhui@meta.com>
This commit is contained in:
@@ -697,6 +697,11 @@ pub fn load_igvm(
|
|||||||
let area = parameter_areas
|
let area = parameter_areas
|
||||||
.get_mut(parameter_area_index)
|
.get_mut(parameter_area_index)
|
||||||
.expect("igvmfile should be valid");
|
.expect("igvmfile should be valid");
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
let page_count = match area {
|
||||||
|
ParameterAreaState::Allocated { max_size, .. } => *max_size / HV_PAGE_SIZE,
|
||||||
|
ParameterAreaState::Inserted => panic!("igvmfile is invalid, multiple insert"),
|
||||||
|
};
|
||||||
match area {
|
match area {
|
||||||
ParameterAreaState::Allocated { data, max_size } => {
|
ParameterAreaState::Allocated { data, max_size } => {
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
@@ -732,11 +737,25 @@ pub fn load_igvm(
|
|||||||
ParameterAreaState::Inserted => panic!("igvmfile is invalid, multiple insert"),
|
ParameterAreaState::Inserted => panic!("igvmfile is invalid, multiple insert"),
|
||||||
}
|
}
|
||||||
*area = ParameterAreaState::Inserted;
|
*area = ParameterAreaState::Inserted;
|
||||||
gpas.push(GpaPages {
|
match hypervisor_type {
|
||||||
gpa: *gpa,
|
#[cfg(feature = "kvm")]
|
||||||
page_type: page_types.unmeasured,
|
HypervisorType::Kvm => {
|
||||||
page_size: page_types.isolated_page_size_4kb,
|
for page_index in 0..page_count {
|
||||||
});
|
gpas.push(GpaPages {
|
||||||
|
gpa: *gpa + page_index * HV_PAGE_SIZE,
|
||||||
|
page_type: page_types.unmeasured,
|
||||||
|
page_size: page_types.isolated_page_size_4kb,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
gpas.push(GpaPages {
|
||||||
|
gpa: *gpa,
|
||||||
|
page_type: page_types.unmeasured,
|
||||||
|
page_size: page_types.isolated_page_size_4kb,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IgvmDirectiveHeader::ErrorRange { .. } => {
|
IgvmDirectiveHeader::ErrorRange { .. } => {
|
||||||
todo!("Error Range not supported")
|
todo!("Error Range not supported")
|
||||||
@@ -786,14 +805,24 @@ pub fn load_igvm(
|
|||||||
|
|
||||||
let mut now = Instant::now();
|
let mut now = Instant::now();
|
||||||
|
|
||||||
// Sort the gpas to group them by the page type
|
// KVM: preserve original IGVM ordering — the SNP launch digest is order-sensitive.
|
||||||
gpas.sort_by_key(|a| a.gpa);
|
// MSHV: sort by GPA to group pages by type for fewer hypercalls.
|
||||||
|
match hypervisor_type {
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
HypervisorType::Kvm => {}
|
||||||
|
_ => gpas.sort_by_key(|a| a.gpa),
|
||||||
|
}
|
||||||
|
|
||||||
let gpas_grouped = gpas
|
let gpas_grouped = gpas
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Vec::<Vec<GpaPages>>::new(), |mut acc, gpa| {
|
.fold(Vec::<Vec<GpaPages>>::new(), |mut acc, gpa| {
|
||||||
if let Some(last_vec) = acc.last_mut()
|
if let Some(last_vec) = acc.last_mut()
|
||||||
&& last_vec[0].page_type == gpa.page_type
|
&& last_vec[0].page_type == gpa.page_type
|
||||||
|
&& match hypervisor_type {
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
HypervisorType::Kvm => last_vec[0].page_size == gpa.page_size,
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
{
|
{
|
||||||
last_vec.push(*gpa);
|
last_vec.push(*gpa);
|
||||||
return acc;
|
return acc;
|
||||||
@@ -802,8 +831,7 @@ pub fn load_igvm(
|
|||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
// Import the pages as a group(by page type) of PFNs to reduce the
|
// Import pages as groups of PFNs to reduce hypercalls.
|
||||||
// hypercall.
|
|
||||||
for group in gpas_grouped.iter() {
|
for group in gpas_grouped.iter() {
|
||||||
info!(
|
info!(
|
||||||
"Importing {} page{}",
|
"Importing {} page{}",
|
||||||
|
|||||||
Reference in New Issue
Block a user