Index: xen-unstable.hg/xen/arch/ia64/xen/regionreg.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/regionreg.c	2008-01-17 14:18:49.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c	2008-01-17 16:26:33.000000000 +0900
@@ -19,8 +19,12 @@
 
 /* Defined in xemasm.S  */
 extern void ia64_new_rr7(unsigned long rid, void *shared_info, void *shared_arch_info, unsigned long shared_info_va, unsigned long va_vhpt);
-extern void ia64_new_rr7_efi(unsigned long rid, unsigned long percpu,
-			      unsigned long palcode, unsigned long vhpt);
+extern void ia64_new_rr7_efi(unsigned long rid,
+			      unsigned long percpu_pte,
+			      unsigned long palcode_pte,
+			      unsigned long vhpt_vaddr,
+			      unsigned long shared_info_vaddr,
+			      unsigned long mapped_regs_vaddr);
 
 /* RID virtualization mechanism is really simple:  domains have less rid bits
    than the host and the host rid space is shared among the domains.  (Values
@@ -232,6 +236,7 @@ set_rr(unsigned long rr, unsigned long r
 
 /* Too early to use PER_CPU */
 unsigned long ia64_saved_vhpt[NR_CPUS];
+unsigned long ia64_saved_shared_info[NR_CPUS];
 
 // validates and changes a single region register
 // in the currently executing domain
@@ -276,6 +281,8 @@ int __set_one_rr(unsigned long rr, unsig
 			       vcpu_vhpt_maddr(current));
 		}
 		ia64_saved_vhpt[smp_processor_id()] = vcpu_vhpt_maddr(current);
+		ia64_saved_shared_info[smp_processor_id()] =
+					v->domain->arch.shared_info_va;
 		ia64_new_rr7(vmMangleRID(newrrv.rrval),v->domain->shared_info,
 			     v->arch.privregs, v->domain->arch.shared_info_va,
 		             __va_ul(vcpu_vhpt_maddr(v)));
