code:
Dynamic debug
+++++++++++++

Introduction
============

Dynamic debug allows you to dynamically enable/disable kernel
debug-print code to obtain additional kernel information.

If ``/proc/dynamic_debug/control`` exists, your kernel has dynamic
debug.  You'll need root access (sudo su) to use this.

Dynamic debug provides:

 * a Catalog of all *prdbgs* in your kernel.
   ``cat /proc/dynamic_debug/control`` to see them.

 * a Simple query/command language to alter *prdbgs* by selecting on
   any combination of 0 or 1 of:

   - source filename
   - function name
   - line number (including ranges of line numbers)
   - module name
   - format string
   - class name (as known/declared by each module)

Viewing Dynamic Debug Behaviour
===============================

You can view the currently configured behaviour in the *prdbg* catalog::

  :#> head -n7 /proc/dynamic_debug/control
  # filename:lineno [module]function flags format
  init/main.c:1179 [main]initcall_blacklist =_ "blacklisting initcall %s\012
  init/main.c:1218 [main]initcall_blacklisted =_ "initcall %s blacklisted\012"
  init/main.c:1424 [main]run_init_process =_ "  with arguments:\012"
  init/main.c:1426 [main]run_init_process =_ "    %s\012"
  init/main.c:1427 [main]run_init_process =_ "  with environment:\012"
  init/main.c:1429 [main]run_init_process =_ "    %s\012"

The 3rd space-delimited column shows the current flags, preceded by
a ``=`` for easy use with grep/cut. ``=p`` shows enabled callsites.

Controlling dynamic debug Behaviour
===================================

The behaviour of *prdbg* sites are controlled by writing
query/commands to the control file.  Example::

  # grease the interface
  :#> alias ddcmd='echo $* > /proc/dynamic_debug/control'

  :#> ddcmd '-p; module main func run* +p'
  :#> grep =p /proc/dynamic_debug/control
  init/main.c:1424 [main]run_init_process =p "  with arguments:\012"
  init/main.c:1426 [main]run_init_process =p "    %s\012"
  init/main.c:1427 [main]run_init_process =p "  with environment:\012"
  init/main.c:1429 [main]run_init_process =p "    %s\012"

Error messages go to console/syslog::

  :#> ddcmd mode foo +p
  dyndbg: unknown keyword "mode"
  dyndbg: query parse failed
  bash: echo: write error: Invalid argument

If debugfs is also enabled and mounted, ``dynamic_debug/control`` is
also under the mount-dir, typically ``/sys/kernel/debug/``.

Command Language Reference
==========================

At the basic lexical level, a command is a sequence of words separated
by spaces or tabs.  So these are all equivalent::

  :#> ddcmd file svcsock.c line 1603 +p
  :#> ddcmd "file svcsock.c line 1603 +p"
  :#> ddcmd '  file   svcsock.c     line  1603 +p  '

Command submissions are bounded by a write() system call.
Multiple commands can be written together, separated by ``;`` or ``\n``::

  :#> ddcmd "func pnpacpi_get_resources +p; func pnp_assign_mem +p"
  :#> ddcmd <<"EOC"
  func pnpacpi_get_resources +p
  func pnp_assign_mem +p
  EOC
  :#> cat query-batch-file > /proc/dynamic_debug/control

You can also use wildcards in each query term. The match rule supports
``*`` (matches zero or more characters) and ``?`` (matches exactly one
character). For example, you can match all usb drivers::

  :#> ddcmd file "drivers/usb/*" +p	# "" to suppress shell expansion

Syntactically, a command is pairs of keyword values, followed by a
flags change or setting::

  command ::= match-spec* flags-spec

The match-spec's select *prdbgs* from the catalog, upon which to apply
the flags-spec, all constraints are ANDed together.  An absent keyword
is the same as keyword "*".

A match specification is a keyword, which selects the attribute of
the callsite to be compared, and a value to compare against.  Possible
keywords are:::

  match-spec ::= 'func' string |
		 'file' string |
		 'module' string |
		 'format' string |
		 'class' string |
		 'line' line-range

  line-range ::= lineno |
		 '-'lineno |
		 lineno'-' |
		 lineno'-'lineno

  lineno ::= unsigned-int

.. note::

  ``line-range`` cannot contain space, e.g.
  "1-30" is valid range but "1 - 30" is not.

The meanings of each keyword are:

func
    The given string is compared against the function name
    of each callsite.  Example::

	func svc_tcp_accept
	func *recv*		# in rfcomm, bluetooth, ping, tcp

