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

[Xen-changelog] [xen-unstable] [IA64] Implement fast hypercall for physdevop eoi.



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID c3f71a4ed653b5a643abf985e05d92039b98dec7
# Parent  bacae4057790768fdc800496b71e10671961f58c
[IA64] Implement fast hypercall for physdevop eoi.

Eoi is a very frequent hypercall which has only one argument passed through
a structure.  To avoid the xencomm overhead, a new hypercall is created
and the argument is passed by value.

Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>
---
 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h |   14 +++++-
 xen/arch/ia64/xen/hypercall.c                     |   51 ++++++++++++----------
 xen/include/asm-ia64/dom_fw.h                     |    7 +++
 xen/include/public/arch-ia64.h                    |    3 +
 4 files changed, 52 insertions(+), 23 deletions(-)

diff -r bacae4057790 -r c3f71a4ed653 
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Mon Oct 02 14:04:39 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Mon Oct 02 14:09:49 
2006 -0600
@@ -259,6 +259,18 @@ xencomm_arch_hypercall_hvm_op(int cmd, v
        return _hypercall2(unsigned long, hvm_op, cmd, arg);
 }
 
+static inline int
+HYPERVISOR_physdev_op(int cmd, void *arg)
+{
+       switch (cmd) {
+       case PHYSDEVOP_eoi:
+               return _hypercall1(int, ia64_fast_eoi,
+                                  ((struct physdev_eoi *)arg)->irq);
+       default:
+               return xencomm_hypercall_physdev_op(cmd, arg);
+       }
+}
+
 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
 static inline void exit_idle(void) {}
 #define do_IRQ(irq, regs) ({                   \
@@ -377,7 +389,6 @@ HYPERVISOR_add_physmap(unsigned long gpf
 #define HYPERVISOR_multicall xencomm_mini_hypercall_multicall
 #define HYPERVISOR_xen_version xencomm_mini_hypercall_xen_version
 #define HYPERVISOR_console_io xencomm_mini_hypercall_console_io
-#define HYPERVISOR_physdev_op xencomm_mini_hypercall_physdev_op
 #define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op
 #ifdef CONFIG_VMX_GUEST
 #define HYPERVISOR_memory_op 0
@@ -391,7 +402,6 @@ HYPERVISOR_add_physmap(unsigned long gpf
 #define HYPERVISOR_multicall xencomm_hypercall_multicall
 #define HYPERVISOR_xen_version xencomm_hypercall_xen_version
 #define HYPERVISOR_console_io xencomm_hypercall_console_io
-#define HYPERVISOR_physdev_op xencomm_hypercall_physdev_op
 #define HYPERVISOR_hvm_op xencomm_hypercall_hvm_op
 #define HYPERVISOR_memory_op xencomm_hypercall_memory_op
 #endif
diff -r bacae4057790 -r c3f71a4ed653 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Mon Oct 02 14:04:39 2006 -0600
+++ b/xen/arch/ia64/xen/hypercall.c     Mon Oct 02 14:09:49 2006 -0600
@@ -120,6 +120,20 @@ xen_hypercall (struct pt_regs *regs)
        } else
                regs->r8 = -ENOSYS;
        
+       return IA64_NO_FAULT;
+}
+
+static IA64FAULT
+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);
+               break;
+       default:
+               regs->r8 = -ENOSYS;
+       }
        return IA64_NO_FAULT;
 }
 
@@ -187,8 +201,8 @@ fw_hypercall_fpswa (struct vcpu *v)
        return PSCBX(v, fpswa_ret);
 }
 
