/*
 * NUMA parameter parsing routines
 *
 * Copyright (c) 2014 Fujitsu Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "sysemu/hostmem.h"
#include "sysemu/numa.h"
#include "sysemu/sysemu.h"
#include "exec/cpu-common.h"
#include "exec/ramlist.h"
#include "qemu/bitmap.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-visit-machine.h"
#include "sysemu/qtest.h"
#include "hw/core/cpu.h"
#include "hw/mem/pc-dimm.h"
#include "migration/vmstate.h"
#include "hw/boards.h"
#include "hw/mem/memory-device.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/cutils.h"

QemuOptsList qemu_numa_opts = {
    .name = "numa",
    .implied_opt_name = "type",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_numa_opts.head),
    .desc = { { 0 } } /* validated with OptsVisitor */
};

static int have_memdevs;
bool numa_uses_legacy_mem(void)
{
    return !have_memdevs;
}

static int have_mem;
static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one.
                             * For all nodes, nodeid < max_numa_nodeid
                             */

static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
                            Error **errp)
{
    Error *err = NULL;
    uint16_t nodenr;
    uint16List *cpus = NULL;
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    unsigned int max_cpus = ms->smp.max_cpus;
    NodeInfo *numa_info = ms->numa_state->nodes;

    if (node->has_nodeid) {
        nodenr = node->nodeid;
    } else {
        nodenr = ms->numa_state->num_nodes;
    }

    if (nodenr >= MAX_NODES) {
        error_setg(errp, "Max number of NUMA nodes reached: %"
                   PRIu16 "", nodenr);
        return;
    }

    if (numa_info[nodenr].present) {
        error_setg(errp, "Duplicate NUMA nodeid: %" PRIu16, nodenr);
        return;
    }

    for (cpus = node->cpus; cpus; cpus = cpus->next) {
        CpuInstanceProperties props;
        if (cpus->value >= max_cpus) {
            error_setg(errp,
                       "CPU index (%" PRIu16 ")"
                       " should be smaller than maxcpus (%d)",
                       cpus->value, max_cpus);
            return;
        }
        props = mc->cpu_index_to_instance_props(ms, cpus->value);
        props.node_id = nodenr;
        props.has_node_id = true;
        machine_set_cpu_numa_node(ms, &props, &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
    }

    have_memdevs = have_memdevs ? : node->has_memdev;
    have_mem = have_mem ? : node->has_mem;
    if ((node->has_mem && have_memdevs) || (node->has_memdev && have_mem)) {
        error_setg(errp, "numa configuration should use either mem= or memdev=,"
                   "mixing both is not allowed");
        return;
    }

    if (node->has_mem) {
        numa_info[nodenr].node_mem = node->mem;
        if (!qtest_enabled()) {
            warn_report("Parameter -numa node,mem is deprecated,"
                        " use -numa node,memdev instead");
        }
    }
    if (node->has_memdev) {
        Object *o;
        o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);
        if (!o) {
            error_setg(errp, "memdev=%s is ambiguous", node->memdev);
            return;
        }

        object_ref(o);
        numa_info[nodenr].node_mem = object_property_get_uint(o, "size", NULL);
        numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
    }

    /*
     * If not set the initiator, set it to MAX_NODES. And if
     * HMAT is enabled and this node has no cpus, QEMU will raise error.
     */
    numa_info[nodenr].initiator = MAX_NODES;
    if (node->has_initiator) {
        if (!ms->numa_state->hmat_enabled) {
            error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
                       "(HMAT) is disabled, enable it with -machine hmat=on "
                       "before using any of hmat specific options");
            return;
        }

        if (node->initiator >= MAX_NODES) {
            error_report("The initiator id %" PRIu16 " expects an integer "
                         "between 0 and %d", node->initiator,
                         MAX_NODES - 1);
            return;
        }

        numa_info[nodenr].initiator = node->initiator;
    }
    numa_info[nodenr].present = true;
    max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
    ms->numa_state->num_nodes++;
}

static
void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp)
{
    uint16_t src = dist->src;
    uint16_t dst = dist->dst;
    uint8_t val = dist->val;
    NodeInfo *numa_info = ms->numa_state->nodes;

    if (src >= MAX_NODES || dst >= MAX_NODES) {
        error_setg(errp, "Parameter '%s' expects an integer between 0 and %d",
                   src >= MAX_NODES ? "src" : "dst", MAX_NODES - 1);
        return;
    }

    if (!numa_info[src].present || !numa_info[dst].present) {
        error_setg(errp, "Source/Destination NUMA node is missing. "
                   "Please use '-numa node' option to declare it first.");
        return;
    }

    if (val < NUMA_DISTANCE_MIN) {
        error_setg(errp, "NUMA distance (%" PRIu8 ") is invalid, "
                   "it shouldn't be less than %d.",
                   val, NUMA_DISTANCE_MIN);
        return;
    }

    if (src == dst && val != NUMA_DISTANCE_MIN) {
        error_setg(errp, "Local distance of node %d should be %d.",
                   src, NUMA_DISTANCE_MIN);
        return;
    }

    numa_info[src].distance[dst] = val;
    ms->numa_state->have_numa_distance = true;
}

void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
                        Error **errp)
{
    int i, first_bit, last_bit;
    uint64_t max_entry, temp_base, bitmap_copy;
    NodeInfo *numa_info = numa_state->nodes;
    HMAT_LB_Info *hmat_lb =
        numa_state->hmat_lb[node->hierarchy][node->data_type];
    HMAT_LB_Data lb_data = {};
    HMAT_LB_Data *lb_temp;

    /* Error checking */
    if (node->initiator > numa_state->num_nodes) {
        error_setg(errp, "Invalid initiator=%d, it should be less than %d",
                   node->initiator, numa_state->num_nodes);
        return;
    }
    if (node->target > numa_state->num_nodes) {
        error_setg(errp, "Invalid target=%d, it should be less than %d",
                   node->target, numa_state->num_nodes);
        return;
    }
    if (!numa_info[node->initiator].has_cpu) {
        error_setg(errp, "Invalid initiator=%d, it isn't an "
                   "initiator proximity domain", node->initiator);
        return;
    }
    if (!numa_info[node->target].present) {
        error_setg(errp, "The target=%d should point to an existing node",
                   node->target);
        return;
    }

    if (!hmat_lb) {
        hmat_lb = g_malloc0(sizeof(*hmat_lb));
        numa_state->hmat_lb[node->hierarchy][node->data_type] = hmat_lb;
        hmat_lb->list = g_array_new(false, true, sizeof(HMAT_LB_Data));
    }
    hmat_lb->hierarchy = node->hierarchy;
    hmat_lb->data_type = node->data_type;
    lb_data.initiator = node->initiator;
    lb_data.target = node->target;

    if (node->data_type <= HMATLB_DATA_TYPE_WRITE_LATENCY) {
        /* Input latency data */

        if (!node->has_latency) {
            error_setg(errp, "Missing 'latency' option");
            return;
        }
        if (node->has_bandwidth) {
            error_setg(errp, "Invalid option 'bandwidth' since "
                       "the data type is latency");
            return;
        }

        /* Detect duplicate configuration */
        for (i = 0; i < hmat_lb->list->len; i++) {
            lb_temp = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);

            if (node->initiator == lb_temp->initiator &&
                node->target == lb_temp->target) {
                error_setg(errp, "Duplicate configuration of the latency for "
                    "initiator=%d and target=%d", node->initiator,
                    node->target);
                return;
            }
        }

        hmat_lb->base = hmat_lb->base ? hmat_lb->base : UINT64_MAX;

        if (node->latency) {
            /* Calculate the temporary base and compressed latency */
            max_entry = node->latency;
            temp_base = 1;
            while (QEMU_IS_ALIGNED(max_entry, 10)) {
                max_entry /= 10;
                temp_base *= 10;
            }

            /* Calculate the max compressed latency */
            temp_base = MIN(hmat_lb->base, temp_base);
            max_entry = node->latency / hmat_lb->base;
            max_entry = MAX(hmat_lb->range_bitmap, max_entry);

            /*
             * For latency hmat_lb->range_bitmap record the max compressed
             * latency which should be less than 0xFFFF (UINT16_MAX)
             */
            if (max_entry >= UINT16_MAX) {
                error_setg(errp, "Latency %" PRIu64 " between initiator=%d and "
                        "target=%d should not differ from previously entered "
                        "min or max values on more than %d", node->latency,
                        node->initiator, node->target, UINT16_MAX - 1);
                return;
            } else {
                hmat_lb->base = temp_base;
                hmat_lb->range_bitmap = max_entry;
            }

            /*
             * Set lb_info_provided bit 0 as 1,
             * latency information is provided
             */
            numa_info[node->target].lb_info_provided |= BIT(0);
        }
        lb_data.data = node->latency;
    } else if (node->data_type >= HMATLB_DATA_TYPE_ACCESS_BANDWIDTH) {
        /* Input bandwidth data */
        if (!node->has_bandwidth) {
            error_setg(errp, "Missing 'bandwidth' option");
            return;
        }
        if (node->has_latency) {
            error_setg(errp, "Invalid option 'latency' since "
                       "the data type is bandwidth");
            return;
        }
        if (!QEMU_IS_ALIGNED(node->bandwidth, MiB)) {
            error_setg(errp, "Bandwidth %" PRIu64 " between initiator=%d and "
                       "target=%d should be 1MB aligned", node->bandwidth,
                       node->initiator, node->target);
            return;
        }

        /* Detect duplicate configuration */
        for (i = 0; i < hmat_lb->list->len; i++) {
            lb_temp = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);

            if (node->initiator == lb_temp->initiator &&
                node->target == lb_temp->target) {
                error_setg(errp, "Duplicate configuration of the bandwidth for "
                    "initiator=%d and target=%d", node->initiator,
                    node->target);
                return;
            }
        }

        hmat_lb->base = hmat_lb->base ? hmat_lb->base : 1;

        if (node->bandwidth) {
            /* Keep bitmap unchanged when bandwidth out of range */
            bitmap_copy = hmat_lb->range_bitmap;
            bitmap_copy |= node->bandwidth;
            first_bit = ctz64(bitmap_copy);
            temp_base = UINT64_C(1) << first_bit;
            max_entry = node->bandwidth / temp_base;
            last_bit = 64 - clz64(bitmap_copy);

            /*
             * For bandwidth, first_bit record the base unit of bandwidth bits,
             * last_bit record the last bit of the max bandwidth. The max
             * compressed bandwidth should be less than 0xFFFF (UINT16_MAX)
             */
            if ((last_bit - first_bit) > UINT16_BITS ||
                max_entry >= UINT16_MAX) {
                error_setg(errp, "Bandwidth %" PRIu64 " between initiator=%d "
                        "and target=%d should not differ from previously "
                        "entered values on more than %d", node->bandwidth,
                        node->initiator, node->target, UINT16_MAX - 1);
                return;
            } else {
                hmat_lb->base = temp_base;
                hmat_lb->range_bitmap = bitmap_copy;
            }

            /*
             * Set lb_info_provided bit 1 as 1,
             * bandwidth information is provided
             */
            numa_info[node->target].lb_info_provided |= BIT(1);
        }
        lb_data.data = node->bandwidth;
    } else {
        assert(0);
    }

    g_array_append_val(hmat_lb->list, lb_data);
}