file
    The given string is compared against either the src-root relative
    pathname, or the basename of the source file of each callsite.
    Examples::

	file svcsock.c
	file kernel/freezer.c	# ie column 1 of control file
	file drivers/usb/*	# all callsites under it
	file inode.c:start_*	# parse :tail as a func (above)
	file inode.c:1-100	# parse :tail as a line-range (above)

module
    The given string is compared against the module name
    of each callsite.  The module name is the string as
    seen in ``lsmod``, i.e. without the directory or the ``.ko``
    suffix and with ``-`` changed to ``_``.  Examples::

	module sunrpc
	module nfsd
	module drm*	# both drm, drm_kms_helper

format
    The given string is searched for in the dynamic debug format
    string.  Note that the string does not need to match the
    entire format, only some part.  Whitespace and other
    special characters can be escaped using C octal character
    escape ``\ooo`` notation, e.g. the space character is ``\040``.
    Alternatively, the string can be enclosed in double quote
    characters (``"``) or single quote characters (``'``).
    Examples::

	format svcrdma:         // many of the NFS/RDMA server pr_debugs
	format readahead        // some pr_debugs in the readahead cache
	format nfsd:\040SETATTR // one way to match a format with whitespace
	format "nfsd: SETATTR"  // a neater way to match a format with whitespace
	format 'nfsd: SETATTR'  // yet another way to match a format with whitespace

class
    The given class_name is validated against each module, which may
    have declared a list of known class_names.  If the class_name is
    found for a module, callsite & class matching and adjustment
    proceeds.  Examples::

	class DRM_UT_KMS	# a DRM.debug category
	class JUNK		# silent non-match
	// class TLD_*		# NOTICE: no wildcard in class names

line
    The given line number or range of line numbers is compared
    against the line number of each ``pr_debug()`` callsite.  A single
    line number matches the callsite line number exactly.  A
    range of line numbers matches any callsite between the first
    and last line number inclusive.  An empty first number means
    the first line in the file, an empty last line number means the
    last line number in the file.  Examples::

	line 1603           // exactly line 1603
	line 1600-1605      // the six lines from line 1600 to line 1605
	line -1605          // the 1605 lines from line 1 to line 1605
	line 1600-          // all lines from line 1600 to the end of the file

The flags specification comprises a change operation followed
by one or more flag characters.  The change operation is one
of the characters::

  -    remove the given flags
  +    add the given flags
  =    set the flags to the given flags

The flags are::

  p    enables the pr_debug() callsite.
  _    enables no flags.

  Decorator flags add to the message-prefix, in order:
  t    Include thread ID, or <intr>
  m    Include module name
  f    Include the function name
  l    Include line number

For ``print_hex_dump_debug()`` and ``print_hex_dump_bytes()``, only
the ``p`` flag has meaning, other flags are ignored.

Note the regexp ``^[-+=][flmpt_]+$`` matches a flags specification.
To clear all flags at once, use ``=_`` or ``-flmpt``.

Debug messages during Boot Process
==================================

To activate debug messages for core code and built-in modules during
the boot process, even before userspace and debugfs exists, use
``dyndbg="QUERY"`` or ``module.dyndbg="QUERY"``.  QUERY follows
the syntax described above, but must not exceed 1023 characters.  Your
bootloader may impose lower limits.

These ``dyndbg`` params are processed just after the ddebug tables are
processed, as part of the early_initcall.  Thus you can enable debug
messages in all code run after this early_initcall via this boot
parameter.

On an x86 system for example ACPI enablement is a subsys_initcall and::

   dyndbg="file ec.c +p"

will show early Embedded Controller transactions during ACPI setup if
your machine (typically a laptop) has an Embedded Controller.
PCI (or other devices) initialization also is a hot candidate for using
this boot parameter for debugging purposes.

If ``foo`` module is not built-in, ``foo.dyndbg`` will still be processed at
boot time, without effect, but will be reprocessed when module is
loaded later. Bare ``dyndbg=`` is only processed at boot.

Debug Messages at Module Initialization Time
============================================

When ``modprobe foo`` is called, modprobe scans ``/proc/cmdline`` for
``foo.params``, strips ``foo.``, and passes them to the kernel along with
params given in modprobe args or ``/etc/modprob.d/*.conf`` files,
in the following order:

1. parameters given via ``/etc/modprobe.d/*.conf``::

	options foo dyndbg=+pt
	options foo dyndbg # defaults to +p

2. ``foo.dyndbg`` as given in boot args, ``foo.`` is stripped and passed::

	foo.dyndbg=" func bar +p; func buz +mp"

3. args to modprobe::

	modprobe foo dyndbg==pmf # override previous settings

These ``dyndbg`` queries are applied in order, with last having final say.
This allows boot args to override or modify those from ``/etc/modprobe.d``
(sensible, since 1 is system wide, 2 is kernel or boot specific), and
modprobe args to override both.

In the ``foo.dyndbg="QUERY"`` form, the query must exclude ``module foo``.
``foo`` is extracted from the param-name, and applied to each query in
``QUERY``, and only 1 match-spec of each type is allowed.

The ``dyndbg`` option is a "fake" module parameter, which means:

- modules do not need to define it explicitly
- every module gets it tacitly, whether they use pr_debug or not
- it doesn't appear in ``/sys/module/$module/parameters/``
  To see it, grep the control file, or inspect ``/proc/cmdline.``

For ``CONFIG_DYNAMIC_DEBUG`` kernels, any settings given at boot-time (or
enabled by ``-DDEBUG`` flag during compilation) can be disabled later via
the debugfs interface if the debug messages are no longer needed::

   echo "module module_name -p" > /proc/dynamic_debug/control

Examples
========

::

  // enable the message at line 1603 of file svcsock.c
  :#> ddcmd 'file svcsock.c line 1603 +p'

  // enable all the messages in file svcsock.c
  :#> ddcmd 'file svcsock.c +p'

  // enable all the messages in the NFS server module
  :#> ddcmd 'module nfsd +p'

  // enable all 12 messages in the function svc_process()
  :#> ddcmd 'func svc_process +p'

  // disable all 12 messages in the function svc_process()
  :#> ddcmd 'func svc_process -p'

  // enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
  :#> ddcmd 'format "nfsd: READ" +p'

  // enable messages in files of which the paths include string "usb"
  :#> ddcmd 'file *usb* +p' > /proc/dynamic_debug/control

  // enable all messages
  :#> ddcmd '+p' > /proc/dynamic_debug/control

  // add module, function to all enabled messages
  :#> ddcmd '+mf' > /proc/dynamic_debug/control

  // boot-args example, with newlines and comments for readability
  Kernel command line: ...
    // see whats going on in dyndbg=value processing
    dynamic_debug.verbose=3
    // enable pr_debugs in the btrfs module (can be builtin or loadable)
    btrfs.dyndbg="+p"
    // enable pr_debugs in all files under init/
    // and the function parse_one, #cmt is stripped
    dyndbg="file init/* +p #cmt ; func parse_one +p"
    // enable pr_debugs in 2 functions in a module loaded later
    pc87360.dyndbg="func pc87360_init_device +p; func pc87360_find +p"

Kernel Configuration
====================

Dynamic Debug is enabled via kernel config items::

  CONFIG_DYNAMIC_DEBUG=y	# build catalog, enables CORE
  CONFIG_DYNAMIC_DEBUG_CORE=y	# enable mechanics only, skip catalog

If you do not want to enable dynamic debug globally (i.e. in some embedded
system), you may set ``CONFIG_DYNAMIC_DEBUG_CORE`` as basic support of dynamic
debug and add ``ccflags := -DDYNAMIC_DEBUG_MODULE`` into the Makefile of any
modules which you'd like to dynamically debug later.

Kernel *prdbg* API
==================

The following functions are cataloged and controllable when dynamic
debug is enabled::

  pr_debug()
  dev_dbg()
  print_hex_dump_debug()
  print_hex_dump_bytes()

Otherwise, they are off by default; ``ccflags += -DDEBUG`` or
``#define DEBUG`` in a source file will enable them appropriately.

If ``CONFIG_DYNAMIC_DEBUG`` is not set, ``print_hex_dump_debug()`` is
just a shortcut for ``print_hex_dump(KERN_DEBUG)``.

For ``print_hex_dump_debug()``/``print_hex_dump_bytes()``, format string is
its ``prefix_str`` argument, if it is constant string; or ``hexdump``
in case ``prefix_str`` is built dynamically.

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

====
EDID
====

In the good old days when graphics parameters were configured explicitly
in a file called xorg.conf, even broken hardware could be managed.

Today, with the advent of Kernel Mode Setting, a graphics board is
either correctly working because all components follow the standards -
or the computer is unusable, because the screen remains dark after
booting or it displays the wrong area. Cases when this happens are:

- The graphics board does not recognize the monitor.
- The graphics board is unable to detect any EDID data.
- The graphics board incorrectly forwards EDID data to the driver.
- The monitor sends no or bogus EDID data.
- A KVM sends its own EDID data instead of querying the connected monitor.

Adding the kernel parameter "nomodeset" helps in most cases, but causes
restrictions later on.

As a remedy for such situations, the kernel configuration item
CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an
individually prepared or corrected EDID data set in the /lib/firmware
directory from where it is loaded via the firmware interface. The code
(see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for
commonly used screen resolutions (800x600, 1024x768, 1280x1024, 1600x1200,
1680x1050, 1920x1080) as binary blobs, but the kernel source tree does
not contain code to create these data. In order to elucidate the origin
of the built-in binary EDID blobs and to facilitate the creation of
individual data for a specific misbehaving monitor, commented sources
and a Makefile environment are given here.

To create binary EDID and C source code files from the existing data
material, simply type "make" in tools/edid/.

If you want to create your own EDID file, copy the file 1024x768.S,
replace the settings with your own data and add a new target to the
Makefile. Please note that the EDID data structure expects the timing
values in a different way as compared to the standard X11 format.

X11:
  HTimings:
    hdisp hsyncstart hsyncend htotal
  VTimings:
    vdisp vsyncstart vsyncend vtotal

EDID::

  #define XPIX hdisp
  #define XBLANK htotal-hdisp
  #define XOFFSET hsyncstart-hdisp
  #define XPULSE hsyncend-hsyncstart

  #define YPIX vdisp
  #define YBLANK vtotal-vdisp
  #define YOFFSET vsyncstart-vdisp
  #define YPULSE vsyncend-vsyncstart


code:
=================
The EFI Boot Stub
=================

On the x86 and ARM platforms, a kernel zImage/bzImage can masquerade
as a PE/COFF image, thereby convincing EFI firmware loaders to load
it as an EFI executable. The code that modifies the bzImage header,
along with the EFI-specific entry point that the firmware loader
jumps to are collectively known as the "EFI boot stub", and live in
arch/x86/boot/header.S and drivers/firmware/efi/libstub/x86-stub.c,
respectively. For ARM the EFI stub is implemented in
arch/arm/boot/compressed/efi-header.S and
drivers/firmware/efi/libstub/arm32-stub.c. EFI stub code that is shared
between architectures is in drivers/firmware/efi/libstub.

For arm64, there is no compressed kernel support, so the Image itself
masquerades as a PE/COFF image and the EFI stub is linked into the
kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S
and drivers/firmware/efi/libstub/arm64-stub.c.

By using the EFI boot stub it's possible to boot a Linux kernel
without the use of a conventional EFI boot loader, such as grub or
elilo. Since the EFI boot stub performs the jobs of a boot loader, in
a certain sense it *IS* the boot loader.

The EFI boot stub is enabled with the CONFIG_EFI_STUB kernel option.

How to install bzImage.efi
--------------------------

The bzImage located in arch/x86/boot/bzImage must be copied to the EFI
System Partition (ESP) and renamed with the extension ".efi". Without
the extension the EFI firmware loader will refuse to execute it. It's
not possible to execute bzImage.efi from the usual Linux file systems
because EFI firmware doesn't have support for them. For ARM the
arch/arm/boot/zImage should be copied to the system partition, and it
may not need to be renamed. Similarly for arm64, arch/arm64/boot/Image
should be copied but not necessarily renamed.

Passing kernel parameters from the EFI shell
--------------------------------------------

Arguments to the kernel can be passed after bzImage.efi, e.g.::

	fs0:> bzImage.efi console=ttyS0 root=/dev/sda4

The "initrd=" option
--------------------

Like most boot loaders, the EFI stub allows the user to specify
multiple initrd files using the "initrd=" option. This is the only EFI
stub-specific command line parameter, everything else is passed to the
kernel when it boots.

The path to the initrd file must be an absolute path from the
beginning of the ESP, relative path names do not work. Also, the path
is an EFI-style path and directory elements must be separated with
backslashes (\). For example, given the following directory layout::

  fs0:>
	Kernels\
			bzImage.efi
			initrd-large.img

	Ramdisks\
			initrd-small.img
			initrd-medium.img

to boot with the initrd-large.img file if the current working
directory is fs0:\Kernels, the following command must be used::

	fs0:\Kernels> bzImage.efi initrd=\Kernels\initrd-large.img

Notice how bzImage.efi can be specified with a relative path. That's
because the image we're executing is interpreted by the EFI shell,
which understands relative paths, whereas the rest of the command line
is passed to bzImage.efi.

The "dtb=" option
-----------------

For the ARM and arm64 architectures, a device tree must be provided to
the kernel. Normally firmware shall supply the device tree via the
EFI CONFIGURATION TABLE. However, the "dtb=" command line option can
be used to override the firmware supplied device tree, or to supply
one when firmware is unable to.

Please note: Firmware adds runtime configuration information to the
device tree before booting the kernel. If dtb= is used to override
the device tree, then any runtime data provided by firmware will be
lost. The dtb= option should only be used either as a debug tool, or
as a last resort when a device tree is not provided in the EFI
CONFIGURATION TABLE.

"dtb=" is processed in the same manner as the "initrd=" option that is
described above.


code:
.. SPDX-License-Identifier: GPL-2.0

========================
ext4 General Information
========================

Ext4 is an advanced level of the ext3 filesystem which incorporates
scalability and reliability enhancements for supporting large filesystems
(64 bit) in keeping with increasing disk capacities and state-of-the-art
feature requirements.

Mailing list:	linux-ext4@vger.kernel.org
Web site:	http://ext4.wiki.kernel.org

Quick usage instructions
========================

Note: More extensive information for getting started with ext4 can be
found at the ext4 wiki site at the URL:
http://ext4.wiki.kernel.org/index.php/Ext4_Howto

  - The latest version of e2fsprogs can be found at:

    https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/

	or

    http://sourceforge.net/project/showfiles.php?group_id=2406

	or grab the latest git repository from:

   https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git

  - Create a new filesystem using the ext4 filesystem type:

        # mke2fs -t ext4 /dev/hda1

    Or to configure an existing ext3 filesystem to support extents:

	# tune2fs -O extents /dev/hda1

    If the filesystem was created with 128 byte inodes, it can be
    converted to use 256 byte for greater efficiency via:

        # tune2fs -I 256 /dev/hda1

  - Mounting:

	# mount -t ext4 /dev/hda1 /wherever

  - When comparing performance with other filesystems, it's always
    important to try multiple workloads; very often a subtle change in a
    workload parameter can completely change the ranking of which
    filesystems do well compared to others.  When comparing versus ext3,
    note that ext4 enables write barriers by default, while ext3 does
    not enable write barriers by default.  So it is useful to use
    explicitly specify whether barriers are enabled or not when via the
    '-o barriers=[0|1]' mount option for both ext3 and ext4 filesystems
    for a fair comparison.  When tuning ext3 for best benchmark numbers,
    it is often worthwhile to try changing the data journaling mode; '-o
    data=writeback' can be faster for some workloads.  (Note however that
    running mounted with data=writeback can potentially leave stale data
    exposed in recently written files in case of an unclean shutdown,
    which could be a security exposure in some situations.)  Configuring
    the filesystem with a large journal can also be helpful for
    metadata-intensive workloads.

Features
========

Currently Available
-------------------

* ability to use filesystems > 16TB (e2fsprogs support not available yet)
* extent format reduces metadata overhead (RAM, IO for access, transactions)
* extent format more robust in face of on-disk corruption due to magics,
* internal redundancy in tree
* improved file allocation (multi-block alloc)
* lift 32000 subdirectory limit imposed by i_links_count[1]
* nsec timestamps for mtime, atime, ctime, create time
* inode version field on disk (NFSv4, Lustre)
* reduced e2fsck time via uninit_bg feature
* journal checksumming for robustness, performance
* persistent file preallocation (e.g for streaming media, databases)
* ability to pack bitmaps and inode tables into larger virtual groups via the
  flex_bg feature
* large file support
* inode allocation using large virtual block groups via flex_bg
* delayed allocation
* large block (up to pagesize) support
* efficient new ordered mode in JBD2 and ext4 (avoid using buffer head to force
  the ordering)
* Case-insensitive file name lookups
* file-based encryption support (fscrypt)
* file-based verity support (fsverity)

[1] Filesystems with a block size of 1k may see a limit imposed by the
directory hash tree having a maximum depth of two.

case-insensitive file name lookups
======================================================

The case-insensitive file name lookup feature is supported on a
per-directory basis, allowing the user to mix case-insensitive and
case-sensitive directories in the same filesystem.  It is enabled by
flipping the +F inode attribute of an empty directory.  The
case-insensitive string match operation is only defined when we know how
text in encoded in a byte sequence.  For that reason, in order to enable
case-insensitive directories, the filesystem must have the
casefold feature, which stores the filesystem-wide encoding
model used.  By default, the charset adopted is the latest version of
Unicode (12.1.0, by the time of this writing), encoded in the UTF-8
form.  The comparison algorithm is implemented by normalizing the
strings to the Canonical decomposition form, as defined by Unicode,
followed by a byte per byte comparison.

The case-awareness is name-preserving on the disk, meaning that the file
name provided by userspace is a byte-per-byte match to what is actually
written in the disk.  The Unicode normalization format used by the
kernel is thus an internal representation, and not exposed to the
userspace nor to the disk, with the important exception of disk hashes,
used on large case-insensitive directories with DX feature.  On DX
directories, the hash must be calculated using the casefolded version of
the filename, meaning that the normalization format used actually has an
impact on where the directory entry is stored.

When we change from viewing filenames as opaque byte sequences to seeing
them as encoded strings we need to address what happens when a program
tries to create a file with an invalid name.  The Unicode subsystem
within the kernel leaves the decision of what to do in this case to the
filesystem, which select its preferred behavior by enabling/disabling
the strict mode.  When Ext4 encounters one of those strings and the
filesystem did not require strict mode, it falls back to considering the
entire string as an opaque byte sequence, which still allows the user to
operate on that file, but the case-insensitive lookups won't work.

Options
=======

When mounting an ext4 filesystem, the following option are accepted:
(*) == default

  ro
        Mount filesystem read only. Note that ext4 will replay the journal (and
        thus write to the partition) even when mounted "read only". The mount
        options "ro,noload" can be used to prevent writes to the filesystem.

  journal_checksum
        Enable checksumming of the journal transactions.  This will allow the
        recovery code in e2fsck and the kernel to detect corruption in the
        kernel.  It is a compatible change and will be ignored by older
        kernels.

  journal_async_commit
        Commit block can be written to disk without waiting for descriptor
        blocks. If enabled older kernels cannot mount the device. This will
        enable 'journal_checksum' internally.

  journal_path=path, journal_dev=devnum
        When the external journal device's major/minor numbers have changed,
        these options allow the user to specify the new journal location.  The
        journal device is identified through either its new major/minor numbers
        encoded in devnum, or via a path to the device.

  norecovery, noload
        Don't load the journal on mounting.  Note that if the filesystem was
        not unmounted cleanly, skipping the journal replay will lead to the
        filesystem containing inconsistencies that can lead to any number of
        problems.

  data=journal
        All data are committed into the journal prior to being written into the
        main file system.  Enabling this mode will disable delayed allocation
        and O_DIRECT support.

  data=ordered	(*)
        All data are forced directly out to the main file system prior to its
        metadata being committed to the journal.

  data=writeback
        Data ordering is not preserved, data may be written into the main file
        system after its metadata has been committed to the journal.

  commit=nrsec	(*)
        This setting limits the maximum age of the running transaction to
        'nrsec' seconds.  The default value is 5 seconds.  This means that if
        you lose your power, you will lose as much as the latest 5 seconds of
        metadata changes (your filesystem will not be damaged though, thanks
        to the journaling). This default value (or any low value) will hurt
        performance, but it's good for data-safety.  Setting it to 0 will have
        the same effect as leaving it at the default (5 seconds).  Setting it
        to very large values will improve performance.  Note that due to
        delayed allocation even older data can be lost on power failure since
        writeback of those data begins only after time set in
        /proc/sys/vm/dirty_expire_centisecs.

  barrier=<0|1(*)>, barrier(*), nobarrier
        This enables/disables the use of write barriers in the jbd code.
        barrier=0 disables, barrier=1 enables.  This also requires an IO stack
        which can support barriers, and if jbd gets an error on a barrier
        write, it will disable again with a warning.  Write barriers enforce
        proper on-disk ordering of journal commits, making volatile disk write
        caches safe to use, at some performance penalty.  If your disks are
        battery-backed in one way or another, disabling barriers may safely
        improve performance.  The mount options "barrier" and "nobarrier" can
        also be used to enable or disable barriers, for consistency with other
        ext4 mount options.

  inode_readahead_blks=n
        This tuning parameter controls the maximum number of inode table blocks
        that ext4's inode table readahead algorithm will pre-read into the
        buffer cache.  The default value is 32 blocks.

  nouser_xattr
        Disables Extended User Attributes.  See the attr(5) manual page for
        more information about extended attributes.

  noacl
        This option disables POSIX Access Control List support. If ACL support
        is enabled in the kernel configuration (CONFIG_EXT4_FS_POSIX_ACL), ACL
        is enabled by default on mount. See the acl(5) manual page for more
        information about acl.

  bsddf	(*)
        Make 'df' act like BSD.

  minixdf
        Make 'df' act like Minix.

  debug
        Extra debugging information is sent to syslog.

  abort
        Simulate the effects of calling ext4_abort() for debugging purposes.
        This is normally used while remounting a filesystem which is already
        mounted.

  errors=remount-ro
        Remount the filesystem read-only on an error.

  errors=continue
        Keep going on a filesystem error.

  errors=panic
        Panic and halt the machine if an error occurs.  (These mount options
        override the errors behavior specified in the superblock, which can be
        configured using tune2fs)

  data_err=ignore(*)
        Just print an error message if an error occurs in a file data buffer in
        ordered mode.
  data_err=abort
        Abort the journal if an error occurs in a file data buffer in ordered
        mode.

  grpid | bsdgroups
        New objects have the group ID of their parent.

  nogrpid (*) | sysvgroups
        New objects have the group ID of their creator.

  resgid=n
        The group ID which may use the reserved blocks.

  resuid=n
        The user ID which may use the reserved blocks.

  sb=
        Use alternate superblock at this location.

  quota, noquota, grpquota, usrquota
        These options are ignored by the filesystem. They are used only by
        quota tools to recognize volumes where quota should be turned on. See
        documentation in the quota-tools package for more details
        (http://sourceforge.net/projects/linuxquota).

  jqfmt=<quota type>, usrjquota=<file>, grpjquota=<file>
        These options tell filesystem details about quota so that quota
        information can be properly updated during journal replay. They replace
        the above quota options. See documentation in the quota-tools package
        for more details (http://sourceforge.net/projects/linuxquota).

  stripe=n
        Number of filesystem blocks that mballoc will try to use for allocation
        size and alignment. For RAID5/6 systems this should be the number of
        data disks *  RAID chunk size in file system blocks.

  delalloc	(*)
        Defer block allocation until just before ext4 writes out the block(s)
        in question.  This allows ext4 to better allocation decisions more
        efficiently.

  nodelalloc
        Disable delayed allocation.  Blocks are allocated when the data is
        copied from userspace to the page cache, either via the write(2) system
        call or when an mmap'ed page which was previously unallocated is
        written for the first time.

  max_batch_time=usec
        Maximum amount of time ext4 should wait for additional filesystem
        operations to be batch together with a synchronous write operation.
        Since a synchronous write operation is going to force a commit and then
        a wait for the I/O complete, it doesn't cost much, and can be a huge
        throughput win, we wait for a small amount of time to see if any other
        transactions can piggyback on the synchronous write.   The algorithm
        used is designed to automatically tune for the speed of the disk, by
        measuring the amount of time (on average) that it takes to finish
        committing a transaction.  Call this time the "commit time".  If the
        time that the transaction has been running is less than the commit
        time, ext4 will try sleeping for the commit time to see if other
        operations will join the transaction.   The commit time is capped by
        the max_batch_time, which defaults to 15000us (15ms).   This
        optimization can be turned off entirely by setting max_batch_time to 0.

  min_batch_time=usec
        This parameter sets the commit time (as described above) to be at least
        min_batch_time.  It defaults to zero microseconds.  Increasing this
        parameter may improve the throughput of multi-threaded, synchronous
        workloads on very fast disks, at the cost of increasing latency.

  journal_ioprio=prio
        The I/O priority (from 0 to 7, where 0 is the highest priority) which
        should be used for I/O operations submitted by kjournald2 during a
        commit operation.  This defaults to 3, which is a slightly higher
        priority than the default I/O priority.

  auto_da_alloc(*), noauto_da_alloc
        Many broken applications don't use fsync() when replacing existing
        files via patterns such as fd = open("foo.new")/write(fd,..)/close(fd)/
        rename("foo.new", "foo"), or worse yet, fd = open("foo",
        O_TRUNC)/write(fd,..)/close(fd).  If auto_da_alloc is enabled, ext4
        will detect the replace-via-rename and replace-via-truncate patterns
        and force that any delayed allocation blocks are allocated such that at
        the next journal commit, in the default data=ordered mode, the data
        blocks of the new file are forced to disk before the rename() operation
        is committed.  This provides roughly the same level of guarantees as
        ext3, and avoids the "zero-length" problem that can happen when a
        system crashes before the delayed allocation blocks are forced to disk.

  noinit_itable
        Do not initialize any uninitialized inode table blocks in the
        background.  This feature may be used by installation CD's so that the
        install process can complete as quickly as possible; the inode table
        initialization process would then be deferred until the next time the
        file system is unmounted.

  init_itable=n
        The lazy itable init code will wait n times the number of milliseconds
        it took to zero out the previous block group's inode table.  This
        minimizes the impact on the system performance while file system's
        inode table is being initialized.

  discard, nodiscard(*)
        Controls whether ext4 should issue discard/TRIM commands to the
        underlying block device when blocks are freed.  This is useful for SSD
        devices and sparse/thinly-provisioned LUNs, but it is off by default
        until sufficient testing has been done.

  nouid32
        Disables 32-bit UIDs and GIDs.  This is for interoperability  with
        older kernels which only store and expect 16-bit values.

  block_validity(*), noblock_validity
        These options enable or disable the in-kernel facility for tracking
        filesystem metadata blocks within internal data structures.  This
        allows multi- block allocator and other routines to notice bugs or
        corrupted allocation bitmaps which cause blocks to be allocated which
        overlap with filesystem metadata blocks.

  dioread_lock, dioread_nolock
        Controls whether or not ext4 should use the DIO read locking. If the
        dioread_nolock option is specified ext4 will allocate uninitialized
        extent before buffer write and convert the extent to initialized after
        IO completes. This approach allows ext4 code to avoid using inode
        mutex, which improves scalability on high speed storages. However this
        does not work with data journaling and dioread_nolock option will be
        ignored with kernel warning. Note that dioread_nolock code path is only
        used for extent-based files.  Because of the restrictions this options
        comprises it is off by default (e.g. dioread_lock).

  max_dir_size_kb=n
        This limits the size of directories so that any attempt to expand them
        beyond the specified limit in kilobytes will cause an ENOSPC error.
        This is useful in memory constrained environments, where a very large
        directory can cause severe performance problems or even provoke the Out
        Of Memory killer.  (For example, if there is only 512mb memory
        available, a 176mb directory may seriously cramp the system's style.)

  i_version
        Enable 64-bit inode version support. This option is off by default.

  dax
        Use direct access (no page cache).  See
        Documentation/filesystems/dax.rst.  Note that this option is
        incompatible with data=journal.

  inlinecrypt
        When possible, encrypt/decrypt the contents of encrypted files using the
        blk-crypto framework rather than filesystem-layer encryption. This
        allows the use of inline encryption hardware. The on-disk format is
        unaffected. For more details, see
        Documentation/block/inline-encryption.rst.

Data Mode
=========
There are 3 different data modes:

* writeback mode

  In data=writeback mode, ext4 does not journal data at all.  This mode provides
  a similar level of journaling as that of XFS, JFS, and ReiserFS in its default
  mode - metadata journaling.  A crash+recovery can cause incorrect data to
  appear in files which were written shortly before the crash.  This mode will
  typically provide the best ext4 performance.

* ordered mode

  In data=ordered mode, ext4 only officially journals metadata, but it logically
  groups metadata information related to data changes with the data blocks into
  a single unit called a transaction.  When it's time to write the new metadata
  out to disk, the associated data blocks are written first.  In general, this
  mode performs slightly slower than writeback but significantly faster than
  journal mode.

* journal mode

  data=journal mode provides full data and metadata journaling.  All new data is
  written to the journal first, and then to its final location.  In the event of
  a crash, the journal can be replayed, bringing both data and metadata into a
  consistent state.  This mode is the slowest except when data needs to be read
  from and written to disk at the same time where it outperforms all others
  modes.  Enabling this mode will disable delayed allocation and O_DIRECT
  support.

/proc entries
=============

Information about mounted ext4 file systems can be found in
/proc/fs/ext4.  Each mounted filesystem will have a directory in
/proc/fs/ext4 based on its device name (i.e., /proc/fs/ext4/hdc or
/proc/fs/ext4/dm-0).   The files in each per-device directory are shown
in table below.

Files in /proc/fs/ext4/<devname>

  mb_groups
        details of multiblock allocator buddy cache of free blocks

/sys entries
============

Information about mounted ext4 file systems can be found in
/sys/fs/ext4.  Each mounted filesystem will have a directory in
/sys/fs/ext4 based on its device name (i.e., /sys/fs/ext4/hdc or
/sys/fs/ext4/dm-0).   The files in each per-device directory are shown
in table below.

Files in /sys/fs/ext4/<devname>:

(see also Documentation/ABI/testing/sysfs-fs-ext4)

  delayed_allocation_blocks
        This file is read-only and shows the number of blocks that are dirty in
        the page cache, but which do not have their location in the filesystem
        allocated yet.

  inode_goal
        Tuning parameter which (if non-zero) controls the goal inode used by
        the inode allocator in preference to all other allocation heuristics.
        This is intended for debugging use only, and should be 0 on production
        systems.

  inode_readahead_blks
        Tuning parameter which controls the maximum number of inode table
        blocks that ext4's inode table readahead algorithm will pre-read into
        the buffer cache.

  lifetime_write_kbytes
        This file is read-only and shows the number of kilobytes of data that
        have been written to this filesystem since it was created.

  max_writeback_mb_bump
        The maximum number of megabytes the writeback code will try to write
        out before move on to another inode.

  mb_group_prealloc
        The multiblock allocator will round up allocation requests to a
        multiple of this tuning parameter if the stripe size is not set in the
        ext4 superblock

  mb_max_inode_prealloc
        The maximum length of per-inode ext4_prealloc_space list.

  mb_max_to_scan
        The maximum number of extents the multiblock allocator will search to
        find the best extent.

  mb_min_to_scan
        The minimum number of extents the multiblock allocator will search to
        find the best extent.

  mb_order2_req
        Tuning parameter which controls the minimum size for requests (as a
        power of 2) where the buddy cache is used.

  mb_stats
        Controls whether the multiblock allocator should collect statistics,
        which are shown during the unmount. 1 means to collect statistics, 0
        means not to collect statistics.

  mb_stream_req
        Files which have fewer blocks than this tunable parameter will have
        their blocks allocated out of a block group specific preallocation
        pool, so that small files are packed closely together.  Each large file
        will have its blocks allocated out of its own unique preallocation
        pool.

  session_write_kbytes
        This file is read-only and shows the number of kilobytes of data that
        have been written to this filesystem since it was mounted.

  reserved_clusters
        This is RW file and contains number of reserved clusters in the file
        system which will be used in the specific situations to avoid costly
        zeroout, unexpected ENOSPC, or possible data loss. The default is 2% or
        4096 clusters, whichever is smaller and this can be changed however it
        can never exceed number of clusters in the file system. If there is not
        enough space for the reserved space when mounting the file mount will
        _not_ fail.

Ioctls
======

Ext4 implements various ioctls which can be used by applications to access
ext4-specific functionality. An incomplete list of these ioctls is shown in the
table below. This list includes truly ext4-specific ioctls (``EXT4_IOC_*``) as
well as ioctls that may have been ext4-specific originally but are now supported
by some other filesystem(s) too (``FS_IOC_*``).

Table of Ext4 ioctls

  FS_IOC_GETFLAGS
        Get additional attributes associated with inode.  The ioctl argument is
        an integer bitfield, with bit values described in ext4.h.

  FS_IOC_SETFLAGS
        Set additional attributes associated with inode.  The ioctl argument is
        an integer bitfield, with bit values described in ext4.h.

  EXT4_IOC_GETVERSION, EXT4_IOC_GETVERSION_OLD
        Get the inode i_generation number stored for each inode. The
        i_generation number is normally changed only when new inode is created
        and it is particularly useful for network filesystems. The '_OLD'
        version of this ioctl is an alias for FS_IOC_GETVERSION.

  EXT4_IOC_SETVERSION, EXT4_IOC_SETVERSION_OLD
        Set the inode i_generation number stored for each inode. The '_OLD'
        version of this ioctl is an alias for FS_IOC_SETVERSION.

  EXT4_IOC_GROUP_EXTEND
        This ioctl has the same purpose as the resize mount option. It allows
        to resize filesystem to the end of the last existing block group,
        further resize has to be done with resize2fs, either online, or
        offline. The argument points to the unsigned logn number representing
        the filesystem new block count.

  EXT4_IOC_MOVE_EXT
        Move the block extents from orig_fd (the one this ioctl is pointing to)
        to the donor_fd (the one specified in move_extent structure passed as
        an argument to this ioctl). Then, exchange inode metadata between
        orig_fd and donor_fd.  This is especially useful for online
        defragmentation, because the allocator has the opportunity to allocate
        moved blocks better, ideally into one contiguous extent.

  EXT4_IOC_GROUP_ADD
        Add a new group descriptor to an existing or new group descriptor
        block. The new group descriptor is described by ext4_new_group_input
        structure, which is passed as an argument to this ioctl. This is
        especially useful in conjunction with EXT4_IOC_GROUP_EXTEND, which
        allows online resize of the filesystem to the end of the last existing
        block group.  Those two ioctls combined is used in userspace online
        resize tool (e.g. resize2fs).

  EXT4_IOC_MIGRATE
        This ioctl operates on the filesystem itself.  It converts (migrates)
        ext3 indirect block mapped inode to ext4 extent mapped inode by walking
        through indirect block mapping of the original inode and converting
        contiguous block ranges into ext4 extents of the temporary inode. Then,
        inodes are swapped. This ioctl might help, when migrating from ext3 to
        ext4 filesystem, however suggestion is to create fresh ext4 filesystem
        and copy data from the backup. Note, that filesystem has to support
        extents for this ioctl to work.

  EXT4_IOC_ALLOC_DA_BLKS
        Force all of the delay allocated blocks to be allocated to preserve
        application-expected ext3 behaviour. Note that this will also start
        triggering a write of the data blocks, but this behaviour may change in
        the future as it is not necessary and has been done this way only for
        sake of simplicity.

  EXT4_IOC_RESIZE_FS
        Resize the filesystem to a new size.  The number of blocks of resized
        filesystem is passed in via 64 bit integer argument.  The kernel
        allocates bitmaps and inode table, the userspace tool thus just passes
        the new number of blocks.

  EXT4_IOC_SWAP_BOOT
        Swap i_blocks and associated attributes (like i_blocks, i_size,
        i_flags, ...) from the specified inode with inode EXT4_BOOT_LOADER_INO
        (#5). This is typically used to store a boot loader in a secure part of
        the filesystem, where it can't be changed by a normal user by accident.
        The data blocks of the previous boot loader will be associated with the
        given inode.

References
==========

kernel source:	<file:fs/ext4/>
		<file:fs/jbd2/>

programs:	http://e2fsprogs.sourceforge.net/

useful links:	https://fedoraproject.org/wiki/ext3-devel
		http://www.bullopensource.org/ext4/
		http://ext4.wiki.kernel.org/index.php/Main_Page
		https://fedoraproject.org/wiki/Features/Ext4


code:
.. SPDX-License-Identifier: GPL-2.0

.. kernel-feat:: $srctree/Documentation/features


code:
.. SPDX-License-Identifier: GPL-2.0

====================================
File system Monitoring with fanotify
====================================

File system Error Reporting
===========================

Fanotify supports the FAN_FS_ERROR event type for file system-wide error
reporting.  It is meant to be used by file system health monitoring
daemons, which listen for these events and take actions (notify
sysadmin, start recovery) when a file system problem is detected.

By design, a FAN_FS_ERROR notification exposes sufficient information
for a monitoring tool to know a problem in the file system has happened.
It doesn't necessarily provide a user space application with semantics
to verify an IO operation was successfully executed.  That is out of
scope for this feature.  Instead, it is only meant as a framework for
early file system problem detection and reporting recovery tools.

When a file system operation fails, it is common for dozens of kernel
errors to cascade after the initial failure, hiding the original failure
log, which is usually the most useful debug data to troubleshoot the
problem.  For this reason, FAN_FS_ERROR tries to report only the first
error that occurred for a file system since the last notification, and
it simply counts additional errors.  This ensures that the most
important pieces of information are never lost.

FAN_FS_ERROR requires the fanotify group to be setup with the
FAN_REPORT_FID flag.

At the time of this writing, the only file system that emits FAN_FS_ERROR
notifications is Ext4.

A FAN_FS_ERROR Notification has the following format::

  ::

     [ Notification Metadata (Mandatory) ]
     [ Generic Error Record  (Mandatory) ]
     [ FID record            (Mandatory) ]

The order of records is not guaranteed, and new records might be added
in the future.  Therefore, applications must not rely on the order and
must be prepared to skip over unknown records. Please refer to
``samples/fanotify/fs-monitor.c`` for an example parser.

Generic error record
--------------------

The generic error record provides enough information for a file system
agnostic tool to learn about a problem in the file system, without
providing any additional details about the problem.  This record is
identified by ``struct fanotify_event_info_header.info_type`` being set
to FAN_EVENT_INFO_TYPE_ERROR.

  ::

     struct fanotify_event_info_error {
          struct fanotify_event_info_header hdr;
         __s32 error;
         __u32 error_count;
     };

The `error` field identifies the type of error using errno values.
`error_count` tracks the number of errors that occurred and were
suppressed to preserve the original error information, since the last
notification.

FID record
----------

The FID record can be used to uniquely identify the inode that triggered
the error through the combination of fsid and file handle.  A file system
specific application can use that information to attempt a recovery
procedure.  Errors that are not related to an inode are reported with an
empty file handle of type FILEID_INVALID.


code:
.. SPDX-License-Identifier: GPL-2.0-only

GPIO Aggregator
===============

The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as
a new gpio_chip.  This supports the following use cases.

Aggregating GPIOs using Sysfs
-----------------------------

GPIO controllers are exported to userspace using /dev/gpiochip* character
devices.  Access control to these devices is provided by standard UNIX file
system permissions, on an all-or-nothing basis: either a GPIO controller is
accessible for a user, or it is not.

The GPIO Aggregator provides access control for a set of one or more GPIOs, by
aggregating them into a new gpio_chip, which can be assigned to a group or user
using standard UNIX file ownership and permissions.  Furthermore, this
simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just
grab the full GPIO controller, and no longer needs to care about which GPIOs to
grab and which not, reducing the attack surface.

Aggregated GPIO controllers are instantiated and destroyed by writing to
write-only attribute files in sysfs.

    /sys/bus/platform/drivers/gpio-aggregator/

	"new_device" ...
		Userspace may ask the kernel to instantiate an aggregated GPIO
		controller by writing a string describing the GPIOs to
		aggregate to the "new_device" file, using the format

		.. code-block:: none

		    [<gpioA>] [<gpiochipB> <offsets>] ...

		Where:

		    "<gpioA>" ...
			    is a GPIO line name,

		    "<gpiochipB>" ...
			    is a GPIO chip label, and

		    "<offsets>" ...
			    is a comma-separated list of GPIO offsets and/or
			    GPIO offset ranges denoted by dashes.

		Example: Instantiate a new GPIO aggregator by aggregating GPIO
		line 19 of "e6052000.gpio" and GPIO lines 20-21 of
		"e6050000.gpio" into a new gpio_chip:

		.. code-block:: sh

		    $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device

	"delete_device" ...
		Userspace may ask the kernel to destroy an aggregated GPIO
		controller after use by writing its device name to the
		"delete_device" file.

		Example: Destroy the previously-created aggregated GPIO
		controller, assumed to be "gpio-aggregator.0":

		.. code-block:: sh

		    $ echo gpio-aggregator.0 > delete_device

Generic GPIO Driver
-------------------

The GPIO Aggregator can also be used as a generic driver for a simple
GPIO-operated device described in DT, without a dedicated in-kernel driver.
This is useful in industrial control, and is not unlike e.g. spidev, which
allows the user to communicate with an SPI device from userspace.

Binding a device to the GPIO Aggregator is performed either by modifying the
gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs.

Example: If "door" is a GPIO-operated device described in DT, using its own
compatible value::

	door {
		compatible = "myvendor,mydoor";

		gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
			<&gpio2 20 GPIO_ACTIVE_LOW>;
		gpio-line-names = "open", "lock";
	};

it can be bound to the GPIO Aggregator by either:

1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
2. Binding manually using "driver_override":

.. code-block:: sh

    $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
    $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind

After that, a new gpiochip "door" has been created:

.. code-block:: sh

    $ gpioinfo door
    gpiochip12 - 2 lines:
	    line   0:       "open"       unused   input  active-high
	    line   1:       "lock"       unused   input  active-high


code:
.. SPDX-License-Identifier: GPL-2.0-only

GPIO Testing Driver
===================

The GPIO Testing Driver (gpio-mockup) provides a way to create simulated GPIO
chips for testing purposes. The lines exposed by these chips can be accessed
using the standard GPIO character device interface as well as manipulated
using the dedicated debugfs directory structure.

Creating simulated chips using module params
--------------------------------------------

When loading the gpio-mockup driver a number of parameters can be passed to the
module.

    gpio_mockup_ranges

        This parameter takes an argument in the form of an array of integer
        pairs. Each pair defines the base GPIO number (non-negative integer)
        and the first number after the last of this chip. If the base GPIO
        is -1, the gpiolib will assign it automatically. while the following
        parameter is the number of lines exposed by the chip.

        Example: gpio_mockup_ranges=-1,8,-1,16,405,409

        The line above creates three chips. The first one will expose 8 lines,
        the second 16 and the third 4. The base GPIO for the third chip is set
        to 405 while for two first chips it will be assigned automatically.

    gpio_mockup_named_lines

        This parameter doesn't take any arguments. It lets the driver know that
        GPIO lines exposed by it should be named.

        The name format is: gpio-mockup-X-Y where X is mockup chip's ID
        and Y is the line offset.

Manipulating simulated lines
----------------------------

Each mockup chip creates its own subdirectory in /sys/kernel/debug/gpio-mockup/.
The directory is named after the chip's label. A symlink is also created, named
after the chip's name, which points to the label directory.

Inside each subdirectory, there's a separate attribute for each GPIO line. The
name of the attribute represents the line's offset in the chip.

Reading from a line attribute returns the current value. Writing to it (0 or 1)
changes the configuration of the simulated pull-up/pull-down resistor
(1 - pull-up, 0 - pull-down).


code:
.. SPDX-License-Identifier: GPL-2.0-or-later

Configfs GPIO Simulator
=======================

The configfs GPIO Simulator (gpio-sim) provides a way to create simulated GPIO
chips for testing purposes. The lines exposed by these chips can be accessed
using the standard GPIO character device interface as well as manipulated
using sysfs attributes.

Creating simulated chips
------------------------

The gpio-sim module registers a configfs subsystem called ``'gpio-sim'``. For
details of the configfs filesystem, please refer to the configfs documentation.

The user can create a hierarchy of configfs groups and items as well as modify
values of exposed attributes. Once the chip is instantiated, this hierarchy
will be translated to appropriate device properties. The general structure is:

**Group:** ``/config/gpio-sim``

This is the top directory of the gpio-sim configfs tree.

**Group:** ``/config/gpio-sim/gpio-device``

**Attribute:** ``/config/gpio-sim/gpio-device/dev_name``

**Attribute:** ``/config/gpio-sim/gpio-device/live``

This is a directory representing a GPIO platform device. The ``'dev_name'``
attribute is read-only and allows the user-space to read the platform device
name (e.g. ``'gpio-sim.0'``). The ``'live'`` attribute allows to trigger the
actual creation of the device once it's fully configured. The accepted values
are: ``'1'`` to enable the simulated device and ``'0'`` to disable and tear
it down.

**Group:** ``/config/gpio-sim/gpio-device/gpio-bankX``

**Attribute:** ``/config/gpio-sim/gpio-device/gpio-bankX/chip_name``

**Attribute:** ``/config/gpio-sim/gpio-device/gpio-bankX/num_lines``

This group represents a bank of GPIOs under the top platform device. The
``'chip_name'`` attribute is read-only and allows the user-space to read the
device name of the bank device. The ``'num_lines'`` attribute allows to specify
the number of lines exposed by this bank.

**Group:** ``/config/gpio-sim/gpio-device/gpio-bankX/lineY``

**Attribute:** ``/config/gpio-sim/gpio-device/gpio-bankX/lineY/name``

This group represents a single line at the offset Y. The 'name' attribute
allows to set the line name as represented by the 'gpio-line-names' property.

**Item:** ``/config/gpio-sim/gpio-device/gpio-bankX/lineY/hog``

**Attribute:** ``/config/gpio-sim/gpio-device/gpio-bankX/lineY/hog/name``

**Attribute:** ``/config/gpio-sim/gpio-device/gpio-bankX/lineY/hog/direction``

This item makes the gpio-sim module hog the associated line. The ``'name'``
attribute specifies the in-kernel consumer name to use. The ``'direction'``
attribute specifies the hog direction and must be one of: ``'input'``,
``'output-high'`` and ``'output-low'``.

Inside each bank directory, there's a set of attributes that can be used to
configure the new chip. Additionally the user can ``mkdir()`` subdirectories
inside the chip's directory that allow to pass additional configuration for
specific lines. The name of those subdirectories must take the form of:
``'line<offset>'`` (e.g. ``'line0'``, ``'line20'``, etc.) as the name will be
used by the module to assign the config to the specific line at given offset.

Once the confiuration is complete, the ``'live'`` attribute must be set to 1 in
order to instantiate the chip. It can be set back to 0 to destroy the simulated
chip. The module will synchronously wait for the new simulated device to be
successfully probed and if this doesn't happen, writing to ``'live'`` will
result in an error.

Simulated GPIO chips can also be defined in device-tree. The compatible string
must be: ``"gpio-simulator"``. Supported properties are:

  ``"gpio-sim,label"`` - chip label

Other standard GPIO properties (like ``"gpio-line-names"``, ``"ngpios"`` or
``"gpio-hog"``) are also supported. Please refer to the GPIO documentation for
details.

An example device-tree code defining a GPIO simulator:

.. code-block :: none

    gpio-sim {
        compatible = "gpio-simulator";

        bank0 {
            gpio-controller;
            #gpio-cells = <2>;
            ngpios = <16>;
            gpio-sim,label = "dt-bank0";
            gpio-line-names = "", "sim-foo", "", "sim-bar";
        };

        bank1 {
            gpio-controller;
            #gpio-cells = <2>;
            ngpios = <8>;
            gpio-sim,label = "dt-bank1";

            line3 {
                gpio-hog;
                gpios = <3 0>;
                output-high;
                line-name = "sim-hog-from-dt";
            };
        };
    };

Manipulating simulated lines
----------------------------

Each simulated GPIO chip creates a separate sysfs group under its device
directory for each exposed line
(e.g. ``/sys/devices/platform/gpio-sim.X/gpiochipY/``). The name of each group
is of the form: ``'sim_gpioX'`` where X is the offset of the line. Inside each
group there are two attibutes:

    ``pull`` - allows to read and set the current simulated pull setting for
               every line, when writing the value must be one of: ``'pull-up'``,
               ``'pull-down'``

    ``value`` - allows to read the current value of the line which may be
                different from the pull if the line is being driven from
                user-space


code:
.. SPDX-License-Identifier: GPL-2.0

====
gpio
====

.. toctree::
    :maxdepth: 1

    gpio-aggregator
    sysfs
    gpio-mockup
    gpio-sim

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
GPIO Sysfs Interface for Userspace
==================================

.. warning::

  THIS ABI IS DEPRECATED, THE ABI DOCUMENTATION HAS BEEN MOVED TO
  Documentation/ABI/obsolete/sysfs-gpio AND NEW USERSPACE CONSUMERS
  ARE SUPPOSED TO USE THE CHARACTER DEVICE ABI. THIS OLD SYSFS ABI WILL
  NOT BE DEVELOPED (NO NEW FEATURES), IT WILL JUST BE MAINTAINED.

Refer to the examples in tools/gpio/* for an introduction to the new
character device ABI. Also see the userspace header in
include/uapi/linux/gpio.h

The deprecated sysfs ABI
------------------------
Platforms which use the "gpiolib" implementors framework may choose to
configure a sysfs user interface to GPIOs. This is different from the
debugfs interface, since it provides control over GPIO direction and
value instead of just showing a gpio state summary. Plus, it could be
present on production systems without debugging support.

Given appropriate hardware documentation for the system, userspace could
know for example that GPIO #23 controls the write protect line used to
protect boot loader segments in flash memory. System upgrade procedures
may need to temporarily remove that protection, first importing a GPIO,
then changing its output state, then updating the code before re-enabling
the write protection. In normal use, GPIO #23 would never be touched,
and the kernel would have no need to know about it.

Again depending on appropriate hardware documentation, on some systems
userspace GPIO can be used to determine system configuration data that
standard kernels won't know about. And for some tasks, simple userspace
GPIO drivers could be all that the system really needs.

DO NOT ABUSE SYSFS TO CONTROL HARDWARE THAT HAS PROPER KERNEL DRIVERS.
PLEASE READ THE DOCUMENT AT Documentation/driver-api/gpio/drivers-on-gpio.rst
TO AVOID REINVENTING KERNEL WHEELS IN USERSPACE. I MEAN IT. REALLY.

Paths in Sysfs
--------------
There are three kinds of entries in /sys/class/gpio:

   -	Control interfaces used to get userspace control over GPIOs;

   -	GPIOs themselves; and

   -	GPIO controllers ("gpio_chip" instances).

That's in addition to standard files including the "device" symlink.

The control interfaces are write-only:

    /sys/class/gpio/

	"export" ...
		Userspace may ask the kernel to export control of
		a GPIO to userspace by writing its number to this file.

		Example:  "echo 19 > export" will create a "gpio19" node
		for GPIO #19, if that's not requested by kernel code.

	"unexport" ...
		Reverses the effect of exporting to userspace.

		Example:  "echo 19 > unexport" will remove a "gpio19"
		node exported using the "export" file.

GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:

    /sys/class/gpio/gpioN/

	"direction" ...
		reads as either "in" or "out". This value may
		normally be written. Writing as "out" defaults to
		initializing the value as low. To ensure glitch free
		operation, values "low" and "high" may be written to
		configure the GPIO as an output with that initial value.

		Note that this attribute *will not exist* if the kernel
		doesn't support changing the direction of a GPIO, or
		it was exported by kernel code that didn't explicitly
		allow userspace to reconfigure this GPIO's direction.

	"value" ...
		reads as either 0 (low) or 1 (high). If the GPIO
		is configured as an output, this value may be written;
		any nonzero value is treated as high.

		If the pin can be configured as interrupt-generating interrupt
		and if it has been configured to generate interrupts (see the
		description of "edge"), you can poll(2) on that file and
		poll(2) will return whenever the interrupt was triggered. If
		you use poll(2), set the events POLLPRI and POLLERR. If you
		use select(2), set the file descriptor in exceptfds. After
		poll(2) returns, either lseek(2) to the beginning of the sysfs
		file and read the new value or close the file and re-open it
		to read the value.

	"edge" ...
		reads as either "none", "rising", "falling", or
		"both". Write these strings to select the signal edge(s)
		that will make poll(2) on the "value" file return.

		This file exists only if the pin can be configured as an
		interrupt generating input pin.

	"active_low" ...
		reads as either 0 (false) or 1 (true). Write
		any nonzero value to invert the value attribute both
		for reading and writing. Existing and subsequent
		poll(2) support configuration via the edge attribute
		for "rising" and "falling" edges will follow this
		setting.

GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
controller implementing GPIOs starting at #42) and have the following
read-only attributes:

    /sys/class/gpio/gpiochipN/

	"base" ...
		same as N, the first GPIO managed by this chip

	"label" ...
		provided for diagnostics (not always unique)

	"ngpio" ...
		how many GPIOs this manages (N to N + ngpio - 1)

Board documentation should in most cases cover what GPIOs are used for
what purposes. However, those numbers are not always stable; GPIOs on
a daughtercard might be different depending on the base board being used,
or other cards in the stack. In such cases, you may need to use the
gpiochip nodes (possibly in conjunction with schematics) to determine
the correct GPIO number to use for a given signal.

Exporting from Kernel code
--------------------------
Kernel code can explicitly manage exports of GPIOs which have already been
requested using gpio_request()::

	/* export the GPIO to userspace */
	int gpiod_export(struct gpio_desc *desc, bool direction_may_change);

	/* reverse gpio_export() */
	void gpiod_unexport(struct gpio_desc *desc);

	/* create a sysfs link to an exported GPIO node */
	int gpiod_export_link(struct device *dev, const char *name,
		      struct gpio_desc *desc);

