direct-io.hg

changeset 7402:ba9706473941

Make the event-channel pending and mask arrays consist of
longs. Thi sensures appropriate alignment for architectures
that require it, and also allows us to naturally support up
to 4096 event channels per 64-bit guest.

Moved 'n_vcpu' field from shared_info to start_info. Really it
ought to disappear altogether as the info can be derived from
xenstore.

Fix a weird bug in XendDomainInfo where 'vcpus' information for
a domain defaults to floating point value 1.0 rather than integer
1. This looks like a Python bug to me, but in any case it is
'fixed' by explicitly converting the default value to an integer.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Oct 17 15:15:17 2005 +0100 (2005-10-17)
parents 5e4e11d059a1
children 895149d24048
files linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h linux-2.6-xen-sparse/include/asm-xen/evtchn.h tools/libxc/xc_linux_build.c tools/libxc/xc_vmx_build.c tools/python/xen/xend/XendDomainInfo.py xen/arch/ia64/vmx/vmx_support.c xen/arch/x86/domain_build.c xen/arch/x86/vmx_io.c xen/common/keyhandler.c xen/include/public/xen.h xen/include/xen/event.h xen/include/xen/sched.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c	Mon Oct 17 14:12:20 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c	Mon Oct 17 15:15:17 2005 +0100
     1.3 @@ -94,7 +94,7 @@ void notify_remote_via_irq(int irq)
     1.4  
     1.5  irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     1.6  {
     1.7 -    u32            l1, l2;
     1.8 +    unsigned long  l1, l2;
     1.9      unsigned int   l1i, l2i, port;
    1.10      irqreturn_t (*handler)(int, void *, struct pt_regs *);
    1.11      shared_info_t *s = HYPERVISOR_shared_info;
    1.12 @@ -108,14 +108,14 @@ irqreturn_t evtchn_interrupt(int irq, vo
    1.13      while ( l1 != 0 )
    1.14      {
    1.15          l1i = __ffs(l1);
    1.16 -        l1 &= ~(1 << l1i);
    1.17 +        l1 &= ~(1UL << l1i);
    1.18  
    1.19          while ( (l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]) != 0 )
    1.20          {
    1.21              l2i = __ffs(l2);
    1.22 -            l2 &= ~(1 << l2i);
    1.23 +            l2 &= ~(1UL << l2i);
    1.24  
    1.25 -            port = (l1i << 5) + l2i;
    1.26 +            port = (l1i * BITS_PER_LONG) + l2i;
    1.27              if ( (handler = evtchns[port].handler) != NULL )
    1.28  	    {
    1.29  		clear_evtchn(port);
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Mon Oct 17 14:12:20 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Mon Oct 17 15:15:17 2005 +0100
     2.3 @@ -1123,7 +1123,7 @@ static void __init smp_boot_cpus(unsigne
     2.4  	 * If SMP should be disabled, then really disable it!
     2.5  	 */
     2.6  	if (!max_cpus) {
     2.7 -		HYPERVISOR_shared_info->n_vcpu = 1;
     2.8 +		xen_start_info->n_vcpu = 1;
     2.9  		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
    2.10  		smpboot_clear_io_apic_irqs();
    2.11  #if 0
    2.12 @@ -1153,12 +1153,10 @@ static void __init smp_boot_cpus(unsigne
    2.13  	 */
    2.14  	Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map));
    2.15  #endif
    2.16 -	Dprintk("CPU present map: %lx\n",
    2.17 -		(1UL << HYPERVISOR_shared_info->n_vcpu) - 1);
    2.18 +	Dprintk("CPU present map: %lx\n", (1UL << xen_start_info->n_vcpu) - 1);
    2.19  
    2.20  	kicked = 1;
    2.21 -	for (cpu = 1; kicked < NR_CPUS &&
    2.22 -		     cpu < HYPERVISOR_shared_info->n_vcpu; cpu++) {
    2.23 +	for (cpu = 1; kicked < NR_CPUS && cpu < xen_start_info->n_vcpu; cpu++) {
    2.24  		if (max_cpus <= cpucount+1)
    2.25  			continue;
    2.26  
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Mon Oct 17 14:12:20 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Mon Oct 17 15:15:17 2005 +0100
     3.3 @@ -71,8 +71,8 @@ static unsigned long pirq_needs_unmask_n
     3.4  
     3.5  #ifdef CONFIG_SMP
     3.6  
     3.7 -static u8  cpu_evtchn[NR_EVENT_CHANNELS];
     3.8 -static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32];
     3.9 +static u8 cpu_evtchn[NR_EVENT_CHANNELS];
    3.10 +static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
    3.11  
    3.12  #define active_evtchns(cpu,sh,idx)		\
    3.13  	((sh)->evtchn_pending[idx] &		\
    3.14 @@ -137,7 +137,7 @@ EXPORT_SYMBOL(force_evtchn_callback);
    3.15  /* NB. Interrupts are disabled on entry. */
    3.16  asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
    3.17  {
    3.18 -	u32     l1, l2;
    3.19 +	unsigned long  l1, l2;
    3.20  	unsigned int   l1i, l2i, port;
    3.21  	int            irq, cpu = smp_processor_id();
    3.22  	shared_info_t *s = HYPERVISOR_shared_info;
    3.23 @@ -149,13 +149,13 @@ asmlinkage void evtchn_do_upcall(struct 
    3.24  	l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
    3.25  	while (l1 != 0) {
    3.26  		l1i = __ffs(l1);
    3.27 -		l1 &= ~(1 << l1i);
    3.28 +		l1 &= ~(1UL << l1i);
    3.29          
    3.30  		while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
    3.31  			l2i = __ffs(l2);
    3.32 -			l2 &= ~(1 << l2i);
    3.33 +			l2 &= ~(1UL << l2i);
    3.34              
    3.35 -			port = (l1i << 5) + l2i;
    3.36 +			port = (l1i * BITS_PER_LONG) + l2i;
    3.37  			if ((irq = evtchn_to_irq[port]) != -1)
    3.38  				do_IRQ(irq, regs);
    3.39  			else
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c	Mon Oct 17 14:12:20 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c	Mon Oct 17 15:15:17 2005 +0100
     4.3 @@ -1045,7 +1045,7 @@ static int __cpuinit smp_sanity_check(un
     4.4  	 */
     4.5  	if (!max_cpus) {
     4.6  #ifdef CONFIG_XEN
     4.7 -		HYPERVISOR_shared_info->n_vcpu = 1;
     4.8 +		xen_start_info->n_vcpu = 1;
     4.9  #endif
    4.10  		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
    4.11  #ifndef CONFIG_XEN
    4.12 @@ -1082,7 +1082,7 @@ void __cpuinit smp_prepare_cpus(unsigned
    4.13  		int apicid = cpu_present_to_apicid(i);
    4.14  		if (physid_isset(apicid, phys_cpu_present_map)) {
    4.15  #else
    4.16 -		if (i < HYPERVISOR_shared_info->n_vcpu) {
    4.17 +		if (i < xen_start_info->n_vcpu) {
    4.18  #endif
    4.19  			cpu_set(i, cpu_present_map);
    4.20  			/* possible map would be different if we supported real
     5.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h	Mon Oct 17 14:12:20 2005 +0100
     5.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h	Mon Oct 17 15:15:17 2005 +0100
     5.3 @@ -52,4 +52,4 @@ static inline void smpboot_setup_io_apic
     5.4  }
     5.5  
     5.6  
     5.7 -#define	smp_found_config	(HYPERVISOR_shared_info->n_vcpu > 1)
     5.8 +#define	smp_found_config	(xen_start_info->n_vcpu > 1)
     6.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h	Mon Oct 17 14:12:20 2005 +0100
     6.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h	Mon Oct 17 15:15:17 2005 +0100
     6.3 @@ -52,4 +52,4 @@ static inline void smpboot_setup_io_apic
     6.4  }
     6.5  
     6.6  
     6.7 -#define	smp_found_config	(HYPERVISOR_shared_info->n_vcpu > 1)
     6.8 +#define	smp_found_config	(xen_start_info->n_vcpu > 1)
     7.1 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Mon Oct 17 14:12:20 2005 +0100
     7.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Mon Oct 17 15:15:17 2005 +0100
     7.3 @@ -99,8 +99,9 @@ static inline void unmask_evtchn(int por
     7.4  	 * like a real IO-APIC we 'lose the interrupt edge' if the channel is
     7.5  	 * masked.
     7.6  	 */
     7.7 -	if (synch_test_bit         (port,    &s->evtchn_pending[0]) && 
     7.8 -	    !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel)) {
     7.9 +	if (synch_test_bit(port, &s->evtchn_pending[0]) && 
    7.10 +	    !synch_test_and_set_bit(port / BITS_PER_LONG,
    7.11 +				    &vcpu_info->evtchn_pending_sel)) {
    7.12  		vcpu_info->evtchn_upcall_pending = 1;
    7.13  		if (!vcpu_info->evtchn_upcall_mask)
    7.14  			force_evtchn_callback();
     8.1 --- a/tools/libxc/xc_linux_build.c	Mon Oct 17 14:12:20 2005 +0100
     8.2 +++ b/tools/libxc/xc_linux_build.c	Mon Oct 17 15:15:17 2005 +0100
     8.3 @@ -636,6 +636,7 @@ static int setup_guest(int xc_handle,
     8.4      start_info->store_evtchn = store_evtchn;
     8.5      start_info->console_mfn   = *console_mfn;
     8.6      start_info->console_evtchn = console_evtchn;
     8.7 +    start_info->n_vcpu       = vcpus;
     8.8      if ( initrd_len != 0 )
     8.9      {
    8.10          start_info->mod_start    = vinitrd_start;
    8.11 @@ -653,9 +654,6 @@ static int setup_guest(int xc_handle,
    8.12      for ( i = 0; i < MAX_VIRT_CPUS; i++ )
    8.13          shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
    8.14  
    8.15 -    shared_info->n_vcpu = vcpus;
    8.16 -    printf(" VCPUS:         %d\n", shared_info->n_vcpu);
    8.17 -
    8.18      munmap(shared_info, PAGE_SIZE);
    8.19  
    8.20      /* Send the page update requests down to the hypervisor. */
     9.1 --- a/tools/libxc/xc_vmx_build.c	Mon Oct 17 14:12:20 2005 +0100
     9.2 +++ b/tools/libxc/xc_vmx_build.c	Mon Oct 17 15:15:17 2005 +0100
     9.3 @@ -519,9 +519,6 @@ static int setup_guest(int xc_handle,
     9.4      for ( i = 0; i < MAX_VIRT_CPUS; i++ )
     9.5          shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
     9.6  
     9.7 -    shared_info->n_vcpu = vcpus;
     9.8 -    printf(" VCPUS:         %d\n", shared_info->n_vcpu);
     9.9 -
    9.10      munmap(shared_info, PAGE_SIZE);
    9.11  
    9.12      /* Populate the event channel port in the shared page */
    10.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 17 14:12:20 2005 +0100
    10.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 17 15:15:17 2005 +0100
    10.3 @@ -439,7 +439,7 @@ class XendDomainInfo:
    10.4              defaultInfo('on_crash',     lambda: "restart")
    10.5              defaultInfo('cpu',          lambda: None)
    10.6              defaultInfo('cpu_weight',   lambda: 1.0)
    10.7 -            defaultInfo('vcpus',        lambda: 1)
    10.8 +            defaultInfo('vcpus',        lambda: int(1))
    10.9              defaultInfo('vcpu_avail',   lambda: (1 << self.info['vcpus']) - 1)
   10.10              defaultInfo('bootloader',   lambda: None)
   10.11              defaultInfo('backend',      lambda: [])
    11.1 --- a/xen/arch/ia64/vmx/vmx_support.c	Mon Oct 17 14:12:20 2005 +0100
    11.2 +++ b/xen/arch/ia64/vmx/vmx_support.c	Mon Oct 17 15:15:17 2005 +0100
    11.3 @@ -49,7 +49,7 @@ void vmx_wait_io(void)
    11.4  	  */
    11.5  	if (test_and_clear_bit(port,
    11.6  		&d->shared_info->evtchn_pending[0])) {
    11.7 -	    clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
    11.8 +	    clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
    11.9  	    clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
   11.10  	    vmx_io_assist(v);
   11.11  	}
   11.12 @@ -67,7 +67,7 @@ void vmx_wait_io(void)
   11.13  	     * nothing losed. Next loop will check I/O channel to fix this
   11.14  	     * window.
   11.15  	     */
   11.16 -	    clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
   11.17 +	    clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
   11.18  	}
   11.19  	else
   11.20  	    break;
   11.21 @@ -139,8 +139,8 @@ void vmx_intr_assist(struct vcpu *v)
   11.22      /* Clear indicator specific to interrupt delivered from DM */
   11.23      if (test_and_clear_bit(port,
   11.24  		&d->shared_info->evtchn_pending[0])) {
   11.25 -	if (!d->shared_info->evtchn_pending[port >> 5])
   11.26 -	    clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
   11.27 +	if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
   11.28 +	    clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
   11.29  
   11.30  	if (!v->vcpu_info->evtchn_pending_sel)
   11.31  	    clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
    12.1 --- a/xen/arch/x86/domain_build.c	Mon Oct 17 14:12:20 2005 +0100
    12.2 +++ b/xen/arch/x86/domain_build.c	Mon Oct 17 15:15:17 2005 +0100
    12.3 @@ -557,10 +557,9 @@ int construct_dom0(struct domain *d,
    12.4      /* Mask all upcalls... */
    12.5      for ( i = 0; i < MAX_VIRT_CPUS; i++ )
    12.6          d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
    12.7 -    d->shared_info->n_vcpu = num_online_cpus();
    12.8  
    12.9 -    for ( i = 1; i < d->shared_info->n_vcpu; i++ )
   12.10 -        (void)alloc_vcpu(d, i, i % num_online_cpus());
   12.11 +    for ( i = 1; i < num_online_cpus(); i++ )
   12.12 +        (void)alloc_vcpu(d, i, i);
   12.13  
   12.14      /* Set up monitor table */
   12.15      update_pagetables(v);
   12.16 @@ -588,7 +587,8 @@ int construct_dom0(struct domain *d,
   12.17      /* Set up start info area. */
   12.18      si = (start_info_t *)vstartinfo_start;
   12.19      memset(si, 0, PAGE_SIZE);
   12.20 -    si->nr_pages     = nr_pages;
   12.21 +    si->nr_pages = nr_pages;
   12.22 +    si->n_vcpu   = num_online_cpus();
   12.23  
   12.24      if ( opt_dom0_translate )
   12.25      {
    13.1 --- a/xen/arch/x86/vmx_io.c	Mon Oct 17 14:12:20 2005 +0100
    13.2 +++ b/xen/arch/x86/vmx_io.c	Mon Oct 17 15:15:17 2005 +0100
    13.3 @@ -684,15 +684,15 @@ int vmx_clear_pending_io_event(struct vc
    13.4      struct domain *d = v->domain;
    13.5      int port = iopacket_port(d);
    13.6  
    13.7 -    /* evtchn_pending is shared by other event channels in 0-31 range */
    13.8 -    if (!d->shared_info->evtchn_pending[port>>5])
    13.9 -        clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
   13.10 +    /* evtchn_pending_sel bit is shared by other event channels. */
   13.11 +    if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
   13.12 +        clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
   13.13  
   13.14 -    /* Note: VMX domains may need upcalls as well */
   13.15 +    /* Note: VMX domains may need upcalls as well. */
   13.16      if (!v->vcpu_info->evtchn_pending_sel)
   13.17          clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
   13.18  
   13.19 -    /* clear the pending bit for port */
   13.20 +    /* Clear the pending bit for port. */
   13.21      return test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]);
   13.22  }
   13.23  
   13.24 @@ -726,7 +726,7 @@ void vmx_wait_io()
   13.25              break;
   13.26          /* Events other than IOPACKET_PORT might have woken us up. In that
   13.27             case, safely go back to sleep. */
   13.28 -        clear_bit(port>>5, &current->vcpu_info->evtchn_pending_sel);
   13.29 +        clear_bit(port/BITS_PER_LONG, &current->vcpu_info->evtchn_pending_sel);
   13.30          clear_bit(0, &current->vcpu_info->evtchn_upcall_pending);
   13.31      } while(1);
   13.32  }
    14.1 --- a/xen/common/keyhandler.c	Mon Oct 17 14:12:20 2005 +0100
    14.2 +++ b/xen/common/keyhandler.c	Mon Oct 17 15:15:17 2005 +0100
    14.3 @@ -136,7 +136,7 @@ static void do_task_queues(unsigned char
    14.4                              &d->shared_info->evtchn_pending[0]),
    14.5                     test_bit(v->virq_to_evtchn[VIRQ_DEBUG], 
    14.6                              &d->shared_info->evtchn_mask[0]),
    14.7 -                   test_bit(v->virq_to_evtchn[VIRQ_DEBUG]>>5, 
    14.8 +                   test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG, 
    14.9                              &v->vcpu_info->evtchn_pending_sel));
   14.10              send_guest_virq(v, VIRQ_DEBUG);
   14.11          }
    15.1 --- a/xen/include/public/xen.h	Mon Oct 17 14:12:20 2005 +0100
    15.2 +++ b/xen/include/public/xen.h	Mon Oct 17 15:15:17 2005 +0100
    15.3 @@ -260,8 +260,11 @@ typedef struct
    15.4      unsigned long args[6];
    15.5  } multicall_entry_t;
    15.6  
    15.7 -/* Event channel endpoints per domain. */
    15.8 -#define NR_EVENT_CHANNELS 1024
    15.9 +/*
   15.10 + * Event channel endpoints per domain:
   15.11 + *  1024 if a long is 32 bits; 4096 if a long is 64 bits.
   15.12 + */
   15.13 +#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
   15.14  
   15.15  /*
   15.16   * Per-VCPU information goes here. This will be cleaned up more when Xen 
   15.17 @@ -295,7 +298,7 @@ typedef struct vcpu_info {
   15.18       */
   15.19      uint8_t evtchn_upcall_pending;
   15.20      uint8_t evtchn_upcall_mask;
   15.21 -    uint32_t evtchn_pending_sel;
   15.22 +    unsigned long evtchn_pending_sel;
   15.23  #ifdef __ARCH_HAS_VCPU_INFO
   15.24      arch_vcpu_info_t arch;
   15.25  #endif
   15.26 @@ -333,16 +336,14 @@ typedef struct shared_info {
   15.27  
   15.28      vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS];
   15.29  
   15.30 -    uint32_t n_vcpu;
   15.31 -
   15.32      /*
   15.33 -     * A domain can have up to 1024 "event channels" on which it can send
   15.34 -     * and receive asynchronous event notifications. There are three classes
   15.35 -     * of event that are delivered by this mechanism:
   15.36 +     * A domain can create "event channels" on which it can send and receive
   15.37 +     * asynchronous event notifications. There are three classes of event that
   15.38 +     * are delivered by this mechanism:
   15.39       *  1. Bi-directional inter- and intra-domain connections. Domains must
   15.40 -     *     arrange out-of-band to set up a connection (usually the setup
   15.41 -     *     is initiated and organised by a privileged third party such as
   15.42 -     *     software running in domain 0).
   15.43 +     *     arrange out-of-band to set up a connection (usually by allocating
   15.44 +     *     an unbound 'listener' port and avertising that via a storage service
   15.45 +     *     such as xenstore).
   15.46       *  2. Physical interrupts. A domain with suitable hardware-access
   15.47       *     privileges can bind an event-channel port to a physical interrupt
   15.48       *     source.
   15.49 @@ -350,8 +351,8 @@ typedef struct shared_info {
   15.50       *     port to a virtual interrupt source, such as the virtual-timer
   15.51       *     device or the emergency console.
   15.52       * 
   15.53 -     * Event channels are addressed by a "port index" between 0 and 1023.
   15.54 -     * Each channel is associated with two bits of information:
   15.55 +     * Event channels are addressed by a "port index". Each channel is
   15.56 +     * associated with two bits of information:
   15.57       *  1. PENDING -- notifies the domain that there is a pending notification
   15.58       *     to be processed. This bit is cleared by the guest.
   15.59       *  2. MASK -- if this bit is clear then a 0->1 transition of PENDING
   15.60 @@ -363,11 +364,11 @@ typedef struct shared_info {
   15.61       * 
   15.62       * To expedite scanning of pending notifications, any 0->1 pending
   15.63       * transition on an unmasked channel causes a corresponding bit in a
   15.64 -     * 32-bit selector to be set. Each bit in the selector covers a 32-bit
   15.65 -     * word in the PENDING bitfield array.
   15.66 +     * per-vcpu selector word to be set. Each bit in the selector covers a
   15.67 +     * 'C long' in the PENDING bitfield array.
   15.68       */
   15.69 -    uint32_t evtchn_pending[32];
   15.70 -    uint32_t evtchn_mask[32];
   15.71 +    unsigned long evtchn_pending[sizeof(unsigned long) * 8];
   15.72 +    unsigned long evtchn_mask[sizeof(unsigned long) * 8];
   15.73  
   15.74      /*
   15.75       * Wallclock time: updated only by control software. Guests should base
   15.76 @@ -422,6 +423,7 @@ typedef struct start_info {
   15.77      unsigned long mfn_list;     /* VIRTUAL address of page-frame list.    */
   15.78      unsigned long mod_start;    /* VIRTUAL address of pre-loaded module.  */
   15.79      unsigned long mod_len;      /* Size (bytes) of pre-loaded module.     */
   15.80 +    uint32_t n_vcpu;
   15.81      int8_t cmd_line[MAX_GUEST_CMDLINE];
   15.82  } start_info_t;
   15.83  
    16.1 --- a/xen/include/xen/event.h	Mon Oct 17 14:12:20 2005 +0100
    16.2 +++ b/xen/include/xen/event.h	Mon Oct 17 15:15:17 2005 +0100
    16.3 @@ -28,10 +28,11 @@ static inline void evtchn_set_pending(st
    16.4      shared_info_t *s = d->shared_info;
    16.5  
    16.6      /* These four operations must happen in strict order. */
    16.7 -    if ( !test_and_set_bit(port,    &s->evtchn_pending[0]) &&
    16.8 -         !test_bit        (port,    &s->evtchn_mask[0])    &&
    16.9 -         !test_and_set_bit(port>>5, &v->vcpu_info->evtchn_pending_sel) &&
   16.10 -         !test_and_set_bit(0,       &v->vcpu_info->evtchn_upcall_pending) )
   16.11 +    if ( !test_and_set_bit(port, &s->evtchn_pending[0]) &&
   16.12 +         !test_bit        (port, &s->evtchn_mask[0])    &&
   16.13 +         !test_and_set_bit(port / BITS_PER_LONG,
   16.14 +                           &v->vcpu_info->evtchn_pending_sel) &&
   16.15 +         !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) )
   16.16      {
   16.17          evtchn_notify(v);
   16.18      }
    17.1 --- a/xen/include/xen/sched.h	Mon Oct 17 14:12:20 2005 +0100
    17.2 +++ b/xen/include/xen/sched.h	Mon Oct 17 15:15:17 2005 +0100
    17.3 @@ -19,7 +19,7 @@ extern rwlock_t domlist_lock;
    17.4  /* A global pointer to the initial domain (DOM0). */
    17.5  extern struct domain *dom0;
    17.6  
    17.7 -#define MAX_EVTCHNS        1024
    17.8 +#define MAX_EVTCHNS        NR_EVENT_CHANNELS
    17.9  #define EVTCHNS_PER_BUCKET 128
   17.10  #define NR_EVTCHN_BUCKETS  (MAX_EVTCHNS / EVTCHNS_PER_BUCKET)
   17.11