news 2026/9/24 17:46:38

第 3 篇 · p2m 内存类型分类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第 3 篇 · p2m 内存类型分类

p2m 表项不只记"对应哪个 MFN",还带一个类型标签(p2m_type),决定访问它时的行为。这一篇把 Xen 的 p2m 类型讲透:完整枚举 + 各自用例,以及它们之上两个容易混淆的"分组/空间"概念——类型组掩码(把类型归类)和XENMAPSPACE(往 physmap 放页时的来源空间)。


1. p2m_type 是什么

Xen 的 p2m 表项 =MFN + 类型 + 权限。类型(p2m_type_t)告诉 Xen:当 guest 访问这个 GFN 时,该怎么处理缺页/写入/权限。

p2m[GFN] = { mfn, p2m_type, access_rights }

同一个 GFN,类型不同,行为天差地别:有的直接读写真实内存,有的一访问就 exit 给 qemu 模拟,有的写入时标脏。


2. 完整的 p2m 类型枚举(x86)

x86 的p2m_type_t一共 16 种(xen/arch/x86/include/asm/p2m.h):

类型含义典型用例
0p2m_ram_rw普通可读写 RAMguest 绝大多数常规内存
1p2m_invalid此处什么都没映射physmap 空洞;访问触发缺页
2p2m_ram_logdirty临时只读,写触发标脏热迁移追踪脏页
3p2m_ram_ro只读 RAM,写被静默丢弃只读区
4p2m_mmio_dm读写都交给 device model模拟设备寄存器(转 qemu)
5p2m_mmio_direct直通真实 MMIOPCI passthrough 的 BAR
6p2m_populate_on_demand空内存占位(PoD)超额分配 / 延迟落地(气球)
7p2m_grant_map_rw读写 grant 映射跨域共享(netfront/blkfront)
8p2m_grant_map_ro只读 grant 映射同上,只读
9p2m_ram_paging_out正在换出的内存mem paging
10p2m_ram_paged已换出mem paging
11p2m_ram_paging_in正在换入mem paging
12p2m_ram_shared可共享 / 已共享内存去重(CoW / mem sharing)
13p2m_ram_broken坏页硬件故障页,访问即崩 domain
14p2m_map_foreign映射另一个域的 RAM 页跨域直接映射
15p2m_ioreq_server交给 ioreq server 处理用户态设备模型介入的内存(如显存脏页跟踪)

小注:ARM 上 foreign 细分成p2m_map_foreign_rw/ro;x86 只有一个p2m_map_foreign,读写权限用访问位区分。


3. 类型分组:type 之上的"region"概念

Xen 内部几乎不逐个判断具体类型,而是把类型按位掩码归成,配一组p2m_is_*谓词来判断。这就是"每个 type 归属哪个类别"的 region 概念(asm/p2m.h):

组(掩码)大致包含谓词语义
P2M_RAM_TYPESram_rw / ro / logdirty / paging* / shared / ioreq_serverp2m_is_ram映射到真实机器帧
P2M_MMIO_TYPESmmio_dm / mmio_directp2m_is_mmio设备内存
P2M_GRANT_TYPESgrant_map_rw / rop2m_is_grantgrant 跨域映射
P2M_RO_TYPESlogdirty / ram_ro / grant_ro / sharedp2m_is_readonly只读,写需特殊处理
P2M_SPECIAL_TYPESgrant +p2m_map_foreign+ mmio_directp2m_is_special需专门访问器建立/拆除
P2M_PAGING_TYPESpaging_out / paged / paging_inp2m_is_paging换页中
P2M_POD_TYPESpopulate_on_demandp2m_is_pod按需填充占位
(单类)p2m_map_foreignp2m_is_foreign别的域的页

作用:建 EPT/NPT 表项、缺页处理、迁移、CoW、换页……都用这些统一判断,而不是写死某个类型。例如写一个p2m_is_readonly的页,会统一走"写处理":logdirty 标脏、grant_ro 丢弃、shared 破 CoW。新增/调整一个类型时,只要把它放进对的组,全套逻辑自动适配。


4. 另一个"空间"概念:XENMAPSPACE(来源空间)

