WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] vDSO paravirtualization: paravirtualize vDSO
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Jul 2006 16:21:20 +0000
Delivery-date: Fri, 28 Jul 2006 09:29:33 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [IA64] vDSO paravirtualization: paravirtualize vDSO, Xen patchbot-unstable <=