msm: kgsl: Support adding VA padding for global allocations

Most of the global buffers are allocated sequentially in the GPU virtual
memory space. Some buffers might want to have a bit of breathing room to
try to detect buffer overwrites. Allow specific buffers to allocate some
additional virtual address padding. To start, add a 4K gap between
ringbuffers and a 16K space after the preemption records.

Change-Id: Ic0dedbadb7bdd39a87228e222990700f3727f51e
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2020-09-10 13:16:16 -06:00
commit d1dfa3f1f0
19 changed files with 42 additions and 39 deletions

View file

@ -92,7 +92,7 @@ int adreno_get_firmware(struct adreno_device *adreno_dev,
return ret;
}
firmware->memdesc = kgsl_allocate_global(device, fw->size - 4,
firmware->memdesc = kgsl_allocate_global(device, fw->size - 4, 0,
KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_UCODE,
"ucode");
@ -1397,7 +1397,7 @@ int adreno_device_probe(struct platform_device *pdev,
priv |= KGSL_MEMDESC_PRIVILEGED;
device->memstore = kgsl_allocate_global(device,
KGSL_MEMSTORE_SIZE, 0, priv, "memstore");
KGSL_MEMSTORE_SIZE, 0, 0, priv, "memstore");
status = PTR_ERR_OR_ZERO(device->memstore);
if (status) {
@ -1722,7 +1722,7 @@ static int adreno_init(struct kgsl_device *device)
priv |= KGSL_MEMDESC_PRIVILEGED;
adreno_dev->profile_buffer =
kgsl_allocate_global(device, PAGE_SIZE, 0, priv,
kgsl_allocate_global(device, PAGE_SIZE, 0, 0, priv,
"alwayson");
adreno_dev->profile_index = 0;

View file

@ -149,7 +149,7 @@ static int _a3xx_pwron_fixup(struct adreno_device *adreno_dev)
return 0;
adreno_dev->pwron_fixup = kgsl_allocate_global(KGSL_DEVICE(adreno_dev),
PAGE_SIZE, KGSL_MEMFLAGS_GPUREADONLY, 0, "pwron_fixup");
PAGE_SIZE, 0, KGSL_MEMFLAGS_GPUREADONLY, 0, "pwron_fixup");
if (IS_ERR(adreno_dev->pwron_fixup))
return PTR_ERR(adreno_dev->pwron_fixup);

View file

@ -155,12 +155,12 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev)
uint64_t gpuaddrs[4];
adreno_dev->critpkts = kgsl_allocate_global(device,
PAGE_SIZE * 4, 0, 0, "crit_pkts");
PAGE_SIZE * 4, 0, 0, 0, "crit_pkts");
if (IS_ERR(adreno_dev->critpkts))
return PTR_ERR(adreno_dev->critpkts);
adreno_dev->critpkts_secure = kgsl_allocate_global(device,
PAGE_SIZE, KGSL_MEMFLAGS_SECURE, 0, "crit_pkts_secure");
PAGE_SIZE, 0, KGSL_MEMFLAGS_SECURE, 0, "crit_pkts_secure");
if (IS_ERR(adreno_dev->critpkts_secure))
return PTR_ERR(adreno_dev->critpkts_secure);

View file