type 描述的是"这个 GFN 现在是什么"。而当你要往 guest physmap 里放一个页时(XENMEM_add_to_physmap[_batch]),还要给一个space参数——告诉 Xen"这个页从哪来"。space 决定了 Xen 怎么取 MFN、以及最终装成哪种 p2m 类型(xen/include/public/memory.h):

XENMAPSPACE_*来源落成的 p2m 类型
shared_info0Xen 的 shared_info 页p2m_ram_rw
grant_table1grant 表页p2m_ram_rw
gmfn2本域已有的一个 GFN重定位,类型随源
gmfn_range3本域一段 GFN同上,批量
gmfn_foreign4另一个域的 GFNp2m_map_foreign(RAM)/p2m_mmio_direct(设备页)
dev_mmio5设备 MMIO 区(ARM)直通 MMIO

还有一个值为 6 的扩展 space,留到下一篇结合具体机制讲。

要点:space 是"入口/来源",type 是"结果/属性"。同一段 GFN 经不同 space 放进来,会得到不同的 type——例如经gmfn_foreign放进来的 RAM 页,落成的就是p2m_map_foreign。所以回答"每个 type 下有没有 space 概念":它俩是"入口→结果"的对应关系,而非从属关系,一张对照表就能把 space 和 type 串起来。

type / region / space / class 一图看清

把前面几节的四个概念放在一起,它们的关系是:

决定落成哪种

按位掩码归类

表级,与 type/space 正交

space(XENMAPSPACE)
放页时的『来源』
gmfn / gmfn_foreign / grant_table / dev_mmio ...

type(p2m_type)
单个表项的『属性』
16 种: ram_rw / mmio_* / grant_* / map_foreign ...

region(类型组)
P2M_*_TYPES + p2m_is_*
is_ram / is_mmio / is_grant / is_special ...

class(p2m_class)
整张表的『维度』
host / nested / altp2m

  • space → type:入口决定结果——同一 GFN 换个 space,落成的 type 不同。
  • type → region:每个 type 按掩码归入若干组,Xen 用p2m_is_*)统一判断,而非逐个类型。
  • class:是"这是哪张 p2m 表"的维度,和 type / space正交(日常用p2m_host)。

5. 跨域共享的两类 type:grant 与 foreign

5.1 为什么单独讲这两类

前面的 RAM/MMIO 类型都是"本域自己的内存"。而有两类 type 专门表示"这一页其实属于另一个域"——它们让同一块物理页同时出现在两个域里,是跨域零拷贝共享的地基,也是理解后续机制的关键,值得单独讲透。

先厘清:独占 vs 跨域、所有权 vs 映射,这是理解后续所有机制的基石,先分清两组概念:

  • 独占:一个 host 物理页(MFN)只出现在一个domain 的 physmap 里,只有它能访问——普通的p2m_ram_rw就是这样,每个 guest 的 RAM 都是分配给它私有的 MFN。
  • 跨域共享同一个 MFN 同时出现在多个 domain 的 physmap 里,于是这块真实物理内存能被多个域同时看到、访问。
独占: MFN_X ◄── domA 的某个 GFN (只有一条) 跨域: MFN_X ◄── domA 的 GFN ◄── domB 的 GFN (同一个 MFN,多条)

再区分"所有权"和"映射"——这点最容易混:

  • 所有权(owner):每个物理页永远只有一个 owner domainpage_get_owner),共享不改变所有权。
  • 映射(mapping):跨域做的是——在另一个域的 physmap 里也加一条指向这个 MFN 的项

所以准确的说法是:跨域 = 一个页仍归某一个域所有,但被"额外"映射进了别的域的地址空间。为防止 owner 在别人还用着时回收它,跨域映射会对该页get_page加一次引用计数,撤映射(remove_from_physmap)时再put_page释放。

下面两类 type,就是这种"额外映射"的两种建立方式,区别只在谁是 owner、谁主动、往哪个方向映射

5.2 为什么这是"虚拟化能用"的性能基石

