debuggers.hg

changeset 21106:377433a77d70

Fix 21051:bcc09eb7379f "x86_32: Relocate multiboot modules to below 1GB."

Copy the modules in ascending order in memory, rather than decsending
order. This reduces the likelihood of the second relocation (in
setup.c) corrupting modules through accidental overwriting.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Mar 24 11:06:48 2010 +0000 (2010-03-24)
parents 3c8719d2cb8d
children 12aebcebff2a
files xen/arch/x86/boot/reloc.c
line diff
     1.1 --- a/xen/arch/x86/boot/reloc.c	Wed Mar 24 11:05:06 2010 +0000
     1.2 +++ b/xen/arch/x86/boot/reloc.c	Wed Mar 24 11:06:48 2010 +0000
     1.3 @@ -68,29 +68,37 @@ multiboot_info_t *reloc(multiboot_info_t
     1.4      {
     1.5          module_t *mods = reloc_mbi_struct(
     1.6              (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
     1.7 +        u32 max_addr = 0;
     1.8 +
     1.9          mbi->mods_addr = (u32)mods;
    1.10 +
    1.11          for ( i = 0; i < mbi->mods_count; i++ )
    1.12          {
    1.13 -#if XEN_BITSPERLONG == 32
    1.14 -            /*
    1.15 -             * 32-bit Xen only maps bottom 1GB of memory at boot time.
    1.16 -             * Relocate modules which extend beyond this (GRUB2 in particular
    1.17 -             * likes to place modules as high as possible below 4GB).
    1.18 -             */
    1.19 +            if ( mods[i].string )
    1.20 +                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
    1.21 +            if ( mods[i].mod_end > max_addr )
    1.22 +                max_addr = mods[i].mod_end;
    1.23 +        }
    1.24 +
    1.25 +        /*
    1.26 +         * 32-bit Xen only maps bottom 1GB of memory at boot time. Relocate 
    1.27 +         * modules which extend beyond this (GRUB2 in particular likes to 
    1.28 +         * place modules as high as possible below 4GB).
    1.29 +         */
    1.30  #define BOOTMAP_END (1ul<<30) /* 1GB */
    1.31 -            static void *mod_alloc = (void *)BOOTMAP_END;
    1.32 -            u32 mod_len = mods[i].mod_end - mods[i].mod_start;
    1.33 -            if ( mods[i].mod_end > BOOTMAP_END )
    1.34 +        if ( (XEN_BITSPERLONG == 32) && (max_addr > BOOTMAP_END) )
    1.35 +        {
    1.36 +            char *mod_alloc = (char *)BOOTMAP_END;
    1.37 +            for ( i = 0; i < mbi->mods_count; i++ )
    1.38 +                mod_alloc -= mods[i].mod_end - mods[i].mod_start;
    1.39 +            for ( i = 0; i < mbi->mods_count; i++ )
    1.40              {
    1.41 -                mod_alloc = (void *)
    1.42 -                    (((unsigned long)mod_alloc - mod_len) & ~15ul);
    1.43 +                u32 mod_len = mods[i].mod_end - mods[i].mod_start;
    1.44                  mods[i].mod_start = (u32)memcpy(
    1.45                      mod_alloc, (char *)mods[i].mod_start, mod_len);
    1.46                  mods[i].mod_end = mods[i].mod_start + mod_len;
    1.47 +                mod_alloc += mod_len;
    1.48              }
    1.49 -#endif
    1.50 -            if ( mods[i].string )
    1.51 -                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
    1.52          }
    1.53      }
    1.54