Skip to content

Commit 9457202

Browse files
authored
Merge pull request #1019 from msft-jlange/heap_info
svsm: fix issues with kernel region expansion
2 parents 3a3663f + f4c8960 commit 9457202

2 files changed

Lines changed: 26 additions & 27 deletions

File tree

kernel/src/kernel_region.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,6 @@ pub unsafe fn expand_kernel_heap(
121121
let new_pdpe_vaddr = VirtAddr::from(u64::from(new_pdpe_paddr) + phys_virt_diff);
122122
allocated_pages += 1;
123123

124-
// Prior to full heap initialization, unallocated heap pages
125-
// are not validated. Since this page is now allocated, it
126-
// must be validated before it can be used.
127-
// SAFETY: the newly mapped page is being used for the first
128-
// time, so it can be validated safely.
129-
unsafe {
130-
platform
131-
.validate_virtual_page_range(
132-
MemoryRegion::new(new_pdpe_vaddr, PAGE_SIZE),
133-
PageValidateOp::Validate,
134-
)
135-
.expect("Failed to validate heap memory");
136-
}
137-
138124
// Ensure that the newly allocated page is filled with zeroes.
139125
// SAFETY: the newly allocated page is known to be unused
140126
// because it is outside the bounds of allocated hep pages, and
@@ -156,6 +142,20 @@ pub unsafe fn expand_kernel_heap(
156142
// Fill in the PDE for the next direct map address in sequence.
157143
pdt[pde_index].set(make_private_address(paddr), pte_flags);
158144

145+
// By the time kernel region expansion is performed, the heap area has
146+
// been fully validated. Now that a new large page has been added,
147+
// that memory must be validated as well.
148+
// SAFETY: the newly mapped page is being used for the first
149+
// time, so it can be validated safely.
150+
unsafe {
151+
platform
152+
.validate_virtual_page_range(
153+
MemoryRegion::new(vaddr, PAGE_SIZE_2M),
154+
PageValidateOp::Validate,
155+
)
156+
.expect("Failed to validate heap memory");
157+
}
158+
159159
paddr = paddr + PAGE_SIZE_2M;
160160
vaddr = vaddr + PAGE_SIZE_2M;
161161
expansion_size -= PAGE_SIZE_2M as u64;

kernel/src/svsm.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,11 @@ unsafe fn memory_init(
188188
// within the direct map.
189189
let heap_vstart = launch_info.kernel_direct_map_vaddr + launch_info.heap_area_offset;
190190
let heap_vaddr = VirtAddr::from(heap_vstart);
191-
let heap_pstart = launch_info.kernel_region_phys_start + launch_info.heap_area_offset;
192-
let initial_heap_pregion = MemoryRegion::from_addresses(
193-
PhysAddr::from(heap_pstart),
194-
PhysAddr::from(launch_info.kernel_region_phys_end),
195-
);
191+
let heap_pstart =
192+
PhysAddr::from(launch_info.kernel_region_phys_start + launch_info.heap_area_offset);
193+
let mut heap_pend = PhysAddr::from(launch_info.kernel_region_phys_end);
196194
let mut heap_allocated = launch_info.heap_area_allocated as usize;
197-
let mut heap_length = initial_heap_pregion.len() / PAGE_SIZE;
195+
let mut heap_length = (heap_pend - heap_pstart) / PAGE_SIZE;
198196

199197
// Reduce the heap size if required.
200198
if heap_adjust_pages < 0 {
@@ -234,22 +232,23 @@ unsafe fn memory_init(
234232
)
235233
};
236234

237-
heap_length += heap_adjust_pages as usize;
235+
// Recalculate the heap size based on hoe much the kernel region
236+
// was actually expanded. This may be less than the requested size
237+
// if it was rounded down to a 2 MB boundary.
238+
heap_pend = PhysAddr::from(launch_info.kernel_region_phys_end);
239+
heap_length = (heap_pend - heap_pstart) / PAGE_SIZE;
238240
}
239241

240242
let heap_vregion = MemoryRegion::new(heap_vaddr, heap_length * PAGE_SIZE);
241243

242244
// Establish the heap region as the fixed kernel mapping region.
243-
let kernel_mapping = FixedAddressMappingRange::new(
244-
heap_vregion.start(),
245-
heap_vregion.end(),
246-
initial_heap_pregion.start(),
247-
);
245+
let kernel_mapping =
246+
FixedAddressMappingRange::new(heap_vregion.start(), heap_vregion.end(), heap_pstart);
248247
init_kernel_mapping_info(kernel_mapping, None);
249248

250249
// Initialize the page heap itself.
251250
root_mem_init(
252-
initial_heap_pregion.start(),
251+
heap_pstart,
253252
heap_vregion.start(),
254253
heap_length,
255254
heap_allocated,

0 commit comments

Comments
 (0)