cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

numa-test.c (22518B)


      1/*
      2 * NUMA configuration test cases
      3 *
      4 * Copyright (c) 2017 Red Hat Inc.
      5 * Authors:
      6 *  Igor Mammedov <imammedo@redhat.com>
      7 *
      8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      9 * See the COPYING file in the top-level directory.
     10 */
     11
     12#include "qemu/osdep.h"
     13#include "libqos/libqtest.h"
     14#include "qapi/qmp/qdict.h"
     15#include "qapi/qmp/qlist.h"
     16
     17static char *make_cli(const GString *generic_cli, const char *test_cli)
     18{
     19    return g_strdup_printf("%s %s", generic_cli->str, test_cli);
     20}
     21
     22static void test_mon_explicit(const void *data)
     23{
     24    QTestState *qts;
     25    g_autofree char *s = NULL;
     26    g_autofree char *cli = NULL;
     27
     28    cli = make_cli(data, "-machine smp.cpus=8 -numa node,nodeid=0,memdev=ram,cpus=0-3 "
     29                         "-numa node,nodeid=1,cpus=4-7");
     30    qts = qtest_init(cli);
     31
     32    s = qtest_hmp(qts, "info numa");
     33    g_assert(strstr(s, "node 0 cpus: 0 1 2 3"));
     34    g_assert(strstr(s, "node 1 cpus: 4 5 6 7"));
     35
     36    qtest_quit(qts);
     37}
     38
     39static void test_def_cpu_split(const void *data)
     40{
     41    QTestState *qts;
     42    g_autofree char *s = NULL;
     43    g_autofree char *cli = NULL;
     44
     45    cli = make_cli(data, "-machine smp.cpus=8,smp.sockets=8 "
     46                         "-numa node,memdev=ram -numa node");
     47    qts = qtest_init(cli);
     48
     49    s = qtest_hmp(qts, "info numa");
     50    g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
     51    g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
     52
     53    qtest_quit(qts);
     54}
     55
     56static void test_mon_partial(const void *data)
     57{
     58    QTestState *qts;
     59    g_autofree char *s = NULL;
     60    g_autofree char *cli = NULL;
     61
     62    cli = make_cli(data, "-machine smp.cpus=8 "
     63                   "-numa node,nodeid=0,memdev=ram,cpus=0-1 "
     64                   "-numa node,nodeid=1,cpus=4-5 ");
     65    qts = qtest_init(cli);
     66
     67    s = qtest_hmp(qts, "info numa");
     68    g_assert(strstr(s, "node 0 cpus: 0 1 2 3 6 7"));
     69    g_assert(strstr(s, "node 1 cpus: 4 5"));
     70
     71    qtest_quit(qts);
     72}
     73
     74static QList *get_cpus(QTestState *qts, QDict **resp)
     75{
     76    *resp = qtest_qmp(qts, "{ 'execute': 'query-cpus-fast' }");
     77    g_assert(*resp);
     78    g_assert(qdict_haskey(*resp, "return"));
     79    return qdict_get_qlist(*resp, "return");
     80}
     81
     82static void test_query_cpus(const void *data)
     83{
     84    QDict *resp;
     85    QList *cpus;
     86    QObject *e;
     87    QTestState *qts;
     88    g_autofree char *cli = NULL;
     89
     90    cli = make_cli(data, "-machine smp.cpus=8 -numa node,memdev=ram,cpus=0-3 "
     91                         "-numa node,cpus=4-7");
     92    qts = qtest_init(cli);
     93    cpus = get_cpus(qts, &resp);
     94    g_assert(cpus);
     95
     96    while ((e = qlist_pop(cpus))) {
     97        QDict *cpu, *props;
     98        int64_t cpu_idx, node;
     99
    100        cpu = qobject_to(QDict, e);
    101        g_assert(qdict_haskey(cpu, "cpu-index"));
    102        g_assert(qdict_haskey(cpu, "props"));
    103
    104        cpu_idx = qdict_get_int(cpu, "cpu-index");
    105        props = qdict_get_qdict(cpu, "props");
    106        g_assert(qdict_haskey(props, "node-id"));
    107        node = qdict_get_int(props, "node-id");
    108        if (cpu_idx >= 0 && cpu_idx < 4) {
    109            g_assert_cmpint(node, ==, 0);
    110        } else {
    111            g_assert_cmpint(node, ==, 1);
    112        }
    113        qobject_unref(e);
    114    }
    115
    116    qobject_unref(resp);
    117    qtest_quit(qts);
    118}
    119
    120static void pc_numa_cpu(const void *data)
    121{
    122    QDict *resp;
    123    QList *cpus;
    124    QObject *e;
    125    QTestState *qts;
    126    g_autofree char *cli = NULL;
    127
    128    cli = make_cli(data, "-cpu pentium -machine smp.cpus=8,smp.sockets=2,smp.cores=2,smp.threads=2 "
    129        "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
    130        "-numa cpu,node-id=1,socket-id=0 "
    131        "-numa cpu,node-id=0,socket-id=1,core-id=0 "
    132        "-numa cpu,node-id=0,socket-id=1,core-id=1,thread-id=0 "
    133        "-numa cpu,node-id=1,socket-id=1,core-id=1,thread-id=1");
    134    qts = qtest_init(cli);
    135    cpus = get_cpus(qts, &resp);
    136    g_assert(cpus);
    137
    138    while ((e = qlist_pop(cpus))) {
    139        QDict *cpu, *props;
    140        int64_t socket, core, thread, node;
    141
    142        cpu = qobject_to(QDict, e);
    143        g_assert(qdict_haskey(cpu, "props"));
    144        props = qdict_get_qdict(cpu, "props");
    145
    146        g_assert(qdict_haskey(props, "node-id"));
    147        node = qdict_get_int(props, "node-id");
    148        g_assert(qdict_haskey(props, "socket-id"));
    149        socket = qdict_get_int(props, "socket-id");
    150        g_assert(qdict_haskey(props, "core-id"));
    151        core = qdict_get_int(props, "core-id");
    152        g_assert(qdict_haskey(props, "thread-id"));
    153        thread = qdict_get_int(props, "thread-id");
    154
    155        if (socket == 0) {
    156            g_assert_cmpint(node, ==, 1);
    157        } else if (socket == 1 && core == 0) {
    158            g_assert_cmpint(node, ==, 0);
    159        } else if (socket == 1 && core == 1 && thread == 0) {
    160            g_assert_cmpint(node, ==, 0);
    161        } else if (socket == 1 && core == 1 && thread == 1) {
    162            g_assert_cmpint(node, ==, 1);
    163        } else {
    164            g_assert(false);
    165        }
    166        qobject_unref(e);
    167    }
    168
    169    qobject_unref(resp);
    170    qtest_quit(qts);
    171}
    172
    173static void spapr_numa_cpu(const void *data)
    174{
    175    QDict *resp;
    176    QList *cpus;
    177    QObject *e;
    178    QTestState *qts;
    179    g_autofree char *cli = NULL;
    180
    181    cli = make_cli(data, "-machine smp.cpus=4,smp.cores=4 "
    182        "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
    183        "-numa cpu,node-id=0,core-id=0 "
    184        "-numa cpu,node-id=0,core-id=1 "
    185        "-numa cpu,node-id=0,core-id=2 "
    186        "-numa cpu,node-id=1,core-id=3");
    187    qts = qtest_init(cli);
    188    cpus = get_cpus(qts, &resp);
    189    g_assert(cpus);
    190
    191    while ((e = qlist_pop(cpus))) {
    192        QDict *cpu, *props;
    193        int64_t core, node;
    194
    195        cpu = qobject_to(QDict, e);
    196        g_assert(qdict_haskey(cpu, "props"));
    197        props = qdict_get_qdict(cpu, "props");
    198
    199        g_assert(qdict_haskey(props, "node-id"));
    200        node = qdict_get_int(props, "node-id");
    201        g_assert(qdict_haskey(props, "core-id"));
    202        core = qdict_get_int(props, "core-id");
    203
    204        if (core >= 0 && core < 3) {
    205            g_assert_cmpint(node, ==, 0);
    206        } else if (core == 3) {
    207            g_assert_cmpint(node, ==, 1);
    208        } else {
    209            g_assert(false);
    210        }
    211        qobject_unref(e);
    212    }
    213
    214    qobject_unref(resp);
    215    qtest_quit(qts);
    216}
    217
    218static void aarch64_numa_cpu(const void *data)
    219{
    220    QDict *resp;
    221    QList *cpus;
    222    QObject *e;
    223    QTestState *qts;
    224    g_autofree char *cli = NULL;
    225
    226    cli = make_cli(data, "-machine smp.cpus=2 "
    227        "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
    228        "-numa cpu,node-id=1,thread-id=0 "
    229        "-numa cpu,node-id=0,thread-id=1");
    230    qts = qtest_init(cli);
    231    cpus = get_cpus(qts, &resp);
    232    g_assert(cpus);
    233
    234    while ((e = qlist_pop(cpus))) {
    235        QDict *cpu, *props;
    236        int64_t thread, node;
    237
    238        cpu = qobject_to(QDict, e);
    239        g_assert(qdict_haskey(cpu, "props"));
    240        props = qdict_get_qdict(cpu, "props");
    241
    242        g_assert(qdict_haskey(props, "node-id"));
    243        node = qdict_get_int(props, "node-id");
    244        g_assert(qdict_haskey(props, "thread-id"));
    245        thread = qdict_get_int(props, "thread-id");
    246
    247        if (thread == 0) {
    248            g_assert_cmpint(node, ==, 1);
    249        } else if (thread == 1) {
    250            g_assert_cmpint(node, ==, 0);
    251        } else {
    252            g_assert(false);
    253        }
    254        qobject_unref(e);
    255    }
    256
    257    qobject_unref(resp);
    258    qtest_quit(qts);
    259}
    260
    261static void pc_dynamic_cpu_cfg(const void *data)
    262{
    263    QObject *e;
    264    QDict *resp;
    265    QList *cpus;
    266    QTestState *qs;
    267    g_autofree char *cli = NULL;
    268
    269    cli = make_cli(data, "-nodefaults --preconfig "
    270                         "-machine smp.cpus=2,smp.sockets=2");
    271    qs = qtest_init(cli);
    272
    273    /* create 2 numa nodes */
    274    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    275        " 'arguments': { 'type': 'node', 'nodeid': 0, 'memdev': 'ram' } }")));
    276    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    277        " 'arguments': { 'type': 'node', 'nodeid': 1 } }")));
    278
    279    /* map 2 cpus in non default reverse order
    280     * i.e socket1->node0, socket0->node1
    281     */
    282    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    283        " 'arguments': { 'type': 'cpu', 'node-id': 0, 'socket-id': 1 } }")));
    284    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    285        " 'arguments': { 'type': 'cpu', 'node-id': 1, 'socket-id': 0 } }")));
    286
    287    /* let machine initialization to complete and run */
    288    g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'x-exit-preconfig' }")));
    289    qtest_qmp_eventwait(qs, "RESUME");
    290
    291    /* check that CPUs are mapped as expected */
    292    resp = qtest_qmp(qs, "{ 'execute': 'query-hotpluggable-cpus'}");
    293    g_assert(qdict_haskey(resp, "return"));
    294    cpus = qdict_get_qlist(resp, "return");
    295    g_assert(cpus);
    296    while ((e = qlist_pop(cpus))) {
    297        const QDict *cpu, *props;
    298        int64_t socket, node;
    299
    300        cpu = qobject_to(QDict, e);
    301        g_assert(qdict_haskey(cpu, "props"));
    302        props = qdict_get_qdict(cpu, "props");
    303
    304        g_assert(qdict_haskey(props, "node-id"));
    305        node = qdict_get_int(props, "node-id");
    306        g_assert(qdict_haskey(props, "socket-id"));
    307        socket = qdict_get_int(props, "socket-id");
    308
    309        if (socket == 0) {
    310            g_assert_cmpint(node, ==, 1);
    311        } else if (socket == 1) {
    312            g_assert_cmpint(node, ==, 0);
    313        } else {
    314            g_assert(false);
    315        }
    316        qobject_unref(e);
    317    }
    318    qobject_unref(resp);
    319
    320    qtest_quit(qs);
    321}
    322
    323static void pc_hmat_build_cfg(const void *data)
    324{
    325    QTestState *qs;
    326    g_autofree char *cli = NULL;
    327
    328    cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on "
    329                         "-machine smp.cpus=2,smp.sockets=2 "
    330                         "-m 128M,slots=2,maxmem=1G "
    331                         "-object memory-backend-ram,size=64M,id=m0 "
    332                         "-object memory-backend-ram,size=64M,id=m1 "
    333                         "-numa node,nodeid=0,memdev=m0 "
    334                         "-numa node,nodeid=1,memdev=m1,initiator=0 "
    335                         "-numa cpu,node-id=0,socket-id=0 "
    336                         "-numa cpu,node-id=0,socket-id=1");
    337    qs = qtest_init(cli);
    338
    339    /* Fail: Initiator should be less than the number of nodes */
    340    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    341        " 'arguments': { 'type': 'hmat-lb', 'initiator': 2, 'target': 0,"
    342        " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }")));
    343
    344    /* Fail: Target should be less than the number of nodes */
    345    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    346        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 2,"
    347        " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }")));
    348
    349    /* Fail: Initiator should contain cpu */
    350    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    351        " 'arguments': { 'type': 'hmat-lb', 'initiator': 1, 'target': 0,"
    352        " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }")));
    353
    354    /* Fail: Data-type mismatch */
    355    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    356        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    357        " 'hierarchy': \"memory\", 'data-type': \"write-latency\","
    358        " 'bandwidth': 524288000 } }")));
    359    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    360        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    361        " 'hierarchy': \"memory\", 'data-type': \"read-bandwidth\","
    362        " 'latency': 5 } }")));
    363
    364    /* Fail: Bandwidth should be 1MB (1048576) aligned */
    365    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    366        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    367        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
    368        " 'bandwidth': 1048575 } }")));
    369
    370    /* Configuring HMAT bandwidth and latency details */
    371    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    372        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    373        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
    374        " 'latency': 1 } }")));    /* 1 ns */
    375    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    376        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    377        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
    378        " 'latency': 5 } }")));    /* Fail: Duplicate configuration */
    379    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    380        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    381        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
    382        " 'bandwidth': 68717379584 } }")));    /* 65534 MB/s */
    383    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    384        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
    385        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
    386        " 'latency': 65534 } }")));    /* 65534 ns */
    387    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    388        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
    389        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
    390        " 'bandwidth': 34358689792 } }")));    /* 32767 MB/s */
    391
    392    /* Fail: node_id should be less than the number of nodes */
    393    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    394        " 'arguments': { 'type': 'hmat-cache', 'node-id': 2, 'size': 10240,"
    395        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
    396        " 'line': 8 } }")));
    397
    398    /* Fail: level should be less than HMAT_LB_LEVELS (4) */
    399    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    400        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    401        " 'level': 4, 'associativity': \"direct\", 'policy': \"write-back\","
    402        " 'line': 8 } }")));
    403
    404    /* Fail: associativity option should be 'none', if level is 0 */
    405    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    406        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    407        " 'level': 0, 'associativity': \"direct\", 'policy': \"none\","
    408        " 'line': 0 } }")));
    409    /* Fail: policy option should be 'none', if level is 0 */
    410    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    411        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    412        " 'level': 0, 'associativity': \"none\", 'policy': \"write-back\","
    413        " 'line': 0 } }")));
    414    /* Fail: line option should be 0, if level is 0 */
    415    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    416        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    417        " 'level': 0, 'associativity': \"none\", 'policy': \"none\","
    418        " 'line': 8 } }")));
    419
    420    /* Configuring HMAT memory side cache attributes */
    421    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    422        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    423        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
    424        " 'line': 8 } }")));
    425    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    426        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    427        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
    428        " 'line': 8 } }")));    /* Fail: Duplicate configuration */
    429    /* Fail: The size of level 2 size should be small than level 1 */
    430    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    431        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    432        " 'level': 2, 'associativity': \"direct\", 'policy': \"write-back\","
    433        " 'line': 8 } }")));
    434    /* Fail: The size of level 0 size should be larger than level 1 */
    435    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    436        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    437        " 'level': 0, 'associativity': \"direct\", 'policy': \"write-back\","
    438        " 'line': 8 } }")));
    439    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    440        " 'arguments': { 'type': 'hmat-cache', 'node-id': 1, 'size': 10240,"
    441        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
    442        " 'line': 8 } }")));
    443
    444    /* let machine initialization to complete and run */
    445    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs,
    446        "{ 'execute': 'x-exit-preconfig' }")));
    447    qtest_qmp_eventwait(qs, "RESUME");
    448
    449    qtest_quit(qs);
    450}
    451
    452static void pc_hmat_off_cfg(const void *data)
    453{
    454    QTestState *qs;
    455    g_autofree char *cli = NULL;
    456
    457    cli = make_cli(data, "-nodefaults --preconfig "
    458                         "-machine smp.cpus=2,smp.sockets=2 "
    459                         "-m 128M,slots=2,maxmem=1G "
    460                         "-object memory-backend-ram,size=64M,id=m0,prealloc=y "
    461                         "-object memory-backend-ram,size=64M,id=m1 "
    462                         "-numa node,nodeid=0,memdev=m0");
    463    qs = qtest_init(cli);
    464
    465    /*
    466     * Fail: Enable HMAT with -machine hmat=on
    467     * before using any of hmat specific options
    468     */
    469    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    470        " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\","
    471        " 'initiator': 0 } }")));
    472    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    473        " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\" } }")));
    474    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    475        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    476        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
    477        " 'latency': 1 } }")));
    478    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    479        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    480        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
    481        " 'line': 8 } }")));
    482
    483    /* let machine initialization to complete and run */
    484    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs,
    485        "{ 'execute': 'x-exit-preconfig' }")));
    486    qtest_qmp_eventwait(qs, "RESUME");
    487
    488    qtest_quit(qs);
    489}
    490
    491static void pc_hmat_erange_cfg(const void *data)
    492{
    493    QTestState *qs;
    494    g_autofree char *cli = NULL;
    495
    496    cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on "
    497                         "-machine smp.cpus=2,smp.sockets=2 "
    498                         "-m 128M,slots=2,maxmem=1G "
    499                         "-object memory-backend-ram,size=64M,id=m0 "
    500                         "-object memory-backend-ram,size=64M,id=m1 "
    501                         "-numa node,nodeid=0,memdev=m0 "
    502                         "-numa node,nodeid=1,memdev=m1,initiator=0 "
    503                         "-numa cpu,node-id=0,socket-id=0 "
    504                         "-numa cpu,node-id=0,socket-id=1");
    505    qs = qtest_init(cli);
    506
    507    /* Can't store the compressed latency */
    508    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    509        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    510        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
    511        " 'latency': 1 } }")));    /* 1 ns */
    512    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    513        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
    514        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
    515        " 'latency': 65535 } }")));    /* 65535 ns */
    516
    517    /* Test the 0 input (bandwidth not provided) */
    518    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    519        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
    520        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
    521        " 'bandwidth': 0 } }")));    /* 0 MB/s */
    522    /* Fail: bandwidth should be provided before memory side cache attributes */
    523    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    524        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
    525        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
    526        " 'line': 8 } }")));
    527
    528    /* Can't store the compressed bandwidth */
    529    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
    530        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
    531        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
    532        " 'bandwidth': 68718428160 } }")));    /* 65535 MB/s */
    533
    534    /* let machine initialization to complete and run */
    535    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs,
    536        "{ 'execute': 'x-exit-preconfig' }")));
    537    qtest_qmp_eventwait(qs, "RESUME");
    538
    539    qtest_quit(qs);
    540}
    541
    542int main(int argc, char **argv)
    543{
    544    g_autoptr(GString) args = g_string_new(NULL);
    545    const char *arch = qtest_get_arch();
    546
    547    if (g_str_equal(arch, "ppc64")) {
    548        g_string_append(args, " -object memory-backend-ram,id=ram,size=512M");
    549    } else {
    550        g_string_append(args, " -object memory-backend-ram,id=ram,size=128M");
    551    }
    552
    553    if (g_str_equal(arch, "aarch64")) {
    554        g_string_append(args, " -machine virt");
    555    }
    556
    557    g_test_init(&argc, &argv, NULL);
    558
    559    qtest_add_data_func("/numa/mon/cpus/default", args, test_def_cpu_split);
    560    qtest_add_data_func("/numa/mon/cpus/explicit", args, test_mon_explicit);
    561    qtest_add_data_func("/numa/mon/cpus/partial", args, test_mon_partial);
    562    qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus);
    563
    564    if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
    565        qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu);
    566        qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg);
    567        qtest_add_data_func("/numa/pc/hmat/build", args, pc_hmat_build_cfg);
    568        qtest_add_data_func("/numa/pc/hmat/off", args, pc_hmat_off_cfg);
    569        qtest_add_data_func("/numa/pc/hmat/erange", args, pc_hmat_erange_cfg);
    570    }
    571
    572    if (!strcmp(arch, "ppc64")) {
    573        qtest_add_data_func("/numa/spapr/cpu/explicit", args, spapr_numa_cpu);
    574    }
    575
    576    if (!strcmp(arch, "aarch64")) {
    577        qtest_add_data_func("/numa/aarch64/cpu/explicit", args,
    578                            aarch64_numa_cpu);
    579    }
    580
    581    return g_test_run();
    582}