LCOV - code coverage report
Current view: top level - arch/x86/kernel - machine_kexec_64.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 194 0.0 %
Date: 2022-04-01 14:35:51 Functions: 0 16 0.0 %
Branches: 0 84 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * handle transition of Linux booting another kernel
       4                 :            :  * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
       5                 :            :  */
       6                 :            : 
       7                 :            : #define pr_fmt(fmt)     "kexec: " fmt
       8                 :            : 
       9                 :            : #include <linux/mm.h>
      10                 :            : #include <linux/kexec.h>
      11                 :            : #include <linux/string.h>
      12                 :            : #include <linux/gfp.h>
      13                 :            : #include <linux/reboot.h>
      14                 :            : #include <linux/numa.h>
      15                 :            : #include <linux/ftrace.h>
      16                 :            : #include <linux/io.h>
      17                 :            : #include <linux/suspend.h>
      18                 :            : #include <linux/vmalloc.h>
      19                 :            : #include <linux/efi.h>
      20                 :            : 
      21                 :            : #include <asm/init.h>
      22                 :            : #include <asm/pgtable.h>
      23                 :            : #include <asm/tlbflush.h>
      24                 :            : #include <asm/mmu_context.h>
      25                 :            : #include <asm/io_apic.h>
      26                 :            : #include <asm/debugreg.h>
      27                 :            : #include <asm/kexec-bzimage64.h>
      28                 :            : #include <asm/setup.h>
      29                 :            : #include <asm/set_memory.h>
      30                 :            : 
      31                 :            : #ifdef CONFIG_ACPI
      32                 :            : /*
      33                 :            :  * Used while adding mapping for ACPI tables.
      34                 :            :  * Can be reused when other iomem regions need be mapped
      35                 :            :  */
      36                 :            : struct init_pgtable_data {
      37                 :            :         struct x86_mapping_info *info;
      38                 :            :         pgd_t *level4p;
      39                 :            : };
      40                 :            : 
      41                 :          0 : static int mem_region_callback(struct resource *res, void *arg)
      42                 :            : {
      43                 :          0 :         struct init_pgtable_data *data = arg;
      44                 :          0 :         unsigned long mstart, mend;
      45                 :            : 
      46                 :          0 :         mstart = res->start;
      47                 :          0 :         mend = mstart + resource_size(res) - 1;
      48                 :            : 
      49                 :          0 :         return kernel_ident_mapping_init(data->info, data->level4p, mstart, mend);
      50                 :            : }
      51                 :            : 
      52                 :            : static int
      53                 :          0 : map_acpi_tables(struct x86_mapping_info *info, pgd_t *level4p)
      54                 :            : {
      55                 :          0 :         struct init_pgtable_data data;
      56                 :          0 :         unsigned long flags;
      57                 :          0 :         int ret;
      58                 :            : 
      59                 :          0 :         data.info = info;
      60                 :          0 :         data.level4p = level4p;
      61                 :          0 :         flags = IORESOURCE_MEM | IORESOURCE_BUSY;
      62                 :            : 
      63                 :          0 :         ret = walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1,
      64                 :            :                                   &data, mem_region_callback);
      65         [ #  # ]:          0 :         if (ret && ret != -EINVAL)
      66                 :            :                 return ret;
      67                 :            : 
      68                 :            :         /* ACPI tables could be located in ACPI Non-volatile Storage region */
      69                 :          0 :         ret = walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1,
      70                 :            :                                   &data, mem_region_callback);
      71         [ #  # ]:          0 :         if (ret && ret != -EINVAL)
      72                 :          0 :                 return ret;
      73                 :            : 
      74                 :            :         return 0;
      75                 :            : }
      76                 :            : #else
      77                 :            : static int map_acpi_tables(struct x86_mapping_info *info, pgd_t *level4p) { return 0; }
      78                 :            : #endif
      79                 :            : 
      80                 :            : #ifdef CONFIG_KEXEC_FILE
      81                 :            : const struct kexec_file_ops * const kexec_file_loaders[] = {
      82                 :            :                 &kexec_bzImage64_ops,
      83                 :            :                 NULL
      84                 :            : };
      85                 :            : #endif
      86                 :            : 
      87                 :            : static int
      88                 :          0 : map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)
      89                 :            : {
      90                 :            : #ifdef CONFIG_EFI
      91                 :          0 :         unsigned long mstart, mend;
      92                 :            : 
      93         [ #  # ]:          0 :         if (!efi_enabled(EFI_BOOT))
      94                 :            :                 return 0;
      95                 :            : 
      96                 :          0 :         mstart = (boot_params.efi_info.efi_systab |
      97                 :          0 :                         ((u64)boot_params.efi_info.efi_systab_hi<<32));
      98                 :            : 
      99         [ #  # ]:          0 :         if (efi_enabled(EFI_64BIT))
     100                 :          0 :                 mend = mstart + sizeof(efi_system_table_64_t);
     101                 :            :         else
     102                 :          0 :                 mend = mstart + sizeof(efi_system_table_32_t);
     103                 :            : 
     104         [ #  # ]:          0 :         if (!mstart)
     105                 :            :                 return 0;
     106                 :            : 
     107                 :          0 :         return kernel_ident_mapping_init(info, level4p, mstart, mend);
     108                 :            : #endif
     109                 :            :         return 0;
     110                 :            : }
     111                 :            : 
     112                 :          0 : static void free_transition_pgtable(struct kimage *image)
     113                 :            : {
     114                 :          0 :         free_page((unsigned long)image->arch.p4d);
     115                 :          0 :         image->arch.p4d = NULL;
     116                 :          0 :         free_page((unsigned long)image->arch.pud);
     117                 :          0 :         image->arch.pud = NULL;
     118                 :          0 :         free_page((unsigned long)image->arch.pmd);
     119                 :          0 :         image->arch.pmd = NULL;
     120                 :          0 :         free_page((unsigned long)image->arch.pte);
     121                 :          0 :         image->arch.pte = NULL;
     122                 :          0 : }
     123                 :            : 
     124                 :          0 : static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
     125                 :            : {
     126                 :          0 :         pgprot_t prot = PAGE_KERNEL_EXEC_NOENC;
     127                 :          0 :         unsigned long vaddr, paddr;
     128                 :          0 :         int result = -ENOMEM;
     129                 :          0 :         p4d_t *p4d;
     130                 :          0 :         pud_t *pud;
     131                 :          0 :         pmd_t *pmd;
     132                 :          0 :         pte_t *pte;
     133                 :            : 
     134                 :          0 :         vaddr = (unsigned long)relocate_kernel;
     135         [ #  # ]:          0 :         paddr = __pa(page_address(image->control_code_page)+PAGE_SIZE);
     136                 :          0 :         pgd += pgd_index(vaddr);
     137         [ #  # ]:          0 :         if (!pgd_present(*pgd)) {
     138                 :          0 :                 p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL);
     139         [ #  # ]:          0 :                 if (!p4d)
     140                 :          0 :                         goto err;
     141                 :          0 :                 image->arch.p4d = p4d;
     142         [ #  # ]:          0 :                 set_pgd(pgd, __pgd(__pa(p4d) | _KERNPG_TABLE));
     143                 :            :         }
     144                 :          0 :         p4d = p4d_offset(pgd, vaddr);
     145         [ #  # ]:          0 :         if (!p4d_present(*p4d)) {
     146                 :          0 :                 pud = (pud_t *)get_zeroed_page(GFP_KERNEL);
     147         [ #  # ]:          0 :                 if (!pud)
     148                 :          0 :                         goto err;
     149                 :          0 :                 image->arch.pud = pud;
     150         [ #  # ]:          0 :                 set_p4d(p4d, __p4d(__pa(pud) | _KERNPG_TABLE));
     151                 :            :         }
     152         [ #  # ]:          0 :         pud = pud_offset(p4d, vaddr);
     153   [ #  #  #  # ]:          0 :         if (!pud_present(*pud)) {
     154                 :          0 :                 pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL);
     155         [ #  # ]:          0 :                 if (!pmd)
     156                 :          0 :                         goto err;
     157                 :          0 :                 image->arch.pmd = pmd;
     158         [ #  # ]:          0 :                 set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
     159                 :            :         }
     160         [ #  # ]:          0 :         pmd = pmd_offset(pud, vaddr);
     161   [ #  #  #  # ]:          0 :         if (!pmd_present(*pmd)) {
     162                 :          0 :                 pte = (pte_t *)get_zeroed_page(GFP_KERNEL);
     163         [ #  # ]:          0 :                 if (!pte)
     164                 :          0 :                         goto err;
     165                 :          0 :                 image->arch.pte = pte;
     166         [ #  # ]:          0 :                 set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
     167                 :            :         }
     168         [ #  # ]:          0 :         pte = pte_offset_kernel(pmd, vaddr);
     169                 :            : 
     170         [ #  # ]:          0 :         if (sev_active())
     171                 :            :                 prot = PAGE_KERNEL_EXEC;
     172                 :            : 
     173         [ #  # ]:          0 :         set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, prot));
     174                 :          0 :         return 0;
     175                 :            : err:
     176                 :            :         return result;
     177                 :            : }
     178                 :            : 
     179                 :          0 : static void *alloc_pgt_page(void *data)
     180                 :            : {
     181                 :          0 :         struct kimage *image = (struct kimage *)data;
     182                 :          0 :         struct page *page;
     183                 :          0 :         void *p = NULL;
     184                 :            : 
     185                 :          0 :         page = kimage_alloc_control_pages(image, 0);
     186         [ #  # ]:          0 :         if (page) {
     187                 :          0 :                 p = page_address(page);
     188                 :          0 :                 clear_page(p);
     189                 :            :         }
     190                 :            : 
     191                 :          0 :         return p;
     192                 :            : }
     193                 :            : 
     194                 :          0 : static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
     195                 :            : {
     196                 :          0 :         struct x86_mapping_info info = {
     197                 :            :                 .alloc_pgt_page = alloc_pgt_page,
     198                 :            :                 .context        = image,
     199                 :            :                 .page_flag      = __PAGE_KERNEL_LARGE_EXEC,
     200                 :            :                 .kernpg_flag    = _KERNPG_TABLE_NOENC,
     201                 :            :         };
     202                 :          0 :         unsigned long mstart, mend;
     203                 :          0 :         pgd_t *level4p;
     204                 :          0 :         int result;
     205                 :          0 :         int i;
     206                 :            : 
     207                 :          0 :         level4p = (pgd_t *)__va(start_pgtable);
     208                 :          0 :         clear_page(level4p);
     209                 :            : 
     210         [ #  # ]:          0 :         if (sev_active()) {
     211                 :            :                 info.page_flag   |= _PAGE_ENC;
     212                 :            :                 info.kernpg_flag |= _PAGE_ENC;
     213                 :            :         }
     214                 :            : 
     215         [ #  # ]:          0 :         if (direct_gbpages)
     216                 :          0 :                 info.direct_gbpages = true;
     217                 :            : 
     218         [ #  # ]:          0 :         for (i = 0; i < nr_pfn_mapped; i++) {
     219                 :          0 :                 mstart = pfn_mapped[i].start << PAGE_SHIFT;
     220                 :          0 :                 mend   = pfn_mapped[i].end << PAGE_SHIFT;
     221                 :            : 
     222                 :          0 :                 result = kernel_ident_mapping_init(&info,
     223                 :            :                                                  level4p, mstart, mend);
     224         [ #  # ]:          0 :                 if (result)
     225                 :          0 :                         return result;
     226                 :            :         }
     227                 :            : 
     228                 :            :         /*
     229                 :            :          * segments's mem ranges could be outside 0 ~ max_pfn,
     230                 :            :          * for example when jump back to original kernel from kexeced kernel.
     231                 :            :          * or first kernel is booted with user mem map, and second kernel
     232                 :            :          * could be loaded out of that range.
     233                 :            :          */
     234         [ #  # ]:          0 :         for (i = 0; i < image->nr_segments; i++) {
     235                 :          0 :                 mstart = image->segment[i].mem;
     236                 :          0 :                 mend   = mstart + image->segment[i].memsz;
     237                 :            : 
     238                 :          0 :                 result = kernel_ident_mapping_init(&info,
     239                 :            :                                                  level4p, mstart, mend);
     240                 :            : 
     241         [ #  # ]:          0 :                 if (result)
     242                 :          0 :                         return result;
     243                 :            :         }
     244                 :            : 
     245                 :            :         /*
     246                 :            :          * Prepare EFI systab and ACPI tables for kexec kernel since they are
     247                 :            :          * not covered by pfn_mapped.
     248                 :            :          */
     249                 :          0 :         result = map_efi_systab(&info, level4p);
     250         [ #  # ]:          0 :         if (result)
     251                 :            :                 return result;
     252                 :            : 
     253                 :          0 :         result = map_acpi_tables(&info, level4p);
     254         [ #  # ]:          0 :         if (result)
     255                 :            :                 return result;
     256                 :            : 
     257                 :          0 :         return init_transition_pgtable(image, level4p);
     258                 :            : }
     259                 :            : 
     260                 :          0 : static void set_idt(void *newidt, u16 limit)
     261                 :            : {
     262                 :          0 :         struct desc_ptr curidt;
     263                 :            : 
     264                 :            :         /* x86-64 supports unaliged loads & stores */
     265                 :          0 :         curidt.size    = limit;
     266                 :          0 :         curidt.address = (unsigned long)newidt;
     267                 :            : 
     268                 :          0 :         __asm__ __volatile__ (
     269                 :            :                 "lidtq %0\n"
     270                 :            :                 : : "m" (curidt)
     271                 :            :                 );
     272                 :            : };
     273                 :            : 
     274                 :            : 
     275                 :          0 : static void set_gdt(void *newgdt, u16 limit)
     276                 :            : {
     277                 :          0 :         struct desc_ptr curgdt;
     278                 :            : 
     279                 :            :         /* x86-64 supports unaligned loads & stores */
     280                 :          0 :         curgdt.size    = limit;
     281                 :          0 :         curgdt.address = (unsigned long)newgdt;
     282                 :            : 
     283                 :          0 :         __asm__ __volatile__ (
     284                 :            :                 "lgdtq %0\n"
     285                 :            :                 : : "m" (curgdt)
     286                 :            :                 );
     287                 :            : };
     288                 :            : 
     289                 :          0 : static void load_segments(void)
     290                 :            : {
     291                 :          0 :         __asm__ __volatile__ (
     292                 :            :                 "\tmovl %0,%%ds\n"
     293                 :            :                 "\tmovl %0,%%es\n"
     294                 :            :                 "\tmovl %0,%%ss\n"
     295                 :            :                 "\tmovl %0,%%fs\n"
     296                 :            :                 "\tmovl %0,%%gs\n"
     297                 :            :                 : : "a" (__KERNEL_DS) : "memory"
     298                 :            :                 );
     299                 :            : }
     300                 :            : 
     301                 :          0 : int machine_kexec_prepare(struct kimage *image)
     302                 :            : {
     303                 :          0 :         unsigned long start_pgtable;
     304                 :          0 :         int result;
     305                 :            : 
     306                 :            :         /* Calculate the offsets */
     307                 :          0 :         start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
     308                 :            : 
     309                 :            :         /* Setup the identity mapped 64bit page table */
     310                 :          0 :         result = init_pgtable(image, start_pgtable);
     311         [ #  # ]:          0 :         if (result)
     312                 :          0 :                 return result;
     313                 :            : 
     314                 :            :         return 0;
     315                 :            : }
     316                 :            : 
     317                 :          0 : void machine_kexec_cleanup(struct kimage *image)
     318                 :            : {
     319                 :          0 :         free_transition_pgtable(image);
     320                 :          0 : }
     321                 :            : 
     322                 :            : /*
     323                 :            :  * Do not allocate memory (or fail in any way) in machine_kexec().
     324                 :            :  * We are past the point of no return, committed to rebooting now.
     325                 :            :  */
     326                 :          0 : void machine_kexec(struct kimage *image)
     327                 :            : {
     328                 :          0 :         unsigned long page_list[PAGES_NR];
     329                 :          0 :         void *control_page;
     330                 :          0 :         int save_ftrace_enabled;
     331                 :            : 
     332                 :            : #ifdef CONFIG_KEXEC_JUMP
     333                 :            :         if (image->preserve_context)
     334                 :            :                 save_processor_state();
     335                 :            : #endif
     336                 :            : 
     337                 :          0 :         save_ftrace_enabled = __ftrace_enabled_save();
     338                 :            : 
     339                 :            :         /* Interrupts aren't acceptable while we reboot */
     340                 :          0 :         local_irq_disable();
     341                 :          0 :         hw_breakpoint_disable();
     342                 :            : 
     343         [ #  # ]:          0 :         if (image->preserve_context) {
     344                 :            : #ifdef CONFIG_X86_IO_APIC
     345                 :            :                 /*
     346                 :            :                  * We need to put APICs in legacy mode so that we can
     347                 :            :                  * get timer interrupts in second kernel. kexec/kdump
     348                 :            :                  * paths already have calls to restore_boot_irq_mode()
     349                 :            :                  * in one form or other. kexec jump path also need one.
     350                 :            :                  */
     351                 :          0 :                 clear_IO_APIC();
     352                 :          0 :                 restore_boot_irq_mode();
     353                 :            : #endif
     354                 :            :         }
     355                 :            : 
     356         [ #  # ]:          0 :         control_page = page_address(image->control_code_page) + PAGE_SIZE;
     357                 :          0 :         memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
     358                 :            : 
     359         [ #  # ]:          0 :         page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
     360                 :          0 :         page_list[VA_CONTROL_PAGE] = (unsigned long)control_page;
     361                 :          0 :         page_list[PA_TABLE_PAGE] =
     362         [ #  # ]:          0 :           (unsigned long)__pa(page_address(image->control_code_page));
     363                 :            : 
     364         [ #  # ]:          0 :         if (image->type == KEXEC_TYPE_DEFAULT)
     365                 :          0 :                 page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page)
     366                 :          0 :                                                 << PAGE_SHIFT);
     367                 :            : 
     368                 :            :         /*
     369                 :            :          * The segment registers are funny things, they have both a
     370                 :            :          * visible and an invisible part.  Whenever the visible part is
     371                 :            :          * set to a specific selector, the invisible part is loaded
     372                 :            :          * with from a table in memory.  At no other time is the
     373                 :            :          * descriptor table in memory accessed.
     374                 :            :          *
     375                 :            :          * I take advantage of this here by force loading the
     376                 :            :          * segments, before I zap the gdt with an invalid value.
     377                 :            :          */
     378                 :          0 :         load_segments();
     379                 :            :         /*
     380                 :            :          * The gdt & idt are now invalid.
     381                 :            :          * If you want to load them you must set up your own idt & gdt.
     382                 :            :          */
     383                 :          0 :         set_gdt(phys_to_virt(0), 0);
     384                 :          0 :         set_idt(phys_to_virt(0), 0);
     385                 :            : 
     386                 :            :         /* now call it */
     387                 :          0 :         image->start = relocate_kernel((unsigned long)image->head,
     388                 :            :                                        (unsigned long)page_list,
     389                 :            :                                        image->start,
     390                 :          0 :                                        image->preserve_context,
     391                 :            :                                        sme_active());
     392                 :            : 
     393                 :            : #ifdef CONFIG_KEXEC_JUMP
     394                 :            :         if (image->preserve_context)
     395                 :            :                 restore_processor_state();
     396                 :            : #endif
     397                 :            : 
     398                 :          0 :         __ftrace_enabled_restore(save_ftrace_enabled);
     399                 :          0 : }
     400                 :            : 
     401                 :            : /* arch-dependent functionality related to kexec file-based syscall */
     402                 :            : 
     403                 :            : #ifdef CONFIG_KEXEC_FILE
     404                 :            : void *arch_kexec_kernel_image_load(struct kimage *image)
     405                 :            : {
     406                 :            :         vfree(image->arch.elf_headers);
     407                 :            :         image->arch.elf_headers = NULL;
     408                 :            : 
     409                 :            :         if (!image->fops || !image->fops->load)
     410                 :            :                 return ERR_PTR(-ENOEXEC);
     411                 :            : 
     412                 :            :         return image->fops->load(image, image->kernel_buf,
     413                 :            :                                  image->kernel_buf_len, image->initrd_buf,
     414                 :            :                                  image->initrd_buf_len, image->cmdline_buf,
     415                 :            :                                  image->cmdline_buf_len);
     416                 :            : }
     417                 :            : 
     418                 :            : /*
     419                 :            :  * Apply purgatory relocations.
     420                 :            :  *
     421                 :            :  * @pi:         Purgatory to be relocated.
     422                 :            :  * @section:    Section relocations applying to.
     423                 :            :  * @relsec:     Section containing RELAs.
     424                 :            :  * @symtabsec:  Corresponding symtab.
     425                 :            :  *
     426                 :            :  * TODO: Some of the code belongs to generic code. Move that in kexec.c.
     427                 :            :  */
     428                 :            : int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
     429                 :            :                                      Elf_Shdr *section, const Elf_Shdr *relsec,
     430                 :            :                                      const Elf_Shdr *symtabsec)
     431                 :            : {
     432                 :            :         unsigned int i;
     433                 :            :         Elf64_Rela *rel;
     434                 :            :         Elf64_Sym *sym;
     435                 :            :         void *location;
     436                 :            :         unsigned long address, sec_base, value;
     437                 :            :         const char *strtab, *name, *shstrtab;
     438                 :            :         const Elf_Shdr *sechdrs;
     439                 :            : 
     440                 :            :         /* String & section header string table */
     441                 :            :         sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff;
     442                 :            :         strtab = (char *)pi->ehdr + sechdrs[symtabsec->sh_link].sh_offset;
     443                 :            :         shstrtab = (char *)pi->ehdr + sechdrs[pi->ehdr->e_shstrndx].sh_offset;
     444                 :            : 
     445                 :            :         rel = (void *)pi->ehdr + relsec->sh_offset;
     446                 :            : 
     447                 :            :         pr_debug("Applying relocate section %s to %u\n",
     448                 :            :                  shstrtab + relsec->sh_name, relsec->sh_info);
     449                 :            : 
     450                 :            :         for (i = 0; i < relsec->sh_size / sizeof(*rel); i++) {
     451                 :            : 
     452                 :            :                 /*
     453                 :            :                  * rel[i].r_offset contains byte offset from beginning
     454                 :            :                  * of section to the storage unit affected.
     455                 :            :                  *
     456                 :            :                  * This is location to update. This is temporary buffer
     457                 :            :                  * where section is currently loaded. This will finally be
     458                 :            :                  * loaded to a different address later, pointed to by
     459                 :            :                  * ->sh_addr. kexec takes care of moving it
     460                 :            :                  *  (kexec_load_segment()).
     461                 :            :                  */
     462                 :            :                 location = pi->purgatory_buf;
     463                 :            :                 location += section->sh_offset;
     464                 :            :                 location += rel[i].r_offset;
     465                 :            : 
     466                 :            :                 /* Final address of the location */
     467                 :            :                 address = section->sh_addr + rel[i].r_offset;
     468                 :            : 
     469                 :            :                 /*
     470                 :            :                  * rel[i].r_info contains information about symbol table index
     471                 :            :                  * w.r.t which relocation must be made and type of relocation
     472                 :            :                  * to apply. ELF64_R_SYM() and ELF64_R_TYPE() macros get
     473                 :            :                  * these respectively.
     474                 :            :                  */
     475                 :            :                 sym = (void *)pi->ehdr + symtabsec->sh_offset;
     476                 :            :                 sym += ELF64_R_SYM(rel[i].r_info);
     477                 :            : 
     478                 :            :                 if (sym->st_name)
     479                 :            :                         name = strtab + sym->st_name;
     480                 :            :                 else
     481                 :            :                         name = shstrtab + sechdrs[sym->st_shndx].sh_name;
     482                 :            : 
     483                 :            :                 pr_debug("Symbol: %s info: %02x shndx: %02x value=%llx size: %llx\n",
     484                 :            :                          name, sym->st_info, sym->st_shndx, sym->st_value,
     485                 :            :                          sym->st_size);
     486                 :            : 
     487                 :            :                 if (sym->st_shndx == SHN_UNDEF) {
     488                 :            :                         pr_err("Undefined symbol: %s\n", name);
     489                 :            :                         return -ENOEXEC;
     490                 :            :                 }
     491                 :            : 
     492                 :            :                 if (sym->st_shndx == SHN_COMMON) {
     493                 :            :                         pr_err("symbol '%s' in common section\n", name);
     494                 :            :                         return -ENOEXEC;
     495                 :            :                 }
     496                 :            : 
     497                 :            :                 if (sym->st_shndx == SHN_ABS)
     498                 :            :                         sec_base = 0;
     499                 :            :                 else if (sym->st_shndx >= pi->ehdr->e_shnum) {
     500                 :            :                         pr_err("Invalid section %d for symbol %s\n",
     501                 :            :                                sym->st_shndx, name);
     502                 :            :                         return -ENOEXEC;
     503                 :            :                 } else
     504                 :            :                         sec_base = pi->sechdrs[sym->st_shndx].sh_addr;
     505                 :            : 
     506                 :            :                 value = sym->st_value;
     507                 :            :                 value += sec_base;
     508                 :            :                 value += rel[i].r_addend;
     509                 :            : 
     510                 :            :                 switch (ELF64_R_TYPE(rel[i].r_info)) {
     511                 :            :                 case R_X86_64_NONE:
     512                 :            :                         break;
     513                 :            :                 case R_X86_64_64:
     514                 :            :                         *(u64 *)location = value;
     515                 :            :                         break;
     516                 :            :                 case R_X86_64_32:
     517                 :            :                         *(u32 *)location = value;
     518                 :            :                         if (value != *(u32 *)location)
     519                 :            :                                 goto overflow;
     520                 :            :                         break;
     521                 :            :                 case R_X86_64_32S:
     522                 :            :                         *(s32 *)location = value;
     523                 :            :                         if ((s64)value != *(s32 *)location)
     524                 :            :                                 goto overflow;
     525                 :            :                         break;
     526                 :            :                 case R_X86_64_PC32:
     527                 :            :                 case R_X86_64_PLT32:
     528                 :            :                         value -= (u64)address;
     529                 :            :                         *(u32 *)location = value;
     530                 :            :                         break;
     531                 :            :                 default:
     532                 :            :                         pr_err("Unknown rela relocation: %llu\n",
     533                 :            :                                ELF64_R_TYPE(rel[i].r_info));
     534                 :            :                         return -ENOEXEC;
     535                 :            :                 }
     536                 :            :         }
     537                 :            :         return 0;
     538                 :            : 
     539                 :            : overflow:
     540                 :            :         pr_err("Overflow in relocation type %d value 0x%lx\n",
     541                 :            :                (int)ELF64_R_TYPE(rel[i].r_info), value);
     542                 :            :         return -ENOEXEC;
     543                 :            : }
     544                 :            : #endif /* CONFIG_KEXEC_FILE */
     545                 :            : 
     546                 :            : static int
     547                 :          0 : kexec_mark_range(unsigned long start, unsigned long end, bool protect)
     548                 :            : {
     549                 :          0 :         struct page *page;
     550                 :          0 :         unsigned int nr_pages;
     551                 :            : 
     552                 :            :         /*
     553                 :            :          * For physical range: [start, end]. We must skip the unassigned
     554                 :            :          * crashk resource with zero-valued "end" member.
     555                 :            :          */
     556         [ #  # ]:          0 :         if (!end || start > end)
     557                 :            :                 return 0;
     558                 :            : 
     559                 :          0 :         page = pfn_to_page(start >> PAGE_SHIFT);
     560                 :          0 :         nr_pages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
     561         [ #  # ]:          0 :         if (protect)
     562                 :          0 :                 return set_pages_ro(page, nr_pages);
     563                 :            :         else
     564                 :          0 :                 return set_pages_rw(page, nr_pages);
     565                 :            : }
     566                 :            : 
     567                 :          0 : static void kexec_mark_crashkres(bool protect)
     568                 :            : {
     569                 :          0 :         unsigned long control;
     570                 :            : 
     571                 :          0 :         kexec_mark_range(crashk_low_res.start, crashk_low_res.end, protect);
     572                 :            : 
     573                 :            :         /* Don't touch the control code page used in crash_kexec().*/
     574                 :          0 :         control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page));
     575                 :            :         /* Control code page is located in the 2nd page. */
     576                 :          0 :         kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect);
     577                 :          0 :         control += KEXEC_CONTROL_PAGE_SIZE;
     578                 :          0 :         kexec_mark_range(control, crashk_res.end, protect);
     579                 :          0 : }
     580                 :            : 
     581                 :          0 : void arch_kexec_protect_crashkres(void)
     582                 :            : {
     583                 :          0 :         kexec_mark_crashkres(true);
     584                 :          0 : }
     585                 :            : 
     586                 :          0 : void arch_kexec_unprotect_crashkres(void)
     587                 :            : {
     588                 :          0 :         kexec_mark_crashkres(false);
     589                 :          0 : }
     590                 :            : 
     591                 :            : /*
     592                 :            :  * During a traditional boot under SME, SME will encrypt the kernel,
     593                 :            :  * so the SME kexec kernel also needs to be un-encrypted in order to
     594                 :            :  * replicate a normal SME boot.
     595                 :            :  *
     596                 :            :  * During a traditional boot under SEV, the kernel has already been
     597                 :            :  * loaded encrypted, so the SEV kexec kernel needs to be encrypted in
     598                 :            :  * order to replicate a normal SEV boot.
     599                 :            :  */
     600                 :          0 : int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp)
     601                 :            : {
     602                 :          0 :         if (sev_active())
     603                 :            :                 return 0;
     604                 :            : 
     605                 :            :         /*
     606                 :            :          * If SME is active we need to be sure that kexec pages are
     607                 :            :          * not encrypted because when we boot to the new kernel the
     608                 :            :          * pages won't be accessed encrypted (initially).
     609                 :            :          */
     610                 :          0 :         return set_memory_decrypted((unsigned long)vaddr, pages);
     611                 :            : }
     612                 :            : 
     613                 :          0 : void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages)
     614                 :            : {
     615                 :          0 :         if (sev_active())
     616                 :            :                 return;
     617                 :            : 
     618                 :            :         /*
     619                 :            :          * If SME is active we need to reset the pages back to being
     620                 :            :          * an encrypted mapping before freeing them.
     621                 :            :          */
     622                 :          0 :         set_memory_encrypted((unsigned long)vaddr, pages);
     623                 :            : }

Generated by: LCOV version 1.14