ia64/xen-unstable

view xen/common/sysctl.c @ 12390:e28beea6d228

[IA64] Fix time services of EFI emulation

This patch serializes the execution of following efi.runtimes.
- GetTime
- SetTime
- GetWakeTime
- SetWakeTime

Linux/ia64 uses similar spinlocks in the EFI RTC driver.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Fri Nov 10 12:03:19 2006 -0700 (2006-11-10)
parents 7210b62802be
children d80684d19ef4
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 <asm/current.h>
22 #include <public/sysctl.h>
24 extern long arch_do_sysctl(
25 struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
26 extern void getdomaininfo(
27 struct domain *d, struct xen_domctl_getdomaininfo *info);
29 long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
30 {
31 long ret = 0;
32 struct xen_sysctl curop, *op = &curop;
33 static DEFINE_SPINLOCK(sysctl_lock);
35 if ( !IS_PRIV(current->domain) )
36 return -EPERM;
38 if ( copy_from_guest(op, u_sysctl, 1) )
39 return -EFAULT;
41 if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
42 return -EACCES;
44 spin_lock(&sysctl_lock);
46 switch ( op->cmd )
47 {
48 case XEN_SYSCTL_readconsole:
49 {
50 ret = read_console_ring(
51 guest_handle_cast(op->u.readconsole.buffer, char),
52 &op->u.readconsole.count,
53 op->u.readconsole.clear);
54 if ( copy_to_guest(u_sysctl, op, 1) )
55 ret = -EFAULT;
56 }
57 break;
59 case XEN_SYSCTL_tbuf_op:
60 {
61 ret = tb_control(&op->u.tbuf_op);
62 if ( copy_to_guest(u_sysctl, op, 1) )
63 ret = -EFAULT;
64 }
65 break;
67 case XEN_SYSCTL_sched_id:
68 {
69 op->u.sched_id.sched_id = sched_id();
70 if ( copy_to_guest(u_sysctl, op, 1) )
71 ret = -EFAULT;
72 else
73 ret = 0;
74 }
75 break;
77 case XEN_SYSCTL_getdomaininfolist:
78 {
79 struct domain *d;
80 struct xen_domctl_getdomaininfo info;
81 u32 num_domains = 0;
83 read_lock(&domlist_lock);
85 for_each_domain ( d )
86 {
87 if ( d->domain_id < op->u.getdomaininfolist.first_domain )
88 continue;
89 if ( num_domains == op->u.getdomaininfolist.max_domains )
90 break;
91 if ( (d == NULL) || !get_domain(d) )
92 {
93 ret = -ESRCH;
94 break;
95 }
97 getdomaininfo(d, &info);
99 put_domain(d);
101 if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
102 num_domains, &info, 1) )
103 {
104 ret = -EFAULT;
105 break;
106 }
108 num_domains++;
109 }
111 read_unlock(&domlist_lock);
113 if ( ret != 0 )
114 break;
116 op->u.getdomaininfolist.num_domains = num_domains;
118 if ( copy_to_guest(u_sysctl, op, 1) )
119 ret = -EFAULT;
120 }
121 break;
123 #ifdef PERF_COUNTERS
124 case XEN_SYSCTL_perfc_op:
125 {
126 extern int perfc_control(xen_sysctl_perfc_op_t *);
127 ret = perfc_control(&op->u.perfc_op);
128 if ( copy_to_guest(u_sysctl, op, 1) )
129 ret = -EFAULT;
130 }
131 break;
132 #endif
134 default:
135 ret = arch_do_sysctl(op, u_sysctl);
136 break;
137 }
139 spin_unlock(&sysctl_lock);
141 return ret;
142 }
144 /*
145 * Local variables:
146 * mode: C
147 * c-set-style: "BSD"
148 * c-basic-offset: 4
149 * tab-width: 4
150 * indent-tabs-mode: nil
151 * End:
152 */