On 03/10/19 23:23, Rick Edgecombe wrote: > + if (!vcpu->arch.gva_available) > + return 0; Please return RET_PF_* constants, RET_PF_EMULATE here. > + if (error_code & PFERR_WRITE_MASK) > + fault_error_code |= X86_PF_WRITE; > + > + fault.vector = PF_VECTOR; > + fault.error_code_valid = true; > + fault.error_code = fault_error_code; > + fault.nested_page_fault = false; > + fault.address = vcpu->arch.gva_val; > + fault.async_page_fault = true; Not an async page fault. > + kvm_inject_page_fault(vcpu, &fault); > + > + return 1; Here you would return RET_PF_RETRY - you've injected the page fault and all that's left to do is reenter execution of the vCPU. [...] > + if (unlikely(vcpu->arch.xo_fault)) { > + /* > + * If not enough information to inject the fault, > + * emulate to figure it out and emulate the PF. > + */ > + if (!try_inject_exec_only_pf(vcpu, error_code)) > + return RET_PF_EMULATE; > + > + return 1; > + } Returning 1 is wrong, it's also RET_PF_EMULATE. If you change try_inject_exec_only_pf return values to RET_PF_*, you can simply return the value of try_inject_exec_only_pf(vcpu, error_code). That said, I wonder if it's better to just handle this in handle_ept_violation. Basically, if bits 5:3 of the exit qualification are 100 you can bypass the whole mmu.c page fault handling and just inject an exec-only page fault. Thanks, Paolo