Context |
Check |
Description |
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch powerpc/merge (51774547e7f80f9111d85a65c8e14eb2d9ffcdf3)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch powerpc/next (8a5be36b9303ae167468d4f5e1b3c090b9981396)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch linus/master (eda809aef53426d044b519405d25d9da55319b76)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch powerpc/fixes (d5c243989fb0cb03c74d7340daca3b819f706ee7)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch linux-next (58cf05f597b03a8212d9ecf2c79ee046d3ee8ad9)
|
snowpatch_ozlabs/apply_patch |
fail
|
Failed to apply to any branch
|
@@ -112,6 +112,7 @@
struct pt_regs;
long do_page_fault(struct pt_regs *);
+long hash__do_page_fault(struct pt_regs *);
void bad_page_fault(struct pt_regs *, int);
void __bad_page_fault(struct pt_regs *regs, int sig);
extern void _exception(int, struct pt_regs *, int, unsigned long);
@@ -1289,7 +1289,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
unsigned long flags)
{
bool is_thp;
- enum ctx_state prev_state = exception_enter();
pgd_t *pgdir;
unsigned long vsid;
pte_t *ptep;
@@ -1491,7 +1490,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
DBG_LOW(" -> rc=%d\n", rc);
bail:
- exception_exit(prev_state);
return rc;
}
EXPORT_SYMBOL_GPL(hash_page_mm);
@@ -1515,6 +1513,7 @@ EXPORT_SYMBOL_GPL(hash_page);
DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
{
+ enum ctx_state prev_state = exception_enter();
unsigned long ea = regs->dar;
unsigned long dsisr = regs->dsisr;
unsigned long access = _PAGE_PRESENT | _PAGE_READ;
@@ -1563,9 +1562,11 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
err = 0;
} else if (err) {
- err = do_page_fault(regs);
+ err = hash__do_page_fault(regs);
}
+ exception_exit(prev_state);
+
return err;
}
@@ -589,6 +589,15 @@ DEFINE_INTERRUPT_HANDLER_RET(do_page_fault)
}
NOKPROBE_SYMBOL(do_page_fault);
+#ifdef CONFIG_PPC_BOOK3S_64
+/* Same as do_page_fault but interrupt entry has already run in do_hash_fault */
+long hash__do_page_fault(struct pt_regs *regs)
+{
+ return __do_page_fault(regs);
+}
+NOKPROBE_SYMBOL(hash__do_page_fault);
+#endif
+
/*
* bad_page_fault is called when we have a bad access from the kernel.
* It is called from the DSI and ISI handlers in head.S and from some
This moves the 64s/hash context tracking from hash_page_mm() to __do_hash_fault(), so it's no longer called by OCXL / SPU accelerators, which was certainly the wrong thing to be doing, because those callers are not low level interrupt handlers, so should have entered a kernel context tracking already. Then remain in kernel context for the duration of the fault, rather than enter/exit for the hash fault then enter/exit for the page fault, which is pointless. Even still, calling exception_enter/exit in __do_hash_fault seems questionable because that's touching per-cpu variables, tracing, etc., which might have been interrupted by this hash fault or themselves cause hash faults. But maybe I miss something because hash_page_mm very deliberately calls trace_hash_fault too, for example. So for now go with it, it's no worse than before, in this regard. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- arch/powerpc/include/asm/bug.h | 1 + arch/powerpc/mm/book3s64/hash_utils.c | 7 ++++--- arch/powerpc/mm/fault.c | 9 +++++++++ 3 files changed, 14 insertions(+), 3 deletions(-)