Correct configuration of the smmuman service requires careful attention to architecture-specific and board-specific details provided in the board manufacturer’s documentation.
The smmuman configuration:
The smmuman service programs the configuration information about DMA devices, and memory regions and permissions into the hardware IOMMU/SMMUs. The IOMMU/SMMUs (or vdev-smmu) use the configuration to limit DMA devices' memory access to their permitted regions, and for their configured permissions.
If the smmuman service is running in a guest in a QNX Hypervisor VM (qvm process instance), the service passes the configuration information for the guest's pass-through DMA devices to the vdev-smmu virtual device. This virtual device then passes this information on to the smmuman service in the hypervisor host to configure the IOMMU/SMMUs on the board, ensuring that devices passed through to a guest are restricted to their permitted memory regions and permissions in host-physical memory.
The smmuman service needs a minimum set of configuration information at startup. This set includes information about:
At startup, the smmuman service reads its configuration input in a single pass, from start to finish. The service usually receives this input through some combination of information:
You may have the smmuman service retrieve information from the board at startup, then add user-input information to it. By default, user-input information will override the information obtained from the board.
For information about how the smmuman service handles multiple instances of the same option, see Options in this chapter.
The information supplied at startup may in some cases also include memory mappings and DMA device permissions for these mapped memory regions. Note, however, that the recommended method for configuring memory mappings and device permissions is through the SMMUMAN client API (see Mapping DMA devices and memory regions in this chapter).
The non-safety variant of the SMMUMAN service (smmuman) only attempts to load the the non-safety variants of support files. For example, if you start the non-safety variant of the smmuman service thus: smmu vtd, the service will always try to load only the non-safety support file: smmu-vtd.so.
However, the service's safety variant (smmuman-safety) preferentially loads the safety variants of support files. If it doesn't find the safety variant of the support file, it then attempts to load the non-safety variant. For example, if you start the smmuman service's safety variant thus: smmu vtd, the service will try to load smmu-vtd-safety.so; if this fails, it will then try to load the non-safety support file: smmu-vtd.so.
You can force either variant of the smmuman service to load only the specified variant of a support file by naming the support file. For example, assuming that you configured the service to move to its DSS if a required safety component isn't present, if you start the service thus: smmu vtd-safety.so, it will attempt to load only the named support file, and move to its DSS if it doesn't find the file.
In the user-input configuration (file or command line), anything that follows a # character is considered a comment and is ignored. An @ character indicates that what follows is a file name.
Configuration files may be identified by their .smmu suffix (e.g., mysystem.smmu).
Thus, in the startup instructions, to use a configuration file, enter smmuman, then an @ followed by the filename. For example:
smmuman @mysystem.smmu
In a production system, you should start the smmuman service as part of the system startup, with a configuration file specified in the startup script. For example:
smmuman @/etc/foo.smmu
This character can be used to nest configuration files. For example, if a configuration file foo.smmu includes a line: @moo.smmu, then when it encounters this line the smmuman service will read its configuration information from moo.smmu before continuing to read foo.smmu.
As it reads through its configuration information, smmuman performs textual substitutions to its configuration information when it encounters the following character sequences:
You can use this textual substitution to make your configuration more robust by having the host startup place values in the system page asinfo entry where they can be picked up by smmuman.
For example, below is a partial smmuman configuration for an x86 board that picks up memory allocations from the system page:
debug 2 smmu vtd require allow smbs0 $asinfo_start{smbs0},$asinfo_length{smbs0},st allow xhci $asinfo_start{xhci},$asinfo_length{xhci},st ... device pci:0:18.0 smbs0 device pci:0:21.0 xhci ...
Note that when using $asinfo_start, pass the leaf name only, and not the full path. For example, the following is incorrect:
allow ahci $asinfo_start{/memory/below4G/ram/testMem},10M,st
but the following is correct:
allow ahci $asinfo_start{testMem},10M,st
For more information about the system page asinfo data structure array, see the System Page chapter in Building Embedded Systems.
The smmuman service supports options that determine how it will run: (e.g., in the foreground, outputting debug information). These options must be specified at startup. For more information, see Global options in this chapter.
When it starts, the smmuman service needs to know about the IOMMU/SMMUs and the DMA devices on the board. The information it requires includes:
If smmuman is running on the hardware (i.e., not in a QNX hypervisor VM) it obtains architecture-specific and board-specific information from the smmu-*.so support libraries. Additional information may be available in different locations on the hardware, depending on the board architecture and the specific board itself. To obtain some of this information, the smmuman service with its support libraries can query the board.
For x86 boards, the hardware description should be available in the board’s ACPI tables. A configuration file is required only for non-standard implementations. For ARM boards, some information may be available in board-specific code. For both architectures, information that isn't provided by the board, must be provided in the smmuman configuration.
If smmuman is running in a QNX Hypervisor VM in a hypervisor system, no support libraries are required; the information for the virtual hardware is provided by the vdev-smmu* virtual IOMMU/SMMU device.
Without proper guidance from the system designer the smmuman service can't know where the information it needs resides on the board. On x86 platforms, the ACPI tables are usually at a standard location; on ARM platforms the location or locations of the information the SMMUMAN needs is less predictable.
Always consult your board manufacturer's documentation for the locations and values you must use for your SoC. These locations and values may change, even between board revisions.
The smmuman service includes options that can be used in the startup configuration to specify memory mappings and DMA device permissions for these mapped memory regions. These mappings and permissions are not mandatory; the service doesn't need them to complete its startup successfully.
In fact, the recommended method for configuring memory mappings and device permissions is not through the startup configuration, but through the SMMUMAN client API in libsmmu.a (see Mapping DMA devices and memory regions in this chapter, and the SMMUMAN Client API Reference chapter).