首页/新闻资讯/正文详情

QEMU ACPI 内存热插拔接口规范详解:IO 端口协议、事件语义与源码实现

发布时间:2026/9/23 2:46:56 来源:云帆数科 栏目:资讯中心
QEMU ACPI 内存热插拔接口规范详解:IO 端口协议、事件语义与源码实现
虚拟化硬件仿真【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址https://gitcode.com/gh_mirrors/qe/qemu点击查看免费下载导读本文基于 QEMU 官方接口规范文档 docs/specs/acpi_mem_hotplug.rst完整讲解 QEMU 与 ACPI BIOS 之间内存热插拔Memory Hotplug的底层通信协议。文章首先给出 IO 端口 0xa00-0xa17 的逐字节寄存器布局与读写语义然后结合 hw/acpi/memory_hotplug.c 与 include/hw/acpi/memory_hotplug.h 的源码实现剖析 QEMU 侧状态机、ACPI AML 代码生成与热移除事件流。读者读完本文后将能准确理解 QEMU 内存热插拔的 ACPI 接口全貌并可直接对照源码与 docs/memory-hotplug.txt 中的 QMP/HMP 实际操作命令进行联调。1. 协议概览GPE.3 与内存热插拔 IO 区QEMU 的内存热插拔功能自 v2.1.0 引入。从 ACPI 视角看GPE.3 中断事件General Purpose Event bit 3被专门保留用于通知 OSPM操作系统电源管理即 guest 内 ACPI 驱动内存热添加hot-add与热移除hot-remove事件。当 QEMU 检测到新的内存设备插入、或管理端发起移除请求时都会通过该 GPE 向 guest 发出系统控制中断SCIOSPM 随后通过扫描内存热插拔 IO 区域来定位发生事件的设备槽位。与 GPE.3 配套的是一个独占的 IO 端口区域地址范围0xa00-0xa17共 24 字节支持 1-4 字节访问。该区域在源码中的定义如下include/hw/acpi/memory_hotplug.h 定义了MEMORY_HOTPLUG_IO_LEN 24即 IO 区域总长度hw/acpi/memory_hotplug.c 通过acpi_memory_hotplug_ops注册读写回调valid.min_access_size 1、max_access_size 4与规范中1-4 字节访问完全一致字节序为DEVICE_LITTLE_ENDIANhw/acpi/memory_hotplug.c 的acpi_memory_hotplug_init()将上述 IO 区域注册为acpi-mem-hotplug其槽位数取自machine-ram_slots即启动参数-m中的slotsN若为 0 则整个热插拔功能不注册。该 IO 区域在不同机器类型中的挂载位置不同可从源码调用点确认i440fx 挂载于 PIIX4 ACPI 设备hw/acpi/piix4.c、ICH9 挂载于 LPC PCI 的 IO 空间hw/acpi/ich9.c、GEDGeneric Event Device机器使用内存容器区域hw/acpi/generic_event_device.c。2. 读访问行为QEMU - OSPM对 0xa00-0xa17 区域的读操作返回当前选中槽位由写操作设置的 selector 决定所对应的内存设备属性。规范定义了以下读偏移偏移长度含义0x0-0x34 字节内存设备物理地址低 32 位Lo part0x4-0x74 字节内存设备物理地址高 32 位Hi part0x8-0xb4 字节内存设备大小字节低 32 位0xc-0xf4 字节内存设备大小字节高 32 位0x10-0x134 字节内存设备 proximity domainNUMA 节点供_PXM方法使用0x141 字节内存设备状态字段status bits0x15-0x173 字节保留reserved2.1 状态字段0x14位定义偏移 0x14 的读回值按位定义如下bit 0设备已启用enabledguest 可以使用该内存设备bit 1设备插入事件insert event用于标识一个尚未向 OSPM 发出 Device Check 事件的设备该位仅在 bit 1 置位时有效原文此处语义为用于区分未发出 device check 事件的设备规范行文如此实际由 OSPM 消费bit 2设备移除事件remove event用于标识一个尚未向 OSPM 发出 Eject Request 请求的设备bit 3-7保留位OSPM 必须忽略。2.2 源码实现对照上述读语义在 hw/acpi/memory_hotplug.c 的acpi_memory_hotplug_read()中逐偏移实现0x0/0x4读取 DIMM 的PC_DIMM_ADDR_PROP属性物理地址低/高 32 位0x8/0xc读取PC_DIMM_SIZE_PROP大小低/高 32 位0x10读取PC_DIMM_NODE_PROPNUMA 节点号0x14将MemStatus结构中的is_enabled、is_inserting、is_removing三个布尔值按 1/2/4 位打包返回其余偏移返回~0全 1。MemStatus结构体在 include/hw/acpi/memory_hotplug.h 中定义包含dimm关联的设备对象、is_enabled、is_inserting、is_removing、ost_event、ost_status六个字段是 QEMU 侧每个内存槽位的完整状态载体。3. 写访问行为OSPM - QEMU对 0xa00-0xa17 区域的写操作用于选择槽位、上报 OST 事件/状态码、以及触发设备移除。规范定义的写偏移如下偏移长度含义0x0-0x34 字节内存设备槽位选择器slot selector选中活动内存设备此后对该区域其他寄存器的访问都作用于该设备0x4-0x74 字节OSPM 上报的_OST事件码event code0x8-0xb4 字节OSPM 上报的_OST状态码status code0xc-0x138 字节保留写入被忽略0x141 字节内存设备控制字段control bits3.1 控制字段0x14位定义bit 0保留。OSPM 在写入前必须将其清零。规范特别强调由于 2.4 之前的版本存在 BUG写入其他字段时该位不会被清除因此该位必须保持保留状态不得尝试复用bit 1置 1 清除选中设备的插入事件。OSPM 在为其发出 Device Check 事件后写入bit 2置 1 清除选中设备的移除事件。OSPM 在为其发出 Eject Request 请求后写入bit 3置 1 发起设备弹出initiates device eject。OSPM 触发内存设备移除并调用_EJ0方法时写入bit 4-7保留OSPM 在写入前必须清零。3.2 越界槽位行为规范明确选择超出当前范围的设备槽位slot selector 越界不会对平台产生任何副作用——对未在上述文档中列出的内存热插拔寄存器进行写访问被直接忽略对未列出的寄存器进行读访问返回全 1所有位均为 1。源码佐证acpi_memory_hotplug_read()中当mem_st-selector mem_st-dev_count时直接return 0并记录 tracehw/acpi/memory_hotplug.c而 default 分支返回~0hw/acpi/memory_hotplug.c写路径则在 selector 越界时直接返回hw/acpi/memory_hotplug.c。3.3 写路径源码对照acpi_memory_hotplug_write()hw/acpi/memory_hotplug.c实现如下关键逻辑偏移 0x0保存data到mem_st-selector完成槽位选择偏移 0x4保存 OST 事件码到mdev-ost_event对值为 1/3 的事件目前仅留有 TODO 注释未做额外处理偏移 0x8保存 OST 状态码到mdev-ost_status并构造ACPIOSTInfo通过qapi_event_send_acpi_device_ost()向管理端发送ACPI_DEVICE_OST QMP 事件偏移 0x14按优先级处理清除插入事件bit 1、清除移除事件bit 2、触发弹出bit 3。弹出路径校验is_enabled后通过qdev_get_hotplug_handler()拿到热插拔控制器并调用hotplug_handler_unplug()失败时发送DEVICE_UNPLUG_GUEST_ERROR事件成功则object_unparent()删除设备并发送设备删除事件。由此可以看到写偏移 0x14 是 QEMU 侧唯一主动动作的入口OSPM 的每一次_EJ0调用最终都收敛到这一处写操作。4. 内存热移除流程时序图规范给出了完整的内存热移除hot remove流程涵盖 QEMU、OSPM、Guest OS 三方协作。以下为原文流程图的忠实还原------------- ----------------------- ------------------ | 1. QEMU | | 2. QEMU | |3. QEMU | | device_del ---- device unplug request -----Send SCI to guest,| | | | cb | |return control to | | | | | |management | ------------- ----------------------- ------------------ --------------------------------------------------------------------- --------------------- ------------------------- | OSPM: | remove event | OSPM: | | send Eject Request, | | Scan memory devices | | clear remove event ------------- for event flags | | | | | --------------------- ------------------------- | | ---------v-------- ----------------------- | Guest OS: | success | OSPM: | | process Ejection ----------- Execute _EJ0 method, | | request | | set eject bit in flags| ------------------ ----------------------- |failure | v v ------------------------ ----------------------- | OSPM: | | QEMU: | | set OST event status | | call device unplug cb | | fields | | | ------------------------ ----------------------- | | v v ------------------ ------------------- |QEMU: | |QEMU: | |Send OST QMP event| |Send device deleted| | | |QMP event | ------------------ | | -------------------该流程与源码回调一一对应管理端执行device_del后QEMU 调用acpi_memory_unplug_request_cb()hw/acpi/memory_hotplug.c将对应槽位is_removing置真并通过acpi_send_event(..., ACPI_MEMORY_HOTPLUG_STATUS)触发 GPE.3 向 guest 发送 SCIOSPM 收到中断后扫描各内存设备的移除事件标志对应 AMLMSCN扫描方法对置位槽位发出 Eject Request 通知并写控制字段 bit 2 清除移除事件Guest OS 处理弹出请求成功后将调用_EJ0方法——即写控制字段 bit 3触发 QEMU 侧弹出逻辑失败则通过_OST写 OST 事件/状态码上报失败原因QEMU 侧发送ACPI_DEVICE_OSTQMP 事件弹出成功后 QEMU 调用acpi_memory_unplug_cb()hw/acpi/memory_hotplug.c将is_enabled置假、dimm置空并向管理端发送设备删除 QMP 事件管理端随后可执行object_del释放内存后端。5. 底层机制AML 代码生成与槽位状态机5.1 ACPI 表生成QEMU 的内存热插拔 AML 由build_memory_hotplug_aml()hw/acpi/memory_hotplug.c动态生成核心内容包括一个PNP0A06内存热插拔控制器设备MHPD声明_CRS资源模板与HPMROperationRegionIO 或 MMIO 方式由AmlRegionSpace rs参数决定一个PNP0A06的 DIMM 设备容器\_SB.MHPC声明MDNR槽位数量、MLCK互斥锁以及完整的字段布局MRBL/MRBH/MRLL/MRLH/MPX/MES/MINS/MRMV/MEJ/MSEL/MOEV/MOSCMSCN扫描方法循环所有槽位对插入事件置位的槽位发出 Device Check值 1通知、对移除事件置位的槽位发出 Eject Request值 3通知并清除对应事件位——这正是 OSPM 收到 GPE 后执行的入口hw/acpi/memory_hotplug.c每个槽位对应一个MP%02X设备PNP0C80其_CRS/_STA/_PXM/_OST/_EJ0方法统一委托给容器内的共享方法MCRS/MRST/MPXM/MOST/MEJ0访问前均获取MLCK互斥锁以保证并发安全hw/acpi/memory_hotplug.cMTFY通知分发方法按槽位索引将Notify()定向到对应MP%02X设备。该函数由各平台 ACPI 构建代码调用x86 的 DSDThw/i386/acpi-build.c、ARM virthw/arm/virt-acpi-build.c与 loongarch virthw/loongarch/virt-acpi-build.c。若传入event_handler_method如 x86 的 GPE 处理方法还会生成调用MSCN的事件处理方法将 GPE 事件与扫描逻辑绑定。5.2 热插状态机与迁移QEMU 侧每个槽位的状态流转通过四个回调维护acpi_memory_plug_cb()设备插入时置is_enabled true若dev-hotplugged为真即运行期热插而非启动时冷插则置is_inserting true并发送 GPEhw/acpi/memory_hotplug.cacpi_memory_unplug_request_cb()置is_removing true并发送 GPEacpi_memory_unplug_cb()清is_enabled与dimm引用acpi_memory_ospm_status()将全部槽位的 OST 信息汇集成ACPIOSTInfo列表供query-acpi-ospm-status类 QMP 命令查询。值得注意的是MemStatus中的is_removing字段被注释为设备已被请求弹出但该字段未纳入迁移状态vmstate_memhp_sts只迁移is_enabled、is_inserting、ost_event、ost_statushw/acpi/memory_hotplug.cis_removing属于运行期瞬时状态。此外当平台未启用内存热插拔时hw/acpi/acpi-mem-hotplug-stub.c 提供了全部接口的空实现stub保证构建与调用的一致性。6. 联调实践从 QMP 命令到 ACPI 事件接口规范之外内存热插拔的完整使用路径可参考 docs/memory-hotplug.txt。核心要点如下启动参数-m [size]megs[,slotsn,maxmemsize]。其中slots决定热插槽位数即ram_slots直接决定 IO 区域中可寻址的设备数maxmem决定 guest 最大可扩展内存。示例qemu [...] -m 1G,slots3,maxmem4G热添加通过两个 HMP 命令配合完成——(qemu) object_add memory-backend-ram,idmem1,size1G (qemu) device_add pc-dimm,iddimm1,memdevmem1设备插入后QEMU 的acpi_memory_plug_cb()会置插入事件位并经 GPE.3 通知 guestOSPM 扫描后完成内存上线。文件后端如 hugetlbfs 大页可改用memory-backend-file并指定mem-path。热移除同样需要两个命令——(qemu) device_del dimm1 (qemu) object_del mem1device_del触发的正是第 4 节流程图中第 1-2 步acpi_memory_unplug_request_cb与 GPE 通知OSPM 完成 eject 握手后 QEMU 才真正销毁设备并向管理端发送删除事件随后方可安全执行object_del释放后端。7. 小结QEMU 的 ACPI 内存热插拔接口是一套设计紧凑的 IO 端口协议通过 0xa00-0xa17 区域内写选择器 读写设备属性/状态的方式配合 GPE.3 中断、MSCN扫描方法与_EJ0/_OST方法实现了 guest 与 QEMU 之间完整的热添加、热移除握手。规范中关于保留位尤其 2.4 前 BUG 的历史包袱、越界槽位读全 1、写忽略的容错约定都在 hw/acpi/memory_hotplug.c 的读写回调中得到了逐字落实。理解这份规范是调试 guest 内存热插拔行为、扩展新平台 ACPI 构建如新增build_memory_hotplug_aml调用点或深入 OSPM 侧驱动的必备基础。赞分享虚拟化硬件仿真【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址https://gitcode.com/gh_mirrors/qe/qemu点击查看免费下载相关推荐QEMU 与 ACPI BIOS 的 NVDIMM 接口深度解析_DSM/_FIT 通信协议与 QEMU 实现原理QEMU 与 ACPI BIOS 的 NVDIMM 接口深度解析_DSM/_FIT 通信协议与 QEMU 实现原理 NVDIMM非易失性内存从 ACPI虚拟化硬件仿真QEMU sPAPR 动态重配置DRC机制完全解析设备树接口、RTAS 调用与热插拔事件实现QEMU sPAPR 动态重配置DRC机制完全解析设备树接口、RTAS 调用与热插拔事件实现 导读 sPAPRpSeries客户机依赖一套名为动态重虚拟化硬件仿真MusicFree插件协议详解理解IPlugin接口设计与实现MusicFree插件协议详解理解IPlugin接口设计与实现 引言插件化架构的革命性优势 你是否曾经遇到过这样的困境喜欢的音乐平台突然下架了某首歌曲或音视频移动开发插件系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

