1. 简介

本章介绍操作处理器的状态扩展 ( SSE 状态 , XMM 寄存器 , MXCSR ) 和其他的处理器扩展状态的指令集扩展的系统编程特性 .
操作 SSE 状态的指令集扩展包括 streaming SIMD extensions ( SSE ) , SSE2 , SSE3 , supplemental SSE3 ( SSSE3 ) , SSE4 , 统称为 SSE 扩展 , 对应的指令称作 SSE 指令 .

XSAVE 特性集指 Intel 架构的扩展 , 允许系统可执行程序实现对于多处理器扩展状态和 FP / SSE 状态的支持 , 这些状态可能逐渐引入 , 每次引入一个状态时不需要修改系统可执行程序 .
XSAVE 特性集提供了机制可以枚举支持的扩展状态 , 开启某一些或全部状态供软件使用 , 提供了指令保存 / 恢复状态 , 枚举保存到内存时的状态布局 .
XSAVE / XRSTOR 指令是 XSAVE 特性集的一部分 , 在 FP / SSE 状态后引入 , 但是可以用于管理传统的 FP / SSE 状态和处理器扩展状态 .

2. 向 OS 提供 SSE 扩展支持

OS 必须执行以下步骤初始化处理器使用 SSE 扩展指令 :

  1. 向 OS 添加对于 SSE 指令的支持
  2. 检查 CPU 是否支持 SSE 指令
  3. 初始化 SSE 扩展 , 以便应用程序使用
  4. 提供 non-numeric 异常处理函数给 SSE 指令产生的异常
  5. 提供处理函数给 SIME 浮点异常 ( #XM )

3. SSE 扩展的模拟

Intel 64 和 IA-32 架构不支持 SSE 指令的模拟 , 如果 CR0.EM = 1 时执行 SSE 指令 , 产生无效的操作码异常 ( #UD ) .

4. 保存和恢复 SSE 状态

SSE 状态由 XMM 和 MXCSR 寄存器组成 , Intel 推荐使用下列方法保存和恢复状态 :

  • 执行 FXSAVE 指令保存 XMM 和 MXCSR 到内存
  • 执行 FXRSTOR 指令从内存中恢复 XMM 和 MXCSR 寄存器

也可以单独保存 XMM 和 MXSCR :

  • 执行 MOVDQ 指令保存 XMM 的内容到内存
  • 执行 STMXCSR 指令保存 MXSCR 的内容到内存

然后通过下列方式恢复寄存器的内容 :

  • 执行 MOVDQ 指令从内存加载 XMM 寄存器的内容
  • 执行 LDMXCSR 指令从内存恢复 MXCSR 寄存器的内容

5. 设计 OS 切换任务或上下文时保存 x87 FPU , SSE 和扩展状态的工具

x87 FPU 和 SSE 状态由 x87 FPU , XMM 和 MXCSR 寄存器的状态组成 , FXSAVEFXRSTOR 可以快速保存和恢复这个状态 . XSAVE 也可以用于保存 FP 和 SSE 状态以及其他的扩展状态 .

如果任务或上下文的切换工具重新编写 , 可以采取下列方式之一 , 利用 FXSAVEFXRSTOR 指令或 XSAVE 特性保存和恢复 x87 FPU 和 SSE 状态 :

  • OS 可以要求应用程序负责切换任务前保存状态 , 恢复任务时还原状态 . 这种方法适用于合作的多任务 OS , 应用决定何时发生任务切换 , 在切换前保存状态 .
  • OS 负责保存状态 , 作为任务切换过程的一部分 , 并且在恢复执行任务时还原寄存器状态 . 适用于抢占式多任务 OS , 应用无法知晓何时被抢占 , 不能提前准备任务切换 .
  • OS 负责保存状态 , 作为任务切换过程的一部分 , 但是推迟状态的还原 , 知道操作状态的指令由新任务真正执行 . 这种方法称作懒恢复 ( lay restore ) .
    使用 XSAVE 特性时 , 不推荐在上下文切换中使用懒恢复机制 .

CR0.TS 标志允许 OS 推迟保存 / 恢复 x87 FPU 和 SSE 状态 , 直到新任务执行了访问这个状态的指令 . 设置这个标志时 , 处理器监测 x87 FPU , MMX , SSE 指令的指令流 , 发现这些指令之一时 , 在执行指令前产生一个设备不可用异常 ( #NM ) .
#NM 异常的处理函数可以用于保存前一个任务的 x87 FPU 和 SSE 状态 , 并加载当前任务的 x87 FPU 和 SSE 状态 . 如果新任务没有 x87 FPU , MMX 或 SSE 指令 , 不会产生 #NM 异常 , 也不会不必要的保存任务状态 .

7. XSAVE 特性集和处理器扩展状态的管理

XSAVE 特性集包括 :

  • 现有和未来处理器状态扩展的一个可扩展的数据布局
  • 特性枚举的 CPUID 扩展
  • 用于开启每个处理器的扩展状态的控制寄存器扩展和专用寄存器
  • 从 XSAVE 区域保存或恢复状态的指令

OS 可以使用 XSAVE 特性集管理 FP / SSE 状态和处理器扩展状态 , OS 需要执行一些步骤支持传统的 FP / SSE 状态和处理器扩展状态 :

  1. 检查处理器支持 XSAVE 特性集
  2. 确定 OS 要开启的 XSAVE 管理特性集 , 计算上下文切换和其他流中保存 / 恢复状态需要的缓冲区大小
  3. 开启 XSAVE 特性集和 XSAVE 管理的特性
  4. 提供 XSAVE 管理的特性状态组件的初始化
  5. 提供每个 XSAVE 管理的特性产生的异常的处理函数

8. XSAVE 特性集和 FXSAVE / FXRSTOR 的协同工作

FXSAVE 指令写入 x87 FPU 和 SSE 状态信息到一个 512 byte FXSAVE 保存区域 , FXRSTOR 从 FXSAVE 区域恢复处理器的 x87 FPU 和 SSE 状态 .
XSAVE 特性集支持 x87 FPU 和 SSE 状态使用和 FXSAVE 区域相同的布局 , 使得 FXSAVE 和 XSAVE , FXRSOTR 和 XRSTOR 协同工作 .
XSAVE 特性集允许系统软件独立于 x87 FPU 状态管理 SSE 状态 , 因此使用 FXSAVEFXRSTOR 管理 x87 FPU 和 SSE 状态的系统软件能够以系统的和向前的方式转向 XSAVE 特性集 , 从而管理 x87 FPU , SSE 和其他处理器扩展状态 .

9. XSAVE 特性集和处理器 supervisor 状态管理

supervisor 状态只能在 ring 0 访问 , XSAVE 特性集的一个扩展允许通过 XSAVE 特性集管理 supervisor 状态 . supervisor 状态扩展包括以下 :

  • 枚举管理员状态集和 XSAVE 特性集可以管理的状态集大小的 CPUID 扩展
  • 一个新的开启 XSAVE 特性集的 MSR IA32_XSS , 管理一个或多个被枚举的管理员状态
  • 一对新的特权保存 / 恢复指令 , XSAVESXRSTORS , 保存 / 恢复管理员状态和其他 XSAVE 管理的特性状态

XSAVE 管理的管理员状态由 IA32_XSS MSR 开启 , 而不是 XCR0 . IA32_XSS MSR 开启的管理员状态 :

  • 即使没有在 IA32_XSS MSR 开启 , 也可以通过其他机制访问 , 比如 RDMSR / WRMSR .
  • 保存 / 恢复状态时可能有其他影响 , 比如关闭 / 开启和状态相关的特性 .
  • 保存 / 恢复状态时可能产生 fault .
  • 恢复已经由特性相关的机制开启的管理员特性的状态时 , XRSTORS 可能 fault .

10. XSAVE 管理的特性的系统编程

10.1. Intel Advanced Vector Extensions ( Intel AVX )

Intel AVX 由 256-bit 和 128-bit 指令组成 , 操作 256-bit YMM 寄存器 , XSAVE 特性集可以用于保存和恢复这些寄存器的状态 .

支持 YMM 状态的处理器 , YMM 状态在所有模式下都存在 , 但是不同模式下访问 YMM 状态的指令接口可能不同 .

OS 支持 AVX 时 , 需要知晓下列事项 :

  • 以没有 SSE 状态的非压缩格式保存 / 恢复 AVX 状态 , 即使 MXSCR 不是 AVX 状态的一部分 , 也会保存 / 恢复 MXCSR . 使用压缩格式时不同 .
  • 少数指令 , 比如 VZEROUPPER / VZEROALL 可能操作 YMM 寄存器的未来扩展 .

OS 必须开启 YMM 状态管理 , 才能支持 AVX 和 256-bit 扩展 ; 否则执行 AVX 扩展指令会产生 #UD 异常 .

10.2. Intel Advanced Vector Extensions 512 ( Intel AVX-512 )

支持 Intel AVX-512 的处理器 , 扩展的处理器状态在所有模式下都存在 , 但是访问方式可能不同 .

OS 必须使用 XSAVE / XRSTOR / XSAVEOPT 指令管理 ZMM 和 opmask 状态 ; OS 必须开启 ZMM 和 opmask 状态管理 , 才能支持 Intel AVX-512 指令 , 否则产生 #UD 异常 .