ia64/xen-unstable

view xen/common/multicall.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 63211a8027fa
children
line source
1 /******************************************************************************
2 * multicall.c
3 */
5 #include <xen/config.h>
6 #include <xen/types.h>
7 #include <xen/lib.h>
8 #include <xen/mm.h>
9 #include <xen/sched.h>
10 #include <xen/event.h>
11 #include <xen/multicall.h>
12 #include <xen/guest_access.h>
13 #include <xen/perfc.h>
14 #include <asm/current.h>
15 #include <asm/hardirq.h>
17 #ifndef COMPAT
18 DEFINE_PER_CPU(struct mc_state, mc_state);
19 typedef long ret_t;
20 #define xlat_multicall_entry(mcs)
21 #endif
23 ret_t
24 do_multicall(
25 XEN_GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls)
26 {
27 struct mc_state *mcs = &this_cpu(mc_state);
28 unsigned int i;
30 if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) )
31 {
32 gdprintk(XENLOG_INFO, "Multicall reentry is disallowed.\n");
33 return -EINVAL;
34 }
36 if ( unlikely(!guest_handle_okay(call_list, nr_calls)) )
37 goto fault;
39 for ( i = 0; i < nr_calls; i++ )
40 {
41 if ( hypercall_preempt_check() )
42 goto preempted;
44 if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) )
45 goto fault;
47 do_multicall_call(&mcs->call);
49 #ifndef NDEBUG
50 {
51 /*
52 * Deliberately corrupt the contents of the multicall structure.
53 * The caller must depend only on the 'result' field on return.
54 */
55 struct multicall_entry corrupt;
56 memset(&corrupt, 0xAA, sizeof(corrupt));
57 (void)__copy_to_guest(call_list, &corrupt, 1);
58 }
59 #endif
61 if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) )
62 goto fault;
64 if ( test_bit(_MCSF_call_preempted, &mcs->flags) )
65 {
66 /* Translate sub-call continuation to guest layout */
67 xlat_multicall_entry(mcs);
69 /* Copy the sub-call continuation. */
70 (void)__copy_to_guest(call_list, &mcs->call, 1);
71 goto preempted;
72 }
74 guest_handle_add_offset(call_list, 1);
75 }
77 perfc_incr(calls_to_multicall);
78 perfc_add(calls_from_multicall, nr_calls);
79 mcs->flags = 0;
80 return 0;
82 fault:
83 perfc_incr(calls_to_multicall);
84 mcs->flags = 0;
85 return -EFAULT;
87 preempted:
88 perfc_add(calls_from_multicall, i);
89 mcs->flags = 0;
90 return hypercall_create_continuation(
91 __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
92 }
94 /*
95 * Local variables:
96 * mode: C
97 * c-set-style: "BSD"
98 * c-basic-offset: 4
99 * tab-width: 4
100 * indent-tabs-mode: nil
101 * End:
102 */