After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpiod_export(). The driver can control whether the
signal direction may change. This helps drivers prevent userspace code
from accidentally clobbering important system state.

This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface that's
suitable for documenting as part of a board support package.

After the GPIO has been exported, gpiod_export_link() allows creating
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
use this to provide the interface under their own device in sysfs with
a descriptive name.


code:
===================================================
Notes on the change from 16-bit UIDs to 32-bit UIDs
===================================================

:Author: Chris Wing <wingc@umich.edu>
:Last updated: January 11, 2000

- kernel code MUST take into account __kernel_uid_t and __kernel_uid32_t
  when communicating between user and kernel space in an ioctl or data
  structure.

- kernel code should use uid_t and gid_t in kernel-private structures and
  code.

What's left to be done for 32-bit UIDs on all Linux architectures:

- Disk quotas have an interesting limitation that is not related to the
  maximum UID/GID. They are limited by the maximum file size on the
  underlying filesystem, because quota records are written at offsets
  corresponding to the UID in question.
  Further investigation is needed to see if the quota system can cope
  properly with huge UIDs. If it can deal with 64-bit file offsets on all
  architectures, this should not be a problem.

- Decide whether or not to keep backwards compatibility with the system
  accounting file, or if we should break it as the comments suggest
  (currently, the old 16-bit UID and GID are still written to disk, and
  part of the former pad space is used to store separate 32-bit UID and
  GID)

- Need to validate that OS emulation calls the 16-bit UID
  compatibility syscalls, if the OS being emulated used 16-bit UIDs, or
  uses the 32-bit UID system calls properly otherwise.

  This affects at least:

	- iBCS on Intel

	- sparc32 emulation on sparc64
	  (need to support whatever new 32-bit UID system calls are added to
	  sparc32)

- Validate that all filesystems behave properly.

  At present, 32-bit UIDs _should_ work for:

	- ext2
	- ufs
	- isofs
	- nfs
	- coda
	- udf

  Ioctl() fixups have been made for:

	- ncpfs
	- smbfs

  Filesystems with simple fixups to prevent 16-bit UID wraparound:

	- minix
	- sysv
	- qnx4

  Other filesystems have not been checked yet.

- The ncpfs and smpfs filesystems cannot presently use 32-bit UIDs in
  all ioctl()s. Some new ioctl()s have been added with 32-bit UIDs, but
  more are needed. (as well as new user<->kernel data structures)

- The ELF core dump format only supports 16-bit UIDs on arm, i386, m68k,
  sh, and sparc32. Fixing this is probably not that important, but would
  require adding a new ELF section.

- The ioctl()s used to control the in-kernel NFS server only support
  16-bit UIDs on arm, i386, m68k, sh, and sparc32.

