[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] vDSO paravirtualization: paravirtualize vDSO



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 8d501f39286c28cddfd0f26e5e92a6e86176bbe4
# Parent  614deef19299e3352233d5e27017b677830d47f3
[IA64] vDSO paravirtualization: paravirtualize vDSO

paravirtualize vdso areabased on Kevin's pointout and Dan's Idea.
introduce hyperprivop HYPERPRIVOP_RSM_BE and HYPERPRIVOP_GET_PSR.
and paravirtualize vdso area using them.

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/Kconfig             |    7 +
 linux-2.6-xen-sparse/arch/ia64/kernel/gate.S       |  112 +++++++++++++++++++++
 linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S   |   22 ++++
 linux-2.6-xen-sparse/arch/ia64/kernel/patch.c      |   71 +++++++++++++
 linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S     |   56 ++++++++++
 linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h |    2 
 xen/arch/ia64/xen/privop.c                         |    7 +
 xen/include/public/arch-ia64.h                     |    4 
 8 files changed, 280 insertions(+), 1 deletion(-)

diff -r 614deef19299 -r 8d501f39286c linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Mon Jul 24 13:04:40 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Mon Jul 24 13:43:35 2006 -0600
@@ -70,6 +70,13 @@ config XEN_IA64_DOM0_NON_VP
        default y
        help
          dom0 P=M model
