ia64/xen-unstable

changeset 2216:36edd9229334

bitkeeper revision 1.1159.1.46 (411bb5cdvVy5iOkL-yrmt3Kr-kunVg)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Thu Aug 12 18:24:13 2004 +0000 (2004-08-12)
parents 0667ac4c62f5 249ef8d5db7d
children afbab8dc06bd
files linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile linux-2.4.26-xen-sparse/arch/xen/kernel/process.c linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c linux-2.4.26-xen-sparse/mkbuildtree linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h xen/drivers/char/console.c
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile	Thu Aug 12 17:01:47 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile	Thu Aug 12 18:24:13 2004 +0000
     1.3 @@ -10,7 +10,8 @@ export-objs     := i386_ksyms.o
     1.4  
     1.5  obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o  \
     1.6  		ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o \
     1.7 -		i386_ksyms.o i387.o evtchn.o ctrl_if.o pci-dma.o
     1.8 +		i386_ksyms.o i387.o evtchn.o ctrl_if.o pci-dma.o \
     1.9 +		reboot.o
    1.10  
    1.11  ifdef CONFIG_PCI
    1.12  obj-y	+= pci-i386.o pci-pc.o
     2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c	Thu Aug 12 17:01:47 2004 +0000
     2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c	Thu Aug 12 18:24:13 2004 +0000
     2.3 @@ -115,27 +115,6 @@ void cpu_idle (void)
     2.4      }
     2.5  }
     2.6  
     2.7 -void machine_restart(char *__unused)
     2.8 -{
     2.9 -    /* We really want to get pending console data out before we die. */
    2.10 -    extern void xencons_force_flush(void);
    2.11 -    xencons_force_flush();
    2.12 -    HYPERVISOR_reboot();
    2.13 -}
    2.14 -
    2.15 -void machine_halt(void)
    2.16 -{
    2.17 -    machine_power_off();
    2.18 -}
    2.19 -
    2.20 -void machine_power_off(void)
    2.21 -{
    2.22 -    /* We really want to get pending console data out before we die. */
    2.23 -    extern void xencons_force_flush(void);
    2.24 -    xencons_force_flush();
    2.25 -    HYPERVISOR_shutdown();
    2.26 -}
    2.27 -
    2.28  extern void show_trace(unsigned long* esp);
    2.29  
    2.30  void show_regs(struct pt_regs * regs)
     3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Thu Aug 12 17:01:47 2004 +0000
     3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Thu Aug 12 18:24:13 2004 +0000
     3.3 @@ -1184,173 +1184,3 @@ void __init cpu_init (void)
     3.4      current->used_math = 0;
     3.5      stts();
     3.6  }
     3.7 -
     3.8 -
     3.9 -/******************************************************************************
    3.10 - * Stop/pickle callback handling.
    3.11 - */
    3.12 -
    3.13 -#include <asm/suspend.h>
    3.14 -
    3.15 -/* Ignore multiple shutdown requests. */
    3.16 -static int shutting_down = -1;
    3.17 -
    3.18 -static void __do_suspend(void)
    3.19 -{
    3.20 -    int i,j;
    3.21 -    /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
    3.22 -    extern void blkdev_suspend(void);
    3.23 -    extern void blkdev_resume(void);
    3.24 -    extern void netif_suspend(void);
    3.25 -    extern void netif_resume(void);    
    3.26 -    extern void time_suspend(void);
    3.27 -    extern void time_resume(void);
    3.28 -
    3.29 -    suspend_record_t *suspend_record     = NULL;
    3.30 -
    3.31 -    if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL))
    3.32 -         == NULL )
    3.33 -        goto out;
    3.34 -
    3.35 -    suspend_record->nr_pfns = max_pfn; /* final number of pfns */
    3.36 -
    3.37 -    __cli();
    3.38 -
    3.39 -    netif_suspend();
    3.40 -
    3.41 -    blkdev_suspend();
    3.42 -
    3.43 -    time_suspend();
    3.44 -
    3.45 -    ctrl_if_suspend();
    3.46 -
    3.47 -    irq_suspend();
    3.48 -
    3.49 -    HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    3.50 -    clear_fixmap(FIX_SHARED_INFO);
    3.51 -
    3.52 -    memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
    3.53 -
    3.54 -    HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
    3.55 -
    3.56 -    shutting_down = -1; 
    3.57 -
    3.58 -    memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
    3.59 -
    3.60 -    set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
    3.61 -
    3.62 -    HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
    3.63 -
    3.64 -    memset(empty_zero_page, 0, PAGE_SIZE);
    3.65 -
    3.66 -    for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    3.67 -    {	
    3.68 -        pfn_to_mfn_frame_list[j] = 
    3.69 -            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
    3.70 -    }
    3.71 -    HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
    3.72 -	virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
    3.73 -
    3.74 -
    3.75 -    irq_resume();
    3.76 -
    3.77 -    ctrl_if_resume();
    3.78 -
    3.79 -    time_resume();
    3.80 -
    3.81 -    blkdev_resume();
    3.82 -
    3.83 -    netif_resume();
    3.84 -
    3.85 -    __sti();
    3.86 -
    3.87 -
    3.88 - out:
    3.89 -    if ( suspend_record != NULL )
    3.90 -        free_page((unsigned long)suspend_record);
    3.91 -}
    3.92 -
    3.93 -static int shutdown_process(void *__unused)
    3.94 -{
    3.95 -    static char *envp[] = { "HOME=/", "TERM=linux", 
    3.96 -                            "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
    3.97 -    static char *restart_argv[]  = { "/sbin/shutdown", "-r", "now", NULL };
    3.98 -    static char *poweroff_argv[] = { "/sbin/halt",     "-p",        NULL };
    3.99 -
   3.100 -    extern asmlinkage long sys_reboot(int magic1, int magic2,
   3.101 -                                      unsigned int cmd, void *arg);
   3.102 -
   3.103 -    daemonize();
   3.104 -
   3.105 -    switch ( shutting_down )
   3.106 -    {
   3.107 -    case CMSG_SHUTDOWN_POWEROFF:
   3.108 -        if ( execve("/sbin/halt", poweroff_argv, envp) < 0 )
   3.109 -        {
   3.110 -            sys_reboot(LINUX_REBOOT_MAGIC1,
   3.111 -                       LINUX_REBOOT_MAGIC2,
   3.112 -                       LINUX_REBOOT_CMD_POWER_OFF,
   3.113 -                       NULL);
   3.114 -        }
   3.115 -        break;
   3.116 -
   3.117 -    case CMSG_SHUTDOWN_REBOOT:
   3.118 -        if ( execve("/sbin/shutdown", restart_argv, envp) < 0 )
   3.119 -        {
   3.120 -            sys_reboot(LINUX_REBOOT_MAGIC1,
   3.121 -                       LINUX_REBOOT_MAGIC2,
   3.122 -                       LINUX_REBOOT_CMD_RESTART,
   3.123 -                       NULL);
   3.124 -        }
   3.125 -        break;
   3.126 -    }
   3.127 -
   3.128 -    return 0;
   3.129 -}
   3.130 -
   3.131 -static void __shutdown_handler(void *unused)
   3.132 -{
   3.133 -    int err;
   3.134 -
   3.135 -    if ( shutting_down != CMSG_SHUTDOWN_SUSPEND )
   3.136 -    {
   3.137 -        err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES);
   3.138 -        if ( err < 0 )
   3.139 -            printk(KERN_ALERT "Error creating shutdown process!\n");
   3.140 -        else
   3.141 -            shutting_down = -1; /* could try again */
   3.142 -    }
   3.143 -    else
   3.144 -    {
   3.145 -        __do_suspend();
   3.146 -    }
   3.147 -}
   3.148 -
   3.149 -static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
   3.150 -{
   3.151 -    static struct tq_struct shutdown_tq;
   3.152 -
   3.153 -    if ( (shutting_down == -1) &&
   3.154 -         ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) ||
   3.155 -          (msg->subtype == CMSG_SHUTDOWN_REBOOT) ||
   3.156 -          (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) )
   3.157 -    {
   3.158 -        shutting_down = msg->subtype;
   3.159 -        shutdown_tq.routine = __shutdown_handler;
   3.160 -        schedule_task(&shutdown_tq);
   3.161 -    }
   3.162 -    else
   3.163 -    {
   3.164 -	printk("Ignore spurious shutdown request\n");
   3.165 -    }
   3.166 -
   3.167 -    ctrl_if_send_response(msg);
   3.168 -}
   3.169 -
   3.170 -static int __init setup_shutdown_event(void)
   3.171 -{
   3.172 -    ctrl_if_register_receiver(CMSG_SHUTDOWN, shutdown_handler, 0);
   3.173 -    return 0;
   3.174 -}
   3.175 -
   3.176 -__initcall(setup_shutdown_event);
     4.1 --- a/linux-2.4.26-xen-sparse/mkbuildtree	Thu Aug 12 17:01:47 2004 +0000
     4.2 +++ b/linux-2.4.26-xen-sparse/mkbuildtree	Thu Aug 12 18:24:13 2004 +0000
     4.3 @@ -222,6 +222,7 @@ ln -sf ../../i386/kernel/semaphore.c
     4.4  ln -sf ../../i386/kernel/sys_i386.c 
     4.5  ln -sf ../../../${LINUX_26}/arch/xen/kernel/ctrl_if.c
     4.6  ln -sf ../../../${LINUX_26}/arch/xen/kernel/evtchn.c
     4.7 +ln -sf ../../../${LINUX_26}/arch/xen/kernel/reboot.c
     4.8  ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/ioport.c
     4.9  ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/pci-dma.c
    4.10  
     5.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c	Thu Aug 12 17:01:47 2004 +0000
     5.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c	Thu Aug 12 18:24:13 2004 +0000
     5.3 @@ -510,7 +510,7 @@ unsigned long get_cmos_time(void)
     5.4  
     5.5  static long clock_cmos_diff;
     5.6  
     5.7 -static int time_suspend(struct sys_device *dev, u32 state)
     5.8 +static int __time_suspend(struct sys_device *dev, u32 state)
     5.9  {
    5.10  	/*
    5.11  	 * Estimate time zone so that set_time can update the clock
    5.12 @@ -520,7 +520,7 @@ static int time_suspend(struct sys_devic
    5.13  	return 0;
    5.14  }
    5.15  
    5.16 -static int time_resume(struct sys_device *dev)
    5.17 +static int __time_resume(struct sys_device *dev)
    5.18  {
    5.19  	unsigned long sec = get_cmos_time() + clock_cmos_diff;
    5.20  	write_seqlock_irq(&xtime_lock);
    5.21 @@ -531,8 +531,8 @@ static int time_resume(struct sys_device
    5.22  }
    5.23  
    5.24  static struct sysdev_class pit_sysclass = {
    5.25 -	.resume = time_resume,
    5.26 -	.suspend = time_suspend,
    5.27 +	.resume = __time_resume,
    5.28 +	.suspend = __time_suspend,
    5.29  	set_kset_name("pit"),
    5.30  };
    5.31  
    5.32 @@ -647,6 +647,25 @@ int set_timeout_timer(void)
    5.33  	return ret;
    5.34  }
    5.35  
    5.36 +void time_suspend(void)
    5.37 +{
    5.38 +}
    5.39 +
    5.40 +void time_resume(void)
    5.41 +{
    5.42 +    unsigned long flags;
    5.43 +    write_lock_irqsave(&xtime_lock, flags);
    5.44 +    /* Get timebases for new environment. */ 
    5.45 +    __get_time_values_from_xen();
    5.46 +    /* Reset our own concept of passage of system time. */
    5.47 +    processed_system_time = shadow_system_time;
    5.48 +    /* Accept a warp in UTC (wall-clock) time. */
    5.49 +    last_seen_tv.tv_sec = 0;
    5.50 +    /* Make sure we resync UTC time with Xen on next timer interrupt. */
    5.51 +    last_update_from_xen = 0;
    5.52 +    write_unlock_irqrestore(&xtime_lock, flags);
    5.53 +}
    5.54 +
    5.55  /*
    5.56   * /proc/sys/xen: This really belongs in another file. It can stay here for
    5.57   * now however.
     6.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Thu Aug 12 17:01:47 2004 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Thu Aug 12 18:24:13 2004 +0000
     6.3 @@ -37,8 +37,8 @@
     6.4      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
     6.5      __LINE__, __FILE__); *(int*)0=0; }
     6.6  #define DPRINTK(_f, _a...) printk(KERN_ALERT \
     6.7 -                           "(file=%s, line=%d, eip=%08lx) " _f "\n", \
     6.8 -                           __FILE__ , __LINE__ , eip, ## _a )
     6.9 +                           "(file=%s, line=%d) " _f "\n", \
    6.10 +                           __FILE__ , __LINE__ , ## _a )
    6.11  #else
    6.12  #define ASSERT(_p) ((void)0)
    6.13  #define DPRINTK(_f, _a...) ((void)0)
    6.14 @@ -138,6 +138,28 @@ static unsigned char insn_decode[256] = 
    6.15      O, O, O, O, O, O, O|M, X
    6.16  };
    6.17  
    6.18 +/* Bitmap of faulting instructions that we can handle. */
    6.19 +static unsigned char handleable_code[32] = {
    6.20 +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.21 +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.22 +    /* 0x80-0x83, 0x89, 0x8B */
    6.23 +    0x0F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.24 +    /* 0xC7 */
    6.25 +    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.26 +};
    6.27 +
    6.28 +/* Bitmap of opcodes that use a register operand specified by Mod/RM. */
    6.29 +static unsigned char opcode_uses_reg[32] = {
    6.30 +    /* 0x00 - 0x3F */
    6.31 +    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
    6.32 +    /* 0x40 - 0x7F */
    6.33 +    0x00, 0x00, 0x00, 0x00, 0x0C, 0x0A, 0x00, 0x00,
    6.34 +    /* 0x80 - 0xBF */
    6.35 +    0xF0, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.36 +    /* 0xC0 - 0xFF */
    6.37 +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.38 +};
    6.39 +
    6.40  static unsigned int parse_insn(unsigned char *insn, 
    6.41                                 unsigned char *p_opcode,
    6.42                                 unsigned char *p_decode)
    6.43 @@ -188,27 +210,61 @@ static unsigned int parse_insn(unsigned 
    6.44      return ((pb - insn) + 1 + (d & INSN_SUFFIX_BYTES));
    6.45  }
    6.46  
    6.47 -/* Bitmap of faulting instructions that we can handle. */
    6.48 -static unsigned char handleable_code[32] = {
    6.49 -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.50 -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.51 -    /* 0x80-0x83, 0x89, 0x8B */
    6.52 -    0x0F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.53 -    /* 0xC7 */
    6.54 -    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.55 -};
    6.56 +/*
    6.57 + * Mainly this function checks that our patches can't erroneously get flushed
    6.58 + * to a file on disc, which would screw us after reboot!
    6.59 + */
    6.60 +static int safe_to_patch(unsigned long addr)
    6.61 +{
    6.62 +    struct mm_struct      *mm = current->mm;
    6.63 +    struct vm_area_struct *vma;
    6.64 +    struct file           *file;
    6.65 +    unsigned char          _name[30], *name;
    6.66 +
    6.67 +    /* Always safe to patch the fixup buffer. */
    6.68 +    if ( addr <= (FIXUP_BUF_USER + FIXUP_BUF_SIZE) )
    6.69 +        return 1;
    6.70 +
    6.71 +    down_read(&mm->mmap_sem);
    6.72 +
    6.73 +    if ( (vma = find_vma(current->mm, addr)) == NULL )
    6.74 +    {
    6.75 +        DPRINTK("No VMA contains fault address.");
    6.76 +        goto fail;
    6.77 +    }
    6.78 +
    6.79 +    /* No backing file, so safe to patch. */
    6.80 +    if ( (file = vma->vm_file) == NULL )
    6.81 +        goto success;
    6.82  
    6.83 -/* Bitmap of opcodes that use a register operand specified by Mod/RM. */
    6.84 -static unsigned char opcode_uses_reg[32] = {
    6.85 -    /* 0x00 - 0x3F */
    6.86 -    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
    6.87 -    /* 0x40 - 0x7F */
    6.88 -    0x00, 0x00, 0x00, 0x00, 0x0C, 0x0A, 0x00, 0x00,
    6.89 -    /* 0x80 - 0xBF */
    6.90 -    0xF0, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.91 -    /* 0xC0 - 0xFF */
    6.92 -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    6.93 -};
    6.94 +    /* No shared mappings => nobody can dirty the file. */
    6.95 +    /* XXX Note the assumption that noone will dirty the file in future! */
    6.96 +    if ( file->f_mapping->i_mmap_writable != 0 )
    6.97 +    {
    6.98 +        DPRINTK("Shared mappings exist.");
    6.99 +        goto fail;
   6.100 +    }
   6.101 +
   6.102 +    /*
   6.103 +     * Because of above dodgy assumption, we will only patch things in
   6.104 +     * /lib/tls. Our belief is that updates here will only ever occur by
   6.105 +     * unlinking the old files and installing completely fresh ones. :-)
   6.106 +     */
   6.107 +    name = d_path(file->f_dentry, file->f_vfsmnt, _name, sizeof(_name));
   6.108 +    if ( strncmp("/lib/tls", name, 8) != 0 )
   6.109 +    {
   6.110 +        DPRINTK("Backing file is not in /lib/tls");
   6.111 +        goto fail;
   6.112 +    }
   6.113 +
   6.114 + success:
   6.115 +    up_read(&mm->mmap_sem);
   6.116 +    return 1;
   6.117 +
   6.118 + fail:
   6.119 +    up_read(&mm->mmap_sem);
   6.120 +    return 0;
   6.121 +}
   6.122  
   6.123  asmlinkage void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
   6.124  {
   6.125 @@ -219,6 +275,7 @@ asmlinkage void do_fixup_4gb_segment(str
   6.126      unsigned char b[20], modrm, mod, reg, rm, sib, patch[20], opcode, decode;
   6.127      unsigned long eip = regs->eip - insn_len;
   6.128      struct fixup_entry *fe;
   6.129 +    struct page *page;
   6.130      pte_t *pte;
   6.131      pmd_t *pmd;
   6.132      pgd_t *pgd;
   6.133 @@ -231,26 +288,8 @@ asmlinkage void do_fixup_4gb_segment(str
   6.134          return;
   6.135      }
   6.136  
   6.137 -    if ( unlikely(eip >= (PAGE_OFFSET-32)) )
   6.138 -    {
   6.139 -        DPRINTK("User executing out of kernel space?!");
   6.140 +    if ( unlikely(!safe_to_patch(eip)) )
   6.141          return;
   6.142 -    }
   6.143 -
   6.144 -    /*
   6.145 -     * Check that the page to be patched is part of a private VMA. This 
   6.146 -     * means that our patch will never erroneously get flushed to disc.
   6.147 -     */
   6.148 -    if ( eip > (FIXUP_BUF_USER + FIXUP_BUF_SIZE) ) /* don't check fixup area */
   6.149 -    {
   6.150 -        /* [SMP] Need to grab the mmap_sem semaphore. */
   6.151 -        struct vm_area_struct *vma = find_vma(current->mm, eip);
   6.152 -        if ( (vma == NULL) || (vma->vm_flags & VM_MAYSHARE) )
   6.153 -        {
   6.154 -            DPRINTK("Cannot patch a shareable VMA.");
   6.155 -            return;
   6.156 -        }
   6.157 -    }
   6.158  
   6.159      if ( unlikely(copy_from_user(b, (void *)eip, sizeof(b)) != 0) )
   6.160      {
   6.161 @@ -591,6 +630,17 @@ asmlinkage void do_fixup_4gb_segment(str
   6.162      for ( i = 5; i < fe->patched_code_len; i++ )
   6.163          patch[i] = 0x90; /* nop */
   6.164  
   6.165 +    /* Find the physical page that is to be patched. Check it isn't dirty. */
   6.166 +    pgd = pgd_offset(current->mm, eip);
   6.167 +    pmd = pmd_offset(pgd, eip);
   6.168 +    pte = pte_offset_kernel(pmd, eip);
   6.169 +    page = pte_page(*pte);
   6.170 +    if ( unlikely(PageDirty(page)) )
   6.171 +    {
   6.172 +        DPRINTK("Page is already dirty.");
   6.173 +        return;
   6.174 +    }
   6.175 +
   6.176      if ( put_user(eip + PATCH_LEN, (unsigned long *)regs->esp - 1) != 0 )
   6.177      {
   6.178          DPRINTK("Failed to place return address on user stack.");
   6.179 @@ -602,12 +652,9 @@ asmlinkage void do_fixup_4gb_segment(str
   6.180      regs->eip = FIXUP_BUF_USER + fe->return_idx;
   6.181  
   6.182      /* [SMP] Need to pause other threads while patching. */
   6.183 -    pgd = pgd_offset(current->mm, eip);
   6.184 -    pmd = pmd_offset(pgd, eip);
   6.185 -    pte = pte_offset_kernel(pmd, eip);
   6.186 -    veip = kmap(pte_page(*pte));
   6.187 +    veip = kmap(page);
   6.188      memcpy((char *)veip + (eip & ~PAGE_MASK), patch, fe->patched_code_len);
   6.189 -    kunmap(pte_page(*pte));
   6.190 +    kunmap(page);
   6.191  
   6.192      return;
   6.193  }
     7.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c	Thu Aug 12 17:01:47 2004 +0000
     7.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c	Thu Aug 12 18:24:13 2004 +0000
     7.3 @@ -1,8 +1,23 @@
     7.4  
     7.5 +#define __KERNEL_SYSCALLS__
     7.6 +static int errno;
     7.7 +#include <linux/errno.h>
     7.8 +#include <linux/version.h>
     7.9 +#include <linux/kernel.h>
    7.10 +#include <linux/mm.h>
    7.11 +#include <linux/unistd.h>
    7.12  #include <linux/module.h>
    7.13 +#include <linux/reboot.h>
    7.14 +#include <asm/irq.h>
    7.15 +#include <asm/mmu_context.h>
    7.16 +#include <asm-xen/ctrl_if.h>
    7.17  #include <asm-xen/hypervisor.h>
    7.18 +#include <asm-xen/hypervisor-ifs/dom0_ops.h>
    7.19 +#include <asm-xen/suspend.h>
    7.20  
    7.21 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    7.22  int reboot_thru_bios = 0;	/* for dmi_scan.c */
    7.23 +#endif
    7.24  
    7.25  void machine_restart(char * __unused)
    7.26  {
    7.27 @@ -12,21 +27,18 @@ void machine_restart(char * __unused)
    7.28  	HYPERVISOR_reboot();
    7.29  }
    7.30  
    7.31 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    7.32  EXPORT_SYMBOL(machine_restart);
    7.33 +#endif
    7.34  
    7.35  void machine_halt(void)
    7.36  {
    7.37 -	/* We really want to get pending console data out before we die. */
    7.38 -	extern void xencons_force_flush(void);
    7.39 -	xencons_force_flush();
    7.40 -	for ( ; ; ) /* loop without wasting cpu cycles */
    7.41 -	{
    7.42 -		HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_pending = 0;
    7.43 -		HYPERVISOR_block();
    7.44 -	}
    7.45 +	machine_power_off();
    7.46  }
    7.47  
    7.48 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    7.49  EXPORT_SYMBOL(machine_halt);
    7.50 +#endif
    7.51  
    7.52  void machine_power_off(void)
    7.53  {
    7.54 @@ -36,4 +48,191 @@ void machine_power_off(void)
    7.55  	HYPERVISOR_shutdown();
    7.56  }
    7.57  
    7.58 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    7.59  EXPORT_SYMBOL(machine_power_off);
    7.60 +#endif
    7.61 +
    7.62 +
    7.63 +
    7.64 +/******************************************************************************
    7.65 + * Stop/pickle callback handling.
    7.66 + */
    7.67 +
    7.68 +#include <asm/suspend.h>
    7.69 +
    7.70 +/* Ignore multiple shutdown requests. */
    7.71 +static int shutting_down = -1;
    7.72 +
    7.73 +static void __do_suspend(void)
    7.74 +{
    7.75 +    int i,j;
    7.76 +    /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
    7.77 +    extern void blkdev_suspend(void);
    7.78 +    extern void blkdev_resume(void);
    7.79 +    extern void netif_suspend(void);
    7.80 +    extern void netif_resume(void);    
    7.81 +    extern void time_suspend(void);
    7.82 +    extern void time_resume(void);
    7.83 +    extern unsigned long max_pfn;
    7.84 +    extern unsigned long *pfn_to_mfn_frame_list;
    7.85 +
    7.86 +    suspend_record_t *suspend_record     = NULL;
    7.87 +
    7.88 +    if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL))
    7.89 +         == NULL )
    7.90 +        goto out;
    7.91 +
    7.92 +    suspend_record->nr_pfns = max_pfn; /* final number of pfns */
    7.93 +
    7.94 +    __cli();
    7.95 +
    7.96 +    netif_suspend();
    7.97 +
    7.98 +    blkdev_suspend();
    7.99 +
   7.100 +    time_suspend();
   7.101 +
   7.102 +    ctrl_if_suspend();
   7.103 +
   7.104 +    irq_suspend();
   7.105 +
   7.106 +    HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
   7.107 +    clear_fixmap(FIX_SHARED_INFO);
   7.108 +
   7.109 +    memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
   7.110 +
   7.111 +    HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
   7.112 +
   7.113 +    shutting_down = -1; 
   7.114 +
   7.115 +    memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
   7.116 +
   7.117 +    set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
   7.118 +
   7.119 +    HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   7.120 +
   7.121 +    memset(empty_zero_page, 0, PAGE_SIZE);
   7.122 +
   7.123 +    for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
   7.124 +    {
   7.125 +        pfn_to_mfn_frame_list[j] = 
   7.126 +            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
   7.127 +    }
   7.128 +    HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
   7.129 +        virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
   7.130 +
   7.131 +
   7.132 +    irq_resume();
   7.133 +
   7.134 +    ctrl_if_resume();
   7.135 +
   7.136 +    time_resume();
   7.137 +
   7.138 +    blkdev_resume();
   7.139 +
   7.140 +    netif_resume();
   7.141 +
   7.142 +    __sti();
   7.143 +
   7.144 +
   7.145 + out:
   7.146 +    if ( suspend_record != NULL )
   7.147 +        free_page((unsigned long)suspend_record);
   7.148 +}
   7.149 +
   7.150 +static int shutdown_process(void *__unused)
   7.151 +{
   7.152 +    static char *envp[] = { "HOME=/", "TERM=linux", 
   7.153 +                            "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
   7.154 +    static char *restart_argv[]  = { "/sbin/shutdown", "-r", "now", NULL };
   7.155 +    static char *poweroff_argv[] = { "/sbin/halt",     "-p",        NULL };
   7.156 +
   7.157 +    extern asmlinkage long sys_reboot(int magic1, int magic2,
   7.158 +                                      unsigned int cmd, void *arg);
   7.159 +
   7.160 +    daemonize(
   7.161 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   7.162 +        "shutdown"
   7.163 +#endif
   7.164 +        );
   7.165 +
   7.166 +    switch ( shutting_down )
   7.167 +    {
   7.168 +    case CMSG_SHUTDOWN_POWEROFF:
   7.169 +        if ( execve("/sbin/halt", poweroff_argv, envp) < 0 )
   7.170 +        {
   7.171 +            sys_reboot(LINUX_REBOOT_MAGIC1,
   7.172 +                       LINUX_REBOOT_MAGIC2,
   7.173 +                       LINUX_REBOOT_CMD_POWER_OFF,
   7.174 +                       NULL);
   7.175 +        }
   7.176 +        break;
   7.177 +
   7.178 +    case CMSG_SHUTDOWN_REBOOT:
   7.179 +        if ( execve("/sbin/shutdown", restart_argv, envp) < 0 )
   7.180 +        {
   7.181 +            sys_reboot(LINUX_REBOOT_MAGIC1,
   7.182 +                       LINUX_REBOOT_MAGIC2,
   7.183 +                       LINUX_REBOOT_CMD_RESTART,
   7.184 +                       NULL);
   7.185 +        }
   7.186 +        break;
   7.187 +    }
   7.188 +
   7.189 +    shutting_down = -1; /* could try again */
   7.190 +
   7.191 +    return 0;
   7.192 +}
   7.193 +
   7.194 +static void __shutdown_handler(void *unused)
   7.195 +{
   7.196 +    int err;
   7.197 +
   7.198 +    if ( shutting_down != CMSG_SHUTDOWN_SUSPEND )
   7.199 +    {
   7.200 +        err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES);
   7.201 +        if ( err < 0 )
   7.202 +            printk(KERN_ALERT "Error creating shutdown process!\n");
   7.203 +    }
   7.204 +    else
   7.205 +    {
   7.206 +        __do_suspend();
   7.207 +    }
   7.208 +}
   7.209 +
   7.210 +static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
   7.211 +{
   7.212 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   7.213 +    static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
   7.214 +#else
   7.215 +    static struct tq_struct shutdown_tq;
   7.216 +#endif
   7.217 +
   7.218 +    if ( (shutting_down == -1) &&
   7.219 +         ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) ||
   7.220 +          (msg->subtype == CMSG_SHUTDOWN_REBOOT) ||
   7.221 +          (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) )
   7.222 +    {
   7.223 +        shutting_down = msg->subtype;
   7.224 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   7.225 +        schedule_work(&shutdown_work);
   7.226 +#else
   7.227 +        shutdown_tq.routine = __shutdown_handler;
   7.228 +        schedule_task(&shutdown_tq);
   7.229 +#endif
   7.230 +    }
   7.231 +    else
   7.232 +    {
   7.233 +        printk("Ignore spurious shutdown request\n");
   7.234 +    }
   7.235 +
   7.236 +    ctrl_if_send_response(msg);
   7.237 +}
   7.238 +
   7.239 +static int __init setup_shutdown_event(void)
   7.240 +{
   7.241 +    ctrl_if_register_receiver(CMSG_SHUTDOWN, shutdown_handler, 0);
   7.242 +    return 0;
   7.243 +}
   7.244 +
   7.245 +__initcall(setup_shutdown_event);
     8.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h	Thu Aug 12 17:01:47 2004 +0000
     8.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h	Thu Aug 12 18:24:13 2004 +0000
     8.3 @@ -140,6 +140,9 @@ extern int  bind_virq_to_irq(int virq);
     8.4  extern void unbind_virq_from_irq(int virq);
     8.5  extern int  bind_evtchn_to_irq(int evtchn);
     8.6  extern void unbind_evtchn_from_irq(int evtchn);
     8.7 +
     8.8 +extern void irq_suspend(void);
     8.9 +extern void irq_resume(void);
    8.10  #endif /* __ASSEMBLY__ */
    8.11  
    8.12  #endif /* _ASM_IRQ_VECTORS_H */
     9.1 --- a/xen/drivers/char/console.c	Thu Aug 12 17:01:47 2004 +0000
     9.2 +++ b/xen/drivers/char/console.c	Thu Aug 12 18:24:13 2004 +0000
     9.3 @@ -292,7 +292,7 @@ long do_console_io(int cmd, int count, c
     9.4      char *kbuf;
     9.5      long  rc;
     9.6  
     9.7 -#ifdef NDEBUG
     9.8 +#ifndef VERBOSE
     9.9      /* Only domain-0 may access the emergency console. */
    9.10      if ( current->domain != 0 )
    9.11          return -EPERM;