void parse_numa_hmat_cache(MachineState *ms, NumaHmatCacheOptions *node,
                           Error **errp)
{
    int nb_numa_nodes = ms->numa_state->num_nodes;
    NodeInfo *numa_info = ms->numa_state->nodes;
    NumaHmatCacheOptions *hmat_cache = NULL;

    if (node->node_id >= nb_numa_nodes) {
        error_setg(errp, "Invalid node-id=%" PRIu32 ", it should be less "
                   "than %d", node->node_id, nb_numa_nodes);
        return;
    }

    if (numa_info[node->node_id].lb_info_provided != (BIT(0) | BIT(1))) {
        error_setg(errp, "The latency and bandwidth information of "
                   "node-id=%" PRIu32 " should be provided before memory side "
                   "cache attributes", node->node_id);
        return;
    }

    if (node->level < 1 || node->level >= HMAT_LB_LEVELS) {
        error_setg(errp, "Invalid level=%" PRIu8 ", it should be larger than 0 "
                   "and less than or equal to %d", node->level,
                   HMAT_LB_LEVELS - 1);
        return;
    }

    assert(node->associativity < HMAT_CACHE_ASSOCIATIVITY__MAX);
    assert(node->policy < HMAT_CACHE_WRITE_POLICY__MAX);
    if (ms->numa_state->hmat_cache[node->node_id][node->level]) {
        error_setg(errp, "Duplicate configuration of the side cache for "
                   "node-id=%" PRIu32 " and level=%" PRIu8,
                   node->node_id, node->level);
        return;
    }

    if ((node->level > 1) &&
        ms->numa_state->hmat_cache[node->node_id][node->level - 1] &&
        (node->size >=
            ms->numa_state->hmat_cache[node->node_id][node->level - 1]->size)) {
        error_setg(errp, "Invalid size=%" PRIu64 ", the size of level=%" PRIu8
                   " should be less than the size(%" PRIu64 ") of "
                   "level=%u", node->size, node->level,
                   ms->numa_state->hmat_cache[node->node_id]
                                             [node->level - 1]->size,
                   node->level - 1);
        return;
    }

    if ((node->level < HMAT_LB_LEVELS - 1) &&
        ms->numa_state->hmat_cache[node->node_id][node->level + 1] &&
        (node->size <=
            ms->numa_state->hmat_cache[node->node_id][node->level + 1]->size)) {
        error_setg(errp, "Invalid size=%" PRIu64 ", the size of level=%" PRIu8
                   " should be larger than the size(%" PRIu64 ") of "
                   "level=%u", node->size, node->level,
                   ms->numa_state->hmat_cache[node->node_id]
                                             [node->level + 1]->size,
                   node->level + 1);
        return;
    }

    hmat_cache = g_malloc0(sizeof(*hmat_cache));
    memcpy(hmat_cache, node, sizeof(*hmat_cache));
    ms->numa_state->hmat_cache[node->node_id][node->level] = hmat_cache;
}

void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
{
    Error *err = NULL;

    if (!ms->numa_state) {
        error_setg(errp, "NUMA is not supported by this machine-type");
        goto end;
    }

    switch (object->type) {
    case NUMA_OPTIONS_TYPE_NODE:
        parse_numa_node(ms, &object->u.node, &err);
        if (err) {
            goto end;
        }
        break;
    case NUMA_OPTIONS_TYPE_DIST:
        parse_numa_distance(ms, &object->u.dist, &err);
        if (err) {
            goto end;
        }
        break;
    case NUMA_OPTIONS_TYPE_CPU:
        if (!object->u.cpu.has_node_id) {
            error_setg(&err, "Missing mandatory node-id property");
            goto end;
        }
        if (!ms->numa_state->nodes[object->u.cpu.node_id].present) {
            error_setg(&err, "Invalid node-id=%" PRId64 ", NUMA node must be "
                "defined with -numa node,nodeid=ID before it's used with "
                "-numa cpu,node-id=ID", object->u.cpu.node_id);
            goto end;
        }

        machine_set_cpu_numa_node(ms, qapi_NumaCpuOptions_base(&object->u.cpu),
                                  &err);
        break;
    case NUMA_OPTIONS_TYPE_HMAT_LB:
        if (!ms->numa_state->hmat_enabled) {
            error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
                       "(HMAT) is disabled, enable it with -machine hmat=on "
                       "before using any of hmat specific options");
            return;
        }

        parse_numa_hmat_lb(ms->numa_state, &object->u.hmat_lb, &err);
        if (err) {
            goto end;
        }
        break;
    case NUMA_OPTIONS_TYPE_HMAT_CACHE:
        if (!ms->numa_state->hmat_enabled) {
            error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
                       "(HMAT) is disabled, enable it with -machine hmat=on "
                       "before using any of hmat specific options");
            return;
        }

        parse_numa_hmat_cache(ms, &object->u.hmat_cache, &err);
        if (err) {
            goto end;
        }
        break;
    default:
        abort();
    }

