Skip to content

Commit

Permalink
powerpc: bad_page_fault, do_break get registers from regs
Browse files Browse the repository at this point in the history
This also moves the 32s DABR match to C.

Similar to the previous patch this makes interrupt handler function
types more regular so they can be wrapped with the next patch.

bad_page_fault and do_break are not performance critical.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
  • Loading branch information
npiggin authored and intel-lab-lkp committed Nov 5, 2020
1 parent 8244894 commit 4232a61
Show file tree
Hide file tree
Showing 12 changed files with 25 additions and 36 deletions.
2 changes: 1 addition & 1 deletion arch/powerpc/include/asm/bug.h
Expand Up @@ -113,7 +113,7 @@
struct pt_regs;
extern long do_page_fault(struct pt_regs *);
extern long hash__do_page_fault(struct pt_regs *);
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
extern void bad_page_fault(struct pt_regs *, int);
extern void _exception(int, struct pt_regs *, int, unsigned long);
extern void _exception_pkey(struct pt_regs *, unsigned long, int);
extern void die(const char *, struct pt_regs *, long);
Expand Down
3 changes: 1 addition & 2 deletions arch/powerpc/include/asm/debug.h
Expand Up @@ -52,8 +52,7 @@ extern void do_send_trap(struct pt_regs *regs, unsigned long address,
unsigned long error_code, int brkpt);
#else

extern void do_break(struct pt_regs *regs, unsigned long address,
unsigned long error_code);
void do_break(struct pt_regs *regs);
#endif

#endif /* _ASM_POWERPC_DEBUG_H */
14 changes: 4 additions & 10 deletions arch/powerpc/kernel/entry_32.S
Expand Up @@ -657,30 +657,24 @@ ppc_swapcontext:
.globl handle_page_fault
handle_page_fault:
addi r3,r1,STACK_FRAME_OVERHEAD
#ifdef CONFIG_PPC_BOOK3S_32
andis. r0,r5,DSISR_DABRMATCH@h
bne- handle_dabr_fault
#endif
bl do_page_fault
cmpwi r3,0
beq+ ret_from_except
SAVE_NVGPRS(r1)
lwz r0,_TRAP(r1)
clrrwi r0,r0,1
stw r0,_TRAP(r1)
mr r5,r3
mr r4,r3 /* err arg for bad_page_fault */
addi r3,r1,STACK_FRAME_OVERHEAD
lwz r4,_DAR(r1)
#ifdef CONFIG_PPC_BOOK3S_32
blt handle_dabr_fault
#endif
bl bad_page_fault
b ret_from_except_full

#ifdef CONFIG_PPC_BOOK3S_32
/* We have a data breakpoint exception - handle it */
handle_dabr_fault:
SAVE_NVGPRS(r1)
lwz r0,_TRAP(r1)
clrrwi r0,r0,1
stw r0,_TRAP(r1)
bl do_break
b ret_from_except_full
#endif
Expand Down
3 changes: 1 addition & 2 deletions arch/powerpc/kernel/exceptions-64e.S
Expand Up @@ -1018,9 +1018,8 @@ storage_fault_common:
bne- 1f
b ret_from_except_lite
1: bl save_nvgprs
mr r5,r3
mr r4,r3
addi r3,r1,STACK_FRAME_OVERHEAD
ld r4,_DAR(r1)
bl bad_page_fault
b ret_from_except

Expand Down
3 changes: 1 addition & 2 deletions arch/powerpc/kernel/exceptions-64s.S
Expand Up @@ -2135,8 +2135,7 @@ EXC_COMMON_BEGIN(h_data_storage_common)
GEN_COMMON h_data_storage
addi r3,r1,STACK_FRAME_OVERHEAD
BEGIN_MMU_FTR_SECTION
ld r4,_DAR(r1)
li r5,SIGSEGV
li r4,SIGSEGV
bl bad_page_fault
MMU_FTR_SECTION_ELSE
bl unknown_exception
Expand Down
5 changes: 2 additions & 3 deletions arch/powerpc/kernel/head_8xx.S
Expand Up @@ -408,10 +408,9 @@ do_databreakpoint:
addi r3,r1,STACK_FRAME_OVERHEAD
mfspr r4,SPRN_BAR
stw r4,_DAR(r11)
#ifdef CONFIG_VMAP_STACK
lwz r5,_DSISR(r11)
#else
#ifndef CONFIG_VMAP_STACK
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
#endif
EXC_XFER_STD(0x1c00, do_break)

