-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement conversion traits for PhysAddr and VirtAddr #394
base: master
Are you sure you want to change the base?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, good point! I guess we could a target_arch
cfg
-gate to avoid this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that'd work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also target_pointer_width = "16"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could technically fail if Intel's 5 level paging is active.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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>
forVirtAddr
andPhysAddr
TryFrom<usize>
forVirtAddr
andPhysAddr
From<u32>
forVirtAddr
andPhysAddr
TryFrom<*const T>
forVirtAddr
TryFrom<*mut T>
forVirtAddr
From<&T>
forVirtAddr
From<&mut T>
forVirtAddr
From<VirtAddr>
foru64
,*const T
and*mut T
From<PhysAddr>
foru64
I restricted pointer and
usize
conversions 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_new
uses.Closes #268.
See also #293 (comment) by @josephlr.