@ -484,7 +484,7 @@ static int a5xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev,
if (IS_ERR_OR_NULL(rb->preemption_desc))
rb->preemption_desc = kgsl_allocate_global(device,
A5XX_CP_CTXRECORD_SIZE_IN_BYTES, 0,
A5XX_CP_CTXRECORD_SIZE_IN_BYTES, SZ_16K, 0,
KGSL_MEMDESC_PRIVILEGED, "preemption_desc");
if (IS_ERR(rb->preemption_desc))
@ -533,7 +533,7 @@ int a5xx_preemption_init(struct adreno_device *adreno_dev)
if (IS_ERR_OR_NULL(preempt->scratch))
preempt->scratch = kgsl_allocate_global(device,
adreno_dev->num_ringbuffers *
A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0,
A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0, 0,
"preemption_counters");
ret = PTR_ERR_OR_ZERO(preempt->scratch);
@ -553,7 +553,7 @@ int a5xx_preemption_init(struct adreno_device *adreno_dev)
/* Allocate mem for storing preemption smmu record */
if (IS_ERR_OR_NULL(iommu->smmu_info))
iommu->smmu_info = kgsl_allocate_global(device, PAGE_SIZE,
iommu->smmu_info = kgsl_allocate_global(device, PAGE_SIZE, 0,
KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED,
"smmu_info");

View file

@ -1134,14 +1134,14 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev)
/* The script buffers needs 2 extra qwords on the end */
if (!IS_ERR_OR_NULL(capturescript))
capturescript = kgsl_allocate_global(device,
script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
script_size + 16, 0, KGSL_MEMFLAGS_GPUREADONLY,
KGSL_MEMDESC_PRIVILEGED, "capturescript");
if (IS_ERR(capturescript))
return;
if (!IS_ERR_OR_NULL(registers))
registers = kgsl_allocate_global(device, data_size, 0,
registers = kgsl_allocate_global(device, data_size, 0, 0,
KGSL_MEMDESC_PRIVILEGED, "capturescript_regs");
if (IS_ERR(registers))

View file

@ -149,7 +149,7 @@ int a6xx_init(struct adreno_device *adreno_dev)
if (IS_ERR_OR_NULL(adreno_dev->pwrup_reglist)) {
adreno_dev->pwrup_reglist =
kgsl_allocate_global(KGSL_DEVICE(adreno_dev),
PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED,
PAGE_SIZE, 0, 0, KGSL_MEMDESC_PRIVILEGED,
"powerup_register_list");
if (IS_ERR(adreno_dev->pwrup_reglist))
return PTR_ERR(adreno_dev->pwrup_reglist);

View file

@ -2960,7 +2960,7 @@ static int a6xx_first_boot(struct adreno_device *adreno_dev)
priv |= KGSL_MEMDESC_PRIVILEGED;
adreno_dev->profile_buffer = kgsl_allocate_global(device, PAGE_SIZE, 0,
priv, "alwayson");
0, priv, "alwayson");
adreno_dev->profile_index = 0;

View file

@ -560,7 +560,7 @@ static struct mem_alloc_entry *get_mem_alloc_entry(
if (desc->flags & MEMFLAG_GFX_SECURE)
flags |= KGSL_MEMFLAGS_SECURE;
entry->gpu_md = kgsl_allocate_global(device, desc->size, flags, priv,
entry->gpu_md = kgsl_allocate_global(device, desc->size, 0, flags, priv,
memkind_string);
if (IS_ERR(entry->gpu_md)) {
int ret = PTR_ERR(entry->gpu_md);

View file

@ -625,14 +625,14 @@ static int a6xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev,
if (IS_ERR_OR_NULL(rb->preemption_desc))
rb->preemption_desc = kgsl_allocate_global(device,
ctxt_record_size, 0,
ctxt_record_size, SZ_16K, 0,
KGSL_MEMDESC_PRIVILEGED, "preemption_desc");
if (IS_ERR(rb->preemption_desc))
return PTR_ERR(rb->preemption_desc);
if (IS_ERR_OR_NULL(rb->secure_preemption_desc))
rb->secure_preemption_desc = kgsl_allocate_global(device,
ctxt_record_size,
ctxt_record_size, 0,
KGSL_MEMFLAGS_SECURE, KGSL_MEMDESC_PRIVILEGED,
"secure_preemption_desc");
@ -641,7 +641,7 @@ static int a6xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev,
if (IS_ERR_OR_NULL(rb->perfcounter_save_restore_desc))
rb->perfcounter_save_restore_desc = kgsl_allocate_global(device,
A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE, 0,
A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE, 0, 0,
KGSL_MEMDESC_PRIVILEGED,
"perfcounter_save_restore_desc");
@ -695,14 +695,14 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev)
if (IS_ERR_OR_NULL(preempt->scratch)) {
preempt->scratch = kgsl_allocate_global(device, PAGE_SIZE,
0, 0, "preempt_scratch");
0, 0, 0, "preempt_scratch");
if (IS_ERR(preempt->scratch))
return PTR_ERR(preempt->scratch);
}
/* Allocate mem for storing preemption smmu record */
if (IS_ERR_OR_NULL(iommu->smmu_info))
iommu->smmu_info = kgsl_allocate_global(device, PAGE_SIZE,
iommu->smmu_info = kgsl_allocate_global(device, PAGE_SIZE, 0,
KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED,
"smmu_info");

View file

@ -991,7 +991,7 @@ static int a6xx_first_boot(struct adreno_device *adreno_dev)
adreno_get_bus_counters(adreno_dev);
adreno_dev->profile_buffer = kgsl_allocate_global(device, PAGE_SIZE, 0,
0, "alwayson");
0, 0, "alwayson");
adreno_dev->profile_index = 0;

View file

@ -2201,7 +2201,7 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev)
/* The script buffers needs 2 extra qwords on the end */
if (IS_ERR_OR_NULL(a6xx_capturescript))
a6xx_capturescript = kgsl_allocate_global(device,
script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
script_size + 16, 0, KGSL_MEMFLAGS_GPUREADONLY,
KGSL_MEMDESC_PRIVILEGED, "capturescript");
if (IS_ERR(a6xx_capturescript))
@ -2209,7 +2209,7 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev)
if (IS_ERR_OR_NULL(a6xx_crashdump_registers))
a6xx_crashdump_registers = kgsl_allocate_global(device,
data_size, 0, KGSL_MEMDESC_PRIVILEGED,
data_size, 0, 0, KGSL_MEMDESC_PRIVILEGED,
"capturescript_regs");
if (IS_ERR(a6xx_crashdump_registers))