宽带路由器是什么?前端老鸟的避坑速查手册
宽带路由器是什么?前端老鸟的避坑速查手册

宽带路由器是什么?前端老鸟的避坑速查手册 版本升级后 API 全变了,这种崩溃感谁懂?就像你刚把宽带路由器拆下来换根线,发现背后的接口协议全改了,代码跑不通,网络也断片。这时候,你需要的不是百度搜一堆废话,而是一份能直接救命的 速查手册… · 2026/9/23 2:46:50

PHPStan 错误标识符 class.extendsInternalClass 全解析:识别并修复继承 @internal 类的代码
PHPStan 错误标识符 class.extendsInternalClass 全解析:识别并修复继承 @internal 类的代码

开发工具代码质量静态分析 【免费下载链接】phpstan PHP Static Analysis Tool - discover bugs in your code without running it! 项目地址: https://gitcode.com/gh_mirrors/ph/phpstan 点击查看 免费下载 导读 class.extendsInternalClass 是 PHPStan 在启用 … · 2026/9/23 2:46:50

FineReport替代方案迁移指南:资产盘点、路线与校验解析
FineReport替代方案迁移指南:资产盘点、路线与校验解析

有些系统,你平时不会觉得它有多重,直到某天打开邮箱续费报价单的价格比去年又上浮两成,或者收到一份关于国产化兼容性检查的表格,再或者新来的技术负责人随口问了一句“这一套报表平台到底占了多少服务器资源”,你才意… · 2026/9/23 2:46:50

