msm: kgsl: Use process specific pt_base in postmortem dump

When doing a look-up of the IB1 base address, use the pagetable
belonging to the respective process rather than the pagetable
belonging to the process in whose context the GPU hung.

Signed-off-by: Sushmita Susheelendra <ssusheel@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index bd1a4aa..fedac3d 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -452,7 +452,7 @@
 	unsigned int r1, r2, r3, rbbm_status;
 	unsigned int cp_ib1_base, cp_ib1_bufsz, cp_stat;
 	unsigned int cp_ib2_base, cp_ib2_bufsz;
-	unsigned int pt_base;
+	unsigned int pt_base, cur_pt_base;
 	unsigned int cp_rb_base, rb_count;
 	unsigned int cp_rb_wptr, cp_rb_rptr;
 	unsigned int i;
@@ -640,6 +640,7 @@
 	KGSL_LOG_DUMP(device,
 		"        MPU_END    = %08X | VA_RANGE = %08X | PT_BASE  ="
 		" %08X\n", r1, r2, pt_base);
+	cur_pt_base = pt_base;
 
 	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ", KGSL_PAGETABLE_SIZE);
 
@@ -670,8 +671,8 @@
 
 	KGSL_LOG_DUMP(device, "RB: rd_addr:%8.8x  rb_size:%d  num_item:%d\n",
 		cp_rb_base, rb_count<<2, num_item);
-	rb_vaddr = (const uint32_t *)kgsl_sharedmem_convertaddr(device, pt_base,
-					cp_rb_base, &rb_memsize);
+	rb_vaddr = (const uint32_t *)kgsl_sharedmem_convertaddr(device,
+			cur_pt_base, cp_rb_base, &rb_memsize);
 	if (!rb_vaddr) {
 		KGSL_LOG_POSTMORTEM_WRITE(device,
 			"Can't fetch vaddr for CP_RB_BASE\n");
@@ -703,16 +704,34 @@
 		if (this_cmd == pm4_type3_packet(PM4_INDIRECT_BUFFER_PFD, 2)) {
 			uint32_t ib_addr = rb_copy[read_idx++];
 			uint32_t ib_size = rb_copy[read_idx++];
-			dump_ib1(device, pt_base, (read_idx-3)<<2, ib_addr,
+			dump_ib1(device, cur_pt_base, (read_idx-3)<<2, ib_addr,
 				ib_size, &ib_list, 0);
 			for (; i < ib_list.count; ++i)
-				dump_ib(device, "IB2:", pt_base,
+				dump_ib(device, "IB2:", cur_pt_base,
 					ib_list.offsets[i],
 					ib_list.bases[i],
 					ib_list.sizes[i], 0);
+		} else if (this_cmd == pm4_type0_packet(MH_MMU_PT_BASE, 1)) {
+
+			KGSL_LOG_DUMP(device, "Current pagetable: %x\t"
+				"pagetable base: %x\n",
+				kgsl_get_ptname_from_ptbase(cur_pt_base),
+				cur_pt_base);
+
+			/* Set cur_pt_base to the new pagetable base */
+			cur_pt_base = rb_copy[read_idx++];
+
+			KGSL_LOG_DUMP(device, "New pagetable: %x\t"
+				"pagetable base: %x\n",
+				kgsl_get_ptname_from_ptbase(cur_pt_base),
+				cur_pt_base);
 		}
 	}
 
+	/* Restore cur_pt_base back to the pt_base of
+	   the process in whose context the GPU hung */
+	cur_pt_base = pt_base;
+
 	read_idx = (int)cp_rb_rptr - 64;
 	if (read_idx < 0)
 		read_idx += rb_count;
@@ -732,7 +751,7 @@
 					KGSL_LOG_DUMP(device,
 						"IB1: base:%8.8X  "
 						"count:%d\n", ib_addr, ib_size);
-					dump_ib(device, "IB1: ", pt_base,
+					dump_ib(device, "IB1: ", cur_pt_base,
 						read_idx<<2, ib_addr, ib_size,
 						1);
 				}
@@ -745,7 +764,7 @@
 				KGSL_LOG_DUMP(device,
 					"IB2: base:%8.8X  count:%d\n",
 					cp_ib2_base, ib_size);
-				dump_ib(device, "IB2: ", pt_base, ib_offset,
+				dump_ib(device, "IB2: ", cur_pt_base, ib_offset,
 					ib_list.bases[i], ib_size, 1);
 			}
 		}
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 22c3467..fb2f63b 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -591,28 +591,36 @@
 	return ret;
 }
 
-void kgsl_mmu_pagefault(struct kgsl_device *device)
+int
+kgsl_get_ptname_from_ptbase(unsigned int pt_base)
 {
-	unsigned int reg;
-	unsigned int ptbase;
 	struct kgsl_pagetable *pt;
 	int ptid = -1;
 
-	kgsl_regread(device, MH_MMU_PAGE_FAULT, &reg);
-	kgsl_regread(device, MH_MMU_PT_BASE, &ptbase);
-
 	spin_lock(&kgsl_driver.ptlock);
 	list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
-		if (ptbase == pt->base.gpuaddr) {
+		if (pt_base == pt->base.gpuaddr) {
 			ptid = (int) pt->name;
 			break;
 		}
 	}
 	spin_unlock(&kgsl_driver.ptlock);
 
+	return ptid;
+}
+
+void kgsl_mmu_pagefault(struct kgsl_device *device)
+{
+	unsigned int reg;
+	unsigned int ptbase;
+
+	kgsl_regread(device, MH_MMU_PAGE_FAULT, &reg);
+	kgsl_regread(device, MH_MMU_PT_BASE, &ptbase);
+
 	KGSL_MEM_CRIT(device,
 			"mmu page fault: page=0x%lx pt=%d op=%s axi=%d\n",
-			reg & ~(PAGE_SIZE - 1), ptid,
+			reg & ~(PAGE_SIZE - 1),
+			kgsl_get_ptname_from_ptbase(ptbase),
 			reg & 0x02 ? "WRITE" : "READ", (reg >> 4) & 0xF);
 }
 
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 775fb95..4e90b8f 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -178,6 +178,7 @@
 unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
 void kgsl_setstate(struct kgsl_device *device, uint32_t flags);
 void kgsl_default_setstate(struct kgsl_device *device, uint32_t flags);
+int kgsl_get_ptname_from_ptbase(unsigned int pt_base);
 
 static inline int kgsl_mmu_enabled(void)
 {
@@ -257,6 +258,9 @@
 
 static inline void kgsl_default_setstate(struct kgsl_device *device,
 	uint32_t flags) { }
+
+static inline int kgsl_get_ptname_from_ptbase(unsigned int pt_base) { }
+
 #endif
 
 static inline unsigned int kgsl_pt_get_flags(struct kgsl_pagetable *pt,