ahci内存越界问题修复+ mm的bug修复+在rust中解析acpi table (#384)

* bugfix: 修复了Flusher Drop的时候没有自动刷新TLB的bug

* 解决进程管理未初始化时,trap.c尝试打印pid导致错误的问题

* 设置kmalloc默认强制清0

* 修复ahci驱动的内存越界问题
* 修复mmio buddy忘记归还buddy block的问题
* 新增acpi模块,暂时能解析acpi tables
This commit is contained in:
LoGin
2023-09-17 15:41:01 +08:00
committed by GitHub
parent 1111099746
commit 7ae679ddd6
19 changed files with 234 additions and 92 deletions

View File

@ -76,16 +76,8 @@ pub unsafe extern "C" fn kmalloc(size: usize, _gfp: gfp_t) -> usize {
return do_kmalloc(size, true);
}
fn do_kmalloc(size: usize, zero: bool) -> usize {
let space: Vec<u8> = if zero {
vec![0u8; size]
} else {
let mut v = Vec::with_capacity(size);
unsafe {
v.set_len(size);
}
v
};
fn do_kmalloc(size: usize, _zero: bool) -> usize {
let space: Vec<u8> = vec![0u8; size];
assert!(space.len() == size);
let (ptr, len, cap) = space.into_raw_parts();
@ -100,7 +92,7 @@ fn do_kmalloc(size: usize, zero: bool) -> usize {
drop(Vec::from_raw_parts(vaddr.data() as *mut u8, len, cap));
}
panic!(
"do_kmalloc: vaddr {:?} already exists in C Allocation Map, query size: {size}, zero: {zero}",
"do_kmalloc: vaddr {:?} already exists in C Allocation Map, query size: {size}, zero: {_zero}",
vaddr
);
}

View File

@ -30,8 +30,8 @@ const PAGE_1G_SIZE: usize = 1 << 30;
static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
pub fn mmio_pool() -> &'static mut MmioBuddyMemPool {
unsafe { __MMIO_POOL.as_mut().unwrap() }
pub fn mmio_pool() -> &'static MmioBuddyMemPool {
unsafe { __MMIO_POOL.as_ref().unwrap() }
}
pub enum MmioResult {
@ -482,7 +482,7 @@ impl MmioBuddyMemPool {
// 计算前导0
#[cfg(target_arch = "x86_64")]
let mut size_exp: u32 = 63 - size.leading_zeros();
// kdebug!("create_mmio: size_exp: {}", size_exp);
// 记录最终申请的空间大小
let mut new_size = size;
// 对齐要申请的空间大小
@ -542,14 +542,26 @@ impl MmioBuddyMemPool {
for i in 0..page_count {
unsafe {
kernel_mapper
let x: Option<(
PhysAddr,
PageFlags<MMArch>,
crate::mm::page::PageFlush<MMArch>,
)> = kernel_mapper
.as_mut()
.unwrap()
.unmap_phys(vaddr + i * MMArch::PAGE_SIZE, true)
.unmap_phys(vaddr + i * MMArch::PAGE_SIZE, false);
if let Some((_, _, flush)) = x {
flush.flush();
}
};
}
// todo: 归还到buddy
// 归还到buddy
mmio_pool()
.give_back_block(vaddr, length.trailing_zeros() as u32)
.unwrap_or_else(|err| {
panic!("MMIO release failed: self: {self:?}, err msg: {:?}", err);
});
return Ok(0);
}
@ -652,29 +664,27 @@ impl MMIOSpaceGuard {
///
/// 传入的物理地址【一定要是设备的物理地址】。
/// 如果物理地址是从内存分配器中分配的那么会造成内存泄露。因为mmio_release的时候只取消映射不会释放内存。
pub unsafe fn map_phys<Arch: MemoryManagementArch>(
&self,
paddr: PhysAddr,
length: usize,
) -> bool {
pub unsafe fn map_phys(&self, paddr: PhysAddr, length: usize) -> Result<(), SystemError> {
if length > self.size {
return false;
return Err(SystemError::EINVAL);
}
let check = self
.mapped
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst);
if check.is_err() {
return false;
return Err(SystemError::EINVAL);
}
let flags = PageFlags::mmio_flags();
let mut kernel_mapper = KernelMapper::lock();
let r = kernel_mapper.map_phys_with_size(self.vaddr, paddr, length, flags, true);
if r.is_err() {
return false;
}
return true;
return r;
}
/// 泄露一个MMIO space guard不会释放映射的空间
pub unsafe fn leak(self) {
core::mem::forget(self);
}
}

View File

@ -803,7 +803,7 @@ impl<Arch, F: Debug> Debug for PageMapper<Arch, F> {
}
/// 页表刷新器的trait
pub trait Flusher<Arch> {
pub trait Flusher<Arch: MemoryManagementArch> {
/// 取消对指定的page flusher的刷新
fn consume(&mut self, flush: PageFlush<Arch>);
}
@ -811,7 +811,7 @@ pub trait Flusher<Arch> {
/// 用于刷新某个虚拟地址的刷新器。这个刷新器一经产生就必须调用flush()方法,
/// 否则会造成对页表的更改被忽略,这是不安全的
#[must_use = "The flusher must call the 'flush()', or the changes to page table will be unsafely ignored."]
pub struct PageFlush<Arch> {
pub struct PageFlush<Arch: MemoryManagementArch> {
virt: VirtAddr,
phantom: PhantomData<Arch>,
}
@ -834,6 +834,14 @@ impl<Arch: MemoryManagementArch> PageFlush<Arch> {
}
}
impl<Arch: MemoryManagementArch> Drop for PageFlush<Arch> {
fn drop(&mut self) {
unsafe {
MMArch::invalidate_page(self.virt);
}
}
}
/// 用于刷新整个页表的刷新器。这个刷新器一经产生就必须调用flush()方法,
/// 否则会造成对页表的更改被忽略,这是不安全的
#[must_use = "The flusher must call the 'flush()', or the changes to page table will be unsafely ignored."]