From: Robin Murphy <robin.murphy@arm.com>
To: Nicolin Chen <nicolinc@nvidia.com>, will@kernel.org, jgg@nvidia.com
Cc: joro@8bytes.org, bhelgaas@google.com, praan@google.com,
kevin.tian@intel.com, kees@kernel.org, smostafa@google.com,
baolu.lu@linux.intel.com, linux-arm-kernel@lists.infradead.org,
iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, skaestle@nvidia.com,
mmarrid@nvidia.com, skolothumtho@nvidia.com, bbiber@nvidia.com
Subject: Re: [PATCH v2 05/11] iommu/arm-smmu-v3: Submit CMDQ_OP_PRI_RESP for IOPF event
Date: Fri, 26 Jun 2026 17:15:13 +0100 [thread overview]
Message-ID: <b5085e09-6533-4f88-938d-8d46751cf7da@arm.com> (raw)
In-Reply-To: <6c713c724fa09bf5a1b5e2247c633e516036f079.1779944354.git.nicolinc@nvidia.com>
On 28/05/2026 8:59 am, Nicolin Chen wrote:
> From: Malak Marrid <mmarrid@nvidia.com>
>
> To handle IOMMU_FAULT_PAGE_REQ from the PRI queue, arm_smmu_page_response()
> must issue a CMDQ_OP_PRI_RESP back to the SMMU.
>
> However, either a stall event in the EVTQ or a PRI request in the PRIQ can
> surface to the IOPF infrastructure with fault.type == IOMMU_FAULT_PAGE_REQ,
> and a single master can in principle be both stall-capable and PRI-capable
No, the SMMU architecture does all it can to specifically forbid this,
see 3.12.1 and 16.4, it just can't be made architecturally ILLEGAL to
enable stalls for PCIe devices because there's no strict architectural
definition for what "a PCIe device" actually is. Similarly with the note
in the definition of STE.EATS about the relationship with CD.S - the
unwritten implication is that defining specific behaviours would only
create an unreasonable burden for hardware validation, for the sake of
something that nobody in their right mind should ever do anyway.
The expectation is that RCiEPs which do speak stallable non-PCIe bus
protocols will not go to the effort of implementing ATS/PRI capabilities
(not least because there's every chance that such protocols simply
doesn't have that kind of transaction flow anyway). And conversely that
it can be considered an egregious firmware (or system design) error to
even claim (let alone force) stall capability for a real PCIe root port
which may be deadlocked by blocking its requirement for free-flowing
writes. Thus I think we could go so far as to refuse to handle any
endpoint which did somehow claim both.
Thanks,
Robin.
> (e.g. FEAT_STALL_FORCE on a PCIe device with PRI), so master state is not a
> reliable discriminator.
>
> Add IOMMU_FAULT_PAGE_REQUEST_STALLS_TRANS to the generic flags so the fault
> reporter can mark a page request that is holding the device's transaction:
> arm_smmu_handle_event() sets it on STALL events
> arm_smmu_handle_ppr() leaves it clear for PRI events
>
> Note: streams[0].id remains the RID because arm_smmu_enable_iopf() rejects
> num_streams != 1.
>
> Co-developed-by: Barak Biber <bbiber@nvidia.com>
> Signed-off-by: Barak Biber <bbiber@nvidia.com>
> Co-developed-by: Stefan Kaestle <skaestle@nvidia.com>
> Signed-off-by: Stefan Kaestle <skaestle@nvidia.com>
> Signed-off-by: Malak Marrid <mmarrid@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 +
> include/linux/iommu.h | 1 +
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 75 +++++++++++++++------
> 3 files changed, 58 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 2bb810e4d5fce..1083621705f16 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -1007,6 +1007,7 @@ struct arm_smmu_master {
> /* Locked by the iommu core using the group mutex */
> struct arm_smmu_ctx_desc_cfg cd_table;
> unsigned int num_streams;
> + bool pri_enabled : 1;
> bool ats_enabled : 1;
> bool ste_ats_enabled : 1;
> bool stall_enabled;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index e587d4ac4d331..83c4dfcf20637 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -76,6 +76,7 @@ struct iommu_fault_page_request {
> #define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID (1 << 0)
> #define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE (1 << 1)
> #define IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID (1 << 2)
> +#define IOMMU_FAULT_PAGE_REQUEST_STALLS_TRANS (1 << 3)
> u32 flags;
> u32 pasid;
> u32 grpid;
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index ffc9621cd2288..061f1d46fda0d 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -921,32 +921,68 @@ static int arm_smmu_drain_queue_for_iopf(struct arm_smmu_device *smmu,
> return ret;
> }
>
> -static void arm_smmu_page_response(struct device *dev, struct iopf_fault *unused,
> +static void arm_smmu_page_response(struct device *dev, struct iopf_fault *evt,
> struct iommu_page_response *resp)
> {
> struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> - u8 resume_resp;
> + struct arm_smmu_cmd cmd;
> + int sid;
>
> - if (WARN_ON(!master->stall_enabled))
> + if (WARN_ON_ONCE(evt->fault.type != IOMMU_FAULT_PAGE_REQ))
> return;
>
> - switch (resp->code) {
> - case IOMMU_PAGE_RESP_INVALID:
> - case IOMMU_PAGE_RESP_FAILURE:
> - resume_resp = CMDQ_RESUME_0_RESP_ABORT;
> - break;
> - case IOMMU_PAGE_RESP_SUCCESS:
> - resume_resp = CMDQ_RESUME_0_RESP_RETRY;
> - break;
> - default:
> - resume_resp = CMDQ_RESUME_0_RESP_TERM;
> - break;
> + /* IOPF is gated to num_streams == 1 in arm_smmu_enable_iopf() */
> + sid = master->streams[0].id;
> +
> + if (evt->fault.prm.flags & IOMMU_FAULT_PAGE_REQUEST_STALLS_TRANS) {
> + u8 resume_resp;
> +
> + if (WARN_ON_ONCE(!master->stall_enabled))
> + return;
> + switch (resp->code) {
> + case IOMMU_PAGE_RESP_INVALID:
> + case IOMMU_PAGE_RESP_FAILURE:
> + resume_resp = CMDQ_RESUME_0_RESP_ABORT;
> + break;
> + case IOMMU_PAGE_RESP_SUCCESS:
> + resume_resp = CMDQ_RESUME_0_RESP_RETRY;
> + break;
> + default:
> + resume_resp = CMDQ_RESUME_0_RESP_TERM;
> + break;
> + }
> + cmd = arm_smmu_make_cmd_resume(sid, resp->grpid, resume_resp);
> + } else {
> + enum pri_resp pri_resp;
> + bool ssv;
> +
> + if (WARN_ON_ONCE(!master->pri_enabled))
> + return;
> + /* PCIe allows only one PRG Response per group */
> + if (!(evt->fault.prm.flags &
> + IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE))
> + return;
> + switch (resp->code) {
> + case IOMMU_PAGE_RESP_SUCCESS:
> + pri_resp = PRI_RESP_SUCC;
> + break;
> + case IOMMU_PAGE_RESP_FAILURE:
> + pri_resp = PRI_RESP_FAIL;
> + break;
> + case IOMMU_PAGE_RESP_INVALID:
> + pri_resp = PRI_RESP_DENY;
> + break;
> + default:
> + WARN_ON(true);
> + return;
> + }
> + ssv = !!(evt->fault.prm.flags &
> + IOMMU_FAULT_PAGE_REQUEST_PASID_VALID);
> + cmd = arm_smmu_make_cmd_pri_resp(sid, resp->pasid, ssv,
> + resp->grpid, pri_resp);
> }
>
> - arm_smmu_cmdq_issue_cmd(master->smmu,
> - arm_smmu_make_cmd_resume(master->streams[0].id,
> - resp->grpid,
> - resume_resp));
> + arm_smmu_cmdq_issue_cmd(master->smmu, cmd);
> /*
> * Don't send a SYNC, it doesn't do anything for RESUME or PRI_RESP.
> * RESUME consumption guarantees that the stalled transaction will be
> @@ -2081,7 +2117,8 @@ static int arm_smmu_handle_event(struct arm_smmu_device *smmu, u64 *evt,
>
> flt->type = IOMMU_FAULT_PAGE_REQ;
> flt->prm = (struct iommu_fault_page_request){
> - .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
> + .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE |
> + IOMMU_FAULT_PAGE_REQUEST_STALLS_TRANS,
> .grpid = event->stag,
> .perm = perm,
> .addr = event->iova,
next prev parent reply other threads:[~2026-06-26 16:15 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-28 7:59 [PATCH v2 00/11] iommu/arm-smmu-v3: Add PRI support Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 01/11] iommu/arm-smmu-v3: Add arm_smmu_attach_release() Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 02/11] iommu/arm-smmu-v3: Factor out __queue_empty() and __queue_consumed() Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 03/11] iommu/arm-smmu-v3: Add arm_smmu_drain_queue_for_iopf() helper Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 04/11] iommu/arm-smmu-v3: Drain in-flight fault handlers Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 05/11] iommu/arm-smmu-v3: Submit CMDQ_OP_PRI_RESP for IOPF event Nicolin Chen
2026-06-26 16:15 ` Robin Murphy [this message]
2026-06-27 0:44 ` Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 06/11] iommu/arm-smmu-v3: Support PRI Page Request in arm_smmu_handle_ppr() Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 07/11] iommu/arm-smmu-v3: Disable PRI when no IRQ handler is registered Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 08/11] iommu/arm-smmu-v3: Allocate IOPF queue for ARM_SMMU_FEAT_PRI Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 09/11] PCI/ATS: Add PRI stubs Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 10/11] PCI/ATS: Export pci_enable_pri() and pci_reset_pri() Nicolin Chen
2026-05-28 7:59 ` [PATCH v2 11/11] iommu/arm-smmu-v3: Enable PRI for PCI device in arm_smmu_probe_device() Nicolin Chen
2026-06-26 14:54 ` [PATCH v2 00/11] iommu/arm-smmu-v3: Add PRI support harsha.v
2026-06-27 0:43 ` Nicolin Chen
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=b5085e09-6533-4f88-938d-8d46751cf7da@arm.com \
--to=robin.murphy@arm.com \
--cc=baolu.lu@linux.intel.com \
--cc=bbiber@nvidia.com \
--cc=bhelgaas@google.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kees@kernel.org \
--cc=kevin.tian@intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mmarrid@nvidia.com \
--cc=nicolinc@nvidia.com \
--cc=praan@google.com \
--cc=skaestle@nvidia.com \
--cc=skolothumtho@nvidia.com \
--cc=smostafa@google.com \
--cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox