From 1798ed81948b3a87848a70ab8149048417fb5cf6 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 14 Sep 2020 11:36:31 +0200 Subject: [PATCH] vmm: virtio-mem: Enforce alignment and size requirements The virtio-mem driver is generating some warnings regarding both size and alignment of the virtio-mem region if not based on 128MiB: The alignment of the physical start address can make some memory unusable. The alignment of the physical end address can make some memory unusable. For these reasons, the current patch enforces virtio-mem regions to be 128MiB aligned and checks the size provided by the user is a multiple of 128MiB. Signed-off-by: Sebastien Boeuf --- virtio-devices/src/mem.rs | 10 ++++++---- vmm/src/memory_manager.rs | 8 +++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index 4f3f1042b..b6d22a9ae 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -42,8 +42,11 @@ use vmm_sys_util::eventfd::EventFd; const QUEUE_SIZE: u16 = 128; const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE]; +// 128MiB is the standard memory block size in Linux. A virtio-mem region must +// be aligned on this size, and the region size must be a multiple of it. +pub const VIRTIO_MEM_ALIGN_SIZE: u64 = 128 * 1024 * 1024; // Use 2 MiB alignment so transparent hugepages can be used by KVM. -pub const VIRTIO_MEM_DEFAULT_BLOCK_SIZE: u64 = 512 * 4096; +const VIRTIO_MEM_DEFAULT_BLOCK_SIZE: u64 = 512 * 4096; const VIRTIO_MEM_USABLE_EXTENT: u64 = 256 * 1024 * 1024; // Request processed successfully, applicable for @@ -702,13 +705,12 @@ impl Mem { ) -> io::Result { let region_len = region.len(); - if region_len != region_len / VIRTIO_MEM_DEFAULT_BLOCK_SIZE * VIRTIO_MEM_DEFAULT_BLOCK_SIZE - { + if region_len != region_len / VIRTIO_MEM_ALIGN_SIZE * VIRTIO_MEM_ALIGN_SIZE { return Err(io::Error::new( io::ErrorKind::Other, format!( "Virtio-mem size is not aligned with {}", - VIRTIO_MEM_DEFAULT_BLOCK_SIZE + VIRTIO_MEM_ALIGN_SIZE ), )); } diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index b1d799001..3651da2b0 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -523,11 +523,9 @@ impl MemoryManager { } else { // Alignment must be "natural" i.e. same as size of block let start_addr = GuestAddress( - (start_of_device_area.0 - + virtio_devices::VIRTIO_MEM_DEFAULT_BLOCK_SIZE - - 1) - / virtio_devices::VIRTIO_MEM_DEFAULT_BLOCK_SIZE - * virtio_devices::VIRTIO_MEM_DEFAULT_BLOCK_SIZE, + (start_of_device_area.0 + virtio_devices::VIRTIO_MEM_ALIGN_SIZE - 1) + / virtio_devices::VIRTIO_MEM_ALIGN_SIZE + * virtio_devices::VIRTIO_MEM_ALIGN_SIZE, ); let region = MemoryManager::create_ram_region(