[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