Adds segment limit checking helper functions. Also added a cs_base() helper while at it. Signed-off-by: Mohammed Gamal <m.gamal005@xxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html