This patch adds a callback into kvm_x86_ops so that svm and
vmx code can do intercept checks on emulated instructions.

Signed-off-by: Joerg Roedel <joerg.roe...@amd.com>
---
 arch/x86/include/asm/kvm_host.h |   21 +++++++++++++++++++++
 arch/x86/kvm/svm.c              |    9 +++++++++
 arch/x86/kvm/x86.c              |   20 +++++++++++++++++++-
 3 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 35f81b1..7544964 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -504,6 +504,22 @@ struct kvm_vcpu_stat {
        u32 nmi_injections;
 };
 
+/*
+ * This struct is used to carry enough information from the instruction
+ * decoder to main KVM so that a decision can be made whether the
+ * instruction needs to be intercepted or not.
+ */
+struct x86_instruction_info {
+       u8  intercept;          /* which intercept                      */
+       u8  rep_prefix;         /* rep prefix?                          */
+       u8  modrm;              /* index of register used               */
+       u64 src_val;            /* value of source operand              */
+       u8  src_bytes;          /* size of source operand               */
+       u8  dst_bytes;          /* size of destination operand          */
+       u8  ad_bytes;           /* size of src/dst address              */
+       u64 next_rip;           /* rip following the instruction        */
+};
+
 struct kvm_x86_ops {
        int (*cpu_has_kvm_support)(void);          /* __init */
        int (*disabled_by_bios)(void);             /* __init */
@@ -591,6 +607,11 @@ struct kvm_x86_ops {
        void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
        void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
+
+       int (*check_intercept)(struct kvm_vcpu *vcpu,
+                              struct x86_instruction_info *info,
+                              enum x86_intercept_stage stage);
+
        const struct trace_print_flags *exit_reasons_str;
 };
 
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 2a19322..b36df64 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3871,6 +3871,13 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
        update_cr0_intercept(svm);
 }
 
+static int svm_check_intercept(struct kvm_vcpu *vcpu,
+                              struct x86_instruction_info *info,
+                              enum x86_intercept_stage stage)
+{
+       return X86EMUL_CONTINUE;
+}
+
 static struct kvm_x86_ops svm_x86_ops = {
        .cpu_has_kvm_support = has_svm,
        .disabled_by_bios = is_disabled,
@@ -3956,6 +3963,8 @@ static struct kvm_x86_ops svm_x86_ops = {
        .adjust_tsc_offset = svm_adjust_tsc_offset,
 
        .set_tdp_cr3 = set_tdp_cr3,
+
+       .check_intercept = svm_check_intercept,
 };
 
 static int __init svm_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 90a41aa..bf72ec6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4245,7 +4245,25 @@ static int emulator_intercept(struct x86_emulate_ctxt 
*ctxt,
                              enum x86_intercept intercept,
                              enum x86_intercept_stage stage)
 {
-       return X86EMUL_CONTINUE;
+       struct x86_instruction_info info = {
+               .intercept  = intercept,
+               .rep_prefix = ctxt->decode.rep_prefix,
+               .modrm      = ctxt->decode.modrm,
+               .src_val    = ctxt->decode.src.val64,
+               .src_bytes  = ctxt->decode.src.bytes,
+               .dst_bytes  = ctxt->decode.dst.bytes,
+               .ad_bytes   = ctxt->decode.ad_bytes,
+               .next_rip   = ctxt->eip,
+       };
+
+       /*
+        * The callback only needs to be implemented if the architecture
+        * supports emulated guest-mode. This BUG_ON reminds the
+        * programmer that this callback needs to be implemented.
+        */
+       BUG_ON(kvm_x86_ops->check_intercept == NULL);
+
+       return kvm_x86_ops->check_intercept(ctxt->vcpu, &info, stage);
 }
 
 static struct x86_emulate_ops emulate_ops = {
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to