Fix powerpc and sparc64 build failures caused by un-nesting memory

map iterators.
This commit is contained in:
Colin Watson 2013-01-21 14:41:06 +00:00
parent 6a0db4492c
commit ed12a00309
3 changed files with 57 additions and 27 deletions

View file

@ -1,3 +1,8 @@
2013-01-21 Colin Watson <cjwatson@ubuntu.com>
Fix powerpc and sparc64 build failures caused by un-nesting memory
map iterators.
2013-01-21 Colin Watson <cjwatson@ubuntu.com> 2013-01-21 Colin Watson <cjwatson@ubuntu.com>
* grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate): Fix * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate): Fix

View file

@ -51,37 +51,47 @@ static char *linux_args;
typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), typedef void (*kernel_entry_t) (void *, unsigned long, int (void *),
unsigned long, unsigned long); unsigned long, unsigned long);
/* Context for grub_linux_claimmap_iterate. */
struct grub_linux_claimmap_iterate_ctx
{
grub_addr_t target;
grub_size_t size;
grub_size_t align;
grub_addr_t found_addr;
};
/* Helper for grub_linux_claimmap_iterate. */ /* Helper for grub_linux_claimmap_iterate. */
static int static int
alloc_mem (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, alloc_mem (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
void *data) void *data)
{ {
grub_addr_t *found_addr = data; struct grub_linux_claimmap_iterate_ctx *ctx = data;
grub_uint64_t end = addr + len; grub_uint64_t end = addr + len;
addr = ALIGN_UP (addr, align); addr = ALIGN_UP (addr, ctx->align);
target = ALIGN_UP (target, align); ctx->target = ALIGN_UP (ctx->target, ctx->align);
/* Target above the memory chunk. */ /* Target above the memory chunk. */
if (type != GRUB_MEMORY_AVAILABLE || target > end) if (type != GRUB_MEMORY_AVAILABLE || ctx->target > end)
return 0; return 0;
/* Target inside the memory chunk. */ /* Target inside the memory chunk. */
if (target >= addr && target < end && size <= end - target) if (ctx->target >= addr && ctx->target < end &&
ctx->size <= end - ctx->target)
{ {
if (grub_claimmap (target, size) == GRUB_ERR_NONE) if (grub_claimmap (ctx->target, ctx->size) == GRUB_ERR_NONE)
{ {
*found_addr = target; ctx->found_addr = ctx->target;
return 1; return 1;
} }
grub_print_error (); grub_print_error ();
} }
/* Target below the memory chunk. */ /* Target below the memory chunk. */
if (target < addr && addr + size <= end) if (ctx->target < addr && addr + ctx->size <= end)
{ {
if (grub_claimmap (addr, size) == GRUB_ERR_NONE) if (grub_claimmap (addr, ctx->size) == GRUB_ERR_NONE)
{ {
*found_addr = addr; ctx->found_addr = addr;
return 1; return 1;
} }
grub_print_error (); grub_print_error ();
@ -93,11 +103,16 @@ static grub_addr_t
grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size,
grub_size_t align) grub_size_t align)
{ {
grub_addr_t found_addr = (grub_addr_t) -1; struct grub_linux_claimmap_iterate_ctx ctx = {
.target = target,
.size = size,
.align = align,
.found_addr = (grub_addr_t) -1
};
grub_machine_mmap_iterate (alloc_mem, &found_addr); grub_machine_mmap_iterate (alloc_mem, &ctx);
return found_addr; return ctx.found_addr;
} }
static grub_err_t static grub_err_t

View file

@ -180,32 +180,39 @@ grub_linux_unload (void)
#define FOUR_MB (4 * 1024 * 1024) #define FOUR_MB (4 * 1024 * 1024)
/* Context for alloc_phys. */
struct alloc_phys_ctx
{
grub_addr_t size;
grub_addr_t ret;
};
/* Helper for alloc_phys. */ /* Helper for alloc_phys. */
static int static int
alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len, alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len,
grub_memory_type_t type, void *data) grub_memory_type_t type, void *data)
{ {
grub_addr_t *ret = data; struct alloc_phys_ctx *ctx = data;
grub_addr_t end = addr + len; grub_addr_t end = addr + len;
if (type != 1) if (type != 1)
return 0; return 0;
addr = ALIGN_UP (addr, FOUR_MB); addr = ALIGN_UP (addr, FOUR_MB);
if (addr + size >= end) if (addr + ctx->size >= end)
return 0; return 0;
if (addr >= grub_phys_start && addr < grub_phys_end) if (addr >= grub_phys_start && addr < grub_phys_end)
{ {
addr = ALIGN_UP (grub_phys_end, FOUR_MB); addr = ALIGN_UP (grub_phys_end, FOUR_MB);
if (addr + size >= end) if (addr + ctx->size >= end)
return 0; return 0;
} }
if ((addr + size) >= grub_phys_start if ((addr + ctx->size) >= grub_phys_start
&& (addr + size) < grub_phys_end) && (addr + ctx->size) < grub_phys_end)
{ {
addr = ALIGN_UP (grub_phys_end, FOUR_MB); addr = ALIGN_UP (grub_phys_end, FOUR_MB);
if (addr + size >= end) if (addr + ctx->size >= end)
return 0; return 0;
} }
@ -216,30 +223,33 @@ alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len,
if (addr >= linux_paddr && addr < linux_end) if (addr >= linux_paddr && addr < linux_end)
{ {
addr = linux_end; addr = linux_end;
if (addr + size >= end) if (addr + ctx->size >= end)
return 0; return 0;
} }
if ((addr + size) >= linux_paddr if ((addr + ctx->size) >= linux_paddr
&& (addr + size) < linux_end) && (addr + ctx->size) < linux_end)
{ {
addr = linux_end; addr = linux_end;
if (addr + size >= end) if (addr + ctx->size >= end)
return 0; return 0;
} }
} }
*ret = addr; ctx->ret = addr;
return 1; return 1;
} }
static grub_addr_t static grub_addr_t
alloc_phys (grub_addr_t size) alloc_phys (grub_addr_t size)
{ {
grub_addr_t ret = (grub_addr_t) -1; struct alloc_phys_ctx ctx = {
.size = size,
.ret = (grub_addr_t) -1
};
grub_machine_mmap_iterate (alloc_phys_choose, &ret); grub_machine_mmap_iterate (alloc_phys_choose, &ctx);
return ret; return ctx.ret;
} }
static grub_err_t static grub_err_t