aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/kernel/sys_sparc.c48
-rw-r--r--arch/sparc64/kernel/rtrap.S6
-rw-r--r--arch/sparc64/kernel/signal.c21
-rw-r--r--arch/sparc64/kernel/signal32.c13
-rw-r--r--arch/sparc64/kernel/sys_sparc.c36
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c33
-rw-r--r--include/asm-sparc/mman.h5
-rw-r--r--include/asm-sparc64/mman.h5
-rw-r--r--include/asm-sparc64/thread_info.h28
-rw-r--r--lib/lmb.c45
10 files changed, 89 insertions, 151 deletions
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index e995491c4436..3c6b49a53ae8 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -219,7 +219,7 @@ out:
219 return err; 219 return err;
220} 220}
221 221
222int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) 222int sparc_mmap_check(unsigned long addr, unsigned long len)
223{ 223{
224 if (ARCH_SUN4C_SUN4 && 224 if (ARCH_SUN4C_SUN4 &&
225 (len > 0x20000000 || 225 (len > 0x20000000 ||
@@ -295,52 +295,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr,
295 unsigned long old_len, unsigned long new_len, 295 unsigned long old_len, unsigned long new_len,
296 unsigned long flags, unsigned long new_addr) 296 unsigned long flags, unsigned long new_addr)
297{ 297{
298 struct vm_area_struct *vma;
299 unsigned long ret = -EINVAL; 298 unsigned long ret = -EINVAL;
300 if (ARCH_SUN4C_SUN4) { 299
301 if (old_len > 0x20000000 || new_len > 0x20000000) 300 if (unlikely(sparc_mmap_check(addr, old_len)))
302 goto out; 301 goto out;
303 if (addr < 0xe0000000 && addr + old_len > 0x20000000) 302 if (unlikely(sparc_mmap_check(new_addr, new_len)))
304 goto out;
305 }
306 if (old_len > TASK_SIZE - PAGE_SIZE ||
307 new_len > TASK_SIZE - PAGE_SIZE)
308 goto out; 303 goto out;
309 down_write(&current->mm->mmap_sem); 304 down_write(&current->mm->mmap_sem);
310 if (flags & MREMAP_FIXED) {
311 if (ARCH_SUN4C_SUN4 &&
312 new_addr < 0xe0000000 &&
313 new_addr + new_len > 0x20000000)
314 goto out_sem;
315 if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)
316 goto out_sem;
317 } else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&
318 addr + new_len > 0x20000000) ||
319 addr + new_len > TASK_SIZE - PAGE_SIZE) {
320 unsigned long map_flags = 0;
321 struct file *file = NULL;
322
323 ret = -ENOMEM;
324 if (!(flags & MREMAP_MAYMOVE))
325 goto out_sem;
326
327 vma = find_vma(current->mm, addr);
328 if (vma) {
329 if (vma->vm_flags & VM_SHARED)
330 map_flags |= MAP_SHARED;
331 file = vma->vm_file;
332 }
333
334 new_addr = get_unmapped_area(file, addr, new_len,
335 vma ? vma->vm_pgoff : 0,
336 map_flags);
337 ret = new_addr;
338 if (new_addr & ~PAGE_MASK)
339 goto out_sem;
340 flags |= MREMAP_FIXED;
341 }
342 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 305 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
343out_sem:
344 up_write(&current->mm->mmap_sem); 306 up_write(&current->mm->mmap_sem);
345out: 307out:
346 return ret; 308 return ret;
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index b9b785fd8b46..16689b2930db 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -46,7 +46,7 @@ __handle_user_windows:
46 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 46 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
47 ldx [%g6 + TI_FLAGS], %l0 47 ldx [%g6 + TI_FLAGS], %l0
48 48
491: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 491: andcc %l0, _TIF_SIGPENDING, %g0
50 be,pt %xcc, __handle_user_windows_continue 50 be,pt %xcc, __handle_user_windows_continue
51 nop 51 nop
52 mov %l5, %o1 52 mov %l5, %o1
@@ -86,7 +86,7 @@ __handle_perfctrs:
86 wrpr %g0, RTRAP_PSTATE, %pstate 86 wrpr %g0, RTRAP_PSTATE, %pstate
87 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 87 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
88 ldx [%g6 + TI_FLAGS], %l0 88 ldx [%g6 + TI_FLAGS], %l0
891: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 891: andcc %l0, _TIF_SIGPENDING, %g0
90 90
91 be,pt %xcc, __handle_perfctrs_continue 91 be,pt %xcc, __handle_perfctrs_continue
92 sethi %hi(TSTATE_PEF), %o0 92 sethi %hi(TSTATE_PEF), %o0
@@ -195,7 +195,7 @@ __handle_preemption_continue:
195 andcc %l1, %o0, %g0 195 andcc %l1, %o0, %g0
196 andcc %l0, _TIF_NEED_RESCHED, %g0 196 andcc %l0, _TIF_NEED_RESCHED, %g0
197 bne,pn %xcc, __handle_preemption 197 bne,pn %xcc, __handle_preemption
198 andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 198 andcc %l0, _TIF_SIGPENDING, %g0
199 bne,pn %xcc, __handle_signal 199 bne,pn %xcc, __handle_signal
200__handle_signal_continue: 200__handle_signal_continue:
201 ldub [%g6 + TI_WSAVED], %o2 201 ldub [%g6 + TI_WSAVED], %o2
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 2378482c2aab..6e4dc67d16af 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set)
247 247
248 current->state = TASK_INTERRUPTIBLE; 248 current->state = TASK_INTERRUPTIBLE;
249 schedule(); 249 schedule();
250 set_thread_flag(TIF_RESTORE_SIGMASK); 250
251 set_restore_sigmask();
252
251 return -ERESTARTNOHAND; 253 return -ERESTARTNOHAND;
252} 254}
253 255
@@ -537,7 +539,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
537 } else 539 } else
538 restart_syscall = 0; 540 restart_syscall = 0;
539 541
540 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 542 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
541 oldset = &current->saved_sigmask; 543 oldset = &current->saved_sigmask;
542 else 544 else
543 oldset = &current->blocked; 545 oldset = &current->blocked;
@@ -566,13 +568,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
566 syscall_restart(orig_i0, regs, &ka.sa); 568 syscall_restart(orig_i0, regs, &ka.sa);
567 handle_signal(signr, &ka, &info, oldset, regs); 569 handle_signal(signr, &ka, &info, oldset, regs);
568 570
569 /* a signal was successfully delivered; the saved 571 /* A signal was successfully delivered; the saved
570 * sigmask will have been stored in the signal frame, 572 * sigmask will have been stored in the signal frame,
571 * and will be restored by sigreturn, so we can simply 573 * and will be restored by sigreturn, so we can simply
572 * clear the TIF_RESTORE_SIGMASK flag. 574 * clear the TS_RESTORE_SIGMASK flag.
573 */ 575 */
574 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 576 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
575 clear_thread_flag(TIF_RESTORE_SIGMASK);
576 return; 577 return;
577 } 578 }
578 if (restart_syscall && 579 if (restart_syscall &&
@@ -591,17 +592,17 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
591 regs->tnpc -= 4; 592 regs->tnpc -= 4;
592 } 593 }
593 594
594 /* if there's no signal to deliver, we just put the saved sigmask 595 /* If there's no signal to deliver, we just put the saved sigmask
595 * back 596 * back
596 */ 597 */
597 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 598 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
598 clear_thread_flag(TIF_RESTORE_SIGMASK); 599 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
599 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 600 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
600 } 601 }
601} 602}
602 603
603void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) 604void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
604{ 605{
605 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 606 if (thread_info_flags & _TIF_SIGPENDING)
606 do_signal(regs, orig_i0); 607 do_signal(regs, orig_i0);
607} 608}
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 3f19e9af3d1b..97cdd1bf4a10 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -788,13 +788,12 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
788 syscall_restart32(orig_i0, regs, &ka.sa); 788 syscall_restart32(orig_i0, regs, &ka.sa);
789 handle_signal32(signr, &ka, &info, oldset, regs); 789 handle_signal32(signr, &ka, &info, oldset, regs);
790 790
791 /* a signal was successfully delivered; the saved 791 /* A signal was successfully delivered; the saved
792 * sigmask will have been stored in the signal frame, 792 * sigmask will have been stored in the signal frame,
793 * and will be restored by sigreturn, so we can simply 793 * and will be restored by sigreturn, so we can simply
794 * clear the TIF_RESTORE_SIGMASK flag. 794 * clear the TS_RESTORE_SIGMASK flag.
795 */ 795 */
796 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 796 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
797 clear_thread_flag(TIF_RESTORE_SIGMASK);
798 return; 797 return;
799 } 798 }
800 if (restart_syscall && 799 if (restart_syscall &&
@@ -813,11 +812,11 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
813 regs->tnpc -= 4; 812 regs->tnpc -= 4;
814 } 813 }
815 814
816 /* if there's no signal to deliver, we just put the saved sigmask 815 /* If there's no signal to deliver, we just put the saved sigmask
817 * back 816 * back
818 */ 817 */
819 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 818 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
820 clear_thread_flag(TIF_RESTORE_SIGMASK); 819 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
821 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 820 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
822 } 821 }
823} 822}
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 0dbc941f130e..ac1bff58c1ac 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality)
542 return ret; 542 return ret;
543} 543}
544 544
545int sparc64_mmap_check(unsigned long addr, unsigned long len, 545int sparc64_mmap_check(unsigned long addr, unsigned long len)
546 unsigned long flags)
547{ 546{
548 if (test_thread_flag(TIF_32BIT)) { 547 if (test_thread_flag(TIF_32BIT)) {
549 if (len >= STACK_TOP32) 548 if (len >= STACK_TOP32)
@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
609 unsigned long old_len, unsigned long new_len, 608 unsigned long old_len, unsigned long new_len,
610 unsigned long flags, unsigned long new_addr) 609 unsigned long flags, unsigned long new_addr)
611{ 610{
612 struct vm_area_struct *vma;
613 unsigned long ret = -EINVAL; 611 unsigned long ret = -EINVAL;
614 612
615 if (test_thread_flag(TIF_32BIT)) 613 if (test_thread_flag(TIF_32BIT))
616 goto out; 614 goto out;
617 if (unlikely(new_len >= VA_EXCLUDE_START)) 615 if (unlikely(new_len >= VA_EXCLUDE_START))
618 goto out; 616 goto out;
619 if (unlikely(invalid_64bit_range(addr, old_len))) 617 if (unlikely(sparc64_mmap_check(addr, old_len)))
618 goto out;
619 if (unlikely(sparc64_mmap_check(new_addr, new_len)))
620 goto out; 620 goto out;
621 621
622 down_write(&current->mm->mmap_sem); 622 down_write(&current->mm->mmap_sem);
623 if (flags & MREMAP_FIXED) {
624 if (invalid_64bit_range(new_addr, new_len))
625 goto out_sem;
626 } else if (invalid_64bit_range(addr, new_len)) {
627 unsigned long map_flags = 0;
628 struct file *file = NULL;
629
630 ret = -ENOMEM;
631 if (!(flags & MREMAP_MAYMOVE))
632 goto out_sem;
633
634 vma = find_vma(current->mm, addr);
635 if (vma) {
636 if (vma->vm_flags & VM_SHARED)
637 map_flags |= MAP_SHARED;
638 file = vma->vm_file;
639 }
640
641 /* MREMAP_FIXED checked above. */
642 new_addr = get_unmapped_area(file, addr, new_len,
643 vma ? vma->vm_pgoff : 0,
644 map_flags);
645 ret = new_addr;
646 if (new_addr & ~PAGE_MASK)
647 goto out_sem;
648 flags |= MREMAP_FIXED;
649 }
650 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 623 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
651out_sem:
652 up_write(&current->mm->mmap_sem); 624 up_write(&current->mm->mmap_sem);
653out: 625out:
654 return ret; 626 return ret;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 1aa4288125f2..ba5bd626b39e 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -867,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
867 unsigned long old_len, unsigned long new_len, 867 unsigned long old_len, unsigned long new_len,
868 unsigned long flags, u32 __new_addr) 868 unsigned long flags, u32 __new_addr)
869{ 869{
870 struct vm_area_struct *vma;
871 unsigned long ret = -EINVAL; 870 unsigned long ret = -EINVAL;
872 unsigned long new_addr = __new_addr; 871 unsigned long new_addr = __new_addr;
873 872
874 if (old_len > STACK_TOP32 || new_len > STACK_TOP32) 873 if (unlikely(sparc64_mmap_check(addr, old_len)))
875 goto out; 874 goto out;
876 if (addr > STACK_TOP32 - old_len) 875 if (unlikely(sparc64_mmap_check(new_addr, new_len)))
877 goto out; 876 goto out;
878 down_write(&current->mm->mmap_sem); 877 down_write(&current->mm->mmap_sem);
879 if (flags & MREMAP_FIXED) {
880 if (new_addr > STACK_TOP32 - new_len)
881 goto out_sem;
882 } else if (addr > STACK_TOP32 - new_len) {
883 unsigned long map_flags = 0;
884 struct file *file = NULL;
885
886 ret = -ENOMEM;
887 if (!(flags & MREMAP_MAYMOVE))
888 goto out_sem;
889
890 vma = find_vma(current->mm, addr);
891 if (vma) {
892 if (vma->vm_flags & VM_SHARED)
893 map_flags |= MAP_SHARED;
894 file = vma->vm_file;
895 }
896
897 /* MREMAP_FIXED checked above. */
898 new_addr = get_unmapped_area(file, addr, new_len,
899 vma ? vma->vm_pgoff : 0,
900 map_flags);
901 ret = new_addr;
902 if (new_addr & ~PAGE_MASK)
903 goto out_sem;
904 flags |= MREMAP_FIXED;
905 }
906 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 878 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
907out_sem:
908 up_write(&current->mm->mmap_sem); 879 up_write(&current->mm->mmap_sem);
909out: 880out:
910 return ret; 881 return ret;
diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
index e18be984c01d..3d16b40bb8ef 100644
--- a/include/asm-sparc/mman.h
+++ b/include/asm-sparc/mman.h
@@ -24,9 +24,8 @@
24 24
25#ifdef __KERNEL__ 25#ifdef __KERNEL__
26#ifndef __ASSEMBLY__ 26#ifndef __ASSEMBLY__
27#define arch_mmap_check sparc_mmap_check 27#define arch_mmap_check(addr,len,flags) sparc_mmap_check(addr,len)
28int sparc_mmap_check(unsigned long addr, unsigned long len, 28int sparc_mmap_check(unsigned long addr, unsigned long len);
29 unsigned long flags);
30#endif 29#endif
31#endif 30#endif
32 31
diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
index e584563b56eb..625be4d61baf 100644
--- a/include/asm-sparc64/mman.h
+++ b/include/asm-sparc64/mman.h
@@ -24,9 +24,8 @@
24 24
25#ifdef __KERNEL__ 25#ifdef __KERNEL__
26#ifndef __ASSEMBLY__ 26#ifndef __ASSEMBLY__
27#define arch_mmap_check sparc64_mmap_check 27#define arch_mmap_check(addr,len,flags) sparc64_mmap_check(addr,len)
28int sparc64_mmap_check(unsigned long addr, unsigned long len, 28int sparc64_mmap_check(unsigned long addr, unsigned long len);
29 unsigned long flags);
30#endif 29#endif
31#endif 30#endif
32 31
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index 71e42d1a80d9..e5873e385306 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -38,7 +38,7 @@ struct thread_info {
38 struct task_struct *task; 38 struct task_struct *task;
39 unsigned long flags; 39 unsigned long flags;
40 __u8 fpsaved[7]; 40 __u8 fpsaved[7];
41 __u8 pad; 41 __u8 status;
42 unsigned long ksp; 42 unsigned long ksp;
43 43
44 /* D$ line 2 */ 44 /* D$ line 2 */
@@ -217,7 +217,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
217 * nop 217 * nop
218 */ 218 */
219#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 219#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
220#define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */ 220/* flags bit 1 is available */
221#define TIF_SIGPENDING 2 /* signal pending */ 221#define TIF_SIGPENDING 2 /* signal pending */
222#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 222#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
223#define TIF_PERFCTR 4 /* performance counters active */ 223#define TIF_PERFCTR 4 /* performance counters active */
@@ -244,14 +244,34 @@ register struct thread_info *current_thread_info_reg asm("g6");
244#define _TIF_32BIT (1<<TIF_32BIT) 244#define _TIF_32BIT (1<<TIF_32BIT)
245#define _TIF_SECCOMP (1<<TIF_SECCOMP) 245#define _TIF_SECCOMP (1<<TIF_SECCOMP)
246#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 246#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
247#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
248#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) 247#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
249#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 248#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
250 249
251#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ 250#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \
252 (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \ 251 (_TIF_SIGPENDING | \
253 _TIF_NEED_RESCHED | _TIF_PERFCTR)) 252 _TIF_NEED_RESCHED | _TIF_PERFCTR))
254 253
254/*
255 * Thread-synchronous status.
256 *
257 * This is different from the flags in that nobody else
258 * ever touches our thread-synchronous status, so we don't
259 * have to worry about atomic accesses.
260 *
261 * Note that there are only 8 bits available.
262 */
263#define TS_RESTORE_SIGMASK 0x0001 /* restore signal mask in do_signal() */
264
265#ifndef __ASSEMBLY__
266#define HAVE_SET_RESTORE_SIGMASK 1
267static inline void set_restore_sigmask(void)
268{
269 struct thread_info *ti = current_thread_info();
270 ti->status |= TS_RESTORE_SIGMASK;
271 set_bit(TIF_SIGPENDING, &ti->flags);
272}
273#endif /* !__ASSEMBLY__ */
274
255#endif /* __KERNEL__ */ 275#endif /* __KERNEL__ */
256 276
257#endif /* _ASM_THREAD_INFO_H */ 277#endif /* _ASM_THREAD_INFO_H */
diff --git a/lib/lmb.c b/lib/lmb.c
index 83287d3869a3..867f7b5a8231 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -19,31 +19,42 @@
19 19
20struct lmb lmb; 20struct lmb lmb;
21 21
22static int lmb_debug;
23
24static int __init early_lmb(char *p)
25{
26 if (p && strstr(p, "debug"))
27 lmb_debug = 1;
28 return 0;
29}
30early_param("lmb", early_lmb);
31
22void lmb_dump_all(void) 32void lmb_dump_all(void)
23{ 33{
24#ifdef DEBUG
25 unsigned long i; 34 unsigned long i;
26 35
27 pr_debug("lmb_dump_all:\n"); 36 if (!lmb_debug)
28 pr_debug(" memory.cnt = 0x%lx\n", lmb.memory.cnt); 37 return;
29 pr_debug(" memory.size = 0x%llx\n", 38
39 pr_info("lmb_dump_all:\n");
40 pr_info(" memory.cnt = 0x%lx\n", lmb.memory.cnt);
41 pr_info(" memory.size = 0x%llx\n",
30 (unsigned long long)lmb.memory.size); 42 (unsigned long long)lmb.memory.size);
31 for (i=0; i < lmb.memory.cnt ;i++) { 43 for (i=0; i < lmb.memory.cnt ;i++) {
32 pr_debug(" memory.region[0x%x].base = 0x%llx\n", 44 pr_info(" memory.region[0x%lx].base = 0x%llx\n",
33 i, (unsigned long long)lmb.memory.region[i].base); 45 i, (unsigned long long)lmb.memory.region[i].base);
34 pr_debug(" .size = 0x%llx\n", 46 pr_info(" .size = 0x%llx\n",
35 (unsigned long long)lmb.memory.region[i].size); 47 (unsigned long long)lmb.memory.region[i].size);
36 } 48 }
37 49
38 pr_debug(" reserved.cnt = 0x%lx\n", lmb.reserved.cnt); 50 pr_info(" reserved.cnt = 0x%lx\n", lmb.reserved.cnt);
39 pr_debug(" reserved.size = 0x%lx\n", lmb.reserved.size); 51 pr_info(" reserved.size = 0x%lx\n", lmb.reserved.size);
40 for (i=0; i < lmb.reserved.cnt ;i++) { 52 for (i=0; i < lmb.reserved.cnt ;i++) {
41 pr_debug(" reserved.region[0x%x].base = 0x%llx\n", 53 pr_info(" reserved.region[0x%lx].base = 0x%llx\n",
42 i, (unsigned long long)lmb.reserved.region[i].base); 54 i, (unsigned long long)lmb.reserved.region[i].base);
43 pr_debug(" .size = 0x%llx\n", 55 pr_info(" .size = 0x%llx\n",
44 (unsigned long long)lmb.reserved.region[i].size); 56 (unsigned long long)lmb.reserved.region[i].size);
45 } 57 }
46#endif /* DEBUG */
47} 58}
48 59
49static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2, 60static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2,
@@ -286,8 +297,7 @@ static u64 __init lmb_alloc_nid_unreserved(u64 start, u64 end,
286 j = lmb_overlaps_region(&lmb.reserved, base, size); 297 j = lmb_overlaps_region(&lmb.reserved, base, size);
287 if (j < 0) { 298 if (j < 0) {
288 /* this area isn't reserved, take it */ 299 /* this area isn't reserved, take it */
289 if (lmb_add_region(&lmb.reserved, base, 300 if (lmb_add_region(&lmb.reserved, base, size) < 0)
290 lmb_align_up(size, align)) < 0)
291 base = ~(u64)0; 301 base = ~(u64)0;
292 return base; 302 return base;
293 } 303 }
@@ -333,6 +343,10 @@ u64 __init lmb_alloc_nid(u64 size, u64 align, int nid,
333 struct lmb_region *mem = &lmb.memory; 343 struct lmb_region *mem = &lmb.memory;
334 int i; 344 int i;
335 345
346 BUG_ON(0 == size);
347
348 size = lmb_align_up(size, align);
349
336 for (i = 0; i < mem->cnt; i++) { 350 for (i = 0; i < mem->cnt; i++) {
337 u64 ret = lmb_alloc_nid_region(&mem->region[i], 351 u64 ret = lmb_alloc_nid_region(&mem->region[i],
338 nid_range, 352 nid_range,
@@ -370,6 +384,8 @@ u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr)
370 384
371 BUG_ON(0 == size); 385 BUG_ON(0 == size);
372 386
387 size = lmb_align_up(size, align);
388
373 /* On some platforms, make sure we allocate lowmem */ 389 /* On some platforms, make sure we allocate lowmem */
374 /* Note that LMB_REAL_LIMIT may be LMB_ALLOC_ANYWHERE */ 390 /* Note that LMB_REAL_LIMIT may be LMB_ALLOC_ANYWHERE */
375 if (max_addr == LMB_ALLOC_ANYWHERE) 391 if (max_addr == LMB_ALLOC_ANYWHERE)
@@ -393,8 +409,7 @@ u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr)
393 j = lmb_overlaps_region(&lmb.reserved, base, size); 409 j = lmb_overlaps_region(&lmb.reserved, base, size);
394 if (j < 0) { 410 if (j < 0) {
395 /* this area isn't reserved, take it */ 411 /* this area isn't reserved, take it */
396 if (lmb_add_region(&lmb.reserved, base, 412 if (lmb_add_region(&lmb.reserved, base, size) < 0)
397 lmb_align_up(size, align)) < 0)
398 return 0; 413 return 0;
399 return base; 414 return base;
400 } 415 }