各位老师和同学好:
hypervisor组例会时间定为本周五14:00—17:00,请各位有兴趣参与者,尽量线下参加
会议地点:北京市海淀区清华科技园科技大厦C座地面层 启迪之星中英创新中心孵化器 云龙湖会议室 (如找不到,可联系李明 13691584139)线上接入方式:#腾讯会议:109-199-665会议主题:hypervisor技术讨论会会议时间:2023/03/24 14:00-17:00 (GMT+08:00) 中国标准时间 - 北京会议议程:
莫策(北航), Rust-Shyper代码结构讲解
郑元昊,RVM1.5系统代码结构讲解
陈星宇,jailhouse 调研分析汇报
请大家关注。
# Hypervisor技术讨论会 会议纪要
## 时间
2023.03.24 14:00—17:00
## 人员 advisor: cdg, ck, cy, ld student: cxy, dsf, jyk, lj, lky, mc, wwt, yjy, zyh ## 内容
1. zyh:RVM1.5系统代码结构讲解
RVM1.5的地址空间包括hvheader、每个vcpu的数据和栈空间、cell的地址空间。src目录下的head.rs文件、percpu.rs文件和cell.rs文件分别声明了hvheader、每个vcpu和cell的成员变量和接口的函数;memory目录下的paging.rs文件声明了扩展四级页表的结构体与接口的函数,并使用加锁的方式避免数据冲突。
2. cxy:jailhouse config analysis
关于config具体的定义可以参考include/jailhouse/cell-config.h头文件
jailhouse的配置文件以c文件的形式存在,在config文件夹下存在大量已经定义的文件,包括imx8wq.c,我们以此为例来解释config内容
header
.signature = JAILHOUSE_SYSTEM_SIGNATURE, .revision = JAILHOUSE_CONFIG_REVISION, .architecture = JAILHOUSE_ARM64,
定义一些版本信息
.flags = JAILHOUSE_SYS_VIRTUAL_DEBUG_CONSOLE,
JAILHOUSE_SYS_VIRTUAL_DEBUG_CONSOLE允许根单元读virtual console
hypervisor_memory
.hypervisor_memory = { .phys_start = 0xfdc00000, .size = 0x00400000, },
预留的hypervisor地址空间
debug_console
.debug_console = { .address = 0x30860000, .size = 0x1000, .type = JAILHOUSE_CON_TYPE_IMX, .flags = JAILHOUSE_CON_ACCESS_MMIO | JAILHOUSE_CON_REGDIST_4, },
定义了debug console,包括其地址大小类型,其中类型和flag定义如下
/* Those definitions are used for the type in struct jailhouse_console */ #define JAILHOUSE_CON_TYPE_NONE 0x0000 #define JAILHOUSE_CON_TYPE_EFIFB 0x0001 #define JAILHOUSE_CON_TYPE_8250 0x0002 #define JAILHOUSE_CON_TYPE_PL011 0x0003 #define JAILHOUSE_CON_TYPE_XUARTPS 0x0004 #define JAILHOUSE_CON_TYPE_MVEBU 0x0005 #define JAILHOUSE_CON_TYPE_HSCIF 0x0006 #define JAILHOUSE_CON_TYPE_SCIFA 0x0007 #define JAILHOUSE_CON_TYPE_IMX 0x0008 #define JAILHOUSE_CON_TYPE_IMX_LPUART 0x0009 #define JAILHOUSE_CON_TYPE_SCIF 0x000a
flag用于定义访问方式和访问位宽
/* Flags: bit 0 is used to select PIO (cleared) or MMIO (set) access */ #define JAILHOUSE_CON_ACCESS_PIO 0x0000 #define JAILHOUSE_CON_ACCESS_MMIO 0x0001 /* * Flags: bit 1 is used to select 1 (cleared) or 4-bytes (set) register distance. * 1 byte implied 8-bit access, 4 bytes 32-bit access. */ #define JAILHOUSE_CON_REGDIST_1 0x0000 #define JAILHOUSE_CON_REGDIST_4 0x0002
platform_info
.platform_info = { .pci_mmconfig_base = 0xbfb00000, .pci_mmconfig_end_bus = 0, .pci_is_virtual = 1, .pci_domain = 2, .arm = { .gic_version = 3, .gicd_base = 0x38800000, .gicr_base = 0x38880000, .maintenance_irq = 25, }, },
pci_mmconfig_base和pci_mmconfig_end_bus用于计算mmcfg_start和mmcfg_size用于将物理设备地址map到虚拟地址
pci_domain属性后续会通过of_changeset_add_property函数用于修改设备树对应信息
maintenance_irq的作用是hypervisor 用来向 GIC 发出它需要执行维护操作的信号的特殊中断(此条存疑)
root_cell
.root_cell = { .name = "imx8mq", .num_pci_devices = ARRAY_SIZE(config.pci_devices), .cpu_set_size = sizeof(config.cpus), .num_memory_regions = ARRAY_SIZE(config.mem_regions), .num_irqchips = ARRAY_SIZE(config.irqchips), .vpci_irq_base = 51, /* Not include 32 base */ }, #define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
num_pci_devices pci设备数量
cpu_set_size cpu集大小
num_memory_regions 分配给cell的内存大小
num_irqchips 指代表系统中的中断控制器的 Irqchip 的数量
cpus[1]
.cpus = { 0xf, },
分配的cpu信息
irq_chip
.irqchips = { /* GIC */ { .address = 0x38800000, .pin_base = 32, .pin_bitmap = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, }, }, ......
pin_base 设备使用的第一个IRQ号
pin_bitmap 表示设备使用的 IRQ 的位图 位图中的每一位代表一个 IRQ 号,如果该位设置为 1,则使用该 IRQ
Jailhouse 使用此信息来配置hypervisor以将中断从设备路由到正确的cell
mem_regions
.mem_regions = { /* IVHSMEM shared memory region for 00:00.0 */ { .phys_start = 0xbfd00000, .virt_start = 0xbfd00000, .size = 0x1000, .flags = JAILHOUSE_MEM_READ , }, { .phys_start = 0xbfd01000, .virt_start = 0xbfd01000, .size = 0x9000, .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE , }, ......
可用内存区域定义
pci_devices
.pci_devices = { { /* IVSHMEM 0000:00:00.0 (demo) */ .type = JAILHOUSE_PCI_TYPE_IVSHMEM, .domain = 2, .bdf = 0 << 3, .bar_mask = JAILHOUSE_IVSHMEM_BAR_MASK_INTX, .shmem_regions_start = 0, .shmem_dev_id = 0, .shmem_peers = 3, .shmem_protocol = JAILHOUSE_SHMEM_PROTO_UNDEFINED, }, { /* IVSHMEM 0000:00:01.0 (networking) */ .type = JAILHOUSE_PCI_TYPE_IVSHMEM, .domain = 2, .bdf = 1 << 3, .bar_mask = JAILHOUSE_IVSHMEM_BAR_MASK_INTX, .shmem_regions_start = 5, .shmem_dev_id = 0, .shmem_peers = 2, .shmem_protocol = JAILHOUSE_SHMEM_PROTO_VETH, }, },
type定义如下 其中bridge允许一条总线上的设备和另一条上的交互,而ivshmem是虚拟设备
#define JAILHOUSE_PCI_TYPE_DEVICE 0x01 #define JAILHOUSE_PCI_TYPE_BRIDGE 0x02 #define JAILHOUSE_PCI_TYPE_IVSHMEM 0x03
domain指pci设备所在域
bdf 代表 Bus/Device/Function 用于唯一标识系统上的 PCI 设备
bar_mask 定义了IVSHMEM设备的不同类型的 Base Address Registers 定义内存地址掩码,有如下四种定义
#define JAILHOUSE_IVSHMEM_BAR_MASK_INTX \ { \ 0xfffff000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, \ }
#define JAILHOUSE_IVSHMEM_BAR_MASK_MSIX \ { \ 0xfffff000, 0xfffff000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, \ }
#define JAILHOUSE_IVSHMEM_BAR_MASK_INTX_64K \ { \ 0xffff0000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, \ }
#define JAILHOUSE_IVSHMEM_BAR_MASK_MSIX_64K \ { \ 0xffff0000, 0xffff0000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, \
device remove
在cell创建时,调用函数static int pci_cell_init(struct cell *cell)将pci设备从root cell取出并添加到新创建的cell中,关键代码如下
root_device = pci_get_assigned_device(&root_cell, dev_infos[ndev].bdf); //获取pci设备信息 if (root_device) pci_remove_physical_device(root_device); //从root cell删除设备
err = pci_add_physical_device(cell, device); //添加设备到新cell中 if (err) goto error;
3. mc:Rust-Shyper介绍
Rust-Shyper特点
基于Rust语言的Type I虚拟机监视器, 具备更好的隔离性和更轻量的代码实现。 能够支持Linux、 裸应用等系统软件的运行 灵活、 动态创建并配置虚拟机, 能够为实时操作系统创建实时虚拟机, 保障嵌入式场景的实时需求 具备资源隔离属性, 保障不同虚拟机间的隔离性 实现多种模拟设备, 提供基本的磁盘、 网络、 串口等设备的虚拟化实现, 提高资源利用率 提供传统虚拟机迁移机制以及本地热更新机制, 保障虚拟机监视器正常运行过程中的可靠性
内存虚拟化
通过对第二阶段地址翻译页表的配置,Rust-Shyper可以在保障隔离性的同时,实现虚拟机间共享内存的效果
设备模型
全模拟设备 、半模拟设备 、直通设备
开发经验分享
RAII与智能指针 、Clippy、Rust FFI
# hypervisor技术讨论会 会议纪要
## 时间
2023.03.24 14:00—17:00
## 人员
advisor: cdg, ck, cy, ld
student: cxy, dsf, jyk, lj, lky, mc, wwt, yjy, zyh
## 内容
**1)zyh:RVM1.5系统代码结构讲解**
RVM1.5的地址空间包括hvheader、每个vcpu的数据和栈空间、cell的地址空间。src目录下的head.rs文件、percpu.rs文件和cell.rs文件分别声明了hvheader、每个vcpu和cell的成员变量和接口的函数;memory目录下的paging.rs文件声明了扩展四级页表的结构体与接口的函数,并使用加锁的方式避免数据冲突。
**2)cxy:jailhouse config analysis**
关于config具体的定义可以参考include/jailhouse/cell-config.h头文件
jailhouse的配置文件以c文件的形式存在,在config文件夹下存在大量已经定义的文件,包括imx8wq.c,我们以此为例来解释config内容
**header**
.signature = JAILHOUSE_SYSTEM_SIGNATURE,
.revision = JAILHOUSE_CONFIG_REVISION,
.architecture = JAILHOUSE_ARM64,
定义一些版本信息
.flags = JAILHOUSE_SYS_VIRTUAL_DEBUG_CONSOLE,
JAILHOUSE_SYS_VIRTUAL_DEBUG_CONSOLE允许根单元读virtual console
**hypervisor_memory**
.hypervisor_memory = {
.phys_start = 0xfdc00000,
.size = 0x00400000,
},
预留的hypervisor地址空间
**debug_console**
.debug_console = {
.address = 0x30860000,
.size = 0x1000,
.type = JAILHOUSE_CON_TYPE_IMX,
.flags = JAILHOUSE_CON_ACCESS_MMIO |
JAILHOUSE_CON_REGDIST_4,
},
定义了debug console,包括其地址大小类型,其中类型和flag定义如下
/* Those definitions are used for the type in struct jailhouse_console */
#define JAILHOUSE_CON_TYPE_NONE0x0000
#define JAILHOUSE_CON_TYPE_EFIFB0x0001
#define JAILHOUSE_CON_TYPE_82500x0002
#define JAILHOUSE_CON_TYPE_PL0110x0003
#define JAILHOUSE_CON_TYPE_XUARTPS0x0004
#define JAILHOUSE_CON_TYPE_MVEBU0x0005
#define JAILHOUSE_CON_TYPE_HSCIF0x0006
#define JAILHOUSE_CON_TYPE_SCIFA0x0007
#define JAILHOUSE_CON_TYPE_IMX0x0008
#define JAILHOUSE_CON_TYPE_IMX_LPUART0x0009
#define JAILHOUSE_CON_TYPE_SCIF0x000a
flag用于定义访问方式和访问位宽
/* Flags: bit 0 is used to select PIO (cleared) or MMIO (set) access */
#define JAILHOUSE_CON_ACCESS_PIO0x0000
#define JAILHOUSE_CON_ACCESS_MMIO0x0001
/*
* Flags: bit 1 is used to select 1 (cleared) or 4-bytes (set) register distance.
* 1 byte implied 8-bit access, 4 bytes 32-bit access.
*/
#define JAILHOUSE_CON_REGDIST_10x0000
#define JAILHOUSE_CON_REGDIST_40x0002
**platform_info**
.platform_info = {
.pci_mmconfig_base = 0xbfb00000,
.pci_mmconfig_end_bus = 0,
.pci_is_virtual = 1,
.pci_domain = 2,
.arm = {
.gic_version = 3,
.gicd_base = 0x38800000,
.gicr_base = 0x38880000,
.maintenance_irq = 25,
},
},
pci_mmconfig_base和pci_mmconfig_end_bus用于计算mmcfg_start和mmcfg_size用于将物理设备地址map到虚拟地址
pci_domain属性后续会通过of_changeset_add_property函数用于修改设备树对应信息
maintenance_irq的作用是hypervisor 用来向 GIC 发出它需要执行维护操作的信号的特殊中断(此条存疑)
**root_cell**
.root_cell = {
.name = "imx8mq",
.num_pci_devices = ARRAY_SIZE(config.pci_devices),
.cpu_set_size = sizeof(config.cpus),
.num_memory_regions = ARRAY_SIZE(config.mem_regions),
.num_irqchips = ARRAY_SIZE(config.irqchips),
.vpci_irq_base = 51, /* Not include 32 base */
},
#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
num_pci_devices pci设备数量
cpu_set_size cpu集大小
num_memory_regions 分配给cell的内存大小
num_irqchips 指代表系统中的中断控制器的 Irqchip 的数量
**cpus[1]**
.cpus = {
0xf,
},
分配的cpu信息
**irq_chip**
.irqchips = {
/* GIC */ {
.address = 0x38800000,
.pin_base = 32,
.pin_bitmap = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
},
},
......
pin_base 设备使用的第一个IRQ号
pin_bitmap 表示设备使用的 IRQ 的位图 位图中的每一位代表一个 IRQ 号,如果该位设置为 1,则使用该 IRQ
Jailhouse 使用此信息来配置hypervisor以将中断从设备路由到正确的cell
**mem_regions**
.mem_regions = {
/* IVHSMEM shared memory region for 00:00.0 */ {
.phys_start = 0xbfd00000,
.virt_start = 0xbfd00000,
.size = 0x1000,
.flags = JAILHOUSE_MEM_READ ,
},
{
.phys_start = 0xbfd01000,
.virt_start = 0xbfd01000,
.size = 0x9000,
.flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE ,
},
......
可用内存区域定义
**pci_devices**
.pci_devices = {
{ /* IVSHMEM 0000:00:00.0 (demo) */
.type = JAILHOUSE_PCI_TYPE_IVSHMEM,
.domain = 2,
.bdf = 0 << 3,
.bar_mask = JAILHOUSE_IVSHMEM_BAR_MASK_INTX,
.shmem_regions_start = 0,
.shmem_dev_id = 0,
.shmem_peers = 3,
.shmem_protocol = JAILHOUSE_SHMEM_PROTO_UNDEFINED,
},
{ /* IVSHMEM 0000:00:01.0 (networking) */
.type = JAILHOUSE_PCI_TYPE_IVSHMEM,
.domain = 2,
.bdf = 1 << 3,
.bar_mask = JAILHOUSE_IVSHMEM_BAR_MASK_INTX,
.shmem_regions_start = 5,
.shmem_dev_id = 0,
.shmem_peers = 2,
.shmem_protocol = JAILHOUSE_SHMEM_PROTO_VETH,
},
},
type定义如下 其中bridge允许一条总线上的设备和另一条上的交互,而ivshmem是虚拟设备
#define JAILHOUSE_PCI_TYPE_DEVICE0x01
#define JAILHOUSE_PCI_TYPE_BRIDGE0x02
#define JAILHOUSE_PCI_TYPE_IVSHMEM0x03
domain指pci设备所在域
bdf 代表 Bus/Device/Function 用于唯一标识系统上的 PCI 设备
bar_mask 定义了IVSHMEM设备的不同类型的 Base Address Registers 定义内存地址掩码,有如下四种定义
#define JAILHOUSE_IVSHMEM_BAR_MASK_INTX\
{\
0xfffff000, 0x00000000, 0x00000000,\
0x00000000, 0x00000000, 0x00000000,\
}
#define JAILHOUSE_IVSHMEM_BAR_MASK_MSIX\
{\
0xfffff000, 0xfffff000, 0x00000000,\
0x00000000, 0x00000000, 0x00000000,\
}
#define JAILHOUSE_IVSHMEM_BAR_MASK_INTX_64K\
{\
0xffff0000, 0x00000000, 0x00000000,\
0x00000000, 0x00000000, 0x00000000,\
}
#define JAILHOUSE_IVSHMEM_BAR_MASK_MSIX_64K\
{\
0xffff0000, 0xffff0000, 0x00000000,\
0x00000000, 0x00000000, 0x00000000,\
**device remove**
在cell创建时,调用函数static int pci_cell_init(struct cell *cell)将pci设备从root cell取出并添加到新创建的cell中,关键代码如下
root_device = pci_get_assigned_device(&root_cell, dev_infos[ndev].bdf); //获取pci设备信息
if (root_device)
pci_remove_physical_device(root_device); //从root cell删除设备
err = pci_add_physical_device(cell, device); //添加设备到新cell中
if (err)
goto error;
**3)mc:Rust-Shyper介绍**
Rust-Shyper特点:
- 基于Rust语言的Type I虚拟机监视器, 具备更好的隔离性和更轻量的代码实现。 能够支持Linux、 裸应用等系统软件的运行
- 灵活、 动态创建并配置虚拟机, 能够为实时操作系统创建实时虚拟机, 保障嵌入式场景的实时需求
- 具备资源隔离属性, 保障不同虚拟机间的隔离性
- 实现多种模拟设备, 提供基本的磁盘、 网络、 串口等设备的虚拟化实现, 提高资源利用率
- 提供传统虚拟机迁移机制以及本地热更新机制, 保障虚拟机监视器正常运行过程中的可靠性
内存虚拟化 :
通过对第二阶段地址翻译页表的配置,Rust-Shyper可以在保障隔离性的同时,实现虚拟机间共享内存的效果
设备模型 :
全模拟设备 、半模拟设备 、直通设备
开发经验分享:
RAII与智能指针 、Clippy、Rust FFI