ia64/xen-unstable

changeset 1676:1c1155a226ec

bitkeeper revision 1.1041.5.8 (40e9b6eaotkt5EbH_KZlRdUM0Adj4A)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/hp.bk
author kaf24@scramble.cl.cam.ac.uk
date Mon Jul 05 20:15:38 2004 +0000 (2004-07-05)
parents e56d5f41a977 138e97a36173
children 35e97fc65a8b 56b68a269319
files .rootkeys xen/arch/x86/Makefile xen/arch/x86/Rules.mk xen/arch/x86/apic.c xen/arch/x86/domain.c xen/arch/x86/domain_page.c xen/arch/x86/entry.S xen/arch/x86/irq.c xen/arch/x86/mm.c xen/arch/x86/mpparse.c xen/arch/x86/process.c xen/arch/x86/rwlock.c xen/arch/x86/setup.c xen/arch/x86/smpboot.c xen/arch/x86/time.c xen/arch/x86/trampoline.S xen/arch/x86/traps.c xen/arch/x86/usercopy.c xen/arch/x86/x86_32/domain_page.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/usercopy.c xen/arch/x86/x86_32/xen.lds xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/usercopy.c xen/arch/x86/x86_64/xen.lds xen/arch/x86/xen.lds xen/include/asm-x86/config.h xen/include/asm-x86/irq.h
line diff
     1.1 --- a/.rootkeys	Mon Jul 05 16:23:43 2004 +0000
     1.2 +++ b/.rootkeys	Mon Jul 05 20:15:38 2004 +0000
     1.3 @@ -313,8 +313,7 @@ 3ddb79bcsjinG9k1KcvbVBuas1R2dA xen/arch/
     1.4  3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S
     1.5  40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S
     1.6  3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c
     1.7 -3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/domain_page.c
     1.8 -3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/entry.S
     1.9 +3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c
    1.10  3ddb79bcY5zW7KhvI9gvfuPi3ZumEg xen/arch/x86/extable.c
    1.11  3fe443fdDDb0Sw6NQBCk4GQapayfTA xen/arch/x86/flushtlb.c
    1.12  3ddb79bcesE5E-lS4QhRhlqXxqj9cA xen/arch/x86/i387.c
    1.13 @@ -322,7 +321,6 @@ 3ddb79bcCAq6IpdkHueChoVTfXqEQQ xen/arch/
    1.14  3ddb79bcBit4xJXbwtX0kb1hh2uO1Q xen/arch/x86/idle0_task.c
    1.15  3ddb79bcKIkRR0kqWaJhe5VUDkMdxg xen/arch/x86/io_apic.c
    1.16  3ddb79bdqfIcjkz_h9Hvtp8Tk_19Zw xen/arch/x86/irq.c
    1.17 -3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/x86/mm.c
    1.18  3ddb79bdS4UeWWXDH-FaBKqcpMFcnw xen/arch/x86/mpparse.c
    1.19  3f12cff65EV3qOG2j37Qm0ShgvXGRw xen/arch/x86/nmi.c
    1.20  3ddb79bdHe6_Uij4-glW91vInNtBYQ xen/arch/x86/pci-irq.c
    1.21 @@ -331,7 +329,6 @@ 3ddb79bdeJ7_86z03yTAPIeeywOg3Q xen/arch/
    1.22  3ddb79bdIKgipvGoqExEQ7jawfVowA xen/arch/x86/pci-x86.h
    1.23  40a4dfced2dnSzbKgJFlD3chKHexjQ xen/arch/x86/pdb-linux.c
    1.24  4022a73czgX7d-2zfF_cb33oVemApQ xen/arch/x86/pdb-stub.c
    1.25 -3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/process.c
    1.26  3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/x86/rwlock.c
    1.27  3ddb79bcrD6Z_rUvSDgrvjyb4846Eg xen/arch/x86/setup.c
    1.28  3ddb79bcSx2e8JSR3pdSGa8x1ScYzA xen/arch/x86/smp.c
    1.29 @@ -339,8 +336,14 @@ 3ddb79bcfUN3-UBCPzX26IU8bq-3aw xen/arch/
    1.30  3ddb79bc-Udq7ol-NX4q9XsYnN7A2Q xen/arch/x86/time.c
    1.31  3ddb79bccYVzXZJyVaxuv5T42Z1Fsw xen/arch/x86/trampoline.S
    1.32  3ddb79bcOftONV9h4QCxXOfiT0h91w xen/arch/x86/traps.c
    1.33 -3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/usercopy.c
    1.34 -3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/xen.lds
    1.35 +3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c
    1.36 +3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S
    1.37 +3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/x86/x86_32/mm.c
    1.38 +3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
    1.39 +3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
    1.40 +40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S
    1.41 +40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
    1.42 +40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
    1.43  3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
    1.44  3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
    1.45  4022a73c_BbDFd2YJ_NQYVvKX5Oz7w xen/common/debug-linux.c
     2.1 --- a/xen/arch/x86/Makefile	Mon Jul 05 16:23:43 2004 +0000
     2.2 +++ b/xen/arch/x86/Makefile	Mon Jul 05 20:15:38 2004 +0000
     2.3 @@ -6,6 +6,9 @@ OBJS := $(subst pdb-linux.o,,$(OBJS))
     2.4  OBJS := $(subst pdb-stub.o,,$(OBJS))
     2.5  endif
     2.6  
     2.7 +OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S))
     2.8 +OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c))
     2.9 +
    2.10  LINK_BASE := 0xFC500000 # Xen is linked here
    2.11  LOAD_BASE := 0x00100000 # Xen is loaded here
    2.12  
    2.13 @@ -23,3 +26,5 @@ default: boot/$(TARGET_SUBARCH).o $(OBJS
    2.14  
    2.15  clean:
    2.16  	rm -f *.o *~ core boot/*.o boot/*~ boot/core
    2.17 +	rm -f $(TARGET_SUBARCH)/*.o $(TARGET_SUBARCH)/*~
    2.18 +	rm -f $(TARGETSUBARCH)/core
     3.1 --- a/xen/arch/x86/Rules.mk	Mon Jul 05 16:23:43 2004 +0000
     3.2 +++ b/xen/arch/x86/Rules.mk	Mon Jul 05 20:15:38 2004 +0000
     3.3 @@ -8,7 +8,7 @@ CFLAGS  := -nostdinc -fno-builtin -fno-c
     3.4  CFLAGS  += -iwithprefix include -Wall -Werror -fomit-frame-pointer
     3.5  CFLAGS  += -I$(BASEDIR)/include -Wno-pointer-arith -Wredundant-decls
     3.6  
     3.7 -LDFLAGS := -T xen.lds -N 
     3.8 +LDFLAGS := -T $(TARGET_SUBARCH)/xen.lds -N 
     3.9  
    3.10  ifeq ($(TARGET_SUBARCH),x86_32)
    3.11  CFLAGS += -m32 -march=i686
     4.1 --- a/xen/arch/x86/apic.c	Mon Jul 05 16:23:43 2004 +0000
     4.2 +++ b/xen/arch/x86/apic.c	Mon Jul 05 20:15:38 2004 +0000
     4.3 @@ -491,9 +491,9 @@ void __init init_apic_mappings(void)
     4.4   *****************************************************************************/
     4.5  
     4.6  /* used for system time scaling */
     4.7 -static unsigned int bus_freq;
     4.8 -static u32          bus_cycle;   /* length of one bus cycle in pico-seconds */
     4.9 -static u32          bus_scale;   /* scaling factor convert ns to bus cycles */
    4.10 +static unsigned long bus_freq;    /* KAF: pointer-size avoids compile warns. */
    4.11 +static u32           bus_cycle;   /* length of one bus cycle in pico-seconds */
    4.12 +static u32           bus_scale;   /* scaling factor convert ns to bus cycles */
    4.13  
    4.14  /*
    4.15   * The timer chip is already set up at HZ interrupts per second here,
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/arch/x86/domain.c	Mon Jul 05 20:15:38 2004 +0000
     5.3 @@ -0,0 +1,360 @@
     5.4 +/*
     5.5 + *  Copyright (C) 1995  Linus Torvalds
     5.6 + *
     5.7 + *  Pentium III FXSR, SSE support
     5.8 + *	Gareth Hughes <gareth@valinux.com>, May 2000
     5.9 + */
    5.10 +
    5.11 +#include <xen/config.h>
    5.12 +#include <xen/lib.h>
    5.13 +#include <xen/errno.h>
    5.14 +#include <xen/sched.h>
    5.15 +#include <xen/smp.h>
    5.16 +#include <xen/delay.h>
    5.17 +#include <xen/softirq.h>
    5.18 +#include <asm/ptrace.h>
    5.19 +#include <asm/mc146818rtc.h>
    5.20 +#include <asm/system.h>
    5.21 +#include <asm/io.h>
    5.22 +#include <asm/processor.h>
    5.23 +#include <asm/desc.h>
    5.24 +#include <asm/i387.h>
    5.25 +#include <asm/mpspec.h>
    5.26 +#include <asm/ldt.h>
    5.27 +#include <xen/irq.h>
    5.28 +#include <xen/event.h>
    5.29 +#include <xen/shadow.h>
    5.30 +
    5.31 +int hlt_counter;
    5.32 +
    5.33 +void disable_hlt(void)
    5.34 +{
    5.35 +    hlt_counter++;
    5.36 +}
    5.37 +
    5.38 +void enable_hlt(void)
    5.39 +{
    5.40 +    hlt_counter--;
    5.41 +}
    5.42 +
    5.43 +/*
    5.44 + * We use this if we don't have any better
    5.45 + * idle routine..
    5.46 + */
    5.47 +static void default_idle(void)
    5.48 +{
    5.49 +    if ( hlt_counter == 0 )
    5.50 +    {
    5.51 +        __cli();
    5.52 +        if ( !softirq_pending(smp_processor_id()) )
    5.53 +            safe_halt();
    5.54 +        else
    5.55 +            __sti();
    5.56 +    }
    5.57 +}
    5.58 +
    5.59 +void continue_cpu_idle_loop(void)
    5.60 +{
    5.61 +    int cpu = smp_processor_id();
    5.62 +    for ( ; ; )
    5.63 +    {
    5.64 +        irq_stat[cpu].idle_timestamp = jiffies;
    5.65 +        while ( !softirq_pending(cpu) )
    5.66 +            default_idle();
    5.67 +        do_softirq();
    5.68 +    }
    5.69 +}
    5.70 +
    5.71 +void startup_cpu_idle_loop(void)
    5.72 +{
    5.73 +    /* Just some sanity to ensure that the scheduler is set up okay. */
    5.74 +    ASSERT(current->domain == IDLE_DOMAIN_ID);
    5.75 +    domain_unpause_by_systemcontroller(current);
    5.76 +    __enter_scheduler();
    5.77 +
    5.78 +    /*
    5.79 +     * Declares CPU setup done to the boot processor.
    5.80 +     * Therefore memory barrier to ensure state is visible.
    5.81 +     */
    5.82 +    smp_mb();
    5.83 +    init_idle();
    5.84 +
    5.85 +    continue_cpu_idle_loop();
    5.86 +}
    5.87 +
    5.88 +static long no_idt[2];
    5.89 +static int reboot_mode;
    5.90 +int reboot_thru_bios = 0;
    5.91 +
    5.92 +#ifdef CONFIG_SMP
    5.93 +int reboot_smp = 0;
    5.94 +static int reboot_cpu = -1;
    5.95 +/* shamelessly grabbed from lib/vsprintf.c for readability */
    5.96 +#define is_digit(c)	((c) >= '0' && (c) <= '9')
    5.97 +#endif
    5.98 +
    5.99 +
   5.100 +static inline void kb_wait(void)
   5.101 +{
   5.102 +    int i;
   5.103 +
   5.104 +    for (i=0; i<0x10000; i++)
   5.105 +        if ((inb_p(0x64) & 0x02) == 0)
   5.106 +            break;
   5.107 +}
   5.108 +
   5.109 +
   5.110 +void machine_restart(char * __unused)
   5.111 +{
   5.112 +    extern int opt_noreboot;
   5.113 +#ifdef CONFIG_SMP
   5.114 +    int cpuid;
   5.115 +#endif
   5.116 +	
   5.117 +    if ( opt_noreboot )
   5.118 +    {
   5.119 +        printk("Reboot disabled on cmdline: require manual reset\n");
   5.120 +        for ( ; ; ) __asm__ __volatile__ ("hlt");
   5.121 +    }
   5.122 +
   5.123 +#ifdef CONFIG_SMP
   5.124 +    cpuid = GET_APIC_ID(apic_read(APIC_ID));
   5.125 +
   5.126 +    /* KAF: Need interrupts enabled for safe IPI. */
   5.127 +    __sti();
   5.128 +
   5.129 +    if (reboot_smp) {
   5.130 +
   5.131 +        /* check to see if reboot_cpu is valid 
   5.132 +           if its not, default to the BSP */
   5.133 +        if ((reboot_cpu == -1) ||  
   5.134 +            (reboot_cpu > (NR_CPUS -1))  || 
   5.135 +            !(phys_cpu_present_map & (1<<cpuid))) 
   5.136 +            reboot_cpu = boot_cpu_physical_apicid;
   5.137 +
   5.138 +        reboot_smp = 0;  /* use this as a flag to only go through this once*/
   5.139 +        /* re-run this function on the other CPUs
   5.140 +           it will fall though this section since we have 
   5.141 +           cleared reboot_smp, and do the reboot if it is the
   5.142 +           correct CPU, otherwise it halts. */
   5.143 +        if (reboot_cpu != cpuid)
   5.144 +            smp_call_function((void *)machine_restart , NULL, 1, 0);
   5.145 +    }
   5.146 +
   5.147 +    /* if reboot_cpu is still -1, then we want a tradional reboot, 
   5.148 +       and if we are not running on the reboot_cpu,, halt */
   5.149 +    if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
   5.150 +        for (;;)
   5.151 +            __asm__ __volatile__ ("hlt");
   5.152 +    }
   5.153 +    /*
   5.154 +     * Stop all CPUs and turn off local APICs and the IO-APIC, so
   5.155 +     * other OSs see a clean IRQ state.
   5.156 +     */
   5.157 +    smp_send_stop();
   5.158 +    disable_IO_APIC();
   5.159 +#endif
   5.160 +
   5.161 +    if(!reboot_thru_bios) {
   5.162 +        /* rebooting needs to touch the page at absolute addr 0 */
   5.163 +        *((unsigned short *)__va(0x472)) = reboot_mode;
   5.164 +        for (;;) {
   5.165 +            int i;
   5.166 +            for (i=0; i<100; i++) {
   5.167 +                kb_wait();
   5.168 +                udelay(50);
   5.169 +                outb(0xfe,0x64);         /* pulse reset low */
   5.170 +                udelay(50);
   5.171 +            }
   5.172 +            /* That didn't work - force a triple fault.. */
   5.173 +            __asm__ __volatile__("lidt %0": "=m" (no_idt));
   5.174 +            __asm__ __volatile__("int3");
   5.175 +        }
   5.176 +    }
   5.177 +
   5.178 +    panic("Need to reinclude BIOS reboot code\n");
   5.179 +}
   5.180 +
   5.181 +void machine_halt(void)
   5.182 +{
   5.183 +    machine_restart(0);
   5.184 +}
   5.185 +
   5.186 +void machine_power_off(void)
   5.187 +{
   5.188 +    machine_restart(0);
   5.189 +}
   5.190 +
   5.191 +#if defined(__i386__)
   5.192 +
   5.193 +void new_thread(struct domain *p,
   5.194 +                unsigned long start_pc,
   5.195 +                unsigned long start_stack,
   5.196 +                unsigned long start_info)
   5.197 +{
   5.198 +    execution_context_t *ec = &p->shared_info->execution_context;
   5.199 +
   5.200 +    /*
   5.201 +     * Initial register values:
   5.202 +     *  DS,ES,FS,GS = FLAT_RING1_DS
   5.203 +     *       CS:EIP = FLAT_RING1_CS:start_pc
   5.204 +     *       SS:ESP = FLAT_RING1_DS:start_stack
   5.205 +     *          ESI = start_info
   5.206 +     *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
   5.207 +     */
   5.208 +    ec->ds = ec->es = ec->fs = ec->gs = ec->ss = FLAT_RING1_DS;
   5.209 +    ec->cs = FLAT_RING1_CS;
   5.210 +    ec->eip = start_pc;
   5.211 +    ec->esp = start_stack;
   5.212 +    ec->esi = start_info;
   5.213 +
   5.214 +    __save_flags(ec->eflags);
   5.215 +    ec->eflags |= X86_EFLAGS_IF;
   5.216 +
   5.217 +    /* No fast trap at start of day. */
   5.218 +    SET_DEFAULT_FAST_TRAP(&p->thread);
   5.219 +}
   5.220 +
   5.221 +
   5.222 +/*
   5.223 + * This special macro can be used to load a debugging register
   5.224 + */
   5.225 +#define loaddebug(thread,register) \
   5.226 +		__asm__("movl %0,%%db" #register  \
   5.227 +			: /* no output */ \
   5.228 +			:"r" (thread->debugreg[register]))
   5.229 +
   5.230 +
   5.231 +void switch_to(struct domain *prev_p, struct domain *next_p)
   5.232 +{
   5.233 +    struct thread_struct *next = &next_p->thread;
   5.234 +    struct tss_struct *tss = init_tss + smp_processor_id();
   5.235 +    execution_context_t *stack_ec = get_execution_context();
   5.236 +    int i;
   5.237 +    
   5.238 +    __cli();
   5.239 +
   5.240 +    /* Switch guest general-register state. */
   5.241 +    if ( !is_idle_task(prev_p) )
   5.242 +    {
   5.243 +        memcpy(&prev_p->shared_info->execution_context, 
   5.244 +               stack_ec, 
   5.245 +               sizeof(*stack_ec));
   5.246 +        unlazy_fpu(prev_p);
   5.247 +        CLEAR_FAST_TRAP(&prev_p->thread);
   5.248 +    }
   5.249 +
   5.250 +    if ( !is_idle_task(next_p) )
   5.251 +    {
   5.252 +        memcpy(stack_ec,
   5.253 +               &next_p->shared_info->execution_context,
   5.254 +               sizeof(*stack_ec));
   5.255 +
   5.256 +        /*
   5.257 +         * This is sufficient! If the descriptor DPL differs from CS RPL then 
   5.258 +         * we'll #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared 
   5.259 +         * automatically. If SS RPL or DPL differs from CS RPL then we'll #GP.
   5.260 +         */
   5.261 +        if ( (stack_ec->cs & 3) == 0 )
   5.262 +            stack_ec->cs = FLAT_RING1_CS;
   5.263 +        if ( (stack_ec->ss & 3) == 0 )
   5.264 +            stack_ec->ss = FLAT_RING1_DS;
   5.265 +
   5.266 +        SET_FAST_TRAP(&next_p->thread);
   5.267 +
   5.268 +        /* Switch the guest OS ring-1 stack. */
   5.269 +        tss->esp1 = next->guestos_sp;
   5.270 +        tss->ss1  = next->guestos_ss;
   5.271 +
   5.272 +        /* Maybe switch the debug registers. */
   5.273 +        if ( unlikely(next->debugreg[7]) )
   5.274 +        {
   5.275 +            loaddebug(next, 0);
   5.276 +            loaddebug(next, 1);
   5.277 +            loaddebug(next, 2);
   5.278 +            loaddebug(next, 3);
   5.279 +            /* no 4 and 5 */
   5.280 +            loaddebug(next, 6);
   5.281 +            loaddebug(next, 7);
   5.282 +        }
   5.283 +
   5.284 +        /* Switch page tables. */
   5.285 +        write_ptbase(&next_p->mm);
   5.286 +        tlb_clocktick();
   5.287 +    }
   5.288 +
   5.289 +    if ( unlikely(prev_p->io_bitmap != NULL) || 
   5.290 +         unlikely(next_p->io_bitmap != NULL) )
   5.291 +    {
   5.292 +        if ( next_p->io_bitmap != NULL )
   5.293 +        {
   5.294 +            /* Copy in the appropriate parts of the IO bitmap.  We use the
   5.295 +             * selector to copy only the interesting parts of the bitmap. */
   5.296 +
   5.297 +            u64 old_sel = ~0ULL; /* IO bitmap selector for previous task. */
   5.298 +
   5.299 +            if ( prev_p->io_bitmap != NULL)
   5.300 +            {
   5.301 +                old_sel = prev_p->io_bitmap_sel;
   5.302 +
   5.303 +                /* Replace any areas of the IO bitmap that had bits cleared. */
   5.304 +                for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
   5.305 +                    if ( !test_bit(i, &prev_p->io_bitmap_sel) )
   5.306 +                        memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
   5.307 +                               &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
   5.308 +                               IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
   5.309 +            }
   5.310 +
   5.311 +            /* Copy in any regions of the new task's bitmap that have bits
   5.312 +             * clear and we haven't already dealt with. */
   5.313 +            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
   5.314 +            {
   5.315 +                if ( test_bit(i, &old_sel)
   5.316 +                     && !test_bit(i, &next_p->io_bitmap_sel) )
   5.317 +                    memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
   5.318 +                           &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
   5.319 +                           IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
   5.320 +            }
   5.321 +
   5.322 +            tss->bitmap = IO_BITMAP_OFFSET;
   5.323 +
   5.324 +	}
   5.325 +        else
   5.326 +        {
   5.327 +            /* In this case, we're switching FROM a task with IO port access,
   5.328 +             * to a task that doesn't use the IO bitmap.  We set any TSS bits
   5.329 +             * that might have been cleared, ready for future use. */
   5.330 +            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
   5.331 +                if ( !test_bit(i, &prev_p->io_bitmap_sel) )
   5.332 +                    memset(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
   5.333 +                           0xFF, IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
   5.334 +
   5.335 +            /*
   5.336 +             * a bitmap offset pointing outside of the TSS limit
   5.337 +             * causes a nicely controllable SIGSEGV if a process
   5.338 +             * tries to use a port IO instruction. The first
   5.339 +             * sys_ioperm() call sets up the bitmap properly.
   5.340 +             */
   5.341 +            tss->bitmap = INVALID_IO_BITMAP_OFFSET;
   5.342 +	}
   5.343 +    }
   5.344 +
   5.345 +    set_current(next_p);
   5.346 +
   5.347 +    /* Switch GDT and LDT. */
   5.348 +    __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->mm.gdt));
   5.349 +    load_LDT(next_p);
   5.350 +
   5.351 +    __sti();
   5.352 +}
   5.353 +
   5.354 +
   5.355 +/* XXX Currently the 'domain' field is ignored! XXX */
   5.356 +long do_iopl(domid_t domain, unsigned int new_io_pl)
   5.357 +{
   5.358 +    execution_context_t *ec = get_execution_context();
   5.359 +    ec->eflags = (ec->eflags & 0xffffcfff) | ((new_io_pl&3) << 12);
   5.360 +    return 0;
   5.361 +}
   5.362 +
   5.363 +#endif
     6.1 --- a/xen/arch/x86/domain_page.c	Mon Jul 05 16:23:43 2004 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,81 +0,0 @@
     6.4 -/******************************************************************************
     6.5 - * domain_page.h
     6.6 - * 
     6.7 - * Allow temporary mapping of domain pages. Based on ideas from the
     6.8 - * Linux PKMAP code -- the copyrights and credits are retained below.
     6.9 - */
    6.10 -
    6.11 -/*
    6.12 - * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de
    6.13 - *          Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de *
    6.14 - * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
    6.15 - */
    6.16 -
    6.17 -#include <xen/config.h>
    6.18 -#include <xen/sched.h>
    6.19 -#include <xen/mm.h>
    6.20 -#include <xen/perfc.h>
    6.21 -#include <asm/domain_page.h>
    6.22 -#include <asm/flushtlb.h>
    6.23 -
    6.24 -unsigned long *mapcache;
    6.25 -static unsigned int map_idx, shadow_map_idx[NR_CPUS];
    6.26 -static spinlock_t map_lock = SPIN_LOCK_UNLOCKED;
    6.27 -
    6.28 -/* Use a spare PTE bit to mark entries ready for recycling. */
    6.29 -#define READY_FOR_TLB_FLUSH (1<<10)
    6.30 -
    6.31 -static void flush_all_ready_maps(void)
    6.32 -{
    6.33 -    unsigned long *cache = mapcache;
    6.34 -
    6.35 -    /* A bit skanky -- depends on having an aligned PAGE_SIZE set of PTEs. */
    6.36 -    do { if ( (*cache & READY_FOR_TLB_FLUSH) ) *cache = 0; }
    6.37 -    while ( ((unsigned long)(++cache) & ~PAGE_MASK) != 0 );
    6.38 -
    6.39 -    perfc_incrc(domain_page_tlb_flush);
    6.40 -    local_flush_tlb();
    6.41 -}
    6.42 -
    6.43 -
    6.44 -void *map_domain_mem(unsigned long pa)
    6.45 -{
    6.46 -    unsigned long va;
    6.47 -    unsigned int idx, cpu = smp_processor_id();
    6.48 -    unsigned long *cache = mapcache;
    6.49 -    unsigned long flags;
    6.50 -
    6.51 -    perfc_incrc(map_domain_mem_count);
    6.52 -
    6.53 -    spin_lock_irqsave(&map_lock, flags);
    6.54 -
    6.55 -    /* Has some other CPU caused a wrap? We must flush if so. */
    6.56 -    if ( map_idx < shadow_map_idx[cpu] )
    6.57 -    {
    6.58 -        perfc_incrc(domain_page_tlb_flush);
    6.59 -        local_flush_tlb();
    6.60 -    }
    6.61 -
    6.62 -    for ( ; ; )
    6.63 -    {
    6.64 -        idx = map_idx = (map_idx + 1) & (MAPCACHE_ENTRIES - 1);
    6.65 -        if ( idx == 0 ) flush_all_ready_maps();
    6.66 -        if ( cache[idx] == 0 ) break;
    6.67 -    }
    6.68 -
    6.69 -    cache[idx] = (pa & PAGE_MASK) | __PAGE_HYPERVISOR;
    6.70 -
    6.71 -    spin_unlock_irqrestore(&map_lock, flags);
    6.72 -
    6.73 -    shadow_map_idx[cpu] = idx;
    6.74 -
    6.75 -    va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT) + (pa & ~PAGE_MASK);
    6.76 -    return (void *)va;
    6.77 -}
    6.78 -
    6.79 -void unmap_domain_mem(void *va)
    6.80 -{
    6.81 -    unsigned int idx;
    6.82 -    idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
    6.83 -    mapcache[idx] |= READY_FOR_TLB_FLUSH;
    6.84 -}
     7.1 --- a/xen/arch/x86/entry.S	Mon Jul 05 16:23:43 2004 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,696 +0,0 @@
     7.4 -/*
     7.5 - * Hypercall and fault low-level handling routines.
     7.6 - *
     7.7 - * Copyright (c) 2002-2004, K A Fraser
     7.8 - * Copyright (c) 1991, 1992 Linus Torvalds
     7.9 - */
    7.10 -
    7.11 -/*
    7.12 - * The idea for callbacks to guest OSes
    7.13 - * ====================================
    7.14 - *
    7.15 - * First, we require that all callbacks (either via a supplied
    7.16 - * interrupt-descriptor-table, or via the special event or failsafe callbacks
    7.17 - * in the shared-info-structure) are to ring 1. This just makes life easier,
    7.18 - * in that it means we don't have to do messy GDT/LDT lookups to find
    7.19 - * out which the privilege-level of the return code-selector. That code
    7.20 - * would just be a hassle to write, and would need to account for running
    7.21 - * off the end of the GDT/LDT, for example. For all callbacks we check
    7.22 - * that the provided
    7.23 - * return CS is not == __HYPERVISOR_{CS,DS}. Apart from that we're safe as
    7.24 - * don't allow a guest OS to install ring-0 privileges into the GDT/LDT.
    7.25 - * It's up to the guest OS to ensure all returns via the IDT are to ring 1.
    7.26 - * If not, we load incorrect SS/ESP values from the TSS (for ring 1 rather
    7.27 - * than the correct ring) and bad things are bound to ensue -- IRET is
    7.28 - * likely to fault, and we may end up killing the domain (no harm can
    7.29 - * come to Xen, though).
    7.30 - *      
    7.31 - * When doing a callback, we check if the return CS is in ring 0. If so,
    7.32 - * callback is delayed until next return to ring != 0.
    7.33 - * If return CS is in ring 1, then we create a callback frame
    7.34 - * starting at return SS/ESP. The base of the frame does an intra-privilege
    7.35 - * interrupt-return.
    7.36 - * If return CS is in ring > 1, we create a callback frame starting
    7.37 - * at SS/ESP taken from appropriate section of the current TSS. The base
    7.38 - * of the frame does an inter-privilege interrupt-return.
    7.39 - * 
    7.40 - * Note that the "failsafe callback" uses a special stackframe:
    7.41 - * { return_DS, return_ES, return_FS, return_GS, return_EIP,
    7.42 - *   return_CS, return_EFLAGS[, return_ESP, return_SS] }
    7.43 - * That is, original values for DS/ES/FS/GS are placed on stack rather than
    7.44 - * in DS/ES/FS/GS themselves. Why? It saves us loading them, only to have them
    7.45 - * saved/restored in guest OS. Furthermore, if we load them we may cause
    7.46 - * a fault if they are invalid, which is a hassle to deal with. We avoid
    7.47 - * that problem if we don't load them :-) This property allows us to use
    7.48 - * the failsafe callback as a fallback: if we ever fault on loading DS/ES/FS/GS
    7.49 - * on return to ring != 0, we can simply package it up as a return via
    7.50 - * the failsafe callback, and let the guest OS sort it out (perhaps by
    7.51 - * killing an application process). Note that we also do this for any
    7.52 - * faulting IRET -- just let the guest OS handle it via the event
    7.53 - * callback.
    7.54 - *
    7.55 - * We terminate a domain in the following cases:
    7.56 - *  - creating a callback stack frame (due to bad ring-1 stack).
    7.57 - *  - faulting IRET on entry to failsafe callback handler.
    7.58 - * So, each domain must keep its ring-1 %ss/%esp and failsafe callback
    7.59 - * handler in good order (absolutely no faults allowed!).
    7.60 - */
    7.61 -
    7.62 -#include <xen/config.h>
    7.63 -#include <xen/errno.h>
    7.64 -#include <hypervisor-ifs/hypervisor-if.h>
    7.65 -
    7.66 -EBX		= 0x00
    7.67 -ECX		= 0x04
    7.68 -EDX		= 0x08
    7.69 -ESI		= 0x0C
    7.70 -EDI		= 0x10
    7.71 -EBP		= 0x14
    7.72 -EAX		= 0x18
    7.73 -DS		= 0x1C
    7.74 -ES		= 0x20
    7.75 -FS              = 0x24
    7.76 -GS              = 0x28
    7.77 -ORIG_EAX	= 0x2C
    7.78 -EIP		= 0x30
    7.79 -CS		= 0x34
    7.80 -EFLAGS		= 0x38
    7.81 -OLDESP		= 0x3C
    7.82 -OLDSS		= 0x40
    7.83 -
    7.84 -/* Offsets in domain structure */
    7.85 -PROCESSOR       =  0
    7.86 -SHARED_INFO     =  4
    7.87 -EVENT_SEL       =  8
    7.88 -EVENT_ADDR      = 12
    7.89 -FAILSAFE_BUFFER = 16
    7.90 -FAILSAFE_SEL    = 32
    7.91 -FAILSAFE_ADDR   = 36
    7.92 -
    7.93 -/* Offsets in shared_info_t */
    7.94 -#define UPCALL_PENDING /* 0 */
    7.95 -#define UPCALL_MASK       1
    7.96 -
    7.97 -/* Offsets in guest_trap_bounce */
    7.98 -GTB_ERROR_CODE   =  0
    7.99 -GTB_CR2          =  4
   7.100 -GTB_FLAGS        =  8
   7.101 -GTB_CS           = 10
   7.102 -GTB_EIP          = 12
   7.103 -GTBF_TRAP        =  1
   7.104 -GTBF_TRAP_NOCODE =  2
   7.105 -GTBF_TRAP_CR2    =  4
   7.106 -                        
   7.107 -CF_MASK		= 0x00000001
   7.108 -IF_MASK		= 0x00000200
   7.109 -NT_MASK		= 0x00004000
   7.110 -        
   7.111 -#define SAVE_ALL_NOSEGREGS \
   7.112 -        cld; \
   7.113 -        pushl %gs; \
   7.114 -        pushl %fs; \
   7.115 -        pushl %es; \
   7.116 -        pushl %ds; \
   7.117 -        pushl %eax; \
   7.118 -        pushl %ebp; \
   7.119 -        pushl %edi; \
   7.120 -        pushl %esi; \
   7.121 -        pushl %edx; \
   7.122 -        pushl %ecx; \
   7.123 -        pushl %ebx; \
   7.124 -
   7.125 -#define SAVE_ALL \
   7.126 -        SAVE_ALL_NOSEGREGS \
   7.127 -        movl $(__HYPERVISOR_DS),%edx; \
   7.128 -        movl %edx,%ds; \
   7.129 -        movl %edx,%es; \
   7.130 -        movl %edx,%fs; \
   7.131 -        movl %edx,%gs; \
   7.132 -        sti;
   7.133 -
   7.134 -#define GET_CURRENT(reg)   \
   7.135 -        movl $4096-4, reg; \
   7.136 -        orl  %esp, reg;    \
   7.137 -        andl $~3,reg;      \
   7.138 -        movl (reg),reg;
   7.139 -
   7.140 -ENTRY(continue_nonidle_task)
   7.141 -        GET_CURRENT(%ebx)
   7.142 -        jmp test_all_events
   7.143 -
   7.144 -        ALIGN
   7.145 -/*
   7.146 - * HYPERVISOR_multicall(call_list, nr_calls)
   7.147 - *   Execute a list of 'nr_calls' hypercalls, pointed at by 'call_list'.
   7.148 - *   This is fairly easy except that:
   7.149 - *   1. We may fault reading the call list, and must patch that up; and
   7.150 - *   2. We cannot recursively call HYPERVISOR_multicall, or a malicious
   7.151 - *      caller could cause our stack to blow up.
   7.152 - */
   7.153 -do_multicall:
   7.154 -        popl  %eax
   7.155 -        cmpl  $SYMBOL_NAME(multicall_return_from_call),%eax
   7.156 -        je    multicall_return_from_call
   7.157 -        pushl %ebx
   7.158 -        movl  4(%esp),%ebx   /* EBX == call_list */
   7.159 -        movl  8(%esp),%ecx   /* ECX == nr_calls  */
   7.160 -multicall_loop:
   7.161 -        pushl %ecx
   7.162 -multicall_fault1: 
   7.163 -        pushl 20(%ebx)      # args[4]
   7.164 -multicall_fault2: 
   7.165 -        pushl 16(%ebx)      # args[3]
   7.166 -multicall_fault3: 
   7.167 -        pushl 12(%ebx)      # args[2]
   7.168 -multicall_fault4: 
   7.169 -        pushl 8(%ebx)       # args[1]
   7.170 -multicall_fault5: 
   7.171 -        pushl 4(%ebx)       # args[0]
   7.172 -multicall_fault6: 
   7.173 -        movl  (%ebx),%eax   # op
   7.174 -        andl  $(NR_hypercalls-1),%eax
   7.175 -        call  *SYMBOL_NAME(hypercall_table)(,%eax,4)
   7.176 -multicall_return_from_call:
   7.177 -multicall_fault7:
   7.178 -        movl  %eax,24(%ebx) # args[5] == result
   7.179 -        addl  $20,%esp
   7.180 -        popl  %ecx
   7.181 -        addl  $(ARGS_PER_MULTICALL_ENTRY*4),%ebx
   7.182 -        loop  multicall_loop
   7.183 -        popl  %ebx
   7.184 -        xorl  %eax,%eax
   7.185 -        jmp   ret_from_hypercall
   7.186 -
   7.187 -.section __ex_table,"a"
   7.188 -        .align 4
   7.189 -        .long multicall_fault1, multicall_fixup1
   7.190 -        .long multicall_fault2, multicall_fixup2
   7.191 -        .long multicall_fault3, multicall_fixup3
   7.192 -        .long multicall_fault4, multicall_fixup4
   7.193 -        .long multicall_fault5, multicall_fixup5
   7.194 -        .long multicall_fault6, multicall_fixup6
   7.195 -.previous
   7.196 -               
   7.197 -.section .fixup,"ax"
   7.198 -multicall_fixup6: 
   7.199 -        addl  $4,%esp
   7.200 -multicall_fixup5: 
   7.201 -        addl  $4,%esp
   7.202 -multicall_fixup4: 
   7.203 -        addl  $4,%esp
   7.204 -multicall_fixup3: 
   7.205 -        addl  $4,%esp
   7.206 -multicall_fixup2: 
   7.207 -        addl  $4,%esp
   7.208 -multicall_fixup1:
   7.209 -        addl  $4,%esp
   7.210 -        popl  %ebx
   7.211 -        movl  $-EFAULT,%eax
   7.212 -        jmp   ret_from_hypercall
   7.213 -.previous        
   7.214 -                
   7.215 -        ALIGN
   7.216 -restore_all_guest:
   7.217 -        # First, may need to restore %ds if clobbered by create_bounce_frame
   7.218 -        pushl %ss
   7.219 -        popl  %ds
   7.220 -        # Second, create a failsafe copy of DS,ES,FS,GS in case any are bad
   7.221 -        leal  DS(%esp),%esi
   7.222 -        leal  FAILSAFE_BUFFER(%ebx),%edi
   7.223 -        movsl
   7.224 -        movsl
   7.225 -        movsl
   7.226 -        movsl
   7.227 -        # Finally, restore guest registers -- faults will cause failsafe
   7.228 -        popl %ebx
   7.229 -	popl %ecx
   7.230 -	popl %edx
   7.231 -	popl %esi
   7.232 -	popl %edi
   7.233 -	popl %ebp
   7.234 -	popl %eax
   7.235 -1:	popl %ds
   7.236 -2:	popl %es
   7.237 -3:	popl %fs
   7.238 -4:	popl %gs
   7.239 -        addl $4,%esp
   7.240 -5:      iret
   7.241 -.section .fixup,"ax"
   7.242 -10:     subl $4,%esp
   7.243 -        pushl %gs
   7.244 -9:      pushl %fs
   7.245 -8:      pushl %es
   7.246 -7:      pushl %ds
   7.247 -6:      pushl %eax
   7.248 -	pushl %ebp
   7.249 -	pushl %edi
   7.250 -	pushl %esi
   7.251 -	pushl %edx
   7.252 -	pushl %ecx
   7.253 -	pushl %ebx
   7.254 -	pushl %ss
   7.255 -	popl  %ds
   7.256 -	pushl %ss
   7.257 -	popl  %es
   7.258 -	jmp  failsafe_callback
   7.259 -.previous
   7.260 -.section __ex_table,"a"
   7.261 -	.align 4
   7.262 -	.long 1b,6b
   7.263 -	.long 2b,7b
   7.264 -	.long 3b,8b
   7.265 -	.long 4b,9b
   7.266 -	.long 5b,10b
   7.267 -.previous
   7.268 -
   7.269 -/* No special register assumptions */
   7.270 -failsafe_callback:
   7.271 -        GET_CURRENT(%ebx)
   7.272 -        movl PROCESSOR(%ebx),%eax
   7.273 -        shl  $4,%eax
   7.274 -        lea  guest_trap_bounce(%eax),%edx
   7.275 -        movl FAILSAFE_ADDR(%ebx),%eax
   7.276 -        movl %eax,GTB_EIP(%edx)
   7.277 -        movl FAILSAFE_SEL(%ebx),%eax
   7.278 -        movw %ax,GTB_CS(%edx)
   7.279 -        call create_bounce_frame
   7.280 -        subl $16,%esi                # add DS/ES/FS/GS to failsafe stack frame
   7.281 -        leal FAILSAFE_BUFFER(%ebx),%ebp
   7.282 -        movl  0(%ebp),%eax           # DS
   7.283 -FAULT1: movl %eax,(%esi) 
   7.284 -        movl  4(%ebp),%eax           # ES
   7.285 -FAULT2: movl %eax,4(%esi)
   7.286 -        movl  8(%ebp),%eax           # FS
   7.287 -FAULT3: movl %eax,8(%esi) 
   7.288 -        movl 12(%ebp),%eax           # GS
   7.289 -FAULT4: movl %eax,12(%esi)
   7.290 -        movl %esi,OLDESP(%esp)
   7.291 -        popl %ebx
   7.292 -        popl %ecx
   7.293 -        popl %edx
   7.294 -        popl %esi
   7.295 -        popl %edi
   7.296 -        popl %ebp
   7.297 -        popl %eax
   7.298 -        addl $20,%esp                # skip DS/ES/FS/GS/ORIG_EAX
   7.299 -FAULT5: iret 
   7.300 -
   7.301 -
   7.302 -        ALIGN
   7.303 -# Simple restore -- we should never fault as we we will only interrupt ring 0
   7.304 -# when sane values have been placed in all registers. The only exception is
   7.305 -# NMI, which may interrupt before good values have been placed in DS-GS.
   7.306 -# The NMI return code deals with this problem itself.
   7.307 -restore_all_xen:
   7.308 -	popl %ebx
   7.309 -	popl %ecx
   7.310 -	popl %edx
   7.311 -	popl %esi
   7.312 -	popl %edi
   7.313 -	popl %ebp
   7.314 -	popl %eax
   7.315 -	popl %ds
   7.316 -	popl %es
   7.317 -	popl %fs
   7.318 -	popl %gs
   7.319 -        addl $4,%esp
   7.320 -        iret
   7.321 -
   7.322 -        ALIGN
   7.323 -ENTRY(hypercall)
   7.324 -        pushl %eax			# save orig_eax
   7.325 -	SAVE_ALL
   7.326 -	GET_CURRENT(%ebx)
   7.327 -	andl $(NR_hypercalls-1),%eax
   7.328 -	call *SYMBOL_NAME(hypercall_table)(,%eax,4)
   7.329 -
   7.330 -ret_from_hypercall:
   7.331 -        movl %eax,EAX(%esp)		# save the return value
   7.332 -
   7.333 -test_all_events:
   7.334 -        xorl %ecx,%ecx
   7.335 -        notl %ecx
   7.336 -        cli                             # tests must not race interrupts
   7.337 -/*test_softirqs:*/  
   7.338 -        movl PROCESSOR(%ebx),%eax
   7.339 -        shl  $6,%eax                    # sizeof(irq_cpustat) == 64
   7.340 -        test %ecx,SYMBOL_NAME(irq_stat)(%eax,1)
   7.341 -        jnz  process_softirqs
   7.342 -/*test_guest_events:*/
   7.343 -        movl SHARED_INFO(%ebx),%eax
   7.344 -        testb $0xFF,UPCALL_MASK(%eax)
   7.345 -        jnz  restore_all_guest
   7.346 -        testb $0xFF,UPCALL_PENDING(%eax)
   7.347 -        jz   restore_all_guest
   7.348 -        movb $1,UPCALL_MASK(%eax)       # Upcalls are masked during delivery
   7.349 -/*process_guest_events:*/
   7.350 -        movl PROCESSOR(%ebx),%edx
   7.351 -        shl  $4,%edx                    # sizeof(guest_trap_bounce) == 16
   7.352 -        lea  guest_trap_bounce(%edx),%edx
   7.353 -        movl EVENT_ADDR(%ebx),%eax
   7.354 -        movl %eax,GTB_EIP(%edx)
   7.355 -        movl EVENT_SEL(%ebx),%eax
   7.356 -        movw %ax,GTB_CS(%edx)
   7.357 -        call create_bounce_frame
   7.358 -        jmp  restore_all_guest
   7.359 -
   7.360 -        ALIGN
   7.361 -process_softirqs:
   7.362 -        sti       
   7.363 -        call SYMBOL_NAME(do_softirq)
   7.364 -        jmp  test_all_events
   7.365 -                
   7.366 -/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:         */
   7.367 -/*   {EIP, CS, EFLAGS, [ESP, SS]}                                     */
   7.368 -/* %edx == guest_trap_bounce, %ebx == task_struct                     */
   7.369 -/* %eax,%ecx are clobbered. %ds:%esi contain new OLDSS/OLDESP.        */
   7.370 -create_bounce_frame:        
   7.371 -        mov  CS+4(%esp),%cl
   7.372 -        test $2,%cl
   7.373 -        jz   1f /* jump if returning to an existing ring-1 activation */
   7.374 -        /* obtain ss/esp from TSS -- no current ring-1 activations */
   7.375 -        movl PROCESSOR(%ebx),%eax
   7.376 -        /* next 4 lines multiply %eax by 8320, which is sizeof(tss_struct) */
   7.377 -        movl %eax, %ecx
   7.378 -        shll $7, %ecx
   7.379 -        shll $13, %eax
   7.380 -        addl %ecx,%eax
   7.381 -        addl $init_tss + 12,%eax
   7.382 -        movl (%eax),%esi /* tss->esp1 */
   7.383 -FAULT6: movl 4(%eax),%ds /* tss->ss1  */
   7.384 -        /* base of stack frame must contain ss/esp (inter-priv iret) */
   7.385 -        subl $8,%esi
   7.386 -        movl OLDESP+4(%esp),%eax
   7.387 -FAULT7: movl %eax,(%esi) 
   7.388 -        movl OLDSS+4(%esp),%eax
   7.389 -FAULT8: movl %eax,4(%esi) 
   7.390 -        jmp 2f
   7.391 -1:      /* obtain ss/esp from oldss/oldesp -- a ring-1 activation exists */
   7.392 -        movl OLDESP+4(%esp),%esi
   7.393 -FAULT9: movl OLDSS+4(%esp),%ds 
   7.394 -2:      /* Construct a stack frame: EFLAGS, CS/EIP */
   7.395 -        subl $12,%esi
   7.396 -        movl EIP+4(%esp),%eax
   7.397 -FAULT10:movl %eax,(%esi) 
   7.398 -        movl CS+4(%esp),%eax
   7.399 -FAULT11:movl %eax,4(%esi) 
   7.400 -        movl EFLAGS+4(%esp),%eax
   7.401 -FAULT12:movl %eax,8(%esi)
   7.402 -        /* Rewrite our stack frame and return to ring 1. */
   7.403 -        /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
   7.404 -        andl $0xfffcbeff,%eax
   7.405 -        movl %eax,EFLAGS+4(%esp)
   7.406 -        movl %ds,OLDSS+4(%esp)
   7.407 -        movl %esi,OLDESP+4(%esp)
   7.408 -        movzwl %es:GTB_CS(%edx),%eax
   7.409 -        movl %eax,CS+4(%esp)
   7.410 -        movl %es:GTB_EIP(%edx),%eax
   7.411 -        movl %eax,EIP+4(%esp)
   7.412 -        ret
   7.413 -        
   7.414 -                              
   7.415 -.section __ex_table,"a"
   7.416 -        .align 4
   7.417 -        .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack
   7.418 -        .long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack
   7.419 -        .long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack
   7.420 -        .long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack
   7.421 -        .long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret
   7.422 -        .long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector
   7.423 -        .long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack
   7.424 -        .long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack
   7.425 -        .long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector
   7.426 -        .long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack
   7.427 -        .long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack
   7.428 -        .long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack
   7.429 -        .long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack
   7.430 -        .long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack
   7.431 -.previous
   7.432 -               
   7.433 -# This handler kills domains which experience unrecoverable faults.
   7.434 -.section .fixup,"ax"
   7.435 -crash_domain_fixup1:
   7.436 -        subl  $4,%esp
   7.437 -        SAVE_ALL
   7.438 -        jmp   domain_crash
   7.439 -crash_domain_fixup2:
   7.440 -        addl  $4,%esp                     
   7.441 -crash_domain_fixup3:
   7.442 -        pushl %ss
   7.443 -        popl  %ds
   7.444 -        jmp   domain_crash
   7.445 -.previous
   7.446 -
   7.447 -        ALIGN
   7.448 -process_guest_exception_and_events:        
   7.449 -        movl PROCESSOR(%ebx),%eax
   7.450 -        shl  $4,%eax
   7.451 -        lea  guest_trap_bounce(%eax),%edx
   7.452 -        testb $~0,GTB_FLAGS(%edx)
   7.453 -        jz   test_all_events
   7.454 -        call create_bounce_frame        # just the basic frame
   7.455 -        mov  %es:GTB_FLAGS(%edx),%cl
   7.456 -        test $GTBF_TRAP_NOCODE,%cl
   7.457 -        jnz  2f
   7.458 -        subl $4,%esi                    # push error_code onto guest frame
   7.459 -        movl %es:GTB_ERROR_CODE(%edx),%eax
   7.460 -FAULT13:movl %eax,(%esi)
   7.461 -        test $GTBF_TRAP_CR2,%cl
   7.462 -        jz   1f
   7.463 -        subl $4,%esi                    # push %cr2 onto guest frame
   7.464 -        movl %es:GTB_CR2(%edx),%eax
   7.465 -FAULT14:movl %eax,(%esi)
   7.466 -1:      movl %esi,OLDESP(%esp)        
   7.467 -2:      push %es                        # unclobber %ds
   7.468 -        pop  %ds 
   7.469 -        movb $0,GTB_FLAGS(%edx)
   7.470 -        jmp  test_all_events
   7.471 -
   7.472 -        ALIGN
   7.473 -ENTRY(ret_from_intr)
   7.474 -	GET_CURRENT(%ebx)
   7.475 -        movb CS(%esp),%al
   7.476 -	testb $3,%al	# return to non-supervisor?
   7.477 -	jne test_all_events
   7.478 -	jmp restore_all_xen
   7.479 -
   7.480 -ENTRY(divide_error)
   7.481 -	pushl $0		# no error code
   7.482 -	pushl $ SYMBOL_NAME(do_divide_error)
   7.483 -	ALIGN
   7.484 -error_code:
   7.485 -	pushl %fs
   7.486 -	pushl %es
   7.487 -	pushl %ds
   7.488 -	pushl %eax
   7.489 -	xorl  %eax,%eax
   7.490 -	pushl %ebp
   7.491 -	pushl %edi
   7.492 -	pushl %esi
   7.493 -	pushl %edx
   7.494 -	decl  %eax			# eax = -1
   7.495 -	pushl %ecx
   7.496 -	pushl %ebx
   7.497 -	cld
   7.498 -	movl  %gs,%ecx
   7.499 -	movl  ORIG_EAX(%esp), %esi	# get the error code
   7.500 -	movl  GS(%esp), %edi		# get the function address
   7.501 -	movl  %eax, ORIG_EAX(%esp)
   7.502 -	movl  %ecx, GS(%esp)
   7.503 -	movl  $(__HYPERVISOR_DS),%edx
   7.504 -	movl  %edx,%ds
   7.505 -	movl  %edx,%es
   7.506 -	movl  %edx,%fs
   7.507 -	movl  %edx,%gs
   7.508 -	movl  %esp,%edx
   7.509 -	pushl %esi			# push the error code
   7.510 -	pushl %edx			# push the pt_regs pointer
   7.511 -	GET_CURRENT(%ebx)
   7.512 -	call  *%edi
   7.513 -        addl  $8,%esp
   7.514 -        movb  CS(%esp),%al
   7.515 -	testb $3,%al
   7.516 -	je    restore_all_xen
   7.517 -        jmp   process_guest_exception_and_events
   7.518 -
   7.519 -ENTRY(coprocessor_error)
   7.520 -	pushl $0
   7.521 -	pushl $ SYMBOL_NAME(do_coprocessor_error)
   7.522 -	jmp error_code
   7.523 -
   7.524 -ENTRY(simd_coprocessor_error)
   7.525 -	pushl $0
   7.526 -	pushl $ SYMBOL_NAME(do_simd_coprocessor_error)
   7.527 -	jmp error_code
   7.528 -
   7.529 -ENTRY(device_not_available)
   7.530 -	pushl $0
   7.531 -        pushl $SYMBOL_NAME(math_state_restore)
   7.532 -        jmp   error_code
   7.533 -
   7.534 -ENTRY(debug)
   7.535 -	pushl $0
   7.536 -	pushl $ SYMBOL_NAME(do_debug)
   7.537 -	jmp error_code
   7.538 -
   7.539 -ENTRY(int3)
   7.540 -	pushl $0
   7.541 -	pushl $ SYMBOL_NAME(do_int3)
   7.542 -	jmp error_code
   7.543 -
   7.544 -ENTRY(overflow)
   7.545 -	pushl $0
   7.546 -	pushl $ SYMBOL_NAME(do_overflow)
   7.547 -	jmp error_code
   7.548 -
   7.549 -ENTRY(bounds)
   7.550 -	pushl $0
   7.551 -	pushl $ SYMBOL_NAME(do_bounds)
   7.552 -	jmp error_code
   7.553 -
   7.554 -ENTRY(invalid_op)
   7.555 -	pushl $0
   7.556 -	pushl $ SYMBOL_NAME(do_invalid_op)
   7.557 -	jmp error_code
   7.558 -
   7.559 -ENTRY(coprocessor_segment_overrun)
   7.560 -	pushl $0
   7.561 -	pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
   7.562 -	jmp error_code
   7.563 -
   7.564 -ENTRY(invalid_TSS)
   7.565 -	pushl $ SYMBOL_NAME(do_invalid_TSS)
   7.566 -	jmp error_code
   7.567 -
   7.568 -ENTRY(segment_not_present)
   7.569 -	pushl $ SYMBOL_NAME(do_segment_not_present)
   7.570 -	jmp error_code
   7.571 -
   7.572 -ENTRY(stack_segment)
   7.573 -	pushl $ SYMBOL_NAME(do_stack_segment)
   7.574 -	jmp error_code
   7.575 -
   7.576 -ENTRY(general_protection)
   7.577 -	pushl $ SYMBOL_NAME(do_general_protection)
   7.578 -	jmp error_code
   7.579 -
   7.580 -ENTRY(alignment_check)
   7.581 -	pushl $ SYMBOL_NAME(do_alignment_check)
   7.582 -	jmp error_code
   7.583 -
   7.584 -ENTRY(page_fault)
   7.585 -	pushl $ SYMBOL_NAME(do_page_fault)
   7.586 -	jmp error_code
   7.587 -
   7.588 -ENTRY(machine_check)
   7.589 -	pushl $0
   7.590 -	pushl $ SYMBOL_NAME(do_machine_check)
   7.591 -	jmp error_code
   7.592 -
   7.593 -ENTRY(spurious_interrupt_bug)
   7.594 -	pushl $0
   7.595 -	pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
   7.596 -	jmp error_code
   7.597 -
   7.598 -ENTRY(nmi)
   7.599 -        # Save state but do not trash the segment registers!
   7.600 -        # We may otherwise be unable to reload them or copy them to ring 1. 
   7.601 -	pushl %eax
   7.602 -	SAVE_ALL_NOSEGREGS
   7.603 -
   7.604 -        # Check for hardware problems. These are always fatal so we can
   7.605 -        # reload DS and ES when handling them.
   7.606 -        inb   $0x61,%al
   7.607 -        testb $0x80,%al
   7.608 -        jne   nmi_parity_err
   7.609 -        testb $0x40,%al
   7.610 -        jne   nmi_io_err
   7.611 -        movl  %eax,%ebx
   7.612 -        
   7.613 -        # Okay, its almost a normal NMI tick. We can only process it if:
   7.614 -        #  A. We are the outermost Xen activation (in which case we have
   7.615 -        #     the selectors safely saved on our stack)
   7.616 -        #  B. DS-GS all contain sane Xen values.
   7.617 -        # In all other cases we bail without touching DS-GS, as we have
   7.618 -        # interrupted an enclosing Xen activation in tricky prologue or
   7.619 -        # epilogue code.
   7.620 -        movb  CS(%esp),%al
   7.621 -	testb $3,%al
   7.622 -        jne   do_watchdog_tick
   7.623 -        movl  DS(%esp),%eax
   7.624 -        cmpw  $(__HYPERVISOR_DS),%ax
   7.625 -        jne   nmi_badseg
   7.626 -        movl  ES(%esp),%eax
   7.627 -        cmpw  $(__HYPERVISOR_DS),%ax
   7.628 -        jne   nmi_badseg
   7.629 -        movl  FS(%esp),%eax
   7.630 -        cmpw  $(__HYPERVISOR_DS),%ax
   7.631 -        jne   nmi_badseg
   7.632 -        movl  GS(%esp),%eax
   7.633 -        cmpw  $(__HYPERVISOR_DS),%ax
   7.634 -        jne   nmi_badseg
   7.635 -
   7.636 -do_watchdog_tick:
   7.637 -        movl  $(__HYPERVISOR_DS),%edx
   7.638 -        movl  %edx,%ds
   7.639 -        movl  %edx,%es
   7.640 -        movl  %esp,%edx
   7.641 -	pushl %ebx   # reason
   7.642 -	pushl %edx   # regs
   7.643 -        call  SYMBOL_NAME(do_nmi)
   7.644 -	addl  $8,%esp
   7.645 -        movb  CS(%esp),%al
   7.646 -	testb $3,%al
   7.647 -	je    restore_all_xen
   7.648 -        GET_CURRENT(%ebx)
   7.649 -        jmp   restore_all_guest
   7.650 -
   7.651 -nmi_badseg:
   7.652 -	popl %ebx
   7.653 -	popl %ecx
   7.654 -	popl %edx
   7.655 -	popl %esi
   7.656 -	popl %edi
   7.657 -	popl %ebp
   7.658 -	popl %eax
   7.659 -        addl $20,%esp
   7.660 -        iret
   7.661 -
   7.662 -nmi_parity_err: 
   7.663 -        movl $(__HYPERVISOR_DS),%edx
   7.664 -        movl %edx,%ds
   7.665 -        movl %edx,%es
   7.666 -        jmp  SYMBOL_NAME(mem_parity_error)
   7.667 -        
   7.668 -nmi_io_err: 
   7.669 -        movl $(__HYPERVISOR_DS),%edx
   7.670 -        movl %edx,%ds
   7.671 -        movl %edx,%es
   7.672 -        jmp  SYMBOL_NAME(io_check_error)                        
   7.673 -        
   7.674 -.data
   7.675 -ENTRY(hypercall_table)
   7.676 -        .long SYMBOL_NAME(do_set_trap_table)     /*  0 */
   7.677 -        .long SYMBOL_NAME(do_mmu_update)
   7.678 -        .long SYMBOL_NAME(do_set_gdt)
   7.679 -        .long SYMBOL_NAME(do_stack_switch)
   7.680 -        .long SYMBOL_NAME(do_set_callbacks)
   7.681 -        .long SYMBOL_NAME(do_fpu_taskswitch)     /*  5 */
   7.682 -        .long SYMBOL_NAME(do_sched_op)
   7.683 -        .long SYMBOL_NAME(do_dom0_op)
   7.684 -        .long SYMBOL_NAME(do_set_debugreg)
   7.685 -        .long SYMBOL_NAME(do_get_debugreg)
   7.686 -        .long SYMBOL_NAME(do_update_descriptor)  /* 10 */
   7.687 -        .long SYMBOL_NAME(do_set_fast_trap)
   7.688 -        .long SYMBOL_NAME(do_dom_mem_op)
   7.689 -        .long SYMBOL_NAME(do_multicall)
   7.690 -        .long SYMBOL_NAME(do_update_va_mapping)
   7.691 -        .long SYMBOL_NAME(do_set_timer_op)       /* 15 */
   7.692 -        .long SYMBOL_NAME(do_event_channel_op)
   7.693 -        .long SYMBOL_NAME(do_xen_version)
   7.694 -        .long SYMBOL_NAME(do_console_io)
   7.695 -        .long SYMBOL_NAME(do_physdev_op)
   7.696 -        .long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 20 */
   7.697 -        .rept NR_hypercalls-((.-hypercall_table)/4)
   7.698 -        .long SYMBOL_NAME(do_ni_hypercall)
   7.699 -        .endr
     8.1 --- a/xen/arch/x86/irq.c	Mon Jul 05 16:23:43 2004 +0000
     8.2 +++ b/xen/arch/x86/irq.c	Mon Jul 05 20:15:38 2004 +0000
     8.3 @@ -89,7 +89,11 @@ void enable_irq(unsigned int irq)
     8.4  
     8.5  asmlinkage void do_IRQ(struct pt_regs regs)
     8.6  {       
     8.7 +#if defined(__i386__)
     8.8      unsigned int      irq = regs.orig_eax;
     8.9 +#else
    8.10 +    unsigned int      irq = 0; /* XXX */
    8.11 +#endif
    8.12      irq_desc_t       *desc = &irq_desc[irq];
    8.13      struct irqaction *action;
    8.14  
     9.1 --- a/xen/arch/x86/mm.c	Mon Jul 05 16:23:43 2004 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,412 +0,0 @@
     9.4 -/******************************************************************************
     9.5 - * arch/i386/mm.c
     9.6 - * 
     9.7 - * Modifications to Linux original are copyright (c) 2002-2003, K A Fraser
     9.8 - * 
     9.9 - * This program is free software; you can redistribute it and/or modify
    9.10 - * it under the terms of the GNU General Public License as published by
    9.11 - * the Free Software Foundation; either version 2 of the License, or
    9.12 - * (at your option) any later version.
    9.13 - * 
    9.14 - * This program is distributed in the hope that it will be useful,
    9.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.17 - * GNU General Public License for more details.
    9.18 - * 
    9.19 - * You should have received a copy of the GNU General Public License
    9.20 - * along with this program; if not, write to the Free Software
    9.21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.22 - */
    9.23 -
    9.24 -#include <xen/config.h>
    9.25 -#include <xen/lib.h>
    9.26 -#include <xen/init.h>
    9.27 -#include <xen/mm.h>
    9.28 -#include <asm/page.h>
    9.29 -#include <asm/flushtlb.h>
    9.30 -#include <asm/fixmap.h>
    9.31 -#include <asm/domain_page.h>
    9.32 -
    9.33 -static inline void set_pte_phys(unsigned long vaddr,
    9.34 -                                l1_pgentry_t entry)
    9.35 -{
    9.36 -    l2_pgentry_t *l2ent;
    9.37 -    l1_pgentry_t *l1ent;
    9.38 -
    9.39 -    l2ent = &idle_pg_table[l2_table_offset(vaddr)];
    9.40 -    l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr);
    9.41 -    *l1ent = entry;
    9.42 -
    9.43 -    /* It's enough to flush this one mapping. */
    9.44 -    __flush_tlb_one(vaddr);
    9.45 -}
    9.46 -
    9.47 -
    9.48 -void __set_fixmap(enum fixed_addresses idx, 
    9.49 -                  l1_pgentry_t entry)
    9.50 -{
    9.51 -    unsigned long address = fix_to_virt(idx);
    9.52 -
    9.53 -    if ( likely(idx < __end_of_fixed_addresses) )
    9.54 -        set_pte_phys(address, entry);
    9.55 -    else
    9.56 -        printk("Invalid __set_fixmap\n");
    9.57 -}
    9.58 -
    9.59 -
    9.60 -static void __init fixrange_init(unsigned long start, 
    9.61 -                                 unsigned long end, 
    9.62 -                                 l2_pgentry_t *pg_base)
    9.63 -{
    9.64 -    l2_pgentry_t *l2e;
    9.65 -    int i;
    9.66 -    unsigned long vaddr, page;
    9.67 -
    9.68 -    vaddr = start;
    9.69 -    i = l2_table_offset(vaddr);
    9.70 -    l2e = pg_base + i;
    9.71 -
    9.72 -    for ( ; (i < ENTRIES_PER_L2_PAGETABLE) && (vaddr != end); l2e++, i++ ) 
    9.73 -    {
    9.74 -        if ( !l2_pgentry_empty(*l2e) )
    9.75 -            continue;
    9.76 -        page = (unsigned long)get_free_page();
    9.77 -        clear_page(page);
    9.78 -        *l2e = mk_l2_pgentry(__pa(page) | __PAGE_HYPERVISOR);
    9.79 -        vaddr += 1 << L2_PAGETABLE_SHIFT;
    9.80 -    }
    9.81 -}
    9.82 -
    9.83 -void __init paging_init(void)
    9.84 -{
    9.85 -    unsigned long addr;
    9.86 -    void *ioremap_pt;
    9.87 -    int i;
    9.88 -
    9.89 -    /* Idle page table 1:1 maps the first part of physical memory. */
    9.90 -    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
    9.91 -        idle_pg_table[i] = 
    9.92 -            mk_l2_pgentry((i << L2_PAGETABLE_SHIFT) | 
    9.93 -                          __PAGE_HYPERVISOR | _PAGE_PSE);
    9.94 -
    9.95 -    /*
    9.96 -     * Fixed mappings, only the page table structure has to be
    9.97 -     * created - mappings will be set by set_fixmap():
    9.98 -     */
    9.99 -    addr = FIXADDR_START & ~((1<<L2_PAGETABLE_SHIFT)-1);
   9.100 -    fixrange_init(addr, 0, idle_pg_table);
   9.101 -
   9.102 -    /* Create page table for ioremap(). */
   9.103 -    ioremap_pt = (void *)get_free_page();
   9.104 -    clear_page(ioremap_pt);
   9.105 -    idle_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] = 
   9.106 -        mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR);
   9.107 -
   9.108 -    /* Create read-only mapping of MPT for guest-OS use. */
   9.109 -    idle_pg_table[RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
   9.110 -        idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT];
   9.111 -    mk_l2_readonly(idle_pg_table + 
   9.112 -                   (RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT));
   9.113 -
   9.114 -    /* Set up mapping cache for domain pages. */
   9.115 -    mapcache = (unsigned long *)get_free_page();
   9.116 -    clear_page(mapcache);
   9.117 -    idle_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] =
   9.118 -        mk_l2_pgentry(__pa(mapcache) | __PAGE_HYPERVISOR);
   9.119 -
   9.120 -    /* Set up linear page table mapping. */
   9.121 -    idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
   9.122 -        mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR);
   9.123 -
   9.124 -}
   9.125 -
   9.126 -void __init zap_low_mappings(void)
   9.127 -{
   9.128 -    int i;
   9.129 -    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
   9.130 -        idle_pg_table[i] = mk_l2_pgentry(0);
   9.131 -    flush_tlb_all_pge();
   9.132 -}
   9.133 -
   9.134 -
   9.135 -long do_stack_switch(unsigned long ss, unsigned long esp)
   9.136 -{
   9.137 -    int nr = smp_processor_id();
   9.138 -    struct tss_struct *t = &init_tss[nr];
   9.139 -
   9.140 -    /* We need to do this check as we load and use SS on guest's behalf. */
   9.141 -    if ( (ss & 3) == 0 )
   9.142 -        return -EPERM;
   9.143 -
   9.144 -    current->thread.guestos_ss = ss;
   9.145 -    current->thread.guestos_sp = esp;
   9.146 -    t->ss1  = ss;
   9.147 -    t->esp1 = esp;
   9.148 -
   9.149 -    return 0;
   9.150 -}
   9.151 -
   9.152 -
   9.153 -/* Returns TRUE if given descriptor is valid for GDT or LDT. */
   9.154 -int check_descriptor(unsigned long a, unsigned long b)
   9.155 -{
   9.156 -    unsigned long base, limit;
   9.157 -
   9.158 -    /* A not-present descriptor will always fault, so is safe. */
   9.159 -    if ( !(b & _SEGMENT_P) ) 
   9.160 -        goto good;
   9.161 -
   9.162 -    /*
   9.163 -     * We don't allow a DPL of zero. There is no legitimate reason for 
   9.164 -     * specifying DPL==0, and it gets rather dangerous if we also accept call 
   9.165 -     * gates (consider a call gate pointing at another guestos descriptor with 
   9.166 -     * DPL 0 -- this would get the OS ring-0 privileges).
   9.167 -     */
   9.168 -    if ( (b & _SEGMENT_DPL) == 0 )
   9.169 -        goto bad;
   9.170 -
   9.171 -    if ( !(b & _SEGMENT_S) )
   9.172 -    {
   9.173 -        /*
   9.174 -         * System segment:
   9.175 -         *  1. Don't allow interrupt or trap gates as they belong in the IDT.
   9.176 -         *  2. Don't allow TSS descriptors or task gates as we don't
   9.177 -         *     virtualise x86 tasks.
   9.178 -         *  3. Don't allow LDT descriptors because they're unnecessary and
   9.179 -         *     I'm uneasy about allowing an LDT page to contain LDT
   9.180 -         *     descriptors. In any case, Xen automatically creates the
   9.181 -         *     required descriptor when reloading the LDT register.
   9.182 -         *  4. We allow call gates but they must not jump to a private segment.
   9.183 -         */
   9.184 -
   9.185 -        /* Disallow everything but call gates. */
   9.186 -        if ( (b & _SEGMENT_TYPE) != 0xc00 )
   9.187 -            goto bad;
   9.188 -
   9.189 -        /* Can't allow far jump to a Xen-private segment. */
   9.190 -        if ( !VALID_CODESEL(a>>16) )
   9.191 -            goto bad;
   9.192 -
   9.193 -        /* Reserved bits must be zero. */
   9.194 -        if ( (b & 0xe0) != 0 )
   9.195 -            goto bad;
   9.196 -        
   9.197 -        /* No base/limit check is needed for a call gate. */
   9.198 -        goto good;
   9.199 -    }
   9.200 -    
   9.201 -    /* Check that base/limit do not overlap Xen-private space. */
   9.202 -    base  = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16);
   9.203 -    limit = (b&0xf0000) | (a&0xffff);
   9.204 -    limit++; /* We add one because limit is inclusive. */
   9.205 -    if ( (b & _SEGMENT_G) )
   9.206 -        limit <<= 12;
   9.207 -    if ( ((base + limit) <= base) || 
   9.208 -         ((base + limit) > PAGE_OFFSET) )
   9.209 -        goto bad;
   9.210 -
   9.211 - good:
   9.212 -    return 1;
   9.213 - bad:
   9.214 -    return 0;
   9.215 -}
   9.216 -
   9.217 -
   9.218 -long set_gdt(struct domain *p, 
   9.219 -             unsigned long *frames,
   9.220 -             unsigned int entries)
   9.221 -{
   9.222 -    /* NB. There are 512 8-byte entries per GDT page. */
   9.223 -    int i, nr_pages = (entries + 511) / 512;
   9.224 -    unsigned long pfn;
   9.225 -    struct desc_struct *vgdt;
   9.226 -
   9.227 -    /* Check the new GDT. */
   9.228 -    for ( i = 0; i < nr_pages; i++ )
   9.229 -    {
   9.230 -        if ( unlikely(frames[i] >= max_page) ||
   9.231 -             unlikely(!get_page_and_type(&frame_table[frames[i]], 
   9.232 -                                         p, PGT_gdt_page)) )
   9.233 -            goto fail;
   9.234 -    }
   9.235 -
   9.236 -    /* Copy reserved GDT entries to the new GDT. */
   9.237 -    vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
   9.238 -    memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, 
   9.239 -           gdt_table + FIRST_RESERVED_GDT_ENTRY, 
   9.240 -           NR_RESERVED_GDT_ENTRIES*8);
   9.241 -    unmap_domain_mem(vgdt);
   9.242 -
   9.243 -    /* Tear down the old GDT. */
   9.244 -    for ( i = 0; i < 16; i++ )
   9.245 -    {
   9.246 -        if ( (pfn = l1_pgentry_to_pagenr(p->mm.perdomain_pt[i])) != 0 )
   9.247 -            put_page_and_type(&frame_table[pfn]);
   9.248 -        p->mm.perdomain_pt[i] = mk_l1_pgentry(0);
   9.249 -    }
   9.250 -
   9.251 -    /* Install the new GDT. */
   9.252 -    for ( i = 0; i < nr_pages; i++ )
   9.253 -        p->mm.perdomain_pt[i] =
   9.254 -            mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   9.255 -
   9.256 -    SET_GDT_ADDRESS(p, GDT_VIRT_START);
   9.257 -    SET_GDT_ENTRIES(p, (entries*8)-1);
   9.258 -
   9.259 -    return 0;
   9.260 -
   9.261 - fail:
   9.262 -    while ( i-- > 0 )
   9.263 -        put_page_and_type(&frame_table[frames[i]]);
   9.264 -    return -EINVAL;
   9.265 -}
   9.266 -
   9.267 -
   9.268 -long do_set_gdt(unsigned long *frame_list, unsigned int entries)
   9.269 -{
   9.270 -    int nr_pages = (entries + 511) / 512;
   9.271 -    unsigned long frames[16];
   9.272 -    long ret;
   9.273 -
   9.274 -    if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) ) 
   9.275 -        return -EINVAL;
   9.276 -    
   9.277 -    if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
   9.278 -        return -EFAULT;
   9.279 -
   9.280 -    if ( (ret = set_gdt(current, frames, entries)) == 0 )
   9.281 -    {
   9.282 -        local_flush_tlb();
   9.283 -        __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt));
   9.284 -    }
   9.285 -
   9.286 -    return ret;
   9.287 -}
   9.288 -
   9.289 -
   9.290 -long do_update_descriptor(
   9.291 -    unsigned long pa, unsigned long word1, unsigned long word2)
   9.292 -{
   9.293 -    unsigned long *gdt_pent, pfn = pa >> PAGE_SHIFT;
   9.294 -    struct pfn_info *page;
   9.295 -    long ret = -EINVAL;
   9.296 -
   9.297 -    if ( (pa & 7) || (pfn >= max_page) || !check_descriptor(word1, word2) )
   9.298 -        return -EINVAL;
   9.299 -
   9.300 -    page = &frame_table[pfn];
   9.301 -    if ( unlikely(!get_page(page, current)) )
   9.302 -        goto out;
   9.303 -
   9.304 -    /* Check if the given frame is in use in an unsafe context. */
   9.305 -    switch ( page->type_and_flags & PGT_type_mask )
   9.306 -    {
   9.307 -    case PGT_gdt_page:
   9.308 -        /* Disallow updates of Xen-reserved descriptors in the current GDT. */
   9.309 -        if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) &&
   9.310 -             (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) &&
   9.311 -             (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) )
   9.312 -            goto out;
   9.313 -        if ( unlikely(!get_page_type(page, PGT_gdt_page)) )
   9.314 -            goto out;
   9.315 -        break;
   9.316 -    case PGT_ldt_page:
   9.317 -        if ( unlikely(!get_page_type(page, PGT_ldt_page)) )
   9.318 -            goto out;
   9.319 -        break;
   9.320 -    default:
   9.321 -        if ( unlikely(!get_page_type(page, PGT_writeable_page)) )
   9.322 -            goto out;
   9.323 -        break;
   9.324 -    }
   9.325 -
   9.326 -    /* All is good so make the update. */
   9.327 -    gdt_pent = map_domain_mem(pa);
   9.328 -    gdt_pent[0] = word1;
   9.329 -    gdt_pent[1] = word2;
   9.330 -    unmap_domain_mem(gdt_pent);
   9.331 -
   9.332 -    put_page_type(page);
   9.333 -
   9.334 -    ret = 0; /* success */
   9.335 -
   9.336 - out:
   9.337 -    put_page(page);
   9.338 -    return ret;
   9.339 -}
   9.340 -
   9.341 -#ifdef MEMORY_GUARD
   9.342 -
   9.343 -void *memguard_init(void *heap_start)
   9.344 -{
   9.345 -    l1_pgentry_t *l1;
   9.346 -    int i, j;
   9.347 -
   9.348 -    /* Round the allocation pointer up to a page boundary. */
   9.349 -    heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) & 
   9.350 -                          PAGE_MASK);
   9.351 -
   9.352 -    /* Memory guarding is incompatible with super pages. */
   9.353 -    for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
   9.354 -    {
   9.355 -        l1 = (l1_pgentry_t *)heap_start;
   9.356 -        heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
   9.357 -        for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ )
   9.358 -            l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) |
   9.359 -                                   (j << L1_PAGETABLE_SHIFT) | 
   9.360 -                                  __PAGE_HYPERVISOR);
   9.361 -        idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] =
   9.362 -            mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR);
   9.363 -    }
   9.364 -
   9.365 -    return heap_start;
   9.366 -}
   9.367 -
   9.368 -static void __memguard_change_range(void *p, unsigned long l, int guard)
   9.369 -{
   9.370 -    l1_pgentry_t *l1;
   9.371 -    l2_pgentry_t *l2;
   9.372 -    unsigned long _p = (unsigned long)p;
   9.373 -    unsigned long _l = (unsigned long)l;
   9.374 -
   9.375 -    /* Ensure we are dealing with a page-aligned whole number of pages. */
   9.376 -    ASSERT((_p&PAGE_MASK) != 0);
   9.377 -    ASSERT((_l&PAGE_MASK) != 0);
   9.378 -    ASSERT((_p&~PAGE_MASK) == 0);
   9.379 -    ASSERT((_l&~PAGE_MASK) == 0);
   9.380 -
   9.381 -    while ( _l != 0 )
   9.382 -    {
   9.383 -        l2  = &idle_pg_table[l2_table_offset(_p)];
   9.384 -        l1  = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
   9.385 -        if ( guard )
   9.386 -            *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT);
   9.387 -        else
   9.388 -            *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) | _PAGE_PRESENT);
   9.389 -        _p += PAGE_SIZE;
   9.390 -        _l -= PAGE_SIZE;
   9.391 -    }
   9.392 -}
   9.393 -
   9.394 -void memguard_guard_range(void *p, unsigned long l)
   9.395 -{
   9.396 -    __memguard_change_range(p, l, 1);
   9.397 -    local_flush_tlb();
   9.398 -}
   9.399 -
   9.400 -void memguard_unguard_range(void *p, unsigned long l)
   9.401 -{
   9.402 -    __memguard_change_range(p, l, 0);
   9.403 -}
   9.404 -
   9.405 -int memguard_is_guarded(void *p)
   9.406 -{
   9.407 -    l1_pgentry_t *l1;
   9.408 -    l2_pgentry_t *l2;
   9.409 -    unsigned long _p = (unsigned long)p;
   9.410 -    l2  = &idle_pg_table[l2_table_offset(_p)];
   9.411 -    l1  = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
   9.412 -    return !(l1_pgentry_val(*l1) & _PAGE_PRESENT);
   9.413 -}
   9.414 -
   9.415 -#endif
    10.1 --- a/xen/arch/x86/mpparse.c	Mon Jul 05 16:23:43 2004 +0000
    10.2 +++ b/xen/arch/x86/mpparse.c	Mon Jul 05 20:15:38 2004 +0000
    10.3 @@ -458,7 +458,7 @@ static int __init smp_read_mpc(struct mp
    10.4  	if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) {
    10.5  		/* We need to process the oem mpc tables to tell us which quad things are in ... */
    10.6  		mpc_record = 0;
    10.7 -		smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, mpc->mpc_oemsize);
    10.8 +		smp_read_mpc_oem((struct mp_config_oemtable *)(unsigned long)mpc->mpc_oemptr, mpc->mpc_oemsize);
    10.9  		mpc_record = 0;
   10.10  	}
   10.11  
   10.12 @@ -824,7 +824,7 @@ void __init get_smp_config (void)
   10.13  		 * Read the physical hardware table.  Anything here will
   10.14  		 * override the defaults.
   10.15  		 */
   10.16 -		if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
   10.17 +		if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
   10.18  			smp_found_config = 0;
   10.19  			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
   10.20  			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
    11.1 --- a/xen/arch/x86/process.c	Mon Jul 05 16:23:43 2004 +0000
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,363 +0,0 @@
    11.4 -/*
    11.5 - *  linux/arch/i386/kernel/process.c
    11.6 - *
    11.7 - *  Copyright (C) 1995  Linus Torvalds
    11.8 - *
    11.9 - *  Pentium III FXSR, SSE support
   11.10 - *	Gareth Hughes <gareth@valinux.com>, May 2000
   11.11 - */
   11.12 -
   11.13 -/*
   11.14 - * This file handles the architecture-dependent parts of process handling..
   11.15 - */
   11.16 -
   11.17 -#define __KERNEL_SYSCALLS__
   11.18 -#include <xen/config.h>
   11.19 -#include <xen/lib.h>
   11.20 -#include <xen/errno.h>
   11.21 -#include <xen/sched.h>
   11.22 -#include <xen/smp.h>
   11.23 -#include <xen/delay.h>
   11.24 -#include <xen/softirq.h>
   11.25 -#include <asm/ptrace.h>
   11.26 -#include <asm/mc146818rtc.h>
   11.27 -#include <asm/system.h>
   11.28 -#include <asm/io.h>
   11.29 -#include <asm/processor.h>
   11.30 -#include <asm/desc.h>
   11.31 -#include <asm/i387.h>
   11.32 -#include <asm/mpspec.h>
   11.33 -#include <asm/ldt.h>
   11.34 -#include <xen/irq.h>
   11.35 -#include <xen/event.h>
   11.36 -#include <xen/shadow.h>
   11.37 -
   11.38 -int hlt_counter;
   11.39 -
   11.40 -void disable_hlt(void)
   11.41 -{
   11.42 -    hlt_counter++;
   11.43 -}
   11.44 -
   11.45 -void enable_hlt(void)
   11.46 -{
   11.47 -    hlt_counter--;
   11.48 -}
   11.49 -
   11.50 -/*
   11.51 - * We use this if we don't have any better
   11.52 - * idle routine..
   11.53 - */
   11.54 -static void default_idle(void)
   11.55 -{
   11.56 -    if ( hlt_counter == 0 )
   11.57 -    {
   11.58 -        __cli();
   11.59 -        if ( !softirq_pending(smp_processor_id()) )
   11.60 -            safe_halt();
   11.61 -        else
   11.62 -            __sti();
   11.63 -    }
   11.64 -}
   11.65 -
   11.66 -void continue_cpu_idle_loop(void)
   11.67 -{
   11.68 -    int cpu = smp_processor_id();
   11.69 -    for ( ; ; )
   11.70 -    {
   11.71 -        irq_stat[cpu].idle_timestamp = jiffies;
   11.72 -        while ( !softirq_pending(cpu) )
   11.73 -            default_idle();
   11.74 -        do_softirq();
   11.75 -    }
   11.76 -}
   11.77 -
   11.78 -void startup_cpu_idle_loop(void)
   11.79 -{
   11.80 -    /* Just some sanity to ensure that the scheduler is set up okay. */
   11.81 -    ASSERT(current->domain == IDLE_DOMAIN_ID);
   11.82 -    domain_unpause_by_systemcontroller(current);
   11.83 -    __enter_scheduler();
   11.84 -
   11.85 -    /*
   11.86 -     * Declares CPU setup done to the boot processor.
   11.87 -     * Therefore memory barrier to ensure state is visible.
   11.88 -     */
   11.89 -    smp_mb();
   11.90 -    init_idle();
   11.91 -
   11.92 -    continue_cpu_idle_loop();
   11.93 -}
   11.94 -
   11.95 -static long no_idt[2];
   11.96 -static int reboot_mode;
   11.97 -int reboot_thru_bios = 0;
   11.98 -
   11.99 -#ifdef CONFIG_SMP
  11.100 -int reboot_smp = 0;
  11.101 -static int reboot_cpu = -1;
  11.102 -/* shamelessly grabbed from lib/vsprintf.c for readability */
  11.103 -#define is_digit(c)	((c) >= '0' && (c) <= '9')
  11.104 -#endif
  11.105 -
  11.106 -
  11.107 -static inline void kb_wait(void)
  11.108 -{
  11.109 -    int i;
  11.110 -
  11.111 -    for (i=0; i<0x10000; i++)
  11.112 -        if ((inb_p(0x64) & 0x02) == 0)
  11.113 -            break;
  11.114 -}
  11.115 -
  11.116 -
  11.117 -void machine_restart(char * __unused)
  11.118 -{
  11.119 -    extern int opt_noreboot;
  11.120 -#ifdef CONFIG_SMP
  11.121 -    int cpuid;
  11.122 -#endif
  11.123 -	
  11.124 -    if ( opt_noreboot )
  11.125 -    {
  11.126 -        printk("Reboot disabled on cmdline: require manual reset\n");
  11.127 -        for ( ; ; ) __asm__ __volatile__ ("hlt");
  11.128 -    }
  11.129 -
  11.130 -#ifdef CONFIG_SMP
  11.131 -    cpuid = GET_APIC_ID(apic_read(APIC_ID));
  11.132 -
  11.133 -    /* KAF: Need interrupts enabled for safe IPI. */
  11.134 -    __sti();
  11.135 -
  11.136 -    if (reboot_smp) {
  11.137 -
  11.138 -        /* check to see if reboot_cpu is valid 
  11.139 -           if its not, default to the BSP */
  11.140 -        if ((reboot_cpu == -1) ||  
  11.141 -            (reboot_cpu > (NR_CPUS -1))  || 
  11.142 -            !(phys_cpu_present_map & (1<<cpuid))) 
  11.143 -            reboot_cpu = boot_cpu_physical_apicid;
  11.144 -
  11.145 -        reboot_smp = 0;  /* use this as a flag to only go through this once*/
  11.146 -        /* re-run this function on the other CPUs
  11.147 -           it will fall though this section since we have 
  11.148 -           cleared reboot_smp, and do the reboot if it is the
  11.149 -           correct CPU, otherwise it halts. */
  11.150 -        if (reboot_cpu != cpuid)
  11.151 -            smp_call_function((void *)machine_restart , NULL, 1, 0);
  11.152 -    }
  11.153 -
  11.154 -    /* if reboot_cpu is still -1, then we want a tradional reboot, 
  11.155 -       and if we are not running on the reboot_cpu,, halt */
  11.156 -    if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
  11.157 -        for (;;)
  11.158 -            __asm__ __volatile__ ("hlt");
  11.159 -    }
  11.160 -    /*
  11.161 -     * Stop all CPUs and turn off local APICs and the IO-APIC, so
  11.162 -     * other OSs see a clean IRQ state.
  11.163 -     */
  11.164 -    smp_send_stop();
  11.165 -    disable_IO_APIC();
  11.166 -#endif
  11.167 -
  11.168 -    if(!reboot_thru_bios) {
  11.169 -        /* rebooting needs to touch the page at absolute addr 0 */
  11.170 -        *((unsigned short *)__va(0x472)) = reboot_mode;
  11.171 -        for (;;) {
  11.172 -            int i;
  11.173 -            for (i=0; i<100; i++) {
  11.174 -                kb_wait();
  11.175 -                udelay(50);
  11.176 -                outb(0xfe,0x64);         /* pulse reset low */
  11.177 -                udelay(50);
  11.178 -            }
  11.179 -            /* That didn't work - force a triple fault.. */
  11.180 -            __asm__ __volatile__("lidt %0": "=m" (no_idt));
  11.181 -            __asm__ __volatile__("int3");
  11.182 -        }
  11.183 -    }
  11.184 -
  11.185 -    panic("Need to reinclude BIOS reboot code\n");
  11.186 -}
  11.187 -
  11.188 -void machine_halt(void)
  11.189 -{
  11.190 -    machine_restart(0);
  11.191 -}
  11.192 -
  11.193 -void machine_power_off(void)
  11.194 -{
  11.195 -    machine_restart(0);
  11.196 -}
  11.197 -
  11.198 -void new_thread(struct domain *p,
  11.199 -                unsigned long start_pc,
  11.200 -                unsigned long start_stack,
  11.201 -                unsigned long start_info)
  11.202 -{
  11.203 -    execution_context_t *ec = &p->shared_info->execution_context;
  11.204 -
  11.205 -    /*
  11.206 -     * Initial register values:
  11.207 -     *  DS,ES,FS,GS = FLAT_RING1_DS
  11.208 -     *       CS:EIP = FLAT_RING1_CS:start_pc
  11.209 -     *       SS:ESP = FLAT_RING1_DS:start_stack
  11.210 -     *          ESI = start_info
  11.211 -     *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
  11.212 -     */
  11.213 -    ec->ds = ec->es = ec->fs = ec->gs = ec->ss = FLAT_RING1_DS;
  11.214 -    ec->cs = FLAT_RING1_CS;
  11.215 -    ec->eip = start_pc;
  11.216 -    ec->esp = start_stack;
  11.217 -    ec->esi = start_info;
  11.218 -
  11.219 -    __save_flags(ec->eflags);
  11.220 -    ec->eflags |= X86_EFLAGS_IF;
  11.221 -
  11.222 -    /* No fast trap at start of day. */
  11.223 -    SET_DEFAULT_FAST_TRAP(&p->thread);
  11.224 -}
  11.225 -
  11.226 -
  11.227 -/*
  11.228 - * This special macro can be used to load a debugging register
  11.229 - */
  11.230 -#define loaddebug(thread,register) \
  11.231 -		__asm__("movl %0,%%db" #register  \
  11.232 -			: /* no output */ \
  11.233 -			:"r" (thread->debugreg[register]))
  11.234 -
  11.235 -
  11.236 -void switch_to(struct domain *prev_p, struct domain *next_p)
  11.237 -{
  11.238 -    struct thread_struct *next = &next_p->thread;
  11.239 -    struct tss_struct *tss = init_tss + smp_processor_id();
  11.240 -    execution_context_t *stack_ec = get_execution_context();
  11.241 -    int i;
  11.242 -    
  11.243 -    __cli();
  11.244 -
  11.245 -    /* Switch guest general-register state. */
  11.246 -    if ( !is_idle_task(prev_p) )
  11.247 -    {
  11.248 -        memcpy(&prev_p->shared_info->execution_context, 
  11.249 -               stack_ec, 
  11.250 -               sizeof(*stack_ec));
  11.251 -        unlazy_fpu(prev_p);
  11.252 -        CLEAR_FAST_TRAP(&prev_p->thread);
  11.253 -    }
  11.254 -
  11.255 -    if ( !is_idle_task(next_p) )
  11.256 -    {
  11.257 -        memcpy(stack_ec,
  11.258 -               &next_p->shared_info->execution_context,
  11.259 -               sizeof(*stack_ec));
  11.260 -
  11.261 -        /*
  11.262 -         * This is sufficient! If the descriptor DPL differs from CS RPL then 
  11.263 -         * we'll #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared 
  11.264 -         * automatically. If SS RPL or DPL differs from CS RPL then we'll #GP.
  11.265 -         */
  11.266 -        if ( (stack_ec->cs & 3) == 0 )
  11.267 -            stack_ec->cs = FLAT_RING1_CS;
  11.268 -        if ( (stack_ec->ss & 3) == 0 )
  11.269 -            stack_ec->ss = FLAT_RING1_DS;
  11.270 -
  11.271 -        SET_FAST_TRAP(&next_p->thread);
  11.272 -
  11.273 -        /* Switch the guest OS ring-1 stack. */
  11.274 -        tss->esp1 = next->guestos_sp;
  11.275 -        tss->ss1  = next->guestos_ss;
  11.276 -
  11.277 -        /* Maybe switch the debug registers. */
  11.278 -        if ( unlikely(next->debugreg[7]) )
  11.279 -        {
  11.280 -            loaddebug(next, 0);
  11.281 -            loaddebug(next, 1);
  11.282 -            loaddebug(next, 2);
  11.283 -            loaddebug(next, 3);
  11.284 -            /* no 4 and 5 */
  11.285 -            loaddebug(next, 6);
  11.286 -            loaddebug(next, 7);
  11.287 -        }
  11.288 -
  11.289 -        /* Switch page tables. */
  11.290 -        write_ptbase(&next_p->mm);
  11.291 -        tlb_clocktick();
  11.292 -    }
  11.293 -
  11.294 -    if ( unlikely(prev_p->io_bitmap != NULL) || 
  11.295 -         unlikely(next_p->io_bitmap != NULL) )
  11.296 -    {
  11.297 -        if ( next_p->io_bitmap != NULL )
  11.298 -        {
  11.299 -            /* Copy in the appropriate parts of the IO bitmap.  We use the
  11.300 -             * selector to copy only the interesting parts of the bitmap. */
  11.301 -
  11.302 -            u64 old_sel = ~0ULL; /* IO bitmap selector for previous task. */
  11.303 -
  11.304 -            if ( prev_p->io_bitmap != NULL)
  11.305 -            {
  11.306 -                old_sel = prev_p->io_bitmap_sel;
  11.307 -
  11.308 -                /* Replace any areas of the IO bitmap that had bits cleared. */
  11.309 -                for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
  11.310 -                    if ( !test_bit(i, &prev_p->io_bitmap_sel) )
  11.311 -                        memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
  11.312 -                               &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
  11.313 -                               IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
  11.314 -            }
  11.315 -
  11.316 -            /* Copy in any regions of the new task's bitmap that have bits
  11.317 -             * clear and we haven't already dealt with. */
  11.318 -            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
  11.319 -            {
  11.320 -                if ( test_bit(i, &old_sel)
  11.321 -                     && !test_bit(i, &next_p->io_bitmap_sel) )
  11.322 -                    memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
  11.323 -                           &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
  11.324 -                           IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
  11.325 -            }
  11.326 -
  11.327 -            tss->bitmap = IO_BITMAP_OFFSET;
  11.328 -
  11.329 -	}
  11.330 -        else
  11.331 -        {
  11.332 -            /* In this case, we're switching FROM a task with IO port access,
  11.333 -             * to a task that doesn't use the IO bitmap.  We set any TSS bits
  11.334 -             * that might have been cleared, ready for future use. */
  11.335 -            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
  11.336 -                if ( !test_bit(i, &prev_p->io_bitmap_sel) )
  11.337 -                    memset(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
  11.338 -                           0xFF, IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
  11.339 -
  11.340 -            /*
  11.341 -             * a bitmap offset pointing outside of the TSS limit
  11.342 -             * causes a nicely controllable SIGSEGV if a process
  11.343 -             * tries to use a port IO instruction. The first
  11.344 -             * sys_ioperm() call sets up the bitmap properly.
  11.345 -             */
  11.346 -            tss->bitmap = INVALID_IO_BITMAP_OFFSET;
  11.347 -	}
  11.348 -    }
  11.349 -
  11.350 -    set_current(next_p);
  11.351 -
  11.352 -    /* Switch GDT and LDT. */
  11.353 -    __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->mm.gdt));
  11.354 -    load_LDT(next_p);
  11.355 -
  11.356 -    __sti();
  11.357 -}
  11.358 -
  11.359 -
  11.360 -/* XXX Currently the 'domain' field is ignored! XXX */
  11.361 -long do_iopl(domid_t domain, unsigned int new_io_pl)
  11.362 -{
  11.363 -    execution_context_t *ec = get_execution_context();
  11.364 -    ec->eflags = (ec->eflags & 0xffffcfff) | ((new_io_pl&3) << 12);
  11.365 -    return 0;
  11.366 -}
    12.1 --- a/xen/arch/x86/rwlock.c	Mon Jul 05 16:23:43 2004 +0000
    12.2 +++ b/xen/arch/x86/rwlock.c	Mon Jul 05 20:15:38 2004 +0000
    12.3 @@ -6,22 +6,22 @@ asm(
    12.4  ".align  4\n"
    12.5  ".globl  __write_lock_failed\n"
    12.6  "__write_lock_failed:\n"
    12.7 -"        " LOCK "addl    $" RW_LOCK_BIAS_STR ",(%eax)\n"
    12.8 +"        " LOCK "addl    $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n"
    12.9  "1:      rep; nop\n"
   12.10 -"        cmpl    $" RW_LOCK_BIAS_STR ",(%eax)\n"
   12.11 +"        cmpl    $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n"
   12.12  "        jne     1b\n"
   12.13 -"        " LOCK "subl    $" RW_LOCK_BIAS_STR ",(%eax)\n"
   12.14 +"        " LOCK "subl    $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n"
   12.15  "        jnz     __write_lock_failed\n"
   12.16  "        ret\n"
   12.17  
   12.18  ".align  4\n"
   12.19  ".globl  __read_lock_failed\n"
   12.20  "__read_lock_failed:\n"
   12.21 -"        lock ; incl     (%eax)\n"
   12.22 +"        lock ; incl     (%"__OP"ax)\n"
   12.23  "1:      rep; nop\n"
   12.24 -"        cmpl    $1,(%eax)\n"
   12.25 +"        cmpl    $1,(%"__OP"ax)\n"
   12.26  "        js      1b\n"
   12.27 -"        lock ; decl     (%eax)\n"
   12.28 +"        lock ; decl     (%"__OP"ax)\n"
   12.29  "        js      __read_lock_failed\n"
   12.30  "        ret\n"
   12.31  );
    13.1 --- a/xen/arch/x86/setup.c	Mon Jul 05 16:23:43 2004 +0000
    13.2 +++ b/xen/arch/x86/setup.c	Mon Jul 05 20:15:38 2004 +0000
    13.3 @@ -54,6 +54,8 @@ int acpi_force __initdata = 0;
    13.4  int phys_proc_id[NR_CPUS];
    13.5  int logical_proc_id[NR_CPUS];
    13.6  
    13.7 +#if defined(__i386__)
    13.8 +
    13.9  /* Standard macro to see if a specific flag is changeable */
   13.10  static inline int flag_is_changeable_p(u32 flag)
   13.11  {
   13.12 @@ -81,6 +83,12 @@ static int __init have_cpuid_p(void)
   13.13      return flag_is_changeable_p(X86_EFLAGS_ID);
   13.14  }
   13.15  
   13.16 +#elif defined(__x86_64__)
   13.17 +
   13.18 +#define have_cpuid_p() (1)
   13.19 +
   13.20 +#endif
   13.21 +
   13.22  void __init get_cpu_vendor(struct cpuinfo_x86 *c)
   13.23  {
   13.24      char *v = c->x86_vendor_id;
   13.25 @@ -259,6 +267,7 @@ void __init identify_cpu(struct cpuinfo_
   13.26  unsigned long cpu_initialized;
   13.27  void __init cpu_init(void)
   13.28  {
   13.29 +#if defined(__i386__) /* XXX */
   13.30      int nr = smp_processor_id();
   13.31      struct tss_struct * t = &init_tss[nr];
   13.32  
   13.33 @@ -297,6 +306,7 @@ void __init cpu_init(void)
   13.34      write_ptbase(&current->mm);
   13.35  
   13.36      init_idle_task();
   13.37 +#endif
   13.38  }
   13.39  
   13.40  static void __init do_initcalls(void)
    14.1 --- a/xen/arch/x86/smpboot.c	Mon Jul 05 16:23:43 2004 +0000
    14.2 +++ b/xen/arch/x86/smpboot.c	Mon Jul 05 20:15:38 2004 +0000
    14.3 @@ -659,7 +659,9 @@ static void __init do_boot_cpu (int apic
    14.4  
    14.5      map_cpu_to_boot_apicid(cpu, apicid);
    14.6  
    14.7 +#if defined(__i386__)
    14.8      SET_DEFAULT_FAST_TRAP(&idle->thread);
    14.9 +#endif
   14.10  
   14.11      idle_task[cpu] = idle;
   14.12  
    15.1 --- a/xen/arch/x86/time.c	Mon Jul 05 16:23:43 2004 +0000
    15.2 +++ b/xen/arch/x86/time.c	Mon Jul 05 20:15:38 2004 +0000
    15.3 @@ -107,7 +107,8 @@ static struct irqaction irq0 = { timer_i
    15.4  
    15.5  static unsigned long __init calibrate_tsc(void)
    15.6  {
    15.7 -    unsigned long startlow, starthigh, endlow, endhigh, count;
    15.8 +    u64 start, end, diff;
    15.9 +    unsigned long count;
   15.10  
   15.11      /* Set the Gate high, disable speaker */
   15.12      outb((inb(0x61) & ~0x02) | 0x01, 0x61);
   15.13 @@ -123,22 +124,24 @@ static unsigned long __init calibrate_ts
   15.14      outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
   15.15      outb(CALIBRATE_LATCH >> 8, 0x42);   /* MSB of count */
   15.16  
   15.17 -    rdtsc(startlow, starthigh);
   15.18 +    rdtscll(start);
   15.19      for ( count = 0; (inb(0x61) & 0x20) == 0; count++ )
   15.20          continue;
   15.21 -    rdtsc(endlow, endhigh);
   15.22 +    rdtscll(end);
   15.23  
   15.24      /* Error if the CTC doesn't behave itself. */
   15.25      if ( count == 0 )
   15.26          return 0;
   15.27  
   15.28 -    /* [endhigh:endlow] = [endhigh:endlow] - [starthigh:startlow] */
   15.29 -    __asm__( "subl %2,%0 ; sbbl %3,%1"
   15.30 -             : "=a" (endlow), "=d" (endhigh)
   15.31 -             : "g" (startlow), "g" (starthigh), "0" (endlow), "1" (endhigh) );
   15.32 +    diff = end - start;
   15.33  
   15.34 +#if defined(_i386__)
   15.35      /* If quotient doesn't fit in 32 bits then we return error (zero). */
   15.36 -    return endhigh ? 0 : endlow;
   15.37 +    if ( diff & ~0xffffffffULL )
   15.38 +        return 0;
   15.39 +#endif
   15.40 +
   15.41 +    return (unsigned long)diff;
   15.42  }
   15.43  
   15.44  
    16.1 --- a/xen/arch/x86/trampoline.S	Mon Jul 05 16:23:43 2004 +0000
    16.2 +++ b/xen/arch/x86/trampoline.S	Mon Jul 05 20:15:38 2004 +0000
    16.3 @@ -43,7 +43,11 @@ r_base = .
    16.4  	lmsw	%ax		# into protected mode
    16.5  	jmp	flush_instr
    16.6  flush_instr:
    16.7 -	ljmpl	$__HYPERVISOR_CS, $0x100000 # 1MB
    16.8 +#if defined(__x86_64__)
    16.9 +	ljmpl	$__HYPERVISOR_CS32, $0x100000 # 1MB
   16.10 +#else        
   16.11 +	ljmpl	$__HYPERVISOR_CS,   $0x100000 # 1MB
   16.12 +#endif
   16.13  
   16.14  idt_48:
   16.15  	.word	0			# idt limit = 0
    17.1 --- a/xen/arch/x86/traps.c	Mon Jul 05 16:23:43 2004 +0000
    17.2 +++ b/xen/arch/x86/traps.c	Mon Jul 05 20:15:38 2004 +0000
    17.3 @@ -62,6 +62,8 @@ struct guest_trap_bounce {
    17.4      unsigned long  eip;               /*  12 */
    17.5  } guest_trap_bounce[NR_CPUS] = { { 0 } };
    17.6  
    17.7 +#if defined(__i386__)
    17.8 +
    17.9  #define DOUBLEFAULT_STACK_SIZE 1024
   17.10  static struct tss_struct doublefault_tss;
   17.11  static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
   17.12 @@ -906,3 +908,5 @@ unsigned long do_get_debugreg(int reg)
   17.13      if ( (reg < 0) || (reg > 7) ) return -EINVAL;
   17.14      return current->thread.debugreg[reg];
   17.15  }
   17.16 +
   17.17 +#endif /* __i386__ */
    18.1 --- a/xen/arch/x86/usercopy.c	Mon Jul 05 16:23:43 2004 +0000
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,190 +0,0 @@
    18.4 -/* 
    18.5 - * User address space access functions.
    18.6 - * The non inlined parts of asm-i386/uaccess.h are here.
    18.7 - *
    18.8 - * Copyright 1997 Andi Kleen <ak@muc.de>
    18.9 - * Copyright 1997 Linus Torvalds
   18.10 - */
   18.11 -#include <xen/config.h>
   18.12 -#include <asm/uaccess.h>
   18.13 -//#include <asm/mmx.h>
   18.14 -
   18.15 -#ifdef CONFIG_X86_USE_3DNOW_AND_WORKS
   18.16 -
   18.17 -unsigned long
   18.18 -__generic_copy_to_user(void *to, const void *from, unsigned long n)
   18.19 -{
   18.20 -	if (access_ok(VERIFY_WRITE, to, n))
   18.21 -	{
   18.22 -		if(n<512)
   18.23 -			__copy_user(to,from,n);
   18.24 -		else
   18.25 -			mmx_copy_user(to,from,n);
   18.26 -	}
   18.27 -	return n;
   18.28 -}
   18.29 -
   18.30 -unsigned long
   18.31 -__generic_copy_from_user(void *to, const void *from, unsigned long n)
   18.32 -{
   18.33 -	if (access_ok(VERIFY_READ, from, n))
   18.34 -	{
   18.35 -		if(n<512)
   18.36 -			__copy_user_zeroing(to,from,n);
   18.37 -		else
   18.38 -			mmx_copy_user_zeroing(to, from, n);
   18.39 -	}
   18.40 -	else
   18.41 -		memset(to, 0, n);
   18.42 -	return n;
   18.43 -}
   18.44 -
   18.45 -#else
   18.46 -
   18.47 -unsigned long
   18.48 -__generic_copy_to_user(void *to, const void *from, unsigned long n)
   18.49 -{
   18.50 -	prefetch(from);
   18.51 -	if (access_ok(VERIFY_WRITE, to, n))
   18.52 -		__copy_user(to,from,n);
   18.53 -	return n;
   18.54 -}
   18.55 -
   18.56 -unsigned long
   18.57 -__generic_copy_from_user(void *to, const void *from, unsigned long n)
   18.58 -{
   18.59 -	prefetchw(to);
   18.60 -	if (access_ok(VERIFY_READ, from, n))
   18.61 -		__copy_user_zeroing(to,from,n);
   18.62 -	else
   18.63 -		memset(to, 0, n);
   18.64 -	return n;
   18.65 -}
   18.66 -
   18.67 -#endif
   18.68 -
   18.69 -/*
   18.70 - * Copy a null terminated string from userspace.
   18.71 - */
   18.72 -
   18.73 -#define __do_strncpy_from_user(dst,src,count,res)			   \
   18.74 -do {									   \
   18.75 -	int __d0, __d1, __d2;						   \
   18.76 -	__asm__ __volatile__(						   \
   18.77 -		"	testl %1,%1\n"					   \
   18.78 -		"	jz 2f\n"					   \
   18.79 -		"0:	lodsb\n"					   \
   18.80 -		"	stosb\n"					   \
   18.81 -		"	testb %%al,%%al\n"				   \
   18.82 -		"	jz 1f\n"					   \
   18.83 -		"	decl %1\n"					   \
   18.84 -		"	jnz 0b\n"					   \
   18.85 -		"1:	subl %1,%0\n"					   \
   18.86 -		"2:\n"							   \
   18.87 -		".section .fixup,\"ax\"\n"				   \
   18.88 -		"3:	movl %5,%0\n"					   \
   18.89 -		"	jmp 2b\n"					   \
   18.90 -		".previous\n"						   \
   18.91 -		".section __ex_table,\"a\"\n"				   \
   18.92 -		"	.align 4\n"					   \
   18.93 -		"	.long 0b,3b\n"					   \
   18.94 -		".previous"						   \
   18.95 -		: "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),	   \
   18.96 -		  "=&D" (__d2)						   \
   18.97 -		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
   18.98 -		: "memory");						   \
   18.99 -} while (0)
  18.100 -
  18.101 -long
  18.102 -__strncpy_from_user(char *dst, const char *src, long count)
  18.103 -{
  18.104 -	long res;
  18.105 -	__do_strncpy_from_user(dst, src, count, res);
  18.106 -	return res;
  18.107 -}
  18.108 -
  18.109 -long
  18.110 -strncpy_from_user(char *dst, const char *src, long count)
  18.111 -{
  18.112 -	long res = -EFAULT;
  18.113 -	if (access_ok(VERIFY_READ, src, 1))
  18.114 -		__do_strncpy_from_user(dst, src, count, res);
  18.115 -	return res;
  18.116 -}
  18.117 -
  18.118 -
  18.119 -/*
  18.120 - * Zero Userspace
  18.121 - */
  18.122 -
  18.123 -#define __do_clear_user(addr,size)					\
  18.124 -do {									\
  18.125 -	int __d0;							\
  18.126 -  	__asm__ __volatile__(						\
  18.127 -		"0:	rep; stosl\n"					\
  18.128 -		"	movl %2,%0\n"					\
  18.129 -		"1:	rep; stosb\n"					\
  18.130 -		"2:\n"							\
  18.131 -		".section .fixup,\"ax\"\n"				\
  18.132 -		"3:	lea 0(%2,%0,4),%0\n"				\
  18.133 -		"	jmp 2b\n"					\
  18.134 -		".previous\n"						\
  18.135 -		".section __ex_table,\"a\"\n"				\
  18.136 -		"	.align 4\n"					\
  18.137 -		"	.long 0b,3b\n"					\
  18.138 -		"	.long 1b,2b\n"					\
  18.139 -		".previous"						\
  18.140 -		: "=&c"(size), "=&D" (__d0)				\
  18.141 -		: "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));	\
  18.142 -} while (0)
  18.143 -
  18.144 -unsigned long
  18.145 -clear_user(void *to, unsigned long n)
  18.146 -{
  18.147 -	if (access_ok(VERIFY_WRITE, to, n))
  18.148 -		__do_clear_user(to, n);
  18.149 -	return n;
  18.150 -}
  18.151 -
  18.152 -unsigned long
  18.153 -__clear_user(void *to, unsigned long n)
  18.154 -{
  18.155 -	__do_clear_user(to, n);
  18.156 -	return n;
  18.157 -}
  18.158 -
  18.159 -/*
  18.160 - * Return the size of a string (including the ending 0)
  18.161 - *
  18.162 - * Return 0 on exception, a value greater than N if too long
  18.163 - */
  18.164 -
  18.165 -long strnlen_user(const char *s, long n)
  18.166 -{
  18.167 -	unsigned long mask = -__addr_ok(s);
  18.168 -	unsigned long res, tmp;
  18.169 -
  18.170 -	__asm__ __volatile__(
  18.171 -		"	testl %0, %0\n"
  18.172 -		"	jz 3f\n"
  18.173 -		"	andl %0,%%ecx\n"
  18.174 -		"0:	repne; scasb\n"
  18.175 -		"	setne %%al\n"
  18.176 -		"	subl %%ecx,%0\n"
  18.177 -		"	addl %0,%%eax\n"
  18.178 -		"1:\n"
  18.179 -		".section .fixup,\"ax\"\n"
  18.180 -		"2:	xorl %%eax,%%eax\n"
  18.181 -		"	jmp 1b\n"
  18.182 -		"3:	movb $1,%%al\n"
  18.183 -		"	jmp 1b\n"
  18.184 -		".previous\n"
  18.185 -		".section __ex_table,\"a\"\n"
  18.186 -		"	.align 4\n"
  18.187 -		"	.long 0b,2b\n"
  18.188 -		".previous"
  18.189 -		:"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
  18.190 -		:"0" (n), "1" (s), "2" (0), "3" (mask)
  18.191 -		:"cc");
  18.192 -	return res & mask;
  18.193 -}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/xen/arch/x86/x86_32/domain_page.c	Mon Jul 05 20:15:38 2004 +0000
    19.3 @@ -0,0 +1,81 @@
    19.4 +/******************************************************************************
    19.5 + * domain_page.h
    19.6 + * 
    19.7 + * Allow temporary mapping of domain pages. Based on ideas from the
    19.8 + * Linux PKMAP code -- the copyrights and credits are retained below.
    19.9 + */
   19.10 +
   19.11 +/*
   19.12 + * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de
   19.13 + *          Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de *
   19.14 + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
   19.15 + */
   19.16 +
   19.17 +#include <xen/config.h>
   19.18 +#include <xen/sched.h>
   19.19 +#include <xen/mm.h>
   19.20 +#include <xen/perfc.h>
   19.21 +#include <asm/domain_page.h>
   19.22 +#include <asm/flushtlb.h>
   19.23 +
   19.24 +unsigned long *mapcache;
   19.25 +static unsigned int map_idx, shadow_map_idx[NR_CPUS];
   19.26 +static spinlock_t map_lock = SPIN_LOCK_UNLOCKED;
   19.27 +
   19.28 +/* Use a spare PTE bit to mark entries ready for recycling. */
   19.29 +#define READY_FOR_TLB_FLUSH (1<<10)
   19.30 +
   19.31 +static void flush_all_ready_maps(void)
   19.32 +{
   19.33 +    unsigned long *cache = mapcache;
   19.34 +
   19.35 +    /* A bit skanky -- depends on having an aligned PAGE_SIZE set of PTEs. */
   19.36 +    do { if ( (*cache & READY_FOR_TLB_FLUSH) ) *cache = 0; }
   19.37 +    while ( ((unsigned long)(++cache) & ~PAGE_MASK) != 0 );
   19.38 +
   19.39 +    perfc_incrc(domain_page_tlb_flush);
   19.40 +    local_flush_tlb();
   19.41 +}
   19.42 +
   19.43 +
   19.44 +void *map_domain_mem(unsigned long pa)
   19.45 +{
   19.46 +    unsigned long va;
   19.47 +    unsigned int idx, cpu = smp_processor_id();
   19.48 +    unsigned long *cache = mapcache;
   19.49 +    unsigned long flags;
   19.50 +
   19.51 +    perfc_incrc(map_domain_mem_count);
   19.52 +
   19.53 +    spin_lock_irqsave(&map_lock, flags);
   19.54 +
   19.55 +    /* Has some other CPU caused a wrap? We must flush if so. */
   19.56 +    if ( map_idx < shadow_map_idx[cpu] )
   19.57 +    {
   19.58 +        perfc_incrc(domain_page_tlb_flush);
   19.59 +        local_flush_tlb();
   19.60 +    }
   19.61 +
   19.62 +    for ( ; ; )
   19.63 +    {
   19.64 +        idx = map_idx = (map_idx + 1) & (MAPCACHE_ENTRIES - 1);
   19.65 +        if ( idx == 0 ) flush_all_ready_maps();
   19.66 +        if ( cache[idx] == 0 ) break;
   19.67 +    }
   19.68 +
   19.69 +    cache[idx] = (pa & PAGE_MASK) | __PAGE_HYPERVISOR;
   19.70 +
   19.71 +    spin_unlock_irqrestore(&map_lock, flags);
   19.72 +
   19.73 +    shadow_map_idx[cpu] = idx;
   19.74 +
   19.75 +    va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT) + (pa & ~PAGE_MASK);
   19.76 +    return (void *)va;
   19.77 +}
   19.78 +
   19.79 +void unmap_domain_mem(void *va)
   19.80 +{
   19.81 +    unsigned int idx;
   19.82 +    idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
   19.83 +    mapcache[idx] |= READY_FOR_TLB_FLUSH;
   19.84 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/xen/arch/x86/x86_32/entry.S	Mon Jul 05 20:15:38 2004 +0000
    20.3 @@ -0,0 +1,696 @@
    20.4 +/*
    20.5 + * Hypercall and fault low-level handling routines.
    20.6 + *
    20.7 + * Copyright (c) 2002-2004, K A Fraser
    20.8 + * Copyright (c) 1991, 1992 Linus Torvalds
    20.9 + */
   20.10 +
   20.11 +/*
   20.12 + * The idea for callbacks to guest OSes
   20.13 + * ====================================
   20.14 + *
   20.15 + * First, we require that all callbacks (either via a supplied
   20.16 + * interrupt-descriptor-table, or via the special event or failsafe callbacks
   20.17 + * in the shared-info-structure) are to ring 1. This just makes life easier,
   20.18 + * in that it means we don't have to do messy GDT/LDT lookups to find
   20.19 + * out which the privilege-level of the return code-selector. That code
   20.20 + * would just be a hassle to write, and would need to account for running
   20.21 + * off the end of the GDT/LDT, for example. For all callbacks we check
   20.22 + * that the provided
   20.23 + * return CS is not == __HYPERVISOR_{CS,DS}. Apart from that we're safe as
   20.24 + * don't allow a guest OS to install ring-0 privileges into the GDT/LDT.
   20.25 + * It's up to the guest OS to ensure all returns via the IDT are to ring 1.
   20.26 + * If not, we load incorrect SS/ESP values from the TSS (for ring 1 rather
   20.27 + * than the correct ring) and bad things are bound to ensue -- IRET is
   20.28 + * likely to fault, and we may end up killing the domain (no harm can
   20.29 + * come to Xen, though).
   20.30 + *      
   20.31 + * When doing a callback, we check if the return CS is in ring 0. If so,
   20.32 + * callback is delayed until next return to ring != 0.
   20.33 + * If return CS is in ring 1, then we create a callback frame
   20.34 + * starting at return SS/ESP. The base of the frame does an intra-privilege
   20.35 + * interrupt-return.
   20.36 + * If return CS is in ring > 1, we create a callback frame starting
   20.37 + * at SS/ESP taken from appropriate section of the current TSS. The base
   20.38 + * of the frame does an inter-privilege interrupt-return.
   20.39 + * 
   20.40 + * Note that the "failsafe callback" uses a special stackframe:
   20.41 + * { return_DS, return_ES, return_FS, return_GS, return_EIP,
   20.42 + *   return_CS, return_EFLAGS[, return_ESP, return_SS] }
   20.43 + * That is, original values for DS/ES/FS/GS are placed on stack rather than
   20.44 + * in DS/ES/FS/GS themselves. Why? It saves us loading them, only to have them
   20.45 + * saved/restored in guest OS. Furthermore, if we load them we may cause
   20.46 + * a fault if they are invalid, which is a hassle to deal with. We avoid
   20.47 + * that problem if we don't load them :-) This property allows us to use
   20.48 + * the failsafe callback as a fallback: if we ever fault on loading DS/ES/FS/GS
   20.49 + * on return to ring != 0, we can simply package it up as a return via
   20.50 + * the failsafe callback, and let the guest OS sort it out (perhaps by
   20.51 + * killing an application process). Note that we also do this for any
   20.52 + * faulting IRET -- just let the guest OS handle it via the event
   20.53 + * callback.
   20.54 + *
   20.55 + * We terminate a domain in the following cases:
   20.56 + *  - creating a callback stack frame (due to bad ring-1 stack).
   20.57 + *  - faulting IRET on entry to failsafe callback handler.
   20.58 + * So, each domain must keep its ring-1 %ss/%esp and failsafe callback
   20.59 + * handler in good order (absolutely no faults allowed!).
   20.60 + */
   20.61 +
   20.62 +#include <xen/config.h>
   20.63 +#include <xen/errno.h>
   20.64 +#include <hypervisor-ifs/hypervisor-if.h>
   20.65 +
   20.66 +EBX		= 0x00
   20.67 +ECX		= 0x04
   20.68 +EDX		= 0x08
   20.69 +ESI		= 0x0C
   20.70 +EDI		= 0x10
   20.71 +EBP		= 0x14
   20.72 +EAX		= 0x18
   20.73 +DS		= 0x1C
   20.74 +ES		= 0x20
   20.75 +FS              = 0x24
   20.76 +GS              = 0x28
   20.77 +ORIG_EAX	= 0x2C
   20.78 +EIP		= 0x30
   20.79 +CS		= 0x34
   20.80 +EFLAGS		= 0x38
   20.81 +OLDESP		= 0x3C
   20.82 +OLDSS		= 0x40
   20.83 +
   20.84 +/* Offsets in domain structure */
   20.85 +PROCESSOR       =  0
   20.86 +SHARED_INFO     =  4
   20.87 +EVENT_SEL       =  8
   20.88 +EVENT_ADDR      = 12
   20.89 +FAILSAFE_BUFFER = 16
   20.90 +FAILSAFE_SEL    = 32
   20.91 +FAILSAFE_ADDR   = 36
   20.92 +
   20.93 +/* Offsets in shared_info_t */
   20.94 +#define UPCALL_PENDING /* 0 */
   20.95 +#define UPCALL_MASK       1
   20.96 +
   20.97 +/* Offsets in guest_trap_bounce */
   20.98 +GTB_ERROR_CODE   =  0
   20.99 +GTB_CR2          =  4
  20.100 +GTB_FLAGS        =  8
  20.101 +GTB_CS           = 10
  20.102 +GTB_EIP          = 12
  20.103 +GTBF_TRAP        =  1
  20.104 +GTBF_TRAP_NOCODE =  2
  20.105 +GTBF_TRAP_CR2    =  4
  20.106 +                        
  20.107 +CF_MASK		= 0x00000001
  20.108 +IF_MASK		= 0x00000200
  20.109 +NT_MASK		= 0x00004000
  20.110 +        
  20.111 +#define SAVE_ALL_NOSEGREGS \
  20.112 +        cld; \
  20.113 +        pushl %gs; \
  20.114 +        pushl %fs; \
  20.115 +        pushl %es; \
  20.116 +        pushl %ds; \
  20.117 +        pushl %eax; \
  20.118 +        pushl %ebp; \
  20.119 +        pushl %edi; \
  20.120 +        pushl %esi; \
  20.121 +        pushl %edx; \
  20.122 +        pushl %ecx; \
  20.123 +        pushl %ebx; \
  20.124 +
  20.125 +#define SAVE_ALL \
  20.126 +        SAVE_ALL_NOSEGREGS \
  20.127 +        movl $(__HYPERVISOR_DS),%edx; \
  20.128 +        movl %edx,%ds; \
  20.129 +        movl %edx,%es; \
  20.130 +        movl %edx,%fs; \
  20.131 +        movl %edx,%gs; \
  20.132 +        sti;
  20.133 +
  20.134 +#define GET_CURRENT(reg)   \
  20.135 +        movl $4096-4, reg; \
  20.136 +        orl  %esp, reg;    \
  20.137 +        andl $~3,reg;      \
  20.138 +        movl (reg),reg;
  20.139 +
  20.140 +ENTRY(continue_nonidle_task)
  20.141 +        GET_CURRENT(%ebx)
  20.142 +        jmp test_all_events
  20.143 +
  20.144 +        ALIGN
  20.145 +/*
  20.146 + * HYPERVISOR_multicall(call_list, nr_calls)
  20.147 + *   Execute a list of 'nr_calls' hypercalls, pointed at by 'call_list'.
  20.148 + *   This is fairly easy except that:
  20.149 + *   1. We may fault reading the call list, and must patch that up; and
  20.150 + *   2. We cannot recursively call HYPERVISOR_multicall, or a malicious
  20.151 + *      caller could cause our stack to blow up.
  20.152 + */
  20.153 +do_multicall:
  20.154 +        popl  %eax
  20.155 +        cmpl  $SYMBOL_NAME(multicall_return_from_call),%eax
  20.156 +        je    multicall_return_from_call
  20.157 +        pushl %ebx
  20.158 +        movl  4(%esp),%ebx   /* EBX == call_list */
  20.159 +        movl  8(%esp),%ecx   /* ECX == nr_calls  */
  20.160 +multicall_loop:
  20.161 +        pushl %ecx
  20.162 +multicall_fault1: 
  20.163 +        pushl 20(%ebx)      # args[4]
  20.164 +multicall_fault2: 
  20.165 +        pushl 16(%ebx)      # args[3]
  20.166 +multicall_fault3: 
  20.167 +        pushl 12(%ebx)      # args[2]
  20.168 +multicall_fault4: 
  20.169 +        pushl 8(%ebx)       # args[1]
  20.170 +multicall_fault5: 
  20.171 +        pushl 4(%ebx)       # args[0]
  20.172 +multicall_fault6: 
  20.173 +        movl  (%ebx),%eax   # op
  20.174 +        andl  $(NR_hypercalls-1),%eax
  20.175 +        call  *SYMBOL_NAME(hypercall_table)(,%eax,4)
  20.176 +multicall_return_from_call:
  20.177 +multicall_fault7:
  20.178 +        movl  %eax,24(%ebx) # args[5] == result
  20.179 +        addl  $20,%esp
  20.180 +        popl  %ecx
  20.181 +        addl  $(ARGS_PER_MULTICALL_ENTRY*4),%ebx
  20.182 +        loop  multicall_loop
  20.183 +        popl  %ebx
  20.184 +        xorl  %eax,%eax
  20.185 +        jmp   ret_from_hypercall
  20.186 +
  20.187 +.section __ex_table,"a"
  20.188 +        .align 4
  20.189 +        .long multicall_fault1, multicall_fixup1
  20.190 +        .long multicall_fault2, multicall_fixup2
  20.191 +        .long multicall_fault3, multicall_fixup3
  20.192 +        .long multicall_fault4, multicall_fixup4
  20.193 +        .long multicall_fault5, multicall_fixup5
  20.194 +        .long multicall_fault6, multicall_fixup6
  20.195 +.previous
  20.196 +               
  20.197 +.section .fixup,"ax"
  20.198 +multicall_fixup6: 
  20.199 +        addl  $4,%esp
  20.200 +multicall_fixup5: 
  20.201 +        addl  $4,%esp
  20.202 +multicall_fixup4: 
  20.203 +        addl  $4,%esp
  20.204 +multicall_fixup3: 
  20.205 +        addl  $4,%esp
  20.206 +multicall_fixup2: 
  20.207 +        addl  $4,%esp
  20.208 +multicall_fixup1:
  20.209 +        addl  $4,%esp
  20.210 +        popl  %ebx
  20.211 +        movl  $-EFAULT,%eax
  20.212 +        jmp   ret_from_hypercall
  20.213 +.previous        
  20.214 +                
  20.215 +        ALIGN
  20.216 +restore_all_guest:
  20.217 +        # First, may need to restore %ds if clobbered by create_bounce_frame
  20.218 +        pushl %ss
  20.219 +        popl  %ds
  20.220 +        # Second, create a failsafe copy of DS,ES,FS,GS in case any are bad
  20.221 +        leal  DS(%esp),%esi
  20.222 +        leal  FAILSAFE_BUFFER(%ebx),%edi
  20.223 +        movsl
  20.224 +        movsl
  20.225 +        movsl
  20.226 +        movsl
  20.227 +        # Finally, restore guest registers -- faults will cause failsafe
  20.228 +        popl %ebx
  20.229 +	popl %ecx
  20.230 +	popl %edx
  20.231 +	popl %esi
  20.232 +	popl %edi
  20.233 +	popl %ebp
  20.234 +	popl %eax
  20.235 +1:	popl %ds
  20.236 +2:	popl %es
  20.237 +3:	popl %fs
  20.238 +4:	popl %gs
  20.239 +        addl $4,%esp
  20.240 +5:      iret
  20.241 +.section .fixup,"ax"
  20.242 +10:     subl $4,%esp
  20.243 +        pushl %gs
  20.244 +9:      pushl %fs
  20.245 +8:      pushl %es
  20.246 +7:      pushl %ds
  20.247 +6:      pushl %eax
  20.248 +	pushl %ebp
  20.249 +	pushl %edi
  20.250 +	pushl %esi
  20.251 +	pushl %edx
  20.252 +	pushl %ecx
  20.253 +	pushl %ebx
  20.254 +	pushl %ss
  20.255 +	popl  %ds
  20.256 +	pushl %ss
  20.257 +	popl  %es
  20.258 +	jmp  failsafe_callback
  20.259 +.previous
  20.260 +.section __ex_table,"a"
  20.261 +	.align 4
  20.262 +	.long 1b,6b
  20.263 +	.long 2b,7b
  20.264 +	.long 3b,8b
  20.265 +	.long 4b,9b
  20.266 +	.long 5b,10b
  20.267 +.previous
  20.268 +
  20.269 +/* No special register assumptions */
  20.270 +failsafe_callback:
  20.271 +        GET_CURRENT(%ebx)
  20.272 +        movl PROCESSOR(%ebx),%eax
  20.273 +        shl  $4,%eax
  20.274 +        lea  guest_trap_bounce(%eax),%edx
  20.275 +        movl FAILSAFE_ADDR(%ebx),%eax
  20.276 +        movl %eax,GTB_EIP(%edx)
  20.277 +        movl FAILSAFE_SEL(%ebx),%eax
  20.278 +        movw %ax,GTB_CS(%edx)
  20.279 +        call create_bounce_frame
  20.280 +        subl $16,%esi                # add DS/ES/FS/GS to failsafe stack frame
  20.281 +        leal FAILSAFE_BUFFER(%ebx),%ebp
  20.282 +        movl  0(%ebp),%eax           # DS
  20.283 +FAULT1: movl %eax,(%esi) 
  20.284 +        movl  4(%ebp),%eax           # ES
  20.285 +FAULT2: movl %eax,4(%esi)
  20.286 +        movl  8(%ebp),%eax           # FS
  20.287 +FAULT3: movl %eax,8(%esi) 
  20.288 +        movl 12(%ebp),%eax           # GS
  20.289 +FAULT4: movl %eax,12(%esi)
  20.290 +        movl %esi,OLDESP(%esp)
  20.291 +        popl %ebx
  20.292 +        popl %ecx
  20.293 +        popl %edx
  20.294 +        popl %esi
  20.295 +        popl %edi
  20.296 +        popl %ebp
  20.297 +        popl %eax
  20.298 +        addl $20,%esp                # skip DS/ES/FS/GS/ORIG_EAX
  20.299 +FAULT5: iret 
  20.300 +
  20.301 +
  20.302 +        ALIGN
  20.303 +# Simple restore -- we should never fault as we we will only interrupt ring 0
  20.304 +# when sane values have been placed in all registers. The only exception is
  20.305 +# NMI, which may interrupt before good values have been placed in DS-GS.
  20.306 +# The NMI return code deals with this problem itself.
  20.307 +restore_all_xen:
  20.308 +	popl %ebx
  20.309 +	popl %ecx
  20.310 +	popl %edx
  20.311 +	popl %esi
  20.312 +	popl %edi
  20.313 +	popl %ebp
  20.314 +	popl %eax
  20.315 +	popl %ds
  20.316 +	popl %es
  20.317 +	popl %fs
  20.318 +	popl %gs
  20.319 +        addl $4,%esp
  20.320 +        iret
  20.321 +
  20.322 +        ALIGN
  20.323 +ENTRY(hypercall)
  20.324 +        pushl %eax			# save orig_eax
  20.325 +	SAVE_ALL
  20.326 +	GET_CURRENT(%ebx)
  20.327 +	andl $(NR_hypercalls-1),%eax
  20.328 +	call *SYMBOL_NAME(hypercall_table)(,%eax,4)
  20.329 +
  20.330 +ret_from_hypercall:
  20.331 +        movl %eax,EAX(%esp)		# save the return value
  20.332 +
  20.333 +test_all_events:
  20.334 +        xorl %ecx,%ecx
  20.335 +        notl %ecx
  20.336 +        cli                             # tests must not race interrupts
  20.337 +/*test_softirqs:*/  
  20.338 +        movl PROCESSOR(%ebx),%eax
  20.339 +        shl  $6,%eax                    # sizeof(irq_cpustat) == 64
  20.340 +        test %ecx,SYMBOL_NAME(irq_stat)(%eax,1)
  20.341 +        jnz  process_softirqs
  20.342 +/*test_guest_events:*/
  20.343 +        movl SHARED_INFO(%ebx),%eax
  20.344 +        testb $0xFF,UPCALL_MASK(%eax)
  20.345 +        jnz  restore_all_guest
  20.346 +        testb $0xFF,UPCALL_PENDING(%eax)
  20.347 +        jz   restore_all_guest
  20.348 +        movb $1,UPCALL_MASK(%eax)       # Upcalls are masked during delivery
  20.349 +/*process_guest_events:*/
  20.350 +        movl PROCESSOR(%ebx),%edx
  20.351 +        shl  $4,%edx                    # sizeof(guest_trap_bounce) == 16
  20.352 +        lea  guest_trap_bounce(%edx),%edx
  20.353 +        movl EVENT_ADDR(%ebx),%eax
  20.354 +        movl %eax,GTB_EIP(%edx)
  20.355 +        movl EVENT_SEL(%ebx),%eax
  20.356 +        movw %ax,GTB_CS(%edx)
  20.357 +        call create_bounce_frame
  20.358 +        jmp  restore_all_guest
  20.359 +
  20.360 +        ALIGN
  20.361 +process_softirqs:
  20.362 +        sti       
  20.363 +        call SYMBOL_NAME(do_softirq)
  20.364 +        jmp  test_all_events
  20.365 +                
  20.366 +/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:         */
  20.367 +/*   {EIP, CS, EFLAGS, [ESP, SS]}                                     */
  20.368 +/* %edx == guest_trap_bounce, %ebx == task_struct                     */
  20.369 +/* %eax,%ecx are clobbered. %ds:%esi contain new OLDSS/OLDESP.        */
  20.370 +create_bounce_frame:        
  20.371 +        mov  CS+4(%esp),%cl
  20.372 +        test $2,%cl
  20.373 +        jz   1f /* jump if returning to an existing ring-1 activation */
  20.374 +        /* obtain ss/esp from TSS -- no current ring-1 activations */
  20.375 +        movl PROCESSOR(%ebx),%eax
  20.376 +        /* next 4 lines multiply %eax by 8320, which is sizeof(tss_struct) */
  20.377 +        movl %eax, %ecx
  20.378 +        shll $7, %ecx
  20.379 +        shll $13, %eax
  20.380 +        addl %ecx,%eax
  20.381 +        addl $init_tss + 12,%eax
  20.382 +        movl (%eax),%esi /* tss->esp1 */
  20.383 +FAULT6: movl 4(%eax),%ds /* tss->ss1  */
  20.384 +        /* base of stack frame must contain ss/esp (inter-priv iret) */
  20.385 +        subl $8,%esi
  20.386 +        movl OLDESP+4(%esp),%eax
  20.387 +FAULT7: movl %eax,(%esi) 
  20.388 +        movl OLDSS+4(%esp),%eax
  20.389 +FAULT8: movl %eax,4(%esi) 
  20.390 +        jmp 2f
  20.391 +1:      /* obtain ss/esp from oldss/oldesp -- a ring-1 activation exists */
  20.392 +        movl OLDESP+4(%esp),%esi
  20.393 +FAULT9: movl OLDSS+4(%esp),%ds 
  20.394 +2:      /* Construct a stack frame: EFLAGS, CS/EIP */
  20.395 +        subl $12,%esi
  20.396 +        movl EIP+4(%esp),%eax
  20.397 +FAULT10:movl %eax,(%esi) 
  20.398 +        movl CS+4(%esp),%eax
  20.399 +FAULT11:movl %eax,4(%esi) 
  20.400 +        movl EFLAGS+4(%esp),%eax
  20.401 +FAULT12:movl %eax,8(%esi)
  20.402 +        /* Rewrite our stack frame and return to ring 1. */
  20.403 +        /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
  20.404 +        andl $0xfffcbeff,%eax
  20.405 +        movl %eax,EFLAGS+4(%esp)
  20.406 +        movl %ds,OLDSS+4(%esp)
  20.407 +        movl %esi,OLDESP+4(%esp)
  20.408 +        movzwl %es:GTB_CS(%edx),%eax
  20.409 +        movl %eax,CS+4(%esp)
  20.410 +        movl %es:GTB_EIP(%edx),%eax
  20.411 +        movl %eax,EIP+4(%esp)
  20.412 +        ret
  20.413 +        
  20.414 +                              
  20.415 +.section __ex_table,"a"
  20.416 +        .align 4
  20.417 +        .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack
  20.418 +        .long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack
  20.419 +        .long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack
  20.420 +        .long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack
  20.421 +        .long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret
  20.422 +        .long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector
  20.423 +        .long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack
  20.424 +        .long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack
  20.425 +        .long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector
  20.426 +        .long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack
  20.427 +        .long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack
  20.428 +        .long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack
  20.429 +        .long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack
  20.430 +        .long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack
  20.431 +.previous
  20.432 +               
  20.433 +# This handler kills domains which experience unrecoverable faults.
  20.434 +.section .fixup,"ax"
  20.435 +crash_domain_fixup1:
  20.436 +        subl  $4,%esp
  20.437 +        SAVE_ALL
  20.438 +        jmp   domain_crash
  20.439 +crash_domain_fixup2:
  20.440 +        addl  $4,%esp                     
  20.441 +crash_domain_fixup3:
  20.442 +        pushl %ss
  20.443 +        popl  %ds
  20.444 +        jmp   domain_crash
  20.445 +.previous
  20.446 +
  20.447 +        ALIGN
  20.448 +process_guest_exception_and_events:        
  20.449 +        movl PROCESSOR(%ebx),%eax
  20.450 +        shl  $4,%eax
  20.451 +        lea  guest_trap_bounce(%eax),%edx
  20.452 +        testb $~0,GTB_FLAGS(%edx)
  20.453 +        jz   test_all_events
  20.454 +        call create_bounce_frame        # just the basic frame
  20.455 +        mov  %es:GTB_FLAGS(%edx),%cl
  20.456 +        test $GTBF_TRAP_NOCODE,%cl
  20.457 +        jnz  2f
  20.458 +        subl $4,%esi                    # push error_code onto guest frame
  20.459 +        movl %es:GTB_ERROR_CODE(%edx),%eax
  20.460 +FAULT13:movl %eax,(%esi)
  20.461 +        test $GTBF_TRAP_CR2,%cl
  20.462 +        jz   1f
  20.463 +        subl $4,%esi                    # push %cr2 onto guest frame
  20.464 +        movl %es:GTB_CR2(%edx),%eax
  20.465 +FAULT14:movl %eax,(%esi)
  20.466 +1:      movl %esi,OLDESP(%esp)        
  20.467 +2:      push %es                        # unclobber %ds
  20.468 +        pop  %ds 
  20.469 +        movb $0,GTB_FLAGS(%edx)
  20.470 +        jmp  test_all_events
  20.471 +
  20.472 +        ALIGN
  20.473 +ENTRY(ret_from_intr)
  20.474 +	GET_CURRENT(%ebx)
  20.475 +        movb CS(%esp),%al
  20.476 +	testb $3,%al	# return to non-supervisor?
  20.477 +	jne test_all_events
  20.478 +	jmp restore_all_xen
  20.479 +
  20.480 +ENTRY(divide_error)
  20.481 +	pushl $0		# no error code
  20.482 +	pushl $ SYMBOL_NAME(do_divide_error)
  20.483 +	ALIGN
  20.484 +error_code:
  20.485 +	pushl %fs
  20.486 +	pushl %es
  20.487 +	pushl %ds
  20.488 +	pushl %eax
  20.489 +	xorl  %eax,%eax
  20.490 +	pushl %ebp
  20.491 +	pushl %edi
  20.492 +	pushl %esi
  20.493 +	pushl %edx
  20.494 +	decl  %eax			# eax = -1
  20.495 +	pushl %ecx
  20.496 +	pushl %ebx
  20.497 +	cld
  20.498 +	movl  %gs,%ecx
  20.499 +	movl  ORIG_EAX(%esp), %esi	# get the error code
  20.500 +	movl  GS(%esp), %edi		# get the function address
  20.501 +	movl  %eax, ORIG_EAX(%esp)
  20.502 +	movl  %ecx, GS(%esp)
  20.503 +	movl  $(__HYPERVISOR_DS),%edx
  20.504 +	movl  %edx,%ds
  20.505 +	movl  %edx,%es
  20.506 +	movl  %edx,%fs
  20.507 +	movl  %edx,%gs
  20.508 +	movl  %esp,%edx
  20.509 +	pushl %esi			# push the error code
  20.510 +	pushl %edx			# push the pt_regs pointer
  20.511 +	GET_CURRENT(%ebx)
  20.512 +	call  *%edi
  20.513 +        addl  $8,%esp
  20.514 +        movb  CS(%esp),%al
  20.515 +	testb $3,%al
  20.516 +	je    restore_all_xen
  20.517 +        jmp   process_guest_exception_and_events
  20.518 +
  20.519 +ENTRY(coprocessor_error)
  20.520 +	pushl $0
  20.521 +	pushl $ SYMBOL_NAME(do_coprocessor_error)
  20.522 +	jmp error_code
  20.523 +
  20.524 +ENTRY(simd_coprocessor_error)
  20.525 +	pushl $0
  20.526 +	pushl $ SYMBOL_NAME(do_simd_coprocessor_error)
  20.527 +	jmp error_code
  20.528 +
  20.529 +ENTRY(device_not_available)
  20.530 +	pushl $0
  20.531 +        pushl $SYMBOL_NAME(math_state_restore)
  20.532 +        jmp   error_code
  20.533 +
  20.534 +ENTRY(debug)
  20.535 +	pushl $0
  20.536 +	pushl $ SYMBOL_NAME(do_debug)
  20.537 +	jmp error_code
  20.538 +
  20.539 +ENTRY(int3)
  20.540 +	pushl $0
  20.541 +	pushl $ SYMBOL_NAME(do_int3)
  20.542 +	jmp error_code
  20.543 +
  20.544 +ENTRY(overflow)
  20.545 +	pushl $0
  20.546 +	pushl $ SYMBOL_NAME(do_overflow)
  20.547 +	jmp error_code
  20.548 +
  20.549 +ENTRY(bounds)
  20.550 +	pushl $0
  20.551 +	pushl $ SYMBOL_NAME(do_bounds)
  20.552 +	jmp error_code
  20.553 +
  20.554 +ENTRY(invalid_op)
  20.555 +	pushl $0
  20.556 +	pushl $ SYMBOL_NAME(do_invalid_op)
  20.557 +	jmp error_code
  20.558 +
  20.559 +ENTRY(coprocessor_segment_overrun)
  20.560 +	pushl $0
  20.561 +	pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
  20.562 +	jmp error_code
  20.563 +
  20.564 +ENTRY(invalid_TSS)
  20.565 +	pushl $ SYMBOL_NAME(do_invalid_TSS)
  20.566 +	jmp error_code
  20.567 +
  20.568 +ENTRY(segment_not_present)
  20.569 +	pushl $ SYMBOL_NAME(do_segment_not_present)
  20.570 +	jmp error_code
  20.571 +
  20.572 +ENTRY(stack_segment)
  20.573 +	pushl $ SYMBOL_NAME(do_stack_segment)
  20.574 +	jmp error_code
  20.575 +
  20.576 +ENTRY(general_protection)
  20.577 +	pushl $ SYMBOL_NAME(do_general_protection)
  20.578 +	jmp error_code
  20.579 +
  20.580 +ENTRY(alignment_check)
  20.581 +	pushl $ SYMBOL_NAME(do_alignment_check)
  20.582 +	jmp error_code
  20.583 +
  20.584 +ENTRY(page_fault)
  20.585 +	pushl $ SYMBOL_NAME(do_page_fault)
  20.586 +	jmp error_code
  20.587 +
  20.588 +ENTRY(machine_check)
  20.589 +	pushl $0
  20.590 +	pushl $ SYMBOL_NAME(do_machine_check)
  20.591 +	jmp error_code
  20.592 +
  20.593 +ENTRY(spurious_interrupt_bug)
  20.594 +	pushl $0
  20.595 +	pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
  20.596 +	jmp error_code
  20.597 +
  20.598 +ENTRY(nmi)
  20.599 +        # Save state but do not trash the segment registers!
  20.600 +        # We may otherwise be unable to reload them or copy them to ring 1. 
  20.601 +	pushl %eax
  20.602 +	SAVE_ALL_NOSEGREGS
  20.603 +
  20.604 +        # Check for hardware problems. These are always fatal so we can
  20.605 +        # reload DS and ES when handling them.
  20.606 +        inb   $0x61,%al
  20.607 +        testb $0x80,%al
  20.608 +        jne   nmi_parity_err
  20.609 +        testb $0x40,%al
  20.610 +        jne   nmi_io_err
  20.611 +        movl  %eax,%ebx
  20.612 +        
  20.613 +        # Okay, its almost a normal NMI tick. We can only process it if:
  20.614 +        #  A. We are the outermost Xen activation (in which case we have
  20.615 +        #     the selectors safely saved on our stack)
  20.616 +        #  B. DS-GS all contain sane Xen values.
  20.617 +        # In all other cases we bail without touching DS-GS, as we have
  20.618 +        # interrupted an enclosing Xen activation in tricky prologue or
  20.619 +        # epilogue code.
  20.620 +        movb  CS(%esp),%al
  20.621 +	testb $3,%al
  20.622 +        jne   do_watchdog_tick
  20.623 +        movl  DS(%esp),%eax
  20.624 +        cmpw  $(__HYPERVISOR_DS),%ax
  20.625 +        jne   nmi_badseg
  20.626 +        movl  ES(%esp),%eax
  20.627 +        cmpw  $(__HYPERVISOR_DS),%ax
  20.628 +        jne   nmi_badseg
  20.629 +        movl  FS(%esp),%eax
  20.630 +        cmpw  $(__HYPERVISOR_DS),%ax
  20.631 +        jne   nmi_badseg
  20.632 +        movl  GS(%esp),%eax
  20.633 +        cmpw  $(__HYPERVISOR_DS),%ax
  20.634 +        jne   nmi_badseg
  20.635 +
  20.636 +do_watchdog_tick:
  20.637 +        movl  $(__HYPERVISOR_DS),%edx
  20.638 +        movl  %edx,%ds
  20.639 +        movl  %edx,%es
  20.640 +        movl  %esp,%edx
  20.641 +	pushl %ebx   # reason
  20.642 +	pushl %edx   # regs
  20.643 +        call  SYMBOL_NAME(do_nmi)
  20.644 +	addl  $8,%esp
  20.645 +        movb  CS(%esp),%al
  20.646 +	testb $3,%al
  20.647 +	je    restore_all_xen
  20.648 +        GET_CURRENT(%ebx)
  20.649 +        jmp   restore_all_guest
  20.650 +
  20.651 +nmi_badseg:
  20.652 +	popl %ebx
  20.653 +	popl %ecx
  20.654 +	popl %edx
  20.655 +	popl %esi
  20.656 +	popl %edi
  20.657 +	popl %ebp
  20.658 +	popl %eax
  20.659 +        addl $20,%esp
  20.660 +        iret
  20.661 +
  20.662 +nmi_parity_err: 
  20.663 +        movl $(__HYPERVISOR_DS),%edx
  20.664 +        movl %edx,%ds
  20.665 +        movl %edx,%es
  20.666 +        jmp  SYMBOL_NAME(mem_parity_error)
  20.667 +        
  20.668 +nmi_io_err: 
  20.669 +        movl $(__HYPERVISOR_DS),%edx
  20.670 +        movl %edx,%ds
  20.671 +        movl %edx,%es
  20.672 +        jmp  SYMBOL_NAME(io_check_error)                        
  20.673 +        
  20.674 +.data
  20.675 +ENTRY(hypercall_table)
  20.676 +        .long SYMBOL_NAME(do_set_trap_table)     /*  0 */
  20.677 +        .long SYMBOL_NAME(do_mmu_update)
  20.678 +        .long SYMBOL_NAME(do_set_gdt)
  20.679 +        .long SYMBOL_NAME(do_stack_switch)
  20.680 +        .long SYMBOL_NAME(do_set_callbacks)
  20.681 +        .long SYMBOL_NAME(do_fpu_taskswitch)     /*  5 */
  20.682 +        .long SYMBOL_NAME(do_sched_op)
  20.683 +        .long SYMBOL_NAME(do_dom0_op)
  20.684 +        .long SYMBOL_NAME(do_set_debugreg)
  20.685 +        .long SYMBOL_NAME(do_get_debugreg)
  20.686 +        .long SYMBOL_NAME(do_update_descriptor)  /* 10 */
  20.687 +        .long SYMBOL_NAME(do_set_fast_trap)
  20.688 +        .long SYMBOL_NAME(do_dom_mem_op)
  20.689 +        .long SYMBOL_NAME(do_multicall)
  20.690 +        .long SYMBOL_NAME(do_update_va_mapping)
  20.691 +        .long SYMBOL_NAME(do_set_timer_op)       /* 15 */
  20.692 +        .long SYMBOL_NAME(do_event_channel_op)
  20.693 +        .long SYMBOL_NAME(do_xen_version)
  20.694 +        .long SYMBOL_NAME(do_console_io)
  20.695 +        .long SYMBOL_NAME(do_physdev_op)
  20.696 +        .long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 20 */
  20.697 +        .rept NR_hypercalls-((.-hypercall_table)/4)
  20.698 +        .long SYMBOL_NAME(do_ni_hypercall)
  20.699 +        .endr
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/xen/arch/x86/x86_32/mm.c	Mon Jul 05 20:15:38 2004 +0000
    21.3 @@ -0,0 +1,412 @@
    21.4 +/******************************************************************************
    21.5 + * arch/i386/mm.c
    21.6 + * 
    21.7 + * Modifications to Linux original are copyright (c) 2002-2003, K A Fraser
    21.8 + * 
    21.9 + * This program is free software; you can redistribute it and/or modify
   21.10 + * it under the terms of the GNU General Public License as published by
   21.11 + * the Free Software Foundation; either version 2 of the License, or
   21.12 + * (at your option) any later version.
   21.13 + * 
   21.14 + * This program is distributed in the hope that it will be useful,
   21.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.17 + * GNU General Public License for more details.
   21.18 + * 
   21.19 + * You should have received a copy of the GNU General Public License
   21.20 + * along with this program; if not, write to the Free Software
   21.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.22 + */
   21.23 +
   21.24 +#include <xen/config.h>
   21.25 +#include <xen/lib.h>
   21.26 +#include <xen/init.h>
   21.27 +#include <xen/mm.h>
   21.28 +#include <asm/page.h>
   21.29 +#include <asm/flushtlb.h>
   21.30 +#include <asm/fixmap.h>
   21.31 +#include <asm/domain_page.h>
   21.32 +
   21.33 +static inline void set_pte_phys(unsigned long vaddr,
   21.34 +                                l1_pgentry_t entry)
   21.35 +{
   21.36 +    l2_pgentry_t *l2ent;
   21.37 +    l1_pgentry_t *l1ent;
   21.38 +
   21.39 +    l2ent = &idle_pg_table[l2_table_offset(vaddr)];
   21.40 +    l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr);
   21.41 +    *l1ent = entry;
   21.42 +
   21.43 +    /* It's enough to flush this one mapping. */
   21.44 +    __flush_tlb_one(vaddr);
   21.45 +}
   21.46 +
   21.47 +
   21.48 +void __set_fixmap(enum fixed_addresses idx, 
   21.49 +                  l1_pgentry_t entry)
   21.50 +{
   21.51 +    unsigned long address = fix_to_virt(idx);
   21.52 +
   21.53 +    if ( likely(idx < __end_of_fixed_addresses) )
   21.54 +        set_pte_phys(address, entry);
   21.55 +    else
   21.56 +        printk("Invalid __set_fixmap\n");
   21.57 +}
   21.58 +
   21.59 +
   21.60 +static void __init fixrange_init(unsigned long start, 
   21.61 +                                 unsigned long end, 
   21.62 +                                 l2_pgentry_t *pg_base)
   21.63 +{
   21.64 +    l2_pgentry_t *l2e;
   21.65 +    int i;
   21.66 +    unsigned long vaddr, page;
   21.67 +
   21.68 +    vaddr = start;
   21.69 +    i = l2_table_offset(vaddr);
   21.70 +    l2e = pg_base + i;
   21.71 +
   21.72 +    for ( ; (i < ENTRIES_PER_L2_PAGETABLE) && (vaddr != end); l2e++, i++ ) 
   21.73 +    {
   21.74 +        if ( !l2_pgentry_empty(*l2e) )
   21.75 +            continue;
   21.76 +        page = (unsigned long)get_free_page();
   21.77 +        clear_page(page);
   21.78 +        *l2e = mk_l2_pgentry(__pa(page) | __PAGE_HYPERVISOR);
   21.79 +        vaddr += 1 << L2_PAGETABLE_SHIFT;
   21.80 +    }
   21.81 +}
   21.82 +
   21.83 +void __init paging_init(void)
   21.84 +{
   21.85 +    unsigned long addr;
   21.86 +    void *ioremap_pt;
   21.87 +    int i;
   21.88 +
   21.89 +    /* Idle page table 1:1 maps the first part of physical memory. */
   21.90 +    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
   21.91 +        idle_pg_table[i] = 
   21.92 +            mk_l2_pgentry((i << L2_PAGETABLE_SHIFT) | 
   21.93 +                          __PAGE_HYPERVISOR | _PAGE_PSE);
   21.94 +
   21.95 +    /*
   21.96 +     * Fixed mappings, only the page table structure has to be
   21.97 +     * created - mappings will be set by set_fixmap():
   21.98 +     */
   21.99 +    addr = FIXADDR_START & ~((1<<L2_PAGETABLE_SHIFT)-1);
  21.100 +    fixrange_init(addr, 0, idle_pg_table);
  21.101 +
  21.102 +    /* Create page table for ioremap(). */
  21.103 +    ioremap_pt = (void *)get_free_page();
  21.104 +    clear_page(ioremap_pt);
  21.105 +    idle_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] = 
  21.106 +        mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR);
  21.107 +
  21.108 +    /* Create read-only mapping of MPT for guest-OS use. */
  21.109 +    idle_pg_table[RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
  21.110 +        idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT];
  21.111 +    mk_l2_readonly(idle_pg_table + 
  21.112 +                   (RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT));
  21.113 +
  21.114 +    /* Set up mapping cache for domain pages. */
  21.115 +    mapcache = (unsigned long *)get_free_page();
  21.116 +    clear_page(mapcache);
  21.117 +    idle_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] =
  21.118 +        mk_l2_pgentry(__pa(mapcache) | __PAGE_HYPERVISOR);
  21.119 +
  21.120 +    /* Set up linear page table mapping. */
  21.121 +    idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
  21.122 +        mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR);
  21.123 +
  21.124 +}
  21.125 +
  21.126 +void __init zap_low_mappings(void)
  21.127 +{
  21.128 +    int i;
  21.129 +    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
  21.130 +        idle_pg_table[i] = mk_l2_pgentry(0);
  21.131 +    flush_tlb_all_pge();
  21.132 +}
  21.133 +
  21.134 +
  21.135 +long do_stack_switch(unsigned long ss, unsigned long esp)
  21.136 +{
  21.137 +    int nr = smp_processor_id();
  21.138 +    struct tss_struct *t = &init_tss[nr];
  21.139 +
  21.140 +    /* We need to do this check as we load and use SS on guest's behalf. */
  21.141 +    if ( (ss & 3) == 0 )
  21.142 +        return -EPERM;
  21.143 +
  21.144 +    current->thread.guestos_ss = ss;
  21.145 +    current->thread.guestos_sp = esp;
  21.146 +    t->ss1  = ss;
  21.147 +    t->esp1 = esp;
  21.148 +
  21.149 +    return 0;
  21.150 +}
  21.151 +
  21.152 +
  21.153 +/* Returns TRUE if given descriptor is valid for GDT or LDT. */
  21.154 +int check_descriptor(unsigned long a, unsigned long b)
  21.155 +{
  21.156 +    unsigned long base, limit;
  21.157 +
  21.158 +    /* A not-present descriptor will always fault, so is safe. */
  21.159 +    if ( !(b & _SEGMENT_P) ) 
  21.160 +        goto good;
  21.161 +
  21.162 +    /*
  21.163 +     * We don't allow a DPL of zero. There is no legitimate reason for 
  21.164 +     * specifying DPL==0, and it gets rather dangerous if we also accept call 
  21.165 +     * gates (consider a call gate pointing at another guestos descriptor with 
  21.166 +     * DPL 0 -- this would get the OS ring-0 privileges).
  21.167 +     */
  21.168 +    if ( (b & _SEGMENT_DPL) == 0 )
  21.169 +        goto bad;
  21.170 +
  21.171 +    if ( !(b & _SEGMENT_S) )
  21.172 +    {
  21.173 +        /*
  21.174 +         * System segment:
  21.175 +         *  1. Don't allow interrupt or trap gates as they belong in the IDT.
  21.176 +         *  2. Don't allow TSS descriptors or task gates as we don't
  21.177 +         *     virtualise x86 tasks.
  21.178 +         *  3. Don't allow LDT descriptors because they're unnecessary and
  21.179 +         *     I'm uneasy about allowing an LDT page to contain LDT
  21.180 +         *     descriptors. In any case, Xen automatically creates the
  21.181 +         *     required descriptor when reloading the LDT register.
  21.182 +         *  4. We allow call gates but they must not jump to a private segment.
  21.183 +         */
  21.184 +
  21.185 +        /* Disallow everything but call gates. */
  21.186 +        if ( (b & _SEGMENT_TYPE) != 0xc00 )
  21.187 +            goto bad;
  21.188 +
  21.189 +        /* Can't allow far jump to a Xen-private segment. */
  21.190 +        if ( !VALID_CODESEL(a>>16) )
  21.191 +            goto bad;
  21.192 +
  21.193 +        /* Reserved bits must be zero. */
  21.194 +        if ( (b & 0xe0) != 0 )
  21.195 +            goto bad;
  21.196 +        
  21.197 +        /* No base/limit check is needed for a call gate. */
  21.198 +        goto good;
  21.199 +    }
  21.200 +    
  21.201 +    /* Check that base/limit do not overlap Xen-private space. */
  21.202 +    base  = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16);
  21.203 +    limit = (b&0xf0000) | (a&0xffff);
  21.204 +    limit++; /* We add one because limit is inclusive. */
  21.205 +    if ( (b & _SEGMENT_G) )
  21.206 +        limit <<= 12;
  21.207 +    if ( ((base + limit) <= base) || 
  21.208 +         ((base + limit) > PAGE_OFFSET) )
  21.209 +        goto bad;
  21.210 +
  21.211 + good:
  21.212 +    return 1;
  21.213 + bad:
  21.214 +    return 0;
  21.215 +}
  21.216 +
  21.217 +
  21.218 +long set_gdt(struct domain *p, 
  21.219 +             unsigned long *frames,
  21.220 +             unsigned int entries)
  21.221 +{
  21.222 +    /* NB. There are 512 8-byte entries per GDT page. */
  21.223 +    int i, nr_pages = (entries + 511) / 512;
  21.224 +    unsigned long pfn;
  21.225 +    struct desc_struct *vgdt;
  21.226 +
  21.227 +    /* Check the new GDT. */
  21.228 +    for ( i = 0; i < nr_pages; i++ )
  21.229 +    {
  21.230 +        if ( unlikely(frames[i] >= max_page) ||
  21.231 +             unlikely(!get_page_and_type(&frame_table[frames[i]], 
  21.232 +                                         p, PGT_gdt_page)) )
  21.233 +            goto fail;
  21.234 +    }
  21.235 +
  21.236 +    /* Copy reserved GDT entries to the new GDT. */
  21.237 +    vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
  21.238 +    memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, 
  21.239 +           gdt_table + FIRST_RESERVED_GDT_ENTRY, 
  21.240 +           NR_RESERVED_GDT_ENTRIES*8);
  21.241 +    unmap_domain_mem(vgdt);
  21.242 +
  21.243 +    /* Tear down the old GDT. */
  21.244 +    for ( i = 0; i < 16; i++ )
  21.245 +    {
  21.246 +        if ( (pfn = l1_pgentry_to_pagenr(p->mm.perdomain_pt[i])) != 0 )
  21.247 +            put_page_and_type(&frame_table[pfn]);
  21.248 +        p->mm.perdomain_pt[i] = mk_l1_pgentry(0);
  21.249 +    }
  21.250 +
  21.251 +    /* Install the new GDT. */
  21.252 +    for ( i = 0; i < nr_pages; i++ )
  21.253 +        p->mm.perdomain_pt[i] =
  21.254 +            mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  21.255 +
  21.256 +    SET_GDT_ADDRESS(p, GDT_VIRT_START);
  21.257 +    SET_GDT_ENTRIES(p, (entries*8)-1);
  21.258 +
  21.259 +    return 0;
  21.260 +
  21.261 + fail:
  21.262 +    while ( i-- > 0 )
  21.263 +        put_page_and_type(&frame_table[frames[i]]);
  21.264 +    return -EINVAL;
  21.265 +}
  21.266 +
  21.267 +
  21.268 +long do_set_gdt(unsigned long *frame_list, unsigned int entries)
  21.269 +{
  21.270 +    int nr_pages = (entries + 511) / 512;
  21.271 +    unsigned long frames[16];
  21.272 +    long ret;
  21.273 +
  21.274 +    if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) ) 
  21.275 +        return -EINVAL;
  21.276 +    
  21.277 +    if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
  21.278 +        return -EFAULT;
  21.279 +
  21.280 +    if ( (ret = set_gdt(current, frames, entries)) == 0 )
  21.281 +    {
  21.282 +        local_flush_tlb();
  21.283 +        __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt));
  21.284 +    }
  21.285 +
  21.286 +    return ret;
  21.287 +}
  21.288 +
  21.289 +
  21.290 +long do_update_descriptor(
  21.291 +    unsigned long pa, unsigned long word1, unsigned long word2)
  21.292 +{
  21.293 +    unsigned long *gdt_pent, pfn = pa >> PAGE_SHIFT;
  21.294 +    struct pfn_info *page;
  21.295 +    long ret = -EINVAL;
  21.296 +
  21.297 +    if ( (pa & 7) || (pfn >= max_page) || !check_descriptor(word1, word2) )
  21.298 +        return -EINVAL;
  21.299 +
  21.300 +    page = &frame_table[pfn];
  21.301 +    if ( unlikely(!get_page(page, current)) )
  21.302 +        goto out;
  21.303 +
  21.304 +    /* Check if the given frame is in use in an unsafe context. */
  21.305 +    switch ( page->type_and_flags & PGT_type_mask )
  21.306 +    {
  21.307 +    case PGT_gdt_page:
  21.308 +        /* Disallow updates of Xen-reserved descriptors in the current GDT. */
  21.309 +        if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) &&
  21.310 +             (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) &&
  21.311 +             (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) )
  21.312 +            goto out;
  21.313 +        if ( unlikely(!get_page_type(page, PGT_gdt_page)) )
  21.314 +            goto out;
  21.315 +        break;
  21.316 +    case PGT_ldt_page:
  21.317 +        if ( unlikely(!get_page_type(page, PGT_ldt_page)) )
  21.318 +            goto out;
  21.319 +        break;
  21.320 +    default:
  21.321 +        if ( unlikely(!get_page_type(page, PGT_writeable_page)) )
  21.322 +            goto out;
  21.323 +        break;
  21.324 +    }
  21.325 +
  21.326 +    /* All is good so make the update. */
  21.327 +    gdt_pent = map_domain_mem(pa);
  21.328 +    gdt_pent[0] = word1;
  21.329 +    gdt_pent[1] = word2;
  21.330 +    unmap_domain_mem(gdt_pent);
  21.331 +
  21.332 +    put_page_type(page);
  21.333 +
  21.334 +    ret = 0; /* success */
  21.335 +
  21.336 + out:
  21.337 +    put_page(page);
  21.338 +    return ret;
  21.339 +}
  21.340 +
  21.341 +#ifdef MEMORY_GUARD
  21.342 +
  21.343 +void *memguard_init(void *heap_start)
  21.344 +{
  21.345 +    l1_pgentry_t *l1;
  21.346 +    int i, j;
  21.347 +
  21.348 +    /* Round the allocation pointer up to a page boundary. */
  21.349 +    heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) & 
  21.350 +                          PAGE_MASK);
  21.351 +
  21.352 +    /* Memory guarding is incompatible with super pages. */
  21.353 +    for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
  21.354 +    {
  21.355 +        l1 = (l1_pgentry_t *)heap_start;
  21.356 +        heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
  21.357 +        for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ )
  21.358 +            l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) |
  21.359 +                                   (j << L1_PAGETABLE_SHIFT) | 
  21.360 +                                  __PAGE_HYPERVISOR);
  21.361 +        idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] =
  21.362 +            mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR);
  21.363 +    }
  21.364 +
  21.365 +    return heap_start;
  21.366 +}
  21.367 +
  21.368 +static void __memguard_change_range(void *p, unsigned long l, int guard)
  21.369 +{
  21.370 +    l1_pgentry_t *l1;
  21.371 +    l2_pgentry_t *l2;
  21.372 +    unsigned long _p = (unsigned long)p;
  21.373 +    unsigned long _l = (unsigned long)l;
  21.374 +
  21.375 +    /* Ensure we are dealing with a page-aligned whole number of pages. */
  21.376 +    ASSERT((_p&PAGE_MASK) != 0);
  21.377 +    ASSERT((_l&PAGE_MASK) != 0);
  21.378 +    ASSERT((_p&~PAGE_MASK) == 0);
  21.379 +    ASSERT((_l&~PAGE_MASK) == 0);
  21.380 +
  21.381 +    while ( _l != 0 )
  21.382 +    {
  21.383 +        l2  = &idle_pg_table[l2_table_offset(_p)];
  21.384 +        l1  = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
  21.385 +        if ( guard )
  21.386 +            *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT);
  21.387 +        else
  21.388 +            *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) | _PAGE_PRESENT);
  21.389 +        _p += PAGE_SIZE;
  21.390 +        _l -= PAGE_SIZE;
  21.391 +    }
  21.392 +}
  21.393 +
  21.394 +void memguard_guard_range(void *p, unsigned long l)
  21.395 +{
  21.396 +    __memguard_change_range(p, l, 1);
  21.397 +    local_flush_tlb();
  21.398 +}
  21.399 +
  21.400 +void memguard_unguard_range(void *p, unsigned long l)
  21.401 +{
  21.402 +    __memguard_change_range(p, l, 0);
  21.403 +}
  21.404 +
  21.405 +int memguard_is_guarded(void *p)
  21.406 +{
  21.407 +    l1_pgentry_t *l1;
  21.408 +    l2_pgentry_t *l2;
  21.409 +    unsigned long _p = (unsigned long)p;
  21.410 +    l2  = &idle_pg_table[l2_table_offset(_p)];
  21.411 +    l1  = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
  21.412 +    return !(l1_pgentry_val(*l1) & _PAGE_PRESENT);
  21.413 +}
  21.414 +
  21.415 +#endif
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/xen/arch/x86/x86_32/usercopy.c	Mon Jul 05 20:15:38 2004 +0000
    22.3 @@ -0,0 +1,190 @@
    22.4 +/* 
    22.5 + * User address space access functions.
    22.6 + * The non inlined parts of asm-i386/uaccess.h are here.
    22.7 + *
    22.8 + * Copyright 1997 Andi Kleen <ak@muc.de>
    22.9 + * Copyright 1997 Linus Torvalds
   22.10 + */
   22.11 +#include <xen/config.h>
   22.12 +#include <asm/uaccess.h>
   22.13 +//#include <asm/mmx.h>
   22.14 +
   22.15 +#ifdef CONFIG_X86_USE_3DNOW_AND_WORKS
   22.16 +
   22.17 +unsigned long
   22.18 +__generic_copy_to_user(void *to, const void *from, unsigned long n)
   22.19 +{
   22.20 +	if (access_ok(VERIFY_WRITE, to, n))
   22.21 +	{
   22.22 +		if(n<512)
   22.23 +			__copy_user(to,from,n);
   22.24 +		else
   22.25 +			mmx_copy_user(to,from,n);
   22.26 +	}
   22.27 +	return n;
   22.28 +}
   22.29 +
   22.30 +unsigned long
   22.31 +__generic_copy_from_user(void *to, const void *from, unsigned long n)
   22.32 +{
   22.33 +	if (access_ok(VERIFY_READ, from, n))
   22.34 +	{
   22.35 +		if(n<512)
   22.36 +			__copy_user_zeroing(to,from,n);
   22.37 +		else
   22.38 +			mmx_copy_user_zeroing(to, from, n);
   22.39 +	}
   22.40 +	else
   22.41 +		memset(to, 0, n);
   22.42 +	return n;
   22.43 +}
   22.44 +
   22.45 +#else
   22.46 +
   22.47 +unsigned long
   22.48 +__generic_copy_to_user(void *to, const void *from, unsigned long n)
   22.49 +{
   22.50 +	prefetch(from);
   22.51 +	if (access_ok(VERIFY_WRITE, to, n))
   22.52 +		__copy_user(to,from,n);
   22.53 +	return n;
   22.54 +}
   22.55 +
   22.56 +unsigned long
   22.57 +__generic_copy_from_user(void *to, const void *from, unsigned long n)
   22.58 +{
   22.59 +	prefetchw(to);
   22.60 +	if (access_ok(VERIFY_READ, from, n))
   22.61 +		__copy_user_zeroing(to,from,n);
   22.62 +	else
   22.63 +		memset(to, 0, n);
   22.64 +	return n;
   22.65 +}
   22.66 +
   22.67 +#endif
   22.68 +
   22.69 +/*
   22.70 + * Copy a null terminated string from userspace.
   22.71 + */
   22.72 +
   22.73 +#define __do_strncpy_from_user(dst,src,count,res)			   \
   22.74 +do {									   \
   22.75 +	int __d0, __d1, __d2;						   \
   22.76 +	__asm__ __volatile__(						   \
   22.77 +		"	testl %1,%1\n"					   \
   22.78 +		"	jz 2f\n"					   \
   22.79 +		"0:	lodsb\n"					   \
   22.80 +		"	stosb\n"					   \
   22.81 +		"	testb %%al,%%al\n"				   \
   22.82 +		"	jz 1f\n"					   \
   22.83 +		"	decl %1\n"					   \
   22.84 +		"	jnz 0b\n"					   \
   22.85 +		"1:	subl %1,%0\n"					   \
   22.86 +		"2:\n"							   \
   22.87 +		".section .fixup,\"ax\"\n"				   \
   22.88 +		"3:	movl %5,%0\n"					   \
   22.89 +		"	jmp 2b\n"					   \
   22.90 +		".previous\n"						   \
   22.91 +		".section __ex_table,\"a\"\n"				   \
   22.92 +		"	.align 4\n"					   \
   22.93 +		"	.long 0b,3b\n"					   \
   22.94 +		".previous"						   \
   22.95 +		: "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),	   \
   22.96 +		  "=&D" (__d2)						   \
   22.97 +		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
   22.98 +		: "memory");						   \
   22.99 +} while (0)
  22.100 +
  22.101 +long
  22.102 +__strncpy_from_user(char *dst, const char *src, long count)
  22.103 +{
  22.104 +	long res;
  22.105 +	__do_strncpy_from_user(dst, src, count, res);
  22.106 +	return res;
  22.107 +}
  22.108 +
  22.109 +long
  22.110 +strncpy_from_user(char *dst, const char *src, long count)
  22.111 +{
  22.112 +	long res = -EFAULT;
  22.113 +	if (access_ok(VERIFY_READ, src, 1))
  22.114 +		__do_strncpy_from_user(dst, src, count, res);
  22.115 +	return res;
  22.116 +}
  22.117 +
  22.118 +
  22.119 +/*
  22.120 + * Zero Userspace
  22.121 + */
  22.122 +
  22.123 +#define __do_clear_user(addr,size)					\
  22.124 +do {									\
  22.125 +	int __d0;							\
  22.126 +  	__asm__ __volatile__(						\
  22.127 +		"0:	rep; stosl\n"					\
  22.128 +		"	movl %2,%0\n"					\
  22.129 +		"1:	rep; stosb\n"					\
  22.130 +		"2:\n"							\
  22.131 +		".section .fixup,\"ax\"\n"				\
  22.132 +		"3:	lea 0(%2,%0,4),%0\n"				\
  22.133 +		"	jmp 2b\n"					\
  22.134 +		".previous\n"						\
  22.135 +		".section __ex_table,\"a\"\n"				\
  22.136 +		"	.align 4\n"					\
  22.137 +		"	.long 0b,3b\n"					\
  22.138 +		"	.long 1b,2b\n"					\
  22.139 +		".previous"						\
  22.140 +		: "=&c"(size), "=&D" (__d0)				\
  22.141 +		: "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));	\
  22.142 +} while (0)
  22.143 +
  22.144 +unsigned long
  22.145 +clear_user(void *to, unsigned long n)
  22.146 +{
  22.147 +	if (access_ok(VERIFY_WRITE, to, n))
  22.148 +		__do_clear_user(to, n);
  22.149 +	return n;
  22.150 +}
  22.151 +
  22.152 +unsigned long
  22.153 +__clear_user(void *to, unsigned long n)
  22.154 +{
  22.155 +	__do_clear_user(to, n);
  22.156 +	return n;
  22.157 +}
  22.158 +
  22.159 +/*
  22.160 + * Return the size of a string (including the ending 0)
  22.161 + *
  22.162 + * Return 0 on exception, a value greater than N if too long
  22.163 + */
  22.164 +
  22.165 +long strnlen_user(const char *s, long n)
  22.166 +{
  22.167 +	unsigned long mask = -__addr_ok(s);
  22.168 +	unsigned long res, tmp;
  22.169 +
  22.170 +	__asm__ __volatile__(
  22.171 +		"	testl %0, %0\n"
  22.172 +		"	jz 3f\n"
  22.173 +		"	andl %0,%%ecx\n"
  22.174 +		"0:	repne; scasb\n"
  22.175 +		"	setne %%al\n"
  22.176 +		"	subl %%ecx,%0\n"
  22.177 +		"	addl %0,%%eax\n"
  22.178 +		"1:\n"
  22.179 +		".section .fixup,\"ax\"\n"
  22.180 +		"2:	xorl %%eax,%%eax\n"
  22.181 +		"	jmp 1b\n"
  22.182 +		"3:	movb $1,%%al\n"
  22.183 +		"	jmp 1b\n"
  22.184 +		".previous\n"
  22.185 +		".section __ex_table,\"a\"\n"
  22.186 +		"	.align 4\n"
  22.187 +		"	.long 0b,2b\n"
  22.188 +		".previous"
  22.189 +		:"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
  22.190 +		:"0" (n), "1" (s), "2" (0), "3" (mask)
  22.191 +		:"cc");
  22.192 +	return res & mask;
  22.193 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/xen/arch/x86/x86_32/xen.lds	Mon Jul 05 20:15:38 2004 +0000
    23.3 @@ -0,0 +1,87 @@
    23.4 +/* ld script to make i386 Linux kernel
    23.5 + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
    23.6 + */
    23.7 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    23.8 +OUTPUT_ARCH(i386)
    23.9 +ENTRY(start)
   23.10 +SECTIONS
   23.11 +{
   23.12 +  . = 0xFC400000 + 0x100000;
   23.13 +  _text = .;			/* Text and read-only data */
   23.14 +  .text : {
   23.15 +	*(.text)
   23.16 +	*(.fixup)
   23.17 +	*(.gnu.warning)
   23.18 +	} = 0x9090
   23.19 +  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   23.20 +
   23.21 +  _etext = .;			/* End of text section */
   23.22 +
   23.23 +  .rodata : { *(.rodata) *(.rodata.*) }
   23.24 +  .kstrtab : { *(.kstrtab) }
   23.25 +
   23.26 +  . = ALIGN(16);		/* Exception table */
   23.27 +  __start___ex_table = .;
   23.28 +  __ex_table : { *(__ex_table) }
   23.29 +  __stop___ex_table = .;
   23.30 +
   23.31 +  __start___ksymtab = .;	/* Kernel symbol table */
   23.32 +  __ksymtab : { *(__ksymtab) }
   23.33 +  __stop___ksymtab = .;
   23.34 +
   23.35 +  __start___kallsyms = .;	/* All kernel symbols */
   23.36 +  __kallsyms : { *(__kallsyms) }
   23.37 +  __stop___kallsyms = .;
   23.38 +
   23.39 +  .data : {			/* Data */
   23.40 +	*(.data)
   23.41 +	CONSTRUCTORS
   23.42 +	}
   23.43 +
   23.44 +  _edata = .;			/* End of data section */
   23.45 +
   23.46 +  . = ALIGN(8192);		/* init_task */
   23.47 +  .data.init_task : { *(.data.init_task) }
   23.48 +
   23.49 +  . = ALIGN(4096);		/* Init code and data */
   23.50 +  __init_begin = .;
   23.51 +  .text.init : { *(.text.init) }
   23.52 +  .data.init : { *(.data.init) }
   23.53 +  . = ALIGN(16);
   23.54 +  __setup_start = .;
   23.55 +  .setup.init : { *(.setup.init) }
   23.56 +  __setup_end = .;
   23.57 +  __initcall_start = .;
   23.58 +  .initcall.init : { *(.initcall.init) }
   23.59 +  __initcall_end = .;
   23.60 +  . = ALIGN(4096);
   23.61 +  __init_end = .;
   23.62 +
   23.63 +  . = ALIGN(4096);
   23.64 +  .data.page_aligned : { *(.data.idt) }
   23.65 +
   23.66 +  . = ALIGN(32);
   23.67 +  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
   23.68 +
   23.69 +  __bss_start = .;		/* BSS */
   23.70 +  .bss : {
   23.71 +	*(.bss)
   23.72 +	}
   23.73 +  _end = . ;
   23.74 +
   23.75 +  /* Sections to be discarded */
   23.76 +  /DISCARD/ : {
   23.77 +	*(.text.exit)
   23.78 +	*(.data.exit)
   23.79 +	*(.exitcall.exit)
   23.80 +	}
   23.81 +
   23.82 +  /* Stabs debugging sections.  */
   23.83 +  .stab 0 : { *(.stab) }
   23.84 +  .stabstr 0 : { *(.stabstr) }
   23.85 +  .stab.excl 0 : { *(.stab.excl) }
   23.86 +  .stab.exclstr 0 : { *(.stab.exclstr) }
   23.87 +  .stab.index 0 : { *(.stab.index) }
   23.88 +  .stab.indexstr 0 : { *(.stab.indexstr) }
   23.89 +  .comment 0 : { *(.comment) }
   23.90 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/xen/arch/x86/x86_64/usercopy.c	Mon Jul 05 20:15:38 2004 +0000
    25.3 @@ -0,0 +1,136 @@
    25.4 +/* 
    25.5 + * User address space access functions.
    25.6 + *
    25.7 + * Copyright 1997 Andi Kleen <ak@muc.de>
    25.8 + * Copyright 1997 Linus Torvalds
    25.9 + * Copyright 2002 Andi Kleen <ak@suse.de>
   25.10 + */
   25.11 +#include <asm/uaccess.h>
   25.12 +
   25.13 +/*
   25.14 + * Copy a null terminated string from userspace.
   25.15 + */
   25.16 +
   25.17 +#define __do_strncpy_from_user(dst,src,count,res)			   \
   25.18 +do {									   \
   25.19 +	long __d0, __d1, __d2;						   \
   25.20 +	__asm__ __volatile__(						   \
   25.21 +		"	testq %1,%1\n"					   \
   25.22 +		"	jz 2f\n"					   \
   25.23 +		"0:	lodsb\n"					   \
   25.24 +		"	stosb\n"					   \
   25.25 +		"	testb %%al,%%al\n"				   \
   25.26 +		"	jz 1f\n"					   \
   25.27 +		"	decq %1\n"					   \
   25.28 +		"	jnz 0b\n"					   \
   25.29 +		"1:	subq %1,%0\n"					   \
   25.30 +		"2:\n"							   \
   25.31 +		".section .fixup,\"ax\"\n"				   \
   25.32 +		"3:	movq %5,%0\n"					   \
   25.33 +		"	jmp 2b\n"					   \
   25.34 +		".previous\n"						   \
   25.35 +		".section __ex_table,\"a\"\n"				   \
   25.36 +		"	.align 8\n"					   \
   25.37 +		"	.quad 0b,3b\n"					   \
   25.38 +		".previous"						   \
   25.39 +		: "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),	   \
   25.40 +		  "=&D" (__d2)						   \
   25.41 +		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
   25.42 +		: "memory");						   \
   25.43 +} while (0)
   25.44 +
   25.45 +long
   25.46 +__strncpy_from_user(char *dst, const char *src, long count)
   25.47 +{
   25.48 +	long res;
   25.49 +	__do_strncpy_from_user(dst, src, count, res);
   25.50 +	return res;
   25.51 +}
   25.52 +
   25.53 +long
   25.54 +strncpy_from_user(char *dst, const char *src, long count)
   25.55 +{
   25.56 +	long res = -EFAULT;
   25.57 +	if (access_ok(VERIFY_READ, src, 1))
   25.58 +		__do_strncpy_from_user(dst, src, count, res);
   25.59 +	return res;
   25.60 +}
   25.61 +
   25.62 +/*
   25.63 + * Zero Userspace
   25.64 + */
   25.65 +
   25.66 +unsigned long __clear_user(void *addr, unsigned long size)
   25.67 +{
   25.68 +	long __d0;
   25.69 +	/* no memory constraint because it doesn't change any memory gcc knows
   25.70 +	   about */
   25.71 +	asm volatile(
   25.72 +		"	testq  %[size8],%[size8]\n"
   25.73 +		"	jz     4f\n"
   25.74 +		"0:	movq %[zero],(%[dst])\n"
   25.75 +		"	addq   %[eight],%[dst]\n"
   25.76 +		"	decl %%ecx ; jnz   0b\n"
   25.77 +		"4:	movq  %[size1],%%rcx\n"
   25.78 +		"	testl %%ecx,%%ecx\n"
   25.79 +		"	jz     2f\n"
   25.80 +		"1:	movb   %b[zero],(%[dst])\n"
   25.81 +		"	incq   %[dst]\n"
   25.82 +		"	decl %%ecx ; jnz  1b\n"
   25.83 +		"2:\n"
   25.84 +		".section .fixup,\"ax\"\n"
   25.85 +		"3:	lea 0(%[size1],%[size8],8),%[size8]\n"
   25.86 +		"	jmp 2b\n"
   25.87 +		".previous\n"
   25.88 +		".section __ex_table,\"a\"\n"
   25.89 +		"       .align 8\n"
   25.90 +		"	.quad 0b,3b\n"
   25.91 +		"	.quad 1b,2b\n"
   25.92 +		".previous"
   25.93 +		: [size8] "=c"(size), [dst] "=&D" (__d0)
   25.94 +		: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst] "(addr),
   25.95 +		  [zero] "r" (0UL), [eight] "r" (8UL));
   25.96 +	return size;
   25.97 +}
   25.98 +
   25.99 +
  25.100 +unsigned long clear_user(void *to, unsigned long n)
  25.101 +{
  25.102 +	if (access_ok(VERIFY_WRITE, to, n))
  25.103 +		return __clear_user(to, n);
  25.104 +	return n;
  25.105 +}
  25.106 +
  25.107 +/*
  25.108 + * Return the size of a string (including the ending 0)
  25.109 + *
  25.110 + * Return 0 on exception, a value greater than N if too long
  25.111 + */
  25.112 +
  25.113 +long strnlen_user(const char *s, long n)
  25.114 +{
  25.115 +	unsigned long res = 0;
  25.116 +	char c;
  25.117 +
  25.118 +	if (!access_ok(VERIFY_READ, s, n))
  25.119 +		return 0;
  25.120 +
  25.121 +	while (1) {
  25.122 +		if (get_user(c, s))
  25.123 +			return 0;
  25.124 +		if (!c)
  25.125 +			return res+1;
  25.126 +		if (res>n)
  25.127 +			return n+1;
  25.128 +		res++;
  25.129 +		s++;
  25.130 +	}
  25.131 +}
  25.132 +
  25.133 +unsigned long copy_in_user(void *to, const void *from, unsigned len)
  25.134 +{
  25.135 +	if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { 
  25.136 +		return copy_user_generic(to, from, len);
  25.137 +	} 
  25.138 +	return len;		
  25.139 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/xen/arch/x86/x86_64/xen.lds	Mon Jul 05 20:15:38 2004 +0000
    26.3 @@ -0,0 +1,85 @@
    26.4 +/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */
    26.5 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
    26.6 +OUTPUT_ARCH(i386:x86-64)
    26.7 +ENTRY(start)
    26.8 +SECTIONS
    26.9 +{
   26.10 +  . = 0xFFFF840000100000;
   26.11 +  _text = .;			/* Text and read-only data */
   26.12 +  .text : {
   26.13 +	*(.text)
   26.14 +	*(.fixup)
   26.15 +	*(.gnu.warning)
   26.16 +	} = 0x9090
   26.17 +  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   26.18 +
   26.19 +  _etext = .;			/* End of text section */
   26.20 +
   26.21 +  .rodata : { *(.rodata) *(.rodata.*) }
   26.22 +  .kstrtab : { *(.kstrtab) }
   26.23 +
   26.24 +  . = ALIGN(16);		/* Exception table */
   26.25 +  __start___ex_table = .;
   26.26 +  __ex_table : { *(__ex_table) }
   26.27 +  __stop___ex_table = .;
   26.28 +
   26.29 +  __start___ksymtab = .;	/* Kernel symbol table */
   26.30 +  __ksymtab : { *(__ksymtab) }
   26.31 +  __stop___ksymtab = .;
   26.32 +
   26.33 +  __start___kallsyms = .;	/* All kernel symbols */
   26.34 +  __kallsyms : { *(__kallsyms) }
   26.35 +  __stop___kallsyms = .;
   26.36 +
   26.37 +  .data : {			/* Data */
   26.38 +	*(.data)
   26.39 +	CONSTRUCTORS
   26.40 +	}
   26.41 +
   26.42 +  _edata = .;			/* End of data section */
   26.43 +
   26.44 +  . = ALIGN(8192);		/* init_task */
   26.45 +  .data.init_task : { *(.data.init_task) }
   26.46 +
   26.47 +  . = ALIGN(4096);		/* Init code and data */
   26.48 +  __init_begin = .;
   26.49 +  .text.init : { *(.text.init) }
   26.50 +  .data.init : { *(.data.init) }
   26.51 +  . = ALIGN(16);
   26.52 +  __setup_start = .;
   26.53 +  .setup.init : { *(.setup.init) }
   26.54 +  __setup_end = .;
   26.55 +  __initcall_start = .;
   26.56 +  .initcall.init : { *(.initcall.init) }
   26.57 +  __initcall_end = .;
   26.58 +  . = ALIGN(4096);
   26.59 +  __init_end = .;
   26.60 +
   26.61 +  . = ALIGN(4096);
   26.62 +  .data.page_aligned : { *(.data.idt) }
   26.63 +
   26.64 +  . = ALIGN(32);
   26.65 +  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
   26.66 +
   26.67 +  __bss_start = .;		/* BSS */
   26.68 +  .bss : {
   26.69 +	*(.bss)
   26.70 +	}
   26.71 +  _end = . ;
   26.72 +
   26.73 +  /* Sections to be discarded */
   26.74 +  /DISCARD/ : {
   26.75 +	*(.text.exit)
   26.76 +	*(.data.exit)
   26.77 +	*(.exitcall.exit)
   26.78 +	}
   26.79 +
   26.80 +  /* Stabs debugging sections.  */
   26.81 +  .stab 0 : { *(.stab) }
   26.82 +  .stabstr 0 : { *(.stabstr) }
   26.83 +  .stab.excl 0 : { *(.stab.excl) }
   26.84 +  .stab.exclstr 0 : { *(.stab.exclstr) }
   26.85 +  .stab.index 0 : { *(.stab.index) }
   26.86 +  .stab.indexstr 0 : { *(.stab.indexstr) }
   26.87 +  .comment 0 : { *(.comment) }
   26.88 +}
    27.1 --- a/xen/arch/x86/xen.lds	Mon Jul 05 16:23:43 2004 +0000
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,87 +0,0 @@
    27.4 -/* ld script to make i386 Linux kernel
    27.5 - * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
    27.6 - */
    27.7 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    27.8 -OUTPUT_ARCH(i386)
    27.9 -ENTRY(start)
   27.10 -SECTIONS
   27.11 -{
   27.12 -  . = 0xFC400000 + 0x100000;
   27.13 -  _text = .;			/* Text and read-only data */
   27.14 -  .text : {
   27.15 -	*(.text)
   27.16 -	*(.fixup)
   27.17 -	*(.gnu.warning)
   27.18 -	} = 0x9090
   27.19 -  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   27.20 -
   27.21 -  _etext = .;			/* End of text section */
   27.22 -
   27.23 -  .rodata : { *(.rodata) *(.rodata.*) }
   27.24 -  .kstrtab : { *(.kstrtab) }
   27.25 -
   27.26 -  . = ALIGN(16);		/* Exception table */
   27.27 -  __start___ex_table = .;
   27.28 -  __ex_table : { *(__ex_table) }
   27.29 -  __stop___ex_table = .;
   27.30 -
   27.31 -  __start___ksymtab = .;	/* Kernel symbol table */
   27.32 -  __ksymtab : { *(__ksymtab) }
   27.33 -  __stop___ksymtab = .;
   27.34 -
   27.35 -  __start___kallsyms = .;	/* All kernel symbols */
   27.36 -  __kallsyms : { *(__kallsyms) }
   27.37 -  __stop___kallsyms = .;
   27.38 -
   27.39 -  .data : {			/* Data */
   27.40 -	*(.data)
   27.41 -	CONSTRUCTORS
   27.42 -	}
   27.43 -
   27.44 -  _edata = .;			/* End of data section */
   27.45 -
   27.46 -  . = ALIGN(8192);		/* init_task */
   27.47 -  .data.init_task : { *(.data.init_task) }
   27.48 -
   27.49 -  . = ALIGN(4096);		/* Init code and data */
   27.50 -  __init_begin = .;
   27.51 -  .text.init : { *(.text.init) }
   27.52 -  .data.init : { *(.data.init) }
   27.53 -  . = ALIGN(16);
   27.54 -  __setup_start = .;
   27.55 -  .setup.init : { *(.setup.init) }
   27.56 -  __setup_end = .;
   27.57 -  __initcall_start = .;
   27.58 -  .initcall.init : { *(.initcall.init) }
   27.59 -  __initcall_end = .;
   27.60 -  . = ALIGN(4096);
   27.61 -  __init_end = .;
   27.62 -
   27.63 -  . = ALIGN(4096);
   27.64 -  .data.page_aligned : { *(.data.idt) }
   27.65 -
   27.66 -  . = ALIGN(32);
   27.67 -  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
   27.68 -
   27.69 -  __bss_start = .;		/* BSS */
   27.70 -  .bss : {
   27.71 -	*(.bss)
   27.72 -	}
   27.73 -  _end = . ;
   27.74 -
   27.75 -  /* Sections to be discarded */
   27.76 -  /DISCARD/ : {
   27.77 -	*(.text.exit)
   27.78 -	*(.data.exit)
   27.79 -	*(.exitcall.exit)
   27.80 -	}
   27.81 -
   27.82 -  /* Stabs debugging sections.  */
   27.83 -  .stab 0 : { *(.stab) }
   27.84 -  .stabstr 0 : { *(.stabstr) }
   27.85 -  .stab.excl 0 : { *(.stab.excl) }
   27.86 -  .stab.exclstr 0 : { *(.stab.exclstr) }
   27.87 -  .stab.index 0 : { *(.stab.index) }
   27.88 -  .stab.indexstr 0 : { *(.stab.indexstr) }
   27.89 -  .comment 0 : { *(.comment) }
   27.90 -}
    28.1 --- a/xen/include/asm-x86/config.h	Mon Jul 05 16:23:43 2004 +0000
    28.2 +++ b/xen/include/asm-x86/config.h	Mon Jul 05 20:15:38 2004 +0000
    28.3 @@ -18,8 +18,10 @@
    28.4  #define CONFIG_ACPI_BOOT 1
    28.5  
    28.6  #define CONFIG_PCI 1
    28.7 +#define CONFIG_PCI_DIRECT 1
    28.8 +#if defined(__i386__)
    28.9  #define CONFIG_PCI_BIOS 1
   28.10 -#define CONFIG_PCI_DIRECT 1
   28.11 +#endif
   28.12  
   28.13  #define CONFIG_IDE 1
   28.14  #define CONFIG_BLK_DEV_IDE 1
    29.1 --- a/xen/include/asm-x86/irq.h	Mon Jul 05 16:23:43 2004 +0000
    29.2 +++ b/xen/include/asm-x86/irq.h	Mon Jul 05 20:15:38 2004 +0000
    29.3 @@ -86,6 +86,8 @@ extern char _stext, _etext;
    29.4  #define __STR(x) #x
    29.5  #define STR(x) __STR(x)
    29.6  
    29.7 +#if defined(__i386__)
    29.8 +
    29.9  #define SAVE_ALL \
   29.10  	"cld\n\t" \
   29.11  	"pushl %gs\n\t" \
   29.12 @@ -105,8 +107,11 @@ extern char _stext, _etext;
   29.13  	"movl %edx,%fs\n\t" \
   29.14  	"movl %edx,%gs\n\t"
   29.15  
   29.16 -#define IRQ_NAME2(nr) nr##_interrupt(void)
   29.17 -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
   29.18 +#else
   29.19 +
   29.20 +#define SAVE_ALL
   29.21 +
   29.22 +#endif
   29.23  
   29.24  #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
   29.25  #define XBUILD_SMP_INTERRUPT(x,v)\
   29.26 @@ -115,7 +120,7 @@ asmlinkage void call_##x(void); \
   29.27  __asm__( \
   29.28  "\n"__ALIGN_STR"\n" \
   29.29  SYMBOL_NAME_STR(x) ":\n\t" \
   29.30 -	"pushl $"#v"\n\t" \
   29.31 +	"push"__OS" $"#v"\n\t" \
   29.32  	SAVE_ALL \
   29.33  	SYMBOL_NAME_STR(call_##x)":\n\t" \
   29.34  	"call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
   29.35 @@ -128,13 +133,13 @@ asmlinkage void call_##x(void); \
   29.36  __asm__( \
   29.37  "\n"__ALIGN_STR"\n" \
   29.38  SYMBOL_NAME_STR(x) ":\n\t" \
   29.39 -	"pushl $"#v"\n\t" \
   29.40 +	"push"__OS" $"#v"\n\t" \
   29.41  	SAVE_ALL \
   29.42 -	"movl %esp,%eax\n\t" \
   29.43 -	"pushl %eax\n\t" \
   29.44 +	"mov %"__OP"sp,%"__OP"ax\n\t" \
   29.45 +	"push %"__OP"ax\n\t" \
   29.46  	SYMBOL_NAME_STR(call_##x)":\n\t" \
   29.47  	"call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
   29.48 -	"addl $4,%esp\n\t" \
   29.49 +	"add $4,%"__OP"sp\n\t" \
   29.50  	"jmp ret_from_intr\n");
   29.51  
   29.52  #define BUILD_COMMON_IRQ() \
   29.53 @@ -147,12 +152,15 @@ asmlinkage void call_do_IRQ(void); \
   29.54  	"call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \
   29.55  	"jmp ret_from_intr\n");
   29.56  
   29.57 +#define IRQ_NAME2(nr) nr##_interrupt(void)
   29.58 +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
   29.59 +
   29.60  #define BUILD_IRQ(nr) \
   29.61  asmlinkage void IRQ_NAME(nr); \
   29.62  __asm__( \
   29.63  "\n"__ALIGN_STR"\n" \
   29.64  SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
   29.65 -	"pushl $"#nr"\n\t" \
   29.66 +	"push"__OS" $"#nr"\n\t" \
   29.67  	"jmp common_interrupt");
   29.68  
   29.69  extern unsigned long prof_cpu_mask;