《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 业界动态 > RISC-V 异常处理在 KVM 中的实现

RISC-V 异常处理在 KVM 中的实现

2023-06-16
作者: 晓泰
来源: 泰晓科技
关键词: RISC-V KVM

  Corrector: TinyCorrect v0.1 - [tounix spaces toc comments tables images urls epw]

  Author: XiakaiPan 13212017962@163.com

  Date: 2022/10/21

  Revisor: walimis, Falcon

  Project: RISC-V Linux 内核剖析

  Proposal: RISC-V 虚拟化技术调研与分析

  Sponsor: PLCT Lab, ISCAS

  本周继续连载 Risc-v Kvm Excp Impl 系列文章,记得收藏分享+关注,写文章领补贴:gitee.com/tinylab/riscv-linux

  该活动统一采用泰晓社区自研 Linux Lab 开源实验环境,也可选用免装即插即跑 Linux Lab Disk (https://tinylab.org/linux-lab-disk),某宝检索“泰晓 Linux”可找到。Linux Lab v1.1 Inside —— 内核开发从未像今天这般简单!

  RISC-V 异常处理在 KVM 中的实现

  前言

  Trap 处理是 RISC-V 虚拟化实现中的重要部分,包括异常和中断两个部分。当前 KVM 是 RISC-V 虚拟化扩展在软件层面较为可靠的实现,本文将结合 RISC-V 特权指令集手册的规定,分析 KVM 中有关异常处理的实现,中断部分由于涉及较多驱动层面的内容,故将在之后的文章中结合 MMIO,timer 等做具体探讨。

  软件版本

 微信截图_20230616161548.png

  KVM 异常处理

  异常处理入口

  在 KVM 对 RISC-V H 扩展的实现中,与异常处理相关的函数调用关系如下图所示。目前的实现中,KVM 能够处理三类异常。即虚拟机内的 page fault、虚拟指令异常和系统调用,三种不同的异常处理分别对应了不同的实现。

  微信截图_20230616161931.png

  异常分类及其定义

  kvm_arch_vcpu_ioctl_run 函数用于实现 vCPU 的运行。其调用 kvm_riscv_vcpu_enter_exit 函数进入 vCPU 的运行,此时 Guest 进入运行状态,CPU 处于 VS 或者 VU 模式。当 Guest 发生无法处理的异常时,Guest 退出,CPU 进入 HS 模式,随后 KVM 调用 kvm_riscv_vcpu_exit 来实现对异常的处理。

  kvm_riscv_vcpu_exit 函数内部包含三个部分,分别对应三种异常的处理,代码如下:

 微信截图_20230616162055.png

微信截图_20230616162245.png

  如上所示,KVM 的实现中包含了三类异常:

  虚拟指令异常;

  Guest page fault;

  SBI 系统调用。

  特权指令集手册 中规定了每种异常对应的编码(即 scause 的可能的值),在进行异常处理时,可依据据 scause 的具体值确定其处理方式,如下表所示。

  微信截图_20230616162009.png

  cause code

  在 KVM 中,其对应宏的定义如下:

 微信截图_20230616162306.png

  虚拟指令异常

  其中,EXC_VIRTUAL_INST_FAULT 即 virtual instruction exception 对应如下情况:

  在 VS-Mode 或 VU-Mode 下访问特定 CSR 的特定位;

  在 VS-Mode 或 VU-Mode 下执行无权限的指令如 HFENCE, HLV, HSV 等。

  KVM 中 virtual instruction 异常的处理如下:

  微信截图_20230616162355.png

      微信截图_20230616162434.png

 

  其中用于处理具体指令的函数其原型或定义如下:

  处理非法压缩指令时,用于从 Guest 获取合法指令的 kvm_riscv_vcpu_unpriv_read 函数:

 微信截图_20230616162634.png

  对合法的压缩指令以及非 SYSTEM 类型的非压缩指令,不进行额外处理,直接调用 truly_illegal_insn 函数处理,保存当前 trap 的具体信息,将 Guest PC 设置为 Guest 中对应的异常向量, 然后返回到到 Guest 中对异常进行处理:

 微信截图_20230616162706.png

     微信截图_20230616162738.png

  其调用关系如下图所示:

  微信截图_20230616162900.png

  SBI 系统调用

  系统调用的处理通过调用 kvm_riscv_vcpu_sbi_ecall 函数实现,如下方代码块所示:

  SBI(Supervisor Binary Interface) 是直接运行在 Machine Mode 下的,为上层 OS 提供统一接口的程序,具有最高权限。而 Guest 访问 SBI 系统调用,是在 KVM 中模拟实现,不是实际访问 Machine Mode 中的 SBI firmware。KVM 通过直接访问和设置寄存器(cp->a7, cp->a0, cp->a0 等)的值来实现对 SBI 系统调用的处理。

  微信截图_20230616163251.png

        微信截图_20230616163337.png

微信截图_20230616163445.png

  总结

  本文结合 KVM 中有关异常处理的实现,讨论了在添加 H 扩展之后的虚拟指令异常、guest page fault 以及来自 guest 的系统调用的处理。

  参考资料

  RISC-V 特权指令集手册

  RISC-V Linux

  首发地址:https://tinylab.org/riscv-kvm-excp-impl

  技术服务:https://tinylab.org/ruma.tech


本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。
Baidu
map