/*
 * QEMU PowerPC pSeries Logical Partition NUMA associativity handling
 *
 * Copyright IBM Corp. 2020
 *
 * Authors:
 *  Daniel Henrique Barboza      <danielhb413@gmail.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/ppc/spapr_numa.h"
#include "hw/pci-host/spapr.h"
#include "hw/ppc/fdt.h"

/* Moved from hw/ppc/spapr_pci_nvlink2.c */
#define SPAPR_GPU_NUMA_ID           (cpu_to_be32(1))

/*
 * Retrieves max_dist_ref_points of the current NUMA affinity.
 */
static int get_max_dist_ref_points(SpaprMachineState *spapr)
{
    if (spapr_ovec_test(spapr->ov5_cas, OV5_FORM2_AFFINITY)) {
        return FORM2_DIST_REF_POINTS;
    }

    return FORM1_DIST_REF_POINTS;
}

/*
 * Retrieves numa_assoc_size of the current NUMA affinity.
 */
static int get_numa_assoc_size(SpaprMachineState *spapr)
{
    if (spapr_ovec_test(spapr->ov5_cas, OV5_FORM2_AFFINITY)) {
        return FORM2_NUMA_ASSOC_SIZE;
    }

    return FORM1_NUMA_ASSOC_SIZE;
}

/*
 * Retrieves vcpu_assoc_size of the current NUMA affinity.
 *
 * vcpu_assoc_size is the size of ibm,associativity array
 * for CPUs, which has an extra element (vcpu_id) in the end.
 */
static int get_vcpu_assoc_size(SpaprMachineState *spapr)
{
    return get_numa_assoc_size(spapr) + 1;
}

/*
 * Retrieves the ibm,associativity array of NUMA node 'node_id'
 * for the current NUMA affinity.
 */
static const uint32_t *get_associativity(SpaprMachineState *spapr, int node_id)
{
    if (spapr_ovec_test(spapr->ov5_cas, OV5_FORM2_AFFINITY)) {
        return spapr->FORM2_assoc_array[node_id];
    }
    return spapr->FORM1_assoc_array[node_id];
}

/*
 * Wrapper that returns node distance from ms->numa_state->nodes
 * after handling edge cases where the distance might be absent.
 */
static int get_numa_distance(MachineState *ms, int src, int dst)
{
    NodeInfo *numa_info = ms->numa_state->nodes;
    int ret = numa_info[src].distance[dst];

    if (ret != 0) {
        return ret;
    }

    /*
     * In case QEMU adds a default NUMA single node when the user
     * did not add any, or where the user did not supply distances,
     * the distance will be absent (zero). Return local/remote
     * distance in this case.
     */
    if (src == dst) {
        return NUMA_DISTANCE_MIN;
    }

    return NUMA_DISTANCE_DEFAULT;
}

static bool spapr_numa_is_symmetrical(MachineState *ms)
{
    int nb_numa_nodes = ms->numa_state->num_nodes;
    int src, dst;

    for (src = 0; src < nb_numa_nodes; src++) {
        for (dst = src; dst < nb_numa_nodes; dst++) {
            if (get_numa_distance(ms, src, dst) !=
                get_numa_distance(ms, dst, src)) {
                return false;
            }
        }
    }

    return true;
}

/*
 * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
 * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
 * called from vPHB reset handler so we initialize the counter here.
 * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
 * must be equally distant from any other node.
 * The final value of spapr->gpu_numa_id is going to be written to
 * max-associativity-domains in spapr_build_fdt().
 */
unsigned int spapr_numa_initial_nvgpu_numa_id(MachineState *machine)
{
    return MAX(1, machine->numa_state->num_nodes);
}

/*
 * This function will translate the user distances into
 * what the kernel understand as possible values: 10
 * (local distance), 20, 40, 80 and 160, and return the equivalent
 * NUMA level for each. Current heuristic is:
 *  - local distance (10) returns numa_level = 0x4, meaning there is
 *    no rounding for local distance
 *  - distances between 11 and 30 inclusive -> rounded to 20,
 *    numa_level = 0x3
 *  - distances between 31 and 60 inclusive -> rounded to 40,
 *    numa_level = 0x2
 *  - distances between 61 and 120 inclusive -> rounded to 80,
 *    numa_level = 0x1
 *  - everything above 120 returns numa_level = 0 to indicate that
 *    there is no match. This will be calculated as disntace = 160
 *    by the kernel (as of v5.9)
 */
static uint8_t spapr_numa_get_numa_level(uint8_t distance)
{
    if (distance == 10) {
        return 0x4;
    } else if (distance > 11 && distance <= 30) {
        return 0x3;
    } else if (distance > 31 && distance <= 60) {
        return 0x2;
    } else if (distance > 61 && distance <= 120) {
        return 0x1;
    }

    return 0;
}

static void spapr_numa_define_FORM1_domains(SpaprMachineState *spapr)
{
    MachineState *ms = MACHINE(spapr);
    int nb_numa_nodes = ms->numa_state->num_nodes;
    int src, dst, i, j;

    /*
     * Fill all associativity domains of non-zero NUMA nodes with
     * node_id. This is required because the default value (0) is
     * considered a match with associativity domains of node 0.
     */
    for (i = 1; i < nb_numa_nodes; i++) {
        for (j = 1; j < FORM1_DIST_REF_POINTS; j++) {
            spapr->FORM1_assoc_array[i][j] = cpu_to_be32(i);
        }
    }

    for (src = 0; src < nb_numa_nodes; src++) {
        for (dst = src; dst < nb_numa_nodes; dst++) {
            /*
             * This is how the associativity domain between A and B
             * is calculated:
             *
             * - get the distance D between them
             * - get the correspondent NUMA level 'n_level' for D
             * - all associativity arrays were initialized with their own
             * numa_ids, and we're calculating the distance in node_id
             * ascending order, starting from node id 0 (the first node
             * retrieved by numa_state). This will have a cascade effect in
             * the algorithm because the associativity domains that node 0
             * defines will be carried over to other nodes, and node 1
             * associativities will be carried over after taking node 0
             * associativities into account, and so on. This happens because
             * we'll assign assoc_src as the associativity domain of dst
             * as well, for all NUMA levels beyond and including n_level.
             *
             * The PPC kernel expects the associativity domains of node 0 to
             * be always 0, and this algorithm will grant that by default.
             */
            uint8_t distance = get_numa_distance(ms, src, dst);
            uint8_t n_level = spapr_numa_get_numa_level(distance);
            uint32_t assoc_src;

            /*
             * n_level = 0 means that the distance is greater than our last
             * rounded value (120). In this case there is no NUMA level match
             * between src and dst and we can skip the remaining of the loop.
             *
             * The Linux kernel will assume that the distance between src and
             * dst, in this case of no match, is 10 (local distance) doubled
             * for each NUMA it didn't match. We have FORM1_DIST_REF_POINTS
             * levels (4), so this gives us 10*2*2*2*2 = 160.
             *
             * This logic can be seen in the Linux kernel source code, as of
             * v5.9, in arch/powerpc/mm/numa.c, function __node_distance().
             */
            if (n_level == 0) {
                continue;
            }

            /*
             * We must assign all assoc_src to dst, starting from n_level
             * and going up to 0x1.
             */
            for (i = n_level; i > 0; i--) {
                assoc_src = spapr->FORM1_assoc_array[src][i];
                spapr->FORM1_assoc_array[dst][i] = assoc_src;
            }
        }
    }

}

static void spapr_numa_FORM1_affinity_check(MachineState *machine)
{
    int i;

    /*
     * Check we don't have a memory-less/cpu-less NUMA node
     * Firmware relies on the existing memory/cpu topology to provide the
     * NUMA topology to the kernel.
     * And the linux kernel needs to know the NUMA topology at start
     * to be able to hotplug CPUs later.
     */
    if (machine->numa_state->num_nodes) {
        for (i = 0; i < machine->numa_state->num_nodes; ++i) {
            /* check for memory-less node */
            if (machine->numa_state->nodes[i].node_mem == 0) {
                CPUState *cs;
                int found = 0;
                /* check for cpu-less node */
                CPU_FOREACH(cs) {
                    PowerPCCPU *cpu = POWERPC_CPU(cs);
                    if (cpu->node_id == i) {
                        found = 1;
                        break;
                    }
                }
                /* memory-less and cpu-less node */
                if (!found) {
                    error_report(
"Memory-less/cpu-less nodes are not supported with FORM1 NUMA (node %d)", i);
                    exit(EXIT_FAILURE);
                }
            }
        }
    }

    if (!spapr_numa_is_symmetrical(machine)) {
        error_report(
"Asymmetrical NUMA topologies aren't supported in the pSeries machine using FORM1 NUMA");
        exit(EXIT_FAILURE);
    }
}

