diff --git a/aarch64/src/lib.rs b/aarch64/src/lib.rs index 5821fd8622..c88ad14d2b 100644 --- a/aarch64/src/lib.rs +++ b/aarch64/src/lib.rs @@ -364,6 +364,16 @@ fn load_kernel( pub struct AArch64; +fn get_block_size() -> u64 { + let page_size = base::pagesize(); + // Each PTE entry being 8 bytes long, we can fit in one page (page_size / 8) + // entries. + let ptes_per_page = page_size / 8; + let block_size = page_size * ptes_per_page; + + block_size as u64 +} + impl arch::LinuxArch for AArch64 { type Error = Error; @@ -376,7 +386,7 @@ impl arch::LinuxArch for AArch64 { let mut memory_regions = vec![( GuestAddress(AARCH64_PHYS_MEM_START), components.memory_size, - Default::default(), + MemoryRegionOptions::new().align(get_block_size()), )]; // Allocate memory for the pVM firmware. diff --git a/vm_memory/src/guest_memory.rs b/vm_memory/src/guest_memory.rs index 564cc3b2d9..fdae103bc2 100644 --- a/vm_memory/src/guest_memory.rs +++ b/vm_memory/src/guest_memory.rs @@ -130,6 +130,10 @@ pub struct MemoryRegionOptions { /// which memory region is used for protected firwmare, static swiotlb, /// or general purpose guest memory. pub purpose: MemoryRegionPurpose, + /// Alignment for the mapping of this region. This intends to be used for + /// arm64 KVM support where a block alignment is required for transparent + /// huge-pages support + pub align: u64, } impl MemoryRegionOptions { @@ -141,6 +145,11 @@ impl MemoryRegionOptions { self.purpose = purpose; self } + + pub fn align(mut self, alignment: u64) -> Self { + self.align = alignment; + self + } } /// A regions of memory mapped memory. @@ -286,6 +295,7 @@ impl GuestMemory { let mapping = MemoryMappingBuilder::new(size) .from_shared_memory(shm.as_ref()) .offset(offset) + .align(range.2.align) .build() .map_err(Error::MemoryMappingFailed)?;