# 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
|