ARMv8系列 CPU虚拟化
虚拟化概念
虚拟化:能对计算机的各种物理资源(CPU/内存/IO设备)进行抽象组合并分配给多个虚拟机
Hypervisor:虚拟机管理程序,也叫VMM(Virtual Machine Manager),位于硬件和虚拟机之间,负责管理和分配计算机资源给各个虚拟机。分类有如下两种:
Type 1: (a)VMM类似小型操作系统,管理所有虚拟机
Type2: (b)VMM依赖于宿主操作系统(例如Windows Linux)
CPU虚拟化
典型Type1虚拟化:Hypervisor运行在EL2, VM的OS运行在EL1
创建多个vCPU
一个物理CPU可以创建多个vCPU,利用OS的多进程/线程机制,hypervisor可以分时复用地调度它们运行,当进程从EL2切到EL1之后,vCPU就创建了
关于异常处理
非虚拟化场景:异常处理集中在EL1,比如异常向量表,异常处理,中断处理,系统调用等
虚拟化场景:
对于hypervisor, 需要处理hypervisor本身的异常,来自VM的(异常处理,中断处理,系统调用)
对于VM:也要处理VM本身的异常和系统调用
vCPU实验
1.把hypervisor(OS)运行在EL2上
从midr_el1和mpidr_el1上获取物理CPU(单/多)的信息,然后放入vpidr_el2和vmpidr_el2中,确保vCPU模拟出CPU相似的处理器ID和亲和性信息。随后设置EL2的异常向量表,然后进入到boot_kernel函数
2.从hypervisor EL2中让OS进入到VM中
(1)创建一个virt_main函数,在main函数中执行,virt_main函数中执行jump to VM的操作
(2)在linker.ld中定义内存中vm_sp的布局
(3)jump_to_vm:
设置HCR_EL2.RW, 让CPU运行在aarch64中
设置SPSR_EL2, 当eret指令后,跳转到EL1
设置ELR_EL2,当eret指令后,跳转到vm_entry中,这里是设置的进入EL1之后的第一个函数
设置SP_EL1栈,让vCPU指向一个新的栈空间,就是vm_sp
最后执行eret指令
3.从VM退出到hypervisor
三种情况:
调用HVC/VM发生异常EL1处理不了(比如GPA缺页异常)/发生硬件中断
HVC
SVC:运行在EL0的app请求进入到EL1的OS
HVC:运行在EL1的VM,请求进入到EL2的hypervisor
SMC:运行在hypervisor或VM的软件,请求进入到EL3的安全固件中
异常综合信息寄存器ESR_EL2
(1) virt_main调用hvc_call
(2) hvc_call会调用__do_vcpu_exit(这个是在EL2的异常向量表中已经定义过了,virt_vectors)
(3)__do_vcpu_exit: 获取ESR_EL2的信息,判断异常类型,跳转到vm_hvc
(4)vm_hvc: 跳转到vm_hvc_handler,处理异常,然后再利用vm_entry 1 跳转到EL1中
#嵌入式Linux##没有实习经历,还有机会进大厂吗##牛客创作赏金赛#