€•‘Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ//translations/zh_CN/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ//translations/zh_TW/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ//translations/it_IT/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ//translations/ja_JP/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ//translations/ko_KR/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ//translations/pt_BR/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ//translations/sp_SP/core-api/real-time/hardware”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒI/var/lib/git/docbuild/linux/Documentation/core-api/real-time/hardware.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒConsidering hardware”h]”hŒConsidering hardware”…””}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ field_list”“”)”}”(hhh]”hŒfield”“”)”}”(hhh]”(hŒ field_name”“”)”}”(hŒAuthor”h]”hŒAuthor”…””}”(hhéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hçhhäh³hÇh´KubhŒ field_body”“”)”}”(hŒ2Sebastian Andrzej Siewior ”h]”hŒ paragraph”“”)”}”(hŒ1Sebastian Andrzej Siewior ”h]”(hŒSebastian Andrzej Siewior <”…””}”(hhÿh²hh³Nh´NubhŒ reference”“”)”}”(hŒbigeasy@linutronix.de”h]”hŒbigeasy@linutronix.de”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:bigeasy@linutronix.de”uh1jhhÿubhŒ>”…””}”(hhÿh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Khhùubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhäubeh}”(h]”h ]”h"]”h$]”h&]”uh1hâh³hÇh´Khhßh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhhÊh²hh³hÇh´Kubhþ)”}”(hXfThe way a workload is handled can be influenced by the hardware it runs on. Key components include the CPU, memory, and the buses that connect them. These resources are shared among all applications on the system. As a result, heavy utilization of one resource by a single application can affect the deterministic handling of workloads in other applications.”h]”hXfThe way a workload is handled can be influenced by the hardware it runs on. Key components include the CPU, memory, and the buses that connect them. These resources are shared among all applications on the system. As a result, heavy utilization of one resource by a single application can affect the deterministic handling of workloads in other applications.”…””}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K hhÊh²hubhþ)”}”(hŒBelow is a brief overview.”h]”hŒBelow is a brief overview.”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhhÊh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒSystem memory and cache”h]”hŒSystem memory and cache”…””}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjQh²hh³hÇh´Kubhþ)”}”(hXTMain memory and the associated caches are the most common shared resources among tasks in a system. One task can dominate the available caches, forcing another task to wait until a cache line is written back to main memory before it can proceed. The impact of this contention varies based on write patterns and the size of the caches available. Larger caches may reduce stalls because more lines can be buffered before being written back. Conversely, certain write patterns may trigger the cache controller to flush many lines at once, causing applications to stall until the operation completes.”h]”hXTMain memory and the associated caches are the most common shared resources among tasks in a system. One task can dominate the available caches, forcing another task to wait until a cache line is written back to main memory before it can proceed. The impact of this contention varies based on write patterns and the size of the caches available. Larger caches may reduce stalls because more lines can be buffered before being written back. Conversely, certain write patterns may trigger the cache controller to flush many lines at once, causing applications to stall until the operation completes.”…””}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhjQh²hubhþ)”}”(hX>This issue can be partly mitigated if applications do not share the same CPU cache. The kernel is aware of the cache topology and exports this information to user space. Tools such as **lstopo** from the Portable Hardware Locality (hwloc) project (https://www.open-mpi.org/projects/hwloc/) can visualize the hierarchy.”h]”(hŒ¸This issue can be partly mitigated if applications do not share the same CPU cache. The kernel is aware of the cache topology and exports this information to user space. Tools such as ”…””}”(hjph²hh³Nh´NubhŒstrong”“”)”}”(hŒ **lstopo**”h]”hŒlstopo”…””}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhjpubhŒ6 from the Portable Hardware Locality (hwloc) project (”…””}”(hjph²hh³Nh´Nubj)”}”(hŒ(https://www.open-mpi.org/projects/hwloc/”h]”hŒ(https://www.open-mpi.org/projects/hwloc/”…””}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jŽuh1jhjpubhŒ) can visualize the hierarchy.”…””}”(hjph²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhjQh²hubhþ)”}”(hXAvoiding shared L2 or L3 caches is not always possible. Even when cache sharing is minimized, bottlenecks can still occur when accessing system memory. Memory is used not only by the CPU but also by peripheral devices via DMA, such as graphics cards or network adapters.”h]”hXAvoiding shared L2 or L3 caches is not always possible. Even when cache sharing is minimized, bottlenecks can still occur when accessing system memory. Memory is used not only by the CPU but also by peripheral devices via DMA, such as graphics cards or network adapters.”…””}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K"hjQh²hubhþ)”}”(hX±In some cases, cache and memory bottlenecks can be controlled if the hardware provides the necessary support. On x86 systems, Intel offers Cache Allocation Technology (CAT), which enables cache partitioning among applications and provides control over the interconnect. AMD provides similar functionality under Platform Quality of Service (PQoS). On Arm64, the equivalent is Memory System Resource Partitioning and Monitoring (MPAM).”h]”hX±In some cases, cache and memory bottlenecks can be controlled if the hardware provides the necessary support. On x86 systems, Intel offers Cache Allocation Technology (CAT), which enables cache partitioning among applications and provides control over the interconnect. AMD provides similar functionality under Platform Quality of Service (PQoS). On Arm64, the equivalent is Memory System Resource Partitioning and Monitoring (MPAM).”…””}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K'hjQh²hubhþ)”}”(hŒ†These features can be configured through the Linux Resource Control interface. For details, see Documentation/filesystems/resctrl.rst.”h]”hŒ†These features can be configured through the Linux Resource Control interface. For details, see Documentation/filesystems/resctrl.rst.”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K.hjQh²hubhþ)”}”(hXPThe perf tool can be used to monitor cache behavior. It can analyze cache misses of an application and compare how they change under different workloads on a neighboring CPU. Even more powerful, the perf c2c tool can help identify cache-to-cache issues, where multiple CPU cores repeatedly access and modify data on the same cache line.”h]”hXPThe perf tool can be used to monitor cache behavior. It can analyze cache misses of an application and compare how they change under different workloads on a neighboring CPU. Even more powerful, the perf c2c tool can help identify cache-to-cache issues, where multiple CPU cores repeatedly access and modify data on the same cache line.”…””}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K1hjQh²hubeh}”(h]”Œsystem-memory-and-cache”ah ]”h"]”Œsystem memory and cache”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒHardware buses”h]”hŒHardware buses”…””}”(hjèh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjåh²hh³hÇh´K8ubhþ)”}”(hXXReal-time systems often need to access hardware directly to perform their work. Any latency in this process is undesirable, as it can affect the outcome of the task. For example, on an I/O bus, a changed output may not become immediately visible but instead appear with variable delay depending on the latency of the bus used for communication.”h]”hXXReal-time systems often need to access hardware directly to perform their work. Any latency in this process is undesirable, as it can affect the outcome of the task. For example, on an I/O bus, a changed output may not become immediately visible but instead appear with variable delay depending on the latency of the bus used for communication.”…””}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K:hjåh²hubhþ)”}”(hŒ»A bus such as PCI is relatively simple because register accesses are routed directly to the connected device. In the worst case, a read operation stalls the CPU until the device responds.”h]”hŒ»A bus such as PCI is relatively simple because register accesses are routed directly to the connected device. In the worst case, a read operation stalls the CPU until the device responds.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K@hjåh²hubhþ)”}”(hX›A bus such as USB is more complex, involving multiple layers. A register read or write is wrapped in a USB Request Block (URB), which is then sent by the USB host controller to the device. Timing and latency are influenced by the underlying USB bus. Requests cannot be sent immediately; they must align with the next frame boundary according to the endpoint type and the host controller's scheduling rules. This can introduce delays and additional latency. For example, a network device connected via USB may still deliver sufficient throughput, but the added latency when sending or receiving packets may fail to meet the requirements of certain real-time use cases.”h]”hXA bus such as USB is more complex, involving multiple layers. A register read or write is wrapped in a USB Request Block (URB), which is then sent by the USB host controller to the device. Timing and latency are influenced by the underlying USB bus. Requests cannot be sent immediately; they must align with the next frame boundary according to the endpoint type and the host controller’s scheduling rules. This can introduce delays and additional latency. For example, a network device connected via USB may still deliver sufficient throughput, but the added latency when sending or receiving packets may fail to meet the requirements of certain real-time use cases.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KDhjåh²hubhþ)”}”(hX³Additional restrictions on bus latency can arise from power management. For instance, PCIe with Active State Power Management (ASPM) enabled can suspend the link between the device and the host. While this behavior is beneficial for power savings, it delays device access and adds latency to responses. This issue is not limited to PCIe; internal buses within a System-on-Chip (SoC) can also be affected by power management mechanisms.”h]”hX³Additional restrictions on bus latency can arise from power management. For instance, PCIe with Active State Power Management (ASPM) enabled can suspend the link between the device and the host. While this behavior is beneficial for power savings, it delays device access and adds latency to responses. This issue is not limited to PCIe; internal buses within a System-on-Chip (SoC) can also be affected by power management mechanisms.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KNhjåh²hubeh}”(h]”Œhardware-buses”ah ]”h"]”Œhardware buses”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K8ubhÉ)”}”(hhh]”(hÎ)”}”(hŒVirtualization”h]”hŒVirtualization”…””}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj6h²hh³hÇh´KVubhþ)”}”(hX§In a virtualized environment such as KVM, each guest CPU is represented as a thread on the host. If such a thread runs with real-time priority, the system should be tested to confirm it can sustain this behavior over extended periods. Because of its priority, the thread will not be preempted by lower-priority threads (such as SCHED_OTHER), which may then receive no CPU time. This can cause problems if a lower-priority thread is pinned to a CPU already occupied by a real-time task and unable to make progress. Even if a CPU has been isolated, the system may still (accidentally) start a per‑CPU thread on that CPU. Ensuring that a guest CPU goes idle is difficult, as it requires avoiding both task scheduling and interrupt handling. Furthermore, if the guest CPU does go idle but the guest system is booted with the option **idle=poll**, the guest CPU will never enter an idle state and will instead spin until an event arrives.”h]”(hX>In a virtualized environment such as KVM, each guest CPU is represented as a thread on the host. If such a thread runs with real-time priority, the system should be tested to confirm it can sustain this behavior over extended periods. Because of its priority, the thread will not be preempted by lower-priority threads (such as SCHED_OTHER), which may then receive no CPU time. This can cause problems if a lower-priority thread is pinned to a CPU already occupied by a real-time task and unable to make progress. Even if a CPU has been isolated, the system may still (accidentally) start a per‑CPU thread on that CPU. Ensuring that a guest CPU goes idle is difficult, as it requires avoiding both task scheduling and interrupt handling. Furthermore, if the guest CPU does go idle but the guest system is booted with the option ”…””}”(hjGh²hh³Nh´Nubjy)”}”(hŒ **idle=poll**”h]”hŒ idle=poll”…””}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhjGubhŒ\, the guest CPU will never enter an idle state and will instead spin until an event arrives.”…””}”(hjGh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KXhj6h²hubhþ)”}”(hXSDevice handling introduces additional considerations. Emulated PCI devices or VirtIO devices require a counterpart on the host to complete requests. This adds latency because the host must intercept and either process the request directly or schedule a thread for its completion. These delays can be avoided if the required PCI device is passed directly through to the guest. Some devices, such as networking or storage controllers, support the PCIe SR-IOV feature. SR-IOV allows a single PCIe device to be divided into multiple virtual functions, which can then be assigned to different guests.”h]”hXSDevice handling introduces additional considerations. Emulated PCI devices or VirtIO devices require a counterpart on the host to complete requests. This adds latency because the host must intercept and either process the request directly or schedule a thread for its completion. These delays can be avoided if the required PCI device is passed directly through to the guest. Some devices, such as networking or storage controllers, support the PCIe SR-IOV feature. SR-IOV allows a single PCIe device to be divided into multiple virtual functions, which can then be assigned to different guests.”…””}”(hjgh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kfhj6h²hubeh}”(h]”Œvirtualization”ah ]”h"]”Œvirtualization”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KVubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Networking”h]”hŒ Networking”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj}h²hh³hÇh´Kpubhþ)”}”(hŒùFor low-latency networking, the full networking stack may be undesirable, as it can introduce additional sources of delay. In this context, XDP can be used as a shortcut to bypass much of the stack while still relying on the kernel's network driver.”h]”hŒûFor low-latency networking, the full networking stack may be undesirable, as it can introduce additional sources of delay. In this context, XDP can be used as a shortcut to bypass much of the stack while still relying on the kernel’s network driver.”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Krhj}h²hubhþ)”}”(hXaThe requirements are that the network driver must support XDP- preferably using an "skb pool" and that the application must use an XDP socket. Additional configuration may involve BPF filters, tuning networking queues, or configuring qdiscs for time-based transmission. These techniques are often applied in Time-Sensitive Networking (TSN) environments.”h]”hXeThe requirements are that the network driver must support XDP- preferably using an “skb pool†and that the application must use an XDP socket. Additional configuration may involve BPF filters, tuning networking queues, or configuring qdiscs for time-based transmission. These techniques are often applied in Time-Sensitive Networking (TSN) environments.”…””}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kwhj}h²hubhþ)”}”(hŒŽDocumenting all required steps exceeds the scope of this text. For detailed guidance, see the TSN documentation at https://tsn.readthedocs.io.”h]”(hŒsDocumenting all required steps exceeds the scope of this text. For detailed guidance, see the TSN documentation at ”…””}”(hjªh²hh³Nh´Nubj)”}”(hŒhttps://tsn.readthedocs.io”h]”hŒhttps://tsn.readthedocs.io”…””}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j´uh1jhjªubhŒ.”…””}”(hjªh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K}hj}h²hubhþ)”}”(hX3Another useful resource is the Linux Real-Time Communication Testbench https://github.com/Linutronix/RTC-Testbench. The goal of this project is to validate real-time network communication. It can be thought of as a "cyclictest" for networking and also serves as a starting point for application development.”h]”(hŒGAnother useful resource is the Linux Real-Time Communication Testbench ”…””}”(hjËh²hh³Nh´Nubj)”}”(hŒ+https://github.com/Linutronix/RTC-Testbench”h]”hŒ+https://github.com/Linutronix/RTC-Testbench”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jÕuh1jhjËubhŒÅ. The goal of this project is to validate real-time network communication. It can be thought of as a “cyclictest†for networking and also serves as a starting point for application development.”…””}”(hjËh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K€hj}h²hubeh}”(h]”Œ networking”ah ]”h"]”Œ networking”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KpubhÉ)”}”(hhh]”(hÎ)”}”(hŒFirmware”h]”hŒFirmware”…””}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjôh²hh³hÇh´K‡ubhþ)”}”(hŒÃThe firmware often plays a significant role in system operation because it can perform tasks that the kernel cannot directly access, and in some cases it can even preempt or intercept the kernel.”h]”hŒÃThe firmware often plays a significant role in system operation because it can perform tasks that the kernel cannot directly access, and in some cases it can even preempt or intercept the kernel.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K‰hjôh²hubhþ)”}”(hXA common example of firmware assisting the kernel is when it provides a generic interface to a resource. Instead of accessing an RTC chip through an I2C host controller, the kernel may query the firmware for the current time, and the firmware then accesses the RTC behind the scenes.”h]”hXA common example of firmware assisting the kernel is when it provides a generic interface to a resource. Instead of accessing an RTC chip through an I2C host controller, the kernel may query the firmware for the current time, and the firmware then accesses the RTC behind the scenes.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Khjôh²hubhþ)”}”(hXãFirmware can also intercept kernel execution by providing services that temporarily take control of the system. One example is memory scrubbing, where the firmware periodically pauses the kernel, reads back portions of system memory, and then returns control. During this time, the kernel is effectively interrupted. In contrast, some systems provide hardware-based memory scrubbing, which operates independently of firmware or software. See Documentation/edac/scrub.rst for details.”h]”hXãFirmware can also intercept kernel execution by providing services that temporarily take control of the system. One example is memory scrubbing, where the firmware periodically pauses the kernel, reads back portions of system memory, and then returns control. During this time, the kernel is effectively interrupted. In contrast, some systems provide hardware-based memory scrubbing, which operates independently of firmware or software. See Documentation/edac/scrub.rst for details.”…””}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K’hjôh²hubhþ)”}”(hŒ¦If the kernel is intercepted for longer periods then these periods can be made visible with the hardware latency detector. See Documentation/trace/hwlat_detector.rst.”h]”hŒ¦If the kernel is intercepted for longer periods then these periods can be made visible with the hardware latency detector. See Documentation/trace/hwlat_detector.rst.”…””}”(hj/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K›hjôh²hubhþ)”}”(hŒ¿The kernel can also be intercepted in response to specific events, such as overheating. In this case, the firmware may throttle the CPU or shut it down immediately to prevent hardware damage.”h]”hŒ¿The kernel can also be intercepted in response to specific events, such as overheating. In this case, the firmware may throttle the CPU or shut it down immediately to prevent hardware damage.”…””}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KŸhjôh²hubhþ)”}”(hŒkUnless the firmware is well documented, it should be thoroughly tested to uncover any unexpected behaviour.”h]”hŒkUnless the firmware is well documented, it should be thoroughly tested to uncover any unexpected behaviour.”…””}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K£hjôh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒEFI”h]”hŒEFI”…””}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjYh²hh³hÇh´K§ubhþ)”}”(hŒäEFI provides runtime services that act as a communication interface between the firmware and the operating system. One such service is reading and writing EFI variables, which are used, for example, to determine the boot source.”h]”hŒäEFI provides runtime services that act as a communication interface between the firmware and the operating system. One such service is reading and writing EFI variables, which are used, for example, to determine the boot source.”…””}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K©hjYh²hubhþ)”}”(hX>Invoking a runtime service may require the architecture to disable kernel preemption or interrupts during the call. This means the duration of a service invocation directly affects the system’s observable latency. There is also nothing that prevents a service call from disabling interrupts internally while it runs.”h]”hX>Invoking a runtime service may require the architecture to disable kernel preemption or interrupts during the call. This means the duration of a service invocation directly affects the system’s observable latency. There is also nothing that prevents a service call from disabling interrupts internally while it runs.”…””}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K­hjYh²hubhþ)”}”(hX´For these reasons, EFI runtime services are disabled by default on a PREEMPT_RT kernel. They can still be enabled at boot time or via a Kconfig option if required. The native EFI runtime service implementation (where both the EFI service and the kernel are either 32-bit or 64-bit executables) uses a wrapper mechanism that invokes the service through a dedicated workqueue. This workqueue is named efi_runtime, and it can be restricted to a housekeeping CPU using the ``/sys/devices/virtual/workqueue/efi_runtime/cpumask`` sysfs file. Assigning it to a housekeeping CPU ensures that potentially long service invocations do not impact the real-time workload which is restricted to other CPUs.”h]”(hXÕFor these reasons, EFI runtime services are disabled by default on a PREEMPT_RT kernel. They can still be enabled at boot time or via a Kconfig option if required. The native EFI runtime service implementation (where both the EFI service and the kernel are either 32-bit or 64-bit executables) uses a wrapper mechanism that invokes the service through a dedicated workqueue. This workqueue is named efi_runtime, and it can be restricted to a housekeeping CPU using the ”…””}”(hj†h²hh³Nh´NubhŒliteral”“”)”}”(hŒ6``/sys/devices/virtual/workqueue/efi_runtime/cpumask``”h]”hŒ2/sys/devices/virtual/workqueue/efi_runtime/cpumask”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jŽhj†ubhŒ© sysfs file. Assigning it to a housekeeping CPU ensures that potentially long service invocations do not impact the real-time workload which is restricted to other CPUs.”…””}”(hj†h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K³hjYh²hubhþ)”}”(hX&It must also be verified that the runtime services behave as expected. Some implementations on the x86 architecture pause all other CPUs while one CPU performs the service call. In such cases, the interruption affects all CPUs, and restricting the workqueue to a single CPU provides no benefit.”h]”hX&It must also be verified that the runtime services behave as expected. Some implementations on the x86 architecture pause all other CPUs while one CPU performs the service call. In such cases, the interruption affects all CPUs, and restricting the workqueue to a single CPU provides no benefit.”…””}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K¾hjYh²hubeh}”(h]”Œefi”ah ]”h"]”Œefi”ah$]”h&]”uh1hÈhjôh²hh³hÇh´K§ubhÉ)”}”(hhh]”(hÎ)”}”(hŒ OP-TEE (ARM)”h]”hŒ OP-TEE (ARM)”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj¾h²hh³hÇh´KÄubhþ)”}”(hXZExecution flows from the normal world (Linux) into the secure world (OP-TEE) through the secure monitor at EL3. The transition is initiated by the `smc` (Secure Monitor Call) opcode or the `hvc` (Hypervisor Call) opcode together with a function identifier. The calling convention defines two types of calls: **yielding calls** and **fast calls**:”h]”(hŒ“Execution flows from the normal world (Linux) into the secure world (OP-TEE) through the secure monitor at EL3. The transition is initiated by the ”…””}”(hjÏh²hh³Nh´NubhŒtitle_reference”“”)”}”(hŒ`smc`”h]”hŒsmc”…””}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjÏubhŒ% (Secure Monitor Call) opcode or the ”…””}”(hjÏh²hh³Nh´NubjØ)”}”(hŒ`hvc`”h]”hŒhvc”…””}”(hjëh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjÏubhŒr (Hypervisor Call) opcode together with a function identifier. The calling convention defines two types of calls: ”…””}”(hjÏh²hh³Nh´Nubjy)”}”(hŒ**yielding calls**”h]”hŒyielding calls”…””}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhjÏubhŒ and ”…””}”(hjÏh²hh³Nh´Nubjy)”}”(hŒ**fast calls**”h]”hŒ fast calls”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhjÏubhŒ:”…””}”(hjÏh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÆhj¾h²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒxA **yielding call** unmasks interrupts before handling the requested service, allowing normal world interrupts to occur.”h]”hþ)”}”(hŒxA **yielding call** unmasks interrupts before handling the requested service, allowing normal world interrupts to occur.”h]”(hŒA ”…””}”(hj2h²hh³Nh´Nubjy)”}”(hŒ**yielding call**”h]”hŒ yielding call”…””}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhj2ubhŒe unmasks interrupts before handling the requested service, allowing normal world interrupts to occur.”…””}”(hj2h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÌhj.ubah}”(h]”h ]”h"]”h$]”h&]”uh1j,hj)h²hh³hÇh´Nubj-)”}”(hŒˆA **fast call** handles the requested service atomically, without allowing interrupts from either the normal world or the secure world. ”h]”hþ)”}”(hŒ‡A **fast call** handles the requested service atomically, without allowing interrupts from either the normal world or the secure world.”h]”(hŒA ”…””}”(hj\h²hh³Nh´Nubjy)”}”(hŒ **fast call**”h]”hŒ fast call”…””}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhj\ubhŒx handles the requested service atomically, without allowing interrupts from either the normal world or the secure world.”…””}”(hj\h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÎhjXubah}”(h]”h ]”h"]”h$]”h&]”uh1j,hj)h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j'h³hÇh´KÌhj¾h²hubhþ)”}”(hŒØIn addition, the secure world (EL3 and OP-TEE) can receive interrupts routed to the secure world. While a secure world interrupt is being serviced, normal world interrupts are masked and cannot preempt the operation.”h]”hŒØIn addition, the secure world (EL3 and OP-TEE) can receive interrupts routed to the secure world. While a secure world interrupt is being serviced, normal world interrupts are masked and cannot preempt the operation.”…””}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÑhj¾h²hubhþ)”}”(hŒîThe transition from normal world to secure monitor to OP-TEE and back introduces additional latency due to world switching and context save/restore. This overhead is typically a few microseconds and usually remains within the noise floor.”h]”hŒîThe transition from normal world to secure monitor to OP-TEE and back introduces additional latency due to world switching and context save/restore. This overhead is typically a few microseconds and usually remains within the noise floor.”…””}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÕhj¾h²hubhþ)”}”(hXIt is worth noting that the normal world cannot mask secure interrupts, while the secure world can mask normal-world interrupts during execution. How OP-TEE affects real-time workloads depends on whether secure interrupts are enabled and which OP-TEE services are invoked.”h]”hXIt is worth noting that the normal world cannot mask secure interrupts, while the secure world can mask normal-world interrupts during execution. How OP-TEE affects real-time workloads depends on whether secure interrupts are enabled and which OP-TEE services are invoked.”…””}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÚhj¾h²hubhþ)”}”(hX6A practical concern is any fast call that runs longer than expected, for example a function that occasionally performs a long-running cryptographic computation. Another example that may block in an unexpected way are OP-TEE drivers that issue RPC requests. An OP-TEE service in the secure world (RPMB for instance) may need to issue a request back to the normal world (the Linux driver) in order to complete the operation. While Linux remains preemptible, the thread that issued the request stays blocked until the RPC completes and the secure function call returns.”h]”hX6A practical concern is any fast call that runs longer than expected, for example a function that occasionally performs a long-running cryptographic computation. Another example that may block in an unexpected way are OP-TEE drivers that issue RPC requests. An OP-TEE service in the secure world (RPMB for instance) may need to issue a request back to the normal world (the Linux driver) in order to complete the operation. While Linux remains preemptible, the thread that issued the request stays blocked until the RPC completes and the secure function call returns.”…””}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kßhj¾h²hubhþ)”}”(hŒ¹The TF-A project provides documentation on interrupt management: https://trustedfirmware-a.readthedocs.io/en/latest/design/interrupt-framework-design.html#interrupt-management-framework”h]”(hŒAThe TF-A project provides documentation on interrupt management: ”…””}”(hjÂh²hh³Nh´Nubj)”}”(hŒxhttps://trustedfirmware-a.readthedocs.io/en/latest/design/interrupt-framework-design.html#interrupt-management-framework”h]”hŒxhttps://trustedfirmware-a.readthedocs.io/en/latest/design/interrupt-framework-design.html#interrupt-management-framework”…””}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jÌuh1jhjÂubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kèhj¾h²hubhþ)”}”(hŒ™The OP-TEE project provides documentation on how interrupts are handled: https://optee.readthedocs.io/en/latest/architecture/core.html#interrupt-handling”h]”(hŒIThe OP-TEE project provides documentation on how interrupts are handled: ”…””}”(hjßh²hh³Nh´Nubj)”}”(hŒPhttps://optee.readthedocs.io/en/latest/architecture/core.html#interrupt-handling”h]”hŒPhttps://optee.readthedocs.io/en/latest/architecture/core.html#interrupt-handling”…””}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jéuh1jhjßubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Këhj¾h²hubeh}”(h]”Œ op-tee-arm”ah ]”h"]”Œ op-tee (arm)”ah$]”h&]”uh1hÈhjôh²hh³hÇh´KÄubeh}”(h]”Œfirmware”ah ]”h"]”Œfirmware”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K‡ubeh}”(h]”Œconsidering-hardware”ah ]”h"]”Œconsidering hardware”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j7Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jjjâjßj3j0jzjwjñjîj jj»j¸jjþuŒ nametypes”}”(j‰jâ‰j3‰jz‰jñ‰j ‰j»‰j‰uh}”(jhÊjßjQj0jåjwj6jîj}jjôj¸jYjþj¾uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.