3天搞定中台之战最新消息入门到精通避坑指南
3天搞定中台之战最新消息入门到精通避坑指南

3天搞定中台之战最新消息入门到精通避坑指南 配置环境就卡半天?别急,这行老代码我写了十年,今天把中台之战最新消息的底层逻辑拆给你看。很多刚接触中台架构的朋友,往往在搭建本地开发环境时陷入泥潭,依赖冲突、端口占用、配置漂移,搞得人怀疑人生。其… · 2026/9/23 4:16:49

多智能体系统实战:角色分工、协作机制与LangGraph编排经验
多智能体系统实战:角色分工、协作机制与LangGraph编排经验

1. 从单兵作战到团队协同:为什么单智能体撑不住复杂任务我最早接触 Agent 开发的时候,和大多数人一样,都是从单智能体起步的。一个 LLM 加上几个工具函数,套一个 ReAct 循环,能查天气、能算数学、能搜网页,… · 2026/9/23 4:16:49

3个坑让你代码跑不通?英雄连2指挥官实战项目选型指南
3个坑让你代码跑不通?英雄连2指挥官实战项目选型指南

3个坑让你代码跑不通?英雄连2指挥官实战项目选型指南 复制来的代码跑不通,报错日志一片红,改了一晚上还没调好?这是很多开发者在接手【英雄连2指挥官】相关【实战项目】时的真实噩梦。别急着骂系统,大概率是你没搞懂底层通信协议和状态同步机制。很多… · 2026/9/23 4:16:49

