From: Joerg Roedel Date: Fri, 12 Jun 2026 12:57:23 +0000 (+0200) Subject: Merge branches 'apple/dart', 'arm/smmu/updates', 'arm/smmu/bindings', 'rockchip'... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd8a3c6cd531dca5917111a94fa3074077f6ba5a;p=thirdparty%2Fkernel%2Flinux.git Merge branches 'apple/dart', 'arm/smmu/updates', 'arm/smmu/bindings', 'rockchip', 'verisilicon', 'riscv', 'intel/vt-d', 'amd/amd-vi' and 'core' into next --- dd8a3c6cd531dca5917111a94fa3074077f6ba5a diff --cc drivers/iommu/amd/iommu.c index 57dc8fabc7d9b,f78e23f03938d,f78e23f03938d,f78e23f03938d,f78e23f03938d,f78e23f03938d,f78e23f03938d,f78e23f03938d,379e551877271,65082b9e4b525..563f9c2672d57 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@@@@@@@@@@ -1270,41 -1266,41 -1266,41 -1266,41 -1266,41 -1266,41 -1266,41 -1266,41 -1266,38 -1266,41 +1270,38 @@@@@@@@@@@ static void build_inv_dte(struct iommu_ * Builds an invalidation address which is suitable for one page or multiple * pages. Sets the size bit (S) as needed is more than one page is flushed. */ -------- -static inline u64 build_inv_address(u64 address, size_t size) ++++++++ +static inline u64 build_inv_address(u64 address, u64 last) { -------- - u64 pages, end, msb_diff; ------- - ------- - pages = iommu_num_pages(address, size, PAGE_SIZE); ++++++++ + unsigned int sz_lg2; - pages = iommu_num_pages(address, size, PAGE_SIZE); - -------- - if (pages == 1) -------- - return address & PAGE_MASK; -------- - -------- - end = address + size - 1; ++++++++ + address &= GENMASK_U64(63, 12); ++++++++ + sz_lg2 = fls64(address ^ last); ++++++++ + if (sz_lg2 <= 12) ++++++++ + return address; /* -------- - * msb_diff would hold the index of the most significant bit that -------- - * flipped between the start and end. ++++++++ + * Encode sz_lg2 according to Table 14: Example Page Size Encodings ++++++++ + * ++++++++ + * See "Note *": ++++++++ + * Address bits 51:32 can be used to encode page sizes greater ++++++++ + * that 4 Gbytes. ++++++++ + * Which we take to mean that the highest page size has bit ++++++++ + * [51]=0, [50:12]=1 ++++++++ + * and that coding happens when sz_lg2 is 52. Fall back to full ++++++++ + * invalidation if the size is too big. ++++++++ + * */ -------- - msb_diff = fls64(end ^ address) - 1; ++++++++ + if (unlikely(sz_lg2 > 52)) ++++++++ + return CMD_INV_IOMMU_ALL_PAGES_ADDRESS | ++++++++ + CMD_INV_IOMMU_PAGES_SIZE_MASK; /* -------- - * Bits 63:52 are sign extended. If for some reason bit 51 is different -------- - * between the start and the end, invalidate everything. ++++++++ + * The sz_lg2 calculation with fls() ensures that: ++++++++ + * address & BIT(sz_lg2 - 1) == 0 ++++++++ + * Therefore only the 1's need to be added. 8KB requires no 1's */ -------- - if (unlikely(msb_diff > 51)) { -------- - address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS; -------- - } else { -------- - /* -------- - * The msb-bit must be clear on the address. Just set all the -------- - * lower bits. -------- - */ -------- - address |= (1ull << msb_diff) - 1; -------- - } -------- - -------- - /* Clear bits 11:0 */ -------- - address &= PAGE_MASK; -------- - -------- - /* Set the size bit - we flush more than one 4kb page */ ++++++++ + if (sz_lg2 > 13) ++++++++ + address |= GENMASK_U64(sz_lg2 - 2, 12); return address | CMD_INV_IOMMU_PAGES_SIZE_MASK; } diff --cc drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index e8d7dbe495f03,e8d7dbe495f03,8ce3e801eda3b,e8d7dbe495f03,e8d7dbe495f03,e8d7dbe495f03,e8d7dbe495f03,e8d7dbe495f03,e8d7dbe495f03,4afdb775e0722..a10affb483a4f --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@@@@@@@@@@ -974,19 -974,19 -865,18 -974,19 -974,19 -974,19 -974,19 -974,19 -974,19 -974,19 +865,18 @@@@@@@@@@@ static void arm_smmu_cmdq_batch_add_cmd if (cmds->num == CMDQ_BATCH_ENTRIES) { arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmdq, cmds->cmds, cmds->num, false); -- ------- arm_smmu_cmdq_batch_init(smmu, cmds, cmd); - } - - index = cmds->num * CMDQ_ENT_DWORDS; - if (unlikely(arm_smmu_cmdq_build_cmd(&cmds->cmds[index], cmd))) { - dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n", - cmd->opcode); - return; ++ +++++++ arm_smmu_cmdq_batch_init_cmd(smmu, cmds, cmd); } -- ------ index = cmds->num * CMDQ_ENT_DWORDS; -- ------ if (unlikely(arm_smmu_cmdq_build_cmd(&cmds->cmds[index], cmd))) { -- ------ dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n", -- ------ cmd->opcode); -- ------ return; -- ------ } -- ------ -- ------- cmds->num++; ++ +++++++ cmds->cmds[cmds->num++] = *cmd; } ++ +++++++#define arm_smmu_cmdq_batch_add_cmd(smmu, cmds, cmd) \ ++ +++++++ ({ \ ++ +++++++ struct arm_smmu_cmd __cmd = cmd; \ ++ +++++++ arm_smmu_cmdq_batch_add_cmd_p(smmu, cmds, &__cmd); \ ++ +++++++ }) ++ +++++++ static int arm_smmu_cmdq_batch_submit(struct arm_smmu_device *smmu, struct arm_smmu_cmdq_batch *cmds) { diff --cc drivers/iommu/generic_pt/iommu_pt.h index dc91fb4e2f61c,19b6daf88f2ab,19b6daf88f2ab,19b6daf88f2ab,19b6daf88f2ab,19b6daf88f2ab,61c6d79c712cf,19b6daf88f2ab,19b6daf88f2ab,512c03f72d921..c2752151c80af --- a/drivers/iommu/generic_pt/iommu_pt.h +++ b/drivers/iommu/generic_pt/iommu_pt.h @@@@@@@@@@@ -40,11 -40,11 -40,11 -40,11 -40,11 -40,11 -40,36 -40,11 -40,11 -40,11 +40,36 @@@@@@@@@@@ static void flush_writes_item(const str PT_ITEM_WORD_SIZE); } ------ ---static void gather_range_pages(struct iommu_iotlb_gather *iotlb_gather, ------ --- struct pt_iommu *iommu_table, pt_vaddr_t iova, ------ --- pt_vaddr_t len, ------ --- struct iommu_pages_list *free_list) ++++++ +++struct iommupt_pending_gather { ++++++ +++ struct iommu_iotlb_gather *iotlb_gather; ++++++ +++ struct iommu_pages_list free_list; ++++++ +++ u8 leaf_levels_bitmap; ++++++ +++ u8 table_levels_bitmap; ++++++ +++}; ++++++ +++ ++++++ +++static void gather_add_table(struct iommupt_pending_gather *pending, ++++++ +++ const struct pt_state *pts, ++++++ +++ struct pt_table_p *table) ++++++ +++{ ++++++ +++ iommu_pages_list_add(&pending->free_list, table); ++++++ +++ if (pts_feature(pts, PT_FEAT_DETAILED_GATHER)) ++++++ +++ pending->table_levels_bitmap |= BIT(pts->level); ++++++ +++} ++++++ +++ ++++++ +++static void gather_add_leaf(struct iommupt_pending_gather *pending, ++++++ +++ const struct pt_state *pts) ++++++ ++ { ++++++ +++ if (!pts_feature(pts, PT_FEAT_DETAILED_GATHER)) ++++++ +++ return; ++++++ +++ ++++++ +++ pending->leaf_levels_bitmap |= BIT(pts->level); ++++++ +++} ++++++ +++ ++++++ +++static void gather_range_pending(struct iommupt_pending_gather *pending, ++++++ +++ struct pt_iommu *iommu_table, pt_vaddr_t iova, ++++++ +++ pt_vaddr_t len) +{ ++++++ +++ struct iommu_iotlb_gather *iotlb_gather = pending->iotlb_gather; struct pt_common *common = common_from_iommu(iommu_table); if (pt_feature(common, PT_FEAT_DMA_INCOHERENT))