Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/kernel/kexec.c
26289 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
#include <linux/kernel.h>
4
#include <linux/console.h>
5
#include <linux/kexec.h>
6
#include <linux/delay.h>
7
#include <linux/reboot.h>
8
9
#include <asm/cacheflush.h>
10
#include <asm/sections.h>
11
12
extern void relocate_new_kernel(unsigned long head,
13
unsigned long start,
14
unsigned long phys);
15
16
extern const unsigned int relocate_new_kernel_size;
17
extern unsigned int kexec_initrd_start_offset;
18
extern unsigned int kexec_initrd_end_offset;
19
extern unsigned int kexec_cmdline_offset;
20
extern unsigned int kexec_free_mem_offset;
21
22
static void kexec_show_segment_info(const struct kimage *kimage,
23
unsigned long n)
24
{
25
pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
26
n,
27
kimage->segment[n].mem,
28
kimage->segment[n].mem + kimage->segment[n].memsz,
29
(unsigned long)kimage->segment[n].memsz,
30
(unsigned long)kimage->segment[n].memsz / PAGE_SIZE);
31
}
32
33
static void kexec_image_info(const struct kimage *kimage)
34
{
35
unsigned long i;
36
37
pr_debug("kexec kimage info:\n");
38
pr_debug(" type: %d\n", kimage->type);
39
pr_debug(" start: %lx\n", kimage->start);
40
pr_debug(" head: %lx\n", kimage->head);
41
pr_debug(" nr_segments: %lu\n", kimage->nr_segments);
42
43
for (i = 0; i < kimage->nr_segments; i++)
44
kexec_show_segment_info(kimage, i);
45
46
#ifdef CONFIG_KEXEC_FILE
47
if (kimage->file_mode) {
48
pr_debug("cmdline: %.*s\n", (int)kimage->cmdline_buf_len,
49
kimage->cmdline_buf);
50
}
51
#endif
52
}
53
54
void machine_kexec_cleanup(struct kimage *kimage)
55
{
56
}
57
58
void machine_crash_shutdown(struct pt_regs *regs)
59
{
60
}
61
62
void machine_shutdown(void)
63
{
64
smp_send_stop();
65
while (num_online_cpus() > 1) {
66
cpu_relax();
67
mdelay(1);
68
}
69
}
70
71
void machine_kexec(struct kimage *image)
72
{
73
#ifdef CONFIG_64BIT
74
Elf64_Fdesc desc;
75
#endif
76
void (*reloc)(unsigned long head,
77
unsigned long start,
78
unsigned long phys);
79
80
unsigned long phys = page_to_phys(image->control_code_page);
81
void *virt = (void *)__fix_to_virt(FIX_TEXT_KEXEC);
82
struct kimage_arch *arch = &image->arch;
83
84
set_fixmap(FIX_TEXT_KEXEC, phys);
85
86
flush_cache_all();
87
88
#ifdef CONFIG_64BIT
89
reloc = (void *)&desc;
90
desc.addr = (long long)virt;
91
#else
92
reloc = (void *)virt;
93
#endif
94
95
memcpy(virt, dereference_function_descriptor(relocate_new_kernel),
96
relocate_new_kernel_size);
97
98
*(unsigned long *)(virt + kexec_cmdline_offset) = arch->cmdline;
99
*(unsigned long *)(virt + kexec_initrd_start_offset) = arch->initrd_start;
100
*(unsigned long *)(virt + kexec_initrd_end_offset) = arch->initrd_end;
101
*(unsigned long *)(virt + kexec_free_mem_offset) = PAGE0->mem_free;
102
103
flush_cache_all();
104
flush_tlb_all();
105
local_irq_disable();
106
107
reloc(image->head & PAGE_MASK, image->start, phys);
108
}
109
110
int machine_kexec_prepare(struct kimage *image)
111
{
112
kexec_image_info(image);
113
return 0;
114
}
115
116