diff options
author | Nadav Amit <namit@cs.technion.ac.il> | 2014-06-18 10:19:34 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-07-11 03:14:04 -0400 |
commit | 10e38fc7cabc668738e6a7b7b57cbcddb2234440 (patch) | |
tree | 9b7982992a39d860b71e7a936e3f8d630c7c17a0 /arch/x86/kvm | |
parent | 44583cba9188b29b20ceeefe8ae23ad19e26d9a4 (diff) |
KVM: x86: Emulator flag for instruction that only support 16-bit addresses in real mode
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>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/emulate.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 6a1d60956d63..b61ffe9d86a7 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -164,6 +164,7 @@ | |||
164 | #define NoMod ((u64)1 << 47) /* Mod field is ignored */ | 164 | #define NoMod ((u64)1 << 47) /* Mod field is ignored */ |
165 | #define Intercept ((u64)1 << 48) /* Has valid intercept field */ | 165 | #define Intercept ((u64)1 << 48) /* Has valid intercept field */ |
166 | #define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */ | 166 | #define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */ |
167 | #define NoBigReal ((u64)1 << 50) /* No big real mode */ | ||
167 | 168 | ||
168 | #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) | 169 | #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) |
169 | 170 | ||
@@ -640,7 +641,12 @@ static int __linearize(struct x86_emulate_ctxt *ctxt, | |||
640 | if (!fetch && (desc.type & 8) && !(desc.type & 2)) | 641 | if (!fetch && (desc.type & 8) && !(desc.type & 2)) |
641 | goto bad; | 642 | goto bad; |
642 | lim = desc_limit_scaled(&desc); | 643 | lim = desc_limit_scaled(&desc); |
643 | if ((desc.type & 8) || !(desc.type & 4)) { | 644 | if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch && |
645 | (ctxt->d & NoBigReal)) { | ||
646 | /* la is between zero and 0xffff */ | ||
647 | if (la > 0xffff || (u32)(la + size - 1) > 0xffff) | ||
648 | goto bad; | ||
649 | } else if ((desc.type & 8) || !(desc.type & 4)) { | ||
644 | /* expand-up segment */ | 650 | /* expand-up segment */ |
645 | if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim) | 651 | if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim) |
646 | goto bad; | 652 | goto bad; |