ia64/xen-unstable

view xen/common/compat/grant_table.c @ 17062:0769835cf50f

x86 shadow: Reduce scope of shadow lock.

emulate_map_dest doesn't require holding lock, since
only shadow related operation possibly involved is to
remove shadow which is less frequent and can acquire
lock inside. Rest are either guest table walk or
per-vcpu monitor table manipulation

Signed-off-by Kevin Tian <kevin.tian@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 14 10:33:12 2008 +0000 (2008-02-14)
parents c229802cedbb
children 115a1720e976
line source
1 /******************************************************************************
2 * common/compat/grant_table.c
3 *
4 */
6 #include <compat/grant_table.h>
8 #define xen_grant_entry grant_entry
9 CHECK_grant_entry;
10 #undef xen_grant_entry
12 #define xen_gnttab_map_grant_ref gnttab_map_grant_ref
13 CHECK_gnttab_map_grant_ref;
14 #undef xen_gnttab_map_grant_ref
16 #define xen_gnttab_unmap_grant_ref gnttab_unmap_grant_ref
17 CHECK_gnttab_unmap_grant_ref;
18 #undef xen_gnttab_unmap_grant_ref
20 #define xen_gnttab_unmap_and_replace gnttab_unmap_and_replace
21 CHECK_gnttab_unmap_and_replace;
22 #undef xen_gnttab_unmap_and_replace
24 DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_compat_t);
25 DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_compat_t);
26 DEFINE_XEN_GUEST_HANDLE(gnttab_copy_compat_t);
28 #define xen_gnttab_dump_table gnttab_dump_table
29 CHECK_gnttab_dump_table;
30 #undef xen_gnttab_dump_table
32 int compat_grant_table_op(unsigned int cmd,
33 XEN_GUEST_HANDLE(void) cmp_uop,
34 unsigned int count)
35 {
36 int rc = 0;
37 unsigned int i;
39 switch ( cmd )
40 {
41 #define CASE(name) \
42 case GNTTABOP_##name: \
43 if ( unlikely(!guest_handle_okay(guest_handle_cast(cmp_uop, \
44 gnttab_##name##_compat_t), \
45 count)) ) \
46 rc = -EFAULT; \
47 break
49 #ifndef CHECK_gnttab_map_grant_ref
50 CASE(map_grant_ref);
51 #endif
53 #ifndef CHECK_gnttab_unmap_grant_ref
54 CASE(unmap_grant_ref);
55 #endif
57 #ifndef CHECK_gnttab_unmap_and_replace
58 CASE(unmap_and_replace);
59 #endif
61 #ifndef CHECK_gnttab_setup_table
62 CASE(setup_table);
63 #endif
65 #ifndef CHECK_gnttab_transfer
66 CASE(transfer);
67 #endif
69 #ifndef CHECK_gnttab_copy
70 CASE(copy);
71 #endif
73 #ifndef CHECK_gnttab_dump_table
74 CASE(dump_table);
75 #endif
77 #undef CASE
78 default:
79 return do_grant_table_op(cmd, cmp_uop, count);
80 }
82 if ( count > 512 )
83 rc = -EINVAL;
85 for ( i = 0; i < count && rc == 0; )
86 {
87 unsigned int n;
88 union {
89 XEN_GUEST_HANDLE(void) uop;
90 struct gnttab_setup_table *setup;
91 struct gnttab_transfer *xfer;
92 struct gnttab_copy *copy;
93 } nat;
94 union {
95 struct compat_gnttab_setup_table setup;
96 struct compat_gnttab_transfer xfer;
97 struct compat_gnttab_copy copy;
98 } cmp;
100 set_xen_guest_handle(nat.uop, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id));
101 switch ( cmd )
102 {
103 case GNTTABOP_setup_table:
104 if ( unlikely(count > 1) )
105 rc = -EINVAL;
106 else if ( unlikely(__copy_from_guest(&cmp.setup, cmp_uop, 1)) )
107 rc = -EFAULT;
108 else if ( unlikely(!compat_handle_okay(cmp.setup.frame_list, cmp.setup.nr_frames)) )
109 rc = -EFAULT;
110 else
111 {
112 BUG_ON((COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) / sizeof(*nat.setup->frame_list.p) < max_nr_grant_frames);
113 #define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
114 set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
115 XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
116 #undef XLAT_gnttab_setup_table_HNDL_frame_list
117 rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
118 }
119 if ( rc == 0 )
120 {
121 #define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
122 do \
123 { \
124 if ( (_s_)->status == GNTST_okay ) \
125 { \
126 for ( i = 0; i < (_s_)->nr_frames; ++i ) \
127 { \
128 unsigned int frame = (_s_)->frame_list.p[i]; \
129 BUG_ON(frame != (_s_)->frame_list.p[i]); \
130 (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
131 } \
132 } \
133 } while (0)
134 XLAT_gnttab_setup_table(&cmp.setup, nat.setup);
135 #undef XLAT_gnttab_setup_table_HNDL_frame_list
136 if ( unlikely(__copy_to_guest(cmp_uop, &cmp.setup, 1)) )
137 rc = -EFAULT;
138 else
139 i = 1;
140 }
141 break;
143 case GNTTABOP_transfer:
144 for ( n = 0; n < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n )
145 {
146 if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 1)) )
147 rc = -EFAULT;
148 else
149 {
150 XLAT_gnttab_transfer(nat.xfer + n, &cmp.xfer);
151 }
152 }
153 if ( rc == 0 )
154 rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n);
155 if ( rc == 0 )
156 {
157 XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer;
159 xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t);
160 guest_handle_add_offset(xfer, i);
161 while ( n-- )
162 {
163 guest_handle_add_offset(xfer, -1);
164 if ( __copy_field_to_guest(xfer, nat.xfer + n, status) )
165 rc = -EFAULT;
166 }
167 }
168 break;
170 case GNTTABOP_copy:
171 for ( n = 0; n < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n )
172 {
173 if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 1)) )
174 rc = -EFAULT;
175 else
176 {
177 enum XLAT_gnttab_copy_source_u source_u;
178 enum XLAT_gnttab_copy_dest_u dest_u;
180 if ( cmp.copy.flags & GNTCOPY_source_gref )
181 source_u = XLAT_gnttab_copy_source_u_ref;
182 else
183 source_u = XLAT_gnttab_copy_source_u_gmfn;
184 if ( cmp.copy.flags & GNTCOPY_dest_gref )
185 dest_u = XLAT_gnttab_copy_dest_u_ref;
186 else
187 dest_u = XLAT_gnttab_copy_dest_u_gmfn;
188 XLAT_gnttab_copy(nat.copy + n, &cmp.copy);
189 }
190 }
191 if ( rc == 0 )
192 rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n);
193 if ( rc == 0 )
194 {
195 XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy;
197 copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t);
198 guest_handle_add_offset(copy, i);
199 while ( n-- )
200 {
201 guest_handle_add_offset(copy, -1);
202 if ( __copy_field_to_guest(copy, nat.copy + n, status) )
203 rc = -EFAULT;
204 }
205 }
206 break;
208 default:
209 domain_crash(current->domain);
210 break;
211 }
212 }
214 return rc;
215 }
217 /*
218 * Local variables:
219 * mode: C
220 * c-set-style: "BSD"
221 * c-basic-offset: 4
222 * tab-width: 4
223 * indent-tabs-mode: nil
224 * End:
225 */