-
-
Notifications
You must be signed in to change notification settings - Fork 852
Add CapbilityPtr and Add SuccessAddr and SuccessPtr syscall variants
#4174
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
Changes from 1 commit
12abe15
c32507d
677183f
6254b9e
a5ee396
fd51098
c97deea
291c8f4
695af1b
7ec6bdd
d0fa5fc
be62a66
950deb2
236a8ac
a4e5936
9ac666b
010bf22
604460c
79b2b8d
6feb692
f800ddd
2cd33d2
bf24e72
d569776
743c8cd
144269e
cc0b53e
45f8a44
391dfc8
8f8ce44
a5e5a6d
f3feec6
a001b33
7ea663f
9560125
670a5d0
3810ca8
0709e6a
1ebf509
d23676d
38a5188
08caaa5
c6156c8
a803e1e
096536c
3c1876b
37cb959
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,48 +52,48 @@ pub(crate) fn memop(process: &dyn Process, op_type: usize, r1: usize) -> Syscall | |
| // Op Type 1: SBRK | ||
|
alevy marked this conversation as resolved.
|
||
| 1 => process | ||
| .sbrk(r1 as isize) | ||
| .map(|addr| SyscallReturn::SuccessU32(addr as u32)) | ||
| .map(|addr| SyscallReturn::SuccessPtr(addr)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...although |
||
| .unwrap_or(SyscallReturn::Failure(ErrorCode::NOMEM)), | ||
|
|
||
| // Op Type 2: Process memory start | ||
| 2 => SyscallReturn::SuccessU32(process.get_addresses().sram_start as u32), | ||
| 2 => SyscallReturn::SuccessUSize(process.get_addresses().sram_start), | ||
|
|
||
| // Op Type 3: Process memory end | ||
| 3 => SyscallReturn::SuccessU32(process.get_addresses().sram_end as u32), | ||
| 3 => SyscallReturn::SuccessUSize(process.get_addresses().sram_end), | ||
|
|
||
| // Op Type 4: Process flash start | ||
| 4 => SyscallReturn::SuccessU32(process.get_addresses().flash_start as u32), | ||
| 4 => SyscallReturn::SuccessUSize(process.get_addresses().flash_start), | ||
|
|
||
| // Op Type 5: Process flash end | ||
| 5 => SyscallReturn::SuccessU32(process.get_addresses().flash_end as u32), | ||
| 5 => SyscallReturn::SuccessUSize(process.get_addresses().flash_end), | ||
|
|
||
| // Op Type 6: Grant region begin | ||
| 6 => SyscallReturn::SuccessU32(process.get_addresses().sram_grant_start as u32), | ||
| 6 => SyscallReturn::SuccessUSize(process.get_addresses().sram_grant_start), | ||
|
|
||
| // Op Type 7: Number of defined writeable regions in the TBF header. | ||
| 7 => SyscallReturn::SuccessU32(process.number_writeable_flash_regions() as u32), | ||
| 7 => SyscallReturn::SuccessUSize(process.number_writeable_flash_regions()), | ||
|
|
||
| // Op Type 8: The start address of the writeable region indexed by r1. | ||
| 8 => { | ||
| let flash_start = process.get_addresses().flash_start as u32; | ||
| let flash_start = process.get_addresses().flash_start; | ||
| let (offset, size) = process.get_writeable_flash_region(r1); | ||
| if size == 0 { | ||
| SyscallReturn::Failure(ErrorCode::FAIL) | ||
| } else { | ||
| SyscallReturn::SuccessU32(flash_start + offset) | ||
| SyscallReturn::SuccessUSize(flash_start + offset) | ||
| } | ||
| } | ||
|
|
||
| // Op Type 9: The end address of the writeable region indexed by r1. | ||
| // Returns (void*) -1 on failure, meaning the selected writeable region | ||
| // does not exist. | ||
| 9 => { | ||
| let flash_start = process.get_addresses().flash_start as u32; | ||
| let flash_start = process.get_addresses().flash_start; | ||
| let (offset, size) = process.get_writeable_flash_region(r1); | ||
| if size == 0 { | ||
| SyscallReturn::Failure(ErrorCode::FAIL) | ||
| } else { | ||
| SyscallReturn::SuccessU32(flash_start + offset + size) | ||
| SyscallReturn::SuccessUSize(flash_start + offset + size) | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| // Licensed under the Apache License, Version 2.0 or the MIT License. | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| // Copyright Google LLC 2024. | ||
|
|
||
| //! Defines the MetaPtr type | ||
|
|
||
| use core::fmt::{Formatter, LowerHex, UpperHex}; | ||
| use core::ops::AddAssign; | ||
|
|
||
| /// A pointer with target specific metadata. | ||
| /// This should be used any time the kernel wishes to grant authority to the user, or any time | ||
| /// the user should be required to prove validity of a pointer. | ||
|
alevy marked this conversation as resolved.
Outdated
|
||
| #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] | ||
| #[repr(transparent)] | ||
|
LawrenceEsswood marked this conversation as resolved.
Outdated
|
||
| pub struct MetaPtr { | ||
| ptr: usize, | ||
| } | ||
|
|
||
| #[derive(Copy, Clone, PartialEq)] | ||
| pub enum MetaPermissions { | ||
| Any, | ||
| Read, | ||
| Write, | ||
| ReadWrite, | ||
| Execute, | ||
| } | ||
|
|
||
| impl From<MetaPtr> for usize { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is OK because a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can add that too (it might even exist as a method?), but this one gets used a lot in syscall / return argument handling.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah got it. Does this imply that those arguments or returns should actually be
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its happening a lot because values that are usize, or even eventually u32, are being passed in registers that can hold something as wide as @bradjc has suggested that maybe those should be a separate I suppose, fairly, one could imagine a platform with pointers that are smaller than u32, in which case really RegisterData would wrap around the largest type.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documenting that The fact that some CHERI systems use different registers for integers and capabilities however, does throw a wrench into the works. However, there are two obvious ways that come to mind for how we might choose to handle that at the ABI level:
In both cases, it makes sense to only use [1] libtock-rs just calls this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not convinced
|
||
| #[inline] | ||
| fn from(from: MetaPtr) -> Self { | ||
| from.ptr | ||
| } | ||
| } | ||
|
|
||
| impl From<usize> for MetaPtr { | ||
|
jrvanwhy marked this conversation as resolved.
Outdated
|
||
| #[inline] | ||
| fn from(from: usize) -> Self { | ||
| Self { ptr: from } | ||
| } | ||
| } | ||
|
|
||
| impl UpperHex for MetaPtr { | ||
| #[inline] | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { | ||
| UpperHex::fmt(&self.ptr, f) | ||
| } | ||
| } | ||
|
|
||
| impl LowerHex for MetaPtr { | ||
| #[inline] | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { | ||
| LowerHex::fmt(&self.ptr, f) | ||
| } | ||
| } | ||
|
|
||
| impl AddAssign<usize> for MetaPtr { | ||
|
alevy marked this conversation as resolved.
Outdated
|
||
| #[inline] | ||
| fn add_assign(&mut self, rhs: usize) { | ||
| self.ptr.add_assign(rhs) | ||
| } | ||
| } | ||
|
|
||
| impl MetaPtr { | ||
| pub fn as_ptr(&self) -> *const () { | ||
|
LawrenceEsswood marked this conversation as resolved.
Outdated
|
||
| self.ptr as *const () | ||
| } | ||
|
|
||
| /// Convert to a raw pointer, checking that metadata allows a particular set of permissions over | ||
| /// a given number of bytes. | ||
| /// If the metadata does not allow for this, returns null. | ||
| /// If no such metadata exists, this succeeds. | ||
| #[inline] | ||
| pub fn as_ptr_checked(&self, _length: usize, _perms: MetaPermissions) -> *const () { | ||
| self.ptr as *const () | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn new_with_metadata( | ||
| ptr: *const (), | ||
| _base: usize, | ||
| _length: usize, | ||
| _perms: MetaPermissions, | ||
| ) -> Self { | ||
| Self { ptr: ptr as usize } | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn map_or<U, F>(&self, default: U, f: F) -> U | ||
| where | ||
| F: FnOnce(&Self) -> U, | ||
| { | ||
| if self.ptr == 0usize { | ||
| default | ||
| } else { | ||
| f(self) | ||
| } | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn map_or_else<U, D, F>(&self, default: D, f: F) -> U | ||
| where | ||
| D: FnOnce() -> U, | ||
| F: FnOnce(&Self) -> U, | ||
| { | ||
| let addr: usize = (*self).into(); | ||
|
|
||
| if addr == 0 { | ||
| default() | ||
| } else { | ||
| f(self) | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.