news 2026/6/24 10:47:07

kvm_riscv_nacl_enable()的原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
kvm_riscv_nacl_enable()的原理

下面详细解析 Linux KVM RISC-V 中kvm_riscv_nacl_enable()的原理、源码和在H-ext 仿真中的意义。


一、NACL 是什么(前置理解)

NACL = SBI Nested Acceleration Extension(EID0x4E41434C "NACL"

只在嵌套虚拟化场景有意义:当 KVM(L1 Hypervisor)自己作为 Guest 跑在另一个 L0 Hypervisor 上时,H-ext CSR 访问 /HFENCE/HLV/HSV原本要 VM-Exit 到 L0 逐条模拟。NACL 通过Per-CPU Shared Memory(共享内存页)​ 让 L1 KVM 批量写入 H-ext CSR 值和 HFENCE 请求,再一次性调 SBI 同步,减少 trap 次数。

⚠️如果你的仿真器是直接跑 KVM 在裸硬件/H-ext 上(非嵌套),OpenSBI 通常不实现 NACL,kvm_riscv_nacl_available()为 false,kvm_riscv_nacl_enable()直接 return 0,无任何副作用。


二、核心数据结构(arch/riscv/kvm/nacl.c / include/asm/kvm_nacl.h)

/* 每 CPU 一个 NACL 上下文 */ struct kvm_riscv_nacl { void *shmem; /* 共享内存虚拟地址(页) */ phys_addr_t shmem_phys; /* 共享内存物理地址(页对齐)*/ }; DEFINE_PER_CPU(struct kvm_riscv_nacl, kvm_riscv_nacl); /* 静态键 —— 若 OpenSBI 不支持 NACL 则 jump 走,零开销 */ DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_available); DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_sync_csr_available); DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_sync_hfence_available); DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_sync_sret_available); DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_autoswap_csr_available);

共享内存布局(SBI 规范):

Offset 0x0000 — 0x0FFF : Scratch Space(HFENCE 队列 / SRET 参数 / Autoswap) Offset 0x1000 — end : CSR Space(1024 × XLEN,索引 = ((csr&0xc00)>>2)|(csr&0xff))

三、kvm_riscv_nacl_enable() 源码解析

来自arch/riscv/kvm/nacl.c

int kvm_riscv_nacl_enable(void) { struct kvm_riscv_nacl *nacl; /* 若 OpenSBI 未声明支持 NACL → 直接返回,不影响非嵌套场景 */ if (!kvm_riscv_nacl_available()) return 0; nacl = this_cpu_ptr(&kvm_riscv_nacl); /* * SBI 调用:SBI_EXT_NACL, SBI_EXT_NACL_SET_SHMEM * 参数:shmem_phys = 本 CPU NACL 共享内存物理地址 * flags = 0(保留) * 作用:告诉 OpenSBI(L0):"此 CPU 的 NACL shmem 现在是这张物理页" * OpenSBI 此后可从 shmem CSR Space 读取 H-ext CSR 批量值 * 并在 SYNC_CSR / SYNC_HFENCE / SYNC_SRET 时应用 */ struct sbiret ret = sbi_ecall(SBI_EXT_NACL, SBI_EXT_NACL_SET_SHMEM, nacl->shmem_phys, 0, 0, 0, 0, 0); return sbi_err_map_linux_errno(ret.error); }

对应disable

void kvm_riscv_nacl_disable(void) { if (!kvm_riscv_nacl_available()) return; sbi_ecall(SBI_EXT_NACL, SBI_EXT_NACL_SET_SHMEM, SBI_SHMEM_DISABLE, SBI_SHMEM_DISABLE, 0, 0, 0, 0); }

四、初始化时机(kvm_init → 之前看的 main.c)

