ia64/xen-unstable

changeset 1492:50574defb9f7

bitkeeper revision 1.973 (40d163b4Ti3-X4Nlq_sFJk0QGTSg1Q)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xeno
author kaf24@scramble.cl.cam.ac.uk
date Thu Jun 17 09:26:12 2004 +0000 (2004-06-17)
parents f32df7f04499 c3ad1ceced2b
children 4e971c8daf85
files xen/arch/x86/extable.c xen/arch/x86/io_apic.c xen/arch/x86/irq.c xen/arch/x86/nmi.c
line diff
     1.1 --- a/xen/arch/x86/extable.c	Thu Jun 17 06:26:58 2004 +0000
     1.2 +++ b/xen/arch/x86/extable.c	Thu Jun 17 09:26:12 2004 +0000
     1.3 @@ -1,9 +1,5 @@
     1.4 -/*
     1.5 - * linux/arch/i386/mm/extable.c
     1.6 - */
     1.7  
     1.8  #include <xen/config.h>
     1.9 -#include <xen/module.h>
    1.10  #include <xen/spinlock.h>
    1.11  #include <asm/uaccess.h>
    1.12  
    1.13 @@ -15,48 +11,25 @@ search_one_table(const struct exception_
    1.14  		 const struct exception_table_entry *last,
    1.15  		 unsigned long value)
    1.16  {
    1.17 -        while (first <= last) {
    1.18 -		const struct exception_table_entry *mid;
    1.19 -		long diff;
    1.20 +    const struct exception_table_entry *mid;
    1.21 +    long diff;
    1.22  
    1.23 -		mid = (last - first) / 2 + first;
    1.24 -		diff = mid->insn - value;
    1.25 -                if (diff == 0)
    1.26 -                        return mid->fixup;
    1.27 -                else if (diff < 0)
    1.28 -                        first = mid+1;
    1.29 -                else
    1.30 -                        last = mid-1;
    1.31 -        }
    1.32 -        return 0;
    1.33 +    while ( first <= last )
    1.34 +    {
    1.35 +        mid = (last - first) / 2 + first;
    1.36 +        diff = mid->insn - value;
    1.37 +        if (diff == 0)
    1.38 +            return mid->fixup;
    1.39 +        else if (diff < 0)
    1.40 +            first = mid+1;
    1.41 +        else
    1.42 +            last = mid-1;
    1.43 +    }
    1.44 +    return 0;
    1.45  }
    1.46  
    1.47 -extern spinlock_t modlist_lock;
    1.48 -
    1.49  unsigned long
    1.50  search_exception_table(unsigned long addr)
    1.51  {
    1.52 -	unsigned long ret = 0;
    1.53 -	
    1.54 -#ifndef CONFIG_MODULES
    1.55 -	/* There is only the kernel to search.  */
    1.56 -	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
    1.57 -	return ret;
    1.58 -#else
    1.59 -	unsigned long flags;
    1.60 -	/* The kernel is the last "module" -- no need to treat it special.  */
    1.61 -	struct module *mp;
    1.62 -
    1.63 -	spin_lock_irqsave(&modlist_lock, flags);
    1.64 -	for (mp = module_list; mp != NULL; mp = mp->next) {
    1.65 -		if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
    1.66 -			continue;
    1.67 -		ret = search_one_table(mp->ex_table_start,
    1.68 -				       mp->ex_table_end - 1, addr);
    1.69 -		if (ret)
    1.70 -			break;
    1.71 -	}
    1.72 -	spin_unlock_irqrestore(&modlist_lock, flags);
    1.73 -	return ret;
    1.74 -#endif
    1.75 +    return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
    1.76  }
     2.1 --- a/xen/arch/x86/io_apic.c	Thu Jun 17 06:26:58 2004 +0000
     2.2 +++ b/xen/arch/x86/io_apic.c	Thu Jun 17 09:26:12 2004 +0000
     2.3 @@ -1252,7 +1252,7 @@ static int __init timer_irq_works(void)
     2.4  {
     2.5  	unsigned int t1 = jiffies;
     2.6  
     2.7 -	sti();
     2.8 +	__sti();
     2.9  	/* Let ten ticks pass... */
    2.10  	mdelay((10 * 1000) / HZ);
    2.11  
     3.1 --- a/xen/arch/x86/irq.c	Thu Jun 17 06:26:58 2004 +0000
     3.2 +++ b/xen/arch/x86/irq.c	Thu Jun 17 09:26:12 2004 +0000
     3.3 @@ -37,7 +37,6 @@
     3.4  #include <asm/bitops.h>
     3.5  #include <asm/flushtlb.h>
     3.6  #include <xen/delay.h>
     3.7 -#include <xen/timex.h>
     3.8  #include <xen/perfc.h>
     3.9  #include <asm/smpboot.h>
    3.10  
    3.11 @@ -63,11 +62,6 @@
    3.12  irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
    3.13  { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
    3.14  
    3.15 -#ifdef CONFIG_SMP
    3.16 -/* NB. XXX We'll want some way of fiddling with this from DOM0. */
    3.17 -unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
    3.18 -#endif
    3.19 -
    3.20  static void __do_IRQ_guest(int irq);
    3.21  
    3.22  /*
    3.23 @@ -132,205 +126,6 @@ atomic_t irq_mis_count;
    3.24   */
    3.25  
    3.26  /*
    3.27 - * Global interrupt locks for SMP. Allow interrupts to come in on any
    3.28 - * CPU, yet make cli/sti act globally to protect critical regions..
    3.29 - */
    3.30 -
    3.31 -#ifdef CONFIG_SMP
    3.32 -unsigned char global_irq_holder = 0xff;
    3.33 -unsigned volatile long global_irq_lock; /* pendantic: long for set_bit --RR */
    3.34 -        
    3.35 -#define MAXCOUNT 100000000
    3.36 -
    3.37 -/*
    3.38 - * I had a lockup scenario where a tight loop doing
    3.39 - * spin_unlock()/spin_lock() on CPU#1 was racing with
    3.40 - * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
    3.41 - * apparently the spin_unlock() information did not make it
    3.42 - * through to CPU#0 ... nasty, is this by design, do we have to limit
    3.43 - * 'memory update oscillation frequency' artificially like here?
    3.44 - *
    3.45 - * Such 'high frequency update' races can be avoided by careful design, but
    3.46 - * some of our major constructs like spinlocks use similar techniques,
    3.47 - * it would be nice to clarify this issue. Set this define to 0 if you
    3.48 - * want to check whether your system freezes.  I suspect the delay done
    3.49 - * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
    3.50 - * i thought that such things are guaranteed by design, since we use
    3.51 - * the 'LOCK' prefix.
    3.52 - */
    3.53 -#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
    3.54 -
    3.55 -#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
    3.56 -# define SYNC_OTHER_CORES(x) udelay(x+1)
    3.57 -#else
    3.58 -/*
    3.59 - * We have to allow irqs to arrive between __sti and __cli
    3.60 - */
    3.61 -# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
    3.62 -#endif
    3.63 -
    3.64 -static inline void wait_on_irq(int cpu)
    3.65 -{
    3.66 -    for (;;) {
    3.67 -
    3.68 -        /*
    3.69 -         * Wait until all interrupts are gone. Wait
    3.70 -         * for bottom half handlers unless we're
    3.71 -         * already executing in one..
    3.72 -         */
    3.73 -        if (!irqs_running())
    3.74 -            if (local_bh_count(cpu))
    3.75 -                break;
    3.76 -
    3.77 -        /* Duh, we have to loop. Release the lock to avoid deadlocks */
    3.78 -        clear_bit(0,&global_irq_lock);
    3.79 -
    3.80 -        for (;;) {
    3.81 -            __sti();
    3.82 -            SYNC_OTHER_CORES(cpu);
    3.83 -            __cli();
    3.84 -            if (irqs_running())
    3.85 -                continue;
    3.86 -            if (global_irq_lock)
    3.87 -                continue;
    3.88 -            if (!local_bh_count(cpu))
    3.89 -                continue;
    3.90 -            if (!test_and_set_bit(0,&global_irq_lock))
    3.91 -                break;
    3.92 -        }
    3.93 -    }
    3.94 -}
    3.95 -
    3.96 -/*
    3.97 - * This is called when we want to synchronize with
    3.98 - * interrupts. We may for example tell a device to
    3.99 - * stop sending interrupts: but to make sure there
   3.100 - * are no interrupts that are executing on another
   3.101 - * CPU we need to call this function.
   3.102 - */
   3.103 -void synchronize_irq(void)
   3.104 -{
   3.105 -    if (irqs_running()) {
   3.106 -        /* Stupid approach */
   3.107 -        cli();
   3.108 -        sti();
   3.109 -    }
   3.110 -}
   3.111 -
   3.112 -static inline void get_irqlock(int cpu)
   3.113 -{
   3.114 -    if (test_and_set_bit(0,&global_irq_lock)) {
   3.115 -        /* do we already hold the lock? */
   3.116 -        if ((unsigned char) cpu == global_irq_holder)
   3.117 -            return;
   3.118 -        /* Uhhuh.. Somebody else got it. Wait.. */
   3.119 -        do {
   3.120 -            do {
   3.121 -                rep_nop();
   3.122 -            } while (test_bit(0,&global_irq_lock));
   3.123 -        } while (test_and_set_bit(0,&global_irq_lock));         
   3.124 -    }
   3.125 -    /* 
   3.126 -     * We also to make sure that nobody else is running
   3.127 -     * in an interrupt context. 
   3.128 -     */
   3.129 -    wait_on_irq(cpu);
   3.130 -
   3.131 -    /*
   3.132 -     * Ok, finally..
   3.133 -     */
   3.134 -    global_irq_holder = cpu;
   3.135 -}
   3.136 -
   3.137 -#define EFLAGS_IF_SHIFT 9
   3.138 -
   3.139 -/*
   3.140 - * A global "cli()" while in an interrupt context
   3.141 - * turns into just a local cli(). Interrupts
   3.142 - * should use spinlocks for the (very unlikely)
   3.143 - * case that they ever want to protect against
   3.144 - * each other.
   3.145 - *
   3.146 - * If we already have local interrupts disabled,
   3.147 - * this will not turn a local disable into a
   3.148 - * global one (problems with spinlocks: this makes
   3.149 - * save_flags+cli+sti usable inside a spinlock).
   3.150 - */
   3.151 -void __global_cli(void)
   3.152 -{
   3.153 -    unsigned int flags;
   3.154 -
   3.155 -    __save_flags(flags);
   3.156 -    if (flags & (1 << EFLAGS_IF_SHIFT)) {
   3.157 -        int cpu = smp_processor_id();
   3.158 -        __cli();
   3.159 -        if (!local_irq_count(cpu))
   3.160 -            get_irqlock(cpu);
   3.161 -    }
   3.162 -}
   3.163 -
   3.164 -void __global_sti(void)
   3.165 -{
   3.166 -    int cpu = smp_processor_id();
   3.167 -
   3.168 -    if (!local_irq_count(cpu))
   3.169 -        release_irqlock(cpu);
   3.170 -    __sti();
   3.171 -}
   3.172 -
   3.173 -/*
   3.174 - * SMP flags value to restore to:
   3.175 - * 0 - global cli
   3.176 - * 1 - global sti
   3.177 - * 2 - local cli
   3.178 - * 3 - local sti
   3.179 - */
   3.180 -unsigned long __global_save_flags(void)
   3.181 -{
   3.182 -    int retval;
   3.183 -    int local_enabled;
   3.184 -    unsigned long flags;
   3.185 -    int cpu = smp_processor_id();
   3.186 -
   3.187 -    __save_flags(flags);
   3.188 -    local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
   3.189 -    /* default to local */
   3.190 -    retval = 2 + local_enabled;
   3.191 -
   3.192 -    /* check for global flags if we're not in an interrupt */
   3.193 -    if (!local_irq_count(cpu)) {
   3.194 -        if (local_enabled)
   3.195 -            retval = 1;
   3.196 -        if (global_irq_holder == cpu)
   3.197 -            retval = 0;
   3.198 -    }
   3.199 -    return retval;
   3.200 -}
   3.201 -
   3.202 -void __global_restore_flags(unsigned long flags)
   3.203 -{
   3.204 -    switch (flags) {
   3.205 -    case 0:
   3.206 -        __global_cli();
   3.207 -        break;
   3.208 -    case 1:
   3.209 -        __global_sti();
   3.210 -        break;
   3.211 -    case 2:
   3.212 -        __cli();
   3.213 -        break;
   3.214 -    case 3:
   3.215 -        __sti();
   3.216 -        break;
   3.217 -    default:
   3.218 -        printk("global_restore_flags: %08lx (%08lx)\n",
   3.219 -               flags, (&flags)[-1]);
   3.220 -    }
   3.221 -}
   3.222 -
   3.223 -#endif
   3.224 -
   3.225 -/*
   3.226   * This should really return information about whether
   3.227   * we should do bottom half handling etc. Right now we
   3.228   * end up _always_ checking the bottom half, which is a
   3.229 @@ -693,204 +488,6 @@ void free_irq(unsigned int irq, void *de
   3.230      }
   3.231  }
   3.232  
   3.233 -/*
   3.234 - * IRQ autodetection code..
   3.235 - *
   3.236 - * This depends on the fact that any interrupt that
   3.237 - * comes in on to an unassigned handler will get stuck
   3.238 - * with "IRQ_WAITING" cleared and the interrupt
   3.239 - * disabled.
   3.240 - */
   3.241 -
   3.242 -static spinlock_t probe_sem = SPIN_LOCK_UNLOCKED;
   3.243 -
   3.244 -/**
   3.245 - *      probe_irq_on    - begin an interrupt autodetect
   3.246 - *
   3.247 - *      Commence probing for an interrupt. The interrupts are scanned
   3.248 - *      and a mask of potential interrupt lines is returned.
   3.249 - *
   3.250 - */
   3.251 - 
   3.252 -unsigned long probe_irq_on(void)
   3.253 -{
   3.254 -    unsigned int i;
   3.255 -    irq_desc_t *desc;
   3.256 -    unsigned long val;
   3.257 -    unsigned long s=0, e=0;
   3.258 -
   3.259 -    spin_lock(&probe_sem);
   3.260 -    /* 
   3.261 -     * something may have generated an irq long ago and we want to
   3.262 -     * flush such a longstanding irq before considering it as spurious. 
   3.263 -     */
   3.264 -    for (i = NR_IRQS-1; i > 0; i--)  {
   3.265 -        desc = irq_desc + i;
   3.266 -
   3.267 -        spin_lock_irq(&desc->lock);
   3.268 -        if (!irq_desc[i].action) 
   3.269 -            irq_desc[i].handler->startup(i);
   3.270 -        spin_unlock_irq(&desc->lock);
   3.271 -    }
   3.272 -
   3.273 -    /* Wait for longstanding interrupts to trigger (20ms delay). */
   3.274 -    rdtscl(s);
   3.275 -    do {
   3.276 -        synchronize_irq();
   3.277 -        rdtscl(e);
   3.278 -    } while ( ((e-s)/ticks_per_usec) < 20000 );
   3.279 -
   3.280 -    /*
   3.281 -     * enable any unassigned irqs
   3.282 -     * (we must startup again here because if a longstanding irq
   3.283 -     * happened in the previous stage, it may have masked itself)
   3.284 -     */
   3.285 -    for (i = NR_IRQS-1; i > 0; i--) {
   3.286 -        desc = irq_desc + i;
   3.287 -
   3.288 -        spin_lock_irq(&desc->lock);
   3.289 -        if (!desc->action) {
   3.290 -            desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
   3.291 -            if (desc->handler->startup(i))
   3.292 -                desc->status |= IRQ_PENDING;
   3.293 -        }
   3.294 -        spin_unlock_irq(&desc->lock);
   3.295 -    }
   3.296 -
   3.297 -    /*
   3.298 -     * Wait for spurious interrupts to trigger (100ms delay). 
   3.299 -     */
   3.300 -    rdtscl(s);
   3.301 -    do {
   3.302 -        synchronize_irq();
   3.303 -        rdtscl(e);
   3.304 -    } while ( ((e-s)/ticks_per_usec) < 100000 );
   3.305 -
   3.306 -    /*
   3.307 -     * Now filter out any obviously spurious interrupts
   3.308 -     */
   3.309 -    val = 0;
   3.310 -    for (i = 0; i < NR_IRQS; i++) {
   3.311 -        irq_desc_t *desc = irq_desc + i;
   3.312 -        unsigned int status;
   3.313 -
   3.314 -        spin_lock_irq(&desc->lock);
   3.315 -        status = desc->status;
   3.316 -
   3.317 -        if (status & IRQ_AUTODETECT) {
   3.318 -            /* It triggered already - consider it spurious. */
   3.319 -            if (!(status & IRQ_WAITING)) {
   3.320 -                desc->status = status & ~IRQ_AUTODETECT;
   3.321 -                desc->handler->shutdown(i);
   3.322 -            } else
   3.323 -                if (i < 32)
   3.324 -                    val |= 1 << i;
   3.325 -        }
   3.326 -        spin_unlock_irq(&desc->lock);
   3.327 -    }
   3.328 -
   3.329 -    return val;
   3.330 -}
   3.331 -
   3.332 -/*
   3.333 - * Return a mask of triggered interrupts (this
   3.334 - * can handle only legacy ISA interrupts).
   3.335 - */
   3.336 - 
   3.337 -/**
   3.338 - *      probe_irq_mask - scan a bitmap of interrupt lines
   3.339 - *      @val:   mask of interrupts to consider
   3.340 - *
   3.341 - *      Scan the ISA bus interrupt lines and return a bitmap of
   3.342 - *      active interrupts. The interrupt probe logic state is then
   3.343 - *      returned to its previous value.
   3.344 - *
   3.345 - *      Note: we need to scan all the irq's even though we will
   3.346 - *      only return ISA irq numbers - just so that we reset them
   3.347 - *      all to a known state.
   3.348 - */
   3.349 -unsigned int probe_irq_mask(unsigned long val)
   3.350 -{
   3.351 -    int i;
   3.352 -    unsigned int mask;
   3.353 -
   3.354 -    mask = 0;
   3.355 -    for (i = 0; i < NR_IRQS; i++) {
   3.356 -        irq_desc_t *desc = irq_desc + i;
   3.357 -        unsigned int status;
   3.358 -
   3.359 -        spin_lock_irq(&desc->lock);
   3.360 -        status = desc->status;
   3.361 -
   3.362 -        if (status & IRQ_AUTODETECT) {
   3.363 -            if (i < 16 && !(status & IRQ_WAITING))
   3.364 -                mask |= 1 << i;
   3.365 -
   3.366 -            desc->status = status & ~IRQ_AUTODETECT;
   3.367 -            desc->handler->shutdown(i);
   3.368 -        }
   3.369 -        spin_unlock_irq(&desc->lock);
   3.370 -    }
   3.371 -    spin_unlock(&probe_sem);
   3.372 -
   3.373 -    return mask & val;
   3.374 -}
   3.375 -
   3.376 -/*
   3.377 - * Return the one interrupt that triggered (this can
   3.378 - * handle any interrupt source).
   3.379 - */
   3.380 -
   3.381 -/**
   3.382 - *      probe_irq_off   - end an interrupt autodetect
   3.383 - *      @val: mask of potential interrupts (unused)
   3.384 - *
   3.385 - *      Scans the unused interrupt lines and returns the line which
   3.386 - *      appears to have triggered the interrupt. If no interrupt was
   3.387 - *      found then zero is returned. If more than one interrupt is
   3.388 - *      found then minus the first candidate is returned to indicate
   3.389 - *      their is doubt.
   3.390 - *
   3.391 - *      The interrupt probe logic state is returned to its previous
   3.392 - *      value.
   3.393 - *
   3.394 - *      BUGS: When used in a module (which arguably shouldnt happen)
   3.395 - *      nothing prevents two IRQ probe callers from overlapping. The
   3.396 - *      results of this are non-optimal.
   3.397 - */
   3.398 - 
   3.399 -int probe_irq_off(unsigned long val)
   3.400 -{
   3.401 -    int i, irq_found, nr_irqs;
   3.402 -
   3.403 -    nr_irqs = 0;
   3.404 -    irq_found = 0;
   3.405 -    for (i = 0; i < NR_IRQS; i++) {
   3.406 -        irq_desc_t *desc = irq_desc + i;
   3.407 -        unsigned int status;
   3.408 -
   3.409 -        spin_lock_irq(&desc->lock);
   3.410 -        status = desc->status;
   3.411 -
   3.412 -        if (status & IRQ_AUTODETECT) {
   3.413 -            if (!(status & IRQ_WAITING)) {
   3.414 -                if (!nr_irqs)
   3.415 -                    irq_found = i;
   3.416 -                nr_irqs++;
   3.417 -            }
   3.418 -            desc->status = status & ~IRQ_AUTODETECT;
   3.419 -            desc->handler->shutdown(i);
   3.420 -        }
   3.421 -        spin_unlock_irq(&desc->lock);
   3.422 -    }
   3.423 -    spin_unlock(&probe_sem);
   3.424 -
   3.425 -    if (nr_irqs > 1)
   3.426 -        irq_found = -irq_found;
   3.427 -    return irq_found;
   3.428 -}
   3.429 -
   3.430 -/* this was setup_x86_irq but it seems pretty generic */
   3.431  int setup_irq(unsigned int irq, struct irqaction * new)
   3.432  {
   3.433      int shared = 0;
     4.1 --- a/xen/arch/x86/nmi.c	Thu Jun 17 06:26:58 2004 +0000
     4.2 +++ b/xen/arch/x86/nmi.c	Thu Jun 17 09:26:12 2004 +0000
     4.3 @@ -20,7 +20,6 @@
     4.4  #include <xen/delay.h>
     4.5  #include <xen/interrupt.h>
     4.6  #include <xen/time.h>
     4.7 -#include <xen/timex.h>
     4.8  #include <xen/sched.h>
     4.9  
    4.10  #include <asm/mc146818rtc.h>
    4.11 @@ -103,7 +102,7 @@ int __init check_nmi_watchdog (void)
    4.12          cpu = cpu_logical_map(j);
    4.13          prev_nmi_count[cpu] = irq_stat[cpu].__nmi_count;
    4.14      }
    4.15 -    sti();
    4.16 +    __sti();
    4.17      mdelay((10*1000)/nmi_hz); /* wait 10 ticks */
    4.18  
    4.19      for ( j = 0; j < smp_num_cpus; j++ )