Commit d88867a2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm

Pull ARM development updates from Russell King:
 "Four changes for v6.4:

   - simplify the path to the top vmlinux

   - three patches to fix vfp with instrumentation enabled (eg lockdep)"

* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
  ARM: 9294/2: vfp: Fix broken softirq handling with instrumentation enabled
  ARM: 9293/1: vfp: Pass successful return address via register R3
  ARM: 9292/1: vfp: Pass thread_info pointer to vfp_support_entry
  ARM: 9291/1: decompressor: simplify the path to the top vmlinux
parents 1a261a6e 60261442
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg
asflags-y := -DZIMAGE

# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
KBSS_SZ = $(shell echo $$(($$($(NM) vmlinux | \
		sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
		       -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
+0 −13
Original line number Diff line number Diff line
@@ -244,19 +244,6 @@ THUMB( fpreg .req r7 )
	.endm
#endif

	.macro	local_bh_disable, ti, tmp
	ldr	\tmp, [\ti, #TI_PREEMPT]
	add	\tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
	str	\tmp, [\ti, #TI_PREEMPT]
	.endm

	.macro	local_bh_enable_ti, ti, tmp
	get_thread_info \ti
	ldr	\tmp, [\ti, #TI_PREEMPT]
	sub	\tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
	str	\tmp, [\ti, #TI_PREEMPT]
	.endm

#define USERL(l, x...)				\
9999:	x;					\
	.pushsection __ex_table,"a";		\
+3 −14
Original line number Diff line number Diff line
@@ -22,18 +22,7 @@
@  IRQs enabled.
@
ENTRY(do_vfp)
	local_bh_disable r10, r4
 	ldr	r4, .LCvfp
	ldr	r11, [r10, #TI_CPU]	@ CPU number
	add	r10, r10, #TI_VFPSTATE	@ r10 = workspace
	ldr	pc, [r4]		@ call VFP entry point
	mov	r1, r10
	mov	r3, r9
	b	vfp_entry
ENDPROC(do_vfp)

ENTRY(vfp_null_entry)
	local_bh_enable_ti r10, r4
	ret	lr
ENDPROC(vfp_null_entry)

	.align	2
.LCvfp:
	.word	vfp_vector
+17 −13
Original line number Diff line number Diff line
@@ -6,9 +6,9 @@
 *  Written by Deep Blue Solutions Limited.
 *
 * This code is called from the kernel's undefined instruction trap.
 * r9 holds the return address for successful handling.
 * r1 holds the thread_info pointer
 * r3 holds the return address for successful handling.
 * lr holds the return address for unrecognised instructions.
 * r10 points at the start of the private FP workspace in the thread structure
 * sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h)
 */
#include <linux/init.h>
@@ -69,13 +69,15 @@
@ VFP hardware support entry point.
@
@  r0  = instruction opcode (32-bit ARM or two 16-bit Thumb)
@  r1  = thread_info pointer
@  r2  = PC value to resume execution after successful emulation
@  r9  = normal "successful" return address
@  r10 = vfp_state union
@  r11 = CPU number
@  r3  = normal "successful" return address
@  lr  = unrecognised instruction return address
@  IRQs enabled.
ENTRY(vfp_support_entry)
	ldr	r11, [r1, #TI_CPU]	@ CPU number
	add	r10, r1, #TI_VFPSTATE	@ r10 = workspace

	DBGSTR3	"instr %08x pc %08x state %p", r0, r2, r10

	.fpu	vfpv2
@@ -85,9 +87,9 @@ ENTRY(vfp_support_entry)
	bne	look_for_VFP_exceptions	@ VFP is already enabled

	DBGSTR1 "enable %x", r10
	ldr	r3, vfp_current_hw_state_address
	ldr	r9, vfp_current_hw_state_address
	orr	r1, r1, #FPEXC_EN	@ user FPEXC has the enable bit set
	ldr	r4, [r3, r11, lsl #2]	@ vfp_current_hw_state pointer
	ldr	r4, [r9, r11, lsl #2]	@ vfp_current_hw_state pointer
	bic	r5, r1, #FPEXC_EX	@ make sure exceptions are disabled
	cmp	r4, r10			@ this thread owns the hw context?
#ifndef CONFIG_SMP
@@ -146,7 +148,7 @@ vfp_reload_hw:
#endif

	DBGSTR1	"load state %p", r10
	str	r10, [r3, r11, lsl #2]	@ update the vfp_current_hw_state pointer
	str	r10, [r9, r11, lsl #2]	@ update the vfp_current_hw_state pointer
					@ Load the saved state back into the VFP
	VFPFLDMIA r10, r5		@ reload the working registers while
					@ FPEXC is in a safe state
@@ -175,9 +177,12 @@ vfp_hw_state_valid:
					@ else it's one 32-bit instruction, so
					@ always subtract 4 from the following
					@ instruction address.
	local_bh_enable_ti r10, r4
	ret	r9			@ we think we have handled things

	mov	lr, r3			@ we think we have handled things
local_bh_enable_and_ret:
	adr	r0, .
	mov	r1, #SOFTIRQ_DISABLE_OFFSET
	b	__local_bh_enable_ip	@ tail call

look_for_VFP_exceptions:
	@ Check for synchronous or asynchronous exception
@@ -200,13 +205,12 @@ skip:
	@ not recognised by VFP

	DBGSTR	"not VFP"
	local_bh_enable_ti r10, r4
	ret	lr
	b	local_bh_enable_and_ret

process_exception:
	DBGSTR	"bounce"
	mov	r2, sp			@ nothing stacked - regdump is at TOS
	mov	lr, r9			@ setup for a return to the user code.
	mov	lr, r3			@ setup for a return to the user code.

	@ Now call the C code to package up the bounce to the support code
	@   r0 holds the trigger instruction
+22 −5
Original line number Diff line number Diff line
@@ -32,10 +32,9 @@
/*
 * Our undef handlers (in entry.S)
 */
asmlinkage void vfp_support_entry(void);
asmlinkage void vfp_null_entry(void);
asmlinkage void vfp_support_entry(u32, void *, u32, u32);

asmlinkage void (*vfp_vector)(void) = vfp_null_entry;
static bool have_vfp __ro_after_init;

/*
 * Dual-use variable.
@@ -645,6 +644,25 @@ static int vfp_starting_cpu(unsigned int unused)
	return 0;
}

/*
 * Entered with:
 *
 *  r0  = instruction opcode (32-bit ARM or two 16-bit Thumb)
 *  r1  = thread_info pointer
 *  r2  = PC value to resume execution after successful emulation
 *  r3  = normal "successful" return address
 *  lr  = unrecognised instruction return address
 */
asmlinkage void vfp_entry(u32 trigger, struct thread_info *ti, u32 resume_pc,
			  u32 resume_return_address)
{
	if (unlikely(!have_vfp))
		return;

	local_bh_disable();
	vfp_support_entry(trigger, ti, resume_pc, resume_return_address);
}

#ifdef CONFIG_KERNEL_MODE_NEON

static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr)
@@ -798,7 +816,6 @@ static int __init vfp_init(void)
	vfpsid = fmrx(FPSID);
	barrier();
	unregister_undef_hook(&vfp_detect_hook);
	vfp_vector = vfp_null_entry;

	pr_info("VFP support v0.3: ");
	if (VFP_arch) {
@@ -883,7 +900,7 @@ static int __init vfp_init(void)
				  "arm/vfp:starting", vfp_starting_cpu,
				  vfp_dying_cpu);

	vfp_vector = vfp_support_entry;
	have_vfp = true;

	thread_register_notifier(&vfp_notifier_block);
	vfp_pm_init();