/*
 * Set NUMA machine state data based on FORM1 affinity semantics.
 */
static void spapr_numa_FORM1_affinity_init(SpaprMachineState *spapr,
                                           MachineState *machine)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    int nb_numa_nodes = machine->numa_state->num_nodes;
    int i, j, max_nodes_with_gpus;

    /*
     * For all associativity arrays: first position is the size,
     * position FORM1_DIST_REF_POINTS is always the numa_id,
     * represented by the index 'i'.
     *
     * This will break on sparse NUMA setups, when/if QEMU starts
     * to support it, because there will be no more guarantee that
     * 'i' will be a valid node_id set by the user.
     */
    for (i = 0; i < nb_numa_nodes; i++) {
        spapr->FORM1_assoc_array[i][0] = cpu_to_be32(FORM1_DIST_REF_POINTS);
        spapr->FORM1_assoc_array[i][FORM1_DIST_REF_POINTS] = cpu_to_be32(i);
    }

    /*
     * Initialize NVLink GPU associativity arrays. We know that
     * the first GPU will take the first available NUMA id, and
     * we'll have a maximum of NVGPU_MAX_NUM GPUs in the machine.
     * At this point we're not sure if there are GPUs or not, but
     * let's initialize the associativity arrays and allow NVLink
     * GPUs to be handled like regular NUMA nodes later on.
     */
    max_nodes_with_gpus = nb_numa_nodes + NVGPU_MAX_NUM;

    for (i = nb_numa_nodes; i < max_nodes_with_gpus; i++) {
        spapr->FORM1_assoc_array[i][0] = cpu_to_be32(FORM1_DIST_REF_POINTS);

        for (j = 1; j < FORM1_DIST_REF_POINTS; j++) {
            uint32_t gpu_assoc = smc->pre_5_1_assoc_refpoints ?
                                 SPAPR_GPU_NUMA_ID : cpu_to_be32(i);
            spapr->FORM1_assoc_array[i][j] = gpu_assoc;
        }

        spapr->FORM1_assoc_array[i][FORM1_DIST_REF_POINTS] = cpu_to_be32(i);
    }

    /*
     * Guests pseries-5.1 and older uses zeroed associativity domains,
     * i.e. no domain definition based on NUMA distance input.
     *
     * Same thing with guests that have only one NUMA node.
     */
    if (smc->pre_5_2_numa_associativity ||
        machine->numa_state->num_nodes <= 1) {
        return;
    }

    spapr_numa_define_FORM1_domains(spapr);
}

/*
 * Init NUMA FORM2 machine state data
 */
static void spapr_numa_FORM2_affinity_init(SpaprMachineState *spapr)
{
    int i;

    /*
     * For all resources but CPUs, FORM2 associativity arrays will
     * be a size 2 array with the following format:
     *
     * ibm,associativity = {1, numa_id}
     *
     * CPUs will write an additional 'vcpu_id' on top of the arrays
     * being initialized here. 'numa_id' is represented by the
     * index 'i' of the loop.
     *
     * Given that this initialization is also valid for GPU associativity
     * arrays, handle everything in one single step by populating the
     * arrays up to NUMA_NODES_MAX_NUM.
     */
    for (i = 0; i < NUMA_NODES_MAX_NUM; i++) {
        spapr->FORM2_assoc_array[i][0] = cpu_to_be32(1);
        spapr->FORM2_assoc_array[i][1] = cpu_to_be32(i);
    }
}

void spapr_numa_associativity_init(SpaprMachineState *spapr,
                                   MachineState *machine)
{
    spapr_numa_FORM1_affinity_init(spapr, machine);
    spapr_numa_FORM2_affinity_init(spapr);
}

void spapr_numa_associativity_check(SpaprMachineState *spapr)
{
    /*
     * FORM2 does not have any restrictions we need to handle
     * at CAS time, for now.
     */
    if (spapr_ovec_test(spapr->ov5_cas, OV5_FORM2_AFFINITY)) {
        return;
    }

    spapr_numa_FORM1_affinity_check(MACHINE(spapr));
}

