From 67c1075292f033d1c039a77085540c8149ef5964 Mon Sep 17 00:00:00 2001 From: longjin Date: Thu, 21 Mar 2024 13:24:51 +0000 Subject: [PATCH 1/2] =?UTF-8?q?riscv64:=20=E6=B7=BB=E5=8A=A0flush=20tlb?= =?UTF-8?q?=E7=9A=84ipi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/arch/riscv64/cpu.rs | 12 +++- kernel/src/arch/riscv64/interrupt/ipi.rs | 36 +++++++++++- kernel/src/arch/riscv64/mm/mod.rs | 75 ++++++++++++++++++++++-- kernel/src/mm/percpu.rs | 4 ++ kernel/src/syscall/mod.rs | 7 ++- 5 files changed, 125 insertions(+), 9 deletions(-) diff --git a/kernel/src/arch/riscv64/cpu.rs b/kernel/src/arch/riscv64/cpu.rs index cb65b7539..1e07b0ecc 100644 --- a/kernel/src/arch/riscv64/cpu.rs +++ b/kernel/src/arch/riscv64/cpu.rs @@ -1,4 +1,5 @@ use alloc::vec::Vec; +use sbi_rt::HartMask; use crate::{ init::boot_params, @@ -10,6 +11,9 @@ use crate::{ /// 栈对齐 pub(super) const STACK_ALIGN: usize = 16; +/// RISC-V的XLEN,也就是寄存器的位宽 +pub const RISCV_XLEN: usize = core::mem::size_of::() * 8; + /// 获取当前cpu的id #[inline] pub fn current_cpu_id() -> ProcessorId { @@ -21,7 +25,13 @@ pub fn current_cpu_id() -> ProcessorId { unsafe { (*ptr).current_cpu() } } - +impl Into for ProcessorId { + fn into(self) -> HartMask { + let base = self.data() as usize / RISCV_XLEN; + let offset = self.data() as usize & (RISCV_XLEN - 1); + HartMask::from_mask_base(offset, base) + } +} /// 重置cpu pub unsafe fn cpu_reset() -> ! { sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason); diff --git a/kernel/src/arch/riscv64/interrupt/ipi.rs b/kernel/src/arch/riscv64/interrupt/ipi.rs index 962e093cd..cd98302ca 100644 --- a/kernel/src/arch/riscv64/interrupt/ipi.rs +++ b/kernel/src/arch/riscv64/interrupt/ipi.rs @@ -1,6 +1,38 @@ -use crate::exception::ipi::{IpiKind, IpiTarget}; +use sbi_rt::HartMask; + +use crate::{ + arch::mm::RiscV64MMArch, + exception::ipi::{IpiKind, IpiTarget}, + smp::core::smp_get_processor_id, +}; #[inline(always)] pub fn send_ipi(kind: IpiKind, target: IpiTarget) { - unimplemented!("RiscV64 send_ipi") + let mask = Into::into(target); + match kind { + IpiKind::KickCpu => todo!(), + IpiKind::FlushTLB => RiscV64MMArch::remote_invalidate_all_with_mask(mask).ok(), + IpiKind::SpecVector(_) => todo!(), + }; +} + +impl Into for IpiTarget { + fn into(self) -> HartMask { + match self { + IpiTarget::All => HartMask::from_mask_base(usize::MAX, 0), + IpiTarget::Other => { + let data = usize::MAX & (!(1 << smp_get_processor_id().data())); + let mask = HartMask::from_mask_base(data, 0); + mask + } + IpiTarget::Specified(cpu_id) => { + let mask = Into::into(cpu_id); + mask + } + IpiTarget::Current => { + let mask = Into::into(smp_get_processor_id()); + mask + } + } + } } diff --git a/kernel/src/arch/riscv64/mm/mod.rs b/kernel/src/arch/riscv64/mm/mod.rs index 5adc21978..8e2f727af 100644 --- a/kernel/src/arch/riscv64/mm/mod.rs +++ b/kernel/src/arch/riscv64/mm/mod.rs @@ -1,17 +1,23 @@ +use acpi::address; use riscv::register::satp; +use sbi_rt::{HartMask, SbiRet}; use system_error::SystemError; use crate::{ arch::MMArch, + kdebug, libs::spinlock::SpinLock, mm::{ allocator::{ buddy::BuddyAllocator, page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame}, }, - page::PageFlags, + kernel_mapper::KernelMapper, + page::{PageEntry, PageFlags}, + ucontext::UserMapper, MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, }, + smp::cpu::ProcessorId, }; use self::init::riscv_mm_init; @@ -38,7 +44,47 @@ pub struct RiscV64MMArch; impl RiscV64MMArch { pub const ENTRY_FLAG_GLOBAL: usize = 1 << 5; + + /// 使远程cpu的TLB中,指定地址范围的页失效 + pub fn remote_invalidate_page( + cpu: ProcessorId, + address: VirtAddr, + size: usize, + ) -> Result<(), SbiRet> { + let r = sbi_rt::remote_sfence_vma(Into::into(cpu), address.data(), size); + if r.is_ok() { + return Ok(()); + } else { + return Err(r); + } + } + + /// 使指定远程cpu的TLB中,所有范围的页失效 + pub fn remote_invalidate_all(cpu: ProcessorId) -> Result<(), SbiRet> { + let r = Self::remote_invalidate_page( + cpu, + VirtAddr::new(0), + 1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT, + ); + + return r; + } + + pub fn remote_invalidate_all_with_mask(mask: HartMask) -> Result<(), SbiRet> { + let r = sbi_rt::remote_sfence_vma(mask, 0, 1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT); + if r.is_ok() { + return Ok(()); + } else { + return Err(r); + } + } } + +/// 内核空间起始地址在顶层页表中的索引 +const KERNEL_TOP_PAGE_ENTRY_NO: usize = (RiscV64MMArch::PHYS_OFFSET + & ((1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT) - 1)) + >> (RiscV64MMArch::ENTRY_ADDRESS_SHIFT - RiscV64MMArch::PAGE_ENTRY_SHIFT); + impl MemoryManagementArch for RiscV64MMArch { const PAGE_SHIFT: usize = 12; @@ -117,16 +163,35 @@ impl MemoryManagementArch for RiscV64MMArch { satp::set(satp::Mode::Sv39, 0, ppn); } - fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool { + fn virt_is_valid(virt: VirtAddr) -> bool { virt.is_canonical() } - fn initial_page_table() -> crate::mm::PhysAddr { + fn initial_page_table() -> PhysAddr { todo!() } - fn setup_new_usermapper() -> Result { - todo!() + fn setup_new_usermapper() -> Result { + let new_umapper: crate::mm::page::PageMapper = unsafe { + PageMapper::create(PageTableKind::User, LockedFrameAllocator) + .ok_or(SystemError::ENOMEM)? + }; + + let current_ktable: KernelMapper = KernelMapper::lock(); + let copy_mapping = |pml4_entry_no| unsafe { + let entry: PageEntry = current_ktable + .table() + .entry(pml4_entry_no) + .unwrap_or_else(|| panic!("entry {} not found", pml4_entry_no)); + new_umapper.table().set_entry(pml4_entry_no, entry) + }; + + // 复制内核的映射 + for pml4_entry_no in KERNEL_TOP_PAGE_ENTRY_NO..512 { + copy_mapping(pml4_entry_no); + } + + return Ok(crate::mm::ucontext::UserMapper::new(new_umapper)); } unsafe fn phys_2_virt(phys: PhysAddr) -> Option { diff --git a/kernel/src/mm/percpu.rs b/kernel/src/mm/percpu.rs index e3d63d62a..1f7766c16 100644 --- a/kernel/src/mm/percpu.rs +++ b/kernel/src/mm/percpu.rs @@ -20,7 +20,11 @@ const CPU_NUM: AtomicU32 = AtomicU32::new(PerCpu::MAX_CPU_NUM); pub struct PerCpu; impl PerCpu { + #[cfg(target_arch = "x86_64")] pub const MAX_CPU_NUM: u32 = 128; + #[cfg(target_arch = "riscv64")] + pub const MAX_CPU_NUM: u32 = 64; + /// # 初始化PerCpu /// /// 该函数应该在内核初始化时调用一次。 diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 1396d3b48..3d55dffc5 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -6,7 +6,6 @@ use core::{ use crate::{ arch::{ipc::signal::SigSet, syscall::nr::*}, - driver::base::device::device_number::DeviceNumber, libs::{futex::constant::FutexFlag, rand::GRandFlags}, mm::syscall::MremapFlags, net::syscall::MsgHdr, @@ -97,6 +96,7 @@ impl Syscall { Self::open(path, flags, mode, true) } + #[cfg(target_arch = "x86_64")] SYS_RENAME => { let oldname: *const u8 = args[0] as *const u8; let newname: *const u8 = args[1] as *const u8; @@ -109,6 +109,7 @@ impl Syscall { ) } + #[cfg(target_arch = "x86_64")] SYS_RENAMEAT => { let oldfd = args[0] as i32; let oldname: *const u8 = args[1] as *const u8; @@ -635,6 +636,8 @@ impl Syscall { #[cfg(target_arch = "x86_64")] SYS_MKNOD => { + use crate::driver::base::device::device_number::DeviceNumber; + let path = args[0]; let flags = args[1]; let dev_t = args[2]; @@ -703,6 +706,7 @@ impl Syscall { Self::stat(path, kstat) } + #[cfg(target_arch = "x86_64")] SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32), SYS_EPOLL_CREATE1 => Self::epoll_create1(args[0]), @@ -713,6 +717,7 @@ impl Syscall { VirtAddr::new(args[3]), ), + #[cfg(target_arch = "x86_64")] SYS_EPOLL_WAIT => Self::epoll_wait( args[0] as i32, VirtAddr::new(args[1]), From 6089593e6a924db7af1be33d993378df487c7410 Mon Sep 17 00:00:00 2001 From: longjin Date: Thu, 21 Mar 2024 13:34:13 +0000 Subject: [PATCH 2/2] update triagebot --- triagebot.toml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index ade91b5b5..19b04d073 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -74,6 +74,16 @@ trigger_files = [ "kernel/src/filesystem", ] +[autolabel."O-x86_64"] +trigger_files = [ + "kernel/src/arch/x86_64", +] + +[autolabel."O-riscv64"] +trigger_files = [ + "kernel/src/arch/riscv64", +] + [autolabel."T-driver"] trigger_files = [ "kernel/src/driver", @@ -133,6 +143,16 @@ filesystem = [ "@fslongjin" ] +riscv64 = [ + "@fslongjin" +] + +x86_64 = [ + "@fslongjin", + "@GnoCiYeH", + "@Chiichen", +] + # CI/CD infra-ci = [ "@fslongjin" @@ -148,3 +168,6 @@ bootstrap = [ "/kernel/src/filesystem" = ["filesystem"] "/kernel/src/virt" = ["virtulization"] "/kernel/src/arch/x86_64/kvm" = ["virtulization"] +"/kernel/src/arch/x86_64" = ["x86_64"] +"/kernel/src/arch/riscv64" = ["riscv64"] +