@@ -83,8 +83,34 @@ pub trait Mapper<S: PageSize> {
8383 /// This function might need additional physical frames to create new page tables. These
8484 /// frames are allocated from the `allocator` argument. At most three frames are required.
8585 ///
86- /// This function is unsafe because the caller must guarantee that passed `frame` is
87- /// unused, i.e. not used for any other mappings.
86+ /// ## Safety
87+ ///
88+ /// Creating page table mappings is a fundamentally unsafe operation because
89+ /// there are various ways to break memory safety through it. For example,
90+ /// re-mapping an in-use page to a different frame changes and invalidates
91+ /// all values stored in that page, resulting in undefined behavior on the
92+ /// next use.
93+ ///
94+ /// The caller must ensure that no undefined behavior or memory safety
95+ /// violations can occur through the new mapping. Among other things, the
96+ /// caller must prevent the following:
97+ ///
98+ /// - Aliasing of `&mut` references, i.e. two `&mut` references that point to
99+ /// the same physical address. This is undefined behavior in Rust.
100+ /// - This can be ensured by mapping each page to an individual physical
101+ /// frame that is not mapped anywhere else.
102+ /// - Creating uninitalized or invalid values: Rust requires that all values
103+ /// have a correct memory layout. For example, a `bool` must be either a 0
104+ /// or a 1 in memory, but not a 3 or 4. An exception is the `MaybeUninit`
105+ /// wrapper type, which abstracts over possibly uninitialized memory.
106+ /// - This is only a problem when re-mapping pages to different physical
107+ /// frames. Mapping a page that is not in use yet is fine.
108+ ///
109+ /// Special care must be taken when sharing pages with other address spaces,
110+ /// e.g. by setting the `GLOBAL` flag. For example, a global mapping must be
111+ /// the same in all address spaces, otherwise undefined behavior can occur
112+ /// because of TLB races. It's worth noting that all the above requirements
113+ /// also apply to shared mappings, including the aliasing requirements.
88114 unsafe fn map_to < A > (
89115 & mut self ,
90116 page : Page < S > ,
@@ -118,8 +144,8 @@ pub trait Mapper<S: PageSize> {
118144 ///
119145 /// ## Safety
120146 ///
121- /// This function is unsafe because the caller must guarantee that the passed `frame` is
122- /// unused, i.e. not used for any other mappings .
147+ /// This is a convencience function that invokes [`map_to`] internally, so
148+ /// all safety requirements of it also apply for this function .
123149 #[ inline]
124150 unsafe fn identity_map < A > (
125151 & mut self ,
0 commit comments