what's with the zeroing out of memory when kexec is configured?

Robert P. J. Day rpjday at crashcourse.ca
Tue Sep 25 16:59:03 EDT 2012


  (undoubtedly another in an upcoming series of nitpicky questions as
i poke around in kernel code i haven't visited in a while and i learn
that there are lots of things i don't know.)

  consider the following free_initrd() routine in init/initramfs.c:

===== start =====

static void __init free_initrd(void)
{
#ifdef CONFIG_KEXEC
        unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
        unsigned long crashk_end   = (unsigned long)__va(crashk_res.end);
#endif
        if (do_retain_initrd)
                goto skip;

#ifdef CONFIG_KEXEC
        /*
         * If the initrd region is overlapped with crashkernel reserved region,
         * free only memory that is not part of crashkernel region.
         */
        if (initrd_start < crashk_end && initrd_end > crashk_start) {
                /*
                 * Initialize initrd memory region since the kexec boot does
                 * not do.
                 */
                memset((void *)initrd_start, 0, initrd_end - initrd_start);
                if (initrd_start < crashk_start)
                        free_initrd_mem(initrd_start, crashk_start);
                if (initrd_end > crashk_end)
                        free_initrd_mem(crashk_end, initrd_end);
        } else
#endif
                free_initrd_mem(initrd_start, initrd_end);
skip:
        initrd_start = 0;
        initrd_end = 0;
}

===== end =====

  so, one step at a time.  simplest case is if i boot with
"retain_initrd" kernel parameter, at which point it doesn't matter if
kexec is configured or not, control just jumps to "skip:" label, and
those variables are set to zero and no memory is freed.  easy enough.

  next scenario is if kexec *isn't* configured, and i *don't* use
retain_initrd, then what's run is:

                free_initrd_mem(initrd_start, initrd_end);
  skip:
        initrd_start = 0;
        initrd_end = 0;

so free_initrd_mem() is call to free the *entire* range of initrd
content.  also, there is no zeroing/clearing of that space first, it's
just freed.  again, not too difficult to grasp.

  here's the third possibility, and the one i'm curious about:  kexec
is configured and i don't retain the initrd.  in that case, here's the
code that's executed:

===== start =====

         * If the initrd region is overlapped with crashkernel reserved region,
         * free only memory that is not part of crashkernel region.
         */
        if (initrd_start < crashk_end && initrd_end > crashk_start) {
                /*
                 * Initialize initrd memory region since the kexec boot does
                 * not do.
                 */
                memset((void *)initrd_start, 0, initrd_end - initrd_start);
                if (initrd_start < crashk_start)
                        free_initrd_mem(initrd_start, crashk_start);
                if (initrd_end > crashk_end)
                        free_initrd_mem(crashk_end, initrd_end);
        } else
#endif
                free_initrd_mem(initrd_start, initrd_end);
===== end =====

  now, if kexec is configured but there is no overlap between the
initrd space and the kexec space, then free_initrd_mem() is called
normally.  but if there *is* overlap, there are two possible calls to
free_initrd_mem() to free the non-kexec space, but it's that call to
memset() that i don't understand -- what's the value of setting the
entire range of the initrd space to zero?

  i don't know enough about kexec to know what that might mean but, in
the normal case, memory about to be freed is not cleared, so what's
the reasoning for that single line:

                memset((void *)initrd_start, 0, initrd_end - initrd_start);

note that that will clear the *entire* initrd range -- both the part
that overlaps the kexec range, and that part that doesn't.

  so what's the reasoning here?  is that zeroing of space actually
necessary?

rday

-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================






More information about the Kernelnewbies mailing list