ia64/xen-unstable
changeset 5703:1d375ce8e0e0
Clean up Xen's event-channel interface, and semantics for binding
to VCPUs.
Signed-off-by: Keir Fraser <keir@xensource.com>
to VCPUs.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Fri Jul 08 14:17:54 2005 +0000 (2005-07-08) |
parents | 579d1e771025 |
children | 9b73afea874e 7c3d7c37dfde |
files | linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h xen/common/event_channel.c xen/include/public/dom0_ops.h xen/include/public/event_channel.h |
line diff
1.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Jul 08 12:24:58 2005 +0000 1.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Jul 08 14:17:54 2005 +0000 1.3 @@ -1533,13 +1533,13 @@ void __init smp_intr_init(void) 1.4 int cpu = smp_processor_id(); 1.5 1.6 per_cpu(resched_irq, cpu) = 1.7 - bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR); 1.8 + bind_ipi_to_irq(RESCHEDULE_VECTOR); 1.9 sprintf(resched_name[cpu], "resched%d", cpu); 1.10 BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, 1.11 SA_INTERRUPT, resched_name[cpu], NULL)); 1.12 1.13 per_cpu(callfunc_irq, cpu) = 1.14 - bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR); 1.15 + bind_ipi_to_irq(CALL_FUNCTION_VECTOR); 1.16 sprintf(callfunc_name[cpu], "callfunc%d", cpu); 1.17 BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), 1.18 smp_call_function_interrupt,
2.1 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Fri Jul 08 12:24:58 2005 +0000 2.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c Fri Jul 08 14:17:54 2005 +0000 2.3 @@ -236,17 +236,17 @@ void unbind_virq_from_irq(int virq) 2.4 spin_unlock(&irq_mapping_update_lock); 2.5 } 2.6 2.7 -int bind_ipi_on_cpu_to_irq(int cpu, int ipi) 2.8 +int bind_ipi_on_cpu_to_irq(int ipi) 2.9 { 2.10 evtchn_op_t op; 2.11 int evtchn, irq; 2.12 + int cpu = smp_processor_id(); 2.13 2.14 spin_lock(&irq_mapping_update_lock); 2.15 2.16 if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 ) 2.17 { 2.18 - op.cmd = EVTCHNOP_bind_ipi; 2.19 - op.u.bind_ipi.ipi_vcpu = cpu; 2.20 + op.cmd = EVTCHNOP_bind_ipi; 2.21 if ( HYPERVISOR_event_channel_op(&op) != 0 ) 2.22 panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu); 2.23 evtchn = op.u.bind_ipi.port; 2.24 @@ -278,9 +278,9 @@ void rebind_evtchn_from_ipi(int cpu, int 2.25 2.26 spin_lock(&irq_mapping_update_lock); 2.27 2.28 - op.cmd = EVTCHNOP_rebind; 2.29 - op.u.rebind.port = evtchn; 2.30 - op.u.rebind.vcpu = newcpu; 2.31 + op.cmd = EVTCHNOP_bind_vcpu; 2.32 + op.u.bind_vcpu.port = evtchn; 2.33 + op.u.bind_vcpu.vcpu = newcpu; 2.34 if ( HYPERVISOR_event_channel_op(&op) != 0 ) 2.35 printk(KERN_INFO "Failed to rebind IPI%d to CPU%d\n",ipi,newcpu); 2.36 2.37 @@ -294,18 +294,19 @@ void rebind_evtchn_from_irq(int cpu, int 2.38 2.39 spin_lock(&irq_mapping_update_lock); 2.40 2.41 - op.cmd = EVTCHNOP_rebind; 2.42 - op.u.rebind.port = evtchn; 2.43 - op.u.rebind.vcpu = newcpu; 2.44 + op.cmd = EVTCHNOP_bind_vcpu; 2.45 + op.u.bind_vcpu.port = evtchn; 2.46 + op.u.bind_vcpu.vcpu = newcpu; 2.47 if ( HYPERVISOR_event_channel_op(&op) != 0 ) 2.48 printk(KERN_INFO "Failed to rebind IRQ%d to CPU%d\n",irq,newcpu); 2.49 2.50 spin_unlock(&irq_mapping_update_lock); 2.51 } 2.52 2.53 -void unbind_ipi_on_cpu_from_irq(int cpu, int ipi) 2.54 +void unbind_ipi_from_irq(int ipi) 2.55 { 2.56 evtchn_op_t op; 2.57 + int cpu = smp_processor_id(); 2.58 int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; 2.59 int irq = irq_to_evtchn[evtchn]; 2.60
3.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Fri Jul 08 12:24:58 2005 +0000 3.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Fri Jul 08 14:17:54 2005 +0000 3.3 @@ -128,8 +128,8 @@ 3.4 /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ 3.5 extern int bind_virq_to_irq(int virq); 3.6 extern void unbind_virq_from_irq(int virq); 3.7 -extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi); 3.8 -extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi); 3.9 +extern int bind_ipi_to_irq(int ipi); 3.10 +extern void unbind_ipi_from_irq(int ipi); 3.11 extern int bind_evtchn_to_irq(int evtchn); 3.12 extern void unbind_evtchn_from_irq(int evtchn); 3.13
4.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Fri Jul 08 12:24:58 2005 +0000 4.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Fri Jul 08 14:17:54 2005 +0000 4.3 @@ -126,8 +126,8 @@ 4.4 /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ 4.5 extern int bind_virq_to_irq(int virq); 4.6 extern void unbind_virq_from_irq(int virq); 4.7 -extern int bind_ipi_on_cpu_to_irq(int cpu, int ipi); 4.8 -extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi); 4.9 +extern int bind_ipi_to_irq(int ipi); 4.10 +extern void unbind_ipi_from_irq(int ipi); 4.11 extern int bind_evtchn_to_irq(int evtchn); 4.12 extern void unbind_evtchn_from_irq(int evtchn); 4.13
5.1 --- a/xen/common/event_channel.c Fri Jul 08 12:24:58 2005 +0000 5.2 +++ b/xen/common/event_channel.c Fri Jul 08 14:17:54 2005 +0000 5.3 @@ -220,12 +220,10 @@ static long evtchn_bind_interdomain(evtc 5.4 5.5 chn1->u.interdomain.remote_dom = d2; 5.6 chn1->u.interdomain.remote_port = (u16)port2; 5.7 - chn1->notify_vcpu_id = 0; 5.8 chn1->state = ECS_INTERDOMAIN; 5.9 5.10 chn2->u.interdomain.remote_dom = d1; 5.11 chn2->u.interdomain.remote_port = (u16)port1; 5.12 - chn2->notify_vcpu_id = 0; 5.13 chn2->state = ECS_INTERDOMAIN; 5.14 5.15 out: 5.16 @@ -285,10 +283,7 @@ static long evtchn_bind_ipi(evtchn_bind_ 5.17 { 5.18 struct evtchn *chn; 5.19 struct domain *d = current->domain; 5.20 - int port, ipi_vcpu = bind->ipi_vcpu; 5.21 - 5.22 - if ( (ipi_vcpu >= MAX_VIRT_CPUS) || (d->vcpu[ipi_vcpu] == NULL) ) 5.23 - return -EINVAL; 5.24 + int port; 5.25 5.26 spin_lock(&d->evtchn_lock); 5.27 5.28 @@ -296,7 +291,7 @@ static long evtchn_bind_ipi(evtchn_bind_ 5.29 { 5.30 chn = evtchn_from_port(d, port); 5.31 chn->state = ECS_IPI; 5.32 - chn->notify_vcpu_id = ipi_vcpu; 5.33 + chn->notify_vcpu_id = current->vcpu_id; 5.34 } 5.35 5.36 spin_unlock(&d->evtchn_lock); 5.37 @@ -326,8 +321,6 @@ static long evtchn_bind_pirq(evtchn_bind 5.38 5.39 chn = evtchn_from_port(d, port); 5.40 5.41 - chn->notify_vcpu_id = 0; 5.42 - 5.43 d->pirq_to_evtchn[pirq] = port; 5.44 rc = pirq_guest_bind(d->vcpu[0], pirq, 5.45 !!(bind->flags & BIND_PIRQ__WILL_SHARE)); 5.46 @@ -441,7 +434,9 @@ static long __evtchn_close(struct domain 5.47 BUG(); 5.48 } 5.49 5.50 - chn1->state = ECS_FREE; 5.51 + /* Reset binding to vcpu0 when the channel is freed. */ 5.52 + chn1->state = ECS_FREE; 5.53 + chn1->notify_vcpu_id = 0; 5.54 5.55 out: 5.56 if ( d2 != NULL ) 5.57 @@ -570,26 +565,30 @@ static long evtchn_status(evtchn_status_ 5.58 status->u.virq = chn->u.virq; 5.59 break; 5.60 case ECS_IPI: 5.61 - status->status = EVTCHNSTAT_ipi; 5.62 - status->u.ipi_vcpu = chn->notify_vcpu_id; 5.63 + status->status = EVTCHNSTAT_ipi; 5.64 break; 5.65 default: 5.66 BUG(); 5.67 } 5.68 5.69 + status->vcpu = chn->notify_vcpu_id; 5.70 + 5.71 out: 5.72 spin_unlock(&d->evtchn_lock); 5.73 put_domain(d); 5.74 return rc; 5.75 } 5.76 5.77 -static long evtchn_rebind(evtchn_rebind_t *bind) 5.78 +static long evtchn_bind_vcpu(evtchn_bind_vcpu_t *bind) 5.79 { 5.80 struct domain *d = current->domain; 5.81 int port = bind->port; 5.82 int vcpu = bind->vcpu; 5.83 struct evtchn *chn; 5.84 - long rc = 0; 5.85 + long rc = 0; 5.86 + 5.87 + if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) ) 5.88 + return -EINVAL; 5.89 5.90 spin_lock(&d->evtchn_lock); 5.91 5.92 @@ -600,7 +599,17 @@ static long evtchn_rebind(evtchn_rebind_ 5.93 } 5.94 5.95 chn = evtchn_from_port(d, port); 5.96 - chn->notify_vcpu_id = vcpu; 5.97 + switch ( chn->state ) 5.98 + { 5.99 + case ECS_UNBOUND: 5.100 + case ECS_INTERDOMAIN: 5.101 + case ECS_PIRQ: 5.102 + chn->notify_vcpu_id = vcpu; 5.103 + break; 5.104 + default: 5.105 + rc = -EINVAL; 5.106 + break; 5.107 + } 5.108 5.109 out: 5.110 spin_unlock(&d->evtchn_lock); 5.111 @@ -664,10 +673,8 @@ long do_event_channel_op(evtchn_op_t *uo 5.112 rc = -EFAULT; 5.113 break; 5.114 5.115 - case EVTCHNOP_rebind: 5.116 - rc = evtchn_rebind(&op.u.rebind); 5.117 - if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) ) 5.118 - rc = -EFAULT; 5.119 + case EVTCHNOP_bind_vcpu: 5.120 + rc = evtchn_bind_vcpu(&op.u.bind_vcpu); 5.121 break; 5.122 5.123 default:
6.1 --- a/xen/include/public/dom0_ops.h Fri Jul 08 12:24:58 2005 +0000 6.2 +++ b/xen/include/public/dom0_ops.h Fri Jul 08 14:17:54 2005 +0000 6.3 @@ -19,7 +19,7 @@ 6.4 * This makes sure that old versions of dom0 tools will stop working in a 6.5 * well-defined way (rather than crashing the machine, for instance). 6.6 */ 6.7 -#define DOM0_INTERFACE_VERSION 0xAAAA100D 6.8 +#define DOM0_INTERFACE_VERSION 0xAAAA100E 6.9 6.10 /************************************************************************/ 6.11
7.1 --- a/xen/include/public/event_channel.h Fri Jul 08 12:24:58 2005 +0000 7.2 +++ b/xen/include/public/event_channel.h Fri Jul 08 14:17:54 2005 +0000 7.3 @@ -89,8 +89,6 @@ typedef struct evtchn_bind_pirq { 7.4 */ 7.5 #define EVTCHNOP_bind_ipi 7 7.6 typedef struct evtchn_bind_ipi { 7.7 - /* IN parameters. */ 7.8 - u32 ipi_vcpu; 7.9 /* OUT parameters. */ 7.10 u32 port; 7.11 } evtchn_bind_ipi_t; 7.12 @@ -144,6 +142,7 @@ typedef struct evtchn_status { 7.13 #define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ 7.14 #define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ 7.15 u32 status; 7.16 + u32 vcpu; /* VCPU to which this channel is bound. */ 7.17 union { 7.18 struct { 7.19 domid_t dom; 7.20 @@ -154,16 +153,25 @@ typedef struct evtchn_status { 7.21 } interdomain; /* EVTCHNSTAT_interdomain */ 7.22 u32 pirq; /* EVTCHNSTAT_pirq */ 7.23 u32 virq; /* EVTCHNSTAT_virq */ 7.24 - u32 ipi_vcpu; /* EVTCHNSTAT_ipi */ 7.25 } u; 7.26 } evtchn_status_t; 7.27 7.28 -#define EVTCHNOP_rebind 8 7.29 -typedef struct { 7.30 +/* 7.31 + * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an 7.32 + * event is pending. 7.33 + * NOTES: 7.34 + * 1. IPI- and VIRQ-bound channels always notify the vcpu that initialised 7.35 + * the binding. This binding cannot be changed. 7.36 + * 2. All other channels notify vcpu0 by default. This default is set when 7.37 + * the channel is allocated (a port that is freed and subsequently reused 7.38 + * has its binding reset to vcpu0). 7.39 + */ 7.40 +#define EVTCHNOP_bind_vcpu 8 7.41 +typedef struct evtchn_bind_vcpu { 7.42 /* IN parameters. */ 7.43 - u32 port; /* 0 */ 7.44 - u32 vcpu; /* 4 */ 7.45 -} evtchn_rebind_t; /* 8 bytes */ 7.46 + u32 port; 7.47 + u32 vcpu; 7.48 +} evtchn_bind_vcpu_t; 7.49 7.50 typedef struct evtchn_op { 7.51 u32 cmd; /* EVTCHNOP_* */ 7.52 @@ -176,7 +184,7 @@ typedef struct evtchn_op { 7.53 evtchn_close_t close; 7.54 evtchn_send_t send; 7.55 evtchn_status_t status; 7.56 - evtchn_rebind_t rebind; 7.57 + evtchn_bind_vcpu_t bind_vcpu; 7.58 } u; 7.59 } evtchn_op_t; 7.60