static int __init riscv_kvm_init(void) { ... rc = kvm_riscv_nacl_init(); // 分配 per-CPU shmem 页,探测 SBI NACL if (rc && rc != -ENODEV) // -ENODEV = OpenSBI 不支持 NACL,忽略 return rc; ... } int kvm_arch_enable_virtualization_cpu(void) { rc = kvm_riscv_nacl_enable(); // 每 CPU online 时绑定 shmem 到当前 CPU if (rc) return rc; csr_write(CSR_HEDELEG, ...); // 之后才是 HEDELEG/HIDELEG/HCOUNTEREN ... }
  • kvm_riscv_nacl_init():分配页 +sbi_probe_extension(SBI_EXT_NACL)+SBI_EXT_NACL_PROBE_FEATURE→ 设 static key

  • kvm_riscv_nacl_enable():在每 CPU 上调SET_SHMEM,激活本 CPU 的 NACL 通道


五、NACL enable 后对 vcpu_run 的影响(原理)

启用后,KVM vcpu world-switch 不再逐条csr_write(CSR_HGATP, ...)/csr_write(CSR_HSTATUS, ...),改为:

  1. 写 H-ext CSR 到 NACL shmem CSR Space(标记 dirty bitmap)

  2. SBI_EXT_NACL_SYNC_CSR(-1UL)→ L0 批量应用 HGATP/HSTATUS/HEDELEG…

  3. 若有 HFENCE → 填 HFENCE queue →SBI_EXT_NACL_SYNC_HFENCE

  4. 若有SBI_NACL_FEAT_SYNC_SRET→ 填 GPR + SRET 参数 →SBI_EXT_NACL_SYNC_SRET原子完成"CSR apply + HFENCE + SRET"

效果:嵌套虚拟化时 L1 KVM world-switch 的 VM-Exit 数大幅下降


六、对 H-ext 仿真器的影响

场景

NACL 影响

裸机跑 KVM( lkvm 场景,OpenSBI 无 NACL)

kvm_riscv_nacl_available()=falsekvm_riscv_nacl_enable()直接 return 0,完全不触 SBI,无影响

OpenSBI 假声明支持 NACL 但仿真器不实现SBI_EXT_NACL_SET_SHMEM

sbi_ecall返回SBI_ERR_NOT_SUPPORTED→ KVM 模块加载失败或 cpuhp 报错 →kvm.ko 加载中止

未来做嵌套虚拟化(KVM-on-KVM)

需仿真器实现 SBI NACL:分配 shmem、解析 SYNC_CSR/SYNC_HFENCE/SYNC_SRET

七、一句话总结

kvm_riscv_nacl_enable()是 KVM 对每个 CPU 调 SBI NACLSET_SHMEM,把预分配的 Per-CPU 共享内存页注册给 OpenSBI,用于嵌套虚拟化时批量同步 H-ext CSR / HFENCE / SRET,减少 VM-Exit。非嵌套场景(裸 H-ext 跑 KVM)OpenSBI 不实现 NACL,kvm_riscv_nacl_available()为 false,该函数直接 return 0,对功能无任何影响。若仿真器错误暴露 NACL 却不实现会导致 KVM 加载失败。

如果你想确认你环境是否走了 NACL 分支,搜 dmesg:

dmesg | grep -i "nested acceleration"

有输出 = NACL 激活(需仿真器支持);无输出 = 正常非嵌套,可忽略 NACL 完全。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/24 10:42:23

每日一技第三天——RAG的查询重写机制

导入先看这样一个场景前两天,我用豆包查高考作文题。我说:“豆包,简单回答一下今年新高考二卷的语文作文要求写什么。”它给了我材料主旨和核心立意。我接着又问了一句:“英语呢?”就两个字,但豆包准确地回…

作者头像 李华
网站建设 2026/6/24 10:36:19

AI拉呱-2026年06月19日AI技术洞察简报

AI拉呱-2026年06月19日AI技术洞察简报 作者:AI拉呱(Errol Yan) 定位:每日三分钟洞察世界AI技术动态,关注了解更多 今日概览 本文汇总了 2026-06-19 的高价值技术动态(评分≥7.0),共…

作者头像 李华
网站建设 2026/6/24 10:33:30

制造业AI视觉质检实战:5万张产品图的数据本地化训练与存储

制造业AI视觉质检实战:5万张产品图的数据本地化训练与存储 汽车零部件工厂里,质检员老周每天盯着产线,一小时要看300个零件。"肉眼疲劳了,漏检是常事,"他坦言,"去年一批转向节差点装到整车里…

作者头像 李华
网站建设 2026/6/24 10:27:57

agent 开发知识点

这样写完全可以,你的问题列表涵盖了大模型(LLM)Agent 框架从架构设计(Protocol、工厂模式)、异步并发(to_thread)、数据安全(脱敏)、状态管理(Memory、上下文…

作者头像 李华