Index: base/src/core/include/rm_session_component.h
===================================================================
--- base/src/core/include/rm_session_component.h	(revision 102)
+++ base/src/core/include/rm_session_component.h	(working copy)
@@ -288,16 +288,21 @@
 			~Rm_session_component();
 
 			/**
-			 * Reversely lookup dataspace and offset matching the specified address
+			 * Reversely lookup pagefault
 			 *
-			 * \param  addr        address relative to region-manager session
-			 * \param  out_dsc     resolved dataspace
-			 * \param  out_offset  offset within resolved dataspace
-			 * \return true        lookup succeeded
+			 * \param  addr             address relative to region-manager session
+			 * \param  out_dsc          resolved dataspace
+			 * \param  out_ds_offset    offset in dataspace where region starts
+			 * \param  out_attach_addr  virtual start address of attached region
+			 * \param  out_attach_size  size of attached region
+			 *
+			 * \return true             lookup succeeded
 			 */
 			bool reverse_lookup(addr_t                addr,
 			                    Dataspace_component **out_dsc,
-			                    off_t                *out_offset);
+			                    off_t                *out_ds_offset,
+			                    addr_t               *out_attach_addr,
+			                    size_t               *out_attach_size);
 
 			/**
 			 * Register fault
Index: base/src/core/rm_session_component.cc
===================================================================
--- base/src/core/rm_session_component.cc	(revision 102)
+++ base/src/core/rm_session_component.cc	(working copy)
@@ -28,8 +28,8 @@
 using namespace Genode;
 
 
-static bool verbose             = false;
-static bool verbose_page_faults = false;
+static bool verbose             = true;
+static bool verbose_page_faults = true;
 
 enum {
 	SUPER_PAGE_SIZE_LOG2 = 22,
@@ -54,28 +54,39 @@
 	Rm_session_component *curr_rm_session = member_rm_session();
 	Dataspace_component  *dsc;
 
-	off_t  offset = 0;
-	addr_t addr   = pf_addr;
+	off_t offset = 0;
+	addr_t addr  = pf_addr;
+	off_t  ds_offset;
+	addr_t attach_addr;
+	size_t attach_size;
 	bool   lookup;
 
 	/* traverse potentially nested dataspaces until we hit a leaf dataspace */
 	unsigned level;
 	enum { MAX_NESTING_LEVELS = 5 };
 	for (level = 0; level < MAX_NESTING_LEVELS; level++) {
-		lookup = curr_rm_session->reverse_lookup(addr, &dsc, &offset);
+		lookup = curr_rm_session->reverse_lookup(addr, &dsc, &ds_offset,
+		                                         &attach_addr, &attach_size);
 		if (!lookup)
 			break;
 
+		offset = pf_addr - attach_addr;
+
 		/* check if we need to traverse into a nested dataspace */
 		Rm_session_component *sub_rm_session = dsc->sub_rm_session();
 		if (!sub_rm_session)
 			break;
 
-		/* set up next iteration */
-		addr            = offset;
+		PDBG("sub-RM session %d", level);
+
+		/* set up next iteration for dataspace-local offset address */
+		addr            = ds_offset + offset;
 		curr_rm_session = sub_rm_session;
 	}
 
