# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1164116163 -32400 # Node ID d4f466290efa229fd6dcb2be8439b0f8c113a231 # Parent 7f8a27d2f0eda3c96cf3c3ae9d1cac91dad30065 fix paravirtualization of clone2() system call. If audit is enabled or the child process is ptraced, non-paravirtualized code path is executed. Thus paravirtualized ifs is left unmodifed so that the child process crashes after clone2(). paravirtualize ia64_ret_from_clone() to fix it. PATCHNAME: paravirtualize_ia64_ret_from_clone2 Signed-off-by: Isaku Yamahata diff -r 7f8a27d2f0ed -r d4f466290efa linux-2.6-xen-sparse/arch/ia64/kernel/entry.S --- a/linux-2.6-xen-sparse/arch/ia64/kernel/entry.S Tue Nov 21 21:54:39 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/entry.S Tue Nov 21 22:36:03 2006 +0900 @@ -602,7 +602,7 @@ GLOBAL_ENTRY(ia64_strace_leave_kernel) .ret4: br.cond.sptk ia64_leave_kernel END(ia64_strace_leave_kernel) -GLOBAL_ENTRY(ia64_ret_from_clone) +GLOBAL_ENTRY(__ia64_ret_from_clone) PT_REGS_UNWIND_INFO(0) { /* * Some versions of gas generate bad unwind info if the first instruction of a @@ -628,7 +628,7 @@ GLOBAL_ENTRY(ia64_ret_from_clone) cmp.ne p6,p0=r2,r0 (p6) br.cond.spnt .strace_check_retval ;; // added stop bits to prevent r8 dependency -END(ia64_ret_from_clone) +END(__ia64_ret_from_clone) // fall through GLOBAL_ENTRY(ia64_ret_from_syscall) PT_REGS_UNWIND_INFO(0) diff -r 7f8a27d2f0ed -r d4f466290efa linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Tue Nov 21 21:54:39 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Tue Nov 21 22:36:03 2006 +0900 @@ -237,6 +237,47 @@ END(ia64_trace_syscall) END(ia64_trace_syscall) #endif +#ifdef CONFIG_XEN +GLOBAL_ENTRY(xen_ret_from_clone) + PT_REGS_UNWIND_INFO(0) + movl r16=running_on_xen;; + ld4 r16=[r16];; + cmp.eq p7,p0=r16,r0 +(p7) br.cond.sptk.many __ia64_ret_from_clone;; +#else +GLOBAL_ENTRY(ia64_ret_from_clone) + PT_REGS_UNWIND_INFO(0) +#endif +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 + /* + * We need to call schedule_tail() to complete the scheduling process. + * Called by ia64_switch_to() after do_fork()->copy_thread(). r8 contains the + * address of the previously executing task. + */ + br.call.sptk.many rp=ia64_invoke_schedule_tail +} +.ret8: + adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 + ;; + ld4 r2=[r2] + ;; + mov r8=0 + and r2=_TIF_SYSCALL_TRACEAUDIT,r2 + ;; + cmp.ne p6,p0=r2,r0 +(p6) br.cond.spnt .strace_check_retval + ;; // added stop bits to prevent r8 dependency +#ifdef CONFIG_XEN + br.cond.sptk ia64_ret_from_syscall +END(xen_ret_from_clone) +#else +END(ia64_ret_from_clone) +#endif /* * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't * need to switch to bank 0 and doesn't restore the scratch registers. diff -r 7f8a27d2f0ed -r d4f466290efa linux-2.6-xen-sparse/include/asm-ia64/privop.h --- a/linux-2.6-xen-sparse/include/asm-ia64/privop.h Tue Nov 21 21:54:39 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/privop.h Tue Nov 21 22:36:03 2006 +0900 @@ -49,6 +49,7 @@ #define ia64_leave_kernel __ia64_leave_kernel #define ia64_leave_syscall __ia64_leave_syscall #define ia64_trace_syscall __ia64_trace_syscall +#define ia64_ret_from_clone __ia64_ret_from_clone #define ia64_switch_to __ia64_switch_to #define ia64_pal_call_static __ia64_pal_call_static diff -r 7f8a27d2f0ed -r d4f466290efa linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h --- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h Tue Nov 21 21:54:39 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h Tue Nov 21 22:36:03 2006 +0900 @@ -295,6 +295,7 @@ extern void xen_ptcga(unsigned long addr #define ia64_leave_kernel xen_leave_kernel #define ia64_leave_syscall xen_leave_syscall #define ia64_trace_syscall xen_trace_syscall +#define ia64_ret_from_clone xen_ret_from_clone #define ia64_switch_to xen_switch_to #define ia64_pal_call_static xen_pal_call_static