ia64/xen-unstable

changeset 1241:916d919c54b7

bitkeeper revision 1.825.3.3 (40644a58kyQA-kAg5Z_gzo6G7pzNLA)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/ach61/xeno-clone/xeno.bk
author ach61@labyrinth.cl.cam.ac.uk
date Fri Mar 26 15:20:56 2004 +0000 (2004-03-26)
parents d1172efb8a1e e2d412f4b445
children 320a5b1813ad
files .rootkeys docs/Console-HOWTO.txt tools/xentrace/Makefile xen/arch/i386/io_apic.c xen/arch/i386/irq.c xen/common/event_channel.c xen/common/physdev.c xen/drivers/char/console.c xen/include/asm-i386/irq.h xen/include/asm-x86_64/irq.h xen/include/hypervisor-ifs/dom0_ops.h xen/include/hypervisor-ifs/event_channel.h xen/include/hypervisor-ifs/physdev.h xen/include/xen/interrupt.h xen/include/xen/irq.h xenolinux-2.4.25-sparse/arch/xen/kernel/Makefile xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c xenolinux-2.4.25-sparse/arch/xen/kernel/physirq.c xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c xenolinux-2.4.25-sparse/arch/xen/kernel/time.c xenolinux-2.4.25-sparse/include/asm-xen/irq.h
line diff
     1.1 --- a/.rootkeys	Thu Mar 25 17:52:36 2004 +0000
     1.2 +++ b/.rootkeys	Fri Mar 26 15:20:56 2004 +0000
     1.3 @@ -641,7 +641,6 @@ 4051db89iiHs38tWGkoW_RukNyaBHw xenolinux
     1.4  4051db8dJYX86ZCLA-WfTW2dAyrehw xenolinux-2.4.25-sparse/arch/xen/kernel/pci-i386.h
     1.5  4051db91BenvDZEMZxQCGkQyJYoG5w xenolinux-2.4.25-sparse/arch/xen/kernel/pci-irq.c
     1.6  4051db95N9N99FjsRwi49YKUNHWI8A xenolinux-2.4.25-sparse/arch/xen/kernel/pci-pc.c
     1.7 -4051db99fbdTHgCpjywPCp7vjLCe7Q xenolinux-2.4.25-sparse/arch/xen/kernel/physirq.c
     1.8  3e5a4e65IGt3WwQDNiL4h-gYWgNTWQ xenolinux-2.4.25-sparse/arch/xen/kernel/process.c
     1.9  3e5a4e66tR-qJMLj3MppcKqmvuI2XQ xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
    1.10  3e5a4e66fWSTagLGU2P8BGFGRjhDiw xenolinux-2.4.25-sparse/arch/xen/kernel/signal.c
     2.1 --- a/docs/Console-HOWTO.txt	Thu Mar 25 17:52:36 2004 +0000
     2.2 +++ b/docs/Console-HOWTO.txt	Fri Mar 26 15:20:56 2004 +0000
     2.3 @@ -60,8 +60,8 @@ Virtual console for other domains
     2.4   the provided init.d script. To integrate startup and shutdown of xend
     2.5   in such a system, you will need to run a few configuration commands:
     2.6    # chkconfig --add xend
     2.7 -  # chkconfig --level 35 on
     2.8 -  # chkconfig --level 01246 off
     2.9 +  # chkconfig --level 35 xend on
    2.10 +  # chkconfig --level 01246 xend off
    2.11   This will avoid the need to run xend manually from rc.local, for example.
    2.12  
    2.13   Note that, when a domain is created using xc_dom_create.py, xend MUST
     3.1 --- a/tools/xentrace/Makefile	Thu Mar 25 17:52:36 2004 +0000
     3.2 +++ b/tools/xentrace/Makefile	Fri Mar 26 15:20:56 2004 +0000
     3.3 @@ -7,7 +7,8 @@ CFLAGS  += -I../../xenolinux-sparse/incl
     3.4  HDRS     = $(wildcard *.h)
     3.5  OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
     3.6  
     3.7 -BIN      = xentrace xentrace_cpusplit xentrace_format
     3.8 +BIN      = xentrace
     3.9 +SCRIPTS  = xentrace_cpusplit xentrace_format
    3.10  MAN1     = $(wildcard *.1)
    3.11  MAN8     = $(wildcard *.8)
    3.12  
    3.13 @@ -17,7 +18,7 @@ install: all
    3.14  	mkdir -p $(prefix)/usr/bin
    3.15  	mkdir -p $(prefix)/usr/man/man1
    3.16  	mkdir -p $(prefix)/usr/man/man8
    3.17 -	install -m0755 $(BIN) $(prefix)/usr/bin
    3.18 +	install -m0755 $(BIN) $(SCRIPTS) $(prefix)/usr/bin
    3.19  	install -m0644 $(MAN1) $(prefix)/usr/man/man1
    3.20  	install -m0644 $(MAN8) $(prefix)/usr/man/man8
    3.21  
     4.1 --- a/xen/arch/i386/io_apic.c	Thu Mar 25 17:52:36 2004 +0000
     4.2 +++ b/xen/arch/i386/io_apic.c	Fri Mar 26 15:20:56 2004 +0000
     4.3 @@ -138,14 +138,10 @@ static void __init replace_pin_at_irq(un
     4.4  	static void name##_IO_APIC_irq (unsigned int irq)		\
     4.5  	__DO_ACTION(R, ACTION, FINAL)
     4.6  
     4.7 -DO_ACTION( __mask,             0, |= 0x00010000, io_apic_sync(entry->apic) )
     4.8 -						/* mask = 1 */
     4.9 -DO_ACTION( __unmask,           0, &= 0xfffeffff, )
    4.10 -						/* mask = 0 */
    4.11 -DO_ACTION( __mask_and_edge,    0, = (reg & 0xffff7fff) | 0x00010000, )
    4.12 -						/* mask = 1, trigger = 0 */
    4.13 -DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
    4.14 -						/* mask = 0, trigger = 1 */
    4.15 +DO_ACTION( __mask,    0, |= 0x00010000, io_apic_sync(entry->apic) )
    4.16 +DO_ACTION( __unmask,  0, &= 0xfffeffff, )
    4.17 +DO_ACTION( __edge,    0, &= 0xffff7fff, )
    4.18 +DO_ACTION( __level,   0, |= 0x00008000, )
    4.19  
    4.20  static void mask_IO_APIC_irq (unsigned int irq)
    4.21  {
    4.22 @@ -1365,13 +1361,15 @@ static unsigned int startup_level_ioapic
    4.23  	return 0; /* don't check for pending */
    4.24  }
    4.25  
    4.26 -static void end_level_ioapic_irq (unsigned int irq)
    4.27 +static void mask_and_ack_level_ioapic_irq(unsigned int irq)
    4.28  {
    4.29  	unsigned long v;
    4.30  	int i;
    4.31  
    4.32  	balance_irq(irq);
    4.33  
    4.34 +	mask_IO_APIC_irq(irq);
    4.35 +
    4.36  /*
    4.37   * It appears there is an erratum which affects at least version 0x11
    4.38   * of I/O APIC (that's the 82093AA and cores integrated into various
    4.39 @@ -1405,7 +1403,7 @@ static void end_level_ioapic_irq (unsign
    4.40  		atomic_inc(&irq_mis_count);
    4.41  #endif
    4.42  		spin_lock(&ioapic_lock);
    4.43 -		__mask_and_edge_IO_APIC_irq(irq);
    4.44 +		__edge_IO_APIC_irq(irq);
    4.45  #ifdef APIC_LOCKUP_DEBUG
    4.46  		for (entry = irq_2_pin + irq;;) {
    4.47  			unsigned int reg;
    4.48 @@ -1421,12 +1419,15 @@ static void end_level_ioapic_irq (unsign
    4.49  			entry = irq_2_pin + entry->next;
    4.50  		}
    4.51  #endif
    4.52 -		__unmask_and_level_IO_APIC_irq(irq);
    4.53 +		__level_IO_APIC_irq(irq);
    4.54  		spin_unlock(&ioapic_lock);
    4.55  	}
    4.56  }
    4.57  
    4.58 -static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
    4.59 +static void end_level_ioapic_irq(unsigned int irq)
    4.60 +{
    4.61 +	unmask_IO_APIC_irq(irq);
    4.62 +}
    4.63  
    4.64  static inline void init_IO_APIC_traps(void)
    4.65  {
     5.1 --- a/xen/arch/i386/irq.c	Thu Mar 25 17:52:36 2004 +0000
     5.2 +++ b/xen/arch/i386/irq.c	Fri Mar 26 15:20:56 2004 +0000
     5.3 @@ -24,6 +24,7 @@
     5.4  #include <xen/interrupt.h>
     5.5  #include <xen/irq.h>
     5.6  #include <xen/slab.h>
     5.7 +#include <xen/event.h>
     5.8  #include <asm/mpspec.h>
     5.9  #include <asm/io_apic.h>
    5.10  #include <asm/msr.h>
    5.11 @@ -66,6 +67,8 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline
    5.12  unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
    5.13  #endif
    5.14  
    5.15 +static void __do_IRQ_guest(int irq);
    5.16 +
    5.17  /*
    5.18   * Special irq handlers.
    5.19   */
    5.20 @@ -333,7 +336,9 @@ void __global_restore_flags(unsigned lon
    5.21   * waste of time and is not what some drivers would
    5.22   * prefer.
    5.23   */
    5.24 -int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
    5.25 +static int handle_IRQ_event(unsigned int irq, 
    5.26 +                            struct pt_regs * regs, 
    5.27 +                            struct irqaction * action)
    5.28  {
    5.29      int status;
    5.30      int cpu = smp_processor_id();
    5.31 @@ -483,6 +488,7 @@ asmlinkage unsigned int do_IRQ(struct pt
    5.32  
    5.33      spin_lock(&desc->lock);
    5.34      desc->handler->ack(irq);
    5.35 +
    5.36      /*
    5.37        REPLAY is when Linux resends an IRQ that was dropped earlier
    5.38        WAITING is used by probe to mark irqs that are being tested
    5.39 @@ -490,6 +496,14 @@ asmlinkage unsigned int do_IRQ(struct pt
    5.40      status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
    5.41      status |= IRQ_PENDING; /* we _want_ to handle it */
    5.42  
    5.43 +    /* We hook off guest-bound IRQs for special handling. */
    5.44 +    if ( status & IRQ_GUEST )
    5.45 +    {
    5.46 +        __do_IRQ_guest(irq);
    5.47 +        spin_unlock(&desc->lock);
    5.48 +        return 1;
    5.49 +    }
    5.50 +
    5.51      /*
    5.52       * If the IRQ is disabled for whatever reason, we cannot use the action we 
    5.53       * have.
    5.54 @@ -883,6 +897,13 @@ int setup_irq(unsigned int irq, struct i
    5.55       * The following block of code has to be executed atomically
    5.56       */
    5.57      spin_lock_irqsave(&desc->lock,flags);
    5.58 +
    5.59 +    if ( desc->status & IRQ_GUEST )
    5.60 +    {
    5.61 +        spin_unlock_irqrestore(&desc->lock,flags);
    5.62 +        return -EBUSY;
    5.63 +    }
    5.64 +
    5.65      p = &desc->action;
    5.66      if ((old = *p) != NULL) {
    5.67          /* Can't share interrupts unless both agree to */
    5.68 @@ -906,7 +927,110 @@ int setup_irq(unsigned int irq, struct i
    5.69          desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
    5.70          desc->handler->startup(irq);
    5.71      }
    5.72 +
    5.73      spin_unlock_irqrestore(&desc->lock,flags);
    5.74  
    5.75      return 0;
    5.76  }
    5.77 +
    5.78 +
    5.79 +
    5.80 +/*
    5.81 + * HANDLING OF GUEST-BOUND PHYSICAL IRQS
    5.82 + */
    5.83 +
    5.84 +#define IRQ_MAX_GUESTS 7
    5.85 +typedef struct {
    5.86 +    unsigned int nr_guests;
    5.87 +    struct task_struct *guest[IRQ_MAX_GUESTS];
    5.88 +} irq_guest_action_t;
    5.89 +
    5.90 +static void __do_IRQ_guest(int irq)
    5.91 +{
    5.92 +    irq_desc_t *desc = &irq_desc[irq];
    5.93 +    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
    5.94 +    struct task_struct *p;
    5.95 +    int i;
    5.96 +
    5.97 +    for ( i = 0; i < action->nr_guests; i++ )
    5.98 +    {
    5.99 +        p = action->guest[i];
   5.100 +        send_guest_pirq(p, irq);
   5.101 +    }
   5.102 +}
   5.103 +
   5.104 +int pirq_guest_bind(struct task_struct *p, int irq)
   5.105 +{
   5.106 +    unsigned long flags;
   5.107 +    irq_desc_t *desc = &irq_desc[irq];
   5.108 +    irq_guest_action_t *action;
   5.109 +    int rc;
   5.110 +
   5.111 +    if ( !IS_PRIV(p) )
   5.112 +        return -EPERM;
   5.113 +
   5.114 +    spin_lock_irqsave(&desc->lock, flags);
   5.115 +
   5.116 +    if ( !(desc->status & IRQ_GUEST) )
   5.117 +    {
   5.118 +        rc = -EBUSY;
   5.119 +        if ( desc->action != NULL )
   5.120 +            goto out;
   5.121 +
   5.122 +        rc = -ENOMEM;
   5.123 +        action = kmalloc(sizeof(irq_guest_action_t), GFP_KERNEL);
   5.124 +        if ( (desc->action = (struct irqaction *)action) == NULL )
   5.125 +            goto out;
   5.126 +
   5.127 +        action->nr_guests = 0;
   5.128 +
   5.129 +        desc->depth = 0;
   5.130 +        desc->status |= IRQ_GUEST;
   5.131 +        desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
   5.132 +        desc->handler->startup(irq);
   5.133 +    }
   5.134 +
   5.135 +    action = (irq_guest_action_t *)desc->action;
   5.136 +
   5.137 +    rc = -EBUSY;
   5.138 +    if ( action->nr_guests == IRQ_MAX_GUESTS )
   5.139 +        goto out;
   5.140 +
   5.141 +    action->guest[action->nr_guests++] = p;
   5.142 +
   5.143 + out:
   5.144 +    spin_unlock_irqrestore(&desc->lock, flags);
   5.145 +    return rc;
   5.146 +}
   5.147 +
   5.148 +int pirq_guest_unbind(struct task_struct *p, int irq)
   5.149 +{
   5.150 +    unsigned long flags;
   5.151 +    irq_desc_t *desc = &irq_desc[irq];
   5.152 +    irq_guest_action_t *action;
   5.153 +    int i;
   5.154 +
   5.155 +    spin_lock_irqsave(&desc->lock, flags);
   5.156 +
   5.157 +    action = (irq_guest_action_t *)desc->action;
   5.158 +
   5.159 +    if ( action->nr_guests == 1 )
   5.160 +    {
   5.161 +        desc->action = NULL;
   5.162 +        kfree(action);
   5.163 +        desc->status |= IRQ_DISABLED;
   5.164 +        desc->status &= ~IRQ_GUEST;
   5.165 +        desc->handler->shutdown(irq);
   5.166 +    }
   5.167 +    else
   5.168 +    {
   5.169 +        i = 0;
   5.170 +        while ( action->guest[i] != p )
   5.171 +            i++;
   5.172 +        memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
   5.173 +        action->nr_guests--;
   5.174 +    }
   5.175 +
   5.176 +    spin_unlock_irqrestore(&desc->lock, flags);    
   5.177 +    return 0;
   5.178 +}
     6.1 --- a/xen/common/event_channel.c	Thu Mar 25 17:52:36 2004 +0000
     6.2 +++ b/xen/common/event_channel.c	Fri Mar 26 15:20:56 2004 +0000
     6.3 @@ -21,6 +21,7 @@
     6.4  #include <xen/errno.h>
     6.5  #include <xen/sched.h>
     6.6  #include <xen/event.h>
     6.7 +#include <xen/irq.h>
     6.8  
     6.9  #include <hypervisor-ifs/hypervisor-if.h>
    6.10  #include <hypervisor-ifs/event_channel.h>
    6.11 @@ -146,7 +147,7 @@ static long evtchn_bind_virq(evtchn_bind
    6.12      int virq = bind->virq;
    6.13      int port;
    6.14  
    6.15 -    if ( virq >= NR_VIRQS )
    6.16 +    if ( virq >= ARRAY_SIZE(p->virq_to_evtchn) )
    6.17          return -EINVAL;
    6.18  
    6.19      spin_lock(&p->event_channel_lock);
    6.20 @@ -177,6 +178,42 @@ static long evtchn_bind_virq(evtchn_bind
    6.21  }
    6.22  
    6.23  
    6.24 +static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
    6.25 +{
    6.26 +    struct task_struct *p = current;
    6.27 +    int pirq = bind->pirq;
    6.28 +    int port, rc;
    6.29 +
    6.30 +    if ( pirq >= ARRAY_SIZE(p->pirq_to_evtchn) )
    6.31 +        return -EINVAL;
    6.32 +
    6.33 +    spin_lock(&p->event_channel_lock);
    6.34 +
    6.35 +    if ( ((rc = port = p->pirq_to_evtchn[pirq]) != 0) ||
    6.36 +         ((rc = port = get_free_port(p)) < 0) )
    6.37 +        goto out;
    6.38 +
    6.39 +    p->pirq_to_evtchn[pirq] = port;
    6.40 +    if ( (rc = pirq_guest_bind(p, pirq)) != 0 )
    6.41 +    {
    6.42 +        p->pirq_to_evtchn[pirq] = 0;
    6.43 +        goto out;
    6.44 +    }
    6.45 +
    6.46 +    p->event_channel[port].state  = ECS_PIRQ;
    6.47 +    p->event_channel[port].u.pirq = pirq;
    6.48 +
    6.49 + out:
    6.50 +    spin_unlock(&p->event_channel_lock);
    6.51 +
    6.52 +    if ( rc < 0 )
    6.53 +        return rc;
    6.54 +
    6.55 +    bind->port = port;
    6.56 +    return 0;
    6.57 +}
    6.58 +
    6.59 +
    6.60  static long __evtchn_close(struct task_struct *p1, int port1)
    6.61  {
    6.62      struct task_struct *p2 = NULL;
    6.63 @@ -206,7 +243,8 @@ static long __evtchn_close(struct task_s
    6.64          break;
    6.65  
    6.66      case ECS_PIRQ:
    6.67 -        p1->pirq_to_evtchn[chn1[port1].u.pirq] = 0;
    6.68 +        if ( (rc = pirq_guest_unbind(p1, chn1[port1].u.pirq)) == 0 )
    6.69 +            p1->pirq_to_evtchn[chn1[port1].u.pirq] = 0;
    6.70          break;
    6.71  
    6.72      case ECS_VIRQ:
    6.73 @@ -396,13 +434,19 @@ long do_event_channel_op(evtchn_op_t *uo
    6.74      {
    6.75      case EVTCHNOP_bind_interdomain:
    6.76          rc = evtchn_bind_interdomain(&op.u.bind_interdomain);
    6.77 -        if ( copy_to_user(uop, &op, sizeof(op)) != 0 )
    6.78 +        if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
    6.79              rc = -EFAULT; /* Cleaning up here would be a mess! */
    6.80          break;
    6.81  
    6.82      case EVTCHNOP_bind_virq:
    6.83          rc = evtchn_bind_virq(&op.u.bind_virq);
    6.84 -        if ( copy_to_user(uop, &op, sizeof(op)) != 0 )
    6.85 +        if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
    6.86 +            rc = -EFAULT; /* Cleaning up here would be a mess! */
    6.87 +        break;
    6.88 +
    6.89 +    case EVTCHNOP_bind_pirq:
    6.90 +        rc = evtchn_bind_pirq(&op.u.bind_pirq);
    6.91 +        if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
    6.92              rc = -EFAULT; /* Cleaning up here would be a mess! */
    6.93          break;
    6.94  
    6.95 @@ -416,7 +460,7 @@ long do_event_channel_op(evtchn_op_t *uo
    6.96  
    6.97      case EVTCHNOP_status:
    6.98          rc = evtchn_status(&op.u.status);
    6.99 -        if ( copy_to_user(uop, &op, sizeof(op)) != 0 )
   6.100 +        if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
   6.101              rc = -EFAULT;
   6.102          break;
   6.103  
     7.1 --- a/xen/common/physdev.c	Thu Mar 25 17:52:36 2004 +0000
     7.2 +++ b/xen/common/physdev.c	Fri Mar 26 15:20:56 2004 +0000
     7.3 @@ -65,26 +65,16 @@
     7.4  /* bit offsets into state */
     7.5  #define ST_BASE_ADDRESS  0   /* bits 0-5: are for base address access */
     7.6  #define ST_ROM_ADDRESS   6   /* bit 6: is for rom address access */    
     7.7 -#define ST_IRQ_DELIVERED 7   /* bit 7: waiting for end irq call */    
     7.8  
     7.9 -typedef struct _phys_dev_st
    7.10 -{
    7.11 +typedef struct _phys_dev_st {
    7.12      int flags;                       /* flags for access etc */
    7.13      struct pci_dev *dev;             /* the device */
    7.14      struct list_head node;           /* link to the list */
    7.15      struct task_struct *owner;       /* 'owner of this device' */
    7.16      int state;                       /* state for various checks */
    7.17 -
    7.18 -    hw_irq_controller *new_handler;  /* saved old handler */
    7.19 -    hw_irq_controller *orig_handler; /* saved old handler */
    7.20 -
    7.21  } phys_dev_t;
    7.22  
    7.23  
    7.24 -#define MAX_IRQS 32
    7.25 -/* an array of device descriptors index by IRQ number */
    7.26 -static phys_dev_t *irqs[MAX_IRQS];
    7.27 -
    7.28  /*
    7.29   * 
    7.30   * General functions
    7.31 @@ -573,201 +563,9 @@ static long pci_find_irq(int seg, int bu
    7.32      return 0;
    7.33  }
    7.34  
    7.35 -static void phys_dev_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
    7.36 -{
    7.37 -    phys_dev_t          *pdev;
    7.38  
    7.39 -    if ( (pdev = (phys_dev_t *)dev_id) == NULL )
    7.40 -    {
    7.41 -        printk("spurious interrupt, no proper device id, %d\n", irq);
    7.42 -        return;
    7.43 -    }
    7.44 -    
    7.45 -    /* XXX KAF: introduced race here? */
    7.46 -    set_bit(ST_IRQ_DELIVERED, &pdev->state);
    7.47 -    send_guest_pirq(pdev->owner, irq);
    7.48 -}
    7.49 -
    7.50 -/* this is called instead of the PICs original end handler. 
    7.51 - * the real end handler is only called once the guest signalled the handling
    7.52 - * of the event. */
    7.53 -static void end_virt_irq (unsigned int i)
    7.54 -{
    7.55 -    /* nothing */
    7.56 -}
    7.57 -
    7.58 -/*
    7.59 - * a guest request an IRQ from a device to be routed to it
    7.60 - * - shared interrupts are not allowed for now
    7.61 - * - we change the hw_irq handler to something else
    7.62 - */
    7.63 -static long pci_request_irq(int irq)
    7.64 +static long pci_unmask_irq(void)
    7.65  {
    7.66 -    int err;
    7.67 -    phys_dev_t *pdev = NULL, *t;
    7.68 -    hw_irq_controller *new, *orig;
    7.69 -    struct list_head *tmp;
    7.70 -
    7.71 -    printk("request irq %d\n", irq);
    7.72 -
    7.73 -    /* find pdev */
    7.74 -
    7.75 -    list_for_each(tmp, &current->pcidev_list)
    7.76 -    {
    7.77 -        t = list_entry(tmp,  phys_dev_t, node);
    7.78 -        if ( t->dev->irq == irq )
    7.79 -        {
    7.80 -            pdev = t;
    7.81 -            break;
    7.82 -        }
    7.83 -    }
    7.84 -
    7.85 -    if ( pdev == NULL )
    7.86 -    {
    7.87 -        printk("no device matching IRQ %d\n", irq);
    7.88 -        return -EINVAL;
    7.89 -    }
    7.90 -
    7.91 -    if ( irq >= MAX_IRQS )
    7.92 -    {
    7.93 -        printk("requested IRQ to big %d\n", irq);
    7.94 -        return -EINVAL;
    7.95 -    }
    7.96 -
    7.97 -    if ( irqs[irq] != NULL )
    7.98 -    {
    7.99 -        printk ("irq already in use %d\n", irq);
   7.100 -        return -EPERM;
   7.101 -    }
   7.102 -
   7.103 -    /* allocate a hw_irq controller and copy the original */
   7.104 -    if ( !(new  = kmalloc(sizeof(hw_irq_controller), GFP_KERNEL)) )
   7.105 -    {
   7.106 -        printf("error allocating new irq controller\n");
   7.107 -        return -ENOMEM;
   7.108 -    }
   7.109 -    orig = irq_desc[irq].handler;
   7.110 -    new->typename = orig->typename;
   7.111 -    new->startup = orig->startup;
   7.112 -    new->shutdown = orig->shutdown;
   7.113 -    new->enable = orig->enable;
   7.114 -    new->disable = orig->disable;
   7.115 -    new->ack = orig->ack;
   7.116 -    new->end = orig->end;
   7.117 -    new->set_affinity = orig->set_affinity;
   7.118 -
   7.119 -    /* swap the end routine */
   7.120 -    new->end = end_virt_irq;
   7.121 -
   7.122 -    /* change the irq controllers */
   7.123 -    pdev->orig_handler = orig;
   7.124 -    pdev->new_handler  = new;
   7.125 -    irq_desc[irq].handler = new;
   7.126 -    irqs[irq] = pdev;
   7.127 -    
   7.128 -    printk ("setup handler %d\n", irq);
   7.129 -
   7.130 -    /* request the IRQ. this is not shared and we use a slow handler! */
   7.131 -    err = request_irq(irq, phys_dev_interrupt, SA_INTERRUPT,
   7.132 -                      "foo", (void *)pdev);
   7.133 -    if ( err )
   7.134 -    {
   7.135 -        printk("error requesting irq\n");
   7.136 -        /* restore original */
   7.137 -        irq_desc[irq].handler = pdev->orig_handler;
   7.138 -        /* free memory */
   7.139 -        kfree(new);
   7.140 -        return err;
   7.141 -    }
   7.142 -
   7.143 -    printk ("done\n");
   7.144 -
   7.145 -    return 0;
   7.146 -}
   7.147 -
   7.148 -static long pci_free_irq(int irq)
   7.149 -{
   7.150 -    phys_dev_t *pdev;
   7.151 -
   7.152 -    if ( irq >= MAX_IRQS )
   7.153 -    {
   7.154 -        printk("requested IRQ to big %d\n", irq);
   7.155 -        return -EINVAL;
   7.156 -    }
   7.157 -
   7.158 -    if ( irqs[irq] == NULL )
   7.159 -    {
   7.160 -        printk ("irq not used %d\n", irq);
   7.161 -        return -EINVAL;
   7.162 -    }
   7.163 -
   7.164 -    pdev = irqs[irq];
   7.165 -
   7.166 -    /* shutdown IRQ */
   7.167 -    free_irq(irq, (void *)pdev);
   7.168 -
   7.169 -    /* restore irq controller  */
   7.170 -    irq_desc[irq].handler = pdev->orig_handler;
   7.171 -
   7.172 -    /* clean up */
   7.173 -    pdev->orig_handler = NULL;
   7.174 -    irqs[irq] = NULL;
   7.175 -    kfree(pdev->new_handler);
   7.176 -    pdev->new_handler = NULL;
   7.177 -
   7.178 -    printk("freed irq %d", irq);
   7.179 -    return 0;
   7.180 -}
   7.181 -
   7.182 -static long pci_enable_irq(int irq)
   7.183 -{
   7.184 -    /* XXX not sure we need this */
   7.185 -    /* guest can enable phys_irq event for now */
   7.186 -    return 0;
   7.187 -}
   7.188 -
   7.189 -static long pci_disable_irq(int irq)
   7.190 -{
   7.191 -    /* XXX not sure we need this */
   7.192 -    /* guest can disable phys_irq event for now */
   7.193 -    return 0;
   7.194 -}
   7.195 -
   7.196 -static long pci_finished_irq(int irq)
   7.197 -{
   7.198 -    phys_dev_t *pdev;
   7.199 -    
   7.200 -    if ( !(pdev = irqs[irq]) )
   7.201 -    {
   7.202 -        printk("finished_irq called for unregistered irq %d\n", irq);
   7.203 -        return -EINVAL;
   7.204 -    }
   7.205 -   
   7.206 -    if ( pdev->owner != current )
   7.207 -    {
   7.208 -        printk("finished_irq called dom not owning irq %d\n", irq);
   7.209 -        return -EPERM;
   7.210 -    }
   7.211 -
   7.212 -    if ( !test_bit(ST_IRQ_DELIVERED, &pdev->state) )
   7.213 -    {
   7.214 -        printk("finished_irq called for undelivered irq %d\n", irq);
   7.215 -        return -EINVAL;
   7.216 -    }
   7.217 -
   7.218 -#if 0 /* XXX KAF: do we need this? */
   7.219 -    if ( test_bit(irq, &current->shared_info->physirq_pend) )
   7.220 -    {
   7.221 -        printk("finished_irq called for un-acknowleged irq %d\n", irq);        
   7.222 -        return -EINVAL;
   7.223 -    }
   7.224 -#endif
   7.225 -
   7.226 -    clear_bit(ST_IRQ_DELIVERED, &pdev->state);
   7.227 -
   7.228 -    /* call original end handler */
   7.229 -    pdev->orig_handler->end(irq);
   7.230 -
   7.231      return 0;
   7.232  }
   7.233  
   7.234 @@ -786,43 +584,27 @@ long do_physdev_op(physdev_op_t *uop)
   7.235      switch ( op.cmd )
   7.236      {
   7.237      case PHYSDEVOP_CFGREG_READ:
   7.238 -        ret = pci_cfgreg_read (op.u.cfg_read.seg, op.u.cfg_read.bus,
   7.239 -                               op.u.cfg_read.dev, op.u.cfg_read.func,
   7.240 -                               op.u.cfg_read.reg, op.u.cfg_read.len,
   7.241 -                               &op.u.cfg_read.value);
   7.242 +        ret = pci_cfgreg_read(op.u.cfg_read.seg, op.u.cfg_read.bus,
   7.243 +                              op.u.cfg_read.dev, op.u.cfg_read.func,
   7.244 +                              op.u.cfg_read.reg, op.u.cfg_read.len,
   7.245 +                              &op.u.cfg_read.value);
   7.246          break;
   7.247  
   7.248      case PHYSDEVOP_CFGREG_WRITE:
   7.249 -        ret = pci_cfgreg_write (op.u.cfg_write.seg, op.u.cfg_write.bus,
   7.250 -                                op.u.cfg_write.dev, op.u.cfg_write.func,
   7.251 -                                op.u.cfg_write.reg, op.u.cfg_write.len,
   7.252 -                                op.u.cfg_write.value);
   7.253 +        ret = pci_cfgreg_write(op.u.cfg_write.seg, op.u.cfg_write.bus,
   7.254 +                               op.u.cfg_write.dev, op.u.cfg_write.func,
   7.255 +                               op.u.cfg_write.reg, op.u.cfg_write.len,
   7.256 +                               op.u.cfg_write.value);
   7.257          break;
   7.258  
   7.259      case PHYSDEVOP_FIND_IRQ:
   7.260 -        ret = pci_find_irq (op.u.find_irq.seg, op.u.find_irq.bus,
   7.261 -                            op.u.find_irq.dev, op.u.find_irq.func,
   7.262 -                            &op.u.find_irq.irq);
   7.263 -        break;
   7.264 -
   7.265 -    case PHYSDEVOP_REQUEST_IRQ:
   7.266 -        ret = pci_request_irq (op.u.request_irq.irq);
   7.267 +        ret = pci_find_irq(op.u.find_irq.seg, op.u.find_irq.bus,
   7.268 +                           op.u.find_irq.dev, op.u.find_irq.func,
   7.269 +                           &op.u.find_irq.irq);
   7.270          break;
   7.271  
   7.272 -    case PHYSDEVOP_FREE_IRQ:
   7.273 -        ret = pci_free_irq (op.u.free_irq.irq);
   7.274 -        break;
   7.275 -
   7.276 -    case PHYSDEVOP_ENABLE_IRQ:
   7.277 -        ret = pci_enable_irq (op.u.enable_irq.irq);
   7.278 -        break;
   7.279 -
   7.280 -    case PHYSDEVOP_DISABLE_IRQ:
   7.281 -        ret = pci_disable_irq (op.u.disable_irq.irq);
   7.282 -        break;
   7.283 -
   7.284 -    case PHYSDEVOP_FINISHED_IRQ:
   7.285 -        ret = pci_finished_irq (op.u.finished_irq.irq);
   7.286 +    case PHYSDEVOP_UNMASK_IRQ:
   7.287 +        ret = pci_unmask_irq();
   7.288          break;
   7.289  
   7.290      default:
     8.1 --- a/xen/drivers/char/console.c	Thu Mar 25 17:52:36 2004 +0000
     8.2 +++ b/xen/drivers/char/console.c	Fri Mar 26 15:20:56 2004 +0000
     8.3 @@ -227,8 +227,8 @@ long read_console_ring(unsigned long str
     8.4  static char serial_rx_ring[SERIAL_RX_SIZE];
     8.5  static unsigned int serial_rx_cons, serial_rx_prod;
     8.6  
     8.7 -/* CTRL-a switches input direction between Xen and DOM0. */
     8.8 -#define CTRL_A 0x01
     8.9 +/* CTRL-g switches input direction between Xen and DOM0. */
    8.10 +#define CTRL_G 0x07
    8.11  static int xen_rx = 1; /* FALSE => serial input passed to domain 0. */
    8.12  
    8.13  static void switch_serial_input(void)
    8.14 @@ -236,7 +236,7 @@ static void switch_serial_input(void)
    8.15      static char *input_str[2] = { "DOM0", "Xen" };
    8.16      xen_rx = !xen_rx;
    8.17      printk("*** Serial input -> %s "
    8.18 -           "(type 'CTRL-a' three times to switch input to %s).\n",
    8.19 +           "(type 'CTRL-g' three times to switch input to %s).\n",
    8.20             input_str[xen_rx], input_str[!xen_rx]);
    8.21  }
    8.22  
    8.23 @@ -264,22 +264,22 @@ static void __serial_rx(unsigned char c,
    8.24  
    8.25  static void serial_rx(unsigned char c, struct pt_regs *regs)
    8.26  {
    8.27 -    static int ctrl_a_count = 0;
    8.28 +    static int ctrl_g_count = 0;
    8.29  
    8.30 -    if ( c == CTRL_A )
    8.31 +    if ( c == CTRL_G )
    8.32      {
    8.33 -        /* We eat CTRL-a in groups of three to switch console input. */
    8.34 -        if ( ++ctrl_a_count == 3 )
    8.35 +        /* We eat CTRL-g in groups of three to switch console input. */
    8.36 +        if ( ++ctrl_g_count == 3 )
    8.37          {
    8.38              switch_serial_input();
    8.39 -            ctrl_a_count = 0;
    8.40 +            ctrl_g_count = 0;
    8.41          }
    8.42      }
    8.43      else
    8.44      {
    8.45 -        /* Flush any pending CTRL-a's. They weren't for us. */
    8.46 -        for ( ; ctrl_a_count != 0; ctrl_a_count-- )
    8.47 -            __serial_rx(CTRL_A, regs);
    8.48 +        /* Flush any pending CTRL-b's. They weren't for us. */
    8.49 +        for ( ; ctrl_g_count != 0; ctrl_g_count-- )
    8.50 +            __serial_rx(CTRL_G, regs);
    8.51          /* Finally process the just-received character. */
    8.52          __serial_rx(c, regs);
    8.53      }
     9.1 --- a/xen/include/asm-i386/irq.h	Thu Mar 25 17:52:36 2004 +0000
     9.2 +++ b/xen/include/asm-i386/irq.h	Fri Mar 26 15:20:56 2004 +0000
     9.3 @@ -192,10 +192,10 @@ extern unsigned long prof_shift;
     9.4  
     9.5  #include <xen/irq.h>
     9.6  
     9.7 -#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
     9.8 +#if defined(CONFIG_X86_IO_APIC)
     9.9  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
    9.10 -	if (IO_APIC_IRQ(i))
    9.11 -		send_IPI_self(IO_APIC_VECTOR(i));
    9.12 +        if (IO_APIC_IRQ(i))
    9.13 +                send_IPI_self(IO_APIC_VECTOR(i));
    9.14  }
    9.15  #else
    9.16  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
    10.1 --- a/xen/include/asm-x86_64/irq.h	Thu Mar 25 17:52:36 2004 +0000
    10.2 +++ b/xen/include/asm-x86_64/irq.h	Fri Mar 26 15:20:56 2004 +0000
    10.3 @@ -124,10 +124,10 @@ extern unsigned long prof_shift;
    10.4  
    10.5  #include <xen/irq.h>
    10.6  
    10.7 -#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
    10.8 +#if defined(CONFIG_X86_IO_APIC)
    10.9  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
   10.10 -	if (IO_APIC_IRQ(i))
   10.11 -		send_IPI_self(IO_APIC_VECTOR(i));
   10.12 +        if (IO_APIC_IRQ(i))
   10.13 +                send_IPI_self(IO_APIC_VECTOR(i));
   10.14  }
   10.15  #else
   10.16  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
    11.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h	Thu Mar 25 17:52:36 2004 +0000
    11.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h	Fri Mar 26 15:20:56 2004 +0000
    11.3 @@ -18,7 +18,7 @@
    11.4   * This makes sure that old versions of dom0 tools will stop working in a
    11.5   * well-defined way (rather than crashing the machine, for instance).
    11.6   */
    11.7 -#define DOM0_INTERFACE_VERSION   0xAAAA0009
    11.8 +#define DOM0_INTERFACE_VERSION   0xAAAA000A
    11.9  
   11.10  #define MAX_CMD_LEN       256
   11.11  #define MAX_DOMAIN_NAME    16
    12.1 --- a/xen/include/hypervisor-ifs/event_channel.h	Thu Mar 25 17:52:36 2004 +0000
    12.2 +++ b/xen/include/hypervisor-ifs/event_channel.h	Fri Mar 26 15:20:56 2004 +0000
    12.3 @@ -30,7 +30,7 @@ typedef struct evtchn_bind_interdomain
    12.4   * NOTES:
    12.5   *  1. A virtual IRQ may be bound to at most one event channel per domain.
    12.6   */
    12.7 -#define EVTCHNOP_bind_virq    1
    12.8 +#define EVTCHNOP_bind_virq        1
    12.9  typedef struct evtchn_bind_virq
   12.10  {
   12.11      /* IN parameters. */
   12.12 @@ -40,6 +40,21 @@ typedef struct evtchn_bind_virq
   12.13  } evtchn_bind_virq_t;
   12.14  
   12.15  /*
   12.16 + * EVTCHNOP_bind_pirq: Bind a local event channel to IRQ <irq>.
   12.17 + * NOTES:
   12.18 + *  1. A physical IRQ may be bound to at most one event channel per domain.
   12.19 + *  2. Only a sufficiently-privileged domain may bind to a physical IRQ.
   12.20 + */
   12.21 +#define EVTCHNOP_bind_pirq        2
   12.22 +typedef struct evtchn_bind_pirq
   12.23 +{
   12.24 +    /* IN parameters. */
   12.25 +    int pirq;
   12.26 +    /* OUT parameters. */
   12.27 +    int port;
   12.28 +} evtchn_bind_pirq_t;
   12.29 +
   12.30 +/*
   12.31   * EVTCHNOP_close: Close the communication channel which has an endpoint at
   12.32   * <dom, port>.
   12.33   * NOTES:
   12.34 @@ -47,7 +62,7 @@ typedef struct evtchn_bind_virq
   12.35   *  2. Only a sufficiently-privileged domain may close an event channel
   12.36   *     for which <dom> is not DOMID_SELF.
   12.37   */
   12.38 -#define EVTCHNOP_close            2
   12.39 +#define EVTCHNOP_close            3
   12.40  typedef struct evtchn_close
   12.41  {
   12.42      /* IN parameters. */
   12.43 @@ -60,7 +75,7 @@ typedef struct evtchn_close
   12.44   * EVTCHNOP_send: Send an event to the remote end of the channel whose local
   12.45   * endpoint is <DOMID_SELF, local_port>.
   12.46   */
   12.47 -#define EVTCHNOP_send             3
   12.48 +#define EVTCHNOP_send             4
   12.49  typedef struct evtchn_send
   12.50  {
   12.51      /* IN parameters. */
   12.52 @@ -76,7 +91,7 @@ typedef struct evtchn_send
   12.53   *  2. Only a sufficiently-privileged domain may obtain the status of an event
   12.54   *     channel for which <dom> is not DOMID_SELF.
   12.55   */
   12.56 -#define EVTCHNOP_status           4
   12.57 +#define EVTCHNOP_status           5
   12.58  typedef struct evtchn_status
   12.59  {
   12.60      /* IN parameters */
   12.61 @@ -86,8 +101,8 @@ typedef struct evtchn_status
   12.62  #define EVTCHNSTAT_closed       0  /* Chennel is not in use.                 */
   12.63  #define EVTCHNSTAT_unbound      1  /* Channel is not bound to a source.      */
   12.64  #define EVTCHNSTAT_interdomain  2  /* Channel is connected to remote domain. */
   12.65 -#define EVTCHNSTAT_pirq     3      /* Channel is bound to a phys IRQ line.   */
   12.66 -#define EVTCHNSTAT_virq     4      /* Channel is bound to a virtual IRQ line */
   12.67 +#define EVTCHNSTAT_pirq         3  /* Channel is bound to a phys IRQ line.   */
   12.68 +#define EVTCHNSTAT_virq         4  /* Channel is bound to a virtual IRQ line */
   12.69      int     status;
   12.70      union {
   12.71          int __none;    /* EVTCHNSTAT_closed, EVTCHNSTAT_unbound */
   12.72 @@ -106,6 +121,7 @@ typedef struct evtchn_op
   12.73      union {
   12.74          evtchn_bind_interdomain_t bind_interdomain;
   12.75          evtchn_bind_virq_t        bind_virq;
   12.76 +        evtchn_bind_pirq_t        bind_pirq;
   12.77          evtchn_close_t            close;
   12.78          evtchn_send_t             send;
   12.79          evtchn_status_t           status;
    13.1 --- a/xen/include/hypervisor-ifs/physdev.h	Thu Mar 25 17:52:36 2004 +0000
    13.2 +++ b/xen/include/hypervisor-ifs/physdev.h	Fri Mar 26 15:20:56 2004 +0000
    13.3 @@ -19,11 +19,7 @@
    13.4  #define PHYSDEVOP_CFGREG_READ   0
    13.5  #define PHYSDEVOP_CFGREG_WRITE  1
    13.6  #define PHYSDEVOP_FIND_IRQ      2
    13.7 -#define PHYSDEVOP_REQUEST_IRQ   3
    13.8 -#define PHYSDEVOP_FREE_IRQ      4
    13.9 -#define PHYSDEVOP_ENABLE_IRQ    5
   13.10 -#define PHYSDEVOP_DISABLE_IRQ   6
   13.11 -#define PHYSDEVOP_FINISHED_IRQ  7
   13.12 +#define PHYSDEVOP_UNMASK_IRQ    3
   13.13  
   13.14  /* read pci config */
   13.15  typedef struct physdevop_cfgreg_read_st
   13.16 @@ -32,8 +28,8 @@ typedef struct physdevop_cfgreg_read_st
   13.17      int bus;        /* IN */
   13.18      int dev;        /* IN */
   13.19      int func;       /* IN */
   13.20 -    int reg;        /* IN  */
   13.21 -    int len;        /* IN  */
   13.22 +    int reg;        /* IN */
   13.23 +    int len;        /* IN */
   13.24      u32 value;      /* OUT */
   13.25  } physdevop_cfgreg_read_t;
   13.26  
   13.27 @@ -59,36 +55,6 @@ typedef struct physdevop_find_irq_st
   13.28      u32 irq;      /* OUT */
   13.29  } physdevop_find_irq_t;
   13.30  
   13.31 -/* request physical IRQ to be routed to guest */
   13.32 -typedef struct physdevop_request_irq_st
   13.33 -{
   13.34 -    u32 irq;      /* IN */
   13.35 -} physdevop_request_irq_t;
   13.36 -
   13.37 -/* stop routing physical interrupts to guest */
   13.38 -typedef struct physdevop_free_irq_st
   13.39 -{
   13.40 -    u32 irq;      /* IN */
   13.41 -} physdevop_free_irq_t;
   13.42 -
   13.43 -/* enable IRQ for the caller  */
   13.44 -typedef struct physdevop_enable_irq_st
   13.45 -{
   13.46 -    u32 irq;      /* IN */
   13.47 -} physdevop_enable_irq_t;
   13.48 -
   13.49 -/* disable interrupts */
   13.50 -typedef struct physdevop_disable_irq_st
   13.51 -{
   13.52 -    u32 irq;      /* IN */
   13.53 -} physdevop_disable_irq_t;
   13.54 -
   13.55 -typedef struct physdevop_finished_irq_st
   13.56 -{
   13.57 -    u32 irq;      /* IN */
   13.58 -} physdevop_finished_irq_t;
   13.59 -
   13.60 -
   13.61  typedef struct _physdev_op_st 
   13.62  {
   13.63      unsigned long cmd;
   13.64 @@ -99,11 +65,6 @@ typedef struct _physdev_op_st
   13.65          physdevop_cfgreg_read_t  cfg_read;
   13.66          physdevop_cfgreg_write_t cfg_write;
   13.67          physdevop_find_irq_t     find_irq;
   13.68 -        physdevop_request_irq_t  request_irq;
   13.69 -        physdevop_free_irq_t     free_irq;
   13.70 -        physdevop_enable_irq_t   enable_irq;
   13.71 -        physdevop_disable_irq_t  disable_irq;
   13.72 -        physdevop_finished_irq_t finished_irq;
   13.73      } u;
   13.74  } physdev_op_t;
   13.75  
    14.1 --- a/xen/include/xen/interrupt.h	Thu Mar 25 17:52:36 2004 +0000
    14.2 +++ b/xen/include/xen/interrupt.h	Fri Mar 26 15:20:56 2004 +0000
    14.3 @@ -16,7 +16,7 @@ typedef void irqreturn_t;
    14.4  #define IRQ_NONE
    14.5  #define IRQ_HANDLED
    14.6  #define IRQ_RETVAL(x)
    14.7 -                                                                                
    14.8 +
    14.9  struct irqaction {
   14.10  	void (*handler)(int, void *, struct pt_regs *);
   14.11  	unsigned long flags;
   14.12 @@ -26,7 +26,6 @@ struct irqaction {
   14.13  	struct irqaction *next;
   14.14  };
   14.15  
   14.16 -
   14.17  enum {
   14.18  	TIMER_BH = 0,
   14.19  	SCSI_BH
    15.1 --- a/xen/include/xen/irq.h	Thu Mar 25 17:52:36 2004 +0000
    15.2 +++ b/xen/include/xen/irq.h	Fri Mar 26 15:20:56 2004 +0000
    15.3 @@ -1,5 +1,5 @@
    15.4 -#ifndef __irq_h
    15.5 -#define __irq_h
    15.6 +#ifndef __XEN_IRQ_H__
    15.7 +#define __XEN_IRQ_H__
    15.8  
    15.9  #include <xen/config.h>
   15.10  #include <xen/spinlock.h>
   15.11 @@ -14,26 +14,24 @@
   15.12  #define IRQ_REPLAY	8	/* IRQ has been replayed but not acked yet */
   15.13  #define IRQ_AUTODETECT	16	/* IRQ is being autodetected */
   15.14  #define IRQ_WAITING	32	/* IRQ not yet seen - for autodetection */
   15.15 -#define IRQ_LEVEL	64	/* IRQ level triggered */
   15.16 -#define IRQ_MASKED	128	/* IRQ masked - shouldn't be seen again */
   15.17 -#define IRQ_PER_CPU	256	/* IRQ is per CPU */
   15.18 +#define IRQ_GUEST       64      /* IRQ is handled by guest OS(es) */
   15.19  
   15.20  /*
   15.21   * Interrupt controller descriptor. This is all we need
   15.22   * to describe about the low-level hardware. 
   15.23   */
   15.24  struct hw_interrupt_type {
   15.25 -	const char * typename;
   15.26 -	unsigned int (*startup)(unsigned int irq);
   15.27 -	void (*shutdown)(unsigned int irq);
   15.28 -	void (*enable)(unsigned int irq);
   15.29 -	void (*disable)(unsigned int irq);
   15.30 -	void (*ack)(unsigned int irq);
   15.31 -	void (*end)(unsigned int irq);
   15.32 -	void (*set_affinity)(unsigned int irq, unsigned long mask);
   15.33 +    const char *typename;
   15.34 +    unsigned int (*startup)(unsigned int irq);
   15.35 +    void (*shutdown)(unsigned int irq);
   15.36 +    void (*enable)(unsigned int irq);
   15.37 +    void (*disable)(unsigned int irq);
   15.38 +    void (*ack)(unsigned int irq);
   15.39 +    void (*end)(unsigned int irq);
   15.40 +    void (*set_affinity)(unsigned int irq, unsigned long mask);
   15.41  };
   15.42  
   15.43 -typedef struct hw_interrupt_type  hw_irq_controller;
   15.44 +typedef struct hw_interrupt_type hw_irq_controller;
   15.45  
   15.46  #include <asm/irq.h>
   15.47  
   15.48 @@ -45,19 +43,22 @@ typedef struct hw_interrupt_type  hw_irq
   15.49   * Pad this out to 32 bytes for cache and indexing reasons.
   15.50   */
   15.51  typedef struct {
   15.52 -	unsigned int status;		/* IRQ status */
   15.53 -	hw_irq_controller *handler;
   15.54 -	struct irqaction *action;	/* IRQ action list */
   15.55 -	unsigned int depth;		/* nested irq disables */
   15.56 -	spinlock_t lock;
   15.57 +    unsigned int status;		/* IRQ status */
   15.58 +    hw_irq_controller *handler;
   15.59 +    struct irqaction *action;	/* IRQ action list */
   15.60 +    unsigned int depth;		/* nested irq disables */
   15.61 +    spinlock_t lock;
   15.62  } ____cacheline_aligned irq_desc_t;
   15.63  
   15.64 -extern irq_desc_t irq_desc [NR_IRQS];
   15.65 +extern irq_desc_t irq_desc[NR_IRQS];
   15.66  
   15.67 -extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
   15.68 -extern int setup_irq(unsigned int , struct irqaction * );
   15.69 +extern int setup_irq(unsigned int, struct irqaction *);
   15.70  
   15.71 -extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
   15.72 +extern hw_irq_controller no_irq_type;
   15.73  extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
   15.74  
   15.75 -#endif /* __asm_h */
   15.76 +struct task_struct;
   15.77 +extern int pirq_guest_bind(struct task_struct *p, int irq);
   15.78 +extern int pirq_guest_unbind(struct task_struct *p, int irq);
   15.79 +
   15.80 +#endif /* __XEN_IRQ_H__ */
    16.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/Makefile	Thu Mar 25 17:52:36 2004 +0000
    16.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/Makefile	Fri Mar 26 15:20:56 2004 +0000
    16.3 @@ -10,7 +10,7 @@ export-objs     := i386_ksyms.o
    16.4  
    16.5  obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o  \
    16.6  		ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o \
    16.7 -		i386_ksyms.o i387.o evtchn.o physirq.o pci-dma.o
    16.8 +		i386_ksyms.o i387.o evtchn.o pci-dma.o
    16.9  
   16.10  ifdef CONFIG_PCI
   16.11  obj-y	+= pci-i386.o pci-pc.o pci-irq.o
    17.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c	Thu Mar 25 17:52:36 2004 +0000
    17.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c	Fri Mar 26 15:20:56 2004 +0000
    17.3 @@ -17,20 +17,23 @@
    17.4  #include <asm/synch_bitops.h>
    17.5  #include <asm/hypervisor.h>
    17.6  #include <asm/hypervisor-ifs/event_channel.h>
    17.7 -
    17.8 -/* Dynamic IRQ <-> event-channel mappings. */
    17.9 -static int evtchn_to_dynirq[1024];
   17.10 -static int dynirq_to_evtchn[NR_IRQS];
   17.11 -
   17.12 -/* Dynamic IRQ <-> VIRQ mapping. */
   17.13 -static int virq_to_dynirq[NR_VIRQS];
   17.14 +#include <asm/hypervisor-ifs/physdev.h>
   17.15  
   17.16  /*
   17.17 - * Reference counts for bindings to dynamic IRQs.
   17.18 - * NB. This array is referenced with respect to DYNIRQ_BASE!
   17.19 + * This lock protects updates to the following mapping and reference-count
   17.20 + * arrays. The lock does not need to be acquired to read the mapping tables.
   17.21   */
   17.22 -static int dynirq_bindcount[NR_DYNIRQS];
   17.23 -static spinlock_t dynirq_lock;
   17.24 +static spinlock_t irq_mapping_update_lock;
   17.25 +
   17.26 +/* IRQ <-> event-channel mappings. */
   17.27 +static int evtchn_to_irq[NR_EVENT_CHANNELS];
   17.28 +static int irq_to_evtchn[NR_IRQS];
   17.29 +
   17.30 +/* IRQ <-> VIRQ mapping. */
   17.31 +static int virq_to_irq[NR_VIRQS];
   17.32 +
   17.33 +/* Reference counts for bindings to IRQs. */
   17.34 +static int irq_bindcount[NR_IRQS];
   17.35  
   17.36  /* Upcall to generic IRQ layer. */
   17.37  extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
   17.38 @@ -39,7 +42,7 @@ static void evtchn_handle_normal(shared_
   17.39  {
   17.40      unsigned long l1, l2;
   17.41      unsigned int  l1i, l2i, port;
   17.42 -    int           dynirq;
   17.43 +    int           irq;
   17.44  
   17.45      l1 = xchg(&s->evtchn_pending_sel, 0);
   17.46      while ( (l1i = ffs(l1)) != 0 )
   17.47 @@ -54,8 +57,8 @@ static void evtchn_handle_normal(shared_
   17.48              l2 &= ~(1 << l2i);
   17.49              
   17.50              port = (l1i << 5) + l2i;
   17.51 -            if ( (dynirq = evtchn_to_dynirq[port]) != -1 )
   17.52 -                do_IRQ(dynirq + DYNIRQ_BASE, regs);
   17.53 +            if ( (irq = evtchn_to_irq[port]) != -1 )
   17.54 +                do_IRQ(irq, regs);
   17.55              else
   17.56                  evtchn_device_upcall(port, 0);
   17.57          }
   17.58 @@ -66,7 +69,7 @@ static void evtchn_handle_exceptions(sha
   17.59  {
   17.60      unsigned long l1, l2;
   17.61      unsigned int  l1i, l2i, port;
   17.62 -    int           dynirq;
   17.63 +    int           irq;
   17.64  
   17.65      l1 = xchg(&s->evtchn_exception_sel, 0);
   17.66      while ( (l1i = ffs(l1)) != 0 )
   17.67 @@ -81,10 +84,9 @@ static void evtchn_handle_exceptions(sha
   17.68              l2 &= ~(1 << l2i);
   17.69              
   17.70              port = (l1i << 5) + l2i;
   17.71 -            if ( (dynirq = evtchn_to_dynirq[port]) != -1 )
   17.72 +            if ( (irq = evtchn_to_irq[port]) != -1 )
   17.73              {
   17.74 -                printk(KERN_ALERT "Error on IRQ line %d!\n", 
   17.75 -                       dynirq + DYNIRQ_BASE);
   17.76 +                printk(KERN_ALERT "Error on IRQ line %d!\n", irq);
   17.77                  synch_clear_bit(port, &s->evtchn_exception[0]);
   17.78              }
   17.79              else
   17.80 @@ -112,28 +114,28 @@ void evtchn_do_upcall(struct pt_regs *re
   17.81  }
   17.82  
   17.83  
   17.84 -static int find_unbound_dynirq(void)
   17.85 +static int find_unbound_irq(void)
   17.86  {
   17.87 -    int i;
   17.88 +    int irq;
   17.89  
   17.90 -    for ( i = 0; i < NR_DYNIRQS; i++ )
   17.91 -        if ( dynirq_bindcount[i] == 0 )
   17.92 +    for ( irq = 0; irq < NR_IRQS; irq++ )
   17.93 +        if ( irq_bindcount[irq] == 0 )
   17.94              break;
   17.95  
   17.96 -    if ( i == NR_DYNIRQS )
   17.97 +    if ( irq == NR_IRQS )
   17.98          BUG();
   17.99  
  17.100 -    return i;
  17.101 +    return irq;
  17.102  }
  17.103  
  17.104  int bind_virq_to_irq(int virq)
  17.105  {
  17.106      evtchn_op_t op;
  17.107 -    int evtchn, dynirq;
  17.108 +    int evtchn, irq;
  17.109  
  17.110 -    spin_lock(&dynirq_lock);
  17.111 +    spin_lock(&irq_mapping_update_lock);
  17.112  
  17.113 -    if ( (dynirq = virq_to_dynirq[virq]) == -1 )
  17.114 +    if ( (irq = virq_to_irq[virq]) == -1 )
  17.115      {
  17.116          op.cmd              = EVTCHNOP_bind_virq;
  17.117          op.u.bind_virq.virq = virq;
  17.118 @@ -141,29 +143,29 @@ int bind_virq_to_irq(int virq)
  17.119              BUG();
  17.120          evtchn = op.u.bind_virq.port;
  17.121  
  17.122 -        dynirq = find_unbound_dynirq();
  17.123 -        evtchn_to_dynirq[evtchn] = dynirq;
  17.124 -        dynirq_to_evtchn[dynirq] = evtchn;
  17.125 +        irq = find_unbound_irq();
  17.126 +        evtchn_to_irq[evtchn] = irq;
  17.127 +        irq_to_evtchn[irq]    = evtchn;
  17.128  
  17.129 -        virq_to_dynirq[virq] = dynirq;
  17.130 +        virq_to_irq[virq] = irq;
  17.131      }
  17.132  
  17.133 -    dynirq_bindcount[dynirq]++;
  17.134 +    irq_bindcount[irq]++;
  17.135  
  17.136 -    spin_unlock(&dynirq_lock);
  17.137 +    spin_unlock(&irq_mapping_update_lock);
  17.138      
  17.139 -    return dynirq + DYNIRQ_BASE;
  17.140 +    return irq;
  17.141  }
  17.142  
  17.143  void unbind_virq_from_irq(int virq)
  17.144  {
  17.145      evtchn_op_t op;
  17.146 -    int dynirq = virq_to_dynirq[virq];
  17.147 -    int evtchn = dynirq_to_evtchn[dynirq];
  17.148 +    int irq    = virq_to_irq[virq];
  17.149 +    int evtchn = irq_to_evtchn[irq];
  17.150  
  17.151 -    spin_lock(&dynirq_lock);
  17.152 +    spin_lock(&irq_mapping_update_lock);
  17.153  
  17.154 -    if ( --dynirq_bindcount[dynirq] == 0 )
  17.155 +    if ( --irq_bindcount[irq] == 0 )
  17.156      {
  17.157          op.cmd          = EVTCHNOP_close;
  17.158          op.u.close.dom  = DOMID_SELF;
  17.159 @@ -171,47 +173,47 @@ void unbind_virq_from_irq(int virq)
  17.160          if ( HYPERVISOR_event_channel_op(&op) != 0 )
  17.161              BUG();
  17.162  
  17.163 -        evtchn_to_dynirq[evtchn] = -1;
  17.164 -        dynirq_to_evtchn[dynirq] = -1;
  17.165 -        virq_to_dynirq[virq]     = -1;
  17.166 +        evtchn_to_irq[evtchn] = -1;
  17.167 +        irq_to_evtchn[irq]    = -1;
  17.168 +        virq_to_irq[virq]     = -1;
  17.169      }
  17.170  
  17.171 -    spin_unlock(&dynirq_lock);
  17.172 +    spin_unlock(&irq_mapping_update_lock);
  17.173  }
  17.174  
  17.175  int bind_evtchn_to_irq(int evtchn)
  17.176  {
  17.177 -    int dynirq;
  17.178 +    int irq;
  17.179  
  17.180 -    spin_lock(&dynirq_lock);
  17.181 +    spin_lock(&irq_mapping_update_lock);
  17.182  
  17.183 -    if ( (dynirq = evtchn_to_dynirq[evtchn]) == -1 )
  17.184 +    if ( (irq = evtchn_to_irq[evtchn]) == -1 )
  17.185      {
  17.186 -        dynirq = find_unbound_dynirq();
  17.187 -        evtchn_to_dynirq[evtchn] = dynirq;
  17.188 -        dynirq_to_evtchn[dynirq] = evtchn;
  17.189 +        irq = find_unbound_irq();
  17.190 +        evtchn_to_irq[evtchn] = irq;
  17.191 +        irq_to_evtchn[irq]    = evtchn;
  17.192      }
  17.193  
  17.194 -    dynirq_bindcount[dynirq]++;
  17.195 +    irq_bindcount[irq]++;
  17.196  
  17.197 -    spin_unlock(&dynirq_lock);
  17.198 +    spin_unlock(&irq_mapping_update_lock);
  17.199      
  17.200 -    return dynirq + DYNIRQ_BASE;
  17.201 +    return irq;
  17.202  }
  17.203  
  17.204  void unbind_evtchn_from_irq(int evtchn)
  17.205  {
  17.206 -    int dynirq = evtchn_to_dynirq[evtchn];
  17.207 +    int irq = evtchn_to_irq[evtchn];
  17.208  
  17.209 -    spin_lock(&dynirq_lock);
  17.210 +    spin_lock(&irq_mapping_update_lock);
  17.211  
  17.212 -    if ( --dynirq_bindcount[dynirq] == 0 )
  17.213 +    if ( --irq_bindcount[irq] == 0 )
  17.214      {
  17.215 -        evtchn_to_dynirq[evtchn] = -1;
  17.216 -        dynirq_to_evtchn[dynirq] = -1;
  17.217 +        evtchn_to_irq[evtchn] = -1;
  17.218 +        irq_to_evtchn[irq]    = -1;
  17.219      }
  17.220  
  17.221 -    spin_unlock(&dynirq_lock);
  17.222 +    spin_unlock(&irq_mapping_update_lock);
  17.223  }
  17.224  
  17.225  
  17.226 @@ -221,41 +223,35 @@ void unbind_evtchn_from_irq(int evtchn)
  17.227  
  17.228  static unsigned int startup_dynirq(unsigned int irq)
  17.229  {
  17.230 -    int dynirq = irq - DYNIRQ_BASE;
  17.231 -    unmask_evtchn(dynirq_to_evtchn[dynirq]);
  17.232 +    unmask_evtchn(irq_to_evtchn[irq]);
  17.233      return 0;
  17.234  }
  17.235  
  17.236  static void shutdown_dynirq(unsigned int irq)
  17.237  {
  17.238 -    int dynirq = irq - DYNIRQ_BASE;
  17.239 -    mask_evtchn(dynirq_to_evtchn[dynirq]);
  17.240 +    mask_evtchn(irq_to_evtchn[irq]);
  17.241  }
  17.242  
  17.243  static void enable_dynirq(unsigned int irq)
  17.244  {
  17.245 -    int dynirq = irq - DYNIRQ_BASE;
  17.246 -    unmask_evtchn(dynirq_to_evtchn[dynirq]);
  17.247 +    unmask_evtchn(irq_to_evtchn[irq]);
  17.248  }
  17.249  
  17.250  static void disable_dynirq(unsigned int irq)
  17.251  {
  17.252 -    int dynirq = irq - DYNIRQ_BASE;
  17.253 -    mask_evtchn(dynirq_to_evtchn[dynirq]);
  17.254 +    mask_evtchn(irq_to_evtchn[irq]);
  17.255  }
  17.256  
  17.257  static void ack_dynirq(unsigned int irq)
  17.258  {
  17.259 -    int dynirq = irq - DYNIRQ_BASE;
  17.260 -    mask_evtchn(dynirq_to_evtchn[dynirq]);
  17.261 -    clear_evtchn(dynirq_to_evtchn[dynirq]);
  17.262 +    mask_evtchn(irq_to_evtchn[irq]);
  17.263 +    clear_evtchn(irq_to_evtchn[irq]);
  17.264  }
  17.265  
  17.266  static void end_dynirq(unsigned int irq)
  17.267  {
  17.268 -    int dynirq = irq - DYNIRQ_BASE;
  17.269      if ( !(irq_desc[irq].status & IRQ_DISABLED) )
  17.270 -        unmask_evtchn(dynirq_to_evtchn[dynirq]);
  17.271 +        unmask_evtchn(irq_to_evtchn[irq]);
  17.272  }
  17.273  
  17.274  static struct hw_interrupt_type dynirq_type = {
  17.275 @@ -269,6 +265,87 @@ static struct hw_interrupt_type dynirq_t
  17.276      NULL
  17.277  };
  17.278  
  17.279 +static inline void pirq_unmask_notify(int pirq)
  17.280 +{
  17.281 +    physdev_op_t op;
  17.282 +    op.cmd = PHYSDEVOP_UNMASK_IRQ;
  17.283 +    (void)HYPERVISOR_physdev_op(&op);
  17.284 +}
  17.285 +
  17.286 +static unsigned int startup_pirq(unsigned int irq)
  17.287 +{
  17.288 +    evtchn_op_t op;
  17.289 +    int evtchn;
  17.290 +
  17.291 +    op.cmd              = EVTCHNOP_bind_pirq;
  17.292 +    op.u.bind_pirq.pirq = irq;
  17.293 +    if ( HYPERVISOR_event_channel_op(&op) != 0 )
  17.294 +        BUG();
  17.295 +    evtchn = op.u.bind_virq.port;
  17.296 +
  17.297 +    evtchn_to_irq[evtchn] = irq;
  17.298 +    irq_to_evtchn[irq]    = evtchn;
  17.299 +
  17.300 +    unmask_evtchn(evtchn);
  17.301 +    pirq_unmask_notify(irq_to_pirq(irq));
  17.302 +
  17.303 +    return 0;
  17.304 +}
  17.305 +
  17.306 +static void shutdown_pirq(unsigned int irq)
  17.307 +{
  17.308 +    evtchn_op_t op;
  17.309 +    int evtchn = irq_to_evtchn[irq];
  17.310 +
  17.311 +    mask_evtchn(evtchn);
  17.312 +
  17.313 +    op.cmd          = EVTCHNOP_close;
  17.314 +    op.u.close.dom  = DOMID_SELF;
  17.315 +    op.u.close.port = evtchn;
  17.316 +    if ( HYPERVISOR_event_channel_op(&op) != 0 )
  17.317 +        BUG();
  17.318 +
  17.319 +    evtchn_to_irq[evtchn] = -1;
  17.320 +    irq_to_evtchn[irq]    = -1;
  17.321 +}
  17.322 +
  17.323 +static void enable_pirq(unsigned int irq)
  17.324 +{
  17.325 +    unmask_evtchn(irq_to_evtchn[irq]);
  17.326 +    pirq_unmask_notify(irq_to_pirq(irq));
  17.327 +}
  17.328 +
  17.329 +static void disable_pirq(unsigned int irq)
  17.330 +{
  17.331 +    mask_evtchn(irq_to_evtchn[irq]);
  17.332 +}
  17.333 +
  17.334 +static void ack_pirq(unsigned int irq)
  17.335 +{
  17.336 +    mask_evtchn(irq_to_evtchn[irq]);
  17.337 +    clear_evtchn(irq_to_evtchn[irq]);
  17.338 +}
  17.339 +
  17.340 +static void end_pirq(unsigned int irq)
  17.341 +{
  17.342 +    if ( !(irq_desc[irq].status & IRQ_DISABLED) )
  17.343 +    {
  17.344 +        unmask_evtchn(irq_to_evtchn[irq]);
  17.345 +        pirq_unmask_notify(irq_to_pirq(irq));
  17.346 +    }
  17.347 +}
  17.348 +
  17.349 +static struct hw_interrupt_type pirq_type = {
  17.350 +    "Phys-irq",
  17.351 +    startup_pirq,
  17.352 +    shutdown_pirq,
  17.353 +    enable_pirq,
  17.354 +    disable_pirq,
  17.355 +    ack_pirq,
  17.356 +    end_pirq,
  17.357 +    NULL
  17.358 +};
  17.359 +
  17.360  static void error_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  17.361  {
  17.362      printk(KERN_ALERT "unexpected VIRQ_ERROR trap to vector %d\n", irq);
  17.363 @@ -287,32 +364,41 @@ void __init init_IRQ(void)
  17.364  {
  17.365      int i;
  17.366  
  17.367 +    spin_lock_init(&irq_mapping_update_lock);
  17.368 +
  17.369 +    /* No VIRQ -> IRQ mappings. */
  17.370      for ( i = 0; i < NR_VIRQS; i++ )
  17.371 -        virq_to_dynirq[i] = -1;
  17.372 +        virq_to_irq[i] = -1;
  17.373  
  17.374 -    for ( i = 0; i < 1024; i++ )
  17.375 -        evtchn_to_dynirq[i] = -1;
  17.376 +    /* No event-channel -> IRQ mappings. */
  17.377 +    for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
  17.378 +        evtchn_to_irq[i] = -1;
  17.379 +
  17.380 +    /* No IRQ -> event-channel mappings. */
  17.381 +    for ( i = 0; i < NR_IRQS; i++ )
  17.382 +        irq_to_evtchn[i] = -1;
  17.383  
  17.384      for ( i = 0; i < NR_DYNIRQS; i++ )
  17.385      {
  17.386 -        dynirq_to_evtchn[i] = -1;
  17.387 -        dynirq_bindcount[i] = 0;
  17.388 +        /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
  17.389 +        irq_bindcount[dynirq_to_irq(i)] = 0;
  17.390 +
  17.391 +        irq_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;
  17.392 +        irq_desc[dynirq_to_irq(i)].action  = 0;
  17.393 +        irq_desc[dynirq_to_irq(i)].depth   = 1;
  17.394 +        irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
  17.395      }
  17.396  
  17.397 -    spin_lock_init(&dynirq_lock);
  17.398 -
  17.399 -    for ( i = 0; i < NR_DYNIRQS; i++ )
  17.400 +    for ( i = 0; i < NR_PIRQS; i++ )
  17.401      {
  17.402 -        irq_desc[i + DYNIRQ_BASE].status  = IRQ_DISABLED;
  17.403 -        irq_desc[i + DYNIRQ_BASE].action  = 0;
  17.404 -        irq_desc[i + DYNIRQ_BASE].depth   = 1;
  17.405 -        irq_desc[i + DYNIRQ_BASE].handler = &dynirq_type;
  17.406 +        /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
  17.407 +        irq_bindcount[pirq_to_irq(i)] = 1;
  17.408 +
  17.409 +        irq_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;
  17.410 +        irq_desc[pirq_to_irq(i)].action  = 0;
  17.411 +        irq_desc[pirq_to_irq(i)].depth   = 1;
  17.412 +        irq_desc[pirq_to_irq(i)].handler = &pirq_type;
  17.413      }
  17.414  
  17.415      (void)setup_irq(bind_virq_to_irq(VIRQ_ERROR), &error_action);
  17.416 -    
  17.417 -#ifdef CONFIG_PCI
  17.418 -    /* Also initialise the physical IRQ handlers. */
  17.419 -    physirq_init();
  17.420 -#endif
  17.421  }
    18.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/physirq.c	Thu Mar 25 17:52:36 2004 +0000
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,175 +0,0 @@
    18.4 -/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
    18.5 - ****************************************************************************
    18.6 - * (C) 2004 - Rolf Neugebauer - Intel Research Cambridge
    18.7 - ****************************************************************************
    18.8 - *
    18.9 - *        File: physirq.c
   18.10 - *      Author: Rolf Neugebauer (rolf.neugebauer@intel.com)
   18.11 - *        Date: Mar 2004
   18.12 - * 
   18.13 - * Description: guests may receive virtual interrupts directly 
   18.14 - *              corresponding to physical interrupts. these virtual
   18.15 - *              interrupts require special handling provided 
   18.16 - *              by the virq irq type.
   18.17 - */
   18.18 -
   18.19 -#ifdef CONFIG_PCI
   18.20 -
   18.21 -#include <linux/config.h>
   18.22 -#include <asm/atomic.h>
   18.23 -#include <asm/irq.h>
   18.24 -#include <asm/hypervisor.h>
   18.25 -#include <asm/system.h>
   18.26 -
   18.27 -#include <linux/irq.h>
   18.28 -#include <linux/sched.h>
   18.29 -
   18.30 -#include <asm/hypervisor-ifs/hypervisor-if.h>
   18.31 -#include <asm/hypervisor-ifs/physdev.h>
   18.32 -
   18.33 -static void physirq_interrupt(int irq, void *unused, struct pt_regs *ptregs);
   18.34 -
   18.35 -static int setup_event_handler = 0;
   18.36 -
   18.37 -static unsigned int startup_physirq_event(unsigned int irq)
   18.38 -{
   18.39 -    physdev_op_t op;
   18.40 -    int err;
   18.41 -
   18.42 -    printk("startup_physirq_event %d\n", irq);
   18.43 -
   18.44 -    /*
   18.45 -     * install a interrupt handler for physirq event when called first time
   18.46 -     * we actually are never executing the handler as _EVENT_PHYSIRQ is 
   18.47 -     * handled specially in hypervisor.c But we need to enable the event etc.
   18.48 -     */
   18.49 -    if ( !setup_event_handler )
   18.50 -    {
   18.51 -        printk("startup_physirq_event %d: setup event handler\n", irq);
   18.52 -        /* set up a event handler to demux virtualised physical interrupts */
   18.53 -        err = request_irq(IRQ_FROM_XEN_VIRQ(VIRQ_PHYSIRQ), physirq_interrupt, 
   18.54 -                          SA_SAMPLE_RANDOM, "physirq", NULL);
   18.55 -        if ( err )
   18.56 -        {
   18.57 -            printk(KERN_WARNING "Could not allocate physirq interrupt\n");
   18.58 -            return err;
   18.59 -        }
   18.60 -        setup_event_handler = 1;
   18.61 -    }
   18.62 -
   18.63 -    /*
   18.64 -     * request the irq from hypervisor
   18.65 -     */
   18.66 -    op.cmd = PHYSDEVOP_REQUEST_IRQ;
   18.67 -    op.u.request_irq.irq   = irq;
   18.68 -    if ( (err = HYPERVISOR_physdev_op(&op)) != 0 )
   18.69 -    {
   18.70 -        printk(KERN_ALERT "could not get IRQ %d from Xen\n", irq);
   18.71 -        return err;
   18.72 -    }
   18.73 -    return 0;
   18.74 -}
   18.75 -/*
   18.76 - * This is a dummy interrupt handler.
   18.77 - * It should never be called. events for physical interrupts are handled
   18.78 - * differently in hypervisor.c
   18.79 - */
   18.80 -static void physirq_interrupt(int irq, void *unused, struct pt_regs *ptregs)
   18.81 -{
   18.82 -    printk("XXX This should never be called!");
   18.83 -}
   18.84 -
   18.85 -
   18.86 -/*
   18.87 - * IRQ is not needed anymore.
   18.88 - */
   18.89 -static void shutdown_physirq_event(unsigned int irq)
   18.90 -{
   18.91 -    physdev_op_t op;
   18.92 -    int err;
   18.93 -
   18.94 -    printk("shutdown_phys_irq called.");
   18.95 -
   18.96 -    /*
   18.97 -     * tell hypervisor
   18.98 -     */
   18.99 -    op.cmd = PHYSDEVOP_FREE_IRQ;
  18.100 -    op.u.free_irq.irq   = irq;
  18.101 -    if ( (err = HYPERVISOR_physdev_op(&op)) != 0 )
  18.102 -    {
  18.103 -        printk(KERN_ALERT "could not free IRQ %d\n", irq);
  18.104 -        return;
  18.105 -    }
  18.106 -    return;
  18.107 -}
  18.108 -
  18.109 -
  18.110 -static void enable_physirq_event(unsigned int irq)
  18.111 -{
  18.112 -    /* XXX just enable all phys interrupts for now */
  18.113 -    enable_irq(IRQ_FROM_XEN_VIRQ(VIRQ_PHYSIRQ));
  18.114 -}
  18.115 -
  18.116 -static void disable_physirq_event(unsigned int irq)
  18.117 -{
  18.118 -    /* XXX just disable all phys interrupts for now */
  18.119 -    disable_irq(IRQ_FROM_XEN_VIRQ(VIRQ_PHYSIRQ));
  18.120 -}
  18.121 -
  18.122 -static void ack_physirq_event(unsigned int irq)
  18.123 -{
  18.124 -    /* clear bit */
  18.125 -    if ( irq <= 0 || irq >= 32 )
  18.126 -    {
  18.127 -        printk("wrong irq %d\n", irq);
  18.128 -    }
  18.129 -
  18.130 -    clear_bit(irq, &HYPERVISOR_shared_info->physirq_pend);
  18.131 -}
  18.132 -
  18.133 -static void end_physirq_event(unsigned int irq)
  18.134 -{
  18.135 -    int err;
  18.136 -    physdev_op_t op;
  18.137 -
  18.138 -    /* call hypervisor */
  18.139 -    op.cmd = PHYSDEVOP_FINISHED_IRQ;
  18.140 -    op.u.finished_irq.irq   = irq;
  18.141 -    if ( (err = HYPERVISOR_physdev_op(&op)) != 0 )
  18.142 -    {
  18.143 -        printk(KERN_ALERT "could not finish IRQ %d\n", irq);
  18.144 -        return;
  18.145 -    }
  18.146 -    return;
  18.147 -}
  18.148 -
  18.149 -static struct hw_interrupt_type physirq_irq_type = {
  18.150 -    "physical-irq",
  18.151 -    startup_physirq_event,
  18.152 -    shutdown_physirq_event,
  18.153 -    enable_physirq_event,
  18.154 -    disable_physirq_event,
  18.155 -    ack_physirq_event,
  18.156 -    end_physirq_event,
  18.157 -    NULL
  18.158 -};
  18.159 -
  18.160 -
  18.161 -
  18.162 -void __init physirq_init(void)
  18.163 -{
  18.164 -    int i;
  18.165 -
  18.166 -    printk("Initialise irq handlers [%d-%d] for physical interrupts.\n",
  18.167 -           PHYS_IRQ_BASE, PHYS_IRQ_BASE+NR_PHYS_IRQS-1);
  18.168 -
  18.169 -    for ( i = 0; i < NR_PHYS_IRQS; i++ )
  18.170 -    {
  18.171 -        irq_desc[i + PHYS_IRQ_BASE].status  = IRQ_DISABLED;
  18.172 -        irq_desc[i + PHYS_IRQ_BASE].action  = 0;
  18.173 -        irq_desc[i + PHYS_IRQ_BASE].depth   = 1;
  18.174 -        irq_desc[i + PHYS_IRQ_BASE].handler = &physirq_irq_type;
  18.175 -    }
  18.176 -}
  18.177 -
  18.178 -#endif
    19.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c	Thu Mar 25 17:52:36 2004 +0000
    19.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c	Fri Mar 26 15:20:56 2004 +0000
    19.3 @@ -1151,6 +1151,9 @@ static void stop_task(void *unused)
    19.4      extern void blkdev_suspend(void);
    19.5      extern void blkdev_resume(void);
    19.6      
    19.7 +    extern void time_suspend(void);
    19.8 +    extern void time_resume(void);
    19.9 +
   19.10      unsigned long *pfn_to_mfn_frame_list = NULL;
   19.11      suspend_record_t *suspend_record     = NULL;
   19.12      struct net_device *dev;
   19.13 @@ -1198,6 +1201,8 @@ static void stop_task(void *unused)
   19.14  
   19.15      __cli();
   19.16  
   19.17 +    time_suspend();
   19.18 +
   19.19      HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
   19.20      clear_fixmap(FIX_SHARED_INFO);
   19.21  
   19.22 @@ -1211,6 +1216,8 @@ static void stop_task(void *unused)
   19.23      HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   19.24      memset(empty_zero_page, 0, PAGE_SIZE);
   19.25  
   19.26 +    time_resume();
   19.27 +
   19.28      __sti();
   19.29  
   19.30      blkdev_resume();
    20.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/time.c	Thu Mar 25 17:52:36 2004 +0000
    20.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/time.c	Fri Mar 26 15:20:56 2004 +0000
    20.3 @@ -634,6 +634,24 @@ void __init time_init(void)
    20.4      rdtscll(alarm);
    20.5  }
    20.6  
    20.7 +void time_suspend(void)
    20.8 +{
    20.9 +}
   20.10 +
   20.11 +void time_resume(void)
   20.12 +{
   20.13 +    unsigned long flags;
   20.14 +    write_lock_irqsave(&xtime_lock, flags);
   20.15 +    /* Get timebases for new environment. */ 
   20.16 +    __get_time_values_from_xen();
   20.17 +    /* Reset our own concept of passage of system time. */
   20.18 +    processed_system_time = shadow_system_time;
   20.19 +    /* Accept a warp in UTC (wall-clock) time. */
   20.20 +    last_seen_tv.tv_sec = 0;
   20.21 +    /* Make sure we resync UTC time with Xen on next timer interrupt. */
   20.22 +    last_update_from_xen = 0;
   20.23 +    write_unlock_irqrestore(&xtime_lock, flags);
   20.24 +}
   20.25  
   20.26  /*
   20.27   * /proc/sys/xen: This really belongs in another file. It can stay here for
    21.1 --- a/xenolinux-2.4.25-sparse/include/asm-xen/irq.h	Thu Mar 25 17:52:36 2004 +0000
    21.2 +++ b/xenolinux-2.4.25-sparse/include/asm-xen/irq.h	Fri Mar 26 15:20:56 2004 +0000
    21.3 @@ -32,7 +32,11 @@
    21.4  
    21.5  #define NR_IRQS   (NR_PIRQS + NR_DYNIRQS)
    21.6  
    21.7 -extern void physirq_init(void);
    21.8 +#define pirq_to_irq(_x)   ((_x) + PIRQ_BASE)
    21.9 +#define irq_to_pirq(_x)   ((_x) - PIRQ_BASE)
   21.10 +
   21.11 +#define dynirq_to_irq(_x) ((_x) + DYNIRQ_BASE)
   21.12 +#define irq_to_dynirq(_x) ((_x) - DYNIRQ_BASE)
   21.13  
   21.14  /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
   21.15  extern int  bind_virq_to_irq(int virq);
   21.16 @@ -40,14 +44,13 @@ extern void unbind_virq_from_irq(int vir
   21.17  extern int  bind_evtchn_to_irq(int evtchn);
   21.18  extern void unbind_evtchn_from_irq(int evtchn);
   21.19  
   21.20 -#define irq_cannonicalize(_irq) (_irq)
   21.21 +static __inline__ int irq_cannonicalize(int irq)
   21.22 +{
   21.23 +    return (irq == 2) ? 9 : irq;
   21.24 +}
   21.25  
   21.26  extern void disable_irq(unsigned int);
   21.27  extern void disable_irq_nosync(unsigned int);
   21.28  extern void enable_irq(unsigned int);
   21.29  
   21.30 -#ifdef CONFIG_X86_LOCAL_APIC
   21.31 -#define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
   21.32 -#endif
   21.33 -
   21.34  #endif /* _ASM_IRQ_H */