Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Kexec bzImage loader
0004  *
0005  * Copyright (C) 2014 Red Hat Inc.
0006  * Authors:
0007  *      Vivek Goyal <vgoyal@redhat.com>
0008  */
0009 
0010 #define pr_fmt(fmt) "kexec-bzImage64: " fmt
0011 
0012 #include <linux/string.h>
0013 #include <linux/printk.h>
0014 #include <linux/errno.h>
0015 #include <linux/slab.h>
0016 #include <linux/kexec.h>
0017 #include <linux/kernel.h>
0018 #include <linux/mm.h>
0019 #include <linux/efi.h>
0020 #include <linux/random.h>
0021 
0022 #include <asm/bootparam.h>
0023 #include <asm/setup.h>
0024 #include <asm/crash.h>
0025 #include <asm/efi.h>
0026 #include <asm/e820/api.h>
0027 #include <asm/kexec-bzimage64.h>
0028 
0029 #define MAX_ELFCOREHDR_STR_LEN  30  /* elfcorehdr=0x<64bit-value> */
0030 
0031 /*
0032  * Defines lowest physical address for various segments. Not sure where
0033  * exactly these limits came from. Current bzimage64 loader in kexec-tools
0034  * uses these so I am retaining it. It can be changed over time as we gain
0035  * more insight.
0036  */
0037 #define MIN_PURGATORY_ADDR  0x3000
0038 #define MIN_BOOTPARAM_ADDR  0x3000
0039 #define MIN_KERNEL_LOAD_ADDR    0x100000
0040 #define MIN_INITRD_LOAD_ADDR    0x1000000
0041 
0042 /*
0043  * This is a place holder for all boot loader specific data structure which
0044  * gets allocated in one call but gets freed much later during cleanup
0045  * time. Right now there is only one field but it can grow as need be.
0046  */
0047 struct bzimage64_data {
0048     /*
0049      * Temporary buffer to hold bootparams buffer. This should be
0050      * freed once the bootparam segment has been loaded.
0051      */
0052     void *bootparams_buf;
0053 };
0054 
0055 static int setup_initrd(struct boot_params *params,
0056         unsigned long initrd_load_addr, unsigned long initrd_len)
0057 {
0058     params->hdr.ramdisk_image = initrd_load_addr & 0xffffffffUL;
0059     params->hdr.ramdisk_size = initrd_len & 0xffffffffUL;
0060 
0061     params->ext_ramdisk_image = initrd_load_addr >> 32;
0062     params->ext_ramdisk_size = initrd_len >> 32;
0063 
0064     return 0;
0065 }
0066 
0067 static int setup_cmdline(struct kimage *image, struct boot_params *params,
0068              unsigned long bootparams_load_addr,
0069              unsigned long cmdline_offset, char *cmdline,
0070              unsigned long cmdline_len)
0071 {
0072     char *cmdline_ptr = ((char *)params) + cmdline_offset;
0073     unsigned long cmdline_ptr_phys, len = 0;
0074     uint32_t cmdline_low_32, cmdline_ext_32;
0075 
0076     if (image->type == KEXEC_TYPE_CRASH) {
0077         len = sprintf(cmdline_ptr,
0078             "elfcorehdr=0x%lx ", image->elf_load_addr);
0079     }
0080     memcpy(cmdline_ptr + len, cmdline, cmdline_len);
0081     cmdline_len += len;
0082 
0083     cmdline_ptr[cmdline_len - 1] = '\0';
0084 
0085     pr_debug("Final command line is: %s\n", cmdline_ptr);
0086     cmdline_ptr_phys = bootparams_load_addr + cmdline_offset;
0087     cmdline_low_32 = cmdline_ptr_phys & 0xffffffffUL;
0088     cmdline_ext_32 = cmdline_ptr_phys >> 32;
0089 
0090     params->hdr.cmd_line_ptr = cmdline_low_32;
0091     if (cmdline_ext_32)
0092         params->ext_cmd_line_ptr = cmdline_ext_32;
0093 
0094     return 0;
0095 }
0096 
0097 static int setup_e820_entries(struct boot_params *params)
0098 {
0099     unsigned int nr_e820_entries;
0100 
0101     nr_e820_entries = e820_table_kexec->nr_entries;
0102 
0103     /* TODO: Pass entries more than E820_MAX_ENTRIES_ZEROPAGE in bootparams setup data */
0104     if (nr_e820_entries > E820_MAX_ENTRIES_ZEROPAGE)
0105         nr_e820_entries = E820_MAX_ENTRIES_ZEROPAGE;
0106 
0107     params->e820_entries = nr_e820_entries;
0108     memcpy(&params->e820_table, &e820_table_kexec->entries, nr_e820_entries*sizeof(struct e820_entry));
0109 
0110     return 0;
0111 }
0112 
0113 enum { RNG_SEED_LENGTH = 32 };
0114 
0115 static void
0116 setup_rng_seed(struct boot_params *params, unsigned long params_load_addr,
0117            unsigned int rng_seed_setup_data_offset)
0118 {
0119     struct setup_data *sd = (void *)params + rng_seed_setup_data_offset;
0120     unsigned long setup_data_phys;
0121 
0122     if (!rng_is_initialized())
0123         return;
0124 
0125     sd->type = SETUP_RNG_SEED;
0126     sd->len = RNG_SEED_LENGTH;
0127     get_random_bytes(sd->data, RNG_SEED_LENGTH);
0128     setup_data_phys = params_load_addr + rng_seed_setup_data_offset;
0129     sd->next = params->hdr.setup_data;
0130     params->hdr.setup_data = setup_data_phys;
0131 }
0132 
0133 #ifdef CONFIG_EFI
0134 static int setup_efi_info_memmap(struct boot_params *params,
0135                   unsigned long params_load_addr,
0136                   unsigned int efi_map_offset,
0137                   unsigned int efi_map_sz)
0138 {
0139     void *efi_map = (void *)params + efi_map_offset;
0140     unsigned long efi_map_phys_addr = params_load_addr + efi_map_offset;
0141     struct efi_info *ei = &params->efi_info;
0142 
0143     if (!efi_map_sz)
0144         return 0;
0145 
0146     efi_runtime_map_copy(efi_map, efi_map_sz);
0147 
0148     ei->efi_memmap = efi_map_phys_addr & 0xffffffff;
0149     ei->efi_memmap_hi = efi_map_phys_addr >> 32;
0150     ei->efi_memmap_size = efi_map_sz;
0151 
0152     return 0;
0153 }
0154 
0155 static int
0156 prepare_add_efi_setup_data(struct boot_params *params,
0157                unsigned long params_load_addr,
0158                unsigned int efi_setup_data_offset)
0159 {
0160     unsigned long setup_data_phys;
0161     struct setup_data *sd = (void *)params + efi_setup_data_offset;
0162     struct efi_setup_data *esd = (void *)sd + sizeof(struct setup_data);
0163 
0164     esd->fw_vendor = efi_fw_vendor;
0165     esd->tables = efi_config_table;
0166     esd->smbios = efi.smbios;
0167 
0168     sd->type = SETUP_EFI;
0169     sd->len = sizeof(struct efi_setup_data);
0170 
0171     /* Add setup data */
0172     setup_data_phys = params_load_addr + efi_setup_data_offset;
0173     sd->next = params->hdr.setup_data;
0174     params->hdr.setup_data = setup_data_phys;
0175 
0176     return 0;
0177 }
0178 
0179 static int
0180 setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
0181         unsigned int efi_map_offset, unsigned int efi_map_sz,
0182         unsigned int efi_setup_data_offset)
0183 {
0184     struct efi_info *current_ei = &boot_params.efi_info;
0185     struct efi_info *ei = &params->efi_info;
0186 
0187     if (!efi_enabled(EFI_RUNTIME_SERVICES))
0188         return 0;
0189 
0190     if (!current_ei->efi_memmap_size)
0191         return 0;
0192 
0193     params->secure_boot = boot_params.secure_boot;
0194     ei->efi_loader_signature = current_ei->efi_loader_signature;
0195     ei->efi_systab = current_ei->efi_systab;
0196     ei->efi_systab_hi = current_ei->efi_systab_hi;
0197 
0198     ei->efi_memdesc_version = current_ei->efi_memdesc_version;
0199     ei->efi_memdesc_size = efi_get_runtime_map_desc_size();
0200 
0201     setup_efi_info_memmap(params, params_load_addr, efi_map_offset,
0202                   efi_map_sz);
0203     prepare_add_efi_setup_data(params, params_load_addr,
0204                    efi_setup_data_offset);
0205     return 0;
0206 }
0207 #endif /* CONFIG_EFI */
0208 
0209 static void
0210 setup_ima_state(const struct kimage *image, struct boot_params *params,
0211         unsigned long params_load_addr,
0212         unsigned int ima_setup_data_offset)
0213 {
0214 #ifdef CONFIG_IMA_KEXEC
0215     struct setup_data *sd = (void *)params + ima_setup_data_offset;
0216     unsigned long setup_data_phys;
0217     struct ima_setup_data *ima;
0218 
0219     if (!image->ima_buffer_size)
0220         return;
0221 
0222     sd->type = SETUP_IMA;
0223     sd->len = sizeof(*ima);
0224 
0225     ima = (void *)sd + sizeof(struct setup_data);
0226     ima->addr = image->ima_buffer_addr;
0227     ima->size = image->ima_buffer_size;
0228 
0229     /* Add setup data */
0230     setup_data_phys = params_load_addr + ima_setup_data_offset;
0231     sd->next = params->hdr.setup_data;
0232     params->hdr.setup_data = setup_data_phys;
0233 #endif /* CONFIG_IMA_KEXEC */
0234 }
0235 
0236 static int
0237 setup_boot_parameters(struct kimage *image, struct boot_params *params,
0238               unsigned long params_load_addr,
0239               unsigned int efi_map_offset, unsigned int efi_map_sz,
0240               unsigned int setup_data_offset)
0241 {
0242     unsigned int nr_e820_entries;
0243     unsigned long long mem_k, start, end;
0244     int i, ret = 0;
0245 
0246     /* Get subarch from existing bootparams */
0247     params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch;
0248 
0249     /* Copying screen_info will do? */
0250     memcpy(&params->screen_info, &screen_info, sizeof(struct screen_info));
0251 
0252     /* Fill in memsize later */
0253     params->screen_info.ext_mem_k = 0;
0254     params->alt_mem_k = 0;
0255 
0256     /* Always fill in RSDP: it is either 0 or a valid value */
0257     params->acpi_rsdp_addr = boot_params.acpi_rsdp_addr;
0258 
0259     /* Default APM info */
0260     memset(&params->apm_bios_info, 0, sizeof(params->apm_bios_info));
0261 
0262     /* Default drive info */
0263     memset(&params->hd0_info, 0, sizeof(params->hd0_info));
0264     memset(&params->hd1_info, 0, sizeof(params->hd1_info));
0265 
0266     if (image->type == KEXEC_TYPE_CRASH) {
0267         ret = crash_setup_memmap_entries(image, params);
0268         if (ret)
0269             return ret;
0270     } else
0271         setup_e820_entries(params);
0272 
0273     nr_e820_entries = params->e820_entries;
0274 
0275     for (i = 0; i < nr_e820_entries; i++) {
0276         if (params->e820_table[i].type != E820_TYPE_RAM)
0277             continue;
0278         start = params->e820_table[i].addr;
0279         end = params->e820_table[i].addr + params->e820_table[i].size - 1;
0280 
0281         if ((start <= 0x100000) && end > 0x100000) {
0282             mem_k = (end >> 10) - (0x100000 >> 10);
0283             params->screen_info.ext_mem_k = mem_k;
0284             params->alt_mem_k = mem_k;
0285             if (mem_k > 0xfc00)
0286                 params->screen_info.ext_mem_k = 0xfc00; /* 64M*/
0287             if (mem_k > 0xffffffff)
0288                 params->alt_mem_k = 0xffffffff;
0289         }
0290     }
0291 
0292 #ifdef CONFIG_EFI
0293     /* Setup EFI state */
0294     setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
0295             setup_data_offset);
0296     setup_data_offset += sizeof(struct setup_data) +
0297             sizeof(struct efi_setup_data);
0298 #endif
0299 
0300     if (IS_ENABLED(CONFIG_IMA_KEXEC)) {
0301         /* Setup IMA log buffer state */
0302         setup_ima_state(image, params, params_load_addr,
0303                 setup_data_offset);
0304         setup_data_offset += sizeof(struct setup_data) +
0305                      sizeof(struct ima_setup_data);
0306     }
0307 
0308     /* Setup RNG seed */
0309     setup_rng_seed(params, params_load_addr, setup_data_offset);
0310 
0311     /* Setup EDD info */
0312     memcpy(params->eddbuf, boot_params.eddbuf,
0313                 EDDMAXNR * sizeof(struct edd_info));
0314     params->eddbuf_entries = boot_params.eddbuf_entries;
0315 
0316     memcpy(params->edd_mbr_sig_buffer, boot_params.edd_mbr_sig_buffer,
0317            EDD_MBR_SIG_MAX * sizeof(unsigned int));
0318 
0319     return ret;
0320 }
0321 
0322 static int bzImage64_probe(const char *buf, unsigned long len)
0323 {
0324     int ret = -ENOEXEC;
0325     struct setup_header *header;
0326 
0327     /* kernel should be at least two sectors long */
0328     if (len < 2 * 512) {
0329         pr_err("File is too short to be a bzImage\n");
0330         return ret;
0331     }
0332 
0333     header = (struct setup_header *)(buf + offsetof(struct boot_params, hdr));
0334     if (memcmp((char *)&header->header, "HdrS", 4) != 0) {
0335         pr_err("Not a bzImage\n");
0336         return ret;
0337     }
0338 
0339     if (header->boot_flag != 0xAA55) {
0340         pr_err("No x86 boot sector present\n");
0341         return ret;
0342     }
0343 
0344     if (header->version < 0x020C) {
0345         pr_err("Must be at least protocol version 2.12\n");
0346         return ret;
0347     }
0348 
0349     if (!(header->loadflags & LOADED_HIGH)) {
0350         pr_err("zImage not a bzImage\n");
0351         return ret;
0352     }
0353 
0354     if (!(header->xloadflags & XLF_KERNEL_64)) {
0355         pr_err("Not a bzImage64. XLF_KERNEL_64 is not set.\n");
0356         return ret;
0357     }
0358 
0359     if (!(header->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G)) {
0360         pr_err("XLF_CAN_BE_LOADED_ABOVE_4G is not set.\n");
0361         return ret;
0362     }
0363 
0364     /*
0365      * Can't handle 32bit EFI as it does not allow loading kernel
0366      * above 4G. This should be handled by 32bit bzImage loader
0367      */
0368     if (efi_enabled(EFI_RUNTIME_SERVICES) && !efi_enabled(EFI_64BIT)) {
0369         pr_debug("EFI is 32 bit. Can't load kernel above 4G.\n");
0370         return ret;
0371     }
0372 
0373     if (!(header->xloadflags & XLF_5LEVEL) && pgtable_l5_enabled()) {
0374         pr_err("bzImage cannot handle 5-level paging mode.\n");
0375         return ret;
0376     }
0377 
0378     /* I've got a bzImage */
0379     pr_debug("It's a relocatable bzImage64\n");
0380     ret = 0;
0381 
0382     return ret;
0383 }
0384 
0385 static void *bzImage64_load(struct kimage *image, char *kernel,
0386                 unsigned long kernel_len, char *initrd,
0387                 unsigned long initrd_len, char *cmdline,
0388                 unsigned long cmdline_len)
0389 {
0390 
0391     struct setup_header *header;
0392     int setup_sects, kern16_size, ret = 0;
0393     unsigned long setup_header_size, params_cmdline_sz;
0394     struct boot_params *params;
0395     unsigned long bootparam_load_addr, kernel_load_addr, initrd_load_addr;
0396     struct bzimage64_data *ldata;
0397     struct kexec_entry64_regs regs64;
0398     void *stack;
0399     unsigned int setup_hdr_offset = offsetof(struct boot_params, hdr);
0400     unsigned int efi_map_offset, efi_map_sz, efi_setup_data_offset;
0401     struct kexec_buf kbuf = { .image = image, .buf_max = ULONG_MAX,
0402                   .top_down = true };
0403     struct kexec_buf pbuf = { .image = image, .buf_min = MIN_PURGATORY_ADDR,
0404                   .buf_max = ULONG_MAX, .top_down = true };
0405 
0406     header = (struct setup_header *)(kernel + setup_hdr_offset);
0407     setup_sects = header->setup_sects;
0408     if (setup_sects == 0)
0409         setup_sects = 4;
0410 
0411     kern16_size = (setup_sects + 1) * 512;
0412     if (kernel_len < kern16_size) {
0413         pr_err("bzImage truncated\n");
0414         return ERR_PTR(-ENOEXEC);
0415     }
0416 
0417     if (cmdline_len > header->cmdline_size) {
0418         pr_err("Kernel command line too long\n");
0419         return ERR_PTR(-EINVAL);
0420     }
0421 
0422     /*
0423      * In case of crash dump, we will append elfcorehdr=<addr> to
0424      * command line. Make sure it does not overflow
0425      */
0426     if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
0427         pr_debug("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
0428         return ERR_PTR(-EINVAL);
0429     }
0430 
0431     /* Allocate and load backup region */
0432     if (image->type == KEXEC_TYPE_CRASH) {
0433         ret = crash_load_segments(image);
0434         if (ret)
0435             return ERR_PTR(ret);
0436     }
0437 
0438     /*
0439      * Load purgatory. For 64bit entry point, purgatory  code can be
0440      * anywhere.
0441      */
0442     ret = kexec_load_purgatory(image, &pbuf);
0443     if (ret) {
0444         pr_err("Loading purgatory failed\n");
0445         return ERR_PTR(ret);
0446     }
0447 
0448     pr_debug("Loaded purgatory at 0x%lx\n", pbuf.mem);
0449 
0450 
0451     /*
0452      * Load Bootparams and cmdline and space for efi stuff.
0453      *
0454      * Allocate memory together for multiple data structures so
0455      * that they all can go in single area/segment and we don't
0456      * have to create separate segment for each. Keeps things
0457      * little bit simple
0458      */
0459     efi_map_sz = efi_get_runtime_map_size();
0460     params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
0461                 MAX_ELFCOREHDR_STR_LEN;
0462     params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
0463     kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
0464                 sizeof(struct setup_data) +
0465                 sizeof(struct efi_setup_data) +
0466                 sizeof(struct setup_data) +
0467                 RNG_SEED_LENGTH;
0468 
0469     if (IS_ENABLED(CONFIG_IMA_KEXEC))
0470         kbuf.bufsz += sizeof(struct setup_data) +
0471                   sizeof(struct ima_setup_data);
0472 
0473     params = kzalloc(kbuf.bufsz, GFP_KERNEL);
0474     if (!params)
0475         return ERR_PTR(-ENOMEM);
0476     efi_map_offset = params_cmdline_sz;
0477     efi_setup_data_offset = efi_map_offset + ALIGN(efi_map_sz, 16);
0478 
0479     /* Copy setup header onto bootparams. Documentation/x86/boot.rst */
0480     setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset;
0481 
0482     /* Is there a limit on setup header size? */
0483     memcpy(&params->hdr, (kernel + setup_hdr_offset), setup_header_size);
0484 
0485     kbuf.buffer = params;
0486     kbuf.memsz = kbuf.bufsz;
0487     kbuf.buf_align = 16;
0488     kbuf.buf_min = MIN_BOOTPARAM_ADDR;
0489     ret = kexec_add_buffer(&kbuf);
0490     if (ret)
0491         goto out_free_params;
0492     bootparam_load_addr = kbuf.mem;
0493     pr_debug("Loaded boot_param, command line and misc at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
0494          bootparam_load_addr, kbuf.bufsz, kbuf.bufsz);
0495 
0496     /* Load kernel */
0497     kbuf.buffer = kernel + kern16_size;
0498     kbuf.bufsz =  kernel_len - kern16_size;
0499     kbuf.memsz = PAGE_ALIGN(header->init_size);
0500     kbuf.buf_align = header->kernel_alignment;
0501     kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
0502     kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
0503     ret = kexec_add_buffer(&kbuf);
0504     if (ret)
0505         goto out_free_params;
0506     kernel_load_addr = kbuf.mem;
0507 
0508     pr_debug("Loaded 64bit kernel at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
0509          kernel_load_addr, kbuf.bufsz, kbuf.memsz);
0510 
0511     /* Load initrd high */
0512     if (initrd) {
0513         kbuf.buffer = initrd;
0514         kbuf.bufsz = kbuf.memsz = initrd_len;
0515         kbuf.buf_align = PAGE_SIZE;
0516         kbuf.buf_min = MIN_INITRD_LOAD_ADDR;
0517         kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
0518         ret = kexec_add_buffer(&kbuf);
0519         if (ret)
0520             goto out_free_params;
0521         initrd_load_addr = kbuf.mem;
0522 
0523         pr_debug("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
0524                 initrd_load_addr, initrd_len, initrd_len);
0525 
0526         setup_initrd(params, initrd_load_addr, initrd_len);
0527     }
0528 
0529     setup_cmdline(image, params, bootparam_load_addr,
0530               sizeof(struct boot_params), cmdline, cmdline_len);
0531 
0532     /* bootloader info. Do we need a separate ID for kexec kernel loader? */
0533     params->hdr.type_of_loader = 0x0D << 4;
0534     params->hdr.loadflags = 0;
0535 
0536     /* Setup purgatory regs for entry */
0537     ret = kexec_purgatory_get_set_symbol(image, "entry64_regs", &regs64,
0538                          sizeof(regs64), 1);
0539     if (ret)
0540         goto out_free_params;
0541 
0542     regs64.rbx = 0; /* Bootstrap Processor */
0543     regs64.rsi = bootparam_load_addr;
0544     regs64.rip = kernel_load_addr + 0x200;
0545     stack = kexec_purgatory_get_symbol_addr(image, "stack_end");
0546     if (IS_ERR(stack)) {
0547         pr_err("Could not find address of symbol stack_end\n");
0548         ret = -EINVAL;
0549         goto out_free_params;
0550     }
0551 
0552     regs64.rsp = (unsigned long)stack;
0553     ret = kexec_purgatory_get_set_symbol(image, "entry64_regs", &regs64,
0554                          sizeof(regs64), 0);
0555     if (ret)
0556         goto out_free_params;
0557 
0558     ret = setup_boot_parameters(image, params, bootparam_load_addr,
0559                     efi_map_offset, efi_map_sz,
0560                     efi_setup_data_offset);
0561     if (ret)
0562         goto out_free_params;
0563 
0564     /* Allocate loader specific data */
0565     ldata = kzalloc(sizeof(struct bzimage64_data), GFP_KERNEL);
0566     if (!ldata) {
0567         ret = -ENOMEM;
0568         goto out_free_params;
0569     }
0570 
0571     /*
0572      * Store pointer to params so that it could be freed after loading
0573      * params segment has been loaded and contents have been copied
0574      * somewhere else.
0575      */
0576     ldata->bootparams_buf = params;
0577     return ldata;
0578 
0579 out_free_params:
0580     kfree(params);
0581     return ERR_PTR(ret);
0582 }
0583 
0584 /* This cleanup function is called after various segments have been loaded */
0585 static int bzImage64_cleanup(void *loader_data)
0586 {
0587     struct bzimage64_data *ldata = loader_data;
0588 
0589     if (!ldata)
0590         return 0;
0591 
0592     kfree(ldata->bootparams_buf);
0593     ldata->bootparams_buf = NULL;
0594 
0595     return 0;
0596 }
0597 
0598 const struct kexec_file_ops kexec_bzImage64_ops = {
0599     .probe = bzImage64_probe,
0600     .load = bzImage64_load,
0601     .cleanup = bzImage64_cleanup,
0602 #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
0603     .verify_sig = kexec_kernel_verify_pe_sig,
0604 #endif
0605 };