WIP: Track grant ownership.

This commit is contained in:
4lDO2
2023-06-20 20:06:34 +02:00
parent e7d94ddff5
commit 490e1b2777
9 changed files with 252 additions and 194 deletions
+5 -3
View File
@@ -62,7 +62,7 @@ impl MemoryScheme {
let page = addr_space
.write()
.mmap((map.address != 0).then_some(span.base), page_count, map.flags, |page, flags, mapper, flusher| {
Ok(Grant::zeroed(page, page_count.get(), flags, mapper, flusher)?)
Ok(Grant::zeroed(span, flags, mapper, flusher)?)
})?;
Ok(page.start_address().data())
@@ -99,8 +99,10 @@ impl MemoryScheme {
Grant::physmap(
Frame::containing_address(PhysicalAddress::new(physical_address)),
dst_page,
page_count.get(),
PageSpan::new(
dst_page,
page_count.get(),
),
page_flags,
dst_mapper,
dst_flusher,
+7 -58
View File
@@ -135,11 +135,6 @@ enum Operation {
// TODO: Remove this once openat is implemented, or allow openat-via-dup via e.g. the top-level
// directory.
OpenViaDup,
// Allows calling fmap directly on a FileDescriptor (as opposed to a FileDescriptor).
//
// TODO: Remove this once cross-scheme links are merged. That would allow acquiring a new
// FD to access the file descriptor behind grants.
GrantHandle { description: Arc<RwLock<FileDescription>> },
SchedAffinity,
Sigactions(Arc<RwLock<Vec<(SigAction, usize)>>>),
@@ -717,28 +712,11 @@ impl KernelScheme for ProcScheme {
let info = self.handles.read().get(&id).ok_or(Error::new(EBADF))?.info.clone();
match info.operation {
Operation::GrantHandle { ref description } => {
// The map struct will probably reside in kernel memory, on the stack, and for that
// it would be very insecure not to use the pinned head/tail buffer.
let mut buf = BorrowedHtBuf::head()?;
// TODO: This can be safe
let map_dst = unsafe { buf.use_for_struct()? };
*map_dst = *map;
let (scheme_id, number) = {
let description = description.read();
(description.scheme, description.number)
};
let scheme = Arc::clone(scheme::schemes().get(scheme_id).ok_or(Error::new(EBADFD))?);
let res = scheme.fmap(number, map_dst);
res
}
Operation::AddrSpace { ref addrspace } => {
if Arc::ptr_eq(addrspace, dst_addr_space) {
return Err(Error::new(EBUSY));
}
/*
// Limit to transferring/borrowing at most one grant, or part of a grant (splitting
// will be mandatory if grants are coalesced).
@@ -780,8 +758,10 @@ impl KernelScheme for ProcScheme {
} else {
dst_addr_space.mmap(requested_dst_page, src_page_count, map.flags, |dst_page, flags, dst_mapper, flusher| Ok(Grant::borrow(src_grant_span.base, dst_page, src_grant_span.count, flags, None, src_mapper, dst_mapper, flusher)?))?
};
*/
Ok(result_page.start_address().data())
//Ok(result_page.start_address().data())
todo!()
}
_ => Err(Error::new(EBADF)),
}
@@ -828,32 +808,6 @@ impl KernelScheme for ProcScheme {
data.offset = VirtualAddress::new(data.offset.data() + bytes_read);
Ok(bytes_read)
},
// TODO: Support reading only a specific address range. Maybe using seek?
Operation::AddrSpace { addrspace } => {
let mut handles = self.handles.write();
let OperationData::Offset(ref mut offset) = handles.get_mut(&id).ok_or(Error::new(EBADF))?.data else {
return Err(Error::new(EBADFD));
};
// TODO: Define a struct somewhere?
const RECORD_SIZE: usize = mem::size_of::<usize>() * 4;
let records = buf.in_exact_chunks(mem::size_of::<usize>()).array_chunks::<4>();
let addrspace = addrspace.read();
let mut bytes_read = 0;
for ([r1, r2, r3, r4], (base, info)) in records.zip(addrspace.grants.iter()).skip(*offset / RECORD_SIZE) {
r1.write_usize(base.start_address().data())?;
r2.write_usize(info.page_count() * PAGE_SIZE)?;
r3.write_usize(map_flags(info.flags()).bits() | if info.desc_opt.is_some() { 0x8000_0000 } else { 0 })?;
r4.write_usize(info.desc_opt.as_ref().map_or(0, |d| d.offset))?;
bytes_read += RECORD_SIZE;
}
*offset += bytes_read;
Ok(bytes_read)
}
Operation::Regs(kind) => {
union Output {
float: FloatRegisters,
@@ -1284,21 +1238,16 @@ impl KernelScheme for ProcScheme {
handle(Operation::Filetable { filetable: new_filetable }, OperationData::Other)
}
Operation::AddrSpace { ref addrspace } => {
let addrspace_clone = Arc::clone(addrspace);
let (operation, is_mem) = match buf {
// 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()? }, false),
b"exclusive" => (Operation::AddrSpace { addrspace: addrspace.write().try_clone()? }, false),
b"exclusive" => (Operation::AddrSpace { addrspace: addrspace.write().try_clone(addrspace_clone)? }, false),
b"mem" => (Operation::Memory { addrspace: Arc::clone(addrspace) }, true),
b"mmap-min-addr" => (Operation::MmapMinAddr(Arc::clone(addrspace)), false),
grant_handle if grant_handle.starts_with(b"grant-") => {
let start_addr = usize::from_str_radix(core::str::from_utf8(&grant_handle[6..]).map_err(|_| Error::new(EINVAL))?, 16).map_err(|_| Error::new(EINVAL))?;
(Operation::GrantHandle {
description: Arc::clone(&addrspace.read().grants.contains(Page::containing_address(VirtualAddress::new(start_addr))).ok_or(Error::new(EINVAL))?.1.desc_opt.as_ref().ok_or(Error::new(EINVAL))?.desc.description)
}, false)
}
_ => return Err(Error::new(EINVAL)),
};
+2 -1
View File
@@ -86,7 +86,8 @@ pub fn resource() -> Result<Vec<u8>> {
}
if let Ok(addr_space) = context.addr_space() {
for (_base, info) in addr_space.read().grants.iter() {
if info.is_owned() {
// TODO: method
if matches!(info.provider, context::memory::Provider::Allocated { .. }) {
memory += info.page_count() * PAGE_SIZE;
}
}
+8 -6
View File
@@ -142,7 +142,7 @@ impl UserInner {
let src_page = Page::containing_address(VirtualAddress::new(tail.buf_mut().as_ptr() as usize));
let dst_page = dst_addr_space.write().mmap(None, ONE, PROT_READ, |dst_page, flags, mapper, flusher| Ok(Grant::borrow(src_page, dst_page, 1, flags, None, &mut KernelMapper::lock(), mapper, flusher)?))?;
let dst_page = dst_addr_space.write().mmap(None, ONE, PROT_READ, |dst_page, flags, mapper, flusher| Ok(Grant::physmap(todo!(), PageSpan::new(dst_page, 1), flags, mapper, flusher)?))?;
Ok(CaptureGuard {
destroyed: false,
@@ -237,7 +237,8 @@ impl UserInner {
let head_buf_page = Page::containing_address(VirtualAddress::new(array.buf_mut().as_mut_ptr() as usize));
dst_space.mmap(Some(free_span.base), ONE, map_flags, move |dst_page, page_flags, mapper, flusher| {
Ok(Grant::borrow(head_buf_page, dst_page, 1, page_flags, None, &mut KernelMapper::lock(), mapper, flusher)?)
//Ok(Grant::borrow(head_buf_page, dst_page, 1, page_flags, None, &mut KernelMapper::lock(), mapper, flusher)?)
todo!()
})?;
let head = CopyInfo {
@@ -261,8 +262,7 @@ impl UserInner {
if let Some(middle_page_count) = NonZeroUsize::new(middle_page_count) {
dst_space.mmap(Some(first_middle_dst_page), middle_page_count, map_flags, move |dst_page, page_flags, mapper, flusher| {
let mut cur_space = cur_space_lock.write();
Ok(Grant::borrow(first_middle_src_page, dst_page, middle_page_count.get(), page_flags, None, &mut cur_space.table.utable, mapper, flusher)?)
Ok(Grant::borrow(Arc::clone(&cur_space_lock), &mut *cur_space_lock.write(), first_middle_src_page, dst_page, middle_page_count.get(), page_flags, mapper, flusher, true)?)
})?;
}
@@ -289,7 +289,8 @@ impl UserInner {
}
dst_space.mmap(Some(tail_dst_page), ONE, map_flags, move |dst_page, page_flags, mapper, flusher| {
Ok(Grant::borrow(tail_buf_page, dst_page, 1, page_flags, None, &mut KernelMapper::lock(), mapper, flusher)?)
todo!();
//Ok(Grant::borrow(tail_buf_page, dst_page, 1, page_flags, None, &mut KernelMapper::lock(), mapper, flusher)?)
})?;
CopyInfo {
@@ -393,7 +394,8 @@ impl UserInner {
let nz_page_count = NonZeroUsize::new(page_count).ok_or(Error::new(EINVAL));
let res = nz_page_count.and_then(|page_count| addr_space.mmap(dst_page, page_count, map.flags, move |dst_page, flags, mapper, flusher| {
Ok(Grant::borrow(src_page, dst_page, page_count.get(), flags, Some(file_ref), &mut AddrSpace::current()?.write().table.utable, mapper, flusher)?)
todo!()
//Ok(Grant::borrow(src_page, dst_page, page_count.get(), flags, Some(file_ref), &mut AddrSpace::current()?.write().table.utable, mapper, flusher)?)
}));
retcode = Error::mux(res.map(|grant_start_page| {
addr_space.grants.funmap.insert(