KVM: x86: Emulator flag for instruction that only support 16-bit addresses in real...
authorNadav Amit <namit@cs.technion.ac.il>
Wed, 18 Jun 2014 14:19:34 +0000 (17:19 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 11 Jul 2014 07:14:04 +0000 (09:14 +0200)
Certain instructions, such as monitor and xsave do not support big real mode
and cause a #GP exception if any of the accessed bytes effective address are
not within [0, 0xffff].  This patch introduces a flag to mark these
instructions, including the necassary checks.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/emulate.c

index 6a1d609..b61ffe9 100644 (file)
 #define NoMod      ((u64)1 << 47)  /* Mod field is ignored */
 #define Intercept   ((u64)1 << 48)  /* Has valid intercept field */
 #define CheckPerm   ((u64)1 << 49)  /* Has valid check_perm field */
+#define NoBigReal   ((u64)1 << 50)  /* No big real mode */
 
 #define DstXacc     (DstAccLo | SrcAccHi | SrcWrite)
 
@@ -640,7 +641,12 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
                if (!fetch && (desc.type & 8) && !(desc.type & 2))
                        goto bad;
                lim = desc_limit_scaled(&desc);
-               if ((desc.type & 8) || !(desc.type & 4)) {
+               if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch &&
+                   (ctxt->d & NoBigReal)) {
+                       /* la is between zero and 0xffff */
+                       if (la > 0xffff || (u32)(la + size - 1) > 0xffff)
+                               goto bad;
+               } else if ((desc.type & 8) || !(desc.type & 4)) {
                        /* expand-up segment */
                        if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim)
                                goto bad;