debuggers.hg

annotate xen/common/multicall.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents 894d10d315c2
children
rev   line source
kaf24@3177 1 /******************************************************************************
kaf24@3177 2 * multicall.c
kaf24@3177 3 */
kaf24@3177 4
kaf24@3177 5 #include <xen/config.h>
kaf24@3177 6 #include <xen/types.h>
kaf24@3177 7 #include <xen/lib.h>
kaf24@3177 8 #include <xen/mm.h>
kaf24@3177 9 #include <xen/sched.h>
kaf24@3177 10 #include <xen/event.h>
kaf24@3177 11 #include <xen/multicall.h>
kaf24@9197 12 #include <xen/guest_access.h>
kfraser@14624 13 #include <xen/perfc.h>
cl349@5329 14 #include <asm/current.h>
cl349@5323 15 #include <asm/hardirq.h>
kaf24@3177 16
ack@13303 17 #ifndef COMPAT
ack@13303 18 typedef long ret_t;
ian@15221 19 #define xlat_multicall_entry(mcs)
ack@13303 20 #endif
kaf24@3177 21
ack@13303 22 ret_t
kaf24@9197 23 do_multicall(
kaf24@9904 24 XEN_GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls)
kaf24@3177 25 {
keir@22438 26 struct mc_state *mcs = &current->mc_state;
kaf24@3177 27 unsigned int i;
kaf24@3177 28
kaf24@3177 29 if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) )
kaf24@3177 30 {
kaf24@12062 31 gdprintk(XENLOG_INFO, "Multicall reentry is disallowed.\n");
kaf24@3177 32 return -EINVAL;
kaf24@3177 33 }
kaf24@3177 34
kaf24@9197 35 if ( unlikely(!guest_handle_okay(call_list, nr_calls)) )
kaf24@3177 36 goto fault;
kaf24@3177 37
kaf24@3177 38 for ( i = 0; i < nr_calls; i++ )
kaf24@3177 39 {
kaf24@9208 40 if ( hypercall_preempt_check() )
kaf24@9208 41 goto preempted;
kaf24@9208 42
kaf24@9208 43 if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) )
kaf24@3177 44 goto fault;
kaf24@3177 45
kaf24@3177 46 do_multicall_call(&mcs->call);
kaf24@3177 47
kaf24@6490 48 #ifndef NDEBUG
kaf24@6490 49 {
kaf24@6490 50 /*
kaf24@6490 51 * Deliberately corrupt the contents of the multicall structure.
kaf24@6490 52 * The caller must depend only on the 'result' field on return.
kaf24@6490 53 */
kaf24@8717 54 struct multicall_entry corrupt;
kaf24@6490 55 memset(&corrupt, 0xAA, sizeof(corrupt));
kaf24@9208 56 (void)__copy_to_guest(call_list, &corrupt, 1);
kaf24@6490 57 }
kaf24@6490 58 #endif
kaf24@6490 59
kaf24@9208 60 if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) )
kaf24@3177 61 goto fault;
kaf24@3177 62
kaf24@9208 63 if ( test_bit(_MCSF_call_preempted, &mcs->flags) )
kaf24@3177 64 {
ian@15221 65 /* Translate sub-call continuation to guest layout */
ian@15221 66 xlat_multicall_entry(mcs);
ian@15221 67
kaf24@9208 68 /* Copy the sub-call continuation. */
kaf24@9208 69 (void)__copy_to_guest(call_list, &mcs->call, 1);
kaf24@9208 70 goto preempted;
kaf24@9208 71 }
kaf24@3177 72
kaf24@9208 73 guest_handle_add_offset(call_list, 1);
kaf24@3177 74 }
kaf24@3177 75
kfraser@14624 76 perfc_incr(calls_to_multicall);
kfraser@14624 77 perfc_add(calls_from_multicall, nr_calls);
kaf24@3177 78 mcs->flags = 0;
kaf24@3177 79 return 0;
kaf24@3177 80
kaf24@3177 81 fault:
kfraser@14624 82 perfc_incr(calls_to_multicall);
kaf24@3177 83 mcs->flags = 0;
kaf24@3177 84 return -EFAULT;
kaf24@9208 85
kaf24@9208 86 preempted:
kfraser@14624 87 perfc_add(calls_from_multicall, i);
kaf24@9208 88 mcs->flags = 0;
kaf24@9208 89 return hypercall_create_continuation(
kaf24@9208 90 __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
kaf24@3177 91 }
kaf24@3952 92
kaf24@3952 93 /*
kaf24@3952 94 * Local variables:
kaf24@3952 95 * mode: C
kaf24@3952 96 * c-set-style: "BSD"
kaf24@3952 97 * c-basic-offset: 4
kaf24@3952 98 * tab-width: 4
kaf24@3952 99 * indent-tabs-mode: nil
kaf24@4026 100 * End:
kaf24@3952 101 */