@@ -44,15 +44,18 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
44
44
page : Page < Size1GiB > ,
45
45
frame : PhysFrame < Size1GiB > ,
46
46
flags : PageTableFlags ,
47
+ parent_table_flags : PageTableFlags ,
47
48
allocator : & mut A ,
48
49
) -> Result < MapperFlush < Size1GiB > , MapToError < Size1GiB > >
49
50
where
50
51
A : FrameAllocator < Size4KiB > ,
51
52
{
52
53
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
+ ) ?;
56
59
57
60
if !p3[ page. p3_index ( ) ] . is_unused ( ) {
58
61
return Err ( MapToError :: PageAlreadyMapped ( frame) ) ;
@@ -69,18 +72,23 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
69
72
page : Page < Size2MiB > ,
70
73
frame : PhysFrame < Size2MiB > ,
71
74
flags : PageTableFlags ,
75
+ parent_table_flags : PageTableFlags ,
72
76
allocator : & mut A ,
73
77
) -> Result < MapperFlush < Size2MiB > , MapToError < Size2MiB > >
74
78
where
75
79
A : FrameAllocator < Size4KiB > ,
76
80
{
77
81
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
+ ) ?;
84
92
85
93
if !p2[ page. p2_index ( ) ] . is_unused ( ) {
86
94
return Err ( MapToError :: PageAlreadyMapped ( frame) ) ;
@@ -97,21 +105,28 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
97
105
page : Page < Size4KiB > ,
98
106
frame : PhysFrame < Size4KiB > ,
99
107
flags : PageTableFlags ,
108
+ parent_table_flags : PageTableFlags ,
100
109
allocator : & mut A ,
101
110
) -> Result < MapperFlush < Size4KiB > , MapToError < Size4KiB > >
102
111
where
103
112
A : FrameAllocator < Size4KiB > ,
104
113
{
105
114
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
+ ) ?;
115
130
116
131
if !p1[ page. p1_index ( ) ] . is_unused ( ) {
117
132
return Err ( MapToError :: PageAlreadyMapped ( frame) ) ;
@@ -124,17 +139,18 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
124
139
125
140
impl < ' a , P : PhysToVirt > Mapper < Size1GiB > for MappedPageTable < ' a , P > {
126
141
#[ inline]
127
- unsafe fn map_to < A > (
142
+ unsafe fn map_to_with_table_flags < A > (
128
143
& mut self ,
129
144
page : Page < Size1GiB > ,
130
145
frame : PhysFrame < Size1GiB > ,
131
146
flags : PageTableFlags ,
147
+ parent_table_flags : PageTableFlags ,
132
148
allocator : & mut A ,
133
149
) -> Result < MapperFlush < Size1GiB > , MapToError < Size1GiB > >
134
150
where
135
151
A : FrameAllocator < Size4KiB > ,
136
152
{
137
- self . map_to_1gib ( page, frame, flags, allocator)
153
+ self . map_to_1gib ( page, frame, flags, parent_table_flags , allocator)
138
154
}
139
155
140
156
fn unmap (
@@ -181,6 +197,39 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
181
197
Ok ( MapperFlush :: new ( page) )
182
198
}
183
199
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
+
184
233
fn translate_page ( & self , page : Page < Size1GiB > ) -> Result < PhysFrame < Size1GiB > , TranslateError > {
185
234
let p4 = & self . level_4_table ;
186
235
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> {
198
247
199
248
impl < ' a , P : PhysToVirt > Mapper < Size2MiB > for MappedPageTable < ' a , P > {
200
249
#[ inline]
201
- unsafe fn map_to < A > (
250
+ unsafe fn map_to_with_table_flags < A > (
202
251
& mut self ,
203
252
page : Page < Size2MiB > ,
204
253
frame : PhysFrame < Size2MiB > ,
205
254
flags : PageTableFlags ,
255
+ parent_table_flags : PageTableFlags ,
206
256
allocator : & mut A ,
207
257
) -> Result < MapperFlush < Size2MiB > , MapToError < Size2MiB > >
208
258
where
209
259
A : FrameAllocator < Size4KiB > ,
210
260
{
211
- self . map_to_2mib ( page, frame, flags, allocator)
261
+ self . map_to_2mib ( page, frame, flags, parent_table_flags , allocator)
212
262
}
213
263
214
264
fn unmap (
@@ -262,6 +312,51 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
262
312
Ok ( MapperFlush :: new ( page) )
263
313
}
264
314
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
+
265
360
fn translate_page ( & self , page : Page < Size2MiB > ) -> Result < PhysFrame < Size2MiB > , TranslateError > {
266
361
let p4 = & self . level_4_table ;
267
362
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> {
280
375
281
376
impl < ' a , P : PhysToVirt > Mapper < Size4KiB > for MappedPageTable < ' a , P > {
282
377
#[ inline]
283
- unsafe fn map_to < A > (
378
+ unsafe fn map_to_with_table_flags < A > (
284
379
& mut self ,
285
380
page : Page < Size4KiB > ,
286
381
frame : PhysFrame < Size4KiB > ,
287
382
flags : PageTableFlags ,
383
+ parent_table_flags : PageTableFlags ,
288
384
allocator : & mut A ,
289
385
) -> Result < MapperFlush < Size4KiB > , MapToError < Size4KiB > >
290
386
where
291
387
A : FrameAllocator < Size4KiB > ,
292
388
{
293
- self . map_to_4kib ( page, frame, flags, allocator)
389
+ self . map_to_4kib ( page, frame, flags, parent_table_flags , allocator)
294
390
}
295
391
296
392
fn unmap (
@@ -344,6 +440,66 @@ impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
344
440
Ok ( MapperFlush :: new ( page) )
345
441
}
346
442
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
+
347
503
fn translate_page ( & self , page : Page < Size4KiB > ) -> Result < PhysFrame < Size4KiB > , TranslateError > {
348
504
let p4 = & self . level_4_table ;
349
505
let p3 = self . page_table_walker . next_table ( & p4[ page. p4_index ( ) ] ) ?;
@@ -461,6 +617,7 @@ impl<P: PhysToVirt> PageTableWalker<P> {
461
617
fn create_next_table < ' b , A > (
462
618
& self ,
463
619
entry : & ' b mut PageTableEntry ,
620
+ insert_flags : PageTableFlags ,
464
621
allocator : & mut A ,
465
622
) -> Result < & ' b mut PageTable , PageTableCreateError >
466
623
where
@@ -470,12 +627,15 @@ impl<P: PhysToVirt> PageTableWalker<P> {
470
627
471
628
if entry. is_unused ( ) {
472
629
if let Some ( frame) = allocator. allocate_frame ( ) {
473
- entry. set_frame ( frame, PageTableFlags :: PRESENT | PageTableFlags :: WRITABLE ) ;
630
+ entry. set_frame ( frame, insert_flags ) ;
474
631
created = true ;
475
632
} else {
476
633
return Err ( PageTableCreateError :: FrameAllocationFailed ) ;
477
634
}
478
635
} else {
636
+ if !insert_flags. is_empty ( ) && !entry. flags ( ) . contains ( insert_flags) {
637
+ entry. set_flags ( entry. flags ( ) | insert_flags) ;
638
+ }
479
639
created = false ;
480
640
}
481
641
0 commit comments