ia64/xen-unstable

changeset 2187:0c7d6ab95324

bitkeeper revision 1.1159.1.37 (4119f39et8u5bHvw8V3o56W8JdTE9A)

Merge xenbk@gandalf:/var/bk/xeno-unstable.bk
into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
author mjw@wray-m-3.hpl.hp.com
date Wed Aug 11 10:19:26 2004 +0000 (2004-08-11)
parents 6c272033a2ed eeb76f67d3d3
children 5de156da549c
files .rootkeys linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c linux-2.4.26-xen-sparse/arch/xen/kernel/i386_ksyms.c linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c linux-2.6.7-xen-sparse/arch/xen/i386/Kconfig linux-2.6.7-xen-sparse/arch/xen/i386/mm/Makefile linux-2.6.7-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6.7-xen-sparse/arch/xen/i386/mm/highmem.c linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/highmem.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h tools/examples/xmdefaults tools/examples/xmexample tools/libxc/xc.h tools/libxc/xc_domain.c tools/libxc/xc_linux_restore.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/create.py xen/arch/x86/Rules.mk xen/arch/x86/smpboot.c xen/common/dom0_ops.c xen/common/domain.c xen/common/kernel.c xen/common/sched_atropos.c xen/common/sched_bvt.c xen/common/sched_fair_bvt.c xen/common/sched_rrobin.c xen/common/schedule.c xen/include/hypervisor-ifs/dom0_ops.h xen/include/xen/sched-if.h xen/include/xen/sched.h
line diff
     1.1 --- a/.rootkeys	Wed Aug 11 10:18:38 2004 +0000
     1.2 +++ b/.rootkeys	Wed Aug 11 10:19:26 2004 +0000
     1.3 @@ -155,6 +155,7 @@ 40f56238JypKAUG01ZojFwH7qnZ5uA linux-2.6
     1.4  40f56238wi6AdNQjm0RT57bSkwb6hg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vsyscall.lds
     1.5  40f56238a3w6-byOzexIlMgni76Lcg linux-2.6.7-xen-sparse/arch/xen/i386/mm/Makefile
     1.6  40f56238ILx8xlbywNbzTdv5Zr4xXQ linux-2.6.7-xen-sparse/arch/xen/i386/mm/fault.c
     1.7 +4118cc35CbY8rfGVspF5O-7EkXBEAA linux-2.6.7-xen-sparse/arch/xen/i386/mm/highmem.c
     1.8  40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.7-xen-sparse/arch/xen/i386/mm/hypervisor.c
     1.9  40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.7-xen-sparse/arch/xen/i386/mm/init.c
    1.10  41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c
    1.11 @@ -202,6 +203,7 @@ 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6
    1.12  4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h
    1.13  40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h
    1.14  40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
    1.15 +4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/highmem.h
    1.16  40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h
    1.17  40f5623am9BzluYFuV6EQfTd-so3dA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/do_timer.h
    1.18  40f5623adZQ1IZGPxbDXONjyZGYuTA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/io_ports.h
     2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c	Wed Aug 11 10:18:38 2004 +0000
     2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c	Wed Aug 11 10:19:26 2004 +0000
     2.3 @@ -805,4 +805,16 @@ void blkdev_suspend(void)
     2.4  
     2.5  void blkdev_resume(void)
     2.6  {
     2.7 +    ctrl_msg_t                       cmsg;
     2.8 +    blkif_fe_driver_status_changed_t st;
     2.9 +    
    2.10 +
    2.11 +    /* Send a driver-UP notification to the domain controller. */
    2.12 +    cmsg.type      = CMSG_BLKIF_FE;
    2.13 +    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED;
    2.14 +    cmsg.length    = sizeof(blkif_fe_driver_status_changed_t);
    2.15 +    st.status      = BLKIF_DRIVER_STATUS_UP;
    2.16 +    memcpy(cmsg.msg, &st, sizeof(st));
    2.17 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    2.18  }
    2.19 +
     3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/i386_ksyms.c	Wed Aug 11 10:18:38 2004 +0000
     3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/i386_ksyms.c	Wed Aug 11 10:19:26 2004 +0000
     3.3 @@ -176,4 +176,5 @@ EXPORT_SYMBOL(create_xen_proc_entry);
     3.4  EXPORT_SYMBOL(remove_xen_proc_entry);
     3.5  
     3.6  EXPORT_SYMBOL(evtchn_do_upcall);
     3.7 +EXPORT_SYMBOL(force_evtchn_callback);
     3.8  EXPORT_SYMBOL(HYPERVISOR_shared_info);
     4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Wed Aug 11 10:18:38 2004 +0000
     4.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Wed Aug 11 10:19:26 2004 +0000
     4.3 @@ -1200,6 +1200,7 @@ static void __do_suspend(void)
     4.4      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
     4.5      extern void blkdev_suspend(void);
     4.6      extern void blkdev_resume(void);
     4.7 +    extern void netif_resume(void);
     4.8      
     4.9      extern void time_suspend(void);
    4.10      extern void time_resume(void);
    4.11 @@ -1248,8 +1249,8 @@ static void __do_suspend(void)
    4.12  
    4.13      __sti();
    4.14  
    4.15 -    //blkdev_resume();
    4.16 -    //netdev_resume();
    4.17 +    blkdev_resume();
    4.18 +    netif_resume();
    4.19  
    4.20   out:
    4.21      if ( suspend_record != NULL )
     5.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/Kconfig	Wed Aug 11 10:18:38 2004 +0000
     5.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/Kconfig	Wed Aug 11 10:19:26 2004 +0000
     5.3 @@ -555,14 +555,14 @@ config HAVE_ARCH_BOOTMEM_NODE
     5.4  	depends on NUMA
     5.5  	default y
     5.6  
     5.7 -config HIGHPTE
     5.8 -	bool "Allocate 3rd-level pagetables from highmem"
     5.9 -	depends on HIGHMEM4G || HIGHMEM64G
    5.10 -	help
    5.11 -	  The VM uses one page table entry for each page of physical memory.
    5.12 -	  For systems with a lot of RAM, this can be wasteful of precious
    5.13 -	  low memory.  Setting this option will put user-space page table
    5.14 -	  entries in high memory.
    5.15 +#config HIGHPTE
    5.16 +#	bool "Allocate 3rd-level pagetables from highmem"
    5.17 +#	depends on HIGHMEM4G || HIGHMEM64G
    5.18 +#	help
    5.19 +#	  The VM uses one page table entry for each page of physical memory.
    5.20 +#	  For systems with a lot of RAM, this can be wasteful of precious
    5.21 +#	  low memory.  Setting this option will put user-space page table
    5.22 +#	  entries in high memory.
    5.23  
    5.24  #config MTRR
    5.25  #	 bool "MTRR (Memory Type Range Register) support"
     6.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/mm/Makefile	Wed Aug 11 10:18:38 2004 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/Makefile	Wed Aug 11 10:19:26 2004 +0000
     6.3 @@ -11,7 +11,7 @@ c-obj-y	:= extable.o pageattr.o
     6.4  
     6.5  c-obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
     6.6  c-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
     6.7 -c-obj-$(CONFIG_HIGHMEM) += highmem.o
     6.8 +obj-$(CONFIG_HIGHMEM) += highmem.o
     6.9  c-obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
    6.10  
    6.11  c-link	:=
     7.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/mm/fault.c	Wed Aug 11 10:18:38 2004 +0000
     7.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/fault.c	Wed Aug 11 10:19:26 2004 +0000
     7.3 @@ -248,7 +248,8 @@ asmlinkage void do_page_fault(struct pt_
     7.4  	 * (error_code & 4) == 0, and that the fault was not a
     7.5  	 * protection error (error_code & 1) == 0.
     7.6  	 */
     7.7 -	if (unlikely(address >= TASK_SIZE)) { 
     7.8 +	if (unlikely(address >= TASK_SIZE) ||
     7.9 +	    unlikely(address < (FIRST_USER_PGD_NR<<PGDIR_SHIFT))) { 
    7.10  		if (!(error_code & 5))
    7.11  			goto vmalloc_fault;
    7.12  		/* 
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/highmem.c	Wed Aug 11 10:19:26 2004 +0000
     8.3 @@ -0,0 +1,137 @@
     8.4 +#include <linux/highmem.h>
     8.5 +
     8.6 +void *kmap(struct page *page)
     8.7 +{
     8.8 +	might_sleep();
     8.9 +	if (page < highmem_start_page)
    8.10 +		return page_address(page);
    8.11 +	return kmap_high(page);
    8.12 +}
    8.13 +
    8.14 +void kunmap(struct page *page)
    8.15 +{
    8.16 +	if (in_interrupt())
    8.17 +		BUG();
    8.18 +	if (page < highmem_start_page)
    8.19 +		return;
    8.20 +	kunmap_high(page);
    8.21 +}
    8.22 +
    8.23 +/*
    8.24 + * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
    8.25 + * no global lock is needed and because the kmap code must perform a global TLB
    8.26 + * invalidation when the kmap pool wraps.
    8.27 + *
    8.28 + * However when holding an atomic kmap is is not legal to sleep, so atomic
    8.29 + * kmaps are appropriate for short, tight code paths only.
    8.30 + */
    8.31 +void *kmap_atomic(struct page *page, enum km_type type)
    8.32 +{
    8.33 +	enum fixed_addresses idx;
    8.34 +	unsigned long vaddr;
    8.35 +
    8.36 +	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
    8.37 +	inc_preempt_count();
    8.38 +	if (page < highmem_start_page)
    8.39 +		return page_address(page);
    8.40 +
    8.41 +	idx = type + KM_TYPE_NR*smp_processor_id();
    8.42 +	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
    8.43 +#ifdef CONFIG_DEBUG_HIGHMEM
    8.44 +	if (!pte_none(*(kmap_pte-idx)))
    8.45 +		BUG();
    8.46 +#endif
    8.47 +	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
    8.48 +	__flush_tlb_one(vaddr);
    8.49 +
    8.50 +	return (void*) vaddr;
    8.51 +}
    8.52 +
    8.53 +/* Same as kmap_atomic but with PAGE_KERNEL_RO page protection */
    8.54 +void *kmap_atomic_pte(struct page *page, enum km_type type)
    8.55 +{
    8.56 +	enum fixed_addresses idx;
    8.57 +	unsigned long vaddr;
    8.58 +
    8.59 +	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
    8.60 +	inc_preempt_count();
    8.61 +	if (page < highmem_start_page)
    8.62 +		return page_address(page);
    8.63 +
    8.64 +	idx = type + KM_TYPE_NR*smp_processor_id();
    8.65 +	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
    8.66 +#ifdef CONFIG_DEBUG_HIGHMEM
    8.67 +	if (!pte_none(*(kmap_pte-idx)))
    8.68 +		BUG();
    8.69 +#endif
    8.70 +	set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL_RO));
    8.71 +	__flush_tlb_one(vaddr);
    8.72 +
    8.73 +	return (void*) vaddr;
    8.74 +}
    8.75 +
    8.76 +void kunmap_atomic(void *kvaddr, enum km_type type)
    8.77 +{
    8.78 +#ifdef CONFIG_DEBUG_HIGHMEM
    8.79 +	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
    8.80 +	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
    8.81 +
    8.82 +	if (vaddr < FIXADDR_START) { // FIXME
    8.83 +		dec_preempt_count();
    8.84 +		preempt_check_resched();
    8.85 +		return;
    8.86 +	}
    8.87 +
    8.88 +	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
    8.89 +		BUG();
    8.90 +
    8.91 +	/*
    8.92 +	 * force other mappings to Oops if they'll try to access
    8.93 +	 * this pte without first remap it
    8.94 +	 */
    8.95 +	pte_clear(kmap_pte-idx);
    8.96 +	__flush_tlb_one(vaddr);
    8.97 +#endif
    8.98 +
    8.99 +	dec_preempt_count();
   8.100 +	preempt_check_resched();
   8.101 +}
   8.102 +
   8.103 +void kunmap_atomic_force(void *kvaddr, enum km_type type)
   8.104 +{
   8.105 +	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
   8.106 +	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
   8.107 +
   8.108 +	if (vaddr < FIXADDR_START) { // FIXME
   8.109 +		dec_preempt_count();
   8.110 +		preempt_check_resched();
   8.111 +		return;
   8.112 +	}
   8.113 +
   8.114 +	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
   8.115 +		BUG();
   8.116 +
   8.117 +	/*
   8.118 +	 * force other mappings to Oops if they'll try to access
   8.119 +	 * this pte without first remap it
   8.120 +	 */
   8.121 +	pte_clear(kmap_pte-idx);
   8.122 +	__flush_tlb_one(vaddr);
   8.123 +
   8.124 +	dec_preempt_count();
   8.125 +	preempt_check_resched();
   8.126 +}
   8.127 +
   8.128 +struct page *kmap_atomic_to_page(void *ptr)
   8.129 +{
   8.130 +	unsigned long idx, vaddr = (unsigned long)ptr;
   8.131 +	pte_t *pte;
   8.132 +
   8.133 +	if (vaddr < FIXADDR_START)
   8.134 +		return virt_to_page(ptr);
   8.135 +
   8.136 +	idx = virt_to_fix(vaddr);
   8.137 +	pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
   8.138 +	return pte_page(*pte);
   8.139 +}
   8.140 +
     9.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c	Wed Aug 11 10:18:38 2004 +0000
     9.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c	Wed Aug 11 10:19:26 2004 +0000
     9.3 @@ -194,9 +194,17 @@ struct page *pte_alloc_one(struct mm_str
     9.4  	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
     9.5  #endif
     9.6  	if (pte) {
     9.7 +#ifdef CONFIG_HIGHPTE
     9.8 +		void *kaddr = kmap_atomic(pte, KM_USER0);
     9.9 +		clear_page(kaddr);
    9.10 +		kunmap_atomic_force(kaddr, KM_USER0);
    9.11 +#else
    9.12  		clear_highpage(pte);
    9.13 +#endif
    9.14 +#ifdef CONFIG_HIGHPTE
    9.15 +		if (pte < highmem_start_page)
    9.16 +#endif
    9.17  		__make_page_readonly(phys_to_virt(page_to_pseudophys(pte)));
    9.18 -				/* XXXcl highmem */
    9.19  	}
    9.20  	return pte;
    9.21  }
    9.22 @@ -250,16 +258,21 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
    9.23  	if (PTRS_PER_PMD == 1)
    9.24  		spin_lock_irqsave(&pgd_lock, flags);
    9.25  
    9.26 -	memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
    9.27 -			swapper_pg_dir + USER_PTRS_PER_PGD,
    9.28 -			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
    9.29 +	memcpy((pgd_t *)pgd,
    9.30 +			swapper_pg_dir,
    9.31 +			FIRST_USER_PGD_NR * sizeof(pgd_t));
    9.32 +	memcpy((pgd_t *)pgd + FIRST_USER_PGD_NR + USER_PTRS_PER_PGD,
    9.33 +			swapper_pg_dir + FIRST_USER_PGD_NR + USER_PTRS_PER_PGD,
    9.34 +			(PTRS_PER_PGD - USER_PTRS_PER_PGD -
    9.35 +			 FIRST_USER_PGD_NR) * sizeof(pgd_t));
    9.36  
    9.37  	if (PTRS_PER_PMD > 1)
    9.38  		goto out;
    9.39  
    9.40  	pgd_list_add(pgd);
    9.41  	spin_unlock_irqrestore(&pgd_lock, flags);
    9.42 -	memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
    9.43 +	memset((pgd_t *)pgd + FIRST_USER_PGD_NR,
    9.44 +			0, USER_PTRS_PER_PGD*sizeof(pgd_t));
    9.45   out:
    9.46  	__make_page_readonly(pgd);
    9.47  	queue_pgd_pin(__pa(pgd));
    10.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c	Wed Aug 11 10:18:38 2004 +0000
    10.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c	Wed Aug 11 10:19:26 2004 +0000
    10.3 @@ -383,21 +383,10 @@ void ctrl_if_suspend(void)
    10.4      unbind_evtchn_from_irq(ctrl_if_evtchn);
    10.5  }
    10.6  
    10.7 -/** Reset the control interface progress pointers.
    10.8 - * Marks the queues empty if 'clear' non-zero.
    10.9 - */
   10.10 -void ctrl_if_reset(int clear){
   10.11 +void ctrl_if_resume(void)
   10.12 +{
   10.13      control_if_t *ctrl_if = get_ctrl_if();
   10.14  
   10.15 -    if(clear){
   10.16 -        *ctrl_if = (control_if_t){};
   10.17 -    }
   10.18 -    ctrl_if_tx_resp_cons = ctrl_if->tx_resp_prod;
   10.19 -    ctrl_if_rx_req_cons  = ctrl_if->rx_resp_prod;
   10.20 -}
   10.21 -
   10.22 -void ctrl_if_resume(void)
   10.23 -{
   10.24      if ( start_info.flags & SIF_INITDOMAIN )
   10.25      {
   10.26          /*
   10.27 @@ -415,7 +404,9 @@ void ctrl_if_resume(void)
   10.28          initdom_ctrlif_domcontroller_port   = op.u.bind_interdomain.port2;
   10.29      }
   10.30  
   10.31 -    ctrl_if_reset(0);
   10.32 +    /* Sync up with shared indexes. */
   10.33 +    ctrl_if_tx_resp_cons = ctrl_if->tx_resp_prod;
   10.34 +    ctrl_if_rx_req_cons  = ctrl_if->rx_resp_prod;
   10.35  
   10.36      ctrl_if_evtchn = start_info.domain_controller_evtchn;
   10.37      ctrl_if_irq    = bind_evtchn_to_irq(ctrl_if_evtchn);
   10.38 @@ -444,7 +435,6 @@ void __init ctrl_if_init(void)
   10.39  
   10.40      spin_lock_init(&ctrl_if_lock);
   10.41  
   10.42 -    ctrl_if_reset(1);
   10.43      ctrl_if_resume();
   10.44  }
   10.45  
   10.46 @@ -455,8 +445,8 @@ static int __init ctrl_if_late_setup(voi
   10.47      safe_to_schedule_task = 1;
   10.48  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   10.49      ctrl_if_tx_wq = create_workqueue("ctrl_if_tx");
   10.50 -    if (ctrl_if_tx_wq == NULL)
   10.51 -        return 1;                 /* XXX */
   10.52 +    if ( ctrl_if_tx_wq == NULL )
   10.53 +        return 1;
   10.54  #endif
   10.55      return 0;
   10.56  }
    11.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c	Wed Aug 11 10:18:38 2004 +0000
    11.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c	Wed Aug 11 10:19:26 2004 +0000
    11.3 @@ -22,6 +22,11 @@
    11.4  #include <asm-xen/ctrl_if.h>
    11.5  #include <asm-xen/hypervisor.h>
    11.6  
    11.7 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    11.8 +EXPORT_SYMBOL(force_evtchn_callback);
    11.9 +EXPORT_SYMBOL(evtchn_do_upcall);
   11.10 +#endif
   11.11 +
   11.12  /*
   11.13   * This lock protects updates to the following mapping and reference-count
   11.14   * arrays. The lock does not need to be acquired to read the mapping tables.
   11.15 @@ -93,9 +98,6 @@ void evtchn_do_upcall(struct pt_regs *re
   11.16  
   11.17      local_irq_restore(flags);
   11.18  }
   11.19 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   11.20 -EXPORT_SYMBOL(evtchn_do_upcall);
   11.21 -#endif
   11.22  
   11.23  static int find_unbound_irq(void)
   11.24  {
    12.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Wed Aug 11 10:18:38 2004 +0000
    12.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Wed Aug 11 10:19:26 2004 +0000
    12.3 @@ -27,11 +27,12 @@
    12.4  #include <linux/sched.h>
    12.5  #include <linux/kernel.h>
    12.6  #include <linux/highmem.h>
    12.7 +#include <linux/vmalloc.h>
    12.8  #include <asm/fixmap.h>
    12.9  #include <asm/pgtable.h>
   12.10  #include <asm/uaccess.h>
   12.11  
   12.12 -#if 0
   12.13 +#if 1
   12.14  #define ASSERT(_p) \
   12.15      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   12.16      __LINE__, __FILE__); *(int*)0=0; }
   12.17 @@ -43,35 +44,57 @@
   12.18  #define DPRINTK(_f, _a...) ((void)0)
   12.19  #endif
   12.20  
   12.21 +static char            *fixup_buf;
   12.22 +#define FIXUP_BUF_USER  PAGE_SIZE
   12.23 +#define FIXUP_BUF_ORDER 1
   12.24 +#define FIXUP_BUF_SIZE  (PAGE_SIZE<<FIXUP_BUF_ORDER)
   12.25 +#define PATCH_LEN       5
   12.26 +
   12.27  struct fixup_entry {
   12.28 -    unsigned long  patch_addr;
   12.29 +    unsigned long  patch_addr; /* XXX */
   12.30      unsigned char  patched_code[20];
   12.31      unsigned short patched_code_len;
   12.32      unsigned short fixup_idx;
   12.33 +    unsigned short return_idx;
   12.34      struct fixup_entry *next;
   12.35  };
   12.36  
   12.37  #define FIXUP_HASHSZ 128
   12.38  static struct fixup_entry *fixup_hash[FIXUP_HASHSZ];
   12.39 -#define FIXUP_HASH(_a) ((unsigned int)(_a) & (FIXUP_HASHSZ-1))
   12.40 +static inline int FIXUP_HASH(char *b)
   12.41 +{
   12.42 +    int i, j = 0;
   12.43 +    for ( i = 0; i < PATCH_LEN; i++ )
   12.44 +        j ^= b[i];
   12.45 +    return j & (FIXUP_HASHSZ-1);
   12.46 +}
   12.47  
   12.48 +/* General instruction properties. */
   12.49  #define INSN_SUFFIX_BYTES (7)
   12.50  #define PREFIX_BYTE       (1<<3)
   12.51  #define OPCODE_BYTE       (1<<4)  
   12.52  #define HAS_MODRM         (1<<5)
   12.53  
   12.54 -#define X  0 /* invalid */
   12.55 +/* Helpful codes for the main decode routine. */
   12.56 +#define CODE_MASK         (3<<6)
   12.57 +#define PUSH              (0<<6) /* PUSH onto stack */
   12.58 +#define POP               (1<<6) /* POP from stack */
   12.59 +#define JMP               (2<<6) /* 8-bit relative JMP */
   12.60 +
   12.61 +/* Short forms for the table. */
   12.62 +#define X  0 /* invalid for some random reason */
   12.63 +#define S  0 /* invalid because it munges the stack */
   12.64  #define P  PREFIX_BYTE
   12.65  #define O  OPCODE_BYTE
   12.66  #define M  HAS_MODRM
   12.67  
   12.68  static unsigned char insn_decode[256] = {
   12.69      /* 0x00 - 0x0F */
   12.70 -    O|M, O|M, O|M, O|M, O|1, O|4, O, O,
   12.71 -    O|M, O|M, O|M, O|M, O|1, O|4, O, X,
   12.72 +    O|M, O|M, O|M, O|M, O|1, O|4, S, S,
   12.73 +    O|M, O|M, O|M, O|M, O|1, O|4, S, X,
   12.74      /* 0x10 - 0x1F */
   12.75 -    O|M, O|M, O|M, O|M, O|1, O|4, O, O,
   12.76 -    O|M, O|M, O|M, O|M, O|1, O|4, O, O,
   12.77 +    O|M, O|M, O|M, O|M, O|1, O|4, S, S,
   12.78 +    O|M, O|M, O|M, O|M, O|1, O|4, S, S,
   12.79      /* 0x20 - 0x2F */
   12.80      O|M, O|M, O|M, O|M, O|1, O|4, P, O,
   12.81      O|M, O|M, O|M, O|M, O|1, O|4, P, O,
   12.82 @@ -79,20 +102,20 @@ static unsigned char insn_decode[256] = 
   12.83      O|M, O|M, O|M, O|M, O|1, O|4, P, O,
   12.84      O|M, O|M, O|M, O|M, O|1, O|4, P, O,
   12.85      /* 0x40 - 0x4F */
   12.86 -    O, O, O, O, O, O, O, O,
   12.87 -    O, O, O, O, O, O, O, O,
   12.88 +    O, O, O, O, S, O, O, O,
   12.89 +    O, O, O, O, S, O, O, O,
   12.90      /* 0x50 - 0x5F */
   12.91 -    O, O, O, O, O, O, O, O,
   12.92 -    O, O, O, O, O, O, O, O,
   12.93 +    O|PUSH, O|PUSH, O|PUSH, O|PUSH, S, O|PUSH, O|PUSH, O|PUSH,
   12.94 +    O|POP, O|POP, O|POP, O|POP, S, O|POP, O|POP, O|POP,
   12.95      /* 0x60 - 0x6F */
   12.96 -    O, O, O|M, O|M, P, P, X, X,
   12.97 -    O|4, O|M|4, O|1, O|M|1, O, O, O, O,
   12.98 +    S, S, O|M, O|M, P, P, X, X,
   12.99 +    O|4|PUSH, O|M|4, O|1|PUSH, O|M|1, O, O, O, O,
  12.100      /* 0x70 - 0x7F */
  12.101 -    O|1, O|1, O|1, O|1, O|1, O|1, O|1, O|1,
  12.102 -    O|1, O|1, O|1, O|1, O|1, O|1, O|1, O|1,
  12.103 +    O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP,
  12.104 +    O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP, O|1|JMP,
  12.105      /* 0x80 - 0x8F */
  12.106      O|M|1, O|M|4, O|M|1, O|M|1, O|M, O|M, O|M, O|M,
  12.107 -    O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, 
  12.108 +    O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M|POP, 
  12.109      /* 0x90 - 0x9F */
  12.110      O, O, O, O, O, O, O, O,
  12.111      O, O, X, O, O, O, O, O,
  12.112 @@ -110,13 +133,15 @@ static unsigned char insn_decode[256] = 
  12.113      X, X, X, X, X, X, X, X,
  12.114      /* 0xE0 - 0xEF */
  12.115      X, X, X, X, X, X, X, X,
  12.116 -    X, O|4, X, O|1, X, X, X, X,
  12.117 +    X, O|4, X, O|1|JMP, X, X, X, X,
  12.118      /* 0xF0 - 0xFF */
  12.119      P, X, P, P, O, O, O|M|1, O|M|4, 
  12.120 -    O, O, O, O, O, O, O|M, O|M
  12.121 +    O, O, O, O, O, O, O|M, X
  12.122  };
  12.123  
  12.124 -static unsigned int get_insn_len(unsigned char *insn, unsigned char *p_opcode)
  12.125 +static unsigned int get_insn_len(unsigned char *insn, 
  12.126 +                                 unsigned char *p_opcode,
  12.127 +                                 unsigned char *p_decode)
  12.128  {
  12.129      unsigned char b, d, *pb, mod, rm;
  12.130  
  12.131 @@ -130,10 +155,14 @@ static unsigned int get_insn_len(unsigne
  12.132      }
  12.133  
  12.134      *p_opcode = b;
  12.135 +    *p_decode = d;
  12.136  
  12.137      /* 2. Ensure we have a valid opcode byte. */
  12.138      if ( !(d & OPCODE_BYTE) )
  12.139 +    {
  12.140 +        printk(KERN_ALERT " *** %02x %02x %02x\n", pb[0], pb[1], pb[2]);
  12.141          return 0;
  12.142 +    }
  12.143  
  12.144      /* 3. Process Mod/RM if there is one. */
  12.145      if ( d & HAS_MODRM )
  12.146 @@ -175,13 +204,10 @@ static unsigned char handleable_code[32]
  12.147  asmlinkage void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
  12.148  {
  12.149      static unsigned int fixup_idx = 0;
  12.150 -    int relbyte_idx = -1, relword_idx = -1, save_indirect_reg;
  12.151 +    unsigned int fi;
  12.152 +    int save_indirect_reg, hash;
  12.153      unsigned int insn_len = (unsigned int)error_code, new_insn_len;
  12.154 -    unsigned char b[20], modrm, mod, reg, rm, patch[5], opcode;
  12.155 -    unsigned char *fixup_buf = 
  12.156 -        (unsigned char *)fix_to_virt(FIX_4GB_SEGMENT_FIXUP_RW);
  12.157 -    unsigned long fixup_buf_user = 
  12.158 -        fix_to_virt(FIX_4GB_SEGMENT_FIXUP_RO);
  12.159 +    unsigned char b[20], modrm, mod, reg, rm, patch[PATCH_LEN], opcode, decode;
  12.160      unsigned long eip = regs->eip - insn_len;
  12.161      struct fixup_entry *fe;
  12.162      pte_t *pte;
  12.163 @@ -198,28 +224,50 @@ asmlinkage void do_fixup_4gb_segment(str
  12.164  
  12.165      if ( unlikely(eip >= (PAGE_OFFSET-32)) )
  12.166      {
  12.167 -        if ( (eip < fixup_buf_user) || (eip >= (fixup_buf_user+PAGE_SIZE-32)) )
  12.168 +        DPRINTK("User executing out of kernel space?!");
  12.169 +        return;
  12.170 +    }
  12.171 +    
  12.172 +    if ( unlikely(((eip ^ (eip+PATCH_LEN)) & PAGE_MASK) != 0) )
  12.173 +    {
  12.174 +        DPRINTK("Patch instruction would straddle a page boundary.");
  12.175 +        return;
  12.176 +    }
  12.177 +
  12.178 +    /*
  12.179 +     * Check that the page to be patched is part of a read-only VMA. This 
  12.180 +     * means that our patch will never erroneously get flushed to disc.
  12.181 +     */
  12.182 +    if ( eip > (FIXUP_BUF_USER + FIXUP_BUF_SIZE) ) /* don't check fixup area */
  12.183 +    {
  12.184 +        /* [SMP] Need to the mmap_sem semaphore. */
  12.185 +        struct vm_area_struct *vma = find_vma(current->mm, eip);
  12.186 +        if ( (vma == NULL) || (vma->vm_flags & VM_MAYSHARE) )
  12.187          {
  12.188 -            DPRINTK("User executing out of kernel space?!");
  12.189 +            DPRINTK("Cannot patch a shareable VMA.");
  12.190              return;
  12.191          }
  12.192 -        /* We know it's safe to directly copy teh bytes into our buffer. */
  12.193 -        memcpy(b, (void *)eip, sizeof(b));
  12.194      }
  12.195 -    else if ( unlikely(copy_from_user(b, (void *)eip, sizeof(b)) != 0) )
  12.196 +
  12.197 +    if ( unlikely(copy_from_user(b, (void *)eip, sizeof(b)) != 0) )
  12.198      {
  12.199          DPRINTK("Could not read instruction bytes from user space.");
  12.200          return;
  12.201      }
  12.202  
  12.203 -    if ( unlikely(((eip ^ (eip+5)) & PAGE_MASK) != 0) )
  12.204 +    /* Already created a fixup for this address and code sequence? */
  12.205 +    hash = FIXUP_HASH(b);
  12.206 +    for ( fe = fixup_hash[hash];
  12.207 +          fe != NULL; fe = fe->next )
  12.208      {
  12.209 -        DPRINTK("Patch instruction would straddle a page boundary.");
  12.210 -        return;
  12.211 +        if ( eip != fe->patch_addr )
  12.212 +            continue; /* XXX */
  12.213 +        if ( memcmp(fe->patched_code, b, fe->patched_code_len) == 0 )
  12.214 +            goto do_the_patch;
  12.215      }
  12.216  
  12.217      /* Guaranteed enough room to patch? */
  12.218 -    if ( unlikely(fixup_idx > (PAGE_SIZE-32)) )
  12.219 +    if ( unlikely((fi = fixup_idx) > (FIXUP_BUF_SIZE-32)) )
  12.220      {
  12.221          static int printed = 0;
  12.222          if ( !printed )
  12.223 @@ -268,40 +316,105 @@ asmlinkage void do_fixup_4gb_segment(str
  12.224          return;
  12.225      }
  12.226  
  12.227 -    while ( insn_len < 5 )
  12.228 +    /* Indirect jump pointer. */
  12.229 +    *(u32 *)&fixup_buf[fi] = FIXUP_BUF_USER + fi + 4;
  12.230 +    fi += 4;
  12.231 +
  12.232 +    /* push <r32> */
  12.233 +    if ( save_indirect_reg )
  12.234 +        fixup_buf[fi++] = 0x50 + rm;
  12.235 +
  12.236 +    /* add %gs:0,<r32> */
  12.237 +    fixup_buf[fi++] = 0x65;
  12.238 +    fixup_buf[fi++] = 0x03;
  12.239 +    fixup_buf[fi++] = 0x05 | (rm << 3);
  12.240 +    *(unsigned long *)&fixup_buf[fi] = 0;
  12.241 +    fi += 4;
  12.242 +
  12.243 +    /* Relocate the faulting instruction, minus the GS override. */
  12.244 +    memcpy(&fixup_buf[fi], &b[1], error_code - 1);
  12.245 +    fi += error_code - 1;
  12.246 +
  12.247 +    /* pop <r32> */
  12.248 +    if ( save_indirect_reg )
  12.249 +        fixup_buf[fi++] = 0x58 + rm;
  12.250 +
  12.251 +    for ( ; ; )
  12.252      {
  12.253 +        if ( insn_len >= PATCH_LEN )
  12.254 +        {
  12.255 +            /* ret */
  12.256 +            fixup_buf[fi++] = 0xc3;
  12.257 +            break;
  12.258 +        }
  12.259 +
  12.260          /* Bail if can't decode the following instruction. */
  12.261          if ( unlikely((new_insn_len =
  12.262 -                       get_insn_len(&b[insn_len], &opcode)) == 0) )
  12.263 +                       get_insn_len(&b[insn_len], &opcode, &decode)) == 0) )
  12.264          {
  12.265              DPRINTK("Could not decode following instruction.");
  12.266              return;
  12.267          }
  12.268  
  12.269 -        /* We track one 8-bit relative offset for patching later. */
  12.270 -        if ( ((opcode >= 0x70) && (opcode <= 0x7f)) || (opcode == 0xeb) )
  12.271 +        if ( (decode & CODE_MASK) == JMP )
  12.272          {
  12.273 -            if ( relbyte_idx != -1 )
  12.274 -            {
  12.275 -                DPRINTK("Multiple relative offsets in patch seq!");
  12.276 -                return;
  12.277 -            }
  12.278 -            relbyte_idx = insn_len;
  12.279 -            while ( b[relbyte_idx] != opcode )
  12.280 -                relbyte_idx++;
  12.281 -            relbyte_idx++;
  12.282 +            return;
  12.283 +
  12.284 +            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 1);
  12.285 +            fi += new_insn_len - 1;
  12.286 +            
  12.287 +            /* Patch the 8-bit relative offset. */
  12.288 +            fixup_buf[fi++] = 1;
  12.289 +
  12.290 +            insn_len += new_insn_len;
  12.291 +            ASSERT(insn_len >= PATCH_LEN);
  12.292 +        
  12.293 +            /* ret */
  12.294 +            fixup_buf[fi++] = 0xc3;
  12.295 +
  12.296 +            /* jmp <rel32> */
  12.297 +            fixup_buf[fi++] = 0xe9;
  12.298 +            fi += 4;
  12.299 +            *(unsigned long *)&fixup_buf[fi-4] = 
  12.300 +                (eip + insn_len + (long)(char)b[insn_len-1]) - 
  12.301 +                (FIXUP_BUF_USER + fi);
  12.302 +            
  12.303 +            break;
  12.304          }
  12.305          else if ( opcode == 0xe9 )
  12.306          {
  12.307 -            if ( relword_idx != -1 )
  12.308 -            {
  12.309 -                DPRINTK("Multiple relative offsets in patch seq!");
  12.310 -                return;
  12.311 -            }
  12.312 -            relword_idx = insn_len;
  12.313 -            while ( b[relword_idx] != opcode )
  12.314 -                relword_idx++;
  12.315 -            relword_idx++;
  12.316 +            return;
  12.317 +
  12.318 +            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 4);
  12.319 +            fi += new_insn_len - 4;
  12.320 +            
  12.321 +            insn_len += new_insn_len;
  12.322 +            ASSERT(insn_len >= PATCH_LEN);
  12.323 +        
  12.324 +            /* Patch the 32-bit relative offset. */
  12.325 +            fi += 4;
  12.326 +            *(unsigned long *)&fixup_buf[fi-4] = 
  12.327 +                (eip + insn_len + *(long *)&b[insn_len-4]) - 
  12.328 +                (FIXUP_BUF_USER + fi);
  12.329 +
  12.330 +            /* ret */
  12.331 +            fixup_buf[fi++] = 0xc3;
  12.332 +
  12.333 +            break;
  12.334 +        }
  12.335 +        else if ( (decode & CODE_MASK) == PUSH )
  12.336 +        {
  12.337 +            return;
  12.338 +        }
  12.339 +        else if ( (decode & CODE_MASK) == POP )
  12.340 +        {
  12.341 +            return;
  12.342 +        }
  12.343 +        else
  12.344 +        {
  12.345 +            /* Relocate the instruction verbatim. */
  12.346 +            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len);
  12.347 +            fi += new_insn_len;
  12.348          }
  12.349  
  12.350          if ( (insn_len += new_insn_len) > 20 )
  12.351 @@ -310,132 +423,84 @@ asmlinkage void do_fixup_4gb_segment(str
  12.352              return;
  12.353          }
  12.354  
  12.355 -        /* The instructions together must be no smaller than 'jmp <disp32>'. */
  12.356 -        if ( insn_len >= 5 )
  12.357 -            break;
  12.358 -
  12.359          /* Can't have a RET in the middle of a patch sequence. */
  12.360 -        if ( opcode == 0xc4 )
  12.361 +        if ( (opcode == 0xc4) && (insn_len < PATCH_LEN) )
  12.362          {
  12.363              DPRINTK("RET in middle of patch seq!\n");
  12.364              return;
  12.365          }
  12.366      }
  12.367  
  12.368 -    /* Already created a fixup for this address and code sequence? */
  12.369 -    for ( fe = fixup_hash[FIXUP_HASH(eip)];
  12.370 -          fe != NULL; fe = fe->next )
  12.371 -    {
  12.372 -        if ( (fe->patch_addr == eip) &&
  12.373 -             (fe->patched_code_len == insn_len) &&
  12.374 -             (memcmp(fe->patched_code, b, insn_len) == 0) )
  12.375 -            goto do_the_patch;
  12.376 -    }
  12.377 -
  12.378 -    /* No existing patch -- create an entry for one. */
  12.379 +    /* Create an entry for a new fixup patch. */
  12.380      fe = kmalloc(sizeof(struct fixup_entry), GFP_KERNEL);
  12.381      if ( unlikely(fe == NULL) )
  12.382      {
  12.383          DPRINTK("Not enough memory to allocate a fixup_entry.");
  12.384          return;
  12.385      }
  12.386 -    fe->patch_addr = eip;
  12.387 +    fe->patch_addr = eip; /* XXX */
  12.388      fe->patched_code_len = insn_len;
  12.389      memcpy(fe->patched_code, b, insn_len);
  12.390      fe->fixup_idx = fixup_idx;
  12.391 -    fe->next = fixup_hash[FIXUP_HASH(eip)];
  12.392 -    fixup_hash[FIXUP_HASH(eip)] = fe;
  12.393 -    
  12.394 -    /* push <r32> */
  12.395 -    if ( save_indirect_reg )
  12.396 -        fixup_buf[fixup_idx++] = 0x50 + rm;
  12.397 +    fe->return_idx = 
  12.398 +        fixup_idx + error_code + 6 + 4/**/ + (save_indirect_reg ? 2 : 0);
  12.399 +    fe->next = fixup_hash[hash];
  12.400 +    fixup_hash[hash] = fe;
  12.401 +
  12.402 +    /* Commit the patch. */
  12.403 +    fixup_idx = fi;
  12.404  
  12.405 -    /* add %gs:0,<r32> */
  12.406 -    fixup_buf[fixup_idx++] = 0x65;
  12.407 -    fixup_buf[fixup_idx++] = 0x03;
  12.408 -    fixup_buf[fixup_idx++] = 0x05 | (rm << 3);
  12.409 -    *(unsigned long *)&fixup_buf[fixup_idx] = 0;
  12.410 -    fixup_idx += 4;
  12.411 + do_the_patch:
  12.412 +#if 1
  12.413 +    /* Create the patching instruction in a temporary buffer. */
  12.414 +    patch[0] = 0x67;
  12.415 +    patch[1] = 0xff;
  12.416 +    patch[2] = 0x16; /* call <r/m16> */
  12.417 +    *(u16 *)&patch[3] = FIXUP_BUF_USER + fe->fixup_idx;
  12.418 +#else
  12.419 +    patch[0] = 0x9a;
  12.420 +    *(u32 *)&patch[1] = FIXUP_BUF_USER + fe->fixup_idx + 4;
  12.421 +    *(u16 *)&patch[5] = __USER_CS;
  12.422 +#endif
  12.423  
  12.424 -    /* First relocated instruction, minus the GS override. */
  12.425 -    memcpy(&fixup_buf[fixup_idx], &b[1], error_code - 1);
  12.426 -    fixup_idx += error_code - 1;
  12.427 +#if 1
  12.428 +    {
  12.429 +        int iii;
  12.430 +        printk(KERN_ALERT "EIP == %08lx; USER_EIP == %08lx\n",
  12.431 +               eip, FIXUP_BUF_USER + fe->fixup_idx);
  12.432 +        printk(KERN_ALERT " .byte ");
  12.433 +        for ( iii = 0; iii < insn_len; iii++ )
  12.434 +            printk("0x%02x,", b[iii]);
  12.435 +        printk("!!\n");
  12.436 +        printk(KERN_ALERT " .byte ");
  12.437 +        for ( iii = fe->fixup_idx; iii < fi; iii++ )
  12.438 +            printk("0x%02x,", (unsigned char)fixup_buf[iii]);
  12.439 +        printk("!!\n");
  12.440 +        printk(KERN_ALERT " .byte ");
  12.441 +        for ( iii = 0; iii < 7; iii++ )
  12.442 +            printk("0x%02x,", (unsigned char)patch[iii]);
  12.443 +        printk("!!\n");
  12.444 +    }
  12.445 +#endif
  12.446  
  12.447 -    /* pop <r32> */
  12.448 -    if ( save_indirect_reg )
  12.449 -        fixup_buf[fixup_idx++] = 0x58 + rm;
  12.450 -
  12.451 -    if ( insn_len != error_code )
  12.452 +    if ( put_user(eip + insn_len, (unsigned long *)regs->esp - 1) != 0 )
  12.453      {
  12.454 -        /* Relocated instructions. */
  12.455 -        memcpy(&fixup_buf[fixup_idx], &b[error_code], insn_len - error_code);
  12.456 -        fixup_idx += insn_len - error_code;
  12.457 +        DPRINTK("Failed to place return address on user stack.");
  12.458 +        return;
  12.459      }
  12.460  
  12.461 -    /* jmp <rel32> */
  12.462 -    fixup_buf[fixup_idx++] = 0xe9;
  12.463 -    fixup_idx += 4;
  12.464 -    *(unsigned long *)&fixup_buf[fixup_idx-4] = 
  12.465 -        (eip + insn_len) - (fixup_buf_user + fixup_idx);
  12.466 -
  12.467 -    if ( relbyte_idx != -1 )
  12.468 -    {
  12.469 -        /* Patch the 8-bit relative offset. */
  12.470 -        int idx = fe->fixup_idx + relbyte_idx + 6;
  12.471 -        if ( save_indirect_reg )
  12.472 -            idx += 2;
  12.473 -        fixup_buf[idx] = fixup_idx - (idx + 1);
  12.474 -        
  12.475 -        /* jmp <rel32> */
  12.476 -        fixup_buf[fixup_idx++] = 0xe9;
  12.477 -        fixup_idx += 4;
  12.478 -        *(unsigned long *)&fixup_buf[fixup_idx-4] = 
  12.479 -            (eip + relbyte_idx + 1 + (long)(char)b[relbyte_idx]) - 
  12.480 -            (fixup_buf_user + fixup_idx);
  12.481 -    }
  12.482 -    else if ( relword_idx != -1 )
  12.483 -    {
  12.484 -        /* Patch the 32-bit relative offset by subtracting the code disp. */
  12.485 -        int idx = fe->fixup_idx + relword_idx + 6;
  12.486 -        if ( save_indirect_reg )
  12.487 -            idx += 2;
  12.488 -        *(unsigned long *)&fixup_buf[idx] +=
  12.489 -            (eip + relword_idx) - (fixup_buf_user + idx);
  12.490 -    }
  12.491 -
  12.492 - do_the_patch:
  12.493 -    /* Create the patching instruction in a temporary buffer. */
  12.494 -    patch[0] = 0xe9;
  12.495 -    *(unsigned long *)&patch[1] = 
  12.496 -        (fixup_buf_user + fe->fixup_idx) - (eip + 5);
  12.497 -
  12.498 -    /*
  12.499 -     * Check that the page to be patched is part of a read-only VMA. This 
  12.500 -     * means that our patch will never erroneously get flushed to disc.
  12.501 -     */
  12.502 -    if ( eip < PAGE_OFFSET ) /* don't need to check the fixmap area */
  12.503 -    {
  12.504 -        /* [SMP] Need to the mmap_sem semaphore. */
  12.505 -        struct vm_area_struct *vma = find_vma(current->mm, eip);
  12.506 -        if ( (vma == NULL) || (vma->vm_flags & VM_MAYSHARE) )
  12.507 -        {
  12.508 -            DPRINTK("Cannot patch a shareable VMA.");
  12.509 -            return;
  12.510 -        }
  12.511 -    }
  12.512 +    /* Success! Return to user land to execute 2nd insn of the pair. */
  12.513 +    regs->esp -= 4;
  12.514 +    regs->eip = FIXUP_BUF_USER + fe->return_idx;
  12.515  
  12.516      /* [SMP] Need to pause other threads while patching. */
  12.517      pgd = pgd_offset(current->mm, eip);
  12.518      pmd = pmd_offset(pgd, eip);
  12.519      pte = pte_offset_kernel(pmd, eip);
  12.520      veip = kmap(pte_page(*pte));
  12.521 -    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, 5);
  12.522 +    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, PATCH_LEN);
  12.523      kunmap(pte_page(*pte));
  12.524  
  12.525 -    /* Success! Return to user land to execute 2nd insn of the pair. */
  12.526 -    regs->eip = fixup_buf_user + fe->fixup_idx + error_code + 6;
  12.527 -    if ( save_indirect_reg )
  12.528 -        regs->eip += 2;
  12.529      return;
  12.530  }
  12.531  
  12.532 @@ -443,17 +508,24 @@ static int nosegfixup = 0;
  12.533  
  12.534  static int __init fixup_init(void)
  12.535  {
  12.536 -    unsigned long page;
  12.537 +    struct vm_struct vma;
  12.538 +    struct page *_pages[1<<FIXUP_BUF_ORDER], **pages=_pages;
  12.539 +    int i;
  12.540  
  12.541 -    if ( nosegfixup )
  12.542 +    /*if ( nosegfixup )*/
  12.543          return 0;
  12.544  
  12.545      HYPERVISOR_vm_assist(VMASST_CMD_enable,
  12.546                           VMASST_TYPE_4gb_segments_notify);
  12.547  
  12.548 -    page = get_zeroed_page(GFP_ATOMIC);
  12.549 -    __set_fixmap(FIX_4GB_SEGMENT_FIXUP_RO, __pa(page), PAGE_READONLY);
  12.550 -    __set_fixmap(FIX_4GB_SEGMENT_FIXUP_RW, __pa(page), PAGE_KERNEL);
  12.551 +    fixup_buf = (char *)__get_free_pages(GFP_ATOMIC, FIXUP_BUF_ORDER);
  12.552 +    for ( i = 0; i < (1<<FIXUP_BUF_ORDER); i++ )
  12.553 +        _pages[i] = virt_to_page(fixup_buf) + i;
  12.554 +
  12.555 +    vma.addr = (void *)FIXUP_BUF_USER;
  12.556 +    vma.size = FIXUP_BUF_SIZE + PAGE_SIZE; /* fucking stupid interface */
  12.557 +    if ( map_vm_area(&vma, PAGE_READONLY, &pages) != 0 )
  12.558 +        BUG();
  12.559  
  12.560      memset(fixup_hash, 0, sizeof(fixup_hash));
  12.561  
    13.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c	Wed Aug 11 10:18:38 2004 +0000
    13.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c	Wed Aug 11 10:19:26 2004 +0000
    13.3 @@ -874,4 +874,21 @@ static int __init netif_init(void)
    13.4      return err;
    13.5  }
    13.6  
    13.7 +void netif_resume(void)
    13.8 +{
    13.9 +    ctrl_msg_t                       cmsg;
   13.10 +    netif_fe_driver_status_changed_t st;
   13.11 +
   13.12 +    /* Send a driver-UP notification to the domain controller. */
   13.13 +    cmsg.type      = CMSG_NETIF_FE;
   13.14 +    cmsg.subtype   = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
   13.15 +    cmsg.length    = sizeof(netif_fe_driver_status_changed_t);
   13.16 +    st.status      = NETIF_DRIVER_STATUS_UP;
   13.17 +    st.nr_interfaces = 0;
   13.18 +    memcpy(cmsg.msg, &st, sizeof(st));
   13.19 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   13.20 +
   13.21 +}
   13.22 +
   13.23 +
   13.24  __initcall(netif_init);
    14.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Wed Aug 11 10:18:38 2004 +0000
    14.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Wed Aug 11 10:19:26 2004 +0000
    14.3 @@ -44,8 +44,6 @@
    14.4  enum fixed_addresses {
    14.5  	FIX_HOLE,
    14.6  	FIX_VSYSCALL,
    14.7 -	FIX_4GB_SEGMENT_FIXUP_RO,
    14.8 -	FIX_4GB_SEGMENT_FIXUP_RW,
    14.9  #ifdef CONFIG_X86_LOCAL_APIC
   14.10  	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
   14.11  #endif
   14.12 @@ -128,8 +126,8 @@ extern void __set_fixmap_ma (enum fixed_
   14.13   * This is the range that is readable by user mode, and things
   14.14   * acting like user mode such as get_user_pages.
   14.15   */
   14.16 -#define FIXADDR_USER_START	(__fix_to_virt(FIX_4GB_SEGMENT_FIXUP_RO))
   14.17 -#define FIXADDR_USER_END	(FIXADDR_USER_START + (2*PAGE_SIZE))
   14.18 +#define FIXADDR_USER_START	(__fix_to_virt(FIX_VSYSCALL))
   14.19 +#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
   14.20  
   14.21  
   14.22  extern void __this_fixmap_does_not_exist(void);
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/highmem.h	Wed Aug 11 10:19:26 2004 +0000
    15.3 @@ -0,0 +1,72 @@
    15.4 +/*
    15.5 + * highmem.h: virtual kernel memory mappings for high memory
    15.6 + *
    15.7 + * Used in CONFIG_HIGHMEM systems for memory pages which
    15.8 + * are not addressable by direct kernel virtual addresses.
    15.9 + *
   15.10 + * Copyright (C) 1999 Gerhard Wichert, Siemens AG
   15.11 + *		      Gerhard.Wichert@pdb.siemens.de
   15.12 + *
   15.13 + *
   15.14 + * Redesigned the x86 32-bit VM architecture to deal with 
   15.15 + * up to 16 Terabyte physical memory. With current x86 CPUs
   15.16 + * we now support up to 64 Gigabytes physical RAM.
   15.17 + *
   15.18 + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
   15.19 + */
   15.20 +
   15.21 +#ifndef _ASM_HIGHMEM_H
   15.22 +#define _ASM_HIGHMEM_H
   15.23 +
   15.24 +#ifdef __KERNEL__
   15.25 +
   15.26 +#include <linux/config.h>
   15.27 +#include <linux/interrupt.h>
   15.28 +#include <linux/threads.h>
   15.29 +#include <asm/kmap_types.h>
   15.30 +#include <asm/tlbflush.h>
   15.31 +
   15.32 +/* declarations for highmem.c */
   15.33 +extern unsigned long highstart_pfn, highend_pfn;
   15.34 +
   15.35 +extern pte_t *kmap_pte;
   15.36 +extern pgprot_t kmap_prot;
   15.37 +extern pte_t *pkmap_page_table;
   15.38 +
   15.39 +extern void kmap_init(void);
   15.40 +
   15.41 +/*
   15.42 + * Right now we initialize only a single pte table. It can be extended
   15.43 + * easily, subsequent pte tables have to be allocated in one physical
   15.44 + * chunk of RAM.
   15.45 + */
   15.46 +#if NR_CPUS <= 32
   15.47 +#define PKMAP_BASE (HYPERVISOR_VIRT_START - (1<<23))
   15.48 +#else
   15.49 +#define PKMAP_BASE (HYPERVISOR_VIRT_START - (1<<23) - 0x200000UL)
   15.50 +#endif
   15.51 +#ifdef CONFIG_X86_PAE
   15.52 +#define LAST_PKMAP 512
   15.53 +#else
   15.54 +#define LAST_PKMAP 1024
   15.55 +#endif
   15.56 +#define LAST_PKMAP_MASK (LAST_PKMAP-1)
   15.57 +#define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
   15.58 +#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
   15.59 +
   15.60 +extern void * FASTCALL(kmap_high(struct page *page));
   15.61 +extern void FASTCALL(kunmap_high(struct page *page));
   15.62 +
   15.63 +void *kmap(struct page *page);
   15.64 +void kunmap(struct page *page);
   15.65 +void *kmap_atomic(struct page *page, enum km_type type);
   15.66 +void *kmap_atomic_pte(struct page *page, enum km_type type);
   15.67 +void kunmap_atomic(void *kvaddr, enum km_type type);
   15.68 +void kunmap_atomic_force(void *kvaddr, enum km_type type);
   15.69 +struct page *kmap_atomic_to_page(void *ptr);
   15.70 +
   15.71 +#define flush_cache_kmaps()	do { } while (0)
   15.72 +
   15.73 +#endif /* __KERNEL__ */
   15.74 +
   15.75 +#endif /* _ASM_HIGHMEM_H */
    16.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Wed Aug 11 10:18:38 2004 +0000
    16.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Wed Aug 11 10:19:26 2004 +0000
    16.3 @@ -64,16 +64,17 @@ void paging_init(void);
    16.4  #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
    16.5  #define PGDIR_MASK	(~(PGDIR_SIZE-1))
    16.6  
    16.7 -#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
    16.8 -#define FIRST_USER_PGD_NR	0
    16.9 +#define FIRST_USER_PGD_NR	1
   16.10 +#define USER_PTRS_PER_PGD	((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
   16.11  
   16.12 +#if 0 /* XEN */
   16.13  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
   16.14  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
   16.15  
   16.16  #define TWOLEVEL_PGDIR_SHIFT	22
   16.17  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
   16.18  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
   16.19 -
   16.20 +#endif
   16.21  
   16.22  #ifndef __ASSEMBLY__
   16.23  /* Just any arbitrary offset to the start of the vmalloc VM area: the
   16.24 @@ -333,9 +334,11 @@ static inline pte_t pte_modify(pte_t pte
   16.25  
   16.26  #if defined(CONFIG_HIGHPTE)
   16.27  #define pte_offset_map(dir, address) \
   16.28 -	((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
   16.29 +	((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + \
   16.30 +	 pte_index(address))
   16.31  #define pte_offset_map_nested(dir, address) \
   16.32 -	((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address))
   16.33 +	((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE1) + \
   16.34 +	 pte_index(address))
   16.35  #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
   16.36  #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
   16.37  #else
    21.1 --- a/tools/libxc/xc_linux_restore.c	Wed Aug 11 10:18:38 2004 +0000
    21.2 +++ b/tools/libxc/xc_linux_restore.c	Wed Aug 11 10:19:26 2004 +0000
    21.3 @@ -224,8 +224,7 @@ int xc_linux_restore(int xc_handle, XcIO
    21.4  
    21.5      /* XXX create domain on CPU=-1 so that in future it auto load ballances by default */
    21.6      if ( xc_domain_create( xc_handle,  nr_pfns * (PAGE_SIZE / 1024),
    21.7 -			   name,
    21.8 -			   -1, &dom ) )
    21.9 +			   name, -1, &dom ) )
   21.10      {
   21.11  	xcio_error(ioctxt, "Could not create domain. pfns=%d, %dKB",
   21.12  		   nr_pfns,nr_pfns * (PAGE_SIZE / 1024));
    25.1 --- a/xen/arch/x86/Rules.mk	Wed Aug 11 10:18:38 2004 +0000
    25.2 +++ b/xen/arch/x86/Rules.mk	Wed Aug 11 10:19:26 2004 +0000
    25.3 @@ -8,6 +8,9 @@ CFLAGS  := -nostdinc -fno-builtin -fno-c
    25.4  CFLAGS  += -iwithprefix include -Wall -Werror -fomit-frame-pointer -pipe
    25.5  CFLAGS  += -I$(BASEDIR)/include -Wno-pointer-arith -Wredundant-decls
    25.6  
    25.7 +# Prevent floating-point variables from creeping into Xen.
    25.8 +CFLAGS  += -msoft-float
    25.9 +
   25.10  ifeq ($(TARGET_SUBARCH),x86_32)
   25.11  CFLAGS  += -m32 -march=i686
   25.12  LDFLAGS := --oformat elf32-i386 
    32.1 --- a/xen/common/sched_fair_bvt.c	Wed Aug 11 10:18:38 2004 +0000
    32.2 +++ b/xen/common/sched_fair_bvt.c	Wed Aug 11 10:19:26 2004 +0000
    32.3 @@ -252,7 +252,7 @@ static void fbvt_wake(struct domain *d)
    32.4           * values, the virtual time can be determined as:
    32.5           * SVT - const * TIME_SLEPT
    32.6           */
    32.7 -        io_warp = (int)(0.5 * inf->time_slept);
    32.8 +        io_warp = inf->time_slept/2;
    32.9          if ( io_warp > 1000 )
   32.10              io_warp = 1000;
   32.11  
   32.12 @@ -551,7 +551,7 @@ static task_slice_t fbvt_do_schedule(s_t
   32.13       * domains earlier in virtual time). Together this should give quite
   32.14       * good control both for CPU and IO-bound domains.
   32.15       */
   32.16 -    LAST_VTB(cpu) = (int)(0.2 * next_inf->time_slept);
   32.17 +    LAST_VTB(cpu) = next_inf->time_slept/5;
   32.18      if(LAST_VTB(cpu) / next_inf->mcu_advance > max_vtb / MCU) 
   32.19          LAST_VTB(cpu) = max_vtb * next_inf->mcu_advance / MCU;
   32.20