direct-io.hg

changeset 11945:c3f71a4ed653

[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@bull.net>
author awilliam@xenbuild.aw
date Mon Oct 02 14:09:49 2006 -0600 (2006-10-02)
parents bacae4057790
children 6268aa7b9177
files linux-2.6-xen-sparse/include/asm-ia64/hypercall.h xen/arch/ia64/xen/hypercall.c xen/include/asm-ia64/dom_fw.h xen/include/public/arch-ia64.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon Oct 02 14:04:39 2006 -0600
     1.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon Oct 02 14:09:49 2006 -0600
     1.3 @@ -259,6 +259,18 @@ xencomm_arch_hypercall_hvm_op(int cmd, v
     1.4  	return _hypercall2(unsigned long, hvm_op, cmd, arg);
     1.5  }
     1.6  
     1.7 +static inline int
     1.8 +HYPERVISOR_physdev_op(int cmd, void *arg)
     1.9 +{
    1.10 +	switch (cmd) {
    1.11 +	case PHYSDEVOP_eoi:
    1.12 +		return _hypercall1(int, ia64_fast_eoi,
    1.13 +		                   ((struct physdev_eoi *)arg)->irq);
    1.14 +	default:
    1.15 +		return xencomm_hypercall_physdev_op(cmd, arg);
    1.16 +	}
    1.17 +}
    1.18 +
    1.19  extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
    1.20  static inline void exit_idle(void) {}
    1.21  #define do_IRQ(irq, regs) ({			\
    1.22 @@ -377,7 +389,6 @@ HYPERVISOR_add_physmap(unsigned long gpf
    1.23  #define HYPERVISOR_multicall xencomm_mini_hypercall_multicall
    1.24  #define HYPERVISOR_xen_version xencomm_mini_hypercall_xen_version
    1.25  #define HYPERVISOR_console_io xencomm_mini_hypercall_console_io
    1.26 -#define HYPERVISOR_physdev_op xencomm_mini_hypercall_physdev_op
    1.27  #define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op
    1.28  #ifdef CONFIG_VMX_GUEST
    1.29  #define HYPERVISOR_memory_op 0
    1.30 @@ -391,7 +402,6 @@ HYPERVISOR_add_physmap(unsigned long gpf
    1.31  #define HYPERVISOR_multicall xencomm_hypercall_multicall
    1.32  #define HYPERVISOR_xen_version xencomm_hypercall_xen_version
    1.33  #define HYPERVISOR_console_io xencomm_hypercall_console_io
    1.34 -#define HYPERVISOR_physdev_op xencomm_hypercall_physdev_op
    1.35  #define HYPERVISOR_hvm_op xencomm_hypercall_hvm_op
    1.36  #define HYPERVISOR_memory_op xencomm_hypercall_memory_op
    1.37  #endif
     2.1 --- a/xen/arch/ia64/xen/hypercall.c	Mon Oct 02 14:04:39 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/hypercall.c	Mon Oct 02 14:09:49 2006 -0600
     2.3 @@ -123,6 +123,20 @@ xen_hypercall (struct pt_regs *regs)
     2.4  	return IA64_NO_FAULT;
     2.5  }
     2.6  
     2.7 +static IA64FAULT
     2.8 +xen_fast_hypercall (struct pt_regs *regs)
     2.9 +{
    2.10 +	uint32_t cmd = (uint32_t)regs->r2;
    2.11 +	switch (cmd) {
    2.12 +	case __HYPERVISOR_ia64_fast_eoi:
    2.13 +		regs->r8 = pirq_guest_eoi(current->domain, regs->r14);
    2.14 +		break;
    2.15 +	default:
    2.16 +		regs->r8 = -ENOSYS;
    2.17 +	}
    2.18 +	return IA64_NO_FAULT;
    2.19 +}
    2.20 +
    2.21  static void
    2.22  fw_hypercall_ipi (struct pt_regs *regs)
    2.23  {
    2.24 @@ -187,8 +201,8 @@ fw_hypercall_fpswa (struct vcpu *v)
    2.25  	return PSCBX(v, fpswa_ret);
    2.26  }
    2.27  
    2.28 -static IA64FAULT
    2.29 -fw_hypercall (struct pt_regs *regs)
    2.30 +IA64FAULT
    2.31 +ia64_hypercall(struct pt_regs *regs)
    2.32  {
    2.33  	struct vcpu *v = current;
    2.34  	struct sal_ret_values x;
    2.35 @@ -199,7 +213,13 @@ fw_hypercall (struct pt_regs *regs)
    2.36  
    2.37  	perfc_incra(fw_hypercall, index >> 8);
    2.38  	switch (index) {
    2.39 -	    case FW_HYPERCALL_PAL_CALL:
    2.40 +	case FW_HYPERCALL_XEN:
    2.41 +		return xen_hypercall(regs);
    2.42 +
    2.43 +	case FW_HYPERCALL_XEN_FAST:
    2.44 +		return xen_fast_hypercall(regs);
    2.45 +
    2.46 +	case FW_HYPERCALL_PAL_CALL:
    2.47  		//printf("*** PAL hypercall: index=%d\n",regs->r28);
    2.48  		//FIXME: This should call a C routine
    2.49  #if 0
    2.50 @@ -250,7 +270,7 @@ fw_hypercall (struct pt_regs *regs)
    2.51  			regs->r10 = y.v1; regs->r11 = y.v2;
    2.52  		}
    2.53  		break;
    2.54 -	    case FW_HYPERCALL_SAL_CALL:
    2.55 +	case FW_HYPERCALL_SAL_CALL:
    2.56  		x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
    2.57  			vcpu_get_gr(v,34),vcpu_get_gr(v,35),
    2.58  			vcpu_get_gr(v,36),vcpu_get_gr(v,37),
    2.59 @@ -258,46 +278,35 @@ fw_hypercall (struct pt_regs *regs)
    2.60  		regs->r8 = x.r8; regs->r9 = x.r9;
    2.61  		regs->r10 = x.r10; regs->r11 = x.r11;
    2.62  		break;
    2.63 - 	    case FW_HYPERCALL_SAL_RETURN:
    2.64 +	case FW_HYPERCALL_SAL_RETURN:
    2.65  	        if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
    2.66  			vcpu_sleep_nosync(v);
    2.67  		break;
    2.68 -	    case FW_HYPERCALL_EFI_CALL:
    2.69 +	case FW_HYPERCALL_EFI_CALL:
    2.70  		efi_ret_value = efi_emulator (regs, &fault);
    2.71  		if (fault != IA64_NO_FAULT) return fault;
    2.72  		regs->r8 = efi_ret_value;
    2.73  		break;
    2.74 -	    case FW_HYPERCALL_IPI:
    2.75 +	case FW_HYPERCALL_IPI:
    2.76  		fw_hypercall_ipi (regs);
    2.77  		break;
    2.78 -	    case FW_HYPERCALL_SET_SHARED_INFO_VA:
    2.79 +	case FW_HYPERCALL_SET_SHARED_INFO_VA:
    2.80  	        regs->r8 = domain_set_shared_info_va (regs->r28);
    2.81  		break;
    2.82 -	    case FW_HYPERCALL_FPSWA:
    2.83 +	case FW_HYPERCALL_FPSWA:
    2.84  		fpswa_ret = fw_hypercall_fpswa (v);
    2.85  		regs->r8  = fpswa_ret.status;
    2.86  		regs->r9  = fpswa_ret.err0;
    2.87  		regs->r10 = fpswa_ret.err1;
    2.88  		regs->r11 = fpswa_ret.err2;
    2.89  		break;
    2.90 -	    default:
    2.91 +	default:
    2.92  		printf("unknown ia64 fw hypercall %lx\n", regs->r2);
    2.93  		regs->r8 = do_ni_hypercall();
    2.94  	}
    2.95  	return IA64_NO_FAULT;
    2.96  }
    2.97  
    2.98 -IA64FAULT
    2.99 -ia64_hypercall (struct pt_regs *regs)
   2.100 -{
   2.101 -	unsigned long index = regs->r2;
   2.102 -
   2.103 -	if (index >= FW_HYPERCALL_FIRST_ARCH)
   2.104 -	    return fw_hypercall (regs);
   2.105 -	else
   2.106 -	    return xen_hypercall (regs);
   2.107 -}
   2.108 -
   2.109  unsigned long hypercall_create_continuation(
   2.110  	unsigned int op, const char *format, ...)
   2.111  {
     3.1 --- a/xen/include/asm-ia64/dom_fw.h	Mon Oct 02 14:04:39 2006 -0600
     3.2 +++ b/xen/include/asm-ia64/dom_fw.h	Mon Oct 02 14:09:49 2006 -0600
     3.3 @@ -39,6 +39,13 @@
     3.4  #define FW_HYPERCALL_NUM_MASK_HIGH	~0xffUL
     3.5  #define FW_HYPERCALL_NUM_MASK_LOW	 0xffUL
     3.6  
     3.7 +/* Xen hypercalls are 0-63.  */
     3.8 +#define FW_HYPERCALL_XEN		0x0000UL
     3.9 +
    3.10 +/* Define some faster and lighter hypercalls.
    3.11 +   See definitions in arch-ia64.h */
    3.12 +#define FW_HYPERCALL_XEN_FAST		0x0200UL
    3.13 +
    3.14  /*
    3.15   * PAL can be called in physical or virtual mode simply by
    3.16   * branching to pal_entry_point, which is found in one of the
     4.1 --- a/xen/include/public/arch-ia64.h	Mon Oct 02 14:04:39 2006 -0600
     4.2 +++ b/xen/include/public/arch-ia64.h	Mon Oct 02 14:09:49 2006 -0600
     4.3 @@ -428,6 +428,9 @@ struct xen_ia64_boot_param {
     4.4  #define HYPERPRIVOP_GET_PSR		0x19
     4.5  #define HYPERPRIVOP_MAX			0x19
     4.6  
     4.7 +/* Fast and light hypercalls.  */
     4.8 +#define __HYPERVISOR_ia64_fast_eoi	0x0200
     4.9 +
    4.10  /* Xencomm macros.  */
    4.11  #define XENCOMM_INLINE_MASK 0xf800000000000000UL
    4.12  #define XENCOMM_INLINE_FLAG 0x8000000000000000UL