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