+
+config XEN_IA64_VDSO_PARAVIRT
+       bool
+       depends on XEN && !ITANIUM
+       default y
+       help
+         vDSO paravirtualization
 
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        bool
diff -r 614deef19299 -r 8d501f39286c 
linux-2.6-xen-sparse/arch/ia64/kernel/gate.S
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S      Mon Jul 24 13:04:40 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S      Mon Jul 24 13:43:35 
2006 -0600
@@ -14,6 +14,9 @@
 #include <asm/sigcontext.h>
 #include <asm/system.h>
 #include <asm/unistd.h>
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+# include <asm/privop.h>
+#endif
 
 /*
  * We can't easily refer to symbols inside the kernel.  To avoid full runtime 
relocation,
@@ -32,6 +35,52 @@
 #define BRL_COND_FSYS_BUBBLE_DOWN(pr)                  \
 [1:](pr)brl.cond.sptk 0;                               \
        .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.
+       .section ".data.patch.running_on_xen", "a"
+       .previous
+#define LOAD_RUNNING_ON_XEN(reg)                       \
+[1:]   movl reg=0;                                     \
+       .xdata4 ".data.patch.running_on_xen", 1b-.
+
+       .section ".data.patch.brl_xen_rsm_be_i", "a"
+       .previous
+#define BRL_COND_XEN_RSM_BE_I(pr)                      \
+[1:](pr)brl.cond.sptk 0;                               \
+       .xdata4 ".data.patch.brl_xen_rsm_be_i", 1b-.
+
+       .section ".data.patch.brl_xen_get_psr", "a"
+       .previous
+#define BRL_COND_XEN_GET_PSR(pr)                       \
+[1:](pr)brl.cond.sptk 0;                               \
+       .xdata4 ".data.patch.brl_xen_get_psr", 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
 
 GLOBAL_ENTRY(__kernel_syscall_via_break)
        .prologue
@@ -77,7 +126,39 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
        epc                                     // B    causes split-issue
 }
        ;;
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+       // r20 = 1
+       // r22 = &vcpu->evtchn_mask
+       // r23 = &vpsr.ic
+       // r24 = vcpu->pending_interruption
+       // r25 = tmp
+       // r28 = &running_on_xen
+       // r30 = running_on_xen
+       // r31 = tmp
+       // p11 = tmp
+       // p12 = running_on_xen
+       // p13 = !running_on_xen
+       // p14 = tmp
+       // p15 = tmp
+#define isXen  p12
+#define isRaw  p13
+       LOAD_RUNNING_ON_XEN(r28)
+       movl r22=XSI_PSR_I_ADDR
+       movl r23=XSI_PSR_IC
+       movl r24=XSI_PSR_I_ADDR+(XSI_PEND_OFS-XSI_PSR_I_ADDR_OFS)
+       mov r20=1
+       ;;
+       ld4 r30=[r28]
+       ;;
+       cmp.ne isXen,isRaw=r0,r30
+       ;;
+(isRaw)        rsm psr.be | psr.i
+       BRL_COND_XEN_RSM_BE_I(isXen)
+       .global .vdso_rsm_be_i_ret
+.vdso_rsm_be_i_ret:
+#else
        rsm psr.be | psr.i                      // M2 (5 cyc to srlz.d)
+#endif
        LOAD_FSYSCALL_TABLE(r14)                // X
        ;;
        mov r16=IA64_KR(CURRENT)                // M2 (12 cyc)
@@ -85,7 +166,14 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
        mov r19=NR_syscalls-1                   // A
        ;;
        lfetch [r18]                            // M0|1
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+(isRaw)        mov r29=psr
+       BRL_COND_XEN_GET_PSR(isXen)
+       .global .vdso_get_psr_ret
+.vdso_get_psr_ret:
+#else
        mov r29=psr                             // M2 (12 cyc)
+#endif
        // If r17 is a NaT, p6 will be zero
        cmp.geu p6,p7=r19,r17                   // A    (sysnr > 0 && sysnr < 
1024+NR_syscalls)?
        ;;
@@ -99,9 +187,21 @@ 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
+       ;;
+       // 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:
+#else
        nop.i 0
        ;;
 (p8)   ssm psr.i
+#endif
 (p6)   mov b7=r18                              // I0
 (p8)   br.dptk.many b7                         // B
 
@@ -122,9 +222,21 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
 #else
        BRL_COND_FSYS_BUBBLE_DOWN(p6)
 #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:
+#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 614deef19299 -r 8d501f39286c 
linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S  Mon Jul 24 13:04:40 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S  Mon Jul 24 13:43:35 
2006 -0600
@@ -43,6 +43,28 @@ SECTIONS
                                    __start_gate_brl_fsys_bubble_down_patchlist 
= .;
                                    *(.data.patch.brl_fsys_bubble_down)
                                    __end_gate_brl_fsys_bubble_down_patchlist = 
.;
+
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+                                   __start_gate_running_on_xen_patchlist = .;
+                                   *(.data.patch.running_on_xen)
+                                   __end_gate_running_on_xen_patchlist = .;
+
+                                   __start_gate_brl_xen_rsm_be_i_patchlist = .;
+                                   *(.data.patch.brl_xen_rsm_be_i)
+                                   __end_gate_brl_xen_rsm_be_i_patchlist = .;
+
+                                   __start_gate_brl_xen_get_psr_patchlist = .;
+                                   *(.data.patch.brl_xen_get_psr)
+                                   __end_gate_brl_xen_get_psr_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*) }
   .IA_64.unwind                        : { *(.IA_64.unwind*) }                 
:readable :unwind
diff -r 614deef19299 -r 8d501f39286c 
linux-2.6-xen-sparse/arch/ia64/kernel/patch.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/patch.c     Mon Jul 24 13:04:40 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/patch.c     Mon Jul 24 13:43:35 
2006 -0600
@@ -184,6 +184,73 @@ patch_brl_fsys_bubble_down (unsigned lon
        ia64_srlz_i();
 }
 
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+extern char __start_gate_running_on_xen_patchlist[];
+extern char __end_gate_running_on_xen_patchlist[];
+
+void
+patch_running_on_xen(unsigned long start, unsigned long end)
+{
+       extern int running_on_xen;
+       s32 *offp = (s32 *)start;
+       u64 ip;
+
+       while (offp < (s32 *)end) {
+               ip = (u64)ia64_imva((char *)offp + *offp);
+               ia64_patch_imm64(ip, (u64)&running_on_xen);
+               ia64_fc((void *)ip);
+               ++offp;
+       }
+       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_rsm_be_i);
+       EXTERN_PATCHLIST(xen_get_psr);
+       EXTERN_PATCHLIST(xen_ssm_i_0);
+       EXTERN_PATCHLIST(xen_ssm_i_1);
+
+       PATCH_BRL_SYMADDR(xen_rsm_be_i);
+       PATCH_BRL_SYMADDR(xen_get_psr);
+       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
 ia64_patch_gate (void)
 {
@@ -192,6 +259,10 @@ ia64_patch_gate (void)
 
        patch_fsyscall_table(START(fsyscall), END(fsyscall));
        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 614deef19299 -r 8d501f39286c 
linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    Mon Jul 24 13:04:40 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    Mon Jul 24 13:43:35 
2006 -0600
@@ -351,3 +351,59 @@ GLOBAL_ENTRY(xen_send_ipi)
         br.ret.sptk.many rp
         ;;
 END(xen_send_ipi)
+
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+// Those are vdso specialized.
+// In fsys mode, call, ret can't be used.
+GLOBAL_ENTRY(xen_rsm_be_i)
+       ld8 r22=[r22]
+       ;; 
+       st1 [r22]=r20
+       st4 [r23]=r0
+       XEN_HYPER_RSM_BE
+       st4 [r23]=r20
+       brl.cond.sptk   .vdso_rsm_be_i_ret
+       ;; 
+END(xen_rsm_be_i)
+
+GLOBAL_ENTRY(xen_get_psr)
+       mov r31=r8
+       mov r25=IA64_PSR_IC
+       st4 [r23]=r0
+       XEN_HYPER_GET_PSR
+       ;; 
+       st4 [r23]=r20
+       or r29=r8,r25 // vpsr.ic was cleared for hyperprivop
+       mov r8=r31
+       brl.cond.sptk   .vdso_get_psr_ret
+       ;; 
+END(xen_get_psr)
+
+GLOBAL_ENTRY(xen_ssm_i_0)
+       st4 [r22]=r20
+       ld4 r25=[r24]
+       ;;
+       cmp.ne.unc p11,p0=r0, r25
+       ;; 
+(p11)  st4 [r22]=r0
+(p11)  st4 [r23]=r0
+(p11)  XEN_HYPER_SSM_I
+       
+       brl.cond.sptk   .vdso_ssm_i_0_ret
+       ;; 
+END(xen_ssm_i_0)
+
+GLOBAL_ENTRY(xen_ssm_i_1)
+       st4 [r22]=r20
+       ld4 r25=[r24]
+       ;; 
+       cmp.ne.unc p11,p0=r0, r25
+       ;; 
+(p11)  st4 [r22]=r0
+(p11)  st4 [r23]=r0
+(p11)  XEN_HYPER_SSM_I
+       ;;
+       brl.cond.sptk   .vdso_ssm_i_1_ret
+       ;; 
+END(xen_ssm_i_1)
+#endif
diff -r 614deef19299 -r 8d501f39286c 
linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h        Mon Jul 24 
13:04:40 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h        Mon Jul 24 
13:43:35 2006 -0600
@@ -48,6 +48,8 @@
 #define        XEN_HYPER_GET_PMD               break HYPERPRIVOP_GET_PMD
 #define        XEN_HYPER_GET_EFLAG             break HYPERPRIVOP_GET_EFLAG
 #define        XEN_HYPER_SET_EFLAG             break HYPERPRIVOP_SET_EFLAG
+#define        XEN_HYPER_RSM_BE                break HYPERPRIVOP_RSM_BE
+#define        XEN_HYPER_GET_PSR               break HYPERPRIVOP_GET_PSR
 
 #define XSI_IFS                        (XSI_BASE + XSI_IFS_OFS)
 #define XSI_PRECOVER_IFS       (XSI_BASE + XSI_PRECOVER_IFS_OFS)
diff -r 614deef19299 -r 8d501f39286c xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Mon Jul 24 13:04:40 2006 -0600
+++ b/xen/arch/ia64/xen/privop.c        Mon Jul 24 13:43:35 2006 -0600
@@ -789,6 +789,13 @@ ia64_hyperprivop(unsigned long iim, REGS
            case HYPERPRIVOP_SET_EFLAG:
                (void)vcpu_set_ar(v,24,regs->r8);
                return 1;
+           case HYPERPRIVOP_RSM_BE:
+               (void)vcpu_reset_psr_sm(v, IA64_PSR_BE);
+               return 1;
+           case HYPERPRIVOP_GET_PSR:
+               (void)vcpu_get_psr(v, &val);
+               regs->r8 = val;
+               return 1;
        }
        return 0;
 }
diff -r 614deef19299 -r 8d501f39286c xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Mon Jul 24 13:04:40 2006 -0600
+++ b/xen/include/public/arch-ia64.h    Mon Jul 24 13:43:35 2006 -0600
@@ -420,7 +420,9 @@ struct xen_ia64_boot_param {
 #define HYPERPRIVOP_GET_PMD            0x15
 #define HYPERPRIVOP_GET_EFLAG          0x16
 #define HYPERPRIVOP_SET_EFLAG          0x17
-#define HYPERPRIVOP_MAX                        0x17
+#define HYPERPRIVOP_RSM_BE             0x18
+#define HYPERPRIVOP_GET_PSR            0x19
+#define HYPERPRIVOP_MAX                        0x19
 
 #endif /* __HYPERVISOR_IF_IA64_H__ */
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.