- make sure that the UID mapping feature of AX25 networking works properly
  (it should be safe because it's always used a 32-bit integer to
  communicate between user and kernel)


code:
.. SPDX-License-Identifier: GPL-2.0

===============
Core Scheduling
===============
Core scheduling support allows userspace to define groups of tasks that can
share a core. These groups can be specified either for security usecases (one
group of tasks don't trust another), or for performance usecases (some
workloads may benefit from running on the same core as they don't need the same
hardware resources of the shared core, or may prefer different cores if they
do share hardware resource needs). This document only describes the security
usecase.

Security usecase
----------------
A cross-HT attack involves the attacker and victim running on different Hyper
Threads of the same core. MDS and L1TF are examples of such attacks.  The only
full mitigation of cross-HT attacks is to disable Hyper Threading (HT). Core
scheduling is a scheduler feature that can mitigate some (not all) cross-HT
attacks. It allows HT to be turned on safely by ensuring that only tasks in a
user-designated trusted group can share a core. This increase in core sharing
can also improve performance, however it is not guaranteed that performance
will always improve, though that is seen to be the case with a number of real
world workloads. In theory, core scheduling aims to perform at least as good as
when Hyper Threading is disabled. In practice, this is mostly the case though
not always: as synchronizing scheduling decisions across 2 or more CPUs in a
core involves additional overhead - especially when the system is lightly
loaded. When ``total_threads <= N_CPUS/2``, the extra overhead may cause core
scheduling to perform more poorly compared to SMT-disabled, where N_CPUS is the
total number of CPUs. Please measure the performance of your workloads always.