+	PDBG("pf_addr=%lx LOOKUP ds_offset=%lx attach_addr=%lx attach_size=%zx offset=%lx",
+	     pf_addr, ds_offset, attach_addr, attach_size, offset);
+
 	if (level == MAX_NESTING_LEVELS) {
 		PWRN("Too many nesting levels of managed dataspaces");
 		return -1;
@@ -103,19 +114,25 @@
 
 	/*
 	 * Map superpage only if
-	 * * The dataspace is physically 4M-aligned
-	 * * The dataspace is attached to a 4M-aligned virtual address
-	 * * The offset is located withing a superpage boundary of the
-	 *   dataspace
+	 * - The dataspace is physically 4M-aligned and the offset is located
+	 *   within a superpage boundary of the dataspace
+	 * - The dataspace is attached to a 4M-aligned virtual address and the
+	 *   address is located within a superpage boundary of the virtual-address
+	 *   region
 	 */
-	addr_t super_page_trunc_offset = (offset & ~(SUPER_PAGE_SIZE - 1));
+	addr_t super_page_trunc_offset = ds_offset & ~(SUPER_PAGE_SIZE - 1);
 	if ((dsc->phys_addr() & (SUPER_PAGE_SIZE - 1)) == 0
-	 && (super_page_trunc_offset + SUPER_PAGE_SIZE) <= dsc->size()) {
-		offset        = super_page_trunc_offset;
+	 && (super_page_trunc_offset + SUPER_PAGE_SIZE) <= dsc->size()
+	 && (attach_addr & (SUPER_PAGE_SIZE - 1)) == 0
+	 && (pf_addr - attach_addr + SUPER_PAGE_SIZE) <= attach_size) {
+		ds_offset     = super_page_trunc_offset;
 		map_size_log2 = SUPER_PAGE_SIZE_LOG2;
 		pf_addr       = pf_addr & ~(SUPER_PAGE_SIZE - 1);
 	}
 
+	PDBG("pf_addr=%lx MAP ds_offset=%lx attach_addr=%lx attach_size=%zx offset=%lx",
+	     pf_addr, ds_offset, attach_addr, attach_size, offset);
+
 	/*
 	 * Check if dataspace is compatible with page-fault type
 	 */
@@ -138,8 +155,8 @@
 	 * addresses.
 	 */
 	Mapping mapping(trunc_page(pf_addr),
-	                trunc_page(dsc->core_local_addr() + offset),
-	                trunc_page(dsc->phys_addr() + offset),
+	                trunc_page(dsc->core_local_addr() + ds_offset + offset),
+	                trunc_page(dsc->phys_addr() + ds_offset + offset),
 	                dsc->write_combined(),
 	                map_size_log2,
 	                dsc->writable());
@@ -155,6 +172,9 @@
 	if (!dsc->is_io_mem())
 		mapping.prepare_map_operation();
 
+	if (verbose_page_faults)
+		printf("map phys %x size %x\n", dsc->phys_addr() + ds_offset, 1 << map_size_log2);
+
 	/* answer page fault with a flex-page mapping */
 	pager.set_reply_mapping(mapping);
 	return 0;
@@ -261,8 +281,9 @@
 	dsc->attached_to(region);
 
 	if (verbose)
-		PDBG("attach ds %p (a=%lx,s=%zx) @ [%lx,%lx)",
-		     dsc, dsc->phys_addr(), dsc->size(), (addr_t)r, (addr_t)r + size);
+		PDBG("attach ds %p (a=%lx,s=%zx) @ [%lx,%lx) use_local_address=%s",
+		     dsc, dsc->phys_addr(), dsc->size(), (addr_t)r, (addr_t)r + size,
+		     use_local_addr ? "true" : "false");
 
 	/* check if attach operation resolves any faulting region-manager clients */
 	for (Rm_faulter *faulter = _faulters.first(); faulter; ) {
@@ -383,7 +404,9 @@
 
 bool Rm_session_component::reverse_lookup(addr_t                addr,
                                           Dataspace_component **out_dsc,
-                                          off_t                *out_offset)
+                                          off_t                *out_ds_offset,
+                                          addr_t               *out_attach_addr,
+                                          size_t               *out_attach_size)
 {
 	/* serialize access */
 	Lock::Guard lock_guard(_lock);
@@ -403,8 +426,10 @@
 	if ((offset < 0) || ((unsigned)offset > dsc->size() - 1))
 		return false;
 
-	*out_dsc    = dsc;
-	*out_offset = offset;
+	*out_dsc         = dsc;
+	*out_ds_offset   = region->offset();
+	*out_attach_addr = region->base();
+	*out_attach_size = region->size();
 	return true;
 }
 
