# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1d375ce8e0e04871782b94408e8b8fe3d399cdd6
# Parent 579d1e771025f8eb36ae537650499dd9a6b66e7b
Clean up Xen's event-channel interface, and semantics for binding
to VCPUs.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 579d1e771025 -r 1d375ce8e0e0
linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
Fri Jul 8 12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
Fri Jul 8 14:17:54 2005
@@ -126,8 +126,8 @@
/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
extern int bind_virq_to_irq(int virq);
extern void unbind_virq_from_irq(int virq);
-extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi);
-extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi);
+extern int bind_ipi_to_irq(int ipi);
+extern void unbind_ipi_from_irq(int ipi);
extern int bind_evtchn_to_irq(int evtchn);
extern void unbind_evtchn_from_irq(int evtchn);
diff -r 579d1e771025 -r 1d375ce8e0e0 xen/common/event_channel.c
--- a/xen/common/event_channel.c Fri Jul 8 12:24:58 2005
+++ b/xen/common/event_channel.c Fri Jul 8 14:17:54 2005
@@ -220,12 +220,10 @@
chn1->u.interdomain.remote_dom = d2;
chn1->u.interdomain.remote_port = (u16)port2;
- chn1->notify_vcpu_id = 0;
chn1->state = ECS_INTERDOMAIN;
chn2->u.interdomain.remote_dom = d1;
chn2->u.interdomain.remote_port = (u16)port1;
- chn2->notify_vcpu_id = 0;
chn2->state = ECS_INTERDOMAIN;
out:
@@ -285,10 +283,7 @@
{
struct evtchn *chn;
struct domain *d = current->domain;
- int port, ipi_vcpu = bind->ipi_vcpu;
-
- if ( (ipi_vcpu >= MAX_VIRT_CPUS) || (d->vcpu[ipi_vcpu] == NULL) )
- return -EINVAL;
+ int port;
spin_lock(&d->evtchn_lock);
@@ -296,7 +291,7 @@
{
chn = evtchn_from_port(d, port);
chn->state = ECS_IPI;
- chn->notify_vcpu_id = ipi_vcpu;
+ chn->notify_vcpu_id = current->vcpu_id;
}
spin_unlock(&d->evtchn_lock);
@@ -325,8 +320,6 @@
goto out;
chn = evtchn_from_port(d, port);
-
- chn->notify_vcpu_id = 0;
d->pirq_to_evtchn[pirq] = port;
rc = pirq_guest_bind(d->vcpu[0], pirq,
@@ -441,7 +434,9 @@
BUG();
}
- chn1->state = ECS_FREE;
+ /* Reset binding to vcpu0 when the channel is freed. */
+ chn1->state = ECS_FREE;
+ chn1->notify_vcpu_id = 0;
out:
if ( d2 != NULL )
@@ -570,12 +565,13 @@
status->u.virq = chn->u.virq;
break;
case ECS_IPI:
- status->status = EVTCHNSTAT_ipi;
- status->u.ipi_vcpu = chn->notify_vcpu_id;
+ status->status = EVTCHNSTAT_ipi;
break;
default:
BUG();
}
+
+ status->vcpu = chn->notify_vcpu_id;
out:
spin_unlock(&d->evtchn_lock);
@@ -583,13 +579,16 @@
return rc;
}
-static long evtchn_rebind(evtchn_rebind_t *bind)
+static long evtchn_bind_vcpu(evtchn_bind_vcpu_t *bind)
{
struct domain *d = current->domain;
int port = bind->port;
int vcpu = bind->vcpu;
struct evtchn *chn;
- long rc = 0;
+ long rc = 0;
+
+ if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) )
+ return -EINVAL;
spin_lock(&d->evtchn_lock);
@@ -600,7 +599,17 @@
}
chn = evtchn_from_port(d, port);
- chn->notify_vcpu_id = vcpu;
+ switch ( chn->state )
+ {
+ case ECS_UNBOUND:
+ case ECS_INTERDOMAIN:
+ case ECS_PIRQ:
+ chn->notify_vcpu_id = vcpu;
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
out:
spin_unlock(&d->evtchn_lock);
@@ -664,10 +673,8 @@
rc = -EFAULT;
break;
- case EVTCHNOP_rebind:
- rc = evtchn_rebind(&op.u.rebind);
- if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
- rc = -EFAULT;
+ case EVTCHNOP_bind_vcpu:
+ rc = evtchn_bind_vcpu(&op.u.bind_vcpu);
break;
default:
diff -r 579d1e771025 -r 1d375ce8e0e0
linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Fri Jul 8 12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Fri Jul 8 14:17:54 2005
@@ -236,17 +236,17 @@
spin_unlock(&irq_mapping_update_lock);
}
-int bind_ipi_on_cpu_to_irq(int cpu, int ipi)
+int bind_ipi_on_cpu_to_irq(int ipi)
{
evtchn_op_t op;
int evtchn, irq;
+ int cpu = smp_processor_id();
spin_lock(&irq_mapping_update_lock);
if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 )
{
- op.cmd = EVTCHNOP_bind_ipi;
- op.u.bind_ipi.ipi_vcpu = cpu;
+ op.cmd = EVTCHNOP_bind_ipi;
if ( HYPERVISOR_event_channel_op(&op) != 0 )
panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu);
evtchn = op.u.bind_ipi.port;
@@ -278,9 +278,9 @@
spin_lock(&irq_mapping_update_lock);
- op.cmd = EVTCHNOP_rebind;
- op.u.rebind.port = evtchn;
- op.u.rebind.vcpu = newcpu;
+ op.cmd = EVTCHNOP_bind_vcpu;
+ op.u.bind_vcpu.port = evtchn;
+ op.u.bind_vcpu.vcpu = newcpu;
if ( HYPERVISOR_event_channel_op(&op) != 0 )
printk(KERN_INFO "Failed to rebind IPI%d to CPU%d\n",ipi,newcpu);
@@ -294,18 +294,19 @@
spin_lock(&irq_mapping_update_lock);
- op.cmd = EVTCHNOP_rebind;
- op.u.rebind.port = evtchn;
- op.u.rebind.vcpu = newcpu;
+ op.cmd = EVTCHNOP_bind_vcpu;
+ op.u.bind_vcpu.port = evtchn;
+ op.u.bind_vcpu.vcpu = newcpu;
if ( HYPERVISOR_event_channel_op(&op) != 0 )
printk(KERN_INFO "Failed to rebind IRQ%d to CPU%d\n",irq,newcpu);
spin_unlock(&irq_mapping_update_lock);
}
-void unbind_ipi_on_cpu_from_irq(int cpu, int ipi)
-{
- evtchn_op_t op;
+void unbind_ipi_from_irq(int ipi)
+{
+ evtchn_op_t op;
+ int cpu = smp_processor_id();
int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
int irq = irq_to_evtchn[evtchn];
diff -r 579d1e771025 -r 1d375ce8e0e0 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h Fri Jul 8 12:24:58 2005
+++ b/xen/include/public/dom0_ops.h Fri Jul 8 14:17:54 2005
@@ -19,7 +19,7 @@
* This makes sure that old versions of dom0 tools will stop working in a
* well-defined way (rather than crashing the machine, for instance).
*/
-#define DOM0_INTERFACE_VERSION 0xAAAA100D
+#define DOM0_INTERFACE_VERSION 0xAAAA100E
/************************************************************************/
diff -r 579d1e771025 -r 1d375ce8e0e0 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h Fri Jul 8 12:24:58 2005
+++ b/xen/include/public/event_channel.h Fri Jul 8 14:17:54 2005
@@ -89,8 +89,6 @@
*/
#define EVTCHNOP_bind_ipi 7
typedef struct evtchn_bind_ipi {
- /* IN parameters. */
- u32 ipi_vcpu;
/* OUT parameters. */
u32 port;
} evtchn_bind_ipi_t;
@@ -144,6 +142,7 @@
#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */
#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */
u32 status;
+ u32 vcpu; /* VCPU to which this channel is bound. */
union {
struct {
domid_t dom;
@@ -154,16 +153,25 @@
} interdomain; /* EVTCHNSTAT_interdomain */
u32 pirq; /* EVTCHNSTAT_pirq */
u32 virq; /* EVTCHNSTAT_virq */
- u32 ipi_vcpu; /* EVTCHNSTAT_ipi */
} u;
} evtchn_status_t;
-#define EVTCHNOP_rebind 8
-typedef struct {
+/*
+ * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
+ * event is pending.
+ * NOTES:
+ * 1. IPI- and VIRQ-bound channels always notify the vcpu that initialised
+ * the binding. This binding cannot be changed.
+ * 2. All other channels notify vcpu0 by default. This default is set when
+ * the channel is allocated (a port that is freed and subsequently reused
+ * has its binding reset to vcpu0).
+ */
+#define EVTCHNOP_bind_vcpu 8
+typedef struct evtchn_bind_vcpu {
/* IN parameters. */
- u32 port; /* 0 */
- u32 vcpu; /* 4 */
-} evtchn_rebind_t; /* 8 bytes */
+ u32 port;
+ u32 vcpu;
+} evtchn_bind_vcpu_t;
typedef struct evtchn_op {
u32 cmd; /* EVTCHNOP_* */
@@ -176,7 +184,7 @@
evtchn_close_t close;
evtchn_send_t send;
evtchn_status_t status;
- evtchn_rebind_t rebind;
+ evtchn_bind_vcpu_t bind_vcpu;
} u;
} evtchn_op_t;
diff -r 579d1e771025 -r 1d375ce8e0e0
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
Fri Jul 8 12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
Fri Jul 8 14:17:54 2005
@@ -128,8 +128,8 @@
/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
extern int bind_virq_to_irq(int virq);
extern void unbind_virq_from_irq(int virq);
-extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi);
-extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi);
+extern int bind_ipi_to_irq(int ipi);
+extern void unbind_ipi_from_irq(int ipi);
extern int bind_evtchn_to_irq(int evtchn);
extern void unbind_evtchn_from_irq(int evtchn);
diff -r 579d1e771025 -r 1d375ce8e0e0
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Jul 8
12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Jul 8
14:17:54 2005
@@ -1533,13 +1533,13 @@
int cpu = smp_processor_id();
per_cpu(resched_irq, cpu) =
- bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR);
+ bind_ipi_to_irq(RESCHEDULE_VECTOR);
sprintf(resched_name[cpu], "resched%d", cpu);
BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
SA_INTERRUPT, resched_name[cpu], NULL));
per_cpu(callfunc_irq, cpu) =
- bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR);
+ bind_ipi_to_irq(CALL_FUNCTION_VECTOR);
sprintf(callfunc_name[cpu], "callfunc%d", cpu);
BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
smp_call_function_interrupt,
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|