File Index
Files and directories
Sign in
FILE

host_sve.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/kvm/arm64/host_sve.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2
  3/*
  4 * Host SVE: Check FPSIMD/SVE/SME save/restore over KVM_RUN ioctls.
  5 *
  6 * Copyright 2025 Arm, Ltd
  7 */
  8
  9#include <errno.h>
 10#include <signal.h>
 11#include <sys/auxv.h>
 12#include <asm/kvm.h>
 13#include <kvm_util.h>
 14
 15#include "ucall_common.h"
 16
 17static void guest_code(void)
 18{
 19	for (int i = 0; i < 10; i++) {
 20		GUEST_UCALL_NONE();
 21	}
 22
 23	GUEST_DONE();
 24}
 25
 26void handle_sigill(int sig, siginfo_t *info, void *ctx)
 27{
 28	ucontext_t *uctx = ctx;
 29
 30	printf("  < host signal %d >\n", sig);
 31
 32	/*
 33	 * Skip the UDF
 34	 */
 35	uctx->uc_mcontext.pc += 4;
 36}
 37
 38void register_sigill_handler(void)
 39{
 40	struct sigaction sa = {
 41		.sa_sigaction = handle_sigill,
 42		.sa_flags = SA_SIGINFO,
 43	};
 44	sigaction(SIGILL, &sa, NULL);
 45}
 46
 47static void do_sve_roundtrip(void)
 48{
 49	unsigned long before, after;
 50
 51	/*
 52	 * Set all bits in a predicate register, force a save/restore via a
 53	 * SIGILL (which handle_sigill() will recover from), then report
 54	 * whether the value has changed.
 55	 */
 56	asm volatile(
 57	"	.arch_extension sve\n"
 58	"	ptrue	p0.B\n"
 59	"	cntp	%[before], p0, p0.B\n"
 60	"	udf #0\n"
 61	"	cntp	%[after], p0, p0.B\n"
 62	: [before] "=r" (before),
 63	  [after] "=r" (after)
 64	:
 65	: "p0"
 66	);
 67
 68	if (before != after) {
 69		TEST_FAIL("Signal roundtrip discarded predicate bits (%ld => %ld)\n",
 70			  before, after);
 71	} else {
 72		printf("Signal roundtrip preserved predicate bits (%ld => %ld)\n",
 73		       before, after);
 74	}
 75}
 76
 77static void test_run(void)
 78{
 79	struct kvm_vcpu *vcpu;
 80	struct kvm_vm *vm;
 81	struct ucall uc;
 82	bool guest_done = false;
 83
 84	register_sigill_handler();
 85
 86	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 87
 88	do_sve_roundtrip();
 89
 90	while (!guest_done) {
 91
 92		printf("Running VCPU...\n");
 93		vcpu_run(vcpu);
 94
 95		switch (get_ucall(vcpu, &uc)) {
 96		case UCALL_NONE:
 97			do_sve_roundtrip();
 98			do_sve_roundtrip();
 99			break;
100		case UCALL_DONE:
101			guest_done = true;
102			break;
103		case UCALL_ABORT:
104			REPORT_GUEST_ASSERT(uc);
105			break;
106		default:
107			TEST_FAIL("Unexpected guest exit");
108		}
109	}
110
111	kvm_vm_free(vm);
112}
113
114int main(void)
115{
116	/*
117	 * This is testing the host environment, we don't care about
118	 * guest SVE support.
119	 */
120	if (!(getauxval(AT_HWCAP) & HWCAP_SVE)) {
121		printf("SVE not supported\n");
122		return KSFT_SKIP;
123	}
124
125	test_run();
126	return 0;
127}
~/ Read-only file preview.