@@ -1436,6 +1436,10 @@ extern u64 kvm_mce_cap_supported;
* retry native execution under certain conditions,
* Can only be set in conjunction with EMULTYPE_PF.
*
+ * EMULTYPE_GPA_AVAILABLE_PF - Set when the emulator can avoid a page walk
+ * to get the GPA.
+ * Can only be set in conjunction with EMULTYPE_PF.
+ *
* EMULTYPE_TRAP_UD_FORCED - Set when emulating an intercepted #UD that was
* triggered by KVM's magic "force emulation" prefix,
* which is opt in via module param (off by default).
@@ -1458,6 +1462,7 @@ extern u64 kvm_mce_cap_supported;
#define EMULTYPE_TRAP_UD_FORCED (1 << 4)
#define EMULTYPE_VMWARE_GP (1 << 5)
#define EMULTYPE_PF (1 << 6)
+#define EMULTYPE_GPA_AVAILABLE_PF (1 << 7)
int kvm_emulate_instruction(struct kvm_vcpu *vcpu, int emulation_type);
int kvm_emulate_instruction_from_buffer(struct kvm_vcpu *vcpu,
@@ -5566,6 +5566,14 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code,
*/
if (!mmio_info_in_cache(vcpu, cr2_or_gpa, direct) && !is_guest_mode(vcpu))
emulation_type |= EMULTYPE_ALLOW_RETRY_PF;
+
+ /*
+ * With shadow page tables, fault_address contains a GVA or nGPA.
+ * On a fetch fault, fault_address contains the instruction pointer.
+ */
+ if (direct && likely(!(error_code & PFERR_FETCH_MASK)) &&
+ (error_code & PFERR_GUEST_FINAL_MASK))
+ emulation_type |= EMULTYPE_GPA_AVAILABLE_PF;
emulate:
/*
* On AMD platforms, under certain conditions insn_len may be zero on #NPF.
@@ -6987,7 +6987,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
ctxt->exception.address = cr2_or_gpa;
/* With shadow page tables, cr2 contains a GVA or nGPA. */
- if (vcpu->arch.mmu->direct_map) {
+ if (emulation_type & EMULTYPE_GPA_AVAILABLE_PF) {
ctxt->gpa_available = true;
ctxt->gpa_val = cr2_or_gpa;
}