Skip to content

Commit 70f159a

Browse files
authored
riscv64: 添加flush tlb的ipi (#636)
* riscv64: 添加flush tlb的ipi * update triagebot
1 parent b4eb05a commit 70f159a

File tree

6 files changed

+148
-10
lines changed

6 files changed

+148
-10
lines changed

kernel/src/arch/riscv64/cpu.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use alloc::vec::Vec;
2+
use sbi_rt::HartMask;
23

34
use crate::{
45
init::boot_params,
@@ -10,6 +11,9 @@ use crate::{
1011
/// 栈对齐
1112
pub(super) const STACK_ALIGN: usize = 16;
1213

14+
/// RISC-V的XLEN,也就是寄存器的位宽
15+
pub const RISCV_XLEN: usize = core::mem::size_of::<usize>() * 8;
16+
1317
/// 获取当前cpu的id
1418
#[inline]
1519
pub fn current_cpu_id() -> ProcessorId {
@@ -21,7 +25,13 @@ pub fn current_cpu_id() -> ProcessorId {
2125

2226
unsafe { (*ptr).current_cpu() }
2327
}
24-
28+
impl Into<HartMask> for ProcessorId {
29+
fn into(self) -> HartMask {
30+
let base = self.data() as usize / RISCV_XLEN;
31+
let offset = self.data() as usize & (RISCV_XLEN - 1);
32+
HartMask::from_mask_base(offset, base)
33+
}
34+
}
2535
/// 重置cpu
2636
pub unsafe fn cpu_reset() -> ! {
2737
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,38 @@
1-
use crate::exception::ipi::{IpiKind, IpiTarget};
1+
use sbi_rt::HartMask;
2+
3+
use crate::{
4+
arch::mm::RiscV64MMArch,
5+
exception::ipi::{IpiKind, IpiTarget},
6+
smp::core::smp_get_processor_id,
7+
};
28

39
#[inline(always)]
410
pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
5-
unimplemented!("RiscV64 send_ipi")
11+
let mask = Into::into(target);
12+
match kind {
13+
IpiKind::KickCpu => todo!(),
14+
IpiKind::FlushTLB => RiscV64MMArch::remote_invalidate_all_with_mask(mask).ok(),
15+
IpiKind::SpecVector(_) => todo!(),
16+
};
17+
}
18+
19+
impl Into<HartMask> for IpiTarget {
20+
fn into(self) -> HartMask {
21+
match self {
22+
IpiTarget::All => HartMask::from_mask_base(usize::MAX, 0),
23+
IpiTarget::Other => {
24+
let data = usize::MAX & (!(1 << smp_get_processor_id().data()));
25+
let mask = HartMask::from_mask_base(data, 0);
26+
mask
27+
}
28+
IpiTarget::Specified(cpu_id) => {
29+
let mask = Into::into(cpu_id);
30+
mask
31+
}
32+
IpiTarget::Current => {
33+
let mask = Into::into(smp_get_processor_id());
34+
mask
35+
}
36+
}
37+
}
638
}

kernel/src/arch/riscv64/mm/mod.rs

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1+
use acpi::address;
12
use riscv::register::satp;
3+
use sbi_rt::{HartMask, SbiRet};
24
use system_error::SystemError;
35

46
use crate::{
57
arch::MMArch,
8+
kdebug,
69
libs::spinlock::SpinLock,
710
mm::{
811
allocator::{
912
buddy::BuddyAllocator,
1013
page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
1114
},
12-
page::PageFlags,
15+
kernel_mapper::KernelMapper,
16+
page::{PageEntry, PageFlags},
17+
ucontext::UserMapper,
1318
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
1419
},
20+
smp::cpu::ProcessorId,
1521
};
1622

1723
use self::init::riscv_mm_init;
@@ -38,7 +44,47 @@ pub struct RiscV64MMArch;
3844

3945
impl RiscV64MMArch {
4046
pub const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
47+
48+
/// 使远程cpu的TLB中,指定地址范围的页失效
49+
pub fn remote_invalidate_page(
50+
cpu: ProcessorId,
51+
address: VirtAddr,
52+
size: usize,
53+
) -> Result<(), SbiRet> {
54+
let r = sbi_rt::remote_sfence_vma(Into::into(cpu), address.data(), size);
55+
if r.is_ok() {
56+
return Ok(());
57+
} else {
58+
return Err(r);
59+
}
60+
}
61+
62+
/// 使指定远程cpu的TLB中,所有范围的页失效
63+
pub fn remote_invalidate_all(cpu: ProcessorId) -> Result<(), SbiRet> {
64+
let r = Self::remote_invalidate_page(
65+
cpu,
66+
VirtAddr::new(0),
67+
1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT,
68+
);
69+
70+
return r;
71+
}
72+
73+
pub fn remote_invalidate_all_with_mask(mask: HartMask) -> Result<(), SbiRet> {
74+
let r = sbi_rt::remote_sfence_vma(mask, 0, 1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT);
75+
if r.is_ok() {
76+
return Ok(());
77+
} else {
78+
return Err(r);
79+
}
80+
}
4181
}
82+
83+
/// 内核空间起始地址在顶层页表中的索引
84+
const KERNEL_TOP_PAGE_ENTRY_NO: usize = (RiscV64MMArch::PHYS_OFFSET
85+
& ((1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT) - 1))
86+
>> (RiscV64MMArch::ENTRY_ADDRESS_SHIFT - RiscV64MMArch::PAGE_ENTRY_SHIFT);
87+
4288
impl MemoryManagementArch for RiscV64MMArch {
4389
const PAGE_SHIFT: usize = 12;
4490

@@ -117,16 +163,35 @@ impl MemoryManagementArch for RiscV64MMArch {
117163
satp::set(satp::Mode::Sv39, 0, ppn);
118164
}
119165

120-
fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool {
166+
fn virt_is_valid(virt: VirtAddr) -> bool {
121167
virt.is_canonical()
122168
}
123169

124-
fn initial_page_table() -> crate::mm::PhysAddr {
170+
fn initial_page_table() -> PhysAddr {
125171
todo!()
126172
}
127173

128-
fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, SystemError> {
129-
todo!()
174+
fn setup_new_usermapper() -> Result<UserMapper, SystemError> {
175+
let new_umapper: crate::mm::page::PageMapper<MMArch, LockedFrameAllocator> = unsafe {
176+
PageMapper::create(PageTableKind::User, LockedFrameAllocator)
177+
.ok_or(SystemError::ENOMEM)?
178+
};
179+
180+
let current_ktable: KernelMapper = KernelMapper::lock();
181+
let copy_mapping = |pml4_entry_no| unsafe {
182+
let entry: PageEntry<RiscV64MMArch> = current_ktable
183+
.table()
184+
.entry(pml4_entry_no)
185+
.unwrap_or_else(|| panic!("entry {} not found", pml4_entry_no));
186+
new_umapper.table().set_entry(pml4_entry_no, entry)
187+
};
188+
189+
// 复制内核的映射
190+
for pml4_entry_no in KERNEL_TOP_PAGE_ENTRY_NO..512 {
191+
copy_mapping(pml4_entry_no);
192+
}
193+
194+
return Ok(crate::mm::ucontext::UserMapper::new(new_umapper));
130195
}
131196

132197
unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> {

kernel/src/mm/percpu.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ const CPU_NUM: AtomicU32 = AtomicU32::new(PerCpu::MAX_CPU_NUM);
2020
pub struct PerCpu;
2121

2222
impl PerCpu {
23+
#[cfg(target_arch = "x86_64")]
2324
pub const MAX_CPU_NUM: u32 = 128;
25+
#[cfg(target_arch = "riscv64")]
26+
pub const MAX_CPU_NUM: u32 = 64;
27+
2428
/// # 初始化PerCpu
2529
///
2630
/// 该函数应该在内核初始化时调用一次。

kernel/src/syscall/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use core::{
66

77
use crate::{
88
arch::{ipc::signal::SigSet, syscall::nr::*},
9-
driver::base::device::device_number::DeviceNumber,
109
filesystem::vfs::syscall::PosixStatx,
1110
libs::{futex::constant::FutexFlag, rand::GRandFlags},
1211
mm::syscall::MremapFlags,
@@ -21,7 +20,6 @@ use crate::{
2120

2221
use num_traits::FromPrimitive;
2322
use system_error::SystemError;
24-
use uefi::proto::debug;
2523

2624
use crate::{
2725
arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch},
@@ -99,6 +97,7 @@ impl Syscall {
9997
Self::open(path, flags, mode, true)
10098
}
10199

100+
#[cfg(target_arch = "x86_64")]
102101
SYS_RENAME => {
103102
let oldname: *const u8 = args[0] as *const u8;
104103
let newname: *const u8 = args[1] as *const u8;
@@ -111,6 +110,7 @@ impl Syscall {
111110
)
112111
}
113112

113+
#[cfg(target_arch = "x86_64")]
114114
SYS_RENAMEAT => {
115115
let oldfd = args[0] as i32;
116116
let oldname: *const u8 = args[1] as *const u8;
@@ -637,6 +637,8 @@ impl Syscall {
637637

638638
#[cfg(target_arch = "x86_64")]
639639
SYS_MKNOD => {
640+
use crate::driver::base::device::device_number::DeviceNumber;
641+
640642
let path = args[0];
641643
let flags = args[1];
642644
let dev_t = args[2];
@@ -715,6 +717,7 @@ impl Syscall {
715717
Self::do_statx(fd, path, flags, mask, kstat)
716718
}
717719

720+
#[cfg(target_arch = "x86_64")]
718721
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
719722
SYS_EPOLL_CREATE1 => Self::epoll_create1(args[0]),
720723

@@ -725,6 +728,7 @@ impl Syscall {
725728
VirtAddr::new(args[3]),
726729
),
727730

731+
#[cfg(target_arch = "x86_64")]
728732
SYS_EPOLL_WAIT => Self::epoll_wait(
729733
args[0] as i32,
730734
VirtAddr::new(args[1]),

triagebot.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ trigger_files = [
7474
"kernel/src/filesystem",
7575
]
7676

77+
[autolabel."O-x86_64"]
78+
trigger_files = [
79+
"kernel/src/arch/x86_64",
80+
]
81+
82+
[autolabel."O-riscv64"]
83+
trigger_files = [
84+
"kernel/src/arch/riscv64",
85+
]
86+
7787
[autolabel."T-driver"]
7888
trigger_files = [
7989
"kernel/src/driver",
@@ -133,6 +143,16 @@ filesystem = [
133143
"@fslongjin"
134144
]
135145

146+
riscv64 = [
147+
"@fslongjin"
148+
]
149+
150+
x86_64 = [
151+
"@fslongjin",
152+
"@GnoCiYeH",
153+
"@Chiichen",
154+
]
155+
136156
# CI/CD
137157
infra-ci = [
138158
"@fslongjin"
@@ -148,3 +168,6 @@ bootstrap = [
148168
"/kernel/src/filesystem" = ["filesystem"]
149169
"/kernel/src/virt" = ["virtulization"]
150170
"/kernel/src/arch/x86_64/kvm" = ["virtulization"]
171+
"/kernel/src/arch/x86_64" = ["x86_64"]
172+
"/kernel/src/arch/riscv64" = ["riscv64"]
173+

0 commit comments

Comments
 (0)