ia64/xen-unstable

changeset 13574:914304b3a3da

linux: Fix enable_irq() crash by removing a BUG_ON() assumption in our
event-channel retrigger() function. Also clean up bitmap usages.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Jan 23 13:39:20 2007 +0000 (2007-01-23)
parents ee7c422c5f7b
children ffe52263b430
files linux-2.6-xen-sparse/drivers/xen/core/evtchn.c linux-2.6-xen-sparse/include/xen/evtchn.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Tue Jan 23 11:39:32 2007 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Tue Jan 23 13:39:20 2007 +0000
     1.3 @@ -60,8 +60,6 @@ static int evtchn_to_irq[NR_EVENT_CHANNE
     1.4  /* Packed IRQ information: binding type, sub-type index, and event channel. */
     1.5  static u32 irq_info[NR_IRQS];
     1.6  
     1.7 -static int resend_irq_on_evtchn(unsigned int);
     1.8 -
     1.9  /* Binding types. */
    1.10  enum {
    1.11  	IRQT_UNBOUND,
    1.12 @@ -113,7 +111,7 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS])
    1.13  static int irq_bindcount[NR_IRQS];
    1.14  
    1.15  /* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
    1.16 -static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)];
    1.17 +static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS);
    1.18  
    1.19  #ifdef CONFIG_SMP
    1.20  
    1.21 @@ -614,6 +612,22 @@ static void set_affinity_irq(unsigned ir
    1.22  }
    1.23  #endif
    1.24  
    1.25 +static int resend_irq_on_evtchn(unsigned int i)
    1.26 +{
    1.27 +	int masked, evtchn = evtchn_from_irq(i);
    1.28 +	shared_info_t *s = HYPERVISOR_shared_info;
    1.29 +
    1.30 +	if (!VALID_EVTCHN(evtchn))
    1.31 +		return 1;
    1.32 +
    1.33 +	masked = synch_test_and_set_bit(evtchn, s->evtchn_mask);
    1.34 +	synch_set_bit(evtchn, s->evtchn_pending);
    1.35 +	if (!masked)
    1.36 +		unmask_evtchn(evtchn);
    1.37 +
    1.38 +	return 1;
    1.39 +}
    1.40 +
    1.41  /*
    1.42   * Interface to generic handling in irq.c
    1.43   */
    1.44 @@ -688,7 +702,7 @@ static struct hw_interrupt_type dynirq_t
    1.45  static inline void pirq_unmask_notify(int pirq)
    1.46  {
    1.47  	struct physdev_eoi eoi = { .irq = pirq };
    1.48 -	if (unlikely(test_bit(pirq, &pirq_needs_eoi[0])))
    1.49 +	if (unlikely(test_bit(pirq, pirq_needs_eoi)))
    1.50  		(void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
    1.51  }
    1.52  
    1.53 @@ -697,9 +711,9 @@ static inline void pirq_query_unmask(int
    1.54  	struct physdev_irq_status_query irq_status;
    1.55  	irq_status.irq = pirq;
    1.56  	(void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
    1.57 -	clear_bit(pirq, &pirq_needs_eoi[0]);
    1.58 +	clear_bit(pirq, pirq_needs_eoi);
    1.59  	if (irq_status.flags & XENIRQSTAT_needs_eoi)
    1.60 -		set_bit(pirq, &pirq_needs_eoi[0]);
    1.61 +		set_bit(pirq, pirq_needs_eoi);
    1.62  }
    1.63  
    1.64  /*
    1.65 @@ -824,18 +838,6 @@ int irq_ignore_unhandled(unsigned int ir
    1.66  	return !!(irq_status.flags & XENIRQSTAT_shared);
    1.67  }
    1.68  
    1.69 -static int resend_irq_on_evtchn(unsigned int i)
    1.70 -{
    1.71 -	int evtchn = evtchn_from_irq(i);
    1.72 -	shared_info_t *s = HYPERVISOR_shared_info;
    1.73 -	if (!VALID_EVTCHN(evtchn))
    1.74 -		return 0;
    1.75 -	BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
    1.76 -	synch_set_bit(evtchn, &s->evtchn_pending[0]);
    1.77 -
    1.78 -	return 1;
    1.79 -}
    1.80 -
    1.81  void notify_remote_via_irq(int irq)
    1.82  {
    1.83  	int evtchn = evtchn_from_irq(irq);
    1.84 @@ -854,7 +856,7 @@ EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
    1.85  void mask_evtchn(int port)
    1.86  {
    1.87  	shared_info_t *s = HYPERVISOR_shared_info;
    1.88 -	synch_set_bit(port, &s->evtchn_mask[0]);
    1.89 +	synch_set_bit(port, s->evtchn_mask);
    1.90  }
    1.91  EXPORT_SYMBOL_GPL(mask_evtchn);
    1.92  
    1.93 @@ -873,14 +875,10 @@ void unmask_evtchn(int port)
    1.94  		return;
    1.95  	}
    1.96  
    1.97 -	synch_clear_bit(port, &s->evtchn_mask[0]);
    1.98 +	synch_clear_bit(port, s->evtchn_mask);
    1.99  
   1.100 -	/*
   1.101 -	 * The following is basically the equivalent of 'hw_resend_irq'. Just
   1.102 -	 * like a real IO-APIC we 'lose the interrupt edge' if the channel is
   1.103 -	 * masked.
   1.104 -	 */
   1.105 -	if (synch_test_bit(port, &s->evtchn_pending[0]) &&
   1.106 +	/* Did we miss an interrupt 'edge'? Re-fire if so. */
   1.107 +	if (synch_test_bit(port, s->evtchn_pending) &&
   1.108  	    !synch_test_and_set_bit(port / BITS_PER_LONG,
   1.109  				    &vcpu_info->evtchn_pending_sel))
   1.110  		vcpu_info->evtchn_upcall_pending = 1;
     2.1 --- a/linux-2.6-xen-sparse/include/xen/evtchn.h	Tue Jan 23 11:39:32 2007 +0000
     2.2 +++ b/linux-2.6-xen-sparse/include/xen/evtchn.h	Tue Jan 23 13:39:20 2007 +0000
     2.3 @@ -108,7 +108,7 @@ void unmask_evtchn(int port);
     2.4  static inline void clear_evtchn(int port)
     2.5  {
     2.6  	shared_info_t *s = HYPERVISOR_shared_info;
     2.7 -	synch_clear_bit(port, &s->evtchn_pending[0]);
     2.8 +	synch_clear_bit(port, s->evtchn_pending);
     2.9  }
    2.10  
    2.11  static inline void notify_remote_via_evtchn(int port)