1 /******************************************************************************
2 *
3 * xc_memshr.c
4 *
5 * Interface to low-level memory sharing functionality.
6 *
7 * Copyright (c) 2009 Citrix Systems, Inc. (Grzegorz Milos)
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 #include <xen/memory.h>
25 #include <xen/grant_table.h>
26
xc_memshr_control(xc_interface * xch,uint32_t domid,int enable)27 int xc_memshr_control(xc_interface *xch,
28 uint32_t domid,
29 int enable)
30 {
31 DECLARE_DOMCTL;
32 struct xen_domctl_mem_sharing_op *op;
33
34 domctl.cmd = XEN_DOMCTL_mem_sharing_op;
35 domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
36 domctl.domain = domid;
37 op = &(domctl.u.mem_sharing_op);
38 op->op = XEN_DOMCTL_MEM_SHARING_CONTROL;
39 op->u.enable = enable;
40
41 return do_domctl(xch, &domctl);
42 }
43
xc_memshr_ring_enable(xc_interface * xch,uint32_t domid,uint32_t * port)44 int xc_memshr_ring_enable(xc_interface *xch,
45 uint32_t domid,
46 uint32_t *port)
47 {
48 if ( !port )
49 {
50 errno = EINVAL;
51 return -1;
52 }
53
54 return xc_vm_event_control(xch, domid,
55 XEN_VM_EVENT_ENABLE,
56 XEN_DOMCTL_VM_EVENT_OP_SHARING,
57 port);
58 }
59
xc_memshr_ring_disable(xc_interface * xch,uint32_t domid)60 int xc_memshr_ring_disable(xc_interface *xch,
61 uint32_t domid)
62 {
63 return xc_vm_event_control(xch, domid,
64 XEN_VM_EVENT_DISABLE,
65 XEN_DOMCTL_VM_EVENT_OP_SHARING,
66 NULL);
67 }
68
xc_memshr_memop(xc_interface * xch,uint32_t domid,xen_mem_sharing_op_t * mso)69 static int xc_memshr_memop(xc_interface *xch, uint32_t domid,
70 xen_mem_sharing_op_t *mso)
71 {
72 mso->domain = domid;
73
74 return do_memory_op(xch, XENMEM_sharing_op, mso, sizeof(*mso));
75 }
76
xc_memshr_nominate_gfn(xc_interface * xch,uint32_t domid,unsigned long gfn,uint64_t * handle)77 int xc_memshr_nominate_gfn(xc_interface *xch,
78 uint32_t domid,
79 unsigned long gfn,
80 uint64_t *handle)
81 {
82 int rc;
83 xen_mem_sharing_op_t mso;
84
85 memset(&mso, 0, sizeof(mso));
86
87 mso.op = XENMEM_sharing_op_nominate_gfn;
88 mso.u.nominate.u.gfn = gfn;
89
90 rc = xc_memshr_memop(xch, domid, &mso);
91
92 if (!rc) *handle = mso.u.nominate.handle;
93
94 return rc;
95 }
96
xc_memshr_nominate_gref(xc_interface * xch,uint32_t domid,grant_ref_t gref,uint64_t * handle)97 int xc_memshr_nominate_gref(xc_interface *xch,
98 uint32_t domid,
99 grant_ref_t gref,
100 uint64_t *handle)
101 {
102 int rc;
103 xen_mem_sharing_op_t mso;
104
105 memset(&mso, 0, sizeof(mso));
106
107 mso.op = XENMEM_sharing_op_nominate_gref;
108 mso.u.nominate.u.grant_ref = gref;
109
110 rc = xc_memshr_memop(xch, domid, &mso);
111
112 if (!rc) *handle = mso.u.nominate.handle;
113
114 return rc;
115 }
116
xc_memshr_share_gfns(xc_interface * xch,uint32_t source_domain,unsigned long source_gfn,uint64_t source_handle,uint32_t client_domain,unsigned long client_gfn,uint64_t client_handle)117 int xc_memshr_share_gfns(xc_interface *xch,
118 uint32_t source_domain,
119 unsigned long source_gfn,
120 uint64_t source_handle,
121 uint32_t client_domain,
122 unsigned long client_gfn,
123 uint64_t client_handle)
124 {
125 xen_mem_sharing_op_t mso;
126
127 memset(&mso, 0, sizeof(mso));
128
129 mso.op = XENMEM_sharing_op_share;
130
131 mso.u.share.source_handle = source_handle;
132 mso.u.share.source_gfn = source_gfn;
133 mso.u.share.client_domain = client_domain;
134 mso.u.share.client_gfn = client_gfn;
135 mso.u.share.client_handle = client_handle;
136
137 return xc_memshr_memop(xch, source_domain, &mso);
138 }
139
xc_memshr_share_grefs(xc_interface * xch,uint32_t source_domain,grant_ref_t source_gref,uint64_t source_handle,uint32_t client_domain,grant_ref_t client_gref,uint64_t client_handle)140 int xc_memshr_share_grefs(xc_interface *xch,
141 uint32_t source_domain,
142 grant_ref_t source_gref,
143 uint64_t source_handle,
144 uint32_t client_domain,
145 grant_ref_t client_gref,
146 uint64_t client_handle)
147 {
148 xen_mem_sharing_op_t mso;
149
150 memset(&mso, 0, sizeof(mso));
151
152 mso.op = XENMEM_sharing_op_share;
153
154 mso.u.share.source_handle = source_handle;
155 XENMEM_SHARING_OP_FIELD_MAKE_GREF(mso.u.share.source_gfn, source_gref);
156 mso.u.share.client_domain = client_domain;
157 XENMEM_SHARING_OP_FIELD_MAKE_GREF(mso.u.share.client_gfn, client_gref);
158 mso.u.share.client_handle = client_handle;
159
160 return xc_memshr_memop(xch, source_domain, &mso);
161 }
162
xc_memshr_add_to_physmap(xc_interface * xch,uint32_t source_domain,unsigned long source_gfn,uint64_t source_handle,uint32_t client_domain,unsigned long client_gfn)163 int xc_memshr_add_to_physmap(xc_interface *xch,
164 uint32_t source_domain,
165 unsigned long source_gfn,
166 uint64_t source_handle,
167 uint32_t client_domain,
168 unsigned long client_gfn)
169 {
170 xen_mem_sharing_op_t mso;
171
172 memset(&mso, 0, sizeof(mso));
173
174 mso.op = XENMEM_sharing_op_add_physmap;
175
176 mso.u.share.source_handle = source_handle;
177 mso.u.share.source_gfn = source_gfn;
178 mso.u.share.client_domain = client_domain;
179 mso.u.share.client_gfn = client_gfn;
180
181 return xc_memshr_memop(xch, source_domain, &mso);
182 }
183
xc_memshr_range_share(xc_interface * xch,uint32_t source_domain,uint32_t client_domain,uint64_t first_gfn,uint64_t last_gfn)184 int xc_memshr_range_share(xc_interface *xch,
185 uint32_t source_domain,
186 uint32_t client_domain,
187 uint64_t first_gfn,
188 uint64_t last_gfn)
189 {
190 xen_mem_sharing_op_t mso;
191
192 memset(&mso, 0, sizeof(mso));
193
194 mso.op = XENMEM_sharing_op_range_share;
195
196 mso.u.range.client_domain = client_domain;
197 mso.u.range.first_gfn = first_gfn;
198 mso.u.range.last_gfn = last_gfn;
199
200 return xc_memshr_memop(xch, source_domain, &mso);
201 }
202
xc_memshr_domain_resume(xc_interface * xch,uint32_t domid)203 int xc_memshr_domain_resume(xc_interface *xch,
204 uint32_t domid)
205 {
206 return xc_vm_event_control(xch, domid,
207 XEN_VM_EVENT_RESUME,
208 XEN_DOMCTL_VM_EVENT_OP_SHARING,
209 NULL);
210 }
211
xc_memshr_debug_gfn(xc_interface * xch,uint32_t domid,unsigned long gfn)212 int xc_memshr_debug_gfn(xc_interface *xch,
213 uint32_t domid,
214 unsigned long gfn)
215 {
216 xen_mem_sharing_op_t mso;
217
218 memset(&mso, 0, sizeof(mso));
219
220 mso.op = XENMEM_sharing_op_debug_gfn;
221 mso.u.debug.u.gfn = gfn;
222
223 return xc_memshr_memop(xch, domid, &mso);
224 }
225
xc_memshr_debug_gref(xc_interface * xch,uint32_t domid,grant_ref_t gref)226 int xc_memshr_debug_gref(xc_interface *xch,
227 uint32_t domid,
228 grant_ref_t gref)
229 {
230 xen_mem_sharing_op_t mso;
231
232 memset(&mso, 0, sizeof(mso));
233
234 mso.op = XENMEM_sharing_op_debug_gref;
235 mso.u.debug.u.gref = gref;
236
237 return xc_memshr_memop(xch, domid, &mso);
238 }
239
xc_memshr_audit(xc_interface * xch)240 int xc_memshr_audit(xc_interface *xch)
241 {
242 xen_mem_sharing_op_t mso;
243
244 memset(&mso, 0, sizeof(mso));
245
246 mso.op = XENMEM_sharing_op_audit;
247
248 return do_memory_op(xch, XENMEM_sharing_op, &mso, sizeof(mso));
249 }
250
xc_sharing_freed_pages(xc_interface * xch)251 long xc_sharing_freed_pages(xc_interface *xch)
252 {
253 return do_memory_op(xch, XENMEM_get_sharing_freed_pages, NULL, 0);
254 }
255
xc_sharing_used_frames(xc_interface * xch)256 long xc_sharing_used_frames(xc_interface *xch)
257 {
258 return do_memory_op(xch, XENMEM_get_sharing_shared_pages, NULL, 0);
259 }
260
261