From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keir Fraser Subject: Re: [PATCH] x86-64: fix #GP generation in assembly code Date: Tue, 17 Apr 2012 14:08:36 +0100 Message-ID: References: <4F8D8216020000780007E79A@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <4F8D8216020000780007E79A@nat28.tlf.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jan Beulich , xen-devel List-Id: xen-devel@lists.xenproject.org On 17/04/2012 13:45, "Jan Beulich" wrote: > When guest use of sysenter (64-bit PV guest) or syscall (32-bit PV > guest) gets converted into a GP fault (due to no callback having got > registered), we must > - honor the GP fault handler's request the keep enabled or mask event > delivery > - not allow TBF_EXCEPTION to remain set past the generation of the > (guest) exception in the vCPU's trap_bounce.flags, as that would > otherwise allow for the next exception occurring in guest mode, > should it happen to get handled in Xen itself, to nevertheless get > bounced to the guest kernel. > > Also, just like compat mode syscall handling already did, native mode > sysenter handling should, when converting to #GP, subtract 2 from the > RIP present in the frame so that the guest's GP fault handler would > see the fault pointing to the offending instruction instead of past it. > > Finally, since those exception generating code blocks needed to be > modified anyway, convert them to make use of UNLIKELY_{START,END}(). > > Signed-off-by: Jan Beulich Acked-by: Keir Fraser > --- a/xen/arch/x86/x86_64/asm-offsets.c > +++ b/xen/arch/x86/x86_64/asm-offsets.c > @@ -145,6 +145,7 @@ void __dummy__(void) > > OFFSET(TRAPINFO_eip, struct trap_info, address); > OFFSET(TRAPINFO_cs, struct trap_info, cs); > + OFFSET(TRAPINFO_flags, struct trap_info, flags); > DEFINE(TRAPINFO_sizeof, sizeof(struct trap_info)); > BLANK(); > > --- a/xen/arch/x86/x86_64/compat/entry.S > +++ b/xen/arch/x86/x86_64/compat/entry.S > @@ -213,6 +213,7 @@ compat_failsafe_callback: > 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 > @@ -225,20 +226,21 @@ ENTRY(compat_syscall) > leaq VCPU_trap_bounce(%rbx),%rdx > testl $~3,%esi > leal (,%rcx,TBF_INTERRUPT),%ecx > - jz 2f > -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 > -2: movq VCPU_trap_ctxt(%rbx),%rsi > +UNLIKELY_START(z, compat_syscall_gpf) > + movq VCPU_trap_ctxt(%rbx),%rdi > movl $TRAP_gp_fault,UREGS_entry_vector(%rsp) > subl $2,UREGS_rip(%rsp) > - movl TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%eax > - movzwl TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_cs(%rsi),%esi > - movb $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl > movl $0,TRAPBOUNCE_error_code(%rdx) > - jmp 1b > + movl TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rdi),%eax > + movzwl TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_cs(%rdi),%esi > + testb $4,TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_flags(%rdi) > + setnz %cl > + leal TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx > +UNLIKELY_END(compat_syscall_gpf) > + movq %rax,TRAPBOUNCE_eip(%rdx) > + movw %si,TRAPBOUNCE_cs(%rdx) > + movb %cl,TRAPBOUNCE_flags(%rdx) > + jmp .Lcompat_bounce_exception > > ENTRY(compat_sysenter) > movq VCPU_trap_ctxt(%rbx),%rcx > --- a/xen/arch/x86/x86_64/entry.S > +++ b/xen/arch/x86/x86_64/entry.S > @@ -277,20 +277,22 @@ sysenter_eflags_saved: > leaq VCPU_trap_bounce(%rbx),%rdx > testq %rax,%rax > leal (,%rcx,TBF_INTERRUPT),%ecx > - jz 2f > -1: movq VCPU_domain(%rbx),%rdi > +UNLIKELY_START(z, sysenter_gpf) > + movq VCPU_trap_ctxt(%rbx),%rsi > + movl $TRAP_gp_fault,UREGS_entry_vector(%rsp) > + subl $2,UREGS_rip(%rsp) > + movl %eax,TRAPBOUNCE_error_code(%rdx) > + movq TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%rax > + testb $4,TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_flags(%rsi) > + setnz %cl > + leal TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx > +UNLIKELY_END(sysenter_gpf) > + movq VCPU_domain(%rbx),%rdi > movq %rax,TRAPBOUNCE_eip(%rdx) > movb %cl,TRAPBOUNCE_flags(%rdx) > testb $1,DOMAIN_is_32bit_pv(%rdi) > jnz compat_sysenter > - call create_bounce_frame > - jmp test_all_events > -2: movq VCPU_trap_ctxt(%rbx),%rcx > - movl %eax,TRAPBOUNCE_error_code(%rdx) > - movq TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rcx),%rax > - movb $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl > - movl $TRAP_gp_fault,UREGS_entry_vector(%rsp) > - jmp 1b > + jmp .Lbounce_exception > > ENTRY(int80_direct_trap) > pushq $0 > @@ -483,6 +485,7 @@ handle_exception_saved: > 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 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel