cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fallback-mechanisms.rst (14818B)


      1===================
      2Fallback mechanisms
      3===================
      4
      5A fallback mechanism is supported to allow to overcome failures to do a direct
      6filesystem lookup on the root filesystem or when the firmware simply cannot be
      7installed for practical reasons on the root filesystem. The kernel
      8configuration options related to supporting the firmware fallback mechanism are:
      9
     10  * CONFIG_FW_LOADER_USER_HELPER: enables building the firmware fallback
     11    mechanism. Most distributions enable this option today. If enabled but
     12    CONFIG_FW_LOADER_USER_HELPER_FALLBACK is disabled, only the custom fallback
     13    mechanism is available and for the request_firmware_nowait() call.
     14  * CONFIG_FW_LOADER_USER_HELPER_FALLBACK: force enables each request to
     15    enable the kobject uevent fallback mechanism on all firmware API calls
     16    except request_firmware_direct(). Most distributions disable this option
     17    today. The call request_firmware_nowait() allows for one alternative
     18    fallback mechanism: if this kconfig option is enabled and your second
     19    argument to request_firmware_nowait(), uevent, is set to false you are
     20    informing the kernel that you have a custom fallback mechanism and it will
     21    manually load the firmware. Read below for more details.
     22
     23Note that this means when having this configuration:
     24
     25CONFIG_FW_LOADER_USER_HELPER=y
     26CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n
     27
     28the kobject uevent fallback mechanism will never take effect even
     29for request_firmware_nowait() when uevent is set to true.
     30
     31Justifying the firmware fallback mechanism
     32==========================================
     33
     34Direct filesystem lookups may fail for a variety of reasons. Known reasons for
     35this are worth itemizing and documenting as it justifies the need for the
     36fallback mechanism:
     37
     38* Race against access with the root filesystem upon bootup.
     39
     40* Races upon resume from suspend. This is resolved by the firmware cache, but
     41  the firmware cache is only supported if you use uevents, and its not
     42  supported for request_firmware_into_buf().
     43
     44* Firmware is not accessible through typical means:
     45
     46        * It cannot be installed into the root filesystem
     47        * The firmware provides very unique device specific data tailored for
     48          the unit gathered with local information. An example is calibration
     49          data for WiFi chipsets for mobile devices. This calibration data is
     50          not common to all units, but tailored per unit.  Such information may
     51          be installed on a separate flash partition other than where the root
     52          filesystem is provided.
     53
     54Types of fallback mechanisms
     55============================
     56
     57There are really two fallback mechanisms available using one shared sysfs
     58interface as a loading facility:
     59
     60* Kobject uevent fallback mechanism
     61* Custom fallback mechanism
     62
     63First lets document the shared sysfs loading facility.
     64
     65Firmware sysfs loading facility
     66===============================
     67
     68In order to help device drivers upload firmware using a fallback mechanism
     69the firmware infrastructure creates a sysfs interface to enable userspace
     70to load and indicate when firmware is ready. The sysfs directory is created
     71via fw_create_instance(). This call creates a new struct device named after
     72the firmware requested, and establishes it in the device hierarchy by
     73associating the device used to make the request as the device's parent.
     74The sysfs directory's file attributes are defined and controlled through
     75the new device's class (firmware_class) and group (fw_dev_attr_groups).
     76This is actually where the original firmware_class module name came from,
     77given that originally the only firmware loading mechanism available was the
     78mechanism we now use as a fallback mechanism, which registers a struct class
     79firmware_class. Because the attributes exposed are part of the module name, the
     80module name firmware_class cannot be renamed in the future, to ensure backward
     81compatibility with old userspace.
     82
     83To load firmware using the sysfs interface we expose a loading indicator,
     84and a file upload firmware into:
     85
     86  * /sys/$DEVPATH/loading
     87  * /sys/$DEVPATH/data
     88
     89To upload firmware you will echo 1 onto the loading file to indicate
     90you are loading firmware. You then write the firmware into the data file,
     91and you notify the kernel the firmware is ready by echo'ing 0 onto
     92the loading file.
     93
     94The firmware device used to help load firmware using sysfs is only created if
     95direct firmware loading fails and if the fallback mechanism is enabled for your
     96firmware request, this is set up with :c:func:`firmware_fallback_sysfs`. It is
     97important to re-iterate that no device is created if a direct filesystem lookup
     98succeeded.
     99
    100Using::
    101
    102        echo 1 > /sys/$DEVPATH/loading
    103
    104Will clean any previous partial load at once and make the firmware API
    105return an error. When loading firmware the firmware_class grows a buffer
    106for the firmware in PAGE_SIZE increments to hold the image as it comes in.
    107
    108firmware_data_read() and firmware_loading_show() are just provided for the
    109test_firmware driver for testing, they are not called in normal use or
    110expected to be used regularly by userspace.
    111
    112firmware_fallback_sysfs
    113-----------------------
    114.. kernel-doc:: drivers/base/firmware_loader/fallback.c
    115   :functions: firmware_fallback_sysfs
    116
    117Firmware kobject uevent fallback mechanism
    118==========================================
    119
    120Since a device is created for the sysfs interface to help load firmware as a
    121fallback mechanism userspace can be informed of the addition of the device by
    122relying on kobject uevents. The addition of the device into the device
    123hierarchy means the fallback mechanism for firmware loading has been initiated.
    124For details of implementation refer to fw_load_sysfs_fallback(), in particular
    125on the use of dev_set_uevent_suppress() and kobject_uevent().
    126
    127The kernel's kobject uevent mechanism is implemented in lib/kobject_uevent.c,
    128it issues uevents to userspace. As a supplement to kobject uevents Linux
    129distributions could also enable CONFIG_UEVENT_HELPER_PATH, which makes use of
    130core kernel's usermode helper (UMH) functionality to call out to a userspace
    131helper for kobject uevents. In practice though no standard distribution has
    132ever used the CONFIG_UEVENT_HELPER_PATH. If CONFIG_UEVENT_HELPER_PATH is
    133enabled this binary would be called each time kobject_uevent_env() gets called
    134in the kernel for each kobject uevent triggered.
    135
    136Different implementations have been supported in userspace to take advantage of
    137this fallback mechanism. When firmware loading was only possible using the
    138sysfs mechanism the userspace component "hotplug" provided the functionality of
    139monitoring for kobject events. Historically this was superseded be systemd's
    140udev, however firmware loading support was removed from udev as of systemd
    141commit be2ea723b1d0 ("udev: remove userspace firmware loading support")
    142as of v217 on August, 2014. This means most Linux distributions today are
    143not using or taking advantage of the firmware fallback mechanism provided
    144by kobject uevents. This is specially exacerbated due to the fact that most
    145distributions today disable CONFIG_FW_LOADER_USER_HELPER_FALLBACK.
    146
    147Refer to do_firmware_uevent() for details of the kobject event variables
    148setup. The variables currently passed to userspace with a "kobject add"
    149event are:
    150
    151* FIRMWARE=firmware name
    152* TIMEOUT=timeout value
    153* ASYNC=whether or not the API request was asynchronous
    154
    155By default DEVPATH is set by the internal kernel kobject infrastructure.
    156Below is an example simple kobject uevent script::
    157
    158        # Both $DEVPATH and $FIRMWARE are already provided in the environment.
    159        MY_FW_DIR=/lib/firmware/
    160        echo 1 > /sys/$DEVPATH/loading
    161        cat $MY_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
    162        echo 0 > /sys/$DEVPATH/loading
    163
    164Firmware custom fallback mechanism
    165==================================
    166
    167Users of the request_firmware_nowait() call have yet another option available
    168at their disposal: rely on the sysfs fallback mechanism but request that no
    169kobject uevents be issued to userspace. The original logic behind this
    170was that utilities other than udev might be required to lookup firmware
    171in non-traditional paths -- paths outside of the listing documented in the
    172section 'Direct filesystem lookup'. This option is not available to any of
    173the other API calls as uevents are always forced for them.
    174
    175Since uevents are only meaningful if the fallback mechanism is enabled
    176in your kernel it would seem odd to enable uevents with kernels that do not
    177have the fallback mechanism enabled in their kernels. Unfortunately we also
    178rely on the uevent flag which can be disabled by request_firmware_nowait() to
    179also setup the firmware cache for firmware requests. As documented above,
    180the firmware cache is only set up if uevent is enabled for an API call.
    181Although this can disable the firmware cache for request_firmware_nowait()
    182calls, users of this API should not use it for the purposes of disabling
    183the cache as that was not the original purpose of the flag. Not setting
    184the uevent flag means you want to opt-in for the firmware fallback mechanism
    185but you want to suppress kobject uevents, as you have a custom solution which
    186will monitor for your device addition into the device hierarchy somehow and
    187load firmware for you through a custom path.
    188
    189Firmware fallback timeout
    190=========================
    191
    192The firmware fallback mechanism has a timeout. If firmware is not loaded
    193onto the sysfs interface by the timeout value an error is sent to the
    194driver. By default the timeout is set to 60 seconds if uevents are
    195desirable, otherwise MAX_JIFFY_OFFSET is used (max timeout possible).
    196The logic behind using MAX_JIFFY_OFFSET for non-uevents is that a custom
    197solution will have as much time as it needs to load firmware.
    198
    199You can customize the firmware timeout by echo'ing your desired timeout into
    200the following file:
    201
    202* /sys/class/firmware/timeout
    203
    204If you echo 0 into it means MAX_JIFFY_OFFSET will be used. The data type
    205for the timeout is an int.
    206
    207EFI embedded firmware fallback mechanism
    208========================================
    209
    210On some devices the system's EFI code / ROM may contain an embedded copy
    211of firmware for some of the system's integrated peripheral devices and
    212the peripheral's Linux device-driver needs to access this firmware.
    213
    214Device drivers which need such firmware can use the
    215firmware_request_platform() function for this, note that this is a
    216separate fallback mechanism from the other fallback mechanisms and
    217this does not use the sysfs interface.
    218
    219A device driver which needs this can describe the firmware it needs
    220using an efi_embedded_fw_desc struct:
    221
    222.. kernel-doc:: include/linux/efi_embedded_fw.h
    223   :functions: efi_embedded_fw_desc
    224
    225The EFI embedded-fw code works by scanning all EFI_BOOT_SERVICES_CODE memory
    226segments for an eight byte sequence matching prefix; if the prefix is found it
    227then does a sha256 over length bytes and if that matches makes a copy of length
    228bytes and adds that to its list with found firmwares.
    229
    230To avoid doing this somewhat expensive scan on all systems, dmi matching is
    231used. Drivers are expected to export a dmi_system_id array, with each entries'
    232driver_data pointing to an efi_embedded_fw_desc.
    233
    234To register this array with the efi-embedded-fw code, a driver needs to:
    235
    2361. Always be builtin to the kernel or store the dmi_system_id array in a
    237   separate object file which always gets builtin.
    238
    2392. Add an extern declaration for the dmi_system_id array to
    240   include/linux/efi_embedded_fw.h.
    241
    2423. Add the dmi_system_id array to the embedded_fw_table in
    243   drivers/firmware/efi/embedded-firmware.c wrapped in a #ifdef testing that
    244   the driver is being builtin.
    245
    2464. Add "select EFI_EMBEDDED_FIRMWARE if EFI_STUB" to its Kconfig entry.
    247
    248The firmware_request_platform() function will always first try to load firmware
    249with the specified name directly from the disk, so the EFI embedded-fw can
    250always be overridden by placing a file under /lib/firmware.
    251
    252Note that:
    253
    2541. The code scanning for EFI embedded-firmware runs near the end
    255   of start_kernel(), just before calling rest_init(). For normal drivers and
    256   subsystems using subsys_initcall() to register themselves this does not
    257   matter. This means that code running earlier cannot use EFI
    258   embedded-firmware.
    259
    2602. At the moment the EFI embedded-fw code assumes that firmwares always start at
    261   an offset which is a multiple of 8 bytes, if this is not true for your case
    262   send in a patch to fix this.
    263
    2643. At the moment the EFI embedded-fw code only works on x86 because other archs
    265   free EFI_BOOT_SERVICES_CODE before the EFI embedded-fw code gets a chance to
    266   scan it.
    267
    2684. The current brute-force scanning of EFI_BOOT_SERVICES_CODE is an ad-hoc
    269   brute-force solution. There has been discussion to use the UEFI Platform
    270   Initialization (PI) spec's Firmware Volume protocol. This has been rejected
    271   because the FV Protocol relies on *internal* interfaces of the PI spec, and:
    272   1. The PI spec does not define peripheral firmware at all
    273   2. The internal interfaces of the PI spec do not guarantee any backward
    274   compatibility. Any implementation details in FV may be subject to change,
    275   and may vary system to system. Supporting the FV Protocol would be
    276   difficult as it is purposely ambiguous.
    277
    278Example how to check for and extract embedded firmware
    279------------------------------------------------------
    280
    281To check for, for example Silead touchscreen controller embedded firmware,
    282do the following:
    283
    2841. Boot the system with efi=debug on the kernel commandline
    285
    2862. cp /sys/kernel/debug/efi/boot_services_code? to your home dir
    287
    2883. Open the boot_services_code? files in a hex-editor, search for the
    289   magic prefix for Silead firmware: F0 00 00 00 02 00 00 00, this gives you
    290   the beginning address of the firmware inside the boot_services_code? file.
    291
    2924. The firmware has a specific pattern, it starts with a 8 byte page-address,
    293   typically F0 00 00 00 02 00 00 00 for the first page followed by 32-bit
    294   word-address + 32-bit value pairs. With the word-address incrementing 4
    295   bytes (1 word) for each pair until a page is complete. A complete page is
    296   followed by a new page-address, followed by more word + value pairs. This
    297   leads to a very distinct pattern. Scroll down until this pattern stops,
    298   this gives you the end of the firmware inside the boot_services_code? file.
    299
    3005. "dd if=boot_services_code? of=firmware bs=1 skip=<begin-addr> count=<len>"
    301   will extract the firmware for you. Inspect the firmware file in a
    302   hexeditor to make sure you got the dd parameters correct.
    303
    3046. Copy it to /lib/firmware under the expected name to test it.
    305
    3067. If the extracted firmware works, you can use the found info to fill an
    307   efi_embedded_fw_desc struct to describe it, run "sha256sum firmware"
    308   to get the sha256sum to put in the sha256 field.