ia64/xen-unstable

view xen/common/sysctl.c @ 18594:5e4e234d58be

x86: Define __per_cpu_shift label to help kdump/crashdump.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Oct 08 13:11:06 2008 +0100 (2008-10-08)
parents 44f039c4aee4
children 605ef79ee46c
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);
30 extern long arch_do_sysctl(
31 struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
33 long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
34 {
35 long ret = 0;
36 struct xen_sysctl curop, *op = &curop;
37 static DEFINE_SPINLOCK(sysctl_lock);
39 if ( !IS_PRIV(current->domain) )
40 return -EPERM;
42 if ( copy_from_guest(op, u_sysctl, 1) )
43 return -EFAULT;
45 if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
46 return -EACCES;
48 spin_lock(&sysctl_lock);
50 switch ( op->cmd )
51 {
52 case XEN_SYSCTL_readconsole:
53 {
54 ret = xsm_readconsole(op->u.readconsole.clear);
55 if ( ret )
56 break;
58 ret = read_console_ring(&op->u.readconsole);
59 if ( copy_to_guest(u_sysctl, op, 1) )
60 ret = -EFAULT;
61 }
62 break;
64 case XEN_SYSCTL_tbuf_op:
65 {
66 ret = xsm_tbufcontrol();
67 if ( ret )
68 break;
70 ret = tb_control(&op->u.tbuf_op);
71 if ( copy_to_guest(u_sysctl, op, 1) )
72 ret = -EFAULT;
73 }
74 break;
76 case XEN_SYSCTL_sched_id:
77 {
78 ret = xsm_sched_id();
79 if ( ret )
80 break;
82 op->u.sched_id.sched_id = sched_id();
83 if ( copy_to_guest(u_sysctl, op, 1) )
84 ret = -EFAULT;
85 else
86 ret = 0;
87 }
88 break;
90 case XEN_SYSCTL_getdomaininfolist:
91 {
92 struct domain *d;
93 struct xen_domctl_getdomaininfo info;
94 u32 num_domains = 0;
96 rcu_read_lock(&domlist_read_lock);
98 for_each_domain ( d )
99 {
100 if ( d->domain_id < op->u.getdomaininfolist.first_domain )
101 continue;
102 if ( num_domains == op->u.getdomaininfolist.max_domains )
103 break;
105 ret = xsm_getdomaininfo(d);
106 if ( ret )
107 continue;
109 getdomaininfo(d, &info);
111 if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
112 num_domains, &info, 1) )
113 {
114 ret = -EFAULT;
115 break;
116 }
118 num_domains++;
119 }
121 rcu_read_unlock(&domlist_read_lock);
123 if ( ret != 0 )
124 break;
126 op->u.getdomaininfolist.num_domains = num_domains;
128 if ( copy_to_guest(u_sysctl, op, 1) )
129 ret = -EFAULT;
130 }
131 break;
133 #ifdef PERF_COUNTERS
134 case XEN_SYSCTL_perfc_op:
135 {
136 ret = xsm_perfcontrol();
137 if ( ret )
138 break;
140 ret = perfc_control(&op->u.perfc_op);
141 if ( copy_to_guest(u_sysctl, op, 1) )
142 ret = -EFAULT;
143 }
144 break;
145 #endif
147 case XEN_SYSCTL_debug_keys:
148 {
149 char c;
150 uint32_t i;
152 ret = xsm_debug_keys();
153 if ( ret )
154 break;
156 for ( i = 0; i < op->u.debug_keys.nr_keys; i++ )
157 {
158 if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) )
159 return -EFAULT;
160 handle_keypress(c, guest_cpu_user_regs());
161 }
162 }
163 break;
165 case XEN_SYSCTL_getcpuinfo:
166 {
167 uint32_t i, nr_cpus;
168 struct xen_sysctl_cpuinfo cpuinfo;
169 struct vcpu *v;
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 /* Assume no holes in idle-vcpu map. */
180 if ( (v = idle_vcpu[i]) == NULL )
181 break;
183 cpuinfo.idletime = v->runstate.time[RUNSTATE_running];
184 if ( v->is_running )
185 cpuinfo.idletime += NOW() - v->runstate.state_entry_time;
187 ret = -EFAULT;
188 if ( copy_to_guest_offset(op->u.getcpuinfo.info, i, &cpuinfo, 1) )
189 goto out;
190 }
192 op->u.getcpuinfo.nr_cpus = i;
193 ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
194 }
195 break;
197 case XEN_SYSCTL_availheap:
198 {
199 ret = xsm_availheap();
200 if ( ret )
201 break;
203 op->u.availheap.avail_bytes = avail_domheap_pages_region(
204 op->u.availheap.node,
205 op->u.availheap.min_bitwidth,
206 op->u.availheap.max_bitwidth);
207 op->u.availheap.avail_bytes <<= PAGE_SHIFT;
209 ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
210 }
211 break;
213 case XEN_SYSCTL_get_pmstat:
214 {
215 ret = do_get_pm_info(&op->u.get_pmstat);
216 if ( ret )
217 break;
219 if ( copy_to_guest(u_sysctl, op, 1) )
220 {
221 ret = -EFAULT;
222 break;
223 }
224 }
225 break;
227 default:
228 ret = arch_do_sysctl(op, u_sysctl);
229 break;
230 }
232 out:
233 spin_unlock(&sysctl_lock);
235 return ret;
236 }
238 /*
239 * Local variables:
240 * mode: C
241 * c-set-style: "BSD"
242 * c-basic-offset: 4
243 * tab-width: 4
244 * indent-tabs-mode: nil
245 * End:
246 */