static void noinline init_done(void)
{
+ system_state = SYS_STATE_active;
+
+ domain_unpause_by_systemcontroller(hardware_domain);
+
/* Free (or page-protect) the init areas. */
memset(__init_begin, 0xcc, __init_end - __init_begin); /* int3 poison */
free_xen_data(__init_begin, __init_end);
startup_cpu_idle_loop();
}
+/* Reinitalise all state referring to the old virtual address of the stack. */
+static void __init noreturn reinit_bsp_stack(void)
+{
+ unsigned long *stack = (void*)(get_stack_bottom() & ~(STACK_SIZE - 1));
+
+ /* Update TSS and ISTs */
+ load_system_tables();
+
+ /* Update SYSCALL trampolines */
+ percpu_traps_init();
+
+ stack_base[0] = stack;
+ memguard_guard_stack(stack);
+
+ reset_stack_and_jump(init_done);
+}
+
static bool_t __init loader_is_grub2(const char *loader_name)
{
/* GRUB1="GNU GRUB 0.xx"; GRUB2="GRUB 1.xx" */
tboot_probe();
- /* Unmap the first page of CPU0's stack. */
- memguard_guard_stack(cpu0_stack);
-
open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
if ( opt_watchdog )
setup_io_bitmap(dom0);
- system_state = SYS_STATE_active;
-
- domain_unpause_by_systemcontroller(dom0);
-
- reset_stack_and_jump(init_done);
+ /* Jump to the 1:1 virtual mappings of cpu0_stack. */
+ asm volatile ("mov %[stk], %%rsp; jmp %c[fn]" ::
+ [stk] "g" (__va(__pa(get_stack_bottom()))),
+ [fn] "i" (reinit_bsp_stack) : "memory");
+ unreachable();
}
void arch_get_xen_caps(xen_capabilities_info_t *info)
return;
}
- if ( (!is_kernel_text(eip) &&
- (system_state > SYS_STATE_boot || !is_kernel_inittext(eip))) ||
+ if ( !is_active_kernel_text(regs->eip) ||
__copy_from_user(bug_insn, eip, sizeof(bug_insn)) ||
memcmp(bug_insn, "\xf\xb", sizeof(bug_insn)) )
goto die;