[PATCH 04/19] iommu/arm-smmu-v3: Make STE programming independent of the callers

Michael Shavit mshavit at google.com
Mon Dec 25 04:17:14 PST 2023


On Tue, Dec 19, 2023 at 9:42 PM Michael Shavit <mshavit at google.com> wrote:
>
>
> +static void arm_smmu_write_entry(struct arm_smmu_entry_writer *writer,
> +                                __le64 *cur, const __le64 *target,
> +                                __le64 *staging_entry)
> +{
> +       bool cleanup_sync_required = false;
> +       u8 entry_qwords_used_diff = 0;
> +       int i = 0;
> +
> +       entry_qwords_used_diff =
> +               writer->ops.get_used_qword_diff_indexes(cur, target);
> +       if (WARN_ON_ONCE(entry_qwords_used_diff == 0))
> +               return;
> +
> +       if (hweight8(entry_qwords_used_diff) > 1) {
> +               /*
> +                * If transitioning to the target entry with a single qword
> +                * write isn't possible, then we must first transition to an
> +                * intermediate entry. The intermediate entry may either be an
> +                * entry that melds bits of the target entry into the current
> +                * entry without disrupting the hardware, or a breaking entry if
> +                * a hitless transition to the target is impossible.
> +                */
> +
> +               /*
> +                * Compute a staging entry that has all the bits currently
> +                * unused by HW set to their target values, such that comitting
> +                * it to the entry table woudn't disrupt the hardware.
> +                */
> +               memcpy(staging_entry, cur, writer->entry_length);

This should be `memcpy(staging_entry, cur, writer->entry_length *
sizeof(cur[0]));`

>
> +               writer->ops.set_unused_bits(staging_entry, target);
> +
> +               entry_qwords_used_diff =
> +                       writer->ops.get_used_qword_diff_indexes(staging_entry,
> +                                                               target);
> +               if (hweight8(entry_qwords_used_diff) > 1) {
> +                       /*
> +                        * More than 1 qword is mismatched between the staging
> +                        * and target entry. A hitless transition to the target
> +                        * entry is not possible. Set the staging entry to be
> +                        * equal to the target entry, apart from the V bit's
> +                        * qword. As long as the V bit is cleared first then
> +                        * writes to the subsequent qwords will not further
> +                        * disrupt the hardware.
> +                        */
> +                       memcpy(staging_entry, target, writer->entry_length);

 ditto, this should be `memcpy(staging_entry, target,
writer->entry_length * sizeof(target[0]));`



More information about the linux-arm-kernel mailing list