@@ -158,12 +158,17 @@ impl VirtAddr {
158
158
/// Aligns the virtual address upwards to the given alignment.
159
159
///
160
160
/// 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`.
161
166
#[ inline]
162
167
pub fn align_up < U > ( self , align : U ) -> Self
163
168
where
164
169
U : Into < u64 > ,
165
170
{
166
- VirtAddr ( align_up ( self . 0 , align. into ( ) ) )
171
+ VirtAddr :: new_truncate ( align_up ( self . 0 , align. into ( ) ) )
167
172
}
168
173
169
174
/// Aligns the virtual address downwards to the given alignment.
@@ -174,7 +179,7 @@ impl VirtAddr {
174
179
where
175
180
U : Into < u64 > ,
176
181
{
177
- VirtAddr ( align_down ( self . 0 , align. into ( ) ) )
182
+ VirtAddr :: new_truncate ( align_down ( self . 0 , align. into ( ) ) )
178
183
}
179
184
180
185
/// Checks whether the virtual address has the demanded alignment.
@@ -478,12 +483,17 @@ impl PhysAddr {
478
483
/// Aligns the physical address upwards to the given alignment.
479
484
///
480
485
/// 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.
481
491
#[ inline]
482
492
pub fn align_up < U > ( self , align : U ) -> Self
483
493
where
484
494
U : Into < u64 > ,
485
495
{
486
- PhysAddr ( align_up ( self . 0 , align. into ( ) ) )
496
+ PhysAddr :: new ( align_up ( self . 0 , align. into ( ) ) )
487
497
}
488
498
489
499
/// Aligns the physical address downwards to the given alignment.
@@ -637,15 +647,20 @@ pub const fn align_down(addr: u64, align: u64) -> u64 {
637
647
///
638
648
/// Returns the smallest `x` with alignment `align` so that `x >= addr`.
639
649
///
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 .
641
651
#[ inline]
642
652
pub const fn align_up ( addr : u64 , align : u64 ) -> u64 {
643
653
assert ! ( align. is_power_of_two( ) , "`align` must be a power of two" ) ;
644
654
let align_mask = align - 1 ;
645
655
if addr & align_mask == 0 {
646
656
addr // already aligned
647
657
} 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
+ }
649
664
}
650
665
}
651
666
@@ -791,4 +806,34 @@ mod tests {
791
806
assert_eq ! ( align_up( 0 , 2 ) , 0 ) ;
792
807
assert_eq ! ( align_up( 0 , 0x8000_0000_0000_0000 ) , 0 ) ;
793
808
}
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
+ }
794
839
}
0 commit comments