1 /******************************************************************************
2 * domain.c
3 *
4 */
5
6 EMIT_FILE;
7
8 #include <xen/lib.h>
9 #include <xen/sched.h>
10 #include <xen/domain.h>
11 #include <xen/guest_access.h>
12 #include <xen/hypercall.h>
13 #include <compat/vcpu.h>
14
15 #define xen_vcpu_set_periodic_timer vcpu_set_periodic_timer
16 CHECK_vcpu_set_periodic_timer;
17 #undef xen_vcpu_set_periodic_timer
18
19 #define xen_vcpu_info vcpu_info
20 CHECK_SIZE_(struct, vcpu_info);
21 #undef xen_vcpu_info
22
23 #define xen_vcpu_register_vcpu_info vcpu_register_vcpu_info
24 CHECK_vcpu_register_vcpu_info;
25 #undef xen_vcpu_register_vcpu_info
26
27 #ifdef CONFIG_HVM
28
29 #include <compat/hvm/hvm_vcpu.h>
30
31 #define xen_vcpu_hvm_context vcpu_hvm_context
32 #define xen_vcpu_hvm_x86_32 vcpu_hvm_x86_32
33 #define xen_vcpu_hvm_x86_64 vcpu_hvm_x86_64
34 CHECK_vcpu_hvm_context;
35 #undef xen_vcpu_hvm_x86_64
36 #undef xen_vcpu_hvm_x86_32
37 #undef xen_vcpu_hvm_context
38
39 #endif
40
compat_common_vcpu_op(int cmd,struct vcpu * v,XEN_GUEST_HANDLE_PARAM (void)arg)41 int compat_common_vcpu_op(int cmd, struct vcpu *v,
42 XEN_GUEST_HANDLE_PARAM(void) arg)
43 {
44 int rc = 0;
45 struct domain *d = current->domain;
46 unsigned int vcpuid = v->vcpu_id;
47
48 switch ( cmd )
49 {
50 case VCPUOP_initialise:
51 {
52 if ( is_pv_domain(d) && v->vcpu_info_area.map == &dummy_vcpu_info )
53 return -EINVAL;
54
55 #ifdef CONFIG_HVM
56 if ( is_hvm_vcpu(v) )
57 {
58 struct vcpu_hvm_context ctxt;
59
60 if ( copy_from_guest(&ctxt, arg, 1) )
61 return -EFAULT;
62
63 domain_lock(d);
64 rc = v->is_initialised ? -EEXIST : arch_set_info_hvm_guest(v, &ctxt);
65 domain_unlock(d);
66 }
67 else
68 #endif
69 {
70 struct compat_vcpu_guest_context *ctxt;
71
72 if ( (ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
73 return -ENOMEM;
74
75 if ( copy_from_guest(ctxt, arg, 1) )
76 {
77 xfree(ctxt);
78 return -EFAULT;
79 }
80
81 domain_lock(d);
82 rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
83 domain_unlock(d);
84
85 xfree(ctxt);
86 }
87
88 if ( rc == -ERESTART )
89 rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
90 cmd, vcpuid, arg);
91
92 break;
93 }
94
95 case VCPUOP_up:
96 case VCPUOP_down:
97 case VCPUOP_is_up:
98 case VCPUOP_set_periodic_timer:
99 case VCPUOP_stop_periodic_timer:
100 case VCPUOP_stop_singleshot_timer:
101 case VCPUOP_register_vcpu_info:
102 rc = common_vcpu_op(cmd, v, arg);
103 break;
104
105 case VCPUOP_get_runstate_info:
106 {
107 union {
108 struct vcpu_runstate_info nat;
109 struct compat_vcpu_runstate_info cmp;
110 } runstate;
111
112 vcpu_runstate_get(v, &runstate.nat);
113 xlat_vcpu_runstate_info(&runstate.nat);
114 if ( copy_to_guest(arg, &runstate.cmp, 1) )
115 rc = -EFAULT;
116 break;
117 }
118
119 case VCPUOP_set_singleshot_timer:
120 {
121 struct compat_vcpu_set_singleshot_timer cmp;
122 struct vcpu_set_singleshot_timer *nat;
123
124 if ( copy_from_guest(&cmp, arg, 1) )
125 return -EFAULT;
126 nat = COMPAT_ARG_XLAT_VIRT_BASE;
127 XLAT_vcpu_set_singleshot_timer(nat, &cmp);
128 rc = do_vcpu_op(cmd, vcpuid, guest_handle_from_ptr(nat, void));
129 break;
130 }
131
132 default:
133 rc = -ENOSYS;
134 break;
135 }
136
137 return rc;
138 }
139
140 /*
141 * Local variables:
142 * mode: C
143 * c-file-style: "BSD"
144 * c-basic-offset: 4
145 * tab-width: 4
146 * indent-tabs-mode: nil
147 * End:
148 */
149