Skip to content

Conversation

Manciukic
Copy link
Contributor

@Manciukic Manciukic commented Sep 24, 2025

Changes

  • introduce GuestMemoryCollection (coming in vm-memory) to store KVM slot
    • this will be used in virtio-mem to also store plugged/unplugged state
  • do not use last_addr to determine the last dram address, instead use the right guest memory region
  • move remove_range util function to free memory from balloon utils to GuestMemoryExtension trait
    • while I'm refactoring it, I'm also adding a TODO note about memfd backed memory (fallocate). I didn't want to increase the scope by adding a new syscall to the seccomp filter to support something we don't actually formally support.

Reason

This refactors are needed for the virtio-mem branch.

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following Developer
Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md.

PR Checklist

  • I have read and understand CONTRIBUTING.md.
  • I have run tools/devtool checkbuild --all to verify that the PR passes
    build checks on all supported architectures.
  • I have run tools/devtool checkstyle to verify that the PR passes the
    automated style checks.
  • I have described what is done in these changes, why they are needed, and
    how they are solving the problem in a clear and encompassing way.
  • I have updated any relevant documentation (both in code and in the docs)
    in the PR.
  • I have mentioned all user-facing changes in CHANGELOG.md.
  • If a specific issue led to this PR, this PR closes the issue.
  • When making API changes, I have followed the
    Runbook for Firecracker API changes.
  • I have tested all new and changed functionalities in unit tests and/or
    integration tests.
  • I have linked an issue to every new TODO.

  • This functionality cannot be added in rust-vmm.

@Manciukic Manciukic force-pushed the refactor/guest-memory-collection branch from 47c4116 to c6010f6 Compare September 24, 2025 12:18
Copy link

codecov bot commented Sep 24, 2025

Codecov Report

❌ Patch coverage is 78.99408% with 71 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.68%. Comparing base (896a5cf) to head (fc5c4b0).

Files with missing lines Patch % Lines
src/vmm/src/vm_memory_vendored.rs 44.80% 69 Missing ⚠️
src/vmm/src/resources.rs 90.90% 1 Missing ⚠️
src/vmm/src/vstate/vm.rs 98.18% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5452      +/-   ##
==========================================
- Coverage   82.78%   82.68%   -0.10%     
==========================================
  Files         263      264       +1     
  Lines       27292    27456     +164     
==========================================
+ Hits        22594    22703     +109     
- Misses       4698     4753      +55     
Flag Coverage Δ
5.10-m5n.metal 82.86% <77.46%> (-0.11%) ⬇️
5.10-m6a.metal 82.10% <77.46%> (-0.12%) ⬇️
5.10-m6g.metal 79.45% <77.77%> (-0.12%) ⬇️
5.10-m6i.metal 82.85% <77.46%> (-0.13%) ⬇️
5.10-m7a.metal-48xl 82.10% <77.46%> (-0.12%) ⬇️
5.10-m7g.metal 79.45% <77.77%> (-0.12%) ⬇️
5.10-m7i.metal-24xl 82.82% <77.46%> (-0.12%) ⬇️
5.10-m7i.metal-48xl 82.81% <77.46%> (-0.13%) ⬇️
5.10-m8g.metal-24xl 79.45% <77.77%> (-0.12%) ⬇️
5.10-m8g.metal-48xl 79.45% <77.77%> (-0.12%) ⬇️
6.1-m5n.metal 82.89% <77.46%> (-0.12%) ⬇️
6.1-m6a.metal 82.15% <77.46%> (-0.12%) ⬇️
6.1-m6g.metal 79.45% <77.77%> (-0.12%) ⬇️
6.1-m6i.metal 82.88% <77.46%> (-0.12%) ⬇️
6.1-m7a.metal-48xl 82.13% <77.46%> (-0.12%) ⬇️
6.1-m7g.metal 79.45% <77.77%> (-0.13%) ⬇️
6.1-m7i.metal-24xl 82.89% <77.46%> (-0.13%) ⬇️
6.1-m7i.metal-48xl 82.90% <77.46%> (-0.11%) ⬇️
6.1-m8g.metal-24xl 79.44% <77.77%> (-0.13%) ⬇️
6.1-m8g.metal-48xl 79.44% <77.77%> (-0.13%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Manciukic Manciukic force-pushed the refactor/guest-memory-collection branch from c6010f6 to b847d28 Compare September 24, 2025 12:51
Copy the implementation downstream while we wait for upstream.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
This refactor enables us to add more information to the GuestMemory.
To start off, I am adding KVM slot number and type of memory. So far we
only support Dram (normal memory), but we will also add Hotpluggable
region type in the future.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
As we will add other guest memory regions, last_addr() will not return
what we actually want: the last addr of the DRAM region.
Use the region type introduced in an earlier refactor to find the DRAM
region and use that instead.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
The way we populate the PVH and E820 memmap is by redoing all the math
about the regions.
Replace that duplicated logic with an iteration over the guest memory,
filtering by Dram type (as we don't want to expose other regions we will
add in the future). Furthermore, clamp the first 1MB as it's reserved
for the system.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
Split the actual allocation from the calculations to find the right
ranges.
This will be used to create the hotpluggable region in the future.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
@Manciukic Manciukic force-pushed the refactor/guest-memory-collection branch from b847d28 to c742637 Compare September 25, 2025 13:03
Move the function to discard guest memory under the GuestMemoryExtension
trait.
This is done so that it could be reused in other parts of the code.

Furthermore, this also changes it to use try_access, which is the
correct way to access a range of guest memory as it deals with the
possibility of it spanning multiple regions.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
This operation is completely useless after we mmap-ed anonymous
private zero pages on top of the file mapping.

Also, add a TODO for memfd-backed memory, as it's currently not
supported using madvise.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
This flag was used for determining how to discard memory, but we
previously changed that logic to look at the region mmap and perform the
right action depending on that.
This commit removes all references to this flag.

Signed-off-by: Riccardo Mancini <mancio@amazon.com>
@Manciukic Manciukic force-pushed the refactor/guest-memory-collection branch from c742637 to fc5c4b0 Compare September 25, 2025 13:22
Comment on lines +377 to +378
if self.common.next_slot > self.common.max_memslots {
Err(VmError::NotEnoughMemorySlots(self.common.max_memslots))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if check fails the self.common.next_slot should be decremented by num_slots.
Alternatevely:

let last_slot = self.common.next_slot + num_slots;
if self.common.max_memslots < last_slot { return Err(...) }
let new_slot = self.common_next_slot;
self.common_next_slot = last_slot;
return Ok(new_slot);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I can keep the order of check/increase as it was before. In any case this error is fatal and leads to the microvm not starting.

let start_addr = dram_region
.start_addr()
.unchecked_add(super::layout::SYSTEM_MEM_SIZE);
let mem_size = dram_region.last_addr().unchecked_offset_from(start_addr) + 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be simply dram_region.size()?
And start_address technically should be a DRAM_MEM_START always as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, start_addr is the start of the non-system memory, which is a SYSTEM_MEM_SIZE offset from the start of the region.
I could change it to:

let mem_size = dram_region.len() - SYSTEM_MEM_SIZE;

which is actually simpler.

Comment on lines 130 to 135
libc::mmap(
phys_address.cast(),
len,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_FIXED | libc::MAP_ANONYMOUS | libc::MAP_PRIVATE,
-1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can munmap be used here to ensure range is not usable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is for the balloon device, so we want to be able to keep accessing the memory. Since when restoring we have a private map of a file, we just patch an anon mapping on top of it to deallocate the previous mapping and any memory associated with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants