[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Merge.



# HG changeset patch
# User adsharma@xxxxxxxxxxxxxxxxxxxx
# Node ID c589ca6d292b28e0da2ccf3675fc6d63d7f1843d
# Parent  f90820349056d0c5b8442078187cf7abafeb9fd4
# Parent  2f75dac09365959d87709d15a181201abf189cb8
Merge.

diff -r f90820349056 -r c589ca6d292b .hgignore
--- a/.hgignore Thu Aug 11 18:44:59 2005
+++ b/.hgignore Thu Aug 11 20:38:44 2005
@@ -116,7 +116,6 @@
 ^tools/ioemu/target-.*/Makefile$
 ^tools/ioemu/target-.*/config\..*$
 ^tools/ioemu/target-.*/qemu-dm$
-^tools/ioemu/target-.*/qemu-vgaram-bin$
 ^tools/libxc/xen/.*$
 ^tools/misc/cpuperf/cpuperf-perfcntr$
 ^tools/misc/cpuperf/cpuperf-xen$
diff -r f90820349056 -r c589ca6d292b Makefile
--- a/Makefile  Thu Aug 11 18:44:59 2005
+++ b/Makefile  Thu Aug 11 20:38:44 2005
@@ -101,11 +101,6 @@
        for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
        for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
 
-install-twisted:
-       wget http://www.twistedmatrix.com/products/get-current.epy
-       tar -zxf Twisted-*.tar.gz
-       cd Twisted-* && python setup.py install
-
 install-logging: LOGGING=logging-0.4.9.2
 install-logging:
        [ -f $(LOGGING).tar.gz ] || wget 
http://www.red-dove.com/$(LOGGING).tar.gz
@@ -149,7 +144,6 @@
        @echo '  kclean           - clean guest kernel build trees'
        @echo ''
        @echo 'Dependency installation targets:'
-       @echo '  install-twisted  - install the Twisted Matrix Framework'
        @echo '  install-logging  - install the Python Logging package'
        @echo '  install-iptables - install iptables tools'
        @echo ''
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Thu Aug 
11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Thu Aug 
11 20:38:44 2005
@@ -669,7 +669,7 @@
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 CONFIG_REISERFS_PROC_INFO=y
 CONFIG_REISERFS_FS_XATTR=y
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Thu Aug 11 20:38:44 2005
@@ -227,12 +227,38 @@
        return scale_delta(delta, shadow->tsc_to_usec_mul, shadow->tsc_shift);
 }
 
-static void update_wallclock(void)
-{
-       shared_info_t *s = HYPERVISOR_shared_info;
+static void __update_wallclock(time_t sec, long nsec)
+{
        long wtm_nsec, xtime_nsec;
        time_t wtm_sec, xtime_sec;
-       u64 tmp, nsec;
+       u64 tmp, wc_nsec;
+
+       /* Adjust wall-clock time base based on wall_jiffies ticks. */
+       wc_nsec = processed_system_time;
+       wc_nsec += (u64)sec * 1000000000ULL;
+       wc_nsec += (u64)nsec;
+       wc_nsec -= (jiffies - wall_jiffies) * (u64)(NSEC_PER_SEC / HZ);
+
+       /* Split wallclock base into seconds and nanoseconds. */
+       tmp = wc_nsec;
+       xtime_nsec = do_div(tmp, 1000000000);
+       xtime_sec  = (time_t)tmp;
+
+       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - xtime_sec);
+       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - xtime_nsec);
+
+       set_normalized_timespec(&xtime, xtime_sec, xtime_nsec);
+       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+       time_adjust = 0;                /* stop active adjtime() */
+       time_status |= STA_UNSYNC;
+       time_maxerror = NTP_PHASE_LIMIT;
+       time_esterror = NTP_PHASE_LIMIT;
+}
+
+static void update_wallclock(void)
+{
+       shared_info_t *s = HYPERVISOR_shared_info;
 
        do {
                shadow_tv_version = s->wc_version;
@@ -243,25 +269,8 @@
        }
        while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
 
-       if (independent_wallclock)
-               return;
-
-       /* Adjust wall-clock time base based on wall_jiffies ticks. */
-       nsec = processed_system_time;
-       nsec += (u64)shadow_tv.tv_sec * 1000000000ULL;
-       nsec += (u64)shadow_tv.tv_nsec;
-       nsec -= (jiffies - wall_jiffies) * (u64)(NSEC_PER_SEC / HZ);
-
-       /* Split wallclock base into seconds and nanoseconds. */
-       tmp = nsec;
-       xtime_nsec = do_div(tmp, 1000000000);
-       xtime_sec  = (time_t)tmp;
-
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - xtime_sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - xtime_nsec);
-
-       set_normalized_timespec(&xtime, xtime_sec, xtime_nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+       if (!independent_wallclock)
+               __update_wallclock(shadow_tv.tv_sec, shadow_tv.tv_nsec);
 }
 
 /*
@@ -408,18 +417,14 @@
 
 int do_settimeofday(struct timespec *tv)
 {
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec;
+       time_t sec;
        s64 nsec;
-       struct timespec xentime;
        unsigned int cpu;
        struct shadow_time_info *shadow;
+       dom0_op_t op;
 
        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                return -EINVAL;
-
-       if (!independent_wallclock && !(xen_start_info.flags & SIF_INITDOMAIN))
-               return 0; /* Silent failure? */
 
        cpu = get_cpu();
        shadow = &per_cpu(shadow_time, cpu);
@@ -431,51 +436,30 @@
         * overflows. If that were to happen then our shadow time values would
         * be stale, so we can retry with fresh ones.
         */
- again:
-       nsec = (s64)tv->tv_nsec - (s64)get_nsec_offset(shadow);
-       if (unlikely(!time_values_up_to_date(cpu))) {
+       for ( ; ; ) {
+               nsec = (s64)tv->tv_nsec - (s64)get_nsec_offset(shadow);
+               if (time_values_up_to_date(cpu))
+                       break;
                get_time_values_from_xen();
-               goto again;
-       }
-
+       }
+       sec = tv->tv_sec;
        __normalize_time(&sec, &nsec);
-       set_normalized_timespec(&xentime, sec, nsec);
-
-       /*
-        * This is revolting. We need to set "xtime" correctly. However, the
-        * value in this location is the value at the most recent update of
-        * wall time.  Discover what correction gettimeofday() would have
-        * made, and then undo it!
-        */
-       nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
-
-       nsec -= (shadow->system_timestamp - processed_system_time);
-
-       __normalize_time(&sec, &nsec);
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-       time_adjust = 0;                /* stop active adjtime() */
-       time_status |= STA_UNSYNC;
-       time_maxerror = NTP_PHASE_LIMIT;
-       time_esterror = NTP_PHASE_LIMIT;
-
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+
        if ((xen_start_info.flags & SIF_INITDOMAIN) &&
            !independent_wallclock) {
-               dom0_op_t op;
                op.cmd = DOM0_SETTIME;
-               op.u.settime.secs        = xentime.tv_sec;
-               op.u.settime.nsecs       = xentime.tv_nsec;
+               op.u.settime.secs        = sec;
+               op.u.settime.nsecs       = nsec;
                op.u.settime.system_time = shadow->system_timestamp;
-               write_sequnlock_irq(&xtime_lock);
                HYPERVISOR_dom0_op(&op);
-       } else
-#endif
-               write_sequnlock_irq(&xtime_lock);
+               update_wallclock();
+       } else if (independent_wallclock) {
+               nsec -= shadow->system_timestamp;
+               __normalize_time(&sec, &nsec);
+               __update_wallclock(sec, nsec);
+       }
+
+       write_sequnlock_irq(&xtime_lock);
 
        put_cpu();
 
@@ -491,6 +475,9 @@
        int retval;
 
        WARN_ON(irqs_disabled());
+
+       if (!(xen_start_info.flags & SIF_INITDOMAIN))
+               return 0;
 
        /* gets recalled with irq locally disabled */
        spin_lock_irq(&rtc_lock);
@@ -603,8 +590,10 @@
                profile_tick(CPU_PROFILING, regs);
        }
 
-       if (unlikely(shadow_tv_version != HYPERVISOR_shared_info->wc_version))
+       if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
                update_wallclock();
+               clock_was_set();
+       }
 }
 
 /*
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Thu Aug 11 20:38:44 2005
@@ -25,6 +25,7 @@
 #include <asm/mmu_context.h>
 
 #include <asm-xen/foreign_page.h>
+#include <asm-xen/hypervisor.h>
 
 void show_mem(void)
 {
@@ -273,6 +274,11 @@
 void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
 {
        unsigned long flags;
+
+#ifdef CONFIG_X86_PAE
+       /* this gives us a page below 4GB */
+       xen_contig_memory((unsigned long)pgd, 0);
+#endif
 
        if (!HAVE_SHARED_KERNEL_PMD)
                spin_lock_irqsave(&pgd_lock, flags);
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig      Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig      Thu Aug 11 20:38:44 2005
@@ -125,6 +125,10 @@
 config X86_IO_APIC
        bool
        default XEN_PRIVILEGED_GUEST
+
+config X86_XEN_GENAPIC
+       bool
+       default XEN_PRIVILEGED_GUEST || SMP
 
 config X86_LOCAL_APIC
        bool
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile      Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile      Thu Aug 11 
20:38:44 2005
@@ -25,11 +25,12 @@
 c-obj-$(CONFIG_X86_MSR)                += msr.o
 obj-$(CONFIG_MICROCODE)                += microcode.o
 obj-$(CONFIG_X86_CPUID)                += cpuid.o
