Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75c0b3b4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm:
  ARM: 6870/1: The mandatory barrier rmb() must be a dsb() in for device accesses
  ARM: 6892/1: handle ptrace requests to change PC during interrupted system calls
  ARM: 6890/1: memmap: only free allocated memmap entries when using SPARSEMEM
  ARM: zImage: the page table memory must be considered before relocation
  ARM: zImage: make sure not to relocate on top of the relocation code
  ARM: zImage: Fix bad SP address after relocating kernel
  ARM: zImage: make sure the stack is 64-bit aligned
  ARM: RiscPC: acornfb: fix section mismatches
  ARM: RiscPC: etherh: fix section mismatches
parents 3568bd97 a904f5f9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR	:= $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR	:= 0
ZBSSADDR	:= ALIGN(4)
ZBSSADDR	:= ALIGN(8)
endif

SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
+24 −11
Original line number Diff line number Diff line
@@ -179,15 +179,14 @@ not_angel:
		bl	cache_on

restart:	adr	r0, LC0
		ldmia	r0, {r1, r2, r3, r5, r6, r9, r11, r12}
		ldr	sp, [r0, #32]
		ldmia	r0, {r1, r2, r3, r6, r9, r11, r12}
		ldr	sp, [r0, #28]

		/*
		 * We might be running at a different address.  We need
		 * to fix up various pointers.
		 */
		sub	r0, r0, r1		@ calculate the delta offset
		add	r5, r5, r0		@ _start
		add	r6, r6, r0		@ _edata

#ifndef CONFIG_ZBOOT_ROM
@@ -206,31 +205,40 @@ restart: adr r0, LC0
/*
 * Check to see if we will overwrite ourselves.
 *   r4  = final kernel address
 *   r5  = start of this image
 *   r9  = size of decompressed image
 *   r10 = end of this image, including  bss/stack/malloc space if non XIP
 * We basically want:
 *   r4 >= r10 -> OK
 *   r4 + image length <= r5 -> OK
 *   r4 - 16k page directory >= r10 -> OK
 *   r4 + image length <= current position (pc) -> OK
 */
		add	r10, r10, #16384
		cmp	r4, r10
		bhs	wont_overwrite
		add	r10, r4, r9
		cmp	r10, r5
   ARM(		cmp	r10, pc		)
 THUMB(		mov	lr, pc		)
 THUMB(		cmp	r10, lr		)
		bls	wont_overwrite

/*
 * Relocate ourselves past the end of the decompressed kernel.
 *   r5  = start of this image
 *   r6  = _edata
 *   r10 = end of the decompressed kernel
 * Because we always copy ahead, we need to do it from the end and go
 * backward in case the source and destination overlap.
 */
		/* Round up to next 256-byte boundary. */
		add	r10, r10, #256
		/*
		 * Bump to the next 256-byte boundary with the size of
		 * the relocation code added. This avoids overwriting
		 * ourself when the offset is small.
		 */
		add	r10, r10, #((reloc_code_end - restart + 256) & ~255)
		bic	r10, r10, #255

		/* Get start of code we want to copy and align it down. */
		adr	r5, restart
		bic	r5, r5, #31

		sub	r9, r6, r5		@ size to copy
		add	r9, r9, #31		@ rounded up to a multiple
		bic	r9, r9, #31		@ ... of 32 bytes
@@ -245,6 +253,11 @@ restart: adr r0, LC0
		/* Preserve offset to relocated code. */
		sub	r6, r9, r6

#ifndef CONFIG_ZBOOT_ROM
		/* cache_clean_flush may use the stack, so relocate it */
		add	sp, sp, r6
#endif

		bl	cache_clean_flush

		adr	r0, BSYM(restart)
@@ -333,7 +346,6 @@ not_relocated: mov r0, #0
LC0:		.word	LC0			@ r1
		.word	__bss_start		@ r2
		.word	_end			@ r3
		.word	_start			@ r5
		.word	_edata			@ r6
		.word	_image_size		@ r9
		.word	_got_start		@ r11
@@ -1062,6 +1074,7 @@ memdump: mov r12, r0
#endif

		.ltorg
reloc_code_end:

		.align
		.section ".stack", "aw", %nobits
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ SECTIONS
  .bss			: { *(.bss) }
  _end = .;

  . = ALIGN(8);		/* the stack must be 64-bit aligned */
  .stack		: { *(.stack) }

  .stab 0		: { *(.stab) }
+1 −1
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ extern unsigned int user_debug;
#include <mach/barriers.h>
#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
#define mb()		do { dsb(); outer_sync(); } while (0)
#define rmb()		dmb()
#define rmb()		dsb()
#define wmb()		mb()
#else
#include <asm/memory.h>
+53 −37
Original line number Diff line number Diff line
@@ -597,45 +597,19 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
	return err;
}

static inline void setup_syscall_restart(struct pt_regs *regs)
{
	regs->ARM_r0 = regs->ARM_ORIG_r0;
	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
}

/*
 * OK, we're invoking a handler
 */	
static int
handle_signal(unsigned long sig, struct k_sigaction *ka,
	      siginfo_t *info, sigset_t *oldset,
	      struct pt_regs * regs, int syscall)
	      struct pt_regs * regs)
{
	struct thread_info *thread = current_thread_info();
	struct task_struct *tsk = current;
	int usig = sig;
	int ret;

