Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(virtualization): 内核虚拟化支持 #900

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build-scripts/kernel_build/src/cfiles/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ impl CFilesArch for X86_64CFilesArch {
files.push(PathBuf::from("src/arch/x86_64/asm/head.S"));
files.push(PathBuf::from("src/arch/x86_64/asm/entry.S"));
files.push(PathBuf::from("src/arch/x86_64/asm/apu_boot.S"));
files.push(PathBuf::from("src/arch/x86_64/vm/vmx/vmenter.S"));
}

fn setup_global_flags(&self, c: &mut Build) {
Expand Down
36 changes: 36 additions & 0 deletions fixme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
### fixme:
PageLevel的类型
MTRR 是 x86 架构中的一组寄存器,用于控制不同内存区域的缓存属性。通过配置 MTRR,可以优化系统性能和兼容性。操作系统在启动时通常会配置 MTRR,以确保不同内存区域具有适当的缓存属性。

初次EPT_VIOLATION的时候,gpa=0,要建立从gpa到hpa的映射,也就是ept映射,处理完各个寄存器以及mmu等状态后
- do_page_fault 初始化page_fault信息,能知道gfn

- gfn_to_memslot 找到包含 gfn 的 memslot 的指针,放在page_fault.slot里面

- __gfn_to_hva_many 得到hva(照着之前的kvm写的)(要用到page_fault的slot)

- hva_to_pfn 得到pfn,可以说相当于知道了hpa(照着之前的kvm写的),放在 page_fault.pfn里面

找到ept root物理地址 kernel/src/arch/x86_64/mm/mod.rs:184

### 疑问?
- 内核里面应该有相似的多级页表查询/映射的机制,是不是可以借鉴或者复用 kernel/src/mm/page.rs:712 kvm:kernel/src/arch/x86_64/kvm/vmx/ept.rs:91

- 我感觉得到ept root 物理地址(不知道存哪了,可能在真正要)后,按照索引在ept页表往下查,然后缺页就alloc块给它然后加入页表建立映射(gpa->hpa),直到找到目标层的level,[linux实现](https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/kvm/mmu/tdp_mmu.c?fi=kvm_tdp_mmu_map#952)

- __va和virt_2_phys是一样的吗?

- mm.h的作用


### Debug
tdp_page_fault :at src/arch/x86_64/vm/mmu/mmu_internal.rs:233
enter_guest : at src/arch/x86_64/vm/kvm_host/vcpu.rs:840
handle_ept_violation :at src/arch/x86_64/vm/vmx/exit.rs:278
try_handle_exit: at kernel/src/arch/x86_64/vm/vmx/exit.rs:250
vmlaunch : at kernel/src/arch/x86_64/vm/vmx/vmenter.S:103
page fault :kernel/src/arch/x86_64/vm/mmu/mmu_internal.rs:105

kernel/src/mm/kernel_mapper.rs


2 changes: 1 addition & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ debug = true # Controls whether the compiler passes `-g`

# The release profile, used for `cargo build --release`
[profile.release]
debug = false
debug = true
6 changes: 5 additions & 1 deletion kernel/crates/bitmap/src/alloc_bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloc::vec::Vec;

use crate::{bitmap_core::BitMapCore, traits::BitMapOps};

#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct AllocBitmap {
elements: usize,
data: Vec<usize>,
Expand All @@ -18,6 +18,10 @@ impl AllocBitmap {
core: BitMapCore::new(),
}
}

pub fn data(&self) -> &[usize] {
&self.data
}
}

