Open colorglass opened 5 months ago
I reduce the memory pool size from 80MB to 1MB and run the VM Linux with 2GB available RAM. Here is my trial
project kernel/
diff --git a/src/plat/qemu-arm-virt/overlay-reserve-vm-memory.dts b/src/plat/qemu-arm-virt/overlay-reserve-vm-memory.dts
index f4c18af24..ddf682337 100644
--- a/src/plat/qemu-arm-virt/overlay-reserve-vm-memory.dts
+++ b/src/plat/qemu-arm-virt/overlay-reserve-vm-memory.dts
@@ -13,7 +13,7 @@
ranges;
vm-memory@40000000 {
- reg = <0x0 0x40000000 0x0 0x20000000>;
+ reg = <0x0 0x40000000 0x0 0x80000000>;
no-map;
};
};
project projects/seL4_projects_libs/
diff --git a/libsel4vm/src/guest_ram.c b/libsel4vm/src/guest_ram.c
index 1d91906..24edfc5 100644
--- a/libsel4vm/src/guest_ram.c
+++ b/libsel4vm/src/guest_ram.c
@@ -169,14 +169,14 @@ int vm_ram_touch(vm_t *vm, uintptr_t addr, size_t size, ram_touch_callback_fn to
access_cookie.data = cookie;
access_cookie.vm = vm;
for (current_addr = addr; current_addr < end_addr; current_addr = next_addr) {
- uintptr_t current_aligned = PAGE_ALIGN_4K(current_addr);
- uintptr_t next_page_start = current_aligned + PAGE_SIZE_4K;
+ uintptr_t current_aligned = PAGE_ALIGN_2M(current_addr);
+ uintptr_t next_page_start = current_aligned + PAGE_SIZE_2M;
next_addr = MIN(end_addr, next_page_start);
access_cookie.size = next_addr - current_addr;
access_cookie.offset = current_addr - addr;
access_cookie.current_addr = current_addr;
int result = vspace_access_page_with_callback(&vm->mem.vm_vspace, &vm->mem.vmm_vspace, (void *)current_aligned,
- seL4_PageBits, seL4_AllRights, 1, touch_access_callback, &access_cookie);
+ seL4_LargePageBits, seL4_AllRights, 1, touch_access_callback, &access_cookie);
if (result) {
return result;
}
@@ -289,7 +289,7 @@ static vm_frame_t ram_ut_alloc_iterator(uintptr_t addr, void *cookie)
if (!vm) {
return frame_result;
}
- int page_size = seL4_PageBits;
+ int page_size = seL4_LargePageBits;
uintptr_t frame_start = ROUND_DOWN(addr, BIT(page_size));
cspacepath_t path;
error = vka_cspace_alloc_path(vm->vka, &path);
project projects/vm-examples/
diff --git a/apps/Arm/vm_minimal/qemu-arm-virt/devices.camkes b/apps/Arm/vm_minimal/qemu-arm-virt/devices.camkes
index e012012..28f845d 100644
--- a/apps/Arm/vm_minimal/qemu-arm-virt/devices.camkes
+++ b/apps/Arm/vm_minimal/qemu-arm-virt/devices.camkes
@@ -8,7 +8,7 @@
#define VM_INITRD_MAX_SIZE 0x1900000 //25 MB
#define VM_RAM_BASE 0x40000000
-#define VM_RAM_SIZE 0x20000000
+#define VM_RAM_SIZE 0x80000000
#define VM_RAM_OFFSET 0x00000000
#define VM_DTB_ADDR 0x4F000000
#define VM_INITRD_ADDR 0x4D700000
@@ -39,7 +39,10 @@ assembly {
vm0.untyped_mmios = [
"0x8040000:12", // Interrupt Controller Virtual CPU interface (Virtual Machine view)
- "0x40000000:29", // Linux kernel memory regions
+ "0x40000000:30", // Linux kernel memory regions
+ "0x80000000:30",
];
+
+ vm0.allocator_mempool_size = 0x100000; // 1MB
}
}
diff --git a/apps/Arm/vm_minimal/settings.cmake b/apps/Arm/vm_minimal/settings.cmake
index 42a5d86..a0b54a9 100644
--- a/apps/Arm/vm_minimal/settings.cmake
+++ b/apps/Arm/vm_minimal/settings.cmake
@@ -32,7 +32,7 @@ if(${PLATFORM} STREQUAL "odroidc2")
endif()
if(${PLATFORM} STREQUAL "qemu-arm-virt")
# force cpu
- set(QEMU_MEMORY "2048")
+ set(QEMU_MEMORY "4096")
set(KernelArmCPU cortex-a53 CACHE STRING "" FORCE)
set(VmInitRdFile ON CACHE BOOL "" FORCE)
endif()
diff --git a/apps/Arm/vm_minimal/vm_minimal.camkes b/apps/Arm/vm_minimal/vm_minimal.camkes
index f6b98a4..d139e87 100644
--- a/apps/Arm/vm_minimal/vm_minimal.camkes
+++ b/apps/Arm/vm_minimal/vm_minimal.camkes
@@ -24,7 +24,7 @@ assembly {
vm0.num_extra_frame_caps = 0;
vm0.extra_frame_map_address = 0;
- vm0.cnode_size_bits = 23;
+ vm0.cnode_size_bits = 18;
vm0.simple_untyped24_pool = 12;
}
}
Running:
Welcome to Buildroot
buildroot login: root
# free -m
total used free shared buff/cache available
Mem: 2001 10 1988 1 1 1957
Swap: 0 0 0
FWIW, I really like this update.
However, on x86 based system with DMA, you need to map with 4k pages, since the IOMMU/IOSpace support in the kernel doesn't support 2M or 1GB pages.
I was working around with the default
vm_minimal
forqemu-arm-virt
64bits platform and tried to allocate 2GB RAM for the VM linux and got some allocation fail error.I found that it was caused by that the static memory pool of
allocman
was consumed up. Then I mentioned that the static memory pool was predefined default to 80MB size. (https://github.com/seL4/camkes-vm/blob/master/templates/seL4AllocatorMempool.template.c#L9)I tried to add it to 140MB and VM Linux was boot successed. But 140MB / 2GB is an unexpected proportion to me.
Then I dived into the details of the related codes and found the default allocator for
untyped
frames isBuddy
like and the RAM allocation is at a 4K granularity. https://github.com/seL4/seL4_libs/blob/master/libsel4allocman/src/utspace/split.c https://github.com/seL4/seL4_projects_libs/blob/97360824eebc80e9a68fef9ef699f3c0ff8bd792/libsel4vm/src/guest_ram.c#L292With this, a 2GB RAM region will need (2GB / 4KB) 2 (sizeof(node) + overload) = 120MB memory.
Here we may switch to use
seL4_LargePage
in VM RAM register, and the allocation granularity is 2M, and reduce the memory overhead to 120MB / 512 size.