Z Fan 597315b04d
feat(virtualization): 内核虚拟化支持 (#1073)
* 几个结构体

* 通过vmx_init以及create_vm,create_vcpu部分TODO

* kvm_run完成一半

* 能够成功vmlaunch,但是在vmexit时候还有些问题未排查出来

* 解决了vmlaunch导致的cpu_reset的问题

* 整理代码

* 暂时性push到hyc仓库

* 修改内存虚拟化部分参数传入,解决死锁问题

* 初步完成ept映射.但不停EPT_VIOLATION

* 初步完成了EPT映射,但是读写内存还是有点问题

* fixme

* 更新了一些truncate到from_bits_unchecked的实现

* 完成内存虚拟化EPT_VIOLATION的映射

* fmt

* Remove /fixme from .gitignore

* Remove /fixme file

* Update kernel/src/init/init.rs

Co-authored-by: Samuel Dai <samuka007@dragonos.org>

* Update kernel/src/init/init.rs

Co-authored-by: Samuel Dai <samuka007@dragonos.org>

* 修改了注释格式,删除了附带的一些文件操作

* feat(syscall): 实现syscall restart (#1075)

能够在系统调用返回ERESTARTSYS时,信号处理结束后,自动重启系统调用.

TODO: 实现wait等需要restart_block的系统调用的重启

Signed-off-by: longjin <longjin@DragonOS.org>

* chore: update docker image version in script && update doc (#1076)

* chore: update docker image version in script

* chore: replace lots of spaces with newline in doc

* fix: 修复wait4系统调用部分语义与Linux不一致的问题 (#1080)

* fix: 修复wait4系统调用部分语义与Linux不一致的问题

解决wait不住/wait之后卡死的bug

---------

Signed-off-by: longjin <longjin@DragonOS.org>

* feat(fs/syscall): 实现fchdir系统调用 (#1081)

Signed-off-by: longjin <longjin@DragonOS.org>

* fix(mm): 修复fat文件系统的PageCache同步问题 (#1005)


---------

Co-authored-by: longjin <longjin@DragonOS.org>

* fix: 修正nographic启动时,控制台日志未能输出到文件的问题 (#1082)

Signed-off-by: longjin <longjin@DragonOS.org>

* fix(process): 修复copy_process的一些bug & 支持默认init进程传参 (#1083)

- 修复`copy_process`函数对标志位处理不正确的bug
- init进程搜索列表中,支持为默认init程序传入参数

Signed-off-by: longjin <longjin@DragonOS.org>

* feat: 完善sys_reboot (#1084)

* fix(process): 修复copy_process的一些bug & 支持默认init进程传参

- 修复`copy_process`函数对标志位处理不正确的bug
- init进程搜索列表中,支持为默认init程序传入参数

Signed-off-by: longjin <longjin@DragonOS.org>

* feat: 完善sys_reboot

- 校验magic number
- 支持多个cmd (具体内容未实现)

Signed-off-by: longjin <longjin@DragonOS.org>

---------

Signed-off-by: longjin <longjin@DragonOS.org>

* fix: 修复do_wait函数在wait所有子进程时,忘了释放锁就sleep的bug (#1089)

Signed-off-by: longjin <longjin@DragonOS.org>

* pull主线并且fmt

---------

Signed-off-by: longjin <longjin@DragonOS.org>
Co-authored-by: GnoCiYeH <heyicong@dragonos.org>
Co-authored-by: Samuel Dai <samuka007@dragonos.org>
Co-authored-by: LoGin <longjin@DragonOS.org>
Co-authored-by: LIU Yuwei <22045841+Marsman1996@users.noreply.github.com>
Co-authored-by: MemoryShore <1353318529@qq.com>
2025-03-04 10:56:20 +08:00

220 lines
7.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// use crate::{
// arch::vm::mmu::mmu::gfn_round_for_level,
// mm::{virt_2_phys, PhysAddr, VirtAddr},
// time::sleep,
// virt::kvm::host_mem::PAGE_SHIFT,
// };
// use super::{
// mmu::{PageLevel, PAGE_SIZE},
// mmu_internal::KvmMmuPage,
// };
// pub const PT64_ROOT_MAX_LEVEL: usize = 5; //通常只用到4级但是确实有5级的情况
// pub const PT_LEVEL_BITS: u8 = 9; // 每个页表级别的位数
// pub const PT64_ENT_PER_PAGE: u32 = 1 << 9;
// pub const PTE_LEN: usize = 64;
// //Bits 51:12 are from the EPT PDPTE
// pub const PT64_BASE_ADDR_MASK: u64 = ((1u64 << 52) - 1) & !(PAGE_SIZE - 1);
// pub fn shadow_pt_index(addr: u64, level: u8) -> u64 {
// (addr >> (PAGE_SHIFT as u8 + (level - 1) * PT_LEVEL_BITS)) & ((1 << PT_LEVEL_BITS) - 1)
// }
// pub fn is_last_spte(pte: u64, level: u8) -> bool {
// level == PageLevel::Level4K as u8 || is_large_pte(pte)
// }
// pub fn is_shadow_present_pte(pte: u64) -> bool {
// pte & 1 << 11 != 0 //在intel手冊中ept PTE:11 Ignored.不是很懂
// }
// pub fn is_large_pte(pte: u64) -> bool {
// pte & 1 << 7 != 0 //在intel手冊中ept PTE:7 Ignored.
// }
// ///Bits 51:12 are from the EPT PDPTE
// pub fn spte_to_pfn(pte: u64) -> u64 {
// (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT
// }
// #[derive(Default)]
// pub struct TdpIter {
// inner: TdpIterInner,
// }
// impl TdpIter {
// pub fn start(
// &self,
// root_pt: usize,
// root_level: u8,
// min_level: u8,
// next_last_level_gfn: u64,
// ) -> Self {
// let mut inner = self.inner.clone();
// inner.start(root_pt, root_level, min_level, next_last_level_gfn);
// TdpIter { inner }
// }
// }
// ///迭代器将遍历分页结构,直到找到此 GFN 的映射。
// #[derive(Default, Clone)]
// pub struct TdpIterInner {
// next_last_level_gfn: u64,
// /// 线程上次让出时的 next_last_level_gfn。
// /// 仅当 next_last_level_gfn != yielded_gfn 时让出,有助于确保前进。
// pub yielded_gfn: u64,
// ///指向遍历到当前 SPTE 的页表的指针
// pt_path: [u64; PT64_ROOT_MAX_LEVEL],
// ///指向当前 SPTE 的指针 是hva吗
// sptep: PhysAddr,
// /// 当前 SPTE 映射的最低 GFN hpa>>shift?
// pub gfn: u64,
// ///给迭代器的根页级别
// pub root_level: u8,
// ///迭代器应遍历到的最低级别
// pub min_level: u8,
// ///迭代器在分页结构中的当前级别
// pub level: u8,
// ///sptep 处值的快照
// pub old_spte: u64,
// ///迭代器是否具有有效状态。如果迭代器走出分页结构的末端,则为 false。
// ///
// pub valid: bool,
// }
// impl TdpIterInner {
// ///初始化ept iter
// #[inline(never)]
// pub fn start(
// &mut self,
// root_pt: usize,
// root_level: u8,
// min_level: u8,
// next_last_level_gfn: u64,
// ) {
// // if root_pt.role.level() == 0 || root_pt.role.level() > PT64_ROOT_MAX_LEVEL as u32 {
// // self.valid = false;
// // return;
// // }
// if root_level < 1 || root_level > PT64_ROOT_MAX_LEVEL as u8 {
// self.valid = false;
// return;
// }
// self.next_last_level_gfn = next_last_level_gfn;
// self.root_level = root_level as u8;
// self.min_level = min_level as u8;
// self.pt_path[(self.root_level - 1) as usize] = root_pt as u64;
// self.yielded_gfn = self.next_last_level_gfn;
// self.level = self.root_level;
// self.gfn = gfn_round_for_level(self.next_last_level_gfn, self.level);
// self.tdp_iter_refresh_sptep();
// self.valid = true;
// }
// /*
// * 重新计算当前GFN和level和SPTE指针并重新读取SPTE。
// */
// fn tdp_iter_refresh_sptep(&mut self) {
// // self.sptep = PhysAddr::new(
// // (self.pt_path[self.level as usize - 1]
// // + shadow_pt_index(self.gfn << PAGE_SHIFT, self.level)) as usize,
// // );
// // self.old_spte = read_sptep(self.sptep);
// }
// pub fn _next(&mut self) {
// if self.try_step_down() {
// return;
// }
// loop {
// if self.try_step_side() {
// return;
// }
// if !self.try_step_up() {
// break;
// }
// }
// self.valid = false;
// }
// ///在分页结构中向目标GFN下降一级。如果迭代器能够下降一级则返回true否则返回false。
// fn try_step_down(&mut self) -> bool {
// if self.level == self.min_level {
// return false;
// }
// //在下降之前重新读取SPTE以避免遍历到不再从此条目链接的页表中。
// self.old_spte = read_sptep(self.sptep);
// match spte_to_child_pt(self.old_spte, self.level) {
// Some(child_pt) => {
// self.level -= 1;
// self.pt_path[self.level as usize - 1] = child_pt.data() as u64;
// self.gfn = gfn_round_for_level(self.gfn, self.level);
// self.tdp_iter_refresh_sptep();
// true
// }
// None => false,
// }
// }
// fn try_step_up(&mut self) -> bool {
// if self.level == self.root_level {
// return false;
// }
// self.level += 1;
// self.gfn = gfn_round_for_level(self.gfn, self.level);
// self.tdp_iter_refresh_sptep();
// true
// }
// ///在当前页表的当前级别中移动到下一个条目。下一个条目可以指向一个page backing guest memory
// ///或者另一个页表或者它可能是不存在的。如果迭代器能够移动到页表中的下一个条目则返回true
// ///如果迭代器已经在当前页表的末尾则返回false。
// fn try_step_side(&mut self) -> bool {
// //检查迭代器是否已经在当前页表的末尾。
// if shadow_pt_index(self.gfn << PAGE_SHIFT, self.level) == (PT64_ENT_PER_PAGE - 1) as u64 {
// return false;
// }
// self.gfn += PageLevel::kvm_pages_per_hpage(self.level);
// self.next_last_level_gfn = self.gfn;
// self.sptep.add(PTE_LEN); //指向下一个spte一个spte占64位
// self.old_spte = read_sptep(self.sptep);
// true
// }
// }
// impl Iterator for TdpIter {
// type Item = TdpIterInner; // 返回 (gfn, spte) 元组
// fn next(&mut self) -> Option<Self::Item> {
// let inner = &mut self.inner;
// if !inner.valid {
// return None;
// }
// inner._next();
// if inner.valid {
// Some(inner.clone())
// } else {
// None
// }
// }
// }
// ///给定一个 SPTE 及其级别,返回一个指针,该指针包含 SPTE 所引用的子页表的hva。
// ///如果没有这样的条目,则返回 null。
// ///
// fn spte_to_child_pt(spte: u64, level: u8) -> Option<VirtAddr> {
// //没有子页表
// if !is_shadow_present_pte(spte) || is_last_spte(spte, level) {
// return None;
// }
// Some(VirtAddr::new(virt_2_phys//__va
// ((spte_to_pfn(spte)<<PAGE_SHIFT) as usize
// )))
// }
// pub fn read_sptep(sptep: PhysAddr) -> u64 {
// unsafe { *(sptep.data() as *const u64) }
// }