[RFC PATCH v3 2/3] x86 emulator: Add segment limit checking helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux