# 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-Shyper可以在保障隔离性的同时,实现虚拟机间共享内存的效果

设备模型 

全模拟设备 、半模拟设备 、直通设备

开发经验分享

RAII与智能指针 、Clippy、Rust FFI