4.4.Debug FS
4.4.1.Overview
TheDebugFS feature is primarily aimed at exposing firmware debug data tohigher SW layers such as a non-secure component. Such component can be theTFTF test payload or a Linux kernel module.
4.4.2.Virtual filesystem
The core functionality lies in a virtual file system based on a 9p file serverinterface (Notes on the Plan 9 Kernel Source andLinux 9p remote filesystem protocol).The implementation permits exposing virtual files, firmware drivers, and file blobs.
4.4.2.1.Namespace
Two namespaces are exposed:
# is used as root for drivers (e.g. #t0 is the first uart)
/ is used as root for virtual “files” (e.g. /fip, or /dev/uart)
4.4.2.2.9p interface
The associated primitives are:
Unix-like:
open(): create a file descriptor that acts as a handle to the file passed asan argument.
close(): close the file descriptor created by open().
read(): read from a file to a buffer.
write(): write from a buffer to a file.
seek(): set the file position indicator of a file descriptor either to arelative or an absolute offset.
stat(): get information about a file (type, mode, size, …).
intopen(constchar*name,intflags);intclose(intfd);intread(intfd,void*buf,intn);intwrite(intfd,void*buf,intn);intseek(intfd,longoff,intwhence);intstat(char*path,dir_t*dir);
Specific primitives :
mount(): create a link between a driver and spec.
create(): create a file in a specific location.
bind(): expose the content of a directory to another directory.
intmount(char*srv,char*mnt,char*spec);intcreate(constchar*name,intflags);intbind(char*path,char*where);
This interface is embedded into the BL31 run-time payload when selected by buildoptions. The interface multiplexes drivers or emulated “files”:
Debug data can be partitioned into different virtual files e.g. expose PMFmeasurements through a file, and internal firmware state counters throughanother file.
This permits direct access to a firmware driver, mainly for test purposes(e.g. a hardware device that may not be accessible to non-privileged/non-secure layers, or for which no support exists in the NS side).
4.4.3.SMC interface
The communication with the 9p layer in BL31 is made through an SMC conduit(SMC Calling Convention), using a specific SiP Function Id. An NSshared buffer is used to pass path string parameters, or e.g. to exchangedata on a read operation. Refer toARM SiP Servicesfor a description of the SMC interface.
4.4.4.Security considerations
Due to the nature of the exposed data, the feature is considered experimentaland importantlyshall only be used in debug builds.
Several primitive imply string manipulations and usage of string formats.
Special care is taken with the shared buffer to avoid TOCTOU attacks.
4.4.5.Limitations
In order to setup the shared buffer, the component consuming the interfaceneeds to allocate a physical page frame and transmit its address.
In order to map the shared buffer, BL31 requires enabling the dynamic xlattable option.
Data exchange is limited by the shared buffer length. A large read operationmight be split into multiple read operations of smaller chunks.
On concurrent access, a spinlock is implemented in the BL31 service to protectthe internal work buffer, and re-entrancy into the filesystem layers.
Notice, a physical device driver if exposed by the firmware may conflict withthe higher level OS if the latter implements its own driver for the samephysical device.
4.4.6.Applications
The SMC interface is accessible from an NS environment, that is:
a test payload, bootloader or hypervisor running at NS-EL2
a Linux kernel driver running at NS-EL1
a Linux userspace application through the kernel driver
Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.