void spapr_numa_write_associativity_dt(SpaprMachineState *spapr, void *fdt,
                                       int offset, int nodeid)
{
    const uint32_t *associativity = get_associativity(spapr, nodeid);

    _FDT((fdt_setprop(fdt, offset, "ibm,associativity",
                      associativity,
                      get_numa_assoc_size(spapr) * sizeof(uint32_t))));
}

static uint32_t *spapr_numa_get_vcpu_assoc(SpaprMachineState *spapr,
                                           PowerPCCPU *cpu)
{
    const uint32_t *associativity = get_associativity(spapr, cpu->node_id);
    int max_distance_ref_points = get_max_dist_ref_points(spapr);
    int vcpu_assoc_size = get_vcpu_assoc_size(spapr);
    uint32_t *vcpu_assoc = g_new(uint32_t, vcpu_assoc_size);
    int index = spapr_get_vcpu_id(cpu);

    /*
     * VCPUs have an extra 'cpu_id' value in ibm,associativity
     * compared to other resources. Increment the size at index
     * 0, put cpu_id last, then copy the remaining associativity
     * domains.
     */
    vcpu_assoc[0] = cpu_to_be32(max_distance_ref_points + 1);
    vcpu_assoc[vcpu_assoc_size - 1] = cpu_to_be32(index);
    memcpy(vcpu_assoc + 1, associativity + 1,
           (vcpu_assoc_size - 2) * sizeof(uint32_t));

    return vcpu_assoc;
}

int spapr_numa_fixup_cpu_dt(SpaprMachineState *spapr, void *fdt,
                            int offset, PowerPCCPU *cpu)
{
    g_autofree uint32_t *vcpu_assoc = NULL;
    int vcpu_assoc_size = get_vcpu_assoc_size(spapr);

    vcpu_assoc = spapr_numa_get_vcpu_assoc(spapr, cpu);

    /* Advertise NUMA via ibm,associativity */
    return fdt_setprop(fdt, offset, "ibm,associativity", vcpu_assoc,
                       vcpu_assoc_size * sizeof(uint32_t));
}


int spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt,
                                         int offset)
{
    MachineState *machine = MACHINE(spapr);
    int max_distance_ref_points = get_max_dist_ref_points(spapr);
    int nb_numa_nodes = machine->numa_state->num_nodes;
    int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
    g_autofree uint32_t *int_buf = NULL;
    uint32_t *cur_index;
    int i;

    /* ibm,associativity-lookup-arrays */
    int_buf = g_new0(uint32_t, nr_nodes * max_distance_ref_points + 2);
    cur_index = int_buf;
    int_buf[0] = cpu_to_be32(nr_nodes);
     /* Number of entries per associativity list */
    int_buf[1] = cpu_to_be32(max_distance_ref_points);
    cur_index += 2;
    for (i = 0; i < nr_nodes; i++) {
        /*
         * For the lookup-array we use the ibm,associativity array of the
         * current NUMA affinity, without the first element (size).
         */
        const uint32_t *associativity = get_associativity(spapr, i);
        memcpy(cur_index, ++associativity,
               sizeof(uint32_t) * max_distance_ref_points);
        cur_index += max_distance_ref_points;
    }

    return fdt_setprop(fdt, offset, "ibm,associativity-lookup-arrays",
                       int_buf, (cur_index - int_buf) * sizeof(uint32_t));
}

