]>
Commit | Line | Data |
---|---|---|
96c1a628 MR |
1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* | |
96c1a628 MR |
3 | * Copyright (C) 2018, Google LLC. |
4 | */ | |
5 | #ifndef SELFTEST_KVM_UCALL_COMMON_H | |
6 | #define SELFTEST_KVM_UCALL_COMMON_H | |
ddcb57af | 7 | #include "test_util.h" |
b35f4c73 | 8 | #include "ucall.h" |
96c1a628 MR |
9 | |
10 | /* Common ucalls */ | |
11 | enum { | |
12 | UCALL_NONE, | |
13 | UCALL_SYNC, | |
14 | UCALL_ABORT, | |
57e5c1fe | 15 | UCALL_PRINTF, |
96c1a628 MR |
16 | UCALL_DONE, |
17 | UCALL_UNHANDLED, | |
18 | }; | |
19 | ||
fc573fa4 | 20 | #define UCALL_MAX_ARGS 7 |
57e5c1fe | 21 | #define UCALL_BUFFER_LEN 1024 |
96c1a628 MR |
22 | |
23 | struct ucall { | |
24 | uint64_t cmd; | |
25 | uint64_t args[UCALL_MAX_ARGS]; | |
57e5c1fe | 26 | char buffer[UCALL_BUFFER_LEN]; |
426729b2 PG |
27 | |
28 | /* Host virtual address of this struct. */ | |
29 | struct ucall *hva; | |
96c1a628 MR |
30 | }; |
31 | ||
dc88244b | 32 | void ucall_arch_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa); |
70466381 | 33 | void ucall_arch_do_ucall(vm_vaddr_t uc); |
ef38871e | 34 | void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu); |
70466381 | 35 | |
96c1a628 | 36 | void ucall(uint64_t cmd, int nargs, ...); |
57e5c1fe | 37 | void ucall_fmt(uint64_t cmd, const char *fmt, ...); |
289c2b4d SC |
38 | void ucall_assert(uint64_t cmd, const char *exp, const char *file, |
39 | unsigned int line, const char *fmt, ...); | |
ef38871e | 40 | uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc); |
426729b2 | 41 | void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa); |
215a6817 | 42 | int ucall_nr_pages_required(uint64_t page_size); |
70466381 | 43 | |
ef16b2df SC |
44 | /* |
45 | * Perform userspace call without any associated data. This bare call avoids | |
46 | * allocating a ucall struct, which can be useful if the atomic operations in | |
47 | * the full ucall() are problematic and/or unwanted. Note, this will come out | |
48 | * as UCALL_NONE on the backend. | |
49 | */ | |
50 | #define GUEST_UCALL_NONE() ucall_arch_do_ucall((vm_vaddr_t)NULL) | |
51 | ||
96c1a628 MR |
52 | #define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4) \ |
53 | ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4) | |
54 | #define GUEST_SYNC(stage) ucall(UCALL_SYNC, 2, "hello", stage) | |
57e5c1fe | 55 | #define GUEST_PRINTF(_fmt, _args...) ucall_fmt(UCALL_PRINTF, _fmt, ##_args) |
96c1a628 | 56 | #define GUEST_DONE() ucall(UCALL_DONE, 0) |
8fb2638a | 57 | |
57e5c1fe AL |
58 | #define REPORT_GUEST_PRINTF(ucall) pr_info("%s", (ucall).buffer) |
59 | ||
8fb2638a CL |
60 | enum guest_assert_builtin_args { |
61 | GUEST_ERROR_STRING, | |
62 | GUEST_FILE, | |
63 | GUEST_LINE, | |
64 | GUEST_ASSERT_BUILTIN_NARGS | |
65 | }; | |
66 | ||
289c2b4d SC |
67 | #define ____GUEST_ASSERT(_condition, _exp, _fmt, _args...) \ |
68 | do { \ | |
69 | if (!(_condition)) \ | |
70 | ucall_assert(UCALL_ABORT, _exp, __FILE__, __LINE__, _fmt, ##_args); \ | |
71 | } while (0) | |
72 | ||
73 | #define __GUEST_ASSERT(_condition, _fmt, _args...) \ | |
74 | ____GUEST_ASSERT(_condition, #_condition, _fmt, ##_args) | |
75 | ||
76 | #define GUEST_ASSERT(_condition) \ | |
77 | __GUEST_ASSERT(_condition, #_condition) | |
78 | ||
79 | #define GUEST_FAIL(_fmt, _args...) \ | |
80 | ucall_assert(UCALL_ABORT, "Unconditional guest failure", \ | |
81 | __FILE__, __LINE__, _fmt, ##_args) | |
82 | ||
83 | #define GUEST_ASSERT_EQ(a, b) \ | |
84 | do { \ | |
85 | typeof(a) __a = (a); \ | |
86 | typeof(b) __b = (b); \ | |
87 | ____GUEST_ASSERT(__a == __b, #a " == " #b, "%#lx != %#lx (%s != %s)", \ | |
88 | (unsigned long)(__a), (unsigned long)(__b), #a, #b); \ | |
89 | } while (0) | |
90 | ||
91 | #define GUEST_ASSERT_NE(a, b) \ | |
92 | do { \ | |
93 | typeof(a) __a = (a); \ | |
94 | typeof(b) __b = (b); \ | |
95 | ____GUEST_ASSERT(__a != __b, #a " != " #b, "%#lx == %#lx (%s == %s)", \ | |
96 | (unsigned long)(__a), (unsigned long)(__b), #a, #b); \ | |
97 | } while (0) | |
98 | ||
99 | #define REPORT_GUEST_ASSERT(ucall) \ | |
100 | test_assert(false, (const char *)(ucall).args[GUEST_ERROR_STRING], \ | |
101 | (const char *)(ucall).args[GUEST_FILE], \ | |
102 | (ucall).args[GUEST_LINE], "%s", (ucall).buffer) | |
103 | ||
96c1a628 | 104 | #endif /* SELFTEST_KVM_UCALL_COMMON_H */ |