-#obj-$(CONFIG_SMP)             += smp.o smpboot.o trampoline.o
+obj-$(CONFIG_SMP)              += smp.o smpboot.o
 obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o
 c-obj-$(CONFIG_X86_LOCAL_APIC) += nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o mpparse.o
-c-obj-$(CONFIG_X86_IO_APIC)    += genapic.o genapic_cluster.o genapic_flat.o
+obj-$(CONFIG_X86_XEN_GENAPIC)  += genapic.o genapic_xen.o
+c-obj-$(CONFIG_X86_IO_APIC)    += genapic_cluster.o genapic_flat.o
 #obj-$(CONFIG_PM)              += suspend.o
 #obj-$(CONFIG_SOFTWARE_SUSPEND)        += suspend_asm.o
 #obj-$(CONFIG_CPU_FREQ)                += cpufreq/
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/apic.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/apic.c        Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/apic.c        Thu Aug 11 
20:38:44 2005
@@ -48,7 +48,7 @@
        int cpu = smp_processor_id();
 
        profile_tick(CPU_PROFILING, regs);
-#if 0
+#ifndef CONFIG_XEN
        if (--per_cpu(prof_counter, cpu) <= 0) {
                /*
                 * The multiplier may have changed since the last time we got
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S        Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S        Thu Aug 11 
20:38:44 2005
@@ -41,7 +41,6 @@
 startup_64:
 ENTRY(_start)
         cld                
-       movq init_rsp(%rip),%rsp
        /* Copy the necessary stuff from xen_start_info structure. */
        movq  $xen_start_info_union,%rdi
        movq  $64,%rcx          /* sizeof (union xen_start_info_union) / sizeof 
(long) */
@@ -52,6 +51,7 @@
        cld
 #endif /* CONFIG_SMP */
 
+       movq init_rsp(%rip),%rsp
        /* zero EFLAGS after setting rsp */
        pushq $0
        popfq
@@ -204,6 +204,7 @@
        .quad   0,0                     /* TSS */
        .quad   0,0                     /* LDT */
        .quad   0,0,0                   /* three TLS descriptors */ 
+       .quad   0                       /* unused now?   __KERNEL16_CS - 16bit 
PM for S3 wakeup. */
 
 gdt_end:       
        /* asm/segment.h:GDT_ENTRIES must match this */ 
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c Thu Aug 11 20:38:44 2005
@@ -21,6 +21,11 @@
 
 atomic_t irq_err_count;
 
+#ifdef CONFIG_X86_IO_APIC
+#ifdef APIC_MISMATCH_DEBUG
+atomic_t irq_mis_count;
+#endif
+#endif
 
 /*
  * Generic, controller-independent functions:
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Thu Aug 11 
20:38:44 2005
@@ -200,12 +200,14 @@
 #define ADAPTER_ROM_RESOURCES \
        (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
 
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
 static struct resource video_rom_resource = {
        .name = "Video ROM",
        .start = 0xc0000,
        .end = 0xc7fff,
        .flags = IORESOURCE_ROM,
 };
+#endif
 
 static struct resource video_ram_resource = {
        .name = "Video RAM area",
@@ -599,6 +601,19 @@
         }
 }
 
+#ifdef CONFIG_XEN
+void __init smp_alloc_memory(void)
+{
+       int cpu;
+
+       for (cpu = 1; cpu < NR_CPUS; cpu++) {
+               cpu_gdt_descr[cpu].address = (unsigned long)
+                       alloc_bootmem_low_pages(PAGE_SIZE);
+               /* XXX free unused pages later */
+       }
+}
+#endif
+
 void __init setup_arch(char **cmdline_p)
 {
        int i, j;
@@ -739,6 +754,11 @@
                        initrd_start = 0;
                }
        }
+#endif
+#ifdef CONFIG_SMP
+#ifdef CONFIG_XEN
+       smp_alloc_memory();
+#endif
 #endif
        paging_init();
 #ifdef CONFIG_X86_LOCAL_APIC
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Thu Aug 11 
20:38:44 2005
@@ -276,9 +276,11 @@
         * Initialize the per-CPU GDT with the boot GDT,
         * and set up the GDT descriptor:
         */
+#ifndef CONFIG_XEN 
        if (cpu) {
                memcpy(cpu_gdt_table[cpu], cpu_gdt_table[0], GDT_SIZE);
        }       
+#endif
 
        cpu_gdt_descr[cpu].size = GDT_SIZE;
        cpu_gdt_descr[cpu].address = (unsigned long)cpu_gdt_table[cpu];
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Thu Aug 11 20:38:44 2005
@@ -28,7 +28,12 @@
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
 #include <asm/apicdef.h>
-
+#ifdef CONFIG_XEN
+#include <asm-xen/evtchn.h>
+
+#define xxprint(msg) HYPERVISOR_console_io(CONSOLEIO_write, strlen(msg), msg)
+
+#else
 /*
  *     Smarter SMP flushing macros. 
  *             c/o Linus Torvalds.
@@ -44,6 +49,7 @@
 static unsigned long flush_va;
 static DEFINE_SPINLOCK(tlbstate_lock);
 #define FLUSH_ALL      -1ULL
+#endif
 
 /*
  * We cannot call mmdrop() because we are in interrupt context, 
@@ -57,6 +63,7 @@
        load_cr3(swapper_pg_dir);
 }
 
+#ifndef CONFIG_XEN
 /*
  *
  * The flush IPI assumes that a thread switch happens in this order:
@@ -250,6 +257,18 @@
 {
        on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
 }
+#else
+asmlinkage void smp_invalidate_interrupt (void)
+{ return; }
+void flush_tlb_current_task(void)
+{ xen_tlb_flush_mask(&current->mm->cpu_vm_mask); }
+void flush_tlb_mm (struct mm_struct * mm)
+{ xen_tlb_flush_mask(&mm->cpu_vm_mask); }
+void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
+{ xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
+void flush_tlb_all(void)
+{ xen_tlb_flush_all(); }
+#endif /* Xen */
 
 void smp_kdb_stop(void)
 {
@@ -310,13 +329,21 @@
 
        /* Wait for response */
        while (atomic_read(&data.started) != cpus)
+#ifndef CONFIG_XEN
                cpu_relax();
+#else
+               barrier();
+#endif
 
        if (!wait)
                return;
 
        while (atomic_read(&data.finished) != cpus)
+#ifndef CONFIG_XEN
                cpu_relax();
+#else
+               barrier();
+#endif
 }
 
 /*
@@ -350,7 +377,11 @@
         */
        cpu_clear(smp_processor_id(), cpu_online_map);
        local_irq_disable();
+#ifndef CONFIG_XEN
        disable_local_APIC();
+#else
+       xxprint("stop_this_cpu disable_local_APIC\n");
+#endif
        local_irq_enable(); 
 }
 
@@ -364,8 +395,10 @@
 void smp_send_stop(void)
 {
        int nolock = 0;
+#ifndef CONFIG_XEN
        if (reboot_force)
                return;
+#endif
        /* Don't deadlock on the call lock in panic */
        if (!spin_trylock(&call_lock)) {
                /* ignore locking because we have paniced anyways */
@@ -376,7 +409,11 @@
                spin_unlock(&call_lock);
 
        local_irq_disable();
+#ifdef CONFIG_XEN
+       xxprint("stop_this_cpu disable_local_APIC\n");
+#else
        disable_local_APIC();
+#endif
        local_irq_enable();
 }
 
@@ -385,18 +422,32 @@
  * all the work is done automatically when
  * we return from the interrupt.
  */
+#ifndef CONFIG_XEN
 asmlinkage void smp_reschedule_interrupt(void)
-{
+#else
+asmlinkage irqreturn_t smp_reschedule_interrupt(void)
+#endif
+{
+#ifndef CONFIG_XEN
        ack_APIC_irq();
-}
-
+#else
+       return IRQ_HANDLED;
+#endif
+}
+
+#ifndef CONFIG_XEN
 asmlinkage void smp_call_function_interrupt(void)
+#else
+asmlinkage irqreturn_t smp_call_function_interrupt(void)
+#endif
 {
        void (*func) (void *info) = call_data->func;
        void *info = call_data->info;
        int wait = call_data->wait;
 
+#ifndef CONFIG_XEN
        ack_APIC_irq();
+#endif
        /*
         * Notify initiating CPU that I've grabbed the data and am
         * about to execute the function
@@ -413,10 +464,16 @@
                mb();
                atomic_inc(&call_data->finished);
        }
+#ifdef CONFIG_XEN
+       return IRQ_HANDLED;
+#endif
 }
 
 int safe_smp_processor_id(void)
 {
+#ifdef CONFIG_XEN
+       return smp_processor_id();
+#else
        int apicid, i;
 
        if (disable_apic)
@@ -437,4 +494,5 @@
                return 0;
 
        return 0; /* Should not happen */
-}
+#endif
+}
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Thu Aug 11 
20:38:44 2005
@@ -47,6 +47,9 @@
 #include <linux/bootmem.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
+#ifdef CONFIG_XEN
+#include <linux/interrupt.h>
+#endif
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
@@ -57,11 +60,20 @@
 #include <asm/tlbflush.h>
 #include <asm/proto.h>
 #include <asm/nmi.h>
+#ifdef CONFIG_XEN
+#include <asm/arch_hooks.h>
+
+#include <asm-xen/evtchn.h>
+#endif
 
 /* Change for real CPU hotplug. Note other files need to be fixed
    first too. */
 #define __cpuinit __init
 #define __cpuinitdata __initdata
+
+#if defined(CONFIG_XEN) && !defined(CONFIG_XEN_PRIVILEGED_GUEST)
+       unsigned int maxcpus = NR_CPUS;
+#endif
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -96,6 +108,7 @@
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
 EXPORT_SYMBOL(cpu_core_map);
 
+#ifndef CONFIG_XEN
 /*
  * Trampoline 80x86 program as an array.
  */
@@ -115,6 +128,7 @@
        memcpy(tramp, trampoline_data, trampoline_end - trampoline_data);
        return virt_to_phys(tramp);
 }
+#endif
 
 /*
  * The bootstrap kernel entry code has set these up. Save them for
@@ -130,6 +144,7 @@
        print_cpu_info(c);
 }
 
+#ifndef CONFIG_XEN
 /*
  * New Funky TSC sync algorithm borrowed from IA64.
  * Main advantage is that it doesn't reset the TSCs fully and
@@ -331,6 +346,7 @@
        return 0;
 }
 __setup("notscsync", notscsync_setup);
+#endif
 
 static atomic_t init_deasserted __cpuinitdata;
 
@@ -343,6 +359,7 @@
        int cpuid, phys_id;
        unsigned long timeout;
 
+#ifndef CONFIG_XEN
        /*
         * If waken up by an INIT in an 82489DX configuration
         * we may get here before an INIT-deassert IPI reaches
@@ -352,10 +369,15 @@
        while (!atomic_read(&init_deasserted))
                cpu_relax();
 
+#endif
        /*
         * (This works even if the APIC is not enabled.)
         */
+#ifndef CONFIG_XEN
        phys_id = GET_APIC_ID(apic_read(APIC_ID));
+#else
+       phys_id = smp_processor_id();
+#endif
        cpuid = smp_processor_id();
        if (cpu_isset(cpuid, cpu_callin_map)) {
                panic("smp_callin: phys CPU#%d, CPU#%d already present??\n",
@@ -389,6 +411,7 @@
                        cpuid);
        }
 
+#ifndef CONFIG_XEN
        /*
         * the boot CPU has finished the init stage and is spinning
         * on callin_map until we finish. We are free to set up this
@@ -398,6 +421,7 @@
 
        Dprintk("CALLIN, before setup_local_APIC().\n");
        setup_local_APIC();
+#endif
 
        /*
         * Get our bogomips.
@@ -405,7 +429,9 @@
        calibrate_delay();
        Dprintk("Stack at about %p\n",&cpuid);
 
+#ifndef CONFIG_XEN
        disable_APIC_timer();
+#endif
 
        /*
         * Save our processor parameters
@@ -417,6 +443,29 @@
         */
        cpu_set(cpuid, cpu_callin_map);
 }
+
+#ifdef CONFIG_XEN
+static irqreturn_t ldebug_interrupt(
+       int irq, void *dev_id, struct pt_regs *regs)
+{
+       return IRQ_HANDLED;
+}
+
+static DEFINE_PER_CPU(int, ldebug_irq);
+static char ldebug_name[NR_CPUS][15];
+
+void ldebug_setup(void)
+{
+       int cpu = smp_processor_id();
+
+       per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG);
+       sprintf(ldebug_name[cpu], "ldebug%d", cpu);
+       BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt,
+                          SA_INTERRUPT, ldebug_name[cpu], NULL));
+}
+
+extern void local_setup_timer(void);
+#endif
 
 /*
  * Setup code on secondary processor (after comming out of the trampoline)
@@ -434,6 +483,7 @@
        /* otherwise gcc will move up the smp_processor_id before the cpu_init 
*/
        barrier();
 
+#ifndef CONFIG_XEN
        Dprintk("cpu %d: setting up apic clock\n", smp_processor_id());         
        setup_secondary_APIC_clock();
 
@@ -446,6 +496,12 @@
        }
 
        enable_APIC_timer();
+#else
+       local_setup_timer();
+       ldebug_setup();
+       smp_intr_init();
+       local_irq_enable();
+#endif
 
        /*
         * Allow the master to continue.
@@ -453,10 +509,12 @@
        cpu_set(smp_processor_id(), cpu_online_map);
        mb();
 
+#ifndef CONFIG_XEN
        /* Wait for TSC sync to not schedule things before.
           We still process interrupts, which could see an inconsistent
           time in that window unfortunately. */
        tsc_sync_wait();
+#endif
 
        cpu_idle();
 }
@@ -464,6 +522,7 @@
 extern volatile unsigned long init_rsp;
 extern void (*initial_code)(void);
 
+#ifndef CONFIG_XEN
 #if APIC_DEBUG
 static void inquire_remote_apic(int apicid)
 {
@@ -627,6 +686,7 @@
 
        return (send_status | accept_status);
 }
+#endif
 
 /*
  * Boot one CPU.
@@ -637,6 +697,14 @@
        unsigned long boot_error;
        int timeout;
        unsigned long start_rip;
+#ifdef CONFIG_XEN
+       vcpu_guest_context_t ctxt;
+       extern void startup_64_smp(void);
+       extern void hypervisor_callback(void);
+       extern void failsafe_callback(void);
+       extern void smp_trap_init(trap_info_t *);
+       int i;
+#endif
        /*
         * We can't use kernel_thread since we must avoid to
         * reschedule the child.
@@ -649,7 +717,11 @@
 
        cpu_pda[cpu].pcurrent = idle;
 
+#ifndef CONFIG_XEN
        start_rip = setup_trampoline();
+#else
+       start_rip = (unsigned long)startup_64_smp;
+#endif
 
        init_rsp = idle->thread.rsp;
        per_cpu(init_tss,cpu).rsp0 = init_rsp;
@@ -666,6 +738,93 @@
 
        atomic_set(&init_deasserted, 0);
 
+#ifdef CONFIG_XEN
+       if (cpu_gdt_descr[0].size > PAGE_SIZE)
+               BUG();
+       cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size;
+       memcpy((void *)cpu_gdt_descr[cpu].address,
+               (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size);
+
+       memset(&ctxt, 0, sizeof(ctxt));
+
+       ctxt.flags = VGCF_IN_KERNEL;
+       ctxt.user_regs.ds = __USER_DS;
+       ctxt.user_regs.es = __USER_DS;
+       ctxt.user_regs.fs = 0;
+       ctxt.user_regs.gs = 0;
+       ctxt.user_regs.ss = __KERNEL_DS|0x3;
+       ctxt.user_regs.cs = __KERNEL_CS|0x3;
+       ctxt.user_regs.rip = start_rip;
+       ctxt.user_regs.rsp = idle->thread.rsp;
+#define X86_EFLAGS_IOPL_RING3 0x3000
+       ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING3;
+
+       /* FPU is set up to default initial state. */
+       memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
+
+       /* Virtual IDT is empty at start-of-day. */
+       for ( i = 0; i < 256; i++ )
+       {
+               ctxt.trap_ctxt[i].vector = i;
+               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
+       smp_trap_init(ctxt.trap_ctxt);
+
+       /* No LDT. */
+       ctxt.ldt_ents = 0;
+
+       {
+               unsigned long va;
+               int f;
+
+               for (va = cpu_gdt_descr[cpu].address, f = 0;
+                    va < cpu_gdt_descr[cpu].address + cpu_gdt_descr[cpu].size;
+                    va += PAGE_SIZE, f++) {
+                       ctxt.gdt_frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
+                       make_page_readonly((void *)va);
+               }
+               ctxt.gdt_ents = GDT_ENTRIES;
+       }
+
+       /* Ring 1 stack is the initial stack. */
+       ctxt.kernel_ss = __KERNEL_DS;
+       ctxt.kernel_sp = idle->thread.rsp;
+
+       /* Callback handlers. */
+       ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
+       ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
+       ctxt.syscall_callback_eip  = (unsigned long)system_call;
+
+       ctxt.ctrlreg[3] = (unsigned long)virt_to_machine(init_level4_pgt);
+
+       boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
+
+       if (!boot_error) {
+               /*
+                * allow APs to start initializing.
+                */
+               Dprintk("Before Callout %d.\n", cpu);
+               cpu_set(cpu, cpu_callout_map);
+               Dprintk("After Callout %d.\n", cpu);
+
+               /*
+                * Wait 5s total for a response
+                */
+               for (timeout = 0; timeout < 50000; timeout++) {
+                       if (cpu_isset(cpu, cpu_callin_map))
+                               break;  /* It has booted */
+                       udelay(100);
+               }
+
+               if (cpu_isset(cpu, cpu_callin_map)) {
+                       /* number CPUs logically, starting from 1 (BSP is 0) */
+                       Dprintk("CPU has booted.\n");
+               } else {
+                       boot_error= 1;
+               }
+       }
+       x86_cpu_to_apicid[cpu] = apicid;
+#else
        Dprintk("Setting warm reset code and vector.\n");
 
        CMOS_WRITE(0xa, 0xf);
@@ -729,6 +888,7 @@
 #endif
                }
        }
+#endif
        if (boot_error) {
                cpu_clear(cpu, cpu_callout_map); /* was set here 
(do_boot_cpu()) */
                clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
@@ -790,6 +950,7 @@
        }
 }
 
+#ifndef CONFIG_XEN
 /*
  * Cleanup possible dangling ends...
  */
@@ -817,6 +978,7 @@
        free_page((unsigned long) __va(SMP_TRAMPOLINE_BASE));
 #endif
 }