跨域共享看着只是个内存技巧,实则决定了虚拟化 I/O 是"能跑"还是"慢到不能用"。先把两层分开:

  • CPU / 内存虚拟化(EPT/NPT 两级翻译)——靠硬件,本身没有拷贝问题,和共享无关,解决的是"能跑"。
  • I/O、设备、GPU 数据通路——这层才是"拷贝 vs 共享"的战场,决定"跑得快不快"。

设想没有共享的 PV 网络:guest 发一个包要先到 dom0 的 backend,backend 再交给网卡;收包反向再来一遍。每个包至少两次内存拷贝 + 跨域切换,10/40Gbps 下光拷贝就吃满 CPU 和内存带宽。grant table 的设计初衷正是干掉这次拷贝——backend 直接读写 guest 那块内存,包"零拷贝"地过去。这也是 Xen PV 驱动能接近裸机的关键。GPU 更极端:几十 GB 的显存 blob,任何一次拷贝都不可接受,所以必须让 host GPU 栈与 guest 共享同一份物理页——没有跨域共享,GPU 虚拟化根本无从谈起。

但共享有代价:它削弱隔离。这正是虚拟化设计的核心张力——

拷贝共享
性能好(零拷贝)
隔离强(各自独立)弱(同一页两个域都能碰)

所以下面 grant/foreign 才要那套授权 + 引用计数 + notifier + XSM 校验:本质是"在尽量不破坏隔离的前提下,换取零拷贝的性能"。跨域共享机制的全部复杂度,都是在这架天平上找平衡。

5.3 grant 映射(p2m_grant_map_rw/ro

  • 谁发起源域(内存拥有者)主动授权——它在自己的 grant table 里登记一条 grant entry(“允许 domX 访问我的第 N 页”),拿到一个 grant ref 交给对方。
  • 谁映射:被授权方拿着 grant ref 发 hypercall,把那一页映射进自己的physmap,落成p2m_grant_map_rw/ro
  • 方向:拥有者 → 授权给使用者。典型是 guest 把自己的收发缓冲授权给后端(netfront 授权给 dom0 的 netback)。
  • 一个细节:Xen 认为 grant 项"随时可能被源域撤回",所以p2m_is_valid特意不把 grant 算作 valid——用它的人必须容忍随时失效。

5.4 foreign 映射(p2m_map_foreign

  • 谁发起有特权的目标域(通常 dom0)主动把"另一个域的某个 GFN"塞进自己的physmap,落成p2m_map_foreign(内部走set_foreign_p2m_entry)。
  • 不需要源域授权:靠发起方的特权(配xsm_map_gmfn_foreign做 XSM 校验),源域甚至不感知。
  • 方向:使用者主动去"借"拥有者的页。典型是 dom0 的工具 / 设备模型要读写某个 guest 的内存。
  • 引用计数:映射时对源页get_page加引用,XENMEM_remove_from_physmap时释放——保证映射期间源页不被回收/搬走。

5.5 两者对比

grantforeign
谁主动源域授权目标域(特权)直接映射
需授权?需要(grant ref)不需要(特权 + XSM)
典型方向owner → useruser 主动借 owner
p2m 类型p2m_grant_map_rw/rop2m_map_foreign
建立入口grant map hypercallXENMAPSPACE_gmfn_foreign/set_foreign_p2m_entry
生命周期源域可随时撤显式 remove 前有效

两者本质相同——让同一块物理页同时落在两个域的地址空间里,实现跨域零拷贝;区别只在"谁发起、要不要授权、怎么维护一致性"。后面要讲的机制,正是选了foreign 这一支来扩展,原因也正是上表透露的:由特权方主动、不依赖源域配合、适合成片大范围映射。至于它在 foreign 之上具体加了什么,留到下一篇。


6. 再往上一层:p2m 的"类"(host / nested / altp2m)

type(项属性)、space(入口)都是单张表层面的。整张 p2m 表还分p2m_class_t):

  • p2m_host:正常的 guest p2m,落到 EPT/NPT;
  • p2m_nested:嵌套虚拟化里,L1 guest 给它的 L2 guest 用的 p2m;
  • p2m_alternate(altp2m):同一个 guest 的多份 p2m 视图,可运行时切换(安全监控、写保护等用)。

这是"表级"的 region 概念,和 type(项级)、space(入口)互相正交。日常内存虚拟化主要用p2m_host


7. 本篇小结 & 下一步

  • p2m 项 =MFN + 类型 + 权限;类型决定访问行为。
  • x86 共16 种p2m 类型,覆盖 RAM / MMIO / grant / foreign / paging / PoD / shared / broken / ioreq_server。
  • 跨域共享靠两类 typep2m_grant_map_*(源域授权)与p2m_map_foreign(特权域主动借)——它们让"同一物理页出现在两个域",是后续机制的地基。
  • 两个易混的"空间/分组"概念:①类型组掩码P2M_*_TYPES+p2m_is_*)是对"项属性"的分类;②XENMAPSPACE是"往 physmap 放页时的来源空间",决定落成哪种类型——space 是入口,type 是结果。
  • 再往上还有表级p2m_class(host / nested / altp2m)。

