From: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
To: Mitchel Humpherys <mitchelh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: "iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org"
<iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>,
"linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>
Subject: Re: [PATCH v6 2/2] iommu/arm-smmu: add support for iova_to_phys through ATS1PR
Date: Mon, 27 Oct 2014 11:44:31 +0000 [thread overview]
Message-ID: <20141027114430.GK8768@arm.com> (raw)
In-Reply-To: <1413323610-27484-3-git-send-email-mitchelh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
On Tue, Oct 14, 2014 at 10:53:30PM +0100, Mitchel Humpherys wrote:
> Currently, we provide the iommu_ops.iova_to_phys service by doing a
> table walk in software to translate IO virtual addresses to physical
> addresses. On SMMUs that support it, it can be useful to ask the SMMU
> itself to do the translation. This can be used to warm the TLBs for an
> SMMU. It can also be useful for testing and hardware validation.
>
> Since the address translation registers are optional on SMMUv2, only
> enable hardware translations when using SMMUv1 or when SMMU_IDR0.S1TS=1
> and SMMU_IDR0.ATOSNS=0, as described in the ARM SMMU v1-v2 spec.
[...]
> -static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
> +static phys_addr_t arm_smmu_iova_to_phys_soft(struct iommu_domain *domain,
> dma_addr_t iova)
> {
> pgd_t *pgdp, pgd;
> @@ -1557,6 +1569,66 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
> return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
> }
>
> +static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
> + dma_addr_t iova)
> +{
> + struct arm_smmu_domain *smmu_domain = domain->priv;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> + struct device *dev = smmu->dev;
> + void __iomem *cb_base;
> + u32 tmp;
> + u64 phys;
> + unsigned long flags;
> +
> + cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
> +
> + spin_lock_irqsave(&smmu_domain->lock, flags);
> +
> + if (smmu->version == 1) {
> + u32 reg = iova & ~0xfff;
> + writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
> + } else {
> + u32 reg = iova & ~0xfff;
> + writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
> + reg = (iova & ~0xfff) >> 32;
> + writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_HI);
> + }
> +
> + if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
> + !(tmp & ATSR_ACTIVE), 5, 50)) {
> + dev_err(dev,
> + "iova to phys timed out on 0x%pa. Falling back to software table walk.\n",
> + &iova);
> + return arm_smmu_iova_to_phys_soft(domain, iova);
Missing unlock here.
> + }
> +
> + phys = readl_relaxed(cb_base + ARM_SMMU_CB_PAR_LO);
> + phys |= ((u64) readl_relaxed(cb_base + ARM_SMMU_CB_PAR_HI)) << 32;
> +
> + spin_unlock_irqrestore(&smmu_domain->lock, flags);
> +
> + if (phys & CB_PAR_F) {
> + dev_err(dev, "translation fault!\n");
> + dev_err(dev, "PAR = 0x%llx\n", phys);
> + phys = 0;
> + } else {
> + phys = (phys & 0xfffffff000ULL) | (iova & 0x00000fff);
> + }
I think your mask is too big here -- SMMUv2 puts the MAIR in the top byte.
It probably makes more sense to use PHYS_MASK & ~0xfffUL.
Will
WARNING: multiple messages have this Message-ID (diff)
From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6 2/2] iommu/arm-smmu: add support for iova_to_phys through ATS1PR
Date: Mon, 27 Oct 2014 11:44:31 +0000 [thread overview]
Message-ID: <20141027114430.GK8768@arm.com> (raw)
In-Reply-To: <1413323610-27484-3-git-send-email-mitchelh@codeaurora.org>
On Tue, Oct 14, 2014 at 10:53:30PM +0100, Mitchel Humpherys wrote:
> Currently, we provide the iommu_ops.iova_to_phys service by doing a
> table walk in software to translate IO virtual addresses to physical
> addresses. On SMMUs that support it, it can be useful to ask the SMMU
> itself to do the translation. This can be used to warm the TLBs for an
> SMMU. It can also be useful for testing and hardware validation.
>
> Since the address translation registers are optional on SMMUv2, only
> enable hardware translations when using SMMUv1 or when SMMU_IDR0.S1TS=1
> and SMMU_IDR0.ATOSNS=0, as described in the ARM SMMU v1-v2 spec.
[...]
> -static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
> +static phys_addr_t arm_smmu_iova_to_phys_soft(struct iommu_domain *domain,
> dma_addr_t iova)
> {
> pgd_t *pgdp, pgd;
> @@ -1557,6 +1569,66 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
> return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
> }
>
> +static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
> + dma_addr_t iova)
> +{
> + struct arm_smmu_domain *smmu_domain = domain->priv;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> + struct device *dev = smmu->dev;
> + void __iomem *cb_base;
> + u32 tmp;
> + u64 phys;
> + unsigned long flags;
> +
> + cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
> +
> + spin_lock_irqsave(&smmu_domain->lock, flags);
> +
> + if (smmu->version == 1) {
> + u32 reg = iova & ~0xfff;
> + writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
> + } else {
> + u32 reg = iova & ~0xfff;
> + writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
> + reg = (iova & ~0xfff) >> 32;
> + writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_HI);
> + }
> +
> + if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
> + !(tmp & ATSR_ACTIVE), 5, 50)) {
> + dev_err(dev,
> + "iova to phys timed out on 0x%pa. Falling back to software table walk.\n",
> + &iova);
> + return arm_smmu_iova_to_phys_soft(domain, iova);
Missing unlock here.
> + }
> +
> + phys = readl_relaxed(cb_base + ARM_SMMU_CB_PAR_LO);
> + phys |= ((u64) readl_relaxed(cb_base + ARM_SMMU_CB_PAR_HI)) << 32;
> +
> + spin_unlock_irqrestore(&smmu_domain->lock, flags);
> +
> + if (phys & CB_PAR_F) {
> + dev_err(dev, "translation fault!\n");
> + dev_err(dev, "PAR = 0x%llx\n", phys);
> + phys = 0;
> + } else {
> + phys = (phys & 0xfffffff000ULL) | (iova & 0x00000fff);
> + }
I think your mask is too big here -- SMMUv2 puts the MAIR in the top byte.
It probably makes more sense to use PHYS_MASK & ~0xfffUL.
Will
next prev parent reply other threads:[~2014-10-27 11:44 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-14 21:53 [PATCH v6 0/2] iommu/arm-smmu: hard iova_to_phys Mitchel Humpherys
2014-10-14 21:53 ` Mitchel Humpherys
[not found] ` <1413323610-27484-1-git-send-email-mitchelh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2014-10-14 21:53 ` [PATCH v6 1/2] iopoll: Introduce memory-mapped IO polling macros Mitchel Humpherys
2014-10-14 21:53 ` Mitchel Humpherys
[not found] ` <1413323610-27484-2-git-send-email-mitchelh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2014-10-21 17:12 ` Mitchel Humpherys
2014-10-21 17:12 ` Mitchel Humpherys
2014-10-14 21:53 ` [PATCH v6 2/2] iommu/arm-smmu: add support for iova_to_phys through ATS1PR Mitchel Humpherys
2014-10-14 21:53 ` Mitchel Humpherys
[not found] ` <1413323610-27484-3-git-send-email-mitchelh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2014-10-27 11:44 ` Will Deacon [this message]
2014-10-27 11:44 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20141027114430.GK8768@arm.com \
--to=will.deacon-5wv7dgnigg8@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=mitchelh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.