diff options
Diffstat (limited to 'arch/x86/mm/fault.c')
-rw-r--r-- | arch/x86/mm/fault.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 56c17830e347..8e52e68c0435 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -35,6 +35,7 @@ #include <asm/smp.h> #include <asm/tlbflush.h> #include <asm/proto.h> +#include <asm/kmemcheck.h> #include <asm-generic/sections.h> #include <asm/traps.h> @@ -604,6 +605,13 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) si_code = SEGV_MAPERR; + /* + * Detect and handle instructions that would cause a page fault for + * both a tracked kernel page and a userspace page. + */ + if(kmemcheck_active(regs)) + kmemcheck_hide(regs); + if (notify_page_fault(regs)) return; if (unlikely(kmmio_fault(regs, address))) @@ -627,9 +635,13 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) #else if (unlikely(address >= TASK_SIZE64)) { #endif - if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) && - vmalloc_fault(address) >= 0) - return; + if (!(error_code & (PF_RSVD | PF_USER | PF_PROT))) { + if (vmalloc_fault(address) >= 0) + return; + + if (kmemcheck_fault(regs, address, error_code)) + return; + } /* Can handle a stale RO->RW TLB */ if (spurious_fault(address, error_code)) |