13518219792

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

Linux虚拟化KVM-Qemu分析之中断虚拟化

linux虚拟化KVM-Qemu分析之中断虚拟化

作者:LoyenWang 2020-11-23 07:19:15

云计算

虚拟化 本文会将ARM GICv2中断虚拟化的总体框架和流程讲清楚,这个曾经困扰我好几天的问题在被捋清的那一刻,让我有点每有会意,欣然忘食的感觉。

成都创新互联公司主要企业基础官网建设,电商平台建设,移动手机平台,小程序定制开发等一系列专为中小企业按需策划设计产品体系;应对中小企业在互联网运营的各种问题,为中小企业在互联网的运营中保驾护航。

本文转载自微信公众号「 LoyenWang」,作者 LoyenWang。转载本文请联系 LoyenWang公众号。

背景

说明:

1. 概述

本文会将ARM GICv2中断虚拟化的总体框架和流程讲清楚,这个曾经困扰我好几天的问题在被捋清的那一刻,让我有点每有会意,欣然忘食的感觉。

在讲述中断虚拟化之前,我们应该对中断的作用与处理流程有个大致的了解:

中断虚拟化,将从中断信号产生到路由到vCPU的角度来展开,包含以下三种情况:

  1. 物理设备产生中断信号,路由到vCPU;
  2. 虚拟外设产生中断信号,路由到vCPU;
  3. Guest OS中CPU之间产生中断信号(IPI中断);

本文将围绕ARM-GICv2来描述,因此也不会涉及到MSI以及ITS等特性,带着问题出发吧。

2. VGIC

  1. Linux ARM架构的Hypervisor在引入时,采用的是左图中的系统架构,以便能充分利用Linux现有的机制,比如scheduler等;
  2. KVM/ARM的实现采用了split模式,分成Highvisor和Lowvisor,这样可以充分利用ARM处理器不同模式的好处,比如,Highvisor可以利用Linux Kernel的现有机制,而Lowvisor又可以利用Hyp Mode的特权。此外,带来的好处还包含了不需要大量修改Linux内核的代码,这个在刚引入的时候是更容易被社区所接受的;
  3. Lowvisor有三个关键功能:1)对不同的执行Context进行隔离与保护,比如VM之间不会相互影响;2)提供Guest和Host的相互切换,也就是所谓的world switch;3)提供一个虚拟化trap handler,用于处理trap到Hypervisor的中断和异常;

VHE

  1. VHE: Virtualization Host Extensions,用于支持Host OS运行在EL2上,Hypervisor和Host OS都运行在EL2,可以减少Context切换带来的开销;
  2. 目前Cortex-A55, Cortex-A75, Cortex-A76支持VHE,其中VHE的控制是通过HCR_EL2寄存器的操作来实现的;

 再补充一个知识点:

  1. Host如果运行在EL1时,可以通过HVC(Hypervisor Call)指令,主动trap到EL2中,从而由Hypervisor来接管;
  2. Guest OS可以配置成当有中断或异常时trap到EL2中,在中断或异常产生时,trap到EL2中,从而由Hypervisor来接管;
  3. EL2可以通过eret指令,退回到EL1;

本文的讨论基于Non-VHE系统。

2.1 GIC虚拟化支持

GICv2硬件支持虚拟化,来一张旧图:

先看一下物理GIC的功能模块:

简化图如下:

GICv2,提供了硬件上的虚拟化支持,也就是虚拟GIC(VGIC),从而中断的接收不需要通过Hypervisor来软件模拟:

2.2 虚拟中断产生流程

本文开始提到的三种中断信号源,如下图所示:

  1. 外设中断信号(Hypervisor已经将其配置成虚拟中断)到达GIC;
  2. GIC Distributor将该物理IRQ发送至CPU;
  3. CPU trap到Hyp模式,此时将会退出Guest OS的运行,并返回到Host OS;
  4. Host OS将响应该物理中断,也就是Host OS驱动响应外设中断信号;
  5. Hypervisor往List Register写入虚拟中断,Virtual CPU interface将virtual irq信号发送至vCPU;
  6. CPU将处理该异常,Guest OS会从Virtual CPU Interface读取中断状态进行响应;

Qemu模拟外设,通过irqfd来触发Hypervisor进行中断注入;

Hypervisor往List Register写入虚拟中断,Virtual CPU interface将virtual irq信号发送至vCPU;

CPU将处理该异常,Guest OS会从Virtual CPU Interface读取中断状态进行响应;

Guest OS访问Virtual Distributor,触发异常,trap到Hypervisor;

Hypervisor进行IO异常响应,并最终将虚拟中断写入到List Register中,Virtual CPU interface将virtual irq信号发送至vCPU;

CPU将处理该异常,Guest OS会从Virtual CPU Interface读取中断状态进行响应;

上述描述的流程,实际中需要和虚拟外设去交互,包括虚拟外设框架(比如VFIO)等,而本文只是从中断的角度来分析,省去了外设部分。

理论部分讲完了,下边就开始从源码中去印证理论了。

3. 软件实现流程

3.1 VGIC初始化

3.2 物理外设产生中断

假设你已经看过之前CPU的虚拟化文章了,按照惯例,先上图:

那虚拟中断是什么时候注入的呢?没错,图中的kvm_vgic_flush_hwstate会将虚拟中断注入,并且在__guest_enter切换回Guest OS时进行响应:

3.3 虚拟外设产生中断

  1. irqfd提供了一种机制用于注入虚拟中断,而这个中断源可以来自虚拟外设;
  2. irqfd是基于eventfd的机制来实现的,用于用户态与内核态,以及内核态之间的事件通知;
  3. 事件源可以是虚拟设备,比如VFIO框架等,这个模块还没有去深入了解过,不敢妄言,后续系列会跟进;

软件流程如下图:

3.4 vCPU IPI

软件流程如下:

耗时耗力耗心血的一篇文章终于写完了,ARMv8 GICv2中断虚拟化的总体框架和流程应该算是理顺了,全网相关主题的文章并不多,希望能给带来点帮助吧。

如果对你有用的话,在看,分享,打赏三连吧。

参考

《arm_gic_architecture_specification》《ARM_Interrupt_Virtualization》《VM-Support-ARM》《CoreLink GIC-400 Generic Interrupt Controller》《Virtualization in the ARM Architecture》https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3


网站标题:Linux虚拟化KVM-Qemu分析之中断虚拟化
分享路径:http://cdbrznjsb.com/article/djsdeig.html

其他资讯

让你的专属顾问为你服务