1 #ifndef _ASM_X86_KEXEC_H 2 #define _ASM_X86_KEXEC_H 3 4 #ifdef CONFIG_X86_32 5 # define PA_CONTROL_PAGE 0 6 # define VA_CONTROL_PAGE 1 7 # define PA_PGD 2 8 # define PA_SWAP_PAGE 3 9 # define PAGES_NR 4 10 #else 11 # define PA_CONTROL_PAGE 0 12 # define VA_CONTROL_PAGE 1 13 # define PA_TABLE_PAGE 2 14 # define PA_SWAP_PAGE 3 15 # define PAGES_NR 4 16 #endif 17 18 # define KEXEC_CONTROL_CODE_MAX_SIZE 2048 19 20 #ifndef __ASSEMBLY__ 21 22 #include <linux/string.h> 23 24 #include <asm/page.h> 25 #include <asm/ptrace.h> 26 #include <asm/bootparam.h> 27 28 struct kimage; 29 30 /* 31 * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. 32 * I.e. Maximum page that is mapped directly into kernel memory, 33 * and kmap is not required. 34 * 35 * So far x86_64 is limited to 40 physical address bits. 36 */ 37 #ifdef CONFIG_X86_32 38 /* Maximum physical address we can use pages from */ 39 # define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) 40 /* Maximum address we can reach in physical address mode */ 41 # define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) 42 /* Maximum address we can use for the control code buffer */ 43 # define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE 44 45 # define KEXEC_CONTROL_PAGE_SIZE 4096 46 47 /* The native architecture */ 48 # define KEXEC_ARCH KEXEC_ARCH_386 49 50 /* We can also handle crash dumps from 64 bit kernel. */ 51 # define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) 52 #else 53 /* Maximum physical address we can use pages from */ 54 # define KEXEC_SOURCE_MEMORY_LIMIT (MAXMEM-1) 55 /* Maximum address we can reach in physical address mode */ 56 # define KEXEC_DESTINATION_MEMORY_LIMIT (MAXMEM-1) 57 /* Maximum address we can use for the control pages */ 58 # define KEXEC_CONTROL_MEMORY_LIMIT (MAXMEM-1) 59 60 /* Allocate one page for the pdp and the second for the code */ 61 # define KEXEC_CONTROL_PAGE_SIZE (4096UL + 4096UL) 62 63 /* The native architecture */ 64 # define KEXEC_ARCH KEXEC_ARCH_X86_64 65 #endif 66 67 /* Memory to backup during crash kdump */ 68 #define KEXEC_BACKUP_SRC_START (0UL) 69 #define KEXEC_BACKUP_SRC_END (640 * 1024UL) /* 640K */ 70 71 /* 72 * CPU does not save ss and sp on stack if execution is already 73 * running in kernel mode at the time of NMI occurrence. This code 74 * fixes it. 75 */ 76 static inline void crash_fixup_ss_esp(struct pt_regs *newregs, 77 struct pt_regs *oldregs) 78 { 79 #ifdef CONFIG_X86_32 80 newregs->sp = (unsigned long)&(oldregs->sp); 81 asm volatile("xorl %%eax, %%eax\n\t" 82 "movw %%ss, %%ax\n\t" 83 :"=a"(newregs->ss)); 84 #endif 85 } 86 87 /* 88 * This function is responsible for capturing register states if coming 89 * via panic otherwise just fix up the ss and sp if coming via kernel 90 * mode exception. 91 */ 92 static inline void crash_setup_regs(struct pt_regs *newregs, 93 struct pt_regs *oldregs) 94 { 95 if (oldregs) { 96 memcpy(newregs, oldregs, sizeof(*newregs)); 97 crash_fixup_ss_esp(newregs, oldregs); 98 } else { 99 #ifdef CONFIG_X86_32 100 asm volatile("movl %%ebx,%0" : "=m"(newregs->bx)); 101 asm volatile("movl %%ecx,%0" : "=m"(newregs->cx)); 102 asm volatile("movl %%edx,%0" : "=m"(newregs->dx)); 103 asm volatile("movl %%esi,%0" : "=m"(newregs->si)); 104 asm volatile("movl %%edi,%0" : "=m"(newregs->di)); 105 asm volatile("movl %%ebp,%0" : "=m"(newregs->bp)); 106 asm volatile("movl %%eax,%0" : "=m"(newregs->ax)); 107 asm volatile("movl %%esp,%0" : "=m"(newregs->sp)); 108 asm volatile("movl %%ss, %%eax;" :"=a"(newregs->ss)); 109 asm volatile("movl %%cs, %%eax;" :"=a"(newregs->cs)); 110 asm volatile("movl %%ds, %%eax;" :"=a"(newregs->ds)); 111 asm volatile("movl %%es, %%eax;" :"=a"(newregs->es)); 112 asm volatile("pushfl; popl %0" :"=m"(newregs->flags)); 113 #else 114 asm volatile("movq %%rbx,%0" : "=m"(newregs->bx)); 115 asm volatile("movq %%rcx,%0" : "=m"(newregs->cx)); 116 asm volatile("movq %%rdx,%0" : "=m"(newregs->dx)); 117 asm volatile("movq %%rsi,%0" : "=m"(newregs->si)); 118 asm volatile("movq %%rdi,%0" : "=m"(newregs->di)); 119 asm volatile("movq %%rbp,%0" : "=m"(newregs->bp)); 120 asm volatile("movq %%rax,%0" : "=m"(newregs->ax)); 121 asm volatile("movq %%rsp,%0" : "=m"(newregs->sp)); 122 asm volatile("movq %%r8,%0" : "=m"(newregs->r8)); 123 asm volatile("movq %%r9,%0" : "=m"(newregs->r9)); 124 asm volatile("movq %%r10,%0" : "=m"(newregs->r10)); 125 asm volatile("movq %%r11,%0" : "=m"(newregs->r11)); 126 asm volatile("movq %%r12,%0" : "=m"(newregs->r12)); 127 asm volatile("movq %%r13,%0" : "=m"(newregs->r13)); 128 asm volatile("movq %%r14,%0" : "=m"(newregs->r14)); 129 asm volatile("movq %%r15,%0" : "=m"(newregs->r15)); 130 asm volatile("movl %%ss, %%eax;" :"=a"(newregs->ss)); 131 asm volatile("movl %%cs, %%eax;" :"=a"(newregs->cs)); 132 asm volatile("pushfq; popq %0" :"=m"(newregs->flags)); 133 #endif 134 newregs->ip = (unsigned long)current_text_addr(); 135 } 136 } 137 138 #ifdef CONFIG_X86_32 139 asmlinkage unsigned long 140 relocate_kernel(unsigned long indirection_page, 141 unsigned long control_page, 142 unsigned long start_address, 143 unsigned int has_pae, 144 unsigned int preserve_context); 145 #else 146 unsigned long 147 relocate_kernel(unsigned long indirection_page, 148 unsigned long page_list, 149 unsigned long start_address, 150 unsigned int preserve_context); 151 #endif 152 153 #define ARCH_HAS_KIMAGE_ARCH 154 155 #ifdef CONFIG_X86_32 156 struct kimage_arch { 157 pgd_t *pgd; 158 #ifdef CONFIG_X86_PAE 159 pmd_t *pmd0; 160 pmd_t *pmd1; 161 #endif 162 pte_t *pte0; 163 pte_t *pte1; 164 }; 165 #else 166 struct kimage_arch { 167 pud_t *pud; 168 pmd_t *pmd; 169 pte_t *pte; 170 /* Details of backup region */ 171 unsigned long backup_src_start; 172 unsigned long backup_src_sz; 173 174 /* Physical address of backup segment */ 175 unsigned long backup_load_addr; 176 177 /* Core ELF header buffer */ 178 void *elf_headers; 179 unsigned long elf_headers_sz; 180 unsigned long elf_load_addr; 181 }; 182 #endif /* CONFIG_X86_32 */ 183 184 #ifdef CONFIG_X86_64 185 /* 186 * Number of elements and order of elements in this structure should match 187 * with the ones in arch/x86/purgatory/entry64.S. If you make a change here 188 * make an appropriate change in purgatory too. 189 */ 190 struct kexec_entry64_regs { 191 uint64_t rax; 192 uint64_t rcx; 193 uint64_t rdx; 194 uint64_t rbx; 195 uint64_t rsp; 196 uint64_t rbp; 197 uint64_t rsi; 198 uint64_t rdi; 199 uint64_t r8; 200 uint64_t r9; 201 uint64_t r10; 202 uint64_t r11; 203 uint64_t r12; 204 uint64_t r13; 205 uint64_t r14; 206 uint64_t r15; 207 uint64_t rip; 208 }; 209 #endif 210 211 typedef void crash_vmclear_fn(void); 212 extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; 213 214 #endif /* __ASSEMBLY__ */ 215 216 #endif /* _ASM_X86_KEXEC_H */ 217