mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-22 11:13:22 +00:00
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:
@ -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
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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."]
|
||||
|
Reference in New Issue
Block a user