direct-io.hg

view xen/include/xen/xencomm.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 a510c94ceaa3
children
line source
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2006
17 *
18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19 */
21 #ifndef __XENCOMM_H__
22 #define __XENCOMM_H__
24 #include <public/xen.h>
26 extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
27 unsigned int len, unsigned int skip);
28 extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
29 unsigned int len, unsigned int skip);
30 extern int xencomm_add_offset(void **handle, unsigned int bytes);
31 extern int xencomm_handle_is_null(void *ptr);
34 static inline int xencomm_is_inline(const void *handle)
35 {
36 unsigned long addr = (unsigned long)handle;
37 return (addr & XENCOMM_INLINE_FLAG) == XENCOMM_INLINE_FLAG;
38 }
40 static inline unsigned long xencomm_inline_addr(const void *handle)
41 {
42 return (unsigned long)handle & ~XENCOMM_INLINE_FLAG;
43 }
45 /* Is the guest handle a NULL reference? */
46 #define guest_handle_is_null(hnd) \
47 ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
49 /* Offset the given guest handle into the array it refers to. */
50 #define guest_handle_add_offset(hnd, nr) ({ \
51 const typeof((hnd).p) _ptr; \
52 xencomm_add_offset((void **)&((hnd).p), nr * sizeof(*_ptr)); \
53 })
55 /* Cast a guest handle to the specified type of handle. */
56 #define guest_handle_cast(hnd, type) ({ \
57 type *_x = (hnd).p; \
58 XEN_GUEST_HANDLE(type) _y; \
59 set_xen_guest_handle(_y, _x); \
60 _y; \
61 })
63 /* Since we run in real mode, we can safely access all addresses. That also
64 * means our __routines are identical to our "normal" routines. */
65 #define guest_handle_okay(hnd, nr) 1
67 /*
68 * Copy an array of objects to guest context via a guest handle.
69 * Optionally specify an offset into the guest array.
70 */
71 #define copy_to_guest_offset(hnd, idx, ptr, nr) \
72 __copy_to_guest_offset(hnd, idx, ptr, nr)
74 /* Copy sub-field of a structure to guest context via a guest handle. */
75 #define copy_field_to_guest(hnd, ptr, field) \
76 __copy_field_to_guest(hnd, ptr, field)
78 /*
79 * Copy an array of objects from guest context via a guest handle.
80 * Optionally specify an offset into the guest array.
81 */
82 #define copy_from_guest_offset(ptr, hnd, idx, nr) \
83 __copy_from_guest_offset(ptr, hnd, idx, nr)
85 /* Copy sub-field of a structure from guest context via a guest handle. */
86 #define copy_field_from_guest(ptr, hnd, field) \
87 __copy_field_from_guest(ptr, hnd, field)
89 #define __copy_to_guest_offset(hnd, idx, ptr, nr) ({ \
90 const typeof(*(ptr)) *_s = (ptr); \
91 void *_d = (hnd).p; \
92 ((void)((hnd).p == (ptr))); \
93 xencomm_copy_to_guest(_d, _s, sizeof(*_s)*(nr), sizeof(*_s)*(idx)); \
94 })
96 #define __copy_field_to_guest(hnd, ptr, field) ({ \
97 unsigned int _off = offsetof(typeof(*(hnd).p), field); \
98 const typeof(&(ptr)->field) _s = &(ptr)->field; \
99 void *_d = (hnd).p; \
100 ((void)(&(hnd).p->field == &(ptr)->field)); \
101 xencomm_copy_to_guest(_d, _s, sizeof(*_s), _off); \
102 })
104 #define __copy_from_guest_offset(ptr, hnd, idx, nr) ({ \
105 const typeof(*(ptr)) *_s = (hnd).p; \
106 typeof(*(ptr)) *_d = (ptr); \
107 xencomm_copy_from_guest(_d, _s, sizeof(*_d)*(nr), sizeof(*_d)*(idx)); \
108 })
110 #define __copy_field_from_guest(ptr, hnd, field) ({ \
111 unsigned int _off = offsetof(typeof(*(hnd).p), field); \
112 const void *_s = (hnd).p; \
113 typeof(&(ptr)->field) _d = &(ptr)->field; \
114 ((void)(&(hnd).p->field == &(ptr)->field)); \
115 xencomm_copy_from_guest(_d, _s, sizeof(*_d), _off); \
116 })
118 #endif /* __XENCOMM_H__ */