@@ -299,6 +306,8 @@ int set_one_rr_efi(unsigned long rr, un
 #if VHPT_ENABLED
 	unsigned long pta = 0UL;
 #endif
+	unsigned long shared_info = 0UL;
+	unsigned long mapped_regs = 0UL;
 	int cpu;
 
 	if (rreg == 6) {
@@ -322,12 +331,22 @@ int set_one_rr_efi(unsigned long rr, un
 	 *   paddr = __pa(pal_vaddr)
 	 *   pte = pte_val(pfn_pte(paddr) >> PAGE_SHIFT, PAGE_KERNEL))
 	 */
+	// XXX: ia64_tr_isset(IA64_TR_PALCODE, 0, cpu) is always true
 	if (ia64_tr_isset(IA64_TR_PALCODE, 0, cpu))
 		palcode = pte_val(pfn_pte(ia64_tpa(pal_vaddr) >>
 					  PAGE_SHIFT, PAGE_KERNEL));
 
+	/* - on non-vmx shared_info and mapped_regs are pinned
+	 *   at the same time as vhpt in ia64_new_rr7() via set_one_rr()
+	 * - in vmx shared_info and mapped_regs are never pinned.
+	 *   vhpt is pinned in vmx_switch_rr7() via vmx_load_all_rr()
+	 *   or vmx_vcpu_set_rr() (I'm not sure which happens first.
+	 */
+	//if (ia64_tr_isset(IA64_TR_VHPT, 1, cpu)) { // Not needes as
+	// we can use ia64_saved_vhpt[]
+	// XXX: Fix up for VMX
 #if VHPT_ENABLED
-	if (ia64_tr_isset(IA64_TR_VHPT, 1, cpu)) {
+	if (ia64_saved_vhpt[cpu]) {
 		vhpt = ia64_saved_vhpt[cpu];
 		BUG_ON(!vhpt);
 		vhpt = __va_ul(vhpt);
@@ -336,8 +355,14 @@ int set_one_rr_efi(unsigned long rr, un
 	}
 #endif
 
+	// N.B: Always zero for VMX, so no need to check VMX_DOMAIN(current)
+	if (ia64_saved_shared_info[cpu]) {
+		shared_info = ia64_saved_shared_info[cpu];
+		mapped_regs = shared_info + XMAPPEDREGS_OFS;
+	}
+
 	//XXX: palcode is only tested for non-zeroness in ia64_new_rr7_efi()
-	ia64_new_rr7_efi(val, percpu, palcode, vhpt);
+	ia64_new_rr7_efi(val, percpu, palcode, vhpt, shared_info, mapped_regs);
 
 #if VHPT_ENABLED
 	if (pta)
Index: xen-unstable.hg/xen/arch/ia64/xen/xenasm.S
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/xenasm.S	2008-01-17 14:18:49.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S	2008-01-17 16:20:08.000000000 +0900
@@ -250,13 +250,15 @@ END(ia64_new_rr7)
 
 
 // in0 = rid
-// in1 = percpu_paddr
-// in2 = palcode_paddr
-// in3 = vhpt_paddr
+// in1 = percpu_pte
+// in2 = palcode_pte
+// in3 = vhpt_vaddr
+// in4 = shared_info_vaddr
+// in5 = mapped_regs_vaddr
 GLOBAL_ENTRY(ia64_new_rr7_efi)
 	// FIXME? not sure this unwind statement is correct...
 	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
-	alloc loc1 = ar.pfs, 4, 8, 0, 0
+	alloc loc1 = ar.pfs, 6, 10, 0, 0
 	movl loc2=PERCPU_ADDR
 1:	{
 	  mov loc3 = psr		// save psr	
@@ -265,7 +267,10 @@ GLOBAL_ENTRY(ia64_new_rr7_efi)
 	};;
 	.body
 	tpa loc2=loc2			// grab this BEFORE changing rr7
-//	tpa in1=in1			// grab shared_info BEFORE changing rr7
+	cmp.ne p8,p0=r0,in4
+	cmp.ne p9,p0=r0,in5
+(p8)	tpa loc8=in4			// grab shared_info BEFORE changing rr7
+(p9)	tpa loc9=in5			// grab mapped_regs BEFORE changing rr7
 	adds r8 = 1f-1b,r8		// calculate return address for call
 	;;
 //	tpa loc7=in2			// grab arch_vcpu_info BEFORE chg rr7
@@ -400,6 +405,45 @@ ia64_new_rr7_efi_percpu_not_mapped:
 	;;
 ia64_new_rr7_efi_palcode_not_mapped:
 
+	//  Shared info
+	cmp.eq p7,p0=r0,in4
+(p7)	br.cond.sptk ia64_new_rr7_efi_shared_info_not_mapped
+	mov r24=XSI_SHIFT<<2
+	movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_PRIV | _PAGE_AR_RW)
+	;;
+	ptr.d in4,r24
+	;;
+	srlz.d
+	;;
+	or r23=loc8,r25			// construct PA | page properties
+	mov cr.itir=r24
+	mov cr.ifa=in4
+	mov r21=IA64_TR_SHARED_INFO
+	;;
+	itr.d dtr[r21]=r23		// wire in new mapping...
+	;;
+	srlz.d
+	;;
+
+	// Map mapped_regs
+	mov r22=XMAPPEDREGS_OFS
+	mov r24=XMAPPEDREGS_SHIFT<<2
+	;;
+	ptr.d	in5,r24
+	;;
+	srlz.d
+	;;
+	or r23=loc9,r25			// construct PA | page properties
+	mov cr.itir=r24
+	mov cr.ifa=in5
+	mov r21=IA64_TR_MAPPED_REGS
+	;;
+	itr.d dtr[r21]=r23		// wire in new mapping...
+	;;
+	srlz.d
+	;;
+ia64_new_rr7_efi_shared_info_not_mapped:
+
 #if VHPT_ENABLED
 	// 5. VHPT
 	cmp.eq p7,p0=r0,in3