Usage
-----
Core scheduling support is enabled via the ``CONFIG_SCHED_CORE`` config option.
Using this feature, userspace defines groups of tasks that can be co-scheduled
on the same core. The core scheduler uses this information to make sure that
tasks that are not in the same group never run simultaneously on a core, while
doing its best to satisfy the system's scheduling requirements.

Core scheduling can be enabled via the ``PR_SCHED_CORE`` prctl interface.
This interface provides support for the creation of core scheduling groups, as
well as admission and removal of tasks from created groups::

    #include <sys/prctl.h>

    int prctl(int option, unsigned long arg2, unsigned long arg3,
            unsigned long arg4, unsigned long arg5);

option:
    ``PR_SCHED_CORE``

arg2:
    Command for operation, must be one off:

    - ``PR_SCHED_CORE_GET`` -- get core_sched cookie of ``pid``.
    - ``PR_SCHED_CORE_CREATE`` -- create a new unique cookie for ``pid``.
    - ``PR_SCHED_CORE_SHARE_TO`` -- push core_sched cookie to ``pid``.
    - ``PR_SCHED_CORE_SHARE_FROM`` -- pull core_sched cookie from ``pid``.

arg3:
    ``pid`` of the task for which the operation applies.

arg4:
    ``pid_type`` for which the operation applies. It is one of
    ``PR_SCHED_CORE_SCOPE_``-prefixed macro constants.  For example, if arg4
    is ``PR_SCHED_CORE_SCOPE_THREAD_GROUP``, then the operation of this command
    will be performed for all tasks in the task group of ``pid``.