end:
    error_propagate(errp, err);
}

static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
{
    NumaOptions *object = NULL;
    MachineState *ms = MACHINE(opaque);
    Error *err = NULL;
    Visitor *v = opts_visitor_new(opts);

    visit_type_NumaOptions(v, NULL, &object, &err);
    visit_free(v);
    if (err) {
        goto end;
    }

    /* Fix up legacy suffix-less format */
    if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) {
        const char *mem_str = qemu_opt_get(opts, "mem");
        qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem);
    }

    set_numa_options(ms, object, &err);

end:
    qapi_free_NumaOptions(object);
    if (err) {
        error_propagate(errp, err);
        return -1;
    }

    return 0;
}

/* If all node pair distances are symmetric, then only distances
 * in one direction are enough. If there is even one asymmetric
 * pair, though, then all distances must be provided. The
 * distance from a node to itself is always NUMA_DISTANCE_MIN,
 * so providing it is never necessary.
 */
static void validate_numa_distance(MachineState *ms)
{
    int src, dst;
    bool is_asymmetrical = false;
    int nb_numa_nodes = ms->numa_state->num_nodes;
    NodeInfo *numa_info = ms->numa_state->nodes;

    for (src = 0; src < nb_numa_nodes; src++) {
        for (dst = src; dst < nb_numa_nodes; dst++) {
            if (numa_info[src].distance[dst] == 0 &&
                numa_info[dst].distance[src] == 0) {
                if (src != dst) {
                    error_report("The distance between node %d and %d is "
                                 "missing, at least one distance value "
                                 "between each nodes should be provided.",
                                 src, dst);
                    exit(EXIT_FAILURE);
                }
            }

            if (numa_info[src].distance[dst] != 0 &&
                numa_info[dst].distance[src] != 0 &&
                numa_info[src].distance[dst] !=
                numa_info[dst].distance[src]) {
                is_asymmetrical = true;
            }
        }
    }

    if (is_asymmetrical) {
        for (src = 0; src < nb_numa_nodes; src++) {
            for (dst = 0; dst < nb_numa_nodes; dst++) {
                if (src != dst && numa_info[src].distance[dst] == 0) {
                    error_report("At least one asymmetrical pair of "
                            "distances is given, please provide distances "
                            "for both directions of all node pairs.");
                    exit(EXIT_FAILURE);
                }
            }
        }
    }
}

static void complete_init_numa_distance(MachineState *ms)
{
    int src, dst;
    NodeInfo *numa_info = ms->numa_state->nodes;

    /* Fixup NUMA distance by symmetric policy because if it is an
     * asymmetric distance table, it should be a complete table and
     * there would not be any missing distance except local node, which
     * is verified by validate_numa_distance above.
     */
    for (src = 0; src < ms->numa_state->num_nodes; src++) {
        for (dst = 0; dst < ms->numa_state->num_nodes; dst++) {
            if (numa_info[src].distance[dst] == 0) {
                if (src == dst) {
                    numa_info[src].distance[dst] = NUMA_DISTANCE_MIN;
                } else {
                    numa_info[src].distance[dst] = numa_info[dst].distance[src];
                }
            }
        }
    }
}

void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
                                 int nb_nodes, ram_addr_t size)
{
    int i;
    uint64_t usedmem = 0;

    /* Align each node according to the alignment
     * requirements of the machine class
     */

    for (i = 0; i < nb_nodes - 1; i++) {
        nodes[i].node_mem = (size / nb_nodes) &
                            ~((1 << mc->numa_mem_align_shift) - 1);
        usedmem += nodes[i].node_mem;
    }
    nodes[i].node_mem = size - usedmem;
}

