Another moderately busy cycle for documentation, including:

- The minimum Sphinx requirement has been raised to 2.4.4, following a
   warning that was added in 6.2.
 
 - Some reworking of the Documentation/process front page to, hopefully,
   make it more useful.
 
 - Various kernel-doc tweaks to, for example, make it deal properly with
   __counted_by annotations.
 
 - We have also restored a warning for documentation of nonexistent
   structure members that disappeared a while back.  That had the delightful
   consequence of adding some 600 warnings to the docs build.  A sustained
   effort by Randy, Vegard, and myself has addressed almost all of those,
   bringing the documentation back into sync with the code.  The fixes are
   going through the appropriate maintainer trees.
 
 - Various improvements to the HTML rendered docs, including automatic links
   to Git revisions and a nice new pulldown to make translations easy to
   access.
 
 - Speaking of translations, more of those for Spanish and Chinese.
 
 ...plus the usual stream of documentation updates and typo fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQFDBAABCAAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAmWcRKMPHGNvcmJldEBs
 d24ubmV0AAoJEBdDWhNsDH5YTKIH/AxBt/3iWt40dPf18arZHLU6tdUbmg01ttef
 CNKWkniCmABGKc//KYDXvjZMRDt0YlrS0KgUzrb8nIQTBlZG40D+88EwjXE0HeGP
 xt1Fk7OPOiJEqBZ3HEe0PDVfOiA+4yR6CmDKklCJuKg77X9atklneBwPUw/cOASk
 CWj+BdbwPBiSNQv48Lp87rGusKwnH/g0MN2uS0z9MPr1DYjM1K8+ngZjGW24lZHt
 qs5yhP43mlZGBF/lwNJXQp/xhnKAqJ9XwylBX9Wmaoxaz9yyzNVsADGvROMudgzi
 9YB+Jdy7Z0JSrVoLIRhUuDOv7aW8vk+8qLmGJt2aTIsqehbQ6pk=
 =fCtT
 -----END PGP SIGNATURE-----

Merge tag 'docs-6.8' of git://git.lwn.net/linux

Pull documentation update from Jonathan Corbet:
 "Another moderately busy cycle for documentation, including:

   - The minimum Sphinx requirement has been raised to 2.4.4, following
     a warning that was added in 6.2

   - Some reworking of the Documentation/process front page to,
     hopefully, make it more useful

   - Various kernel-doc tweaks to, for example, make it deal properly
     with __counted_by annotations

   - We have also restored a warning for documentation of nonexistent
     structure members that disappeared a while back. That had the
     delightful consequence of adding some 600 warnings to the docs
     build. A sustained effort by Randy, Vegard, and myself has
     addressed almost all of those, bringing the documentation back into
     sync with the code. The fixes are going through the appropriate
     maintainer trees

   - Various improvements to the HTML rendered docs, including automatic
     links to Git revisions and a nice new pulldown to make translations
     easy to access

   - Speaking of translations, more of those for Spanish and Chinese

  ... plus the usual stream of documentation updates and typo fixes"

* tag 'docs-6.8' of git://git.lwn.net/linux: (57 commits)
  MAINTAINERS: use tabs for indent of CONFIDENTIAL COMPUTING THREAT MODEL
  A reworked process/index.rst
  ring-buffer/Documentation: Add documentation on buffer_percent file
  Translated the RISC-V architecture boot documentation.
  Docs: remove mentions of fdformat from util-linux
  Docs/zh_CN: Fix the meaning of DEBUG to pr_debug()
  Documentation: move driver-api/dcdbas to userspace-api/
  Documentation: move driver-api/isapnp to userspace-api/
  Documentation/core-api : fix typo in workqueue
  Documentation/trace: Fixed typos in the ftrace FLAGS section
  kernel-doc: handle a void function without producing a warning
  scripts/get_abi.pl: ignore some temp files
  docs: kernel_abi.py: fix command injection
  scripts/get_abi: fix source path leak
  CREDITS, MAINTAINERS, docs/process/howto: Update man-pages' maintainer
  docs: translations: add translations links when they exist
  kernel-doc: Align quick help and the code
  MAINTAINERS: add reviewer for Spanish translations
  docs: ignore __counted_by attribute in structure definitions
  scripts: kernel-doc: Clarify missing struct member description
  ..
This commit is contained in:
Linus Torvalds 2024-01-11 19:46:52 -08:00
commit 5b9b41617b
153 changed files with 3215 additions and 803 deletions

View File

@ -1835,6 +1835,13 @@ S: K osmidomkum 723
S: 160 00 Praha 6 S: 160 00 Praha 6
S: Czech Republic S: Czech Republic
N: Michael Kerrisk
E: mtk.manpages@gmail.com
W: https://man7.org/
P: 4096R/3A35CE5E E522 595B 52ED A4E6 BFCC CB5E 8561 9911 3A35 CE5E
D: Maintainer of the Linux man-pages project
D: Linux man pages online, at <https://man7.org/linux/man-pages/>
N: Niels Kristian Bech Jensen N: Niels Kristian Bech Jensen
E: nkbj1970@hotmail.com E: nkbj1970@hotmail.com
D: Miscellaneous kernel updates and fixes. D: Miscellaneous kernel updates and fixes.

View File

@ -7,5 +7,5 @@ marked to be removed at some later point in time.
The description of the interface will document the reason why it is The description of the interface will document the reason why it is
obsolete and when it can be expected to be removed. obsolete and when it can be expected to be removed.
.. kernel-abi:: $srctree/Documentation/ABI/obsolete .. kernel-abi:: ABI/obsolete
:rst: :rst:

View File

@ -1,5 +1,5 @@
ABI removed symbols ABI removed symbols
=================== ===================
.. kernel-abi:: $srctree/Documentation/ABI/removed .. kernel-abi:: ABI/removed
:rst: :rst:

View File

@ -10,5 +10,5 @@ for at least 2 years.
Most interfaces (like syscalls) are expected to never change and always Most interfaces (like syscalls) are expected to never change and always
be available. be available.
.. kernel-abi:: $srctree/Documentation/ABI/stable .. kernel-abi:: ABI/stable
:rst: :rst:

View File

@ -16,5 +16,5 @@ Programs that use these interfaces are strongly encouraged to add their
name to the description of these interfaces, so that the kernel name to the description of these interfaces, so that the kernel
developers can easily notify them if any changes occur. developers can easily notify them if any changes occur.
.. kernel-abi:: $srctree/Documentation/ABI/testing .. kernel-abi:: ABI/testing
:rst: :rst:

View File

@ -321,13 +321,13 @@ Examples
:#> ddcmd 'format "nfsd: READ" +p' :#> ddcmd 'format "nfsd: READ" +p'
// enable messages in files of which the paths include string "usb" // enable messages in files of which the paths include string "usb"
:#> ddcmd 'file *usb* +p' > /proc/dynamic_debug/control :#> ddcmd 'file *usb* +p'
// enable all messages // enable all messages
:#> ddcmd '+p' > /proc/dynamic_debug/control :#> ddcmd '+p'
// add module, function to all enabled messages // add module, function to all enabled messages
:#> ddcmd '+mf' > /proc/dynamic_debug/control :#> ddcmd '+mf'
// boot-args example, with newlines and comments for readability // boot-args example, with newlines and comments for readability
Kernel command line: ... Kernel command line: ...

View File

