1%
2% Copyright 2014, General Dynamics C4 Systems
3%
4% SPDX-License-Identifier: GPL-2.0-only
5%
6
7\chapter{\label{ch:io}Hardware I/O}
8
9\section{Interrupt Delivery}
10\label{sec:interrupts}
11
12Interrupts are delivered as notifications. A thread
13may configure the kernel to signal a particular \obj{Notification}
14object each time a certain interrupt triggers. Threads may then wait for
15interrupts to occur by calling \apifunc{seL4\_Wait}{sel4_wait} or
16\apifunc{seL4\_Poll}{sel4_poll} on
17that \obj{Notification}.
18
19
20\obj{IRQHandler} capabilities represent the ability of a thread to
21configure a certain interrupt. They have three methods:
22
23\begin{description}
24    \item[\apifunc{seL4\_IRQHandler\_SetNotification}{irq_handlersetnotification}]
25    specifies the \obj{Notification} the kernel should
26    \apifunc{signal}{sel4_signal} when an interrupt occurs. A driver
27    may then call \apifunc{seL4\_Wait}{sel4_wait} or \apifunc{seL4\_Poll}{sel4_poll}
28    on this notification to
29    wait for interrupts to arrive.
30
31    \item[\apifunc{seL4\_IRQHandler\_Ack}{irq_handleracknowledge}]
32    informs the kernel that the userspace driver has finished processing
33    the interrupt and the microkernel can send further pending or new
34    interrupts to the application.
35
36    \item[\apifunc{seL4\_IRQHandler\_Clear}{irq_handlerclear}]
37    de-registers the \obj{Notification} from the \obj{IRQHandler} object.
38\end{description}
39
40When the system first starts, no \obj{IRQHandler} capabilities are
41present. Instead, the initial thread's CSpace contains a single
42\obj{IRQControl} capability. This capability may be used to produce
43a single \obj{IRQHandler} capability for each interrupt available in the
44system. Typically, the initial thread of a system will determine which
45IRQs are required by other components in the system, produce an
46\obj{IRQHandler} capability for each interrupt, and then delegate the
47resulting capabilities as appropriate. Methods on \obj{IRQControl} can
48be used for creating \obj{IRQHandler} capabilities for interrupt sources.
49
50\ifxeightsix
51\section{x86-Specific I/O}
52
53\subsection{Interrupts}
54\label{sec:x86_interrupts}
55
56In addition to managing \obj{IRQHandler} capabilities, x86 platforms require
57the delivery location in the CPU vectors to be configured. Regardless of where
58an interrupt comes from (IOAPIC, MSI, etc) it must be assigned a unique vector
59for delivery, ranging from VECTOR\_MIN to VECTOR\_MAX. The rights to allocate
60a vector are effectively given through the \obj{IRQControl} capability and can
61be considered as the kernel outsourcing the allocation of this namespace to
62user level.
63
64\begin{description}
65    \item[\apifunc{seL4\_IRQControl\_GetIOAPIC}{x86_irq_handler_getioapic}] creates
66    an \obj{IRQHandler} capability for an IOAPIC interrupt
67
68    \item[\apifunc{seL4\_IRQControl\_GetMSI}{x86_irq_handler_getmsi}] creates
69    an \obj{IRQHandler} capability for an MSI interrupt
70\end{description}
71
72\subsection{I/O Ports}
73\label{sec:ioports}
74
75On x86 platforms, seL4 provides access to I/O ports to user-level threads.
76Access to I/O ports is controlled by \obj{IO Port} capabilities. Each
77\obj{IO Port} capability identifies a range of ports that can be accessed with
78it. Reading from I/O ports is accomplished with the
79\apifunc{seL4\_X86\_IOPort\_In8}{x86_io_port_in8},
80\apifunc{seL4\_X86\_IOPort\_In16}{x86_io_port_in16}, and
81\apifunc{seL4\_X86\_IOPort\_In32}{x86_io_port_in32} methods, which
82allow for reading of 8-, 16- and 32-bit quantities.
83Similarly, writing to I/O ports is accomplished with the
84\apifunc{seL4\_X86\_IOPort\_Out8}{x86_io_port_out8},
85\apifunc{seL4\_X86\_IOPort\_Out16}{x86_io_port_out16}, and
86\apifunc{seL4\_X86\_IOPort\_Out32}{x86_io_port_out32} methods.
87Each of these methods takes as arguments an \obj{IO Port} capability
88and an unsigned integer~\texttt{port}, which indicates the I/O port to read from
89or write to, respectively.
90In each case, \texttt{port} must be within the range of I/O ports identified
91by the given \obj{IO Port} capability in order for the method to succeed.
92
93The I/O port methods return error codes upon failure.
94A \texttt{seL4\_IllegalOperation} code is returned if port access is
95attempted outside the range allowed by the \obj{IO Port} capability. 
96Since invocations that
97read from I/O ports are required to return two values -- the value read
98and the error code -- a structure containing two members, \texttt{result}
99and \texttt{error}, is returned from these API calls.
100
101At system initialisation, the initial thread's \obj{CSpace} contains the
102\obj{IOPortControl} capability, which can be used to \apifunc{seL4\_X86\_IOPort\_Issue}{x86_ioport_issue}
103\obj{IO Port} capabilities to sub ranges of I/O ports. Any range that is issued
104may not have overlap with any existing issued \obj{IO Port} capability.
105
106\subsection{I/O Space}
107\label{sec:iospace}
108
109I/O devices capable of DMA present a security risk because the CPU's MMU
110is bypassed when the device accesses memory. In seL4, device drivers run
111in user space to keep them out of the trusted computing base.
112A malicious or buggy device driver may, however, program the device to
113access or corrupt memory that is not part of its address space, thus
114subverting security. To mitigate this threat, seL4 provides support for
115the IOMMU on Intel x86-based platforms. An IOMMU allows memory to be
116remapped from the device's point of view. It acts as an MMU for the
117device, restricting the regions of system memory that it can access.
118More information can be obtained from Intel's IOMMU documentation \cite{extra:vtd}.
119
120Two new objects are provided by the kernel to abstract the IOMMU:
121\begin{description}
122
123    \item[\obj{IOSpace}] This object represents the address space associated
124    with a hardware device on the PCI bus. It represents the right to
125    modify a device's memory mappings.
126
127    \item[\obj{IOPageTable}] This object represents a node in the multilevel
128    page-table structure used by IOMMU hardware to translate hardware
129    memory accesses.
130
131\end{description}
132
133\obj{Page} capabilities are used to represent the actual frames that are
134mapped into the I/O address space. A \obj{Page} can be mapped into
135either a \obj{VSpace} or an \obj{IOSpace} but never into both at the same time.
136
137\obj{IOSpace} and \obj{VSpace} fault handling differ significantly.
138\obj{VSpace} page faults are redirected to the thread's exception handler (see \autoref{sec:faults}), 
139which can take the
140appropriate action and restart the thread at the faulting instruction.
141There is no concept of an exception handler for an \obj{IOSpace}. Instead, faulting
142transactions are simply
143aborted; the device driver must correct the cause of the fault and retry
144the DMA transaction.
145
146An initial master \obj{IOSpace} capability is provided in the initial thread's
147CSpace. An \obj{IOSpace} capability for a specific device is created by
148using the \apifunc{seL4\_CNode\_Mint}{cnode_mint} method, passing the
149PCI identifier of the device as the low 16 bits of the \texttt{badge} argument, and
150a Domain ID as the high 16 bits of the \texttt{badge} argument.
151PCI identifiers are explained fully in the PCI specification 
152\cite{Shanley:PCISA}, but are briefly described here. A PCI identifier is
153a 16-bit quantity.  The first 8 bits identify the bus that the device is on.
154The next 5 bits are the device identifier: the number of the device on
155the bus. The last 3 bits are the function number. A single device may
156consist of several independent functions, each of which may be addressed
157by the PCI identifier.
158Domain IDs are explained fully in the Intel IOMMU documentation \cite{extra:vtd}.
159There is presently no way to query seL4 for how many Domain IDs are supported by
160the IOMMU and the \apifunc{seL4\_CNode\_Mint}{cnode_mint} method will fail if an
161unsupported value is chosen.
162
163The IOMMU page-table structure has three levels.
164Page tables are mapped into an \obj{IOSpace} using the \apifunc{seL4\_X86\_IOPageTable\_Map}{x86_io_page_table_map} method.
165This method takes the \obj{IOPageTable} to map, the \obj{IOSpace} to map into 
166and the address to map at. Three levels of page tables must be mapped before
167a frame can be mapped successfully. A frame is mapped with the
168\apifunc{seL4\_X86\_Page\_MapIO}{x86_page_map_io} method whose parameters are analogous to
169the corresponding method that maps \obj{Page}s into \obj{VSpaces} (see \autoref{ch:vspace}), 
170namely \apifunc{seL4\_X86\_Page\_Map}{x86_page_map}.
171
172Unmapping is accomplished with the usual unmap (see \autoref{ch:vspace}) API 
173call,
174\apifunc{seL4\_X86\_Page\_Unmap}{x86_page_unmap}.
175
176More information about seL4's IOMMU abstractions can be found in \cite{Palande:M}.
177\fi
178
179\section{Arm-Specific I/O}
180
181\subsection{Arm SMMU version 2.0}
182\label{sec:smmuv2}
183
184
185seL4 provides an API for programming the Arm System MMU (SMMU) version 2.0,
186which allows system software to manage access rights and address translation for
187devices that can initiate direct memory accesses (DMA).
188
189An Arm SMMU v2.0 implementation allows device memory transactions to be associated
190with an identifier (StreamID) that is used to direct the transaction through a
191SMMU translation context bank (CB). A translation context bank can perform
192address translation, memory protection and memory attribute transformation.
193The standard specifies different types of address translations that correspond
194to stages in the ArmV8 virtual memory system architecture such as either 
195non-secure  EL0, EL1 first and second stage translations, Hyp mode translations
196or secure mode translations. It is possible to associate different StreamIDs
197with the same context bank and it is possible to share address translation
198tables between a context bank and software MMU address space if the stage and type
199of translation is the same.
200
201Faults that occur when a memory transaction conflicts with a StreamID or CB
202configuration happen asynchronously with respect to a processor element's
203execution. When this occurs an interrupt is used to allow a PE to handle the
204SMMU fault. Faults are reported through registers in the SMMU that can be
205queried in an interrupt handler.
206
207TLB maintenance operations are required to keep SMMU translation caches
208consistent when there are changes to any valid page table mapping entries.
209
210An SMMU implementation usually has a maximum number of StreamIDs that it supports.
211The specificiation allows StreamIDs to be up to 16bits wide. There are also a
212fixed number of context banks, up to a maximum of 128. Context banks can
213be generic or support only a single address translation stage. This information
214is reported by ID registers in each implementation.
215
216The seL4 API allows system software to manage an SMMU by assigning StreamIDs to
217context banks, bind context banks to page translation structures, implement
218SMMU fault handling and also perform explicit TLB maintenance.
219This allows system software to ensure that a device is only able to access and
220modify memory contents that it has been explicitly given access to and allow
221devices to be presented with a virtualized address space for performing DMA.
222
223All the StreamIDs and context banks are accessible via capabilities. Control
224capabilities are used to create capabilities referring to each StreamID and
225context bank in a system. The kernel tracks the allocation of StreamIDs and
226context banks with two static CNodes, one for each resource type. These CNodes
227track which VSpace a context bank has bound to it, and which context bank a
228StreamID is bound to.
229
230The capabilities allow access control policies to be implemented by a user thread.
231When StreamID, context bank capabilities are revoked, the kernel will disable
232the context banks or StreamID mappings.
233
234TLB maintenance is handled by the kernel via tracking which context banks are
235associated with a particular VSpace. Any TLB maintenance operations that the
236kernel performs on VSpace invocations are also applied to associated context
237banks.
238
239SMMU fault handling is delegated to user level via invocations that allow fault
240statuses to be queried and cleared for each context bank and for the SMMU globally.
241SMMU fault interrupts can be handled the same as other platform level interrupts.
242
243The kernel implementation only uses translation stages matching what translation
244the kernel is performing for VSpace objects. When seL4 is operating in EL1,
245the SMMU only uses stage 1 translation (ASID), that is "stage 1 with stage 2
246bypass" in the context bank attribute configuration. When hypervisor mode is
247enabled, and seL4 is operating in EL2, the SMMU only does stage 2 translations.
248
249Four capabilities types provide access to SMMU resources:
250\begin{description}
251    \item[\obj{seL4\_ARM\_SID}] A capability granting access to a single 
252        transaction stream, which can be used to bind and unbind a stream to a
253        single context bank.
254    \item[\obj{seL4\_ARM\_CB}] A capbility representing a single specific context
255        bank. It can be used to bind and unbind a VSpace to assign what page
256        tables the context bank should use for translation, assign StreamIDs and
257        process context bank faults.
258    \item[\obj{seL4\_ARM\_SIDControl}] A control capability which can be used to
259        create \obj{seL4\_ARM\_SID} capabilities to specific transaction streams.
260        The \obj{seL4\_ARM\_SIDControl} cap is used for managing rights on
261        StreamID configurations. This capability is provided in the initial
262        thread's CSpace.
263    \item[\obj{seL4\_ARM\_CBControl}] A control capability that can be used to
264        derive \obj{seL4\_ARM\_CB} capabilities. The \obj{seL4\_ARM\_CBControl}
265        cap is used for managing rights on context bank configurations.
266        This capability is provided in the initial thread's CSpace.
267\end{description}
268
269
270\subsubsection{Creating \obj{seL4\_ARM\_SID} capabilities}
271\label{sec:smmuv2-creating-sel4-arm-sid-capabilities}
272
273The Arm SMMU 2.0 specification doesn't specify how StreamIDs need to correspond
274to different devices. Each platform can define its own policy for how StreamIDs
275are allocated. A \obj{seL4\_ARM\_SIDControl} capability can be used to create
276a capability to any valid StreamID for the SMMU and delegate access to other
277tasks in the system.
278
279\begin{description}
280\item[\apifunc{seL4\_ARM\_SIDControl\_GetSID}{arm_sid_controlgetsid}] uses the
281    \obj{seL4\_ARM\_SIDControl} capability to create a new \obj{seL4\_ARM\_SID}
282    capability that represents a single StreamID.  This new capbility is placed
283    in the provided slot.  It is expected that whatever thread controls an 
284    \obj{seL4\_ARM\_SIDControl} capability knows about how StreamIDs are
285    allocated in a system.
286\end{description}
287
288The Arm SMMU 2.0 specification descibes many ways of associating StreamIDs with
289context banks. Currently only direct mapping of a StreamID to a context bank is
290supported.
291
292\subsubsection{Creating \obj{seL4\_ARM\_CB} capabilities}
293\label{sec:smmuv2-creating-sel4-arm-cb-capabilities}
294
295Each context bank allows the SMMU to maintain an active translation context with
296it's own registers for holding context specific information. An SMMU has a fixed
297number of context banks available for use and these are allocated using the
298\obj{seL4\_ARM\_CBControl} capability.
299
300\begin{description}
301
302\item[\apifunc{seL4\_ARM\_CBControl\_GetCB}{arm_cb_controlgetcb}] uses the
303    \obj{seL4\_ARM\_CBControl} capability to create a new \obj{seL4\_ARM\_CB}
304    capability that represents a single context bank.  This new capability is
305    placed in the provided slot.  It is expected that whatever thread controls a
306    \obj{seL4\_ARM\_CBControl} capability has knowledge of the properties of each
307    context bank that each index refers to.
308\end{description}
309
310
311\subsubsection{Configuring context banks}
312\label{sec:smmuv2-configuring-context-banks}
313
314By providing a \obj{seL4\_ARM\_CB} cap, a user-level thread can configure the
315VSpace used by the bank with the following API:
316
317\begin{description}
318    \item[\apifunc{seL4\_ARM\_CB\_AssignVspace}{arm_cb_assignvspace}] configures
319        the context bank to use the provided VSapce root for translations.
320    \item[\apifunc{seL4\_ARM\_CB\_UnassignVspace}{arm_cb_unassignvspace}] removes
321        the configured VSpace and conducting a TLB invalidation.
322\end{description}
323
324The SMMU-v2 uses the same paging structure as the MMU (AArch\_64 and AArch\_32
325formats). Therefore, there is no need to provide a new set of page structure caps
326nor a separate set of map and unmap functions. To manage the assignment, the
327kernel has an internal CNode, called smmuStateCBNode, that stores copies of the
328\obj{VSpace\_cap} created by executing the above API. The copy of the
329\obj{VSpace\_cap} contains its assigned ContextBank number. Therefore the kernel
330can conduct context bank invalidation if the \obj{VSpace\_cap} is revoked.
331
332
333\subsubsection{Configuring streams (transactions)}
334\label{sec:smmuv2-configuring-streams-transactions}
335
336A user-level thread can bind a context bank with an \obj{seL4\_ARM\_SID}
337capability with:
338\begin{description}
339    \item[\apifunc{seL4\_ARM\_SID\_BindCB}{arm_sid_bindcb}] configures the stream
340        to use given context bank for translation. To simplify the process, the
341        binding also enables the stream ID.  \obj{seL4\_ARM\_SID\_BindCB}
342        generates a copy of the \obj{seL4\_ARM\_CB} cap in kernel's internal
343        CNode. This allows the stream ID to be disabled if the
344        \obj{seL4\_ARM\_CB} cap is revoked.
345    \item[\apifunc{seL4\_ARM\_SID\_UnbindCB}{arm_sid_unbindcb}] removes the
346        \obj{seL4\_ARM\_CB} cap from the kernel's internal CNode and disables
347        the stream ID. The kernel provides this API for the conveniences of
348        sharing a stream ID among multiple VSpaces.
349\end{description}
350
351If there are any exceptions after the stream ID is enabled, the user-level
352software should use the fault handling mechanisms to resolve them.
353
354
355
356\subsubsection{Copying and Deleting caps}
357\label{sec:smmuv2-copying-and-deleting-caps}
358The kernel allows copying both \obj{ARM\_SID} cap and \obj{seL4\_ARM\_CB} cap.
359This allows capabilites to be delegated to different threads.
360The kernel does not allow copying neither the \obj{seL4\_ARM\_SIDControl} nor
361the \obj{seL4\_ARM\_CBControl} capabilities.
362
363Deleting a \obj{seL4\_ARM\_CB} cap that contains a valid capBindSID field will:
364\begin{itemize}
365    \item invalidate the streamID to ContextBank assignment in hardware.
366\end{itemize}
367
368Deleting the last \obj{seL4\_ARM\_CB} cap will:
369\begin{itemize}
370    \item perform an \apifunc{seL4\_ARM\_CB\_UnassignVspace}{arm_cb_unassignvspace},
371    removing any configured VSpace,
372    \item conduct a TLB invalidation.
373\end{itemize}
374
375Similarly, deleting a VSpace\_cap that contains assigned context bank number will:
376\begin{itemize}
377    \item invalidate the context bank
378    \item conduct a TLB invalidation
379\end{itemize}
380
381Deleting the last ARM\_SID cap will:
382\begin{itemize}
383    \item Perform an \apifunc{seL4\_ARM\_SID\_UnbindCB}{arm_sid_unbindcb}, 
384        (deleting the copy of the assigned \obj{seL4\_ARM\_CB} cap)
385    \item Disable the stream ID.
386\end{itemize}
387
388\subsubsection{TLB invalidation}
389\label{sec:smmuv2-tlb-invalidation}
390The kernel is expected to perform all required SMMU TLB maintenance operations
391as part of the API implementation.  In addition, the kernel provides two system
392calls for explicitly performing invalidations:
393\begin{description}
394    \item[\apifunc{seL4\_ARM\_CBControl\_TLBInvalidateAll}{arm_cb_controltlbinvalidate}]
395        invalidates all TLB entries in all
396    context banks.
397    \item[\apifunc{seL4\_ARM\_CB\_TLBInvalidate}{arm_cb_tlbinvalidate}]
398        invalidates all TLB entries in a context bank.
399\end{description}
400
401The kernel does not impose any restrictions on how a VSpace is used by user-level
402applications, hence a VSpace can be shared by normal threads and drivers. Sharing
403a VSpace between threads and drivers also means sharing all mappings in that
404VSpace between MMUs in CPU cores and SMMU used by device transactions. Moreover,
405multiple context banks in SMMU can share a VSpace. Therefore, maintaining the
406coherency between the TLB in MMU and the TLB in SMMU's context banks is important.
407
408The kernel keeps a record of Vspace's usage in context banks in SMMU by
409maintaining: the number of context banks using a given ASID, and the ASID that a
410given context bank is using. There are a few reasons behind this design.
411\begin{itemize}
412\item First, the ASID is efficient for representing a VSpace. In seL4, each VSpace has
413an ASID which is assigned before the VSpace is ready to be used and will never
414change until the VSpace is deleted. Recording how many context banks are using a
415VSpace's ASID is equivalent to recording the VSpace's usage in context banks.
416\item Second, all TLB invalidation operation requires knowledge of the ASID. There are
417two types of TLB invalidation operations: invalidating a page table entry using
418its ASID (triggered by updating a page table entry, e.g. unmapping a page), and
419invalidating all mappings of an ASID (triggered by deleting a VSpace).
420\item Third, the kernel can easily find a context banks' ASID on all occasions, which is
421useful to either conduct TLB invalidation requests or unassign VSpace from a
422context bank.
423\end{itemize}
424
425By knowing how many context banks are using an ASID, the kernel can easily check
426in every TLB invalidation operation and invoke TLB invalidation in SMMU if the
427value is not zero. In SMMU's TLB invalidation operation, the kernel searches the
428context banks using the ASID, and conducts TLB invalidation in those context banks.
429
430Ideally, the SMMU shares the same ASID or VMID name space with the rest of the
431system. This allows the SMMU to maintain TLB coherency by listening for TLB
432broadcasting messages. This means the context banks should be configured with
433the correct ASID or VMID when the StreamID is enabled. This is not a problem for
434stage 1 translation, as there are a large number of ASID bits and an ASID can be
435assigned to a vspace root with existing APIs. However, the VMID used in stage 2
436only has 8 bits, and the kernel allocates them on demand and can reclaim a
437VSpace's hardware ASID to reuse if there are more VSpaces than available ASIDS.
438While it is possible to do this when the VSpace is only used in an MMU, it is
439not possible with multiple active context banks.
440Due to this, the context bank in SMMU cannot be configured with the correct VMID.
441Currently, the SMMU driver uses private VMID space, and uses the context bank
442number as the corresponding VMID number.
443
444
445
446\subsubsection{Fault handling}
447\label{sec:smmuv2-fault-handling}
448The number of IRQs used for reporting transaction faults is hardware dependent.
449There are two kinds of faults: global faults ( general configuration and
450transaction faults), or context bank faults. For transaction faults, the SMMU
451reports faulty stream IDs. The global faults reports:
452\begin{itemize}
453    \item Invalid context fault.
454    \item Unidentified stream fault.
455    \item Stream match conflict fault.
456    \item Unimplemented context bank fault.
457    \item Unimplemented context interrupt fault.
458    \item Configuration access fault.
459    \item External fault.
460\end{itemize}
461Each context bank contains registers to report faults on address translation, for
462example, faulty addresses, or permission errors. The SMMU driver identifies the
463cause of a fault by first reading the global fault registers (one state register
464and three fault syndrome registers), then by reading corresponding context bank
465fault registers. Note, the SMMU reports the faulty transaction (stream) ID,
466which can be used to identify its context bank ID.
467
468\begin{itemize}
469\item System assumption: Both the SMMU's IRQ handler and the owner of the
470    \obj{seL4\_ARM\_SIDControl} cap (controlling stream ID distributions) are trusted.
471\item SMMU interrupts are handled as same as other IRQs, i,e, the kernel does not
472    treat the SMMU IRQs special, reporting the interrupt via IRQ notifications.
473\item The kernel provides a API for reading the global fault registers: 
474    \apifunc{seL4\_ARM\_SIDControl\_GetFault}{arm_sid_controlgetfault}. Because
475    the IRQ notification can only deliver information via the badge, the owner
476    of the StreamControl\_cap can retrieve more information via this API.
477\item If the fault is related to a transaction, the owner of the
478    \obj{seL4\_ARM\_SIDControl} cap will notify the holder of the corresponding
479    stream ID cap, which should also have a copy of the context bank cap bound to
480    this transaction.
481\item The kernel provides an API for reading the context bank fault registers:
482    \apifunc{seL4\_ARM\_CB\_CBGetFault}{arm_cb_getfault}, used by a context bank
483    cap holder (the \obj{seL4\_ARM\_CB} cap holder).
484\item Once the fault handling is done, the server can call
485    \apifunc{seL4\_ARM\_CB\_CBClearFault}{arm_cb_clearfault} to clear the fault
486    status on a context bank, and 
487    \apifunc{seL4\_ARM\_SIDControl\_ClearFault}{arm_sid_controlclearfault}
488    to clear the fault status on SMMU.
489\end{itemize}
490
491