1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2025 Juniper Networks, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <machine/asmacros.h> 29#include <machine/specialreg.h> 30#include "assym.inc" 31 32/* 33 * Take a pointer to the image, copy each segment, and jump to the trampoline. 34 * 35 * Assumptions: 36 * - image is in safe memory 37 * - We're already running out of the new "identity" map. 38 * - All registers are free game, so go nuts 39 * - Interrupts are disabled 40 * - All APs are disabled 41 */ 42ENTRY(kexec_do_reboot) 43 /* 44 r9: image pointer 45 r10: segment pointer 46 r11: segment counter 47 */ 48 leaq kexec_stack(%rip), %rsp 49 /* Get the saved kexec_image. */ 50 leaq kexec_saved_image(%rip), %r9 51 leaq KEXEC_SEGMENTS(%r9), %r10 52 movq $KEXEC_SEGMENT_MAX, %r11 53copy_segment: 54 movq KEXEC_SEGMENT_SIZE(%r10), %rcx 55 cmpq $0, %rcx 56 je done 57 shrq $3, %rcx 58 movq KEXEC_SEGMENT_TARGET(%r10), %rdi 59 movq KEXEC_SEGMENT_MAP(%r10), %rsi 60 rep 61 movsq 62 addq $KEXEC_STAGED_SEGMENT_SIZE, %r10 63 decq %r11 64 jg copy_segment 65 66done: 67 pushq KEXEC_ENTRY(%r9) 68 ret 69fail: 70 jmp fail 71END(kexec_do_reboot) 72ENTRY(kexec_do_reboot_trampoline) 73 /* Set new page table, clears most of TLB. */ 74 movq %rdi, %cr3 75 76 /* Now flush the rest of the TLB, including global pages. */ 77 movq %cr4, %rax 78 andq $~CR4_PGE, %rax 79 movq %rax, %cr4 80 jmp *%rsi 81END(kexec_do_reboot_trampoline) 82CNAME(kexec_saved_image): 83 .globl kexec_saved_image 84 .space KEXEC_IMAGE_SIZE 85 .quad 0 86 /* We don't need more than quad, so just fill out the page. */ 87 .p2align PAGE_SHIFT 88 kexec_stack: 89CNAME(kexec_do_reboot_size): 90 .globl kexec_do_reboot_size 91 .quad . - kexec_do_reboot 92 93 .section .note.GNU-stack,"",%progbits 94