应用程序数据完整性 (ADI)

SPARC M7 处理器增加了应用程序数据完整性 (ADI) 功能。ADI 允许任务在其地址空间的任何子集上设置版本标签。一旦启用了 ADI 并为任务的地址空间范围设置了版本标签,处理器会将这些范围内的内存指针中的标签与应用程序先前设置的版本进行比较。只有当给定指针中的标签与应用程序设置的标签匹配时,才允许访问内存。如果发生不匹配,处理器会引发异常。

任务必须执行以下步骤才能完全启用 ADI

  1. 设置用户模式 PSTATE.mcde 位。这充当任务整个地址空间的主开关,以启用/禁用任务的 ADI。

  2. 在与启用 ADI 的地址范围相对应的任何 TLB 条目上设置 TTE.mcd 位。MMU 仅检查设置了 TTE.mcd 位的页面上的版本标签。

  3. 使用 stxa 指令和 MCD 特定的 ASI 之一为虚拟地址设置版本标签。每个 stxa 指令为 ADI 块大小字节数设置给定的标签。必须为整个页面重复此步骤,以设置整个页面的标签。

平台的 ADI 块大小由虚拟机管理程序在机器描述表中提供给内核。虚拟机管理程序还提供虚拟地址中指定版本标签的最高位数。一旦为内存位置设置了版本标签,该标签将存储在物理内存中,并且相同的标签必须存在于呈现给 MMU 的虚拟地址的 ADI 版本标签位中。例如,在 SPARC M7 处理器上,MMU 使用位 63-60 作为版本标签,ADI 块大小与缓存行大小相同,为 64 字节。在某个内存范围内将 ADI 版本设置为(例如)10 的任务必须使用位 63-60 中包含 0xa 的虚拟地址访问该内存。

使用带有 PROT_ADI 标志的 mprotect() 在一组页面上启用 ADI。当任务第一次在一组页面上启用 ADI 时,内核会为该任务设置 PSTATE.mcde 位。内存地址的版本标签使用 ASI_MCD_PRIMARY 或 ASI_MCD_ST_BLKINIT_PRIMARY 通过 stxa 指令在地址上设置。ADI 块大小由虚拟机管理程序提供给内核。内核使用辅助向量以及其他 ADI 信息将 ADI 块大小的值返回给用户空间。内核提供以下辅助向量

AT_ADI_BLKSZ

ADI 块大小。这是 ADI 版本控制的粒度和对齐方式,以字节为单位。

AT_ADI_NBITS

VA 中 ADI 版本位的数量

重要提示

  • 0x0 和 0xf 的版本标签值是保留的。这些值与虚拟地址中的任何标签匹配,并且永远不会生成不匹配异常。

  • 版本标签是在用户空间的虚拟地址上设置的,即使标签存储在物理内存中。标签是在物理页面分配给任务并为其创建 pte 后在物理页面上设置的。

  • 当任务释放它设置了版本标签的内存页时,该页面将返回到空闲页面池。当此页面重新分配给任务时,内核会使用块初始化 ASI 清除该页面,这也将清除该页面的版本标签。如果分配给任务的页面被释放并重新分配回同一任务,则任务在该页面上设置的旧版本标签将不再存在。

  • 不会检测到非故障加载的 ADI 标签不匹配。

  • 内核不会为用户页面设置任何标签,并且设置任何版本标签完全是任务的责任。如果页面被交换到磁盘并重新交换回来,内核会确保保留版本标签。如果页面被迁移,它也会保留版本标签。

  • ADI 适用于任何大小的页面。用户空间任务在使用 ADI 时无需了解页面大小。它可以简单地选择一个虚拟地址范围,使用 mprotect() 在该范围内启用 ADI 并为整个范围设置版本标签。mprotect() 确保范围与页面大小对齐并且是页面大小的倍数。

  • ADI 标签只能在可写内存上设置。例如,ADI 标签不能在只读映射上设置。