-static IA64FAULT
-fw_hypercall (struct pt_regs *regs)
+IA64FAULT
+ia64_hypercall(struct pt_regs *regs)
 {
        struct vcpu *v = current;
        struct sal_ret_values x;
@@ -199,7 +213,13 @@ fw_hypercall (struct pt_regs *regs)
 
        perfc_incra(fw_hypercall, index >> 8);
        switch (index) {
-           case FW_HYPERCALL_PAL_CALL:
+       case FW_HYPERCALL_XEN:
+               return xen_hypercall(regs);
+
+       case FW_HYPERCALL_XEN_FAST:
+               return xen_fast_hypercall(regs);
+
+       case FW_HYPERCALL_PAL_CALL:
                //printf("*** PAL hypercall: index=%d\n",regs->r28);
                //FIXME: This should call a C routine
 #if 0
@@ -250,7 +270,7 @@ fw_hypercall (struct pt_regs *regs)
                        regs->r10 = y.v1; regs->r11 = y.v2;
                }
                break;
-           case FW_HYPERCALL_SAL_CALL:
+       case FW_HYPERCALL_SAL_CALL:
                x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
                        vcpu_get_gr(v,34),vcpu_get_gr(v,35),
                        vcpu_get_gr(v,36),vcpu_get_gr(v,37),
@@ -258,44 +278,33 @@ fw_hypercall (struct pt_regs *regs)
                regs->r8 = x.r8; regs->r9 = x.r9;
                regs->r10 = x.r10; regs->r11 = x.r11;
                break;
-           case FW_HYPERCALL_SAL_RETURN:
+       case FW_HYPERCALL_SAL_RETURN:
                if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
                        vcpu_sleep_nosync(v);
                break;
-           case FW_HYPERCALL_EFI_CALL:
+       case FW_HYPERCALL_EFI_CALL:
                efi_ret_value = efi_emulator (regs, &fault);
                if (fault != IA64_NO_FAULT) return fault;
                regs->r8 = efi_ret_value;
                break;
-           case FW_HYPERCALL_IPI:
+       case FW_HYPERCALL_IPI:
                fw_hypercall_ipi (regs);
                break;
-           case FW_HYPERCALL_SET_SHARED_INFO_VA:
+       case FW_HYPERCALL_SET_SHARED_INFO_VA:
                regs->r8 = domain_set_shared_info_va (regs->r28);
                break;
-           case FW_HYPERCALL_FPSWA:
+       case FW_HYPERCALL_FPSWA:
                fpswa_ret = fw_hypercall_fpswa (v);
                regs->r8  = fpswa_ret.status;
                regs->r9  = fpswa_ret.err0;
                regs->r10 = fpswa_ret.err1;
                regs->r11 = fpswa_ret.err2;
                break;
-           default:
+       default:
                printf("unknown ia64 fw hypercall %lx\n", regs->r2);
                regs->r8 = do_ni_hypercall();
        }
        return IA64_NO_FAULT;
-}
-
-IA64FAULT
-ia64_hypercall (struct pt_regs *regs)
-{
-       unsigned long index = regs->r2;
-
-       if (index >= FW_HYPERCALL_FIRST_ARCH)
-           return fw_hypercall (regs);
-       else
-           return xen_hypercall (regs);
 }
 
 unsigned long hypercall_create_continuation(
diff -r bacae4057790 -r c3f71a4ed653 xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h     Mon Oct 02 14:04:39 2006 -0600
+++ b/xen/include/asm-ia64/dom_fw.h     Mon Oct 02 14:09:49 2006 -0600
@@ -38,6 +38,13 @@
    The high part is the class (xen/pal/sal/efi).  */
 #define FW_HYPERCALL_NUM_MASK_HIGH     ~0xffUL
 #define FW_HYPERCALL_NUM_MASK_LOW       0xffUL
+
+/* Xen hypercalls are 0-63.  */
+#define FW_HYPERCALL_XEN               0x0000UL
+
+/* Define some faster and lighter hypercalls.
+   See definitions in arch-ia64.h */
+#define FW_HYPERCALL_XEN_FAST          0x0200UL
 
 /*
  * PAL can be called in physical or virtual mode simply by
diff -r bacae4057790 -r c3f71a4ed653 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Mon Oct 02 14:04:39 2006 -0600
+++ b/xen/include/public/arch-ia64.h    Mon Oct 02 14:09:49 2006 -0600
@@ -428,6 +428,9 @@ struct xen_ia64_boot_param {
 #define HYPERPRIVOP_GET_PSR            0x19
 #define HYPERPRIVOP_MAX                        0x19
 
+/* Fast and light hypercalls.  */
+#define __HYPERVISOR_ia64_fast_eoi     0x0200
+
 /* Xencomm macros.  */
 #define XENCOMM_INLINE_MASK 0xf800000000000000UL
 #define XENCOMM_INLINE_FLAG 0x8000000000000000UL

_______________________________________________
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®.