diff mbox

[RFC,11/19] kvm: x86: Hook in kvmi_breakpoint_event()

Message ID 20170616134348.17725-12-alazar@bitdefender.com (mailing list archive)
State New, archived
Headers show

Commit Message

Adalbert Lazăr June 16, 2017, 1:43 p.m. UTC
From: Mihai Dontu <mdontu@bitdefender.com>

Inform the guest introspection tool than a breakpoint instruction (INT3)
is being executed. These one-byte intructions are placed in the slack
space of various functions and used as notification for when the OS or
an application has reached a certain state or is trying to perform a
certain operation (like creating a process).

Signed-off-by: Mihai Dontu <mdontu@bitdefender.com>
---
 arch/x86/include/asm/kvm_host.h |  2 ++
 arch/x86/kvm/svm.c              |  3 +++
 arch/x86/kvm/vmx.c              |  3 +++
 arch/x86/kvm/x86.c              | 14 ++++++++++++++
 4 files changed, 22 insertions(+)

Comments

Paolo Bonzini June 21, 2017, 11:48 a.m. UTC | #1
On 16/06/2017 15:43, Adalbert Lazar wrote:
> +int kvm_breakpoint(struct kvm_vcpu *vcpu)
> +{
> +	gpa_t gpa;
> +	struct kvm_segment cs;
> +
> +	kvm_get_segment(vcpu, &cs, VCPU_SREG_CS);
> +	gpa = kvm_mmu_gva_to_gpa_read(vcpu, cs.base + kvm_rip_read(vcpu), NULL);
> +	if (kvmi_breakpoint_event(vcpu, gpa))
> +		return 0;
> +	return 1;
> +}
> +EXPORT_SYMBOL_GPL(kvm_breakpoint);
> +

Please create a separate file with all these functions.
x86.c/vmx.c/svm.c are already too big, let's not make it worse.

Paolo
Mihai Donțu June 21, 2017, 12:37 p.m. UTC | #2
On Wed, 2017-06-21 at 13:48 +0200, Paolo Bonzini wrote:
> On 16/06/2017 15:43, Adalbert Lazar wrote:
> > +int kvm_breakpoint(struct kvm_vcpu *vcpu)
> > +{
> > +	gpa_t gpa;
> > +	struct kvm_segment cs;
> > +
> > +	kvm_get_segment(vcpu, &cs, VCPU_SREG_CS);
> > +	gpa = kvm_mmu_gva_to_gpa_read(vcpu, cs.base +
> > kvm_rip_read(vcpu), NULL);
> > +	if (kvmi_breakpoint_event(vcpu, gpa))
> > +		return 0;
> > +	return 1;
> > +}
> > +EXPORT_SYMBOL_GPL(kvm_breakpoint);
> > +
> 
> Please create a separate file with all these functions.
> x86.c/vmx.c/svm.c are already too big, let's not make it worse.

Noted. Thank you!
diff mbox

Patch

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8d1d80bd2230..7024f8e3962b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1434,4 +1434,6 @@  static inline int kvm_cpu_get_apicid(int mps_cpu)
 }
 
 void kvm_arch_msr_intercept(unsigned int msr, bool enable);
+int kvm_breakpoint(struct kvm_vcpu *vcpu);
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 7f1b00b74199..69d4d5c9e469 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2133,6 +2133,9 @@  static int bp_interception(struct vcpu_svm *svm)
 {
 	struct kvm_run *kvm_run = svm->vcpu.run;
 
+	if (kvm_breakpoint(svm->vcpu, svm->vmcb->control.exit_info_2))
+		return 1;
+
 	kvm_run->exit_reason = KVM_EXIT_DEBUG;
 	kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip;
 	kvm_run->debug.arch.exception = BP_VECTOR;
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f99fcc86f141..405b739cd07b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5682,6 +5682,9 @@  static int handle_exception(struct kvm_vcpu *vcpu)
 		kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
 		/* fall through */
 	case BP_VECTOR:
+		if (kvm_breakpoint(vcpu))
+			return 1;
+
 		/*
 		 * Update instruction length as we may reinject #BP from
 		 * user space while in guest debugging mode. Reading it for
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9a47f640a7b5..3a50710629b5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -54,6 +54,7 @@ 
 #include <linux/kvm_irqfd.h>
 #include <linux/irqbypass.h>
 #include <linux/sched/stat.h>
+#include "../../../../virt/kvm/kvmi.h"
 
 #include <trace/events/kvm.h>
 
@@ -8740,6 +8741,19 @@  void kvm_arch_msr_intercept(unsigned int msr, bool enable)
 }
 EXPORT_SYMBOL_GPL(kvm_arch_msr_intercept);
 
+int kvm_breakpoint(struct kvm_vcpu *vcpu)
+{
+	gpa_t gpa;
+	struct kvm_segment cs;
+
+	kvm_get_segment(vcpu, &cs, VCPU_SREG_CS);
+	gpa = kvm_mmu_gva_to_gpa_read(vcpu, cs.base + kvm_rip_read(vcpu), NULL);
+	if (kvmi_breakpoint_event(vcpu, gpa))
+		return 0;
+	return 1;
+}
+EXPORT_SYMBOL_GPL(kvm_breakpoint);
+
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);