direct-io.hg

view xen/include/asm-x86/guest_access.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 9c6531217c7c
children
line source
1 /******************************************************************************
2 * guest_access.h
3 *
4 * Copyright (c) 2006, K A Fraser
5 */
7 #ifndef __ASM_X86_GUEST_ACCESS_H__
8 #define __ASM_X86_GUEST_ACCESS_H__
10 #include <asm/uaccess.h>
11 #include <asm/shadow.h>
12 #include <asm/hvm/support.h>
13 #include <asm/hvm/guest_access.h>
15 /* Is the guest handle a NULL reference? */
16 #define guest_handle_is_null(hnd) ((hnd).p == NULL)
18 /* Offset the given guest handle into the array it refers to. */
19 #define guest_handle_add_offset(hnd, nr) ((hnd).p += (nr))
21 /* Cast a guest handle to the specified type of handle. */
22 #define guest_handle_cast(hnd, type) ({ \
23 type *_x = (hnd).p; \
24 (XEN_GUEST_HANDLE(type)) { _x }; \
25 })
27 #define guest_handle_from_ptr(ptr, type) \
28 ((XEN_GUEST_HANDLE(type)) { (type *)ptr })
30 /*
31 * Copy an array of objects to guest context via a guest handle,
32 * specifying an offset into the guest array.
33 */
34 #define copy_to_guest_offset(hnd, off, ptr, nr) ({ \
35 const typeof(*(ptr)) *_s = (ptr); \
36 char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \
37 ((void)((hnd).p == (ptr))); \
38 is_hvm_vcpu(current) ? \
39 copy_to_user_hvm(_d+(off), _s, sizeof(*_s)*(nr)) : \
40 copy_to_user(_d+(off), _s, sizeof(*_s)*(nr)); \
41 })
43 /*
44 * Copy an array of objects from guest context via a guest handle,
45 * specifying an offset into the guest array.
46 */
47 #define copy_from_guest_offset(ptr, hnd, off, nr) ({ \
48 const typeof(*(ptr)) *_s = (hnd).p; \
49 typeof(*(ptr)) *_d = (ptr); \
50 is_hvm_vcpu(current) ? \
51 copy_from_user_hvm(_d, _s+(off), sizeof(*_d)*(nr)) :\
52 copy_from_user(_d, _s+(off), sizeof(*_d)*(nr)); \
53 })
55 /* Copy sub-field of a structure to guest context via a guest handle. */
56 #define copy_field_to_guest(hnd, ptr, field) ({ \
57 const typeof(&(ptr)->field) _s = &(ptr)->field; \
58 void *_d = &(hnd).p->field; \
59 ((void)(&(hnd).p->field == &(ptr)->field)); \
60 is_hvm_vcpu(current) ? \
61 copy_to_user_hvm(_d, _s, sizeof(*_s)) : \
62 copy_to_user(_d, _s, sizeof(*_s)); \
63 })
65 /* Copy sub-field of a structure from guest context via a guest handle. */
66 #define copy_field_from_guest(ptr, hnd, field) ({ \
67 const typeof(&(ptr)->field) _s = &(hnd).p->field; \
68 typeof(&(ptr)->field) _d = &(ptr)->field; \
69 is_hvm_vcpu(current) ? \
70 copy_from_user_hvm(_d, _s, sizeof(*_d)) : \
71 copy_from_user(_d, _s, sizeof(*_d)); \
72 })
74 /*
75 * Pre-validate a guest handle.
76 * Allows use of faster __copy_* functions.
77 */
78 #define guest_handle_okay(hnd, nr) \
79 (shadow_mode_external(current->domain) || \
80 array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
82 #define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \
83 const typeof(*(ptr)) *_s = (ptr); \
84 char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \
85 ((void)((hnd).p == (ptr))); \
86 is_hvm_vcpu(current) ? \
87 copy_to_user_hvm(_d+(off), _s, sizeof(*_s)*(nr)) : \
88 __copy_to_user(_d+(off), _s, sizeof(*_s)*(nr)); \
89 })
91 #define __copy_from_guest_offset(ptr, hnd, off, nr) ({ \
92 const typeof(*(ptr)) *_s = (hnd).p; \
93 typeof(*(ptr)) *_d = (ptr); \
94 is_hvm_vcpu(current) ? \
95 copy_from_user_hvm(_d, _s+(off), sizeof(*_d)*(nr)) :\
96 __copy_from_user(_d, _s+(off), sizeof(*_d)*(nr)); \
97 })
99 #define __copy_field_to_guest(hnd, ptr, field) ({ \
100 const typeof(&(ptr)->field) _s = &(ptr)->field; \
101 void *_d = &(hnd).p->field; \
102 ((void)(&(hnd).p->field == &(ptr)->field)); \
103 is_hvm_vcpu(current) ? \
104 copy_to_user_hvm(_d, _s, sizeof(*_s)) : \
105 __copy_to_user(_d, _s, sizeof(*_s)); \
106 })
108 #define __copy_field_from_guest(ptr, hnd, field) ({ \
109 const typeof(&(ptr)->field) _s = &(hnd).p->field; \
110 typeof(&(ptr)->field) _d = &(ptr)->field; \
111 is_hvm_vcpu(current) ? \
112 copy_from_user_hvm(_d, _s, sizeof(*_d)) : \
113 __copy_from_user(_d, _s, sizeof(*_d)); \
114 })
116 #endif /* __ASM_X86_GUEST_ACCESS_H__ */