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] Hypercall optimizations

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] Hypercall optimizations
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 18 Jan 2007 21:10:52 -0800
Delivery-date: Thu, 18 Jan 2007 21:13:42 -0800
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@xxxxxxxxxxxx
# Date 1168559818 25200
# Node ID 01ea554f1c5e8bdbfa172349438298b15da6fc5c
# Parent  db72b85b81bb1478cb2e91b6411596648bdc9a2c
[IA64] Hypercall optimizations

provide hypercall the same path with system
most of scrach registers don't need to be saved/restored
it is good for performance

Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    |    7 
 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   |    2 
 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h |  108 +----
 xen/arch/ia64/asm-offsets.c                       |    1 
 xen/arch/ia64/linux-xen/entry.S                   |  111 +++++
 xen/arch/ia64/xen/faults.c                        |   23 -
 xen/arch/ia64/xen/hypercall.c                     |  172 ++------
 xen/arch/ia64/xen/ivt.S                           |  430 +++++++++++++++++-----
 xen/include/asm-ia64/config.h                     |    6 
 xen/include/asm-ia64/hypercall.h                  |    2 
 xen/include/public/arch-ia64.h                    |    2 
 11 files changed, 541 insertions(+), 323 deletions(-)

diff -r db72b85b81bb -r 01ea554f1c5e 
linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    Thu Jan 11 14:42:24 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    Thu Jan 11 16:56:58 
2007 -0700
@@ -306,4 +306,11 @@ GLOBAL_ENTRY(xen_ssm_i_1)
        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
diff -r db72b85b81bb -r 01ea554f1c5e 
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Thu Jan 11 14:42:24 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Thu Jan 11 16:56:58 
2007 -0700
@@ -48,6 +48,8 @@ static int p2m_expose_init(void);
 #else
 #define p2m_expose_init() (-ENOSYS)
 #endif
+
+EXPORT_SYMBOL(__hypercall);
 
 //XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
 // move those to lib/contiguous_bitmap?
diff -r db72b85b81bb -r 01ea554f1c5e 
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Jan 11 14:42:24 
2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Jan 11 16:56:58 
2007 -0700
@@ -39,6 +39,9 @@
 
 #include <asm/xen/xcom_hcall.h>
 struct xencomm_handle;
+extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
+                                 unsigned long a3, unsigned long a4,
+                                 unsigned long a5, unsigned long cmd);
 
 /*
  * Assembler stubs for hyper-calls.
@@ -47,115 +50,58 @@ struct xencomm_handle;
 #define _hypercall0(type, name)                                        \
 ({                                                             \
        long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "J" (__HYPERVISOR_##name)       \
-                             : "r2","r8",                      \
-                               "memory" );                     \
+       __res=__hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);  \
        (type)__res;                                            \
 })
 
 #define _hypercall1(type, name, a1)                            \
 ({                                                             \
        long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "J" (__HYPERVISOR_##name),      \
-                               "rI" ((unsigned long)(a1))      \
-                             : "r14","r2","r8",                \
-                               "memory" );                     \
+       __res = __hypercall((unsigned long)a1,                  \
+                            0, 0, 0, 0, __HYPERVISOR_##name);  \
        (type)__res;                                            \
 })
 
 #define _hypercall2(type, name, a1, a2)                                \
 ({                                                             \
        long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "J" (__HYPERVISOR_##name),      \
-                               "rI" ((unsigned long)(a1)),     \
-                               "rI" ((unsigned long)(a2))      \
-                             : "r14","r15","r2","r8",          \
-                               "memory" );                     \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           0, 0, 0, __HYPERVISOR_##name);      \
        (type)__res;                                            \
 })
 
 #define _hypercall3(type, name, a1, a2, a3)                    \
 ({                                                             \
        long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r16=%4\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "J" (__HYPERVISOR_##name),      \
-                               "rI" ((unsigned long)(a1)),     \
-                               "rI" ((unsigned long)(a2)),     \
-                               "rI" ((unsigned long)(a3))      \
-                             : "r14","r15","r16","r2","r8",    \
-                               "memory" );                     \
-       (type)__res;                                            \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           (unsigned long)a3,                  \
+                           0, 0, __HYPERVISOR_##name);         \
+       (type)__res;                                            \
 })
 
 #define _hypercall4(type, name, a1, a2, a3, a4)                        \
 ({                                                             \
        long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r16=%4\n"                    \
-                             "mov r17=%5\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "J" (__HYPERVISOR_##name),      \
-                               "rI" ((unsigned long)(a1)),     \
-                               "rI" ((unsigned long)(a2)),     \
-                               "rI" ((unsigned long)(a3)),     \
-                               "rI" ((unsigned long)(a4))      \
-                             : "r14","r15","r16","r2","r8",    \
-                               "r17","memory" );               \
-       (type)__res;                                            \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           (unsigned long)a3,                  \
+                           (unsigned long)a4,                  \
+                           0, __HYPERVISOR_##name);            \
+       (type)__res;                                            \
 })
 
 #define _hypercall5(type, name, a1, a2, a3, a4, a5)            \
 ({                                                             \
        long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r16=%4\n"                    \
-                             "mov r17=%5\n"                    \
-                             "mov r18=%6\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "J" (__HYPERVISOR_##name),      \
-                               "rI" ((unsigned long)(a1)),     \
-                               "rI" ((unsigned long)(a2)),     \
-                               "rI" ((unsigned long)(a3)),     \
-                               "rI" ((unsigned long)(a4)),     \
-                               "rI" ((unsigned long)(a5))      \
-                             : "r14","r15","r16","r2","r8",    \
-                               "r17","r18","memory" );         \
-       (type)__res;                                            \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           (unsigned long)a3,                  \
+                           (unsigned long)a4,                  \
+                           (unsigned long)a5,                  \
+                           __HYPERVISOR_##name);               \
+       (type)__res;                                            \
 })
 
 
diff -r db72b85b81bb -r 01ea554f1c5e xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/arch/ia64/asm-offsets.c       Thu Jan 11 16:56:58 2007 -0700
@@ -56,6 +56,7 @@ void foo(void)
        DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, 
arch._thread.on_ustack));
 
        DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain));
+       DEFINE(IA64_VCPU_HYPERCALL_CONTINUATION_OFS, offsetof (struct vcpu, 
arch.hypercall_continuation));
        DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu, 
arch.metaphysical_rr0));
        DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, 
arch.metaphysical_saved_rr0));
        DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, 
arch.breakimm));
diff -r db72b85b81bb -r 01ea554f1c5e xen/arch/ia64/linux-xen/entry.S
--- a/xen/arch/ia64/linux-xen/entry.S   Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/arch/ia64/linux-xen/entry.S   Thu Jan 11 16:56:58 2007 -0700
@@ -676,7 +676,9 @@ GLOBAL_ENTRY(ia64_ret_from_syscall)
        cmp.ge p6,p7=r8,r0                      // syscall executed 
successfully?
        adds r2=PT(R8)+16,sp                    // r2 = &pt_regs.r8
        mov r10=r0                              // clear error indication in r10
+#ifndef XEN    
 (p7)   br.cond.spnt handle_syscall_error       // handle potential syscall 
failure
+#endif
 END(ia64_ret_from_syscall)
        // fall through
 /*
@@ -764,7 +766,9 @@ ENTRY(ia64_leave_syscall)
        ld8 r19=[r2],PT(B6)-PT(LOADRS)          // load ar.rsc value for 
"loadrs"
        nop.i 0
        ;;
+#ifndef XEN    
        mov r16=ar.bsp                          // M2  get existing backing 
store pointer
+#endif    
        ld8 r18=[r2],PT(R9)-PT(B6)              // load b6
 #ifndef XEN
 (p6)   and r15=TIF_WORK_MASK,r31               // any work other than 
TIF_SYSCALL_TRACE?
@@ -814,7 +818,11 @@ ENTRY(ia64_leave_syscall)
        mov f8=f0                               // F    clear f8
        ;;
        ld8.fill r12=[r2]                       // M0|1 restore r12 (sp)
+#ifdef XEN    
+       ld8.fill r2=[r3]                        // M0|1
+#else    
        ld8.fill r15=[r3]                       // M0|1 restore r15
+#endif    
        mov b6=r18                              // I0   restore b6
 
 #ifdef XEN
@@ -827,7 +835,9 @@ ENTRY(ia64_leave_syscall)
 
        srlz.d                          // M0   ensure interruption collection 
is off (for cover)
        shr.u r18=r19,16                // I0|1 get byte size of existing 
"dirty" partition
+#ifndef XEN    
        cover                           // B    add current frame into dirty 
partition & set cr.ifs
+#endif    
        ;;
 (pUStk) ld4 r17=[r17]                  // M0|1 r17 = 
cpu_data->phys_stacked_size_p8
        mov r19=ar.bsp                  // M2   get new backing store pointer
@@ -893,23 +903,18 @@ GLOBAL_ENTRY(ia64_leave_kernel)
 .work_processed_kernel:
 #ifdef XEN
        ;;
-(pUStk) ssm psr.i
-(pUStk)    br.call.sptk.many b0=do_softirq
-(pUStk) rsm psr.i
-    ;;
-       alloc loc0=ar.pfs,0,1,1,0
-       adds out0=16,r12
+(pUStk)        ssm psr.i
+(pUStk)        br.call.sptk.many b0=do_softirq
+(pUStk)        ssm psr.i
+       ;;
+(pUStk)        br.call.sptk.many b0=reflect_event
+       ;;
        adds r7 = PT(EML_UNAT)+16,r12
        ;;
        ld8 r7 = [r7]
        ;;
-(pUStk)        br.call.sptk.many b0=reflect_event
-//(pUStk)      br.call.sptk.many b0=deliver_pending_interrupt
-    ;;
-       mov ar.pfs=loc0
        mov ar.unat=r7  /* load eml_unat  */
        mov r31=r0
-
 
 #else
        adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
@@ -1184,8 +1189,11 @@ skip_rbs_switch:
        mov cr.ipsr=r29         // M2
        mov ar.pfs=r26          // I0
 (pLvSys)mov r17=r0             // A  clear r17 for leave_syscall, no-op 
otherwise
-
+#ifdef XEN
+       mov cr.ifs=r30          // M2
+#else    
 (p9)   mov cr.ifs=r30          // M2
+#endif
        mov b0=r21              // I0
 (pLvSys)mov r18=r0             // A  clear r18 for leave_syscall, no-op 
otherwise
 
@@ -1195,7 +1203,11 @@ skip_rbs_switch:
        ;;
 (pUStk)        mov ar.rnat=r24         // M2 must happen with RSE in lazy mode
        nop 0
+#ifdef XEN    
+(pLvSys)mov r15=r0
+#else
 (pLvSys)mov r2=r0
+#endif
 
        mov ar.rsc=r27          // M2
        mov pr=r31,-1           // I0
@@ -1459,7 +1471,80 @@ 1:       mov gp=loc2                             // 
restore gp
        br.ret.sptk.many rp
 END(unw_init_running)
 