下一篇:04 · 跨域协作全景:一张 p2m 表的五种填法 —— 有了这张"类型 + space"地图,下一篇把p2m_map_foreign这条主线铺成完整全景:p2m 被填充的5 种情形(1 种单域基准 + 4 种跨域协作),讲清每种的方向、授权模型、以及用什么标识源页(GFN 还是 hva)。之后再逐个深入具体机制——hmem 从第 5 篇起。


关联阅读

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

Zoom视频会议软件电脑版下载安装教程

概述 Zoom 是一款跨平台云视频会议软件,支持 Windows、macOS、Linux、iOS、Android,提供高清视频会议、屏幕共享、文字聊天、会议录制、虚拟背景等功能。本文讲清电脑版下载安装、权限设置与核心功能。 一、下载与安装 从 Zoom 下载入口 获取安装包&…

作者头像 李华
网站建设 2026/9/24 17:45:28

【AI大模型进阶】整理你的 AI 工具集:构建属于你自己的 AI 开发百宝箱

【AI大模型进阶】整理你的 AI 工具集:构建属于你自己的 AI 开发百宝箱 这是【AI大模型进阶】系列第一百五十课,也是本系列算力工程、云端开发、模型训练运维板块的收官总结课。在前序149节课程中,我们从零入门,逐一掌握了云端算力租赁、SSH远程开发、Tmux终端保活、GPU状态…

作者头像 李华
网站建设 2026/9/24 17:44:20

函数:写一次代码,用一万次

如果你连函数都写不出来, 那么你根本就没有进入到这门学问的门槛里面去。函数, 它是编程里面的那个核心的抽象。你现在去写一个函数, 这就等于你去发明了一个新的动词。那其他的人, 包括那个未来的你自己在内, 也只需要去知道它是做什么事情的就行了。至于说它到底是怎么去做的…

作者头像 李华
网站建设 2026/9/24 17:40:38

ben skills

代码开发规范 不要为了测试便利在主业务代码中加入测试专用的注入点、分支或参数;应优先在测试代码中通过 mock 依赖或替换模块实现测试,保持主业务代码的可读性和职责纯粹。 开发前端代码时默认不添加无障碍属性(role、aria-* 等&#xff09…

作者头像 李华
网站建设 2026/9/24 17:40:38

春晚机器人火爆背后:AI大模型点燃黄金赛道,普通人也能抓住机遇!

春晚的机器人表演引发了人们对AI技术的关注。文章指出,AI和机器人已经进入普通人的生活,并推动了“机器人租赁”等新产业的发展。同时,AI行业的薪资水平也在不断提高,因为市场上对AI人才的需求远远大于供给。普通人可以通过学习实…

作者头像 李华
网站建设 2026/9/24 17:40:21

实操——修复OpenSSH远程代码执行漏洞

文章目录说明修复步骤1.安装telnet服务2.升级openssh2.1 **开始安装openssl****2.2 安装openssh**说明 首先openssh漏洞,需要升级openssh,所以在升级过程中我们是无法用ssh连接过去的;所以我们需要先安装telnet 来进行连接。 参考文章&…

作者头像 李华