Skip to content

Commit 2fbc64b

Browse files
gaojiaqi7jyao1
authored andcommitted
fix the regression on frame allocator for page table
Correct the miatake use of 'base' field of BMFrameAllocator, otherwise the allocated frames will be started from a wrong value. The page table only occupies 1M bytes memory at present, so the problem has not been exposed yet. In addition, a page must be reserved for level-4 table when we init the frame allocator. Signed-off-by: Jiaqi Gao <jiaqi.gao@intel.com>
1 parent 6ffe3a1 commit 2fbc64b

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

td-paging/src/frame.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ impl BMFrameAllocator {
9393
// - base + size doesn't wrap around
9494
fn new(base: usize, size: usize) -> Self {
9595
let mut inner = FrameAlloc::default();
96-
let base = base / PAGE_SIZE;
9796
let page_count = size / PAGE_SIZE;
9897

9998
inner.free(0..page_count);
@@ -108,14 +107,16 @@ impl BMFrameAllocator {
108107
}
109108

110109
pub(crate) fn reserve(&mut self, addr: u64) {
111-
let idx = addr as usize / PAGE_SIZE;
112-
if addr > usize::MAX as u64 || idx < self.base || idx >= self.base + self.size {
110+
if addr > usize::MAX as u64
111+
|| (addr as usize) < self.base
112+
|| (addr as usize) >= self.base + self.size
113+
{
113114
panic!(
114115
"Invalid address 0x{:x} to BMFrameAllocator::reserve()",
115116
addr
116117
);
117118
}
118-
self.inner.reserve(idx - self.base);
119+
self.inner.reserve((addr as usize - self.base) / PAGE_SIZE);
119120
}
120121
}
121122

@@ -131,6 +132,9 @@ pub(super) fn init() {
131132
let mut allocator = FRAME_ALLOCATOR.lock();
132133
if allocator.base == 0 && allocator.size == 0 {
133134
*allocator = BMFrameAllocator::new(TD_PAYLOAD_PAGE_TABLE_BASE as usize, PAGE_TABLE_SIZE);
135+
// The first frame should've already been allocated to level 4 PT
136+
// Safe since the PAGE_TABLE_SIZE can be ensured
137+
allocator.alloc().unwrap();
134138
info!(
135139
"Frame allocator init done: {:#x?}\n",
136140
TD_PAYLOAD_PAGE_TABLE_BASE..TD_PAYLOAD_PAGE_TABLE_BASE + PAGE_TABLE_SIZE as u64
@@ -229,11 +233,12 @@ mod tests {
229233
init();
230234
let mut allocator = FRAME_ALLOCATOR.lock();
231235

232-
allocator.reserve(TD_PAYLOAD_PAGE_TABLE_BASE);
236+
// First page has been allocated by init(), try second page
237+
allocator.reserve(TD_PAYLOAD_PAGE_TABLE_BASE + PAGE_SIZE as u64);
233238
allocator.reserve(TD_PAYLOAD_PAGE_TABLE_BASE + PAGE_TABLE_SIZE as u64 - 1);
234239
assert_eq!(
235240
allocator.allocate_frame().unwrap().start_address().as_u64(),
236-
0x1000
241+
TD_PAYLOAD_PAGE_TABLE_BASE + 2 * PAGE_SIZE as u64
237242
);
238243
}
239244
}

0 commit comments

Comments
 (0)