From 423b064dd95b0d10ff3cfbdcaf5d51f81b90d7bc Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 30 Oct 2019 09:05:27 -0600 Subject: [PATCH] msm: kgsl: Add a function to map global buffers Currently all global buffers are mapped when pagetables are created which means that all global buffers need to be in place before the default pagetable is created otherwise they will not be available in that context. Add a new MMU function to map each global buffer. If the default pagetable has been created then the new buffer can be mapped immediately, otherwise all the buffers on the list will be mapped when the pagetable finally comes along. Per-process pagetables will map everything from the list at create time as they do now. As a caveat this function only applies to the default pagetable. We will not go back and retroactively map buffers into existing per-process pagetables. Previously if somebody mapped a global buffer late it wouldn't be available in the default pagetable either so it was easier to debug. Now that this function will always successfully map buffers in the default pagetable "late" buffers that got missed in a per-process table will be harder to debug. In recognition of this the new map function will trigger a warning if a buffer is mapped after the first per-process pagetable is created. It won't stop breakage from happening but at least it will be more easily debuggable. Change-Id: Ic0dedbad2ed20769ea96bfdac3b707a30c6f9737 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/kgsl_iommu.c | 28 +++++++++++++++++++++++++++- drivers/gpu/msm/kgsl_iommu.h | 8 +++++++- drivers/gpu/msm/kgsl_mmu.c | 11 ++++++++++- drivers/gpu/msm/kgsl_mmu.h | 14 +++++++++++++- drivers/gpu/msm/kgsl_sharedmem.c | 6 +++++- 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index d615ebcae95d..3cfa9c6d197b 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. */ #include @@ -88,6 +88,29 @@ static void kgsl_iommu_map_globals(struct kgsl_mmu *mmu, kgsl_mmu_map(pagetable, &md->memdesc); } +static void kgsl_iommu_map_global(struct kgsl_mmu *mmu, + struct kgsl_memdesc *memdesc) +{ + struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); + + /* + * If the global pagetable hasn't been created yet, do nothing. We'll + * get them all in one big swoop at create time + */ + if (!mmu->defaultpagetable) + return; + + /* + * Warn if a global is added after first per-process pagetables have + * been created since we do not go back and retroactively add the + * globals to existing pages + */ + WARN_ON(iommu->ppt_active); + + /* Map the buffer in the default pagetable */ + kgsl_mmu_map(mmu->defaultpagetable, memdesc); +} + static u64 kgsl_iommu_get_global_base(struct kgsl_mmu *mmu) { return KGSL_IOMMU_GLOBAL_MEM_BASE(mmu); @@ -1108,6 +1131,8 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) goto done; } + iommu->ppt_active = true; + kgsl_iommu_map_globals(mmu, pt); done: @@ -2383,6 +2408,7 @@ struct kgsl_mmu_ops kgsl_iommu_ops = { .mmu_init_pt = kgsl_iommu_init_pt, .mmu_getpagetable = kgsl_iommu_getpagetable, .mmu_get_global_base = kgsl_iommu_get_global_base, + .mmu_map_global = kgsl_iommu_map_global, .probe = kgsl_iommu_probe, }; diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h index 8b4f7e3952b7..5c0433fad221 100644 --- a/drivers/gpu/msm/kgsl_iommu.h +++ b/drivers/gpu/msm/kgsl_iommu.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __KGSL_IOMMU_H #define __KGSL_IOMMU_H @@ -124,6 +124,12 @@ struct kgsl_iommu { struct kgsl_memdesc *smmu_info; /** @pdev: Pointer to the platform device for the IOMMU device */ struct platform_device *pdev; + /** + * @ppt_active: Set when the first per process pagetable is created. + * This is used to warn when global buffers are created that might not + * be mapped in all contexts + */ + bool ppt_active; }; /* diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index e3dcdb629d6c..e7411896f17c 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. */ #include @@ -537,6 +537,15 @@ u64 kgsl_mmu_get_global_base(struct kgsl_device *device) return 0; } +void kgsl_mmu_map_global(struct kgsl_device *device, + struct kgsl_memdesc *memdesc) +{ + struct kgsl_mmu *mmu = &(device->mmu); + + if (MMU_OP_VALID(mmu, mmu_map_global)) + mmu->mmu_ops->mmu_map_global(mmu, memdesc); +} + void kgsl_mmu_close(struct kgsl_device *device) { struct kgsl_mmu *mmu = &(device->mmu); diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 952dbb70b3b4..cdef06d1741d 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. */ #ifndef __KGSL_MMU_H #define __KGSL_MMU_H @@ -71,6 +71,8 @@ struct kgsl_mmu_ops { struct kgsl_pagetable * (*mmu_getpagetable)(struct kgsl_mmu *mmu, unsigned long name); u64 (*mmu_get_global_base)(struct kgsl_mmu *mmu); + void (*mmu_map_global)(struct kgsl_mmu *mmu, + struct kgsl_memdesc *memdesc); }; struct kgsl_mmu_pt_ops { @@ -344,4 +346,14 @@ kgsl_mmu_pagetable_get_contextidr(struct kgsl_pagetable *pagetable) */ u64 kgsl_mmu_get_global_base(struct kgsl_device *device); +/** + * kgsl_mmu_map_global - Map a memdesc as a global buffer + * @device: A KGSL GPU device handle + * @memdesc: Pointer to a GPU memory descriptor + * + * Map a buffer as globally accessible in all pagetable contexts + */ +void kgsl_mmu_map_global(struct kgsl_device *device, + struct kgsl_memdesc *memdesc); + #endif /* __KGSL_MMU_H */ diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index ba33934c94d2..95d1a990bd61 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. */ #include @@ -1325,6 +1325,8 @@ 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); + return &md->memdesc; } @@ -1374,6 +1376,8 @@ struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device, */ list_add_tail(&md->node, &device->globals); + kgsl_mmu_map_global(device, &md->memdesc); + return &md->memdesc; }