# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID 19f5ffa02154db55a4fa5a67201e763d8626868b
# Parent ec4ef8c5f04d9fef83acf5281a432a7821906520
Fix x86/32 do_iret implementation, fixes VM86 mode.
Do not clobber a freshly restored esp when performing an iret.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
Signed-off-by: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>
diff -r ec4ef8c5f04d -r 19f5ffa02154 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Jan 13 10:38:33 2006
+++ b/xen/arch/x86/x86_32/traps.c Fri Jan 13 11:04:04 2006
@@ -157,14 +157,6 @@
__asm__ __volatile__ ( "hlt" );
}
-static inline void pop_from_guest_stack(
- void *dst, struct cpu_user_regs *regs, unsigned int bytes)
-{
- if ( unlikely(__copy_from_user(dst, (void __user *)regs->esp, bytes)) )
- domain_crash_synchronous();
- regs->esp += bytes;
-}
-
asmlinkage unsigned long do_iret(void)
{
struct cpu_user_regs *regs = guest_cpu_user_regs();
@@ -175,22 +167,29 @@
domain_crash_synchronous();
/* Pop and restore EAX (clobbered by hypercall). */
- pop_from_guest_stack(®s->eax, regs, 4);
+ if ( unlikely(__copy_from_user(®s->eax, (void __user *)regs->esp, 4)) )
+ domain_crash_synchronous();
+ regs->esp += 4;
/* Pop and restore CS and EIP. */
- pop_from_guest_stack(®s->eip, regs, 8);
+ if ( unlikely(__copy_from_user(®s->eip, (void __user *)regs->esp, 8)) )
+ domain_crash_synchronous();
+ regs->esp += 8;
/*
* Pop, fix up and restore EFLAGS. We fix up in a local staging area
* to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
*/
- pop_from_guest_stack(&eflags, regs, 4);
+ if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
+ domain_crash_synchronous();
+ regs->esp += 4;
regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
if ( VM86_MODE(regs) )
{
/* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
- pop_from_guest_stack(®s->esp, regs, 24);
+ if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 24) )
+ domain_crash_synchronous();
}
else if ( unlikely(RING_0(regs)) )
{
@@ -199,7 +198,8 @@
else if ( !RING_1(regs) )
{
/* Return to ring 2/3: pop and restore ESP and SS. */
- pop_from_guest_stack(®s->esp, regs, 8);
+ if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 8) )
+ domain_crash_synchronous();
}
/* No longer in NMI context. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|