从像素匹配到语义理解:以图搜图工具与大模型agent实战指南
从像素匹配到语义理解:以图搜图工具与大模型agent实战指南

以图搜图这个功能,看起来不过是把一张图丢进搜索框、敲一下回车,但真到用的时候你会发现,工具选对和选错,结果完全是两个世界。我从早年用TinEye追盗图、到后来靠必应识图挽救一批低分辨率老照片、再到最近用CLIP和向量数据库自己… · 2026/9/23 4:16:43

祝福前任的话各自安好最佳实践源码拆解
祝福前任的话各自安好最佳实践源码拆解

祝福前任的话各自安好最佳实践源码拆解 很多开发者刚学完 Python 或 Java 基础语法,脑子里全是 if-else 和循环,但真让你动手搭个完整项目,立马卡壳。这不是你笨,是缺乏 最佳实践… · 2026/9/23 4:16:36

基于CNN的驾驶员疲劳检测与预警系统:从模型到部署
基于CNN的驾驶员疲劳检测与预警系统:从模型到部署

简介:这份资源是面向高校计算机相关专业学生的Python毕业设计完整项目,主题为基于卷积神经网络的人脸识别驾驶员疲劳检测与预警系统,适合用作毕业设计、期末大作业或课程设计,也适合想入门深度学习与计算机视觉实战的初学者。压缩… · 2026/9/23 4:16:36

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码