@@ -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 (
@@ -198,17 +214,18 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
198
214
199
215
impl < ' a , P : PhysToVirt > Mapper < Size2MiB > for MappedPageTable < ' a , P > {
200
216
#[ inline]
201
- unsafe fn map_to < A > (
217
+ unsafe fn map_to_with_table_flags < A > (
202
218
& mut self ,
203
219
page : Page < Size2MiB > ,
204
220
frame : PhysFrame < Size2MiB > ,
205
221
flags : PageTableFlags ,
222
+ parent_table_flags : PageTableFlags ,
206
223
allocator : & mut A ,
207
224
) -> Result < MapperFlush < Size2MiB > , MapToError < Size2MiB > >
208
225
where
209
226
A : FrameAllocator < Size4KiB > ,
210
227
{
211
- self . map_to_2mib ( page, frame, flags, allocator)
228
+ self . map_to_2mib ( page, frame, flags, parent_table_flags , allocator)
212
229
}
213
230
214
231
fn unmap (
@@ -280,17 +297,18 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
280
297
281
298
impl < ' a , P : PhysToVirt > Mapper < Size4KiB > for MappedPageTable < ' a , P > {
282
299
#[ inline]
283
- unsafe fn map_to < A > (
300
+ unsafe fn map_to_with_table_flags < A > (
284
301
& mut self ,
285
302
page : Page < Size4KiB > ,
286
303
frame : PhysFrame < Size4KiB > ,
287
304
flags : PageTableFlags ,
305
+ parent_table_flags : PageTableFlags ,
288
306
allocator : & mut A ,
289
307
) -> Result < MapperFlush < Size4KiB > , MapToError < Size4KiB > >
290
308
where
291
309
A : FrameAllocator < Size4KiB > ,
292
310
{
293
- self . map_to_4kib ( page, frame, flags, allocator)
311
+ self . map_to_4kib ( page, frame, flags, parent_table_flags , allocator)
294
312
}
295
313
296
314
fn unmap (
@@ -461,6 +479,7 @@ impl<P: PhysToVirt> PageTableWalker<P> {
461
479
fn create_next_table < ' b , A > (
462
480
& self ,
463
481
entry : & ' b mut PageTableEntry ,
482
+ insert_flags : PageTableFlags ,
464
483
allocator : & mut A ,
465
484
) -> Result < & ' b mut PageTable , PageTableCreateError >
466
485
where
@@ -470,12 +489,15 @@ impl<P: PhysToVirt> PageTableWalker<P> {
470
489
471
490
if entry. is_unused ( ) {
472
491
if let Some ( frame) = allocator. allocate_frame ( ) {
473
- entry. set_frame ( frame, PageTableFlags :: PRESENT | PageTableFlags :: WRITABLE ) ;
492
+ entry. set_frame ( frame, insert_flags ) ;
474
493
created = true ;
475
494
} else {
476
495
return Err ( PageTableCreateError :: FrameAllocationFailed ) ;
477
496
}
478
497
} else {
498
+ if !insert_flags. is_empty ( ) && !entry. flags ( ) . contains ( insert_flags) {
499
+ entry. set_flags ( entry. flags ( ) | insert_flags) ;
500
+ }
479
501
created = false ;
480
502
}
481
503
0 commit comments