ia64/xen-unstable

view xen/common/multicall.c @ 6832:5959fae4722a

Set NE bit for VMX guest CR0. VMCS guest CR0.NE bit must
be set, else it will cause "vm-entry failed".

Signed-off-by: Chengyuan Li <chengyuan.li@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Sep 14 13:37:50 2005 +0000 (2005-09-14)
parents dd668f7527cb
children b2f4823b6ff0 b35215021b32 9af349b055e5 3233e7ecfa9f
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/perfc.h>
10 #include <xen/sched.h>
11 #include <xen/event.h>
12 #include <xen/multicall.h>
13 #include <asm/current.h>
14 #include <asm/hardirq.h>
16 struct mc_state mc_state[NR_CPUS];
18 long do_multicall(multicall_entry_t *call_list, unsigned int nr_calls)
19 {
20 struct mc_state *mcs = &mc_state[smp_processor_id()];
21 unsigned int i;
23 if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) )
24 {
25 DPRINTK("Multicall reentry is disallowed.\n");
26 return -EINVAL;
27 }
29 if ( unlikely(!array_access_ok(call_list, nr_calls, sizeof(*call_list))) )
30 {
31 DPRINTK("Bad memory range %p for %u*%u bytes.\n",
32 call_list, nr_calls, (unsigned int)sizeof(*call_list));
33 goto fault;
34 }
36 for ( i = 0; i < nr_calls; i++ )
37 {
38 if ( unlikely(__copy_from_user(&mcs->call, &call_list[i],
39 sizeof(*call_list))) )
40 {
41 DPRINTK("Error copying from user range %p for %u bytes.\n",
42 &call_list[i], (unsigned int)sizeof(*call_list));
43 goto fault;
44 }
46 do_multicall_call(&mcs->call);
48 #ifndef NDEBUG
49 {
50 /*
51 * Deliberately corrupt the contents of the multicall structure.
52 * The caller must depend only on the 'result' field on return.
53 */
54 multicall_entry_t corrupt;
55 memset(&corrupt, 0xAA, sizeof(corrupt));
56 (void)__copy_to_user(&call_list[i], &corrupt, sizeof(corrupt));
57 }
58 #endif
60 if ( unlikely(__put_user(mcs->call.result, &call_list[i].result)) )
61 {
62 DPRINTK("Error writing result back to multicall block.\n");
63 goto fault;
64 }
66 if ( hypercall_preempt_check() )
67 {
68 /*
69 * Copy the sub-call continuation if it was preempted.
70 * Otherwise skip over the sub-call entirely.
71 */
72 if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
73 i++;
74 else
75 (void)__copy_to_user(&call_list[i], &mcs->call,
76 sizeof(*call_list));
78 /* Only create a continuation if there is work left to be done. */
79 if ( i < nr_calls )
80 {
81 mcs->flags = 0;
82 return hypercall2_create_continuation(
83 __HYPERVISOR_multicall, &call_list[i], nr_calls-i);
84 }
85 }
86 }
88 mcs->flags = 0;
89 return 0;
91 fault:
92 mcs->flags = 0;
93 return -EFAULT;
94 }
96 /*
97 * Local variables:
98 * mode: C
99 * c-set-style: "BSD"
100 * c-basic-offset: 4
101 * tab-width: 4
102 * indent-tabs-mode: nil
103 * End:
104 */