diff -r a8dcfc92f53c linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c --- a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c Mon Dec 04 15:40:32 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c Mon Dec 04 15:41:29 2006 +0900 @@ -197,6 +197,17 @@ int xen_assign_irq_vector(int irq) return irq_op.vector; } + +void xen_free_irq_vector(int vector) +{ + struct physdev_irq irq_op; + + irq_op.vector = vector; + if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op)) + printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n", __FUNCTION__, vector); + + return; +} #endif /* XEN */ /* diff -r a8dcfc92f53c linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c --- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c Mon Dec 04 15:40:32 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c Mon Dec 04 15:41:29 2006 +0900 @@ -94,6 +94,13 @@ free_irq_vector (int vector) if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR) return; +#ifdef CONFIG_XEN + if (is_running_on_xen()) { + extern void xen_free_irq_vector(int); + xen_free_irq_vector(vector); + return; + } +#endif pos = vector - IA64_FIRST_DEVICE_VECTOR; if (!test_and_clear_bit(pos, ia64_vector_mask)) printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); diff -r a8dcfc92f53c xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c Mon Dec 04 15:40:32 2006 +0900 +++ b/xen/arch/ia64/xen/hypercall.c Mon Dec 04 15:41:29 2006 +0900 @@ -372,6 +372,7 @@ static long do_physdev_op(int cmd, XEN_G static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) { int irq; + int vector; long ret; switch ( cmd ) @@ -454,6 +455,27 @@ static long do_physdev_op(int cmd, XEN_G break; } + case PHYSDEVOP_free_irq_vector: { + struct physdev_irq irq_op; + + ret = -EFAULT; + if ( copy_from_guest(&irq_op, arg, 1) != 0 ) + break; + + ret = -EPERM; + if ( !IS_PRIV(current->domain) ) + break; + + ret = -EINVAL; + vector = irq_op.vector; + if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR) + break; + + free_irq_vector(vector); + ret = 0; + break; + } + default: ret = -ENOSYS; break; diff -r a8dcfc92f53c xen/include/public/physdev.h --- a/xen/include/public/physdev.h Mon Dec 04 15:40:32 2006 +0900 +++ b/xen/include/public/physdev.h Mon Dec 04 15:41:29 2006 +0900 @@ -152,6 +152,7 @@ DEFINE_XEN_GUEST_HANDLE(physdev_op_t); #define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read #define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write #define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector +#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector #define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi #define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared