diff -r d8fd425b60d3 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c	Tue May 01 14:18:46 2012 +0100
+++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu May 24 11:18:47 2012 +0100
@@ -89,6 +89,8 @@ void __dummy__(void)
            arch.guest_context.trap_ctxt[TRAP_gp_fault].address);
     OFFSET(VCPU_gp_fault_sel, struct vcpu,
            arch.guest_context.trap_ctxt[TRAP_gp_fault].cs);
+    OFFSET(VCPU_gp_fault_flags, struct vcpu,
+           arch.guest_context.trap_ctxt[TRAP_gp_fault].flags);
     OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp);
     OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss);
     OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
diff -r d8fd425b60d3 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S	Tue May 01 14:18:46 2012 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S	Thu May 24 11:18:47 2012 +0100
@@ -227,6 +227,7 @@ 1:      call  compat_create_bounce_frame
 ENTRY(compat_post_handle_exception)
         testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
         jz    compat_test_all_events
+.Lcompat_bounce_exception:
         call  compat_create_bounce_frame
         movb  $0,TRAPBOUNCE_flags(%rdx)
         jmp   compat_test_all_events
@@ -243,14 +244,15 @@ ENTRY(compat_syscall)
 1:      movq  %rax,TRAPBOUNCE_eip(%rdx)
         movw  %si,TRAPBOUNCE_cs(%rdx)
         movb  %cl,TRAPBOUNCE_flags(%rdx)
-        call  compat_create_bounce_frame
-        jmp   compat_test_all_events
+        jmp   .Lcompat_bounce_exception
 2:      movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
         subl  $2,UREGS_rip(%rsp)
         movq  VCPU_gp_fault_addr(%rbx),%rax
         movzwl VCPU_gp_fault_sel(%rbx),%esi
-        movb  $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
         movl  $0,TRAPBOUNCE_error_code(%rdx)
+        testb $4,VCPU_gp_fault_flags(%rbx)
+        setnz %cl
+        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
         jmp   1b
 
 ENTRY(compat_sysenter)
diff -r d8fd425b60d3 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Tue May 01 14:18:46 2012 +0100
+++ b/xen/arch/x86/x86_64/entry.S	Thu May 24 11:18:47 2012 +0100
@@ -51,6 +51,13 @@ restore_all_guest:
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
 
+        /* Don't use SYSRET path if the return address is not canonical. */
+        movq  8(%rsp),%rcx
+        sarq  $47,%rcx
+        incl  %ecx
+        cmpl  $1,%ecx
+        ja    .Lforce_iret
+
         addq  $8,%rsp
         popq  %rcx                    # RIP
         popq  %r11                    # CS
@@ -61,6 +68,10 @@ restore_all_guest:
         sysretq
 1:      sysretl
 
+.Lforce_iret:
+        /* Mimic SYSRET behavior. */
+        movq  8(%rsp),%rcx            # RIP
+        movq  24(%rsp),%r11           # RFLAGS
         ALIGN
 /* No special register assumptions. */
 iret_exit_to_guest:
@@ -298,12 +309,14 @@ 1:      movq  VCPU_domain(%rbx),%rdi
         movb  %cl,TRAPBOUNCE_flags(%rdx)
         testb $1,DOMAIN_is_32bit_pv(%rdi)
         jnz   compat_sysenter
-        call  create_bounce_frame
-        jmp   test_all_events
+        jmp   .Lbounce_exception
 2:      movl  %eax,TRAPBOUNCE_error_code(%rdx)
         movq  VCPU_gp_fault_addr(%rbx),%rax
-        movb  $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
         movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+        subq  $2,UREGS_rip(%rsp)
+        testb $4,VCPU_gp_fault_flags(%rbx)
+        setnz %cl
+        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
         jmp   1b
 
 ENTRY(int80_direct_trap)
@@ -490,6 +503,7 @@ 1:      movq  %rsp,%rdi
         jnz   compat_post_handle_exception
         testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
         jz    test_all_events
+.Lbounce_exception:
         call  create_bounce_frame
         movb  $0,TRAPBOUNCE_flags(%rdx)
         jmp   test_all_events