void numa_default_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
                                  int nb_nodes, ram_addr_t size)
{
    int i;
    uint64_t usedmem = 0, node_mem;
    uint64_t granularity = size / nb_nodes;
    uint64_t propagate = 0;

    for (i = 0; i < nb_nodes - 1; i++) {
        node_mem = (granularity + propagate) &
                   ~((1 << mc->numa_mem_align_shift) - 1);
        propagate = granularity + propagate - node_mem;
        nodes[i].node_mem = node_mem;
        usedmem += node_mem;
    }
    nodes[i].node_mem = size - usedmem;
}

static void numa_init_memdev_container(MachineState *ms, MemoryRegion *ram)
{
    int i;
    uint64_t addr = 0;

    for (i = 0; i < ms->numa_state->num_nodes; i++) {
        uint64_t size = ms->numa_state->nodes[i].node_mem;
        HostMemoryBackend *backend = ms->numa_state->nodes[i].node_memdev;
        if (!backend) {
            continue;
        }
        MemoryRegion *seg = machine_consume_memdev(ms, backend);
        memory_region_add_subregion(ram, addr, seg);
        addr += size;
    }
}

void numa_complete_configuration(MachineState *ms)
{
    int i;
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    NodeInfo *numa_info = ms->numa_state->nodes;

    /*
     * If memory hotplug is enabled (slots > 0) but without '-numa'
     * options explicitly on CLI, guestes will break.
     *
     *   Windows: won't enable memory hotplug without SRAT table at all
     *
     *   Linux: if QEMU is started with initial memory all below 4Gb
     *   and no SRAT table present, guest kernel will use nommu DMA ops,
     *   which breaks 32bit hw drivers when memory is hotplugged and
     *   guest tries to use it with that drivers.
     *
     * Enable NUMA implicitly by adding a new NUMA node automatically.
     *
     * Or if MachineClass::auto_enable_numa is true and no NUMA nodes,
     * assume there is just one node with whole RAM.
     */
    if (ms->numa_state->num_nodes == 0 &&
        ((ms->ram_slots > 0 &&
        mc->auto_enable_numa_with_memhp) ||
        mc->auto_enable_numa)) {
            NumaNodeOptions node = { };
            parse_numa_node(ms, &node, &error_abort);
            numa_info[0].node_mem = ram_size;
    }

    assert(max_numa_nodeid <= MAX_NODES);

    /* No support for sparse NUMA node IDs yet: */
    for (i = max_numa_nodeid - 1; i >= 0; i--) {
        /* Report large node IDs first, to make mistakes easier to spot */
        if (!numa_info[i].present) {
            error_report("numa: Node ID missing: %d", i);
            exit(1);
        }
    }

    /* This must be always true if all nodes are present: */
    assert(ms->numa_state->num_nodes == max_numa_nodeid);

    if (ms->numa_state->num_nodes > 0) {
        uint64_t numa_total;

        if (ms->numa_state->num_nodes > MAX_NODES) {
            ms->numa_state->num_nodes = MAX_NODES;
        }

        /* If no memory size is given for any node, assume the default case
         * and distribute the available memory equally across all nodes
         */
        for (i = 0; i < ms->numa_state->num_nodes; i++) {
            if (numa_info[i].node_mem != 0) {
                break;
            }
        }
        if (i == ms->numa_state->num_nodes) {
            assert(mc->numa_auto_assign_ram);
            mc->numa_auto_assign_ram(mc, numa_info,
                                     ms->numa_state->num_nodes, ram_size);
            if (!qtest_enabled()) {
                warn_report("Default splitting of RAM between nodes is deprecated,"
                            " Use '-numa node,memdev' to explictly define RAM"
                            " allocation per node");
            }
        }

        numa_total = 0;
        for (i = 0; i < ms->numa_state->num_nodes; i++) {
            numa_total += numa_info[i].node_mem;
        }
        if (numa_total != ram_size) {
            error_report("total memory for NUMA nodes (0x%" PRIx64 ")"
                         " should equal RAM size (0x" RAM_ADDR_FMT ")",
                         numa_total, ram_size);
            exit(1);
        }

        if (!numa_uses_legacy_mem() && mc->default_ram_id) {
            ms->ram = g_new(MemoryRegion, 1);
            memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id,
                               ram_size);
            numa_init_memdev_container(ms, ms->ram);
        }
        /* QEMU needs at least all unique node pair distances to build
         * the whole NUMA distance table. QEMU treats the distance table
         * as symmetric by default, i.e. distance A->B == distance B->A.
         * Thus, QEMU is able to complete the distance table
         * initialization even though only distance A->B is provided and
         * distance B->A is not. QEMU knows the distance of a node to
         * itself is always 10, so A->A distances may be omitted. When
         * the distances of two nodes of a pair differ, i.e. distance
         * A->B != distance B->A, then that means the distance table is
         * asymmetric. In this case, the distances for both directions
         * of all node pairs are required.
         */
        if (ms->numa_state->have_numa_distance) {
            /* Validate enough NUMA distance information was provided. */
            validate_numa_distance(ms);

            /* Validation succeeded, now fill in any missing distances. */
            complete_init_numa_distance(ms);
        }
    }
}

