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, ®);
- 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, ®);
+ 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,