0001
0002
0003
0004
0005
0006
0007 #ifndef SELFTEST_KVM_UCALL_COMMON_H
0008 #define SELFTEST_KVM_UCALL_COMMON_H
0009 #include "test_util.h"
0010
0011
0012 enum {
0013 UCALL_NONE,
0014 UCALL_SYNC,
0015 UCALL_ABORT,
0016 UCALL_DONE,
0017 UCALL_UNHANDLED,
0018 };
0019
0020 #define UCALL_MAX_ARGS 7
0021
0022 struct ucall {
0023 uint64_t cmd;
0024 uint64_t args[UCALL_MAX_ARGS];
0025 };
0026
0027 void ucall_init(struct kvm_vm *vm, void *arg);
0028 void ucall_uninit(struct kvm_vm *vm);
0029 void ucall(uint64_t cmd, int nargs, ...);
0030 uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc);
0031
0032 #define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4) \
0033 ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4)
0034 #define GUEST_SYNC(stage) ucall(UCALL_SYNC, 2, "hello", stage)
0035 #define GUEST_DONE() ucall(UCALL_DONE, 0)
0036
0037 enum guest_assert_builtin_args {
0038 GUEST_ERROR_STRING,
0039 GUEST_FILE,
0040 GUEST_LINE,
0041 GUEST_ASSERT_BUILTIN_NARGS
0042 };
0043
0044 #define __GUEST_ASSERT(_condition, _condstr, _nargs, _args...) \
0045 do { \
0046 if (!(_condition)) \
0047 ucall(UCALL_ABORT, GUEST_ASSERT_BUILTIN_NARGS + _nargs, \
0048 "Failed guest assert: " _condstr, \
0049 __FILE__, __LINE__, ##_args); \
0050 } while (0)
0051
0052 #define GUEST_ASSERT(_condition) \
0053 __GUEST_ASSERT(_condition, #_condition, 0, 0)
0054
0055 #define GUEST_ASSERT_1(_condition, arg1) \
0056 __GUEST_ASSERT(_condition, #_condition, 1, (arg1))
0057
0058 #define GUEST_ASSERT_2(_condition, arg1, arg2) \
0059 __GUEST_ASSERT(_condition, #_condition, 2, (arg1), (arg2))
0060
0061 #define GUEST_ASSERT_3(_condition, arg1, arg2, arg3) \
0062 __GUEST_ASSERT(_condition, #_condition, 3, (arg1), (arg2), (arg3))
0063
0064 #define GUEST_ASSERT_4(_condition, arg1, arg2, arg3, arg4) \
0065 __GUEST_ASSERT(_condition, #_condition, 4, (arg1), (arg2), (arg3), (arg4))
0066
0067 #define GUEST_ASSERT_EQ(a, b) __GUEST_ASSERT((a) == (b), #a " == " #b, 2, a, b)
0068
0069 #define __REPORT_GUEST_ASSERT(_ucall, fmt, _args...) \
0070 TEST_FAIL("%s at %s:%ld\n" fmt, \
0071 (const char *)(_ucall).args[GUEST_ERROR_STRING], \
0072 (const char *)(_ucall).args[GUEST_FILE], \
0073 (_ucall).args[GUEST_LINE], \
0074 ##_args)
0075
0076 #define GUEST_ASSERT_ARG(ucall, i) ((ucall).args[GUEST_ASSERT_BUILTIN_NARGS + i])
0077
0078 #define REPORT_GUEST_ASSERT(ucall) \
0079 __REPORT_GUEST_ASSERT((ucall), "")
0080
0081 #define REPORT_GUEST_ASSERT_1(ucall, fmt) \
0082 __REPORT_GUEST_ASSERT((ucall), \
0083 fmt, \
0084 GUEST_ASSERT_ARG((ucall), 0))
0085
0086 #define REPORT_GUEST_ASSERT_2(ucall, fmt) \
0087 __REPORT_GUEST_ASSERT((ucall), \
0088 fmt, \
0089 GUEST_ASSERT_ARG((ucall), 0), \
0090 GUEST_ASSERT_ARG((ucall), 1))
0091
0092 #define REPORT_GUEST_ASSERT_3(ucall, fmt) \
0093 __REPORT_GUEST_ASSERT((ucall), \
0094 fmt, \
0095 GUEST_ASSERT_ARG((ucall), 0), \
0096 GUEST_ASSERT_ARG((ucall), 1), \
0097 GUEST_ASSERT_ARG((ucall), 2))
0098
0099 #define REPORT_GUEST_ASSERT_4(ucall, fmt) \
0100 __REPORT_GUEST_ASSERT((ucall), \
0101 fmt, \
0102 GUEST_ASSERT_ARG((ucall), 0), \
0103 GUEST_ASSERT_ARG((ucall), 1), \
0104 GUEST_ASSERT_ARG((ucall), 2), \
0105 GUEST_ASSERT_ARG((ucall), 3))
0106
0107 #define REPORT_GUEST_ASSERT_N(ucall, fmt, args...) \
0108 __REPORT_GUEST_ASSERT((ucall), fmt, ##args)
0109
0110 #endif