1 /******************************************************************************
2 *
3 * xc_monitor.c
4 *
5 * Interface to VM event monitor
6 *
7 * Copyright (c) 2015 Tamas K Lengyel (tamas@tklengyel.com)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "xc_private.h"
24
xc_monitor_enable(xc_interface * xch,uint32_t domain_id,uint32_t * port)25 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port)
26 {
27 return xc_vm_event_enable(xch, domain_id, HVM_PARAM_MONITOR_RING_PFN,
28 port);
29 }
30
xc_monitor_disable(xc_interface * xch,uint32_t domain_id)31 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id)
32 {
33 return xc_vm_event_control(xch, domain_id,
34 XEN_VM_EVENT_DISABLE,
35 XEN_DOMCTL_VM_EVENT_OP_MONITOR,
36 NULL);
37 }
38
xc_monitor_resume(xc_interface * xch,uint32_t domain_id)39 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id)
40 {
41 return xc_vm_event_control(xch, domain_id,
42 XEN_VM_EVENT_RESUME,
43 XEN_DOMCTL_VM_EVENT_OP_MONITOR,
44 NULL);
45 }
46
xc_monitor_get_capabilities(xc_interface * xch,uint32_t domain_id,uint32_t * capabilities)47 int xc_monitor_get_capabilities(xc_interface *xch, uint32_t domain_id,
48 uint32_t *capabilities)
49 {
50 int rc;
51 DECLARE_DOMCTL;
52
53 if ( !capabilities )
54 {
55 errno = EINVAL;
56 return -1;
57 }
58
59 domctl.cmd = XEN_DOMCTL_monitor_op;
60 domctl.domain = domain_id;
61 domctl.u.monitor_op.op = XEN_DOMCTL_MONITOR_OP_GET_CAPABILITIES;
62
63 rc = do_domctl(xch, &domctl);
64 if ( rc )
65 return rc;
66
67 *capabilities = domctl.u.monitor_op.event;
68 return 0;
69 }
70
xc_monitor_write_ctrlreg(xc_interface * xch,uint32_t domain_id,uint16_t index,bool enable,bool sync,uint64_t bitmask,bool onchangeonly)71 int xc_monitor_write_ctrlreg(xc_interface *xch, uint32_t domain_id,
72 uint16_t index, bool enable, bool sync,
73 uint64_t bitmask, bool onchangeonly)
74 {
75 DECLARE_DOMCTL;
76
77 domctl.cmd = XEN_DOMCTL_monitor_op;
78 domctl.domain = domain_id;
79 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
80 : XEN_DOMCTL_MONITOR_OP_DISABLE;
81 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG;
82 domctl.u.monitor_op.u.mov_to_cr.index = index;
83 domctl.u.monitor_op.u.mov_to_cr.sync = sync;
84 domctl.u.monitor_op.u.mov_to_cr.onchangeonly = onchangeonly;
85 domctl.u.monitor_op.u.mov_to_cr.bitmask = bitmask;
86 domctl.u.monitor_op.u.mov_to_cr.pad1 = 0;
87 domctl.u.monitor_op.u.mov_to_cr.pad2 = 0;
88
89 return do_domctl(xch, &domctl);
90 }
91
xc_monitor_mov_to_msr(xc_interface * xch,uint32_t domain_id,uint32_t msr,bool enable,bool onchangeonly)92 int xc_monitor_mov_to_msr(xc_interface *xch, uint32_t domain_id, uint32_t msr,
93 bool enable, bool onchangeonly)
94 {
95 DECLARE_DOMCTL;
96
97 domctl.cmd = XEN_DOMCTL_monitor_op;
98 domctl.domain = domain_id;
99 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
100 : XEN_DOMCTL_MONITOR_OP_DISABLE;
101 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR;
102 domctl.u.monitor_op.u.mov_to_msr.msr = msr;
103 domctl.u.monitor_op.u.mov_to_msr.onchangeonly = onchangeonly;
104
105 return do_domctl(xch, &domctl);
106 }
107
xc_monitor_software_breakpoint(xc_interface * xch,uint32_t domain_id,bool enable)108 int xc_monitor_software_breakpoint(xc_interface *xch, uint32_t domain_id,
109 bool enable)
110 {
111 DECLARE_DOMCTL;
112
113 domctl.cmd = XEN_DOMCTL_monitor_op;
114 domctl.domain = domain_id;
115 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
116 : XEN_DOMCTL_MONITOR_OP_DISABLE;
117 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT;
118
119 return do_domctl(xch, &domctl);
120 }
121
xc_monitor_singlestep(xc_interface * xch,uint32_t domain_id,bool enable)122 int xc_monitor_singlestep(xc_interface *xch, uint32_t domain_id,
123 bool enable)
124 {
125 DECLARE_DOMCTL;
126
127 domctl.cmd = XEN_DOMCTL_monitor_op;
128 domctl.domain = domain_id;
129 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
130 : XEN_DOMCTL_MONITOR_OP_DISABLE;
131 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP;
132
133 return do_domctl(xch, &domctl);
134 }
135
xc_monitor_descriptor_access(xc_interface * xch,uint32_t domain_id,bool enable)136 int xc_monitor_descriptor_access(xc_interface *xch, uint32_t domain_id,
137 bool enable)
138 {
139 DECLARE_DOMCTL;
140
141 domctl.cmd = XEN_DOMCTL_monitor_op;
142 domctl.domain = domain_id;
143 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
144 : XEN_DOMCTL_MONITOR_OP_DISABLE;
145 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS;
146
147 return do_domctl(xch, &domctl);
148 }
149
xc_monitor_guest_request(xc_interface * xch,uint32_t domain_id,bool enable,bool sync,bool allow_userspace)150 int xc_monitor_guest_request(xc_interface *xch, uint32_t domain_id, bool enable,
151 bool sync, bool allow_userspace)
152 {
153 DECLARE_DOMCTL;
154
155 domctl.cmd = XEN_DOMCTL_monitor_op;
156 domctl.domain = domain_id;
157 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
158 : XEN_DOMCTL_MONITOR_OP_DISABLE;
159 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST;
160 domctl.u.monitor_op.u.guest_request.sync = sync;
161 domctl.u.monitor_op.u.guest_request.allow_userspace = enable ? allow_userspace : false;
162
163 return do_domctl(xch, &domctl);
164 }
165
xc_monitor_inguest_pagefault(xc_interface * xch,uint32_t domain_id,bool disable)166 int xc_monitor_inguest_pagefault(xc_interface *xch, uint32_t domain_id,
167 bool disable)
168 {
169 DECLARE_DOMCTL;
170
171 domctl.cmd = XEN_DOMCTL_monitor_op;
172 domctl.domain = domain_id;
173 domctl.u.monitor_op.op = disable ? XEN_DOMCTL_MONITOR_OP_ENABLE
174 : XEN_DOMCTL_MONITOR_OP_DISABLE;
175 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_INGUEST_PAGEFAULT;
176
177 return do_domctl(xch, &domctl);
178 }
179
xc_monitor_emulate_each_rep(xc_interface * xch,uint32_t domain_id,bool enable)180 int xc_monitor_emulate_each_rep(xc_interface *xch, uint32_t domain_id,
181 bool enable)
182 {
183 DECLARE_DOMCTL;
184
185 domctl.cmd = XEN_DOMCTL_monitor_op;
186 domctl.domain = domain_id;
187 domctl.u.monitor_op.op = XEN_DOMCTL_MONITOR_OP_EMULATE_EACH_REP;
188 domctl.u.monitor_op.event = enable;
189
190 return do_domctl(xch, &domctl);
191 }
192
xc_monitor_debug_exceptions(xc_interface * xch,uint32_t domain_id,bool enable,bool sync)193 int xc_monitor_debug_exceptions(xc_interface *xch, uint32_t domain_id,
194 bool enable, bool sync)
195 {
196 DECLARE_DOMCTL;
197
198 domctl.cmd = XEN_DOMCTL_monitor_op;
199 domctl.domain = domain_id;
200 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
201 : XEN_DOMCTL_MONITOR_OP_DISABLE;
202 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION;
203 domctl.u.monitor_op.u.debug_exception.sync = sync;
204
205 return do_domctl(xch, &domctl);
206 }
207
xc_monitor_cpuid(xc_interface * xch,uint32_t domain_id,bool enable)208 int xc_monitor_cpuid(xc_interface *xch, uint32_t domain_id, bool enable)
209 {
210 DECLARE_DOMCTL;
211
212 domctl.cmd = XEN_DOMCTL_monitor_op;
213 domctl.domain = domain_id;
214 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
215 : XEN_DOMCTL_MONITOR_OP_DISABLE;
216 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_CPUID;
217
218 return do_domctl(xch, &domctl);
219 }
220
xc_monitor_privileged_call(xc_interface * xch,uint32_t domain_id,bool enable)221 int xc_monitor_privileged_call(xc_interface *xch, uint32_t domain_id,
222 bool enable)
223 {
224 DECLARE_DOMCTL;
225
226 domctl.cmd = XEN_DOMCTL_monitor_op;
227 domctl.domain = domain_id;
228 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
229 : XEN_DOMCTL_MONITOR_OP_DISABLE;
230 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_PRIVILEGED_CALL;
231
232 return do_domctl(xch, &domctl);
233 }
234
xc_monitor_emul_unimplemented(xc_interface * xch,uint32_t domain_id,bool enable)235 int xc_monitor_emul_unimplemented(xc_interface *xch, uint32_t domain_id,
236 bool enable)
237 {
238 DECLARE_DOMCTL;
239
240 domctl.cmd = XEN_DOMCTL_monitor_op;
241 domctl.domain = domain_id;
242 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
243 : XEN_DOMCTL_MONITOR_OP_DISABLE;
244 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED;
245
246 return do_domctl(xch, &domctl);
247 }
248
249 /*
250 * Local variables:
251 * mode: C
252 * c-file-style: "BSD"
253 * c-basic-offset: 4
254 * tab-width: 4
255 * indent-tabs-mode: nil
256 * End:
257 */
258