diff options
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; |