static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,

                            QemuOpts *opts, Error **errp)

{

    uint16_t nodenr;

    uint16List *cpus = NULL;

    MachineClass *mc = MACHINE_GET_CLASS(ms);



    if (node->has_nodeid) {

        nodenr = node->nodeid;

    } else {

        nodenr = nb_numa_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 (!mc->cpu_index_to_instance_props) {

        error_report("NUMA is not supported by this machine-type");

        exit(1);

    }

    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, &error_fatal);

    }



    if (node->has_mem && node->has_memdev) {

        error_setg(errp, "cannot specify both mem= and memdev=");

        return;

    }



    if (have_memdevs == -1) {

        have_memdevs = node->has_memdev;

    }

    if (node->has_memdev != have_memdevs) {

        error_setg(errp, "memdev option must be specified for either "

                   "all or no nodes");

        return;

    }



    if (node->has_mem) {

        uint64_t mem_size = node->mem;

        const char *mem_str = qemu_opt_get(opts, "mem");

        /* Fix up legacy suffix-less format */

        if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {

            mem_size <<= 20;

        }

        numa_info[nodenr].node_mem = mem_size;

    }

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

    }

    numa_info[nodenr].present = true;

    max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);

}