impl BitMapOps<usize> for AllocBitmap {
Expand Down
30 changes: 15 additions & 15 deletions kernel/crates/bitmap/src/bitmap_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::{intrinsics::unlikely, marker::PhantomData};
use crate::traits::BitOps;

#[derive(Debug, Clone)]
pub(crate) struct BitMapCore<T: BitOps> {
pub struct BitMapCore<T: BitOps> {
phantom: PhantomData<T>,
}

Expand All @@ -15,7 +15,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中的某一位
pub(crate) fn get(&self, n: usize, data: &[T], index: usize) -> Option<bool> {
pub fn get(&self, n: usize, data: &[T], index: usize) -> Option<bool> {
if unlikely(index >= n) {
return None;
}
Expand All @@ -30,7 +30,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 设置位图中的某一位
pub(crate) fn set(&self, n: usize, data: &mut [T], index: usize, value: bool) -> Option<bool> {
pub fn set(&self, n: usize, data: &mut [T], index: usize, value: bool) -> Option<bool> {
if unlikely(index >= n) {
return None;
}
Expand All @@ -43,7 +43,7 @@ impl<T: BitOps> BitMapCore<T> {
Some(bit)
}

pub(crate) fn set_all(&self, n: usize, data: &mut [T], value: bool) {
pub fn set_all(&self, n: usize, data: &mut [T], value: bool) {
let val = if value { T::max() } else { T::zero() };
for element in data.iter_mut() {
*element = val;
Expand All @@ -58,7 +58,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中第一个为1的位
pub(crate) fn first_index(&self, data: &[T]) -> Option<usize> {
pub fn first_index(&self, data: &[T]) -> Option<usize> {
for (i, element) in data.iter().enumerate() {
let bit = <T as BitOps>::first_index(element);
if let Some(b) = bit {
Expand All @@ -70,7 +70,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中第一个为0的位
pub(crate) fn first_false_index(&self, n: usize, data: &[T]) -> Option<usize> {
pub fn first_false_index(&self, n: usize, data: &[T]) -> Option<usize> {
for (i, element) in data.iter().enumerate() {
if let Some(bit) = <T as BitOps>::first_false_index(element) {
return self.make_index(n, i * T::bit_size() + bit);
Expand All @@ -81,7 +81,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中最后一个为1的位
pub(crate) fn last_index(&self, n: usize, data: &[T]) -> Option<usize> {
pub fn last_index(&self, n: usize, data: &[T]) -> Option<usize> {
for (i, element) in data.iter().enumerate().rev() {
if let Some(bit) = <T as BitOps>::last_index(element) {
return self.make_index(n, i * T::bit_size() + bit);
Expand All @@ -97,7 +97,7 @@ impl<T: BitOps> BitMapCore<T> {
///
/// - `data`:位图数据
/// - `n`:位图有效位数
pub(crate) fn last_false_index(&self, n: usize, data: &[T]) -> Option<usize> {
pub fn last_false_index(&self, n: usize, data: &[T]) -> Option<usize> {
let mut iter = data.iter().rev();
let mut last_element = *iter.next()?;

Expand All @@ -123,7 +123,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中下一个为1的位
pub(crate) fn next_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
pub fn next_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
if unlikely(index >= n) {
return None;
}
Expand All @@ -146,7 +146,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中下一个为0的位
pub(crate) fn next_false_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
pub fn next_false_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
if unlikely(index >= n) {
return None;
}
Expand All @@ -169,7 +169,7 @@ impl<T: BitOps> BitMapCore<T> {
}

/// 获取位图中上一个为1的位
pub(crate) fn prev_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
pub fn prev_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
if unlikely(index >= n) {
return None;
}
Expand All @@ -190,7 +190,7 @@ impl<T: BitOps> BitMapCore<T> {
None
}

pub(crate) fn prev_false_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
pub fn prev_false_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();

Expand All @@ -208,7 +208,7 @@ impl<T: BitOps> BitMapCore<T> {
None
}

pub(crate) fn invert(&self, n: usize, data: &mut [T]) {
pub fn invert(&self, n: usize, data: &mut [T]) {
for element in data.iter_mut() {
<T as BitOps>::invert(element);
}
Expand All @@ -222,7 +222,7 @@ impl<T: BitOps> BitMapCore<T> {
}
}

pub(crate) fn is_full(&self, n: usize, data: &[T]) -> bool {
pub fn is_full(&self, n: usize, data: &[T]) -> bool {
let mut iter = data.iter().peekable();
while let Some(element) = iter.next() {
if iter.peek().is_none() {
Expand All @@ -245,7 +245,7 @@ impl<T: BitOps> BitMapCore<T> {
return false;
}

pub(crate) fn is_empty(&self, data: &[T]) -> bool {
pub fn is_empty(&self, data: &[T]) -> bool {
for element in data.iter() {
if element != &T::zero() {
return false;
Expand Down
1 change: 1 addition & 0 deletions kernel/crates/bitmap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ mod bitmap_core;
mod static_bitmap;
pub mod traits;
pub use alloc_bitmap::AllocBitmap;
pub use bitmap_core::BitMapCore;
pub use static_bitmap::StaticBitmap;
2 changes: 1 addition & 1 deletion kernel/src/arch/x86_64/kvm/vmx/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ pub fn get_segment_base(gdt_base: *const u64, gdt_size: u16, segment_selector: u
// }
pub fn adjust_vmx_controls(ctl_min: u32, ctl_opt: u32, msr: u32, result: &mut u32) {
let vmx_msr_low: u32 = unsafe { (msr::rdmsr(msr) & 0x0000_0000_FFFF_FFFF) as u32 };
let vmx_msr_high: u32 = unsafe { (msr::rdmsr(msr) << 32) as u32 };
let vmx_msr_high: u32 = unsafe { (msr::rdmsr(msr) >> 32) as u32 };
let mut ctl: u32 = ctl_min | ctl_opt;
ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */
ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */
Expand Down
10 changes: 10 additions & 0 deletions kernel/src/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod sched;
pub mod smp;
pub mod syscall;
pub mod time;
pub mod vm;

pub use self::pci::pci::X86_64PciArch as PciArch;

Expand All @@ -38,3 +39,12 @@ pub use crate::arch::elf::X86_64ElfArch as CurrentElfArch;
pub use crate::arch::smp::X86_64SMPArch as CurrentSMPArch;

pub use crate::arch::sched::X86_64SchedArch as CurrentSchedArch;

pub use crate::arch::vm::KvmArchManager as CurrentKvmManager;

pub use crate::arch::vm::kvm_host::X86KvmArch as KvmArch;

pub use crate::arch::vm::x86_kvm_ops as kvm_arch_ops;

pub use crate::arch::vm::kvm_host::vcpu::X86VcpuArch as VirtCpuArch;
pub use crate::arch::vm::kvm_host::KvmVcpuStat as VirtCpuStat;
Loading