4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/param.h>
29 #include <sys/thread.h>
30 #include <sys/cpuvar.h>
31 #include <sys/kstat.h>
32 #include <sys/uadmin.h>
33 #include <sys/systm.h>
34 #include <sys/errno.h>
35 #include <sys/cmn_err.h>
36 #include <sys/procset.h>
37 #include <sys/processor.h>
38 #include <sys/debug.h>
39 #include <sys/policy.h>
45 * P_POWEROFF <---> P_OFFLINE <---> P_ONLINE <---> P_NOINTR
49 p_online_internal_locked(processorid_t cpun
, int new_status
, int *old_status
)
57 * Try to get a pointer to the requested CPU structure.
59 ASSERT(MUTEX_HELD(&cpu_lock
));
60 if ((cp
= cpu_get(cpun
)) == NULL
) {
65 if (new_status
& P_FORCED
)
67 *old_status
= status
= cpu_get_state(cp
); /* get processor status */
68 new_status
&= ~P_FORCED
;
71 * Perform credentials check.
81 if (secpolicy_ponline(CRED()) != 0)
92 * return 0 if the CPU is already in the desired new state.
94 if (status
== new_status
)
102 * If CPU is powered off, power it on.
104 if (error
= cpu_poweron(cp
))
106 ASSERT(cpu_get_state(cp
) == P_OFFLINE
);
112 * If CPU is in one of the offline states,
115 error
= cpu_online(cp
);
127 * Before we take the CPU offline, we first enable I/O
136 * CPU is online, or in a special offline state.
139 error
= cpu_offline(cp
, flags
);
143 * If CPU is powered off, power it on.
145 error
= cpu_poweron(cp
);
153 * if CPU is powered off, power it on.
155 if (error
= cpu_poweron(cp
))
157 ASSERT(cpu_get_state(cp
) == P_OFFLINE
);
163 * First, bring the CPU online.
165 if (error
= cpu_online(cp
))
170 * CPU is now online. Try to disable interrupts.
172 error
= cpu_intr_disable(cp
);
180 * If CPU is powered off, power it on.
182 if (error
= cpu_poweron(cp
))
184 ASSERT(cpu_get_state(cp
) == P_OFFLINE
);
191 * Mark this CPU as faulted.
193 error
= cpu_faulted(cp
, flags
);
201 * If CPU is powered off, power it on.
203 if (error
= cpu_poweron(cp
))
205 ASSERT(cpu_get_state(cp
) == P_OFFLINE
);
212 * Mark this CPU as a spare.
214 error
= cpu_spare(cp
, flags
);
223 p_online_internal(processorid_t cpun
, int new_status
, int *old_status
)
227 mutex_enter(&cpu_lock
); /* protects CPU states */
228 rc
= p_online_internal_locked(cpun
, new_status
, old_status
);
229 mutex_exit(&cpu_lock
);
235 * p_online(2) - get/change processor operational status.
237 * As noted in os/cpu.c, the P_ONLINE and other state constants are for use
238 * only in this system call path and other paths conveying CPU state to
239 * userland. In general, other kernel consumers should be using the accessor
240 * functions in kernel/os/cpu.c.
243 p_online(processorid_t cpun
, int new_status
)
248 ret
= p_online_internal(cpun
, new_status
, &old_status
);
250 return (set_errno(ret
));