X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=arch%2Fx86%2Fmm%2Ffault.c;h=c5437f2964ee6fd68c9dd23fef687b2004d9ae03;hb=039aeb9deb9291f3b19c375a8bc6fa7f768996cc;hp=dffe8e4d3140efa283c30d75d7eb3552d8ca800c;hpb=7f0a002b5a21302d9f4b29ba83c96cd433ff3769;p=tomoyo%2Ftomoyo-test1.git diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index dffe8e4d3140..c5437f2964ee 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -30,6 +30,7 @@ #include /* store_idt(), ... */ #include /* exception stack */ #include /* VMALLOC_START, ... */ +#include /* kvm_handle_async_pf */ #define CREATE_TRACE_POINTS #include @@ -1359,6 +1360,24 @@ do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, unsigned long address) { prefetchw(¤t->mm->mmap_sem); + /* + * KVM has two types of events that are, logically, interrupts, but + * are unfortunately delivered using the #PF vector. These events are + * "you just accessed valid memory, but the host doesn't have it right + * now, so I'll put you to sleep if you continue" and "that memory + * you tried to access earlier is available now." + * + * We are relying on the interrupted context being sane (valid RSP, + * relevant locks not held, etc.), which is fine as long as the + * interrupted context had IF=1. We are also relying on the KVM + * async pf type field and CR2 being read consistently instead of + * getting values from real and async page faults mixed up. + * + * Fingers crossed. + */ + if (kvm_handle_async_pf(regs, (u32)address)) + return; + trace_page_fault_entries(regs, hw_error_code, address); if (unlikely(kmmio_fault(regs, address)))