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)92 int xc_monitor_mov_to_msr(xc_interface *xch, uint32_t domain_id, uint32_t msr,
93 bool enable)
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
104 return do_domctl(xch, &domctl);
105 }
106
xc_monitor_software_breakpoint(xc_interface * xch,uint32_t domain_id,bool enable)107 int xc_monitor_software_breakpoint(xc_interface *xch, uint32_t domain_id,
108 bool enable)
109 {
110 DECLARE_DOMCTL;
111
112 domctl.cmd = XEN_DOMCTL_monitor_op;
113 domctl.domain = domain_id;
114 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
115 : XEN_DOMCTL_MONITOR_OP_DISABLE;
116 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT;
117
118 return do_domctl(xch, &domctl);
119 }
120
xc_monitor_singlestep(xc_interface * xch,uint32_t domain_id,bool enable)121 int xc_monitor_singlestep(xc_interface *xch, uint32_t domain_id,
122 bool enable)
123 {
124 DECLARE_DOMCTL;
125
126 domctl.cmd = XEN_DOMCTL_monitor_op;
127 domctl.domain = domain_id;
128 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
129 : XEN_DOMCTL_MONITOR_OP_DISABLE;
130 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP;
131
132 return do_domctl(xch, &domctl);
133 }
134
xc_monitor_descriptor_access(xc_interface * xch,uint32_t domain_id,bool enable)135 int xc_monitor_descriptor_access(xc_interface *xch, uint32_t domain_id,
136 bool enable)
137 {
138 DECLARE_DOMCTL;
139
140 domctl.cmd = XEN_DOMCTL_monitor_op;
141 domctl.domain = domain_id;
142 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
143 : XEN_DOMCTL_MONITOR_OP_DISABLE;
144 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS;
145
146 return do_domctl(xch, &domctl);
147 }
148
xc_monitor_guest_request(xc_interface * xch,uint32_t domain_id,bool enable,bool sync,bool allow_userspace)149 int xc_monitor_guest_request(xc_interface *xch, uint32_t domain_id, bool enable,
150 bool sync, bool allow_userspace)
151 {
152 DECLARE_DOMCTL;
153
154 domctl.cmd = XEN_DOMCTL_monitor_op;
155 domctl.domain = domain_id;
156 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
157 : XEN_DOMCTL_MONITOR_OP_DISABLE;
158 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST;
159 domctl.u.monitor_op.u.guest_request.sync = sync;
160 domctl.u.monitor_op.u.guest_request.allow_userspace = enable ? allow_userspace : false;
161
162 return do_domctl(xch, &domctl);
163 }
164
xc_monitor_emulate_each_rep(xc_interface * xch,uint32_t domain_id,bool enable)165 int xc_monitor_emulate_each_rep(xc_interface *xch, uint32_t domain_id,
166 bool enable)
167 {
168 DECLARE_DOMCTL;
169
170 domctl.cmd = XEN_DOMCTL_monitor_op;
171 domctl.domain = domain_id;
172 domctl.u.monitor_op.op = XEN_DOMCTL_MONITOR_OP_EMULATE_EACH_REP;
173 domctl.u.monitor_op.event = enable;
174
175 return do_domctl(xch, &domctl);
176 }
177
xc_monitor_debug_exceptions(xc_interface * xch,uint32_t domain_id,bool enable,bool sync)178 int xc_monitor_debug_exceptions(xc_interface *xch, uint32_t domain_id,
179 bool enable, bool sync)
180 {
181 DECLARE_DOMCTL;
182
183 domctl.cmd = XEN_DOMCTL_monitor_op;
184 domctl.domain = domain_id;
185 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
186 : XEN_DOMCTL_MONITOR_OP_DISABLE;
187 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION;
188 domctl.u.monitor_op.u.debug_exception.sync = sync;
189
190 return do_domctl(xch, &domctl);
191 }
192
xc_monitor_cpuid(xc_interface * xch,uint32_t domain_id,bool enable)193 int xc_monitor_cpuid(xc_interface *xch, uint32_t domain_id, bool enable)
194 {
195 DECLARE_DOMCTL;
196
197 domctl.cmd = XEN_DOMCTL_monitor_op;
198 domctl.domain = domain_id;
199 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
200 : XEN_DOMCTL_MONITOR_OP_DISABLE;
201 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_CPUID;
202
203 return do_domctl(xch, &domctl);
204 }
205
xc_monitor_privileged_call(xc_interface * xch,uint32_t domain_id,bool enable)206 int xc_monitor_privileged_call(xc_interface *xch, uint32_t domain_id,
207 bool enable)
208 {
209 DECLARE_DOMCTL;
210
211 domctl.cmd = XEN_DOMCTL_monitor_op;
212 domctl.domain = domain_id;
213 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
214 : XEN_DOMCTL_MONITOR_OP_DISABLE;
215 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_PRIVILEGED_CALL;
216
217 return do_domctl(xch, &domctl);
218 }
219
xc_monitor_emul_unimplemented(xc_interface * xch,uint32_t domain_id,bool enable)220 int xc_monitor_emul_unimplemented(xc_interface *xch, uint32_t domain_id,
221 bool enable)
222 {
223 DECLARE_DOMCTL;
224
225 domctl.cmd = XEN_DOMCTL_monitor_op;
226 domctl.domain = domain_id;
227 domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
228 : XEN_DOMCTL_MONITOR_OP_DISABLE;
229 domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED;
230
231 return do_domctl(xch, &domctl);
232 }
233
234 /*
235 * Local variables:
236 * mode: C
237 * c-file-style: "BSD"
238 * c-basic-offset: 4
239 * tab-width: 4
240 * indent-tabs-mode: nil
241 * End:
242 */
243