@@ -209,27 +209,42 @@ impl PageTable {
209
209
/// Clears all entries.
210
210
#[ inline]
211
211
pub fn zero ( & mut self ) {
212
- for entry in self . entries . iter_mut ( ) {
212
+ for entry in self . iter_mut ( ) {
213
213
entry. set_unused ( ) ;
214
214
}
215
215
}
216
216
217
217
/// Returns an iterator over the entries of the page table.
218
218
#[ inline]
219
219
pub fn iter ( & self ) -> impl Iterator < Item = & PageTableEntry > {
220
- self . entries . iter ( )
220
+ ( 0 .. 512 ) . map ( move |i| & self . entries [ i ] )
221
221
}
222
222
223
223
/// Returns an iterator that allows modifying the entries of the page table.
224
224
#[ inline]
225
225
pub fn iter_mut ( & mut self ) -> impl Iterator < Item = & mut PageTableEntry > {
226
- self . entries . iter_mut ( )
226
+ // Note that we intentionally don't just return `self.entries.iter()`:
227
+ // Some users may choose to create a reference to a page table at
228
+ // `0xffff_ffff_ffff_f000`. This causes problems because calculating
229
+ // the end pointer of the page tables causes an overflow. Therefore
230
+ // creating page tables at that address is unsound and must be avoided.
231
+ // Unfortunately creating such page tables is quite common when
232
+ // recursive page tables are used, so we try to avoid calculating the
233
+ // end pointer if possible. `core::slice::Iter` calculates the end
234
+ // pointer to determine when it should stop yielding elements. Because
235
+ // we want to avoid calculating the end pointer, we don't use
236
+ // `core::slice::Iter`, we implement our own iterator that doesn't
237
+ // calculate the end pointer. This doesn't make creating page tables at
238
+ // that address sound, but it avoids some easy to trigger
239
+ // miscompilations.
240
+ let ptr = self . entries . as_mut_ptr ( ) ;
241
+ ( 0 ..512 ) . map ( move |i| unsafe { & mut * ptr. add ( i) } )
227
242
}
228
243
229
244
/// Checks if the page table is empty (all entries are zero).
230
245
#[ inline]
231
246
pub fn is_empty ( & self ) -> bool {
232
- self . entries . iter ( ) . all ( |entry| entry. is_unused ( ) )
247
+ self . iter ( ) . all ( |entry| entry. is_unused ( ) )
233
248
}
234
249
}
235
250
0 commit comments