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