-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Documentation for zone config, hvisor structure, percpu struct, a…
…nd ARM-GIC (#15)
- Loading branch information
1 parent
25058c2
commit 8fec6d6
Showing
8 changed files
with
208 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Zone的配置和管理 | ||
|
||
hvisor项目作为一款轻量级的hypervisor,它使用了Type-1架构,允许在硬件之上直接运行多个虚拟机(zones)。下面是对zone配置和管理的关键点的详细说明: | ||
|
||
## 资源分配 | ||
|
||
资源如CPU、内存、设备和中断对每个zone都是静态分配的,这意味着一旦分配,这些资源就不会在zones之间动态调度。 | ||
|
||
## Root Zone配置 | ||
|
||
根zone的配置是硬编码在hvisor内部的,以Rust语言编写,并表现为一个C风格的结构体HvZoneConfig。这个结构体包含了zone ID、CPU数量、内存区域、中断信息、内核和设备树二进制(DTB)的物理地址与大小等关键信息。 | ||
|
||
## Non-root Zones配置 | ||
|
||
非root zones的配置则存储在root linux的文件系统中,通常以JSON格式表示。例如: | ||
|
||
```json | ||
{ | ||
"arch": "arm64", | ||
"zone_id": 1, | ||
"cpus": [2, 3], | ||
"memory_regions": [ | ||
{ | ||
"type": "ram", | ||
"physical_start": "0x50000000", | ||
"virtual_start": "0x50000000", | ||
"size": "0x30000000" | ||
}, | ||
{ | ||
"type": "io", | ||
"physical_start": "0x30a60000", | ||
"virtual_start": "0x30a60000", | ||
"size": "0x1000" | ||
}, | ||
{ | ||
"type": "virtio", | ||
"physical_start": "0xa003c00", | ||
"virtual_start": "0xa003c00", | ||
"size": "0x200" | ||
} | ||
], | ||
"interrupts": [61, 75, 76, 78], | ||
"kernel_filepath": "./Image", | ||
"dtb_filepath": "./linux2.dtb", | ||
"kernel_load_paddr": "0x50400000", | ||
"dtb_load_paddr": "0x50000000", | ||
"entry_point": "0x50400000" | ||
} | ||
``` | ||
|
||
- `arch`字段指定了目标架构(例如arm64)。 | ||
- `cpus`是一个列表,指明了分配给该zone的CPU核心ID。 | ||
- `memory_regions`描述了不同类型的内存区域及其物理和虚拟起始地址与大小。 | ||
- `interrupts`列出了分配给zone的中断号。 | ||
- `kernel_filepath`和`dtb_filepath`分别指明了内核和设备树二进制文件的路径。 | ||
- `kernel_load_paddr`和`dtb_load_paddr`则是内核和设备树二进制在物理内存中的加载地址。 | ||
- `entry_point`指定了内核的入口点地址。 | ||
|
||
root linux的管理工具负责读取JSON配置文件并将其转换为C风格的结构体,随后传递给hvisor以启动非root zones。 |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# hvisor总体架构 | ||
|
||
- CPU虚拟化 | ||
- 架构兼容性:支持aarch64, riscv64, 和loongarch等架构,每种架构有专门的CPU虚拟化组件。 | ||
- CPU分配:采用静态分配方式,预先决定每个虚拟机的CPU资源。 | ||
|
||
- 内存虚拟化 | ||
- 二阶段页表:利用二阶段页表技术,优化内存虚拟化过程。 | ||
|
||
- 中断虚拟化 | ||
- 中断控制器虚拟化:支持ARM GIC、RISC-V PLIC等不同架构的中断控制器虚拟化。 | ||
- 中断处理:管理中断信号的传递和处理流程。 | ||
|
||
- I/O虚拟化 | ||
- IOMMU集成:支持IOMMU,增强DMA虚拟化的效率和安全性。 | ||
- VirtIO标准:遵循VirtIO规范,提供高性能的虚拟设备。 | ||
- PCI虚拟化:实现PCI虚拟化,确保虚拟机可以访问物理或虚拟I/O设备。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# AArch64下的CPU虚拟化 | ||
|
||
## CPU启动机制 | ||
|
||
在AArch64架构下,hvisor利用`psci::cpu_on()`函数唤醒指定的CPU核心,将其从关闭状态带入运行状态。该函数接收CPU的ID、启动地址以及一个不透明参数作为输入。遇到错误时,如CPU已处于唤醒状态,函数会进行适当的错误处理避免重复唤醒。 | ||
|
||
## CPU虚拟化初始化与运行 | ||
|
||
`ArchCpu`结构体封装了特定于架构的CPU信息和功能,其`reset()`方法负责将CPU设置为虚拟化模式的初始状态。这包括: | ||
|
||
- 设置ELR_EL2寄存器至指定的入口点 | ||
- 配置SPSR_EL2寄存器 | ||
- 清空通用寄存器 | ||
- 重置虚拟机相关寄存器 | ||
- `activate_vmm()`,激活虚拟内存管理器(VMM) | ||
|
||
`activate_vmm()`方法用于配置VTCR_EL2和HCR_EL2寄存器,启用虚拟化环境。 | ||
|
||
`ArchCpu`的`run()`和`idle()`方法分别用于启动和闲置CPU。启动时,激活zone的GPM(Guest Page Management),重置到指定的入口点和设备树二进制(DTB)地址,然后通过`vmreturn`宏跳转到EL2入口点。在闲置模式下,CPU被重置到等待状态(WFI),并准备`parking`指令页面以供闲置期间使用。 | ||
|
||
## EL1与EL2之间的切换 | ||
|
||
hvisor在AArch64架构中使用EL2作为hypervisor模式,而EL1用于guest OS。`handle_vmexit`宏处理从EL1到EL2的上下文切换(VMEXIT事件),保存用户模式寄存器上下文,调用外部函数处理退出原因,之后返回到hypervisor代码段继续执行。`vmreturn`函数用于从EL2模式回到EL1模式(VMENTRY事件),恢复用户模式寄存器上下文后,通过`eret`指令返回到guest OS的代码段。 | ||
|
||
## MMU配置与启用 | ||
|
||
为了支持虚拟化,`enable_mmu()`函数在EL2模式下配置MMU映射,包括设置MAIR_EL2、TCR_EL2和SCTLR_EL2寄存器,允许指令和数据缓存能力,并确保虚拟范围覆盖整个48位地址空间。 | ||
|
||
通过这些机制,hvisor在AArch64架构上实现了高效的CPU虚拟化,允许多个独立的zones在静态分配的资源下运行,同时保持系统稳定性和性能。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
|
||
# PerCPU结构体 | ||
|
||
在hvisor的架构中,PerCpu结构体扮演着核心角色,用于实现每个CPU核心的本地状态管理以及支持CPU虚拟化。下面是对PerCpu结构体及相关函数的详细介绍: | ||
|
||
## PerCpu结构体定义 | ||
|
||
PerCpu结构体被设计为每个CPU核心存储其特定数据和状态的容器。它的布局如下: | ||
|
||
``` | ||
#[repr(C)] | ||
pub struct PerCpu { | ||
pub id: usize, | ||
pub cpu_on_entry: usize, | ||
pub dtb_ipa: usize, | ||
pub arch_cpu: ArchCpu, | ||
pub zone: Option<Arc<RwLock<Zone>>>, | ||
pub ctrl_lock: Mutex<()>, | ||
pub boot_cpu: bool, | ||
// percpu stack | ||
} | ||
``` | ||
|
||
各字段定义如下: | ||
|
||
``` | ||
id: CPU核心的标识符。 | ||
cpu_on_entry: 一个用于追踪CPU进入状态的地址,初始化为INVALID_ADDRESS,表示无效地址。 | ||
dtb_ipa: 设备树二进制的物理地址,同样初始化为INVALID_ADDRESS。 | ||
arch_cpu: 一个指向ArchCpu类型的引用,ArchCpu包含特定于架构的CPU信息和功能。 | ||
zone: 一个可选的Arc<RwLock<Zone>>类型,表示当前CPU核心正在运行的虚拟机(zone)。 | ||
ctrl_lock: 一个互斥锁,用于控制访问和同步PerCpu的数据。 | ||
boot_cpu: 一个布尔值,指示是否为引导CPU。 | ||
``` | ||
|
||
## PerCpu的构造和操作 | ||
|
||
``` | ||
PerCpu::new: 此函数创建并初始化PerCpu结构体。它首先计算结构体的虚拟地址,然后安全地写入初始化数据。对于RISC-V架构,还会更新CSR_SSCRATCH寄存器来存储ArchCpu的指针。 | ||
run_vm: 当调用此方法时,如果当前CPU不是引导CPU,则会先将其置于空闲状态,然后再运行虚拟机。 | ||
entered_cpus: 返回已进入虚拟机运行状态的CPU核心数。 | ||
activate_gpm: 激活所关联zone的GPM(Guest Page Management)。 | ||
``` | ||
|
||
## 获取PerCpu实例 | ||
|
||
``` | ||
get_cpu_data: 提供基于CPU ID获取PerCpu实例的方法。 | ||
this_cpu_data: 返回当前执行CPU的PerCpu实例。 | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# ARM GICv3模块 | ||
|
||
## 1. GICv3模块 | ||
|
||
### GICv3初始化流程 | ||
|
||
hvisor中的GICv3初始化流程涉及了GIC分布控制器(GICD)和GIC重新分布控制器(GICR)的初始化,以及中断处理和虚拟中断注入的机制。这一过程的关键步骤: | ||
|
||
- SDEI版本检查:通过smc_arg1!(0xc4000020)获取Secure Debug Extensions Interface (SDEI)的版本信息。 | ||
- ICCs配置:设置icc_ctlr_el1以仅提供优先级下降功能,设置icc_pmr_el1以定义中断优先级掩码,使能Group 1 IRQs。 | ||
- 清除待处理中断:调用gicv3_clear_pending_irqs函数,清除所有待处理的中断,确保系统处于干净状态。 | ||
- VMCR和HCR配置:设置ich_vmcr_el2和ich_hcr_el2寄存器,使能虚拟化CPU接口,准备虚拟中断处理。 | ||
|
||
### 待处理中断处理 | ||
|
||
- `pending_irq`函数读取`icc_iar1_el1`寄存器,返回当前正在处理的中断ID,若值大于等于0x3fe则视为无效中断。 | ||
- `deactivate_irq`函数通过写入`icc_eoir1_el1`和`icc_dir_el1`寄存器来清除中断标志,使能中断。 | ||
|
||
### 虚拟中断注入 | ||
|
||
- `inject_irq`函数检查是否有可用的`List Register (LR)`,并将虚拟中断信息写入其中。此函数区分硬件中断和软件生成中断,适当设置LR中的字段。 | ||
|
||
### GIC数据结构初始化 | ||
|
||
- GIC是一个全局的Once容器,用于延迟初始化Gic结构体,其中包含了GICD和GICR的基地址及其大小。 | ||
- primary_init_early和primary_init_late函数分别在早期和后期初始化阶段配置GIC,使能中断。 | ||
|
||
### 区域(Zone)级别的初始化 | ||
|
||
在Zone结构体中,`arch_irqchip_reset`方法负责重置分配给特定zone的所有中断,通过直接写入GICD的ICENABLER和ICACTIVER寄存器来实现。 | ||
|
||
## 2. vGICv3模块 | ||
|
||
hvisor的VGICv3(Virtual Generic Interrupt Controller version 3)模块提供了对ARMv8-A架构中GICv3的虚拟化支持。它通过MMIO(Memory Mapped I/O)访问和中断比特图管理来控制和协调不同zone(虚拟机实例)间的中断请求。 | ||
|
||
### MMIO区域注册 | ||
|
||
在初始化阶段,`Zone`结构体的`vgicv3_mmio_init`方法注册了GIC分布控制器(GICD)和每个CPU的GIC重新分布控制器(GICR)的MMIO区域。MMIO区域注册是通过`mmio_region_register`函数完成的,该函数关联了特定的处理器或中断控制器地址,以及相应的处理函数`vgicv3_dist_handler`和`vgicv3_redist_handler`。 | ||
|
||
### 中断比特图初始化 | ||
|
||
`Zone`结构体的`irq_bitmap_init`方法用于初始化中断比特图,这是为了跟踪哪些中断属于当前`zone`。通过遍历提供的中断列表,每个中断都会被插入到比特图中。`insert_irq_to_bitmap`函数负责将特定的中断号映射到比特图中的相应位置。 | ||
MMIO访问限制 | ||
|
||
`restrict_bitmask_access`函数用于限制对`GICD`寄存器的`MMIO`访问,确保只有属于当前`zone`的中断才能被修改。该函数检查访问是否针对当前zone的中断,如果是,则更新访问掩码,以允许或限制特定的读写操作。 | ||
|
||
### VGICv3 MMIO处理 | ||
|
||
`vgicv3_redist_handler`和`vgicv3_dist_handler`函数分别处理GICR和GICD的MMIO访问。`vgicv3_redist_handler`函数处理GICR的读写操作,检查是否访问的是当前`zone`的GICR,如果是,则允许访问;否则,忽略该访问。`vgicv3_dist_handler`函数根据不同的GICD寄存器类型,调用`vgicv3_handle_irq_ops`或`restrict_bitmask_access`函数,以适当地处理中断路由和配置寄存器的访问。 | ||
|
||
通过上述机制,hvisor能够有效地管理跨zone的中断,确保每个zone只能够访问和控制分配给它的中断资源,同时提供必要的隔离性。这使得在多zone环境中,VGICv3能够高效、安全地工作,支持复杂的虚拟化场景。 |