1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * tools/testing/selftests/kvm/include/kvm_util.h 4 * 5 * Copyright (C) 2018, Google LLC. 6 */ 7 #ifndef SELFTEST_KVM_UCALL_COMMON_H 8 #define SELFTEST_KVM_UCALL_COMMON_H 9 #include "test_util.h" 10 11 /* Common ucalls */ 12 enum { 13 UCALL_NONE, 14 UCALL_SYNC, 15 UCALL_ABORT, 16 UCALL_DONE, 17 UCALL_UNHANDLED, 18 }; 19 20 #define UCALL_MAX_ARGS 7 21 22 struct ucall { 23 uint64_t cmd; 24 uint64_t args[UCALL_MAX_ARGS]; 25 26 /* Host virtual address of this struct. */ 27 struct ucall *hva; 28 }; 29 30 void ucall_arch_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa); 31 void ucall_arch_do_ucall(vm_vaddr_t uc); 32 void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu); 33 34 void ucall(uint64_t cmd, int nargs, ...); 35 uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc); 36 void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa); 37 38 /* 39 * Perform userspace call without any associated data. This bare call avoids 40 * allocating a ucall struct, which can be useful if the atomic operations in 41 * the full ucall() are problematic and/or unwanted. Note, this will come out 42 * as UCALL_NONE on the backend. 43 */ 44 #define GUEST_UCALL_NONE() ucall_arch_do_ucall((vm_vaddr_t)NULL) 45 46 #define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4) \ 47 ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4) 48 #define GUEST_SYNC(stage) ucall(UCALL_SYNC, 2, "hello", stage) 49 #define GUEST_DONE() ucall(UCALL_DONE, 0) 50 51 enum guest_assert_builtin_args { 52 GUEST_ERROR_STRING, 53 GUEST_FILE, 54 GUEST_LINE, 55 GUEST_ASSERT_BUILTIN_NARGS 56 }; 57 58 #define __GUEST_ASSERT(_condition, _condstr, _nargs, _args...) \ 59 do { \ 60 if (!(_condition)) \ 61 ucall(UCALL_ABORT, GUEST_ASSERT_BUILTIN_NARGS + _nargs, \ 62 "Failed guest assert: " _condstr, \ 63 __FILE__, __LINE__, ##_args); \ 64 } while (0) 65 66 #define GUEST_ASSERT(_condition) \ 67 __GUEST_ASSERT(_condition, #_condition, 0, 0) 68 69 #define GUEST_ASSERT_1(_condition, arg1) \ 70 __GUEST_ASSERT(_condition, #_condition, 1, (arg1)) 71 72 #define GUEST_ASSERT_2(_condition, arg1, arg2) \ 73 __GUEST_ASSERT(_condition, #_condition, 2, (arg1), (arg2)) 74 75 #define GUEST_ASSERT_3(_condition, arg1, arg2, arg3) \ 76 __GUEST_ASSERT(_condition, #_condition, 3, (arg1), (arg2), (arg3)) 77 78 #define GUEST_ASSERT_4(_condition, arg1, arg2, arg3, arg4) \ 79 __GUEST_ASSERT(_condition, #_condition, 4, (arg1), (arg2), (arg3), (arg4)) 80 81 #define GUEST_ASSERT_EQ(a, b) __GUEST_ASSERT((a) == (b), #a " == " #b, 2, a, b) 82 83 #define __REPORT_GUEST_ASSERT(_ucall, fmt, _args...) \ 84 TEST_FAIL("%s at %s:%ld\n" fmt, \ 85 (const char *)(_ucall).args[GUEST_ERROR_STRING], \ 86 (const char *)(_ucall).args[GUEST_FILE], \ 87 (_ucall).args[GUEST_LINE], \ 88 ##_args) 89 90 #define GUEST_ASSERT_ARG(ucall, i) ((ucall).args[GUEST_ASSERT_BUILTIN_NARGS + i]) 91 92 #define REPORT_GUEST_ASSERT(ucall) \ 93 __REPORT_GUEST_ASSERT((ucall), "") 94 95 #define REPORT_GUEST_ASSERT_1(ucall, fmt) \ 96 __REPORT_GUEST_ASSERT((ucall), \ 97 fmt, \ 98 GUEST_ASSERT_ARG((ucall), 0)) 99 100 #define REPORT_GUEST_ASSERT_2(ucall, fmt) \ 101 __REPORT_GUEST_ASSERT((ucall), \ 102 fmt, \ 103 GUEST_ASSERT_ARG((ucall), 0), \ 104 GUEST_ASSERT_ARG((ucall), 1)) 105 106 #define REPORT_GUEST_ASSERT_3(ucall, fmt) \ 107 __REPORT_GUEST_ASSERT((ucall), \ 108 fmt, \ 109 GUEST_ASSERT_ARG((ucall), 0), \ 110 GUEST_ASSERT_ARG((ucall), 1), \ 111 GUEST_ASSERT_ARG((ucall), 2)) 112 113 #define REPORT_GUEST_ASSERT_4(ucall, fmt) \ 114 __REPORT_GUEST_ASSERT((ucall), \ 115 fmt, \ 116 GUEST_ASSERT_ARG((ucall), 0), \ 117 GUEST_ASSERT_ARG((ucall), 1), \ 118 GUEST_ASSERT_ARG((ucall), 2), \ 119 GUEST_ASSERT_ARG((ucall), 3)) 120 121 #define REPORT_GUEST_ASSERT_N(ucall, fmt, args...) \ 122 __REPORT_GUEST_ASSERT((ucall), fmt, ##args) 123 124 #endif /* SELFTEST_KVM_UCALL_COMMON_H */ 125