[kernel] r6128 - in dists/trunk/linux-2.6/debian/patches: . series

Bastian Blank waldi at costa.debian.org
Sat Mar 11 18:10:27 UTC 2006


Author: waldi
Date: Sat Mar 11 18:10:24 2006
New Revision: 6128

Added:
   dists/trunk/linux-2.6/debian/patches/series/0experimental.2-extra
   dists/trunk/linux-2.6/debian/patches/xen-tree-merge-21966-update.patch   (contents, props changed)
Log:
Update xen patch.

* debian/patches/series/0experimental.2-extra: Update.
* debian/patches/xen-tree-merge-21966-update.patch: Add.


Added: dists/trunk/linux-2.6/debian/patches/series/0experimental.2-extra
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/series/0experimental.2-extra	Sat Mar 11 18:10:24 2006
@@ -0,0 +1 @@
++ xen-tree-merge-21966-update.patch *_xen

Added: dists/trunk/linux-2.6/debian/patches/xen-tree-merge-21966-update.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/xen-tree-merge-21966-update.patch	Sat Mar 11 18:10:24 2006
@@ -0,0 +1,10168 @@
+diff -r c75ede70c907 -r f6bd46559b93 arch/i386/kernel/entry-xen.S
+--- a/arch/i386/kernel/entry-xen.S	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/i386/kernel/entry-xen.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -560,7 +560,7 @@ 11:	push %esp
+ 	jmp  ret_from_intr
+ 
+         ALIGN
+-restore_all_enable_events:  
++restore_all_enable_events:
+ 	XEN_LOCKED_UNBLOCK_EVENTS(%esi)
+ scrit:	/**** START OF CRITICAL REGION ****/
+ 	XEN_TEST_PENDING(%esi)
+@@ -577,7 +577,7 @@ ecrit:  /**** END OF CRITICAL REGION ***
+ # registers are in each frame. We do this quickly using the lookup table
+ # 'critical_fixup_table'. For each byte offset in the critical region, it
+ # provides the number of bytes which have already been popped from the
+-# interrupted stack frame. 
++# interrupted stack frame.
+ critical_region_fixup:
+ 	addl $critical_fixup_table-scrit,%eax
+ 	movzbl (%eax),%eax		# %eax contains num bytes popped
+diff -r c75ede70c907 -r f6bd46559b93 arch/i386/kernel/head-xen.S
+--- a/arch/i386/kernel/head-xen.S	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/i386/kernel/head-xen.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -29,8 +29,6 @@ ENTRY(startup_32)
+ 
+ 	/* Set up the stack pointer */
+ 	movl $(init_thread_union+THREAD_SIZE),%esp
+-
+-checkCPUtype:
+ 
+ 	/* get vendor info */
+ 	xorl %eax,%eax			# call CPUID with 0 -> return vendor ID
+diff -r c75ede70c907 -r f6bd46559b93 arch/i386/kernel/io_apic-xen.c
+--- a/arch/i386/kernel/io_apic-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/i386/kernel/io_apic-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -61,8 +61,8 @@ static inline unsigned int xen_io_apic_r
+ 	int ret;
+ 
+ 	op.cmd = PHYSDEVOP_APIC_READ;
+-	op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
+-	op.u.apic_op.offset = reg;
++	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
++	op.u.apic_op.reg = reg;
+ 	ret = HYPERVISOR_physdev_op(&op);
+ 	if (ret)
+ 		return ret;
+@@ -74,8 +74,8 @@ static inline void xen_io_apic_write(uns
+ 	physdev_op_t op;
+ 
+ 	op.cmd = PHYSDEVOP_APIC_WRITE;
+-	op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
+-	op.u.apic_op.offset = reg;
++	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
++	op.u.apic_op.reg = reg;
+ 	op.u.apic_op.value = value;
+ 	HYPERVISOR_physdev_op(&op);
+ }
+diff -r c75ede70c907 -r f6bd46559b93 arch/i386/kernel/process-xen.c
+--- a/arch/i386/kernel/process-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/i386/kernel/process-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -107,9 +107,9 @@ void xen_idle(void)
+ {
+ 	local_irq_disable();
+ 
+-	if (need_resched()) {
++	if (need_resched())
+ 		local_irq_enable();
+-	} else {
++	else {
+ 		clear_thread_flag(TIF_POLLING_NRFLAG);
+ 		smp_mb__after_clear_bit();
+ 		stop_hz_timer();
+diff -r c75ede70c907 -r f6bd46559b93 arch/i386/kernel/time-xen.c
+--- a/arch/i386/kernel/time-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/i386/kernel/time-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -160,13 +160,12 @@ static void delay_tsc(unsigned long loop
+ static void delay_tsc(unsigned long loops)
+ {
+ 	unsigned long bclock, now;
+-	
++
+ 	rdtscl(bclock);
+-	do
+-	{
++	do {
+ 		rep_nop();
+ 		rdtscl(now);
+-	} while ((now-bclock) < loops);
++	} while ((now - bclock) < loops);
+ }
+ 
+ static struct timer_opts timer_tsc = {
+@@ -187,7 +186,7 @@ static inline u64 scale_delta(u64 delta,
+ 	u32 tmp1, tmp2;
+ #endif
+ 
+-	if ( shift < 0 )
++	if (shift < 0)
+ 		delta >>= -shift;
+ 	else
+ 		delta <<= shift;
+@@ -226,7 +225,7 @@ void init_cpu_khz(void)
+ 	struct vcpu_time_info *info;
+ 	info = &HYPERVISOR_shared_info->vcpu_info[0].time;
+ 	do_div(__cpu_khz, info->tsc_to_system_mul);
+-	if ( info->tsc_shift < 0 )
++	if (info->tsc_shift < 0)
+ 		cpu_khz = __cpu_khz << -info->tsc_shift;
+ 	else
+ 		cpu_khz = __cpu_khz >> info->tsc_shift;
+@@ -284,8 +283,7 @@ static void update_wallclock(void)
+ 		shadow_tv.tv_sec  = s->wc_sec;
+ 		shadow_tv.tv_nsec = s->wc_nsec;
+ 		rmb();
+-	}
+-	while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
++	} while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
+ 
+ 	if (!independent_wallclock)
+ 		__update_wallclock(shadow_tv.tv_sec, shadow_tv.tv_nsec);
+@@ -312,8 +310,7 @@ static void get_time_values_from_xen(voi
+ 		dst->tsc_to_nsec_mul   = src->tsc_to_system_mul;
+ 		dst->tsc_shift         = src->tsc_shift;
+ 		rmb();
+-	}
+-	while ((src->version & 1) | (dst->version ^ src->version));
++	} while ((src->version & 1) | (dst->version ^ src->version));
+ 
+ 	dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
+ }
+@@ -324,7 +321,7 @@ static inline int time_values_up_to_date
+ 	struct shadow_time_info *dst;
+ 
+ 	src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
+-	dst = &per_cpu(shadow_time, cpu); 
++	dst = &per_cpu(shadow_time, cpu);
+ 
+ 	return (dst->version == src->version);
+ }
+@@ -456,7 +453,7 @@ int do_settimeofday(struct timespec *tv)
+ 	 * overflows. If that were to happen then our shadow time values would
+ 	 * be stale, so we can retry with fresh ones.
+ 	 */
+-	for ( ; ; ) {
++	for (;;) {
+ 		nsec = tv->tv_nsec - get_nsec_offset(shadow);
+ 		if (time_values_up_to_date(cpu))
+ 			break;
+@@ -640,7 +637,7 @@ irqreturn_t timer_interrupt(int irq, voi
+ 		get_time_values_from_xen();
+ 
+ 		/* Obtain a consistent snapshot of elapsed wallclock cycles. */
+-		delta = delta_cpu = 
++		delta = delta_cpu =
+ 			shadow->system_timestamp + get_nsec_offset(shadow);
+ 		delta     -= processed_system_time;
+ 		delta_cpu -= per_cpu(processed_system_time, cpu);
+@@ -659,8 +656,7 @@ irqreturn_t timer_interrupt(int irq, voi
+ 				per_cpu(processed_blocked_time, cpu);
+ 			barrier();
+ 		} while (sched_time != runstate->state_entry_time);
+-	}
+-	while (!time_values_up_to_date(cpu));
++	} while (!time_values_up_to_date(cpu));
+ 
+ 	if ((unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0))
+ 	    && printk_ratelimit()) {
+@@ -1012,7 +1008,7 @@ void __init time_init(void)
+ }
+ 
+ /* Convert jiffies to system time. */
+-static inline u64 jiffies_to_st(unsigned long j) 
++static inline u64 jiffies_to_st(unsigned long j)
+ {
+ 	unsigned long seq;
+ 	long delta;
+@@ -1023,7 +1019,7 @@ static inline u64 jiffies_to_st(unsigned
+ 		delta = j - jiffies;
+ 		/* NB. The next check can trigger in some wrap-around cases,
+ 		 * but that's ok: we'll just end up with a shorter timeout. */
+-		if (delta < 1) 
++		if (delta < 1)
+ 			delta = 1;
+ 		st = processed_system_time + (delta * (u64)NS_PER_TICK);
+ 	} while (read_seqretry(&xtime_lock, seq));
+@@ -1039,7 +1035,7 @@ void stop_hz_timer(void)
+ {
+ 	unsigned int cpu = smp_processor_id();
+ 	unsigned long j;
+-	
++
+ 	/* We must do this /before/ checking rcu_pending(). */
+ 	cpu_set(cpu, nohz_cpu_mask);
+ 	smp_mb();
+@@ -1086,7 +1082,7 @@ void local_setup_timer(unsigned int cpu)
+ 	do {
+ 		seq = read_seqbegin(&xtime_lock);
+ 		/* Use cpu0 timestamp: cpu's shadow is not initialised yet. */
+-		per_cpu(processed_system_time, cpu) = 
++		per_cpu(processed_system_time, cpu) =
+ 			per_cpu(shadow_time, 0).system_timestamp;
+ 		init_missing_ticks_accounting(cpu);
+ 	} while (read_seqretry(&xtime_lock, seq));
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/Kconfig
+--- a/arch/ia64/Kconfig	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/Kconfig	Mon Mar  6 17:57:34 2006 +0000
+@@ -49,6 +49,53 @@ config GENERIC_IOMAP
+ config GENERIC_IOMAP
+ 	bool
+ 	default y
++
++config XEN
++	bool
++	default y
++	help
++	  Enable Xen hypervisor support.  Resulting kernel runs
++	  both as a guest OS on Xen and natively on hardware.
++
++config ARCH_XEN
++	bool
++	default y
++	help
++	  TEMP ONLY. Needs to be on for drivers/xen to build.
++
++config XEN_PRIVILEGED_GUEST
++	bool "Privileged Guest"
++	default n
++	help
++	  Used in drivers/xen/privcmd.c.  Should go away?
++
++config XEN_BLKDEV_GRANT
++	depends on XEN
++	bool
++	default y
++
++config XEN_BLKDEV_FRONTEND
++	depends on XEN
++	bool
++	default y
++
++config XEN_BLKDEV_BACKEND
++	depends on XEN
++	bool
++	default y
++
++config XEN_VT
++	bool "Override for turning on CONFIG_VT for domU"
++	default y
++	help
++	  Hack to turn off CONFIG_VT for domU
++
++config VT
++	bool
++	default y if XEN && XEN_VT
++	default n if XEN && !XEN_VT
++	help
++	  Hack to turn off CONFIG_VT for domU
+ 
+ config SCHED_NO_NO_OMIT_FRAME_POINTER
+ 	bool
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/Makefile
+--- a/arch/ia64/Makefile	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -52,9 +52,15 @@ core-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/
+ core-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/dig/
+ core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
+ core-$(CONFIG_IA64_SGI_SN2)	+= arch/ia64/sn/
++core-$(CONFIG_XEN)		+= arch/ia64/xen/
+ 
+ drivers-$(CONFIG_PCI)		+= arch/ia64/pci/
++ifneq ($(CONFIG_XEN),y)
+ drivers-$(CONFIG_IA64_HP_SIM)	+= arch/ia64/hp/sim/
++endif
++ifneq ($(CONFIG_IA64_GENERIC),y)
++drivers-$(CONFIG_XEN)		+= arch/ia64/hp/sim/
++endif
+ drivers-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/
+ drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
+ drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/
+@@ -67,6 +73,8 @@ all: compressed unwcheck
+ all: compressed unwcheck
+ 
+ compressed: vmlinux.gz
++
++vmlinuz: vmlinux.gz
+ 
+ vmlinux.gz: vmlinux
+ 	$(Q)$(MAKE) $(build)=$(boot) $@
+@@ -82,7 +90,7 @@ boot:	lib/lib.a vmlinux
+ boot:	lib/lib.a vmlinux
+ 	$(Q)$(MAKE) $(build)=$(boot) $@
+ 
+-install: vmlinux.gz
++install:
+ 	sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
+ 
+ define archhelp
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/hp/sim/Makefile
+--- a/arch/ia64/hp/sim/Makefile	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/hp/sim/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -14,3 +14,5 @@ obj-$(CONFIG_HP_SIMSERIAL) += simserial.
+ obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
+ obj-$(CONFIG_HP_SIMSERIAL_CONSOLE) += hpsim_console.o
+ obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
++obj-$(CONFIG_XEN) += simserial.o
++obj-$(CONFIG_XEN) += hpsim_console.o
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/kernel/entry.S
+--- a/arch/ia64/kernel/entry.S	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/kernel/entry.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -181,7 +181,7 @@ END(sys_clone)
+  *	called.  The code starting at .map relies on this.  The rest of the code
+  *	doesn't care about the interrupt masking status.
+  */
+-GLOBAL_ENTRY(ia64_switch_to)
++GLOBAL_ENTRY(__ia64_switch_to)
+ 	.prologue
+ 	alloc r16=ar.pfs,1,0,0,0
+ 	DO_SAVE_SWITCH_STACK
+@@ -235,7 +235,7 @@ GLOBAL_ENTRY(ia64_switch_to)
+ 	;;
+ 	srlz.d
+ 	br.cond.sptk .done
+-END(ia64_switch_to)
++END(__ia64_switch_to)
+ 
+ /*
+  * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
+@@ -376,7 +376,7 @@ END(save_switch_stack)
+  *	- b7 holds address to return to
+  *	- must not touch r8-r11
+  */
+-ENTRY(load_switch_stack)
++GLOBAL_ENTRY(load_switch_stack)
+ 	.prologue
+ 	.altrp b7
+ 
+@@ -511,7 +511,7 @@ END(clone)
+ 	 * because some system calls (such as ia64_execve) directly
+ 	 * manipulate ar.pfs.
+ 	 */
+-GLOBAL_ENTRY(ia64_trace_syscall)
++GLOBAL_ENTRY(__ia64_trace_syscall)
+ 	PT_REGS_UNWIND_INFO(0)
+ 	/*
+ 	 * We need to preserve the scratch registers f6-f11 in case the system
+@@ -583,7 +583,7 @@ strace_error:
+ (p6)	mov r10=-1
+ (p6)	mov r8=r9
+ 	br.cond.sptk .strace_save_retval
+-END(ia64_trace_syscall)
++END(__ia64_trace_syscall)
+ 
+ 	/*
+ 	 * When traced and returning from sigreturn, we invoke syscall_trace but then
+@@ -636,8 +636,11 @@ GLOBAL_ENTRY(ia64_ret_from_syscall)
+ 	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
+ 	mov r10=r0				// clear error indication in r10
+ (p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
++	;;
++	// don't fall through, ia64_leave_syscall may be #define'd
++	br.cond.sptk.few ia64_leave_syscall
++	;;
+ END(ia64_ret_from_syscall)
+-	// fall through
+ /*
+  * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
+  *	need to switch to bank 0 and doesn't restore the scratch registers.
+@@ -682,7 +685,7 @@ END(ia64_ret_from_syscall)
+  *	      ar.csd: cleared
+  *	      ar.ssd: cleared
+  */
+-ENTRY(ia64_leave_syscall)
++GLOBAL_ENTRY(__ia64_leave_syscall)
+ 	PT_REGS_UNWIND_INFO(0)
+ 	/*
+ 	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
+@@ -790,7 +793,7 @@ ENTRY(ia64_leave_syscall)
+ 	mov.m ar.ssd=r0			// M2   clear ar.ssd
+ 	mov f11=f0			// F    clear f11
+ 	br.cond.sptk.many rbs_switch	// B
+-END(ia64_leave_syscall)
++END(__ia64_leave_syscall)
+ 
+ #ifdef CONFIG_IA32_SUPPORT
+ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
+@@ -802,10 +805,13 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
+ 	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
+ 	.mem.offset 8,0
+ 	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
++	;;
++	// don't fall through, ia64_leave_kernel may be #define'd
++	br.cond.sptk.few ia64_leave_kernel
++	;;
+ END(ia64_ret_from_ia32_execve)
+-	// fall through
+ #endif /* CONFIG_IA32_SUPPORT */
+-GLOBAL_ENTRY(ia64_leave_kernel)
++GLOBAL_ENTRY(__ia64_leave_kernel)
+ 	PT_REGS_UNWIND_INFO(0)
+ 	/*
+ 	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
+@@ -1150,7 +1156,7 @@ skip_rbs_switch:
+ 	ld8 r10=[r3]
+ 	br.cond.sptk.many .work_processed_syscall	// re-check
+ 
+-END(ia64_leave_kernel)
++END(__ia64_leave_kernel)
+ 
+ ENTRY(handle_syscall_error)
+ 	/*
+@@ -1190,7 +1196,7 @@ END(ia64_invoke_schedule_tail)
+ 	 * be set up by the caller.  We declare 8 input registers so the system call
+ 	 * args get preserved, in case we need to restart a system call.
+ 	 */
+-ENTRY(notify_resume_user)
++GLOBAL_ENTRY(notify_resume_user)
+ 	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
+ 	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
+ 	mov r9=ar.unat
+@@ -1278,7 +1284,7 @@ ENTRY(sys_rt_sigreturn)
+ 	adds sp=16,sp
+ 	;;
+ 	ld8 r9=[sp]				// load new ar.unat
+-	mov.sptk b7=r8,ia64_leave_kernel
++	mov.sptk b7=r8,__ia64_leave_kernel
+ 	;;
+ 	mov ar.unat=r9
+ 	br.many b7
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/kernel/head.S
+--- a/arch/ia64/kernel/head.S	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/kernel/head.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -362,6 +362,12 @@ 1:	// now we are in virtual mode
+ (isBP)	movl r2=ia64_boot_param
+ 	;;
+ (isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader
++
++#ifdef CONFIG_XEN
++	//  Note: isBP is used by the subprogram.
++	br.call.sptk.many rp=early_xen_setup
++	;;
++#endif
+ 
+ #ifdef CONFIG_SMP
+ (isAP)	br.call.sptk.many rp=start_secondary
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/kernel/pal.S
+--- a/arch/ia64/kernel/pal.S	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/kernel/pal.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -16,6 +16,7 @@
+ #include <asm/processor.h>
+ 
+ 	.data
++	.globl pal_entry_point
+ pal_entry_point:
+ 	data8 ia64_pal_default_handler
+ 	.text
+@@ -53,7 +54,7 @@ END(ia64_pal_default_handler)
+  * in4	       1 ==> clear psr.ic,  0 ==> don't clear psr.ic
+  *
+  */
+-GLOBAL_ENTRY(ia64_pal_call_static)
++GLOBAL_ENTRY(__ia64_pal_call_static)
+ 	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
+ 	alloc loc1 = ar.pfs,5,5,0,0
+ 	movl loc2 = pal_entry_point
+@@ -90,7 +91,7 @@ 1:	mov psr.l = loc3
+ 	;;
+ 	srlz.d				// seralize restoration of psr.l
+ 	br.ret.sptk.many b0
+-END(ia64_pal_call_static)
++END(__ia64_pal_call_static)
+ 
+ /*
+  * Make a PAL call using the stacked registers calling convention.
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/kernel/sal.c
+--- a/arch/ia64/kernel/sal.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/kernel/sal.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -336,6 +336,9 @@ ia64_sal_init (struct ia64_sal_systab *s
+ 		p += SAL_DESC_SIZE(*p);
+ 	}
+ 
++#ifdef CONFIG_XEN
++	if (!running_on_xen)
++#endif
+ 	check_sal_cache_flush();
+ }
+ 
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/kernel/setup.c
+--- a/arch/ia64/kernel/setup.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/ia64/kernel/setup.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -61,6 +61,9 @@
+ #include <asm/system.h>
+ #include <asm/unistd.h>
+ #include <asm/system.h>
++#ifdef CONFIG_XEN
++#include <asm/hypervisor.h>
++#endif
+ 
+ #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
+ # error "struct cpuinfo_ia64 too big!"
+@@ -243,6 +246,14 @@ reserve_memory (void)
+ 	rsvd_region[n].end   = (unsigned long) ia64_imva(_end);
+ 	n++;
+ 
++#ifdef CONFIG_XEN
++	if (running_on_xen) {
++		rsvd_region[n].start = (unsigned long)__va((HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT));
++		rsvd_region[n].end   = rsvd_region[n].start + PAGE_SIZE;
++		n++;
++ 	}
++#endif
++
+ #ifdef CONFIG_BLK_DEV_INITRD
+ 	if (ia64_boot_param->initrd_start) {
+ 		rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
+@@ -260,6 +271,7 @@ reserve_memory (void)
+ 	n++;
+ 
+ 	num_rsvd_regions = n;
++	BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n);
+ 
+ 	sort_regions(rsvd_region, num_rsvd_regions);
+ }
+@@ -333,6 +345,10 @@ early_console_setup (char *cmdline)
+ {
+ 	int earlycons = 0;
+ 
++#ifdef CONFIG_XEN
++	if (!early_xen_console_setup(cmdline))
++		earlycons++;
++#endif
+ #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
+ 	{
+ 		extern int sn_serial_console_early_setup(void);
+diff -r c75ede70c907 -r f6bd46559b93 arch/x86_64/kernel/io_apic-xen.c
+--- a/arch/x86_64/kernel/io_apic-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/x86_64/kernel/io_apic-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -108,8 +108,8 @@ static inline unsigned int xen_io_apic_r
+ 	int ret;
+ 
+ 	op.cmd = PHYSDEVOP_APIC_READ;
+-	op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
+-	op.u.apic_op.offset = reg;
++	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
++	op.u.apic_op.reg = reg;
+ 	ret = HYPERVISOR_physdev_op(&op);
+ 	if (ret)
+ 		return ret;
+@@ -121,8 +121,8 @@ static inline void xen_io_apic_write(uns
+ 	physdev_op_t op;
+ 
+ 	op.cmd = PHYSDEVOP_APIC_WRITE;
+-	op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
+-	op.u.apic_op.offset = reg;
++	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
++	op.u.apic_op.reg = reg;
+ 	op.u.apic_op.value = value;
+ 	HYPERVISOR_physdev_op(&op);
+ }
+diff -r c75ede70c907 -r f6bd46559b93 arch/x86_64/kernel/process-xen.c
+--- a/arch/x86_64/kernel/process-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/x86_64/kernel/process-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -124,9 +124,9 @@ void xen_idle(void)
+ {
+ 	local_irq_disable();
+ 
+-	if (need_resched()) {
++	if (need_resched())
+ 		local_irq_enable();
+-	} else {
++	else {
+ 		clear_thread_flag(TIF_POLLING_NRFLAG);
+ 		smp_mb__after_clear_bit();
+ 		stop_hz_timer();
+diff -r c75ede70c907 -r f6bd46559b93 arch/x86_64/kernel/setup-xen.c
+--- a/arch/x86_64/kernel/setup-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/x86_64/kernel/setup-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -661,13 +661,7 @@ void __init setup_arch(char **cmdline_p)
+ 	HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
+ #endif
+ 
+-	clear_bit(X86_FEATURE_VME, boot_cpu_data.x86_capability);
+-	clear_bit(X86_FEATURE_DE, boot_cpu_data.x86_capability);
+-	clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
+-	clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
+-	clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
+-	if (!(xen_start_info->flags & SIF_PRIVILEGED))
+-		clear_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability);
++	modify_cpu_capabilities(&boot_cpu_data);
+ #endif
+ 
+ 	if (!MOUNT_ROOT_RDONLY)
+@@ -1393,6 +1387,8 @@ void __cpuinit identify_cpu(struct cpuin
+ 	select_idle_routine(c);
+ 	detect_ht(c); 
+ 
++	modify_cpu_capabilities(c);
++
+ 	/*
+ 	 * On SMP, boot_cpu_data holds the common feature set between
+ 	 * all CPUs; so make sure that we indicate which features are
+diff -r c75ede70c907 -r f6bd46559b93 arch/x86_64/kernel/x8664_ksyms-xen.c
+--- a/arch/x86_64/kernel/x8664_ksyms-xen.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/arch/x86_64/kernel/x8664_ksyms-xen.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -32,8 +32,6 @@
+ #include <asm/tlbflush.h>
+ #include <asm/kdebug.h>
+ 
+-extern spinlock_t rtc_lock;
+-
+ #ifdef CONFIG_SMP
+ extern void __write_lock_failed(rwlock_t *rw);
+ extern void __read_lock_failed(rwlock_t *rw);
+@@ -42,9 +40,6 @@ extern void __read_lock_failed(rwlock_t 
+ /* platform dependent support */
+ EXPORT_SYMBOL(boot_cpu_data);
+ //EXPORT_SYMBOL(dump_fpu);
+-EXPORT_SYMBOL(__ioremap);
+-EXPORT_SYMBOL(ioremap_nocache);
+-EXPORT_SYMBOL(iounmap);
+ EXPORT_SYMBOL(kernel_thread);
+ EXPORT_SYMBOL(pm_idle);
+ EXPORT_SYMBOL(pm_power_off);
+@@ -101,8 +96,6 @@ EXPORT_SYMBOL(screen_info);
+ #endif
+ 
+ EXPORT_SYMBOL(get_wchan);
+-
+-EXPORT_SYMBOL(rtc_lock);
+ 
+ #ifdef CONFIG_X86_LOCAL_APIC
+ EXPORT_SYMBOL_GPL(set_nmi_callback);
+@@ -166,7 +159,5 @@ EXPORT_SYMBOL(flush_tlb_page);
+ EXPORT_SYMBOL(flush_tlb_page);
+ #endif
+ 
+-EXPORT_SYMBOL(cpu_khz);
+-
+ EXPORT_SYMBOL(load_gs_index);
+ 
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/Kconfig
+--- a/drivers/xen/Kconfig	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/Kconfig	Mon Mar  6 17:57:34 2006 +0000
+@@ -68,7 +68,7 @@ config XEN_PCIDEV_BE_DEBUG
+ 	default n
+ 
+ config XEN_BLKDEV_BACKEND
+-	bool "Block-device backend driver"
++	tristate "Block-device backend driver"
+ 	default y
+ 	help
+ 	  The block-device backend driver allows the kernel to export its
+@@ -76,7 +76,7 @@ config XEN_BLKDEV_BACKEND
+ 	  interface.
+ 
+ config XEN_BLKDEV_TAP_BE
+-        bool "Block Tap support for backend driver (DANGEROUS)"
++        tristate "Block Tap support for backend driver (DANGEROUS)"
+         depends on XEN_BLKDEV_BACKEND
+         default n
+         help
+@@ -89,7 +89,7 @@ config XEN_BLKDEV_TAP_BE
+           modified to use grant tables.
+ 
+ config XEN_NETDEV_BACKEND
+-	bool "Network-device backend driver"
++	tristate "Network-device backend driver"
+ 	default y
+ 	help
+ 	  The network-device backend driver allows the kernel to export its
+@@ -109,8 +109,16 @@ config XEN_NETDEV_PIPELINED_TRANSMITTER
+ 	  are unsure; or if you experience network hangs when this option is
+ 	  enabled; then you must say N here.
+ 
++config XEN_NETDEV_LOOPBACK
++	tristate "Network-device loopback driver"
++	depends on XEN_NETDEV_BACKEND
++	default y
++	help
++	  A two-interface loopback device to emulate a local netfront-netback
++	  connection.
++
+ config XEN_TPMDEV_BACKEND
+-	bool "TPM-device backend driver"
++	tristate "TPM-device backend driver"
+ 	default n
+ 	help
+ 	  The TPM-device backend driver
+@@ -145,7 +153,7 @@ config XEN_NETDEV_FRONTEND
+ 	  (domain 0), then you almost certainly want to say Y here.
+ 
+ config XEN_BLKDEV_TAP
+-	bool "Block device tap driver"
++	tristate "Block device tap driver"
+ 	default n
+ 	help
+ 	  This driver allows a VM to interact on block device channels
+@@ -154,7 +162,7 @@ config XEN_BLKDEV_TAP
+ 	  space.  Odds are that you want to say N here.
+ 
+ config XEN_TPMDEV_FRONTEND
+-	bool "TPM-device frontend driver"
++	tristate "TPM-device frontend driver"
+ 	default n
+ 	select TCG_TPM
+ 	select TCG_XEN
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/blkback/Makefile
+--- a/drivers/xen/blkback/Makefile	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/blkback/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -1,2 +1,3 @@
++obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o
+ 
+-obj-y	:= blkback.o xenbus.o interface.o vbd.o
++blkbk-y	:= blkback.o xenbus.o interface.o vbd.o
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/blkback/blkback.c
+--- a/drivers/xen/blkback/blkback.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/blkback/blkback.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -29,14 +29,10 @@
+  * 64 should be enough to keep us competitive with Linux.
+  */
+ static int blkif_reqs = 64;
++module_param_named(reqs, blkif_reqs, int, 0);
++MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
++
+ static int mmap_pages;
+-
+-static int __init set_blkif_reqs(char *str)
+-{
+-	get_option(&str, &blkif_reqs);
+-	return 1;
+-}
+-__setup("blkif_reqs=", set_blkif_reqs);
+ 
+ /* Run-time switchable: /sys/module/blkback/parameters/ */
+ static unsigned int log_stats = 0;
+@@ -574,10 +570,20 @@ static int __init blkif_init(void)
+ 		list_add_tail(&pending_reqs[i].free_list, &pending_free);
+     
+ 	blkif_xenbus_init();
++	__unsafe(THIS_MODULE);
+ 	return 0;
+ }
+ 
+-__initcall(blkif_init);
++module_init(blkif_init);
++
++static void blkif_exit(void)
++{
++	BUG();
++}
++
++module_exit(blkif_exit);
++
++MODULE_LICENSE("Dual BSD/GPL");
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/blkfront/blkfront.c
+--- a/drivers/xen/blkfront/blkfront.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/blkfront/blkfront.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -182,9 +182,8 @@ again:
+ 	}
+ 
+ 	err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
+-	if (err) {
++	if (err)
+ 		goto abort_transaction;
+-	}
+ 
+ 	err = xenbus_transaction_end(xbt, 0);
+ 	if (err) {
+@@ -295,17 +294,17 @@ static void backend_changed(struct xenbu
+ /* ** Connection ** */
+ 
+ 
+-/* 
+-** Invoked when the backend is finally 'ready' (and has told produced 
+-** the details about the physical device - #sectors, size, etc). 
+-*/
++/*
++ * Invoked when the backend is finally 'ready' (and has told produced
++ * the details about the physical device - #sectors, size, etc).
++ */
+ static void connect(struct blkfront_info *info)
+ {
+ 	unsigned long sectors, sector_size;
+ 	unsigned int binfo;
+ 	int err;
+ 
+-        if( (info->connected == BLKIF_STATE_CONNECTED) || 
++	if ((info->connected == BLKIF_STATE_CONNECTED) ||
+ 	    (info->connected == BLKIF_STATE_SUSPENDED) )
+ 		return;
+ 
+@@ -330,7 +329,7 @@ static void connect(struct blkfront_info
+ 		return;
+ 	}
+ 
+-	(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected); 
++	(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
+ 
+ 	/* Kick pending requests. */
+ 	spin_lock_irq(&blkif_io_lock);
+@@ -463,8 +462,7 @@ int blkif_ioctl(struct inode *inode, str
+ 	DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
+ 		      command, (long)argument, inode->i_rdev);
+ 
+-	switch ( command )
+-	{
++	switch (command) {
+ 	case HDIO_GETGEO:
+ 		/* return ENOSYS to use defaults */
+ 		return -ENOSYS;
+@@ -490,7 +488,7 @@ int blkif_ioctl(struct inode *inode, str
+  * blkif_queue_request
+  *
+  * request block io
+- * 
++ *
+  * id: for guest use only.
+  * operation: BLKIF_OP_{READ,WRITE,PROBE}
+  * buffer: buffer to read/write into. this should be a
+@@ -557,7 +555,7 @@ static int blkif_queue_request(struct re
+ 			ring_req->seg[ring_req->nr_segments] =
+ 				(struct blkif_request_segment) {
+ 					.gref       = ref,
+-					.first_sect = fsect, 
++					.first_sect = fsect,
+ 					.last_sect  = lsect };
+ 
+ 			ring_req->nr_segments++;
+@@ -679,9 +677,8 @@ static irqreturn_t blkif_int(int irq, vo
+ 		RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
+ 		if (more_to_do)
+ 			goto again;
+-	} else {
++	} else
+ 		info->ring.sring->rsp_event = i + 1;
+-	}
+ 
+ 	kick_pending_request_queues(info);
+ 
+@@ -694,8 +691,8 @@ static void blkif_free(struct blkfront_i
+ {
+ 	/* Prevent new requests being issued until we fix things up. */
+ 	spin_lock_irq(&blkif_io_lock);
+-	info->connected = suspend ? 
+-		BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; 
++	info->connected = suspend ?
++		BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
+ 	spin_unlock_irq(&blkif_io_lock);
+ 
+ 	/* Free resources associated with old device channel. */
+@@ -706,7 +703,7 @@ static void blkif_free(struct blkfront_i
+ 		info->ring.sring = NULL;
+ 	}
+ 	if (info->irq)
+-		unbind_from_irqhandler(info->irq, info); 
++		unbind_from_irqhandler(info->irq, info);
+ 	info->evtchn = info->irq = 0;
+ 
+ }
+@@ -767,11 +764,11 @@ static void blkif_recover(struct blkfron
+ 
+ 	kfree(copy);
+ 
+-	(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected); 
+-	
++	(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
++
+ 	/* Now safe for us to use the shared ring */
+ 	spin_lock_irq(&blkif_io_lock);
+-        info->connected = BLKIF_STATE_CONNECTED;
++	info->connected = BLKIF_STATE_CONNECTED;
+ 	spin_unlock_irq(&blkif_io_lock);
+ 
+ 	/* Send off requeued requests */
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/blkfront/block.h
+--- a/drivers/xen/blkfront/block.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/blkfront/block.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -55,24 +55,24 @@
+ #include <asm/atomic.h>
+ #include <asm/uaccess.h>
+ 
+-#if 1 
++#if 1
+ #define IPRINTK(fmt, args...) \
+     printk(KERN_INFO "xen_blk: " fmt, ##args)
+ #else
+ #define IPRINTK(fmt, args...) ((void)0)
+ #endif
+ 
+-#if 1 
++#if 1
+ #define WPRINTK(fmt, args...) \
+     printk(KERN_WARNING "xen_blk: " fmt, ##args)
+ #else
+ #define WPRINTK(fmt, args...) ((void)0)
+ #endif
+- 
+-#define DPRINTK(_f, _a...) pr_debug ( _f , ## _a )
++
++#define DPRINTK(_f, _a...) pr_debug(_f, ## _a)
+ 
+ #if 0
+-#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
++#define DPRINTK_IOCTL(_f, _a...) printk(KERN_ALERT _f, ## _a)
+ #else
+ #define DPRINTK_IOCTL(_f, _a...) ((void)0)
+ #endif
+@@ -139,7 +139,7 @@ extern int blkif_ioctl(struct inode *ino
+                        unsigned command, unsigned long argument);
+ extern int blkif_check(dev_t dev);
+ extern int blkif_revalidate(dev_t dev);
+-extern void do_blkif_request (request_queue_t *rq); 
++extern void do_blkif_request (request_queue_t *rq);
+ 
+ /* Virtual block-device subsystem. */
+ /* Note that xlvbd_add doesn't call add_disk for you: you're expected
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/char/mem.c
+--- a/drivers/xen/char/mem.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/char/mem.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -43,49 +43,85 @@ static ssize_t read_mem(struct file * fi
+ static ssize_t read_mem(struct file * file, char __user * buf,
+ 			size_t count, loff_t *ppos)
+ {
+-	unsigned long i, p = *ppos;
+-	ssize_t read = -EFAULT;
++	unsigned long p = *ppos, ignored;
++	ssize_t read = 0, sz;
+ 	void __iomem *v;
+ 
+-	if ((v = ioremap(p, count)) == NULL) {
++	while (count > 0) {
+ 		/*
+-		 * Some programs (e.g., dmidecode) groove off into weird RAM
+-		 * areas where no table scan possibly exist (because Xen will
+-		 * have stomped on them!). These programs get rather upset if
+-                 * we let them know that Xen failed their access, so we fake
+-                 * out a read of all zeroes. :-)
++		 * Handle first page in case it's not aligned
+ 		 */
+-		for (i = 0; i < count; i++)
+-			if (put_user(0, buf+i))
++		if (-p & (PAGE_SIZE - 1))
++			sz = -p & (PAGE_SIZE - 1);
++		else
++			sz = PAGE_SIZE;
++
++		sz = min_t(unsigned long, sz, count);
++
++		if ((v = ioremap(p, sz)) == NULL) {
++			/*
++			 * Some programs (e.g., dmidecode) groove off into weird RAM
++			 * areas where no tables can possibly exist (because Xen will
++			 * have stomped on them!). These programs get rather upset if
++			 * we let them know that Xen failed their access, so we fake
++			 * out a read of all zeroes. :-)
++			 */
++			if (clear_user(buf, count))
+ 				return -EFAULT;
+-		return count;
++			read += count;
++			break;
++		}
++
++		ignored = copy_to_user(buf, v, sz);
++		iounmap(v);
++		if (ignored)
++			return -EFAULT;
++		buf += sz;
++		p += sz;
++		count -= sz;
++		read += sz;
+ 	}
+-	if (copy_to_user(buf, v, count))
+-		goto out;
+ 
+-	read = count;
+ 	*ppos += read;
+-out:
+-	iounmap(v);
+ 	return read;
+ }
+ 
+ static ssize_t write_mem(struct file * file, const char __user * buf, 
+ 			 size_t count, loff_t *ppos)
+ {
+-	unsigned long p = *ppos;
+-	ssize_t written = -EFAULT;
++	unsigned long p = *ppos, ignored;
++	ssize_t written = 0, sz;
+ 	void __iomem *v;
+ 
+-	if ((v = ioremap(p, count)) == NULL)
+-		return -EFAULT;
+-	if (copy_from_user(v, buf, count))
+-		goto out;
++	while (count > 0) {
++		/*
++		 * Handle first page in case it's not aligned
++		 */
++		if (-p & (PAGE_SIZE - 1))
++			sz = -p & (PAGE_SIZE - 1);
++		else
++			sz = PAGE_SIZE;
+ 
+-	written = count;
++		sz = min_t(unsigned long, sz, count);
++
++		if ((v = ioremap(p, sz)) == NULL)
++			break;
++
++		ignored = copy_from_user(v, buf, sz);
++		iounmap(v);
++		if (ignored) {
++			written += sz - ignored;
++			if (written)
++				break;
++			return -EFAULT;
++		}
++		buf += sz;
++		p += sz;
++		count -= sz;
++		written += sz;
++	}
++
+ 	*ppos += written;
+-out:
+-	iounmap(v);
+ 	return written;
+ }
+ 
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/console/console.c
+--- a/drivers/xen/console/console.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/console/console.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -85,8 +85,7 @@ static int __init xencons_setup(char *st
+ 	else if (!strncmp(str, "off", 3))
+ 		xc_mode = XC_OFF;
+ 
+-	switch ( xc_mode )
+-	{
++	switch (xc_mode) {
+ 	case XC_SERIAL:
+ 		n = simple_strtol(str+4, &q, 10);
+ 		if (q > (str + 4))
+@@ -227,7 +226,7 @@ asmlinkage int xprintk(const char *fmt, 
+ 	va_list args;
+ 	int printk_len;
+ 	static char printk_buf[1024];
+-    
++
+ 	/* Emit the output into the temporary buffer */
+ 	va_start(args, fmt);
+ 	printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+@@ -485,7 +484,7 @@ static void xencons_flush_chars(struct t
+ 
+ 	spin_lock_irqsave(&xencons_lock, flags);
+ 	__xencons_tx_flush();
+-	spin_unlock_irqrestore(&xencons_lock, flags);    
++	spin_unlock_irqrestore(&xencons_lock, flags);
+ }
+ 
+ static void xencons_wait_until_sent(struct tty_struct *tty, int timeout)
+@@ -495,17 +494,15 @@ static void xencons_wait_until_sent(stru
+ 	if (TTY_INDEX(tty) != 0)
+ 		return;
+ 
+-	while (DRV(tty->driver)->chars_in_buffer(tty))
+-	{
++	while (DRV(tty->driver)->chars_in_buffer(tty)) {
+ 		set_current_state(TASK_INTERRUPTIBLE);
+ 		schedule_timeout(1);
+ 		if (signal_pending(current))
+ 			break;
+-		if ( (timeout != 0) &&
+-		     time_after(jiffies, orig_jiffies + timeout) )
++		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+ 			break;
+ 	}
+-    
++
+ 	set_current_state(TASK_RUNNING);
+ }
+ 
+@@ -521,7 +518,7 @@ static int xencons_open(struct tty_struc
+ 	if (xencons_tty == NULL)
+ 		xencons_tty = tty;
+ 	__xencons_tx_flush();
+-	spin_unlock_irqrestore(&xencons_lock, flags);    
++	spin_unlock_irqrestore(&xencons_lock, flags);
+ 
+ 	return 0;
+ }
+@@ -543,7 +540,7 @@ static void xencons_close(struct tty_str
+ 		tty->closing = 0;
+ 		spin_lock_irqsave(&xencons_lock, flags);
+ 		xencons_tty = NULL;
+-		spin_unlock_irqrestore(&xencons_lock, flags);    
++		spin_unlock_irqrestore(&xencons_lock, flags);
+ 	}
+ }
+ 
+@@ -574,7 +571,7 @@ static int __init xencons_init(void)
+ 
+ 	xencons_ring_init();
+ 
+-	xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? 
++	xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ?
+ 					  1 : MAX_NR_CONSOLES);
+ 	if (xencons_driver == NULL)
+ 		return -ENOMEM;
+@@ -584,15 +581,14 @@ static int __init xencons_init(void)
+ 	DRV(xencons_driver)->type            = TTY_DRIVER_TYPE_SERIAL;
+ 	DRV(xencons_driver)->subtype         = SERIAL_TYPE_NORMAL;
+ 	DRV(xencons_driver)->init_termios    = tty_std_termios;
+-	DRV(xencons_driver)->flags           = 
++	DRV(xencons_driver)->flags           =
+ 		TTY_DRIVER_REAL_RAW |
+ 		TTY_DRIVER_RESET_TERMIOS |
+ 		TTY_DRIVER_NO_DEVFS;
+ 	DRV(xencons_driver)->termios         = xencons_termios;
+ 	DRV(xencons_driver)->termios_locked  = xencons_termios_locked;
+ 
+-	if (xc_mode == XC_SERIAL)
+-	{
++	if (xc_mode == XC_SERIAL) {
+ 		DRV(xencons_driver)->name        = "ttyS";
+ 		DRV(xencons_driver)->minor_start = 64 + xc_num;
+ 		DRV(xencons_driver)->name_base   = 0 + xc_num;
+@@ -630,7 +626,7 @@ static int __init xencons_init(void)
+ 	printk("Xen virtual console successfully installed as %s%d\n",
+ 	       DRV(xencons_driver)->name,
+ 	       DRV(xencons_driver)->name_base );
+-    
++
+ 	return 0;
+ }
+ 
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/console/xencons_ring.c
+--- a/drivers/xen/console/xencons_ring.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/console/xencons_ring.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -55,7 +55,7 @@ int xencons_ring_send(const char *data, 
+ 	notify_daemon();
+ 
+ 	return sent;
+-}	
++}
+ 
+ static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
+ {
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/core/evtchn.c
+--- a/drivers/xen/core/evtchn.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/core/evtchn.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -72,7 +72,7 @@ DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS
+ 
+ /* IRQ <-> IPI mapping. */
+ #ifndef NR_IPIS
+-#define NR_IPIS 1 
++#define NR_IPIS 1
+ #endif
+ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
+ 
+@@ -209,7 +209,7 @@ static int bind_evtchn_to_irq(unsigned i
+ 	irq_bindcount[irq]++;
+ 
+ 	spin_unlock(&irq_mapping_update_lock);
+-    
++
+ 	return irq;
+ }
+ 
+@@ -238,7 +238,7 @@ static int bind_virq_to_irq(unsigned int
+ 	irq_bindcount[irq]++;
+ 
+ 	spin_unlock(&irq_mapping_update_lock);
+-    
++
+ 	return irq;
+ }
+ 
+@@ -535,9 +535,9 @@ static unsigned int startup_pirq(unsigne
+ 	/* NB. We are happy to share unless we are probing. */
+ 	op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+ 	if (HYPERVISOR_event_channel_op(&op) != 0) {
+-		if ( !probing_irq(irq) )
+-			printk(KERN_INFO "Failed to obtain physical "
+-			       "IRQ %d\n", irq);
++		if (!probing_irq(irq))
++			printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
++			       irq);
+ 		return 0;
+ 	}
+ 	evtchn = op.u.bind_pirq.port;
+@@ -669,7 +669,7 @@ void unmask_evtchn(int port)
+ 	 * like a real IO-APIC we 'lose the interrupt edge' if the channel is
+ 	 * masked.
+ 	 */
+-	if (synch_test_bit(port, &s->evtchn_pending[0]) && 
++	if (synch_test_bit(port, &s->evtchn_pending[0]) &&
+ 	    !synch_test_and_set_bit(port / BITS_PER_LONG,
+ 				    &vcpu_info->evtchn_pending_sel)) {
+ 		vcpu_info->evtchn_upcall_pending = 1;
+@@ -722,7 +722,7 @@ void irq_resume(void)
+ 		op.u.bind_virq.vcpu = 0;
+ 		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ 		evtchn = op.u.bind_virq.port;
+-        
++
+ 		/* Record the new mapping. */
+ 		evtchn_to_irq[evtchn] = irq;
+ 		irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
+@@ -744,7 +744,7 @@ void irq_resume(void)
+ 		op.u.bind_ipi.vcpu = 0;
+ 		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ 		evtchn = op.u.bind_ipi.port;
+-        
++
+ 		/* Record the new mapping. */
+ 		evtchn_to_irq[evtchn] = irq;
+ 		irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
+@@ -794,8 +794,7 @@ void __init init_IRQ(void)
+ 	}
+ 
+ 	/* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
+-	for (i = 0; i < NR_PIRQS; i++)
+-	{
++	for (i = 0; i < NR_PIRQS; i++) {
+ 		irq_bindcount[pirq_to_irq(i)] = 1;
+ 
+ #ifdef RTC_IRQ
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/core/features.c
+--- a/drivers/xen/core/features.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/core/features.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -19,7 +19,7 @@ void setup_xen_features(void)
+ 	xen_feature_info_t fi;
+ 	int i, j;
+ 
+-	for (i=0; i<XENFEAT_NR_SUBMAPS; i++) {
++	for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) {
+ 		fi.submap_idx = i;
+ 		if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
+ 			break;
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/core/gnttab.c
+--- a/drivers/xen/core/gnttab.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/core/gnttab.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -35,13 +35,12 @@
+ #include <xen/interface/xen.h>
+ #include <asm/fixmap.h>
+ #include <asm/uaccess.h>
+-#include <xen/public/privcmd.h>
+ #include <xen/gnttab.h>
+ #include <asm/synch_bitops.h>
+ 
+ #if 1
+ #define ASSERT(_p)							      \
+-	if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
++	if (!(_p)) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n",   \
+ 	#_p , __LINE__, __FILE__); *(int*)0=0; }
+ #else
+ #define ASSERT(_p) ((void)0)
+@@ -153,7 +152,7 @@ gnttab_grant_foreign_access(domid_t domi
+ gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
+ {
+ 	int ref;
+-    
++
+ 	if (unlikely((ref = get_free_entry()) == -1))
+ 		return -ENOSPC;
+ 
+@@ -193,13 +192,12 @@ gnttab_end_foreign_access_ref(grant_ref_
+ 
+ 	nflags = shared[ref].flags;
+ 	do {
+-		if ( (flags = nflags) & (GTF_reading|GTF_writing) ) {
++		if ((flags = nflags) & (GTF_reading|GTF_writing)) {
+ 			printk(KERN_ALERT "WARNING: g.e. still in use!\n");
+ 			return 0;
+ 		}
+-	}
+-	while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
+-	       flags);
++	} while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
++		 flags);
+ 
+ 	return 1;
+ }
+@@ -212,8 +210,7 @@ gnttab_end_foreign_access(grant_ref_t re
+ 		if (page != 0) {
+ 			free_page(page);
+ 		}
+-	}
+-	else {
++	} else {
+ 		/* XXX This needs to be fixed so that the ref and page are
+ 		   placed on a list to be freed up later. */
+ 		printk(KERN_WARNING
+@@ -254,7 +251,7 @@ gnttab_end_foreign_transfer_ref(grant_re
+          * reference and return failure (== 0).
+          */
+ 	while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
+-		if ( synch_cmpxchg(&shared[ref].flags, flags, 0) == flags )
++		if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
+ 			return 0;
+ 		cpu_relax();
+ 	}
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/core/reboot.c
+--- a/drivers/xen/core/reboot.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/core/reboot.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -29,10 +29,11 @@ EXPORT_SYMBOL(pm_power_off);
+ #define SHUTDOWN_POWEROFF  0
+ #define SHUTDOWN_REBOOT    1
+ #define SHUTDOWN_SUSPEND   2
+-// Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
+-// report a crash, not be instructed to crash!
+-// HALT is the same as POWEROFF, as far as we're concerned.  The tools use
+-// the distinction when we return the reason code to them.
++/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
++ * report a crash, not be instructed to crash!
++ * HALT is the same as POWEROFF, as far as we're concerned.  The tools use
++ * the distinction when we return the reason code to them.
++ */
+ #define SHUTDOWN_HALT      4
+ 
+ void machine_emergency_restart(void)
+@@ -84,13 +85,13 @@ static int __do_suspend(void *ignore)
+ {
+ 	int i, j, k, fpp;
+ 
+-	extern int gnttab_suspend(void);
+-	extern int gnttab_resume(void);
+-
+-	extern void time_resume(void);
+ 	extern unsigned long max_pfn;
+ 	extern unsigned long *pfn_to_mfn_frame_list_list;
+ 	extern unsigned long *pfn_to_mfn_frame_list[];
++
++	extern int gnttab_suspend(void);
++	extern int gnttab_resume(void);
++	extern void time_resume(void);
+ 
+ #ifdef CONFIG_SMP
+ 	cpumask_t prev_online_cpus;
+@@ -167,26 +168,26 @@ static int __do_suspend(void *ignore)
+ 	 */
+ 	HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+ 
+-	shutting_down = SHUTDOWN_INVALID; 
++	shutting_down = SHUTDOWN_INVALID;
+ 
+ 	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+ 
+ 	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+ 
+ 	memset(empty_zero_page, 0, PAGE_SIZE);
+-	     
++
+ 	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+ 		virt_to_mfn(pfn_to_mfn_frame_list_list);
+-  
++
+ 	fpp = PAGE_SIZE/sizeof(unsigned long);
+ 	for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
+ 		if ((j % fpp) == 0) {
+ 			k++;
+-			pfn_to_mfn_frame_list_list[k] = 
++			pfn_to_mfn_frame_list_list[k] =
+ 				virt_to_mfn(pfn_to_mfn_frame_list[k]);
+ 			j = 0;
+ 		}
+-		pfn_to_mfn_frame_list[k][j] = 
++		pfn_to_mfn_frame_list[k][j] =
+ 			virt_to_mfn(&phys_to_machine_mapping[i]);
+ 	}
+ 	HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+@@ -207,7 +208,7 @@ static int __do_suspend(void *ignore)
+ 
+ #endif
+ 
+-	/* 
++	/*
+ 	 * Only resume xenbus /after/ we've prepared our VCPUs; otherwise
+ 	 * the VCPU hotplug callback can race with our vcpu_prepare
+ 	 */
+@@ -231,7 +232,7 @@ static int __do_suspend(void *ignore)
+ 
+ static int shutdown_process(void *__unused)
+ {
+-	static char *envp[] = { "HOME=/", "TERM=linux", 
++	static char *envp[] = { "HOME=/", "TERM=linux",
+ 				"PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+ 	static char *restart_argv[]  = { "/sbin/reboot", NULL };
+ 	static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
+@@ -291,7 +292,7 @@ static void __shutdown_handler(void *unu
+ 	else
+ 		err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0);
+ 
+-	if ( err < 0 ) {
++	if (err < 0) {
+ 		printk(KERN_WARNING "Error creating shutdown process (%d): "
+ 		       "retrying...\n", -err);
+ 		schedule_delayed_work(&shutdown_work, HZ/2);
+@@ -406,14 +407,12 @@ static int setup_shutdown_watcher(struct
+ 	err2 = register_xenbus_watch(&sysrq_watch);
+ #endif
+ 
+-	if (err1) {
++	if (err1)
+ 		printk(KERN_ERR "Failed to set shutdown watcher\n");
+-	}
+-    
+-#ifdef CONFIG_MAGIC_SYSRQ
+-	if (err2) {
++
++#ifdef CONFIG_MAGIC_SYSRQ
++	if (err2)
+ 		printk(KERN_ERR "Failed to set sysrq watcher\n");
+-	}
+ #endif
+ 
+ 	return NOTIFY_DONE;
+@@ -421,11 +420,11 @@ static int setup_shutdown_watcher(struct
+ 
+ static int __init setup_shutdown_event(void)
+ {
+-    
++
+ 	xenstore_notifier.notifier_call = setup_shutdown_watcher;
+ 
+ 	register_xenstore_notifier(&xenstore_notifier);
+-    
++
+ 	return 0;
+ }
+ 
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/core/skbuff.c
+--- a/drivers/xen/core/skbuff.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/core/skbuff.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -16,6 +16,7 @@
+ 
+ /* Referenced in netback.c. */
+ /*static*/ kmem_cache_t *skbuff_cachep;
++EXPORT_SYMBOL(skbuff_cachep);
+ 
+ #define MAX_SKBUFF_ORDER 4
+ static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1];
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/net_driver_util.c
+--- a/drivers/xen/net_driver_util.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/net_driver_util.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -40,9 +40,8 @@ int xen_net_read_mac(struct xenbus_devic
+ 	int i;
+ 	char *e;
+ 	char *macstr = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
+-	if (IS_ERR(macstr)) {
++	if (IS_ERR(macstr))
+ 		return PTR_ERR(macstr);
+-	}
+ 	s = macstr;
+ 	for (i = 0; i < ETH_ALEN; i++) {
+ 		mac[i] = simple_strtoul(s, &e, 16);
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/netback/Makefile
+--- a/drivers/xen/netback/Makefile	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/netback/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -1,2 +1,5 @@
++obj-$(CONFIG_XEN_NETDEV_BACKEND) := netbk.o
++obj-$(CONFIG_XEN_NETDEV_LOOPBACK) += netloop.o
+ 
+-obj-y	:= netback.o xenbus.o interface.o loopback.o
++netbk-y   := netback.o xenbus.o interface.o
++netloop-y := loopback.o
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/netback/loopback.c
+--- a/drivers/xen/netback/loopback.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/netback/loopback.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -178,6 +178,23 @@ static int __init make_loopback(int i)
+ 	return err;
+ }
+ 
++static void __init clean_loopback(int i)
++{
++	struct net_device *dev1, *dev2;
++	char dev_name[IFNAMSIZ];
++
++	sprintf(dev_name, "vif0.%d", i);
++	dev1 = dev_get_by_name(dev_name);
++	sprintf(dev_name, "veth%d", i);
++	dev2 = dev_get_by_name(dev_name);
++	if (dev1 && dev2) {
++		unregister_netdev(dev2);
++		unregister_netdev(dev1);
++		free_netdev(dev2);
++		free_netdev(dev1);
++	}
++}
++
+ static int __init loopback_init(void)
+ {
+ 	int i, err = 0;
+@@ -190,6 +207,18 @@ static int __init loopback_init(void)
+ }
+ 
+ module_init(loopback_init);
++
++static void __exit loopback_exit(void)
++{
++	int i;
++
++	for (i = nloopbacks; i-- > 0; )
++		clean_loopback(i);
++}
++
++module_exit(loopback_exit);
++
++MODULE_LICENSE("Dual BSD/GPL");
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/netback/netback.c
+--- a/drivers/xen/netback/netback.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/netback/netback.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -505,14 +505,12 @@ static void net_tx_action(unsigned long 
+ 			/* Still too big to send right now? Set a callback. */
+ 			if (txreq.size > netif->remaining_credit) {
+ 				netif->remaining_credit = 0;
+-				netif->credit_timeout.expires  = 
+-					next_credit;
+ 				netif->credit_timeout.data     =
+ 					(unsigned long)netif;
+ 				netif->credit_timeout.function =
+ 					tx_credit_callback;
+-				add_timer_on(&netif->credit_timeout,
+-					     smp_processor_id());
++				__mod_timer(&netif->credit_timeout,
++					    next_credit);
+ 				break;
+ 			}
+ 		}
+@@ -811,6 +809,8 @@ static int __init netback_init(void)
+ 		&netif_be_dbg);
+ #endif
+ 
++	__unsafe(THIS_MODULE);
++
+ 	return 0;
+ }
+ 
+@@ -821,6 +821,8 @@ static void netback_cleanup(void)
+ 
+ module_init(netback_init);
+ module_exit(netback_cleanup);
++
++MODULE_LICENSE("Dual BSD/GPL");
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/netfront/netfront.c
+--- a/drivers/xen/netfront/netfront.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/netfront/netfront.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -91,7 +91,7 @@ struct netfront_info
+ 
+ 	struct net_device_stats stats;
+ 	unsigned int tx_full;
+-    
++
+ 	netif_tx_front_ring_t tx;
+ 	netif_rx_front_ring_t rx;
+ 
+@@ -129,9 +129,9 @@ struct netfront_info
+ 	struct sk_buff *rx_skbs[NET_RX_RING_SIZE+1];
+ 
+ 	grant_ref_t gref_tx_head;
+-	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; 
++	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
+ 	grant_ref_t gref_rx_head;
+-	grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; 
++	grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1];
+ 
+ 	struct xenbus_device *xbdev;
+ 	int tx_ring_ref;
+@@ -433,7 +433,7 @@ static int send_fake_arp(struct net_devi
+ 
+ 	skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
+ 			 dst_ip, dev, src_ip,
+-			 /*dst_hw*/ NULL, /*src_hw*/ NULL, 
++			 /*dst_hw*/ NULL, /*src_hw*/ NULL,
+ 			 /*target_hw*/ dev->dev_addr);
+ 	if (skb == NULL)
+ 		return -ENOMEM;
+@@ -480,7 +480,7 @@ static void network_tx_buf_gc(struct net
+ 				printk(KERN_ALERT "network_tx_buf_gc: warning "
+ 				       "-- grant still in use by backend "
+ 				       "domain.\n");
+-				goto out; 
++				goto out;
+ 			}
+ 			gnttab_end_foreign_access_ref(
+ 				np->grant_tx_ref[id], GNTMAP_readonly);
+@@ -490,9 +490,9 @@ static void network_tx_buf_gc(struct net
+ 			ADD_ID_TO_FREELIST(np->tx_skbs, id);
+ 			dev_kfree_skb_irq(skb);
+ 		}
+-        
++
+ 		np->tx.rsp_cons = prod;
+-        
++
+ 		/*
+ 		 * Set a new event, then check for race with update of tx_cons.
+ 		 * Note that it is essential to schedule a callback, no matter
+@@ -506,7 +506,7 @@ static void network_tx_buf_gc(struct net
+ 		mb();
+ 	} while (prod != np->tx.sring->rsp_prod);
+ 
+- out: 
++ out:
+ 	if (np->tx_full &&
+ 	    ((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE)) {
+ 		np->tx_full = 0;
+@@ -582,7 +582,7 @@ static void network_alloc_rx_buffers(str
+ 		id = GET_ID_FROM_FREELIST(np->rx_skbs);
+ 
+ 		np->rx_skbs[id] = skb;
+-        
++
+ 		RING_GET_REQUEST(&np->rx, req_prod + i)->id = id;
+ 		ref = gnttab_claim_grant_reference(&np->gref_rx_head);
+ 		BUG_ON((signed short)ref < 0);
+@@ -628,11 +628,10 @@ static void network_alloc_rx_buffers(str
+ 		/* Check return status of HYPERVISOR_memory_op(). */
+ 		if (unlikely(rx_mcl[i].result != i))
+ 			panic("Unable to reduce memory reservation\n");
+-	} else {
++	} else
+ 		if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ 					 &reservation) != i)
+ 			panic("Unable to reduce memory reservation\n");
+-	}
+ 
+ 	/* Above is a suitable barrier to ensure backend will see requests. */
+ 	np->rx.req_prod_pvt = req_prod + i;
+@@ -668,7 +667,7 @@ static int network_start_xmit(struct sk_
+ 		dev_kfree_skb(skb);
+ 		skb = nskb;
+ 	}
+-    
++
+ 	spin_lock_irq(&np->tx_lock);
+ 
+ 	if (np->backend_state != BEST_CONNECTED) {
+@@ -765,7 +764,7 @@ static int netif_poll(struct net_device 
+ 	rp = np->rx.sring->rsp_prod;
+ 	rmb(); /* Ensure we see queued responses up to 'rp'. */
+ 
+-	for (i = np->rx.rsp_cons, work_done = 0; 
++	for (i = np->rx.rsp_cons, work_done = 0;
+ 	     (i != rp) && (work_done < budget);
+ 	     i++, work_done++) {
+ 		rx = RING_GET_RESPONSE(&np->rx, i);
+@@ -807,7 +806,7 @@ static int netif_poll(struct net_device 
+ 		skb->len  = rx->status;
+ 		skb->tail = skb->data + skb->len;
+ 
+-		if ( rx->flags & NETRXF_csum_valid )
++		if (rx->flags & NETRXF_csum_valid)
+ 			skb->ip_summed = CHECKSUM_UNNECESSARY;
+ 
+ 		np->stats.rx_packets++;
+@@ -862,7 +861,7 @@ static int netif_poll(struct net_device 
+ 		 * Enough room in skbuff for the data we were passed? Also,
+ 		 * Linux expects at least 16 bytes headroom in each rx buffer.
+ 		 */
+-		if (unlikely(skb->tail > skb->end) || 
++		if (unlikely(skb->tail > skb->end) ||
+ 		    unlikely((skb->data - skb->head) < 16)) {
+ 			if (net_ratelimit()) {
+ 				if (skb->tail > skb->end)
+@@ -894,7 +893,7 @@ static int netif_poll(struct net_device 
+ 			if ((skb = nskb) == NULL)
+ 				continue;
+ 		}
+-        
++
+ 		/* Set the shinfo area, which is hidden behind the data. */
+ 		init_skb_shinfo(skb);
+ 		/* Ethernet work: Delayed to here as it peeks the header. */
+@@ -995,9 +994,9 @@ static void network_connect(struct net_d
+ 
+ 		tx->id = i;
+ 		gnttab_grant_foreign_access_ref(
+-			np->grant_tx_ref[i], np->xbdev->otherend_id, 
++			np->grant_tx_ref[i], np->xbdev->otherend_id,
+ 			virt_to_mfn(np->tx_skbs[i]->data),
+-			GNTMAP_readonly); 
++			GNTMAP_readonly);
+ 		tx->gref = np->grant_tx_ref[i];
+ 		tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
+ 		tx->size = skb->len;
+@@ -1012,7 +1011,7 @@ static void network_connect(struct net_d
+ 	RING_PUSH_REQUESTS(&np->tx);
+ 
+ 	/* Rebuild the RX buffer freelist and the RX ring itself. */
+-	for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) { 
++	for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) {
+ 		if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
+ 			continue;
+ 		gnttab_grant_foreign_transfer_ref(
+@@ -1021,7 +1020,7 @@ static void network_connect(struct net_d
+ 		RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
+ 			np->grant_rx_ref[i];
+ 		RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
+-		requeue_idx++; 
++		requeue_idx++;
+ 	}
+ 
+ 	np->rx.req_prod_pvt = requeue_idx;
+@@ -1055,9 +1054,8 @@ static void show_device(struct netfront_
+ 			np->evtchn,
+ 			np->tx,
+ 			np->rx);
+-	} else {
++	} else
+ 		IPRINTK("<vif NULL>\n");
+-	}
+ #endif
+ }
+ 
+@@ -1150,7 +1148,7 @@ static int create_netdev(int handle, str
+ 	SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
+ 	SET_MODULE_OWNER(netdev);
+ 	SET_NETDEV_DEV(netdev, &dev->dev);
+-    
++
+ 	if ((err = register_netdev(netdev)) != 0) {
+ 		printk(KERN_WARNING "%s> register_netdev err=%d\n",
+ 		       __FUNCTION__, err);
+@@ -1181,16 +1179,16 @@ static int create_netdev(int handle, str
+  * We use this notifier to send out a fake ARP reply to reset switches and
+  * router ARP caches when an IP interface is brought up on a VIF.
+  */
+-static int 
++static int
+ inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
+ {
+-	struct in_ifaddr  *ifa = (struct in_ifaddr *)ptr; 
++	struct in_ifaddr  *ifa = (struct in_ifaddr *)ptr;
+ 	struct net_device *dev = ifa->ifa_dev->dev;
+ 
+ 	/* UP event and is it one of our devices? */
+ 	if (event == NETDEV_UP && dev->open == network_open)
+ 		(void)send_fake_arp(dev);
+-        
++
+ 	return NOTIFY_DONE;
+ }
+ 
+@@ -1336,8 +1334,8 @@ module_exit(netif_exit);
+ module_exit(netif_exit);
+ 
+ MODULE_LICENSE("Dual BSD/GPL");
+- 
+- 
++
++
+ /* ** /proc **/
+ 
+ 
+@@ -1354,9 +1352,8 @@ static int xennet_proc_read(
+ 		(struct net_device *)((unsigned long)data & ~3UL);
+ 	struct netfront_info *np = netdev_priv(dev);
+ 	int len = 0, which_target = (long)data & 3;
+-    
+-	switch (which_target)
+-	{
++
++	switch (which_target) {
+ 	case TARGET_MIN:
+ 		len = sprintf(page, "%d\n", np->rx_min_target);
+ 		break;
+@@ -1403,8 +1400,7 @@ static int xennet_proc_write(
+ 
+ 	spin_lock(&np->rx_lock);
+ 
+-	switch (which_target)
+-	{
++	switch (which_target) {
+ 	case TARGET_MIN:
+ 		if (target > np->rx_max_target)
+ 			np->rx_max_target = target;
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/tpmback/common.h
+--- a/drivers/xen/tpmback/common.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/tpmback/common.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -54,9 +54,11 @@ void tpmif_disconnect_complete(tpmif_t *
+ void tpmif_disconnect_complete(tpmif_t * tpmif);
+ tpmif_t *tpmif_find(domid_t domid, long int instance);
+ void tpmif_interface_init(void);
++void tpmif_interface_exit(void);
+ void tpmif_schedule_work(tpmif_t * tpmif);
+ void tpmif_deschedule_work(tpmif_t * tpmif);
+ void tpmif_xenbus_init(void);
++void tpmif_xenbus_exit(void);
+ int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
+ irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+ int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/tpmback/interface.c
+--- a/drivers/xen/tpmback/interface.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/tpmback/interface.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -19,8 +19,7 @@ int num_frontends = 0;
+ 
+ LIST_HEAD(tpmif_list);
+ 
+-tpmif_t *
+-alloc_tpmif(domid_t domid, long int instance)
++static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
+ {
+ 	struct page *page;
+ 	tpmif_t *tpmif;
+@@ -45,16 +44,14 @@ alloc_tpmif(domid_t domid, long int inst
+ 	return tpmif;
+ }
+ 
+-void
+-free_tpmif(tpmif_t * tpmif)
++static void free_tpmif(tpmif_t * tpmif)
+ {
+ 	num_frontends--;
+ 	list_del(&tpmif->tpmif_list);
+ 	kmem_cache_free(tpmif_cachep, tpmif);
+ }
+ 
+-tpmif_t *
+-tpmif_find(domid_t domid, long int instance)
++tpmif_t *tpmif_find(domid_t domid, long int instance)
+ {
+ 	tpmif_t *tpmif;
+ 
+@@ -72,8 +69,7 @@ tpmif_find(domid_t domid, long int insta
+ 	return alloc_tpmif(domid, instance);
+ }
+ 
+-static int
+-map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
++static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
+ {
+ 	int ret;
+ 	struct gnttab_map_grant_ref op = {
+@@ -99,8 +95,7 @@ map_frontend_page(tpmif_t *tpmif, unsign
+ 	return 0;
+ }
+ 
+-static void
+-unmap_frontend_page(tpmif_t *tpmif)
++static void unmap_frontend_page(tpmif_t *tpmif)
+ {
+ 	struct gnttab_unmap_grant_ref op;
+ 	int ret;
+@@ -115,14 +110,14 @@ unmap_frontend_page(tpmif_t *tpmif)
+ 	BUG_ON(ret);
+ }
+ 
+-int
+-tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
++int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
+ {
+ 	int err;
+ 	evtchn_op_t op = {
+ 		.cmd = EVTCHNOP_bind_interdomain,
+ 		.u.bind_interdomain.remote_dom = tpmif->domid,
+-		.u.bind_interdomain.remote_port = evtchn };
++		.u.bind_interdomain.remote_port = evtchn,
++        };
+ 
+         if (tpmif->irq) {
+                 return 0;
+@@ -156,8 +151,7 @@ tpmif_map(tpmif_t *tpmif, unsigned long 
+ 	return 0;
+ }
+ 
+-static void
+-__tpmif_disconnect_complete(void *arg)
++static void __tpmif_disconnect_complete(void *arg)
+ {
+ 	tpmif_t *tpmif = (tpmif_t *) arg;
+ 
+@@ -172,18 +166,21 @@ __tpmif_disconnect_complete(void *arg)
+ 	free_tpmif(tpmif);
+ }
+ 
+-void
+-tpmif_disconnect_complete(tpmif_t * tpmif)
++void tpmif_disconnect_complete(tpmif_t * tpmif)
+ {
+ 	INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
+ 	schedule_work(&tpmif->work);
+ }
+ 
+-void __init
+-tpmif_interface_init(void)
++void __init tpmif_interface_init(void)
+ {
+ 	tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
+ 					 0, 0, NULL, NULL);
++}
++
++void __init tpmif_interface_exit(void)
++{
++	kmem_cache_destroy(tpmif_cachep);
+ }
+ 
+ /*
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/tpmback/tpmback.c
+--- a/drivers/xen/tpmback/tpmback.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/tpmback/tpmback.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -22,16 +22,22 @@
+ #include <xen/xenbus.h>
+ #include <xen/interface/grant_table.h>
+ 
+-
+ /* local data structures */
+ struct data_exchange {
+ 	struct list_head pending_pak;
+ 	struct list_head current_pak;
+ 	unsigned int copied_so_far;
+ 	u8 has_opener;
+-	rwlock_t pak_lock;  // protects all of the previous fields
++	rwlock_t pak_lock;	// protects all of the previous fields
+ 	wait_queue_head_t wait_queue;
+ };
++
++struct vtpm_resp_hdr {
++	uint32_t instance_no;
++	uint16_t tag_no;
++	uint32_t len_no;
++	uint32_t ordinal_no;
++} __attribute__ ((packed));
+ 
+ struct packet {
+ 	struct list_head next;
+@@ -50,36 +56,30 @@ enum {
+ 	PACKET_FLAG_CHECK_RESPONSESTATUS = 2,
+ };
+ 
++/* local variables */
+ static struct data_exchange dataex;
+ 
+ /* local function prototypes */
++static int _packet_write(struct packet *pak,
++			 const char *data, size_t size, int userbuffer);
++static void processing_timeout(unsigned long ptr);
++static int packet_read_shmem(struct packet *pak,
++			     tpmif_t * tpmif,
++			     u32 offset,
++			     char *buffer, int isuserbuffer, u32 left);
+ static int vtpm_queue_packet(struct packet *pak);
+-static int _packet_write(struct packet *pak,
+-                         const char *data, size_t size,
+-                         int userbuffer);
+-static void processing_timeout(unsigned long ptr);
+-static int  packet_read_shmem(struct packet *pak,
+-                              tpmif_t *tpmif,
+-                              u32 offset,
+-                              char *buffer,
+-                              int isuserbuffer,
+-                              u32 left);
+-
+ 
+ #define MIN(x,y)  (x) < (y) ? (x) : (y)
+ 
+-
+ /***************************************************************
+- Buffer copying
++ Buffer copying fo user and kernel space buffes.
+ ***************************************************************/
+-static inline int
+-copy_from_buffer(void *to,
+-                 const void *from,
+-                 unsigned long size,
+-                 int userbuffer)
+-{
+-	if (userbuffer) {
+-		if (copy_from_user(to, from, size))
++static inline int copy_from_buffer(void *to,
++				   const void *from, unsigned long size,
++				   int isuserbuffer)
++{
++	if (isuserbuffer) {
++		if (copy_from_user(to, (void __user *)from, size))
+ 			return -EFAULT;
+ 	} else {
+ 		memcpy(to, from, size);
+@@ -87,21 +87,36 @@ copy_from_buffer(void *to,
+ 	return 0;
+ }
+ 
++static inline int copy_to_buffer(void *to,
++				 const void *from, unsigned long size,
++				 int isuserbuffer)
++{
++	if (isuserbuffer) {
++		if (copy_to_user((void __user *)to, from, size))
++			return -EFAULT;
++	} else {
++		memcpy(to, from, size);
++	}
++	return 0;
++}
++
+ /***************************************************************
+  Packet-related functions
+ ***************************************************************/
+ 
+-static struct packet *
+-packet_find_instance(struct list_head *head, u32 tpm_instance)
++static struct packet *packet_find_instance(struct list_head *head,
++					   u32 tpm_instance)
+ {
+ 	struct packet *pak;
+ 	struct list_head *p;
++
+ 	/*
+ 	 * traverse the list of packets and return the first
+ 	 * one with the given instance number
+ 	 */
+ 	list_for_each(p, head) {
+ 		pak = list_entry(p, struct packet, next);
++
+ 		if (pak->tpm_instance == tpm_instance) {
+ 			return pak;
+ 		}
+@@ -109,17 +124,18 @@ packet_find_instance(struct list_head *h
+ 	return NULL;
+ }
+ 
+-static struct packet *
+-packet_find_packet(struct list_head *head, void *packet)
++static struct packet *packet_find_packet(struct list_head *head, void *packet)
+ {
+ 	struct packet *pak;
+ 	struct list_head *p;
++
+ 	/*
+ 	 * traverse the list of packets and return the first
+ 	 * one with the given instance number
+ 	 */
+ 	list_for_each(p, head) {
+ 		pak = list_entry(p, struct packet, next);
++
+ 		if (pak == packet) {
+ 			return pak;
+ 		}
+@@ -127,22 +143,20 @@ packet_find_packet(struct list_head *hea
+ 	return NULL;
+ }
+ 
+-static struct packet *
+-packet_alloc(tpmif_t *tpmif, u32 size, u8 req_tag, u8 flags)
++static struct packet *packet_alloc(tpmif_t * tpmif,
++				   u32 size, u8 req_tag, u8 flags)
+ {
+ 	struct packet *pak = NULL;
+-	pak = kmalloc(sizeof(struct packet),
+-                      GFP_KERNEL);
++	pak = kzalloc(sizeof (struct packet), GFP_KERNEL);
+ 	if (NULL != pak) {
+-		memset(pak, 0x0, sizeof(*pak));
+ 		if (tpmif) {
+ 			pak->tpmif = tpmif;
+ 			pak->tpm_instance = tpmif->tpm_instance;
+ 		}
+-		pak->data_len  = size;
+-		pak->req_tag   = req_tag;
++		pak->data_len = size;
++		pak->req_tag = req_tag;
+ 		pak->last_read = 0;
+-		pak->flags     = flags;
++		pak->flags = flags;
+ 
+ 		/*
+ 		 * cannot do tpmif_get(tpmif); bad things happen
+@@ -155,16 +169,16 @@ packet_alloc(tpmif_t *tpmif, u32 size, u
+ 	return pak;
+ }
+ 
+-static void inline
+-packet_reset(struct packet *pak)
++static void inline packet_reset(struct packet *pak)
+ {
+ 	pak->last_read = 0;
+ }
+ 
+-static void inline
+-packet_free(struct packet *pak)
+-{
+-	del_singleshot_timer_sync(&pak->processing_timer);
++static void packet_free(struct packet *pak)
++{
++	if (timer_pending(&pak->processing_timer)) {
++		BUG();
++	}
+ 	kfree(pak->data_buffer);
+ 	/*
+ 	 * cannot do tpmif_put(pak->tpmif); bad things happen
+@@ -173,13 +187,13 @@ packet_free(struct packet *pak)
+ 	kfree(pak);
+ }
+ 
+-static int
+-packet_set(struct packet *pak,
+-           const unsigned char *buffer, u32 size)
++static int packet_set(struct packet *pak,
++		      const unsigned char *buffer, u32 size)
+ {
+ 	int rc = 0;
+ 	unsigned char *buf = kmalloc(size, GFP_KERNEL);
+-	if (NULL != buf) {
++
++	if (buf) {
+ 		pak->data_buffer = buf;
+ 		memcpy(buf, buffer, size);
+ 		pak->data_len = size;
+@@ -189,27 +203,21 @@ packet_set(struct packet *pak,
+ 	return rc;
+ }
+ 
+-
+ /*
+  * Write data to the shared memory and send it to the FE.
+  */
+-static int
+-packet_write(struct packet *pak,
+-             const char *data, size_t size,
+-             int userbuffer)
++static int packet_write(struct packet *pak,
++			const char *data, size_t size, int isuserbuffer)
+ {
+ 	int rc = 0;
+ 
+-	DPRINTK("Supposed to send %d bytes to front-end!\n",
+-	        size);
+-
+-	if (0 != (pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
++	if ((pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
+ #ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
+ 		u32 res;
++
+ 		if (copy_from_buffer(&res,
+-		                     &data[2+4],
+-		                     sizeof(res),
+-		                     userbuffer)) {
++				     &data[2 + 4], sizeof (res),
++				     isuserbuffer)) {
+ 			return -EFAULT;
+ 		}
+ 
+@@ -230,17 +238,14 @@ packet_write(struct packet *pak,
+ 		/* Don't send a respone to this packet. Just acknowledge it. */
+ 		rc = size;
+ 	} else {
+-		rc = _packet_write(pak, data, size, userbuffer);
++		rc = _packet_write(pak, data, size, isuserbuffer);
+ 	}
+ 
+ 	return rc;
+ }
+ 
+-
+-static int
+-_packet_write(struct packet *pak,
+-              const char *data, size_t size,
+-              int userbuffer)
++int _packet_write(struct packet *pak,
++		  const char *data, size_t size, int isuserbuffer)
+ {
+ 	/*
+ 	 * Write into the shared memory pages directly
+@@ -254,7 +259,7 @@ _packet_write(struct packet *pak,
+ 
+ 	if (tpmif == NULL) {
+ 		return -EFAULT;
+-        }
++	}
+ 
+ 	if (tpmif->status == DISCONNECTED) {
+ 		return size;
+@@ -273,16 +278,13 @@ _packet_write(struct packet *pak,
+ 			return 0;
+ 		}
+ 
+-		map_op.host_addr  = MMAP_VADDR(tpmif, i);
+-		map_op.flags      = GNTMAP_host_map;
+-		map_op.ref        = tx->ref;
+-		map_op.dom        = tpmif->domid;
+-
+-		if(unlikely(
+-		    HYPERVISOR_grant_table_op(
+-		        GNTTABOP_map_grant_ref,
+-		        &map_op,
+-		        1))) {
++		map_op.host_addr = MMAP_VADDR(tpmif, i);
++		map_op.flags = GNTMAP_host_map;
++		map_op.ref = tx->ref;
++		map_op.dom = tpmif->domid;
++
++		if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
++						       &map_op, 1))) {
+ 			BUG();
+ 		}
+ 
+@@ -292,28 +294,27 @@ _packet_write(struct packet *pak,
+ 			DPRINTK(" Grant table operation failure !\n");
+ 			return 0;
+ 		}
+-		set_phys_to_machine(__pa(MMAP_VADDR(tpmif,i)) >> PAGE_SHIFT,
+-			FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT));
++		set_phys_to_machine(__pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT,
++				    FOREIGN_FRAME(map_op.
++						  dev_bus_addr >> PAGE_SHIFT));
+ 
+ 		tocopy = MIN(size - offset, PAGE_SIZE);
+ 
+-		if (copy_from_buffer((void *)(MMAP_VADDR(tpmif,i)|
+-		                     (tx->addr & ~PAGE_MASK)),
+-		                     &data[offset],
+-		                     tocopy,
+-		                     userbuffer)) {
++		if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) |
++					      (tx->addr & ~PAGE_MASK)),
++				     &data[offset], tocopy, isuserbuffer)) {
+ 			tpmif_put(tpmif);
+ 			return -EFAULT;
+ 		}
+ 		tx->size = tocopy;
+ 
+-		unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
+-		unmap_op.handle       = handle;
++		unmap_op.host_addr = MMAP_VADDR(tpmif, i);
++		unmap_op.handle = handle;
+ 		unmap_op.dev_bus_addr = 0;
+ 
+-		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+-		                                      &unmap_op,
+-		                                      1))) {
++		if (unlikely
++		    (HYPERVISOR_grant_table_op
++		     (GNTTABOP_unmap_grant_ref, &unmap_op, 1))) {
+ 			BUG();
+ 		}
+ 
+@@ -322,8 +323,7 @@ _packet_write(struct packet *pak,
+ 	}
+ 
+ 	rc = offset;
+-	DPRINTK("Notifying frontend via irq %d\n",
+-	        tpmif->irq);
++	DPRINTK("Notifying frontend via irq %d\n", tpmif->irq);
+ 	notify_remote_via_irq(tpmif->irq);
+ 
+ 	return rc;
+@@ -334,26 +334,19 @@ _packet_write(struct packet *pak,
+  * provided buffer. Advance the read_last indicator which tells
+  * how many bytes have already been read.
+  */
+-static int
+-packet_read(struct packet *pak, size_t numbytes,
+-            char *buffer, size_t buffersize,
+-            int userbuffer)
++static int packet_read(struct packet *pak, size_t numbytes,
++		       char *buffer, size_t buffersize, int isuserbuffer)
+ {
+ 	tpmif_t *tpmif = pak->tpmif;
+-	/*
+-	 * I am supposed to read 'numbytes' of data from the
+-	 * buffer.
+-	 * The first 4 bytes that are read are the instance number in
+-	 * network byte order, after that comes the data from the
+-	 * shared memory buffer.
++
++	/*
++	 * Read 'numbytes' of data from the buffer. The first 4
++	 * bytes are the instance number in network byte order,
++	 * after that come the data from the shared memory buffer.
+ 	 */
+ 	u32 to_copy;
+ 	u32 offset = 0;
+ 	u32 room_left = buffersize;
+-	/*
+-	 * Ensure that we see the request when we copy it.
+-	 */
+-	mb();
+ 
+ 	if (pak->last_read < 4) {
+ 		/*
+@@ -361,18 +354,13 @@ packet_read(struct packet *pak, size_t n
+ 		 */
+ 		u32 instance_no = htonl(pak->tpm_instance);
+ 		u32 last_read = pak->last_read;
++
+ 		to_copy = MIN(4 - last_read, numbytes);
+ 
+-		if (userbuffer) {
+-			if (copy_to_user(&buffer[0],
+-			                 &(((u8 *)&instance_no)[last_read]),
+-			                 to_copy)) {
+-				return -EFAULT;
+-			}
+-		} else {
+-			memcpy(&buffer[0],
+-			       &(((u8 *)&instance_no)[last_read]),
+-			       to_copy);
++		if (copy_to_buffer(&buffer[0],
++				   &(((u8 *) & instance_no)[last_read]),
++				   to_copy, isuserbuffer)) {
++			return -EFAULT;
+ 		}
+ 
+ 		pak->last_read += to_copy;
+@@ -388,39 +376,30 @@ packet_read(struct packet *pak, size_t n
+ 		if (pak->data_buffer) {
+ 			u32 to_copy = MIN(pak->data_len - offset, room_left);
+ 			u32 last_read = pak->last_read - 4;
+-			if (userbuffer) {
+-				if (copy_to_user(&buffer[offset],
+-				                 &pak->data_buffer[last_read],
+-				                 to_copy)) {
+-					return -EFAULT;
+-				}
+-			} else {
+-				memcpy(&buffer[offset],
+-				       &pak->data_buffer[last_read],
+-				       to_copy);
++
++			if (copy_to_buffer(&buffer[offset],
++					   &pak->data_buffer[last_read],
++					   to_copy, isuserbuffer)) {
++				return -EFAULT;
+ 			}
+ 			pak->last_read += to_copy;
+ 			offset += to_copy;
+ 		} else {
+ 			offset = packet_read_shmem(pak,
+-			                           tpmif,
+-			                           offset,
+-			                           buffer,
+-			                           userbuffer,
+-			                           room_left);
++						   tpmif,
++						   offset,
++						   buffer,
++						   isuserbuffer, room_left);
+ 		}
+ 	}
+ 	return offset;
+ }
+ 
+-
+-static int
+-packet_read_shmem(struct packet *pak,
+-                  tpmif_t *tpmif,
+-                  u32 offset,
+-                  char *buffer,
+-                  int isuserbuffer,
+-                  u32 room_left) {
++static int packet_read_shmem(struct packet *pak,
++			     tpmif_t * tpmif,
++			     u32 offset, char *buffer, int isuserbuffer,
++			     u32 room_left)
++{
+ 	u32 last_read = pak->last_read - 4;
+ 	u32 i = (last_read / PAGE_SIZE);
+ 	u32 pg_offset = last_read & (PAGE_SIZE - 1);
+@@ -428,6 +407,7 @@ packet_read_shmem(struct packet *pak,
+ 	grant_handle_t handle;
+ 
+ 	tpmif_tx_request_t *tx;
++
+ 	tx = &tpmif->tx->ring[0].req;
+ 	/*
+ 	 * Start copying data at the page with index 'index'
+@@ -443,13 +423,12 @@ packet_read_shmem(struct packet *pak,
+ 		tx = &tpmif->tx->ring[i].req;
+ 
+ 		map_op.host_addr = MMAP_VADDR(tpmif, i);
+-		map_op.flags     = GNTMAP_host_map;
+-		map_op.ref       = tx->ref;
+-		map_op.dom       = tpmif->domid;
+-
+-		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+-		                                      &map_op,
+-		                                      1))) {
++		map_op.flags = GNTMAP_host_map;
++		map_op.ref = tx->ref;
++		map_op.dom = tpmif->domid;
++
++		if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
++						       &map_op, 1))) {
+ 			BUG();
+ 		}
+ 
+@@ -462,41 +441,33 @@ packet_read_shmem(struct packet *pak,
+ 
+ 		if (to_copy > tx->size) {
+ 			/*
+-			 * This is the case when the user wants to read more
+-			 * than what we have. So we just give him what we
+-			 * have.
++			 * User requests more than what's available
+ 			 */
+ 			to_copy = MIN(tx->size, to_copy);
+ 		}
+ 
+ 		DPRINTK("Copying from mapped memory at %08lx\n",
+-		        (unsigned long)(MMAP_VADDR(tpmif,i) |
+-			(tx->addr & ~PAGE_MASK)));
+-
+-		src = (void *)(MMAP_VADDR(tpmif,i) | ((tx->addr & ~PAGE_MASK) + pg_offset));
+-		if (isuserbuffer) {
+-			if (copy_to_user(&buffer[offset],
+-			                 src,
+-			                 to_copy)) {
+-				return -EFAULT;
+-			}
+-		} else {
+-			memcpy(&buffer[offset],
+-			       src,
+-			       to_copy);
+-		}
+-
++			(unsigned long)(MMAP_VADDR(tpmif, i) |
++					(tx->addr & ~PAGE_MASK)));
++
++		src = (void *)(MMAP_VADDR(tpmif, i) |
++			       ((tx->addr & ~PAGE_MASK) + pg_offset));
++		if (copy_to_buffer(&buffer[offset],
++				   src, to_copy, isuserbuffer)) {
++			return -EFAULT;
++		}
+ 
+ 		DPRINTK("Data from TPM-FE of domain %d are %d %d %d %d\n",
+-		        tpmif->domid, buffer[offset], buffer[offset+1],buffer[offset+2],buffer[offset+3]);
+-
+-		unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
+-		unmap_op.handle       = handle;
++			tpmif->domid, buffer[offset], buffer[offset + 1],
++			buffer[offset + 2], buffer[offset + 3]);
++
++		unmap_op.host_addr = MMAP_VADDR(tpmif, i);
++		unmap_op.handle = handle;
+ 		unmap_op.dev_bus_addr = 0;
+ 
+-		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+-		                                      &unmap_op,
+-		                                      1))) {
++		if (unlikely
++		    (HYPERVISOR_grant_table_op
++		     (GNTTABOP_unmap_grant_ref, &unmap_op, 1))) {
+ 			BUG();
+ 		}
+ 
+@@ -507,21 +478,19 @@ packet_read_shmem(struct packet *pak,
+ 
+ 		to_copy = MIN(PAGE_SIZE, room_left);
+ 		i++;
+-	} /* while (to_copy > 0) */
++	}			/* while (to_copy > 0) */
+ 	/*
+ 	 * Adjust the last_read pointer
+ 	 */
+ 	pak->last_read = last_read + 4;
+ 	return offset;
+ }
+-
+ 
+ /* ============================================================
+  * The file layer for reading data from this device
+  * ============================================================
+  */
+-static int
+-vtpm_op_open(struct inode *inode, struct file *f)
++static int vtpm_op_open(struct inode *inode, struct file *f)
+ {
+ 	int rc = 0;
+ 	unsigned long flags;
+@@ -536,9 +505,8 @@ vtpm_op_open(struct inode *inode, struct
+ 	return rc;
+ }
+ 
+-static ssize_t
+-vtpm_op_read(struct file *file,
+-	     char __user * data, size_t size, loff_t * offset)
++static ssize_t vtpm_op_read(struct file *file,
++			    char __user * data, size_t size, loff_t * offset)
+ {
+ 	int ret_size = -ENODATA;
+ 	struct packet *pak = NULL;
+@@ -549,7 +517,7 @@ vtpm_op_read(struct file *file,
+ 	if (list_empty(&dataex.pending_pak)) {
+ 		write_unlock_irqrestore(&dataex.pak_lock, flags);
+ 		wait_event_interruptible(dataex.wait_queue,
+-		                         !list_empty(&dataex.pending_pak));
++					 !list_empty(&dataex.pending_pak));
+ 		write_lock_irqsave(&dataex.pak_lock, flags);
+ 	}
+ 
+@@ -561,7 +529,7 @@ vtpm_op_read(struct file *file,
+ 
+ 		DPRINTK("size given by app: %d, available: %d\n", size, left);
+ 
+-		ret_size = MIN(size,left);
++		ret_size = MIN(size, left);
+ 
+ 		ret_size = packet_read(pak, ret_size, data, size, 1);
+ 		if (ret_size < 0) {
+@@ -574,7 +542,8 @@ vtpm_op_read(struct file *file,
+ 				DPRINTK("All data from this packet given to app.\n");
+ 				/* All data given to app */
+ 
+-				del_singleshot_timer_sync(&pak->processing_timer);
++				del_singleshot_timer_sync(&pak->
++							  processing_timer);
+ 				list_del(&pak->next);
+ 				list_add_tail(&pak->next, &dataex.current_pak);
+ 				/*
+@@ -582,7 +551,7 @@ vtpm_op_read(struct file *file,
+ 				 * the more time we give the TPM to process the request.
+ 				 */
+ 				mod_timer(&pak->processing_timer,
+-				          jiffies + (num_frontends * 60 * HZ));
++					  jiffies + (num_frontends * 60 * HZ));
+ 				dataex.copied_so_far = 0;
+ 			}
+ 		}
+@@ -597,16 +566,15 @@ vtpm_op_read(struct file *file,
+ /*
+  * Write operation - only works after a previous read operation!
+  */
+-static ssize_t
+-vtpm_op_write(struct file *file, const char __user * data, size_t size,
+-	      loff_t * offset)
++static ssize_t vtpm_op_write(struct file *file,
++			     const char __user * data, size_t size,
++			     loff_t * offset)
+ {
+ 	struct packet *pak;
+ 	int rc = 0;
+ 	unsigned int off = 4;
+ 	unsigned long flags;
+-	u32 instance_no = 0;
+-	u32 len_no = 0;
++	struct vtpm_resp_hdr vrh;
+ 
+ 	/*
+ 	 * Minimum required packet size is:
+@@ -616,45 +584,38 @@ vtpm_op_write(struct file *file, const c
+ 	 * 4 bytes for the ordinal
+ 	 * sum: 14 bytes
+ 	 */
+-	if ( size < off + 10 ) {
++	if (size < sizeof (vrh))
+ 		return -EFAULT;
+-	}
+-
+-	if (copy_from_user(&instance_no,
+-	                   (void __user *)&data[0],
+-	                   4)) {
++
++	if (copy_from_user(&vrh, data, sizeof (vrh)))
+ 		return -EFAULT;
+-	}
+-
+-	if (copy_from_user(&len_no,
+-	                   (void __user *)&data[off+2],
+-	                   4) ||
+-	    (off + ntohl(len_no) != size)) {
++
++	/* malformed packet? */
++	if ((off + ntohl(vrh.len_no)) != size)
+ 		return -EFAULT;
+-	}
+ 
+ 	write_lock_irqsave(&dataex.pak_lock, flags);
+-	pak = packet_find_instance(&dataex.current_pak, ntohl(instance_no));
++	pak = packet_find_instance(&dataex.current_pak,
++				   ntohl(vrh.instance_no));
+ 
+ 	if (pak == NULL) {
+ 		write_unlock_irqrestore(&dataex.pak_lock, flags);
+-		printk(KERN_ALERT "No associated packet!\n");
++		printk(KERN_ALERT "No associated packet! (inst=%d)\n",
++		       ntohl(vrh.instance_no));
+ 		return -EFAULT;
+-	} else {
+-		del_singleshot_timer_sync(&pak->processing_timer);
+-		list_del(&pak->next);
+-	}
++	}
++
++	del_singleshot_timer_sync(&pak->processing_timer);
++	list_del(&pak->next);
+ 
+ 	write_unlock_irqrestore(&dataex.pak_lock, flags);
+ 
+ 	/*
+-	 * The first 'offset' bytes must be the instance number.
+-	 * I will just pull that from the packet.
++	 * The first 'offset' bytes must be the instance number - skip them.
+ 	 */
+ 	size -= off;
+-	data = &data[off];
+-
+-	rc = packet_write(pak, data, size, 1);
++
++	rc = packet_write(pak, &data[off], size, 1);
+ 
+ 	if (rc > 0) {
+ 		/* I neglected the first 4 bytes */
+@@ -664,10 +625,10 @@ vtpm_op_write(struct file *file, const c
+ 	return rc;
+ }
+ 
+-static int
+-vtpm_op_release(struct inode *inode, struct file *file)
++static int vtpm_op_release(struct inode *inode, struct file *file)
+ {
+ 	unsigned long flags;
++
+ 	vtpm_release_packets(NULL, 1);
+ 	write_lock_irqsave(&dataex.pak_lock, flags);
+ 	dataex.has_opener = 0;
+@@ -675,10 +636,11 @@ vtpm_op_release(struct inode *inode, str
+ 	return 0;
+ }
+ 
+-static unsigned int
+-vtpm_op_poll(struct file *file, struct poll_table_struct *pts)
++static unsigned int vtpm_op_poll(struct file *file,
++				 struct poll_table_struct *pts)
+ {
+ 	unsigned int flags = POLLOUT | POLLWRNORM;
++
+ 	poll_wait(file, &dataex.wait_queue, pts);
+ 	if (!list_empty(&dataex.pending_pak)) {
+ 		flags |= POLLIN | POLLRDNORM;
+@@ -696,54 +658,47 @@ static struct file_operations vtpm_ops =
+ 	.poll = vtpm_op_poll,
+ };
+ 
+-static struct miscdevice ibmvtpms_miscdevice = {
++static struct miscdevice vtpms_miscdevice = {
+ 	.minor = 225,
+ 	.name = "vtpm",
+ 	.fops = &vtpm_ops,
+ };
+ 
+-
+ /***************************************************************
+  Virtual TPM functions and data stuctures
+ ***************************************************************/
+ 
+ static u8 create_cmd[] = {
+-        1,193,		/* 0: TPM_TAG_RQU_COMMAMD */
+-        0,0,0,19,	/* 2: length */
+-        0,0,0,0x1,	/* 6: VTPM_ORD_OPEN */
+-        0,		/* 10: VTPM type */
+-        0,0,0,0,	/* 11: domain id */
+-        0,0,0,0		/* 15: instance id */
++	1, 193,			/* 0: TPM_TAG_RQU_COMMAMD */
++	0, 0, 0, 19,		/* 2: length */
++	0, 0, 0, 0x1,		/* 6: VTPM_ORD_OPEN */
++	0,			/* 10: VTPM type */
++	0, 0, 0, 0,		/* 11: domain id */
++	0, 0, 0, 0		/* 15: instance id */
+ };
+ 
+-static u8 destroy_cmd[] = {
+-        1,193,		/* 0: TPM_TAG_RQU_COMMAMD */
+-        0,0,0,14,	/* 2: length */
+-        0,0,0,0x2,	/* 6: VTPM_ORD_CLOSE */
+-        0,0,0,0		/* 10: instance id */
+-};
+-
+-int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domid, u32 instance)
++int tpmif_vtpm_open(tpmif_t * tpmif, domid_t domid, u32 instance)
+ {
+ 	int rc = 0;
+ 	struct packet *pak;
+ 
+ 	pak = packet_alloc(tpmif,
+-	                   sizeof(create_cmd),
+-	                   create_cmd[0],
+-	                   PACKET_FLAG_DISCARD_RESPONSE|
+-	                   PACKET_FLAG_CHECK_RESPONSESTATUS);
++			   sizeof (create_cmd),
++			   create_cmd[1],
++			   PACKET_FLAG_DISCARD_RESPONSE |
++			   PACKET_FLAG_CHECK_RESPONSESTATUS);
+ 	if (pak) {
+-		u8 buf[sizeof(create_cmd)];
+-		u32 domid_no = htonl((u32)domid);
++		u8 buf[sizeof (create_cmd)];
++		u32 domid_no = htonl((u32) domid);
+ 		u32 instance_no = htonl(instance);
+-		memcpy(buf, create_cmd, sizeof(create_cmd));
+-
+-		memcpy(&buf[11], &domid_no, sizeof(u32));
+-		memcpy(&buf[15], &instance_no, sizeof(u32));
++
++		memcpy(buf, create_cmd, sizeof (create_cmd));
++
++		memcpy(&buf[11], &domid_no, sizeof (u32));
++		memcpy(&buf[15], &instance_no, sizeof (u32));
+ 
+ 		/* copy the buffer into the packet */
+-		rc = packet_set(pak, buf, sizeof(buf));
++		rc = packet_set(pak, buf, sizeof (buf));
+ 
+ 		if (rc == 0) {
+ 			pak->tpm_instance = 0;
+@@ -759,23 +714,30 @@ int tpmif_vtpm_open(tpmif_t *tpmif, domi
+ 	return rc;
+ }
+ 
++static u8 destroy_cmd[] = {
++	1, 193,			/* 0: TPM_TAG_RQU_COMMAMD */
++	0, 0, 0, 14,		/* 2: length */
++	0, 0, 0, 0x2,		/* 6: VTPM_ORD_CLOSE */
++	0, 0, 0, 0		/* 10: instance id */
++};
++
+ int tpmif_vtpm_close(u32 instid)
+ {
+ 	int rc = 0;
+ 	struct packet *pak;
+ 
+ 	pak = packet_alloc(NULL,
+-	                   sizeof(create_cmd),
+-	                   create_cmd[0],
+-	                   PACKET_FLAG_DISCARD_RESPONSE);
++			   sizeof (destroy_cmd),
++			   destroy_cmd[1], PACKET_FLAG_DISCARD_RESPONSE);
+ 	if (pak) {
+-		u8 buf[sizeof(destroy_cmd)];
++		u8 buf[sizeof (destroy_cmd)];
+ 		u32 instid_no = htonl(instid);
+-		memcpy(buf, destroy_cmd, sizeof(destroy_cmd));
+-		memcpy(&buf[10], &instid_no, sizeof(u32));
++
++		memcpy(buf, destroy_cmd, sizeof (destroy_cmd));
++		memcpy(&buf[10], &instid_no, sizeof (u32));
+ 
+ 		/* copy the buffer into the packet */
+-		rc = packet_set(pak, buf, sizeof(buf));
++		rc = packet_set(pak, buf, sizeof (buf));
+ 
+ 		if (rc == 0) {
+ 			pak->tpm_instance = 0;
+@@ -791,23 +753,22 @@ int tpmif_vtpm_close(u32 instid)
+ 	return rc;
+ }
+ 
+-
+ /***************************************************************
+  Utility functions
+ ***************************************************************/
+ 
+-static int
+-tpm_send_fail_message(struct packet *pak, u8 req_tag)
++static int tpm_send_fail_message(struct packet *pak, u8 req_tag)
+ {
+ 	int rc;
+ 	static const unsigned char tpm_error_message_fail[] = {
+ 		0x00, 0x00,
+ 		0x00, 0x00, 0x00, 0x0a,
+-		0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
++		0x00, 0x00, 0x00, 0x09	/* TPM_FAIL */
+ 	};
+-	unsigned char buffer[sizeof(tpm_error_message_fail)];
+-
+-	memcpy(buffer, tpm_error_message_fail, sizeof(tpm_error_message_fail));
++	unsigned char buffer[sizeof (tpm_error_message_fail)];
++
++	memcpy(buffer, tpm_error_message_fail,
++	       sizeof (tpm_error_message_fail));
+ 	/*
+ 	 * Insert the right response tag depending on the given tag
+ 	 * All response tags are '+3' to the request tag.
+@@ -817,23 +778,24 @@ tpm_send_fail_message(struct packet *pak
+ 	/*
+ 	 * Write the data to shared memory and notify the front-end
+ 	 */
+-	rc = packet_write(pak, buffer, sizeof(buffer), 0);
++	rc = packet_write(pak, buffer, sizeof (buffer), 0);
+ 
+ 	return rc;
+ }
+ 
+-
+-static void
+-_vtpm_release_packets(struct list_head *head, tpmif_t *tpmif,
+-                      int send_msgs)
++static void _vtpm_release_packets(struct list_head *head,
++				  tpmif_t * tpmif, int send_msgs)
+ {
+ 	struct packet *pak;
+-	struct list_head *pos, *tmp;
++	struct list_head *pos,
++	         *tmp;
+ 
+ 	list_for_each_safe(pos, tmp, head) {
+ 		pak = list_entry(pos, struct packet, next);
++
+ 		if (tpmif == NULL || pak->tpmif == tpmif) {
+ 			int can_send = 0;
++
+ 			del_singleshot_timer_sync(&pak->processing_timer);
+ 			list_del(&pak->next);
+ 
+@@ -849,9 +811,7 @@ _vtpm_release_packets(struct list_head *
+ 	}
+ }
+ 
+-
+-int
+-vtpm_release_packets(tpmif_t *tpmif, int send_msgs)
++int vtpm_release_packets(tpmif_t * tpmif, int send_msgs)
+ {
+ 	unsigned long flags;
+ 
+@@ -860,23 +820,22 @@ vtpm_release_packets(tpmif_t *tpmif, int
+ 	_vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
+ 	_vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
+ 
+-	write_unlock_irqrestore(&dataex.pak_lock,
+-	                        flags);
++	write_unlock_irqrestore(&dataex.pak_lock, flags);
+ 	return 0;
+ }
+ 
+-
+ static int vtpm_queue_packet(struct packet *pak)
+ {
+ 	int rc = 0;
++
+ 	if (dataex.has_opener) {
+ 		unsigned long flags;
++
+ 		write_lock_irqsave(&dataex.pak_lock, flags);
+ 		list_add_tail(&pak->next, &dataex.pending_pak);
+ 		/* give the TPM some time to pick up the request */
+ 		mod_timer(&pak->processing_timer, jiffies + (30 * HZ));
+-		write_unlock_irqrestore(&dataex.pak_lock,
+-		                        flags);
++		write_unlock_irqrestore(&dataex.pak_lock, flags);
+ 
+ 		wake_up_interruptible(&dataex.wait_queue);
+ 	} else {
+@@ -885,24 +844,22 @@ static int vtpm_queue_packet(struct pack
+ 	return rc;
+ }
+ 
+-
+-static int vtpm_receive(tpmif_t *tpmif, u32 size)
++static int vtpm_receive(tpmif_t * tpmif, u32 size)
+ {
+ 	int rc = 0;
+ 	unsigned char buffer[10];
+ 	__be32 *native_size;
+-
+-	struct packet *pak = packet_alloc(tpmif, size, buffer[4], 0);
+-	if (NULL == pak) {
++	struct packet *pak = packet_alloc(tpmif, size, 0, 0);
++
++	if (!pak)
+ 		return -ENOMEM;
+-	}
+ 	/*
+ 	 * Read 10 bytes from the received buffer to test its
+ 	 * content for validity.
+ 	 */
+-	if (sizeof(buffer) != packet_read(pak,
+-	                                  sizeof(buffer), buffer,
+-	                                  sizeof(buffer), 0)) {
++	if (sizeof (buffer) != packet_read(pak,
++					   sizeof (buffer), buffer,
++					   sizeof (buffer), 0)) {
+ 		goto failexit;
+ 	}
+ 	/*
+@@ -911,7 +868,7 @@ static int vtpm_receive(tpmif_t *tpmif, 
+ 	 */
+ 	packet_reset(pak);
+ 
+-	native_size = (__force __be32 *)(&buffer[4+2]);
++	native_size = (__force __be32 *) (&buffer[4 + 2]);
+ 	/*
+ 	 * Verify that the size of the packet is correct
+ 	 * as indicated and that there's actually someone reading packets.
+@@ -920,25 +877,23 @@ static int vtpm_receive(tpmif_t *tpmif, 
+ 	 */
+ 	if (size < 10 ||
+ 	    be32_to_cpu(*native_size) != size ||
+-	    0 == dataex.has_opener ||
+-	    tpmif->status != CONNECTED) {
+-	    	rc = -EINVAL;
+-	    	goto failexit;
++	    0 == dataex.has_opener || tpmif->status != CONNECTED) {
++		rc = -EINVAL;
++		goto failexit;
+ 	} else {
+-		if ((rc = vtpm_queue_packet(pak)) < 0) {
++		rc = vtpm_queue_packet(pak);
++		if (rc < 0)
+ 			goto failexit;
+-		}
+ 	}
+ 	return 0;
+ 
+-failexit:
++      failexit:
+ 	if (pak) {
+-		tpm_send_fail_message(pak, buffer[4+1]);
++		tpm_send_fail_message(pak, buffer[4 + 1]);
+ 		packet_free(pak);
+ 	}
+ 	return rc;
+ }
+-
+ 
+ /*
+  * Timeout function that gets invoked when a packet has not been processed
+@@ -951,22 +906,23 @@ static void processing_timeout(unsigned 
+ {
+ 	struct packet *pak = (struct packet *)ptr;
+ 	unsigned long flags;
++
+ 	write_lock_irqsave(&dataex.pak_lock, flags);
+ 	/*
+ 	 * The packet needs to be searched whether it
+ 	 * is still on the list.
+ 	 */
+ 	if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
+-	    pak == packet_find_packet(&dataex.current_pak, pak) ) {
++	    pak == packet_find_packet(&dataex.current_pak, pak)) {
+ 		list_del(&pak->next);
+-		tpm_send_fail_message(pak, pak->req_tag);
++		if ((pak->flags & PACKET_FLAG_DISCARD_RESPONSE) == 0) {
++			tpm_send_fail_message(pak, pak->req_tag);
++		}
+ 		packet_free(pak);
+ 	}
+ 
+ 	write_unlock_irqrestore(&dataex.pak_lock, flags);
+ }
+-
+-
+ 
+ static void tpm_tx_action(unsigned long unused);
+ static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0);
+@@ -974,21 +930,18 @@ static struct list_head tpm_schedule_lis
+ static struct list_head tpm_schedule_list;
+ static spinlock_t tpm_schedule_list_lock;
+ 
+-static inline void
+-maybe_schedule_tx_action(void)
++static inline void maybe_schedule_tx_action(void)
+ {
+ 	smp_mb();
+ 	tasklet_schedule(&tpm_tx_tasklet);
+ }
+ 
+-static inline int
+-__on_tpm_schedule_list(tpmif_t * tpmif)
++static inline int __on_tpm_schedule_list(tpmif_t * tpmif)
+ {
+ 	return tpmif->list.next != NULL;
+ }
+ 
+-static void
+-remove_from_tpm_schedule_list(tpmif_t * tpmif)
++static void remove_from_tpm_schedule_list(tpmif_t * tpmif)
+ {
+ 	spin_lock_irq(&tpm_schedule_list_lock);
+ 	if (likely(__on_tpm_schedule_list(tpmif))) {
+@@ -999,8 +952,7 @@ remove_from_tpm_schedule_list(tpmif_t * 
+ 	spin_unlock_irq(&tpm_schedule_list_lock);
+ }
+ 
+-static void
+-add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
++static void add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
+ {
+ 	if (__on_tpm_schedule_list(tpmif))
+ 		return;
+@@ -1013,22 +965,18 @@ add_to_tpm_schedule_list_tail(tpmif_t * 
+ 	spin_unlock_irq(&tpm_schedule_list_lock);
+ }
+ 
+-void
+-tpmif_schedule_work(tpmif_t * tpmif)
++void tpmif_schedule_work(tpmif_t * tpmif)
+ {
+ 	add_to_tpm_schedule_list_tail(tpmif);
+ 	maybe_schedule_tx_action();
+ }
+ 
+-void
+-tpmif_deschedule_work(tpmif_t * tpmif)
++void tpmif_deschedule_work(tpmif_t * tpmif)
+ {
+ 	remove_from_tpm_schedule_list(tpmif);
+ }
+ 
+-
+-static void
+-tpm_tx_action(unsigned long unused)
++static void tpm_tx_action(unsigned long unused)
+ {
+ 	struct list_head *ent;
+ 	tpmif_t *tpmif;
+@@ -1042,10 +990,6 @@ tpm_tx_action(unsigned long unused)
+ 		tpmif = list_entry(ent, tpmif_t, list);
+ 		tpmif_get(tpmif);
+ 		remove_from_tpm_schedule_list(tpmif);
+-		/*
+-		 * Ensure that we see the request when we read from it.
+-		 */
+-		mb();
+ 
+ 		tx = &tpmif->tx->ring[0].req;
+ 
+@@ -1056,22 +1000,22 @@ tpm_tx_action(unsigned long unused)
+ 	}
+ }
+ 
+-irqreturn_t
+-tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+-{
+-	tpmif_t *tpmif = dev_id;
++irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
++{
++	tpmif_t *tpmif = (tpmif_t *) dev_id;
++
+ 	add_to_tpm_schedule_list_tail(tpmif);
+ 	maybe_schedule_tx_action();
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int __init
+-tpmback_init(void)
++static int __init tpmback_init(void)
+ {
+ 	int rc;
+ 
+-	if ((rc = misc_register(&ibmvtpms_miscdevice)) != 0) {
+-		printk(KERN_ALERT "Could not register misc device for TPM BE.\n");
++	if ((rc = misc_register(&vtpms_miscdevice)) != 0) {
++		printk(KERN_ALERT
++		       "Could not register misc device for TPM BE.\n");
+ 		return rc;
+ 	}
+ 
+@@ -1092,7 +1036,18 @@ tpmback_init(void)
+ 	return 0;
+ }
+ 
+-__initcall(tpmback_init);
++module_init(tpmback_init);
++
++static void __exit tpmback_exit(void)
++{
++	tpmif_xenbus_exit();
++	tpmif_interface_exit();
++	misc_deregister(&vtpms_miscdevice);
++}
++
++module_exit(tpmback_exit);
++
++MODULE_LICENSE("Dual BSD/GPL");
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/tpmback/xenbus.c
+--- a/drivers/xen/tpmback/xenbus.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/tpmback/xenbus.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -317,6 +317,11 @@ void tpmif_xenbus_init(void)
+ 	xenbus_register_backend(&tpmback);
+ }
+ 
++void tpmif_xenbus_exit(void)
++{
++	xenbus_unregister_driver(&tpmback);
++}
++
+ /*
+  * Local variables:
+  *  c-file-style: "linux"
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/tpmfront/tpmfront.c
+--- a/drivers/xen/tpmfront/tpmfront.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/tpmfront/tpmfront.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -480,6 +480,11 @@ static void __init init_tpm_xenbus(void)
+ 	xenbus_register_frontend(&tpmfront);
+ }
+ 
++static void __exit exit_tpm_xenbus(void)
++{
++	xenbus_unregister_driver(&tpmfront);
++}
++
+ 
+ static int
+ tpm_allocate_buffers(struct tpm_private *tp)
+@@ -597,7 +602,6 @@ tpm_xmit(struct tpm_private *tp,
+ 
+ 		tx = &tp->tx->ring[i].req;
+ 
+-		tx->id = i;
+ 		tx->addr = virt_to_machine(txb->data);
+ 		tx->size = txb->len;
+ 
+@@ -700,7 +704,18 @@ tpmif_init(void)
+ 	return 0;
+ }
+ 
+-__initcall(tpmif_init);
++module_init(tpmif_init);
++
++static void __exit
++tpmif_exit(void)
++{
++	exit_tpm_xenbus();
++	gnttab_free_grant_references(gref_head);
++}
++
++module_exit(tpmif_exit);
++
++MODULE_LICENSE("Dual BSD/GPL");
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/xenbus/Makefile
+--- a/drivers/xen/xenbus/Makefile	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/xenbus/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -1,8 +1,8 @@ obj-y	+= xenbus.o
+ obj-y	+= xenbus.o
+ 
+ xenbus-objs =
+-xenbus-objs += xenbus_client.o 
++xenbus-objs += xenbus_client.o
+ xenbus-objs += xenbus_comms.o
+ xenbus-objs += xenbus_xs.o
+-xenbus-objs += xenbus_probe.o 
+-xenbus-objs += xenbus_dev.o 
++xenbus-objs += xenbus_probe.o
++xenbus-objs += xenbus_dev.o
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/xenbus/xenbus_client.c
+--- a/drivers/xen/xenbus/xenbus_client.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/xenbus/xenbus_client.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -39,7 +39,7 @@ extern char *kasprintf(const char *fmt, 
+     pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
+ 
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+-		      struct xenbus_watch *watch, 
++		      struct xenbus_watch *watch,
+ 		      void (*callback)(struct xenbus_watch *,
+ 				       const char **, unsigned int))
+ {
+@@ -62,7 +62,7 @@ EXPORT_SYMBOL(xenbus_watch_path);
+ 
+ 
+ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
+-		       const char *path2, struct xenbus_watch *watch, 
++		       const char *path2, struct xenbus_watch *watch,
+ 		       void (*callback)(struct xenbus_watch *,
+ 					const char **, unsigned int))
+ {
+@@ -74,9 +74,8 @@ int xenbus_watch_path2(struct xenbus_dev
+ 	}
+ 	err = xenbus_watch_path(dev, state, watch, callback);
+ 
+-	if (err) {
++	if (err)
+ 		kfree(state);
+-	}
+ 	return err;
+ }
+ EXPORT_SYMBOL(xenbus_watch_path2);
+@@ -95,18 +94,25 @@ int xenbus_switch_state(struct xenbus_de
+ 	 */
+ 
+ 	int current_state;
+-
+-	int err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
++	int err;
++
++	if (state == dev->state)
++		return 0;
++
++	err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
+ 			       &current_state);
+-	if ((err == 1 && (XenbusState)current_state == state) ||
+-	    err == -ENOENT)
++	if (err != 1)
+ 		return 0;
+ 
+ 	err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
+ 	if (err) {
+-		xenbus_dev_fatal(dev, err, "writing new state");
++		if (state != XenbusStateClosing) /* Avoid looping */
++			xenbus_dev_fatal(dev, err, "writing new state");
+ 		return err;
+ 	}
++
++	dev->state = state;
++
+ 	return 0;
+ }
+ EXPORT_SYMBOL(xenbus_switch_state);
+@@ -138,7 +144,6 @@ void _dev_error(struct xenbus_device *de
+ 	ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
+ 
+ 	BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
+-	dev->has_error = 1;
+ 
+ 	dev_err(&dev->dev, "%s\n", printf_buffer);
+ 
+@@ -184,7 +189,7 @@ void xenbus_dev_fatal(struct xenbus_devi
+ 	va_start(ap, fmt);
+ 	_dev_error(dev, err, fmt, ap);
+ 	va_end(ap);
+-	
++
+ 	xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
+ }
+ EXPORT_SYMBOL(xenbus_dev_fatal);
+@@ -207,7 +212,6 @@ int xenbus_alloc_evtchn(struct xenbus_de
+ 		.u.alloc_unbound.dom = DOMID_SELF,
+ 		.u.alloc_unbound.remote_dom = dev->otherend_id
+ 	};
+-
+ 	int err = HYPERVISOR_event_channel_op(&op);
+ 	if (err)
+ 		xenbus_dev_fatal(dev, err, "allocating event channel");
+@@ -225,7 +229,6 @@ int xenbus_bind_evtchn(struct xenbus_dev
+ 		.u.bind_interdomain.remote_dom = dev->otherend_id,
+ 		.u.bind_interdomain.remote_port = remote_port,
+ 	};
+-
+ 	int err = HYPERVISOR_event_channel_op(&op);
+ 	if (err)
+ 		xenbus_dev_fatal(dev, err,
+@@ -382,7 +385,6 @@ XenbusState xenbus_read_driver_state(con
+ XenbusState xenbus_read_driver_state(const char *path)
+ {
+ 	XenbusState result;
+-
+ 	int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL);
+ 	if (err)
+ 		result = XenbusStateClosed;
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/xenbus/xenbus_comms.c
+--- a/drivers/xen/xenbus/xenbus_comms.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/xenbus/xenbus_comms.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -38,8 +38,8 @@
+ 
+ static int xenbus_irq;
+ 
+-extern void xenbus_probe(void *); 
+-extern int xenstored_ready; 
++extern void xenbus_probe(void *);
++extern int xenstored_ready;
+ static DECLARE_WORK(probe_work, xenbus_probe, NULL);
+ 
+ DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
+@@ -52,9 +52,9 @@ static irqreturn_t wake_waiting(int irq,
+ static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
+ {
+ 	if (unlikely(xenstored_ready == 0)) {
+-		xenstored_ready = 1; 
+-		schedule_work(&probe_work); 
+-	} 
++		xenstored_ready = 1;
++		schedule_work(&probe_work);
++	}
+ 
+ 	wake_up(&xb_waitq);
+ 	return IRQ_HANDLED;
+@@ -89,14 +89,18 @@ int xb_write(const void *data, unsigned 
+ {
+ 	struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ 	XENSTORE_RING_IDX cons, prod;
++	int rc;
+ 
+ 	while (len != 0) {
+ 		void *dst;
+ 		unsigned int avail;
+ 
+-		wait_event_interruptible(xb_waitq,
+-					 (intf->req_prod - intf->req_cons) !=
+-					 XENSTORE_RING_SIZE);
++		rc = wait_event_interruptible(
++			xb_waitq,
++			(intf->req_prod - intf->req_cons) !=
++			XENSTORE_RING_SIZE);
++		if (rc < 0)
++			return rc;
+ 
+ 		/* Read indexes, then verify. */
+ 		cons = intf->req_cons;
+@@ -130,13 +134,17 @@ int xb_read(void *data, unsigned len)
+ {
+ 	struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ 	XENSTORE_RING_IDX cons, prod;
++	int rc;
+ 
+ 	while (len != 0) {
+ 		unsigned int avail;
+ 		const char *src;
+ 
+-		wait_event_interruptible(xb_waitq,
+-					 intf->rsp_cons != intf->rsp_prod);
++		rc = wait_event_interruptible(
++			xb_waitq,
++			intf->rsp_cons != intf->rsp_prod);
++		if (rc < 0)
++			return rc;
+ 
+ 		/* Read indexes, then verify. */
+ 		cons = intf->rsp_cons;
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/xenbus/xenbus_probe.c
+--- a/drivers/xen/xenbus/xenbus_probe.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/xenbus/xenbus_probe.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -45,9 +45,7 @@
+ #include <asm/hypervisor.h>
+ #include <xen/xenbus.h>
+ #include <xen/xen_proc.h>
+-#include <xen/balloon.h>
+ #include <xen/evtchn.h>
+-#include <xen/public/evtchn.h>
+ 
+ #include "xenbus_comms.h"
+ 
+@@ -368,7 +366,6 @@ fail:
+ 	xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
+ 	xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
+ 	return -ENODEV;
+-	
+ }
+ 
+ static int xenbus_dev_remove(struct device *_dev)
+@@ -497,9 +494,8 @@ static void xenbus_dev_free(struct xenbu
+ 
+ static void xenbus_dev_release(struct device *dev)
+ {
+-	if (dev) {
++	if (dev)
+ 		xenbus_dev_free(to_xenbus_device(dev));
+-	}
+ }
+ 
+ /* Simplified asprintf. */
+@@ -602,7 +598,7 @@ static int xenbus_probe_frontend(const c
+ 	nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
+ 	if (!nodename)
+ 		return -ENOMEM;
+-	
++
+ 	DPRINTK("%s", nodename);
+ 
+ 	err = xenbus_probe_node(&xenbus_frontend, type, nodename);
+@@ -886,9 +882,33 @@ EXPORT_SYMBOL(unregister_xenstore_notifi
+ EXPORT_SYMBOL(unregister_xenstore_notifier);
+ 
+ 
++static int all_devices_ready_(struct device *dev, void *data)
++{
++	struct xenbus_device *xendev = to_xenbus_device(dev);
++	int *result = data;
++
++	if (xendev->state != XenbusStateConnected) {
++		result = 0;
++		return 1;
++	}
++
++	return 0;
++}
++
++
++static int all_devices_ready(void)
++{
++	int ready = 1;
++	bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
++			 all_devices_ready_);
++	return ready;
++}
++
+ 
+ void xenbus_probe(void *unused)
+ {
++	int i;
++
+ 	BUG_ON((xenstored_ready <= 0));
+ 
+ 	/* Enumerate devices in xenstore. */
+@@ -901,17 +921,56 @@ void xenbus_probe(void *unused)
+ 
+ 	/* Notify others that xenstore is up */
+ 	notifier_call_chain(&xenstore_chain, 0, NULL);
+-}
+-
+-
++
++	/* On a 10 second timeout, waiting for all devices currently
++	   configured.  We need to do this to guarantee that the filesystems
++	   and / or network devices needed for boot are available, before we
++	   can allow the boot to proceed.
++
++	   A possible improvement here would be to have the tools add a
++	   per-device flag to the store entry, indicating whether it is needed
++	   at boot time.  This would allow people who knew what they were
++	   doing to accelerate their boot slightly, but of course needs tools
++	   or manual intervention to set up those flags correctly.
++	 */
++	for (i = 0; i < 10 * HZ; i++) {
++		if (all_devices_ready())
++			return;
++
++		set_current_state(TASK_INTERRUPTIBLE);
++		schedule_timeout(1);
++	}
++
++	printk(KERN_WARNING
++	       "XENBUS: Timeout connecting to devices!\n");
++}
++
++
++static struct file_operations xsd_kva_fops;
+ static struct proc_dir_entry *xsd_kva_intf;
+ static struct proc_dir_entry *xsd_port_intf;
+ 
++static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	size_t size = vma->vm_end - vma->vm_start;
++
++	if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
++		return -EINVAL;
++
++	vma->vm_pgoff = mfn_to_pfn(xen_start_info->store_mfn);
++
++	if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
++			    size, vma->vm_page_prot))
++		return -EAGAIN;
++
++	return 0;
++}
+ 
+ static int xsd_kva_read(char *page, char **start, off_t off,
+                         int count, int *eof, void *data)
+ {
+ 	int len;
++
+ 	len  = sprintf(page, "0x%p", mfn_to_virt(xen_start_info->store_mfn));
+ 	*eof = 1;
+ 	return len;
+@@ -946,8 +1005,8 @@ static int __init xenbus_probe_init(void
+ 	device_register(&xenbus_backend.dev);
+ 
+ 	/*
+-	** Domain0 doesn't have a store_evtchn or store_mfn yet.
+-	*/
++	 * Domain0 doesn't have a store_evtchn or store_mfn yet.
++	 */
+ 	dom0 = (xen_start_info->store_evtchn == 0);
+ 
+ 	if (dom0) {
+@@ -969,7 +1028,7 @@ static int __init xenbus_probe_init(void
+ 		xen_start_info->store_mfn =
+ 			pfn_to_mfn(virt_to_phys((void *)page) >>
+ 				   PAGE_SHIFT);
+-		
++
+ 		/* Next allocate a local port which xenstored can bind to */
+ 		op.cmd = EVTCHNOP_alloc_unbound;
+ 		op.u.alloc_unbound.dom        = DOMID_SELF;
+@@ -980,9 +1039,16 @@ static int __init xenbus_probe_init(void
+ 		xen_start_info->store_evtchn = op.u.alloc_unbound.port;
+ 
+ 		/* And finally publish the above info in /proc/xen */
+-		if((xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400)))
++		xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400);
++		if (xsd_kva_intf) {
++			memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops,
++			       sizeof(xsd_kva_fops));
++			xsd_kva_fops.mmap = xsd_kva_mmap;
++			xsd_kva_intf->proc_fops = &xsd_kva_fops;
+ 			xsd_kva_intf->read_proc = xsd_kva_read;
+-		if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
++		}
++		xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
++		if (xsd_port_intf)
+ 			xsd_port_intf->read_proc = xsd_port_read;
+ 	}
+ 
+diff -r c75ede70c907 -r f6bd46559b93 drivers/xen/xenbus/xenbus_xs.c
+--- a/drivers/xen/xenbus/xenbus_xs.c	Mon Feb 27 15:43:34 2006 +0000
++++ b/drivers/xen/xenbus/xenbus_xs.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -123,8 +123,9 @@ static void *read_reply(enum xsd_sockmsg
+ 
+ 	while (list_empty(&xs_state.reply_list)) {
+ 		spin_unlock(&xs_state.reply_lock);
+-		wait_event_interruptible(xs_state.reply_waitq,
+-					 !list_empty(&xs_state.reply_list));
++		/* XXX FIXME: Avoid synchronous wait for response here. */
++		wait_event(xs_state.reply_waitq,
++			   !list_empty(&xs_state.reply_list));
+ 		spin_lock(&xs_state.reply_lock);
+ 	}
+ 
+@@ -175,9 +176,8 @@ void *xenbus_dev_request_and_reply(struc
+ 	if (err) {
+ 		msg->type = XS_ERROR;
+ 		ret = ERR_PTR(err);
+-	} else {
++	} else
+ 		ret = read_reply(&msg->type, &msg->len);
+-	}
+ 
+ 	up(&xs_state.request_mutex);
+ 
+@@ -274,7 +274,7 @@ static unsigned int count_strings(const 
+ 	return num;
+ }
+ 
+-/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */ 
++/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
+ static char *join(const char *dir, const char *name)
+ {
+ 	char *buffer;
+@@ -685,6 +685,9 @@ static int xenwatch_thread(void *unused)
+ 		wait_event_interruptible(watch_events_waitq,
+ 					 !list_empty(&watch_events));
+ 
++		if (kthread_should_stop())
++			break;
++
+ 		down(&xenwatch_mutex);
+ 
+ 		spin_lock(&watch_events_lock);
+@@ -705,6 +708,8 @@ static int xenwatch_thread(void *unused)
+ 
+ 		up(&xenwatch_mutex);
+ 	}
++
++	return 0;
+ }
+ 
+ static int process_msg(void)
+@@ -778,7 +783,11 @@ static int xenbus_thread(void *unused)
+ 		if (err)
+ 			printk(KERN_WARNING "XENBUS error %d while reading "
+ 			       "message\n", err);
+-	}
++		if (kthread_should_stop())
++			break;
++	}
++
++	return 0;
+ }
+ 
+ int xs_init(void)
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-i386/mach-xen/mach_page.h
+--- a/include/asm-i386/mach-xen/mach_page.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-i386/mach-xen/mach_page.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -41,7 +41,8 @@ static inline unsigned long pfn_to_mfn(u
+ {
+ 	if (xen_feature(XENFEAT_auto_translated_physmap))
+ 		return pfn;
+-	return phys_to_machine_mapping[(unsigned int)(pfn)] & ~FOREIGN_FRAME_BIT;
++	return phys_to_machine_mapping[(unsigned int)(pfn)] &
++		~FOREIGN_FRAME_BIT;
+ }
+ 
+ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-i386/mach-xen/mach_pgtable.h
+--- a/include/asm-i386/mach-xen/mach_pgtable.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-i386/mach-xen/mach_pgtable.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -27,8 +27,8 @@ extern pgd_t *swapper_pg_dir;
+ #define pfn_pte_ma(pfn, prot)	__pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+ #else
+ #define PTRS_PER_PGD_NO_HV PTRS_PER_PGD
+-#define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
+-		        (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
++#define pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) |\
++		       (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)))
+ static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
+ {
+ 	pte_t pte;
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-i386/mach-xen/mach_system.h
+--- a/include/asm-i386/mach-xen/mach_system.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-i386/mach-xen/mach_system.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -93,7 +93,7 @@ do {									\
+ 	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
+ 	_vcpu->evtchn_upcall_mask = 0;					\
+ 	barrier(); /* unmask then check (avoid races) */		\
+-	if ( unlikely(_vcpu->evtchn_upcall_pending) )			\
++	if (unlikely(_vcpu->evtchn_upcall_pending))			\
+ 		force_evtchn_callback();				\
+ 	preempt_enable();						\
+ } while (0)
+@@ -115,7 +115,7 @@ do {									\
+ 	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
+ 	if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {			\
+ 		barrier(); /* unmask then check (avoid races) */	\
+-		if ( unlikely(_vcpu->evtchn_upcall_pending) )		\
++		if (unlikely(_vcpu->evtchn_upcall_pending))		\
+ 			force_evtchn_callback();			\
+ 		preempt_enable();					\
+ 	} else								\
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-i386/mach-xen/setup_arch_post.h
+--- a/include/asm-i386/mach-xen/setup_arch_post.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-i386/mach-xen/setup_arch_post.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -16,7 +16,7 @@ static char * __init machine_specific_me
+ 	return "Xen";
+ }
+ 
+-void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
++void __devinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
+ {
+ 	clear_bit(X86_FEATURE_VME, c->x86_capability);
+ 	clear_bit(X86_FEATURE_DE, c->x86_capability);
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/gcc_intrin.h
+--- a/include/asm-ia64/gcc_intrin.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-ia64/gcc_intrin.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -26,7 +26,7 @@ extern void ia64_bad_param_for_getreg (v
+ 
+ register unsigned long ia64_r13 asm ("r13") __attribute_used__;
+ 
+-#define ia64_setreg(regnum, val)						\
++#define __ia64_setreg(regnum, val)						\
+ ({										\
+ 	switch (regnum) {							\
+ 	    case _IA64_REG_PSR_L:						\
+@@ -55,7 +55,7 @@ register unsigned long ia64_r13 asm ("r1
+ 	}									\
+ })
+ 
+-#define ia64_getreg(regnum)							\
++#define __ia64_getreg(regnum)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 										\
+@@ -92,7 +92,7 @@ register unsigned long ia64_r13 asm ("r1
+ 
+ #define ia64_hint_pause 0
+ 
+-#define ia64_hint(mode)						\
++#define __ia64_hint(mode)						\
+ ({								\
+ 	switch (mode) {						\
+ 	case ia64_hint_pause:					\
+@@ -374,7 +374,7 @@ register unsigned long ia64_r13 asm ("r1
+ 
+ #define ia64_invala() asm volatile ("invala" ::: "memory")
+ 
+-#define ia64_thash(addr)							\
++#define __ia64_thash(addr)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 	asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr));	\
+@@ -394,18 +394,18 @@ register unsigned long ia64_r13 asm ("r1
+ 
+ #define ia64_nop(x)	asm volatile ("nop %0"::"i"(x));
+ 
+-#define ia64_itci(addr)	asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
+-
+-#define ia64_itcd(addr)	asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
+-
+-
+-#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1"				\
++#define __ia64_itci(addr)	asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
++
++#define __ia64_itcd(addr)	asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
++
++
++#define __ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1"			\
+ 					     :: "r"(trnum), "r"(addr) : "memory")
+ 
+-#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1"				\
++#define __ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1"			\
+ 					     :: "r"(trnum), "r"(addr) : "memory")
+ 
+-#define ia64_tpa(addr)								\
++#define __ia64_tpa(addr)							\
+ ({										\
+ 	__u64 ia64_pa;								\
+ 	asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory");	\
+@@ -415,22 +415,22 @@ register unsigned long ia64_r13 asm ("r1
+ #define __ia64_set_dbr(index, val)						\
+ 	asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory")
+ 
+-#define ia64_set_ibr(index, val)						\
++#define __ia64_set_ibr(index, val)						\
+ 	asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory")
+ 
+-#define ia64_set_pkr(index, val)						\
++#define __ia64_set_pkr(index, val)						\
+ 	asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory")
+ 
+-#define ia64_set_pmc(index, val)						\
++#define __ia64_set_pmc(index, val)						\
+ 	asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory")
+ 
+-#define ia64_set_pmd(index, val)						\
++#define __ia64_set_pmd(index, val)						\
+ 	asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
+ 
+-#define ia64_set_rr(index, val)							\
++#define __ia64_set_rr(index, val)							\
+ 	asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
+ 
+-#define ia64_get_cpuid(index)								\
++#define __ia64_get_cpuid(index)								\
+ ({											\
+ 	__u64 ia64_intri_res;								\
+ 	asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index));	\
+@@ -444,21 +444,21 @@ register unsigned long ia64_r13 asm ("r1
+ 	ia64_intri_res;								\
+ })
+ 
+-#define ia64_get_ibr(index)							\
++#define __ia64_get_ibr(index)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 	asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index));	\
+ 	ia64_intri_res;								\
+ })
+ 
+-#define ia64_get_pkr(index)							\
++#define __ia64_get_pkr(index)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 	asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index));	\
+ 	ia64_intri_res;								\
+ })
+ 
+-#define ia64_get_pmc(index)							\
++#define __ia64_get_pmc(index)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 	asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index));	\
+@@ -466,48 +466,48 @@ register unsigned long ia64_r13 asm ("r1
+ })
+ 
+ 
+-#define ia64_get_pmd(index)							\
++#define __ia64_get_pmd(index)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 	asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index));	\
+ 	ia64_intri_res;								\
+ })
+ 
+-#define ia64_get_rr(index)							\
++#define __ia64_get_rr(index)							\
+ ({										\
+ 	__u64 ia64_intri_res;							\
+ 	asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index));	\
+ 	ia64_intri_res;								\
+ })
+ 
+-#define ia64_fc(addr)	asm volatile ("fc %0" :: "r"(addr) : "memory")
++#define __ia64_fc(addr)	asm volatile ("fc %0" :: "r"(addr) : "memory")
+ 
+ 
+ #define ia64_sync_i()	asm volatile (";; sync.i" ::: "memory")
+ 
+-#define ia64_ssm(mask)	asm volatile ("ssm %0":: "i"((mask)) : "memory")
+-#define ia64_rsm(mask)	asm volatile ("rsm %0":: "i"((mask)) : "memory")
++#define __ia64_ssm(mask)	asm volatile ("ssm %0":: "i"((mask)) : "memory")
++#define __ia64_rsm(mask)	asm volatile ("rsm %0":: "i"((mask)) : "memory")
+ #define ia64_sum(mask)	asm volatile ("sum %0":: "i"((mask)) : "memory")
+ #define ia64_rum(mask)	asm volatile ("rum %0":: "i"((mask)) : "memory")
+ 
+-#define ia64_ptce(addr)	asm volatile ("ptc.e %0" :: "r"(addr))
+-
+-#define ia64_ptcga(addr, size)							\
++#define __ia64_ptce(addr)	asm volatile ("ptc.e %0" :: "r"(addr))
++
++#define __ia64_ptcga(addr, size)							\
+ do {										\
+ 	asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory");	\
+ 	ia64_dv_serialize_data();						\
+ } while (0)
+ 
+-#define ia64_ptcl(addr, size)							\
++#define __ia64_ptcl(addr, size)							\
+ do {										\
+ 	asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory");	\
+ 	ia64_dv_serialize_data();						\
+ } while (0)
+ 
+-#define ia64_ptri(addr, size)						\
++#define __ia64_ptri(addr, size)						\
+ 	asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory")
+ 
+-#define ia64_ptrd(addr, size)						\
++#define __ia64_ptrd(addr, size)						\
+ 	asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory")
+ 
+ /* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */
+@@ -589,7 +589,7 @@ do {										\
+         }								\
+ })
+ 
+-#define ia64_intrin_local_irq_restore(x)			\
++#define __ia64_intrin_local_irq_restore(x)			\
+ do {								\
+ 	asm volatile (";;   cmp.ne p6,p7=%0,r0;;"		\
+ 		      "(p6) ssm psr.i;"				\
+@@ -598,4 +598,6 @@ do {								\
+ 		      :: "r"((x)) : "p6", "p7", "memory");	\
+ } while (0)
+ 
++#define __ia64_get_psr_i()	(__ia64_getreg(_IA64_REG_PSR) & 0x4000UL)
++
+ #endif /* _ASM_IA64_GCC_INTRIN_H */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/intel_intrin.h
+--- a/include/asm-ia64/intel_intrin.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-ia64/intel_intrin.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -119,10 +119,10 @@ __s64 _m64_popcnt(__s64 a);
+ 		 	 * intrinsic
+ 		 	 */
+ 
+-#define ia64_getreg		__getReg
+-#define ia64_setreg		__setReg
+-
+-#define ia64_hint(x)
++#define __ia64_getreg		__getReg
++#define __ia64_setreg		__setReg
++
++#define __ia64_hint(x)
+ 
+ #define ia64_mux1_brcst	 0
+ #define ia64_mux1_mix		 8
+@@ -135,16 +135,16 @@ __s64 _m64_popcnt(__s64 a);
+ #define ia64_getf_exp		__getf_exp
+ #define ia64_shrp		_m64_shrp
+ 
+-#define ia64_tpa		__tpa
++#define __ia64_tpa		__tpa
+ #define ia64_invala		__invala
+ #define ia64_invala_gr		__invala_gr
+ #define ia64_invala_fr		__invala_fr
+ #define ia64_nop		__nop
+ #define ia64_sum		__sum
+-#define ia64_ssm		__ssm
++#define __ia64_ssm		__ssm
+ #define ia64_rum		__rum
+-#define ia64_rsm		__rsm
+-#define ia64_fc 		__fc
++#define __ia64_rsm		__rsm
++#define __ia64_fc 		__fc
+ 
+ #define ia64_ldfs		__ldfs
+ #define ia64_ldfd		__ldfd
+@@ -182,24 +182,24 @@ __s64 _m64_popcnt(__s64 a);
+ 
+ #define __ia64_set_dbr(index, val)	\
+ 		__setIndReg(_IA64_REG_INDR_DBR, index, val)
+-#define ia64_set_ibr(index, val)	\
++#define __ia64_set_ibr(index, val)	\
+ 		__setIndReg(_IA64_REG_INDR_IBR, index, val)
+-#define ia64_set_pkr(index, val)	\
++#define __ia64_set_pkr(index, val)	\
+ 		__setIndReg(_IA64_REG_INDR_PKR, index, val)
+-#define ia64_set_pmc(index, val)	\
++#define __ia64_set_pmc(index, val)	\
+ 		__setIndReg(_IA64_REG_INDR_PMC, index, val)
+-#define ia64_set_pmd(index, val)	\
++#define __ia64_set_pmd(index, val)	\
+ 		__setIndReg(_IA64_REG_INDR_PMD, index, val)
+-#define ia64_set_rr(index, val)	\
++#define __ia64_set_rr(index, val)	\
+ 		__setIndReg(_IA64_REG_INDR_RR, index, val)
+ 
+-#define ia64_get_cpuid(index) 	__getIndReg(_IA64_REG_INDR_CPUID, index)
++#define __ia64_get_cpuid(index) 	__getIndReg(_IA64_REG_INDR_CPUID, index)
+ #define __ia64_get_dbr(index) 	__getIndReg(_IA64_REG_INDR_DBR, index)
+-#define ia64_get_ibr(index) 	__getIndReg(_IA64_REG_INDR_IBR, index)
+-#define ia64_get_pkr(index) 	__getIndReg(_IA64_REG_INDR_PKR, index)
+-#define ia64_get_pmc(index) 	__getIndReg(_IA64_REG_INDR_PMC, index)
+-#define ia64_get_pmd(index)  	__getIndReg(_IA64_REG_INDR_PMD, index)
+-#define ia64_get_rr(index) 	__getIndReg(_IA64_REG_INDR_RR, index)
++#define __ia64_get_ibr(index) 	__getIndReg(_IA64_REG_INDR_IBR, index)
++#define __ia64_get_pkr(index) 	__getIndReg(_IA64_REG_INDR_PKR, index)
++#define __ia64_get_pmc(index) 	__getIndReg(_IA64_REG_INDR_PMC, index)
++#define __ia64_get_pmd(index)  	__getIndReg(_IA64_REG_INDR_PMD, index)
++#define __ia64_get_rr(index) 	__getIndReg(_IA64_REG_INDR_RR, index)
+ 
+ #define ia64_srlz_d		__dsrlz
+ #define ia64_srlz_i		__isrlz
+@@ -218,18 +218,18 @@ __s64 _m64_popcnt(__s64 a);
+ #define ia64_ld8_acq		__ld8_acq
+ 
+ #define ia64_sync_i		__synci
+-#define ia64_thash		__thash
+-#define ia64_ttag		__ttag
+-#define ia64_itcd		__itcd
+-#define ia64_itci		__itci
+-#define ia64_itrd		__itrd
+-#define ia64_itri		__itri
+-#define ia64_ptce		__ptce
+-#define ia64_ptcl		__ptcl
+-#define ia64_ptcg		__ptcg
+-#define ia64_ptcga		__ptcga
+-#define ia64_ptri		__ptri
+-#define ia64_ptrd		__ptrd
++#define __ia64_thash		__thash
++#define __ia64_ttag		__ttag
++#define __ia64_itcd		__itcd
++#define __ia64_itci		__itci
++#define __ia64_itrd		__itrd
++#define __ia64_itri		__itri
++#define __ia64_ptce		__ptce
++#define __ia64_ptcl		__ptcl
++#define __ia64_ptcg		__ptcg
++#define __ia64_ptcga		__ptcga
++#define __ia64_ptri		__ptri
++#define __ia64_ptrd		__ptrd
+ #define ia64_dep_mi		_m64_dep_mi
+ 
+ /* Values for lfhint in __lfetch and __lfetch_fault */
+@@ -244,14 +244,16 @@ __s64 _m64_popcnt(__s64 a);
+ #define ia64_lfetch_fault	__lfetch_fault
+ #define ia64_lfetch_fault_excl	__lfetch_fault_excl
+ 
+-#define ia64_intrin_local_irq_restore(x)		\
++#define __ia64_intrin_local_irq_restore(x)		\
+ do {							\
+ 	if ((x) != 0) {					\
+-		ia64_ssm(IA64_PSR_I);			\
++		__ia64_ssm(IA64_PSR_I);			\
+ 		ia64_srlz_d();				\
+ 	} else {					\
+-		ia64_rsm(IA64_PSR_I);			\
++		__ia64_rsm(IA64_PSR_I);			\
+ 	}						\
+ } while (0)
+ 
++#define __ia64_get_psr_i()	(__ia64_getreg(_IA64_REG_PSR) & 0x4000UL)
++
+ #endif /* _ASM_IA64_INTEL_INTRIN_H */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/meminit.h
+--- a/include/asm-ia64/meminit.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-ia64/meminit.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -17,10 +17,15 @@
+  * 	- command line string
+  * 	- kernel code & data
+  * 	- Kernel memory map built from EFI memory map
++ *	- xen start info
+  *
+  * More could be added if necessary
+  */
++#ifndef CONFIG_XEN
+ #define IA64_MAX_RSVD_REGIONS 6
++#else
++#define IA64_MAX_RSVD_REGIONS 7
++#endif
+ 
+ struct rsvd_region {
+ 	unsigned long start;	/* virtual address of beginning of element */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/pal.h
+--- a/include/asm-ia64/pal.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-ia64/pal.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -81,6 +81,7 @@
+ #ifndef __ASSEMBLY__
+ 
+ #include <linux/types.h>
++#include <asm/processor.h>
+ #include <asm/fpu.h>
+ 
+ /*
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/processor.h
+--- a/include/asm-ia64/processor.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-ia64/processor.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -19,6 +19,7 @@
+ #include <asm/kregs.h>
+ #include <asm/ptrace.h>
+ #include <asm/ustack.h>
++#include <asm/privop.h>
+ 
+ #define IA64_NUM_DBG_REGS	8
+ /*
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/system.h
+--- a/include/asm-ia64/system.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-ia64/system.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -125,7 +125,7 @@ extern struct ia64_boot_param {
+ #define __local_irq_save(x)			\
+ do {						\
+ 	ia64_stop();				\
+-	(x) = ia64_getreg(_IA64_REG_PSR);	\
++	(x) = ia64_get_psr_i();			\
+ 	ia64_stop();				\
+ 	ia64_rsm(IA64_PSR_I);			\
+ } while (0)
+@@ -173,7 +173,7 @@ do {								\
+ #endif /* !CONFIG_IA64_DEBUG_IRQ */
+ 
+ #define local_irq_enable()	({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
+-#define local_save_flags(flags)	({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
++#define local_save_flags(flags)	({ ia64_stop(); (flags) = ia64_get_psr_i(); })
+ 
+ #define irqs_disabled()				\
+ ({						\
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-x86_64/page.h
+--- a/include/asm-x86_64/page.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-x86_64/page.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -94,7 +94,8 @@ static inline unsigned long pfn_to_mfn(u
+ {
+ 	if (xen_feature(XENFEAT_auto_translated_physmap))
+ 		return pfn;
+-	return phys_to_machine_mapping[(unsigned int)(pfn)] & ~FOREIGN_FRAME_BIT;
++	return phys_to_machine_mapping[(unsigned int)(pfn)] &
++		~FOREIGN_FRAME_BIT;
+ }
+ 
+ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-x86_64/processor.h
+--- a/include/asm-x86_64/processor.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/asm-x86_64/processor.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -520,4 +520,17 @@ extern int bootloader_type;
+ 
+ #define HAVE_ARCH_PICK_MMAP_LAYOUT 1
+ 
++static inline void modify_cpu_capabilities(struct cpuinfo_x86 *c)
++{
++#ifdef CONFIG_XEN
++	clear_bit(X86_FEATURE_VME, c->x86_capability);
++	clear_bit(X86_FEATURE_DE, c->x86_capability);
++	clear_bit(X86_FEATURE_PSE, c->x86_capability);
++	clear_bit(X86_FEATURE_PGE, c->x86_capability);
++	clear_bit(X86_FEATURE_SEP, c->x86_capability);
++	if (!(xen_start_info->flags & SIF_PRIVILEGED))
++		clear_bit(X86_FEATURE_MTRR, c->x86_capability);
++#endif
++}
++
+ #endif /* __ASM_X86_64_PROCESSOR_H */
+diff -r c75ede70c907 -r f6bd46559b93 include/linux/mm.h
+--- a/include/linux/mm.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/linux/mm.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -1020,9 +1020,9 @@ struct page *follow_page(struct vm_area_
+ #define FOLL_ANON	0x08	/* give ZERO_PAGE if no pgtable */
+ 
+ #ifdef CONFIG_XEN
+-typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr, 
++typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
+                         void *data);
+-extern int generic_page_range(struct mm_struct *mm, unsigned long address, 
++extern int generic_page_range(struct mm_struct *mm, unsigned long address,
+                               unsigned long size, pte_fn_t fn, void *data);
+ #endif
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/acm.h
+--- a/include/xen/interface/acm.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/acm.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -152,7 +152,7 @@ struct acm_ste_stats_buffer {
+     uint32_t ec_eval_count;
+     uint32_t gt_eval_count;
+     uint32_t ec_denied_count;
+-    uint32_t gt_denied_count; 
++    uint32_t gt_denied_count;
+     uint32_t ec_cachehit_count;
+     uint32_t gt_cachehit_count;
+ };
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/arch-ia64.h
+--- a/include/xen/interface/arch-ia64.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/arch-ia64.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -6,6 +6,28 @@
+ 
+ #ifndef __HYPERVISOR_IF_IA64_H__
+ #define __HYPERVISOR_IF_IA64_H__
++
++#ifdef __XEN__
++#define __DEFINE_GUEST_HANDLE(name, type) \
++    typedef struct { type *p; } __guest_handle_ ## name
++#else
++#define __DEFINE_GUEST_HANDLE(name, type) \
++    typedef type * __guest_handle_ ## name
++#endif
++
++#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
++#define GUEST_HANDLE(name)        __guest_handle_ ## name
++
++#ifndef __ASSEMBLY__
++/* Guest handles for primitive C types. */
++__DEFINE_GUEST_HANDLE(uchar, unsigned char);
++__DEFINE_GUEST_HANDLE(uint,  unsigned int);
++__DEFINE_GUEST_HANDLE(ulong, unsigned long);
++DEFINE_GUEST_HANDLE(char);
++DEFINE_GUEST_HANDLE(int);
++DEFINE_GUEST_HANDLE(long);
++DEFINE_GUEST_HANDLE(void);
++#endif
+ 
+ /* Maximum number of virtual CPUs in multi-processor guests. */
+ /* WARNING: before changing this, check that shared_info fits on a page */
+@@ -263,6 +285,7 @@ typedef struct vcpu_guest_context {
+     arch_vcpu_info_t vcpu;
+     arch_shared_info_t shared;
+ } vcpu_guest_context_t;
++DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
+ 
+ #endif /* !__ASSEMBLY__ */
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/arch-x86_32.h
+--- a/include/xen/interface/arch-x86_32.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/arch-x86_32.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -8,6 +8,28 @@
+ 
+ #ifndef __XEN_PUBLIC_ARCH_X86_32_H__
+ #define __XEN_PUBLIC_ARCH_X86_32_H__
++
++#ifdef __XEN__
++#define __DEFINE_GUEST_HANDLE(name, type) \
++    typedef struct { type *p; } __guest_handle_ ## name
++#else
++#define __DEFINE_GUEST_HANDLE(name, type) \
++    typedef type * __guest_handle_ ## name
++#endif
++
++#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
++#define GUEST_HANDLE(name)        __guest_handle_ ## name
++
++#ifndef __ASSEMBLY__
++/* Guest handles for primitive C types. */
++__DEFINE_GUEST_HANDLE(uchar, unsigned char);
++__DEFINE_GUEST_HANDLE(uint,  unsigned int);
++__DEFINE_GUEST_HANDLE(ulong, unsigned long);
++DEFINE_GUEST_HANDLE(char);
++DEFINE_GUEST_HANDLE(int);
++DEFINE_GUEST_HANDLE(long);
++DEFINE_GUEST_HANDLE(void);
++#endif
+ 
+ /*
+  * SEGMENT DESCRIPTOR TABLES
+@@ -130,11 +152,12 @@ typedef struct vcpu_guest_context {
+     unsigned long failsafe_callback_eip;
+     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
+ } vcpu_guest_context_t;
++DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
+ 
+ typedef struct arch_shared_info {
+     unsigned long max_pfn;                  /* max pfn that appears in table */
+     /* Frame containing list of mfns containing list of mfns containing p2m. */
+-    unsigned long pfn_to_mfn_frame_list_list; 
++    unsigned long pfn_to_mfn_frame_list_list;
+     unsigned long nmi_reason;
+ } arch_shared_info_t;
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/arch-x86_64.h
+--- a/include/xen/interface/arch-x86_64.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/arch-x86_64.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -8,6 +8,28 @@
+ 
+ #ifndef __XEN_PUBLIC_ARCH_X86_64_H__
+ #define __XEN_PUBLIC_ARCH_X86_64_H__
++
++#ifdef __XEN__
++#define __DEFINE_GUEST_HANDLE(name, type) \
++    typedef struct { type *p; } __guest_handle_ ## name
++#else
++#define __DEFINE_GUEST_HANDLE(name, type) \
++    typedef type * __guest_handle_ ## name
++#endif
++
++#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
++#define GUEST_HANDLE(name)        __guest_handle_ ## name
++
++#ifndef __ASSEMBLY__
++/* Guest handles for primitive C types. */
++__DEFINE_GUEST_HANDLE(uchar, unsigned char);
++__DEFINE_GUEST_HANDLE(uint,  unsigned int);
++__DEFINE_GUEST_HANDLE(ulong, unsigned long);
++DEFINE_GUEST_HANDLE(char);
++DEFINE_GUEST_HANDLE(int);
++DEFINE_GUEST_HANDLE(long);
++DEFINE_GUEST_HANDLE(void);
++#endif
+ 
+ /*
+  * SEGMENT DESCRIPTOR TABLES
+@@ -215,11 +237,12 @@ typedef struct vcpu_guest_context {
+     uint64_t      gs_base_kernel;
+     uint64_t      gs_base_user;
+ } vcpu_guest_context_t;
++DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
+ 
+ typedef struct arch_shared_info {
+     unsigned long max_pfn;                  /* max pfn that appears in table */
+     /* Frame containing list of mfns containing list of mfns containing p2m. */
+-    unsigned long pfn_to_mfn_frame_list_list; 
++    unsigned long pfn_to_mfn_frame_list_list;
+     unsigned long nmi_reason;
+ } arch_shared_info_t;
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/dom0_ops.h
+--- a/include/xen/interface/dom0_ops.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/dom0_ops.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -28,18 +28,21 @@ typedef struct dom0_getmemlist {
+     /* IN variables. */
+     domid_t       domain;
+     unsigned long max_pfns;
+-    void         *buffer;
++    GUEST_HANDLE(ulong) buffer;
+     /* OUT variables. */
+     unsigned long num_pfns;
+ } dom0_getmemlist_t;
++DEFINE_GUEST_HANDLE(dom0_getmemlist_t);
+ 
+ #define DOM0_SCHEDCTL          6
+  /* struct sched_ctl_cmd is from sched-ctl.h   */
+ typedef struct sched_ctl_cmd dom0_schedctl_t;
++DEFINE_GUEST_HANDLE(dom0_schedctl_t);
+ 
+ #define DOM0_ADJUSTDOM         7
+ /* struct sched_adjdom_cmd is from sched-ctl.h */
+ typedef struct sched_adjdom_cmd dom0_adjustdom_t;
++DEFINE_GUEST_HANDLE(dom0_adjustdom_t);
+ 
+ #define DOM0_CREATEDOMAIN      8
+ typedef struct dom0_createdomain {
+@@ -50,24 +53,28 @@ typedef struct dom0_createdomain {
+     /* Identifier for new domain (auto-allocate if zero is specified). */
+     domid_t domain;
+ } dom0_createdomain_t;
++DEFINE_GUEST_HANDLE(dom0_createdomain_t);
+ 
+ #define DOM0_DESTROYDOMAIN     9
+ typedef struct dom0_destroydomain {
+     /* IN variables. */
+     domid_t domain;
+ } dom0_destroydomain_t;
++DEFINE_GUEST_HANDLE(dom0_destroydomain_t);
+ 
+ #define DOM0_PAUSEDOMAIN      10
+ typedef struct dom0_pausedomain {
+     /* IN parameters. */
+     domid_t domain;
+ } dom0_pausedomain_t;
++DEFINE_GUEST_HANDLE(dom0_pausedomain_t);
+ 
+ #define DOM0_UNPAUSEDOMAIN    11
+ typedef struct dom0_unpausedomain {
+     /* IN parameters. */
+     domid_t domain;
+ } dom0_unpausedomain_t;
++DEFINE_GUEST_HANDLE(dom0_unpausedomain_t);
+ 
+ #define DOM0_GETDOMAININFO    12
+ typedef struct dom0_getdomaininfo {
+@@ -93,6 +100,7 @@ typedef struct dom0_getdomaininfo {
+     uint32_t ssidref;
+     xen_domain_handle_t handle;
+ } dom0_getdomaininfo_t;
++DEFINE_GUEST_HANDLE(dom0_getdomaininfo_t);
+ 
+ #define DOM0_SETVCPUCONTEXT   13
+ typedef struct dom0_setvcpucontext {
+@@ -100,8 +108,9 @@ typedef struct dom0_setvcpucontext {
+     domid_t               domain;
+     uint32_t              vcpu;
+     /* IN/OUT parameters */
+-    vcpu_guest_context_t *ctxt;
++    GUEST_HANDLE(vcpu_guest_context_t) ctxt;
+ } dom0_setvcpucontext_t;
++DEFINE_GUEST_HANDLE(dom0_setvcpucontext_t);
+ 
+ #define DOM0_MSR              15
+ typedef struct dom0_msr {
+@@ -115,6 +124,7 @@ typedef struct dom0_msr {
+     uint32_t out1;
+     uint32_t out2;
+ } dom0_msr_t;
++DEFINE_GUEST_HANDLE(dom0_msr_t);
+ 
+ /*
+  * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
+@@ -127,6 +137,7 @@ typedef struct dom0_settime {
+     uint32_t nsecs;
+     uint64_t system_time;
+ } dom0_settime_t;
++DEFINE_GUEST_HANDLE(dom0_settime_t);
+ 
+ #define DOM0_GETPAGEFRAMEINFO 18
+ #define NOTAB 0         /* normal page */
+@@ -147,6 +158,7 @@ typedef struct dom0_getpageframeinfo {
+     /* Is the page PINNED to a type? */
+     uint32_t type;         /* see above type defs */
+ } dom0_getpageframeinfo_t;
++DEFINE_GUEST_HANDLE(dom0_getpageframeinfo_t);
+ 
+ /*
+  * Read console content from Xen buffer ring.
+@@ -154,13 +166,14 @@ typedef struct dom0_getpageframeinfo {
+ #define DOM0_READCONSOLE      19
+ typedef struct dom0_readconsole {
+     /* IN variables. */
+-    uint32_t clear;        /* Non-zero -> clear after reading. */
++    uint32_t clear;            /* Non-zero -> clear after reading. */
+     /* IN/OUT variables. */
+-    char    *buffer;       /* In: Buffer start; Out: Used buffer start */
+-    uint32_t count;        /* In: Buffer size;  Out: Used buffer size  */
++    GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
++    uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
+ } dom0_readconsole_t;
+-
+-/* 
++DEFINE_GUEST_HANDLE(dom0_readconsole_t);
++
++/*
+  * Set which physical cpus a vcpu can execute on.
+  */
+ #define DOM0_SETVCPUAFFINITY  20
+@@ -170,6 +183,7 @@ typedef struct dom0_setvcpuaffinity {
+     uint32_t  vcpu;
+     cpumap_t  cpumap;
+ } dom0_setvcpuaffinity_t;
++DEFINE_GUEST_HANDLE(dom0_setvcpuaffinity_t);
+ 
+ /* Get trace buffers machine base address */
+ #define DOM0_TBUFCONTROL       21
+@@ -189,6 +203,7 @@ typedef struct dom0_tbufcontrol {
+     unsigned long buffer_mfn;
+     uint32_t size;
+ } dom0_tbufcontrol_t;
++DEFINE_GUEST_HANDLE(dom0_tbufcontrol_t);
+ 
+ /*
+  * Get physical information about the host machine
+@@ -204,6 +219,7 @@ typedef struct dom0_physinfo {
+     unsigned long free_pages;
+     uint32_t hw_cap[8];
+ } dom0_physinfo_t;
++DEFINE_GUEST_HANDLE(dom0_physinfo_t);
+ 
+ /*
+  * Get the ID of the current scheduler.
+@@ -213,8 +229,9 @@ typedef struct dom0_sched_id {
+     /* OUT variable */
+     uint32_t sched_id;
+ } dom0_sched_id_t;
+-
+-/* 
++DEFINE_GUEST_HANDLE(dom0_sched_id_t);
++
++/*
+  * Control shadow pagetables operation
+  */
+ #define DOM0_SHADOW_CONTROL  25
+@@ -231,20 +248,22 @@ typedef struct dom0_shadow_control_stats
+ typedef struct dom0_shadow_control_stats {
+     uint32_t fault_count;
+     uint32_t dirty_count;
+-    uint32_t dirty_net_count;     
+-    uint32_t dirty_block_count;     
++    uint32_t dirty_net_count;
++    uint32_t dirty_block_count;
+ } dom0_shadow_control_stats_t;
++DEFINE_GUEST_HANDLE(dom0_shadow_control_stats_t);
+ 
+ typedef struct dom0_shadow_control {
+     /* IN variables. */
+     domid_t        domain;
+     uint32_t       op;
+-    unsigned long *dirty_bitmap; /* pointer to locked buffer */
++    GUEST_HANDLE(ulong) dirty_bitmap;
+     /* IN/OUT variables. */
+     unsigned long  pages;        /* size of buffer, updated with actual size */
+     /* OUT variables. */
+     dom0_shadow_control_stats_t stats;
+ } dom0_shadow_control_t;
++DEFINE_GUEST_HANDLE(dom0_shadow_control_t);
+ 
+ #define DOM0_SETDOMAINMAXMEM   28
+ typedef struct dom0_setdomainmaxmem {
+@@ -252,6 +271,7 @@ typedef struct dom0_setdomainmaxmem {
+     domid_t       domain;
+     unsigned long max_memkb;
+ } dom0_setdomainmaxmem_t;
++DEFINE_GUEST_HANDLE(dom0_setdomainmaxmem_t);
+ 
+ #define DOM0_GETPAGEFRAMEINFO2 29   /* batched interface */
+ typedef struct dom0_getpageframeinfo2 {
+@@ -259,8 +279,9 @@ typedef struct dom0_getpageframeinfo2 {
+     domid_t        domain;
+     unsigned long  num;
+     /* IN/OUT variables. */
+-    unsigned long *array;
++    GUEST_HANDLE(ulong) array;
+ } dom0_getpageframeinfo2_t;
++DEFINE_GUEST_HANDLE(dom0_getpageframeinfo2_t);
+ 
+ /*
+  * Request memory range (@mfn, @mfn+ at nr_mfns-1) to have type @type.
+@@ -279,6 +300,7 @@ typedef struct dom0_add_memtype {
+     uint32_t      handle;
+     uint32_t      reg;
+ } dom0_add_memtype_t;
++DEFINE_GUEST_HANDLE(dom0_add_memtype_t);
+ 
+ /*
+  * Tear down an existing memory-range type. If @handle is remembered then it
+@@ -293,6 +315,7 @@ typedef struct dom0_del_memtype {
+     uint32_t handle;
+     uint32_t reg;
+ } dom0_del_memtype_t;
++DEFINE_GUEST_HANDLE(dom0_del_memtype_t);
+ 
+ /* Read current type of an MTRR (x86-specific). */
+ #define DOM0_READ_MEMTYPE        33
+@@ -304,6 +327,7 @@ typedef struct dom0_read_memtype {
+     unsigned long nr_mfns;
+     uint32_t type;
+ } dom0_read_memtype_t;
++DEFINE_GUEST_HANDLE(dom0_read_memtype_t);
+ 
+ /* Interface for controlling Xen software performance counters. */
+ #define DOM0_PERFCCONTROL        34
+@@ -315,20 +339,23 @@ typedef struct dom0_perfc_desc {
+     uint32_t     nr_vals;              /* number of values for this counter */
+     uint32_t     vals[64];             /* array of values */
+ } dom0_perfc_desc_t;
++DEFINE_GUEST_HANDLE(dom0_perfc_desc_t);
+ typedef struct dom0_perfccontrol {
+     /* IN variables. */
+     uint32_t       op;                /*  DOM0_PERFCCONTROL_OP_??? */
+     /* OUT variables. */
+     uint32_t       nr_counters;       /*  number of counters */
+-    dom0_perfc_desc_t *desc;          /*  counter information (or NULL) */
++    GUEST_HANDLE(dom0_perfc_desc_t) desc; /*  counter information (or NULL) */
+ } dom0_perfccontrol_t;
++DEFINE_GUEST_HANDLE(dom0_perfccontrol_t);
+ 
+ #define DOM0_MICROCODE           35
+ typedef struct dom0_microcode {
+     /* IN variables. */
+-    void    *data;                    /* Pointer to microcode data */
++    GUEST_HANDLE(void) data;          /* Pointer to microcode data */
+     uint32_t length;                  /* Length of microcode data. */
+ } dom0_microcode_t;
++DEFINE_GUEST_HANDLE(dom0_microcode_t);
+ 
+ #define DOM0_IOPORT_PERMISSION   36
+ typedef struct dom0_ioport_permission {
+@@ -337,6 +364,7 @@ typedef struct dom0_ioport_permission {
+     uint32_t nr_ports;                /* size of port range */
+     uint8_t  allow_access;            /* allow or deny access to range? */
+ } dom0_ioport_permission_t;
++DEFINE_GUEST_HANDLE(dom0_ioport_permission_t);
+ 
+ #define DOM0_GETVCPUCONTEXT      37
+ typedef struct dom0_getvcpucontext {
+@@ -344,8 +372,9 @@ typedef struct dom0_getvcpucontext {
+     domid_t  domain;                  /* domain to be affected */
+     uint32_t vcpu;                    /* vcpu # */
+     /* OUT variables. */
+-    vcpu_guest_context_t *ctxt;
++    GUEST_HANDLE(vcpu_guest_context_t) ctxt;
+ } dom0_getvcpucontext_t;
++DEFINE_GUEST_HANDLE(dom0_getvcpucontext_t);
+ 
+ #define DOM0_GETVCPUINFO         43
+ typedef struct dom0_getvcpuinfo {
+@@ -360,54 +389,63 @@ typedef struct dom0_getvcpuinfo {
+     uint32_t cpu;                     /* current mapping   */
+     cpumap_t cpumap;                  /* allowable mapping */
+ } dom0_getvcpuinfo_t;
++DEFINE_GUEST_HANDLE(dom0_getvcpuinfo_t);
+ 
+ #define DOM0_GETDOMAININFOLIST   38
+ typedef struct dom0_getdomaininfolist {
+     /* IN variables. */
+     domid_t               first_domain;
+     uint32_t              max_domains;
+-    dom0_getdomaininfo_t *buffer;
++    GUEST_HANDLE(dom0_getdomaininfo_t) buffer;
+     /* OUT variables. */
+     uint32_t              num_domains;
+ } dom0_getdomaininfolist_t;
+-
+-#define DOM0_PLATFORM_QUIRK      39  
++DEFINE_GUEST_HANDLE(dom0_getdomaininfolist_t);
++
++#define DOM0_PLATFORM_QUIRK      39
+ #define QUIRK_NOIRQBALANCING  1
+ typedef struct dom0_platform_quirk {
+     /* IN variables. */
+     uint32_t quirk_id;
+ } dom0_platform_quirk_t;
++DEFINE_GUEST_HANDLE(dom0_platform_quirk_t);
+ 
+ #define DOM0_PHYSICAL_MEMORY_MAP 40
++typedef struct dom0_memory_map_entry {
++    uint64_t start, end;
++    uint32_t flags; /* reserved */
++    uint8_t  is_ram;
++} dom0_memory_map_entry_t;
++DEFINE_GUEST_HANDLE(dom0_memory_map_entry_t);
+ typedef struct dom0_physical_memory_map {
+     /* IN variables. */
+     uint32_t max_map_entries;
+     /* OUT variables. */
+     uint32_t nr_map_entries;
+-    struct dom0_memory_map_entry {
+-        uint64_t start, end;
+-        uint32_t flags; /* reserved */
+-        uint8_t  is_ram;
+-    } *memory_map;
++    GUEST_HANDLE(dom0_memory_map_entry_t) memory_map;
+ } dom0_physical_memory_map_t;
++DEFINE_GUEST_HANDLE(dom0_physical_memory_map_t);
+ 
+ #define DOM0_MAX_VCPUS 41
+ typedef struct dom0_max_vcpus {
+     domid_t  domain;        /* domain to be affected */
+     uint32_t max;           /* maximum number of vcpus */
+ } dom0_max_vcpus_t;
++DEFINE_GUEST_HANDLE(dom0_max_vcpus_t);
+ 
+ #define DOM0_SETDOMAINHANDLE 44
+ typedef struct dom0_setdomainhandle {
+     domid_t domain;
+     xen_domain_handle_t handle;
+ } dom0_setdomainhandle_t;
++DEFINE_GUEST_HANDLE(dom0_setdomainhandle_t);
+ 
+ #define DOM0_SETDEBUGGING 45
+ typedef struct dom0_setdebugging {
+     domid_t domain;
+     uint8_t enable;
+ } dom0_setdebugging_t;
++DEFINE_GUEST_HANDLE(dom0_setdebugging_t);
+ 
+ #define DOM0_IRQ_PERMISSION 46
+ typedef struct dom0_irq_permission {
+@@ -415,6 +453,7 @@ typedef struct dom0_irq_permission {
+     uint8_t pirq;
+     uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
+ } dom0_irq_permission_t;
++DEFINE_GUEST_HANDLE(dom0_irq_permission_t);
+ 
+ #define DOM0_IOMEM_PERMISSION 47
+ typedef struct dom0_iomem_permission {
+@@ -423,12 +462,14 @@ typedef struct dom0_iomem_permission {
+     unsigned long nr_mfns;    /* number of pages in range (>0) */
+     uint8_t allow_access;     /* allow (!0) or deny (0) access to range? */
+ } dom0_iomem_permission_t;
++DEFINE_GUEST_HANDLE(dom0_iomem_permission_t);
+ 
+ #define DOM0_HYPERCALL_INIT   48
+ typedef struct dom0_hypercall_init {
+     domid_t  domain;          /* domain to be affected */
+     unsigned long mfn;        /* machine frame to be initialised */
+ } dom0_hypercall_init_t;
++DEFINE_GUEST_HANDLE(dom0_hypercall_init_t);
+ 
+ typedef struct dom0_op {
+     uint32_t cmd;
+@@ -466,14 +507,15 @@ typedef struct dom0_op {
+         struct dom0_platform_quirk    platform_quirk;
+         struct dom0_physical_memory_map physical_memory_map;
+         struct dom0_max_vcpus         max_vcpus;
+-        struct dom0_setdomainhandle   setdomainhandle;        
++        struct dom0_setdomainhandle   setdomainhandle;
+         struct dom0_setdebugging      setdebugging;
+         struct dom0_irq_permission    irq_permission;
+         struct dom0_iomem_permission  iomem_permission;
+         struct dom0_hypercall_init    hypercall_init;
+-        uint8_t                  pad[128];
++        uint8_t                       pad[128];
+     } u;
+ } dom0_op_t;
++DEFINE_GUEST_HANDLE(dom0_op_t);
+ 
+ #endif /* __XEN_PUBLIC_DOM0_OPS_H__ */
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/grant_table.h
+--- a/include/xen/interface/grant_table.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/grant_table.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -262,7 +262,7 @@ typedef struct gnttab_transfer {
+   * GNTMAP_contains_pte subflag:
+   *  0 => This map request contains a host virtual address.
+   *  1 => This map request contains the machine addess of the PTE to update.
+-  */ 
++  */
+ #define _GNTMAP_contains_pte    (4)
+ #define GNTMAP_contains_pte     (1<<_GNTMAP_contains_pte)
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/hvm/ioreq.h
+--- a/include/xen/interface/hvm/ioreq.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/hvm/ioreq.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -71,8 +71,8 @@ typedef struct {
+ typedef struct {
+     ioreq_t         vp_ioreq;
+     /* Event channel port */
+-    unsigned long   vp_eport;   /* VMX vcpu uses this to notify DM */
+-    unsigned long   dm_eport;   /* DM uses this to notify VMX vcpu */
++    unsigned int    vp_eport;   /* VMX vcpu uses this to notify DM */
++    unsigned int    dm_eport;   /* DM uses this to notify VMX vcpu */
+ } vcpu_iodata_t;
+ 
+ typedef struct {
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/hvm/vmx_assist.h
+--- a/include/xen/interface/hvm/vmx_assist.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/hvm/vmx_assist.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -22,13 +22,13 @@ union vmcs_arbytes {
+         unsigned int seg_type : 4,
+             s         : 1,
+             dpl       : 2,
+-            p         : 1, 
++            p         : 1,
+             reserved0 : 4,
+             avl       : 1,
+-            reserved1 : 1,     
++            reserved1 : 1,
+             default_ops_size: 1,
+             g         : 1,
+-            null_bit  : 1, 
++            null_bit  : 1,
+             reserved2 : 15;
+     } fields;
+     unsigned int bytes;
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/io/ring.h
+--- a/include/xen/interface/io/ring.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/io/ring.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -39,7 +39,7 @@ typedef unsigned int RING_IDX;
+  *
+  * These expand out to give you a set of types, as you can see below.
+  * The most important of these are:
+- *  
++ * 
+  *     mytag_sring_t      - The shared ring.
+  *     mytag_front_ring_t - The 'front' half of the ring.
+  *     mytag_back_ring_t  - The 'back' half of the ring.
+@@ -58,7 +58,7 @@ typedef unsigned int RING_IDX;
+  *     mytag_back_ring_t back_ring;
+  *     BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
+  */
+-         
++
+ #define DEFINE_RING_TYPES(__name, __req_t, __rsp_t)                     \
+                                                                         \
+ /* Shared ring entry */                                                 \
+@@ -97,7 +97,7 @@ typedef struct __name##_back_ring __name
+ typedef struct __name##_back_ring __name##_back_ring_t
+ 
+ /*
+- * Macros for manipulating rings.  
++ * Macros for manipulating rings.
+  * 
+  * FRONT_RING_whatever works on the "front end" of a ring: here 
+  * requests are pushed on to the ring and responses taken off it.
+@@ -105,7 +105,7 @@ typedef struct __name##_back_ring __name
+  * BACK_RING_whatever works on the "back end" of a ring: here 
+  * requests are taken off the ring and responses put on.
+  * 
+- * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.  
++ * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL. 
+  * This is OK in 1-for-1 request-response situations where the 
+  * requestor (front end) never has more than RING_SIZE()-1
+  * outstanding requests.
+@@ -151,7 +151,7 @@ typedef struct __name##_back_ring __name
+ #define RING_SIZE(_r)                                                   \
+     ((_r)->nr_ents)
+ 
+-/* Test if there is an empty slot available on the front ring. 
++/* Test if there is an empty slot available on the front ring.
+  * (This is only meaningful from the front. )
+  */
+ #define RING_FULL(_r)                                                   \
+@@ -159,24 +159,19 @@ typedef struct __name##_back_ring __name
+ 
+ /* Test if there are outstanding messages to be processed on a ring. */
+ #define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \
+-   ( (_r)->rsp_cons != (_r)->sring->rsp_prod )
+-   
++    ((_r)->rsp_cons != (_r)->sring->rsp_prod)
++
+ #define RING_HAS_UNCONSUMED_REQUESTS(_r)                                \
+-   ( ((_r)->req_cons != (_r)->sring->req_prod ) &&                      \
+-     (((_r)->req_cons - (_r)->rsp_prod_pvt) !=                          \
+-      RING_SIZE(_r)) )
+-      
++    (((_r)->req_cons != (_r)->sring->req_prod) &&                       \
++     (((_r)->req_cons - (_r)->rsp_prod_pvt) != RING_SIZE(_r)))
++
+ /* Direct access to individual ring elements, by index. */
+ #define RING_GET_REQUEST(_r, _idx)                                      \
+- (&((_r)->sring->ring[                                                  \
+-     ((_idx) & (RING_SIZE(_r) - 1))                                     \
+-     ].req))
++    (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+ 
+ #define RING_GET_RESPONSE(_r, _idx)                                     \
+- (&((_r)->sring->ring[                                                  \
+-     ((_idx) & (RING_SIZE(_r) - 1))                                     \
+-     ].rsp))   
+-    
++    (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
++
+ /* Loop termination condition: Would the specified index overflow the ring? */
+ #define RING_REQUEST_CONS_OVERFLOW(_r, _cons)                           \
+     (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
+@@ -212,7 +207,7 @@ typedef struct __name##_back_ring __name
+  *  The second argument is a boolean return value. True indicates that there
+  *  are pending messages on the ring (i.e., the connection should not be put
+  *  to sleep).
+- *  
++ * 
+  *  These macros will set the req_event/rsp_event field to trigger a
+  *  notification on the very next message that is enqueued. If you want to
+  *  create batches of work (i.e., only receive a notification after several
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/io/tpmif.h
+--- a/include/xen/interface/io/tpmif.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/io/tpmif.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -21,7 +21,7 @@ typedef struct {
+ typedef struct {
+     unsigned long addr;   /* Machine address of packet.   */
+     grant_ref_t ref;      /* grant table access reference */
+-    uint16_t id;          /* Echoed in response message.  */
++    uint16_t unused;
+     uint16_t size;        /* Packet size in bytes.        */
+ } tpmif_tx_request_t;
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/io/xenbus.h
+--- a/include/xen/interface/io/xenbus.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/io/xenbus.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -6,9 +6,8 @@
+  * Copyright (C) 2005 XenSource Ltd.
+  */
+ 
+-#ifndef _XEN_XENBUS_H
+-#define _XEN_XENBUS_H
+-
++#ifndef _XEN_PUBLIC_IO_XENBUS_H
++#define _XEN_PUBLIC_IO_XENBUS_H
+ 
+ /* The state of either end of the Xenbus, i.e. the current communication
+    status of initialisation across the bus.  States here imply nothing about
+@@ -30,8 +29,7 @@ typedef enum
+ 
+ } XenbusState;
+ 
+-
+-#endif /* _XEN_XENBUS_H */
++#endif /* _XEN_PUBLIC_IO_XENBUS_H */
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/memory.h
+--- a/include/xen/interface/memory.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/memory.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -29,7 +29,7 @@ typedef struct xen_memory_reservation {
+      *   OUT: GMFN bases of extents that were allocated
+      *   (NB. This command also updates the mach_to_phys translation table)
+      */
+-    unsigned long *extent_start;
++    GUEST_HANDLE(ulong) extent_start;
+ 
+     /* Number of extents, and size/alignment of each (2^extent_order pages). */
+     unsigned long  nr_extents;
+@@ -50,6 +50,7 @@ typedef struct xen_memory_reservation {
+     domid_t        domid;
+ 
+ } xen_memory_reservation_t;
++DEFINE_GUEST_HANDLE(xen_memory_reservation_t);
+ 
+ /*
+  * Returns the maximum machine frame number of mapped RAM in this system.
+@@ -79,13 +80,13 @@ typedef struct xen_machphys_mfn_list {
+      * machphys table is smaller than max_extents * 2MB.
+      */
+     unsigned int max_extents;
+-    
++
+     /*
+      * Pointer to buffer to fill with list of extent starts. If there are
+      * any large discontiguities in the machine address space, 2MB gaps in
+      * the machphys table will be represented by an MFN base of zero.
+      */
+-    unsigned long *extent_start;
++    GUEST_HANDLE(ulong) extent_start;
+ 
+     /*
+      * Number of extents written to the above array. This will be smaller
+@@ -93,6 +94,7 @@ typedef struct xen_machphys_mfn_list {
+      */
+     unsigned int nr_extents;
+ } xen_machphys_mfn_list_t;
++DEFINE_GUEST_HANDLE(xen_machphys_mfn_list_t);
+ 
+ /*
+  * Returns the base and size of the specified reserved 'RAM hole' in the
+@@ -113,6 +115,7 @@ typedef struct xen_reserved_phys_area {
+     /* Base and size of the specified reserved area. */
+     unsigned long first_gpfn, nr_gpfns;
+ } xen_reserved_phys_area_t;
++DEFINE_GUEST_HANDLE(xen_reserved_phys_area_t);
+ 
+ /*
+  * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
+@@ -127,14 +130,15 @@ typedef struct xen_translate_gpfn_list {
+     unsigned long nr_gpfns;
+ 
+     /* List of GPFNs to translate. */
+-    unsigned long *gpfn_list;
++    GUEST_HANDLE(ulong) gpfn_list;
+ 
+     /*
+      * Output list to contain MFN translations. May be the same as the input
+      * list (in which case each input GPFN is overwritten with the output MFN).
+      */
+-    unsigned long *mfn_list;
++    GUEST_HANDLE(ulong) mfn_list;
+ } xen_translate_gpfn_list_t;
++DEFINE_GUEST_HANDLE(xen_translate_gpfn_list_t);
+ 
+ #endif /* __XEN_PUBLIC_MEMORY_H__ */
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/physdev.h
+--- a/include/xen/interface/physdev.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/physdev.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -33,18 +33,18 @@ typedef struct physdevop_set_iobitmap {
+ 
+ typedef struct physdevop_apic {
+     /* IN */
+-    uint32_t apic;
+-    uint32_t offset;
++    unsigned long apic_physbase;
++    uint32_t reg;
+     /* IN or OUT */
+     uint32_t value;
+-} physdevop_apic_t; 
++} physdevop_apic_t;
+ 
+ typedef struct physdevop_irq {
+     /* IN */
+     uint32_t irq;
+     /* OUT */
+     uint32_t vector;
+-} physdevop_irq_t; 
++} physdevop_irq_t;
+ 
+ typedef struct physdev_op {
+     uint32_t cmd;
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/sched_ctl.h
+--- a/include/xen/interface/sched_ctl.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/sched_ctl.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -34,24 +34,20 @@ struct sched_adjdom_cmd {
+     uint32_t direction;
+     domid_t  domain;
+     union {
+-        struct bvt_adjdom
+-        {
++        struct bvt_adjdom {
+             uint32_t mcu_adv;      /* mcu advance: inverse of weight */
+             uint32_t warpback;     /* warp? */
+             int32_t  warpvalue;    /* warp value */
+             int64_t  warpl;        /* warp limit */
+             int64_t  warpu;        /* unwarp time requirement */
+         } bvt;
+-        
+-        struct sedf_adjdom
+-        {
++        struct sedf_adjdom {
+             uint64_t period;
+             uint64_t slice;
+             uint64_t latency;
+             uint32_t extratime;
+             uint32_t weight;
+         } sedf;
+-
+     } u;
+ };
+ 
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/interface/xen.h
+--- a/include/xen/interface/xen.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/interface/xen.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -380,8 +380,8 @@ typedef struct shared_info {
+  *      a. relocated kernel image
+  *      b. initial ram disk              [mod_start, mod_len]
+  *      c. list of allocated page frames [mfn_list, nr_pages]
+- *      d. bootstrap page tables         [pt_base, CR3 (x86)]
+- *      e. start_info_t structure        [register ESI (x86)]
++ *      d. start_info_t structure        [register ESI (x86)]
++ *      e. bootstrap page tables         [pt_base, CR3 (x86)]
+  *      f. bootstrap stack               [register ESP (x86)]
+  *  5. Bootstrap elements are packed together, but each is 4kB-aligned.
+  *  6. The initial ram disk may be omitted.
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/xenbus.h
+--- a/include/xen/xenbus.h	Mon Feb 27 15:43:34 2006 +0000
++++ b/include/xen/xenbus.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -28,8 +28,8 @@
+  * IN THE SOFTWARE.
+  */
+ 
+-#ifndef _ASM_XEN_XENBUS_H
+-#define _ASM_XEN_XENBUS_H
++#ifndef _XEN_XENBUS_H
++#define _XEN_XENBUS_H
+ 
+ #include <linux/device.h>
+ #include <linux/notifier.h>
+@@ -63,7 +63,7 @@ struct xenbus_device {
+ 	int otherend_id;
+ 	struct xenbus_watch otherend_watch;
+ 	struct device dev;
+-	int has_error;
++	XenbusState state;
+ 	void *data;
+ };
+ 
+@@ -170,7 +170,7 @@ void xenbus_resume(void);
+  * be saved in the store.
+  */
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+-		      struct xenbus_watch *watch, 
++		      struct xenbus_watch *watch,
+ 		      void (*callback)(struct xenbus_watch *,
+ 				       const char **, unsigned int));
+ 
+@@ -185,7 +185,7 @@ int xenbus_watch_path(struct xenbus_devi
+  * saved in the store.
+  */
+ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
+-		       const char *path2, struct xenbus_watch *watch, 
++		       const char *path2, struct xenbus_watch *watch,
+ 		       void (*callback)(struct xenbus_watch *,
+ 					const char **, unsigned int));
+ 
+@@ -216,8 +216,8 @@ int xenbus_grant_ring(struct xenbus_devi
+  * page to that address, and sets *vaddr to that address.
+  * xenbus_map_ring does not allocate the virtual address space (you must do
+  * this yourself!). It only maps in the page to the specified address.
+- * Returns 0 on success, and GNTST_* (see xen/include/public/grant_table.h) or
+- * -ENOMEM on error. If an error is returned, device will switch to
++ * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
++ * or -ENOMEM on error. If an error is returned, device will switch to
+  * XenbusStateClosing and the error message will be saved in XenStore.
+  */
+ int xenbus_map_ring_valloc(struct xenbus_device *dev,
+@@ -231,7 +231,7 @@ int xenbus_map_ring(struct xenbus_device
+  * Use xenbus_unmap_ring_vfree if you mapped in your memory with
+  * xenbus_map_ring_valloc (it will free the virtual address space).
+  * Returns 0 on success and returns GNTST_* on error
+- * (see xen/include/public/grant_table.h).
++ * (see xen/include/interface/grant_table.h).
+  */
+ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr);
+ int xenbus_unmap_ring(struct xenbus_device *dev,
+@@ -285,7 +285,7 @@ void xenbus_dev_fatal(struct xenbus_devi
+ 		      ...);
+ 
+ 
+-#endif /* _ASM_XEN_XENBUS_H */
++#endif /* _XEN_XENBUS_H */
+ 
+ /*
+  * Local variables:
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/Makefile
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,5 @@
++#
++# Makefile for Xen components
++#
++
++obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o xenconsole.o xen_ksyms.o
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/Makefile
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/Makefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,20 @@
++
++obj-y   += util.o
++
++obj-y	+= core/
++obj-y	+= console/
++obj-y	+= evtchn/
++#obj-y	+= balloon/
++obj-y	+= privcmd/
++obj-y	+= blkback/
++#obj-y	+= netback/
++obj-y	+= blkfront/
++obj-y	+= xenbus/
++#obj-y	+= netfront/
++#obj-$(CONFIG_XEN_PRIVILEGED_GUEST)	+= privcmd/
++#obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
++#obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
++#obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
++#obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
++#obj-$(CONFIG_XEN_BLKDEV_TAP)    	+= blktap/
++
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/README
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/README	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,2 @@
++This is a temporary location for source/Makefiles that need to be
++patched/reworked in drivers/xen to work with xenlinux/ia64.
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/coreMakefile
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/coreMakefile	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,24 @@
++#
++# Makefile for the linux kernel.
++#
++
++XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
++
++CPPFLAGS_vmlinux.lds += -U$(XENARCH)
++
++$(obj)/vmlinux.lds.S:
++	@ln -fsn $(srctree)/arch/$(XENARCH)/kernel/vmlinux.lds.S $@
++
++
++obj-y   := gnttab.o
++obj-$(CONFIG_PROC_FS) += xen_proc.o
++
++ifeq ($(ARCH),ia64)
++obj-y   += evtchn_ia64.o
++obj-y   += xenia64_init.o
++else
++extra-y += vmlinux.lds
++obj-y   += reboot.o evtchn.o fixup.o 
++obj-$(CONFIG_SMP)     += smp.o		# setup_profiling_timer def'd in ia64
++obj-$(CONFIG_NET)     += skbuff.o	# until networking is up on ia64
++endif
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/evtchn_ia64.c
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/evtchn_ia64.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,273 @@
++/* NOTE: This file split off from evtchn.c because there was
++   some discussion that the mechanism is sufficiently different.
++   It may be possible to merge it back in the future... djm */
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <asm/hw_irq.h>
++#include <xen/evtchn.h>
++
++#define MAX_EVTCHN 1024
++
++/* Xen will never allocate port zero for any purpose. */
++#define VALID_EVTCHN(_chn) (((_chn) != 0) && ((_chn) < MAX_EVTCHN))
++
++/* Binding types. Hey, only IRQT_VIRQ and IRQT_EVTCHN are supported now
++ * for XEN/IA64 - ktian1
++ */
++enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
++
++/* Constructor for packed IRQ information. */
++#define mk_irq_info(type, index, evtchn)				\
++	(((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
++/* Convenient shorthand for packed representation of an unbound IRQ. */
++#define IRQ_UNBOUND	mk_irq_info(IRQT_UNBOUND, 0, 0)
++/* Accessor macros for packed IRQ information. */
++#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
++#define index_from_irq(irq)  ((u8)(irq_info[irq] >> 16))
++#define type_from_irq(irq)   ((u8)(irq_info[irq] >> 24))
++
++/* Packed IRQ information: binding type, sub-type index, and event channel. */
++static u32 irq_info[NR_IRQS];
++
++/* One note for XEN/IA64 is that we have all event channels bound to one
++ * physical irq vector. So we always mean evtchn vector identical to 'irq'
++ * vector in this context. - ktian1
++ */
++static struct {
++	irqreturn_t (*handler)(int, void *, struct pt_regs *);
++	void *dev_id;
++	char opened;	/* Whether allocated */
++} evtchns[MAX_EVTCHN];
++
++/*
++ * This lock protects updates to the following mapping and reference-count
++ * arrays. The lock does not need to be acquired to read the mapping tables.
++ */
++static spinlock_t irq_mapping_update_lock;
++
++void mask_evtchn(int port)
++{
++	shared_info_t *s = HYPERVISOR_shared_info;
++	synch_set_bit(port, &s->evtchn_mask[0]);
++}
++EXPORT_SYMBOL(mask_evtchn);
++
++void unmask_evtchn(int port)
++{
++	shared_info_t *s = HYPERVISOR_shared_info;
++	unsigned int cpu = smp_processor_id();
++	vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
++
++#if 0	// FIXME: diverged from x86 evtchn.c
++	/* Slow path (hypercall) if this is a non-local port. */
++	if (unlikely(cpu != cpu_from_evtchn(port))) {
++		evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
++				   .u.unmask.port = port };
++		(void)HYPERVISOR_event_channel_op(&op);
++		return;
++	}
++#endif
++
++	synch_clear_bit(port, &s->evtchn_mask[0]);
++
++	/*
++	 * The following is basically the equivalent of 'hw_resend_irq'. Just
++	 * like a real IO-APIC we 'lose the interrupt edge' if the channel is
++	 * masked.
++	 */
++	if (synch_test_bit(port, &s->evtchn_pending[0]) && 
++	    !synch_test_and_set_bit(port / BITS_PER_LONG,
++				    &vcpu_info->evtchn_pending_sel)) {
++		vcpu_info->evtchn_upcall_pending = 1;
++		if (!vcpu_info->evtchn_upcall_mask)
++			force_evtchn_callback();
++	}
++}
++EXPORT_SYMBOL(unmask_evtchn);
++
++
++#define unbound_irq(e) (VALID_EVTCHN(e) && (!evtchns[(e)].opened))
++int bind_virq_to_irqhandler(
++	unsigned int virq,
++	unsigned int cpu,
++	irqreturn_t (*handler)(int, void *, struct pt_regs *),
++	unsigned long irqflags,
++	const char *devname,
++	void *dev_id)
++{
++    evtchn_op_t op;
++    int evtchn;
++
++    spin_lock(&irq_mapping_update_lock);
++
++    op.cmd = EVTCHNOP_bind_virq;
++    op.u.bind_virq.virq = virq;
++    op.u.bind_virq.vcpu = cpu;
++    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0 );
++    evtchn = op.u.bind_virq.port;
++
++    if (!unbound_irq(evtchn)) {
++        evtchn = -EINVAL;
++        goto out;
++    }
++
++    evtchns[evtchn].handler = handler;
++    evtchns[evtchn].dev_id = dev_id;
++    evtchns[evtchn].opened = 1;
++    irq_info[evtchn] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
++
++    unmask_evtchn(evtchn);
++out:
++    spin_unlock(&irq_mapping_update_lock);
++    return evtchn;
++}
++
++int bind_evtchn_to_irqhandler(unsigned int evtchn,
++                   irqreturn_t (*handler)(int, void *, struct pt_regs *),
++                   unsigned long irqflags, const char * devname, void *dev_id)
++{
++    spin_lock(&irq_mapping_update_lock);
++
++    if (!unbound_irq(evtchn)) {
++	evtchn = -EINVAL;
++	goto out;
++    }
++
++    evtchns[evtchn].handler = handler;
++    evtchns[evtchn].dev_id = dev_id;
++    evtchns[evtchn].opened = 1;
++    irq_info[evtchn] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
++
++    unmask_evtchn(evtchn);
++out:
++    spin_unlock(&irq_mapping_update_lock);
++    return evtchn;
++}
++
++int bind_ipi_to_irqhandler(
++	unsigned int ipi,
++	unsigned int cpu,
++	irqreturn_t (*handler)(int, void *, struct pt_regs *),
++	unsigned long irqflags,
++	const char *devname,
++	void *dev_id)
++{
++    printk("%s is called which has not been supported now...?\n", __FUNCTION__);
++    while(1);
++}
++
++void unbind_from_irqhandler(unsigned int irq, void *dev_id)
++{
++    evtchn_op_t op;
++    int evtchn = evtchn_from_irq(irq);
++
++    spin_lock(&irq_mapping_update_lock);
++
++    if (unbound_irq(irq))
++        goto out;
++
++    op.cmd = EVTCHNOP_close;
++    op.u.close.port = evtchn;
++    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
++
++    switch (type_from_irq(irq)) {
++	case IRQT_VIRQ:
++	    /* Add smp stuff later... */
++	    break;
++	case IRQT_IPI:
++	    /* Add smp stuff later... */
++	    break;
++	default:
++	    break;
++    }
++
++    mask_evtchn(evtchn);
++    evtchns[evtchn].handler = NULL;
++    evtchns[evtchn].opened = 0;
++
++out:
++    spin_unlock(&irq_mapping_update_lock);
++}
++
++void notify_remote_via_irq(int irq)
++{
++	int evtchn = evtchn_from_irq(irq);
++
++	if (!unbound_irq(evtchn))
++		notify_remote_via_evtchn(evtchn);
++}
++
++irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++    unsigned long  l1, l2;
++    unsigned int   l1i, l2i, port;
++    irqreturn_t (*handler)(int, void *, struct pt_regs *);
++    shared_info_t *s = HYPERVISOR_shared_info;
++    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
++
++    vcpu_info->evtchn_upcall_mask = 1;
++    vcpu_info->evtchn_upcall_pending = 0;
++
++    /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
++    l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
++    while ( l1 != 0 )
++    {
++        l1i = __ffs(l1);
++        l1 &= ~(1UL << l1i);
++
++        while ( (l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]) != 0 )
++        {
++            l2i = __ffs(l2);
++            l2 &= ~(1UL << l2i);
++
++            port = (l1i * BITS_PER_LONG) + l2i;
++            if ( (handler = evtchns[port].handler) != NULL )
++	    {
++		clear_evtchn(port);
++                handler(port, evtchns[port].dev_id, regs);
++	    }
++            else
++	    {
++                evtchn_device_upcall(port);
++	    }
++        }
++    }
++    vcpu_info->evtchn_upcall_mask = 0;
++    return IRQ_HANDLED;
++}
++
++void force_evtchn_callback(void)
++{
++	//(void)HYPERVISOR_xen_version(0, NULL);
++}
++
++static struct irqaction evtchn_irqaction = {
++	.handler =	evtchn_interrupt,
++	.flags =	SA_INTERRUPT,
++	.name =		"xen-event-channel"
++};
++
++int evtchn_irq = 0xe9;
++void __init evtchn_init(void)
++{
++    shared_info_t *s = HYPERVISOR_shared_info;
++    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
++
++#if 0
++    int ret;
++    irq = assign_irq_vector(AUTO_ASSIGN);
++    ret = request_irq(irq, evtchn_interrupt, 0, "xen-event-channel", NULL);
++    if (ret < 0)
++    {
++	printk("xen-event-channel unable to get irq %d (%d)\n", irq, ret);
++	return;
++    }
++#endif
++    register_percpu_irq(evtchn_irq, &evtchn_irqaction);
++
++    vcpu_info->arch.evtchn_vector = evtchn_irq;
++    printk("xen-event-channel using irq %d\n", evtchn_irq);
++
++    spin_lock_init(&irq_mapping_update_lock);
++    memset(evtchns, 0, sizeof(evtchns));
++}
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/patches/blkback.c.patch
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/patches/blkback.c.patch	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,57 @@
++diff -Naur xen/blkback/blkback.c xen.patched/blkback/blkback.c
++--- xen/blkback/blkback.c	2005-09-23 10:54:50.000000000 -0600
+++++ xen.patched/blkback/blkback.c	2005-09-23 10:57:51.000000000 -0600
++@@ -30,10 +30,16 @@
++ static unsigned long mmap_vstart;
++ #define MMAP_PAGES						\
++ 	(MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
+++#ifdef __ia64__
+++static void *pending_vaddrs[MMAP_PAGES];
+++#define MMAP_VADDR(_idx, _i) \
+++	(unsigned long)(pending_vaddrs[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
+++#else
++ #define MMAP_VADDR(_req,_seg)						\
++ 	(mmap_vstart +							\
++ 	 ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) +	\
++ 	 ((_seg) * PAGE_SIZE))
+++#endif
++ 
++ /*
++  * Each outstanding request that we've passed to the lower device layers has a 
++@@ -377,9 +383,13 @@
++ 			goto bad_descriptor;
++ 		}
++ 
+++#ifdef __ia64__
+++		MMAP_VADDR(pending_idx,i) = gnttab_map_vaddr(map[i]);
+++#else
++ 		phys_to_machine_mapping[__pa(MMAP_VADDR(
++ 			pending_idx, i)) >> PAGE_SHIFT] =
++ 			FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT);
+++#endif
++ 
++ 		pending_handle(pending_idx, i) = map[i].handle;
++ 	}
++@@ -500,9 +510,22 @@
++ 
++ 	blkif_interface_init();
++ 
+++#ifdef __ia64__
+++    {
+++	extern unsigned long alloc_empty_foreign_map_page_range(unsigned long pages);
+++	int i;
+++
+++	mmap_vstart =  alloc_empty_foreign_map_page_range(MMAP_PAGES);
+++	printk("Allocated mmap_vstart: 0x%lx\n", mmap_vstart);
+++	for(i = 0; i < MMAP_PAGES; i++)
+++	    pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
+++	BUG_ON(mmap_vstart == NULL);
+++    }
+++#else
++ 	page = balloon_alloc_empty_page_range(MMAP_PAGES);
++ 	BUG_ON(page == NULL);
++ 	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+++#endif
++ 
++ 	pending_cons = 0;
++ 	pending_prod = MAX_PENDING_REQS;
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/patches/console.c.patch
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/patches/console.c.patch	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,18 @@
++--- xen/console/console.c	2005-11-02 14:13:07.000000000 +0100
+++++ xen.patched/console/console.c	2005-11-02 14:21:20.000000000 +0100
++@@ -768,9 +771,15 @@
++ #endif
++ 
++ 	if (xen_start_info->flags & SIF_INITDOMAIN) {
+++#ifdef __ia64__
+++		xencons_priv_irq = bind_virq_to_evtchn(VIRQ_CONSOLE);
+++		bind_evtchn_to_irqhandler(xencons_priv_irq,
+++				xencons_priv_interrupt, 0, "console", NULL);
+++#else
++ 		xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
++ 		(void)request_irq(xencons_priv_irq,
++ 				  xencons_priv_interrupt, 0, "console", NULL);
+++#endif
++ 	} else {
++ 		xencons_ring_register_receiver(xencons_rx);
++ 	}
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/patches/devmem.c.patch
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/patches/devmem.c.patch	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,3 @@
++diff -Naur xen/core/devmem.c xen.patched/core/devmem.c
++--- xen/core/devmem.c	2005-09-23 10:54:50.000000000 -0600
+++++ xen.patched/core/devmem.c	2005-09-23 10:57:51.000000000 -0600
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/patches/gnttab.c.patch
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/patches/gnttab.c.patch	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,46 @@
++diff -Naur xen/core/gnttab.c xen.patched/core/gnttab.c
++--- xen/core/gnttab.c	2005-09-23 10:54:50.000000000 -0600
+++++ xen.patched/core/gnttab.c	2005-09-23 10:57:51.000000000 -0600
++@@ -346,6 +350,10 @@
++ 	if ( hypercall.op != __HYPERVISOR_grant_table_op )
++ 		return -ENOSYS;
++ 
+++
+++#ifdef __ia64__
+++	ret = HYPERVISOR_grant_table_op(hypercall.arg[0], (void *)hypercall.arg[1], hypercall.arg[2]);
+++#else
++ 	/* hypercall-invoking asm taken from privcmd.c */
++ 	__asm__ __volatile__ (
++ 		"pushl %%ebx; pushl %%ecx; pushl %%edx; "
++@@ -359,6 +367,7 @@
++ 		TRAP_INSTR "; "
++ 		"popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
++ 		: "=a" (ret) : "0" (&hypercall) : "memory" );
+++#endif
++ 
++ 	return ret;
++ }
++@@ -423,8 +432,13 @@
++ 	BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
++ 	BUG_ON(setup.status != 0);
++ 
+++#ifdef __ia64__
+++	shared = __va(frames[0] << PAGE_SHIFT);
+++	printk("grant table at %p\n", shared);
+++#else
++ 	for (i = 0; i < NR_GRANT_FRAMES; i++)
++ 		set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
+++#endif
++ 
++ 	return 0;
++ }
++@@ -450,7 +466,9 @@
++ 
++ 	BUG_ON(gnttab_resume());
++ 
+++#ifndef __ia64__
++ 	shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
+++#endif
++ 
++ 	for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
++ 		gnttab_list[i] = i + 1;
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/patches/privcmd.c.patch
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/patches/privcmd.c.patch	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,43 @@
++diff -Naur xen/privcmd/privcmd.c xen.patched/privcmd/privcmd.c
++--- xen/privcmd/privcmd.c	2005-09-23 10:54:50.000000000 -0600
+++++ xen.patched/privcmd/privcmd.c	2005-09-23 10:57:51.000000000 -0600
++@@ -180,6 +183,15 @@
++ 		for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
++ 			if (get_user(mfn, p))
++ 				return -EFAULT;
+++#ifdef __ia64__
+++			ret = remap_pfn_range(vma,
+++					      addr&PAGE_MASK,
+++					      mfn,
+++					      1<<PAGE_SHIFT,
+++					      vma->vm_page_prot);
+++			if (ret < 0)
+++			    goto batch_err;
+++#else
++ 
++ 			ret = create_lookup_pte_addr(vma->vm_mm, addr, &ptep);
++ 			if (ret)
++@@ -190,6 +202,7 @@
++ 
++ 			if (HYPERVISOR_mmu_update(&u, 1, NULL, m.dom) < 0)
++ 				put_user(0xF0000000 | mfn, p);
+++#endif
++ 		}
++ 
++ 		ret = 0;
++@@ -205,6 +218,7 @@
++ 	break;
++ #endif
++ 
+++#ifndef __ia64__
++ 	case IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN: {
++ 		unsigned long m2pv = (unsigned long)machine_to_phys_mapping;
++ 		pgd_t *pgd = pgd_offset_k(m2pv);
++@@ -216,6 +230,7 @@
++ 			-EFAULT: 0;
++ 	}
++ 	break;
+++#endif
++ 
++ 	default:
++ 		ret = -EINVAL;
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/drivers/xenia64_init.c
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/drivers/xenia64_init.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,55 @@
++#ifdef __ia64__
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/efi.h>
++#include <asm/sal.h>
++#include <asm/hypervisor.h>
++/* #include <asm-xen/evtchn.h> */
++#include <linux/vmalloc.h>
++
++shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)0xf100000000000000;
++EXPORT_SYMBOL(HYPERVISOR_shared_info);
++
++static int initialized;
++start_info_t *xen_start_info;
++
++int xen_init(void)
++{
++	shared_info_t *s = HYPERVISOR_shared_info;
++
++	if (initialized)
++		return running_on_xen ? 0 : -1;
++
++	if (!running_on_xen)
++		return -1;
++
++	xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
++	xen_start_info->flags = s->arch.flags;
++	printk("Running on Xen! start_info_pfn=0x%lx nr_pages=%d flags=0x%x\n",
++		s->arch.start_info_pfn, xen_start_info->nr_pages,
++		xen_start_info->flags);
++
++	evtchn_init();
++	initialized = 1;
++	return 0;
++}
++
++/* We just need a range of legal va here, though finally identity
++ * mapped one is instead used for gnttab mapping.
++ */
++unsigned long alloc_empty_foreign_map_page_range(unsigned long pages)
++{
++	struct vm_struct *vma;
++
++	if ( (vma = get_vm_area(PAGE_SIZE * pages, VM_ALLOC)) == NULL )
++		return NULL;
++
++	return (unsigned long)vma->addr;
++}
++
++#if 0
++/* These should be define'd but some drivers use them without
++ * a convenient arch include */
++unsigned long mfn_to_pfn(unsigned long mfn) { return mfn; }
++#endif
++#endif
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/hypercall.S
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/hypercall.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,323 @@
++/*
++ * Support routines for Xen hypercalls
++ *
++ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer at hp.com>
++ */
++
++#include <linux/config.h>
++#include <asm/processor.h>
++#include <asm/asmmacro.h>
++
++GLOBAL_ENTRY(xen_get_ivr)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov r8=cr.ivr;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_GET_IVR
++	;;
++	st8 [r9]=r10
++	br.ret.sptk.many rp
++	;;
++END(xen_get_ivr)
++
++GLOBAL_ENTRY(xen_get_tpr)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov r8=cr.tpr;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_GET_TPR
++	;;
++	st8 [r9]=r10
++	br.ret.sptk.many rp
++	;;
++END(xen_get_tpr)
++
++GLOBAL_ENTRY(xen_set_tpr)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov cr.tpr=r32;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	mov r8=r32
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_SET_TPR
++	;;
++	st8 [r9]=r10
++	br.ret.sptk.many rp
++	;;
++END(xen_set_tpr)
++
++GLOBAL_ENTRY(xen_eoi)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov cr.eoi=r0;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	mov r8=r32
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_EOI
++	;;
++	st8 [r9]=r10
++	br.ret.sptk.many rp
++	;;
++END(xen_eoi)
++
++GLOBAL_ENTRY(xen_thash)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	thash r8=r32;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	mov r8=r32
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_THASH
++	;;
++	st8 [r9]=r10
++	;;
++	br.ret.sptk.many rp
++	;;
++END(xen_thash)
++
++GLOBAL_ENTRY(xen_set_itm)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov cr.itm=r32;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	mov r8=r32
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_SET_ITM
++	;;
++	st8 [r9]=r10
++	;;
++	br.ret.sptk.many rp
++	;;
++END(xen_set_itm)
++
++GLOBAL_ENTRY(xen_ptcga)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	ptc.ga r32,r33;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r11=XSI_PSR_IC
++	mov r8=r32
++	mov r9=r33
++	;;
++	ld8 r10=[r11]
++	;;
++	st8 [r11]=r0
++	;;
++	XEN_HYPER_PTC_GA
++	;;
++	st8 [r11]=r10
++	;;
++	br.ret.sptk.many rp
++	;;
++END(xen_ptcga)
++
++GLOBAL_ENTRY(xen_get_rr)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov r8=rr[r32];;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r9=XSI_PSR_IC
++	mov r8=r32
++	;;
++	ld8 r10=[r9]
++	;;
++	st8 [r9]=r0
++	;;
++	XEN_HYPER_GET_RR
++	;;
++	st8 [r9]=r10
++	;;
++	br.ret.sptk.many rp
++	;;
++END(xen_get_rr)
++
++GLOBAL_ENTRY(xen_set_rr)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov rr[r32]=r33;;
++(p7)	br.ret.sptk.many rp
++	;;
++	movl r11=XSI_PSR_IC
++	mov r8=r32
++	mov r9=r33
++	;;
++	ld8 r10=[r11]
++	;;
++	st8 [r11]=r0
++	;;
++	XEN_HYPER_SET_RR
++	;;
++	st8 [r11]=r10
++	;;
++	br.ret.sptk.many rp
++	;;
++END(xen_set_rr)
++
++GLOBAL_ENTRY(xen_set_kr)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.ne p7,p0=r8,r0;;
++(p7)	br.cond.spnt.few 1f;
++	;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar0=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar1=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar2=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar3=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar4=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar5=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar6=r9
++(p7)	br.ret.sptk.many rp;;
++	cmp.eq p7,p0=r8,r0
++	adds r8=-1,r8;;
++(p7)	mov ar7=r9
++(p7)	br.ret.sptk.many rp;;
++
++1:	movl r11=XSI_PSR_IC
++	mov r8=r32
++	mov r9=r33
++	;;
++	ld8 r10=[r11]
++	;;
++	st8 [r11]=r0
++	;;
++	XEN_HYPER_SET_KR
++	;;
++	st8 [r11]=r10
++	;;
++	br.ret.sptk.many rp
++	;;
++END(xen_set_rr)
++
++GLOBAL_ENTRY(xen_fc)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	fc r32;;
++(p7)	br.ret.sptk.many rp
++	;;
++	ptc.e r96		// this is a "privified" fc r32
++	;;
++	br.ret.sptk.many rp
++END(xen_fc)
++
++GLOBAL_ENTRY(xen_get_cpuid)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov r8=cpuid[r32];;
++(p7)	br.ret.sptk.many rp
++	;;
++	mov r72=rr[r32]		// this is a "privified" mov r8=cpuid[r32]
++	;;
++	br.ret.sptk.many rp
++END(xen_get_cpuid)
++
++GLOBAL_ENTRY(xen_get_pmd)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov r8=pmd[r32];;
++(p7)	br.ret.sptk.many rp
++	;;
++	mov r72=pmc[r32] 	// this is a "privified" mov r8=pmd[r32]
++	;;
++	br.ret.sptk.many rp
++END(xen_get_pmd)
++
++#ifdef CONFIG_IA32_SUPPORT
++GLOBAL_ENTRY(xen_get_eflag)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov r8=ar24;;
++(p7)	br.ret.sptk.many rp
++	;;
++	mov ar24=r72		// this is a "privified" mov r8=ar.eflg
++	;;
++	br.ret.sptk.many rp
++END(xen_get_eflag)
++// some bits aren't set if pl!=0, see SDM vol1 3.1.8
++GLOBAL_ENTRY(xen_set_eflag)
++	movl r8=running_on_xen;;
++	ld4 r8=[r8];;
++	cmp.eq p7,p0=r8,r0;;
++(p7)	mov ar24=r32
++(p7)	br.ret.sptk.many rp
++	;;
++	// FIXME: this remains no-op'd because it generates
++	// a privileged register (general exception) trap rather than
++	// a privileged operation fault
++	//mov ar24=r32
++	;;
++	br.ret.sptk.many rp
++END(xen_get_eflag)
++#endif
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xen_ksyms.c
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xen_ksyms.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,12 @@
++/*
++ * Architecture-specific kernel symbols
++ *
++ * Don't put any exports here unless it's defined in an assembler file.
++ * All other exports should be put directly after the definition.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++
++extern int is_running_on_xen(void);
++EXPORT_SYMBOL(is_running_on_xen);
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xenconsole.c
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xenconsole.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,19 @@
++#include <linux/config.h>
++#include <linux/console.h>
++
++int
++early_xen_console_setup (char *cmdline)
++{
++#ifdef CONFIG_XEN
++#ifndef CONFIG_IA64_HP_SIM
++	extern int running_on_xen;
++	if (running_on_xen) {
++		extern struct console hpsim_cons;
++		hpsim_cons.flags |= CON_BOOT;
++		register_console(&hpsim_cons);
++		return 0;
++	}
++#endif
++#endif
++	return -1;
++}
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xenentry.S
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xenentry.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,850 @@
++/*
++ * ia64/xen/entry.S
++ *
++ * Alternate kernel routines for Xen.  Heavily leveraged from
++ *   ia64/kernel/entry.S
++ *
++ * Copyright (C) 2005 Hewlett-Packard Co
++ *	Dan Magenheimer <dan.magenheimer at .hp.com>
++ */
++
++#include <linux/config.h>
++
++#include <asm/asmmacro.h>
++#include <asm/cache.h>
++#include <asm/errno.h>
++#include <asm/kregs.h>
++#include <asm/asm-offsets.h>
++#include <asm/pgtable.h>
++#include <asm/percpu.h>
++#include <asm/processor.h>
++#include <asm/thread_info.h>
++#include <asm/unistd.h>
++
++#ifdef CONFIG_XEN
++#include "xenminstate.h"
++#else
++#include "minstate.h"
++#endif
++
++/*
++ * prev_task <- ia64_switch_to(struct task_struct *next)
++ *	With Ingo's new scheduler, interrupts are disabled when this routine gets
++ *	called.  The code starting at .map relies on this.  The rest of the code
++ *	doesn't care about the interrupt masking status.
++ */
++#ifdef CONFIG_XEN
++GLOBAL_ENTRY(xen_switch_to)
++	.prologue
++	alloc r16=ar.pfs,1,0,0,0
++	movl r22=running_on_xen;;
++	ld4 r22=[r22];;
++	cmp.eq p7,p0=r22,r0
++(p7)	br.cond.sptk.many __ia64_switch_to;;
++#else
++GLOBAL_ENTRY(ia64_switch_to)
++	.prologue
++	alloc r16=ar.pfs,1,0,0,0
++#endif
++	DO_SAVE_SWITCH_STACK
++	.body
++
++	adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
++	movl r25=init_task
++	mov r27=IA64_KR(CURRENT_STACK)
++	adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
++	dep r20=0,in0,61,3		// physical address of "next"
++	;;
++	st8 [r22]=sp			// save kernel stack pointer of old task
++	shr.u r26=r20,IA64_GRANULE_SHIFT
++	cmp.eq p7,p6=r25,in0
++	;;
++#ifdef CONFIG_XEN
++	movl r8=XSI_PSR_IC
++	;;
++	st4 [r8]=r0	// force psr.ic off for hyperprivop(s)
++	;;
++#endif
++	/*
++	 * If we've already mapped this task's page, we can skip doing it again.
++	 */
++(p6)	cmp.eq p7,p6=r26,r27
++(p6)	br.cond.dpnt .map
++	;;
++.done:
++#ifdef CONFIG_XEN
++	// psr.ic already off
++	// update "current" application register
++	mov r8=IA64_KR_CURRENT
++	mov r9=in0;;
++	XEN_HYPER_SET_KR
++	ld8 sp=[r21]			// load kernel stack pointer of new task
++	movl r27=XSI_PSR_IC
++	mov r8=1
++	;;
++	st4 [r27]=r8			// psr.ic back on
++	;;
++#else
++(p6)	ssm psr.ic			// if we had to map, reenable the psr.ic bit FIRST!!!
++	;;
++(p6)	srlz.d
++	ld8 sp=[r21]			// load kernel stack pointer of new task
++	mov IA64_KR(CURRENT)=in0	// update "current" application register
++#endif
++	mov r8=r13			// return pointer to previously running task
++	mov r13=in0			// set "current" pointer
++	;;
++	DO_LOAD_SWITCH_STACK
++
++#ifdef CONFIG_SMP
++	sync.i				// ensure "fc"s done by this CPU are visible on other CPUs
++#endif
++	br.ret.sptk.many rp		// boogie on out in new context
++
++.map:
++#ifdef CONFIG_XEN
++	// psr.ic already off
++#else
++	rsm psr.ic			// interrupts (psr.i) are already disabled here
++#endif
++	movl r25=PAGE_KERNEL
++	;;
++	srlz.d
++	or r23=r25,r20			// construct PA | page properties
++	mov r25=IA64_GRANULE_SHIFT<<2
++	;;
++#ifdef CONFIG_XEN
++	movl r8=XSI_ITIR
++	;;
++	st8 [r8]=r25
++	;;
++	movl r8=XSI_IFA
++	;;
++	st8 [r8]=in0			 // VA of next task...
++	;;
++	mov r25=IA64_TR_CURRENT_STACK
++	// remember last page we mapped...
++	mov r8=IA64_KR_CURRENT_STACK
++	mov r9=r26;;
++	XEN_HYPER_SET_KR;;
++#else
++	mov cr.itir=r25
++	mov cr.ifa=in0			// VA of next task...
++	;;
++	mov r25=IA64_TR_CURRENT_STACK
++	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
++#endif
++	;;
++	itr.d dtr[r25]=r23		// wire in new mapping...
++	br.cond.sptk .done
++#ifdef CONFIG_XEN
++END(xen_switch_to)
++#else
++END(ia64_switch_to)
++#endif
++
++	/*
++	 * Invoke a system call, but do some tracing before and after the call.
++	 * We MUST preserve the current register frame throughout this routine
++	 * because some system calls (such as ia64_execve) directly
++	 * manipulate ar.pfs.
++	 */
++#ifdef CONFIG_XEN
++GLOBAL_ENTRY(xen_trace_syscall)
++	PT_REGS_UNWIND_INFO(0)
++	movl r16=running_on_xen;;
++	ld4 r16=[r16];;
++	cmp.eq p7,p0=r16,r0
++(p7)	br.cond.sptk.many __ia64_trace_syscall;;
++#else
++GLOBAL_ENTRY(ia64_trace_syscall)
++	PT_REGS_UNWIND_INFO(0)
++#endif
++	/*
++	 * We need to preserve the scratch registers f6-f11 in case the system
++	 * call is sigreturn.
++	 */
++	adds r16=PT(F6)+16,sp
++	adds r17=PT(F7)+16,sp
++	;;
++ 	stf.spill [r16]=f6,32
++ 	stf.spill [r17]=f7,32
++	;;
++ 	stf.spill [r16]=f8,32
++ 	stf.spill [r17]=f9,32
++	;;
++ 	stf.spill [r16]=f10
++ 	stf.spill [r17]=f11
++	br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
++	adds r16=PT(F6)+16,sp
++	adds r17=PT(F7)+16,sp
++	;;
++	ldf.fill f6=[r16],32
++	ldf.fill f7=[r17],32
++	;;
++	ldf.fill f8=[r16],32
++	ldf.fill f9=[r17],32
++	;;
++	ldf.fill f10=[r16]
++	ldf.fill f11=[r17]
++	// the syscall number may have changed, so re-load it and re-calculate the
++	// syscall entry-point:
++	adds r15=PT(R15)+16,sp			// r15 = &pt_regs.r15 (syscall #)
++	;;
++	ld8 r15=[r15]
++	mov r3=NR_syscalls - 1
++	;;
++	adds r15=-1024,r15
++	movl r16=sys_call_table
++	;;
++	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
++	cmp.leu p6,p7=r15,r3
++	;;
++(p6)	ld8 r20=[r20]				// load address of syscall entry point
++(p7)	movl r20=sys_ni_syscall
++	;;
++	mov b6=r20
++	br.call.sptk.many rp=b6			// do the syscall
++.strace_check_retval:
++	cmp.lt p6,p0=r8,r0			// syscall failed?
++	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
++	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
++	mov r10=0
++(p6)	br.cond.sptk strace_error		// syscall failed ->
++	;;					// avoid RAW on r10
++.strace_save_retval:
++.mem.offset 0,0; st8.spill [r2]=r8		// store return value in slot for r8
++.mem.offset 8,0; st8.spill [r3]=r10		// clear error indication in slot for r10
++	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
++.ret3:	br.cond.sptk .work_pending_syscall_end
++
++strace_error:
++	ld8 r3=[r2]				// load pt_regs.r8
++	sub r9=0,r8				// negate return value to get errno value
++	;;
++	cmp.ne p6,p0=r3,r0			// is pt_regs.r8!=0?
++	adds r3=16,r2				// r3=&pt_regs.r10
++	;;
++(p6)	mov r10=-1
++(p6)	mov r8=r9
++	br.cond.sptk .strace_save_retval
++#ifdef CONFIG_XEN
++END(xen_trace_syscall)
++#else
++END(ia64_trace_syscall)
++#endif
++
++/*
++ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
++ *	need to switch to bank 0 and doesn't restore the scratch registers.
++ *	To avoid leaking kernel bits, the scratch registers are set to
++ *	the following known-to-be-safe values:
++ *
++ *		  r1: restored (global pointer)
++ *		  r2: cleared
++ *		  r3: 1 (when returning to user-level)
++ *	      r8-r11: restored (syscall return value(s))
++ *		 r12: restored (user-level stack pointer)
++ *		 r13: restored (user-level thread pointer)
++ *		 r14: cleared
++ *		 r15: restored (syscall #)
++ *	     r16-r17: cleared
++ *		 r18: user-level b6
++ *		 r19: cleared
++ *		 r20: user-level ar.fpsr
++ *		 r21: user-level b0
++ *		 r22: cleared
++ *		 r23: user-level ar.bspstore
++ *		 r24: user-level ar.rnat
++ *		 r25: user-level ar.unat
++ *		 r26: user-level ar.pfs
++ *		 r27: user-level ar.rsc
++ *		 r28: user-level ip
++ *		 r29: user-level psr
++ *		 r30: user-level cfm
++ *		 r31: user-level pr
++ *	      f6-f11: cleared
++ *		  pr: restored (user-level pr)
++ *		  b0: restored (user-level rp)
++ *	          b6: restored
++ *		  b7: cleared
++ *	     ar.unat: restored (user-level ar.unat)
++ *	      ar.pfs: restored (user-level ar.pfs)
++ *	      ar.rsc: restored (user-level ar.rsc)
++ *	     ar.rnat: restored (user-level ar.rnat)
++ *	 ar.bspstore: restored (user-level ar.bspstore)
++ *	     ar.fpsr: restored (user-level ar.fpsr)
++ *	      ar.ccv: cleared
++ *	      ar.csd: cleared
++ *	      ar.ssd: cleared
++ */
++#ifdef CONFIG_XEN
++GLOBAL_ENTRY(xen_leave_syscall)
++	PT_REGS_UNWIND_INFO(0)
++	movl r22=running_on_xen;;
++	ld4 r22=[r22];;
++	cmp.eq p7,p0=r22,r0
++(p7)	br.cond.sptk.many __ia64_leave_syscall;;
++#else
++ENTRY(ia64_leave_syscall)
++	PT_REGS_UNWIND_INFO(0)
++#endif
++	/*
++	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
++	 * user- or fsys-mode, hence we disable interrupts early on.
++	 *
++	 * p6 controls whether current_thread_info()->flags needs to be check for
++	 * extra work.  We always check for extra work when returning to user-level.
++	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
++	 * is 0.  After extra work processing has been completed, execution
++	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
++	 * needs to be redone.
++	 */
++#ifdef CONFIG_PREEMPT
++	rsm psr.i				// disable interrupts
++	cmp.eq pLvSys,p0=r0,r0			// pLvSys=1: leave from syscall
++(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
++	;;
++	.pred.rel.mutex pUStk,pKStk
++(pKStk) ld4 r21=[r20]			// r21 <- preempt_count
++(pUStk)	mov r21=0			// r21 <- 0
++	;;
++	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
++#else /* !CONFIG_PREEMPT */
++#ifdef CONFIG_XEN
++	movl r2=XSI_PSR_I
++	;;
++(pUStk)	st4 [r2]=r0
++#else
++(pUStk)	rsm psr.i
++#endif
++	cmp.eq pLvSys,p0=r0,r0		// pLvSys=1: leave from syscall
++(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
++#endif
++.work_processed_syscall:
++	adds r2=PT(LOADRS)+16,r12
++	adds r3=PT(AR_BSPSTORE)+16,r12
++	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
++	;;
++(p6)	ld4 r31=[r18]				// load current_thread_info()->flags
++	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
++	mov b7=r0		// clear b7
++	;;
++	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
++	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
++(p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
++	;;
++	mov r16=ar.bsp				// M2  get existing backing store pointer
++(p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
++(p6)	br.cond.spnt .work_pending_syscall
++	;;
++	// start restoring the state saved on the kernel stack (struct pt_regs):
++	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
++	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
++	mov f6=f0		// clear f6
++	;;
++	invala			// M0|1 invalidate ALAT
++#ifdef CONFIG_XEN
++	movl r29=XSI_PSR_IC
++	;;
++	st8	[r29]=r0	// note: clears both vpsr.i and vpsr.ic!
++	;;
++#else
++	rsm psr.i | psr.ic	// M2 initiate turning off of interrupt and interruption collection
++#endif
++	mov f9=f0		// clear f9
++
++	ld8 r29=[r2],16		// load cr.ipsr
++	ld8 r28=[r3],16			// load cr.iip
++	mov f8=f0		// clear f8
++	;;
++	ld8 r30=[r2],16		// M0|1 load cr.ifs
++	mov.m ar.ssd=r0		// M2 clear ar.ssd
++	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
++	;;
++	ld8 r25=[r3],16		// M0|1 load ar.unat
++	mov.m ar.csd=r0		// M2 clear ar.csd
++	mov r22=r0		// clear r22
++	;;
++	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
++(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
++	mov f10=f0		// clear f10
++	;;
++	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
++	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// load ar.rsc
++	mov f11=f0		// clear f11
++	;;
++	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
++	ld8 r31=[r3],PT(R1)-PT(PR)		// load predicates
++(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
++	;;
++	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// load ar.fpsr
++	ld8.fill r1=[r3],16	// load r1
++(pUStk) mov r17=1
++	;;
++	srlz.d			// M0  ensure interruption collection is off
++	ld8.fill r13=[r3],16
++	mov f7=f0		// clear f7
++	;;
++	ld8.fill r12=[r2]	// restore r12 (sp)
++	ld8.fill r15=[r3]	// restore r15
++	addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
++	;;
++(pUStk)	ld4 r3=[r3]		// r3 = cpu_data->phys_stacked_size_p8
++(pUStk) st1 [r14]=r17
++	mov b6=r18		// I0  restore b6
++	;;
++	mov r14=r0		// clear r14
++	shr.u r18=r19,16	// I0|1 get byte size of existing "dirty" partition
++(pKStk) br.cond.dpnt.many skip_rbs_switch
++
++	mov.m ar.ccv=r0		// clear ar.ccv
++(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
++	br.cond.sptk.many rbs_switch
++#ifdef CONFIG_XEN
++END(xen_leave_syscall)
++#else
++END(ia64_leave_syscall)
++#endif
++
++#ifdef CONFIG_XEN
++GLOBAL_ENTRY(xen_leave_kernel)
++	PT_REGS_UNWIND_INFO(0)
++	movl r22=running_on_xen;;
++	ld4 r22=[r22];;
++	cmp.eq p7,p0=r22,r0
++(p7)	br.cond.sptk.many __ia64_leave_kernel;;
++#else
++GLOBAL_ENTRY(ia64_leave_kernel)
++	PT_REGS_UNWIND_INFO(0)
++#endif
++	/*
++	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
++	 * user- or fsys-mode, hence we disable interrupts early on.
++	 *
++	 * p6 controls whether current_thread_info()->flags needs to be check for
++	 * extra work.  We always check for extra work when returning to user-level.
++	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
++	 * is 0.  After extra work processing has been completed, execution
++	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
++	 * needs to be redone.
++	 */
++#ifdef CONFIG_PREEMPT
++	rsm psr.i				// disable interrupts
++	cmp.eq p0,pLvSys=r0,r0			// pLvSys=0: leave from kernel
++(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
++	;;
++	.pred.rel.mutex pUStk,pKStk
++(pKStk)	ld4 r21=[r20]			// r21 <- preempt_count
++(pUStk)	mov r21=0			// r21 <- 0
++	;;
++	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
++#else
++#ifdef CONFIG_XEN
++(pUStk)	movl r17=XSI_PSR_I
++	;;
++(pUStk)	st4 [r17]=r0
++	;;
++#else
++(pUStk)	rsm psr.i
++#endif
++	cmp.eq p0,pLvSys=r0,r0		// pLvSys=0: leave from kernel
++(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
++#endif
++.work_processed_kernel:
++	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
++	;;
++(p6)	ld4 r31=[r17]				// load current_thread_info()->flags
++	adds r21=PT(PR)+16,r12
++	;;
++
++	lfetch [r21],PT(CR_IPSR)-PT(PR)
++	adds r2=PT(B6)+16,r12
++	adds r3=PT(R16)+16,r12
++	;;
++	lfetch [r21]
++	ld8 r28=[r2],8		// load b6
++	adds r29=PT(R24)+16,r12
++
++	ld8.fill r16=[r3],PT(AR_CSD)-PT(R16)
++	adds r30=PT(AR_CCV)+16,r12
++(p6)	and r19=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
++	;;
++	ld8.fill r24=[r29]
++	ld8 r15=[r30]		// load ar.ccv
++(p6)	cmp4.ne.unc p6,p0=r19, r0		// any special work pending?
++	;;
++	ld8 r29=[r2],16		// load b7
++	ld8 r30=[r3],16		// load ar.csd
++(p6)	br.cond.spnt .work_pending
++	;;
++	ld8 r31=[r2],16		// load ar.ssd
++	ld8.fill r8=[r3],16
++	;;
++	ld8.fill r9=[r2],16
++	ld8.fill r10=[r3],PT(R17)-PT(R10)
++	;;
++	ld8.fill r11=[r2],PT(R18)-PT(R11)
++	ld8.fill r17=[r3],16
++	;;
++	ld8.fill r18=[r2],16
++	ld8.fill r19=[r3],16
++	;;
++	ld8.fill r20=[r2],16
++	ld8.fill r21=[r3],16
++	mov ar.csd=r30
++	mov ar.ssd=r31
++	;;
++#ifdef CONFIG_XEN
++	movl r22=XSI_PSR_IC
++	;;
++	st8 [r22]=r0		// note: clears both vpsr.i and vpsr.ic!
++	;;
++#else
++	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
++#endif
++	invala			// invalidate ALAT
++	;;
++	ld8.fill r22=[r2],24
++	ld8.fill r23=[r3],24
++	mov b6=r28
++	;;
++	ld8.fill r25=[r2],16
++	ld8.fill r26=[r3],16
++	mov b7=r29
++	;;
++	ld8.fill r27=[r2],16
++	ld8.fill r28=[r3],16
++	;;
++	ld8.fill r29=[r2],16
++	ld8.fill r30=[r3],24
++	;;
++	ld8.fill r31=[r2],PT(F9)-PT(R31)
++	adds r3=PT(F10)-PT(F6),r3
++	;;
++	ldf.fill f9=[r2],PT(F6)-PT(F9)
++	ldf.fill f10=[r3],PT(F8)-PT(F10)
++	;;
++	ldf.fill f6=[r2],PT(F7)-PT(F6)
++	;;
++	ldf.fill f7=[r2],PT(F11)-PT(F7)
++	ldf.fill f8=[r3],32
++	;;
++	srlz.i			// ensure interruption collection is off
++	mov ar.ccv=r15
++	;;
++	ldf.fill f11=[r2]
++#ifdef CONFIG_XEN
++	;;
++	// r16-r31 all now hold bank1 values
++	movl r2=XSI_BANK1_R16
++	movl r3=XSI_BANK1_R16+8
++	;;
++	st8.spill [r2]=r16,16
++	st8.spill [r3]=r17,16
++	;;
++	st8.spill [r2]=r18,16
++	st8.spill [r3]=r19,16
++	;;
++	st8.spill [r2]=r20,16
++	st8.spill [r3]=r21,16
++	;;
++	st8.spill [r2]=r22,16
++	st8.spill [r3]=r23,16
++	;;
++	st8.spill [r2]=r24,16
++	st8.spill [r3]=r25,16
++	;;
++	st8.spill [r2]=r26,16
++	st8.spill [r3]=r27,16
++	;;
++	st8.spill [r2]=r28,16
++	st8.spill [r3]=r29,16
++	;;
++	st8.spill [r2]=r30,16
++	st8.spill [r3]=r31,16
++	;;
++	movl r2=XSI_BANKNUM;;
++	st4 [r2]=r0;
++#else
++	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
++#endif
++	;;
++(pUStk)	mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
++	adds r16=PT(CR_IPSR)+16,r12
++	adds r17=PT(CR_IIP)+16,r12
++
++(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
++	nop.i 0
++	nop.i 0
++	;;
++	ld8 r29=[r16],16	// load cr.ipsr
++	ld8 r28=[r17],16	// load cr.iip
++	;;
++	ld8 r30=[r16],16	// load cr.ifs
++	ld8 r25=[r17],16	// load ar.unat
++	;;
++	ld8 r26=[r16],16	// load ar.pfs
++	ld8 r27=[r17],16	// load ar.rsc
++	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
++	;;
++	ld8 r24=[r16],16	// load ar.rnat (may be garbage)
++	ld8 r23=[r17],16	// load ar.bspstore (may be garbage)
++	;;
++	ld8 r31=[r16],16	// load predicates
++	ld8 r21=[r17],16	// load b0
++	;;
++	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
++	ld8.fill r1=[r17],16	// load r1
++	;;
++	ld8.fill r12=[r16],16
++	ld8.fill r13=[r17],16
++(pUStk)	adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
++	;;
++	ld8 r20=[r16],16	// ar.fpsr
++	ld8.fill r15=[r17],16
++	;;
++	ld8.fill r14=[r16],16
++	ld8.fill r2=[r17]
++(pUStk)	mov r17=1
++	;;
++	ld8.fill r3=[r16]
++(pUStk)	st1 [r18]=r17		// restore current->thread.on_ustack
++	shr.u r18=r19,16	// get byte size of existing "dirty" partition
++	;;
++	mov r16=ar.bsp		// get existing backing store pointer
++	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
++	;;
++	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
++(pKStk)	br.cond.dpnt skip_rbs_switch
++
++	/*
++	 * Restore user backing store.
++	 *
++	 * NOTE: alloc, loadrs, and cover can't be predicated.
++	 */
++(pNonSys) br.cond.dpnt dont_preserve_current_frame
++
++rbs_switch:
++#ifdef CONFIG_XEN
++	XEN_HYPER_COVER;
++#else
++	cover				// add current frame into dirty partition and set cr.ifs
++#endif
++	;;
++	mov r19=ar.bsp			// get new backing store pointer
++	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
++	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
++	;;
++	sub r19=r19,r16			// calculate total byte size of dirty partition
++	add r18=64,r18			// don't force in0-in7 into memory...
++	;;
++	shl r19=r19,16			// shift size of dirty partition into loadrs position
++	;;
++dont_preserve_current_frame:
++	/*
++	 * To prevent leaking bits between the kernel and user-space,
++	 * we must clear the stacked registers in the "invalid" partition here.
++	 * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
++	 * 5 registers/cycle on McKinley).
++	 */
++#	define pRecurse	p6
++#	define pReturn	p7
++#ifdef CONFIG_ITANIUM
++#	define Nregs	10
++#else
++#	define Nregs	14
++#endif
++	alloc loc0=ar.pfs,2,Nregs-2,2,0
++	shr.u loc1=r18,9		// RNaTslots <= floor(dirtySize / (64*8))
++	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
++	;;
++	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
++	shladd in0=loc1,3,r17
++	mov in1=0
++	;;
++	TEXT_ALIGN(32)
++rse_clear_invalid:
++#ifdef CONFIG_ITANIUM
++	// cycle 0
++ { .mii
++	alloc loc0=ar.pfs,2,Nregs-2,2,0
++	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
++	add out0=-Nregs*8,in0
++}{ .mfb
++	add out1=1,in1			// increment recursion count
++	nop.f 0
++	nop.b 0				// can't do br.call here because of alloc (WAW on CFM)
++	;;
++}{ .mfi	// cycle 1
++	mov loc1=0
++	nop.f 0
++	mov loc2=0
++}{ .mib
++	mov loc3=0
++	mov loc4=0
++(pRecurse) br.call.sptk.many b0=rse_clear_invalid
++
++}{ .mfi	// cycle 2
++	mov loc5=0
++	nop.f 0
++	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
++}{ .mib
++	mov loc6=0
++	mov loc7=0
++(pReturn) br.ret.sptk.many b0
++}
++#else /* !CONFIG_ITANIUM */
++	alloc loc0=ar.pfs,2,Nregs-2,2,0
++	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
++	add out0=-Nregs*8,in0
++	add out1=1,in1			// increment recursion count
++	mov loc1=0
++	mov loc2=0
++	;;
++	mov loc3=0
++	mov loc4=0
++	mov loc5=0
++	mov loc6=0
++	mov loc7=0
++(pRecurse) br.call.sptk.few b0=rse_clear_invalid
++	;;
++	mov loc8=0
++	mov loc9=0
++	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
++	mov loc10=0
++	mov loc11=0
++(pReturn) br.ret.sptk.many b0
++#endif /* !CONFIG_ITANIUM */
++#	undef pRecurse
++#	undef pReturn
++	;;
++	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
++	;;
++	loadrs
++	;;
++skip_rbs_switch:
++	mov ar.unat=r25		// M2
++(pKStk)	extr.u r22=r22,21,1	// I0 extract current value of psr.pp from r22
++(pLvSys)mov r19=r0		// A  clear r19 for leave_syscall, no-op otherwise
++	;;
++(pUStk)	mov ar.bspstore=r23	// M2
++(pKStk)	dep r29=r22,r29,21,1	// I0 update ipsr.pp with psr.pp
++(pLvSys)mov r16=r0		// A  clear r16 for leave_syscall, no-op otherwise
++	;;
++#ifdef CONFIG_XEN
++	movl r25=XSI_IPSR
++	;;
++	st8[r25]=r29,XSI_IFS-XSI_IPSR
++	;;
++#else
++	mov cr.ipsr=r29		// M2
++#endif
++	mov ar.pfs=r26		// I0
++(pLvSys)mov r17=r0		// A  clear r17 for leave_syscall, no-op otherwise
++
++#ifdef CONFIG_XEN
++(p9)	st8 [r25]=r30
++	;;
++	adds r25=XSI_IIP-XSI_IFS,r25
++	;;
++#else
++(p9)	mov cr.ifs=r30		// M2
++#endif
++	mov b0=r21		// I0
++(pLvSys)mov r18=r0		// A  clear r18 for leave_syscall, no-op otherwise
++
++	mov ar.fpsr=r20		// M2
++#ifdef CONFIG_XEN
++	st8	[r25]=r28
++#else
++	mov cr.iip=r28		// M2
++#endif
++	nop 0
++	;;
++(pUStk)	mov ar.rnat=r24		// M2 must happen with RSE in lazy mode
++	nop 0
++(pLvSys)mov r2=r0
++
++	mov ar.rsc=r27		// M2
++	mov pr=r31,-1		// I0
++#ifdef CONFIG_XEN
++	;;
++	XEN_HYPER_RFI;
++#else
++	rfi			// B
++#endif
++
++	/*
++	 * On entry:
++	 *	r20 = &current->thread_info->pre_count (if CONFIG_PREEMPT)
++	 *	r31 = current->thread_info->flags
++	 * On exit:
++	 *	p6 = TRUE if work-pending-check needs to be redone
++	 */
++.work_pending_syscall:
++	add r2=-8,r2
++	add r3=-8,r3
++	;;
++	st8 [r2]=r8
++	st8 [r3]=r10
++.work_pending:
++	tbit.nz p6,p0=r31,TIF_SIGDELAYED		// signal delayed from  MCA/INIT/NMI/PMI context?
++(p6)	br.cond.sptk.few .sigdelayed
++	;;
++	tbit.z p6,p0=r31,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
++(p6)	br.cond.sptk.few .notify
++#ifdef CONFIG_PREEMPT
++(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
++	;;
++(pKStk) st4 [r20]=r21
++	ssm psr.i		// enable interrupts
++#endif
++	br.call.spnt.many rp=schedule
++.ret9:	cmp.eq p6,p0=r0,r0				// p6 <- 1
++#ifdef CONFIG_XEN
++	movl r2=XSI_PSR_I
++	;;
++	st4 [r2]=r0
++#else
++	rsm psr.i		// disable interrupts
++#endif
++	;;
++#ifdef CONFIG_PREEMPT
++(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
++	;;
++(pKStk)	st4 [r20]=r0		// preempt_count() <- 0
++#endif
++(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
++	br.cond.sptk.many .work_processed_kernel	// re-check
++
++.notify:
++(pUStk)	br.call.spnt.many rp=notify_resume_user
++.ret10:	cmp.ne p6,p0=r0,r0				// p6 <- 0
++(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
++	br.cond.sptk.many .work_processed_kernel	// don't re-check
++
++// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where
++// it could not be delivered.  Deliver it now.  The signal might be for us and
++// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
++// signal.
++
++.sigdelayed:
++	br.call.sptk.many rp=do_sigdelayed
++	cmp.eq p6,p0=r0,r0				// p6 <- 1, always re-check
++(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
++	br.cond.sptk.many .work_processed_kernel	// re-check
++
++.work_pending_syscall_end:
++	adds r2=PT(R8)+16,r12
++	adds r3=PT(R10)+16,r12
++	;;
++	ld8 r8=[r2]
++	ld8 r10=[r3]
++	br.cond.sptk.many .work_processed_syscall	// re-check
++
++#ifdef CONFIG_XEN
++END(xen_leave_kernel)
++#else
++END(ia64_leave_kernel)
++#endif
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xenhpski.c
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xenhpski.c	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,19 @@
++
++extern unsigned long xen_get_cpuid(int);
++
++int
++running_on_sim(void)
++{
++	int i;
++	long cpuid[6];
++
++	for (i = 0; i < 5; ++i)
++		cpuid[i] = xen_get_cpuid(i);
++	if ((cpuid[0] & 0xff) != 'H') return 0;
++	if ((cpuid[3] & 0xff) != 0x4) return 0;
++	if (((cpuid[3] >> 8) & 0xff) != 0x0) return 0;
++	if (((cpuid[3] >> 16) & 0xff) != 0x0) return 0;
++	if (((cpuid[3] >> 24) & 0x7) != 0x7) return 0;
++	return 1;
++}
++
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xenivt.S
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xenivt.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,2044 @@
++/*
++ * arch/ia64/xen/ivt.S
++ *
++ * Copyright (C) 2005 Hewlett-Packard Co
++ *	Dan Magenheimer <dan.magenheimer at hp.com>
++ */
++/*
++ * This file defines the interruption vector table used by the CPU.
++ * It does not include one entry per possible cause of interruption.
++ *
++ * The first 20 entries of the table contain 64 bundles each while the
++ * remaining 48 entries contain only 16 bundles each.
++ *
++ * The 64 bundles are used to allow inlining the whole handler for critical
++ * interruptions like TLB misses.
++ *
++ *  For each entry, the comment is as follows:
++ *
++ *		// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
++ *  entry offset ----/     /         /                  /          /
++ *  entry number ---------/         /                  /          /
++ *  size of the entry -------------/                  /          /
++ *  vector name -------------------------------------/          /
++ *  interruptions triggering this vector ----------------------/
++ *
++ * The table is 32KB in size and must be aligned on 32KB boundary.
++ * (The CPU ignores the 15 lower bits of the address)
++ *
++ * Table is based upon EAS2.6 (Oct 1999)
++ */
++
++#include <linux/config.h>
++
++#include <asm/asmmacro.h>
++#include <asm/break.h>
++#include <asm/ia32.h>
++#include <asm/kregs.h>
++#include <asm/asm-offsets.h>
++#include <asm/pgtable.h>
++#include <asm/processor.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include <asm/thread_info.h>
++#include <asm/unistd.h>
++#include <asm/errno.h>
++
++#ifdef CONFIG_XEN
++#define ia64_ivt xen_ivt
++#endif
++
++#if 1
++# define PSR_DEFAULT_BITS	psr.ac
++#else
++# define PSR_DEFAULT_BITS	0
++#endif
++
++#if 0
++  /*
++   * This lets you track the last eight faults that occurred on the CPU.  Make sure ar.k2 isn't
++   * needed for something else before enabling this...
++   */
++# define DBG_FAULT(i)	mov r16=ar.k2;;	shl r16=r16,8;;	add r16=(i),r16;;mov ar.k2=r16
++#else
++# define DBG_FAULT(i)
++#endif
++
++#define MINSTATE_VIRT	/* needed by minstate.h */
++#include "xenminstate.h"
++
++#define FAULT(n)									\
++	mov r31=pr;									\
++	mov r19=n;;			/* prepare to save predicates */		\
++	br.sptk.many dispatch_to_fault_handler
++
++	.section .text.ivt,"ax"
++
++	.align 32768	// align on 32KB boundary
++	.global ia64_ivt
++ia64_ivt:
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
++ENTRY(vhpt_miss)
++	DBG_FAULT(0)
++	/*
++	 * The VHPT vector is invoked when the TLB entry for the virtual page table
++	 * is missing.  This happens only as a result of a previous
++	 * (the "original") TLB miss, which may either be caused by an instruction
++	 * fetch or a data access (or non-access).
++	 *
++	 * What we do here is normal TLB miss handing for the _original_ miss, followed
++	 * by inserting the TLB entry for the virtual page table page that the VHPT
++	 * walker was attempting to access.  The latter gets inserted as long
++	 * as both L1 and L2 have valid mappings for the faulting address.
++	 * The TLB entry for the original miss gets inserted only if
++	 * the L3 entry indicates that the page is present.
++	 *
++	 * do_page_fault gets invoked in the following cases:
++	 *	- the faulting virtual address uses unimplemented address bits
++	 *	- the faulting virtual address has no L1, L2, or L3 mapping
++	 */
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++#ifdef CONFIG_HUGETLB_PAGE
++	movl r18=PAGE_SHIFT
++	movl r25=XSI_ITIR
++	;;
++	ld8 r25=[r25]
++#endif
++	;;
++#else
++	mov r16=cr.ifa				// get address that caused the TLB miss
++#ifdef CONFIG_HUGETLB_PAGE
++	movl r18=PAGE_SHIFT
++	mov r25=cr.itir
++#endif
++#endif
++	;;
++#ifdef CONFIG_XEN
++	XEN_HYPER_RSM_PSR_DT;
++#else
++	rsm psr.dt				// use physical addressing for data
++#endif
++	mov r31=pr				// save the predicate registers
++	mov r19=IA64_KR(PT_BASE)		// get page table base address
++	shl r21=r16,3				// shift bit 60 into sign bit
++	shr.u r17=r16,61			// get the region number into r17
++	;;
++	shr r22=r21,3
++#ifdef CONFIG_HUGETLB_PAGE
++	extr.u r26=r25,2,6
++	;;
++	cmp.ne p8,p0=r18,r26
++	sub r27=r26,r18
++	;;
++(p8)	dep r25=r18,r25,2,6
++(p8)	shr r22=r22,r27
++#endif
++	;;
++	cmp.eq p6,p7=5,r17			// is IFA pointing into to region 5?
++	shr.u r18=r22,PGDIR_SHIFT		// get bits 33-63 of the faulting address
++	;;
++(p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
++
++	srlz.d
++	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
++
++	.pred.rel "mutex", p6, p7
++(p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
++(p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
++	;;
++(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
++(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
++	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
++	shr.u r18=r22,PMD_SHIFT			// shift L2 index into position
++	;;
++	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
++	;;
++(p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
++	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
++	;;
++(p7)	ld8 r20=[r17]				// fetch the L2 entry (may be 0)
++	shr.u r19=r22,PAGE_SHIFT		// shift L3 index into position
++	;;
++(p7)	cmp.eq.or.andcm p6,p7=r20,r0		// was L2 entry NULL?
++	dep r21=r19,r20,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
++	;;
++#ifdef CONFIG_XEN
++(p7)	ld8 r18=[r21]				// read the L3 PTE
++	movl r19=XSI_ISR
++	;;
++	ld8 r19=[r19]
++	;;
++(p7)	tbit.z p6,p7=r18,_PAGE_P_BIT		// page present bit cleared?
++	movl r22=XSI_IHA
++	;;
++	ld8 r22=[r22]
++	;;
++#else
++(p7)	ld8 r18=[r21]				// read the L3 PTE
++	mov r19=cr.isr				// cr.isr bit 0 tells us if this is an insn miss
++	;;
++(p7)	tbit.z p6,p7=r18,_PAGE_P_BIT		// page present bit cleared?
++	mov r22=cr.iha				// get the VHPT address that caused the TLB miss
++	;;					// avoid RAW on p7
++#endif
++(p7)	tbit.nz.unc p10,p11=r19,32		// is it an instruction TLB miss?
++	dep r23=0,r20,0,PAGE_SHIFT		// clear low bits to get page address
++	;;
++#ifdef CONFIG_XEN
++	mov r24=r8
++	mov r8=r18
++	;;
++(p10)	XEN_HYPER_ITC_D
++	;;
++(p11)	XEN_HYPER_ITC_I
++	;;
++	mov r8=r24
++	;;
++(p6)	br.cond.spnt.many page_fault		// handle bad address/page not present (page fault)
++	;;
++	movl r24=XSI_IFA
++	;;
++	st8 [r24]=r22
++	;;
++#else
++(p10)	itc.i r18				// insert the instruction TLB entry
++(p11)	itc.d r18				// insert the data TLB entry
++(p6)	br.cond.spnt.many page_fault		// handle bad address/page not present (page fault)
++	mov cr.ifa=r22
++#endif
++
++#ifdef CONFIG_HUGETLB_PAGE
++(p8)	mov cr.itir=r25				// change to default page-size for VHPT
++#endif
++
++	/*
++	 * Now compute and insert the TLB entry for the virtual page table.  We never
++	 * execute in a page table page so there is no need to set the exception deferral
++	 * bit.
++	 */
++	adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
++	;;
++#ifdef CONFIG_XEN
++(p7)	mov r25=r8
++(p7)	mov r8=r24
++	;;
++(p7)	XEN_HYPER_ITC_D
++	;;
++(p7)	mov r8=r25
++	;;
++#else
++(p7)	itc.d r24
++#endif
++	;;
++#ifdef CONFIG_SMP
++	/*
++	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
++	 * cannot possibly affect the following loads:
++	 */
++	dv_serialize_data
++
++	/*
++	 * Re-check L2 and L3 pagetable.  If they changed, we may have received a ptc.g
++	 * between reading the pagetable and the "itc".  If so, flush the entry we
++	 * inserted and retry.
++	 */
++	ld8 r25=[r21]				// read L3 PTE again
++	ld8 r26=[r17]				// read L2 entry again
++	;;
++	cmp.ne p6,p7=r26,r20			// did L2 entry change
++	mov r27=PAGE_SHIFT<<2
++	;;
++(p6)	ptc.l r22,r27				// purge PTE page translation
++(p7)	cmp.ne.or.andcm p6,p7=r25,r18		// did L3 PTE change
++	;;
++(p6)	ptc.l r16,r27				// purge translation
++#endif
++
++	mov pr=r31,-1				// restore predicate registers
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(vhpt_miss)
++
++	.org ia64_ivt+0x400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
++ENTRY(itlb_miss)
++	DBG_FAULT(1)
++	/*
++	 * The ITLB handler accesses the L3 PTE via the virtually mapped linear
++	 * page table.  If a nested TLB miss occurs, we switch into physical
++	 * mode, walk the page table, and then re-execute the L3 PTE read
++	 * and go on normally after that.
++	 */
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++#else
++	mov r16=cr.ifa				// get virtual address
++#endif
++	mov r29=b0				// save b0
++	mov r31=pr				// save predicates
++.itlb_fault:
++#ifdef CONFIG_XEN
++	movl r17=XSI_IHA
++	;;
++	ld8 r17=[r17]				// get virtual address of L3 PTE
++#else
++	mov r17=cr.iha				// get virtual address of L3 PTE
++#endif
++	movl r30=1f				// load nested fault continuation point
++	;;
++1:	ld8 r18=[r17]				// read L3 PTE
++	;;
++	mov b0=r29
++	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
++(p6)	br.cond.spnt page_fault
++	;;
++#ifdef CONFIG_XEN
++	mov r19=r8
++	mov r8=r18
++	;;
++	XEN_HYPER_ITC_I
++	;;
++	mov r8=r19
++#else
++	itc.i r18
++#endif
++	;;
++#ifdef CONFIG_SMP
++	/*
++	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
++	 * cannot possibly affect the following loads:
++	 */
++	dv_serialize_data
++
++	ld8 r19=[r17]				// read L3 PTE again and see if same
++	mov r20=PAGE_SHIFT<<2			// setup page size for purge
++	;;
++	cmp.ne p7,p0=r18,r19
++	;;
++(p7)	ptc.l r16,r20
++#endif
++	mov pr=r31,-1
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(itlb_miss)
++
++	.org ia64_ivt+0x0800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
++ENTRY(dtlb_miss)
++	DBG_FAULT(2)
++	/*
++	 * The DTLB handler accesses the L3 PTE via the virtually mapped linear
++	 * page table.  If a nested TLB miss occurs, we switch into physical
++	 * mode, walk the page table, and then re-execute the L3 PTE read
++	 * and go on normally after that.
++	 */
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++#else
++	mov r16=cr.ifa				// get virtual address
++#endif
++	mov r29=b0				// save b0
++	mov r31=pr				// save predicates
++dtlb_fault:
++#ifdef CONFIG_XEN
++	movl r17=XSI_IHA
++	;;
++	ld8 r17=[r17]				// get virtual address of L3 PTE
++#else
++	mov r17=cr.iha				// get virtual address of L3 PTE
++#endif
++	movl r30=1f				// load nested fault continuation point
++	;;
++1:	ld8 r18=[r17]				// read L3 PTE
++	;;
++	mov b0=r29
++	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
++(p6)	br.cond.spnt page_fault
++	;;
++#ifdef CONFIG_XEN
++	mov r19=r8
++	mov r8=r18
++	;;
++	XEN_HYPER_ITC_D
++	;;
++	mov r8=r19
++	;;
++#else
++	itc.d r18
++#endif
++	;;
++#ifdef CONFIG_SMP
++	/*
++	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
++	 * cannot possibly affect the following loads:
++	 */
++	dv_serialize_data
++
++	ld8 r19=[r17]				// read L3 PTE again and see if same
++	mov r20=PAGE_SHIFT<<2			// setup page size for purge
++	;;
++	cmp.ne p7,p0=r18,r19
++	;;
++(p7)	ptc.l r16,r20
++#endif
++	mov pr=r31,-1
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(dtlb_miss)
++
++	.org ia64_ivt+0x0c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
++ENTRY(alt_itlb_miss)
++	DBG_FAULT(3)
++#ifdef CONFIG_XEN
++	movl r31=XSI_IPSR
++	;;
++	ld8 r21=[r31],XSI_IFA-XSI_IPSR	// get ipsr, point to ifa
++	movl r17=PAGE_KERNEL
++	;;
++	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
++	;;
++	ld8 r16=[r31]		// get ifa
++	mov r31=pr
++	;;
++#else
++	mov r16=cr.ifa		// get address that caused the TLB miss
++	movl r17=PAGE_KERNEL
++	mov r21=cr.ipsr
++	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
++	mov r31=pr
++	;;
++#endif
++#ifdef CONFIG_DISABLE_VHPT
++	shr.u r22=r16,61			// get the region number into r21
++	;;
++	cmp.gt p8,p0=6,r22			// user mode
++	;;
++#ifndef CONFIG_XEN
++(p8)	thash r17=r16
++	;;
++(p8)	mov cr.iha=r17
++#endif
++(p8)	mov r29=b0				// save b0
++(p8)	br.cond.dptk .itlb_fault
++#endif
++	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
++	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
++	shr.u r18=r16,57	// move address bit 61 to bit 4
++	;;
++	andcm r18=0x10,r18	// bit 4=~address-bit(61)
++	cmp.ne p8,p0=r0,r23	// psr.cpl != 0?
++	or r19=r17,r19		// insert PTE control bits into r19
++	;;
++	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
++(p8)	br.cond.spnt page_fault
++	;;
++#ifdef CONFIG_XEN
++	mov r18=r8
++	mov r8=r19
++	;;
++	XEN_HYPER_ITC_I
++	;;
++	mov r8=r18
++	;;
++	mov pr=r31,-1
++	;;
++	XEN_HYPER_RFI;
++#else
++	itc.i r19		// insert the TLB entry
++	mov pr=r31,-1
++	rfi
++#endif
++END(alt_itlb_miss)
++
++	.org ia64_ivt+0x1000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
++ENTRY(alt_dtlb_miss)
++	DBG_FAULT(4)
++#ifdef CONFIG_XEN
++	movl r31=XSI_IPSR
++	;;
++	ld8 r21=[r31],XSI_ISR-XSI_IPSR	// get ipsr, point to isr
++	movl r17=PAGE_KERNEL
++	;;
++	ld8 r20=[r31],XSI_IFA-XSI_ISR	// get isr, point to ifa
++	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
++	;;
++	ld8 r16=[r31]		// get ifa
++	mov r31=pr
++	;;
++#else
++	mov r16=cr.ifa		// get address that caused the TLB miss
++	movl r17=PAGE_KERNEL
++	mov r20=cr.isr
++	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
++	mov r21=cr.ipsr
++	mov r31=pr
++	;;
++#endif
++#ifdef CONFIG_DISABLE_VHPT
++	shr.u r22=r16,61			// get the region number into r21
++	;;
++	cmp.gt p8,p0=6,r22			// access to region 0-5
++	;;
++#ifndef CONFIG_XEN
++(p8)	thash r17=r16
++	;;
++(p8)	mov cr.iha=r17
++#endif
++(p8)	mov r29=b0				// save b0
++(p8)	br.cond.dptk dtlb_fault
++#endif
++	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
++	and r22=IA64_ISR_CODE_MASK,r20		// get the isr.code field
++	tbit.nz p6,p7=r20,IA64_ISR_SP_BIT	// is speculation bit on?
++	shr.u r18=r16,57			// move address bit 61 to bit 4
++	and r19=r19,r16				// clear ed, reserved bits, and PTE control bits
++	tbit.nz p9,p0=r20,IA64_ISR_NA_BIT	// is non-access bit on?
++	;;
++	andcm r18=0x10,r18	// bit 4=~address-bit(61)
++	cmp.ne p8,p0=r0,r23
++(p9)	cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22	// check isr.code field
++(p8)	br.cond.spnt page_fault
++
++	dep r21=-1,r21,IA64_PSR_ED_BIT,1
++	or r19=r19,r17		// insert PTE control bits into r19
++	;;
++	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
++(p6)	mov cr.ipsr=r21
++	;;
++#ifdef CONFIG_XEN
++(p7)	mov r18=r8
++(p7)	mov r8=r19
++	;;
++(p7)	XEN_HYPER_ITC_D
++	;;
++(p7)	mov r8=r18
++	;;
++	mov pr=r31,-1
++	;;
++	XEN_HYPER_RFI;
++#else
++(p7)	itc.d r19		// insert the TLB entry
++	mov pr=r31,-1
++	rfi
++#endif
++END(alt_dtlb_miss)
++
++	.org ia64_ivt+0x1400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
++ENTRY(nested_dtlb_miss)
++	/*
++	 * In the absence of kernel bugs, we get here when the virtually mapped linear
++	 * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction
++	 * Access-bit, or Data Access-bit faults).  If the DTLB entry for the virtual page
++	 * table is missing, a nested TLB miss fault is triggered and control is
++	 * transferred to this point.  When this happens, we lookup the pte for the
++	 * faulting address by walking the page table in physical mode and return to the
++	 * continuation point passed in register r30 (or call page_fault if the address is
++	 * not mapped).
++	 *
++	 * Input:	r16:	faulting address
++	 *		r29:	saved b0
++	 *		r30:	continuation address
++	 *		r31:	saved pr
++	 *
++	 * Output:	r17:	physical address of L3 PTE of faulting address
++	 *		r29:	saved b0
++	 *		r30:	continuation address
++	 *		r31:	saved pr
++	 *
++	 * Clobbered:	b0, r18, r19, r21, psr.dt (cleared)
++	 */
++#ifdef CONFIG_XEN
++	XEN_HYPER_RSM_PSR_DT;
++#else
++	rsm psr.dt				// switch to using physical data addressing
++#endif
++	mov r19=IA64_KR(PT_BASE)		// get the page table base address
++	shl r21=r16,3				// shift bit 60 into sign bit
++	;;
++	shr.u r17=r16,61			// get the region number into r17
++	;;
++	cmp.eq p6,p7=5,r17			// is faulting address in region 5?
++	shr.u r18=r16,PGDIR_SHIFT		// get bits 33-63 of faulting address
++	;;
++(p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
++
++	srlz.d
++	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
++
++	.pred.rel "mutex", p6, p7
++(p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
++(p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
++	;;
++(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
++(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
++	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
++	shr.u r18=r16,PMD_SHIFT			// shift L2 index into position
++	;;
++	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
++	;;
++(p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
++	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
++	;;
++(p7)	ld8 r17=[r17]				// fetch the L2 entry (may be 0)
++	shr.u r19=r16,PAGE_SHIFT		// shift L3 index into position
++	;;
++(p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was L2 entry NULL?
++	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
++(p6)	br.cond.spnt page_fault
++	mov b0=r30
++	br.sptk.many b0				// return to continuation point
++END(nested_dtlb_miss)
++
++	.org ia64_ivt+0x1800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
++ENTRY(ikey_miss)
++	DBG_FAULT(6)
++	FAULT(6)
++END(ikey_miss)
++
++	//-----------------------------------------------------------------------------------
++	// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
++ENTRY(page_fault)
++#ifdef CONFIG_XEN
++	XEN_HYPER_SSM_PSR_DT;
++#else
++	ssm psr.dt
++	;;
++	srlz.i
++#endif
++	;;
++	SAVE_MIN_WITH_COVER
++	alloc r15=ar.pfs,0,0,3,0
++#ifdef CONFIG_XEN
++	movl r3=XSI_ISR
++	;;
++	ld8 out1=[r3],XSI_IFA-XSI_ISR		// get vcr.isr, point to ifa
++	;;
++	ld8 out0=[r3]				// get vcr.ifa
++	mov r14=1
++	;;
++	add r3=XSI_PSR_IC-XSI_IFA, r3		// point to vpsr.ic
++	;;
++	st4 [r3]=r14				// vpsr.ic = 1
++	adds r3=8,r2				// set up second base pointer
++	;;
++#else
++	mov out0=cr.ifa
++	mov out1=cr.isr
++	adds r3=8,r2				// set up second base pointer
++	;;
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i					// guarantee that interruption collectin is on
++	;;
++#endif
++#ifdef CONFIG_XEN
++	br.cond.sptk.many	xen_page_fault
++	;;
++done_xen_page_fault:
++#endif
++(p15)	ssm psr.i				// restore psr.i
++	movl r14=ia64_leave_kernel
++	;;
++	SAVE_REST
++	mov rp=r14
++	;;
++	adds out2=16,r12			// out2 = pointer to pt_regs
++	br.call.sptk.many b6=ia64_do_page_fault	// ignore return address
++END(page_fault)
++
++	.org ia64_ivt+0x1c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
++ENTRY(dkey_miss)
++	DBG_FAULT(7)
++	FAULT(7)
++#ifdef CONFIG_XEN
++	// Leaving this code inline above results in an IVT section overflow
++	// There is no particular reason for this code to be here...
++xen_page_fault:
++(p15)	movl r3=XSI_PSR_I
++	;;
++(p15)	st4 [r3]=r14,XSI_PEND-XSI_PSR_I		// if (p15) vpsr.i = 1
++	mov r14=r0
++	;;
++(p15)	ld4 r14=[r3]				// if (pending_interrupts)
++	adds r3=8,r2				// re-set up second base pointer
++	;;
++(p15)	cmp.ne	p15,p0=r14,r0
++	;;
++	br.cond.sptk.many done_xen_page_fault
++	;;
++#endif
++END(dkey_miss)
++
++	.org ia64_ivt+0x2000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
++ENTRY(dirty_bit)
++	DBG_FAULT(8)
++	/*
++	 * What we do here is to simply turn on the dirty bit in the PTE.  We need to
++	 * update both the page-table and the TLB entry.  To efficiently access the PTE,
++	 * we address it through the virtual page table.  Most likely, the TLB entry for
++	 * the relevant virtual page table page is still present in the TLB so we can
++	 * normally do this without additional TLB misses.  In case the necessary virtual
++	 * page table TLB entry isn't present, we take a nested TLB miss hit where we look
++	 * up the physical address of the L3 PTE and then continue at label 1 below.
++	 */
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++	;;
++#else
++	mov r16=cr.ifa				// get the address that caused the fault
++#endif
++	movl r30=1f				// load continuation point in case of nested fault
++	;;
++#ifdef CONFIG_XEN
++#if 1
++	mov r18=r8;
++	mov r8=r16;
++	XEN_HYPER_THASH;;
++	mov r17=r8;
++	mov r8=r18;;
++#else
++	tak r17=r80				// "privified" thash
++#endif
++#else
++	thash r17=r16				// compute virtual address of L3 PTE
++#endif
++	mov r29=b0				// save b0 in case of nested fault
++	mov r31=pr				// save pr
++#ifdef CONFIG_SMP
++	mov r28=ar.ccv				// save ar.ccv
++	;;
++1:	ld8 r18=[r17]
++	;;					// avoid RAW on r18
++	mov ar.ccv=r18				// set compare value for cmpxchg
++	or r25=_PAGE_D|_PAGE_A,r18		// set the dirty and accessed bits
++	;;
++	cmpxchg8.acq r26=[r17],r25,ar.ccv
++	mov r24=PAGE_SHIFT<<2
++	;;
++	cmp.eq p6,p7=r26,r18
++	;;
++(p6)	itc.d r25				// install updated PTE
++	;;
++	/*
++	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
++	 * cannot possibly affect the following loads:
++	 */
++	dv_serialize_data
++
++	ld8 r18=[r17]				// read PTE again
++	;;
++	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
++	;;
++(p7)	ptc.l r16,r24
++	mov b0=r29				// restore b0
++	mov ar.ccv=r28
++#else
++	;;
++1:	ld8 r18=[r17]
++	;;					// avoid RAW on r18
++	or r18=_PAGE_D|_PAGE_A,r18		// set the dirty and accessed bits
++	mov b0=r29				// restore b0
++	;;
++	st8 [r17]=r18				// store back updated PTE
++	itc.d r18				// install updated PTE
++#endif
++	mov pr=r31,-1				// restore pr
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(dirty_bit)
++
++	.org ia64_ivt+0x2400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
++ENTRY(iaccess_bit)
++	DBG_FAULT(9)
++	// Like Entry 8, except for instruction access
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++	;;
++#else
++	mov r16=cr.ifa				// get the address that caused the fault
++#endif
++	movl r30=1f				// load continuation point in case of nested fault
++	mov r31=pr				// save predicates
++#ifdef CONFIG_ITANIUM
++	/*
++	 * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
++	 */
++	mov r17=cr.ipsr
++	;;
++	mov r18=cr.iip
++	tbit.z p6,p0=r17,IA64_PSR_IS_BIT	// IA64 instruction set?
++	;;
++(p6)	mov r16=r18				// if so, use cr.iip instead of cr.ifa
++#endif /* CONFIG_ITANIUM */
++	;;
++#ifdef CONFIG_XEN
++#if 1
++	mov r18=r8;
++	mov r8=r16;
++	XEN_HYPER_THASH;;
++	mov r17=r8;
++	mov r8=r18;;
++#else
++	tak r17=r80				// "privified" thash
++#endif
++#else
++	thash r17=r16				// compute virtual address of L3 PTE
++#endif
++	mov r29=b0				// save b0 in case of nested fault)
++#ifdef CONFIG_SMP
++	mov r28=ar.ccv				// save ar.ccv
++	;;
++1:	ld8 r18=[r17]
++	;;
++	mov ar.ccv=r18				// set compare value for cmpxchg
++	or r25=_PAGE_A,r18			// set the accessed bit
++	;;
++	cmpxchg8.acq r26=[r17],r25,ar.ccv
++	mov r24=PAGE_SHIFT<<2
++	;;
++	cmp.eq p6,p7=r26,r18
++	;;
++#ifdef CONFIG_XEN
++	mov r26=r8
++	mov r8=r25
++	;;
++(p6)	XEN_HYPER_ITC_I
++	;;
++	mov r8=r26
++	;;
++#else
++(p6)	itc.i r25				// install updated PTE
++#endif
++	;;
++	/*
++	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
++	 * cannot possibly affect the following loads:
++	 */
++	dv_serialize_data
++
++	ld8 r18=[r17]				// read PTE again
++	;;
++	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
++	;;
++(p7)	ptc.l r16,r24
++	mov b0=r29				// restore b0
++	mov ar.ccv=r28
++#else /* !CONFIG_SMP */
++	;;
++1:	ld8 r18=[r17]
++	;;
++	or r18=_PAGE_A,r18			// set the accessed bit
++	mov b0=r29				// restore b0
++	;;
++	st8 [r17]=r18				// store back updated PTE
++	itc.i r18				// install updated PTE
++#endif /* !CONFIG_SMP */
++	mov pr=r31,-1
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(iaccess_bit)
++
++	.org ia64_ivt+0x2800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
++ENTRY(daccess_bit)
++	DBG_FAULT(10)
++	// Like Entry 8, except for data access
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++	;;
++#else
++	mov r16=cr.ifa				// get the address that caused the fault
++#endif
++	movl r30=1f				// load continuation point in case of nested fault
++	;;
++#ifdef CONFIG_XEN
++#if 1
++	mov r18=r8;
++	mov r8=r16;
++	XEN_HYPER_THASH;;
++	mov r17=r8;
++	mov r8=r18;;
++#else
++	tak r17=r80				// "privified" thash
++#endif
++#else
++	thash r17=r16				// compute virtual address of L3 PTE
++#endif
++	mov r31=pr
++	mov r29=b0				// save b0 in case of nested fault)
++#ifdef CONFIG_SMP
++	mov r28=ar.ccv				// save ar.ccv
++	;;
++1:	ld8 r18=[r17]
++	;;					// avoid RAW on r18
++	mov ar.ccv=r18				// set compare value for cmpxchg
++	or r25=_PAGE_A,r18			// set the dirty bit
++	;;
++	cmpxchg8.acq r26=[r17],r25,ar.ccv
++	mov r24=PAGE_SHIFT<<2
++	;;
++	cmp.eq p6,p7=r26,r18
++	;;
++#ifdef CONFIG_XEN
++	mov r26=r8
++	mov r8=r25
++	;;
++(p6)	XEN_HYPER_ITC_D
++	;;
++	mov r8=r26
++	;;
++#else
++(p6)	itc.d r25				// install updated PTE
++#endif
++	/*
++	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
++	 * cannot possibly affect the following loads:
++	 */
++	dv_serialize_data
++	;;
++	ld8 r18=[r17]				// read PTE again
++	;;
++	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
++	;;
++(p7)	ptc.l r16,r24
++	mov ar.ccv=r28
++#else
++	;;
++1:	ld8 r18=[r17]
++	;;					// avoid RAW on r18
++	or r18=_PAGE_A,r18			// set the accessed bit
++	;;
++	st8 [r17]=r18				// store back updated PTE
++	itc.d r18				// install updated PTE
++#endif
++	mov b0=r29				// restore b0
++	mov pr=r31,-1
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(daccess_bit)
++
++	.org ia64_ivt+0x2c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
++ENTRY(break_fault)
++	/*
++	 * The streamlined system call entry/exit paths only save/restore the initial part
++	 * of pt_regs.  This implies that the callers of system-calls must adhere to the
++	 * normal procedure calling conventions.
++	 *
++	 *   Registers to be saved & restored:
++	 *	CR registers: cr.ipsr, cr.iip, cr.ifs
++	 *	AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
++	 * 	others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
++	 *   Registers to be restored only:
++	 * 	r8-r11: output value from the system call.
++	 *
++	 * During system call exit, scratch registers (including r15) are modified/cleared
++	 * to prevent leaking bits from kernel to user level.
++	 */
++	DBG_FAULT(11)
++	mov r16=IA64_KR(CURRENT)		// r16 = current task; 12 cycle read lat.
++#ifdef CONFIG_XEN
++	movl r31=XSI_IPSR
++	;;
++	ld8 r29=[r31],XSI_IIP-XSI_IPSR		// get ipsr, point to iip
++	mov r18=__IA64_BREAK_SYSCALL
++	mov r21=ar.fpsr
++	;;
++	ld8 r28=[r31],XSI_IIM-XSI_IIP		// get iip, point to iim
++	mov r19=b6
++	mov r25=ar.unat
++	;;
++	ld8 r17=[r31]				// get iim
++	mov r27=ar.rsc
++	mov r26=ar.pfs
++	;;
++#else
++	mov r17=cr.iim
++	mov r18=__IA64_BREAK_SYSCALL
++	mov r21=ar.fpsr
++	mov r29=cr.ipsr
++	mov r19=b6
++	mov r25=ar.unat
++	mov r27=ar.rsc
++	mov r26=ar.pfs
++	mov r28=cr.iip
++#endif
++	mov r31=pr				// prepare to save predicates
++	mov r20=r1
++	;;
++	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
++	cmp.eq p0,p7=r18,r17			// is this a system call? (p7 <- false, if so)
++(p7)	br.cond.spnt non_syscall
++	;;
++	ld1 r17=[r16]				// load current->thread.on_ustack flag
++	st1 [r16]=r0				// clear current->thread.on_ustack flag
++	add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16	// set r1 for MINSTATE_START_SAVE_MIN_VIRT
++	;;
++	invala
++
++	/* adjust return address so we skip over the break instruction: */
++
++	extr.u r8=r29,41,2			// extract ei field from cr.ipsr
++	;;
++	cmp.eq p6,p7=2,r8			// isr.ei==2?
++	mov r2=r1				// setup r2 for ia64_syscall_setup
++	;;
++(p6)	mov r8=0				// clear ei to 0
++(p6)	adds r28=16,r28				// switch cr.iip to next bundle cr.ipsr.ei wrapped
++(p7)	adds r8=1,r8				// increment ei to next slot
++	;;
++	cmp.eq pKStk,pUStk=r0,r17		// are we in kernel mode already?
++	dep r29=r8,r29,41,2			// insert new ei into cr.ipsr
++	;;
++
++	// switch from user to kernel RBS:
++	MINSTATE_START_SAVE_MIN_VIRT
++	br.call.sptk.many b7=ia64_syscall_setup
++	;;
++#ifdef CONFIG_XEN
++	mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;;
++#else
++	MINSTATE_END_SAVE_MIN_VIRT		// switch to bank 1
++#endif
++#ifdef CONFIG_XEN
++	movl r3=XSI_PSR_IC
++	mov r16=1
++	;;
++#if 1
++	st4 [r3]=r16,XSI_PSR_I-XSI_PSR_IC	// vpsr.ic = 1
++	;;
++(p15)	st4 [r3]=r16,XSI_PEND-XSI_PSR_I		// if (p15) vpsr.i = 1
++	mov r16=r0
++	;;
++(p15)	ld4 r16=[r3]				// if (pending_interrupts)
++	;;
++	cmp.ne	p6,p0=r16,r0
++	;;
++(p6)	ssm	psr.i				//   do a real ssm psr.i
++	;;
++#else
++//	st4 [r3]=r16,XSI_PSR_I-XSI_PSR_IC	// vpsr.ic = 1
++	adds r3=XSI_PSR_I-XSI_PSR_IC,r3		// SKIP vpsr.ic = 1
++	;;
++(p15)	st4 [r3]=r16,XSI_PEND-XSI_PSR_I		// if (p15) vpsr.i = 1
++	mov r16=r0
++	;;
++(p15)	ld4 r16=[r3]				// if (pending_interrupts)
++	;;
++	cmp.ne	p6,p0=r16,r0
++	;;
++//(p6)	ssm	psr.i				//   do a real ssm psr.i
++//(p6)	XEN_HYPER_SSM_I;
++(p6)	break 0x7;
++	;;
++#endif
++	mov r3=NR_syscalls - 1
++	;;
++#else
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i					// guarantee that interruption collection is on
++	mov r3=NR_syscalls - 1
++	;;
++(p15)	ssm psr.i				// restore psr.i
++#endif
++	// p10==true means out registers are more than 8 or r15's Nat is true
++(p10)	br.cond.spnt.many ia64_ret_from_syscall
++	;;
++	movl r16=sys_call_table
++
++	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
++	movl r2=ia64_ret_from_syscall
++	;;
++	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
++	cmp.leu p6,p7=r15,r3			// (syscall > 0 && syscall < 1024 + NR_syscalls) ?
++	mov rp=r2				// set the real return addr
++	;;
++(p6)	ld8 r20=[r20]				// load address of syscall entry point
++(p7)	movl r20=sys_ni_syscall
++
++	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
++	;;
++	ld4 r2=[r2]				// r2 = current_thread_info()->flags
++	;;
++	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
++	;;
++	cmp.eq p8,p0=r2,r0
++	mov b6=r20
++	;;
++(p8)	br.call.sptk.many b6=b6			// ignore this return addr
++	br.cond.sptk ia64_trace_syscall
++	// NOT REACHED
++END(break_fault)
++
++	.org ia64_ivt+0x3000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
++ENTRY(interrupt)
++	DBG_FAULT(12)
++	mov r31=pr		// prepare to save predicates
++	;;
++	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
++#ifdef CONFIG_XEN
++	movl r3=XSI_PSR_IC
++	mov r14=1
++	;;
++	st4 [r3]=r14
++#else
++	ssm psr.ic | PSR_DEFAULT_BITS
++#endif
++	;;
++	adds r3=8,r2		// set up second base pointer for SAVE_REST
++	srlz.i			// ensure everybody knows psr.ic is back on
++	;;
++	SAVE_REST
++	;;
++	alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
++#ifdef CONFIG_XEN
++	;;
++	br.call.sptk.many rp=xen_get_ivr
++	;;
++	mov out0=r8		// pass cr.ivr as first arg
++#else
++	mov out0=cr.ivr		// pass cr.ivr as first arg
++#endif
++	add out1=16,sp		// pass pointer to pt_regs as second arg
++	;;
++	srlz.d			// make sure we see the effect of cr.ivr
++	movl r14=ia64_leave_kernel
++	;;
++	mov rp=r14
++	br.call.sptk.many b6=ia64_handle_irq
++END(interrupt)
++
++	.org ia64_ivt+0x3400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x3400 Entry 13 (size 64 bundles) Reserved
++	DBG_FAULT(13)
++	FAULT(13)
++
++	.org ia64_ivt+0x3800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x3800 Entry 14 (size 64 bundles) Reserved
++	DBG_FAULT(14)
++	FAULT(14)
++
++	/*
++	 * There is no particular reason for this code to be here, other than that
++	 * there happens to be space here that would go unused otherwise.  If this
++	 * fault ever gets "unreserved", simply moved the following code to a more
++	 * suitable spot...
++	 *
++	 * ia64_syscall_setup() is a separate subroutine so that it can
++	 *	allocate stacked registers so it can safely demine any
++	 *	potential NaT values from the input registers.
++	 *
++	 * On entry:
++	 *	- executing on bank 0 or bank 1 register set (doesn't matter)
++	 *	-  r1: stack pointer
++	 *	-  r2: current task pointer
++	 *	-  r3: preserved
++	 *	- r11: original contents (saved ar.pfs to be saved)
++	 *	- r12: original contents (sp to be saved)
++	 *	- r13: original contents (tp to be saved)
++	 *	- r15: original contents (syscall # to be saved)
++	 *	- r18: saved bsp (after switching to kernel stack)
++	 *	- r19: saved b6
++	 *	- r20: saved r1 (gp)
++	 *	- r21: saved ar.fpsr
++	 *	- r22: kernel's register backing store base (krbs_base)
++	 *	- r23: saved ar.bspstore
++	 *	- r24: saved ar.rnat
++	 *	- r25: saved ar.unat
++	 *	- r26: saved ar.pfs
++	 *	- r27: saved ar.rsc
++	 *	- r28: saved cr.iip
++	 *	- r29: saved cr.ipsr
++	 *	- r31: saved pr
++	 *	-  b0: original contents (to be saved)
++	 * On exit:
++	 *	- executing on bank 1 registers
++	 *	- psr.ic enabled, interrupts restored
++	 *	-  p10: TRUE if syscall is invoked with more than 8 out
++	 *		registers or r15's Nat is true
++	 *	-  r1: kernel's gp
++	 *	-  r3: preserved (same as on entry)
++	 *	-  r8: -EINVAL if p10 is true
++	 *	- r12: points to kernel stack
++	 *	- r13: points to current task
++	 *	- p15: TRUE if interrupts need to be re-enabled
++	 *	- ar.fpsr: set to kernel settings
++	 */
++#ifndef CONFIG_XEN
++GLOBAL_ENTRY(ia64_syscall_setup)
++#if PT(B6) != 0
++# error This code assumes that b6 is the first field in pt_regs.
++#endif
++	st8 [r1]=r19				// save b6
++	add r16=PT(CR_IPSR),r1			// initialize first base pointer
++	add r17=PT(R11),r1			// initialize second base pointer
++	;;
++	alloc r19=ar.pfs,8,0,0,0		// ensure in0-in7 are writable
++	st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)	// save cr.ipsr
++	tnat.nz p8,p0=in0
++
++	st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)	// save r11
++	tnat.nz p9,p0=in1
++(pKStk)	mov r18=r0				// make sure r18 isn't NaT
++	;;
++
++	st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)	// save ar.pfs
++	st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)	// save cr.iip
++	mov r28=b0				// save b0 (2 cyc)
++	;;
++
++	st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)	// save ar.unat
++	dep r19=0,r19,38,26			// clear all bits but 0..37 [I0]
++(p8)	mov in0=-1
++	;;
++
++	st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)	// store ar.pfs.pfm in cr.ifs
++	extr.u r11=r19,7,7	// I0		// get sol of ar.pfs
++	and r8=0x7f,r19		// A		// get sof of ar.pfs
++
++	st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
++	tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
++(p9)	mov in1=-1
++	;;
++
++(pUStk) sub r18=r18,r22				// r18=RSE.ndirty*8
++	tnat.nz p10,p0=in2
++	add r11=8,r11
++	;;
++(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16		// skip over ar_rnat field
++(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17	// skip over ar_bspstore field
++	tnat.nz p11,p0=in3
++	;;
++(p10)	mov in2=-1
++	tnat.nz p12,p0=in4				// [I0]
++(p11)	mov in3=-1
++	;;
++(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)	// save ar.rnat
++(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)	// save ar.bspstore
++	shl r18=r18,16				// compute ar.rsc to be used for "loadrs"
++	;;
++	st8 [r16]=r31,PT(LOADRS)-PT(PR)		// save predicates
++	st8 [r17]=r28,PT(R1)-PT(B0)		// save b0
++	tnat.nz p13,p0=in5				// [I0]
++	;;
++	st8 [r16]=r18,PT(R12)-PT(LOADRS)	// save ar.rsc value for "loadrs"
++	st8.spill [r17]=r20,PT(R13)-PT(R1)	// save original r1
++(p12)	mov in4=-1
++	;;
++
++.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)	// save r12
++.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)		// save r13
++(p13)	mov in5=-1
++	;;
++	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
++	tnat.nz p14,p0=in6
++	cmp.lt p10,p9=r11,r8	// frame size can't be more than local+8
++	;;
++	stf8 [r16]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
++(p9)	tnat.nz p10,p0=r15
++	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
++
++	st8.spill [r17]=r15			// save r15
++	tnat.nz p8,p0=in7
++	nop.i 0
++
++	mov r13=r2				// establish `current'
++	movl r1=__gp				// establish kernel global pointer
++	;;
++(p14)	mov in6=-1
++(p8)	mov in7=-1
++	nop.i 0
++
++	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
++	movl r17=FPSR_DEFAULT
++	;;
++	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value
++(p10)	mov r8=-EINVAL
++	br.ret.sptk.many b7
++END(ia64_syscall_setup)
++#endif
++
++	.org ia64_ivt+0x3c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x3c00 Entry 15 (size 64 bundles) Reserved
++	DBG_FAULT(15)
++	FAULT(15)
++
++	/*
++	 * Squatting in this space ...
++	 *
++	 * This special case dispatcher for illegal operation faults allows preserved
++	 * registers to be modified through a callback function (asm only) that is handed
++	 * back from the fault handler in r8. Up to three arguments can be passed to the
++	 * callback function by returning an aggregate with the callback as its first
++	 * element, followed by the arguments.
++	 */
++ENTRY(dispatch_illegal_op_fault)
++	SAVE_MIN_WITH_COVER
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i		// guarantee that interruption collection is on
++	;;
++(p15)	ssm psr.i	// restore psr.i
++	adds r3=8,r2	// set up second base pointer for SAVE_REST
++	;;
++	alloc r14=ar.pfs,0,0,1,0	// must be first in insn group
++	mov out0=ar.ec
++	;;
++	SAVE_REST
++	;;
++	br.call.sptk.many rp=ia64_illegal_op_fault
++.ret0:	;;
++	alloc r14=ar.pfs,0,0,3,0	// must be first in insn group
++	mov out0=r9
++	mov out1=r10
++	mov out2=r11
++	movl r15=ia64_leave_kernel
++	;;
++	mov rp=r15
++	mov b6=r8
++	;;
++	cmp.ne p6,p0=0,r8
++(p6)	br.call.dpnt.many b6=b6		// call returns to ia64_leave_kernel
++	br.sptk.many ia64_leave_kernel
++END(dispatch_illegal_op_fault)
++
++	.org ia64_ivt+0x4000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x4000 Entry 16 (size 64 bundles) Reserved
++	DBG_FAULT(16)
++	FAULT(16)
++
++	.org ia64_ivt+0x4400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x4400 Entry 17 (size 64 bundles) Reserved
++	DBG_FAULT(17)
++	FAULT(17)
++
++ENTRY(non_syscall)
++	SAVE_MIN_WITH_COVER
++
++	// There is no particular reason for this code to be here, other than that
++	// there happens to be space here that would go unused otherwise.  If this
++	// fault ever gets "unreserved", simply moved the following code to a more
++	// suitable spot...
++
++	alloc r14=ar.pfs,0,0,2,0
++	mov out0=cr.iim
++	add out1=16,sp
++	adds r3=8,r2			// set up second base pointer for SAVE_REST
++
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i				// guarantee that interruption collection is on
++	;;
++(p15)	ssm psr.i			// restore psr.i
++	movl r15=ia64_leave_kernel
++	;;
++	SAVE_REST
++	mov rp=r15
++	;;
++	br.call.sptk.many b6=ia64_bad_break	// avoid WAW on CFM and ignore return addr
++END(non_syscall)
++
++	.org ia64_ivt+0x4800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x4800 Entry 18 (size 64 bundles) Reserved
++	DBG_FAULT(18)
++	FAULT(18)
++
++	/*
++	 * There is no particular reason for this code to be here, other than that
++	 * there happens to be space here that would go unused otherwise.  If this
++	 * fault ever gets "unreserved", simply moved the following code to a more
++	 * suitable spot...
++	 */
++
++ENTRY(dispatch_unaligned_handler)
++	SAVE_MIN_WITH_COVER
++	;;
++	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
++	mov out0=cr.ifa
++	adds out1=16,sp
++
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i					// guarantee that interruption collection is on
++	;;
++(p15)	ssm psr.i				// restore psr.i
++	adds r3=8,r2				// set up second base pointer
++	;;
++	SAVE_REST
++	movl r14=ia64_leave_kernel
++	;;
++	mov rp=r14
++	br.sptk.many ia64_prepare_handle_unaligned
++END(dispatch_unaligned_handler)
++
++	.org ia64_ivt+0x4c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x4c00 Entry 19 (size 64 bundles) Reserved
++	DBG_FAULT(19)
++	FAULT(19)
++
++	/*
++	 * There is no particular reason for this code to be here, other than that
++	 * there happens to be space here that would go unused otherwise.  If this
++	 * fault ever gets "unreserved", simply moved the following code to a more
++	 * suitable spot...
++	 */
++
++ENTRY(dispatch_to_fault_handler)
++	/*
++	 * Input:
++	 *	psr.ic:	off
++	 *	r19:	fault vector number (e.g., 24 for General Exception)
++	 *	r31:	contains saved predicates (pr)
++	 */
++	SAVE_MIN_WITH_COVER_R19
++	alloc r14=ar.pfs,0,0,5,0
++	mov out0=r15
++#ifdef CONFIG_XEN
++	movl out1=XSI_ISR
++	;;
++	adds out2=XSI_IFA-XSI_ISR,out1
++	adds out3=XSI_IIM-XSI_ISR,out1
++	adds out4=XSI_ITIR-XSI_ISR,out1
++	;;
++	ld8 out1=[out1]
++	ld8 out2=[out2]
++	ld8 out3=[out4]
++	ld8 out4=[out4]
++	;;
++#else
++	mov out1=cr.isr
++	mov out2=cr.ifa
++	mov out3=cr.iim
++	mov out4=cr.itir
++	;;
++#endif
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i					// guarantee that interruption collection is on
++	;;
++(p15)	ssm psr.i				// restore psr.i
++	adds r3=8,r2				// set up second base pointer for SAVE_REST
++	;;
++	SAVE_REST
++	movl r14=ia64_leave_kernel
++	;;
++	mov rp=r14
++	br.call.sptk.many b6=ia64_fault
++END(dispatch_to_fault_handler)
++
++//
++// --- End of long entries, Beginning of short entries
++//
++
++	.org ia64_ivt+0x5000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
++ENTRY(page_not_present)
++	DBG_FAULT(20)
++	mov r16=cr.ifa
++	rsm psr.dt
++	/*
++	 * The Linux page fault handler doesn't expect non-present pages to be in
++	 * the TLB.  Flush the existing entry now, so we meet that expectation.
++	 */
++	mov r17=PAGE_SHIFT<<2
++	;;
++	ptc.l r16,r17
++	;;
++	mov r31=pr
++	srlz.d
++	br.sptk.many page_fault
++END(page_not_present)
++
++	.org ia64_ivt+0x5100
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
++ENTRY(key_permission)
++	DBG_FAULT(21)
++	mov r16=cr.ifa
++	rsm psr.dt
++	mov r31=pr
++	;;
++	srlz.d
++	br.sptk.many page_fault
++END(key_permission)
++
++	.org ia64_ivt+0x5200
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
++ENTRY(iaccess_rights)
++	DBG_FAULT(22)
++	mov r16=cr.ifa
++	rsm psr.dt
++	mov r31=pr
++	;;
++	srlz.d
++	br.sptk.many page_fault
++END(iaccess_rights)
++
++	.org ia64_ivt+0x5300
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
++ENTRY(daccess_rights)
++	DBG_FAULT(23)
++#ifdef CONFIG_XEN
++	movl r16=XSI_IFA
++	;;
++	ld8 r16=[r16]
++	;;
++	XEN_HYPER_RSM_PSR_DT;
++#else
++	mov r16=cr.ifa
++	rsm psr.dt
++#endif
++	mov r31=pr
++	;;
++	srlz.d
++	br.sptk.many page_fault
++END(daccess_rights)
++
++	.org ia64_ivt+0x5400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
++ENTRY(general_exception)
++	DBG_FAULT(24)
++	mov r16=cr.isr
++	mov r31=pr
++	;;
++	cmp4.eq p6,p0=0,r16
++(p6)	br.sptk.many dispatch_illegal_op_fault
++	;;
++	mov r19=24		// fault number
++	br.sptk.many dispatch_to_fault_handler
++END(general_exception)
++
++	.org ia64_ivt+0x5500
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
++ENTRY(disabled_fp_reg)
++	DBG_FAULT(25)
++	rsm psr.dfh		// ensure we can access fph
++	;;
++	srlz.d
++	mov r31=pr
++	mov r19=25
++	br.sptk.many dispatch_to_fault_handler
++END(disabled_fp_reg)
++
++	.org ia64_ivt+0x5600
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
++ENTRY(nat_consumption)
++	DBG_FAULT(26)
++	FAULT(26)
++END(nat_consumption)
++
++	.org ia64_ivt+0x5700
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
++ENTRY(speculation_vector)
++	DBG_FAULT(27)
++	/*
++	 * A [f]chk.[as] instruction needs to take the branch to the recovery code but
++	 * this part of the architecture is not implemented in hardware on some CPUs, such
++	 * as Itanium.  Thus, in general we need to emulate the behavior.  IIM contains
++	 * the relative target (not yet sign extended).  So after sign extending it we
++	 * simply add it to IIP.  We also need to reset the EI field of the IPSR to zero,
++	 * i.e., the slot to restart into.
++	 *
++	 * cr.imm contains zero_ext(imm21)
++	 */
++	mov r18=cr.iim
++	;;
++	mov r17=cr.iip
++	shl r18=r18,43			// put sign bit in position (43=64-21)
++	;;
++
++	mov r16=cr.ipsr
++	shr r18=r18,39			// sign extend (39=43-4)
++	;;
++
++	add r17=r17,r18			// now add the offset
++	;;
++	mov cr.iip=r17
++	dep r16=0,r16,41,2		// clear EI
++	;;
++
++	mov cr.ipsr=r16
++	;;
++
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++END(speculation_vector)
++
++	.org ia64_ivt+0x5800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5800 Entry 28 (size 16 bundles) Reserved
++	DBG_FAULT(28)
++	FAULT(28)
++
++	.org ia64_ivt+0x5900
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
++ENTRY(debug_vector)
++	DBG_FAULT(29)
++	FAULT(29)
++END(debug_vector)
++
++	.org ia64_ivt+0x5a00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
++ENTRY(unaligned_access)
++	DBG_FAULT(30)
++	mov r16=cr.ipsr
++	mov r31=pr		// prepare to save predicates
++	;;
++	br.sptk.many dispatch_unaligned_handler
++END(unaligned_access)
++
++	.org ia64_ivt+0x5b00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
++ENTRY(unsupported_data_reference)
++	DBG_FAULT(31)
++	FAULT(31)
++END(unsupported_data_reference)
++
++	.org ia64_ivt+0x5c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
++ENTRY(floating_point_fault)
++	DBG_FAULT(32)
++	FAULT(32)
++END(floating_point_fault)
++
++	.org ia64_ivt+0x5d00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
++ENTRY(floating_point_trap)
++	DBG_FAULT(33)
++	FAULT(33)
++END(floating_point_trap)
++
++	.org ia64_ivt+0x5e00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
++ENTRY(lower_privilege_trap)
++	DBG_FAULT(34)
++	FAULT(34)
++END(lower_privilege_trap)
++
++	.org ia64_ivt+0x5f00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
++ENTRY(taken_branch_trap)
++	DBG_FAULT(35)
++	FAULT(35)
++END(taken_branch_trap)
++
++	.org ia64_ivt+0x6000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
++ENTRY(single_step_trap)
++	DBG_FAULT(36)
++	FAULT(36)
++END(single_step_trap)
++
++	.org ia64_ivt+0x6100
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6100 Entry 37 (size 16 bundles) Reserved
++	DBG_FAULT(37)
++	FAULT(37)
++
++	.org ia64_ivt+0x6200
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6200 Entry 38 (size 16 bundles) Reserved
++	DBG_FAULT(38)
++	FAULT(38)
++
++	.org ia64_ivt+0x6300
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6300 Entry 39 (size 16 bundles) Reserved
++	DBG_FAULT(39)
++	FAULT(39)
++
++	.org ia64_ivt+0x6400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6400 Entry 40 (size 16 bundles) Reserved
++	DBG_FAULT(40)
++	FAULT(40)
++
++	.org ia64_ivt+0x6500
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6500 Entry 41 (size 16 bundles) Reserved
++	DBG_FAULT(41)
++	FAULT(41)
++
++	.org ia64_ivt+0x6600
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6600 Entry 42 (size 16 bundles) Reserved
++	DBG_FAULT(42)
++	FAULT(42)
++
++	.org ia64_ivt+0x6700
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6700 Entry 43 (size 16 bundles) Reserved
++	DBG_FAULT(43)
++	FAULT(43)
++
++	.org ia64_ivt+0x6800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6800 Entry 44 (size 16 bundles) Reserved
++	DBG_FAULT(44)
++	FAULT(44)
++
++	.org ia64_ivt+0x6900
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
++ENTRY(ia32_exception)
++	DBG_FAULT(45)
++	FAULT(45)
++END(ia32_exception)
++
++	.org ia64_ivt+0x6a00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
++ENTRY(ia32_intercept)
++	DBG_FAULT(46)
++#ifdef	CONFIG_IA32_SUPPORT
++	mov r31=pr
++	mov r16=cr.isr
++	;;
++	extr.u r17=r16,16,8	// get ISR.code
++	mov r18=ar.eflag
++	mov r19=cr.iim		// old eflag value
++	;;
++	cmp.ne p6,p0=2,r17
++(p6)	br.cond.spnt 1f		// not a system flag fault
++	xor r16=r18,r19
++	;;
++	extr.u r17=r16,18,1	// get the eflags.ac bit
++	;;
++	cmp.eq p6,p0=0,r17
++(p6)	br.cond.spnt 1f		// eflags.ac bit didn't change
++	;;
++	mov pr=r31,-1		// restore predicate registers
++#ifdef CONFIG_XEN
++	XEN_HYPER_RFI;
++#else
++	rfi
++#endif
++
++1:
++#endif	// CONFIG_IA32_SUPPORT
++	FAULT(46)
++END(ia32_intercept)
++
++	.org ia64_ivt+0x6b00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
++ENTRY(ia32_interrupt)
++	DBG_FAULT(47)
++#ifdef CONFIG_IA32_SUPPORT
++	mov r31=pr
++	br.sptk.many dispatch_to_ia32_handler
++#else
++	FAULT(47)
++#endif
++END(ia32_interrupt)
++
++	.org ia64_ivt+0x6c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6c00 Entry 48 (size 16 bundles) Reserved
++	DBG_FAULT(48)
++	FAULT(48)
++
++	.org ia64_ivt+0x6d00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6d00 Entry 49 (size 16 bundles) Reserved
++	DBG_FAULT(49)
++	FAULT(49)
++
++	.org ia64_ivt+0x6e00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6e00 Entry 50 (size 16 bundles) Reserved
++	DBG_FAULT(50)
++	FAULT(50)
++
++	.org ia64_ivt+0x6f00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x6f00 Entry 51 (size 16 bundles) Reserved
++	DBG_FAULT(51)
++	FAULT(51)
++
++	.org ia64_ivt+0x7000
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7000 Entry 52 (size 16 bundles) Reserved
++	DBG_FAULT(52)
++	FAULT(52)
++
++	.org ia64_ivt+0x7100
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7100 Entry 53 (size 16 bundles) Reserved
++	DBG_FAULT(53)
++	FAULT(53)
++
++	.org ia64_ivt+0x7200
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7200 Entry 54 (size 16 bundles) Reserved
++	DBG_FAULT(54)
++	FAULT(54)
++
++	.org ia64_ivt+0x7300
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7300 Entry 55 (size 16 bundles) Reserved
++	DBG_FAULT(55)
++	FAULT(55)
++
++	.org ia64_ivt+0x7400
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7400 Entry 56 (size 16 bundles) Reserved
++	DBG_FAULT(56)
++	FAULT(56)
++
++	.org ia64_ivt+0x7500
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7500 Entry 57 (size 16 bundles) Reserved
++	DBG_FAULT(57)
++	FAULT(57)
++
++	.org ia64_ivt+0x7600
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7600 Entry 58 (size 16 bundles) Reserved
++	DBG_FAULT(58)
++	FAULT(58)
++
++	.org ia64_ivt+0x7700
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7700 Entry 59 (size 16 bundles) Reserved
++	DBG_FAULT(59)
++	FAULT(59)
++
++	.org ia64_ivt+0x7800
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7800 Entry 60 (size 16 bundles) Reserved
++	DBG_FAULT(60)
++	FAULT(60)
++
++	.org ia64_ivt+0x7900
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7900 Entry 61 (size 16 bundles) Reserved
++	DBG_FAULT(61)
++	FAULT(61)
++
++	.org ia64_ivt+0x7a00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7a00 Entry 62 (size 16 bundles) Reserved
++	DBG_FAULT(62)
++	FAULT(62)
++
++	.org ia64_ivt+0x7b00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7b00 Entry 63 (size 16 bundles) Reserved
++	DBG_FAULT(63)
++	FAULT(63)
++
++	.org ia64_ivt+0x7c00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7c00 Entry 64 (size 16 bundles) Reserved
++	DBG_FAULT(64)
++	FAULT(64)
++
++	.org ia64_ivt+0x7d00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7d00 Entry 65 (size 16 bundles) Reserved
++	DBG_FAULT(65)
++	FAULT(65)
++
++	.org ia64_ivt+0x7e00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7e00 Entry 66 (size 16 bundles) Reserved
++	DBG_FAULT(66)
++	FAULT(66)
++
++#ifdef CONFIG_XEN
++	/*
++	 * There is no particular reason for this code to be here, other than that
++	 * there happens to be space here that would go unused otherwise.  If this
++	 * fault ever gets "unreserved", simply moved the following code to a more
++	 * suitable spot...
++	 */
++
++GLOBAL_ENTRY(xen_bsw1)
++	/* FIXME: THIS CODE IS NOT NaT SAFE! */
++	movl r30=XSI_BANKNUM;
++	mov r31=1;;
++	st4 [r30]=r31;
++	movl r30=XSI_BANK1_R16;
++	movl r31=XSI_BANK1_R16+8;;
++	ld8 r16=[r30],16; ld8 r17=[r31],16;;
++	ld8 r18=[r30],16; ld8 r19=[r31],16;;
++	ld8 r20=[r30],16; ld8 r21=[r31],16;;
++	ld8 r22=[r30],16; ld8 r23=[r31],16;;
++	ld8 r24=[r30],16; ld8 r25=[r31],16;;
++	ld8 r26=[r30],16; ld8 r27=[r31],16;;
++	ld8 r28=[r30],16; ld8 r29=[r31],16;;
++	ld8 r30=[r30]; ld8 r31=[r31];;
++	br.ret.sptk.many b0
++#endif
++
++	.org ia64_ivt+0x7f00
++/////////////////////////////////////////////////////////////////////////////////////////
++// 0x7f00 Entry 67 (size 16 bundles) Reserved
++	DBG_FAULT(67)
++	FAULT(67)
++
++#ifdef CONFIG_IA32_SUPPORT
++
++	/*
++	 * There is no particular reason for this code to be here, other than that
++	 * there happens to be space here that would go unused otherwise.  If this
++	 * fault ever gets "unreserved", simply moved the following code to a more
++	 * suitable spot...
++	 */
++
++	// IA32 interrupt entry point
++
++ENTRY(dispatch_to_ia32_handler)
++	SAVE_MIN
++	;;
++	mov r14=cr.isr
++	ssm psr.ic | PSR_DEFAULT_BITS
++	;;
++	srlz.i					// guarantee that interruption collection is on
++	;;
++(p15)	ssm psr.i
++	adds r3=8,r2		// Base pointer for SAVE_REST
++	;;
++	SAVE_REST
++	;;
++	mov r15=0x80
++	shr r14=r14,16		// Get interrupt number
++	;;
++	cmp.ne p6,p0=r14,r15
++(p6)	br.call.dpnt.many b6=non_ia32_syscall
++
++	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
++	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
++	;;
++	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
++	ld8 r8=[r14]		// get r8
++	;;
++	st8 [r15]=r8		// save original EAX in r1 (IA32 procs don't use the GP)
++	;;
++	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
++	;;
++	ld4 r8=[r14],8		// r8 == eax (syscall number)
++	mov r15=IA32_NR_syscalls
++	;;
++	cmp.ltu.unc p6,p7=r8,r15
++	ld4 out1=[r14],8	// r9 == ecx
++	;;
++	ld4 out2=[r14],8	// r10 == edx
++	;;
++	ld4 out0=[r14]		// r11 == ebx
++	adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
++	;;
++	ld4 out5=[r14],PT(R14)-PT(R13)	// r13 == ebp
++	;;
++	ld4 out3=[r14],PT(R15)-PT(R14)	// r14 == esi
++	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
++	;;
++	ld4 out4=[r14]		// r15 == edi
++	movl r16=ia32_syscall_table
++	;;
++(p6)	shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
++	ld4 r2=[r2]		// r2 = current_thread_info()->flags
++	;;
++	ld8 r16=[r16]
++	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
++	;;
++	mov b6=r16
++	movl r15=ia32_ret_from_syscall
++	cmp.eq p8,p0=r2,r0
++	;;
++	mov rp=r15
++(p8)	br.call.sptk.many b6=b6
++	br.cond.sptk ia32_trace_syscall
++
++non_ia32_syscall:
++	alloc r15=ar.pfs,0,0,2,0
++	mov out0=r14				// interrupt #
++	add out1=16,sp				// pointer to pt_regs
++	;;			// avoid WAW on CFM
++	br.call.sptk.many rp=ia32_bad_interrupt
++.ret1:	movl r15=ia64_leave_kernel
++	;;
++	mov rp=r15
++	br.ret.sptk.many rp
++END(dispatch_to_ia32_handler)
++
++#endif /* CONFIG_IA32_SUPPORT */
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xenminstate.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xenminstate.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,367 @@
++#include <linux/config.h>
++
++#include <asm/cache.h>
++
++#ifdef CONFIG_XEN
++#include "../kernel/entry.h"
++#else
++#include "entry.h"
++#endif
++
++/*
++ * For ivt.s we want to access the stack virtually so we don't have to disable translation
++ * on interrupts.
++ *
++ *  On entry:
++ *	r1:	pointer to current task (ar.k6)
++ */
++#define MINSTATE_START_SAVE_MIN_VIRT								\
++(pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
++	;;											\
++(pUStk)	mov.m r24=ar.rnat;									\
++(pUStk)	addl r22=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
++(pKStk) mov r1=sp;					/* get sp  */				\
++	;;											\
++(pUStk) lfetch.fault.excl.nt1 [r22];								\
++(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
++(pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
++	;;											\
++(pUStk)	mov ar.bspstore=r22;				/* switch to kernel RBS */		\
++(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
++	;;											\
++(pUStk)	mov r18=ar.bsp;										\
++(pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
++
++#define MINSTATE_END_SAVE_MIN_VIRT								\
++	bsw.1;			/* switch back to bank 1 (must be last in insn group) */	\
++	;;
++
++/*
++ * For mca_asm.S we want to access the stack physically since the state is saved before we
++ * go virtual and don't want to destroy the iip or ipsr.
++ */
++#define MINSTATE_START_SAVE_MIN_PHYS								\
++(pKStk) mov r3=IA64_KR(PER_CPU_DATA);;								\
++(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
++(pKStk) ld8 r3 = [r3];;										\
++(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
++(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
++(pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
++(pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
++	;;											\
++(pUStk)	mov r24=ar.rnat;									\
++(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
++(pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
++(pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
++	;;											\
++(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
++(pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
++	;;											\
++(pUStk)	mov r18=ar.bsp;										\
++(pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
++
++#define MINSTATE_END_SAVE_MIN_PHYS								\
++	dep r12=-1,r12,61,3;		/* make sp a kernel virtual address */			\
++	;;
++
++#ifdef MINSTATE_VIRT
++# define MINSTATE_GET_CURRENT(reg)	mov reg=IA64_KR(CURRENT)
++# define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_VIRT
++# define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_VIRT
++#endif
++
++#ifdef MINSTATE_PHYS
++# define MINSTATE_GET_CURRENT(reg)	mov reg=IA64_KR(CURRENT);; tpa reg=reg
++# define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_PHYS
++# define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_PHYS
++#endif
++
++/*
++ * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
++ * the minimum state necessary that allows us to turn psr.ic back
++ * on.
++ *
++ * Assumed state upon entry:
++ *	psr.ic: off
++ *	r31:	contains saved predicates (pr)
++ *
++ * Upon exit, the state is as follows:
++ *	psr.ic: off
++ *	 r2 = points to &pt_regs.r16
++ *	 r8 = contents of ar.ccv
++ *	 r9 = contents of ar.csd
++ *	r10 = contents of ar.ssd
++ *	r11 = FPSR_DEFAULT
++ *	r12 = kernel sp (kernel virtual address)
++ *	r13 = points to current task_struct (kernel virtual address)
++ *	p15 = TRUE if psr.i is set in cr.ipsr
++ *	predicate registers (other than p2, p3, and p15), b6, r3, r14, r15:
++ *		preserved
++ * CONFIG_XEN note: p6/p7 are not preserved
++ *
++ * Note that psr.ic is NOT turned on by this macro.  This is so that
++ * we can pass interruption state as arguments to a handler.
++ */
++#ifdef CONFIG_XEN
++#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							\
++	MINSTATE_GET_CURRENT(r16);	/* M (or M;;I) */					\
++	mov r27=ar.rsc;			/* M */							\
++	mov r20=r1;			/* A */							\
++	mov r25=ar.unat;		/* M */							\
++	/* mov r29=cr.ipsr;		/* M */							\
++	movl r29=XSI_IPSR;;									\
++	ld8 r29=[r29];;										\
++	mov r26=ar.pfs;			/* I */							\
++	/* mov r28=cr.iip;		/* M */							\
++	movl r28=XSI_IIP;;									\
++	ld8 r28=[r28];;										\
++	mov r21=ar.fpsr;		/* M */							\
++	COVER;			/* B;; (or nothing) */					\
++	;;											\
++	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;						\
++	;;											\
++	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	\
++	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	\
++	adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16						\
++	/* switch from user to kernel RBS: */							\
++	;;											\
++	invala;				/* M */							\
++	/* SAVE_IFS; /* see xen special handling below */						\
++	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? */		\
++	;;											\
++	MINSTATE_START_SAVE_MIN									\
++	adds r17=2*L1_CACHE_BYTES,r1;		/* really: biggest cache-line size */		\
++	adds r16=PT(CR_IPSR),r1;								\
++	;;											\
++	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						\
++	st8 [r16]=r29;		/* save cr.ipsr */						\
++	;;											\
++	lfetch.fault.excl.nt1 [r17];								\
++	tbit.nz p15,p0=r29,IA64_PSR_I_BIT;							\
++	mov r29=b0										\
++	;;											\
++	adds r16=PT(R8),r1;	/* initialize first base pointer */				\
++	adds r17=PT(R9),r1;	/* initialize second base pointer */				\
++(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r8,16;								\
++.mem.offset 8,0; st8.spill [r17]=r9,16;								\
++        ;;											\
++.mem.offset 0,0; st8.spill [r16]=r10,24;							\
++.mem.offset 8,0; st8.spill [r17]=r11,24;							\
++        ;;											\
++	/* xen special handling for possibly lazy cover */					\
++	movl r8=XSI_INCOMPL_REGFR;								\
++	;;											\
++	ld4 r30=[r8];										\
++	;;											\
++	cmp.eq	p6,p7=r30,r0;									\
++	;; /* not sure if this stop bit is necessary */						\
++(p6)	adds r8=XSI_PRECOVER_IFS-XSI_INCOMPL_REGFR,r8;						\
++(p7)	adds r8=XSI_IFS-XSI_INCOMPL_REGFR,r8;							\
++	;;											\
++	ld8 r30=[r8];										\
++	;;											\
++	st8 [r16]=r28,16;	/* save cr.iip */						\
++	st8 [r17]=r30,16;	/* save cr.ifs */						\
++(pUStk)	sub r18=r18,r22;	/* r18=RSE.ndirty*8 */						\
++	mov r8=ar.ccv;										\
++	mov r9=ar.csd;										\
++	mov r10=ar.ssd;										\
++	movl r11=FPSR_DEFAULT;   /* L-unit */							\
++	;;											\
++	st8 [r16]=r25,16;	/* save ar.unat */						\
++	st8 [r17]=r26,16;	/* save ar.pfs */						\
++	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			\
++	;;											\
++	st8 [r16]=r27,16;	/* save ar.rsc */						\
++(pUStk)	st8 [r17]=r24,16;	/* save ar.rnat */						\
++(pKStk)	adds r17=16,r17;	/* skip over ar_rnat field */					\
++	;;			/* avoid RAW on r16 & r17 */					\
++(pUStk)	st8 [r16]=r23,16;	/* save ar.bspstore */						\
++	st8 [r17]=r31,16;	/* save predicates */						\
++(pKStk)	adds r16=16,r16;	/* skip over ar_bspstore field */				\
++	;;											\
++	st8 [r16]=r29,16;	/* save b0 */							\
++	st8 [r17]=r18,16;	/* save ar.rsc value for "loadrs" */				\
++	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r20,16;	/* save original r1 */				\
++.mem.offset 8,0; st8.spill [r17]=r12,16;							\
++	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r13,16;							\
++.mem.offset 8,0; st8.spill [r17]=r21,16;	/* save ar.fpsr */				\
++	mov r13=IA64_KR(CURRENT);	/* establish `current' */				\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r15,16;							\
++.mem.offset 8,0; st8.spill [r17]=r14,16;							\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r2,16;								\
++.mem.offset 8,0; st8.spill [r17]=r3,16;								\
++	;;											\
++	EXTRA;											\
++	mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;					\
++	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
++	;;											\
++	movl r1=__gp;		/* establish kernel global pointer */				\
++	;;											\
++	/* MINSTATE_END_SAVE_MIN */
++#else
++#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							\
++	MINSTATE_GET_CURRENT(r16);	/* M (or M;;I) */					\
++	mov r27=ar.rsc;			/* M */							\
++	mov r20=r1;			/* A */							\
++	mov r25=ar.unat;		/* M */							\
++	mov r29=cr.ipsr;		/* M */							\
++	mov r26=ar.pfs;			/* I */							\
++	mov r28=cr.iip;			/* M */							\
++	mov r21=ar.fpsr;		/* M */							\
++	COVER;				/* B;; (or nothing) */					\
++	;;											\
++	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;						\
++	;;											\
++	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	\
++	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	\
++	adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16						\
++	/* switch from user to kernel RBS: */							\
++	;;											\
++	invala;				/* M */							\
++	SAVE_IFS;										\
++	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? */		\
++	;;											\
++	MINSTATE_START_SAVE_MIN									\
++	adds r17=2*L1_CACHE_BYTES,r1;		/* really: biggest cache-line size */		\
++	adds r16=PT(CR_IPSR),r1;								\
++	;;											\
++	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						\
++	st8 [r16]=r29;		/* save cr.ipsr */						\
++	;;											\
++	lfetch.fault.excl.nt1 [r17];								\
++	tbit.nz p15,p0=r29,IA64_PSR_I_BIT;							\
++	mov r29=b0										\
++	;;											\
++	adds r16=PT(R8),r1;	/* initialize first base pointer */				\
++	adds r17=PT(R9),r1;	/* initialize second base pointer */				\
++(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r8,16;								\
++.mem.offset 8,0; st8.spill [r17]=r9,16;								\
++        ;;											\
++.mem.offset 0,0; st8.spill [r16]=r10,24;							\
++.mem.offset 8,0; st8.spill [r17]=r11,24;							\
++        ;;											\
++	st8 [r16]=r28,16;	/* save cr.iip */						\
++	st8 [r17]=r30,16;	/* save cr.ifs */						\
++(pUStk)	sub r18=r18,r22;	/* r18=RSE.ndirty*8 */						\
++	mov r8=ar.ccv;										\
++	mov r9=ar.csd;										\
++	mov r10=ar.ssd;										\
++	movl r11=FPSR_DEFAULT;   /* L-unit */							\
++	;;											\
++	st8 [r16]=r25,16;	/* save ar.unat */						\
++	st8 [r17]=r26,16;	/* save ar.pfs */						\
++	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			\
++	;;											\
++	st8 [r16]=r27,16;	/* save ar.rsc */						\
++(pUStk)	st8 [r17]=r24,16;	/* save ar.rnat */						\
++(pKStk)	adds r17=16,r17;	/* skip over ar_rnat field */					\
++	;;			/* avoid RAW on r16 & r17 */					\
++(pUStk)	st8 [r16]=r23,16;	/* save ar.bspstore */						\
++	st8 [r17]=r31,16;	/* save predicates */						\
++(pKStk)	adds r16=16,r16;	/* skip over ar_bspstore field */				\
++	;;											\
++	st8 [r16]=r29,16;	/* save b0 */							\
++	st8 [r17]=r18,16;	/* save ar.rsc value for "loadrs" */				\
++	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r20,16;	/* save original r1 */				\
++.mem.offset 8,0; st8.spill [r17]=r12,16;							\
++	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r13,16;							\
++.mem.offset 8,0; st8.spill [r17]=r21,16;	/* save ar.fpsr */				\
++	mov r13=IA64_KR(CURRENT);	/* establish `current' */				\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r15,16;							\
++.mem.offset 8,0; st8.spill [r17]=r14,16;							\
++	;;											\
++.mem.offset 0,0; st8.spill [r16]=r2,16;								\
++.mem.offset 8,0; st8.spill [r17]=r3,16;								\
++	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
++	;;											\
++	EXTRA;											\
++	movl r1=__gp;		/* establish kernel global pointer */				\
++	;;											\
++	MINSTATE_END_SAVE_MIN
++#endif
++
++/*
++ * SAVE_REST saves the remainder of pt_regs (with psr.ic on).
++ *
++ * Assumed state upon entry:
++ *	psr.ic: on
++ *	r2:	points to &pt_regs.r16
++ *	r3:	points to &pt_regs.r17
++ *	r8:	contents of ar.ccv
++ *	r9:	contents of ar.csd
++ *	r10:	contents of ar.ssd
++ *	r11:	FPSR_DEFAULT
++ *
++ * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST.
++ */
++#define SAVE_REST				\
++.mem.offset 0,0; st8.spill [r2]=r16,16;		\
++.mem.offset 8,0; st8.spill [r3]=r17,16;		\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r18,16;		\
++.mem.offset 8,0; st8.spill [r3]=r19,16;		\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r20,16;		\
++.mem.offset 8,0; st8.spill [r3]=r21,16;		\
++	mov r18=b6;				\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r22,16;		\
++.mem.offset 8,0; st8.spill [r3]=r23,16;		\
++	mov r19=b7;				\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r24,16;		\
++.mem.offset 8,0; st8.spill [r3]=r25,16;		\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r26,16;		\
++.mem.offset 8,0; st8.spill [r3]=r27,16;		\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r28,16;		\
++.mem.offset 8,0; st8.spill [r3]=r29,16;		\
++	;;					\
++.mem.offset 0,0; st8.spill [r2]=r30,16;		\
++.mem.offset 8,0; st8.spill [r3]=r31,32;		\
++	;;					\
++	mov ar.fpsr=r11;	/* M-unit */	\
++	st8 [r2]=r8,8;		/* ar.ccv */	\
++	adds r24=PT(B6)-PT(F7),r3;		\
++	;;					\
++	stf.spill [r2]=f6,32;			\
++	stf.spill [r3]=f7,32;			\
++	;;					\
++	stf.spill [r2]=f8,32;			\
++	stf.spill [r3]=f9,32;			\
++	;;					\
++	stf.spill [r2]=f10;			\
++	stf.spill [r3]=f11;			\
++	adds r25=PT(B7)-PT(F11),r3;		\
++	;;					\
++	st8 [r24]=r18,16;       /* b6 */	\
++	st8 [r25]=r19,16;       /* b7 */	\
++	;;					\
++	st8 [r24]=r9;        	/* ar.csd */	\
++	st8 [r25]=r10;      	/* ar.ssd */	\
++	;;
++
++#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov r30=cr.ifs,)
++#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19)
++#ifdef CONFIG_XEN
++#define SAVE_MIN		break 0;; /* FIXME: non-cover version only for ia32 support? */
++#else
++#define SAVE_MIN		DO_SAVE_MIN(     , mov r30=r0, )
++#endif
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xenpal.S
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xenpal.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,73 @@
++/*
++ * ia64/xen/xenpal.S
++ *
++ * Alternate PAL  routines for Xen.  Heavily leveraged from
++ *   ia64/kernel/pal.S
++ *
++ * Copyright (C) 2005 Hewlett-Packard Co
++ *	Dan Magenheimer <dan.magenheimer at .hp.com>
++ */
++
++#include <asm/asmmacro.h>
++#include <asm/processor.h>
++
++GLOBAL_ENTRY(xen_pal_call_static)
++	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
++	alloc loc1 = ar.pfs,5,5,0,0
++#ifdef CONFIG_XEN
++	movl r22=running_on_xen;;
++	ld4 r22=[r22];;
++	cmp.eq p7,p0=r22,r0
++(p7)	br.cond.spnt.many __ia64_pal_call_static;;
++#endif
++	movl loc2 = pal_entry_point
++1:	{
++	  mov r28 = in0
++	  mov r29 = in1
++	  mov r8 = ip
++	}
++	;;
++	ld8 loc2 = [loc2]		// loc2 <- entry point
++	tbit.nz p6,p7 = in4, 0
++	adds r8 = 1f-1b,r8
++	mov loc4=ar.rsc			// save RSE configuration
++	;;
++	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
++	mov loc3 = psr
++	mov loc0 = rp
++	.body
++	mov r30 = in2
++
++#ifdef CONFIG_XEN
++	// this is low priority for paravirtualization, but is called
++	// from the idle loop so confuses privop counting
++	movl r31=XSI_PSR_IC
++	;;
++(p6)	st8 [r31]=r0
++	;;
++(p7)	adds r31=XSI_PSR_I-XSI_PSR_IC,r31
++	;;
++(p7)	st4 [r31]=r0
++	;;
++	mov r31 = in3
++	mov b7 = loc2
++	;;
++#else
++(p6)	rsm psr.i | psr.ic
++	mov r31 = in3
++	mov b7 = loc2
++
++(p7)	rsm psr.i
++	;;
++(p6)	srlz.i
++#endif
++	mov rp = r8
++	br.cond.sptk.many b7
++1:	mov psr.l = loc3
++	mov ar.rsc = loc4		// restore RSE configuration
++	mov ar.pfs = loc1
++	mov rp = loc0
++	;;
++	srlz.d				// seralize restoration of psr.l
++	br.ret.sptk.many b0
++END(xen_pal_call_static)
+diff -r c75ede70c907 -r f6bd46559b93 arch/ia64/xen/xensetup.S
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/arch/ia64/xen/xensetup.S	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,35 @@
++/*
++ * Support routines for Xen
++ *
++ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer at hp.com>
++ */
++
++#include <linux/config.h>
++#include <asm/processor.h>
++#include <asm/asmmacro.h>
++
++	.data
++	.align 8
++	.globl running_on_xen
++running_on_xen:
++	data4 0
++
++#define isBP	p3	// are we the Bootstrap Processor?
++
++	.text
++GLOBAL_ENTRY(early_xen_setup)
++	mov r8=cr.dcr
++(isBP)	movl r9=running_on_xen;;
++	extr.u r8=r8,63,1;;
++	cmp.ne p7,p0=r8,r0;;
++(isBP)	st4 [r9]=r8
++(p7)	movl r10=xen_ivt;;
++(p7)	mov cr.iva=r10
++	br.ret.sptk.many rp;;
++END(early_xen_setup)
++
++GLOBAL_ENTRY(is_running_on_xen)
++	movl r9=running_on_xen;;
++	ld4 r8=[r9]
++	br.ret.sptk.many rp;;
++END(is_running_on_xen)
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/fixmap.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/include/asm-ia64/fixmap.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,2 @@
++#define clear_fixmap(x)	do {} while (0)
++#define	set_fixmap(x,y)	do {} while (0)
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/hypercall.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/include/asm-ia64/hypercall.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,253 @@
++/******************************************************************************
++ * hypercall.h
++ * 
++ * Linux-specific hypervisor handling.
++ * 
++ * Copyright (c) 2002-2004, K A Fraser
++ * 
++ * This file may be distributed separately from the Linux kernel, or
++ * incorporated into other software packages, subject to the following license:
++ * 
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this source file (the "Software"), to deal in the Software without
++ * restriction, including without limitation the rights to use, copy, modify,
++ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ * 
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ * 
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
++ */
++
++#ifndef __HYPERCALL_H__
++#define __HYPERCALL_H__
++
++#include <xen/interface/xen.h>
++#include <xen/interface/sched.h>
++
++/* FIXME: temp place to hold these page related macros */
++#include <asm/page.h>
++#define virt_to_machine(v) __pa(v)
++#define machine_to_virt(m) __va(m)
++#define virt_to_mfn(v)	((__pa(v)) >> PAGE_SHIFT)
++#define mfn_to_virt(m)	(__va((m) << PAGE_SHIFT))
++
++/*
++ * Assembler stubs for hyper-calls.
++ */
++
++#define _hypercall0(type, name)					\
++({								\
++	long __res;						\
++	__asm__ __volatile__ (";;\n"				\
++			      "mov r2=%1\n"			\
++			      "break 0x1000 ;;\n"		\
++			      "mov %0=r8 ;;\n"			\
++			      : "=r" (__res)			\
++			      : "i" (__HYPERVISOR_##name)	\
++			      : "r2","r8",			\
++			        "memory" );			\
++	(type)__res;						\
++})
++
++#define _hypercall1(type, name, a1)				\
++({								\
++	long __res;						\
++	__asm__ __volatile__ (";;\n"				\
++			      "mov r14=%2\n"			\
++			      "mov r2=%1\n"			\
++			      "break 0x1000 ;;\n"		\
++			      "mov %0=r8 ;;\n"			\
++			      : "=r" (__res)			\
++			      : "i" (__HYPERVISOR_##name),	\
++				"r" ((unsigned long)(a1))	\
++			      : "r14","r2","r8",		\
++				"memory" );			\
++	(type)__res;						\
++})
++
++#define _hypercall2(type, name, a1, a2)				\
++({								\
++	long __res;						\
++	__asm__ __volatile__ (";;\n"				\
++			      "mov r14=%2\n"			\
++			      "mov r15=%3\n"			\
++			      "mov r2=%1\n"			\
++			      "break 0x1000 ;;\n"		\
++			      "mov %0=r8 ;;\n"			\
++			      : "=r" (__res)			\
++			      : "i" (__HYPERVISOR_##name),	\
++				"r" ((unsigned long)(a1)),	\
++				"r" ((unsigned long)(a2))	\
++			      : "r14","r15","r2","r8",		\
++				"memory" );			\
++	(type)__res;						\
++})
++
++#define _hypercall3(type, name, a1, a2, a3)			\
++({								\
++	long __res;						\
++	__asm__ __volatile__ (";;\n"                            \
++			      "mov r14=%2\n"                    \
++			      "mov r15=%3\n"                    \
++			      "mov r16=%4\n"                    \
++			      "mov r2=%1\n"                     \
++			      "break 0x1000 ;;\n"               \
++			      "mov %0=r8 ;;\n"                  \
++			      : "=r" (__res)                    \
++			      : "i" (__HYPERVISOR_##name),      \
++				"r" ((unsigned long)(a1)),	\
++				"r" ((unsigned long)(a2)),	\
++				"r" ((unsigned long)(a3))	\
++			      : "r14","r15","r16","r2","r8",	\
++			        "memory" );                     \
++	(type)__res;                                            \
++})
++
++#define _hypercall4(type, name, a1, a2, a3, a4)			\
++({								\
++	long __res;						\
++	__asm__ __volatile__ (";;\n"                            \
++			      "mov r14=%2\n"                    \
++			      "mov r15=%3\n"                    \
++			      "mov r16=%4\n"                    \
++			      "mov r17=%5\n"                    \
++			      "mov r2=%1\n"                     \
++			      "break 0x1000 ;;\n"               \
++			      "mov %0=r8 ;;\n"                  \
++			      : "=r" (__res)                    \
++			      : "i" (__HYPERVISOR_##name),      \
++				"r" ((unsigned long)(a1)),	\
++				"r" ((unsigned long)(a2)),	\
++				"r" ((unsigned long)(a3)),	\
++				"r" ((unsigned long)(a4))       \
++			      : "r14","r15","r16","r2","r8",	\
++			        "r17","memory" );               \
++	(type)__res;                                            \
++})
++
++#define _hypercall5(type, name, a1, a2, a3, a4, a5)		\
++({								\
++	long __res;						\
++	__asm__ __volatile__ (";;\n"                            \
++			      "mov r14=%2\n"                    \
++			      "mov r15=%3\n"                    \
++			      "mov r16=%4\n"                    \
++			      "mov r17=%5\n"                    \
++			      "mov r18=%6\n"                    \
++			      "mov r2=%1\n"                     \
++			      "break 0x1000 ;;\n"               \
++			      "mov %0=r8 ;;\n"                  \
++			      : "=r" (__res)                    \
++			      : "i" (__HYPERVISOR_##name),      \
++				"r" ((unsigned long)(a1)),	\
++				"r" ((unsigned long)(a2)),	\
++				"r" ((unsigned long)(a3)),	\
++				"r" ((unsigned long)(a4)),	\
++				"r" ((unsigned long)(a5))       \
++			      : "r14","r15","r16","r2","r8",	\
++			        "r17","r18","memory" );         \
++	(type)__res;                                            \
++})
++
++static inline int
++HYPERVISOR_sched_op(
++    int cmd, unsigned long arg)
++{
++	return _hypercall2(int, sched_op, cmd, arg);
++}
++
++static inline long
++HYPERVISOR_set_timer_op(
++    u64 timeout)
++{
++    unsigned long timeout_hi = (unsigned long)(timeout>>32);
++    unsigned long timeout_lo = (unsigned long)timeout;
++    return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
++}
++
++static inline int
++HYPERVISOR_dom0_op(
++    dom0_op_t *dom0_op)
++{
++    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
++    return _hypercall1(int, dom0_op, dom0_op);
++}
++
++static inline int
++HYPERVISOR_multicall(
++    void *call_list, int nr_calls)
++{
++    return _hypercall2(int, multicall, call_list, nr_calls);
++}
++
++static inline int
++HYPERVISOR_memory_op(
++    unsigned int cmd, void *arg)
++{
++    return _hypercall2(int, memory_op, cmd, arg);
++}
++
++static inline int
++HYPERVISOR_event_channel_op(
++    void *op)
++{
++    return _hypercall1(int, event_channel_op, op);
++}
++
++static inline int
++HYPERVISOR_xen_version(
++    int cmd, void *arg)
++{
++    return _hypercall2(int, xen_version, cmd, arg);
++}
++
++static inline int
++HYPERVISOR_console_io(
++    int cmd, int count, char *str)
++{
++    return _hypercall3(int, console_io, cmd, count, str);
++}
++
++static inline int
++HYPERVISOR_physdev_op(
++    void *physdev_op)
++{
++    return _hypercall1(int, physdev_op, physdev_op);
++}
++
++static inline int
++HYPERVISOR_grant_table_op(
++    unsigned int cmd, void *uop, unsigned int count)
++{
++    return _hypercall3(int, grant_table_op, cmd, uop, count);
++}
++
++static inline int
++HYPERVISOR_vcpu_op(
++	int cmd, int vcpuid, void *extra_args)
++{
++    return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
++}
++
++static inline int
++HYPERVISOR_suspend(
++	unsigned long srec)
++{
++    return _hypercall3(int, sched_op, SCHEDOP_shutdown,
++			SHUTDOWN_suspend, srec);
++}
++
++extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
++static inline void exit_idle(void) {}
++#define do_IRQ(irq, regs) __do_IRQ((irq), (regs))
++
++#endif /* __HYPERCALL_H__ */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/hypervisor.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/include/asm-ia64/hypervisor.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,70 @@
++/******************************************************************************
++ * hypervisor.h
++ * 
++ * Linux-specific hypervisor handling.
++ * 
++ * Copyright (c) 2002-2004, K A Fraser
++ * 
++ * This file may be distributed separately from the Linux kernel, or
++ * incorporated into other software packages, subject to the following license:
++ * 
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this source file (the "Software"), to deal in the Software without
++ * restriction, including without limitation the rights to use, copy, modify,
++ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ * 
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ * 
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
++ */
++
++#ifndef __HYPERVISOR_H__
++#define __HYPERVISOR_H__
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/version.h>
++#include <xen/interface/xen.h>
++#include <xen/interface/dom0_ops.h>
++#include <asm/ptrace.h>
++#include <asm/page.h>
++
++extern shared_info_t *HYPERVISOR_shared_info;
++extern start_info_t *xen_start_info;
++
++void force_evtchn_callback(void);
++
++#include <asm/hypercall.h>
++
++// for drivers/xen/privcmd/privcmd.c
++#define direct_remap_pfn_range(a,b,c,d,e,f) remap_pfn_range(a,b,c,d,e)
++#define	pfn_to_mfn(x)	(x)
++#define	mfn_to_pfn(x)	(x)
++#define machine_to_phys_mapping 0
++
++// for drivers/xen/balloon/balloon.c
++#ifdef CONFIG_XEN_SCRUB_PAGES
++#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
++#else
++#define scrub_pages(_p,_n) ((void)0)
++#endif
++#define	pte_mfn(_x)	pte_pfn(_x)
++#define INVALID_P2M_ENTRY	(~0UL)
++#define __pte_ma(_x)	((pte_t) {(_x)})
++#define phys_to_machine_mapping_valid(_x)	(1)
++#define	kmap_flush_unused()	do {} while (0)
++#define set_phys_to_machine(_x,_y)	do {} while (0)
++#define xen_machphys_update(_x,_y)	do {} while (0)
++#define pfn_pte_ma(_x,_y)	__pte_ma(0)
++
++#endif /* __HYPERVISOR_H__ */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/privop.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/include/asm-ia64/privop.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,59 @@
++#ifndef _ASM_IA64_PRIVOP_H
++#define _ASM_IA64_PRIVOP_H
++
++/*
++ * Copyright (C) 2005 Hewlett-Packard Co
++ *	Dan Magenheimer <dan.magenheimer at hp.com>
++ *
++ */
++
++#include <linux/config.h>
++#ifdef CONFIG_XEN
++#include <asm/xen/privop.h>
++#endif
++
++#ifndef __ASSEMBLY
++
++#ifndef IA64_PARAVIRTUALIZED
++
++#define ia64_getreg			__ia64_getreg
++#define ia64_setreg			__ia64_setreg
++#define ia64_hint			__ia64_hint
++#define ia64_thash			__ia64_thash
++#define ia64_itci			__ia64_itci
++#define ia64_itcd			__ia64_itcd
++#define ia64_itri			__ia64_itri
++#define ia64_itrd			__ia64_itrd
++#define ia64_tpa			__ia64_tpa
++#define ia64_set_ibr			__ia64_set_ibr
++#define ia64_set_pkr			__ia64_set_pkr
++#define ia64_set_pmc			__ia64_set_pmc
++#define ia64_set_pmd			__ia64_set_pmd
++#define ia64_set_rr			__ia64_set_rr
++#define ia64_get_cpuid			__ia64_get_cpuid
++#define ia64_get_ibr			__ia64_get_ibr
++#define ia64_get_pkr			__ia64_get_pkr
++#define ia64_get_pmc			__ia64_get_pmc
++#define ia64_get_pmd			__ia64_get_pmd
++#define ia64_get_rr			__ia64_get_rr
++#define ia64_fc				__ia64_fc
++#define ia64_ssm			__ia64_ssm
++#define ia64_rsm			__ia64_rsm
++#define ia64_ptce			__ia64_ptce
++#define ia64_ptcga			__ia64_ptcga
++#define ia64_ptcl			__ia64_ptcl
++#define ia64_ptri			__ia64_ptri
++#define ia64_ptrd			__ia64_ptrd
++#define	ia64_get_psr_i			__ia64_get_psr_i
++#define ia64_intrin_local_irq_restore	__ia64_intrin_local_irq_restore
++#define ia64_pal_halt_light		__ia64_pal_halt_light
++#define	ia64_leave_kernel		__ia64_leave_kernel
++#define	ia64_leave_syscall		__ia64_leave_syscall
++#define	ia64_switch_to			__ia64_switch_to
++#define	ia64_pal_call_static		__ia64_pal_call_static
++
++#endif /* !IA64_PARAVIRTUALIZED */
++
++#endif /* !__ASSEMBLY */
++
++#endif /* _ASM_IA64_PRIVOP_H */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/synch_bitops.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/include/asm-ia64/synch_bitops.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,61 @@
++#ifndef __XEN_SYNCH_BITOPS_H__
++#define __XEN_SYNCH_BITOPS_H__
++
++/*
++ * Copyright 1992, Linus Torvalds.
++ * Heavily modified to provide guaranteed strong synchronisation
++ * when communicating with Xen or other guest OSes running on other CPUs.
++ */
++
++#include <linux/config.h>
++
++#define ADDR (*(volatile long *) addr)
++
++static __inline__ void synch_set_bit(int nr, volatile void * addr)
++{
++	set_bit(nr, addr);
++}
++
++static __inline__ void synch_clear_bit(int nr, volatile void * addr)
++{
++	clear_bit(nr, addr);
++}
++
++static __inline__ void synch_change_bit(int nr, volatile void * addr)
++{
++	change_bit(nr, addr);
++}
++
++static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
++{
++    return test_and_set_bit(nr, addr);
++}
++
++static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
++{
++    return test_and_clear_bit(nr, addr);
++}
++
++static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr)
++{
++    return test_and_change_bit(nr, addr);
++}
++
++static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
++{
++    return test_bit(nr, addr);
++}
++
++static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
++{
++    return test_bit(nr, addr);
++}
++
++#define synch_cmpxchg	ia64_cmpxchg4_acq
++
++#define synch_test_bit(nr,addr) \
++(__builtin_constant_p(nr) ? \
++ synch_const_test_bit((nr),(addr)) : \
++ synch_var_test_bit((nr),(addr)))
++
++#endif /* __XEN_SYNCH_BITOPS_H__ */
+diff -r c75ede70c907 -r f6bd46559b93 include/asm-ia64/xen/privop.h
+--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
++++ b/include/asm-ia64/xen/privop.h	Mon Mar  6 17:57:34 2006 +0000
+@@ -0,0 +1,272 @@
++#ifndef _ASM_IA64_XEN_PRIVOP_H
++#define _ASM_IA64_XEN_PRIVOP_H
++
++/*
++ * Copyright (C) 2005 Hewlett-Packard Co
++ *	Dan Magenheimer <dan.magenheimer at hp.com>
++ *
++ * Paravirtualizations of privileged operations for Xen/ia64
++ *
++ */
++
++
++#include <asm/xen/asm-xsi-offsets.h>
++
++#define IA64_PARAVIRTUALIZED
++
++#ifdef __ASSEMBLY__
++#define	XEN_HYPER_RFI			break 0x1
++#define	XEN_HYPER_RSM_PSR_DT		break 0x2
++#define	XEN_HYPER_SSM_PSR_DT		break 0x3
++#define	XEN_HYPER_COVER			break 0x4
++#define	XEN_HYPER_ITC_D			break 0x5
++#define	XEN_HYPER_ITC_I			break 0x6
++#define	XEN_HYPER_SSM_I			break 0x7
++#define	XEN_HYPER_GET_IVR		break 0x8
++#define	XEN_HYPER_GET_TPR		break 0x9
++#define	XEN_HYPER_SET_TPR		break 0xa
++#define	XEN_HYPER_EOI			break 0xb
++#define	XEN_HYPER_SET_ITM		break 0xc
++#define	XEN_HYPER_THASH			break 0xd
++#define	XEN_HYPER_PTC_GA		break 0xe
++#define	XEN_HYPER_ITR_D			break 0xf
++#define	XEN_HYPER_GET_RR		break 0x10
++#define	XEN_HYPER_SET_RR		break 0x11
++#define	XEN_HYPER_SET_KR		break 0x12
++#endif
++
++#ifndef __ASSEMBLY__
++#ifdef MODULE
++extern int is_running_on_xen(void);
++#define running_on_xen (is_running_on_xen())
++#else
++extern int running_on_xen;
++#endif
++
++#define	XEN_HYPER_SSM_I			asm("break 0x7");
++#define	XEN_HYPER_GET_IVR		asm("break 0x8");
++
++/************************************************/
++/* Instructions paravirtualized for correctness */
++/************************************************/
++
++/* "fc" and "thash" are privilege-sensitive instructions, meaning they
++ *  may have different semantics depending on whether they are executed
++ *  at PL0 vs PL!=0.  When paravirtualized, these instructions mustn't
++ *  be allowed to execute directly, lest incorrect semantics result. */
++extern unsigned long xen_fc(unsigned long addr);
++#define ia64_fc(addr)			xen_fc((unsigned long)(addr))
++extern unsigned long xen_thash(unsigned long addr);
++#define ia64_thash(addr)		xen_thash((unsigned long)(addr))
++/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
++ * is not currently used (though it may be in a long-format VHPT system!)
++ * and the semantics of cover only change if psr.ic is off which is very
++ * rare (and currently non-existent outside of assembly code */
++
++/* There are also privilege-sensitive registers.  These registers are
++ * readable at any privilege level but only writable at PL0. */
++extern unsigned long xen_get_cpuid(int index);
++#define	ia64_get_cpuid(i)		xen_get_cpuid(i)
++extern unsigned long xen_get_pmd(int index);
++#define	ia64_get_pmd(i)			xen_get_pmd(i)
++extern unsigned long xen_get_eflag(void);	/* see xen_ia64_getreg */
++extern void xen_set_eflag(unsigned long);	/* see xen_ia64_setreg */
++
++/************************************************/
++/* Instructions paravirtualized for performance */
++/************************************************/
++
++/* Xen uses memory-mapped virtual privileged registers for access to many
++ * performance-sensitive privileged registers.  Some, like the processor
++ * status register (psr), are broken up into multiple memory locations.
++ * Others, like "pend", are abstractions based on privileged registers.
++ * "Pend" is guaranteed to be set if reading cr.ivr would return a
++ * (non-spurious) interrupt. */
++#define xen_get_virtual_psr_i()		(*(int *)(XSI_PSR_I))
++#define xen_set_virtual_psr_i(_val)	({ *(int *)(XSI_PSR_I) = _val ? 1:0; })
++#define xen_set_virtual_psr_ic(_val)	({ *(int *)(XSI_PSR_IC) = _val ? 1:0; })
++#define xen_get_virtual_pend()		(*(int *)(XSI_PEND))
++
++/* Hyperprivops are "break" instructions with a well-defined API.
++ * In particular, the virtual psr.ic bit must be off; in this way
++ * it is guaranteed to never conflict with a linux break instruction.
++ * Normally, this is done in a xen stub but this one is frequent enough
++ * that we inline it */
++#define xen_hyper_ssm_i()						\
++({									\
++	xen_set_virtual_psr_i(0);					\
++	xen_set_virtual_psr_ic(0);					\
++	XEN_HYPER_SSM_I;						\
++})
++
++/* turning off interrupts can be paravirtualized simply by writing
++ * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
++#define xen_rsm_i()	xen_set_virtual_psr_i(0)
++
++/* turning on interrupts is a bit more complicated.. write to the
++ * memory-mapped virtual psr.i bit first (to avoid race condition),
++ * then if any interrupts were pending, we have to execute a hyperprivop
++ * to ensure the pending interrupt gets delivered; else we're done! */
++#define xen_ssm_i()							\
++({									\
++	int old = xen_get_virtual_psr_i();				\
++	xen_set_virtual_psr_i(1);					\
++	if (!old && xen_get_virtual_pend()) xen_hyper_ssm_i();		\
++})
++
++#define xen_ia64_intrin_local_irq_restore(x)				\
++{									\
++     if (running_on_xen) {						\
++	if ((x) & IA64_PSR_I) { xen_ssm_i(); }				\
++	else { xen_rsm_i(); }						\
++    }									\
++    else __ia64_intrin_local_irq_restore((x));				\
++}
++
++#define	xen_get_psr_i()							\
++(									\
++	(running_on_xen) ?						\
++		(xen_get_virtual_psr_i() ? IA64_PSR_I : 0)		\
++		: __ia64_get_psr_i()					\
++)
++
++#define xen_ia64_ssm(mask)						\
++{									\
++	if ((mask)==IA64_PSR_I) {					\
++		if (running_on_xen) { xen_ssm_i(); }			\
++		else { __ia64_ssm(mask); }				\
++	}								\
++	else { __ia64_ssm(mask); }					\
++}
++
++#define xen_ia64_rsm(mask)						\
++{									\
++	if ((mask)==IA64_PSR_I) {					\
++		if (running_on_xen) { xen_rsm_i(); }			\
++		else { __ia64_rsm(mask); }				\
++	}								\
++	else { __ia64_rsm(mask); }					\
++}
++
++
++/* Although all privileged operations can be left to trap and will
++ * be properly handled by Xen, some are frequent enough that we use
++ * hyperprivops for performance. */
++
++extern unsigned long xen_get_ivr(void);
++extern unsigned long xen_get_tpr(void);
++extern void xen_set_itm(unsigned long);
++extern void xen_set_tpr(unsigned long);
++extern void xen_eoi(void);
++extern void xen_set_rr(unsigned long index, unsigned long val);
++extern unsigned long xen_get_rr(unsigned long index);
++extern void xen_set_kr(unsigned long index, unsigned long val);
++
++/* Note: It may look wrong to test for running_on_xen in each case.
++ * However regnum is always a constant so, as written, the compiler
++ * eliminates the switch statement, whereas running_on_xen must be
++ * tested dynamically. */
++#define xen_ia64_getreg(regnum)						\
++({									\
++	__u64 ia64_intri_res;						\
++									\
++	switch(regnum) {						\
++	case _IA64_REG_CR_IVR:						\
++		ia64_intri_res = (running_on_xen) ?			\
++			xen_get_ivr() :					\
++			__ia64_getreg(regnum);				\
++		break;							\
++	case _IA64_REG_CR_TPR:						\
++		ia64_intri_res = (running_on_xen) ?			\
++			xen_get_tpr() :					\
++			__ia64_getreg(regnum);				\
++		break;							\
++	case _IA64_REG_AR_EFLAG:					\
++		ia64_intri_res = (running_on_xen) ?			\
++			xen_get_eflag() :				\
++			__ia64_getreg(regnum);				\
++		break;							\
++	default:							\
++		ia64_intri_res = __ia64_getreg(regnum);			\
++		break;							\
++	}								\
++	ia64_intri_res;							\
++})
++
++#define xen_ia64_setreg(regnum,val)					\
++({									\
++	switch(regnum) {						\
++	case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:			\
++		(running_on_xen) ?					\
++			xen_set_kr((regnum-_IA64_REG_AR_KR0), val) :	\
++			__ia64_setreg(regnum,val);			\
++		break;							\
++	case _IA64_REG_CR_ITM:						\
++		(running_on_xen) ?					\
++			xen_set_itm(val) :				\
++			__ia64_setreg(regnum,val);			\
++		break;							\
++	case _IA64_REG_CR_TPR:						\
++		(running_on_xen) ?					\
++			xen_set_tpr(val) :				\
++			__ia64_setreg(regnum,val);			\
++		break;							\
++	case _IA64_REG_CR_EOI:						\
++		(running_on_xen) ?					\
++			xen_eoi() :					\
++			__ia64_setreg(regnum,val);			\
++		break;							\
++	case _IA64_REG_AR_EFLAG:					\
++		(running_on_xen) ?					\
++			xen_set_eflag(val) :				\
++			__ia64_setreg(regnum,val);			\
++		break;							\
++	default:							\
++		__ia64_setreg(regnum,val);				\
++		break;							\
++	}								\
++})
++
++#define ia64_ssm			xen_ia64_ssm
++#define ia64_rsm			xen_ia64_rsm
++#define ia64_intrin_local_irq_restore	xen_ia64_intrin_local_irq_restore
++#define	ia64_ptcga			xen_ptcga
++#define	ia64_set_rr(index,val)		xen_set_rr(index,val)
++#define	ia64_get_rr(index)		xen_get_rr(index)
++#define ia64_getreg			xen_ia64_getreg
++#define ia64_setreg			xen_ia64_setreg
++#define	ia64_get_psr_i			xen_get_psr_i
++
++/* the remainder of these are not performance-sensitive so its
++ * OK to not paravirtualize and just take a privop trap and emulate */
++#define ia64_hint			__ia64_hint
++#define ia64_set_pmd			__ia64_set_pmd
++#define ia64_itci			__ia64_itci
++#define ia64_itcd			__ia64_itcd
++#define ia64_itri			__ia64_itri
++#define ia64_itrd			__ia64_itrd
++#define ia64_tpa			__ia64_tpa
++#define ia64_set_ibr			__ia64_set_ibr
++#define ia64_set_pkr			__ia64_set_pkr
++#define ia64_set_pmc			__ia64_set_pmc
++#define ia64_get_ibr			__ia64_get_ibr
++#define ia64_get_pkr			__ia64_get_pkr
++#define ia64_get_pmc			__ia64_get_pmc
++#define ia64_ptce			__ia64_ptce
++#define ia64_ptcl			__ia64_ptcl
++#define ia64_ptri			__ia64_ptri
++#define ia64_ptrd			__ia64_ptrd
++
++#endif /* !__ASSEMBLY__ */
++
++/* these routines utilize privilege-sensitive or performance-sensitive
++ * privileged instructions so the code must be replaced with
++ * paravirtualized versions */
++#define ia64_pal_halt_light		xen_pal_halt_light
++#define	ia64_leave_kernel		xen_leave_kernel
++#define	ia64_leave_syscall		xen_leave_syscall
++#define	ia64_trace_syscall		xen_trace_syscall
++#define	ia64_switch_to			xen_switch_to
++#define	ia64_pal_call_static		xen_pal_call_static
++
++#endif /* _ASM_IA64_XEN_PRIVOP_H */
+diff -r c75ede70c907 -r f6bd46559b93 include/xen/public/xenstored.h
+--- a/include/xen/public/xenstored.h	Mon Feb 27 15:43:34 2006 +0000
++++ /dev/null	Thu Jan  1 00:00:00 1970 +0000
+@@ -1,89 +0,0 @@
+-/*
+- * Simple prototyle Xen Store Daemon providing simple tree-like database.
+- * Copyright (C) 2005 Rusty Russell IBM Corporation
+- *
+- * This file may be distributed separately from the Linux kernel, or
+- * incorporated into other software packages, subject to the following license:
+- * 
+- * Permission is hereby granted, free of charge, to any person obtaining a copy
+- * of this source file (the "Software"), to deal in the Software without
+- * restriction, including without limitation the rights to use, copy, modify,
+- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+- * and to permit persons to whom the Software is furnished to do so, subject to
+- * the following conditions:
+- * 
+- * The above copyright notice and this permission notice shall be included in
+- * all copies or substantial portions of the Software.
+- * 
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+- * IN THE SOFTWARE.
+- */
+-
+-#ifndef _XENSTORED_H
+-#define _XENSTORED_H
+-
+-enum xsd_sockmsg_type
+-{
+-	XS_DEBUG,
+-	XS_SHUTDOWN,
+-	XS_DIRECTORY,
+-	XS_READ,
+-	XS_GET_PERMS,
+-	XS_WATCH,
+-	XS_WATCH_ACK,
+-	XS_UNWATCH,
+-	XS_TRANSACTION_START,
+-	XS_TRANSACTION_END,
+-	XS_OP_READ_ONLY = XS_TRANSACTION_END,
+-	XS_INTRODUCE,
+-	XS_RELEASE,
+-	XS_GET_DOMAIN_PATH,
+-	XS_WRITE,
+-	XS_MKDIR,
+-	XS_RM,
+-	XS_SET_PERMS,
+-	XS_WATCH_EVENT,
+-	XS_ERROR,
+-};
+-
+-#define XS_WRITE_NONE "NONE"
+-#define XS_WRITE_CREATE "CREATE"
+-#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
+-
+-/* We hand errors as strings, for portability. */
+-struct xsd_errors
+-{
+-	int errnum;
+-	const char *errstring;
+-};
+-#define XSD_ERROR(x) { x, #x }
+-static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
+-	XSD_ERROR(EINVAL),
+-	XSD_ERROR(EACCES),
+-	XSD_ERROR(EEXIST),
+-	XSD_ERROR(EISDIR),
+-	XSD_ERROR(ENOENT),
+-	XSD_ERROR(ENOMEM),
+-	XSD_ERROR(ENOSPC),
+-	XSD_ERROR(EIO),
+-	XSD_ERROR(ENOTEMPTY),
+-	XSD_ERROR(ENOSYS),
+-	XSD_ERROR(EROFS),
+-	XSD_ERROR(EBUSY),
+-	XSD_ERROR(EAGAIN),
+-	XSD_ERROR(EISCONN),
+-};
+-struct xsd_sockmsg
+-{
+-	u32 type;
+-	u32 len; 		/* Length of data following this. */
+-
+-	/* Generally followed by nul-terminated string(s). */
+-};
+-
+-#endif /* _XENSTORED_H */



More information about the Kernel-svn-changes mailing list