ia64/xen-unstable

changeset 3009:f0fe276ae088

bitkeeper revision 1.1159.1.429 (419b24f2Eb_QhjT-WzlSl5_8eiYX7w)

sync w/ head.
author cl349@freefall.cl.cam.ac.uk
date Wed Nov 17 10:16:18 2004 +0000 (2004-11-17)
parents 7d1e3f96a1b8 a38b578f1146
children cf2447c5a0c6
files Makefile buildconfigs/Rules.mk linux-2.4.27-xen-sparse/arch/xen/kernel/entry.S linux-2.4.27-xen-sparse/arch/xen/kernel/traps.c linux-2.4.27-xen-sparse/include/asm-xen/irq.h linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig linux-2.6.9-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6.9-xen-sparse/drivers/char/mem.c linux-2.6.9-xen-sparse/drivers/char/tty_io.c linux-2.6.9-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6.9-xen-sparse/drivers/xen/evtchn/evtchn.c linux-2.6.9-xen-sparse/include/asm-generic/pgtable.h linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable.h tools/examples/init.d/xend tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/netif.py xen/arch/x86/memory.c xen/common/keyhandler.c
line diff
     1.1 --- a/Makefile	Tue Nov 16 18:59:47 2004 +0000
     1.2 +++ b/Makefile	Wed Nov 17 10:16:18 2004 +0000
     1.3 @@ -5,25 +5,23 @@
     1.4  DIST_DIR    ?= $(shell pwd)/dist
     1.5  INSTALL_DIR ?= $(DIST_DIR)/install
     1.6  
     1.7 -SOURCEFORGE_MIRROR := http://heanet.dl.sourceforge.net/sourceforge
     1.8 -#http://voxel.dl.sourceforge.net/sourceforge/
     1.9 -#http://easynews.dl.sourceforge.net/sourceforge
    1.10 +KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
    1.11 +# linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU
    1.12  
    1.13 -#KERNELS ?= mk.linux-2.6-xen0 mk.linux-2.6-xenU mk.linux-2.4-xen0 mk.linux-2.4-xenU mk.netbsd-2.0-xenU
    1.14 -KERNELS ?= mk.linux-2.6-xen0 mk.linux-2.6-xenU
    1.15 -
    1.16 -ALLKERNELS = $(patsubst buildconfigs/%,%,$(wildcard buildconfigs/mk.*))
    1.17 +ALLKERNELS = $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.*))
    1.18  ALLSPARSETREES = $(patsubst %-xen-sparse,%,$(wildcard *-xen-sparse))
    1.19  
    1.20 -export INSTALL_DIR SOURCEFORGE_MIRROR
    1.21 +export INSTALL_DIR
    1.22 +
    1.23 +include buildconfigs/Rules.mk
    1.24  
    1.25  .PHONY:	all dist install xen tools kernels docs world clean mkpatches mrproper
    1.26  .PHONY:	kbuild kdelete kclean
    1.27  
    1.28 -all: 	dist
    1.29 +all: dist
    1.30  
    1.31  # build and install everything into local dist directory
    1.32 -dist:	xen tools kernels docs
    1.33 +dist: xen tools kernels docs
    1.34  	install -m0644 ./COPYING $(DIST_DIR)
    1.35  	install -m0644 ./README $(DIST_DIR)
    1.36  	install -m0755 ./install.sh $(DIST_DIR)
    1.37 @@ -47,27 +45,27 @@ xen:
    1.38  tools:
    1.39  	$(MAKE) prefix=$(INSTALL_DIR) dist=yes -C tools install
    1.40  
    1.41 -# Build all the various kernels and modules
    1.42  kernels:
    1.43 -	for i in $(KERNELS) ; do $(MAKE) -f buildconfigs/$$i build ; done
    1.44 +	for i in $(KERNELS) ; do $(MAKE) $$i-build ; done
    1.45  
    1.46  docs:
    1.47  	sh ./docs/check_pkgs && \
    1.48  		$(MAKE) prefix=$(INSTALL_DIR) dist=yes -C docs install || true
    1.49  
    1.50 +# Build all the various kernels and modules
    1.51  kbuild: kernels
    1.52  
    1.53  # Delete the kernel build trees entirely
    1.54  kdelete:
    1.55 -	for i in $(KERNELS) ; do $(MAKE) -f buildconfigs/$$i delete ; done
    1.56 +	for i in $(KERNELS) ; do $(MAKE) $$i-delete ; done
    1.57  
    1.58  # Clean the kernel build trees
    1.59  kclean:
    1.60 -	for i in $(KERNELS) ; do $(MAKE) -f buildconfigs/$$i clean ; done
    1.61 +	for i in $(KERNELS) ; do $(MAKE) $$i-clean ; done
    1.62  
    1.63  # Make patches from kernel sparse trees
    1.64  mkpatches:
    1.65 -	for i in $(ALLSPARSETREES) ; do $(MAKE) -f buildconfigs/Rules.mk $$i-xen.patch ; done
    1.66 +	for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch ; done
    1.67  
    1.68  
    1.69  # build xen, the tools, and a domain 0 plus unprivileged linux-xen images,
    1.70 @@ -87,8 +85,8 @@ clean:
    1.71  # clean, but blow away kernel build tree plus tar balls
    1.72  mrproper: clean
    1.73  	rm -rf dist patches/tmp
    1.74 -	for i in $(ALLKERNELS) ; do $(MAKE) -f buildconfigs/$$i delete ; done
    1.75 -	for i in $(ALLSPARSETREES) ; do $(MAKE) -f buildconfigs/Rules.mk $$i-mrproper ; done
    1.76 +	for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
    1.77 +	for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
    1.78  
    1.79  install-twisted:
    1.80  	wget http://www.twistedmatrix.com/products/get-current.epy
    1.81 @@ -113,16 +111,14 @@ uninstall:
    1.82  	cp -a /etc/xen /etc/xen.old && rm -rf /etc/xen 
    1.83  	rm -rf "/usr/lib/python2.?/site-packages/xen* /usr/lib/libxc* /usr/lib/python2.?/site-packages/Xc*"
    1.84  
    1.85 -# Legacy target for compatibility
    1.86 +# Legacy targets for compatibility
    1.87  linux24:
    1.88 -	$(MAKE) -f buildconfigs/mk.linux-2.4-xen0 build
    1.89 -	$(MAKE) -f buildconfigs/mk.linux-2.4-xenU build
    1.90 +	$(MAKE) linux-2.4-xen0-build
    1.91 +	$(MAKE) linux-2.4-xenU-build
    1.92  
    1.93 -# Legacy target for compatibility
    1.94  linux26:
    1.95 -	$(MAKE) -f buildconfigs/mk.linux-2.6-xen0 build
    1.96 -	$(MAKE) -f buildconfigs/mk.linux-2.6-xenU build
    1.97 +	$(MAKE) linux-2.6-xen0-build
    1.98 +	$(MAKE) linux-2.6-xenU-build
    1.99  
   1.100 -# Legacy target for compatibility
   1.101  netbsd20:
   1.102 -	$(MAKE) -f buildconfigs/mk.netbsd-2.0-xenU build
   1.103 +	$(MAKE) netbsd-2.0-xenU-build
     2.1 --- a/buildconfigs/Rules.mk	Tue Nov 16 18:59:47 2004 +0000
     2.2 +++ b/buildconfigs/Rules.mk	Wed Nov 17 10:16:18 2004 +0000
     2.3 @@ -1,17 +1,10 @@
     2.4 -
     2.5 -# We expect these two to already be set if people 
     2.6 -# are using the top-level Makefile
     2.7 -DIST_DIR	?= $(shell pwd)/dist
     2.8 -INSTALL_DIR	?= $(DIST_DIR)/install
     2.9  
    2.10  .PHONY:	mkpatches mrproper
    2.11  
    2.12 -
    2.13  # Setup pristine search path
    2.14  PRISTINE_SRC_PATH	?= .:..
    2.15  vpath pristine-% $(PRISTINE_SRC_PATH)
    2.16  
    2.17 -
    2.18  # Expand Linux series to Linux version
    2.19  LINUX_SERIES	?= 2.6
    2.20  LINUX_VER	?= $(patsubst linux-%-xen-sparse,%,$(wildcard linux-$(LINUX_SERIES)*-xen-sparse))
    2.21 @@ -26,8 +19,6 @@ linux-%.tar.bz2:
    2.22  	@echo "Cannot find $@ in path $(LINUX_SRC_PATH)"
    2.23  	wget http://www.kernel.org/pub/linux/kernel/v$(_LINUX_VDIR)/$@ -O./$@
    2.24  
    2.25 -
    2.26 -
    2.27  # Expand NetBSD release to NetBSD version
    2.28  NETBSD_RELEASE  ?= 2.0
    2.29  NETBSD_VER      ?= $(patsubst netbsd-%-xen-sparse,%,$(wildcard netbsd-$(NETBSD_RELEASE)*-xen-sparse))
    2.30 @@ -45,9 +36,6 @@ netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).ta
    2.31  netbsd-%.tar.bz2: netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
    2.32  	ln -fs $< $@
    2.33  
    2.34 -
    2.35 -
    2.36 -
    2.37  pristine-%: %.tar.bz2
    2.38  	rm -rf tmp-$(@F) $@
    2.39  	mkdir -p tmp-$(@F)
    2.40 @@ -56,6 +44,15 @@ pristine-%: %.tar.bz2
    2.41  	touch $@ # update timestamp to avoid rebuild
    2.42  	@rm -rf tmp-$(@F)
    2.43  
    2.44 +%-build:
    2.45 +	$(MAKE) -f buildconfigs/mk.$* build
    2.46 +
    2.47 +%-delete:
    2.48 +	$(MAKE) -f buildconfigs/mk.$* delete
    2.49 +
    2.50 +%-clean:
    2.51 +	$(MAKE) -f buildconfigs/mk.$* clean
    2.52 +
    2.53  %-xen.patch: pristine-%
    2.54  	rm -rf tmp-$@
    2.55  	cp -al $< tmp-$@
     3.1 --- a/linux-2.4.27-xen-sparse/arch/xen/kernel/entry.S	Tue Nov 16 18:59:47 2004 +0000
     3.2 +++ b/linux-2.4.27-xen-sparse/arch/xen/kernel/entry.S	Wed Nov 17 10:16:18 2004 +0000
     3.3 @@ -369,28 +369,19 @@ critical_fixup_table:
     3.4  
     3.5  # Hypervisor uses this for application faults while it executes.
     3.6  ENTRY(failsafe_callback)
     3.7 -        pushal
     3.8 -        call SYMBOL_NAME(install_safe_pf_handler)
     3.9 -        movl 32(%esp),%ebx
    3.10 -1:      movl %ebx,%ds
    3.11 -        movl 36(%esp),%ebx
    3.12 -2:      movl %ebx,%es
    3.13 -        movl 40(%esp),%ebx
    3.14 -3:      movl %ebx,%fs
    3.15 -        movl 44(%esp),%ebx
    3.16 -4:      movl %ebx,%gs
    3.17 -        call SYMBOL_NAME(install_normal_pf_handler)
    3.18 -        popal
    3.19 -        addl $16,%esp
    3.20 +1:      popl %ds
    3.21 +2:      popl %es
    3.22 +3:      popl %fs
    3.23 +4:      popl %gs
    3.24  5:      iret
    3.25  .section .fixup,"ax";	\
    3.26 -6:	xorl %ebx,%ebx;	\
    3.27 +6:	movl $0,(%esp);	\
    3.28  	jmp 1b;		\
    3.29 -7:	xorl %ebx,%ebx;	\
    3.30 +7:	movl $0,(%esp);	\
    3.31  	jmp 2b;		\
    3.32 -8:	xorl %ebx,%ebx;	\
    3.33 +8:	movl $0,(%esp);	\
    3.34  	jmp 3b;		\
    3.35 -9:	xorl %ebx,%ebx;	\
    3.36 +9:	movl $0,(%esp);	\
    3.37  	jmp 4b;		\
    3.38  10:	pushl %ss;	\
    3.39  	popl %ds;	\
    3.40 @@ -511,7 +502,6 @@ ENTRY(_name1)                           
    3.41  	addl $12,%esp                                                  ; \
    3.42  	jmp ret_from_exception                                         ;
    3.43  PAGE_FAULT_STUB(page_fault, do_page_fault)
    3.44 -PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
    3.45  
    3.46  ENTRY(machine_check)
    3.47  	pushl $0
     4.1 --- a/linux-2.4.27-xen-sparse/arch/xen/kernel/traps.c	Tue Nov 16 18:59:47 2004 +0000
     4.2 +++ b/linux-2.4.27-xen-sparse/arch/xen/kernel/traps.c	Wed Nov 17 10:16:18 2004 +0000
     4.3 @@ -59,7 +59,6 @@ asmlinkage void segment_not_present(void
     4.4  asmlinkage void stack_segment(void);
     4.5  asmlinkage void general_protection(void);
     4.6  asmlinkage void page_fault(void);
     4.7 -asmlinkage void safe_page_fault(void);
     4.8  asmlinkage void coprocessor_error(void);
     4.9  asmlinkage void simd_coprocessor_error(void);
    4.10  asmlinkage void alignment_check(void);
    4.11 @@ -627,65 +626,3 @@ void __init trap_init(void)
    4.12  
    4.13      cpu_init();
    4.14  }
    4.15 -
    4.16 -
    4.17 -/*
    4.18 - * install_safe_pf_handler / install_normal_pf_handler:
    4.19 - * 
    4.20 - * These are used within the failsafe_callback handler in entry.S to avoid
    4.21 - * taking a full page fault when reloading FS and GS. This is because FS and 
    4.22 - * GS could be invalid at pretty much any point while Xenolinux executes (we 
    4.23 - * don't set them to safe values on entry to the kernel). At *any* point Xen 
    4.24 - * may be entered due to a hardware interrupt --- on exit from Xen an invalid 
    4.25 - * FS/GS will cause our failsafe_callback to be executed. This could occur, 
    4.26 - * for example, while the mmu_update_queue is in an inconsistent state. This
    4.27 - * is disastrous because the normal page-fault handler touches the update
    4.28 - * queue!
    4.29 - * 
    4.30 - * Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
    4.31 - * to zero if they cannot be reloaded -- at this point executing a normal
    4.32 - * page fault would not change this effect. The safe page-fault handler
    4.33 - * ensures this end result (blow away the selector value) without the dangers
    4.34 - * of the normal page-fault handler.
    4.35 - * 
    4.36 - * NB. Perhaps this can all go away after we have implemented writable
    4.37 - * page tables. :-)
    4.38 - */
    4.39 -
    4.40 -asmlinkage void do_safe_page_fault(struct pt_regs *regs, 
    4.41 -                                   unsigned long error_code,
    4.42 -                                   unsigned long address)
    4.43 -{
    4.44 -    unsigned long fixup;
    4.45 -
    4.46 -    if ( (fixup = search_exception_table(regs->eip)) != 0 )
    4.47 -    {
    4.48 -        regs->eip = fixup;
    4.49 -        return;
    4.50 -    }
    4.51 -
    4.52 -    die("Unhandleable 'safe' page fault!", regs, error_code);
    4.53 -}
    4.54 -
    4.55 -unsigned long install_safe_pf_handler(void)
    4.56 -{
    4.57 -    static trap_info_t safe_pf[] = { 
    4.58 -        { 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
    4.59 -        {  0, 0,           0, 0                              }
    4.60 -    };
    4.61 -    unsigned long flags;
    4.62 -    local_irq_save(flags);
    4.63 -    HYPERVISOR_set_trap_table(safe_pf);
    4.64 -    return flags; /* This is returned in %%eax */
    4.65 -}
    4.66 -
    4.67 -__attribute__((regparm(3))) /* This function take its arg in %%eax */
    4.68 -void install_normal_pf_handler(unsigned long flags)
    4.69 -{
    4.70 -    static trap_info_t normal_pf[] = { 
    4.71 -        { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
    4.72 -        {  0, 0,           0, 0                         }
    4.73 -    };
    4.74 -    HYPERVISOR_set_trap_table(normal_pf);
    4.75 -    local_irq_restore(flags);
    4.76 -}
     5.1 --- a/linux-2.4.27-xen-sparse/include/asm-xen/irq.h	Tue Nov 16 18:59:47 2004 +0000
     5.2 +++ b/linux-2.4.27-xen-sparse/include/asm-xen/irq.h	Wed Nov 17 10:16:18 2004 +0000
     5.3 @@ -59,4 +59,7 @@ extern void irq_resume(void);
     5.4  
     5.5  #define CPU_MASK_NONE 0
     5.6  
     5.7 +/* XXX SMH: no-op for compat w/ 2.6 shared files */ 
     5.8 +#define irq_ctx_init(cpu) do { ; } while (0)
     5.9 +
    5.10  #endif /* _ASM_IRQ_H */
     6.1 --- a/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig	Tue Nov 16 18:59:47 2004 +0000
     6.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig	Wed Nov 17 10:16:18 2004 +0000
     6.3 @@ -158,7 +158,7 @@ CONFIG_MAGIC_SYSRQ=y
     6.4  # CONFIG_DEBUG_INFO is not set
     6.5  # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
     6.6  # CONFIG_FRAME_POINTER is not set
     6.7 -# CONFIG_4KSTACKS is not set
     6.8 +CONFIG_4KSTACKS=y
     6.9  CONFIG_X86_BIOS_REBOOT=y
    6.10  CONFIG_X86_STD_RESOURCES=y
    6.11  CONFIG_PC=y
     7.1 --- a/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig	Tue Nov 16 18:59:47 2004 +0000
     7.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig	Wed Nov 17 10:16:18 2004 +0000
     7.3 @@ -119,7 +119,7 @@ CONFIG_HAVE_DEC_LOCK=y
     7.4  CONFIG_EARLY_PRINTK=y
     7.5  # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
     7.6  # CONFIG_FRAME_POINTER is not set
     7.7 -# CONFIG_4KSTACKS is not set
     7.8 +CONFIG_4KSTACKS=y
     7.9  CONFIG_X86_BIOS_REBOOT=y
    7.10  CONFIG_X86_STD_RESOURCES=y
    7.11  CONFIG_PC=y
     8.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/entry.S	Tue Nov 16 18:59:47 2004 +0000
     8.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/entry.S	Wed Nov 17 10:16:18 2004 +0000
     8.3 @@ -526,28 +526,19 @@ critical_fixup_table:
     8.4  
     8.5  # Hypervisor uses this for application faults while it executes.
     8.6  ENTRY(failsafe_callback)
     8.7 -	pushal
     8.8 -	call install_safe_pf_handler
     8.9 -	movl 32(%esp),%ebx
    8.10 -1:	movl %ebx,%ds
    8.11 -	movl 36(%esp),%ebx
    8.12 -2:	movl %ebx,%es
    8.13 -	movl 40(%esp),%ebx
    8.14 -3:	movl %ebx,%fs
    8.15 -	movl 44(%esp),%ebx
    8.16 -4:	movl %ebx,%gs
    8.17 -	call install_normal_pf_handler
    8.18 -	popal
    8.19 -	addl $16,%esp
    8.20 +1:      popl %ds
    8.21 +2:      popl %es
    8.22 +3:      popl %fs
    8.23 +4:      popl %gs
    8.24  5:	iret
    8.25  .section .fixup,"ax";	\
    8.26 -6:	xorl %ebx,%ebx;	\
    8.27 +6:	movl $0,(%esp);	\
    8.28  	jmp 1b;		\
    8.29 -7:	xorl %ebx,%ebx;	\
    8.30 +7:	movl $0,(%esp);	\
    8.31  	jmp 2b;		\
    8.32 -8:	xorl %ebx,%ebx;	\
    8.33 +8:	movl $0,(%esp);	\
    8.34  	jmp 3b;		\
    8.35 -9:	xorl %ebx,%ebx;	\
    8.36 +9:	movl $0,(%esp);	\
    8.37  	jmp 4b;		\
    8.38  10:	pushl %ss;	\
    8.39  	popl %ds;	\
    8.40 @@ -742,7 +733,6 @@ ENTRY(_name1)								  \
    8.41  	addl $12,%esp							; \
    8.42  	jmp ret_from_exception						;
    8.43  PAGE_FAULT_STUB(page_fault, do_page_fault)
    8.44 -PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
    8.45  
    8.46  #ifdef CONFIG_X86_MCE
    8.47  ENTRY(machine_check)
     9.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Nov 16 18:59:47 2004 +0000
     9.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c	Wed Nov 17 10:16:18 2004 +0000
     9.3 @@ -1320,6 +1320,11 @@ void __init setup_arch(char **cmdline_p)
     9.4  
     9.5          unsigned long max_low_pfn;
     9.6  
     9.7 +	/* Force a quick death if the kernel panics. */
     9.8 +	extern int panic_timeout;
     9.9 +	if ( panic_timeout == 0 )
    9.10 +		panic_timeout = 1;
    9.11 +
    9.12  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
    9.13  			     VMASST_TYPE_4gb_segments);
    9.14  
    10.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Nov 16 18:59:47 2004 +0000
    10.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c	Wed Nov 17 10:16:18 2004 +0000
    10.3 @@ -60,8 +60,6 @@ asmlinkage int system_call(void);
    10.4  asmlinkage void lcall7(void);
    10.5  asmlinkage void lcall27(void);
    10.6  
    10.7 -asmlinkage void safe_page_fault(void);
    10.8 -
    10.9  /* Do we ignore FPU interrupts ? */
   10.10  char ignore_fpu_irq = 0;
   10.11  
   10.12 @@ -1064,7 +1062,7 @@ void __init trap_init(void)
   10.13  	clear_page(&default_ldt[0]);
   10.14  	set_call_gate(&default_ldt[0],lcall7);
   10.15  	set_call_gate(&default_ldt[4],lcall27);
   10.16 -	__make_page_readonly(&default_ldt[0]);
   10.17 +	make_lowmem_page_readonly(&default_ldt[0]);
   10.18  	xen_flush_page_update_queue();
   10.19  
   10.20  	/*
   10.21 @@ -1084,58 +1082,3 @@ int smp_trap_init(trap_info_t *trap_ctxt
   10.22  	}
   10.23  	return SYSCALL_VECTOR;
   10.24  }
   10.25 -
   10.26 -
   10.27 -/*
   10.28 - * install_safe_pf_handler / install_normal_pf_handler:
   10.29 - * 
   10.30 - * These are used within the failsafe_callback handler in entry.S to avoid
   10.31 - * taking a full page fault when reloading FS and GS. This is because FS and 
   10.32 - * GS could be invalid at pretty much any point while Xen Linux executes (we 
   10.33 - * don't set them to safe values on entry to the kernel). At *any* point Xen 
   10.34 - * may be entered due to a hardware interrupt --- on exit from Xen an invalid 
   10.35 - * FS/GS will cause our failsafe_callback to be executed. This could occur, 
   10.36 - * for example, while the mmmu_update_queue is in an inconsistent state. This
   10.37 - * is disastrous because the normal page-fault handler touches the update
   10.38 - * queue!
   10.39 - * 
   10.40 - * Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
   10.41 - * to zero if they cannot be reloaded -- at this point executing a normal
   10.42 - * page fault would not change this effect. The safe page-fault handler
   10.43 - * ensures this end result (blow away the selector value) without the dangers
   10.44 - * of the normal page-fault handler.
   10.45 - * 
   10.46 - * NB. Perhaps this can all go away after we have implemented writable
   10.47 - * page tables. :-)
   10.48 - */
   10.49 -
   10.50 -asmlinkage void do_safe_page_fault(struct pt_regs *regs, 
   10.51 -                                   unsigned long error_code,
   10.52 -                                   unsigned long address)
   10.53 -{
   10.54 -	if (!fixup_exception(regs))
   10.55 -		die("Unhandleable 'safe' page fault!", regs, error_code);
   10.56 -}
   10.57 -
   10.58 -unsigned long install_safe_pf_handler(void)
   10.59 -{
   10.60 -	static trap_info_t safe_pf[] = { 
   10.61 -		{ 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
   10.62 -		{  0, 0,           0, 0                              }
   10.63 -	};
   10.64 -	unsigned long flags;
   10.65 -	local_irq_save(flags);
   10.66 -	HYPERVISOR_set_trap_table(safe_pf);
   10.67 -	return flags; /* This is returned in %%eax */
   10.68 -}
   10.69 -
   10.70 -__attribute__((regparm(3))) /* This function take its arg in %%eax */
   10.71 -void install_normal_pf_handler(unsigned long flags)
   10.72 -{
   10.73 -	static trap_info_t normal_pf[] = { 
   10.74 -		{ 14, 0, __KERNEL_CS, (unsigned long)page_fault },
   10.75 -		{  0, 0,           0, 0                         }
   10.76 -	};
   10.77 -	HYPERVISOR_set_trap_table(normal_pf);
   10.78 -	local_irq_restore(flags);
   10.79 -}
    11.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c	Tue Nov 16 18:59:47 2004 +0000
    11.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c	Wed Nov 17 10:16:18 2004 +0000
    11.3 @@ -119,7 +119,7 @@ static int
    11.4  		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
    11.5  			pte_t old = *kpte;
    11.6  			pte_t standard = mk_pte(page, PAGE_KERNEL); 
    11.7 -			set_pte_atomic(kpte, mk_pte(page, prot)); 
    11.8 +			set_pte_batched(kpte, mk_pte(page, prot)); 
    11.9  			if (pte_same(old,standard))
   11.10  				get_page(kpte_page);
   11.11  		} else {
   11.12 @@ -130,7 +130,7 @@ static int
   11.13  			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
   11.14  		}	
   11.15  	} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
   11.16 -		set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
   11.17 +		set_pte_batched(kpte, mk_pte(page, PAGE_KERNEL));
   11.18  		__put_page(kpte_page);
   11.19  	}
   11.20  
   11.21 @@ -171,6 +171,7 @@ int change_page_attr(struct page *page, 
   11.22  		if (err) 
   11.23  			break; 
   11.24  	} 	
   11.25 +	flush_page_update_queue();
   11.26  	spin_unlock_irqrestore(&cpa_lock, flags);
   11.27  	return err;
   11.28  }
    12.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c	Tue Nov 16 18:59:47 2004 +0000
    12.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c	Wed Nov 17 10:16:18 2004 +0000
    12.3 @@ -179,7 +179,7 @@ pte_t *pte_alloc_one_kernel(struct mm_st
    12.4  	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
    12.5  	if (pte) {
    12.6  		clear_page(pte);
    12.7 -		__make_page_readonly(pte);
    12.8 +		make_page_readonly(pte);
    12.9  		xen_flush_page_update_queue();
   12.10  	}
   12.11  	return pte;
   12.12 @@ -192,7 +192,7 @@ void pte_ctor(void *pte, kmem_cache_t *c
   12.13  	set_page_count(page, 1);
   12.14  
   12.15  	clear_page(pte);
   12.16 -	__make_page_readonly(pte);
   12.17 +	make_page_readonly(pte);
   12.18  	queue_pte_pin(virt_to_phys(pte));
   12.19  	flush_page_update_queue();
   12.20  }
   12.21 @@ -203,7 +203,7 @@ void pte_dtor(void *pte, kmem_cache_t *c
   12.22  	ClearPageForeign(page);
   12.23  
   12.24  	queue_pte_unpin(virt_to_phys(pte));
   12.25 -	__make_page_writable(pte);
   12.26 +	make_page_writable(pte);
   12.27  	flush_page_update_queue();
   12.28  }
   12.29  
   12.30 @@ -304,7 +304,7 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
   12.31  	spin_unlock_irqrestore(&pgd_lock, flags);
   12.32  	memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
   12.33   out:
   12.34 -	__make_page_readonly(pgd);
   12.35 +	make_page_readonly(pgd);
   12.36  	queue_pgd_pin(__pa(pgd));
   12.37  	flush_page_update_queue();
   12.38  }
   12.39 @@ -315,7 +315,7 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
   12.40  	unsigned long flags; /* can be called from interrupt context */
   12.41  
   12.42  	queue_pgd_unpin(__pa(pgd));
   12.43 -	__make_page_writable(pgd);
   12.44 +	make_page_writable(pgd);
   12.45  	flush_page_update_queue();
   12.46  
   12.47  	if (PTRS_PER_PMD > 1)
   12.48 @@ -360,3 +360,71 @@ void pgd_free(pgd_t *pgd)
   12.49  	/* in the non-PAE case, clear_page_tables() clears user pgd entries */
   12.50  	kmem_cache_free(pgd_cache, pgd);
   12.51  }
   12.52 +
   12.53 +void make_lowmem_page_readonly(void *va)
   12.54 +{
   12.55 +	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   12.56 +	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   12.57 +	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   12.58 +	queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
   12.59 +}
   12.60 +
   12.61 +void make_lowmem_page_writable(void *va)
   12.62 +{
   12.63 +	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   12.64 +	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   12.65 +	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   12.66 +	queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
   12.67 +}
   12.68 +
   12.69 +void make_page_readonly(void *va)
   12.70 +{
   12.71 +	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   12.72 +	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   12.73 +	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   12.74 +	queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
   12.75 +	if ( (unsigned long)va >= (unsigned long)high_memory )
   12.76 +	{
   12.77 +		unsigned long phys;
   12.78 +		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
   12.79 +#ifdef CONFIG_HIGHMEM
   12.80 +		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
   12.81 +#endif
   12.82 +			make_lowmem_page_readonly(phys_to_virt(phys));
   12.83 +	}
   12.84 +}
   12.85 +
   12.86 +void make_page_writable(void *va)
   12.87 +{
   12.88 +	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   12.89 +	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   12.90 +	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   12.91 +	queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
   12.92 +	if ( (unsigned long)va >= (unsigned long)high_memory )
   12.93 +	{
   12.94 +		unsigned long phys;
   12.95 +		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
   12.96 +#ifdef CONFIG_HIGHMEM
   12.97 +		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
   12.98 +#endif
   12.99 +			make_lowmem_page_writable(phys_to_virt(phys));
  12.100 +	}
  12.101 +}
  12.102 +
  12.103 +void make_pages_readonly(void *va, unsigned int nr)
  12.104 +{
  12.105 +	while ( nr-- != 0 )
  12.106 +	{
  12.107 +		make_page_readonly(va);
  12.108 +		va = (void *)((unsigned long)va + PAGE_SIZE);
  12.109 +	}
  12.110 +}
  12.111 +
  12.112 +void make_pages_writable(void *va, unsigned int nr)
  12.113 +{
  12.114 +	while ( nr-- != 0 )
  12.115 +	{
  12.116 +		make_page_writable(va);
  12.117 +		va = (void *)((unsigned long)va + PAGE_SIZE);
  12.118 +	}
  12.119 +}
    13.1 --- a/linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c	Tue Nov 16 18:59:47 2004 +0000
    13.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c	Wed Nov 17 10:16:18 2004 +0000
    13.3 @@ -553,6 +553,8 @@ void __init init_IRQ(void)
    13.4      int i;
    13.5      int cpu;
    13.6  
    13.7 +    irq_ctx_init(0);
    13.8 +
    13.9      spin_lock_init(&irq_mapping_update_lock);
   13.10  
   13.11      for ( cpu = 0; cpu < NR_CPUS; cpu++ ) {
    14.1 --- a/linux-2.6.9-xen-sparse/drivers/char/mem.c	Tue Nov 16 18:59:47 2004 +0000
    14.2 +++ b/linux-2.6.9-xen-sparse/drivers/char/mem.c	Wed Nov 17 10:16:18 2004 +0000
    14.3 @@ -43,7 +43,12 @@ extern void tapechar_init(void);
    14.4   */
    14.5  static inline int uncached_access(struct file *file, unsigned long addr)
    14.6  {
    14.7 -#if defined(__i386__)
    14.8 +#ifdef CONFIG_XEN
    14.9 +        if (file->f_flags & O_SYNC)
   14.10 +                return 1;
   14.11 +        /* Xen sets correct MTRR type on non-RAM for us. */
   14.12 +        return 0;
   14.13 +#elif defined(__i386__)
   14.14  	/*
   14.15  	 * On the PPro and successors, the MTRRs are used to set
   14.16  	 * memory types for physical addresses outside main memory,
   14.17 @@ -193,7 +198,6 @@ static ssize_t write_mem(struct file * f
   14.18  
   14.19  static int mmap_mem(struct file * file, struct vm_area_struct * vma)
   14.20  {
   14.21 -#if !defined(CONFIG_XEN)
   14.22  	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
   14.23  	int uncached;
   14.24  
   14.25 @@ -212,28 +216,16 @@ static int mmap_mem(struct file * file, 
   14.26  	if (uncached)
   14.27  		vma->vm_flags |= VM_IO;
   14.28  
   14.29 +#if defined(CONFIG_XEN)
   14.30 +	if (io_remap_page_range(vma, vma->vm_start, offset, 
   14.31 +				vma->vm_end-vma->vm_start, vma->vm_page_prot))
   14.32 +		return -EAGAIN;
   14.33 +#else
   14.34  	if (remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start,
   14.35  			     vma->vm_page_prot))
   14.36  		return -EAGAIN;
   14.37 +#endif
   14.38  	return 0;
   14.39 -#elif !defined(CONFIG_XEN_PRIVILEGED_GUEST)
   14.40 -	return -ENXIO;
   14.41 -#else
   14.42 -	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
   14.43 -
   14.44 -	if (!(xen_start_info.flags & SIF_PRIVILEGED))
   14.45 -		return -ENXIO;
   14.46 -
   14.47 -	/* Currently we're not smart about setting PTE cacheability. */
   14.48 -	vma->vm_flags |= VM_RESERVED | VM_IO;
   14.49 -	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
   14.50 -
   14.51 -	if (direct_remap_area_pages(vma->vm_mm, vma->vm_start, offset, 
   14.52 -				vma->vm_end-vma->vm_start, vma->vm_page_prot,
   14.53 -				DOMID_IO))
   14.54 -		return -EAGAIN;
   14.55 -	return 0;
   14.56 -#endif
   14.57  }
   14.58  
   14.59  extern long vread(char *buf, char *addr, unsigned long count);
    15.1 --- a/linux-2.6.9-xen-sparse/drivers/char/tty_io.c	Tue Nov 16 18:59:47 2004 +0000
    15.2 +++ b/linux-2.6.9-xen-sparse/drivers/char/tty_io.c	Wed Nov 17 10:16:18 2004 +0000
    15.3 @@ -131,9 +131,8 @@ LIST_HEAD(tty_drivers);			/* linked list
    15.4     vt.c for deeply disgusting hack reasons */
    15.5  DECLARE_MUTEX(tty_sem);
    15.6  
    15.7 -#ifdef CONFIG_VT
    15.8  int console_use_vt = 1;
    15.9 -#endif
   15.10 +
   15.11  #ifdef CONFIG_UNIX98_PTYS
   15.12  extern struct tty_driver *ptm_driver;	/* Unix98 pty masters; for /dev/ptmx */
   15.13  extern int pty_limit;		/* Config limit on Unix98 ptys */
    16.1 --- a/linux-2.6.9-xen-sparse/drivers/xen/balloon/balloon.c	Tue Nov 16 18:59:47 2004 +0000
    16.2 +++ b/linux-2.6.9-xen-sparse/drivers/xen/balloon/balloon.c	Wed Nov 17 10:16:18 2004 +0000
    16.3 @@ -534,10 +534,13 @@ static void balloon_ctrlif_rx(ctrl_msg_t
    16.4      ctrl_if_send_response(msg);
    16.5  }
    16.6  
    16.7 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    16.8 +typedef size_t count_t;
    16.9 +#else
   16.10 +typedef u_long count_t;
   16.11 +#endif
   16.12  
   16.13 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   16.14 -static int balloon_write(struct file *file, const char *buffer,
   16.15 -                         size_t count, loff_t *offp)
   16.16 +static int do_balloon_write(const char *buffer, count_t count)
   16.17  {
   16.18      char memstring[64], *endchar;
   16.19      int len, i;
   16.20 @@ -571,6 +574,17 @@ static int balloon_write(struct file *fi
   16.21  
   16.22      if ( i <= 0 ) return i;
   16.23  
   16.24 +    return len;
   16.25 +}
   16.26 +
   16.27 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   16.28 +static int balloon_write(struct file *file, const char *buffer,
   16.29 +                         size_t count, loff_t *offp)
   16.30 +{
   16.31 +    int len = do_balloon_write(buffer, count);
   16.32 +    
   16.33 +    if ( len <= 0 ) return len;
   16.34 +
   16.35      *offp += len;
   16.36      return len;
   16.37  }
   16.38 @@ -605,71 +619,7 @@ static struct file_operations balloon_fo
   16.39  static int balloon_write(struct file *file, const char *buffer,
   16.40                           u_long count, void *data)
   16.41  {
   16.42 -    char memstring[64], *endchar;
   16.43 -    int len, i;
   16.44 -    unsigned long target;
   16.45 -    unsigned long long targetbytes;
   16.46 -
   16.47 -    /* Only admin can play with the balloon :) */
   16.48 -    if ( !capable(CAP_SYS_ADMIN) )
   16.49 -        return -EPERM;
   16.50 -
   16.51 -    if ( count > sizeof(memstring) )
   16.52 -        return -EFBIG;
   16.53 -
   16.54 -    len = strnlen_user(buffer, count);
   16.55 -    if ( len == 0 ) return -EBADMSG;
   16.56 -    if ( len == 1 ) return 1; /* input starts with a NUL char */
   16.57 -    if ( strncpy_from_user(memstring, buffer, len) < 0 )
   16.58 -        return -EFAULT;
   16.59 -
   16.60 -    endchar = memstring;
   16.61 -    for ( i = 0; i < len; ++i, ++endchar )
   16.62 -        if ( (memstring[i] < '0') || (memstring[i] > '9') )
   16.63 -            break;
   16.64 -    if ( i == 0 )
   16.65 -        return -EBADMSG;
   16.66 -
   16.67 -    targetbytes = memparse(memstring,&endchar);
   16.68 -    target = targetbytes >> PAGE_SHIFT;
   16.69 -
   16.70 -    if ( target < current_pages )
   16.71 -    {
   16.72 -        int change = inflate_balloon(current_pages-target);
   16.73 -        if ( change <= 0 )
   16.74 -            return change;
   16.75 -
   16.76 -        current_pages -= change;
   16.77 -        printk(KERN_INFO "Relinquish %dMB to xen. Domain now has %luMB\n",
   16.78 -            change>>PAGE_TO_MB_SHIFT, current_pages>>PAGE_TO_MB_SHIFT);
   16.79 -    }
   16.80 -    else if ( target > current_pages )
   16.81 -    {
   16.82 -        int change, reclaim = min(target,most_seen_pages) - current_pages;
   16.83 -
   16.84 -        if ( reclaim )
   16.85 -        {
   16.86 -            change = deflate_balloon( reclaim);
   16.87 -            if ( change <= 0 )
   16.88 -                return change;
   16.89 -            current_pages += change;
   16.90 -            printk(KERN_INFO "Reclaim %dMB from xen. Domain now has %luMB\n",
   16.91 -                change>>PAGE_TO_MB_SHIFT, current_pages>>PAGE_TO_MB_SHIFT);
   16.92 -        }
   16.93 -
   16.94 -        if ( most_seen_pages < target )
   16.95 -        {
   16.96 -            int growth = claim_new_pages(target-most_seen_pages);
   16.97 -            if ( growth <= 0 )
   16.98 -                return growth;
   16.99 -            most_seen_pages += growth;
  16.100 -            current_pages += growth;
  16.101 -            printk(KERN_INFO "Granted %dMB new mem. Dom now has %luMB\n",
  16.102 -                growth>>PAGE_TO_MB_SHIFT, current_pages>>PAGE_TO_MB_SHIFT);
  16.103 -        }
  16.104 -    }
  16.105 -
  16.106 -    return len;
  16.107 +    return do_balloon_write(buffer, count);
  16.108  }
  16.109  
  16.110  static int balloon_read(char *page, char **start, off_t off,
    17.1 --- a/linux-2.6.9-xen-sparse/drivers/xen/evtchn/evtchn.c	Tue Nov 16 18:59:47 2004 +0000
    17.2 +++ b/linux-2.6.9-xen-sparse/drivers/xen/evtchn/evtchn.c	Wed Nov 17 10:16:18 2004 +0000
    17.3 @@ -4,6 +4,7 @@
    17.4   * Xenolinux driver for receiving and demuxing event-channel signals.
    17.5   * 
    17.6   * Copyright (c) 2004, K A Fraser
    17.7 + * Multi-process extensions Copyright (c) 2004, Steven Smith
    17.8   * 
    17.9   * This file may be distributed separately from the Linux kernel, or
   17.10   * incorporated into other software packages, subject to the following license:
   17.11 @@ -58,55 +59,49 @@
   17.12  static devfs_handle_t xen_dev_dir;
   17.13  #endif
   17.14  
   17.15 -/* Only one process may open /dev/xen/evtchn at any time. */
   17.16 -static unsigned long evtchn_dev_inuse;
   17.17 -
   17.18 -/* Notification ring, accessed via /dev/xen/evtchn. */
   17.19 -#define RING_SIZE     2048  /* 2048 16-bit entries */
   17.20 -#define RING_MASK(_i) ((_i)&(RING_SIZE-1))
   17.21 -static u16 *ring;
   17.22 -static unsigned int ring_cons, ring_prod, ring_overflow;
   17.23 +struct per_user_data {
   17.24 +    /* Notification ring, accessed via /dev/xen/evtchn. */
   17.25 +#   define RING_SIZE     2048  /* 2048 16-bit entries */
   17.26 +#   define RING_MASK(_i) ((_i)&(RING_SIZE-1))
   17.27 +    u16 *ring;
   17.28 +    unsigned int ring_cons, ring_prod, ring_overflow;
   17.29  
   17.30 -/* Processes wait on this queue via /dev/xen/evtchn when ring is empty. */
   17.31 -static DECLARE_WAIT_QUEUE_HEAD(evtchn_wait);
   17.32 -static struct fasync_struct *evtchn_async_queue;
   17.33 +    /* Processes wait on this queue when ring is empty. */
   17.34 +    wait_queue_head_t evtchn_wait;
   17.35 +    struct fasync_struct *evtchn_async_queue;
   17.36 +};
   17.37  
   17.38 -/* Which ports is user-space bound to? */
   17.39 -static u32 bound_ports[32];
   17.40 -
   17.41 -static spinlock_t lock;
   17.42 +/* Who's bound to each port? */
   17.43 +static struct per_user_data *port_user[NR_EVENT_CHANNELS];
   17.44 +static spinlock_t port_user_lock;
   17.45  
   17.46  void evtchn_device_upcall(int port)
   17.47  {
   17.48 -    spin_lock(&lock);
   17.49 +    struct per_user_data *u;
   17.50 +
   17.51 +    spin_lock(&port_user_lock);
   17.52  
   17.53      mask_evtchn(port);
   17.54      clear_evtchn(port);
   17.55  
   17.56 -    if ( ring != NULL )
   17.57 +    if ( (u = port_user[port]) != NULL )
   17.58      {
   17.59 -        if ( (ring_prod - ring_cons) < RING_SIZE )
   17.60 +        if ( (u->ring_prod - u->ring_cons) < RING_SIZE )
   17.61          {
   17.62 -            ring[RING_MASK(ring_prod)] = (u16)port;
   17.63 -            if ( ring_cons == ring_prod++ )
   17.64 +            u->ring[RING_MASK(u->ring_prod)] = (u16)port;
   17.65 +            if ( u->ring_cons == u->ring_prod++ )
   17.66              {
   17.67 -                wake_up_interruptible(&evtchn_wait);
   17.68 -                kill_fasync(&evtchn_async_queue, SIGIO, POLL_IN);
   17.69 +                wake_up_interruptible(&u->evtchn_wait);
   17.70 +                kill_fasync(&u->evtchn_async_queue, SIGIO, POLL_IN);
   17.71              }
   17.72          }
   17.73          else
   17.74          {
   17.75 -            ring_overflow = 1;
   17.76 +            u->ring_overflow = 1;
   17.77          }
   17.78      }
   17.79  
   17.80 -    spin_unlock(&lock);
   17.81 -}
   17.82 -
   17.83 -static void __evtchn_reset_buffer_ring(void)
   17.84 -{
   17.85 -    /* Initialise the ring to empty. Clear errors. */
   17.86 -    ring_cons = ring_prod = ring_overflow = 0;
   17.87 +    spin_unlock(&port_user_lock);
   17.88  }
   17.89  
   17.90  static ssize_t evtchn_read(struct file *file, char *buf,
   17.91 @@ -115,8 +110,9 @@ static ssize_t evtchn_read(struct file *
   17.92      int rc;
   17.93      unsigned int c, p, bytes1 = 0, bytes2 = 0;
   17.94      DECLARE_WAITQUEUE(wait, current);
   17.95 +    struct per_user_data *u = file->private_data;
   17.96  
   17.97 -    add_wait_queue(&evtchn_wait, &wait);
   17.98 +    add_wait_queue(&u->evtchn_wait, &wait);
   17.99  
  17.100      count &= ~1; /* even number of bytes */
  17.101  
  17.102 @@ -133,10 +129,10 @@ static ssize_t evtchn_read(struct file *
  17.103      {
  17.104          set_current_state(TASK_INTERRUPTIBLE);
  17.105  
  17.106 -        if ( (c = ring_cons) != (p = ring_prod) )
  17.107 +        if ( (c = u->ring_cons) != (p = u->ring_prod) )
  17.108              break;
  17.109  
  17.110 -        if ( ring_overflow )
  17.111 +        if ( u->ring_overflow )
  17.112          {
  17.113              rc = -EFBIG;
  17.114              goto out;
  17.115 @@ -180,20 +176,20 @@ static ssize_t evtchn_read(struct file *
  17.116          bytes2 = count - bytes1;
  17.117      }
  17.118  
  17.119 -    if ( copy_to_user(buf, &ring[RING_MASK(c)], bytes1) ||
  17.120 -         ((bytes2 != 0) && copy_to_user(&buf[bytes1], &ring[0], bytes2)) )
  17.121 +    if ( copy_to_user(buf, &u->ring[RING_MASK(c)], bytes1) ||
  17.122 +         ((bytes2 != 0) && copy_to_user(&buf[bytes1], &u->ring[0], bytes2)) )
  17.123      {
  17.124          rc = -EFAULT;
  17.125          goto out;
  17.126      }
  17.127  
  17.128 -    ring_cons += (bytes1 + bytes2) / sizeof(u16);
  17.129 +    u->ring_cons += (bytes1 + bytes2) / sizeof(u16);
  17.130  
  17.131      rc = bytes1 + bytes2;
  17.132  
  17.133   out:
  17.134      __set_current_state(TASK_RUNNING);
  17.135 -    remove_wait_queue(&evtchn_wait, &wait);
  17.136 +    remove_wait_queue(&u->evtchn_wait, &wait);
  17.137      return rc;
  17.138  }
  17.139  
  17.140 @@ -202,6 +198,7 @@ static ssize_t evtchn_write(struct file 
  17.141  {
  17.142      int  rc, i;
  17.143      u16 *kbuf = (u16 *)__get_free_page(GFP_KERNEL);
  17.144 +    struct per_user_data *u = file->private_data;
  17.145  
  17.146      if ( kbuf == NULL )
  17.147          return -ENOMEM;
  17.148 @@ -223,11 +220,11 @@ static ssize_t evtchn_write(struct file 
  17.149          goto out;
  17.150      }
  17.151  
  17.152 -    spin_lock_irq(&lock);
  17.153 +    spin_lock_irq(&port_user_lock);
  17.154      for ( i = 0; i < (count/2); i++ )
  17.155 -        if ( test_bit(kbuf[i], (unsigned long *)&bound_ports[0]) )
  17.156 +        if ( (kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u) )
  17.157              unmask_evtchn(kbuf[i]);
  17.158 -    spin_unlock_irq(&lock);
  17.159 +    spin_unlock_irq(&port_user_lock);
  17.160  
  17.161      rc = count;
  17.162  
  17.163 @@ -240,32 +237,55 @@ static int evtchn_ioctl(struct inode *in
  17.164                          unsigned int cmd, unsigned long arg)
  17.165  {
  17.166      int rc = 0;
  17.167 -    
  17.168 -    spin_lock_irq(&lock);
  17.169 +    struct per_user_data *u = file->private_data;
  17.170 +
  17.171 +    spin_lock_irq(&port_user_lock);
  17.172      
  17.173      switch ( cmd )
  17.174      {
  17.175      case EVTCHN_RESET:
  17.176 -        __evtchn_reset_buffer_ring();
  17.177 +        /* Initialise the ring to empty. Clear errors. */
  17.178 +        u->ring_cons = u->ring_prod = u->ring_overflow = 0;
  17.179          break;
  17.180 +
  17.181      case EVTCHN_BIND:
  17.182 -        if ( !test_and_set_bit(arg, (unsigned long *)&bound_ports[0]) )
  17.183 -            unmask_evtchn(arg);
  17.184 -        else
  17.185 +        if ( arg >= NR_EVENT_CHANNELS )
  17.186 +        {
  17.187              rc = -EINVAL;
  17.188 +        }
  17.189 +        else if ( port_user[arg] != NULL )
  17.190 +        {
  17.191 +            rc = -EISCONN;
  17.192 +        }
  17.193 +        else
  17.194 +        {
  17.195 +            port_user[arg] = u;
  17.196 +            unmask_evtchn(arg);
  17.197 +        }
  17.198          break;
  17.199 +
  17.200      case EVTCHN_UNBIND:
  17.201 -        if ( test_and_clear_bit(arg, (unsigned long *)&bound_ports[0]) )
  17.202 +        if ( arg >= NR_EVENT_CHANNELS )
  17.203 +        {
  17.204 +            rc = -EINVAL;
  17.205 +        }
  17.206 +        else if ( port_user[arg] != u )
  17.207 +        {
  17.208 +            rc = -ENOTCONN;
  17.209 +        }
  17.210 +        else
  17.211 +        {
  17.212 +            port_user[arg] = NULL;
  17.213              mask_evtchn(arg);
  17.214 -        else
  17.215 -            rc = -EINVAL;
  17.216 +        }
  17.217          break;
  17.218 +
  17.219      default:
  17.220          rc = -ENOSYS;
  17.221          break;
  17.222      }
  17.223  
  17.224 -    spin_unlock_irq(&lock);   
  17.225 +    spin_unlock_irq(&port_user_lock);   
  17.226  
  17.227      return rc;
  17.228  }
  17.229 @@ -273,34 +293,39 @@ static int evtchn_ioctl(struct inode *in
  17.230  static unsigned int evtchn_poll(struct file *file, poll_table *wait)
  17.231  {
  17.232      unsigned int mask = POLLOUT | POLLWRNORM;
  17.233 -    poll_wait(file, &evtchn_wait, wait);
  17.234 -    if ( ring_cons != ring_prod )
  17.235 +    struct per_user_data *u = file->private_data;
  17.236 +
  17.237 +    poll_wait(file, &u->evtchn_wait, wait);
  17.238 +    if ( u->ring_cons != u->ring_prod )
  17.239          mask |= POLLIN | POLLRDNORM;
  17.240 -    if ( ring_overflow )
  17.241 +    if ( u->ring_overflow )
  17.242          mask = POLLERR;
  17.243      return mask;
  17.244  }
  17.245  
  17.246  static int evtchn_fasync(int fd, struct file *filp, int on)
  17.247  {
  17.248 -    return fasync_helper(fd, filp, on, &evtchn_async_queue);
  17.249 +    struct per_user_data *u = filp->private_data;
  17.250 +    return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
  17.251  }
  17.252  
  17.253  static int evtchn_open(struct inode *inode, struct file *filp)
  17.254  {
  17.255 -    u16 *_ring;
  17.256 +    struct per_user_data *u;
  17.257  
  17.258 -    if ( test_and_set_bit(0, &evtchn_dev_inuse) )
  17.259 -        return -EBUSY;
  17.260 -
  17.261 -    /* Allocate outside locked region so that we can use GFP_KERNEL. */
  17.262 -    if ( (_ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL )
  17.263 +    if ( (u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL )
  17.264          return -ENOMEM;
  17.265  
  17.266 -    spin_lock_irq(&lock);
  17.267 -    ring = _ring;
  17.268 -    __evtchn_reset_buffer_ring();
  17.269 -    spin_unlock_irq(&lock);
  17.270 +    memset(u, 0, sizeof(*u));
  17.271 +    init_waitqueue_head(&u->evtchn_wait);
  17.272 +
  17.273 +    if ( (u->ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL )
  17.274 +    {
  17.275 +        kfree(u);
  17.276 +        return -ENOMEM;
  17.277 +    }
  17.278 +
  17.279 +    filp->private_data = u;
  17.280  
  17.281      MOD_INC_USE_COUNT;
  17.282  
  17.283 @@ -310,19 +335,22 @@ static int evtchn_open(struct inode *ino
  17.284  static int evtchn_release(struct inode *inode, struct file *filp)
  17.285  {
  17.286      int i;
  17.287 +    struct per_user_data *u = filp->private_data;
  17.288  
  17.289 -    spin_lock_irq(&lock);
  17.290 -    if ( ring != NULL )
  17.291 +    spin_lock_irq(&port_user_lock);
  17.292 +
  17.293 +    free_page((unsigned long)u->ring);
  17.294 +
  17.295 +    for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
  17.296      {
  17.297 -        free_page((unsigned long)ring);
  17.298 -        ring = NULL;
  17.299 +        if ( port_user[i] == u )
  17.300 +        {
  17.301 +            port_user[i] = NULL;
  17.302 +            mask_evtchn(i);
  17.303 +        }
  17.304      }
  17.305 -    for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
  17.306 -        if ( test_and_clear_bit(i, (unsigned long *)&bound_ports[0]) )
  17.307 -            mask_evtchn(i);
  17.308 -    spin_unlock_irq(&lock);
  17.309  
  17.310 -    evtchn_dev_inuse = 0;
  17.311 +    spin_unlock_irq(&port_user_lock);
  17.312  
  17.313      MOD_DEC_USE_COUNT;
  17.314  
  17.315 @@ -358,6 +386,9 @@ static int __init evtchn_init(void)
  17.316  #endif
  17.317      int err;
  17.318  
  17.319 +    spin_lock_init(&port_user_lock);
  17.320 +    memset(port_user, 0, sizeof(port_user));
  17.321 +
  17.322      /* (DEVFS) create '/dev/misc/evtchn'. */
  17.323      err = misc_register(&evtchn_miscdev);
  17.324      if ( err != 0 )
    18.1 --- a/linux-2.6.9-xen-sparse/include/asm-generic/pgtable.h	Tue Nov 16 18:59:47 2004 +0000
    18.2 +++ b/linux-2.6.9-xen-sparse/include/asm-generic/pgtable.h	Wed Nov 17 10:16:18 2004 +0000
    18.3 @@ -43,6 +43,9 @@ do {				  					  \
    18.4  #endif
    18.5  
    18.6  #ifndef __HAVE_ARCH_PTEP_ESTABLISH_NEW
    18.7 +/*
    18.8 + * Establish a mapping where none previously existed
    18.9 + */
   18.10  #define ptep_establish_new(__vma, __address, __ptep, __entry)		\
   18.11  do {									\
   18.12  	set_pte(__ptep, __entry);					\
    19.1 --- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Tue Nov 16 18:59:47 2004 +0000
    19.2 +++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Wed Nov 17 10:16:18 2004 +0000
    19.3 @@ -32,7 +32,7 @@ extern struct page *pte_alloc_one(struct
    19.4  static inline void pte_free_kernel(pte_t *pte)
    19.5  {
    19.6  	free_page((unsigned long)pte);
    19.7 -	__make_page_writable(pte);
    19.8 +	make_page_writable(pte);
    19.9  	flush_page_update_queue();
   19.10  }
   19.11  
    20.1 --- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Tue Nov 16 18:59:47 2004 +0000
    20.2 +++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Wed Nov 17 10:16:18 2004 +0000
    20.3 @@ -23,6 +23,9 @@ static inline int pgd_present(pgd_t pgd)
    20.4   * within a page table are directly modified.  Thus, the following
    20.5   * hook is made available.
    20.6   */
    20.7 +#define set_pte_batched(pteptr, pteval) \
    20.8 +queue_l1_entry_update(pteptr, (pteval).pte_low)
    20.9 +
   20.10  #ifdef CONFIG_SMP
   20.11  #define set_pte(pteptr, pteval) xen_l1_entry_update(pteptr, (pteval).pte_low)
   20.12  #if 0
   20.13 @@ -33,13 +36,8 @@ do { \
   20.14  #endif
   20.15  #define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval)
   20.16  #else
   20.17 -#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
   20.18  #define set_pte(pteptr, pteval) (*(pteptr) = pteval)
   20.19 -#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval)
   20.20 -#else
   20.21 -#define set_pte(pteptr, pteval) xen_l1_entry_update(pteptr, (pteval).pte_low)
   20.22 -#define set_pte_atomic(pteptr, pteval) xen_l1_entry_update(pteptr, (pteval).pte_low)
   20.23 -#endif
   20.24 +#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
   20.25  #endif
   20.26  /*
   20.27   * (pmds are folded into pgds so this doesn't get actually called,
    21.1 --- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Tue Nov 16 18:59:47 2004 +0000
    21.2 +++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Wed Nov 17 10:16:18 2004 +0000
    21.3 @@ -465,61 +465,12 @@ do {				  					\
    21.4  } while (0)
    21.5  
    21.6  /* NOTE: make_page* callers must call flush_page_update_queue() */
    21.7 -static inline void __make_page_readonly(void *va)
    21.8 -{
    21.9 -	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   21.10 -	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   21.11 -	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   21.12 -	queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
   21.13 -}
   21.14 -
   21.15 -static inline void __make_page_writable(void *va)
   21.16 -{
   21.17 -	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   21.18 -	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   21.19 -	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   21.20 -	queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
   21.21 -}
   21.22 -
   21.23 -static inline void make_page_readonly(void *va)
   21.24 -{
   21.25 -	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   21.26 -	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   21.27 -	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   21.28 -	queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
   21.29 -	if ( (unsigned long)va >= VMALLOC_START )
   21.30 -		__make_page_readonly(machine_to_virt(
   21.31 -			*(unsigned long *)pte&PAGE_MASK));
   21.32 -}
   21.33 -
   21.34 -static inline void make_page_writable(void *va)
   21.35 -{
   21.36 -	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   21.37 -	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   21.38 -	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   21.39 -	queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
   21.40 -	if ( (unsigned long)va >= VMALLOC_START )
   21.41 -		__make_page_writable(machine_to_virt(
   21.42 -			*(unsigned long *)pte&PAGE_MASK));
   21.43 -}
   21.44 -
   21.45 -static inline void make_pages_readonly(void *va, unsigned int nr)
   21.46 -{
   21.47 -	while ( nr-- != 0 )
   21.48 -	{
   21.49 -		make_page_readonly(va);
   21.50 -		va = (void *)((unsigned long)va + PAGE_SIZE);
   21.51 -	}
   21.52 -}
   21.53 -
   21.54 -static inline void make_pages_writable(void *va, unsigned int nr)
   21.55 -{
   21.56 -	while ( nr-- != 0 )
   21.57 -	{
   21.58 -		make_page_writable(va);
   21.59 -		va = (void *)((unsigned long)va + PAGE_SIZE);
   21.60 -	}
   21.61 -}
   21.62 +void make_lowmem_page_readonly(void *va);
   21.63 +void make_lowmem_page_writable(void *va);
   21.64 +void make_page_readonly(void *va);
   21.65 +void make_page_writable(void *va);
   21.66 +void make_pages_readonly(void *va, unsigned int nr);
   21.67 +void make_pages_writable(void *va, unsigned int nr);
   21.68  
   21.69  static inline unsigned long arbitrary_virt_to_phys(void *va)
   21.70  {
   21.71 @@ -536,7 +487,8 @@ static inline unsigned long arbitrary_vi
   21.72  #define kern_addr_valid(addr)	(1)
   21.73  #endif /* !CONFIG_DISCONTIGMEM */
   21.74  
   21.75 -#define io_remap_page_range remap_page_range
   21.76 +#define io_remap_page_range(vma,from,phys,size,prot)                     \
   21.77 +        direct_remap_area_pages(vma->vm_mm,from,phys,size,prot,DOMID_IO)
   21.78  
   21.79  #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
   21.80  #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
    22.1 --- a/tools/examples/init.d/xend	Tue Nov 16 18:59:47 2004 +0000
    22.2 +++ b/tools/examples/init.d/xend	Wed Nov 17 10:16:18 2004 +0000
    22.3 @@ -7,9 +7,24 @@
    22.4  # chkconfig: 2345 98 01
    22.5  # description: Starts and stops the Xen control daemon.
    22.6  
    22.7 +# Wait for Xend / Xfrd to be up
    22.8 +function await_daemons_up
    22.9 +{
   22.10 +	i=1
   22.11 +	rets=10
   22.12 +	xend status
   22.13 +	while [ $? -ne 0 -a $i -lt $rets ]; do
   22.14 +	    sleep 1
   22.15 +	    echo -n .
   22.16 +	    i=$(($i + 1))
   22.17 +	    xend status
   22.18 +	done
   22.19 +}
   22.20 +
   22.21  case "$1" in
   22.22    start)
   22.23  	xend start
   22.24 +	await_daemons_up
   22.25  	;;
   22.26    stop)
   22.27  	xend stop
   22.28 @@ -19,6 +34,7 @@ case "$1" in
   22.29  	;;
   22.30    restart|reload)
   22.31  	xend restart
   22.32 +	await_daemons_up
   22.33  	;;
   22.34    *)
   22.35  	# do not advertise unreasonable commands that there is no reason
    23.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Nov 16 18:59:47 2004 +0000
    23.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Nov 17 10:16:18 2004 +0000
    23.3 @@ -971,8 +971,8 @@ class XendDomainInfo:
    23.4  
    23.5          @return: deferred - calls callback with vm
    23.6          """
    23.7 -        d = self.create_blkif()
    23.8 -        d.addCallback(lambda x: self.create_devices())
    23.9 +        d = self.create_devices()
   23.10 +        d.addCallback(lambda x: self.create_blkif())
   23.11          d.addCallback(self._configure)
   23.12          return d
   23.13  
   23.14 @@ -994,9 +994,12 @@ class XendDomainInfo:
   23.15  
   23.16          @return: deferred
   23.17          """
   23.18 -        ctrl = xend.blkif_create(self.dom, recreate=self.recreate)
   23.19 -        back = ctrl.getBackendInterface(0)
   23.20 -        return back.connect(recreate=self.recreate)
   23.21 +        if (self.get_devices("vbd") == None):
   23.22 +            ctrl = xend.blkif_create(self.dom, recreate=self.recreate)
   23.23 +            back = ctrl.getBackendInterface(0)
   23.24 +            return back.connect(recreate=self.recreate)
   23.25 +        else:
   23.26 +            return None
   23.27      
   23.28      def dom_construct(self, dom, config):
   23.29          """Construct a vm for an existing domain.
    24.1 --- a/tools/python/xen/xend/server/blkif.py	Tue Nov 16 18:59:47 2004 +0000
    24.2 +++ b/tools/python/xen/xend/server/blkif.py	Wed Nov 17 10:16:18 2004 +0000
    24.3 @@ -187,7 +187,7 @@ class BlkifBackendInterface(controller.B
    24.4          self.writeRequest(msg, response=response)
    24.5  
    24.6      def connectInterface(self, val):
    24.7 -        self.evtchn = channel.eventChannel(0, self.controller.dom)
    24.8 +        self.evtchn = channel.eventChannel(self.dom, self.controller.dom)
    24.9          log.debug("Connecting blkif to event channel %s ports=%d:%d",
   24.10                    str(self), self.evtchn['port1'], self.evtchn['port2'])
   24.11          msg = packMsg('blkif_be_connect_t',
    25.1 --- a/tools/python/xen/xend/server/netif.py	Tue Nov 16 18:59:47 2004 +0000
    25.2 +++ b/tools/python/xen/xend/server/netif.py	Wed Nov 17 10:16:18 2004 +0000
    25.3 @@ -307,7 +307,7 @@ class NetDev(controller.SplitDev):
    25.4      
    25.5      def recv_fe_interface_connect(self, val, req):
    25.6          if not req: return
    25.7 -        self.evtchn = channel.eventChannel(0, self.controller.dom)
    25.8 +        self.evtchn = channel.eventChannel(self.dom, self.controller.dom)
    25.9          msg = packMsg('netif_be_connect_t',
   25.10                        { 'domid'          : self.controller.dom,
   25.11                          'netif_handle'   : self.vif,
    26.1 --- a/xen/arch/x86/memory.c	Tue Nov 16 18:59:47 2004 +0000
    26.2 +++ b/xen/arch/x86/memory.c	Wed Nov 17 10:16:18 2004 +0000
    26.3 @@ -1590,7 +1590,7 @@ void ptwr_flush(const int which)
    26.4  {
    26.5      unsigned long  sstat, spte, pte, *ptep, l1va;
    26.6      l1_pgentry_t  *sl1e = NULL, *pl1e, ol1e, nl1e;
    26.7 -    l2_pgentry_t  *pl2e, nl2e;
    26.8 +    l2_pgentry_t  *pl2e;
    26.9      int            i, cpu = smp_processor_id();
   26.10      struct exec_domain *ed = current;
   26.11      struct domain *d = ed->domain;
   26.12 @@ -1710,8 +1710,7 @@ void ptwr_flush(const int which)
   26.13      if ( (which == PTWR_PT_ACTIVE) && likely(!ed->mm.shadow_mode) )
   26.14      {
   26.15          pl2e = &linear_l2_table[ptwr_info[cpu].ptinfo[which].l2_idx];
   26.16 -        nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
   26.17 -        update_l2e(pl2e, *pl2e, nl2e);
   26.18 +        *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); 
   26.19      }
   26.20  
   26.21      /*
   26.22 @@ -1730,9 +1729,9 @@ void ptwr_flush(const int which)
   26.23  /* Write page fault handler: check if guest is trying to modify a PTE. */
   26.24  int ptwr_do_page_fault(unsigned long addr)
   26.25  {
   26.26 -    unsigned long    pte, pfn;
   26.27 +    unsigned long    pte, pfn, l2e;
   26.28      struct pfn_info *page;
   26.29 -    l2_pgentry_t    *pl2e, nl2e;
   26.30 +    l2_pgentry_t    *pl2e;
   26.31      int              which, cpu = smp_processor_id();
   26.32      u32              l2_idx;
   26.33      struct domain   *d = current->domain;
   26.34 @@ -1769,14 +1768,34 @@ int ptwr_do_page_fault(unsigned long add
   26.35          domain_crash(); /* Urk! This L1 is mapped in multiple L2 slots! */
   26.36      }
   26.37      l2_idx >>= PGT_va_shift;
   26.38 -        
   26.39 +
   26.40 +    if ( l2_idx == (addr >> L2_PAGETABLE_SHIFT) )
   26.41 +    {
   26.42 +        MEM_LOG("PTWR failure! Pagetable maps itself at %08lx\n", addr);
   26.43 +        domain_crash();
   26.44 +    }
   26.45 +
   26.46      /*
   26.47       * Is the L1 p.t. mapped into the current address space? If so we call it
   26.48       * an ACTIVE p.t., otherwise it is INACTIVE.
   26.49       */
   26.50      pl2e = &linear_l2_table[l2_idx];
   26.51 -    which = (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) ?
   26.52 -        PTWR_PT_INACTIVE : PTWR_PT_ACTIVE;
   26.53 +    l2e  = l2_pgentry_val(*pl2e);
   26.54 +    which = PTWR_PT_INACTIVE;
   26.55 +    if ( (l2e >> PAGE_SHIFT) == pfn )
   26.56 +    {
   26.57 +        /*
   26.58 +         * If the PRESENT bit is clear, we may be conflicting with the current 
   26.59 +         * ACTIVE p.t. (it may be the same p.t. mapped at another virt addr).
   26.60 +         */
   26.61 +        if ( unlikely(!(l2e & _PAGE_PRESENT)) &&
   26.62 +             ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va )
   26.63 +            ptwr_flush(PTWR_PT_ACTIVE);
   26.64 +        
   26.65 +        /* Now do a final check of the PRESENT bit to set ACTIVE. */
   26.66 +        if ( likely(l2e & _PAGE_PRESENT) )
   26.67 +            which = PTWR_PT_ACTIVE;
   26.68 +    }
   26.69      
   26.70      PTWR_PRINTK("[%c] page_fault on l1 pt at va %08lx, pt for %08x, "
   26.71                  "pfn %08lx\n", PTWR_PRINT_WHICH,
   26.72 @@ -1795,8 +1814,7 @@ int ptwr_do_page_fault(unsigned long add
   26.73      /* For safety, disconnect the L1 p.t. page from current space. */
   26.74      if ( (which == PTWR_PT_ACTIVE) && likely(!current->mm.shadow_mode) )
   26.75      {
   26.76 -        nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT);
   26.77 -        update_l2e(pl2e, *pl2e, nl2e);
   26.78 +        *pl2e = mk_l2_pgentry(l2e & ~_PAGE_PRESENT);
   26.79  #if 0
   26.80          flush_tlb(); /* XXX Multi-CPU guests? */
   26.81  #else
    27.1 --- a/xen/common/keyhandler.c	Tue Nov 16 18:59:47 2004 +0000
    27.2 +++ b/xen/common/keyhandler.c	Wed Nov 17 10:16:18 2004 +0000
    27.3 @@ -89,7 +89,7 @@ static void dump_registers(unsigned char
    27.4      show_registers(regs); 
    27.5  }
    27.6  
    27.7 -static void halt_machine(unsigned char key)
    27.8 +static void halt_machine(unsigned char key, struct xen_regs *regs)
    27.9  {
   27.10      printk("'%c' pressed -> rebooting machine\n", key); 
   27.11      machine_restart(NULL); 
   27.12 @@ -179,7 +179,7 @@ void initialize_keytable(void)
   27.13          'q', do_task_queues, "dump task queues + guest state");
   27.14      register_keyhandler(
   27.15          'r', dump_runq,      "dump run queues");
   27.16 -    register_keyhandler(
   27.17 +    register_irq_keyhandler(
   27.18          'R', halt_machine,   "reboot machine"); 
   27.19  
   27.20  #ifndef NDEBUG