Path: blob/master/tools/testing/selftests/kvm/arm64/host_sve.c
38237 views
// SPDX-License-Identifier: GPL-2.0-only12/*3* Host SVE: Check FPSIMD/SVE/SME save/restore over KVM_RUN ioctls.4*5* Copyright 2025 Arm, Ltd6*/78#include <errno.h>9#include <signal.h>10#include <sys/auxv.h>11#include <asm/kvm.h>12#include <kvm_util.h>1314#include "ucall_common.h"1516static void guest_code(void)17{18for (int i = 0; i < 10; i++) {19GUEST_UCALL_NONE();20}2122GUEST_DONE();23}2425void handle_sigill(int sig, siginfo_t *info, void *ctx)26{27ucontext_t *uctx = ctx;2829printf(" < host signal %d >\n", sig);3031/*32* Skip the UDF33*/34uctx->uc_mcontext.pc += 4;35}3637void register_sigill_handler(void)38{39struct sigaction sa = {40.sa_sigaction = handle_sigill,41.sa_flags = SA_SIGINFO,42};43sigaction(SIGILL, &sa, NULL);44}4546static void do_sve_roundtrip(void)47{48unsigned long before, after;4950/*51* Set all bits in a predicate register, force a save/restore via a52* SIGILL (which handle_sigill() will recover from), then report53* whether the value has changed.54*/55asm volatile(56" .arch_extension sve\n"57" ptrue p0.B\n"58" cntp %[before], p0, p0.B\n"59" udf #0\n"60" cntp %[after], p0, p0.B\n"61: [before] "=r" (before),62[after] "=r" (after)63:64: "p0"65);6667if (before != after) {68TEST_FAIL("Signal roundtrip discarded predicate bits (%ld => %ld)\n",69before, after);70} else {71printf("Signal roundtrip preserved predicate bits (%ld => %ld)\n",72before, after);73}74}7576static void test_run(void)77{78struct kvm_vcpu *vcpu;79struct kvm_vm *vm;80struct ucall uc;81bool guest_done = false;8283register_sigill_handler();8485vm = vm_create_with_one_vcpu(&vcpu, guest_code);8687do_sve_roundtrip();8889while (!guest_done) {9091printf("Running VCPU...\n");92vcpu_run(vcpu);9394switch (get_ucall(vcpu, &uc)) {95case UCALL_NONE:96do_sve_roundtrip();97do_sve_roundtrip();98break;99case UCALL_DONE:100guest_done = true;101break;102case UCALL_ABORT:103REPORT_GUEST_ASSERT(uc);104break;105default:106TEST_FAIL("Unexpected guest exit");107}108}109110kvm_vm_free(vm);111}112113int main(void)114{115/*116* This is testing the host environment, we don't care about117* guest SVE support.118*/119if (!(getauxval(AT_HWCAP) & HWCAP_SVE)) {120printf("SVE not supported\n");121return KSFT_SKIP;122}123124test_run();125return 0;126}127128129