openEuler qemu CPU热插

openEuler的qemu-4.1.0版本实现了aarch64架构的CPU热插拔功能。该功能涉及ACPI的MADT和DSDT表修改、GED事件模型、GICv3设备以及热插拔流程的调整。在ACPI方面,介绍了ACPI的结构、DSDT和MADT表的作用,以及CPU热插拔所涉及的ACPI事件编程模型。CPU热插拔流程包括设备添加、CPU属性设置、GIC连接和状态恢复等步骤,同时需要对ged设备进行相应修改以支持CPU热插拔事件。
摘要由CSDN通过智能技术生成

openEuler社区的qemu-4.1.0实现了aarch64 CPU热插特性。

CPU热插功能涉及的修改主要包括ACPI(MADT表,DSDT表),GED,GICv3,以及热插流程的支持。

1 ACPI

1.1 什么是ACPI?

ACPI是Advanced Configuration and Power Interface的简写。可以将ACPI理解为与体系结构无关的电源管理和配置框架,该框架在主机OS内形成子系统。 该框架建立了一个硬件寄存器集来定义电源状态(睡眠,休眠,唤醒等)。 硬件寄存器集可以容纳专用硬件和通用硬件上的操作。标准ACPI框架和硬件寄存器集的主要目的是启用电源管理和系统配置,而无需直接从OS本地调用固件。ACPI充当系统固件(BIOS)和OS之间的接口层,并具有一定的限制和规则。

Definition blocks字节代码是从ACPI源语言(ASL)代码编译而成的。 ASL是用于定义ACPI对象和编写控制方法的语言。 ASL编译器将ASL转换为ACPI机器语言(AML)字节码。 AML是AML解释程序处理的语言。

1.2 ACPI整体系统

图中OSPM是Operating System-directed configuration and Power Management的简写。
ACPI有三个运行时组件:

  • ACPI Description Tables:描述对硬件的接口。ACPI Description Tables包含了Definition Blocks,其可以使用称为ACPI Machine Lanague(AML)的伪代码。
  • ACPI Registers:硬件接口的受约束部分,由ACPI系统描述表描述(至少在位置上)。
  • ACPI Platform Firmware:与ACPI规范兼容的固件部分。通常,这是引导计算机(如旧版BIOS完成)并实现睡眠,唤醒和某些重新启动操作的接口的代码。

1.3 CPU热插涉及的ACPI表

  • Differentiated System Description Table (DSDT):OEM必须向兼容ACPI的操作系统提供DSDT。 DSDT包含“差分definition blocks”,该块提供有关基本系统的实现和配置信息。 操作系统始终在系统引导时将DSDT信息插入ACPI namespace,并且永远不会删除它。
  • Multiple APIC Description Table (MADT):用于支持APIC和SAPIC的系统上,以描述APIC实现。 M计ADT后面是APIC / SAPIC结构的列表,这些结构声明了算机的APIC / SAPIC功能。

1.4 ACPI事件编程模型(GED)

ACPI 6.1引入了对ACPI事件的支持:当Generic Event Device(GED)的_CRS对象中列出的中断发生时,会产生ACPI事件并由OSPM接收。OSPM声明所有此类中断,并将它们映射到ACPI事件模型所需的适当事件方法。GED在namespace中是一个设备,其_HID为ACPI0013。GED必须提供一个_CRS和_EVT对象,以声明中断并将它们映射到ACPI事件。OS可以通过_OSC方法查询平台是否支持GED。

2 GICv3

GIC(Generic Interrupt Controller)是一个通用的中断控制器,用来接收硬件中断信号,并经过一定处理后,分发给对应的CPU进行处理。GIC V3是其中一个版本,支持的中断类型如下表:

中断类型

中断号

描述

SGI (Software Generated Interrupt)

0-15

软件触发中断,通常用于多核之间通讯,在Linux内核中通常被用作IPI(inter-process interrupts)中断,并送达到系统指定的CPU,最多支持16个SGI中断,中断号0-15

PPI (Private Peripheral Interrupt)

16-31

每个处理器的私有外设中断,最多支持16个PPI中断,中断号16-31,PPI通常会送达到指定的CPU上

SPI (Shared Peripheral Interrupt)

32-1019

系统共享的外设中断

LPI (Locality-specific Peripheral Interrupt)

8192-MAX

LPI是基于消息的中断,它们的配置保存在表中而不是寄存器

GIC V3中断控制器的组成部分包括:distributor,redistributor,cpu interface,ITS,GIC V3中断控制器和处理器核心之间的关系图如下:

3 主要修改

对于需要支持CPU热插的虚拟机,vcpu配置示例如下:

<vcpu placement='static' current='4'>8</vcpu>

其中current='4'指定当前CPU数量为4,<vcpu>8</vcpu>指定最大CPU数量为8。

3.1 CPU热插流程

qemu处理CPU热插事件的相关流程如下:

  1. 收到device_add qmp,且设备类型为cpu
  2. 进入device_set_realized流程
    1. virt_cpu_pre_plug,设置CPU相关属性,并暂停所有CPU
    2. 实例化CPU
    3. virt_cpu_plug,连接GIC irq,重置CPU,并恢复所有CPU运行,然后发送消息给guest OS,通知CPU热插。

guest处理CPU热插事件的相关流程如下:

  1. GED发送CPU热插事件给guest。
  2. guest中的ACPI驱动调用GED AML定义的_EVT方法。
  3. GED AML定义的_EVT方法判断是CPU热插事件,调用CPUS AML定义的CSCN方法获取所有CPU的状态。
  4. guest的CPU的状态由GED的CPUHotplugState结构进行模拟,并通过Memory Region由guest访问。

3.2 对ACPI表的修改

3.2.1 对MADT表的修改

MADT表向OSPM提供了中断控制器的描述信息。qemu模拟的aarch64平台使用的是GICv3作为中断控制器,因此MADT表中包含了n个GICC(GIC CPU Interface)结构,虚拟机每个CPU对应一个GICC。由于要支持CPU热插,因此提供给虚拟机的MADT表中GICC结构的数量需要指定为虚拟机配置的最大CPU数量。

build_madt

/* MADT */

static void

build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)

{

    ...

    /* The MADT GICC numbers */

    int num_cpu = vms->smp_cpus;

    ...

    if (vms->cpu_hotplug_enabled) {

        num_cpu = ms->smp.max_cpus;  /* 设置num_cpu为最大CPU数量 */

    }

    for (i = 0; i < num_cpu; i++) {  /* 构造最大CPU数量的GICC结构 */

        virt_madt_cpu_entry(NULL, i, possible_cpus, table_data);

    }

    ...

}

3.2.2 对DSDT表的修改

DSDT表向OSPM提供了CPU信息,构造CPU信息的功能由build_cpus_aml函数提供。

build_dsdt

/* DSDT */

static void

build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)

{

    ...

    if (vms->acpi_dev) {

        /* 支持CPU热插时,DSDT表提供的CPU信息需要增加部分内容,且CPU数量为最大CPU数量 */

        if (event & ACPI_GED_CPU_HOTPLUG_EVT) {

            CPUHotplugFeatures opts = {

                .acpi_1_compatible = false, .has_legacy_cphp = false

            };

            build_cpus_aml(dsdt, ms, opts, memmap[VIRT_CPU_ACPI].base,

                           "\\_SB", NULL, AML_SYSTEM_MEMORY);

            cpu_aml_built = true;

        }

    }

 

    if (!cpu_aml_built) {

        acpi_dsdt_add_cpus(scope, vms->smp_cpus);

    }

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值