1 /****************************************************************************** 2 * compat.h 3 */ 4 5 #ifndef __XEN_COMPAT_H__ 6 #define __XEN_COMPAT_H__ 7 8 #ifdef CONFIG_COMPAT 9 10 #include <xen/types.h> 11 #include <asm/compat.h> 12 #include <compat/xlat.h> 13 14 #define __DEFINE_COMPAT_HANDLE(name, type) \ 15 typedef struct { \ 16 compat_ptr_t c; \ 17 type *_[0] __packed; \ 18 } __compat_handle_ ## name; \ 19 typedef struct { \ 20 compat_ptr_t c; \ 21 const type *_[0] __packed; \ 22 } __compat_handle_const_ ## name 23 24 #define DEFINE_COMPAT_HANDLE(name) \ 25 __DEFINE_COMPAT_HANDLE(name, name) 26 #define COMPAT_HANDLE(name) __compat_handle_ ## name 27 28 /* Is the compat handle a NULL reference? */ 29 #define compat_handle_is_null(hnd) ((hnd).c == 0) 30 31 /* Offset the given compat handle into the array it refers to. */ 32 #define compat_handle_add_offset(hnd, nr) \ 33 ((hnd).c += (nr) * sizeof(**(hnd)._)) 34 35 /* Cast a compat handle to the specified type of handle. */ 36 #define compat_handle_cast(chnd, type) ({ \ 37 type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \ 38 (COMPAT_HANDLE(type)) { (full_ptr_t)_x }; \ 39 }) 40 41 #define guest_from_compat_handle(ghnd, chnd) \ 42 set_xen_guest_handle(ghnd, \ 43 (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c) 44 45 /* 46 * Copy an array of objects to guest context via a compat handle, 47 * specifying an offset into the guest array. 48 */ 49 #define copy_to_compat_offset(hnd, off, ptr, nr) ({ \ 50 const typeof(*(ptr)) *_s = (ptr); \ 51 char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \ 52 ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \ 53 raw_copy_to_guest(_d + (off), _s, sizeof(*_s) * (nr)); \ 54 }) 55 56 /* 57 * Copy an array of objects from guest context via a compat handle, 58 * specifying an offset into the guest array. 59 */ 60 #define copy_from_compat_offset(ptr, hnd, off, nr) ({ \ 61 const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ 62 typeof(*(ptr)) *_d = (ptr); \ 63 raw_copy_from_guest(_d, _s + (off), sizeof(*_d) * (nr)); \ 64 }) 65 66 #define copy_to_compat(hnd, ptr, nr) \ 67 copy_to_compat_offset(hnd, 0, ptr, nr) 68 69 #define copy_from_compat(ptr, hnd, nr) \ 70 copy_from_compat_offset(ptr, hnd, 0, nr) 71 72 /* Copy sub-field of a structure to guest context via a compat handle. */ 73 #define copy_field_to_compat(hnd, ptr, field) ({ \ 74 const typeof(&(ptr)->field) _s = &(ptr)->field; \ 75 void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ 76 ((void)(&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field == \ 77 &(ptr)->field)); \ 78 raw_copy_to_guest(_d, _s, sizeof(*_s)); \ 79 }) 80 81 /* Copy sub-field of a structure from guest context via a compat handle. */ 82 #define copy_field_from_compat(ptr, hnd, field) ({ \ 83 const typeof(&(ptr)->field) _s = \ 84 &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ 85 typeof(&(ptr)->field) _d = &(ptr)->field; \ 86 raw_copy_from_guest(_d, _s, sizeof(*_d)); \ 87 }) 88 89 /* 90 * Pre-validate a guest handle. 91 * Allows use of faster __copy_* functions. 92 */ 93 #define compat_handle_okay(hnd, nr) \ 94 (paging_mode_external(current->domain) || \ 95 compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), \ 96 sizeof(**(hnd)._))) 97 98 #define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \ 99 const typeof(*(ptr)) *_s = (ptr); \ 100 char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \ 101 ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \ 102 __raw_copy_to_guest(_d + (off), _s, sizeof(*_s) * (nr)); \ 103 }) 104 105 #define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \ 106 const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ 107 typeof(*(ptr)) *_d = (ptr); \ 108 __raw_copy_from_guest(_d, _s + (off), sizeof(*_d) * (nr)); \ 109 }) 110 111 #define __copy_to_compat(hnd, ptr, nr) \ 112 __copy_to_compat_offset(hnd, 0, ptr, nr) 113 114 #define __copy_from_compat(ptr, hnd, nr) \ 115 __copy_from_compat_offset(ptr, hnd, 0, nr) 116 117 #define __copy_field_to_compat(hnd, ptr, field) ({ \ 118 const typeof(&(ptr)->field) _s = &(ptr)->field; \ 119 void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ 120 ((void)(&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field == \ 121 &(ptr)->field)); \ 122 __raw_copy_to_guest(_d, _s, sizeof(*_s)); \ 123 }) 124 125 #define __copy_field_from_compat(ptr, hnd, field) ({ \ 126 const typeof(&(ptr)->field) _s = \ 127 &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ 128 typeof(&(ptr)->field) _d = &(ptr)->field; \ 129 __raw_copy_from_guest(_d, _s, sizeof(*_d)); \ 130 }) 131 132 133 #define CHECK_NAME(name, tag) __check ## tag ## name 134 #define CHECK_NAME_(k, n, tag) __check ## tag ## k ## _ ## n 135 136 #define CHECK_TYPE(name) \ 137 static inline int __maybe_unused \ 138 CHECK_NAME(name, T)(xen_ ## name ## _t *x, \ 139 compat_ ## name ## _t *c) \ 140 { \ 141 return x == c; \ 142 } 143 #define CHECK_TYPE_(k, n) \ 144 static inline int __maybe_unused \ 145 CHECK_NAME_(k, n, T)(k xen_ ## n *x, \ 146 k compat_ ## n *c) \ 147 { \ 148 return x == c; \ 149 } 150 151 #define CHECK_SIZE(name) \ 152 typedef int CHECK_NAME(name, S)[1 - (sizeof(xen_ ## name ## _t) != \ 153 sizeof(compat_ ## name ## _t)) * 2] 154 #define CHECK_SIZE_(k, n) \ 155 typedef int CHECK_NAME_(k, n, S)[1 - (sizeof(k xen_ ## n) != \ 156 sizeof(k compat_ ## n)) * 2] 157 158 #define CHECK_FIELD_COMMON(name, t, f) \ 159 static inline int __maybe_unused name(xen_ ## t ## _t *x, compat_ ## t ## _t *c) \ 160 { \ 161 BUILD_BUG_ON(offsetof(xen_ ## t ## _t, f) != \ 162 offsetof(compat_ ## t ## _t, f)); \ 163 return &x->f == &c->f; \ 164 } 165 #define CHECK_FIELD_COMMON_(k, name, n, f) \ 166 static inline int __maybe_unused name(k xen_ ## n *x, k compat_ ## n *c) \ 167 { \ 168 BUILD_BUG_ON(offsetof(k xen_ ## n, f) != \ 169 offsetof(k compat_ ## n, f)); \ 170 return &x->f == &c->f; \ 171 } 172 173 #define CHECK_FIELD(t, f) \ 174 CHECK_FIELD_COMMON(CHECK_NAME(t ## __ ## f, F), t, f) 175 #define CHECK_FIELD_(k, n, f) \ 176 CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f, F), n, f) 177 178 #define CHECK_SUBFIELD_1(t, f1, f2) \ 179 CHECK_FIELD_COMMON(CHECK_NAME(t ## __ ## f1 ## __ ## f2, F1), t, f1.f2) 180 #define CHECK_SUBFIELD_1_(k, n, f1, f2) \ 181 CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f1 ## __ ## f2, F1), \ 182 n, f1.f2) 183 184 #define CHECK_SUBFIELD_2(t, f1, f2, f3) \ 185 CHECK_FIELD_COMMON(CHECK_NAME(t ## __ ## f1 ## __ ## f2 ## __ ## f3, F2), \ 186 t, f1.f2.f3) 187 #define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \ 188 CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f1 ## __ ## f2 ## __ ## \ 189 f3, F2), n, f1.f2.f3) 190 191 /* 192 * Translate a native continuation into a compat guest continuation. 193 * 194 * id: If non-NULL then points to an integer N between 0-5. Will be updated 195 * with the value of the N'th argument to the hypercall. The N'th argument must 196 * not be subject to translation (i.e. cannot be referenced by @mask below). 197 * This option is useful for extracting the "op" argument or similar from the 198 * hypercall to enable further xlat processing. 199 * 200 * nr: Total number of arguments the hypercall has. 201 * 202 * mask: Specifies which of the hypercall arguments require compat translation. 203 * bit 0 indicates that the 0'th argument requires translation, bit 1 indicates 204 * that the first argument requires translation and so on. Native and compat 205 * values for each translated argument are provided as @varargs (see below). 206 * 207 * varargs: For each bit which is set in @mask the varargs contain a native 208 * value (unsigned long) and a compat value (unsigned int). If the native value 209 * and compat value differ and the N'th argument is equal to the native value 210 * then that argument is replaced by the compat value. If the native and compat 211 * values are equal then no translation takes place. If the N'th argument does 212 * not equal the native value then no translation takes place. 213 * 214 * Any untranslated argument (whether due to not being requested in @mask, 215 * native and compat values being equal or N'th argument not equalling native 216 * value) must be equal in both native and compat representations (i.e. the 217 * native version cannot have any bits > 32 set) 218 * 219 * Return: Number of arguments which were actually translated. 220 */ 221 int hypercall_xlat_continuation(unsigned int *id, unsigned int nr, 222 unsigned int mask, ...); 223 224 /* In-place translation functons: */ 225 struct start_info; 226 void xlat_start_info(struct start_info *, enum XLAT_start_info_console); 227 struct vcpu_runstate_info; 228 void xlat_vcpu_runstate_info(struct vcpu_runstate_info *); 229 230 struct domain; 231 int switch_compat(struct domain *); 232 233 #else 234 235 #define compat_handle_is_null(hnd) 0 236 237 #endif 238 239 #endif /* __XEN_COMPAT_H__ */ 240