arg5:
    userspace pointer to an unsigned long for storing the cookie returned by
    ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.

In order for a process to push a cookie to, or pull a cookie from a process, it
is required to have the ptrace access mode: `PTRACE_MODE_READ_REALCREDS` to the
process.

Building hierarchies of tasks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The simplest way to build hierarchies of threads/processes which share a
cookie and thus a core is to rely on the fact that the core-sched cookie is
inherited across forks/clones and execs, thus setting a cookie for the
'initial' script/executable/daemon will place every spawned child in the
same core-sched group.

Cookie Transferral
~~~~~~~~~~~~~~~~~~
Transferring a cookie between the current and other tasks is possible using
PR_SCHED_CORE_SHARE_FROM and PR_SCHED_CORE_SHARE_TO to inherit a cookie from a
specified task or a share a cookie with a task. In combination this allows a
simple helper program to pull a cookie from a task in an existing core
scheduling group and share it with already running tasks.

Design/Implementation
---------------------
Each task that is tagged is assigned a cookie internally in the kernel. As
mentioned in `Usage`_, tasks with the same cookie value are assumed to trust
each other and share a core.

The basic idea is that, every schedule event tries to select tasks for all the
siblings of a core such that all the selected tasks running on a core are
trusted (same cookie) at any point in time. Kernel threads are assumed trusted.
The idle task is considered special, as it trusts everything and everything
trusts it.

