mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-24 06:59:27 -05:00
182 lines
6.0 KiB
Diff
182 lines
6.0 KiB
Diff
From 7613c9d520ee4d227e635f6db0270d4cf26102bc Mon Sep 17 00:00:00 2001
|
|
From: Jordan Crouse <jcrouse@codeaurora.org>
|
|
Date: Mon, 21 Apr 2014 15:04:54 -0600
|
|
Subject: msm: kgsl: Protect CP_STATE_DEBUG_INDEX
|
|
|
|
Put CP_STATE_DEBUG_INDEX and CP_STATE_DEBUG_DATA under protection
|
|
to keep it from being written from an IB1. Doing so however opens
|
|
up a subtle "feature" in the microcode: memory read opcodes turn off
|
|
protected mode in the microcode to do the read and then turns it
|
|
back on regardless of the initial state. This is a problem if the
|
|
memory read happens while protected mode is turned off and then we
|
|
try to access a protected register which then complains and goes boom.
|
|
|
|
To account for this irregularity explicitly turn back off protected
|
|
mode in all the places where we know this will be a problem.
|
|
|
|
Change-Id: Ic0dedbad1397ca9b80132241ac006560a615e042
|
|
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
|
|
---
|
|
drivers/gpu/msm/adreno.c | 24 +++++++++++++-----------
|
|
drivers/gpu/msm/adreno.h | 10 ++++++++++
|
|
drivers/gpu/msm/adreno_a3xx.c | 1 +
|
|
drivers/gpu/msm/kgsl_iommu.c | 16 ++++++++++++++++
|
|
4 files changed, 40 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
|
|
index 4b21218..9bd07c6 100644
|
|
--- a/drivers/gpu/msm/adreno.c
|
|
+++ b/drivers/gpu/msm/adreno.c
|
|
@@ -1150,9 +1150,7 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
|
uint32_t flags)
|
|
{
|
|
phys_addr_t pt_val;
|
|
- unsigned int link[230];
|
|
- unsigned int *cmds = &link[0];
|
|
- int sizedwords = 0;
|
|
+ unsigned int *link = NULL, *cmds;
|
|
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
|
int num_iommu_units;
|
|
struct kgsl_context *context;
|
|
@@ -1170,6 +1168,14 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
|
if (context)
|
|
adreno_ctx = ADRENO_CONTEXT(context);
|
|
|
|
+ link = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
+ if (link == NULL) {
|
|
+ result = -ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ cmds = link;
|
|
+
|
|
result = kgsl_mmu_enable_clk(&device->mmu, KGSL_IOMMU_CONTEXT_USER);
|
|
|
|
if (result)
|
|
@@ -1192,17 +1198,11 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
|
cmds += _adreno_iommu_setstate_v1(device, cmds, pt_val,
|
|
num_iommu_units, flags);
|
|
|
|
- sizedwords += (cmds - &link[0]);
|
|
- if (sizedwords == 0) {
|
|
- KGSL_DRV_ERR(device, "no commands generated\n");
|
|
- BUG();
|
|
- }
|
|
/* invalidate all base pointers */
|
|
*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
|
|
*cmds++ = 0x7fff;
|
|
- sizedwords += 2;
|
|
|
|
- if (sizedwords > (ARRAY_SIZE(link))) {
|
|
+ if ((unsigned int) (cmds - link) > (PAGE_SIZE / sizeof(unsigned int))) {
|
|
KGSL_DRV_ERR(device, "Temp command buffer overflow\n");
|
|
BUG();
|
|
}
|
|
@@ -1211,7 +1211,8 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
|
* use the global timestamp for iommu clock disablement
|
|
*/
|
|
result = adreno_ringbuffer_issuecmds(device, adreno_ctx,
|
|
- KGSL_CMD_FLAGS_PMODE, &link[0], sizedwords);
|
|
+ KGSL_CMD_FLAGS_PMODE, link,
|
|
+ (unsigned int)(cmds - link));
|
|
|
|
/*
|
|
* On error disable the IOMMU clock right away otherwise turn it off
|
|
@@ -1225,6 +1226,7 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
|
KGSL_IOMMU_CONTEXT_USER);
|
|
|
|
done:
|
|
+ kfree(link);
|
|
kgsl_context_put(context);
|
|
return result;
|
|
}
|
|
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
|
|
index 8e162ca..0b793fa 100644
|
|
--- a/drivers/gpu/msm/adreno.h
|
|
+++ b/drivers/gpu/msm/adreno.h
|
|
@@ -805,6 +805,11 @@ static inline int adreno_add_read_cmds(struct kgsl_device *device,
|
|
*cmds++ = val;
|
|
*cmds++ = 0xFFFFFFFF;
|
|
*cmds++ = 0xFFFFFFFF;
|
|
+
|
|
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
|
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
|
+ *cmds++ = 0;
|
|
+
|
|
cmds += __adreno_add_idle_indirect_cmds(cmds, nop_gpuaddr);
|
|
return cmds - start;
|
|
}
|
|
@@ -850,6 +855,11 @@ static inline int adreno_wait_reg_mem(unsigned int *cmds, unsigned int addr,
|
|
*cmds++ = val; /* ref val */
|
|
*cmds++ = mask;
|
|
*cmds++ = interval;
|
|
+
|
|
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
|
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
|
+ *cmds++ = 0;
|
|
+
|
|
return cmds - start;
|
|
}
|
|
/*
|
|
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
|
|
index 70ba50e..873a5c9 100644
|
|
--- a/drivers/gpu/msm/adreno_a3xx.c
|
|
+++ b/drivers/gpu/msm/adreno_a3xx.c
|
|
@@ -2038,6 +2038,7 @@ static void a3xx_protect_init(struct kgsl_device *device)
|
|
|
|
/* CP registers */
|
|
adreno_set_protected_registers(device, &index, 0x1C0, 5);
|
|
+ adreno_set_protected_registers(device, &index, 0x1EC, 1);
|
|
adreno_set_protected_registers(device, &index, 0x1F6, 1);
|
|
adreno_set_protected_registers(device, &index, 0x1F8, 2);
|
|
adreno_set_protected_registers(device, &index, 0x45E, 2);
|
|
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
|
|
index dba23b0..68b3420 100644
|
|
--- a/drivers/gpu/msm/kgsl_iommu.c
|
|
+++ b/drivers/gpu/msm/kgsl_iommu.c
|
|
@@ -1036,6 +1036,10 @@ static unsigned int kgsl_iommu_sync_lock(struct kgsl_mmu *mmu,
|
|
*cmds++ = 0x1;
|
|
*cmds++ = 0x1;
|
|
|
|
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
|
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
|
+ *cmds++ = 0;
|
|
+
|
|
*cmds++ = cp_type3_packet(CP_MEM_WRITE, 2);
|
|
*cmds++ = lock_vars->turn;
|
|
*cmds++ = 0;
|
|
@@ -1050,11 +1054,19 @@ static unsigned int kgsl_iommu_sync_lock(struct kgsl_mmu *mmu,
|
|
*cmds++ = 0x1;
|
|
*cmds++ = 0x1;
|
|
|
|
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
|
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
|
+ *cmds++ = 0;
|
|
+
|
|
*cmds++ = cp_type3_packet(CP_TEST_TWO_MEMS, 3);
|
|
*cmds++ = lock_vars->flag[PROC_APPS];
|
|
*cmds++ = lock_vars->turn;
|
|
*cmds++ = 0;
|
|
|
|
+ /* TEST_TWO_MEMS turns back on protected mode - push it off */
|
|
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
|
+ *cmds++ = 0;
|
|
+
|
|
cmds += adreno_add_idle_cmds(adreno_dev, cmds);
|
|
|
|
return cmds - start;
|
|
@@ -1092,6 +1104,10 @@ static unsigned int kgsl_iommu_sync_unlock(struct kgsl_mmu *mmu,
|
|
*cmds++ = 0x1;
|
|
*cmds++ = 0x1;
|
|
|
|
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
|
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
|
+ *cmds++ = 0;
|
|
+
|
|
cmds += adreno_add_idle_cmds(adreno_dev, cmds);
|
|
|
|
return cmds - start;
|
|
--
|
|
cgit v1.1
|
|
|