mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
acpi: use build_append_int_noprefix() API to compose SRAT table
Drop usage of packed structures and explicit endian conversions when building SRAT tables for arm/x86 and use endian agnostic build_append_int_noprefix() API to build it. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Message-Id: <20210924122802.1455362-18-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
255bf20f2e
commit
e5b6d55a6e
6 changed files with 80 additions and 106 deletions
|
@ -1940,15 +1940,25 @@ build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
|
||||||
acpi_table_end(linker, &table);
|
acpi_table_end(linker, &table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
|
/*
|
||||||
|
* ACPI spec, Revision 4.0
|
||||||
|
* 5.2.16.2 Memory Affinity Structure
|
||||||
|
*/
|
||||||
|
void build_srat_memory(GArray *table_data, uint64_t base,
|
||||||
uint64_t len, int node, MemoryAffinityFlags flags)
|
uint64_t len, int node, MemoryAffinityFlags flags)
|
||||||
{
|
{
|
||||||
numamem->type = ACPI_SRAT_MEMORY;
|
build_append_int_noprefix(table_data, 1, 1); /* Type */
|
||||||
numamem->length = sizeof(*numamem);
|
build_append_int_noprefix(table_data, 40, 1); /* Length */
|
||||||
numamem->proximity = cpu_to_le32(node);
|
build_append_int_noprefix(table_data, node, 4); /* Proximity Domain */
|
||||||
numamem->flags = cpu_to_le32(flags);
|
build_append_int_noprefix(table_data, 0, 2); /* Reserved */
|
||||||
numamem->base_addr = cpu_to_le64(base);
|
build_append_int_noprefix(table_data, base, 4); /* Base Address Low */
|
||||||
numamem->range_length = cpu_to_le64(len);
|
/* Base Address High */
|
||||||
|
build_append_int_noprefix(table_data, base >> 32, 4);
|
||||||
|
build_append_int_noprefix(table_data, len, 4); /* Length Low */
|
||||||
|
build_append_int_noprefix(table_data, len >> 32, 4); /* Length High */
|
||||||
|
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||||
|
build_append_int_noprefix(table_data, flags, 4); /* Flags */
|
||||||
|
build_append_int_noprefix(table_data, 0, 8); /* Reserved */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1336,7 +1336,6 @@ void nvdimm_build_srat(GArray *table_data)
|
||||||
GSList *device_list = nvdimm_get_device_list();
|
GSList *device_list = nvdimm_get_device_list();
|
||||||
|
|
||||||
for (; device_list; device_list = device_list->next) {
|
for (; device_list; device_list = device_list->next) {
|
||||||
AcpiSratMemoryAffinity *numamem = NULL;
|
|
||||||
DeviceState *dev = device_list->data;
|
DeviceState *dev = device_list->data;
|
||||||
Object *obj = OBJECT(dev);
|
Object *obj = OBJECT(dev);
|
||||||
uint64_t addr, size;
|
uint64_t addr, size;
|
||||||
|
@ -1346,8 +1345,7 @@ void nvdimm_build_srat(GArray *table_data)
|
||||||
addr = object_property_get_uint(obj, PC_DIMM_ADDR_PROP, &error_abort);
|
addr = object_property_get_uint(obj, PC_DIMM_ADDR_PROP, &error_abort);
|
||||||
size = object_property_get_uint(obj, PC_DIMM_SIZE_PROP, &error_abort);
|
size = object_property_get_uint(obj, PC_DIMM_SIZE_PROP, &error_abort);
|
||||||
|
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, addr, size, node,
|
||||||
build_srat_memory(numamem, addr, size, node,
|
|
||||||
MEM_AFFINITY_ENABLED | MEM_AFFINITY_NON_VOLATILE);
|
MEM_AFFINITY_ENABLED | MEM_AFFINITY_NON_VOLATILE);
|
||||||
}
|
}
|
||||||
g_slist_free(device_list);
|
g_slist_free(device_list);
|
||||||
|
|
|
@ -474,11 +474,13 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
vms->oem_table_id);
|
vms->oem_table_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACPI spec, Revision 5.1
|
||||||
|
* 5.2.16 System Resource Affinity Table (SRAT)
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
AcpiSratProcessorGiccAffinity *core;
|
|
||||||
AcpiSratMemoryAffinity *numamem;
|
|
||||||
int i;
|
int i;
|
||||||
uint64_t mem_base;
|
uint64_t mem_base;
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||||||
|
@ -492,19 +494,23 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
build_append_int_noprefix(table_data, 0, 8); /* Reserved */
|
build_append_int_noprefix(table_data, 0, 8); /* Reserved */
|
||||||
|
|
||||||
for (i = 0; i < cpu_list->len; ++i) {
|
for (i = 0; i < cpu_list->len; ++i) {
|
||||||
core = acpi_data_push(table_data, sizeof(*core));
|
uint32_t nodeid = cpu_list->cpus[i].props.node_id;
|
||||||
core->type = ACPI_SRAT_PROCESSOR_GICC;
|
/*
|
||||||
core->length = sizeof(*core);
|
* 5.2.16.4 GICC Affinity Structure
|
||||||
core->proximity = cpu_to_le32(cpu_list->cpus[i].props.node_id);
|
*/
|
||||||
core->acpi_processor_uid = cpu_to_le32(i);
|
build_append_int_noprefix(table_data, 3, 1); /* Type */
|
||||||
core->flags = cpu_to_le32(1);
|
build_append_int_noprefix(table_data, 18, 1); /* Length */
|
||||||
|
build_append_int_noprefix(table_data, nodeid, 4); /* Proximity Domain */
|
||||||
|
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */
|
||||||
|
/* Flags, Table 5-76 */
|
||||||
|
build_append_int_noprefix(table_data, 1 /* Enabled */, 4);
|
||||||
|
build_append_int_noprefix(table_data, 0, 4); /* Clock Domain */
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_base = vms->memmap[VIRT_MEM].base;
|
mem_base = vms->memmap[VIRT_MEM].base;
|
||||||
for (i = 0; i < ms->numa_state->num_nodes; ++i) {
|
for (i = 0; i < ms->numa_state->num_nodes; ++i) {
|
||||||
if (ms->numa_state->nodes[i].node_mem > 0) {
|
if (ms->numa_state->nodes[i].node_mem > 0) {
|
||||||
numamem = acpi_data_push(table_data, sizeof(*numamem));
|
build_srat_memory(table_data, mem_base,
|
||||||
build_srat_memory(numamem, mem_base,
|
|
||||||
ms->numa_state->nodes[i].node_mem, i,
|
ms->numa_state->nodes[i].node_mem, i,
|
||||||
MEM_AFFINITY_ENABLED);
|
MEM_AFFINITY_ENABLED);
|
||||||
mem_base += ms->numa_state->nodes[i].node_mem;
|
mem_base += ms->numa_state->nodes[i].node_mem;
|
||||||
|
@ -516,8 +522,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ms->device_memory) {
|
if (ms->device_memory) {
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, ms->device_memory->base,
|
||||||
build_srat_memory(numamem, ms->device_memory->base,
|
|
||||||
memory_region_size(&ms->device_memory->mr),
|
memory_region_size(&ms->device_memory->mr),
|
||||||
ms->numa_state->num_nodes - 1,
|
ms->numa_state->num_nodes - 1,
|
||||||
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
||||||
|
|
|
@ -1939,13 +1939,15 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
|
||||||
#define HOLE_640K_START (640 * KiB)
|
#define HOLE_640K_START (640 * KiB)
|
||||||
#define HOLE_640K_END (1 * MiB)
|
#define HOLE_640K_END (1 * MiB)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACPI spec, Revision 3.0
|
||||||
|
* 5.2.15 System Resource Affinity Table (SRAT)
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
{
|
{
|
||||||
AcpiSratMemoryAffinity *numamem;
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int numa_start, slots;
|
int numa_mem_start, slots;
|
||||||
uint64_t mem_len, mem_base, next_base;
|
uint64_t mem_len, mem_base, next_base;
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||||
X86MachineState *x86ms = X86_MACHINE(machine);
|
X86MachineState *x86ms = X86_MACHINE(machine);
|
||||||
|
@ -1968,34 +1970,41 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
uint32_t apic_id = apic_ids->cpus[i].arch_id;
|
uint32_t apic_id = apic_ids->cpus[i].arch_id;
|
||||||
|
|
||||||
if (apic_id < 255) {
|
if (apic_id < 255) {
|
||||||
AcpiSratProcessorAffinity *core;
|
/* 5.2.15.1 Processor Local APIC/SAPIC Affinity Structure */
|
||||||
|
build_append_int_noprefix(table_data, 0, 1); /* Type */
|
||||||
core = acpi_data_push(table_data, sizeof *core);
|
build_append_int_noprefix(table_data, 16, 1); /* Length */
|
||||||
core->type = ACPI_SRAT_PROCESSOR_APIC;
|
/* Proximity Domain [7:0] */
|
||||||
core->length = sizeof(*core);
|
build_append_int_noprefix(table_data, node_id, 1);
|
||||||
core->local_apic_id = apic_id;
|
build_append_int_noprefix(table_data, apic_id, 1); /* APIC ID */
|
||||||
core->proximity_lo = node_id;
|
/* Flags, Table 5-36 */
|
||||||
memset(core->proximity_hi, 0, 3);
|
build_append_int_noprefix(table_data, 1, 4);
|
||||||
core->local_sapic_eid = 0;
|
build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */
|
||||||
core->flags = cpu_to_le32(1);
|
/* Proximity Domain [31:8] */
|
||||||
|
build_append_int_noprefix(table_data, 0, 3);
|
||||||
|
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||||
} else {
|
} else {
|
||||||
AcpiSratProcessorX2ApicAffinity *core;
|
/*
|
||||||
|
* ACPI spec, Revision 4.0
|
||||||
core = acpi_data_push(table_data, sizeof *core);
|
* 5.2.16.3 Processor Local x2APIC Affinity Structure
|
||||||
core->type = ACPI_SRAT_PROCESSOR_x2APIC;
|
*/
|
||||||
core->length = sizeof(*core);
|
build_append_int_noprefix(table_data, 2, 1); /* Type */
|
||||||
core->x2apic_id = cpu_to_le32(apic_id);
|
build_append_int_noprefix(table_data, 24, 1); /* Length */
|
||||||
core->proximity_domain = cpu_to_le32(node_id);
|
build_append_int_noprefix(table_data, 0, 2); /* Reserved */
|
||||||
core->flags = cpu_to_le32(1);
|
/* Proximity Domain */
|
||||||
|
build_append_int_noprefix(table_data, node_id, 4);
|
||||||
|
build_append_int_noprefix(table_data, apic_id, 4); /* X2APIC ID */
|
||||||
|
/* Flags, Table 5-39 */
|
||||||
|
build_append_int_noprefix(table_data, 1 /* Enabled */, 4);
|
||||||
|
build_append_int_noprefix(table_data, 0, 4); /* Clock Domain */
|
||||||
|
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* the memory map is a bit tricky, it contains at least one hole
|
/* the memory map is a bit tricky, it contains at least one hole
|
||||||
* from 640k-1M and possibly another one from 3.5G-4G.
|
* from 640k-1M and possibly another one from 3.5G-4G.
|
||||||
*/
|
*/
|
||||||
next_base = 0;
|
next_base = 0;
|
||||||
numa_start = table_data->len;
|
numa_mem_start = table_data->len;
|
||||||
|
|
||||||
for (i = 1; i < nb_numa_nodes + 1; ++i) {
|
for (i = 1; i < nb_numa_nodes + 1; ++i) {
|
||||||
mem_base = next_base;
|
mem_base = next_base;
|
||||||
|
@ -2007,8 +2016,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
next_base > HOLE_640K_START) {
|
next_base > HOLE_640K_START) {
|
||||||
mem_len -= next_base - HOLE_640K_START;
|
mem_len -= next_base - HOLE_640K_START;
|
||||||
if (mem_len > 0) {
|
if (mem_len > 0) {
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, mem_base, mem_len, i - 1,
|
||||||
build_srat_memory(numamem, mem_base, mem_len, i - 1,
|
|
||||||
MEM_AFFINITY_ENABLED);
|
MEM_AFFINITY_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2026,8 +2034,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
next_base > x86ms->below_4g_mem_size) {
|
next_base > x86ms->below_4g_mem_size) {
|
||||||
mem_len -= next_base - x86ms->below_4g_mem_size;
|
mem_len -= next_base - x86ms->below_4g_mem_size;
|
||||||
if (mem_len > 0) {
|
if (mem_len > 0) {
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, mem_base, mem_len, i - 1,
|
||||||
build_srat_memory(numamem, mem_base, mem_len, i - 1,
|
|
||||||
MEM_AFFINITY_ENABLED);
|
MEM_AFFINITY_ENABLED);
|
||||||
}
|
}
|
||||||
mem_base = 1ULL << 32;
|
mem_base = 1ULL << 32;
|
||||||
|
@ -2036,8 +2043,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem_len > 0) {
|
if (mem_len > 0) {
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, mem_base, mem_len, i - 1,
|
||||||
build_srat_memory(numamem, mem_base, mem_len, i - 1,
|
|
||||||
MEM_AFFINITY_ENABLED);
|
MEM_AFFINITY_ENABLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2046,10 +2052,15 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
nvdimm_build_srat(table_data);
|
nvdimm_build_srat(table_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
slots = (table_data->len - numa_start) / sizeof *numamem;
|
/*
|
||||||
|
* TODO: this part is not in ACPI spec and current linux kernel boots fine
|
||||||
|
* without these entries. But I recall there were issues the last time I
|
||||||
|
* tried to remove it with some ancient guest OS, however I can't remember
|
||||||
|
* what that was so keep this around for now
|
||||||
|
*/
|
||||||
|
slots = (table_data->len - numa_mem_start) / 40 /* mem affinity len */;
|
||||||
for (; slots < nb_numa_nodes + 2; slots++) {
|
for (; slots < nb_numa_nodes + 2; slots++) {
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
|
||||||
build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2061,8 +2072,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
* providing _PXM method if necessary.
|
* providing _PXM method if necessary.
|
||||||
*/
|
*/
|
||||||
if (hotpluggable_address_space_size) {
|
if (hotpluggable_address_space_size) {
|
||||||
numamem = acpi_data_push(table_data, sizeof *numamem);
|
build_srat_memory(table_data, machine->device_memory->base,
|
||||||
build_srat_memory(numamem, machine->device_memory->base,
|
|
||||||
hotpluggable_address_space_size, nb_numa_nodes - 1,
|
hotpluggable_address_space_size, nb_numa_nodes - 1,
|
||||||
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,55 +358,6 @@ struct AcpiGenericTimerTable {
|
||||||
} QEMU_PACKED;
|
} QEMU_PACKED;
|
||||||
typedef struct AcpiGenericTimerTable AcpiGenericTimerTable;
|
typedef struct AcpiGenericTimerTable AcpiGenericTimerTable;
|
||||||
|
|
||||||
#define ACPI_SRAT_PROCESSOR_APIC 0
|
|
||||||
#define ACPI_SRAT_MEMORY 1
|
|
||||||
#define ACPI_SRAT_PROCESSOR_x2APIC 2
|
|
||||||
#define ACPI_SRAT_PROCESSOR_GICC 3
|
|
||||||
|
|
||||||
struct AcpiSratProcessorAffinity {
|
|
||||||
ACPI_SUB_HEADER_DEF
|
|
||||||
uint8_t proximity_lo;
|
|
||||||
uint8_t local_apic_id;
|
|
||||||
uint32_t flags;
|
|
||||||
uint8_t local_sapic_eid;
|
|
||||||
uint8_t proximity_hi[3];
|
|
||||||
uint32_t reserved;
|
|
||||||
} QEMU_PACKED;
|
|
||||||
typedef struct AcpiSratProcessorAffinity AcpiSratProcessorAffinity;
|
|
||||||
|
|
||||||
struct AcpiSratProcessorX2ApicAffinity {
|
|
||||||
ACPI_SUB_HEADER_DEF
|
|
||||||
uint16_t reserved;
|
|
||||||
uint32_t proximity_domain;
|
|
||||||
uint32_t x2apic_id;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t clk_domain;
|
|
||||||
uint32_t reserved2;
|
|
||||||
} QEMU_PACKED;
|
|
||||||
typedef struct AcpiSratProcessorX2ApicAffinity AcpiSratProcessorX2ApicAffinity;
|
|
||||||
|
|
||||||
struct AcpiSratMemoryAffinity {
|
|
||||||
ACPI_SUB_HEADER_DEF
|
|
||||||
uint32_t proximity;
|
|
||||||
uint16_t reserved1;
|
|
||||||
uint64_t base_addr;
|
|
||||||
uint64_t range_length;
|
|
||||||
uint32_t reserved2;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t reserved3[2];
|
|
||||||
} QEMU_PACKED;
|
|
||||||
typedef struct AcpiSratMemoryAffinity AcpiSratMemoryAffinity;
|
|
||||||
|
|
||||||
struct AcpiSratProcessorGiccAffinity {
|
|
||||||
ACPI_SUB_HEADER_DEF
|
|
||||||
uint32_t proximity;
|
|
||||||
uint32_t acpi_processor_uid;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t clock_domain;
|
|
||||||
} QEMU_PACKED;
|
|
||||||
|
|
||||||
typedef struct AcpiSratProcessorGiccAffinity AcpiSratProcessorGiccAffinity;
|
|
||||||
|
|
||||||
/* DMAR - DMA Remapping table r2.2 */
|
/* DMAR - DMA Remapping table r2.2 */
|
||||||
struct AcpiTableDmar {
|
struct AcpiTableDmar {
|
||||||
ACPI_TABLE_HEADER_DEF
|
ACPI_TABLE_HEADER_DEF
|
||||||
|
|
|
@ -487,7 +487,7 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set, uint32_t io_offset,
|
||||||
uint32_t mmio32_offset, uint64_t mmio64_offset,
|
uint32_t mmio32_offset, uint64_t mmio64_offset,
|
||||||
uint16_t bus_nr_offset);
|
uint16_t bus_nr_offset);
|
||||||
|
|
||||||
void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
|
void build_srat_memory(GArray *table_data, uint64_t base,
|
||||||
uint64_t len, int node, MemoryAffinityFlags flags);
|
uint64_t len, int node, MemoryAffinityFlags flags);
|
||||||
|
|
||||||
void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue