ia64/xen-unstable

view tools/libxc/xc_misc.c @ 15854:9071521d4864

xc_map_foreign_pages(), a convenient alternative to xc_map_foreign_batch()

xc_map_foreign_batch() can succeed partially. It is awkward to use
when you're only interested in complete success. Provide new
xc_map_foreign_pages() convenience function for that kind of use.
Also convert two obvious calls to use it.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
author kfraser@localhost.localdomain
date Fri Sep 07 11:39:10 2007 +0100 (2007-09-07)
parents 89d2192942be
children 3bb94bb35dad
line source
1 /******************************************************************************
2 * xc_misc.c
3 *
4 * Miscellaneous control interface functions.
5 */
7 #include "xc_private.h"
8 #include <xen/hvm/hvm_op.h>
10 int xc_readconsolering(int xc_handle,
11 char **pbuffer,
12 unsigned int *pnr_chars,
13 int clear)
14 {
15 int ret;
16 DECLARE_SYSCTL;
17 char *buffer = *pbuffer;
18 unsigned int nr_chars = *pnr_chars;
20 sysctl.cmd = XEN_SYSCTL_readconsole;
21 set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer);
22 sysctl.u.readconsole.count = nr_chars;
23 sysctl.u.readconsole.clear = clear;
25 if ( (ret = lock_pages(buffer, nr_chars)) != 0 )
26 return ret;
28 if ( (ret = do_sysctl(xc_handle, &sysctl)) == 0 )
29 *pnr_chars = sysctl.u.readconsole.count;
31 unlock_pages(buffer, nr_chars);
33 return ret;
34 }
36 int xc_send_debug_keys(int xc_handle, char *keys)
37 {
38 int ret, len = strlen(keys);
39 DECLARE_SYSCTL;
41 sysctl.cmd = XEN_SYSCTL_debug_keys;
42 set_xen_guest_handle(sysctl.u.debug_keys.keys, keys);
43 sysctl.u.debug_keys.nr_keys = len;
45 if ( (ret = lock_pages(keys, len)) != 0 )
46 return ret;
48 ret = do_sysctl(xc_handle, &sysctl);
50 unlock_pages(keys, len);
52 return ret;
53 }
55 int xc_physinfo(int xc_handle,
56 xc_physinfo_t *put_info)
57 {
58 int ret;
59 DECLARE_SYSCTL;
61 sysctl.cmd = XEN_SYSCTL_physinfo;
63 memcpy(&sysctl.u.physinfo, put_info, sizeof(*put_info));
65 if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
66 return ret;
68 memcpy(put_info, &sysctl.u.physinfo, sizeof(*put_info));
70 return 0;
71 }
73 int xc_sched_id(int xc_handle,
74 int *sched_id)
75 {
76 int ret;
77 DECLARE_SYSCTL;
79 sysctl.cmd = XEN_SYSCTL_sched_id;
81 if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
82 return ret;
84 *sched_id = sysctl.u.sched_id.sched_id;
86 return 0;
87 }
89 int xc_perfc_control(int xc_handle,
90 uint32_t opcode,
91 xc_perfc_desc_t *desc,
92 xc_perfc_val_t *val,
93 int *nbr_desc,
94 int *nbr_val)
95 {
96 int rc;
97 DECLARE_SYSCTL;
99 sysctl.cmd = XEN_SYSCTL_perfc_op;
100 sysctl.u.perfc_op.cmd = opcode;
101 set_xen_guest_handle(sysctl.u.perfc_op.desc, desc);
102 set_xen_guest_handle(sysctl.u.perfc_op.val, val);
104 rc = do_sysctl(xc_handle, &sysctl);
106 if ( nbr_desc )
107 *nbr_desc = sysctl.u.perfc_op.nr_counters;
108 if ( nbr_val )
109 *nbr_val = sysctl.u.perfc_op.nr_vals;
111 return rc;
112 }
114 int xc_getcpuinfo(int xc_handle, int max_cpus,
115 xc_cpuinfo_t *info, int *nr_cpus)
116 {
117 int rc;
118 DECLARE_SYSCTL;
120 sysctl.cmd = XEN_SYSCTL_getcpuinfo;
121 sysctl.u.getcpuinfo.max_cpus = max_cpus;
122 set_xen_guest_handle(sysctl.u.getcpuinfo.info, info);
124 if ( (rc = lock_pages(info, max_cpus*sizeof(*info))) != 0 )
125 return rc;
127 rc = do_sysctl(xc_handle, &sysctl);
129 unlock_pages(info, max_cpus*sizeof(*info));
131 if ( nr_cpus )
132 *nr_cpus = sysctl.u.getcpuinfo.nr_cpus;
134 return rc;
135 }
138 int xc_hvm_set_pci_intx_level(
139 int xc_handle, domid_t dom,
140 uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
141 unsigned int level)
142 {
143 DECLARE_HYPERCALL;
144 struct xen_hvm_set_pci_intx_level arg;
145 int rc;
147 hypercall.op = __HYPERVISOR_hvm_op;
148 hypercall.arg[0] = HVMOP_set_pci_intx_level;
149 hypercall.arg[1] = (unsigned long)&arg;
151 arg.domid = dom;
152 arg.domain = domain;
153 arg.bus = bus;
154 arg.device = device;
155 arg.intx = intx;
156 arg.level = level;
158 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
159 {
160 PERROR("Could not lock memory");
161 return rc;
162 }
164 rc = do_xen_hypercall(xc_handle, &hypercall);
166 unlock_pages(&arg, sizeof(arg));
168 return rc;
169 }
171 int xc_hvm_set_isa_irq_level(
172 int xc_handle, domid_t dom,
173 uint8_t isa_irq,
174 unsigned int level)
175 {
176 DECLARE_HYPERCALL;
177 struct xen_hvm_set_isa_irq_level arg;
178 int rc;
180 hypercall.op = __HYPERVISOR_hvm_op;
181 hypercall.arg[0] = HVMOP_set_isa_irq_level;
182 hypercall.arg[1] = (unsigned long)&arg;
184 arg.domid = dom;
185 arg.isa_irq = isa_irq;
186 arg.level = level;
188 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
189 {
190 PERROR("Could not lock memory");
191 return rc;
192 }
194 rc = do_xen_hypercall(xc_handle, &hypercall);
196 unlock_pages(&arg, sizeof(arg));
198 return rc;
199 }
201 int xc_hvm_set_pci_link_route(
202 int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq)
203 {
204 DECLARE_HYPERCALL;
205 struct xen_hvm_set_pci_link_route arg;
206 int rc;
208 hypercall.op = __HYPERVISOR_hvm_op;
209 hypercall.arg[0] = HVMOP_set_pci_link_route;
210 hypercall.arg[1] = (unsigned long)&arg;
212 arg.domid = dom;
213 arg.link = link;
214 arg.isa_irq = isa_irq;
216 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
217 {
218 PERROR("Could not lock memory");
219 return rc;
220 }
222 rc = do_xen_hypercall(xc_handle, &hypercall);
224 unlock_pages(&arg, sizeof(arg));
226 return rc;
227 }
229 void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
230 const xen_pfn_t *arr, int num)
231 {
232 xen_pfn_t *pfn;
233 void *res;
234 int i;
236 pfn = malloc(num * sizeof(*pfn));
237 if (!pfn)
238 return NULL;
239 memcpy(pfn, arr, num * sizeof(*pfn));
241 res = xc_map_foreign_batch(xc_handle, dom, prot, pfn, num);
242 if (res) {
243 for (i = 0; i < num; i++) {
244 if ((pfn[i] & 0xF0000000UL) == 0xF0000000UL) {
245 /*
246 * xc_map_foreign_batch() doesn't give us an error
247 * code, so we have to make one up. May not be the
248 * appropriate one.
249 */
250 errno = EINVAL;
251 munmap(res, num * PAGE_SIZE);
252 res = NULL;
253 break;
254 }
255 }
256 }
258 free(pfn);
259 return res;
260 }
262 /*
263 * Local variables:
264 * mode: C
265 * c-set-style: "BSD"
266 * c-basic-offset: 4
267 * tab-width: 4
268 * indent-tabs-mode: nil
269 * End:
270 */