@@ -66,13 +66,27 @@ impl<const PAGE_SIZE: usize> BaseAllocator for BitmapPageAllocator<PAGE_SIZE> {
6666 self . total_pages = ( end - start) / PAGE_SIZE ;
6767
6868 // Calculate the base offset stored in the real [`BitAlloc`] instance.
69+ // The base must be aligned to MAX_ALIGN_1GB to support maximum alignment.
6970 self . base = crate :: align_down ( start, MAX_ALIGN_1GB ) ;
7071
7172 // Range in bitmap: [start - self.base, start - self.base + total_pages * PAGE_SIZE)
72- let start = start - self . base ;
73- let start_idx = start / PAGE_SIZE ;
73+ let start_idx = ( start - self . base ) / PAGE_SIZE ;
74+ let end_idx = start_idx + self . total_pages ;
7475
75- self . inner . insert ( start_idx..start_idx + self . total_pages ) ;
76+ // Panic if the bitmap capacity is insufficient for the requested range.
77+ // This can happen when:
78+ // 1. The size is too large for the bitmap capacity
79+ // 2. The start address is not aligned well, creating a large gap
80+ assert ! (
81+ end_idx <= BitAllocUsed :: CAP ,
82+ "bitmap capacity exceeded: need {} pages but CAP is {} (start={:#x}, size={:#x})" ,
83+ end_idx,
84+ BitAllocUsed :: CAP ,
85+ start,
86+ size
87+ ) ;
88+
89+ self . inner . insert ( start_idx..end_idx) ;
7690 }
7791
7892 fn add_memory ( & mut self , _start : usize , _size : usize ) -> AllocResult {
@@ -334,4 +348,21 @@ mod tests {
334348 i += 1 ;
335349 }
336350 }
351+
352+ #[ test]
353+ #[ should_panic( expected = "bitmap capacity exceeded" ) ]
354+ fn test_init_capacity_exceeded ( ) {
355+ // Test that init panics when the required range exceeds bitmap capacity.
356+ // In test mode, BitAlloc1M has CAP = 1M pages = 4GB.
357+ // With a start address that creates a 1GB gap (due to alignment) and
358+ // requesting 4GB allocation, we need 1GB/4KB + 4GB/4KB = 256K + 1M = ~1.25M pages,
359+ // which exceeds the 1M capacity.
360+ let mut allocator = BitmapPageAllocator :: < PAGE_SIZE > :: new ( ) ;
361+ let size = 4 * 1024 * 1024 * 1024 ; // 4 GB - at capacity limit
362+ let start_addr = PAGE_SIZE ; // Small offset causes 1GB gap when aligned down to 1GB boundary
363+
364+ // This should panic because start is aligned down to 0, creating gap of 1 page,
365+ // and 4GB = 1M pages, total = 1M + 1 which exceeds CAP of 1M
366+ allocator. init ( start_addr, size) ;
367+ }
337368}
0 commit comments