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

Commit 9c7cc234 authored by K.Prasad's avatar K.Prasad Committed by Benjamin Herrenschmidt
Browse files

powerpc: Disable interrupts for data breakpoint exceptions



Data address breakpoint exceptions are currently handled along with page-faults
which require interrupts to remain in enabled state. Since exception handling
for data breakpoints aren't pre-empt safe, we handle them separately.

Signed-off-by: default avatarK.Prasad <prasad@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 578b7cd1
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -735,8 +735,11 @@ _STATIC(do_hash_page)
	std	r3,_DAR(r1)
	std	r3,_DAR(r1)
	std	r4,_DSISR(r1)
	std	r4,_DSISR(r1)


	andis.	r0,r4,0xa450		/* weird error? */
	andis.	r0,r4,0xa410		/* weird error? */
	bne-	handle_page_fault	/* if not, try to insert a HPTE */
	bne-	handle_page_fault	/* if not, try to insert a HPTE */
	andis.  r0,r4,DSISR_DABRMATCH@h
	bne-    handle_dabr_fault

BEGIN_FTR_SECTION
BEGIN_FTR_SECTION
	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
	bne-	do_ste_alloc		/* If so handle it */
	bne-	do_ste_alloc		/* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
	bl	.raw_local_irq_restore
	bl	.raw_local_irq_restore
	b	11f
	b	11f


/* We have a data breakpoint exception - handle it */
handle_dabr_fault:
	ld      r4,_DAR(r1)
	ld      r5,_DSISR(r1)
	addi    r3,r1,STACK_FRAME_OVERHEAD
	bl      .do_dabr
	b       .ret_from_except_lite

/* Here we have a page fault that hash_page can't handle. */
/* Here we have a page fault that hash_page can't handle. */
handle_page_fault:
handle_page_fault:
	ENABLE_INTS
	ENABLE_INTS
+3 −2
Original line number Original line Diff line number Diff line
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
	if (!user_mode(regs) && (address >= TASK_SIZE))
	if (!user_mode(regs) && (address >= TASK_SIZE))
		return SIGSEGV;
		return SIGSEGV;


#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
			     defined(CONFIG_PPC_BOOK3S_64))
  	if (error_code & DSISR_DABRMATCH) {
  	if (error_code & DSISR_DABRMATCH) {
		/* DABR match */
		/* DABR match */
		do_dabr(regs, address, error_code);
		do_dabr(regs, address, error_code);
		return 0;
		return 0;
	}
	}
#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
#endif


	if (in_atomic() || mm == NULL) {
	if (in_atomic() || mm == NULL) {
		if (!user_mode(regs))
		if (!user_mode(regs))