void parse_numa_opts(MachineState *ms)
{
    qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, &error_fatal);
}

void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp)
{
    int node_id = object_property_get_int(OBJECT(dev), "node-id", &error_abort);

    if (node_id == CPU_UNSET_NUMA_NODE_ID) {
        /* due to bug in libvirt, it doesn't pass node-id from props on
         * device_add as expected, so we have to fix it up here */
        if (slot->props.has_node_id) {
            object_property_set_int(OBJECT(dev), slot->props.node_id,
                                    "node-id", errp);
        }
    } else if (node_id != slot->props.node_id) {
        error_setg(errp, "invalid node-id, must be %"PRId64,
                   slot->props.node_id);
    }
}

static void numa_stat_memory_devices(NumaNodeMem node_mem[])
{
    MemoryDeviceInfoList *info_list = qmp_memory_device_list();
    MemoryDeviceInfoList *info;
    PCDIMMDeviceInfo     *pcdimm_info;
    VirtioPMEMDeviceInfo *vpi;

    for (info = info_list; info; info = info->next) {
        MemoryDeviceInfo *value = info->value;

        if (value) {
            switch (value->type) {
            case MEMORY_DEVICE_INFO_KIND_DIMM:
            case MEMORY_DEVICE_INFO_KIND_NVDIMM:
                pcdimm_info = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?
                              value->u.dimm.data : value->u.nvdimm.data;
                node_mem[pcdimm_info->node].node_mem += pcdimm_info->size;
                node_mem[pcdimm_info->node].node_plugged_mem +=
                    pcdimm_info->size;
                break;
            case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
                vpi = value->u.virtio_pmem.data;
                /* TODO: once we support numa, assign to right node */
                node_mem[0].node_mem += vpi->size;
                node_mem[0].node_plugged_mem += vpi->size;
                break;
            default:
                g_assert_not_reached();
            }
        }
    }
    qapi_free_MemoryDeviceInfoList(info_list);
}

void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms)
{
    int i;

    if (ms->numa_state == NULL || ms->numa_state->num_nodes <= 0) {
        return;
    }

    numa_stat_memory_devices(node_mem);
    for (i = 0; i < ms->numa_state->num_nodes; i++) {
        node_mem[i].node_mem += ms->numa_state->nodes[i].node_mem;
    }
}

void ram_block_notifier_add(RAMBlockNotifier *n)
{
    QLIST_INSERT_HEAD(&ram_list.ramblock_notifiers, n, next);
}

void ram_block_notifier_remove(RAMBlockNotifier *n)
{
    QLIST_REMOVE(n, next);
}

void ram_block_notify_add(void *host, size_t size)
{
    RAMBlockNotifier *notifier;

    QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
        notifier->ram_block_added(notifier, host, size);
    }
}

void ram_block_notify_remove(void *host, size_t size)
{
    RAMBlockNotifier *notifier;

    QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
        notifier->ram_block_removed(notifier, host, size);
    }
}