	/*
	 * If we were from a system call, check for system call restarting...
	 */
	if (syscall) {
		switch (regs->ARM_r0) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->ARM_r0 = -EINTR;
			break;
		case -ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->ARM_r0 = -EINTR;
				break;
			}
			/* fallthrough */
		case -ERESTARTNOINTR:
			setup_syscall_restart(regs);
		}
	}

	/*
	 * translate the signal
	 */
@@ -685,6 +659,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
 */
static void do_signal(struct pt_regs *regs, int syscall)
{
	unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
	struct k_sigaction ka;
	siginfo_t info;
	int signr;
@@ -698,18 +673,61 @@ static void do_signal(struct pt_regs *regs, int syscall)
	if (!user_mode(regs))
		return;

	/*
	 * If we were from a system call, check for system call restarting...
	 */
	if (syscall) {
		continue_addr = regs->ARM_pc;
		restart_addr = continue_addr - (thumb_mode(regs) ? 2 : 4);
		retval = regs->ARM_r0;

		/*
		 * Prepare for system call restart.  We do this here so that a
		 * debugger will see the already changed PSW.
		 */
		switch (retval) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->ARM_r0 = regs->ARM_ORIG_r0;
			regs->ARM_pc = restart_addr;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->ARM_r0 = -EINTR;
			break;
		}
	}

	if (try_to_freeze())
		goto no_signal;

	/*
	 * Get the signal to deliver.  When running under ptrace, at this
	 * point the debugger may change all our registers ...
	 */
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		sigset_t *oldset;

		/*
		 * Depending on the signal settings we may need to revert the
		 * decision to restart the system call.  But skip this if a
		 * debugger has chosen to restart at a different PC.
		 */
		if (regs->ARM_pc == restart_addr) {
			if (retval == -ERESTARTNOHAND
			    || (retval == -ERESTARTSYS
				&& !(ka.sa.sa_flags & SA_RESTART))) {
				regs->ARM_r0 = -EINTR;
				regs->ARM_pc = continue_addr;
			}
		}

		if (test_thread_flag(TIF_RESTORE_SIGMASK))
			oldset = &current->saved_sigmask;
		else
			oldset = &current->blocked;
		if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
			/*
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
@@ -723,11 +741,14 @@ static void do_signal(struct pt_regs *regs, int syscall)
	}

 no_signal:
	if (syscall) {
		/*
	 * No signal to deliver to the process - restart the syscall.
		 * Handle restarting a different system call.  As above,
		 * if a debugger has chosen to restart at a different PC,
		 * ignore the restart.
		 */
	if (syscall) {
		if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) {
		if (retval == -ERESTART_RESTARTBLOCK
		    && regs->ARM_pc == continue_addr) {
			if (thumb_mode(regs)) {
				regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
				regs->ARM_pc -= 2;
@@ -750,11 +771,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
#endif
			}
		}
		if (regs->ARM_r0 == -ERESTARTNOHAND ||
		    regs->ARM_r0 == -ERESTARTSYS ||
		    regs->ARM_r0 == -ERESTARTNOINTR) {
			setup_syscall_restart(regs);
		}

		/* If there's no signal to deliver, we just put the saved sigmask
		 * back.
Loading