1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
/******************************************************************************
* compat.h
*/
#ifndef __XEN_COMPAT_H__
#define __XEN_COMPAT_H__
#include <xen/config.h>
#ifdef CONFIG_COMPAT
#include <xen/types.h>
#include <asm/compat.h>
#include <compat/xlat.h>
#define __DEFINE_COMPAT_HANDLE(name, type) \
typedef struct { \
compat_ptr_t c; \
type *_[0] __attribute__((__packed__)); \
} __compat_handle_ ## name
#define DEFINE_COMPAT_HANDLE(name) \
__DEFINE_COMPAT_HANDLE(name, name); \
__DEFINE_COMPAT_HANDLE(const_ ## name, const name)
#define COMPAT_HANDLE(name) __compat_handle_ ## name
/* Is the compat handle a NULL reference? */
#define compat_handle_is_null(hnd) ((hnd).c == 0)
/* Offset the given compat handle into the array it refers to. */
#define compat_handle_add_offset(hnd, nr) \
((hnd).c += (nr) * sizeof(**(hnd)._))
/* Cast a compat handle to the specified type of handle. */
#define compat_handle_cast(chnd, type) ({ \
type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \
(XEN_GUEST_HANDLE(type)) { _x }; \
})
#define guest_from_compat_handle(ghnd, chnd) \
set_xen_guest_handle(ghnd, \
(__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c)
/*
* Copy an array of objects to guest context via a compat handle,
* specifying an offset into the guest array.
*/
#define copy_to_compat_offset(hnd, off, ptr, nr) ({ \
const typeof(*(ptr)) *_s = (ptr); \
char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \
((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
raw_copy_to_guest(_d + (off), _s, sizeof(*_s) * (nr)); \
})
/*
* Copy an array of objects from guest context via a compat handle,
* specifying an offset into the guest array.
*/
#define copy_from_compat_offset(ptr, hnd, off, nr) ({ \
const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
typeof(*(ptr)) *_d = (ptr); \
raw_copy_from_guest(_d, _s + (off), sizeof(*_d) * (nr)); \
})
#define copy_to_compat(hnd, ptr, nr) \
copy_to_compat_offset(hnd, 0, ptr, nr)
#define copy_from_compat(ptr, hnd, nr) \
copy_from_compat_offset(ptr, hnd, 0, nr)
/* Copy sub-field of a structure to guest context via a compat handle. */
#define copy_field_to_compat(hnd, ptr, field) ({ \
const typeof(&(ptr)->field) _s = &(ptr)->field; \
void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
((void)(&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field == \
&(ptr)->field)); \
raw_copy_to_guest(_d, _s, sizeof(*_s)); \
})
/* Copy sub-field of a structure from guest context via a compat handle. */
#define copy_field_from_compat(ptr, hnd, field) ({ \
const typeof(&(ptr)->field) _s = \
&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
typeof(&(ptr)->field) _d = &(ptr)->field; \
raw_copy_from_guest(_d, _s, sizeof(*_d)); \
})
/*
* Pre-validate a guest handle.
* Allows use of faster __copy_* functions.
*/
#define compat_handle_okay(hnd, nr) \
(paging_mode_external(current->domain) || \
compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), \
sizeof(**(hnd)._)))
#define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \
const typeof(*(ptr)) *_s = (ptr); \
char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \
((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
__raw_copy_to_guest(_d + (off), _s, sizeof(*_s) * (nr)); \
})
#define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \
const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
typeof(*(ptr)) *_d = (ptr); \
__raw_copy_from_guest(_d, _s + (off), sizeof(*_d) * (nr)); \
})
#define __copy_to_compat(hnd, ptr, nr) \
__copy_to_compat_offset(hnd, 0, ptr, nr)
#define __copy_from_compat(ptr, hnd, nr) \
__copy_from_compat_offset(ptr, hnd, 0, nr)
#define __copy_field_to_compat(hnd, ptr, field) ({ \
const typeof(&(ptr)->field) _s = &(ptr)->field; \
void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
((void)(&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field == \
&(ptr)->field)); \
__raw_copy_to_guest(_d, _s, sizeof(*_s)); \
})
#define __copy_field_from_compat(ptr, hnd, field) ({ \
const typeof(&(ptr)->field) _s = \
&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
typeof(&(ptr)->field) _d = &(ptr)->field; \
__raw_copy_from_guest(_d, _s, sizeof(*_d)); \
})
#define CHECK_NAME(name, tag) __check ## tag ## name
#define CHECK_NAME_(k, n, tag) __check ## tag ## k ## _ ## n
#define CHECK_TYPE(name) \
static inline int CHECK_NAME(name, T)(xen_ ## name ## _t *x, \
compat_ ## name ## _t *c) \
{ \
return x == c; \
}
#define CHECK_TYPE_(k, n) \
static inline int CHECK_NAME_(k, n, T)(k xen_ ## n *x, \
k compat_ ## n *c) \
{ \
return x == c; \
}
#define CHECK_SIZE(name) \
typedef int CHECK_NAME(name, S)[1 - (sizeof(xen_ ## name ## _t) != \
sizeof(compat_ ## name ## _t)) * 2]
#define CHECK_SIZE_(k, n) \
typedef int CHECK_NAME_(k, n, S)[1 - (sizeof(k xen_ ## n) != \
sizeof(k compat_ ## n)) * 2]
#define CHECK_FIELD_COMMON(name, t, f) \
static inline int name(xen_ ## t ## _t *x, compat_ ## t ## _t *c) \
{ \
BUILD_BUG_ON(offsetof(xen_ ## t ## _t, f) != \
offsetof(compat_ ## t ## _t, f)); \
return &x->f == &c->f; \
}
#define CHECK_FIELD_COMMON_(k, name, n, f) \
static inline int name(k xen_ ## n *x, k compat_ ## n *c) \
{ \
BUILD_BUG_ON(offsetof(k xen_ ## n, f) != \
offsetof(k compat_ ## n, f)); \
return &x->f == &c->f; \
}
#define CHECK_FIELD(t, f) \
CHECK_FIELD_COMMON(CHECK_NAME(t ## __ ## f, F), t, f)
#define CHECK_FIELD_(k, n, f) \
CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f, F), n, f)
#define CHECK_SUBFIELD_1(t, f1, f2) \
CHECK_FIELD_COMMON(CHECK_NAME(t ## __ ## f1 ## __ ## f2, F1), t, f1.f2)
#define CHECK_SUBFIELD_1_(k, n, f1, f2) \
CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f1 ## __ ## f2, F1), \
n, f1.f2)
#define CHECK_SUBFIELD_2(t, f1, f2, f3) \
CHECK_FIELD_COMMON(CHECK_NAME(t ## __ ## f1 ## __ ## f2 ## __ ## f3, F2), \
t, f1.f2.f3)
#define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \
CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f1 ## __ ## f2 ## __ ## \
f3, F2), n, f1.f2.f3)
int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...);
/* In-place translation functons: */
struct start_info;
void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
struct vcpu_runstate_info;
void xlat_vcpu_runstate_info(struct vcpu_runstate_info *);
int switch_compat(struct domain *);
int switch_native(struct domain *);
#else
#define compat_handle_is_null(hnd) 0
#endif
#endif /* __XEN_COMPAT_H__ */
|