ia64/xen-unstable

view xen/common/sysctl.c @ 15896:42d4313b5fdd

[IA64] update .hgignore for xenitp

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author Alex Williamson <alex.williamson@hp.com>
date Mon Sep 24 14:21:02 2007 -0600 (2007-09-24)
parents 96f64f4c42f0
children 8c67b2038ff2
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 long arch_do_sysctl(
29 struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
31 long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
32 {
33 long ret = 0;
34 struct xen_sysctl curop, *op = &curop;
35 static DEFINE_SPINLOCK(sysctl_lock);
37 if ( !IS_PRIV(current->domain) )
38 return -EPERM;
40 if ( copy_from_guest(op, u_sysctl, 1) )
41 return -EFAULT;
43 if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
44 return -EACCES;
46 spin_lock(&sysctl_lock);
48 switch ( op->cmd )
49 {
50 case XEN_SYSCTL_readconsole:
51 {
52 ret = xsm_readconsole(op->u.readconsole.clear);
53 if ( ret )
54 break;
56 ret = read_console_ring(
57 guest_handle_cast(op->u.readconsole.buffer, char),
58 &op->u.readconsole.count,
59 op->u.readconsole.clear);
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 for ( i = 0; i < op->u.debug_keys.nr_keys; i++ )
154 {
155 if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) )
156 return -EFAULT;
157 handle_keypress(c, guest_cpu_user_regs());
158 }
159 }
160 break;
162 case XEN_SYSCTL_getcpuinfo:
163 {
164 uint32_t i, nr_cpus;
165 struct xen_sysctl_cpuinfo cpuinfo;
166 struct vcpu *v;
168 nr_cpus = min_t(uint32_t, op->u.getcpuinfo.max_cpus, NR_CPUS);
170 for ( i = 0; i < nr_cpus; i++ )
171 {
172 /* Assume no holes in idle-vcpu map. */
173 if ( (v = idle_vcpu[i]) == NULL )
174 break;
176 cpuinfo.idletime = v->runstate.time[RUNSTATE_running];
177 if ( v->is_running )
178 cpuinfo.idletime += NOW() - v->runstate.state_entry_time;
180 if ( copy_to_guest_offset(op->u.getcpuinfo.info, i, &cpuinfo, 1) )
181 {
182 ret = -EFAULT;
183 break;
184 }
185 }
187 op->u.getcpuinfo.nr_cpus = i;
188 ret = 0;
190 if ( copy_to_guest(u_sysctl, op, 1) )
191 ret = -EFAULT;
192 }
193 break;
195 case XEN_SYSCTL_availheap:
196 {
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 default:
208 ret = arch_do_sysctl(op, u_sysctl);
209 break;
210 }
212 spin_unlock(&sysctl_lock);
214 return ret;
215 }
217 /*
218 * Local variables:
219 * mode: C
220 * c-set-style: "BSD"
221 * c-basic-offset: 4
222 * tab-width: 4
223 * indent-tabs-mode: nil
224 * End:
225 */