[PATCH v7 5/7] arm64: Add support for FEAT_{LS64, LS64_V}

Arnd Bergmann arnd at arndb.de
Thu Nov 13 08:26:30 PST 2025


On Thu, Nov 13, 2025, at 15:40, Zhou Wang wrote:
> On 2025/11/11 19:15, Marc Zyngier wrote:
>> On Fri, 07 Nov 2025 07:21:25 +0000,
>> 
>> But this doesn't mean that the system actually supports this. It is
>> also trivial for EL0 to spoof a PASID using ST64BV, by populating the
>> bottom 32bit with whatever it wants (hiding ST64BV0 doesn't prevent
>> this).
>
> I am confused here, we enable FEAT_LS64 and FEAT_LS64V in this patch,
> so only LD64B/ST64B/ST64BV are involved.
>
> Sending the value of ACCDATA(maybe a PASID) is defined in ST64BV0, which
> is not enabled currently.
>
> If a bad system implements ST64BV wrongly, isn't the fault of this bad
> system?

As far as I can tell, the design of ST64BV/ST64BV0 is a bit vague
on this, both on the Arm architecture and the PCI side [1], which each
leave the meaning of ACCDATA open to system design.

However, when the intention is to implement a shared hardware workqueue
in the style of drivers/dma/idxd/ [2], the only sensible implementation
is to follow the way that the corresponding Intel instructions work:

- movdir64b/st64b is a nonprivileged instruction to produce a posted
  atomic 64-byte write TLP to a PCIe device, which can only be used
  with a dedicated workqueue that is preconfigured to a fixed PASID

- enqcmds/st64bv is a privileged instruction to produce a non-posted
  atomic 64-byte write Deferrable Memory Write (DMWr) TLP, which can be
  used on a shared workqueue from kernel space, using an arbitrary PASID
  value per transaction, which would normally correspond to the
  physical address space when the kernel initiates DMA.

- enqcmd/st64bv0 is a nonprivileged instruction like enqcmds/st64bv
  using the pasid from accdata that corresponds to 
  current->mm->iommu_mm->pasid value [3] in the kernel for the task
  that initates the transaction in userspace.

A PCIe device can tell the difference between a posted write and a
non-posted DMWr, but it cannot tell the difference between st64bv
and st64bv0, so the kernel must disallow st64bv from userspace if
it can be used on a device that expects the PASID value in the
low bits.

Things would be different if there is a PCIe device that expects
a DMWr transaction but does not use it for a shared hardware
workqueue with the PASID in that field.

Are you using a particular device, or are you trying to enable
the support in general? If you have a specific device you are
working on, does it use the PASID data or not?

Things will clearly get a lot harder if we want to support a
system that can have devices with conflicting interpretations
of the ACCDATA value. Ideally we could always use the
iommu_mm->pasid value here and enable st64bv0 globally like
idxd does. If any devices requires the use of st64bv, that
would have to be mutually exclusive with another driver
handing out access to shared hardware workqueues.

     Arnd

[1] https://members.pcisig.com/wg/PCI-SIG/document/14237
[2] https://www.kernel.org/doc/html/v6.1/x86/sva.html
[3] drivers/iommu/iommu-sva.c



More information about the linux-arm-kernel mailing list