# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 53b0dc1cb1db1ca55723d241758bceb4b0577801
# Parent 3627061dcc9af8622bd7f63086d9d673cd3d8624
Implement guest_access routines for copying to/from a sub-field of a structure.
Use this as part of a tidy-up of the multicall hypercall.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 3627061dcc9a -r 53b0dc1cb1db xen/common/multicall.c
--- a/xen/common/multicall.c Wed Mar 8 14:35:14 2006
+++ b/xen/common/multicall.c Wed Mar 8 14:39:59 2006
@@ -34,7 +34,10 @@
for ( i = 0; i < nr_calls; i++ )
{
- if ( unlikely(__copy_from_guest_offset(&mcs->call, call_list, i, 1)) )
+ if ( hypercall_preempt_check() )
+ goto preempted;
+
+ if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) )
goto fault;
do_multicall_call(&mcs->call);
@@ -47,33 +50,21 @@
*/
struct multicall_entry corrupt;
memset(&corrupt, 0xAA, sizeof(corrupt));
- (void)__copy_to_guest_offset(call_list, i, &corrupt, 1);
+ (void)__copy_to_guest(call_list, &corrupt, 1);
}
#endif
- if ( unlikely(__copy_to_guest_offset(call_list, i, &mcs->call, 1)) )
+ if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) )
goto fault;
- if ( hypercall_preempt_check() )
+ if ( test_bit(_MCSF_call_preempted, &mcs->flags) )
{
- /*
- * Copy the sub-call continuation if it was preempted.
- * Otherwise skip over the sub-call entirely.
- */
- if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
- i++;
- else
- (void)__copy_to_guest_offset(call_list, i, &mcs->call, 1);
+ /* Copy the sub-call continuation. */
+ (void)__copy_to_guest(call_list, &mcs->call, 1);
+ goto preempted;
+ }
- /* Only create a continuation if there is work left to be done. */
- if ( i < nr_calls )
- {
- mcs->flags = 0;
- guest_handle_add_offset(call_list, i);
- return hypercall_create_continuation(
- __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
- }
- }
+ guest_handle_add_offset(call_list, 1);
}
mcs->flags = 0;
@@ -82,6 +73,11 @@
fault:
mcs->flags = 0;
return -EFAULT;
+
+ preempted:
+ mcs->flags = 0;
+ return hypercall_create_continuation(
+ __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
}
/*
diff -r 3627061dcc9a -r 53b0dc1cb1db xen/include/asm-ia64/guest_access.h
--- a/xen/include/asm-ia64/guest_access.h Wed Mar 8 14:35:14 2006
+++ b/xen/include/asm-ia64/guest_access.h Wed Mar 8 14:39:59 2006
@@ -43,6 +43,20 @@
copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \
})
+/* Copy sub-field of a structure to guest context via a guest handle. */
+#define copy_field_to_guest(hnd, ptr, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ copy_to_user(_x, _y, sizeof(*_x)); \
+})
+
+/* Copy sub-field of a structure from guest context via a guest handle. */
+#define copy_field_from_guest(ptr, hnd, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ copy_from_user(_y, _x, sizeof(*_x)); \
+})
+
/*
* Pre-validate a guest handle.
* Allows use of faster __copy_* functions.
@@ -62,4 +76,16 @@
__copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \
})
+#define __copy_field_to_guest(hnd, ptr, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ __copy_to_user(_x, _y, sizeof(*_x)); \
+})
+
+#define __copy_field_from_guest(ptr, hnd, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ __copy_from_user(_y, _x, sizeof(*_x)); \
+})
+
#endif /* __ASM_IA64_GUEST_ACCESS_H__ */
diff -r 3627061dcc9a -r 53b0dc1cb1db xen/include/asm-x86/guest_access.h
--- a/xen/include/asm-x86/guest_access.h Wed Mar 8 14:35:14 2006
+++ b/xen/include/asm-x86/guest_access.h Wed Mar 8 14:39:59 2006
@@ -41,6 +41,20 @@
copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \
})
+/* Copy sub-field of a structure to guest context via a guest handle. */
+#define copy_field_to_guest(hnd, ptr, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ copy_to_user(_x, _y, sizeof(*_x)); \
+})
+
+/* Copy sub-field of a structure from guest context via a guest handle. */
+#define copy_field_from_guest(ptr, hnd, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ copy_from_user(_y, _x, sizeof(*_x)); \
+})
+
/*
* Pre-validate a guest handle.
* Allows use of faster __copy_* functions.
@@ -60,4 +74,16 @@
__copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \
})
+#define __copy_field_to_guest(hnd, ptr, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ __copy_to_user(_x, _y, sizeof(*_x)); \
+})
+
+#define __copy_field_from_guest(ptr, hnd, field) ({ \
+ const typeof(&(ptr)->field) _x = &(hnd).p->field; \
+ const typeof(&(ptr)->field) _y = &(ptr)->field; \
+ __copy_from_user(_y, _x, sizeof(*_x)); \
+})
+
#endif /* __ASM_X86_GUEST_ACCESS_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|