Refactor: wrap RwLock<AddrSpace>.
This commit is contained in:
@@ -234,13 +234,13 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
.map_or(true, |prev_space| !Arc::ptr_eq(prev_space, next_space))
|
||||
{
|
||||
if let Some(ref prev_space) = prev.addr_space {
|
||||
prev_space.read().used_by.atomic_clear(this_cpu);
|
||||
prev_space.inner.read().used_by.atomic_clear(this_cpu);
|
||||
}
|
||||
// This lock needs to be held, because if the address space is write-locked by some
|
||||
// context that is e.g. unmapping memory, we either need to switch after its
|
||||
// changes have been made, or it needs to know this context is potentially using
|
||||
// this address space, at that time.
|
||||
let next_space = next_space.read();
|
||||
let next_space = next_space.inner.read();
|
||||
|
||||
next_space.used_by.atomic_set(this_cpu);
|
||||
next_space.table.utable.make_current();
|
||||
@@ -250,7 +250,7 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
// The next context is kernel-only, so switch to the page table without any user
|
||||
// mappings.
|
||||
if let Some(ref prev_space) = prev.addr_space {
|
||||
prev_space.read().used_by.atomic_clear(this_cpu);
|
||||
prev_space.inner.read().used_by.atomic_clear(this_cpu);
|
||||
}
|
||||
RmmA::set_table(TableKind::User, empty_cr3());
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::syscall::{
|
||||
/// Unique identifier for a context (i.e. `pid`).
|
||||
use ::core::sync::atomic::AtomicUsize;
|
||||
|
||||
use super::memory::GrantFileRef;
|
||||
use super::memory::{GrantFileRef, AddrSpaceWrapper};
|
||||
int_like!(ContextId, AtomicContextId, usize, AtomicUsize);
|
||||
|
||||
/// The status of a context - used for scheduling
|
||||
@@ -198,7 +198,7 @@ pub struct Context {
|
||||
/// but can be None while the context is being reaped or when a new context is created but has
|
||||
/// not yet had its address space changed. Note that these are only for user mappings; kernel
|
||||
/// mappings are universal and independent on address spaces or contexts.
|
||||
pub addr_space: Option<Arc<RwLock<AddrSpace>>>,
|
||||
pub addr_space: Option<Arc<AddrSpaceWrapper>>,
|
||||
/// The name of the context
|
||||
// TODO: fixed size ArrayString?
|
||||
pub name: Cow<'static, str>,
|
||||
@@ -392,16 +392,16 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addr_space(&self) -> Result<&Arc<RwLock<AddrSpace>>> {
|
||||
pub fn addr_space(&self) -> Result<&Arc<AddrSpaceWrapper>> {
|
||||
self.addr_space.as_ref().ok_or(Error::new(ESRCH))
|
||||
}
|
||||
pub fn set_addr_space(
|
||||
&mut self,
|
||||
addr_space: Arc<RwLock<AddrSpace>>,
|
||||
) -> Option<Arc<RwLock<AddrSpace>>> {
|
||||
addr_space: Arc<AddrSpaceWrapper>,
|
||||
) -> Option<Arc<AddrSpaceWrapper>> {
|
||||
if self.id == super::context_id() {
|
||||
unsafe {
|
||||
addr_space.read().table.utable.make_current();
|
||||
addr_space.inner.read().table.utable.make_current();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ use core::{iter, mem};
|
||||
use spinning_top::RwSpinlock;
|
||||
|
||||
use super::context::{Context, ContextId};
|
||||
use super::memory::{AddrSpaceWrapper, AddrSpace};
|
||||
use crate::syscall::error::{Error, Result, EAGAIN};
|
||||
|
||||
/// Context list type
|
||||
@@ -107,7 +108,7 @@ impl ContextList {
|
||||
let context_lock = self.new_context()?;
|
||||
{
|
||||
let mut context = context_lock.write();
|
||||
let _ = context.set_addr_space(super::memory::new_addrspace()?);
|
||||
let _ = context.set_addr_space(AddrSpaceWrapper::new()?);
|
||||
|
||||
let mut stack = vec![0; 65_536].into_boxed_slice();
|
||||
let mut offset = stack.len();
|
||||
|
||||
+36
-28
@@ -1,5 +1,5 @@
|
||||
use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
|
||||
use core::{cmp, fmt::Debug, num::NonZeroUsize, sync::atomic::Ordering};
|
||||
use core::{cmp, fmt::Debug, num::NonZeroUsize, sync::atomic::{Ordering, AtomicU32}};
|
||||
use hashbrown::HashMap;
|
||||
use rmm::{Arch as _, PageFlush};
|
||||
use spin::{RwLock, RwLockUpgradableGuard, RwLockWriteGuard};
|
||||
@@ -73,8 +73,18 @@ impl UnmapResult {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_addrspace() -> Result<Arc<RwLock<AddrSpace>>> {
|
||||
Arc::try_new(RwLock::new(AddrSpace::new()?)).map_err(|_| Error::new(ENOMEM))
|
||||
#[derive(Debug)]
|
||||
pub struct AddrSpaceWrapper {
|
||||
pub inner: RwLock<AddrSpace>,
|
||||
pub tlb_ack: AtomicU32,
|
||||
}
|
||||
impl AddrSpaceWrapper {
|
||||
pub fn new() -> Result<Arc<Self>> {
|
||||
Arc::try_new(Self {
|
||||
inner: RwLock::new(AddrSpace::new()?),
|
||||
tlb_ack: AtomicU32::new(0),
|
||||
}).map_err(|_| Error::new(ENOMEM))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -89,20 +99,18 @@ pub struct AddrSpace {
|
||||
pub mmap_min: usize,
|
||||
}
|
||||
impl AddrSpace {
|
||||
pub fn current() -> Result<Arc<RwLock<Self>>> {
|
||||
pub fn current() -> Result<Arc<AddrSpaceWrapper>> {
|
||||
Ok(Arc::clone(super::current()?.read().addr_space()?))
|
||||
}
|
||||
|
||||
/// Attempt to clone an existing address space so that all mappings are copied (CoW).
|
||||
pub fn try_clone(&mut self) -> Result<Arc<RwLock<Self>>> {
|
||||
let mut new = new_addrspace()?;
|
||||
pub fn try_clone(&mut self) -> Result<Arc<AddrSpaceWrapper>> {
|
||||
let mut new_arc = AddrSpaceWrapper::new()?;
|
||||
|
||||
let new_guard = Arc::get_mut(&mut new)
|
||||
.expect("expected new address space Arc not to be aliased")
|
||||
.get_mut();
|
||||
let new = Arc::get_mut(&mut new_arc)
|
||||
.expect("expected new address space Arc not to be aliased");
|
||||
|
||||
let this_mapper = &mut self.table.utable;
|
||||
let new_mapper = &mut new_guard.table.utable;
|
||||
let mut this_flusher = Flusher::with_cpu_set(&mut self.used_by);
|
||||
|
||||
for (grant_base, grant_info) in self.grants.iter() {
|
||||
@@ -127,7 +135,7 @@ impl AddrSpace {
|
||||
base.clone(),
|
||||
PageSpan::new(grant_base, grant_info.page_count),
|
||||
grant_info.flags,
|
||||
new_mapper,
|
||||
&mut new.inner.get_mut().table.utable,
|
||||
&mut NopFlusher,
|
||||
)?,
|
||||
Provider::Allocated {
|
||||
@@ -139,7 +147,7 @@ impl AddrSpace {
|
||||
grant_info.page_count,
|
||||
grant_info.flags,
|
||||
this_mapper,
|
||||
new_mapper,
|
||||
&mut new.inner.get_mut().table.utable,
|
||||
&mut this_flusher,
|
||||
&mut NopFlusher,
|
||||
CopyMappingsMode::Owned {
|
||||
@@ -155,7 +163,7 @@ impl AddrSpace {
|
||||
grant_info.page_count,
|
||||
grant_info.flags,
|
||||
this_mapper,
|
||||
new_mapper,
|
||||
&mut new.inner.get_mut().table.utable,
|
||||
&mut this_flusher,
|
||||
&mut NopFlusher,
|
||||
CopyMappingsMode::Borrowed,
|
||||
@@ -172,16 +180,16 @@ impl AddrSpace {
|
||||
src_base,
|
||||
grant_base,
|
||||
grant_info,
|
||||
new_mapper,
|
||||
&mut new.inner.get_mut().table.utable,
|
||||
&mut NopFlusher,
|
||||
false,
|
||||
)?,
|
||||
Provider::FmapBorrowed { .. } => continue,
|
||||
};
|
||||
|
||||
new_guard.grants.insert(new_grant);
|
||||
new.inner.get_mut().grants.insert(new_grant);
|
||||
}
|
||||
Ok(new)
|
||||
Ok(new_arc)
|
||||
}
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
@@ -912,7 +920,7 @@ pub enum Provider {
|
||||
|
||||
/// The memory is borrowed directly from another address space.
|
||||
External {
|
||||
address_space: Arc<RwLock<AddrSpace>>,
|
||||
address_space: Arc<AddrSpaceWrapper>,
|
||||
src_base: Page,
|
||||
is_pinned_userscheme_borrow: bool,
|
||||
},
|
||||
@@ -1119,7 +1127,7 @@ impl Grant {
|
||||
// XXX: borrow_grant is needed because of the borrow checker (iterator invalidation), maybe
|
||||
// borrow_grant/borrow can be abstracted somehow?
|
||||
pub fn borrow_grant(
|
||||
src_address_space_lock: Arc<RwLock<AddrSpace>>,
|
||||
src_address_space_lock: Arc<AddrSpaceWrapper>,
|
||||
src_base: Page,
|
||||
dst_base: Page,
|
||||
src_info: &GrantInfo,
|
||||
@@ -1258,7 +1266,7 @@ impl Grant {
|
||||
/// the page tables of the source pages, but once present in the destination address space,
|
||||
/// pages that are unmaped or moved will not be made visible to the destination address space.
|
||||
pub fn borrow(
|
||||
src_address_space_lock: Arc<RwLock<AddrSpace>>,
|
||||
src_address_space_lock: Arc<AddrSpaceWrapper>,
|
||||
src_address_space: &mut AddrSpace,
|
||||
src_base: Page,
|
||||
dst_base: Page,
|
||||
@@ -1555,7 +1563,7 @@ impl Grant {
|
||||
..
|
||||
} = self.info.provider
|
||||
{
|
||||
let mut guard = address_space.write();
|
||||
let mut guard = address_space.inner.write();
|
||||
|
||||
for (_, grant) in guard
|
||||
.grants
|
||||
@@ -2156,14 +2164,14 @@ pub fn try_correcting_page_tables(faulting_page: Page, access: AccessMode) -> Re
|
||||
};
|
||||
|
||||
let lock = &addr_space_lock;
|
||||
let (_, flush, _) = correct_inner(lock, lock.write(), faulting_page, access, 0)?;
|
||||
let (_, flush, _) = correct_inner(lock, lock.inner.write(), faulting_page, access, 0)?;
|
||||
|
||||
flush.flush();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn correct_inner<'l>(
|
||||
addr_space_lock: &'l Arc<RwLock<AddrSpace>>,
|
||||
addr_space_lock: &'l Arc<AddrSpaceWrapper>,
|
||||
mut addr_space_guard: RwLockWriteGuard<'l, AddrSpace>,
|
||||
faulting_page: Page,
|
||||
access: AccessMode,
|
||||
@@ -2274,7 +2282,7 @@ fn correct_inner<'l>(
|
||||
return Err(PfError::NonfatalInternalError);
|
||||
}
|
||||
|
||||
let mut guard = foreign_address_space.upgradeable_read();
|
||||
let mut guard = foreign_address_space.inner.upgradeable_read();
|
||||
let src_page = src_base.next_by(pages_from_grant_start);
|
||||
|
||||
if let Some(_) = guard.grants.contains(src_page) {
|
||||
@@ -2298,7 +2306,7 @@ fn correct_inner<'l>(
|
||||
// FIXME: Can this result in invalid address space state?
|
||||
let ext_addrspace = &foreign_address_space;
|
||||
let (frame, _, _) = {
|
||||
let g = ext_addrspace.write();
|
||||
let g = ext_addrspace.inner.write();
|
||||
correct_inner(
|
||||
ext_addrspace,
|
||||
g,
|
||||
@@ -2308,9 +2316,9 @@ fn correct_inner<'l>(
|
||||
)?
|
||||
};
|
||||
|
||||
addr_space_guard = addr_space_lock.write();
|
||||
addr_space_guard = addr_space_lock.inner.write();
|
||||
addr_space = &mut *addr_space_guard;
|
||||
guard = foreign_address_space.upgradeable_read();
|
||||
guard = foreign_address_space.inner.upgradeable_read();
|
||||
|
||||
frame
|
||||
};
|
||||
@@ -2395,7 +2403,7 @@ fn correct_inner<'l>(
|
||||
.take()
|
||||
.ok_or(PfError::NonfatalInternalError)?;
|
||||
|
||||
addr_space_guard = addr_space_lock.write();
|
||||
addr_space_guard = addr_space_lock.inner.write();
|
||||
addr_space = &mut *addr_space_guard;
|
||||
|
||||
log::info!("Got frame {:?} from external fmap", frame);
|
||||
@@ -2429,7 +2437,7 @@ pub struct BorrowedFmapSource<'a> {
|
||||
pub src_base: Page,
|
||||
pub mode: MmapMode,
|
||||
// TODO: There should be a method that obtains the lock from the guard.
|
||||
pub addr_space_lock: &'a Arc<RwLock<AddrSpace>>,
|
||||
pub addr_space_lock: &'a Arc<AddrSpaceWrapper>,
|
||||
pub addr_space_guard: RwLockWriteGuard<'a, AddrSpace>,
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -244,9 +244,9 @@ pub unsafe fn debugger(target_id: Option<crate::context::ContextId>) {
|
||||
|
||||
// Switch to context page table to ensure syscall debug and stack dump will work
|
||||
if let Some(ref space) = context.addr_space {
|
||||
let was_new = spaces.insert(space.read().table.utable.table().phys().data());
|
||||
RmmA::set_table(TableKind::User, space.read().table.utable.table().phys());
|
||||
check_consistency(&mut space.write(), was_new, &mut tree);
|
||||
let was_new = spaces.insert(space.inner.read().table.utable.table().phys().data());
|
||||
RmmA::set_table(TableKind::User, space.inner.read().table.utable.table().phys());
|
||||
check_consistency(&mut space.inner.write(), was_new, &mut tree);
|
||||
}
|
||||
|
||||
println!("status: {:?}", context.status);
|
||||
@@ -260,7 +260,7 @@ pub unsafe fn debugger(target_id: Option<crate::context::ContextId>) {
|
||||
);
|
||||
}
|
||||
if let Some(ref addr_space) = context.addr_space {
|
||||
let addr_space = addr_space.read();
|
||||
let addr_space = addr_space.inner.read();
|
||||
if !addr_space.grants.is_empty() {
|
||||
println!("grants:");
|
||||
for (base, info) in addr_space.grants.iter() {
|
||||
@@ -285,6 +285,7 @@ pub unsafe fn debugger(target_id: Option<crate::context::ContextId>) {
|
||||
for _ in 0..64 {
|
||||
if context.addr_space.as_ref().map_or(false, |space| {
|
||||
space
|
||||
.inner
|
||||
.read()
|
||||
.table
|
||||
.utable
|
||||
|
||||
@@ -5,7 +5,7 @@ use rmm::PhysicalAddress;
|
||||
use spin::RwLock;
|
||||
|
||||
use crate::{
|
||||
context::memory::{handle_notify_files, AddrSpace, Grant, PageSpan},
|
||||
context::memory::{handle_notify_files, AddrSpace, Grant, PageSpan, AddrSpaceWrapper},
|
||||
memory::{free_frames, used_frames, Frame, PAGE_SIZE},
|
||||
paging::VirtualAddress,
|
||||
};
|
||||
@@ -68,7 +68,7 @@ fn from_raw(raw: u32) -> Option<(HandleTy, MemoryType, HandleFlags)> {
|
||||
|
||||
impl MemoryScheme {
|
||||
pub fn fmap_anonymous(
|
||||
addr_space: &Arc<RwLock<AddrSpace>>,
|
||||
addr_space: &Arc<AddrSpaceWrapper>,
|
||||
map: &Map,
|
||||
is_phys_contiguous: bool,
|
||||
) -> Result<usize> {
|
||||
@@ -83,7 +83,7 @@ impl MemoryScheme {
|
||||
return Err(Error::new(EOPNOTSUPP));
|
||||
}
|
||||
|
||||
let page = addr_space.write().mmap(
|
||||
let page = addr_space.inner.write().mmap(
|
||||
(map.address != 0).then_some(span.base),
|
||||
page_count,
|
||||
map.flags,
|
||||
@@ -132,6 +132,7 @@ impl MemoryScheme {
|
||||
let page_count = NonZeroUsize::new(size.div_ceil(PAGE_SIZE)).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
AddrSpace::current()?
|
||||
.inner
|
||||
.write()
|
||||
.mmap_anywhere(
|
||||
page_count,
|
||||
@@ -234,7 +235,7 @@ impl KernelScheme for MemoryScheme {
|
||||
fn kfmap(
|
||||
&self,
|
||||
id: usize,
|
||||
addr_space: &Arc<RwLock<AddrSpace>>,
|
||||
addr_space: &Arc<AddrSpaceWrapper>,
|
||||
map: &Map,
|
||||
_consume: bool,
|
||||
) -> Result<usize> {
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use syscall::{EventFlags, MunmapFlags, SendFdFlags, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
|
||||
use crate::{
|
||||
context::{file::FileDescription, memory::AddrSpace},
|
||||
context::{file::FileDescription, memory::{AddrSpace, AddrSpaceWrapper}},
|
||||
syscall::{
|
||||
error::*,
|
||||
usercopy::{UserSliceRo, UserSliceWo},
|
||||
@@ -381,7 +381,7 @@ pub trait KernelScheme: Send + Sync + 'static {
|
||||
fn kfmap(
|
||||
&self,
|
||||
number: usize,
|
||||
addr_space: &Arc<RwLock<AddrSpace>>,
|
||||
addr_space: &Arc<AddrSpaceWrapper>,
|
||||
map: &crate::syscall::data::Map,
|
||||
consume: bool,
|
||||
) -> Result<usize> {
|
||||
|
||||
+15
-15
@@ -3,7 +3,7 @@ use crate::{
|
||||
context::{
|
||||
self,
|
||||
file::FileDescriptor,
|
||||
memory::{handle_notify_files, new_addrspace, AddrSpace, Grant, PageSpan},
|
||||
memory::{handle_notify_files, AddrSpace, Grant, PageSpan, AddrSpaceWrapper},
|
||||
Context, ContextId, Status,
|
||||
},
|
||||
memory::PAGE_SIZE,
|
||||
@@ -127,7 +127,7 @@ enum Operation {
|
||||
filetable: Arc<RwLock<Vec<Option<FileDescriptor>>>>,
|
||||
},
|
||||
AddrSpace {
|
||||
addrspace: Arc<RwLock<AddrSpace>>,
|
||||
addrspace: Arc<AddrSpaceWrapper>,
|
||||
},
|
||||
CurrentAddrSpace,
|
||||
|
||||
@@ -135,7 +135,7 @@ enum Operation {
|
||||
// types, is that we would rather want the actual switch to occur when closing, as opposed to
|
||||
// when writing. This is so that we can actually guarantee that no file descriptors are leaked.
|
||||
AwaitingAddrSpaceChange {
|
||||
new: Arc<RwLock<AddrSpace>>,
|
||||
new: Arc<AddrSpaceWrapper>,
|
||||
new_sp: usize,
|
||||
new_ip: usize,
|
||||
},
|
||||
@@ -153,7 +153,7 @@ enum Operation {
|
||||
CurrentSigactions,
|
||||
AwaitingSigactionsChange(Arc<RwLock<Vec<(SigAction, usize)>>>),
|
||||
|
||||
MmapMinAddr(Arc<RwLock<AddrSpace>>),
|
||||
MmapMinAddr(Arc<AddrSpaceWrapper>),
|
||||
}
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
enum Attr {
|
||||
@@ -692,7 +692,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
fn kfmap(
|
||||
&self,
|
||||
id: usize,
|
||||
dst_addr_space: &Arc<RwLock<AddrSpace>>,
|
||||
dst_addr_space: &Arc<AddrSpaceWrapper>,
|
||||
map: &crate::syscall::data::Map,
|
||||
consume: bool,
|
||||
) -> Result<usize> {
|
||||
@@ -717,8 +717,8 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
|
||||
let requested_dst_base = (map.address != 0).then_some(requested_dst_page);
|
||||
|
||||
let mut src_addr_space = addrspace.write();
|
||||
let mut dst_addr_space = dst_addr_space.write();
|
||||
let mut src_addr_space = addrspace.inner.write();
|
||||
let mut dst_addr_space = dst_addr_space.inner.write();
|
||||
|
||||
let src_page_count = NonZeroUsize::new(src_span.count).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
@@ -901,7 +901,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
|
||||
for (dst, (grant_base, grant_info)) in dst
|
||||
.iter_mut()
|
||||
.zip(addrspace.read().grants.iter().skip(orig_offset))
|
||||
.zip(addrspace.inner.read().grants.iter().skip(orig_offset))
|
||||
{
|
||||
*dst = GrantDesc {
|
||||
base: grant_base.start_address().data(),
|
||||
@@ -981,7 +981,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
read_from(buf, &data.buf, &mut data.offset)
|
||||
}
|
||||
Operation::MmapMinAddr(ref addrspace) => {
|
||||
buf.write_usize(addrspace.read().mmap_min)?;
|
||||
buf.write_usize(addrspace.inner.read().mmap_min)?;
|
||||
Ok(mem::size_of::<usize>())
|
||||
}
|
||||
Operation::SchedAffinity => {
|
||||
@@ -1053,7 +1053,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
|
||||
let unpin = false;
|
||||
addrspace
|
||||
.write()
|
||||
.inner.write()
|
||||
.munmap(PageSpan::new(page, page_count), unpin)?;
|
||||
}
|
||||
ADDRSPACE_OP_MPROTECT => {
|
||||
@@ -1062,7 +1062,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
let flags = MapFlags::from_bits(next()??).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
addrspace
|
||||
.write()
|
||||
.inner.write()
|
||||
.mprotect(PageSpan::new(page, page_count), flags)?;
|
||||
}
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
@@ -1304,7 +1304,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
if val % PAGE_SIZE != 0 || val > crate::USER_END_OFFSET {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
addrspace.write().mmap_min = val;
|
||||
addrspace.inner.write().mmap_min = val;
|
||||
Ok(mem::size_of::<usize>())
|
||||
}
|
||||
Operation::SchedAffinity => {
|
||||
@@ -1441,10 +1441,10 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
// TODO: Better way to obtain new empty address spaces, perhaps using SYS_OPEN. But
|
||||
// in that case, what scheme?
|
||||
b"empty" => Operation::AddrSpace {
|
||||
addrspace: new_addrspace()?,
|
||||
addrspace: AddrSpaceWrapper::new()?,
|
||||
},
|
||||
b"exclusive" => Operation::AddrSpace {
|
||||
addrspace: addrspace.write().try_clone()?,
|
||||
addrspace: addrspace.inner.write().try_clone()?,
|
||||
},
|
||||
b"mmap-min-addr" => Operation::MmapMinAddr(Arc::clone(addrspace)),
|
||||
|
||||
@@ -1461,7 +1461,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
let page = Page::containing_address(VirtualAddress::new(page_addr));
|
||||
|
||||
match addrspace
|
||||
.read()
|
||||
.inner.read()
|
||||
.grants
|
||||
.contains(page)
|
||||
.ok_or(Error::new(EINVAL))?
|
||||
|
||||
@@ -32,7 +32,7 @@ pub fn resource() -> Result<Vec<u8>> {
|
||||
// TODO: All user programs must have some grant in order for executable memory to even
|
||||
// exist, but is this a good indicator of whether it is user or kernel?
|
||||
stat_string.push(if let Ok(addr_space) = context.addr_space() {
|
||||
if addr_space.read().grants.is_empty() {
|
||||
if addr_space.inner.read().grants.is_empty() {
|
||||
'K'
|
||||
} else {
|
||||
'U'
|
||||
@@ -84,7 +84,7 @@ pub fn resource() -> Result<Vec<u8>> {
|
||||
memory += kstack.len();
|
||||
}
|
||||
if let Ok(addr_space) = context.addr_space() {
|
||||
for (_base, info) in addr_space.read().grants.iter() {
|
||||
for (_base, info) in addr_space.inner.read().grants.iter() {
|
||||
// TODO: method
|
||||
if matches!(info.provider, context::memory::Provider::Allocated { .. }) {
|
||||
memory += info.page_count() * PAGE_SIZE;
|
||||
|
||||
+11
-9
@@ -24,7 +24,7 @@ use crate::{
|
||||
context::HardBlockedReason,
|
||||
file::{FileDescription, FileDescriptor},
|
||||
memory::{
|
||||
AddrSpace, BorrowedFmapSource, Grant, GrantFileRef, MmapMode, PageSpan, DANGLING,
|
||||
AddrSpace, BorrowedFmapSource, Grant, GrantFileRef, MmapMode, PageSpan, DANGLING, AddrSpaceWrapper,
|
||||
},
|
||||
BorrowedHtBuf, Context, Status,
|
||||
},
|
||||
@@ -242,7 +242,7 @@ impl UserInner {
|
||||
tail.buf_mut()[..buf.len()].copy_from_slice(buf);
|
||||
|
||||
let is_pinned = true;
|
||||
let dst_page = dst_addr_space.write().mmap_anywhere(
|
||||
let dst_page = dst_addr_space.inner.write().mmap_anywhere(
|
||||
ONE,
|
||||
PROT_READ,
|
||||
|dst_page, flags, mapper, flusher| {
|
||||
@@ -342,7 +342,7 @@ impl UserInner {
|
||||
.split_at(core::cmp::min(align_offset, user_buf.len()))
|
||||
.expect("split must succeed");
|
||||
|
||||
let mut dst_space = dst_space_lock.write();
|
||||
let mut dst_space = dst_space_lock.inner.write();
|
||||
|
||||
let free_span = dst_space
|
||||
.grants
|
||||
@@ -434,7 +434,7 @@ impl UserInner {
|
||||
|
||||
Ok(Grant::borrow(
|
||||
Arc::clone(&cur_space_lock),
|
||||
&mut *cur_space_lock.write(),
|
||||
&mut *cur_space_lock.inner.write(),
|
||||
first_middle_src_page,
|
||||
dst_page,
|
||||
middle_page_count.get(),
|
||||
@@ -667,6 +667,7 @@ impl UserInner {
|
||||
let context = context.upgrade().ok_or(Error::new(ESRCH))?;
|
||||
|
||||
let (frame, _) = AddrSpace::current()?
|
||||
.inner
|
||||
.read()
|
||||
.table
|
||||
.utable
|
||||
@@ -736,7 +737,7 @@ impl UserInner {
|
||||
|
||||
fn fmap_inner(
|
||||
&self,
|
||||
dst_addr_space: Arc<RwLock<AddrSpace>>,
|
||||
dst_addr_space: Arc<AddrSpaceWrapper>,
|
||||
file: usize,
|
||||
map: &Map,
|
||||
) -> Result<usize> {
|
||||
@@ -836,7 +837,7 @@ impl UserInner {
|
||||
BorrowedFmapSource {
|
||||
src_base: Page::containing_address(VirtualAddress::new(base_addr)),
|
||||
addr_space_lock,
|
||||
addr_space_guard: addr_space_lock.write(),
|
||||
addr_space_guard: addr_space_lock.inner.write(),
|
||||
mode: if map.flags.contains(MapFlags::MAP_SHARED) {
|
||||
MmapMode::Shared
|
||||
} else {
|
||||
@@ -849,7 +850,7 @@ impl UserInner {
|
||||
|
||||
let page_count_nz = NonZeroUsize::new(page_count).expect("already validated map.size != 0");
|
||||
let mut notify_files = Vec::new();
|
||||
let dst_base = dst_addr_space.write().mmap(
|
||||
let dst_base = dst_addr_space.inner.write().mmap(
|
||||
dst_base,
|
||||
page_count_nz,
|
||||
map.flags,
|
||||
@@ -878,7 +879,7 @@ pub struct CaptureGuard<const READ: bool, const WRITE: bool> {
|
||||
base: usize,
|
||||
len: usize,
|
||||
|
||||
space: Option<Arc<RwLock<AddrSpace>>>,
|
||||
space: Option<Arc<AddrSpaceWrapper>>,
|
||||
|
||||
head: CopyInfo<READ, WRITE>,
|
||||
tail: CopyInfo<READ, WRITE>,
|
||||
@@ -935,6 +936,7 @@ impl<const READ: bool, const WRITE: bool> CaptureGuard<READ, WRITE> {
|
||||
|
||||
let unpin = true;
|
||||
space
|
||||
.inner
|
||||
.write()
|
||||
.munmap(PageSpan::new(first_page, page_count), unpin)?;
|
||||
|
||||
@@ -1160,7 +1162,7 @@ impl KernelScheme for UserScheme {
|
||||
fn kfmap(
|
||||
&self,
|
||||
file: usize,
|
||||
addr_space: &Arc<RwLock<AddrSpace>>,
|
||||
addr_space: &Arc<AddrSpaceWrapper>,
|
||||
map: &Map,
|
||||
_consume: bool,
|
||||
) -> Result<usize> {
|
||||
|
||||
@@ -52,7 +52,7 @@ pub fn virttophys(virtual_address: usize) -> Result<usize> {
|
||||
enforce_root()?;
|
||||
|
||||
let addr_space = Arc::clone(context::current()?.read().addr_space()?);
|
||||
let addr_space = addr_space.read();
|
||||
let addr_space = addr_space.inner.read();
|
||||
|
||||
match addr_space
|
||||
.table
|
||||
|
||||
+2
-2
@@ -433,7 +433,7 @@ pub fn funmap(virtual_address: usize, length: usize) -> Result<usize> {
|
||||
let span = PageSpan::validate_nonempty(VirtualAddress::new(virtual_address), length_aligned)
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
let unpin = false;
|
||||
let notify = addr_space.write().munmap(span, unpin)?;
|
||||
let notify = addr_space.inner.write().munmap(span, unpin)?;
|
||||
|
||||
for map in notify {
|
||||
let _ = map.unmap();
|
||||
@@ -480,7 +480,7 @@ pub fn mremap(
|
||||
let new_page_count = new_size.div_ceil(PAGE_SIZE);
|
||||
let requested_dst_base = Some(new_base).filter(|_| new_address != 0);
|
||||
|
||||
let mut guard = addr_space.write();
|
||||
let mut guard = addr_space.inner.write();
|
||||
|
||||
let base = AddrSpace::r#move(
|
||||
&mut *guard,
|
||||
|
||||
@@ -53,7 +53,7 @@ pub fn futex(addr: usize, op: usize, val: usize, val2: usize, addr2: usize) -> R
|
||||
|
||||
// Keep the address space locked so we can safely read from the physical address. Unlock it
|
||||
// before context switching.
|
||||
let addr_space_guard = addr_space_lock.read();
|
||||
let addr_space_guard = addr_space_lock.inner.read();
|
||||
|
||||
let target_physaddr =
|
||||
validate_and_translate_virt(&*addr_space_guard, VirtualAddress::new(addr))
|
||||
|
||||
@@ -261,6 +261,7 @@ pub fn mprotect(address: usize, size: usize, flags: MapFlags) -> Result<usize> {
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
AddrSpace::current()?
|
||||
.inner
|
||||
.write()
|
||||
.mprotect(span, flags)
|
||||
.map(|()| 0)
|
||||
@@ -590,7 +591,7 @@ pub unsafe fn usermode_bootstrap(bootstrap: &Bootstrap) -> ! {
|
||||
let page_count = NonZeroUsize::new(bootstrap.page_count)
|
||||
.expect("bootstrap contained no pages!");
|
||||
|
||||
let _base_page = addr_space.write().mmap(Some(base), page_count, flags, &mut Vec::new(), |page, flags, mapper, flusher| {
|
||||
let _base_page = addr_space.inner.write().mmap(Some(base), page_count, flags, &mut Vec::new(), |page, flags, mapper, flusher| {
|
||||
let shared = false;
|
||||
Ok(Grant::zeroed(PageSpan::new(page, bootstrap.page_count), flags, mapper, flusher, shared)?)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user