From db1db167dd172955afe447f0bb020d8b9f792a68 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Mon, 8 Apr 2013 14:43:14 -0700 Subject: [PATCH] lib: genalloc: Use 64 bit types for holding allocations genalloc may be used to allocate physical addresses in addition to virtual addresses. On LPAE based systems, physical addresses are 64-bit which does not fit in an unsigned long. Change the type used for allocation internally to be 64 bit to ensure that genalloc can properly allocate physical addresses > 4GB. Ideally this will just be a temporary workaround until either a proper fix comes elsewhere or an alternative API is used to manage physical memory. Change-Id: Ib10b887730e0c6916de5d1e6f77e771c6cde14bb Signed-off-by: Laura Abbott --- include/linux/genalloc.h | 16 ++++++++-------- lib/genalloc.c | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index a87246c9cfc..3bb38ad2e8b 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -45,14 +45,14 @@ struct gen_pool_chunk { struct list_head next_chunk; /* next chunk in pool */ atomic_t avail; phys_addr_t phys_addr; /* physical starting address of memory chunk */ - unsigned long start_addr; /* starting address of memory chunk */ - unsigned long end_addr; /* ending address of memory chunk */ + u64 start_addr; /* starting address of memory chunk */ + u64 end_addr; /* ending address of memory chunk */ unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; extern struct gen_pool *gen_pool_create(int, int); -extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); -extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, +extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, u64); +extern int gen_pool_add_virt(struct gen_pool *, u64, phys_addr_t, size_t, int); /** * gen_pool_add - add a new chunk of special memory to the pool @@ -66,19 +66,19 @@ extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, * * Returns 0 on success or a -ve errno on failure. */ -static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, +static inline int gen_pool_add(struct gen_pool *pool, u64 addr, size_t size, int nid) { return gen_pool_add_virt(pool, addr, -1, size, nid); } extern void gen_pool_destroy(struct gen_pool *); -extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); +extern void gen_pool_free(struct gen_pool *, u64, size_t); extern void gen_pool_for_each_chunk(struct gen_pool *, void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); extern size_t gen_pool_avail(struct gen_pool *); extern size_t gen_pool_size(struct gen_pool *); -unsigned long __must_check +u64 __must_check gen_pool_alloc_aligned(struct gen_pool *pool, size_t size, unsigned alignment_order); @@ -90,7 +90,7 @@ gen_pool_alloc_aligned(struct gen_pool *pool, size_t size, * Allocate the requested number of bytes from the specified pool. * Uses a first-fit algorithm. */ -static inline unsigned long __must_check +static inline u64 __must_check gen_pool_alloc(struct gen_pool *pool, size_t size) { return gen_pool_alloc_aligned(pool, size, 0); diff --git a/lib/genalloc.c b/lib/genalloc.c index 9cf1b8b51ac..604ee0921fb 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -171,7 +171,7 @@ EXPORT_SYMBOL(gen_pool_create); * * Returns 0 on success or a -ve errno on failure. */ -int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys, +int gen_pool_add_virt(struct gen_pool *pool, u64 virt, phys_addr_t phys, size_t size, int nid) { struct gen_pool_chunk *chunk; @@ -208,7 +208,7 @@ EXPORT_SYMBOL(gen_pool_add_virt); * * Returns the physical address on success, or -1 on error. */ -phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr) +phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, u64 addr) { struct gen_pool_chunk *chunk; phys_addr_t paddr = -1; @@ -273,11 +273,11 @@ EXPORT_SYMBOL(gen_pool_destroy); * Uses a first-fit algorithm. Can not be used in NMI handler on * architectures without NMI-safe cmpxchg implementation. */ -unsigned long gen_pool_alloc_aligned(struct gen_pool *pool, size_t size, +u64 gen_pool_alloc_aligned(struct gen_pool *pool, size_t size, unsigned alignment_order) { struct gen_pool_chunk *chunk; - unsigned long addr = 0, align_mask = 0; + u64 addr = 0, align_mask = 0; int order = pool->min_alloc_order; int nbits, start_bit = 0, remain; @@ -314,7 +314,7 @@ retry: goto retry; } - addr = chunk->start_addr + ((unsigned long)start_bit << order); + addr = chunk->start_addr + ((u64)start_bit << order); size = nbits << pool->min_alloc_order; atomic_sub(size, &chunk->avail); break; @@ -334,7 +334,7 @@ EXPORT_SYMBOL(gen_pool_alloc_aligned); * pool. Can not be used in NMI handler on architectures without * NMI-safe cmpxchg implementation. */ -void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size) +void gen_pool_free(struct gen_pool *pool, u64 addr, size_t size) { struct gen_pool_chunk *chunk; int order = pool->min_alloc_order;