static void spapr_numa_FORM1_write_rtas_dt(SpaprMachineState *spapr,
                                           void *fdt, int rtas)
{
    MachineState *ms = MACHINE(spapr);
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    uint32_t number_nvgpus_nodes = spapr->gpu_numa_id -
                                   spapr_numa_initial_nvgpu_numa_id(ms);
    uint32_t refpoints[] = {
        cpu_to_be32(0x4),
        cpu_to_be32(0x3),
        cpu_to_be32(0x2),
        cpu_to_be32(0x1),
    };
    uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
    uint32_t maxdomain = ms->numa_state->num_nodes + number_nvgpus_nodes;
    uint32_t maxdomains[] = {
        cpu_to_be32(4),
        cpu_to_be32(maxdomain),
        cpu_to_be32(maxdomain),
        cpu_to_be32(maxdomain),
        cpu_to_be32(maxdomain)
    };

    if (smc->pre_5_2_numa_associativity ||
        ms->numa_state->num_nodes <= 1) {
        uint32_t legacy_refpoints[] = {
            cpu_to_be32(0x4),
            cpu_to_be32(0x4),
            cpu_to_be32(0x2),
        };
        uint32_t legacy_maxdomain = spapr->gpu_numa_id > 1 ? 1 : 0;
        uint32_t legacy_maxdomains[] = {
            cpu_to_be32(4),
            cpu_to_be32(legacy_maxdomain),
            cpu_to_be32(legacy_maxdomain),
            cpu_to_be32(legacy_maxdomain),
            cpu_to_be32(spapr->gpu_numa_id),
        };

        G_STATIC_ASSERT(sizeof(legacy_refpoints) <= sizeof(refpoints));
        G_STATIC_ASSERT(sizeof(legacy_maxdomains) <= sizeof(maxdomains));

        nr_refpoints = 3;

        memcpy(refpoints, legacy_refpoints, sizeof(legacy_refpoints));
        memcpy(maxdomains, legacy_maxdomains, sizeof(legacy_maxdomains));

        /* pseries-5.0 and older reference-points array is {0x4, 0x4} */
        if (smc->pre_5_1_assoc_refpoints) {
            nr_refpoints = 2;
        }
    }

    _FDT(fdt_setprop(fdt, rtas, "ibm,associativity-reference-points",
                     refpoints, nr_refpoints * sizeof(refpoints[0])));

    _FDT(fdt_setprop(fdt, rtas, "ibm,max-associativity-domains",
                     maxdomains, sizeof(maxdomains)));
}

static void spapr_numa_FORM2_write_rtas_tables(SpaprMachineState *spapr,
                                               void *fdt, int rtas)
{
    MachineState *ms = MACHINE(spapr);
    int nb_numa_nodes = ms->numa_state->num_nodes;
    int distance_table_entries = nb_numa_nodes * nb_numa_nodes;
    g_autofree uint32_t *lookup_index_table = NULL;
    g_autofree uint8_t *distance_table = NULL;
    int src, dst, i, distance_table_size;

    /*
     * ibm,numa-lookup-index-table: array with length and a
     * list of NUMA ids present in the guest.
     */
    lookup_index_table = g_new0(uint32_t, nb_numa_nodes + 1);
    lookup_index_table[0] = cpu_to_be32(nb_numa_nodes);

    for (i = 0; i < nb_numa_nodes; i++) {
        lookup_index_table[i + 1] = cpu_to_be32(i);
    }

    _FDT(fdt_setprop(fdt, rtas, "ibm,numa-lookup-index-table",
                     lookup_index_table,
                     (nb_numa_nodes + 1) * sizeof(uint32_t)));

    /*
     * ibm,numa-distance-table: contains all node distances. First
     * element is the size of the table as uint32, followed up
     * by all the uint8 distances from the first NUMA node, then all
     * distances from the second NUMA node and so on.
     *
     * ibm,numa-lookup-index-table is used by guest to navigate this
     * array because NUMA ids can be sparse (node 0 is the first,
     * node 8 is the second ...).
     */
    distance_table_size = distance_table_entries * sizeof(uint8_t) +
                          sizeof(uint32_t);
    distance_table = g_new0(uint8_t, distance_table_size);
    stl_be_p(distance_table, distance_table_entries);

    /* Skip the uint32_t array length at the start */
    i = sizeof(uint32_t);

    for (src = 0; src < nb_numa_nodes; src++) {
        for (dst = 0; dst < nb_numa_nodes; dst++) {
            distance_table[i++] = get_numa_distance(ms, src, dst);
        }
    }

    _FDT(fdt_setprop(fdt, rtas, "ibm,numa-distance-table",
                     distance_table, distance_table_size));
}

/*
 * This helper could be compressed in a single function with
 * FORM1 logic since we're setting the same DT values, with the
 * difference being a call to spapr_numa_FORM2_write_rtas_tables()
 * in the end. The separation was made to avoid clogging FORM1 code
 * which already has to deal with compat modes from previous
 * QEMU machine types.
 */
