Implement conversion traits for PhysAddr and VirtAddr#394
Implement conversion traits for PhysAddr and VirtAddr#394mikeleany wants to merge 4 commits intorust-osdev:masterfrom
Conversation
src/addr.rs
Outdated
| #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] | ||
| impl<T> From<&T> for VirtAddr { | ||
| #[inline] | ||
| fn from(addr: &T) -> Self { | ||
| Self::new(addr as *const _ as u64) | ||
| } | ||
| } | ||
|
|
||
| #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] | ||
| impl<T> From<&mut T> for VirtAddr { | ||
| #[inline] | ||
| fn from(addr: &mut T) -> Self { | ||
| Self::new(addr as *mut _ as u64) | ||
| } | ||
| } |
There was a problem hiding this comment.
These could fail on different architectures. Do we want to care about that given that most users will probably run on x86?
There was a problem hiding this comment.
Ah yeah, good point! I guess we could a target_arch cfg-gate to avoid this?
There was a problem hiding this comment.
Changes these to target_arch. The target_pointer_width ought to be reasonable if the target_arch is x86 or x86_64, so I just removed those.
There was a problem hiding this comment.
I was also wondering if we ought to use target_arch for the raw pointer conversions. I left them for now, since they implement TryFrom instead of From, but those really don't make a whole lot of sense on non-x86 based architectures.
src/addr.rs
Outdated
| } | ||
| } | ||
|
|
||
| #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] |
There was a problem hiding this comment.
There's also target_pointer_width = "16".
There was a problem hiding this comment.
Added target_pointer_width = "16" where applicable.
|
Do we want to deprecate the old conversion methods/constructors? |
I think the only issue here would be that some of those are Otherwise the idea seems reasonable to me. |
|
We should unify the
It's not entirely clear to me which variation we should use. |
| #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] | ||
| impl<T> From<&T> for VirtAddr { | ||
| #[inline] | ||
| fn from(addr: &T) -> Self { | ||
| Self::new(addr as *const _ as u64) | ||
| } | ||
| } | ||
|
|
||
| #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] | ||
| impl<T> From<&mut T> for VirtAddr { | ||
| #[inline] | ||
| fn from(addr: &mut T) -> Self { | ||
| Self::new(addr as *mut _ as u64) | ||
| } | ||
| } |
There was a problem hiding this comment.
These could technically fail if Intel's 5 level paging is active.
There was a problem hiding this comment.
This possibility was mentioned in issue #293, here and here.
The last comment on the subject, by @josephlr was:
Personally, I think the panic is fine (for now). Before we (potentially) support 5-level paging, we can just have a disclaimer that is like: "if you use 5-level paging, some methods might panic, but safety will not be violated".
No disclaimer has been added yet, but I can add one if that's the course we want to take.
There was a problem hiding this comment.
Personally, I think the panic is fine (for now). Before we (potentially) support 5-level paging, we can just have a disclaimer that is like: "if you use 5-level paging, some methods might panic, but safety will not be violated".
That seems like a good pragmatic option to me. Intel's LAM (Linear Address Masking) and AMD's UAI (Upper Address Ignore) can also cause problems because they relax the requirements on pointers to be canonical.
No disclaimer has been added yet, but I can add one if that's the course we want to take.
That'd be great, thanks!
For conversions from pointers (and references), I think
For conversions to pointers
So I think the following
However, if I modified the |
👍
We could also just drop the
👍
Yes, breaking changes should only be merged into the |
Implements the following conversions:
TryFrom<u64>forVirtAddrandPhysAddrTryFrom<usize>forVirtAddrandPhysAddrFrom<u32>forVirtAddrandPhysAddrTryFrom<*const T>forVirtAddrTryFrom<*mut T>forVirtAddrFrom<&T>forVirtAddrFrom<&mut T>forVirtAddrFrom<VirtAddr>foru64,*const Tand*mut TFrom<PhysAddr>foru64I restricted pointer and
usizeconversions with#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]. This restriction isn't strictly necessary forTryFrom, but without it we would need a different error type than whattry_newuses.Closes #268.
See also #293 (comment) by @josephlr.