+#endif
 
 /*
  * Fall back to non SMP mode after errors.
@@ -827,10 +989,12 @@
 {
        cpu_present_map = cpumask_of_cpu(0);
        cpu_possible_map = cpumask_of_cpu(0);
+#ifndef CONFIG_XEN
        if (smp_found_config)
                phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
        else
                phys_cpu_present_map = physid_mask_of_physid(0);
+#endif
        cpu_set(0, cpu_sibling_map[0]);
        cpu_set(0, cpu_core_map[0]);
 }
@@ -857,6 +1021,7 @@
  */
 static int __cpuinit smp_sanity_check(unsigned max_cpus)
 {
+#ifndef CONFIG_XEN
        if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
                printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
                       hard_smp_processor_id());
@@ -896,13 +1061,19 @@
                nr_ioapics = 0;
                return -1;
        }
+#endif
 
        /*
         * If SMP should be disabled, then really disable it!
         */
        if (!max_cpus) {
+#ifdef CONFIG_XEN
+               HYPERVISOR_shared_info->n_vcpu = 1;
+#endif
                printk(KERN_INFO "SMP mode deactivated, forcing use of dummy 
APIC emulation.\n");
+#ifndef CONFIG_XEN
                nr_ioapics = 0;
+#endif
                return -1;
        }
 
@@ -917,7 +1088,10 @@
 {
        int i;
 
+#if defined(CONFIG_XEN) && !defined(CONFIG_XEN_PRIVILEGED_GUEST)
+#else
        nmi_watchdog_default();
+#endif
        current_cpu_data = boot_cpu_data;
        current_thread_info()->cpu = 0;  /* needed? */
 
@@ -927,8 +1101,12 @@
         * Fill in cpu_present_mask
         */
        for (i = 0; i < NR_CPUS; i++) {
+#ifndef CONFIG_XEN
                int apicid = cpu_present_to_apicid(i);
                if (physid_isset(apicid, phys_cpu_present_map)) {
+#else
+               if (i < HYPERVISOR_shared_info->n_vcpu) {
+#endif
                        cpu_set(i, cpu_present_map);
                        /* possible map would be different if we supported real
                           CPU hotplug. */
@@ -942,6 +1120,9 @@
                return;
        }
 
+#ifdef CONFIG_XEN
+       smp_intr_init();
+#else
 
        /*
         * Switch from PIC to APIC mode.
@@ -954,20 +1135,26 @@
                      GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id);
                /* Or can we switch back to PIC here? */
        }
+#endif
 
        /*
         * Now start the IO-APICs
         */
+#if defined(CONFIG_XEN) && !defined(CONFIG_XEN_PRIVILEGED_GUEST)
+#else
        if (!skip_ioapic_setup && nr_ioapics)
                setup_IO_APIC();
        else
                nr_ioapics = 0;
+#endif
 
        /*
         * Set up local APIC timer on boot CPU.
         */
 
+#ifndef CONFIG_XEN
        setup_boot_APIC_clock();
+#endif
 }
 
 /*
@@ -989,17 +1176,23 @@
 int __cpuinit __cpu_up(unsigned int cpu)
 {
        int err;
+#ifndef CONFIG_XEN
        int apicid = cpu_present_to_apicid(cpu);
+#else
+       int apicid = cpu;
+#endif
 
        WARN_ON(irqs_disabled());
 
        Dprintk("++++++++++++++++++++=_---CPU UP  %u\n", cpu);
 
+#ifndef CONFIG_XEN
        if (apicid == BAD_APICID || apicid == boot_cpu_id ||
            !physid_isset(apicid, phys_cpu_present_map)) {
                printk("__cpu_up: bad cpu %d\n", cpu);
                return -EINVAL;
        }
+#endif
 
        /* Boot it! */
        err = do_boot_cpu(cpu, apicid);
@@ -1021,15 +1214,76 @@
  */
 void __cpuinit smp_cpus_done(unsigned int max_cpus)
 {
+#ifndef CONFIG_XEN
        zap_low_mappings();
        smp_cleanup_boot();
 
 #ifdef CONFIG_X86_IO_APIC
        setup_ioapic_dest();
 #endif
+#endif
 
        detect_siblings();
+#ifndef CONFIG_XEN
        time_init_gtod();
 
        check_nmi_watchdog();
-}
+#endif
+}
+
+#ifdef CONFIG_XEN
+extern int bind_ipi_to_irq(int ipi);
+extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *);
+extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *);
+
+static DEFINE_PER_CPU(int, resched_irq);
+static DEFINE_PER_CPU(int, callfunc_irq);
+static char resched_name[NR_CPUS][15];
+static char callfunc_name[NR_CPUS][15];
+
+void smp_intr_init(void)
+{
+       int cpu = smp_processor_id();
+
+       per_cpu(resched_irq, cpu) =
+               bind_ipi_to_irq(RESCHEDULE_VECTOR);
+       sprintf(resched_name[cpu], "resched%d", cpu);
+       BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
+                          SA_INTERRUPT, resched_name[cpu], NULL));
+
+       per_cpu(callfunc_irq, cpu) =
+               bind_ipi_to_irq(CALL_FUNCTION_VECTOR);
+       sprintf(callfunc_name[cpu], "callfunc%d", cpu);
+       BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
+                          smp_call_function_interrupt,
+                          SA_INTERRUPT, callfunc_name[cpu], NULL));
+}
+
+static void smp_intr_exit(void)
+{
+       int cpu = smp_processor_id();
+
+       free_irq(per_cpu(resched_irq, cpu), NULL);
+       unbind_ipi_from_irq(RESCHEDULE_VECTOR);
+
+       free_irq(per_cpu(callfunc_irq, cpu), NULL);
+       unbind_ipi_from_irq(CALL_FUNCTION_VECTOR);
+}
+
+extern void local_setup_timer_irq(void);
+extern void local_teardown_timer_irq(void);
+
+void smp_suspend(void)
+{
+       /* XXX todo: take down time and ipi's on all cpus */
+       local_teardown_timer_irq();
+       smp_intr_exit();
+}
+
+void smp_resume(void)
+{
+       /* XXX todo: restore time and ipi's on all cpus */
+       smp_intr_init();
+       local_setup_timer_irq();
+}
+#endif
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Thu Aug 11 
20:38:44 2005
@@ -953,6 +953,17 @@
        cpu_init();
 }
 
+void smp_trap_init(trap_info_t *trap_ctxt)
+{
+       trap_info_t *t = trap_table;
+
+       for (t = trap_table; t->address; t++) {
+               trap_ctxt[t->vector].flags = t->flags;
+               trap_ctxt[t->vector].cs = t->cs;
+               trap_ctxt[t->vector].address = t->address;
+       }
+}
+
 
 /* Actual parsing is done early in setup.c. */
 static int __init oops_dummy(char *s)
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S   Thu Aug 11 
18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S   Thu Aug 11 
20:38:44 2005
@@ -8,11 +8,14 @@
 #define sizeof_vcpu_shift              3
 
 #ifdef CONFIG_SMP
-#define preempt_disable(reg)   incl threadinfo_preempt_count(reg)
-#define preempt_enable(reg)    decl threadinfo_preempt_count(reg)
+//#define preempt_disable(reg) incl threadinfo_preempt_count(reg)
+//#define preempt_enable(reg)  decl threadinfo_preempt_count(reg)
+#define preempt_disable(reg)
+#define preempt_enable(reg)
 #define XEN_GET_VCPU_INFO(reg) preempt_disable(%rbp)                   ; \
                                movq %gs:pda_cpunumber,reg              ; \
-                               shl  $sizeof_vcpu_shift,reg             ; \
+                               shl  $32, reg                           ; \
+                               shr  $32-sizeof_vcpu_shift,reg          ; \
                                addq HYPERVISOR_shared_info,reg
 #define XEN_PUT_VCPU_INFO(reg) preempt_enable(%rbp)                    ; \
 #define XEN_PUT_VCPU_INFO_fixup .byte 0xff,0xff,0xff
diff -r f90820349056 -r c589ca6d292b tools/console/client/main.c
--- a/tools/console/client/main.c       Thu Aug 11 18:44:59 2005
+++ b/tools/console/client/main.c       Thu Aug 11 20:38:44 2005
@@ -162,14 +162,11 @@
        struct termios attr;
        int domid;
        int xc_handle;
-       char *sopt = "hf:pc";
+       char *sopt = "h";
        int ch;
        int opt_ind=0;
        struct option lopt[] = {
                { "help",    0, 0, 'h' },
-               { "file",    1, 0, 'f' },
-               { "pty",     0, 0, 'p' },
-               { "ctty",    0, 0, 'c' },
                { 0 },
 
        };
@@ -178,6 +175,7 @@
        int spty;
        unsigned int len = 0;
        struct xs_handle *xs;
+       char *end;
 
        while((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
                switch(ch) {
@@ -195,7 +193,13 @@
                exit(EINVAL);
        }
        
-       domid = atoi(argv[optind]);
+       domid = strtol(argv[optind], &end, 10);
+       if (end && *end) {
+               fprintf(stderr, "Invalid DOMID `%s'\n", argv[optind]);
+               fprintf(stderr, "Try `%s --help' for more information.\n",
+                       argv[0]);
+               exit(EINVAL);
+       }
 
        xs = xs_daemon_open();
        if (xs == NULL) {
@@ -211,7 +215,11 @@
 
        snprintf(path, sizeof(path), "/console/%d/tty", domid);
        str_pty = xs_read(xs, path, &len);
-       if (str_pty == NULL) {
+       /* FIXME consoled currently does not assume domain-0 doesn't have a
+          console which is good when we break domain-0 up.  To keep us
+          user friendly, we'll bail out here since no data will ever show
+          up on domain-0. */
+       if (domid == 0 || str_pty == NULL) {
                err(errno, "Could not read tty from store");
        }
        spty = open(str_pty, O_RDWR | O_NOCTTY);
diff -r f90820349056 -r c589ca6d292b tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Thu Aug 11 18:44:59 2005
+++ b/tools/ioemu/target-i386-dm/Makefile       Thu Aug 11 20:38:44 2005
@@ -376,10 +376,10 @@
        $(CC) $(DEFINES) -c -o $@ $<
 
 clean:
-       rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp 
qemu-vgaram-bin
+       rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp
 
 distclean:
-       rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp 
qemu-vgaram-bin
+       rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp
 
 install: all 
        if [ ! -d $(INSTALL_DIR) ];then mkdir -p $(INSTALL_DIR);fi
@@ -387,8 +387,6 @@
        install -m 755 -s $(PROGS) "$(INSTALL_DIR)"
        install -m 755 qemu-dm.debug "$(INSTALL_DIR)"
        install -m 755 qemu-ifup "$(DESTDIR)$(configdir)"
-       gunzip -c qemu-vgaram-bin.gz >qemu-vgaram-bin 
-       install -m 755 qemu-vgaram-bin "$(DESTDIR)$(configdir)"
 ifneq ($(wildcard .depend),)
 include .depend
 endif
diff -r f90820349056 -r c589ca6d292b tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Aug 11 18:44:59 2005
+++ b/tools/python/xen/xm/main.py       Thu Aug 11 20:38:44 2005
@@ -265,7 +265,7 @@
     print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
     for dominfo in domsinfo:
         if dominfo.has_key("ssidref1"):
-            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   
%(state)5s  %(cpu_time)7.1f     %s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
+            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   
%(state)5s  %(cpu_time)7.1f     s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
         else:
             print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   
%(state)5s  %(cpu_time)7.1f" % dominfo)
 
@@ -605,6 +605,10 @@
         deprecated(cmd,aliases[cmd])
         return commands[aliases[cmd]]
     else:
+        if len( cmd ) > 1:
+            matched_commands = filter( lambda (command, func): command[ 
0:len(cmd) ] == cmd, commands.iteritems() )
+            if len( matched_commands ) == 1:
+                       return matched_commands[0][1]
         err('Sub Command %s not found!' % cmd)
         usage()
 
diff -r f90820349056 -r c589ca6d292b xen/arch/ia64/vcpu.c
--- a/xen/arch/ia64/vcpu.c      Thu Aug 11 18:44:59 2005
+++ b/xen/arch/ia64/vcpu.c      Thu Aug 11 20:38:44 2005
@@ -587,6 +587,14 @@
        set_bit(vector,PSCBX(vcpu,irr));
        PSCB(vcpu,pending_interruption) = 1;
     }
+
+    /* Keir: I think you should unblock when an interrupt is pending. */
+    {
+        int running = test_bit(_VCPUF_running, &vcpu->vcpu_flags);
+        vcpu_unblock(vcpu);
+        if ( running )
+            smp_send_event_check_cpu(vcpu->processor);
+    }
 }
 
 void early_tick(VCPU *vcpu)
diff -r f90820349056 -r c589ca6d292b xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Aug 11 18:44:59 2005
+++ b/xen/arch/x86/domain.c     Thu Aug 11 20:38:44 2005
@@ -279,8 +279,6 @@
     
     shadow_lock_init(d);        
     INIT_LIST_HEAD(&d->arch.free_shadow_frames);
-
-    init_domain_time(d);
 }
 
 void arch_do_boot_vcpu(struct vcpu *v)
@@ -503,7 +501,10 @@
     }
 
     update_pagetables(v);
-    
+
+    if ( v->vcpu_id == 0 )
+        init_domain_time(d);
+
     /* Don't redo final setup */
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
 
diff -r f90820349056 -r c589ca6d292b xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Aug 11 18:44:59 2005
+++ b/xen/arch/x86/domain_build.c       Thu Aug 11 20:38:44 2005
@@ -74,7 +74,7 @@
                    unsigned long _initrd_start, unsigned long initrd_len,
                    char *cmdline)
 {
-    int i, rc, dom0_pae, xen_pae;
+    int i, rc, dom0_pae, xen_pae, order;
     unsigned long pfn, mfn;
     unsigned long nr_pages;
     unsigned long nr_pt_pages;
@@ -143,10 +143,6 @@
         nr_pages = avail_domheap_pages() +
             ((initrd_len + PAGE_SIZE - 1) >> PAGE_SHIFT) +
             ((image_len  + PAGE_SIZE - 1) >> PAGE_SHIFT);
-    if ( (page = alloc_largest(d, nr_pages)) == NULL )
-        panic("Not enough RAM for DOM0 reservation.\n");
-    alloc_spfn = page_to_pfn(page);
-    alloc_epfn = alloc_spfn + d->tot_pages;
 
     if ( (rc = parseelfimage(&dsi)) != 0 )
         return rc;
@@ -215,8 +211,15 @@
 #endif
     }
 
-    if ( ((v_end - dsi.v_start) >> PAGE_SHIFT) > (alloc_epfn - alloc_spfn) )
-        panic("Insufficient contiguous RAM to build kernel image.\n");
+    order = get_order(v_end - dsi.v_start);
+    if ( (1UL << order) > nr_pages )
+        panic("Domain 0 allocation is too small for kernel image.\n");
+
+    /* Allocate from DMA pool: PAE L3 table must be below 4GB boundary. */
+    if ( (page = alloc_domheap_pages(d, order, ALLOC_DOM_DMA)) == NULL )
+        panic("Not enough RAM for domain 0 allocation.\n");
+    alloc_spfn = page_to_pfn(page);
+    alloc_epfn = alloc_spfn + d->tot_pages;
 
     printk("PHYSICAL MEMORY ARRANGEMENT:\n"
            " Dom0 alloc.:   %"PRIphysaddr"->%"PRIphysaddr,
@@ -615,6 +618,8 @@
     /* DOM0 gets access to everything. */
     physdev_init_dom0(d);
 
+    init_domain_time(d);
+
     set_bit(_DOMF_constructed, &d->domain_flags);
 
     new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start);
diff -r f90820349056 -r c589ca6d292b xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Aug 11 18:44:59 2005
+++ b/xen/arch/x86/mm.c Thu Aug 11 20:38:44 2005
@@ -95,6 +95,7 @@
 #include <xen/irq.h>
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
+#include <xen/event.h>
 #include <asm/shadow.h>
 #include <asm/page.h>
 #include <asm/flushtlb.h>
@@ -855,6 +856,14 @@
     int            i;
 
     ASSERT(!shadow_mode_refcounts(d));
+
+#ifdef CONFIG_X86_PAE
+    if ( pfn >= 0x100000 )
+    {
+        MEM_LOG("PAE pgd must be below 4GB (0x%lx >= 0x100000)", pfn);
+        return 0;
+    }
+#endif
 
     pl3e = map_domain_page(pfn);
     for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ )
diff -r f90820349056 -r c589ca6d292b xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Thu Aug 11 18:44:59 2005
+++ b/xen/arch/x86/setup.c      Thu Aug 11 20:38:44 2005
@@ -248,10 +248,11 @@
 {
     char *cmdline;
     module_t *mod = (module_t *)__va(mbi->mods_addr);
-    unsigned long firsthole_start, nr_pages;
+    unsigned long nr_pages, modules_length;
     unsigned long initial_images_start, initial_images_end;
     unsigned long _initrd_start = 0, _initrd_len = 0;
     unsigned int initrdidx = 1;
+    physaddr_t s, e;
     struct e820entry e820_raw[E820MAX];
     int i, e820_raw_nr = 0, bytes = 0;
     struct ns16550_defaults ns16550 = {
@@ -330,22 +331,31 @@
 
     max_page = init_e820(e820_raw, &e820_raw_nr);
 
-    /* Find the first high-memory RAM hole. */
-    for ( i = 0; i < e820.nr_map; i++ )
+    modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
+
+    /* Find a large enough RAM extent to stash the DOM0 modules. */
+    for ( i = 0; ; i++ )
+    {
         if ( (e820.map[i].type == E820_RAM) &&
-             (e820.map[i].addr >= 0x100000) )
+             (e820.map[i].size >= modules_length) &&
+             ((e820.map[i].addr + e820.map[i].size) >=
+              (xenheap_phys_end + modules_length)) )
+        {
+            /* Stash as near as possible to the beginning of the RAM extent. */
+            initial_images_start = e820.map[i].addr;
+            if ( initial_images_start < xenheap_phys_end )
+                initial_images_start = xenheap_phys_end;
+            initial_images_end = initial_images_start + modules_length;
             break;
-    firsthole_start = e820.map[i].addr + e820.map[i].size;
-
-    /* Relocate the Multiboot modules. */
-    initial_images_start = xenheap_phys_end;
-    initial_images_end   = initial_images_start + 
-        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-    if ( initial_images_end > firsthole_start )
-    {
-        printk("Not enough memory to stash the DOM0 kernel image.\n");
-        for ( ; ; ) ;
-    }
+        }
+
+        if ( i == e820.nr_map )
+        {
+            printk("Not enough memory to stash the DOM0 kernel image.\n");
+            for ( ; ; ) ;
+        }
+    }
+
 #if defined(CONFIG_X86_32)
     memmove((void *)initial_images_start,  /* use low mapping */
             (void *)mod[0].mod_start,      /* use low mapping */
@@ -358,16 +368,23 @@
 
     /* Initialise boot-time allocator with all RAM situated after modules. */
     xenheap_phys_start = init_boot_allocator(__pa(&_end));
-    nr_pages   = 0;
+    nr_pages = 0;
     for ( i = 0; i < e820.nr_map; i++ )
     {
         if ( e820.map[i].type != E820_RAM )
             continue;
+
         nr_pages += e820.map[i].size >> PAGE_SHIFT;
-        if ( (e820.map[i].addr + e820.map[i].size) >= initial_images_end )
-            init_boot_pages((e820.map[i].addr < initial_images_end) ?
-                            initial_images_end : e820.map[i].addr,
-                            e820.map[i].addr + e820.map[i].size);
+
+        /* Initialise boot heap, skipping Xen heap and dom0 modules. */
+        s = e820.map[i].addr;
+        e = s + e820.map[i].size;
+        if ( s < xenheap_phys_end )
+            s = xenheap_phys_end;
+        if ( (s < initial_images_end) && (e > initial_images_start) )
+            s = initial_images_end;
+        init_boot_pages(s, e);
+
 #if defined (CONFIG_X86_64)
         /*
          * x86/64 maps all registered RAM. Points to note:
@@ -404,10 +421,30 @@
 
     end_boot_allocator();
 
-    init_xenheap_pages(xenheap_phys_start, xenheap_phys_end);
-    printk("Xen heap: %luMB (%lukB)\n",
-           (xenheap_phys_end-xenheap_phys_start) >> 20,
-           (xenheap_phys_end-xenheap_phys_start) >> 10);
+    /* Initialise the Xen heap, skipping RAM holes. */
+    nr_pages = 0;
+    for ( i = 0; i < e820.nr_map; i++ )
+    {
+        if ( e820.map[i].type != E820_RAM )
+            continue;
+
+        s = e820.map[i].addr;
+        e = s + e820.map[i].size;
+        if ( s < xenheap_phys_start )
+            s = xenheap_phys_start;
+        if ( e > xenheap_phys_end )
+            e = xenheap_phys_end;
+ 
+        if ( s < e )
+        {
+            nr_pages += (e - s) >> PAGE_SHIFT;
+            init_xenheap_pages(s, e);
+        }
+    }
+
+    printk("Xen heap: %luMB (%lukB)\n", 
+           nr_pages >> (20 - PAGE_SHIFT),
+           nr_pages << (PAGE_SHIFT - 10));
 
     early_boot = 0;
 
diff -r f90820349056 -r c589ca6d292b xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Thu Aug 11 18:44:59 2005
+++ b/xen/arch/x86/time.c       Thu Aug 11 20:38:44 2005
@@ -44,6 +44,7 @@
 int timer_ack = 0;
 unsigned long volatile jiffies;
 static u32 wc_sec, wc_nsec; /* UTC time at last 'time update'. */
+static spinlock_t wc_lock = SPIN_LOCK_UNLOCKED;
 
 struct time_scale {
     int shift;
@@ -699,13 +700,14 @@
     struct domain *d;
     shared_info_t *s;
 
-    x = (secs * 1000000000ULL) + (u64)nsecs + system_time_base;
+    x = (secs * 1000000000ULL) + (u64)nsecs - system_time_base;
     y = do_div(x, 1000000000);
 
     wc_sec  = _wc_sec  = (u32)x;
     wc_nsec = _wc_nsec = (u32)y;
 
     read_lock(&domlist_lock);
+    spin_lock(&wc_lock);
 
     for_each_domain ( d )
     {
@@ -716,15 +718,18 @@
         version_update_end(&s->wc_version);
     }
 
+    spin_unlock(&wc_lock);
     read_unlock(&domlist_lock);
 }
 
 void init_domain_time(struct domain *d)
 {
+    spin_lock(&wc_lock);
     version_update_begin(&d->shared_info->wc_version);
     d->shared_info->wc_sec  = wc_sec;
     d->shared_info->wc_nsec = wc_nsec;
     version_update_end(&d->shared_info->wc_version);
+    spin_unlock(&wc_lock);
 }
 
 static void local_time_calibration(void *unused)
diff -r f90820349056 -r c589ca6d292b xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Thu Aug 11 18:44:59 2005
+++ b/xen/common/page_alloc.c   Thu Aug 11 20:38:44 2005
@@ -418,6 +418,8 @@
 
     ps = round_pgup(ps);
     pe = round_pgdown(pe);
+    if ( pe <= ps )
+        return;
 
     memguard_guard_range(phys_to_virt(ps), pe - ps);
 
@@ -487,19 +489,25 @@
 
     ps = round_pgup(ps) >> PAGE_SHIFT;
     pe = round_pgdown(pe) >> PAGE_SHIFT;
-
-    if (ps < MAX_DMADOM_PFN && pe > MAX_DMADOM_PFN) {
-        init_heap_pages(MEMZONE_DMADOM, pfn_to_page(ps), MAX_DMADOM_PFN - ps);
-        init_heap_pages(MEMZONE_DOM, pfn_to_page(MAX_DMADOM_PFN),
-                        pe - MAX_DMADOM_PFN);
+    if ( pe <= ps )
+        return;
+
+    if ( (ps < MAX_DMADOM_PFN) && (pe > MAX_DMADOM_PFN) )
+    {
+        init_heap_pages(
+            MEMZONE_DMADOM, pfn_to_page(ps), MAX_DMADOM_PFN - ps);
+        init_heap_pages(
+            MEMZONE_DOM, pfn_to_page(MAX_DMADOM_PFN), pe - MAX_DMADOM_PFN);
     }
     else
+    {
         init_heap_pages(pfn_dom_zone_type(ps), pfn_to_page(ps), pe - ps);
-}
-
-
-struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order,
-                                     unsigned int flags)
+    }
+}
+
+
+struct pfn_info *alloc_domheap_pages(
+    struct domain *d, unsigned int order, unsigned int flags)
 {
     struct pfn_info *pg;
     cpumask_t mask;
diff -r f90820349056 -r c589ca6d292b xen/include/asm-x86/event.h
--- a/xen/include/asm-x86/event.h       Thu Aug 11 18:44:59 2005
+++ b/xen/include/asm-x86/event.h       Thu Aug 11 20:38:44 2005
@@ -11,6 +11,19 @@
 
 static inline void evtchn_notify(struct vcpu *v)
 {
+    /*
+     * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of
+     * pending flag. These values may fluctuate (after all, we hold no
+     * locks) but the key insight is that each change will cause
+     * evtchn_upcall_pending to be polled.
+     * 
+     * NB2. We save VCPUF_running across the unblock to avoid a needless
+     * IPI for domains that we IPI'd to unblock.
+     */
+    int running = test_bit(_VCPUF_running, &v->vcpu_flags);
+    vcpu_unblock(v);
+    if ( running )
+        smp_send_event_check_cpu(v->processor);
 }
 
 #endif
diff -r f90820349056 -r c589ca6d292b xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h        Thu Aug 11 18:44:59 2005
+++ b/xen/include/asm-x86/page.h        Thu Aug 11 20:38:44 2005
@@ -283,13 +283,9 @@
 static __inline__ int get_order(unsigned long size)
 {
     int order;
-    
-    size = (size-1) >> (PAGE_SHIFT-1);
-    order = -1;
-    do {
+    size = (size-1) >> PAGE_SHIFT;
+    for ( order = 0; size; order++ )
         size >>= 1;
-        order++;
-    } while (size);
     return order;
 }
 
diff -r f90820349056 -r c589ca6d292b xen/include/xen/event.h
--- a/xen/include/xen/event.h   Thu Aug 11 18:44:59 2005
+++ b/xen/include/xen/event.h   Thu Aug 11 20:38:44 2005
@@ -26,30 +26,14 @@
 {
     struct domain *d = v->domain;
     shared_info_t *s = d->shared_info;
-    int            running;
 
-    /* These three operations must happen in strict order. */
+    /* 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(port>>5, &v->vcpu_info->evtchn_pending_sel) &&
+         !test_and_set_bit(0,       &v->vcpu_info->evtchn_upcall_pending) )
     {
-        /* The VCPU pending flag must be set /after/ update to evtchn-pend. */
-        set_bit(0, &v->vcpu_info->evtchn_upcall_pending);
         evtchn_notify(v);
-
-        /*
-         * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of
-         * pending flag. These values may fluctuate (after all, we hold no
-         * locks) but the key insight is that each change will cause
-         * evtchn_upcall_pending to be polled.
-         * 
-         * NB2. We save VCPUF_running across the unblock to avoid a needless
-         * IPI for domains that we IPI'd to unblock.
-         */
-        running = test_bit(_VCPUF_running, &v->vcpu_flags);
-        vcpu_unblock(v);
-        if ( running )
-            smp_send_event_check_cpu(v->processor);
     }
 }
 
@@ -73,8 +57,9 @@
  */
 extern void send_guest_pirq(struct domain *d, int pirq);
 
-#define event_pending(_d)                                     \
-    ((_d)->vcpu_info->evtchn_upcall_pending && \
-     !(_d)->vcpu_info->evtchn_upcall_mask)
+/* Note: Bitwise operations result in fast code with no branches. */
+#define event_pending(v)                        \
+    ((v)->vcpu_info->evtchn_upcall_pending &    \
+     ~(v)->vcpu_info->evtchn_upcall_mask)
 
 #endif /* __XEN_EVENT_H__ */
diff -r f90820349056 -r c589ca6d292b xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Thu Aug 11 18:44:59 2005
+++ b/xen/include/xen/sched.h   Thu Aug 11 20:38:44 2005
@@ -297,10 +297,9 @@
         (unsigned long)(_a1), (unsigned long)(_a2), (unsigned long)(_a3), \
         (unsigned long)(_a4), (unsigned long)(_a5), (unsigned long)(_a6))
 
