[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86-64: fix #GP generation in assembly code
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxx> # Date 1334669633 -7200 # Node ID 80f4113be5007f5b8a61048272193ce134b4fc28 # Parent 6092641e364428e7be20c9e23497d7a1fc535112 x86-64: fix #GP generation in assembly code 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 <jbeulich@xxxxxxxx> Acked-by: Keir Fraser <keir@xxxxxxx> --- diff -r 6092641e3644 -r 80f4113be500 xen/arch/x86/x86_64/asm-offsets.c --- a/xen/arch/x86/x86_64/asm-offsets.c Tue Apr 17 15:05:05 2012 +0200 +++ b/xen/arch/x86/x86_64/asm-offsets.c Tue Apr 17 15:33:53 2012 +0200 @@ -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(); diff -r 6092641e3644 -r 80f4113be500 xen/arch/x86/x86_64/compat/entry.S --- a/xen/arch/x86/x86_64/compat/entry.S Tue Apr 17 15:05:05 2012 +0200 +++ b/xen/arch/x86/x86_64/compat/entry.S Tue Apr 17 15:33:53 2012 +0200 @@ -213,6 +213,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 @@ -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) +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 $0,TRAPBOUNCE_error_code(%rdx) + 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) - call compat_create_bounce_frame - jmp compat_test_all_events -2: movq VCPU_trap_ctxt(%rbx),%rsi - 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 + jmp .Lcompat_bounce_exception ENTRY(compat_sysenter) movq VCPU_trap_ctxt(%rbx),%rcx diff -r 6092641e3644 -r 80f4113be500 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Tue Apr 17 15:05:05 2012 +0200 +++ b/xen/arch/x86/x86_64/entry.S Tue Apr 17 15:33:53 2012 +0200 @@ -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 @@ 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 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |