debugfs-design.rst 4.31 KB
Newer Older
Ambroise Vincent's avatar
Ambroise Vincent committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
========
Debug FS
========

.. contents::

Overview
--------

The *DebugFS* feature is primarily aimed at exposing firmware debug data to
higher SW layers such as a non-secure component. Such component can be the
TFTF test payload or a Linux kernel module.

Virtual filesystem
------------------

The core functionality lies in a virtual file system based on a 9p file server
18
19
20
interface (`Notes on the Plan 9 Kernel Source`_ and
`Linux 9p remote filesystem protocol`_).
The implementation permits exposing virtual files, firmware drivers, and file blobs.
Ambroise Vincent's avatar
Ambroise Vincent committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

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)

9p interface
~~~~~~~~~~~~

The associated primitives are:

- Unix-like:

  - open(): create a file descriptor that acts as a handle to the file passed as
    an 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 a
    relative or an absolute offset.
  - stat(): get information about a file (type, mode, size, ...).

.. code:: c

    int open(const char *name, int flags);
    int close(int fd);
    int read(int fd, void *buf, int n);
    int write(int fd, void *buf, int n);
    int seek(int fd, long off, int whence);
    int stat(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.

.. code:: c

    int mount(char *srv, char *mnt, char *spec);
    int create(const char *name, int flags);
    int bind(char *path, char *where);

This interface is embedded into the BL31 run-time payload when selected by build
options. The interface multiplexes drivers or emulated "files":

- Debug data can be partitioned into different virtual files e.g. expose PMF
  measurements through a file, and internal firmware state counters through
  another 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).

SMC interface
-------------

The communication with the 9p layer in BL31 is made through an SMC conduit
81
82
83
84
(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS
shared buffer is used to pass path string parameters, or e.g. to exchange
data on a read operation. Refer to `ARM SiP Services`_ for a description
of the SMC interface.
Ambroise Vincent's avatar
Ambroise Vincent committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

Security considerations
-----------------------

- Due to the nature of the exposed data, the feature is considered experimental
  and importantly **shall 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.

Limitations
-----------

- In order to setup the shared buffer, the component consuming the interface
  needs to allocate a physical page frame and transmit its address.
- In order to map the shared buffer, BL31 requires enabling the dynamic xlat
  table option.
- Data exchange is limited by the shared buffer length. A large read operation
  might be split into multiple read operations of smaller chunks.
- On concurrent access, a spinlock is implemented in the BL31 service to protect
  the internal work buffer, and re-entrancy into the filesystem layers.
- Notice, a physical device driver if exposed by the firmware may conflict with
  the higher level OS if the latter implements its own driver for the same
  physical device.

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

--------------

120
*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
Ambroise Vincent's avatar
Ambroise Vincent committed
121

122
.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
Ambroise Vincent's avatar
Ambroise Vincent committed
123
124
125
.. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf
.. _Linux 9p remote filesystem protocol: https://www.kernel.org/doc/Documentation/filesystems/9p.txt
.. _ARM SiP Services: arm-sip-service.rst