direct-io.hg

view xen/include/xen/compat.h @ 15399:45a44a9cbe8d

Enhance guest memory accessor macros so that source operands can be
pointers to const or arrays.

Only build-tested on ia64, and untested for powerpc (which, however,
is almost identical to ia64, except for an apparent bug in the original
version of __copy_field_{from,to}_guest in that the field offset was
multiplied by the field size).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Wed Jun 20 15:29:53 2007 +0100 (2007-06-20)
parents 0bf0672528cf
children ecb89c6ce615
line source
1 /******************************************************************************
2 * compat.h
3 */
5 #ifndef __XEN_COMPAT_H__
6 #define __XEN_COMPAT_H__
8 #include <xen/config.h>
10 #ifdef CONFIG_COMPAT
12 #include <xen/types.h>
13 #include <asm/compat.h>
14 #include <compat/xlat.h>
16 #define __DEFINE_COMPAT_HANDLE(name, type) \
17 typedef struct { \
18 compat_ptr_t c; \
19 type *_[0] __attribute__((__packed__)); \
20 } __compat_handle_ ## name
22 #define DEFINE_COMPAT_HANDLE(name) __DEFINE_COMPAT_HANDLE(name, name)
23 #define COMPAT_HANDLE(name) __compat_handle_ ## name
25 /* Is the compat handle a NULL reference? */
26 #define compat_handle_is_null(hnd) ((hnd).c == 0)
28 /* Offset the given compat handle into the array it refers to. */
29 #define compat_handle_add_offset(hnd, nr) \
30 ((hnd).c += (nr) * sizeof(**(hnd)._))
32 /* Cast a compat handle to the specified type of handle. */
33 #define compat_handle_cast(chnd, type) ({ \
34 type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \
35 (XEN_GUEST_HANDLE(type)) { _x }; \
36 })
38 #define guest_from_compat_handle(ghnd, chnd) \
39 set_xen_guest_handle(ghnd, \
40 (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c)
42 /*
43 * Copy an array of objects to guest context via a compat handle,
44 * specifying an offset into the guest array.
45 */
46 #define copy_to_compat_offset(hnd, off, ptr, nr) ({ \
47 const typeof(*(ptr)) *_s = (ptr); \
48 char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \
49 ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
50 copy_to_user(_d + (off), _s, sizeof(*_s) * (nr)); \
51 })
53 /*
54 * Copy an array of objects from guest context via a compat handle,
55 * specifying an offset into the guest array.
56 */
57 #define copy_from_compat_offset(ptr, hnd, off, nr) ({ \
58 const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
59 typeof(*(ptr)) *_d = (ptr); \
60 copy_from_user(_d, _s + (off), sizeof(*_d) * (nr)); \
61 })
63 #define copy_to_compat(hnd, ptr, nr) \
64 copy_to_compat_offset(hnd, 0, ptr, nr)
66 #define copy_from_compat(ptr, hnd, nr) \
67 copy_from_compat_offset(ptr, hnd, 0, nr)
69 /* Copy sub-field of a structure to guest context via a compat handle. */
70 #define copy_field_to_compat(hnd, ptr, field) ({ \
71 const typeof(&(ptr)->field) _s = &(ptr)->field; \
72 void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
73 ((void)(&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field == \
74 &(ptr)->field)); \
75 copy_to_user(_d, _s, sizeof(*_s)); \
76 })
78 /* Copy sub-field of a structure from guest context via a compat handle. */
79 #define copy_field_from_compat(ptr, hnd, field) ({ \
80 const typeof(&(ptr)->field) _s = \
81 &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
82 typeof(&(ptr)->field) _d = &(ptr)->field; \
83 copy_from_user(_d, _s, sizeof(*_d)); \
84 })
86 /*
87 * Pre-validate a guest handle.
88 * Allows use of faster __copy_* functions.
89 */
90 #define compat_handle_okay(hnd, nr) \
91 compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), \
92 sizeof(**(hnd)._))
94 #define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \
95 const typeof(*(ptr)) *_s = (ptr); \
96 char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \
97 ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
98 __copy_to_user(_d + (off), _s, sizeof(*_s) * (nr)); \
99 })
101 #define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \
102 const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
103 typeof(*(ptr)) *_d = (ptr); \
104 __copy_from_user(_d, _s + (off), sizeof(*_d) * (nr)); \
105 })
107 #define __copy_to_compat(hnd, ptr, nr) \
108 __copy_to_compat_offset(hnd, 0, ptr, nr)
110 #define __copy_from_compat(ptr, hnd, nr) \
111 __copy_from_compat_offset(ptr, hnd, 0, nr)
113 #define __copy_field_to_compat(hnd, ptr, field) ({ \
114 const typeof(&(ptr)->field) _s = &(ptr)->field; \
115 void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
116 ((void)(&((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field == \
117 &(ptr)->field)); \
118 __copy_to_user(_d, _s, sizeof(*_s)); \
119 })
121 #define __copy_field_from_compat(ptr, hnd, field) ({ \
122 const typeof(&(ptr)->field) _s = \
123 &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
124 typeof(&(ptr)->field) _d = &(ptr)->field; \
125 __copy_from_user(_d, _s, sizeof(*_d)); \
126 })
129 #define CHECK_TYPE(name) \
130 typedef int __checkT ## name[1 - ((xen_ ## name ## _t *)0 != \
131 (compat_ ## name ## _t *)0) * 2]
132 #define CHECK_TYPE_(k, n) \
133 typedef int __checkT ## k ## _ ## n[1 - ((k xen_ ## n *)0 != \
134 (k compat_ ## n *)0) * 2]
136 #define CHECK_SIZE(name) \
137 typedef int __checkS ## name[1 - (sizeof(xen_ ## name ## _t) != \
138 sizeof(compat_ ## name ## _t)) * 2]
139 #define CHECK_SIZE_(k, n) \
140 typedef int __checkS ## k ## _ ## n[1 - (sizeof(k xen_ ## n) != \
141 sizeof(k compat_ ## n)) * 2]
143 #define CHECK_FIELD(t, f) \
144 typedef int __checkF ## t ## __ ## f[1 - (&((xen_ ## t ## _t *)0)->f != \
145 &((compat_ ## t ## _t *)0)->f) * 2]
146 #define CHECK_FIELD_(k, n, f) \
147 typedef int __checkF ## k ## _ ## n ## __ ## f[1 - (&((k xen_ ## n *)0)->f != \
148 &((k compat_ ## n *)0)->f) * 2]
150 #define CHECK_SUBFIELD_1(t, f1, f2) \
151 typedef int __checkF1 ## t ## __ ## f1 ## __ ## f2 \
152 [1 - (&((xen_ ## t ## _t *)0)->f1.f2 != \
153 &((compat_ ## t ## _t *)0)->f1.f2) * 2]
154 #define CHECK_SUBFIELD_1_(k, n, f1, f2) \
155 typedef int __checkF1 ## k ## _ ## n ## __ ## f1 ## __ ## f2 \
156 [1 - (&((k xen_ ## n *)0)->f1.f2 != \
157 &((k compat_ ## n *)0)->f1.f2) * 2]
159 #define CHECK_SUBFIELD_2(t, f1, f2, f3) \
160 typedef int __checkF2 ## t ## __ ## f1 ## __ ## f2 ## __ ## f3 \
161 [1 - (&((xen_ ## t ## _t *)0)->f1.f2.f3 != \
162 &((compat_ ## t ## _t *)0)->f1.f2.f3) * 2]
163 #define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \
164 typedef int __checkF2 ## k ## _ ## n ## __ ## f1 ## __ ## f2 ## __ ## f3 \
165 [1 - (&((k xen_ ## n *)0)->f1.f2.f3 != \
166 &((k compat_ ## n *)0)->f1.f2.f3) * 2]
168 extern int compat_disabled;
170 int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...);
172 /* In-place translation functons: */
173 struct start_info;
174 void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
175 struct vcpu_runstate_info;
176 void xlat_vcpu_runstate_info(struct vcpu_runstate_info *);
178 int switch_compat(struct domain *);
179 int switch_native(struct domain *);
181 #define BITS_PER_GUEST_LONG(d) \
182 (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG)
184 #else
186 #define compat_handle_is_null(hnd) 0
188 #define BITS_PER_GUEST_LONG(d) BITS_PER_LONG
190 #endif
192 #endif /* __XEN_COMPAT_H__ */