-#define hypercall_preempt_check() (unlikely(            \
-        softirq_pending(smp_processor_id()) |           \
-        (!!current->vcpu_info->evtchn_upcall_pending &  \
-          !current->vcpu_info->evtchn_upcall_mask)      \
+#define hypercall_preempt_check() (unlikely(    \
+        softirq_pending(smp_processor_id()) |   \
+        event_pending(current)                  \
     ))
 
 /* This domain_hash and domain_list are protected by the domlist_lock. */
diff -r f90820349056 -r c589ca6d292b xen/tools/symbols.c
--- a/xen/tools/symbols.c       Thu Aug 11 18:44:59 2005
+++ b/xen/tools/symbols.c       Thu Aug 11 20:38:44 2005
@@ -311,7 +311,7 @@
        off = 0;
        for (i = 0; i < cnt; i++) {
 
-               if (!table[i].flags & SYM_FLAG_VALID)
+               if (!(table[i].flags & SYM_FLAG_VALID))
                        continue;
 
                if ((valid & 0xFF) == 0)
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic.c
--- /dev/null   Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic.c     Thu Aug 11 
20:38:44 2005
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic APIC sub-arch probe layer.
+ *
+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
+ * James Cleverdon.
+ */
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/smp.h>
+#include <asm/ipi.h>
+
+#if defined(CONFIG_ACPI_BUS)
+#include <acpi/acpi_bus.h>
+#endif
+
+/* which logical CPU number maps to which CPU (physical APIC ID) */
+u8 x86_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+EXPORT_SYMBOL(x86_cpu_to_apicid);
+u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+
+extern struct genapic apic_cluster;
+extern struct genapic apic_flat;
+
+#ifndef CONFIG_XEN
+struct genapic *genapic = &apic_flat;
+#else
+extern struct genapic apic_xen;
+struct genapic *genapic = &apic_xen;
+#endif
+
+
+/*
+ * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
+ */
+void __init clustered_apic_check(void)
+{
+#ifndef CONFIG_XEN
+       long i;
+       u8 clusters, max_cluster;
+       u8 id;
+       u8 cluster_cnt[NUM_APIC_CLUSTERS];
+
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+               /* AMD always uses flat mode right now */
+               genapic = &apic_flat;
+               goto print;
+       }
+
+#if defined(CONFIG_ACPI_BUS)
+       /*
+        * Some x86_64 machines use physical APIC mode regardless of how many
+        * procs/clusters are present (x86_64 ES7000 is an example).
+        */
+       if (acpi_fadt.revision > FADT2_REVISION_ID)
+               if (acpi_fadt.force_apic_physical_destination_mode) {
+                       genapic = &apic_cluster;
+                       goto print;
+               }
+#endif
+
+       memset(cluster_cnt, 0, sizeof(cluster_cnt));
+
+       for (i = 0; i < NR_CPUS; i++) {
+               id = bios_cpu_apicid[i];
+               if (id != BAD_APICID)
+                       cluster_cnt[APIC_CLUSTERID(id)]++;
+       }
+
+       clusters = 0;
+       max_cluster = 0;
+       for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
+               if (cluster_cnt[i] > 0) {
+                       ++clusters;
+                       if (cluster_cnt[i] > max_cluster)
+                               max_cluster = cluster_cnt[i];
+               }
+       }
+
+       /*
+        * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode,
+        * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical
+        * else physical mode.
+        * (We don't use lowest priority delivery + HW APIC IRQ steering, so
+        * can ignore the clustered logical case and go straight to physical.)
+        */
+       if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster)
+               genapic = &apic_flat;
+       else
+               genapic = &apic_cluster;
+
+print:
+#else
+       /* hardcode to xen apic functions */
+       genapic = &apic_xen;
+#endif
+       printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+}
+
+/* Same for both flat and clustered. */
+
+#ifdef CONFIG_XEN
+extern void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned 
int dest);
+#endif
+
+void send_IPI_self(int vector)
+{
+#ifndef CONFIG_XEN
+       __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
+#else
+       xen_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
+#endif
+}
diff -r f90820349056 -r c589ca6d292b 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
--- /dev/null   Thu Aug 11 18:44:59 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Thu Aug 11 
20:38:44 2005
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
+ * Subject to the GNU Public License, v.2
+ *
+ * Xen APIC subarch code.  Maximum 8 CPUs, logical delivery.
+ *
+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
+ * James Cleverdon.
+ *
+ * Hacked to pieces for Xen by Chris Wright.
+ */
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+#include <asm/smp.h>
+#include <asm/ipi.h>
+#else
+#include <asm/apic.h>
+#include <asm/apicdef.h>
+#include <asm/genapic.h>
+#endif
+#include <asm-xen/evtchn.h>
+
+DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+
+static inline void __send_IPI_one(unsigned int cpu, int vector)
+{
+       unsigned int evtchn;
+       Dprintk("%s\n", __FUNCTION__);
+
+       evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+       if (evtchn)
+               notify_via_evtchn(evtchn);
+       else
+               printk("send_IPI to unbound port %d/%d", cpu, vector);
+}
+
+void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int 
dest)
+{
+       int cpu;
+
+       switch (shortcut) {
+       case APIC_DEST_SELF:
+               __send_IPI_one(smp_processor_id(), vector);
+               break;
+       case APIC_DEST_ALLBUT:
+               for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+                       if (cpu == smp_processor_id())
+                               continue;
+                       if (cpu_isset(cpu, cpu_online_map)) {
+                               __send_IPI_one(cpu, vector);
+                       }
+               }
+               break;
+       case APIC_DEST_ALLINC:
+               for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+                       if (cpu_isset(cpu, cpu_online_map)) {
+                               __send_IPI_one(cpu, vector);
+                       }
+               }
+               break;
+       default:
+               printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut,
+                      vector);
+               break;
+       }
+}
+
+static cpumask_t xen_target_cpus(void)
+{
+       return cpu_online_map;
+}
+
+/*
+ * Set up the logical destination ID.
+ * Do nothing, not called now.
+ */
+static void xen_init_apic_ldr(void)
+{
+       Dprintk("%s\n", __FUNCTION__);
+       return;
+}
+
+static void xen_send_IPI_allbutself(int vector)
+{
+       /*
+        * if there are no other CPUs in the system then
+        * we get an APIC send error if we try to broadcast.
+        * thus we have to avoid sending IPIs in this case.
+        */
+       Dprintk("%s\n", __FUNCTION__);
+       if (num_online_cpus() > 1)
+               xen_send_IPI_shortcut(APIC_DEST_ALLBUT, vector, 
APIC_DEST_LOGICAL);
+}
+
+static void xen_send_IPI_all(int vector)
+{
+       Dprintk("%s\n", __FUNCTION__);
+       xen_send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
+}
+
+static void xen_send_IPI_mask(cpumask_t cpumask, int vector)
+{
+       unsigned long mask = cpus_addr(cpumask)[0];
+       unsigned int cpu;
+       unsigned long flags;
+
+       Dprintk("%s\n", __FUNCTION__);
+       local_irq_save(flags);
+       WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
+
+       for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+               if (cpu_isset(cpu, cpumask)) {
+                       __send_IPI_one(cpu, vector);
+               }
+       }
+       local_irq_restore(flags);
+}
+
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+static int xen_apic_id_registered(void)
+{
+       /* better be set */
+       Dprintk("%s\n", __FUNCTION__);
+       return physid_isset(smp_processor_id(), phys_cpu_present_map);
+}
+#endif
+
+static unsigned int xen_cpu_mask_to_apicid(cpumask_t cpumask)
+{
+       Dprintk("%s\n", __FUNCTION__);
+       return cpus_addr(cpumask)[0] & APIC_ALL_CPUS;
+}
+
+static unsigned int phys_pkg_id(int index_msb)
+{
+       u32 ebx;
+
+       Dprintk("%s\n", __FUNCTION__);
+       ebx = cpuid_ebx(1);
+       return ((ebx >> 24) & 0xFF) >> index_msb;
+}
+
+struct genapic apic_xen =  {
+       .name = "xen",
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+       .int_delivery_mode = dest_LowestPrio,
+#endif
+       .int_dest_mode = (APIC_DEST_LOGICAL != 0),
+       .int_delivery_dest = APIC_DEST_LOGICAL | APIC_DM_LOWEST,
+       .target_cpus = xen_target_cpus,
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+       .apic_id_registered = xen_apic_id_registered,
+#endif
+       .init_apic_ldr = xen_init_apic_ldr,
+       .send_IPI_all = xen_send_IPI_all,
+       .send_IPI_allbutself = xen_send_IPI_allbutself,
+       .send_IPI_mask = xen_send_IPI_mask,
+       .cpu_mask_to_apicid = xen_cpu_mask_to_apicid,
+       .phys_pkg_id = phys_pkg_id,
+};
diff -r f90820349056 -r c589ca6d292b 
tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz
--- a/tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz     Thu Aug 11 18:44:59 2005
+++ /dev/null   Thu Aug 11 20:38:44 2005
@@ -1,7 +0,0 @@
-?ËmBqemu-vgaram-biníÝÍk\×ÇñCòÂÁMw¢    I
-^´?XÊ?#\c?Ô¡
\ No newline at end of file
-M7okɲe?L,a9?J?oò'B×Ýô(¨1?.L?Å?´x?lJ1/?ÜçÑ}Ï?3wf?h?s7ßü¸3wFsæ?{î¹ç¾?}öpJ=ÉÉ?dAr\2'yI²&Y?\?lH??¼#ù?äE{Ϫ½Ï_×÷¿/¹bÑϾ,¹*yÊ^ßÌÞ?/yáðuy|#½vø¯òY7äõòüïé?Ã?Èë7öò?¾çP
-?~ö}Éç6ÕÜ?|?=.ÿ-«?Õõ3gϵ?^¶×Ûê¬ÿ÷=©³]©³]Y/Ítéð5ymA??ÎÛûß·:=oõ{Åæ_µïsÁ?ë÷xMò¶=Õæ?µÇÃõð°dArM²kÓ?U÷?YÉIËWYf³×j?ïmÁ×y­òGÕÅìÈ÷?Ͷß%kC¾î7³vµjmCç?Xï÷GDëýfÞÊD,».ó?ä%ËJ\ݾ??ItzIru/7Óºô;'¤ÿ?ÛË'é?Ì[?×?í}öw¶{·lõ¿bóuÞE?w̶Ù¾.¾Ëc?#??I??lInÙ
-lo^çy¼íåÛ@YÍr=aýÎU˺µ³9ËY¼ÖlzqozZêðYyí´Ì??z??ùóò·óÒ?×åñ]ißwd=}çÔ?ÿCÉr6Ís15ÛÀ??íÀuàuüyê÷?'íù?ú?J>²åº#¹+¹??¾ÿ?=¿c¯Tþ?$3©iÿº?²òO¥þv1cïü[Ý·½?íWG?Wòýï?¶½®[?ítVÚ­Ôµ?1?äñ¦D§«ò¼'óõñ¹¬¯ýùTÛ?¦Üöò¤âqD>´væù?ä??D?­c?ÉbjÆ={¾c?uÞCöüZ`´e·Èàë/IÖ$Ë?K??lþ+?×%oJ?´ùOÛTß¿.yÿÁk³é¨lëoH_{AoJV%ò|Uæ¯ÉãËòøDö9Çlª?·ùG³éÉ?äªä?Äÿö{¿æ9ÉÜÞãÙô¼?3'e<+??¶þF§úü?=~Ú>G?ã?¢Ì?evLtÿ3~4ÝÌZ{Ûµi­r=ó©Ùvm:?ò½¾~?²6ð?=ßÈÖý?lýÿAò²ä÷?·mÞo%/JÞ°vsFúûW$oJ~gí^_˦OYð¿]²2ÎÛkú«öÞµ÷ýBò|ö=µ|ÝNþ?}O}ÿ/MM_wߦGÃêz¸þ?ã?
\ No newline at end of file
-IOú?%ɦ,ÿ?×?ÖÙe[.?êöÿ?=~Âê@?eÓê`Ù?¿þæZê{Õ:þ:XýyßöCÚ߯e;#ÛøS{}àIé7gåõfûoÚ?NgÓÙCM¿ªmì¹Û´7?÷?­ýs6ÿ?¯÷?#ß×ƵµÉõ§ûºÞÞúß?iO²$iÚ_Oê¯Ðþ¼?õ}ð§?m{>cù8õ÷½?ãÐdåkYÞïz_¸cß#ª\wøxcSòE<þÚ

*{>Ëbà2ÇÇ/kRßW÷ÆóÒ?äØ˾Ï?ä?DÇïí­?áþ^ç?ýý±,û¯ßï¶ÅÛB?zñcßû©\Üþ^ß?õû?u«ß?mXÝèû.Úß½?ÍÓ1àÖ@?5ÛØë2îyW¦OÚövîÁºjú?ò3uÞ¥CýmýÝCý¾÷²=î}¯uâÉÇbµÖ?fx¼Ý]¢û=??ýßv?;þÖx;÷s~~èÏÏÁ=¨_íw·Òøã?¨ò}ÿ7ªîõµÈö???cu=?%úØW?ùQ+W÷?·RÿøÇóX`ù»VÏ?ï*/ÿB¶®½ü?"?åïë?o?y¢Û_¾¬5?¿,ïz±þµ>"Ï{ÚúùZ}ÿ¤ò£÷½m}_>.?©T×G<?NÛò?õUvÞþ½Ì¼-Ôh?ùwøO=ÚN±Û¿_wÎÏýî¦á>(ª|íïóó×ÒðyøïË÷ñ?çù4Å?¿îYÝ?ºѳ÷D?¿kå??\JM_¯ÓE?·?bÇ_ãÊ÷Ü­¼þuÛóv¯¯?,¿ÜÎÚ¶½ÈíÏÏï?Kdû×±mÛy?Z×ß¿L?ÛÚ?%ß&¿

,_Ûöâ?ÔØþÊûLòcÏ<QåïXý~cË©ÛÞg©^ûoo×·íÿÊvÙÿ?[þÙúÐ÷è6y¤Òò?ûÃÈí/_~­k¿æ=?ê¬ßæ>IÝô¿?Ú~ôò·õ5幯Èñw[¹~ί?®T(?_V_ç+)¾ÿUßµÚ?ßïûq>æû?½u¿c²e+Ïõ??¾ÿô#Évjî÷ZOM¤çGß5ÝåuíDZüåqgdýN+Ól?Þ¶jßã2.[¶¾µ¿¯qýUs'õÇ9å¸;ÔX~lg?Þÿ=?·3¿P«þÛ??¿&½üÞ?Oý±îbª7þͳÙR÷·Rüq,z'[Î?}?²ýG?óó?©þøÓ¯3èã#iðÚC¯?i?¼þG??¬ÿQu^«þóèrúñH?å??Û~ôø;ϨcáZû?QË???ì'õÑ×¢¿Hýþo1ÕïÿËûákÜû®ã`~???=?§f?PcùÛÖ}ÍñGÇÿ£Ê/ÏÔ*?_æü@?òG?ÿñ{t{?¾u+
\ No newline at end of file
-ßyþûHÜ×®§áýoÄyOOYVÛ¼Èö_.oY^'Qåûý¾Q?¿ß´]?n{?Q×?ókÏ~>:b?t«x\³ÿ/ï/®}ü?¯s}ÞÅù?¼þk?¿?ÏAÕ.ßë~¡Ãú÷øv¸?úÇ?ù¶}4¥nοäç^k?_¶¿.??ÛÕ>ÿ??ñº(¿¬ÿÚå{ÛÛÏ=hÓ.»ì{j?_ÞÛè÷Aéóüx%Õû=ÆeɯRó{sóßNÍØì?À2O¥ÁsÞ»ixüñYPÙ£úß?çÚúßZåkûjëk?¯eo¥þ¨öø³\þ.Îì?'Oóú??=騨õ¿?M»(ß÷oZ¿z?e;ËÍ4ößß?JösíKÏÉGÞÿ\?sº_L#??¿÷K×±ßï¸?ÏT¾?ëx¤XÎë©}

¤ûÂi?)ǵ?Êãï.Æ¿ùò×Þÿ?åwÑÿçç¿j^ÿÊËÕ:Ö~fÜ=¸Ëî÷;hNÙ¼?¿;ZH?ÿö?·ÁZåkòßæÿÁv?oÿm)º]¹>´ü?"Qeùòù¿}Q^{Ðmà/©?öz¼bù+Vþ?S³mDÕŨë'³Ôºþ¦×:u[¼mÓã?Êõäåú÷?*ë§?3?´ü·%;Àô åÿ;5ç~ètZíþ?&²ü{?¯bùÇÇä?
      
