Exemple #1
0
static void
ps_md_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen)
{
	extern int mach_descrip_update(void);
	extern void mdeg_notify_clients(void);
	extern void recalc_xc_timeouts(void);

	ds_svc_hdl_t		 ds_handle = ds_md_handle;
	platsvc_md_update_req_t	 *msg = buf;
	platsvc_md_update_resp_t resp_msg;
	uint_t			 rv;

	if (arg == NULL)
		return;

	if (ds_handle == DS_INVALID_HDL) {
		DBG("ps_md_data_handler: DS handle no longer valid\n");
		return;
	}

	if (msg == NULL || buflen != sizeof (platsvc_md_update_req_t)) {
		resp_msg.req_num = 0;
		resp_msg.result = MD_UPDATE_INVALID_MSG;
		if ((rv = ds_cap_send(ds_handle, &resp_msg,
		    sizeof (resp_msg))) != 0) {
			cmn_err(CE_NOTE, "md ds_cap_send failed (%d)", rv);
		}
		return;
	}

	DBG("MD Reload...\n");
	if (mach_descrip_update()) {
		cmn_err(CE_WARN, "MD reload failed\n");
		return;
	}

	recalc_xc_timeouts();

	/*
	 * notify registered clients that MD has
	 * been updated
	 */
	mdeg_notify_clients();

	resp_msg.req_num = msg->req_num;
	resp_msg.result = MD_UPDATE_SUCCESS;
	if ((rv = ds_cap_send(ds_handle, &resp_msg, sizeof (resp_msg))) != 0) {
		cmn_err(CE_NOTE, "md ds_cap_send resp failed (%d)", rv);
	}
}
/*
 * Initialize the kernel's Machine Description(MD) framework
 * after the the VM system has been initialized.
 *
 * Also get the most recent version of the MD.
 * Assumes that the machine description frame work is in a clean
 * state and the machine description intialized during startup
 * has been cleaned up and resources deallocated.
 */
void
mach_descrip_init(void)
{
	ASSERT((curr_mach_descrip == NULL &&
	    curr_mach_descrip_memops == NULL));

	curr_mach_descrip_memops = &mach_descrip_memops;

	curr_mach_descrip = new_mach_descrip();
	if (curr_mach_descrip == NULL)
		panic("Allocation for machine description failed\n");

	if (mach_descrip_update())
		panic("Machine description intialization failed\n");

	/* read in global params */
	init_md_params();
}
/*
 * Initialize the kernel's Machine Description(MD) framework
 * early on in startup during mlsetup() so consumers
 * can get to the MD before the VM system has been initialized.
 *
 * Also get the most recent version of the MD.
 */
void
mach_descrip_startup_init(void)
{

	mutex_init(&curr_mach_descrip_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&obs_list_lock, NULL, MUTEX_DRIVER, NULL);

	obs_machine_descrip_list = NULL;

	curr_mach_descrip_memops = &startup_memops;

	curr_mach_descrip = new_mach_descrip();
	if (curr_mach_descrip == NULL)
		panic("Allocation for machine description failed\n");

	if (mach_descrip_update())
		panic("Machine description initialization failed\n");

}
Exemple #4
0
/*ARGSUSED*/
int
suspend_start(char *error_reason, size_t max_reason_len)
{
	uint64_t	source_tick;
	uint64_t	source_stick;
	uint64_t	rv;
	timestruc_t	source_tod;
	int		spl;

	ASSERT(suspend_supported());
	DBG("suspend: %s", __func__);

	sfmmu_ctxdoms_lock();

	mutex_enter(&cpu_lock);

	/* Suspend the watchdog */
	watchdog_suspend();

	/* Record the TOD */
	mutex_enter(&tod_lock);
	source_tod = tod_get();
	mutex_exit(&tod_lock);

	/* Pause all other CPUs */
	pause_cpus(NULL);
	DBG_PROM("suspend: CPUs paused\n");

	/* Suspend cyclics */
	cyclic_suspend();
	DBG_PROM("suspend: cyclics suspended\n");

	/* Disable interrupts */
	spl = spl8();
	DBG_PROM("suspend: spl8()\n");

	source_tick = gettick_counter();
	source_stick = gettick();
	DBG_PROM("suspend: source_tick: 0x%lx\n", source_tick);
	DBG_PROM("suspend: source_stick: 0x%lx\n", source_stick);

	/*
	 * Call into the HV to initiate the suspend. hv_guest_suspend()
	 * returns after the guest has been resumed or if the suspend
	 * operation failed or was cancelled. After a successful suspend,
	 * the %tick and %stick registers may have changed by an amount
	 * that is not proportional to the amount of time that has passed.
	 * They may have jumped forwards or backwards. Some variation is
	 * allowed and accounted for using suspend_tick_stick_max_delta,
	 * but otherwise this jump must be uniform across all CPUs and we
	 * operate under the assumption that it is (maintaining two global
	 * offset variables--one for %tick and one for %stick.)
	 */
	DBG_PROM("suspend: suspending... \n");
	rv = hv_guest_suspend();
	if (rv != 0) {
		splx(spl);
		cyclic_resume();
		start_cpus();
		watchdog_resume();
		mutex_exit(&cpu_lock);
		sfmmu_ctxdoms_unlock();
		DBG("suspend: failed, rv: %ld\n", rv);
		return (rv);
	}

	suspend_count++;

	/* Update the global tick and stick offsets and the preserved TOD */
	set_tick_offsets(source_tick, source_stick, &source_tod);

	/* Ensure new offsets are globally visible before resuming CPUs */
	membar_sync();

	/* Enable interrupts */
	splx(spl);

	/* Set the {%tick,%stick}.NPT bits on all CPUs */
	if (enable_user_tick_stick_emulation) {
		xc_all((xcfunc_t *)enable_tick_stick_npt, NULL, NULL);
		xt_sync(cpu_ready_set);
		ASSERT(gettick_npt() != 0);
		ASSERT(getstick_npt() != 0);
	}

	/* If emulation is enabled, but not currently active, enable it */
	if (enable_user_tick_stick_emulation && !tick_stick_emulation_active) {
		tick_stick_emulation_active = B_TRUE;
	}

	sfmmu_ctxdoms_remove();

	/* Resume cyclics, unpause CPUs */
	cyclic_resume();
	start_cpus();

	/* Set the TOD */
	mutex_enter(&tod_lock);
	tod_set(source_tod);
	mutex_exit(&tod_lock);

	/* Re-enable the watchdog */
	watchdog_resume();

	mutex_exit(&cpu_lock);

	/* Download the latest MD */
	if ((rv = mach_descrip_update()) != 0)
		cmn_err(CE_PANIC, "suspend: mach_descrip_update failed: %ld",
		    rv);

	sfmmu_ctxdoms_update();
	sfmmu_ctxdoms_unlock();

	/* Get new MD, update CPU mappings/relationships */
	if (suspend_update_cpu_mappings)
		update_cpu_mappings();

	DBG("suspend: target tick: 0x%lx", gettick_counter());
	DBG("suspend: target stick: 0x%llx", gettick());
	DBG("suspend: user %%tick/%%stick emulation is %d",
	    tick_stick_emulation_active);
	DBG("suspend: finished");

	return (0);
}