Skip to content

Commit

Permalink
enter grant before initializing its contents
Browse files Browse the repository at this point in the history
  • Loading branch information
hudson-ayers committed Jul 22, 2022
1 parent 43429fe commit f6adf9d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 25 deletions.
21 changes: 11 additions & 10 deletions kernel/src/grant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,11 @@ impl<'a> EnteredGrantKernelManagedLayout<'a> {
/// time, otherwise multiple mutable references to the same upcall/allow
/// slices could be created.
unsafe fn read_from_base(
base_ptr: *mut u8,
base_ptr: NonNull<u8>,
process: &'a dyn Process,
grant_num: usize,
) -> Self {
let counters_ptr = base_ptr as *mut usize;
let counters_ptr = base_ptr.as_ptr() as *mut usize;
let counters_val = counters_ptr.read();

// Parse the counters field for each of the fields
Expand Down Expand Up @@ -305,14 +305,14 @@ impl<'a> EnteredGrantKernelManagedLayout<'a> {
/// the given `base_ptr` at the same time, otherwise multiple mutable
/// references to the same upcall/allow slices could be created.
unsafe fn initialize_from_counts(
base_ptr: *mut u8,
base_ptr: NonNull<u8>,
upcalls_num_val: UpcallItems,
allow_ro_num_val: AllowRoItems,
allow_rw_num_val: AllowRwItems,
process: &'a dyn Process,
grant_num: usize,
) -> Self {
let counters_ptr = base_ptr as *mut usize;
let counters_ptr = base_ptr.as_ptr() as *mut usize;

// Create the counters usize value by correctly packing the various
// counts into 8 bit fields.
Expand Down Expand Up @@ -381,15 +381,15 @@ impl<'a> EnteredGrantKernelManagedLayout<'a> {
/// least the alignment of T and points to a grant that is of size
/// grant_size bytes.
unsafe fn offset_of_grant_data_t(
base_ptr: *mut u8,
base_ptr: NonNull<u8>,
grant_size: usize,
grant_t_size: GrantDataSize,
) -> NonNull<u8> {
// The location of the grant data T is the last element in the entire
// grant region. Caller must verify that memory is accessible and well
// aligned to T.
let grant_t_size_usize: usize = grant_t_size.0;
NonNull::new_unchecked(base_ptr.add(grant_size - grant_t_size_usize))
NonNull::new_unchecked(base_ptr.as_ptr().add(grant_size - grant_t_size_usize))
}

/// Read an 8 bit value from the counter field offset by the specified
Expand Down Expand Up @@ -1035,10 +1035,11 @@ impl<'a, T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: Allow
);

// Allocate grant, the memory is still uninitialized though.
let grant_ptr = process
.allocate_grant(grant_num, driver_num, alloc_size, alloc_align)
.ok_or(Error::OutOfMemory)?
.as_ptr();
if !process.allocate_grant(grant_num, driver_num, alloc_size, alloc_align) {
return Err(Error::OutOfMemory);
}

let grant_ptr = process.enter_grant(grant_num)?;

// Create a layout from the counts we have and initialize
// all memory so it is valid in the future to read as a
Expand Down
6 changes: 3 additions & 3 deletions kernel/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ pub trait Process {
/// actual app_brk, as MPU alignment and size constraints may result in the
/// MPU enforced region differing from the app_brk.
///
/// This will return `None` and fail if:
/// This will return `false` and fail if:
/// - The process is inactive, or
/// - There is not enough available memory to do the allocation, or
/// - The grant_num is invalid, or
Expand All @@ -464,7 +464,7 @@ pub trait Process {
driver_num: usize,
size: usize,
align: usize,
) -> Option<NonNull<u8>>;
) -> bool;

/// Check if a given grant for this process has been allocated.
///
Expand Down Expand Up @@ -495,7 +495,7 @@ pub trait Process {
/// is invalid, if the grant has not been allocated, or if the grant is
/// already entered. If this returns `Ok()` then the pointer points to the
/// previously allocated memory for this grant.
fn enter_grant(&self, grant_num: usize) -> Result<*mut u8, Error>;
fn enter_grant(&self, grant_num: usize) -> Result<NonNull<u8>, Error>;

/// Enter a custom grant based on the `identifier`.
///
Expand Down
24 changes: 12 additions & 12 deletions kernel/src/process_standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,22 +728,22 @@ impl<C: Chip> Process for ProcessStandard<'_, C> {
driver_num: usize,
size: usize,
align: usize,
) -> Option<NonNull<u8>> {
) -> bool {
// Do not modify an inactive process.
if !self.is_active() {
return None;
return false;
}

// Verify the grant_num is valid.
if grant_num >= self.kernel.get_grant_count_and_finalize() {
return None;
return false;
}

// Verify that the grant is not already allocated. If the pointer is not
// null then the grant is already allocated.
if let Some(is_allocated) = self.grant_is_allocated(grant_num) {
if is_allocated {
return None;
return false;
}
}

Expand All @@ -760,30 +760,30 @@ impl<C: Chip> Process for ProcessStandard<'_, C> {
// If we find a match, then the driver_num must already be used and the
// grant allocation fails.
if exists {
return None;
return false;
}

// Use the shared grant allocator function to actually allocate memory.
// Returns `None` if the allocation cannot be created.
if let Some(grant_ptr) = self.allocate_in_grant_region_internal(size, align) {
// Update the grant pointer to the address of the new allocation.
self.grant_pointers.map_or(None, |grant_pointers| {
self.grant_pointers.map_or(false, |grant_pointers| {
// Implement `grant_pointers[grant_num] = grant_ptr` without a
// chance of a panic.
grant_pointers
.get_mut(grant_num)
.map_or(None, |grant_entry| {
.map_or(false, |grant_entry| {
// Actually set the driver num and grant pointer.
grant_entry.driver_num = driver_num;
grant_entry.grant_ptr = grant_ptr.as_ptr() as *mut u8;

// If all of this worked, return the allocated pointer.
Some(grant_ptr)
// If all of this worked, return true.
true
})
})
} else {
// Could not allocate the memory for the grant region.
None
false
}
}

Expand Down Expand Up @@ -811,7 +811,7 @@ impl<C: Chip> Process for ProcessStandard<'_, C> {
}
}

fn enter_grant(&self, grant_num: usize) -> Result<*mut u8, Error> {
fn enter_grant(&self, grant_num: usize) -> Result<NonNull<u8>, Error> {
// Do not try to access the grant region of inactive process.
if !self.is_active() {
return Err(Error::InactiveApp);
Expand Down Expand Up @@ -843,7 +843,7 @@ impl<C: Chip> Process for ProcessStandard<'_, C> {

// And we return the grant pointer to the entered
// grant.
Ok(grant_ptr)
Ok(unsafe { NonNull::new_unchecked(grant_ptr) })
}
}
None => Err(Error::AddressOutOfBounds),
Expand Down

0 comments on commit f6adf9d

Please sign in to comment.