Expand Down
7 changes: 3 additions & 4 deletions arch/powerpc/kernel/process.c
Expand Up @@ -660,11 +660,10 @@ static void do_break_handler(struct pt_regs *regs)
}
}

void do_break (struct pt_regs *regs, unsigned long address,
unsigned long error_code)
void do_break(struct pt_regs *regs)
{
current->thread.trap_nr = TRAP_HWBKPT;
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, regs->dsisr,
11, SIGSEGV) == NOTIFY_STOP)
return;

Expand All @@ -682,7 +681,7 @@ void do_break (struct pt_regs *regs, unsigned long address,
do_break_handler(regs);

/* Deliver the signal to userspace */
force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address);
force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)regs->dar);
}
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */

Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/traps.c
Expand Up @@ -1641,7 +1641,7 @@ void alignment_exception(struct pt_regs *regs)
if (user_mode(regs))
_exception(sig, regs, code, regs->dar);
else
bad_page_fault(regs, regs->dar, sig);
bad_page_fault(regs, sig);

bail:
exception_exit(prev_state);
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/mm/book3s64/hash_utils.c
Expand Up @@ -1537,7 +1537,7 @@ long do_hash_fault(struct pt_regs *regs)
* the access, or panic if there isn't a handler.
*/
if (unlikely(in_nmi())) {
bad_page_fault(regs, ea, SIGSEGV);
bad_page_fault(regs, SIGSEGV);
return 0;
}

Expand Down Expand Up @@ -1576,7 +1576,7 @@ long do_hash_fault(struct pt_regs *regs)
else
_exception(SIGBUS, regs, BUS_ADRERR, ea);
} else {
bad_page_fault(regs, ea, SIGBUS);
bad_page_fault(regs, SIGBUS);
}
err = 0;

Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/mm/book3s64/slb.c
Expand Up @@ -898,7 +898,7 @@ void do_bad_slb_fault(struct pt_regs *regs)
if (user_mode(regs))
_exception(SIGSEGV, regs, SEGV_BNDERR, regs->dar);
else
bad_page_fault(regs, regs->dar, SIGSEGV);
bad_page_fault(regs, SIGSEGV);
} else if (err == -EINVAL) {
unrecoverable_exception(regs);
} else {
Expand Down
14 changes: 7 additions & 7 deletions arch/powerpc/mm/fault.c
Expand Up @@ -375,7 +375,7 @@ static void sanity_check_fault(bool is_write, bool is_user,
#elif defined(CONFIG_PPC_BOOK3E_64)
#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_64S)
#else
#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S)
#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)
#endif
#endif

Expand Down Expand Up @@ -408,7 +408,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
return 0;

if (unlikely(page_fault_is_bad(error_code))) {
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && (error_code & DSISR_DABRMATCH))
if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (error_code & DSISR_DABRMATCH))
return -1;

if (is_user) {
Expand Down Expand Up @@ -562,14 +562,14 @@ long do_page_fault(struct pt_regs *regs)
/* 32 and 64e handle errors in their asm code */
if (unlikely(err)) {
if (err > 0) {
bad_page_fault(regs, address, err);
bad_page_fault(regs, err);
err = 0;
} else {
/*
* do_break() may change NV GPRS while handling the
* breakpoint. Return -ve to caller to do that.
*/
do_break(regs, address, error_code);
do_break(regs);
}
}
#endif
Expand All @@ -591,14 +591,14 @@ long hash__do_page_fault(struct pt_regs *regs)
err = __do_page_fault(regs, address, error_code);
if (unlikely(err)) {
if (err > 0) {
bad_page_fault(regs, address, err);
bad_page_fault(regs, err);
err = 0;
} else {
/*
* do_break() may change NV GPRS while handling the
* breakpoint. Return -ve to caller to do that.
*/
do_break(regs, address, error_code);
do_break(regs);
}
}

Expand All @@ -612,7 +612,7 @@ NOKPROBE_SYMBOL(hash__do_page_fault);
* It is called from the DSI and ISI handlers in head.S and from some
* of the procedures in traps.c.
*/
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
void bad_page_fault(struct pt_regs *regs, int sig)
{
const struct exception_table_entry *entry;
int is_write = page_fault_is_write(regs->dsisr);
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/8xx/machine_check.c
Expand Up @@ -26,7 +26,7 @@ int machine_check_8xx(struct pt_regs *regs)
* to deal with that than having a wart in the mcheck handler.
* -- BenH
*/
bad_page_fault(regs, regs->dar, SIGBUS);
bad_page_fault(regs, SIGBUS);
return 1;
#else
return 0;
Expand Down

0 comments on commit 4232a61

Please sign in to comment.