@@ -361,6 +361,63 @@ mod x86_64 {
361361 asm ! ( "mov cr3, {}" , in( reg) value, options( nostack, preserves_flags) ) ;
362362 }
363363 }
364+
365+ /// Update the P4 table address in the CR3 register.
366+ ///
367+ /// ## Safety
368+ ///
369+ /// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
370+ /// changing the page mapping.
371+ #[ inline]
372+ pub unsafe fn update < F > ( f : F )
373+ where
374+ F : FnOnce ( & mut PhysFrame , & mut Cr3Flags ) ,
375+ {
376+ let ( mut frame, mut flags) = Self :: read ( ) ;
377+ f ( & mut frame, & mut flags) ;
378+ unsafe {
379+ Self :: write ( frame, flags) ;
380+ }
381+ }
382+
383+ /// Updates the P4 table address in the CR3 register.
384+ ///
385+ /// ## Safety
386+ ///
387+ /// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
388+ /// changing the page mapping.
389+ /// [`Cr4Flags::PCID`] must be set before calling this method.
390+ #[ inline]
391+ pub unsafe fn update_pcid < F > ( f : F )
392+ where
393+ F : FnOnce ( & mut PhysFrame , & mut Pcid ) ,
394+ {
395+ let ( mut frame, mut pcid) = Self :: read_pcid ( ) ;
396+ f ( & mut frame, & mut pcid) ;
397+ unsafe {
398+ Self :: write_pcid ( frame, pcid) ;
399+ }
400+ }
401+
402+ /// Updates the P4 table address in the CR3 register without flushing existing TLB entries for
403+ /// the PCID.
404+ ///
405+ /// ## Safety
406+ ///
407+ /// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
408+ /// changing the page mapping.
409+ /// [`Cr4Flags::PCID`] must be set before calling this method.
410+ #[ inline]
411+ pub unsafe fn update_pcid_no_flush < F > ( f : F )
412+ where
413+ F : FnOnce ( & mut PhysFrame , & mut Pcid ) ,
414+ {
415+ let ( mut frame, mut pcid) = Self :: read_pcid ( ) ;
416+ f ( & mut frame, & mut pcid) ;
417+ unsafe {
418+ Self :: write_pcid_no_flush ( frame, pcid) ;
419+ }
420+ }
364421 }
365422
366423 impl Cr4 {
0 commit comments