예제 #1
0
void
vmmcall_init (void)
{
	n_vmmcall = 0;
	vmmcall_register ("get_vmmcall_number", get_vmmcall_number);
	call_initfunc ("vmmcal");
}
예제 #2
0
u32
prepare_for_sleep (u32 firmware_waking_vector)
{
	u8 *p;
	int wakeup_entry_len;

	/* Get the suspend-lock to make other processors stopping or staying
	   in the guest mode. */
	get_suspend_lock ();

	/* Now the VMM is executed by the current processor only.
	   Call suspend functions. */
	call_initfunc ("suspend");

	/* Initialize variables used by wakeup functions */
	wakeup_cpucount = 0;
	spinlock_init (&wakeup_cpucount_lock);
	waking_vector = firmware_waking_vector;
	wakeup_prepare ();

	/* Copy the wakeup_entry code. */
	wakeup_entry_len = wakeup_entry_end - wakeup_entry_start;
	p = mapmem_hphys (wakeup_entry_addr, wakeup_entry_len, MAPMEM_WRITE);
	memcpy (p, wakeup_entry_start, wakeup_entry_len);
	unmapmem (p, wakeup_entry_len);
	return wakeup_entry_addr;
}
예제 #3
0
void
svm_vminit (void)
{
	current->u.svm.np = NULL;
	svm_vmcb_init ();
	/* svm_msr_init (); */
	if (current->u.svm.vi.vmcb->np_enable)
		svm_np_init ();
	else
		cpu_mmu_spt_init ();
	call_initfunc ("vcpu");
}
예제 #4
0
asmlinkage void
wakeup_cont (void)
{
	static rw_spinlock_t wakeup_wait_lock;

	asm_wrcr3 (currentcpu->cr3);
	call_initfunc ("wakeup");
	if (!currentcpu->cpunum) {
		call_initfunc ("resume");
		rw_spinlock_init (&wakeup_wait_lock);
		rw_spinlock_lock_ex (&wakeup_wait_lock);
		wakeup_ap ();
		rw_spinlock_unlock_ex (&wakeup_wait_lock);
	} else {
		rw_spinlock_lock_sh (&wakeup_wait_lock);
		rw_spinlock_unlock_sh (&wakeup_wait_lock);
	}
	update_mtrr_and_pat ();
	resume_vm (waking_vector);
	panic ("resume_vm failed.");
}
예제 #5
0
static void
do_reboot (void)
{
	call_initfunc ("panic"); /* for disabling VT-x */
	acpi_reset ();
	rebooting = true;
	/*
	asm_outb (0x70, 0x0F);
	asm_outb (0x71, 0x00);
	asm_outb (0x70, 0x00);
	asm_outb (0x64, 0xFE);
	*/
	if (apic_available ()) {
		usleep (1 * 1000000);
		printf ("shutdown\n");
		asm_wridtr (0, 0);
		asm volatile ("int3");
	} else {
예제 #6
0
void
cancel_sleep (void)
{
	release_suspend_lock ();
	call_initfunc ("resume");
}
예제 #7
0
panic (char *format, ...)
{
	u64 time;
	int count;
	va_list ap;
	ulong curstk;
	bool w = false;
	char *p, *pend;
	int cpunum = -1;
	static int panic_count = 0;
	static ulong panic_shell = 0;
	struct panic_pcpu_data_state *state, local_state;

	va_start (ap, format);
	if (currentcpu_available ())
		cpunum = get_cpu_id ();
	if (cpunum >= 0) {
		spinlock_lock (&panic_lock);
		count = panic_count++;
		spinlock_unlock (&panic_lock);
		wait_for_other_cpu (cpunum);
		p = panicmsg_tmp;
		pend = panicmsg_tmp + sizeof panicmsg_tmp;
		if (panic_reboot)
			*p = '\0';
		else
			snprintf (p, pend - p, "panic(CPU%d): ", cpunum);
		p += strlen (p);
		vsnprintf (p, pend - p, format, ap);
		if (*p != '\0') {
			printf ("%s\n", panicmsg_tmp);
			if (panicmsg[0] == '\0')
				snprintf (panicmsg, sizeof panicmsg, "%s",
					  panicmsg_tmp);
		}
		asm_rdrsp (&curstk);
		if (count > 5 ||
		    curstk - (ulong)currentcpu->stackaddr < VMM_MINSTACKSIZE) {
			spinlock_lock (&panic_lock);
			paniccpu = -1;
			spinlock_unlock (&panic_lock);
			freeze ();
		}
		state = &currentcpu->panic.state;
	} else {
		spinlock_lock (&panic_lock);
		count = panic_count++;
		printf ("panic: ");
		vprintf (format, ap);
		printf ("\n");
		spinlock_unlock (&panic_lock);
		if (count)
			freeze ();
		state = &local_state;
		state->dump_vmm = false;
		state->backtrace = false;
		state->flag_dump_vm = false;
	}
	va_end (ap);
	if (!state->dump_vmm) {
		state->dump_vmm = true;
		catch_exception (cpunum, dump_vmm_control_regs);
		catch_exception (cpunum, dump_vmm_other_regs);
		state->dump_vmm = false;
	}
	if (!state->backtrace) {
		state->backtrace = true;
		catch_exception (cpunum, backtrace);
		state->backtrace = false;
	}
	if (cpunum >= 0 && current && !state->flag_dump_vm) {
		/* Guest state is printed only once.  Because the
		 * state will not change if panic will have been
		 * called twice or more. */
		state->flag_dump_vm = true;
		printf ("Guest state and registers of cpu %d ------------\n",
			cpunum);
		catch_exception (cpunum, dump_vm_general_regs);
		catch_exception (cpunum, dump_vm_control_regs);
		catch_exception (cpunum, dump_vm_sregs);
		catch_exception (cpunum, dump_vm_other_regs);
		printf ("------------------------------------------------\n");
	}
	if (cpunum < 0)
		freeze ();
	if (do_wakeup) {
		do_wakeup = false;
		w = true;
	}
	spinlock_lock (&panic_lock);
	paniccpu = -1;
	spinlock_unlock (&panic_lock);
	if (w) {
		sleep_set_timer_counter ();
		panic_wakeup_all ();
	}
	call_initfunc ("panic");
	if (cpunum == 0) {
		usleep (1000000);	/* wait for dump of other processors */
#ifndef TTY_SERIAL
		setkbdled (LED_NUMLOCK_BIT | LED_SCROLLLOCK_BIT |
			   LED_CAPSLOCK_BIT);
		if (!uefi_booted) {
			disable_apic ();
			if (bios_area_saved)
				copy_bios_area (bios_area_panic,
						bios_area_orig);
			callrealmode_setvideomode
				(VIDEOMODE_80x25TEXT_16COLORS);
			if (bios_area_saved)
				copy_bios_area (NULL, bios_area_panic);
			if (panic_reboot)
				printf ("%s\n", panicmsg);
		}
		keyboard_reset ();
		usleep (250000);
		setkbdled (LED_SCROLLLOCK_BIT | LED_CAPSLOCK_BIT);
#endif
	} else {
		/* setvideomode is expected to be done in 3 seconds */
		time = get_time ();
		while (get_time () - time < 3000000);
	}
	if (asm_lock_ulong_swap (&panic_shell, 1)) {
		for (;;)
			reboot_test ();
		clihlt ();
	}
	if (panic_reboot)
		do_panic_reboot ();
	printf ("%s\n", panicmsg);
	call_panic_shell ();
}