Commit 4926403c authored by Eduardo Habkost's avatar Eduardo Habkost
Browse files

hw/acpi-build: Fix SRAT memory building in case of node 0 without RAM



Currently, Using the fisrt node without memory on the machine makes
QEMU unhappy. With this example command line:
  ... \
  -m 1024M,slots=4,maxmem=32G \
  -numa node,nodeid=0 \
  -numa node,mem=1024M,nodeid=1 \
  -numa node,nodeid=2 \
  -numa node,nodeid=3 \
Guest reports "No NUMA configuration found" and the NUMA topology is
wrong.

This is because when QEMU builds ACPI SRAT, it regards node 0 as the
default node to deal with the memory hole(640K-1M). this means the
node0 must have some memory(>1M), but, actually it can have no
memory.

Fix this problem by cut out the 640K hole in the same way the PCI
4G hole does.

Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
Signed-off-by: default avatarDou Liyang <douly.fnst@cn.fujitsu.com>
Message-Id: <1504231805-30957-2-git-send-email-douly.fnst@cn.fujitsu.com>
Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
parent f51878ba
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -2288,6 +2288,9 @@ build_tpm2(GArray *table_data, BIOSLinker *linker)
                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL);
}

#define HOLE_640K_START  (640 * 1024)
#define HOLE_640K_END   (1024 * 1024)

static void
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
@@ -2343,17 +2346,30 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
    next_base = 0;
    numa_start = table_data->len;

    numamem = acpi_data_push(table_data, sizeof *numamem);
    build_srat_memory(numamem, 0, 640 * 1024, 0, MEM_AFFINITY_ENABLED);
    next_base = 1024 * 1024;
    for (i = 1; i < pcms->numa_nodes + 1; ++i) {
        mem_base = next_base;
        mem_len = pcms->node_mem[i - 1];
        if (i == 1) {
            mem_len -= 1024 * 1024;
        }
        next_base = mem_base + mem_len;

        /* Cut out the 640K hole */
        if (mem_base <= HOLE_640K_START &&
            next_base > HOLE_640K_START) {
            mem_len -= next_base - HOLE_640K_START;
            if (mem_len > 0) {
                numamem = acpi_data_push(table_data, sizeof *numamem);
                build_srat_memory(numamem, mem_base, mem_len, i - 1,
                                  MEM_AFFINITY_ENABLED);
            }

            /* Check for the rare case: 640K < RAM < 1M */
            if (next_base <= HOLE_640K_END) {
                next_base = HOLE_640K_END;
                continue;
            }
            mem_base = HOLE_640K_END;
            mem_len = next_base - HOLE_640K_END;
        }

        /* Cut out the ACPI_PCI hole */
        if (mem_base <= pcms->below_4g_mem_size &&
            next_base > pcms->below_4g_mem_size) {