xref: /freebsd/sys/amd64/amd64/kexec_tramp.S (revision 755c1e039adfd68ecf4d5954e13fe54263c34a03)
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