Skip to content

Commit 5b315d9

Browse files
haraldhphil-opp
authored andcommitted
Return the UnusedPhysFrame on MapToError::PageAlreadyMapped (#118)
The UnusedPhysFrame might want to be used otherwise. Fixes #117
1 parent c94759c commit 5b315d9

File tree

4 files changed

+48
-30
lines changed

4 files changed

+48
-30
lines changed

src/structures/paging/mapper/mapped_page_table.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
4242
frame: UnusedPhysFrame<Size1GiB>,
4343
flags: PageTableFlags,
4444
allocator: &mut A,
45-
) -> Result<MapperFlush<Size1GiB>, MapToError>
45+
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
4646
where
4747
A: FrameAllocator<Size4KiB>,
4848
{
@@ -52,7 +52,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
5252
.create_next_table(&mut p4[page.p4_index()], allocator)?;
5353

5454
if !p3[page.p3_index()].is_unused() {
55-
return Err(MapToError::PageAlreadyMapped);
55+
return Err(MapToError::PageAlreadyMapped(frame));
5656
}
5757
p3[page.p3_index()].set_addr(frame.start_address(), flags | PageTableFlags::HUGE_PAGE);
5858

@@ -67,7 +67,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
6767
frame: UnusedPhysFrame<Size2MiB>,
6868
flags: PageTableFlags,
6969
allocator: &mut A,
70-
) -> Result<MapperFlush<Size2MiB>, MapToError>
70+
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
7171
where
7272
A: FrameAllocator<Size4KiB>,
7373
{
@@ -80,7 +80,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
8080
.create_next_table(&mut p3[page.p3_index()], allocator)?;
8181

8282
if !p2[page.p2_index()].is_unused() {
83-
return Err(MapToError::PageAlreadyMapped);
83+
return Err(MapToError::PageAlreadyMapped(frame));
8484
}
8585
p2[page.p2_index()].set_addr(frame.start_address(), flags | PageTableFlags::HUGE_PAGE);
8686

@@ -95,7 +95,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
9595
frame: UnusedPhysFrame<Size4KiB>,
9696
flags: PageTableFlags,
9797
allocator: &mut A,
98-
) -> Result<MapperFlush<Size4KiB>, MapToError>
98+
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
9999
where
100100
A: FrameAllocator<Size4KiB>,
101101
{
@@ -111,7 +111,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
111111
.create_next_table(&mut p2[page.p2_index()], allocator)?;
112112

113113
if !p1[page.p1_index()].is_unused() {
114-
return Err(MapToError::PageAlreadyMapped);
114+
return Err(MapToError::PageAlreadyMapped(frame));
115115
}
116116
p1[page.p1_index()].set_frame(frame.frame(), flags);
117117

@@ -126,7 +126,7 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
126126
frame: UnusedPhysFrame<Size1GiB>,
127127
flags: PageTableFlags,
128128
allocator: &mut A,
129-
) -> Result<MapperFlush<Size1GiB>, MapToError>
129+
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
130130
where
131131
A: FrameAllocator<Size4KiB>,
132132
{
@@ -199,7 +199,7 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
199199
frame: UnusedPhysFrame<Size2MiB>,
200200
flags: PageTableFlags,
201201
allocator: &mut A,
202-
) -> Result<MapperFlush<Size2MiB>, MapToError>
202+
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
203203
where
204204
A: FrameAllocator<Size4KiB>,
205205
{
@@ -280,7 +280,7 @@ impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
280280
frame: UnusedPhysFrame<Size4KiB>,
281281
flags: PageTableFlags,
282282
allocator: &mut A,
283-
) -> Result<MapperFlush<Size4KiB>, MapToError>
283+
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
284284
where
285285
A: FrameAllocator<Size4KiB>,
286286
{
@@ -499,7 +499,25 @@ enum PageTableCreateError {
499499
FrameAllocationFailed,
500500
}
501501

502-
impl From<PageTableCreateError> for MapToError {
502+
impl From<PageTableCreateError> for MapToError<Size4KiB> {
503+
fn from(err: PageTableCreateError) -> Self {
504+
match err {
505+
PageTableCreateError::MappedToHugePage => MapToError::ParentEntryHugePage,
506+
PageTableCreateError::FrameAllocationFailed => MapToError::FrameAllocationFailed,
507+
}
508+
}
509+
}
510+
511+
impl From<PageTableCreateError> for MapToError<Size2MiB> {
512+
fn from(err: PageTableCreateError) -> Self {
513+
match err {
514+
PageTableCreateError::MappedToHugePage => MapToError::ParentEntryHugePage,
515+
PageTableCreateError::FrameAllocationFailed => MapToError::FrameAllocationFailed,
516+
}
517+
}
518+
}
519+
520+
impl From<PageTableCreateError> for MapToError<Size1GiB> {
503521
fn from(err: PageTableCreateError) -> Self {
504522
match err {
505523
PageTableCreateError::MappedToHugePage => MapToError::ParentEntryHugePage,

src/structures/paging/mapper/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub trait Mapper<S: PageSize> {
8888
frame: UnusedPhysFrame<S>,
8989
flags: PageTableFlags,
9090
frame_allocator: &mut A,
91-
) -> Result<MapperFlush<S>, MapToError>
91+
) -> Result<MapperFlush<S>, MapToError<S>>
9292
where
9393
Self: Sized,
9494
A: FrameAllocator<Size4KiB>;
@@ -117,7 +117,7 @@ pub trait Mapper<S: PageSize> {
117117
frame: UnusedPhysFrame<S>,
118118
flags: PageTableFlags,
119119
frame_allocator: &mut A,
120-
) -> Result<MapperFlush<S>, MapToError>
120+
) -> Result<MapperFlush<S>, MapToError<S>>
121121
where
122122
Self: Sized,
123123
A: FrameAllocator<Size4KiB>,
@@ -156,15 +156,15 @@ impl<S: PageSize> MapperFlush<S> {
156156

157157
/// This error is returned from `map_to` and similar methods.
158158
#[derive(Debug)]
159-
pub enum MapToError {
159+
pub enum MapToError<S: PageSize> {
160160
/// An additional frame was needed for the mapping process, but the frame allocator
161161
/// returned `None`.
162162
FrameAllocationFailed,
163163
/// An upper level page table entry has the `HUGE_PAGE` flag set, which means that the
164164
/// given page is part of an already mapped huge page.
165165
ParentEntryHugePage,
166166
/// The given page is already mapped to a physical frame.
167-
PageAlreadyMapped,
167+
PageAlreadyMapped(UnusedPhysFrame<S>),
168168
}
169169

170170
/// An error indicating that an `unmap` call failed.

src/structures/paging/mapper/offset_page_table.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<'a> Mapper<Size1GiB> for OffsetPageTable<'a> {
5555
frame: UnusedPhysFrame<Size1GiB>,
5656
flags: PageTableFlags,
5757
allocator: &mut A,
58-
) -> Result<MapperFlush<Size1GiB>, MapToError>
58+
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
5959
where
6060
A: FrameAllocator<Size4KiB>,
6161
{
@@ -89,7 +89,7 @@ impl<'a> Mapper<Size2MiB> for OffsetPageTable<'a> {
8989
frame: UnusedPhysFrame<Size2MiB>,
9090
flags: PageTableFlags,
9191
allocator: &mut A,
92-
) -> Result<MapperFlush<Size2MiB>, MapToError>
92+
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
9393
where
9494
A: FrameAllocator<Size4KiB>,
9595
{
@@ -123,7 +123,7 @@ impl<'a> Mapper<Size4KiB> for OffsetPageTable<'a> {
123123
frame: UnusedPhysFrame<Size4KiB>,
124124
flags: PageTableFlags,
125125
allocator: &mut A,
126-
) -> Result<MapperFlush<Size4KiB>, MapToError>
126+
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
127127
where
128128
A: FrameAllocator<Size4KiB>,
129129
{

src/structures/paging/mapper/recursive_page_table.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,22 @@ impl<'a> RecursivePageTable<'a> {
8585
/// Returns `MapToError::FrameAllocationFailed` if the entry is unused and the allocator
8686
/// returned `None`. Returns `MapToError::ParentEntryHugePage` if the `HUGE_PAGE` flag is set
8787
/// in the passed entry.
88-
unsafe fn create_next_table<'b, A>(
88+
unsafe fn create_next_table<'b, A, S: PageSize>(
8989
entry: &'b mut PageTableEntry,
9090
next_table_page: Page,
9191
allocator: &mut A,
92-
) -> Result<&'b mut PageTable, MapToError>
92+
) -> Result<&'b mut PageTable, MapToError<S>>
9393
where
9494
A: FrameAllocator<Size4KiB>,
9595
{
9696
/// This inner function is used to limit the scope of `unsafe`.
9797
///
9898
/// This is a safe function, so we need to use `unsafe` blocks when we do something unsafe.
99-
fn inner<'b, A>(
99+
fn inner<'b, A, S: PageSize>(
100100
entry: &'b mut PageTableEntry,
101101
next_table_page: Page,
102102
allocator: &mut A,
103-
) -> Result<&'b mut PageTable, MapToError>
103+
) -> Result<&'b mut PageTable, MapToError<S>>
104104
where
105105
A: FrameAllocator<Size4KiB>,
106106
{
@@ -141,7 +141,7 @@ impl<'a> RecursivePageTable<'a> {
141141
frame: UnusedPhysFrame<Size1GiB>,
142142
flags: PageTableFlags,
143143
allocator: &mut A,
144-
) -> Result<MapperFlush<Size1GiB>, MapToError>
144+
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
145145
where
146146
A: FrameAllocator<Size4KiB>,
147147
{
@@ -152,7 +152,7 @@ impl<'a> RecursivePageTable<'a> {
152152
let p3 = unsafe { Self::create_next_table(&mut p4[page.p4_index()], p3_page, allocator)? };
153153

154154
if !p3[page.p3_index()].is_unused() {
155-
return Err(MapToError::PageAlreadyMapped);
155+
return Err(MapToError::PageAlreadyMapped(frame));
156156
}
157157
p3[page.p3_index()].set_addr(frame.start_address(), flags | Flags::HUGE_PAGE);
158158

@@ -167,7 +167,7 @@ impl<'a> RecursivePageTable<'a> {
167167
frame: UnusedPhysFrame<Size2MiB>,
168168
flags: PageTableFlags,
169169
allocator: &mut A,
170-
) -> Result<MapperFlush<Size2MiB>, MapToError>
170+
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
171171
where
172172
A: FrameAllocator<Size4KiB>,
173173
{
@@ -181,7 +181,7 @@ impl<'a> RecursivePageTable<'a> {
181181
let p2 = unsafe { Self::create_next_table(&mut p3[page.p3_index()], p2_page, allocator)? };
182182

183183
if !p2[page.p2_index()].is_unused() {
184-
return Err(MapToError::PageAlreadyMapped);
184+
return Err(MapToError::PageAlreadyMapped(frame));
185185
}
186186
p2[page.p2_index()].set_addr(frame.start_address(), flags | Flags::HUGE_PAGE);
187187

@@ -196,7 +196,7 @@ impl<'a> RecursivePageTable<'a> {
196196
frame: UnusedPhysFrame<Size4KiB>,
197197
flags: PageTableFlags,
198198
allocator: &mut A,
199-
) -> Result<MapperFlush<Size4KiB>, MapToError>
199+
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
200200
where
201201
A: FrameAllocator<Size4KiB>,
202202
{
@@ -212,7 +212,7 @@ impl<'a> RecursivePageTable<'a> {
212212
let p1 = unsafe { Self::create_next_table(&mut p2[page.p2_index()], p1_page, allocator)? };
213213

214214
if !p1[page.p1_index()].is_unused() {
215-
return Err(MapToError::PageAlreadyMapped);
215+
return Err(MapToError::PageAlreadyMapped(frame));
216216
}
217217
p1[page.p1_index()].set_frame(frame.frame(), flags);
218218

@@ -227,7 +227,7 @@ impl<'a> Mapper<Size1GiB> for RecursivePageTable<'a> {
227227
frame: UnusedPhysFrame<Size1GiB>,
228228
flags: PageTableFlags,
229229
allocator: &mut A,
230-
) -> Result<MapperFlush<Size1GiB>, MapToError>
230+
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
231231
where
232232
A: FrameAllocator<Size4KiB>,
233233
{
@@ -312,7 +312,7 @@ impl<'a> Mapper<Size2MiB> for RecursivePageTable<'a> {
312312
frame: UnusedPhysFrame<Size2MiB>,
313313
flags: PageTableFlags,
314314
allocator: &mut A,
315-
) -> Result<MapperFlush<Size2MiB>, MapToError>
315+
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
316316
where
317317
A: FrameAllocator<Size4KiB>,
318318
{
@@ -417,7 +417,7 @@ impl<'a> Mapper<Size4KiB> for RecursivePageTable<'a> {
417417
frame: UnusedPhysFrame<Size4KiB>,
418418
flags: PageTableFlags,
419419
allocator: &mut A,
420-
) -> Result<MapperFlush<Size4KiB>, MapToError>
420+
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
421421
where
422422
A: FrameAllocator<Size4KiB>,
423423
{

0 commit comments

Comments
 (0)