ia64/xen-unstable

view xen/common/sysctl.c @ 19835:edfdeb150f27

Fix buildsystem to detect udev > version 124

udev removed the udevinfo symlink from versions higher than 123 and
xen's build-system could not detect if udev is in place and has the
required version.

Signed-off-by: Marc-A. Dahlhaus <mad@wol.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 25 13:02:37 2009 +0100 (2009-06-25)
parents 5966b71195b4
children
line source
1 /******************************************************************************
2 * sysctl.c
3 *
4 * System management operations. For use by node control stack.
5 *
6 * Copyright (c) 2002-2006, K Fraser
7 */
9 #include <xen/config.h>
10 #include <xen/types.h>
11 #include <xen/lib.h>
12 #include <xen/mm.h>
13 #include <xen/sched.h>
14 #include <xen/domain.h>
15 #include <xen/event.h>
16 #include <xen/domain_page.h>
17 #include <xen/trace.h>
18 #include <xen/console.h>
19 #include <xen/iocap.h>
20 #include <xen/guest_access.h>
21 #include <xen/keyhandler.h>
22 #include <asm/current.h>
23 #include <public/sysctl.h>
24 #include <asm/numa.h>
25 #include <xen/nodemask.h>
26 #include <xsm/xsm.h>
28 extern int do_get_pm_info(struct xen_sysctl_get_pmstat *op);
29 extern int do_pm_op(struct xen_sysctl_pm_op *op);
31 extern long arch_do_sysctl(
32 struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
34 long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
35 {
36 long ret = 0;
37 struct xen_sysctl curop, *op = &curop;
38 static DEFINE_SPINLOCK(sysctl_lock);
40 if ( !IS_PRIV(current->domain) )
41 return -EPERM;
43 if ( copy_from_guest(op, u_sysctl, 1) )
44 return -EFAULT;
46 if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
47 return -EACCES;
49 spin_lock(&sysctl_lock);
51 switch ( op->cmd )
52 {
53 case XEN_SYSCTL_readconsole:
54 {
55 ret = xsm_readconsole(op->u.readconsole.clear);
56 if ( ret )
57 break;
59 ret = read_console_ring(&op->u.readconsole);
60 if ( copy_to_guest(u_sysctl, op, 1) )
61 ret = -EFAULT;
62 }
63 break;
65 case XEN_SYSCTL_tbuf_op:
66 {
67 ret = xsm_tbufcontrol();
68 if ( ret )
69 break;
71 ret = tb_control(&op->u.tbuf_op);
72 if ( copy_to_guest(u_sysctl, op, 1) )
73 ret = -EFAULT;
74 }
75 break;
77 case XEN_SYSCTL_sched_id:
78 {
79 ret = xsm_sched_id();
80 if ( ret )
81 break;
83 op->u.sched_id.sched_id = sched_id();
84 if ( copy_to_guest(u_sysctl, op, 1) )
85 ret = -EFAULT;
86 else
87 ret = 0;
88 }
89 break;
91 case XEN_SYSCTL_getdomaininfolist:
92 {
93 struct domain *d;
94 struct xen_domctl_getdomaininfo info;
95 u32 num_domains = 0;
97 rcu_read_lock(&domlist_read_lock);
99 for_each_domain ( d )
100 {
101 if ( d->domain_id < op->u.getdomaininfolist.first_domain )
102 continue;
103 if ( num_domains == op->u.getdomaininfolist.max_domains )
104 break;
106 ret = xsm_getdomaininfo(d);
107 if ( ret )
108 continue;
110 getdomaininfo(d, &info);
112 if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
113 num_domains, &info, 1) )
114 {
115 ret = -EFAULT;
116 break;
117 }
119 num_domains++;
120 }
122 rcu_read_unlock(&domlist_read_lock);
124 if ( ret != 0 )
125 break;
127 op->u.getdomaininfolist.num_domains = num_domains;
129 if ( copy_to_guest(u_sysctl, op, 1) )
130 ret = -EFAULT;
131 }
132 break;
134 #ifdef PERF_COUNTERS
135 case XEN_SYSCTL_perfc_op:
136 {
137 ret = xsm_perfcontrol();
138 if ( ret )
139 break;
141 ret = perfc_control(&op->u.perfc_op);
142 if ( copy_to_guest(u_sysctl, op, 1) )
143 ret = -EFAULT;
144 }
145 break;
146 #endif
148 case XEN_SYSCTL_debug_keys:
149 {
150 char c;
151 uint32_t i;
153 ret = xsm_debug_keys();
154 if ( ret )
155 break;
157 for ( i = 0; i < op->u.debug_keys.nr_keys; i++ )
158 {
159 if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) )
160 return -EFAULT;
161 handle_keypress(c, guest_cpu_user_regs());
162 }
163 }
164 break;
166 case XEN_SYSCTL_getcpuinfo:
167 {
168 uint32_t i, nr_cpus;
169 struct xen_sysctl_cpuinfo cpuinfo;
171 nr_cpus = min_t(uint32_t, op->u.getcpuinfo.max_cpus, NR_CPUS);
173 ret = xsm_getcpuinfo();
174 if ( ret )
175 break;
177 for ( i = 0; i < nr_cpus; i++ )
178 {
179 cpuinfo.idletime = get_cpu_idle_time(i);
181 ret = -EFAULT;
182 if ( copy_to_guest_offset(op->u.getcpuinfo.info, i, &cpuinfo, 1) )
183 goto out;
184 }
186 op->u.getcpuinfo.nr_cpus = i;
187 ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
188 }
189 break;
191 case XEN_SYSCTL_availheap:
192 {
193 ret = xsm_availheap();
194 if ( ret )
195 break;
197 op->u.availheap.avail_bytes = avail_domheap_pages_region(
198 op->u.availheap.node,
199 op->u.availheap.min_bitwidth,
200 op->u.availheap.max_bitwidth);
201 op->u.availheap.avail_bytes <<= PAGE_SHIFT;
203 ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
204 }
205 break;
207 case XEN_SYSCTL_get_pmstat:
208 {
209 ret = xsm_get_pmstat();
210 if ( ret )
211 break;
213 ret = do_get_pm_info(&op->u.get_pmstat);
214 if ( ret )
215 break;
217 if ( copy_to_guest(u_sysctl, op, 1) )
218 {
219 ret = -EFAULT;
220 break;
221 }
222 }
223 break;
225 case XEN_SYSCTL_pm_op:
226 {
227 ret = xsm_pm_op();
228 if ( ret )
229 break;
231 ret = do_pm_op(&op->u.pm_op);
232 if ( ret && (ret != -EAGAIN) )
233 break;
235 if ( copy_to_guest(u_sysctl, op, 1) )
236 {
237 ret = -EFAULT;
238 break;
239 }
240 }
241 break;
243 case XEN_SYSCTL_page_offline_op:
244 {
245 uint32_t *status, *ptr;
246 unsigned long pfn;
248 ptr = status = xmalloc_bytes( sizeof(uint32_t) *
249 (op->u.page_offline.end -
250 op->u.page_offline.start + 1));
251 if ( !status )
252 {
253 dprintk(XENLOG_WARNING, "Out of memory for page offline op\n");
254 ret = -ENOMEM;
255 break;
256 }
258 memset(status, PG_OFFLINE_INVALID, sizeof(uint32_t) *
259 (op->u.page_offline.end - op->u.page_offline.start + 1));
261 for ( pfn = op->u.page_offline.start;
262 pfn <= op->u.page_offline.end;
263 pfn ++ )
264 {
265 switch ( op->u.page_offline.cmd )
266 {
267 /* Shall revert her if failed, or leave caller do it? */
268 case sysctl_page_offline:
269 ret = offline_page(pfn, 0, ptr++);
270 break;
271 case sysctl_page_online:
272 ret = online_page(pfn, ptr++);
273 break;
274 case sysctl_query_page_offline:
275 ret = query_page_offline(pfn, ptr++);
276 break;
277 default:
278 gdprintk(XENLOG_WARNING, "invalid page offline op %x\n",
279 op->u.page_offline.cmd);
280 ret = -EINVAL;
281 break;
282 }
284 if (ret)
285 break;
286 }
288 if ( copy_to_guest(
289 op->u.page_offline.status, status,
290 op->u.page_offline.end - op->u.page_offline.start + 1) )
291 {
292 ret = -EFAULT;
293 break;
294 }
296 xfree(status);
297 }
298 break;
300 default:
301 ret = arch_do_sysctl(op, u_sysctl);
302 break;
303 }
305 out:
306 spin_unlock(&sysctl_lock);
308 return ret;
309 }
311 /*
312 * Local variables:
313 * mode: C
314 * c-set-style: "BSD"
315 * c-basic-offset: 4
316 * tab-width: 4
317 * indent-tabs-mode: nil
318 * End:
319 */