当前位置: 首页 > article >正文

让KVM支持滚动热升级:Multi-KVM

Multi-KVM 允许多个独立的 KVM 模块在同一台 Linux 主机上同时加载、卸载和运行。主要包括:

  • 升级和回滚 KVM,而不会中断正在运行的虚拟机

  • 允许在同一主机上运行具有不同参数的 KVM 模块

  • 为 KVM 的 A/B 测试提供便利

1. 设计方案

隔离性

  • 从整个内核中隐藏 KVM 内部结构

  • 详细参见:  https://lore.kernel.org/lkml/20230916003118.2540661-1-seanjc@google.com[PATCH 00/26] KVM: vfio: Hide KVM internals from others - Sean Christopherson

Multi KVM

  • 将 kvm_intel.ko 和 kvm_amd.ko 合并为 kvm.ko 

  • 暴露多个 kvmN.ko 模块和 /dev/kvmN 设备 

  • "N" 通过 Kconfig 字符串定义(默认为 null/off)

VAC

  • 将 KVM 中的共享系统资源提取到新的 "基础模块"(VAC)中 

  • VAC = Virtualization Acceleration Code 虚拟化加速代码 (不可升级单元的模块)

用户空间

  • 无需更改用户空间 VMM

    • 符号链接(/dev/kvm -> /dev/kvmN)
    • kvm 绑定挂载等
  • 不需要用户空间更改部署、使用方式和VM生命周期管理等

2.主要工作

  • 将 KVM 内部结构与内核其他部分隔离

  • 修改基本模块名称/命名空间

  • 将 x86 厂商模块合并到 kvm.ko 中

  • 其他

3.LKML Review

From: Sean Christopherson <seanjc@google.com>
Subject: [PATCH 00/26] KVM: vfio: Hide KVM internals from others
Date: Fri, 15 Sep 2023 17:30:52 -0700  [thread overview]
Message-ID: <20230916003118.2540661-1-seanjc@google.com> (raw)

Anish Ghulati (1):
  KVM: arm64: Move arm_{psci,hypercalls}.h to an internal KVM path

Sean Christopherson (25):
  vfio: Wrap KVM helpers with CONFIG_KVM instead of CONFIG_HAVE_KVM
  vfio: Move KVM get/put helpers to colocate it with other KVM related
    code
  virt: Declare and define vfio_file_set_kvm() iff CONFIG_KVM is enabled
  vfio: Add struct to hold KVM assets and dedup group vs. iommufd code
  vfio: KVM: Pass get/put helpers from KVM to VFIO, don't do circular
    lookup
  KVM: Drop CONFIG_KVM_VFIO and just look at KVM+VFIO
  x86/idt: Wrap KVM logic with CONFIG_KVM instead of CONFIG_HAVE_KVM
  KVM: x86: Stop selecting and depending on HAVE_KVM
  KVM: arm64: Stop selecting and depending on HAVE_KVM
  KVM: s390: Stop selecting and depending on HAVE_KVM
  KVM: MIPS: Make HAVE_KVM a MIPS-only Kconfig
  KVM: arm64: Include KVM headers to get forward declarations
  KVM: arm64: Move ARM specific headers in include/kvm to arch directory
  KVM: Move include/kvm/iodev.h to include/linux as kvm_iodev.h
  KVM: MIPS: Stop adding virt/kvm to the arch include path
  KVM: PPC: Stop adding virt/kvm to the arch include path
  KVM: s390: Stop adding virt/kvm to the arch include path
  KVM: Standardize include paths across all architectures
  perf/x86: KVM: Have perf define a dedicated struct for getting guest
    PEBS data
  entry/kvm: Drop @vcpu param from arch_xfer_to_guest_mode_handle_work()
  entry/kvm: KVM: Move KVM details related to signal/-EINTR into KVM
    proper
  KVM: arm64: Move and consolidate "public" functions in asm/kvm_host.h
  powerpc/xics: Move declaration of xics_wake_cpu() out of kvm_ppc.h
  KVM: PPC: Rearrange code in kvm_ppc.h to isolate "public" information
  KVM: Hide KVM internal data structures and values from kernel at-large

 MAINTAINERS                                   |   1 -
 arch/arm64/Kconfig                            |   1 -
 arch/arm64/include/asm/kvm_emulate.h          |   3 +
 arch/arm64/kvm/Kconfig                        |   2 -
 arch/arm64/kvm/Makefile                       |   2 -
 arch/arm64/kvm/arch_timer.c                   |   5 +-
 arch/x86/Kconfig                              |   1 -
 arch/x86/events/core.c                        |   5 +-
 arch/x86/events/intel/core.c                  |  18 +-
 arch/x86/events/perf_event.h                  |   3 +-
 arch/x86/include/asm/hardirq.h                |   2 +-
  .
  .
  .