static void spapr_numa_FORM2_write_rtas_dt(SpaprMachineState *spapr,
                                           void *fdt, int rtas)
{
    MachineState *ms = MACHINE(spapr);
    uint32_t number_nvgpus_nodes = spapr->gpu_numa_id -
                                   spapr_numa_initial_nvgpu_numa_id(ms);

    /*
     * In FORM2, ibm,associativity-reference-points will point to
     * the element in the ibm,associativity array that contains the
     * primary domain index (for FORM2, the first element).
     *
     * This value (in our case, the numa-id) is then used as an index
     * to retrieve all other attributes of the node (distance,
     * bandwidth, latency) via ibm,numa-lookup-index-table and other
     * ibm,numa-*-table properties.
     */
    uint32_t refpoints[] = { cpu_to_be32(1) };

    uint32_t maxdomain = ms->numa_state->num_nodes + number_nvgpus_nodes;
    uint32_t maxdomains[] = { cpu_to_be32(1), cpu_to_be32(maxdomain) };

    _FDT(fdt_setprop(fdt, rtas, "ibm,associativity-reference-points",
                     refpoints, sizeof(refpoints)));

    _FDT(fdt_setprop(fdt, rtas, "ibm,max-associativity-domains",
                     maxdomains, sizeof(maxdomains)));

    spapr_numa_FORM2_write_rtas_tables(spapr, fdt, rtas);
}

/*
 * Helper that writes ibm,associativity-reference-points and
 * max-associativity-domains in the RTAS pointed by @rtas
 * in the DT @fdt.
 */
void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int rtas)
{
    if (spapr_ovec_test(spapr->ov5_cas, OV5_FORM2_AFFINITY)) {
        spapr_numa_FORM2_write_rtas_dt(spapr, fdt, rtas);
        return;
    }

    spapr_numa_FORM1_write_rtas_dt(spapr, fdt, rtas);
}

static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
                                              SpaprMachineState *spapr,
                                              target_ulong opcode,
                                              target_ulong *args)
{
    g_autofree uint32_t *vcpu_assoc = NULL;
    target_ulong flags = args[0];
    target_ulong procno = args[1];
    PowerPCCPU *tcpu;
    int idx, assoc_idx;
    int vcpu_assoc_size = get_vcpu_assoc_size(spapr);

    /* only support procno from H_REGISTER_VPA */
    if (flags != 0x1) {
        return H_FUNCTION;
    }

    tcpu = spapr_find_cpu(procno);
    if (tcpu == NULL) {
        return H_P2;
    }

    /*
     * Given that we want to be flexible with the sizes and indexes,
     * we must consider that there is a hard limit of how many
     * associativities domain we can fit in R4 up to R9, which would be
     * 12 associativity domains for vcpus. Assert and bail if that's
     * not the case.
     */
    g_assert((vcpu_assoc_size - 1) <= 12);

    vcpu_assoc = spapr_numa_get_vcpu_assoc(spapr, tcpu);
    /* assoc_idx starts at 1 to skip associativity size */
    assoc_idx = 1;

#define ASSOCIATIVITY(a, b) (((uint64_t)(a) << 32) | \
                             ((uint64_t)(b) & 0xffffffff))

    for (idx = 0; idx < 6; idx++) {
        int32_t a, b;

        /*
         * vcpu_assoc[] will contain the associativity domains for tcpu,
         * including tcpu->node_id and procno, meaning that we don't
         * need to use these variables here.
         *
         * We'll read 2 values at a time to fill up the ASSOCIATIVITY()
         * macro. The ternary will fill the remaining registers with -1
         * after we went through vcpu_assoc[].
         */
        a = assoc_idx < vcpu_assoc_size ?
            be32_to_cpu(vcpu_assoc[assoc_idx++]) : -1;
        b = assoc_idx < vcpu_assoc_size ?
            be32_to_cpu(vcpu_assoc[assoc_idx++]) : -1;

        args[idx] = ASSOCIATIVITY(a, b);
    }
#undef ASSOCIATIVITY

    return H_SUCCESS;
}

static void spapr_numa_register_types(void)
{
    /* Virtual Processor Home Node */
    spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
                             h_home_node_associativity);
}

type_init(spapr_numa_register_types)
