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