这是一个没被标记为RFC的代码提交, 目的是将 KVM 的内部结构从内核中隐藏起来。这里的 "内部"指的是数据结构、枚举、#defines、API等。这些数据结构、枚举、#defines、API等本应仅限于KVM使用, 但却由于kvm_host.h的存在而暴露在其他地方。由于 kvm_host.h(以及其他头文件) 存在于全局 include 路径中,因此在任何地方都会暴露出来。

隐藏 KVM 内部结构的动机是为了在无需重启主机的情况下安全地加载新的KVM 模块。新KVM模块加载而无需重启主机, 其中的 "新 "并不一定是严格意义上的更新, 只是 KVM 的不同版本。隐藏KVM 的内部结构意味着这些资源可以在不同的 KVM 实例中进行更改。例如: 可以修改 kvm_vcpu 结构的布局, 以引入与新的 KVM 实例相关的新字段, 引入与新功能相关的新字段或解决硬件错误。

所有这一切的最终目标是允许在一台主机上同时加载和运行多个KVM模块。例如: 修复部署问题、解决错误或加入新功能,而无需关闭主机上不相干的虚拟机。

目前,我们的首要目标是让 KVM x86 达到这样一种状态, 即 KVM x86 不会将对外部无用的信息暴露给内核。例如: 页面写入跟踪将使用KVM-GT技术, 使用新的 API。

我不认为我在此之前 "正式"提出过隐藏 KVM 内部细节的想法, 因此我决定不标记此 RFC, 因为这些改动最终并非不具备侵入性, 而且在最后六个补丁之前的所有修改都不会标记为RFC, 即使隐藏KVM内部细节的实现最终被否决。

理想情况下, 将会有 5 个独立的提交, 如果我们想以这种方式合并这些内容,我觉得或许也可以实现。例如按照下列步骤提交:

 (1) VFIO 清理 

   (2) 删除 HAVE_KVM

   (3) 清理 Makefile

   (4) x86 perf 清理

   (5) 实现KVM隐藏细节

HAVE_KVM 和 virt/kvm 包括的东西, 并不是严格意义上的必需, 但我还是把它们包括进来了, 因为它们也是又必要处理的。

除了 #ifdef __KVM__ 方法, 我们还探索了其他几种方法, 但都非常糟糕。 我真正想做到的(现在也想做到)是把大部分的 kvm_host.h (以及其他 KVM 头文件) 藏在 virt/kvm 中, 但每次尝试都以失败告终。即使有 __KVM__ 宏保护也无济于事, 原因是每个架构的 kvm_host.h 与通用的 kvm_host.h 交织在一起。试图以迭代补丁提交看起来比较复杂(每个补丁不可避免地会滚成一头巨兽)。

我们考虑过的另一个想法(这是我想到的, 我甚至为在内部提出这个想法而感到羞愧)。那就是将所有头文件移到 virt/kvm 下, 在全局头文件路径中添加, virt/kvm/include 到全局头文件路径中, 然后让 KVM x86 在配置默认为隐藏 virt/kvm/include。

我讨厌这个想法因为它开创了一个不好的先例,需要大量的文件移动, 而不会给其他架构带来任何好处。我希望用 #ifdef __KVM__ 来保护 KVM 的内部结构,可以让我们慢慢地把代码整理干净, 以便有一天 KVM 只向内核的其他部分暴露少量的 API。


http://www.kler.cn/a/147984.html

相关文章:

  • C++算法练习-day40——617.合并二叉树
  • HTTP常见的状态码有哪些,都代表什么意思
  • 随时随地编码:香橙派Zero3上安装Code Server远程开发指南
  • vue2.7.14 + vant + vue cli脚手架转vite启动运行问题记录
  • 力扣104 : 二叉树最大深度
  • 丹摩征文活动|丹摩智算平台使用指南
  • 【Qt】之QSet使用
  • 小程序----使用图表显示数据--canvas
  • VMware虚拟机网络配置详解
  • echarts 几千条分钟级别在小时级别图标上展示
  • 【开源】基于Vue和SpringBoot的农家乐订餐系统
  • Python基础:标准库概览
  • 汇编语言指令大全30条
  • 二百零八、Hive——HiveSQL异常:Select查询数据正常,但SQL语句加上group by查询数据为空
  • redis的高可用(主从复制和哨兵模式)
  • 【go入门】表单
  • 基于OpenCV+YOLOv5实现车辆跟踪与计数(附源码)
  • MySOL常见四种连接查询
  • NX二次开发UF_CURVE_ask_spline_feature 函数介绍
  • 从范式标准谈一下OLTP和OLAP的区别
  • 1panel可视化Docker面板安装与使用
  • Flutter 桌面应用开发之读写Windows注册表
  • 记录一次内存泄漏排查历程
  • 利用python对数据进行季节性和趋势拆解
  • bitnami Docker 安装ELK
  • web:[ZJCTF 2019]NiZhuanSiWei1