Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19-rc8 127 lines 2.2 kB view raw
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}