@@ -158,12 +158,17 @@ impl VirtAddr {
158158 /// Aligns the virtual address upwards to the given alignment.
159159 ///
160160 /// See the `align_up` function for more information.
161+ ///
162+ /// # Panics
163+ ///
164+ /// This function panics if the resulting address is higher than
165+ /// `0xffff_ffff_ffff_ffff`.
161166 #[ inline]
162167 pub fn align_up < U > ( self , align : U ) -> Self
163168 where
164169 U : Into < u64 > ,
165170 {
166- VirtAddr ( align_up ( self . 0 , align. into ( ) ) )
171+ VirtAddr :: new_truncate ( align_up ( self . 0 , align. into ( ) ) )
167172 }
168173
169174 /// Aligns the virtual address downwards to the given alignment.
@@ -174,7 +179,7 @@ impl VirtAddr {
174179 where
175180 U : Into < u64 > ,
176181 {
177- VirtAddr ( align_down ( self . 0 , align. into ( ) ) )
182+ VirtAddr :: new_truncate ( align_down ( self . 0 , align. into ( ) ) )
178183 }
179184
180185 /// Checks whether the virtual address has the demanded alignment.
@@ -478,12 +483,17 @@ impl PhysAddr {
478483 /// Aligns the physical address upwards to the given alignment.
479484 ///
480485 /// See the `align_up` function for more information.
486+ ///
487+ /// # Panics
488+ ///
489+ /// This function panics if the resulting address has a bit in the range 52
490+ /// to 64 set.
481491 #[ inline]
482492 pub fn align_up < U > ( self , align : U ) -> Self
483493 where
484494 U : Into < u64 > ,
485495 {
486- PhysAddr ( align_up ( self . 0 , align. into ( ) ) )
496+ PhysAddr :: new ( align_up ( self . 0 , align. into ( ) ) )
487497 }
488498
489499 /// Aligns the physical address downwards to the given alignment.
@@ -637,15 +647,20 @@ pub const fn align_down(addr: u64, align: u64) -> u64 {
637647///
638648/// Returns the smallest `x` with alignment `align` so that `x >= addr`.
639649///
640- /// Panics if the alignment is not a power of two.
650+ /// Panics if the alignment is not a power of two or if an overflow occurs .
641651#[ inline]
642652pub const fn align_up ( addr : u64 , align : u64 ) -> u64 {
643653 assert ! ( align. is_power_of_two( ) , "`align` must be a power of two" ) ;
644654 let align_mask = align - 1 ;
645655 if addr & align_mask == 0 {
646656 addr // already aligned
647657 } else {
648- ( addr | align_mask) + 1
658+ // FIXME: Replace with .expect, once `Option::expect` is const.
659+ if let Some ( aligned) = ( addr | align_mask) . checked_add ( 1 ) {
660+ aligned
661+ } else {
662+ panic ! ( "attempt to add with overflow" )
663+ }
649664 }
650665}
651666
@@ -791,4 +806,34 @@ mod tests {
791806 assert_eq ! ( align_up( 0 , 2 ) , 0 ) ;
792807 assert_eq ! ( align_up( 0 , 0x8000_0000_0000_0000 ) , 0 ) ;
793808 }
809+
810+ #[ test]
811+ fn test_virt_addr_align_up ( ) {
812+ // Make sure the 47th bit is extended.
813+ assert_eq ! (
814+ VirtAddr :: new( 0x7fff_ffff_ffff ) . align_up( 2u64 ) ,
815+ VirtAddr :: new( 0xffff_8000_0000_0000 )
816+ ) ;
817+ }
818+
819+ #[ test]
820+ fn test_virt_addr_align_down ( ) {
821+ // Make sure the 47th bit is extended.
822+ assert_eq ! (
823+ VirtAddr :: new( 0xffff_8000_0000_0000 ) . align_down( 1u64 << 48 ) ,
824+ VirtAddr :: new( 0 )
825+ ) ;
826+ }
827+
828+ #[ test]
829+ #[ should_panic]
830+ fn test_virt_addr_align_up_overflow ( ) {
831+ VirtAddr :: new ( 0xffff_ffff_ffff_ffff ) . align_up ( 2u64 ) ;
832+ }
833+
834+ #[ test]
835+ #[ should_panic]
836+ fn test_phys_addr_align_up_overflow ( ) {
837+ PhysAddr :: new ( 0x000f_ffff_ffff_ffff ) . align_up ( 2u64 ) ;
838+ }
794839}
0 commit comments