/*
 * 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 "exec/cpu-common.h"
#include "exec/ramlist.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 "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;
    }

    /*
     * 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;
    }

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

    if (node->has_mem) {
        if (!mc->numa_mem_supported) {
            error_setg(errp, "Parameter -numa node,mem is not supported by this"
                      " machine type");
            error_append_hint(errp, "Use -numa node,memdev instead\n");
            return;
        }

        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->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);
    }

    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 &&
        !numa_info[node->initiator].has_gi) {
        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 <= HMAT_LB_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 >= HMAT_LB_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 {
        g_assert_not_reached();
    }

    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] == NULL) {
        error_setg(errp, "Cache level=%u shall be defined first",
                   node->level - 1);
        return;
    }

    if ((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;
    }

    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 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;
    }

    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)
{
    if (!ms->numa_state) {
        error_setg(errp, "NUMA is not supported by this machine-type");
        return;
    }

    switch (object->type) {
    case NUMA_OPTIONS_TYPE_NODE:
        parse_numa_node(ms, &object->u.node, errp);
        break;
    case NUMA_OPTIONS_TYPE_DIST:
        parse_numa_distance(ms, &object->u.dist, errp);
        break;
    case NUMA_OPTIONS_TYPE_CPU:
        if (!object->u.cpu.has_node_id) {
            error_setg(errp, "Missing mandatory node-id property");
            return;
        }
        if (!ms->numa_state->nodes[object->u.cpu.node_id].present) {
            error_setg(errp, "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);
            return;
        }

        machine_set_cpu_numa_node(ms,
                                  qapi_NumaCpuOptions_base(&object->u.cpu),
                                  errp);
        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, errp);
        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, errp);
        break;
    default:
        abort();
    }
}

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, errp);
    visit_free(v);
    if (!object) {
        return -1;
    }

    /* 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");
        int ret = qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem);

        if (ret < 0) {
            error_setg_errno(&err, -ret, "could not parse memory size '%s'",
                             mem_str);
        }
    }

    if (!err) {
        set_numa_options(ms, object, &err);
    }

    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];
                }
            }
        }
    }
}

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 (slot > 0) or memory devices are enabled
     * (ms->maxram_size > ms->ram_size) but without '-numa' options explicitly on
     * CLI, guests 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 && mc->auto_enable_numa_with_memhp) ||
         (ms->maxram_size > ms->ram_size && mc->auto_enable_numa_with_memdev) ||
         mc->auto_enable_numa)) {
            NumaNodeOptions node = { };
            parse_numa_node(ms, &node, &error_abort);
            numa_info[0].node_mem = ms->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;

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

        if (!numa_uses_legacy_mem() && mc->default_ram_id) {
            if (ms->memdev) {
                error_report("'-machine memory-backend' and '-numa memdev'"
                             " properties are mutually exclusive");
                exit(1);
            }
            ms->ram = g_new(MemoryRegion, 1);
            memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id,
                               ms->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), "node-id",
                                    slot->props.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;
    VirtioMEMDeviceInfo *vmi;
    SgxEPCDeviceInfo *se;

    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;
            case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:
                vmi = value->u.virtio_mem.data;
                node_mem[vmi->node].node_mem += vmi->size;
                node_mem[vmi->node].node_plugged_mem += vmi->size;
                break;
            case MEMORY_DEVICE_INFO_KIND_SGX_EPC:
                se = value->u.sgx_epc.data;
                node_mem[se->node].node_mem += se->size;
                node_mem[se->node].node_plugged_mem = 0;
                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;
    }
}

static int ram_block_notify_add_single(RAMBlock *rb, void *opaque)
{
    const ram_addr_t max_size = qemu_ram_get_max_length(rb);
    const ram_addr_t size = qemu_ram_get_used_length(rb);
    void *host = qemu_ram_get_host_addr(rb);
    RAMBlockNotifier *notifier = opaque;

    if (host) {
        notifier->ram_block_added(notifier, host, size, max_size);
    }
    return 0;
}

static int ram_block_notify_remove_single(RAMBlock *rb, void *opaque)
{
    const ram_addr_t max_size = qemu_ram_get_max_length(rb);
    const ram_addr_t size = qemu_ram_get_used_length(rb);
    void *host = qemu_ram_get_host_addr(rb);
    RAMBlockNotifier *notifier = opaque;

    if (host) {
        notifier->ram_block_removed(notifier, host, size, max_size);
    }
    return 0;
}

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

    /* Notify about all existing ram blocks. */
    if (n->ram_block_added) {
        qemu_ram_foreach_block(ram_block_notify_add_single, n);
    }
}

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

    if (n->ram_block_removed) {
        qemu_ram_foreach_block(ram_block_notify_remove_single, n);
    }
}

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

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

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

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

void ram_block_notify_resize(void *host, size_t old_size, size_t new_size)
{
    RAMBlockNotifier *notifier;
    RAMBlockNotifier *next;

    QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next) {
        if (notifier->ram_block_resized) {
            notifier->ram_block_resized(notifier, host, old_size, new_size);
        }
    }
}
