Adds segment limit checking helper functions. Also added a cs_base() helper 
while at it.

Signed-off-by: Mohammed Gamal <m.gamal...@gmail.com>
---
 arch/x86/kvm/emulate.c |   33 ++++++++++++++++++++++++++++++++-
 1 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 255473f..07ca28e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -633,6 +633,15 @@ static unsigned long seg_base(struct x86_emulate_ctxt 
*ctxt,
        return ops->get_cached_segment_base(seg, ctxt->vcpu);
 }
 
+static u64 seg_limit(struct x86_emulate_ctxt *ctxt,
+                    struct x86_emulate_ops *ops, int seg)
+{
+       if (ctxt->mode == X86EMUL_MODE_PROT64)
+               return -1ULL;
+
+       return ops->get_cached_segment_limit(seg, ctxt->vcpu);
+}
+
 static unsigned long seg_override_base(struct x86_emulate_ctxt *ctxt,
                                       struct x86_emulate_ops *ops,
                                       struct decode_cache *c)
@@ -643,6 +652,12 @@ static unsigned long seg_override_base(struct 
x86_emulate_ctxt *ctxt,
        return seg_base(ctxt, ops, c->seg_override);
 }
 
+static unsigned long cs_base(struct x86_emulate_ctxt *ctxt,
+                            struct x86_emulate_ops *ops)
+{
+       return seg_base(ctxt, ops, VCPU_SREG_CS);
+}
+
 static unsigned long es_base(struct x86_emulate_ctxt *ctxt,
                             struct x86_emulate_ops *ops)
 {
@@ -686,6 +701,22 @@ static void emulate_ts(struct x86_emulate_ctxt *ctxt, int 
err)
        emulate_exception(ctxt, TS_VECTOR, err, true);
 }
 
+static int seg_limit_check(struct x86_emulate_ctxt *ctxt,
+                          struct x86_emulate_ops *ops, int seg,
+                          unsigned long addr, unsigned size,
+                          int vec, u32 err)
+{
+       unsigned long base = seg_base(ctxt, ops, seg);
+       u64 limit = seg_limit(ctxt, ops, seg);
+
+       if (addr - base + size - 1 > limit) {
+               emulate_exception(ctxt, vec, err, true);
+               return X86EMUL_PROPAGATE_FAULT;
+       }
+
+       return X86EMUL_CONTINUE;
+}
+
 static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
                              struct x86_emulate_ops *ops,
                              unsigned long eip, u8 *dest)
@@ -976,7 +1007,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct 
x86_emulate_ops *ops)
 
        c->eip = ctxt->eip;
        c->fetch.start = c->fetch.end = c->eip;
-       ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
+       ctxt->cs_base = cs_base(ctxt, ops);
 
        switch (mode) {
        case X86EMUL_MODE_REAL:
-- 
1.7.0.4

--
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