-#ifndef XEN
+#ifdef XEN
+       .rodata
+       .align 8
+       .globl ia64_hypercall_table
+ia64_hypercall_table:
+       data8 do_ni_hypercall           /* do_set_trap_table *//*  0 */
+       data8 do_ni_hypercall           /* do_mmu_update */
+       data8 do_ni_hypercall           /* do_set_gdt */
+       data8 do_ni_hypercall           /* do_stack_switch */
+       data8 do_ni_hypercall           /* do_set_callbacks */
+       data8 do_ni_hypercall           /* do_fpu_taskswitch *//*  5 */
+       data8 do_sched_op_compat
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall           /* do_set_debugreg */
+       data8 do_ni_hypercall           /* do_get_debugreg */
+       data8 do_ni_hypercall           /* do_update_descriptor * 10 */
+       data8 do_ni_hypercall           /* do_ni_hypercall */
+       data8 do_memory_op
+       data8 do_multicall
+       data8 do_ni_hypercall           /* do_update_va_mapping */
+       data8 do_ni_hypercall           /* do_set_timer_op */  /* 15 */
+       data8 do_ni_hypercall
+       data8 do_xen_version
+       data8 do_console_io
+       data8 do_ni_hypercall
+       data8 do_grant_table_op                                /* 20 */
+       data8 do_ni_hypercall           /* do_vm_assist */
+       data8 do_ni_hypercall           /* do_update_va_mapping_othe */
+       data8 do_ni_hypercall           /* (x86 only) */
+       data8 do_ni_hypercall           /* do_vcpu_op */
+       data8 do_ni_hypercall           /* (x86_64 only) */    /* 25 */
+       data8 do_ni_hypercall           /* do_mmuext_op */
+       data8 do_ni_hypercall           /* do_acm_op */
+       data8 do_ni_hypercall           /* do_nmi_op */
+       data8 do_sched_op
+       data8 do_callback_op            /*  */                 /* 30 */
+       data8 do_xenoprof_op            /*  */
+       data8 do_event_channel_op
+       data8 do_physdev_op
+       data8 do_hvm_op                 /*  */
+       data8 do_sysctl                 /*  */                  /* 35 */
+       data8 do_domctl                 /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */                 /* 40 */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */                 /* 45 */
+       data8 do_ni_hypercall           /*  */
+       data8 do_ni_hypercall           /*  */
+       data8 do_dom0vp_op              /* dom0vp_op */
+       data8 do_pirq_guest_eoi         /* arch_1 */
+       data8 do_ni_hypercall           /* arch_2 */           /* 50 */
+       data8 do_ni_hypercall           /* arch_3 */
+       data8 do_ni_hypercall           /* arch_4 */
+       data8 do_ni_hypercall           /* arch_5 */
+       data8 do_ni_hypercall           /* arch_6 */
+       data8 do_ni_hypercall           /* arch_7 */           /* 55 */
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall                                  /* 60 */
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall
+       data8 do_ni_hypercall
+
+       // guard against failures to increase NR_hypercalls
+       .org ia64_hypercall_table + 8*NR_hypercalls
+
+#else
        .rodata
        .align 8
        .globl sys_call_table
