# HG changeset patch # User gingold@virtu10 # Node ID 780e422b936818fbc91a458f1e7632d2ded48332 # Parent ae93d70e8df7247494b580043db156d4d298fd36 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 diff -r ae93d70e8df7 -r 780e422b9368 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Sep 28 10:39:00 2006 +0200 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Sep 28 11:06:30 2006 +0200 @@ -259,6 +259,19 @@ 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 +390,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 +403,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 ae93d70e8df7 -r 780e422b9368 xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c Thu Sep 28 10:39:00 2006 +0200 +++ b/xen/arch/ia64/xen/hypercall.c Thu Sep 28 11:06:30 2006 +0200 @@ -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,6 +213,12 @@ fw_hypercall (struct pt_regs *regs) perfc_incra(fw_hypercall, index >> 8); switch (index) { + 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 @@ -287,17 +307,6 @@ fw_hypercall (struct pt_regs *regs) 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( unsigned int op, const char *format, ...) { diff -r ae93d70e8df7 -r 780e422b9368 xen/include/asm-ia64/dom_fw.h --- a/xen/include/asm-ia64/dom_fw.h Thu Sep 28 10:39:00 2006 +0200 +++ b/xen/include/asm-ia64/dom_fw.h Thu Sep 28 11:06:30 2006 +0200 @@ -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 ae93d70e8df7 -r 780e422b9368 xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Thu Sep 28 10:39:00 2006 +0200 +++ b/xen/include/public/arch-ia64.h Thu Sep 28 11:06:30 2006 +0200 @@ -432,6 +432,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