Index: xen-unstable.hg/xen/arch/ia64/xen/xensetup.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/xensetup.c	2008-01-11 15:36:30.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/xensetup.c	2008-01-11 15:37:22.000000000 +0900
@@ -281,6 +281,9 @@ void __init start_kernel(void)
     int i;
 #endif
 
+    ia64_tr_set(IA64_TR_KERNEL, 0, 0);
+    ia64_tr_set(IA64_TR_CURRENT_STACK, 1, smp_processor_id());
+
     /* Be sure the struct shared_info size is <= XSI_SIZE.  */
     BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
 
Index: xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/processor.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux-xen/asm/processor.h	2008-01-11 15:36:29.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/processor.h	2008-01-11 15:40:06.000000000 +0900
@@ -770,6 +770,32 @@ ia64_get_cpl(unsigned long psr)
 {
   return (psr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT;
 }
+
+/*
+ * Track which TRs have already been pinned
+ */
+extern unsigned long ia64_tr_map[];
+
+/* A data entry and an instruction entry may have
+ * the same index, even though they are separate.
+ * So use the bottom 32bits of the mask for data-only entries and the
+ * top 32 for other entries (that is instruction-only entries, and
+ * instruction and data entries).
+ */
+static inline int ia64_tr_index(int tr, int data_only)
+{
+	return tr + (data_only ? 0 : 32);
+}
+
+static inline int ia64_tr_isset(int tr, int data_only, int cpu)
+{
+	return ia64_tr_map[cpu] & (1UL << ia64_tr_index(tr, data_only)) ? 1 : 0;
+}
+
+static inline void ia64_tr_set(int tr, int data_only, int cpu)
+{
+	ia64_tr_map[cpu] |= 1UL << ia64_tr_index(tr, data_only);
+}
 #endif
 
 #endif /* !__ASSEMBLY__ */
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/process-linux-xen.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/process-linux-xen.c	2008-01-11 15:36:29.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/process-linux-xen.c	2008-01-11 15:37:22.000000000 +0900
@@ -70,6 +70,12 @@ static DEFINE_PER_CPU(unsigned int, cpu_
 
 unsigned long boot_option_idle_override = 0;
 EXPORT_SYMBOL(boot_option_idle_override);
+
+#endif
+
+#ifdef XEN
+/* Too early to use PER_CPU */
+unsigned long ia64_tr_map[NR_CPUS];
 #endif
 
 void
Index: xen-unstable.hg/xen/arch/ia64/xen/mm_init.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/mm_init.c	2008-01-11 15:36:30.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/mm_init.c	2008-01-11 15:40:41.000000000 +0900
@@ -23,7 +23,7 @@ ia64_mmu_init (void *my_cpu_data)
 {
 	unsigned long psr, impl_va_bits;
 	extern void __devinit tlb_init (void);
-	int cpu;
+	int cpu = smp_processor_id();
 
 	/* Pin mapping for percpu area into TLB */
 	psr = ia64_clear_ic();
@@ -33,6 +33,7 @@ ia64_mmu_init (void *my_cpu_data)
 	ia64_srlz_i();
 #ifdef XEN
 	cpu_set(cpu, percpu_set);
+	ia64_tr_set(IA64_TR_PERCPU_DATA, 1, cpu);
 #endif
 
 	/*
@@ -72,8 +75,6 @@ ia64_mmu_init (void *my_cpu_data)
 	ia64_srlz_d();
 #endif
 
-	cpu = smp_processor_id();
-
 	/* mca handler uses cr.lid as key to pick the right entry */
 	ia64_mca_tlb_list[cpu].cr_lid = ia64_getreg(_IA64_REG_CR_LID);
 
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/efi.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/efi.c	2008-01-11 15:37:22.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/efi.c	2008-01-11 15:37:22.000000000 +0900
@@ -466,6 +466,9 @@ efi_map_pal_code (void)
 		 IA64_GRANULE_SHIFT);
 	ia64_set_psr(psr);		/* restore psr */
 	ia64_srlz_i();
+#ifdef XEN
+	ia64_tr_set(IA64_TR_PALCODE, 0, smp_processor_id());
+#endif
 }
 
 void __init
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/smpboot.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/smpboot.c	2008-01-11 15:36:29.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/smpboot.c	2008-01-11 15:37:22.000000000 +0900
@@ -435,6 +435,10 @@ int __devinit
 start_secondary (void *unused)
 {
 	/* Early console may use I/O ports */
+#ifdef XEN
+	ia64_tr_set(IA64_TR_KERNEL, 0, smp_processor_id());
+	ia64_tr_set(IA64_TR_CURRENT_STACK, 1, smp_processor_id());
+#endif
 	ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
 	Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
 	efi_map_pal_code();
Index: xen-unstable.hg/xen/arch/ia64/xen/domain.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/domain.c	2008-01-11 15:39:43.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/domain.c	2008-01-11 15:40:06.000000000 +0900
@@ -205,6 +205,7 @@ void schedule_tail(struct vcpu *prev)
 
 	if (VMX_DOMAIN(current)) {
 		vmx_do_launch(current);
+		ia64_tr_set(IA64_TR_VHPT, 1, current->processor);
 		migrate_timer(&current->arch.arch_vmx.vtm.vtm_timer,
 		              current->processor);
 	} else {
@@ -212,6 +213,7 @@ void schedule_tail(struct vcpu *prev)
 			ia64_set_iva(&ia64_ivt);
 		load_region_regs(current);
 		ia64_set_pta(vcpu_pta(current));
+		ia64_tr_set(IA64_TR_VHPT, 1, current->processor);
 		vcpu_load_kernel_regs(current);
 		__ia64_per_cpu_var(current_psr_i_addr) = &current->domain->
 		  shared_info->vcpu_info[current->vcpu_id].evtchn_upcall_mask;
@@ -262,13 +264,16 @@ void context_switch(struct vcpu *prev, s
         struct domain *nd;
         extern char ia64_ivt;
 
-        if (VMX_DOMAIN(prev))
+        if (VMX_DOMAIN(prev)) {
             ia64_set_iva(&ia64_ivt);
+	    ia64_tr_set(IA64_TR_VHPT, 1, current->processor);
+	}
 
         nd = current->domain;
         if (!is_idle_domain(nd)) {
             load_region_regs(current);
             ia64_set_pta(vcpu_pta(current));
+	    ia64_tr_set(IA64_TR_VHPT, 1, current->processor);
             vcpu_load_kernel_regs(current);
             if (vcpu_pkr_in_use(current))
                 vcpu_pkr_load_regs(current);
