AMD SEV机密虚拟机ASID管理
本文将介绍 Linux 内核中,AMD SEV 机密虚拟机对虚拟机号 ASID 的管理设计,基于的内核版本为 Linux 5.10。
数据结构AMD SEV 中对 ASID 管理的核心代码位于 arch/x86/kvm/svm/sev.c 中,以下是与之相关的数据结构定义:
/* 定义保护位图的互斥锁 */
static DEFINE_MUTEX(sev_bitmap_lock);
/* SEV 同时支持的最大 ASID */
unsigned int max_sev_asid;
/* SEV 应该使用的最小的 ASID */
static unsigned int min_sev_asid;
/* 待分配的 ASID 位图 */
static unsigned long *sev_asid_bitmap;
/* 回收的 ASID 位图 */
static unsigned long *sev_reclaim_asid_bitmap;
AMD SEV 的 ASID 管理采用了 双位图 的设计,包含一张分配位图 sev_asid_bitmap 和一张回收位图 sev_recla ...
Linux内核initcall初始化机制
本文将介绍 Linux 内核的初始化函数结构,其通过 initcall 机制来实现,其核心是一系列优先级不同的宏,用于控制初始化函数的执行顺序。本文的实验的内核环境基于 Linux 5.10。
initcall 的级别与执行顺序Linux 内核定义了多个初始化级别(按照执行顺序从高到低排列):
宏定义
级别名
优先级值
用途说明
early_initcall(fn)
early
-
早期的初始化,在 SMP 初始化之前
pure_initcall(fn)
pure
0
用于初始化不能被静态初始化的变量
core_initcall(fn)
core
1
核心子系统初始化
postcore_initcall(fn)
postcore
2
核心子系统之后的初始化
arch_initcall(fn)
arch
3
架构相关初始化
subsys_initcall(fn)
subsys
4
子系统初始化
fs_initcall(fn)
fs
5
文件系统初始化
rootfs_initcall(fn)
rootfs
-
根文件系统初始化
device ...
使用QEMU TCG模拟一个硬件虚拟化环境
本文将介绍如何使用 QEMU TCG 模拟的方式,构建一个支持硬件虚拟化的环境,使得能够在该模拟器环境下启动一个 KVM 虚拟机。
编译最新 QEMU首先需要下载并编译 QEMU,我们以 x86_64 架构为例,QEMU 选择使用最新版本。
# 下载最新仓库
$ git clone https://git.qemu-project.org/qemu.git
$ cd qemu
# 配置编译目标
$ ./configure --target-list=x86_64-softmmu
# 编译
$ make -j$(nproc)
准备 Linux 内核(选用 6.12.0)接下来,需要准备 Linux 内核,我这里选用的是 6.12.0 版本。硬件虚拟化技术使用 AMD-V,需要在 menuconfig 中启用 KVM for AMD processor support。
# 下载 6.12 版本内核
$ wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.12.tar.xz
$ tar -xvf linux-6.12.t ...
QEMU softmmu模型
本文将分析 QEMU TCG 模式下的访存模型,也就是 softmmu 的设计,基于的版本为 QEMU 6.2,架构则以 RISC-V 为例。
基本调用链1. target/riscv/translate.c 访存指令翻译。
2. accel/tcg/cputlb.c 调用 helper 加载函数(如 helper_le_ldq_mmu)。
3. 调用 load_helper 函数
1. 查 TLB,若未命中,则 tlb_fill 进行填充。
2. 处理各种特殊情况(MMIO、不对界访问等)。
3. 计算得到对应的宿主机虚拟地址 haddr = addr + entry->addend,并根据字长进行访问。
TLB 数据结构QEMU 的 softmmu 模型的核心数据结构为其 TLB 的设计,结构如下:
CPUTLBtypedef struct CPUTLB {
CPUTLBCommon c; // 存储 TLB 的一系列元数据。
CPUTLBDesc d[NB_MMU_MODES]; // ...
OS功能挑战赛2025总结
随着最近 OS 功能挑战赛 2025 的落幕,既标志着这几个月比赛工作的结束,也标志着本人研一生活的结束。本文将作为一个简单的记录,对本次比赛的过程以及得到的经验教训做一个总结,同时也对未来的学习研究做一个展望。
比赛回顾首先说一下比赛结果—— 三等奖 ,一个稍微有些令人失望的结果。但不管如何,比赛过程中的收获却是实打实的。
项目的源代码已经开放在了 github 中,欢迎参考:
LordaeronESZ/SEVFS: A simple encrypted versioning file system.
时间线接下来,我将简单梳理一下本次比赛的整个时间线。
首先是 3 月份,我们完成了比赛的报名和选题工作。其中选题工作并不那么顺利,最开始我们选题备选方案为:(1)proj121-使用哈希页表实现虚拟机的 stage-2 页表 和 (2)proj319-支持 RISC-V 架构的文件级加密文件系统。由于个人科研方向为虚拟化方向,因此两个题目中更偏向于前者。但通过对往年的参赛作品进行调研发现,已经有队伍做过了该题目并且基本完成了题目的所有要求,并最终获得了一等奖——我们再选择该题目 ...
论文《SVSM-KMS:Safeguarding Keys for Cloud Services with Encrypted Virtualization》总结
本文将介绍 2024 年发表在 arXiv 上的论文《SVSM-KMS:Safeguarding Keys for Cloud Services with Encrypted Virtualization》。
解决的问题密钥管理服务是云环境中最重要的服务之一。集中式密钥管理系统(centralized Key Management System, KMS)通常提供一个统一的平台来进行密钥生成、分发、管理等操作,然而,这会导致可信计算基(TCB)过大,带来单点故障的风险。非集中式的 KMS 是一个方向,但是这会带来为维护多结点一致性的高昂的开销。
云端的安全密钥管理存在许多问题:首先云服务提供商(CSP)拥有对平台的绝对控制权,需要将其视作可信。此外,网络延迟会影响集中式的 KMS 的效率。同时,如果宿主机系统被攻破,还可能导致密钥的泄露。
为了解决这些问题,本文基于 AMD SEV-SNP 所引入的 VMPL 机制和 SVSM 特权软件,设计了 SVSM-KMS,将 KMS 放在 CVM 内的最高 VMPL 特权级,与 host 和 guest 隔离开来。具体来说,本文的贡献如下:
...
RISC-V 架构下的裸金属程序
本文将介绍如何在 RISC-V 环境下,编写一个最简的裸金属(bare-metal)程序,该程序不依赖于操作系统的支持,计算机在启动后直接跳转到该程序开始执行。本文的目的主要是作为一个程序模板,可以对其进行扩展成为一个完整的操作系统或是常驻内存中的固件服务。
实现原理要实现计算机在启动后立马跳转到该程序执行,需要明确一点:计算机启动后执行的第一条指令是什么?或者说,PC 初始值是什么?答案根据平台的不同可能存在差异,我们的测试环境为 qemu-system-riscv64 模拟器的 virt 模型,其初始 PC 为 0x80000000。那么我们便要编写链接脚本,将需要程序的入口点链接到该地址处。
还有第二个问题:程序入口可以直接是 C 程序吗?答案是不行,至少绝大部分情况下不行。C 代码编译之后,局部作用域内变量的保存依赖于栈,因此我们必须准备好一片连续的内存区域(栈空间),并在进入 C 环境前将栈指针寄存器(SP)指向该内存区域的最高地址处(因为栈从高地址向低地址增长)。
至于栈空间的分配,通常有两种方式。首先可以编写链接脚本进行预留:
OUTPUT_ARCH("ris ...
论文《Cabin:Confining Untrusted Programs within Confidential VMs》总结
本文将介绍 2024 年发表在 arXiv 上的论文《Cabin: Confining Untrusted Programs within Confidential VMs》。
解决的问题特权级划分保证系统稳定运行的最基本机制,然而传统的特权级划分存在一些不足之处:首先,由于内核庞大的代码所带来的庞大的攻击面,用户态和内核态的接口——系统调用可能会被恶意用户程序利用以绕过内核的保护机制;其次,MMU 缺乏细粒度的页面保护,x86 架构下页表项的读写权限仅由一个 R/W 位来指示,只能被配置为只读或可读可写,限制了 XOM(eXecute-Only Memory)的高效实现。
具体来说,本文工作的威胁模型基本继承自 CVM 的威胁模型,在此基础上加入了对于部分应用程序的不信任,认为其可能包含内存安全错误。贡献如下:
设计并实现了一个 CVM 内的安全进程执行框架,借助 VPML 机制,保护 guest OS 免受不可信程序的威胁。
引入系统调用异步转发、自管理内存等机制降低框架带来的性能开销,根据在 Nbench、WolfSSL 等基准测试下的性能表现,表明本框架的性能开销较低。
...
xv6-riscv 上下文切换代码分析
由于最近的工作涉及到编写上下文切换跳板代码的需求,因此便想将 xv6 中与此相关的代码读一读,正好之前学习时对这一块也没有看得太仔细。
系统初始化xv6 的 qemu 启动参数为 -kernel kernel/kernel -bios none,qemu 模拟器在启动时,pc 将自动跳转到预先设定的地址 0x80000000 处,而链接脚本 kernel.ld 已经将下列代码 entry.S 链接到了该地址,因此下列代码即模拟器启动后 CPU 执行的初始代码。
这段代码的作用是为每个 CPU 核心开辟属于自己的栈空间,以便后续内核代码的执行。
.section .text
.global _entry
_entry:
# stack0 在 start.c 中定义
# 每个 CPU 固定为 4KB 的内核栈大小
# sp = stack0 + (hartid * 4096)
la sp, stack0
li a0, 1024*4
csrr a1, mhartid
a ...
论文《Ditto:Elastic Confidential VMs with Secure and Dynamic CPU Scaling》总结
本文将介绍 2024 年发表在 arXiv 上的论文《DITTO:Elastic Confidential VMs with Secure and Dynamic CPU Scaling》。
解决的问题机密虚拟机(CVM)在带来了强大的机密性和完整性保护的同时,也带来了很多限制,导致虚拟机的性能和灵活性的下降。例如:不支持 vCPU 的热插拔(即运行中动态调整 vCPU 的数量),该特性可以用于在虚拟机运行过程中灵活调整计算能力,应用于 Serverless 等计算环境下。
虽然的商用 CVM 方案还没有任何一家支持 vCPU 热插拔,但是内存的动态调整是可行的。例如 AMD SEV-SNP 下 hypervisor 可以使用 RMPUPDATE 指令将 CVM 的内存进行回收和动态分配。
由于缺少了 vCPU 数量的动态调整能力,现有的机密无服务器环境(OpenWhisk + Kubernetes + 机密容器)要想动态调整运算能力,只能借助于启动新的 CVM,这会带来很大的性能开销。本文提出了“弹性 CVM” 和 “Woker vCPU” 的概念,能够在 CVM 环境下动态调 ...