@@ -20,7 +20,7 @@ const ADDRESS_SPACE_SIZE: u64 = 0x1_0000_0000_0000;
20
20
/// between `u64` and `usize`.
21
21
///
22
22
/// On `x86_64`, only the 48 lower bits of a virtual address can be used. The top 16 bits need
23
- /// to be copies of bit 47, i.e. the most significant bit. Addresses that fulfil this criterium
23
+ /// to be copies of bit 47, i.e. the most significant bit. Addresses that fulfil this criterion
24
24
/// are called “canonical”. This type guarantees that it always represents a canonical address.
25
25
#[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
26
26
#[ repr( transparent) ]
@@ -60,39 +60,43 @@ impl core::fmt::Debug for VirtAddrNotValid {
60
60
impl VirtAddr {
61
61
/// Creates a new canonical virtual address.
62
62
///
63
- /// This function performs sign extension of bit 47 to make the address canonical.
63
+ /// The provided address should already be canonical. If you want to check
64
+ /// whether an address is canonical, use [`try_new`](Self::try_new).
64
65
///
65
66
/// ## Panics
66
67
///
67
- /// This function panics if the bits in the range 48 to 64 contain data (i.e. are not null and no sign extension).
68
+ /// This function panics if the bits in the range 48 to 64 are invalid
69
+ /// (i.e. are not a proper sign extension of bit 47).
68
70
#[ inline]
69
- pub fn new ( addr : u64 ) -> VirtAddr {
70
- Self :: try_new ( addr) . expect (
71
- "address passed to VirtAddr::new must not contain any data \
72
- in bits 48 to 64",
73
- )
71
+ pub const fn new ( addr : u64 ) -> VirtAddr {
72
+ // TODO: Replace with .ok().expect(msg) when that works on stable.
73
+ match Self :: try_new ( addr) {
74
+ Ok ( v) => v,
75
+ Err ( _) => panic ! ( "virtual address must be sign extended in bits 48 to 64" ) ,
76
+ }
74
77
}
75
78
76
79
/// Tries to create a new canonical virtual address.
77
80
///
78
- /// This function tries to performs sign
79
- /// extension of bit 47 to make the address canonical. It succeeds if bits 48 to 64 are
80
- /// either a correct sign extension (i.e. copies of bit 47) or all null. Else, an error
81
- /// is returned.
82
- #[ inline]
83
- pub fn try_new ( addr : u64 ) -> Result < VirtAddr , VirtAddrNotValid > {
84
- match addr. get_bits ( 47 ..64 ) {
85
- 0 | 0x1ffff => Ok ( VirtAddr ( addr) ) , // address is canonical
86
- 1 => Ok ( VirtAddr :: new_truncate ( addr) ) , // address needs sign extension
87
- _ => Err ( VirtAddrNotValid ( addr) ) ,
81
+ /// This function checks wether the given address is canonical
82
+ /// and returns an error otherwise. An address is canonical
83
+ /// if bits 48 to 64 are a correct sign
84
+ /// extension (i.e. copies of bit 47).
85
+ #[ inline]
86
+ pub const fn try_new ( addr : u64 ) -> Result < VirtAddr , VirtAddrNotValid > {
87
+ let v = Self :: new_truncate ( addr) ;
88
+ if v. 0 == addr {
89
+ Ok ( v)
90
+ } else {
91
+ Err ( VirtAddrNotValid ( addr) )
88
92
}
89
93
}
90
94
91
95
/// Creates a new canonical virtual address, throwing out bits 48..64.
92
96
///
93
- /// This function performs sign extension of bit 47 to make the address canonical, so
94
- /// bits 48 to 64 are overwritten . If you want to check that these bits contain no data,
95
- /// use `new` or `try_new`.
97
+ /// This function performs sign extension of bit 47 to make the address
98
+ /// canonical, overwriting bits 48 to 64. If you want to check whether an
99
+ /// address is canonical, use [ `new`](Self::new) or [ `try_new`](Self::try_new) .
96
100
#[ inline]
97
101
pub const fn new_truncate ( addr : u64 ) -> VirtAddr {
98
102
// By doing the right shift as a signed operation (on a i64), it will
@@ -123,11 +127,7 @@ impl VirtAddr {
123
127
}
124
128
125
129
/// Creates a virtual address from the given pointer
126
- // cfg(target_pointer_width = "32") is only here for backwards
127
- // compatibility: Earlier versions of this crate did not have any `cfg()`
128
- // on this function. At least for 32- and 64-bit we know the `as u64` cast
129
- // doesn't truncate.
130
- #[ cfg( any( target_pointer_width = "32" , target_pointer_width = "64" ) ) ]
130
+ #[ cfg( target_pointer_width = "64" ) ]
131
131
#[ inline]
132
132
pub fn from_ptr < T : ?Sized > ( ptr : * const T ) -> Self {
133
133
Self :: new ( ptr as * const ( ) as u64 )
@@ -320,23 +320,6 @@ impl AddAssign<u64> for VirtAddr {
320
320
}
321
321
}
322
322
323
- #[ cfg( target_pointer_width = "64" ) ]
324
- impl Add < usize > for VirtAddr {
325
- type Output = Self ;
326
- #[ inline]
327
- fn add ( self , rhs : usize ) -> Self :: Output {
328
- self + rhs as u64
329
- }
330
- }
331
-
332
- #[ cfg( target_pointer_width = "64" ) ]
333
- impl AddAssign < usize > for VirtAddr {
334
- #[ inline]
335
- fn add_assign ( & mut self , rhs : usize ) {
336
- self . add_assign ( rhs as u64 )
337
- }
338
- }
339
-
340
323
impl Sub < u64 > for VirtAddr {
341
324
type Output = Self ;
342
325
#[ inline]
@@ -352,23 +335,6 @@ impl SubAssign<u64> for VirtAddr {
352
335
}
353
336
}
354
337
355
- #[ cfg( target_pointer_width = "64" ) ]
356
- impl Sub < usize > for VirtAddr {
357
- type Output = Self ;
358
- #[ inline]
359
- fn sub ( self , rhs : usize ) -> Self :: Output {
360
- self - rhs as u64
361
- }
362
- }
363
-
364
- #[ cfg( target_pointer_width = "64" ) ]
365
- impl SubAssign < usize > for VirtAddr {
366
- #[ inline]
367
- fn sub_assign ( & mut self , rhs : usize ) {
368
- self . sub_assign ( rhs as u64 )
369
- }
370
- }
371
-
372
338
impl Sub < VirtAddr > for VirtAddr {
373
339
type Output = u64 ;
374
340
#[ inline]
@@ -583,23 +549,6 @@ impl AddAssign<u64> for PhysAddr {
583
549
}
584
550
}
585
551
586
- #[ cfg( target_pointer_width = "64" ) ]
587
- impl Add < usize > for PhysAddr {
588
- type Output = Self ;
589
- #[ inline]
590
- fn add ( self , rhs : usize ) -> Self :: Output {
591
- self + rhs as u64
592
- }
593
- }
594
-
595
- #[ cfg( target_pointer_width = "64" ) ]
596
- impl AddAssign < usize > for PhysAddr {
597
- #[ inline]
598
- fn add_assign ( & mut self , rhs : usize ) {
599
- self . add_assign ( rhs as u64 )
600
- }
601
- }
602
-
603
552
impl Sub < u64 > for PhysAddr {
604
553
type Output = Self ;
605
554
#[ inline]
@@ -615,23 +564,6 @@ impl SubAssign<u64> for PhysAddr {
615
564
}
616
565
}
617
566
618
- #[ cfg( target_pointer_width = "64" ) ]
619
- impl Sub < usize > for PhysAddr {
620
- type Output = Self ;
621
- #[ inline]
622
- fn sub ( self , rhs : usize ) -> Self :: Output {
623
- self - rhs as u64
624
- }
625
- }
626
-
627
- #[ cfg( target_pointer_width = "64" ) ]
628
- impl SubAssign < usize > for PhysAddr {
629
- #[ inline]
630
- fn sub_assign ( & mut self , rhs : usize ) {
631
- self . sub_assign ( rhs as u64 )
632
- }
633
- }
634
-
635
567
impl Sub < PhysAddr > for PhysAddr {
636
568
type Output = u64 ;
637
569
#[ inline]
0 commit comments