This adds interrupt remapping to the virtio-IOMMU device. This is needed to support deprivileged userspace drivers on x86_64 and other platforms where interrupt remapping is the job of the IOMMU. It is not needed on AArch64 and must not be supported on that platform. --- device-types/iommu/description.tex | 70 +++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/device-types/iommu/description.tex b/device-types/iommu/description.tex index f8cbe88..0a3bcab 100644 --- a/device-types/iommu/description.tex +++ b/device-types/iommu/description.tex @@ -3,7 +3,8 @@ \section{IOMMU device}\label{sec:Device Types / IOMMU Device} The virtio-iommu device manages Direct Memory Access (DMA) from one or more endpoints. It may act both as a proxy for physical IOMMUs managing devices assigned to the guest, and as virtual IOMMU managing emulated and -paravirtualized devices. +paravirtualized devices. On some platforms, it is also responsible for +interrupt remapping. The driver first discovers endpoints managed by the virtio-iommu device using platform specific mechanisms. It then sends requests to create @@ -74,6 +75,13 @@ \subsection{Feature bits}\label{sec:Device Types / IOMMU Device / Feature bits} whether endpoints that are attached to a domain are in bypass mode. +\item[VIRTIO_IOMMU_F_IRQ_MAP_UNMAP (7)] + Interrupt remapping is available. This is architecture specific + and MUST NOT be negotiated on architectures such as AArch64 where + interrupt remapping is not handled by the IOMMU. If this feature + is negotiated, all interrupts from endpoints that are not in + bypass mode are initially disabled. + \end{description} \drivernormative{\subsubsection}{Feature bits}{Device Types / IOMMU Device / Feature bits} @@ -531,6 +539,66 @@ \subsubsection{MAP request}\label{sec:Device Types / IOMMU Device / Device opera range mapped with VIRTIO_IOMMU_MAP_F_WRITE but not VIRTIO_IOMMU_MAP_F_READ. +\subsubsection{IRQ MAP request}\label{sec:Device Types / IOMMU Device / Device operations / IRQ MAP request} + +\begin{lstlisting} +struct virtio_iommu_req_irq_map { + struct virtio_iommu_req_head head; + le32 domain; + le64 msi_address; + le32 msi_payload; + le32 vector_id; + le32 vcpu_id; + le32 flags; + u8 reserved[4]; + struct virtio_iommu_req_tail tail; +}; +\end{lstlisting} + +Map a host MSI to a guest MSI directed at the given vCPU. vCPUs range from 0 to +$2^{32} - 2$ inclusive. $2^{32} - 1$ is reserved and means ``no vCPU'', +effectively disabling the interrupt. Any previous mapping of the MSI is overwritten. + +This request takes effect immediately. It is the device's job to flush caches if +necessary. However, any interrupts that are pending remain pending. + +The set of permitted values for \field{msi_address} and \field{msi_payload} +is architecture-dependent. Invalid values include, but are not limited to: + +\begin{itemize} +\item Values that are not in the architecture-dependent range of MSI addresses. +\item Values that have bits set that are ignored by the physical IOMMU. +\item Values that have reserved bits set. +\item Values that would cause the MSI to not be subject to interrupt remapping, + and which the host must therefore block for its own security. +\end{itemize} + +This request is only available when VIRTIO_IOMMU_F_IRQ_MAP_UNMAP has been negotiated. + +\drivernormative{\paragraph}{IRQ MAP request}{Device Types / IOMMU Device / Device operations / IRQ MAP request} + +The driver SHOULD set undefined \field{flags} bits to zero. + +The driver SHOULD NOT send IRQ MAP requests on a bypass domain. + +The driver SHOULD NOT choose values for \field{msi_address} or \field{msi_payload} +that are invalid for the CPU architecture. + +The driver SHOULD NOT choose a \field{vcpu_id} that corresponds to a vCPU that does +not exist and is not $2^{32} - 1$. + +\devicenormative{\paragraph}{IRQ MAP request}{Device Types / IOMMU Device / Device operations / IRQ MAP request} + +If \field{msi_address} or \field{msi_payload} is invalid for the CPU architecture, +the device SHOULD reject the request and set \field{status} to VIRTIO_IOMMU_S_INVAL. + +If \field{domain} does not exist, the device SHOULD reject the request and +set \field{status} to VIRTIO_IOMMU_S_NOENT. + +If \field{vcpu_id} does not correspond to a CPU that is running in the guest +and is not $2^{32} - 1$, the device SHOULD reject the request and set +\field{status} to VIRTIO_IOMMU_S_NOENT. + \subsubsection{UNMAP request}\label{sec:Device Types / IOMMU Device / Device operations / UNMAP request} \begin{lstlisting} -- Sincerely, Demi Marie Obenour