Allocate kernel stacks using the frame allocator.

This commit is contained in:
4lDO2
2024-03-25 16:31:16 +01:00
parent 9253e16240
commit c17279f5bf
3 changed files with 51 additions and 13 deletions
+1 -1
View File
@@ -148,7 +148,7 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
let pcr = crate::gdt::pcr();
if let Some(ref stack) = next.kstack {
crate::gdt::set_tss_stack(pcr, stack.as_ptr() as usize + stack.len());
crate::gdt::set_tss_stack(pcr, stack.initial_top() as usize);
}
crate::gdt::set_userspace_io_allowed(pcr, next.arch.userspace_io_allowed);
+47 -7
View File
@@ -1,10 +1,10 @@
use alloc::{borrow::Cow, sync::Arc, vec::Vec};
use syscall::{SIGKILL, SIGSTOP};
use core::{cmp::Ordering, mem, num::NonZeroUsize};
use core::{cmp::Ordering, mem::{self, size_of}, num::NonZeroUsize};
use spin::RwLock;
use crate::{
arch::{interrupt::InterruptStack, paging::PAGE_SIZE}, common::aligned_box::AlignedBox, context::{self, arch, file::FileDescriptor, memory::AddrSpace}, cpu_set::{LogicalCpuId, LogicalCpuSet}, ipi::{ipi, IpiKind, IpiTarget}, memory::{Frame, RaiiFrame}, paging::{RmmA, RmmArch}, percpu::PercpuBlock, scheme::{CallerCtx, FileHandle, SchemeNamespace}, sync::WaitMap,
arch::{interrupt::InterruptStack, paging::PAGE_SIZE}, common::aligned_box::AlignedBox, context::{self, arch, file::FileDescriptor, memory::AddrSpace}, cpu_set::{LogicalCpuId, LogicalCpuSet}, ipi::{ipi, IpiKind, IpiTarget}, memory::{allocate_p2frame, deallocate_p2frame, Enomem, Frame, RaiiFrame}, paging::{RmmA, RmmArch}, percpu::PercpuBlock, scheme::{CallerCtx, FileHandle, SchemeNamespace}, sync::WaitMap,
};
use crate::syscall::{
@@ -180,7 +180,7 @@ pub struct Context {
/// Kernel FX - used to store SIMD and FPU registers on context switch
pub kfx: AlignedBox<[u8], { arch::KFX_ALIGN }>,
/// Kernel stack, if located on the heap.
pub kstack: Option<AlignedBox<[u8; arch::KSTACK_SIZE], { arch::KSTACK_ALIGN }>>,
pub kstack: Option<Kstack>,
/// Address space containing a page table lock, and grants. Normally this will have a value,
/// 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
@@ -460,8 +460,7 @@ impl Context {
let Some(ref kstack) = self.kstack else {
return None;
};
let range = kstack.len().checked_sub(mem::size_of::<InterruptStack>())?..;
Some(unsafe { &*kstack.get(range)?.as_ptr().cast() })
Some(unsafe { &*kstack.initial_top().sub(size_of::<InterruptStack>()).cast() })
}
pub fn regs_mut(&mut self) -> Option<&mut InterruptStack> {
if !self.can_access_regs() {
@@ -470,8 +469,7 @@ impl Context {
let Some(ref mut kstack) = self.kstack else {
return None;
};
let range = kstack.len().checked_sub(mem::size_of::<InterruptStack>())?..;
Some(unsafe { &mut *kstack.get_mut(range)?.as_mut_ptr().cast() })
Some(unsafe { &mut *kstack.initial_top().sub(size_of::<InterruptStack>()).cast() })
}
}
@@ -581,3 +579,45 @@ impl Drop for BorrowedHtBuf {
}
}
}
pub struct Kstack {
/// naturally aligned, order 4
base: Frame,
}
impl Kstack {
pub fn new() -> Result<Self, Enomem> {
Ok(Self {
base: allocate_p2frame(4).ok_or(Enomem)?,
})
}
pub fn initial_top(&self) -> *mut u8 {
unsafe {
(RmmA::phys_to_virt(self.base.start_address()).data() as *mut u8).add(PAGE_SIZE << 4)
}
}
pub fn len(&self) -> usize {
PAGE_SIZE << 4
}
}
const _: () = {
if PAGE_SIZE << 4 != arch::KSTACK_SIZE {
panic!();
}
if arch::KSTACK_ALIGN > (PAGE_SIZE << 4) {
panic!();
}
};
impl Drop for Kstack {
fn drop(&mut self) {
unsafe {
deallocate_p2frame(self.base, 4)
}
}
}
impl core::fmt::Debug for Kstack {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "[kstack at {:?}]", self.base)
}
}
+3 -5
View File
@@ -3,10 +3,8 @@ use core::iter;
use spinning_top::RwSpinlock;
use super::arch::KSTACK_SIZE;
use super::context::{Context, ContextId};
use super::context::{Context, ContextId, Kstack};
use super::memory::AddrSpaceWrapper;
use crate::common::aligned_box::AlignedBox;
use crate::interrupt::InterruptStack;
use crate::syscall::error::{Error, Result, EAGAIN};
@@ -108,14 +106,14 @@ impl ContextList {
/// Spawn a context from a function.
pub fn spawn(&mut self, userspace_allowed: bool, func: extern "C" fn()) -> Result<&Arc<RwSpinlock<Context>>> {
let mut stack = AlignedBox::<[u8; crate::context::arch::KSTACK_SIZE], {crate::context::arch::KSTACK_ALIGN}>::try_zeroed()?;
let mut stack = Kstack::new()?;
let context_lock = self.new_context()?;
{
let mut context = context_lock.write();
let _ = context.set_addr_space(Some(AddrSpaceWrapper::new()?));
let mut stack_top = unsafe { stack.as_mut_ptr().add(KSTACK_SIZE) };
let mut stack_top = stack.initial_top();
const INT_REGS_SIZE: usize = core::mem::size_of::<crate::interrupt::InterruptStack>();