From: Chuck Ebbert <76306.1226@compuserve.com> We need to check for vm86 mode first before looking at selector privilege bits. Segment limit is always base + 64k and only the low 16 bits of EIP are significant in vm86 mode. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Cc: Andi Kleen Cc: Zachary Amsden Cc: Rohit Seth Signed-off-by: Andrew Morton --- arch/i386/mm/fault.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff -puN arch/i386/mm/fault.c~i386-fix-get_segment_eip-with-vm86 arch/i386/mm/fault.c --- devel/arch/i386/mm/fault.c~i386-fix-get_segment_eip-with-vm86 2006-05-29 20:06:19.000000000 -0700 +++ devel-akpm/arch/i386/mm/fault.c 2006-05-29 20:06:19.000000000 -0700 @@ -77,12 +77,15 @@ static inline unsigned long get_segment_ unsigned seg = regs->xcs & 0xffff; u32 seg_ar, seg_limit, base, *desc; + /* Unlikely, but must come before segment checks. */ + if (unlikely(regs->eflags & VM_MASK)) { + base = seg << 4; + *eip_limit = base + 0xffff; + return base + (eip & 0xffff); + } + /* The standard kernel/user address space limit. */ *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; - - /* Unlikely, but must come before segment checks. */ - if (unlikely((regs->eflags & VM_MASK) != 0)) - return eip + (seg << 4); /* By far the most common cases. */ if (likely(seg == __USER_CS || seg == __KERNEL_CS)) _