During a schedule() event on any sibling of a core, the highest priority task on
the sibling's core is picked and assigned to the sibling calling schedule(), if
the sibling has the task enqueued. For rest of the siblings in the core,
highest priority task with the same cookie is selected if there is one runnable
in their individual run queues. If a task with same cookie is not available,
the idle task is selected.  Idle task is globally trusted.

Once a task has been selected for all the siblings in the core, an IPI is sent to
siblings for whom a new task was selected. Siblings on receiving the IPI will
switch to the new task immediately. If an idle task is selected for a sibling,
then the sibling is considered to be in a `forced idle` state. I.e., it may
have tasks on its on runqueue to run, however it will still have to run idle.
More on this in the next section.

Forced-idling of hyperthreads
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The scheduler tries its best to find tasks that trust each other such that all
tasks selected to be scheduled are of the highest priority in a core.  However,
it is possible that some runqueues had tasks that were incompatible with the
highest priority ones in the core. Favoring security over fairness, one or more
siblings could be forced to select a lower priority task if the highest
priority task is not trusted with respect to the core wide highest priority
task.  If a sibling does not have a trusted task to run, it will be forced idle
by the scheduler (idle thread is scheduled to run).

When the highest priority task is selected to run, a reschedule-IPI is sent to
the sibling to force it into idle. This results in 4 cases which need to be
considered depending on whether a VM or a regular usermode process was running
on either HT::

          HT1 (attack)            HT2 (victim)
   A      idle -> user space      user space -> idle
   B      idle -> user space      guest -> idle
   C      idle -> guest           user space -> idle
   D      idle -> guest           guest -> idle

Note that for better performance, we do not wait for the destination CPU
(victim) to enter idle mode. This is because the sending of the IPI would bring
the destination CPU immediately into kernel mode from user space, or VMEXIT
in the case of guests. At best, this would only leak some scheduler metadata
which may not be worth protecting. It is also possible that the IPI is received
too late on some architectures, but this has not been observed in the case of
x86.

Trust model
~~~~~~~~~~~
Core scheduling maintains trust relationships amongst groups of tasks by
assigning them a tag that is the same cookie value.
When a system with core scheduling boots, all tasks are considered to trust
each other. This is because the core scheduler does not have information about
trust relationships until userspace uses the above mentioned interfaces, to
communicate them. In other words, all tasks have a default cookie value of 0.
and are considered system-wide trusted. The forced-idling of siblings running
cookie-0 tasks is also avoided.

Once userspace uses the above mentioned interfaces to group sets of tasks, tasks
within such groups are considered to trust each other, but do not trust those
outside. Tasks outside the group also don't trust tasks within.

Limitations of core-scheduling
------------------------------
Core scheduling tries to guarantee that only trusted tasks run concurrently on a
core. But there could be small window of time during which untrusted tasks run
concurrently or kernel could be running concurrently with a task not trusted by
kernel.

IPI processing delays
~~~~~~~~~~~~~~~~~~~~~
Core scheduling selects only trusted tasks to run together. IPI is used to notify
the siblings to switch to the new task. But there could be hardware delays in
receiving of the IPI on some arch (on x86, this has not been observed). This may
cause an attacker task to start running on a CPU before its siblings receive the
IPI. Even though cache is flushed on entry to user mode, victim tasks on siblings
may populate data in the cache and micro architectural buffers after the attacker
starts to run and this is a possibility for data leak.

Open cross-HT issues that core scheduling does not solve
--------------------------------------------------------
1. For MDS
~~~~~~~~~~
Core scheduling cannot protect against MDS attacks between the siblings
running in user mode and the others running in kernel mode. Even though all
siblings run tasks which trust each other, when the kernel is executing
code on behalf of a task, it cannot trust the code running in the
sibling. Such attacks are possible for any combination of sibling CPU modes
(host or guest mode).

2. For L1TF
~~~~~~~~~~~
Core scheduling cannot protect against an L1TF guest attacker exploiting a
guest or host victim. This is because the guest attacker can craft invalid
PTEs which are not inverted due to a vulnerable guest kernel. The only
solution is to disable EPT (Extended Page Tables).

For both MDS and L1TF, if the guest vCPU is configured to not trust each
other (by tagging separately), then the guest to guest attacks would go away.
Or it could be a system admin policy which considers guest to guest attacks as
a guest problem.

Another approach to resolve these would be to make every untrusted task on the
system to not trust every other untrusted task. While this could reduce
parallelism of the untrusted tasks, it would still solve the above issues while
allowing system processes (trusted tasks) to share a core.

3. Protecting the kernel (IRQ, syscall, VMEXIT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unfortunately, core scheduling does not protect kernel contexts running on
sibling hyperthreads from one another. Prototypes of mitigations have been posted
to LKML to solve this, but it is debatable whether such windows are practically
exploitable, and whether the performance overhead of the prototypes are worth
it (not to mention, the added code complexity).

Other Use cases
---------------
The main use case for Core scheduling is mitigating the cross-HT vulnerabilities
with SMT enabled. There are other use cases where this feature could be used:

- Isolating tasks that needs a whole core: Examples include realtime tasks, tasks
  that uses SIMD instructions etc.
- Gang scheduling: Requirements for a group of tasks that needs to be scheduled
  together could also be realized using core scheduling. One example is vCPUs of
  a VM.


code:
========================
Hardware vulnerabilities
========================

This section describes CPU vulnerabilities and provides an overview of the
possible mitigations along with guidance for selecting mitigations if they
are configurable at compile, boot or run time.

.. toctree::
   :maxdepth: 1

   spectre
   l1tf
   mds
   tsx_async_abort
   multihit.rst
   special-register-buffer-data-sampling.rst
   core-scheduling.rst
   l1d_flush.rst
   processor_mmio_stale_data.rst


code:
L1D Flushing
============

With an increasing number of vulnerabilities being reported around data
leaks from the Level 1 Data cache (L1D) the kernel provides an opt-in
mechanism to flush the L1D cache on context switch.

This mechanism can be used to address e.g. CVE-2020-0550. For applications
the mechanism keeps them safe from vulnerabilities, related to leaks
(snooping of) from the L1D cache.

Related CVEs
------------
The following CVEs can be addressed by this
mechanism

    =============       ========================     ==================
    CVE-2020-0550       Improper Data Forwarding     OS related aspects
    =============       ========================     ==================

Usage Guidelines
----------------

Please see document: :ref:`Documentation/userspace-api/spec_ctrl.rst
<set_spec_ctrl>` for details.

**NOTE**: The feature is disabled by default, applications need to
specifically opt into the feature to enable it.

Mitigation
----------

When PR_SET_L1D_FLUSH is enabled for a task a flush of the L1D cache is
performed when the task is scheduled out and the incoming task belongs to a
different process and therefore to a different address space.

If the underlying CPU supports L1D flushing in hardware, the hardware
mechanism is used, software fallback for the mitigation, is not supported.

Mitigation control on the kernel command line
---------------------------------------------

The kernel command line allows to control the L1D flush mitigations at boot
time with the option "l1d_flush=". The valid arguments for this option are:

  ============  =============================================================
  on            Enables the prctl interface, applications trying to use
                the prctl() will fail with an error if l1d_flush is not
                enabled
  ============  =============================================================

By default the mechanism is disabled.

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

The mechanism does not mitigate L1D data leaks between tasks belonging to
different processes which are concurrently executing on sibling threads of
a physical CPU core when SMT is enabled on the system.

This can be addressed by controlled placement of processes on physical CPU
cores or by disabling SMT. See the relevant chapter in the L1TF mitigation
document: :ref:`Documentation/admin-guide/hw-vuln/l1tf.rst <smt_control>`.

**NOTE** : The opt-in of a task for L1D flushing works only when the task's
affinity is limited to cores running in non-SMT mode. If a task which
requested L1D flushing is scheduled on a SMT-enabled core the kernel sends
a SIGBUS to the task.