¯G÷»?ßuýk½ÏTªÿI?ßEýûØ£«å÷ú¯q¾wܲÕ(Rÿ]þ¸tÕÿz¦=Îü¾åGþÞf?)Ï=uQÿÑåOZþ®×õÿxªWÿãú¿&¼Õÿk¹zìwºÂúoËi+¿«åÿ6Õkÿmñr¿íxýרÿqË_£þÇ­ÿõ?n¿×Õò{ºnÿ5úÿIߣËã?ýï¤ý_ë¿æþw\Nw¼þk´¿q㮮ǿ]Õh£þ_¥ý&rùk?÷?9hù?9`"븫v¿??k²·³øoâ¢ÊÜJ?׺oÛ4¿ö{+°üü>Ëí1?®{ý½1?.[?1õïG«õû§<~Ïg?ÈßÿxÚîyÈï??n¾íu1Þñ{?ü^p?_{?¾'b!?¾÷9¿7¢FÙ^f?ÿ?¯¿gÎÿíÙSi¸Öúý½®çü7÷µî?ùqj®;äåmÏ%Û?e??ú}?¦ü÷ïæSüï?÷óoF¯?Ý}<??÷sm÷¼F??ÆýÛÏ)ÅoyyÞæüûD?ï÷ ?÷¡vyü§©½ÿÏ?ëz˼ñ1@ù8*¾ï?ÞÇd]tù¢ËÐãÈ?Zòßl½è¾?jÿs;Õ?ÖȳnßÁû½¦îÎý\?.¾!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B!?B¢äþ½î4¡
\ No newline at end of file

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.