View file

@ -413,7 +413,7 @@ void adreno_iommu_init(struct adreno_device *adreno_dev)
*/
if (IS_ERR_OR_NULL(iommu->setstate)) {
iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE,
KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate");
0, KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate");
kgsl_sharedmem_writel(iommu->setstate,
KGSL_IOMMU_SETSTATE_NOP_OFFSET,

View file

@ -1024,7 +1024,7 @@ void adreno_profile_init(struct adreno_device *adreno_dev)
profile->shared_size = ADRENO_PROFILE_SHARED_BUF_SIZE_DWORDS;
profile->shared_buffer = kgsl_allocate_global(device,
profile->shared_size * sizeof(unsigned int),
0, 0, "profile");
0, 0, 0, "profile");
if (IS_ERR(profile->shared_buffer)) {
profile->shared_size = 0;
return;

View file

@ -241,7 +241,7 @@ static int _adreno_ringbuffer_init(struct adreno_device *adreno_dev,
*/
if (IS_ERR_OR_NULL(rb->pagetable_desc)) {
rb->pagetable_desc = kgsl_allocate_global(device, PAGE_SIZE,
0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc");
SZ_16K, 0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc");
if (IS_ERR(rb->pagetable_desc))
return PTR_ERR(rb->pagetable_desc);
}
@ -249,14 +249,14 @@ static int _adreno_ringbuffer_init(struct adreno_device *adreno_dev,
/* allocate a chunk of memory to create user profiling IB1s */
if (IS_ERR_OR_NULL(rb->profile_desc))
rb->profile_desc = kgsl_allocate_global(device, PAGE_SIZE,
KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc");
0, KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc");
if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV))
priv |= KGSL_MEMDESC_PRIVILEGED;
if (IS_ERR_OR_NULL(rb->buffer_desc)) {
rb->buffer_desc = kgsl_allocate_global(device, KGSL_RB_SIZE,
KGSL_MEMFLAGS_GPUREADONLY, priv, "ringbuffer");
SZ_4K, KGSL_MEMFLAGS_GPUREADONLY, priv, "ringbuffer");
if (IS_ERR(rb->buffer_desc))
return PTR_ERR(rb->buffer_desc);
}
@ -303,7 +303,7 @@ int adreno_ringbuffer_init(struct adreno_device *adreno_dev)
if (IS_ERR_OR_NULL(device->scratch)) {
device->scratch = kgsl_allocate_global(device,
PAGE_SIZE, 0, priv, "scratch");
PAGE_SIZE, 0, 0, priv, "scratch");
if (IS_ERR(device->scratch))
return PTR_ERR(device->scratch);

View file

@ -261,7 +261,7 @@ static void kgsl_iommu_map_global_to_pt(struct kgsl_mmu *mmu,
}
static void kgsl_iommu_map_global(struct kgsl_mmu *mmu,
struct kgsl_memdesc *memdesc)
struct kgsl_memdesc *memdesc, u32 padding)
{
struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
@ -275,7 +275,8 @@ static void kgsl_iommu_map_global(struct kgsl_mmu *mmu,
u64 offset;
u64 base;
offset = global_get_offset(device, memdesc->size,
/* Find room for the memdesc plus any padding */
offset = global_get_offset(device, memdesc->size + padding,
memdesc->priv);
if (IS_ERR_VALUE(offset))

View file

@ -463,12 +463,12 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
}
void kgsl_mmu_map_global(struct kgsl_device *device,
struct kgsl_memdesc *memdesc)
struct kgsl_memdesc *memdesc, u32 padding)
{
struct kgsl_mmu *mmu = &(device->mmu);
if (MMU_OP_VALID(mmu, mmu_map_global))
mmu->mmu_ops->mmu_map_global(mmu, memdesc);
mmu->mmu_ops->mmu_map_global(mmu, memdesc, padding);
}
void kgsl_mmu_close(struct kgsl_device *device)

View file

@ -70,7 +70,7 @@ struct kgsl_mmu_ops {
struct kgsl_pagetable * (*mmu_getpagetable)(struct kgsl_mmu *mmu,
unsigned long name);
void (*mmu_map_global)(struct kgsl_mmu *mmu,
struct kgsl_memdesc *memdesc);
struct kgsl_memdesc *memdesc, u32 padding);
};
struct kgsl_mmu_pt_ops {
@ -325,11 +325,12 @@ kgsl_mmu_pagetable_get_contextidr(struct kgsl_pagetable *pagetable)
* kgsl_mmu_map_global - Map a memdesc as a global buffer
* @device: A KGSL GPU device handle
* @memdesc: Pointer to a GPU memory descriptor
* @padding: Any padding to add to the end of the VA allotment (in bytes)
*
* Map a buffer as globally accessible in all pagetable contexts
*/
void kgsl_mmu_map_global(struct kgsl_device *device,
struct kgsl_memdesc *memdesc);
struct kgsl_memdesc *memdesc, u32 padding);
/**
* kgsl_mmu_pagetable_get_context_bank - Return the context bank number

View file

@ -1253,7 +1253,7 @@ struct kgsl_memdesc *kgsl_allocate_global_fixed(struct kgsl_device *device,
*/
list_add_tail(&md->node, &device->globals);
kgsl_mmu_map_global(device, &md->memdesc);
kgsl_mmu_map_global(device, &md->memdesc, 0);
return &md->memdesc;
}
@ -1290,13 +1290,13 @@ kgsl_allocate_secure_global(struct kgsl_device *device,
* No offset needed, we'll get an address inside of the pagetable
* normally
*/
kgsl_mmu_map_global(device, &md->memdesc);
kgsl_mmu_map_global(device, &md->memdesc, 0);
return &md->memdesc;
}
struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device,
u64 size, u64 flags, u32 priv, const char *name)
u64 size, u32 padding, u64 flags, u32 priv, const char *name)
{
int ret;
struct kgsl_global_memdesc *md;
@ -1329,7 +1329,7 @@ struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device,
*/
list_add_tail(&md->node, &device->globals);
kgsl_mmu_map_global(device, &md->memdesc);
kgsl_mmu_map_global(device, &md->memdesc, padding);
return &md->memdesc;
}

View file

@ -107,6 +107,7 @@ int kgsl_allocate_kernel(struct kgsl_device *device,
* kgsl_allocate_global - Allocate a global GPU memory object
* @device: A GPU device handle
* @size: Size of the allocation in bytes
* @padding: Amount of extra adding to add to the VA allocation
* @flags: Control flags for the allocation
* @priv: Internal flags for the allocation
* @name: Name of the allocation (for the debugfs file)
@ -118,7 +119,7 @@ int kgsl_allocate_kernel(struct kgsl_device *device,
* failure.
*/
struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device,
u64 size, u64 flags, u32 priv, const char *name);
u64 size, u32 padding, u64 flags, u32 priv, const char *name);
/**
* kgsl_allocate_global_fixed - Allocate a global GPU memory object from a fixed