@ -1,3 +1,14 @@
accept_memory= [MM]
Format: { eager | lazy }
default: lazy
By default, unaccepted memory is accepted lazily to
avoid prolonged boot times. The lazy option will add
some runtime overhead until all memory is eventually
accepted. In most cases the overhead is negligible.
For some workloads or for debugging purposes
accept_memory=eager can be used to accept all memory
at once during boot.
acpi= [HW,ACPI,X86,ARM64,RISCV64] acpi= [HW,ACPI,X86,ARM64,RISCV64]
Advanced Configuration and Power Interface Advanced Configuration and Power Interface
Format: { force | on | off | strict | noirq | rsdt | Format: { force | on | off | strict | noirq | rsdt |

View File

@ -20,16 +20,8 @@ Documentation/driver-api/media/index.rst
- for driver development information and Kernel APIs used by - for driver development information and Kernel APIs used by
media devices; media devices;
The media subsystem
===================
.. only:: html
.. class:: toc-title
Table of Contents
.. toctree:: .. toctree::
:caption: Table of Contents
:maxdepth: 2 :maxdepth: 2
:numbered: :numbered:

View File

@ -71,7 +71,7 @@ Protocol 2.13 (Kernel 3.14) Support 32- and 64-bit flags being set in
Protocol 2.14 BURNT BY INCORRECT COMMIT Protocol 2.14 BURNT BY INCORRECT COMMIT
ae7e1238e68f2a472a125673ab506d49158c1889 ae7e1238e68f2a472a125673ab506d49158c1889
(x86/boot: Add ACPI RSDP address to setup_header) ("x86/boot: Add ACPI RSDP address to setup_header")
DO NOT USE!!! ASSUME SAME AS 2.13. DO NOT USE!!! ASSUME SAME AS 2.13.
Protocol 2.15 (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max. Protocol 2.15 (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max.

View File

@ -272,10 +272,8 @@ In this case, if the base type is an int type, it must be a regular int type:
* ``BTF_INT_OFFSET()`` must be 0. * ``BTF_INT_OFFSET()`` must be 0.
* ``BTF_INT_BITS()`` must be equal to ``{1,2,4,8,16} * 8``. * ``BTF_INT_BITS()`` must be equal to ``{1,2,4,8,16} * 8``.
The following kernel patch introduced ``kind_flag`` and explained why both Commit 9d5f9f701b18 introduced ``kind_flag`` and explains why both modes
modes exist: exist.
https://github.com/torvalds/linux/commit/9d5f9f701b1891466fb3dbb1806ad97716f95cc3#diff-fa650a64fdd3968396883d2fe8215ff3
2.2.6 BTF_KIND_ENUM 2.2.6 BTF_KIND_ENUM
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~

View File

@ -47,7 +47,7 @@ from load_config import loadConfig
# -- General configuration ------------------------------------------------ # -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here. # If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.7' needs_sphinx = '2.4.4'
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@ -55,7 +55,7 @@ needs_sphinx = '1.7'
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include',
'kfigure', 'sphinx.ext.ifconfig', 'automarkup', 'kfigure', 'sphinx.ext.ifconfig', 'automarkup',
'maintainers_include', 'sphinx.ext.autosectionlabel', 'maintainers_include', 'sphinx.ext.autosectionlabel',
'kernel_abi', 'kernel_feat'] 'kernel_abi', 'kernel_feat', 'translations']
if major >= 3: if major >= 3:
if (major > 3) or (minor > 0 or patch >= 2): if (major > 3) or (minor > 0 or patch >= 2):
@ -106,6 +106,7 @@ if major >= 3:
"__weak", "__weak",
"noinline", "noinline",
"__fix_address", "__fix_address",
"__counted_by",
# include/linux/memblock.h: # include/linux/memblock.h:
"__init_memblock", "__init_memblock",
@ -357,6 +358,10 @@ html_sidebars = { '**': ['searchbox.html', 'kernel-toc.html', 'sourcelink.html']
if html_theme == 'alabaster': if html_theme == 'alabaster':
html_sidebars['**'].insert(0, 'about.html') html_sidebars['**'].insert(0, 'about.html')
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = 'images/logo.svg'
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = 'TheLinuxKerneldoc' htmlhelp_basename = 'TheLinuxKerneldoc'

View File

@ -8,7 +8,7 @@ Dynamic DMA mapping Guide
This is a guide to device driver writers on how to use the DMA API This is a guide to device driver writers on how to use the DMA API
with example pseudo-code. For a concise description of the API, see with example pseudo-code. For a concise description of the API, see
DMA-API.txt. Documentation/core-api/dma-api.rst.
CPU and DMA addresses CPU and DMA addresses
===================== =====================

View File

@ -448,7 +448,7 @@ DMA address entries returned.
Synchronise a single contiguous or scatter/gather mapping for the CPU Synchronise a single contiguous or scatter/gather mapping for the CPU
and device. With the sync_sg API, all the parameters must be the same and device. With the sync_sg API, all the parameters must be the same
as those passed into the single mapping API. With the sync_single API, as those passed into the sg mapping API. With the sync_single API,
you can use dma_handle and size parameters that aren't identical to you can use dma_handle and size parameters that aren't identical to
those passed into the single mapping API to do a partial sync. those passed into the single mapping API to do a partial sync.

View File

@ -379,7 +379,7 @@ Workqueue currently supports the following affinity scopes.
cases. This is the default affinity scope. cases. This is the default affinity scope.
``numa`` ``numa``
CPUs are grouped according to NUMA bounaries. CPUs are grouped according to NUMA boundaries.
``system`` ``system``
All CPUs are put in the same group. Workqueue makes no effort to process a All CPUs are put in the same group. Workqueue makes no effort to process a

View File

@ -1,11 +1,8 @@
Programming Interface Programming Interface
===================== =====================
.. class:: toc-title
Table of contents
.. toctree:: .. toctree::
:caption: Table of contents
:maxdepth: 2 :maxdepth: 2
api-skcipher api-skcipher

View File

@ -9,11 +9,8 @@ This documentation outlines the Linux kernel crypto API with its
concepts, details about developing cipher implementations, employment of the API concepts, details about developing cipher implementations, employment of the API
for cryptographic use cases, as well as programming examples. for cryptographic use cases, as well as programming examples.
.. class:: toc-title
Table of contents
.. toctree:: .. toctree::
:caption: Table of contents
:maxdepth: 2 :maxdepth: 2
intro intro

View File

@ -10,11 +10,8 @@ whole; patches welcome!
A brief overview of testing-specific tools can be found in A brief overview of testing-specific tools can be found in
Documentation/dev-tools/testing-overview.rst Documentation/dev-tools/testing-overview.rst
.. class:: toc-title
Table of contents
.. toctree:: .. toctree::
:caption: Table of contents
:maxdepth: 2 :maxdepth: 2
testing-overview testing-overview

View File

@ -28,7 +28,7 @@ Sphinx Install
============== ==============
The ReST markups currently used by the Documentation/ files are meant to be The ReST markups currently used by the Documentation/ files are meant to be
built with ``Sphinx`` version 1.7 or higher. built with ``Sphinx`` version 2.4.4 or higher.
There's a script that checks for the Sphinx requirements. Please see There's a script that checks for the Sphinx requirements. Please see
:ref:`sphinx-pre-install` for further details. :ref:`sphinx-pre-install` for further details.
@ -435,6 +435,15 @@ path.
For information on cross-referencing to kernel-doc functions or types, see For information on cross-referencing to kernel-doc functions or types, see
Documentation/doc-guide/kernel-doc.rst. Documentation/doc-guide/kernel-doc.rst.
Referencing commits
~~~~~~~~~~~~~~~~~~~
References to git commits are automatically hyperlinked given that they are
written in one of these formats::
commit 72bf4f1767f0
commit 72bf4f1767f0 ("net: do not leave an empty skb in write queue")
.. _sphinx_kfigure: .. _sphinx_kfigure:
Figures & Images Figures & Images

View File

@ -9,11 +9,8 @@ of device drivers. This document is an only somewhat organized collection
of some of those interfaces — it will hopefully get better over time! The of some of those interfaces — it will hopefully get better over time! The
available subsections can be seen below. available subsections can be seen below.
.. class:: toc-title
Table of contents
.. toctree:: .. toctree::
:caption: Table of contents
:maxdepth: 2 :maxdepth: 2
driver-model/index driver-model/index
@ -81,10 +78,8 @@ available subsections can be seen below.
backlight/lp855x-driver.rst backlight/lp855x-driver.rst
connector connector
console console
dcdbas
eisa eisa
isa isa
isapnp
io-mapping io-mapping
io_ordering io_ordering
generic-counter generic-counter
@ -117,6 +112,7 @@ available subsections can be seen below.
dpll dpll
wbrf wbrf
crypto/index crypto/index
tee
.. only:: subproject and html .. only:: subproject and html

View File

@ -20,13 +20,8 @@ Documentation/userspace-api/media/index.rst
- for the userspace APIs used on media devices. - for the userspace APIs used on media devices.
.. only:: html
.. class:: toc-title
Table of Contents
.. toctree:: .. toctree::
:caption: Table of Contents
:maxdepth: 5 :maxdepth: 5
:numbered: :numbered:

View File

@ -9,13 +9,8 @@ Intel(R) Management Engine Interface (Intel(R) MEI)
**Copyright** |copy| 2019 Intel Corporation **Copyright** |copy| 2019 Intel Corporation
.. only:: html
.. class:: toc-title
Table of Contents
.. toctree:: .. toctree::
:caption: Table of Contents
:maxdepth: 3 :maxdepth: 3
mei mei

View File

@ -41,7 +41,7 @@ A NVMEM provider can register with NVMEM core by supplying relevant
nvmem configuration to nvmem_register(), on success core would return a valid nvmem configuration to nvmem_register(), on success core would return a valid
nvmem_device pointer. nvmem_device pointer.
nvmem_unregister(nvmem) is used to unregister a previously registered provider. nvmem_unregister() is used to unregister a previously registered provider.
For example, a simple nvram case:: For example, a simple nvram case::
@ -200,3 +200,9 @@ and let you add cells dynamically.
Another use case for layouts is the post processing of cells. With layouts, Another use case for layouts is the post processing of cells. With layouts,
it is possible to associate a custom post processing hook to a cell. It it is possible to associate a custom post processing hook to a cell. It
even possible to add this hook to cells not created by the layout itself. even possible to add this hook to cells not created by the layout itself.
9. Internal kernel API
======================
.. kernel-doc:: drivers/nvmem/core.c
:export:

View File

@ -4,11 +4,8 @@
The Linux PCI driver implementer's API guide The Linux PCI driver implementer's API guide
============================================ ============================================
.. class:: toc-title
Table of contents
.. toctree:: .. toctree::
:caption: Table of contents
:maxdepth: 2 :maxdepth: 2
pci pci

View File

@ -0,0 +1,66 @@
.. SPDX-License-Identifier: GPL-2.0
===============================================
TEE (Trusted Execution Environment) driver API
===============================================
Kernel provides a TEE bus infrastructure where a Trusted Application is
represented as a device identified via Universally Unique Identifier (UUID) and
client drivers register a table of supported device UUIDs.
TEE bus infrastructure registers following APIs:
match():
iterates over the client driver UUID table to find a corresponding
match for device UUID. If a match is found, then this particular device is
probed via corresponding probe API registered by the client driver. This
process happens whenever a device or a client driver is registered with TEE
bus.
uevent():
notifies user-space (udev) whenever a new device is registered on
TEE bus for auto-loading of modularized client drivers.
TEE bus device enumeration is specific to underlying TEE implementation, so it
is left open for TEE drivers to provide corresponding implementation.
Then TEE client driver can talk to a matched Trusted Application using APIs
listed in include/linux/tee_drv.h.
TEE client driver example
-------------------------
Suppose a TEE client driver needs to communicate with a Trusted Application
having UUID: ``ac6a4085-0e82-4c33-bf98-8eb8e118b6c2``, so driver registration
snippet would look like::
static const struct tee_client_device_id client_id_table[] = {
{UUID_INIT(0xac6a4085, 0x0e82, 0x4c33,
0xbf, 0x98, 0x8e, 0xb8, 0xe1, 0x18, 0xb6, 0xc2)},
{}
};
MODULE_DEVICE_TABLE(tee, client_id_table);
static struct tee_client_driver client_driver = {
.id_table = client_id_table,
.driver = {
.name = DRIVER_NAME,
.bus = &tee_bus_type,
.probe = client_probe,
.remove = client_remove,
},
};
static int __init client_init(void)
{
return driver_register(&client_driver.driver);
}
static void __exit client_exit(void)
{
driver_unregister(&client_driver.driver);
}
module_init(client_init);
module_exit(client_exit);

View File

@ -437,7 +437,7 @@ field. This is a pointer to a "struct inode_operations" which describes
the methods that can be performed on individual inodes. the methods that can be performed on individual inodes.
struct xattr_handlers struct xattr_handler
--------------------- ---------------------
On filesystems that support extended attributes (xattrs), the s_xattr On filesystems that support extended attributes (xattrs), the s_xattr

View File

@ -4,11 +4,8 @@
Linux Input Subsystem kernel API Linux Input Subsystem kernel API
################################ ################################
.. class:: toc-title
Table of Contents
.. toctree:: .. toctree::
:caption: Table of Contents
:maxdepth: 2 :maxdepth: 2
:numbered: :numbered:

View File

@ -4,11 +4,8 @@
Linux Input Subsystem userspace API Linux Input Subsystem userspace API
################################### ###################################
.. class:: toc-title
Table of Contents
.. toctree:: .. toctree::
:caption: Table of Contents
:maxdepth: 2 :maxdepth: 2
:numbered: :numbered:

View File

@ -6,11 +6,8 @@ Linux Joystick support
:Copyright: |copy| 1996-2000 Vojtech Pavlik <vojtech@ucw.cz> - Sponsored by SuSE :Copyright: |copy| 1996-2000 Vojtech Pavlik <vojtech@ucw.cz> - Sponsored by SuSE
.. class:: toc-title
Table of Contents
.. toctree:: .. toctree::
:caption: Table of Contents
:maxdepth: 3 :maxdepth: 3
joystick joystick

View File

@ -110,7 +110,7 @@ Global data update
------------------ ------------------
A pre-patch callback can be useful to update a global variable. For A pre-patch callback can be useful to update a global variable. For
example, 75ff39ccc1bd ("tcp: make challenge acks less predictable") example, commit 75ff39ccc1bd ("tcp: make challenge acks less predictable")
changes a global sysctl, as well as patches the tcp_send_challenge_ack() changes a global sysctl, as well as patches the tcp_send_challenge_ack()
function. function.
@ -126,7 +126,7 @@ Although __init and probe functions are not directly livepatch-able, it
may be possible to implement similar updates via pre/post-patch may be possible to implement similar updates via pre/post-patch
callbacks. callbacks.
The commit ``48900cb6af42 ("virtio-net: drop NETIF_F_FRAGLIST")`` change the way that The commit 48900cb6af42 ("virtio-net: drop NETIF_F_FRAGLIST") change the way that
virtnet_probe() initialized its driver's net_device features. A virtnet_probe() initialized its driver's net_device features. A
pre/post-patch callback could iterate over all such devices, making a pre/post-patch callback could iterate over all such devices, making a
similar change to their hw_features value. (Client functions of the similar change to their hw_features value. (Client functions of the

View File

@ -7,11 +7,8 @@ Assorted Miscellaneous Devices Documentation
This documentation contains information for assorted devices that do not This documentation contains information for assorted devices that do not
fit into other categories. fit into other categories.
.. class:: toc-title
Table of contents
.. toctree:: .. toctree::
:caption: Table of contents
:maxdepth: 2 :maxdepth: 2
ad525x_dpot ad525x_dpot

View File

@ -313,7 +313,7 @@ https://lwn.net/Articles/576263/
* TcpExtTCPOrigDataSent * TcpExtTCPOrigDataSent
This counter is explained by `kernel commit f19c29e3e391`_, I pasted the This counter is explained by kernel commit f19c29e3e391, I pasted the
explanation below:: explanation below::
TCPOrigDataSent: number of outgoing packets with original data (excluding TCPOrigDataSent: number of outgoing packets with original data (excluding
@ -323,7 +323,7 @@ explanation below::
* TCPSynRetrans * TCPSynRetrans
This counter is explained by `kernel commit f19c29e3e391`_, I pasted the This counter is explained by kernel commit f19c29e3e391, I pasted the
explanation below:: explanation below::
TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down
@ -331,14 +331,12 @@ explanation below::
* TCPFastOpenActiveFail * TCPFastOpenActiveFail
This counter is explained by `kernel commit f19c29e3e391`_, I pasted the This counter is explained by kernel commit f19c29e3e391, I pasted the
explanation below:: explanation below::
TCPFastOpenActiveFail: Fast Open attempts (SYN/data) failed because TCPFastOpenActiveFail: Fast Open attempts (SYN/data) failed because
the remote does not accept it or the attempts timed out. the remote does not accept it or the attempts timed out.
.. _kernel commit f19c29e3e391: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f19c29e3e391a66a273e9afebaf01917245148cd
* TcpExtListenOverflows and TcpExtListenDrops * TcpExtListenOverflows and TcpExtListenDrops
When kernel receives a SYN from a client, and if the TCP accept queue When kernel receives a SYN from a client, and if the TCP accept queue
@ -698,11 +696,9 @@ number of the SACK block. For more details, please refer the comment
of the function tcp_is_sackblock_valid in the kernel source code. A of the function tcp_is_sackblock_valid in the kernel source code. A
SACK option could have up to 4 blocks, they are checked SACK option could have up to 4 blocks, they are checked
individually. E.g., if 3 blocks of a SACk is invalid, the individually. E.g., if 3 blocks of a SACk is invalid, the
corresponding counter would be updated 3 times. The comment of the corresponding counter would be updated 3 times. The comment of commit
`Add counters for discarded SACK blocks`_ patch has additional 18f02545a9a1 ("[TCP] MIB: Add counters for discarded SACK blocks")
explanation: has additional explanation:
.. _Add counters for discarded SACK blocks: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=18f02545a9a16c9a89778b91a162ad16d510bb32
* TcpExtTCPSACKDiscard * TcpExtTCPSACKDiscard

View File

@ -39,7 +39,7 @@ binutils 2.25 ld -v
flex 2.5.35 flex --version flex 2.5.35 flex --version
bison 2.0 bison --version bison 2.0 bison --version
pahole 1.16 pahole --version pahole 1.16 pahole --version
util-linux 2.10o fdformat --version util-linux 2.10o mount --version
kmod 13 depmod -V kmod 13 depmod -V
e2fsprogs 1.41.4 e2fsck -V e2fsprogs 1.41.4 e2fsck -V
jfsutils 1.1.3 fsck.jfs -V jfsutils 1.1.3 fsck.jfs -V
@ -58,7 +58,7 @@ mcelog 0.6 mcelog --version
iptables 1.4.2 iptables -V iptables 1.4.2 iptables -V
openssl & libcrypto 1.0.0 openssl version openssl & libcrypto 1.0.0 openssl version
bc 1.06.95 bc --version bc 1.06.95 bc --version
Sphinx\ [#f1]_ 1.7 sphinx-build --version Sphinx\ [#f1]_ 2.4.4 sphinx-build --version
cpio any cpio --version cpio any cpio --version
GNU tar 1.28 tar --version GNU tar 1.28 tar --version
gtags (optional) 6.6.5 gtags --version gtags (optional) 6.6.5 gtags --version
@ -213,7 +213,7 @@ Util-linux
New versions of util-linux provide ``fdisk`` support for larger disks, New versions of util-linux provide ``fdisk`` support for larger disks,
support new options to mount, recognize more supported partition support new options to mount, recognize more supported partition
types, have a fdformat which works with 2.4 kernels, and similar goodies. types, and similar goodies.
You'll probably want to upgrade. You'll probably want to upgrade.
Ksymoops Ksymoops

View File

@ -3,9 +3,17 @@
A guide to the Kernel Development Process A guide to the Kernel Development Process
========================================= =========================================
Contents: The purpose of this document is to help developers (and their managers)
work with the development community with a minimum of frustration. It is
an attempt to document how this community works in a way which is
accessible to those who are not intimately familiar with Linux kernel
development (or, indeed, free software development in general). While
there is some technical material here, this is very much a process-oriented
discussion which does not require a deep knowledge of kernel programming to
understand.
.. toctree:: .. toctree::
:caption: Contents
:numbered: :numbered:
:maxdepth: 2 :maxdepth: 2
@ -17,12 +25,3 @@ Contents:
6.Followthrough 6.Followthrough
7.AdvancedTopics 7.AdvancedTopics
8.Conclusion 8.Conclusion
The purpose of this document is to help developers (and their managers)
work with the development community with a minimum of frustration. It is
an attempt to document how this community works in a way which is
accessible to those who are not intimately familiar with Linux kernel
development (or, indeed, free software development in general). While
there is some technical material here, this is very much a process-oriented
discussion which does not require a deep knowledge of kernel programming to
understand.

View File

@ -82,8 +82,7 @@ documentation files are also added which explain how to use the feature.
When a kernel change causes the interface that the kernel exposes to When a kernel change causes the interface that the kernel exposes to
userspace to change, it is recommended that you send the information or userspace to change, it is recommended that you send the information or
a patch to the manual pages explaining the change to the manual pages a patch to the manual pages explaining the change to the manual pages
maintainer at mtk.manpages@gmail.com, and CC the list maintainer at alx@kernel.org, and CC the list linux-api@vger.kernel.org.
linux-api@vger.kernel.org.
Here is a list of files that are in the kernel source tree that are Here is a list of files that are in the kernel source tree that are
required reading: required reading:

View File

@ -15,49 +15,96 @@ to learn about how our community works. Reading these documents will make
it much easier for you to get your changes merged with a minimum of it much easier for you to get your changes merged with a minimum of
trouble. trouble.
Below are the essential guides that every developer should read. An introduction to how kernel development works
-----------------------------------------------
Read these documents first: an understanding of the material here will ease
your entry into the kernel community.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
license-rules
howto howto
code-of-conduct
code-of-conduct-interpretation
development-process development-process
submitting-patches submitting-patches
handling-regressions submit-checklist
programming-language
coding-style
maintainer-handbooks
maintainer-pgp-guide
email-clients
kernel-enforcement-statement
kernel-driver-statement
For security issues, see: Tools and technical guides for kernel developers
------------------------------------------------
.. toctree:: This is a collection of material that kernel developers should be familiar
:maxdepth: 1 with.
security-bugs
embargoed-hardware-issues
Other guides to the community that are of interest to most developers are:
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
changes changes
programming-language
coding-style
maintainer-pgp-guide
email-clients
applying-patches
backporting
adding-syscalls
volatile-considered-harmful
botching-up-ioctls
Policy guides and developer statements
--------------------------------------
These are the rules that we try to live by in the kernel community (and
beyond).
.. toctree::
:maxdepth: 1
license-rules
code-of-conduct
code-of-conduct-interpretation
contribution-maturity-model
kernel-enforcement-statement
kernel-driver-statement
stable-api-nonsense stable-api-nonsense
management-style
stable-kernel-rules stable-kernel-rules
submit-checklist management-style
researcher-guidelines
Dealing with bugs
-----------------
Bugs are a fact of life; it is important that we handle them properly.
The documents below describe our policies around the handling of a couple
of special classes of bugs: regressions and security problems.
.. toctree::
:maxdepth: 1
handling-regressions
security-bugs
embargoed-hardware-issues
Maintainer information
----------------------
How to find the people who will accept your patches.
.. toctree::
:maxdepth: 1
maintainer-handbooks
maintainers
Other material
--------------
Here are some other guides to the community that are of interest to most
developers:
.. toctree::
:maxdepth: 1
kernel-docs kernel-docs
deprecated deprecated
maintainers
researcher-guidelines
contribution-maturity-model
These are some overall technical guides that have been put here for now for These are some overall technical guides that have been put here for now for
lack of a better place. lack of a better place.
@ -65,12 +112,7 @@ lack of a better place.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
applying-patches
backporting
adding-syscalls
magic-number magic-number
volatile-considered-harmful
botching-up-ioctls
clang-format clang-format
../arch/riscv/patch-acceptance ../arch/riscv/patch-acceptance
../core-api/unaligned-memory-access ../core-api/unaligned-memory-access

View File

@ -790,10 +790,14 @@ Providing base tree information
------------------------------- -------------------------------
When other developers receive your patches and start the review process, When other developers receive your patches and start the review process,
it is often useful for them to know where in the tree history they it is absolutely necessary for them to know what is the base
should place your work. This is particularly useful for automated CI commit/branch your work applies on, considering the sheer amount of
processes that attempt to run a series of tests in order to establish maintainer trees present nowadays. Note again the **T:** entry in the
the quality of your submission before the maintainer starts the review. MAINTAINERS file explained above.
This is even more important for automated CI processes that attempt to
run a series of tests in order to establish the quality of your
submission before the maintainer starts the review.
If you are using ``git format-patch`` to generate your patches, you can If you are using ``git format-patch`` to generate your patches, you can
automatically include the base tree information in your submission by automatically include the base tree information in your submission by
@ -836,6 +840,9 @@ letter or in the first patch of the series and it should be placed
either below the ``---`` line or at the very bottom of all other either below the ``---`` line or at the very bottom of all other
content, right before your email signature. content, right before your email signature.
Make sure that base commit is in an official maintainer/mainline tree
and not in some internal, accessible only to you tree - otherwise it
would be worthless.
References References
---------- ----------

View File

@ -88,7 +88,7 @@ safe.
(2) TEE (2) TEE
TEEs have well-documented, standardized client interface and APIs. For TEEs have well-documented, standardized client interface and APIs. For
more details refer to ``Documentation/staging/tee.rst``. more details refer to ``Documentation/driver-api/tee.rst``.
(3) CAAM (3) CAAM

View File

@ -7,6 +7,10 @@
div.body h1 { font-size: 180%; } div.body h1 { font-size: 180%; }
div.body h2 { font-size: 150%; } div.body h2 { font-size: 150%; }
div.body h3 { font-size: 130%; } div.body h3 { font-size: 130%; }
div.body h4 { font-size: 110%; }
/* toctree captions are styled like h2 */
div.toctree-wrapper p.caption[role=heading] { font-size: 150%; }
/* Tighten up the layout slightly */ /* Tighten up the layout slightly */
div.body { padding: 0 15px 0 10px; } div.body { padding: 0 15px 0 10px; }
@ -20,6 +24,12 @@ div.document {
width: auto; width: auto;
} }
/* Size the logo appropriately */
img.logo {
width: 104px;
margin-bottom: 20px;
}
/* /*
* Parameters for the display of function prototypes and such included * Parameters for the display of function prototypes and such included
* from C source files. * from C source files.
@ -73,3 +83,56 @@ input.kernel-toc-toggle { display: none; }
h3.kernel-toc-contents { display: inline; } h3.kernel-toc-contents { display: inline; }
div.kerneltoc a { color: black; } div.kerneltoc a { color: black; }
} }
/* Language selection menu */
div.admonition {
/*
* Make sure we don't overlap notes and warnings at the top of the
* document.
*/
clear: both;
}
div.language-selection {
background: #eeeeee;
border: 1px solid #cccccc;
margin-bottom: 1em;
padding: .5em;
position: relative;
float: right;
}
div.language-selection a {
display: block;
padding: 0.5em;
color: #333333;
text-decoration: none;
}
div.language-selection ul {
display: none;
position: absolute;
/* Align with the parent div */
top: 100%;
right: 0;
margin: 0;
list-style: none;
background: #fafafa;
border: 1px solid #cccccc;
/* Never break menu item lines */
white-space: nowrap;
}
div.language-selection:hover ul {
display: block;
}
div.language-selection ul li:hover {
background: #dddddd;
}

View File

@ -81,11 +81,6 @@ div[class^="highlight"] pre {
* - hide the permalink symbol as long as link is not hovered * - hide the permalink symbol as long as link is not hovered
*/ */
.toc-title {
font-size: 150%;
font-weight: bold;
}
caption, .wy-table caption, .rst-content table.field-list caption { caption, .wy-table caption, .rst-content table.field-list caption {
font-size: 100%; font-size: 100%;
} }

View File

@ -7,11 +7,7 @@
from docutils import nodes from docutils import nodes
import sphinx import sphinx
from sphinx import addnodes from sphinx import addnodes
if sphinx.version_info[0] < 2 or \ from sphinx.errors import NoUri
sphinx.version_info[0] == 2 and sphinx.version_info[1] < 1:
from sphinx.environment import NoUri
else:
from sphinx.errors import NoUri
import re import re
from itertools import chain from itertools import chain
@ -74,6 +70,12 @@ Skipfuncs = [ 'open', 'close', 'read', 'write', 'fcntl', 'mmap',
c_namespace = '' c_namespace = ''
#
# Detect references to commits.
#
RE_git = re.compile(r'commit\s+(?P<rev>[0-9a-f]{12,40})(?:\s+\(".*?"\))?',
flags=re.IGNORECASE | re.DOTALL)
def markup_refs(docname, app, node): def markup_refs(docname, app, node):
t = node.astext() t = node.astext()
done = 0 done = 0
@ -90,7 +92,8 @@ def markup_refs(docname, app, node):
RE_struct: markup_c_ref, RE_struct: markup_c_ref,
RE_union: markup_c_ref, RE_union: markup_c_ref,
RE_enum: markup_c_ref, RE_enum: markup_c_ref,
RE_typedef: markup_c_ref} RE_typedef: markup_c_ref,
RE_git: markup_git}
if sphinx.version_info[0] >= 3: if sphinx.version_info[0] >= 3:
markup_func = markup_func_sphinx3 markup_func = markup_func_sphinx3
@ -276,6 +279,17 @@ def get_c_namespace(app, docname):
return match.group(1) return match.group(1)
return '' return ''
def markup_git(docname, app, match):
# While we could probably assume that we are running in a git
# repository, we can't know for sure, so let's just mechanically
# turn them into git.kernel.org links without checking their
# validity. (Maybe we can do something in the future to warn about
# these references if this is explicitly requested.)
text = match.group(0)
rev = match.group('rev')
return nodes.reference('', nodes.Text(text),
refuri=f'https://git.kernel.org/torvalds/c/{rev}')
def auto_markup(app, doctree, name): def auto_markup(app, doctree, name):
global c_namespace global c_namespace
c_namespace = get_c_namespace(app, name) c_namespace = get_c_namespace(app, name)

View File

@ -127,11 +127,7 @@ def setup(app):
# Handle easy Sphinx 3.1+ simple new tags: :c:expr and .. c:namespace:: # Handle easy Sphinx 3.1+ simple new tags: :c:expr and .. c:namespace::
app.connect('source-read', c_markups) app.connect('source-read', c_markups)
app.add_domain(CDomain, override=True)
if (major == 1 and minor < 8):
app.override_domain(CDomain)
else:
app.add_domain(CDomain, override=True)
return dict( return dict(
version = __version__, version = __version__,

View File

@ -39,8 +39,6 @@ import sys
import re import re
import kernellog import kernellog
from os import path
from docutils import nodes, statemachine from docutils import nodes, statemachine
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive from docutils.parsers.rst import directives, Directive
@ -73,60 +71,26 @@ class KernelCmd(Directive):
} }
def run(self): def run(self):
doc = self.state.document doc = self.state.document
if not doc.settings.file_insertion_enabled: if not doc.settings.file_insertion_enabled:
raise self.warning("docutils: file insertion disabled") raise self.warning("docutils: file insertion disabled")
env = doc.settings.env srctree = os.path.abspath(os.environ["srctree"])
cwd = path.dirname(doc.current_source)
cmd = "get_abi.pl rest --enable-lineno --dir " args = [
cmd += self.arguments[0] os.path.join(srctree, 'scripts/get_abi.pl'),
'rest',
'--enable-lineno',
'--dir', os.path.join(srctree, 'Documentation', self.arguments[0]),
]
if 'rst' in self.options: if 'rst' in self.options:
cmd += " --rst-source" args.append('--rst-source')
srctree = path.abspath(os.environ["srctree"]) lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')
fname = cmd
# extend PATH with $(srctree)/scripts
path_env = os.pathsep.join([
srctree + os.sep + "scripts",
os.environ["PATH"]
])
shell_env = os.environ.copy()
shell_env["PATH"] = path_env
shell_env["srctree"] = srctree
lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
nodeList = self.nestedParse(lines, self.arguments[0]) nodeList = self.nestedParse(lines, self.arguments[0])
return nodeList return nodeList
def runCmd(self, cmd, **kwargs):
u"""Run command ``cmd`` and return its stdout as unicode."""
try:
proc = subprocess.Popen(
cmd
, stdout = subprocess.PIPE
, stderr = subprocess.PIPE
, **kwargs
)
out, err = proc.communicate()
out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8')
if proc.returncode != 0:
raise self.severe(
u"command '%s' failed with return code %d"
% (cmd, proc.returncode)
)
except OSError as exc:
raise self.severe(u"problems with '%s' directive: %s."
% (self.name, ErrorString(exc)))
return out
def nestedParse(self, lines, fname): def nestedParse(self, lines, fname):
env = self.state.document.settings.env env = self.state.document.settings.env
content = ViewList() content = ViewList()

View File

@ -61,13 +61,7 @@ import sphinx
from sphinx.util.nodes import clean_astext from sphinx.util.nodes import clean_astext
import kernellog import kernellog
# Get Sphinx version Figure = images.Figure
major, minor, patch = sphinx.version_info[:3]
if major == 1 and minor > 3:
# patches.Figure only landed in Sphinx 1.4
from sphinx.directives.patches import Figure # pylint: disable=C0413
else:
Figure = images.Figure
__version__ = '1.0.0' __version__ = '1.0.0'

View File

@ -0,0 +1,15 @@
<!-- SPDX-License-Identifier: GPL-2.0 -->
<!-- Copyright © 2023, Oracle and/or its affiliates. -->
{# Create a language menu for translations #}
{% if languages|length > 0: %}
<div class="language-selection">
{{ current_language }}
<ul>
{% for ref in languages: %}
<li><a href="{{ ref.refuri }}">{{ ref.astext() }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}

View File

@ -0,0 +1,101 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright © 2023, Oracle and/or its affiliates.
# Author: Vegard Nossum <vegard.nossum@oracle.com>
#
# Add translation links to the top of the document.
#
import os
from docutils import nodes
from docutils.transforms import Transform
import sphinx
from sphinx import addnodes
from sphinx.errors import NoUri
all_languages = {
# English is always first
None: 'English',
# Keep the rest sorted alphabetically
'zh_CN': 'Chinese (Simplified)',
'zh_TW': 'Chinese (Traditional)',
'it_IT': 'Italian',
'ja_JP': 'Japanese',
'ko_KR': 'Korean',
'sp_SP': 'Spanish',
}
class LanguagesNode(nodes.Element):
def __init__(self, current_language, *args, **kwargs):
super().__init__(*args, **kwargs)
self.current_language = current_language
class TranslationsTransform(Transform):
default_priority = 900
def apply(self):
app = self.document.settings.env.app
docname = self.document.settings.env.docname
this_lang_code = None
components = docname.split(os.sep)
if components[0] == 'translations' and len(components) > 2:
this_lang_code = components[1]
# normalize docname to be the untranslated one
docname = os.path.join(*components[2:])
new_nodes = LanguagesNode(all_languages[this_lang_code])
for lang_code, lang_name in all_languages.items():
if lang_code == this_lang_code:
continue
if lang_code is None:
target_name = docname
else:
target_name = os.path.join('translations', lang_code, docname)
pxref = addnodes.pending_xref('', refdomain='std',
reftype='doc', reftarget='/' + target_name, modname=None,
classname=None, refexplicit=True)
pxref += nodes.Text(lang_name)
new_nodes += pxref
self.document.insert(0, new_nodes)
def process_languages(app, doctree, docname):
for node in doctree.traverse(LanguagesNode):
if app.builder.format not in ['html']:
node.parent.remove(node)
continue
languages = []
# Iterate over the child nodes; any resolved links will have
# the type 'nodes.reference', while unresolved links will be
# type 'nodes.Text'.
languages = list(filter(lambda xref:
isinstance(xref, nodes.reference), node.children))
html_content = app.builder.templates.render('translations.html',
context={
'current_language': node.current_language,
'languages': languages,
})
node.replace_self(nodes.raw('', html_content, format='html'))
def setup(app):
app.add_node(LanguagesNode)
app.add_transform(TranslationsTransform)
app.connect('doctree-resolved', process_languages)
return {
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -12,5 +12,4 @@ Unsorted Documentation
rpmsg rpmsg
speculation speculation
static-keys static-keys
tee
xz xz

View File

@ -1,364 +0,0 @@
=============
TEE subsystem
=============
This document describes the TEE subsystem in Linux.
A TEE (Trusted Execution Environment) is a trusted OS running in some
secure environment, for example, TrustZone on ARM CPUs, or a separate
secure co-processor etc. A TEE driver handles the details needed to
communicate with the TEE.
This subsystem deals with:
- Registration of TEE drivers
- Managing shared memory between Linux and the TEE
- Providing a generic API to the TEE
The TEE interface
=================
include/uapi/linux/tee.h defines the generic interface to a TEE.
User space (the client) connects to the driver by opening /dev/tee[0-9]* or
/dev/teepriv[0-9]*.
- TEE_IOC_SHM_ALLOC allocates shared memory and returns a file descriptor
which user space can mmap. When user space doesn't need the file
descriptor any more, it should be closed. When shared memory isn't needed
any longer it should be unmapped with munmap() to allow the reuse of
memory.
- TEE_IOC_VERSION lets user space know which TEE this driver handles and
its capabilities.
- TEE_IOC_OPEN_SESSION opens a new session to a Trusted Application.
- TEE_IOC_INVOKE invokes a function in a Trusted Application.
- TEE_IOC_CANCEL may cancel an ongoing TEE_IOC_OPEN_SESSION or TEE_IOC_INVOKE.
- TEE_IOC_CLOSE_SESSION closes a session to a Trusted Application.
There are two classes of clients, normal clients and supplicants. The latter is
a helper process for the TEE to access resources in Linux, for example file
system access. A normal client opens /dev/tee[0-9]* and a supplicant opens
/dev/teepriv[0-9].
Much of the communication between clients and the TEE is opaque to the
driver. The main job for the driver is to receive requests from the
clients, forward them to the TEE and send back the results. In the case of
supplicants the communication goes in the other direction, the TEE sends
requests to the supplicant which then sends back the result.
The TEE kernel interface
========================
Kernel provides a TEE bus infrastructure where a Trusted Application is
represented as a device identified via Universally Unique Identifier (UUID) and
client drivers register a table of supported device UUIDs.
TEE bus infrastructure registers following APIs:
match():
iterates over the client driver UUID table to find a corresponding
match for device UUID. If a match is found, then this particular device is
probed via corresponding probe API registered by the client driver. This
process happens whenever a device or a client driver is registered with TEE
bus.
uevent():
notifies user-space (udev) whenever a new device is registered on
TEE bus for auto-loading of modularized client drivers.
TEE bus device enumeration is specific to underlying TEE implementation, so it
is left open for TEE drivers to provide corresponding implementation.
Then TEE client driver can talk to a matched Trusted Application using APIs
listed in include/linux/tee_drv.h.
TEE client driver example
-------------------------
Suppose a TEE client driver needs to communicate with a Trusted Application
having UUID: ``ac6a4085-0e82-4c33-bf98-8eb8e118b6c2``, so driver registration
snippet would look like::
static const struct tee_client_device_id client_id_table[] = {
{UUID_INIT(0xac6a4085, 0x0e82, 0x4c33,
0xbf, 0x98, 0x8e, 0xb8, 0xe1, 0x18, 0xb6, 0xc2)},
{}
};
MODULE_DEVICE_TABLE(tee, client_id_table);
static struct tee_client_driver client_driver = {
.id_table = client_id_table,
.driver = {
.name = DRIVER_NAME,
.bus = &tee_bus_type,
.probe = client_probe,
.remove = client_remove,
},
};
static int __init client_init(void)
{
return driver_register(&client_driver.driver);
}
static void __exit client_exit(void)
{
driver_unregister(&client_driver.driver);
}
module_init(client_init);
module_exit(client_exit);
OP-TEE driver
=============
The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
TrustZone based OP-TEE solution that is supported.
Lowest level of communication with OP-TEE builds on ARM SMC Calling
Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
[3] used internally by the driver. Stacked on top of that is OP-TEE Message
Protocol [4].
OP-TEE SMC interface provides the basic functions required by SMCCC and some
additional functions specific for OP-TEE. The most interesting functions are:
- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
which is then returned by TEE_IOC_VERSION
- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
separate secure co-processor.
- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
range to used for shared memory between Linux and OP-TEE.
The GlobalPlatform TEE Client API [5] is implemented on top of the generic
TEE API.
Picture of the relationship between the different components in the
OP-TEE architecture::
User space Kernel Secure world
~~~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~
+--------+ +-------------+
| Client | | Trusted |
+--------+ | Application |
/\ +-------------+
|| +----------+ /\
|| |tee- | ||
|| |supplicant| \/
|| +----------+ +-------------+
\/ /\ | TEE Internal|
+-------+ || | API |
+ TEE | || +--------+--------+ +-------------+
| Client| || | TEE | OP-TEE | | OP-TEE |
| API | \/ | subsys | driver | | Trusted OS |
+-------+----------------+----+-------+----+-----------+-------------+
| Generic TEE API | | OP-TEE MSG |
| IOCTL (TEE_IOC_*) | | SMCCC (OPTEE_SMC_CALL_*) |
+-----------------------------+ +------------------------------+
RPC (Remote Procedure Call) are requests from secure world to kernel driver
or tee-supplicant. An RPC is identified by a special range of SMCCC return
values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
kernel are handled by the kernel driver. Other RPC messages will be forwarded to
tee-supplicant without further involvement of the driver, except switching
shared memory buffer representation.
OP-TEE device enumeration
-------------------------
OP-TEE provides a pseudo Trusted Application: drivers/tee/optee/device.c in
order to support device enumeration. In other words, OP-TEE driver invokes this
application to retrieve a list of Trusted Applications which can be registered
as devices on the TEE bus.
OP-TEE notifications
--------------------
There are two kinds of notifications that secure world can use to make
normal world aware of some event.
1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
2. Asynchronous notifications delivered with a combination of a non-secure
edge-triggered interrupt and a fast call from the non-secure interrupt
handler.
Synchronous notifications are limited by depending on RPC for delivery,
this is only usable when secure world is entered with a yielding call via
``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
world interrupt handlers.
An asynchronous notification is delivered via a non-secure edge-triggered
interrupt to an interrupt handler registered in the OP-TEE driver. The
actual notification value are retrieved with the fast call
``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``. Note that one interrupt can represent
multiple notifications.
One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
special meaning. When this value is received it means that normal world is
supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
call is done from the thread assisting the interrupt handler. This is a
building block for OP-TEE OS in secure world to implement the top half and
bottom half style of device drivers.
OPTEE_INSECURE_LOAD_IMAGE Kconfig option
----------------------------------------
The OPTEE_INSECURE_LOAD_IMAGE Kconfig option enables the ability to load the
BL32 OP-TEE image from the kernel after the kernel boots, rather than loading
it from the firmware before the kernel boots. This also requires enabling the
corresponding option in Trusted Firmware for Arm. The Trusted Firmware for Arm
documentation [8] explains the security threat associated with enabling this as
well as mitigations at the firmware and platform level.
There are additional attack vectors/mitigations for the kernel that should be
addressed when using this option.
1. Boot chain security.
* Attack vector: Replace the OP-TEE OS image in the rootfs to gain control of
the system.
* Mitigation: There must be boot chain security that verifies the kernel and
rootfs, otherwise an attacker can modify the loaded OP-TEE binary by
modifying it in the rootfs.
2. Alternate boot modes.
* Attack vector: Using an alternate boot mode (i.e. recovery mode), the
OP-TEE driver isn't loaded, leaving the SMC hole open.
* Mitigation: If there are alternate methods of booting the device, such as a
recovery mode, it should be ensured that the same mitigations are applied
in that mode.
3. Attacks prior to SMC invocation.
* Attack vector: Code that is executed prior to issuing the SMC call to load
OP-TEE can be exploited to then load an alternate OS image.
* Mitigation: The OP-TEE driver must be loaded before any potential attack
vectors are opened up. This should include mounting of any modifiable
filesystems, opening of network ports or communicating with external
devices (e.g. USB).
4. Blocking SMC call to load OP-TEE.
* Attack vector: Prevent the driver from being probed, so the SMC call to
load OP-TEE isn't executed when desired, leaving it open to being executed
later and loading a modified OS.
* Mitigation: It is recommended to build the OP-TEE driver as builtin driver
rather than as a module to prevent exploits that may cause the module to
not be loaded.
AMD-TEE driver
==============
The AMD-TEE driver handles the communication with AMD's TEE environment. The
TEE environment is provided by AMD Secure Processor.
The AMD Secure Processor (formerly called Platform Security Processor or PSP)
is a dedicated processor that features ARM TrustZone technology, along with a
software-based Trusted Execution Environment (TEE) designed to enable
third-party Trusted Applications. This feature is currently enabled only for
APUs.
The following picture shows a high level overview of AMD-TEE::
|
x86 |
|
User space (Kernel space) | AMD Secure Processor (PSP)
~~~~~~~~~~ ~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
+--------+ | +-------------+
| Client | | | Trusted |
+--------+ | | Application |
/\ | +-------------+
|| | /\
|| | ||
|| | \/
|| | +----------+
|| | | TEE |
|| | | Internal |
\/ | | API |
+---------+ +-----------+---------+ +----------+
| TEE | | TEE | AMD-TEE | | AMD-TEE |
| Client | | subsystem | driver | | Trusted |
| API | | | | | OS |
+---------+-----------+----+------+---------+---------+----------+
| Generic TEE API | | ASP | Mailbox |
| IOCTL (TEE_IOC_*) | | driver | Register Protocol |
+--------------------------+ +---------+--------------------+
At the lowest level (in x86), the AMD Secure Processor (ASP) driver uses the
CPU to PSP mailbox register to submit commands to the PSP. The format of the
command buffer is opaque to the ASP driver. It's role is to submit commands to
the secure processor and return results to AMD-TEE driver. The interface
between AMD-TEE driver and AMD Secure Processor driver can be found in [6].
The AMD-TEE driver packages the command buffer payload for processing in TEE.
The command buffer format for the different TEE commands can be found in [7].
The TEE commands supported by AMD-TEE Trusted OS are:
* TEE_CMD_ID_LOAD_TA - loads a Trusted Application (TA) binary into
TEE environment.
* TEE_CMD_ID_UNLOAD_TA - unloads TA binary from TEE environment.
* TEE_CMD_ID_OPEN_SESSION - opens a session with a loaded TA.
* TEE_CMD_ID_CLOSE_SESSION - closes session with loaded TA
* TEE_CMD_ID_INVOKE_CMD - invokes a command with loaded TA
* TEE_CMD_ID_MAP_SHARED_MEM - maps shared memory
* TEE_CMD_ID_UNMAP_SHARED_MEM - unmaps shared memory
AMD-TEE Trusted OS is the firmware running on AMD Secure Processor.
The AMD-TEE driver registers itself with TEE subsystem and implements the
following driver function callbacks:
* get_version - returns the driver implementation id and capability.
* open - sets up the driver context data structure.
* release - frees up driver resources.
* open_session - loads the TA binary and opens session with loaded TA.
* close_session - closes session with loaded TA and unloads it.
* invoke_func - invokes a command with loaded TA.
cancel_req driver callback is not supported by AMD-TEE.
The GlobalPlatform TEE Client API [5] can be used by the user space (client) to
talk to AMD's TEE. AMD's TEE provides a secure environment for loading, opening
a session, invoking commands and closing session with TA.
References
==========
[1] https://github.com/OP-TEE/optee_os
[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
[3] drivers/tee/optee/optee_smc.h
[4] drivers/tee/optee/optee_msg.h
[5] http://www.globalplatform.org/specificationsdevice.asp look for
"TEE Client API Specification v1.0" and click download.
[6] include/linux/psp-tee.h
[7] drivers/tee/amdtee/amdtee_if.h
[8] https://trustedfirmware-a.readthedocs.io/en/latest/threat_model/threat_model.html

View File

@ -86,3 +86,4 @@ Storage interfaces
misc-devices/index misc-devices/index
peci/index peci/index
wmi/index wmi/index
tee/index

View File

@ -0,0 +1,90 @@
.. SPDX-License-Identifier: GPL-2.0
=============================================
AMD-TEE (AMD's Trusted Execution Environment)
=============================================
The AMD-TEE driver handles the communication with AMD's TEE environment. The
TEE environment is provided by AMD Secure Processor.
The AMD Secure Processor (formerly called Platform Security Processor or PSP)
is a dedicated processor that features ARM TrustZone technology, along with a
software-based Trusted Execution Environment (TEE) designed to enable
third-party Trusted Applications. This feature is currently enabled only for
APUs.
The following picture shows a high level overview of AMD-TEE::
|
x86 |
|
User space (Kernel space) | AMD Secure Processor (PSP)
~~~~~~~~~~ ~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
+--------+ | +-------------+
| Client | | | Trusted |
+--------+ | | Application |
/\ | +-------------+
|| | /\
|| | ||
|| | \/
|| | +----------+
|| | | TEE |
|| | | Internal |
\/ | | API |
+---------+ +-----------+---------+ +----------+
| TEE | | TEE | AMD-TEE | | AMD-TEE |
| Client | | subsystem | driver | | Trusted |
| API | | | | | OS |
+---------+-----------+----+------+---------+---------+----------+
| Generic TEE API | | ASP | Mailbox |
| IOCTL (TEE_IOC_*) | | driver | Register Protocol |
+--------------------------+ +---------+--------------------+
At the lowest level (in x86), the AMD Secure Processor (ASP) driver uses the
CPU to PSP mailbox register to submit commands to the PSP. The format of the
command buffer is opaque to the ASP driver. It's role is to submit commands to
the secure processor and return results to AMD-TEE driver. The interface
between AMD-TEE driver and AMD Secure Processor driver can be found in [1].
The AMD-TEE driver packages the command buffer payload for processing in TEE.
The command buffer format for the different TEE commands can be found in [2].
The TEE commands supported by AMD-TEE Trusted OS are:
* TEE_CMD_ID_LOAD_TA - loads a Trusted Application (TA) binary into
TEE environment.
* TEE_CMD_ID_UNLOAD_TA - unloads TA binary from TEE environment.
* TEE_CMD_ID_OPEN_SESSION - opens a session with a loaded TA.
* TEE_CMD_ID_CLOSE_SESSION - closes session with loaded TA
* TEE_CMD_ID_INVOKE_CMD - invokes a command with loaded TA
* TEE_CMD_ID_MAP_SHARED_MEM - maps shared memory
* TEE_CMD_ID_UNMAP_SHARED_MEM - unmaps shared memory
AMD-TEE Trusted OS is the firmware running on AMD Secure Processor.
The AMD-TEE driver registers itself with TEE subsystem and implements the
following driver function callbacks:
* get_version - returns the driver implementation id and capability.
* open - sets up the driver context data structure.
* release - frees up driver resources.
* open_session - loads the TA binary and opens session with loaded TA.
* close_session - closes session with loaded TA and unloads it.
* invoke_func - invokes a command with loaded TA.
cancel_req driver callback is not supported by AMD-TEE.
The GlobalPlatform TEE Client API [3] can be used by the user space (client) to
talk to AMD's TEE. AMD's TEE provides a secure environment for loading, opening
a session, invoking commands and closing session with TA.
References
==========
[1] include/linux/psp-tee.h
[2] drivers/tee/amdtee/amdtee_if.h
[3] http://www.globalplatform.org/specificationsdevice.asp look for
"TEE Client API Specification v1.0" and click download.

View File

@ -0,0 +1,19 @@
.. SPDX-License-Identifier: GPL-2.0
=============
TEE Subsystem
=============
.. toctree::
:maxdepth: 1
tee
op-tee
amd-tee
.. only:: subproject and html
Indices
=======
* :ref:`genindex`

View File

@ -0,0 +1,166 @@
.. SPDX-License-Identifier: GPL-2.0
====================================================
OP-TEE (Open Portable Trusted Execution Environment)
====================================================
The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
TrustZone based OP-TEE solution that is supported.
Lowest level of communication with OP-TEE builds on ARM SMC Calling
Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
[3] used internally by the driver. Stacked on top of that is OP-TEE Message
Protocol [4].
OP-TEE SMC interface provides the basic functions required by SMCCC and some
additional functions specific for OP-TEE. The most interesting functions are:
- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
which is then returned by TEE_IOC_VERSION
- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
separate secure co-processor.
- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
range to used for shared memory between Linux and OP-TEE.
The GlobalPlatform TEE Client API [5] is implemented on top of the generic
TEE API.
Picture of the relationship between the different components in the
OP-TEE architecture::
User space Kernel Secure world
~~~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~
+--------+ +-------------+
| Client | | Trusted |
+--------+ | Application |
/\ +-------------+
|| +----------+ /\
|| |tee- | ||
|| |supplicant| \/
|| +----------+ +-------------+
\/ /\ | TEE Internal|
+-------+ || | API |
+ TEE | || +--------+--------+ +-------------+
| Client| || | TEE | OP-TEE | | OP-TEE |
| API | \/ | subsys | driver | | Trusted OS |
+-------+----------------+----+-------+----+-----------+-------------+
| Generic TEE API | | OP-TEE MSG |
| IOCTL (TEE_IOC_*) | | SMCCC (OPTEE_SMC_CALL_*) |
+-----------------------------+ +------------------------------+
RPC (Remote Procedure Call) are requests from secure world to kernel driver
or tee-supplicant. An RPC is identified by a special range of SMCCC return
values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
kernel are handled by the kernel driver. Other RPC messages will be forwarded to
tee-supplicant without further involvement of the driver, except switching
shared memory buffer representation.
OP-TEE device enumeration
-------------------------
OP-TEE provides a pseudo Trusted Application: drivers/tee/optee/device.c in
order to support device enumeration. In other words, OP-TEE driver invokes this
application to retrieve a list of Trusted Applications which can be registered
as devices on the TEE bus.
OP-TEE notifications
--------------------
There are two kinds of notifications that secure world can use to make
normal world aware of some event.
1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
2. Asynchronous notifications delivered with a combination of a non-secure
edge-triggered interrupt and a fast call from the non-secure interrupt
handler.
Synchronous notifications are limited by depending on RPC for delivery,
this is only usable when secure world is entered with a yielding call via
``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
world interrupt handlers.
An asynchronous notification is delivered via a non-secure edge-triggered
interrupt to an interrupt handler registered in the OP-TEE driver. The
actual notification value are retrieved with the fast call
``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``. Note that one interrupt can represent
multiple notifications.
One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
special meaning. When this value is received it means that normal world is
supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
call is done from the thread assisting the interrupt handler. This is a
building block for OP-TEE OS in secure world to implement the top half and
bottom half style of device drivers.
OPTEE_INSECURE_LOAD_IMAGE Kconfig option
----------------------------------------
The OPTEE_INSECURE_LOAD_IMAGE Kconfig option enables the ability to load the
BL32 OP-TEE image from the kernel after the kernel boots, rather than loading
it from the firmware before the kernel boots. This also requires enabling the
corresponding option in Trusted Firmware for Arm. The Trusted Firmware for Arm
documentation [6] explains the security threat associated with enabling this as
well as mitigations at the firmware and platform level.
There are additional attack vectors/mitigations for the kernel that should be
addressed when using this option.
1. Boot chain security.
* Attack vector: Replace the OP-TEE OS image in the rootfs to gain control of
the system.
* Mitigation: There must be boot chain security that verifies the kernel and
rootfs, otherwise an attacker can modify the loaded OP-TEE binary by
modifying it in the rootfs.
2. Alternate boot modes.
* Attack vector: Using an alternate boot mode (i.e. recovery mode), the
OP-TEE driver isn't loaded, leaving the SMC hole open.
* Mitigation: If there are alternate methods of booting the device, such as a
recovery mode, it should be ensured that the same mitigations are applied
in that mode.
3. Attacks prior to SMC invocation.
* Attack vector: Code that is executed prior to issuing the SMC call to load
OP-TEE can be exploited to then load an alternate OS image.
* Mitigation: The OP-TEE driver must be loaded before any potential attack
vectors are opened up. This should include mounting of any modifiable
filesystems, opening of network ports or communicating with external
devices (e.g. USB).
4. Blocking SMC call to load OP-TEE.
* Attack vector: Prevent the driver from being probed, so the SMC call to
load OP-TEE isn't executed when desired, leaving it open to being executed
later and loading a modified OS.
* Mitigation: It is recommended to build the OP-TEE driver as builtin driver
rather than as a module to prevent exploits that may cause the module to
not be loaded.
References
==========
[1] https://github.com/OP-TEE/optee_os
[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
[3] drivers/tee/optee/optee_smc.h
[4] drivers/tee/optee/optee_msg.h
[5] http://www.globalplatform.org/specificationsdevice.asp look for
"TEE Client API Specification v1.0" and click download.
[6] https://trustedfirmware-a.readthedocs.io/en/latest/threat_model/threat_model.html

22
Documentation/tee/tee.rst Normal file
View File

@ -0,0 +1,22 @@
.. SPDX-License-Identifier: GPL-2.0
===================================
TEE (Trusted Execution Environment)
===================================
This document describes the TEE subsystem in Linux.
Overview
========
A TEE is a trusted OS running in some secure environment, for example,
TrustZone on ARM CPUs, or a separate secure co-processor etc. A TEE driver
handles the details needed to communicate with the TEE.
This subsystem deals with:
- Registration of TEE drivers
- Managing shared memory between Linux and the TEE
- Providing a generic API to the TEE

View File

@ -182,7 +182,7 @@ FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED
FTRACE_OPS_FL_RECURSION FTRACE_OPS_FL_RECURSION
By default, it is expected that the callback can handle recursion. By default, it is expected that the callback can handle recursion.
But if the callback is not that worried about overehead, then But if the callback is not that worried about overhead, then
setting this bit will add the recursion protection around the setting this bit will add the recursion protection around the
callback by calling a helper function that will do the recursion callback by calling a helper function that will do the recursion
protection and only call the callback if it did not recurse. protection and only call the callback if it did not recurse.
@ -190,7 +190,7 @@ FTRACE_OPS_FL_RECURSION
Note, if this flag is not set, and recursion does occur, it could Note, if this flag is not set, and recursion does occur, it could
cause the system to crash, and possibly reboot via a triple fault. cause the system to crash, and possibly reboot via a triple fault.
Not, if this flag is set, then the callback will always be called Note, if this flag is set, then the callback will always be called
with preemption disabled. If it is not set, then it is possible with preemption disabled. If it is not set, then it is possible
(but not guaranteed) that the callback will be called in (but not guaranteed) that the callback will be called in
preemptable context. preemptable context.

View File

@ -180,6 +180,21 @@ of ftrace. Here is a list of some of the key files:
Only active when the file contains a number greater than 0. Only active when the file contains a number greater than 0.
(in microseconds) (in microseconds)
buffer_percent:
This is the watermark for how much the ring buffer needs to be filled
before a waiter is woken up. That is, if an application calls a
blocking read syscall on one of the per_cpu trace_pipe_raw files, it
will block until the given amount of data specified by buffer_percent
is in the ring buffer before it wakes the reader up. This also
controls how the splice system calls are blocked on this file::
0 - means to wake up as soon as there is any data in the ring buffer.
50 - means to wake up when roughly half of the ring buffer sub-buffers
are full.
100 - means to block until the ring buffer is totally full and is
about to start overwriting the older data.
buffer_size_kb: buffer_size_kb:
This sets or displays the number of kilobytes each CPU This sets or displays the number of kilobytes each CPU
@ -2574,7 +2589,7 @@ want, depending on your needs.
- The cpu number on which the function executed is default - The cpu number on which the function executed is default
enabled. It is sometimes better to only trace one cpu (see enabled. It is sometimes better to only trace one cpu (see
tracing_cpu_mask file) or you might sometimes see unordered tracing_cpumask file) or you might sometimes see unordered
function calls while cpu tracing switch. function calls while cpu tracing switch.
- hide: echo nofuncgraph-cpu > trace_options - hide: echo nofuncgraph-cpu > trace_options

View File

@ -8,9 +8,17 @@
Una guida al processo di sviluppo del Kernel Una guida al processo di sviluppo del Kernel
============================================ ============================================
Contenuti: Lo scopo di questo documento è quello di aiutare gli sviluppatori (ed i loro
supervisori) a lavorare con la communità di sviluppo con il minimo sforzo. È
un tentativo di documentare il funzionamento di questa communità in modo che
sia accessibile anche a coloro che non hanno famigliarità con lo sviluppo del
Kernel Linux (o, anzi, con lo sviluppo di software libero in generale). Benchè
qui sia presente del materiale tecnico, questa è una discussione rivolta in
particolare al procedimento, e quindi per essere compreso non richiede una
conoscenza approfondità sullo sviluppo del kernel.
.. toctree:: .. toctree::
:caption: Contenuti
:numbered: :numbered:
:maxdepth: 2 :maxdepth: 2
@ -22,12 +30,3 @@ Contenuti:
6.Followthrough 6.Followthrough
7.AdvancedTopics 7.AdvancedTopics
8.Conclusion 8.Conclusion
Lo scopo di questo documento è quello di aiutare gli sviluppatori (ed i loro
supervisori) a lavorare con la communità di sviluppo con il minimo sforzo. È
un tentativo di documentare il funzionamento di questa communità in modo che
sia accessibile anche a coloro che non hanno famigliarità con lo sviluppo del
Kernel Linux (o, anzi, con lo sviluppo di software libero in generale). Benchè
qui sia presente del materiale tecnico, questa è una discussione rivolta in
particolare al procedimento, e quindi per essere compreso non richiede una
conoscenza approfondità sullo sviluppo del kernel.

View File

@ -4,3 +4,6 @@
Si tiene alguna duda sobre la exactitud del contenido de esta Si tiene alguna duda sobre la exactitud del contenido de esta
traducción, la única referencia válida es la documentación oficial en traducción, la única referencia válida es la documentación oficial en
inglés. inglés.
Además, por defecto, los enlaces a documentos redirigen a la
documentación en inglés, incluso si existe una versión traducida.
Consulte el índice para más información.

View File

@ -76,6 +76,5 @@ Traducciones al español
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
howto
process/index process/index
wrappers/memory-barriers wrappers/memory-barriers

View File

@ -0,0 +1,797 @@
.. include:: ../disclaimer-sp.rst
:Translator: Sergio González Collado <sergio.collado@gmail.com>
.. _sp_handling_regressions:
Gestión de regresiones
++++++++++++++++++++++
*No causamos regresiones* -- este documento describe la que es la "primera
regla del desarrollo del kernel de Linux" y que implica en la práctica para
los desarrolladores. Y complementa la documentación:
Documentation/admin-guide/reporting-regressions.rst, que cubre el tema
desde el punto de vista de un usuario; si nunca ha leído ese texto, realice
al menos una lectura rápida del mismo antes de continuar.
Las partes importantes (el "TL;DR")
===================================
#. Asegúrese de que los suscriptores a la lista `regression mailing list
<https://lore.kernel.org/regressions/>`_ (regressions@lists.linux.dev)
son conocedores con rapidez de cualquier nuevo informe de regresión:
* Cuando se reciba un correo que no incluyó a la lista, inclúyalo en la
conversación de los correos, mandando un breve "Reply-all" con la
lista en CCed.
* Mande o redirija cualquier informe originado en los gestores de bugs
a la lista.
#. Haga que el bot del kernel de Linux "regzbot" realice el seguimiento del
incidente (esto es opcional, pero recomendado).
* Para reportes enviados por correo, verificar si contiene alguna línea
como ``#regzbot introduced v5.13..v5.14-rc1``. Si no, mandar una
respuesta (con la lista de regresiones en CC) que contenga un párrafo
como el siguiente, lo que le indica a regzbot cuando empezó a suceder
el incidente::
#regzbot ^introduced 1f2e3d4c5b6a
* Cuando se mandan informes desde un gestor de incidentes a la lista de
regresiones(ver más arriba), incluir un párrafo como el siguiente::
#regzbot introduced: v5.13..v5.14-rc1
#regzbot from: Some N. Ice Human <some.human@example.com>
#regzbot monitor: http://some.bugtracker.example.com/ticket?id=123456789
#. Cuando se manden correcciones para las regresiones, añadir etiquetas
"Link:" a la descripción, apuntado a todos los sitios donde se informó
del incidente, como se indica en el documento:
Documentation/process/submitting-patches.rst y
:ref:`Documentation/process/5.Posting.rst <development_posting>`.
#. Intente arreglar las regresiones rápidamente una vez la causa haya sido
identificada; las correcciones para la mayor parte de las regresiones
deberían ser integradas en menos de dos semanas, pero algunas pueden
resolverse en dos o tres días.
Detalles importantes para desarrolladores en la regresiones de kernel de Linux
==============================================================================
Puntos básicos importantes más en detalle
-----------------------------------------
Qué hacer cuando se recibe un aviso de regresión.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Asegúrese de que el programa de gestión de regresiones del kernel de Linux
y los subscritos a la lista de correo `regression mailing list
<https://lore.kernel.org/regressions/>`_ (regressions@lists.linux.dev) son
conocedores de cualquier nuevo informe de regresión:
* Cuando se recibe un informe por email que no tiene en CC la lista,
inmediatamente meterla en el la cadena de emails mandado al menos un
breve "Reply-all" con la lista en CC; Intentar asegurar que la lista es
añadida en CC de nuevo en caso de que alguna respuesta la omita de la
lista.
* Si un informe enviado a un gestor de defectos, llega a su correo,
reenvíelo o redirijalo a la lista. Considere verificar los archivos de
la lista de antemano, si la persona que lo ha informado, lo ha enviado
anteriormente, como se indica en:
Documentation/admin-guide/reporting-issues.rst.
Cuando se realice cualquiera de las acciones anteriores, considere
inmediatamente iniciar el seguimiento de la regresión con "regzbot" el
gestor de regresiones del kernel de Linux.
* Para los informes enviados por email, verificar si se ha incluido un
comando a "regzbot", como ``#regzbot introduced 1f2e3d4c5b6a``. Si no es
así, envíe una respuesta (con la lista de regresiones en CC) con un
párrafo como el siguiente::
#regzbot ^introduced: v5.13..v5.14-rc1
Esto indica a regzbot el rango de versiones en el cual es defecto
comenzó a suceder; Puede especificar un rango usando los identificadores
de los commits así como un único commit, en caso en el que el informante
haya identificado el commit causante con 'bisect'.
Tenga en cuenta que el acento circunflejo (^) antes de "introduced":
Esto indica a regzbot, que debe tratar el email padre (el que ha sido
respondido) como el informeinicial para la regresión que quiere ser
seguida. Esto es importante, ya que regzbot buscará más tarde parches
con etiquetas "Link:" que apunten al al informe de losarchivos de
lore.kernel.org.
* Cuando mande informes de regresiones a un gestor de defectos, incluya un
párrafo con los siguientes comandos a regzbot::
#regzbot introduced: 1f2e3d4c5b6a
#regzbot from: Some N. Ice Human <some.human@example.com>
#regzbot monitor: http://some.bugtracker.example.com/ticket?id=123456789
Regzbot asociará automáticamente parches con el informe que contengan
las etiquetas "Link:" apuntando a su email o el ticket indicado.
Qué es importante cuando se corrigen regresiones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
No se necesita hacer nada especial cuando se mandan las correcciones para
las regresiones únicamente recordar lo que se explica en los documentos:
Documentation/process/submitting-patches.rst,
:ref:`Documentation/process/5.Posting.rst <development_posting>`, y
Documentation/process/stable-kernel-rules.rst
* Apunte a todos los lugares donde el incidente se reportó usando la
etiqueta "Link:" ::
Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
Link: https://bugzilla.kernel.org/show_bug.cgi?id=1234567890
* Añada la etiqueta "Fixes:" para indicar el commit causante de la
regresión.
* Si el culpable ha sido "mergeado" en un ciclo de desarrollo anterior,
marque explícitamente el fix para retro-importarlo usando la etiqueta
``Cc: stable@vger.kernel.org`` tag.
Todo esto se espera y es importante en una regresión, ya que estas
etiquetas son de gran valor para todos (incluido usted) que pueda estar
mirando en ese incidente semanas, meses o años después. Estas etiquetas son
también cruciales para las herramientas y scripts usados por otros
desarrolladores del kernel o distribuciones de Linux; una de esas
herramientas es regzbot, el cual depende mucho de las etiquetas "Link:"
para asociar los informes por regresiones con los cambios que las
resuelven.
Priorización del trabajo en arreglar regresiones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Al final, los desarrolladores deberían hacer lo posible para evitar a los
usuarios situaciones donde una regresión les deje solo tres opciones:
* Ejecutar el kernel con una regresión que afecta seriamente al uso.
* Cambiar a un kernel nuevo o mas antiguo -- rebajarse a una versión
soportada del kernel que no tenga las funcionalidades requeridas.
* Continuar ejecutando una versión desfasada y potencialmente insegura del
kernel por más de dos semanas después de que el causante de una regresión
fuese identificado.
Cómo se ejecuta esto depende mucho de la situación. A continuación se
presentan unas reglas generales, en orden de importancia:
* Priorice el trabajo en la gestión de los informes de la regresión y
arreglar la regresión por encima de cualquier otro trabajo en el kernel
de Linux, a menos que lo último afecte profundamente a efectos de
seguridad, o cause errores en los que haya pérdida o daño de datos.
* Considere siempre revertir los commits responsables y re-aplicarlos
después, junto con las correcciones necesarias, ya que esto puede la
forma menos peligrosa y más rápida de arreglar la regresión.
* Los desarrolladores deberían gestionar la regresión en todos los kernels
soportados de la serie, pero son libres de delegar el trabajo al equipo
permanente el incidente no hubiese ocurrido en la línea principal.
* Intente resolver cualquier regresión que apareciera en el ciclo de
desarrollo antes de que este acabe. Si se teme que una corrección
pudiera ser demasiado arriesgada para aplicarla días antes de una
liberación de la línea principal de desarrollo, dejar decidir a Linus:
mande la corrección a él de forma separada, tan pronto como sea posible
con una explicación de la situación. El podrá decidir, y posponer la
liberación si fuese necesario, por ejemplo si aparecieran múltiples
cambios como ese.
* Gestione las regresiones en la rama estable, de largo término, o la
propia rama principal de las versiones, con más urgencia que la
regresiones en las preliberaciones. Esto cambia después de la liberación
de la quinta pre-liberación, aka "-rc5": la rama principal entonces se
vuelve más importante, asegurar que todas las mejoras y correcciones son
idealmente testeados juntos por al menos una semana antes de que Linux
libere la nueva versión en la rama principal.
* Intente arreglar regresiones en un intervalo de una semana después de
que se ha identificado el responsable, si el incidente fue introducido
en alguno de los siguientes casos:
* una versión estable/largo-plazo reciente
* en el último ciclo de desarrollo de la rama principal
En el último caso (por ejemplo v5.14), intentar gestionar las
regresiones incluso más rápido, si la versión estable precedente (v5.13)
ha de ser abandonada pronto o ya se ha etiquetado como de final de vida
(EOL de las siglas en inglés End-of-Life) -- esto sucede usualmente
sobre tres o cuatro semanas después de una liberación de una versión en
la rama principal.
* Intente arreglar cualquier otra regresión en un periodo de dos semanas
después de que el culpable haya sido identificado. Dos o tres semanas
adicionales son aceptables para regresiones de rendimiento y otros
incidentes que son molestos, pero no bloquean a nadie la ejecución de
Linux (a menos que se un incidente en el ciclo de desarrollo actual, en
ese caso se debería gestionar antes de la liberación de la versión).
Unas semanas son aceptables si la regresión únicamente puede ser
arreglada con un cambio arriesgado y al mismo tiempo únicamente afecta a
unos pocos usuarios; también está bien si se usa tanto tiempo como fuera
necesario si la regresión está presente en la segunda versión más nueva
de largo plazo del kernel.
Nota: Los intervalos de tiempo mencionados anteriormente para la resolución
de las regresiones, incluyen la verificación de esta, revisión e inclusión
en la rama principal, idealmente con la corrección incluida en la rama
"linux-next" al menos brevemente. Esto conllevará retrasos que también se
tienen tener en cuenta.
Se espera que los maintainers de los subsistemas, ayuden en conseguir esos
tiempos, haciendo revisiones con prontitud y gestionando con rapidez los
parches aceptados. Esto puede resultar en tener que mandar peticiones de
git-pull antes o de forma más frecuente que lo normal; dependiendo del
arreglo, podría incluso ser aceptable saltarse la verificación en
linux-next. Especialmente para las correcciones en las ramas de los kernels
estable y de largo plazo necesitan ser gestionadas rápidamente, y las
correcciones necesitan ser incluidas en la rama principal antes de que
puedan ser incluidas posteriormente a las series precedentes.
Más aspectos sobre regresiones que los desarrolladores deben saber
------------------------------------------------------------------
Cómo tratar con cambios donde se sabe que hay riesgo de regresión
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Evalué cómo de grande es el riesgo de una regresión, por ejemplo realizando
una búsqueda en las distribuciones de linux y en Git forges. Considere
también preguntar a otros desarrolladores o proyectos que pudieran ser
afectados para evaluar o incluso testear el cambio propuesto; si
apareciesen problemas, quizás se pudiera encontrar una solución aceptable
para todos.
Si al final, el riesgo de la regresión parece ser relativamente pequeño,
entonces adelante con el cambio, pero siempre informe a todas las partes
involucradas del posible riesgo. Por tanto, asegúrese de que la descripción
del parche, se hace explícito este hecho. Una vez el cambio ha sido
integrado, informe al gestor de regresiones de Linux y a las listas de
correo de regresiones sobre el riesgo, de manera que cualquiera que tenga
el cambio en el radar, en el caso de que aparezcan reportes. Dependiendo
del riesgo, quizás se quiera preguntar al mantenedor del subsistema, que
mencione el hecho en su línea principal de desarrollo.
¿Qué más hay que saber sobre regresiones?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Repase la documentación: Documentation/admin-guide/reporting-regressions.rst,
esta cubre otros aspectos a tener a en cuenta y conocer:
* la finalidad de la "regla de no regresión"
* qué incidencias no se califican como regresión
* quién es el responsable de identificar la causa raíz de una regresión
* cómo gestionar situaciones difíciles, como por ejemplo cuando una
regresión es causada por una corrección de seguridad o cuando una
regresión causa otra regresión
A quién preguntar por consejo cuando se trata de regresiones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mande un email a la lista de correo de regresiones
(regressions@lists.linux.dev) y CC al seguidor de regresiones del kernel de
Linux (regressions@leemhuis.info); Si el incidente pudiera ser mejor
gestionarlo en privado, puede omitirse la lista.
Más sobre la gestión de regresiones con regzbot
-----------------------------------------------
¿Por qué el kernel de Linux tiene un gestor de regresiones, y por qué se usa regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reglas como "no regresiones" necesitan asegurar que se cumplen, de otro
modo se romperían accidentalmente o a propósito. La historia ha mostrado
que esto es verdad también para el kernel de Linux. Esto es por lo que
Thorsten Leemhuis se ofreció como voluntario para dar una solución a esto,
con el gestor de regresiones del kernel de Linux. A nadie se le paga por
hacer esto, y esa es la razón por la gestión de regresiones es un servicio
con el "mejor esfuerzo".
Intentos iniciales de gestionar manualmente las regresiones han demostrado
que es una tarea extenuante y frustrante, y por esa razón se dejaron de
hacer después de un tiempo. Para evitar que volviese a suceder esto,
Thorsten desarrollo regbot para facilitar el trabajo, con el objetivo a
largo plazo de automatizar la gestión de regresiones tanto como fuese
posible para cualquiera que estuviese involucrado.
¿Cómo funciona el seguimiento de regresiones con regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El bot monitoriza las respuestas de los informes de las regresiones
identificadas. Adicionalmente mira si se han publicado o enviado parches
que hagan referencia a esos informes con la etiqueta: "Link:"; respuestas a
esos parches también se siguen. Combinando esta información, también
proporciona una buena imagen del estado actual del proceso de corrección.
Regzbot intenta hacer todo este trabajo con tan poco retraso como sea
posible tanto para la gente que lo reporta, como para los desarrolladores.
De hecho, solo los informantes son requeridos para una tarea adicional:
necesitan informar a regzbot con el comando ``#regzbot introduced``
indicado anteriormente; si no hacen esto, alguien más puede hacerlo usando
``#regzbot ^introduced``.
Para los desarrolladores normalmente no hay un trabajo adicional que
realizar, únicamente necesitan asegurarse una cosa, que ya se hacía mucho
antes de que regzbot apareciera: añadir las etiquetas "Link:" a la
descripción del parche apuntando a todos los informes sobre el error
corregido.
¿Tengo que usar regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~
Hacerlo es por el bien de todo el mundo, tanto los mantenedores del kernel,
como Linus Torvalds dependen parcialmente en regzbot para seguir su trabajo
-- por ejemplo cuando deciden liberar una nueva versión o ampliar la fase de
desarrollo. Para esto necesitan conocer todas las regresiones que están sin
corregir; para esto, es conocido que Linux mira los informes semanales que
manda regzbot.
¿He de informar a regzbot cada regresión que encuentre?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Idealmente, sí: todos somos humanos y olvidamos fácilmente los problemas
cuando algo más importante aparece inesperadamente -- por ejemplo un
problema mayor en el kernel de Linux o algo en la vida real que nos mantenga
alejados de los teclados por un tiempo. Por eso es mejor informar a regzbot
sobre cada regresión, excepto cuando inmediatamente escribimos un parche y
los mandamos al árbol de desarrollo en el que se integran habitualmente a
la serie del kernel.
¿Cómo ver qué regresiones esta siguiendo regbot actualmente?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Verifique el `interfaz web de regzbot <https://linux-regtracking.leemhuis.info/regzbot/>`_
para ver la última información; o `busque el último informe de regresiones
<https://lore.kernel.org/lkml/?q=%22Linux+regressions+report%22+f%3Aregzbot>`_,
el cual suele ser enviado por regzbot una vez a la semana el domingo por la
noche (UTC), lo cual es unas horas antes de que Linus normalmente anuncie
las "(pre-)releases".
¿Qué sitios supervisa regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Regzbot supervisa las listas de correo más importantes de Linux, como
también las de los repositorios linux-next, mainline y stable/longterm.
¿Qué tipos de incidentes han de ser monitorizados por regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El bot debe hacer seguimiento de las regresiones, y por tanto por favor,
no involucre a regzbot para incidencias normales. Pero es correcto para
el gestor de incidencias de kernel de Linux, monitorizar incidentes
graves, como informes sobre cuelgues, corrupción de datos o errores
internos (Panic, Oops, BUG(), warning, ...).
¿Puedo añadir una regresión detectada por un sistema de CI al seguimiento de regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Siéntase libre de hacerlo, si la regresión en concreto puede tener un
impacto en casos de uso prácticos y por tanto ser detectado por los usuarios;
Así, por favor no involucre a regzbot en regresiones teóricas que
difícilmente pudieran manifestarse en un uso real.
¿Cómo interactuar con regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Usando el comando 'regzbot' en una respuesta directa o indirecta al correo
con el informe de regresión. Ese comando necesita estar en su propio
párrafo (debe estar separado del resto del texto usando líneas en blanco):
Por ejemplo ``#regzbot introduced <version or commit>``, que hace que regzbot
considere el correo como un informe de regressión que se ha de añadir al
seguimiento, como se ha descrito anteriormente; ``#regzbot ^introduced <version or commit>``
es otro ejemplo del comando, el cual indica a regzbot que considere el email
anterior como el informe de una regresión que se ha de comenzar a monitorizar.
Una vez uno de esos dos comandos se ha utilizado, se pueden usar otros
comandos regzbot en respuestas directas o indirectas al informe. Puede
escribirlos debajo de uno de los comandos anteriormente usados o en las
respuestas al correo en el que se uso como respuesta a ese correo:
* Definir o actualizar el título::
#regzbot title: foo
* Monitorizar una discusión o un tiquet de bugzilla.kernel.org donde
aspectos adicionales del incidente o de la corrección se están
comentando -- por ejemplo presentar un parche que corrige la regresión::
#regzbot monitor: https://lore.kernel.org/all/30th.anniversary.repost@klaava.Helsinki.FI/
Monitorizar solamente funciona para lore.kernel.org y bugzilla.kernel.org;
regzbot considerará todos los mensajes en ese hilo o el tiquet como
relacionados al proceso de corrección.
* Indicar a un lugar donde más detalles de interés, como un mensaje en una
lista de correo o un tiquet en un gestor de incidencias que pueden estar
levemente relacionados, pero con un tema diferente::
#regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
* Identificar una regresión como corregida por un commit que se ha mandado
aguas arriba o se ha publicado::
#regzbot fixed-by: 1f2e3d4c5d
* Identificar una regresión como un duplicado de otra que ya es seguida
por regzbot::
#regzbot dup-of: https://lore.kernel.org/all/30th.anniversary.repost@klaava.Helsinki.FI/
* Identificar una regresión como inválida::
#regzbot invalid: wasn't a regression, problem has always existed
¿Algo más que decir sobre regzbot y sus comandos?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hay información más detallada y actualizada sobre el bot de seguimiento de
regresiones del kernel de Linux en: `project page <https://gitlab.com/knurd42/regzbot>`_,
y entre otros contiene una `guia de inicio <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_
y `documentación de referencia <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_
Ambos contienen más detalles que las secciones anteriores.
Citas de Linus sobre regresiones
--------------------------------
A continuación se encuentran unos ejemplos reales (traducidos) de como
Linus Torvalds espera que se gestionen las regresiones:
* De 2017-10-26 (1/2)
<https://lore.kernel.org/lkml/CA+55aFwiiQYJ+YoLKCXjN_beDVfu38mg=Ggg5LFOcqHE8Qi7Zw@mail.gmail.com/>`_::
Si rompes la configuración de los espacios de usuario ESO ES UNA REGRESIÓN.
No está bien decir "pero nosotros arreglaremos la configuración del espacio
de usuario".
Realmente. NO ESTÁ BIEN.
[...]
La primera regla es:
- no causamos regresiones
y el corolario es que cuando una regresión pasa, lo admitimos y lo
arreglamos, en vez de echar la culpa al espacio de usuario.
El hecho de que aparentemente se haya negado la regresión durante
tres semanas, significa que lo revertiré y dejaré de integrar peticiones
de apparmor hasta que la gente involucrada entienda como se hace
el desarrollo del kernel.
* De `2017-10-26 (2/2)
<https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
La gente debería sentirse libre de actualizar su kernel y simplemente
no preocuparse por ello.
Me niego a imponer una limitación del tipo "solo puede actualizar
el kernel si actualiza otro programa". Si el kernel trabaja para tí,
la regla es que continúe trabajando para tí.
Ha habido algunas excepciones, pero son pocas y separadas entre sí, y
generalmente tienen una razón fundamental para haber sucedido, que era
básicamente inevitable, y la gente intentó evitarlas por todos los
medios. Quizás no podamos mantener el hardware más, después de que han
pasado décadas y nadie los usacon kernel modernos. Quizás haya un
problema de seguridad serio con cómo hicimos las cosas, y la gente
depende de un modelo fundamentalmente roto. Quizás haya algún otro roto
fundamental, que tenga que tener una _flag_ y por razones internas y
fundamentales.
Y nótese que esto trata sobre *romper* los entornos de la gente.
Cambios de comportamiento pasan, y quizás no se mantengan algunas
funcionalidades más. Hay un número de campos en /proc/<pid>/stat que
se imprimen como ceros, simplemente porque ni siquiera existen ya en
kernel, o porque mostrarlos era un error (típica una fuga de
información). Pero los números se sustituyeron por ceros, así que
el código que se usaba para parsear esos campos todavía existe. El
usuario puede no ver todo lo que podía ver antes, y por eso el
omportamiento es claramente diferente, pero las cosas todavía
_funcionan_, incluso si no se puede mostrar información sensible
(o que no es ya importante).
Pero si algo realmente se rompe, entonces el cambio debe de arreglarse
o revertirse. Y se arregla en el *kernel*. No diciendo "bueno, arreglaremos
tu espacio de usuario". Ha sido un cambio en el kernel el que creo
el problema, entonces ha de ser el kernel el que lo corrija, porque
tenemos un modelo de "actualización". Pero no tenemos una "actualización
con el nuevo espacio de usuario".
Y yo seriamente me negaré a coger código de gente que no entiende y
honre esta sencilla regla.
Y esta regla no va a cambiar.
Y sí, me doy cuenta que el kernel es "especial" en este respecto. Y
estoy orgulloso de ello.
Y he visto, y puedo señalar, muchos proyectos que dicen "Tenemos que
romper ese caso de uso para poder hacer progresos" o "estabas basandote
en comportamientos no documentados, debe ser duro ser tú" o "hay una
forma mejor de hacer lo que quieres hacer, y tienes que cambiar a esa
nueva forma", y yo simplemente no pienso que eso sea aceptable fuera
de una fase alfa muy temprana que tenga usuarios experimentales que
saben a lo que se han apuntado. El kernel no ha estado en esta
situación en las dos últimas décadas.
Nosotros rompemos la API _dentro_ del kernel todo el tiempo. Y
arreglaremos los problemas internos diciendo "tú ahora necesitas
hacer XYZ", pero entonces es sobre la API interna del kernel y la
gente que hace esto entonces tendrá obviamente que arreglar todos
los usos de esa API del kernel. Nadie puede decir "ahora, yo he roto
la API que usas, y ahora tú necesitas arreglarlo". Quién rompa algo,
lo arregla también.
Y nosotros, simplemente, no rompemos el espacio de usuario.
* De `2020-05-21
<https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
Las reglas sobre regresiones nunca han sido sobre ningún tipo de
comportamiento documentado, o dónde está situado el código.
Las reglas sobre regresiones son siempre sobre "roturas en el
flujo de trabajo del usuario".
Los usuarios son literalmente la _única_ cosa que importa.
Argumentaciones como "no debería haber usado esto" o "ese
comportamiento es indefinido, es su culpa que su aplicación no
funcione" o "eso solía funcionar únicamente por un bug del kernel" son
irrelevantes.
Ahora, la realidad nunca es blanca o negra. Así hemos tenido situaciones
como "un serio incidente de seguridad" etc que solamente nos fuerza
a hacer cambios que pueden romper el espacio de usuario. Pero incluso
entonces la regla es que realmente no hay otras opciones para que
las cosas sigan funcionando.
Y obviamente, si los usuarios tardan años en darse cuenta que algo
se ha roto, o si hay formas adecuadas para sortear la rotura que
no causen muchos problemas para los usuarios (por ejemplo: "hay un
puñado de usuarios, y estos pueden usar la línea de comandos del
kernel para evitarlos"; ese tipo de casos), en esos casos se ha sido
un poco menos estricto.
Pero no, "eso que está documentado que está roto" (si es dado a que
el código estaba en preparación o porque el manual dice otra cosa) eso
es irrelevante. Si preparar el código es tan útil que la gente,
acaba usando, esto implica que básicamente es código del kernel con
una señal diciendo "por favor limpiar esto".
El otro lado de la moneda es que la gente que habla sobre "estabilidad
de las APIs" están totalmente equivocados. Las APIs tampoco importan.
Se puede hacer cualquier cambio que se quiera a una API ... siempre y
cuando nadie se de cuenta.
De nuevo, la regla de las regresiones no trata sobre la documentación,
tampoco sobre las APIs y tampoco sobre las fases de la Luna.
Únicamente trata sobre "hemos causado problemas al espacio de usuario que
antes funcionaba".
* De `2017-11-05
<https://lore.kernel.org/all/CA+55aFzUvbGjD8nQ-+3oiMBx14c_6zOj2n7KLN3UsJ-qsd4Dcw@mail.gmail.com/>`_::
Y nuestra regla sobre las regresiones nunca ha sido "el comportamiento
no cambia". Eso podría significar que nunca podríamos hacer ningún
cambio.
Por ejemplo, hacemos cosas como añadir una nueva gestión de
errores etc todo el tiempo, con lo cual a veces incluso añadimos
tests en el directorio de kselftest.
Así que claramente cambia el comportamiento todo el tiempo y
nosotros no consideramos eso una regresión per se.
La regla para regresiones para el kernel es para cuando se
rompe algo en el espacio de usuario. No en algún test. No en
"mira, antes podía hacer X, y ahora no puedo".
* De `2018-08-03
<https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
ESTÁS OLVIDANDO LA REGLA #1 DEL KERNEL.
No hacemos regresiones, y no hacemos regresiones porque estás 100%
equivocado.
Y la razón que apuntas en tú opinión es exactamente *PORQUÉ* estás
equivocado.
Tus "buenas razones" son honradas y pura basura.
El punto de "no hacemos regresiones" es para que la gente pueda
actualizar el kernel y nunca tengan que preocuparse por ello.
> El kernel tiene un bug que ha de ser arreglado
Eso es *TOTALMENTE* insustancial.
Chicos, si algo estaba roto o no, NO IMPORTA.
¿Porqué?
Los errores pasan. Eso es un hecho de la vida. Discutir que
"tenemos que romper algo porque estábamos arreglando un error" es
una locura. Arreglamos decenas de errores cada dia, pensando que
"arreglando un bug" significa que podemos romper otra cosa es algo
que simplemente NO ES VERDAD.
Así que los bugs no son realmente relevantes para la discusión. Estos
suceden y se detectan, se arreglan, y no tienen nada que ver con
"rompemos a los usuarios".
Porque la única cosa que importa ES EL USUARIO.
¿Cómo de complicado es eso de comprender?
Cualquier persona que use "pero no funcionaba correctamente" es
un argumento no tiene la razón. Con respecto al USUARIO, no era
erróneo - funcionaba para él/ella.
Quizás funcionaba *porque* el usuario había tenido el bug en cuenta,
y quizás funcionaba porque el usuario no lo había notado - de nuevo
no importa. Funcionaba para el usuario.
Romper el flujo del trabajo de un usuario, debido a un "bug" es la
PEOR razón que se pueda usar.
Es básicamente decir "He cogido algo que funcionaba, y lo he roto,
pero ahora es mejor". ¿No ves que un argumento como este es j*didamente
absurdo?
y sin usuarios, tu programa no es un programa, es una pieza de
código sin finalidad que puedes perfectamente tirar a la basura.
Seriamente. Esto es *porque* la regla #1 para el desarrollo del
kernel es "no rompemos el espacio de usuario". Porque "He arreglado
un error" PARA NADA ES UN ARGUMENTO si esa corrección del código
rompe el espacio de usuario.
si actualizamos el kernel TODO EL TIEMPO, sin actualizar ningún otro
programa en absoluto. Y esto es absolutamente necesario, porque
las dependencias son terribles.
Y esto es necesario simplemente porque yo como desarrollador del
kernel no actualizo al azar otras herramientas que ni siquiera me
importan como desarrollador del kernel, y yo quiero que mis usuarios
se sientan a salvo haciendo lo mismo.
Así que no. Tu regla está COMPLETAMENTE equivocada. Si no puedes
actualizar el kernel sin actualizar otro binario al azar, entonces
tenemos un problema.
* De `2021-06-05
<https://lore.kernel.org/all/CAHk-=wiUVqHN76YUwhkjZzwTdjMMJf_zN4+u7vEJjmEGh3recw@mail.gmail.com/>`_::
NO HAY ARGUMENTOS VÁLIDOS PARA UNA REGRESIÓN.
Honestamente, la gente de seguridad necesita entender que "no funciona"
no es un caso de éxito sobre seguridad. Es un caso de fallo.
Sí, "no funciona" puede ser seguro. Pero en este caso es totalmente
inutil.
* De `2011-05-06 (1/3)
<https://lore.kernel.org/all/BANLkTim9YvResB+PwRp7QTK-a5VNg2PvmQ@mail.gmail.com/>`_::
La compatibilidad de los binarios es más importante.
Y si los binarios no usan el interfaz para parsear el formato
(o justamente lo parsea incorrectamente - como el reciente ejemplo
de añadir uuid al /proc/self/mountinfo), entonces es una regresión.
Y las regresiones se revierten, a menos que haya problemas de
seguridad o similares que nos hagan decir "Dios mío, realmente
tenemos que romper las cosas".
No entiendo porqué esta simple lógica es tan difícil para algunos
desarrolladores del kernel. La realidad importa. Sus deseos personales
NO IMPORTAN NADA.
Si se crea un interface que puede usarse sin parsear la
descripción del interface, entonces estaḿos atascados en el interface.
La teoría simplemente no importa.
Podrias alludar a arreglar las herramientas, e intentar evitar los
errores de compatibilidad de ese modo. No hay tampoco tantos de esos.
De `2011-05-06 (2/3)
<https://lore.kernel.org/all/BANLkTi=KVXjKR82sqsz4gwjr+E0vtqCmvA@mail.gmail.com/>`_::
Esto claramente NO es un tracepoint interno. Por definición. Y está
siendo usado por powertop.
De `2011-05-06 (3/3)
<https://lore.kernel.org/all/BANLkTinazaXRdGovYL7rRVp+j6HbJ7pzhg@mail.gmail.com/>`_::
Tenemos programas que usan esa ABI y si eso se rompe eso es una
regresión.
* De `2012-07-06 <https://lore.kernel.org/all/CA+55aFwnLJ+0sjx92EGREGTWOx84wwKaraSzpTNJwPVV8edw8g@mail.gmail.com/>`_::
> Ahora esto me ha dejado preguntandome si Debian _inestable_
realmente califica
> como espacio de usuario estándar.
Oh, si el kernel rompe algún espacio de usuario estándar, eso cuenta.
Muchísima gente usa Debian inestable.
* De `2019-09-15
<https://lore.kernel.org/lkml/CAHk-=wiP4K8DRJWsCo=20hn_6054xBamGKF2kPgUzpB5aMaofA@mail.gmail.com/>`_::
Una reversión _en particular_ en el último minuto en el último commit
(no teniendo en cuenta el propio cambio de versión) justo antes
de la liberación, y aunque es bastante incómodo, quizás también es
instructivo.
Lo que es instructivo sobre esto es que he revertido un commit que no
tenía ningún error. De hecho, hacía exactamente lo que pretendía, y lo
hacía muy bien. De hecho lo hacía _tan_ bien que los muy mejorados
patrones de IO que causaba han acabado revelando una regresión observable
desde el espacio de usuario, debido a un error real en un componente
no relacionado en absoluto.
De todas maneras, los detalles actuales de esta regresión no son la
razón por la que señalo esto como instructivo. Es más que es un ejemplo
ilustrativo sobre lo que cuenta como una regresión, y lo que conlleva
la regla del kernel de "no regresiones". El commit que ha sido revertido
no cambiaba ninguna API, y no introducía ningún error nuevo en el código.
Pero acabó exponiendo otro problema, y como eso causaba que la
actualización del kernel fallara para el usuario. Así que ha sido
revertido.
El foco aquí, es que hemos hecho la reversión basándonos en el
comportamiento reportado en el espacio de usuario, no basado en
conceptos como "cambios de ABI" o "provocaba un error". Los mejores
patrones de IO que se han presentado debido al cambio únicamente han
expuesto un viejo error, y la gente ya dependía del benigno
comportamiento de ese viejo error.
Y que no haya miedo, reintroduciremos el arreglo que mejoraba los
patrones de IO una vez hayamos decidido cómo gestionar el hecho de
que hay una interacción incorrecta con un interfaz en el que la
gente dependía de ese comportamiento previo. Es únicamente que
tenemos que ver cómo gestionamos y cómo lo hacemos (no hay menos de
tres parches diferentes de tres desarrolladores distintos que estamos
evaluando, ... puede haber más por llegar). Mientras tanto, he
revertido lo que exponía el problema a los usuarios de esta release,
incluso cuando espero que el fix será reintroducido (quizás insertado
a posteriormente como un parche estable) una vez lleguemos a un
acuerdo sobre cómo se ha de exponer el error.
Lo que hay que recordar de todo el asunto no es sobre si el cambio
de kernel-espacio-de-usuario ABI, o la corrección de un error, o si
el código antiguo "en primer lugar nunca debería haber estado ahí".
Es sobre si algo rompe el actual flujo de trabajo del usuario.
De todas formas, esto era mi pequeña aclaración en todo este
tema de la regresión. Ya que es la "primera regla de la programación
del kernel", me ha parecido que quizás es bueno mencionarlo de
vez en cuando.

View File

@ -1,4 +1,4 @@
.. include:: ./disclaimer-sp.rst .. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/howto.rst <process_howto>` :Original: :ref:`Documentation/process/howto.rst <process_howto>`
:Translator: Carlos Bilbao <carlos.bilbao@amd.com> :Translator: Carlos Bilbao <carlos.bilbao@amd.com>

View File

@ -24,3 +24,7 @@
contribution-maturity-model contribution-maturity-model
security-bugs security-bugs
embargoed-hardware-issues embargoed-hardware-issues
handling-regressions
management-style
submit-checklist
howto

View File

@ -0,0 +1,299 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/management-style.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
.. _sp_managementstyle:
Estilo de gestión del kernel de Linux
=====================================
Este es un documento breve que describe el estilo de gestión preferido (o
inventado, dependiendo de a quién le preguntes) para el kernel de Linux.
Está destinado a reflejar el documento
:ref:`translations/sp_SP/process/coding-style.rst <sp_codingstyle>` hasta
cierto punto y está escrito principalmente para evitar responder a [#f1]_
las mismas preguntas (o similares) una y otra vez.
El estilo de gestión es muy personal y mucho más difícil de cuantificar
que reglas simples de estilo de codificación, por lo que este documento
puede o no tener relación con la realidad. Comenzó como una broma, pero
eso no significa que no pueda ser realmente cierto. Tendrás que decidir
por ti mismo.
Por cierto, cuando se hable de “gerente de kernel”, se refiere a las
personas lideres técnicas, no de las personas que hacen la gestión
tradicional dentro de las empresas. Si firmas pedidos de compra o tienes
alguna idea sobre el presupuesto de tu grupo, es casi seguro que no eres
un gerente de kernel. Estas sugerencias pueden o no aplicarse a usted.
En primer lugar, sugeriría comprar “Seven Habits of Highly Effective
People” y NO leerlo. Quemarlo, es un gran gesto simbólico.
.. [#f1] Este documento lo hace no tanto respondiendo a la pregunta, sino
haciendo dolorosamente obvio para el interrogador que no tenemos ni idea
de cuál es la respuesta.
De todos modos, aquí va:
.. _decisiones:
1) Decisiones
-------------
Todos piensan que los gerentes toman decisiones, y que la toma de
decisiones en importante. Cuanto más grande y dolorosa sea la decisión,
más grande debe ser el gerente para tomarla. Eso es muy profundo y obvio,
pero en realidad no es cierto.
El nombre del partido es **evitar** tener que tomar una decisión. En
particular, si alguien te dice “elige (a) o (b), realmente necesitamos
que decidas sobre esto”, estas en problemas como gerente. Es mejor que
las personas a las que diriges conozcan los detalles mejor que tú, así
que, si acuden a ti para tomar una decisión técnica, estas jodido.
Claramente no eres competente para tomar una decisión por ellos.
(Corolario: Si las personas a las que diriges no conocen los detalles
mejor que tú, también estas jodido, aunque por una razón totalmente
diferente. Es decir, que estas en el trabajo equivocado y que **ellos**
deberían gestionando tu brillantez en su lugar).
Así que el nombre del partido es **evitar** las decisiones, al menos las
grandes y dolorosas. Tomar decisiones pequeñas y sin consecuencias está
bien, y te hace parecer que sabes lo que estás haciendo, así que lo que
un gerente de kernel necesita hacer es convertir las decisiones grandes
y dolorosas en cosas pequeñas a los que a nadie realmente le importa.
Ayuda darse cuenta de que la diferencia clave entre una decisión grande
y una pequeña es si puede arreglar su decisión después. Cualquier
decisión se puede hacer pequeña simplemente asegurándose siempre de que
si te equivocaste (u **estarás** equivocado), siempre puede deshacer el
daño más tarde retrocediendo. De repente, llegas a ser doblemente
gerencial por tomar **dos** decisiones intrascendentes - la equivocada
**y** la correcta.
Y las personas incluso verán eso como un verdadero liderazgo (*tos*
mierda *tos*).
Por lo tanto, la llave para evitar las grandes decisiones se convierte en
simplemente evitar hacer cosas que no se pueden deshacer. No te dejes
llevar a una esquina del que no puedas escapar. Una rata acorralada puede
ser peligrosa un gerente acorralado es directamente lamentable.
Resulta que, dado que nadie sería tan estúpido como para dejar que un
gerente de kernel tenga una gran responsabilidad **de todos modos**,
generalmente es bastante fácil retroceder. Dado que no vas a poder
malgastar grandes cantidades de dinero que tal vez no puedas pagar, lo
único que puedes revertir es una decisión técnica, y ahí retroceder es
muy fácil: simplemente diles a todos que fuiste un bobo incompetente,
pide disculpas y deshaz todo el trabajo inútil que hiciste trabajar a la
gente durante el año pasado. De repente, la decisión que tomaste hace un
año no era una gran decisión después de todo, ya que se podía deshacer
fácilmente.
Resulta que algunas personas tienen problemas con este enfoque, por dos
razones:
- admitir que eras un idiota es más difícil de lo que parece. A todos
nos gusta mantener las apariencias, y salir en público a decir que te
equivocaste a veces es muy duro.
- que alguien te diga que lo que trabajaste durante el último año no
valió la pena después de todo también puede ser duro para los pobres
ingenieros humildes, y aunque el **trabajo** real fue bastante fácil
de deshacer simplemente eliminándolo, es posible que hayas perdido
irrevocablemente la confianza de ese ingeniero. Y recuerda:
“irrevocablemente” fue lo que tratamos de evitar en primer lugar, y
tu decisión terminó siendo muy grande después de todo.
Afortunadamente, estas dos razones pueden mitigarse eficazmente
simplemente admitiendo inicialmente que no tienes ni idea, y diciéndole
a la gente que tu decisión es puramente preliminar, y podría ser la cosa
equivocada. Siempre te debes reservar el derecho de cambiar de opinión, y
hacer que la gente sea muy **consciente** de eso. Y es mucho más fácil
admitir que eres estúpido cuando **aun** no has hecho la cosa realmente
estúpida.
Entonces, cuando realmente resulta ser estúpido, la gente simplemente
pone los ojos y dice “Ups, otra vez no”.
Esta admisión preventiva de incompetencia también podría hacer que las
personas que realmente hacen el trabajo piensen dos veces sobre si vale la
pena hacerlo o no. Después de todo, si **ellos** no están seguros de si es
una buena idea, seguro que no deberías alentarlos prometiéndoles que lo
que trabajan será incluido. Haz que al menos lo piensen dos veces antes de
embarcarse en un gran esfuerzo.
Recuerda: Es mejor que sepan más sobre los detalles que tú, y
generalmente ya piensan que tienen la respuesta a todo. Lo mejor que puede
hacer como gerente no es inculcar confianza, sino más bien una dosis
saludable de pensamiento crítico sobre lo que hacen.
Por cierto, otra forma de evitar una decisión es quejarse lastimeramente
de “no podemos hacer ambas cosas?” y parecer lamentable. Créeme, funciona.
Si no está claro cuál enfoque es mejor, lo descubrirán. La respuesta puede
terminar siendo que ambos equipos se sientan tan frustrados por la
situación que simplemente se den por vencidos.
Eso puede sonar como un fracaso, pero generalmente es una señal de que
había algo mal con ambos proyectos, y la razón por la que las personas
involucradas no pudieron decidir fue que ambos estaban equivocados.
Terminas oliendo a rosas y evitaste otra decisión que podrías haber
metido la pata.
2) Gente
--------
La mayoría de las personas son idiotas, y ser gerente significa que
tendrás que lidiar con eso, y quizás lo más importante, que **ellos**
tienen que lidiar **contigo**.
Resulta que, si bien es fácil deshacer los errores técnicos, no es tan
fácil deshacer los trastornos de personalidad. Solo tienes que vivir
con los suyos - y el tuyo.
Sin embargo, para prepararse como gerente del kernel, es mejor recordar
no quemar ningún puente, bombardear a ningún aldeano inocente o alienar
a demasiados desarrolladores del kernel. Resulta que alienar a las
personas es bastante fácil, y desalienarlas es difícil. Por lo tanto,
“alienar” cae inmediatamente debajo del título “no reversible”, y se
convierte en un no-no según :ref:`decisiones`.
Aquí solo hay algunas reglas simples:
(1) No llames a la gente pen*ejos (al menos no en público)
(2) Aprende a disculparte cuando olvidaste la regla (1)
El problema con #1 es que es muy fácil de hacer, ya que puedes decir
“eres un pen*ejo” de millones de manera diferentes [#f2]_, a veces sin
siquiera darte cuenta, y casi siempre con una convicción ardiente de que
tienes razón.
Y cuanto más convencido estés de que tienes razón (y seamos sinceros,
puedes llamar a casi **cualquiera** un pen*ejo, y a menudo **tendrás**
razón), más difícil termina siendo disculparse después.
Para resolver este problema, realmente solo tienes dos opciones:
- Se muy buenos en las disculpas.
- Difunde el “amor” de manera tan uniforme que nadie termina sintiendo
que es atacado injustamente. Hazlo lo suficientemente ingenioso, e
incluso podría divertirse.
La opción de ser infaliblemente educado realmente no existe. Nadie
confiará en alguien que está ocultando tan claramente su verdadero
carácter.
.. [#f2] Paul Simon cantó “Cincuenta maneras de dejar a tu amante” porque,
francamente, “Un millón de maneras de decirle a un desarrollador que es
un pen*ejo” no escanea tan bien. Pero estoy seguro de que lo pensó.
3) Gente II el Buen Tipo
--------------------------
Aunque resulta que la mayoría de las personas son idiotas, el corolario
de eso es, tristemente, que tú también seas uno, y aunque todos podemos
disfrutar del conocimiento seguro de que somos mejores que la persona
promedio (somos realistas, nadie cree que nunca que son promedio o debajo
del promedio), también debemos admitir que no somos el cuchillo más
afilado alrededor, y habrá otras personas que son menos idiotas que tú.
Algunas personas reaccionan mal a las personas inteligentes. Otras se
aprovechan de ellos.
Asegúrate de que tú, como mantenedor del kernel, estás en el segundo
grupo. Aguanta con ellos, porque son las personas que te facilitarán el
trabajo. En particular, podrán tomar tus decisiones por ti, que es de lo
que se trata el juego.
Así que cuando encuentras a alguien más inteligente que tú, simplemente
sigue adelante. Sus responsabilidades de gestión se convierten en gran
medida en las de decir “Suena como una buena idea, - hazlo sin
restricciones”, o “Eso suena bien, pero ¿qué pasa con xxx?". La segunda
versión en particular es una excelente manera de aprender algo nuevo
sobre “xxx” o parecer **extra** gerencial al señalar algo que la persona
más inteligente no había pensado. En cualquier caso, sales ganando.
Una cosa para tener en cuenta es darse cuenta de que la grandeza en un
área no necesariamente se traduce en otras áreas. Así que puedes impulsar
a la gente en direcciones específicas, pero seamos realistas, pueden ser
buenos en lo que hacen, y ser malos en todo lo demás. La buena noticia es
que las personas tienden a gravitar naturalmente hacia lo que son buenos,
por lo que no es como si estuvieras haciendo algo irreversible cuando los
impulsas en alguna dirección, simplemente no presiones demasiado.
4) Colocar la culpa
-------------------
Las cosas saldrán mal, y la gente quiere culpar a alguien. Etiqueta, tú
lo eres.
En realidad, no es tan difícil aceptar la culpa, especialmente si la gente
se da cuenta de que no fue **toda** tu culpa. Lo que nos lleva a la mejor
manera de asumir la culpa: hacerlo por otra persona. Te sentirás bien por
asumir la caída, ellos se sentirán bien por no ser culpados, y la persona
que perdió toda su colección de pornografía de 36 GB debido a tu
incompetencia admitirá a regañadientes que al menos intentaste escapar
de ella.
Luego haz que el desarrollador que realmente metió la pata (si puedes
encontrarlo) sepa **en privado** que metió la pata. No solo para que
pueda evitarlo en futuro, sino para que sepan que te deben uno. Y, quizás
aún más importante, también es probable que sea la persona que puede
solucionarlo. Porque, seamos sinceros, seguro que no eres tú.
Asumir la culpa también es la razón por la que llegas a ser un gerente
en primer lugar. Es parte de lo que hace que la gente confíe en ti y te
permita la gloria potencial porque eres tú quien puede decir “metí la
pata”. Y si has seguido las reglas anteriores, ya serás bastante bueno
para decir eso.
5) Cosas que evitar
-------------------
Hay una cosa que la gente odia incluso más que ser llamado “pen*ejo”,
y que es ser llamado “pen*ejo” en una voz mojigata. Por lo primero,
puedes disculparte, por lo segundo, realmente, no tendrás la oportunidad.
Es probable que ya no estén escuchando, incluso si de lo contrario haces
un buen trabajo.
Todos pensamos que somos mejores que los demás, lo que significa que
cuando alguien más se da aires, **realmente** nos molesta. Puedes ser
moral e intelectualmente superior a todos los que te rodean, pero no
trates de hacerlo demasiado obvio a menos que tengas **la intención**
real de irritar a alguien [#f3]_.
Del mismo modo, no seas demasiado educado o sutil acerca de las cosas. La
cortesía fácilmente termina yendo demasiado lejos y ocultado el problema,
y como dicen “En internet, nadie puede oírte ser sutil”. Usa un gran
objeto contundente para enfatizar el punto, porque realmente no puedes
depender de que las personas entiendan tu punto de otra manera.
Un poco de humor puede ayudar a suavizar tanto la franqueza como la
moralización. Exagerar hasta el punto de ser ridículo puede reforzar un
punto sin hacer que sea doloroso para el destinatario, quien simplemente
piensa que estas siendo tonto. Por lo tanto, puede ayudarnos a superar el
bloqueo mental personal que todos tenemos sobre la crítica.
.. [#f3] La pista: Los grupos de noticias de Internet que no están
directamente relacionados con tu trabajo son excelentes maneras de
desahogar tus frustraciones con otras personas. Escribe mensajes
insultantes con una mueca de desprecio solo para entrar en un humor de
vez en cuando, y te sentirás limpio. Eso sí, no te cagues demasiado
cerca de casa.
6) ¿Por qué a mí?
-----------------
Dado que tu principal responsabilidad parece ser asumir la culpa de los
errores de otras personas y hacer dolorosamente obvio para todos los
demás que eres incompetente, la pregunta obvia es: ¿por qué hacerlo en
primer lugar?
Pase lo que pase, **tendrás** una sensación inmensa de logro personal por
estar “a cargo”. No importa el hecho de que realmente estés liderando al
tratar de mantenerte al día con todos los demás y correr detrás de ellos
lo más rápido que puedes. Todo el mundo seguirá pensando que eres la
persona a cargo.
Es un gran trabajo si puedes descifrarlo.

View File

@ -0,0 +1,133 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/submit-checklist.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
.. _sp_submitchecklist:
Lista de comprobación para enviar parches del kernel de Linux
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Aquí hay algunas cosas básicas que los desarrolladores deben hacer si
quieren que sus envíos de parches del kernel sean aceptados más
rápidamente.
Todo esto está más allá de la documentación que se proporciona en
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`
y en otros lugares con respecto al envío de parches del kernel de Linux.
1) Si utiliza una funcionalidad, #include el archivo que define/declara
esa funcionalidad. No dependa de otros archivos de encabezado que
extraigan los que utiliza.
2) Compile limpiamente:
a) Con las opciones ``CONFIG`` aplicables o modificadas ``=y``, ``=m``,
y ``=n``. Sin advertencias/errores del compilador ``gcc``, ni
advertencias/errores del linker.
b) Aprobar ``allnoconfig``, ``allmodconfig``
c) Compila correctamente cuando se usa ``O=builddir``
d) Cualquier documentación o cambios se compilan correctamente sin
nuevas advertencias/errores. Utilice ``make htmldocs`` o
``make pdfdocs`` para comprobar la compilación y corregir cualquier
problema.
3) Se compila en varias arquitecturas de CPU mediante herramientas de
compilación cruzada locales o alguna otra granja de compilación.
4) ppc64 es una buena arquitectura para verificar la compilación cruzada
por que tiende a usar ``unsigned long`` para cantidades de 64-bits.
5) Verifique su parche para el estilo general según se detalla en
:ref:`Documentation/translations/sp_SP/process/coding-style.rst <sp_codingstyle>`.
Verifique las infracciones triviales con el verificador de estilo de
parches antes de la entrega (``scripts/checkpatch.pl``).
Debería ser capaz de justificar todas las infracciones que permanezcan
en su parche.
6) Cualquier opción ``CONFIG`` nueva o modificada no altera el menú de
configuración y se desactiva por defecto, a menos que cumpla con los
criterios de excepción documentados en
``Documentation/kbuild/kconfig-language.rst`` Atributos del menú: valor por defecto.
7) Todas las nuevas opciones de ``Kconfig`` tienen texto de ayuda.
8) Ha sido revisado cuidadosamente con respecto a las combinaciones
relevantes de ``Kconfig``. Esto es muy difícil de hacer correctamente
con las pruebas -- la concentración mental da resultados aquí.
9) Verifique limpiamente con sparse.
10) Use ``make checkstack`` y solucione cualquier problema que encuentre.
.. note::
``checkstack`` no señala los problemas explícitamente, pero
cualquier función que use más de 512 bytes en la pila es
candidata para el cambio.
11) Incluya :ref:`kernel-doc <kernel_doc>` para documentar las API
globales del kernel. (No es necesario para funciones estáticas, pero
también está bien.) Utilice ``make htmldocs`` o ``make pdfdocs``
para comprobar el :ref:`kernel-doc <kernel_doc>` y solucionar
cualquier problema.
12) Ha sido probado con ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``
``CONFIG_PROVE_RCU`` y ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` todos
habilitados simultáneamente.
13) Ha sido probado en tiempo de compilación y ejecución con y sin
``CONFIG_SMP`` y ``CONFIG_PREEMPT``.
14) Todas las rutas de código se han ejercido con todas las
características de lockdep habilitadas.
15) Todas las nuevas entradas de ``/proc`` están documentadas en
``Documentation/``.
16) Todos los nuevos parámetros de arranque del kernel están documentados
en ``Documentation/admin-guide/kernel-parameters.rst``.
17) Todos los nuevos parámetros del módulo están documentados con
``MODULE_PARM_DESC()``.
18) Todas las nuevas interfaces de espacio de usuario están documentadas
en ``Documentation/ABI/``. Consulte ``Documentation/ABI/README`` para
obtener más información. Los parches que cambian las interfaces del
espacio de usuario deben ser CCed a linux-api@vger.kernel.org.
19) Se ha comprobado con la inyección de al menos errores de asignación
de slab y página. Consulte ``Documentation/fault-injection/``.
Si el nuevo código es sustancial, la adición de la inyección de
errores específica del subsistema podría ser apropiada.
20) El nuevo código añadido ha sido compilado con ``gcc -W`` (use
``make KCFLAGS=-W``). Esto generara mucho ruido per es buena para
encontrar errores como "warning: comparison between signed and unsigned".
21) Se prueba después de que se haya fusionado en el conjunto de
parches -mm para asegurarse de que siga funcionando con todos los
demás parches en cola y varios cambios en VM, VFS y otros subsistemas.
22) Todas las barreras de memoria {p.ej., ``barrier()``, ``rmb()``,
``wmb()``} necesitan un comentario en el código fuente que explique
la lógica de lo que están haciendo y por qué.
23) Si se añaden algún ioctl en el parche, actualice también
``Documentation/userspace-api/ioctl/ioctl-number.rst``.
24) Si su código fuente modificado depende o utiliza cualquiera de las
API o características del kernel que están relacionadas con los
siguientes símbolos ``Kconfig`` entonces pruebe varias compilaciones
con los símbolos ``Kconfig`` relacionados deshabilitados y/o ``=m``
(si esa opción esta disponible) [no todos estos al mismo tiempo, solo
varias/aleatorias combinaciones de ellos]:
``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``
``CONFIG_NET``, ``CONFIG_INET=n`` (pero luego con ``CONFIG_NET=y``).

View File

@ -0,0 +1,155 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../../disclaimer-zh_CN.rst
:Original: Documentation/arch/riscv/boot.rst
:翻译:
龙进 Jin Long <longjin@dragonos.org>
========================
RISC-V内核启动要求和限制
========================
:Author: Alexandre Ghiti <alexghiti@rivosinc.com>
:Date: 23 May 2023
这份文档描述了RISC-V内核对引导加载程序和固件的期望以及任何开发者在接触
早期启动过程时必须牢记的约束。在这份文档中, ``早期启动过程`` 指的是在最
终虚拟映射设置之前运行的任何代码。
内核预加载的要求和限制
======================
RISC-V内核对引导加载程序和平台固件有以下要求
寄存器状态
----------
RISC-V内核期望
* ``$a0`` 应包含当前核心的hartid。
* ``$a1`` 应包含内存中设备树的地址。
CSR 寄存器状态
--------------
RISC-V内核期望
* ``$satp = 0`` 如果存在MMU必须将其禁用。
为常驻固件保留的内存
--------------------
RISC-V内核在直接映射中不能映射任何常驻内存或用PMPs保护的内存
因此固件必须根据设备树规范 和/或 UEFI规范正确标记这些区域。
内核的位置
----------
RISC-V内核期望被放置在PMD边界对于rv64为2MB对齐对于rv32为4MB对齐
请注意如果不是这样EFI stub 将重定位内核。
硬件描述
--------
固件可以将设备树或ACPI表传递给RISC-V内核。
设备树可以直接从前一阶段通过$a1寄存器传递给内核或者在使用UEFI启动时
可以通过EFI配置表传递。
ACPI表通过EFI配置表传递给内核。在这种情况下EFI stub 仍然会创建一个
小的设备树。请参阅下面的"EFI stub 和设备树"部分,了解这个设备树的详细
信息。
内核入口
--------
在SMP系统中有两种方法可以进入内核
- ``RISCV_BOOT_SPINWAIT``固件在内核中释放所有的hart一个hart赢
得抽奖并执行早期启动代码而其他的hart则停在那里等待初始化完成。这种
方法主要用于支持没有SBI HSM扩展和M模式RISC-V内核的旧固件。
- ``有序启动``固件只释放一个将执行初始化阶段的hart然后使用SBI HSM
扩展启动所有其他的hart。有序启动方法是启动RISC-V内核的首选启动方法
因为它可以支持CPU热插拔和kexec。
UEFI
----
UEFI 内存映射
~~~~~~~~~~~~~
使用UEFI启动时RISC-V内核将只使用EFI内存映射来填充系统内存。
UEFI固件必须解析 ``/reserved-memory`` 设备树节点的子节点,并遵守设备
树规范,将这些子节点的属性( ``no-map````reusable`` )转换为其正
确的EFI等价物参见设备树规范v0.4-rc1的"3.5.4/reserved-memory和
UEFI"部分)。
RISCV_EFI_BOOT_PROTOCOL
~~~~~~~~~~~~~~~~~~~~~~~
使用UEFI启动时EFI stub 需要引导hartid以便将其传递给 ``$a1`` 中的
RISC-V内核。EFI stub使用以下方法之一获取引导hartid
- ``RISCV_EFI_BOOT_PROTOCOL`` **首选**)。
- ``boot-hartid`` 设备树子节点(**已弃用**)。
任何新的固件都必须实现 ``RISCV_EFI_BOOT_PROTOCOL``,因为基于设备树
的方法现已被弃用。
早期启动的要求和约束
====================
RISC-V内核的早期启动过程遵循以下约束
EFI stub 和设备树
-----------------
使用UEFI启动时EFI stub 会用与arm64相同的参数补充或创建设备树
这些参数在Documentation/arch/arm/uefi.rst中的
"UEFI kernel supporton ARM"段落中有描述。
虚拟映射安装
------------
在RISC-V内核中虚拟映射的安装分为两步进行
1. ``setup_vm()````early_pg_dir`` 中安装一个临时的内核映射,这
允许发现系统内存。 此时只有内核文本/数据被映射。在建立这个映射时,
不能进行分配(因为系统内存还未知),所以``early_pg_dir``页表是静
态分配的(每个级别只使用一个表)。
2. ``setup_vm_final()````swapper_pg_dir`` 中创建最终的内核映
射,并利用发现的系统内存 创建线性映射。在建立这个映射时,内核可以
分配内存但不能直接访问它因为直接映射还不存在所以它使用fixmap
区域的临时映射来访问新分配的页表级别。
为了让 ``virt_to_phys()````phys_to_virt()`` 能够正确地将直接
映射地址转换为物理地址它们需要知道DRAM的起始位置。这发生在步骤1之后
就在步骤2安装直接映射之前参见arch/riscv/mm/init.c中的
``setup_bootmem()`` 函数)。在安装最终虚拟映射之前使用这些宏时必须
仔细检查。
通过fixmap进行设备树映射
------------------------
由于 ``reserved_mem`` 数组是用 ``setup_vm()`` 建立的虚拟地址初始化
的,并且与``setup_vm_final()``建立的映射一起使用RISC-V内核使用
fixmap区域来映射设备树。这确保设备树可以通过两种虚拟映射访问。
Pre-MMU执行
-----------
在建立第一个虚拟映射之前,需要运行一些代码。这些包括第一个虚拟映射的安装本身,
早期替代方案的修补,以及内核命令行的早期解析。这些代码必须非常小心地编译,因为:
- ``-fno-pie``:这对于使用``-fPIE``的可重定位内核是必需的,否则,任何对
全局符号的访问都将通过 GOT进行而GOT只是虚拟地重新定位。
- ``-mcmodel=medany``任何对全局符号的访问都必须是PC相对的以避免在设
置MMU之前发生任何重定位。
- *所有* 的仪表化功能也必须被禁用包括KASANftrace和其他
由于使用来自不同编译单元的符号需要用这些标志编译该单元,我们建议尽可能不要使用
外部符号。

View File

@ -17,6 +17,7 @@ RISC-V 体系结构
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
boot
boot-image-header boot-image-header
vm-layout vm-layout
patch-acceptance patch-acceptance

View File

@ -100,7 +100,7 @@ printk()的用法通常是这样的::
为了调试,还有两个有条件编译的宏: 为了调试,还有两个有条件编译的宏:
pr_debug()和pr_devel(),除非定义了 ``DEBUG`` (或者在pr_debug()的情况下定义了 pr_debug()和pr_devel(),除非定义了 ``DEBUG`` (或者在pr_debug()的情况下定义了
``CONFIG_DYNAMIC_DEBUG`` ),否则它们会被编译。 ``CONFIG_DYNAMIC_DEBUG`` ),否则它们会被编译。
函数接口 函数接口

View File

@ -14,11 +14,8 @@
有关测试专用工具的简要概述,参见 有关测试专用工具的简要概述,参见
Documentation/translations/zh_CN/dev-tools/testing-overview.rst Documentation/translations/zh_CN/dev-tools/testing-overview.rst
.. class:: toc-title
目录
.. toctree:: .. toctree::
:caption: 目录
:maxdepth: 2 :maxdepth: 2
testing-overview testing-overview

View File

@ -3,7 +3,7 @@
.. include:: ../disclaimer-zh_CN.rst .. include:: ../disclaimer-zh_CN.rst
:Original: Documentation/dev-tools/testing-overview.rst :Original: Documentation/dev-tools/testing-overview.rst
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com> :Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
============ ============
内核测试指南 内核测试指南

View File

@ -14,9 +14,8 @@
通用型输入/输出GPIO 通用型输入/输出GPIO
======================= =======================
目录:
.. toctree:: .. toctree::
:caption: 目录
:maxdepth: 2 :maxdepth: 2
legacy legacy

View File

@ -17,11 +17,8 @@ Linux驱动实现者的API指南
内核提供了各种各样的接口来支持设备驱动的开发。这份文档只是对其中一些接口进行了 内核提供了各种各样的接口来支持设备驱动的开发。这份文档只是对其中一些接口进行了
一定程度的整理——希望随着时间的推移,它能变得更好!可用的小节可以在下面看到。 一定程度的整理——希望随着时间的推移,它能变得更好!可用的小节可以在下面看到。
.. class:: toc-title
目录列表:
.. toctree:: .. toctree::
:caption: 目录列表
:maxdepth: 2 :maxdepth: 2
gpio/index gpio/index

View File

@ -8,9 +8,10 @@
内核开发过程指南 内核开发过程指南
================ ================
内容: 本文档的目的是帮助开发人员及其经理以最小的挫折感与开发社区合作。它试图记录这个社区如何以一种不熟悉Linux内核开发或者实际上是自由软件开发的人可以访问的方式工作。虽然这里有一些技术资料但这是一个面向过程的讨论不需要深入了解内核编程就可以理解。
.. toctree:: .. toctree::
:caption: 内容
:numbered: :numbered:
:maxdepth: 2 :maxdepth: 2
@ -22,5 +23,3 @@
6.Followthrough 6.Followthrough
7.AdvancedTopics 7.AdvancedTopics
8.Conclusion 8.Conclusion
本文档的目的是帮助开发人员及其经理以最小的挫折感与开发社区合作。它试图记录这个社区如何以一种不熟悉Linux内核开发或者实际上是自由软件开发的人可以访问的方式工作。虽然这里有一些技术资料但这是一个面向过程的讨论不需要深入了解内核编程就可以理解。

View File

@ -5,10 +5,11 @@
.. include:: ../disclaimer-zh_CN.rst .. include:: ../disclaimer-zh_CN.rst
:Original: :ref:`Documentation/process/index.rst <process_index>` :Original: Documentation/process/index.rst
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
.. _cn_process_index: :翻译:
Alex Shi <alex.shi@linux.alibaba.com>
======================== ========================
与Linux 内核社区一起工作 与Linux 内核社区一起工作
@ -23,29 +24,55 @@
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
license-rules
howto howto
code-of-conduct code-of-conduct
code-of-conduct-interpretation code-of-conduct-interpretation
development-process
submitting-patches submitting-patches
programming-language programming-language
coding-style coding-style
development-process maintainer-pgp-guide
email-clients email-clients
license-rules
kernel-enforcement-statement kernel-enforcement-statement
kernel-driver-statement kernel-driver-statement
TODOLIST:
* handling-regressions
* maintainer-handbooks
安全方面, 请阅读:
.. toctree::
:maxdepth: 1
embargoed-hardware-issues
TODOLIST:
* security-bugs
其它大多数开发人员感兴趣的社区指南: 其它大多数开发人员感兴趣的社区指南:
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
submit-checklist
stable-api-nonsense stable-api-nonsense
stable-kernel-rules
management-style management-style
embargoed-hardware-issues stable-kernel-rules
submit-checklist
TODOLIST:
* changes
* kernel-docs
* deprecated
* maintainers
* researcher-guidelines
* contribution-maturity-model
这些是一些总体性技术指南,由于不大好分类而放在这里: 这些是一些总体性技术指南,由于不大好分类而放在这里:
@ -54,6 +81,16 @@
magic-number magic-number
volatile-considered-harmful volatile-considered-harmful
../arch/riscv/patch-acceptance
../core-api/unaligned-memory-access
TODOLIST:
* applying-patches
* backporting
* adding-syscalls
* botching-up-ioctls
* clang-format
.. only:: subproject and html .. only:: subproject and html

View File

@ -1,58 +1,67 @@
.. _cn_magicnumbers:
.. include:: ../disclaimer-zh_CN.rst .. include:: ../disclaimer-zh_CN.rst
:Original: :ref:`Documentation/process/magic-number.rst <magicnumbers>` :Original: Documentation/process/magic-number.rst
如果想评论或更新本文的内容请直接发信到LKML。如果你使用英文交流有困难的话也可 :翻译:
以向中文版维护者求助。如果本翻译更新不及时或者翻译存在问题,请联系中文版维护者::
中文版维护者: 贾威威 Jia Wei Wei <harryxiyou@gmail.com> 贾威威 Jia Wei Wei <harryxiyou@gmail.com>
中文版翻译者: 贾威威 Jia Wei Wei <harryxiyou@gmail.com>
中文版校译者: 贾威威 Jia Wei Wei <harryxiyou@gmail.com> :校译:
司延腾 Yanteng Si <siyanteng@loongson.cn>
Linux 魔术数 Linux 魔术数
============ ============
这个文件是有关当前使用的魔术值注册表。当你给一个结构添加了一个魔术值,你也应该把这个魔术值添加到这个文件,因为我们最好把用于各种结构的魔术值统一起来。 这个文件是有关当前使用的魔术值注册表。当你给一个结构体添加了一个魔术值,你也
应该把这个魔术值添加到这个文件,因为我们最好把用于各种结构体的魔术值统一起来。
使用魔术值来保护内核数据结构是一个非常好的主意。这就允许你在运行期检查(a)一个结构是否已经被攻击,或者(b)你已经给一个例行程序通过了一个错误的结构。后一种情况特别地有用---特别是当你通过一个空指针指向结构体的时候。tty源码例如经常通过特定驱动使用这种方法并且反复地排列特定方面的结构。 使用魔术值来保护内核数据结构是一个 **非常好的主意** 。这就允许你在运行时检
查一个结构体(a)是否已经被攻击,或者(b)你已经给一个例程传递了一个错误的结构
体。最后一种情况特别地有用---特别是当你通过一个空指针指向结构体的时候。例如,
tty源码经常通过特定驱动使用这种方法用来反复地排列特定方面的结构体。
使用魔术值的方法是在结构的开始处声明的,如下:: 使用魔术值的方法是在结构体的开头声明它们,如下::
struct tty_ldisc { struct tty_ldisc {
int magic; int magic;
... ...
}; };
当你以后给内核添加增强功能的时候,请遵守这条规则!这样就会节省数不清的调试时间,特别是一些古怪的情况,例如,数组超出范围并且重新写了超出部分。遵守这个规则,这些情况可以被快速地,安全地避免。 当你以后给内核添加增强功能的时候,请遵守这条规则!这样就会节省数不清的调试
时间,特别是一些古怪的情况,例如,数组超出范围并且覆盖写了超出部分。利用这
个规则,这些情况可以被快速地,安全地检测到这些案例。
Theodore Ts'o 变更日志::
31 Mar 94
给当前的Linux 2.1.55添加魔术表。 Theodore Ts'o
31 Mar 94
Michael Chastain 给当前的Linux 2.1.55添加魔术表。
<mailto:mec@shout.net>
22 Sep 1997
现在应该最新的Linux 2.1.112.因为在特性冻结期间不能在2.2.x前改变任何东西。这些条目被数域所排序。 Michael Chastain
<mailto:mec@shout.net>
22 Sep 1997
Krzysztof G.Baranowski 现在应该最新的Linux 2.1.112.因为在特性冻结期间不能在2.2.x前改变任
<mailto: kgb@knm.org.pl> 何东西。这些条目被数域所排序。
29 Jul 1998
更新魔术表到Linux 2.5.45。刚好越过特性冻结但是有可能还会有一些新的魔术值在2.6.x之前融入到内核中。 Krzysztof G.Baranowski
<mailto: kgb@knm.org.pl>
29 Jul 1998
Petr Baudis 更新魔术表到Linux 2.5.45。刚好越过特性冻结,但是有可能还会有一些新的魔
<pasky@ucw.cz> 术值在2.6.x之前融入到内核中。
03 Nov 2002
更新魔术表到Linux 2.5.74。 Petr Baudis
<pasky@ucw.cz>
03 Nov 2002
Fabian Frederick 更新魔术表到Linux 2.5.74。
<ffrederick@users.sourceforge.net>
09 Jul 2003 Fabian Frederick
<ffrederick@users.sourceforge.net>
09 Jul 2003
===================== ================ ======================== ========================================== ===================== ================ ======================== ==========================================
魔术数名 数字 结构 文件 魔术数名 数字 结构 文件

View File

@ -0,0 +1,789 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-zh_CN.rst
:Original: Documentation/process/maintainer-pgp-guide.rst
:翻译:
司延腾 Yanteng Si <siyanteng@loongson.cn>
:校译:
===================
内核维护者 PGP 指南
===================
:作者: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
本文档面向 Linux 内核开发者特别是子系统维护人员。文档中含有Linux 基金
会发布的更通用的 `保护代码完整性`_ 指南中讨论的内容子集。阅读该文档,以更
深入地讨论本指南中提到的一些主题。
.. _`保护代码完整性`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md
PGP 在 Linux 内核开发中的作用
=============================
PGP 有助于确保 Linux 内核开发社区产出代码的完整性,并在较小程度上,通过
PGP 签名的电子邮件交换,在开发者之间建立可信的交流渠道。
Linux 内核源代码主要有两种(维护)方式:
- 分布式源仓库 (git)
- 定期发布快照 (tarballs)
git 仓库和 tarball 都带有创建官方内核版本的内核开发者的 PGP 签名。这
些签名提供了加密保证,即保证 kernel.org 或任何其他镜像提供的可下载版本
与这些开发者在其工作站上的版本相同。为此:
- git 仓库在所有标签上提供 PGP 签名
- tarball 为所有下载提供独立的 PGP 签名
信任开发者,不要信基础设施
--------------------------
自从 2011 年 kernel.org 核心系统遭到入侵以来,内核存档项目的主要运行原
则就是假定基础设施的任何部分都可能随时受到入侵。因此,管理员特意采取措施,
强调必须始终信任开发者,不能信任代码托管基础设施,无论后者的安全实践有多好。
上述指导原则正是需要本指南的原因。希望确保通过对开发者的信任,我们不会简
单地将未来潜在安全事件的责任归咎于其他人。目的是提供一套指导开发者可以用
来创建安全的工作环境并保护用于建立 Linux 内核本身完整性的 PGP 密钥。
PGP 工具
========
使用 GnuPG 2.2 或更高版本
-------------------------
默认情况下,你的发行版应该已经安装了 GnuPG你只需要验证你使用的是相当新的
版本即可。要检查,请运行::
$ gpg --version | head -n1
如果你有 2.2 或更高版本,那么你就可以开始了。如果你的版本早于 2.2,则本指
南中的某些命令可能不起作用。
配置 gpg-agent 选项
~~~~~~~~~~~~~~~~~~~
GnuPG agent是一个辅助工具每当你使用该命令时它都会自动启动gpg并在
后台运行,目的是缓存私钥密码。你应该知道两个选项,以便调整密码何时从缓存
过期:
- ``default-cache-ttl`` (秒): 如果在生命周期结束之前再次使用相同的
密钥,倒计时将重置为另一段时间。默认值为 60010 分钟)。
- ``max-cache-ttl`` (秒): 无论你自输入初始密码以来多久使用过密钥,
如果最大生存时间倒计时结束,你都必须再次输入密码。默认值为 30 分钟。
如果你发现这些默认值太短(或太长),你可以编辑 ``~/.gnupg/gpg-agent.conf``
文件以设置你自己的值::
# 常规ttl设置为30分钟最大ttl设置为2小时
default-cache-ttl 1800
max-cache-ttl 7200
.. note::
不需要在 shell 会话开始时手动启动 gpg-agent。你可能需要检查
rc 文件来删除旧版本 GnuPG 中的所有内容,因为它可能不再做正确
的事情。
保护你的 PGP 密钥
=================
本指南假定你已经拥有用于 Linux 内核开发目的的 PGP 密钥。如果你还没
有,请参阅前面提到的 "`保护代码完整性`_" 文档,以获取有关如何创建新
密钥的指导。
如果你当前的密钥低于 2048 位 (RSA),你还应该创建一个新密钥。
了解 PGP 子密钥
---------------
PGP 密钥很少由单个密钥对组成 - 通常它是独立子密钥的集合,这些子密钥
可根据其功能用于不同的目的并在创建时分配。PGP 定义了密钥可以具有的
四种功能:
- **[S]** 密钥可用于签名
- **[E]** 密钥可用于加密
- **[A]** 密钥可用于身份验证
- **[C]** 密钥可用于验证其他密钥
具有 **[C]** 功能的密钥通常称为“主”密钥,但该术语具有误导性,因为
它意味着可以使用Certify密钥来代替同一链上的任何其他子密钥如物理
“主密钥”可用于打开为其他钥匙制作的锁)。由于情况并非如此,本指南将
其称为“认证密钥”以避免任何歧义。
充分理解以下内容至关重要:
1. 所有子项彼此完全独立。如果你丢失了私有子密钥,则无法从链上的任何
其他私钥恢复或重新创建它。
2. 除 Certify 密钥外,可以有多个具有相同功能的子密钥(例如,你可
以有 2 个有效的加密子密钥、3 个有效的签名子密钥,但只有 1 个有
效的认证子密钥)。所有子密钥都是完全独立的——加密到一个 **[E]**
子密钥的信息messages无法使用你可能拥有的任何其他 **[E]**
子密钥解密。
3. 单个子密钥可能具有多种功能(例如,你的 **[C]** 密钥也可以是你
**[S]** 密钥)。
携带 **[C]** (证明)能力的密钥是唯一可以用来指示与其他密钥的关系
的密钥。仅 **[C]** 密钥可用于:
- 添加或撤销具有 S/E/A 功能的其他密钥(子密钥)
- 添加、更改或撤销与密钥关联的身份 (uid)
- 添加或更改其本身或任何子密钥的到期日期
- 出于信任网络的目的签署其他人的密钥
默认情况下GnuPG 在生成新密钥时创建以下内容:
- 一个子密钥同时具有认证和签名功能 (**[SC]**)
- 具有加密功能的单独子密钥 (**[E]**)
如果你在生成密钥时使用了默认参数,那么这就是你将得到的。你可以通过
运行命令来验证,例如: ``gpg --list-secret-keys``
::
sec ed25519 2022-12-20 [SC] [expires: 2024-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
uid [ultimate] Alice Dev <adev@kernel.org>
ssb cv25519 2022-12-20 [E] [expires: 2024-12-19]
``sec`` 这行下面长长的一行就是你的密钥指纹-无论在下文任何地方
看到 ``[fpr]`` 都指的是这40个字符。
确保你的密码强度高
------------------
GnuPG 在将私钥存储到磁盘之前使用密码对其进行加密。这样,即使你的
``.gnupg`` 目录全部泄露或被盗,攻击者在没有事先获取密码来解密的
情况下也无法使用你的私钥。
你的私钥受到强密码保护是绝对必要的。要设置或更改它,请使用::
$ gpg --change-passphrase [fpr]
创建一个单独的签名子密钥
------------------------
我们的目的是通过将你的证书密钥移动到离线媒介来保护它,因此如果你只
有组合的 **[SC]** 密钥,那么你应该创建一个单独的签名子密钥::
$ gpg --quick-addkey [fpr] ed25519 sign
.. note:: GnuPG 中的 ECC 支持
请注意,如果你打算使用不支持 ED25519 ECC 密钥的硬件密钥,则
应选择“nistp256”或“ed25519”。请参阅下面有关推荐硬件设备的
部分。
备份你的证书密钥以进行灾难恢复
------------------------------
你的 PGP 密钥上来自其他开发者的签名越多,出于灾难恢复的原因,你就越
有理由创建一个位于数字媒体之外的备份版本。
创建私钥的可打印硬拷贝的最佳方法是使用 ``paperkey`` 为此目的编写
的软件。有关输出格式及其相对于其他解决方案的优势的更多详细信息,请参
``paperkey`` 参考资料。大多数发行版都应该已经打包了 Paperkey。
运行以下命令来创建私钥的硬拷贝备份::
$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt
打印出该文件(或将输出直接传输到 lpr然后用笔在纸的边缘写下你的密
码。 **强烈建议这样做**,因为密钥打印输出仍然使用该密码进行加密,并且
如果你更改了它,你将不记得创建备份时它曾经是什么 - *保证*
将生成的打印输出和手写密码放入信封中,并存放在安全且受到良好保护的地
方,最好远离你的家,例如银行保险柜。
.. note::
你的打印机可能不再是连接到并行端口的简单哑设备,但由于输出仍然使
用你的密码进行加密,因此即使“云端打印”的现代打印机也应该保持相
对安全的操作
备份整个 GnuPG 目录
-------------------
.. warning::
**!!!不要跳过这个步骤!!!**
如果你需要恢复 PGP 密钥,拥有一个随时可用的备份非常重要。这与我们
所做的灾难级准备不同 ``paperkey`` 。每当你需要使用你的证书密钥时,
例如在会议和峰会后更改你自己的密钥或签署其他人的密钥时,你还将依赖
这些外部副本。
首先获取一个小型 USB “拇指” 驱动器(最好是两个!),用于备份目的。
你需要使用 LUKS 对其进行加密——请参阅你的发行版文档以了解如何完成
此操作。
对于加密密码,你可以使用与 PGP 密钥相同的密码。
加密过程完成后,重新插入 USB 驱动器并确保其正确安装。将整个 ``.gnupg``
目录复制到加密存储::
$ cp -a ~/.gnupg /media/disk/foo/gnupg-backup
你现在应该测试一下,确保一切依然能正常工作::
$ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]
如果没有出现任何错误,那么就可以开始了。卸下 USB 驱动器,给它贴上
明显的标签,这样下次需要使用随机 USB 驱动器时就不会把它吹走,然后
放在安全的地方 - 但不要太远,因为你每次都需要使用它时不时地用于诸
如编辑身份、添加或撤销子密钥或签署其他人的密钥之类的事情。
从你的 homedir 中删除 Certify 密钥
----------------------------------
我们的主目录中的文件并没有我们想象的那么受到保护。它们可以通过多种
不同的方式泄露或被盗:
- 在制作快速主目录备份以设置新工作站时意外发生
- 系统管理员的疏忽或恶意
- 通过不安全的备份
- 通过桌面应用程序浏览器、pdf 查看器等)中的恶意软件
- 跨越国界时通过胁迫
使用良好的密码短语保护你的密钥极大地有助于降低上述任何风险,但密码
短语可以通过键盘记录器、肩窥或任何其他方式发现。因此,建议的设置是
从主目录中删除你的证书密钥并将其存储在离线存储中。
.. warning::
请参阅上一节并确保你已完整备份 GnuPG 目录。如果你没有可用的
备份,我们要做的事情将使你的密钥毫无用处!
首先确定你的证书密钥的keygrip::
$ gpg --with-keygrip --list-key [fpr]
输出将是这样的::
pub ed25519 2022-12-20 [SC] [expires: 2022-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
Keygrip = 1111000000000000000000000000000000000000
uid [ultimate] Alice Dev <adev@kernel.org>
sub cv25519 2022-12-20 [E] [expires: 2022-12-19]
Keygrip = 2222000000000000000000000000000000000000
sub ed25519 2022-12-20 [S]
Keygrip = 3333000000000000000000000000000000000000
找到该线 ``pub`` 下方的keygrip项 (位于“认证密钥指纹”的正下方)。
这将直接对应于你``~/.gnupg`` 目录中的一个文件::
$ cd ~/.gnupg/private-keys-v1.d
$ ls
1111000000000000000000000000000000000000.key
2222000000000000000000000000000000000000.key
3333000000000000000000000000000000000000.key
你所要做的只是删除与证书密钥 keygrip 对应的 .key 文件::
$ cd ~/.gnupg/private-keys-v1.d
$ rm 1111000000000000000000000000000000000000.key
现在,如果你发出命令 ``--list-secret-keys`` ,它将显示证书密钥丢
失( 表示 ``#`` 它不可用)::
$ gpg --list-secret-keys
sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
uid [ultimate] Alice Dev <adev@kernel.org>
ssb cv25519 2022-12-20 [E] [expires: 2024-12-19]
ssb ed25519 2022-12-20 [S]
你还应该删除 ``~/.gnupg``目录中的所有 ``secring.gpg`` 文件 ,这些
文件可能是以前版本的 GnuPG 留下的。
如果你没有“private-keys-v1.d”目录
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果你没有 ``~/.gnupg/private-keys-v1.d`` 目录,那么你的密钥仍存
储在 GnuPG v1 使用的旧文件 ``secring.gpg`` 中。对密钥进行任何更改
(例如更改密码或添加子密钥)应该会自动转换旧 ``secring.gpg`` 格式以
供使用 ``private-keys-v1.d``
完成此操作后,请确保删除过时的 ``secring.gpg`` 文件,其中仍然包含你
的私钥。
将子密钥移至专用加密设备
========================
尽管 Certify 密钥现在不会被泄露或被盗,但子密钥仍然位于你的主目录中。
任何设法获得这些内容的人都将能够解密你的通信或伪造你的签名(如果他们知
道密码)。此外,每次执行 GnuPG 操作时,密钥都会加载到系统内存中,并
可能被足够高级的恶意软件(例如 Meltdown 和 Spectre从那里窃取。
完全保护密钥的最佳方法是将它们转移到能够进行智能卡操作的专用硬件设备上。
智能卡的好处
------------
智能卡包含一个加密芯片,能够存储私钥并直接在卡本身上执行加密操作。由于
密钥内容永远不会离开智能卡,因此插入硬件设备的计算机的操作系统无法自行
检索私钥。这与我们之前用于备份目的的加密 USB 存储设备有很大不同——当
USB 设备插入并安装时,操作系统能够访问私钥内容。
使用外部加密 USB 介质并不能替代具有智能卡功能的设备。
可用的智能卡设备
----------------
除非你的所有笔记本电脑和工作站都有智能卡读卡器,否则最简单的方法是获
取实现智能卡功能的专用 USB 设备。有多种选择::
- `Nitrokey Start`_: 开放硬件和免费软件日本基于FSI的 `Gnuk`
少数支持 ED25519 ECC 密钥的商用设备之一,但提供的安全功能最少
(例如防篡改或某些旁路攻击)。
- `Nitrokey Pro 2`_: 与 Nitrokey Start 类似,但更防篡改并提供
更多安全功能。Pro 2 支持 ECC 加密 (NISTP)。
- `Yubikey 5`_: 专有硬件和软件,但比 Nitrokey Pro 便宜,并且以
USB-C 形式提供,对于较新的笔记本电脑更有用。提供额外的安全功能,
例如 FIDO U2F 等,现在终于支持 NISTP 和 ED25519 ECC 密钥。
你的选择将取决于成本、你所在地理区域的货运便利性以及开放/专有硬件考虑
因素。
.. note::
如果你位列于 MAINTAINERS 中或在 kernel.org 上拥有帐户,则你有
资格获得Linux 基金会提供的_`qualify for a free Nitrokey Start`
.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6
.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3
.. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/
.. _Gnuk: https://www.fsij.org/doc-gnuk/
.. _`qualify for a free Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html
配置你的智能卡设备
------------------
当你将智能卡设备插入任何现代 Linux 工作站时,它就应该可以正常工作
(TM)。你可以通过运行来验证它::
$ gpg --card-status
如果你看到完整的智能卡详细信息,那么你就可以开始了。不幸的是,对所有
可能无法正常工作的原因进行故障排除超出了本指南的范围。如果你在使该卡
与 GnuPG 配合使用时遇到问题,请通过常规支持渠道寻求帮助。
要配置你的智能卡,你需要使用 GnuPG 菜单系统,因为没有方便的命令行开
关::
$ gpg --card-edit
[...omitted...]
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
你应该设置用户 PIN (1)、管理员 PIN (3) 和重置代码 (4)。请确保将
这些信息记录并存储在安全的地方,尤其是管理员 PIN 码和重置代码(它允
许你完全擦除智能卡)。你很少需要使用管理员 PIN 码,如果你不记录它,
你将不可避免地忘记它是什么。
回到主卡菜单,你还可以设置其他值(例如姓名、性别、登录数据等),但这
不是必需的,并且如果你丢失智能卡,还会泄露有关智能卡的信息。
.. note::
尽管名称为“PIN”但卡上的用户 PIN 和管理员 PIN 都不需要是数字。
.. warning::
某些设备可能要求你将子密钥移至设备上,然后才能更改密码。请检查设
备制造商提供的文档。
将子密钥移至你的智能卡
----------------------
退出卡菜单使用“q”并保存所有更改。接下来让我们将子密钥移至智能卡
上。对于大多数操作,你将需要 PGP 密钥密码和卡的管理员 PIN::
$ gpg --edit-key [fpr]
Secret subkeys are available.
pub ed25519/AAAABBBBCCCCDDDD
created: 2022-12-20 expires: 2024-12-19 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/1111222233334444
created: 2022-12-20 expires: never usage: E
ssb ed25519/5555666677778888
created: 2017-12-07 expires: never usage: S
[ultimate] (1). Alice Dev <adev@kernel.org>
gpg>
使用 ``--edit-key`` 使我们再次进入菜单模式,你会注意到按键列表有点
不同。从现在开始,所有命令都在此菜单模式内完成,如 所示 ``gpg>``
首先,让我们选择要放入卡上的密钥 - 你可以通过键入 ``key 1`` (它是
列表中的第一个, **[E]** 子密钥)来完成此操作:
gpg> key 1
在输出中,你现在在 **[E]** 子密钥应该看到 ``ssb*`` 。意味着这个子
密钥当前被选中。它用作切换键,这意味着如果你再次输入 ``key 1``
``*`` 将会消失并且该键将不再被选择。
现在,让我们将该密钥移至智能卡上::
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
由于它是我们的 **[E]** 密钥,因此将其放入加密槽中是有意义的。当你提
交选择时,系统将首先提示你输入 PGP 密钥密码,然后输入管理员 PIN 码。
如果命令返回且没有错误,则你的密钥已被移动。
**重要提示**:现在再次键入 ``key 1`` 以取消选择第一个键,并 ``key 2``
选择 **[S]** 密钥::
gpg> key 1
gpg> key 2
gpg> keytocard
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
你可以使用 **[S]** 密钥进行签名和身份验证,但我们希望确保它位于签名槽中,
因此选择 (1)。跟之前一样,如果你的命令返回且没有错误,则操作成功::
gpg> q
Save changes? (y/N) y
保存更改将删除你从主目录移动到卡上的密钥(但这没关系,因为我们还有备份,
让我们需要替换智能卡时再次执行此操作)。
验证密钥是否已移动
~~~~~~~~~~~~~~~~~~
如果你现在执行 ``--list-secret-keys`` ,你将看到输出中存在细微的差异::
$ gpg --list-secret-keys
sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
uid [ultimate] Alice Dev <adev@kernel.org>
ssb> cv25519 2022-12-20 [E] [expires: 2024-12-19]
ssb> ed25519 2022-12-20 [S]
``ssb>``中的 ``>`` 输出意味着子密钥只能在智能卡上可用,如果你返回
密钥目录并查看那里的内容,你会注意到 ``.key`` 那里的文件已被存根替换::
$ cd ~/.gnupg/private-keys-v1.d
$ strings *.key | grep 'private-key'
输出应包含 ``shadowed-private-key`` 指示这些文件只是存根,实际内容
位于智能卡上。
验证智能卡是否正常工作
~~~~~~~~~~~~~~~~~~~~~~
要验证智能卡是否按预期工作,你可以创建签名::
$ echo "Hello world" | gpg --clearsign > /tmp/test.asc
$ gpg --verify /tmp/test.asc
在你的第一条命令执行时应该会询问你智能卡的PIN然后在你运行
``gpg --verify`` 后显示"Good signature"。
恭喜,你已成功使窃取你的数字开发者身份变得极其困难!
其他常见的 GnuPG 操作
---------------------
以下是你需要使用 PGP 密钥执行的一些常见操作的快速参考。
安装你的安全离线存储
~~~~~~~~~~~~~~~~~~~~
你将需要你的证书密钥来执行以下任何操作,因此你首先需要安装备份离线存储
并告诉 GnuPG 使用它::
$ export GNUPGHOME=/media/disk/foo/gnupg-backup
$ gpg --list-secret-keys
你需要确保你看到 ``sec`` 而不是 ``sec#`` 在输出中( ``#`` 意味着
密钥不可用并且你仍在使用常规主目录位置)。
延长密钥有效期
~~~~~~~~~~~~~~
证书密钥的默认到期日期为自创建之日起 2 年。这样做既是出于安全原因,也
是为了使过时的密钥最终从密钥服务器中消失。
要将密钥的有效期从当前日期延长一年,只需运行::
$ gpg --quick-set-expire [fpr] 1y
如果更容易记住你也可以使用特定日期例如你的生日、1 月 1 日或加拿大
国庆日)::
$ gpg --quick-set-expire [fpr] 2025-07-01
请记住将更新后的密钥发送回密钥服务器::
$ gpg --send-key [fpr]
进行任何更改后更新你的工作目录
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
使用离线存储对密钥进行任何更改后,你需要将这些更改导入回常规工作目录
中::
$ gpg --export | gpg --homedir ~/.gnupg --import
$ unset GNUPGHOME
通过 ssh 使用 gpg-agent
~~~~~~~~~~~~~~~~~~~~~~~
如果你需要在远程系统上签署标签或提交,你可以通过 ssh 转发你的
gpg-agent。
请参考 GnuPG wiki 上提供的说明:
- `Agent通过SSH转发`_
如果你可以修改远程端的 sshd 服务器设置,则工作会更顺利。
.. _`Agent通过SSH转发`: https://wiki.gnupg.org/AgentForwarding
将 PGP 与 Git 结合使用
======================
Git 的核心功能之一是它的分散性——一旦将仓库克隆到你的系统,你就拥有该
项目的完整历史记录,包括其所有标签、提交和分支。然而,随着数百个克隆仓
库的出现,人们如何验证他们的 linux.git 副本没有被恶意第三方篡改?
或者如果在代码中发现后门并且提交中的“Author”行表示它是由你完成的
而你非常确定 `自己与它无关`_ ,会发生什么?
为了解决这两个问题Git 引入了 PGP 集成。签名的标签通过确保其内容与创
建标签的开发人员的工作站上的内容完全相同来证明仓库的完整性,而签名的提
交使其他人几乎不可能在无法访问你的 PGP 密钥的情况下冒充你。
.. _`自己与它无关`: https://github.com/jayphelps/git-blame-someone-else
配置 git 使用你的 PGP 密钥
--------------------------
如果你的密钥环中只有一个密钥,那么你实际上不需要执行任何额外操作,因为
它会成为你的默认密钥。但是,如果你碰巧有多个密钥,你可以告诉 git 应该
使用哪个密钥(``[fpr]`` 是你密钥的指纹)::
$ git config --global user.signingKey [fpr]
如何使用签名标签
----------------
要创建签名标签,只需将 ``-s`` 开关传递给 tag 命令::
$ git tag -s [tagname]
我们的建议是始终签署 git 标签,因为这可以让其他开发人员确保他们从中提
取的 git 仓库没有被恶意更改。
如何验证签名标签
~~~~~~~~~~~~~~~~
要验证签名标签,只需使用以下 ``verify-tag`` 命令::
$ git verify-tag [tagname]
如果你从项目仓库的另一个分支中拉取标签git 应该自动验证你拉取的顶
部的签名,并在合并操作期间向你显示结果::
$ git pull [url] tags/sometag
合并消息将包含如下内容::
Merge tag 'sometag' of [url]
[Tag message]
# gpg: Signature made [...]
# gpg: Good signature from [...]
如果你正在验证其他人的 git 标签,那么你将需要导入他们的 PGP 密钥。
请参阅下面的":ref:`身份验证`"部分。
配置 git 始终对带注释的标签annotated tags进行签名annotated tags
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果你要创建带注释的标签,你很可能会想要对其进行签名。要强制 git 始终签
署带注释的标签,你可以设置一个全局配置选项::
$ git config --global tag.forceSignAnnotated true
如何使用签名的提交
------------------
创建签名提交很容易,但在 Linux 内核开发中使用它们要困难得多,因为它依赖
于发送到邮件列表的补丁,并且此工作流程不保留 PGP 提交签名。此外,当重新
调整仓库以匹配上游时,甚至你自己的 PGP 提交签名最终也会被丢弃。因此,大
多数内核开发人员不会费心签署他们的提交,并且会忽略他们在工作中依赖的任何
外部仓库中的签名提交。
但是,如果你的工作 git 树在某些 git 托管服务kernel.org、
infradead.org、ozlabs.org 或其他)上公开可用,那么建议你签署所有 git
提交,即使上游开发人员不直接受益于这种做法。
我们推荐这样做的原因如下:
1. 如果需要执行代码取证或跟踪代码来源,即使是外部维护的带有 PGP 提交签名
的树对于此类问题也很有价值。
2. 如果你需要重新克隆本地仓库(例如,在磁盘故障后),这可以让你在恢复工
作之前轻松验证仓库的完整性。
3. 如果有人需要挑选你的提交,这可以让他们在应用之前快速验证其完整性。
创建签名提交
~~~~~~~~~~~~
要创建签名提交,你只需将 ``-S`` 标志传递给 ``git commit`` 命令(由于
与另一个标志冲突,所以它是大写的 ``-S`` ::
$ git commit -S
配置 git 始终对提交进行签名
~~~~~~~~~~~~~~~~~~~~~~~~~~~
你可以告诉 git 总是签署提交::
git config --global commit.gpgSign true
.. note::
确保 ``gpg-agent`` 在打开此功能之前进行配置。
.. _身份验证:
如何使用签名补丁
----------------
可以使用你的 PGP 密钥来签署发送到内核开发人员邮件列表的补丁。由于现有的
电子邮件签名机制PGP-Mime 或 PGP-inline往往会导致常规代码审查任务
出现问题,因此你应该使用为此创建的 kernel.org 工具,该工具将加密证明签
名放入消息标头中a-la DKIM:
- `Patatt Patch Attestation`_
.. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/
安装和配置 patatt
~~~~~~~~~~~~~~~~~
Patatt 已针对许多发行版进行了打包,因此请先检查那里。你还可以使用
``pip install patatt`` ”从 pypi 安装它。
如果你已经使用 git 配置了 PGP 密钥(通过``user.signingKey`` 配置参数),
则 patatt 不需要进一步配置。你可以通过在所需的仓库中安装 git-send-email
钩子来开始签署补丁::
patatt install-hook
现在,你使用 ``git send-email`` 发送的任何补丁都将自动使用你的加密签
名进行签名
检查 patatt 签名
~~~~~~~~~~~~~~~~
如果你用于 ``b4`` 检索和应用补丁,那么它将自动尝试验证它遇到的所有
DKIM 和 patatt 签名,例如::
$ b4 am 20220720205013.890942-1-broonie@kernel.org
[...]
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers
✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall
✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls
---
✓ Signed: openpgp/broonie@kernel.org
✓ Signed: DKIM/kernel.org
.. note::
Patatt 和 b4 仍在积极开发中,你应该检查这些项目的最新文档以了解任
何新功能或更新功能。
如何验证内核开发者身份
======================
签署标签和提交很容易,但是如何验证用于签署某项内容的密钥是否属于实际的内
核开发人员而不是恶意冒名顶替者?
使用 WKD 和 DANE 配置auto-key-locate自动密钥检索
----------------------------------------------------
如果你还没有广泛收集其他开发人员的公钥,那么你可以依靠密钥自动发现和自动
检索来快速启动你的密钥环。如果从头开始创建自己的信任 Web 的预期太令人畏
惧, GnuPG 可以借助其他委托信任技术(即 DNSSEC 和 TLS来帮助你继续前
进。
将以下内容添加到你的 ``~/.gnupg/gpg.conf``::
auto-key-locate wkd,dane,local
auto-key-retrieve
基于 DNS 的命名实体身份验证“DANE”是一种在 DNS 中发布公钥并使用
DNSSEC 签名区域保护它们的方法。Web 密钥目录“WKD”是使用 https
查找来达到相同目的的替代方法。当使用 DANE 或 WKD 查找公钥时GnuPG
将分别验证 DNSSEC 或 TLS 证书,然后将自动检索的公钥添加到本地密钥环。
Kernel.org 为所有拥有 kernel.org 帐户的开发人员发布 WKD。一旦你的
``gpg.conf`` 中进行了上述更改,你就可以自动检索 Linus Torvalds 和
Greg Kroah-Hartman 的密钥(如果你还没有它们)::
$ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org
如果你有 kernel.org 帐户,那么你应该 `添加 kernel.org UID 到你的密钥中`_
添加到你的密钥中,以使 WKD 对其他内核开发人员更有用。
.. _`添加 kernel.org UID 到你的密钥中`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key
信任网 (WOT) 与首次使用信任 (TOFU)
-----------------------------------
PGP 结合了称为“信任网”的信任委托机制。从本质上讲,这是一次尝试取代
HTTPS/TLS 世界对集中式证书颁发机构的需求。PGP 将这一责任留给每个
用户,而不是由各种软件制造商规定谁应该是你值得信赖的认证实体。
不幸的是,很少有人了解信任网是如何运作的。虽然它仍然是 OpenPGP 规
范的一个重要方面,但最新版本的 GnuPG2.2 及更高版本)已经实现了
一种称为“首次使用信任”(TOFU) 的替代机制。你可以将 TOFU 视为“类似
SSH 的信任方法”。使用 SSH第一次连接到远程系统时其密钥指纹会被
记录并记住。如果将来密钥发生变化SSH 客户端将向你发出警报并拒绝连
接,迫使你决定是否选择信任更改后的密钥。同样,第一次导入某人的 PGP
密钥时,它被认为是有效的。如果将来的任何时候 GnuPG 遇到具有相同标
识的另一个密钥,则先前导入的密钥和新密钥都将被标记为无效,你将需要手
动确定保留哪一个。
我们建议你使用 TOFU+PGP 组合信任模型(这是 GnuPG v2 中新默认的)。
若要设置它,在 ``~/.gnupg/gpg.conf`` 中添加(或修改)
``trust-model`` 设置::
trust-model tofu+pgp
使用 kernel.org 信任网仓库
--------------------------
Kernel.org 维护着一个包含开发人员公钥的 git 仓库,作为复制密钥服
务器网络的替代品,而在过去几年中,该网络几乎已经陷入黑暗。有关如何将
该仓库设置为公钥来源的完整文档可以在此处找到:
- `内核开发者密钥环`_
如果你是内核开发人员,请考虑提交你的密钥以将其包含到该密钥环中。
.. _`内核开发者密钥环`: https://korg.docs.kernel.org/pgpkeys.html

View File

@ -17,11 +17,8 @@ Linux 内核用户空间API指南
在代码树中仍然可以找到有关用户空间的部分信息。这个手册意在成为这些信息 在代码树中仍然可以找到有关用户空间的部分信息。这个手册意在成为这些信息
聚集的地方。 聚集的地方。
.. class:: toc-title
目录
.. toctree:: .. toctree::
:caption: 目录
:maxdepth: 2 :maxdepth: 2
no_new_privs no_new_privs

View File

@ -7,7 +7,7 @@ help. Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation. or if there is a problem with the translation.
Maintainer: Eric W. Biederman <ebiederman@xmission.com> Maintainer: Eric W. Biederman <ebiederman@xmission.com>
Traditional Chinese maintainer: Hu Haowen <src.res.211@gmail.com> Traditional Chinese maintainer: Hu Haowen <2023002089@link.tyut.edu.cn>
--------------------------------------------------------------------- ---------------------------------------------------------------------
Documentation/core-api/irq/index.rst 的繁體中文翻譯 Documentation/core-api/irq/index.rst 的繁體中文翻譯
@ -16,9 +16,9 @@ Documentation/core-api/irq/index.rst 的繁體中文翻譯
者翻譯存在問題,請聯繫繁體中文版維護者。 者翻譯存在問題,請聯繫繁體中文版維護者。
英文版維護者: Eric W. Biederman <ebiederman@xmission.com> 英文版維護者: Eric W. Biederman <ebiederman@xmission.com>
繁體中文版維護者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版維護者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版翻譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
以下爲正文 以下爲正文

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
Linux內核6.x版本 <http://kernel.org/> Linux內核6.x版本 <http://kernel.org/>
========================================= =========================================

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
二分bisect缺陷 二分bisect缺陷
+++++++++++++++++++ +++++++++++++++++++

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
追蹤缺陷 追蹤缺陷
========= =========

View File

@ -2,7 +2,7 @@
.. include:: ../disclaimer-zh_TW.rst .. include:: ../disclaimer-zh_TW.rst
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com> :Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
清除 WARN_ONCE 清除 WARN_ONCE
-------------- --------------

View File

@ -2,7 +2,7 @@
.. include:: ../disclaimer-zh_TW.rst .. include:: ../disclaimer-zh_TW.rst
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com> :Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
======== ========
CPU 負載 CPU 負載

View File

@ -4,7 +4,7 @@
:Original: :doc:`../../../admin-guide/index` :Original: :doc:`../../../admin-guide/index`
:Translator: Alex Shi <alex.shi@linux.alibaba.com> :Translator: Alex Shi <alex.shi@linux.alibaba.com>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
Linux 內核用戶和管理員指南 Linux 內核用戶和管理員指南
========================== ==========================

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
解釋“No working init found.”啓動掛起消息 解釋“No working init found.”啓動掛起消息
========================================= =========================================

View File

@ -9,7 +9,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
報告問題 報告問題

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
安全缺陷 安全缺陷
========= =========

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
受污染的內核 受污染的內核
------------- -------------

View File

@ -7,7 +7,7 @@
:譯者: :譯者:
吳想成 Wu XiangCheng <bobwxc@email.cn> 吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
Unicode統一碼支持 Unicode統一碼支持
====================== ======================

View File

@ -5,7 +5,7 @@
:Original: :ref:`Documentation/arch/arm64/amu.rst <amu_index>` :Original: :ref:`Documentation/arch/arm64/amu.rst <amu_index>`
Translator: Bailu Lin <bailu.lin@vivo.com> Translator: Bailu Lin <bailu.lin@vivo.com>
Hu Haowen <src.res.211@gmail.com> Hu Haowen <2023002089@link.tyut.edu.cn>
================================== ==================================
AArch64 Linux 中擴展的活動監控單元 AArch64 Linux 中擴展的活動監控單元

View File

@ -10,7 +10,7 @@ or if there is a problem with the translation.
M: Will Deacon <will.deacon@arm.com> M: Will Deacon <will.deacon@arm.com>
zh_CN: Fu Wei <wefu@redhat.com> zh_CN: Fu Wei <wefu@redhat.com>
zh_TW: Hu Haowen <src.res.211@gmail.com> zh_TW: Hu Haowen <2023002089@link.tyut.edu.cn>
C: 55f058e7574c3615dea4615573a19bdb258696c6 C: 55f058e7574c3615dea4615573a19bdb258696c6
--------------------------------------------------------------------- ---------------------------------------------------------------------
Documentation/arch/arm64/booting.rst 的中文翻譯 Documentation/arch/arm64/booting.rst 的中文翻譯
@ -23,7 +23,7 @@ Documentation/arch/arm64/booting.rst 的中文翻譯
中文版維護者: 傅煒 Fu Wei <wefu@redhat.com> 中文版維護者: 傅煒 Fu Wei <wefu@redhat.com>
中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com>
中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com>
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
本文翻譯提交時的 Git 檢出點爲: 55f058e7574c3615dea4615573a19bdb258696c6 本文翻譯提交時的 Git 檢出點爲: 55f058e7574c3615dea4615573a19bdb258696c6
以下爲正文 以下爲正文

View File

@ -5,7 +5,7 @@
:Original: :ref:`Documentation/arch/arm64/elf_hwcaps.rst <elf_hwcaps_index>` :Original: :ref:`Documentation/arch/arm64/elf_hwcaps.rst <elf_hwcaps_index>`
Translator: Bailu Lin <bailu.lin@vivo.com> Translator: Bailu Lin <bailu.lin@vivo.com>
Hu Haowen <src.res.211@gmail.com> Hu Haowen <2023002089@link.tyut.edu.cn>
================ ================
ARM64 ELF hwcaps ARM64 ELF hwcaps

View File

@ -5,7 +5,7 @@
:Original: :ref:`Documentation/arch/arm64/hugetlbpage.rst <hugetlbpage_index>` :Original: :ref:`Documentation/arch/arm64/hugetlbpage.rst <hugetlbpage_index>`
Translator: Bailu Lin <bailu.lin@vivo.com> Translator: Bailu Lin <bailu.lin@vivo.com>
Hu Haowen <src.res.211@gmail.com> Hu Haowen <2023002089@link.tyut.edu.cn>
===================== =====================
ARM64中的 HugeTLBpage ARM64中的 HugeTLBpage

View File

@ -4,7 +4,7 @@
:Original: :ref:`Documentation/arch/arm64/index.rst <arm64_index>` :Original: :ref:`Documentation/arch/arm64/index.rst <arm64_index>`
:Translator: Bailu Lin <bailu.lin@vivo.com> :Translator: Bailu Lin <bailu.lin@vivo.com>
Hu Haowen <src.res.211@gmail.com> Hu Haowen <2023002089@link.tyut.edu.cn>
.. _tw_arm64_index: .. _tw_arm64_index:

View File

@ -11,7 +11,7 @@ or if there is a problem with the translation.
Maintainer: Punit Agrawal <punit.agrawal@arm.com> Maintainer: Punit Agrawal <punit.agrawal@arm.com>
Suzuki K. Poulose <suzuki.poulose@arm.com> Suzuki K. Poulose <suzuki.poulose@arm.com>
Chinese maintainer: Fu Wei <wefu@redhat.com> Chinese maintainer: Fu Wei <wefu@redhat.com>
Traditional Chinese maintainer: Hu Haowen <src.res.211@gmail.com> Traditional Chinese maintainer: Hu Haowen <2023002089@link.tyut.edu.cn>
--------------------------------------------------------------------- ---------------------------------------------------------------------
Documentation/arch/arm64/legacy_instructions.rst 的中文翻譯 Documentation/arch/arm64/legacy_instructions.rst 的中文翻譯
@ -26,7 +26,7 @@ Documentation/arch/arm64/legacy_instructions.rst 的中文翻譯
中文版維護者: 傅煒 Fu Wei <wefu@redhat.com> 中文版維護者: 傅煒 Fu Wei <wefu@redhat.com>
中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com>
中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com>
繁體中文版校譯者:胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者:胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
以下爲正文 以下爲正文
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -10,7 +10,7 @@ or if there is a problem with the translation.
Maintainer: Catalin Marinas <catalin.marinas@arm.com> Maintainer: Catalin Marinas <catalin.marinas@arm.com>
Chinese maintainer: Fu Wei <wefu@redhat.com> Chinese maintainer: Fu Wei <wefu@redhat.com>
Traditional Chinese maintainer: Hu Haowen <src.res.211@gmail.com> Traditional Chinese maintainer: Hu Haowen <2023002089@link.tyut.edu.cn>
--------------------------------------------------------------------- ---------------------------------------------------------------------
Documentation/arch/arm64/memory.rst 的中文翻譯 Documentation/arch/arm64/memory.rst 的中文翻譯
@ -24,7 +24,7 @@ Documentation/arch/arm64/memory.rst 的中文翻譯
中文版維護者: 傅煒 Fu Wei <wefu@redhat.com> 中文版維護者: 傅煒 Fu Wei <wefu@redhat.com>
中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com>
中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com>
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
以下爲正文 以下爲正文
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
:Original: :ref:`Documentation/arch/arm64/perf.rst <perf_index>` :Original: :ref:`Documentation/arch/arm64/perf.rst <perf_index>`
Translator: Bailu Lin <bailu.lin@vivo.com> Translator: Bailu Lin <bailu.lin@vivo.com>
Hu Haowen <src.res.211@gmail.com> Hu Haowen <2023002089@link.tyut.edu.cn>
============= =============
Perf 事件屬性 Perf 事件屬性

View File

@ -10,7 +10,7 @@ or if there is a problem with the translation.
M: Will Deacon <will.deacon@arm.com> M: Will Deacon <will.deacon@arm.com>
zh_CN: Fu Wei <wefu@redhat.com> zh_CN: Fu Wei <wefu@redhat.com>
zh_TW: Hu Haowen <src.res.211@gmail.com> zh_TW: Hu Haowen <2023002089@link.tyut.edu.cn>
C: 1926e54f115725a9248d0c4c65c22acaf94de4c4 C: 1926e54f115725a9248d0c4c65c22acaf94de4c4
--------------------------------------------------------------------- ---------------------------------------------------------------------
Documentation/arch/arm64/silicon-errata.rst 的中文翻譯 Documentation/arch/arm64/silicon-errata.rst 的中文翻譯
@ -23,7 +23,7 @@ Documentation/arch/arm64/silicon-errata.rst 的中文翻譯
中文版維護者: 傅煒 Fu Wei <wefu@redhat.com> 中文版維護者: 傅煒 Fu Wei <wefu@redhat.com>
中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com>
中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com>
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
本文翻譯提交時的 Git 檢出點爲: 1926e54f115725a9248d0c4c65c22acaf94de4c4 本文翻譯提交時的 Git 檢出點爲: 1926e54f115725a9248d0c4c65c22acaf94de4c4
以下爲正文 以下爲正文

View File

@ -10,7 +10,7 @@ or if there is a problem with the translation.
Maintainer: Will Deacon <will.deacon@arm.com> Maintainer: Will Deacon <will.deacon@arm.com>
Chinese maintainer: Fu Wei <wefu@redhat.com> Chinese maintainer: Fu Wei <wefu@redhat.com>
Traditional Chinese maintainer: Hu Haowen <src.res.211@gmail.com> Traditional Chinese maintainer: Hu Haowen <2023002089@link.tyut.edu.cn>
--------------------------------------------------------------------- ---------------------------------------------------------------------
Documentation/arch/arm64/tagged-pointers.rst 的中文翻譯 Documentation/arch/arm64/tagged-pointers.rst 的中文翻譯
@ -22,7 +22,7 @@ Documentation/arch/arm64/tagged-pointers.rst 的中文翻譯
中文版維護者: 傅煒 Fu Wei <wefu@redhat.com> 中文版維護者: 傅煒 Fu Wei <wefu@redhat.com>
中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版翻譯者: 傅煒 Fu Wei <wefu@redhat.com>
中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com> 中文版校譯者: 傅煒 Fu Wei <wefu@redhat.com>
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
以下爲正文 以下爲正文
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -6,19 +6,19 @@ communicating in English you can also ask the Chinese maintainer for
help. Contact the Chinese maintainer if this translation is outdated help. Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation. or if there is a problem with the translation.
Traditional Chinese maintainer: Hu Haowen <src.res.211@gmail.com> Traditional Chinese maintainer: Hu Haowen <2023002089@link.tyut.edu.cn>
--------------------------------------------------------------------- -------------------------------------------------------------------------
Documentation/dev-tools/sparse.rst 的繁體中文翻譯 Documentation/dev-tools/sparse.rst 的繁體中文翻譯
如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文
交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或
者翻譯存在問題,請聯繫繁體中文版維護者。 者翻譯存在問題,請聯繫繁體中文版維護者。
繁體中文版維護者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版維護者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版翻譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
以下爲正文 以下爲正文
--------------------------------------------------------------------- -------------------------------------------------------------------------
Copyright 2004 Linus Torvalds Copyright 2004 Linus Torvalds
Copyright 2004 Pavel Machek <pavel@ucw.cz> Copyright 2004 Pavel Machek <pavel@ucw.cz>

View File

@ -3,7 +3,7 @@
.. include:: ../disclaimer-zh_TW.rst .. include:: ../disclaimer-zh_TW.rst
:Original: Documentation/dev-tools/testing-overview.rst :Original: Documentation/dev-tools/testing-overview.rst
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com> :Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
============ ============
內核測試指南 內核測試指南

View File

@ -7,5 +7,5 @@
.. note:: .. note::
如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者, 如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者,
或者發送電子郵件給胡皓文以獲取幫助:<src.res.211@gmail.com>。 或者發送電子郵件給胡皓文以獲取幫助:<2023002089@link.tyut.edu.cn>。

View File

@ -14,7 +14,7 @@ Debugfs
中文版維護者: 羅楚成 Chucheng Luo <luochucheng@vivo.com> 中文版維護者: 羅楚成 Chucheng Luo <luochucheng@vivo.com>
中文版翻譯者: 羅楚成 Chucheng Luo <luochucheng@vivo.com> 中文版翻譯者: 羅楚成 Chucheng Luo <luochucheng@vivo.com>
中文版校譯者: 羅楚成 Chucheng Luo <luochucheng@vivo.com> 中文版校譯者: 羅楚成 Chucheng Luo <luochucheng@vivo.com>
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com> 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>

Some files were not shown because too many files have changed in this diff Show More