xref: /titanic_44/usr/src/uts/common/cpr/cpr_main.c (revision 4eaa471005973e11a6110b69fe990530b3b95a38)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * This module contains the guts of checkpoint-resume mechanism.
30  * All code in this module is platform independent.
31  */
32 
33 #include <sys/types.h>
34 #include <sys/errno.h>
35 #include <sys/callb.h>
36 #include <sys/processor.h>
37 #include <sys/machsystm.h>
38 #include <sys/clock.h>
39 #include <sys/vfs.h>
40 #include <sys/kmem.h>
41 #include <nfs/lm.h>
42 #include <sys/systm.h>
43 #include <sys/cpr.h>
44 #include <sys/bootconf.h>
45 #include <sys/cyclic.h>
46 #include <sys/filio.h>
47 #include <sys/fs/ufs_filio.h>
48 #include <sys/epm.h>
49 #include <sys/modctl.h>
50 #include <sys/reboot.h>
51 #include <sys/kdi.h>
52 #include <sys/promif.h>
53 #include <sys/srn.h>
54 #include <sys/cpr_impl.h>
55 
56 #define	PPM(dip) ((dev_info_t *)DEVI(dip)->devi_pm_ppm)
57 
58 extern struct cpr_terminator cpr_term;
59 
60 extern int cpr_alloc_statefile(int);
61 extern void cpr_start_kernel_threads(void);
62 extern void cpr_abbreviate_devpath(char *, char *);
63 extern void cpr_convert_promtime(cpr_time_t *);
64 extern void cpr_send_notice(void);
65 extern void cpr_set_bitmap_size(void);
66 extern void cpr_stat_init();
67 extern void cpr_statef_close(void);
68 extern void flush_windows(void);
69 extern void (*srn_signal)(int, int);
70 extern void init_cpu_syscall(struct cpu *);
71 extern void i_cpr_pre_resume_cpus();
72 extern void i_cpr_post_resume_cpus();
73 extern int cpr_is_ufs(struct vfs *);
74 
75 extern int pm_powering_down;
76 extern kmutex_t srn_clone_lock;
77 extern int srn_inuse;
78 
79 static int cpr_suspend(int);
80 static int cpr_resume(int);
81 static void cpr_suspend_init(int);
82 #if defined(__x86)
83 static int cpr_suspend_cpus(void);
84 static void cpr_resume_cpus(void);
85 #endif
86 static int cpr_all_online(void);
87 static void cpr_restore_offline(void);
88 
89 cpr_time_t wholecycle_tv;
90 int cpr_suspend_succeeded;
91 pfn_t curthreadpfn;
92 int curthreadremapped;
93 
94 extern cpuset_t cpu_ready_set;
95 extern void *(*cpu_pause_func)(void *);
96 
97 extern processorid_t i_cpr_bootcpuid(void);
98 extern cpu_t *i_cpr_bootcpu(void);
99 extern void tsc_adjust_delta(hrtime_t tdelta);
100 extern void tsc_resume(void);
101 extern int tsc_resume_in_cyclic;
102 
103 /*
104  * Set this variable to 1, to have device drivers resume in an
105  * uniprocessor environment. This is to allow drivers that assume
106  * that they resume on a UP machine to continue to work. Should be
107  * deprecated once the broken drivers are fixed
108  */
109 int cpr_resume_uniproc = 0;
110 
111 /*
112  * save or restore abort_enable;  this prevents a drop
113  * to kadb or prom during cpr_resume_devices() when
114  * there is no kbd present;  see abort_sequence_enter()
115  */
116 static void
117 cpr_sae(int stash)
118 {
119 	static int saved_ae = -1;
120 
121 	if (stash) {
122 		saved_ae = abort_enable;
123 		abort_enable = 0;
124 	} else if (saved_ae != -1) {
125 		abort_enable = saved_ae;
126 		saved_ae = -1;
127 	}
128 }
129 
130 
131 /*
132  * The main switching point for cpr, this routine starts the ckpt
133  * and state file saving routines; on resume the control is
134  * returned back to here and it then calls the resume routine.
135  */
136 int
137 cpr_main(int sleeptype)
138 {
139 	int rc, rc2;
140 	label_t saveq;
141 	klwp_t *tlwp = ttolwp(curthread);
142 
143 	if (sleeptype == CPR_TODISK) {
144 		if ((rc = cpr_default_setup(1)) != 0)
145 			return (rc);
146 		ASSERT(tlwp);
147 		saveq = tlwp->lwp_qsav;
148 	}
149 
150 	if (sleeptype == CPR_TORAM) {
151 		rc = cpr_suspend(sleeptype);
152 		PMD(PMD_SX, ("cpr_suspend rets %x\n", rc))
153 		if (rc == 0) {
154 			int i_cpr_power_down(int sleeptype);
155 
156 			/*
157 			 * From this point on, we should be at a high
158 			 * spl, interrupts disabled, and all but one
159 			 * cpu's paused (effectively UP/single threaded).
160 			 * So this is were we want to put ASSERTS()
161 			 * to let us know otherwise.
162 			 */
163 			ASSERT(cpus_paused());
164 
165 			/*
166 			 * Now do the work of actually putting this
167 			 * machine to sleep!
168 			 */
169 			rc = i_cpr_power_down(sleeptype);
170 			if (rc == 0) {
171 				PMD(PMD_SX, ("back from succssful suspend\n"))
172 			}
173 			/*
174 			 * We do care about the return value from cpr_resume
175 			 * at this point, as it will tell us if one of the
176 			 * resume functions failed (cpr_resume_devices())
177 			 * However, for this to return and _not_ panic, means
178 			 * that we must be in one of the test functions.  So
179 			 * check for that and return an appropriate message.
180 			 */
181 			rc2 = cpr_resume(sleeptype);
182 			if (rc2 != 0) {
183 				ASSERT(cpr_test_point > 0);
184 				cmn_err(CE_NOTE,
185 				    "cpr_resume returned non-zero: %d\n", rc2);
186 				PMD(PMD_SX, ("cpr_resume rets %x\n", rc2))
187 			}
188 			ASSERT(!cpus_paused());
189 		} else {
190 			PMD(PMD_SX, ("failed suspend, resuming\n"))
191 			rc = cpr_resume(sleeptype);
192 		}
193 		return (rc);
194 	}
195 	/*
196 	 * Remember where we are for resume after reboot
197 	 */
198 	if (!setjmp(&tlwp->lwp_qsav)) {
199 		/*
200 		 * try to checkpoint the system, if failed return back
201 		 * to userland, otherwise power off.
202 		 */
203 		rc = cpr_suspend(sleeptype);
204 		if (rc || cpr_reusable_mode) {
205 			/*
206 			 * We don't really want to go down, or
207 			 * something went wrong in suspend, do what we can
208 			 * to put the system back to an operable state then
209 			 * return back to userland.
210 			 */
211 			PMD(PMD_SX, ("failed suspend, resuming\n"))
212 			(void) cpr_resume(sleeptype);
213 			PMD(PMD_SX, ("back from failed suspend resume\n"))
214 		}
215 	} else {
216 		/*
217 		 * This is the resumed side of longjmp, restore the previous
218 		 * longjmp pointer if there is one so this will be transparent
219 		 * to the world.
220 		 * This path is only for CPR_TODISK, where we reboot
221 		 */
222 		ASSERT(sleeptype == CPR_TODISK);
223 		tlwp->lwp_qsav = saveq;
224 		CPR->c_flags &= ~C_SUSPENDING;
225 		CPR->c_flags |= C_RESUMING;
226 
227 		/*
228 		 * resume the system back to the original state
229 		 */
230 		rc = cpr_resume(sleeptype);
231 		PMD(PMD_SX, ("back from successful suspend; resume rets %x\n",
232 		    rc))
233 	}
234 
235 	(void) cpr_default_setup(0);
236 
237 	return (rc);
238 }
239 
240 
241 #if defined(__sparc)
242 
243 /*
244  * check/disable or re-enable UFS logging
245  */
246 static void
247 cpr_log_status(int enable, int *svstat, vnode_t *vp)
248 {
249 	int cmd, status, error;
250 	char *str, *able;
251 	fiolog_t fl;
252 	refstr_t *mntpt;
253 
254 	str = "cpr_log_status";
255 	bzero(&fl, sizeof (fl));
256 	fl.error = FIOLOG_ENONE;
257 
258 	/*
259 	 * when disabling, first get and save logging status (0 or 1)
260 	 */
261 	if (enable == 0) {
262 		if (error = VOP_IOCTL(vp, _FIOISLOG,
263 		    (uintptr_t)&status, FKIOCTL, CRED(), NULL, NULL)) {
264 			mntpt = vfs_getmntpoint(vp->v_vfsp);
265 			prom_printf("%s: \"%s\", cant get logging "
266 			    "status, error %d\n", str, refstr_value(mntpt),
267 			    error);
268 			refstr_rele(mntpt);
269 			return;
270 		}
271 		*svstat = status;
272 		if (cpr_debug & CPR_DEBUG5) {
273 			mntpt = vfs_getmntpoint(vp->v_vfsp);
274 			errp("%s: \"%s\", logging status = %d\n",
275 			    str, refstr_value(mntpt), status);
276 			refstr_rele(mntpt);
277 		};
278 
279 		able = "disable";
280 		cmd = _FIOLOGDISABLE;
281 	} else {
282 		able = "enable";
283 		cmd = _FIOLOGENABLE;
284 	}
285 
286 	/*
287 	 * disable or re-enable logging when the saved status is 1
288 	 */
289 	if (*svstat == 1) {
290 		error = VOP_IOCTL(vp, cmd, (uintptr_t)&fl,
291 		    FKIOCTL, CRED(), NULL, NULL);
292 		if (error) {
293 			mntpt = vfs_getmntpoint(vp->v_vfsp);
294 			prom_printf("%s: \"%s\", cant %s logging, error %d\n",
295 			    str, refstr_value(mntpt), able, error);
296 			refstr_rele(mntpt);
297 		} else {
298 			if (cpr_debug & CPR_DEBUG5) {
299 				mntpt = vfs_getmntpoint(vp->v_vfsp);
300 				errp("%s: \"%s\", logging is now %sd\n",
301 				    str, refstr_value(mntpt), able);
302 				refstr_rele(mntpt);
303 			};
304 		}
305 	}
306 
307 	/*
308 	 * when enabling logging, reset the saved status
309 	 * to unknown for next time
310 	 */
311 	if (enable)
312 		*svstat = -1;
313 }
314 
315 /*
316  * enable/disable UFS logging on filesystems containing cpr_default_path
317  * and cpr statefile.  since the statefile can be on any fs, that fs
318  * needs to be handled separately.  this routine and cprboot expect that
319  * CPR_CONFIG and CPR_DEFAULT both reside on the same fs, rootfs.  cprboot
320  * is loaded from the device with rootfs and uses the same device to open
321  * both CPR_CONFIG and CPR_DEFAULT (see common/support.c).  moving either
322  * file outside of rootfs would cause errors during cprboot, plus cpr and
323  * fsck problems with the new fs if logging were enabled.
324  */
325 
326 static int
327 cpr_ufs_logging(int enable)
328 {
329 	static int def_status = -1, sf_status = -1;
330 	struct vfs *vfsp;
331 	char *fname;
332 	vnode_t *vp;
333 	int error;
334 
335 	if (cpr_reusable_mode)
336 		return (0);
337 
338 	if (error = cpr_open_deffile(FREAD, &vp))
339 		return (error);
340 	vfsp = vp->v_vfsp;
341 	if (!cpr_is_ufs(vfsp)) {
342 		(void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
343 		VN_RELE(vp);
344 		return (0);
345 	}
346 
347 	cpr_log_status(enable, &def_status, vp);
348 	(void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
349 	VN_RELE(vp);
350 
351 	fname = cpr_build_statefile_path();
352 	if (fname == NULL)
353 		return (ENOENT);
354 	if (error = vn_open(fname, UIO_SYSSPACE, FCREAT|FWRITE,
355 	    0600, &vp, CRCREAT, 0)) {
356 		prom_printf("cpr_ufs_logging: cant open/create \"%s\", "
357 		    "error %d\n", fname, error);
358 		return (error);
359 	}
360 
361 	/*
362 	 * check logging status for the statefile if it resides
363 	 * on a different fs and the type is a regular file
364 	 */
365 	if (vp->v_vfsp != vfsp && vp->v_type == VREG)
366 		cpr_log_status(enable, &sf_status, vp);
367 	(void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
368 	VN_RELE(vp);
369 
370 	return (0);
371 }
372 #endif
373 
374 
375 /*
376  * Check if klmmod is loaded and call a lock manager service; if klmmod
377  * is not loaded, the services aren't needed and a call would trigger a
378  * modload, which would block since another thread would never run.
379  */
380 static void
381 cpr_lock_mgr(void (*service)(void))
382 {
383 	if (mod_find_by_filename(NULL, "misc/klmmod") != NULL)
384 		(*service)();
385 }
386 
387 int
388 cpr_suspend_cpus(void)
389 {
390 	int	ret = 0;
391 	extern void *i_cpr_save_context(void *arg);
392 
393 	mutex_enter(&cpu_lock);
394 
395 	/*
396 	 * the machine could not have booted without a bootcpu
397 	 */
398 	ASSERT(i_cpr_bootcpu() != NULL);
399 
400 	/*
401 	 * bring all the offline cpus online
402 	 */
403 	if ((ret = cpr_all_online())) {
404 		mutex_exit(&cpu_lock);
405 		return (ret);
406 	}
407 
408 	/*
409 	 * Set the affinity to be the boot processor
410 	 * This is cleared in either cpr_resume_cpus() or cpr_unpause_cpus()
411 	 */
412 	affinity_set(i_cpr_bootcpuid());
413 
414 	ASSERT(CPU->cpu_id == 0);
415 
416 	PMD(PMD_SX, ("curthread running on bootcpu\n"))
417 
418 	/*
419 	 * pause all other running CPUs and save the CPU state at the sametime
420 	 */
421 	cpu_pause_func = i_cpr_save_context;
422 	pause_cpus(NULL);
423 
424 	mutex_exit(&cpu_lock);
425 
426 	return (0);
427 }
428 
429 /*
430  * Take the system down to a checkpointable state and write
431  * the state file, the following are sequentially executed:
432  *
433  *    - Request all user threads to stop themselves
434  *    - push out and invalidate user pages
435  *    - bring statefile inode incore to prevent a miss later
436  *    - request all daemons to stop
437  *    - check and make sure all threads are stopped
438  *    - sync the file system
439  *    - suspend all devices
440  *    - block intrpts
441  *    - dump system state and memory to state file
442  *    - SPARC code will not be called with CPR_TORAM, caller filters
443  */
444 static int
445 cpr_suspend(int sleeptype)
446 {
447 #if defined(__sparc)
448 	int sf_realloc, nverr;
449 #endif
450 	int	rc = 0;
451 	int	skt_rc = 0;
452 
453 	PMD(PMD_SX, ("cpr_suspend %x\n", sleeptype))
454 	cpr_set_substate(C_ST_SUSPEND_BEGIN);
455 
456 	cpr_suspend_init(sleeptype);
457 
458 	cpr_save_time();
459 
460 	cpr_tod_get(&wholecycle_tv);
461 	CPR_STAT_EVENT_START("Suspend Total");
462 
463 	i_cpr_alloc_cpus();
464 
465 #if defined(__sparc)
466 	ASSERT(sleeptype == CPR_TODISK);
467 	if (!cpr_reusable_mode) {
468 		/*
469 		 * We need to validate default file before fs
470 		 * functionality is disabled.
471 		 */
472 		if (rc = cpr_validate_definfo(0))
473 			return (rc);
474 	}
475 	i_cpr_save_machdep_info();
476 #endif
477 
478 	PMD(PMD_SX, ("cpr_suspend: stop scans\n"))
479 	/* Stop PM scans ASAP */
480 	(void) callb_execute_class(CB_CL_CPR_PM, CB_CODE_CPR_CHKPT);
481 
482 	pm_dispatch_to_dep_thread(PM_DEP_WK_CPR_SUSPEND,
483 	    NULL, NULL, PM_DEP_WAIT, NULL, 0);
484 
485 #if defined(__sparc)
486 	ASSERT(sleeptype == CPR_TODISK);
487 	cpr_set_substate(C_ST_MP_OFFLINE);
488 	if (rc = cpr_mp_offline())
489 		return (rc);
490 #endif
491 	/*
492 	 * Ask Xorg to suspend the frame buffer, and wait for it to happen
493 	 */
494 	mutex_enter(&srn_clone_lock);
495 	if (srn_signal) {
496 		PMD(PMD_SX, ("cpr_suspend: (*srn_signal)(..., "
497 		    "SRN_SUSPEND_REQ)\n"))
498 		srn_inuse = 1;	/* because *(srn_signal) cv_waits */
499 		(*srn_signal)(SRN_TYPE_APM, SRN_SUSPEND_REQ);
500 		srn_inuse = 0;
501 	} else {
502 		PMD(PMD_SX, ("cpr_suspend: srn_signal NULL\n"))
503 	}
504 	mutex_exit(&srn_clone_lock);
505 
506 	/*
507 	 * Ask the user threads to stop by themselves, but
508 	 * if they don't or can't after 3 retries, we give up on CPR.
509 	 * The 3 retry is not a random number because 2 is possible if
510 	 * a thread has been forked before the parent thread is stopped.
511 	 */
512 	CPR_DEBUG(CPR_DEBUG1, "\nstopping user threads...");
513 	CPR_STAT_EVENT_START("  stop users");
514 	cpr_set_substate(C_ST_STOP_USER_THREADS);
515 	PMD(PMD_SX, ("cpr_suspend: stop user threads\n"))
516 	if (rc = cpr_stop_user_threads())
517 		return (rc);
518 	CPR_STAT_EVENT_END("  stop users");
519 	CPR_DEBUG(CPR_DEBUG1, "done\n");
520 
521 	PMD(PMD_SX, ("cpr_suspend: save direct levels\n"))
522 	pm_save_direct_levels();
523 
524 	/*
525 	 * User threads are stopped.  We will start communicating with the
526 	 * user via prom_printf (some debug output may have already happened)
527 	 * so let anybody who cares know about this (bug 4096122)
528 	 */
529 	(void) callb_execute_class(CB_CL_CPR_PROMPRINTF, CB_CODE_CPR_CHKPT);
530 
531 	PMD(PMD_SX, ("cpr_suspend: send notice\n"))
532 #ifndef DEBUG
533 	cpr_send_notice();
534 	if (cpr_debug)
535 		prom_printf("\n");
536 #endif
537 
538 	PMD(PMD_SX, ("cpr_suspend: POST USER callback\n"))
539 	(void) callb_execute_class(CB_CL_CPR_POST_USER, CB_CODE_CPR_CHKPT);
540 
541 	/*
542 	 * Reattach any drivers which originally exported the
543 	 * no-involuntary-power-cycles property.  We need to do this before
544 	 * stopping kernel threads because modload is implemented using
545 	 * a kernel thread.
546 	 */
547 	cpr_set_substate(C_ST_PM_REATTACH_NOINVOL);
548 	PMD(PMD_SX, ("cpr_suspend: reattach noinvol\n"))
549 	if (!pm_reattach_noinvol())
550 		return (ENXIO);
551 
552 #if defined(__sparc)
553 	ASSERT(sleeptype == CPR_TODISK);
554 	/*
555 	 * if ufs logging is enabled, we need to disable before
556 	 * stopping kernel threads so that ufs delete and roll
557 	 * threads can do the work.
558 	 */
559 	cpr_set_substate(C_ST_DISABLE_UFS_LOGGING);
560 	if (rc = cpr_ufs_logging(0))
561 		return (rc);
562 
563 	/*
564 	 * Use sync_all to swap out all user pages and find out how much
565 	 * extra space needed for user pages that don't have back store
566 	 * space left.
567 	 */
568 	CPR_STAT_EVENT_START("  swapout upages");
569 	vfs_sync(SYNC_ALL);
570 	CPR_STAT_EVENT_END("  swapout upages");
571 
572 	cpr_set_bitmap_size();
573 
574 alloc_statefile:
575 	/*
576 	 * If our last state was C_ST_DUMP_NOSPC, we're trying to
577 	 * realloc the statefile, otherwise this is the first attempt.
578 	 */
579 	sf_realloc = (CPR->c_substate == C_ST_DUMP_NOSPC) ? 1 : 0;
580 
581 	CPR_STAT_EVENT_START("  alloc statefile");
582 	cpr_set_substate(C_ST_STATEF_ALLOC);
583 	if (rc = cpr_alloc_statefile(sf_realloc)) {
584 		if (sf_realloc)
585 			errp("realloc failed\n");
586 		return (rc);
587 	}
588 	CPR_STAT_EVENT_END("  alloc statefile");
589 
590 	/*
591 	 * Sync the filesystem to preserve its integrity.
592 	 *
593 	 * This sync is also used to flush out all B_DELWRI buffers
594 	 * (fs cache) which are mapped and neither dirty nor referenced
595 	 * before cpr_invalidate_pages destroys them.
596 	 * fsflush does similar thing.
597 	 */
598 	sync();
599 
600 	/*
601 	 * destroy all clean file mapped kernel pages
602 	 */
603 	CPR_STAT_EVENT_START("  clean pages");
604 	CPR_DEBUG(CPR_DEBUG1, ("cleaning up mapped pages..."));
605 	(void) callb_execute_class(CB_CL_CPR_VM, CB_CODE_CPR_CHKPT);
606 	CPR_DEBUG(CPR_DEBUG1, ("done\n"));
607 	CPR_STAT_EVENT_END("  clean pages");
608 #endif
609 
610 
611 	/*
612 	 * Hooks needed by lock manager prior to suspending.
613 	 * Refer to code for more comments.
614 	 */
615 	PMD(PMD_SX, ("cpr_suspend: lock mgr\n"))
616 	cpr_lock_mgr(lm_cprsuspend);
617 
618 	/*
619 	 * Now suspend all the devices
620 	 */
621 	CPR_STAT_EVENT_START("  stop drivers");
622 	CPR_DEBUG(CPR_DEBUG1, "suspending drivers...");
623 	cpr_set_substate(C_ST_SUSPEND_DEVICES);
624 	pm_powering_down = 1;
625 	PMD(PMD_SX, ("cpr_suspend: suspending devices\n"))
626 	rc = cpr_suspend_devices(ddi_root_node());
627 	pm_powering_down = 0;
628 	if (rc)
629 		return (rc);
630 	CPR_DEBUG(CPR_DEBUG1, "done\n");
631 	CPR_STAT_EVENT_END("  stop drivers");
632 
633 	/*
634 	 * Stop all daemon activities
635 	 */
636 	cpr_set_substate(C_ST_STOP_KERNEL_THREADS);
637 	PMD(PMD_SX, ("cpr_suspend: stopping kernel threads\n"))
638 	if (skt_rc = cpr_stop_kernel_threads())
639 		return (skt_rc);
640 
641 	PMD(PMD_SX, ("cpr_suspend: POST KERNEL callback\n"))
642 	(void) callb_execute_class(CB_CL_CPR_POST_KERNEL, CB_CODE_CPR_CHKPT);
643 
644 	PMD(PMD_SX, ("cpr_suspend: reattach noinvol fini\n"))
645 	pm_reattach_noinvol_fini();
646 
647 	cpr_sae(1);
648 
649 	PMD(PMD_SX, ("cpr_suspend: CPR CALLOUT callback\n"))
650 	(void) callb_execute_class(CB_CL_CPR_CALLOUT, CB_CODE_CPR_CHKPT);
651 
652 	if (sleeptype == CPR_TODISK) {
653 		/*
654 		 * It's safer to do tod_get before we disable all intr.
655 		 */
656 		CPR_STAT_EVENT_START("  write statefile");
657 	}
658 
659 	/*
660 	 * it's time to ignore the outside world, stop the real time
661 	 * clock and disable any further intrpt activity.
662 	 */
663 	PMD(PMD_SX, ("cpr_suspend: handle xc\n"))
664 	i_cpr_handle_xc(1);	/* turn it on to disable xc assertion */
665 
666 	mutex_enter(&cpu_lock);
667 	PMD(PMD_SX, ("cpr_suspend: cyclic suspend\n"))
668 	cyclic_suspend();
669 	mutex_exit(&cpu_lock);
670 
671 	/*
672 	 * Due to the different methods of resuming the system between
673 	 * CPR_TODISK (boot cprboot on SPARC, which reloads kernel image)
674 	 * and CPR_TORAM (restart via reset into existing kernel image)
675 	 * cpus are not suspended and restored in the SPARC case, since it
676 	 * is necessary to restart the cpus and pause them before restoring
677 	 * the OBP image
678 	 */
679 
680 #if defined(__x86)
681 
682 	/* pause aux cpus */
683 	PMD(PMD_SX, ("pause aux cpus\n"))
684 
685 	cpr_set_substate(C_ST_MP_PAUSED);
686 
687 	if ((rc = cpr_suspend_cpus()) != 0)
688 		return (rc);
689 #endif
690 
691 	PMD(PMD_SX, ("cpr_suspend: stop intr\n"))
692 	i_cpr_stop_intr();
693 	CPR_DEBUG(CPR_DEBUG1, "interrupt is stopped\n");
694 
695 	/*
696 	 * Since we will now disable the mechanism that causes prom_printfs
697 	 * to power up (if needed) the console fb/monitor, we assert that
698 	 * it must be up now.
699 	 */
700 	ASSERT(pm_cfb_is_up());
701 	PMD(PMD_SX, ("cpr_suspend: prom suspend prepost\n"))
702 	prom_suspend_prepost();
703 
704 #if defined(__sparc)
705 	/*
706 	 * getting ready to write ourself out, flush the register
707 	 * windows to make sure that our stack is good when we
708 	 * come back on the resume side.
709 	 */
710 	flush_windows();
711 #endif
712 
713 	/*
714 	 * For S3, we're done
715 	 */
716 	if (sleeptype == CPR_TORAM) {
717 		PMD(PMD_SX, ("cpr_suspend rets %x\n", rc))
718 		cpr_set_substate(C_ST_NODUMP);
719 		return (rc);
720 	}
721 #if defined(__sparc)
722 	/*
723 	 * FATAL: NO MORE MEMORY ALLOCATION ALLOWED AFTER THIS POINT!!!
724 	 *
725 	 * The system is quiesced at this point, we are ready to either dump
726 	 * to the state file for a extended sleep or a simple shutdown for
727 	 * systems with non-volatile memory.
728 	 */
729 
730 	/*
731 	 * special handling for reusable:
732 	 */
733 	if (cpr_reusable_mode) {
734 		cpr_set_substate(C_ST_SETPROPS_1);
735 		if (nverr = cpr_set_properties(1))
736 			return (nverr);
737 	}
738 
739 	cpr_set_substate(C_ST_DUMP);
740 	rc = cpr_dump(C_VP);
741 
742 	/*
743 	 * if any error occurred during dump, more
744 	 * special handling for reusable:
745 	 */
746 	if (rc && cpr_reusable_mode) {
747 		cpr_set_substate(C_ST_SETPROPS_0);
748 		if (nverr = cpr_set_properties(0))
749 			return (nverr);
750 	}
751 
752 	if (rc == ENOSPC) {
753 		cpr_set_substate(C_ST_DUMP_NOSPC);
754 		(void) cpr_resume(sleeptype);
755 		goto alloc_statefile;
756 	} else if (rc == 0) {
757 		if (cpr_reusable_mode) {
758 			cpr_set_substate(C_ST_REUSABLE);
759 			longjmp(&ttolwp(curthread)->lwp_qsav);
760 		} else
761 			rc = cpr_set_properties(1);
762 	}
763 #endif
764 	PMD(PMD_SX, ("cpr_suspend: return %d\n", rc))
765 	return (rc);
766 }
767 
768 void
769 cpr_resume_cpus(void)
770 {
771 	/*
772 	 * this is a cut down version of start_other_cpus()
773 	 * just do the initialization to wake the other cpus
774 	 */
775 
776 #if defined(__x86)
777 	/*
778 	 * Initialize our syscall handlers
779 	 */
780 	init_cpu_syscall(CPU);
781 
782 #endif
783 
784 	i_cpr_pre_resume_cpus();
785 
786 	/*
787 	 * Restart the paused cpus
788 	 */
789 	mutex_enter(&cpu_lock);
790 	start_cpus();
791 	mutex_exit(&cpu_lock);
792 
793 	i_cpr_post_resume_cpus();
794 
795 	mutex_enter(&cpu_lock);
796 	/*
797 	 * Restore this cpu to use the regular cpu_pause(), so that
798 	 * online and offline will work correctly
799 	 */
800 	cpu_pause_func = NULL;
801 
802 	/*
803 	 * clear the affinity set in cpr_suspend_cpus()
804 	 */
805 	affinity_clear();
806 
807 	/*
808 	 * offline all the cpus that were brought online during suspend
809 	 */
810 	cpr_restore_offline();
811 
812 	mutex_exit(&cpu_lock);
813 }
814 
815 void
816 cpr_unpause_cpus(void)
817 {
818 	/*
819 	 * Now restore the system back to what it was before we suspended
820 	 */
821 
822 	PMD(PMD_SX, ("cpr_unpause_cpus: restoring system\n"))
823 
824 	mutex_enter(&cpu_lock);
825 
826 	/*
827 	 * Restore this cpu to use the regular cpu_pause(), so that
828 	 * online and offline will work correctly
829 	 */
830 	cpu_pause_func = NULL;
831 
832 	/*
833 	 * Restart the paused cpus
834 	 */
835 	start_cpus();
836 
837 	/*
838 	 * clear the affinity set in cpr_suspend_cpus()
839 	 */
840 	affinity_clear();
841 
842 	/*
843 	 * offline all the cpus that were brought online during suspend
844 	 */
845 	cpr_restore_offline();
846 
847 	mutex_exit(&cpu_lock);
848 }
849 
850 /*
851  * Bring the system back up from a checkpoint, at this point
852  * the VM has been minimally restored by boot, the following
853  * are executed sequentially:
854  *
855  *    - machdep setup and enable interrupts (mp startup if it's mp)
856  *    - resume all devices
857  *    - restart daemons
858  *    - put all threads back on run queue
859  */
860 static int
861 cpr_resume(int sleeptype)
862 {
863 	cpr_time_t pwron_tv, *ctp;
864 	char *str;
865 	int rc = 0;
866 
867 	/*
868 	 * The following switch is used to resume the system
869 	 * that was suspended to a different level.
870 	 */
871 	CPR_DEBUG(CPR_DEBUG1, "\nEntering cpr_resume...\n");
872 	PMD(PMD_SX, ("cpr_resume %x\n", sleeptype))
873 
874 	/*
875 	 * Note:
876 	 *
877 	 * The rollback labels rb_xyz do not represent the cpr resume
878 	 * state when event 'xyz' has happened. Instead they represent
879 	 * the state during cpr suspend when event 'xyz' was being
880 	 * entered (and where cpr suspend failed). The actual call that
881 	 * failed may also need to be partially rolled back, since they
882 	 * aren't atomic in most cases.  In other words, rb_xyz means
883 	 * "roll back all cpr suspend events that happened before 'xyz',
884 	 * and the one that caused the failure, if necessary."
885 	 */
886 	switch (CPR->c_substate) {
887 #if defined(__sparc)
888 	case C_ST_DUMP:
889 		/*
890 		 * This is most likely a full-fledged cpr_resume after
891 		 * a complete and successful cpr suspend. Just roll back
892 		 * everything.
893 		 */
894 		ASSERT(sleeptype == CPR_TODISK);
895 		break;
896 
897 	case C_ST_REUSABLE:
898 	case C_ST_DUMP_NOSPC:
899 	case C_ST_SETPROPS_0:
900 	case C_ST_SETPROPS_1:
901 		/*
902 		 * C_ST_REUSABLE and C_ST_DUMP_NOSPC are the only two
903 		 * special switch cases here. The other two do not have
904 		 * any state change during cpr_suspend() that needs to
905 		 * be rolled back. But these are exit points from
906 		 * cpr_suspend, so theoretically (or in the future), it
907 		 * is possible that a need for roll back of a state
908 		 * change arises between these exit points.
909 		 */
910 		ASSERT(sleeptype == CPR_TODISK);
911 		goto rb_dump;
912 #endif
913 
914 	case C_ST_NODUMP:
915 		PMD(PMD_SX, ("cpr_resume: NODUMP\n"))
916 		goto rb_nodump;
917 
918 	case C_ST_STOP_KERNEL_THREADS:
919 		PMD(PMD_SX, ("cpr_resume: STOP_KERNEL_THREADS\n"))
920 		goto rb_stop_kernel_threads;
921 
922 	case C_ST_SUSPEND_DEVICES:
923 		PMD(PMD_SX, ("cpr_resume: SUSPEND_DEVICES\n"))
924 		goto rb_suspend_devices;
925 
926 #if defined(__sparc)
927 	case C_ST_STATEF_ALLOC:
928 		ASSERT(sleeptype == CPR_TODISK);
929 		goto rb_statef_alloc;
930 
931 	case C_ST_DISABLE_UFS_LOGGING:
932 		ASSERT(sleeptype == CPR_TODISK);
933 		goto rb_disable_ufs_logging;
934 #endif
935 
936 	case C_ST_PM_REATTACH_NOINVOL:
937 		PMD(PMD_SX, ("cpr_resume: REATTACH_NOINVOL\n"))
938 		goto rb_pm_reattach_noinvol;
939 
940 	case C_ST_STOP_USER_THREADS:
941 		PMD(PMD_SX, ("cpr_resume: STOP_USER_THREADS\n"))
942 		goto rb_stop_user_threads;
943 
944 #if defined(__sparc)
945 	case C_ST_MP_OFFLINE:
946 		PMD(PMD_SX, ("cpr_resume: MP_OFFLINE\n"))
947 		goto rb_mp_offline;
948 #endif
949 
950 #if defined(__x86)
951 	case C_ST_MP_PAUSED:
952 		PMD(PMD_SX, ("cpr_resume: MP_PAUSED\n"))
953 		goto rb_mp_paused;
954 #endif
955 
956 
957 	default:
958 		PMD(PMD_SX, ("cpr_resume: others\n"))
959 		goto rb_others;
960 	}
961 
962 rb_all:
963 	/*
964 	 * perform platform-dependent initialization
965 	 */
966 	if (cpr_suspend_succeeded)
967 		i_cpr_machdep_setup();
968 
969 	/*
970 	 * system did not really go down if we jump here
971 	 */
972 rb_dump:
973 	/*
974 	 * IMPORTANT:  SENSITIVE RESUME SEQUENCE
975 	 *
976 	 * DO NOT ADD ANY INITIALIZATION STEP BEFORE THIS POINT!!
977 	 */
978 rb_nodump:
979 	/*
980 	 * If we did suspend to RAM, we didn't generate a dump
981 	 */
982 	PMD(PMD_SX, ("cpr_resume: CPR DMA callback\n"))
983 	(void) callb_execute_class(CB_CL_CPR_DMA, CB_CODE_CPR_RESUME);
984 	if (cpr_suspend_succeeded) {
985 		PMD(PMD_SX, ("cpr_resume: CPR RPC callback\n"))
986 		(void) callb_execute_class(CB_CL_CPR_RPC, CB_CODE_CPR_RESUME);
987 	}
988 
989 	prom_resume_prepost();
990 #if !defined(__sparc)
991 	/*
992 	 * Need to sync the software clock with the hardware clock.
993 	 * On Sparc, this occurs in the sparc-specific cbe.  However
994 	 * on x86 this needs to be handled _before_ we bring other cpu's
995 	 * back online.  So we call a resume function in timestamp.c
996 	 */
997 	if (tsc_resume_in_cyclic == 0)
998 		tsc_resume();
999 
1000 #endif
1001 
1002 #if defined(__sparc)
1003 	if (cpr_suspend_succeeded && (boothowto & RB_DEBUG))
1004 		kdi_dvec_cpr_restart();
1005 #endif
1006 
1007 
1008 #if defined(__x86)
1009 rb_mp_paused:
1010 	PT(PT_RMPO);
1011 	PMD(PMD_SX, ("resume aux cpus\n"))
1012 
1013 	if (cpr_suspend_succeeded) {
1014 		cpr_resume_cpus();
1015 	} else {
1016 		cpr_unpause_cpus();
1017 	}
1018 #endif
1019 
1020 	/*
1021 	 * let the tmp callout catch up.
1022 	 */
1023 	PMD(PMD_SX, ("cpr_resume: CPR CALLOUT callback\n"))
1024 	(void) callb_execute_class(CB_CL_CPR_CALLOUT, CB_CODE_CPR_RESUME);
1025 
1026 	i_cpr_enable_intr();
1027 
1028 	mutex_enter(&cpu_lock);
1029 	PMD(PMD_SX, ("cpr_resume: cyclic resume\n"))
1030 	cyclic_resume();
1031 	mutex_exit(&cpu_lock);
1032 
1033 	PMD(PMD_SX, ("cpr_resume: handle xc\n"))
1034 	i_cpr_handle_xc(0);	/* turn it off to allow xc assertion */
1035 
1036 	PMD(PMD_SX, ("cpr_resume: CPR POST KERNEL callback\n"))
1037 	(void) callb_execute_class(CB_CL_CPR_POST_KERNEL, CB_CODE_CPR_RESUME);
1038 
1039 	/*
1040 	 * statistics gathering
1041 	 */
1042 	if (cpr_suspend_succeeded) {
1043 		/*
1044 		 * Prevent false alarm in tod_validate() due to tod
1045 		 * value change between suspend and resume
1046 		 */
1047 		cpr_tod_fault_reset();
1048 
1049 		cpr_convert_promtime(&pwron_tv);
1050 
1051 		ctp = &cpr_term.tm_shutdown;
1052 		if (sleeptype == CPR_TODISK)
1053 			CPR_STAT_EVENT_END_TMZ("  write statefile", ctp);
1054 		CPR_STAT_EVENT_END_TMZ("Suspend Total", ctp);
1055 
1056 		CPR_STAT_EVENT_START_TMZ("Resume Total", &pwron_tv);
1057 
1058 		str = "  prom time";
1059 		CPR_STAT_EVENT_START_TMZ(str, &pwron_tv);
1060 		ctp = &cpr_term.tm_cprboot_start;
1061 		CPR_STAT_EVENT_END_TMZ(str, ctp);
1062 
1063 		str = "  read statefile";
1064 		CPR_STAT_EVENT_START_TMZ(str, ctp);
1065 		ctp = &cpr_term.tm_cprboot_end;
1066 		CPR_STAT_EVENT_END_TMZ(str, ctp);
1067 	}
1068 
1069 rb_stop_kernel_threads:
1070 	/*
1071 	 * Put all threads back to where they belong; get the kernel
1072 	 * daemons straightened up too. Note that the callback table
1073 	 * locked during cpr_stop_kernel_threads() is released only
1074 	 * in cpr_start_kernel_threads(). Ensure modunloading is
1075 	 * disabled before starting kernel threads, we don't want
1076 	 * modunload thread to start changing device tree underneath.
1077 	 */
1078 	PMD(PMD_SX, ("cpr_resume: modunload disable\n"))
1079 	modunload_disable();
1080 	PMD(PMD_SX, ("cpr_resume: start kernel threads\n"))
1081 	cpr_start_kernel_threads();
1082 
1083 rb_suspend_devices:
1084 	CPR_DEBUG(CPR_DEBUG1, "resuming devices...");
1085 	CPR_STAT_EVENT_START("  start drivers");
1086 
1087 	PMD(PMD_SX,
1088 	    ("cpr_resume: rb_suspend_devices: cpr_resume_uniproc = %d\n",
1089 	    cpr_resume_uniproc))
1090 
1091 #if defined(__x86)
1092 	/*
1093 	 * If cpr_resume_uniproc is set, then pause all the other cpus
1094 	 * apart from the current cpu, so that broken drivers that think
1095 	 * that they are on a uniprocessor machine will resume
1096 	 */
1097 	if (cpr_resume_uniproc) {
1098 		mutex_enter(&cpu_lock);
1099 		pause_cpus(NULL);
1100 		mutex_exit(&cpu_lock);
1101 	}
1102 #endif
1103 
1104 	/*
1105 	 * The policy here is to continue resume everything we can if we did
1106 	 * not successfully finish suspend; and panic if we are coming back
1107 	 * from a fully suspended system.
1108 	 */
1109 	PMD(PMD_SX, ("cpr_resume: resume devices\n"))
1110 	rc = cpr_resume_devices(ddi_root_node(), 0);
1111 
1112 	cpr_sae(0);
1113 
1114 	str = "Failed to resume one or more devices.";
1115 
1116 	if (rc) {
1117 		if (CPR->c_substate == C_ST_DUMP ||
1118 		    (sleeptype == CPR_TORAM &&
1119 		    CPR->c_substate == C_ST_NODUMP)) {
1120 			if (cpr_test_point == FORCE_SUSPEND_TO_RAM) {
1121 				PMD(PMD_SX, ("cpr_resume: resume device "
1122 				    "warn\n"))
1123 				cpr_err(CE_WARN, str);
1124 			} else {
1125 				PMD(PMD_SX, ("cpr_resume: resume device "
1126 				    "panic\n"))
1127 				cpr_err(CE_PANIC, str);
1128 			}
1129 		} else {
1130 			PMD(PMD_SX, ("cpr_resume: resume device warn\n"))
1131 			cpr_err(CE_WARN, str);
1132 		}
1133 	}
1134 
1135 	CPR_STAT_EVENT_END("  start drivers");
1136 	CPR_DEBUG(CPR_DEBUG1, "done\n");
1137 
1138 #if defined(__x86)
1139 	/*
1140 	 * If cpr_resume_uniproc is set, then unpause all the processors
1141 	 * that were paused before resuming the drivers
1142 	 */
1143 	if (cpr_resume_uniproc) {
1144 		mutex_enter(&cpu_lock);
1145 		start_cpus();
1146 		mutex_exit(&cpu_lock);
1147 	}
1148 #endif
1149 
1150 	/*
1151 	 * If we had disabled modunloading in this cpr resume cycle (i.e. we
1152 	 * resumed from a state earlier than C_ST_SUSPEND_DEVICES), re-enable
1153 	 * modunloading now.
1154 	 */
1155 	if (CPR->c_substate != C_ST_SUSPEND_DEVICES) {
1156 		PMD(PMD_SX, ("cpr_resume: modload enable\n"))
1157 		modunload_enable();
1158 	}
1159 
1160 	/*
1161 	 * Hooks needed by lock manager prior to resuming.
1162 	 * Refer to code for more comments.
1163 	 */
1164 	PMD(PMD_SX, ("cpr_resume: lock mgr\n"))
1165 	cpr_lock_mgr(lm_cprresume);
1166 
1167 #if defined(__sparc)
1168 	/*
1169 	 * This is a partial (half) resume during cpr suspend, we
1170 	 * haven't yet given up on the suspend. On return from here,
1171 	 * cpr_suspend() will try to reallocate and retry the suspend.
1172 	 */
1173 	if (CPR->c_substate == C_ST_DUMP_NOSPC) {
1174 		return (0);
1175 	}
1176 
1177 	if (sleeptype == CPR_TODISK) {
1178 rb_statef_alloc:
1179 		cpr_statef_close();
1180 
1181 rb_disable_ufs_logging:
1182 		/*
1183 		 * if ufs logging was disabled, re-enable
1184 		 */
1185 		(void) cpr_ufs_logging(1);
1186 	}
1187 #endif
1188 
1189 rb_pm_reattach_noinvol:
1190 	/*
1191 	 * When pm_reattach_noinvol() succeeds, modunload_thread will
1192 	 * remain disabled until after cpr suspend passes the
1193 	 * C_ST_STOP_KERNEL_THREADS state. If any failure happens before
1194 	 * cpr suspend reaches this state, we'll need to enable modunload
1195 	 * thread during rollback.
1196 	 */
1197 	if (CPR->c_substate == C_ST_DISABLE_UFS_LOGGING ||
1198 	    CPR->c_substate == C_ST_STATEF_ALLOC ||
1199 	    CPR->c_substate == C_ST_SUSPEND_DEVICES ||
1200 	    CPR->c_substate == C_ST_STOP_KERNEL_THREADS) {
1201 		PMD(PMD_SX, ("cpr_resume: reattach noinvol fini\n"))
1202 		pm_reattach_noinvol_fini();
1203 	}
1204 
1205 	PMD(PMD_SX, ("cpr_resume: CPR POST USER callback\n"))
1206 	(void) callb_execute_class(CB_CL_CPR_POST_USER, CB_CODE_CPR_RESUME);
1207 	PMD(PMD_SX, ("cpr_resume: CPR PROMPRINTF callback\n"))
1208 	(void) callb_execute_class(CB_CL_CPR_PROMPRINTF, CB_CODE_CPR_RESUME);
1209 
1210 	PMD(PMD_SX, ("cpr_resume: restore direct levels\n"))
1211 	pm_restore_direct_levels();
1212 
1213 rb_stop_user_threads:
1214 	CPR_DEBUG(CPR_DEBUG1, "starting user threads...");
1215 	PMD(PMD_SX, ("cpr_resume: starting user threads\n"))
1216 	cpr_start_user_threads();
1217 	CPR_DEBUG(CPR_DEBUG1, "done\n");
1218 	/*
1219 	 * Ask Xorg to resume the frame buffer, and wait for it to happen
1220 	 */
1221 	mutex_enter(&srn_clone_lock);
1222 	if (srn_signal) {
1223 		PMD(PMD_SX, ("cpr_suspend: (*srn_signal)(..., "
1224 		    "SRN_NORMAL_RESUME)\n"))
1225 		srn_inuse = 1;		/* because (*srn_signal) cv_waits */
1226 		(*srn_signal)(SRN_TYPE_APM, SRN_NORMAL_RESUME);
1227 		srn_inuse = 0;
1228 	} else {
1229 		PMD(PMD_SX, ("cpr_suspend: srn_signal NULL\n"))
1230 	}
1231 	mutex_exit(&srn_clone_lock);
1232 
1233 #if defined(__sparc)
1234 rb_mp_offline:
1235 	if (cpr_mp_online())
1236 		cpr_err(CE_WARN, "Failed to online all the processors.");
1237 #endif
1238 
1239 rb_others:
1240 	PMD(PMD_SX, ("cpr_resume: dep thread\n"))
1241 	pm_dispatch_to_dep_thread(PM_DEP_WK_CPR_RESUME, NULL, NULL,
1242 	    PM_DEP_WAIT, NULL, 0);
1243 
1244 	PMD(PMD_SX, ("cpr_resume: CPR PM callback\n"))
1245 	(void) callb_execute_class(CB_CL_CPR_PM, CB_CODE_CPR_RESUME);
1246 
1247 	if (cpr_suspend_succeeded) {
1248 		cpr_stat_record_events();
1249 	}
1250 
1251 #if defined(__sparc)
1252 	if (sleeptype == CPR_TODISK && !cpr_reusable_mode)
1253 		cpr_clear_definfo();
1254 #endif
1255 
1256 	i_cpr_free_cpus();
1257 	CPR_DEBUG(CPR_DEBUG1, "Sending SIGTHAW...");
1258 	PMD(PMD_SX, ("cpr_resume: SIGTHAW\n"))
1259 	cpr_signal_user(SIGTHAW);
1260 	CPR_DEBUG(CPR_DEBUG1, "done\n");
1261 
1262 	CPR_STAT_EVENT_END("Resume Total");
1263 
1264 	CPR_STAT_EVENT_START_TMZ("WHOLE CYCLE", &wholecycle_tv);
1265 	CPR_STAT_EVENT_END("WHOLE CYCLE");
1266 
1267 	if (cpr_debug & CPR_DEBUG1)
1268 		cmn_err(CE_CONT, "\nThe system is back where you left!\n");
1269 
1270 	CPR_STAT_EVENT_START("POST CPR DELAY");
1271 
1272 #ifdef CPR_STAT
1273 	ctp = &cpr_term.tm_shutdown;
1274 	CPR_STAT_EVENT_START_TMZ("PWROFF TIME", ctp);
1275 	CPR_STAT_EVENT_END_TMZ("PWROFF TIME", &pwron_tv);
1276 
1277 	CPR_STAT_EVENT_PRINT();
1278 #endif /* CPR_STAT */
1279 
1280 	PMD(PMD_SX, ("cpr_resume returns %x\n", rc))
1281 	return (rc);
1282 }
1283 
1284 static void
1285 cpr_suspend_init(int sleeptype)
1286 {
1287 	cpr_time_t *ctp;
1288 
1289 	cpr_stat_init();
1290 
1291 	/*
1292 	 * If cpr_suspend() failed before cpr_dump() gets a chance
1293 	 * to reinitialize the terminator of the statefile,
1294 	 * the values of the old terminator will still linger around.
1295 	 * Since the terminator contains information that we need to
1296 	 * decide whether suspend succeeded or not, we need to
1297 	 * reinitialize it as early as possible.
1298 	 */
1299 	cpr_term.real_statef_size = 0;
1300 	ctp = &cpr_term.tm_shutdown;
1301 	bzero(ctp, sizeof (*ctp));
1302 	ctp = &cpr_term.tm_cprboot_start;
1303 	bzero(ctp, sizeof (*ctp));
1304 	ctp = &cpr_term.tm_cprboot_end;
1305 	bzero(ctp, sizeof (*ctp));
1306 
1307 	if (sleeptype == CPR_TODISK) {
1308 		/*
1309 		 * Lookup the physical address of our thread structure.
1310 		 * This should never be invalid and the entire thread structure
1311 		 * is expected to reside within the same pfn.
1312 		 */
1313 		curthreadpfn = hat_getpfnum(kas.a_hat, (caddr_t)curthread);
1314 		ASSERT(curthreadpfn != PFN_INVALID);
1315 		ASSERT(curthreadpfn == hat_getpfnum(kas.a_hat,
1316 		    (caddr_t)curthread + sizeof (kthread_t) - 1));
1317 	}
1318 
1319 	cpr_suspend_succeeded = 0;
1320 }
1321 
1322 /*
1323  * bring all the offline cpus online
1324  */
1325 static int
1326 cpr_all_online(void)
1327 {
1328 	int	rc = 0;
1329 
1330 #ifdef	__sparc
1331 	/*
1332 	 * do nothing
1333 	 */
1334 #else
1335 
1336 	cpu_t	*cp;
1337 
1338 	ASSERT(MUTEX_HELD(&cpu_lock));
1339 
1340 	cp = cpu_list;
1341 	do {
1342 		cp->cpu_cpr_flags &= ~CPU_CPR_ONLINE;
1343 		if (!CPU_ACTIVE(cp)) {
1344 			if ((rc = cpu_online(cp)) != 0)
1345 				break;
1346 			CPU_SET_CPR_FLAGS(cp, CPU_CPR_ONLINE);
1347 		}
1348 	} while ((cp = cp->cpu_next) != cpu_list);
1349 
1350 	if (rc) {
1351 		/*
1352 		 * an online operation failed so offline the cpus
1353 		 * that were onlined above to restore the system
1354 		 * to its original state
1355 		 */
1356 		cpr_restore_offline();
1357 	}
1358 #endif
1359 	return (rc);
1360 }
1361 
1362 /*
1363  * offline all the cpus that were brought online by cpr_all_online()
1364  */
1365 static void
1366 cpr_restore_offline(void)
1367 {
1368 
1369 #ifdef	__sparc
1370 	/*
1371 	 * do nothing
1372 	 */
1373 #else
1374 
1375 	cpu_t	*cp;
1376 	int	rc = 0;
1377 
1378 	ASSERT(MUTEX_HELD(&cpu_lock));
1379 
1380 	cp = cpu_list;
1381 	do {
1382 		if (CPU_CPR_IS_ONLINE(cp)) {
1383 			rc =  cpu_offline(cp, 0);
1384 			/*
1385 			 * this offline should work, since the cpu was
1386 			 * offline originally and was successfully onlined
1387 			 * by cpr_all_online()
1388 			 */
1389 			ASSERT(rc == 0);
1390 			cp->cpu_cpr_flags &= ~CPU_CPR_ONLINE;
1391 		}
1392 	} while ((cp = cp->cpu_next) != cpu_list);
1393 
1394 #endif
1395 
1396 }
1397