# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1184743850 -32400 # Node ID d56b9afce6ef5e5a5e7b9e79d75c2d6e8bf0bd19 # Parent 3a6c6fdb633bcf41d089a31b857518a217b6a93b cleanup vdso paravirtualization. Hyperprivop calling convention was changed such that vpsr.ic is left intact. So we don't have to worry about itlb miss fault with vpsr.ic = 0 PATCHNAME: vdso_paravirtualization_clean_up Signed-off-by: Isaku Yamahata diff -r 3a6c6fdb633b -r d56b9afce6ef arch/ia64/Kconfig --- a/arch/ia64/Kconfig Wed Jul 18 12:18:02 2007 +0900 +++ b/arch/ia64/Kconfig Wed Jul 18 16:30:50 2007 +0900 @@ -66,7 +66,7 @@ config XEN both as a guest OS on Xen and natively on hardware. config XEN_IA64_VDSO_PARAVIRT - bool + bool "Xen/IA64 vdso area paravirtualization" depends on XEN && !ITANIUM default y help diff -r 3a6c6fdb633b -r d56b9afce6ef arch/ia64/kernel/gate.S --- a/arch/ia64/kernel/gate.S Wed Jul 18 12:18:02 2007 +0900 +++ b/arch/ia64/kernel/gate.S Wed Jul 18 16:30:50 2007 +0900 @@ -33,17 +33,6 @@ .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-. #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT - // The page in which hyperprivop lives must be pinned by ITR. - // However vDSO area isn't pinned. So issuing hyperprivop - // from vDSO page causes trouble that Kevin pointed out. - // After clearing vpsr.ic, the vcpu is pre-empted and the itlb - // is flushed. Then vcpu get cpu again, tlb miss fault occures. - // However it results in nested dtlb fault because vpsr.ic is off. - // To avoid such a situation, we jump into the kernel text area - // which is pinned, and then issue hyperprivop and return back - // to vDSO page. - // This is Dan Magenheimer's idea. - // Currently is_running_on_xen() is defined as running_on_xen. // If is_running_on_xen() is a real function, we must update // according to it. @@ -52,21 +41,7 @@ #define LOAD_RUNNING_ON_XEN(reg) \ [1:] movl reg=0; \ .xdata4 ".data.patch.running_on_xen", 1b-. - - .section ".data.patch.brl_xen_ssm_i_0", "a" - .previous -#define BRL_COND_XEN_SSM_I_0(pr) \ -[1:](pr)brl.cond.sptk 0; \ - ;; ; \ - .xdata4 ".data.patch.brl_xen_ssm_i_0", 1b-. - - .section ".data.patch.brl_xen_ssm_i_1", "a" - .previous -#define BRL_COND_XEN_SSM_I_1(pr) \ -[1:](pr)brl.cond.sptk 0; \ - ;; ; \ - .xdata4 ".data.patch.brl_xen_ssm_i_1", 1b-. -#endif +#endif /* CONFIG_XEN_IA64_VDSO_PARAVIRT */ GLOBAL_ENTRY(__kernel_syscall_via_break) .prologue @@ -111,11 +86,9 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) mov r10=0 // A default to successful syscall execution epc // B causes split-issue } - ;; #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT // r20 = 1 // r22 = &vcpu->vcpu_info->evtchn_upcall_mask - // r23 = &vpsr.ic // r24 = &vcpu->vcpu_info->evtchn_upcall_pending // r25 = tmp // r28 = &running_on_xen @@ -130,8 +103,6 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) #define isRaw p13 LOAD_RUNNING_ON_XEN(r28) movl r22=XSI_PSR_I_ADDR - ;; - movl r23=XSI_PSR_IC mov r20=1 ;; ld4 r30=[r28] @@ -144,8 +115,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) (isXen) adds r24=-1,r22 (isXen) st1 [r22]=r20 (isXen) rum psr.be - ;; -#else +#else + ;; rsm psr.be | psr.i // M2 (5 cyc to srlz.d) #endif LOAD_FSYSCALL_TABLE(r14) // X @@ -177,15 +148,26 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) nop.m 0 (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT - ;; + +#define XEN_SET_PSR_I(pr) \ +(pr) ld1 r31=[r22]; \ +(pr) ld1 r25=[r24]; \ + ;; \ +(pr) st1 [r22]=r0; \ +(pr) cmp.ne.unc p14,p0=r0,r31; \ + ;; \ +(p14) cmp.ne.unc p11,p0=r0,r25; \ + ;; \ +(p11) st1 [r22]=r20; \ +(p11) XEN_HYPER_SSM_I; + + ;; // p14 = running_on_xen && p8 // p15 = !running_on_xen && p8 (p8) cmp.ne.unc p14,p15=r0,r30 ;; (p15) ssm psr.i - BRL_COND_XEN_SSM_I_0(p14) - .global .vdso_ssm_i_0_ret -.vdso_ssm_i_0_ret: + XEN_SET_PSR_I(p14) #else nop.i 0 ;; @@ -213,19 +195,12 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) #endif #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT (isRaw) ssm psr.i - BRL_COND_XEN_SSM_I_1(isXen) - .global .vdso_ssm_i_1_ret -.vdso_ssm_i_1_ret: + XEN_SET_PSR_I(isXen) #else ssm psr.i #endif mov r10=-1 (p10) mov r8=EINVAL -#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT - dv_serialize_data // shut up gas warning. - // we know xen_hyper_ssm_i_0 or xen_hyper_ssm_i_1 - // doesn't change p9 and p10 -#endif (p9) mov r8=ENOSYS FSYS_RETURN END(__kernel_syscall_via_epc) diff -r 3a6c6fdb633b -r d56b9afce6ef arch/ia64/kernel/gate.lds.S --- a/arch/ia64/kernel/gate.lds.S Wed Jul 18 12:18:02 2007 +0900 +++ b/arch/ia64/kernel/gate.lds.S Wed Jul 18 16:30:50 2007 +0900 @@ -48,14 +48,6 @@ SECTIONS __start_gate_running_on_xen_patchlist = .; *(.data.patch.running_on_xen) __end_gate_running_on_xen_patchlist = .; - - __start_gate_brl_xen_ssm_i_0_patchlist = .; - *(.data.patch.brl_xen_ssm_i_0) - __end_gate_brl_xen_ssm_i_0_patchlist = .; - - __start_gate_brl_xen_ssm_i_1_patchlist = .; - *(.data.patch.brl_xen_ssm_i_1) - __end_gate_brl_xen_ssm_i_1_patchlist = .; #endif } :readable .IA_64.unwind_info : { *(.IA_64.unwind_info*) } diff -r 3a6c6fdb633b -r d56b9afce6ef arch/ia64/kernel/patch.c --- a/arch/ia64/kernel/patch.c Wed Jul 18 12:18:02 2007 +0900 +++ b/arch/ia64/kernel/patch.c Wed Jul 18 16:30:50 2007 +0900 @@ -204,47 +204,8 @@ patch_running_on_xen(unsigned long start ia64_sync_i(); ia64_srlz_i(); } - -static void -patch_brl_symaddr(unsigned long start, unsigned long end, - unsigned long symaddr) -{ - s32 *offp = (s32 *)start; - u64 ip; - - while (offp < (s32 *)end) { - ip = (u64)offp + *offp; - ia64_patch_imm60((u64)ia64_imva((void *)ip), - (u64)(symaddr - (ip & -16)) / 16); - ia64_fc((void *)ip); - ++offp; - } - ia64_sync_i(); - ia64_srlz_i(); -} - -#define EXTERN_PATCHLIST(name) \ - extern char __start_gate_brl_##name##_patchlist[]; \ - extern char __end_gate_brl_##name##_patchlist[]; \ - extern char name[] - -#define PATCH_BRL_SYMADDR(name) \ - patch_brl_symaddr((unsigned long)__start_gate_brl_##name##_patchlist, \ - (unsigned long)__end_gate_brl_##name##_patchlist, \ - (unsigned long)name) - -static void -patch_brl_in_vdso(void) -{ - EXTERN_PATCHLIST(xen_ssm_i_0); - EXTERN_PATCHLIST(xen_ssm_i_1); - - PATCH_BRL_SYMADDR(xen_ssm_i_0); - PATCH_BRL_SYMADDR(xen_ssm_i_1); -} #else #define patch_running_on_xen(start, end) do { } while (0) -#define patch_brl_in_vdso() do { } while (0) #endif void __init @@ -257,7 +218,6 @@ ia64_patch_gate (void) patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down)); #ifdef CONFIG_XEN patch_running_on_xen(START(running_on_xen), END(running_on_xen)); - patch_brl_in_vdso(); #endif ia64_patch_vtop(START(vtop), END(vtop)); ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); diff -r 3a6c6fdb633b -r d56b9afce6ef arch/ia64/xen/hypercall.S --- a/arch/ia64/xen/hypercall.S Wed Jul 18 12:18:02 2007 +0900 +++ b/arch/ia64/xen/hypercall.S Wed Jul 18 16:30:50 2007 +0900 @@ -133,46 +133,9 @@ GLOBAL_ENTRY(xen_send_ipi) ;; END(xen_send_ipi) -#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT -// Those are vdso specialized. -// In fsys mode, call, ret can't be used. - - // see xen_ssm_i() in privop.h - // r22 = &vcpu->vcpu_info->evtchn_upcall_mask - // r23 = &vpsr.ic - // r24 = &vcpu->vcpu_info->evtchn_upcall_pending - // r25 = tmp - // r31 = tmp - // p11 = tmp - // p14 = tmp -#define XEN_SET_PSR_I \ - ld1 r31=[r22]; \ - ld1 r25=[r24]; \ - ;; \ - st1 [r22]=r0; \ - cmp.ne.unc p14,p0=r0,r31; \ - ;; \ -(p14) cmp.ne.unc p11,p0=r0,r25; \ - ;; \ -(p11) st1 [r22]=r20; \ -(p11) XEN_HYPER_SSM_I; - -GLOBAL_ENTRY(xen_ssm_i_0) - XEN_SET_PSR_I - brl.cond.sptk .vdso_ssm_i_0_ret - ;; -END(xen_ssm_i_0) - -GLOBAL_ENTRY(xen_ssm_i_1) - XEN_SET_PSR_I - brl.cond.sptk .vdso_ssm_i_1_ret - ;; -END(xen_ssm_i_1) - GLOBAL_ENTRY(__hypercall) mov r2=r37 break 0x1000 br.ret.sptk.many b0 ;; END(__hypercall) -#endif