Path: blob/master/tools/testing/selftests/kexec/test_kexec_jump.c
26285 views
#include <unistd.h>1#include <errno.h>2#include <stdio.h>3#include <stdlib.h>4#include <linux/kexec.h>5#include <linux/reboot.h>6#include <sys/reboot.h>7#include <sys/syscall.h>89asm(10" .code64\n"11" .data\n"12"purgatory_start:\n"1314// Trigger kexec debug exception handling15" int3\n"1617// Set load address for next time18" leaq purgatory_start_b(%rip), %r11\n"19" movq %r11, 8(%rsp)\n"2021// Back to Linux22" ret\n"2324// Same again25"purgatory_start_b:\n"2627// Trigger kexec debug exception handling28" int3\n"2930// Set load address for next time31" leaq purgatory_start(%rip), %r11\n"32" movq %r11, 8(%rsp)\n"3334// Back to Linux35" ret\n"3637"purgatory_end:\n"38".previous"39);40extern char purgatory_start[], purgatory_end[];4142int main (void)43{44struct kexec_segment segment = {};45int ret;4647segment.buf = purgatory_start;48segment.bufsz = purgatory_end - purgatory_start;49segment.mem = (void *)0x400000;50segment.memsz = 0x1000;51ret = syscall(__NR_kexec_load, 0x400000, 1, &segment, KEXEC_PRESERVE_CONTEXT);52if (ret) {53perror("kexec_load");54exit(1);55}5657ret = syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_KEXEC);58if (ret) {59perror("kexec reboot");60exit(1);61}6263ret = syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_KEXEC);64if (ret) {65perror("kexec reboot");66exit(1);67}68printf("Success\n");69return 0;70}71727374