|
@@ -14,6 +14,7 @@
|
|
|
|
|
|
#include <asm/traps.h> /* dotraplinkage, ... */
|
|
#include <asm/traps.h> /* dotraplinkage, ... */
|
|
#include <asm/pgalloc.h> /* pgd_*(), ... */
|
|
#include <asm/pgalloc.h> /* pgd_*(), ... */
|
|
|
|
+#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
|
|
|
|
|
|
/*
|
|
/*
|
|
* Page fault error code bits:
|
|
* Page fault error code bits:
|
|
@@ -956,6 +957,13 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
|
/* Get the faulting address: */
|
|
/* Get the faulting address: */
|
|
address = read_cr2();
|
|
address = read_cr2();
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * 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 (unlikely(kmmio_fault(regs, address)))
|
|
if (unlikely(kmmio_fault(regs, address)))
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -973,9 +981,13 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
|
* protection error (error_code & 9) == 0.
|
|
* protection error (error_code & 9) == 0.
|
|
*/
|
|
*/
|
|
if (unlikely(fault_in_kernel_space(address))) {
|
|
if (unlikely(fault_in_kernel_space(address))) {
|
|
- 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: */
|
|
/* Can handle a stale RO->RW TLB: */
|
|
if (spurious_fault(error_code, address))
|
|
if (spurious_fault(error_code, address))
|