* [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables Jordan Crouse
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Joerg Roedel, Robin Murphy, Will Deacon,
linux-arm-kernel, linux-kernel
Construct the io-pgtable config before calling the implementation specific
init_context function and pass it so the implementation specific function
can get a chance to change it before the io-pgtable is created.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
drivers/iommu/arm-smmu-impl.c | 3 ++-
drivers/iommu/arm-smmu.c | 11 ++++++-----
drivers/iommu/arm-smmu.h | 3 ++-
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index c75b9d957b70..a20e426d81ac 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -68,7 +68,8 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
return 0;
}
-static int cavium_init_context(struct arm_smmu_domain *smmu_domain)
+static int cavium_init_context(struct arm_smmu_domain *smmu_domain,
+ struct io_pgtable_cfg *pgtbl_cfg)
{
struct cavium_smmu *cs = container_of(smmu_domain->smmu,
struct cavium_smmu, smmu);
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 243bc4cb2705..8a3a6c8c887a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -797,11 +797,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
cfg->asid = cfg->cbndx;
smmu_domain->smmu = smmu;
- if (smmu->impl && smmu->impl->init_context) {
- ret = smmu->impl->init_context(smmu_domain);
- if (ret)
- goto out_unlock;
- }
pgtbl_cfg = (struct io_pgtable_cfg) {
.pgsize_bitmap = smmu->pgsize_bitmap,
@@ -812,6 +807,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
.iommu_dev = smmu->dev,
};
+ if (smmu->impl && smmu->impl->init_context) {
+ ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg);
+ if (ret)
+ goto out_unlock;
+ }
+
if (smmu_domain->non_strict)
pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index d172c024be61..38b041530a4f 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -383,7 +383,8 @@ struct arm_smmu_impl {
u64 val);
int (*cfg_probe)(struct arm_smmu_device *smmu);
int (*reset)(struct arm_smmu_device *smmu);
- int (*init_context)(struct arm_smmu_domain *smmu_domain);
+ int (*init_context)(struct arm_smmu_domain *smmu_domain,
+ struct io_pgtable_cfg *cfg);
void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
int status);
int (*def_domain_type)(struct device *dev);
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Joerg Roedel, Robin Murphy, Will Deacon,
linux-arm-kernel, linux-kernel
Enable TTBR1 for a context bank if IO_PGTABLE_QUIRK_ARM_TTBR1 is selected
by the io-pgtable configuration.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
drivers/iommu/arm-smmu.c | 21 ++++++++++++++++-----
drivers/iommu/arm-smmu.h | 25 +++++++++++++++++++------
2 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 8a3a6c8c887a..048de2681670 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -555,11 +555,15 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr;
cb->ttbr[1] = 0;
} else {
- cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
- cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID,
- cfg->asid);
+ cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
+ cfg->asid);
cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
- cfg->asid);
+ cfg->asid);
+
+ if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+ cb->ttbr[1] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+ else
+ cb->ttbr[0] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
}
} else {
cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -824,7 +828,14 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
/* Update the domain's page sizes to reflect the page table format */
domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
- domain->geometry.aperture_end = (1UL << ias) - 1;
+
+ if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
+ domain->geometry.aperture_start = ~0UL << ias;
+ domain->geometry.aperture_end = ~0UL;
+ } else {
+ domain->geometry.aperture_end = (1UL << ias) - 1;
+ }
+
domain->geometry.force_aperture = true;
/* Initialise the context bank with our page table cfg */
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 38b041530a4f..5f2de20e883b 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -168,10 +168,12 @@ enum arm_smmu_cbar_type {
#define ARM_SMMU_CB_TCR 0x30
#define ARM_SMMU_TCR_EAE BIT(31)
#define ARM_SMMU_TCR_EPD1 BIT(23)
+#define ARM_SMMU_TCR_A1 BIT(22)
#define ARM_SMMU_TCR_TG0 GENMASK(15, 14)
#define ARM_SMMU_TCR_SH0 GENMASK(13, 12)
#define ARM_SMMU_TCR_ORGN0 GENMASK(11, 10)
#define ARM_SMMU_TCR_IRGN0 GENMASK(9, 8)
+#define ARM_SMMU_TCR_EPD0 BIT(7)
#define ARM_SMMU_TCR_T0SZ GENMASK(5, 0)
#define ARM_SMMU_VTCR_RES1 BIT(31)
@@ -347,12 +349,23 @@ struct arm_smmu_domain {
static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
{
- return ARM_SMMU_TCR_EPD1 |
- FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
- FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
- FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
- FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
- FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+ u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
+ FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
+ FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
+ FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
+ FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+
+ /*
+ * When TTBR1 is selected shift the TCR fields by 16 bits and disable
+ * translation in TTBR0
+ */
+ if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
+ tcr = (tcr << 16) & ~ARM_SMMU_TCR_A1;
+ tcr |= ARM_SMMU_TCR_EPD0;
+ } else
+ tcr |= ARM_SMMU_TCR_EPD1;
+
+ return tcr;
}
static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg)
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
2020-06-17 22:40 ` Rob Herring
2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
` (3 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Joerg Roedel, Rob Herring, Robin Murphy,
Will Deacon, devicetree, linux-arm-kernel, linux-kernel
Every Qcom Adreno GPU has an embedded SMMU for its own use. These
devices depend on unique features such as split pagetables,
different stall/halt requirements and other settings. Identify them
with a compatible string so that they can be identified in the
arm-smmu implementation specific code.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index d7ceb4c34423..e52a1b146c97 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -38,6 +38,10 @@ properties:
- qcom,sc7180-smmu-500
- qcom,sdm845-smmu-500
- const: arm,mmu-500
+ - description: Qcom Adreno GPUs implementing "arm,smmu-v2"
+ items:
+ - const: qcom,adreno-smmu
+ - const: qcom,smmu-v2
- items:
- const: arm,mmu-500
- const: arm,smmu-v2
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU
2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
@ 2020-06-17 22:40 ` Rob Herring
0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2020-06-17 22:40 UTC (permalink / raw)
To: Jordan Crouse
Cc: Robin Murphy, iommu, linux-kernel, Rob Herring, Joerg Roedel,
linux-arm-kernel, linux-arm-msm, freedreno, devicetree,
Will Deacon
On Thu, 11 Jun 2020 16:21:24 -0600, Jordan Crouse wrote:
> Every Qcom Adreno GPU has an embedded SMMU for its own use. These
> devices depend on unique features such as split pagetables,
> different stall/halt requirements and other settings. Identify them
> with a compatible string so that they can be identified in the
> arm-smmu implementation specific code.
>
> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
> ---
>
> Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 ++++
> 1 file changed, 4 insertions(+)
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
` (2 preceding siblings ...)
2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
2020-06-12 4:19 ` kernel test robot
2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
` (2 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Joerg Roedel, Robin Murphy, Will Deacon,
linux-arm-kernel, linux-kernel
Add a link to the pointer to the struct device that is attached to a
domain. This makes it easy to get the pointer if it is needed in the
implementation specific code.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
drivers/iommu/arm-smmu.c | 1 +
drivers/iommu/arm-smmu.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 048de2681670..743d75b9ff3f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -801,6 +801,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
cfg->asid = cfg->cbndx;
smmu_domain->smmu = smmu;
+ smmu_domain->dev = dev;
pgtbl_cfg = (struct io_pgtable_cfg) {
.pgsize_bitmap = smmu->pgsize_bitmap,
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 5f2de20e883b..d33cfe26b2f5 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -345,6 +345,7 @@ struct arm_smmu_domain {
struct mutex init_mutex; /* Protects smmu pointer */
spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */
struct iommu_domain domain;
+ struct device *dev; /* Device attached to this domain */
};
static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain
2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
@ 2020-06-12 4:19 ` kernel test robot
0 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2020-06-12 4:19 UTC (permalink / raw)
To: Jordan Crouse, linux-arm-msm
Cc: kbuild-all, iommu, freedreno, Joerg Roedel, Robin Murphy,
Will Deacon, linux-arm-kernel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 9293 bytes --]
Hi Jordan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v5.7 next-20200611]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm64-randconfig-s031-20200612 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-250-g42323db3-dirty
# save the attached .config to linux build tree
make W=1 C=1 ARCH=arm64 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>, old ones prefixed by <<):
drivers/iommu/arm-smmu.c: In function 'arm_smmu_init_domain_context':
>> drivers/iommu/arm-smmu.c:804:21: error: 'dev' undeclared (first use in this function); did you mean 'cdev'?
804 | smmu_domain->dev = dev;
| ^~~
| cdev
drivers/iommu/arm-smmu.c:804:21: note: each undeclared identifier is reported only once for each function it appears in
vim +804 drivers/iommu/arm-smmu.c
669
670 static int arm_smmu_init_domain_context(struct iommu_domain *domain,
671 struct arm_smmu_device *smmu)
672 {
673 int irq, start, ret = 0;
674 unsigned long ias, oas;
675 struct io_pgtable_ops *pgtbl_ops;
676 struct io_pgtable_cfg pgtbl_cfg;
677 enum io_pgtable_fmt fmt;
678 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
679 struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
680
681 mutex_lock(&smmu_domain->init_mutex);
682 if (smmu_domain->smmu)
683 goto out_unlock;
684
685 if (domain->type == IOMMU_DOMAIN_IDENTITY) {
686 smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
687 smmu_domain->smmu = smmu;
688 goto out_unlock;
689 }
690
691 /*
692 * Mapping the requested stage onto what we support is surprisingly
693 * complicated, mainly because the spec allows S1+S2 SMMUs without
694 * support for nested translation. That means we end up with the
695 * following table:
696 *
697 * Requested Supported Actual
698 * S1 N S1
699 * S1 S1+S2 S1
700 * S1 S2 S2
701 * S1 S1 S1
702 * N N N
703 * N S1+S2 S2
704 * N S2 S2
705 * N S1 S1
706 *
707 * Note that you can't actually request stage-2 mappings.
708 */
709 if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
710 smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
711 if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
712 smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
713
714 /*
715 * Choosing a suitable context format is even more fiddly. Until we
716 * grow some way for the caller to express a preference, and/or move
717 * the decision into the io-pgtable code where it arguably belongs,
718 * just aim for the closest thing to the rest of the system, and hope
719 * that the hardware isn't esoteric enough that we can't assume AArch64
720 * support to be a superset of AArch32 support...
721 */
722 if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_L)
723 cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_L;
724 if (IS_ENABLED(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) &&
725 !IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_ARM_LPAE) &&
726 (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) &&
727 (smmu_domain->stage == ARM_SMMU_DOMAIN_S1))
728 cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_S;
729 if ((IS_ENABLED(CONFIG_64BIT) || cfg->fmt == ARM_SMMU_CTX_FMT_NONE) &&
730 (smmu->features & (ARM_SMMU_FEAT_FMT_AARCH64_64K |
731 ARM_SMMU_FEAT_FMT_AARCH64_16K |
732 ARM_SMMU_FEAT_FMT_AARCH64_4K)))
733 cfg->fmt = ARM_SMMU_CTX_FMT_AARCH64;
734
735 if (cfg->fmt == ARM_SMMU_CTX_FMT_NONE) {
736 ret = -EINVAL;
737 goto out_unlock;
738 }
739
740 switch (smmu_domain->stage) {
741 case ARM_SMMU_DOMAIN_S1:
742 cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
743 start = smmu->num_s2_context_banks;
744 ias = smmu->va_size;
745 oas = smmu->ipa_size;
746 if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) {
747 fmt = ARM_64_LPAE_S1;
748 } else if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_L) {
749 fmt = ARM_32_LPAE_S1;
750 ias = min(ias, 32UL);
751 oas = min(oas, 40UL);
752 } else {
753 fmt = ARM_V7S;
754 ias = min(ias, 32UL);
755 oas = min(oas, 32UL);
756 }
757 smmu_domain->flush_ops = &arm_smmu_s1_tlb_ops;
758 break;
759 case ARM_SMMU_DOMAIN_NESTED:
760 /*
761 * We will likely want to change this if/when KVM gets
762 * involved.
763 */
764 case ARM_SMMU_DOMAIN_S2:
765 cfg->cbar = CBAR_TYPE_S2_TRANS;
766 start = 0;
767 ias = smmu->ipa_size;
768 oas = smmu->pa_size;
769 if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) {
770 fmt = ARM_64_LPAE_S2;
771 } else {
772 fmt = ARM_32_LPAE_S2;
773 ias = min(ias, 40UL);
774 oas = min(oas, 40UL);
775 }
776 if (smmu->version == ARM_SMMU_V2)
777 smmu_domain->flush_ops = &arm_smmu_s2_tlb_ops_v2;
778 else
779 smmu_domain->flush_ops = &arm_smmu_s2_tlb_ops_v1;
780 break;
781 default:
782 ret = -EINVAL;
783 goto out_unlock;
784 }
785 ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
786 smmu->num_context_banks);
787 if (ret < 0)
788 goto out_unlock;
789
790 cfg->cbndx = ret;
791 if (smmu->version < ARM_SMMU_V2) {
792 cfg->irptndx = atomic_inc_return(&smmu->irptndx);
793 cfg->irptndx %= smmu->num_context_irqs;
794 } else {
795 cfg->irptndx = cfg->cbndx;
796 }
797
798 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
799 cfg->vmid = cfg->cbndx + 1;
800 else
801 cfg->asid = cfg->cbndx;
802
803 smmu_domain->smmu = smmu;
> 804 smmu_domain->dev = dev;
805
806 pgtbl_cfg = (struct io_pgtable_cfg) {
807 .pgsize_bitmap = smmu->pgsize_bitmap,
808 .ias = ias,
809 .oas = oas,
810 .coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK,
811 .tlb = smmu_domain->flush_ops,
812 .iommu_dev = smmu->dev,
813 };
814
815 if (smmu->impl && smmu->impl->init_context) {
816 ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg);
817 if (ret)
818 goto out_unlock;
819 }
820
821 if (smmu_domain->non_strict)
822 pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
823
824 pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
825 if (!pgtbl_ops) {
826 ret = -ENOMEM;
827 goto out_clear_smmu;
828 }
829
830 /* Update the domain's page sizes to reflect the page table format */
831 domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
832
833 if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
834 domain->geometry.aperture_start = ~0UL << ias;
835 domain->geometry.aperture_end = ~0UL;
836 } else {
837 domain->geometry.aperture_end = (1UL << ias) - 1;
838 }
839
840 domain->geometry.force_aperture = true;
841
842 /* Initialise the context bank with our page table cfg */
843 arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg);
844 arm_smmu_write_context_bank(smmu, cfg->cbndx);
845
846 /*
847 * Request context fault interrupt. Do this last to avoid the
848 * handler seeing a half-initialised domain state.
849 */
850 irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
851 ret = devm_request_irq(smmu->dev, irq, arm_smmu_context_fault,
852 IRQF_SHARED, "arm-smmu-context-fault", domain);
853 if (ret < 0) {
854 dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
855 cfg->irptndx, irq);
856 cfg->irptndx = ARM_SMMU_INVALID_IRPTNDX;
857 }
858
859 mutex_unlock(&smmu_domain->init_mutex);
860
861 /* Publish page table ops for map/unmap */
862 smmu_domain->pgtbl_ops = pgtbl_ops;
863 return 0;
864
865 out_clear_smmu:
866 __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
867 smmu_domain->smmu = NULL;
868 out_unlock:
869 mutex_unlock(&smmu_domain->init_mutex);
870 return ret;
871 }
872
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30307 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
` (3 preceding siblings ...)
2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
2020-06-12 5:11 ` kernel test robot
2020-06-13 1:34 ` kernel test robot
2020-06-11 22:21 ` [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU Jordan Crouse
6 siblings, 2 replies; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Joerg Roedel, Robin Murphy, Will Deacon,
linux-arm-kernel, linux-kernel
Add a special implementation for the SMMU attached to most Adreno GPU
target triggered from the qcom,adreno-gpu-smmu compatible string. When
selected the driver will attempt to enable split pagetables.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
drivers/iommu/arm-smmu-impl.c | 3 +++
drivers/iommu/arm-smmu-qcom.c | 45 +++++++++++++++++++++++++++++++++--
drivers/iommu/arm-smmu.h | 1 +
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index a20e426d81ac..309675cf6699 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -176,5 +176,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
of_device_is_compatible(np, "qcom,sc7180-smmu-500"))
return qcom_smmu_impl_init(smmu);
+ if (of_device_is_compatible(smmu->dev->of_node, "qcom,adreno-smmu"))
+ return qcom_adreno_smmu_impl_init(smmu);
+
return smmu;
}
diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index cf01d0215a39..6d0ab4865fc7 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -12,6 +12,29 @@ struct qcom_smmu {
struct arm_smmu_device smmu;
};
+static bool qcom_adreno_smmu_is_gpu_device(struct arm_smmu_domain *smmu_domain)
+{
+ return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
+}
+
+static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
+ struct io_pgtable_cfg *pgtbl_cfg)
+{
+ /* TTBR1 is only for the GPU stream ID and not the GMU */
+ if (!qcom_adreno_smmu_is_gpu_device(smmu_domain))
+ return 0;
+ /*
+ * All targets that use the qcom,adreno-smmu compatible string *should*
+ * be AARCH64 stage 1 but double check because the arm-smmu code assumes
+ * that is the case when the TTBR1 quirk is enabled
+ */
+ if ((smmu_domain->stage == ARM_SMMU_DOMAIN_S1) &&
+ (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64))
+ pgtbl_cfg->quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1;
+
+ return 0;
+}
+
static const struct of_device_id qcom_smmu_client_of_match[] = {
{ .compatible = "qcom,adreno" },
{ .compatible = "qcom,mdp4" },
@@ -65,7 +88,15 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
.reset = qcom_smmu500_reset,
};
-struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
+static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
+ .init_context = qcom_adreno_smmu_init_context,
+ .def_domain_type = qcom_smmu_def_domain_type,
+ .reset = qcom_smmu500_reset,
+};
+
+
+static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
+ const struct arm_smmu_impl *impl)
{
struct qcom_smmu *qsmmu;
@@ -75,8 +106,18 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
qsmmu->smmu = *smmu;
- qsmmu->smmu.impl = &qcom_smmu_impl;
+ qsmmu->smmu.impl = impl;
devm_kfree(smmu->dev, smmu);
return &qsmmu->smmu;
}
+
+struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+ return qcom_smmu_create(smmu, &qcom_smmu_impl);
+}
+
+struct arm_smmu_device *qcom_adreno_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+ return qcom_smmu_create(smmu, &qcom_adreno_smmu_impl);
+}
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index d33cfe26b2f5..c417814f1d98 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -466,6 +466,7 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu);
struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu);
+struct arm_smmu_device *qcom_adreno_smmu_impl_init(struct arm_smmu_device *smmu);
int arm_mmu500_reset(struct arm_smmu_device *smmu);
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU
2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
@ 2020-06-12 5:11 ` kernel test robot
2020-06-13 1:34 ` kernel test robot
1 sibling, 0 replies; 12+ messages in thread
From: kernel test robot @ 2020-06-12 5:11 UTC (permalink / raw)
To: Jordan Crouse, linux-arm-msm
Cc: kbuild-all, iommu, freedreno, Joerg Roedel, Robin Murphy,
Will Deacon, linux-arm-kernel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2121 bytes --]
Hi Jordan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on next-20200611]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next v5.7]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm64-randconfig-s031-20200612 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-250-g42323db3-dirty
# save the attached .config to linux build tree
make W=1 C=1 ARCH=arm64 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>, old ones prefixed by <<):
drivers/iommu/arm-smmu-qcom.c: In function 'qcom_adreno_smmu_is_gpu_device':
>> drivers/iommu/arm-smmu-qcom.c:17:49: error: 'smmu_domain->dev' is a pointer; did you mean to use '->'?
17 | return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
| ^
| ->
>> drivers/iommu/arm-smmu-qcom.c:18:1: warning: control reaches end of non-void function [-Wreturn-type]
18 | }
| ^
vim +17 drivers/iommu/arm-smmu-qcom.c
14
15 static bool qcom_adreno_smmu_is_gpu_device(struct arm_smmu_domain *smmu_domain)
16 {
> 17 return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
> 18 }
19
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30307 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU
2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
2020-06-12 5:11 ` kernel test robot
@ 2020-06-13 1:34 ` kernel test robot
1 sibling, 0 replies; 12+ messages in thread
From: kernel test robot @ 2020-06-13 1:34 UTC (permalink / raw)
To: Jordan Crouse, linux-arm-msm
Cc: kbuild-all, clang-built-linux, iommu, freedreno, Joerg Roedel,
Robin Murphy, Will Deacon, linux-arm-kernel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2134 bytes --]
Hi Jordan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on next-20200612]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next v5.7]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm64-randconfig-r026-20200612 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 3b43f006294971b8049d4807110032169780e5b8)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm64 cross compiling tool for clang build
# apt-get install binutils-aarch64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> drivers/iommu/arm-smmu-qcom.c:17:49: error: member reference type 'struct device *' is a pointer; did you mean to use '->'?
return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
~~~~~~~~~~~~~~~~^
->
1 error generated.
vim +17 drivers/iommu/arm-smmu-qcom.c
14
15 static bool qcom_adreno_smmu_is_gpu_device(struct arm_smmu_domain *smmu_domain)
16 {
> 17 return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
18 }
19
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 43304 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
` (4 preceding siblings ...)
2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU Jordan Crouse
6 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Bjorn Andersson, Brian Masney, Daniel Vetter,
David Airlie, Douglas Anderson, Jeffrey Hugo, Rob Clark,
Sean Paul, Shawn Guo, Thomas Gleixner, dri-devel, linux-kernel
Use the aperture settings from the IOMMU domain to set up the virtual
address range for the GPU. This allows us to transparently deal with
IOMMU side features (like split pagetables).
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 13 +++++++++++--
drivers/gpu/drm/msm/msm_iommu.c | 7 +++++++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 89673c7ed473..3e717c1ebb7f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -192,9 +192,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
struct msm_gem_address_space *aspace;
+ u64 start, size;
- aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
- 0xfffffff);
+ /*
+ * Use the aperture start or SZ_16M, whichever is greater. This will
+ * ensure that we align with the allocated pagetable range while still
+ * allowing room in the lower 32 bits for GMEM and whatnot
+ */
+ start = max_t(u64, SZ_16M, iommu->geometry.aperture_start);
+ size = iommu->geometry.aperture_end - start + 1;
+
+ aspace = msm_gem_address_space_create(mmu, "gpu",
+ start & GENMASK(48, 0), size);
if (IS_ERR(aspace) && !IS_ERR(mmu))
mmu->funcs->destroy(mmu);
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 3a381a9674c9..bbe129867590 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -36,6 +36,10 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
+ /* The arm-smmu driver expects the addresses to be sign extended */
+ if (iova & BIT(48))
+ iova |= GENMASK(63, 49);
+
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
WARN_ON(!ret);
@@ -46,6 +50,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
+ if (iova & BIT(48))
+ iova |= GENMASK(63, 49);
+
iommu_unmap(iommu->domain, iova, len);
return 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
` (5 preceding siblings ...)
2020-06-11 22:21 ` [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
6 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
To: linux-arm-msm
Cc: iommu, freedreno, Andy Gross, Bjorn Andersson, Rob Herring,
devicetree, linux-kernel
Set the qcom,adreno-smmu compatible string for the GPU SMMU to enable
split pagetables.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 8eb5a31346d2..8b15cd74e9ba 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -3556,7 +3556,7 @@
};
adreno_smmu: iommu@5040000 {
- compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2";
+ compatible = "qcom,adreno-smmu", "qcom,smmu-v2";
reg = <0 0x5040000 0 0x10000>;
#iommu-cells = <1>;
#global-interrupts = <2>;
--
2.17.1
^ permalink raw reply related [flat|nested] 12+ messages in thread