source: trunk/target/linux/generic/patches-3.0/335-mips-kexec-cleanup-kexec-tools-parameter-handling.patch @ 31344

Last change on this file since 31344 was 31344, checked in by florian, 4 years ago

[generic] fix 335-mips-kexec patch for all 3+ kernels

File size: 4.9 KB
  • arch/mips/kernel/machine_kexec.c

    a b void (*relocated_kexec_smp_wait) (void * 
    2323atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0); 
    2424#endif 
    2525 
    26 static void machine_kexec_init_args(void) 
     26#define KEXEC_MIPS_ARGV_BUF_SIZE        COMMAND_LINE_SIZE 
     27#define KEXEC_MIPS_ARGV_MAX_ARGS        (COMMAND_LINE_SIZE / 15) 
     28 
     29char kexec_argv_buf[KEXEC_MIPS_ARGV_BUF_SIZE] __kexec; 
     30char *kexec_argv[KEXEC_MIPS_ARGV_MAX_ARGS] __kexec; 
     31 
     32static void 
     33machine_kexec_print_args(void) 
    2734{ 
    28         kexec_args[0] = fw_arg0; 
    29         kexec_args[1] = fw_arg1; 
    30         kexec_args[2] = fw_arg2; 
    31         kexec_args[3] = fw_arg3; 
     35        int i; 
    3236 
    3337        pr_info("kexec_args[0] (argc): %lu\n", kexec_args[0]); 
    3438        pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); 
    3539        pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); 
    3640        pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); 
    37 } 
    3841 
    39 #define ARGV_MAX_ARGS (COMMAND_LINE_SIZE / 15) 
     42        for (i = 0; i < kexec_args[0]; i++) 
     43                pr_info("kexec_argv[%d] = %p, %s\n", i, 
     44                        (char *)kexec_argv[i], (char *)kexec_argv[i]); 
     45} 
    4046 
    41 int machine_kexec_pass_args(struct kimage *image) 
     47static void 
     48machine_kexec_init_argv(struct kimage *image) 
    4249{ 
    43         int i, argc = 0; 
    44         char *bootloader = "kexec"; 
    45         int *kexec_argv = (int *)kexec_args[1]; 
     50        void __user *buf = NULL; 
     51        size_t bufsz; 
     52        size_t size; 
     53        int i; 
    4654 
     55        bufsz = 0; 
    4756        for (i = 0; i < image->nr_segments; i++) { 
    48                 if (!strncmp(bootloader, (char *)image->segment[i].buf, 
    49                                 strlen(bootloader))) { 
    50                         /* 
    51                          * convert command line string to array 
    52                          * of parameters (as bootloader does). 
    53                          */ 
    54                         /* 
    55                          * Note: we do treat the 1st string "kexec" as an 
    56                          * argument ;-) so, argc here is 1. 
    57                          */ 
    58                         char *str = (char *)image->segment[i].buf; 
    59                         char *ptr = strchr(str, ' '); 
    60                         char *kbuf = (char *)kexec_argv[0]; 
    61                         /* Whenever --command-line or --append used, "kexec" is copied */ 
    62                         argc = 1; 
    63                         /* Parse the offset */ 
    64                         while (ptr && (ARGV_MAX_ARGS > argc)) { 
    65                                 *ptr = '\0'; 
    66                                 if (ptr[1] != ' ' && ptr[1] != '\0') { 
    67                                         int offt = (int)(ptr - str + 1); 
    68                                         kexec_argv[argc] = (int)kbuf + offt; 
    69                                         argc++; 
    70                                 } 
    71                                 ptr = strchr(ptr + 1, ' '); 
    72                         } 
    73                         if (argc > 1) { 
    74                                 /* Copy to kernel space */ 
    75                                 copy_from_user(kbuf, (char *)image->segment[i].buf, image->segment[i].bufsz); 
    76                                 fw_arg0 = kexec_args[0] = argc; 
    77                         } 
    78                         break; 
     57                struct kexec_segment *seg; 
     58 
     59                seg = &image->segment[i]; 
     60                if (seg->bufsz < 6) 
     61                        continue; 
     62 
     63                if (strncmp((char *) seg->buf, "kexec", 5)) 
     64                        continue; 
     65 
     66                /* don't copy "kexec" */ 
     67                buf = seg->buf + 5; 
     68                bufsz = seg->bufsz - 5; 
     69                break; 
     70        } 
     71 
     72        if (!buf) 
     73                return; 
     74 
     75        size = KEXEC_MIPS_ARGV_BUF_SIZE - 1; 
     76        size = min(size, bufsz); 
     77        if (size < bufsz) 
     78                pr_warn("kexec command line truncated to %zd bytes\n", size); 
     79 
     80        /* Copy to kernel space */ 
     81        copy_from_user(kexec_argv_buf, buf, size); 
     82} 
     83 
     84static void 
     85machine_kexec_parse_argv(struct kimage *image) 
     86{ 
     87        char *reboot_code_buffer; 
     88        int reloc_delta; 
     89        char *ptr; 
     90        int argc; 
     91        int i; 
     92 
     93        ptr = kexec_argv_buf; 
     94        argc = 0; 
     95 
     96        /* 
     97         * convert command line string to array of parameters 
     98         * (as bootloader does). 
     99         */ 
     100        while (ptr && *ptr && (KEXEC_MIPS_ARGV_MAX_ARGS > argc)) { 
     101                if (*ptr == ' ') { 
     102                        *ptr++ = '\0'; 
     103                        continue; 
    79104                } 
     105 
     106                kexec_argv[argc++] = ptr; 
     107                ptr = strchr(ptr, ' '); 
    80108        } 
    81109 
    82         pr_info("argc = %lu\n", kexec_args[0]); 
    83         for (i = 0; i < kexec_args[0]; i++) 
    84                 pr_info("argv[%d] = %p, %s\n", i, (char *)kexec_argv[i], (char *)kexec_argv[i]); 
     110        if (!argc) 
     111                return; 
    85112 
    86         return 0; 
     113        kexec_args[0] = argc; 
     114        kexec_args[1] = (unsigned long)kexec_argv; 
     115        kexec_args[2] = 0; 
     116        kexec_args[3] = 0; 
     117 
     118        reboot_code_buffer = page_address(image->control_code_page); 
     119        reloc_delta = reboot_code_buffer - (char *) &__start___kexec_relocate; 
     120 
     121        kexec_args[1] += reloc_delta; 
     122        for (i = 0; i < argc; i++) 
     123                kexec_argv[i] += reloc_delta; 
    87124} 
    88125 
    89126int 
    machine_kexec_prepare(struct kimage *kim 
    95132         * 
    96133         * This can be overrided by _machine_kexec_prepare(). 
    97134         */ 
    98         machine_kexec_init_args(); 
    99         machine_kexec_pass_args(kimage); 
     135 
     136        kexec_args[0] = fw_arg0; 
     137        kexec_args[1] = fw_arg1; 
     138        kexec_args[2] = fw_arg2; 
     139        kexec_args[3] = fw_arg3; 
     140 
     141        machine_kexec_init_argv(kimage); 
     142        machine_kexec_parse_argv(kimage); 
    100143 
    101144        if (_machine_kexec_prepare) 
    102145                return _machine_kexec_prepare(kimage); 
    machine_kexec(struct kimage *image) 
    152195        pr_info("kexec_indirection_page = %p\n", 
    153196                        (void *)kexec_indirection_page); 
    154197 
     198        pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n", 
     199                        &__start___kexec_relocate, (void *)reboot_code_buffer); 
     200 
    155201        memcpy((void *)reboot_code_buffer, &__start___kexec_relocate, 
    156202               kexec_relocate_size); 
    157203 
    158         pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n", 
    159                         &__start___kexec_relocate, (void *)reboot_code_buffer); 
     204        machine_kexec_print_args(); 
    160205 
    161206        /* 
    162207         * The generic kexec code builds a page list with physical 
Note: See TracBrowser for help on using the repository browser.