x86机器上的不同CPU可以具有不同的本地APIC寄存器MMIO基址吗?

joz*_*joz 5 x86 intel interrupt pci

英特尔手册称本地APIC寄存器的存储器映射到4KB区域,默认地址为FEE00000H.可以使用IA32_APIC_BASE MSR 修改此地址.

引用SDM第3卷,第10.4.5节

Pentium 4,Intel Xeon和P6系列处理器允许通过修改IA32_APIC_BASE MSR的24位基址字段中的值,将APIC寄存器的起始地址从FEE00000H重定位到另一个物理地址.提供APIC架构的这种扩展以帮助解决与现有系统的存储器映射的冲突,并允许MP系统中的各个处理器将其APIC寄存器映射到物理存储器中的不同位置.

  1. 是否有可能同一台机器上的不同CPU可以为本地APIC提供不同的基址?比如说,CPU 0决定保持在FEE00000H,但CPU1移动到FEF00000H

  2. 如果满足以上条件,PCI MSI中断如何工作?如果不同的CPU可以具有不同的本地APIC地址,则MSI消息地址对于不同的CPU意味着不同.

Mar*_*oom 5

  1. 是的,正如您所引用的,英特尔手册明确允许这样做。但是,由于 P6 架构,APIC 访问由处理器内部处理,没有可见的外部总线周期。

    对于 P6 系列、奔腾 4 和英特尔至强处理器,APIC 在内部处理对 4 KB APIC 寄存器空间内地址的所有内存访问,并且不产生外部总线周期。

    因此,重新映射只是为了避免与旧设备发生冲突。
    今天,这是一种罕见的情况,因为从 4 GiB - 18 MiB 到 4GiB - 17 MiB(开放式)的区域是为 MSI 保留的。

  2. 从 PCI 的角度来看,MSI 非常简单:向地址写入一个值。
    地址和值都通过MSIMSI-x能力结构(值分别为 05h 和 11h)在设备的 PCI 地址空间中配置。
    只有MSI-x允许 32 位数据。

    PCI 规范有意通用,地址和数据对形成唯一的“中断向量”,即标识中断的值。
    第一个设备实际上具有非常有限的MESSAGE_DATA领域扩展,只有几个低位可写。
    然而,在 x86 架构中,地址和数据采用特定的形式。
    这些在 Intel 手册 3A 的 10.11 节中有描述。

    Address format
    
    31   20  19            12  11         4   3    2  0
    0FEEH    Destination ID    Reserved   RH  DM   XX
    
    Data format
    
    63     16   15   14   13     11  10          8  7   0
    Reserved    TM   LM   Reserved   Delivery mode  Vector
    
    Run Code Online (Sandbox Code Playgroud)

    我们可以看到这些格式与 MSI 和 MSI-x 都兼容,但更重要的是地址的前缀为 0feeh,使其至少为 0fee00000h,即 4 GiB - 18 MiB。
    该区域用于通过主机到 PCI 即根联合体(在 CPU 芯片上或在 PCH 中)或 MCH(对于旧平台)路由 MSI。
    地址决定了哪组处理器将处理 MSI(确切的规则可以在 Intel 的手册中找到)。

    即使所有本地APIC都映射到同一个地址,选择一组处理器也是目的地址的格式, x86的MSI的设计是为了让OS可以将中断定向到特定的处理器。
    所以,不,MSI 地址对每个 CPU 都意味着相同的事情,因为处理 PCI 写入的不是 CPU,而是主机到 PCI 桥接器,并且该芯片是系统范围的。


Host-to-PCI 如何知道将 MSI 发送到哪里?

地址有一个目的地 ID(英特尔术语中的 MDA - 消息目的地地址),连同一些元信息,足以在“APIC 总线”中路由消息 - 一个逻辑结构,实现定义(可能是带有一些QPI/UPI/DMI 段),连接 APIC 和 APIC 集群。
与网络数据包的路由方式非常相似。

MSI 范围和默认的本地 APIC 范围是否重叠?

是的,但是这些范围存在于两个不同的“地址空间”中:本地 APIC 范围存在于每个内核中,或者最多存在于非内核中(但不在系统代理中),MSI 范围存在于主机到 PCI 芯片中。
从针对 MSI 范围的 PCI 总线写入永远不会离开主机到 PCI 桥,而对本地 APIC 范围的访问永远不会离开内核。
这两个域之间的通信是通过 APIC 总线进行的。


附录

评论中出现了一个问题:在启用了VT-d的系统(本质上是一个 IOMMU)中,为什么需要中断重映射 (IR) 机制?为什么 DMA 重映射不够用?

由于 MSI(-X) 是从设备启动的内存写入,因此 DMA 重新映射应该足以重新映射中断。

DMA 重新映射转换地址,而 MSI(-X) 由目标地址(传送中断的目的地)和数据(指定要传送的中断类型)组成。
为了让软件完全控制要传送的中断,VT-d 规范为 MSI(-X) 引入了一种新格式:可重映射格式
这个想法类似于 CPU 使用的标准内存转换:MSI(-X) 只具有必要的信息来索引具有中断目标和类型的完整定义的表。

新格式是:

可重映射的 MSI(-X) 格式

基本上有三个字段:

  • HandleSub handle领域
    他们被添加在一起,得到的索引,IR表(IRT)。它们已分开,因为Sub handle位于数据寄存器中(而Handle位于地址寄存器中),这允许使用单个地址和多个数据值配置设备(显然这是必要的要求)。
  • SHV告诉现场如果Sub handle字段是有效的,否则,将零代替。

请注意,索引是一个 16 位值。

找到索引后,它将用于检索 IRT 条目 (IRTE),其中包含传递中断的所有信息 - 包括用于验证中断源的某些字段。

请注意,旧版(兼容格式)MSI(-X)永远不会重新映射,无论是通过还是被阻止(取决于软件如何配置转换器)。