Index: arch/ia64/src/mm/page.c
===================================================================
--- arch/ia64/src/mm/page.c	(revision c2b95d3111e055b6d943ddfba623e6f44e4262d0)
+++ arch/ia64/src/mm/page.c	(revision 849386a07eb8c9ccdf6283b866a86ee0c59052bc)
@@ -39,4 +39,5 @@
 #include <arch/asm.h>
 #include <arch/barrier.h>
+#include <memstr.h>
 
 /** Initialize VHPT and region registers. */
@@ -67,4 +68,5 @@
 	
 		rr.word == rr_read(i);
+		rr.map.ve = 0;		/* disable VHPT walker */
 		rr.map.rid = ASID_INVALID;
 		rr_write(i, rr.word);
@@ -77,5 +79,6 @@
 	 */
 	page_ht = (pte_t *) frame_alloc(FRAME_KA, VHPT_WIDTH - FRAME_WIDTH, NULL);
-	ht_invalidate_all();
+	memsetb((__address) page_ht, VHPT_SIZE, 0);
+	ht_invalidate_all();	
 	
 	/*
@@ -99,2 +102,37 @@
 	set_vhpt_environment();
 }
+
+/** Calculate address of collision chain from VPN and ASID.
+ *
+ * This is rather non-trivial function.
+ * First, it has to translate ASID to RID.
+ * This is achieved by taking VRN bits of
+ * page into account.
+ * Second, it must preserve the region register
+ * it writes the RID to.
+ *
+ * @param page Address of virtual page including VRN bits.
+ * @param asid Address space identifier.
+ *
+ * @return Head of VHPT collision chain for page and asid.
+ */
+pte_t *vhpt_hash(__address page, asid_t asid)
+{
+	region_register rr_save, rr;
+	pte_t *t;
+
+	rr_save.word = rr_read(VRN_WORK);
+	rr.word = rr_save.word;
+	if ((page >> VRN_SHIFT) != VRN_KERNEL)
+		rr.map.rid = (asid * RIDS_PER_ASID) + (page >> VRN_SHIFT);
+	else
+		rr.map.rid = ASID_KERNEL;
+	rr_write(VRN_WORK, rr.word);
+	srlz_i();
+	t = (pte_t *) thash((VRN_WORK << VRN_SHIFT) | (~(VRN_MASK) & page));
+	rr_write(VRN_WORK, rr_save.word);
+	srlz_i();
+	srlz_d();
+
+	return t;
+}