diff -r db72b85b81bb -r 01ea554f1c5e xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c        Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/arch/ia64/xen/faults.c        Thu Jan 11 16:56:58 2007 -0700
@@ -83,8 +83,8 @@ void reflect_interruption(unsigned long 
                check_bad_nested_interruption(isr, regs, vector);
        PSCB(v, unat) = regs->ar_unat;  // not sure if this is really needed?
        PSCB(v, precover_ifs) = regs->cr_ifs;
+       PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
        vcpu_bsw0(v);
-       PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
        PSCB(v, isr) = isr;
        PSCB(v, iip) = regs->cr_iip;
        PSCB(v, ifs) = 0;
@@ -120,24 +120,29 @@ void reflect_extint(struct pt_regs *regs
        reflect_interruption(isr, regs, IA64_EXTINT_VECTOR);
 }
 
-void reflect_event(struct pt_regs *regs)
-{
-       unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
-       struct vcpu *v = current;
+void reflect_event(void)
+{
+       struct vcpu *v = current;
+       struct pt_regs *regs;
+       unsigned long isr;
+
+       if (!event_pending(v))
+               return;
 
        /* Sanity check */
-       if (is_idle_vcpu(v) || !user_mode(regs)) {
+       if (is_idle_vcpu(v)) {
                //printk("WARN: invocation to reflect_event in nested xen\n");
                return;
        }
 
-       if (!event_pending(v))
-               return;
+       regs = vcpu_regs(v);
 
        // can't inject event, when XEN is emulating rfi 
        // and both PSCB(v, ifs) and regs->ifs are valid
        if (regs->cr_iip == *(unsigned long *)dorfirfi)
                return;
+
+       isr = regs->cr_ipsr & IA64_PSR_RI;
 
        if (!PSCB(v, interrupt_collection_enabled))
                printk("psr.ic off, delivering event, ipsr=%lx,iip=%lx,"
@@ -145,8 +150,8 @@ void reflect_event(struct pt_regs *regs)
                       regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip));
        PSCB(v, unat) = regs->ar_unat;  // not sure if this is really needed?
        PSCB(v, precover_ifs) = regs->cr_ifs;
+       PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
        vcpu_bsw0(v);
-       PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr);
        PSCB(v, isr) = isr;
        PSCB(v, iip) = regs->cr_iip;
        PSCB(v, ifs) = 0;
diff -r db72b85b81bb -r 01ea554f1c5e xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/arch/ia64/xen/hypercall.c     Thu Jan 11 16:56:58 2007 -0700
@@ -17,6 +17,7 @@
 #include <asm/sal.h>   /* FOR struct ia64_sal_retval */
 #include <asm/fpswa.h> /* FOR struct fpswa_ret_t */
 
+#include <asm/vmx_vcpu.h>
 #include <asm/vcpu.h>
 #include <asm/dom_fw.h>
 #include <public/domctl.h>
@@ -32,94 +33,14 @@
 #include <xen/event.h>
 #include <xen/perfc.h>
 
-static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
-static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
-
-const hypercall_t ia64_hypercall_table[NR_hypercalls] =
-{
-       (hypercall_t)do_ni_hypercall,           /* do_set_trap_table *//*  0 */
-       (hypercall_t)do_ni_hypercall,           /* do_mmu_update */
-       (hypercall_t)do_ni_hypercall,           /* do_set_gdt */
-       (hypercall_t)do_ni_hypercall,           /* do_stack_switch */
-       (hypercall_t)do_ni_hypercall,           /* do_set_callbacks */
-       (hypercall_t)do_ni_hypercall,           /* do_fpu_taskswitch *//*  5 */
-       (hypercall_t)do_sched_op_compat,
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall,           /* do_set_debugreg */
-       (hypercall_t)do_ni_hypercall,           /* do_get_debugreg */
-       (hypercall_t)do_ni_hypercall,           /* do_update_descriptor * 10 */
-       (hypercall_t)do_ni_hypercall,           /* do_ni_hypercall */
-       (hypercall_t)do_memory_op,
-       (hypercall_t)do_multicall,
-       (hypercall_t)do_ni_hypercall,           /* do_update_va_mapping */
-       (hypercall_t)do_ni_hypercall,           /* do_set_timer_op */  /* 15 */
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_xen_version,
-       (hypercall_t)do_console_io,
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_grant_table_op,                                /* 20 */
-       (hypercall_t)do_ni_hypercall,           /* do_vm_assist */
-       (hypercall_t)do_ni_hypercall,           /* do_update_va_mapping_othe */
-       (hypercall_t)do_ni_hypercall,           /* (x86 only) */
-       (hypercall_t)do_ni_hypercall,           /* do_vcpu_op */
-       (hypercall_t)do_ni_hypercall,           /* (x86_64 only) */    /* 25 */
-       (hypercall_t)do_ni_hypercall,           /* do_mmuext_op */
-       (hypercall_t)do_ni_hypercall,           /* do_acm_op */
-       (hypercall_t)do_ni_hypercall,           /* do_nmi_op */
-       (hypercall_t)do_sched_op,
-       (hypercall_t)do_callback_op,            /*  */                 /* 30 */
-       (hypercall_t)do_xenoprof_op,            /*  */
-       (hypercall_t)do_event_channel_op,
-       (hypercall_t)do_physdev_op,
-       (hypercall_t)do_hvm_op,                 /*  */
-       (hypercall_t)do_sysctl,                 /*  */                  /* 35 */
-       (hypercall_t)do_domctl,                 /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */                 /* 40 */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */                 /* 45 */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_ni_hypercall,           /*  */
-       (hypercall_t)do_dom0vp_op,              /* dom0vp_op */
-       (hypercall_t)do_ni_hypercall,           /* arch_1 */
-       (hypercall_t)do_ni_hypercall,           /* arch_2 */           /* 50 */
-       (hypercall_t)do_ni_hypercall,           /* arch_3 */
-       (hypercall_t)do_ni_hypercall,           /* arch_4 */
-       (hypercall_t)do_ni_hypercall,           /* arch_5 */
-       (hypercall_t)do_ni_hypercall,           /* arch_6 */
-       (hypercall_t)do_ni_hypercall,           /* arch_7 */           /* 55 */
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall,                                  /* 60 */
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall,
-       (hypercall_t)do_ni_hypercall
-};
+extern long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
+extern long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
 
 static IA64FAULT
 xen_hypercall (struct pt_regs *regs)
 {
        uint32_t cmd = (uint32_t)regs->r2;
-
-       if (cmd < NR_hypercalls) {
-               perfc_incra(hypercalls, cmd);
-               regs->r8 = (*ia64_hypercall_table[cmd])(
-                       regs->r14,
-                       regs->r15,
-                       regs->r16,
-                       regs->r17,
-                       regs->r18,
-                       regs->r19);
-       } else
-               regs->r8 = -ENOSYS;
-       
+       printk("Warning %s should not be called %d\n", __FUNCTION__, cmd);
        return IA64_NO_FAULT;
 }
 
@@ -129,13 +50,20 @@ xen_fast_hypercall (struct pt_regs *regs
        uint32_t cmd = (uint32_t)regs->r2;
        switch (cmd) {
        case __HYPERVISOR_ia64_fast_eoi:
-               regs->r8 = pirq_guest_eoi(current->domain, regs->r14);
+               printk("Warning %s should not be called %d\n",
+                      __FUNCTION__, cmd);
                break;
        default:
                regs->r8 = -ENOSYS;
        }
        return IA64_NO_FAULT;
 }
+
+long do_pirq_guest_eoi(int pirq)
+{
+       return pirq_guest_eoi(current->domain, pirq);
+}
+    
 
 static void
 fw_hypercall_ipi (struct pt_regs *regs)
@@ -320,42 +248,42 @@ unsigned long hypercall_create_continuat
     va_list args;
 
     va_start(args, format);
-    if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) {
-       panic("PREEMPT happen in multicall\n"); // Not support yet
-    } else {
-       vcpu_set_gr(v, 2, op, 0);
-       for ( i = 0; *p != '\0'; i++) {
-            switch ( *p++ )
-            {
-            case 'i':
-                arg = (unsigned long)va_arg(args, unsigned int);
-                break;
-            case 'l':
-                arg = (unsigned long)va_arg(args, unsigned long);
-                break;
-            case 'h':
-                arg = (unsigned long)va_arg(args, void *);
-                break;
-            default:
-                arg = 0;
-                BUG();
-            }
-           switch (i) {
-           case 0: vcpu_set_gr(v, 14, arg, 0);
-                   break;
-           case 1: vcpu_set_gr(v, 15, arg, 0);
-                   break;
-           case 2: vcpu_set_gr(v, 16, arg, 0);
-                   break;
-           case 3: vcpu_set_gr(v, 17, arg, 0);
-                   break;
-           case 4: vcpu_set_gr(v, 18, arg, 0);
-                   break;
-           default: panic("Too many args for hypercall continuation\n");
-                   break;
-           }
-       }
-    }
+    if (test_bit(_MCSF_in_multicall, &mcs->flags))
+        panic("PREEMPT happen in multicall\n");        // Not support yet
+
+    vcpu_set_gr(v, 15, op, 0);
+
+    for (i = 0; *p != '\0'; i++) {
+        switch ( *p++ )
+        {
+        case 'i':
+            arg = (unsigned long)va_arg(args, unsigned int);
+            break;
+        case 'l':
+            arg = (unsigned long)va_arg(args, unsigned long);
+            break;
+        case 'h':
+            arg = (unsigned long)va_arg(args, void *);
+            break;
+        default:
+            arg = 0;
+            BUG();
+        }
+        vcpu_set_gr(v, 16 + i, arg, 0);
+    }
+    
+    if (i >= 6)
+        panic("Too many args for hypercall continuation\n");
+
+    // Clean other argument to 0
+    while (i < 6) {
+        vcpu_set_gr(v, 16 + i, 0, 0);
+        i++;
+    }
+
+    // re-execute break;
+    vcpu_decrement_iip(v);
+    
     v->arch.hypercall_continuation = 1;
     va_end(args);
     return op;
@@ -369,7 +297,7 @@ iosapic_guest_write(
 iosapic_guest_write(
     unsigned long physbase, unsigned int reg, u32 pval);
 
-static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     int irq;
     long ret;
@@ -524,7 +452,7 @@ static long unregister_guest_callback(st
 /* First time to add callback to xen/ia64, so let's just stick to
  * the newer callback interface.
  */
-static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     long ret;
 
diff -r db72b85b81bb -r 01ea554f1c5e xen/arch/ia64/xen/ivt.S
--- a/xen/arch/ia64/xen/ivt.S   Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/arch/ia64/xen/ivt.S   Thu Jan 11 16:56:58 2007 -0700
@@ -2,6 +2,7 @@
 #include <asm/debugger.h>
 #include <asm/vhpt.h>
 #include <public/arch-ia64.h>
+#include <asm/config.h>
 #endif
 /*
  * arch/ia64/kernel/ivt.S
@@ -1055,7 +1056,6 @@ ENTRY(break_fault)
         * level.
         */
        DBG_FAULT(11)
-#ifdef XEN
        mov r16=cr.isr
        mov r17=cr.iim
        mov r31=pr
@@ -1101,103 +1101,202 @@ ENTRY(break_fault)
        ;;
        ld8 r22 = [r22]
        ;;
-       adds r22=IA64_VCPU_BREAKIMM_OFFSET,r22
-       ;;
-       ld4 r23=[r22];;
+       adds r23=IA64_VCPU_BREAKIMM_OFFSET,r22
+       ;;
+       ld4 r23=[r23];;
        cmp4.eq p6,p7=r23,r17                   // Xen-reserved breakimm?
-(p6)   br.spnt.many dispatch_break_fault
+(p6)   br.spnt.many fast_hypercall
        ;;
        br.sptk.many fast_break_reflect
        ;;
-#else /* !XEN */
-       movl r16=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
-       ld8 r16=[r16]
-       mov r17=cr.iim
-       mov r18=__IA64_BREAK_SYSCALL
-       mov r21=ar.fpsr
-       mov r29=cr.ipsr
-       mov r19=b6
-       mov r25=ar.unat
-       mov r27=ar.rsc
-       mov r26=ar.pfs
-       mov r28=cr.iip
-#ifndef XEN
-       mov r31=pr                      // prepare to save predicates
-#endif
-       mov r20=r1
-       ;;
+
+
+fast_hypercall:
+       shr r25=r2,8;;
+       cmp.ne p7,p0=r0,r25
+(p7)   br.spnt.few dispatch_break_fault
+       ;;
+       // fall through
+   
+
+       /*
+        * The streamlined system call entry/exit paths only save/restore the 
initial part
+        * of pt_regs.  This implies that the callers of system-calls must 
adhere to the
+        * normal procedure calling conventions.
+        *
+        *   Registers to be saved & restored:
+        *      CR registers: cr.ipsr, cr.iip, cr.ifs
+        *      AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, 
ar.fpsr
+        *      others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
+        *   Registers to be restored only:
+        *      r8-r11: output value from the system call.
+        *
+        * During system call exit, scratch registers (including r15) are 
modified/cleared
+        * to prevent leaking bits from kernel to user level.
+        */
+    
+//     DBG_FAULT(11)
+//     mov.m r16=IA64_KR(CURRENT)              // M2 r16 <- current task (12 
cyc)
+       mov r16=r22
+       mov r29=cr.ipsr                         // M2 (12 cyc)
+//     mov r31=pr                              // I0 (2 cyc)
+       mov r15=r2
+
+//     mov r17=cr.iim                          // M2 (2 cyc)
+       mov.m r27=ar.rsc                        // M2 (12 cyc)
+//     mov r18=__IA64_BREAK_SYSCALL            // A
+
+       mov.m ar.rsc=0                          // M2
+       mov.m r21=ar.fpsr                       // M2 (12 cyc)
+       mov r19=b6                              // I0 (2 cyc)
+       ;;
+       mov.m r23=ar.bspstore                   // M2 (12 cyc)
+       mov.m r24=ar.rnat                       // M2 (5 cyc)
+       mov.i r26=ar.pfs                        // I0 (2 cyc)
+
+       invala                                  // M0|1
+       nop.m 0                                 // M
+       mov r20=r1                              // A                    save r1
+
+       nop.m 0
+//     movl r30=sys_call_table                 // X
+       movl r30=ia64_hypercall_table                   // X
+
+       mov r28=cr.iip                          // M2 (2 cyc)
+//     cmp.eq p0,p7=r18,r17                    // I0 is this a system call?
+//(p7) br.cond.spnt non_syscall                // B  no ->
+       //
+       // From this point on, we are definitely on the syscall-path
+       // and we can use (non-banked) scratch registers.
+       //
+///////////////////////////////////////////////////////////////////////
+       mov r1=r16                              // A    move task-pointer to 
"addl"-addressable reg
+       mov r2=r16                              // A    setup r2 for 
ia64_syscall_setup
+//     add r9=TI_FLAGS+IA64_TASK_SIZE,r16      // A    r9 = 
&current_thread_info()->flags
+
        adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
-       cmp.eq p0,p7=r18,r17            // is this a system call? 
-                                       //   (p7 <- false, if so)
-(p7)   br.cond.spnt non_syscall
-       ;;
-       ld1 r17=[r16]                   // load current->thread.on_ustack flag
-       st1 [r16]=r0                    // clear current->thread.on_ustack flag
-       add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
-                                       // set r1 for 
-                                       //   MINSTATE_START_SAVE_MIN_VIRT
-       ;;
-       invala
-
-       /* adjust return address so we skip over the break instruction: */
-
-       extr.u r8=r29,41,2              // extract ei field from cr.ipsr
-       ;;
-       cmp.eq p6,p7=2,r8               // isr.ei==2?
-       mov r2=r1                       // setup r2 for ia64_syscall_setup
-       ;;
-(p6)   mov r8=0                        // clear ei to 0
-(p6)   adds r28=16,r28                 // switch cr.iip to next bundle 
-                                       //   cr.ipsr.ei wrapped
-(p7)   adds r8=1,r8                    // increment ei to next slot
-       ;;
-       cmp.eq pKStk,pUStk=r0,r17       // are we in kernel mode already?
-       dep r29=r8,r29,41,2             // insert new ei into cr.ipsr
-       ;;
-
-       // switch from user to kernel RBS:
-       MINSTATE_START_SAVE_MIN_VIRT
-       br.call.sptk.many b7=ia64_syscall_setup
-       ;;
-       MINSTATE_END_SAVE_MIN_VIRT      // switch to bank 1
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i                          // guarantee that interruption 
-                                       //   collection is on
-       mov r3=NR_syscalls - 1
-       ;;
-(p15)  ssm psr.i                       // restore psr.i
-       // p10==true means out registers are more than 8 or r15's Nat is true
-(p10)  br.cond.spnt.many ia64_ret_from_syscall
-       ;;
-       movl r16=sys_call_table
-
-       adds r15=-1024,r15              // r15 contains the syscall number --
-                                       //   subtract 1024 from it
-       movl r2=ia64_ret_from_syscall
-       ;;
-       shladd r20=r15,3,r16            // r20 = sys_call_table + 
-                                       //       8*(syscall-1024)
-       cmp.leu p6,p7=r15,r3            // (syscall > 0 && syscall < 1024 +
-                                       //  NR_syscalls) ?
-       mov rp=r2                       // set the real return addr
-       ;;
-(p6)   ld8 r20=[r20]                   // load address of syscall entry point
-(p7)   movl r20=sys_ni_syscall
-
-       add r2=TI_FLAGS+IA64_TASK_SIZE,r13
-       ;;
-       ld4 r2=[r2]                     // r2 = current_thread_info()->flags
-       ;;
-       and r2=_TIF_SYSCALL_TRACEAUDIT,r2  // mask trace or audit
-       ;;
-       cmp.eq p8,p0=r2,r0
-       mov b6=r20
-       ;;
-(p8)   br.call.sptk.many b6=b6         // ignore this return addr
-       br.cond.sptk ia64_trace_syscall
-       // NOT REACHED
-#endif
+//     adds r15=-1024,r15                      // A    subtract 1024 from 
syscall number
+//     mov r3=NR_syscalls - 1
+       mov r3=NR_hypercalls - 1
+       ;;
+       ld1.bias r17=[r16]                      // M0|1 r17 = 
current->thread.on_ustack flag
+//     ld4 r9=[r9]                             // M0|1 r9 = 
current_thread_info()->flags
+       mov r9=r0               // force flags = 0
+       extr.u r8=r29,41,2                      // I0   extract ei field from 
cr.ipsr
+
+       shladd r30=r15,3,r30                    // A    r30 = sys_call_table + 
8*(syscall-1024)
+       addl r22=IA64_RBS_OFFSET,r1             // A    compute base of RBS
+       cmp.leu p6,p7=r15,r3                    // A    syscall number in range?
+       ;;
+
+       lfetch.fault.excl.nt1 [r22]             // M0|1 prefetch RBS
+(p6)   ld8 r30=[r30]                           // M0|1 load address of syscall 
entry point
+       tnat.nz.or p7,p0=r15                    // I0   is syscall nr a NaT?
+
+       mov.m ar.bspstore=r22                   // M2   switch to kernel RBS
+       cmp.eq p8,p9=2,r8                       // A    isr.ei==2?
+       ;;
+
+(p8)   mov r8=0                                // A    clear ei to 0
+//(p7) movl r30=sys_ni_syscall                 // X
+(p7)   movl r30=do_ni_hypercall                        // X
+
+(p8)   adds r28=16,r28                         // A    switch cr.iip to next 
bundle
+(p9)   adds r8=1,r8                            // A    increment ei to next 
slot
+       nop.i 0
+       ;;
+
+       mov.m r25=ar.unat                       // M2 (5 cyc)
+       dep r29=r8,r29,41,2                     // I0   insert new ei into 
cr.ipsr
+//     adds r15=1024,r15                       // A    restore original 
syscall number
+       //
+       // If any of the above loads miss in L1D, we'll stall here until
+       // the data arrives.
+       //
+///////////////////////////////////////////////////////////////////////
+       st1 [r16]=r0                            // M2|3 clear 
current->thread.on_ustack flag
+       mov b6=r30                              // I0   setup syscall handler 
branch reg early
+       cmp.eq pKStk,pUStk=r0,r17               // A    were we on kernel 
stacks already?
+
+//     and r9=_TIF_SYSCALL_TRACEAUDIT,r9       // A    mask trace or audit
+       mov r18=ar.bsp                          // M2 (12 cyc)
+       ;;
+(pUStk)        addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute 
base of memory stack
+//     cmp.eq p14,p0=r9,r0                     // A    are syscalls being 
traced/audited?
+       br.call.sptk.many b7=ia64_syscall_setup // B
+1:
+       mov ar.rsc=0x3                          // M2   set eager mode, pl 0, 
LE, loadrs=0
+       nop 0
+       bsw.1                                   // B (6 cyc) regs are saved, 
switch to bank 1
+       ;;
+
+       ssm psr.ic | PSR_DEFAULT_BITS           // M2   now it's safe to 
re-enable intr.-collection
+//     movl r3=ia64_ret_from_syscall           // X
+       ;;
+
+       srlz.i                                  // M0   ensure interruption 
collection is on
+//     mov rp=r3                               // I0   set the real return addr
+//(p10)        br.cond.spnt.many ia64_ret_from_syscall // B    return if bad 
call-frame or r15 is a NaT
+(p15)  ssm psr.i                               // M2   restore psr.i
+//(p14)        br.call.sptk.many b6=b6                 // B    invoke 
syscall-handker (ignore return addr)
+//     br.call.sptk.many b6=b6                 // B    invoke syscall-handker 
(ignore return addr)
+       br.call.sptk.many b0=b6                 // B    invoke syscall-handker 
(ignore return addr)
+//     br.cond.spnt.many ia64_trace_syscall    // B    do syscall-tracing 
thingamagic
+       ;;
+       adds r2=PT(R8)+16,r12
+       ;;
+       st8 [r2]=r8
+       ;;
+       br.call.sptk.many b0=do_softirq
+       ;;
+       //restore hypercall argument if continuation
+       adds r2=IA64_VCPU_HYPERCALL_CONTINUATION_OFS,r13
+       ;;
+       ld1 r20=[r2]
+       ;;
+       st1 [r2]=r0
+       ;;
+       cmp.ne p6,p0=r20,r0
+       ;;
+(p6)   adds r2=PT(R16)+16,r12
+(p6)   adds r3=PT(R17)+16,r12
+       ;;
+(p6)   ld8 r32=[r2],16
+(p6)   ld8 r33=[r3],16
+       ;;
+(p6)   ld8 r34=[r2],16
+(p6)   ld8 r35=[r3],16
+       ;;
+(p6)   ld8 r36=[r2],16
+       ;;
+//save ar.bsp before cover
+       mov r16=ar.bsp
+       add r2=PT(R14)+16,r12
+       ;;
+       st8 [r2]=r16
+       ;;
+       rsm psr.i|psr.ic
+       ;;
+       srlz.i
+       ;;
+       cover
+       ;;
+       mov r20=cr.ifs    
+       adds r2=PT(CR_IFS)+16,r12
+       ;;
+       st8 [r2]=r20
+       ;;   
+       br.call.sptk.many b0=reflect_event
+       ;;
+       adds r2=PT(R14)+16,r12
+       adds r3=PT(R8)+16,r12
+       ;;
+       //r16 contains ar.bsp before cover
+       ld8 r16=[r2]
+       ld8 r8=[r3]
+       ;;
+       br.sptk.many ia64_ret_from_syscall
+       ;;
 END(break_fault)
 
        .org ia64_ivt+0x3000
@@ -1297,7 +1396,150 @@ END(dispatch_break_fault)
        DBG_FAULT(14)
        FAULT(14)
 
-#ifndef XEN
+#ifdef XEN
+    // this code segment is from 2.6.16.13
+    
+       /*
+        * There is no particular reason for this code to be here, other than 
that
+        * there happens to be space here that would go unused otherwise.  If 
this
+        * fault ever gets "unreserved", simply moved the following code to a 
more
+        * suitable spot...
+        *
+        * ia64_syscall_setup() is a separate subroutine so that it can
+        *      allocate stacked registers so it can safely demine any
+        *      potential NaT values from the input registers.
+        *
+        * On entry:
+        *      - executing on bank 0 or bank 1 register set (doesn't matter)
+        *      -  r1: stack pointer
+        *      -  r2: current task pointer
+        *      -  r3: preserved
+        *      - r11: original contents (saved ar.pfs to be saved)
+        *      - r12: original contents (sp to be saved)
+        *      - r13: original contents (tp to be saved)
+        *      - r15: original contents (syscall # to be saved)
+        *      - r18: saved bsp (after switching to kernel stack)
+        *      - r19: saved b6
+        *      - r20: saved r1 (gp)
+        *      - r21: saved ar.fpsr
+        *      - r22: kernel's register backing store base (krbs_base)
+        *      - r23: saved ar.bspstore
+        *      - r24: saved ar.rnat
+        *      - r25: saved ar.unat
+        *      - r26: saved ar.pfs
+        *      - r27: saved ar.rsc
+        *      - r28: saved cr.iip
+        *      - r29: saved cr.ipsr
+        *      - r31: saved pr
+        *      -  b0: original contents (to be saved)
+        * On exit:
+        *      -  p10: TRUE if syscall is invoked with more than 8 out
+        *              registers or r15's Nat is true
+        *      -  r1: kernel's gp
+        *      -  r3: preserved (same as on entry)
+        *      -  r8: -EINVAL if p10 is true
+        *      - r12: points to kernel stack
+        *      - r13: points to current task
+        *      - r14: preserved (same as on entry)
+        *      - p13: preserved
+        *      - p15: TRUE if interrupts need to be re-enabled
+        *      - ar.fpsr: set to kernel settings
+        *      -  b6: preserved (same as on entry)
+        */
+GLOBAL_ENTRY(ia64_syscall_setup)
+#if PT(B6) != 0
+# error This code assumes that b6 is the first field in pt_regs.
+#endif
+       st8 [r1]=r19                            // save b6
+       add r16=PT(CR_IPSR),r1                  // initialize first base pointer
+       add r17=PT(R11),r1                      // initialize second base 
pointer
+       ;;
+       alloc r19=ar.pfs,8,0,0,0                // ensure in0-in7 are writable
+       st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)    // save cr.ipsr
+       tnat.nz p8,p0=in0
+
+       st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)  // save r11
+       tnat.nz p9,p0=in1
+(pKStk)        mov r18=r0                              // make sure r18 isn't 
NaT
+       ;;
+
+       st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)     // save ar.pfs
+       st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)    // save cr.iip
+       mov r28=b0                              // save b0 (2 cyc)
+       ;;
+
+       st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)    // save ar.unat
+       dep r19=0,r19,38,26                     // clear all bits but 0..37 [I0]
+(p8)   mov in0=-1
+       ;;
+
+       st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)    // store ar.pfs.pfm in cr.ifs
+       extr.u r11=r19,7,7      // I0           // get sol of ar.pfs
+       and r8=0x7f,r19         // A            // get sof of ar.pfs
+
+       st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
+       tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
+(p9)   mov in1=-1
+       ;;
+
+(pUStk) sub r18=r18,r22                                // r18=RSE.ndirty*8
+       tnat.nz p10,p0=in2
+       add r11=8,r11
+       ;;
+(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16                // skip over ar_rnat 
field
+(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17    // skip over ar_bspstore field
+       tnat.nz p11,p0=in3
+       ;;
+(p10)  mov in2=-1
+       tnat.nz p12,p0=in4                              // [I0]
+(p11)  mov in3=-1
+       ;;
+(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)       // save ar.rnat
+(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)   // save ar.bspstore
+       shl r18=r18,16                          // compute ar.rsc to be used 
for "loadrs"
+       ;;
+       st8 [r16]=r31,PT(LOADRS)-PT(PR)         // save predicates
+       st8 [r17]=r28,PT(R1)-PT(B0)             // save b0
+       tnat.nz p13,p0=in5                              // [I0]
+       ;;
+       st8 [r16]=r18,PT(R12)-PT(LOADRS)        // save ar.rsc value for 
"loadrs"
+       st8.spill [r17]=r20,PT(R13)-PT(R1)      // save original r1
+(p12)  mov in4=-1
+       ;;
+
+.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)       // save r12
+.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)           // save r13
+(p13)  mov in5=-1
+       ;;
+       st8 [r16]=r21,PT(R8)-PT(AR_FPSR)        // save ar.fpsr
+       tnat.nz p13,p0=in6
+       cmp.lt p10,p9=r11,r8    // frame size can't be more than local+8
+       ;;
+       mov r8=1
+(p9)   tnat.nz p10,p0=r15
+       adds r12=-16,r1         // switch to kernel memory stack (with 16 bytes 
of scratch)
+
+       st8.spill [r17]=r15                     // save r15
+       tnat.nz p8,p0=in7
+       nop.i 0
+
+       mov r13=r2                              // establish `current'
+       movl r1=__gp                            // establish kernel global 
pointer
+       ;;
+       st8 [r16]=r8            // ensure pt_regs.r8 != 0 (see 
handle_syscall_error)
+(p13)  mov in6=-1
+(p8)   mov in7=-1
+
+       cmp.eq pSys,pNonSys=r0,r0               // set pSys=1, pNonSys=0
+       movl r17=FPSR_DEFAULT
+       ;;
+       mov.m ar.fpsr=r17                       // set ar.fpsr to kernel 
default value
+(p10)  mov r8=-EINVAL
+       br.ret.sptk.many b7
+END(ia64_syscall_setup)
+
+
+#else    
        /*
         * There is no particular reason for this code to be here, other 
         * than that there happens to be space here that would go unused 
diff -r db72b85b81bb -r 01ea554f1c5e xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h     Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/include/asm-ia64/config.h     Thu Jan 11 16:56:58 2007 -0700
@@ -51,6 +51,9 @@
 #endif
 
 #define CONFIG_VGA 1
+
+
+#define NR_hypercalls 64
 
 #ifndef __ASSEMBLY__
 
@@ -107,9 +110,6 @@ extern char _end[]; /* standard ELF symb
 // xen/include/asm/config.h
 //#define HZ 1000
 // FIXME SMP: leave SMP for a later time
-
-#define NR_hypercalls 64
-
 ///////////////////////////////////////////////////////////////
 // xen/include/asm/config.h
 // Natural boundary upon TR size to define xenheap space
diff -r db72b85b81bb -r 01ea554f1c5e xen/include/asm-ia64/hypercall.h
--- a/xen/include/asm-ia64/hypercall.h  Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/include/asm-ia64/hypercall.h  Thu Jan 11 16:56:58 2007 -0700
@@ -13,6 +13,8 @@ do_event_channel_op_compat(
 do_event_channel_op_compat(
     XEN_GUEST_HANDLE(evtchn_op_t) uop);
 
+extern long do_pirq_guest_eoi(int pirq);
+
 extern int
 vmx_do_mmu_update(
     mmu_update_t *ureqs,
diff -r db72b85b81bb -r 01ea554f1c5e xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Thu Jan 11 14:42:24 2007 -0700
+++ b/xen/include/public/arch-ia64.h    Thu Jan 11 16:56:58 2007 -0700
@@ -463,7 +463,7 @@ struct xen_ia64_boot_param {
 #define HYPERPRIVOP_MAX                        (0x19)
 
 /* Fast and light hypercalls.  */
-#define __HYPERVISOR_ia64_fast_eoi     0x0200
+#define __HYPERVISOR_ia64_fast_eoi     __HYPERVISOR_arch_1
 
 /* Xencomm macros.  */
 #define XENCOMM_INLINE_MASK 0xf800000000000000UL

_______________________________________________
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] Hypercall optimizations, Xen patchbot-unstable <=