mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
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:
commit
5b9b41617b
7
CREDITS
7
CREDITS
@ -1835,6 +1835,13 @@ S: K osmidomkum 723
|
||||
S: 160 00 Praha 6
|
||||
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
|
||||
E: nkbj1970@hotmail.com
|
||||
D: Miscellaneous kernel updates and fixes.
|
||||
|
@ -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
|
||||
obsolete and when it can be expected to be removed.
|
||||
|
||||
.. kernel-abi:: $srctree/Documentation/ABI/obsolete
|
||||
.. kernel-abi:: ABI/obsolete
|
||||
:rst:
|
||||
|
@ -1,5 +1,5 @@
|
||||
ABI removed symbols
|
||||
===================
|
||||
|
||||
.. kernel-abi:: $srctree/Documentation/ABI/removed
|
||||
.. kernel-abi:: ABI/removed
|
||||
:rst:
|
||||
|
@ -10,5 +10,5 @@ for at least 2 years.
|
||||
Most interfaces (like syscalls) are expected to never change and always
|
||||
be available.
|
||||
|
||||
.. kernel-abi:: $srctree/Documentation/ABI/stable
|
||||
.. kernel-abi:: ABI/stable
|
||||
:rst:
|
||||
|
@ -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
|
||||
developers can easily notify them if any changes occur.
|
||||
|
||||
.. kernel-abi:: $srctree/Documentation/ABI/testing
|
||||
.. kernel-abi:: ABI/testing
|
||||
:rst:
|
||||
|
@ -321,13 +321,13 @@ Examples
|
||||
:#> ddcmd 'format "nfsd: READ" +p'
|
||||
|
||||
// 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
|
||||
:#> ddcmd '+p' > /proc/dynamic_debug/control
|
||||
:#> ddcmd '+p'
|
||||
|
||||
// add module, function to all enabled messages
|
||||
:#> ddcmd '+mf' > /proc/dynamic_debug/control
|
||||
:#> ddcmd '+mf'
|
||||
|
||||
// boot-args example, with newlines and comments for readability
|
||||
Kernel command line: ...
|
||||
|
@ -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]
|
||||
Advanced Configuration and Power Interface
|
||||
Format: { force | on | off | strict | noirq | rsdt |
|
||||
|
@ -20,16 +20,8 @@ Documentation/driver-api/media/index.rst
|
||||
- for driver development information and Kernel APIs used by
|
||||
media devices;
|
||||
|
||||
The media subsystem
|
||||
===================
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of Contents
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
|
@ -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
|
||||
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.
|
||||
|
||||
Protocol 2.15 (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max.
|
||||
|
@ -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_BITS()`` must be equal to ``{1,2,4,8,16} * 8``.
|
||||
|
||||
The following kernel patch introduced ``kind_flag`` and explained why both
|
||||
modes exist:
|
||||
|
||||
https://github.com/torvalds/linux/commit/9d5f9f701b1891466fb3dbb1806ad97716f95cc3#diff-fa650a64fdd3968396883d2fe8215ff3
|
||||
Commit 9d5f9f701b18 introduced ``kind_flag`` and explains why both modes
|
||||
exist.
|
||||
|
||||
2.2.6 BTF_KIND_ENUM
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -47,7 +47,7 @@ from load_config import loadConfig
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# 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
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@ -55,7 +55,7 @@ needs_sphinx = '1.7'
|
||||
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include',
|
||||
'kfigure', 'sphinx.ext.ifconfig', 'automarkup',
|
||||
'maintainers_include', 'sphinx.ext.autosectionlabel',
|
||||
'kernel_abi', 'kernel_feat']
|
||||
'kernel_abi', 'kernel_feat', 'translations']
|
||||
|
||||
if major >= 3:
|
||||
if (major > 3) or (minor > 0 or patch >= 2):
|
||||
@ -106,6 +106,7 @@ if major >= 3:
|
||||
"__weak",
|
||||
"noinline",
|
||||
"__fix_address",
|
||||
"__counted_by",
|
||||
|
||||
# include/linux/memblock.h:
|
||||
"__init_memblock",
|
||||
@ -357,6 +358,10 @@ html_sidebars = { '**': ['searchbox.html', 'kernel-toc.html', 'sourcelink.html']
|
||||
if html_theme == 'alabaster':
|
||||
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.
|
||||
htmlhelp_basename = 'TheLinuxKerneldoc'
|
||||
|
||||
|
@ -8,7 +8,7 @@ Dynamic DMA mapping Guide
|
||||
|
||||
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
|
||||
DMA-API.txt.
|
||||
Documentation/core-api/dma-api.rst.
|
||||
|
||||
CPU and DMA addresses
|
||||
=====================
|
||||
|
@ -448,7 +448,7 @@ DMA address entries returned.
|
||||
|
||||
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
|
||||
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
|
||||
those passed into the single mapping API to do a partial sync.
|
||||
|
||||
|
@ -379,7 +379,7 @@ Workqueue currently supports the following affinity scopes.
|
||||
cases. This is the default affinity scope.
|
||||
|
||||
``numa``
|
||||
CPUs are grouped according to NUMA bounaries.
|
||||
CPUs are grouped according to NUMA boundaries.
|
||||
|
||||
``system``
|
||||
All CPUs are put in the same group. Workqueue makes no effort to process a
|
||||
|
@ -1,11 +1,8 @@
|
||||
Programming Interface
|
||||
=====================
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of contents
|
||||
:maxdepth: 2
|
||||
|
||||
api-skcipher
|
||||
|
@ -9,11 +9,8 @@ This documentation outlines the Linux kernel crypto API with its
|
||||
concepts, details about developing cipher implementations, employment of the API
|
||||
for cryptographic use cases, as well as programming examples.
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of contents
|
||||
:maxdepth: 2
|
||||
|
||||
intro
|
||||
|
@ -10,11 +10,8 @@ whole; patches welcome!
|
||||
A brief overview of testing-specific tools can be found in
|
||||
Documentation/dev-tools/testing-overview.rst
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of contents
|
||||
:maxdepth: 2
|
||||
|
||||
testing-overview
|
||||
|
@ -28,7 +28,7 @@ Sphinx Install
|
||||
==============
|
||||
|
||||
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
|
||||
:ref:`sphinx-pre-install` for further details.
|
||||
@ -435,6 +435,15 @@ path.
|
||||
For information on cross-referencing to kernel-doc functions or types, see
|
||||
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:
|
||||
|
||||
Figures & Images
|
||||
|
@ -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
|
||||
available subsections can be seen below.
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of contents
|
||||
:maxdepth: 2
|
||||
|
||||
driver-model/index
|
||||
@ -81,10 +78,8 @@ available subsections can be seen below.
|
||||
backlight/lp855x-driver.rst
|
||||
connector
|
||||
console
|
||||
dcdbas
|
||||
eisa
|
||||
isa
|
||||
isapnp
|
||||
io-mapping
|
||||
io_ordering
|
||||
generic-counter
|
||||
@ -117,6 +112,7 @@ available subsections can be seen below.
|
||||
dpll
|
||||
wbrf
|
||||
crypto/index
|
||||
tee
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
@ -20,13 +20,8 @@ Documentation/userspace-api/media/index.rst
|
||||
- for the userspace APIs used on media devices.
|
||||
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of Contents
|
||||
:maxdepth: 5
|
||||
:numbered:
|
||||
|
||||
|
@ -9,13 +9,8 @@ Intel(R) Management Engine Interface (Intel(R) MEI)
|
||||
**Copyright** |copy| 2019 Intel Corporation
|
||||
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of Contents
|
||||
:maxdepth: 3
|
||||
|
||||
mei
|
||||
|
@ -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_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::
|
||||
|
||||
@ -200,3 +200,9 @@ and let you add cells dynamically.
|
||||
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
|
||||
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:
|
||||
|
@ -4,11 +4,8 @@
|
||||
The Linux PCI driver implementer's API guide
|
||||
============================================
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of contents
|
||||
:maxdepth: 2
|
||||
|
||||
pci
|
||||
|
66
Documentation/driver-api/tee.rst
Normal file
66
Documentation/driver-api/tee.rst
Normal 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);
|
@ -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.
|
||||
|
||||
|
||||
struct xattr_handlers
|
||||
struct xattr_handler
|
||||
---------------------
|
||||
|
||||
On filesystems that support extended attributes (xattrs), the s_xattr
|
||||
|
@ -4,11 +4,8 @@
|
||||
Linux Input Subsystem kernel API
|
||||
################################
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of Contents
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
|
@ -4,11 +4,8 @@
|
||||
Linux Input Subsystem userspace API
|
||||
###################################
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of Contents
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
|
@ -6,11 +6,8 @@ Linux Joystick support
|
||||
|
||||
:Copyright: |copy| 1996-2000 Vojtech Pavlik <vojtech@ucw.cz> - Sponsored by SuSE
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of Contents
|
||||
:maxdepth: 3
|
||||
|
||||
joystick
|
||||
|
@ -110,7 +110,7 @@ Global data update
|
||||
------------------
|
||||
|
||||
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()
|
||||
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
|
||||
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
|
||||
pre/post-patch callback could iterate over all such devices, making a
|
||||
similar change to their hw_features value. (Client functions of the
|
||||
|
@ -7,11 +7,8 @@ Assorted Miscellaneous Devices Documentation
|
||||
This documentation contains information for assorted devices that do not
|
||||
fit into other categories.
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of contents
|
||||
|
||||
.. toctree::
|
||||
:caption: Table of contents
|
||||
:maxdepth: 2
|
||||
|
||||
ad525x_dpot
|
||||
|
@ -313,7 +313,7 @@ https://lwn.net/Articles/576263/
|
||||
|
||||
* 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::
|
||||
|
||||
TCPOrigDataSent: number of outgoing packets with original data (excluding
|
||||
@ -323,7 +323,7 @@ explanation below::
|
||||
|
||||
* 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::
|
||||
|
||||
TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down
|
||||
@ -331,14 +331,12 @@ explanation below::
|
||||
|
||||
* 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::
|
||||
|
||||
TCPFastOpenActiveFail: Fast Open attempts (SYN/data) failed because
|
||||
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
|
||||
|
||||
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
|
||||
SACK option could have up to 4 blocks, they are checked
|
||||
individually. E.g., if 3 blocks of a SACk is invalid, the
|
||||
corresponding counter would be updated 3 times. The comment of the
|
||||
`Add counters for discarded SACK blocks`_ patch has additional
|
||||
explanation:
|
||||
|
||||
.. _Add counters for discarded SACK blocks: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=18f02545a9a16c9a89778b91a162ad16d510bb32
|
||||
corresponding counter would be updated 3 times. The comment of commit
|
||||
18f02545a9a1 ("[TCP] MIB: Add counters for discarded SACK blocks")
|
||||
has additional explanation:
|
||||
|
||||
* TcpExtTCPSACKDiscard
|
||||
|
||||
|
@ -39,7 +39,7 @@ binutils 2.25 ld -v
|
||||
flex 2.5.35 flex --version
|
||||
bison 2.0 bison --version
|
||||
pahole 1.16 pahole --version
|
||||
util-linux 2.10o fdformat --version
|
||||
util-linux 2.10o mount --version
|
||||
kmod 13 depmod -V
|
||||
e2fsprogs 1.41.4 e2fsck -V
|
||||
jfsutils 1.1.3 fsck.jfs -V
|
||||
@ -58,7 +58,7 @@ mcelog 0.6 mcelog --version
|
||||
iptables 1.4.2 iptables -V
|
||||
openssl & libcrypto 1.0.0 openssl 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
|
||||
GNU tar 1.28 tar --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,
|
||||
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.
|
||||
|
||||
Ksymoops
|
||||
|
@ -3,9 +3,17 @@
|
||||
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::
|
||||
:caption: Contents
|
||||
:numbered:
|
||||
:maxdepth: 2
|
||||
|
||||
@ -17,12 +25,3 @@ Contents:
|
||||
6.Followthrough
|
||||
7.AdvancedTopics
|
||||
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.
|
||||
|
@ -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
|
||||
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
|
||||
maintainer at mtk.manpages@gmail.com, and CC the list
|
||||
linux-api@vger.kernel.org.
|
||||
maintainer at alx@kernel.org, and CC the list linux-api@vger.kernel.org.
|
||||
|
||||
Here is a list of files that are in the kernel source tree that are
|
||||
required reading:
|
||||
|
@ -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
|
||||
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::
|
||||
:maxdepth: 1
|
||||
|
||||
license-rules
|
||||
howto
|
||||
code-of-conduct
|
||||
code-of-conduct-interpretation
|
||||
development-process
|
||||
submitting-patches
|
||||
handling-regressions
|
||||
programming-language
|
||||
coding-style
|
||||
maintainer-handbooks
|
||||
maintainer-pgp-guide
|
||||
email-clients
|
||||
kernel-enforcement-statement
|
||||
kernel-driver-statement
|
||||
submit-checklist
|
||||
|
||||
For security issues, see:
|
||||
Tools and technical guides for kernel developers
|
||||
------------------------------------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
security-bugs
|
||||
embargoed-hardware-issues
|
||||
|
||||
Other guides to the community that are of interest to most developers are:
|
||||
This is a collection of material that kernel developers should be familiar
|
||||
with.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
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
|
||||
management-style
|
||||
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
|
||||
deprecated
|
||||
maintainers
|
||||
researcher-guidelines
|
||||
contribution-maturity-model
|
||||
|
||||
These are some overall technical guides that have been put here for now for
|
||||
lack of a better place.
|
||||
@ -65,12 +112,7 @@ lack of a better place.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
applying-patches
|
||||
backporting
|
||||
adding-syscalls
|
||||
magic-number
|
||||
volatile-considered-harmful
|
||||
botching-up-ioctls
|
||||
clang-format
|
||||
../arch/riscv/patch-acceptance
|
||||
../core-api/unaligned-memory-access
|
||||
|
@ -790,10 +790,14 @@ Providing base tree information
|
||||
-------------------------------
|
||||
|
||||
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
|
||||
should place your work. This is particularly useful 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.
|
||||
it is absolutely necessary for them to know what is the base
|
||||
commit/branch your work applies on, considering the sheer amount of
|
||||
maintainer trees present nowadays. Note again the **T:** entry in the
|
||||
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
|
||||
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
|
||||
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
|
||||
----------
|
||||
|
@ -88,7 +88,7 @@ safe.
|
||||
(2) TEE
|
||||
|
||||
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
|
||||
|
||||
|
@ -7,6 +7,10 @@
|
||||
div.body h1 { font-size: 180%; }
|
||||
div.body h2 { font-size: 150%; }
|
||||
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 */
|
||||
div.body { padding: 0 15px 0 10px; }
|
||||
@ -20,6 +24,12 @@ div.document {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Size the logo appropriately */
|
||||
img.logo {
|
||||
width: 104px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters for the display of function prototypes and such included
|
||||
* from C source files.
|
||||
@ -73,3 +83,56 @@ input.kernel-toc-toggle { display: none; }
|
||||
h3.kernel-toc-contents { display: inline; }
|
||||
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;
|
||||
}
|
||||
|
@ -81,11 +81,6 @@ div[class^="highlight"] pre {
|
||||
* - 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 {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
@ -7,11 +7,7 @@
|
||||
from docutils import nodes
|
||||
import sphinx
|
||||
from sphinx import addnodes
|
||||
if sphinx.version_info[0] < 2 or \
|
||||
sphinx.version_info[0] == 2 and sphinx.version_info[1] < 1:
|
||||
from sphinx.environment import NoUri
|
||||
else:
|
||||
from sphinx.errors import NoUri
|
||||
from sphinx.errors import NoUri
|
||||
import re
|
||||
from itertools import chain
|
||||
|
||||
@ -74,6 +70,12 @@ Skipfuncs = [ 'open', 'close', 'read', 'write', 'fcntl', 'mmap',
|
||||
|
||||
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):
|
||||
t = node.astext()
|
||||
done = 0
|
||||
@ -90,7 +92,8 @@ def markup_refs(docname, app, node):
|
||||
RE_struct: markup_c_ref,
|
||||
RE_union: 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:
|
||||
markup_func = markup_func_sphinx3
|
||||
@ -276,6 +279,17 @@ def get_c_namespace(app, docname):
|
||||
return match.group(1)
|
||||
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):
|
||||
global c_namespace
|
||||
c_namespace = get_c_namespace(app, name)
|
||||
|
@ -127,11 +127,7 @@ def setup(app):
|
||||
|
||||
# Handle easy Sphinx 3.1+ simple new tags: :c:expr and .. c:namespace::
|
||||
app.connect('source-read', c_markups)
|
||||
|
||||
if (major == 1 and minor < 8):
|
||||
app.override_domain(CDomain)
|
||||
else:
|
||||
app.add_domain(CDomain, override=True)
|
||||
app.add_domain(CDomain, override=True)
|
||||
|
||||
return dict(
|
||||
version = __version__,
|
||||
|
@ -39,8 +39,6 @@ import sys
|
||||
import re
|
||||
import kernellog
|
||||
|
||||
from os import path
|
||||
|
||||
from docutils import nodes, statemachine
|
||||
from docutils.statemachine import ViewList
|
||||
from docutils.parsers.rst import directives, Directive
|
||||
@ -73,60 +71,26 @@ class KernelCmd(Directive):
|
||||
}
|
||||
|
||||
def run(self):
|
||||
|
||||
doc = self.state.document
|
||||
if not doc.settings.file_insertion_enabled:
|
||||
raise self.warning("docutils: file insertion disabled")
|
||||
|
||||
env = doc.settings.env
|
||||
cwd = path.dirname(doc.current_source)
|
||||
cmd = "get_abi.pl rest --enable-lineno --dir "
|
||||
cmd += self.arguments[0]
|
||||
srctree = os.path.abspath(os.environ["srctree"])
|
||||
|
||||
args = [
|
||||
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:
|
||||
cmd += " --rst-source"
|
||||
args.append('--rst-source')
|
||||
|
||||
srctree = path.abspath(os.environ["srctree"])
|
||||
|
||||
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)
|
||||
lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')
|
||||
nodeList = self.nestedParse(lines, self.arguments[0])
|
||||
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):
|
||||
env = self.state.document.settings.env
|
||||
content = ViewList()
|
||||
|
@ -61,13 +61,7 @@ import sphinx
|
||||
from sphinx.util.nodes import clean_astext
|
||||
import kernellog
|
||||
|
||||
# Get Sphinx version
|
||||
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
|
||||
Figure = images.Figure
|
||||
|
||||
__version__ = '1.0.0'
|
||||
|
||||
|
15
Documentation/sphinx/templates/translations.html
Normal file
15
Documentation/sphinx/templates/translations.html
Normal 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 %}
|
101
Documentation/sphinx/translations.py
Normal file
101
Documentation/sphinx/translations.py
Normal 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,
|
||||
}
|
@ -12,5 +12,4 @@ Unsorted Documentation
|
||||
rpmsg
|
||||
speculation
|
||||
static-keys
|
||||
tee
|
||||
xz
|
||||
|
@ -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
|
@ -86,3 +86,4 @@ Storage interfaces
|
||||
misc-devices/index
|
||||
peci/index
|
||||
wmi/index
|
||||
tee/index
|
||||
|
90
Documentation/tee/amd-tee.rst
Normal file
90
Documentation/tee/amd-tee.rst
Normal 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.
|
19
Documentation/tee/index.rst
Normal file
19
Documentation/tee/index.rst
Normal 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`
|
166
Documentation/tee/op-tee.rst
Normal file
166
Documentation/tee/op-tee.rst
Normal 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
22
Documentation/tee/tee.rst
Normal 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
|
@ -182,7 +182,7 @@ FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED
|
||||
|
||||
FTRACE_OPS_FL_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
|
||||
callback by calling a helper function that will do the recursion
|
||||
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
|
||||
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
|
||||
(but not guaranteed) that the callback will be called in
|
||||
preemptable context.
|
||||
|
@ -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.
|
||||
(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:
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
- hide: echo nofuncgraph-cpu > trace_options
|
||||
|
@ -8,9 +8,17 @@
|
||||
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::
|
||||
:caption: Contenuti
|
||||
:numbered:
|
||||
:maxdepth: 2
|
||||
|
||||
@ -22,12 +30,3 @@ Contenuti:
|
||||
6.Followthrough
|
||||
7.AdvancedTopics
|
||||
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.
|
||||
|
@ -4,3 +4,6 @@
|
||||
Si tiene alguna duda sobre la exactitud del contenido de esta
|
||||
traducción, la única referencia válida es la documentación oficial en
|
||||
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.
|
||||
|
@ -76,6 +76,5 @@ Traducciones al español
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
howto
|
||||
process/index
|
||||
wrappers/memory-barriers
|
||||
|
@ -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.
|
@ -1,4 +1,4 @@
|
||||
.. include:: ./disclaimer-sp.rst
|
||||
.. include:: ../disclaimer-sp.rst
|
||||
|
||||
:Original: :ref:`Documentation/process/howto.rst <process_howto>`
|
||||
:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
|
@ -24,3 +24,7 @@
|
||||
contribution-maturity-model
|
||||
security-bugs
|
||||
embargoed-hardware-issues
|
||||
handling-regressions
|
||||
management-style
|
||||
submit-checklist
|
||||
howto
|
||||
|
299
Documentation/translations/sp_SP/process/management-style.rst
Normal file
299
Documentation/translations/sp_SP/process/management-style.rst
Normal 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.
|
133
Documentation/translations/sp_SP/process/submit-checklist.rst
Normal file
133
Documentation/translations/sp_SP/process/submit-checklist.rst
Normal 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``).
|
155
Documentation/translations/zh_CN/arch/riscv/boot.rst
Normal file
155
Documentation/translations/zh_CN/arch/riscv/boot.rst
Normal 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之前发生任何重定位。
|
||||
- *所有* 的仪表化功能也必须被禁用(包括KASAN,ftrace和其他)。
|
||||
|
||||
由于使用来自不同编译单元的符号需要用这些标志编译该单元,我们建议尽可能不要使用
|
||||
外部符号。
|
@ -17,6 +17,7 @@ RISC-V 体系结构
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
boot
|
||||
boot-image-header
|
||||
vm-layout
|
||||
patch-acceptance
|
||||
|
@ -100,7 +100,7 @@ printk()的用法通常是这样的::
|
||||
|
||||
为了调试,还有两个有条件编译的宏:
|
||||
pr_debug()和pr_devel(),除非定义了 ``DEBUG`` (或者在pr_debug()的情况下定义了
|
||||
``CONFIG_DYNAMIC_DEBUG`` ),否则它们会被编译。
|
||||
``CONFIG_DYNAMIC_DEBUG`` ),否则它们不会被编译。
|
||||
|
||||
|
||||
函数接口
|
||||
|
@ -14,11 +14,8 @@
|
||||
有关测试专用工具的简要概述,参见
|
||||
Documentation/translations/zh_CN/dev-tools/testing-overview.rst
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
目录
|
||||
|
||||
.. toctree::
|
||||
:caption: 目录
|
||||
:maxdepth: 2
|
||||
|
||||
testing-overview
|
||||
|
@ -3,7 +3,7 @@
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/dev-tools/testing-overview.rst
|
||||
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
:Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
============
|
||||
内核测试指南
|
||||
|
@ -14,9 +14,8 @@
|
||||
通用型输入/输出(GPIO)
|
||||
=======================
|
||||
|
||||
目录:
|
||||
|
||||
.. toctree::
|
||||
:caption: 目录
|
||||
:maxdepth: 2
|
||||
|
||||
legacy
|
||||
|
@ -17,11 +17,8 @@ Linux驱动实现者的API指南
|
||||
内核提供了各种各样的接口来支持设备驱动的开发。这份文档只是对其中一些接口进行了
|
||||
一定程度的整理——希望随着时间的推移,它能变得更好!可用的小节可以在下面看到。
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
目录列表:
|
||||
|
||||
.. toctree::
|
||||
:caption: 目录列表
|
||||
:maxdepth: 2
|
||||
|
||||
gpio/index
|
||||
|
@ -8,9 +8,10 @@
|
||||
内核开发过程指南
|
||||
================
|
||||
|
||||
内容:
|
||||
本文档的目的是帮助开发人员(及其经理)以最小的挫折感与开发社区合作。它试图记录这个社区如何以一种不熟悉Linux内核开发(或者实际上是自由软件开发)的人可以访问的方式工作。虽然这里有一些技术资料,但这是一个面向过程的讨论,不需要深入了解内核编程就可以理解。
|
||||
|
||||
.. toctree::
|
||||
:caption: 内容
|
||||
:numbered:
|
||||
:maxdepth: 2
|
||||
|
||||
@ -22,5 +23,3 @@
|
||||
6.Followthrough
|
||||
7.AdvancedTopics
|
||||
8.Conclusion
|
||||
|
||||
本文档的目的是帮助开发人员(及其经理)以最小的挫折感与开发社区合作。它试图记录这个社区如何以一种不熟悉Linux内核开发(或者实际上是自由软件开发)的人可以访问的方式工作。虽然这里有一些技术资料,但这是一个面向过程的讨论,不需要深入了解内核编程就可以理解。
|
||||
|
@ -5,10 +5,11 @@
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :ref:`Documentation/process/index.rst <process_index>`
|
||||
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
|
||||
:Original: Documentation/process/index.rst
|
||||
|
||||
.. _cn_process_index:
|
||||
:翻译:
|
||||
|
||||
Alex Shi <alex.shi@linux.alibaba.com>
|
||||
|
||||
========================
|
||||
与Linux 内核社区一起工作
|
||||
@ -23,29 +24,55 @@
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
license-rules
|
||||
howto
|
||||
code-of-conduct
|
||||
code-of-conduct-interpretation
|
||||
development-process
|
||||
submitting-patches
|
||||
programming-language
|
||||
coding-style
|
||||
development-process
|
||||
maintainer-pgp-guide
|
||||
email-clients
|
||||
license-rules
|
||||
kernel-enforcement-statement
|
||||
kernel-driver-statement
|
||||
|
||||
TODOLIST:
|
||||
|
||||
* handling-regressions
|
||||
* maintainer-handbooks
|
||||
|
||||
安全方面, 请阅读:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
embargoed-hardware-issues
|
||||
|
||||
TODOLIST:
|
||||
|
||||
* security-bugs
|
||||
|
||||
其它大多数开发人员感兴趣的社区指南:
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
submit-checklist
|
||||
stable-api-nonsense
|
||||
stable-kernel-rules
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -1,58 +1,67 @@
|
||||
.. _cn_magicnumbers:
|
||||
|
||||
.. 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 魔术数
|
||||
============
|
||||
|
||||
这个文件是有关当前使用的魔术值注册表。当你给一个结构添加了一个魔术值,你也应该把这个魔术值添加到这个文件,因为我们最好把用于各种结构的魔术值统一起来。
|
||||
这个文件是有关当前使用的魔术值注册表。当你给一个结构体添加了一个魔术值,你也
|
||||
应该把这个魔术值添加到这个文件,因为我们最好把用于各种结构体的魔术值统一起来。
|
||||
|
||||
使用魔术值来保护内核数据结构是一个非常好的主意。这就允许你在运行期检查(a)一个结构是否已经被攻击,或者(b)你已经给一个例行程序通过了一个错误的结构。后一种情况特别地有用---特别是当你通过一个空指针指向结构体的时候。tty源码,例如,经常通过特定驱动使用这种方法并且反复地排列特定方面的结构。
|
||||
使用魔术值来保护内核数据结构是一个 **非常好的主意** 。这就允许你在运行时检
|
||||
查一个结构体(a)是否已经被攻击,或者(b)你已经给一个例程传递了一个错误的结构
|
||||
体。最后一种情况特别地有用---特别是当你通过一个空指针指向结构体的时候。例如,
|
||||
tty源码经常通过特定驱动使用这种方法用来反复地排列特定方面的结构体。
|
||||
|
||||
使用魔术值的方法是在结构的开始处声明的,如下::
|
||||
使用魔术值的方法是在结构体的开头声明它们,如下::
|
||||
|
||||
struct tty_ldisc {
|
||||
int magic;
|
||||
...
|
||||
};
|
||||
|
||||
当你以后给内核添加增强功能的时候,请遵守这条规则!这样就会节省数不清的调试时间,特别是一些古怪的情况,例如,数组超出范围并且重新写了超出部分。遵守这个规则,这些情况可以被快速地,安全地避免。
|
||||
当你以后给内核添加增强功能的时候,请遵守这条规则!这样就会节省数不清的调试
|
||||
时间,特别是一些古怪的情况,例如,数组超出范围并且覆盖写了超出部分。利用这
|
||||
个规则,这些情况可以被快速地,安全地检测到这些案例。
|
||||
|
||||
Theodore Ts'o
|
||||
31 Mar 94
|
||||
变更日志::
|
||||
|
||||
给当前的Linux 2.1.55添加魔术表。
|
||||
Theodore Ts'o
|
||||
31 Mar 94
|
||||
|
||||
Michael Chastain
|
||||
<mailto:mec@shout.net>
|
||||
22 Sep 1997
|
||||
给当前的Linux 2.1.55添加魔术表。
|
||||
|
||||
现在应该最新的Linux 2.1.112.因为在特性冻结期间,不能在2.2.x前改变任何东西。这些条目被数域所排序。
|
||||
Michael Chastain
|
||||
<mailto:mec@shout.net>
|
||||
22 Sep 1997
|
||||
|
||||
Krzysztof G.Baranowski
|
||||
<mailto: kgb@knm.org.pl>
|
||||
29 Jul 1998
|
||||
现在应该最新的Linux 2.1.112.因为在特性冻结期间,不能在2.2.x前改变任
|
||||
何东西。这些条目被数域所排序。
|
||||
|
||||
更新魔术表到Linux 2.5.45。刚好越过特性冻结,但是有可能还会有一些新的魔术值在2.6.x之前融入到内核中。
|
||||
Krzysztof G.Baranowski
|
||||
<mailto: kgb@knm.org.pl>
|
||||
29 Jul 1998
|
||||
|
||||
Petr Baudis
|
||||
<pasky@ucw.cz>
|
||||
03 Nov 2002
|
||||
更新魔术表到Linux 2.5.45。刚好越过特性冻结,但是有可能还会有一些新的魔
|
||||
术值在2.6.x之前融入到内核中。
|
||||
|
||||
更新魔术表到Linux 2.5.74。
|
||||
Petr Baudis
|
||||
<pasky@ucw.cz>
|
||||
03 Nov 2002
|
||||
|
||||
Fabian Frederick
|
||||
<ffrederick@users.sourceforge.net>
|
||||
09 Jul 2003
|
||||
更新魔术表到Linux 2.5.74。
|
||||
|
||||
Fabian Frederick
|
||||
<ffrederick@users.sourceforge.net>
|
||||
09 Jul 2003
|
||||
|
||||
===================== ================ ======================== ==========================================
|
||||
魔术数名 数字 结构 文件
|
||||
|
@ -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`` (秒): 如果在生命周期结束之前再次使用相同的
|
||||
密钥,倒计时将重置为另一段时间。默认值为 600(10 分钟)。
|
||||
- ``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 规
|
||||
范的一个重要方面,但最新版本的 GnuPG(2.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
|
@ -17,11 +17,8 @@ Linux 内核用户空间API指南
|
||||
在代码树中仍然可以找到有关用户空间的部分信息。这个手册意在成为这些信息
|
||||
聚集的地方。
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
目录
|
||||
|
||||
.. toctree::
|
||||
:caption: 目录
|
||||
:maxdepth: 2
|
||||
|
||||
no_new_privs
|
||||
|
@ -7,7 +7,7 @@ help. Contact the Chinese maintainer if this translation is outdated
|
||||
or if there is a problem with the translation.
|
||||
|
||||
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 的繁體中文翻譯
|
||||
|
||||
@ -16,9 +16,9 @@ Documentation/core-api/irq/index.rst 的繁體中文翻譯
|
||||
者翻譯存在問題,請聯繫繁體中文版維護者。
|
||||
|
||||
英文版維護者: Eric W. Biederman <ebiederman@xmission.com>
|
||||
繁體中文版維護者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版維護者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
繁體中文版翻譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
|
||||
以下爲正文
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 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/>
|
||||
=========================================
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
二分(bisect)缺陷
|
||||
+++++++++++++++++++
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
追蹤缺陷
|
||||
=========
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
.. include:: ../disclaimer-zh_TW.rst
|
||||
|
||||
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
:Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
清除 WARN_ONCE
|
||||
--------------
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
.. include:: ../disclaimer-zh_TW.rst
|
||||
|
||||
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
:Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
========
|
||||
CPU 負載
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
:Original: :doc:`../../../admin-guide/index`
|
||||
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
Linux 內核用戶和管理員指南
|
||||
==========================
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
解釋“No working init found.”啓動掛起消息
|
||||
=========================================
|
||||
|
@ -9,7 +9,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
|
||||
報告問題
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
安全缺陷
|
||||
=========
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
受污染的內核
|
||||
-------------
|
||||
|
@ -7,7 +7,7 @@
|
||||
:譯者:
|
||||
|
||||
吳想成 Wu XiangCheng <bobwxc@email.cn>
|
||||
胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
Unicode(統一碼)支持
|
||||
======================
|
||||
|
@ -5,7 +5,7 @@
|
||||
:Original: :ref:`Documentation/arch/arm64/amu.rst <amu_index>`
|
||||
|
||||
Translator: Bailu Lin <bailu.lin@vivo.com>
|
||||
Hu Haowen <src.res.211@gmail.com>
|
||||
Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
==================================
|
||||
AArch64 Linux 中擴展的活動監控單元
|
||||
|
@ -10,7 +10,7 @@ or if there is a problem with the translation.
|
||||
|
||||
M: Will Deacon <will.deacon@arm.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
|
||||
---------------------------------------------------------------------
|
||||
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>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
本文翻譯提交時的 Git 檢出點爲: 55f058e7574c3615dea4615573a19bdb258696c6
|
||||
|
||||
以下爲正文
|
||||
|
@ -5,7 +5,7 @@
|
||||
:Original: :ref:`Documentation/arch/arm64/elf_hwcaps.rst <elf_hwcaps_index>`
|
||||
|
||||
Translator: Bailu Lin <bailu.lin@vivo.com>
|
||||
Hu Haowen <src.res.211@gmail.com>
|
||||
Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
================
|
||||
ARM64 ELF hwcaps
|
||||
|
@ -5,7 +5,7 @@
|
||||
:Original: :ref:`Documentation/arch/arm64/hugetlbpage.rst <hugetlbpage_index>`
|
||||
|
||||
Translator: Bailu Lin <bailu.lin@vivo.com>
|
||||
Hu Haowen <src.res.211@gmail.com>
|
||||
Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
=====================
|
||||
ARM64中的 HugeTLBpage
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
:Original: :ref:`Documentation/arch/arm64/index.rst <arm64_index>`
|
||||
:Translator: Bailu Lin <bailu.lin@vivo.com>
|
||||
Hu Haowen <src.res.211@gmail.com>
|
||||
Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
.. _tw_arm64_index:
|
||||
|
||||
|
@ -11,7 +11,7 @@ or if there is a problem with the translation.
|
||||
Maintainer: Punit Agrawal <punit.agrawal@arm.com>
|
||||
Suzuki K. Poulose <suzuki.poulose@arm.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 的中文翻譯
|
||||
|
||||
@ -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>
|
||||
繁體中文版校譯者:胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版校譯者:胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
以下爲正文
|
||||
---------------------------------------------------------------------
|
||||
|
@ -10,7 +10,7 @@ or if there is a problem with the translation.
|
||||
|
||||
Maintainer: Catalin Marinas <catalin.marinas@arm.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 的中文翻譯
|
||||
|
||||
@ -24,7 +24,7 @@ Documentation/arch/arm64/memory.rst 的中文翻譯
|
||||
中文版維護者: 傅煒 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>
|
||||
|
||||
以下爲正文
|
||||
---------------------------------------------------------------------
|
||||
|
@ -5,7 +5,7 @@
|
||||
:Original: :ref:`Documentation/arch/arm64/perf.rst <perf_index>`
|
||||
|
||||
Translator: Bailu Lin <bailu.lin@vivo.com>
|
||||
Hu Haowen <src.res.211@gmail.com>
|
||||
Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
=============
|
||||
Perf 事件屬性
|
||||
|
@ -10,7 +10,7 @@ or if there is a problem with the translation.
|
||||
|
||||
M: Will Deacon <will.deacon@arm.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
|
||||
---------------------------------------------------------------------
|
||||
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>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
本文翻譯提交時的 Git 檢出點爲: 1926e54f115725a9248d0c4c65c22acaf94de4c4
|
||||
|
||||
以下爲正文
|
||||
|
@ -10,7 +10,7 @@ or if there is a problem with the translation.
|
||||
|
||||
Maintainer: Will Deacon <will.deacon@arm.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 的中文翻譯
|
||||
|
||||
@ -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>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
以下爲正文
|
||||
---------------------------------------------------------------------
|
||||
|
@ -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
|
||||
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 的繁體中文翻譯
|
||||
|
||||
如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文
|
||||
交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或
|
||||
者翻譯存在問題,請聯繫繁體中文版維護者。
|
||||
|
||||
繁體中文版維護者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
繁體中文版維護者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
繁體中文版翻譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
以下爲正文
|
||||
---------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Copyright 2004 Linus Torvalds
|
||||
Copyright 2004 Pavel Machek <pavel@ucw.cz>
|
||||
|
@ -3,7 +3,7 @@
|
||||
.. include:: ../disclaimer-zh_TW.rst
|
||||
|
||||
:Original: Documentation/dev-tools/testing-overview.rst
|
||||
:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
|
||||
:Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
|
||||
============
|
||||
內核測試指南
|
||||
|
@ -7,5 +7,5 @@
|
||||
|
||||
.. note::
|
||||
如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者,
|
||||
或者發送電子郵件給胡皓文以獲取幫助:<src.res.211@gmail.com>。
|
||||
或者發送電子郵件給胡皓文以獲取幫助:<2023002089@link.tyut.edu.cn>。
|
||||
|
||||
|
@ -14,7 +14,7 @@ Debugfs
|
||||
中文版維護者: 羅楚成 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
Loading…
Reference in New Issue
Block a user