Skip to content

Commit eaf91c2

Browse files
authored
Merge pull request #114 from haraldh/p23_insert_flags
Add p23_insert_flag_mask argument to mapper.map_to()
2 parents cd0e895 + 4a72bc6 commit eaf91c2

File tree

4 files changed

+699
-46
lines changed

4 files changed

+699
-46
lines changed

src/structures/paging/mapper/mapped_page_table.rs

+185-25
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,18 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
4444
page: Page<Size1GiB>,
4545
frame: PhysFrame<Size1GiB>,
4646
flags: PageTableFlags,
47+
parent_table_flags: PageTableFlags,
4748
allocator: &mut A,
4849
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
4950
where
5051
A: FrameAllocator<Size4KiB>,
5152
{
5253
let p4 = &mut self.level_4_table;
53-
let p3 = self
54-
.page_table_walker
55-
.create_next_table(&mut p4[page.p4_index()], allocator)?;
54+
let p3 = self.page_table_walker.create_next_table(
55+
&mut p4[page.p4_index()],
56+
parent_table_flags,
57+
allocator,
58+
)?;
5659

5760
if !p3[page.p3_index()].is_unused() {
5861
return Err(MapToError::PageAlreadyMapped(frame));
@@ -69,18 +72,23 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
6972
page: Page<Size2MiB>,
7073
frame: PhysFrame<Size2MiB>,
7174
flags: PageTableFlags,
75+
parent_table_flags: PageTableFlags,
7276
allocator: &mut A,
7377
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
7478
where
7579
A: FrameAllocator<Size4KiB>,
7680
{
7781
let p4 = &mut self.level_4_table;
78-
let p3 = self
79-
.page_table_walker
80-
.create_next_table(&mut p4[page.p4_index()], allocator)?;
81-
let p2 = self
82-
.page_table_walker
83-
.create_next_table(&mut p3[page.p3_index()], allocator)?;
82+
let p3 = self.page_table_walker.create_next_table(
83+
&mut p4[page.p4_index()],
84+
parent_table_flags,
85+
allocator,
86+
)?;
87+
let p2 = self.page_table_walker.create_next_table(
88+
&mut p3[page.p3_index()],
89+
parent_table_flags,
90+
allocator,
91+
)?;
8492

8593
if !p2[page.p2_index()].is_unused() {
8694
return Err(MapToError::PageAlreadyMapped(frame));
@@ -97,21 +105,28 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
97105
page: Page<Size4KiB>,
98106
frame: PhysFrame<Size4KiB>,
99107
flags: PageTableFlags,
108+
parent_table_flags: PageTableFlags,
100109
allocator: &mut A,
101110
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
102111
where
103112
A: FrameAllocator<Size4KiB>,
104113
{
105114
let p4 = &mut self.level_4_table;
106-
let p3 = self
107-
.page_table_walker
108-
.create_next_table(&mut p4[page.p4_index()], allocator)?;
109-
let p2 = self
110-
.page_table_walker
111-
.create_next_table(&mut p3[page.p3_index()], allocator)?;
112-
let p1 = self
113-
.page_table_walker
114-
.create_next_table(&mut p2[page.p2_index()], allocator)?;
115+
let p3 = self.page_table_walker.create_next_table(
116+
&mut p4[page.p4_index()],
117+
parent_table_flags,
118+
allocator,
119+
)?;
120+
let p2 = self.page_table_walker.create_next_table(
121+
&mut p3[page.p3_index()],
122+
parent_table_flags,
123+
allocator,
124+
)?;
125+
let p1 = self.page_table_walker.create_next_table(
126+
&mut p2[page.p2_index()],
127+
parent_table_flags,
128+
allocator,
129+
)?;
115130

116131
if !p1[page.p1_index()].is_unused() {
117132
return Err(MapToError::PageAlreadyMapped(frame));
@@ -124,17 +139,18 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
124139

125140
impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
126141
#[inline]
127-
unsafe fn map_to<A>(
142+
unsafe fn map_to_with_table_flags<A>(
128143
&mut self,
129144
page: Page<Size1GiB>,
130145
frame: PhysFrame<Size1GiB>,
131146
flags: PageTableFlags,
147+
parent_table_flags: PageTableFlags,
132148
allocator: &mut A,
133149
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
134150
where
135151
A: FrameAllocator<Size4KiB>,
136152
{
137-
self.map_to_1gib(page, frame, flags, allocator)
153+
self.map_to_1gib(page, frame, flags, parent_table_flags, allocator)
138154
}
139155

140156
fn unmap(
@@ -181,6 +197,39 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
181197
Ok(MapperFlush::new(page))
182198
}
183199

200+
unsafe fn set_flags_p4_entry(
201+
&mut self,
202+
page: Page<Size1GiB>,
203+
flags: PageTableFlags,
204+
) -> Result<MapperFlushAll, FlagUpdateError> {
205+
let p4 = &mut self.level_4_table;
206+
let p4_entry = &mut p4[page.p4_index()];
207+
208+
if p4_entry.is_unused() {
209+
return Err(FlagUpdateError::PageNotMapped);
210+
}
211+
212+
p4_entry.set_flags(flags);
213+
214+
Ok(MapperFlushAll::new())
215+
}
216+
217+
unsafe fn set_flags_p3_entry(
218+
&mut self,
219+
_page: Page<Size1GiB>,
220+
_flags: PageTableFlags,
221+
) -> Result<MapperFlushAll, FlagUpdateError> {
222+
Err(FlagUpdateError::ParentEntryHugePage)
223+
}
224+
225+
unsafe fn set_flags_p2_entry(
226+
&mut self,
227+
_page: Page<Size1GiB>,
228+
_flags: PageTableFlags,
229+
) -> Result<MapperFlushAll, FlagUpdateError> {
230+
Err(FlagUpdateError::ParentEntryHugePage)
231+
}
232+
184233
fn translate_page(&self, page: Page<Size1GiB>) -> Result<PhysFrame<Size1GiB>, TranslateError> {
185234
let p4 = &self.level_4_table;
186235
let p3 = self.page_table_walker.next_table(&p4[page.p4_index()])?;
@@ -198,17 +247,18 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
198247

199248
impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
200249
#[inline]
201-
unsafe fn map_to<A>(
250+
unsafe fn map_to_with_table_flags<A>(
202251
&mut self,
203252
page: Page<Size2MiB>,
204253
frame: PhysFrame<Size2MiB>,
205254
flags: PageTableFlags,
255+
parent_table_flags: PageTableFlags,
206256
allocator: &mut A,
207257
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
208258
where
209259
A: FrameAllocator<Size4KiB>,
210260
{
211-
self.map_to_2mib(page, frame, flags, allocator)
261+
self.map_to_2mib(page, frame, flags, parent_table_flags, allocator)
212262
}
213263

214264
fn unmap(
@@ -262,6 +312,51 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
262312
Ok(MapperFlush::new(page))
263313
}
264314

315+
unsafe fn set_flags_p4_entry(
316+
&mut self,
317+
page: Page<Size2MiB>,
318+
flags: PageTableFlags,
319+
) -> Result<MapperFlushAll, FlagUpdateError> {
320+
let p4 = &mut self.level_4_table;
321+
let p4_entry = &mut p4[page.p4_index()];
322+
323+
if p4_entry.is_unused() {
324+
return Err(FlagUpdateError::PageNotMapped);
325+
}
326+
327+
p4_entry.set_flags(flags);
328+
329+
Ok(MapperFlushAll::new())
330+
}
331+
332+
unsafe fn set_flags_p3_entry(
333+
&mut self,
334+
page: Page<Size2MiB>,
335+
flags: PageTableFlags,
336+
) -> Result<MapperFlushAll, FlagUpdateError> {
337+
let p4 = &mut self.level_4_table;
338+
let p3 = self
339+
.page_table_walker
340+
.next_table_mut(&mut p4[page.p4_index()])?;
341+
let p3_entry = &mut p3[page.p3_index()];
342+
343+
if p3_entry.is_unused() {
344+
return Err(FlagUpdateError::PageNotMapped);
345+
}
346+
347+
p3_entry.set_flags(flags);
348+
349+
Ok(MapperFlushAll::new())
350+
}
351+
352+
unsafe fn set_flags_p2_entry(
353+
&mut self,
354+
_page: Page<Size2MiB>,
355+
_flags: PageTableFlags,
356+
) -> Result<MapperFlushAll, FlagUpdateError> {
357+
Err(FlagUpdateError::ParentEntryHugePage)
358+
}
359+
265360
fn translate_page(&self, page: Page<Size2MiB>) -> Result<PhysFrame<Size2MiB>, TranslateError> {
266361
let p4 = &self.level_4_table;
267362
let p3 = self.page_table_walker.next_table(&p4[page.p4_index()])?;
@@ -280,17 +375,18 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
280375

281376
impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
282377
#[inline]
283-
unsafe fn map_to<A>(
378+
unsafe fn map_to_with_table_flags<A>(
284379
&mut self,
285380
page: Page<Size4KiB>,
286381
frame: PhysFrame<Size4KiB>,
287382
flags: PageTableFlags,
383+
parent_table_flags: PageTableFlags,
288384
allocator: &mut A,
289385
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
290386
where
291387
A: FrameAllocator<Size4KiB>,
292388
{
293-
self.map_to_4kib(page, frame, flags, allocator)
389+
self.map_to_4kib(page, frame, flags, parent_table_flags, allocator)
294390
}
295391

296392
fn unmap(
@@ -344,6 +440,66 @@ impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
344440
Ok(MapperFlush::new(page))
345441
}
346442

443+
unsafe fn set_flags_p4_entry(
444+
&mut self,
445+
page: Page<Size4KiB>,
446+
flags: PageTableFlags,
447+
) -> Result<MapperFlushAll, FlagUpdateError> {
448+
let p4 = &mut self.level_4_table;
449+
let p4_entry = &mut p4[page.p4_index()];
450+
451+
if p4_entry.is_unused() {
452+
return Err(FlagUpdateError::PageNotMapped);
453+
}
454+
455+
p4_entry.set_flags(flags);
456+
457+
Ok(MapperFlushAll::new())
458+
}
459+
460+
unsafe fn set_flags_p3_entry(
461+
&mut self,
462+
page: Page<Size4KiB>,
463+
flags: PageTableFlags,
464+
) -> Result<MapperFlushAll, FlagUpdateError> {
465+
let p4 = &mut self.level_4_table;
466+
let p3 = self
467+
.page_table_walker
468+
.next_table_mut(&mut p4[page.p4_index()])?;
469+
let p3_entry = &mut p3[page.p3_index()];
470+
471+
if p3_entry.is_unused() {
472+
return Err(FlagUpdateError::PageNotMapped);
473+
}
474+
475+
p3_entry.set_flags(flags);
476+
477+
Ok(MapperFlushAll::new())
478+
}
479+
480+
unsafe fn set_flags_p2_entry(
481+
&mut self,
482+
page: Page<Size4KiB>,
483+
flags: PageTableFlags,
484+
) -> Result<MapperFlushAll, FlagUpdateError> {
485+
let p4 = &mut self.level_4_table;
486+
let p3 = self
487+
.page_table_walker
488+
.next_table_mut(&mut p4[page.p4_index()])?;
489+
let p2 = self
490+
.page_table_walker
491+
.next_table_mut(&mut p3[page.p3_index()])?;
492+
let p2_entry = &mut p2[page.p2_index()];
493+
494+
if p2_entry.is_unused() {
495+
return Err(FlagUpdateError::PageNotMapped);
496+
}
497+
498+
p2_entry.set_flags(flags);
499+
500+
Ok(MapperFlushAll::new())
501+
}
502+
347503
fn translate_page(&self, page: Page<Size4KiB>) -> Result<PhysFrame<Size4KiB>, TranslateError> {
348504
let p4 = &self.level_4_table;
349505
let p3 = self.page_table_walker.next_table(&p4[page.p4_index()])?;
@@ -461,6 +617,7 @@ impl<P: PhysToVirt> PageTableWalker<P> {
461617
fn create_next_table<'b, A>(
462618
&self,
463619
entry: &'b mut PageTableEntry,
620+
insert_flags: PageTableFlags,
464621
allocator: &mut A,
465622
) -> Result<&'b mut PageTable, PageTableCreateError>
466623
where
@@ -470,12 +627,15 @@ impl<P: PhysToVirt> PageTableWalker<P> {
470627

471628
if entry.is_unused() {
472629
if let Some(frame) = allocator.allocate_frame() {
473-
entry.set_frame(frame, PageTableFlags::PRESENT | PageTableFlags::WRITABLE);
630+
entry.set_frame(frame, insert_flags);
474631
created = true;
475632
} else {
476633
return Err(PageTableCreateError::FrameAllocationFailed);
477634
}
478635
} else {
636+
if !insert_flags.is_empty() && !entry.flags().contains(insert_flags) {
637+
entry.set_flags(entry.flags() | insert_flags);
638+
}
479639
created = false;
480640
}
481641

0 commit comments

Comments
 (0)