diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c index bd576ce869..0027b82a62 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c @@ -94,7 +94,7 @@ void notify_remote_via_irq(int irq) irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - u32 l1, l2; + unsigned long l1, l2; unsigned int l1i, l2i, port; irqreturn_t (*handler)(int, void *, struct pt_regs *); shared_info_t *s = HYPERVISOR_shared_info; @@ -108,14 +108,14 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) while ( l1 != 0 ) { l1i = __ffs(l1); - l1 &= ~(1 << l1i); + l1 &= ~(1UL << l1i); while ( (l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]) != 0 ) { l2i = __ffs(l2); - l2 &= ~(1 << l2i); + l2 &= ~(1UL << l2i); - port = (l1i << 5) + l2i; + port = (l1i * BITS_PER_LONG) + l2i; if ( (handler = evtchns[port].handler) != NULL ) { clear_evtchn(port); diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index b13abf720e..01e245e3ab 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -1123,7 +1123,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) * If SMP should be disabled, then really disable it! */ if (!max_cpus) { - HYPERVISOR_shared_info->n_vcpu = 1; + xen_start_info->n_vcpu = 1; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); smpboot_clear_io_apic_irqs(); #if 0 @@ -1153,12 +1153,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) */ Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); #endif - Dprintk("CPU present map: %lx\n", - (1UL << HYPERVISOR_shared_info->n_vcpu) - 1); + Dprintk("CPU present map: %lx\n", (1UL << xen_start_info->n_vcpu) - 1); kicked = 1; - for (cpu = 1; kicked < NR_CPUS && - cpu < HYPERVISOR_shared_info->n_vcpu; cpu++) { + for (cpu = 1; kicked < NR_CPUS && cpu < xen_start_info->n_vcpu; cpu++) { if (max_cpus <= cpucount+1) continue; diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index 80e017684b..1d27f11910 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -71,8 +71,8 @@ static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)]; #ifdef CONFIG_SMP -static u8 cpu_evtchn[NR_EVENT_CHANNELS]; -static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32]; +static u8 cpu_evtchn[NR_EVENT_CHANNELS]; +static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG]; #define active_evtchns(cpu,sh,idx) \ ((sh)->evtchn_pending[idx] & \ @@ -137,7 +137,7 @@ EXPORT_SYMBOL(force_evtchn_callback); /* NB. Interrupts are disabled on entry. */ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) { - u32 l1, l2; + unsigned long l1, l2; unsigned int l1i, l2i, port; int irq, cpu = smp_processor_id(); shared_info_t *s = HYPERVISOR_shared_info; @@ -149,13 +149,13 @@ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); while (l1 != 0) { l1i = __ffs(l1); - l1 &= ~(1 << l1i); + l1 &= ~(1UL << l1i); while ((l2 = active_evtchns(cpu, s, l1i)) != 0) { l2i = __ffs(l2); - l2 &= ~(1 << l2i); + l2 &= ~(1UL << l2i); - port = (l1i << 5) + l2i; + port = (l1i * BITS_PER_LONG) + l2i; if ((irq = evtchn_to_irq[port]) != -1) do_IRQ(irq, regs); else diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c index 48abf11507..b48b559a45 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c @@ -1045,7 +1045,7 @@ static int __cpuinit smp_sanity_check(unsigned max_cpus) */ if (!max_cpus) { #ifdef CONFIG_XEN - HYPERVISOR_shared_info->n_vcpu = 1; + xen_start_info->n_vcpu = 1; #endif printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); #ifndef CONFIG_XEN @@ -1082,7 +1082,7 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus) int apicid = cpu_present_to_apicid(i); if (physid_isset(apicid, phys_cpu_present_map)) { #else - if (i < HYPERVISOR_shared_info->n_vcpu) { + if (i < xen_start_info->n_vcpu) { #endif cpu_set(i, cpu_present_map); /* possible map would be different if we supported real diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h index 28adeaf244..fa85aa2cfe 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h @@ -52,4 +52,4 @@ static inline void smpboot_setup_io_apic(void) } -#define smp_found_config (HYPERVISOR_shared_info->n_vcpu > 1) +#define smp_found_config (xen_start_info->n_vcpu > 1) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h index 28adeaf244..fa85aa2cfe 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h @@ -52,4 +52,4 @@ static inline void smpboot_setup_io_apic(void) } -#define smp_found_config (HYPERVISOR_shared_info->n_vcpu > 1) +#define smp_found_config (xen_start_info->n_vcpu > 1) diff --git a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h index f2523926d8..127cf8e72f 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h @@ -99,8 +99,9 @@ static inline void unmask_evtchn(int port) * like a real IO-APIC we 'lose the interrupt edge' if the channel is * masked. */ - if (synch_test_bit (port, &s->evtchn_pending[0]) && - !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel)) { + if (synch_test_bit(port, &s->evtchn_pending[0]) && + !synch_test_and_set_bit(port / BITS_PER_LONG, + &vcpu_info->evtchn_pending_sel)) { vcpu_info->evtchn_upcall_pending = 1; if (!vcpu_info->evtchn_upcall_mask) force_evtchn_callback(); diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 5cdb568bc0..1185fc020e 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -636,6 +636,7 @@ static int setup_guest(int xc_handle, start_info->store_evtchn = store_evtchn; start_info->console_mfn = *console_mfn; start_info->console_evtchn = console_evtchn; + start_info->n_vcpu = vcpus; if ( initrd_len != 0 ) { start_info->mod_start = vinitrd_start; @@ -653,9 +654,6 @@ static int setup_guest(int xc_handle, for ( i = 0; i < MAX_VIRT_CPUS; i++ ) shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - shared_info->n_vcpu = vcpus; - printf(" VCPUS: %d\n", shared_info->n_vcpu); - munmap(shared_info, PAGE_SIZE); /* Send the page update requests down to the hypervisor. */ diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 5dd55e94f7..2f8a5ec72d 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -519,9 +519,6 @@ static int setup_guest(int xc_handle, for ( i = 0; i < MAX_VIRT_CPUS; i++ ) shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - shared_info->n_vcpu = vcpus; - printf(" VCPUS: %d\n", shared_info->n_vcpu); - munmap(shared_info, PAGE_SIZE); /* Populate the event channel port in the shared page */ diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 79fdd38a9a..3615aed8d9 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -439,7 +439,7 @@ class XendDomainInfo: defaultInfo('on_crash', lambda: "restart") defaultInfo('cpu', lambda: None) defaultInfo('cpu_weight', lambda: 1.0) - defaultInfo('vcpus', lambda: 1) + defaultInfo('vcpus', lambda: int(1)) defaultInfo('vcpu_avail', lambda: (1 << self.info['vcpus']) - 1) defaultInfo('bootloader', lambda: None) defaultInfo('backend', lambda: []) diff --git a/xen/arch/ia64/vmx/vmx_support.c b/xen/arch/ia64/vmx/vmx_support.c index afd0f650d0..4da31f2332 100644 --- a/xen/arch/ia64/vmx/vmx_support.c +++ b/xen/arch/ia64/vmx/vmx_support.c @@ -49,7 +49,7 @@ void vmx_wait_io(void) */ if (test_and_clear_bit(port, &d->shared_info->evtchn_pending[0])) { - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); clear_bit(0, &v->vcpu_info->evtchn_upcall_pending); vmx_io_assist(v); } @@ -67,7 +67,7 @@ void vmx_wait_io(void) * nothing losed. Next loop will check I/O channel to fix this * window. */ - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); } else break; @@ -139,8 +139,8 @@ void vmx_intr_assist(struct vcpu *v) /* Clear indicator specific to interrupt delivered from DM */ if (test_and_clear_bit(port, &d->shared_info->evtchn_pending[0])) { - if (!d->shared_info->evtchn_pending[port >> 5]) - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG]) + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); if (!v->vcpu_info->evtchn_pending_sel) clear_bit(0, &v->vcpu_info->evtchn_upcall_pending); diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 69b0ddd58b..38a3cb2c99 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -557,10 +557,9 @@ int construct_dom0(struct domain *d, /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - d->shared_info->n_vcpu = num_online_cpus(); - for ( i = 1; i < d->shared_info->n_vcpu; i++ ) - (void)alloc_vcpu(d, i, i % num_online_cpus()); + for ( i = 1; i < num_online_cpus(); i++ ) + (void)alloc_vcpu(d, i, i); /* Set up monitor table */ update_pagetables(v); @@ -588,7 +587,8 @@ int construct_dom0(struct domain *d, /* Set up start info area. */ si = (start_info_t *)vstartinfo_start; memset(si, 0, PAGE_SIZE); - si->nr_pages = nr_pages; + si->nr_pages = nr_pages; + si->n_vcpu = num_online_cpus(); if ( opt_dom0_translate ) { diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 1d904e43a9..e6536b31a1 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -684,15 +684,15 @@ int vmx_clear_pending_io_event(struct vcpu *v) struct domain *d = v->domain; int port = iopacket_port(d); - /* evtchn_pending is shared by other event channels in 0-31 range */ - if (!d->shared_info->evtchn_pending[port>>5]) - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + /* evtchn_pending_sel bit is shared by other event channels. */ + if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG]) + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); - /* Note: VMX domains may need upcalls as well */ + /* Note: VMX domains may need upcalls as well. */ if (!v->vcpu_info->evtchn_pending_sel) clear_bit(0, &v->vcpu_info->evtchn_upcall_pending); - /* clear the pending bit for port */ + /* Clear the pending bit for port. */ return test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]); } @@ -726,7 +726,7 @@ void vmx_wait_io() break; /* Events other than IOPACKET_PORT might have woken us up. In that case, safely go back to sleep. */ - clear_bit(port>>5, ¤t->vcpu_info->evtchn_pending_sel); + clear_bit(port/BITS_PER_LONG, ¤t->vcpu_info->evtchn_pending_sel); clear_bit(0, ¤t->vcpu_info->evtchn_upcall_pending); } while(1); } diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 0f1bbb9872..acbfd094bc 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -136,7 +136,7 @@ static void do_task_queues(unsigned char key) &d->shared_info->evtchn_pending[0]), test_bit(v->virq_to_evtchn[VIRQ_DEBUG], &d->shared_info->evtchn_mask[0]), - test_bit(v->virq_to_evtchn[VIRQ_DEBUG]>>5, + test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel)); send_guest_virq(v, VIRQ_DEBUG); } diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index c0111b5027..3c2d0094f2 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -260,8 +260,11 @@ typedef struct unsigned long args[6]; } multicall_entry_t; -/* Event channel endpoints per domain. */ -#define NR_EVENT_CHANNELS 1024 +/* + * Event channel endpoints per domain: + * 1024 if a long is 32 bits; 4096 if a long is 64 bits. + */ +#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64) /* * Per-VCPU information goes here. This will be cleaned up more when Xen @@ -295,7 +298,7 @@ typedef struct vcpu_info { */ uint8_t evtchn_upcall_pending; uint8_t evtchn_upcall_mask; - uint32_t evtchn_pending_sel; + unsigned long evtchn_pending_sel; #ifdef __ARCH_HAS_VCPU_INFO arch_vcpu_info_t arch; #endif @@ -333,16 +336,14 @@ typedef struct shared_info { vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS]; - uint32_t n_vcpu; - /* - * A domain can have up to 1024 "event channels" on which it can send - * and receive asynchronous event notifications. There are three classes - * of event that are delivered by this mechanism: + * A domain can create "event channels" on which it can send and receive + * asynchronous event notifications. There are three classes of event that + * are delivered by this mechanism: * 1. Bi-directional inter- and intra-domain connections. Domains must - * arrange out-of-band to set up a connection (usually the setup - * is initiated and organised by a privileged third party such as - * software running in domain 0). + * arrange out-of-band to set up a connection (usually by allocating + * an unbound 'listener' port and avertising that via a storage service + * such as xenstore). * 2. Physical interrupts. A domain with suitable hardware-access * privileges can bind an event-channel port to a physical interrupt * source. @@ -350,8 +351,8 @@ typedef struct shared_info { * port to a virtual interrupt source, such as the virtual-timer * device or the emergency console. * - * Event channels are addressed by a "port index" between 0 and 1023. - * Each channel is associated with two bits of information: + * Event channels are addressed by a "port index". Each channel is + * associated with two bits of information: * 1. PENDING -- notifies the domain that there is a pending notification * to be processed. This bit is cleared by the guest. * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING @@ -363,11 +364,11 @@ typedef struct shared_info { * * To expedite scanning of pending notifications, any 0->1 pending * transition on an unmasked channel causes a corresponding bit in a - * 32-bit selector to be set. Each bit in the selector covers a 32-bit - * word in the PENDING bitfield array. + * per-vcpu selector word to be set. Each bit in the selector covers a + * 'C long' in the PENDING bitfield array. */ - uint32_t evtchn_pending[32]; - uint32_t evtchn_mask[32]; + unsigned long evtchn_pending[sizeof(unsigned long) * 8]; + unsigned long evtchn_mask[sizeof(unsigned long) * 8]; /* * Wallclock time: updated only by control software. Guests should base @@ -422,6 +423,7 @@ typedef struct start_info { unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */ unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ + uint32_t n_vcpu; int8_t cmd_line[MAX_GUEST_CMDLINE]; } start_info_t; diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 8f527b0c83..e8a8bc2b5b 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -28,10 +28,11 @@ static inline void evtchn_set_pending(struct vcpu *v, int port) shared_info_t *s = d->shared_info; /* These four operations must happen in strict order. */ - if ( !test_and_set_bit(port, &s->evtchn_pending[0]) && - !test_bit (port, &s->evtchn_mask[0]) && - !test_and_set_bit(port>>5, &v->vcpu_info->evtchn_pending_sel) && - !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) ) + if ( !test_and_set_bit(port, &s->evtchn_pending[0]) && + !test_bit (port, &s->evtchn_mask[0]) && + !test_and_set_bit(port / BITS_PER_LONG, + &v->vcpu_info->evtchn_pending_sel) && + !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) ) { evtchn_notify(v); } diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 4250205268..0f012456af 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -19,7 +19,7 @@ extern rwlock_t domlist_lock; /* A global pointer to the initial domain (DOM0). */ extern struct domain *dom0; -#define MAX_EVTCHNS 1024 +#define MAX_EVTCHNS NR_EVENT_CHANNELS #define EVTCHNS_PER_BUCKET 128 #define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET)