Re: [PATCH v12 10/10] iommu/arm-smmu-v3: Add stall support for platform devices
From: Auger Eric <eric.auger@redhat.com>
Date: 2021-02-01 13:19:10
Also in:
linux-arm-kernel, linux-devicetree, linux-iommu
Hi Jean, On 2/1/21 12:12 PM, Jean-Philippe Brucker wrote:
On Sun, Jan 31, 2021 at 07:29:09PM +0100, Auger Eric wrote:quoted
Hi Jean, Some rather minor comments§questions below that may not justify a respin. On 1/27/21 4:43 PM, Jean-Philippe Brucker wrote:quoted
-static bool arm_smmu_iopf_supported(struct arm_smmu_master *master) +bool arm_smmu_master_iopf_supported(struct arm_smmu_master *master) { - return false; + /* We're not keeping track of SIDs in fault events */shall we? [*] belowThat would require storing the incoming SID into the iommu_fault_event struct, and retrieve it in arm_smmu_page_response(). Easy enough, but I don't think it's needed for existing devices.
OK
quoted
quoted
+ if (master->num_streams != 1) + return false;[...]quoted
quoted
+static int arm_smmu_page_response(struct device *dev, + struct iommu_fault_event *unused, + struct iommu_page_response *resp) +{ + struct arm_smmu_cmdq_ent cmd = {0}; + struct arm_smmu_master *master = dev_iommu_priv_get(dev); + int sid = master->streams[0].id;[*]quoted
+ + if (master->stall_enabled) { + cmd.opcode = CMDQ_OP_RESUME; + cmd.resume.sid = sid; + cmd.resume.stag = resp->grpid; + switch (resp->code) { + case IOMMU_PAGE_RESP_INVALID:add fallthrough?I think fallthrough is mainly useful to tell reader and compiler that a break was omitted on purpose. When two cases are stuck together the intent to merge the flow is clear enough in my opinion. GCC's -Wimplicit-fallthrough doesn't warn in this case.
OK
quoted
quoted
+ case IOMMU_PAGE_RESP_FAILURE: + cmd.resume.resp = CMDQ_RESUME_0_RESP_ABORT; + break;[...]quoted
quoted
+static int arm_smmu_handle_evt(struct arm_smmu_device *smmu, u64 *evt) +{ + int ret; + u32 reason; + u32 perm = 0; + struct arm_smmu_master *master; + bool ssid_valid = evt[0] & EVTQ_0_SSV; + u32 sid = FIELD_GET(EVTQ_0_SID, evt[0]); + struct iommu_fault_event fault_evt = { }; + struct iommu_fault *flt = &fault_evt.fault; + + /* Stage-2 is always pinned at the moment */ + if (evt[1] & EVTQ_1_S2) + return -EFAULT; + + master = arm_smmu_find_master(smmu, sid); + if (!master) + return -EINVAL; + + if (evt[1] & EVTQ_1_RnW) + perm |= IOMMU_FAULT_PERM_READ; + else + perm |= IOMMU_FAULT_PERM_WRITE; + + if (evt[1] & EVTQ_1_InD) + perm |= IOMMU_FAULT_PERM_EXEC; + + if (evt[1] & EVTQ_1_PnU) + perm |= IOMMU_FAULT_PERM_PRIV; + + switch (FIELD_GET(EVTQ_0_ID, evt[0])) { + case EVT_ID_TRANSLATION_FAULT: + case EVT_ID_ADDR_SIZE_FAULT: + case EVT_ID_ACCESS_FAULT: + reason = IOMMU_FAULT_REASON_PTE_FETCH;Doesn't it rather map to IOMMU_FAULT_REASON_ACCESS? /* access flag check failed */"Good point, I guess it didn't exist when I wrote this. And ADDR_SIZE_FAULT corresponds to IOMMU_FAULT_REASON_OOR_ADDRESS now, right?
yes it dies
By the way the wording on those two fault reasons, "access flag" and "stage", seems arch-specific - x86 names are "accessed flag" and "level".quoted
quoted
+ break; + case EVT_ID_PERMISSION_FAULT: + reason = IOMMU_FAULT_REASON_PERMISSION; + break; + default: + return -EOPNOTSUPP; + } + + if (evt[1] & EVTQ_1_STALL) { + flt->type = IOMMU_FAULT_PAGE_REQ; + flt->prm = (struct iommu_fault_page_request) { + .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE, + .grpid = FIELD_GET(EVTQ_1_STAG, evt[1]), + .perm = perm, + .addr = FIELD_GET(EVTQ_2_ADDR, evt[2]), + }; + + if (ssid_valid) { + flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID; + flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]); + } + } else { + flt->type = IOMMU_FAULT_DMA_UNRECOV; + flt->event = (struct iommu_fault_unrecoverable) { + .reason = reason, + .flags = IOMMU_FAULT_UNRECOV_ADDR_VALID | + IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID,nit: shall IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID be set here? Supported unrecoverable faults feature the IPA field which is UNKNOWN for S1 translations. fetch_addr rather was corresponding to WALK_EABT.Fetch_addr to me.Right I should drop the IPA part entirely, since we don't report S2 faults in this patch.
OK But as I mentioned this can be fixed separately if you don't have other comments on this version. Thanks Eric
Thanks, Jeanquoted
quoted
+ .perm = perm, + .addr = FIELD_GET(EVTQ_2_ADDR, evt[2]), + .fetch_addr = FIELD_GET(EVTQ_3_IPA, evt[3]), + };_______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel