ia64/xen-unstable

view tools/xenstat/libxenstat/src/xen-interface.c @ 8820:605672867c0f

Check the hypercall number in the privcmd hypercall ioctl.
We check it is a member of a small set of permitted hypercalls.
Fix libxenstat to not use multicalls (not permitted, and not
need for efficiency in libxenstat).

Based on an original patch by Chris Wright.

Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
author kaf24@firebug.cl.cam.ac.uk
date Fri Feb 10 00:16:53 2006 +0100 (2006-02-10)
parents 37050ba0e35c
children d4e433d615b0
line source
1 /* xen-interface.c
2 *
3 * Copyright (C) International Business Machines Corp., 2005
4 * Authors: Josh Triplett <josht@us.ibm.com>
5 * Judy Fischbach <jfisch@us.ibm.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 */
18 #include "xen-interface.h"
19 #include <fcntl.h>
20 #include <sys/ioctl.h>
21 #include <sys/mman.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <xen/linux/privcmd.h>
28 struct xi_handle {
29 int fd;
30 };
32 /* Initialize for xen-interface. Returns a handle to be used with subsequent
33 * calls to the xen-interface functions or NULL if an error occurs. */
34 xi_handle *xi_init()
35 {
36 xi_handle *handle;
38 handle = (xi_handle *)calloc(1, sizeof(xi_handle));
39 if (handle == NULL)
40 return NULL;
42 handle->fd = open("/proc/xen/privcmd", O_RDWR);
43 if (handle->fd < 0) {
44 perror("Couldn't open /proc/xen/privcmd");
45 free(handle);
46 return NULL;
47 }
49 return handle;
50 }
52 /* Release the handle to libxc, free resources, etc. */
53 void xi_uninit(xi_handle *handle)
54 {
55 close (handle->fd);
56 free (handle);
57 }
59 /* Make simple xen version hypervisor calls */
60 static int xi_make_xen_version_hypercall(xi_handle *handle, long *vnum,
61 xen_extraversion_t *ver)
62 {
63 privcmd_hypercall_t privcmd;
64 int ret = 0;
66 if (mlock(&privcmd, sizeof(privcmd)) < 0) {
67 perror("Failed to mlock privcmd structure");
68 return -1;
69 }
71 if (mlock(ver, sizeof(*ver)) < 0) {
72 perror("Failed to mlock extraversion structure");
73 munlock(&privcmd, sizeof(privcmd));
74 return -1;
75 }
77 privcmd.op = __HYPERVISOR_xen_version;
78 privcmd.arg[0] = (unsigned long)XENVER_version;
79 privcmd.arg[1] = 0;
81 *vnum = ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd);
82 if (*vnum < 0) {
83 perror("Hypercall failed");
84 ret = -1;
85 }
87 privcmd.op = __HYPERVISOR_xen_version;
88 privcmd.arg[0] = (unsigned long)XENVER_extraversion;
89 privcmd.arg[1] = (unsigned long)ver;
91 if (ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
92 perror("Hypercall failed");
93 ret = -1;
94 }
96 munlock(&privcmd, sizeof(privcmd));
97 munlock(ver, sizeof(*ver));
99 return ret;
100 }
102 /* Make Xen Dom0 op hypervisor call */
103 static int xi_make_dom0_op(xi_handle *handle, dom0_op_t *dom_op,
104 int dom_opcode)
105 {
106 privcmd_hypercall_t privcmd;
107 int ret = 0;
109 /* set up for doing hypercall */
110 privcmd.op = __HYPERVISOR_dom0_op;
111 privcmd.arg[0] = (unsigned long)dom_op;
112 dom_op->cmd = dom_opcode;
113 dom_op->interface_version = DOM0_INTERFACE_VERSION;
115 if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
116 perror("Failed to mlock privcmd structure");
117 return -1;
118 }
120 if (mlock( dom_op, sizeof(dom0_op_t)) < 0) {
121 perror("Failed to mlock dom0_op structure");
122 munlock( &privcmd, sizeof(privcmd_hypercall_t));
123 return -1;
124 }
126 if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
127 perror("Hypercall failed");
128 ret = -1;
129 }
131 munlock( &privcmd, sizeof(privcmd_hypercall_t));
132 munlock( dom_op, sizeof(dom0_op_t));
134 return ret;
135 }
137 /* Obtain domain data from dom0 */
138 int xi_get_physinfo(xi_handle *handle, dom0_physinfo_t *physinfo)
139 {
140 dom0_op_t op;
142 if (xi_make_dom0_op(handle, &op, DOM0_PHYSINFO) < 0) {
143 perror("DOM0_PHYSINFO Hypercall failed");
144 return -1;
145 }
147 *physinfo = op.u.physinfo;
148 return 0;
149 }
151 /* Obtain domain data from dom0 */
152 int xi_get_domaininfolist(xi_handle *handle, dom0_getdomaininfo_t *info,
153 unsigned int first_domain, unsigned int max_domains)
154 {
155 dom0_op_t op;
156 op.u.getdomaininfolist.first_domain = first_domain;
157 op.u.getdomaininfolist.max_domains = max_domains;
158 op.u.getdomaininfolist.buffer = info;
160 if (mlock( info, max_domains * sizeof(dom0_getdomaininfo_t)) < 0) {
161 perror("Failed to mlock domaininfo array");
162 return -1;
163 }
165 if (xi_make_dom0_op(handle, &op, DOM0_GETDOMAININFOLIST) < 0) {
166 perror("DOM0_GETDOMAININFOLIST Hypercall failed");
167 return -1;
168 }
170 return op.u.getdomaininfolist.num_domains;
171 }
173 /* Get vcpu info from a domain */
174 int xi_get_domain_vcpu_info(xi_handle *handle, unsigned int domain,
175 unsigned int vcpu, dom0_getvcpuinfo_t *info)
176 {
177 dom0_op_t op;
178 op.u.getvcpuinfo.domain = domain;
179 op.u.getvcpuinfo.vcpu = vcpu;
181 if (xi_make_dom0_op(handle, &op, DOM0_GETVCPUINFO) < 0) {
182 perror("DOM0_GETVCPUINFO Hypercall failed");
183 return -1;
184 }
186 memcpy(info, &op.u.getvcpuinfo, sizeof(dom0_getvcpuinfo_t));
188 return 0;
189 }
191 /* gets xen version information from hypervisor */
192 int xi_get_xen_version(xi_handle *handle, long *vnum, xen_extraversion_t *ver)
193 {
194 /* gets the XENVER_version and XENVER_extraversion */
195 if (xi_make_xen_version_hypercall( handle, vnum, ver) < 0) {
196 perror("XEN VERSION Hypercall failed");
197 return -1;
198 }
200 return 0;
201 }