ia64/xen-unstable

changeset 7127:805ee053e61f

VIRQs and IPIs on VCPU#0 are automatically re-bound on save/restore.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Sep 29 13:05:43 2005 +0100 (2005-09-29)
parents c317e0aca9f1
children 559ad1abb3d5
files linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h linux-2.6-xen-sparse/include/asm-xen/evtchn.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c	Thu Sep 29 11:10:27 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c	Thu Sep 29 13:05:43 2005 +0100
     1.3 @@ -131,21 +131,9 @@ DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IP
     1.4  
     1.5  static inline void __send_IPI_one(unsigned int cpu, int vector)
     1.6  {
     1.7 -	unsigned int evtchn;
     1.8 -
     1.9 -	evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
    1.10 -	// printk("send_IPI_mask_bitmask cpu %d vector %d evtchn %d\n", cpu, vector, evtchn);
    1.11 -	if (evtchn) {
    1.12 -#if 0
    1.13 -		shared_info_t *s = HYPERVISOR_shared_info;
    1.14 -		while (synch_test_bit(evtchn, &s->evtchn_pending[0]) ||
    1.15 -		       synch_test_bit(evtchn, &s->evtchn_mask[0]))
    1.16 -			;
    1.17 -#endif
    1.18 -		notify_via_evtchn(evtchn);
    1.19 -	} else
    1.20 -		printk("send_IPI to unbound port %d/%d",
    1.21 -		       cpu, vector);
    1.22 +	int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
    1.23 +	BUG_ON(evtchn < 0);
    1.24 +	notify_via_evtchn(evtchn);
    1.25  }
    1.26  
    1.27  void __send_IPI_shortcut(unsigned int shortcut, int vector)
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Thu Sep 29 11:10:27 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Thu Sep 29 13:05:43 2005 +0100
     2.3 @@ -836,13 +836,6 @@ void start_hz_timer(void)
     2.4  	cpu_clear(smp_processor_id(), nohz_cpu_mask);
     2.5  }
     2.6  
     2.7 -void time_suspend(void)
     2.8 -{
     2.9 -	/* nothing */
    2.10 -	teardown_irq(per_cpu(timer_irq, 0), &irq_timer);
    2.11 -	unbind_virq_from_irq(VIRQ_TIMER);
    2.12 -}
    2.13 -
    2.14  /* No locking required. We are only CPU running, and interrupts are off. */
    2.15  void time_resume(void)
    2.16  {
    2.17 @@ -854,9 +847,6 @@ void time_resume(void)
    2.18  	per_cpu(processed_system_time, 0) = processed_system_time;
    2.19  
    2.20  	update_wallclock();
    2.21 -
    2.22 -	per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
    2.23 -	(void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
    2.24  }
    2.25  
    2.26  #ifdef CONFIG_SMP
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Thu Sep 29 11:10:27 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Thu Sep 29 13:05:43 2005 +0100
     3.3 @@ -78,22 +78,28 @@ static u32 cpu_evtchn_mask[NR_CPUS][NR_E
     3.4  	 cpu_evtchn_mask[cpu][idx] &		\
     3.5  	 ~(sh)->evtchn_mask[idx])
     3.6  
     3.7 -void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
     3.8 +static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
     3.9  {
    3.10  	clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
    3.11  	set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
    3.12  	cpu_evtchn[chn] = cpu;
    3.13  }
    3.14  
    3.15 +static void init_evtchn_cpu_bindings(void)
    3.16 +{
    3.17 +	/* By default all event channels notify CPU#0. */
    3.18 +	memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
    3.19 +	memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
    3.20 +}
    3.21 +
    3.22  #else
    3.23  
    3.24  #define active_evtchns(cpu,sh,idx)		\
    3.25  	((sh)->evtchn_pending[idx] &		\
    3.26  	 ~(sh)->evtchn_mask[idx])
    3.27 +#define bind_evtchn_to_cpu(chn,cpu)	((void)0)
    3.28 +#define init_evtchn_cpu_bindings()	((void)0)
    3.29  
    3.30 -void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
    3.31 -{
    3.32 -}
    3.33  #endif
    3.34  
    3.35  /* Upcall to generic IRQ layer. */
    3.36 @@ -244,7 +250,7 @@ int bind_ipi_to_irq(int ipi)
    3.37  
    3.38  	spin_lock(&irq_mapping_update_lock);
    3.39  
    3.40 -	if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0) {
    3.41 +	if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
    3.42  		op.cmd = EVTCHNOP_bind_ipi;
    3.43  		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
    3.44  		evtchn = op.u.bind_ipi.port;
    3.45 @@ -287,7 +293,7 @@ void unbind_ipi_from_irq(int ipi)
    3.46  		bind_evtchn_to_cpu(evtchn, 0);
    3.47  		evtchn_to_irq[evtchn] = -1;
    3.48  		irq_to_evtchn[irq]    = -1;
    3.49 -		per_cpu(ipi_to_evtchn, cpu)[ipi] = 0;
    3.50 +		per_cpu(ipi_to_evtchn, cpu)[ipi] = -1;
    3.51  	}
    3.52  
    3.53  	spin_unlock(&irq_mapping_update_lock);
    3.54 @@ -608,41 +614,32 @@ void hw_resend_irq(struct hw_interrupt_t
    3.55  	synch_set_bit(evtchn, &s->evtchn_pending[0]);
    3.56  }
    3.57  
    3.58 -void irq_suspend(void)
    3.59 -{
    3.60 -	int pirq, virq, irq, evtchn;
    3.61 -	int cpu = smp_processor_id(); /* XXX */
    3.62 -
    3.63 -	/* Unbind VIRQs from event channels. */
    3.64 -	for (virq = 0; virq < NR_VIRQS; virq++) {
    3.65 -		if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
    3.66 -			continue;
    3.67 -		evtchn = irq_to_evtchn[irq];
    3.68 -
    3.69 -		/* Mark the event channel as unused in our table. */
    3.70 -		evtchn_to_irq[evtchn] = -1;
    3.71 -		irq_to_evtchn[irq]    = -1;
    3.72 -	}
    3.73 -
    3.74 -	/* Check that no PIRQs are still bound. */
    3.75 -	for (pirq = 0; pirq < NR_PIRQS; pirq++)
    3.76 -		if ((evtchn = irq_to_evtchn[pirq_to_irq(pirq)]) != -1)
    3.77 -			panic("Suspend attempted while PIRQ %d bound "
    3.78 -			      "to evtchn %d.\n", pirq, evtchn);
    3.79 -}
    3.80 -
    3.81  void irq_resume(void)
    3.82  {
    3.83  	evtchn_op_t op;
    3.84 -	int         virq, irq, evtchn;
    3.85 -	int cpu = smp_processor_id(); /* XXX */
    3.86 +	int         cpu, pirq, virq, ipi, irq, evtchn;
    3.87 +
    3.88 +	init_evtchn_cpu_bindings();
    3.89  
    3.90  	/* New event-channel space is not 'live' yet. */
    3.91  	for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
    3.92  		mask_evtchn(evtchn);
    3.93  
    3.94 +	/* Check that no PIRQs are still bound. */
    3.95 +	for (pirq = 0; pirq < NR_PIRQS; pirq++)
    3.96 +		BUG_ON(irq_to_evtchn[pirq_to_irq(pirq)] != -1);
    3.97 +
    3.98 +	/* Secondary CPUs must have no VIRQ or IPI bindings. */
    3.99 +	for (cpu = 1; cpu < NR_CPUS; cpu++) {
   3.100 +		for (virq = 0; virq < NR_VIRQS; virq++)
   3.101 +			BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
   3.102 +		for (ipi = 0; ipi < NR_IPIS; ipi++)
   3.103 +			BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
   3.104 +	}
   3.105 +
   3.106 +	/* Primary CPU: rebind VIRQs automatically. */
   3.107  	for (virq = 0; virq < NR_VIRQS; virq++) {
   3.108 -		if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
   3.109 +		if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
   3.110  			continue;
   3.111  
   3.112  		/* Get a new binding from Xen. */
   3.113 @@ -652,7 +649,27 @@ void irq_resume(void)
   3.114  		evtchn = op.u.bind_virq.port;
   3.115          
   3.116  		/* Record the new mapping. */
   3.117 -		bind_evtchn_to_cpu(evtchn, 0);
   3.118 +		evtchn_to_irq[evtchn] = irq;
   3.119 +		irq_to_evtchn[irq]    = evtchn;
   3.120 +
   3.121 +		/* Ready for use. */
   3.122 +		unmask_evtchn(evtchn);
   3.123 +	}
   3.124 +
   3.125 +	/* Primary CPU: rebind IPIs automatically. */
   3.126 +	for (ipi = 0; ipi < NR_IPIS; ipi++) {
   3.127 +		if ((evtchn = per_cpu(ipi_to_evtchn, 0)[ipi]) == -1)
   3.128 +			continue;
   3.129 +
   3.130 +		irq = evtchn_to_irq[evtchn];
   3.131 +		evtchn_to_irq[evtchn] = -1;
   3.132 +
   3.133 +		/* Get a new binding from Xen. */
   3.134 +		op.cmd = EVTCHNOP_bind_ipi;
   3.135 +		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
   3.136 +		evtchn = op.u.bind_ipi.port;
   3.137 +        
   3.138 +		/* Record the new mapping. */
   3.139  		evtchn_to_irq[evtchn] = irq;
   3.140  		irq_to_evtchn[irq]    = evtchn;
   3.141  
   3.142 @@ -670,15 +687,15 @@ void __init init_IRQ(void)
   3.143  
   3.144  	spin_lock_init(&irq_mapping_update_lock);
   3.145  
   3.146 -#ifdef CONFIG_SMP
   3.147 -	/* By default all event channels notify CPU#0. */
   3.148 -	memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
   3.149 -#endif
   3.150 +	init_evtchn_cpu_bindings();
   3.151  
   3.152  	for (cpu = 0; cpu < NR_CPUS; cpu++) {
   3.153  		/* No VIRQ -> IRQ mappings. */
   3.154  		for (i = 0; i < NR_VIRQS; i++)
   3.155  			per_cpu(virq_to_irq, cpu)[i] = -1;
   3.156 +		/* No VIRQ -> IRQ mappings. */
   3.157 +		for (i = 0; i < NR_IPIS; i++)
   3.158 +			per_cpu(ipi_to_evtchn, cpu)[i] = -1;
   3.159  	}
   3.160  
   3.161  	/* No event-channel -> IRQ mappings. */
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Thu Sep 29 11:10:27 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Thu Sep 29 13:05:43 2005 +0100
     4.3 @@ -74,16 +74,12 @@ static int __do_suspend(void *ignore)
     4.4  	extern int gnttab_suspend(void);
     4.5  	extern int gnttab_resume(void);
     4.6  
     4.7 -	extern void time_suspend(void);
     4.8  	extern void time_resume(void);
     4.9  	extern unsigned long max_pfn;
    4.10  	extern unsigned long *pfn_to_mfn_frame_list_list;
    4.11  	extern unsigned long *pfn_to_mfn_frame_list[];
    4.12  
    4.13  #ifdef CONFIG_SMP
    4.14 -	extern void smp_suspend(void);
    4.15 -	extern void smp_resume(void);
    4.16 -
    4.17  	static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
    4.18  	cpumask_t prev_online_cpus, prev_present_cpus;
    4.19  
    4.20 @@ -156,18 +152,10 @@ static int __do_suspend(void *ignore)
    4.21  	kmem_cache_shrink(pgd_cache);
    4.22  #endif
    4.23  
    4.24 -	time_suspend();
    4.25 -
    4.26 -#ifdef CONFIG_SMP
    4.27 -	smp_suspend();
    4.28 -#endif
    4.29 -
    4.30  	xenbus_suspend();
    4.31  
    4.32  	xencons_suspend();
    4.33  
    4.34 -	irq_suspend();
    4.35 -
    4.36  	gnttab_suspend();
    4.37  
    4.38  	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    4.39 @@ -212,10 +200,6 @@ static int __do_suspend(void *ignore)
    4.40  
    4.41  	xenbus_resume();
    4.42  
    4.43 -#ifdef CONFIG_SMP
    4.44 -	smp_resume();
    4.45 -#endif
    4.46 -
    4.47  	time_resume();
    4.48  
    4.49  	usbif_resume();
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c	Thu Sep 29 11:10:27 2005 +0100
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c	Thu Sep 29 13:05:43 2005 +0100
     5.3 @@ -31,14 +31,9 @@ DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IP
     5.4  
     5.5  static inline void __send_IPI_one(unsigned int cpu, int vector)
     5.6  {
     5.7 -	unsigned int evtchn;
     5.8 -	Dprintk("%s\n", __FUNCTION__);
     5.9 -
    5.10 -	evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
    5.11 -	if (evtchn)
    5.12 -		notify_via_evtchn(evtchn);
    5.13 -	else
    5.14 -		printk("send_IPI to unbound port %d/%d", cpu, vector);
    5.15 +	int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
    5.16 +	BUG_ON(evtchn < 0);
    5.17 +	notify_via_evtchn(evtchn);
    5.18  }
    5.19  
    5.20  void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
     6.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h	Thu Sep 29 11:10:27 2005 +0100
     6.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h	Thu Sep 29 13:05:43 2005 +0100
     6.3 @@ -80,11 +80,9 @@
     6.4   * the usable vector space is 0x20-0xff (224 vectors)
     6.5   */
     6.6  
     6.7 -#define NR_IPIS 8
     6.8 -
     6.9 -#define RESCHEDULE_VECTOR	1
    6.10 -#define INVALIDATE_TLB_VECTOR	2
    6.11 -#define CALL_FUNCTION_VECTOR	3
    6.12 +#define RESCHEDULE_VECTOR	0
    6.13 +#define CALL_FUNCTION_VECTOR	1
    6.14 +#define NR_IPIS			2
    6.15  
    6.16  /*
    6.17   * The maximum number of vectors supported by i386 processors
     7.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h	Thu Sep 29 11:10:27 2005 +0100
     7.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h	Thu Sep 29 13:05:43 2005 +0100
     7.3 @@ -78,11 +78,9 @@
     7.4   * the usable vector space is 0x20-0xff (224 vectors)
     7.5   */
     7.6  
     7.7 -#define NR_IPIS 8
     7.8 -
     7.9 -#define RESCHEDULE_VECTOR	1
    7.10 -#define INVALIDATE_TLB_VECTOR	2
    7.11 -#define CALL_FUNCTION_VECTOR	3
    7.12 +#define RESCHEDULE_VECTOR	0
    7.13 +#define CALL_FUNCTION_VECTOR	1
    7.14 +#define NR_IPIS			2
    7.15  
    7.16  /*
    7.17   * The maximum number of vectors supported by i386 processors
     8.1 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Thu Sep 29 11:10:27 2005 +0100
     8.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Thu Sep 29 13:05:43 2005 +0100
     8.3 @@ -68,7 +68,6 @@ extern int  bind_evtchn_to_irqhandler(
     8.4  	void *dev_id);
     8.5  extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
     8.6  
     8.7 -extern void irq_suspend(void);
     8.8  extern void irq_resume(void);
     8.9  
    8.10  /* Entry point for notifications into Linux subsystems. */