Commit 2b6d6371 authored by Alex Bennée's avatar Alex Bennée
Browse files

tests/tcg/aarch64: add SVE iotcl test



This is a fairly bare-bones test of setting the various vector sizes
for SVE which will only fail if the PR_SVE_SET_VL can't reduce the
user-space vector length by powers of 2.

However we will also be able to use it in a future test which
exercises the GDB stub.

Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Tested-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200316172155.971-25-alex.bennee@linaro.org>
parent cf58773f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -47,6 +47,10 @@ ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),)
AARCH64_TESTS += sysregs
sysregs: CFLAGS+=-march=armv8.1-a+sve

# SVE ioctl test
AARCH64_TESTS += sve-ioctls
sve-ioctls: CFLAGS+=-march=armv8.1-a+sve

ifneq ($(HAVE_GDB_BIN),)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py

+70 −0
Original line number Diff line number Diff line
/*
 * SVE ioctls tests
 *
 * Test the SVE width setting ioctls work and provide a base for
 * testing the gdbstub.
 *
 * Copyright (c) 2019 Linaro Ltd
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */
#include <sys/prctl.h>
#include <asm/hwcap.h>
#include <stdio.h>
#include <sys/auxv.h>
#include <stdint.h>
#include <stdlib.h>

#ifndef HWCAP_CPUID
#define HWCAP_CPUID (1 << 11)
#endif

#define SVE_MAX_QUADS  (2048 / 128)
#define BYTES_PER_QUAD (128 / 8)

#define get_cpu_reg(id) ({                                      \
            unsigned long __val;                                \
            asm("mrs %0, "#id : "=r" (__val));                  \
            __val;                                              \
        })

static int do_sve_ioctl_test(void)
{
    int i, res, init_vq;

    res = prctl(PR_SVE_GET_VL, 0, 0, 0, 0);
    if (res < 0) {
        printf("FAILED to PR_SVE_GET_VL (%d)", res);
        return -1;
    }
    init_vq = res & PR_SVE_VL_LEN_MASK;

    for (i = init_vq; i > 15; i /= 2) {
        printf("Checking PR_SVE_SET_VL=%d\n", i);
        res = prctl(PR_SVE_SET_VL, i, 0, 0, 0, 0);
        if (res < 0) {
            printf("FAILED to PR_SVE_SET_VL (%d)", res);
            return -1;
        }
        asm("index z0.b, #0, #1\n"
            ".global __sve_ld_done\n"
            "__sve_ld_done:\n"
            "mov z0.b, #0\n"
            : /* no outputs kept */
            : /* no inputs */
            : "memory", "z0");
    }
    printf("PASS\n");
    return 0;
}

int main(int argc, char **argv)
{
    /* we also need to probe for the ioctl support */
    if (getauxval(AT_HWCAP) & HWCAP_SVE) {
        return do_sve_ioctl_test();
    } else {
        printf("SKIP: no HWCAP_SVE on this system\n");
        return 0;
    }
}