ia64/xen-unstable

view xen/common/sysctl.c @ 15717:c229802cedbb

[32on64] Copy the right grant table status code back to the guest.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Mon Aug 06 13:19:44 2007 +0100 (2007-08-06)
parents 29761c9b9105
children 96f64f4c42f0
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>
27 extern long arch_do_sysctl(
28 struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
30 long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
31 {
32 long ret = 0;
33 struct xen_sysctl curop, *op = &curop;
34 static DEFINE_SPINLOCK(sysctl_lock);
36 if ( !IS_PRIV(current->domain) )
37 return -EPERM;
39 if ( copy_from_guest(op, u_sysctl, 1) )
40 return -EFAULT;
42 if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
43 return -EACCES;
45 spin_lock(&sysctl_lock);
47 switch ( op->cmd )
48 {
49 case XEN_SYSCTL_readconsole:
50 {
51 ret = read_console_ring(
52 guest_handle_cast(op->u.readconsole.buffer, char),
53 &op->u.readconsole.count,
54 op->u.readconsole.clear);
55 if ( copy_to_guest(u_sysctl, op, 1) )
56 ret = -EFAULT;
57 }
58 break;
60 case XEN_SYSCTL_tbuf_op:
61 {
62 ret = tb_control(&op->u.tbuf_op);
63 if ( copy_to_guest(u_sysctl, op, 1) )
64 ret = -EFAULT;
65 }
66 break;
68 case XEN_SYSCTL_sched_id:
69 {
70 op->u.sched_id.sched_id = sched_id();
71 if ( copy_to_guest(u_sysctl, op, 1) )
72 ret = -EFAULT;
73 else
74 ret = 0;
75 }
76 break;
78 case XEN_SYSCTL_getdomaininfolist:
79 {
80 struct domain *d;
81 struct xen_domctl_getdomaininfo info;
82 u32 num_domains = 0;
84 rcu_read_lock(&domlist_read_lock);
86 for_each_domain ( d )
87 {
88 if ( d->domain_id < op->u.getdomaininfolist.first_domain )
89 continue;
90 if ( num_domains == op->u.getdomaininfolist.max_domains )
91 break;
93 getdomaininfo(d, &info);
95 if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
96 num_domains, &info, 1) )
97 {
98 ret = -EFAULT;
99 break;
100 }
102 num_domains++;
103 }
105 rcu_read_unlock(&domlist_read_lock);
107 if ( ret != 0 )
108 break;
110 op->u.getdomaininfolist.num_domains = num_domains;
112 if ( copy_to_guest(u_sysctl, op, 1) )
113 ret = -EFAULT;
114 }
115 break;
117 #ifdef PERF_COUNTERS
118 case XEN_SYSCTL_perfc_op:
119 {
120 ret = perfc_control(&op->u.perfc_op);
121 if ( copy_to_guest(u_sysctl, op, 1) )
122 ret = -EFAULT;
123 }
124 break;
125 #endif
127 case XEN_SYSCTL_debug_keys:
128 {
129 char c;
130 uint32_t i;
132 for ( i = 0; i < op->u.debug_keys.nr_keys; i++ )
133 {
134 if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) )
135 return -EFAULT;
136 handle_keypress(c, guest_cpu_user_regs());
137 }
138 }
139 break;
141 case XEN_SYSCTL_getcpuinfo:
142 {
143 uint32_t i, nr_cpus;
144 struct xen_sysctl_cpuinfo cpuinfo;
145 struct vcpu *v;
147 nr_cpus = min_t(uint32_t, op->u.getcpuinfo.max_cpus, NR_CPUS);
149 for ( i = 0; i < nr_cpus; i++ )
150 {
151 /* Assume no holes in idle-vcpu map. */
152 if ( (v = idle_vcpu[i]) == NULL )
153 break;
155 cpuinfo.idletime = v->runstate.time[RUNSTATE_running];
156 if ( v->is_running )
157 cpuinfo.idletime += NOW() - v->runstate.state_entry_time;
159 if ( copy_to_guest_offset(op->u.getcpuinfo.info, i, &cpuinfo, 1) )
160 {
161 ret = -EFAULT;
162 break;
163 }
164 }
166 op->u.getcpuinfo.nr_cpus = i;
167 ret = 0;
169 if ( copy_to_guest(u_sysctl, op, 1) )
170 ret = -EFAULT;
171 }
172 break;
174 case XEN_SYSCTL_availheap:
175 {
176 op->u.availheap.avail_bytes = avail_domheap_pages_region(
177 op->u.availheap.node,
178 op->u.availheap.min_bitwidth,
179 op->u.availheap.max_bitwidth);
180 op->u.availheap.avail_bytes <<= PAGE_SHIFT;
182 ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
183 }
184 break;
186 default:
187 ret = arch_do_sysctl(op, u_sysctl);
188 break;
189 }
191 spin_unlock(&sysctl_lock);
193 return ret;
194 }
196 /*
197 * Local variables:
198 * mode: C
199 * c-set-style: "BSD"
200 * c-basic-offset: 4
201 * tab-width: 4
202 * indent-tabs-mode: nil
203 * End:
204 */