From: Mircea Cîrjaliu <redacted>
This change is needed because the introspection tool can write-protect
guest page tables or exec-protect heap/stack pages.
Signed-off-by: Mircea Cîrjaliu <redacted>
Co-developed-by: Adalbert Lazăr <redacted>
Signed-off-by: Adalbert Lazăr <redacted>
---
arch/x86/include/asm/kvm_host.h | 5 +++++
arch/x86/kvm/mmu/mmu.c | 7 +++++++
arch/x86/kvm/x86.c | 2 +-
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 692e55a5c312..dc3c83edc4bc 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1664,6 +1664,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).
@@ -1686,6 +1690,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,
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index b5685e342945..c90683284098 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -5297,6 +5297,13 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code,
if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root_hpa)))
return RET_PF_RETRY;
+ /*
+ * 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;
r = RET_PF_INVALID;
if (unlikely(error_code & PFERR_RSVD_MASK)) {diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c52ac5e9a020..ab97e0175c04 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7933,7 +7933,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;
}_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization