Pull in wireless/main content since some new code would otherwise conflict with it.
Unified · Split
| @@ -37,6 +37,8 @@ · 36 unmodified lines | ||
| 37 | 37 | *.o |
| 38 | 38 | *.o.* |
| 39 | 39 | *.patch |
| 40 | +*.rmeta | |
| 41 | +*.rsi | |
| 40 | 42 | *.s |
| 41 | 43 | *.so |
| 42 | 44 | *.so.dbg |
| @@ -97,6 +99,7 @@ modules.order · 54 unmodified lines | ||
| 97 | 99 | !.gitattributes |
| 98 | 100 | !.gitignore |
| 99 | 101 | !.mailmap |
| 102 | +!.rustfmt.toml | |
| 100 | 103 | |
| 101 | 104 | # |
| 102 | 105 | # Generated include files |
| @@ -162,3 +165,6 @@ x509.genkey · 59 unmodified lines | ||
| 162 | 165 | |
| 163 | 166 | # Documentation toolchain |
| 164 | 167 | sphinx_*/ |
| 168 | + | |
| 169 | +# Rust analyzer configuration | |
| 170 | +/rust-project.json | |
| @@ -0,0 +1,12 @@ | ||
| 1 | +edition = "2021" | |
| 2 | +newline_style = "Unix" | |
| 3 | + | |
| 4 | +# Unstable options that help catching some mistakes in formatting and that we may want to enable | |
| 5 | +# when they become stable. | |
| 6 | +# | |
| 7 | +# They are kept here since they are useful to run from time to time. | |
| 8 | +#format_code_in_doc_comments = true | |
| 9 | +#reorder_impl_items = true | |
| 10 | +#comment_width = 100 | |
| 11 | +#wrap_comments = true | |
| 12 | +#normalize_comments = true | |
| @@ -3,7 +3,7 @@ Date: May 2011 · 2 unmodified lines | ||
| 3 | 3 | KernelVersion: 3.0 |
| 4 | 4 | Contact: Rafał Miłecki <zajec5@gmail.com> |
| 5 | 5 | Description: |
| 6 | − Each BCMA core has it's manufacturer id. See | |
| 6 | + Each BCMA core has its manufacturer id. See | |
| 7 | 7 | include/linux/bcma/bcma.h for possible values. |
| 8 | 8 | |
| 9 | 9 | What: /sys/bus/bcma/devices/.../id |
| @@ -31,7 +31,7 @@ Description: 'FCoE Controller' instances on the fcoe bus. · 30 unmodified lines | ||
| 31 | 31 | 1) Write interface name to ctlr_create 2) Configure the FCoE |
| 32 | 32 | Controller (ctlr_X) 3) Enable the FCoE Controller to begin |
| 33 | 33 | discovery and login. The FCoE Controller is destroyed by |
| 34 | − writing it's name, i.e. ctlr_X to the ctlr_delete file. | |
| 34 | + writing its name, i.e. ctlr_X to the ctlr_delete file. | |
| 35 | 35 | |
| 36 | 36 | Attributes: |
| 37 | 37 | |
| @@ -18,7 +18,7 @@ Description: · 17 unmodified lines | ||
| 18 | 18 | on the signal from which time of flight measurements are |
| 19 | 19 | taken. |
| 20 | 20 | The appropriate values to take is dependent on both the |
| 21 | − sensor and it's operating environment: | |
| 21 | + sensor and its operating environment: | |
| 22 | 22 | * as3935 (0-31 range) |
| 23 | 23 | 18 = indoors (default) |
| 24 | 24 | 14 = outdoors |
| @@ -296,7 +296,7 @@ Description: Processor frequency boosting control · 295 unmodified lines | ||
| 296 | 296 | |
| 297 | 297 | This switch controls the boost setting for the whole system. |
| 298 | 298 | Boosting allows the CPU and the firmware to run at a frequency |
| 299 | − beyond it's nominal limit. | |
| 299 | + beyond its nominal limit. | |
| 300 | 300 | |
| 301 | 301 | More details can be found in |
| 302 | 302 | Documentation/admin-guide/pm/cpufreq.rst |
| @@ -2,8 +2,8 @@ What: /sys/bus/platform/devices/ci_hdrc.0/role · 1 unmodified line | ||
| 2 | 2 | Date: Mar 2017 |
| 3 | 3 | Contact: Peter Chen <peter.chen@nxp.com> |
| 4 | 4 | Description: |
| 5 | − It returns string "gadget" or "host" when read it, it indicates | |
| 6 | − current controller role. | |
| 5 | + When read, it returns string "gadget" or "host", indicating | |
| 6 | + the current controller role. | |
| 7 | 7 | |
| 8 | − It will do role switch when write "gadget" or "host" to it. | |
| 8 | + It will do role switch when "gadget" or "host" is written to it. | |
| 9 | 9 | Only controller at dual-role configuration supports writing. |
| @@ -152,7 +152,7 @@ Description: · 151 unmodified lines | ||
| 152 | 152 | case further investigation is required to determine which |
| 153 | 153 | device is causing the problem. Note that genuine RTC clock |
| 154 | 154 | values (such as when pm_trace has not been used), can still |
| 155 | − match a device and output it's name here. | |
| 155 | + match a device and output its name here. | |
| 156 | 156 | |
| 157 | 157 | What: /sys/power/pm_async |
| 158 | 158 | Date: January 2009 |
| @@ -66,8 +66,13 @@ over a rather long period of time, but improvements are always welcome! · 65 unmodified lines | ||
| 66 | 66 | As a rough rule of thumb, any dereference of an RCU-protected |
| 67 | 67 | pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(), |
| 68 | 68 | rcu_read_lock_sched(), or by the appropriate update-side lock. |
| 69 | − Disabling of preemption can serve as rcu_read_lock_sched(), but | |
| 70 | − is less readable and prevents lockdep from detecting locking issues. | |
| 69 | + Explicit disabling of preemption (preempt_disable(), for example) | |
| 70 | + can serve as rcu_read_lock_sched(), but is less readable and | |
| 71 | + prevents lockdep from detecting locking issues. | |
| 72 | + | |
| 73 | + Please not that you *cannot* rely on code known to be built | |
| 74 | + only in non-preemptible kernels. Such code can and will break, | |
| 75 | + especially in kernels built with CONFIG_PREEMPT_COUNT=y. | |
| 71 | 76 | |
| 72 | 77 | Letting RCU-protected pointers "leak" out of an RCU read-side |
| 73 | 78 | critical section is every bit as bad as letting them leak out |
| @@ -185,6 +190,9 @@ over a rather long period of time, but improvements are always welcome! · 111 unmodified lines | ||
| 185 | 190 | |
| 186 | 191 | 5. If call_rcu() or call_srcu() is used, the callback function will |
| 187 | 192 | be called from softirq context. In particular, it cannot block. |
| 193 | + If you need the callback to block, run that code in a workqueue | |
| 194 | + handler scheduled from the callback. The queue_rcu_work() | |
| 195 | + function does this for you in the case of call_rcu(). | |
| 188 | 196 | |
| 189 | 197 | 6. Since synchronize_rcu() can block, it cannot be called |
| 190 | 198 | from any sort of irq context. The same rule applies |
| @@ -297,7 +305,8 @@ over a rather long period of time, but improvements are always welcome! · 106 unmodified lines | ||
| 297 | 305 | the machine. |
| 298 | 306 | |
| 299 | 307 | d. Periodically invoke synchronize_rcu(), permitting a limited |
| 300 | − number of updates per grace period. | |
| 308 | + number of updates per grace period. Better yet, periodically | |
| 309 | + invoke rcu_barrier() to wait for all outstanding callbacks. | |
| 301 | 310 | |
| 302 | 311 | The same cautions apply to call_srcu() and kfree_rcu(). |
| 303 | 312 | |
| @@ -477,6 +486,6 @@ over a rather long period of time, but improvements are always welcome! · 173 unmodified lines | ||
| 477 | 486 | So if you need to wait for both an RCU grace period and for |
| 478 | 487 | all pre-existing call_rcu() callbacks, you will need to execute |
| 479 | 488 | both rcu_barrier() and synchronize_rcu(), if necessary, using |
| 480 | − something like workqueues to to execute them concurrently. | |
| 489 | + something like workqueues to execute them concurrently. | |
| 481 | 490 | |
| 482 | 491 | See rcubarrier.rst for more information. |
| @@ -61,7 +61,7 @@ checking of rcu_dereference() primitives: · 60 unmodified lines | ||
| 61 | 61 | rcu_access_pointer(p): |
| 62 | 62 | Return the value of the pointer and omit all barriers, |
| 63 | 63 | but retain the compiler constraints that prevent duplicating |
| 64 | − or coalescsing. This is useful when when testing the | |
| 64 | + or coalescsing. This is useful when testing the | |
| 65 | 65 | value of the pointer itself, for example, against NULL. |
| 66 | 66 | |
| 67 | 67 | The rcu_dereference_check() check expression can be any boolean |
| @@ -128,10 +128,16 @@ Follow these rules to keep your RCU code working properly: · 127 unmodified lines | ||
| 128 | 128 | This sort of comparison occurs frequently when scanning |
| 129 | 129 | RCU-protected circular linked lists. |
| 130 | 130 | |
| 131 | − Note that if checks for being within an RCU read-side | |
| 132 | − critical section are not required and the pointer is never | |
| 133 | − dereferenced, rcu_access_pointer() should be used in place | |
| 134 | − of rcu_dereference(). | |
| 131 | + Note that if the pointer comparison is done outside | |
| 132 | + of an RCU read-side critical section, and the pointer | |
| 133 | + is never dereferenced, rcu_access_pointer() should be | |
| 134 | + used in place of rcu_dereference(). In most cases, | |
| 135 | + it is best to avoid accidental dereferences by testing | |
| 136 | + the rcu_access_pointer() return value directly, without | |
| 137 | + assigning it to a variable. | |
| 138 | + | |
| 139 | + Within an RCU read-side critical section, there is little | |
| 140 | + reason to use rcu_access_pointer(). | |
| 135 | 141 | |
| 136 | 142 | - The comparison is against a pointer that references memory |
| 137 | 143 | that was initialized "a long time ago." The reason |
| @@ -6,13 +6,15 @@ What is RCU? -- "Read, Copy, Update" · 5 unmodified lines | ||
| 6 | 6 | Please note that the "What is RCU?" LWN series is an excellent place |
| 7 | 7 | to start learning about RCU: |
| 8 | 8 | |
| 9 | −| 1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ | |
| 10 | −| 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ | |
| 11 | −| 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ | |
| 12 | −| 4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ | |
| 13 | −| 2010 Big API Table http://lwn.net/Articles/419086/ | |
| 14 | −| 5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ | |
| 15 | −| 2014 Big API Table http://lwn.net/Articles/609973/ | |
| 9 | +| 1. What is RCU, Fundamentally? https://lwn.net/Articles/262464/ | |
| 10 | +| 2. What is RCU? Part 2: Usage https://lwn.net/Articles/263130/ | |
| 11 | +| 3. RCU part 3: the RCU API https://lwn.net/Articles/264090/ | |
| 12 | +| 4. The RCU API, 2010 Edition https://lwn.net/Articles/418853/ | |
| 13 | +| 2010 Big API Table https://lwn.net/Articles/419086/ | |
| 14 | +| 5. The RCU API, 2014 Edition https://lwn.net/Articles/609904/ | |
| 15 | +| 2014 Big API Table https://lwn.net/Articles/609973/ | |
| 16 | +| 6. The RCU API, 2019 Edition https://lwn.net/Articles/777036/ | |
| 17 | +| 2019 Big API Table https://lwn.net/Articles/777165/ | |
| 16 | 18 | |
| 17 | 19 | |
| 18 | 20 | What is RCU? |
| @@ -915,13 +917,18 @@ which an RCU reference is held include: · 896 unmodified lines | ||
| 915 | 917 | The understanding that RCU provides a reference that only prevents a |
| 916 | 918 | change of type is particularly visible with objects allocated from a |
| 917 | 919 | slab cache marked ``SLAB_TYPESAFE_BY_RCU``. RCU operations may yield a |
| 918 | −reference to an object from such a cache that has been concurrently | |
| 919 | −freed and the memory reallocated to a completely different object, | |
| 920 | −though of the same type. In this case RCU doesn't even protect the | |
| 921 | −identity of the object from changing, only its type. So the object | |
| 922 | −found may not be the one expected, but it will be one where it is safe | |
| 923 | −to take a reference or spinlock and then confirm that the identity | |
| 924 | −matches the expectations. | |
| 920 | +reference to an object from such a cache that has been concurrently freed | |
| 921 | +and the memory reallocated to a completely different object, though of | |
| 922 | +the same type. In this case RCU doesn't even protect the identity of the | |
| 923 | +object from changing, only its type. So the object found may not be the | |
| 924 | +one expected, but it will be one where it is safe to take a reference | |
| 925 | +(and then potentially acquiring a spinlock), allowing subsequent code | |
| 926 | +to check whether the identity matches expectations. It is tempting | |
| 927 | +to simply acquire the spinlock without first taking the reference, but | |
| 928 | +unfortunately any spinlock in a ``SLAB_TYPESAFE_BY_RCU`` object must be | |
| 929 | +initialized after each and every call to kmem_cache_alloc(), which renders | |
| 930 | +reference-free spinlock acquisition completely unsafe. Therefore, when | |
| 931 | +using ``SLAB_TYPESAFE_BY_RCU``, make proper use of a reference counter. | |
| 925 | 932 | |
| 926 | 933 | With traditional reference counting -- such as that implemented by the |
| 927 | 934 | kref library in Linux -- there is typically code that runs when the last |
| @@ -1057,14 +1064,20 @@ SRCU: Initialization/cleanup:: · 129 unmodified lines | ||
| 1057 | 1064 | init_srcu_struct |
| 1058 | 1065 | cleanup_srcu_struct |
| 1059 | 1066 | |
| 1060 | −All: lockdep-checked RCU-protected pointer access:: | |
| 1067 | +All: lockdep-checked RCU utility APIs:: | |
| 1061 | 1068 | |
| 1062 | − rcu_access_pointer | |
| 1063 | − rcu_dereference_raw | |
| 1064 | 1069 | RCU_LOCKDEP_WARN |
| 1065 | 1070 | rcu_sleep_check |
| 1066 | 1071 | RCU_NONIDLE |
| 1067 | 1072 | |
| 1073 | +All: Unchecked RCU-protected pointer access:: | |
| 1074 | + | |
| 1075 | + rcu_dereference_raw | |
| 1076 | + | |
| 1077 | +All: Unchecked RCU-protected pointer access with dereferencing prohibited:: | |
| 1078 | + | |
| 1079 | + rcu_access_pointer | |
| 1080 | + | |
| 1068 | 1081 | See the comment headers in the source code (or the docbook generated |
| 1069 | 1082 | from them) for more information. |
| 1070 | 1083 | |
| @@ -262,8 +262,6 @@ Compiling the kernel · 261 unmodified lines | ||
| 262 | 262 | - Make sure you have at least gcc 5.1 available. |
| 263 | 263 | For more information, refer to :ref:`Documentation/process/changes.rst <changes>`. |
| 264 | 264 | |
| 265 | − Please note that you can still run a.out user programs with this kernel. | |
| 266 | − | |
| 267 | 265 | - Do a ``make`` to create a compressed kernel image. It is also |
| 268 | 266 | possible to do ``make install`` if you have lilo installed to suit the |
| 269 | 267 | kernel makefiles, but you may want to check your particular lilo setup first. |
| @@ -332,85 +330,10 @@ Compiling the kernel · 62 unmodified lines | ||
| 332 | 330 | If something goes wrong |
| 333 | 331 | ----------------------- |
| 334 | 332 | |
| 335 | − - If you have problems that seem to be due to kernel bugs, please check | |
| 336 | − the file MAINTAINERS to see if there is a particular person associated | |
| 337 | − with the part of the kernel that you are having trouble with. If there | |
| 338 | − isn't anyone listed there, then the second best thing is to mail | |
| 339 | − them to me (torvalds@linux-foundation.org), and possibly to any other | |
| 340 | − relevant mailing-list or to the newsgroup. | |
| 341 | − | |
| 342 | − - In all bug-reports, *please* tell what kernel you are talking about, | |
| 343 | − how to duplicate the problem, and what your setup is (use your common | |
| 344 | − sense). If the problem is new, tell me so, and if the problem is | |
| 345 | − old, please try to tell me when you first noticed it. | |
| 346 | − | |
| 347 | − - If the bug results in a message like:: | |
| 348 | − | |
| 349 | − unable to handle kernel paging request at address C0000010 | |
| 350 | − Oops: 0002 | |
| 351 | − EIP: 0010:XXXXXXXX | |
| 352 | − eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx | |
| 353 | − esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx | |
| 354 | − ds: xxxx es: xxxx fs: xxxx gs: xxxx | |
| 355 | − Pid: xx, process nr: xx | |
| 356 | − xx xx xx xx xx xx xx xx xx xx | |
| 357 | − | |
| 358 | − or similar kernel debugging information on your screen or in your | |
| 359 | − system log, please duplicate it *exactly*. The dump may look | |
| 360 | − incomprehensible to you, but it does contain information that may | |
| 361 | − help debugging the problem. The text above the dump is also | |
| 362 | − important: it tells something about why the kernel dumped code (in | |
| 363 | − the above example, it's due to a bad kernel pointer). More information | |
| 364 | − on making sense of the dump is in Documentation/admin-guide/bug-hunting.rst | |
| 365 | − | |
| 366 | − - If you compiled the kernel with CONFIG_KALLSYMS you can send the dump | |
| 367 | − as is, otherwise you will have to use the ``ksymoops`` program to make | |
| 368 | − sense of the dump (but compiling with CONFIG_KALLSYMS is usually preferred). | |
| 369 | − This utility can be downloaded from | |
| 370 | − https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ . | |
| 371 | − Alternatively, you can do the dump lookup by hand: | |
| 372 | − | |
| 373 | − - In debugging dumps like the above, it helps enormously if you can | |
| 374 | − look up what the EIP value means. The hex value as such doesn't help | |
| 375 | − me or anybody else very much: it will depend on your particular | |
| 376 | − kernel setup. What you should do is take the hex value from the EIP | |
| 377 | − line (ignore the ``0010:``), and look it up in the kernel namelist to | |
| 378 | − see which kernel function contains the offending address. | |
| 379 | − | |
| 380 | − To find out the kernel function name, you'll need to find the system | |
| 381 | − binary associated with the kernel that exhibited the symptom. This is | |
| 382 | − the file 'linux/vmlinux'. To extract the namelist and match it against | |
| 383 | − the EIP from the kernel crash, do:: | |
| 384 | − | |
| 385 | − nm vmlinux | sort | less | |
| 386 | − | |
| 387 | − This will give you a list of kernel addresses sorted in ascending | |
| 388 | − order, from which it is simple to find the function that contains the | |
| 389 | − offending address. Note that the address given by the kernel | |
| 390 | − debugging messages will not necessarily match exactly with the | |
| 391 | − function addresses (in fact, that is very unlikely), so you can't | |
| 392 | − just 'grep' the list: the list will, however, give you the starting | |
| 393 | − point of each kernel function, so by looking for the function that | |
| 394 | − has a starting address lower than the one you are searching for but | |
| 395 | − is followed by a function with a higher address you will find the one | |
| 396 | − you want. In fact, it may be a good idea to include a bit of | |
| 397 | − "context" in your problem report, giving a few lines around the | |
| 398 | − interesting one. | |
| 399 | − | |
| 400 | − If you for some reason cannot do the above (you have a pre-compiled | |
| 401 | − kernel image or similar), telling me as much about your setup as | |
| 402 | − possible will help. Please read | |
| 403 | − 'Documentation/admin-guide/reporting-issues.rst' for details. | |
| 404 | − | |
| 405 | − - Alternatively, you can use gdb on a running kernel. (read-only; i.e. you | |
| 406 | − cannot change values or set break points.) To do this, first compile the | |
| 407 | − kernel with -g; edit arch/x86/Makefile appropriately, then do a ``make | |
| 408 | − clean``. You'll also need to enable CONFIG_PROC_FS (via ``make config``). | |
| 409 | − | |
| 410 | − After you've rebooted with the new kernel, do ``gdb vmlinux /proc/kcore``. | |
| 411 | − You can now use all the usual gdb commands. The command to look up the | |
| 412 | − point where your system crashed is ``l *0xXXXXXXXX``. (Replace the XXXes | |
| 413 | − with the EIP value.) | |
| 414 | − | |
| 415 | − gdb'ing a non-running kernel currently fails because ``gdb`` (wrongly) | |
| 416 | − disregards the starting offset for which the kernel is compiled. | |
| 333 | +If you have problems that seem to be due to kernel bugs, please follow the | |
| 334 | +instructions at 'Documentation/admin-guide/reporting-issues.rst'. | |
| 335 | + | |
| 336 | +Hints on understanding kernel bug reports are in | |
| 337 | +'Documentation/admin-guide/bug-hunting.rst'. More on debugging the kernel | |
| 338 | +with gdb is in 'Documentation/dev-tools/gdb-kernel-debugging.rst' and | |
| 339 | +'Documentation/dev-tools/kgdb.rst'. | |
| @@ -1,13 +0,0 @@ | ||
| 1 | −.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | − | |
| 3 | −=============== | |
| 4 | −Overriding DSDT | |
| 5 | −=============== | |
| 6 | − | |
| 7 | −Linux supports a method of overriding the BIOS DSDT: | |
| 8 | − | |
| 9 | −CONFIG_ACPI_CUSTOM_DSDT - builds the image into the kernel. | |
| 10 | − | |
| 11 | −When to use this method is described in detail on the | |
| 12 | −Linux/ACPI home page: | |
| 13 | −https://01.org/linux-acpi/documentation/overriding-dsdt | |
| @@ -613,6 +613,7 @@ kernel command line. · 612 unmodified lines | ||
| 613 | 613 | eibrs enhanced IBRS |
| 614 | 614 | eibrs,retpoline enhanced IBRS + Retpolines |
| 615 | 615 | eibrs,lfence enhanced IBRS + LFENCE |
| 616 | + ibrs use IBRS to protect kernel | |
| 616 | 617 | |
| 617 | 618 | Not specifying this option is equivalent to |
| 618 | 619 | spectre_v2=auto. |
| @@ -200,7 +200,7 @@ prb · 199 unmodified lines | ||
| 200 | 200 | |
| 201 | 201 | A pointer to the printk ringbuffer (struct printk_ringbuffer). This |
| 202 | 202 | may be pointing to the static boot ringbuffer or the dynamically |
| 203 | −allocated ringbuffer, depending on when the the core dump occurred. | |
| 203 | +allocated ringbuffer, depending on when the core dump occurred. | |
| 204 | 204 | Used by user-space tools to read the active kernel log buffer. |
| 205 | 205 | |
| 206 | 206 | printk_rb_static |
| @@ -3801,6 +3801,10 @@ · 3800 unmodified lines | ||
| 3801 | 3801 | |
| 3802 | 3802 | nox2apic [X86-64,APIC] Do not enable x2APIC mode. |
| 3803 | 3803 | |
| 3804 | + NOTE: this parameter will be ignored on systems with the | |
| 3805 | + LEGACY_XAPIC_DISABLED bit set in the | |
| 3806 | + IA32_XAPIC_DISABLE_STATUS MSR. | |
| 3807 | + | |
| 3804 | 3808 | nps_mtm_hs_ctr= [KNL,ARC] |
| 3805 | 3809 | This parameter sets the maximum duration, in |
| 3806 | 3810 | cycles, each HW thread of the CTOP can run |
| @@ -65,7 +65,7 @@ HugePages_Surp · 64 unmodified lines | ||
| 65 | 65 | may be temporarily larger than the maximum number of surplus huge |
| 66 | 66 | pages when the system is under memory pressure. |
| 67 | 67 | Hugepagesize |
| 68 | − is the default hugepage size (in Kb). | |
| 68 | + is the default hugepage size (in kB). | |
| 69 | 69 | Hugetlb |
| 70 | 70 | is the total amount of memory (in kB), consumed by huge |
| 71 | 71 | pages of all sizes. |
| @@ -102,6 +102,9 @@ Values: · 101 unmodified lines | ||
| 102 | 102 | - 1 - enable JIT hardening for unprivileged users only |
| 103 | 103 | - 2 - enable JIT hardening for all users |
| 104 | 104 | |
| 105 | +where "privileged user" in this context means a process having | |
| 106 | +CAP_BPF or CAP_SYS_ADMIN in the root user name space. | |
| 107 | + | |
| 105 | 108 | bpf_jit_kallsyms |
| 106 | 109 | ---------------- |
| 107 | 110 | |
| @@ -134,6 +134,12 @@ More detailed explanation for tainting · 133 unmodified lines | ||
| 134 | 134 | scsi/snic on something else than x86_64, scsi/ips on non |
| 135 | 135 | x86/x86_64/itanium, have broken firmware settings for the |
| 136 | 136 | irqchip/irq-gic on arm64 ...). |
| 137 | + - x86/x86_64: Microcode late loading is dangerous and will result in | |
| 138 | + tainting the kernel. It requires that all CPUs rendezvous to make sure | |
| 139 | + the update happens when the system is as quiescent as possible. However, | |
| 140 | + a higher priority MCE/SMI/NMI can move control flow away from that | |
| 141 | + rendezvous and interrupt the update, which can be detrimental to the | |
| 142 | + machine. | |
| 137 | 143 | |
| 138 | 144 | 3) ``R`` if a module was force unloaded by ``rmmod -f``, ``' '`` if all |
| 139 | 145 | modules were unloaded normally. |
| @@ -0,0 +1,30 @@ | ||
| 1 | +.. contents:: | |
| 2 | +.. sectnum:: | |
| 3 | + | |
| 4 | +========================== | |
| 5 | +Clang implementation notes | |
| 6 | +========================== | |
| 7 | + | |
| 8 | +This document provides more details specific to the Clang/LLVM implementation of the eBPF instruction set. | |
| 9 | + | |
| 10 | +Versions | |
| 11 | +======== | |
| 12 | + | |
| 13 | +Clang defined "CPU" versions, where a CPU version of 3 corresponds to the current eBPF ISA. | |
| 14 | + | |
| 15 | +Clang can select the eBPF ISA version using ``-mcpu=v3`` for example to select version 3. | |
| 16 | + | |
| 17 | +Arithmetic instructions | |
| 18 | +======================= | |
| 19 | + | |
| 20 | +For CPU versions prior to 3, Clang v7.0 and later can enable ``BPF_ALU`` support with | |
| 21 | +``-Xclang -target-feature -Xclang +alu32``. In CPU version 3, support is automatically included. | |
| 22 | + | |
| 23 | +Atomic operations | |
| 24 | +================= | |
| 25 | + | |
| 26 | +Clang can generate atomic instructions by default when ``-mcpu=v3`` is | |
| 27 | +enabled. If a lower version for ``-mcpu`` is set, the only atomic instruction | |
| 28 | +Clang can generate is ``BPF_ADD`` *without* ``BPF_FETCH``. If you need to enable | |
| 29 | +the atomics features, while keeping a lower ``-mcpu`` version, you can use | |
| 30 | +``-Xclang -target-feature -Xclang +alu32``. | |
| @@ -26,6 +26,8 @@ that goes into great technical depth about the BPF Architecture. · 25 unmodified lines | ||
| 26 | 26 | classic_vs_extended.rst |
| 27 | 27 | bpf_licensing |
| 28 | 28 | test_debug |
| 29 | + clang-notes | |
| 30 | + linux-notes | |
| 29 | 31 | other |
| 30 | 32 | |
| 31 | 33 | .. only:: subproject and html |
| @@ -1,7 +1,12 @@ | ||
| 1 | +.. contents:: | |
| 2 | +.. sectnum:: | |
| 3 | + | |
| 4 | +======================================== | |
| 5 | +eBPF Instruction Set Specification, v1.0 | |
| 6 | +======================================== | |
| 7 | + | |
| 8 | +This document specifies version 1.0 of the eBPF instruction set. | |
| 1 | 9 | |
| 2 | −==================== | |
| 3 | −eBPF Instruction Set | |
| 4 | −==================== | |
| 5 | 10 | |
| 6 | 11 | Registers and calling convention |
| 7 | 12 | ================================ |
| @@ -11,10 +16,10 @@ all of which are 64-bits wide. · 3 unmodified lines | ||
| 11 | 16 | |
| 12 | 17 | The eBPF calling convention is defined as: |
| 13 | 18 | |
| 14 | − * R0: return value from function calls, and exit value for eBPF programs | |
| 15 | − * R1 - R5: arguments for function calls | |
| 16 | − * R6 - R9: callee saved registers that function calls will preserve | |
| 17 | − * R10: read-only frame pointer to access stack | |
| 19 | +* R0: return value from function calls, and exit value for eBPF programs | |
| 20 | +* R1 - R5: arguments for function calls | |
| 21 | +* R6 - R9: callee saved registers that function calls will preserve | |
| 22 | +* R10: read-only frame pointer to access stack | |
| 18 | 23 | |
| 19 | 24 | R0 - R5 are scratch registers and eBPF programs needs to spill/fill them if |
| 20 | 25 | necessary across calls. |
| @@ -24,17 +29,17 @@ Instruction encoding · 3 unmodified lines | ||
| 24 | 29 | |
| 25 | 30 | eBPF has two instruction encodings: |
| 26 | 31 | |
| 27 | − * the basic instruction encoding, which uses 64 bits to encode an instruction | |
| 28 | − * the wide instruction encoding, which appends a second 64-bit immediate value | |
| 29 | − (imm64) after the basic instruction for a total of 128 bits. | |
| 32 | +* the basic instruction encoding, which uses 64 bits to encode an instruction | |
| 33 | +* the wide instruction encoding, which appends a second 64-bit immediate value | |
| 34 | + (imm64) after the basic instruction for a total of 128 bits. | |
| 30 | 35 | |
| 31 | 36 | The basic instruction encoding looks as follows: |
| 32 | 37 | |
| 33 | − ============= ======= =============== ==================== ============ | |
| 34 | − 32 bits (MSB) 16 bits 4 bits 4 bits 8 bits (LSB) | |
| 35 | − ============= ======= =============== ==================== ============ | |
| 36 | − immediate offset source register destination register opcode | |
| 37 | − ============= ======= =============== ==================== ============ | |
| 38 | +============= ======= =============== ==================== ============ | |
| 39 | +32 bits (MSB) 16 bits 4 bits 4 bits 8 bits (LSB) | |
| 40 | +============= ======= =============== ==================== ============ | |
| 41 | +immediate offset source register destination register opcode | |
| 42 | +============= ======= =============== ==================== ============ | |
| 38 | 43 | |
| 39 | 44 | Note that most instructions do not use all of the fields. |
| 40 | 45 | Unused fields shall be cleared to zero. |
| @@ -44,30 +49,30 @@ Instruction classes · 3 unmodified lines | ||
| 44 | 49 | |
| 45 | 50 | The three LSB bits of the 'opcode' field store the instruction class: |
| 46 | 51 | |
| 47 | − ========= ===== =============================== | |
| 48 | − class value description | |
| 49 | − ========= ===== =============================== | |
| 50 | − BPF_LD 0x00 non-standard load operations | |
| 51 | − BPF_LDX 0x01 load into register operations | |
| 52 | − BPF_ST 0x02 store from immediate operations | |
| 53 | − BPF_STX 0x03 store from register operations | |
| 54 | − BPF_ALU 0x04 32-bit arithmetic operations | |
| 55 | − BPF_JMP 0x05 64-bit jump operations | |
| 56 | − BPF_JMP32 0x06 32-bit jump operations | |
| 57 | − BPF_ALU64 0x07 64-bit arithmetic operations | |
| 58 | − ========= ===== =============================== | |
| 52 | +========= ===== =============================== =================================== | |
| 53 | +class value description reference | |
| 54 | +========= ===== =============================== =================================== | |
| 55 | +BPF_LD 0x00 non-standard load operations `Load and store instructions`_ | |
| 56 | +BPF_LDX 0x01 load into register operations `Load and store instructions`_ | |
| 57 | +BPF_ST 0x02 store from immediate operations `Load and store instructions`_ | |
| 58 | +BPF_STX 0x03 store from register operations `Load and store instructions`_ | |
| 59 | +BPF_ALU 0x04 32-bit arithmetic operations `Arithmetic and jump instructions`_ | |
| 60 | +BPF_JMP 0x05 64-bit jump operations `Arithmetic and jump instructions`_ | |
| 61 | +BPF_JMP32 0x06 32-bit jump operations `Arithmetic and jump instructions`_ | |
| 62 | +BPF_ALU64 0x07 64-bit arithmetic operations `Arithmetic and jump instructions`_ | |
| 63 | +========= ===== =============================== =================================== | |
| 59 | 64 | |
| 60 | 65 | Arithmetic and jump instructions |
| 61 | 66 | ================================ |
| 62 | 67 | |
| 63 | −For arithmetic and jump instructions (BPF_ALU, BPF_ALU64, BPF_JMP and | |
| 64 | −BPF_JMP32), the 8-bit 'opcode' field is divided into three parts: | |
| 68 | +For arithmetic and jump instructions (``BPF_ALU``, ``BPF_ALU64``, ``BPF_JMP`` and | |
| 69 | +``BPF_JMP32``), the 8-bit 'opcode' field is divided into three parts: | |
| 65 | 70 | |
| 66 | − ============== ====== ================= | |
| 67 | − 4 bits (MSB) 1 bit 3 bits (LSB) | |
| 68 | − ============== ====== ================= | |
| 69 | − operation code source instruction class | |
| 70 | − ============== ====== ================= | |
| 71 | +============== ====== ================= | |
| 72 | +4 bits (MSB) 1 bit 3 bits (LSB) | |
| 73 | +============== ====== ================= | |
| 74 | +operation code source instruction class | |
| 75 | +============== ====== ================= | |
| 71 | 76 | |
| 72 | 77 | The 4th bit encodes the source operand: |
| 73 | 78 | |
| @@ -84,66 +89,66 @@ The four MSB bits store the operation code. · 10 unmodified lines | ||
| 84 | 89 | Arithmetic instructions |
| 85 | 90 | ----------------------- |
| 86 | 91 | |
| 87 | −BPF_ALU uses 32-bit wide operands while BPF_ALU64 uses 64-bit wide operands for | |
| 92 | +``BPF_ALU`` uses 32-bit wide operands while ``BPF_ALU64`` uses 64-bit wide operands for | |
| 88 | 93 | otherwise identical operations. |
| 89 | −The code field encodes the operation as below: | |
| 90 | − | |
| 91 | − ======== ===== ================================================= | |
| 92 | − code value description | |
| 93 | − ======== ===== ================================================= | |
| 94 | − BPF_ADD 0x00 dst += src | |
| 95 | − BPF_SUB 0x10 dst -= src | |
| 96 | − BPF_MUL 0x20 dst \*= src | |
| 97 | − BPF_DIV 0x30 dst /= src | |
| 98 | − BPF_OR 0x40 dst \|= src | |
| 99 | − BPF_AND 0x50 dst &= src | |
| 100 | − BPF_LSH 0x60 dst <<= src | |
| 101 | − BPF_RSH 0x70 dst >>= src | |
| 102 | − BPF_NEG 0x80 dst = ~src | |
| 103 | − BPF_MOD 0x90 dst %= src | |
| 104 | − BPF_XOR 0xa0 dst ^= src | |
| 105 | − BPF_MOV 0xb0 dst = src | |
| 106 | − BPF_ARSH 0xc0 sign extending shift right | |
| 107 | − BPF_END 0xd0 byte swap operations (see separate section below) | |
| 108 | − ======== ===== ================================================= | |
| 109 | − | |
| 110 | −BPF_ADD | BPF_X | BPF_ALU means:: | |
| 94 | +The 'code' field encodes the operation as below: | |
| 95 | + | |
| 96 | +======== ===== ========================================================== | |
| 97 | +code value description | |
| 98 | +======== ===== ========================================================== | |
| 99 | +BPF_ADD 0x00 dst += src | |
| 100 | +BPF_SUB 0x10 dst -= src | |
| 101 | +BPF_MUL 0x20 dst \*= src | |
| 102 | +BPF_DIV 0x30 dst /= src | |
| 103 | +BPF_OR 0x40 dst \|= src | |
| 104 | +BPF_AND 0x50 dst &= src | |
| 105 | +BPF_LSH 0x60 dst <<= src | |
| 106 | +BPF_RSH 0x70 dst >>= src | |
| 107 | +BPF_NEG 0x80 dst = ~src | |
| 108 | +BPF_MOD 0x90 dst %= src | |
| 109 | +BPF_XOR 0xa0 dst ^= src | |
| 110 | +BPF_MOV 0xb0 dst = src | |
| 111 | +BPF_ARSH 0xc0 sign extending shift right | |
| 112 | +BPF_END 0xd0 byte swap operations (see `Byte swap instructions`_ below) | |
| 113 | +======== ===== ========================================================== | |
| 114 | + | |
| 115 | +``BPF_ADD | BPF_X | BPF_ALU`` means:: | |
| 111 | 116 | |
| 112 | 117 | dst_reg = (u32) dst_reg + (u32) src_reg; |
| 113 | 118 | |
| 114 | −BPF_ADD | BPF_X | BPF_ALU64 means:: | |
| 119 | +``BPF_ADD | BPF_X | BPF_ALU64`` means:: | |
| 115 | 120 | |
| 116 | 121 | dst_reg = dst_reg + src_reg |
| 117 | 122 | |
| 118 | −BPF_XOR | BPF_K | BPF_ALU means:: | |
| 123 | +``BPF_XOR | BPF_K | BPF_ALU`` means:: | |
| 119 | 124 | |
| 120 | 125 | src_reg = (u32) src_reg ^ (u32) imm32 |
| 121 | 126 | |
| 122 | −BPF_XOR | BPF_K | BPF_ALU64 means:: | |
| 127 | +``BPF_XOR | BPF_K | BPF_ALU64`` means:: | |
| 123 | 128 | |
| 124 | 129 | src_reg = src_reg ^ imm32 |
| 125 | 130 | |
| 126 | 131 | |
| 127 | 132 | Byte swap instructions |
| 128 | −---------------------- | |
| 133 | +~~~~~~~~~~~~~~~~~~~~~~ | |
| 129 | 134 | |
| 130 | 135 | The byte swap instructions use an instruction class of ``BPF_ALU`` and a 4-bit |
| 131 | −code field of ``BPF_END``. | |
| 136 | +'code' field of ``BPF_END``. | |
| 132 | 137 | |
| 133 | 138 | The byte swap instructions operate on the destination register |
| 134 | 139 | only and do not use a separate source register or immediate value. |
| 135 | 140 | |
| 136 | −The 1-bit source operand field in the opcode is used to to select what byte | |
| 141 | +The 1-bit source operand field in the opcode is used to select what byte | |
| 137 | 142 | order the operation convert from or to: |
| 138 | 143 | |
| 139 | − ========= ===== ================================================= | |
| 140 | − source value description | |
| 141 | − ========= ===== ================================================= | |
| 142 | − BPF_TO_LE 0x00 convert between host byte order and little endian | |
| 143 | − BPF_TO_BE 0x08 convert between host byte order and big endian | |
| 144 | − ========= ===== ================================================= | |
| 144 | +========= ===== ================================================= | |
| 145 | +source value description | |
| 146 | +========= ===== ================================================= | |
| 147 | +BPF_TO_LE 0x00 convert between host byte order and little endian | |
| 148 | +BPF_TO_BE 0x08 convert between host byte order and big endian | |
| 149 | +========= ===== ================================================= | |
| 145 | 150 | |
| 146 | −The imm field encodes the width of the swap operations. The following widths | |
| 151 | +The 'imm' field encodes the width of the swap operations. The following widths | |
| 147 | 152 | are supported: 16, 32 and 64. |
| 148 | 153 | |
| 149 | 154 | Examples: |
| @@ -156,35 +161,31 @@ Examples: · 6 unmodified lines | ||
| 156 | 161 | |
| 157 | 162 | dst_reg = htobe64(dst_reg) |
| 158 | 163 | |
| 159 | −``BPF_FROM_LE`` and ``BPF_FROM_BE`` exist as aliases for ``BPF_TO_LE`` and | |
| 160 | −``BPF_TO_BE`` respectively. | |
| 161 | − | |
| 162 | − | |
| 163 | 164 | Jump instructions |
| 164 | 165 | ----------------- |
| 165 | 166 | |
| 166 | −BPF_JMP32 uses 32-bit wide operands while BPF_JMP uses 64-bit wide operands for | |
| 167 | +``BPF_JMP32`` uses 32-bit wide operands while ``BPF_JMP`` uses 64-bit wide operands for | |
| 167 | 168 | otherwise identical operations. |
| 168 | −The code field encodes the operation as below: | |
| 169 | − | |
| 170 | − ======== ===== ========================= ============ | |
| 171 | − code value description notes | |
| 172 | − ======== ===== ========================= ============ | |
| 173 | − BPF_JA 0x00 PC += off BPF_JMP only | |
| 174 | − BPF_JEQ 0x10 PC += off if dst == src | |
| 175 | − BPF_JGT 0x20 PC += off if dst > src unsigned | |
| 176 | − BPF_JGE 0x30 PC += off if dst >= src unsigned | |
| 177 | − BPF_JSET 0x40 PC += off if dst & src | |
| 178 | − BPF_JNE 0x50 PC += off if dst != src | |
| 179 | − BPF_JSGT 0x60 PC += off if dst > src signed | |
| 180 | − BPF_JSGE 0x70 PC += off if dst >= src signed | |
| 181 | − BPF_CALL 0x80 function call | |
| 182 | − BPF_EXIT 0x90 function / program return BPF_JMP only | |
| 183 | − BPF_JLT 0xa0 PC += off if dst < src unsigned | |
| 184 | − BPF_JLE 0xb0 PC += off if dst <= src unsigned | |
| 185 | − BPF_JSLT 0xc0 PC += off if dst < src signed | |
| 186 | − BPF_JSLE 0xd0 PC += off if dst <= src signed | |
| 187 | − ======== ===== ========================= ============ | |
| 169 | +The 'code' field encodes the operation as below: | |
| 170 | + | |
| 171 | +======== ===== ========================= ============ | |
| 172 | +code value description notes | |
| 173 | +======== ===== ========================= ============ | |
| 174 | +BPF_JA 0x00 PC += off BPF_JMP only | |
| 175 | +BPF_JEQ 0x10 PC += off if dst == src | |
| 176 | +BPF_JGT 0x20 PC += off if dst > src unsigned | |
| 177 | +BPF_JGE 0x30 PC += off if dst >= src unsigned | |
| 178 | +BPF_JSET 0x40 PC += off if dst & src | |
| 179 | +BPF_JNE 0x50 PC += off if dst != src | |
| 180 | +BPF_JSGT 0x60 PC += off if dst > src signed | |
| 181 | +BPF_JSGE 0x70 PC += off if dst >= src signed | |
| 182 | +BPF_CALL 0x80 function call | |
| 183 | +BPF_EXIT 0x90 function / program return BPF_JMP only | |
| 184 | +BPF_JLT 0xa0 PC += off if dst < src unsigned | |
| 185 | +BPF_JLE 0xb0 PC += off if dst <= src unsigned | |
| 186 | +BPF_JSLT 0xc0 PC += off if dst < src signed | |
| 187 | +BPF_JSLE 0xd0 PC += off if dst <= src signed | |
| 188 | +======== ===== ========================= ============ | |
| 188 | 189 | |
| 189 | 190 | The eBPF program needs to store the return value into register R0 before doing a |
| 190 | 191 | BPF_EXIT. |
| @@ -193,14 +194,26 @@ BPF_EXIT. · 2 unmodified lines | ||
| 193 | 194 | Load and store instructions |
| 194 | 195 | =========================== |
| 195 | 196 | |
| 196 | −For load and store instructions (BPF_LD, BPF_LDX, BPF_ST and BPF_STX), the | |
| 197 | +For load and store instructions (``BPF_LD``, ``BPF_LDX``, ``BPF_ST``, and ``BPF_STX``), the | |
| 197 | 198 | 8-bit 'opcode' field is divided as: |
| 198 | 199 | |
| 199 | − ============ ====== ================= | |
| 200 | − 3 bits (MSB) 2 bits 3 bits (LSB) | |
| 201 | − ============ ====== ================= | |
| 202 | − mode size instruction class | |
| 203 | − ============ ====== ================= | |
| 200 | +============ ====== ================= | |
| 201 | +3 bits (MSB) 2 bits 3 bits (LSB) | |
| 202 | +============ ====== ================= | |
| 203 | +mode size instruction class | |
| 204 | +============ ====== ================= | |
| 205 | + | |
| 206 | +The mode modifier is one of: | |
| 207 | + | |
| 208 | + ============= ===== ==================================== ============= | |
| 209 | + mode modifier value description reference | |
| 210 | + ============= ===== ==================================== ============= | |
| 211 | + BPF_IMM 0x00 64-bit immediate instructions `64-bit immediate instructions`_ | |
| 212 | + BPF_ABS 0x20 legacy BPF packet access (absolute) `Legacy BPF Packet access instructions`_ | |
| 213 | + BPF_IND 0x40 legacy BPF packet access (indirect) `Legacy BPF Packet access instructions`_ | |
| 214 | + BPF_MEM 0x60 regular load and store operations `Regular load and store operations`_ | |
| 215 | + BPF_ATOMIC 0xc0 atomic operations `Atomic operations`_ | |
| 216 | + ============= ===== ==================================== ============= | |
| 204 | 217 | |
| 205 | 218 | The size modifier is one of: |
| 206 | 219 | |
| @@ -213,19 +226,6 @@ The size modifier is one of: · 6 unmodified lines | ||
| 213 | 226 | BPF_DW 0x18 double word (8 bytes) |
| 214 | 227 | ============= ===== ===================== |
| 215 | 228 | |
| 216 | −The mode modifier is one of: | |
| 217 | − | |
| 218 | − ============= ===== ==================================== | |
| 219 | − mode modifier value description | |
| 220 | − ============= ===== ==================================== | |
| 221 | − BPF_IMM 0x00 64-bit immediate instructions | |
| 222 | − BPF_ABS 0x20 legacy BPF packet access (absolute) | |
| 223 | − BPF_IND 0x40 legacy BPF packet access (indirect) | |
| 224 | − BPF_MEM 0x60 regular load and store operations | |
| 225 | − BPF_ATOMIC 0xc0 atomic operations | |
| 226 | − ============= ===== ==================================== | |
| 227 | − | |
| 228 | − | |
| 229 | 229 | Regular load and store operations |
| 230 | 230 | --------------------------------- |
| 231 | 231 | |
| @@ -256,44 +256,42 @@ by other eBPF programs or means outside of this specification. · 24 unmodified lines | ||
| 256 | 256 | All atomic operations supported by eBPF are encoded as store operations |
| 257 | 257 | that use the ``BPF_ATOMIC`` mode modifier as follows: |
| 258 | 258 | |
| 259 | − * ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations | |
| 260 | − * ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations | |
| 261 | − * 8-bit and 16-bit wide atomic operations are not supported. | |
| 259 | +* ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations | |
| 260 | +* ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations | |
| 261 | +* 8-bit and 16-bit wide atomic operations are not supported. | |
| 262 | 262 | |
| 263 | −The imm field is used to encode the actual atomic operation. | |
| 263 | +The 'imm' field is used to encode the actual atomic operation. | |
| 264 | 264 | Simple atomic operation use a subset of the values defined to encode |
| 265 | −arithmetic operations in the imm field to encode the atomic operation: | |
| 265 | +arithmetic operations in the 'imm' field to encode the atomic operation: | |
| 266 | 266 | |
| 267 | − ======== ===== =========== | |
| 268 | − imm value description | |
| 269 | − ======== ===== =========== | |
| 270 | − BPF_ADD 0x00 atomic add | |
| 271 | − BPF_OR 0x40 atomic or | |
| 272 | − BPF_AND 0x50 atomic and | |
| 273 | − BPF_XOR 0xa0 atomic xor | |
| 274 | − ======== ===== =========== | |
| 267 | +======== ===== =========== | |
| 268 | +imm value description | |
| 269 | +======== ===== =========== | |
| 270 | +BPF_ADD 0x00 atomic add | |
| 271 | +BPF_OR 0x40 atomic or | |
| 272 | +BPF_AND 0x50 atomic and | |
| 273 | +BPF_XOR 0xa0 atomic xor | |
| 274 | +======== ===== =========== | |
| 275 | 275 | |
| 276 | 276 | |
| 277 | −``BPF_ATOMIC | BPF_W | BPF_STX`` with imm = BPF_ADD means:: | |
| 277 | +``BPF_ATOMIC | BPF_W | BPF_STX`` with 'imm' = BPF_ADD means:: | |
| 278 | 278 | |
| 279 | 279 | *(u32 *)(dst_reg + off16) += src_reg |
| 280 | 280 | |
| 281 | −``BPF_ATOMIC | BPF_DW | BPF_STX`` with imm = BPF ADD means:: | |
| 281 | +``BPF_ATOMIC | BPF_DW | BPF_STX`` with 'imm' = BPF ADD means:: | |
| 282 | 282 | |
| 283 | 283 | *(u64 *)(dst_reg + off16) += src_reg |
| 284 | 284 | |
| 285 | −``BPF_XADD`` is a deprecated name for ``BPF_ATOMIC | BPF_ADD``. | |
| 286 | − | |
| 287 | 285 | In addition to the simple atomic operations, there also is a modifier and |
| 288 | 286 | two complex atomic operations: |
| 289 | 287 | |
| 290 | − =========== ================ =========================== | |
| 291 | − imm value description | |
| 292 | − =========== ================ =========================== | |
| 293 | − BPF_FETCH 0x01 modifier: return old value | |
| 294 | − BPF_XCHG 0xe0 | BPF_FETCH atomic exchange | |
| 295 | − BPF_CMPXCHG 0xf0 | BPF_FETCH atomic compare and exchange | |
| 296 | − =========== ================ =========================== | |
| 288 | +=========== ================ =========================== | |
| 289 | +imm value description | |
| 290 | +=========== ================ =========================== | |
| 291 | +BPF_FETCH 0x01 modifier: return old value | |
| 292 | +BPF_XCHG 0xe0 | BPF_FETCH atomic exchange | |
| 293 | +BPF_CMPXCHG 0xf0 | BPF_FETCH atomic compare and exchange | |
| 294 | +=========== ================ =========================== | |
| 297 | 295 | |
| 298 | 296 | The ``BPF_FETCH`` modifier is optional for simple atomic operations, and |
| 299 | 297 | always set for the complex atomic operations. If the ``BPF_FETCH`` flag |
| @@ -309,16 +307,10 @@ The ``BPF_CMPXCHG`` operation atomically compares the value addressed by · 9 unmodified lines | ||
| 309 | 307 | value that was at ``dst_reg + off`` before the operation is zero-extended |
| 310 | 308 | and loaded back to ``R0``. |
| 311 | 309 | |
| 312 | −Clang can generate atomic instructions by default when ``-mcpu=v3`` is | |
| 313 | −enabled. If a lower version for ``-mcpu`` is set, the only atomic instruction | |
| 314 | −Clang can generate is ``BPF_ADD`` *without* ``BPF_FETCH``. If you need to enable | |
| 315 | −the atomics features, while keeping a lower ``-mcpu`` version, you can use | |
| 316 | −``-Xclang -target-feature -Xclang +alu32``. | |
| 317 | − | |
| 318 | 310 | 64-bit immediate instructions |
| 319 | 311 | ----------------------------- |
| 320 | 312 | |
| 321 | −Instructions with the ``BPF_IMM`` mode modifier use the wide instruction | |
| 313 | +Instructions with the ``BPF_IMM`` 'mode' modifier use the wide instruction | |
| 322 | 314 | encoding for an extra imm64 value. |
| 323 | 315 | |
| 324 | 316 | There is currently only one such instruction. |
| @@ -331,36 +323,6 @@ There is currently only one such instruction. · 6 unmodified lines | ||
| 331 | 323 | Legacy BPF Packet access instructions |
| 332 | 324 | ------------------------------------- |
| 333 | 325 | |
| 334 | −eBPF has special instructions for access to packet data that have been | |
| 335 | −carried over from classic BPF to retain the performance of legacy socket | |
| 336 | −filters running in the eBPF interpreter. | |
| 337 | − | |
| 338 | −The instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and | |
| 339 | −``BPF_IND | <size> | BPF_LD``. | |
| 340 | − | |
| 341 | −These instructions are used to access packet data and can only be used when | |
| 342 | −the program context is a pointer to networking packet. ``BPF_ABS`` | |
| 343 | −accesses packet data at an absolute offset specified by the immediate data | |
| 344 | −and ``BPF_IND`` access packet data at an offset that includes the value of | |
| 345 | −a register in addition to the immediate data. | |
| 346 | − | |
| 347 | −These instructions have seven implicit operands: | |
| 348 | − | |
| 349 | − * Register R6 is an implicit input that must contain pointer to a | |
| 350 | − struct sk_buff. | |
| 351 | − * Register R0 is an implicit output which contains the data fetched from | |
| 352 | − the packet. | |
| 353 | − * Registers R1-R5 are scratch registers that are clobbered after a call to | |
| 354 | − ``BPF_ABS | BPF_LD`` or ``BPF_IND | BPF_LD`` instructions. | |
| 355 | − | |
| 356 | −These instructions have an implicit program exit condition as well. When an | |
| 357 | −eBPF program is trying to access the data beyond the packet boundary, the | |
| 358 | −program execution will be aborted. | |
| 359 | − | |
| 360 | −``BPF_ABS | BPF_W | BPF_LD`` means:: | |
| 361 | − | |
| 362 | − R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + imm32)) | |
| 363 | − | |
| 364 | −``BPF_IND | BPF_W | BPF_LD`` means:: | |
| 365 | − | |
| 366 | − R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32)) | |
| 326 | +eBPF previously introduced special instructions for access to packet data that were | |
| 327 | +carried over from classic BPF. However, these instructions are | |
| 328 | +deprecated and should no longer be used. | |
| @@ -137,14 +137,22 @@ KF_ACQUIRE and KF_RET_NULL flags. · 136 unmodified lines | ||
| 137 | 137 | -------------------------- |
| 138 | 138 | |
| 139 | 139 | The KF_TRUSTED_ARGS flag is used for kfuncs taking pointer arguments. It |
| 140 | −indicates that the all pointer arguments will always be refcounted, and have | |
| 141 | −their offset set to 0. It can be used to enforce that a pointer to a refcounted | |
| 142 | −object acquired from a kfunc or BPF helper is passed as an argument to this | |
| 143 | −kfunc without any modifications (e.g. pointer arithmetic) such that it is | |
| 144 | −trusted and points to the original object. This flag is often used for kfuncs | |
| 145 | −that operate (change some property, perform some operation) on an object that | |
| 146 | −was obtained using an acquire kfunc. Such kfuncs need an unchanged pointer to | |
| 147 | −ensure the integrity of the operation being performed on the expected object. | |
| 140 | +indicates that the all pointer arguments will always have a guaranteed lifetime, | |
| 141 | +and pointers to kernel objects are always passed to helpers in their unmodified | |
| 142 | +form (as obtained from acquire kfuncs). | |
| 143 | + | |
| 144 | +It can be used to enforce that a pointer to a refcounted object acquired from a | |
| 145 | +kfunc or BPF helper is passed as an argument to this kfunc without any | |
| 146 | +modifications (e.g. pointer arithmetic) such that it is trusted and points to | |
| 147 | +the original object. | |
| 148 | + | |
| 149 | +Meanwhile, it is also allowed pass pointers to normal memory to such kfuncs, | |
| 150 | +but those can have a non-zero offset. | |
| 151 | + | |
| 152 | +This flag is often used for kfuncs that operate (change some property, perform | |
| 153 | +some operation) on an object that was obtained using an acquire kfunc. Such | |
| 154 | +kfuncs need an unchanged pointer to ensure the integrity of the operation being | |
| 155 | +performed on the expected object. | |
| 148 | 156 | |
| 149 | 157 | 2.4.6 KF_SLEEPABLE flag |
| 150 | 158 | ----------------------- |
| @@ -0,0 +1,53 @@ | ||
| 1 | +.. contents:: | |
| 2 | +.. sectnum:: | |
| 3 | + | |
| 4 | +========================== | |
| 5 | +Linux implementation notes | |
| 6 | +========================== | |
| 7 | + | |
| 8 | +This document provides more details specific to the Linux kernel implementation of the eBPF instruction set. | |
| 9 | + | |
| 10 | +Byte swap instructions | |
| 11 | +====================== | |
| 12 | + | |
| 13 | +``BPF_FROM_LE`` and ``BPF_FROM_BE`` exist as aliases for ``BPF_TO_LE`` and ``BPF_TO_BE`` respectively. | |
| 14 | + | |
| 15 | +Legacy BPF Packet access instructions | |
| 16 | +===================================== | |
| 17 | + | |
| 18 | +As mentioned in the `ISA standard documentation <instruction-set.rst#legacy-bpf-packet-access-instructions>`_, | |
| 19 | +Linux has special eBPF instructions for access to packet data that have been | |
| 20 | +carried over from classic BPF to retain the performance of legacy socket | |
| 21 | +filters running in the eBPF interpreter. | |
| 22 | + | |
| 23 | +The instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and | |
| 24 | +``BPF_IND | <size> | BPF_LD``. | |
| 25 | + | |
| 26 | +These instructions are used to access packet data and can only be used when | |
| 27 | +the program context is a pointer to a networking packet. ``BPF_ABS`` | |
| 28 | +accesses packet data at an absolute offset specified by the immediate data | |
| 29 | +and ``BPF_IND`` access packet data at an offset that includes the value of | |
| 30 | +a register in addition to the immediate data. | |
| 31 | + | |
| 32 | +These instructions have seven implicit operands: | |
| 33 | + | |
| 34 | +* Register R6 is an implicit input that must contain a pointer to a | |
| 35 | + struct sk_buff. | |
| 36 | +* Register R0 is an implicit output which contains the data fetched from | |
| 37 | + the packet. | |
| 38 | +* Registers R1-R5 are scratch registers that are clobbered by the | |
| 39 | + instruction. | |
| 40 | + | |
| 41 | +These instructions have an implicit program exit condition as well. If an | |
| 42 | +eBPF program attempts access data beyond the packet boundary, the | |
| 43 | +program execution will be aborted. | |
| 44 | + | |
| 45 | +``BPF_ABS | BPF_W | BPF_LD`` (0x20) means:: | |
| 46 | + | |
| 47 | + R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + imm)) | |
| 48 | + | |
| 49 | +where ``ntohl()`` converts a 32-bit value from network byte order to host byte order. | |
| 50 | + | |
| 51 | +``BPF_IND | BPF_W | BPF_LD`` (0x40) means:: | |
| 52 | + | |
| 53 | + R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + src + imm)) | |
| @@ -31,7 +31,7 @@ The map uses key of type of either ``__u64 cgroup_inode_id`` or · 30 unmodified lines | ||
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | 33 | ``cgroup_inode_id`` is the inode id of the cgroup directory. |
| 34 | −``attach_type`` is the the program's attach type. | |
| 34 | +``attach_type`` is the program's attach type. | |
| 35 | 35 | |
| 36 | 36 | Linux 5.9 added support for type ``__u64 cgroup_inode_id`` as the key type. |
| 37 | 37 | When this key type is used, then all attach types of the particular cgroup and |
| @@ -155,7 +155,7 @@ However, the BPF program can still only associate with one map of each type · 117 unmodified lines | ||
| 155 | 155 | ``BPF_MAP_TYPE_CGROUP_STORAGE`` or more than one |
| 156 | 156 | ``BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE``. |
| 157 | 157 | |
| 158 | −In all versions, userspace may use the the attach parameters of cgroup and | |
| 158 | +In all versions, userspace may use the attach parameters of cgroup and | |
| 159 | 159 | attach type pair in ``struct bpf_cgroup_storage_key`` as the key to the BPF map |
| 160 | 160 | APIs to read or update the storage for a given attachment. For Linux 5.9 |
| 161 | 161 | attach type shared storages, only the first value in the struct, cgroup inode |
| @@ -15,6 +15,18 @@ · 14 unmodified lines | ||
| 15 | 15 | import sys |
| 16 | 16 | import os |
| 17 | 17 | import sphinx |
| 18 | +import shutil | |
| 19 | + | |
| 20 | +# helper | |
| 21 | +# ------ | |
| 22 | + | |
| 23 | +def have_command(cmd): | |
| 24 | + """Search ``cmd`` in the ``PATH`` environment. | |
| 25 | + | |
| 26 | + If found, return True. | |
| 27 | + If not found, return False. | |
| 28 | + """ | |
| 29 | + return shutil.which(cmd) is not None | |
| 18 | 30 | |
| 19 | 31 | # Get Sphinx version |
| 20 | 32 | major, minor, patch = sphinx.version_info[:3] |
| @@ -107,7 +119,32 @@ else: · 86 unmodified lines | ||
| 107 | 119 | autosectionlabel_prefix_document = True |
| 108 | 120 | autosectionlabel_maxdepth = 2 |
| 109 | 121 | |
| 110 | −extensions.append("sphinx.ext.imgmath") | |
| 122 | +# Load math renderer: | |
| 123 | +# For html builder, load imgmath only when its dependencies are met. | |
| 124 | +# mathjax is the default math renderer since Sphinx 1.8. | |
| 125 | +have_latex = have_command('latex') | |
| 126 | +have_dvipng = have_command('dvipng') | |
| 127 | +load_imgmath = have_latex and have_dvipng | |
| 128 | + | |
| 129 | +# Respect SPHINX_IMGMATH (for html docs only) | |
| 130 | +if 'SPHINX_IMGMATH' in os.environ: | |
| 131 | + env_sphinx_imgmath = os.environ['SPHINX_IMGMATH'] | |
| 132 | + if 'yes' in env_sphinx_imgmath: | |
| 133 | + load_imgmath = True | |
| 134 | + elif 'no' in env_sphinx_imgmath: | |
| 135 | + load_imgmath = False | |
| 136 | + else: | |
| 137 | + sys.stderr.write("Unknown env SPHINX_IMGMATH=%s ignored.\n" % env_sphinx_imgmath) | |
| 138 | + | |
| 139 | +# Always load imgmath for Sphinx <1.8 or for epub docs | |
| 140 | +load_imgmath = (load_imgmath or (major == 1 and minor < 8) | |
| 141 | + or 'epub' in sys.argv) | |
| 142 | + | |
| 143 | +if load_imgmath: | |
| 144 | + extensions.append("sphinx.ext.imgmath") | |
| 145 | + math_renderer = 'imgmath' | |
| 146 | +else: | |
| 147 | + math_renderer = 'mathjax' | |
| 111 | 148 | |
| 112 | 149 | # Add any paths that contain templates here, relative to this directory. |
| 113 | 150 | templates_path = ['_templates'] |
| @@ -333,7 +370,8 @@ html_static_path = ['sphinx-static'] · 219 unmodified lines | ||
| 333 | 370 | html_use_smartypants = False |
| 334 | 371 | |
| 335 | 372 | # Custom sidebar templates, maps document names to template names. |
| 336 | −#html_sidebars = {} | |
| 373 | +# Note that the RTD theme ignores this. | |
| 374 | +html_sidebars = { '**': ['searchbox.html', 'localtoc.html', 'sourcelink.html']} | |
| 337 | 375 | |
| 338 | 376 | # Additional templates that should be rendered to pages, maps page names to |
| 339 | 377 | # template names. |
| @@ -43,10 +43,11 @@ annotated objects like this, tools can be run on them to generate more useful · 42 unmodified lines | ||
| 43 | 43 | information. In particular, on properly annotated objects, ``objtool`` can be |
| 44 | 44 | run to check and fix the object if needed. Currently, ``objtool`` can report |
| 45 | 45 | missing frame pointer setup/destruction in functions. It can also |
| 46 | −automatically generate annotations for :doc:`ORC unwinder <x86/orc-unwinder>` | |
| 46 | +automatically generate annotations for the ORC unwinder | |
| 47 | +(Documentation/x86/orc-unwinder.rst) | |
| 47 | 48 | for most code. Both of these are especially important to support reliable |
| 48 | −stack traces which are in turn necessary for :doc:`Kernel live patching | |
| 49 | −<livepatch/livepatch>`. | |
| 49 | +stack traces which are in turn necessary for kernel live patching | |
| 50 | +(Documentation/livepatch/livepatch.rst). | |
| 50 | 51 | |
| 51 | 52 | Caveat and Discussion |
| 52 | 53 | --------------------- |
| @@ -560,7 +560,7 @@ available: · 559 unmodified lines | ||
| 560 | 560 | * cpuhp_state_remove_instance(state, node) |
| 561 | 561 | * cpuhp_state_remove_instance_nocalls(state, node) |
| 562 | 562 | |
| 563 | −The arguments are the same as for the the cpuhp_state_add_instance*() | |
| 563 | +The arguments are the same as for the cpuhp_state_add_instance*() | |
| 564 | 564 | variants above. |
| 565 | 565 | |
| 566 | 566 | The functions differ in the way how the installed callbacks are treated: |
| @@ -23,6 +23,7 @@ it. · 22 unmodified lines | ||
| 23 | 23 | printk-formats |
| 24 | 24 | printk-index |
| 25 | 25 | symbol-namespaces |
| 26 | + asm-annotations | |
| 26 | 27 | |
| 27 | 28 | Data structures and low-level utilities |
| 28 | 29 | ======================================= |
| @@ -44,6 +45,8 @@ Library functionality that is used throughout the kernel. · 15 unmodified lines | ||
| 44 | 45 | this_cpu_ops |
| 45 | 46 | timekeeping |
| 46 | 47 | errseq |
| 48 | + wrappers/atomic_t | |
| 49 | + wrappers/atomic_bitops | |
| 47 | 50 | |
| 48 | 51 | Low level entry and exit |
| 49 | 52 | ======================== |
| @@ -67,6 +70,7 @@ Documentation/locking/index.rst for more related documentation. · 17 unmodified lines | ||
| 67 | 70 | local_ops |
| 68 | 71 | padata |
| 69 | 72 | ../RCU/index |
| 73 | + wrappers/memory-barriers.rst | |
| 70 | 74 | |
| 71 | 75 | Low-level hardware management |
| 72 | 76 | ============================= |
| @@ -71,7 +71,7 @@ variety of methods: · 70 unmodified lines | ||
| 71 | 71 | Note that irq domain lookups must happen in contexts that are |
| 72 | 72 | compatible with a RCU read-side critical section. |
| 73 | 73 | |
| 74 | −The irq_create_mapping() function must be called *atleast once* | |
| 74 | +The irq_create_mapping() function must be called *at least once* | |
| 75 | 75 | before any call to irq_find_mapping(), lest the descriptor will not |
| 76 | 76 | be allocated. |
| 77 | 77 | |
| @@ -625,6 +625,16 @@ Examples:: · 624 unmodified lines | ||
| 625 | 625 | %p4cc Y10 little-endian (0x20303159) |
| 626 | 626 | %p4cc NV12 big-endian (0xb231564e) |
| 627 | 627 | |
| 628 | +Rust | |
| 629 | +---- | |
| 630 | + | |
| 631 | +:: | |
| 632 | + | |
| 633 | + %pA | |
| 634 | + | |
| 635 | +Only intended to be used from Rust code to format ``core::fmt::Arguments``. | |
| 636 | +Do *not* use it from C. | |
| 637 | + | |
| 628 | 638 | Thanks |
| 629 | 639 | ====== |
| 630 | 640 | |
| @@ -0,0 +1,18 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + This is a simple wrapper to bring atomic_bitops.txt into the RST world | |
| 3 | + until such a time as that file can be converted directly. | |
| 4 | + | |
| 5 | +============= | |
| 6 | +Atomic bitops | |
| 7 | +============= | |
| 8 | + | |
| 9 | +.. raw:: latex | |
| 10 | + | |
| 11 | + \footnotesize | |
| 12 | + | |
| 13 | +.. include:: ../../atomic_bitops.txt | |
| 14 | + :literal: | |
| 15 | + | |
| 16 | +.. raw:: latex | |
| 17 | + | |
| 18 | + \normalsize | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + This is a simple wrapper to bring atomic_t.txt into the RST world | |
| 3 | + until such a time as that file can be converted directly. | |
| 4 | + | |
| 5 | +============ | |
| 6 | +Atomic types | |
| 7 | +============ | |
| 8 | + | |
| 9 | +.. raw:: latex | |
| 10 | + | |
| 11 | + \footnotesize | |
| 12 | + | |
| 13 | +.. include:: ../../atomic_t.txt | |
| 14 | + :literal: | |
| 15 | + | |
| 16 | +.. raw:: latex | |
| 17 | + | |
| 18 | + \normalsize | |
| 19 | + | |
| @@ -0,0 +1,18 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + This is a simple wrapper to bring memory-barriers.txt into the RST world | |
| 3 | + until such a time as that file can be converted directly. | |
| 4 | + | |
| 5 | +============================ | |
| 6 | +Linux kernel memory barriers | |
| 7 | +============================ | |
| 8 | + | |
| 9 | +.. raw:: latex | |
| 10 | + | |
| 11 | + \footnotesize | |
| 12 | + | |
| 13 | +.. include:: ../../memory-barriers.txt | |
| 14 | + :literal: | |
| 15 | + | |
| 16 | +.. raw:: latex | |
| 17 | + | |
| 18 | + \normalsize | |
| @@ -57,6 +57,11 @@ properties: · 56 unmodified lines | ||
| 57 | 57 | - description: interrupt ID for I2C event |
| 58 | 58 | - description: interrupt ID for I2C error |
| 59 | 59 | |
| 60 | + interrupt-names: | |
| 61 | + items: | |
| 62 | + - const: event | |
| 63 | + - const: error | |
| 64 | + | |
| 60 | 65 | resets: |
| 61 | 66 | maxItems: 1 |
| 62 | 67 | |
| @@ -92,6 +97,8 @@ properties: · 29 unmodified lines | ||
| 92 | 97 | - description: register offset within syscfg |
| 93 | 98 | - description: register bitmask for FMP bit |
| 94 | 99 | |
| 100 | + wakeup-source: true | |
| 101 | + | |
| 95 | 102 | required: |
| 96 | 103 | - compatible |
| 97 | 104 | - reg |
| @@ -144,6 +144,12 @@ properties: · 143 unmodified lines | ||
| 144 | 144 | Mark the corresponding energy efficient ethernet mode as |
| 145 | 145 | broken and request the ethernet to stop advertising it. |
| 146 | 146 | |
| 147 | + pses: | |
| 148 | + $ref: /schemas/types.yaml#/definitions/phandle-array | |
| 149 | + maxItems: 1 | |
| 150 | + description: | |
| 151 | + Specifies a reference to a node representing a Power Sourcing Equipment. | |
| 152 | + | |
| 147 | 153 | phy-is-integrated: |
| 148 | 154 | $ref: /schemas/types.yaml#/definitions/flag |
| 149 | 155 | description: |
| @@ -128,7 +128,7 @@ examples: · 127 unmodified lines | ||
| 128 | 128 | |
| 129 | 129 | i2c-int-rising; |
| 130 | 130 | |
| 131 | − reset-n-io = <&gpio3 19 GPIO_ACTIVE_HIGH>; | |
| 131 | + reset-n-io = <&gpio3 19 GPIO_ACTIVE_LOW>; | |
| 132 | 132 | }; |
| 133 | 133 | }; |
| 134 | 134 | |
| @@ -151,7 +151,7 @@ examples: · 16 unmodified lines | ||
| 151 | 151 | interrupt-parent = <&gpio1>; |
| 152 | 152 | interrupts = <17 IRQ_TYPE_EDGE_RISING>; |
| 153 | 153 | |
| 154 | − reset-n-io = <&gpio3 19 GPIO_ACTIVE_HIGH>; | |
| 154 | + reset-n-io = <&gpio3 19 GPIO_ACTIVE_LOW>; | |
| 155 | 155 | }; |
| 156 | 156 | }; |
| 157 | 157 | |
| @@ -162,7 +162,7 @@ examples: · 4 unmodified lines | ||
| 162 | 162 | nfc { |
| 163 | 163 | compatible = "marvell,nfc-uart"; |
| 164 | 164 | |
| 165 | − reset-n-io = <&gpio3 16 GPIO_ACTIVE_HIGH>; | |
| 165 | + reset-n-io = <&gpio3 16 GPIO_ACTIVE_LOW>; | |
| 166 | 166 | |
| 167 | 167 | hci-muxed; |
| 168 | 168 | flow-control; |
| @@ -0,0 +1,40 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/net/pse-pd/podl-pse-regulator.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Regulator based Power Sourcing Equipment | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Oleksij Rempel <o.rempel@pengutronix.de> | |
| 11 | + | |
| 12 | +description: Regulator based PoDL PSE controller. The device must be referenced | |
| 13 | + by the PHY node to control power injection to the Ethernet cable. | |
| 14 | + | |
| 15 | +allOf: | |
| 16 | + - $ref: "pse-controller.yaml#" | |
| 17 | + | |
| 18 | +properties: | |
| 19 | + compatible: | |
| 20 | + const: podl-pse-regulator | |
| 21 | + | |
| 22 | + '#pse-cells': | |
| 23 | + const: 0 | |
| 24 | + | |
| 25 | + pse-supply: | |
| 26 | + description: Power supply for the PSE controller | |
| 27 | + | |
| 28 | +additionalProperties: false | |
| 29 | + | |
| 30 | +required: | |
| 31 | + - compatible | |
| 32 | + - pse-supply | |
| 33 | + | |
| 34 | +examples: | |
| 35 | + - | | |
| 36 | + ethernet-pse { | |
| 37 | + compatible = "podl-pse-regulator"; | |
| 38 | + pse-supply = <®_t1l1>; | |
| 39 | + #pse-cells = <0>; | |
| 40 | + }; | |
| @@ -0,0 +1,33 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/net/pse-pd/pse-controller.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Power Sourcing Equipment (PSE). | |
| 8 | + | |
| 9 | +description: Binding for the Power Sourcing Equipment (PSE) as defined in the | |
| 10 | + IEEE 802.3 specification. It is designed for hardware which is delivering | |
| 11 | + power over twisted pair/ethernet cable. The ethernet-pse nodes should be | |
| 12 | + used to describe PSE controller and referenced by the ethernet-phy node. | |
| 13 | + | |
| 14 | +maintainers: | |
| 15 | + - Oleksij Rempel <o.rempel@pengutronix.de> | |
| 16 | + | |
| 17 | +properties: | |
| 18 | + $nodename: | |
| 19 | + pattern: "^ethernet-pse(@.*)?$" | |
| 20 | + | |
| 21 | + "#pse-cells": | |
| 22 | + description: | |
| 23 | + Used to uniquely identify a PSE instance within an IC. Will be | |
| 24 | + 0 on PSE nodes with only a single output and at least 1 on nodes | |
| 25 | + controlling several outputs. | |
| 26 | + enum: [0, 1] | |
| 27 | + | |
| 28 | +required: | |
| 29 | + - "#pse-cells" | |
| 30 | + | |
| 31 | +additionalProperties: true | |
| 32 | + | |
| 33 | +... | |
| @@ -14,6 +14,9 @@ when it is embedded in source files. · 13 unmodified lines | ||
| 14 | 14 | reasons. The kernel source contains tens of thousands of kernel-doc |
| 15 | 15 | comments. Please stick to the style described here. |
| 16 | 16 | |
| 17 | +.. note:: kernel-doc does not cover Rust code: please see | |
| 18 | + Documentation/rust/general-information.rst instead. | |
| 19 | + | |
| 17 | 20 | The kernel-doc structure is extracted from the comments, and proper |
| 18 | 21 | `Sphinx C Domain`_ function and type descriptions with anchors are |
| 19 | 22 | generated from them. The descriptions are filtered for special kernel-doc |
| @@ -48,10 +48,6 @@ or ``virtualenv``, depending on how your distribution packaged Python 3. · 47 unmodified lines | ||
| 48 | 48 | on the Sphinx version, it should be installed separately, |
| 49 | 49 | with ``pip install sphinx_rtd_theme``. |
| 50 | 50 | |
| 51 | − #) Some ReST pages contain math expressions. Due to the way Sphinx works, | |
| 52 | − those expressions are written using LaTeX notation. It needs texlive | |
| 53 | − installed with amsfonts and amsmath in order to evaluate them. | |
| 54 | − | |
| 55 | 51 | In summary, if you want to install Sphinx version 2.4.4, you should do:: |
| 56 | 52 | |
| 57 | 53 | $ virtualenv sphinx_2.4.4 |
| @@ -86,6 +82,27 @@ Depending on the distribution, you may also need to install a series of · 28 unmodified lines | ||
| 86 | 82 | ``texlive`` packages that provide the minimal set of functionalities |
| 87 | 83 | required for ``XeLaTeX`` to work. |
| 88 | 84 | |
| 85 | +Math Expressions in HTML | |
| 86 | +------------------------ | |
| 87 | + | |
| 88 | +Some ReST pages contain math expressions. Due to the way Sphinx works, | |
| 89 | +those expressions are written using LaTeX notation. | |
| 90 | +There are two options for Sphinx to render math expressions in html output. | |
| 91 | +One is an extension called `imgmath`_ which converts math expressions into | |
| 92 | +images and embeds them in html pages. | |
| 93 | +The other is an extension called `mathjax`_ which delegates math rendering | |
| 94 | +to JavaScript capable web browsers. | |
| 95 | +The former was the only option for pre-6.1 kernel documentation and it | |
| 96 | +requires quite a few texlive packages including amsfonts and amsmath among | |
| 97 | +others. | |
| 98 | + | |
| 99 | +Since kernel release 6.1, html pages with math expressions can be built | |
| 100 | +without installing any texlive packages. See `Choice of Math Renderer`_ for | |
| 101 | +further info. | |
| 102 | + | |
| 103 | +.. _imgmath: https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.imgmath | |
| 104 | +.. _mathjax: https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.mathjax | |
| 105 | + | |
| 89 | 106 | .. _sphinx-pre-install: |
| 90 | 107 | |
| 91 | 108 | Checking for Sphinx dependencies |
| @@ -164,6 +181,38 @@ To remove the generated documentation, run ``make cleandocs``. · 72 unmodified lines | ||
| 164 | 181 | as well would improve the quality of images embedded in PDF |
| 165 | 182 | documents, especially for kernel releases 5.18 and later. |
| 166 | 183 | |
| 184 | +Choice of Math Renderer | |
| 185 | +----------------------- | |
| 186 | + | |
| 187 | +Since kernel release 6.1, mathjax works as a fallback math renderer for | |
| 188 | +html output.\ [#sph1_8]_ | |
| 189 | + | |
| 190 | +Math renderer is chosen depending on available commands as shown below: | |
| 191 | + | |
| 192 | +.. table:: Math Renderer Choices for HTML | |
| 193 | + | |
| 194 | + ============= ================= ============ | |
| 195 | + Math renderer Required commands Image format | |
| 196 | + ============= ================= ============ | |
| 197 | + imgmath latex, dvipng PNG (raster) | |
| 198 | + mathjax | |
| 199 | + ============= ================= ============ | |
| 200 | + | |
| 201 | +The choice can be overridden by setting an environment variable | |
| 202 | +``SPHINX_IMGMATH`` as shown below: | |
| 203 | + | |
| 204 | +.. table:: Effect of Setting ``SPHINX_IMGMATH`` | |
| 205 | + | |
| 206 | + ====================== ======== | |
| 207 | + Setting Renderer | |
| 208 | + ====================== ======== | |
| 209 | + ``SPHINX_IMGMATH=yes`` imgmath | |
| 210 | + ``SPHINX_IMGMATH=no`` mathjax | |
| 211 | + ====================== ======== | |
| 212 | + | |
| 213 | +.. [#sph1_8] Fallback of math renderer requires Sphinx >=1.8. | |
| 214 | + | |
| 215 | + | |
| 167 | 216 | Writing Documentation |
| 168 | 217 | ===================== |
| 169 | 218 | |
| @@ -301,6 +301,7 @@ IO region · 300 unmodified lines | ||
| 301 | 301 | devm_release_region() |
| 302 | 302 | devm_release_resource() |
| 303 | 303 | devm_request_mem_region() |
| 304 | + devm_request_free_mem_region() | |
| 304 | 305 | devm_request_region() |
| 305 | 306 | devm_request_resource() |
| 306 | 307 | |
| @@ -334,7 +335,7 @@ IRQ · 27 unmodified lines | ||
| 334 | 335 | devm_irq_alloc_descs_from() |
| 335 | 336 | devm_irq_alloc_generic_chip() |
| 336 | 337 | devm_irq_setup_generic_chip() |
| 337 | − devm_irq_sim_init() | |
| 338 | + devm_irq_domain_create_sim() | |
| 338 | 339 | |
| 339 | 340 | LED |
| 340 | 341 | devm_led_classdev_register() |
| @@ -392,7 +393,9 @@ PHY · 51 unmodified lines | ||
| 392 | 393 | PINCTRL |
| 393 | 394 | devm_pinctrl_get() |
| 394 | 395 | devm_pinctrl_put() |
| 396 | + devm_pinctrl_get_select() | |
| 395 | 397 | devm_pinctrl_register() |
| 398 | + devm_pinctrl_register_and_init() | |
| 396 | 399 | devm_pinctrl_unregister() |
| 397 | 400 | |
| 398 | 401 | POWER |
| @@ -427,6 +430,8 @@ SLAVE DMA ENGINE · 28 unmodified lines | ||
| 427 | 430 | devm_acpi_dma_controller_register() |
| 428 | 431 | |
| 429 | 432 | SPI |
| 433 | + devm_spi_alloc_master() | |
| 434 | + devm_spi_alloc_slave() | |
| 430 | 435 | devm_spi_register_master() |
| 431 | 436 | |
| 432 | 437 | WATCHDOG |
| @@ -100,7 +100,7 @@ I believe platform_data is available for this, but if rather not, moving · 99 unmodified lines | ||
| 100 | 100 | the isa_driver pointer to the private struct isa_dev is ofcourse fine as |
| 101 | 101 | well. |
| 102 | 102 | |
| 103 | −Then, if the the driver did not provide a .match, it matches. If it did, | |
| 103 | +Then, if the driver did not provide a .match, it matches. If it did, | |
| 104 | 104 | the driver match() method is called to determine a match. |
| 105 | 105 | |
| 106 | 106 | If it did **not** match, dev->platform_data is reset to indicate this to |
| @@ -86,17 +86,24 @@ Module Options · 85 unmodified lines | ||
| 86 | 86 | Special configuration for udlfb is usually unnecessary. There are a few |
| 87 | 87 | options, however. |
| 88 | 88 | |
| 89 | −From the command line, pass options to modprobe | |
| 90 | −modprobe udlfb fb_defio=0 console=1 shadow=1 | |
| 89 | +From the command line, pass options to modprobe:: | |
| 91 | 90 | |
| 92 | −Or modify options on the fly at /sys/module/udlfb/parameters directory via | |
| 93 | −sudo nano fb_defio | |
| 94 | −change the parameter in place, and save the file. | |
| 91 | + modprobe udlfb fb_defio=0 console=1 shadow=1 | |
| 95 | 92 | |
| 96 | −Unplug/replug USB device to apply with new settings | |
| 93 | +Or change options on the fly by editing | |
| 94 | +/sys/module/udlfb/parameters/PARAMETER_NAME :: | |
| 97 | 95 | |
| 98 | −Or for permanent option, create file like /etc/modprobe.d/udlfb.conf with text | |
| 99 | −options udlfb fb_defio=0 console=1 shadow=1 | |
| 96 | + cd /sys/module/udlfb/parameters | |
| 97 | + ls # to see a list of parameter names | |
| 98 | + sudo nano PARAMETER_NAME | |
| 99 | + # change the parameter in place, and save the file. | |
| 100 | + | |
| 101 | +Unplug/replug USB device to apply with new settings. | |
| 102 | + | |
| 103 | +Or to apply options permanently, create a modprobe configuration file | |
| 104 | +like /etc/modprobe.d/udlfb.conf with text:: | |
| 105 | + | |
| 106 | + options udlfb fb_defio=0 console=1 shadow=1 | |
| 100 | 107 | |
| 101 | 108 | Accepted boolean options: |
| 102 | 109 | |
| @@ -122,7 +122,7 @@ volumes, calling:: · 121 unmodified lines | ||
| 122 | 122 | to tell fscache that a volume has been withdrawn. This waits for all |
| 123 | 123 | outstanding accesses on the volume to complete before returning. |
| 124 | 124 | |
| 125 | −When the the cache is completely withdrawn, fscache should be notified by | |
| 125 | +When the cache is completely withdrawn, fscache should be notified by | |
| 126 | 126 | calling:: |
| 127 | 127 | |
| 128 | 128 | void fscache_relinquish_cache(struct fscache_cache *cache); |
| @@ -456,15 +456,15 @@ The ext4 superblock is laid out as follows in · 455 unmodified lines | ||
| 456 | 456 | * - 0x277 |
| 457 | 457 | - __u8 |
| 458 | 458 | - s_lastcheck_hi |
| 459 | − - Upper 8 bits of the s_lastcheck_hi field. | |
| 459 | + - Upper 8 bits of the s_lastcheck field. | |
| 460 | 460 | * - 0x278 |
| 461 | 461 | - __u8 |
| 462 | 462 | - s_first_error_time_hi |
| 463 | − - Upper 8 bits of the s_first_error_time_hi field. | |
| 463 | + - Upper 8 bits of the s_first_error_time field. | |
| 464 | 464 | * - 0x279 |
| 465 | 465 | - __u8 |
| 466 | 466 | - s_last_error_time_hi |
| 467 | − - Upper 8 bits of the s_last_error_time_hi field. | |
| 467 | + - Upper 8 bits of the s_last_error_time field. | |
| 468 | 468 | * - 0x27A |
| 469 | 469 | - __u8 |
| 470 | 470 | - s_pad[2] |
| @@ -286,9 +286,8 @@ compress_algorithm=%s:%d Control compress algorithm and its compress level, now, · 285 unmodified lines | ||
| 286 | 286 | algorithm level range |
| 287 | 287 | lz4 3 - 16 |
| 288 | 288 | zstd 1 - 22 |
| 289 | −compress_log_size=%u Support configuring compress cluster size, the size will | |
| 290 | − be 4KB * (1 << %u), 16KB is minimum size, also it's | |
| 291 | − default size. | |
| 289 | +compress_log_size=%u Support configuring compress cluster size. The size will | |
| 290 | + be 4KB * (1 << %u). The default and minimum sizes are 16KB. | |
| 292 | 291 | compress_extension=%s Support adding specified extension, so that f2fs can enable |
| 293 | 292 | compression on those corresponding files, e.g. if all files |
| 294 | 293 | with '.ext' has high compression rate, we can set the '.ext' |
| @@ -661,7 +661,7 @@ idmappings:: · 660 unmodified lines | ||
| 661 | 661 | mount idmapping: u0:k10000:r10000 |
| 662 | 662 | |
| 663 | 663 | Assume a file owned by ``u1000`` is read from disk. The filesystem maps this id |
| 664 | −to ``k21000`` according to it's idmapping. This is what is stored in the | |
| 664 | +to ``k21000`` according to its idmapping. This is what is stored in the | |
| 665 | 665 | inode's ``i_uid`` and ``i_gid`` fields. |
| 666 | 666 | |
| 667 | 667 | When the caller queries the ownership of this file via ``stat()`` the kernel |
| @@ -176,7 +176,7 @@ Then userspace. · 175 unmodified lines | ||
| 176 | 176 | The requirement for a static, fixed preallocated system area comes from how |
| 177 | 177 | qnx6fs deals with writes. |
| 178 | 178 | |
| 179 | −Each superblock got it's own half of the system area. So superblock #1 | |
| 179 | +Each superblock got its own half of the system area. So superblock #1 | |
| 180 | 180 | always uses blocks from the lower half while superblock #2 just writes to |
| 181 | 181 | blocks represented by the upper half bitmap system area bits. |
| 182 | 182 | |
| @@ -227,7 +227,7 @@ Files · 226 unmodified lines | ||
| 227 | 227 | from the data buffer, updating the value of the specified signal |
| 228 | 228 | notification register. The signal notification register will |
| 229 | 229 | either be replaced with the input data or will be updated to the |
| 230 | − bitwise OR or the old value and the input data, depending on the | |
| 230 | + bitwise OR of the old value and the input data, depending on the | |
| 231 | 231 | contents of the signal1_type, or signal2_type respectively, |
| 232 | 232 | file. |
| 233 | 233 | |
| @@ -100,7 +100,7 @@ transactions together:: · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | ntp = xfs_trans_dup(tp); |
| 102 | 102 | xfs_trans_commit(tp); |
| 103 | − xfs_log_reserve(ntp); | |
| 103 | + xfs_trans_reserve(ntp); | |
| 104 | 104 | |
| 105 | 105 | This results in a series of "rolling transactions" where the inode is locked |
| 106 | 106 | across the entire chain of transactions. Hence while this series of rolling |
| @@ -191,7 +191,7 @@ transaction rolling mechanism to re-reserve space on every transaction roll. We · 84 unmodified lines | ||
| 191 | 191 | know from the implementation of the permanent transactions how many transaction |
| 192 | 192 | rolls are likely for the common modifications that need to be made. |
| 193 | 193 | |
| 194 | −For example, and inode allocation is typically two transactions - one to | |
| 194 | +For example, an inode allocation is typically two transactions - one to | |
| 195 | 195 | physically allocate a free inode chunk on disk, and another to allocate an inode |
| 196 | 196 | from an inode chunk that has free inodes in it. Hence for an inode allocation |
| 197 | 197 | transaction, we might set the reservation log count to a value of 2 to indicate |
| @@ -200,7 +200,7 @@ chain. Each time a permanent transaction rolls, it consumes an entire unit · 2 unmodified lines | ||
| 200 | 200 | reservation. |
| 201 | 201 | |
| 202 | 202 | Hence when the permanent transaction is first allocated, the log space |
| 203 | −reservation is increases from a single unit reservation to multiple unit | |
| 203 | +reservation is increased from a single unit reservation to multiple unit | |
| 204 | 204 | reservations. That multiple is defined by the reservation log count, and this |
| 205 | 205 | means we can roll the transaction multiple times before we have to re-reserve |
| 206 | 206 | log space when we roll the transaction. This ensures that the common |
| @@ -259,7 +259,7 @@ the next transaction in the sequeunce, but we have none remaining. We cannot · 52 unmodified lines | ||
| 259 | 259 | sleep during the transaction commit process waiting for new log space to become |
| 260 | 260 | available, as we may end up on the end of the FIFO queue and the items we have |
| 261 | 261 | locked while we sleep could end up pinning the tail of the log before there is |
| 262 | −enough free space in the log to fulfil all of the pending reservations and | |
| 262 | +enough free space in the log to fulfill all of the pending reservations and | |
| 263 | 263 | then wake up transaction commit in progress. |
| 264 | 264 | |
| 265 | 265 | To take a new reservation without sleeping requires us to be able to take a |
| @@ -551,14 +551,14 @@ Essentially, this shows that an item that is in the AIL can still be modified · 285 unmodified lines | ||
| 551 | 551 | and relogged, so any tracking must be separate to the AIL infrastructure. As |
| 552 | 552 | such, we cannot reuse the AIL list pointers for tracking committed items, nor |
| 553 | 553 | can we store state in any field that is protected by the AIL lock. Hence the |
| 554 | −committed item tracking needs it's own locks, lists and state fields in the log | |
| 554 | +committed item tracking needs its own locks, lists and state fields in the log | |
| 555 | 555 | item. |
| 556 | 556 | |
| 557 | 557 | Similar to the AIL, tracking of committed items is done through a new list |
| 558 | 558 | called the Committed Item List (CIL). The list tracks log items that have been |
| 559 | 559 | committed and have formatted memory buffers attached to them. It tracks objects |
| 560 | 560 | in transaction commit order, so when an object is relogged it is removed from |
| 561 | −it's place in the list and re-inserted at the tail. This is entirely arbitrary | |
| 561 | +its place in the list and re-inserted at the tail. This is entirely arbitrary | |
| 562 | 562 | and done to make it easy for debugging - the last items in the list are the |
| 563 | 563 | ones that are most recently modified. Ordering of the CIL is not necessary for |
| 564 | 564 | transactional integrity (as discussed in the next section) so the ordering is |
| @@ -615,7 +615,7 @@ those changes into the current checkpoint context. We then initialise a new · 50 unmodified lines | ||
| 615 | 615 | context and attach that to the CIL for aggregation of new transactions. |
| 616 | 616 | |
| 617 | 617 | This allows us to unlock the CIL immediately after transfer of all the |
| 618 | −committed items and effectively allow new transactions to be issued while we | |
| 618 | +committed items and effectively allows new transactions to be issued while we | |
| 619 | 619 | are formatting the checkpoint into the log. It also allows concurrent |
| 620 | 620 | checkpoints to be written into the log buffers in the case of log force heavy |
| 621 | 621 | workloads, just like the existing transaction commit code does. This, however, |
| @@ -884,9 +884,9 @@ pin the object the first time it is inserted into the CIL - if it is already in · 262 unmodified lines | ||
| 884 | 884 | the CIL during a transaction commit, then we do not pin it again. Because there |
| 885 | 885 | can be multiple outstanding checkpoint contexts, we can still see elevated pin |
| 886 | 886 | counts, but as each checkpoint completes the pin count will retain the correct |
| 887 | −value according to it's context. | |
| 887 | +value according to its context. | |
| 888 | 888 | |
| 889 | −Just to make matters more slightly more complex, this checkpoint level context | |
| 889 | +Just to make matters slightly more complex, this checkpoint level context | |
| 890 | 890 | for the pin count means that the pinning of an item must take place under the |
| 891 | 891 | CIL commit/flush lock. If we pin the object outside this lock, we cannot |
| 892 | 892 | guarantee which context the pin count is associated with. This is because of |
| @@ -21,7 +21,7 @@ possible we decided to do following: · 20 unmodified lines | ||
| 21 | 21 | - Devices behind real busses where there is a connector resource |
| 22 | 22 | are represented as struct spi_device or struct i2c_device. Note |
| 23 | 23 | that standard UARTs are not busses so there is no struct uart_device, |
| 24 | − although some of them may be represented by sturct serdev_device. | |
| 24 | + although some of them may be represented by struct serdev_device. | |
| 25 | 25 | |
| 26 | 26 | As both ACPI and Device Tree represent a tree of devices (and their |
| 27 | 27 | resources) this implementation follows the Device Tree way as much as |
| @@ -205,7 +205,7 @@ Here is what the ACPI namespace for a SPI slave might look like:: · 177 unmodified lines | ||
| 205 | 205 | } |
| 206 | 206 | ... |
| 207 | 207 | |
| 208 | −The SPI device drivers only need to add ACPI IDs in a similar way than with | |
| 208 | +The SPI device drivers only need to add ACPI IDs in a similar way to | |
| 209 | 209 | the platform device drivers. Below is an example where we add ACPI support |
| 210 | 210 | to at25 SPI eeprom driver (this is meant for the above ACPI snippet):: |
| 211 | 211 | |
| @@ -362,7 +362,7 @@ These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" · 150 unmodified lines | ||
| 362 | 362 | specifies the path to the controller. In order to use these GPIOs in Linux |
| 363 | 363 | we need to translate them to the corresponding Linux GPIO descriptors. |
| 364 | 364 | |
| 365 | −There is a standard GPIO API for that and is documented in | |
| 365 | +There is a standard GPIO API for that and it is documented in | |
| 366 | 366 | Documentation/admin-guide/gpio/. |
| 367 | 367 | |
| 368 | 368 | In the above example we can get the corresponding two GPIO descriptors with |
| @@ -538,8 +538,8 @@ information. · 169 unmodified lines | ||
| 538 | 538 | PCI hierarchy representation |
| 539 | 539 | ============================ |
| 540 | 540 | |
| 541 | −Sometimes could be useful to enumerate a PCI device, knowing its position on the | |
| 542 | −PCI bus. | |
| 541 | +Sometimes it could be useful to enumerate a PCI device, knowing its position on | |
| 542 | +the PCI bus. | |
| 543 | 543 | |
| 544 | 544 | For example, some systems use PCI devices soldered directly on the mother board, |
| 545 | 545 | in a fixed position (ethernet, Wi-Fi, serial ports, etc.). In this conditions it |
| @@ -550,7 +550,7 @@ To identify a PCI device, a complete hierarchical description is required, from · 4 unmodified lines | ||
| 550 | 550 | the chipset root port to the final device, through all the intermediate |
| 551 | 551 | bridges/switches of the board. |
| 552 | 552 | |
| 553 | −For example, let us assume to have a system with a PCIe serial port, an | |
| 553 | +For example, let's assume we have a system with a PCIe serial port, an | |
| 554 | 554 | Exar XR17V3521, soldered on the main board. This UART chip also includes |
| 555 | 555 | 16 GPIOs and we want to add the property ``gpio-line-names`` [1] to these pins. |
| 556 | 556 | In this case, the ``lspci`` output for this component is:: |
| @@ -593,8 +593,8 @@ of the chipset bridge (also called "root port") with address:: · 36 unmodified lines | ||
| 593 | 593 | |
| 594 | 594 | Bus: 0 - Device: 14 - Function: 1 |
| 595 | 595 | |
| 596 | −To find this information is necessary disassemble the BIOS ACPI tables, in | |
| 597 | −particular the DSDT (see also [2]):: | |
| 596 | +To find this information, it is necessary to disassemble the BIOS ACPI tables, | |
| 597 | +in particular the DSDT (see also [2]):: | |
| 598 | 598 | |
| 599 | 599 | mkdir ~/tables/ |
| 600 | 600 | cd ~/tables/ |
| @@ -41,26 +41,23 @@ But it is likely that they will all eventually be added. · 40 unmodified lines | ||
| 41 | 41 | What should an OEM do if they want to support Linux and Windows |
| 42 | 42 | using the same BIOS image? Often they need to do something different |
| 43 | 43 | for Linux to deal with how Linux is different from Windows. |
| 44 | −Here the BIOS should ask exactly what it wants to know: | |
| 45 | 44 | |
| 45 | +In this case, the OEM should create custom ASL to be executed by the | |
| 46 | +Linux kernel and changes to Linux kernel drivers to execute this custom | |
| 47 | +ASL. The easiest way to accomplish this is to introduce a device specific | |
| 48 | +method (_DSM) that is called from the Linux kernel. | |
| 49 | + | |
| 50 | +In the past the kernel used to support something like: | |
| 46 | 51 | _OSI("Linux-OEM-my_interface_name") |
| 47 | 52 | where 'OEM' is needed if this is an OEM-specific hook, |
| 48 | 53 | and 'my_interface_name' describes the hook, which could be a |
| 49 | 54 | quirk, a bug, or a bug-fix. |
| 50 | 55 | |
| 51 | −In addition, the OEM should send a patch to upstream Linux | |
| 52 | −via the linux-acpi@vger.kernel.org mailing list. When that patch | |
| 53 | −is checked into Linux, the OS will answer "YES" when the BIOS | |
| 54 | −on the OEM's system uses _OSI to ask if the interface is supported | |
| 55 | −by the OS. Linux distributors can back-port that patch for Linux | |
| 56 | −pre-installs, and it will be included by all distributions that | |
| 57 | −re-base to upstream. If the distribution can not update the kernel binary, | |
| 58 | −they can also add an acpi_osi=Linux-OEM-my_interface_name | |
| 59 | −cmdline parameter to the boot loader, as needed. | |
| 60 | − | |
| 61 | −If the string refers to a feature where the upstream kernel | |
| 62 | −eventually grows support, a patch should be sent to remove | |
| 63 | −the string when that support is added to the kernel. | |
| 56 | +However this was discovered to be abused by other BIOS vendors to change | |
| 57 | +completely unrelated code on completely unrelated systems. This prompted | |
| 58 | +an evaluation of all of it's uses. This uncovered that they aren't needed | |
| 59 | +for any of the original reasons. As such, the kernel will not respond to | |
| 60 | +any custom Linux-* strings by default. | |
| 64 | 61 | |
| 65 | 62 | That was easy. Read on, to find out how to do it wrong. |
| 66 | 63 | |
| @@ -1,11 +1,5 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | − | |
| 4 | −.. The Linux Kernel documentation master file, created by | |
| 5 | − sphinx-quickstart on Fri Feb 12 13:51:46 2016. | |
| 6 | − You can adapt this file completely to your liking, but it should at least | |
| 7 | − contain the root `toctree` directive. | |
| 8 | − | |
| 9 | 3 | .. _linux_doc: |
| 10 | 4 | |
| 11 | 5 | The Linux Kernel documentation |
| @@ -18,133 +12,85 @@ documents into a coherent whole. Please note that improvements to the · 6 unmodified lines | ||
| 18 | 12 | documentation are welcome; join the linux-doc list at vger.kernel.org if |
| 19 | 13 | you want to help out. |
| 20 | 14 | |
| 21 | −Licensing documentation | |
| 22 | −----------------------- | |
| 15 | +Working with the development community | |
| 16 | +-------------------------------------- | |
| 23 | 17 | |
| 24 | −The following describes the license of the Linux kernel source code | |
| 25 | −(GPLv2), how to properly mark the license of individual files in the source | |
| 26 | −tree, as well as links to the full license text. | |
| 27 | − | |
| 28 | −* :ref:`kernel_licensing` | |
| 29 | − | |
| 30 | −User-oriented documentation | |
| 31 | −--------------------------- | |
| 32 | − | |
| 33 | −The following manuals are written for *users* of the kernel — those who are | |
| 34 | −trying to get it to work optimally on a given system. | |
| 18 | +The essential guides for interacting with the kernel's development | |
| 19 | +community and getting your work upstream. | |
| 35 | 20 | |
| 36 | 21 | .. toctree:: |
| 37 | − :maxdepth: 2 | |
| 38 | − | |
| 39 | − admin-guide/index | |
| 40 | − kbuild/index | |
| 41 | − | |
| 42 | −Firmware-related documentation | |
| 43 | −------------------------------ | |
| 44 | −The following holds information on the kernel's expectations regarding the | |
| 45 | −platform firmwares. | |
| 22 | + :maxdepth: 1 | |
| 46 | 23 | |
| 47 | −.. toctree:: | |
| 48 | − :maxdepth: 2 | |
| 24 | + process/development-process | |
| 25 | + process/submitting-patches | |
| 26 | + Code of conduct <process/code-of-conduct> | |
| 27 | + maintainer/index | |
| 28 | + All development-process docs <process/index> | |
| 49 | 29 | |
| 50 | − firmware-guide/index | |
| 51 | − devicetree/index | |
| 52 | 30 | |
| 53 | −Application-developer documentation | |
| 54 | −----------------------------------- | |
| 31 | +Internal API manuals | |
| 32 | +-------------------- | |
| 55 | 33 | |
| 56 | −The user-space API manual gathers together documents describing aspects of | |
| 57 | −the kernel interface as seen by application developers. | |
| 34 | +Manuals for use by developers working to interface with the rest of the | |
| 35 | +kernel. | |
| 58 | 36 | |
| 59 | 37 | .. toctree:: |
| 60 | − :maxdepth: 2 | |
| 61 | − | |
| 62 | − userspace-api/index | |
| 38 | + :maxdepth: 1 | |
| 63 | 39 | |
| 40 | + core-api/index | |
| 41 | + driver-api/index | |
| 42 | + subsystem-apis | |
| 43 | + Locking in the kernel <locking/index> | |
| 64 | 44 | |
| 65 | −Introduction to kernel development | |
| 66 | −---------------------------------- | |
| 45 | +Development tools and processes | |
| 46 | +------------------------------- | |
| 67 | 47 | |
| 68 | −These manuals contain overall information about how to develop the kernel. | |
| 69 | −The kernel community is quite large, with thousands of developers | |
| 70 | −contributing over the course of a year. As with any large community, | |
| 71 | −knowing how things are done will make the process of getting your changes | |
| 72 | −merged much easier. | |
| 48 | +Various other manuals with useful information for all kernel developers. | |
| 73 | 49 | |
| 74 | 50 | .. toctree:: |
| 75 | − :maxdepth: 2 | |
| 51 | + :maxdepth: 1 | |
| 76 | 52 | |
| 77 | − process/index | |
| 78 | − dev-tools/index | |
| 53 | + process/license-rules | |
| 79 | 54 | doc-guide/index |
| 55 | + dev-tools/index | |
| 56 | + dev-tools/testing-overview | |
| 80 | 57 | kernel-hacking/index |
| 81 | 58 | trace/index |
| 82 | − maintainer/index | |
| 83 | 59 | fault-injection/index |
| 84 | 60 | livepatch/index |
| 61 | + rust/index | |
| 85 | 62 | |
| 86 | 63 | |
| 87 | −Kernel API documentation | |
| 88 | −------------------------ | |
| 64 | +User-oriented documentation | |
| 65 | +--------------------------- | |
| 89 | 66 | |
| 90 | −These books get into the details of how specific kernel subsystems work | |
| 91 | −from the point of view of a kernel developer. Much of the information here | |
| 92 | −is taken directly from the kernel source, with supplemental material added | |
| 93 | −as needed (or at least as we managed to add it — probably *not* all that is | |
| 94 | −needed). | |
| 67 | +The following manuals are written for *users* of the kernel — those who are | |
| 68 | +trying to get it to work optimally on a given system and application | |
| 69 | +developers seeking information on the kernel's user-space APIs. | |
| 95 | 70 | |
| 96 | 71 | .. toctree:: |
| 97 | − :maxdepth: 2 | |
| 72 | + :maxdepth: 1 | |
| 98 | 73 | |
| 99 | − driver-api/index | |
| 100 | − core-api/index | |
| 101 | − locking/index | |
| 102 | − accounting/index | |
| 103 | − block/index | |
| 104 | − cdrom/index | |
| 105 | − cpu-freq/index | |
| 106 | − fb/index | |
| 107 | − fpga/index | |
| 108 | − hid/index | |
| 109 | − i2c/index | |
| 110 | − iio/index | |
| 111 | − isdn/index | |
| 112 | − infiniband/index | |
| 113 | − leds/index | |
| 114 | − netlabel/index | |
| 115 | − networking/index | |
| 116 | − pcmcia/index | |
| 117 | − power/index | |
| 118 | − target/index | |
| 119 | − timers/index | |
| 120 | − spi/index | |
| 121 | − w1/index | |
| 122 | − watchdog/index | |
| 123 | − virt/index | |
| 124 | − input/index | |
| 125 | − hwmon/index | |
| 126 | − gpu/index | |
| 127 | − security/index | |
| 128 | − sound/index | |
| 129 | − crypto/index | |
| 130 | − filesystems/index | |
| 131 | − mm/index | |
| 132 | − bpf/index | |
| 133 | − usb/index | |
| 134 | − PCI/index | |
| 135 | − scsi/index | |
| 136 | − misc-devices/index | |
| 137 | − scheduler/index | |
| 138 | − mhi/index | |
| 139 | − peci/index | |
| 140 | − | |
| 141 | −Architecture-agnostic documentation | |
| 142 | −----------------------------------- | |
| 74 | + admin-guide/index | |
| 75 | + The kernel build system <kbuild/index> | |
| 76 | + admin-guide/reporting-issues.rst | |
| 77 | + User-space tools <tools/index> | |
| 78 | + userspace-api/index | |
| 79 | + | |
| 80 | +See also: the `Linux man pages <https://www.kernel.org/doc/man-pages/>`_, | |
| 81 | +which are kept separately from the kernel's own documentation. | |
| 82 | + | |
| 83 | +Firmware-related documentation | |
| 84 | +------------------------------ | |
| 85 | +The following holds information on the kernel's expectations regarding the | |
| 86 | +platform firmwares. | |
| 143 | 87 | |
| 144 | 88 | .. toctree:: |
| 145 | − :maxdepth: 2 | |
| 89 | + :maxdepth: 1 | |
| 90 | + | |
| 91 | + firmware-guide/index | |
| 92 | + devicetree/index | |
| 146 | 93 | |
| 147 | − asm-annotations | |
| 148 | 94 | |
| 149 | 95 | Architecture-specific documentation |
| 150 | 96 | ----------------------------------- |
| @@ -163,9 +109,8 @@ of the documentation body, or may require some adjustments and/or conversion · 12 unmodified lines | ||
| 163 | 109 | to ReStructured Text format, or are simply too old. |
| 164 | 110 | |
| 165 | 111 | .. toctree:: |
| 166 | − :maxdepth: 2 | |
| 112 | + :maxdepth: 1 | |
| 167 | 113 | |
| 168 | − tools/index | |
| 169 | 114 | staging/index |
| 170 | 115 | |
| 171 | 116 | |
| @@ -90,7 +90,11 @@ e.g., on Ubuntu for gcc-10:: · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | Or on Fedora:: |
| 92 | 92 | |
| 93 | − dnf install gcc-plugin-devel | |
| 93 | + dnf install gcc-plugin-devel libmpc-devel | |
| 94 | + | |
| 95 | +Or on Fedora when using cross-compilers that include plugins:: | |
| 96 | + | |
| 97 | + dnf install libmpc-devel | |
| 94 | 98 | |
| 95 | 99 | Enable the GCC plugin infrastructure and some plugin(s) you want to use |
| 96 | 100 | in the kernel config:: |
| @@ -99,6 +103,19 @@ in the kernel config:: · 2 unmodified lines | ||
| 99 | 103 | CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y |
| 100 | 104 | ... |
| 101 | 105 | |
| 106 | +Run gcc (native or cross-compiler) to ensure plugin headers are detected:: | |
| 107 | + | |
| 108 | + gcc -print-file-name=plugin | |
| 109 | + CROSS_COMPILE=arm-linux-gnu- ${CROSS_COMPILE}gcc -print-file-name=plugin | |
| 110 | + | |
| 111 | +The word "plugin" means they are not detected:: | |
| 112 | + | |
| 113 | + plugin | |
| 114 | + | |
| 115 | +A full path means they are detected:: | |
| 116 | + | |
| 117 | + /usr/lib/gcc/x86_64-redhat-linux/12/plugin | |
| 118 | + | |
| 102 | 119 | To compile the minimum tool set including the plugin(s):: |
| 103 | 120 | |
| 104 | 121 | make scripts |
| @@ -48,6 +48,10 @@ KCFLAGS · 47 unmodified lines | ||
| 48 | 48 | ------- |
| 49 | 49 | Additional options to the C compiler (for built-in and modules). |
| 50 | 50 | |
| 51 | +KRUSTFLAGS | |
| 52 | +---------- | |
| 53 | +Additional options to the Rust compiler (for built-in and modules). | |
| 54 | + | |
| 51 | 55 | CFLAGS_KERNEL |
| 52 | 56 | ------------- |
| 53 | 57 | Additional options for $(CC) when used to compile |
| @@ -57,6 +61,15 @@ CFLAGS_MODULE · 3 unmodified lines | ||
| 57 | 61 | ------------- |
| 58 | 62 | Additional module specific options to use for $(CC). |
| 59 | 63 | |
| 64 | +RUSTFLAGS_KERNEL | |
| 65 | +---------------- | |
| 66 | +Additional options for $(RUSTC) when used to compile | |
| 67 | +code that is compiled as built-in. | |
| 68 | + | |
| 69 | +RUSTFLAGS_MODULE | |
| 70 | +---------------- | |
| 71 | +Additional module specific options to use for $(RUSTC). | |
| 72 | + | |
| 60 | 73 | LDFLAGS_MODULE |
| 61 | 74 | -------------- |
| 62 | 75 | Additional options used for $(LD) when linking modules. |
| @@ -69,6 +82,10 @@ HOSTCXXFLAGS · 6 unmodified lines | ||
| 69 | 82 | ------------ |
| 70 | 83 | Additional flags to be passed to $(HOSTCXX) when building host programs. |
| 71 | 84 | |
| 85 | +HOSTRUSTFLAGS | |
| 86 | +------------- | |
| 87 | +Additional flags to be passed to $(HOSTRUSTC) when building host programs. | |
| 88 | + | |
| 72 | 89 | HOSTLDFLAGS |
| 73 | 90 | ----------- |
| 74 | 91 | Additional flags to be passed when linking host programs. |
| @@ -29,8 +29,9 @@ This document describes the Linux kernel Makefiles. · 28 unmodified lines | ||
| 29 | 29 | --- 4.1 Simple Host Program |
| 30 | 30 | --- 4.2 Composite Host Programs |
| 31 | 31 | --- 4.3 Using C++ for host programs |
| 32 | − --- 4.4 Controlling compiler options for host programs | |
| 33 | − --- 4.5 When host programs are actually built | |
| 32 | + --- 4.4 Using Rust for host programs | |
| 33 | + --- 4.5 Controlling compiler options for host programs | |
| 34 | + --- 4.6 When host programs are actually built | |
| 34 | 35 | |
| 35 | 36 | === 5 Userspace Program support |
| 36 | 37 | --- 5.1 Simple Userspace Program |
| @@ -835,7 +836,24 @@ Both possibilities are described in the following. · 798 unmodified lines | ||
| 835 | 836 | qconf-cxxobjs := qconf.o |
| 836 | 837 | qconf-objs := check.o |
| 837 | 838 | |
| 838 | −4.4 Controlling compiler options for host programs | |
| 839 | +4.4 Using Rust for host programs | |
| 840 | +-------------------------------- | |
| 841 | + | |
| 842 | + Kbuild offers support for host programs written in Rust. However, | |
| 843 | + since a Rust toolchain is not mandatory for kernel compilation, | |
| 844 | + it may only be used in scenarios where Rust is required to be | |
| 845 | + available (e.g. when ``CONFIG_RUST`` is enabled). | |
| 846 | + | |
| 847 | + Example:: | |
| 848 | + | |
| 849 | + hostprogs := target | |
| 850 | + target-rust := y | |
| 851 | + | |
| 852 | + Kbuild will compile ``target`` using ``target.rs`` as the crate root, | |
| 853 | + located in the same directory as the ``Makefile``. The crate may | |
| 854 | + consist of several source files (see ``samples/rust/hostprogs``). | |
| 855 | + | |
| 856 | +4.5 Controlling compiler options for host programs | |
| 839 | 857 | -------------------------------------------------- |
| 840 | 858 | |
| 841 | 859 | When compiling host programs, it is possible to set specific flags. |
| @@ -867,7 +885,7 @@ Both possibilities are described in the following. · 25 unmodified lines | ||
| 867 | 885 | When linking qconf, it will be passed the extra option |
| 868 | 886 | "-L$(QTDIR)/lib". |
| 869 | 887 | |
| 870 | −4.5 When host programs are actually built | |
| 888 | +4.6 When host programs are actually built | |
| 871 | 889 | ----------------------------------------- |
| 872 | 890 | |
| 873 | 891 | Kbuild will only build host-programs when they are referenced |
| @@ -1181,6 +1199,17 @@ When kbuild executes, the following steps are followed (roughly): · 307 unmodified lines | ||
| 1181 | 1199 | The first example utilises the trick that a config option expands |
| 1182 | 1200 | to 'y' when selected. |
| 1183 | 1201 | |
| 1202 | + KBUILD_RUSTFLAGS | |
| 1203 | + $(RUSTC) compiler flags | |
| 1204 | + | |
| 1205 | + Default value - see top level Makefile | |
| 1206 | + Append or modify as required per architecture. | |
| 1207 | + | |
| 1208 | + Often, the KBUILD_RUSTFLAGS variable depends on the configuration. | |
| 1209 | + | |
| 1210 | + Note that target specification file generation (for ``--target``) | |
| 1211 | + is handled in ``scripts/generate_rust_target.rs``. | |
| 1212 | + | |
| 1184 | 1213 | KBUILD_AFLAGS_KERNEL |
| 1185 | 1214 | Assembler options specific for built-in |
| 1186 | 1215 | |
| @@ -1208,6 +1237,19 @@ When kbuild executes, the following steps are followed (roughly): · 21 unmodified lines | ||
| 1208 | 1237 | are used for $(CC). |
| 1209 | 1238 | From commandline CFLAGS_MODULE shall be used (see kbuild.rst). |
| 1210 | 1239 | |
| 1240 | + KBUILD_RUSTFLAGS_KERNEL | |
| 1241 | + $(RUSTC) options specific for built-in | |
| 1242 | + | |
| 1243 | + $(KBUILD_RUSTFLAGS_KERNEL) contains extra Rust compiler flags used to | |
| 1244 | + compile resident kernel code. | |
| 1245 | + | |
| 1246 | + KBUILD_RUSTFLAGS_MODULE | |
| 1247 | + Options for $(RUSTC) when building modules | |
| 1248 | + | |
| 1249 | + $(KBUILD_RUSTFLAGS_MODULE) is used to add arch-specific options that | |
| 1250 | + are used for $(RUSTC). | |
| 1251 | + From commandline RUSTFLAGS_MODULE shall be used (see kbuild.rst). | |
| 1252 | + | |
| 1211 | 1253 | KBUILD_LDFLAGS_MODULE |
| 1212 | 1254 | Options for $(LD) when linking modules |
| 1213 | 1255 | |
| @@ -39,7 +39,7 @@ as the writer can invalidate a pointer that the reader is following. · 38 unmodified lines | ||
| 39 | 39 | Sequence counters (``seqcount_t``) |
| 40 | 40 | ================================== |
| 41 | 41 | |
| 42 | −This is the the raw counting mechanism, which does not protect against | |
| 42 | +This is the raw counting mechanism, which does not protect against | |
| 43 | 43 | multiple writers. Write side critical sections must thus be serialized |
| 44 | 44 | by an external lock. |
| 45 | 45 | |
| @@ -52,7 +52,7 @@ CONTENTS · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | - Varieties of memory barrier. |
| 54 | 54 | - What may not be assumed about memory barriers? |
| 55 | − - Data dependency barriers (historical). | |
| 55 | + - Address-dependency barriers (historical). | |
| 56 | 56 | - Control dependencies. |
| 57 | 57 | - SMP barrier pairing. |
| 58 | 58 | - Examples of memory barrier sequences. |
| @@ -187,9 +187,9 @@ As a further example, consider this sequence of events: · 128 unmodified lines | ||
| 187 | 187 | B = 4; Q = P; |
| 188 | 188 | P = &B; D = *Q; |
| 189 | 189 | |
| 190 | −There is an obvious data dependency here, as the value loaded into D depends on | |
| 191 | −the address retrieved from P by CPU 2. At the end of the sequence, any of the | |
| 192 | −following results are possible: | |
| 190 | +There is an obvious address dependency here, as the value loaded into D depends | |
| 191 | +on the address retrieved from P by CPU 2. At the end of the sequence, any of | |
| 192 | +the following results are possible: | |
| 193 | 193 | |
| 194 | 194 | (Q == &A) and (D == 1) |
| 195 | 195 | (Q == &B) and (D == 2) |
| @@ -391,58 +391,62 @@ Memory barriers come in four basic varieties: · 195 unmodified lines | ||
| 391 | 391 | memory system as time progresses. All stores _before_ a write barrier |
| 392 | 392 | will occur _before_ all the stores after the write barrier. |
| 393 | 393 | |
| 394 | − [!] Note that write barriers should normally be paired with read or data | |
| 395 | − dependency barriers; see the "SMP barrier pairing" subsection. | |
| 394 | + [!] Note that write barriers should normally be paired with read or | |
| 395 | + address-dependency barriers; see the "SMP barrier pairing" subsection. | |
| 396 | 396 | |
| 397 | 397 | |
| 398 | − (2) Data dependency barriers. | |
| 398 | + (2) Address-dependency barriers (historical). | |
| 399 | 399 | |
| 400 | − A data dependency barrier is a weaker form of read barrier. In the case | |
| 401 | − where two loads are performed such that the second depends on the result | |
| 402 | − of the first (eg: the first load retrieves the address to which the second | |
| 403 | − load will be directed), a data dependency barrier would be required to | |
| 404 | − make sure that the target of the second load is updated after the address | |
| 405 | − obtained by the first load is accessed. | |
| 400 | + An address-dependency barrier is a weaker form of read barrier. In the | |
| 401 | + case where two loads are performed such that the second depends on the | |
| 402 | + result of the first (eg: the first load retrieves the address to which | |
| 403 | + the second load will be directed), an address-dependency barrier would | |
| 404 | + be required to make sure that the target of the second load is updated | |
| 405 | + after the address obtained by the first load is accessed. | |
| 406 | 406 | |
| 407 | − A data dependency barrier is a partial ordering on interdependent loads | |
| 408 | − only; it is not required to have any effect on stores, independent loads | |
| 409 | − or overlapping loads. | |
| 407 | + An address-dependency barrier is a partial ordering on interdependent | |
| 408 | + loads only; it is not required to have any effect on stores, independent | |
| 409 | + loads or overlapping loads. | |
| 410 | 410 | |
| 411 | 411 | As mentioned in (1), the other CPUs in the system can be viewed as |
| 412 | 412 | committing sequences of stores to the memory system that the CPU being |
| 413 | − considered can then perceive. A data dependency barrier issued by the CPU | |
| 414 | − under consideration guarantees that for any load preceding it, if that | |
| 415 | − load touches one of a sequence of stores from another CPU, then by the | |
| 416 | − time the barrier completes, the effects of all the stores prior to that | |
| 417 | − touched by the load will be perceptible to any loads issued after the data | |
| 418 | − dependency barrier. | |
| 413 | + considered can then perceive. An address-dependency barrier issued by | |
| 414 | + the CPU under consideration guarantees that for any load preceding it, | |
| 415 | + if that load touches one of a sequence of stores from another CPU, then | |
| 416 | + by the time the barrier completes, the effects of all the stores prior to | |
| 417 | + that touched by the load will be perceptible to any loads issued after | |
| 418 | + the address-dependency barrier. | |
| 419 | 419 | |
| 420 | 420 | See the "Examples of memory barrier sequences" subsection for diagrams |
| 421 | 421 | showing the ordering constraints. |
| 422 | 422 | |
| 423 | − [!] Note that the first load really has to have a _data_ dependency and | |
| 423 | + [!] Note that the first load really has to have an _address_ dependency and | |
| 424 | 424 | not a control dependency. If the address for the second load is dependent |
| 425 | 425 | on the first load, but the dependency is through a conditional rather than |
| 426 | 426 | actually loading the address itself, then it's a _control_ dependency and |
| 427 | 427 | a full read barrier or better is required. See the "Control dependencies" |
| 428 | 428 | subsection for more information. |
| 429 | 429 | |
| 430 | − [!] Note that data dependency barriers should normally be paired with | |
| 430 | + [!] Note that address-dependency barriers should normally be paired with | |
| 431 | 431 | write barriers; see the "SMP barrier pairing" subsection. |
| 432 | 432 | |
| 433 | + [!] Kernel release v5.9 removed kernel APIs for explicit address- | |
| 434 | + dependency barriers. Nowadays, APIs for marking loads from shared | |
| 435 | + variables such as READ_ONCE() and rcu_dereference() provide implicit | |
| 436 | + address-dependency barriers. | |
| 433 | 437 | |
| 434 | 438 | (3) Read (or load) memory barriers. |
| 435 | 439 | |
| 436 | − A read barrier is a data dependency barrier plus a guarantee that all the | |
| 437 | − LOAD operations specified before the barrier will appear to happen before | |
| 438 | − all the LOAD operations specified after the barrier with respect to the | |
| 439 | − other components of the system. | |
| 440 | + A read barrier is an address-dependency barrier plus a guarantee that all | |
| 441 | + the LOAD operations specified before the barrier will appear to happen | |
| 442 | + before all the LOAD operations specified after the barrier with respect to | |
| 443 | + the other components of the system. | |
| 440 | 444 | |
| 441 | 445 | A read barrier is a partial ordering on loads only; it is not required to |
| 442 | 446 | have any effect on stores. |
| 443 | 447 | |
| 444 | − Read memory barriers imply data dependency barriers, and so can substitute | |
| 445 | − for them. | |
| 448 | + Read memory barriers imply address-dependency barriers, and so can | |
| 449 | + substitute for them. | |
| 446 | 450 | |
| 447 | 451 | [!] Note that read barriers should normally be paired with write barriers; |
| 448 | 452 | see the "SMP barrier pairing" subsection. |
| @@ -550,17 +554,21 @@ There are certain things that the Linux kernel memory barriers do not guarantee: · 101 unmodified lines | ||
| 550 | 554 | Documentation/core-api/dma-api.rst |
| 551 | 555 | |
| 552 | 556 | |
| 553 | −DATA DEPENDENCY BARRIERS (HISTORICAL) | |
| 554 | −------------------------------------- | |
| 557 | +ADDRESS-DEPENDENCY BARRIERS (HISTORICAL) | |
| 558 | +---------------------------------------- | |
| 555 | 559 | |
| 556 | 560 | As of v4.15 of the Linux kernel, an smp_mb() was added to READ_ONCE() for |
| 557 | 561 | DEC Alpha, which means that about the only people who need to pay attention |
| 558 | 562 | to this section are those working on DEC Alpha architecture-specific code |
| 559 | 563 | and those working on READ_ONCE() itself. For those who need it, and for |
| 560 | 564 | those who are interested in the history, here is the story of |
| 561 | −data-dependency barriers. | |
| 565 | +address-dependency barriers. | |
| 566 | + | |
| 567 | +[!] While address dependencies are observed in both load-to-load and | |
| 568 | +load-to-store relations, address-dependency barriers are not necessary | |
| 569 | +for load-to-store situations. | |
| 562 | 570 | |
| 563 | −The usage requirements of data dependency barriers are a little subtle, and | |
| 571 | +The requirement of address-dependency barriers is a little subtle, and | |
| 564 | 572 | it's not always obvious that they're needed. To illustrate, consider the |
| 565 | 573 | following sequence of events: |
| 566 | 574 | |
| @@ -570,11 +578,14 @@ following sequence of events: · 3 unmodified lines | ||
| 570 | 578 | B = 4; |
| 571 | 579 | <write barrier> |
| 572 | 580 | WRITE_ONCE(P, &B); |
| 573 | − Q = READ_ONCE(P); | |
| 581 | + Q = READ_ONCE_OLD(P); | |
| 574 | 582 | D = *Q; |
| 575 | 583 | |
| 576 | −There's a clear data dependency here, and it would seem that by the end of the | |
| 577 | −sequence, Q must be either &A or &B, and that: | |
| 584 | +[!] READ_ONCE_OLD() corresponds to READ_ONCE() of pre-4.15 kernel, which | |
| 585 | +doesn't imply an address-dependency barrier. | |
| 586 | + | |
| 587 | +There's a clear address dependency here, and it would seem that by the end of | |
| 588 | +the sequence, Q must be either &A or &B, and that: | |
| 578 | 589 | |
| 579 | 590 | (Q == &A) implies (D == 1) |
| 580 | 591 | (Q == &B) implies (D == 4) |
| @@ -588,8 +599,8 @@ While this may seem like a failure of coherency or causality maintenance, it · 7 unmodified lines | ||
| 588 | 599 | isn't, and this behaviour can be observed on certain real CPUs (such as the DEC |
| 589 | 600 | Alpha). |
| 590 | 601 | |
| 591 | −To deal with this, a data dependency barrier or better must be inserted | |
| 592 | −between the address load and the data load: | |
| 602 | +To deal with this, READ_ONCE() provides an implicit address-dependency barrier | |
| 603 | +since kernel release v4.15: | |
| 593 | 604 | |
| 594 | 605 | CPU 1 CPU 2 |
| 595 | 606 | =============== =============== |
| @@ -598,7 +609,7 @@ between the address load and the data load: · 2 unmodified lines | ||
| 598 | 609 | <write barrier> |
| 599 | 610 | WRITE_ONCE(P, &B); |
| 600 | 611 | Q = READ_ONCE(P); |
| 601 | − <data dependency barrier> | |
| 612 | + <implicit address-dependency barrier> | |
| 602 | 613 | D = *Q; |
| 603 | 614 | |
| 604 | 615 | This enforces the occurrence of one of the two implications, and prevents the |
| @@ -615,13 +626,13 @@ odd-numbered bank is idle, one can see the new value of the pointer P (&B), · 10 unmodified lines | ||
| 615 | 626 | but the old value of the variable B (2). |
| 616 | 627 | |
| 617 | 628 | |
| 618 | −A data-dependency barrier is not required to order dependent writes | |
| 619 | −because the CPUs that the Linux kernel supports don't do writes | |
| 620 | −until they are certain (1) that the write will actually happen, (2) | |
| 621 | −of the location of the write, and (3) of the value to be written. | |
| 629 | +An address-dependency barrier is not required to order dependent writes | |
| 630 | +because the CPUs that the Linux kernel supports don't do writes until they | |
| 631 | +are certain (1) that the write will actually happen, (2) of the location of | |
| 632 | +the write, and (3) of the value to be written. | |
| 622 | 633 | But please carefully read the "CONTROL DEPENDENCIES" section and the |
| 623 | −Documentation/RCU/rcu_dereference.rst file: The compiler can and does | |
| 624 | −break dependencies in a great many highly creative ways. | |
| 634 | +Documentation/RCU/rcu_dereference.rst file: The compiler can and does break | |
| 635 | +dependencies in a great many highly creative ways. | |
| 625 | 636 | |
| 626 | 637 | CPU 1 CPU 2 |
| 627 | 638 | =============== =============== |
| @@ -629,12 +640,12 @@ break dependencies in a great many highly creative ways. · 1 unmodified line | ||
| 629 | 640 | B = 4; |
| 630 | 641 | <write barrier> |
| 631 | 642 | WRITE_ONCE(P, &B); |
| 632 | − Q = READ_ONCE(P); | |
| 643 | + Q = READ_ONCE_OLD(P); | |
| 633 | 644 | WRITE_ONCE(*Q, 5); |
| 634 | 645 | |
| 635 | −Therefore, no data-dependency barrier is required to order the read into | |
| 646 | +Therefore, no address-dependency barrier is required to order the read into | |
| 636 | 647 | Q with the store into *Q. In other words, this outcome is prohibited, |
| 637 | −even without a data-dependency barrier: | |
| 648 | +even without an implicit address-dependency barrier of modern READ_ONCE(): | |
| 638 | 649 | |
| 639 | 650 | (Q == &B) && (B == 4) |
| 640 | 651 | |
| @@ -645,12 +656,12 @@ can be used to record rare error conditions and the like, and the CPUs' · 4 unmodified lines | ||
| 645 | 656 | naturally occurring ordering prevents such records from being lost. |
| 646 | 657 | |
| 647 | 658 | |
| 648 | −Note well that the ordering provided by a data dependency is local to | |
| 659 | +Note well that the ordering provided by an address dependency is local to | |
| 649 | 660 | the CPU containing it. See the section on "Multicopy atomicity" for |
| 650 | 661 | more information. |
| 651 | 662 | |
| 652 | 663 | |
| 653 | −The data dependency barrier is very important to the RCU system, | |
| 664 | +The address-dependency barrier is very important to the RCU system, | |
| 654 | 665 | for example. See rcu_assign_pointer() and rcu_dereference() in |
| 655 | 666 | include/linux/rcupdate.h. This permits the current target of an RCU'd |
| 656 | 667 | pointer to be replaced with a new modified target, without the replacement |
| @@ -667,20 +678,21 @@ not understand them. The purpose of this section is to help you prevent · 10 unmodified lines | ||
| 667 | 678 | the compiler's ignorance from breaking your code. |
| 668 | 679 | |
| 669 | 680 | A load-load control dependency requires a full read memory barrier, not |
| 670 | −simply a data dependency barrier to make it work correctly. Consider the | |
| 671 | −following bit of code: | |
| 681 | +simply an (implicit) address-dependency barrier to make it work correctly. | |
| 682 | +Consider the following bit of code: | |
| 672 | 683 | |
| 673 | 684 | q = READ_ONCE(a); |
| 685 | + <implicit address-dependency barrier> | |
| 674 | 686 | if (q) { |
| 675 | − <data dependency barrier> /* BUG: No data dependency!!! */ | |
| 687 | + /* BUG: No address dependency!!! */ | |
| 676 | 688 | p = READ_ONCE(b); |
| 677 | 689 | } |
| 678 | 690 | |
| 679 | −This will not have the desired effect because there is no actual data | |
| 691 | +This will not have the desired effect because there is no actual address | |
| 680 | 692 | dependency, but rather a control dependency that the CPU may short-circuit |
| 681 | 693 | by attempting to predict the outcome in advance, so that other CPUs see |
| 682 | −the load from b as having happened before the load from a. In such a | |
| 683 | −case what's actually required is: | |
| 694 | +the load from b as having happened before the load from a. In such a case | |
| 695 | +what's actually required is: | |
| 684 | 696 | |
| 685 | 697 | q = READ_ONCE(a); |
| 686 | 698 | if (q) { |
| @@ -927,9 +939,9 @@ General barriers pair with each other, though they also pair with most · 240 unmodified lines | ||
| 927 | 939 | other types of barriers, albeit without multicopy atomicity. An acquire |
| 928 | 940 | barrier pairs with a release barrier, but both may also pair with other |
| 929 | 941 | barriers, including of course general barriers. A write barrier pairs |
| 930 | −with a data dependency barrier, a control dependency, an acquire barrier, | |
| 942 | +with an address-dependency barrier, a control dependency, an acquire barrier, | |
| 931 | 943 | a release barrier, a read barrier, or a general barrier. Similarly a |
| 932 | −read barrier, control dependency, or a data dependency barrier pairs | |
| 944 | +read barrier, control dependency, or an address-dependency barrier pairs | |
| 933 | 945 | with a write barrier, an acquire barrier, a release barrier, or a |
| 934 | 946 | general barrier: |
| 935 | 947 | |
| @@ -948,7 +960,7 @@ Or: · 12 unmodified lines | ||
| 948 | 960 | a = 1; |
| 949 | 961 | <write barrier> |
| 950 | 962 | WRITE_ONCE(b, &a); x = READ_ONCE(b); |
| 951 | − <data dependency barrier> | |
| 963 | + <implicit address-dependency barrier> | |
| 952 | 964 | y = *x; |
| 953 | 965 | |
| 954 | 966 | Or even: |
| @@ -968,8 +980,8 @@ Basically, the read barrier always has to be there, even though it can be of · 13 unmodified lines | ||
| 968 | 980 | the "weaker" type. |
| 969 | 981 | |
| 970 | 982 | [!] Note that the stores before the write barrier would normally be expected to |
| 971 | −match the loads after the read barrier or the data dependency barrier, and vice | |
| 972 | −versa: | |
| 983 | +match the loads after the read barrier or the address-dependency barrier, and | |
| 984 | +vice versa: | |
| 973 | 985 | |
| 974 | 986 | CPU 1 CPU 2 |
| 975 | 987 | =================== =================== |
| @@ -1021,8 +1033,8 @@ STORE B, STORE C } all occurring before the unordered set of { STORE D, STORE E · 45 unmodified lines | ||
| 1021 | 1033 | V |
| 1022 | 1034 | |
| 1023 | 1035 | |
| 1024 | −Secondly, data dependency barriers act as partial orderings on data-dependent | |
| 1025 | −loads. Consider the following sequence of events: | |
| 1036 | +Secondly, address-dependency barriers act as partial orderings on address- | |
| 1037 | +dependent loads. Consider the following sequence of events: | |
| 1026 | 1038 | |
| 1027 | 1039 | CPU 1 CPU 2 |
| 1028 | 1040 | ======================= ======================= |
| @@ -1067,8 +1079,8 @@ effectively random order, despite the write barrier issued by CPU 1: · 38 unmodified lines | ||
| 1067 | 1079 | In the above example, CPU 2 perceives that B is 7, despite the load of *C |
| 1068 | 1080 | (which would be B) coming after the LOAD of C. |
| 1069 | 1081 | |
| 1070 | −If, however, a data dependency barrier were to be placed between the load of C | |
| 1071 | −and the load of *C (ie: B) on CPU 2: | |
| 1082 | +If, however, an address-dependency barrier were to be placed between the load | |
| 1083 | +of C and the load of *C (ie: B) on CPU 2: | |
| 1072 | 1084 | |
| 1073 | 1085 | CPU 1 CPU 2 |
| 1074 | 1086 | ======================= ======================= |
| @@ -1078,7 +1090,7 @@ and the load of *C (ie: B) on CPU 2: · 3 unmodified lines | ||
| 1078 | 1090 | <write barrier> |
| 1079 | 1091 | STORE C = &B LOAD X |
| 1080 | 1092 | STORE D = 4 LOAD C (gets &B) |
| 1081 | − <data dependency barrier> | |
| 1093 | + <address-dependency barrier> | |
| 1082 | 1094 | LOAD *C (reads B) |
| 1083 | 1095 | |
| 1084 | 1096 | then the following will occur: |
| @@ -1101,7 +1113,7 @@ then the following will occur: · 16 unmodified lines | ||
| 1101 | 1113 | | +-------+ | | |
| 1102 | 1114 | | | X->9 |------>| | |
| 1103 | 1115 | | +-------+ | | |
| 1104 | − Makes sure all effects ---> \ ddddddddddddddddd | | | |
| 1116 | + Makes sure all effects ---> \ aaaaaaaaaaaaaaaaa | | | |
| 1105 | 1117 | prior to the store of C \ +-------+ | | |
| 1106 | 1118 | are perceptible to ----->| B->2 |------>| | |
| 1107 | 1119 | subsequent loads +-------+ | | |
| @@ -1292,7 +1304,7 @@ Which might appear as this: · 184 unmodified lines | ||
| 1292 | 1304 | LOAD with immediate effect : : +-------+ |
| 1293 | 1305 | |
| 1294 | 1306 | |
| 1295 | −Placing a read barrier or a data dependency barrier just before the second | |
| 1307 | +Placing a read barrier or an address-dependency barrier just before the second | |
| 1296 | 1308 | load: |
| 1297 | 1309 | |
| 1298 | 1310 | CPU 1 CPU 2 |
| @@ -1816,20 +1828,20 @@ which may then reorder things however it wishes. · 517 unmodified lines | ||
| 1816 | 1828 | CPU MEMORY BARRIERS |
| 1817 | 1829 | ------------------- |
| 1818 | 1830 | |
| 1819 | −The Linux kernel has eight basic CPU memory barriers: | |
| 1831 | +The Linux kernel has seven basic CPU memory barriers: | |
| 1820 | 1832 | |
| 1821 | − TYPE MANDATORY SMP CONDITIONAL | |
| 1822 | − =============== ======================= =========================== | |
| 1823 | − GENERAL mb() smp_mb() | |
| 1824 | − WRITE wmb() smp_wmb() | |
| 1825 | − READ rmb() smp_rmb() | |
| 1826 | − DATA DEPENDENCY READ_ONCE() | |
| 1833 | + TYPE MANDATORY SMP CONDITIONAL | |
| 1834 | + ======================= =============== =============== | |
| 1835 | + GENERAL mb() smp_mb() | |
| 1836 | + WRITE wmb() smp_wmb() | |
| 1837 | + READ rmb() smp_rmb() | |
| 1838 | + ADDRESS DEPENDENCY READ_ONCE() | |
| 1827 | 1839 | |
| 1828 | 1840 | |
| 1829 | −All memory barriers except the data dependency barriers imply a compiler | |
| 1830 | −barrier. Data dependencies do not impose any additional compiler ordering. | |
| 1841 | +All memory barriers except the address-dependency barriers imply a compiler | |
| 1842 | +barrier. Address dependencies do not impose any additional compiler ordering. | |
| 1831 | 1843 | |
| 1832 | −Aside: In the case of data dependencies, the compiler would be expected | |
| 1844 | +Aside: In the case of address dependencies, the compiler would be expected | |
| 1833 | 1845 | to issue the loads in the correct order (eg. `a[b]` would have to load |
| 1834 | 1846 | the value of b before loading a[b]), however there is no guarantee in |
| 1835 | 1847 | the C specification that the compiler may not speculate the value of b |
| @@ -2749,7 +2761,8 @@ is discarded from the CPU's cache and reloaded. To deal with this, the · 913 unmodified lines | ||
| 2749 | 2761 | appropriate part of the kernel must invalidate the overlapping bits of the |
| 2750 | 2762 | cache on each CPU. |
| 2751 | 2763 | |
| 2752 | −See Documentation/core-api/cachetlb.rst for more information on cache management. | |
| 2764 | +See Documentation/core-api/cachetlb.rst for more information on cache | |
| 2765 | +management. | |
| 2753 | 2766 | |
| 2754 | 2767 | |
| 2755 | 2768 | CACHE COHERENCY VS MMIO |
| @@ -2889,8 +2902,8 @@ AND THEN THERE'S THE ALPHA · 133 unmodified lines | ||
| 2889 | 2902 | The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that, |
| 2890 | 2903 | some versions of the Alpha CPU have a split data cache, permitting them to have |
| 2891 | 2904 | two semantically-related cache lines updated at separate times. This is where |
| 2892 | −the data dependency barrier really becomes necessary as this synchronises both | |
| 2893 | −caches with the memory coherence system, thus making it seem like pointer | |
| 2905 | +the address-dependency barrier really becomes necessary as this synchronises | |
| 2906 | +both caches with the memory coherence system, thus making it seem like pointer | |
| 2894 | 2907 | changes vs new data occur in the right order. |
| 2895 | 2908 | |
| 2896 | 2909 | The Alpha defines the Linux kernel's memory model, although as of v4.15 |
| @@ -197,7 +197,7 @@ unevictable list for the memory cgroup and node being scanned. · 196 unmodified lines | ||
| 197 | 197 | There may be situations where a page is mapped into a VM_LOCKED VMA, but the |
| 198 | 198 | page is not marked as PG_mlocked. Such pages will make it all the way to |
| 199 | 199 | shrink_active_list() or shrink_page_list() where they will be detected when |
| 200 | −vmscan walks the reverse map in page_referenced() or try_to_unmap(). The page | |
| 200 | +vmscan walks the reverse map in folio_referenced() or try_to_unmap(). The page | |
| 201 | 201 | is culled to the unevictable list when it is released by the shrinker. |
| 202 | 202 | |
| 203 | 203 | To "cull" an unevictable page, vmscan simply puts the page back on the LRU list |
| @@ -267,7 +267,7 @@ the LRU. Such pages can be "noticed" by memory management in several places: · 63 unmodified lines | ||
| 267 | 267 | (4) in the fault path and when a VM_LOCKED stack segment is expanded; or |
| 268 | 268 | |
| 269 | 269 | (5) as mentioned above, in vmscan:shrink_page_list() when attempting to |
| 270 | − reclaim a page in a VM_LOCKED VMA by page_referenced() or try_to_unmap(). | |
| 270 | + reclaim a page in a VM_LOCKED VMA by folio_referenced() or try_to_unmap(). | |
| 271 | 271 | |
| 272 | 272 | mlocked pages become unlocked and rescued from the unevictable list when: |
| 273 | 273 | |
| @@ -547,7 +547,7 @@ vmscan's shrink_inactive_list() and shrink_page_list() also divert obviously · 273 unmodified lines | ||
| 547 | 547 | unevictable pages found on the inactive lists to the appropriate memory cgroup |
| 548 | 548 | and node unevictable list. |
| 549 | 549 | |
| 550 | −rmap's page_referenced_one(), called via vmscan's shrink_active_list() or | |
| 550 | +rmap's folio_referenced_one(), called via vmscan's shrink_active_list() or | |
| 551 | 551 | shrink_page_list(), and rmap's try_to_unmap_one() called via shrink_page_list(), |
| 552 | 552 | check for (3) pages still mapped into VM_LOCKED VMAs, and call mlock_vma_page() |
| 553 | 553 | to correct them. Such pages are culled to the unevictable list when released |
| @@ -220,6 +220,8 @@ Userspace to kernel: · 219 unmodified lines | ||
| 220 | 220 | ``ETHTOOL_MSG_PHC_VCLOCKS_GET`` get PHC virtual clocks info |
| 221 | 221 | ``ETHTOOL_MSG_MODULE_SET`` set transceiver module parameters |
| 222 | 222 | ``ETHTOOL_MSG_MODULE_GET`` get transceiver module parameters |
| 223 | + ``ETHTOOL_MSG_PSE_SET`` set PSE parameters | |
| 224 | + ``ETHTOOL_MSG_PSE_GET`` get PSE parameters | |
| 223 | 225 | ===================================== ================================= |
| 224 | 226 | |
| 225 | 227 | Kernel to userspace: |
| @@ -260,6 +262,7 @@ Kernel to userspace: · 34 unmodified lines | ||
| 260 | 262 | ``ETHTOOL_MSG_STATS_GET_REPLY`` standard statistics |
| 261 | 263 | ``ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY`` PHC virtual clocks info |
| 262 | 264 | ``ETHTOOL_MSG_MODULE_GET_REPLY`` transceiver module parameters |
| 265 | + ``ETHTOOL_MSG_PSE_GET_REPLY`` PSE parameters | |
| 263 | 266 | ======================================== ================================= |
| 264 | 267 | |
| 265 | 268 | ``GET`` requests are sent by userspace applications to retrieve device |
| @@ -1627,6 +1630,62 @@ For SFF-8636 modules, low power mode is forced by the host according to table · 1361 unmodified lines | ||
| 1627 | 1630 | For CMIS modules, low power mode is forced by the host according to table 6-12 |
| 1628 | 1631 | in revision 5.0 of the specification. |
| 1629 | 1632 | |
| 1633 | +PSE_GET | |
| 1634 | +======= | |
| 1635 | + | |
| 1636 | +Gets PSE attributes. | |
| 1637 | + | |
| 1638 | +Request contents: | |
| 1639 | + | |
| 1640 | + ===================================== ====== ========================== | |
| 1641 | + ``ETHTOOL_A_PSE_HEADER`` nested request header | |
| 1642 | + ===================================== ====== ========================== | |
| 1643 | + | |
| 1644 | +Kernel response contents: | |
| 1645 | + | |
| 1646 | + ====================================== ====== ============================= | |
| 1647 | + ``ETHTOOL_A_PSE_HEADER`` nested reply header | |
| 1648 | + ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` u32 Operational state of the PoDL | |
| 1649 | + PSE functions | |
| 1650 | + ``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` u32 power detection status of the | |
| 1651 | + PoDL PSE. | |
| 1652 | + ====================================== ====== ============================= | |
| 1653 | + | |
| 1654 | +When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies | |
| 1655 | +the operational state of the PoDL PSE functions. The operational state of the | |
| 1656 | +PSE function can be changed using the ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` | |
| 1657 | +action. This option is corresponding to ``IEEE 802.3-2018`` 30.15.1.1.2 | |
| 1658 | +aPoDLPSEAdminState. Possible values are: | |
| 1659 | + | |
| 1660 | +.. kernel-doc:: include/uapi/linux/ethtool.h | |
| 1661 | + :identifiers: ethtool_podl_pse_admin_state | |
| 1662 | + | |
| 1663 | +When set, the optional ``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` attribute identifies | |
| 1664 | +the power detection status of the PoDL PSE. The status depend on internal PSE | |
| 1665 | +state machine and automatic PD classification support. This option is | |
| 1666 | +corresponding to ``IEEE 802.3-2018`` 30.15.1.1.3 aPoDLPSEPowerDetectionStatus. | |
| 1667 | +Possible values are: | |
| 1668 | + | |
| 1669 | +.. kernel-doc:: include/uapi/linux/ethtool.h | |
| 1670 | + :identifiers: ethtool_podl_pse_pw_d_status | |
| 1671 | + | |
| 1672 | +PSE_SET | |
| 1673 | +======= | |
| 1674 | + | |
| 1675 | +Sets PSE parameters. | |
| 1676 | + | |
| 1677 | +Request contents: | |
| 1678 | + | |
| 1679 | + ====================================== ====== ============================= | |
| 1680 | + ``ETHTOOL_A_PSE_HEADER`` nested request header | |
| 1681 | + ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` u32 Control PoDL PSE Admin state | |
| 1682 | + ====================================== ====== ============================= | |
| 1683 | + | |
| 1684 | +When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` attribute is used | |
| 1685 | +to control PoDL PSE Admin functions. This option is implementing | |
| 1686 | +``IEEE 802.3-2018`` 30.15.1.2.1 acPoDLPSEAdminControl. See | |
| 1687 | +``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` for supported values. | |
| 1688 | + | |
| 1630 | 1689 | Request translation |
| 1631 | 1690 | =================== |
| 1632 | 1691 | |
| @@ -256,8 +256,10 @@ The tags in common use are: · 255 unmodified lines | ||
| 256 | 256 | - Cc: the named person received a copy of the patch and had the |
| 257 | 257 | opportunity to comment on it. |
| 258 | 258 | |
| 259 | −Be careful in the addition of tags to your patches: only Cc: is appropriate | |
| 260 | −for addition without the explicit permission of the person named. | |
| 259 | +Be careful in the addition of tags to your patches, as only Cc: is appropriate | |
| 260 | +for addition without the explicit permission of the person named; using | |
| 261 | +Reported-by: is fine most of the time as well, but ask for permission if | |
| 262 | +the bug was reported in private. | |
| 261 | 263 | |
| 262 | 264 | |
| 263 | 265 | Sending the patch |
| @@ -31,6 +31,8 @@ you probably needn't concern yourself with pcmciautils. · 30 unmodified lines | ||
| 31 | 31 | ====================== =============== ======================================== |
| 32 | 32 | GNU C 5.1 gcc --version |
| 33 | 33 | Clang/LLVM (optional) 11.0.0 clang --version |
| 34 | +Rust (optional) 1.62.0 rustc --version | |
| 35 | +bindgen (optional) 0.56.0 bindgen --version | |
| 34 | 36 | GNU make 3.81 make --version |
| 35 | 37 | bash 4.2 bash --version |
| 36 | 38 | binutils 2.23 ld -v |
| @@ -80,6 +82,29 @@ kernels. Older releases aren't guaranteed to work, and we may drop workarounds · 43 unmodified lines | ||
| 80 | 82 | from the kernel that were used to support older versions. Please see additional |
| 81 | 83 | docs on :ref:`Building Linux with Clang/LLVM <kbuild_llvm>`. |
| 82 | 84 | |
| 85 | +Rust (optional) | |
| 86 | +--------------- | |
| 87 | + | |
| 88 | +A particular version of the Rust toolchain is required. Newer versions may or | |
| 89 | +may not work because the kernel depends on some unstable Rust features, for | |
| 90 | +the moment. | |
| 91 | + | |
| 92 | +Each Rust toolchain comes with several "components", some of which are required | |
| 93 | +(like ``rustc``) and some that are optional. The ``rust-src`` component (which | |
| 94 | +is optional) needs to be installed to build the kernel. Other components are | |
| 95 | +useful for developing. | |
| 96 | + | |
| 97 | +Please see Documentation/rust/quick-start.rst for instructions on how to | |
| 98 | +satisfy the build requirements of Rust support. In particular, the ``Makefile`` | |
| 99 | +target ``rustavailable`` is useful to check why the Rust toolchain may not | |
| 100 | +be detected. | |
| 101 | + | |
| 102 | +bindgen (optional) | |
| 103 | +------------------ | |
| 104 | + | |
| 105 | +``bindgen`` is used to generate the Rust bindings to the C side of the kernel. | |
| 106 | +It depends on ``libclang``. | |
| 107 | + | |
| 83 | 108 | Make |
| 84 | 109 | ---- |
| 85 | 110 | |
| @@ -348,6 +373,12 @@ Sphinx · 262 unmodified lines | ||
| 348 | 373 | Please see :ref:`sphinx_install` in :ref:`Documentation/doc-guide/sphinx.rst <sphinxdoc>` |
| 349 | 374 | for details about Sphinx requirements. |
| 350 | 375 | |
| 376 | +rustdoc | |
| 377 | +------- | |
| 378 | + | |
| 379 | +``rustdoc`` is used to generate the documentation for Rust code. Please see | |
| 380 | +Documentation/rust/general-information.rst for more information. | |
| 381 | + | |
| 351 | 382 | Getting updated software |
| 352 | 383 | ======================== |
| 353 | 384 | |
| @@ -364,6 +395,16 @@ Clang/LLVM · 10 unmodified lines | ||
| 364 | 395 | |
| 365 | 396 | - :ref:`Getting LLVM <getting_llvm>`. |
| 366 | 397 | |
| 398 | +Rust | |
| 399 | +---- | |
| 400 | + | |
| 401 | +- Documentation/rust/quick-start.rst. | |
| 402 | + | |
| 403 | +bindgen | |
| 404 | +------- | |
| 405 | + | |
| 406 | +- Documentation/rust/quick-start.rst. | |
| 407 | + | |
| 367 | 408 | Make |
| 368 | 409 | ---- |
| 369 | 410 | |
| @@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're · 50 unmodified lines | ||
| 51 | 51 | uncertain how to handle situations that come up. It will not be |
| 52 | 52 | considered a violation report unless you want it to be. If you are |
| 53 | 53 | uncertain about approaching the TAB or any other maintainers, please |
| 54 | −reach out to our conflict mediator, Mishi Choudhary <mishi@linux.com>. | |
| 54 | +reach out to our conflict mediator, Joanna Lee <joanna.lee@gesmer.com>. | |
| 55 | 55 | |
| 56 | 56 | In the end, "be kind to each other" is really what the end goal is for |
| 57 | 57 | everybody. We know everyone is human and we all fail at times, but the |
| @@ -127,10 +127,12 @@ are listed at https://kernel.org/code-of-conduct.html. Members can not · 69 unmodified lines | ||
| 127 | 127 | access reports made before they joined or after they have left the |
| 128 | 128 | committee. |
| 129 | 129 | |
| 130 | −The initial Code of Conduct Committee consists of volunteer members of | |
| 131 | −the TAB, as well as a professional mediator acting as a neutral third | |
| 132 | −party. The first task of the committee is to establish documented | |
| 133 | −processes, which will be made public. | |
| 130 | +The Code of Conduct Committee consists of volunteer community members | |
| 131 | +appointed by the TAB, as well as a professional mediator acting as a | |
| 132 | +neutral third party. The processes the Code of Conduct committee will | |
| 133 | +use to address reports is varied and will depend on the individual | |
| 134 | +circumstance, however, this file serves as documentation for the | |
| 135 | +general process used. | |
| 134 | 136 | |
| 135 | 137 | Any member of the committee, including the mediator, can be contacted |
| 136 | 138 | directly if a reporter does not wish to include the full committee in a |
| @@ -141,16 +143,16 @@ processes (see above) and consults with the TAB as needed and · 4 unmodified lines | ||
| 141 | 143 | appropriate, for instance to request and receive information about the |
| 142 | 144 | kernel community. |
| 143 | 145 | |
| 144 | −Any decisions by the committee will be brought to the TAB, for | |
| 145 | −implementation of enforcement with the relevant maintainers if needed. | |
| 146 | −A decision by the Code of Conduct Committee can be overturned by the TAB | |
| 147 | −by a two-thirds vote. | |
| 146 | +Any decisions regarding enforcement recommendations will be brought to | |
| 147 | +the TAB for implementation of enforcement with the relevant maintainers | |
| 148 | +if needed. A decision by the Code of Conduct Committee can be overturned | |
| 149 | +by the TAB by a two-thirds vote. | |
| 148 | 150 | |
| 149 | 151 | At quarterly intervals, the Code of Conduct Committee and TAB will |
| 150 | 152 | provide a report summarizing the anonymised reports that the Code of |
| 151 | 153 | Conduct committee has received and their status, as well details of any |
| 152 | 154 | overridden decisions including complete and identifiable voting details. |
| 153 | 155 | |
| 154 | −We expect to establish a different process for Code of Conduct Committee | |
| 155 | −staffing beyond the bootstrap period. This document will be updated | |
| 156 | −with that information when this occurs. | |
| 156 | +Because how we interpret and enforce the Code of Conduct will evolve over | |
| 157 | +time, this document will be updated when necessary to reflect any | |
| 158 | +changes. | |
| @@ -1186,6 +1186,68 @@ expression used. For instance: · 1185 unmodified lines | ||
| 1186 | 1186 | #endif /* CONFIG_SOMETHING */ |
| 1187 | 1187 | |
| 1188 | 1188 | |
| 1189 | +22) Do not crash the kernel | |
| 1190 | +--------------------------- | |
| 1191 | + | |
| 1192 | +In general, the decision to crash the kernel belongs to the user, rather | |
| 1193 | +than to the kernel developer. | |
| 1194 | + | |
| 1195 | +Avoid panic() | |
| 1196 | +************* | |
| 1197 | + | |
| 1198 | +panic() should be used with care and primarily only during system boot. | |
| 1199 | +panic() is, for example, acceptable when running out of memory during boot and | |
| 1200 | +not being able to continue. | |
| 1201 | + | |
| 1202 | +Use WARN() rather than BUG() | |
| 1203 | +**************************** | |
| 1204 | + | |
| 1205 | +Do not add new code that uses any of the BUG() variants, such as BUG(), | |
| 1206 | +BUG_ON(), or VM_BUG_ON(). Instead, use a WARN*() variant, preferably | |
| 1207 | +WARN_ON_ONCE(), and possibly with recovery code. Recovery code is not | |
| 1208 | +required if there is no reasonable way to at least partially recover. | |
| 1209 | + | |
| 1210 | +"I'm too lazy to do error handling" is not an excuse for using BUG(). Major | |
| 1211 | +internal corruptions with no way of continuing may still use BUG(), but need | |
| 1212 | +good justification. | |
| 1213 | + | |
| 1214 | +Use WARN_ON_ONCE() rather than WARN() or WARN_ON() | |
| 1215 | +************************************************** | |
| 1216 | + | |
| 1217 | +WARN_ON_ONCE() is generally preferred over WARN() or WARN_ON(), because it | |
| 1218 | +is common for a given warning condition, if it occurs at all, to occur | |
| 1219 | +multiple times. This can fill up and wrap the kernel log, and can even slow | |
| 1220 | +the system enough that the excessive logging turns into its own, additional | |
| 1221 | +problem. | |
| 1222 | + | |
| 1223 | +Do not WARN lightly | |
| 1224 | +******************* | |
| 1225 | + | |
| 1226 | +WARN*() is intended for unexpected, this-should-never-happen situations. | |
| 1227 | +WARN*() macros are not to be used for anything that is expected to happen | |
| 1228 | +during normal operation. These are not pre- or post-condition asserts, for | |
| 1229 | +example. Again: WARN*() must not be used for a condition that is expected | |
| 1230 | +to trigger easily, for example, by user space actions. pr_warn_once() is a | |
| 1231 | +possible alternative, if you need to notify the user of a problem. | |
| 1232 | + | |
| 1233 | +Do not worry about panic_on_warn users | |
| 1234 | +************************************** | |
| 1235 | + | |
| 1236 | +A few more words about panic_on_warn: Remember that ``panic_on_warn`` is an | |
| 1237 | +available kernel option, and that many users set this option. This is why | |
| 1238 | +there is a "Do not WARN lightly" writeup, above. However, the existence of | |
| 1239 | +panic_on_warn users is not a valid reason to avoid the judicious use | |
| 1240 | +WARN*(). That is because, whoever enables panic_on_warn has explicitly | |
| 1241 | +asked the kernel to crash if a WARN*() fires, and such users must be | |
| 1242 | +prepared to deal with the consequences of a system that is somewhat more | |
| 1243 | +likely to crash. | |
| 1244 | + | |
| 1245 | +Use BUILD_BUG_ON() for compile-time assertions | |
| 1246 | +********************************************** | |
| 1247 | + | |
| 1248 | +The use of BUILD_BUG_ON() is acceptable and encouraged, because it is a | |
| 1249 | +compile-time assertion that has no effect at runtime. | |
| 1250 | + | |
| 1189 | 1251 | Appendix I) References |
| 1190 | 1252 | ---------------------- |
| 1191 | 1253 | |
| @@ -138,17 +138,20 @@ be NUL terminated. This can lead to various linear read overflows and · 137 unmodified lines | ||
| 138 | 138 | other misbehavior due to the missing termination. It also NUL-pads |
| 139 | 139 | the destination buffer if the source contents are shorter than the |
| 140 | 140 | destination buffer size, which may be a needless performance penalty |
| 141 | −for callers using only NUL-terminated strings. The safe replacement is | |
| 141 | +for callers using only NUL-terminated strings. | |
| 142 | + | |
| 143 | +When the destination is required to be NUL-terminated, the replacement is | |
| 142 | 144 | strscpy(), though care must be given to any cases where the return value |
| 143 | 145 | of strncpy() was used, since strscpy() does not return a pointer to the |
| 144 | 146 | destination, but rather a count of non-NUL bytes copied (or negative |
| 145 | 147 | errno when it truncates). Any cases still needing NUL-padding should |
| 146 | 148 | instead use strscpy_pad(). |
| 147 | 149 | |
| 148 | −If a caller is using non-NUL-terminated strings, strncpy() can | |
| 149 | −still be used, but destinations should be marked with the `__nonstring | |
| 150 | +If a caller is using non-NUL-terminated strings, strtomem() should be | |
| 151 | +used, and the destinations should be marked with the `__nonstring | |
| 150 | 152 | <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_ |
| 151 | −attribute to avoid future compiler warnings. | |
| 153 | +attribute to avoid future compiler warnings. For cases still needing | |
| 154 | +NUL-padding, strtomem_pad() can be used. | |
| 152 | 155 | |
| 153 | 156 | strlcpy() |
| 154 | 157 | --------- |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | .. _process_index: |
| 7 | 7 | |
| 8 | +============================================= | |
| 8 | 9 | Working with the kernel development community |
| 9 | 10 | ============================================= |
| 10 | 11 | |
| @@ -121,57 +121,56 @@ edit your ``~/.gnupg/gpg-agent.conf`` file to set your own values:: · 120 unmodified lines | ||
| 121 | 121 | to remove anything you had in place for older versions of GnuPG, as |
| 122 | 122 | it may not be doing the right thing any more. |
| 123 | 123 | |
| 124 | −Set up a refresh cronjob | |
| 125 | −~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 126 | − | |
| 127 | −You will need to regularly refresh your keyring in order to get the | |
| 128 | −latest changes on other people's public keys, which is best done with a | |
| 129 | −daily cronjob:: | |
| 130 | − | |
| 131 | − @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1 | |
| 132 | − | |
| 133 | −Check the full path to your ``gpg`` or ``gpg2`` command and use the | |
| 134 | −``gpg2`` command if regular ``gpg`` for you is the legacy GnuPG v.1. | |
| 135 | − | |
| 136 | −.. _master_key: | |
| 124 | +.. _protect_your_key: | |
| 137 | 125 | |
| 138 | −Protect your master PGP key | |
| 139 | −=========================== | |
| 126 | +Protect your PGP key | |
| 127 | +==================== | |
| 140 | 128 | |
| 141 | 129 | This guide assumes that you already have a PGP key that you use for Linux |
| 142 | 130 | kernel development purposes. If you do not yet have one, please see the |
| 143 | 131 | "`Protecting Code Integrity`_" document mentioned earlier for guidance |
| 144 | 132 | on how to create a new one. |
| 145 | 133 | |
| 146 | −You should also make a new key if your current one is weaker than 2048 bits | |
| 147 | −(RSA). | |
| 148 | − | |
| 149 | −Master key vs. Subkeys | |
| 150 | −---------------------- | |
| 151 | − | |
| 152 | −Subkeys are fully independent PGP keypairs that are tied to the "master" | |
| 153 | −key using certifying key signatures (certificates). It is important to | |
| 154 | −understand the following: | |
| 155 | − | |
| 156 | −1. There are no technical differences between the "master key" and "subkeys." | |
| 157 | −2. At creation time, we assign functional limitations to each key by | |
| 158 | − giving it specific capabilities. | |
| 159 | −3. A PGP key can have 4 capabilities: | |
| 160 | − | |
| 161 | − - **[S]** key can be used for signing | |
| 162 | − - **[E]** key can be used for encryption | |
| 163 | − - **[A]** key can be used for authentication | |
| 164 | − - **[C]** key can be used for certifying other keys | |
| 165 | − | |
| 166 | −4. A single key may have multiple capabilities. | |
| 167 | −5. A subkey is fully independent from the master key. A message | |
| 168 | − encrypted to a subkey cannot be decrypted with the master key. If you | |
| 169 | − lose your private subkey, it cannot be recreated from the master key | |
| 170 | − in any way. | |
| 171 | − | |
| 172 | −The key carrying the **[C]** (certify) capability is considered the | |
| 173 | −"master" key because it is the only key that can be used to indicate | |
| 174 | −relationship with other keys. Only the **[C]** key can be used to: | |
| 134 | +You should also make a new key if your current one is weaker than 2048 | |
| 135 | +bits (RSA). | |
| 136 | + | |
| 137 | +Understanding PGP Subkeys | |
| 138 | +------------------------- | |
| 139 | + | |
| 140 | +A PGP key rarely consists of a single keypair -- usually it is a | |
| 141 | +collection of independent subkeys that can be used for different | |
| 142 | +purposes based on their capabilities, assigned at their creation time. | |
| 143 | +PGP defines four capabilities that a key can have: | |
| 144 | + | |
| 145 | +- **[S]** keys can be used for signing | |
| 146 | +- **[E]** keys can be used for encryption | |
| 147 | +- **[A]** keys can be used for authentication | |
| 148 | +- **[C]** keys can be used for certifying other keys | |
| 149 | + | |
| 150 | +The key with the **[C]** capability is often called the "master" key, | |
| 151 | +but this terminology is misleading because it implies that the Certify | |
| 152 | +key can be used in place of any of other subkey on the same chain (like | |
| 153 | +a physical "master key" can be used to open the locks made for other | |
| 154 | +keys). Since this is not the case, this guide will refer to it as "the | |
| 155 | +Certify key" to avoid any ambiguity. | |
| 156 | + | |
| 157 | +It is critical to fully understand the following: | |
| 158 | + | |
| 159 | +1. All subkeys are fully independent from each other. If you lose a | |
| 160 | + private subkey, it cannot be restored or recreated from any other | |
| 161 | + private key on your chain. | |
| 162 | +2. With the exception of the Certify key, there can be multiple subkeys | |
| 163 | + with identical capabilities (e.g. you can have 2 valid encryption | |
| 164 | + subkeys, 3 valid signing subkeys, but only one valid certification | |
| 165 | + subkey). All subkeys are fully independent -- a message encrypted to | |
| 166 | + one **[E]** subkey cannot be decrypted with any other **[E]** subkey | |
| 167 | + you may also have. | |
| 168 | +3. A single subkey may have multiple capabilities (e.g. your **[C]** key | |
| 169 | + can also be your **[S]** key). | |
| 170 | + | |
| 171 | +The key carrying the **[C]** (certify) capability is the only key that | |
| 172 | +can be used to indicate relationship with other keys. Only the **[C]** | |
| 173 | +key can be used to: | |
| 175 | 174 | |
| 176 | 175 | - add or revoke other keys (subkeys) with S/E/A capabilities |
| 177 | 176 | - add, change or revoke identities (uids) associated with the key |
| @@ -180,7 +179,7 @@ relationship with other keys. Only the **[C]** key can be used to: · 2 unmodified lines | ||
| 180 | 179 | |
| 181 | 180 | By default, GnuPG creates the following when generating new keys: |
| 182 | 181 | |
| 183 | −- A master key carrying both Certify and Sign capabilities (**[SC]**) | |
| 182 | +- One subkey carrying both Certify and Sign capabilities (**[SC]**) | |
| 184 | 183 | - A separate subkey with the Encryption capability (**[E]**) |
| 185 | 184 | |
| 186 | 185 | If you used the default parameters when generating your key, then that |
| @@ -192,9 +191,6 @@ for example:: · 5 unmodified lines | ||
| 192 | 191 | uid [ultimate] Alice Dev <adev@kernel.org> |
| 193 | 192 | ssb rsa2048 2018-01-23 [E] [expires: 2020-01-23] |
| 194 | 193 | |
| 195 | −Any key carrying the **[C]** capability is your master key, regardless | |
| 196 | −of any other capabilities it may have assigned to it. | |
| 197 | − | |
| 198 | 194 | The long line under the ``sec`` entry is your key fingerprint -- |
| 199 | 195 | whenever you see ``[fpr]`` in the examples below, that 40-character |
| 200 | 196 | string is what it refers to. |
| @@ -215,37 +211,30 @@ strong passphrase. To set it or change it, use:: · 14 unmodified lines | ||
| 215 | 211 | Create a separate Signing subkey |
| 216 | 212 | -------------------------------- |
| 217 | 213 | |
| 218 | −Our goal is to protect your master key by moving it to offline media, so | |
| 219 | −if you only have a combined **[SC]** key, then you should create a separate | |
| 220 | −signing subkey:: | |
| 214 | +Our goal is to protect your Certify key by moving it to offline media, | |
| 215 | +so if you only have a combined **[SC]** key, then you should create a | |
| 216 | +separate signing subkey:: | |
| 221 | 217 | |
| 222 | 218 | $ gpg --quick-addkey [fpr] ed25519 sign |
| 223 | 219 | |
| 224 | −Remember to tell the keyservers about this change, so others can pull down | |
| 225 | −your new subkey:: | |
| 226 | − | |
| 227 | − $ gpg --send-key [fpr] | |
| 228 | − | |
| 229 | 220 | .. note:: ECC support in GnuPG |
| 230 | 221 | |
| 231 | 222 | GnuPG 2.1 and later has full support for Elliptic Curve |
| 232 | 223 | Cryptography, with ability to combine ECC subkeys with traditional |
| 233 | − RSA master keys. The main upside of ECC cryptography is that it is | |
| 234 | − much faster computationally and creates much smaller signatures when | |
| 224 | + RSA keys. The main upside of ECC cryptography is that it is much | |
| 225 | + faster computationally and creates much smaller signatures when | |
| 235 | 226 | compared byte for byte with 2048+ bit RSA keys. Unless you plan on |
| 236 | 227 | using a smartcard device that does not support ECC operations, we |
| 237 | 228 | recommend that you create an ECC signing subkey for your kernel |
| 238 | 229 | work. |
| 239 | 230 | |
| 240 | − If for some reason you prefer to stay with RSA subkeys, just replace | |
| 241 | − "ed25519" with "rsa2048" in the above command. Additionally, if you | |
| 242 | − plan to use a hardware device that does not support ED25519 ECC | |
| 243 | − keys, like Nitrokey Pro or a Yubikey, then you should use | |
| 244 | − "nistp256" instead or "ed25519." | |
| 231 | + Note, that if you plan to use a hardware device that does not | |
| 232 | + support ED25519 ECC keys, you should choose "nistp256" instead or | |
| 233 | + "ed25519." | |
| 245 | 234 | |
| 246 | 235 | |
| 247 | −Back up your master key for disaster recovery | |
| 248 | −--------------------------------------------- | |
| 236 | +Back up your Certify key for disaster recovery | |
| 237 | +---------------------------------------------- | |
| 249 | 238 | |
| 250 | 239 | The more signatures you have on your PGP key from other developers, the |
| 251 | 240 | more reasons you have to create a backup version that lives on something |
| @@ -277,9 +266,7 @@ home, such as your bank vault. · 25 unmodified lines | ||
| 277 | 266 | Your printer is probably no longer a simple dumb device connected to |
| 278 | 267 | your parallel port, but since the output is still encrypted with |
| 279 | 268 | your passphrase, printing out even to "cloud-integrated" modern |
| 280 | − printers should remain a relatively safe operation. One option is to | |
| 281 | − change the passphrase on your master key immediately after you are | |
| 282 | − done with paperkey. | |
| 269 | + printers should remain a relatively safe operation. | |
| 283 | 270 | |
| 284 | 271 | Back up your whole GnuPG directory |
| 285 | 272 | ---------------------------------- |
| @@ -300,7 +287,7 @@ will use for backup purposes. You will need to encrypt them using LUKS · 14 unmodified lines | ||
| 300 | 287 | -- refer to your distro's documentation on how to accomplish this. |
| 301 | 288 | |
| 302 | 289 | For the encryption passphrase, you can use the same one as on your |
| 303 | −master key. | |
| 290 | +PGP key. | |
| 304 | 291 | |
| 305 | 292 | Once the encryption process is over, re-insert the USB drive and make |
| 306 | 293 | sure it gets properly mounted. Copy your entire ``.gnupg`` directory |
| @@ -319,7 +306,7 @@ far away, because you'll need to use it every now and again for things · 12 unmodified lines | ||
| 319 | 306 | like editing identities, adding or revoking subkeys, or signing other |
| 320 | 307 | people's keys. |
| 321 | 308 | |
| 322 | −Remove the master key from your homedir | |
| 309 | +Remove the Certify key from your homedir | |
| 323 | 310 | ---------------------------------------- |
| 324 | 311 | |
| 325 | 312 | The files in our home directory are not as well protected as we like to |
| @@ -334,7 +321,7 @@ think. They can be leaked or stolen via many different means: · 8 unmodified lines | ||
| 334 | 321 | Protecting your key with a good passphrase greatly helps reduce the risk |
| 335 | 322 | of any of the above, but passphrases can be discovered via keyloggers, |
| 336 | 323 | shoulder-surfing, or any number of other means. For this reason, the |
| 337 | −recommended setup is to remove your master key from your home directory | |
| 324 | +recommended setup is to remove your Certify key from your home directory | |
| 338 | 325 | and store it on offline storage. |
| 339 | 326 | |
| 340 | 327 | .. warning:: |
| @@ -343,7 +330,7 @@ and store it on offline storage. · 2 unmodified lines | ||
| 343 | 330 | your GnuPG directory in its entirety. What we are about to do will |
| 344 | 331 | render your key useless if you do not have a usable backup! |
| 345 | 332 | |
| 346 | −First, identify the keygrip of your master key:: | |
| 333 | +First, identify the keygrip of your Certify key:: | |
| 347 | 334 | |
| 348 | 335 | $ gpg --with-keygrip --list-key [fpr] |
| 349 | 336 | |
| @@ -359,7 +346,7 @@ The output will be something like this:: · 9 unmodified lines | ||
| 359 | 346 | Keygrip = 3333000000000000000000000000000000000000 |
| 360 | 347 | |
| 361 | 348 | Find the keygrip entry that is beneath the ``pub`` line (right under the |
| 362 | −master key fingerprint). This will correspond directly to a file in your | |
| 349 | +Certify key fingerprint). This will correspond directly to a file in your | |
| 363 | 350 | ``~/.gnupg`` directory:: |
| 364 | 351 | |
| 365 | 352 | $ cd ~/.gnupg/private-keys-v1.d |
| @@ -369,13 +356,13 @@ master key fingerprint). This will correspond directly to a file in your · 3 unmodified lines | ||
| 369 | 356 | 3333000000000000000000000000000000000000.key |
| 370 | 357 | |
| 371 | 358 | All you have to do is simply remove the .key file that corresponds to |
| 372 | −the master keygrip:: | |
| 359 | +the Certify key keygrip:: | |
| 373 | 360 | |
| 374 | 361 | $ cd ~/.gnupg/private-keys-v1.d |
| 375 | 362 | $ rm 1111000000000000000000000000000000000000.key |
| 376 | 363 | |
| 377 | 364 | Now, if you issue the ``--list-secret-keys`` command, it will show that |
| 378 | −the master key is missing (the ``#`` indicates it is not available):: | |
| 365 | +the Certify key is missing (the ``#`` indicates it is not available):: | |
| 379 | 366 | |
| 380 | 367 | $ gpg --list-secret-keys |
| 381 | 368 | sec# rsa2048 2018-01-24 [SC] [expires: 2020-01-24] |
| @@ -404,7 +391,7 @@ file, which still contains your private keys. · 22 unmodified lines | ||
| 404 | 391 | Move the subkeys to a dedicated crypto device |
| 405 | 392 | ============================================= |
| 406 | 393 | |
| 407 | −Even though the master key is now safe from being leaked or stolen, the | |
| 394 | +Even though the Certify key is now safe from being leaked or stolen, the | |
| 408 | 395 | subkeys are still in your home directory. Anyone who manages to get |
| 409 | 396 | their hands on those will be able to decrypt your communication or fake |
| 410 | 397 | your signatures (if they know the passphrase). Furthermore, each time a |
| @@ -447,7 +434,8 @@ functionality. There are several options available: · 36 unmodified lines | ||
| 447 | 434 | - `Yubikey 5`_: proprietary hardware and software, but cheaper than |
| 448 | 435 | Nitrokey Pro and comes available in the USB-C form that is more useful |
| 449 | 436 | with newer laptops. Offers additional security features such as FIDO |
| 450 | − U2F, among others, and now finally supports ECC keys (NISTP). | |
| 437 | + U2F, among others, and now finally supports NISTP and ED25519 ECC | |
| 438 | + keys. | |
| 451 | 439 | |
| 452 | 440 | `LWN has a good review`_ of some of the above models, as well as several |
| 453 | 441 | others. Your choice will depend on cost, shipping availability in your |
| @@ -460,7 +448,7 @@ geographical region, and open/proprietary hardware considerations. · 6 unmodified lines | ||
| 460 | 448 | Foundation. |
| 461 | 449 | |
| 462 | 450 | .. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6 |
| 463 | −.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nitrokey-pro-2-3 | |
| 451 | +.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3 | |
| 464 | 452 | .. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/ |
| 465 | 453 | .. _Gnuk: https://www.fsij.org/doc-gnuk/ |
| 466 | 454 | .. _`LWN has a good review`: https://lwn.net/Articles/736231/ |
| @@ -627,10 +615,10 @@ Other common GnuPG operations · 160 unmodified lines | ||
| 627 | 615 | Here is a quick reference for some common operations you'll need to do |
| 628 | 616 | with your PGP key. |
| 629 | 617 | |
| 630 | −Mounting your master key offline storage | |
| 631 | −~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 618 | +Mounting your safe offline storage | |
| 619 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 632 | 620 | |
| 633 | −You will need your master key for any of the operations below, so you | |
| 621 | +You will need your Certify key for any of the operations below, so you | |
| 634 | 622 | will first need to mount your backup offline storage and tell GnuPG to |
| 635 | 623 | use it:: |
| 636 | 624 | |
| @@ -644,7 +632,7 @@ your regular home directory location). · 7 unmodified lines | ||
| 644 | 632 | Extending key expiration date |
| 645 | 633 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 646 | 634 | |
| 647 | −The master key has the default expiration date of 2 years from the date | |
| 635 | +The Certify key has the default expiration date of 2 years from the date | |
| 648 | 636 | of creation. This is done both for security reasons and to make obsolete |
| 649 | 637 | keys eventually disappear from keyservers. |
| 650 | 638 | |
| @@ -685,6 +673,7 @@ remote end. · 34 unmodified lines | ||
| 685 | 673 | |
| 686 | 674 | .. _`Agent Forwarding over SSH`: https://wiki.gnupg.org/AgentForwarding |
| 687 | 675 | |
| 676 | +.. _pgp_with_git: | |
| 688 | 677 | |
| 689 | 678 | Using PGP with Git |
| 690 | 679 | ================== |
| @@ -828,6 +817,63 @@ You can tell git to always sign commits:: · 137 unmodified lines | ||
| 828 | 817 | |
| 829 | 818 | .. _verify_identities: |
| 830 | 819 | |
| 820 | + | |
| 821 | +How to work with signed patches | |
| 822 | +------------------------------- | |
| 823 | + | |
| 824 | +It is possible to use your PGP key to sign patches sent to kernel | |
| 825 | +developer mailing lists. Since existing email signature mechanisms | |
| 826 | +(PGP-Mime or PGP-inline) tend to cause problems with regular code | |
| 827 | +review tasks, you should use the tool kernel.org created for this | |
| 828 | +purpose that puts cryptographic attestation signatures into message | |
| 829 | +headers (a-la DKIM): | |
| 830 | + | |
| 831 | +- `Patatt Patch Attestation`_ | |
| 832 | + | |
| 833 | +.. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/ | |
| 834 | + | |
| 835 | +Installing and configuring patatt | |
| 836 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 837 | + | |
| 838 | +Patatt is packaged for many distributions already, so please check there | |
| 839 | +first. You can also install it from pypi using "``pip install patatt``". | |
| 840 | + | |
| 841 | +If you already have your PGP key configured with git (via the | |
| 842 | +``user.signingKey`` configuration parameter), then patatt requires no | |
| 843 | +further configuration. You can start signing your patches by installing | |
| 844 | +the git-send-email hook in the repository you want:: | |
| 845 | + | |
| 846 | + patatt install-hook | |
| 847 | + | |
| 848 | +Now any patches you send with ``git send-email`` will be automatically | |
| 849 | +signed with your cryptographic signature. | |
| 850 | + | |
| 851 | +Checking patatt signatures | |
| 852 | +~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 853 | + | |
| 854 | +If you are using ``b4`` to retrieve and apply patches, then it will | |
| 855 | +automatically attempt to verify all DKIM and patatt signatures it | |
| 856 | +encounters, for example:: | |
| 857 | + | |
| 858 | + $ b4 am 20220720205013.890942-1-broonie@kernel.org | |
| 859 | + [...] | |
| 860 | + Checking attestation on all messages, may take a moment... | |
| 861 | + --- | |
| 862 | + ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers | |
| 863 | + ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall | |
| 864 | + ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls | |
| 865 | + --- | |
| 866 | + ✓ Signed: openpgp/broonie@kernel.org | |
| 867 | + ✓ Signed: DKIM/kernel.org | |
| 868 | + | |
| 869 | +.. note:: | |
| 870 | + | |
| 871 | + Patatt and b4 are still in active development and you should check | |
| 872 | + the latest documentation for these projects for any new or updated | |
| 873 | + features. | |
| 874 | + | |
| 875 | +.. _kernel_identities: | |
| 876 | + | |
| 831 | 877 | How to verify kernel developer identities |
| 832 | 878 | ========================================= |
| 833 | 879 | |
| @@ -899,65 +945,17 @@ the new default in GnuPG v2). To set it, add (or modify) the · 65 unmodified lines | ||
| 899 | 945 | |
| 900 | 946 | trust-model tofu+pgp |
| 901 | 947 | |
| 902 | −How to use keyservers (more) safely | |
| 903 | −----------------------------------- | |
| 904 | − | |
| 905 | −If you get a "No public key" error when trying to validate someone's | |
| 906 | −tag, then you should attempt to lookup that key using a keyserver. It is | |
| 907 | −important to keep in mind that there is absolutely no guarantee that the | |
| 908 | −key you retrieve from PGP keyservers belongs to the actual person -- | |
| 909 | −that much is by design. You are supposed to use the Web of Trust to | |
| 910 | −establish key validity. | |
| 911 | − | |
| 912 | −How to properly maintain the Web of Trust is beyond the scope of this | |
| 913 | −document, simply because doing it properly requires both effort and | |
| 914 | −dedication that tends to be beyond the caring threshold of most human | |
| 915 | −beings. Here are some shortcuts that will help you reduce the risk of | |
| 916 | −importing a malicious key. | |
| 917 | − | |
| 918 | −First, let's say you've tried to run ``git verify-tag`` but it returned | |
| 919 | −an error saying the key is not found:: | |
| 920 | − | |
| 921 | − $ git verify-tag sunxi-fixes-for-4.15-2 | |
| 922 | − gpg: Signature made Sun 07 Jan 2018 10:51:55 PM EST | |
| 923 | − gpg: using RSA key DA73759BF8619E484E5A3B47389A54219C0F2430 | |
| 924 | − gpg: issuer "wens@...org" | |
| 925 | − gpg: Can't check signature: No public key | |
| 926 | − | |
| 927 | −Let's query the keyserver for more info about that key fingerprint (the | |
| 928 | −fingerprint probably belongs to a subkey, so we can't use it directly | |
| 929 | −without finding out the ID of the master key it is associated with):: | |
| 930 | − | |
| 931 | − $ gpg --search DA73759BF8619E484E5A3B47389A54219C0F2430 | |
| 932 | − gpg: data source: hkp://keys.gnupg.net | |
| 933 | − (1) Chen-Yu Tsai <wens@...org> | |
| 934 | − 4096 bit RSA key C94035C21B4F2AEB, created: 2017-03-14, expires: 2019-03-15 | |
| 935 | − Keys 1-1 of 1 for "DA73759BF8619E484E5A3B47389A54219C0F2430". Enter number(s), N)ext, or Q)uit > q | |
| 936 | − | |
| 937 | −Locate the ID of the master key in the output, in our example | |
| 938 | −``C94035C21B4F2AEB``. Now display the key of Linus Torvalds that you | |
| 939 | −have on your keyring:: | |
| 940 | − | |
| 941 | − $ gpg --list-key torvalds@kernel.org | |
| 942 | − pub rsa2048 2011-09-20 [SC] | |
| 943 | − ABAF11C65A2970B130ABE3C479BE3E4300411886 | |
| 944 | − uid [ unknown] Linus Torvalds <torvalds@kernel.org> | |
| 945 | − sub rsa2048 2011-09-20 [E] | |
| 946 | − | |
| 947 | −Next, find a trust path from Linus Torvalds to the key-id you found via ``gpg | |
| 948 | −--search`` of the unknown key. For this, you can use several tools including | |
| 949 | −https://github.com/mricon/wotmate, | |
| 950 | −https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/tree/graphs, and | |
| 951 | −https://the.earth.li/~noodles/pathfind.html. | |
| 952 | − | |
| 953 | −If you get a few decent trust paths, then it's a pretty good indication | |
| 954 | −that it is a valid key. You can add it to your keyring from the | |
| 955 | −keyserver now:: | |
| 956 | − | |
| 957 | − $ gpg --recv-key C94035C21B4F2AEB | |
| 958 | − | |
| 959 | −This process is not perfect, and you are obviously trusting the | |
| 960 | −administrators of the PGP Pathfinder service to not be malicious (in | |
| 961 | −fact, this goes against :ref:`devs_not_infra`). However, if you | |
| 962 | −do not carefully maintain your own web of trust, then it is a marked | |
| 963 | −improvement over blindly trusting keyservers. | |
| 948 | +Using the kernel.org web of trust repository | |
| 949 | +-------------------------------------------- | |
| 950 | + | |
| 951 | +Kernel.org maintains a git repository with developers' public keys as a | |
| 952 | +replacement for replicating keyserver networks that have gone mostly | |
| 953 | +dark in the past few years. The full documentation for how to set up | |
| 954 | +that repository as your source of public keys can be found here: | |
| 955 | + | |
| 956 | +- `Kernel developer PGP Keyring`_ | |
| 957 | + | |
| 958 | +If you are a kernel developer, please consider submitting your key for | |
| 959 | +inclusion into that keyring. | |
| 960 | + | |
| 961 | +.. _`Kernel developer PGP Keyring`: https://korg.docs.kernel.org/pgpkeys.html | |
| @@ -97,6 +97,12 @@ text, like this: · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | commit <sha1> upstream. |
| 99 | 99 | |
| 100 | +or alternatively: | |
| 101 | + | |
| 102 | +.. code-block:: none | |
| 103 | + | |
| 104 | + [ Upstream commit <sha1> ] | |
| 105 | + | |
| 100 | 106 | Additionally, some patches submitted via :ref:`option_1` may have additional |
| 101 | 107 | patch prerequisites which can be cherry-picked. This can be specified in the |
| 102 | 108 | following format in the sign-off area: |
| @@ -715,8 +715,8 @@ references. · 714 unmodified lines | ||
| 715 | 715 | |
| 716 | 716 | .. _backtraces: |
| 717 | 717 | |
| 718 | −Backtraces in commit mesages | |
| 719 | −^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 718 | +Backtraces in commit messages | |
| 719 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 720 | 720 | |
| 721 | 721 | Backtraces help document the call chain leading to a problem. However, |
| 722 | 722 | not all backtraces are helpful. For example, early boot call chains are |
| @@ -0,0 +1,19 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +Arch Support | |
| 4 | +============ | |
| 5 | + | |
| 6 | +Currently, the Rust compiler (``rustc``) uses LLVM for code generation, | |
| 7 | +which limits the supported architectures that can be targeted. In addition, | |
| 8 | +support for building the kernel with LLVM/Clang varies (please see | |
| 9 | +Documentation/kbuild/llvm.rst). This support is needed for ``bindgen`` | |
| 10 | +which uses ``libclang``. | |
| 11 | + | |
| 12 | +Below is a general summary of architectures that currently work. Level of | |
| 13 | +support corresponds to ``S`` values in the ``MAINTAINERS`` file. | |
| 14 | + | |
| 15 | +============ ================ ============================================== | |
| 16 | +Architecture Level of support Constraints | |
| 17 | +============ ================ ============================================== | |
| 18 | +``x86`` Maintained ``x86_64`` only. | |
| 19 | +============ ================ ============================================== | |
| @@ -0,0 +1,216 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +Coding Guidelines | |
| 4 | +================= | |
| 5 | + | |
| 6 | +This document describes how to write Rust code in the kernel. | |
| 7 | + | |
| 8 | + | |
| 9 | +Style & formatting | |
| 10 | +------------------ | |
| 11 | + | |
| 12 | +The code should be formatted using ``rustfmt``. In this way, a person | |
| 13 | +contributing from time to time to the kernel does not need to learn and | |
| 14 | +remember one more style guide. More importantly, reviewers and maintainers | |
| 15 | +do not need to spend time pointing out style issues anymore, and thus | |
| 16 | +less patch roundtrips may be needed to land a change. | |
| 17 | + | |
| 18 | +.. note:: Conventions on comments and documentation are not checked by | |
| 19 | + ``rustfmt``. Thus those are still needed to be taken care of. | |
| 20 | + | |
| 21 | +The default settings of ``rustfmt`` are used. This means the idiomatic Rust | |
| 22 | +style is followed. For instance, 4 spaces are used for indentation rather | |
| 23 | +than tabs. | |
| 24 | + | |
| 25 | +It is convenient to instruct editors/IDEs to format while typing, | |
| 26 | +when saving or at commit time. However, if for some reason reformatting | |
| 27 | +the entire kernel Rust sources is needed at some point, the following can be | |
| 28 | +run:: | |
| 29 | + | |
| 30 | + make LLVM=1 rustfmt | |
| 31 | + | |
| 32 | +It is also possible to check if everything is formatted (printing a diff | |
| 33 | +otherwise), for instance for a CI, with:: | |
| 34 | + | |
| 35 | + make LLVM=1 rustfmtcheck | |
| 36 | + | |
| 37 | +Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on | |
| 38 | +individual files, and does not require a kernel configuration. Sometimes it may | |
| 39 | +even work with broken code. | |
| 40 | + | |
| 41 | + | |
| 42 | +Comments | |
| 43 | +-------- | |
| 44 | + | |
| 45 | +"Normal" comments (i.e. ``//``, rather than code documentation which starts | |
| 46 | +with ``///`` or ``//!``) are written in Markdown the same way as documentation | |
| 47 | +comments are, even though they will not be rendered. This improves consistency, | |
| 48 | +simplifies the rules and allows to move content between the two kinds of | |
| 49 | +comments more easily. For instance: | |
| 50 | + | |
| 51 | +.. code-block:: rust | |
| 52 | + | |
| 53 | + // `object` is ready to be handled now. | |
| 54 | + f(object); | |
| 55 | + | |
| 56 | +Furthermore, just like documentation, comments are capitalized at the beginning | |
| 57 | +of a sentence and ended with a period (even if it is a single sentence). This | |
| 58 | +includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.: | |
| 59 | + | |
| 60 | +.. code-block:: rust | |
| 61 | + | |
| 62 | + // FIXME: The error should be handled properly. | |
| 63 | + | |
| 64 | +Comments should not be used for documentation purposes: comments are intended | |
| 65 | +for implementation details, not users. This distinction is useful even if the | |
| 66 | +reader of the source file is both an implementor and a user of an API. In fact, | |
| 67 | +sometimes it is useful to use both comments and documentation at the same time. | |
| 68 | +For instance, for a ``TODO`` list or to comment on the documentation itself. | |
| 69 | +For the latter case, comments can be inserted in the middle; that is, closer to | |
| 70 | +the line of documentation to be commented. For any other case, comments are | |
| 71 | +written after the documentation, e.g.: | |
| 72 | + | |
| 73 | +.. code-block:: rust | |
| 74 | + | |
| 75 | + /// Returns a new [`Foo`]. | |
| 76 | + /// | |
| 77 | + /// # Examples | |
| 78 | + /// | |
| 79 | + // TODO: Find a better example. | |
| 80 | + /// ``` | |
| 81 | + /// let foo = f(42); | |
| 82 | + /// ``` | |
| 83 | + // FIXME: Use fallible approach. | |
| 84 | + pub fn f(x: i32) -> Foo { | |
| 85 | + // ... | |
| 86 | + } | |
| 87 | + | |
| 88 | +One special kind of comments are the ``// SAFETY:`` comments. These must appear | |
| 89 | +before every ``unsafe`` block, and they explain why the code inside the block is | |
| 90 | +correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.: | |
| 91 | + | |
| 92 | +.. code-block:: rust | |
| 93 | + | |
| 94 | + // SAFETY: `p` is valid by the safety requirements. | |
| 95 | + unsafe { *p = 0; } | |
| 96 | + | |
| 97 | +``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections | |
| 98 | +in code documentation. ``# Safety`` sections specify the contract that callers | |
| 99 | +(for functions) or implementors (for traits) need to abide by. ``// SAFETY:`` | |
| 100 | +comments show why a call (for functions) or implementation (for traits) actually | |
| 101 | +respects the preconditions stated in a ``# Safety`` section or the language | |
| 102 | +reference. | |
| 103 | + | |
| 104 | + | |
| 105 | +Code documentation | |
| 106 | +------------------ | |
| 107 | + | |
| 108 | +Rust kernel code is not documented like C kernel code (i.e. via kernel-doc). | |
| 109 | +Instead, the usual system for documenting Rust code is used: the ``rustdoc`` | |
| 110 | +tool, which uses Markdown (a lightweight markup language). | |
| 111 | + | |
| 112 | +To learn Markdown, there are many guides available out there. For instance, | |
| 113 | +the one at: | |
| 114 | + | |
| 115 | + https://commonmark.org/help/ | |
| 116 | + | |
| 117 | +This is how a well-documented Rust function may look like: | |
| 118 | + | |
| 119 | +.. code-block:: rust | |
| 120 | + | |
| 121 | + /// Returns the contained [`Some`] value, consuming the `self` value, | |
| 122 | + /// without checking that the value is not [`None`]. | |
| 123 | + /// | |
| 124 | + /// # Safety | |
| 125 | + /// | |
| 126 | + /// Calling this method on [`None`] is *[undefined behavior]*. | |
| 127 | + /// | |
| 128 | + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html | |
| 129 | + /// | |
| 130 | + /// # Examples | |
| 131 | + /// | |
| 132 | + /// ``` | |
| 133 | + /// let x = Some("air"); | |
| 134 | + /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); | |
| 135 | + /// ``` | |
| 136 | + pub unsafe fn unwrap_unchecked(self) -> T { | |
| 137 | + match self { | |
| 138 | + Some(val) => val, | |
| 139 | + | |
| 140 | + // SAFETY: The safety contract must be upheld by the caller. | |
| 141 | + None => unsafe { hint::unreachable_unchecked() }, | |
| 142 | + } | |
| 143 | + } | |
| 144 | + | |
| 145 | +This example showcases a few ``rustdoc`` features and some conventions followed | |
| 146 | +in the kernel: | |
| 147 | + | |
| 148 | + - The first paragraph must be a single sentence briefly describing what | |
| 149 | + the documented item does. Further explanations must go in extra paragraphs. | |
| 150 | + | |
| 151 | + - Unsafe functions must document their safety preconditions under | |
| 152 | + a ``# Safety`` section. | |
| 153 | + | |
| 154 | + - While not shown here, if a function may panic, the conditions under which | |
| 155 | + that happens must be described under a ``# Panics`` section. | |
| 156 | + | |
| 157 | + Please note that panicking should be very rare and used only with a good | |
| 158 | + reason. In almost all cases, a fallible approach should be used, typically | |
| 159 | + returning a ``Result``. | |
| 160 | + | |
| 161 | + - If providing examples of usage would help readers, they must be written in | |
| 162 | + a section called ``# Examples``. | |
| 163 | + | |
| 164 | + - Rust items (functions, types, constants...) must be linked appropriately | |
| 165 | + (``rustdoc`` will create a link automatically). | |
| 166 | + | |
| 167 | + - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment | |
| 168 | + describing why the code inside is sound. | |
| 169 | + | |
| 170 | + While sometimes the reason might look trivial and therefore unneeded, | |
| 171 | + writing these comments is not just a good way of documenting what has been | |
| 172 | + taken into account, but most importantly, it provides a way to know that | |
| 173 | + there are no *extra* implicit constraints. | |
| 174 | + | |
| 175 | +To learn more about how to write documentation for Rust and extra features, | |
| 176 | +please take a look at the ``rustdoc`` book at: | |
| 177 | + | |
| 178 | + https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html | |
| 179 | + | |
| 180 | + | |
| 181 | +Naming | |
| 182 | +------ | |
| 183 | + | |
| 184 | +Rust kernel code follows the usual Rust naming conventions: | |
| 185 | + | |
| 186 | + https://rust-lang.github.io/api-guidelines/naming.html | |
| 187 | + | |
| 188 | +When existing C concepts (e.g. macros, functions, objects...) are wrapped into | |
| 189 | +a Rust abstraction, a name as close as reasonably possible to the C side should | |
| 190 | +be used in order to avoid confusion and to improve readability when switching | |
| 191 | +back and forth between the C and Rust sides. For instance, macros such as | |
| 192 | +``pr_info`` from C are named the same in the Rust side. | |
| 193 | + | |
| 194 | +Having said that, casing should be adjusted to follow the Rust naming | |
| 195 | +conventions, and namespacing introduced by modules and types should not be | |
| 196 | +repeated in the item names. For instance, when wrapping constants like: | |
| 197 | + | |
| 198 | +.. code-block:: c | |
| 199 | + | |
| 200 | + #define GPIO_LINE_DIRECTION_IN 0 | |
| 201 | + #define GPIO_LINE_DIRECTION_OUT 1 | |
| 202 | + | |
| 203 | +The equivalent in Rust may look like (ignoring documentation): | |
| 204 | + | |
| 205 | +.. code-block:: rust | |
| 206 | + | |
| 207 | + pub mod gpio { | |
| 208 | + pub enum LineDirection { | |
| 209 | + In = bindings::GPIO_LINE_DIRECTION_IN as _, | |
| 210 | + Out = bindings::GPIO_LINE_DIRECTION_OUT as _, | |
| 211 | + } | |
| 212 | + } | |
| 213 | + | |
| 214 | +That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as | |
| 215 | +``gpio::LineDirection::In``. In particular, it should not be named | |
| 216 | +``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``. | |
| @@ -0,0 +1,79 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +General Information | |
| 4 | +=================== | |
| 5 | + | |
| 6 | +This document contains useful information to know when working with | |
| 7 | +the Rust support in the kernel. | |
| 8 | + | |
| 9 | + | |
| 10 | +Code documentation | |
| 11 | +------------------ | |
| 12 | + | |
| 13 | +Rust kernel code is documented using ``rustdoc``, its built-in documentation | |
| 14 | +generator. | |
| 15 | + | |
| 16 | +The generated HTML docs include integrated search, linked items (e.g. types, | |
| 17 | +functions, constants), source code, etc. They may be read at (TODO: link when | |
| 18 | +in mainline and generated alongside the rest of the documentation): | |
| 19 | + | |
| 20 | + http://kernel.org/ | |
| 21 | + | |
| 22 | +The docs can also be easily generated and read locally. This is quite fast | |
| 23 | +(same order as compiling the code itself) and no special tools or environment | |
| 24 | +are needed. This has the added advantage that they will be tailored to | |
| 25 | +the particular kernel configuration used. To generate them, use the ``rustdoc`` | |
| 26 | +target with the same invocation used for compilation, e.g.:: | |
| 27 | + | |
| 28 | + make LLVM=1 rustdoc | |
| 29 | + | |
| 30 | +To read the docs locally in your web browser, run e.g.:: | |
| 31 | + | |
| 32 | + xdg-open rust/doc/kernel/index.html | |
| 33 | + | |
| 34 | +To learn about how to write the documentation, please see coding-guidelines.rst. | |
| 35 | + | |
| 36 | + | |
| 37 | +Extra lints | |
| 38 | +----------- | |
| 39 | + | |
| 40 | +While ``rustc`` is a very helpful compiler, some extra lints and analyses are | |
| 41 | +available via ``clippy``, a Rust linter. To enable it, pass ``CLIPPY=1`` to | |
| 42 | +the same invocation used for compilation, e.g.:: | |
| 43 | + | |
| 44 | + make LLVM=1 CLIPPY=1 | |
| 45 | + | |
| 46 | +Please note that Clippy may change code generation, thus it should not be | |
| 47 | +enabled while building a production kernel. | |
| 48 | + | |
| 49 | + | |
| 50 | +Abstractions vs. bindings | |
| 51 | +------------------------- | |
| 52 | + | |
| 53 | +Abstractions are Rust code wrapping kernel functionality from the C side. | |
| 54 | + | |
| 55 | +In order to use functions and types from the C side, bindings are created. | |
| 56 | +Bindings are the declarations for Rust of those functions and types from | |
| 57 | +the C side. | |
| 58 | + | |
| 59 | +For instance, one may write a ``Mutex`` abstraction in Rust which wraps | |
| 60 | +a ``struct mutex`` from the C side and calls its functions through the bindings. | |
| 61 | + | |
| 62 | +Abstractions are not available for all the kernel internal APIs and concepts, | |
| 63 | +but it is intended that coverage is expanded as time goes on. "Leaf" modules | |
| 64 | +(e.g. drivers) should not use the C bindings directly. Instead, subsystems | |
| 65 | +should provide as-safe-as-possible abstractions as needed. | |
| 66 | + | |
| 67 | + | |
| 68 | +Conditional compilation | |
| 69 | +----------------------- | |
| 70 | + | |
| 71 | +Rust code has access to conditional compilation based on the kernel | |
| 72 | +configuration: | |
| 73 | + | |
| 74 | +.. code-block:: rust | |
| 75 | + | |
| 76 | + #[cfg(CONFIG_X)] // Enabled (`y` or `m`) | |
| 77 | + #[cfg(CONFIG_X="y")] // Enabled as a built-in (`y`) | |
| 78 | + #[cfg(CONFIG_X="m")] // Enabled as a module (`m`) | |
| 79 | + #[cfg(not(CONFIG_X))] // Disabled | |
| @@ -0,0 +1,22 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +Rust | |
| 4 | +==== | |
| 5 | + | |
| 6 | +Documentation related to Rust within the kernel. To start using Rust | |
| 7 | +in the kernel, please read the quick-start.rst guide. | |
| 8 | + | |
| 9 | +.. toctree:: | |
| 10 | + :maxdepth: 1 | |
| 11 | + | |
| 12 | + quick-start | |
| 13 | + general-information | |
| 14 | + coding-guidelines | |
| 15 | + arch-support | |
| 16 | + | |
| 17 | +.. only:: subproject and html | |
| 18 | + | |
| 19 | + Indices | |
| 20 | + ======= | |
| 21 | + | |
| 22 | + * :ref:`genindex` | |
| @@ -0,0 +1,232 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +Quick Start | |
| 4 | +=========== | |
| 5 | + | |
| 6 | +This document describes how to get started with kernel development in Rust. | |
| 7 | + | |
| 8 | + | |
| 9 | +Requirements: Building | |
| 10 | +---------------------- | |
| 11 | + | |
| 12 | +This section explains how to fetch the tools needed for building. | |
| 13 | + | |
| 14 | +Some of these requirements might be available from Linux distributions | |
| 15 | +under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However, | |
| 16 | +at the time of writing, they are likely not to be recent enough unless | |
| 17 | +the distribution tracks the latest releases. | |
| 18 | + | |
| 19 | +To easily check whether the requirements are met, the following target | |
| 20 | +can be used:: | |
| 21 | + | |
| 22 | + make LLVM=1 rustavailable | |
| 23 | + | |
| 24 | +This triggers the same logic used by Kconfig to determine whether | |
| 25 | +``RUST_IS_AVAILABLE`` should be enabled; but it also explains why not | |
| 26 | +if that is the case. | |
| 27 | + | |
| 28 | + | |
| 29 | +rustc | |
| 30 | +***** | |
| 31 | + | |
| 32 | +A particular version of the Rust compiler is required. Newer versions may or | |
| 33 | +may not work because, for the moment, the kernel depends on some unstable | |
| 34 | +Rust features. | |
| 35 | + | |
| 36 | +If ``rustup`` is being used, enter the checked out source code directory | |
| 37 | +and run:: | |
| 38 | + | |
| 39 | + rustup override set $(scripts/min-tool-version.sh rustc) | |
| 40 | + | |
| 41 | +Otherwise, fetch a standalone installer or install ``rustup`` from: | |
| 42 | + | |
| 43 | + https://www.rust-lang.org | |
| 44 | + | |
| 45 | + | |
| 46 | +Rust standard library source | |
| 47 | +**************************** | |
| 48 | + | |
| 49 | +The Rust standard library source is required because the build system will | |
| 50 | +cross-compile ``core`` and ``alloc``. | |
| 51 | + | |
| 52 | +If ``rustup`` is being used, run:: | |
| 53 | + | |
| 54 | + rustup component add rust-src | |
| 55 | + | |
| 56 | +The components are installed per toolchain, thus upgrading the Rust compiler | |
| 57 | +version later on requires re-adding the component. | |
| 58 | + | |
| 59 | +Otherwise, if a standalone installer is used, the Rust repository may be cloned | |
| 60 | +into the installation folder of the toolchain:: | |
| 61 | + | |
| 62 | + git clone --recurse-submodules \ | |
| 63 | + --branch $(scripts/min-tool-version.sh rustc) \ | |
| 64 | + https://github.com/rust-lang/rust \ | |
| 65 | + $(rustc --print sysroot)/lib/rustlib/src/rust | |
| 66 | + | |
| 67 | +In this case, upgrading the Rust compiler version later on requires manually | |
| 68 | +updating this clone. | |
| 69 | + | |
| 70 | + | |
| 71 | +libclang | |
| 72 | +******** | |
| 73 | + | |
| 74 | +``libclang`` (part of LLVM) is used by ``bindgen`` to understand the C code | |
| 75 | +in the kernel, which means LLVM needs to be installed; like when the kernel | |
| 76 | +is compiled with ``CC=clang`` or ``LLVM=1``. | |
| 77 | + | |
| 78 | +Linux distributions are likely to have a suitable one available, so it is | |
| 79 | +best to check that first. | |
| 80 | + | |
| 81 | +There are also some binaries for several systems and architectures uploaded at: | |
| 82 | + | |
| 83 | + https://releases.llvm.org/download.html | |
| 84 | + | |
| 85 | +Otherwise, building LLVM takes quite a while, but it is not a complex process: | |
| 86 | + | |
| 87 | + https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm | |
| 88 | + | |
| 89 | +Please see Documentation/kbuild/llvm.rst for more information and further ways | |
| 90 | +to fetch pre-built releases and distribution packages. | |
| 91 | + | |
| 92 | + | |
| 93 | +bindgen | |
| 94 | +******* | |
| 95 | + | |
| 96 | +The bindings to the C side of the kernel are generated at build time using | |
| 97 | +the ``bindgen`` tool. A particular version is required. | |
| 98 | + | |
| 99 | +Install it via (note that this will download and build the tool from source):: | |
| 100 | + | |
| 101 | + cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen | |
| 102 | + | |
| 103 | + | |
| 104 | +Requirements: Developing | |
| 105 | +------------------------ | |
| 106 | + | |
| 107 | +This section explains how to fetch the tools needed for developing. That is, | |
| 108 | +they are not needed when just building the kernel. | |
| 109 | + | |
| 110 | + | |
| 111 | +rustfmt | |
| 112 | +******* | |
| 113 | + | |
| 114 | +The ``rustfmt`` tool is used to automatically format all the Rust kernel code, | |
| 115 | +including the generated C bindings (for details, please see | |
| 116 | +coding-guidelines.rst). | |
| 117 | + | |
| 118 | +If ``rustup`` is being used, its ``default`` profile already installs the tool, | |
| 119 | +thus nothing needs to be done. If another profile is being used, the component | |
| 120 | +can be installed manually:: | |
| 121 | + | |
| 122 | + rustup component add rustfmt | |
| 123 | + | |
| 124 | +The standalone installers also come with ``rustfmt``. | |
| 125 | + | |
| 126 | + | |
| 127 | +clippy | |
| 128 | +****** | |
| 129 | + | |
| 130 | +``clippy`` is a Rust linter. Running it provides extra warnings for Rust code. | |
| 131 | +It can be run by passing ``CLIPPY=1`` to ``make`` (for details, please see | |
| 132 | +general-information.rst). | |
| 133 | + | |
| 134 | +If ``rustup`` is being used, its ``default`` profile already installs the tool, | |
| 135 | +thus nothing needs to be done. If another profile is being used, the component | |
| 136 | +can be installed manually:: | |
| 137 | + | |
| 138 | + rustup component add clippy | |
| 139 | + | |
| 140 | +The standalone installers also come with ``clippy``. | |
| 141 | + | |
| 142 | + | |
| 143 | +cargo | |
| 144 | +***** | |
| 145 | + | |
| 146 | +``cargo`` is the Rust native build system. It is currently required to run | |
| 147 | +the tests since it is used to build a custom standard library that contains | |
| 148 | +the facilities provided by the custom ``alloc`` in the kernel. The tests can | |
| 149 | +be run using the ``rusttest`` Make target. | |
| 150 | + | |
| 151 | +If ``rustup`` is being used, all the profiles already install the tool, | |
| 152 | +thus nothing needs to be done. | |
| 153 | + | |
| 154 | +The standalone installers also come with ``cargo``. | |
| 155 | + | |
| 156 | + | |
| 157 | +rustdoc | |
| 158 | +******* | |
| 159 | + | |
| 160 | +``rustdoc`` is the documentation tool for Rust. It generates pretty HTML | |
| 161 | +documentation for Rust code (for details, please see | |
| 162 | +general-information.rst). | |
| 163 | + | |
| 164 | +``rustdoc`` is also used to test the examples provided in documented Rust code | |
| 165 | +(called doctests or documentation tests). The ``rusttest`` Make target uses | |
| 166 | +this feature. | |
| 167 | + | |
| 168 | +If ``rustup`` is being used, all the profiles already install the tool, | |
| 169 | +thus nothing needs to be done. | |
| 170 | + | |
| 171 | +The standalone installers also come with ``rustdoc``. | |
| 172 | + | |
| 173 | + | |
| 174 | +rust-analyzer | |
| 175 | +************* | |
| 176 | + | |
| 177 | +The `rust-analyzer <https://rust-analyzer.github.io/>`_ language server can | |
| 178 | +be used with many editors to enable syntax highlighting, completion, go to | |
| 179 | +definition, and other features. | |
| 180 | + | |
| 181 | +``rust-analyzer`` needs a configuration file, ``rust-project.json``, which | |
| 182 | +can be generated by the ``rust-analyzer`` Make target. | |
| 183 | + | |
| 184 | + | |
| 185 | +Configuration | |
| 186 | +------------- | |
| 187 | + | |
| 188 | +``Rust support`` (``CONFIG_RUST``) needs to be enabled in the ``General setup`` | |
| 189 | +menu. The option is only shown if a suitable Rust toolchain is found (see | |
| 190 | +above), as long as the other requirements are met. In turn, this will make | |
| 191 | +visible the rest of options that depend on Rust. | |
| 192 | + | |
| 193 | +Afterwards, go to:: | |
| 194 | + | |
| 195 | + Kernel hacking | |
| 196 | + -> Sample kernel code | |
| 197 | + -> Rust samples | |
| 198 | + | |
| 199 | +And enable some sample modules either as built-in or as loadable. | |
| 200 | + | |
| 201 | + | |
| 202 | +Building | |
| 203 | +-------- | |
| 204 | + | |
| 205 | +Building a kernel with a complete LLVM toolchain is the best supported setup | |
| 206 | +at the moment. That is:: | |
| 207 | + | |
| 208 | + make LLVM=1 | |
| 209 | + | |
| 210 | +For architectures that do not support a full LLVM toolchain, use:: | |
| 211 | + | |
| 212 | + make CC=clang | |
| 213 | + | |
| 214 | +Using GCC also works for some configurations, but it is very experimental at | |
| 215 | +the moment. | |
| 216 | + | |
| 217 | + | |
| 218 | +Hacking | |
| 219 | +------- | |
| 220 | + | |
| 221 | +To dive deeper, take a look at the source code of the samples | |
| 222 | +at ``samples/rust/``, the Rust support code under ``rust/`` and | |
| 223 | +the ``Rust hacking`` menu under ``Kernel hacking``. | |
| 224 | + | |
| 225 | +If GDB/Binutils is used and Rust symbols are not getting demangled, the reason | |
| 226 | +is the toolchain does not support Rust's new v0 mangling scheme yet. | |
| 227 | +There are a few ways out: | |
| 228 | + | |
| 229 | + - Install a newer release (GDB >= 10.2, Binutils >= 2.36). | |
| 230 | + | |
| 231 | + - Some versions of GDB (e.g. vanilla GDB 10.1) are able to use | |
| 232 | + the pre-demangled names embedded in the debug info (``CONFIG_DEBUG_INFO``). | |
| @@ -94,7 +94,7 @@ other HZ detail. Thus the CFS scheduler has no notion of "timeslices" in the · 93 unmodified lines | ||
| 94 | 94 | way the previous scheduler had, and has no heuristics whatsoever. There is |
| 95 | 95 | only one central tunable (you have to switch on CONFIG_SCHED_DEBUG): |
| 96 | 96 | |
| 97 | − /proc/sys/kernel/sched_min_granularity_ns | |
| 97 | + /sys/kernel/debug/sched/min_granularity_ns | |
| 98 | 98 | |
| 99 | 99 | which can be used to tune the scheduler from "desktop" (i.e., low latencies) to |
| 100 | 100 | "server" (i.e., good batching) workloads. It defaults to a setting suitable |
| @@ -7,7 +7,7 @@ Landlock LSM: kernel documentation · 6 unmodified lines | ||
| 7 | 7 | ================================== |
| 8 | 8 | |
| 9 | 9 | :Author: Mickaël Salaün |
| 10 | −:Date: May 2022 | |
| 10 | +:Date: September 2022 | |
| 11 | 11 | |
| 12 | 12 | Landlock's goal is to create scoped access-control (i.e. sandboxing). To |
| 13 | 13 | harden a whole system, this feature should be available to any process, |
| @@ -49,13 +49,13 @@ Filesystem access rights · 35 unmodified lines | ||
| 49 | 49 | ------------------------ |
| 50 | 50 | |
| 51 | 51 | All access rights are tied to an inode and what can be accessed through it. |
| 52 | −Reading the content of a directory doesn't imply to be allowed to read the | |
| 52 | +Reading the content of a directory does not imply to be allowed to read the | |
| 53 | 53 | content of a listed inode. Indeed, a file name is local to its parent |
| 54 | 54 | directory, and an inode can be referenced by multiple file names thanks to |
| 55 | 55 | (hard) links. Being able to unlink a file only has a direct impact on the |
| 56 | 56 | directory, not the unlinked inode. This is the reason why |
| 57 | −`LANDLOCK_ACCESS_FS_REMOVE_FILE` or `LANDLOCK_ACCESS_FS_REFER` are not allowed | |
| 58 | −to be tied to files but only to directories. | |
| 57 | +``LANDLOCK_ACCESS_FS_REMOVE_FILE`` or ``LANDLOCK_ACCESS_FS_REFER`` are not | |
| 58 | +allowed to be tied to files but only to directories. | |
| 59 | 59 | |
| 60 | 60 | Tests |
| 61 | 61 | ===== |
| @@ -14,45 +14,3 @@ Unsorted Documentation · 13 unmodified lines | ||
| 14 | 14 | static-keys |
| 15 | 15 | tee |
| 16 | 16 | xz |
| 17 | − | |
| 18 | −Atomic Types | |
| 19 | −============ | |
| 20 | − | |
| 21 | −.. raw:: latex | |
| 22 | − | |
| 23 | − \footnotesize | |
| 24 | − | |
| 25 | −.. include:: ../atomic_t.txt | |
| 26 | − :literal: | |
| 27 | − | |
| 28 | −.. raw:: latex | |
| 29 | − | |
| 30 | − \normalsize | |
| 31 | − | |
| 32 | −Atomic bitops | |
| 33 | −============= | |
| 34 | − | |
| 35 | −.. raw:: latex | |
| 36 | − | |
| 37 | − \footnotesize | |
| 38 | − | |
| 39 | −.. include:: ../atomic_bitops.txt | |
| 40 | − :literal: | |
| 41 | − | |
| 42 | −.. raw:: latex | |
| 43 | − | |
| 44 | − \normalsize | |
| 45 | − | |
| 46 | −Memory Barriers | |
| 47 | −=============== | |
| 48 | − | |
| 49 | −.. raw:: latex | |
| 50 | − | |
| 51 | − \footnotesize | |
| 52 | − | |
| 53 | −.. include:: ../memory-barriers.txt | |
| 54 | − :literal: | |
| 55 | − | |
| 56 | −.. raw:: latex | |
| 57 | − | |
| 58 | − \normalsize | |
| @@ -0,0 +1,58 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +============================== | |
| 4 | +Kernel subsystem documentation | |
| 5 | +============================== | |
| 6 | + | |
| 7 | +These books get into the details of how specific kernel subsystems work | |
| 8 | +from the point of view of a kernel developer. Much of the information here | |
| 9 | +is taken directly from the kernel source, with supplemental material added | |
| 10 | +as needed (or at least as we managed to add it — probably *not* all that is | |
| 11 | +needed). | |
| 12 | + | |
| 13 | +**Fixme**: much more organizational work is needed here. | |
| 14 | + | |
| 15 | +.. toctree:: | |
| 16 | + :maxdepth: 1 | |
| 17 | + | |
| 18 | + driver-api/index | |
| 19 | + core-api/index | |
| 20 | + locking/index | |
| 21 | + accounting/index | |
| 22 | + block/index | |
| 23 | + cdrom/index | |
| 24 | + cpu-freq/index | |
| 25 | + fb/index | |
| 26 | + fpga/index | |
| 27 | + hid/index | |
| 28 | + i2c/index | |
| 29 | + iio/index | |
| 30 | + isdn/index | |
| 31 | + infiniband/index | |
| 32 | + leds/index | |
| 33 | + netlabel/index | |
| 34 | + networking/index | |
| 35 | + pcmcia/index | |
| 36 | + power/index | |
| 37 | + target/index | |
| 38 | + timers/index | |
| 39 | + spi/index | |
| 40 | + w1/index | |
| 41 | + watchdog/index | |
| 42 | + virt/index | |
| 43 | + input/index | |
| 44 | + hwmon/index | |
| 45 | + gpu/index | |
| 46 | + security/index | |
| 47 | + sound/index | |
| 48 | + crypto/index | |
| 49 | + filesystems/index | |
| 50 | + mm/index | |
| 51 | + bpf/index | |
| 52 | + usb/index | |
| 53 | + PCI/index | |
| 54 | + scsi/index | |
| 55 | + misc-devices/index | |
| 56 | + scheduler/index | |
| 57 | + mhi/index | |
| 58 | + peci/index | |
| @@ -412,7 +412,7 @@ Extended error information · 411 unmodified lines | ||
| 412 | 412 | Because the default sort key above is 'hitcount', the above shows a |
| 413 | 413 | the list of call_sites by increasing hitcount, so that at the bottom |
| 414 | 414 | we see the functions that made the most kmalloc calls during the |
| 415 | − run. If instead we we wanted to see the top kmalloc callers in | |
| 415 | + run. If instead we wanted to see the top kmalloc callers in | |
| 416 | 416 | terms of the number of bytes requested rather than the number of |
| 417 | 417 | calls, and we wanted the top caller to appear at the top, we can use |
| 418 | 418 | the 'sort' parameter, along with the 'descending' modifier:: |
| @@ -328,8 +328,8 @@ Configuring Kprobes · 327 unmodified lines | ||
| 328 | 328 | =================== |
| 329 | 329 | |
| 330 | 330 | When configuring the kernel using make menuconfig/xconfig/oldconfig, |
| 331 | −ensure that CONFIG_KPROBES is set to "y". Under "General setup", look | |
| 332 | −for "Kprobes". | |
| 331 | +ensure that CONFIG_KPROBES is set to "y", look for "Kprobes" under | |
| 332 | +"General architecture-dependent options". | |
| 333 | 333 | |
| 334 | 334 | So that you can load and unload Kprobes-based instrumentation modules, |
| 335 | 335 | make sure "Loadable module support" (CONFIG_MODULES) and "Module |
| @@ -20,7 +20,7 @@ For example:: · 19 unmodified lines | ||
| 20 | 20 | [root@f32 ~]# cd /sys/kernel/tracing/ |
| 21 | 21 | [root@f32 tracing]# echo timerlat > current_tracer |
| 22 | 22 | |
| 23 | −It is possible to follow the trace by reading the trace trace file:: | |
| 23 | +It is possible to follow the trace by reading the trace file:: | |
| 24 | 24 | |
| 25 | 25 | [root@f32 tracing]# cat trace |
| 26 | 26 | # tracer: timerlat |
| @@ -1,39 +0,0 @@ | ||
| 1 | −Chinese translated version of Documentation/core-api/irq/index.rst | |
| 2 | − | |
| 3 | −If you have any comment or update to the content, please contact the | |
| 4 | −original document maintainer directly. However, if you have a problem | |
| 5 | −communicating in English you can also ask the Chinese maintainer for | |
| 6 | −help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | −or if there is a problem with the translation. | |
| 8 | − | |
| 9 | −Maintainer: Eric W. Biederman <ebiederman@xmission.com> | |
| 10 | −Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> | |
| 11 | −--------------------------------------------------------------------- | |
| 12 | −Documentation/core-api/irq/index.rst 的中文翻译 | |
| 13 | − | |
| 14 | −如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 15 | −交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 16 | −译存在问题,请联系中文版维护者。 | |
| 17 | −英文版维护者: Eric W. Biederman <ebiederman@xmission.com> | |
| 18 | −中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 19 | −中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 20 | −中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 21 | − | |
| 22 | − | |
| 23 | −以下为正文 | |
| 24 | −--------------------------------------------------------------------- | |
| 25 | −何为 IRQ? | |
| 26 | − | |
| 27 | −一个 IRQ 是来自某个设备的一个中断请求。目前,它们可以来自一个硬件引脚, | |
| 28 | −或来自一个数据包。多个设备可能连接到同个硬件引脚,从而共享一个 IRQ。 | |
| 29 | − | |
| 30 | −一个 IRQ 编号是用于告知硬件中断源的内核标识。通常情况下,这是一个 | |
| 31 | −全局 irq_desc 数组的索引,但是除了在 linux/interrupt.h 中的实现, | |
| 32 | −具体的细节是体系结构特定的。 | |
| 33 | − | |
| 34 | −一个 IRQ 编号是设备上某个可能的中断源的枚举。通常情况下,枚举的编号是 | |
| 35 | −该引脚在系统内中断控制器的所有输入引脚中的编号。对于 ISA 总线中的情况, | |
| 36 | −枚举的是在两个 i8259 中断控制器中 16 个输入引脚。 | |
| 37 | − | |
| 38 | −架构可以对 IRQ 编号指定额外的含义,在硬件涉及任何手工配置的情况下, | |
| 39 | −是被提倡的。ISA 的 IRQ 是一个分配这类额外含义的典型例子。 | |
| @@ -0,0 +1,139 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. include:: ../disclaimer-zh_CN.rst | |
| 3 | + | |
| 4 | +:Original: Documentation/PCI/acpi-info.rst | |
| 5 | + | |
| 6 | +:翻译: | |
| 7 | + | |
| 8 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 9 | + | |
| 10 | +:校译: | |
| 11 | + | |
| 12 | + | |
| 13 | +===================== | |
| 14 | +PCI主桥的ACPI注意事项 | |
| 15 | +===================== | |
| 16 | + | |
| 17 | +一般的规则是,ACPI命名空间应该描述操作系统可能使用的所有东西,除非有其他方法让操作系 | |
| 18 | +统找到它[1, 2]。 | |
| 19 | + | |
| 20 | +例如,没有标准的硬件机制来枚举PCI主桥,所以ACPI命名空间必须描述每个主桥、访问它 | |
| 21 | +下面的PCI配置空间的方法、主桥转发到PCI的地址空间窗口(使用_CRS)以及传统的INTx | |
| 22 | +中断的路由(使用_PRT)。 | |
| 23 | + | |
| 24 | +在主桥下面的PCI设备,通常不需要通过ACPI描述。操作系统可以通过标准的PCI枚举机制来 | |
| 25 | +发现它们,使用配置访问来发现和识别设备,并读取和测量它们的BAR。然而,如果ACPI为它们 | |
| 26 | +提供电源管理或热插拔功能,或者如果设备有由平台中断控制器连接的INTx中断,需要一个_PRT | |
| 27 | +来描述这些连接,这种情况下ACPI可以描述PCI设备。 | |
| 28 | + | |
| 29 | +ACPI资源描述是通过ACPI命名空间中设备的_CRS对象完成的[2]。_CRS就像一个通用的PCI BAR: | |
| 30 | +操作系统可以读取_CRS并找出正在消耗的资源,即使它没有该设备的驱动程序[3]。这一点很重要, | |
| 31 | +因为它意味着一个旧的操作系统可以正确地工作,即使是在操作系统不知道的新设备的系统上。新设 | |
| 32 | +备可能什么都不做,但操作系统至少可以确保没有资源与它们冲突。 | |
| 33 | + | |
| 34 | +像MCFG、HPET、ECDT等静态表,不是保留地址空间的机制。静态表是在操作系统在启动初期且在它 | |
| 35 | +能够解析ACPI命名空间之前需要知道的东西。如果定义了一个新的表,即使旧的操作系统忽略了这 | |
| 36 | +个表,它也需要正常运行。_CRS允许这样做,因为它是通用的,可以被旧的操作系统解析;而静态表 | |
| 37 | +则不允许。 | |
| 38 | + | |
| 39 | +如果操作系统要管理一个通过ACPI描述的不可发现的设备,该设备将有一个特定的_HID/_CID,以 | |
| 40 | +告诉操作系统与之绑定的驱动程序,并且_CRS告诉操作系统和驱动程序该设备的寄存器在哪里。 | |
| 41 | + | |
| 42 | +PCI主桥是PNP0A03或PNP0A08设备。它们的_CRS应该描述它们所消耗的所有地址空间。这包括它 | |
| 43 | +们转发到PCI总线上的所有窗口,以及不转发到PCI的主桥本身的寄存器。主桥的寄存器包括次要/下 | |
| 44 | +级总线寄存器,决定了桥下面的总线范围,窗口寄存器描述了桥洞,等等。这些都是设备相关的,非 | |
| 45 | +架构相关的东西,所以PNP0A03/PNP0A08驱动可以管理它们的唯一方法是通过_PRS/_CRS/_SRS, | |
| 46 | +它包含了特定于设备的细节。主桥寄存器也包括ECAM空间,因为它是由主桥消耗的。 | |
| 47 | + | |
| 48 | +ACPI定义了一个Consumer/Producer位来区分桥寄存器(“Consumer”下文译作消费者)和 | |
| 49 | +桥洞(“Producer”下文译作生产者)[4, 5],但是早期的BIOS没有正确使用这个位。其结果 | |
| 50 | +是,目前的ACPI规范只为扩展地址空间描述符定义了消费者/生产者;在旧的QWord/Word/Word地 | |
| 51 | +址空间描述符中,该位应该被忽略。因此,操作系统必须假定所有的QWord/Word/Word描述符都是 | |
| 52 | +窗口。 | |
| 53 | + | |
| 54 | +在增加扩展地址空间描述符之前,消费者/生产者的失败意味着没有办法描述PNP0A03/PNP0A08设 | |
| 55 | +备本身的桥寄存器。解决办法是在PNP0C02捕捉器中描述桥寄存器(包括ECAM空间)[6]。 | |
| 56 | +除了ECAM之外,桥寄存器空间反正是特定于设备的,所以通用的PNP0A03/PNP0A08驱动程 | |
| 57 | +序(pci_root.c)没有必要了解它。 | |
| 58 | + | |
| 59 | +新的架构应该能够在PNP0A03设备中使用“消费者”扩展地址空间描述符,用于桥寄存器,包括 | |
| 60 | +ECAM,尽管对[6]的严格解释可能禁止这样做。旧的x86和ia64内核假定所有的地址空间描述 | |
| 61 | +符,包括“消费者”扩展地址空间的描述符,都是窗口,所以在这些架构上以这种方式描述桥寄 | |
| 62 | +存器是不安全的。 | |
| 63 | + | |
| 64 | +PNP0C02“主板”设备基本上是万能的。除了“不要将这些资源用于其他用途”之外,没有其他的编 | |
| 65 | +程模型。因此,PNP0C02 _CRS应该声明ACPI命名空间中(1)没有被_CRS声明的任何其他设备对 | |
| 66 | +象的地址空间,(2)不应该被OS分配给其他东西。 | |
| 67 | + | |
| 68 | +除非有一个标准的固件接口用于配置访问,例如ia64 SAL接口[7],否则PCIe规范要求使用增强 | |
| 69 | +型配置访问方法(ECAM)。主桥消耗ECAM内存地址空间并将内存访问转换为PCI配置访问。该规范 | |
| 70 | +定义了ECAM地址空间的布局和功能;只有地址空间的基础是特定于设备的。ACPI操作系统从静态 | |
| 71 | +MCFG表或PNP0A03设备中的_CBA方法中了解基础地址。 | |
| 72 | + | |
| 73 | +MCFG表必须描述非热插拔主桥的ECAM空间[8]。由于MCFG是一个静态表,不能通过热插拔更新, | |
| 74 | +PNP0A03设备中的_CBA方法描述了可热插拔主桥的ECAM空间[9]。请注意,对于MCFG和_CBA, | |
| 75 | +基址总是对应于总线0,即使桥器下面的总线范围(通过_CRS报告)不从0开始。 | |
| 76 | + | |
| 77 | + | |
| 78 | +[1] ACPI 6.2, sec 6.1: | |
| 79 | + 对于任何在非枚举类型的总线上的设备(例如,ISA总线),OSPM会枚举设备的标识符,ACPI | |
| 80 | + 系统固件必须为每个设备提供一个_HID对象...以使OSPM能够做到这一点。 | |
| 81 | + | |
| 82 | +[2] ACPI 6.2, sec 3.7: | |
| 83 | + 操作系统枚举主板设备时,只需通过读取ACPI命名空间来寻找具有硬件ID的设备。 | |
| 84 | + | |
| 85 | + ACPI枚举的每个设备都包括ACPI命名空间中ACPI定义的对象,该对象报告设备可能占用的硬 | |
| 86 | + 件资源[_PRS],报告设备当前使用的资源[_CRS]的对象,以及配置这些资源的对象[_SRS]。 | |
| 87 | + 这些信息被即插即用操作系统(OSPM)用来配置设备。 | |
| 88 | + | |
| 89 | +[3] ACPI 6.2, sec 6.2: | |
| 90 | + OSPM使用设备配置对象来配置通过ACPI列举的设备的硬件资源。设备配置对象提供了关于当前 | |
| 91 | + 和可能的资源需求的信息,共享资源之间的关系,以及配置硬件资源的方法。 | |
| 92 | + | |
| 93 | + 当OSPM枚举一个设备时,它调用_PRS来确定该设备的资源需求。它也可以调用_CRS来找到该设 | |
| 94 | + 备的当前资源设置。利用这些信息,即插即用系统决定设备应该消耗什么资源,并通过调用设备 | |
| 95 | + 的_SRS控制方法来设置这些资源。 | |
| 96 | + | |
| 97 | + 在ACPI中,设备可以消耗资源(例如,传统的键盘),提供资源(例如,一个专有的PCI桥), | |
| 98 | + 或者两者都做。除非另有规定,设备的资源被假定为来自设备层次结构中设备上方最近的匹配资 | |
| 99 | + 源。 | |
| 100 | + | |
| 101 | +[4] ACPI 6.2, sec 6.4.3.5.1, 2, 3, 4: | |
| 102 | + QWord/DWord/Word 地址空间描述符 (.1, .2, .3) | |
| 103 | + 常规标志: Bit [0] 被忽略。 | |
| 104 | + | |
| 105 | + 扩展地址空间描述符 (.4) | |
| 106 | + 常规标志: Bit [0] 消费者/生产者: | |
| 107 | + | |
| 108 | + * 1 – 这个设备消费这个资源 | |
| 109 | + * 0 – 该设备生产和消费该资源 | |
| 110 | + | |
| 111 | +[5] ACPI 6.2, sec 19.6.43: | |
| 112 | + ResourceUsage指定内存范围是由这个设备(ResourceConsumer)消费还是传递给子设备 | |
| 113 | + (ResourceProducer)。如果没有指定,那么就假定是ResourceConsumer。 | |
| 114 | + | |
| 115 | +[6] PCI Firmware 3.2, sec 4.1.2: | |
| 116 | + 如果操作系统不能原生的懂得保留MMCFG区域,MMCFG区域必须由固件保留。在MCFG表中或通 | |
| 117 | + 过_CBA方法(见第4.1.3节)报告的地址范围必须通过声明主板资源来保留。对于大多数系统, | |
| 118 | + 主板资源将出现在ACPI命名空间的根部(在_SB下),在一个节点的_HID为EISAID(PNP0C0 | |
| 119 | + 2),在这种情况下的资源不应该要求在根PCI总线的_CRS。这些资源可以选择在Int15 E820 | |
| 120 | + 或EFIGetMemoryMap中作为保留内存返回,但必须始终通过ACPI作为主板资源报告。 | |
| 121 | + | |
| 122 | +[7] PCI Express 4.0, sec 7.2.2: | |
| 123 | + 对于PC兼容的系统,或者没有实现允许访问配置空间的处理器架构特定固件接口标准的系统,需 | |
| 124 | + 要使用本节中定义的ECAM。 | |
| 125 | + | |
| 126 | +[8] PCI Firmware 3.2, sec 4.1.2: | |
| 127 | + MCFG表是一个ACPI表,用于沟通的基础地址对应的非热的可移动的PCI段组范围内的PCI段组在 | |
| 128 | + 启动时提供给操作系统。这对PC兼容系统来说是必需的。 | |
| 129 | + | |
| 130 | + MCFG表仅用于沟通在启动时系统可用的PCI段组对应的基址。 | |
| 131 | + | |
| 132 | +[9] PCI Firmware 3.2, sec 4.1.3: | |
| 133 | + _CBA (Memory mapped Configuration Base Address) 控制方法是一个可选的ACPI对 | |
| 134 | + 象,用于返回热插拔主桥的64位内存映射的配置基址。_CBA 返回的基址是与处理器相关的地址。 | |
| 135 | + _CBA 控制方法被评估为一个整数。 | |
| 136 | + | |
| 137 | + 这个控制方法出现在主桥对象下。当_CBA方法出现在一个活动的主桥对象下时,操作系统会评 | |
| 138 | + 估这个结构,以确定内存映射的配置基址,对应于_CRS方法中指定的总线编号范围的PCI段组。 | |
| 139 | + 一个包含_CBA方法的ACPI命名空间对象也必须包含一个相应的_SEG方法。 | |
| @@ -10,9 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | :校译: |
| 11 | 11 | |
| 12 | 12 | |
| 13 | − | |
| 14 | −.. _cn_PCI_index.rst: | |
| 15 | − | |
| 16 | 13 | =================== |
| 17 | 14 | Linux PCI总线子系统 |
| 18 | 15 | =================== |
| @@ -26,12 +23,12 @@ Linux PCI总线子系统 · 7 unmodified lines | ||
| 26 | 23 | pci-iov-howto |
| 27 | 24 | msi-howto |
| 28 | 25 | sysfs-pci |
| 26 | + acpi-info | |
| 29 | 27 | |
| 30 | 28 | |
| 31 | 29 | Todolist: |
| 32 | 30 | |
| 33 | − acpi-info | |
| 34 | − pci-error-recovery | |
| 35 | − pcieaer-howto | |
| 36 | − endpoint/index | |
| 37 | − boot-interrupts | |
| 31 | +* pci-error-recovery | |
| 32 | +* pcieaer-howto | |
| 33 | +* endpoint/index | |
| 34 | +* boot-interrupts | |
| @@ -6,10 +6,10 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | 吴想成 Wu XiangCheng <bobwxc@email.cn> |
| 8 | 8 | |
| 9 | −Linux内核5.x版本 <http://kernel.org/> | |
| 9 | +Linux内核6.x版本 <http://kernel.org/> | |
| 10 | 10 | ========================================= |
| 11 | 11 | |
| 12 | −以下是Linux版本5的发行注记。仔细阅读它们, | |
| 12 | +以下是Linux版本6的发行注记。仔细阅读它们, | |
| 13 | 13 | 它们会告诉你这些都是什么,解释如何安装内核,以及遇到问题时该如何做。 |
| 14 | 14 | |
| 15 | 15 | 什么是Linux? |
| @@ -61,27 +61,27 @@ Linux内核5.x版本 <http://kernel.org/> · 45 unmodified lines | ||
| 61 | 61 | - 如果您要安装完整的源代码,请把内核tar档案包放在您有权限的目录中(例如您 |
| 62 | 62 | 的主目录)并将其解包:: |
| 63 | 63 | |
| 64 | − xz -cd linux-5.x.tar.xz | tar xvf - | |
| 64 | + xz -cd linux-6.x.tar.xz | tar xvf - | |
| 65 | 65 | |
| 66 | 66 | 将“X”替换成最新内核的版本号。 |
| 67 | 67 | |
| 68 | 68 | 【不要】使用 /usr/src/linux 目录!这里有一组库头文件使用的内核头文件 |
| 69 | 69 | (通常是不完整的)。它们应该与库匹配,而不是被内核的变化搞得一团糟。 |
| 70 | 70 | |
| 71 | − - 您还可以通过打补丁在5.x版本之间升级。补丁以xz格式分发。要通过打补丁进行 | |
| 72 | − 安装,请获取所有较新的补丁文件,进入内核源代码(linux-5.x)的目录并 | |
| 71 | + - 您还可以通过打补丁在6.x版本之间升级。补丁以xz格式分发。要通过打补丁进行 | |
| 72 | + 安装,请获取所有较新的补丁文件,进入内核源代码(linux-6.x)的目录并 | |
| 73 | 73 | 执行:: |
| 74 | 74 | |
| 75 | − xz -cd ../patch-5.x.xz | patch -p1 | |
| 75 | + xz -cd ../patch-6.x.xz | patch -p1 | |
| 76 | 76 | |
| 77 | 77 | 请【按顺序】替换所有大于当前源代码树版本的“x”,这样就可以了。您可能想要 |
| 78 | 78 | 删除备份文件(文件名类似xxx~ 或 xxx.orig),并确保没有失败的补丁(文件名 |
| 79 | 79 | 类似xxx# 或 xxx.rej)。如果有,不是你就是我犯了错误。 |
| 80 | 80 | |
| 81 | − 与5.x内核的补丁不同,5.x.y内核(也称为稳定版内核)的补丁不是增量的,而是 | |
| 82 | − 直接应用于基本的5.x内核。例如,如果您的基本内核是5.0,并且希望应用5.0.3 | |
| 83 | − 补丁,则不应先应用5.0.1和5.0.2的补丁。类似地,如果您运行的是5.0.2内核, | |
| 84 | − 并且希望跳转到5.0.3,那么在应用5.0.3补丁之前,必须首先撤销5.0.2补丁 | |
| 81 | + 与6.x内核的补丁不同,6.x.y内核(也称为稳定版内核)的补丁不是增量的,而是 | |
| 82 | + 直接应用于基本的6.x内核。例如,如果您的基本内核是6.0,并且希望应用6.0.3 | |
| 83 | + 补丁,则不应先应用6.0.1和6.0.2的补丁。类似地,如果您运行的是6.0.2内核, | |
| 84 | + 并且希望跳转到6.0.3,那么在应用6.0.3补丁之前,必须首先撤销6.0.2补丁 | |
| 85 | 85 | (即patch -R)。更多关于这方面的内容,请阅读 |
| 86 | 86 | :ref:`Documentation/process/applying-patches.rst <applying_patches>` 。 |
| 87 | 87 | |
| @@ -103,7 +103,7 @@ Linux内核5.x版本 <http://kernel.org/> · 15 unmodified lines | ||
| 103 | 103 | 软件要求 |
| 104 | 104 | --------- |
| 105 | 105 | |
| 106 | − 编译和运行5.x内核需要各种软件包的最新版本。请参考 | |
| 106 | + 编译和运行6.x内核需要各种软件包的最新版本。请参考 | |
| 107 | 107 | :ref:`Documentation/process/changes.rst <changes>` |
| 108 | 108 | 来了解最低版本要求以及如何升级软件包。请注意,使用过旧版本的这些包可能会 |
| 109 | 109 | 导致很难追踪的间接错误,因此不要以为在生成或操作过程中出现明显问题时可以 |
| @@ -116,12 +116,12 @@ Linux内核5.x版本 <http://kernel.org/> · 6 unmodified lines | ||
| 116 | 116 | ``make O=output/dir`` 选项可以为输出文件(包括 .config)指定备用位置。 |
| 117 | 117 | 例如:: |
| 118 | 118 | |
| 119 | − kernel source code: /usr/src/linux-5.x | |
| 119 | + kernel source code: /usr/src/linux-6.x | |
| 120 | 120 | build directory: /home/name/build/kernel |
| 121 | 121 | |
| 122 | 122 | 要配置和构建内核,请使用:: |
| 123 | 123 | |
| 124 | − cd /usr/src/linux-5.x | |
| 124 | + cd /usr/src/linux-6.x | |
| 125 | 125 | make O=/home/name/build/kernel menuconfig |
| 126 | 126 | make O=/home/name/build/kernel |
| 127 | 127 | sudo make O=/home/name/build/kernel modules_install install |
| @@ -227,8 +227,6 @@ Linux内核5.x版本 <http://kernel.org/> · 99 unmodified lines | ||
| 227 | 227 | - 确保您至少有gcc 5.1可用。 |
| 228 | 228 | 有关更多信息,请参阅 :ref:`Documentation/process/changes.rst <changes>` 。 |
| 229 | 229 | |
| 230 | − 请注意,您仍然可以使用此内核运行a.out用户程序。 | |
| 231 | − | |
| 232 | 230 | - 执行 ``make`` 来创建压缩内核映像。如果您安装了lilo以适配内核makefile, |
| 233 | 231 | 那么也可以进行 ``make install`` ,但是您可能需要先检查特定的lilo设置。 |
| 234 | 232 | |
| @@ -282,67 +280,12 @@ Linux内核5.x版本 <http://kernel.org/> · 47 unmodified lines | ||
| 282 | 280 | 若遇到问题 |
| 283 | 281 | ----------- |
| 284 | 282 | |
| 285 | − - 如果您发现了一些可能由于内核缺陷所导致的问题,请检查MAINTAINERS(维护者) | |
| 286 | − 文件看看是否有人与令您遇到麻烦的内核部分相关。如果无人在此列出,那么第二 | |
| 287 | − 个最好的方案就是把它们发给我(torvalds@linux-foundation.org),也可能发送 | |
| 288 | − 到任何其他相关的邮件列表或新闻组。 | |
| 289 | − | |
| 290 | − - 在所有的缺陷报告中,【请】告诉我们您在说什么内核,如何复现问题,以及您的 | |
| 291 | − 设置是什么的(使用您的常识)。如果问题是新的,请告诉我;如果问题是旧的, | |
| 292 | − 请尝试告诉我您什么时候首次注意到它。 | |
| 293 | − | |
| 294 | − - 如果缺陷导致如下消息:: | |
| 295 | − | |
| 296 | − unable to handle kernel paging request at address C0000010 | |
| 297 | − Oops: 0002 | |
| 298 | − EIP: 0010:XXXXXXXX | |
| 299 | − eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx | |
| 300 | − esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx | |
| 301 | − ds: xxxx es: xxxx fs: xxxx gs: xxxx | |
| 302 | − Pid: xx, process nr: xx | |
| 303 | − xx xx xx xx xx xx xx xx xx xx | |
| 304 | − | |
| 305 | − 或者类似的内核调试信息显示在屏幕上或在系统日志里,请【如实】复制它。 | |
| 306 | − 可能对你来说转储(dump)看起来不可理解,但它确实包含可能有助于调试问题的 | |
| 307 | − 信息。转储上方的文本也很重要:它说明了内核转储代码的原因(在上面的示例中, | |
| 308 | − 是由于内核指针错误)。更多关于如何理解转储的信息,请参见 | |
| 309 | − Documentation/admin-guide/bug-hunting.rst。 | |
| 310 | − | |
| 311 | − - 如果使用 CONFIG_KALLSYMS 编译内核,则可以按原样发送转储,否则必须使用 | |
| 312 | − ``ksymoops`` 程序来理解转储(但通常首选使用CONFIG_KALLSYMS编译)。 | |
| 313 | − 此实用程序可从 | |
| 314 | − https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下载。 | |
| 315 | − 或者,您可以手动执行转储查找: | |
| 316 | − | |
| 317 | − - 在调试像上面这样的转储时,如果您可以查找EIP值的含义,这将非常有帮助。 | |
| 318 | − 十六进制值本身对我或其他任何人都没有太大帮助:它会取决于特定的内核设置。 | |
| 319 | − 您应该做的是从EIP行获取十六进制值(忽略 ``0010:`` ),然后在内核名字列表 | |
| 320 | − 中查找它,以查看哪个内核函数包含有问题的地址。 | |
| 321 | − | |
| 322 | − 要找到内核函数名,您需要找到与显示症状的内核相关联的系统二进制文件。就是 | |
| 323 | − 文件“linux/vmlinux”。要提取名字列表并将其与内核崩溃中的EIP进行匹配, | |
| 324 | − 请执行:: | |
| 325 | − | |
| 326 | − nm vmlinux | sort | less | |
| 327 | − | |
| 328 | − 这将为您提供一个按升序排序的内核地址列表,从中很容易找到包含有问题的地址 | |
| 329 | − 的函数。请注意,内核调试消息提供的地址不一定与函数地址完全匹配(事实上, | |
| 330 | − 这是不可能的),因此您不能只“grep”列表:不过列表将为您提供每个内核函数 | |
| 331 | − 的起点,因此通过查找起始地址低于你正在搜索的地址,但后一个函数的高于的 | |
| 332 | − 函数,你会找到您想要的。实际上,在您的问题报告中加入一些“上下文”可能是 | |
| 333 | − 一个好主意,给出相关的上下几行。 | |
| 334 | − | |
| 335 | − 如果您由于某些原因无法完成上述操作(如您使用预编译的内核映像或类似的映像), | |
| 336 | − 请尽可能多地告诉我您的相关设置信息,这会有所帮助。有关详细信息请阅读 | |
| 337 | − ‘Documentation/admin-guide/reporting-issues.rst’。 | |
| 338 | − | |
| 339 | − - 或者,您可以在正在运行的内核上使用gdb(只读的;即不能更改值或设置断点)。 | |
| 340 | − 为此,请首先使用-g编译内核;适当地编辑arch/x86/Makefile,然后执行 ``make | |
| 341 | − clean`` 。您还需要启用CONFIG_PROC_FS(通过 ``make config`` )。 | |
| 342 | − | |
| 343 | − 使用新内核重新启动后,执行 ``gdb vmlinux /proc/kcore`` 。现在可以使用所有 | |
| 344 | − 普通的gdb命令。查找系统崩溃点的命令是 ``l *0xXXXXXXXX`` (将xxx替换为EIP | |
| 345 | − 值)。 | |
| 346 | − | |
| 347 | − 用gdb无法调试一个当前未运行的内核是由于gdb(错误地)忽略了编译内核的起始 | |
| 348 | − 偏移量。 | |
| 283 | +如果您发现了一些可能由于内核缺陷所导致的问题,请参阅: | |
| 284 | +Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 。 | |
| 285 | + | |
| 286 | +想要理解内核错误报告,请参阅: | |
| 287 | +Documentation/translations/zh_CN/admin-guide/bug-hunting.rst 。 | |
| 288 | + | |
| 289 | +更多用GDB调试内核的信息,请参阅: | |
| 290 | +Documentation/translations/zh_CN/dev-tools/gdb-kernel-debugging.rst | |
| 291 | +和 Documentation/dev-tools/kgdb.rst 。 | |
| @@ -0,0 +1,293 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/admin-guide/bootconfig.rst | |
| 6 | + | |
| 7 | +:译者: 吴想成 Wu XiangCheng <bobwxc@email.cn> | |
| 8 | + | |
| 9 | +======== | |
| 10 | +引导配置 | |
| 11 | +======== | |
| 12 | + | |
| 13 | +:作者: Masami Hiramatsu <mhiramat@kernel.org> | |
| 14 | + | |
| 15 | +概述 | |
| 16 | +==== | |
| 17 | + | |
| 18 | +引导配置扩展了现有的内核命令行,以一种更有效率的方式在引导内核时进一步支持 | |
| 19 | +键值数据。这允许管理员传递一份结构化关键字的配置文件。 | |
| 20 | + | |
| 21 | +配置文件语法 | |
| 22 | +============ | |
| 23 | + | |
| 24 | +引导配置文件的语法采用非常简单的键值结构。每个关键字由点连接的单词组成,键 | |
| 25 | +和值由 ``=`` 连接。值以分号( ``;`` )或换行符( ``\n`` )结尾。数组值中每 | |
| 26 | +个元素由逗号( ``,`` )分隔。:: | |
| 27 | + | |
| 28 | + KEY[.WORD[...]] = VALUE[, VALUE2[...]][;] | |
| 29 | + | |
| 30 | +与内核命令行语法不同,逗号和 ``=`` 周围允许有空格。 | |
| 31 | + | |
| 32 | +关键字只允许包含字母、数字、连字符( ``-`` )和下划线( ``_`` )。值可包含 | |
| 33 | +可打印字符和空格,但分号( ``;`` )、换行符( ``\n`` )、逗号( ``,`` )、 | |
| 34 | +井号( ``#`` )和右大括号( ``}`` )等分隔符除外。 | |
| 35 | + | |
| 36 | +如果你需要在值中使用这些分隔符,可以用双引号( ``"VALUE"`` )或单引号 | |
| 37 | +( ``'VALUE'`` )括起来。注意,引号无法转义。 | |
| 38 | + | |
| 39 | +键的值可以为空或不存在。这些键用于检查该键是否存在(类似布尔值)。 | |
| 40 | + | |
| 41 | +键值语法 | |
| 42 | +-------- | |
| 43 | + | |
| 44 | +引导配置文件语法允许用户通过大括号合并键名部分相同的关键字。例如:: | |
| 45 | + | |
| 46 | + foo.bar.baz = value1 | |
| 47 | + foo.bar.qux.quux = value2 | |
| 48 | + | |
| 49 | +也可以写成:: | |
| 50 | + | |
| 51 | + foo.bar { | |
| 52 | + baz = value1 | |
| 53 | + qux.quux = value2 | |
| 54 | + } | |
| 55 | + | |
| 56 | +或者更紧凑一些,写成:: | |
| 57 | + | |
| 58 | + foo.bar { baz = value1; qux.quux = value2 } | |
| 59 | + | |
| 60 | +在这两种样式中,引导解析时相同的关键字都会自动合并。因此可以追加类似的树或 | |
| 61 | +键值。 | |
| 62 | + | |
| 63 | +相同关键字的值 | |
| 64 | +-------------- | |
| 65 | + | |
| 66 | +禁止两个或多个值或数组共享同一个关键字。例如:: | |
| 67 | + | |
| 68 | + foo = bar, baz | |
| 69 | + foo = qux # !错误! 我们不可以重定义相同的关键字 | |
| 70 | + | |
| 71 | +如果你想要更新值,必须显式使用覆盖操作符 ``:=`` 。例如:: | |
| 72 | + | |
| 73 | + foo = bar, baz | |
| 74 | + foo := qux | |
| 75 | + | |
| 76 | +这样 ``foo`` 关键字的值就变成了 ``qux`` 。这对于通过添加(部分)自定义引导 | |
| 77 | +配置来覆盖默认值非常有用,免于解析默认引导配置。 | |
| 78 | + | |
| 79 | +如果你想对现有关键字追加值作为数组成员,可以使用 ``+=`` 操作符。例如:: | |
| 80 | + | |
| 81 | + foo = bar, baz | |
| 82 | + foo += qux | |
| 83 | + | |
| 84 | +这样, ``foo`` 关键字就同时拥有了 ``bar`` , ``baz`` 和 ``qux`` 。 | |
| 85 | + | |
| 86 | +此外,父关键字下可同时存在值和子关键字。 | |
| 87 | +例如,下列配置是可行的。:: | |
| 88 | + | |
| 89 | + foo = value1 | |
| 90 | + foo.bar = value2 | |
| 91 | + foo := value3 # 这会更新foo的值。 | |
| 92 | + | |
| 93 | +注意,裸值不能直接放进结构化关键字中,必须在大括号外定义它。例如:: | |
| 94 | + | |
| 95 | + foo { | |
| 96 | + bar = value1 | |
| 97 | + bar { | |
| 98 | + baz = value2 | |
| 99 | + qux = value3 | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | +同时,关键字下值节点的顺序是固定的。如果值和子关键字同时存在,值永远是该关 | |
| 104 | +键字的第一个子节点。因此如果用户先指定子关键字,如:: | |
| 105 | + | |
| 106 | + foo.bar = value1 | |
| 107 | + foo = value2 | |
| 108 | + | |
| 109 | +则在程序(和/proc/bootconfig)中,它会按如下显示:: | |
| 110 | + | |
| 111 | + foo = value2 | |
| 112 | + foo.bar = value1 | |
| 113 | + | |
| 114 | +注释 | |
| 115 | +---- | |
| 116 | + | |
| 117 | +配置语法接受shell脚本风格的注释。注释以井号( ``#`` )开始,到换行符 | |
| 118 | +( ``\n`` )结束。 | |
| 119 | + | |
| 120 | +:: | |
| 121 | + | |
| 122 | + # comment line | |
| 123 | + foo = value # value is set to foo. | |
| 124 | + bar = 1, # 1st element | |
| 125 | + 2, # 2nd element | |
| 126 | + 3 # 3rd element | |
| 127 | + | |
| 128 | +会被解析为:: | |
| 129 | + | |
| 130 | + foo = value | |
| 131 | + bar = 1, 2, 3 | |
| 132 | + | |
| 133 | +注意你不能把注释放在值和分隔符( ``,`` 或 ``;`` )之间。如下配置语法是错误的:: | |
| 134 | + | |
| 135 | + key = 1 # comment | |
| 136 | + ,2 | |
| 137 | + | |
| 138 | + | |
| 139 | +/proc/bootconfig | |
| 140 | +================ | |
| 141 | + | |
| 142 | +/proc/bootconfig是引导配置的用户空间接口。与/proc/cmdline不同,此文件内容以 | |
| 143 | +键值列表样式显示。 | |
| 144 | +每个键值对一行,样式如下:: | |
| 145 | + | |
| 146 | + KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...] | |
| 147 | + | |
| 148 | + | |
| 149 | +用引导配置引导内核 | |
| 150 | +================== | |
| 151 | + | |
| 152 | +用引导配置引导内核有两种方法:将引导配置附加到initrd镜像或直接嵌入内核中。 | |
| 153 | + | |
| 154 | +*initrd: initial RAM disk,初始内存磁盘* | |
| 155 | + | |
| 156 | +将引导配置附加到initrd | |
| 157 | +---------------------- | |
| 158 | + | |
| 159 | +由于默认情况下引导配置文件是用initrd加载的,因此它将被添加到initrd(initramfs) | |
| 160 | +镜像文件的末尾,其中包含填充、大小、校验值和12字节幻数,如下所示:: | |
| 161 | + | |
| 162 | + [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n] | |
| 163 | + | |
| 164 | +大小和校验值为小端序存放的32位无符号值。 | |
| 165 | + | |
| 166 | +当引导配置被加到initrd镜像时,整个文件大小会对齐到4字节。空字符( ``\0`` ) | |
| 167 | +会填补对齐空隙。因此 ``size`` 就是引导配置文件的长度+填充的字节。 | |
| 168 | + | |
| 169 | +Linux内核在内存中解码initrd镜像的最后部分以获取引导配置数据。由于这种“背负式” | |
| 170 | +的方法,只要引导加载器传递了正确的initrd文件大小,就无需更改或更新引导加载器 | |
| 171 | +和内核镜像本身。如果引导加载器意外传递了更长的大小,内核将无法找到引导配置数 | |
| 172 | +据。 | |
| 173 | + | |
| 174 | +Linux内核在tools/bootconfig下提供了 ``bootconfig`` 命令来完成此操作,管理员 | |
| 175 | +可以用它从initrd镜像中删除或追加配置文件。你可以用以下命令来构建它:: | |
| 176 | + | |
| 177 | + # make -C tools/bootconfig | |
| 178 | + | |
| 179 | +要向initrd镜像添加你的引导配置文件,请按如下命令操作(旧数据会自动移除):: | |
| 180 | + | |
| 181 | + # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z | |
| 182 | + | |
| 183 | +要从镜像中移除配置,可以使用-d选项:: | |
| 184 | + | |
| 185 | + # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z | |
| 186 | + | |
| 187 | +然后在内核命令行上添加 ``bootconfig`` 告诉内核去initrd文件末尾寻找内核配置。 | |
| 188 | + | |
| 189 | +将引导配置嵌入内核 | |
| 190 | +------------------ | |
| 191 | + | |
| 192 | +如果你不能使用initrd,也可以通过Kconfig选项将引导配置文件嵌入内核中。在此情 | |
| 193 | +况下,你需要用以下选项重新编译内核:: | |
| 194 | + | |
| 195 | + CONFIG_BOOT_CONFIG_EMBED=y | |
| 196 | + CONFIG_BOOT_CONFIG_EMBED_FILE="/引导配置/文件/的/路径" | |
| 197 | + | |
| 198 | +``CONFIG_BOOT_CONFIG_EMBED_FILE`` 需要从源码树或对象树开始的引导配置文件的 | |
| 199 | +绝对/相对路径。内核会将其嵌入作为默认引导配置。 | |
| 200 | + | |
| 201 | +与将引导配置附加到initrd一样,你也需要在内核命令行上添加 ``bootconfig`` 告诉 | |
| 202 | +内核去启用内嵌的引导配置。 | |
| 203 | + | |
| 204 | +注意,即使你已经设置了此选项,仍可用附加到initrd的其他引导配置覆盖内嵌的引导 | |
| 205 | +配置。 | |
| 206 | + | |
| 207 | +通过引导配置传递内核参数 | |
| 208 | +======================== | |
| 209 | + | |
| 210 | +除了内核命令行,引导配置也可以用于传递内核参数。所有 ``kernel`` 关键字下的键 | |
| 211 | +值对都将直接传递给内核命令行。此外, ``init`` 下的键值对将通过命令行传递给 | |
| 212 | +init进程。参数按以下顺序与用户给定的内核命令行字符串相连,因此命令行参数可以 | |
| 213 | +覆盖引导配置参数(这取决于子系统如何处理参数,但通常前面的参数将被后面的参数 | |
| 214 | +覆盖):: | |
| 215 | + | |
| 216 | + [bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params] | |
| 217 | + | |
| 218 | +如果引导配置文件给出的kernel/init参数是:: | |
| 219 | + | |
| 220 | + kernel { | |
| 221 | + root = 01234567-89ab-cdef-0123-456789abcd | |
| 222 | + } | |
| 223 | + init { | |
| 224 | + splash | |
| 225 | + } | |
| 226 | + | |
| 227 | +这将被复制到内核命令行字符串中,如下所示:: | |
| 228 | + | |
| 229 | + root="01234567-89ab-cdef-0123-456789abcd" -- splash | |
| 230 | + | |
| 231 | +如果用户给出的其他命令行是:: | |
| 232 | + | |
| 233 | + ro bootconfig -- quiet | |
| 234 | + | |
| 235 | +则最后的内核命令行如下:: | |
| 236 | + | |
| 237 | + root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet | |
| 238 | + | |
| 239 | + | |
| 240 | +配置文件的限制 | |
| 241 | +============== | |
| 242 | + | |
| 243 | +当前最大的配置大小是32KB,关键字总数(不是键值条目)必须少于1024个节点。 | |
| 244 | +注意:这不是条目数而是节点数,条目必须消耗超过2个节点(一个关键字和一个值)。 | |
| 245 | +所以从理论上讲最多512个键值对。如果关键字平均包含3个单词,则可有256个键值对。 | |
| 246 | +在大多数情况下,配置项的数量将少于100个条目,小于8KB,因此这应该足够了。如果 | |
| 247 | +节点数超过1024,解析器将返回错误,即使文件大小小于32KB。(请注意,此最大尺寸 | |
| 248 | +不包括填充的空字符。) | |
| 249 | +无论如何,因为 ``bootconfig`` 命令在附加启动配置到initrd映像时会验证它,用户 | |
| 250 | +可以在引导之前注意到它。 | |
| 251 | + | |
| 252 | + | |
| 253 | +引导配置API | |
| 254 | +=========== | |
| 255 | + | |
| 256 | +用户可以查询或遍历键值对,也可以查找(前缀)根关键字节点,并在查找该节点下的 | |
| 257 | +键值。 | |
| 258 | + | |
| 259 | +如果您有一个关键字字符串,则可以直接使用 xbc_find_value() 查询该键的值。如果 | |
| 260 | +你想知道引导配置里有哪些关键字,可以使用 xbc_for_each_key_value() 迭代键值对。 | |
| 261 | +请注意,您需要使用 xbc_array_for_each_value() 访问数组的值,例如:: | |
| 262 | + | |
| 263 | + vnode = NULL; | |
| 264 | + xbc_find_value("key.word", &vnode); | |
| 265 | + if (vnode && xbc_node_is_array(vnode)) | |
| 266 | + xbc_array_for_each_value(vnode, value) { | |
| 267 | + printk("%s ", value); | |
| 268 | + } | |
| 269 | + | |
| 270 | +如果您想查找具有前缀字符串的键,可以使用 xbc_find_node() 通过前缀字符串查找 | |
| 271 | +节点,然后用 xbc_node_for_each_key_value() 迭代前缀节点下的键。 | |
| 272 | + | |
| 273 | +但最典型的用法是获取前缀下的命名值或前缀下的命名数组,例如:: | |
| 274 | + | |
| 275 | + root = xbc_find_node("key.prefix"); | |
| 276 | + value = xbc_node_find_value(root, "option", &vnode); | |
| 277 | + ... | |
| 278 | + xbc_node_for_each_array_value(root, "array-option", value, anode) { | |
| 279 | + ... | |
| 280 | + } | |
| 281 | + | |
| 282 | +这将访问值“key.prefix.option”的值和“key.prefix.array-option”的数组。 | |
| 283 | + | |
| 284 | +锁是不需要的,因为在初始化之后配置只读。如果需要修改,必须复制所有数据和关键字。 | |
| 285 | + | |
| 286 | + | |
| 287 | +函数与结构体 | |
| 288 | +============ | |
| 289 | + | |
| 290 | +相关定义的kernel-doc参见: | |
| 291 | + | |
| 292 | + - include/linux/bootconfig.h | |
| 293 | + - lib/bootconfig.c | |
| @@ -63,6 +63,7 @@ Todolist: · 62 unmodified lines | ||
| 63 | 63 | .. toctree:: |
| 64 | 64 | :maxdepth: 1 |
| 65 | 65 | |
| 66 | + bootconfig | |
| 66 | 67 | clearing-warn-once |
| 67 | 68 | cpu-load |
| 68 | 69 | cputopology |
| @@ -80,7 +81,6 @@ Todolist: · 11 unmodified lines | ||
| 80 | 81 | * binderfs |
| 81 | 82 | * binfmt-misc |
| 82 | 83 | * blockdev/index |
| 83 | −* bootconfig | |
| 84 | 84 | * braille-console |
| 85 | 85 | * btmrvl |
| 86 | 86 | * cgroup-v1/index |
| @@ -0,0 +1,210 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0+ | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/core-api/circular-buffers.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 周彬彬 Binbin Zhou <zhoubinbin@loongson.cn> | |
| 10 | + | |
| 11 | +:校译: | |
| 12 | + | |
| 13 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 14 | + 吴想成 Wu Xiangcheng <bobwxc@email.cn> | |
| 15 | + 时奎亮 Alex Shi <alexs@kernel.org> | |
| 16 | + | |
| 17 | +========== | |
| 18 | +环形缓冲区 | |
| 19 | +========== | |
| 20 | + | |
| 21 | +:作者: David Howells <dhowells@redhat.com> | |
| 22 | +:作者: Paul E. McKenney <paulmck@linux.ibm.com> | |
| 23 | + | |
| 24 | + | |
| 25 | +Linux 提供了许多可用于实现循环缓冲的特性。有两组这样的特性: | |
| 26 | + | |
| 27 | + (1) 用于确定2次方大小的缓冲区信息的便利函数。 | |
| 28 | + | |
| 29 | + (2) 可以代替缓冲区中对象的生产者和消费者共享锁的内存屏障。 | |
| 30 | + | |
| 31 | +如下所述,要使用这些设施,只需要一个生产者和一个消费者。可以通过序列化来处理多个 | |
| 32 | +生产者,并通过序列化来处理多个消费者。 | |
| 33 | + | |
| 34 | +.. Contents: | |
| 35 | + | |
| 36 | + (*) 什么是环形缓冲区? | |
| 37 | + | |
| 38 | + (*) 测量2次幂缓冲区 | |
| 39 | + | |
| 40 | + (*) 内存屏障与环形缓冲区的结合使用 | |
| 41 | + - 生产者 | |
| 42 | + - 消费者 | |
| 43 | + | |
| 44 | + (*) 延伸阅读 | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | +什么是环形缓冲区? | |
| 49 | +================== | |
| 50 | + | |
| 51 | +首先,什么是环形缓冲区?环形缓冲区是具有固定的有限大小的缓冲区,它有两个索引: | |
| 52 | + | |
| 53 | + (1) 'head'索引 - 生产者将元素插入缓冲区的位置。 | |
| 54 | + | |
| 55 | + (2) 'tail'索引 - 消费者在缓冲区中找到下一个元素的位置。 | |
| 56 | + | |
| 57 | +通常,当tail指针等于head指针时,表明缓冲区是空的;而当head指针比tail指针少一个时, | |
| 58 | +表明缓冲区是满的。 | |
| 59 | + | |
| 60 | +添加元素时,递增head索引;删除元素时,递增tail索引。tail索引不应该跳过head索引, | |
| 61 | +两个索引在到达缓冲区末端时都应该被赋值为0,从而允许海量的数据流过缓冲区。 | |
| 62 | + | |
| 63 | +通常情况下,元素都有相同的单元大小,但这并不是使用以下技术的严格要求。如果要在缓 | |
| 64 | +冲区中包含多个元素或可变大小的元素,则索引可以增加超过1,前提是两个索引都没有超过 | |
| 65 | +另一个。然而,实现者必须小心,因为超过一个单位大小的区域可能会覆盖缓冲区的末端并 | |
| 66 | +且缓冲区会被分成两段。 | |
| 67 | + | |
| 68 | +测量2次幂缓冲区 | |
| 69 | +=============== | |
| 70 | + | |
| 71 | +计算任意大小的环形缓冲区的占用或剩余容量通常是一个费时的操作,需要使用模(除法) | |
| 72 | +指令。但是如果缓冲区的大小为2次幂,则可以使用更快的按位与指令代替。 | |
| 73 | + | |
| 74 | +Linux提供了一组用于处理2次幂环形缓冲区的宏。可以通过以下方式使用:: | |
| 75 | + | |
| 76 | + #include <linux/circ_buf.h> | |
| 77 | + | |
| 78 | +这些宏包括: | |
| 79 | + | |
| 80 | + (#) 测量缓冲区的剩余容量:: | |
| 81 | + | |
| 82 | + CIRC_SPACE(head_index, tail_index, buffer_size); | |
| 83 | + | |
| 84 | + 返回缓冲区[1]中可插入元素的剩余空间大小。 | |
| 85 | + | |
| 86 | + | |
| 87 | + (#) 测量缓冲区中的最大连续立即可用空间:: | |
| 88 | + | |
| 89 | + CIRC_SPACE_TO_END(head_index, tail_index, buffer_size); | |
| 90 | + | |
| 91 | + 返回缓冲区[1]中剩余的连续空间的大小,元素可以立即插入其中,而不必绕回到缓冲 | |
| 92 | + 区的开头。 | |
| 93 | + | |
| 94 | + | |
| 95 | + (#) 测量缓冲区的使用数:: | |
| 96 | + | |
| 97 | + CIRC_CNT(head_index, tail_index, buffer_size); | |
| 98 | + | |
| 99 | + 返回当前占用缓冲区[2]的元素数量。 | |
| 100 | + | |
| 101 | + | |
| 102 | + (#) 测量缓冲区的连续使用数:: | |
| 103 | + | |
| 104 | + CIRC_CNT_TO_END(head_index, tail_index, buffer_size); | |
| 105 | + | |
| 106 | + 返回可以从缓冲区中提取的连续元素[2]的数量,而不必绕回到缓冲区的开头。 | |
| 107 | + | |
| 108 | +这里的每一个宏名义上都会返回一个介于0和buffer_size-1之间的值,但是: | |
| 109 | + | |
| 110 | + (1) CIRC_SPACE*()是为了在生产者中使用。对生产者来说,它们将返回一个下限,因为生 | |
| 111 | + 产者控制着head索引,但消费者可能仍然在另一个CPU上耗尽缓冲区并移动tail索引。 | |
| 112 | + | |
| 113 | + 对消费者来说,它将显示一个上限,因为生产者可能正忙于耗尽空间。 | |
| 114 | + | |
| 115 | + (2) CIRC_CNT*()是为了在消费者中使用。对消费者来说,它们将返回一个下限,因为消费 | |
| 116 | + 者控制着tail索引,但生产者可能仍然在另一个CPU上填充缓冲区并移动head索引。 | |
| 117 | + | |
| 118 | + 对于生产者,它将显示一个上限,因为消费者可能正忙于清空缓冲区。 | |
| 119 | + | |
| 120 | + (3) 对于第三方来说,生产者和消费者对索引的写入顺序是无法保证的,因为它们是独立的, | |
| 121 | + 而且可能是在不同的CPU上进行的,所以在这种情况下的结果只是一种猜测,甚至可能 | |
| 122 | + 是错误的。 | |
| 123 | + | |
| 124 | +内存屏障与环形缓冲区的结合使用 | |
| 125 | +============================== | |
| 126 | + | |
| 127 | +通过将内存屏障与环形缓冲区结合使用,可以避免以下需求: | |
| 128 | + | |
| 129 | + (1) 使用单个锁来控制对缓冲区两端的访问,从而允许同时填充和清空缓冲区;以及 | |
| 130 | + | |
| 131 | + (2) 使用原子计数器操作。 | |
| 132 | + | |
| 133 | +这有两个方面:填充缓冲区的生产者和清空缓冲区的消费者。在任何时候,只应有一个生产 | |
| 134 | +者在填充缓冲区,同样的也只应有一个消费者在清空缓冲区,但双方可以同时操作。 | |
| 135 | + | |
| 136 | + | |
| 137 | +生产者 | |
| 138 | +------ | |
| 139 | + | |
| 140 | +生产者看起来像这样:: | |
| 141 | + | |
| 142 | + spin_lock(&producer_lock); | |
| 143 | + | |
| 144 | + unsigned long head = buffer->head; | |
| 145 | + /* spin_unlock()和下一个spin_lock()提供必要的排序。 */ | |
| 146 | + unsigned long tail = READ_ONCE(buffer->tail); | |
| 147 | + | |
| 148 | + if (CIRC_SPACE(head, tail, buffer->size) >= 1) { | |
| 149 | + /* 添加一个元素到缓冲区 */ | |
| 150 | + struct item *item = buffer[head]; | |
| 151 | + | |
| 152 | + produce_item(item); | |
| 153 | + | |
| 154 | + smp_store_release(buffer->head, | |
| 155 | + (head + 1) & (buffer->size - 1)); | |
| 156 | + | |
| 157 | + /* wake_up()将确保在唤醒任何人之前提交head */ | |
| 158 | + wake_up(consumer); | |
| 159 | + } | |
| 160 | + | |
| 161 | + spin_unlock(&producer_lock); | |
| 162 | + | |
| 163 | +这将表明CPU必须在head索引使其对消费者可用之前写入新项目的内容,同时CPU必须在唤醒 | |
| 164 | +消费者之前写入修改后的head索引。 | |
| 165 | + | |
| 166 | +请注意,wake_up()并不保证任何形式的屏障,除非确实唤醒了某些东西。因此我们不能依靠 | |
| 167 | +它来进行排序。但是数组中始终有一个元素留空,因此生产者必须产生两个元素,然后才可 | |
| 168 | +能破坏消费者当前正在读取的元素。同时,消费者连续调用之间成对的解锁-加锁提供了索引 | |
| 169 | +读取(指示消费者已清空给定元素)和生产者对该相同元素的写入之间的必要顺序。 | |
| 170 | + | |
| 171 | + | |
| 172 | +消费者 | |
| 173 | +------ | |
| 174 | + | |
| 175 | +消费者看起来像这样:: | |
| 176 | + | |
| 177 | + spin_lock(&consumer_lock); | |
| 178 | + | |
| 179 | + /* 读取该索引处的内容之前,先读取索引 */ | |
| 180 | + unsigned long head = smp_load_acquire(buffer->head); | |
| 181 | + unsigned long tail = buffer->tail; | |
| 182 | + | |
| 183 | + if (CIRC_CNT(head, tail, buffer->size) >= 1) { | |
| 184 | + | |
| 185 | + /* 从缓冲区中提取一个元素 */ | |
| 186 | + struct item *item = buffer[tail]; | |
| 187 | + | |
| 188 | + consume_item(item); | |
| 189 | + | |
| 190 | + /* 在递增tail之前完成对描述符的读取。 */ | |
| 191 | + smp_store_release(buffer->tail, | |
| 192 | + (tail + 1) & (buffer->size - 1)); | |
| 193 | + } | |
| 194 | + | |
| 195 | + spin_unlock(&consumer_lock); | |
| 196 | + | |
| 197 | +这表明CPU在读取新元素之前确保索引是最新的,然后在写入新的尾指针之前应确保CPU已完 | |
| 198 | +成读取该元素,这将擦除该元素。 | |
| 199 | + | |
| 200 | +请注意,使用READ_ONCE()和smp_load_acquire()来读取反向(head)索引。这可以防止编译 | |
| 201 | +器丢弃并重新加载其缓存值。如果您能确定反向(head)索引将仅使用一次,则这不是必须 | |
| 202 | +的。smp_load_acquire()还可以强制CPU对后续的内存引用进行排序。类似地,两种算法都使 | |
| 203 | +用smp_store_release()来写入线程的索引。这记录了我们正在写入可以并发读取的内容的事 | |
| 204 | +实,以防止编译器破坏存储,并强制对以前的访问进行排序。 | |
| 205 | + | |
| 206 | + | |
| 207 | +延伸阅读 | |
| 208 | +======== | |
| 209 | + | |
| 210 | +关于Linux的内存屏障设施的描述,请查看Documentation/memory-barriers.txt。 | |
| @@ -0,0 +1,23 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0+ | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/core-api/generic-radix-tree.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 周彬彬 Binbin Zhou <zhoubinbin@loongson.cn> | |
| 10 | + | |
| 11 | +=================== | |
| 12 | +通用基数树/稀疏数组 | |
| 13 | +=================== | |
| 14 | + | |
| 15 | +通用基数树/稀疏数组的相关内容请见include/linux/generic-radix-tree.h文件中的 | |
| 16 | +“DOC: Generic radix trees/sparse arrays”。 | |
| 17 | + | |
| 18 | +通用基数树函数 | |
| 19 | +-------------- | |
| 20 | + | |
| 21 | +该API在以下内核代码中: | |
| 22 | + | |
| 23 | +include/linux/generic-radix-tree.h | |
| @@ -0,0 +1,80 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0+ | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/core-api/idr.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 周彬彬 Binbin Zhou <zhoubinbin@loongson.cn> | |
| 10 | + | |
| 11 | +:校译: | |
| 12 | + | |
| 13 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 14 | + 吴想成 Wu Xiangcheng <bobwxc@email.cn> | |
| 15 | + 时奎亮 Alex Shi <alexs@kernel.org> | |
| 16 | + | |
| 17 | +====== | |
| 18 | +ID分配 | |
| 19 | +====== | |
| 20 | + | |
| 21 | +:作者: Matthew Wilcox | |
| 22 | + | |
| 23 | +概述 | |
| 24 | +==== | |
| 25 | + | |
| 26 | +要解决的一个常见问题是分配标识符(IDs);它通常是标识事物的数字。比如包括文件描述 | |
| 27 | +符、进程ID、网络协议中的数据包标识符、SCSI标记和设备实例编号。IDR和IDA为这个问题 | |
| 28 | +提供了一个合理的解决方案,以避免每个人都自创。IDR提供将ID映射到指针的能力,而IDA | |
| 29 | +仅提供ID分配,因此内存效率更高。 | |
| 30 | + | |
| 31 | +IDR接口已经被废弃,请使用 ``XArray`` 。 | |
| 32 | + | |
| 33 | +IDR的用法 | |
| 34 | +========= | |
| 35 | + | |
| 36 | +首先初始化一个IDR,对于静态分配的IDR使用DEFINE_IDR(),或者对于动态分配的IDR使用 | |
| 37 | +idr_init()。 | |
| 38 | + | |
| 39 | +您可以调用idr_alloc()来分配一个未使用的ID。通过调用idr_find()查询与该ID相关的指针, | |
| 40 | +并通过调用idr_remove()释放该ID。 | |
| 41 | + | |
| 42 | +如果需要更改与一个ID相关联的指针,可以调用idr_replace()。这样做的一个常见原因是通 | |
| 43 | +过将 ``NULL`` 指针传递给分配函数来保留ID;用保留的ID初始化对象,最后将初始化的对 | |
| 44 | +象插入IDR。 | |
| 45 | + | |
| 46 | +一些用户需要分配大于 ``INT_MAX`` 的ID。到目前为止,所有这些用户都满足 ``UINT_MAX`` | |
| 47 | +的限制,他们使用idr_alloc_u32()。如果您需要超出u32的ID,我们将与您合作以满足您的 | |
| 48 | +需求。 | |
| 49 | + | |
| 50 | +如果需要按顺序分配ID,可以使用idr_alloc_cyclic()。处理较大数量的ID时,IDR的效率会 | |
| 51 | +降低,所以使用这个函数会有一点代价。 | |
| 52 | + | |
| 53 | +要对IDR使用的所有指针进行操作,您可以使用基于回调的idr_for_each()或迭代器样式的 | |
| 54 | +idr_for_each_entry()。您可能需要使用idr_for_each_entry_continue()来继续迭代。如果 | |
| 55 | +迭代器不符合您的需求,您也可以使用idr_get_next()。 | |
| 56 | + | |
| 57 | +当使用完IDR后,您可以调用idr_destroy()来释放IDR占用的内存。这并不会释放IDR指向的 | |
| 58 | +对象;如果您想这样做,请使用其中一个迭代器来执行此操作。 | |
| 59 | + | |
| 60 | +您可以使用idr_is_empty()来查看当前是否分配了任何ID。 | |
| 61 | + | |
| 62 | +如果在从IDR分配一个新ID时需要带锁,您可能需要传递一组限制性的GFP标志,但这可能导 | |
| 63 | +致IDR无法分配内存。为了解决该问题,您可以在获取锁之前调用idr_preload(),然后在分 | |
| 64 | +配之后调用idr_preload_end()。 | |
| 65 | + | |
| 66 | +IDR同步的相关内容请见include/linux/idr.h文件中的“DOC: idr sync”。 | |
| 67 | + | |
| 68 | +IDA的用法 | |
| 69 | +========= | |
| 70 | + | |
| 71 | +IDA的用法的相关内容请见lib/idr.c文件中的“DOC: IDA description”。 | |
| 72 | + | |
| 73 | +函数和数据结构 | |
| 74 | +============== | |
| 75 | + | |
| 76 | +该API在以下内核代码中: | |
| 77 | + | |
| 78 | +include/linux/idr.h | |
| 79 | + | |
| 80 | +lib/idr.c | |
| @@ -44,15 +44,15 @@ · 43 unmodified lines | ||
| 44 | 44 | assoc_array |
| 45 | 45 | xarray |
| 46 | 46 | rbtree |
| 47 | + idr | |
| 48 | + circular-buffers | |
| 49 | + generic-radix-tree | |
| 50 | + packing | |
| 47 | 51 | |
| 48 | 52 | Todolist: |
| 49 | 53 | |
| 50 | 54 | |
| 51 | 55 | |
| 52 | − idr | |
| 53 | − circular-buffers | |
| 54 | − generic-radix-tree | |
| 55 | − packing | |
| 56 | 56 | this_cpu_ops |
| 57 | 57 | timekeeping |
| 58 | 58 | errseq |
| @@ -0,0 +1,160 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0+ | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/core-api/packing.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 周彬彬 Binbin Zhou <zhoubinbin@loongson.cn> | |
| 10 | + | |
| 11 | +:校译: | |
| 12 | + | |
| 13 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 14 | + 吴想成 Wu Xiangcheng <bobwxc@email.cn> | |
| 15 | + 时奎亮 Alex Shi <alexs@kernel.org> | |
| 16 | + | |
| 17 | +======================== | |
| 18 | +通用的位域打包和解包函数 | |
| 19 | +======================== | |
| 20 | + | |
| 21 | +问题陈述 | |
| 22 | +-------- | |
| 23 | + | |
| 24 | +使用硬件时,必须在几种与其交互的方法之间进行选择。 | |
| 25 | + | |
| 26 | +可以将指针映射到在硬件设备的内存区上精心设计的结构体,并将其字段作为结构成员(可 | |
| 27 | +能声明为位域)访问。但是由于CPU和硬件设备之间潜在的字节顺序不匹配,以这种方式编写 | |
| 28 | +代码会降低其可移植性。 | |
| 29 | + | |
| 30 | +此外,必须密切注意将硬件文档中的寄存器定义转换为结构的位域索引。此外,一些硬件 | |
| 31 | +(通常是网络设备)倾向于以违反任何合理字边界(有时甚至是64位)的方式对其寄存器字 | |
| 32 | +段进行分组。这就造成了不得不在结构中定义寄存器字段的“高”和“低”部分的不便。 | |
| 33 | + | |
| 34 | +结构域定义的更可靠的替代方法是通过移动适当数量的位来提取所需的字段。但这仍然不能 | |
| 35 | +防止字节顺序不匹配,除非所有内存访问都是逐字节执行的。此外,代码很容易变得杂乱无 | |
| 36 | +章,同时可能会在所需的许多位移操作中丢失一些高层次的想法。 | |
| 37 | + | |
| 38 | +许多驱动程序采用了位移的方法,然后试图用定制的宏来减少杂乱无章的东西,但更多的时 | |
| 39 | +候,这些宏所采用的捷径依旧妨碍了代码真正的可移植性。 | |
| 40 | + | |
| 41 | +解决方案 | |
| 42 | +-------- | |
| 43 | + | |
| 44 | +该API涉及2个基本操作: | |
| 45 | + | |
| 46 | + - 将一个CPU可使用的数字打包到内存缓冲区中(具有硬件约束/特殊性)。 | |
| 47 | + - 将内存缓冲区(具有硬件约束/特殊性)解压缩为一个CPU可使用的数字。 | |
| 48 | + | |
| 49 | +该API提供了对所述硬件约束和特殊性以及CPU字节序的抽象,因此这两者之间可能不匹配。 | |
| 50 | + | |
| 51 | +这些API函数的基本单元是u64。从CPU的角度来看,位63总是意味着字节7的位偏移量7,尽管 | |
| 52 | +只是逻辑上的。问题是:我们将这个比特放在内存的什么位置? | |
| 53 | + | |
| 54 | +以下示例介绍了打包u64字段的内存布局。打包缓冲区中的字节偏移量始终默认为0,1...7。 | |
| 55 | +示例显示的是逻辑字节和位所在的位置。 | |
| 56 | + | |
| 57 | +1. 通常情况下(无特殊性),我们会这样做: | |
| 58 | + | |
| 59 | +:: | |
| 60 | + | |
| 61 | + 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 | |
| 62 | + 7 6 5 4 | |
| 63 | + 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
| 64 | + 3 2 1 0 | |
| 65 | + | |
| 66 | +也就是说,CPU可使用的u64的MSByte(7)位于内存偏移量0处,而u64的LSByte(0)位于内存偏移量7处。 | |
| 67 | + | |
| 68 | +这对应于大多数人认为的“大端”,其中位i对应于数字2^i。这在代码注释中也称为“逻辑”符号。 | |
| 69 | + | |
| 70 | + | |
| 71 | +2. 如果设置了QUIRK_MSB_ON_THE_RIGHT,我们按如下方式操作: | |
| 72 | + | |
| 73 | +:: | |
| 74 | + | |
| 75 | + 56 57 58 59 60 61 62 63 48 49 50 51 52 53 54 55 40 41 42 43 44 45 46 47 32 33 34 35 36 37 38 39 | |
| 76 | + 7 6 5 4 | |
| 77 | + 24 25 26 27 28 29 30 31 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 | |
| 78 | + 3 2 1 0 | |
| 79 | + | |
| 80 | +也就是说,QUIRK_MSB_ON_THE_RIGHT不会影响字节定位,但会反转字节内的位偏移量。 | |
| 81 | + | |
| 82 | + | |
| 83 | +3. 如果设置了QUIRK_LITTLE_ENDIAN,我们按如下方式操作: | |
| 84 | + | |
| 85 | +:: | |
| 86 | + | |
| 87 | + 39 38 37 36 35 34 33 32 47 46 45 44 43 42 41 40 55 54 53 52 51 50 49 48 63 62 61 60 59 58 57 56 | |
| 88 | + 4 5 6 7 | |
| 89 | + 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 | |
| 90 | + 0 1 2 3 | |
| 91 | + | |
| 92 | +因此,QUIRK_LITTLE_ENDIAN意味着在内存区域内,每个4字节的字的每个字节都被放置在与 | |
| 93 | +该字的边界相比的镜像位置。 | |
| 94 | + | |
| 95 | + | |
| 96 | +4. 如果设置了QUIRK_MSB_ON_THE_RIGHT和QUIRK_LITTLE_ENDIAN,我们这样做: | |
| 97 | + | |
| 98 | +:: | |
| 99 | + | |
| 100 | + 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
| 101 | + 4 5 6 7 | |
| 102 | + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
| 103 | + 0 1 2 3 | |
| 104 | + | |
| 105 | + | |
| 106 | +5. 如果只设置了QUIRK_LSW32_IS_FIRST,我们这样做: | |
| 107 | + | |
| 108 | +:: | |
| 109 | + | |
| 110 | + 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
| 111 | + 3 2 1 0 | |
| 112 | + 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 | |
| 113 | + 7 6 5 4 | |
| 114 | + | |
| 115 | +在这种情况下,8字节内存区域解释如下:前4字节对应最不重要的4字节的字,后4字节对应 | |
| 116 | +更重要的4字节的字。 | |
| 117 | + | |
| 118 | +6. 如果设置了QUIRK_LSW32_IS_FIRST和QUIRK_MSB_ON_THE_RIGHT,我们这样做: | |
| 119 | + | |
| 120 | +:: | |
| 121 | + | |
| 122 | + 24 25 26 27 28 29 30 31 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 | |
| 123 | + 3 2 1 0 | |
| 124 | + 56 57 58 59 60 61 62 63 48 49 50 51 52 53 54 55 40 41 42 43 44 45 46 47 32 33 34 35 36 37 38 39 | |
| 125 | + 7 6 5 4 | |
| 126 | + | |
| 127 | + | |
| 128 | +7. 如果设置了QUIRK_LSW32_IS_FIRST和QUIRK_LITTLE_ENDIAN,则如下所示: | |
| 129 | + | |
| 130 | +:: | |
| 131 | + | |
| 132 | + 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 | |
| 133 | + 0 1 2 3 | |
| 134 | + 39 38 37 36 35 34 33 32 47 46 45 44 43 42 41 40 55 54 53 52 51 50 49 48 63 62 61 60 59 58 57 56 | |
| 135 | + 4 5 6 7 | |
| 136 | + | |
| 137 | + | |
| 138 | +8. 如果设置了QUIRK_LSW32_IS_FIRST,QUIRK_LITTLE_ENDIAN和QUIRK_MSB_ON_THE_RIGHT, | |
| 139 | + 则如下所示: | |
| 140 | + | |
| 141 | +:: | |
| 142 | + | |
| 143 | + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
| 144 | + 0 1 2 3 | |
| 145 | + 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
| 146 | + 4 5 6 7 | |
| 147 | + | |
| 148 | + | |
| 149 | +我们总是认为我们的偏移量好像没有特殊性,然后在访问内存区域之前翻译它们。 | |
| 150 | + | |
| 151 | +预期用途 | |
| 152 | +-------- | |
| 153 | + | |
| 154 | +选择使用该API的驱动程序首先需要确定上述3种quirk组合(共8种)中的哪一种与硬件文档 | |
| 155 | +中描述的相匹配。然后,他们应该封装packing()函数,创建一个新的xxx_packing(),使用 | |
| 156 | +适当的QUIRK_* one-hot 位集合来调用它。 | |
| 157 | + | |
| 158 | +packing()函数返回一个int类型的错误码,以防止程序员使用不正确的API。这些错误预计不 | |
| 159 | +会在运行时发生,因此xxx_packing()返回void并简单地接受这些错误是合理的。它可以选择 | |
| 160 | +转储栈或打印错误描述。 | |
| @@ -0,0 +1,37 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. include:: ../disclaimer-zh_CN.rst | |
| 3 | + | |
| 4 | +:Original: Documentation/Devicetree/changesets.rst | |
| 5 | + | |
| 6 | +:翻译: | |
| 7 | + | |
| 8 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 9 | + | |
| 10 | +:校译: | |
| 11 | + | |
| 12 | + | |
| 13 | +============ | |
| 14 | +设备树变更集 | |
| 15 | +============ | |
| 16 | + | |
| 17 | +设备树变更集是一种方法,它允许人们以这样一种方式在实时树中使用变化,即要么使用全部的 | |
| 18 | +变化,要么不使用。如果在使用变更集的过程中发生错误,那么树将被回滚到之前的状态。一个 | |
| 19 | +变更集也可以在使用后被删除。 | |
| 20 | + | |
| 21 | +当一个变更集被使用时,所有的改变在发出OF_RECONFIG通知器之前被一次性使用到树上。这是 | |
| 22 | +为了让接收者在收到通知时看到一个完整的、一致的树的状态。 | |
| 23 | + | |
| 24 | +一个变化集的顺序如下。 | |
| 25 | + | |
| 26 | +1. of_changeset_init() - 初始化一个变更集。 | |
| 27 | + | |
| 28 | +2. 一些DT树变化的调用,of_changeset_attach_node(), of_changeset_detach_node(), | |
| 29 | + of_changeset_add_property(), of_changeset_remove_property, | |
| 30 | + of_changeset_update_property()来准备一组变更。此时不会对活动树做任何变更。所有 | |
| 31 | + 的变更操作都记录在of_changeset的 `entries` 列表中。 | |
| 32 | + | |
| 33 | +3. of_changeset_apply() - 将变更使用到树上。要么整个变更集被使用,要么如果有错误, | |
| 34 | + 树会被恢复到之前的状态。核心通过锁确保正确的顺序。如果需要的话,可以使用一个解锁的 | |
| 35 | + __of_changeset_apply版本。 | |
| 36 | + | |
| 37 | +如果一个成功使用的变更集需要被删除,可以用of_changeset_revert()来完成。 | |
| @@ -0,0 +1,31 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. include:: ../disclaimer-zh_CN.rst | |
| 3 | + | |
| 4 | +:Original: Documentation/Devicetree/dynamic-resolution-notes.rst | |
| 5 | + | |
| 6 | +:翻译: | |
| 7 | + | |
| 8 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 9 | + | |
| 10 | +:校译: | |
| 11 | + | |
| 12 | +======================== | |
| 13 | +Devicetree动态解析器说明 | |
| 14 | +======================== | |
| 15 | + | |
| 16 | +本文描述了内核内DeviceTree解析器的实现,它位于drivers/of/resolver.c中。 | |
| 17 | + | |
| 18 | +解析器如何工作? | |
| 19 | +---------------- | |
| 20 | + | |
| 21 | +解析器被赋予一个任意的树作为输入,该树用适当的dtc选项编译,并有一个/plugin/标签。这就产 | |
| 22 | +生了适当的__fixups__和__local_fixups__节点。 | |
| 23 | + | |
| 24 | +解析器依次通过以下步骤工作: | |
| 25 | + | |
| 26 | +1. 从实时树中获取最大的设备树phandle值 + 1. | |
| 27 | +2. 调整树的所有本地 phandles,以解决这个量。 | |
| 28 | +3. 使用 __local__fixups__ 节点信息以相同的量调整所有本地引用。 | |
| 29 | +4. 对于__fixups__节点中的每个属性,找到它在实时树中引用的节点。这是用来标记该节点的标签。 | |
| 30 | +5. 检索fixup的目标的phandle。 | |
| 31 | +6. 对于属性中的每个fixup,找到节点:属性:偏移的位置,并用phandle值替换它。 | |
| @@ -24,21 +24,16 @@ Open Firmware 和 Devicetree · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | usage-model |
| 26 | 26 | of_unittest |
| 27 | − | |
| 28 | −Todolist: | |
| 29 | − | |
| 30 | −* kernel-api | |
| 27 | + kernel-api | |
| 31 | 28 | |
| 32 | 29 | Devicetree Overlays |
| 33 | 30 | =================== |
| 34 | 31 | .. toctree:: |
| 35 | 32 | :maxdepth: 1 |
| 36 | 33 | |
| 37 | −Todolist: | |
| 38 | − | |
| 39 | −* changesets | |
| 40 | −* dynamic-resolution-notes | |
| 41 | −* overlay-notes | |
| 34 | + changesets | |
| 35 | + dynamic-resolution-notes | |
| 36 | + overlay-notes | |
| 42 | 37 | |
| 43 | 38 | Devicetree Bindings |
| 44 | 39 | =================== |
| @@ -0,0 +1,58 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. include:: ../disclaimer-zh_CN.rst | |
| 3 | + | |
| 4 | +:Original: Documentation/Devicetree/kernel-api.rst | |
| 5 | + | |
| 6 | +:翻译: | |
| 7 | + | |
| 8 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 9 | + | |
| 10 | +:校译: | |
| 11 | + | |
| 12 | + | |
| 13 | +================= | |
| 14 | +内核中的设备树API | |
| 15 | +================= | |
| 16 | + | |
| 17 | +核心函数 | |
| 18 | +-------- | |
| 19 | + | |
| 20 | +该API在以下内核代码中: | |
| 21 | + | |
| 22 | +drivers/of/base.c | |
| 23 | + | |
| 24 | +include/linux/of.h | |
| 25 | + | |
| 26 | +drivers/of/property.c | |
| 27 | + | |
| 28 | +include/linux/of_graph.h | |
| 29 | + | |
| 30 | +drivers/of/address.c | |
| 31 | + | |
| 32 | +drivers/of/irq.c | |
| 33 | + | |
| 34 | +drivers/of/fdt.c | |
| 35 | + | |
| 36 | +驱动模型函数 | |
| 37 | +------------ | |
| 38 | + | |
| 39 | +该API在以下内核代码中: | |
| 40 | + | |
| 41 | +include/linux/of_device.h | |
| 42 | + | |
| 43 | +drivers/of/device.c | |
| 44 | + | |
| 45 | +include/linux/of_platform.h | |
| 46 | + | |
| 47 | +drivers/of/platform.c | |
| 48 | + | |
| 49 | +覆盖和动态DT函数 | |
| 50 | +---------------- | |
| 51 | + | |
| 52 | +该API在以下内核代码中: | |
| 53 | + | |
| 54 | +drivers/of/resolver.c | |
| 55 | + | |
| 56 | +drivers/of/dynamic.c | |
| 57 | + | |
| 58 | +drivers/of/overlay.c | |
| @@ -0,0 +1,140 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. include:: ../disclaimer-zh_CN.rst | |
| 3 | + | |
| 4 | +:Original: Documentation/Devicetree/overlay-notes.rst | |
| 5 | + | |
| 6 | +:翻译: | |
| 7 | + | |
| 8 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 9 | + | |
| 10 | +:校译: | |
| 11 | + | |
| 12 | +============== | |
| 13 | +设备树覆盖说明 | |
| 14 | +============== | |
| 15 | + | |
| 16 | +本文档描述了drivers/of/overlay.c中的内核内设备树覆盖功能的实现,是 | |
| 17 | +Documentation/devicetree/dynamic-resolution-notes.rst[1]的配套文档。 | |
| 18 | + | |
| 19 | +覆盖如何工作 | |
| 20 | +------------ | |
| 21 | + | |
| 22 | +设备树覆盖的目的是修改内核的实时树,并使修改以反映变化的方式影响内核的状态。 | |
| 23 | +由于内核主要处理的是设备,任何新的设备节点如果导致一个活动的设备,就应该创建它, | |
| 24 | +而如果设备节点被禁用或被全部删除,受影响的设备应该被取消注册。 | |
| 25 | + | |
| 26 | +让我们举个例子,我们有一个foo板,它的基本树形图如下:: | |
| 27 | + | |
| 28 | + ---- foo.dts --------------------------------------------------------------- | |
| 29 | + /* FOO平台 */ | |
| 30 | + /dts-v1/; | |
| 31 | + / { | |
| 32 | + compatible = "corp,foo"; | |
| 33 | + | |
| 34 | + /* 共享的资源 */ | |
| 35 | + res: res { | |
| 36 | + }; | |
| 37 | + | |
| 38 | + /* 芯片上的外围设备 */ | |
| 39 | + ocp: ocp { | |
| 40 | + /* 总是被实例化的外围设备 */ | |
| 41 | + peripheral1 { ... }; | |
| 42 | + }; | |
| 43 | + }; | |
| 44 | + ---- foo.dts --------------------------------------------------------------- | |
| 45 | + | |
| 46 | +覆盖bar.dts, | |
| 47 | +:: | |
| 48 | + | |
| 49 | + ---- bar.dts - 按标签覆盖目标位置 ---------------------------- | |
| 50 | + /dts-v1/; | |
| 51 | + /插件/; | |
| 52 | + &ocp { | |
| 53 | + /* bar外围 */ | |
| 54 | + bar { | |
| 55 | + compatible = "corp,bar"; | |
| 56 | + ... /* 各种属性和子节点 */ | |
| 57 | + }; | |
| 58 | + }; | |
| 59 | + ---- bar.dts --------------------------------------------------------------- | |
| 60 | + | |
| 61 | +当加载(并按照[1]中描述的方式解决)时,应该产生foo+bar.dts:: | |
| 62 | + | |
| 63 | + ---- foo+bar.dts ----------------------------------------------------------- | |
| 64 | + /* FOO平台 + bar外围 */ | |
| 65 | + / { | |
| 66 | + compatible = "corp,foo"; | |
| 67 | + | |
| 68 | + /* 共享资源 */ | |
| 69 | + res: res { | |
| 70 | + }; | |
| 71 | + | |
| 72 | + /* 芯片上的外围设备 */ | |
| 73 | + ocp: ocp { | |
| 74 | + /* 总是被实例化的外围设备 */ | |
| 75 | + peripheral1 { ... }; | |
| 76 | + | |
| 77 | + /* bar外围 */ | |
| 78 | + bar { | |
| 79 | + compatible = "corp,bar"; | |
| 80 | + ... /* 各种属性和子节点 */ | |
| 81 | + }; | |
| 82 | + }; | |
| 83 | + }; | |
| 84 | + ---- foo+bar.dts ----------------------------------------------------------- | |
| 85 | + | |
| 86 | +作为覆盖的结果,已经创建了一个新的设备节点(bar),因此将注册一个bar平台设备, | |
| 87 | +如果加载了匹配的设备驱动程序,将按预期创建设备。 | |
| 88 | + | |
| 89 | +如果基础DT不是用-@选项编译的,那么“&ocp”标签将不能用于将覆盖节点解析到基础 | |
| 90 | +DT中的适当位置。在这种情况下,可以提供目标路径。通过标签的目标位置的语法是比 | |
| 91 | +较好的,因为不管标签在DT中出现在哪里,覆盖都可以被应用到任何包含标签的基础DT上。 | |
| 92 | + | |
| 93 | +上面的bar.dts例子被修改为使用目标路径语法,即为:: | |
| 94 | + | |
| 95 | + ---- bar.dts - 通过明确的路径覆盖目标位置 -------------------- | |
| 96 | + /dts-v1/; | |
| 97 | + /插件/; | |
| 98 | + &{/ocp} { | |
| 99 | + /* bar外围 */ | |
| 100 | + bar { | |
| 101 | + compatible = "corp,bar"; | |
| 102 | + ... /* 各种外围设备和子节点 */ | |
| 103 | + } | |
| 104 | + }; | |
| 105 | + ---- bar.dts --------------------------------------------------------------- | |
| 106 | + | |
| 107 | + | |
| 108 | +内核中关于覆盖的API | |
| 109 | +------------------- | |
| 110 | + | |
| 111 | +该API相当容易使用。 | |
| 112 | + | |
| 113 | +1) 调用of_overlay_fdt_apply()来创建和应用一个覆盖的变更集。返回值是一个 | |
| 114 | + 错误或一个识别这个覆盖的cookie。 | |
| 115 | + | |
| 116 | +2) 调用of_overlay_remove()来删除和清理先前通过调用of_overlay_fdt_apply() | |
| 117 | + 而创建的覆盖变更集。不允许删除一个被另一个覆盖的覆盖变化集。 | |
| 118 | + | |
| 119 | +最后,如果你需要一次性删除所有的覆盖,只需调用of_overlay_remove_all(), | |
| 120 | +它将以正确的顺序删除每一个覆盖。 | |
| 121 | + | |
| 122 | +你可以选择注册在覆盖操作中被调用的通知器。详见 | |
| 123 | +of_overlay_notifier_register/unregister和enum of_overlay_notify_action。 | |
| 124 | + | |
| 125 | +OF_OVERLAY_PRE_APPLY、OF_OVERLAY_POST_APPLY或OF_OVERLAY_PRE_REMOVE | |
| 126 | +的通知器回调可以存储指向覆盖层中的设备树节点或其内容的指针,但这些指针不能持 | |
| 127 | +续到OF_OVERLAY_POST_REMOVE的通知器回调。在OF_OVERLAY_POST_REMOVE通 | |
| 128 | +知器被调用后,包含覆盖层的内存将被kfree()ed。请注意,即使OF_OVERLAY_POST_REMOVE | |
| 129 | +的通知器返回错误,内存也会被kfree()ed。 | |
| 130 | + | |
| 131 | +drivers/of/dynamic.c中的变更集通知器是第二种类型的通知器,可以通过应用或移除 | |
| 132 | +覆盖层来触发。这些通知器不允许在覆盖层或其内容中存储指向设备树节点的指针。当包含 | |
| 133 | +覆盖层的内存因移除覆盖层而被释放时,覆盖层代码并不能防止这类指针仍然有效。 | |
| 134 | + | |
| 135 | +任何其他保留指向覆盖层节点或数据的指针的代码都被认为是一个错误,因为在移除覆盖层 | |
| 136 | +后,该指针将指向已释放的内存。 | |
| 137 | + | |
| 138 | +覆盖层的用户必须特别注意系统上发生的整体操作,以确保其他内核代码不保留任何指向覆 | |
| 139 | +盖层节点或数据的指针。任何无意中使用这种指针的例子是,如果一个驱动或子系统模块在 | |
| 140 | +应用了覆盖后被加载,并且该驱动或子系统扫描了整个设备树或其大部分,包括覆盖节点。 | |
| @@ -0,0 +1,69 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +.. include:: ../../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/driver-api/gpio/index.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 10 | + | |
| 11 | +:校译: | |
| 12 | + | |
| 13 | +======================= | |
| 14 | +通用型输入/输出(GPIO) | |
| 15 | +======================= | |
| 16 | + | |
| 17 | +目录: | |
| 18 | + | |
| 19 | +.. toctree:: | |
| 20 | + :maxdepth: 2 | |
| 21 | + | |
| 22 | + legacy | |
| 23 | + | |
| 24 | +Todolist: | |
| 25 | + | |
| 26 | +* intro | |
| 27 | +* using-gpio | |
| 28 | +* driver | |
| 29 | +* consumer | |
| 30 | +* board | |
| 31 | +* drivers-on-gpio | |
| 32 | +* bt8xxgpio | |
| 33 | + | |
| 34 | +核心 | |
| 35 | +==== | |
| 36 | + | |
| 37 | +该API在以下内核代码中: | |
| 38 | + | |
| 39 | +include/linux/gpio/driver.h | |
| 40 | + | |
| 41 | +drivers/gpio/gpiolib.c | |
| 42 | + | |
| 43 | +ACPI支持 | |
| 44 | +======== | |
| 45 | + | |
| 46 | +该API在以下内核代码中: | |
| 47 | + | |
| 48 | +drivers/gpio/gpiolib-acpi.c | |
| 49 | + | |
| 50 | +设备树支持 | |
| 51 | +========== | |
| 52 | + | |
| 53 | +该API在以下内核代码中: | |
| 54 | + | |
| 55 | +drivers/gpio/gpiolib-of.c | |
| 56 | + | |
| 57 | +设备管理支持 | |
| 58 | +============ | |
| 59 | + | |
| 60 | +该API在以下内核代码中: | |
| 61 | + | |
| 62 | +drivers/gpio/gpiolib-devres.c | |
| 63 | + | |
| 64 | +sysfs帮助(函数) | |
| 65 | +================= | |
| 66 | + | |
| 67 | +该API在以下内核代码中: | |
| 68 | + | |
| 69 | +drivers/gpio/gpiolib-sysfs.c | |
| @@ -1,39 +1,28 @@ | ||
| 1 | −Chinese translated version of Documentation/admin-guide/gpio | |
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | 2 | |
| 3 | −If you have any comment or update to the content, please contact the | |
| 4 | −original document maintainer directly. However, if you have a problem | |
| 5 | −communicating in English you can also ask the Chinese maintainer for | |
| 6 | −help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | −or if there is a problem with the translation. | |
| 3 | +.. include:: ../../disclaimer-zh_CN.rst | |
| 8 | 4 | |
| 9 | −Maintainer: Grant Likely <grant.likely@secretlab.ca> | |
| 10 | − Linus Walleij <linus.walleij@linaro.org> | |
| 11 | −Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> | |
| 12 | −--------------------------------------------------------------------- | |
| 13 | −Documentation/admin-guide/gpio 的中文翻译 | |
| 5 | +:Original: Documentation/driver-api/gpio/legacy.rst | |
| 14 | 6 | |
| 15 | −如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 16 | −交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 17 | −译存在问题,请联系中文版维护者。 | |
| 18 | −英文版维护者: Grant Likely <grant.likely@secretlab.ca> | |
| 19 | − Linus Walleij <linus.walleij@linaro.org> | |
| 20 | −中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 21 | −中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 22 | −中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 7 | +:翻译: | |
| 23 | 8 | |
| 9 | + 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 10 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 24 | 11 | |
| 25 | −以下为正文 | |
| 26 | −--------------------------------------------------------------------- | |
| 27 | −GPIO 接口 | |
| 12 | +:校译: | |
| 28 | 13 | |
| 29 | −本文档提供了一个在Linux下访问GPIO的公约概述。 | |
| 14 | + | |
| 15 | +传统GPIO接口 | |
| 16 | +============ | |
| 17 | + | |
| 18 | +本文档概述了Linux下的GPIO访问公约。 | |
| 30 | 19 | |
| 31 | 20 | 这些函数以 gpio_* 作为前缀。其他的函数不允许使用这样的前缀或相关的 |
| 32 | 21 | __gpio_* 前缀。 |
| 33 | 22 | |
| 34 | 23 | |
| 35 | −什么是GPIO? | |
| 36 | −========== | |
| 24 | +什么是GPIO? | |
| 25 | +============ | |
| 37 | 26 | "通用输入/输出口"(GPIO)是一个灵活的由软件控制的数字信号。他们可 |
| 38 | 27 | 由多种芯片提供,且对于从事嵌入式和定制硬件的 Linux 开发者来说是 |
| 39 | 28 | 比较熟悉。每个GPIO 都代表一个连接到特定引脚或球栅阵列(BGA)封装中 |
| @@ -99,6 +88,7 @@ GPIO 公约 · 59 unmodified lines | ||
| 99 | 88 | |
| 100 | 89 | 标识 GPIO |
| 101 | 90 | --------- |
| 91 | + | |
| 102 | 92 | GPIO 是通过无符号整型来标识的,范围是 0 到 MAX_INT。保留“负”数 |
| 103 | 93 | 用于其他目的,例如标识信号“在这个板子上不可用”或指示错误。未接触底层 |
| 104 | 94 | 硬件的代码会忽略这些整数。 |
| @@ -115,7 +105,7 @@ FPGA 的特定板子上使用 80-95。编号不一定要连续,那些平台中 · 10 unmodified lines | ||
| 115 | 105 | |
| 116 | 106 | 如果你要初始化一个带有无效 GPIO 编号的结构体,可以使用一些负编码 |
| 117 | 107 | (如"-EINVAL"),那将使其永远不会是有效。来测试这样一个结构体中的编号 |
| 118 | −是否关联一个 GPIO,你可使用以下断言: | |
| 108 | +是否关联一个 GPIO,你可使用以下断言:: | |
| 119 | 109 | |
| 120 | 110 | int gpio_is_valid(int number); |
| 121 | 111 | |
| @@ -128,11 +118,12 @@ FPGA 的特定板子上使用 80-95。编号不一定要连续,那些平台中 · 6 unmodified lines | ||
| 128 | 118 | |
| 129 | 119 | 使用 GPIO |
| 130 | 120 | --------- |
| 121 | + | |
| 131 | 122 | 对于一个 GPIO,系统应该做的第一件事情就是通过 gpio_request() |
| 132 | 123 | 函数分配它,见下文。 |
| 133 | 124 | |
| 134 | 125 | 接下来是设置I/O方向,这通常是在板级启动代码中为所使用的 GPIO 设置 |
| 135 | −platform_device 时完成。 | |
| 126 | +platform_device 时完成:: | |
| 136 | 127 | |
| 137 | 128 | /* 设置为输入或输出, 返回 0 或负的错误代码 */ |
| 138 | 129 | int gpio_direction_input(unsigned gpio); |
| @@ -157,12 +148,13 @@ get/set(获取/设置)函数调用没法返回错误,且有可能是配置错误 · 18 unmodified lines | ||
| 157 | 148 | |
| 158 | 149 | |
| 159 | 150 | 访问自旋锁安全的 GPIO |
| 160 | −------------------- | |
| 151 | +--------------------- | |
| 152 | + | |
| 161 | 153 | 大多数 GPIO 控制器可以通过内存读/写指令来访问。这些指令不会休眠,可以 |
| 162 | 154 | 安全地在硬(非线程)中断例程和类似的上下文中完成。 |
| 163 | 155 | |
| 164 | 156 | 对于那些用 gpio_cansleep()测试总是返回失败的 GPIO(见下文),使用 |
| 165 | −以下的函数访问: | |
| 157 | +以下的函数访问:: | |
| 166 | 158 | |
| 167 | 159 | /* GPIO 输入:返回零或非零 */ |
| 168 | 160 | int gpio_get_value(unsigned gpio); |
| @@ -188,17 +180,18 @@ GPIO值是布尔值,零表示低电平,非零表示高电平。当读取一 · 19 unmodified lines | ||
| 188 | 180 | |
| 189 | 181 | |
| 190 | 182 | 访问可能休眠的 GPIO |
| 191 | −----------------- | |
| 183 | +------------------- | |
| 184 | + | |
| 192 | 185 | 某些 GPIO 控制器必须通过基于总线(如 I2C 或 SPI)的消息访问。读或写这些 |
| 193 | 186 | GPIO 值的命令需要等待其信息排到队首才发送命令,再获得其反馈。期间需要 |
| 194 | 187 | 休眠,这不能在 IRQ 例程(中断上下文)中执行。 |
| 195 | 188 | |
| 196 | 189 | 支持此类 GPIO 的平台通过以下函数返回非零值来区分出这种 GPIO。(此函数需要 |
| 197 | −一个之前通过 gpio_request 分配到的有效 GPIO 编号): | |
| 190 | +一个之前通过 gpio_request 分配到的有效 GPIO 编号):: | |
| 198 | 191 | |
| 199 | 192 | int gpio_cansleep(unsigned gpio); |
| 200 | 193 | |
| 201 | −为了访问这种 GPIO,内核定义了一套不同的函数: | |
| 194 | +为了访问这种 GPIO,内核定义了一套不同的函数:: | |
| 202 | 195 | |
| 203 | 196 | /* GPIO 输入:返回零或非零 ,可能会休眠 */ |
| 204 | 197 | int gpio_get_value_cansleep(unsigned gpio); |
| @@ -214,25 +207,26 @@ GPIO 值的命令需要等待其信息排到队首才发送命令,再获得其 · 9 unmodified lines | ||
| 214 | 207 | 事实,这些处理例程实际上和自旋锁安全的函数是一样的。 |
| 215 | 208 | |
| 216 | 209 | ** 除此之外 ** 调用设置和配置此类 GPIO 的函数也必须在允许休眠的上下文中, |
| 217 | −因为它们可能也需要访问 GPIO 控制器芯片: (这些设置函数通常在板级启动代码或者 | |
| 218 | −驱动探测/断开代码中,所以这是一个容易满足的约束条件。) | |
| 210 | +因为它们可能也需要访问 GPIO 控制器芯片 (这些设置函数通常在板级启动代码或者 | |
| 211 | +驱动探测/断开代码中,所以这是一个容易满足的约束条件。) :: | |
| 219 | 212 | |
| 220 | − gpio_direction_input() | |
| 221 | − gpio_direction_output() | |
| 222 | − gpio_request() | |
| 213 | + gpio_direction_input() | |
| 214 | + gpio_direction_output() | |
| 215 | + gpio_request() | |
| 223 | 216 | |
| 224 | −## gpio_request_one() | |
| 225 | −## gpio_request_array() | |
| 226 | −## gpio_free_array() | |
| 217 | + ## gpio_request_one() | |
| 218 | + ## gpio_request_array() | |
| 219 | + ## gpio_free_array() | |
| 227 | 220 | |
| 228 | − gpio_free() | |
| 229 | − gpio_set_debounce() | |
| 221 | + gpio_free() | |
| 222 | + gpio_set_debounce() | |
| 230 | 223 | |
| 231 | 224 | |
| 232 | 225 | |
| 233 | 226 | 声明和释放 GPIO |
| 234 | −---------------------------- | |
| 235 | −为了有助于捕获系统配置错误,定义了两个函数。 | |
| 227 | +---------------- | |
| 228 | + | |
| 229 | +为了有助于捕获系统配置错误,定义了两个函数:: | |
| 236 | 230 | |
| 237 | 231 | /* 申请 GPIO, 返回 0 或负的错误代码. |
| 238 | 232 | * 非空标签可能有助于诊断. |
| @@ -256,9 +250,9 @@ GPIO 值的命令需要等待其信息排到队首才发送命令,再获得其 · 17 unmodified lines | ||
| 256 | 250 | 某些平台可能也使用 GPIO 作为电源管理激活信号(例如通过关闭未使用芯片区和 |
| 257 | 251 | 简单地关闭未使用时钟)。 |
| 258 | 252 | |
| 259 | −对于 GPIO 使用 pinctrl 子系统已知的引脚,子系统应该被告知其使用情况; | |
| 253 | +对于 GPIO 使用引脚控制子系统已知的引脚,子系统应该被告知其使用情况; | |
| 260 | 254 | 一个 gpiolib 驱动的 .request()操作应调用 pinctrl_gpio_request(), |
| 261 | −而 gpiolib 驱动的 .free()操作应调用 pinctrl_gpio_free()。pinctrl | |
| 255 | +而 gpiolib 驱动的 .free()操作应调用 pinctrl_gpio_free()。引脚控制 | |
| 262 | 256 | 子系统允许 pinctrl_gpio_request()在某个引脚或引脚组以复用形式“属于” |
| 263 | 257 | 一个设备时都成功返回。 |
| 264 | 258 | |
| @@ -270,7 +264,7 @@ GPIO 值的命令需要等待其信息排到队首才发送命令,再获得其 · 5 unmodified lines | ||
| 270 | 264 | |
| 271 | 265 | 某些平台允许部分或所有 GPIO 信号使用不同的引脚。类似的,GPIO 或引脚的 |
| 272 | 266 | 其他方面也需要配置,如上拉/下拉。平台软件应该在对这些 GPIO 调用 |
| 273 | −gpio_request()前将这类细节配置好,例如使用 pinctrl 子系统的映射表, | |
| 267 | +gpio_request()前将这类细节配置好,例如使用引脚控制子系统的映射表, | |
| 274 | 268 | 使得 GPIO 的用户无须关注这些细节。 |
| 275 | 269 | |
| 276 | 270 | 还有一个值得注意的是在释放 GPIO 前,你必须停止使用它。 |
| @@ -278,7 +272,7 @@ gpio_request()前将这类细节配置好,例如使用 pinctrl 子系统的映 · 1 unmodified line | ||
| 278 | 272 | |
| 279 | 273 | 注意:申请一个 GPIO 并没有以任何方式配置它,只不过标识那个 GPIO 处于使用 |
| 280 | 274 | 状态。必须有另外的代码来处理引脚配置(如控制 GPIO 使用的引脚、上拉/下拉)。 |
| 281 | −考虑到大多数情况下声明 GPIO 之后就会立即配置它们,所以定义了以下三个辅助函数: | |
| 275 | +考虑到大多数情况下声明 GPIO 之后就会立即配置它们,所以定义了以下三个辅助函数:: | |
| 282 | 276 | |
| 283 | 277 | /* 申请一个 GPIO 信号, 同时通过特定的'flags'初始化配置, |
| 284 | 278 | * 其他和 gpio_request()的参数和返回值相同 |
| @@ -326,7 +320,7 @@ gpio_request()前将这类细节配置好,例如使用 pinctrl 子系统的映 · 41 unmodified lines | ||
| 326 | 320 | 将来这些标志可能扩展到支持更多的属性。 |
| 327 | 321 | |
| 328 | 322 | 更进一步,为了更简单地声明/释放多个 GPIO,'struct gpio'被引进来封装所有 |
| 329 | −这三个领域: | |
| 323 | +这三个领域:: | |
| 330 | 324 | |
| 331 | 325 | struct gpio { |
| 332 | 326 | unsigned gpio; |
| @@ -334,7 +328,7 @@ gpio_request()前将这类细节配置好,例如使用 pinctrl 子系统的映 · 1 unmodified line | ||
| 334 | 328 | const char *label; |
| 335 | 329 | }; |
| 336 | 330 | |
| 337 | −一个典型的用例: | |
| 331 | +一个典型的用例:: | |
| 338 | 332 | |
| 339 | 333 | static struct gpio leds_gpios[] = { |
| 340 | 334 | { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* 默认开启 */ |
| @@ -356,9 +350,10 @@ gpio_request()前将这类细节配置好,例如使用 pinctrl 子系统的映 · 15 unmodified lines | ||
| 356 | 350 | |
| 357 | 351 | |
| 358 | 352 | GPIO 映射到 IRQ |
| 359 | −-------------------- | |
| 353 | +---------------- | |
| 354 | + | |
| 360 | 355 | GPIO 编号是无符号整数;IRQ 编号也是。这些构成了两个逻辑上不同的命名空间 |
| 361 | −(GPIO 0 不一定使用 IRQ 0)。你可以通过以下函数在它们之间实现映射: | |
| 356 | +(GPIO 0 不一定使用 IRQ 0)。你可以通过以下函数在它们之间实现映射:: | |
| 362 | 357 | |
| 363 | 358 | /* 映射 GPIO 编号到 IRQ 编号 */ |
| 364 | 359 | int gpio_to_irq(unsigned gpio); |
| @@ -384,7 +379,8 @@ irq_to_gpio()返回的非错误值大多数通常可以被 gpio_get_value()所 · 19 unmodified lines | ||
| 384 | 379 | |
| 385 | 380 | |
| 386 | 381 | 模拟开漏信号 |
| 387 | −---------------------------- | |
| 382 | +------------ | |
| 383 | + | |
| 388 | 384 | 有时在只有低电平信号作为实际驱动结果(译者注:多个输出连接于一点,逻辑电平 |
| 389 | 385 | 结果为所有输出的逻辑与)的时候,共享的信号线需要使用“开漏”信号。(该术语 |
| 390 | 386 | 适用于 CMOS 管;而 TTL 用“集电极开路”。)一个上拉电阻使信号为高电平。这 |
| @@ -408,9 +404,44 @@ irq_to_gpio()返回的非错误值大多数通常可以被 gpio_get_value()所 · 17 unmodified lines | ||
| 408 | 404 | 这不一定是错误的。一个常见的例子就是 I2C 时钟的延长:一个需要较慢时钟的 |
| 409 | 405 | 从设备延迟 SCK 的上升沿,而 I2C 主设备相应地调整其信号传输速率。 |
| 410 | 406 | |
| 407 | +GPIO控制器和引脚控制子系统 | |
| 408 | +-------------------------- | |
| 409 | + | |
| 410 | +SOC上的GPIO控制器可能与引脚控制子系统紧密结合,即引脚可以与可选的gpio功 | |
| 411 | +能一起被其他功能使用。我们已经涵盖了这样的情况,例如一个GPIO控制器需要保 | |
| 412 | +留一个引脚或通过调用以下任何一个引脚来设置其方向:: | |
| 413 | + | |
| 414 | + pinctrl_gpio_request() | |
| 415 | + pinctrl_gpio_free() | |
| 416 | + pinctrl_gpio_direction_input() | |
| 417 | + pinctrl_gpio_direction_output() | |
| 418 | + | |
| 419 | +但是,引脚控制子系统是如何将GPIO号码(这是一个全局事项)与某个引脚控制器 | |
| 420 | +上的某个引脚交叉关联的? | |
| 421 | + | |
| 422 | +这是通过注册引脚的“范围”来实现的,这基本上是交叉参考表。这些描述是在 | |
| 423 | +Documentation/driver-api/pin-control.rst | |
| 424 | + | |
| 425 | +虽然引脚分配完全由引脚控制子系统管理,但gpio(在gpiolib下)仍由gpio驱动 | |
| 426 | +维护。可能发生的情况是,SoC中的不同引脚范围由不同的gpio驱动器管理。 | |
| 427 | + | |
| 428 | +这使得在调用 "pinctrl_gpio_request" 之前,让gpio驱动向pin ctrl子系 | |
| 429 | +统宣布它们的引脚范围是合理的,以便在使用任何gpio之前要求引脚控制子系统准 | |
| 430 | +备相应的引脚。 | |
| 431 | + | |
| 432 | +为此,gpio控制器可以用引脚控制子系统注册其引脚范围。目前有两种方法:有或 | |
| 433 | +无DT。 | |
| 434 | + | |
| 435 | +关于对DT的支持,请参考 Documentation/devicetree/bindings/gpio/gpio.txt. | |
| 436 | + | |
| 437 | +对于非DT支持,用户可以用适当的参数调用gpiochip_add_pin_range(),将一 | |
| 438 | +系列的gpio引脚注册到引脚控制驱动上。为此,必须将引脚控制设备的名称字符串 | |
| 439 | +作为参数之一传给这个程序。 | |
| 440 | + | |
| 441 | + | |
| 442 | +这些公约忽略了什么? | |
| 443 | +==================== | |
| 411 | 444 | |
| 412 | −这些公约忽略了什么? | |
| 413 | −================ | |
| 414 | 445 | 这些公约忽略的最大一件事就是引脚复用,因为这属于高度芯片特定的属性且 |
| 415 | 446 | 没有可移植性。某个平台可能不需要明确的复用信息;有的对于任意给定的引脚 |
| 416 | 447 | 可能只有两个功能选项;有的可能每个引脚有八个功能选项;有的可能可以将 |
| @@ -433,8 +464,9 @@ Linux 的系统。) · 16 unmodified lines | ||
| 433 | 464 | 当前,动态定义 GPIO 并不是标准的,例如作为配置一个带有某些 GPIO 扩展器的 |
| 434 | 465 | 附加电路板的副作用。 |
| 435 | 466 | |
| 436 | −GPIO 实现者的框架 (可选) | |
| 437 | −===================== | |
| 467 | +GPIO 实现者的框架(可选) | |
| 468 | +========================= | |
| 469 | + | |
| 438 | 470 | 前面提到了,有一个可选的实现框架,让平台使用相同的编程接口,更加简单地支持 |
| 439 | 471 | 不同种类的 GPIO 控制器。这个框架称为"gpiolib"。 |
| 440 | 472 | |
| @@ -444,15 +476,16 @@ GPIO 实现者的框架 (可选) · 3 unmodified lines | ||
| 444 | 476 | |
| 445 | 477 | |
| 446 | 478 | 控制器驱动: gpio_chip |
| 447 | −------------------- | |
| 479 | +--------------------- | |
| 480 | + | |
| 448 | 481 | 在框架中每个 GPIO 控制器都包装为一个 "struct gpio_chip",他包含了 |
| 449 | 482 | 该类型的每个控制器的常用信息: |
| 450 | 483 | |
| 451 | − - 设置 GPIO 方向的方法 | |
| 452 | − - 用于访问 GPIO 值的方法 | |
| 453 | − - 告知调用其方法是否可能休眠的标志 | |
| 454 | − - 可选的 debugfs 信息导出方法 (显示类似上拉配置一样的额外状态) | |
| 455 | − - 诊断标签 | |
| 484 | + - 设置 GPIO 方向的方法 | |
| 485 | + - 用于访问 GPIO 值的方法 | |
| 486 | + - 告知调用其方法是否可能休眠的标志 | |
| 487 | + - 可选的 debugfs 信息导出方法 (显示类似上拉配置一样的额外状态) | |
| 488 | + - 诊断标签 | |
| 456 | 489 | |
| 457 | 490 | 也包含了来自 device.platform_data 的每个实例的数据:它第一个 GPIO 的 |
| 458 | 491 | 编号和它可用的 GPIO 的数量。 |
| @@ -471,7 +504,8 @@ GPIO 实现者的框架 (可选) · 12 unmodified lines | ||
| 471 | 504 | |
| 472 | 505 | |
| 473 | 506 | 平台支持 |
| 474 | −------- | |
| 507 | +-------- | |
| 508 | + | |
| 475 | 509 | 为了支持这个框架,一个平台的 Kconfig 文件将会 "select"(选择) |
| 476 | 510 | ARCH_REQUIRE_GPIOLIB 或 ARCH_WANT_OPTIONAL_GPIOLIB,并让它的 |
| 477 | 511 | <asm/gpio.h> 包含 <asm-generic/gpio.h>,同时定义三个方法: |
| @@ -489,7 +523,7 @@ ARCH_WANT_OPTIONAL_GPIOLIB 意味着 gpiolib 核心默认关闭,且用户可以 · 11 unmodified lines | ||
| 489 | 523 | 如果这些选项都没被选择,该平台就不通过 GPIO-lib 支持 GPIO,且代码不可以 |
| 490 | 524 | 被用户使能。 |
| 491 | 525 | |
| 492 | −以下这些方法的实现可以直接使用框架代码,并总是通过 gpio_chip 调度: | |
| 526 | +以下这些方法的实现可以直接使用框架代码,并总是通过 gpio_chip 调度:: | |
| 493 | 527 | |
| 494 | 528 | #define gpio_get_value __gpio_get_value |
| 495 | 529 | #define gpio_set_value __gpio_set_value |
| @@ -508,7 +542,8 @@ arch_initcall()或者更早的地方集成进平台初始化代码,使这些 G · 12 unmodified lines | ||
| 508 | 542 | 且他们通常可以作为 IRQ 使用。 |
| 509 | 543 | |
| 510 | 544 | 板级支持 |
| 511 | −------- | |
| 545 | +-------- | |
| 546 | + | |
| 512 | 547 | 对于外部 GPIO 控制器(例如 I2C 或 SPI 扩展器、专用芯片、多功能器件、FPGA |
| 513 | 548 | 或 CPLD),大多数常用板级特定代码都可以注册控制器设备,并保证他们的驱动知道 |
| 514 | 549 | gpiochip_add()所使用的 GPIO 编号。他们的起始编号通常跟在平台特定的 GPIO |
| @@ -526,8 +561,9 @@ GPIO 可以工作之后才可被注册。解决这类依赖的的一种方法是 · 11 unmodified lines | ||
| 526 | 561 | 设备变成无效时移除它们。 |
| 527 | 562 | |
| 528 | 563 | |
| 529 | −用户空间的 Sysfs 接口(可选) | |
| 530 | −======================== | |
| 564 | +用户空间的 Sysfs 接口(可选) | |
| 565 | +============================= | |
| 566 | + | |
| 531 | 567 | 使用“gpiolib”实现框架的平台可以选择配置一个 GPIO 的 sysfs 用户接口。 |
| 532 | 568 | 这不同于 debugfs 接口,因为它提供的是对 GPIO方向和值的控制,而不只显示 |
| 533 | 569 | 一个GPIO 的状态摘要。此外,它可以出现在没有调试支持的产品级系统中。 |
| @@ -548,6 +584,7 @@ GPIO 可以工作之后才可被注册。解决这类依赖的的一种方法是 · 14 unmodified lines | ||
| 548 | 584 | |
| 549 | 585 | Sysfs 中的路径 |
| 550 | 586 | -------------- |
| 587 | + | |
| 551 | 588 | 在/sys/class/gpio 中有 3 类入口: |
| 552 | 589 | |
| 553 | 590 | - 用于在用户空间控制 GPIO 的控制接口; |
| @@ -625,8 +662,9 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO · 71 unmodified lines | ||
| 625 | 662 | |
| 626 | 663 | |
| 627 | 664 | 从内核代码中导出 |
| 628 | −------------- | |
| 629 | −内核代码可以明确地管理那些已通过 gpio_request()申请的 GPIO 的导出: | |
| 665 | +---------------- | |
| 666 | + | |
| 667 | +内核代码可以明确地管理那些已通过 gpio_request()申请的 GPIO 的导出:: | |
| 630 | 668 | |
| 631 | 669 | /* 导出 GPIO 到用户空间 */ |
| 632 | 670 | int gpio_export(unsigned gpio, bool direction_may_change); |
| @@ -648,3 +686,9 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO · 15 unmodified lines | ||
| 648 | 686 | 在 GPIO 被导出之后,gpio_export_link()允许在 sysfs 文件系统的任何地方 |
| 649 | 687 | 创建一个到这个 GPIO sysfs 节点的符号链接。这样驱动就可以通过一个描述性的 |
| 650 | 688 | 名字,在 sysfs 中他们所拥有的设备下提供一个(到这个 GPIO sysfs 节点的)接口。 |
| 689 | + | |
| 690 | + | |
| 691 | +API参考 | |
| 692 | +======= | |
| 693 | + | |
| 694 | +本节中列出的函数已被废弃。在新的代码中应该使用基于GPIO描述符的API。 | |
| @@ -0,0 +1,132 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/driver-api/index.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 10 | + | |
| 11 | +:校译: | |
| 12 | + | |
| 13 | +======================== | |
| 14 | +Linux驱动实现者的API指南 | |
| 15 | +======================== | |
| 16 | + | |
| 17 | +内核提供了各种各样的接口来支持设备驱动的开发。这份文档只是对其中一些接口进行了 | |
| 18 | +一定程度的整理——希望随着时间的推移,它能变得更好!可用的小节可以在下面看到。 | |
| 19 | + | |
| 20 | +.. class:: toc-title | |
| 21 | + | |
| 22 | + 目录列表: | |
| 23 | + | |
| 24 | +.. toctree:: | |
| 25 | + :maxdepth: 2 | |
| 26 | + | |
| 27 | + gpio/index | |
| 28 | + io_ordering | |
| 29 | + | |
| 30 | +Todolist: | |
| 31 | + | |
| 32 | +* driver-model/index | |
| 33 | +* basics | |
| 34 | +* infrastructure | |
| 35 | +* ioctl | |
| 36 | +* early-userspace/index | |
| 37 | +* pm/index | |
| 38 | +* clk | |
| 39 | +* device-io | |
| 40 | +* dma-buf | |
| 41 | +* device_link | |
| 42 | +* component | |
| 43 | +* message-based | |
| 44 | +* infiniband | |
| 45 | +* aperture | |
| 46 | +* frame-buffer | |
| 47 | +* regulator | |
| 48 | +* reset | |
| 49 | +* iio/index | |
| 50 | +* input | |
| 51 | +* usb/index | |
| 52 | +* firewire | |
| 53 | +* pci/index | |
| 54 | +* cxl/index | |
| 55 | +* spi | |
| 56 | +* i2c | |
| 57 | +* ipmb | |
| 58 | +* ipmi | |
| 59 | +* i3c/index | |
| 60 | +* interconnect | |
| 61 | +* devfreq | |
| 62 | +* hsi | |
| 63 | +* edac | |
| 64 | +* scsi | |
| 65 | +* libata | |
| 66 | +* target | |
| 67 | +* mailbox | |
| 68 | +* mtdnand | |
| 69 | +* miscellaneous | |
| 70 | +* mei/index | |
| 71 | +* mtd/index | |
| 72 | +* mmc/index | |
| 73 | +* nvdimm/index | |
| 74 | +* w1 | |
| 75 | +* rapidio/index | |
| 76 | +* s390-drivers | |
| 77 | +* vme | |
| 78 | +* 80211/index | |
| 79 | +* uio-howto | |
| 80 | +* firmware/index | |
| 81 | +* pin-control | |
| 82 | +* md/index | |
| 83 | +* media/index | |
| 84 | +* misc_devices | |
| 85 | +* nfc/index | |
| 86 | +* dmaengine/index | |
| 87 | +* slimbus | |
| 88 | +* soundwire/index | |
| 89 | +* thermal/index | |
| 90 | +* fpga/index | |
| 91 | +* acpi/index | |
| 92 | +* auxiliary_bus | |
| 93 | +* backlight/lp855x-driver.rst | |
| 94 | +* connector | |
| 95 | +* console | |
| 96 | +* dcdbas | |
| 97 | +* eisa | |
| 98 | +* isa | |
| 99 | +* isapnp | |
| 100 | +* io-mapping | |
| 101 | +* generic-counter | |
| 102 | +* memory-devices/index | |
| 103 | +* men-chameleon-bus | |
| 104 | +* ntb | |
| 105 | +* nvmem | |
| 106 | +* parport-lowlevel | |
| 107 | +* pps | |
| 108 | +* ptp | |
| 109 | +* phy/index | |
| 110 | +* pwm | |
| 111 | +* pldmfw/index | |
| 112 | +* rfkill | |
| 113 | +* serial/index | |
| 114 | +* sm501 | |
| 115 | +* surface_aggregator/index | |
| 116 | +* switchtec | |
| 117 | +* sync_file | |
| 118 | +* tty/index | |
| 119 | +* vfio-mediated-device | |
| 120 | +* vfio | |
| 121 | +* vfio-pci-device-specific-driver-acceptance | |
| 122 | +* xilinx/index | |
| 123 | +* xillybus | |
| 124 | +* zorro | |
| 125 | +* hte/index | |
| 126 | + | |
| 127 | +.. only:: subproject and html | |
| 128 | + | |
| 129 | + Indices | |
| 130 | + ======= | |
| 131 | + | |
| 132 | + * :ref:`genindex` | |
| @@ -0,0 +1,60 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +.. include:: ../disclaimer-zh_CN.rst | |
| 4 | + | |
| 5 | +:Original: Documentation/driver-api/io_ordering.rst | |
| 6 | + | |
| 7 | +:翻译: | |
| 8 | + | |
| 9 | + 林永听 Lin Yongting <linyongting@gmail.com> | |
| 10 | + 司延腾 Yanteng Si <siyanteng@loongson.cn> | |
| 11 | + | |
| 12 | +:校译: | |
| 13 | + | |
| 14 | +=========================== | |
| 15 | +对内存映射地址的I/O写入排序 | |
| 16 | +=========================== | |
| 17 | + | |
| 18 | +在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任 | |
| 19 | +保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全” | |
| 20 | +设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作, | |
| 21 | +而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。 | |
| 22 | +这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存 | |
| 23 | +屏障操作,mb(),不过仅适用于I/O)。 | |
| 24 | + | |
| 25 | +假设一个设备驱动程的具体例子:: | |
| 26 | + | |
| 27 | + ... | |
| 28 | + CPU A: spin_lock_irqsave(&dev_lock, flags) | |
| 29 | + CPU A: val = readl(my_status); | |
| 30 | + CPU A: ... | |
| 31 | + CPU A: writel(newval, ring_ptr); | |
| 32 | + CPU A: spin_unlock_irqrestore(&dev_lock, flags) | |
| 33 | + ... | |
| 34 | + CPU B: spin_lock_irqsave(&dev_lock, flags) | |
| 35 | + CPU B: val = readl(my_status); | |
| 36 | + CPU B: ... | |
| 37 | + CPU B: writel(newval2, ring_ptr); | |
| 38 | + CPU B: spin_unlock_irqrestore(&dev_lock, flags) | |
| 39 | + ... | |
| 40 | + | |
| 41 | +上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就 | |
| 42 | +发生了。不过很容易通过下面方法来修复:: | |
| 43 | + | |
| 44 | + ... | |
| 45 | + CPU A: spin_lock_irqsave(&dev_lock, flags) | |
| 46 | + CPU A: val = readl(my_status); | |
| 47 | + CPU A: ... | |
| 48 | + CPU A: writel(newval, ring_ptr); | |
| 49 | + CPU A: (void)readl(safe_register); /* 配置寄存器?*/ | |
| 50 | + CPU A: spin_unlock_irqrestore(&dev_lock, flags) | |
| 51 | + ... | |
| 52 | + CPU B: spin_lock_irqsave(&dev_lock, flags) | |
| 53 | + CPU B: val = readl(my_status); | |
| 54 | + CPU B: ... | |
| 55 | + CPU B: writel(newval2, ring_ptr); | |
| 56 | + CPU B: (void)readl(safe_register); /* 配置寄存器?*/ | |
| 57 | + CPU B: spin_unlock_irqrestore(&dev_lock, flags) | |
| 58 | + | |
| 59 | +在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作, | |
| 60 | +再处理后面的读操作,防止引发数据不一致问题。 | |
| @@ -108,6 +108,7 @@ TODOList: · 107 unmodified lines | ||
| 108 | 108 | :maxdepth: 2 |
| 109 | 109 | |
| 110 | 110 | core-api/index |
| 111 | + driver-api/index | |
| 111 | 112 | locking/index |
| 112 | 113 | accounting/index |
| 113 | 114 | cpu-freq/index |
| @@ -120,10 +121,10 @@ TODOList: · 6 unmodified lines | ||
| 120 | 121 | scheduler/index |
| 121 | 122 | mm/index |
| 122 | 123 | peci/index |
| 124 | + PCI/index | |
| 123 | 125 | |
| 124 | 126 | TODOList: |
| 125 | 127 | |
| 126 | −* driver-api/index | |
| 127 | 128 | * block/index |
| 128 | 129 | * cdrom/index |
| 129 | 130 | * ide/index |
| @@ -148,7 +149,6 @@ TODOList: · 18 unmodified lines | ||
| 148 | 149 | * crypto/index |
| 149 | 150 | * bpf/index |
| 150 | 151 | * usb/index |
| 151 | −* PCI/index | |
| 152 | 152 | * scsi/index |
| 153 | 153 | * misc-devices/index |
| 154 | 154 | * mhi/index |
| @@ -1,67 +0,0 @@ | ||
| 1 | −Chinese translated version of Documentation/driver-api/io_ordering.rst | |
| 2 | − | |
| 3 | −If you have any comment or update to the content, please contact the | |
| 4 | −original document maintainer directly. However, if you have a problem | |
| 5 | −communicating in English you can also ask the Chinese maintainer for | |
| 6 | −help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | −or if there is a problem with the translation. | |
| 8 | − | |
| 9 | −Chinese maintainer: Lin Yongting <linyongting@gmail.com> | |
| 10 | −--------------------------------------------------------------------- | |
| 11 | −Documentation/driver-api/io_ordering.rst 的中文翻译 | |
| 12 | − | |
| 13 | −如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 14 | −交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 15 | −译存在问题,请联系中文版维护者。 | |
| 16 | − | |
| 17 | −中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com> | |
| 18 | −中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com> | |
| 19 | −中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com> | |
| 20 | − | |
| 21 | − | |
| 22 | −以下为正文 | |
| 23 | −--------------------------------------------------------------------- | |
| 24 | − | |
| 25 | −在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任 | |
| 26 | −保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全” | |
| 27 | −设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作, | |
| 28 | −而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。 | |
| 29 | −这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存 | |
| 30 | −屏障操作,mb(),不过仅适用于I/O)。 | |
| 31 | − | |
| 32 | −假设一个设备驱动程的具体例子: | |
| 33 | − | |
| 34 | − ... | |
| 35 | −CPU A: spin_lock_irqsave(&dev_lock, flags) | |
| 36 | −CPU A: val = readl(my_status); | |
| 37 | −CPU A: ... | |
| 38 | −CPU A: writel(newval, ring_ptr); | |
| 39 | −CPU A: spin_unlock_irqrestore(&dev_lock, flags) | |
| 40 | − ... | |
| 41 | −CPU B: spin_lock_irqsave(&dev_lock, flags) | |
| 42 | −CPU B: val = readl(my_status); | |
| 43 | −CPU B: ... | |
| 44 | −CPU B: writel(newval2, ring_ptr); | |
| 45 | −CPU B: spin_unlock_irqrestore(&dev_lock, flags) | |
| 46 | − ... | |
| 47 | − | |
| 48 | −上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就 | |
| 49 | −发生了。不过很容易通过下面方法来修复: | |
| 50 | − | |
| 51 | − ... | |
| 52 | −CPU A: spin_lock_irqsave(&dev_lock, flags) | |
| 53 | −CPU A: val = readl(my_status); | |
| 54 | −CPU A: ... | |
| 55 | −CPU A: writel(newval, ring_ptr); | |
| 56 | −CPU A: (void)readl(safe_register); /* 配置寄存器?*/ | |
| 57 | −CPU A: spin_unlock_irqrestore(&dev_lock, flags) | |
| 58 | − ... | |
| 59 | −CPU B: spin_lock_irqsave(&dev_lock, flags) | |
| 60 | −CPU B: val = readl(my_status); | |
| 61 | −CPU B: ... | |
| 62 | −CPU B: writel(newval2, ring_ptr); | |
| 63 | −CPU B: (void)readl(safe_register); /* 配置寄存器?*/ | |
| 64 | −CPU B: spin_unlock_irqrestore(&dev_lock, flags) | |
| 65 | − | |
| 66 | −在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作, | |
| 67 | −再处理后面的读操作,防止引发数据不一致问题。 | |
| @@ -1,212 +0,0 @@ | ||
| 1 | −Chinese translated version of Documentation/admin-guide/bug-hunting.rst | |
| 2 | − | |
| 3 | −If you have any comment or update to the content, please contact the | |
| 4 | −original document maintainer directly. However, if you have a problem | |
| 5 | −communicating in English you can also ask the Chinese maintainer for | |
| 6 | −help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | −or if there is a problem with the translation. | |
| 8 | − | |
| 9 | −Chinese maintainer: Dave Young <hidave.darkstar@gmail.com> | |
| 10 | −--------------------------------------------------------------------- | |
| 11 | −Documentation/admin-guide/bug-hunting.rst 的中文翻译 | |
| 12 | − | |
| 13 | −如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 14 | −交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 15 | −译存在问题,请联系中文版维护者。 | |
| 16 | − | |
| 17 | −中文版维护者: 杨瑞 Dave Young <hidave.darkstar@gmail.com> | |
| 18 | −中文版翻译者: 杨瑞 Dave Young <hidave.darkstar@gmail.com> | |
| 19 | −中文版校译者: 李阳 Li Yang <leoyang.li@nxp.com> | |
| 20 | − 王聪 Wang Cong <xiyou.wangcong@gmail.com> | |
| 21 | − | |
| 22 | −以下为正文 | |
| 23 | −--------------------------------------------------------------------- | |
| 24 | − | |
| 25 | −注意: ksymoops 在2.6中是没有用的。 请以原有格式使用Oops(来自dmesg,等等)。 | |
| 26 | −忽略任何这样那样关于“解码Oops”或者“通过ksymoops运行”的文档。 如果你贴出运行过 | |
| 27 | −ksymoops的来自2.6的Oops,人们只会让你重贴一次。 | |
| 28 | − | |
| 29 | −快速总结 | |
| 30 | −------------- | |
| 31 | − | |
| 32 | −发现Oops并发送给看似相关的内核领域的维护者。别太担心对不上号。如果你不确定就发给 | |
| 33 | −和你所做的事情相关的代码的负责人。 如果可重现试着描述怎样重构。 那甚至比oops更有 | |
| 34 | −价值。 | |
| 35 | − | |
| 36 | −如果你对于发送给谁一无所知, 发给linux-kernel@vger.kernel.org。感谢你帮助Linux | |
| 37 | −尽可能地稳定。 | |
| 38 | − | |
| 39 | −Oops在哪里? | |
| 40 | −---------------------- | |
| 41 | − | |
| 42 | −通常Oops文本由klogd从内核缓冲区里读取并传给syslogd,由syslogd写到syslog文件中, | |
| 43 | −典型地是/var/log/messages(依赖于/etc/syslog.conf)。有时klogd崩溃了,这种情况下你 | |
| 44 | −能够运行dmesg > file来从内核缓冲区中读取数据并保存下来。 否则你可以 | |
| 45 | −cat /proc/kmsg > file, 然而你必须介入中止传输, kmsg是一个“永不结束的文件”。如 | |
| 46 | −果机器崩溃坏到你不能输入命令或者磁盘不可用那么你有三种选择:- | |
| 47 | − | |
| 48 | −(1) 手抄屏幕上的文本待机器重启后再输入计算机。 麻烦但如果没有针对崩溃的准备, | |
| 49 | −这是仅有的选择。 另外,你可以用数码相机把屏幕拍下来-不太好,但比没有强。 如果信 | |
| 50 | −息滚动到了终端的上面,你会发现以高分辩率启动(比如,vga=791)会让你读到更多的文 | |
| 51 | −本。(注意:这需要vesafb,所以对‘早期’的oops没有帮助) | |
| 52 | − | |
| 53 | −(2)用串口终端启动(请参看Documentation/admin-guide/serial-console.rst),运行一个null | |
| 54 | −modem到另一台机器并用你喜欢的通讯工具获取输出。Minicom工作地很好。 | |
| 55 | − | |
| 56 | −(3)使用Kdump(请参看Documentation/admin-guide/kdump/kdump.rst), | |
| 57 | −使用在Documentation/admin-guide/kdump/gdbmacros.txt中定义的dmesg gdb宏,从旧的内存中提取内核 | |
| 58 | −环形缓冲区。 | |
| 59 | − | |
| 60 | −完整信息 | |
| 61 | −---------------- | |
| 62 | − | |
| 63 | −注意:以下来自于Linus的邮件适用于2.4内核。 我因为历史原因保留了它,并且因为其中 | |
| 64 | −一些信息仍然适用。 特别注意的是,请忽略任何ksymoops的引用。 | |
| 65 | − | |
| 66 | −From: Linus Torvalds <torvalds@osdl.org> | |
| 67 | − | |
| 68 | −怎样跟踪Oops.. [原发到linux-kernel的一封邮件] | |
| 69 | − | |
| 70 | −主要的窍门是有五年和这些烦人的oops消息打交道的经验;-) | |
| 71 | − | |
| 72 | −实际上,你有办法使它更简单。我有两个不同的方法: | |
| 73 | − | |
| 74 | − gdb /usr/src/linux/vmlinux | |
| 75 | − gdb> disassemble <offending_function> | |
| 76 | − | |
| 77 | −那是发现问题的简单办法,至少如果bug报告做的好的情况下(象这个一样-运行ksymoops | |
| 78 | −得到oops发生的函数及函数内的偏移)。 | |
| 79 | − | |
| 80 | −哦,如果报告发生的内核以相同的编译器和相似的配置编译它会有帮助的。 | |
| 81 | − | |
| 82 | −另一件要做的事是反汇编bug报告的“Code”部分:ksymoops也会用正确的工具来做这件事, | |
| 83 | −但如果没有那些工具你可以写一个傻程序: | |
| 84 | − | |
| 85 | − char str[] = "\xXX\xXX\xXX..."; | |
| 86 | − main(){} | |
| 87 | − | |
| 88 | −并用gcc -g编译它然后执行“disassemble str”(XX部分是由Oops报告的值-你可以仅剪切 | |
| 89 | −粘贴并用“\x”替换空格-我就是这么做的,因为我懒得写程序自动做这一切)。 | |
| 90 | − | |
| 91 | −另外,你可以用scripts/decodecode这个shell脚本。它的使用方法是: | |
| 92 | −decodecode < oops.txt | |
| 93 | − | |
| 94 | −“Code”之后的十六进制字节可能(在某些架构上)有一些当前指令之前的指令字节以及 | |
| 95 | −当前和之后的指令字节 | |
| 96 | − | |
| 97 | −Code: f9 0f 8d f9 00 00 00 8d 42 0c e8 dd 26 11 c7 a1 60 ea 2b f9 8b 50 08 a1 | |
| 98 | −64 ea 2b f9 8d 34 82 8b 1e 85 db 74 6d 8b 15 60 ea 2b f9 <8b> 43 04 39 42 54 | |
| 99 | −7e 04 40 89 42 54 8b 43 04 3b 05 00 f6 52 c0 | |
| 100 | − | |
| 101 | −最后,如果你想知道代码来自哪里,你可以: | |
| 102 | − | |
| 103 | − cd /usr/src/linux | |
| 104 | − make fs/buffer.s # 或任何产生BUG的文件 | |
| 105 | − | |
| 106 | −然后你会比gdb反汇编更清楚的知道发生了什么。 | |
| 107 | − | |
| 108 | −现在,问题是把你所拥有的所有数据结合起来:C源码(关于它应该怎样的一般知识), | |
| 109 | −汇编代码及其反汇编得到的代码(另外还有从“oops”消息得到的寄存器状态-对了解毁坏的 | |
| 110 | −指针有用,而且当你有了汇编代码你也能拿其它的寄存器和任何它们对应的C表达式做匹配 | |
| 111 | −)。 | |
| 112 | − | |
| 113 | −实际上,你仅需看看哪里不匹配(这个例子是“Code”反汇编和编译器生成的代码不匹配)。 | |
| 114 | −然后你须要找出为什么不匹配。通常很简单-你看到代码使用了空指针然后你看代码想知道 | |
| 115 | −空指针是怎么出现的,还有检查它是否合法.. | |
| 116 | − | |
| 117 | −现在,如果明白这是一项耗时的工作而且需要一丁点儿的专心,没错。这就是我为什么大多 | |
| 118 | −只是忽略那些没有符号表信息的崩溃报告的原因:简单的说太难查找了(我有一些 | |
| 119 | −程序用于在内核代码段中搜索特定的模式,而且有时我也已经能找出那些崩溃的地方,但是 | |
| 120 | −仅仅是找出正确的序列也确实需要相当扎实的内核知识) | |
| 121 | − | |
| 122 | −_有时_会发生这种情况,我仅看到崩溃中的反汇编代码序列, 然后我马上就明白问题出在 | |
| 123 | −哪里。这时我才意识到自己干这个工作已经太长时间了;-) | |
| 124 | − | |
| 125 | − Linus | |
| 126 | − | |
| 127 | − | |
| 128 | −--------------------------------------------------------------------------- | |
| 129 | −关于Oops跟踪的注解: | |
| 130 | − | |
| 131 | −为了帮助Linus和其它内核开发者,klogd纳入了大量的支持来处理保护错误。为了拥有对 | |
| 132 | −地址解析的完整支持至少应该使用1.3-pl3的sysklogd包。 | |
| 133 | − | |
| 134 | −当保护错误发生时,klogd守护进程自动把内核日志信息中的重要地址翻译成它们相应的符 | |
| 135 | −号。 | |
| 136 | − | |
| 137 | −klogd执行两种类型的地址解析。首先是静态翻译其次是动态翻译。静态翻译和ksymoops | |
| 138 | −一样使用System.map文件。为了做静态翻译klogd守护进程必须在初始化时能找到system | |
| 139 | −map文件。关于klogd怎样搜索map文件请参看klogd手册页。 | |
| 140 | − | |
| 141 | −动态地址翻译在使用内核可装载模块时很重要。 因为内核模块的内存是从内核动态内存池 | |
| 142 | −里分配的,所以不管是模块开始位置还是模块中函数和符号的位置都不是固定的。 | |
| 143 | − | |
| 144 | −内核支持允许程序决定装载哪些模块和它们在内存中位置的系统调用。使用这些系统调用 | |
| 145 | −klogd守护进程生成一张符号表用于调试发生在可装载模块中的保护错误。 | |
| 146 | − | |
| 147 | −至少klogd会提供产生保护错误的模块名。还可有额外的符号信息供可装载模块开发者选择 | |
| 148 | −以从模块中输出符号信息。 | |
| 149 | − | |
| 150 | −因为内核模块环境可能是动态的,所以必须有一种机制当模块环境发生改变时来通知klogd | |
| 151 | −守护进程。 有一些可用的命令行选项允许klogd向当前执行中的守护进程发送信号,告知符 | |
| 152 | −号信息应该被刷新了。 更多信息请参看klogd手册页。 | |
| 153 | − | |
| 154 | −sysklogd发布时包含一个补丁修改了modules-2.0.0包,无论何时一个模块装载或者卸载都 | |
| 155 | −会自动向klogd发送信号。打上这个补丁提供了必要的对调试发生于内核可装载模块的保护 | |
| 156 | −错误的无缝支持。 | |
| 157 | − | |
| 158 | −以下是被klogd处理过的发生在可装载模块中的一个保护错误例子: | |
| 159 | −--------------------------------------------------------------------------- | |
| 160 | −Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc | |
| 161 | −Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 | |
| 162 | −Aug 29 09:51:01 blizard kernel: *pde = 00000000 | |
| 163 | −Aug 29 09:51:01 blizard kernel: Oops: 0002 | |
| 164 | −Aug 29 09:51:01 blizard kernel: CPU: 0 | |
| 165 | −Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] | |
| 166 | −Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 | |
| 167 | −Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c | |
| 168 | −Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c | |
| 169 | −Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 | |
| 170 | −Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) | |
| 171 | −Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 | |
| 172 | −Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 | |
| 173 | −Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 | |
| 174 | −Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] | |
| 175 | −Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3 | |
| 176 | −--------------------------------------------------------------------------- | |
| 177 | − | |
| 178 | −Dr. G.W. Wettstein Oncology Research Div. Computing Facility | |
| 179 | −Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com | |
| 180 | −820 4th St. N. | |
| 181 | −Fargo, ND 58122 | |
| 182 | −Phone: 701-234-7556 | |
| 183 | − | |
| 184 | − | |
| 185 | −--------------------------------------------------------------------------- | |
| 186 | −受污染的内核 | |
| 187 | − | |
| 188 | −一些oops报告在程序记数器之后包含字符串'Tainted: '。这表明内核已经被一些东西给污 | |
| 189 | −染了。 该字符串之后紧跟着一系列的位置敏感的字符,每个代表一个特定的污染值。 | |
| 190 | − | |
| 191 | − 1:'G'如果所有装载的模块都有GPL或相容的许可证,'P'如果装载了任何的专有模块。 | |
| 192 | −没有模块MODULE_LICENSE或者带有insmod认为是与GPL不相容的的MODULE_LICENSE的模块被 | |
| 193 | −认定是专有的。 | |
| 194 | − | |
| 195 | − 2:'F'如果有任何通过“insmod -f”被强制装载的模块,' '如果所有模块都被正常装载。 | |
| 196 | − | |
| 197 | − 3:'S'如果oops发生在SMP内核中,运行于没有证明安全运行多处理器的硬件。 当前这种 | |
| 198 | −情况仅限于几种不支持SMP的速龙处理器。 | |
| 199 | − | |
| 200 | − 4:'R'如果模块通过“insmod -f”被强制装载,' '如果所有模块都被正常装载。 | |
| 201 | − | |
| 202 | − 5:'M'如果任何处理器报告了机器检查异常,' '如果没有发生机器检查异常。 | |
| 203 | − | |
| 204 | − 6:'B'如果页释放函数发现了一个错误的页引用或者一些非预期的页标志。 | |
| 205 | − | |
| 206 | − 7:'U'如果用户或者用户应用程序特别请求设置污染标志,否则' '。 | |
| 207 | − | |
| 208 | − 8:'D'如果内核刚刚死掉,比如有OOPS或者BUG。 | |
| 209 | − | |
| 210 | −使用'Tainted: '字符串的主要原因是要告诉内核调试者,这是否是一个干净的内核亦或发 | |
| 211 | −生了任何的不正常的事。污染是永久的:即使出错的模块已经被卸载了,污染值仍然存在, | |
| 212 | −以表明内核不再值得信任。 | |
| @@ -1,21 +1,23 @@ | ||
| 1 | 1 | .. include:: ../disclaimer-zh_CN.rst |
| 2 | 2 | |
| 3 | −:Original: :ref:`Documentation/process/coding-style.rst <codingstyle>` | |
| 3 | +:Original: Documentation/process/coding-style.rst | |
| 4 | 4 | |
| 5 | 5 | .. _cn_codingstyle: |
| 6 | 6 | |
| 7 | −译者:: | |
| 7 | +:译者: | |
| 8 | + - 张乐 Zhang Le <r0bertz@gentoo.org> | |
| 9 | + - Andy Deng <theandy.deng@gmail.com> | |
| 10 | + - 吴想成 <bobwxc@email.cn> | |
| 8 | 11 | |
| 9 | − 中文版维护者: 张乐 Zhang Le <r0bertz@gentoo.org> | |
| 10 | − 中文版翻译者: 张乐 Zhang Le <r0bertz@gentoo.org> | |
| 11 | − 中文版校译者: 王聪 Wang Cong <xiyou.wangcong@gmail.com> | |
| 12 | − wheelz <kernel.zeng@gmail.com> | |
| 13 | − 管旭东 Xudong Guan <xudong.guan@gmail.com> | |
| 14 | − Li Zefan <lizf@cn.fujitsu.com> | |
| 15 | − Wang Chen <wangchen@cn.fujitsu.com> | |
| 12 | +:校译: | |
| 13 | + - 王聪 Wang Cong <xiyou.wangcong@gmail.com> | |
| 14 | + - wheelz <kernel.zeng@gmail.com> | |
| 15 | + - 管旭东 Xudong Guan <xudong.guan@gmail.com> | |
| 16 | + - Li Zefan <lizf@cn.fujitsu.com> | |
| 17 | + - Wang Chen <wangchen@cn.fujitsu.com> | |
| 16 | 18 | |
| 17 | 19 | Linux 内核代码风格 |
| 18 | −========================= | |
| 20 | +================== | |
| 19 | 21 | |
| 20 | 22 | 这是一个简短的文档,描述了 linux 内核的首选代码风格。代码风格是因人而异的, |
| 21 | 23 | 而且我不愿意把自己的观点强加给任何人,但这就像我去做任何事情都必须遵循的原则 |
| @@ -29,7 +31,7 @@ Linux 内核代码风格 · 7 unmodified lines | ||
| 29 | 31 | |
| 30 | 32 | |
| 31 | 33 | 1) 缩进 |
| 32 | −-------------- | |
| 34 | +------- | |
| 33 | 35 | |
| 34 | 36 | 制表符是 8 个字符,所以缩进也是 8 个字符。有些异端运动试图将缩进变为 4 (甚至 |
| 35 | 37 | 2!) 字符深,这几乎相当于尝试将圆周率的值定义为 3。 |
| @@ -73,6 +75,22 @@ Linux 内核代码风格 · 37 unmodified lines | ||
| 73 | 75 | if (condition) do_this; |
| 74 | 76 | do_something_everytime; |
| 75 | 77 | |
| 78 | +不要使用逗号来避免使用大括号: | |
| 79 | + | |
| 80 | +.. code-block:: c | |
| 81 | + | |
| 82 | + if (condition) | |
| 83 | + do_this(), do_that(); | |
| 84 | + | |
| 85 | +使用大括号包裹多语句: | |
| 86 | + | |
| 87 | +.. code-block:: c | |
| 88 | + | |
| 89 | + if (condition) { | |
| 90 | + do_this(); | |
| 91 | + do_that(); | |
| 92 | + } | |
| 93 | + | |
| 76 | 94 | 也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读 |
| 77 | 95 | 的表达式。 |
| 78 | 96 | |
| @@ -83,20 +101,25 @@ Linux 内核代码风格 · 4 unmodified lines | ||
| 83 | 101 | |
| 84 | 102 | |
| 85 | 103 | 2) 把长的行和字符串打散 |
| 86 | −------------------------------ | |
| 104 | +----------------------- | |
| 87 | 105 | |
| 88 | 106 | 代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。 |
| 89 | 107 | |
| 90 | 108 | 每一行的长度的限制是 80 列,我们强烈建议您遵守这个惯例。 |
| 91 | 109 | |
| 92 | 110 | 长于 80 列的语句要打散成有意义的片段。除非超过 80 列能显著增加可读性,并且不 |
| 93 | −会隐藏信息。子片段要明显短于母片段,并明显靠右。这同样适用于有着很长参数列表 | |
| 94 | −的函数头。然而,绝对不要打散对用户可见的字符串,例如 printk 信息,因为这样就 | |
| 111 | +会隐藏信息。 | |
| 112 | + | |
| 113 | +子片段要明显短于母片段,并明显靠右。一种非常常用的样式是将子体与函数左括号对齐。 | |
| 114 | + | |
| 115 | +这同样适用于有着很长参数列表的函数头。 | |
| 116 | + | |
| 117 | +然而,绝对不要打散对用户可见的字符串,例如 printk 信息,因为这样就 | |
| 95 | 118 | 很难对它们 grep。 |
| 96 | 119 | |
| 97 | 120 | |
| 98 | 121 | 3) 大括号和空格的放置 |
| 99 | −------------------------------ | |
| 122 | +--------------------- | |
| 100 | 123 | |
| 101 | 124 | C 语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放 |
| 102 | 125 | 置策略并没有多少技术上的原因,不过首选的方式,就像 Kernighan 和 Ritchie 展示 |
| @@ -132,12 +155,12 @@ C 语言风格中另外一个常见问题是大括号的放置。和缩进大小 · 29 unmodified lines | ||
| 132 | 155 | body of function |
| 133 | 156 | } |
| 134 | 157 | |
| 135 | −全世界的异端可能会抱怨这个不一致性是... 呃... 不一致的,不过所有思维健全的人 | |
| 158 | +全世界的异端可能会抱怨这个不一致性是……呃……不一致,不过所有思维健全的人 | |
| 136 | 159 | 都知道 (a) K&R 是 **正确的** 并且 (b) K&R 是正确的。此外,不管怎样函数都是特 |
| 137 | 160 | 殊的 (C 函数是不能嵌套的)。 |
| 138 | 161 | |
| 139 | 162 | 注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是 do 语 |
| 140 | −句中的 "while" 或者 if 语句中的 "else",像这样: | |
| 163 | +句中的 ``while`` 或者 if 语句中的 ``else`` ,像这样: | |
| 141 | 164 | |
| 142 | 165 | .. code-block:: c |
| 143 | 166 | |
| @@ -191,7 +214,7 @@ C 语言风格中另外一个常见问题是大括号的放置。和缩进大小 · 47 unmodified lines | ||
| 191 | 214 | } |
| 192 | 215 | |
| 193 | 216 | 3.1) 空格 |
| 194 | −******************** | |
| 217 | +********* | |
| 195 | 218 | |
| 196 | 219 | Linux 内核的空格使用方式 (主要) 取决于它是用于函数还是关键字。(大多数) 关键字 |
| 197 | 220 | 后要加一个空格。值得注意的例外是 sizeof, typeof, alignof 和 __attribute__,这 |
| @@ -254,7 +277,7 @@ Linux 内核的空格使用方式 (主要) 取决于它是用于函数还是关 · 56 unmodified lines | ||
| 254 | 277 | |
| 255 | 278 | |
| 256 | 279 | 4) 命名 |
| 257 | −------------------------------ | |
| 280 | +------- | |
| 258 | 281 | |
| 259 | 282 | C 是一个简朴的语言,你的命名也应该这样。和 Modula-2 和 Pascal 程序员不同, |
| 260 | 283 | C 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C 程序员会 |
| @@ -275,11 +298,31 @@ C 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字 · 14 unmodified lines | ||
| 275 | 298 | 可能的话。类似的, ``tmp`` 可以用来称呼任意类型的临时变量。 |
| 276 | 299 | |
| 277 | 300 | 如果你怕混淆了你的本地变量名,你就遇到另一个问题了,叫做函数增长荷尔蒙失衡综 |
| 278 | −合症。请看第六章 (函数)。 | |
| 301 | +合征。请看第六章 (函数)。 | |
| 279 | 302 | |
| 303 | +对于符号名称和文档,避免引入新的“master/slave”(或独立于“master”的“slave”) | |
| 304 | +和“blacklist/whitelist”。 | |
| 305 | + | |
| 306 | +“master/slave”推荐替换为: | |
| 307 | + '{primary,main} / {secondary,replica,subordinate}' | |
| 308 | + '{initiator,requester} / {target,responder}' | |
| 309 | + '{controller,host} / {device,worker,proxy}' | |
| 310 | + 'leader/follower' | |
| 311 | + 'director/performer' | |
| 312 | + | |
| 313 | +“blacklist/whitelist”推荐替换为: | |
| 314 | + 'denylist/allowlist' | |
| 315 | + 'blocklist/passlist' | |
| 316 | + | |
| 317 | +引入新用法的例外情况是:维护用户空间ABI/API,或更新现有(截至2020年)硬件或 | |
| 318 | +协议规范的代码时要求这些术语。对于新规范,尽可能将术语的规范用法转换为内核 | |
| 319 | +编码标准。 | |
| 320 | + | |
| 321 | +.. warning:: | |
| 322 | + 以上主从、黑白名单规则不适用于中文文档,请勿更改中文术语! | |
| 280 | 323 | |
| 281 | 324 | 5) Typedef |
| 282 | −----------- | |
| 325 | +---------- | |
| 283 | 326 | |
| 284 | 327 | 不要使用类似 ``vps_t`` 之类的东西。 |
| 285 | 328 | |
| @@ -308,7 +351,7 @@ C 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字 · 22 unmodified lines | ||
| 308 | 351 | |
| 309 | 352 | .. note:: |
| 310 | 353 | |
| 311 | − 不透明性和 "访问函数" 本身是不好的。我们使用 pte_t 等类型的原因在于真 | |
| 354 | + 不透明性和“访问函数”本身是不好的。我们使用 pte_t 等类型的原因在于真 | |
| 312 | 355 | 的是完全没有任何共用的可访问信息。 |
| 313 | 356 | |
| 314 | 357 | (b) 清楚的整数类型,如此,这层抽象就可以 **帮助** 消除到底是 ``int`` 还是 |
| @@ -353,7 +396,7 @@ C 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字 · 38 unmodified lines | ||
| 353 | 396 | |
| 354 | 397 | |
| 355 | 398 | 6) 函数 |
| 356 | −------------------------------ | |
| 399 | +------- | |
| 357 | 400 | |
| 358 | 401 | 函数应该简短而漂亮,并且只完成一件事情。函数应该可以一屏或者两屏显示完 (我们 |
| 359 | 402 | 都知道 ISO/ANSI 屏幕大小是 80x24),只做一件事情,而且把它做好。 |
| @@ -383,12 +426,46 @@ C 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字 · 23 unmodified lines | ||
| 383 | 426 | } |
| 384 | 427 | EXPORT_SYMBOL(system_is_up); |
| 385 | 428 | |
| 386 | −在函数原型中,包含函数名和它们的数据类型。虽然 C 语言里没有这样的要求,在 | |
| 429 | +6.1) 函数原型 | |
| 430 | +************* | |
| 431 | + | |
| 432 | +在函数原型中包含参数名和它们的数据类型。虽然 C 语言里没有这样的要求,但在 | |
| 387 | 433 | Linux 里这是提倡的做法,因为这样可以很简单的给读者提供更多的有价值的信息。 |
| 388 | 434 | |
| 435 | +不要在函数声明里使用 ``extern`` 关键字,因为这会导致代码行变长,并且不是严格 | |
| 436 | +必需的。 | |
| 437 | + | |
| 438 | +写函数原型时,请保持 `元素顺序规则 <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_ 。 | |
| 439 | +例如下列函数声明:: | |
| 440 | + | |
| 441 | + __init void * __must_check action(enum magic value, size_t size, u8 count, | |
| 442 | + char *fmt, ...) __printf(4, 5) __malloc; | |
| 443 | + | |
| 444 | +推荐的函数原型元素顺序是: | |
| 445 | + | |
| 446 | +- 储存类型(下方的 ``static __always_inline`` ,注意 ``__always_inline`` | |
| 447 | + 技术上来讲是个属性但被当做 ``inline`` ) | |
| 448 | +- 储存类型属性(上方的 ``__init`` ——即节声明,但也像 ``__cold`` ) | |
| 449 | +- 返回类型(上方的 ``void *`` ) | |
| 450 | +- 返回类型属性(上方的 ``__must_check`` ) | |
| 451 | +- 函数名(上方的 ``action`` ) | |
| 452 | +- 函数参数(上方的 ``(enum magic value, size_t size, u8 count, char *fmt, ...)`` , | |
| 453 | + 注意必须写上参数名) | |
| 454 | +- 函数参数属性(上方的 ``__printf(4, 5)`` ) | |
| 455 | +- 函数行为属性(上方的 ``__malloc`` ) | |
| 456 | + | |
| 457 | +请注意,对于函数 **定义** (即实际函数体),编译器不允许在函数参数之后添加函 | |
| 458 | +数参数属性。在这种情况下,它们应该跟随存储类型属性(例如,与上面的 **声明** | |
| 459 | +示例相比,请注意下面的 ``__printf(4, 5)`` 的位置发生了变化):: | |
| 460 | + | |
| 461 | + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, | |
| 462 | + size_t size, u8 count, char *fmt, ...) __malloc | |
| 463 | + { | |
| 464 | + ... | |
| 465 | + } | |
| 389 | 466 | |
| 390 | 467 | 7) 集中的函数退出途径 |
| 391 | −------------------------------ | |
| 468 | +--------------------- | |
| 392 | 469 | |
| 393 | 470 | 虽然被某些人声称已经过时,但是 goto 语句的等价物还是经常被编译器所使用,具体 |
| 394 | 471 | 形式是无条件跳转指令。 |
| @@ -432,7 +509,7 @@ Linux 里这是提倡的做法,因为这样可以很简单的给读者提供 · 37 unmodified lines | ||
| 432 | 509 | return result; |
| 433 | 510 | } |
| 434 | 511 | |
| 435 | −一个需要注意的常见错误是 ``一个 err 错误`` ,就像这样: | |
| 512 | +一个需要注意的常见错误是 ``单 err 错误`` ,就像这样: | |
| 436 | 513 | |
| 437 | 514 | .. code-block:: c |
| 438 | 515 | |
| @@ -456,19 +533,19 @@ Linux 里这是提倡的做法,因为这样可以很简单的给读者提供 · 17 unmodified lines | ||
| 456 | 533 | |
| 457 | 534 | |
| 458 | 535 | 8) 注释 |
| 459 | −------------------------------ | |
| 536 | +------- | |
| 460 | 537 | |
| 461 | 538 | 注释是好的,不过有过度注释的危险。永远不要在注释里解释你的代码是如何运作的: |
| 462 | 539 | 更好的做法是让别人一看你的代码就可以明白,解释写的很差的代码是浪费时间。 |
| 463 | 540 | |
| 464 | −一般的,你想要你的注释告诉别人你的代码做了什么,而不是怎么做的。也请你不要把 | |
| 541 | +一般来说你用注释告诉别人你的代码做了什么,而不是怎么做的。也请你不要把 | |
| 465 | 542 | 注释放在一个函数体内部:如果函数复杂到你需要独立的注释其中的一部分,你很可能 |
| 466 | 543 | 需要回到第六章看一看。你可以做一些小注释来注明或警告某些很聪明 (或者槽糕) 的 |
| 467 | 544 | 做法,但不要加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么, |
| 468 | 545 | 也可以加上它做这些事情的原因。 |
| 469 | 546 | |
| 470 | −当注释内核 API 函数时,请使用 kernel-doc 格式。请看 | |
| 471 | −Documentation/doc-guide/ 和 scripts/kernel-doc 以获得详细信息。 | |
| 547 | +当注释内核 API 函数时,请使用 kernel-doc 格式。详见 | |
| 548 | +Documentation/translations/zh_CN/doc-guide/index.rst 和 scripts/kernel-doc 。 | |
| 472 | 549 | |
| 473 | 550 | 长 (多行) 注释的首选风格是: |
| 474 | 551 | |
| @@ -500,17 +577,18 @@ Documentation/doc-guide/ 和 scripts/kernel-doc 以获得详细信息。 · 25 unmodified lines | ||
| 500 | 577 | |
| 501 | 578 | |
| 502 | 579 | 9) 你已经把事情弄糟了 |
| 503 | −------------------------------ | |
| 580 | +--------------------- | |
| 504 | 581 | |
| 505 | −这没什么,我们都是这样。可能你的使用了很长时间 Unix 的朋友已经告诉你 | |
| 582 | +这没什么,我们都是这样。可能你长期使用 Unix 的朋友已经告诉你 | |
| 506 | 583 | ``GNU emacs`` 能自动帮你格式化 C 源代码,而且你也注意到了,确实是这样,不过它 |
| 507 | 584 | 所使用的默认值和我们想要的相去甚远 (实际上,甚至比随机打的还要差——无数个猴子 |
| 508 | −在 GNU emacs 里打字永远不会创造出一个好程序) (译注:Infinite Monkey Theorem) | |
| 585 | +在 GNU emacs 里打字永远不会创造出一个好程序) | |
| 586 | +*(译注:Infinite Monkey Theorem)* | |
| 509 | 587 | |
| 510 | 588 | 所以你要么放弃 GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案, |
| 511 | 589 | 你可以把下面这段粘贴到你的 .emacs 文件里。 |
| 512 | 590 | |
| 513 | −.. code-block:: none | |
| 591 | +.. code-block:: elisp | |
| 514 | 592 | |
| 515 | 593 | (defun c-lineup-arglist-tabs-only (ignored) |
| 516 | 594 | "Line up argument lists by tabs, not spaces" |
| @@ -529,7 +607,7 @@ Documentation/doc-guide/ 和 scripts/kernel-doc 以获得详细信息。 · 12 unmodified lines | ||
| 529 | 607 | (c-offsets-alist . ( |
| 530 | 608 | (arglist-close . c-lineup-arglist-tabs-only) |
| 531 | 609 | (arglist-cont-nonempty . |
| 532 | − (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) | |
| 610 | + (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) | |
| 533 | 611 | (arglist-intro . +) |
| 534 | 612 | (brace-list-intro . +) |
| 535 | 613 | (c . c-lineup-C-comments) |
| @@ -573,9 +651,14 @@ Documentation/doc-guide/ 和 scripts/kernel-doc 以获得详细信息。 · 37 unmodified lines | ||
| 573 | 651 | ``indent`` 有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册。 |
| 574 | 652 | 不过记住: ``indent`` 不能修正坏的编程习惯。 |
| 575 | 653 | |
| 654 | +请注意,您还可以使用 ``clang-format`` 工具帮助您处理这些规则,快速自动重新格 | |
| 655 | +式化部分代码,并审阅整个文件以发现代码风格错误、打字错误和可能的改进。它还可 | |
| 656 | +以方便地排序 ``#include`` ,对齐变量/宏,重排文本和其他类似任务。 | |
| 657 | +详见 Documentation/process/clang-format.rst 。 | |
| 658 | + | |
| 576 | 659 | |
| 577 | 660 | 10) Kconfig 配置文件 |
| 578 | −------------------------------ | |
| 661 | +-------------------- | |
| 579 | 662 | |
| 580 | 663 | 对于遍布源码树的所有 Kconfig* 配置文件来说,它们缩进方式有所不同。紧挨着 |
| 581 | 664 | ``config`` 定义的行,用一个制表符缩进,然而 help 信息的缩进则额外增加 2 个空 |
| @@ -598,11 +681,11 @@ Documentation/doc-guide/ 和 scripts/kernel-doc 以获得详细信息。 · 16 unmodified lines | ||
| 598 | 681 | depends on ADFS_FS |
| 599 | 682 | ... |
| 600 | 683 | |
| 601 | −要查看配置文件的完整文档,请看 Documentation/kbuild/kconfig-language.rst。 | |
| 684 | +要查看配置文件的完整文档,请看 Documentation/kbuild/kconfig-language.rst 。 | |
| 602 | 685 | |
| 603 | 686 | |
| 604 | 687 | 11) 数据结构 |
| 605 | −------------------------------ | |
| 688 | +------------ | |
| 606 | 689 | |
| 607 | 690 | 如果一个数据结构,在创建和销毁它的单线执行环境之外可见,那么它必须要有一个引 |
| 608 | 691 | 用计数器。内核里没有垃圾收集 (并且内核之外的垃圾收集慢且效率低下),这意味着你 |
| @@ -626,7 +709,7 @@ mm_count),和文件系统 (``struct super_block``: s_count 和 s_active) 中 · 17 unmodified lines | ||
| 626 | 709 | |
| 627 | 710 | |
| 628 | 711 | 12) 宏,枚举和RTL |
| 629 | −------------------------------ | |
| 712 | +----------------- | |
| 630 | 713 | |
| 631 | 714 | 用于定义常量的宏的名字及枚举里的标签需要大写。 |
| 632 | 715 | |
| @@ -638,7 +721,7 @@ mm_count),和文件系统 (``struct super_block``: s_count 和 s_active) 中 · 5 unmodified lines | ||
| 638 | 721 | |
| 639 | 722 | 宏的名字请用大写字母,不过形如函数的宏的名字可以用小写字母。 |
| 640 | 723 | |
| 641 | −一般的,如果能写成内联函数就不要写成像函数的宏。 | |
| 724 | +通常如果能写成内联函数就不要写成像函数的宏。 | |
| 642 | 725 | |
| 643 | 726 | 含有多个语句的宏应该被包含在一个 do-while 代码块里: |
| 644 | 727 | |
| @@ -696,18 +779,18 @@ mm_count),和文件系统 (``struct super_block``: s_count 和 s_active) 中 · 51 unmodified lines | ||
| 696 | 779 | (ret); \ |
| 697 | 780 | }) |
| 698 | 781 | |
| 699 | −ret 是本地变量的通用名字 - __foo_ret 更不容易与一个已存在的变量冲突。 | |
| 782 | +ret 是本地变量的通用名字—— __foo_ret 更不容易与一个已存在的变量冲突。 | |
| 700 | 783 | |
| 701 | 784 | cpp 手册对宏的讲解很详细。gcc internals 手册也详细讲解了 RTL,内核里的汇编语 |
| 702 | 785 | 言经常用到它。 |
| 703 | 786 | |
| 704 | 787 | |
| 705 | 788 | 13) 打印内核消息 |
| 706 | −------------------------------ | |
| 789 | +---------------- | |
| 707 | 790 | |
| 708 | −内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。 | |
| 791 | +内核开发者应该看起来有文化。请一定注意内核信息的拼写,以给人良好的印象。 | |
| 709 | 792 | 不要用不规范的单词比如 ``dont``,而要用 ``do not`` 或者 ``don't`` 。保证这些信 |
| 710 | −息简单明了,无歧义。 | |
| 793 | +息简单明了、无歧义。 | |
| 711 | 794 | |
| 712 | 795 | 内核信息不必以英文句号结束。 |
| 713 | 796 | |
| @@ -724,17 +807,18 @@ dev_info() 等等。对于那些不和某个特定设备相关连的信息,<li · 10 unmodified lines | ||
| 724 | 807 | 或设定了 CONFIG_DYNAMIC_DEBUG。实际这同样是为了 dev_dbg(),一个相关约定是在一 |
| 725 | 808 | 个已经开启了 DEBUG 时,使用 VERBOSE_DEBUG 来添加 dev_vdbg()。 |
| 726 | 809 | |
| 727 | −许多子系统拥有 Kconfig 调试选项来开启 -DDEBUG 在对应的 Makefile 里面;在其他 | |
| 810 | +许多子系统拥有 Kconfig 调试选项来开启对应 Makefile 里面的 -DDEBUG;在其他 | |
| 728 | 811 | 情况下,特殊文件使用 #define DEBUG。当一条调试信息需要被无条件打印时,例如, |
| 729 | 812 | 如果已经包含一个调试相关的 #ifdef 条件,printk(KERN_DEBUG ...) 就可被使用。 |
| 730 | 813 | |
| 731 | 814 | |
| 732 | 815 | 14) 分配内存 |
| 733 | −------------------------------ | |
| 816 | +------------ | |
| 734 | 817 | |
| 735 | 818 | 内核提供了下面的一般用途的内存分配函数: |
| 736 | 819 | kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() 和 vzalloc()。 |
| 737 | −请参考 API 文档以获取有关它们的详细信息。 | |
| 820 | +请参考 API 文档以获取有关它们的详细信息: | |
| 821 | +Documentation/translations/zh_CN/core-api/memory-allocation.rst 。 | |
| 738 | 822 | |
| 739 | 823 | 传递结构体大小的首选形式是这样的: |
| 740 | 824 | |
| @@ -761,11 +845,13 @@ kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() 和 vzalloc()。 · 20 unmodified lines | ||
| 761 | 845 | |
| 762 | 846 | p = kcalloc(n, sizeof(...), ...); |
| 763 | 847 | |
| 764 | −两种形式检查分配大小 n * sizeof(...) 的溢出,如果溢出返回 NULL。 | |
| 848 | +两种形式都会检查分配 n * sizeof(...) 大小时内存的溢出,如果溢出返回 NULL。 | |
| 765 | 849 | |
| 850 | +在没有 __GFP_NOWARN 的情况下使用时,这些通用分配函数都会在失败时发起堆栈转储, | |
| 851 | +因此当返回NULL时,没有必要发出额外的失败消息。 | |
| 766 | 852 | |
| 767 | 853 | 15) 内联弊病 |
| 768 | −------------------------------ | |
| 854 | +------------ | |
| 769 | 855 | |
| 770 | 856 | 有一个常见的误解是 ``内联`` 是 gcc 提供的可以让代码运行更快的一个选项。虽然使 |
| 771 | 857 | 用内联函数有时候是恰当的 (比如作为一种替代宏的方式,请看第十二章),不过很多情 |
| @@ -786,7 +872,7 @@ inline gcc 也可以自动使其内联。而且其他用户可能会要求移除 · 14 unmodified lines | ||
| 786 | 872 | |
| 787 | 873 | |
| 788 | 874 | 16) 函数返回值及命名 |
| 789 | −------------------------------ | |
| 875 | +-------------------- | |
| 790 | 876 | |
| 791 | 877 | 函数可以返回多种不同类型的值,最常见的一种是表明函数执行成功或者失败的值。这样 |
| 792 | 878 | 的一个值可以表示为一个错误代码整数 (-Exxx=失败,0=成功) 或者一个 ``成功`` |
| @@ -797,7 +883,7 @@ inline gcc 也可以自动使其内联。而且其他用户可能会要求移除 · 4 unmodified lines | ||
| 797 | 883 | 产生这种 bug,请遵循下面的惯例:: |
| 798 | 884 | |
| 799 | 885 | 如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代 |
| 800 | − 码整数。如果是一个判断,那么函数应该返回一个 "成功" 布尔值。 | |
| 886 | + 码整数。如果是一个判断,那么函数应该返回一个“成功”布尔值。 | |
| 801 | 887 | |
| 802 | 888 | 比如, ``add work`` 是一个命令,所以 add_work() 在成功时返回 0,在失败时返回 |
| 803 | 889 | -EBUSY。类似的,因为 ``PCI device present`` 是一个判断,所以 pci_dev_present() |
| @@ -806,13 +892,35 @@ inline gcc 也可以自动使其内联。而且其他用户可能会要求移除 · 2 unmodified lines | ||
| 806 | 892 | 所有 EXPORTed 函数都必须遵守这个惯例,所有的公共函数也都应该如此。私有 |
| 807 | 893 | (static) 函数不需要如此,但是我们也推荐这样做。 |
| 808 | 894 | |
| 809 | −返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。一般的, | |
| 895 | +返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。通常 | |
| 810 | 896 | 他们通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数, |
| 811 | 897 | 他们使用 NULL 或者 ERR_PTR 机制来报告错误。 |
| 812 | 898 | |
| 899 | +17) 使用布尔类型 | |
| 900 | +---------------- | |
| 901 | + | |
| 902 | +Linux内核布尔(bool)类型是C99 _Bool类型的别名。布尔值只能为0或1,而对布尔的 | |
| 903 | +隐式或显式转换将自动将值转换为true或false。在使用布尔类型时 **不需要** 构造, | |
| 904 | +它会消除一类错误。 | |
| 905 | + | |
| 906 | +使用布尔值时,应使用true和false定义,而不是1和0。 | |
| 813 | 907 | |
| 814 | −17) 不要重新发明内核宏 | |
| 815 | −------------------------------ | |
| 908 | +布尔函数返回类型和堆栈变量总是可以在适当的时候使用。鼓励使用布尔来提高可读性, | |
| 909 | +并且布尔值在存储时通常比“int”更好。 | |
| 910 | + | |
| 911 | +如果缓存行布局或值的大小很重要,请不要使用布尔,因为其大小和对齐方式根据编译 | |
| 912 | +的体系结构而不同。针对对齐和大小进行优化的结构体不应使用布尔。 | |
| 913 | + | |
| 914 | +如果一个结构体有多个true/false值,请考虑将它们合并为具有1比特成员的位域,或使 | |
| 915 | +用适当的固定宽度类型,如u8。 | |
| 916 | + | |
| 917 | +类似地,对于函数参数,多个true/false值可以合并为单个按位的“标志”参数,如果调 | |
| 918 | +用点具有裸true/false常量,“标志”参数通常是更具可读性的替代方法。 | |
| 919 | + | |
| 920 | +总之,在结构体和参数中有限地使用布尔可以提高可读性。 | |
| 921 | + | |
| 922 | +18) 不要重新发明内核宏 | |
| 923 | +---------------------- | |
| 816 | 924 | |
| 817 | 925 | 头文件 include/linux/kernel.h 包含了一些宏,你应该使用它们,而不要自己写一些 |
| 818 | 926 | 它们的变种。比如,如果你需要计算一个数组的长度,使用这个宏 |
| @@ -832,11 +940,11 @@ inline gcc 也可以自动使其内联。而且其他用户可能会要求移除 · 13 unmodified lines | ||
| 832 | 940 | 在你的代码里自己重新定义。 |
| 833 | 941 | |
| 834 | 942 | |
| 835 | −18) 编辑器模式行和其他需要罗嗦的事情 | |
| 836 | −-------------------------------------------------- | |
| 943 | +19) 编辑器模式行和其他需要罗嗦的事情 | |
| 944 | +------------------------------------ | |
| 837 | 945 | |
| 838 | 946 | 有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs |
| 839 | −能够解释被标记成这样的行: | |
| 947 | +能够解析被标记成这样的行: | |
| 840 | 948 | |
| 841 | 949 | .. code-block:: c |
| 842 | 950 | |
| @@ -852,7 +960,7 @@ inline gcc 也可以自动使其内联。而且其他用户可能会要求移除 · 9 unmodified lines | ||
| 852 | 960 | End: |
| 853 | 961 | */ |
| 854 | 962 | |
| 855 | −Vim 能够解释这样的标记: | |
| 963 | +Vim 能够解析这样的标记: | |
| 856 | 964 | |
| 857 | 965 | .. code-block:: c |
| 858 | 966 | |
| @@ -863,8 +971,8 @@ Vim 能够解释这样的标记: · 4 unmodified lines | ||
| 863 | 971 | 的模式,或者使用其他可以产生正确的缩进的巧妙方法。 |
| 864 | 972 | |
| 865 | 973 | |
| 866 | −19) 内联汇编 | |
| 867 | −------------------------------ | |
| 974 | +20) 内联汇编 | |
| 975 | +------------ | |
| 868 | 976 | |
| 869 | 977 | 在特定架构的代码中,你可能需要内联汇编与 CPU 和平台相关功能连接。需要这么做时 |
| 870 | 978 | 就不要犹豫。然而,当 C 可以完成工作时,不要平白无故地使用内联汇编。在可能的情 |
| @@ -880,8 +988,8 @@ Vim 能够解释这样的标记: · 9 unmodified lines | ||
| 880 | 988 | 移除了。你不必总是这样做,尽管,这不必要的举动会限制优化。 |
| 881 | 989 | |
| 882 | 990 | 在写一个包含多条指令的单个内联汇编语句时,把每条指令用引号分割而且各占一行, |
| 883 | −除了最后一条指令外,在每个指令结尾加上 \n\t,让汇编输出时可以正确地缩进下一条 | |
| 884 | −指令: | |
| 991 | +除了最后一条指令外,在每个指令结尾加上 ``\n\t`` ,让汇编输出时可以正确地缩进 | |
| 992 | +下一条指令: | |
| 885 | 993 | |
| 886 | 994 | .. code-block:: c |
| 887 | 995 | |
| @@ -890,10 +998,10 @@ Vim 能够解释这样的标记: · 2 unmodified lines | ||
| 890 | 998 | : /* outputs */ : /* inputs */ : /* clobbers */); |
| 891 | 999 | |
| 892 | 1000 | |
| 893 | −20) 条件编译 | |
| 894 | −------------------------------ | |
| 1001 | +21) 条件编译 | |
| 1002 | +------------ | |
| 895 | 1003 | |
| 896 | −只要可能,就不要在 .c 文件里面使用预处理条件 (#if, #ifdef);这样做让代码更难 | |
| 1004 | +只要可能,就不要在 .c 文件里面使用预处理条件 (#if, #ifdef);这样做会让代码更难 | |
| 897 | 1005 | 阅读并且更难去跟踪逻辑。替代方案是,在头文件中用预处理条件提供给那些 .c 文件 |
| 898 | 1006 | 使用,再给 #else 提供一个空桩 (no-op stub) 版本,然后在 .c 文件内无条件地调用 |
| 899 | 1007 | 那些 (定义在头文件内的) 函数。这样做,编译器会避免为桩函数 (stub) 的调用生成 |
| @@ -904,8 +1012,8 @@ Vim 能够解释这样的标记: · 4 unmodified lines | ||
| 904 | 1012 | 条件到这个辅助函数内。 |
| 905 | 1013 | |
| 906 | 1014 | 如果你有一个在特定配置中,可能变成未使用的函数或变量,编译器会警告它定义了但 |
| 907 | −未使用,把它标记为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而,如 | |
| 908 | −果一个函数或变量总是未使用,就直接删除它。) | |
| 1015 | +未使用,请把它标记为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而, | |
| 1016 | +如果一个函数或变量总是未使用,就直接删除它。) | |
| 909 | 1017 | |
| 910 | 1018 | 在代码中,尽可能地使用 IS_ENABLED 宏来转化某个 Kconfig 标记为 C 的布尔 |
| 911 | 1019 | 表达式,并在一般的 C 条件中使用它: |
| @@ -931,23 +1039,45 @@ Vim 能够解释这样的标记: · 19 unmodified lines | ||
| 931 | 1039 | #endif /* CONFIG_SOMETHING */ |
| 932 | 1040 | |
| 933 | 1041 | |
| 934 | −附录 I) 参考 | |
| 935 | −------------------- | |
| 1042 | +附录 I) 参考资料 | |
| 1043 | +---------------- | |
| 936 | 1044 | |
| 937 | −The C Programming Language, 第二版 | |
| 1045 | +The C Programming Language, 2nd Edition | |
| 938 | 1046 | 作者:Brian W. Kernighan 和 Denni M. Ritchie. |
| 939 | 1047 | Prentice Hall, Inc., 1988. |
| 940 | −ISBN 0-13-110362-8 (软皮), 0-13-110370-9 (硬皮). | |
| 1048 | +ISBN 0-13-110362-8 (平装), 0-13-110370-9 (精装). | |
| 1049 | + | |
| 1050 | +.. note:: | |
| 1051 | + | |
| 1052 | + 《C程序设计语言(第2版)》 | |
| 1053 | + 作者:[美] Brian W. Kernighan / [美] Dennis M. Ritchie | |
| 1054 | + 译者:徐宝文 / 李志 / 尤晋元(审校) | |
| 1055 | + 出版社:机械工业出版社,2019 | |
| 1056 | + ISBN:9787111617945 | |
| 941 | 1057 | |
| 942 | 1058 | The Practice of Programming |
| 943 | 1059 | 作者:Brian W. Kernighan 和 Rob Pike. |
| 944 | 1060 | Addison-Wesley, Inc., 1999. |
| 945 | 1061 | ISBN 0-201-61586-X. |
| 946 | 1062 | |
| 1063 | +.. note:: | |
| 1064 | + | |
| 1065 | + 《程序设计实践》 | |
| 1066 | + 作者:[美] Brian W. Kernighan / [美] Rob Pike | |
| 1067 | + 出版社:机械工业出版社,2005 | |
| 1068 | + ISBN:9787111091578 | |
| 1069 | + | |
| 1070 | + 《程序设计实践》 | |
| 1071 | + 作者:[美] Brian W. Kernighan / Rob Pike | |
| 1072 | + 译者:裘宗燕 | |
| 1073 | + 出版社:机械工业出版社,2000 | |
| 1074 | + ISBN:9787111075738 | |
| 1075 | + | |
| 947 | 1076 | GNU 手册 - 遵循 K&R 标准和此文本 - cpp, gcc, gcc internals and indent, |
| 948 | 1077 | 都可以从 https://www.gnu.org/manual/ 找到 |
| 949 | 1078 | |
| 950 | 1079 | WG14 是 C 语言的国际标准化工作组,URL: http://www.open-std.org/JTC1/SC22/WG14/ |
| 951 | 1080 | |
| 952 | −Kernel process/coding-style.rst,作者 greg@kroah.com 发表于 OLS 2002: | |
| 1081 | +内核文档 Documentation/process/coding-style.rst, | |
| 1082 | +作者 greg@kroah.com 发表于 OLS 2002: | |
| 953 | 1083 | http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ |
| @@ -1,17 +1,20 @@ | ||
| 1 | −.. _cn_email_clients: | |
| 1 | +.. SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | |
| 3 | 3 | .. include:: ../disclaimer-zh_CN.rst |
| 4 | 4 | |
| 5 | −:Original: :ref:`Documentation/process/email-clients.rst <email_clients>` | |
| 5 | +.. _cn_email_clients: | |
| 6 | 6 | |
| 7 | −译者:: | |
| 7 | +:Original: Documentation/process/email-clients.rst | |
| 8 | 8 | |
| 9 | − 中文版维护者: 贾威威 Harry Wei <harryxiyou@gmail.com> | |
| 10 | − 中文版翻译者: 贾威威 Harry Wei <harryxiyou@gmail.com> | |
| 11 | − 时奎亮 Alex Shi <alex.shi@linux.alibaba.com> | |
| 12 | − 中文版校译者: Yinglin Luan <synmyth@gmail.com> | |
| 13 | − Xiaochen Wang <wangxiaochen0@gmail.com> | |
| 14 | − yaxinsn <yaxinsn@163.com> | |
| 9 | +:译者: | |
| 10 | + - 贾威威 Harry Wei <harryxiyou@gmail.com> | |
| 11 | + - 时奎亮 Alex Shi <alexs@kernel.org> | |
| 12 | + - 吴想成 Wu XiangCheng <bobwxc@email.cn> | |
| 13 | + | |
| 14 | +:校译: | |
| 15 | + - Yinglin Luan <synmyth@gmail.com> | |
| 16 | + - Xiaochen Wang <wangxiaochen0@gmail.com> | |
| 17 | + - yaxinsn <yaxinsn@163.com> | |
| 15 | 18 | |
| 16 | 19 | Linux邮件客户端配置信息 |
| 17 | 20 | ======================= |
| @@ -27,12 +30,17 @@ Git · 9 unmodified lines | ||
| 27 | 30 | 改日志。如果工作正常,再将补丁发送到相应的邮件列表。 |
| 28 | 31 | |
| 29 | 32 | |
| 30 | −普通配置 | |
| 33 | +通用配置 | |
| 31 | 34 | -------- |
| 35 | + | |
| 32 | 36 | Linux内核补丁是通过邮件被提交的,最好把补丁作为邮件体的内嵌文本。有些维护者 |
| 33 | 37 | 接收附件,但是附件的内容格式应该是"text/plain"。然而,附件一般是不赞成的, |
| 34 | 38 | 因为这会使补丁的引用部分在评论过程中变的很困难。 |
| 35 | 39 | |
| 40 | +同时也强烈建议在补丁或其他邮件的正文中使用纯文本格式。https://useplaintext.email | |
| 41 | +有助于了解如何配置你喜欢的邮件客户端,并在您还没有首选的情况下列出一些推荐的 | |
| 42 | +客户端。 | |
| 43 | + | |
| 36 | 44 | 用来发送Linux内核补丁的邮件客户端在发送补丁时应该处于文本的原始状态。例如, |
| 37 | 45 | 他们不能改变或者删除制表符或者空格,甚至是在每一行的开头或者结尾。 |
| 38 | 46 | |
| @@ -40,17 +48,17 @@ Linux内核补丁是通过邮件被提交的,最好把补丁作为邮件体的 · 1 unmodified line | ||
| 40 | 48 | |
| 41 | 49 | 不要让你的邮件客户端进行自动换行。这样也会破坏你的补丁。 |
| 42 | 50 | |
| 43 | −邮件客户端不能改变文本的字符集编码方式。要发送的补丁只能是ASCII或者UTF-8编码方式, | |
| 44 | −如果你使用UTF-8编码方式发送邮件,那么你将会避免一些可能发生的字符集问题。 | |
| 51 | +邮件客户端不能改变文本的字符集编码方式。要发送的补丁只能是ASCII或者UTF-8编码 | |
| 52 | +方式,如果你使用UTF-8编码方式发送邮件,那么你将会避免一些可能发生的字符集问题。 | |
| 45 | 53 | |
| 46 | −邮件客户端应该形成并且保持 References: 或者 In-Reply-To: 标题,那么 | |
| 47 | −邮件话题就不会中断。 | |
| 54 | +邮件客户端应该生成并且保持“References:”或者“In-Reply-To:”邮件头,这样邮件会话 | |
| 55 | +就不会中断。 | |
| 48 | 56 | |
| 49 | −复制粘帖(或者剪贴粘帖)通常不能用于补丁,因为制表符会转换为空格。使用xclipboard, xclip | |
| 50 | −或者xcutsel也许可以,但是最好测试一下或者避免使用复制粘帖。 | |
| 57 | +复制粘帖(或者剪贴粘帖)通常不能用于补丁,因为制表符会转换为空格。使用xclipboard, | |
| 58 | +xclip或者xcutsel也许可以,但是最好测试一下或者避免使用复制粘帖。 | |
| 51 | 59 | |
| 52 | −不要在使用PGP/GPG署名的邮件中包含补丁。这样会使得很多脚本不能读取和适用于你的补丁。 | |
| 53 | −(这个问题应该是可以修复的) | |
| 60 | +不要在使用PGP/GPG签名的邮件中包含补丁。这样会使得很多脚本不能读取和适用于你的 | |
| 61 | +补丁。(这个问题应该是可以修复的) | |
| 54 | 62 | |
| 55 | 63 | 在给内核邮件列表发送补丁之前,给自己发送一个补丁是个不错的主意,保存接收到的 |
| 56 | 64 | 邮件,将补丁用'patch'命令打上,如果成功了,再给内核邮件列表发送。 |
| @@ -58,98 +66,133 @@ Linux内核补丁是通过邮件被提交的,最好把补丁作为邮件体的 · 1 unmodified line | ||
| 58 | 66 | |
| 59 | 67 | 一些邮件客户端提示 |
| 60 | 68 | ------------------ |
| 69 | + | |
| 61 | 70 | 这里给出一些详细的MUA配置提示,可以用于给Linux内核发送补丁。这些并不意味是 |
| 62 | 71 | 所有的软件包配置总结。 |
| 63 | 72 | |
| 64 | 73 | 说明: |
| 65 | −TUI = 以文本为基础的用户接口 | |
| 66 | −GUI = 图形界面用户接口 | |
| 74 | + | |
| 75 | +- TUI = 以文本为基础的用户接口 | |
| 76 | +- GUI = 图形界面用户接口 | |
| 67 | 77 | |
| 68 | 78 | Alpine (TUI) |
| 69 | −~~~~~~~~~~~~ | |
| 79 | +************ | |
| 70 | 80 | |
| 71 | 81 | 配置选项: |
| 72 | −在"Sending Preferences"部分: | |
| 73 | 82 | |
| 74 | −- "Do Not Send Flowed Text"必须开启 | |
| 75 | −- "Strip Whitespace Before Sending"必须关闭 | |
| 83 | +在 :menuselection:`Sending Preferences` 菜单: | |
| 84 | + | |
| 85 | +- :menuselection:`Do Not Send Flowed Text` 必须开启 | |
| 86 | +- :menuselection:`Strip Whitespace Before Sending` 必须关闭 | |
| 87 | + | |
| 88 | +当写邮件时,光标应该放在补丁会出现的地方,然后按下 :kbd:`CTRL-R` 组合键,使指 | |
| 89 | +定的补丁文件嵌入到邮件中。 | |
| 90 | + | |
| 91 | +Claws Mail (GUI) | |
| 92 | +**************** | |
| 93 | + | |
| 94 | +可以用,有人用它成功地发过补丁。 | |
| 76 | 95 | |
| 77 | −当写邮件时,光标应该放在补丁会出现的地方,然后按下CTRL-R组合键,使指定的 | |
| 78 | −补丁文件嵌入到邮件中。 | |
| 96 | +用 :menuselection:`Message-->Insert File` (:kbd:`CTRL-I`) 或外置编辑器插入补丁。 | |
| 97 | + | |
| 98 | +若要在Claws编辑窗口重修改插入的补丁,需关闭 | |
| 99 | +:menuselection:`Configuration-->Preferences-->Compose-->Wrapping` | |
| 100 | +的 `Auto wrapping` 。 | |
| 79 | 101 | |
| 80 | 102 | Evolution (GUI) |
| 81 | −~~~~~~~~~~~~~~~ | |
| 103 | +*************** | |
| 82 | 104 | |
| 83 | −一些开发者成功的使用它发送补丁 | |
| 105 | +一些开发者成功的使用它发送补丁。 | |
| 84 | 106 | |
| 85 | −当选择邮件选项:Preformat | |
| 86 | − 从Format->Heading->Preformatted (Ctrl-7)或者工具栏 | |
| 107 | +撰写邮件时: | |
| 108 | +从 :menuselection:`格式-->段落样式-->预格式化` (:kbd:`CTRL-7`) | |
| 109 | +或工具栏选择 :menuselection:`预格式化` ; | |
| 87 | 110 | |
| 88 | 111 | 然后使用: |
| 89 | − Insert->Text File... (Alt-n x)插入补丁文件。 | |
| 112 | +:menuselection:`插入-->文本文件...` (:kbd:`ALT-N x`) 插入补丁文件。 | |
| 90 | 113 | |
| 91 | −你还可以"diff -Nru old.c new.c | xclip",选择Preformat,然后使用中间键进行粘帖。 | |
| 114 | +你还可以 ``diff -Nru old.c new.c | xclip`` ,选择 :menuselection:`预格式化` , | |
| 115 | +然后使用鼠标中键进行粘帖。 | |
| 92 | 116 | |
| 93 | 117 | Kmail (GUI) |
| 94 | −~~~~~~~~~~~ | |
| 118 | +*********** | |
| 95 | 119 | |
| 96 | 120 | 一些开发者成功的使用它发送补丁。 |
| 97 | 121 | |
| 98 | −默认设置不为HTML格式是合适的;不要启用它。 | |
| 122 | +默认撰写设置禁用HTML格式是合适的;不要启用它。 | |
| 99 | 123 | |
| 100 | −当书写一封邮件的时候,在选项下面不要选择自动换行。唯一的缺点就是你在邮件中输入的任何文本 | |
| 101 | −都不会被自动换行,因此你必须在发送补丁之前手动换行。最简单的方法就是启用自动换行来书写邮件, | |
| 102 | −然后把它保存为草稿。一旦你在草稿中再次打开它,它已经全部自动换行了,那么你的邮件虽然没有 | |
| 103 | −选择自动换行,但是还不会失去已有的自动换行。 | |
| 124 | +当书写一封邮件的时候,在选项下面不要选择自动换行。唯一的缺点就是你在邮件中输 | |
| 125 | +入的任何文本都不会被自动换行,因此你必须在发送补丁之前手动换行。最简单的方法 | |
| 126 | +就是启用自动换行来书写邮件,然后把它保存为草稿。一旦你在草稿中再次打开它,它 | |
| 127 | +已经全部自动换行了,那么你的邮件虽然没有选择自动换行,但是还不会失去已有的自 | |
| 128 | +动换行。 | |
| 104 | 129 | |
| 105 | −在邮件的底部,插入补丁之前,放上常用的补丁定界符:三个连字号(---)。 | |
| 130 | +在邮件的底部,插入补丁之前,放上常用的补丁定界符:三个连字符(``---``)。 | |
| 106 | 131 | |
| 107 | −然后在"Message"菜单条目,选择插入文件,接着选取你的补丁文件。还有一个额外的选项,你可以 | |
| 108 | −通过它配置你的邮件建立工具栏菜单,还可以带上"insert file"图标。 | |
| 132 | +然后在 :menuselection:`信件` 菜单,选择 :menuselection:`插入文本文件` ,接 | |
| 133 | +着选取你的补丁文件。还有一个额外的选项,你可以通过它配置你的创建新邮件工具栏, | |
| 134 | +加上 :menuselection:`插入文本文件` 图标。 | |
| 109 | 135 | |
| 110 | −你可以安全地通过GPG标记附件,但是内嵌补丁最好不要使用GPG标记它们。作为内嵌文本的签发补丁, | |
| 111 | −当从GPG中提取7位编码时会使他们变的更加复杂。 | |
| 136 | +将编辑器窗口拉到足够宽避免折行。对于KMail 1.13.5 (KDE 4.5.4),它会在发送邮件 | |
| 137 | +时对编辑器窗口中显示折行的地方自动换行。在选项菜单中取消自动换行仍不能解决。 | |
| 138 | +因此,如果你的补丁中有非常长的行,必须在发送之前把编辑器窗口拉得非常宽。 | |
| 139 | +参见:https://bugs.kde.org/show_bug.cgi?id=174034 | |
| 112 | 140 | |
| 113 | −如果你非要以附件的形式发送补丁,那么就右键点击附件,然后选中属性,突出"Suggest automatic | |
| 114 | −display",这样内嵌附件更容易让读者看到。 | |
| 141 | +你可以安全地用GPG签名附件,但是内嵌补丁最好不要使用GPG签名它们。作为内嵌文本 | |
| 142 | +插入的签名补丁将使其难以从7-bit编码中提取。 | |
| 115 | 143 | |
| 116 | −当你要保存将要发送的内嵌文本补丁,你可以从消息列表窗格选择包含补丁的邮件,然后右击选择 | |
| 117 | −"save as"。你可以使用一个没有更改的包含补丁的邮件,如果它是以正确的形式组成。当你正真在它 | |
| 118 | −自己的窗口之下察看,那时没有选项可以保存邮件--已经有一个这样的bug被汇报到了kmail的bugzilla | |
| 119 | −并且希望这将会被处理。邮件是以只针对某个用户可读写的权限被保存的,所以如果你想把邮件复制到其他地方, | |
| 120 | −你不得不把他们的权限改为组或者整体可读。 | |
| 144 | +如果你非要以附件的形式发送补丁,那么就右键点击附件,然后选择 | |
| 145 | +:menuselection:`属性` ,打开 :menuselection:`建议自动显示` ,使附件内联更容 | |
| 146 | +易让读者看到。 | |
| 147 | + | |
| 148 | +当你要保存将要发送的内嵌文本补丁,你可以从消息列表窗格选择包含补丁的邮件,然 | |
| 149 | +后右键选择 :menuselection:`另存为` 。如果整个电子邮件的组成正确,您可直接将 | |
| 150 | +其作为补丁使用。电子邮件以当前用户可读写权限保存,因此您必须 ``chmod`` ,以 | |
| 151 | +使其在复制到别处时用户组和其他人可读。 | |
| 121 | 152 | |
| 122 | 153 | Lotus Notes (GUI) |
| 123 | −~~~~~~~~~~~~~~~~~ | |
| 154 | +***************** | |
| 124 | 155 | |
| 125 | 156 | 不要使用它。 |
| 126 | 157 | |
| 158 | +IBM Verse (Web GUI) | |
| 159 | +******************* | |
| 160 | + | |
| 161 | +同上条。 | |
| 162 | + | |
| 127 | 163 | Mutt (TUI) |
| 128 | −~~~~~~~~~~ | |
| 164 | +********** | |
| 165 | + | |
| 166 | +很多Linux开发人员使用mutt客户端,这证明它肯定工作得非常漂亮。 | |
| 129 | 167 | |
| 130 | −很多Linux开发人员使用mutt客户端,所以证明它肯定工作的非常漂亮。 | |
| 168 | +Mutt不自带编辑器,所以不管你使用什么编辑器,不自动断行就行。大多数编辑器都有 | |
| 169 | +:menuselection:`插入文件` 选项,它可以在不改变文件内容的情况下插入文件。 | |
| 131 | 170 | |
| 132 | −Mutt不自带编辑器,所以不管你使用什么编辑器都不应该带有自动断行。大多数编辑器都带有 | |
| 133 | −一个"insert file"选项,它可以通过不改变文件内容的方式插入文件。 | |
| 171 | +用 ``vim`` 作为mutt的编辑器:: | |
| 134 | 172 | |
| 135 | −'vim'作为mutt的编辑器: | |
| 136 | 173 | set editor="vi" |
| 137 | 174 | |
| 138 | − 如果使用xclip,敲入以下命令 | |
| 175 | +如果使用xclip,敲入以下命令:: | |
| 176 | + | |
| 139 | 177 | :set paste |
| 140 | − 按中键之前或者shift-insert或者使用 | |
| 178 | + | |
| 179 | +然后再按中键或者shift-insert或者使用:: | |
| 180 | + | |
| 141 | 181 | :r filename |
| 142 | 182 | |
| 143 | −如果想要把补丁作为内嵌文本。 | |
| 144 | −(a)ttach工作的很好,不带有"set paste"。 | |
| 183 | +把补丁插入为内嵌文本。 | |
| 184 | +在未设置 ``set paste`` 时(a)ttach工作的很好。 | |
| 145 | 185 | |
| 146 | 186 | 你可以通过 ``git format-patch`` 生成补丁,然后用 Mutt发送它们:: |
| 147 | 187 | |
| 148 | − $ mutt -H 0001-some-bug-fix.patch | |
| 188 | + $ mutt -H 0001-some-bug-fix.patch | |
| 149 | 189 | |
| 150 | 190 | 配置选项: |
| 191 | + | |
| 151 | 192 | 它应该以默认设置的形式工作。 |
| 152 | −然而,把"send_charset"设置为"us-ascii::utf-8"也是一个不错的主意。 | |
| 193 | +然而,把 ``send_charset`` 设置一下也是一个不错的主意:: | |
| 194 | + | |
| 195 | + set send_charset="us-ascii:utf-8" | |
| 153 | 196 | |
| 154 | 197 | Mutt 是高度可配置的。 这里是个使用mutt通过 Gmail 发送的补丁的最小配置:: |
| 155 | 198 | |
| @@ -178,71 +221,107 @@ Mutt 是高度可配置的。 这里是个使用mutt通过 Gmail 发送的补丁 · 22 unmodified lines | ||
| 178 | 221 | set from = "username@gmail.com" |
| 179 | 222 | set use_from = yes |
| 180 | 223 | |
| 181 | −Mutt文档含有更多信息: | |
| 224 | +Mutt文档含有更多信息: | |
| 182 | 225 | |
| 183 | − http://dev.mutt.org/trac/wiki/UseCases/Gmail | |
| 226 | + https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail | |
| 184 | 227 | |
| 185 | − http://dev.mutt.org/doc/manual.html | |
| 228 | + http://www.mutt.org/doc/manual/ | |
| 186 | 229 | |
| 187 | 230 | Pine (TUI) |
| 188 | −~~~~~~~~~~ | |
| 231 | +********** | |
| 189 | 232 | |
| 190 | 233 | Pine过去有一些空格删减问题,但是这些现在应该都被修复了。 |
| 191 | 234 | |
| 192 | −如果可以,请使用alpine(pine的继承者) | |
| 235 | +如果可以,请使用alpine(pine的继承者)。 | |
| 193 | 236 | |
| 194 | 237 | 配置选项: |
| 195 | −- 最近的版本需要消除流程文本 | |
| 196 | −- "no-strip-whitespace-before-send"选项也是需要的。 | |
| 238 | + | |
| 239 | +- 最近的版本需要 ``quell-flowed-text`` | |
| 240 | +- ``no-strip-whitespace-before-send`` 选项也是需要的。 | |
| 197 | 241 | |
| 198 | 242 | |
| 199 | 243 | Sylpheed (GUI) |
| 200 | −~~~~~~~~~~~~~~ | |
| 244 | +************** | |
| 201 | 245 | |
| 202 | 246 | - 内嵌文本可以很好的工作(或者使用附件)。 |
| 203 | 247 | - 允许使用外部的编辑器。 |
| 204 | −- 对于目录较多时非常慢。 | |
| 248 | +- 收件箱较多时非常慢。 | |
| 205 | 249 | - 如果通过non-SSL连接,无法使用TLS SMTP授权。 |
| 206 | −- 在组成窗口中有一个很有用的ruler bar。 | |
| 207 | −- 给地址本中添加地址就不会正确的了解显示名。 | |
| 250 | +- 撰写窗口的标尺很有用。 | |
| 251 | +- 将地址添加到通讯簿时无法正确理解显示的名称。 | |
| 208 | 252 | |
| 209 | 253 | Thunderbird (GUI) |
| 210 | −~~~~~~~~~~~~~~~~~ | |
| 254 | +***************** | |
| 255 | + | |
| 256 | +Thunderbird是Outlook的克隆版本,它很容易损坏文本,但也有一些方法强制修正。 | |
| 257 | + | |
| 258 | +在完成修改后(包括安装扩展),您需要重新启动Thunderbird。 | |
| 259 | + | |
| 260 | +- 允许使用外部编辑器: | |
| 261 | + | |
| 262 | + 使用Thunderbird发补丁最简单的方法是使用扩展来打开您最喜欢的外部编辑器。 | |
| 263 | + | |
| 264 | + 下面是一些能够做到这一点的扩展样例。 | |
| 265 | + | |
| 266 | + - “External Editor Revived” | |
| 267 | + | |
| 268 | + https://github.com/Frederick888/external-editor-revived | |
| 269 | + | |
| 270 | + https://addons.thunderbird.net/en-GB/thunderbird/addon/external-editor-revived/ | |
| 271 | + | |
| 272 | + 它需要安装“本地消息主机(native messaging host)”。 | |
| 273 | + 参见以下文档: | |
| 274 | + https://github.com/Frederick888/external-editor-revived/wiki | |
| 275 | + | |
| 276 | + - “External Editor” | |
| 277 | + | |
| 278 | + https://github.com/exteditor/exteditor | |
| 279 | + | |
| 280 | + 下载并安装此扩展,然后打开 :menuselection:`新建消息` 窗口, 用 | |
| 281 | + :menuselection:`查看-->工具栏-->自定义...` 给它增加一个按钮,直接点击此 | |
| 282 | + 按钮即可使用外置编辑器。 | |
| 283 | + | |
| 284 | + 请注意,“External Editor”要求你的编辑器不能fork,换句话说,编辑器必须在 | |
| 285 | + 关闭前不返回。你可能需要传递额外的参数或修改编辑器设置。最值得注意的是, | |
| 286 | + 如果您使用的是gvim,那么您必须将 :menuselection:`external editor` 设置的 | |
| 287 | + 编辑器字段设置为 ``/usr/bin/gvim --nofork"`` (假设可执行文件在 | |
| 288 | + ``/usr/bin`` ),以传递 ``-f`` 参数。如果您正在使用其他编辑器,请阅读其 | |
| 289 | + 手册了解如何处理。 | |
| 211 | 290 | |
| 212 | −默认情况下,thunderbird很容易损坏文本,但是还有一些方法可以强制它变得更好。 | |
| 291 | +若要修正内部编辑器,请执行以下操作: | |
| 213 | 292 | |
| 214 | −- 在用户帐号设置里,组成和寻址,不要选择"Compose messages in HTML format"。 | |
| 293 | +- 修改你的Thunderbird设置,不要使用 ``format=flowed`` ! | |
| 294 | + 回到主窗口,按照 | |
| 295 | + :menuselection:`主菜单-->首选项-->常规-->配置编辑器...` | |
| 296 | + 打开Thunderbird的配置编辑器。 | |
| 215 | 297 | |
| 216 | −- 编辑你的Thunderbird配置设置来使它不要拆行使用:user_pref("mailnews.wraplength", 0); | |
| 298 | + - 将 ``mailnews.send_plaintext_flowed`` 设为 ``false`` | |
| 217 | 299 | |
| 218 | −- 编辑你的Thunderbird配置设置,使它不要使用"format=flowed"格式:user_pref("mailnews. | |
| 219 | − send_plaintext_flowed", false); | |
| 300 | + - 将 ``mailnews.wraplength`` 从 ``72`` 改为 ``0`` | |
| 220 | 301 | |
| 221 | −- 你需要使Thunderbird变为预先格式方式: | |
| 222 | − 如果默认情况下你书写的是HTML格式,那不是很难。仅仅从标题栏的下拉框中选择"Preformat"格式。 | |
| 223 | − 如果默认情况下你书写的是文本格式,你不得把它改为HTML格式(仅仅作为一次性的)来书写新的消息, | |
| 224 | − 然后强制使它回到文本格式,否则它就会拆行。要实现它,在写信的图标上使用shift键来使它变为HTML | |
| 225 | − 格式,然后标题栏的下拉框中选择"Preformat"格式。 | |
| 302 | +- 不要写HTML邮件! | |
| 303 | + 回到主窗口,打开 | |
| 304 | + :menuselection:`主菜单-->账户设置-->你的@邮件.地址-->通讯录/编写&地址簿` , | |
| 305 | + 关掉 ``以HTML格式编写消息`` 。 | |
| 226 | 306 | |
| 227 | −- 允许使用外部的编辑器: | |
| 228 | − 针对Thunderbird打补丁最简单的方法就是使用一个"external editor"扩展,然后使用你最喜欢的 | |
| 229 | − $EDITOR来读取或者合并补丁到文本中。要实现它,可以下载并且安装这个扩展,然后添加一个使用它的 | |
| 230 | − 按键View->Toolbars->Customize...最后当你书写信息的时候仅仅点击它就可以了。 | |
| 307 | +- 只用纯文本格式查看邮件! | |
| 308 | + 回到主窗口, :menuselection:`主菜单-->查看-->消息体为-->纯文本` ! | |
| 231 | 309 | |
| 232 | 310 | TkRat (GUI) |
| 233 | −~~~~~~~~~~~ | |
| 311 | +*********** | |
| 234 | 312 | |
| 235 | 313 | 可以使用它。使用"Insert file..."或者外部的编辑器。 |
| 236 | 314 | |
| 237 | 315 | Gmail (Web GUI) |
| 238 | −~~~~~~~~~~~~~~~ | |
| 316 | +*************** | |
| 239 | 317 | |
| 240 | 318 | 不要使用它发送补丁。 |
| 241 | 319 | |
| 242 | 320 | Gmail网页客户端自动地把制表符转换为空格。 |
| 243 | 321 | |
| 244 | −虽然制表符转换为空格问题可以被外部编辑器解决,同时它还会使用回车换行把每行拆分为78个字符。 | |
| 322 | +虽然制表符转换为空格问题可以被外部编辑器解决,但它同时还会使用回车换行把每行 | |
| 323 | +拆分为78个字符。 | |
| 245 | 324 | |
| 246 | −另一个问题是Gmail还会把任何不是ASCII的字符的信息改为base64编码。它把东西变的像欧洲人的名字。 | |
| 325 | +另一个问题是Gmail还会把任何含有非ASCII的字符的消息改用base64编码,如欧洲人的 | |
| 326 | +名字。 | |
| 247 | 327 | |
| 248 | − ### | |
| @@ -1,105 +1,111 @@ | ||
| 1 | 1 | .. include:: ../disclaimer-zh_CN.rst |
| 2 | 2 | |
| 3 | −:Original: :ref:`Documentation/process/submit-checklist.rst <submitchecklist>` | |
| 4 | −:Translator: Alex Shi <alex.shi@linux.alibaba.com> | |
| 3 | +:Original: Documentation/process/submit-checklist.rst | |
| 4 | +:Translator: | |
| 5 | + - Alex Shi <alexs@kernel.org> | |
| 6 | + - Wu XiangCheng <bobwxc@email.cn> | |
| 5 | 7 | |
| 6 | 8 | .. _cn_submitchecklist: |
| 7 | 9 | |
| 8 | −Linux内核补丁提交清单 | |
| 9 | −~~~~~~~~~~~~~~~~~~~~~ | |
| 10 | +Linux内核补丁提交检查单 | |
| 11 | +~~~~~~~~~~~~~~~~~~~~~~~ | |
| 10 | 12 | |
| 11 | 13 | 如果开发人员希望看到他们的内核补丁提交更快地被接受,那么他们应该做一些基本 |
| 12 | 14 | 的事情。 |
| 13 | 15 | |
| 14 | −这些都是在 | |
| 15 | −:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst <cn_submittingpatches>` | |
| 16 | +这些都是在 Documentation/translations/zh_CN/process/submitting-patches.rst | |
| 16 | 17 | 和其他有关提交Linux内核补丁的文档中提供的。 |
| 17 | 18 | |
| 18 | −1) 如果使用工具,则包括定义/声明该工具的文件。不要依赖于其他头文件拉入您使用 | |
| 19 | +1) 如果使用工具,则包括定义/声明该工具的文件。不要依赖其他头文件来引入您使用 | |
| 19 | 20 | 的头文件。 |
| 20 | 21 | |
| 21 | 22 | 2) 干净的编译: |
| 22 | 23 | |
| 23 | − a) 使用适用或修改的 ``CONFIG`` 选项 ``=y``、``=m`` 和 ``=n`` 。没有GCC | |
| 24 | + a) 使用合适的 ``CONFIG`` 选项 ``=y``、``=m`` 和 ``=n`` 。没有 ``gcc`` | |
| 24 | 25 | 警告/错误,没有链接器警告/错误。 |
| 25 | 26 | |
| 26 | − b) 通过allnoconfig、allmodconfig | |
| 27 | + b) 通过 ``allnoconfig`` 、 ``allmodconfig`` | |
| 27 | 28 | |
| 28 | 29 | c) 使用 ``O=builddir`` 时可以成功编译 |
| 29 | 30 | |
| 30 | −3) 通过使用本地交叉编译工具或其他一些构建场在多个CPU体系结构上构建。 | |
| 31 | + d) 任何 Doucmentation/ 下的变更都能成功构建且不引入新警告/错误。 | |
| 32 | + 用 ``make htmldocs`` 或 ``make pdfdocs`` 检验构建情况并修复问题。 | |
| 33 | + | |
| 34 | +3) 通过使用本地交叉编译工具或其他一些构建设施在多个CPU体系结构上构建。 | |
| 31 | 35 | |
| 32 | 36 | 4) PPC64是一种很好的交叉编译检查体系结构,因为它倾向于对64位的数使用无符号 |
| 33 | 37 | 长整型。 |
| 34 | 38 | |
| 35 | −5) 如下所述 :ref:`Documentation/translations/zh_CN/process/coding-style.rst <cn_codingstyle>`. | |
| 36 | − 检查您的补丁是否为常规样式。在提交( ``scripts/check patch.pl`` )之前, | |
| 37 | − 使用补丁样式检查器检查是否有轻微的冲突。您应该能够处理您的补丁中存在的所有 | |
| 39 | +5) 按 Documentation/translations/zh_CN/process/coding-style.rst 所述检查您的 | |
| 40 | + 补丁是否为常规样式。在提交之前使用补丁样式检查器 ``scripts/checkpatch.pl`` | |
| 41 | + 检查是否有轻微的冲突。您应该能够处理您的补丁中存在的所有 | |
| 38 | 42 | 违规行为。 |
| 39 | 43 | |
| 40 | −6) 任何新的或修改过的 ``CONFIG`` 选项都不会弄脏配置菜单,并默认为关闭,除非 | |
| 41 | − 它们符合 ``Documentation/kbuild/kconfig-language.rst`` 中记录的异常条件, | |
| 42 | − 菜单属性:默认值. | |
| 44 | +6) 任何新的或修改过的 ``CONFIG`` 选项都不应搞乱配置菜单,并默认为关闭,除非 | |
| 45 | + 它们符合 ``Documentation/kbuild/kconfig-language.rst`` 菜单属性:默认值中 | |
| 46 | + 记录的例外条件。 | |
| 43 | 47 | |
| 44 | 48 | 7) 所有新的 ``kconfig`` 选项都有帮助文本。 |
| 45 | 49 | |
| 46 | 50 | 8) 已仔细审查了相关的 ``Kconfig`` 组合。这很难用测试来纠正——脑力在这里是有 |
| 47 | 51 | 回报的。 |
| 48 | 52 | |
| 49 | −9) 用 sparse 检查干净。 | |
| 53 | +9) 通过 sparse 清查。 | |
| 54 | + (参见 Documentation/translations/zh_CN/dev-tools/sparse.rst ) | |
| 50 | 55 | |
| 51 | 56 | 10) 使用 ``make checkstack`` 和 ``make namespacecheck`` 并修复他们发现的任何 |
| 52 | 57 | 问题。 |
| 53 | 58 | |
| 54 | 59 | .. note:: |
| 55 | 60 | |
| 56 | − ``checkstack`` 并没有明确指出问题,但是任何一个在堆栈上使用超过512 | |
| 61 | + ``checkstack`` 并不会明确指出问题,但是任何一个在堆栈上使用超过512 | |
| 57 | 62 | 字节的函数都可以进行更改。 |
| 58 | 63 | |
| 59 | −11) 包括 :ref:`kernel-doc <kernel_doc>` 内核文档以记录全局内核API。(静态函数 | |
| 60 | − 不需要,但也可以。)使用 ``make htmldocs`` 或 ``make pdfdocs`` 检查 | |
| 61 | − :ref:`kernel-doc <kernel_doc>` 并修复任何问题。 | |
| 64 | +11) 包括 :ref:`kernel-doc <kernel_doc_zh>` 内核文档以记录全局内核API。(静态 | |
| 65 | + 函数不需要,但也可以。)使用 ``make htmldocs`` 或 ``make pdfdocs`` 检查 | |
| 66 | + :ref:`kernel-doc <kernel_doc_zh>` 并修复任何问题。 | |
| 62 | 67 | |
| 63 | −12) 通过以下选项同时启用的测试 ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``, | |
| 68 | +12) 通过以下选项同时启用的测试: ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``, | |
| 64 | 69 | ``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``, |
| 65 | 70 | ``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``, |
| 66 | − ``CONFIG_PROVE_RCU`` and ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` | |
| 67 | − | |
| 68 | −13) 已经过构建和运行时测试,包括有或没有 ``CONFIG_SMP``, ``CONFIG_PREEMPT``. | |
| 71 | + ``CONFIG_PROVE_RCU`` 和 ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` 。 | |
| 69 | 72 | |
| 70 | −14) 如果补丁程序影响IO/磁盘等:使用或不使用 ``CONFIG_LBDAF`` 进行测试。 | |
| 73 | +13) 在 ``CONFIG_SMP``, ``CONFIG_PREEMPT`` 开启和关闭的情况下都进行构建和运行 | |
| 74 | + 时测试。 | |
| 71 | 75 | |
| 72 | −15) 所有代码路径都已在启用所有lockdep功能的情况下运行。 | |
| 76 | +14) 所有代码路径都已在启用所有死锁检测(lockdep)功能的情况下运行。 | |
| 73 | 77 | |
| 74 | −16) 所有新的/proc条目都记录在 ``Documentation/`` | |
| 78 | +15) 所有新的 ``/proc`` 条目都记录在 ``Documentation/`` | |
| 75 | 79 | |
| 76 | −17) 所有新的内核引导参数都记录在 | |
| 80 | +16) 所有新的内核引导参数都记录在 | |
| 77 | 81 | Documentation/admin-guide/kernel-parameters.rst 中。 |
| 78 | 82 | |
| 79 | −18) 所有新的模块参数都记录在 ``MODULE_PARM_DESC()`` | |
| 83 | +17) 所有新的模块参数都记录在 ``MODULE_PARM_DESC()`` | |
| 80 | 84 | |
| 81 | −19) 所有新的用户空间接口都记录在 ``Documentation/ABI/`` 中。有关详细信息, | |
| 85 | +18) 所有新的用户空间接口都记录在 ``Documentation/ABI/`` 中。有关详细信息, | |
| 82 | 86 | 请参阅 ``Documentation/ABI/README`` 。更改用户空间接口的补丁应该抄送 |
| 83 | 87 | linux-api@vger.kernel.org。 |
| 84 | 88 | |
| 85 | −20) 已通过至少注入slab和page分配失败进行检查。请参阅 ``Documentation/fault-injection/`` | |
| 89 | +19) 已通过至少注入slab和page分配失败进行检查。请参阅 ``Documentation/fault-injection/`` 。 | |
| 86 | 90 | 如果新代码是实质性的,那么添加子系统特定的故障注入可能是合适的。 |
| 87 | 91 | |
| 88 | −21) 新添加的代码已经用 ``gcc -W`` 编译(使用 ``make EXTRA-CFLAGS=-W`` )。这 | |
| 92 | +20) 新添加的代码已经用 ``gcc -W`` 编译(使用 ``make EXTRA-CFLAGS=-W`` )。这 | |
| 89 | 93 | 将产生大量噪声,但对于查找诸如“警告:有符号和无符号之间的比较”之类的错误 |
| 90 | 94 | 很有用。 |
| 91 | 95 | |
| 92 | −22) 在它被合并到-mm补丁集中之后进行测试,以确保它仍然与所有其他排队的补丁以 | |
| 96 | +21) 在它被合并到-mm补丁集中之后进行测试,以确保它仍然与所有其他排队的补丁以 | |
| 93 | 97 | 及VM、VFS和其他子系统中的各种更改一起工作。 |
| 94 | 98 | |
| 95 | −23) 所有内存屏障例如 ``barrier()``, ``rmb()``, ``wmb()`` 都需要源代码中的注 | |
| 99 | +22) 所有内存屏障(例如 ``barrier()``, ``rmb()``, ``wmb()`` )都需要源代码注 | |
| 96 | 100 | 释来解释它们正在执行的操作及其原因的逻辑。 |
| 97 | 101 | |
| 98 | −24) 如果补丁添加了任何ioctl,那么也要更新 ``Documentation/userspace-api/ioctl/ioctl-number.rst`` | |
| 102 | +23) 如果补丁添加了任何ioctl,那么也要更新 | |
| 103 | + ``Documentation/userspace-api/ioctl/ioctl-number.rst`` 。 | |
| 99 | 104 | |
| 100 | −25) 如果修改后的源代码依赖或使用与以下 ``Kconfig`` 符号相关的任何内核API或 | |
| 105 | +24) 如果修改后的源代码依赖或使用与以下 ``Kconfig`` 符号相关的任何内核API或 | |
| 101 | 106 | 功能,则在禁用相关 ``Kconfig`` 符号和/或 ``=m`` (如果该选项可用)的情况 |
| 102 | 107 | 下测试以下多个构建[并非所有这些都同时存在,只是它们的各种/随机组合]: |
| 103 | 108 | |
| 104 | − ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``, | |
| 105 | − ``CONFIG_NET``, ``CONFIG_INET=n`` (但是后者伴随 ``CONFIG_NET=y``). | |
| 109 | + ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, | |
| 110 | + ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``, | |
| 111 | + ``CONFIG_NET``, ``CONFIG_INET=n`` (但是最后一个需要 ``CONFIG_NET=y`` )。 | |
| @@ -1,142 +1,92 @@ | ||
| 1 | −.. _cn_submittingpatches: | |
| 1 | +.. SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | |
| 3 | 3 | .. include:: ../disclaimer-zh_CN.rst |
| 4 | 4 | |
| 5 | −:Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>` | |
| 5 | +.. _cn_submittingpatches: | |
| 6 | + | |
| 7 | +:Original: Documentation/process/submitting-patches.rst | |
| 6 | 8 | |
| 7 | −译者:: | |
| 9 | +:译者: | |
| 10 | + - 钟宇 TripleX Chung <xxx.phy@gmail.com> | |
| 11 | + - 时奎亮 Alex Shi <alexs@kernel.org> | |
| 12 | + - 吴想成 Wu XiangCheng <bobwxc@email.cn> | |
| 8 | 13 | |
| 9 | − 中文版维护者: 钟宇 TripleX Chung <xxx.phy@gmail.com> | |
| 10 | − 中文版翻译者: 钟宇 TripleX Chung <xxx.phy@gmail.com> | |
| 11 | − 时奎亮 Alex Shi <alex.shi@linux.alibaba.com> | |
| 12 | − 中文版校译者: 李阳 Li Yang <leoyang.li@nxp.com> | |
| 13 | − 王聪 Wang Cong <xiyou.wangcong@gmail.com> | |
| 14 | +:校译: | |
| 15 | + - 李阳 Li Yang <leoyang.li@nxp.com> | |
| 16 | + - 王聪 Wang Cong <xiyou.wangcong@gmail.com> | |
| 14 | 17 | |
| 15 | 18 | |
| 16 | −如何让你的改动进入内核 | |
| 17 | −====================== | |
| 19 | +提交补丁:如何让你的改动进入内核 | |
| 20 | +================================ | |
| 18 | 21 | |
| 19 | 22 | 对于想要将改动提交到 Linux 内核的个人或者公司来说,如果不熟悉“规矩”, |
| 20 | −提交的流程会让人畏惧。本文档收集了一系列建议,这些建议可以大大的提高你 | |
| 23 | +提交的流程会让人畏惧。本文档包含了一系列建议,可以大大提高你 | |
| 21 | 24 | 的改动被接受的机会. |
| 22 | 25 | |
| 23 | −以下文档含有大量简洁的建议, 具体请见: | |
| 24 | −:ref:`Documentation/process <development_process_main>` | |
| 25 | −同样,:ref:`Documentation/translations/zh_CN/process/submit-checklist.rst <cn_submitchecklist>` | |
| 26 | −给出在提交代码前需要检查的项目的列表。 | |
| 26 | +本文档以较为简洁的行文给出了大量建议。关于内核开发流程如何进行的详细信息, | |
| 27 | +参见: Documentation/translations/zh_CN/process/development-process.rst 。 | |
| 28 | +Documentation/translations/zh_CN/process/submit-checklist.rst 给出了一系列 | |
| 29 | +提交补丁之前要检查的事项。设备树相关的补丁,请参阅 | |
| 30 | +Documentation/devicetree/bindings/submitting-patches.rst 。 | |
| 27 | 31 | |
| 28 | −其中许多步骤描述了Git版本控制系统的默认行为;如果您使用Git来准备补丁, | |
| 29 | −您将发现它为您完成的大部分机械工作,尽管您仍然需要准备和记录一组合理的 | |
| 30 | −补丁。一般来说,使用git将使您作为内核开发人员的生活更轻松。 | |
| 32 | +本文档假设您正在使用 ``git`` 准备你的补丁。如果您不熟悉 ``git`` ,最好学习 | |
| 33 | +如何使用它,这将使您作为内核开发人员的生活变得更加轻松。 | |
| 31 | 34 | |
| 35 | +部分子系统和维护人员的树有一些关于其工作流程和要求的额外信息,请参阅 | |
| 36 | +Documentation/process/maintainer-handbooks.rst 。 | |
| 32 | 37 | |
| 33 | −0) 获取当前源码树 | |
| 34 | −----------------- | |
| 38 | +获取当前源码树 | |
| 39 | +-------------- | |
| 35 | 40 | |
| 36 | −如果您没有一个可以使用当前内核源代码的存储库,请使用git获取一个。您将要 | |
| 37 | −从主线存储库开始,它可以通过以下方式获取:: | |
| 41 | +如果您手头没有当前内核源代码的存储库,请使用 ``git`` 获取一份。您需要先获取 | |
| 42 | +主线存储库,它可以通过以下命令拉取:: | |
| 38 | 43 | |
| 39 | − git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git | |
| 44 | + git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git | |
| 40 | 45 | |
| 41 | −但是,请注意,您可能不希望直接针对主线树进行开发。大多数子系统维护人员运 | |
| 46 | +但是,请注意,您可能不想直接针对主线树进行开发。大多数子系统维护人员运 | |
| 42 | 47 | 行自己的树,并希望看到针对这些树准备的补丁。请参见MAINTAINERS文件中子系 |
| 43 | −统的 **T:** 项以查找该树,或者简单地询问维护者该树是否未在其中列出。 | |
| 44 | − | |
| 45 | −仍然可以通过tarballs下载内核版本(如下一节所述),但这是进行内核开发的 | |
| 46 | −一种困难的方式。 | |
| 47 | − | |
| 48 | −1) "diff -up" | |
| 49 | −------------- | |
| 50 | − | |
| 51 | −使用 "diff -up" 或者 "diff -uprN" 来创建补丁。 | |
| 52 | − | |
| 53 | −所有内核的改动,都是以补丁的形式呈现的,补丁由 diff(1) 生成。创建补丁的 | |
| 54 | −时候,要确认它是以 "unified diff" 格式创建的,这种格式由 diff(1) 的 '-u' | |
| 55 | −参数生成。而且,请使用 '-p' 参数,那样会显示每个改动所在的C函数,使得 | |
| 56 | −产生的补丁容易读得多。补丁应该基于内核源代码树的根目录,而不是里边的任 | |
| 57 | −何子目录。 | |
| 58 | − | |
| 59 | −为一个单独的文件创建补丁,一般来说这样做就够了:: | |
| 60 | − | |
| 61 | − SRCTREE=linux | |
| 62 | − MYFILE=drivers/net/mydriver.c | |
| 48 | +统的 **T:** 项以查找该树,或者直接询问维护者该树是否未在其中列出。 | |
| 63 | 49 | |
| 64 | − cd $SRCTREE | |
| 65 | − cp $MYFILE $MYFILE.orig | |
| 66 | − vi $MYFILE # make your change | |
| 67 | − cd .. | |
| 68 | − diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch | |
| 50 | +.. _zh_describe_changes: | |
| 69 | 51 | |
| 70 | −为多个文件创建补丁,你可以解开一个没有修改过的内核源代码树,然后和你自 | |
| 71 | −己的代码树之间做 diff 。例如:: | |
| 72 | − | |
| 73 | − MYSRC=/devel/linux | |
| 74 | − | |
| 75 | − tar xvfz linux-3.19.tar.gz | |
| 76 | − mv linux-3.19 linux-3.19-vanilla | |
| 77 | − diff -uprN -X linux-3.19-vanilla/Documentation/dontdiff \ | |
| 78 | − linux-3.19-vanilla $MYSRC > /tmp/patch | |
| 79 | − | |
| 80 | −"dontdiff" 是内核在编译的时候产生的文件的列表,列表中的文件在 diff(1) | |
| 81 | −产生的补丁里会被跳过。 | |
| 82 | − | |
| 83 | −确定你的补丁里没有包含任何不属于这次补丁提交的额外文件。记得在用diff(1) | |
| 84 | −生成补丁之后,审阅一次补丁,以确保准确。 | |
| 85 | − | |
| 86 | −如果你的改动很散乱,你应该研究一下如何将补丁分割成独立的部分,将改动分 | |
| 87 | −割成一系列合乎逻辑的步骤。这样更容易让其他内核开发者审核,如果你想你的 | |
| 88 | −补丁被接受,这是很重要的。请参阅: | |
| 89 | −:ref:`cn_split_changes` | |
| 90 | − | |
| 91 | −如果你用 ``git`` , ``git rebase -i`` 可以帮助你这一点。如果你不用 ``git``, | |
| 92 | −``quilt`` <https://savannah.nongnu.org/projects/quilt> 另外一个流行的选择。 | |
| 93 | − | |
| 94 | −.. _cn_describe_changes: | |
| 95 | − | |
| 96 | −2) 描述你的改动 | |
| 97 | −--------------- | |
| 52 | +描述你的改动 | |
| 53 | +------------ | |
| 98 | 54 | |
| 99 | 55 | 描述你的问题。无论您的补丁是一行错误修复还是5000行新功能,都必须有一个潜在 |
| 100 | −的问题激励您完成这项工作。让审稿人相信有一个问题值得解决,让他们读完第一段 | |
| 101 | −是有意义的。 | |
| 56 | +的问题激励您完成这项工作。说服审阅者相信有一个问题值得解决,让他们读完第一段 | |
| 57 | +后就能明白这一点。 | |
| 102 | 58 | |
| 103 | 59 | 描述用户可见的影响。直接崩溃和锁定是相当有说服力的,但并不是所有的错误都那么 |
| 104 | −明目张胆。即使在代码审查期间发现了这个问题,也要描述一下您认为它可能对用户产 | |
| 60 | +明目张胆。即使在代码审阅期间发现了这个问题,也要描述一下您认为它可能对用户产 | |
| 105 | 61 | 生的影响。请记住,大多数Linux安装运行的内核来自二级稳定树或特定于供应商/产品 |
| 106 | 62 | 的树,只从上游精选特定的补丁,因此请包含任何可以帮助您将更改定位到下游的内容: |
| 107 | 63 | 触发的场景、DMESG的摘录、崩溃描述、性能回归、延迟尖峰、锁定等。 |
| 108 | 64 | |
| 109 | −量化优化和权衡。如果您声称在性能、内存消耗、堆栈占用空间或二进制大小方面有所 | |
| 110 | −改进,请包括支持它们的数字。但也要描述不明显的成本。优化通常不是免费的,而是 | |
| 111 | −在CPU、内存和可读性之间进行权衡;或者,探索性的工作,在不同的工作负载之间进 | |
| 65 | +质量优化和权衡。如果您声称在性能、内存消耗、堆栈占用空间或二进制大小方面有所 | |
| 66 | +改进,请包括支持它们的数据。但也要描述不明显的成本。优化通常不是零成本的,而是 | |
| 67 | +在CPU、内存和可读性之间进行权衡;或者,做探索性的工作,在不同的工作负载之间进 | |
| 112 | 68 | 行权衡。请描述优化的预期缺点,以便审阅者可以权衡成本和收益。 |
| 113 | 69 | |
| 114 | −一旦问题建立起来,就要详细地描述一下您实际在做什么。对于审阅者来说,用简单的 | |
| 115 | −英语描述代码的变化是很重要的,以验证代码的行为是否符合您的意愿。 | |
| 70 | +提出问题之后,就要详细地描述一下您实际在做的技术细节。对于审阅者来说,用简练的 | |
| 71 | +英语描述代码的变化是很重要的,以验证代码的行为是否符合您的意图。 | |
| 116 | 72 | |
| 117 | −如果您将补丁描述写在一个表单中,这个表单可以很容易地作为“提交日志”放入Linux | |
| 118 | −的源代码管理系统git中,那么维护人员将非常感谢您。见 :ref:`cn_explicit_in_reply_to`. | |
| 73 | +如果您将补丁描述写成“标准格式”,可以很容易地作为“提交日志”放入Linux的源代 | |
| 74 | +码管理系统 ``git`` 中,那么维护人员将非常感谢您。 | |
| 75 | +参见 :ref:`zh_the_canonical_patch_format` 。 | |
| 119 | 76 | |
| 120 | 77 | 每个补丁只解决一个问题。如果你的描述开始变长,这就表明你可能需要拆分你的补丁。 |
| 121 | −请见 :ref:`cn_split_changes` | |
| 78 | +请见 :ref:`zh_split_changes` 。 | |
| 122 | 79 | |
| 123 | −提交或重新提交修补程序或修补程序系列时,请包括完整的修补程序说明和理由。不要 | |
| 80 | +提交或重新提交补丁或补丁系列时,请包括完整的补丁说明和理由。不要 | |
| 124 | 81 | 只说这是补丁(系列)的第几版。不要期望子系统维护人员引用更早的补丁版本或引用 |
| 125 | 82 | URL来查找补丁描述并将其放入补丁中。也就是说,补丁(系列)及其描述应该是独立的。 |
| 126 | −这对维护人员和审查人员都有好处。一些评审者可能甚至没有收到补丁的早期版本。 | |
| 83 | +这对维护人员和审阅者都有好处。一些审阅者可能甚至没有收到补丁的早期版本。 | |
| 127 | 84 | |
| 128 | −描述你在命令语气中的变化,例如“make xyzzy do frotz”而不是“[This patch]make | |
| 85 | +用祈使句描述你的变更,例如“make xyzzy do frotz”而不是“[This patch]make | |
| 129 | 86 | xyzzy do frotz”或“[I]changed xyzzy to do frotz”,就好像你在命令代码库改变 |
| 130 | 87 | 它的行为一样。 |
| 131 | 88 | |
| 132 | −如果修补程序修复了一个记录的bug条目,请按编号和URL引用该bug条目。如果补丁来 | |
| 133 | −自邮件列表讨论,请给出邮件列表存档的URL;使用带有 ``Message-ID`` 的 | |
| 134 | −https://lore.kernel.org/ 重定向,以确保链接不会过时。 | |
| 135 | − | |
| 136 | −但是,在没有外部资源的情况下,尽量让你的解释可理解。除了提供邮件列表存档或 | |
| 137 | −bug的URL之外,还要总结需要提交补丁的相关讨论要点。 | |
| 138 | − | |
| 139 | −如果您想要引用一个特定的提交,不要只引用提交的 SHA-1 ID。还请包括提交的一行 | |
| 89 | +如果您想要引用一个特定的提交,不要只引用提交的SHA-1 ID。还请包括提交的一行 | |
| 140 | 90 | 摘要,以便于审阅者了解它是关于什么的。例如:: |
| 141 | 91 | |
| 142 | 92 | Commit e21d2170f36602ae2708 ("video: remove unnecessary |
| @@ -144,82 +94,104 @@ bug的URL之外,还要总结需要提交补丁的相关讨论要点。 · 1 unmodified line | ||
| 144 | 94 | platform_set_drvdata(), but left the variable "dev" unused, |
| 145 | 95 | delete it. |
| 146 | 96 | |
| 147 | −您还应该确保至少使用前12位 SHA-1 ID. 内核存储库包含*许多*对象,使与较短的ID | |
| 97 | +您还应该确保至少使用前12位SHA-1 ID。内核存储库包含 *许多* 对象,使较短的ID | |
| 148 | 98 | 发生冲突的可能性很大。记住,即使现在不会与您的六个字符ID发生冲突,这种情况 |
| 149 | −可能五年后改变。 | |
| 99 | +也可能在五年后改变。 | |
| 100 | + | |
| 101 | +如果该变更的相关讨论或背景信息可以在网上查阅,请加上“Link:”标签指向它。例如 | |
| 102 | +你的补丁修复了一个缺陷,需要添加一个带有URL的标签指向邮件列表存档或缺陷跟踪器 | |
| 103 | +的相关报告;如果该补丁是由一些早先邮件列表讨论或网络上的记录引起的,请指向它。 | |
| 104 | + | |
| 105 | +当链接到邮件列表存档时,请首选lore.kernel.org邮件存档服务。用邮件中的 | |
| 106 | +``Message-ID`` 头(去掉尖括号)可以创建链接URL。例如:: | |
| 107 | + | |
| 108 | + Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/ | |
| 109 | + | |
| 110 | +请检查该链接以确保可用且指向正确的邮件。 | |
| 150 | 111 | |
| 151 | −如果修补程序修复了特定提交中的错误,例如,使用 ``git bisct`` ,请使用带有前 | |
| 152 | −12个字符SHA-1 ID 的"Fixes:"标记和单行摘要。为了简化不要将标记拆分为多个, | |
| 153 | −行、标记不受分析脚本“75列换行”规则的限制。例如:: | |
| 112 | +不过,在没有外部资源的情况下,也要尽量让你的解释可理解。除了提供邮件列表存档或 | |
| 113 | +缺陷的URL之外,还要需要总结该补丁的相关讨论要点。 | |
| 154 | 114 | |
| 155 | − Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed") | |
| 115 | +如果补丁修复了特定提交中的错误,例如使用 ``git bisct`` 发现了一个问题,请使用 | |
| 116 | +带有前12个字符SHA-1 ID的“Fixes:”标签和单行摘要。为了简化解析脚本,不要将该 | |
| 117 | +标签拆分为多行,标签不受“75列换行”规则的限制。例如:: | |
| 156 | 118 | |
| 157 | −下列 ``git config`` 设置可以添加让 ``git log``, ``git show`` 漂亮的显示格式:: | |
| 119 | + Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed") | |
| 120 | + | |
| 121 | +下列 ``git config`` 设置可以让 ``git log``, ``git show`` 增加上述风格的显示格式:: | |
| 158 | 122 | |
| 159 | 123 | [core] |
| 160 | 124 | abbrev = 12 |
| 161 | 125 | [pretty] |
| 162 | 126 | fixes = Fixes: %h (\"%s\") |
| 163 | 127 | |
| 164 | −.. _cn_split_changes: | |
| 128 | +使用示例:: | |
| 129 | + | |
| 130 | + $ git log -1 --pretty=fixes 54a4f0239f2e | |
| 131 | + Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed") | |
| 165 | 132 | |
| 166 | −3) 拆分你的改动 | |
| 167 | −--------------- | |
| 133 | +.. _zh_split_changes: | |
| 168 | 134 | |
| 169 | −将每个逻辑更改分隔成一个单独的补丁。 | |
| 135 | +拆分你的改动 | |
| 136 | +------------ | |
| 137 | + | |
| 138 | +将每个 **逻辑更改** 拆分成一个单独的补丁。 | |
| 170 | 139 | |
| 171 | 140 | 例如,如果你的改动里同时有bug修正和性能优化,那么把这些改动拆分到两个或 |
| 172 | −者更多的补丁文件中。如果你的改动包含对API的修改,并且修改了驱动程序来适 | |
| 173 | −应这些新的API,那么把这些修改分成两个补丁。 | |
| 141 | +者更多的补丁文件中。如果你的改动包含对API的修改,并且增加了一个使用该新API | |
| 142 | +的驱动,那么把这些修改分成两个补丁。 | |
| 174 | 143 | |
| 175 | 144 | 另一方面,如果你将一个单独的改动做成多个补丁文件,那么将它们合并成一个 |
| 176 | 145 | 单独的补丁文件。这样一个逻辑上单独的改动只被包含在一个补丁文件里。 |
| 177 | 146 | |
| 178 | −如果有一个补丁依赖另外一个补丁来完成它的改动,那没问题。简单的在你的补 | |
| 179 | −丁描述里指出“这个补丁依赖某补丁”就好了。 | |
| 147 | +需要记住的一点是,每个补丁的更改都应易于理解,以便审阅者验证。每个补丁都应该 | |
| 148 | +对其价值进行阐述。 | |
| 149 | + | |
| 150 | +如果有一个补丁依赖另外一个补丁来完成它的改动,那没问题。直接在你的补 | |
| 151 | +丁描述里指出 **“这个补丁依赖某补丁”** 就好了。 | |
| 180 | 152 | |
| 181 | −在将您的更改划分为一系列补丁时,要特别注意确保内核在系列中的每个补丁之后 | |
| 182 | −都能正常构建和运行。使用 ``git bisect`` 来追踪问题的开发者可能会在任何时 | |
| 183 | −候分割你的补丁系列;如果你在中间引入错误,他们不会感谢你。 | |
| 153 | +在将您的更改划分为一系列补丁时,要特别注意确保内核在应用系列中的每个补丁之后 | |
| 154 | +都能正常构建和运行。使用 ``git bisect`` 来追踪问题的开发者可能会在任何地方分 | |
| 155 | +割你的补丁系列;如果你在中间引入错误,他们不会感谢你。 | |
| 184 | 156 | |
| 185 | −如果你不能将补丁浓缩成更少的文件,那么每次大约发送出15个,然后等待审查 | |
| 157 | +如果你不能将补丁系列浓缩得更小,那么每次大约发送出15个补丁,然后等待审阅 | |
| 186 | 158 | 和集成。 |
| 187 | 159 | |
| 188 | −4) 检查你的更改风格 | |
| 189 | −------------------- | |
| 160 | +检查你的更改风格 | |
| 161 | +---------------- | |
| 190 | 162 | |
| 191 | −检查您的补丁是否存在基本样式冲突,详细信息可在 | |
| 192 | −:ref:`Documentation/translations/zh_CN/process/coding-style.rst <cn_codingstyle>` | |
| 193 | −中找到。如果不这样做,只会浪费审稿人的时间,并且会导致你的补丁被拒绝,甚至 | |
| 163 | +检查您的补丁是否违反了基本样式规定,详细信息参见 | |
| 164 | +Documentation/translations/zh_CN/process/coding-style.rst | |
| 165 | +中找到。如果不这样做,只会浪费审阅者的时间,并且会导致你的补丁被拒绝,甚至 | |
| 194 | 166 | 可能没有被阅读。 |
| 195 | 167 | |
| 196 | 168 | 一个重要的例外是在将代码从一个文件移动到另一个文件时——在这种情况下,您不应 |
| 197 | 169 | 该在移动代码的同一个补丁中修改移动的代码。这清楚地描述了移动代码和您的更改 |
| 198 | −的行为。这大大有助于审查实际差异,并允许工具更好地跟踪代码本身的历史。 | |
| 170 | +的行为。这大大有助于审阅实际差异,并允许工具更好地跟踪代码本身的历史。 | |
| 199 | 171 | |
| 200 | 172 | 在提交之前,使用补丁样式检查程序检查补丁(scripts/check patch.pl)。不过, |
| 201 | 173 | 请注意,样式检查程序应该被视为一个指南,而不是作为人类判断的替代品。如果您 |
| 202 | −的代码看起来更好,但有违规行为,那么最好不要使用它。 | |
| 174 | +的代码看起来更好,但有违规行为,那么最好别管它。 | |
| 203 | 175 | |
| 204 | 176 | 检查者报告三个级别: |
| 205 | 177 | |
| 206 | 178 | - ERROR:很可能出错的事情 |
| 207 | − - WARNING:需要仔细审查的事项 | |
| 179 | + - WARNING:需要仔细审阅的事项 | |
| 208 | 180 | - CHECK:需要思考的事情 |
| 209 | 181 | |
| 210 | 182 | 您应该能够判断您的补丁中存在的所有违规行为。 |
| 211 | 183 | |
| 212 | −5) 选择补丁收件人 | |
| 213 | −----------------- | |
| 184 | +选择补丁收件人 | |
| 185 | +-------------- | |
| 214 | 186 | |
| 215 | −您应该总是在任何补丁上复制相应的子系统维护人员,以获得他们维护的代码;查看 | |
| 187 | +您应该总是知会任何补丁相应代码的子系统维护人员;查看 | |
| 216 | 188 | 维护人员文件和源代码修订历史记录,以了解这些维护人员是谁。脚本 |
| 217 | −scripts/get_Maintainer.pl在这个步骤中非常有用。如果您找不到正在工作的子系统 | |
| 189 | +scripts/get_maintainer.pl在这个步骤中非常有用。如果您找不到正在工作的子系统 | |
| 218 | 190 | 的维护人员,那么Andrew Morton(akpm@linux-foundation.org)将充当最后的维护 |
| 219 | 191 | 人员。 |
| 220 | 192 | |
| 221 | −您通常还应该选择至少一个邮件列表来接收补丁集的。linux-kernel@vger.kernel.org | |
| 222 | −作为最后一个解决办法的列表,但是这个列表上的体积已经引起了许多开发人员的拒绝。 | |
| 193 | +您通常还应该选择至少一个邮件列表来接收补丁集的副本。linux-kernel@vger.kernel.org | |
| 194 | +是所有补丁的默认列表,但是这个列表的流量已经导致了许多开发人员不再看它。 | |
| 223 | 195 | 在MAINTAINERS文件中查找子系统特定的列表;您的补丁可能会在那里得到更多的关注。 |
| 224 | 196 | 不过,请不要发送垃圾邮件到无关的列表。 |
| 225 | 197 | |
| @@ -229,189 +201,170 @@ http://vger.kernel.org/vger-lists.html 上找到它们的列表。不过,也 · 3 unmodified lines | ||
| 229 | 201 | |
| 230 | 202 | 不要一次发送超过15个补丁到vger邮件列表!!!! |
| 231 | 203 | |
| 232 | −Linus Torvalds 是决定改动能否进入 Linux 内核的最终裁决者。他的 e-mail | |
| 233 | −地址是 <torvalds@linux-foundation.org> 。他收到的 e-mail 很多,所以一般 | |
| 234 | −的说,最好别给他发 e-mail。 | |
| 235 | − | |
| 236 | −如果您有修复可利用安全漏洞的补丁,请将该补丁发送到 security@kernel.org。对于 | |
| 237 | −严重的bug,可以考虑短期暂停以允许分销商向用户发布补丁;在这种情况下,显然不应 | |
| 238 | −将补丁发送到任何公共列表。 | |
| 204 | +Linus Torvalds是决定改动能否进入 Linux 内核的最终裁决者。他的邮件地址是 | |
| 205 | +torvalds@linux-foundation.org 。他收到的邮件很多,所以一般来说最好 **别** | |
| 206 | +给他发邮件。 | |
| 239 | 207 | |
| 240 | −修复已发布内核中严重错误的补丁程序应该指向稳定版维护人员,方法是放这样的一行:: | |
| 208 | +如果您有修复可利用安全漏洞的补丁,请将该补丁发送到 security@kernel.org 。对于 | |
| 209 | +严重的bug,可以考虑短期禁令以允许分销商(有时间)向用户发布补丁;在这种情况下, | |
| 210 | +显然不应将补丁发送到任何公共列表。 | |
| 211 | +参见 Documentation/translations/zh_CN/admin-guide/security-bugs.rst 。 | |
| 241 | 212 | |
| 242 | − Cc: stable@vger.kernel.org | |
| 213 | +修复已发布内核中严重错误的补丁程序应该抄送给稳定版维护人员,方法是把以下列行 | |
| 214 | +放进补丁的签准区(注意,不是电子邮件收件人):: | |
| 243 | 215 | |
| 244 | −进入补丁的签准区(注意,不是电子邮件收件人)。除了这个文件之外,您还应该阅读 | |
| 245 | −:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>` | |
| 216 | + Cc: stable@vger.kernel.org | |
| 246 | 217 | |
| 247 | −但是,请注意,一些子系统维护人员希望得出他们自己的结论,即哪些补丁应该被放到 | |
| 248 | −稳定的树上。尤其是网络维护人员,不希望看到单个开发人员在补丁中添加像上面这样 | |
| 249 | −的行。 | |
| 218 | +除了本文件之外,您还应该阅读 | |
| 219 | +Documentation/translations/zh_CN/process/stable-kernel-rules.rst 。 | |
| 250 | 220 | |
| 251 | −如果更改影响到用户和内核接口,请向手册页维护人员(如维护人员文件中所列)发送 | |
| 221 | +如果更改影响到用户侧内核接口,请向手册页维护人员(如维护人员文件中所列)发送 | |
| 252 | 222 | 手册页补丁,或至少发送更改通知,以便一些信息进入手册页。还应将用户空间API |
| 253 | −更改复制到 linux-api@vger.kernel.org。 | |
| 223 | +更改抄送到 linux-api@vger.kernel.org 。 | |
| 254 | 224 | |
| 255 | 225 | |
| 256 | −6) 没有 MIME 编码,没有链接,没有压缩,没有附件,只有纯文本 | |
| 257 | −----------------------------------------------------------- | |
| 226 | +不要MIME编码,不要链接,不要压缩,不要附件,只要纯文本 | |
| 227 | +------------------------------------------------------ | |
| 258 | 228 | |
| 259 | 229 | Linus 和其他的内核开发者需要阅读和评论你提交的改动。对于内核开发者来说 |
| 260 | −,可以“引用”你的改动很重要,使用一般的 e-mail 工具,他们就可以在你的 | |
| 230 | +,可以“引用”你的改动很重要,使用一般的邮件工具,他们就可以在你的 | |
| 261 | 231 | 代码的任何位置添加评论。 |
| 262 | 232 | |
| 263 | −因为这个原因,所有的提交的补丁都是 e-mail 中“内嵌”的。 | |
| 233 | +因为这个原因,所有的提交的补丁都是邮件中“内嵌”的。最简单(和推荐)的方法就 | |
| 234 | +是使用 ``git send-email`` 。https://git-send-email.io 有 ``git send-email`` | |
| 235 | +的交互式教程。 | |
| 236 | + | |
| 237 | +如果你选择不用 ``git send-email`` : | |
| 264 | 238 | |
| 265 | 239 | .. warning:: |
| 266 | − 如果你使用剪切-粘贴你的补丁,小心你的编辑器的自动换行功能破坏你的补丁 | |
| 267 | 240 | |
| 268 | −不要将补丁作为 MIME 编码的附件,不管是否压缩。很多流行的 e-mail 软件不 | |
| 269 | −是任何时候都将 MIME 编码的附件当作纯文本发送的,这会使得别人无法在你的 | |
| 270 | −代码中加评论。另外,MIME 编码的附件会让 Linus 多花一点时间来处理,这就 | |
| 271 | −降低了你的改动被接受的可能性。 | |
| 241 | + 如果你使用剪切-粘贴你的补丁,小心你的编辑器的自动换行功能破坏你的补丁 | |
| 272 | 242 | |
| 273 | −例外:如果你的邮递员弄坏了补丁,那么有人可能会要求你使用mime重新发送补丁 | |
| 243 | +不要将补丁作为MIME编码的附件,不管是否压缩。很多流行的邮件软件不 | |
| 244 | +是任何时候都将MIME编码的附件当作纯文本发送的,这会使得别人无法在你的 | |
| 245 | +代码中加评论。另外,MIME编码的附件会让Linus多花一点时间来处理,这就 | |
| 246 | +降低了你的改动被接受的可能性。 | |
| 274 | 247 | |
| 275 | −请参阅 :ref:`Documentation/translations/zh_CN/process/email-clients.rst <cn_email_clients>` | |
| 276 | −以获取有关配置电子邮件客户端以使其不受影响地发送修补程序的提示。 | |
| 248 | +例外:如果你的邮路损坏了补丁,那么有人可能会要求你使用MIME重新发送补丁。 | |
| 277 | 249 | |
| 278 | −7) e-mail 的大小 | |
| 279 | −---------------- | |
| 250 | +请参阅 Documentation/translations/zh_CN/process/email-clients.rst | |
| 251 | +以获取有关配置电子邮件客户端以使其不受影响地发送补丁的提示。 | |
| 280 | 252 | |
| 281 | −大的改动对邮件列表不合适,对某些维护者也不合适。如果你的补丁,在不压缩 | |
| 282 | −的情况下,超过了300kB,那么你最好将补丁放在一个能通过 internet 访问的服 | |
| 283 | −务器上,然后用指向你的补丁的 URL 替代。但是请注意,如果您的补丁超过了 | |
| 284 | −300kb,那么它几乎肯定需要被破坏。 | |
| 253 | +回复审阅意见 | |
| 254 | +------------ | |
| 285 | 255 | |
| 286 | −8)回复评审意见 | |
| 287 | −--------------- | |
| 256 | +你的补丁几乎肯定会得到审阅者对补丁改进方法的评论(以回复邮件的形式)。您必须 | |
| 257 | +对这些评论作出回应;让补丁被忽略的一个好办法就是忽略审阅者的意见。直接回复邮 | |
| 258 | +件来回应意见即可。不会导致代码更改的意见或问题几乎肯定会带来注释或变更日志的 | |
| 259 | +改变,以便下一个审阅者更好地了解正在发生的事情。 | |
| 288 | 260 | |
| 289 | −你的补丁几乎肯定会得到评审者对补丁改进方法的评论。您必须对这些评论作出 | |
| 290 | −回应;让补丁被忽略的一个好办法就是忽略审阅者的意见。不会导致代码更改的 | |
| 291 | −意见或问题几乎肯定会带来注释或变更日志的改变,以便下一个评审者更好地了解 | |
| 292 | −正在发生的事情。 | |
| 261 | +一定要告诉审阅者你在做什么改变,并感谢他们的时间。代码审阅是一个累人且耗时的 | |
| 262 | +过程,审阅者有时会变得暴躁。即使在这种情况下,也要礼貌地回应并解决他们指出的 | |
| 263 | +问题。当发送下一版时,在封面邮件或独立补丁里加上 ``patch changelog`` 说明与 | |
| 264 | +前一版本的不同之处(参见 :ref:`zh_the_canonical_patch_format` )。 | |
| 293 | 265 | |
| 294 | −一定要告诉审稿人你在做什么改变,并感谢他们的时间。代码审查是一个累人且 | |
| 295 | −耗时的过程,审查人员有时会变得暴躁。即使在这种情况下,也要礼貌地回应并 | |
| 296 | −解决他们指出的问题。 | |
| 266 | +.. _zh_resend_reminders: | |
| 297 | 267 | |
| 298 | −9)不要泄气或不耐烦 | |
| 299 | −------------------- | |
| 268 | +不要泄气或不耐烦 | |
| 269 | +---------------- | |
| 300 | 270 | |
| 301 | −提交更改后,请耐心等待。审阅者是忙碌的人,可能无法立即访问您的修补程序。 | |
| 271 | +提交更改后,请耐心等待。审阅者是大忙人,可能无法立即审阅您的补丁。 | |
| 302 | 272 | |
| 303 | −曾几何时,补丁曾在没有评论的情况下消失在空白中,但开发过程比现在更加顺利。 | |
| 273 | +曾几何时,补丁曾在没收到评论的情况下消失在虚空中,但现在开发过程应该更加顺利了。 | |
| 304 | 274 | 您应该在一周左右的时间内收到评论;如果没有收到评论,请确保您已将补丁发送 |
| 305 | −到正确的位置。在重新提交或联系审阅者之前至少等待一周-在诸如合并窗口之类的 | |
| 275 | +到正确的位置。在重新提交或联系审阅者之前至少等待一周——在诸如合并窗口之类的 | |
| 306 | 276 | 繁忙时间可能更长。 |
| 307 | 277 | |
| 308 | −10)主题中包含 PATCH | |
| 309 | −-------------------- | |
| 278 | +在等了几个星期后,用带RESEND的主题重发补丁也是可以的:: | |
| 310 | 279 | |
| 311 | −由于到linus和linux内核的电子邮件流量很高,通常会在主题行前面加上[PATCH] | |
| 312 | −前缀. 这使Linus和其他内核开发人员更容易将补丁与其他电子邮件讨论区分开。 | |
| 280 | + [PATCH Vx RESEND] sub/sys: Condensed patch summary | |
| 313 | 281 | |
| 314 | −11)签署你的作品-开发者原始认证 | |
| 315 | −------------------------------- | |
| 282 | +当你发布补丁(系列)修改版的时候,不要加上“RESEND”——“RESEND”只适用于重 | |
| 283 | +新提交之前未经修改的补丁(系列)。 | |
| 316 | 284 | |
| 317 | −为了加强对谁做了何事的追踪,尤其是对那些透过好几层的维护者的补丁,我们 | |
| 318 | −建议在发送出去的补丁上加一个 “sign-off” 的过程。 | |
| 285 | +主题中包含 PATCH | |
| 286 | +---------------- | |
| 319 | 287 | |
| 320 | −"sign-off" 是在补丁的注释的最后的简单的一行文字,认证你编写了它或者其他 | |
| 288 | +由于到Linus和linux-kernel的电子邮件流量很高,通常会在主题行前面加上[PATCH] | |
| 289 | +前缀。这使Linus和其他内核开发人员更容易将补丁与其他电子邮件讨论区分开。 | |
| 290 | + | |
| 291 | +``git send-email`` 会自动为你加上。 | |
| 292 | + | |
| 293 | +签署你的作品——开发者来源认证 | |
| 294 | +------------------------------ | |
| 295 | + | |
| 296 | +为了加强对谁做了何事的追踪,尤其是对那些透过好几层维护者才最终到达的补丁,我 | |
| 297 | +们在通过邮件发送的补丁上引入了“签署(sign-off)”流程。 | |
| 298 | + | |
| 299 | +“签署”是在补丁注释最后的一行简单文字,认证你编写了它或者其他 | |
| 321 | 300 | 人有权力将它作为开放源代码的补丁传递。规则很简单:如果你能认证如下信息: |
| 322 | 301 | |
| 323 | −开发者来源证书 1.1 | |
| 302 | +开发者来源认证 1.1 | |
| 324 | 303 | ^^^^^^^^^^^^^^^^^^ |
| 325 | 304 | |
| 326 | 305 | 对于本项目的贡献,我认证如下信息: |
| 327 | 306 | |
| 328 | − (a)这些贡献是完全或者部分的由我创建,我有权利以文件中指出 | |
| 307 | + (a) 这些贡献是完全或者部分的由我创建,我有权利以文件中指出 | |
| 329 | 308 | 的开放源代码许可证提交它;或者 |
| 330 | − (b)这些贡献基于以前的工作,据我所知,这些以前的工作受恰当的开放 | |
| 331 | − 源代码许可证保护,而且,根据许可证,我有权提交修改后的贡献, | |
| 309 | + | |
| 310 | + (b) 这些贡献基于以前的工作,据我所知,这些以前的工作受恰当的开放 | |
| 311 | + 源代码许可证保护,而且,根据文件中指出的许可证,我有权提交修改后的贡献, | |
| 332 | 312 | 无论是完全还是部分由我创造,这些贡献都使用同一个开放源代码许可证 |
| 333 | − (除非我被允许用其它的许可证),正如文件中指出的;或者 | |
| 334 | − (c)这些贡献由认证(a),(b)或者(c)的人直接提供给我,而 | |
| 313 | + (除非我被允许用其它的许可证);或者 | |
| 314 | + | |
| 315 | + (c) 这些贡献由认证(a),(b)或者(c)的人直接提供给我,而 | |
| 335 | 316 | 且我没有修改它。 |
| 336 | − (d)我理解并同意这个项目和贡献是公开的,贡献的记录(包括我 | |
| 337 | − 一起提交的个人记录,包括 sign-off )被永久维护并且可以和这个项目 | |
| 317 | + | |
| 318 | + (d) 我理解并同意这个项目和贡献是公开的,贡献的记录(包括我 | |
| 319 | + 一起提交的个人记录,包括sign-off)被永久维护并且可以和这个项目 | |
| 338 | 320 | 或者开放源代码的许可证同步地再发行。 |
| 339 | 321 | |
| 340 | 322 | 那么加入这样一行:: |
| 341 | 323 | |
| 342 | − Signed-off-by: Random J Developer <random@developer.example.org> | |
| 343 | − | |
| 344 | −使用你的真名(抱歉,不能使用假名或者匿名。) | |
| 345 | − | |
| 346 | −有人在最后加上标签。现在这些东西会被忽略,但是你可以这样做,来标记公司 | |
| 347 | −内部的过程,或者只是指出关于 sign-off 的一些特殊细节。 | |
| 348 | − | |
| 349 | −如果您是子系统或分支维护人员,有时需要稍微修改收到的补丁,以便合并它们, | |
| 350 | −因为树和提交者中的代码不完全相同。如果你严格遵守规则(c),你应该要求提交者 | |
| 351 | −重新发布,但这完全是在浪费时间和精力。规则(b)允许您调整代码,但是更改一个 | |
| 352 | −提交者的代码并让他认可您的错误是非常不礼貌的。要解决此问题,建议在最后一个 | |
| 353 | −由签名行和您的行之间添加一行,指示更改的性质。虽然这并不是强制性的,但似乎 | |
| 354 | −在描述前加上您的邮件和/或姓名(全部用方括号括起来),这足以让人注意到您对最 | |
| 355 | −后一分钟的更改负有责任。例如:: | |
| 356 | − | |
| 357 | − Signed-off-by: Random J Developer <random@developer.example.org> | |
| 358 | − [lucky@maintainer.example.org: struct foo moved from foo.c to foo.h] | |
| 359 | − Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org> | |
| 360 | − | |
| 361 | −如果您维护一个稳定的分支机构,同时希望对作者进行致谢、跟踪更改、合并修复并 | |
| 362 | −保护提交者不受投诉,那么这种做法尤其有用。请注意,在任何情况下都不能更改作者 | |
| 363 | −的ID(From 头),因为它是出现在更改日志中的标识。 | |
| 364 | − | |
| 365 | −对回合(back-porters)的特别说明:在提交消息的顶部(主题行之后)插入一个补丁 | |
| 366 | −的起源指示似乎是一种常见且有用的实践,以便于跟踪。例如,下面是我们在3.x稳定 | |
| 367 | −版本中看到的内容:: | |
| 368 | − | |
| 369 | − Date: Tue Oct 7 07:26:38 2014 -0400 | |
| 370 | − | |
| 371 | − libata: Un-break ATA blacklist | |
| 372 | − | |
| 373 | − commit 1c40279960bcd7d52dbdf1d466b20d24b99176c8 upstream. | |
| 374 | − | |
| 375 | −还有, 这里是一个旧版内核中的一个回合补丁:: | |
| 324 | + Signed-off-by: Random J Developer <random@developer.example.org> | |
| 376 | 325 | |
| 377 | − Date: Tue May 13 22:12:27 2008 +0200 | |
| 326 | +使用你的真名(抱歉,不能使用假名或者匿名。)如果使用 ``git commit -s`` 的话 | |
| 327 | +将会自动完成。撤销也应当包含“Signed-off-by”, ``git revert -s`` 会帮你搞定。 | |
| 378 | 328 | |
| 379 | − wireless, airo: waitbusy() won't delay | |
| 329 | +有些人会在最后加上额外的标签。现在这些东西会被忽略,但是你可以这样做,来标记 | |
| 330 | +公司内部的过程,或者只是指出关于签署的一些特殊细节。 | |
| 380 | 331 | |
| 381 | − [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a] | |
| 332 | +作者签署之后的任何其他签署(Signed-off-by:'s)均来自处理和传递补丁的人员,但 | |
| 333 | +未参与其开发。签署链应当反映补丁传播到维护者并最终传播到Linus所经过的 **真实** | |
| 334 | +路径,首个签署指明单个作者的主要作者身份。 | |
| 382 | 335 | |
| 383 | −12)何时使用Acked-by:,CC:,和Co-Developed by: | |
| 384 | −---------------------------------------------- | |
| 336 | +何时使用Acked-by:,CC:,和Co-Developed by: | |
| 337 | +------------------------------------------ | |
| 385 | 338 | |
| 386 | −Singed-off-by: 标记表示签名者参与了补丁的开发,或者他/她在补丁的传递路径中。 | |
| 339 | +Singed-off-by: 标签表示签名者参与了补丁的开发,或者他/她在补丁的传递路径中。 | |
| 387 | 340 | |
| 388 | −如果一个人没有直接参与补丁的准备或处理,但希望表示并记录他们对补丁的批准, | |
| 389 | −那么他们可以要求在补丁的变更日志中添加一个 Acked-by: | |
| 341 | +如果一个人没有直接参与补丁的准备或处理,但希望表示并记录他们对补丁的批准/赞成, | |
| 342 | +那么他们可以要求在补丁的变更日志中添加一个Acked-by:。 | |
| 390 | 343 | |
| 391 | −Acked-by:通常由受影响代码的维护者使用,当该维护者既没有贡献也没有转发补丁时。 | |
| 344 | +Acked-by: 通常由受影响代码的维护者使用,当该维护者既没有贡献也没有转发补丁时。 | |
| 392 | 345 | |
| 393 | −Acked-by: 不像签字人那样正式。这是一个记录,确认人至少审查了补丁,并表示接受。 | |
| 394 | −因此,补丁合并有时会手动将Acker的“Yep,looks good to me”转换为 Acked-By:(但 | |
| 346 | +Acked-by: 不像签署那样正式。这是一个记录,确认人至少审阅了补丁,并表示接受。 | |
| 347 | +因此,补丁合并有时会手动将Acker的“Yep,looks good to me”转换为 Acked-By:(但 | |
| 395 | 348 | 请注意,通常最好要求一个明确的Ack)。 |
| 396 | 349 | |
| 397 | 350 | Acked-by:不一定表示对整个补丁的确认。例如,如果一个补丁影响多个子系统,并且 |
| 398 | −有一个:来自一个子系统维护者,那么这通常表示只确认影响维护者代码的部分。这里 | |
| 399 | −应该仔细判断。如有疑问,应参考邮件列表档案中的原始讨论。 | |
| 351 | +有一个来自某个子系统维护者的Acked-By:,那么这通常表示只确认影响维护者代码的部 | |
| 352 | +分。这里应该仔细判断。如有疑问,应参考邮件列表存档中的原始讨论。 | |
| 400 | 353 | |
| 401 | −如果某人有机会对补丁进行评论,但没有提供此类评论,您可以选择在补丁中添加 ``Cc:`` | |
| 402 | −这是唯一一个标签,它可以在没有被它命名的人显式操作的情况下添加,但它应该表明 | |
| 403 | −这个人是在补丁上抄送的。讨论中包含了潜在利益相关方。 | |
| 354 | +如果某人本应有机会对补丁进行评论,但没有提供此类评论,您可以选择在补丁中添加 | |
| 355 | +``Cc:`` 这是唯一可以在没有被该人明确同意的情况下添加的标签——但它应该表明 | |
| 356 | +这个人是在补丁上抄送的。此标签记录了讨论中包含的潜在利益相关方。 | |
| 404 | 357 | |
| 405 | 358 | Co-developed-by: 声明补丁是由多个开发人员共同创建的;当几个人在一个补丁上工 |
| 406 | −作时,它用于将属性赋予共同作者(除了 From: 所赋予的作者之外)。因为 | |
| 407 | −Co-developed-by: 表示作者身份,所以每个共同开发人:必须紧跟在相关合作作者的 | |
| 408 | −签名之后。标准的签核程序要求:标记的签核顺序应尽可能反映补丁的时间历史,而不 | |
| 409 | −管作者是通过 From :还是由 Co-developed-by: 共同开发的。值得注意的是,最后一 | |
| 410 | −个签字人:必须始终是提交补丁的开发人员。 | |
| 359 | +作时,它用于给出共同作者(除了From:所给出的作者之外)。因为Co-developed-by: | |
| 360 | +表示作者身份,所以每个Co-developed-by:必须紧跟在相关合作作者的签署之后。标准 | |
| 361 | +签署程序要求Singed-off-by:标签的顺序应尽可能反映补丁的时间历史,无论作者是通 | |
| 362 | +过From:还是Co-developed-by:表明。值得注意的是,最后一个Singed-off-by:必须是 | |
| 363 | +提交补丁的开发人员。 | |
| 411 | 364 | |
| 412 | −注意,当作者也是电子邮件标题“发件人:”行中列出的人时,“From: ” 标记是可选的。 | |
| 365 | +注意,如果From:作者也是电子邮件标题的From:行中列出的人,则From:标签是可选的。 | |
| 413 | 366 | |
| 414 | −作者提交的补丁程序示例:: | |
| 367 | +被From:作者提交的补丁示例:: | |
| 415 | 368 | |
| 416 | 369 | <changelog> |
| 417 | 370 | |
| @@ -421,7 +374,7 @@ Co-developed-by: 表示作者身份,所以每个共同开发人:必须紧跟 · 3 unmodified lines | ||
| 421 | 374 | Signed-off-by: Second Co-Author <second@coauthor.example.org> |
| 422 | 375 | Signed-off-by: From Author <from@author.example.org> |
| 423 | 376 | |
| 424 | −合作开发者提交的补丁示例:: | |
| 377 | +被合作开发者提交的补丁示例:: | |
| 425 | 378 | |
| 426 | 379 | From: From Author <from@author.example.org> |
| 427 | 380 | |
| @@ -434,76 +387,85 @@ Co-developed-by: 表示作者身份,所以每个共同开发人:必须紧跟 · 6 unmodified lines | ||
| 434 | 387 | Signed-off-by: Submitting Co-Author <sub@coauthor.example.org> |
| 435 | 388 | |
| 436 | 389 | |
| 437 | −13)使用报告人:、测试人:、审核人:、建议人:、修复人: | |
| 438 | −-------------------------------------------------------- | |
| 390 | +使用Reported-by:、Tested-by:、Reviewed-by:、Suggested-by:和Fixes: | |
| 391 | +----------------------------------------------------------------- | |
| 439 | 392 | |
| 440 | 393 | Reported-by: 给那些发现错误并报告错误的人致谢,它希望激励他们在将来再次帮助 |
| 441 | −我们。请注意,如果bug是以私有方式报告的,那么在使用Reported-by标记之前,请 | |
| 442 | −先请求权限。 | |
| 394 | +我们。请注意,如果bug是以私有方式报告的,那么在使用Reported-by标签之前,请 | |
| 395 | +先请求许可。此标签是为Bug设计的;请不要将其用于感谢功能请求。 | |
| 443 | 396 | |
| 444 | −Tested-by: 标记表示补丁已由指定的人(在某些环境中)成功测试。这个标签通知 | |
| 445 | −维护人员已经执行了一些测试,为将来的补丁提供了一种定位测试人员的方法,并确 | |
| 446 | −保测试人员的信誉。 | |
| 397 | +Tested-by: 标签表示补丁已由指定的人(在某些环境中)成功测试。这个标签通知 | |
| 398 | +维护人员已经执行了一些测试,为将来的补丁提供了一种定位测试人员的方法,并彰显测试人员的功劳。 | |
| 447 | 399 | |
| 448 | −Reviewed-by:相反,根据审查人的声明,表明该补丁已被审查并被认为是可接受的: | |
| 400 | +Reviewed-by:根据审阅者的监督声明,表明该补丁已被审阅并被认为是可接受的: | |
| 449 | 401 | |
| 450 | 402 | |
| 451 | −审查人的监督声明 | |
| 403 | +审阅者的监督声明 | |
| 452 | 404 | ^^^^^^^^^^^^^^^^ |
| 453 | 405 | |
| 454 | −通过提供我的 Reviewed-by,我声明: | |
| 406 | +通过提供我的Reviewed-by:标签,我声明: | |
| 455 | 407 | |
| 456 | − (a) 我已经对这个补丁进行了一次技术审查,以评估它是否适合被包含到 | |
| 408 | + (a) 我已经对这个补丁进行了一次技术审阅,以评估它是否适合被包含到 | |
| 457 | 409 | 主线内核中。 |
| 458 | 410 | |
| 459 | 411 | (b) 与补丁相关的任何问题、顾虑或问题都已反馈给提交者。我对提交者对 |
| 460 | 412 | 我的评论的回应感到满意。 |
| 461 | 413 | |
| 462 | − (c) 虽然这一提交可能会改进一些东西,但我相信,此时,(1)对内核 | |
| 414 | + (c) 虽然这一提交可能仍可被改进,但我相信,此时,(1)对内核 | |
| 463 | 415 | 进行了有价值的修改,(2)没有包含争论中涉及的已知问题。 |
| 464 | 416 | |
| 465 | − (d) 虽然我已经审查了补丁并认为它是健全的,但我不会(除非另有明确 | |
| 466 | − 说明)作出任何保证或保证它将在任何给定情况下实现其规定的目的 | |
| 417 | + (d) 虽然我已经审阅了补丁并认为它是健全的,但我不会(除非另有明确 | |
| 418 | + 说明)作出任何保证或担保它会在任何给定情况下实现其规定的目的 | |
| 467 | 419 | 或正常运行。 |
| 468 | 420 | |
| 469 | −Reviewed-by 是一种观点声明,即补丁是对内核的适当修改,没有任何遗留的严重技术 | |
| 470 | −问题。任何感兴趣的审阅者(完成工作的人)都可以为一个补丁提供一个 Review-by | |
| 471 | −标签。此标签用于向审阅者提供致谢,并通知维护者已在修补程序上完成的审阅程度。 | |
| 472 | −Reviewed-by: 当由已知了解主题区域并执行彻底检查的审阅者提供时,通常会增加 | |
| 421 | +Reviewed-by是一种观点声明,即补丁是对内核的适当修改,没有任何遗留的严重技术 | |
| 422 | +问题。任何感兴趣的审阅者(完成工作的人)都可以为一个补丁提供一个Reviewed-by | |
| 423 | +标签。此标签用于向审阅者提供致谢,并通知维护者补丁的审阅进度。 | |
| 424 | +当Reviewed-by:标签由已知了解主题区域并执行彻底检查的审阅者提供时,通常会增加 | |
| 473 | 425 | 补丁进入内核的可能性。 |
| 474 | 426 | |
| 427 | +一旦从测试人员或审阅者的“Tested-by”和“Reviewed-by”标签出现在邮件列表中, | |
| 428 | +作者应在发送下一个版本时将其添加到适用的补丁中。但是,如果补丁在以下版本中发 | |
| 429 | +生了实质性更改,这些标签可能不再适用,因此应该删除。通常,在补丁更改日志中 | |
| 430 | +(在 ``---`` 分隔符之后)应该提到删除某人的测试者或审阅者标签。 | |
| 431 | + | |
| 475 | 432 | Suggested-by: 表示补丁的想法是由指定的人提出的,并确保将此想法归功于指定的 |
| 476 | 433 | 人。请注意,未经许可,不得添加此标签,特别是如果该想法未在公共论坛上发布。 |
| 477 | −这就是说,如果我们勤快地致谢我们的创意者,他们很有希望在未来得到鼓舞,再次 | |
| 434 | +也就是说,如果我们勤快地致谢创意提供者,他们将受到鼓舞,很有希望在未来再次 | |
| 478 | 435 | 帮助我们。 |
| 479 | 436 | |
| 480 | −Fixes: 指示补丁在以前的提交中修复了一个问题。它可以很容易地确定错误的来源, | |
| 481 | −这有助于检查错误修复。这个标记还帮助稳定内核团队确定应该接收修复的稳定内核 | |
| 482 | −版本。这是指示补丁修复的错误的首选方法。请参阅 :ref:`cn_describe_changes` | |
| 483 | −描述您的更改以了解更多详细信息。 | |
| 437 | +Fixes: 指示补丁修复了之前提交的一个问题。它可以便于确定错误的来源,这有助于 | |
| 438 | +检查错误修复。这个标签还帮助稳定内核团队确定应该接收修复的稳定内核版本。这是 | |
| 439 | +指示补丁修复的错误的首选方法。请参阅 :ref:`zh_describe_changes` 了解更多信息。 | |
| 484 | 440 | |
| 485 | −.. _cn_the_canonical_patch_format: | |
| 441 | +.. note:: | |
| 486 | 442 | |
| 487 | −12)标准补丁格式 | |
| 488 | −---------------- | |
| 443 | + 附加Fixes:标签不会改变稳定内核规则流程,也不改变所有稳定版补丁抄送 | |
| 444 | + stable@vger.kernel.org的要求。有关更多信息,请阅读 | |
| 445 | + Documentation/translations/zh_CN/process/stable-kernel-rules.rst 。 | |
| 446 | + | |
| 447 | +.. _zh_the_canonical_patch_format: | |
| 448 | + | |
| 449 | +标准补丁格式 | |
| 450 | +------------ | |
| 489 | 451 | |
| 490 | 452 | 本节描述如何格式化补丁本身。请注意,如果您的补丁存储在 ``Git`` 存储库中,则 |
| 491 | −可以使用 ``git format-patch`` 进行正确的补丁格式设置。但是,这些工具无法创建 | |
| 453 | +可以使用 ``git format-patch`` 进行正确的补丁格式化。但是,这些工具无法创建 | |
| 492 | 454 | 必要的文本,因此请务必阅读下面的说明。 |
| 493 | 455 | |
| 494 | −标准的补丁,标题行是:: | |
| 456 | +标准的补丁标题行是:: | |
| 495 | 457 | |
| 496 | 458 | Subject: [PATCH 001/123] 子系统:一句话概述 |
| 497 | 459 | |
| 498 | −标准补丁的信体存在如下部分: | |
| 460 | +标准补丁的信体包含如下部分: | |
| 499 | 461 | |
| 500 | − - 一个 "from" 行指出补丁作者。后跟空行(仅当发送修补程序的人不是作者时才需要)。 | |
| 462 | + - 一个 ``from`` 行指出补丁作者。后跟空行(仅当发送补丁的人不是作者时才需要)。 | |
| 501 | 463 | |
| 502 | − - 解释的正文,行以75列包装,这将被复制到永久变更日志来描述这个补丁。 | |
| 464 | + - 说明文字,每行最长75列,这将被复制到永久变更日志来描述这个补丁。 | |
| 503 | 465 | |
| 504 | 466 | - 一个空行 |
| 505 | 467 | |
| 506 | − - 上面描述的“Signed-off-by” 行,也将出现在更改日志中。 | |
| 468 | + - 上述的 ``Signed-off-by:`` 行,也将出现在更改日志中。 | |
| 507 | 469 | |
| 508 | 470 | - 只包含 ``---`` 的标记线。 |
| 509 | 471 | |
| @@ -511,29 +473,29 @@ Fixes: 指示补丁在以前的提交中修复了一个问题。它可以很容 · 1 unmodified line | ||
| 511 | 473 | |
| 512 | 474 | - 实际补丁( ``diff`` 输出)。 |
| 513 | 475 | |
| 514 | −标题行的格式,使得对标题行按字母序排序非常的容易 - 很多 e-mail 客户端都 | |
| 515 | −可以支持 - 因为序列号是用零填充的,所以按数字排序和按字母排序是一样的。 | |
| 476 | +标题行的格式,使得对标题行按字母序排序非常的容易——很多邮件客户端都 | |
| 477 | +可以支持——因为序列号是用零填充的,所以按数字排序和按字母排序是一样的。 | |
| 516 | 478 | |
| 517 | −e-mail 标题中的“子系统”标识哪个内核子系统将被打补丁。 | |
| 479 | +邮件标题中的“子系统”标识哪个内核子系统将被打补丁。 | |
| 518 | 480 | |
| 519 | −e-mail 标题中的“一句话概述”扼要的描述 e-mail 中的补丁。“一句话概述” | |
| 481 | +邮件标题中的“一句话概述”扼要的描述邮件中的补丁。“一句话概述” | |
| 520 | 482 | 不应该是一个文件名。对于一个补丁系列(“补丁系列”指一系列的多个相关补 |
| 521 | 483 | 丁),不要对每个补丁都使用同样的“一句话概述”。 |
| 522 | 484 | |
| 523 | −记住 e-mail 的“一句话概述”会成为该补丁的全局唯一标识。它会蔓延到 git | |
| 485 | +记住邮件的“一句话概述”会成为该补丁的全局唯一标识。它会进入 ``git`` | |
| 524 | 486 | 的改动记录里。然后“一句话概述”会被用在开发者的讨论里,用来指代这个补 |
| 525 | −丁。用户将希望通过 google 来搜索"一句话概述"来找到那些讨论这个补丁的文 | |
| 487 | +丁。用户将希望通过搜索引擎搜索“一句话概述”来找到那些讨论这个补丁的文 | |
| 526 | 488 | 章。当人们在两三个月后使用诸如 ``gitk`` 或 ``git log --oneline`` 之类 |
| 527 | 489 | 的工具查看数千个补丁时,也会很快看到它。 |
| 528 | 490 | |
| 529 | 491 | 出于这些原因,概述必须不超过70-75个字符,并且必须描述补丁的更改以及为 |
| 530 | −什么需要补丁。既要简洁又要描述性很有挑战性,但写得好的概述应该这样做。 | |
| 492 | +什么需要补丁。既要简洁又要描述性很有挑战性,但写得好的概述应该这样。 | |
| 531 | 493 | |
| 532 | 494 | 概述的前缀可以用方括号括起来:“Subject: [PATCH <tag>...] <概述>”。标记 |
| 533 | 495 | 不被视为概述的一部分,而是描述应该如何处理补丁。如果补丁的多个版本已发 |
| 534 | −送出来以响应评审(即“v1,v2,v3”)或“rfc”,以指示评审请求,那么通用标记 | |
| 535 | −可能包括版本描述符。如果一个补丁系列中有四个补丁,那么各个补丁可以这样 | |
| 536 | −编号:1/4、2/4、3/4、4/4。这可以确保开发人员了解补丁应用的顺序,并且他们 | |
| 496 | +送出来以响应评审(即“v1,v2,v3”)则必须包含版本号,或包含“RFC”以指示 | |
| 497 | +评审请求。如果一个补丁系列中有四个补丁,那么各个补丁可以这样编号:1/4、2/4、 | |
| 498 | +3/4、4/4。这可以确保开发人员了解补丁应用的顺序,且 | |
| 537 | 499 | 已经查看或应用了补丁系列中的所有补丁。 |
| 538 | 500 | |
| 539 | 501 | 一些标题的例子:: |
| @@ -541,95 +503,134 @@ e-mail 标题中的“一句话概述”扼要的描述 e-mail 中的补丁。 · 1 unmodified line | ||
| 541 | 503 | Subject: [patch 2/5] ext2: improve scalability of bitmap searching |
| 542 | 504 | Subject: [PATCHv2 001/207] x86: fix eflags tracking |
| 543 | 505 | |
| 544 | −"From" 行是信体里的最上面一行,具有如下格式: | |
| 506 | +``From`` 行是信体里的最上面一行,具有如下格式:: | |
| 507 | + | |
| 545 | 508 | From: Patch Author <author@example.com> |
| 546 | 509 | |
| 547 | −"From" 行指明在永久改动日志里,谁会被确认为作者。如果没有 "From" 行,那 | |
| 548 | −么邮件头里的 "From: " 行会被用来决定改动日志中的作者。 | |
| 510 | +``From`` 行指明在永久改动日志里,谁会被确认为作者。如果没有 ``From`` 行,那 | |
| 511 | +么邮件头里的 ``From:`` 行会被用来决定改动日志中的作者。 | |
| 549 | 512 | |
| 550 | −说明的主题将会被提交到永久的源代码改动日志里,因此对那些早已经不记得和 | |
| 551 | −这个补丁相关的讨论细节的有能力的读者来说,是有意义的。包括补丁程序定位 | |
| 552 | −错误的(内核日志消息、OOPS消息等)症状,对于搜索提交日志以寻找适用补丁的人 | |
| 553 | −尤其有用。如果一个补丁修复了一个编译失败,那么可能不需要包含所有编译失败; | |
| 513 | +说明文字将会被提交到永久的源代码改动日志里,因此应针对那些早已经不记得和这 | |
| 514 | +个补丁相关的讨论细节的读者。包括补丁处理的故障症状(内核日志消息、oops消息 | |
| 515 | +等),这对于可能正在搜索提交日志以查找适用补丁的人特别有用。文本应该写得如 | |
| 516 | +此详细,以便在数周、数月甚至数年后阅读时,能够为读者提供所需的细节信息,以 | |
| 517 | +掌握创建补丁的 **原因** 。 | |
| 518 | + | |
| 519 | +如果一个补丁修复了一个编译失败,那么可能不需要包含 *所有* 编译失败; | |
| 554 | 520 | 只要足够让搜索补丁的人能够找到它就行了。与概述一样,既要简洁又要描述性。 |
| 555 | 521 | |
| 556 | −"---" 标记行对于补丁处理工具要找到哪里是改动日志信息的结束,是不可缺少 | |
| 522 | +``---`` 标记行对于补丁处理工具要找到哪里是改动日志信息的结束,是不可缺少 | |
| 557 | 523 | 的。 |
| 558 | 524 | |
| 559 | −对于 "---" 标记之后的额外注解,一个好的用途就是用来写 diffstat,用来显 | |
| 560 | −示修改了什么文件和每个文件都增加和删除了多少行。diffstat 对于比较大的补 | |
| 561 | −丁特别有用。其余那些只是和时刻或者开发者相关的注解,不合适放到永久的改 | |
| 562 | −动日志里的,也应该放这里。 | |
| 563 | −使用 diffstat的选项 "-p 1 -w 70" 这样文件名就会从内核源代码树的目录开始 | |
| 525 | +对于 ``---`` 标记之后的额外注解,一个好的用途就是用来写 ``diffstat`` ,用来显 | |
| 526 | +示修改了什么文件和每个文件都增加和删除了多少行。 ``diffstat`` 对于比较大的补 | |
| 527 | +丁特别有用。 | |
| 528 | +使用 ``diffstat`` 的选项 ``-p 1 -w 70`` 这样文件名就会从内核源代码树的目录开始 | |
| 564 | 529 | ,不会占用太宽的空间(很容易适合80列的宽度,也许会有一些缩进。) |
| 530 | +( ``git`` 默认会生成合适的diffstat。) | |
| 531 | + | |
| 532 | +其余那些只适用于当时或者与维护者相关的注解,不合适放到永久的改动日志里的,也 | |
| 533 | +应该放这里。较好的例子就是 ``补丁更改记录`` ,记录了v1和v2版本补丁之间的差异。 | |
| 534 | + | |
| 535 | +请将此信息放在将变更日志与补丁的其余部分分隔开的 ``---`` 行 **之后** 。版本 | |
| 536 | +信息不是提交到git树的变更日志的一部分。只是供审阅人员使用的附加信息。如果将 | |
| 537 | +其放置在提交标记上方,则需要手动交互才能将其删除。如果它位于分隔线以下,则在 | |
| 538 | +应用补丁时会自动剥离:: | |
| 539 | + | |
| 540 | + <commit message> | |
| 541 | + ... | |
| 542 | + Signed-off-by: Author <author@mail> | |
| 543 | + --- | |
| 544 | + V2 -> V3: Removed redundant helper function | |
| 545 | + V1 -> V2: Cleaned up coding style and addressed review comments | |
| 565 | 546 | |
| 566 | −在后面的参考资料中能看到适当的补丁格式的更多细节。 | |
| 547 | + path/to/file | 5+++-- | |
| 548 | + ... | |
| 567 | 549 | |
| 568 | −.. _cn_explicit_in_reply_to: | |
| 550 | +在后面的参考资料中能看到正确补丁格式的更多细节。 | |
| 569 | 551 | |
| 570 | −15) 明确回复邮件头(In-Reply-To) | |
| 571 | −------------------------------- | |
| 552 | +.. _zh_backtraces: | |
| 572 | 553 | |
| 573 | −手动添加回复补丁的的标题头(In-Reply_To:) 是有帮助的(例如,使用 ``git send-email`` ) | |
| 574 | −将补丁与以前的相关讨论关联起来,例如,将bug修复程序链接到电子邮件和bug报告。 | |
| 554 | +提交消息中的回溯(Backtraces) | |
| 555 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 556 | + | |
| 557 | +回溯有助于记录导致问题的调用链。然而,并非所有回溯都有帮助。例如,早期引导调 | |
| 558 | +用链是独特而明显的。而逐字复制完整的dmesg输出则会增加时间戳、模块列表、寄存 | |
| 559 | +器和堆栈转储等分散注意力的信息。 | |
| 560 | + | |
| 561 | +因此,最有用的回溯应该从转储中提取相关信息,以更容易集中在真实问题上。下面是 | |
| 562 | +一个剪裁良好的回溯示例:: | |
| 563 | + | |
| 564 | + unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064) | |
| 565 | + at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20) | |
| 566 | + Call Trace: | |
| 567 | + mba_wrmsr | |
| 568 | + update_domains | |
| 569 | + rdtgroup_mkdir | |
| 570 | + | |
| 571 | +.. _zh_explicit_in_reply_to: | |
| 572 | + | |
| 573 | +明确回复邮件头(In-Reply-To) | |
| 574 | +----------------------------- | |
| 575 | + | |
| 576 | +手动添加回复补丁的的邮件头(In-Reply_To:)是有用的(例如,使用 ``git send-email`` ), | |
| 577 | +可以将补丁与以前的相关讨论关联起来,例如,将bug补丁链接到电子邮件和bug报告。 | |
| 575 | 578 | 但是,对于多补丁系列,最好避免在回复时使用链接到该系列的旧版本。这样, |
| 576 | −补丁的多个版本就不会成为电子邮件客户端中无法管理的引用序列。如果链接有用, | |
| 579 | +补丁的多个版本就不会成为电子邮件客户端中无法管理的引用树。如果链接有用, | |
| 577 | 580 | 可以使用 https://lore.kernel.org/ 重定向器(例如,在封面电子邮件文本中) |
| 578 | 581 | 链接到补丁系列的早期版本。 |
| 579 | 582 | |
| 580 | −16) 发送git pull请求 | |
| 581 | −-------------------- | |
| 582 | − | |
| 583 | −如果您有一系列补丁,那么让维护人员通过git pull操作将它们直接拉入子系统存储 | |
| 584 | −库可能是最方便的。但是,请注意,从开发人员那里获取补丁比从邮件列表中获取补 | |
| 585 | −丁需要更高的信任度。因此,许多子系统维护人员不愿意接受请求,特别是来自新的 | |
| 586 | −未知开发人员的请求。如果有疑问,您可以在封面邮件中使用pull 请求作为补丁系列 | |
| 587 | −正常发布的一个选项,让维护人员可以选择使用其中之一。 | |
| 588 | − | |
| 589 | −pull 请求的主题行中应该有[Git Pull]。请求本身应该在一行中包含存储库名称和 | |
| 590 | −感兴趣的分支;它应该看起来像:: | |
| 583 | +给出基础树信息 | |
| 584 | +-------------- | |
| 591 | 585 | |
| 592 | − Please pull from | |
| 586 | +当其他开发人员收到您的补丁并开始审阅时,知道应该将您的工作放到代码树历史记录 | |
| 587 | +中的什么位置通常很有用。这对于自动化持续集成流水(CI)特别有用,这些流水线试 | |
| 588 | +图运行一系列测试,以便在维护人员开始审阅之前确定提交的质量。 | |
| 593 | 589 | |
| 594 | − git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus | |
| 590 | +如果您使用 ``git format-patch`` 生成补丁,则可以通过 ``--base`` 标志在提交中 | |
| 591 | +自动包含基础树信息。使用此选项最简单、最方便的方法是配合主题分支:: | |
| 595 | 592 | |
| 596 | − to get these changes: | |
| 593 | + $ git checkout -t -b my-topical-branch master | |
| 594 | + Branch 'my-topical-branch' set up to track local branch 'master'. | |
| 595 | + Switched to a new branch 'my-topical-branch' | |
| 597 | 596 | |
| 597 | + [perform your edits and commits] | |
| 598 | 598 | |
| 599 | −pull 请求还应该包含一条整体消息,说明请求中将包含什么,一个补丁本身的 ``Git shortlog`` | |
| 600 | −以及一个显示补丁系列整体效果的 ``diffstat`` 。当然,将所有这些信息收集在一起 | |
| 601 | −的最简单方法是让 ``git`` 使用 ``git request-pull`` 命令为您完成这些工作。 | |
| 599 | + $ git format-patch --base=auto --cover-letter -o outgoing/ master | |
| 600 | + outgoing/0000-cover-letter.patch | |
| 601 | + outgoing/0001-First-Commit.patch | |
| 602 | + outgoing/... | |
| 602 | 603 | |
| 603 | −一些维护人员(包括Linus)希望看到来自已签名提交的请求;这增加了他们对你的 | |
| 604 | −请求信心。特别是,在没有签名标签的情况下,Linus 不会从像 Github 这样的公共 | |
| 605 | −托管站点拉请求。 | |
| 604 | +当你编辑 ``outgoing/0000-cover-letter.patch`` 时,您会注意到在它的最底部有一 | |
| 605 | +行 ``base-commit:`` 尾注,它为审阅者和CI工具提供了足够的信息以正确执行 | |
| 606 | +``git am`` 而不必担心冲突:: | |
| 606 | 607 | |
| 607 | −创建此类签名的第一步是生成一个 GNRPG 密钥,并由一个或多个核心内核开发人员对 | |
| 608 | −其进行签名。这一步对新开发人员来说可能很困难,但没有办法绕过它。参加会议是 | |
| 609 | −找到可以签署您的密钥的开发人员的好方法。 | |
| 608 | + $ git checkout -b patch-review [base-commit-id] | |
| 609 | + Switched to a new branch 'patch-review' | |
| 610 | + $ git am patches.mbox | |
| 611 | + Applying: First Commit | |
| 612 | + Applying: ... | |
| 610 | 613 | |
| 611 | −一旦您在Git 中准备了一个您希望有人拉的补丁系列,就用 ``git tag -s`` 创建一 | |
| 612 | −个签名标记。这将创建一个新标记,标识该系列中的最后一次提交,并包含用您的私 | |
| 613 | −钥创建的签名。您还可以将changelog样式的消息添加到标记中;这是一个描述拉请求 | |
| 614 | −整体效果的理想位置。 | |
| 614 | +有关此选项的更多信息,请参阅 ``man git-format-patch`` 。 | |
| 615 | 615 | |
| 616 | −如果维护人员将要从中提取的树不是您正在使用的存储库,请不要忘记将已签名的标记 | |
| 617 | −显式推送到公共树。 | |
| 616 | +.. note:: | |
| 618 | 617 | |
| 619 | −生成拉请求时,请使用已签名的标记作为目标。这样的命令可以实现:: | |
| 618 | + ``--base`` 功能是在2.9.0版git中引入的。 | |
| 620 | 619 | |
| 621 | − git request-pull master git://my.public.tree/linux.git my-signed-tag | |
| 620 | +如果您不使用git格式化补丁,仍然可以包含相同的 ``base-commit`` 尾注,以指示您 | |
| 621 | +的工作所基于的树的提交哈希。你应该在封面邮件或系列的第一个补丁中添加它,它应 | |
| 622 | +该放在 ``---`` 行的下面或所有其他内容之后,即只在你的电子邮件签名之前。 | |
| 622 | 623 | |
| 623 | 624 | 参考文献 |
| 624 | 625 | -------- |
| 625 | 626 | |
| 626 | −Andrew Morton, "The perfect patch" (tpp). | |
| 627 | +Andrew Morton,“完美的补丁”(tpp) | |
| 627 | 628 | <https://www.ozlabs.org/~akpm/stuff/tpp.txt> |
| 628 | 629 | |
| 629 | −Jeff Garzik, "Linux kernel patch submission format". | |
| 630 | +Jeff Garzik,“Linux内核补丁提交格式” | |
| 630 | 631 | <https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html> |
| 631 | 632 | |
| 632 | −Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". | |
| 633 | +Greg Kroah-Hartman,“如何惹恼内核子系统维护人员” | |
| 633 | 634 | <http://www.kroah.com/log/linux/maintainer.html> |
| 634 | 635 | |
| 635 | 636 | <http://www.kroah.com/log/linux/maintainer-02.html> |
| @@ -642,16 +643,15 @@ Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". · 6 unmodified lines | ||
| 642 | 643 | |
| 643 | 644 | <http://www.kroah.com/log/linux/maintainer-06.html> |
| 644 | 645 | |
| 645 | −NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! | |
| 646 | +不!!!别再发巨型补丁炸弹给linux-kernel@vger.kernel.org的人们了! | |
| 646 | 647 | <https://lore.kernel.org/r/20050711.125305.08322243.davem@davemloft.net> |
| 647 | 648 | |
| 648 | −Kernel Documentation/process/coding-style.rst: | |
| 649 | − :ref:`Documentation/translations/zh_CN/process/coding-style.rst <cn_codingstyle>` | |
| 649 | +内核 Documentation/translations/zh_CN/process/coding-style.rst | |
| 650 | 650 | |
| 651 | −Linus Torvalds's mail on the canonical patch format: | |
| 651 | +Linus Torvalds关于标准补丁格式的邮件 | |
| 652 | 652 | <https://lore.kernel.org/r/Pine.LNX.4.58.0504071023190.28951@ppc970.osdl.org> |
| 653 | 653 | |
| 654 | −Andi Kleen, "On submitting kernel patches" | |
| 655 | − Some strategies to get difficult or controversial changes in. | |
| 654 | +Andi Kleen,“提交补丁之路” | |
| 655 | + 一些帮助合入困难或有争议的变更的策略。 | |
| 656 | 656 | |
| 657 | 657 | http://halobates.de/on-submitting-patches.pdf |
| @@ -80,7 +80,7 @@ p->se.vruntime。一旦p->se.vruntime变得足够大,其它的任务将成为 · 79 unmodified lines | ||
| 80 | 80 | CFS使用纳秒粒度的计时,不依赖于任何jiffies或HZ的细节。因此CFS并不像之前的调度器那样 |
| 81 | 81 | 有“时间片”的概念,也没有任何启发式的设计。唯一可调的参数(你需要打开CONFIG_SCHED_DEBUG)是: |
| 82 | 82 | |
| 83 | − /proc/sys/kernel/sched_min_granularity_ns | |
| 83 | + /sys/kernel/debug/sched/min_granularity_ns | |
| 84 | 84 | |
| 85 | 85 | 它可以用来将调度器从“桌面”模式(也就是低时延)调节为“服务器”(也就是高批处理)模式。 |
| 86 | 86 | 它的默认设置是适合桌面的工作负载。SCHED_BATCH也被CFS调度器模块处理。 |
| @@ -1,212 +0,0 @@ | ||
| 1 | −Chinese translated version of Documentation/admin-guide/bug-hunting.rst | |
| 2 | − | |
| 3 | −If you have any comment or update to the content, please contact the | |
| 4 | −original document maintainer directly. However, if you have a problem | |
| 5 | −communicating in English you can also ask the Chinese maintainer for | |
| 6 | −help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | −or if there is a problem with the translation. | |
| 8 | − | |
| 9 | −Traditional Chinese maintainer: Hu Haowen <src.res@email.cn> | |
| 10 | −--------------------------------------------------------------------- | |
| 11 | −Documentation/admin-guide/bug-hunting.rst 的繁體中文版翻譯 | |
| 12 | − | |
| 13 | −如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 | |
| 14 | −交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 | |
| 15 | −者翻譯存在問題,請聯繫繁體中文版維護者。 | |
| 16 | − | |
| 17 | −繁體中文版維護者: 胡皓文 Hu Haowen <src.res@email.cn> | |
| 18 | −繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res@email.cn> | |
| 19 | −繁體中文版校譯者: 胡皓文 Hu Haowen <src.res@email.cn> | |
| 20 | − | |
| 21 | −以下爲正文 | |
| 22 | −--------------------------------------------------------------------- | |
| 23 | − | |
| 24 | −注意: ksymoops 在2.6中是沒有用的。 請以原有格式使用Oops(來自dmesg,等等)。 | |
| 25 | −忽略任何這樣那樣關於「解碼Oops」或者「通過ksymoops運行」的文檔。 如果你貼出運行過 | |
| 26 | −ksymoops的來自2.6的Oops,人們只會讓你重貼一次。 | |
| 27 | − | |
| 28 | −快速總結 | |
| 29 | −------------- | |
| 30 | − | |
| 31 | −發現Oops並發送給看似相關的內核領域的維護者。別太擔心對不上號。如果你不確定就發給 | |
| 32 | −和你所做的事情相關的代碼的負責人。 如果可重現試著描述怎樣重構。 那甚至比oops更有 | |
| 33 | −價值。 | |
| 34 | − | |
| 35 | −如果你對於發送給誰一無所知, 發給linux-kernel@vger.kernel.org。感謝你幫助Linux | |
| 36 | −儘可能地穩定。 | |
| 37 | − | |
| 38 | −Oops在哪裡? | |
| 39 | −---------------------- | |
| 40 | − | |
| 41 | −通常Oops文本由klogd從內核緩衝區里讀取並傳給syslogd,由syslogd寫到syslog文件中, | |
| 42 | −典型地是/var/log/messages(依賴於/etc/syslog.conf)。有時klogd崩潰了,這種情況下你 | |
| 43 | −能夠運行dmesg > file來從內核緩衝區中讀取數據並保存下來。 否則你可以 | |
| 44 | −cat /proc/kmsg > file, 然而你必須介入中止傳輸, kmsg是一個「永不結束的文件」。如 | |
| 45 | −果機器崩潰壞到你不能輸入命令或者磁碟不可用那麼你有三種選擇:- | |
| 46 | − | |
| 47 | −(1) 手抄屏幕上的文本待機器重啓後再輸入計算機。 麻煩但如果沒有針對崩潰的準備, | |
| 48 | −這是僅有的選擇。 另外,你可以用數位相機把屏幕拍下來-不太好,但比沒有強。 如果信 | |
| 49 | −息滾動到了終端的上面,你會發現以高分辯率啓動(比如,vga=791)會讓你讀到更多的文 | |
| 50 | −本。(注意:這需要vesafb,所以對『早期』的oops沒有幫助) | |
| 51 | − | |
| 52 | −(2)用串口終端啓動(請參看Documentation/admin-guide/serial-console.rst),運行一個null | |
| 53 | −modem到另一台機器並用你喜歡的通訊工具獲取輸出。Minicom工作地很好。 | |
| 54 | − | |
| 55 | −(3)使用Kdump(請參看Documentation/admin-guide/kdump/kdump.rst), | |
| 56 | −使用在Documentation/admin-guide/kdump/gdbmacros.txt中定義的dmesg gdb宏,從舊的內存中提取內核 | |
| 57 | −環形緩衝區。 | |
| 58 | − | |
| 59 | −完整信息 | |
| 60 | −---------------- | |
| 61 | − | |
| 62 | −注意:以下來自於Linus的郵件適用於2.4內核。 我因爲歷史原因保留了它,並且因爲其中 | |
| 63 | −一些信息仍然適用。 特別注意的是,請忽略任何ksymoops的引用。 | |
| 64 | − | |
| 65 | −From: Linus Torvalds <torvalds@osdl.org> | |
| 66 | − | |
| 67 | −怎樣跟蹤Oops.. [原發到linux-kernel的一封郵件] | |
| 68 | − | |
| 69 | −主要的竅門是有五年和這些煩人的oops消息打交道的經驗;-) | |
| 70 | − | |
| 71 | −實際上,你有辦法使它更簡單。我有兩個不同的方法: | |
| 72 | − | |
| 73 | − gdb /usr/src/linux/vmlinux | |
| 74 | − gdb> disassemble <offending_function> | |
| 75 | − | |
| 76 | −那是發現問題的簡單辦法,至少如果bug報告做的好的情況下(象這個一樣-運行ksymoops | |
| 77 | −得到oops發生的函數及函數內的偏移)。 | |
| 78 | − | |
| 79 | −哦,如果報告發生的內核以相同的編譯器和相似的配置編譯它會有幫助的。 | |
| 80 | − | |
| 81 | −另一件要做的事是反彙編bug報告的「Code」部分:ksymoops也會用正確的工具來做這件事, | |
| 82 | −但如果沒有那些工具你可以寫一個傻程序: | |
| 83 | − | |
| 84 | − char str[] = "\xXX\xXX\xXX..."; | |
| 85 | − main(){} | |
| 86 | − | |
| 87 | −並用gcc -g編譯它然後執行「disassemble str」(XX部分是由Oops報告的值-你可以僅剪切 | |
| 88 | −粘貼並用「\x」替換空格-我就是這麼做的,因爲我懶得寫程序自動做這一切)。 | |
| 89 | − | |
| 90 | −另外,你可以用scripts/decodecode這個shell腳本。它的使用方法是: | |
| 91 | −decodecode < oops.txt | |
| 92 | − | |
| 93 | −「Code」之後的十六進位字節可能(在某些架構上)有一些當前指令之前的指令字節以及 | |
| 94 | −當前和之後的指令字節 | |
| 95 | − | |
| 96 | −Code: f9 0f 8d f9 00 00 00 8d 42 0c e8 dd 26 11 c7 a1 60 ea 2b f9 8b 50 08 a1 | |
| 97 | −64 ea 2b f9 8d 34 82 8b 1e 85 db 74 6d 8b 15 60 ea 2b f9 <8b> 43 04 39 42 54 | |
| 98 | −7e 04 40 89 42 54 8b 43 04 3b 05 00 f6 52 c0 | |
| 99 | − | |
| 100 | −最後,如果你想知道代碼來自哪裡,你可以: | |
| 101 | − | |
| 102 | − cd /usr/src/linux | |
| 103 | − make fs/buffer.s # 或任何產生BUG的文件 | |
| 104 | − | |
| 105 | −然後你會比gdb反彙編更清楚的知道發生了什麼。 | |
| 106 | − | |
| 107 | −現在,問題是把你所擁有的所有數據結合起來:C源碼(關於它應該怎樣的一般知識), | |
| 108 | −彙編代碼及其反彙編得到的代碼(另外還有從「oops」消息得到的寄存器狀態-對了解毀壞的 | |
| 109 | −指針有用,而且當你有了彙編代碼你也能拿其它的寄存器和任何它們對應的C表達式做匹配 | |
| 110 | −)。 | |
| 111 | − | |
| 112 | −實際上,你僅需看看哪裡不匹配(這個例子是「Code」反彙編和編譯器生成的代碼不匹配)。 | |
| 113 | −然後你須要找出爲什麼不匹配。通常很簡單-你看到代碼使用了空指針然後你看代碼想知道 | |
| 114 | −空指針是怎麼出現的,還有檢查它是否合法.. | |
| 115 | − | |
| 116 | −現在,如果明白這是一項耗時的工作而且需要一丁點兒的專心,沒錯。這就是我爲什麼大多 | |
| 117 | −只是忽略那些沒有符號表信息的崩潰報告的原因:簡單的說太難查找了(我有一些 | |
| 118 | −程序用於在內核代碼段中搜索特定的模式,而且有時我也已經能找出那些崩潰的地方,但是 | |
| 119 | −僅僅是找出正確的序列也確實需要相當紮實的內核知識) | |
| 120 | − | |
| 121 | −_有時_會發生這種情況,我僅看到崩潰中的反彙編代碼序列, 然後我馬上就明白問題出在 | |
| 122 | −哪裡。這時我才意識到自己幹這個工作已經太長時間了;-) | |
| 123 | − | |
| 124 | − Linus | |
| 125 | − | |
| 126 | − | |
| 127 | −--------------------------------------------------------------------------- | |
| 128 | −關於Oops跟蹤的註解: | |
| 129 | − | |
| 130 | −爲了幫助Linus和其它內核開發者,klogd納入了大量的支持來處理保護錯誤。爲了擁有對 | |
| 131 | −地址解析的完整支持至少應該使用1.3-pl3的sysklogd包。 | |
| 132 | − | |
| 133 | −當保護錯誤發生時,klogd守護進程自動把內核日誌信息中的重要地址翻譯成它們相應的符 | |
| 134 | −號。 | |
| 135 | − | |
| 136 | −klogd執行兩種類型的地址解析。首先是靜態翻譯其次是動態翻譯。靜態翻譯和ksymoops | |
| 137 | −一樣使用System.map文件。爲了做靜態翻譯klogd守護進程必須在初始化時能找到system | |
| 138 | −map文件。關於klogd怎樣搜索map文件請參看klogd手冊頁。 | |
| 139 | − | |
| 140 | −動態地址翻譯在使用內核可裝載模塊時很重要。 因爲內核模塊的內存是從內核動態內存池 | |
| 141 | −里分配的,所以不管是模塊開始位置還是模塊中函數和符號的位置都不是固定的。 | |
| 142 | − | |
| 143 | −內核支持允許程序決定裝載哪些模塊和它們在內存中位置的系統調用。使用這些系統調用 | |
| 144 | −klogd守護進程生成一張符號表用於調試發生在可裝載模塊中的保護錯誤。 | |
| 145 | − | |
| 146 | −至少klogd會提供產生保護錯誤的模塊名。還可有額外的符號信息供可裝載模塊開發者選擇 | |
| 147 | −以從模塊中輸出符號信息。 | |
| 148 | − | |
| 149 | −因爲內核模塊環境可能是動態的,所以必須有一種機制當模塊環境發生改變時來通知klogd | |
| 150 | −守護進程。 有一些可用的命令行選項允許klogd向當前執行中的守護進程發送信號,告知符 | |
| 151 | −號信息應該被刷新了。 更多信息請參看klogd手冊頁。 | |
| 152 | − | |
| 153 | −sysklogd發布時包含一個補丁修改了modules-2.0.0包,無論何時一個模塊裝載或者卸載都 | |
| 154 | −會自動向klogd發送信號。打上這個補丁提供了必要的對調試發生於內核可裝載模塊的保護 | |
| 155 | −錯誤的無縫支持。 | |
| 156 | − | |
| 157 | −以下是被klogd處理過的發生在可裝載模塊中的一個保護錯誤例子: | |
| 158 | −--------------------------------------------------------------------------- | |
| 159 | −Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc | |
| 160 | −Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 | |
| 161 | −Aug 29 09:51:01 blizard kernel: *pde = 00000000 | |
| 162 | −Aug 29 09:51:01 blizard kernel: Oops: 0002 | |
| 163 | −Aug 29 09:51:01 blizard kernel: CPU: 0 | |
| 164 | −Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] | |
| 165 | −Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 | |
| 166 | −Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c | |
| 167 | −Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c | |
| 168 | −Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 | |
| 169 | −Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) | |
| 170 | −Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 | |
| 171 | −Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 | |
| 172 | −Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 | |
| 173 | −Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] | |
| 174 | −Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3 | |
| 175 | −--------------------------------------------------------------------------- | |
| 176 | − | |
| 177 | −Dr. G.W. Wettstein Oncology Research Div. Computing Facility | |
| 178 | −Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com | |
| 179 | −820 4th St. N. | |
| 180 | −Fargo, ND 58122 | |
| 181 | −Phone: 701-234-7556 | |
| 182 | − | |
| 183 | − | |
| 184 | −--------------------------------------------------------------------------- | |
| 185 | −受汙染的內核 | |
| 186 | − | |
| 187 | −一些oops報告在程序記數器之後包含字符串'Tainted: '。這表明內核已經被一些東西給汙 | |
| 188 | −染了。 該字符串之後緊跟著一系列的位置敏感的字符,每個代表一個特定的汙染值。 | |
| 189 | − | |
| 190 | − 1:'G'如果所有裝載的模塊都有GPL或相容的許可證,'P'如果裝載了任何的專有模塊。 | |
| 191 | −沒有模塊MODULE_LICENSE或者帶有insmod認爲是與GPL不相容的的MODULE_LICENSE的模塊被 | |
| 192 | −認定是專有的。 | |
| 193 | − | |
| 194 | − 2:'F'如果有任何通過「insmod -f」被強制裝載的模塊,' '如果所有模塊都被正常裝載。 | |
| 195 | − | |
| 196 | − 3:'S'如果oops發生在SMP內核中,運行於沒有證明安全運行多處理器的硬體。 當前這種 | |
| 197 | −情況僅限於幾種不支持SMP的速龍處理器。 | |
| 198 | − | |
| 199 | − 4:'R'如果模塊通過「insmod -f」被強制裝載,' '如果所有模塊都被正常裝載。 | |
| 200 | − | |
| 201 | − 5:'M'如果任何處理器報告了機器檢查異常,' '如果沒有發生機器檢查異常。 | |
| 202 | − | |
| 203 | − 6:'B'如果頁釋放函數發現了一個錯誤的頁引用或者一些非預期的頁標誌。 | |
| 204 | − | |
| 205 | − 7:'U'如果用戶或者用戶應用程式特別請求設置汙染標誌,否則' '。 | |
| 206 | − | |
| 207 | − 8:'D'如果內核剛剛死掉,比如有OOPS或者BUG。 | |
| 208 | − | |
| 209 | −使用'Tainted: '字符串的主要原因是要告訴內核調試者,這是否是一個乾淨的內核亦或發 | |
| 210 | −生了任何的不正常的事。汙染是永久的:即使出錯的模塊已經被卸載了,汙染值仍然存在, | |
| 211 | −以表明內核不再值得信任。 | |
| 212 | − | |
| @@ -8,7 +8,7 @@ Landlock: unprivileged access control · 7 unmodified lines | ||
| 8 | 8 | ===================================== |
| 9 | 9 | |
| 10 | 10 | :Author: Mickaël Salaün |
| 11 | −:Date: May 2022 | |
| 11 | +:Date: September 2022 | |
| 12 | 12 | |
| 13 | 13 | The goal of Landlock is to enable to restrict ambient rights (e.g. global |
| 14 | 14 | filesystem access) for a set of processes. Because Landlock is a stackable |
| @@ -69,7 +69,7 @@ should try to protect users as much as possible whatever the kernel they are · 54 unmodified lines | ||
| 69 | 69 | using. To avoid binary enforcement (i.e. either all security features or |
| 70 | 70 | none), we can leverage a dedicated Landlock command to get the current version |
| 71 | 71 | of the Landlock ABI and adapt the handled accesses. Let's check if we should |
| 72 | −remove the `LANDLOCK_ACCESS_FS_REFER` access right which is only supported | |
| 72 | +remove the ``LANDLOCK_ACCESS_FS_REFER`` access right which is only supported | |
| 73 | 73 | starting with the second version of the ABI. |
| 74 | 74 | |
| 75 | 75 | .. code-block:: c |
| @@ -128,7 +128,7 @@ descriptor. · 52 unmodified lines | ||
| 128 | 128 | It may also be required to create rules following the same logic as explained |
| 129 | 129 | for the ruleset creation, by filtering access rights according to the Landlock |
| 130 | 130 | ABI version. In this example, this is not required because |
| 131 | −`LANDLOCK_ACCESS_FS_REFER` is not allowed by any rule. | |
| 131 | +``LANDLOCK_ACCESS_FS_REFER`` is not allowed by any rule. | |
| 132 | 132 | |
| 133 | 133 | We now have a ruleset with one rule allowing read access to ``/usr`` while |
| 134 | 134 | denying all other handled accesses for the filesystem. The next step is to |
| @@ -154,8 +154,8 @@ The current thread is now ready to sandbox itself with the ruleset. · 19 unmodified lines | ||
| 154 | 154 | } |
| 155 | 155 | close(ruleset_fd); |
| 156 | 156 | |
| 157 | −If the `landlock_restrict_self` system call succeeds, the current thread is now | |
| 158 | −restricted and this policy will be enforced on all its subsequently created | |
| 157 | +If the ``landlock_restrict_self`` system call succeeds, the current thread is | |
| 158 | +now restricted and this policy will be enforced on all its subsequently created | |
| 159 | 159 | children as well. Once a thread is landlocked, there is no way to remove its |
| 160 | 160 | security policy; only adding more restrictions is allowed. These threads are |
| 161 | 161 | now in a new Landlock domain, merge of their parent one (if any) with the new |
| @@ -170,12 +170,13 @@ It is recommended setting access rights to file hierarchy leaves as much as · 8 unmodified lines | ||
| 170 | 170 | possible. For instance, it is better to be able to have ``~/doc/`` as a |
| 171 | 171 | read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to |
| 172 | 172 | ``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy. |
| 173 | −Following this good practice leads to self-sufficient hierarchies that don't | |
| 173 | +Following this good practice leads to self-sufficient hierarchies that do not | |
| 174 | 174 | depend on their location (i.e. parent directories). This is particularly |
| 175 | 175 | relevant when we want to allow linking or renaming. Indeed, having consistent |
| 176 | 176 | access rights per directory enables to change the location of such directory |
| 177 | 177 | without relying on the destination directory access rights (except those that |
| 178 | −are required for this operation, see `LANDLOCK_ACCESS_FS_REFER` documentation). | |
| 178 | +are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER`` | |
| 179 | +documentation). | |
| 179 | 180 | Having self-sufficient hierarchies also helps to tighten the required access |
| 180 | 181 | rights to the minimal set of data. This also helps avoid sinkhole directories, |
| 181 | 182 | i.e. directories where data can be linked to but not linked from. However, |
| @@ -259,7 +260,7 @@ Backward and forward compatibility · 77 unmodified lines | ||
| 259 | 260 | |
| 260 | 261 | Landlock is designed to be compatible with past and future versions of the |
| 261 | 262 | kernel. This is achieved thanks to the system call attributes and the |
| 262 | −associated bitflags, particularly the ruleset's `handled_access_fs`. Making | |
| 263 | +associated bitflags, particularly the ruleset's ``handled_access_fs``. Making | |
| 263 | 264 | handled access right explicit enables the kernel and user space to have a clear |
| 264 | 265 | contract with each other. This is required to make sure sandboxing will not |
| 265 | 266 | get stricter with a system update, which could break applications. |
| @@ -380,8 +381,8 @@ by the Documentation/admin-guide/cgroup-v1/memory.rst. · 114 unmodified lines | ||
| 380 | 381 | Previous limitations |
| 381 | 382 | ==================== |
| 382 | 383 | |
| 383 | −File renaming and linking (ABI 1) | |
| 384 | −--------------------------------- | |
| 384 | +File renaming and linking (ABI < 2) | |
| 385 | +----------------------------------- | |
| 385 | 386 | |
| 386 | 387 | Because Landlock targets unprivileged access controls, it needs to properly |
| 387 | 388 | handle composition of rules. Such property also implies rules nesting. |
| @@ -394,7 +395,7 @@ according to the potentially lost constraints. To protect against privilege · 6 unmodified lines | ||
| 394 | 395 | escalations through renaming or linking, and for the sake of simplicity, |
| 395 | 396 | Landlock previously limited linking and renaming to the same directory. |
| 396 | 397 | Starting with the Landlock ABI version 2, it is now possible to securely |
| 397 | −control renaming and linking thanks to the new `LANDLOCK_ACCESS_FS_REFER` | |
| 398 | +control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER`` | |
| 398 | 399 | access right. |
| 399 | 400 | |
| 400 | 401 | .. _kernel_support: |
| @@ -403,14 +404,14 @@ Kernel support · 2 unmodified lines | ||
| 403 | 404 | ============== |
| 404 | 405 | |
| 405 | 406 | Landlock was first introduced in Linux 5.13 but it must be configured at build |
| 406 | −time with `CONFIG_SECURITY_LANDLOCK=y`. Landlock must also be enabled at boot | |
| 407 | +time with ``CONFIG_SECURITY_LANDLOCK=y``. Landlock must also be enabled at boot | |
| 407 | 408 | time as the other security modules. The list of security modules enabled by |
| 408 | −default is set with `CONFIG_LSM`. The kernel configuration should then | |
| 409 | −contains `CONFIG_LSM=landlock,[...]` with `[...]` as the list of other | |
| 409 | +default is set with ``CONFIG_LSM``. The kernel configuration should then | |
| 410 | +contains ``CONFIG_LSM=landlock,[...]`` with ``[...]`` as the list of other | |
| 410 | 411 | potentially useful security modules for the running system (see the |
| 411 | −`CONFIG_LSM` help). | |
| 412 | +``CONFIG_LSM`` help). | |
| 412 | 413 | |
| 413 | −If the running kernel doesn't have `landlock` in `CONFIG_LSM`, then we can | |
| 414 | +If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can | |
| 414 | 415 | still enable it by adding ``lsm=landlock,[...]`` to |
| 415 | 416 | Documentation/admin-guide/kernel-parameters.rst thanks to the bootloader |
| 416 | 417 | configuration. |
| @@ -377,7 +377,7 @@ Emulating cr0.wp · 376 unmodified lines | ||
| 377 | 377 | ================ |
| 378 | 378 | |
| 379 | 379 | If tdp is not enabled, the host must keep cr0.wp=1 so page write protection |
| 380 | −works for the guest kernel, not guest guest userspace. When the guest | |
| 380 | +works for the guest kernel, not guest userspace. When the guest | |
| 381 | 381 | cr0.wp=1, this does not present a problem. However when the guest cr0.wp=0, |
| 382 | 382 | we cannot map the permissions for gpte.u=1, gpte.w=0 to any spte (the |
| 383 | 383 | semantics require allowing any guest kernel access plus user read access). |
| @@ -52,7 +52,7 @@ Notes and limitations. · 51 unmodified lines | ||
| 52 | 52 | clear the entire bulk in buffer. It would be possible to read the |
| 53 | 53 | maximum buffer size to not run into this error condition, only extra |
| 54 | 54 | bytes in the buffer is a logic error in the driver. The code should |
| 55 | − should match reads and writes as well as data sizes. Reads and | |
| 55 | + match reads and writes as well as data sizes. Reads and | |
| 56 | 56 | writes are serialized and the status verifies that the chip is idle |
| 57 | 57 | (and data is available) before the read is executed, so it should |
| 58 | 58 | not happen. |
| @@ -113,7 +113,7 @@ generally only make sense when searching is disabled, as a search will · 112 unmodified lines | ||
| 113 | 113 | redetect manually removed devices that are present and timeout manually |
| 114 | 114 | added devices that aren't on the bus. |
| 115 | 115 | |
| 116 | −Bus searches occur at an interval, specified as a summ of timeout and | |
| 116 | +Bus searches occur at an interval, specified as a sum of timeout and | |
| 117 | 117 | timeout_us module parameters (either of which may be 0) for as long as |
| 118 | 118 | w1_master_search remains greater than 0 or is -1. Each search attempt |
| 119 | 119 | decrements w1_master_search by 1 (down to 0) and increments |
| @@ -33,8 +33,8 @@ Some of these entries are: · 32 unmodified lines | ||
| 33 | 33 | - interrupt: An array of entries. Every IDT vector that doesn't |
| 34 | 34 | explicitly point somewhere else gets set to the corresponding |
| 35 | 35 | value in interrupts. These point to a whole array of |
| 36 | − magically-generated functions that make their way to do_IRQ with | |
| 37 | − the interrupt number as a parameter. | |
| 36 | + magically-generated functions that make their way to common_interrupt() | |
| 37 | + with the interrupt number as a parameter. | |
| 38 | 38 | |
| 39 | 39 | - APIC interrupts: Various special-purpose interrupts for things |
| 40 | 40 | like TLB shootdown. |
| @@ -6,6 +6,7 @@ The Linux Microcode Loader · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | :Authors: - Fenghua Yu <fenghua.yu@intel.com> |
| 8 | 8 | - Borislav Petkov <bp@suse.de> |
| 9 | + - Ashok Raj <ashok.raj@intel.com> | |
| 9 | 10 | |
| 10 | 11 | The kernel has a x86 microcode loading facility which is supposed to |
| 11 | 12 | provide microcode loading methods in the OS. Potential use cases are |
| @@ -92,15 +93,8 @@ vendor's site. · 80 unmodified lines | ||
| 92 | 93 | Late loading |
| 93 | 94 | ============ |
| 94 | 95 | |
| 95 | −There are two legacy user space interfaces to load microcode, either through | |
| 96 | −/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file | |
| 97 | −in sysfs. | |
| 98 | − | |
| 99 | −The /dev/cpu/microcode method is deprecated because it needs a special | |
| 100 | −userspace tool for that. | |
| 101 | − | |
| 102 | −The easier method is simply installing the microcode packages your distro | |
| 103 | −supplies and running:: | |
| 96 | +You simply install the microcode packages your distro supplies and | |
| 97 | +run:: | |
| 104 | 98 | |
| 105 | 99 | # echo 1 > /sys/devices/system/cpu/microcode/reload |
| 106 | 100 | |
| @@ -110,6 +104,110 @@ The loading mechanism looks for microcode blobs in · 3 unmodified lines | ||
| 110 | 104 | /lib/firmware/{intel-ucode,amd-ucode}. The default distro installation |
| 111 | 105 | packages already put them there. |
| 112 | 106 | |
| 107 | +Since kernel 5.19, late loading is not enabled by default. | |
| 108 | + | |
| 109 | +The /dev/cpu/microcode method has been removed in 5.19. | |
| 110 | + | |
| 111 | +Why is late loading dangerous? | |
| 112 | +============================== | |
| 113 | + | |
| 114 | +Synchronizing all CPUs | |
| 115 | +---------------------- | |
| 116 | + | |
| 117 | +The microcode engine which receives the microcode update is shared | |
| 118 | +between the two logical threads in a SMT system. Therefore, when | |
| 119 | +the update is executed on one SMT thread of the core, the sibling | |
| 120 | +"automatically" gets the update. | |
| 121 | + | |
| 122 | +Since the microcode can "simulate" MSRs too, while the microcode update | |
| 123 | +is in progress, those simulated MSRs transiently cease to exist. This | |
| 124 | +can result in unpredictable results if the SMT sibling thread happens to | |
| 125 | +be in the middle of an access to such an MSR. The usual observation is | |
| 126 | +that such MSR accesses cause #GPs to be raised to signal that former are | |
| 127 | +not present. | |
| 128 | + | |
| 129 | +The disappearing MSRs are just one common issue which is being observed. | |
| 130 | +Any other instruction that's being patched and gets concurrently | |
| 131 | +executed by the other SMT sibling, can also result in similar, | |
| 132 | +unpredictable behavior. | |
| 133 | + | |
| 134 | +To eliminate this case, a stop_machine()-based CPU synchronization was | |
| 135 | +introduced as a way to guarantee that all logical CPUs will not execute | |
| 136 | +any code but just wait in a spin loop, polling an atomic variable. | |
| 137 | + | |
| 138 | +While this took care of device or external interrupts, IPIs including | |
| 139 | +LVT ones, such as CMCI etc, it cannot address other special interrupts | |
| 140 | +that can't be shut off. Those are Machine Check (#MC), System Management | |
| 141 | +(#SMI) and Non-Maskable interrupts (#NMI). | |
| 142 | + | |
| 143 | +Machine Checks | |
| 144 | +-------------- | |
| 145 | + | |
| 146 | +Machine Checks (#MC) are non-maskable. There are two kinds of MCEs. | |
| 147 | +Fatal un-recoverable MCEs and recoverable MCEs. While un-recoverable | |
| 148 | +errors are fatal, recoverable errors can also happen in kernel context | |
| 149 | +are also treated as fatal by the kernel. | |
| 150 | + | |
| 151 | +On certain Intel machines, MCEs are also broadcast to all threads in a | |
| 152 | +system. If one thread is in the middle of executing WRMSR, a MCE will be | |
| 153 | +taken at the end of the flow. Either way, they will wait for the thread | |
| 154 | +performing the wrmsr(0x79) to rendezvous in the MCE handler and shutdown | |
| 155 | +eventually if any of the threads in the system fail to check in to the | |
| 156 | +MCE rendezvous. | |
| 157 | + | |
| 158 | +To be paranoid and get predictable behavior, the OS can choose to set | |
| 159 | +MCG_STATUS.MCIP. Since MCEs can be at most one in a system, if an | |
| 160 | +MCE was signaled, the above condition will promote to a system reset | |
| 161 | +automatically. OS can turn off MCIP at the end of the update for that | |
| 162 | +core. | |
| 163 | + | |
| 164 | +System Management Interrupt | |
| 165 | +--------------------------- | |
| 166 | + | |
| 167 | +SMIs are also broadcast to all CPUs in the platform. Microcode update | |
| 168 | +requests exclusive access to the core before writing to MSR 0x79. So if | |
| 169 | +it does happen such that, one thread is in WRMSR flow, and the 2nd got | |
| 170 | +an SMI, that thread will be stopped in the first instruction in the SMI | |
| 171 | +handler. | |
| 172 | + | |
| 173 | +Since the secondary thread is stopped in the first instruction in SMI, | |
| 174 | +there is very little chance that it would be in the middle of executing | |
| 175 | +an instruction being patched. Plus OS has no way to stop SMIs from | |
| 176 | +happening. | |
| 177 | + | |
| 178 | +Non-Maskable Interrupts | |
| 179 | +----------------------- | |
| 180 | + | |
| 181 | +When thread0 of a core is doing the microcode update, if thread1 is | |
| 182 | +pulled into NMI, that can cause unpredictable behavior due to the | |
| 183 | +reasons above. | |
| 184 | + | |
| 185 | +OS can choose a variety of methods to avoid running into this situation. | |
| 186 | + | |
| 187 | + | |
| 188 | +Is the microcode suitable for late loading? | |
| 189 | +------------------------------------------- | |
| 190 | + | |
| 191 | +Late loading is done when the system is fully operational and running | |
| 192 | +real workloads. Late loading behavior depends on what the base patch on | |
| 193 | +the CPU is before upgrading to the new patch. | |
| 194 | + | |
| 195 | +This is true for Intel CPUs. | |
| 196 | + | |
| 197 | +Consider, for example, a CPU has patch level 1 and the update is to | |
| 198 | +patch level 3. | |
| 199 | + | |
| 200 | +Between patch1 and patch3, patch2 might have deprecated a software-visible | |
| 201 | +feature. | |
| 202 | + | |
| 203 | +This is unacceptable if software is even potentially using that feature. | |
| 204 | +For instance, say MSR_X is no longer available after an update, | |
| 205 | +accessing that MSR will cause a #GP fault. | |
| 206 | + | |
| 207 | +Basically there is no way to declare a new microcode update suitable | |
| 208 | +for late-loading. This is another one of the problems that caused late | |
| 209 | +loading to be not enabled by default. | |
| 210 | + | |
| 113 | 211 | Builtin microcode |
| 114 | 212 | ================= |
| 115 | 213 | |
| @@ -348,7 +348,6 @@ M: "Rafael J. Wysocki" <rafael@kernel.org> · 347 unmodified lines | ||
| 348 | 348 | R: Len Brown <lenb@kernel.org> |
| 349 | 349 | L: linux-acpi@vger.kernel.org |
| 350 | 350 | S: Supported |
| 351 | −W: https://01.org/linux-acpi | |
| 352 | 351 | Q: https://patchwork.kernel.org/project/linux-acpi/list/ |
| 353 | 352 | B: https://bugzilla.kernel.org |
| 354 | 353 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm |
| @@ -427,7 +426,6 @@ M: Rafael J. Wysocki <rafael@kernel.org> · 72 unmodified lines | ||
| 427 | 426 | R: Zhang Rui <rui.zhang@intel.com> |
| 428 | 427 | L: linux-acpi@vger.kernel.org |
| 429 | 428 | S: Supported |
| 430 | −W: https://01.org/linux-acpi | |
| 431 | 429 | B: https://bugzilla.kernel.org |
| 432 | 430 | F: drivers/acpi/*thermal* |
| 433 | 431 | |
| @@ -2678,7 +2676,6 @@ M: Russell King <linux@armlinux.org.uk> · 2244 unmodified lines | ||
| 2678 | 2676 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2679 | 2677 | S: Maintained |
| 2680 | 2678 | W: http://www.armlinux.org.uk/ |
| 2681 | −F: arch/arm/include/asm/hardware/entry-macro-iomd.S | |
| 2682 | 2679 | F: arch/arm/include/asm/hardware/ioc.h |
| 2683 | 2680 | F: arch/arm/include/asm/hardware/iomd.h |
| 2684 | 2681 | F: arch/arm/include/asm/hardware/memc.h |
| @@ -3833,6 +3830,7 @@ F: kernel/bpf/dispatcher.c · 1148 unmodified lines | ||
| 3833 | 3830 | F: kernel/bpf/trampoline.c |
| 3834 | 3831 | F: include/linux/bpf* |
| 3835 | 3832 | F: include/linux/filter.h |
| 3833 | +F: include/linux/tnum.h | |
| 3836 | 3834 | |
| 3837 | 3835 | BPF [BTF] |
| 3838 | 3836 | M: Martin KaFai Lau <martin.lau@linux.dev> |
| @@ -7689,7 +7687,6 @@ R: Kees Cook <keescook@chromium.org> · 3850 unmodified lines | ||
| 7689 | 7687 | L: linux-mm@kvack.org |
| 7690 | 7688 | S: Supported |
| 7691 | 7689 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve |
| 7692 | −F: arch/alpha/kernel/binfmt_loader.c | |
| 7693 | 7690 | F: fs/*binfmt_*.c |
| 7694 | 7691 | F: fs/exec.c |
| 7695 | 7692 | F: include/linux/binfmts.h |
| @@ -8006,6 +8003,7 @@ L: linux-hardening@vger.kernel.org · 310 unmodified lines | ||
| 8006 | 8003 | S: Supported |
| 8007 | 8004 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| 8008 | 8005 | F: include/linux/fortify-string.h |
| 8006 | +F: lib/fortify_kunit.c | |
| 8009 | 8007 | F: lib/test_fortify/* |
| 8010 | 8008 | F: scripts/test_fortify.sh |
| 8011 | 8009 | K: \b__NO_FORTIFY\b |
| @@ -10380,7 +10378,6 @@ INTEL MENLOW THERMAL DRIVER · 2368 unmodified lines | ||
| 10380 | 10378 | M: Sujith Thomas <sujith.thomas@intel.com> |
| 10381 | 10379 | L: linux-pm@vger.kernel.org |
| 10382 | 10380 | S: Supported |
| 10383 | −W: https://01.org/linux-acpi | |
| 10384 | 10381 | F: drivers/thermal/intel/intel_menlow.c |
| 10385 | 10382 | |
| 10386 | 10383 | INTEL P-Unit IPC DRIVER |
| @@ -14451,6 +14448,7 @@ M: Willy Tarreau <w@1wt.eu> · 4064 unmodified lines | ||
| 14451 | 14448 | S: Maintained |
| 14452 | 14449 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git |
| 14453 | 14450 | F: tools/include/nolibc/ |
| 14451 | +F: tools/testing/selftests/nolibc/ | |
| 14454 | 14452 | |
| 14455 | 14453 | NSDEPS |
| 14456 | 14454 | M: Matthias Maennich <maennich@google.com> |
| @@ -17766,6 +17764,24 @@ F: include/rv/ · 3309 unmodified lines | ||
| 17766 | 17764 | F: kernel/trace/rv/ |
| 17767 | 17765 | F: tools/verification/ |
| 17768 | 17766 | |
| 17767 | +RUST | |
| 17768 | +M: Miguel Ojeda <ojeda@kernel.org> | |
| 17769 | +M: Alex Gaynor <alex.gaynor@gmail.com> | |
| 17770 | +M: Wedson Almeida Filho <wedsonaf@gmail.com> | |
| 17771 | +R: Boqun Feng <boqun.feng@gmail.com> | |
| 17772 | +R: Gary Guo <gary@garyguo.net> | |
| 17773 | +R: Björn Roy Baron <bjorn3_gh@protonmail.com> | |
| 17774 | +L: rust-for-linux@vger.kernel.org | |
| 17775 | +S: Supported | |
| 17776 | +W: https://github.com/Rust-for-Linux/linux | |
| 17777 | +B: https://github.com/Rust-for-Linux/linux/issues | |
| 17778 | +T: git https://github.com/Rust-for-Linux/linux.git rust-next | |
| 17779 | +F: Documentation/rust/ | |
| 17780 | +F: rust/ | |
| 17781 | +F: samples/rust/ | |
| 17782 | +F: scripts/*rust* | |
| 17783 | +K: \b(?i:rust)\b | |
| 17784 | + | |
| 17769 | 17785 | RXRPC SOCKETS (AF_RXRPC) |
| 17770 | 17786 | M: David Howells <dhowells@redhat.com> |
| 17771 | 17787 | M: Marc Dionne <marc.dionne@auristor.com> |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 0 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc7 | |
| 5 | +EXTRAVERSION = | |
| 6 | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -120,6 +120,15 @@ endif · 111 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | export KBUILD_CHECKSRC |
| 122 | 122 | |
| 123 | +# Enable "clippy" (a linter) as part of the Rust compilation. | |
| 124 | +# | |
| 125 | +# Use 'make CLIPPY=1' to enable it. | |
| 126 | +ifeq ("$(origin CLIPPY)", "command line") | |
| 127 | + KBUILD_CLIPPY := $(CLIPPY) | |
| 128 | +endif | |
| 129 | + | |
| 130 | +export KBUILD_CLIPPY | |
| 131 | + | |
| 123 | 132 | # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the |
| 124 | 133 | # directory of external module to build. Setting M= takes precedence. |
| 125 | 134 | ifeq ("$(origin M)", "command line") |
| @@ -270,14 +279,14 @@ no-dot-config-targets := $(clean-targets) \ · 144 unmodified lines | ||
| 270 | 279 | cscope gtags TAGS tags help% %docs check% coccicheck \ |
| 271 | 280 | $(version_h) headers headers_% archheaders archscripts \ |
| 272 | 281 | %asm-generic kernelversion %src-pkg dt_binding_check \ |
| 273 | − outputmakefile | |
| 282 | + outputmakefile rustavailable rustfmt rustfmtcheck | |
| 274 | 283 | # Installation targets should not require compiler. Unfortunately, vdso_install |
| 275 | 284 | # is an exception where build artifacts may be updated. This must be fixed. |
| 276 | 285 | no-compiler-targets := $(no-dot-config-targets) install dtbs_install \ |
| 277 | 286 | headers_install modules_install kernelrelease image_name |
| 278 | 287 | no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \ |
| 279 | 288 | image_name |
| 280 | −single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ | |
| 289 | +single-targets := %.a %.i %.rsi %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ | |
| 281 | 290 | |
| 282 | 291 | config-build := |
| 283 | 292 | mixed-build := |
| @@ -439,6 +448,7 @@ else · 155 unmodified lines | ||
| 439 | 448 | HOSTCC = gcc |
| 440 | 449 | HOSTCXX = g++ |
| 441 | 450 | endif |
| 451 | +HOSTRUSTC = rustc | |
| 442 | 452 | HOSTPKG_CONFIG = pkg-config |
| 443 | 453 | |
| 444 | 454 | KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ |
| @@ -447,8 +457,26 @@ KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ · 2 unmodified lines | ||
| 447 | 457 | KBUILD_USERCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(USERCFLAGS) |
| 448 | 458 | KBUILD_USERLDFLAGS := $(USERLDFLAGS) |
| 449 | 459 | |
| 460 | +# These flags apply to all Rust code in the tree, including the kernel and | |
| 461 | +# host programs. | |
| 462 | +export rust_common_flags := --edition=2021 \ | |
| 463 | + -Zbinary_dep_depinfo=y \ | |
| 464 | + -Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \ | |
| 465 | + -Dunreachable_pub -Dnon_ascii_idents \ | |
| 466 | + -Wmissing_docs \ | |
| 467 | + -Drustdoc::missing_crate_level_docs \ | |
| 468 | + -Dclippy::correctness -Dclippy::style \ | |
| 469 | + -Dclippy::suspicious -Dclippy::complexity \ | |
| 470 | + -Dclippy::perf \ | |
| 471 | + -Dclippy::let_unit_value -Dclippy::mut_mut \ | |
| 472 | + -Dclippy::needless_bitwise_bool \ | |
| 473 | + -Dclippy::needless_continue \ | |
| 474 | + -Wclippy::dbg_macro | |
| 475 | + | |
| 450 | 476 | KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) |
| 451 | 477 | KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) |
| 478 | +KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \ | |
| 479 | + -Zallow-features= $(HOSTRUSTFLAGS) | |
| 452 | 480 | KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) |
| 453 | 481 | KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) |
| 454 | 482 | |
| @@ -473,6 +501,12 @@ OBJDUMP = $(CROSS_COMPILE)objdump · 18 unmodified lines | ||
| 473 | 501 | READELF = $(CROSS_COMPILE)readelf |
| 474 | 502 | STRIP = $(CROSS_COMPILE)strip |
| 475 | 503 | endif |
| 504 | +RUSTC = rustc | |
| 505 | +RUSTDOC = rustdoc | |
| 506 | +RUSTFMT = rustfmt | |
| 507 | +CLIPPY_DRIVER = clippy-driver | |
| 508 | +BINDGEN = bindgen | |
| 509 | +CARGO = cargo | |
| 476 | 510 | PAHOLE = pahole |
| 477 | 511 | RESOLVE_BTFIDS = $(objtree)/tools/bpf/resolve_btfids/resolve_btfids |
| 478 | 512 | LEX = flex |
| @@ -498,9 +532,11 @@ CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ · 19 unmodified lines | ||
| 498 | 532 | -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) |
| 499 | 533 | NOSTDINC_FLAGS := |
| 500 | 534 | CFLAGS_MODULE = |
| 535 | +RUSTFLAGS_MODULE = | |
| 501 | 536 | AFLAGS_MODULE = |
| 502 | 537 | LDFLAGS_MODULE = |
| 503 | 538 | CFLAGS_KERNEL = |
| 539 | +RUSTFLAGS_KERNEL = | |
| 504 | 540 | AFLAGS_KERNEL = |
| 505 | 541 | LDFLAGS_vmlinux = |
| 506 | 542 | |
| @@ -529,15 +565,43 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ · 22 unmodified lines | ||
| 529 | 565 | -Werror=return-type -Wno-format-security \ |
| 530 | 566 | -std=gnu11 |
| 531 | 567 | KBUILD_CPPFLAGS := -D__KERNEL__ |
| 568 | +KBUILD_RUSTFLAGS := $(rust_common_flags) \ | |
| 569 | + --target=$(objtree)/rust/target.json \ | |
| 570 | + -Cpanic=abort -Cembed-bitcode=n -Clto=n \ | |
| 571 | + -Cforce-unwind-tables=n -Ccodegen-units=1 \ | |
| 572 | + -Csymbol-mangling-version=v0 \ | |
| 573 | + -Crelocation-model=static \ | |
| 574 | + -Zfunction-sections=n \ | |
| 575 | + -Dclippy::float_arithmetic | |
| 576 | + | |
| 532 | 577 | KBUILD_AFLAGS_KERNEL := |
| 533 | 578 | KBUILD_CFLAGS_KERNEL := |
| 579 | +KBUILD_RUSTFLAGS_KERNEL := | |
| 534 | 580 | KBUILD_AFLAGS_MODULE := -DMODULE |
| 535 | 581 | KBUILD_CFLAGS_MODULE := -DMODULE |
| 582 | +KBUILD_RUSTFLAGS_MODULE := --cfg MODULE | |
| 536 | 583 | KBUILD_LDFLAGS_MODULE := |
| 537 | 584 | KBUILD_LDFLAGS := |
| 538 | 585 | CLANG_FLAGS := |
| 539 | 586 | |
| 587 | +ifeq ($(KBUILD_CLIPPY),1) | |
| 588 | + RUSTC_OR_CLIPPY_QUIET := CLIPPY | |
| 589 | + RUSTC_OR_CLIPPY = $(CLIPPY_DRIVER) | |
| 590 | +else | |
| 591 | + RUSTC_OR_CLIPPY_QUIET := RUSTC | |
| 592 | + RUSTC_OR_CLIPPY = $(RUSTC) | |
| 593 | +endif | |
| 594 | + | |
| 595 | +ifdef RUST_LIB_SRC | |
| 596 | + export RUST_LIB_SRC | |
| 597 | +endif | |
| 598 | + | |
| 599 | +# Allows the usage of unstable features in stable compilers. | |
| 600 | +export RUSTC_BOOTSTRAP := 1 | |
| 601 | + | |
| 540 | 602 | export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG |
| 603 | +export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO | |
| 604 | +export HOSTRUSTC KBUILD_HOSTRUSTFLAGS | |
| 541 | 605 | export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL |
| 542 | 606 | export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX |
| 543 | 607 | export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD |
| @@ -546,9 +610,10 @@ export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS · 2 unmodified lines | ||
| 546 | 610 | |
| 547 | 611 | export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS |
| 548 | 612 | export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE |
| 613 | +export KBUILD_RUSTFLAGS RUSTFLAGS_KERNEL RUSTFLAGS_MODULE | |
| 549 | 614 | export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE |
| 550 | −export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE | |
| 551 | −export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL | |
| 615 | +export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_RUSTFLAGS_MODULE KBUILD_LDFLAGS_MODULE | |
| 616 | +export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL | |
| 552 | 617 | export PAHOLE_FLAGS |
| 553 | 618 | |
| 554 | 619 | # Files to ignore in find ... statements |
| @@ -729,7 +794,7 @@ $(KCONFIG_CONFIG): · 174 unmodified lines | ||
| 729 | 794 | # |
| 730 | 795 | # Do not use $(call cmd,...) here. That would suppress prompts from syncconfig, |
| 731 | 796 | # so you cannot notice that Kconfig is waiting for the user input. |
| 732 | −%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG) | |
| 797 | +%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h %/generated/rustc_cfg: $(KCONFIG_CONFIG) | |
| 733 | 798 | $(Q)$(kecho) " SYNC $@" |
| 734 | 799 | $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig |
| 735 | 800 | else # !may-sync-config |
| @@ -758,10 +823,17 @@ KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) · 22 unmodified lines | ||
| 758 | 823 | |
| 759 | 824 | ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE |
| 760 | 825 | KBUILD_CFLAGS += -O2 |
| 826 | +KBUILD_RUSTFLAGS += -Copt-level=2 | |
| 761 | 827 | else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE |
| 762 | 828 | KBUILD_CFLAGS += -Os |
| 829 | +KBUILD_RUSTFLAGS += -Copt-level=s | |
| 763 | 830 | endif |
| 764 | 831 | |
| 832 | +# Always set `debug-assertions` and `overflow-checks` because their default | |
| 833 | +# depends on `opt-level` and `debug-assertions`, respectively. | |
| 834 | +KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n) | |
| 835 | +KBUILD_RUSTFLAGS += -Coverflow-checks=$(if $(CONFIG_RUST_OVERFLOW_CHECKS),y,n) | |
| 836 | + | |
| 765 | 837 | # Tell gcc to never replace conditional load with a non-conditional one |
| 766 | 838 | ifdef CONFIG_CC_IS_GCC |
| 767 | 839 | # gcc-10 renamed --param=allow-store-data-races=0 to |
| @@ -792,6 +864,9 @@ KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror · 24 unmodified lines | ||
| 792 | 864 | KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds |
| 793 | 865 | KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) |
| 794 | 866 | |
| 867 | +KBUILD_RUSTFLAGS-$(CONFIG_WERROR) += -Dwarnings | |
| 868 | +KBUILD_RUSTFLAGS += $(KBUILD_RUSTFLAGS-y) | |
| 869 | + | |
| 795 | 870 | ifdef CONFIG_CC_IS_CLANG |
| 796 | 871 | KBUILD_CPPFLAGS += -Qunused-arguments |
| 797 | 872 | # The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable. |
| @@ -812,12 +887,15 @@ KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer) · 14 unmodified lines | ||
| 812 | 887 | |
| 813 | 888 | ifdef CONFIG_FRAME_POINTER |
| 814 | 889 | KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls |
| 890 | +KBUILD_RUSTFLAGS += -Cforce-frame-pointers=y | |
| 815 | 891 | else |
| 816 | 892 | # Some targets (ARM with Thumb2, for example), can't be built with frame |
| 817 | 893 | # pointers. For those, we don't have FUNCTION_TRACER automatically |
| 818 | 894 | # select FRAME_POINTER. However, FUNCTION_TRACER adds -pg, and this is |
| 819 | 895 | # incompatible with -fomit-frame-pointer with current GCC, so we don't use |
| 820 | 896 | # -fomit-frame-pointer with FUNCTION_TRACER. |
| 897 | +# In the Rust target specification, "frame-pointer" is set explicitly | |
| 898 | +# to "may-omit". | |
| 821 | 899 | ifndef CONFIG_FUNCTION_TRACER |
| 822 | 900 | KBUILD_CFLAGS += -fomit-frame-pointer |
| 823 | 901 | endif |
| @@ -831,8 +909,8 @@ endif · 7 unmodified lines | ||
| 831 | 909 | # Initialize all stack variables with a zero value. |
| 832 | 910 | ifdef CONFIG_INIT_STACK_ALL_ZERO |
| 833 | 911 | KBUILD_CFLAGS += -ftrivial-auto-var-init=zero |
| 834 | −ifdef CONFIG_CC_IS_CLANG | |
| 835 | −# https://bugs.llvm.org/show_bug.cgi?id=45497 | |
| 912 | +ifdef CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER | |
| 913 | +# https://github.com/llvm/llvm-project/issues/44842 | |
| 836 | 914 | KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang |
| 837 | 915 | endif |
| 838 | 916 | endif |
| @@ -882,8 +960,10 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH · 43 unmodified lines | ||
| 882 | 960 | KBUILD_CFLAGS += -fno-inline-functions-called-once |
| 883 | 961 | endif |
| 884 | 962 | |
| 963 | +# `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0). | |
| 885 | 964 | ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION |
| 886 | 965 | KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections |
| 966 | +KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y | |
| 887 | 967 | LDFLAGS_vmlinux += --gc-sections |
| 888 | 968 | endif |
| 889 | 969 | |
| @@ -921,18 +1001,7 @@ export CC_FLAGS_LTO · 31 unmodified lines | ||
| 921 | 1001 | endif |
| 922 | 1002 | |
| 923 | 1003 | ifdef CONFIG_CFI_CLANG |
| 924 | −CC_FLAGS_CFI := -fsanitize=cfi \ | |
| 925 | − -fsanitize-cfi-cross-dso \ | |
| 926 | − -fno-sanitize-cfi-canonical-jump-tables \ | |
| 927 | − -fno-sanitize-trap=cfi \ | |
| 928 | − -fno-sanitize-blacklist | |
| 929 | − | |
| 930 | −ifdef CONFIG_CFI_PERMISSIVE | |
| 931 | −CC_FLAGS_CFI += -fsanitize-recover=cfi | |
| 932 | −endif | |
| 933 | − | |
| 934 | −# If LTO flags are filtered out, we must also filter out CFI. | |
| 935 | −CC_FLAGS_LTO += $(CC_FLAGS_CFI) | |
| 1004 | +CC_FLAGS_CFI := -fsanitize=kcfi | |
| 936 | 1005 | KBUILD_CFLAGS += $(CC_FLAGS_CFI) |
| 937 | 1006 | export CC_FLAGS_CFI |
| 938 | 1007 | endif |
| @@ -1026,10 +1095,11 @@ include $(addprefix $(srctree)/, $(include-y)) · 87 unmodified lines | ||
| 1026 | 1095 | # Do not add $(call cc-option,...) below this line. When you build the kernel |
| 1027 | 1096 | # from the clean source tree, the GCC plugins do not exist at this point. |
| 1028 | 1097 | |
| 1029 | −# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments | |
| 1098 | +# Add user supplied CPPFLAGS, AFLAGS, CFLAGS and RUSTFLAGS as the last assignments | |
| 1030 | 1099 | KBUILD_CPPFLAGS += $(KCPPFLAGS) |
| 1031 | 1100 | KBUILD_AFLAGS += $(KAFLAGS) |
| 1032 | 1101 | KBUILD_CFLAGS += $(KCFLAGS) |
| 1102 | +KBUILD_RUSTFLAGS += $(KRUSTFLAGS) | |
| 1033 | 1103 | |
| 1034 | 1104 | KBUILD_LDFLAGS_MODULE += --build-id=sha1 |
| 1035 | 1105 | LDFLAGS_vmlinux += --build-id=sha1 |
| @@ -1104,6 +1174,7 @@ ifeq ($(KBUILD_EXTMOD),) · 68 unmodified lines | ||
| 1104 | 1174 | core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ |
| 1105 | 1175 | core-$(CONFIG_BLOCK) += block/ |
| 1106 | 1176 | core-$(CONFIG_IO_URING) += io_uring/ |
| 1177 | +core-$(CONFIG_RUST) += rust/ | |
| 1107 | 1178 | |
| 1108 | 1179 | vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ |
| 1109 | 1180 | $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ |
| @@ -1206,6 +1277,10 @@ prepare0: archprepare · 96 unmodified lines | ||
| 1206 | 1277 | |
| 1207 | 1278 | # All the preparing.. |
| 1208 | 1279 | prepare: prepare0 |
| 1280 | +ifdef CONFIG_RUST | |
| 1281 | + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v | |
| 1282 | + $(Q)$(MAKE) $(build)=rust | |
| 1283 | +endif | |
| 1209 | 1284 | |
| 1210 | 1285 | PHONY += remove-stale-files |
| 1211 | 1286 | remove-stale-files: |
| @@ -1499,7 +1574,7 @@ endif # CONFIG_MODULES · 287 unmodified lines | ||
| 1499 | 1574 | # Directories & files removed with 'make clean' |
| 1500 | 1575 | CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ |
| 1501 | 1576 | modules.builtin modules.builtin.modinfo modules.nsdeps \ |
| 1502 | − compile_commands.json .thinlto-cache | |
| 1577 | + compile_commands.json .thinlto-cache rust/test rust/doc | |
| 1503 | 1578 | |
| 1504 | 1579 | # Directories & files removed with 'make mrproper' |
| 1505 | 1580 | MRPROPER_FILES += include/config include/generated \ |
| @@ -1510,7 +1585,8 @@ MRPROPER_FILES += include/config include/generated \ · 4 unmodified lines | ||
| 1510 | 1585 | certs/signing_key.pem \ |
| 1511 | 1586 | certs/x509.genkey \ |
| 1512 | 1587 | vmlinux-gdb.py \ |
| 1513 | − *.spec | |
| 1588 | + *.spec \ | |
| 1589 | + rust/target.json rust/libmacros.so | |
| 1514 | 1590 | |
| 1515 | 1591 | # clean - Delete most, but leave enough to build external modules |
| 1516 | 1592 | # |
| @@ -1535,6 +1611,9 @@ $(mrproper-dirs): · 18 unmodified lines | ||
| 1535 | 1611 | |
| 1536 | 1612 | mrproper: clean $(mrproper-dirs) |
| 1537 | 1613 | $(call cmd,rmfiles) |
| 1614 | + @find . $(RCS_FIND_IGNORE) \ | |
| 1615 | + \( -name '*.rmeta' \) \ | |
| 1616 | + -type f -print | xargs rm -f | |
| 1538 | 1617 | |
| 1539 | 1618 | # distclean |
| 1540 | 1619 | # |
| @@ -1622,6 +1701,24 @@ help: · 81 unmodified lines | ||
| 1622 | 1701 | @echo ' kselftest-merge - Merge all the config dependencies of' |
| 1623 | 1702 | @echo ' kselftest to existing .config.' |
| 1624 | 1703 | @echo '' |
| 1704 | + @echo 'Rust targets:' | |
| 1705 | + @echo ' rustavailable - Checks whether the Rust toolchain is' | |
| 1706 | + @echo ' available and, if not, explains why.' | |
| 1707 | + @echo ' rustfmt - Reformat all the Rust code in the kernel' | |
| 1708 | + @echo ' rustfmtcheck - Checks if all the Rust code in the kernel' | |
| 1709 | + @echo ' is formatted, printing a diff otherwise.' | |
| 1710 | + @echo ' rustdoc - Generate Rust documentation' | |
| 1711 | + @echo ' (requires kernel .config)' | |
| 1712 | + @echo ' rusttest - Runs the Rust tests' | |
| 1713 | + @echo ' (requires kernel .config; downloads external repos)' | |
| 1714 | + @echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file' | |
| 1715 | + @echo ' (requires kernel .config)' | |
| 1716 | + @echo ' dir/file.[os] - Build specified target only' | |
| 1717 | + @echo ' dir/file.rsi - Build macro expanded source, similar to C preprocessing.' | |
| 1718 | + @echo ' Run with RUSTFMT=n to skip reformatting if needed.' | |
| 1719 | + @echo ' The output is not intended to be compilable.' | |
| 1720 | + @echo ' dir/file.ll - Build the LLVM assembly file' | |
| 1721 | + @echo '' | |
| 1625 | 1722 | @$(if $(dtstree), \ |
| 1626 | 1723 | echo 'Devicetree:'; \ |
| 1627 | 1724 | echo '* dtbs - Build device tree blobs for enabled boards'; \ |
| @@ -1694,6 +1791,52 @@ PHONY += $(DOC_TARGETS) · 66 unmodified lines | ||
| 1694 | 1791 | $(DOC_TARGETS): |
| 1695 | 1792 | $(Q)$(MAKE) $(build)=Documentation $@ |
| 1696 | 1793 | |
| 1794 | + | |
| 1795 | +# Rust targets | |
| 1796 | +# --------------------------------------------------------------------------- | |
| 1797 | + | |
| 1798 | +# "Is Rust available?" target | |
| 1799 | +PHONY += rustavailable | |
| 1800 | +rustavailable: | |
| 1801 | + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!" | |
| 1802 | + | |
| 1803 | +# Documentation target | |
| 1804 | +# | |
| 1805 | +# Using the singular to avoid running afoul of `no-dot-config-targets`. | |
| 1806 | +PHONY += rustdoc | |
| 1807 | +rustdoc: prepare | |
| 1808 | + $(Q)$(MAKE) $(build)=rust $@ | |
| 1809 | + | |
| 1810 | +# Testing target | |
| 1811 | +PHONY += rusttest | |
| 1812 | +rusttest: prepare | |
| 1813 | + $(Q)$(MAKE) $(build)=rust $@ | |
| 1814 | + | |
| 1815 | +# Formatting targets | |
| 1816 | +PHONY += rustfmt rustfmtcheck | |
| 1817 | + | |
| 1818 | +# We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream. | |
| 1819 | +# | |
| 1820 | +# We match using absolute paths since `find` does not resolve them | |
| 1821 | +# when matching, which is a problem when e.g. `srctree` is `..`. | |
| 1822 | +# We `grep` afterwards in order to remove the directory entry itself. | |
| 1823 | +rustfmt: | |
| 1824 | + $(Q)find $(abs_srctree) -type f -name '*.rs' \ | |
| 1825 | + -o -path $(abs_srctree)/rust/alloc -prune \ | |
| 1826 | + -o -path $(abs_objtree)/rust/test -prune \ | |
| 1827 | + | grep -Fv $(abs_srctree)/rust/alloc \ | |
| 1828 | + | grep -Fv $(abs_objtree)/rust/test \ | |
| 1829 | + | grep -Fv generated \ | |
| 1830 | + | xargs $(RUSTFMT) $(rustfmt_flags) | |
| 1831 | + | |
| 1832 | +rustfmtcheck: rustfmt_flags = --check | |
| 1833 | +rustfmtcheck: rustfmt | |
| 1834 | + | |
| 1835 | +# IDE support targets | |
| 1836 | +PHONY += rust-analyzer | |
| 1837 | +rust-analyzer: | |
| 1838 | + $(Q)$(MAKE) $(build)=rust $@ | |
| 1839 | + | |
| 1697 | 1840 | # Misc |
| 1698 | 1841 | # --------------------------------------------------------------------------- |
| 1699 | 1842 | |
| @@ -1861,7 +2004,7 @@ $(clean-dirs): · 161 unmodified lines | ||
| 1861 | 2004 | clean: $(clean-dirs) |
| 1862 | 2005 | $(call cmd,rmfiles) |
| 1863 | 2006 | @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ |
| 1864 | − \( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \ | |
| 2007 | + \( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \ | |
| 1865 | 2008 | -o -name '*.ko.*' \ |
| 1866 | 2009 | -o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ |
| 1867 | 2010 | -o -name '*.dwo' -o -name '*.lst' \ |
| @@ -355,6 +355,12 @@ config HAVE_RSEQ · 354 unmodified lines | ||
| 355 | 355 | This symbol should be selected by an architecture if it |
| 356 | 356 | supports an implementation of restartable sequences. |
| 357 | 357 | |
| 358 | +config HAVE_RUST | |
| 359 | + bool | |
| 360 | + help | |
| 361 | + This symbol should be selected by an architecture if it | |
| 362 | + supports Rust. | |
| 363 | + | |
| 358 | 364 | config HAVE_FUNCTION_ARG_ACCESS_API |
| 359 | 365 | bool |
| 360 | 366 | help |
| @@ -738,11 +744,13 @@ config ARCH_SUPPORTS_CFI_CLANG · 377 unmodified lines | ||
| 738 | 744 | An architecture should select this option if it can support Clang's |
| 739 | 745 | Control-Flow Integrity (CFI) checking. |
| 740 | 746 | |
| 747 | +config ARCH_USES_CFI_TRAPS | |
| 748 | + bool | |
| 749 | + | |
| 741 | 750 | config CFI_CLANG |
| 742 | 751 | bool "Use Clang's Control Flow Integrity (CFI)" |
| 743 | − depends on LTO_CLANG && ARCH_SUPPORTS_CFI_CLANG | |
| 744 | − depends on CLANG_VERSION >= 140000 | |
| 745 | − select KALLSYMS | |
| 752 | + depends on ARCH_SUPPORTS_CFI_CLANG | |
| 753 | + depends on $(cc-option,-fsanitize=kcfi) | |
| 746 | 754 | help |
| 747 | 755 | This option enables Clang’s forward-edge Control Flow Integrity |
| 748 | 756 | (CFI) checking, where the compiler injects a runtime check to each |
| @@ -754,16 +762,6 @@ config CFI_CLANG · 5 unmodified lines | ||
| 754 | 762 | |
| 755 | 763 | https://clang.llvm.org/docs/ControlFlowIntegrity.html |
| 756 | 764 | |
| 757 | −config CFI_CLANG_SHADOW | |
| 758 | − bool "Use CFI shadow to speed up cross-module checks" | |
| 759 | − default y | |
| 760 | − depends on CFI_CLANG && MODULES | |
| 761 | − help | |
| 762 | − If you select this option, the kernel builds a fast look-up table of | |
| 763 | − CFI check functions in loaded modules to reduce performance overhead. | |
| 764 | − | |
| 765 | − If unsure, say Y. | |
| 766 | − | |
| 767 | 765 | config CFI_PERMISSIVE |
| 768 | 766 | bool "Use CFI in permissive mode" |
| 769 | 767 | depends on CFI_CLANG |
| @@ -1,16 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | −#ifndef __ALPHA_A_OUT_H__ | |
| 3 | −#define __ALPHA_A_OUT_H__ | |
| 4 | − | |
| 5 | −#include <uapi/asm/a.out.h> | |
| 6 | − | |
| 7 | − | |
| 8 | −/* Assume that start addresses below 4G belong to a TASO application. | |
| 9 | − Unfortunately, there is no proper bit in the exec header to check. | |
| 10 | − Worse, we have to notice the start address before swapping to use | |
| 11 | − /sbin/loader, which of course is _not_ a TASO application. */ | |
| 12 | −#define SET_AOUT_PERSONALITY(BFPM, EX) \ | |
| 13 | − set_personality (((BFPM->taso || EX.ah.entry < 0x100000000L \ | |
| 14 | − ? ADDR_LIMIT_32BIT : 0) | PER_OSF4)) | |
| 15 | − | |
| 16 | −#endif /* __A_OUT_GNU_H__ */ | |
| @@ -47,10 +47,6 @@ else · 46 unmodified lines | ||
| 47 | 47 | # Misc support |
| 48 | 48 | obj-$(CONFIG_ALPHA_SRM) += srmcons.o |
| 49 | 49 | |
| 50 | −ifdef CONFIG_BINFMT_AOUT | |
| 51 | −obj-y += binfmt_loader.o | |
| 52 | −endif | |
| 53 | − | |
| 54 | 50 | # Core logic support |
| 55 | 51 | obj-$(CONFIG_ALPHA_APECS) += core_apecs.o |
| 56 | 52 | obj-$(CONFIG_ALPHA_CIA) += core_cia.o |
| @@ -1,46 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 2 | −#include <linux/init.h> | |
| 3 | −#include <linux/fs.h> | |
| 4 | −#include <linux/file.h> | |
| 5 | −#include <linux/mm_types.h> | |
| 6 | −#include <linux/binfmts.h> | |
| 7 | −#include <linux/a.out.h> | |
| 8 | − | |
| 9 | −static int load_binary(struct linux_binprm *bprm) | |
| 10 | −{ | |
| 11 | − struct exec *eh = (struct exec *)bprm->buf; | |
| 12 | − unsigned long loader; | |
| 13 | − struct file *file; | |
| 14 | − int retval; | |
| 15 | − | |
| 16 | − if (eh->fh.f_magic != 0x183 || (eh->fh.f_flags & 0x3000) != 0x3000) | |
| 17 | − return -ENOEXEC; | |
| 18 | − | |
| 19 | − if (bprm->loader) | |
| 20 | − return -ENOEXEC; | |
| 21 | − | |
| 22 | − loader = bprm->vma->vm_end - sizeof(void *); | |
| 23 | − | |
| 24 | − file = open_exec("/sbin/loader"); | |
| 25 | − retval = PTR_ERR(file); | |
| 26 | − if (IS_ERR(file)) | |
| 27 | − return retval; | |
| 28 | − | |
| 29 | − /* Remember if the application is TASO. */ | |
| 30 | − bprm->taso = eh->ah.entry < 0x100000000UL; | |
| 31 | − | |
| 32 | − bprm->interpreter = file; | |
| 33 | − bprm->loader = loader; | |
| 34 | − return 0; | |
| 35 | −} | |
| 36 | − | |
| 37 | −static struct linux_binfmt loader_format = { | |
| 38 | − .load_binary = load_binary, | |
| 39 | −}; | |
| 40 | − | |
| 41 | −static int __init init_loader_binfmt(void) | |
| 42 | −{ | |
| 43 | − insert_binfmt(&loader_format); | |
| 44 | − return 0; | |
| 45 | −} | |
| 46 | −arch_initcall(init_loader_binfmt); | |
| @@ -1278,45 +1278,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, · 1277 unmodified lines | ||
| 1278 | 1278 | return addr; |
| 1279 | 1279 | } |
| 1280 | 1280 | |
| 1281 | −#ifdef CONFIG_OSF4_COMPAT | |
| 1282 | −/* Clear top 32 bits of iov_len in the user's buffer for | |
| 1283 | − compatibility with old versions of OSF/1 where iov_len | |
| 1284 | − was defined as int. */ | |
| 1285 | −static int | |
| 1286 | −osf_fix_iov_len(const struct iovec __user *iov, unsigned long count) | |
| 1287 | −{ | |
| 1288 | − unsigned long i; | |
| 1289 | − | |
| 1290 | − for (i = 0 ; i < count ; i++) { | |
| 1291 | − int __user *iov_len_high = (int __user *)&iov[i].iov_len + 1; | |
| 1292 | − | |
| 1293 | − if (put_user(0, iov_len_high)) | |
| 1294 | − return -EFAULT; | |
| 1295 | − } | |
| 1296 | − return 0; | |
| 1297 | −} | |
| 1298 | −#endif | |
| 1299 | − | |
| 1300 | 1281 | SYSCALL_DEFINE3(osf_readv, unsigned long, fd, |
| 1301 | 1282 | const struct iovec __user *, vector, unsigned long, count) |
| 1302 | 1283 | { |
| 1303 | −#ifdef CONFIG_OSF4_COMPAT | |
| 1304 | − if (unlikely(personality(current->personality) == PER_OSF4)) | |
| 1305 | − if (osf_fix_iov_len(vector, count)) | |
| 1306 | − return -EFAULT; | |
| 1307 | −#endif | |
| 1308 | − | |
| 1309 | 1284 | return sys_readv(fd, vector, count); |
| 1310 | 1285 | } |
| 1311 | 1286 | |
| 1312 | 1287 | SYSCALL_DEFINE3(osf_writev, unsigned long, fd, |
| 1313 | 1288 | const struct iovec __user *, vector, unsigned long, count) |
| 1314 | 1289 | { |
| 1315 | −#ifdef CONFIG_OSF4_COMPAT | |
| 1316 | − if (unlikely(personality(current->personality) == PER_OSF4)) | |
| 1317 | − if (osf_fix_iov_len(vector, count)) | |
| 1318 | − return -EFAULT; | |
| 1319 | −#endif | |
| 1320 | 1290 | return sys_writev(fd, vector, count); |
| 1321 | 1291 | } |
| 1322 | 1292 | |
| @@ -23,7 +23,9 @@ unsigned int __machine_arch_type; · 22 unmodified lines | ||
| 23 | 23 | #include <linux/types.h> |
| 24 | 24 | #include <linux/linkage.h> |
| 25 | 25 | #include "misc.h" |
| 26 | +#ifdef CONFIG_ARCH_EP93XX | |
| 26 | 27 | #include "misc-ep93xx.h" |
| 28 | +#endif | |
| 27 | 29 | |
| 28 | 30 | static void putstr(const char *ptr); |
| 29 | 31 | |
| @@ -23,6 +23,7 @@ SECTIONS · 22 unmodified lines | ||
| 23 | 23 | *(.ARM.extab*) |
| 24 | 24 | *(.note.*) |
| 25 | 25 | *(.rel.*) |
| 26 | + *(.printk_index) | |
| 26 | 27 | /* |
| 27 | 28 | * Discard any r/w data - this produces a link error if we have any, |
| 28 | 29 | * which is required for PIC decompression. Local data generates |
| @@ -57,6 +58,7 @@ SECTIONS · 28 unmodified lines | ||
| 57 | 58 | *(.rodata) |
| 58 | 59 | *(.rodata.*) |
| 59 | 60 | *(.data.rel.ro) |
| 61 | + *(.data.rel.ro.*) | |
| 60 | 62 | } |
| 61 | 63 | .piggydata : { |
| 62 | 64 | *(.piggydata) |
| @@ -6,7 +6,6 @@ CONFIG_UNUSED_BOARD_FILES=y · 5 unmodified lines | ||
| 6 | 6 | CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3" |
| 7 | 7 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y |
| 8 | 8 | CONFIG_FPE_NWFPE=y |
| 9 | −CONFIG_BINFMT_AOUT=m | |
| 10 | 9 | CONFIG_MODULES=y |
| 11 | 10 | CONFIG_MODVERSIONS=y |
| 12 | 11 | CONFIG_PARTITION_ADVANCED=y |
| @@ -16,7 +16,6 @@ CONFIG_MACH_HUSKY=y · 15 unmodified lines | ||
| 16 | 16 | CONFIG_UNUSED_BOARD_FILES=y |
| 17 | 17 | CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug" |
| 18 | 18 | CONFIG_FPE_NWFPE=y |
| 19 | −CONFIG_BINFMT_AOUT=m | |
| 20 | 19 | CONFIG_MODULES=y |
| 21 | 20 | CONFIG_MODULE_UNLOAD=y |
| 22 | 21 | CONFIG_MODULE_FORCE_UNLOAD=y |
| @@ -25,7 +25,6 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=m · 24 unmodified lines | ||
| 25 | 25 | CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m |
| 26 | 26 | CONFIG_CPU_IDLE=y |
| 27 | 27 | CONFIG_FPE_NWFPE=y |
| 28 | −CONFIG_BINFMT_AOUT=m | |
| 29 | 28 | CONFIG_PM=y |
| 30 | 29 | CONFIG_APM_EMULATION=y |
| 31 | 30 | CONFIG_MODULES=y |
| @@ -9,7 +9,6 @@ CONFIG_ARCH_EBSA285_HOST=y · 8 unmodified lines | ||
| 9 | 9 | CONFIG_ARCH_NETWINDER=y |
| 10 | 10 | CONFIG_FPE_NWFPE=y |
| 11 | 11 | CONFIG_FPE_NWFPE_XP=y |
| 12 | −CONFIG_BINFMT_AOUT=y | |
| 13 | 12 | CONFIG_MODULES=y |
| 14 | 13 | CONFIG_PARTITION_ADVANCED=y |
| 15 | 14 | CONFIG_ACORN_PARTITION=y |
| @@ -7,7 +7,6 @@ CONFIG_UNUSED_BOARD_FILES=y · 6 unmodified lines | ||
| 7 | 7 | CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell" |
| 8 | 8 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y |
| 9 | 9 | CONFIG_FPE_NWFPE=y |
| 10 | −CONFIG_BINFMT_AOUT=y | |
| 11 | 10 | CONFIG_MODULES=y |
| 12 | 11 | CONFIG_NET=y |
| 13 | 12 | CONFIG_PACKET=y |
| @@ -12,7 +12,6 @@ CONFIG_MACH_N2100=y · 11 unmodified lines | ||
| 12 | 12 | CONFIG_UNUSED_BOARD_FILES=y |
| 13 | 13 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc" |
| 14 | 14 | CONFIG_FPE_NWFPE=y |
| 15 | −CONFIG_BINFMT_AOUT=y | |
| 16 | 15 | CONFIG_MODULES=y |
| 17 | 16 | CONFIG_MODULE_UNLOAD=y |
| 18 | 17 | CONFIG_PARTITION_ADVANCED=y |
| @@ -6,7 +6,6 @@ CONFIG_SA1100_JORNADA720=y · 5 unmodified lines | ||
| 6 | 6 | CONFIG_SA1100_JORNADA720_SSP=y |
| 7 | 7 | CONFIG_UNUSED_BOARD_FILES=y |
| 8 | 8 | CONFIG_FPE_NWFPE=y |
| 9 | −CONFIG_BINFMT_AOUT=y | |
| 10 | 9 | CONFIG_PM=y |
| 11 | 10 | CONFIG_MODULES=y |
| 12 | 11 | CONFIG_NET=y |
| @@ -8,7 +8,6 @@ CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram" · 7 unmodified lines | ||
| 8 | 8 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y |
| 9 | 9 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
| 10 | 10 | CONFIG_FPE_NWFPE=y |
| 11 | −CONFIG_BINFMT_AOUT=y | |
| 12 | 11 | CONFIG_PM=y |
| 13 | 12 | CONFIG_MODULES=y |
| 14 | 13 | CONFIG_NET=y |
| @@ -9,7 +9,6 @@ CONFIG_ZBOOT_ROM_BSS=0xc1000000 · 8 unmodified lines | ||
| 9 | 9 | CONFIG_ZBOOT_ROM=y |
| 10 | 10 | CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M" |
| 11 | 11 | CONFIG_FPE_NWFPE=y |
| 12 | −CONFIG_BINFMT_AOUT=y | |
| 13 | 12 | CONFIG_PM=y |
| 14 | 13 | CONFIG_MODULES=y |
| 15 | 14 | CONFIG_MODULE_UNLOAD=y |
| @@ -5,7 +5,6 @@ CONFIG_ARCH_NETWINDER=y · 4 unmodified lines | ||
| 5 | 5 | CONFIG_DEPRECATED_PARAM_STRUCT=y |
| 6 | 6 | CONFIG_CMDLINE="root=0x801" |
| 7 | 7 | CONFIG_FPE_NWFPE=y |
| 8 | −CONFIG_BINFMT_AOUT=y | |
| 9 | 8 | CONFIG_PARTITION_ADVANCED=y |
| 10 | 9 | CONFIG_NET=y |
| 11 | 10 | CONFIG_PACKET=y |
| @@ -7,7 +7,6 @@ CONFIG_MODULE_UNLOAD=y · 6 unmodified lines | ||
| 7 | 7 | CONFIG_ARCH_RPC=y |
| 8 | 8 | CONFIG_CPU_SA110=y |
| 9 | 9 | CONFIG_FPE_NWFPE=y |
| 10 | −CONFIG_BINFMT_AOUT=y | |
| 11 | 10 | CONFIG_PARTITION_ADVANCED=y |
| 12 | 11 | CONFIG_BSD_DISKLABEL=y |
| 13 | 12 | CONFIG_SLAB=y |
| @@ -13,7 +13,6 @@ CONFIG_MACH_AKITA=y · 12 unmodified lines | ||
| 13 | 13 | CONFIG_MACH_BORZOI=y |
| 14 | 14 | CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug" |
| 15 | 15 | CONFIG_FPE_NWFPE=y |
| 16 | −CONFIG_BINFMT_AOUT=m | |
| 17 | 16 | CONFIG_MODULES=y |
| 18 | 17 | CONFIG_MODULE_UNLOAD=y |
| 19 | 18 | CONFIG_MODULE_FORCE_UNLOAD=y |
| @@ -346,7 +346,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) · 345 unmodified lines | ||
| 346 | 346 | addr = start + i * PMD_SIZE; |
| 347 | 347 | domain = get_domain_name(pmd); |
| 348 | 348 | if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd)) |
| 349 | − note_page(st, addr, 3, pmd_val(*pmd), domain); | |
| 349 | + note_page(st, addr, 4, pmd_val(*pmd), domain); | |
| 350 | 350 | else |
| 351 | 351 | walk_pte(st, pmd, addr, domain); |
| 352 | 352 | |
| @@ -300,7 +300,11 @@ static struct mem_type mem_types[] __ro_after_init = { · 299 unmodified lines | ||
| 300 | 300 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | |
| 301 | 301 | L_PTE_XN | L_PTE_RDONLY, |
| 302 | 302 | .prot_l1 = PMD_TYPE_TABLE, |
| 303 | +#ifdef CONFIG_ARM_LPAE | |
| 304 | + .prot_sect = PMD_TYPE_SECT | L_PMD_SECT_RDONLY | PMD_SECT_AP2, | |
| 305 | +#else | |
| 303 | 306 | .prot_sect = PMD_TYPE_SECT, |
| 307 | +#endif | |
| 304 | 308 | .domain = DOMAIN_KERNEL, |
| 305 | 309 | }, |
| 306 | 310 | [MT_ROM] = { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/linkage.h> |
| 9 | +#include <linux/cfi_types.h> | |
| 9 | 10 | #include <asm/assembler.h> |
| 10 | 11 | |
| 11 | 12 | SHASH .req v0 |
| @@ -350,11 +351,11 @@ CPU_LE( rev64 T1.16b, T1.16b ) · 338 unmodified lines | ||
| 350 | 351 | * void pmull_ghash_update(int blocks, u64 dg[], const char *src, |
| 351 | 352 | * struct ghash_key const *k, const char *head) |
| 352 | 353 | */ |
| 353 | −SYM_FUNC_START(pmull_ghash_update_p64) | |
| 354 | +SYM_TYPED_FUNC_START(pmull_ghash_update_p64) | |
| 354 | 355 | __pmull_ghash p64 |
| 355 | 356 | SYM_FUNC_END(pmull_ghash_update_p64) |
| 356 | 357 | |
| 357 | −SYM_FUNC_START(pmull_ghash_update_p8) | |
| 358 | +SYM_TYPED_FUNC_START(pmull_ghash_update_p8) | |
| 358 | 359 | __pmull_ghash p8 |
| 359 | 360 | SYM_FUNC_END(pmull_ghash_update_p8) |
| 360 | 361 | |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/linkage.h> |
| 9 | +#include <linux/cfi_types.h> | |
| 9 | 10 | #include <asm/assembler.h> |
| 10 | 11 | |
| 11 | 12 | .irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 |
| @@ -73,7 +74,7 @@ · 61 unmodified lines | ||
| 73 | 74 | * int blocks) |
| 74 | 75 | */ |
| 75 | 76 | .text |
| 76 | −SYM_FUNC_START(sm3_ce_transform) | |
| 77 | +SYM_TYPED_FUNC_START(sm3_ce_transform) | |
| 77 | 78 | /* load state */ |
| 78 | 79 | ld1 {v8.4s-v9.4s}, [x0] |
| 79 | 80 | rev64 v8.4s, v8.4s |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | * 0x401: for compile time BRK instruction |
| 18 | 18 | * 0x800: kernel-mode BUG() and WARN() traps |
| 19 | 19 | * 0x9xx: tag-based KASAN trap (allowed values 0x900 - 0x9ff) |
| 20 | + * 0x8xxx: Control-Flow Integrity traps | |
| 20 | 21 | */ |
| 21 | 22 | #define KPROBES_BRK_IMM 0x004 |
| 22 | 23 | #define UPROBES_BRK_IMM 0x005 |
| @@ -28,4 +29,9 @@ · 5 unmodified lines | ||
| 28 | 29 | #define KASAN_BRK_IMM 0x900 |
| 29 | 30 | #define KASAN_BRK_MASK 0x0ff |
| 30 | 31 | |
| 32 | +#define CFI_BRK_IMM_TARGET GENMASK(4, 0) | |
| 33 | +#define CFI_BRK_IMM_TYPE GENMASK(9, 5) | |
| 34 | +#define CFI_BRK_IMM_BASE 0x8000 | |
| 35 | +#define CFI_BRK_IMM_MASK (CFI_BRK_IMM_TARGET | CFI_BRK_IMM_TYPE) | |
| 36 | + | |
| 31 | 37 | #endif |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS |
| 27 | 27 | #define ARCH_SUPPORTS_FTRACE_OPS 1 |
| 28 | 28 | #else |
| 29 | −#define MCOUNT_ADDR ((unsigned long)function_nocfi(_mcount)) | |
| 29 | +#define MCOUNT_ADDR ((unsigned long)_mcount) | |
| 30 | 30 | #endif |
| 31 | 31 | |
| 32 | 32 | /* The BL at the callsite's adjusted rec->ip */ |
| @@ -39,4 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | SYM_START(name, SYM_L_WEAK, SYM_A_NONE) \ |
| 40 | 40 | bti c ; |
| 41 | 41 | |
| 42 | +#define SYM_TYPED_FUNC_START(name) \ | |
| 43 | + SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) \ | |
| 44 | + bti c ; | |
| 45 | + | |
| 42 | 46 | #endif |
| @@ -147,7 +147,7 @@ static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz) · 146 unmodified lines | ||
| 147 | 147 | * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD, |
| 148 | 148 | * avoiding the possibility of conflicting TLB entries being allocated. |
| 149 | 149 | */ |
| 150 | −static inline void __nocfi cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap) | |
| 150 | +static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap) | |
| 151 | 151 | { |
| 152 | 152 | typedef void (ttbr_replace_func)(phys_addr_t); |
| 153 | 153 | extern ttbr_replace_func idmap_cpu_replace_ttbr1; |
| @@ -168,7 +168,7 @@ static inline void __nocfi cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap) · 14 unmodified lines | ||
| 168 | 168 | ttbr1 |= TTBR_CNP_BIT; |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | − replace_phys = (void *)__pa_symbol(function_nocfi(idmap_cpu_replace_ttbr1)); | |
| 171 | + replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1); | |
| 172 | 172 | |
| 173 | 173 | __cpu_install_idmap(idmap); |
| 174 | 174 | replace_phys(ttbr1); |
| @@ -99,7 +99,7 @@ static int acpi_parking_protocol_cpu_boot(unsigned int cpu) · 98 unmodified lines | ||
| 99 | 99 | * that read this address need to convert this address to the |
| 100 | 100 | * Boot-Loader's endianness before jumping. |
| 101 | 101 | */ |
| 102 | − writeq_relaxed(__pa_symbol(function_nocfi(secondary_entry)), | |
| 102 | + writeq_relaxed(__pa_symbol(secondary_entry), | |
| 103 | 103 | &mailbox->entry_point); |
| 104 | 104 | writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id); |
| 105 | 105 | |
| @@ -133,7 +133,7 @@ static void clean_dcache_range_nopatch(u64 start, u64 end) · 132 unmodified lines | ||
| 133 | 133 | } while (cur += d_size, cur < end); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | −static void __nocfi __apply_alternatives(struct alt_region *region, bool is_module, | |
| 136 | +static void __apply_alternatives(struct alt_region *region, bool is_module, | |
| 137 | 137 | unsigned long *feature_mask) |
| 138 | 138 | { |
| 139 | 139 | struct alt_instr *alt; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | #include <linux/linkage.h> |
| 11 | +#include <linux/cfi_types.h> | |
| 11 | 12 | #include <asm/assembler.h> |
| 12 | 13 | #include <asm/sysreg.h> |
| 13 | 14 | #include <asm/virt.h> |
| @@ -28,7 +29,7 @@ · 14 unmodified lines | ||
| 28 | 29 | * branch to what would be the reset vector. It must be executed with the |
| 29 | 30 | * flat identity mapping. |
| 30 | 31 | */ |
| 31 | −SYM_CODE_START(cpu_soft_restart) | |
| 32 | +SYM_TYPED_FUNC_START(cpu_soft_restart) | |
| 32 | 33 | mov_q x12, INIT_SCTLR_EL1_MMU_OFF |
| 33 | 34 | pre_disable_mmu_workaround |
| 34 | 35 | /* |
| @@ -47,6 +48,6 @@ SYM_CODE_START(cpu_soft_restart) · 12 unmodified lines | ||
| 47 | 48 | mov x1, x3 // arg1 |
| 48 | 49 | mov x2, x4 // arg2 |
| 49 | 50 | br x8 |
| 50 | −SYM_CODE_END(cpu_soft_restart) | |
| 51 | +SYM_FUNC_END(cpu_soft_restart) | |
| 51 | 52 | |
| 52 | 53 | .popsection |
| @@ -1685,7 +1685,7 @@ static phys_addr_t kpti_ng_pgd_alloc(int shift) · 1684 unmodified lines | ||
| 1685 | 1685 | return kpti_ng_temp_alloc; |
| 1686 | 1686 | } |
| 1687 | 1687 | |
| 1688 | −static void __nocfi | |
| 1688 | +static void | |
| 1689 | 1689 | kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused) |
| 1690 | 1690 | { |
| 1691 | 1691 | typedef void (kpti_remap_fn)(int, int, phys_addr_t, unsigned long); |
| @@ -1713,7 +1713,7 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused) · 21 unmodified lines | ||
| 1713 | 1713 | if (arm64_use_ng_mappings) |
| 1714 | 1714 | return; |
| 1715 | 1715 | |
| 1716 | − remap_fn = (void *)__pa_symbol(function_nocfi(idmap_kpti_install_ng_mappings)); | |
| 1716 | + remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings); | |
| 1717 | 1717 | |
| 1718 | 1718 | if (!cpu) { |
| 1719 | 1719 | alloc = __get_free_pages(GFP_ATOMIC | __GFP_ZERO, order); |
| @@ -56,7 +56,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) · 55 unmodified lines | ||
| 56 | 56 | unsigned long pc; |
| 57 | 57 | u32 new; |
| 58 | 58 | |
| 59 | − pc = (unsigned long)function_nocfi(ftrace_call); | |
| 59 | + pc = (unsigned long)ftrace_call; | |
| 60 | 60 | new = aarch64_insn_gen_branch_imm(pc, (unsigned long)func, |
| 61 | 61 | AARCH64_INSN_BRANCH_LINK); |
| 62 | 62 | |
| @@ -204,7 +204,7 @@ void machine_kexec(struct kimage *kimage) · 203 unmodified lines | ||
| 204 | 204 | typeof(cpu_soft_restart) *restart; |
| 205 | 205 | |
| 206 | 206 | cpu_install_idmap(); |
| 207 | − restart = (void *)__pa_symbol(function_nocfi(cpu_soft_restart)); | |
| 207 | + restart = (void *)__pa_symbol(cpu_soft_restart); | |
| 208 | 208 | restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem, |
| 209 | 209 | 0, 0); |
| 210 | 210 | } else { |
| @@ -38,7 +38,7 @@ static int __init cpu_psci_cpu_prepare(unsigned int cpu) · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | static int cpu_psci_cpu_boot(unsigned int cpu) |
| 40 | 40 | { |
| 41 | − phys_addr_t pa_secondary_entry = __pa_symbol(function_nocfi(secondary_entry)); | |
| 41 | + phys_addr_t pa_secondary_entry = __pa_symbol(secondary_entry); | |
| 42 | 42 | int err = psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry); |
| 43 | 43 | if (err) |
| 44 | 44 | pr_err("failed to boot CPU%d (%d)\n", cpu, err); |
| @@ -66,7 +66,7 @@ static int smp_spin_table_cpu_init(unsigned int cpu) · 65 unmodified lines | ||
| 66 | 66 | static int smp_spin_table_cpu_prepare(unsigned int cpu) |
| 67 | 67 | { |
| 68 | 68 | __le64 __iomem *release_addr; |
| 69 | − phys_addr_t pa_holding_pen = __pa_symbol(function_nocfi(secondary_holding_pen)); | |
| 69 | + phys_addr_t pa_holding_pen = __pa_symbol(secondary_holding_pen); | |
| 70 | 70 | |
| 71 | 71 | if (!cpu_release_addr[cpu]) |
| 72 | 72 | return -ENODEV; |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/syscalls.h> |
| 27 | 27 | #include <linux/mm_types.h> |
| 28 | 28 | #include <linux/kasan.h> |
| 29 | +#include <linux/cfi.h> | |
| 29 | 30 | |
| 30 | 31 | #include <asm/atomic.h> |
| 31 | 32 | #include <asm/bug.h> |
| @@ -991,6 +992,38 @@ static struct break_hook bug_break_hook = { · 959 unmodified lines | ||
| 991 | 992 | .imm = BUG_BRK_IMM, |
| 992 | 993 | }; |
| 993 | 994 | |
| 995 | +#ifdef CONFIG_CFI_CLANG | |
| 996 | +static int cfi_handler(struct pt_regs *regs, unsigned long esr) | |
| 997 | +{ | |
| 998 | + unsigned long target; | |
| 999 | + u32 type; | |
| 1000 | + | |
| 1001 | + target = pt_regs_read_reg(regs, FIELD_GET(CFI_BRK_IMM_TARGET, esr)); | |
| 1002 | + type = (u32)pt_regs_read_reg(regs, FIELD_GET(CFI_BRK_IMM_TYPE, esr)); | |
| 1003 | + | |
| 1004 | + switch (report_cfi_failure(regs, regs->pc, &target, type)) { | |
| 1005 | + case BUG_TRAP_TYPE_BUG: | |
| 1006 | + die("Oops - CFI", regs, 0); | |
| 1007 | + break; | |
| 1008 | + | |
| 1009 | + case BUG_TRAP_TYPE_WARN: | |
| 1010 | + break; | |
| 1011 | + | |
| 1012 | + default: | |
| 1013 | + return DBG_HOOK_ERROR; | |
| 1014 | + } | |
| 1015 | + | |
| 1016 | + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); | |
| 1017 | + return DBG_HOOK_HANDLED; | |
| 1018 | +} | |
| 1019 | + | |
| 1020 | +static struct break_hook cfi_break_hook = { | |
| 1021 | + .fn = cfi_handler, | |
| 1022 | + .imm = CFI_BRK_IMM_BASE, | |
| 1023 | + .mask = CFI_BRK_IMM_MASK, | |
| 1024 | +}; | |
| 1025 | +#endif /* CONFIG_CFI_CLANG */ | |
| 1026 | + | |
| 994 | 1027 | static int reserved_fault_handler(struct pt_regs *regs, unsigned long esr) |
| 995 | 1028 | { |
| 996 | 1029 | pr_err("%s generated an invalid instruction at %pS!\n", |
| @@ -1052,6 +1085,9 @@ static struct break_hook kasan_break_hook = { · 55 unmodified lines | ||
| 1052 | 1085 | }; |
| 1053 | 1086 | #endif |
| 1054 | 1087 | |
| 1088 | + | |
| 1089 | +#define esr_comment(esr) ((esr) & ESR_ELx_BRK64_ISS_COMMENT_MASK) | |
| 1090 | + | |
| 1055 | 1091 | /* |
| 1056 | 1092 | * Initial handler for AArch64 BRK exceptions |
| 1057 | 1093 | * This handler only used until debug_traps_init(). |
| @@ -1059,10 +1095,12 @@ static struct break_hook kasan_break_hook = { · 1 unmodified line | ||
| 1059 | 1095 | int __init early_brk64(unsigned long addr, unsigned long esr, |
| 1060 | 1096 | struct pt_regs *regs) |
| 1061 | 1097 | { |
| 1098 | +#ifdef CONFIG_CFI_CLANG | |
| 1099 | + if ((esr_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE) | |
| 1100 | + return cfi_handler(regs, esr) != DBG_HOOK_HANDLED; | |
| 1101 | +#endif | |
| 1062 | 1102 | #ifdef CONFIG_KASAN_SW_TAGS |
| 1063 | − unsigned long comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK; | |
| 1064 | − | |
| 1065 | − if ((comment & ~KASAN_BRK_MASK) == KASAN_BRK_IMM) | |
| 1103 | + if ((esr_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM) | |
| 1066 | 1104 | return kasan_handler(regs, esr) != DBG_HOOK_HANDLED; |
| 1067 | 1105 | #endif |
| 1068 | 1106 | return bug_handler(regs, esr) != DBG_HOOK_HANDLED; |
| @@ -1071,6 +1109,9 @@ int __init early_brk64(unsigned long addr, unsigned long esr, · 2 unmodified lines | ||
| 1071 | 1109 | void __init trap_init(void) |
| 1072 | 1110 | { |
| 1073 | 1111 | register_kernel_break_hook(&bug_break_hook); |
| 1112 | +#ifdef CONFIG_CFI_CLANG | |
| 1113 | + register_kernel_break_hook(&cfi_break_hook); | |
| 1114 | +#endif | |
| 1074 | 1115 | register_kernel_break_hook(&fault_break_hook); |
| 1075 | 1116 | #ifdef CONFIG_KASAN_SW_TAGS |
| 1076 | 1117 | register_kernel_break_hook(&kasan_break_hook); |
| @@ -40,7 +40,8 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO · 39 unmodified lines | ||
| 40 | 40 | # kernel with CONFIG_WERROR enabled. |
| 41 | 41 | CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \ |
| 42 | 42 | $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) \ |
| 43 | − $(CC_FLAGS_LTO) -Wmissing-prototypes -Wmissing-declarations | |
| 43 | + $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \ | |
| 44 | + -Wmissing-prototypes -Wmissing-declarations | |
| 44 | 45 | KASAN_SANITIZE := n |
| 45 | 46 | KCSAN_SANITIZE := n |
| 46 | 47 | UBSAN_SANITIZE := n |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/init.h> |
| 11 | 11 | #include <linux/linkage.h> |
| 12 | 12 | #include <linux/pgtable.h> |
| 13 | +#include <linux/cfi_types.h> | |
| 13 | 14 | #include <asm/assembler.h> |
| 14 | 15 | #include <asm/asm-offsets.h> |
| 15 | 16 | #include <asm/asm_pointer_auth.h> |
| @@ -185,7 +186,7 @@ SYM_FUNC_END(cpu_do_resume) · 169 unmodified lines | ||
| 185 | 186 | * This is the low-level counterpart to cpu_replace_ttbr1, and should not be |
| 186 | 187 | * called by anything else. It can only be executed from a TTBR0 mapping. |
| 187 | 188 | */ |
| 188 | −SYM_FUNC_START(idmap_cpu_replace_ttbr1) | |
| 189 | +SYM_TYPED_FUNC_START(idmap_cpu_replace_ttbr1) | |
| 189 | 190 | save_and_disable_daif flags=x2 |
| 190 | 191 | |
| 191 | 192 | __idmap_cpu_set_reserved_ttbr1 x1, x3 |
| @@ -253,7 +254,7 @@ SYM_FUNC_END(idmap_cpu_replace_ttbr1) · 61 unmodified lines | ||
| 253 | 254 | SYM_DATA(__idmap_kpti_flag, .long 1) |
| 254 | 255 | .popsection |
| 255 | 256 | |
| 256 | −SYM_FUNC_START(idmap_kpti_install_ng_mappings) | |
| 257 | +SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings) | |
| 257 | 258 | cpu .req w0 |
| 258 | 259 | temp_pte .req x0 |
| 259 | 260 | num_cpus .req w1 |
| @@ -1970,7 +1970,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, · 1969 unmodified lines | ||
| 1970 | 1970 | u32 flags, struct bpf_tramp_links *tlinks, |
| 1971 | 1971 | void *orig_call) |
| 1972 | 1972 | { |
| 1973 | − int ret; | |
| 1973 | + int i, ret; | |
| 1974 | 1974 | int nargs = m->nr_args; |
| 1975 | 1975 | int max_insns = ((long)image_end - (long)image) / AARCH64_INSN_SIZE; |
| 1976 | 1976 | struct jit_ctx ctx = { |
| @@ -1982,6 +1982,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, · 5 unmodified lines | ||
| 1982 | 1982 | if (nargs > 8) |
| 1983 | 1983 | return -ENOTSUPP; |
| 1984 | 1984 | |
| 1985 | + /* don't support struct argument */ | |
| 1986 | + for (i = 0; i < MAX_BPF_FUNC_ARGS; i++) { | |
| 1987 | + if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) | |
| 1988 | + return -ENOTSUPP; | |
| 1989 | + } | |
| 1990 | + | |
| 1985 | 1991 | ret = prepare_trampoline(&ctx, im, tlinks, orig_call, nargs, flags); |
| 1986 | 1992 | if (ret < 0) |
| 1987 | 1993 | return ret; |
| @@ -10,7 +10,6 @@ config LOONGARCH · 9 unmodified lines | ||
| 10 | 10 | select ARCH_ENABLE_MEMORY_HOTPLUG |
| 11 | 11 | select ARCH_ENABLE_MEMORY_HOTREMOVE |
| 12 | 12 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI |
| 13 | − select ARCH_HAS_PHYS_TO_DMA | |
| 14 | 13 | select ARCH_HAS_PTE_SPECIAL |
| 15 | 14 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
| 16 | 15 | select ARCH_INLINE_READ_LOCK if !PREEMPTION |
| @@ -2,39 +2,29 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited |
| 4 | 4 | */ |
| 5 | −#include <linux/init.h> | |
| 5 | +#include <linux/acpi.h> | |
| 6 | 6 | #include <linux/dma-direct.h> |
| 7 | −#include <linux/dma-mapping.h> | |
| 8 | −#include <linux/dma-map-ops.h> | |
| 9 | −#include <linux/swiotlb.h> | |
| 10 | 7 | |
| 11 | −#include <asm/bootinfo.h> | |
| 12 | −#include <asm/dma.h> | |
| 13 | −#include <asm/loongson.h> | |
| 14 | − | |
| 15 | −/* | |
| 16 | − * We extract 4bit node id (bit 44~47) from Loongson-3's | |
| 17 | − * 48bit physical address space and embed it into 40bit. | |
| 18 | − */ | |
| 19 | − | |
| 20 | −static int node_id_offset; | |
| 21 | − | |
| 22 | −dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) | |
| 23 | −{ | |
| 24 | − long nid = (paddr >> 44) & 0xf; | |
| 25 | − | |
| 26 | − return ((nid << 44) ^ paddr) | (nid << node_id_offset); | |
| 27 | −} | |
| 28 | − | |
| 29 | −phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | |
| 8 | +void acpi_arch_dma_setup(struct device *dev) | |
| 30 | 9 | { |
| 31 | − long nid = (daddr >> node_id_offset) & 0xf; | |
| 10 | + int ret; | |
| 11 | + u64 mask, end = 0; | |
| 12 | + const struct bus_dma_region *map = NULL; | |
| 13 | + | |
| 14 | + ret = acpi_dma_get_range(dev, &map); | |
| 15 | + if (!ret && map) { | |
| 16 | + const struct bus_dma_region *r = map; | |
| 17 | + | |
| 18 | + for (end = 0; r->size; r++) { | |
| 19 | + if (r->dma_start + r->size - 1 > end) | |
| 20 | + end = r->dma_start + r->size - 1; | |
| 21 | + } | |
| 22 | + | |
| 23 | + mask = DMA_BIT_MASK(ilog2(end) + 1); | |
| 24 | + dev->bus_dma_limit = end; | |
| 25 | + dev->dma_range_map = map; | |
| 26 | + dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask); | |
| 27 | + *dev->dma_mask = min(*dev->dma_mask, mask); | |
| 28 | + } | |
| 32 | 29 | |
| 33 | − return ((nid << node_id_offset) ^ daddr) | (nid << 44); | |
| 34 | −} | |
| 35 | − | |
| 36 | −void __init plat_swiotlb_setup(void) | |
| 37 | −{ | |
| 38 | − swiotlb_init(true, SWIOTLB_VERBOSE); | |
| 39 | − node_id_offset = ((readl(LS7A_DMA_CFG) & LS7A_DMA_NODE_MASK) >> LS7A_DMA_NODE_SHF) + 36; | |
| 40 | 30 | } |
| @@ -247,7 +247,7 @@ static void __init arch_mem_init(char **cmdline_p) · 246 unmodified lines | ||
| 247 | 247 | sparse_init(); |
| 248 | 248 | memblock_set_bottom_up(true); |
| 249 | 249 | |
| 250 | − plat_swiotlb_setup(); | |
| 250 | + swiotlb_init(true, SWIOTLB_VERBOSE); | |
| 251 | 251 | |
| 252 | 252 | dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); |
| 253 | 253 | |
| @@ -87,7 +87,7 @@ config MMU_SUN3 · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | config KEXEC |
| 89 | 89 | bool "kexec system call" |
| 90 | − depends on M68KCLASSIC | |
| 90 | + depends on M68KCLASSIC && MMU | |
| 91 | 91 | select KEXEC_CORE |
| 92 | 92 | help |
| 93 | 93 | kexec is a system call that implements the ability to shutdown your |
| @@ -84,7 +84,6 @@ CONFIG_NETFILTER=y · 83 unmodified lines | ||
| 84 | 84 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 85 | 85 | CONFIG_NF_CONNTRACK=m |
| 86 | 86 | CONFIG_NF_CONNTRACK_ZONES=y |
| 87 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 88 | 87 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 89 | 88 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 90 | 89 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -573,9 +572,9 @@ CONFIG_CRYPTO_PCBC=m · 482 unmodified lines | ||
| 573 | 572 | CONFIG_CRYPTO_XTS=m |
| 574 | 573 | CONFIG_CRYPTO_KEYWRAP=m |
| 575 | 574 | CONFIG_CRYPTO_ADIANTUM=m |
| 575 | +CONFIG_CRYPTO_HCTR2=m | |
| 576 | 576 | CONFIG_CRYPTO_XCBC=m |
| 577 | 577 | CONFIG_CRYPTO_VMAC=m |
| 578 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 579 | 578 | CONFIG_CRYPTO_MD4=m |
| 580 | 579 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 581 | 580 | CONFIG_CRYPTO_RMD160=m |
| @@ -594,6 +593,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 594 | 593 | CONFIG_CRYPTO_FCRYPT=m |
| 595 | 594 | CONFIG_CRYPTO_KHAZAD=m |
| 596 | 595 | CONFIG_CRYPTO_SEED=m |
| 596 | +CONFIG_CRYPTO_ARIA=m | |
| 597 | 597 | CONFIG_CRYPTO_SERPENT=m |
| 598 | 598 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 599 | 599 | CONFIG_CRYPTO_TEA=m |
| @@ -80,7 +80,6 @@ CONFIG_NETFILTER=y · 79 unmodified lines | ||
| 80 | 80 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 81 | 81 | CONFIG_NF_CONNTRACK=m |
| 82 | 82 | CONFIG_NF_CONNTRACK_ZONES=y |
| 83 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 84 | 83 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 85 | 84 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 86 | 85 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -530,9 +529,9 @@ CONFIG_CRYPTO_PCBC=m · 443 unmodified lines | ||
| 530 | 529 | CONFIG_CRYPTO_XTS=m |
| 531 | 530 | CONFIG_CRYPTO_KEYWRAP=m |
| 532 | 531 | CONFIG_CRYPTO_ADIANTUM=m |
| 532 | +CONFIG_CRYPTO_HCTR2=m | |
| 533 | 533 | CONFIG_CRYPTO_XCBC=m |
| 534 | 534 | CONFIG_CRYPTO_VMAC=m |
| 535 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 536 | 535 | CONFIG_CRYPTO_MD4=m |
| 537 | 536 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 538 | 537 | CONFIG_CRYPTO_RMD160=m |
| @@ -551,6 +550,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 551 | 550 | CONFIG_CRYPTO_FCRYPT=m |
| 552 | 551 | CONFIG_CRYPTO_KHAZAD=m |
| 553 | 552 | CONFIG_CRYPTO_SEED=m |
| 553 | +CONFIG_CRYPTO_ARIA=m | |
| 554 | 554 | CONFIG_CRYPTO_SERPENT=m |
| 555 | 555 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 556 | 556 | CONFIG_CRYPTO_TEA=m |
| @@ -87,7 +87,6 @@ CONFIG_NETFILTER=y · 86 unmodified lines | ||
| 87 | 87 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 88 | 88 | CONFIG_NF_CONNTRACK=m |
| 89 | 89 | CONFIG_NF_CONNTRACK_ZONES=y |
| 90 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 91 | 90 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 92 | 91 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 93 | 92 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -550,9 +549,9 @@ CONFIG_CRYPTO_PCBC=m · 456 unmodified lines | ||
| 550 | 549 | CONFIG_CRYPTO_XTS=m |
| 551 | 550 | CONFIG_CRYPTO_KEYWRAP=m |
| 552 | 551 | CONFIG_CRYPTO_ADIANTUM=m |
| 552 | +CONFIG_CRYPTO_HCTR2=m | |
| 553 | 553 | CONFIG_CRYPTO_XCBC=m |
| 554 | 554 | CONFIG_CRYPTO_VMAC=m |
| 555 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 556 | 555 | CONFIG_CRYPTO_MD4=m |
| 557 | 556 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 558 | 557 | CONFIG_CRYPTO_RMD160=m |
| @@ -571,6 +570,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 571 | 570 | CONFIG_CRYPTO_FCRYPT=m |
| 572 | 571 | CONFIG_CRYPTO_KHAZAD=m |
| 573 | 572 | CONFIG_CRYPTO_SEED=m |
| 573 | +CONFIG_CRYPTO_ARIA=m | |
| 574 | 574 | CONFIG_CRYPTO_SERPENT=m |
| 575 | 575 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 576 | 576 | CONFIG_CRYPTO_TEA=m |
| @@ -77,7 +77,6 @@ CONFIG_NETFILTER=y · 76 unmodified lines | ||
| 77 | 77 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 78 | 78 | CONFIG_NF_CONNTRACK=m |
| 79 | 79 | CONFIG_NF_CONNTRACK_ZONES=y |
| 80 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 81 | 80 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 82 | 81 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 83 | 82 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -522,9 +521,9 @@ CONFIG_CRYPTO_PCBC=m · 438 unmodified lines | ||
| 522 | 521 | CONFIG_CRYPTO_XTS=m |
| 523 | 522 | CONFIG_CRYPTO_KEYWRAP=m |
| 524 | 523 | CONFIG_CRYPTO_ADIANTUM=m |
| 524 | +CONFIG_CRYPTO_HCTR2=m | |
| 525 | 525 | CONFIG_CRYPTO_XCBC=m |
| 526 | 526 | CONFIG_CRYPTO_VMAC=m |
| 527 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 528 | 527 | CONFIG_CRYPTO_MD4=m |
| 529 | 528 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 530 | 529 | CONFIG_CRYPTO_RMD160=m |
| @@ -543,6 +542,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 543 | 542 | CONFIG_CRYPTO_FCRYPT=m |
| 544 | 543 | CONFIG_CRYPTO_KHAZAD=m |
| 545 | 544 | CONFIG_CRYPTO_SEED=m |
| 545 | +CONFIG_CRYPTO_ARIA=m | |
| 546 | 546 | CONFIG_CRYPTO_SERPENT=m |
| 547 | 547 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 548 | 548 | CONFIG_CRYPTO_TEA=m |
| @@ -79,7 +79,6 @@ CONFIG_NETFILTER=y · 78 unmodified lines | ||
| 79 | 79 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 80 | 80 | CONFIG_NF_CONNTRACK=m |
| 81 | 81 | CONFIG_NF_CONNTRACK_ZONES=y |
| 82 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 83 | 82 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 84 | 83 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 85 | 84 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -532,9 +531,9 @@ CONFIG_CRYPTO_PCBC=m · 446 unmodified lines | ||
| 532 | 531 | CONFIG_CRYPTO_XTS=m |
| 533 | 532 | CONFIG_CRYPTO_KEYWRAP=m |
| 534 | 533 | CONFIG_CRYPTO_ADIANTUM=m |
| 534 | +CONFIG_CRYPTO_HCTR2=m | |
| 535 | 535 | CONFIG_CRYPTO_XCBC=m |
| 536 | 536 | CONFIG_CRYPTO_VMAC=m |
| 537 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 538 | 537 | CONFIG_CRYPTO_MD4=m |
| 539 | 538 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 540 | 539 | CONFIG_CRYPTO_RMD160=m |
| @@ -553,6 +552,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 553 | 552 | CONFIG_CRYPTO_FCRYPT=m |
| 554 | 553 | CONFIG_CRYPTO_KHAZAD=m |
| 555 | 554 | CONFIG_CRYPTO_SEED=m |
| 555 | +CONFIG_CRYPTO_ARIA=m | |
| 556 | 556 | CONFIG_CRYPTO_SERPENT=m |
| 557 | 557 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 558 | 558 | CONFIG_CRYPTO_TEA=m |
| @@ -78,7 +78,6 @@ CONFIG_NETFILTER=y · 77 unmodified lines | ||
| 78 | 78 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 79 | 79 | CONFIG_NF_CONNTRACK=m |
| 80 | 80 | CONFIG_NF_CONNTRACK_ZONES=y |
| 81 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 82 | 81 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 83 | 82 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 84 | 83 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -552,9 +551,9 @@ CONFIG_CRYPTO_PCBC=m · 467 unmodified lines | ||
| 552 | 551 | CONFIG_CRYPTO_XTS=m |
| 553 | 552 | CONFIG_CRYPTO_KEYWRAP=m |
| 554 | 553 | CONFIG_CRYPTO_ADIANTUM=m |
| 554 | +CONFIG_CRYPTO_HCTR2=m | |
| 555 | 555 | CONFIG_CRYPTO_XCBC=m |
| 556 | 556 | CONFIG_CRYPTO_VMAC=m |
| 557 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 558 | 557 | CONFIG_CRYPTO_MD4=m |
| 559 | 558 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 560 | 559 | CONFIG_CRYPTO_RMD160=m |
| @@ -573,6 +572,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 573 | 572 | CONFIG_CRYPTO_FCRYPT=m |
| 574 | 573 | CONFIG_CRYPTO_KHAZAD=m |
| 575 | 574 | CONFIG_CRYPTO_SEED=m |
| 575 | +CONFIG_CRYPTO_ARIA=m | |
| 576 | 576 | CONFIG_CRYPTO_SERPENT=m |
| 577 | 577 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 578 | 578 | CONFIG_CRYPTO_TEA=m |
| @@ -98,7 +98,6 @@ CONFIG_NETFILTER=y · 97 unmodified lines | ||
| 98 | 98 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 99 | 99 | CONFIG_NF_CONNTRACK=m |
| 100 | 100 | CONFIG_NF_CONNTRACK_ZONES=y |
| 101 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 102 | 101 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 103 | 102 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 104 | 103 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -638,9 +637,9 @@ CONFIG_CRYPTO_PCBC=m · 533 unmodified lines | ||
| 638 | 637 | CONFIG_CRYPTO_XTS=m |
| 639 | 638 | CONFIG_CRYPTO_KEYWRAP=m |
| 640 | 639 | CONFIG_CRYPTO_ADIANTUM=m |
| 640 | +CONFIG_CRYPTO_HCTR2=m | |
| 641 | 641 | CONFIG_CRYPTO_XCBC=m |
| 642 | 642 | CONFIG_CRYPTO_VMAC=m |
| 643 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 644 | 643 | CONFIG_CRYPTO_MD4=m |
| 645 | 644 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 646 | 645 | CONFIG_CRYPTO_RMD160=m |
| @@ -659,6 +658,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 659 | 658 | CONFIG_CRYPTO_FCRYPT=m |
| 660 | 659 | CONFIG_CRYPTO_KHAZAD=m |
| 661 | 660 | CONFIG_CRYPTO_SEED=m |
| 661 | +CONFIG_CRYPTO_ARIA=m | |
| 662 | 662 | CONFIG_CRYPTO_SERPENT=m |
| 663 | 663 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 664 | 664 | CONFIG_CRYPTO_TEA=m |
| @@ -76,7 +76,6 @@ CONFIG_NETFILTER=y · 75 unmodified lines | ||
| 76 | 76 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 77 | 77 | CONFIG_NF_CONNTRACK=m |
| 78 | 78 | CONFIG_NF_CONNTRACK_ZONES=y |
| 79 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 80 | 79 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 81 | 80 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 82 | 81 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -521,9 +520,9 @@ CONFIG_CRYPTO_PCBC=m · 438 unmodified lines | ||
| 521 | 520 | CONFIG_CRYPTO_XTS=m |
| 522 | 521 | CONFIG_CRYPTO_KEYWRAP=m |
| 523 | 522 | CONFIG_CRYPTO_ADIANTUM=m |
| 523 | +CONFIG_CRYPTO_HCTR2=m | |
| 524 | 524 | CONFIG_CRYPTO_XCBC=m |
| 525 | 525 | CONFIG_CRYPTO_VMAC=m |
| 526 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 527 | 526 | CONFIG_CRYPTO_MD4=m |
| 528 | 527 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 529 | 528 | CONFIG_CRYPTO_RMD160=m |
| @@ -542,6 +541,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 542 | 541 | CONFIG_CRYPTO_FCRYPT=m |
| 543 | 542 | CONFIG_CRYPTO_KHAZAD=m |
| 544 | 543 | CONFIG_CRYPTO_SEED=m |
| 544 | +CONFIG_CRYPTO_ARIA=m | |
| 545 | 545 | CONFIG_CRYPTO_SERPENT=m |
| 546 | 546 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 547 | 547 | CONFIG_CRYPTO_TEA=m |
| @@ -77,7 +77,6 @@ CONFIG_NETFILTER=y · 76 unmodified lines | ||
| 77 | 77 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 78 | 78 | CONFIG_NF_CONNTRACK=m |
| 79 | 79 | CONFIG_NF_CONNTRACK_ZONES=y |
| 80 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 81 | 80 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 82 | 81 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 83 | 82 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -522,9 +521,9 @@ CONFIG_CRYPTO_PCBC=m · 438 unmodified lines | ||
| 522 | 521 | CONFIG_CRYPTO_XTS=m |
| 523 | 522 | CONFIG_CRYPTO_KEYWRAP=m |
| 524 | 523 | CONFIG_CRYPTO_ADIANTUM=m |
| 524 | +CONFIG_CRYPTO_HCTR2=m | |
| 525 | 525 | CONFIG_CRYPTO_XCBC=m |
| 526 | 526 | CONFIG_CRYPTO_VMAC=m |
| 527 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 528 | 527 | CONFIG_CRYPTO_MD4=m |
| 529 | 528 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 530 | 529 | CONFIG_CRYPTO_RMD160=m |
| @@ -543,6 +542,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 543 | 542 | CONFIG_CRYPTO_FCRYPT=m |
| 544 | 543 | CONFIG_CRYPTO_KHAZAD=m |
| 545 | 544 | CONFIG_CRYPTO_SEED=m |
| 545 | +CONFIG_CRYPTO_ARIA=m | |
| 546 | 546 | CONFIG_CRYPTO_SERPENT=m |
| 547 | 547 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 548 | 548 | CONFIG_CRYPTO_TEA=m |
| @@ -78,7 +78,6 @@ CONFIG_NETFILTER=y · 77 unmodified lines | ||
| 78 | 78 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 79 | 79 | CONFIG_NF_CONNTRACK=m |
| 80 | 80 | CONFIG_NF_CONNTRACK_ZONES=y |
| 81 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 82 | 81 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 83 | 82 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 84 | 83 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -539,9 +538,9 @@ CONFIG_CRYPTO_PCBC=m · 454 unmodified lines | ||
| 539 | 538 | CONFIG_CRYPTO_XTS=m |
| 540 | 539 | CONFIG_CRYPTO_KEYWRAP=m |
| 541 | 540 | CONFIG_CRYPTO_ADIANTUM=m |
| 541 | +CONFIG_CRYPTO_HCTR2=m | |
| 542 | 542 | CONFIG_CRYPTO_XCBC=m |
| 543 | 543 | CONFIG_CRYPTO_VMAC=m |
| 544 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 545 | 544 | CONFIG_CRYPTO_MD4=m |
| 546 | 545 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 547 | 546 | CONFIG_CRYPTO_RMD160=m |
| @@ -560,6 +559,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 560 | 559 | CONFIG_CRYPTO_FCRYPT=m |
| 561 | 560 | CONFIG_CRYPTO_KHAZAD=m |
| 562 | 561 | CONFIG_CRYPTO_SEED=m |
| 562 | +CONFIG_CRYPTO_ARIA=m | |
| 563 | 563 | CONFIG_CRYPTO_SERPENT=m |
| 564 | 564 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 565 | 565 | CONFIG_CRYPTO_TEA=m |
| @@ -74,7 +74,6 @@ CONFIG_NETFILTER=y · 73 unmodified lines | ||
| 74 | 74 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 75 | 75 | CONFIG_NF_CONNTRACK=m |
| 76 | 76 | CONFIG_NF_CONNTRACK_ZONES=y |
| 77 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 78 | 77 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 79 | 78 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 80 | 79 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -521,9 +520,9 @@ CONFIG_CRYPTO_PCBC=m · 440 unmodified lines | ||
| 521 | 520 | CONFIG_CRYPTO_XTS=m |
| 522 | 521 | CONFIG_CRYPTO_KEYWRAP=m |
| 523 | 522 | CONFIG_CRYPTO_ADIANTUM=m |
| 523 | +CONFIG_CRYPTO_HCTR2=m | |
| 524 | 524 | CONFIG_CRYPTO_XCBC=m |
| 525 | 525 | CONFIG_CRYPTO_VMAC=m |
| 526 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 527 | 526 | CONFIG_CRYPTO_MD4=m |
| 528 | 527 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 529 | 528 | CONFIG_CRYPTO_RMD160=m |
| @@ -542,6 +541,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 542 | 541 | CONFIG_CRYPTO_FCRYPT=m |
| 543 | 542 | CONFIG_CRYPTO_KHAZAD=m |
| 544 | 543 | CONFIG_CRYPTO_SEED=m |
| 544 | +CONFIG_CRYPTO_ARIA=m | |
| 545 | 545 | CONFIG_CRYPTO_SERPENT=m |
| 546 | 546 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 547 | 547 | CONFIG_CRYPTO_TEA=m |
| @@ -74,7 +74,6 @@ CONFIG_NETFILTER=y · 73 unmodified lines | ||
| 74 | 74 | CONFIG_NETFILTER_NETLINK_HOOK=m |
| 75 | 75 | CONFIG_NF_CONNTRACK=m |
| 76 | 76 | CONFIG_NF_CONNTRACK_ZONES=y |
| 77 | −# CONFIG_NF_CONNTRACK_PROCFS is not set | |
| 78 | 77 | # CONFIG_NF_CT_PROTO_DCCP is not set |
| 79 | 78 | CONFIG_NF_CONNTRACK_AMANDA=m |
| 80 | 79 | CONFIG_NF_CONNTRACK_FTP=m |
| @@ -520,9 +519,9 @@ CONFIG_CRYPTO_PCBC=m · 439 unmodified lines | ||
| 520 | 519 | CONFIG_CRYPTO_XTS=m |
| 521 | 520 | CONFIG_CRYPTO_KEYWRAP=m |
| 522 | 521 | CONFIG_CRYPTO_ADIANTUM=m |
| 522 | +CONFIG_CRYPTO_HCTR2=m | |
| 523 | 523 | CONFIG_CRYPTO_XCBC=m |
| 524 | 524 | CONFIG_CRYPTO_VMAC=m |
| 525 | −CONFIG_CRYPTO_BLAKE2S=m | |
| 526 | 525 | CONFIG_CRYPTO_MD4=m |
| 527 | 526 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 528 | 527 | CONFIG_CRYPTO_RMD160=m |
| @@ -541,6 +540,7 @@ CONFIG_CRYPTO_DES=m · 12 unmodified lines | ||
| 541 | 540 | CONFIG_CRYPTO_FCRYPT=m |
| 542 | 541 | CONFIG_CRYPTO_KHAZAD=m |
| 543 | 542 | CONFIG_CRYPTO_SEED=m |
| 543 | +CONFIG_CRYPTO_ARIA=m | |
| 544 | 544 | CONFIG_CRYPTO_SERPENT=m |
| 545 | 545 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 546 | 546 | CONFIG_CRYPTO_TEA=m |
| @@ -13,13 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | #define BI_VIRT_VIRTIO_BASE 0x8004 |
| 14 | 14 | #define BI_VIRT_CTRL_BASE 0x8005 |
| 15 | 15 | |
| 16 | −/* | |
| 17 | − * A random seed used to initialize the RNG. Record format: | |
| 18 | − * | |
| 19 | − * - length [ 2 bytes, 16-bit big endian ] | |
| 20 | − * - seed data [ `length` bytes, padded to preserve 2-byte alignment ] | |
| 21 | − */ | |
| 22 | −#define BI_VIRT_RNG_SEED 0x8006 | |
| 16 | +/* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index: | |
| 17 | + * #define BI_VIRT_RNG_SEED 0x8006 */ | |
| 23 | 18 | |
| 24 | 19 | #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0) |
| 25 | 20 | |
| @@ -64,6 +64,13 @@ struct mem_info { · 63 unmodified lines | ||
| 64 | 64 | /* (struct mem_info) */ |
| 65 | 65 | #define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ |
| 66 | 66 | /* (string) */ |
| 67 | +/* | |
| 68 | + * A random seed used to initialize the RNG. Record format: | |
| 69 | + * | |
| 70 | + * - length [ 2 bytes, 16-bit big endian ] | |
| 71 | + * - seed data [ `length` bytes, padded to preserve 4-byte struct alignment ] | |
| 72 | + */ | |
| 73 | +#define BI_RNG_SEED 0x0008 | |
| 67 | 74 | |
| 68 | 75 | |
| 69 | 76 | /* |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/module.h> |
| 26 | 26 | #include <linux/nvram.h> |
| 27 | 27 | #include <linux/initrd.h> |
| 28 | +#include <linux/random.h> | |
| 28 | 29 | |
| 29 | 30 | #include <asm/bootinfo.h> |
| 30 | 31 | #include <asm/byteorder.h> |
| @@ -109,10 +110,9 @@ extern void paging_init(void); · 78 unmodified lines | ||
| 109 | 110 | |
| 110 | 111 | static void __init m68k_parse_bootinfo(const struct bi_record *record) |
| 111 | 112 | { |
| 113 | + const struct bi_record *first_record = record; | |
| 112 | 114 | uint16_t tag; |
| 113 | 115 | |
| 114 | − save_bootinfo(record); | |
| 115 | − | |
| 116 | 116 | while ((tag = be16_to_cpu(record->tag)) != BI_LAST) { |
| 117 | 117 | int unknown = 0; |
| 118 | 118 | const void *data = record->data; |
| @@ -148,10 +148,21 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) · 29 unmodified lines | ||
| 148 | 148 | break; |
| 149 | 149 | |
| 150 | 150 | case BI_COMMAND_LINE: |
| 151 | − strlcpy(m68k_command_line, data, | |
| 151 | + strscpy(m68k_command_line, data, | |
| 152 | 152 | sizeof(m68k_command_line)); |
| 153 | 153 | break; |
| 154 | 154 | |
| 155 | + case BI_RNG_SEED: { | |
| 156 | + u16 len = be16_to_cpup(data); | |
| 157 | + add_bootloader_randomness(data + 2, len); | |
| 158 | + /* | |
| 159 | + * Zero the data to preserve forward secrecy, and zero the | |
| 160 | + * length to prevent kexec from using it. | |
| 161 | + */ | |
| 162 | + memzero_explicit((void *)data, len + 2); | |
| 163 | + break; | |
| 164 | + } | |
| 165 | + | |
| 155 | 166 | default: |
| 156 | 167 | if (MACH_IS_AMIGA) |
| 157 | 168 | unknown = amiga_parse_bootinfo(record); |
| @@ -182,6 +193,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) · 24 unmodified lines | ||
| 182 | 193 | record = (struct bi_record *)((unsigned long)record + size); |
| 183 | 194 | } |
| 184 | 195 | |
| 196 | + save_bootinfo(first_record); | |
| 197 | + | |
| 185 | 198 | m68k_realnum_memory = m68k_num_memory; |
| 186 | 199 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK |
| 187 | 200 | if (m68k_num_memory > 1) { |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | #include <linux/reboot.h> |
| 4 | 4 | #include <linux/serial_core.h> |
| 5 | −#include <linux/random.h> | |
| 6 | 5 | #include <clocksource/timer-goldfish.h> |
| 7 | 6 | |
| 8 | 7 | #include <asm/bootinfo.h> |
| @@ -93,16 +92,6 @@ int __init virt_parse_bootinfo(const struct bi_record *record) · 84 unmodified lines | ||
| 93 | 92 | data += 4; |
| 94 | 93 | virt_bi_data.virtio.irq = be32_to_cpup(data); |
| 95 | 94 | break; |
| 96 | − case BI_VIRT_RNG_SEED: { | |
| 97 | − u16 len = be16_to_cpup(data); | |
| 98 | − add_bootloader_randomness(data + 2, len); | |
| 99 | − /* | |
| 100 | − * Zero the data to preserve forward secrecy, and zero the | |
| 101 | − * length to prevent kexec from using it. | |
| 102 | − */ | |
| 103 | − memzero_explicit((void *)data, len + 2); | |
| 104 | − break; | |
| 105 | − } | |
| 106 | 95 | default: |
| 107 | 96 | unknown = 1; |
| 108 | 97 | break; |
| @@ -86,7 +86,7 @@ static __init void prom_init_mem(void) · 85 unmodified lines | ||
| 86 | 86 | pr_debug("Assume 128MB RAM\n"); |
| 87 | 87 | break; |
| 88 | 88 | } |
| 89 | − if (!memcmp(prom_init, prom_init + mem, 32)) | |
| 89 | + if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32)) | |
| 90 | 90 | break; |
| 91 | 91 | } |
| 92 | 92 | lowmem = mem; |
| @@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void) · 66 unmodified lines | ||
| 159 | 159 | |
| 160 | 160 | off = EXTVBASE + __pa(off); |
| 161 | 161 | for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { |
| 162 | − if (!memcmp(prom_init, (void *)(off + extmem), 16)) | |
| 162 | + if (!memcmp((void *)prom_init, (void *)(off + extmem), 16)) | |
| 163 | 163 | break; |
| 164 | 164 | } |
| 165 | 165 | extmem -= lowmem; |
| @@ -105,14 +105,20 @@ · 104 unmodified lines | ||
| 105 | 105 | interrupts = <2>, <3>; |
| 106 | 106 | }; |
| 107 | 107 | |
| 108 | − wdt: watchdog@1000009c { | |
| 109 | − compatible = "brcm,bcm7038-wdt"; | |
| 110 | − reg = <0x1000009c 0xc>; | |
| 108 | + timer-mfd@10000080 { | |
| 109 | + compatible = "brcm,bcm7038-twd", "simple-mfd", "syscon"; | |
| 110 | + reg = <0x10000080 0x30>; | |
| 111 | + ranges = <0x0 0x10000080 0x30>; | |
| 111 | 112 | |
| 112 | − clocks = <&periph_osc>; | |
| 113 | − clock-names = "refclk"; | |
| 113 | + wdt: watchdog@1c { | |
| 114 | + compatible = "brcm,bcm7038-wdt"; | |
| 115 | + reg = <0x1c 0xc>; | |
| 114 | 116 | |
| 115 | − timeout-sec = <30>; | |
| 117 | + clocks = <&periph_osc>; | |
| 118 | + clock-names = "refclk"; | |
| 119 | + | |
| 120 | + timeout-sec = <30>; | |
| 121 | + }; | |
| 116 | 122 | }; |
| 117 | 123 | |
| 118 | 124 | uart0: serial@10000180 { |
| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb | |
| 2 | +dtb-$(CONFIG_DT_EASY50712) += danube_easy50712.dtb | |
| 3 | 3 | |
| 4 | 4 | obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y)) |
File renamed without changes.
| @@ -28,7 +28,7 @@ struct latency_info { · 27 unmodified lines | ||
| 28 | 28 | static struct latency_info li; |
| 29 | 29 | static struct dentry *dir; |
| 30 | 30 | |
| 31 | −static int show_latency(struct seq_file *m, void *v) | |
| 31 | +static int oct_ilm_show(struct seq_file *m, void *v) | |
| 32 | 32 | { |
| 33 | 33 | u64 cpuclk, avg, max, min; |
| 34 | 34 | struct latency_info curr_li = li; |
| @@ -43,18 +43,7 @@ static int show_latency(struct seq_file *m, void *v) · 8 unmodified lines | ||
| 43 | 43 | curr_li.interrupt_cnt, avg, max, min); |
| 44 | 44 | return 0; |
| 45 | 45 | } |
| 46 | − | |
| 47 | −static int oct_ilm_open(struct inode *inode, struct file *file) | |
| 48 | −{ | |
| 49 | − return single_open(file, show_latency, NULL); | |
| 50 | −} | |
| 51 | − | |
| 52 | −static const struct file_operations oct_ilm_ops = { | |
| 53 | − .open = oct_ilm_open, | |
| 54 | − .read = seq_read, | |
| 55 | − .llseek = seq_lseek, | |
| 56 | − .release = single_release, | |
| 57 | −}; | |
| 46 | +DEFINE_SHOW_ATTRIBUTE(oct_ilm); | |
| 58 | 47 | |
| 59 | 48 | static int reset_statistics(void *data, u64 value) |
| 60 | 49 | { |
| @@ -67,7 +56,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(reset_statistics_ops, NULL, reset_statistics, "%llu\n") · 6 unmodified lines | ||
| 67 | 56 | static void init_debugfs(void) |
| 68 | 57 | { |
| 69 | 58 | dir = debugfs_create_dir("oct_ilm", 0); |
| 70 | − debugfs_create_file("statistics", 0222, dir, NULL, &oct_ilm_ops); | |
| 59 | + debugfs_create_file("statistics", 0222, dir, NULL, &oct_ilm_fops); | |
| 71 | 60 | debugfs_create_file("reset", 0222, dir, NULL, &reset_statistics_ops); |
| 72 | 61 | } |
| 73 | 62 | |
| @@ -530,7 +530,7 @@ void octeon_user_io_init(void) · 529 unmodified lines | ||
| 530 | 530 | /* Get the current settings for CP0_CVMMEMCTL_REG */ |
| 531 | 531 | cvmmemctl.u64 = read_c0_cvmmemctl(); |
| 532 | 532 | /* R/W If set, marked write-buffer entries time out the same |
| 533 | − * as as other entries; if clear, marked write-buffer entries | |
| 533 | + * as other entries; if clear, marked write-buffer entries | |
| 534 | 534 | * use the maximum timeout. */ |
| 535 | 535 | cvmmemctl.s.dismarkwblongto = 1; |
| 536 | 536 | /* R/W If set, a merged store does not clear the write-buffer |
| @@ -32,9 +32,6 @@ CONFIG_IP_ROUTE_MULTIPATH=y · 31 unmodified lines | ||
| 32 | 32 | CONFIG_IP_ROUTE_VERBOSE=y |
| 33 | 33 | CONFIG_IP_MROUTE=y |
| 34 | 34 | CONFIG_SYN_COOKIES=y |
| 35 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 36 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 37 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 38 | 35 | # CONFIG_INET_DIAG is not set |
| 39 | 36 | CONFIG_TCP_CONG_ADVANCED=y |
| 40 | 37 | # CONFIG_TCP_CONG_BIC is not set |
| @@ -117,7 +114,6 @@ CONFIG_JFFS2_SUMMARY=y · 76 unmodified lines | ||
| 117 | 114 | CONFIG_JFFS2_COMPRESSION_OPTIONS=y |
| 118 | 115 | CONFIG_SQUASHFS=y |
| 119 | 116 | # CONFIG_CRYPTO_HW is not set |
| 120 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 121 | 117 | CONFIG_STRIP_ASM_SYMS=y |
| 122 | 118 | CONFIG_DEBUG_FS=y |
| 123 | 119 | CONFIG_CMDLINE_BOOL=y |
| @@ -29,9 +29,6 @@ CONFIG_UNIX=y · 28 unmodified lines | ||
| 29 | 29 | CONFIG_INET=y |
| 30 | 30 | CONFIG_IP_MULTICAST=y |
| 31 | 31 | CONFIG_IP_ADVANCED_ROUTER=y |
| 32 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 33 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 34 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 35 | 32 | # CONFIG_IPV6 is not set |
| 36 | 33 | CONFIG_CFG80211=m |
| 37 | 34 | CONFIG_MAC80211=m |
| @@ -108,7 +105,6 @@ CONFIG_SQUASHFS_XZ=y · 70 unmodified lines | ||
| 108 | 105 | # CONFIG_XZ_DEC_ARMTHUMB is not set |
| 109 | 106 | # CONFIG_XZ_DEC_SPARC is not set |
| 110 | 107 | CONFIG_PRINTK_TIME=y |
| 111 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 112 | 108 | CONFIG_STRIP_ASM_SYMS=y |
| 113 | 109 | CONFIG_DEBUG_FS=y |
| 114 | 110 | # CONFIG_SCHED_DEBUG is not set |
| @@ -10,12 +10,6 @@ CONFIG_EMBEDDED=y · 9 unmodified lines | ||
| 10 | 10 | # CONFIG_SLUB_DEBUG is not set |
| 11 | 11 | # CONFIG_COMPAT_BRK is not set |
| 12 | 12 | CONFIG_ATH79=y |
| 13 | −CONFIG_ATH79_MACH_AP121=y | |
| 14 | −CONFIG_ATH79_MACH_AP136=y | |
| 15 | −CONFIG_ATH79_MACH_AP81=y | |
| 16 | −CONFIG_ATH79_MACH_DB120=y | |
| 17 | −CONFIG_ATH79_MACH_PB44=y | |
| 18 | −CONFIG_ATH79_MACH_UBNT_XM=y | |
| 19 | 13 | CONFIG_HZ_100=y |
| 20 | 14 | # CONFIG_SECCOMP is not set |
| 21 | 15 | CONFIG_PCI=y |
| @@ -29,9 +23,6 @@ CONFIG_UNIX=y · 7 unmodified lines | ||
| 29 | 23 | CONFIG_INET=y |
| 30 | 24 | CONFIG_IP_MULTICAST=y |
| 31 | 25 | CONFIG_IP_ADVANCED_ROUTER=y |
| 32 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 33 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 34 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 35 | 26 | # CONFIG_IPV6 is not set |
| 36 | 27 | CONFIG_CFG80211=m |
| 37 | 28 | CONFIG_MAC80211=m |
| @@ -92,7 +83,6 @@ CONFIG_LEDS_GPIO=y · 54 unmodified lines | ||
| 92 | 83 | # CONFIG_DNOTIFY is not set |
| 93 | 84 | # CONFIG_PROC_PAGE_MONITOR is not set |
| 94 | 85 | CONFIG_CRC_ITU_T=m |
| 95 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 96 | 86 | CONFIG_STRIP_ASM_SYMS=y |
| 97 | 87 | CONFIG_DEBUG_FS=y |
| 98 | 88 | # CONFIG_SCHED_DEBUG is not set |
| @@ -24,9 +24,6 @@ CONFIG_PCMCIA_BCM63XX=y · 23 unmodified lines | ||
| 24 | 24 | CONFIG_NET=y |
| 25 | 25 | CONFIG_UNIX=y |
| 26 | 26 | CONFIG_INET=y |
| 27 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 28 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 29 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 30 | 27 | # CONFIG_INET_DIAG is not set |
| 31 | 28 | # CONFIG_IPV6 is not set |
| 32 | 29 | CONFIG_CFG80211=y |
| @@ -49,8 +49,6 @@ CONFIG_IP_PIMSM_V2=y · 48 unmodified lines | ||
| 49 | 49 | CONFIG_INET_AH=m |
| 50 | 50 | CONFIG_INET_ESP=m |
| 51 | 51 | CONFIG_INET_IPCOMP=m |
| 52 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 53 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 54 | 52 | CONFIG_TCP_MD5SIG=y |
| 55 | 53 | CONFIG_IPV6_ROUTER_PREF=y |
| 56 | 54 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -59,7 +57,6 @@ CONFIG_INET6_AH=m · 2 unmodified lines | ||
| 59 | 57 | CONFIG_INET6_ESP=m |
| 60 | 58 | CONFIG_INET6_IPCOMP=m |
| 61 | 59 | CONFIG_IPV6_MIP6=m |
| 62 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 63 | 60 | CONFIG_IPV6_SIT_6RD=y |
| 64 | 61 | CONFIG_IPV6_TUNNEL=m |
| 65 | 62 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| @@ -101,7 +98,6 @@ CONFIG_BAYCOM_SER_HDX=m · 35 unmodified lines | ||
| 101 | 98 | CONFIG_YAM=m |
| 102 | 99 | CONFIG_FW_LOADER=m |
| 103 | 100 | CONFIG_BLK_DEV_LOOP=m |
| 104 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 105 | 101 | CONFIG_BLK_DEV_NBD=m |
| 106 | 102 | CONFIG_EEPROM_LEGACY=y |
| 107 | 103 | CONFIG_EEPROM_MAX6875=y |
| @@ -230,12 +226,8 @@ CONFIG_CRYPTO_XCBC=m · 122 unmodified lines | ||
| 230 | 226 | CONFIG_CRYPTO_VMAC=m |
| 231 | 227 | CONFIG_CRYPTO_MD4=m |
| 232 | 228 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 233 | −CONFIG_CRYPTO_RMD128=m | |
| 234 | 229 | CONFIG_CRYPTO_RMD160=m |
| 235 | −CONFIG_CRYPTO_RMD256=m | |
| 236 | −CONFIG_CRYPTO_RMD320=m | |
| 237 | 230 | CONFIG_CRYPTO_SHA512=m |
| 238 | −CONFIG_CRYPTO_TGR192=m | |
| 239 | 231 | CONFIG_CRYPTO_WP512=m |
| 240 | 232 | CONFIG_CRYPTO_ANUBIS=m |
| 241 | 233 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -243,7 +235,6 @@ CONFIG_CRYPTO_CAMELLIA=m · 1 unmodified line | ||
| 243 | 235 | CONFIG_CRYPTO_CAST6=m |
| 244 | 236 | CONFIG_CRYPTO_FCRYPT=m |
| 245 | 237 | CONFIG_CRYPTO_KHAZAD=m |
| 246 | −CONFIG_CRYPTO_SALSA20=m | |
| 247 | 238 | CONFIG_CRYPTO_SEED=m |
| 248 | 239 | CONFIG_CRYPTO_SERPENT=m |
| 249 | 240 | CONFIG_CRYPTO_TEA=m |
| @@ -17,9 +17,6 @@ CONFIG_PACKET=y · 16 unmodified lines | ||
| 17 | 17 | CONFIG_PACKET_DIAG=y |
| 18 | 18 | CONFIG_UNIX=y |
| 19 | 19 | CONFIG_INET=y |
| 20 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 21 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 22 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 23 | 20 | # CONFIG_INET_DIAG is not set |
| 24 | 21 | CONFIG_CFG80211=y |
| 25 | 22 | CONFIG_NL80211_TESTMODE=y |
| @@ -12,7 +12,6 @@ CONFIG_HIGHMEM=y · 11 unmodified lines | ||
| 12 | 12 | CONFIG_HIGH_RES_TIMERS=y |
| 13 | 13 | CONFIG_SMP=y |
| 14 | 14 | CONFIG_NR_CPUS=4 |
| 15 | −CONFIG_CC_STACKPROTECTOR_STRONG=y | |
| 16 | 15 | # CONFIG_SECCOMP is not set |
| 17 | 16 | CONFIG_MIPS_O32_FP64_SUPPORT=y |
| 18 | 17 | # CONFIG_RD_GZIP is not set |
| @@ -21,8 +20,6 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y · 2 unmodified lines | ||
| 21 | 20 | CONFIG_RD_XZ=y |
| 22 | 21 | # CONFIG_RD_LZO is not set |
| 23 | 22 | # CONFIG_RD_LZ4 is not set |
| 24 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 25 | −# CONFIG_IOSCHED_CFQ is not set | |
| 26 | 23 | CONFIG_PCI=y |
| 27 | 24 | CONFIG_PCI_MSI=y |
| 28 | 25 | CONFIG_PCIEASPM_POWERSAVE=y |
| @@ -30,7 +27,6 @@ CONFIG_PCIEPORTBUS=y · 1 unmodified line | ||
| 30 | 27 | CONFIG_PCIE_BRCMSTB=y |
| 31 | 28 | CONFIG_CPU_FREQ=y |
| 32 | 29 | CONFIG_CPU_FREQ_STAT=y |
| 33 | −CONFIG_CPU_FREQ_STAT_DETAILS=y | |
| 34 | 30 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y |
| 35 | 31 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y |
| 36 | 32 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y |
| @@ -44,15 +40,11 @@ CONFIG_PACKET=y · 7 unmodified lines | ||
| 44 | 40 | CONFIG_PACKET_DIAG=y |
| 45 | 41 | CONFIG_UNIX=y |
| 46 | 42 | CONFIG_INET=y |
| 47 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 48 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 49 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 50 | 43 | # CONFIG_INET_DIAG is not set |
| 51 | 44 | CONFIG_CFG80211=y |
| 52 | 45 | CONFIG_NL80211_TESTMODE=y |
| 53 | 46 | CONFIG_WIRELESS=y |
| 54 | 47 | CONFIG_MAC80211=y |
| 55 | −CONFIG_NL80211=y | |
| 56 | 48 | CONFIG_DEVTMPFS=y |
| 57 | 49 | CONFIG_DEVTMPFS_MOUNT=y |
| 58 | 50 | # CONFIG_STANDALONE is not set |
| @@ -70,10 +62,6 @@ CONFIG_IP_PNP_RARP=y · 11 unmodified lines | ||
| 70 | 62 | CONFIG_IP_MROUTE=y |
| 71 | 63 | CONFIG_IP_PIMSM_V1=y |
| 72 | 64 | CONFIG_IP_PIMSM_V2=y |
| 73 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 74 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 75 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 76 | −# CONFIG_INET_LRO is not set | |
| 77 | 65 | CONFIG_INET_UDP_DIAG=y |
| 78 | 66 | CONFIG_TCP_CONG_ADVANCED=y |
| 79 | 67 | CONFIG_TCP_CONG_BIC=y |
| @@ -93,7 +81,6 @@ CONFIG_NET_SWITCHDEV=y · 13 unmodified lines | ||
| 93 | 81 | CONFIG_DMA_CMA=y |
| 94 | 82 | CONFIG_CMA_ALIGNMENT=12 |
| 95 | 83 | CONFIG_SPI=y |
| 96 | −CONFIG_SPI_BRCMSTB=y | |
| 97 | 84 | CONFIG_MTD=y |
| 98 | 85 | CONFIG_MTD_CMDLINE_PARTS=y |
| 99 | 86 | CONFIG_MTD_BLOCK=y |
| @@ -105,14 +92,11 @@ CONFIG_MTD_CFI_STAA=y · 5 unmodified lines | ||
| 105 | 92 | CONFIG_MTD_ROM=y |
| 106 | 93 | CONFIG_MTD_ABSENT=y |
| 107 | 94 | CONFIG_MTD_PHYSMAP_OF=y |
| 108 | −CONFIG_MTD_M25P80=y | |
| 109 | −CONFIG_MTD_NAND=y | |
| 110 | 95 | CONFIG_MTD_NAND_BRCMNAND=y |
| 111 | 96 | CONFIG_MTD_SPI_NOR=y |
| 112 | 97 | # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set |
| 113 | 98 | CONFIG_MTD_UBI=y |
| 114 | 99 | CONFIG_MTD_UBI_GLUEBI=y |
| 115 | −CONFIG_PROC_DEVICETREE=y | |
| 116 | 100 | CONFIG_BLK_DEV_LOOP=y |
| 117 | 101 | CONFIG_BLK_DEV_RAM=y |
| 118 | 102 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
| @@ -120,7 +104,6 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 · 1 unmodified line | ||
| 120 | 104 | CONFIG_SCSI=y |
| 121 | 105 | CONFIG_BLK_DEV_SD=y |
| 122 | 106 | CONFIG_CHR_DEV_SG=y |
| 123 | −CONFIG_SCSI_MULTI_LUN=y | |
| 124 | 107 | # CONFIG_SCSI_LOWLEVEL is not set |
| 125 | 108 | CONFIG_NETDEVICES=y |
| 126 | 109 | CONFIG_VLAN_8021Q=y |
| @@ -135,7 +118,6 @@ CONFIG_INPUT_UINPUT=y · 8 unmodified lines | ||
| 135 | 118 | # CONFIG_SERIO is not set |
| 136 | 119 | CONFIG_VT=y |
| 137 | 120 | CONFIG_VT_HW_CONSOLE_BINDING=y |
| 138 | −# CONFIG_DEVKMEM is not set | |
| 139 | 121 | CONFIG_SERIAL_8250=y |
| 140 | 122 | # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set |
| 141 | 123 | CONFIG_SERIAL_8250_CONSOLE=y |
| @@ -203,17 +185,14 @@ CONFIG_CMDLINE="earlycon" · 61 unmodified lines | ||
| 203 | 185 | CONFIG_MIPS_CMDLINE_DTB_EXTEND=y |
| 204 | 186 | # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set |
| 205 | 187 | # CONFIG_CRYPTO_HW is not set |
| 206 | −CONFIG_DT_BCM974XX=y | |
| 207 | 188 | CONFIG_FW_CFE=y |
| 208 | 189 | CONFIG_ATA=y |
| 209 | 190 | CONFIG_SATA_AHCI_PLATFORM=y |
| 210 | −CONFIG_AHCI_BRCMSTB=y | |
| 211 | 191 | CONFIG_GENERIC_PHY=y |
| 212 | 192 | CONFIG_GPIOLIB=y |
| 213 | 193 | CONFIG_GPIO_SYSFS=y |
| 214 | 194 | CONFIG_PHY_BRCM_USB=y |
| 215 | 195 | CONFIG_PHY_BRCM_SATA=y |
| 216 | −CONFIG_PM_RUNTIME=y | |
| 217 | 196 | CONFIG_PM_DEBUG=y |
| 218 | 197 | CONFIG_SYSVIPC=y |
| 219 | 198 | CONFIG_FUNCTION_GRAPH_TRACER=y |
| @@ -227,3 +206,5 @@ CONFIG_FTRACE_SYSCALLS=y · 7 unmodified lines | ||
| 227 | 206 | CONFIG_TRACER_SNAPSHOT=y |
| 228 | 207 | CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y |
| 229 | 208 | CONFIG_STACK_TRACER=y |
| 209 | +CONFIG_AHCI_BRCM=y | |
| 210 | +CONFIG_MTD_RAW_NAND=y | |
| @@ -71,7 +71,6 @@ CONFIG_NETDEVICES=y · 70 unmodified lines | ||
| 71 | 71 | # CONFIG_NET_VENDOR_DEC is not set |
| 72 | 72 | # CONFIG_NET_VENDOR_DLINK is not set |
| 73 | 73 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 74 | −# CONFIG_NET_VENDOR_HP is not set | |
| 75 | 74 | # CONFIG_NET_VENDOR_INTEL is not set |
| 76 | 75 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 77 | 76 | # CONFIG_NET_VENDOR_MELLANOX is not set |
| @@ -61,7 +61,6 @@ CONFIG_INET6_AH=y · 60 unmodified lines | ||
| 61 | 61 | CONFIG_INET6_ESP=y |
| 62 | 62 | CONFIG_INET6_IPCOMP=y |
| 63 | 63 | CONFIG_IPV6_MIP6=y |
| 64 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y | |
| 65 | 64 | CONFIG_IPV6_VTI=y |
| 66 | 65 | CONFIG_IPV6_SIT_6RD=y |
| 67 | 66 | CONFIG_IPV6_GRE=y |
| @@ -37,9 +37,6 @@ CONFIG_SYN_COOKIES=y · 36 unmodified lines | ||
| 37 | 37 | CONFIG_INET_AH=m |
| 38 | 38 | CONFIG_INET_ESP=m |
| 39 | 39 | CONFIG_INET_IPCOMP=m |
| 40 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 41 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 42 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 43 | 40 | CONFIG_TCP_MD5SIG=y |
| 44 | 41 | CONFIG_IPV6_ROUTER_PREF=y |
| 45 | 42 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -47,7 +44,6 @@ CONFIG_INET6_AH=m · 1 unmodified line | ||
| 47 | 44 | CONFIG_INET6_ESP=m |
| 48 | 45 | CONFIG_INET6_IPCOMP=m |
| 49 | 46 | CONFIG_IPV6_MIP6=m |
| 50 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 51 | 47 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 52 | 48 | CONFIG_IPV6_SUBTREES=y |
| 53 | 49 | CONFIG_NETWORK_SECMARK=y |
| @@ -77,7 +73,6 @@ CONFIG_NETDEVICES=y · 23 unmodified lines | ||
| 77 | 73 | CONFIG_DECLANCE=y |
| 78 | 74 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 79 | 75 | # CONFIG_NET_VENDOR_ARC is not set |
| 80 | −# CONFIG_NET_VENDOR_AURORA is not set | |
| 81 | 76 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 82 | 77 | # CONFIG_NET_VENDOR_CADENCE is not set |
| 83 | 78 | # CONFIG_NET_VENDOR_CAVIUM is not set |
| @@ -191,12 +186,8 @@ CONFIG_CRYPTO_CRC32=m · 107 unmodified lines | ||
| 191 | 186 | CONFIG_CRYPTO_CRCT10DIF=m |
| 192 | 187 | CONFIG_CRYPTO_MD4=m |
| 193 | 188 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 194 | −CONFIG_CRYPTO_RMD128=m | |
| 195 | 189 | CONFIG_CRYPTO_RMD160=m |
| 196 | −CONFIG_CRYPTO_RMD256=m | |
| 197 | −CONFIG_CRYPTO_RMD320=m | |
| 198 | 190 | CONFIG_CRYPTO_SHA512=m |
| 199 | −CONFIG_CRYPTO_TGR192=m | |
| 200 | 191 | CONFIG_CRYPTO_WP512=m |
| 201 | 192 | CONFIG_CRYPTO_ANUBIS=m |
| 202 | 193 | CONFIG_CRYPTO_ARC4=m |
| @@ -206,7 +197,6 @@ CONFIG_CRYPTO_CAST5=m · 3 unmodified lines | ||
| 206 | 197 | CONFIG_CRYPTO_CAST6=m |
| 207 | 198 | CONFIG_CRYPTO_FCRYPT=m |
| 208 | 199 | CONFIG_CRYPTO_KHAZAD=m |
| 209 | −CONFIG_CRYPTO_SALSA20=m | |
| 210 | 200 | CONFIG_CRYPTO_SEED=m |
| 211 | 201 | CONFIG_CRYPTO_SERPENT=m |
| 212 | 202 | CONFIG_CRYPTO_TEA=m |
| @@ -33,9 +33,6 @@ CONFIG_SYN_COOKIES=y · 32 unmodified lines | ||
| 33 | 33 | CONFIG_INET_AH=m |
| 34 | 34 | CONFIG_INET_ESP=m |
| 35 | 35 | CONFIG_INET_IPCOMP=m |
| 36 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 37 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 38 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 39 | 36 | CONFIG_TCP_MD5SIG=y |
| 40 | 37 | CONFIG_IPV6_ROUTER_PREF=y |
| 41 | 38 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -43,7 +40,6 @@ CONFIG_INET6_AH=m · 1 unmodified line | ||
| 43 | 40 | CONFIG_INET6_ESP=m |
| 44 | 41 | CONFIG_INET6_IPCOMP=m |
| 45 | 42 | CONFIG_IPV6_MIP6=m |
| 46 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 47 | 43 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 48 | 44 | CONFIG_IPV6_SUBTREES=y |
| 49 | 45 | CONFIG_NETWORK_SECMARK=y |
| @@ -73,7 +69,6 @@ CONFIG_NETDEVICES=y · 23 unmodified lines | ||
| 73 | 69 | CONFIG_DECLANCE=y |
| 74 | 70 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 75 | 71 | # CONFIG_NET_VENDOR_ARC is not set |
| 76 | −# CONFIG_NET_VENDOR_AURORA is not set | |
| 77 | 72 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 78 | 73 | # CONFIG_NET_VENDOR_CADENCE is not set |
| 79 | 74 | # CONFIG_NET_VENDOR_CAVIUM is not set |
| @@ -186,12 +181,8 @@ CONFIG_CRYPTO_CRC32=m · 106 unmodified lines | ||
| 186 | 181 | CONFIG_CRYPTO_CRCT10DIF=m |
| 187 | 182 | CONFIG_CRYPTO_MD4=m |
| 188 | 183 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 189 | −CONFIG_CRYPTO_RMD128=m | |
| 190 | 184 | CONFIG_CRYPTO_RMD160=m |
| 191 | −CONFIG_CRYPTO_RMD256=m | |
| 192 | −CONFIG_CRYPTO_RMD320=m | |
| 193 | 185 | CONFIG_CRYPTO_SHA512=m |
| 194 | −CONFIG_CRYPTO_TGR192=m | |
| 195 | 186 | CONFIG_CRYPTO_WP512=m |
| 196 | 187 | CONFIG_CRYPTO_ANUBIS=m |
| 197 | 188 | CONFIG_CRYPTO_ARC4=m |
| @@ -201,7 +192,6 @@ CONFIG_CRYPTO_CAST5=m · 3 unmodified lines | ||
| 201 | 192 | CONFIG_CRYPTO_CAST6=m |
| 202 | 193 | CONFIG_CRYPTO_FCRYPT=m |
| 203 | 194 | CONFIG_CRYPTO_KHAZAD=m |
| 204 | −CONFIG_CRYPTO_SALSA20=m | |
| 205 | 195 | CONFIG_CRYPTO_SEED=m |
| 206 | 196 | CONFIG_CRYPTO_SERPENT=m |
| 207 | 197 | CONFIG_CRYPTO_TEA=m |
| @@ -32,9 +32,6 @@ CONFIG_SYN_COOKIES=y · 31 unmodified lines | ||
| 32 | 32 | CONFIG_INET_AH=m |
| 33 | 33 | CONFIG_INET_ESP=m |
| 34 | 34 | CONFIG_INET_IPCOMP=m |
| 35 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 36 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 37 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 38 | 35 | CONFIG_TCP_MD5SIG=y |
| 39 | 36 | CONFIG_IPV6_ROUTER_PREF=y |
| 40 | 37 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -42,7 +39,6 @@ CONFIG_INET6_AH=m · 1 unmodified line | ||
| 42 | 39 | CONFIG_INET6_ESP=m |
| 43 | 40 | CONFIG_INET6_IPCOMP=m |
| 44 | 41 | CONFIG_IPV6_MIP6=m |
| 45 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 46 | 42 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 47 | 43 | CONFIG_IPV6_SUBTREES=y |
| 48 | 44 | CONFIG_NETWORK_SECMARK=y |
| @@ -72,7 +68,6 @@ CONFIG_NETDEVICES=y · 23 unmodified lines | ||
| 72 | 68 | CONFIG_DECLANCE=y |
| 73 | 69 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 74 | 70 | # CONFIG_NET_VENDOR_ARC is not set |
| 75 | −# CONFIG_NET_VENDOR_AURORA is not set | |
| 76 | 71 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 77 | 72 | # CONFIG_NET_VENDOR_CADENCE is not set |
| 78 | 73 | # CONFIG_NET_VENDOR_CAVIUM is not set |
| @@ -186,12 +181,8 @@ CONFIG_CRYPTO_CRC32=m · 107 unmodified lines | ||
| 186 | 181 | CONFIG_CRYPTO_CRCT10DIF=m |
| 187 | 182 | CONFIG_CRYPTO_MD4=m |
| 188 | 183 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 189 | −CONFIG_CRYPTO_RMD128=m | |
| 190 | 184 | CONFIG_CRYPTO_RMD160=m |
| 191 | −CONFIG_CRYPTO_RMD256=m | |
| 192 | −CONFIG_CRYPTO_RMD320=m | |
| 193 | 185 | CONFIG_CRYPTO_SHA512=m |
| 194 | −CONFIG_CRYPTO_TGR192=m | |
| 195 | 186 | CONFIG_CRYPTO_WP512=m |
| 196 | 187 | CONFIG_CRYPTO_ANUBIS=m |
| 197 | 188 | CONFIG_CRYPTO_ARC4=m |
| @@ -201,7 +192,6 @@ CONFIG_CRYPTO_CAST5=m · 3 unmodified lines | ||
| 201 | 192 | CONFIG_CRYPTO_CAST6=m |
| 202 | 193 | CONFIG_CRYPTO_FCRYPT=m |
| 203 | 194 | CONFIG_CRYPTO_KHAZAD=m |
| 204 | −CONFIG_CRYPTO_SALSA20=m | |
| 205 | 195 | CONFIG_CRYPTO_SEED=m |
| 206 | 196 | CONFIG_CRYPTO_SERPENT=m |
| 207 | 197 | CONFIG_CRYPTO_TEA=m |
| @@ -35,8 +35,6 @@ CONFIG_IP_MULTICAST=y · 34 unmodified lines | ||
| 35 | 35 | CONFIG_IP_PNP=y |
| 36 | 36 | CONFIG_IP_PNP_BOOTP=y |
| 37 | 37 | CONFIG_NET_IPIP=m |
| 38 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 39 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 40 | 38 | # CONFIG_INET_DIAG is not set |
| 41 | 39 | # CONFIG_IPV6 is not set |
| 42 | 40 | CONFIG_NETFILTER=y |
| @@ -92,7 +90,6 @@ CONFIG_MTD_CFI_AMDSTD=m · 49 unmodified lines | ||
| 92 | 90 | CONFIG_MTD_CFI_STAA=m |
| 93 | 91 | CONFIG_MTD_PHYSMAP=m |
| 94 | 92 | CONFIG_BLK_DEV_LOOP=y |
| 95 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 96 | 93 | CONFIG_BLK_DEV_RAM=m |
| 97 | 94 | CONFIG_CDROM_PKTCDVD=m |
| 98 | 95 | CONFIG_ATA_OVER_ETH=m |
| @@ -159,7 +156,6 @@ CONFIG_USB_MOUSE=y · 60 unmodified lines | ||
| 159 | 156 | CONFIG_USB=y |
| 160 | 157 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y |
| 161 | 158 | CONFIG_USB_OTG_PRODUCTLIST=y |
| 162 | −CONFIG_USB_WUSB_CBAF=m | |
| 163 | 159 | CONFIG_USB_C67X00_HCD=m |
| 164 | 160 | CONFIG_USB_EHCI_HCD=y |
| 165 | 161 | CONFIG_USB_EHCI_ROOT_HUB_TT=y |
| @@ -219,15 +215,10 @@ CONFIG_CRYPTO_CTS=m · 53 unmodified lines | ||
| 219 | 215 | CONFIG_CRYPTO_PCBC=m |
| 220 | 216 | CONFIG_CRYPTO_XTS=m |
| 221 | 217 | CONFIG_CRYPTO_HMAC=y |
| 222 | −CONFIG_CRYPTO_RMD128=m | |
| 223 | 218 | CONFIG_CRYPTO_RMD160=m |
| 224 | −CONFIG_CRYPTO_RMD256=m | |
| 225 | −CONFIG_CRYPTO_RMD320=m | |
| 226 | −CONFIG_CRYPTO_SALSA20=m | |
| 227 | 219 | CONFIG_CRYPTO_SEED=m |
| 228 | 220 | CONFIG_CRYPTO_DEFLATE=m |
| 229 | 221 | CONFIG_CRYPTO_LZO=m |
| 230 | 222 | # CONFIG_CRYPTO_HW is not set |
| 231 | 223 | CONFIG_CRC_CCITT=y |
| 232 | 224 | CONFIG_CRC7=m |
| 233 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| @@ -25,7 +25,6 @@ CONFIG_NETDEVICES=y · 24 unmodified lines | ||
| 25 | 25 | CONFIG_NET_SWITCHDEV=y |
| 26 | 26 | CONFIG_NET_DSA=y |
| 27 | 27 | CONFIG_MSCC_OCELOT_SWITCH=y |
| 28 | −CONFIG_MSCC_OCELOT_SWITCH_OCELOT=y | |
| 29 | 28 | CONFIG_MDIO_MSCC_MIIM=y |
| 30 | 29 | CONFIG_MICROSEMI_PHY=y |
| 31 | 30 | |
| @@ -29,9 +29,6 @@ CONFIG_IP_ROUTE_VERBOSE=y · 28 unmodified lines | ||
| 29 | 29 | CONFIG_IP_PNP=y |
| 30 | 30 | CONFIG_IP_PNP_BOOTP=y |
| 31 | 31 | CONFIG_SYN_COOKIES=y |
| 32 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 33 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 34 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 35 | 32 | # CONFIG_IPV6 is not set |
| 36 | 33 | CONFIG_NETWORK_SECMARK=y |
| 37 | 34 | CONFIG_NETFILTER=y |
| @@ -218,9 +215,6 @@ CONFIG_HDLC_X25=m · 180 unmodified lines | ||
| 218 | 215 | CONFIG_PCI200SYN=m |
| 219 | 216 | CONFIG_WANXL=m |
| 220 | 217 | CONFIG_FARSYNC=m |
| 221 | −CONFIG_DSCC4=m | |
| 222 | −CONFIG_DSCC4_PCISYNC=y | |
| 223 | −CONFIG_DSCC4_PCI_RST=y | |
| 224 | 218 | CONFIG_LAPBETHER=m |
| 225 | 219 | # CONFIG_INPUT_KEYBOARD is not set |
| 226 | 220 | # CONFIG_INPUT_MOUSE is not set |
| @@ -286,7 +280,6 @@ CONFIG_CRYPTO_PCBC=m · 59 unmodified lines | ||
| 286 | 280 | CONFIG_CRYPTO_MD4=m |
| 287 | 281 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 288 | 282 | CONFIG_CRYPTO_SHA512=m |
| 289 | −CONFIG_CRYPTO_TGR192=m | |
| 290 | 283 | CONFIG_CRYPTO_WP512=m |
| 291 | 284 | CONFIG_CRYPTO_ANUBIS=m |
| 292 | 285 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -297,7 +290,6 @@ CONFIG_CRYPTO_SERPENT=m · 4 unmodified lines | ||
| 297 | 290 | CONFIG_CRYPTO_TEA=m |
| 298 | 291 | CONFIG_CRYPTO_TWOFISH=m |
| 299 | 292 | CONFIG_CRYPTO_DEFLATE=m |
| 300 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 301 | 293 | CONFIG_MAGIC_SYSRQ=y |
| 302 | 294 | CONFIG_CMDLINE_BOOL=y |
| 303 | 295 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw ip=auto" |
| @@ -36,9 +36,6 @@ CONFIG_IP_PNP_BOOTP=y · 35 unmodified lines | ||
| 36 | 36 | CONFIG_INET_AH=m |
| 37 | 37 | CONFIG_INET_ESP=m |
| 38 | 38 | CONFIG_INET_IPCOMP=m |
| 39 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 40 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 41 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 42 | 39 | CONFIG_TCP_MD5SIG=y |
| 43 | 40 | CONFIG_IPV6_ROUTER_PREF=y |
| 44 | 41 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -47,7 +44,6 @@ CONFIG_INET6_AH=m · 2 unmodified lines | ||
| 47 | 44 | CONFIG_INET6_ESP=m |
| 48 | 45 | CONFIG_INET6_IPCOMP=m |
| 49 | 46 | CONFIG_IPV6_MIP6=m |
| 50 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 51 | 47 | CONFIG_IPV6_TUNNEL=m |
| 52 | 48 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 53 | 49 | CONFIG_IPV6_SUBTREES=y |
| @@ -226,7 +222,6 @@ CONFIG_SERIO_RAW=m · 172 unmodified lines | ||
| 226 | 222 | CONFIG_VT_HW_CONSOLE_BINDING=y |
| 227 | 223 | CONFIG_SERIAL_IP22_ZILOG=m |
| 228 | 224 | # CONFIG_HW_RANDOM is not set |
| 229 | −CONFIG_RAW_DRIVER=m | |
| 230 | 225 | # CONFIG_HWMON is not set |
| 231 | 226 | CONFIG_THERMAL=y |
| 232 | 227 | CONFIG_WATCHDOG=y |
| @@ -320,11 +315,7 @@ CONFIG_CRYPTO_PCBC=m · 87 unmodified lines | ||
| 320 | 315 | CONFIG_CRYPTO_XTS=m |
| 321 | 316 | CONFIG_CRYPTO_HMAC=y |
| 322 | 317 | CONFIG_CRYPTO_XCBC=m |
| 323 | −CONFIG_CRYPTO_RMD128=m | |
| 324 | 318 | CONFIG_CRYPTO_RMD160=m |
| 325 | −CONFIG_CRYPTO_RMD256=m | |
| 326 | −CONFIG_CRYPTO_RMD320=m | |
| 327 | −CONFIG_CRYPTO_TGR192=m | |
| 328 | 319 | CONFIG_CRYPTO_WP512=m |
| 329 | 320 | CONFIG_CRYPTO_ANUBIS=m |
| 330 | 321 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -333,7 +324,6 @@ CONFIG_CRYPTO_CAST5=m · 2 unmodified lines | ||
| 333 | 324 | CONFIG_CRYPTO_CAST6=m |
| 334 | 325 | CONFIG_CRYPTO_FCRYPT=m |
| 335 | 326 | CONFIG_CRYPTO_KHAZAD=m |
| 336 | −CONFIG_CRYPTO_SALSA20=m | |
| 337 | 327 | CONFIG_CRYPTO_SEED=m |
| 338 | 328 | CONFIG_CRYPTO_SERPENT=m |
| 339 | 329 | CONFIG_CRYPTO_TEA=m |
| @@ -33,9 +33,6 @@ CONFIG_NET_KEY_MIGRATE=y · 32 unmodified lines | ||
| 33 | 33 | CONFIG_INET=y |
| 34 | 34 | CONFIG_IP_MULTICAST=y |
| 35 | 35 | CONFIG_IP_PNP=y |
| 36 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 37 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 38 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 39 | 36 | CONFIG_TCP_MD5SIG=y |
| 40 | 37 | CONFIG_IPV6_ROUTER_PREF=y |
| 41 | 38 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -44,10 +41,6 @@ CONFIG_INET6_AH=m · 2 unmodified lines | ||
| 44 | 41 | CONFIG_INET6_ESP=m |
| 45 | 42 | CONFIG_INET6_IPCOMP=m |
| 46 | 43 | CONFIG_IPV6_MIP6=m |
| 47 | −CONFIG_INET6_XFRM_MODE_TRANSPORT=m | |
| 48 | −CONFIG_INET6_XFRM_MODE_TUNNEL=m | |
| 49 | −CONFIG_INET6_XFRM_MODE_BEET=m | |
| 50 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 51 | 44 | CONFIG_IPV6_SIT=m |
| 52 | 45 | CONFIG_IPV6_SIT_6RD=y |
| 53 | 46 | CONFIG_IPV6_TUNNEL=m |
| @@ -92,7 +85,6 @@ CONFIG_CFG80211=m · 38 unmodified lines | ||
| 92 | 85 | CONFIG_MAC80211=m |
| 93 | 86 | CONFIG_RFKILL=m |
| 94 | 87 | CONFIG_BLK_DEV_LOOP=y |
| 95 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 96 | 88 | CONFIG_CDROM_PKTCDVD=m |
| 97 | 89 | CONFIG_ATA_OVER_ETH=m |
| 98 | 90 | CONFIG_SCSI=y |
| @@ -115,7 +107,6 @@ CONFIG_SCSI_AIC94XX=m · 16 unmodified lines | ||
| 115 | 107 | # CONFIG_AIC94XX_DEBUG is not set |
| 116 | 108 | CONFIG_SCSI_MVSAS=m |
| 117 | 109 | # CONFIG_SCSI_MVSAS_DEBUG is not set |
| 118 | −CONFIG_SCSI_DPT_I2O=m | |
| 119 | 110 | CONFIG_SCSI_MPT2SAS=m |
| 120 | 111 | CONFIG_LIBFC=m |
| 121 | 112 | CONFIG_SCSI_QLOGIC_1280=y |
| @@ -126,8 +117,6 @@ CONFIG_SCSI_DH_RDAC=m · 4 unmodified lines | ||
| 126 | 117 | CONFIG_SCSI_DH_HP_SW=m |
| 127 | 118 | CONFIG_SCSI_DH_EMC=m |
| 128 | 119 | CONFIG_SCSI_DH_ALUA=m |
| 129 | −CONFIG_SCSI_OSD_INITIATOR=m | |
| 130 | −CONFIG_SCSI_OSD_ULD=m | |
| 131 | 120 | CONFIG_MD=y |
| 132 | 121 | CONFIG_BLK_DEV_MD=y |
| 133 | 122 | CONFIG_MD_LINEAR=m |
| @@ -166,7 +155,6 @@ CONFIG_JME=m · 32 unmodified lines | ||
| 166 | 155 | CONFIG_MLX4_EN=m |
| 167 | 156 | # CONFIG_MLX4_DEBUG is not set |
| 168 | 157 | CONFIG_KS8851_MLL=m |
| 169 | −CONFIG_VXGE=m | |
| 170 | 158 | CONFIG_AX88796=m |
| 171 | 159 | CONFIG_AX88796_93CX6=y |
| 172 | 160 | CONFIG_ETHOC=m |
| @@ -264,7 +252,6 @@ CONFIG_I2C_VIAPRO=m · 91 unmodified lines | ||
| 264 | 252 | CONFIG_I2C_OCORES=m |
| 265 | 253 | CONFIG_I2C_PCA_PLATFORM=m |
| 266 | 254 | CONFIG_I2C_SIMTEC=m |
| 267 | −CONFIG_I2C_PARPORT_LIGHT=m | |
| 268 | 255 | CONFIG_I2C_TAOS_EVM=m |
| 269 | 256 | CONFIG_I2C_STUB=m |
| 270 | 257 | # CONFIG_HWMON is not set |
| @@ -309,7 +296,6 @@ CONFIG_TMPFS=y · 38 unmodified lines | ||
| 309 | 296 | CONFIG_TMPFS_POSIX_ACL=y |
| 310 | 297 | CONFIG_SQUASHFS=m |
| 311 | 298 | CONFIG_OMFS_FS=m |
| 312 | −CONFIG_EXOFS_FS=m | |
| 313 | 299 | CONFIG_NFS_FS=y |
| 314 | 300 | CONFIG_SECURITYFS=y |
| 315 | 301 | CONFIG_CRYPTO_CRYPTD=m |
| @@ -321,12 +307,8 @@ CONFIG_CRYPTO_HMAC=y · 5 unmodified lines | ||
| 321 | 307 | CONFIG_CRYPTO_XCBC=m |
| 322 | 308 | CONFIG_CRYPTO_VMAC=m |
| 323 | 309 | CONFIG_CRYPTO_MD4=m |
| 324 | −CONFIG_CRYPTO_RMD128=m | |
| 325 | 310 | CONFIG_CRYPTO_RMD160=m |
| 326 | −CONFIG_CRYPTO_RMD256=m | |
| 327 | −CONFIG_CRYPTO_RMD320=m | |
| 328 | 311 | CONFIG_CRYPTO_SHA512=m |
| 329 | −CONFIG_CRYPTO_TGR192=m | |
| 330 | 312 | CONFIG_CRYPTO_WP512=m |
| 331 | 313 | CONFIG_CRYPTO_ANUBIS=m |
| 332 | 314 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -335,7 +317,6 @@ CONFIG_CRYPTO_CAST5=m · 2 unmodified lines | ||
| 335 | 317 | CONFIG_CRYPTO_CAST6=m |
| 336 | 318 | CONFIG_CRYPTO_FCRYPT=m |
| 337 | 319 | CONFIG_CRYPTO_KHAZAD=m |
| 338 | −CONFIG_CRYPTO_SALSA20=m | |
| 339 | 320 | CONFIG_CRYPTO_SEED=m |
| 340 | 321 | CONFIG_CRYPTO_SERPENT=m |
| 341 | 322 | CONFIG_CRYPTO_TEA=m |
| @@ -29,9 +29,6 @@ CONFIG_IP_MULTICAST=y · 28 unmodified lines | ||
| 29 | 29 | CONFIG_IP_PNP=y |
| 30 | 30 | CONFIG_IP_PNP_DHCP=y |
| 31 | 31 | CONFIG_IP_PNP_BOOTP=y |
| 32 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 33 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 34 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 35 | 32 | CONFIG_TCP_MD5SIG=y |
| 36 | 33 | # CONFIG_IPV6 is not set |
| 37 | 34 | CONFIG_SCSI=y |
| @@ -43,7 +43,6 @@ CONFIG_IPV6_TUNNEL=m · 42 unmodified lines | ||
| 43 | 43 | CONFIG_NETWORK_SECMARK=y |
| 44 | 44 | CONFIG_CONNECTOR=y |
| 45 | 45 | CONFIG_BLK_DEV_LOOP=m |
| 46 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 47 | 46 | CONFIG_BLK_DEV_NBD=m |
| 48 | 47 | CONFIG_RAID_ATTRS=y |
| 49 | 48 | CONFIG_SCSI=y |
| @@ -165,7 +164,6 @@ CONFIG_CRYPTO_MICHAEL_MIC=y · 115 unmodified lines | ||
| 165 | 164 | CONFIG_CRYPTO_SHA1=y |
| 166 | 165 | CONFIG_CRYPTO_SHA256=y |
| 167 | 166 | CONFIG_CRYPTO_SHA512=y |
| 168 | −CONFIG_CRYPTO_TGR192=y | |
| 169 | 167 | CONFIG_CRYPTO_WP512=y |
| 170 | 168 | CONFIG_CRYPTO_ANUBIS=y |
| 171 | 169 | CONFIG_CRYPTO_ARC4=y |
| @@ -32,7 +32,6 @@ CONFIG_PARPORT_1284=y · 31 unmodified lines | ||
| 32 | 32 | CONFIG_DEVTMPFS=y |
| 33 | 33 | CONFIG_BLK_DEV_FD=m |
| 34 | 34 | CONFIG_BLK_DEV_LOOP=m |
| 35 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 36 | 35 | CONFIG_BLK_DEV_NBD=m |
| 37 | 36 | CONFIG_BLK_DEV_RAM=m |
| 38 | 37 | CONFIG_CDROM_PKTCDVD=m |
| @@ -43,9 +43,6 @@ CONFIG_IP_MROUTE=y · 42 unmodified lines | ||
| 43 | 43 | CONFIG_IP_PIMSM_V1=y |
| 44 | 44 | CONFIG_IP_PIMSM_V2=y |
| 45 | 45 | CONFIG_SYN_COOKIES=y |
| 46 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 47 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 48 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 49 | 46 | CONFIG_TCP_CONG_ADVANCED=y |
| 50 | 47 | CONFIG_TCP_CONG_BIC=y |
| 51 | 48 | CONFIG_DEFAULT_BIC=y |
| @@ -77,7 +74,6 @@ CONFIG_MAC80211_LEDS=y · 25 unmodified lines | ||
| 77 | 74 | CONFIG_RFKILL=m |
| 78 | 75 | CONFIG_RFKILL_INPUT=y |
| 79 | 76 | CONFIG_BLK_DEV_LOOP=y |
| 80 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 81 | 77 | CONFIG_BLK_DEV_RAM=y |
| 82 | 78 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
| 83 | 79 | CONFIG_BLK_DEV_SD=y |
| @@ -312,12 +308,8 @@ CONFIG_CRYPTO_PCBC=m · 228 unmodified lines | ||
| 312 | 308 | CONFIG_CRYPTO_XTS=m |
| 313 | 309 | CONFIG_CRYPTO_XCBC=m |
| 314 | 310 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 315 | −CONFIG_CRYPTO_RMD128=m | |
| 316 | 311 | CONFIG_CRYPTO_RMD160=m |
| 317 | −CONFIG_CRYPTO_RMD256=m | |
| 318 | −CONFIG_CRYPTO_RMD320=m | |
| 319 | 312 | CONFIG_CRYPTO_SHA1=m |
| 320 | −CONFIG_CRYPTO_TGR192=m | |
| 321 | 313 | CONFIG_CRYPTO_WP512=m |
| 322 | 314 | CONFIG_CRYPTO_ANUBIS=m |
| 323 | 315 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -326,7 +318,6 @@ CONFIG_CRYPTO_CAST5=m · 2 unmodified lines | ||
| 326 | 318 | CONFIG_CRYPTO_CAST6=m |
| 327 | 319 | CONFIG_CRYPTO_FCRYPT=m |
| 328 | 320 | CONFIG_CRYPTO_KHAZAD=m |
| 329 | −CONFIG_CRYPTO_SALSA20=m | |
| 330 | 321 | CONFIG_CRYPTO_SEED=m |
| 331 | 322 | CONFIG_CRYPTO_SERPENT=m |
| 332 | 323 | CONFIG_CRYPTO_TEA=m |
| @@ -28,9 +28,6 @@ CONFIG_INET=y · 27 unmodified lines | ||
| 28 | 28 | CONFIG_IP_PNP=y |
| 29 | 29 | CONFIG_IP_PNP_DHCP=y |
| 30 | 30 | CONFIG_SYN_COOKIES=y |
| 31 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 32 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 33 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 34 | 31 | # CONFIG_INET_DIAG is not set |
| 35 | 32 | # CONFIG_IPV6 is not set |
| 36 | 33 | # CONFIG_WIRELESS is not set |
| @@ -115,7 +112,6 @@ CONFIG_NLS_ISO8859_1=m · 78 unmodified lines | ||
| 115 | 112 | # CONFIG_CRYPTO_ECHAINIV is not set |
| 116 | 113 | # CONFIG_CRYPTO_HW is not set |
| 117 | 114 | CONFIG_DYNAMIC_DEBUG=y |
| 118 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 119 | 115 | CONFIG_DEBUG_FS=y |
| 120 | 116 | CONFIG_MAGIC_SYSRQ=y |
| 121 | 117 | # CONFIG_SCHED_DEBUG is not set |
| @@ -29,9 +29,6 @@ CONFIG_INET=y · 28 unmodified lines | ||
| 29 | 29 | CONFIG_IP_PNP=y |
| 30 | 30 | CONFIG_IP_PNP_DHCP=y |
| 31 | 31 | CONFIG_SYN_COOKIES=y |
| 32 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 33 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 34 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 35 | 32 | # CONFIG_INET_DIAG is not set |
| 36 | 33 | # CONFIG_IPV6 is not set |
| 37 | 34 | # CONFIG_WIRELESS is not set |
| @@ -116,7 +113,6 @@ CONFIG_NLS_ISO8859_1=m · 78 unmodified lines | ||
| 116 | 113 | # CONFIG_CRYPTO_ECHAINIV is not set |
| 117 | 114 | # CONFIG_CRYPTO_HW is not set |
| 118 | 115 | CONFIG_DYNAMIC_DEBUG=y |
| 119 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 120 | 116 | CONFIG_DEBUG_FS=y |
| 121 | 117 | CONFIG_MAGIC_SYSRQ=y |
| 122 | 118 | # CONFIG_SCHED_DEBUG is not set |
| @@ -95,7 +95,6 @@ CONFIG_DEVTMPFS=y · 94 unmodified lines | ||
| 95 | 95 | CONFIG_DEVTMPFS_MOUNT=y |
| 96 | 96 | CONFIG_MTD=m |
| 97 | 97 | CONFIG_BLK_DEV_LOOP=y |
| 98 | −CONFIG_BLK_DEV_CRYPTOLOOP=y | |
| 99 | 98 | CONFIG_BLK_DEV_RAM=y |
| 100 | 99 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
| 101 | 100 | CONFIG_RAID_ATTRS=m |
| @@ -229,7 +228,6 @@ CONFIG_SERIAL_8250_RSA=y · 127 unmodified lines | ||
| 229 | 228 | CONFIG_SERIAL_OF_PLATFORM=y |
| 230 | 229 | CONFIG_SERIAL_NONSTANDARD=y |
| 231 | 230 | CONFIG_HW_RANDOM=y |
| 232 | −CONFIG_RAW_DRIVER=m | |
| 233 | 231 | CONFIG_I2C_CHARDEV=y |
| 234 | 232 | CONFIG_I2C_PIIX4=y |
| 235 | 233 | CONFIG_GPIO_LOONGSON=y |
| @@ -336,7 +334,6 @@ CONFIG_DEFAULT_SECURITY_DAC=y · 100 unmodified lines | ||
| 336 | 334 | CONFIG_CRYPTO_SEQIV=m |
| 337 | 335 | CONFIG_CRYPTO_HMAC=y |
| 338 | 336 | CONFIG_CRYPTO_MD5=y |
| 339 | −CONFIG_CRYPTO_TGR192=m | |
| 340 | 337 | CONFIG_CRYPTO_WP512=m |
| 341 | 338 | CONFIG_CRYPTO_BLOWFISH=m |
| 342 | 339 | CONFIG_CRYPTO_CAST5=m |
| @@ -143,7 +143,6 @@ CONFIG_DEVTMPFS=y · 142 unmodified lines | ||
| 143 | 143 | CONFIG_DEVTMPFS_MOUNT=y |
| 144 | 144 | CONFIG_MTD=m |
| 145 | 145 | CONFIG_BLK_DEV_LOOP=y |
| 146 | −CONFIG_BLK_DEV_CRYPTOLOOP=y | |
| 147 | 146 | CONFIG_BLK_DEV_RAM=y |
| 148 | 147 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
| 149 | 148 | CONFIG_VIRTIO_BLK=y |
| @@ -268,7 +267,6 @@ CONFIG_SERIAL_OF_PLATFORM=y · 118 unmodified lines | ||
| 268 | 267 | CONFIG_SERIAL_NONSTANDARD=y |
| 269 | 268 | CONFIG_VIRTIO_CONSOLE=y |
| 270 | 269 | CONFIG_HW_RANDOM=y |
| 271 | −CONFIG_RAW_DRIVER=m | |
| 272 | 270 | CONFIG_I2C_CHARDEV=y |
| 273 | 271 | CONFIG_I2C_PIIX4=y |
| 274 | 272 | CONFIG_GPIO_LOONGSON=y |
| @@ -42,8 +42,6 @@ CONFIG_SYN_COOKIES=y · 41 unmodified lines | ||
| 42 | 42 | CONFIG_INET_AH=m |
| 43 | 43 | CONFIG_INET_ESP=m |
| 44 | 44 | CONFIG_INET_IPCOMP=m |
| 45 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 46 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 47 | 45 | CONFIG_TCP_MD5SIG=y |
| 48 | 46 | CONFIG_IPV6_ROUTER_PREF=y |
| 49 | 47 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -229,7 +227,6 @@ CONFIG_MTD_UBI=m · 179 unmodified lines | ||
| 229 | 227 | CONFIG_MTD_UBI_GLUEBI=m |
| 230 | 228 | CONFIG_BLK_DEV_FD=m |
| 231 | 229 | CONFIG_BLK_DEV_LOOP=m |
| 232 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 233 | 230 | CONFIG_BLK_DEV_NBD=m |
| 234 | 231 | CONFIG_BLK_DEV_RAM=y |
| 235 | 232 | CONFIG_CDROM_PKTCDVD=m |
| @@ -237,7 +234,6 @@ CONFIG_ATA_OVER_ETH=m · 1 unmodified line | ||
| 237 | 234 | CONFIG_RAID_ATTRS=m |
| 238 | 235 | CONFIG_BLK_DEV_SD=y |
| 239 | 236 | CONFIG_CHR_DEV_ST=m |
| 240 | −CONFIG_CHR_DEV_OSST=m | |
| 241 | 237 | CONFIG_BLK_DEV_SR=y |
| 242 | 238 | CONFIG_CHR_DEV_SG=m |
| 243 | 239 | CONFIG_SCSI_CONSTANTS=y |
| @@ -408,7 +404,6 @@ CONFIG_CRYPTO_HMAC=y · 164 unmodified lines | ||
| 408 | 404 | CONFIG_CRYPTO_XCBC=m |
| 409 | 405 | CONFIG_CRYPTO_MD4=m |
| 410 | 406 | CONFIG_CRYPTO_SHA512=m |
| 411 | −CONFIG_CRYPTO_TGR192=m | |
| 412 | 407 | CONFIG_CRYPTO_WP512=m |
| 413 | 408 | CONFIG_CRYPTO_ANUBIS=m |
| 414 | 409 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -46,8 +46,6 @@ CONFIG_SYN_COOKIES=y · 45 unmodified lines | ||
| 46 | 46 | CONFIG_INET_AH=m |
| 47 | 47 | CONFIG_INET_ESP=m |
| 48 | 48 | CONFIG_INET_IPCOMP=m |
| 49 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 50 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 51 | 49 | CONFIG_TCP_MD5SIG=y |
| 52 | 50 | CONFIG_IPV6_ROUTER_PREF=y |
| 53 | 51 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -233,7 +231,6 @@ CONFIG_MTD_UBI=m · 179 unmodified lines | ||
| 233 | 231 | CONFIG_MTD_UBI_GLUEBI=m |
| 234 | 232 | CONFIG_BLK_DEV_FD=m |
| 235 | 233 | CONFIG_BLK_DEV_LOOP=m |
| 236 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 237 | 234 | CONFIG_BLK_DEV_NBD=m |
| 238 | 235 | CONFIG_BLK_DEV_RAM=y |
| 239 | 236 | CONFIG_CDROM_PKTCDVD=m |
| @@ -241,7 +238,6 @@ CONFIG_ATA_OVER_ETH=m · 1 unmodified line | ||
| 241 | 238 | CONFIG_RAID_ATTRS=m |
| 242 | 239 | CONFIG_BLK_DEV_SD=y |
| 243 | 240 | CONFIG_CHR_DEV_ST=m |
| 244 | −CONFIG_CHR_DEV_OSST=m | |
| 245 | 241 | CONFIG_BLK_DEV_SR=y |
| 246 | 242 | CONFIG_CHR_DEV_SG=m |
| 247 | 243 | CONFIG_SCSI_CONSTANTS=y |
| @@ -415,7 +411,6 @@ CONFIG_CRYPTO_HMAC=y · 167 unmodified lines | ||
| 415 | 411 | CONFIG_CRYPTO_XCBC=m |
| 416 | 412 | CONFIG_CRYPTO_MD4=m |
| 417 | 413 | CONFIG_CRYPTO_SHA512=m |
| 418 | −CONFIG_CRYPTO_TGR192=m | |
| 419 | 414 | CONFIG_CRYPTO_WP512=m |
| 420 | 415 | CONFIG_CRYPTO_ANUBIS=m |
| 421 | 416 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -76,7 +76,6 @@ CONFIG_NET_ACT_POLICE=y · 75 unmodified lines | ||
| 76 | 76 | # CONFIG_WIRELESS is not set |
| 77 | 77 | CONFIG_DEVTMPFS=y |
| 78 | 78 | CONFIG_BLK_DEV_LOOP=y |
| 79 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 80 | 79 | CONFIG_BLK_DEV_SD=y |
| 81 | 80 | CONFIG_CHR_DEV_SG=y |
| 82 | 81 | # CONFIG_SCSI_LOWLEVEL is not set |
| @@ -98,7 +97,6 @@ CONFIG_PCNET32=y · 15 unmodified lines | ||
| 98 | 97 | # CONFIG_NET_VENDOR_DEC is not set |
| 99 | 98 | # CONFIG_NET_VENDOR_DLINK is not set |
| 100 | 99 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 101 | −# CONFIG_NET_VENDOR_HP is not set | |
| 102 | 100 | # CONFIG_NET_VENDOR_INTEL is not set |
| 103 | 101 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 104 | 102 | # CONFIG_NET_VENDOR_MELLANOX is not set |
| @@ -172,7 +170,6 @@ CONFIG_NLS_ISO8859_1=m · 67 unmodified lines | ||
| 172 | 170 | CONFIG_CRYPTO_PCBC=m |
| 173 | 171 | CONFIG_CRYPTO_HMAC=y |
| 174 | 172 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 175 | −CONFIG_CRYPTO_TGR192=m | |
| 176 | 173 | CONFIG_CRYPTO_WP512=m |
| 177 | 174 | CONFIG_CRYPTO_ANUBIS=m |
| 178 | 175 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -78,7 +78,6 @@ CONFIG_NET_ACT_POLICE=y · 77 unmodified lines | ||
| 78 | 78 | # CONFIG_WIRELESS is not set |
| 79 | 79 | CONFIG_DEVTMPFS=y |
| 80 | 80 | CONFIG_BLK_DEV_LOOP=y |
| 81 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 82 | 81 | CONFIG_BLK_DEV_SD=y |
| 83 | 82 | CONFIG_CHR_DEV_SG=y |
| 84 | 83 | # CONFIG_SCSI_LOWLEVEL is not set |
| @@ -100,7 +99,6 @@ CONFIG_PCNET32=y · 15 unmodified lines | ||
| 100 | 99 | # CONFIG_NET_VENDOR_DEC is not set |
| 101 | 100 | # CONFIG_NET_VENDOR_DLINK is not set |
| 102 | 101 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 103 | −# CONFIG_NET_VENDOR_HP is not set | |
| 104 | 102 | # CONFIG_NET_VENDOR_INTEL is not set |
| 105 | 103 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 106 | 104 | # CONFIG_NET_VENDOR_MELLANOX is not set |
| @@ -173,7 +171,6 @@ CONFIG_NLS_ISO8859_1=m · 66 unmodified lines | ||
| 173 | 171 | CONFIG_CRYPTO_PCBC=m |
| 174 | 172 | CONFIG_CRYPTO_HMAC=y |
| 175 | 173 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 176 | −CONFIG_CRYPTO_TGR192=m | |
| 177 | 174 | CONFIG_CRYPTO_WP512=m |
| 178 | 175 | CONFIG_CRYPTO_ANUBIS=m |
| 179 | 176 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -79,7 +79,6 @@ CONFIG_NET_ACT_POLICE=y · 78 unmodified lines | ||
| 79 | 79 | # CONFIG_WIRELESS is not set |
| 80 | 80 | CONFIG_DEVTMPFS=y |
| 81 | 81 | CONFIG_BLK_DEV_LOOP=y |
| 82 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 83 | 82 | CONFIG_BLK_DEV_SD=y |
| 84 | 83 | CONFIG_CHR_DEV_SG=y |
| 85 | 84 | # CONFIG_SCSI_LOWLEVEL is not set |
| @@ -99,7 +98,6 @@ CONFIG_PCNET32=y · 13 unmodified lines | ||
| 99 | 98 | # CONFIG_NET_VENDOR_DEC is not set |
| 100 | 99 | # CONFIG_NET_VENDOR_DLINK is not set |
| 101 | 100 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 102 | −# CONFIG_NET_VENDOR_HP is not set | |
| 103 | 101 | # CONFIG_NET_VENDOR_INTEL is not set |
| 104 | 102 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 105 | 103 | # CONFIG_NET_VENDOR_MELLANOX is not set |
| @@ -174,7 +172,6 @@ CONFIG_NLS_ISO8859_1=m · 68 unmodified lines | ||
| 174 | 172 | CONFIG_CRYPTO_PCBC=m |
| 175 | 173 | CONFIG_CRYPTO_HMAC=y |
| 176 | 174 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 177 | −CONFIG_CRYPTO_TGR192=m | |
| 178 | 175 | CONFIG_CRYPTO_WP512=m |
| 179 | 176 | CONFIG_CRYPTO_ANUBIS=m |
| 180 | 177 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -80,7 +80,6 @@ CONFIG_NET_ACT_POLICE=y · 79 unmodified lines | ||
| 80 | 80 | # CONFIG_WIRELESS is not set |
| 81 | 81 | CONFIG_DEVTMPFS=y |
| 82 | 82 | CONFIG_BLK_DEV_LOOP=y |
| 83 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 84 | 83 | CONFIG_BLK_DEV_SD=y |
| 85 | 84 | CONFIG_CHR_DEV_SG=y |
| 86 | 85 | # CONFIG_SCSI_LOWLEVEL is not set |
| @@ -102,7 +101,6 @@ CONFIG_PCNET32=y · 15 unmodified lines | ||
| 102 | 101 | # CONFIG_NET_VENDOR_DEC is not set |
| 103 | 102 | # CONFIG_NET_VENDOR_DLINK is not set |
| 104 | 103 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 105 | −# CONFIG_NET_VENDOR_HP is not set | |
| 106 | 104 | # CONFIG_NET_VENDOR_INTEL is not set |
| 107 | 105 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 108 | 106 | # CONFIG_NET_VENDOR_MELLANOX is not set |
| @@ -176,7 +174,6 @@ CONFIG_NLS_ISO8859_1=m · 67 unmodified lines | ||
| 176 | 174 | CONFIG_CRYPTO_PCBC=m |
| 177 | 175 | CONFIG_CRYPTO_HMAC=y |
| 178 | 176 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 179 | −CONFIG_CRYPTO_TGR192=m | |
| 180 | 177 | CONFIG_CRYPTO_WP512=m |
| 181 | 178 | CONFIG_CRYPTO_ANUBIS=m |
| 182 | 179 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -77,7 +77,6 @@ CONFIG_NET_ACT_POLICE=y · 76 unmodified lines | ||
| 77 | 77 | # CONFIG_WIRELESS is not set |
| 78 | 78 | CONFIG_DEVTMPFS=y |
| 79 | 79 | CONFIG_BLK_DEV_LOOP=y |
| 80 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 81 | 80 | CONFIG_BLK_DEV_SD=y |
| 82 | 81 | CONFIG_CHR_DEV_SG=y |
| 83 | 82 | # CONFIG_SCSI_LOWLEVEL is not set |
| @@ -99,7 +98,6 @@ CONFIG_PCNET32=y · 15 unmodified lines | ||
| 99 | 98 | # CONFIG_NET_VENDOR_DEC is not set |
| 100 | 99 | # CONFIG_NET_VENDOR_DLINK is not set |
| 101 | 100 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 102 | −# CONFIG_NET_VENDOR_HP is not set | |
| 103 | 101 | # CONFIG_NET_VENDOR_INTEL is not set |
| 104 | 102 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 105 | 103 | # CONFIG_NET_VENDOR_MELLANOX is not set |
| @@ -172,7 +170,6 @@ CONFIG_NLS_ISO8859_1=m · 66 unmodified lines | ||
| 172 | 170 | CONFIG_CRYPTO_PCBC=m |
| 173 | 171 | CONFIG_CRYPTO_HMAC=y |
| 174 | 172 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 175 | −CONFIG_CRYPTO_TGR192=m | |
| 176 | 173 | CONFIG_CRYPTO_WP512=m |
| 177 | 174 | CONFIG_CRYPTO_ANUBIS=m |
| 178 | 175 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -45,8 +45,6 @@ CONFIG_SYN_COOKIES=y · 44 unmodified lines | ||
| 45 | 45 | CONFIG_INET_AH=m |
| 46 | 46 | CONFIG_INET_ESP=m |
| 47 | 47 | CONFIG_INET_IPCOMP=m |
| 48 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 49 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 50 | 48 | CONFIG_TCP_MD5SIG=y |
| 51 | 49 | CONFIG_IPV6_ROUTER_PREF=y |
| 52 | 50 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -231,7 +229,6 @@ CONFIG_MTD_UBI=m · 178 unmodified lines | ||
| 231 | 229 | CONFIG_MTD_UBI_GLUEBI=m |
| 232 | 230 | CONFIG_BLK_DEV_FD=m |
| 233 | 231 | CONFIG_BLK_DEV_LOOP=m |
| 234 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 235 | 232 | CONFIG_BLK_DEV_NBD=m |
| 236 | 233 | CONFIG_BLK_DEV_RAM=y |
| 237 | 234 | CONFIG_CDROM_PKTCDVD=m |
| @@ -239,7 +236,6 @@ CONFIG_ATA_OVER_ETH=m · 1 unmodified line | ||
| 239 | 236 | CONFIG_RAID_ATTRS=m |
| 240 | 237 | CONFIG_BLK_DEV_SD=y |
| 241 | 238 | CONFIG_CHR_DEV_ST=m |
| 242 | −CONFIG_CHR_DEV_OSST=m | |
| 243 | 239 | CONFIG_BLK_DEV_SR=y |
| 244 | 240 | CONFIG_CHR_DEV_SG=m |
| 245 | 241 | CONFIG_SCSI_CONSTANTS=y |
| @@ -414,7 +410,6 @@ CONFIG_CRYPTO_HMAC=y · 168 unmodified lines | ||
| 414 | 410 | CONFIG_CRYPTO_XCBC=m |
| 415 | 411 | CONFIG_CRYPTO_MD4=m |
| 416 | 412 | CONFIG_CRYPTO_SHA512=m |
| 417 | −CONFIG_CRYPTO_TGR192=m | |
| 418 | 413 | CONFIG_CRYPTO_WP512=m |
| 419 | 414 | CONFIG_CRYPTO_ANUBIS=m |
| 420 | 415 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -58,13 +58,9 @@ CONFIG_SYN_COOKIES=y · 57 unmodified lines | ||
| 58 | 58 | CONFIG_INET_AH=m |
| 59 | 59 | CONFIG_INET_ESP=m |
| 60 | 60 | CONFIG_INET_IPCOMP=m |
| 61 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 62 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 63 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 64 | 61 | CONFIG_INET6_AH=m |
| 65 | 62 | CONFIG_INET6_ESP=m |
| 66 | 63 | CONFIG_INET6_IPCOMP=m |
| 67 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 68 | 64 | CONFIG_IPV6_TUNNEL=m |
| 69 | 65 | CONFIG_NETWORK_SECMARK=y |
| 70 | 66 | CONFIG_NETFILTER=y |
| @@ -282,7 +278,6 @@ CONFIG_PCMCIA_XIRCOM=m · 211 unmodified lines | ||
| 282 | 278 | CONFIG_DL2K=m |
| 283 | 279 | CONFIG_SUNDANCE=m |
| 284 | 280 | CONFIG_PCMCIA_FMVJ18X=m |
| 285 | −CONFIG_HP100=m | |
| 286 | 281 | CONFIG_E100=m |
| 287 | 282 | CONFIG_E1000=m |
| 288 | 283 | CONFIG_IXGB=m |
| @@ -366,9 +361,6 @@ CONFIG_HDLC_X25=m · 77 unmodified lines | ||
| 366 | 361 | CONFIG_PCI200SYN=m |
| 367 | 362 | CONFIG_WANXL=m |
| 368 | 363 | CONFIG_FARSYNC=m |
| 369 | −CONFIG_DSCC4=m | |
| 370 | −CONFIG_DSCC4_PCISYNC=y | |
| 371 | −CONFIG_DSCC4_PCI_RST=y | |
| 372 | 364 | CONFIG_LAPBETHER=m |
| 373 | 365 | # CONFIG_KEYBOARD_ATKBD is not set |
| 374 | 366 | CONFIG_KEYBOARD_GPIO=y |
| @@ -681,7 +673,6 @@ CONFIG_CRYPTO_PCBC=m · 306 unmodified lines | ||
| 681 | 673 | CONFIG_CRYPTO_HMAC=y |
| 682 | 674 | CONFIG_CRYPTO_MD5=y |
| 683 | 675 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 684 | −CONFIG_CRYPTO_TGR192=m | |
| 685 | 676 | CONFIG_CRYPTO_WP512=m |
| 686 | 677 | CONFIG_CRYPTO_ANUBIS=m |
| 687 | 678 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -690,5 +681,4 @@ CONFIG_CRYPTO_KHAZAD=m · 2 unmodified lines | ||
| 690 | 681 | CONFIG_CRYPTO_SERPENT=m |
| 691 | 682 | CONFIG_CRYPTO_TEA=m |
| 692 | 683 | CONFIG_CRYPTO_TWOFISH=m |
| 693 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 694 | 684 | CONFIG_MAGIC_SYSRQ=y |
| @@ -35,9 +35,6 @@ CONFIG_NET=y · 34 unmodified lines | ||
| 35 | 35 | CONFIG_PACKET=y |
| 36 | 36 | CONFIG_UNIX=y |
| 37 | 37 | CONFIG_INET=y |
| 38 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 39 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 40 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 41 | 38 | # CONFIG_INET_DIAG is not set |
| 42 | 39 | # CONFIG_IPV6 is not set |
| 43 | 40 | # CONFIG_WIRELESS is not set |
| @@ -45,7 +45,6 @@ CONFIG_KEYBOARD_GPIO_POLLED=m · 44 unmodified lines | ||
| 45 | 45 | CONFIG_SERIAL_PIC32=y |
| 46 | 46 | CONFIG_SERIAL_PIC32_CONSOLE=y |
| 47 | 47 | CONFIG_HW_RANDOM=y |
| 48 | −CONFIG_RAW_DRIVER=m | |
| 49 | 48 | CONFIG_GPIO_SYSFS=y |
| 50 | 49 | # CONFIG_HWMON is not set |
| 51 | 50 | CONFIG_HIDRAW=y |
| @@ -33,9 +33,6 @@ CONFIG_IP_MULTIPLE_TABLES=y · 32 unmodified lines | ||
| 33 | 33 | CONFIG_IP_ROUTE_MULTIPATH=y |
| 34 | 34 | CONFIG_IP_ROUTE_VERBOSE=y |
| 35 | 35 | CONFIG_SYN_COOKIES=y |
| 36 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 37 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 38 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 39 | 36 | CONFIG_INET_DIAG=m |
| 40 | 37 | CONFIG_TCP_CONG_ADVANCED=y |
| 41 | 38 | CONFIG_TCP_CONG_CUBIC=m |
| @@ -162,5 +159,4 @@ CONFIG_SQUASHFS=y · 120 unmodified lines | ||
| 162 | 159 | CONFIG_CRYPTO_TEST=m |
| 163 | 160 | # CONFIG_CRYPTO_HW is not set |
| 164 | 161 | CONFIG_CRC16=m |
| 165 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 166 | 162 | CONFIG_STRIP_ASM_SYMS=y |
| @@ -21,9 +21,6 @@ CONFIG_UNIX=y · 20 unmodified lines | ||
| 21 | 21 | CONFIG_INET=y |
| 22 | 22 | CONFIG_IP_MULTICAST=y |
| 23 | 23 | CONFIG_IP_PNP=y |
| 24 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 25 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 26 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 27 | 24 | # CONFIG_IPV6 is not set |
| 28 | 25 | # CONFIG_WIRELESS is not set |
| 29 | 26 | CONFIG_MTD=y |
| @@ -51,7 +48,6 @@ CONFIG_TC35815=y · 21 unmodified lines | ||
| 51 | 48 | CONFIG_SERIAL_TXX9_CONSOLE=y |
| 52 | 49 | CONFIG_SERIAL_TXX9_STDSERIAL=y |
| 53 | 50 | CONFIG_SPI=y |
| 54 | −CONFIG_SPI_TXX9=y | |
| 55 | 51 | # CONFIG_HWMON is not set |
| 56 | 52 | CONFIG_WATCHDOG=y |
| 57 | 53 | CONFIG_TXX9_WDT=m |
| @@ -65,8 +61,6 @@ CONFIG_SND=m · 7 unmodified lines | ||
| 65 | 61 | # CONFIG_SND_SPI is not set |
| 66 | 62 | # CONFIG_SND_MIPS is not set |
| 67 | 63 | CONFIG_SND_SOC=m |
| 68 | −CONFIG_SND_SOC_TXX9ACLC=m | |
| 69 | −CONFIG_SND_SOC_TXX9ACLC_GENERIC=m | |
| 70 | 64 | # CONFIG_USB_SUPPORT is not set |
| 71 | 65 | CONFIG_NEW_LEDS=y |
| 72 | 66 | CONFIG_LEDS_CLASS=y |
| @@ -78,7 +72,6 @@ CONFIG_RTC_CLASS=y · 5 unmodified lines | ||
| 78 | 72 | CONFIG_RTC_INTF_DEV_UIE_EMUL=y |
| 79 | 73 | CONFIG_RTC_DRV_RS5C348=y |
| 80 | 74 | CONFIG_RTC_DRV_DS1742=y |
| 81 | −CONFIG_RTC_DRV_TX4939=y | |
| 82 | 75 | CONFIG_DMADEVICES=y |
| 83 | 76 | CONFIG_TXX9_DMAC=m |
| 84 | 77 | # CONFIG_DNOTIFY is not set |
| @@ -29,9 +29,6 @@ CONFIG_NET_IPIP=m · 28 unmodified lines | ||
| 29 | 29 | CONFIG_IP_MROUTE=y |
| 30 | 30 | CONFIG_IP_PIMSM_V1=y |
| 31 | 31 | CONFIG_IP_PIMSM_V2=y |
| 32 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 33 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 34 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 35 | 32 | CONFIG_TCP_MD5SIG=y |
| 36 | 33 | CONFIG_IPV6_ROUTER_PREF=y |
| 37 | 34 | CONFIG_IPV6_ROUTE_INFO=y |
| @@ -39,7 +36,6 @@ CONFIG_INET6_AH=m · 1 unmodified line | ||
| 39 | 36 | CONFIG_INET6_ESP=m |
| 40 | 37 | CONFIG_INET6_IPCOMP=m |
| 41 | 38 | CONFIG_IPV6_MIP6=m |
| 42 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 43 | 39 | CONFIG_IPV6_TUNNEL=m |
| 44 | 40 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 45 | 41 | CONFIG_IPV6_SUBTREES=y |
| @@ -190,9 +186,7 @@ CONFIG_PARIDE_KTTI=m · 144 unmodified lines | ||
| 190 | 186 | CONFIG_PARIDE_ON20=m |
| 191 | 187 | CONFIG_PARIDE_ON26=m |
| 192 | 188 | CONFIG_BLK_DEV_LOOP=m |
| 193 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 194 | 189 | CONFIG_BLK_DEV_NBD=m |
| 195 | −CONFIG_BLK_DEV_SX8=m | |
| 196 | 190 | CONFIG_BLK_DEV_RAM=m |
| 197 | 191 | CONFIG_CDROM_PKTCDVD=m |
| 198 | 192 | CONFIG_ATA_OVER_ETH=m |
| @@ -398,7 +392,6 @@ CONFIG_CRYPTO_PCBC=m · 199 unmodified lines | ||
| 398 | 392 | CONFIG_CRYPTO_HMAC=y |
| 399 | 393 | CONFIG_CRYPTO_XCBC=m |
| 400 | 394 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 401 | −CONFIG_CRYPTO_TGR192=m | |
| 402 | 395 | CONFIG_CRYPTO_WP512=m |
| 403 | 396 | CONFIG_CRYPTO_ANUBIS=m |
| 404 | 397 | CONFIG_CRYPTO_BLOWFISH=m |
| @@ -35,9 +35,6 @@ CONFIG_IP_ROUTE_VERBOSE=y · 34 unmodified lines | ||
| 35 | 35 | CONFIG_IP_MROUTE=y |
| 36 | 36 | CONFIG_IP_MROUTE_MULTIPLE_TABLES=y |
| 37 | 37 | CONFIG_SYN_COOKIES=y |
| 38 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 39 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 40 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 41 | 38 | # CONFIG_INET_DIAG is not set |
| 42 | 39 | CONFIG_TCP_CONG_ADVANCED=y |
| 43 | 40 | # CONFIG_TCP_CONG_BIC is not set |
| @@ -140,7 +137,6 @@ CONFIG_CRC32_SARWATE=y · 96 unmodified lines | ||
| 140 | 137 | # CONFIG_XZ_DEC_ARMTHUMB is not set |
| 141 | 138 | # CONFIG_XZ_DEC_SPARC is not set |
| 142 | 139 | CONFIG_PRINTK_TIME=y |
| 143 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 144 | 140 | CONFIG_STRIP_ASM_SYMS=y |
| 145 | 141 | CONFIG_DEBUG_FS=y |
| 146 | 142 | CONFIG_MAGIC_SYSRQ=y |
| @@ -88,7 +88,6 @@ CONFIG_CRYPTO_XCBC=m · 87 unmodified lines | ||
| 88 | 88 | CONFIG_CRYPTO_MD4=m |
| 89 | 89 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 90 | 90 | CONFIG_CRYPTO_SHA512=m |
| 91 | −CONFIG_CRYPTO_TGR192=m | |
| 92 | 91 | CONFIG_CRYPTO_WP512=m |
| 93 | 92 | CONFIG_CRYPTO_BLOWFISH=m |
| 94 | 93 | CONFIG_CRYPTO_CAMELLIA=m |
| @@ -96,7 +95,6 @@ CONFIG_CRYPTO_CAST5=m · 1 unmodified line | ||
| 96 | 95 | CONFIG_CRYPTO_CAST6=m |
| 97 | 96 | CONFIG_CRYPTO_DES=m |
| 98 | 97 | CONFIG_CRYPTO_FCRYPT=m |
| 99 | −CONFIG_CRYPTO_SALSA20=m | |
| 100 | 98 | CONFIG_CRYPTO_SERPENT=m |
| 101 | 99 | CONFIG_CRYPTO_TWOFISH=m |
| 102 | 100 | CONFIG_CRYPTO_DEFLATE=m |
| @@ -35,9 +35,6 @@ CONFIG_NET=y · 34 unmodified lines | ||
| 35 | 35 | CONFIG_PACKET=y |
| 36 | 36 | CONFIG_UNIX=y |
| 37 | 37 | CONFIG_INET=y |
| 38 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 39 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 40 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 41 | 38 | # CONFIG_INET_DIAG is not set |
| 42 | 39 | # CONFIG_IPV6 is not set |
| 43 | 40 | # CONFIG_WIRELESS is not set |
| @@ -37,9 +37,6 @@ CONFIG_IP_ROUTE_VERBOSE=y · 36 unmodified lines | ||
| 37 | 37 | CONFIG_IP_MROUTE=y |
| 38 | 38 | CONFIG_IP_MROUTE_MULTIPLE_TABLES=y |
| 39 | 39 | CONFIG_SYN_COOKIES=y |
| 40 | −# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 41 | −# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 42 | −# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 43 | 40 | # CONFIG_INET_DIAG is not set |
| 44 | 41 | CONFIG_TCP_CONG_ADVANCED=y |
| 45 | 42 | # CONFIG_TCP_CONG_BIC is not set |
| @@ -146,7 +143,6 @@ CONFIG_CRYPTO_ARC4=m · 100 unmodified lines | ||
| 146 | 143 | CONFIG_CRC_ITU_T=m |
| 147 | 144 | CONFIG_CRC32_SARWATE=y |
| 148 | 145 | CONFIG_PRINTK_TIME=y |
| 149 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 150 | 146 | CONFIG_STRIP_ASM_SYMS=y |
| 151 | 147 | CONFIG_DEBUG_FS=y |
| 152 | 148 | CONFIG_MAGIC_SYSRQ=y |
| @@ -63,10 +63,6 @@ extern void do_domain_IRQ(struct irq_domain *domain, unsigned int irq); · 62 unmodified lines | ||
| 63 | 63 | extern void arch_init_irq(void); |
| 64 | 64 | extern void spurious_interrupt(void); |
| 65 | 65 | |
| 66 | −extern int allocate_irqno(void); | |
| 67 | −extern void alloc_legacy_irqno(void); | |
| 68 | −extern void free_irqno(unsigned int irq); | |
| 69 | − | |
| 70 | 66 | /* |
| 71 | 67 | * Before R2 the timer and performance counter interrupts were both fixed to |
| 72 | 68 | * IE7. Since R2 their number has to be read from the c0_intctl register. |
| @@ -104,8 +104,6 @@ struct plat_dsl_data { · 103 unmodified lines | ||
| 104 | 104 | int reset_bit_sar; |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | −extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock; | |
| 108 | − | |
| 109 | 107 | static inline int ar7_is_titan(void) |
| 110 | 108 | { |
| 111 | 109 | return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) == |
| @@ -263,26 +263,6 @@ static inline void cvmx_fpa_free(void *ptr, uint64_t pool, · 262 unmodified lines | ||
| 263 | 263 | cvmx_write_io(newptr.u64, num_cache_lines); |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | −/** | |
| 267 | − * Setup a FPA pool to control a new block of memory. | |
| 268 | − * This can only be called once per pool. Make sure proper | |
| 269 | − * locking enforces this. | |
| 270 | − * | |
| 271 | − * @pool: Pool to initialize | |
| 272 | − * 0 <= pool < 8 | |
| 273 | − * @name: Constant character string to name this pool. | |
| 274 | − * String is not copied. | |
| 275 | − * @buffer: Pointer to the block of memory to use. This must be | |
| 276 | − * accessible by all processors and external hardware. | |
| 277 | − * @block_size: Size for each block controlled by the FPA | |
| 278 | − * @num_blocks: Number of blocks | |
| 279 | − * | |
| 280 | − * Returns 0 on Success, | |
| 281 | − * -1 on failure | |
| 282 | − */ | |
| 283 | −extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer, | |
| 284 | − uint64_t block_size, uint64_t num_blocks); | |
| 285 | − | |
| 286 | 266 | /** |
| 287 | 267 | * Shutdown a Memory pool and validate that it had all of |
| 288 | 268 | * the buffers originally placed in it. This should only be |
| @@ -43,7 +43,6 @@ extern int octeon_get_southbridge_interrupt(void); · 42 unmodified lines | ||
| 43 | 43 | extern int octeon_get_boot_coremask(void); |
| 44 | 44 | extern int octeon_get_boot_num_arguments(void); |
| 45 | 45 | extern const char *octeon_get_boot_argument(int arg); |
| 46 | −extern void octeon_hal_setup_reserved32(void); | |
| 47 | 46 | extern void octeon_user_io_init(void); |
| 48 | 47 | |
| 49 | 48 | extern void octeon_init_cvmcount(void); |
| @@ -64,6 +64,4 @@ enum octeon_dma_bar_type { · 63 unmodified lines | ||
| 64 | 64 | extern enum octeon_dma_bar_type octeon_dma_bar_type; |
| 65 | 65 | |
| 66 | 66 | void octeon_pci_dma_init(void); |
| 67 | −extern char *octeon_swiotlb; | |
| 68 | − | |
| 69 | 67 | #endif |
| @@ -32,7 +32,6 @@ extern unsigned int soc_type; · 31 unmodified lines | ||
| 32 | 32 | extern unsigned int periph_rev; |
| 33 | 33 | extern unsigned int zbbus_mhz; |
| 34 | 34 | |
| 35 | −extern void sb1250_time_init(void); | |
| 36 | 35 | extern void sb1250_mask_irq(int cpu, int irq); |
| 37 | 36 | extern void sb1250_unmask_irq(int cpu, int irq); |
| 38 | 37 | |
| @@ -226,9 +226,6 @@ extern void sni_pcit_cplus_irq_init(void); · 225 unmodified lines | ||
| 226 | 226 | extern void sni_rm200_irq_init(void); |
| 227 | 227 | extern void sni_pcimt_irq_init(void); |
| 228 | 228 | |
| 229 | −/* timer inits */ | |
| 230 | −extern void sni_cpu_time_init(void); | |
| 231 | − | |
| 232 | 229 | /* eisa init for RM200/400 */ |
| 233 | 230 | #ifdef CONFIG_EISA |
| 234 | 231 | extern int sni_eisa_root_init(void); |
| @@ -26,7 +26,7 @@ __init void mips_set_machine_name(const char *name) · 25 unmodified lines | ||
| 26 | 26 | if (name == NULL) |
| 27 | 27 | return; |
| 28 | 28 | |
| 29 | − strlcpy(mips_machine_name, name, sizeof(mips_machine_name)); | |
| 29 | + strscpy(mips_machine_name, name, sizeof(mips_machine_name)); | |
| 30 | 30 | pr_info("MIPS: machine is %s\n", mips_get_machine_name()); |
| 31 | 31 | } |
| 32 | 32 | |
| @@ -52,9 +52,9 @@ int __init __dt_register_buses(const char *bus0, const char *bus1) · 19 unmodified lines | ||
| 52 | 52 | if (!of_have_populated_dt()) |
| 53 | 53 | panic("device tree not present"); |
| 54 | 54 | |
| 55 | − strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible)); | |
| 55 | + strscpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible)); | |
| 56 | 56 | if (bus1) { |
| 57 | − strlcpy(of_ids[1].compatible, bus1, | |
| 57 | + strscpy(of_ids[1].compatible, bus1, | |
| 58 | 58 | sizeof(of_ids[1].compatible)); |
| 59 | 59 | } |
| 60 | 60 | |
| @@ -340,7 +340,7 @@ void *__init relocate_kernel(void) · 339 unmodified lines | ||
| 340 | 340 | early_init_dt_scan(fdt); |
| 341 | 341 | if (boot_command_line[0]) { |
| 342 | 342 | /* Boot command line was passed in device tree */ |
| 343 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 343 | + strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 344 | 344 | } |
| 345 | 345 | #endif /* CONFIG_USE_OF */ |
| 346 | 346 | |
| @@ -46,7 +46,7 @@ static void build_segment_config(char *str, unsigned int cfg) · 45 unmodified lines | ||
| 46 | 46 | ((cfg & MIPS_SEGCFG_EU) >> MIPS_SEGCFG_EU_SHIFT)); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | −static int show_segments(struct seq_file *m, void *v) | |
| 49 | +static int segments_show(struct seq_file *m, void *v) | |
| 50 | 50 | { |
| 51 | 51 | unsigned int segcfg; |
| 52 | 52 | char str[42]; |
| @@ -80,18 +80,7 @@ static int show_segments(struct seq_file *m, void *v) · 27 unmodified lines | ||
| 80 | 80 | |
| 81 | 81 | return 0; |
| 82 | 82 | } |
| 83 | − | |
| 84 | −static int segments_open(struct inode *inode, struct file *file) | |
| 85 | −{ | |
| 86 | − return single_open(file, show_segments, NULL); | |
| 87 | −} | |
| 88 | − | |
| 89 | −static const struct file_operations segments_fops = { | |
| 90 | − .open = segments_open, | |
| 91 | − .read = seq_read, | |
| 92 | − .llseek = seq_lseek, | |
| 93 | − .release = single_release, | |
| 94 | −}; | |
| 83 | +DEFINE_SHOW_ATTRIBUTE(segments); | |
| 95 | 84 | |
| 96 | 85 | static int __init segments_info(void) |
| 97 | 86 | { |
| @@ -42,6 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <asm/setup.h> |
| 43 | 43 | #include <asm/smp-ops.h> |
| 44 | 44 | #include <asm/prom.h> |
| 45 | +#include <asm/fw/fw.h> | |
| 45 | 46 | |
| 46 | 47 | #ifdef CONFIG_MIPS_ELF_APPENDED_DTB |
| 47 | 48 | char __section(".appended_dtb") __appended_dtb[0x100000]; |
| @@ -756,6 +757,24 @@ static void __init prefill_possible_map(void) · 708 unmodified lines | ||
| 756 | 757 | static inline void prefill_possible_map(void) {} |
| 757 | 758 | #endif |
| 758 | 759 | |
| 760 | +static void __init setup_rng_seed(void) | |
| 761 | +{ | |
| 762 | + char *rng_seed_hex = fw_getenv("rngseed"); | |
| 763 | + u8 rng_seed[512]; | |
| 764 | + size_t len; | |
| 765 | + | |
| 766 | + if (!rng_seed_hex) | |
| 767 | + return; | |
| 768 | + | |
| 769 | + len = min(sizeof(rng_seed), strlen(rng_seed_hex) / 2); | |
| 770 | + if (hex2bin(rng_seed, rng_seed_hex, len)) | |
| 771 | + return; | |
| 772 | + | |
| 773 | + add_bootloader_randomness(rng_seed, len); | |
| 774 | + memzero_explicit(rng_seed, len); | |
| 775 | + memzero_explicit(rng_seed_hex, len * 2); | |
| 776 | +} | |
| 777 | + | |
| 759 | 778 | void __init setup_arch(char **cmdline_p) |
| 760 | 779 | { |
| 761 | 780 | cpu_probe(); |
| @@ -786,6 +805,8 @@ void __init setup_arch(char **cmdline_p) · 24 unmodified lines | ||
| 786 | 805 | paging_init(); |
| 787 | 806 | |
| 788 | 807 | memblock_dump_all(); |
| 808 | + | |
| 809 | + setup_rng_seed(); | |
| 789 | 810 | } |
| 790 | 811 | |
| 791 | 812 | unsigned long kernelsp[NR_CPUS]; |
| @@ -34,6 +34,14 @@ unsigned long physical_memsize = 0L; · 33 unmodified lines | ||
| 34 | 34 | */ |
| 35 | 35 | static struct ltq_soc_info soc_info; |
| 36 | 36 | |
| 37 | +/* | |
| 38 | + * These structs are used to override vsmp_init_secondary() | |
| 39 | + */ | |
| 40 | +#if defined(CONFIG_MIPS_MT_SMP) | |
| 41 | +extern const struct plat_smp_ops vsmp_smp_ops; | |
| 42 | +static struct plat_smp_ops lantiq_smp_ops; | |
| 43 | +#endif | |
| 44 | + | |
| 37 | 45 | const char *get_system_type(void) |
| 38 | 46 | { |
| 39 | 47 | return soc_info.sys_type; |
| @@ -84,6 +92,17 @@ void __init plat_mem_setup(void) · 44 unmodified lines | ||
| 84 | 92 | __dt_setup_arch(dtb); |
| 85 | 93 | } |
| 86 | 94 | |
| 95 | +#if defined(CONFIG_MIPS_MT_SMP) | |
| 96 | +static void lantiq_init_secondary(void) | |
| 97 | +{ | |
| 98 | + /* | |
| 99 | + * MIPS CPU startup function vsmp_init_secondary() will only | |
| 100 | + * enable some of the interrupts for the second CPU/VPE. | |
| 101 | + */ | |
| 102 | + set_c0_status(ST0_IM); | |
| 103 | +} | |
| 104 | +#endif | |
| 105 | + | |
| 87 | 106 | void __init prom_init(void) |
| 88 | 107 | { |
| 89 | 108 | /* call the soc specific detetcion code and get it to fill soc_info */ |
| @@ -95,7 +114,10 @@ void __init prom_init(void) · 5 unmodified lines | ||
| 95 | 114 | prom_init_cmdline(); |
| 96 | 115 | |
| 97 | 116 | #if defined(CONFIG_MIPS_MT_SMP) |
| 98 | − if (register_vsmp_smp_ops()) | |
| 99 | − panic("failed to register_vsmp_smp_ops()"); | |
| 117 | + if (cpu_has_mipsmt) { | |
| 118 | + lantiq_smp_ops = vsmp_smp_ops; | |
| 119 | + lantiq_smp_ops.init_secondary = lantiq_init_secondary; | |
| 120 | + register_smp_ops(&lantiq_smp_ops); | |
| 121 | + } | |
| 100 | 122 | #endif |
| 101 | 123 | } |
| @@ -4,9 +4,10 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <linux/err.h> | |
| 7 | 8 | #include <linux/export.h> |
| 9 | +#include <linux/gpio/consumer.h> | |
| 8 | 10 | #include <linux/of_platform.h> |
| 9 | −#include <linux/of_gpio.h> | |
| 10 | 11 | #include <linux/dma-mapping.h> |
| 11 | 12 | |
| 12 | 13 | #include <lantiq_soc.h> |
| @@ -25,23 +26,28 @@ EXPORT_SYMBOL(ltq_get_cp1_base); · 12 unmodified lines | ||
| 25 | 26 | static int vmmc_probe(struct platform_device *pdev) |
| 26 | 27 | { |
| 27 | 28 | #define CP1_SIZE (1 << 20) |
| 29 | + struct gpio_desc *gpio; | |
| 28 | 30 | int gpio_count; |
| 29 | 31 | dma_addr_t dma; |
| 32 | + int error; | |
| 30 | 33 | |
| 31 | 34 | cp1_base = |
| 32 | 35 | (void *) CPHYSADDR(dma_alloc_coherent(&pdev->dev, CP1_SIZE, |
| 33 | 36 | &dma, GFP_KERNEL)); |
| 34 | 37 | |
| 35 | − gpio_count = of_gpio_count(pdev->dev.of_node); | |
| 38 | + gpio_count = gpiod_count(&pdev->dev, NULL); | |
| 36 | 39 | while (gpio_count > 0) { |
| 37 | − enum of_gpio_flags flags; | |
| 38 | − int gpio = of_get_gpio_flags(pdev->dev.of_node, | |
| 39 | − --gpio_count, &flags); | |
| 40 | − if (gpio_request(gpio, "vmmc-relay")) | |
| 40 | + gpio = devm_gpiod_get_index(&pdev->dev, | |
| 41 | + NULL, --gpio_count, GPIOD_OUT_HIGH); | |
| 42 | + error = PTR_ERR_OR_ZERO(gpio); | |
| 43 | + if (error) { | |
| 44 | + dev_err(&pdev->dev, | |
| 45 | + "failed to request GPIO idx %d: %d\n", | |
| 46 | + gpio_count, error); | |
| 41 | 47 | continue; |
| 42 | − dev_info(&pdev->dev, "requested GPIO %d\n", gpio); | |
| 43 | − gpio_direction_output(gpio, | |
| 44 | − (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1)); | |
| 48 | + } | |
| 49 | + | |
| 50 | + gpiod_set_consumer_name(gpio, "vmmc-relay"); | |
| 45 | 51 | } |
| 46 | 52 | |
| 47 | 53 | dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base); |
| @@ -1,17 +1,13 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/export.h> |
| 3 | 3 | #include <linux/compiler.h> |
| 4 | +#include <uapi/linux/swab.h> | |
| 5 | + | |
| 6 | +/* To silence -Wmissing-prototypes. */ | |
| 7 | +unsigned long long __bswapdi2(unsigned long long u); | |
| 4 | 8 | |
| 5 | 9 | unsigned long long notrace __bswapdi2(unsigned long long u) |
| 6 | 10 | { |
| 7 | − return (((u) & 0xff00000000000000ull) >> 56) | | |
| 8 | − (((u) & 0x00ff000000000000ull) >> 40) | | |
| 9 | − (((u) & 0x0000ff0000000000ull) >> 24) | | |
| 10 | − (((u) & 0x000000ff00000000ull) >> 8) | | |
| 11 | − (((u) & 0x00000000ff000000ull) << 8) | | |
| 12 | − (((u) & 0x0000000000ff0000ull) << 24) | | |
| 13 | − (((u) & 0x000000000000ff00ull) << 40) | | |
| 14 | − (((u) & 0x00000000000000ffull) << 56); | |
| 11 | + return ___constant_swab64(u); | |
| 15 | 12 | } |
| 16 | − | |
| 17 | 13 | EXPORT_SYMBOL(__bswapdi2); |
| @@ -1,13 +1,13 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/export.h> |
| 3 | 3 | #include <linux/compiler.h> |
| 4 | +#include <uapi/linux/swab.h> | |
| 5 | + | |
| 6 | +/* To silence -Wmissing-prototypes. */ | |
| 7 | +unsigned int __bswapsi2(unsigned int u); | |
| 4 | 8 | |
| 5 | 9 | unsigned int notrace __bswapsi2(unsigned int u) |
| 6 | 10 | { |
| 7 | − return (((u) & 0xff000000) >> 24) | | |
| 8 | − (((u) & 0x00ff0000) >> 8) | | |
| 9 | − (((u) & 0x0000ff00) << 8) | | |
| 10 | − (((u) & 0x000000ff) << 24); | |
| 11 | + return ___constant_swab32(u); | |
| 11 | 12 | } |
| 12 | − | |
| 13 | 13 | EXPORT_SYMBOL(__bswapsi2); |
| @@ -73,8 +73,6 @@ static void __init setup_pcimap(void) · 72 unmodified lines | ||
| 73 | 73 | #endif |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | −extern int sbx00_acpi_init(void); | |
| 77 | − | |
| 78 | 76 | static int __init pcibios_init(void) |
| 79 | 77 | { |
| 80 | 78 | setup_pcimap(); |
| @@ -1032,7 +1032,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 1031 unmodified lines | ||
| 1032 | 1032 | */ |
| 1033 | 1033 | if (dec_insn.micro_mips_mode) { |
| 1034 | 1034 | /* |
| 1035 | − * If next instruction is a 16-bit instruction, then it | |
| 1035 | + * If next instruction is a 16-bit instruction, then | |
| 1036 | 1036 | * it cannot be a FPU instruction. This could happen |
| 1037 | 1037 | * since we can be called for non-FPU instructions. |
| 1038 | 1038 | */ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | */ |
| 4 | 4 | |
| 5 | −/** | |
| 5 | +/* | |
| 6 | 6 | * Both AR2315 and AR2316 chips have PCI interface unit, which supports DMA |
| 7 | 7 | * and interrupt. PCI interface supports MMIO access method, but does not |
| 8 | 8 | * seem to support I/O ports. |
| @@ -9,11 +9,11 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/kernel.h> |
| 10 | 10 | #include <linux/init.h> |
| 11 | 11 | #include <linux/delay.h> |
| 12 | +#include <linux/gpio/consumer.h> | |
| 12 | 13 | #include <linux/mm.h> |
| 13 | 14 | #include <linux/vmalloc.h> |
| 14 | 15 | #include <linux/clk.h> |
| 15 | 16 | #include <linux/of_platform.h> |
| 16 | −#include <linux/of_gpio.h> | |
| 17 | 17 | #include <linux/of_irq.h> |
| 18 | 18 | #include <linux/of_pci.h> |
| 19 | 19 | |
| @@ -62,7 +62,7 @@ · 42 unmodified lines | ||
| 62 | 62 | __iomem void *ltq_pci_mapped_cfg; |
| 63 | 63 | static __iomem void *ltq_pci_membase; |
| 64 | 64 | |
| 65 | −static int reset_gpio; | |
| 65 | +static struct gpio_desc *reset_gpio; | |
| 66 | 66 | static struct clk *clk_pci, *clk_external; |
| 67 | 67 | static struct resource pci_io_resource; |
| 68 | 68 | static struct resource pci_mem_resource; |
| @@ -95,6 +95,7 @@ static int ltq_pci_startup(struct platform_device *pdev) · 26 unmodified lines | ||
| 95 | 95 | struct device_node *node = pdev->dev.of_node; |
| 96 | 96 | const __be32 *req_mask, *bus_clk; |
| 97 | 97 | u32 temp_buffer; |
| 98 | + int error; | |
| 98 | 99 | |
| 99 | 100 | /* get our clocks */ |
| 100 | 101 | clk_pci = clk_get(&pdev->dev, NULL); |
| @@ -123,17 +124,14 @@ static int ltq_pci_startup(struct platform_device *pdev) · 22 unmodified lines | ||
| 123 | 124 | clk_disable(clk_external); |
| 124 | 125 | |
| 125 | 126 | /* setup reset gpio used by pci */ |
| 126 | − reset_gpio = of_get_named_gpio(node, "gpio-reset", 0); | |
| 127 | − if (gpio_is_valid(reset_gpio)) { | |
| 128 | − int ret = devm_gpio_request(&pdev->dev, | |
| 129 | − reset_gpio, "pci-reset"); | |
| 130 | − if (ret) { | |
| 131 | − dev_err(&pdev->dev, | |
| 132 | − "failed to request gpio %d\n", reset_gpio); | |
| 133 | − return ret; | |
| 134 | − } | |
| 135 | − gpio_direction_output(reset_gpio, 1); | |
| 127 | + reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", | |
| 128 | + GPIOD_OUT_LOW); | |
| 129 | + error = PTR_ERR_OR_ZERO(reset_gpio); | |
| 130 | + if (error) { | |
| 131 | + dev_err(&pdev->dev, "failed to request gpio: %d\n", error); | |
| 132 | + return error; | |
| 136 | 133 | } |
| 134 | + gpiod_set_consumer_name(reset_gpio, "pci_reset"); | |
| 137 | 135 | |
| 138 | 136 | /* enable auto-switching between PCI and EBU */ |
| 139 | 137 | ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); |
| @@ -195,11 +193,11 @@ static int ltq_pci_startup(struct platform_device *pdev) · 55 unmodified lines | ||
| 195 | 193 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN); |
| 196 | 194 | |
| 197 | 195 | /* toggle reset pin */ |
| 198 | − if (gpio_is_valid(reset_gpio)) { | |
| 199 | − __gpio_set_value(reset_gpio, 0); | |
| 196 | + if (reset_gpio) { | |
| 197 | + gpiod_set_value_cansleep(reset_gpio, 1); | |
| 200 | 198 | wmb(); |
| 201 | 199 | mdelay(1); |
| 202 | − __gpio_set_value(reset_gpio, 1); | |
| 200 | + gpiod_set_value_cansleep(reset_gpio, 0); | |
| 203 | 201 | } |
| 204 | 202 | return 0; |
| 205 | 203 | } |
| @@ -44,7 +44,7 @@ void __init plat_mem_setup(void) · 43 unmodified lines | ||
| 44 | 44 | pr_info(" builtin_cmdline : %s\n", CONFIG_CMDLINE); |
| 45 | 45 | #endif |
| 46 | 46 | if (dtb != __dtb_start) |
| 47 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 47 | + strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 48 | 48 | |
| 49 | 49 | #ifdef CONFIG_EARLY_PRINTK |
| 50 | 50 | fw_init_early_console(-1); |
| @@ -18,22 +18,11 @@ static int bootrom_show(struct seq_file *s, void *unused) · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | return 0; |
| 20 | 20 | } |
| 21 | − | |
| 22 | −static int bootrom_open(struct inode *inode, struct file *file) | |
| 23 | −{ | |
| 24 | − return single_open(file, bootrom_show, NULL); | |
| 25 | −} | |
| 26 | − | |
| 27 | −static const struct file_operations bootrom_file_ops = { | |
| 28 | − .open = bootrom_open, | |
| 29 | − .read = seq_read, | |
| 30 | − .llseek = seq_lseek, | |
| 31 | − .release = single_release, | |
| 32 | −}; | |
| 21 | +DEFINE_SHOW_ATTRIBUTE(bootrom); | |
| 33 | 22 | |
| 34 | 23 | static int __init bootrom_setup(void) |
| 35 | 24 | { |
| 36 | − debugfs_create_file("bootrom", 0444, NULL, NULL, &bootrom_file_ops); | |
| 25 | + debugfs_create_file("bootrom", 0444, NULL, NULL, &bootrom_fops); | |
| 37 | 26 | return 0; |
| 38 | 27 | } |
| 39 | 28 | |
| @@ -27,15 +27,18 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) · 26 unmodified lines | ||
| 27 | 27 | { |
| 28 | 28 | struct xtalk_bridge_platform_data *bd; |
| 29 | 29 | struct sgi_w1_platform_data *wd; |
| 30 | − struct platform_device *pdev; | |
| 30 | + struct platform_device *pdev_wd; | |
| 31 | + struct platform_device *pdev_bd; | |
| 31 | 32 | struct resource w1_res; |
| 32 | 33 | unsigned long offset; |
| 33 | 34 | |
| 34 | 35 | offset = NODE_OFFSET(nasid); |
| 35 | 36 | |
| 36 | 37 | wd = kzalloc(sizeof(*wd), GFP_KERNEL); |
| 37 | − if (!wd) | |
| 38 | − goto no_mem; | |
| 38 | + if (!wd) { | |
| 39 | + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); | |
| 40 | + return; | |
| 41 | + } | |
| 39 | 42 | |
| 40 | 43 | snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx", |
| 41 | 44 | offset + (widget << SWIN_SIZE_BITS)); |
| @@ -46,24 +49,35 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) · 4 unmodified lines | ||
| 46 | 49 | w1_res.end = w1_res.start + 3; |
| 47 | 50 | w1_res.flags = IORESOURCE_MEM; |
| 48 | 51 | |
| 49 | − pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); | |
| 50 | − if (!pdev) { | |
| 51 | − kfree(wd); | |
| 52 | − goto no_mem; | |
| 52 | + pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); | |
| 53 | + if (!pdev_wd) { | |
| 54 | + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); | |
| 55 | + goto err_kfree_wd; | |
| 56 | + } | |
| 57 | + if (platform_device_add_resources(pdev_wd, &w1_res, 1)) { | |
| 58 | + pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget); | |
| 59 | + goto err_put_pdev_wd; | |
| 60 | + } | |
| 61 | + if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) { | |
| 62 | + pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget); | |
| 63 | + goto err_put_pdev_wd; | |
| 64 | + } | |
| 65 | + if (platform_device_add(pdev_wd)) { | |
| 66 | + pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget); | |
| 67 | + goto err_put_pdev_wd; | |
| 53 | 68 | } |
| 54 | − platform_device_add_resources(pdev, &w1_res, 1); | |
| 55 | − platform_device_add_data(pdev, wd, sizeof(*wd)); | |
| 56 | 69 | /* platform_device_add_data() duplicates the data */ |
| 57 | 70 | kfree(wd); |
| 58 | − platform_device_add(pdev); | |
| 59 | 71 | |
| 60 | 72 | bd = kzalloc(sizeof(*bd), GFP_KERNEL); |
| 61 | − if (!bd) | |
| 62 | − goto no_mem; | |
| 63 | − pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); | |
| 64 | − if (!pdev) { | |
| 65 | − kfree(bd); | |
| 66 | − goto no_mem; | |
| 73 | + if (!bd) { | |
| 74 | + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); | |
| 75 | + goto err_unregister_pdev_wd; | |
| 76 | + } | |
| 77 | + pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); | |
| 78 | + if (!pdev_bd) { | |
| 79 | + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); | |
| 80 | + goto err_kfree_bd; | |
| 67 | 81 | } |
| 68 | 82 | |
| 69 | 83 | |
| @@ -84,15 +98,31 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) · 14 unmodified lines | ||
| 84 | 98 | bd->io.flags = IORESOURCE_IO; |
| 85 | 99 | bd->io_offset = offset; |
| 86 | 100 | |
| 87 | − platform_device_add_data(pdev, bd, sizeof(*bd)); | |
| 101 | + if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) { | |
| 102 | + pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget); | |
| 103 | + goto err_put_pdev_bd; | |
| 104 | + } | |
| 105 | + if (platform_device_add(pdev_bd)) { | |
| 106 | + pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget); | |
| 107 | + goto err_put_pdev_bd; | |
| 108 | + } | |
| 88 | 109 | /* platform_device_add_data() duplicates the data */ |
| 89 | 110 | kfree(bd); |
| 90 | − platform_device_add(pdev); | |
| 91 | 111 | pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget); |
| 92 | 112 | return; |
| 93 | 113 | |
| 94 | −no_mem: | |
| 95 | − pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); | |
| 114 | +err_put_pdev_bd: | |
| 115 | + platform_device_put(pdev_bd); | |
| 116 | +err_kfree_bd: | |
| 117 | + kfree(bd); | |
| 118 | +err_unregister_pdev_wd: | |
| 119 | + platform_device_unregister(pdev_wd); | |
| 120 | + return; | |
| 121 | +err_put_pdev_wd: | |
| 122 | + platform_device_put(pdev_wd); | |
| 123 | +err_kfree_wd: | |
| 124 | + kfree(wd); | |
| 125 | + return; | |
| 96 | 126 | } |
| 97 | 127 | |
| 98 | 128 | static int probe_one_port(nasid_t nasid, int widget, int masterwid) |
| @@ -40,12 +40,15 @@ static void bridge_platform_create(int widget, int masterwid) · 39 unmodified lines | ||
| 40 | 40 | { |
| 41 | 41 | struct xtalk_bridge_platform_data *bd; |
| 42 | 42 | struct sgi_w1_platform_data *wd; |
| 43 | − struct platform_device *pdev; | |
| 43 | + struct platform_device *pdev_wd; | |
| 44 | + struct platform_device *pdev_bd; | |
| 44 | 45 | struct resource w1_res; |
| 45 | 46 | |
| 46 | 47 | wd = kzalloc(sizeof(*wd), GFP_KERNEL); |
| 47 | − if (!wd) | |
| 48 | − goto no_mem; | |
| 48 | + if (!wd) { | |
| 49 | + pr_warn("xtalk:%x bridge create out of memory\n", widget); | |
| 50 | + return; | |
| 51 | + } | |
| 49 | 52 | |
| 50 | 53 | snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx", |
| 51 | 54 | IP30_SWIN_BASE(widget)); |
| @@ -56,24 +59,35 @@ static void bridge_platform_create(int widget, int masterwid) · 4 unmodified lines | ||
| 56 | 59 | w1_res.end = w1_res.start + 3; |
| 57 | 60 | w1_res.flags = IORESOURCE_MEM; |
| 58 | 61 | |
| 59 | − pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); | |
| 60 | − if (!pdev) { | |
| 61 | − kfree(wd); | |
| 62 | − goto no_mem; | |
| 62 | + pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); | |
| 63 | + if (!pdev_wd) { | |
| 64 | + pr_warn("xtalk:%x bridge create out of memory\n", widget); | |
| 65 | + goto err_kfree_wd; | |
| 66 | + } | |
| 67 | + if (platform_device_add_resources(pdev_wd, &w1_res, 1)) { | |
| 68 | + pr_warn("xtalk:%x bridge failed to add platform resources.\n", widget); | |
| 69 | + goto err_put_pdev_wd; | |
| 70 | + } | |
| 71 | + if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) { | |
| 72 | + pr_warn("xtalk:%x bridge failed to add platform data.\n", widget); | |
| 73 | + goto err_put_pdev_wd; | |
| 74 | + } | |
| 75 | + if (platform_device_add(pdev_wd)) { | |
| 76 | + pr_warn("xtalk:%x bridge failed to add platform device.\n", widget); | |
| 77 | + goto err_put_pdev_wd; | |
| 63 | 78 | } |
| 64 | − platform_device_add_resources(pdev, &w1_res, 1); | |
| 65 | − platform_device_add_data(pdev, wd, sizeof(*wd)); | |
| 66 | 79 | /* platform_device_add_data() duplicates the data */ |
| 67 | 80 | kfree(wd); |
| 68 | − platform_device_add(pdev); | |
| 69 | 81 | |
| 70 | 82 | bd = kzalloc(sizeof(*bd), GFP_KERNEL); |
| 71 | − if (!bd) | |
| 72 | − goto no_mem; | |
| 73 | − pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); | |
| 74 | − if (!pdev) { | |
| 75 | − kfree(bd); | |
| 76 | − goto no_mem; | |
| 83 | + if (!bd) { | |
| 84 | + pr_warn("xtalk:%x bridge create out of memory\n", widget); | |
| 85 | + goto err_unregister_pdev_wd; | |
| 86 | + } | |
| 87 | + pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); | |
| 88 | + if (!pdev_bd) { | |
| 89 | + pr_warn("xtalk:%x bridge create out of memory\n", widget); | |
| 90 | + goto err_kfree_bd; | |
| 77 | 91 | } |
| 78 | 92 | |
| 79 | 93 | bd->bridge_addr = IP30_RAW_SWIN_BASE(widget); |
| @@ -93,15 +107,31 @@ static void bridge_platform_create(int widget, int masterwid) · 13 unmodified lines | ||
| 93 | 107 | bd->io.flags = IORESOURCE_IO; |
| 94 | 108 | bd->io_offset = IP30_SWIN_BASE(widget); |
| 95 | 109 | |
| 96 | − platform_device_add_data(pdev, bd, sizeof(*bd)); | |
| 110 | + if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) { | |
| 111 | + pr_warn("xtalk:%x bridge failed to add platform data.\n", widget); | |
| 112 | + goto err_put_pdev_bd; | |
| 113 | + } | |
| 114 | + if (platform_device_add(pdev_bd)) { | |
| 115 | + pr_warn("xtalk:%x bridge failed to add platform device.\n", widget); | |
| 116 | + goto err_put_pdev_bd; | |
| 117 | + } | |
| 97 | 118 | /* platform_device_add_data() duplicates the data */ |
| 98 | 119 | kfree(bd); |
| 99 | − platform_device_add(pdev); | |
| 100 | 120 | pr_info("xtalk:%x bridge widget\n", widget); |
| 101 | 121 | return; |
| 102 | 122 | |
| 103 | −no_mem: | |
| 104 | − pr_warn("xtalk:%x bridge create out of memory\n", widget); | |
| 123 | +err_put_pdev_bd: | |
| 124 | + platform_device_put(pdev_bd); | |
| 125 | +err_kfree_bd: | |
| 126 | + kfree(bd); | |
| 127 | +err_unregister_pdev_wd: | |
| 128 | + platform_device_unregister(pdev_wd); | |
| 129 | + return; | |
| 130 | +err_put_pdev_wd: | |
| 131 | + platform_device_put(pdev_wd); | |
| 132 | +err_kfree_wd: | |
| 133 | + kfree(wd); | |
| 134 | + return; | |
| 105 | 135 | } |
| 106 | 136 | |
| 107 | 137 | static unsigned int __init xbow_widget_active(s8 wid) |
| @@ -262,12 +262,6 @@ void __init arch_init_irq(void) · 261 unmodified lines | ||
| 262 | 262 | __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK))); |
| 263 | 263 | __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK))); |
| 264 | 264 | |
| 265 | − /* | |
| 266 | − * Note that the timer interrupts are also mapped, but this is | |
| 267 | − * done in sb1250_time_init(). Also, the profiling driver | |
| 268 | − * does its own management of IP7. | |
| 269 | − */ | |
| 270 | − | |
| 271 | 265 | /* Enable necessary IPs, disable the rest */ |
| 272 | 266 | change_c0_status(ST0_IM, imask); |
| 273 | 267 | } |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <asm-generic/sections.h> |
| 6 | 6 | |
| 7 | −extern long __machvec_start, __machvec_end; | |
| 7 | +extern char __machvec_start[], __machvec_end[]; | |
| 8 | 8 | extern char __uncached_start, __uncached_end; |
| 9 | 9 | extern char __start_eh_frame[], __stop_eh_frame[]; |
| 10 | 10 | |
| @@ -20,8 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | #define MV_NAME_SIZE 32 |
| 21 | 21 | |
| 22 | 22 | #define for_each_mv(mv) \ |
| 23 | − for ((mv) = (struct sh_machine_vector *)&__machvec_start; \ | |
| 24 | − (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \ | |
| 23 | + for ((mv) = (struct sh_machine_vector *)__machvec_start; \ | |
| 24 | + (mv) && (unsigned long)(mv) < (unsigned long)__machvec_end; \ | |
| 25 | 25 | (mv)++) |
| 26 | 26 | |
| 27 | 27 | static struct sh_machine_vector * __init get_mv_byname(const char *name) |
| @@ -87,8 +87,8 @@ void __init sh_mv_setup(void) · 59 unmodified lines | ||
| 87 | 87 | if (!machvec_selected) { |
| 88 | 88 | unsigned long machvec_size; |
| 89 | 89 | |
| 90 | − machvec_size = ((unsigned long)&__machvec_end - | |
| 91 | − (unsigned long)&__machvec_start); | |
| 90 | + machvec_size = ((unsigned long)__machvec_end - | |
| 91 | + (unsigned long)__machvec_start); | |
| 92 | 92 | |
| 93 | 93 | /* |
| 94 | 94 | * Sanity check for machvec section alignment. Ensure |
| @@ -102,7 +102,7 @@ void __init sh_mv_setup(void) · 7 unmodified lines | ||
| 102 | 102 | * vector (usually the only one) from .machvec.init. |
| 103 | 103 | */ |
| 104 | 104 | if (machvec_size >= sizeof(struct sh_machine_vector)) |
| 105 | − sh_mv = *(struct sh_machine_vector *)&__machvec_start; | |
| 105 | + sh_mv = *(struct sh_machine_vector *)__machvec_start; | |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | pr_notice("Booting machvec: %s\n", get_system_type()); |
| @@ -33,9 +33,6 @@ extern volatile unsigned long cpu_callin_map[NR_CPUS]; · 32 unmodified lines | ||
| 33 | 33 | extern cpumask_t smp_commenced_mask; |
| 34 | 34 | extern struct linux_prom_registers smp_penguin_ctable; |
| 35 | 35 | |
| 36 | −typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, | |
| 37 | − unsigned long, unsigned long); | |
| 38 | − | |
| 39 | 36 | void cpu_panic(void); |
| 40 | 37 | |
| 41 | 38 | /* |
| @@ -57,7 +54,7 @@ void smp_bogo(struct seq_file *); · 15 unmodified lines | ||
| 57 | 54 | void smp_info(struct seq_file *); |
| 58 | 55 | |
| 59 | 56 | struct sparc32_ipi_ops { |
| 60 | − void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1, | |
| 57 | + void (*cross_call)(void *func, cpumask_t mask, unsigned long arg1, | |
| 61 | 58 | unsigned long arg2, unsigned long arg3, |
| 62 | 59 | unsigned long arg4); |
| 63 | 60 | void (*resched)(int cpu); |
| @@ -66,28 +63,28 @@ struct sparc32_ipi_ops { · 2 unmodified lines | ||
| 66 | 63 | }; |
| 67 | 64 | extern const struct sparc32_ipi_ops *sparc32_ipi_ops; |
| 68 | 65 | |
| 69 | −static inline void xc0(smpfunc_t func) | |
| 66 | +static inline void xc0(void *func) | |
| 70 | 67 | { |
| 71 | 68 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0); |
| 72 | 69 | } |
| 73 | 70 | |
| 74 | −static inline void xc1(smpfunc_t func, unsigned long arg1) | |
| 71 | +static inline void xc1(void *func, unsigned long arg1) | |
| 75 | 72 | { |
| 76 | 73 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); |
| 77 | 74 | } |
| 78 | −static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) | |
| 75 | +static inline void xc2(void *func, unsigned long arg1, unsigned long arg2) | |
| 79 | 76 | { |
| 80 | 77 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); |
| 81 | 78 | } |
| 82 | 79 | |
| 83 | −static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |
| 80 | +static inline void xc3(void *func, unsigned long arg1, unsigned long arg2, | |
| 84 | 81 | unsigned long arg3) |
| 85 | 82 | { |
| 86 | 83 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, |
| 87 | 84 | arg1, arg2, arg3, 0); |
| 88 | 85 | } |
| 89 | 86 | |
| 90 | −static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |
| 87 | +static inline void xc4(void *func, unsigned long arg1, unsigned long arg2, | |
| 91 | 88 | unsigned long arg3, unsigned long arg4) |
| 92 | 89 | { |
| 93 | 90 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, |
| @@ -359,7 +359,7 @@ void leonsmp_ipi_interrupt(void) · 358 unmodified lines | ||
| 359 | 359 | } |
| 360 | 360 | |
| 361 | 361 | static struct smp_funcall { |
| 362 | − smpfunc_t func; | |
| 362 | + void *func; | |
| 363 | 363 | unsigned long arg1; |
| 364 | 364 | unsigned long arg2; |
| 365 | 365 | unsigned long arg3; |
| @@ -372,7 +372,7 @@ static struct smp_funcall { · 6 unmodified lines | ||
| 372 | 372 | static DEFINE_SPINLOCK(cross_call_lock); |
| 373 | 373 | |
| 374 | 374 | /* Cross calls must be serialized, at least currently. */ |
| 375 | −static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | |
| 375 | +static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1, | |
| 376 | 376 | unsigned long arg2, unsigned long arg3, |
| 377 | 377 | unsigned long arg4) |
| 378 | 378 | { |
| @@ -384,7 +384,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, · 5 unmodified lines | ||
| 384 | 384 | |
| 385 | 385 | { |
| 386 | 386 | /* If you make changes here, make sure gcc generates proper code... */ |
| 387 | − register smpfunc_t f asm("i0") = func; | |
| 387 | + register void *f asm("i0") = func; | |
| 388 | 388 | register unsigned long a1 asm("i1") = arg1; |
| 389 | 389 | register unsigned long a2 asm("i2") = arg2; |
| 390 | 390 | register unsigned long a3 asm("i3") = arg3; |
| @@ -444,11 +444,13 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, · 53 unmodified lines | ||
| 444 | 444 | /* Running cross calls. */ |
| 445 | 445 | void leon_cross_call_irq(void) |
| 446 | 446 | { |
| 447 | + void (*func)(unsigned long, unsigned long, unsigned long, unsigned long, | |
| 448 | + unsigned long) = ccall_info.func; | |
| 447 | 449 | int i = smp_processor_id(); |
| 448 | 450 | |
| 449 | 451 | ccall_info.processors_in[i] = 1; |
| 450 | − ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, | |
| 451 | − ccall_info.arg4, ccall_info.arg5); | |
| 452 | + func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4, | |
| 453 | + ccall_info.arg5); | |
| 452 | 454 | ccall_info.processors_out[i] = 1; |
| 453 | 455 | } |
| 454 | 456 | |
| @@ -268,7 +268,7 @@ static void sun4d_ipi_resched(int cpu) · 267 unmodified lines | ||
| 268 | 268 | } |
| 269 | 269 | |
| 270 | 270 | static struct smp_funcall { |
| 271 | − smpfunc_t func; | |
| 271 | + void *func; | |
| 272 | 272 | unsigned long arg1; |
| 273 | 273 | unsigned long arg2; |
| 274 | 274 | unsigned long arg3; |
| @@ -281,7 +281,7 @@ static struct smp_funcall { · 6 unmodified lines | ||
| 281 | 281 | static DEFINE_SPINLOCK(cross_call_lock); |
| 282 | 282 | |
| 283 | 283 | /* Cross calls must be serialized, at least currently. */ |
| 284 | −static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | |
| 284 | +static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1, | |
| 285 | 285 | unsigned long arg2, unsigned long arg3, |
| 286 | 286 | unsigned long arg4) |
| 287 | 287 | { |
| @@ -296,7 +296,7 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, · 8 unmodified lines | ||
| 296 | 296 | * If you make changes here, make sure |
| 297 | 297 | * gcc generates proper code... |
| 298 | 298 | */ |
| 299 | − register smpfunc_t f asm("i0") = func; | |
| 299 | + register void *f asm("i0") = func; | |
| 300 | 300 | register unsigned long a1 asm("i1") = arg1; |
| 301 | 301 | register unsigned long a2 asm("i2") = arg2; |
| 302 | 302 | register unsigned long a3 asm("i3") = arg3; |
| @@ -353,11 +353,13 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, · 50 unmodified lines | ||
| 353 | 353 | /* Running cross calls. */ |
| 354 | 354 | void smp4d_cross_call_irq(void) |
| 355 | 355 | { |
| 356 | + void (*func)(unsigned long, unsigned long, unsigned long, unsigned long, | |
| 357 | + unsigned long) = ccall_info.func; | |
| 356 | 358 | int i = hard_smp_processor_id(); |
| 357 | 359 | |
| 358 | 360 | ccall_info.processors_in[i] = 1; |
| 359 | − ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, | |
| 360 | − ccall_info.arg4, ccall_info.arg5); | |
| 361 | + func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4, | |
| 362 | + ccall_info.arg5); | |
| 361 | 363 | ccall_info.processors_out[i] = 1; |
| 362 | 364 | } |
| 363 | 365 | |
| @@ -157,7 +157,7 @@ static void sun4m_ipi_mask_one(int cpu) · 156 unmodified lines | ||
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | static struct smp_funcall { |
| 160 | − smpfunc_t func; | |
| 160 | + void *func; | |
| 161 | 161 | unsigned long arg1; |
| 162 | 162 | unsigned long arg2; |
| 163 | 163 | unsigned long arg3; |
| @@ -170,7 +170,7 @@ static struct smp_funcall { · 6 unmodified lines | ||
| 170 | 170 | static DEFINE_SPINLOCK(cross_call_lock); |
| 171 | 171 | |
| 172 | 172 | /* Cross calls must be serialized, at least currently. */ |
| 173 | −static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | |
| 173 | +static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1, | |
| 174 | 174 | unsigned long arg2, unsigned long arg3, |
| 175 | 175 | unsigned long arg4) |
| 176 | 176 | { |
| @@ -230,11 +230,13 @@ static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, · 53 unmodified lines | ||
| 230 | 230 | /* Running cross calls. */ |
| 231 | 231 | void smp4m_cross_call_irq(void) |
| 232 | 232 | { |
| 233 | + void (*func)(unsigned long, unsigned long, unsigned long, unsigned long, | |
| 234 | + unsigned long) = ccall_info.func; | |
| 233 | 235 | int i = smp_processor_id(); |
| 234 | 236 | |
| 235 | 237 | ccall_info.processors_in[i] = 1; |
| 236 | − ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, | |
| 237 | − ccall_info.arg4, ccall_info.arg5); | |
| 238 | + func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4, | |
| 239 | + ccall_info.arg5); | |
| 238 | 240 | ccall_info.processors_out[i] = 1; |
| 239 | 241 | } |
| 240 | 242 | |
| @@ -1636,19 +1636,19 @@ static void __init get_srmmu_type(void) · 1635 unmodified lines | ||
| 1636 | 1636 | /* Local cross-calls. */ |
| 1637 | 1637 | static void smp_flush_page_for_dma(unsigned long page) |
| 1638 | 1638 | { |
| 1639 | − xc1((smpfunc_t) local_ops->page_for_dma, page); | |
| 1639 | + xc1(local_ops->page_for_dma, page); | |
| 1640 | 1640 | local_ops->page_for_dma(page); |
| 1641 | 1641 | } |
| 1642 | 1642 | |
| 1643 | 1643 | static void smp_flush_cache_all(void) |
| 1644 | 1644 | { |
| 1645 | − xc0((smpfunc_t) local_ops->cache_all); | |
| 1645 | + xc0(local_ops->cache_all); | |
| 1646 | 1646 | local_ops->cache_all(); |
| 1647 | 1647 | } |
| 1648 | 1648 | |
| 1649 | 1649 | static void smp_flush_tlb_all(void) |
| 1650 | 1650 | { |
| 1651 | − xc0((smpfunc_t) local_ops->tlb_all); | |
| 1651 | + xc0(local_ops->tlb_all); | |
| 1652 | 1652 | local_ops->tlb_all(); |
| 1653 | 1653 | } |
| 1654 | 1654 | |
| @@ -1659,7 +1659,7 @@ static void smp_flush_cache_mm(struct mm_struct *mm) · 4 unmodified lines | ||
| 1659 | 1659 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1660 | 1660 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1661 | 1661 | if (!cpumask_empty(&cpu_mask)) |
| 1662 | − xc1((smpfunc_t) local_ops->cache_mm, (unsigned long) mm); | |
| 1662 | + xc1(local_ops->cache_mm, (unsigned long)mm); | |
| 1663 | 1663 | local_ops->cache_mm(mm); |
| 1664 | 1664 | } |
| 1665 | 1665 | } |
| @@ -1671,7 +1671,7 @@ static void smp_flush_tlb_mm(struct mm_struct *mm) · 5 unmodified lines | ||
| 1671 | 1671 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1672 | 1672 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1673 | 1673 | if (!cpumask_empty(&cpu_mask)) { |
| 1674 | − xc1((smpfunc_t) local_ops->tlb_mm, (unsigned long) mm); | |
| 1674 | + xc1(local_ops->tlb_mm, (unsigned long)mm); | |
| 1675 | 1675 | if (atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) |
| 1676 | 1676 | cpumask_copy(mm_cpumask(mm), |
| 1677 | 1677 | cpumask_of(smp_processor_id())); |
| @@ -1691,8 +1691,8 @@ static void smp_flush_cache_range(struct vm_area_struct *vma, · 13 unmodified lines | ||
| 1691 | 1691 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1692 | 1692 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1693 | 1693 | if (!cpumask_empty(&cpu_mask)) |
| 1694 | − xc3((smpfunc_t) local_ops->cache_range, | |
| 1695 | − (unsigned long) vma, start, end); | |
| 1694 | + xc3(local_ops->cache_range, (unsigned long)vma, start, | |
| 1695 | + end); | |
| 1696 | 1696 | local_ops->cache_range(vma, start, end); |
| 1697 | 1697 | } |
| 1698 | 1698 | } |
| @@ -1708,8 +1708,8 @@ static void smp_flush_tlb_range(struct vm_area_struct *vma, · 9 unmodified lines | ||
| 1708 | 1708 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1709 | 1709 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1710 | 1710 | if (!cpumask_empty(&cpu_mask)) |
| 1711 | − xc3((smpfunc_t) local_ops->tlb_range, | |
| 1712 | − (unsigned long) vma, start, end); | |
| 1711 | + xc3(local_ops->tlb_range, (unsigned long)vma, start, | |
| 1712 | + end); | |
| 1713 | 1713 | local_ops->tlb_range(vma, start, end); |
| 1714 | 1714 | } |
| 1715 | 1715 | } |
| @@ -1723,8 +1723,7 @@ static void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) · 7 unmodified lines | ||
| 1723 | 1723 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1724 | 1724 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1725 | 1725 | if (!cpumask_empty(&cpu_mask)) |
| 1726 | − xc2((smpfunc_t) local_ops->cache_page, | |
| 1727 | − (unsigned long) vma, page); | |
| 1726 | + xc2(local_ops->cache_page, (unsigned long)vma, page); | |
| 1728 | 1727 | local_ops->cache_page(vma, page); |
| 1729 | 1728 | } |
| 1730 | 1729 | } |
| @@ -1738,8 +1737,7 @@ static void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) · 7 unmodified lines | ||
| 1738 | 1737 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1739 | 1738 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1740 | 1739 | if (!cpumask_empty(&cpu_mask)) |
| 1741 | − xc2((smpfunc_t) local_ops->tlb_page, | |
| 1742 | − (unsigned long) vma, page); | |
| 1740 | + xc2(local_ops->tlb_page, (unsigned long)vma, page); | |
| 1743 | 1741 | local_ops->tlb_page(vma, page); |
| 1744 | 1742 | } |
| 1745 | 1743 | } |
| @@ -1753,7 +1751,7 @@ static void smp_flush_page_to_ram(unsigned long page) · 7 unmodified lines | ||
| 1753 | 1751 | * XXX This experiment failed, research further... -DaveM |
| 1754 | 1752 | */ |
| 1755 | 1753 | #if 1 |
| 1756 | − xc1((smpfunc_t) local_ops->page_to_ram, page); | |
| 1754 | + xc1(local_ops->page_to_ram, page); | |
| 1757 | 1755 | #endif |
| 1758 | 1756 | local_ops->page_to_ram(page); |
| 1759 | 1757 | } |
| @@ -1764,8 +1762,7 @@ static void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) · 4 unmodified lines | ||
| 1764 | 1762 | cpumask_copy(&cpu_mask, mm_cpumask(mm)); |
| 1765 | 1763 | cpumask_clear_cpu(smp_processor_id(), &cpu_mask); |
| 1766 | 1764 | if (!cpumask_empty(&cpu_mask)) |
| 1767 | − xc2((smpfunc_t) local_ops->sig_insns, | |
| 1768 | − (unsigned long) mm, insn_addr); | |
| 1765 | + xc2(local_ops->sig_insns, (unsigned long)mm, insn_addr); | |
| 1769 | 1766 | local_ops->sig_insns(mm, insn_addr); |
| 1770 | 1767 | } |
| 1771 | 1768 | |
| @@ -6,6 +6,7 @@ config UML · 5 unmodified lines | ||
| 6 | 6 | bool |
| 7 | 7 | default y |
| 8 | 8 | select ARCH_EPHEMERAL_INODES |
| 9 | + select ARCH_HAS_FORTIFY_SOURCE | |
| 9 | 10 | select ARCH_HAS_GCOV_PROFILE_ALL |
| 10 | 11 | select ARCH_HAS_KCOV |
| 11 | 12 | select ARCH_HAS_STRNCPY_FROM_USER |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | +#define __NO_FORTIFY | |
| 2 | 3 | #include <linux/types.h> |
| 3 | 4 | #include <linux/module.h> |
| 4 | 5 | |
| @@ -107,6 +107,8 @@ config X86 · 106 unmodified lines | ||
| 107 | 107 | select ARCH_SUPPORTS_PAGE_TABLE_CHECK if X86_64 |
| 108 | 108 | select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 |
| 109 | 109 | select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096 |
| 110 | + select ARCH_SUPPORTS_CFI_CLANG if X86_64 | |
| 111 | + select ARCH_USES_CFI_TRAPS if X86_64 && CFI_CLANG | |
| 110 | 112 | select ARCH_SUPPORTS_LTO_CLANG |
| 111 | 113 | select ARCH_SUPPORTS_LTO_CLANG_THIN |
| 112 | 114 | select ARCH_USE_BUILTIN_BSWAP |
| @@ -257,6 +259,7 @@ config X86 · 144 unmodified lines | ||
| 257 | 259 | select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL |
| 258 | 260 | select HAVE_PREEMPT_DYNAMIC_CALL |
| 259 | 261 | select HAVE_RSEQ |
| 262 | + select HAVE_RUST if X86_64 | |
| 260 | 263 | select HAVE_SYSCALL_TRACEPOINTS |
| 261 | 264 | select HAVE_UACCESS_VALIDATION if HAVE_OBJTOOL |
| 262 | 265 | select HAVE_UNSTABLE_SCHED_CLOCK |
| @@ -284,6 +287,7 @@ config X86 · 21 unmodified lines | ||
| 284 | 287 | select PROC_PID_ARCH_STATUS if PROC_FS |
| 285 | 288 | select HAVE_ARCH_NODE_DEV_GROUP if X86_SGX |
| 286 | 289 | imply IMA_SECURE_AND_OR_TRUSTED_BOOT if EFI |
| 290 | + select HAVE_DYNAMIC_FTRACE_NO_PATCHABLE | |
| 287 | 291 | |
| 288 | 292 | config INSTRUCTION_DECODER |
| 289 | 293 | def_bool y |
| @@ -448,6 +452,11 @@ config X86_X2APIC · 158 unmodified lines | ||
| 448 | 452 | This allows 32-bit apic IDs (so it can support very large systems), |
| 449 | 453 | and accesses the local apic via MSRs not via mmio. |
| 450 | 454 | |
| 455 | + Some Intel systems circa 2022 and later are locked into x2APIC mode | |
| 456 | + and can not fall back to the legacy APIC modes if SGX or TDX are | |
| 457 | + enabled in the BIOS. They will be unable to boot without enabling | |
| 458 | + this option. | |
| 459 | + | |
| 451 | 460 | If you don't know what to do here, say N. |
| 452 | 461 | |
| 453 | 462 | config X86_MPPARSE |
| @@ -1919,7 +1928,7 @@ endchoice · 1465 unmodified lines | ||
| 1919 | 1928 | |
| 1920 | 1929 | config X86_SGX |
| 1921 | 1930 | bool "Software Guard eXtensions (SGX)" |
| 1922 | − depends on X86_64 && CPU_SUP_INTEL | |
| 1931 | + depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC | |
| 1923 | 1932 | depends on CRYPTO=y |
| 1924 | 1933 | depends on CRYPTO_SHA256=y |
| 1925 | 1934 | select SRCU |
| @@ -2569,7 +2578,7 @@ menuconfig APM · 643 unmodified lines | ||
| 2569 | 2578 | |
| 2570 | 2579 | 1) make sure that you have enough swap space and that it is |
| 2571 | 2580 | enabled. |
| 2572 | − 2) pass the "no-hlt" option to the kernel | |
| 2581 | + 2) pass the "idle=poll" option to the kernel | |
| 2573 | 2582 | 3) switch on floating point emulation in the kernel and pass |
| 2574 | 2583 | the "no387" option to the kernel |
| 2575 | 2584 | 4) pass the "floppy=nodma" option to the kernel |
| @@ -68,6 +68,7 @@ export BITS · 67 unmodified lines | ||
| 68 | 68 | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 |
| 69 | 69 | # |
| 70 | 70 | KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx |
| 71 | +KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2 | |
| 71 | 72 | |
| 72 | 73 | ifeq ($(CONFIG_X86_KERNEL_IBT),y) |
| 73 | 74 | # |
| @@ -155,8 +156,17 @@ else · 81 unmodified lines | ||
| 155 | 156 | cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic |
| 156 | 157 | KBUILD_CFLAGS += $(cflags-y) |
| 157 | 158 | |
| 159 | + rustflags-$(CONFIG_MK8) += -Ctarget-cpu=k8 | |
| 160 | + rustflags-$(CONFIG_MPSC) += -Ctarget-cpu=nocona | |
| 161 | + rustflags-$(CONFIG_MCORE2) += -Ctarget-cpu=core2 | |
| 162 | + rustflags-$(CONFIG_MATOM) += -Ctarget-cpu=atom | |
| 163 | + rustflags-$(CONFIG_GENERIC_CPU) += -Ztune-cpu=generic | |
| 164 | + KBUILD_RUSTFLAGS += $(rustflags-y) | |
| 165 | + | |
| 158 | 166 | KBUILD_CFLAGS += -mno-red-zone |
| 159 | 167 | KBUILD_CFLAGS += -mcmodel=kernel |
| 168 | + KBUILD_RUSTFLAGS += -Cno-redzone=y | |
| 169 | + KBUILD_RUSTFLAGS += -Ccode-model=kernel | |
| 160 | 170 | endif |
| 161 | 171 | |
| 162 | 172 | # |
| @@ -19,13 +19,13 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | static inline bool constant_test_bit(int nr, const void *addr) |
| 21 | 21 | { |
| 22 | − const u32 *p = (const u32 *)addr; | |
| 22 | + const u32 *p = addr; | |
| 23 | 23 | return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0; |
| 24 | 24 | } |
| 25 | 25 | static inline bool variable_test_bit(int nr, const void *addr) |
| 26 | 26 | { |
| 27 | 27 | bool v; |
| 28 | − const u32 *p = (const u32 *)addr; | |
| 28 | + const u32 *p = addr; | |
| 29 | 29 | |
| 30 | 30 | asm("btl %2,%1" CC_SET(c) : CC_OUT(c) (v) : "m" (*p), "Ir" (nr)); |
| 31 | 31 | return v; |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/linkage.h> |
| 9 | +#include <linux/cfi_types.h> | |
| 9 | 10 | |
| 10 | 11 | .file "blowfish-x86_64-asm.S" |
| 11 | 12 | .text |
| @@ -141,7 +142,7 @@ SYM_FUNC_START(__blowfish_enc_blk) · 129 unmodified lines | ||
| 141 | 142 | RET; |
| 142 | 143 | SYM_FUNC_END(__blowfish_enc_blk) |
| 143 | 144 | |
| 144 | −SYM_FUNC_START(blowfish_dec_blk) | |
| 145 | +SYM_TYPED_FUNC_START(blowfish_dec_blk) | |
| 145 | 146 | /* input: |
| 146 | 147 | * %rdi: ctx |
| 147 | 148 | * %rsi: dst |
| @@ -332,7 +333,7 @@ SYM_FUNC_START(__blowfish_enc_blk_4way) · 184 unmodified lines | ||
| 332 | 333 | RET; |
| 333 | 334 | SYM_FUNC_END(__blowfish_enc_blk_4way) |
| 334 | 335 | |
| 335 | −SYM_FUNC_START(blowfish_dec_blk_4way) | |
| 336 | +SYM_TYPED_FUNC_START(blowfish_dec_blk_4way) | |
| 336 | 337 | /* input: |
| 337 | 338 | * %rdi: ctx |
| 338 | 339 | * %rsi: dst |
| @@ -91,7 +91,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),) · 90 unmodified lines | ||
| 91 | 91 | endif |
| 92 | 92 | endif |
| 93 | 93 | |
| 94 | −$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) | |
| 94 | +$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) | |
| 95 | 95 | $(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO |
| 96 | 96 | |
| 97 | 97 | # |
| @@ -153,6 +153,7 @@ KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32)) · 55 unmodified lines | ||
| 153 | 153 | KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) |
| 154 | 154 | KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32)) |
| 155 | 155 | KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32)) |
| 156 | +KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_CFI),$(KBUILD_CFLAGS_32)) | |
| 156 | 157 | KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic |
| 157 | 158 | KBUILD_CFLAGS_32 += -fno-stack-protector |
| 158 | 159 | KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) |
| @@ -2102,6 +2102,15 @@ static struct extra_reg intel_tnt_extra_regs[] __read_mostly = { · 2101 unmodified lines | ||
| 2102 | 2102 | EVENT_EXTRA_END |
| 2103 | 2103 | }; |
| 2104 | 2104 | |
| 2105 | +EVENT_ATTR_STR(mem-loads, mem_ld_grt, "event=0xd0,umask=0x5,ldlat=3"); | |
| 2106 | +EVENT_ATTR_STR(mem-stores, mem_st_grt, "event=0xd0,umask=0x6"); | |
| 2107 | + | |
| 2108 | +static struct attribute *grt_mem_attrs[] = { | |
| 2109 | + EVENT_PTR(mem_ld_grt), | |
| 2110 | + EVENT_PTR(mem_st_grt), | |
| 2111 | + NULL | |
| 2112 | +}; | |
| 2113 | + | |
| 2105 | 2114 | static struct extra_reg intel_grt_extra_regs[] __read_mostly = { |
| 2106 | 2115 | /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ |
| 2107 | 2116 | INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), |
| @@ -5975,6 +5984,36 @@ __init int intel_pmu_init(void) · 3867 unmodified lines | ||
| 5975 | 5984 | name = "Tremont"; |
| 5976 | 5985 | break; |
| 5977 | 5986 | |
| 5987 | + case INTEL_FAM6_ALDERLAKE_N: | |
| 5988 | + x86_pmu.mid_ack = true; | |
| 5989 | + memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, | |
| 5990 | + sizeof(hw_cache_event_ids)); | |
| 5991 | + memcpy(hw_cache_extra_regs, tnt_hw_cache_extra_regs, | |
| 5992 | + sizeof(hw_cache_extra_regs)); | |
| 5993 | + hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1; | |
| 5994 | + | |
| 5995 | + x86_pmu.event_constraints = intel_slm_event_constraints; | |
| 5996 | + x86_pmu.pebs_constraints = intel_grt_pebs_event_constraints; | |
| 5997 | + x86_pmu.extra_regs = intel_grt_extra_regs; | |
| 5998 | + | |
| 5999 | + x86_pmu.pebs_aliases = NULL; | |
| 6000 | + x86_pmu.pebs_prec_dist = true; | |
| 6001 | + x86_pmu.pebs_block = true; | |
| 6002 | + x86_pmu.lbr_pt_coexist = true; | |
| 6003 | + x86_pmu.flags |= PMU_FL_HAS_RSP_1; | |
| 6004 | + x86_pmu.flags |= PMU_FL_INSTR_LATENCY; | |
| 6005 | + | |
| 6006 | + intel_pmu_pebs_data_source_grt(); | |
| 6007 | + x86_pmu.pebs_latency_data = adl_latency_data_small; | |
| 6008 | + x86_pmu.get_event_constraints = tnt_get_event_constraints; | |
| 6009 | + x86_pmu.limit_period = spr_limit_period; | |
| 6010 | + td_attr = tnt_events_attrs; | |
| 6011 | + mem_attr = grt_mem_attrs; | |
| 6012 | + extra_attr = nhm_format_attr; | |
| 6013 | + pr_cont("Gracemont events, "); | |
| 6014 | + name = "gracemont"; | |
| 6015 | + break; | |
| 6016 | + | |
| 5978 | 6017 | case INTEL_FAM6_WESTMERE: |
| 5979 | 6018 | case INTEL_FAM6_WESTMERE_EP: |
| 5980 | 6019 | case INTEL_FAM6_WESTMERE_EX: |
| @@ -6317,7 +6356,6 @@ __init int intel_pmu_init(void) · 336 unmodified lines | ||
| 6317 | 6356 | |
| 6318 | 6357 | case INTEL_FAM6_ALDERLAKE: |
| 6319 | 6358 | case INTEL_FAM6_ALDERLAKE_L: |
| 6320 | − case INTEL_FAM6_ALDERLAKE_N: | |
| 6321 | 6359 | case INTEL_FAM6_RAPTORLAKE: |
| 6322 | 6360 | case INTEL_FAM6_RAPTORLAKE_P: |
| 6323 | 6361 | /* |
| @@ -110,13 +110,18 @@ void __init intel_pmu_pebs_data_source_skl(bool pmem) · 109 unmodified lines | ||
| 110 | 110 | __intel_pmu_pebs_data_source_skl(pmem, pebs_data_source); |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | −static void __init intel_pmu_pebs_data_source_grt(u64 *data_source) | |
| 113 | +static void __init __intel_pmu_pebs_data_source_grt(u64 *data_source) | |
| 114 | 114 | { |
| 115 | 115 | data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); |
| 116 | 116 | data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); |
| 117 | 117 | data_source[0x08] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD); |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | +void __init intel_pmu_pebs_data_source_grt(void) | |
| 121 | +{ | |
| 122 | + __intel_pmu_pebs_data_source_grt(pebs_data_source); | |
| 123 | +} | |
| 124 | + | |
| 120 | 125 | void __init intel_pmu_pebs_data_source_adl(void) |
| 121 | 126 | { |
| 122 | 127 | u64 *data_source; |
| @@ -127,7 +132,7 @@ void __init intel_pmu_pebs_data_source_adl(void) · 4 unmodified lines | ||
| 127 | 132 | |
| 128 | 133 | data_source = x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX].pebs_data_source; |
| 129 | 134 | memcpy(data_source, pebs_data_source, sizeof(pebs_data_source)); |
| 130 | − intel_pmu_pebs_data_source_grt(data_source); | |
| 135 | + __intel_pmu_pebs_data_source_grt(data_source); | |
| 131 | 136 | } |
| 132 | 137 | |
| 133 | 138 | static u64 precise_store_data(u64 status) |
| @@ -1516,6 +1516,8 @@ void intel_pmu_pebs_data_source_skl(bool pmem); · 1515 unmodified lines | ||
| 1516 | 1516 | |
| 1517 | 1517 | void intel_pmu_pebs_data_source_adl(void); |
| 1518 | 1518 | |
| 1519 | +void intel_pmu_pebs_data_source_grt(void); | |
| 1520 | + | |
| 1519 | 1521 | int intel_pmu_setup_lbr_filter(struct perf_event *event); |
| 1520 | 1522 | |
| 1521 | 1523 | void intel_pt_interrupt(void); |
| @@ -10,6 +10,15 @@ · 9 unmodified lines | ||
| 10 | 10 | /* Bit 0 indicates whether guest VM is privileged */ |
| 11 | 11 | #define ACRN_FEATURE_PRIVILEGED_VM BIT(0) |
| 12 | 12 | |
| 13 | +/* | |
| 14 | + * Timing Information. | |
| 15 | + * This leaf returns the current TSC frequency in kHz. | |
| 16 | + * | |
| 17 | + * EAX: (Virtual) TSC frequency in kHz. | |
| 18 | + * EBX, ECX, EDX: RESERVED (reserved fields are set to zero). | |
| 19 | + */ | |
| 20 | +#define ACRN_CPUID_TIMING_INFO 0x40000010 | |
| 21 | + | |
| 13 | 22 | void acrn_setup_intr_handler(void (*handler)(void)); |
| 14 | 23 | void acrn_remove_intr_handler(void); |
| 15 | 24 | |
| @@ -21,6 +30,11 @@ static inline u32 acrn_cpuid_base(void) · 5 unmodified lines | ||
| 21 | 30 | return 0; |
| 22 | 31 | } |
| 23 | 32 | |
| 33 | +static inline unsigned long acrn_get_tsc_khz(void) | |
| 34 | +{ | |
| 35 | + return cpuid_eax(ACRN_CPUID_TIMING_INFO); | |
| 36 | +} | |
| 37 | + | |
| 24 | 38 | /* |
| 25 | 39 | * Hypercalls for ACRN |
| 26 | 40 | * |
| @@ -247,17 +247,30 @@ arch_test_bit_acquire(unsigned long nr, const volatile unsigned long *addr) · 246 unmodified lines | ||
| 247 | 247 | variable_test_bit(nr, addr); |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | +static __always_inline unsigned long variable__ffs(unsigned long word) | |
| 251 | +{ | |
| 252 | + asm("rep; bsf %1,%0" | |
| 253 | + : "=r" (word) | |
| 254 | + : "rm" (word)); | |
| 255 | + return word; | |
| 256 | +} | |
| 257 | + | |
| 250 | 258 | /** |
| 251 | 259 | * __ffs - find first set bit in word |
| 252 | 260 | * @word: The word to search |
| 253 | 261 | * |
| 254 | 262 | * Undefined if no bit exists, so code should check against 0 first. |
| 255 | 263 | */ |
| 256 | −static __always_inline unsigned long __ffs(unsigned long word) | |
| 264 | +#define __ffs(word) \ | |
| 265 | + (__builtin_constant_p(word) ? \ | |
| 266 | + (unsigned long)__builtin_ctzl(word) : \ | |
| 267 | + variable__ffs(word)) | |
| 268 | + | |
| 269 | +static __always_inline unsigned long variable_ffz(unsigned long word) | |
| 257 | 270 | { |
| 258 | 271 | asm("rep; bsf %1,%0" |
| 259 | 272 | : "=r" (word) |
| 260 | − : "rm" (word)); | |
| 273 | + : "r" (~word)); | |
| 261 | 274 | return word; |
| 262 | 275 | } |
| 263 | 276 | |
| @@ -267,13 +280,10 @@ static __always_inline unsigned long __ffs(unsigned long word) · 3 unmodified lines | ||
| 267 | 280 | * |
| 268 | 281 | * Undefined if no zero exists, so code should check against ~0UL first. |
| 269 | 282 | */ |
| 270 | −static __always_inline unsigned long ffz(unsigned long word) | |
| 271 | −{ | |
| 272 | − asm("rep; bsf %1,%0" | |
| 273 | − : "=r" (word) | |
| 274 | − : "r" (~word)); | |
| 275 | − return word; | |
| 276 | −} | |
| 283 | +#define ffz(word) \ | |
| 284 | + (__builtin_constant_p(word) ? \ | |
| 285 | + (unsigned long)__builtin_ctzl(~word) : \ | |
| 286 | + variable_ffz(word)) | |
| 277 | 287 | |
| 278 | 288 | /* |
| 279 | 289 | * __fls: find last set bit in word |
| @@ -292,18 +302,7 @@ static __always_inline unsigned long __fls(unsigned long word) · 12 unmodified lines | ||
| 292 | 302 | #undef ADDR |
| 293 | 303 | |
| 294 | 304 | #ifdef __KERNEL__ |
| 295 | −/** | |
| 296 | − * ffs - find first set bit in word | |
| 297 | − * @x: the word to search | |
| 298 | − * | |
| 299 | − * This is defined the same way as the libc and compiler builtin ffs | |
| 300 | − * routines, therefore differs in spirit from the other bitops. | |
| 301 | − * | |
| 302 | − * ffs(value) returns 0 if value is 0 or the position of the first | |
| 303 | − * set bit if value is nonzero. The first (least significant) bit | |
| 304 | − * is at position 1. | |
| 305 | − */ | |
| 306 | −static __always_inline int ffs(int x) | |
| 305 | +static __always_inline int variable_ffs(int x) | |
| 307 | 306 | { |
| 308 | 307 | int r; |
| 309 | 308 | |
| @@ -333,6 +332,19 @@ static __always_inline int ffs(int x) · 23 unmodified lines | ||
| 333 | 332 | return r + 1; |
| 334 | 333 | } |
| 335 | 334 | |
| 335 | +/** | |
| 336 | + * ffs - find first set bit in word | |
| 337 | + * @x: the word to search | |
| 338 | + * | |
| 339 | + * This is defined the same way as the libc and compiler builtin ffs | |
| 340 | + * routines, therefore differs in spirit from the other bitops. | |
| 341 | + * | |
| 342 | + * ffs(value) returns 0 if value is 0 or the position of the first | |
| 343 | + * set bit if value is nonzero. The first (least significant) bit | |
| 344 | + * is at position 1. | |
| 345 | + */ | |
| 346 | +#define ffs(x) (__builtin_constant_p(x) ? __builtin_ffs(x) : variable_ffs(x)) | |
| 347 | + | |
| 336 | 348 | /** |
| 337 | 349 | * fls - find last set bit in word |
| 338 | 350 | * @x: the word to search |
| @@ -0,0 +1,22 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef _ASM_X86_CFI_H | |
| 3 | +#define _ASM_X86_CFI_H | |
| 4 | + | |
| 5 | +/* | |
| 6 | + * Clang Control Flow Integrity (CFI) support. | |
| 7 | + * | |
| 8 | + * Copyright (C) 2022 Google LLC | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <linux/cfi.h> | |
| 12 | + | |
| 13 | +#ifdef CONFIG_CFI_CLANG | |
| 14 | +enum bug_trap_type handle_cfi_failure(struct pt_regs *regs); | |
| 15 | +#else | |
| 16 | +static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs) | |
| 17 | +{ | |
| 18 | + return BUG_TRAP_TYPE_NONE; | |
| 19 | +} | |
| 20 | +#endif /* CONFIG_CFI_CLANG */ | |
| 21 | + | |
| 22 | +#endif /* _ASM_X86_CFI_H */ | |
| @@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1, · 93 unmodified lines | ||
| 94 | 94 | return p1 & p2; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | +extern u64 x86_read_arch_cap_msr(void); | |
| 98 | + | |
| 97 | 99 | #endif /* _ASM_X86_CPU_H */ |
| @@ -43,6 +43,18 @@ · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | #endif /* __ASSEMBLY__ */ |
| 45 | 45 | |
| 46 | +#define __CFI_TYPE(name) \ | |
| 47 | + SYM_START(__cfi_##name, SYM_L_LOCAL, SYM_A_NONE) \ | |
| 48 | + .fill 11, 1, 0x90 ASM_NL \ | |
| 49 | + .byte 0xb8 ASM_NL \ | |
| 50 | + .long __kcfi_typeid_##name ASM_NL \ | |
| 51 | + SYM_FUNC_END(__cfi_##name) | |
| 52 | + | |
| 53 | +/* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */ | |
| 54 | +#define SYM_TYPED_FUNC_START(name) \ | |
| 55 | + SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) \ | |
| 56 | + ENDBR | |
| 57 | + | |
| 46 | 58 | /* SYM_FUNC_START -- use for global functions */ |
| 47 | 59 | #define SYM_FUNC_START(name) \ |
| 48 | 60 | SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) \ |
| @@ -95,7 +95,7 @@ static inline unsigned char current_lock_cmos_reg(void) · 94 unmodified lines | ||
| 95 | 95 | unsigned char rtc_cmos_read(unsigned char addr); |
| 96 | 96 | void rtc_cmos_write(unsigned char val, unsigned char addr); |
| 97 | 97 | |
| 98 | −extern int mach_set_rtc_mmss(const struct timespec64 *now); | |
| 98 | +extern int mach_set_cmos_time(const struct timespec64 *now); | |
| 99 | 99 | extern void mach_get_cmos_time(struct timespec64 *now); |
| 100 | 100 | |
| 101 | 101 | #define RTC_IRQ 8 |
| @@ -42,6 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #define MCI_STATUS_CEC_SHIFT 38 /* Corrected Error Count */ |
| 43 | 43 | #define MCI_STATUS_CEC_MASK GENMASK_ULL(52,38) |
| 44 | 44 | #define MCI_STATUS_CEC(c) (((c) & MCI_STATUS_CEC_MASK) >> MCI_STATUS_CEC_SHIFT) |
| 45 | +#define MCI_STATUS_MSCOD(m) (((m) >> 16) & 0xffff) | |
| 45 | 46 | |
| 46 | 47 | /* AMD-specific bits */ |
| 47 | 48 | #define MCI_STATUS_TCC BIT_ULL(55) /* Task context corrupt */ |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | struct ucode_patch { |
| 10 | 10 | struct list_head plist; |
| 11 | 11 | void *data; /* Intel uses only this one */ |
| 12 | + unsigned int size; | |
| 12 | 13 | u32 patch_id; |
| 13 | 14 | u16 equiv_cpu; |
| 14 | 15 | }; |
| @@ -32,9 +33,6 @@ enum ucode_state { · 17 unmodified lines | ||
| 32 | 33 | }; |
| 33 | 34 | |
| 34 | 35 | struct microcode_ops { |
| 35 | − enum ucode_state (*request_microcode_user) (int cpu, | |
| 36 | − const void __user *buf, size_t size); | |
| 37 | − | |
| 38 | 36 | enum ucode_state (*request_microcode_fw) (int cpu, struct device *, |
| 39 | 37 | bool refresh_fw); |
| 40 | 38 | |
| @@ -155,6 +155,11 @@ · 154 unmodified lines | ||
| 155 | 155 | * Return Stack Buffer Predictions. |
| 156 | 156 | */ |
| 157 | 157 | |
| 158 | +#define ARCH_CAP_XAPIC_DISABLE BIT(21) /* | |
| 159 | + * IA32_XAPIC_DISABLE_STATUS MSR | |
| 160 | + * supported | |
| 161 | + */ | |
| 162 | + | |
| 158 | 163 | #define MSR_IA32_FLUSH_CMD 0x0000010b |
| 159 | 164 | #define L1D_FLUSH BIT(0) /* |
| 160 | 165 | * Writeback and invalidate the |
| @@ -1054,4 +1059,12 @@ · 893 unmodified lines | ||
| 1054 | 1059 | #define MSR_IA32_HW_FEEDBACK_PTR 0x17d0 |
| 1055 | 1060 | #define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1 |
| 1056 | 1061 | |
| 1062 | +/* x2APIC locked status */ | |
| 1063 | +#define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD | |
| 1064 | +#define LEGACY_XAPIC_DISABLED BIT(0) /* | |
| 1065 | + * x2APIC mode is locked and | |
| 1066 | + * disabling x2APIC will cause | |
| 1067 | + * a #GP | |
| 1068 | + */ | |
| 1069 | + | |
| 1057 | 1070 | #endif /* _ASM_X86_MSR_INDEX_H */ |
| @@ -743,6 +743,7 @@ extern void default_banner(void); · 742 unmodified lines | ||
| 743 | 743 | word 771b; \ |
| 744 | 744 | .byte ptype; \ |
| 745 | 745 | .byte 772b-771b; \ |
| 746 | + _ASM_ALIGN; \ | |
| 746 | 747 | .popsection |
| 747 | 748 | |
| 748 | 749 | |
| @@ -294,6 +294,7 @@ extern struct paravirt_patch_template pv_ops; · 293 unmodified lines | ||
| 294 | 294 | " .byte " type "\n" \ |
| 295 | 295 | " .byte 772b-771b\n" \ |
| 296 | 296 | " .short " clobber "\n" \ |
| 297 | + _ASM_ALIGN "\n" \ | |
| 297 | 298 | ".popsection\n" |
| 298 | 299 | |
| 299 | 300 | /* Generate patchable code, with the default asm parameters. */ |
| @@ -328,7 +329,7 @@ int paravirt_disable_iospace(void); · 28 unmodified lines | ||
| 328 | 329 | * Unfortunately, this is a relatively slow operation for modern CPUs, |
| 329 | 330 | * because it cannot necessarily determine what the destination |
| 330 | 331 | * address is. In this case, the address is a runtime constant, so at |
| 331 | − * the very least we can patch the call to e a simple direct call, or | |
| 332 | + * the very least we can patch the call to a simple direct call, or, | |
| 332 | 333 | * ideally, patch an inline implementation into the callsite. (Direct |
| 333 | 334 | * calls are essentially free, because the call and return addresses |
| 334 | 335 | * are completely predictable.) |
| @@ -339,10 +340,10 @@ int paravirt_disable_iospace(void); · 4 unmodified lines | ||
| 339 | 340 | * on the stack. All caller-save registers (eax,edx,ecx) are expected |
| 340 | 341 | * to be modified (either clobbered or used for return values). |
| 341 | 342 | * X86_64, on the other hand, already specifies a register-based calling |
| 342 | − * conventions, returning at %rax, with parameters going on %rdi, %rsi, | |
| 343 | + * conventions, returning at %rax, with parameters going in %rdi, %rsi, | |
| 343 | 344 | * %rdx, and %rcx. Note that for this reason, x86_64 does not need any |
| 344 | 345 | * special handling for dealing with 4 arguments, unlike i386. |
| 345 | − * However, x86_64 also have to clobber all caller saved registers, which | |
| 346 | + * However, x86_64 also has to clobber all caller saved registers, which | |
| 346 | 347 | * unfortunately, are quite a bit (r8 - r11) |
| 347 | 348 | * |
| 348 | 349 | * The call instruction itself is marked by placing its start address |
| @@ -360,22 +361,22 @@ int paravirt_disable_iospace(void); · 11 unmodified lines | ||
| 360 | 361 | * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments. |
| 361 | 362 | * It could be extended to more arguments, but there would be little |
| 362 | 363 | * to be gained from that. For each number of arguments, there are |
| 363 | − * the two VCALL and CALL variants for void and non-void functions. | |
| 364 | + * two VCALL and CALL variants for void and non-void functions. | |
| 364 | 365 | * |
| 365 | 366 | * When there is a return value, the invoker of the macro must specify |
| 366 | 367 | * the return type. The macro then uses sizeof() on that type to |
| 367 | − * determine whether its a 32 or 64 bit value, and places the return | |
| 368 | + * determine whether it's a 32 or 64 bit value and places the return | |
| 368 | 369 | * in the right register(s) (just %eax for 32-bit, and %edx:%eax for |
| 369 | − * 64-bit). For x86_64 machines, it just returns at %rax regardless of | |
| 370 | + * 64-bit). For x86_64 machines, it just returns in %rax regardless of | |
| 370 | 371 | * the return value size. |
| 371 | 372 | * |
| 372 | − * 64-bit arguments are passed as a pair of adjacent 32-bit arguments | |
| 373 | + * 64-bit arguments are passed as a pair of adjacent 32-bit arguments; | |
| 373 | 374 | * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments |
| 374 | 375 | * in low,high order |
| 375 | 376 | * |
| 376 | 377 | * Small structures are passed and returned in registers. The macro |
| 377 | 378 | * calling convention can't directly deal with this, so the wrapper |
| 378 | − * functions must do this. | |
| 379 | + * functions must do it. | |
| 379 | 380 | * |
| 380 | 381 | * These PVOP_* macros are only defined within this header. This |
| 381 | 382 | * means that all uses must be wrapped in inline functions. This also |
| @@ -414,8 +415,17 @@ int paravirt_disable_iospace(void); · 32 unmodified lines | ||
| 414 | 415 | "=c" (__ecx) |
| 415 | 416 | #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) |
| 416 | 417 | |
| 417 | −/* void functions are still allowed [re]ax for scratch */ | |
| 418 | +/* | |
| 419 | + * void functions are still allowed [re]ax for scratch. | |
| 420 | + * | |
| 421 | + * The ZERO_CALL_USED REGS feature may end up zeroing out callee-saved | |
| 422 | + * registers. Make sure we model this with the appropriate clobbers. | |
| 423 | + */ | |
| 424 | +#ifdef CONFIG_ZERO_CALL_USED_REGS | |
| 425 | +#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), PVOP_VCALL_CLOBBERS | |
| 426 | +#else | |
| 418 | 427 | #define PVOP_VCALLEE_CLOBBERS "=a" (__eax) |
| 428 | +#endif | |
| 419 | 429 | #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS |
| 420 | 430 | |
| 421 | 431 | #define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11" |
| @@ -81,6 +81,15 @@ static void __resctrl_sched_in(void) · 80 unmodified lines | ||
| 81 | 81 | } |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | +static inline unsigned int resctrl_arch_round_mon_val(unsigned int val) | |
| 85 | +{ | |
| 86 | + unsigned int scale = boot_cpu_data.x86_cache_occ_scale; | |
| 87 | + | |
| 88 | + /* h/w works in units of "boot_cpu_data.x86_cache_occ_scale" */ | |
| 89 | + val /= scale; | |
| 90 | + return val * scale; | |
| 91 | +} | |
| 92 | + | |
| 84 | 93 | static inline void resctrl_sched_in(void) |
| 85 | 94 | { |
| 86 | 95 | if (static_branch_likely(&rdt_enable_key)) |
| @@ -21,16 +21,6 @@ DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id); · 20 unmodified lines | ||
| 21 | 21 | DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id); |
| 22 | 22 | DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number); |
| 23 | 23 | |
| 24 | −static inline struct cpumask *cpu_llc_shared_mask(int cpu) | |
| 25 | −{ | |
| 26 | − return per_cpu(cpu_llc_shared_map, cpu); | |
| 27 | −} | |
| 28 | − | |
| 29 | −static inline struct cpumask *cpu_l2c_shared_mask(int cpu) | |
| 30 | −{ | |
| 31 | − return per_cpu(cpu_l2c_shared_map, cpu); | |
| 32 | −} | |
| 33 | − | |
| 34 | 24 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid); |
| 35 | 25 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid); |
| 36 | 26 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid); |
| @@ -172,6 +162,16 @@ extern int safe_smp_processor_id(void); · 135 unmodified lines | ||
| 172 | 162 | # define safe_smp_processor_id() smp_processor_id() |
| 173 | 163 | #endif |
| 174 | 164 | |
| 165 | +static inline struct cpumask *cpu_llc_shared_mask(int cpu) | |
| 166 | +{ | |
| 167 | + return per_cpu(cpu_llc_shared_map, cpu); | |
| 168 | +} | |
| 169 | + | |
| 170 | +static inline struct cpumask *cpu_l2c_shared_mask(int cpu) | |
| 171 | +{ | |
| 172 | + return per_cpu(cpu_l2c_shared_map, cpu); | |
| 173 | +} | |
| 174 | + | |
| 175 | 175 | #else /* !CONFIG_SMP */ |
| 176 | 176 | #define wbinvd_on_cpu(cpu) wbinvd() |
| 177 | 177 | static inline int wbinvd_on_all_cpus(void) |
| @@ -179,6 +179,11 @@ static inline int wbinvd_on_all_cpus(void) · 1 unmodified line | ||
| 179 | 179 | wbinvd(); |
| 180 | 180 | return 0; |
| 181 | 181 | } |
| 182 | + | |
| 183 | +static inline struct cpumask *cpu_llc_shared_mask(int cpu) | |
| 184 | +{ | |
| 185 | + return (struct cpumask *)cpumask_of(0); | |
| 186 | +} | |
| 182 | 187 | #endif /* CONFIG_SMP */ |
| 183 | 188 | |
| 184 | 189 | extern unsigned disabled_cpus; |
| @@ -448,7 +448,7 @@ do { \ · 447 unmodified lines | ||
| 448 | 448 | |
| 449 | 449 | #ifdef CONFIG_X86_32 |
| 450 | 450 | /* |
| 451 | − * Unlike the normal CMPXCHG, hardcode ECX for both success/fail and error. | |
| 451 | + * Unlike the normal CMPXCHG, use output GPR for both success/fail and error. | |
| 452 | 452 | * There are only six GPRs available and four (EAX, EBX, ECX, and EDX) are |
| 453 | 453 | * hardcoded by CMPXCHG8B, leaving only ESI and EDI. If the compiler uses |
| 454 | 454 | * both ESI and EDI for the memory operand, compilation will fail if the error |
| @@ -461,11 +461,12 @@ do { \ · 6 unmodified lines | ||
| 461 | 461 | __typeof__(*(_ptr)) __new = (_new); \ |
| 462 | 462 | asm volatile("\n" \ |
| 463 | 463 | "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ |
| 464 | − "mov $0, %%ecx\n\t" \ | |
| 465 | − "setz %%cl\n" \ | |
| 464 | + "mov $0, %[result]\n\t" \ | |
| 465 | + "setz %b[result]\n" \ | |
| 466 | 466 | "2:\n" \ |
| 467 | − _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %%ecx) \ | |
| 468 | − : [result]"=c" (__result), \ | |
| 467 | + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, \ | |
| 468 | + %[result]) \ | |
| 469 | + : [result] "=q" (__result), \ | |
| 469 | 470 | "+A" (__old), \ |
| 470 | 471 | [ptr] "+m" (*_ptr) \ |
| 471 | 472 | : "b" ((u32)__new), \ |
| @@ -502,9 +503,6 @@ strncpy_from_user(char *dst, const char __user *src, long count); · 30 unmodified lines | ||
| 502 | 503 | |
| 503 | 504 | extern __must_check long strnlen_user(const char __user *str, long n); |
| 504 | 505 | |
| 505 | −unsigned long __must_check clear_user(void __user *mem, unsigned long len); | |
| 506 | −unsigned long __must_check __clear_user(void __user *mem, unsigned long len); | |
| 507 | − | |
| 508 | 506 | #ifdef CONFIG_ARCH_HAS_COPY_MC |
| 509 | 507 | unsigned long __must_check |
| 510 | 508 | copy_mc_to_kernel(void *to, const void *from, unsigned len); |
| @@ -526,6 +524,8 @@ extern struct movsl_mask { · 15 unmodified lines | ||
| 526 | 524 | #define ARCH_HAS_NOCACHE_UACCESS 1 |
| 527 | 525 | |
| 528 | 526 | #ifdef CONFIG_X86_32 |
| 527 | +unsigned long __must_check clear_user(void __user *mem, unsigned long len); | |
| 528 | +unsigned long __must_check __clear_user(void __user *mem, unsigned long len); | |
| 529 | 529 | # include <asm/uaccess_32.h> |
| 530 | 530 | #else |
| 531 | 531 | # include <asm/uaccess_64.h> |
| @@ -79,4 +79,49 @@ __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size) · 78 unmodified lines | ||
| 79 | 79 | kasan_check_write(dst, size); |
| 80 | 80 | return __copy_user_flushcache(dst, src, size); |
| 81 | 81 | } |
| 82 | + | |
| 83 | +/* | |
| 84 | + * Zero Userspace. | |
| 85 | + */ | |
| 86 | + | |
| 87 | +__must_check unsigned long | |
| 88 | +clear_user_original(void __user *addr, unsigned long len); | |
| 89 | +__must_check unsigned long | |
| 90 | +clear_user_rep_good(void __user *addr, unsigned long len); | |
| 91 | +__must_check unsigned long | |
| 92 | +clear_user_erms(void __user *addr, unsigned long len); | |
| 93 | + | |
| 94 | +static __always_inline __must_check unsigned long __clear_user(void __user *addr, unsigned long size) | |
| 95 | +{ | |
| 96 | + might_fault(); | |
| 97 | + stac(); | |
| 98 | + | |
| 99 | + /* | |
| 100 | + * No memory constraint because it doesn't change any memory gcc | |
| 101 | + * knows about. | |
| 102 | + */ | |
| 103 | + asm volatile( | |
| 104 | + "1:\n\t" | |
| 105 | + ALTERNATIVE_3("rep stosb", | |
| 106 | + "call clear_user_erms", ALT_NOT(X86_FEATURE_FSRM), | |
| 107 | + "call clear_user_rep_good", ALT_NOT(X86_FEATURE_ERMS), | |
| 108 | + "call clear_user_original", ALT_NOT(X86_FEATURE_REP_GOOD)) | |
| 109 | + "2:\n" | |
| 110 | + _ASM_EXTABLE_UA(1b, 2b) | |
| 111 | + : "+c" (size), "+D" (addr), ASM_CALL_CONSTRAINT | |
| 112 | + : "a" (0) | |
| 113 | + /* rep_good clobbers %rdx */ | |
| 114 | + : "rdx"); | |
| 115 | + | |
| 116 | + clac(); | |
| 117 | + | |
| 118 | + return size; | |
| 119 | +} | |
| 120 | + | |
| 121 | +static __always_inline unsigned long clear_user(void __user *to, unsigned long n) | |
| 122 | +{ | |
| 123 | + if (access_ok(to, n)) | |
| 124 | + return __clear_user(to, n); | |
| 125 | + return n; | |
| 126 | +} | |
| 82 | 127 | #endif /* _ASM_X86_UACCESS_64_H */ |
| @@ -139,6 +139,8 @@ obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o · 138 unmodified lines | ||
| 139 | 139 | |
| 140 | 140 | obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev.o |
| 141 | 141 | |
| 142 | +obj-$(CONFIG_CFI_CLANG) += cfi.o | |
| 143 | + | |
| 142 | 144 | ### |
| 143 | 145 | # 64 bit specific files |
| 144 | 146 | ifeq ($(CONFIG_X86_64),y) |
| @@ -453,6 +453,15 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes) · 452 unmodified lines | ||
| 453 | 453 | return ret; |
| 454 | 454 | i += ret; |
| 455 | 455 | |
| 456 | + /* | |
| 457 | + * The compiler is supposed to EMIT an INT3 after every unconditional | |
| 458 | + * JMP instruction due to AMD BTC. However, if the compiler is too old | |
| 459 | + * or SLS isn't enabled, we still need an INT3 after indirect JMPs | |
| 460 | + * even on Intel. | |
| 461 | + */ | |
| 462 | + if (op == JMP32_INSN_OPCODE && i < insn->length) | |
| 463 | + bytes[i++] = INT3_INSN_OPCODE; | |
| 464 | + | |
| 456 | 465 | for (; i < insn->length;) |
| 457 | 466 | bytes[i++] = BYTES_NOP1; |
| 458 | 467 | |
| @@ -1319,22 +1328,23 @@ struct bp_patching_desc { · 860 unmodified lines | ||
| 1319 | 1328 | atomic_t refs; |
| 1320 | 1329 | }; |
| 1321 | 1330 | |
| 1322 | −static struct bp_patching_desc *bp_desc; | |
| 1331 | +static struct bp_patching_desc bp_desc; | |
| 1323 | 1332 | |
| 1324 | 1333 | static __always_inline |
| 1325 | −struct bp_patching_desc *try_get_desc(struct bp_patching_desc **descp) | |
| 1334 | +struct bp_patching_desc *try_get_desc(void) | |
| 1326 | 1335 | { |
| 1327 | − /* rcu_dereference */ | |
| 1328 | − struct bp_patching_desc *desc = __READ_ONCE(*descp); | |
| 1336 | + struct bp_patching_desc *desc = &bp_desc; | |
| 1329 | 1337 | |
| 1330 | − if (!desc || !arch_atomic_inc_not_zero(&desc->refs)) | |
| 1338 | + if (!arch_atomic_inc_not_zero(&desc->refs)) | |
| 1331 | 1339 | return NULL; |
| 1332 | 1340 | |
| 1333 | 1341 | return desc; |
| 1334 | 1342 | } |
| 1335 | 1343 | |
| 1336 | −static __always_inline void put_desc(struct bp_patching_desc *desc) | |
| 1344 | +static __always_inline void put_desc(void) | |
| 1337 | 1345 | { |
| 1346 | + struct bp_patching_desc *desc = &bp_desc; | |
| 1347 | + | |
| 1338 | 1348 | smp_mb__before_atomic(); |
| 1339 | 1349 | arch_atomic_dec(&desc->refs); |
| 1340 | 1350 | } |
| @@ -1367,15 +1377,15 @@ noinstr int poke_int3_handler(struct pt_regs *regs) · 26 unmodified lines | ||
| 1367 | 1377 | |
| 1368 | 1378 | /* |
| 1369 | 1379 | * Having observed our INT3 instruction, we now must observe |
| 1370 | − * bp_desc: | |
| 1380 | + * bp_desc with non-zero refcount: | |
| 1371 | 1381 | * |
| 1372 | − * bp_desc = desc INT3 | |
| 1382 | + * bp_desc.refs = 1 INT3 | |
| 1373 | 1383 | * WMB RMB |
| 1374 | − * write INT3 if (desc) | |
| 1384 | + * write INT3 if (bp_desc.refs != 0) | |
| 1375 | 1385 | */ |
| 1376 | 1386 | smp_rmb(); |
| 1377 | 1387 | |
| 1378 | − desc = try_get_desc(&bp_desc); | |
| 1388 | + desc = try_get_desc(); | |
| 1379 | 1389 | if (!desc) |
| 1380 | 1390 | return 0; |
| 1381 | 1391 | |
| @@ -1429,7 +1439,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs) · 47 unmodified lines | ||
| 1429 | 1439 | ret = 1; |
| 1430 | 1440 | |
| 1431 | 1441 | out_put: |
| 1432 | − put_desc(desc); | |
| 1442 | + put_desc(); | |
| 1433 | 1443 | return ret; |
| 1434 | 1444 | } |
| 1435 | 1445 | |
| @@ -1460,18 +1470,20 @@ static int tp_vec_nr; · 24 unmodified lines | ||
| 1460 | 1470 | */ |
| 1461 | 1471 | static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries) |
| 1462 | 1472 | { |
| 1463 | − struct bp_patching_desc desc = { | |
| 1464 | − .vec = tp, | |
| 1465 | − .nr_entries = nr_entries, | |
| 1466 | − .refs = ATOMIC_INIT(1), | |
| 1467 | − }; | |
| 1468 | 1473 | unsigned char int3 = INT3_INSN_OPCODE; |
| 1469 | 1474 | unsigned int i; |
| 1470 | 1475 | int do_sync; |
| 1471 | 1476 | |
| 1472 | 1477 | lockdep_assert_held(&text_mutex); |
| 1473 | 1478 | |
| 1474 | − smp_store_release(&bp_desc, &desc); /* rcu_assign_pointer */ | |
| 1479 | + bp_desc.vec = tp; | |
| 1480 | + bp_desc.nr_entries = nr_entries; | |
| 1481 | + | |
| 1482 | + /* | |
| 1483 | + * Corresponds to the implicit memory barrier in try_get_desc() to | |
| 1484 | + * ensure reading a non-zero refcount provides up to date bp_desc data. | |
| 1485 | + */ | |
| 1486 | + atomic_set_release(&bp_desc.refs, 1); | |
| 1475 | 1487 | |
| 1476 | 1488 | /* |
| 1477 | 1489 | * Corresponding read barrier in int3 notifier for making sure the |
| @@ -1559,12 +1571,10 @@ static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries · 81 unmodified lines | ||
| 1559 | 1571 | text_poke_sync(); |
| 1560 | 1572 | |
| 1561 | 1573 | /* |
| 1562 | − * Remove and synchronize_rcu(), except we have a very primitive | |
| 1563 | − * refcount based completion. | |
| 1574 | + * Remove and wait for refs to be zero. | |
| 1564 | 1575 | */ |
| 1565 | − WRITE_ONCE(bp_desc, NULL); /* RCU_INIT_POINTER */ | |
| 1566 | − if (!atomic_dec_and_test(&desc.refs)) | |
| 1567 | − atomic_cond_read_acquire(&desc.refs, !VAL); | |
| 1576 | + if (!atomic_dec_and_test(&bp_desc.refs)) | |
| 1577 | + atomic_cond_read_acquire(&bp_desc.refs, !VAL); | |
| 1568 | 1578 | } |
| 1569 | 1579 | |
| 1570 | 1580 | static void text_poke_loc_init(struct text_poke_loc *tp, void *addr, |
| @@ -53,7 +53,7 @@ static u32 *iommu_gatt_base; /* Remapping table */ · 52 unmodified lines | ||
| 53 | 53 | * of only flushing when an mapping is reused. With it true the GART is |
| 54 | 54 | * flushed for every mapping. Problem is that doing the lazy flush seems |
| 55 | 55 | * to trigger bugs with some popular PCI cards, in particular 3ware (but |
| 56 | − * has been also also seen with Qlogic at least). | |
| 56 | + * has been also seen with Qlogic at least). | |
| 57 | 57 | */ |
| 58 | 58 | static int iommu_fullflush = 1; |
| 59 | 59 | |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | /* |
| 37 | 37 | * Using 512M as goal, in case kexec will load kernel_big |
| 38 | 38 | * that will do the on-position decompress, and could overlap with |
| 39 | − * with the gart aperture that is used. | |
| 39 | + * the gart aperture that is used. | |
| 40 | 40 | * Sequence: |
| 41 | 41 | * kernel_small |
| 42 | 42 | * ==> kexec (with kdump trigger path or gart still enabled) |
| @@ -61,6 +61,7 @@ · 60 unmodified lines | ||
| 61 | 61 | #include <asm/cpu_device_id.h> |
| 62 | 62 | #include <asm/intel-family.h> |
| 63 | 63 | #include <asm/irq_regs.h> |
| 64 | +#include <asm/cpu.h> | |
| 64 | 65 | |
| 65 | 66 | unsigned int num_processors; |
| 66 | 67 | |
| @@ -1751,11 +1752,26 @@ EXPORT_SYMBOL_GPL(x2apic_mode); · 1684 unmodified lines | ||
| 1751 | 1752 | |
| 1752 | 1753 | enum { |
| 1753 | 1754 | X2APIC_OFF, |
| 1754 | − X2APIC_ON, | |
| 1755 | 1755 | X2APIC_DISABLED, |
| 1756 | + /* All states below here have X2APIC enabled */ | |
| 1757 | + X2APIC_ON, | |
| 1758 | + X2APIC_ON_LOCKED | |
| 1756 | 1759 | }; |
| 1757 | 1760 | static int x2apic_state; |
| 1758 | 1761 | |
| 1762 | +static bool x2apic_hw_locked(void) | |
| 1763 | +{ | |
| 1764 | + u64 ia32_cap; | |
| 1765 | + u64 msr; | |
| 1766 | + | |
| 1767 | + ia32_cap = x86_read_arch_cap_msr(); | |
| 1768 | + if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) { | |
| 1769 | + rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr); | |
| 1770 | + return (msr & LEGACY_XAPIC_DISABLED); | |
| 1771 | + } | |
| 1772 | + return false; | |
| 1773 | +} | |
| 1774 | + | |
| 1759 | 1775 | static void __x2apic_disable(void) |
| 1760 | 1776 | { |
| 1761 | 1777 | u64 msr; |
| @@ -1793,6 +1809,10 @@ static int __init setup_nox2apic(char *str) · 31 unmodified lines | ||
| 1793 | 1809 | apicid); |
| 1794 | 1810 | return 0; |
| 1795 | 1811 | } |
| 1812 | + if (x2apic_hw_locked()) { | |
| 1813 | + pr_warn("APIC locked in x2apic mode, can't disable\n"); | |
| 1814 | + return 0; | |
| 1815 | + } | |
| 1796 | 1816 | pr_warn("x2apic already enabled.\n"); |
| 1797 | 1817 | __x2apic_disable(); |
| 1798 | 1818 | } |
| @@ -1807,10 +1827,18 @@ early_param("nox2apic", setup_nox2apic); · 8 unmodified lines | ||
| 1807 | 1827 | void x2apic_setup(void) |
| 1808 | 1828 | { |
| 1809 | 1829 | /* |
| 1810 | − * If x2apic is not in ON state, disable it if already enabled | |
| 1830 | + * Try to make the AP's APIC state match that of the BSP, but if the | |
| 1831 | + * BSP is unlocked and the AP is locked then there is a state mismatch. | |
| 1832 | + * Warn about the mismatch in case a GP fault occurs due to a locked AP | |
| 1833 | + * trying to be turned off. | |
| 1834 | + */ | |
| 1835 | + if (x2apic_state != X2APIC_ON_LOCKED && x2apic_hw_locked()) | |
| 1836 | + pr_warn("x2apic lock mismatch between BSP and AP.\n"); | |
| 1837 | + /* | |
| 1838 | + * If x2apic is not in ON or LOCKED state, disable it if already enabled | |
| 1811 | 1839 | * from BIOS. |
| 1812 | 1840 | */ |
| 1813 | − if (x2apic_state != X2APIC_ON) { | |
| 1841 | + if (x2apic_state < X2APIC_ON) { | |
| 1814 | 1842 | __x2apic_disable(); |
| 1815 | 1843 | return; |
| 1816 | 1844 | } |
| @@ -1831,6 +1859,11 @@ static __init void x2apic_disable(void) · 14 unmodified lines | ||
| 1831 | 1859 | if (x2apic_id >= 255) |
| 1832 | 1860 | panic("Cannot disable x2apic, id: %08x\n", x2apic_id); |
| 1833 | 1861 | |
| 1862 | + if (x2apic_hw_locked()) { | |
| 1863 | + pr_warn("Cannot disable locked x2apic, id: %08x\n", x2apic_id); | |
| 1864 | + return; | |
| 1865 | + } | |
| 1866 | + | |
| 1834 | 1867 | __x2apic_disable(); |
| 1835 | 1868 | register_lapic_address(mp_lapic_addr); |
| 1836 | 1869 | } |
| @@ -1889,7 +1922,10 @@ void __init check_x2apic(void) · 52 unmodified lines | ||
| 1889 | 1922 | if (x2apic_enabled()) { |
| 1890 | 1923 | pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n"); |
| 1891 | 1924 | x2apic_mode = 1; |
| 1892 | − x2apic_state = X2APIC_ON; | |
| 1925 | + if (x2apic_hw_locked()) | |
| 1926 | + x2apic_state = X2APIC_ON_LOCKED; | |
| 1927 | + else | |
| 1928 | + x2apic_state = X2APIC_ON; | |
| 1893 | 1929 | } else if (!boot_cpu_has(X86_FEATURE_X2APIC)) { |
| 1894 | 1930 | x2apic_state = X2APIC_DISABLED; |
| 1895 | 1931 | } |
| @@ -0,0 +1,86 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Clang Control Flow Integrity (CFI) support. | |
| 4 | + * | |
| 5 | + * Copyright (C) 2022 Google LLC | |
| 6 | + */ | |
| 7 | +#include <asm/cfi.h> | |
| 8 | +#include <asm/insn.h> | |
| 9 | +#include <asm/insn-eval.h> | |
| 10 | +#include <linux/string.h> | |
| 11 | + | |
| 12 | +/* | |
| 13 | + * Returns the target address and the expected type when regs->ip points | |
| 14 | + * to a compiler-generated CFI trap. | |
| 15 | + */ | |
| 16 | +static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target, | |
| 17 | + u32 *type) | |
| 18 | +{ | |
| 19 | + char buffer[MAX_INSN_SIZE]; | |
| 20 | + struct insn insn; | |
| 21 | + int offset = 0; | |
| 22 | + | |
| 23 | + *target = *type = 0; | |
| 24 | + | |
| 25 | + /* | |
| 26 | + * The compiler generates the following instruction sequence | |
| 27 | + * for indirect call checks: | |
| 28 | + * | |
| 29 | + * movl -<id>, %r10d ; 6 bytes | |
| 30 | + * addl -4(%reg), %r10d ; 4 bytes | |
| 31 | + * je .Ltmp1 ; 2 bytes | |
| 32 | + * ud2 ; <- regs->ip | |
| 33 | + * .Ltmp1: | |
| 34 | + * | |
| 35 | + * We can decode the expected type and the target address from the | |
| 36 | + * movl/addl instructions. | |
| 37 | + */ | |
| 38 | + if (copy_from_kernel_nofault(buffer, (void *)regs->ip - 12, MAX_INSN_SIZE)) | |
| 39 | + return false; | |
| 40 | + if (insn_decode_kernel(&insn, &buffer[offset])) | |
| 41 | + return false; | |
| 42 | + if (insn.opcode.value != 0xBA) | |
| 43 | + return false; | |
| 44 | + | |
| 45 | + *type = -(u32)insn.immediate.value; | |
| 46 | + | |
| 47 | + if (copy_from_kernel_nofault(buffer, (void *)regs->ip - 6, MAX_INSN_SIZE)) | |
| 48 | + return false; | |
| 49 | + if (insn_decode_kernel(&insn, &buffer[offset])) | |
| 50 | + return false; | |
| 51 | + if (insn.opcode.value != 0x3) | |
| 52 | + return false; | |
| 53 | + | |
| 54 | + /* Read the target address from the register. */ | |
| 55 | + offset = insn_get_modrm_rm_off(&insn, regs); | |
| 56 | + if (offset < 0) | |
| 57 | + return false; | |
| 58 | + | |
| 59 | + *target = *(unsigned long *)((void *)regs + offset); | |
| 60 | + | |
| 61 | + return true; | |
| 62 | +} | |
| 63 | + | |
| 64 | +/* | |
| 65 | + * Checks if a ud2 trap is because of a CFI failure, and handles the trap | |
| 66 | + * if needed. Returns a bug_trap_type value similarly to report_bug. | |
| 67 | + */ | |
| 68 | +enum bug_trap_type handle_cfi_failure(struct pt_regs *regs) | |
| 69 | +{ | |
| 70 | + unsigned long target; | |
| 71 | + u32 type; | |
| 72 | + | |
| 73 | + if (!is_cfi_trap(regs->ip)) | |
| 74 | + return BUG_TRAP_TYPE_NONE; | |
| 75 | + | |
| 76 | + if (!decode_cfi_insn(regs, &target, &type)) | |
| 77 | + return report_cfi_failure_noaddr(regs, regs->ip); | |
| 78 | + | |
| 79 | + return report_cfi_failure(regs, regs->ip, &target, type); | |
| 80 | +} | |
| 81 | + | |
| 82 | +/* | |
| 83 | + * Ensure that __kcfi_typeid_ symbols are emitted for functions that may | |
| 84 | + * not be indirectly called with all configurations. | |
| 85 | + */ | |
| 86 | +__ADDRESSABLE(__memcpy) | |
| @@ -28,6 +28,9 @@ static void __init acrn_init_platform(void) · 27 unmodified lines | ||
| 28 | 28 | { |
| 29 | 29 | /* Setup the IDT for ACRN hypervisor callback */ |
| 30 | 30 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_acrn_hv_callback); |
| 31 | + | |
| 32 | + x86_platform.calibrate_tsc = acrn_get_tsc_khz; | |
| 33 | + x86_platform.calibrate_cpu = acrn_get_tsc_khz; | |
| 31 | 34 | } |
| 32 | 35 | |
| 33 | 36 | static bool acrn_x2apic_available(void) |
| @@ -1,11 +1,11 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/tboot.h> |
| 3 | 3 | |
| 4 | +#include <asm/cpu.h> | |
| 4 | 5 | #include <asm/cpufeature.h> |
| 5 | 6 | #include <asm/msr-index.h> |
| 6 | 7 | #include <asm/processor.h> |
| 7 | 8 | #include <asm/vmx.h> |
| 8 | −#include "cpu.h" | |
| 9 | 9 | |
| 10 | 10 | #undef pr_fmt |
| 11 | 11 | #define pr_fmt(fmt) "x86/cpu: " fmt |
| @@ -29,15 +29,26 @@ · 28 unmodified lines | ||
| 29 | 29 | void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err) |
| 30 | 30 | { |
| 31 | 31 | struct mce m; |
| 32 | + int lsb; | |
| 32 | 33 | |
| 33 | 34 | if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) |
| 34 | 35 | return; |
| 35 | 36 | |
| 37 | + /* | |
| 38 | + * Even if the ->validation_bits are set for address mask, | |
| 39 | + * to be extra safe, check and reject an error radius '0', | |
| 40 | + * and fall back to the default page size. | |
| 41 | + */ | |
| 42 | + if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK) | |
| 43 | + lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT); | |
| 44 | + else | |
| 45 | + lsb = PAGE_SHIFT; | |
| 46 | + | |
| 36 | 47 | mce_setup(&m); |
| 37 | 48 | m.bank = -1; |
| 38 | 49 | /* Fake a memory read error with unknown channel */ |
| 39 | 50 | m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f; |
| 40 | − m.misc = (MCI_MISC_ADDR_PHYS << 6) | PAGE_SHIFT; | |
| 51 | + m.misc = (MCI_MISC_ADDR_PHYS << 6) | lsb; | |
| 41 | 52 | |
| 42 | 53 | if (severity >= GHES_SEV_RECOVERABLE) |
| 43 | 54 | m.status |= MCI_STATUS_UC; |
| @@ -788,6 +788,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover, · 787 unmodified lines | ||
| 788 | 788 | kfree(patch); |
| 789 | 789 | return -EINVAL; |
| 790 | 790 | } |
| 791 | + patch->size = *patch_size; | |
| 791 | 792 | |
| 792 | 793 | mc_hdr = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE); |
| 793 | 794 | proc_id = mc_hdr->processor_rev_id; |
| @@ -869,7 +870,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) · 75 unmodified lines | ||
| 869 | 870 | return ret; |
| 870 | 871 | |
| 871 | 872 | memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); |
| 872 | − memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE)); | |
| 873 | + memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); | |
| 873 | 874 | |
| 874 | 875 | return ret; |
| 875 | 876 | } |
| @@ -924,12 +925,6 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, · 48 unmodified lines | ||
| 924 | 925 | return ret; |
| 925 | 926 | } |
| 926 | 927 | |
| 927 | −static enum ucode_state | |
| 928 | −request_microcode_user(int cpu, const void __user *buf, size_t size) | |
| 929 | −{ | |
| 930 | − return UCODE_ERROR; | |
| 931 | −} | |
| 932 | − | |
| 933 | 928 | static void microcode_fini_cpu_amd(int cpu) |
| 934 | 929 | { |
| 935 | 930 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
| @@ -938,7 +933,6 @@ static void microcode_fini_cpu_amd(int cpu) · 2 unmodified lines | ||
| 938 | 933 | } |
| 939 | 934 | |
| 940 | 935 | static struct microcode_ops microcode_amd_ops = { |
| 941 | − .request_microcode_user = request_microcode_user, | |
| 942 | 936 | .request_microcode_fw = request_microcode_amd, |
| 943 | 937 | .collect_cpu_info = collect_cpu_info_amd, |
| 944 | 938 | .apply_microcode = apply_microcode_amd, |
| @@ -491,7 +491,7 @@ wait_for_siblings: · 490 unmodified lines | ||
| 491 | 491 | */ |
| 492 | 492 | static int microcode_reload_late(void) |
| 493 | 493 | { |
| 494 | − int ret; | |
| 494 | + int old = boot_cpu_data.microcode, ret; | |
| 495 | 495 | |
| 496 | 496 | pr_err("Attempting late microcode loading - it is dangerous and taints the kernel.\n"); |
| 497 | 497 | pr_err("You should switch to early loading, if possible.\n"); |
| @@ -503,7 +503,8 @@ static int microcode_reload_late(void) · 5 unmodified lines | ||
| 503 | 503 | if (ret == 0) |
| 504 | 504 | microcode_check(); |
| 505 | 505 | |
| 506 | − pr_info("Reload completed, microcode revision: 0x%x\n", boot_cpu_data.microcode); | |
| 506 | + pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n", | |
| 507 | + old, boot_cpu_data.microcode); | |
| 507 | 508 | |
| 508 | 509 | return ret; |
| 509 | 510 | } |
| @@ -916,24 +916,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device, · 915 unmodified lines | ||
| 916 | 916 | return ret; |
| 917 | 917 | } |
| 918 | 918 | |
| 919 | −static enum ucode_state | |
| 920 | −request_microcode_user(int cpu, const void __user *buf, size_t size) | |
| 921 | −{ | |
| 922 | − struct iov_iter iter; | |
| 923 | − struct iovec iov; | |
| 924 | − | |
| 925 | − if (is_blacklisted(cpu)) | |
| 926 | − return UCODE_NFOUND; | |
| 927 | − | |
| 928 | − iov.iov_base = (void __user *)buf; | |
| 929 | − iov.iov_len = size; | |
| 930 | − iov_iter_init(&iter, WRITE, &iov, 1, size); | |
| 931 | − | |
| 932 | − return generic_load_microcode(cpu, &iter); | |
| 933 | −} | |
| 934 | − | |
| 935 | 919 | static struct microcode_ops microcode_intel_ops = { |
| 936 | − .request_microcode_user = request_microcode_user, | |
| 937 | 920 | .request_microcode_fw = request_microcode_fw, |
| 938 | 921 | .collect_cpu_info = collect_cpu_info, |
| 939 | 922 | .apply_microcode = apply_microcode_intel, |
| @@ -147,7 +147,6 @@ static inline void cache_alloc_hsw_probe(void) · 146 unmodified lines | ||
| 147 | 147 | r->cache.shareable_bits = 0xc0000; |
| 148 | 148 | r->cache.min_cbm_bits = 2; |
| 149 | 149 | r->alloc_capable = true; |
| 150 | − r->alloc_enabled = true; | |
| 151 | 150 | |
| 152 | 151 | rdt_alloc_capable = true; |
| 153 | 152 | } |
| @@ -211,7 +210,6 @@ static bool __get_mem_config_intel(struct rdt_resource *r) · 57 unmodified lines | ||
| 211 | 210 | thread_throttle_mode_init(); |
| 212 | 211 | |
| 213 | 212 | r->alloc_capable = true; |
| 214 | − r->alloc_enabled = true; | |
| 215 | 213 | |
| 216 | 214 | return true; |
| 217 | 215 | } |
| @@ -242,7 +240,6 @@ static bool __rdt_get_mem_config_amd(struct rdt_resource *r) · 24 unmodified lines | ||
| 242 | 240 | r->data_width = 4; |
| 243 | 241 | |
| 244 | 242 | r->alloc_capable = true; |
| 245 | − r->alloc_enabled = true; | |
| 246 | 243 | |
| 247 | 244 | return true; |
| 248 | 245 | } |
| @@ -261,7 +258,6 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r) · 12 unmodified lines | ||
| 261 | 258 | r->cache.shareable_bits = ebx & r->default_ctrl; |
| 262 | 259 | r->data_width = (r->cache.cbm_len + 3) / 4; |
| 263 | 260 | r->alloc_capable = true; |
| 264 | − r->alloc_enabled = true; | |
| 265 | 261 | } |
| 266 | 262 | |
| 267 | 263 | static void rdt_get_cdp_config(int level) |
| @@ -300,7 +296,7 @@ mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) · 32 unmodified lines | ||
| 300 | 296 | * that can be written to QOS_MSRs. |
| 301 | 297 | * There are currently no SKUs which support non linear delay values. |
| 302 | 298 | */ |
| 303 | −u32 delay_bw_map(unsigned long bw, struct rdt_resource *r) | |
| 299 | +static u32 delay_bw_map(unsigned long bw, struct rdt_resource *r) | |
| 304 | 300 | { |
| 305 | 301 | if (r->membw.delay_linear) |
| 306 | 302 | return MAX_MBA_BW - bw; |
| @@ -401,7 +397,7 @@ struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, · 94 unmodified lines | ||
| 401 | 397 | return NULL; |
| 402 | 398 | } |
| 403 | 399 | |
| 404 | −void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm) | |
| 400 | +static void setup_default_ctrlval(struct rdt_resource *r, u32 *dc) | |
| 405 | 401 | { |
| 406 | 402 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 407 | 403 | int i; |
| @@ -410,12 +406,17 @@ void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm) · 2 unmodified lines | ||
| 410 | 406 | * Initialize the Control MSRs to having no control. |
| 411 | 407 | * For Cache Allocation: Set all bits in cbm |
| 412 | 408 | * For Memory Allocation: Set b/w requested to 100% |
| 413 | − * and the bandwidth in MBps to U32_MAX | |
| 414 | 409 | */ |
| 415 | − for (i = 0; i < hw_res->num_closid; i++, dc++, dm++) { | |
| 410 | + for (i = 0; i < hw_res->num_closid; i++, dc++) | |
| 416 | 411 | *dc = r->default_ctrl; |
| 417 | − *dm = MBA_MAX_MBPS; | |
| 418 | − } | |
| 412 | +} | |
| 413 | + | |
| 414 | +static void domain_free(struct rdt_hw_domain *hw_dom) | |
| 415 | +{ | |
| 416 | + kfree(hw_dom->arch_mbm_total); | |
| 417 | + kfree(hw_dom->arch_mbm_local); | |
| 418 | + kfree(hw_dom->ctrl_val); | |
| 419 | + kfree(hw_dom); | |
| 419 | 420 | } |
| 420 | 421 | |
| 421 | 422 | static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) |
| @@ -423,23 +424,15 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) · 1 unmodified line | ||
| 423 | 424 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 424 | 425 | struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); |
| 425 | 426 | struct msr_param m; |
| 426 | − u32 *dc, *dm; | |
| 427 | + u32 *dc; | |
| 427 | 428 | |
| 428 | 429 | dc = kmalloc_array(hw_res->num_closid, sizeof(*hw_dom->ctrl_val), |
| 429 | 430 | GFP_KERNEL); |
| 430 | 431 | if (!dc) |
| 431 | 432 | return -ENOMEM; |
| 432 | 433 | |
| 433 | − dm = kmalloc_array(hw_res->num_closid, sizeof(*hw_dom->mbps_val), | |
| 434 | − GFP_KERNEL); | |
| 435 | − if (!dm) { | |
| 436 | − kfree(dc); | |
| 437 | − return -ENOMEM; | |
| 438 | − } | |
| 439 | − | |
| 440 | 434 | hw_dom->ctrl_val = dc; |
| 441 | − hw_dom->mbps_val = dm; | |
| 442 | − setup_default_ctrlval(r, dc, dm); | |
| 435 | + setup_default_ctrlval(r, dc); | |
| 443 | 436 | |
| 444 | 437 | m.low = 0; |
| 445 | 438 | m.high = hw_res->num_closid; |
| @@ -447,39 +440,31 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) · 1 unmodified line | ||
| 447 | 440 | return 0; |
| 448 | 441 | } |
| 449 | 442 | |
| 450 | −static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) | |
| 443 | +/** | |
| 444 | + * arch_domain_mbm_alloc() - Allocate arch private storage for the MBM counters | |
| 445 | + * @num_rmid: The size of the MBM counter array | |
| 446 | + * @hw_dom: The domain that owns the allocated arrays | |
| 447 | + */ | |
| 448 | +static int arch_domain_mbm_alloc(u32 num_rmid, struct rdt_hw_domain *hw_dom) | |
| 451 | 449 | { |
| 452 | 450 | size_t tsize; |
| 453 | 451 | |
| 454 | − if (is_llc_occupancy_enabled()) { | |
| 455 | − d->rmid_busy_llc = bitmap_zalloc(r->num_rmid, GFP_KERNEL); | |
| 456 | − if (!d->rmid_busy_llc) | |
| 457 | − return -ENOMEM; | |
| 458 | − INIT_DELAYED_WORK(&d->cqm_limbo, cqm_handle_limbo); | |
| 459 | − } | |
| 460 | 452 | if (is_mbm_total_enabled()) { |
| 461 | − tsize = sizeof(*d->mbm_total); | |
| 462 | − d->mbm_total = kcalloc(r->num_rmid, tsize, GFP_KERNEL); | |
| 463 | − if (!d->mbm_total) { | |
| 464 | − bitmap_free(d->rmid_busy_llc); | |
| 453 | + tsize = sizeof(*hw_dom->arch_mbm_total); | |
| 454 | + hw_dom->arch_mbm_total = kcalloc(num_rmid, tsize, GFP_KERNEL); | |
| 455 | + if (!hw_dom->arch_mbm_total) | |
| 465 | 456 | return -ENOMEM; |
| 466 | − } | |
| 467 | 457 | } |
| 468 | 458 | if (is_mbm_local_enabled()) { |
| 469 | − tsize = sizeof(*d->mbm_local); | |
| 470 | − d->mbm_local = kcalloc(r->num_rmid, tsize, GFP_KERNEL); | |
| 471 | − if (!d->mbm_local) { | |
| 472 | − bitmap_free(d->rmid_busy_llc); | |
| 473 | − kfree(d->mbm_total); | |
| 459 | + tsize = sizeof(*hw_dom->arch_mbm_local); | |
| 460 | + hw_dom->arch_mbm_local = kcalloc(num_rmid, tsize, GFP_KERNEL); | |
| 461 | + if (!hw_dom->arch_mbm_local) { | |
| 462 | + kfree(hw_dom->arch_mbm_total); | |
| 463 | + hw_dom->arch_mbm_total = NULL; | |
| 474 | 464 | return -ENOMEM; |
| 475 | 465 | } |
| 476 | 466 | } |
| 477 | 467 | |
| 478 | − if (is_mbm_enabled()) { | |
| 479 | − INIT_DELAYED_WORK(&d->mbm_over, mbm_handle_overflow); | |
| 480 | − mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL); | |
| 481 | − } | |
| 482 | − | |
| 483 | 468 | return 0; |
| 484 | 469 | } |
| 485 | 470 | |
| @@ -502,6 +487,7 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) · 16 unmodified lines | ||
| 502 | 487 | struct list_head *add_pos = NULL; |
| 503 | 488 | struct rdt_hw_domain *hw_dom; |
| 504 | 489 | struct rdt_domain *d; |
| 490 | + int err; | |
| 505 | 491 | |
| 506 | 492 | d = rdt_find_domain(r, id, &add_pos); |
| 507 | 493 | if (IS_ERR(d)) { |
| @@ -527,25 +513,22 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) · 19 unmodified lines | ||
| 527 | 513 | rdt_domain_reconfigure_cdp(r); |
| 528 | 514 | |
| 529 | 515 | if (r->alloc_capable && domain_setup_ctrlval(r, d)) { |
| 530 | − kfree(hw_dom); | |
| 516 | + domain_free(hw_dom); | |
| 531 | 517 | return; |
| 532 | 518 | } |
| 533 | 519 | |
| 534 | − if (r->mon_capable && domain_setup_mon_state(r, d)) { | |
| 535 | − kfree(hw_dom->ctrl_val); | |
| 536 | − kfree(hw_dom->mbps_val); | |
| 537 | − kfree(hw_dom); | |
| 520 | + if (r->mon_capable && arch_domain_mbm_alloc(r->num_rmid, hw_dom)) { | |
| 521 | + domain_free(hw_dom); | |
| 538 | 522 | return; |
| 539 | 523 | } |
| 540 | 524 | |
| 541 | 525 | list_add_tail(&d->list, add_pos); |
| 542 | 526 | |
| 543 | − /* | |
| 544 | − * If resctrl is mounted, add | |
| 545 | − * per domain monitor data directories. | |
| 546 | − */ | |
| 547 | − if (static_branch_unlikely(&rdt_mon_enable_key)) | |
| 548 | − mkdir_mondata_subdir_allrdtgrp(r, d); | |
| 527 | + err = resctrl_online_domain(r, d); | |
| 528 | + if (err) { | |
| 529 | + list_del(&d->list); | |
| 530 | + domain_free(hw_dom); | |
| 531 | + } | |
| 549 | 532 | } |
| 550 | 533 | |
| 551 | 534 | static void domain_remove_cpu(int cpu, struct rdt_resource *r) |
| @@ -563,27 +546,8 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) · 11 unmodified lines | ||
| 563 | 546 | |
| 564 | 547 | cpumask_clear_cpu(cpu, &d->cpu_mask); |
| 565 | 548 | if (cpumask_empty(&d->cpu_mask)) { |
| 566 | − /* | |
| 567 | − * If resctrl is mounted, remove all the | |
| 568 | − * per domain monitor data directories. | |
| 569 | − */ | |
| 570 | − if (static_branch_unlikely(&rdt_mon_enable_key)) | |
| 571 | − rmdir_mondata_subdir_allrdtgrp(r, d->id); | |
| 549 | + resctrl_offline_domain(r, d); | |
| 572 | 550 | list_del(&d->list); |
| 573 | − if (r->mon_capable && is_mbm_enabled()) | |
| 574 | − cancel_delayed_work(&d->mbm_over); | |
| 575 | − if (is_llc_occupancy_enabled() && has_busy_rmid(r, d)) { | |
| 576 | − /* | |
| 577 | − * When a package is going down, forcefully | |
| 578 | − * decrement rmid->ebusy. There is no way to know | |
| 579 | − * that the L3 was flushed and hence may lead to | |
| 580 | − * incorrect counts in rare scenarios, but leaving | |
| 581 | − * the RMID as busy creates RMID leaks if the | |
| 582 | − * package never comes back. | |
| 583 | − */ | |
| 584 | − __check_limbo(d, true); | |
| 585 | − cancel_delayed_work(&d->cqm_limbo); | |
| 586 | − } | |
| 587 | 551 | |
| 588 | 552 | /* |
| 589 | 553 | * rdt_domain "d" is going to be freed below, so clear |
| @@ -591,13 +555,8 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) · 1 unmodified line | ||
| 591 | 555 | */ |
| 592 | 556 | if (d->plr) |
| 593 | 557 | d->plr->d = NULL; |
| 558 | + domain_free(hw_dom); | |
| 594 | 559 | |
| 595 | − kfree(hw_dom->ctrl_val); | |
| 596 | − kfree(hw_dom->mbps_val); | |
| 597 | − bitmap_free(d->rmid_busy_llc); | |
| 598 | − kfree(d->mbm_total); | |
| 599 | − kfree(d->mbm_local); | |
| 600 | − kfree(hw_dom); | |
| 601 | 560 | return; |
| 602 | 561 | } |
| 603 | 562 | |
| @@ -61,6 +61,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, · 60 unmodified lines | ||
| 61 | 61 | struct rdt_domain *d) |
| 62 | 62 | { |
| 63 | 63 | struct resctrl_staged_config *cfg; |
| 64 | + u32 closid = data->rdtgrp->closid; | |
| 64 | 65 | struct rdt_resource *r = s->res; |
| 65 | 66 | unsigned long bw_val; |
| 66 | 67 | |
| @@ -72,6 +73,12 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, · 5 unmodified lines | ||
| 72 | 73 | |
| 73 | 74 | if (!bw_validate(data->buf, &bw_val, r)) |
| 74 | 75 | return -EINVAL; |
| 76 | + | |
| 77 | + if (is_mba_sc(r)) { | |
| 78 | + d->mbps_val[closid] = bw_val; | |
| 79 | + return 0; | |
| 80 | + } | |
| 81 | + | |
| 75 | 82 | cfg->new_ctrl = bw_val; |
| 76 | 83 | cfg->have_new_ctrl = true; |
| 77 | 84 | |
| @@ -261,14 +268,13 @@ static u32 get_config_index(u32 closid, enum resctrl_conf_type type) · 183 unmodified lines | ||
| 261 | 268 | |
| 262 | 269 | static bool apply_config(struct rdt_hw_domain *hw_dom, |
| 263 | 270 | struct resctrl_staged_config *cfg, u32 idx, |
| 264 | − cpumask_var_t cpu_mask, bool mba_sc) | |
| 271 | + cpumask_var_t cpu_mask) | |
| 265 | 272 | { |
| 266 | 273 | struct rdt_domain *dom = &hw_dom->d_resctrl; |
| 267 | − u32 *dc = !mba_sc ? hw_dom->ctrl_val : hw_dom->mbps_val; | |
| 268 | 274 | |
| 269 | − if (cfg->new_ctrl != dc[idx]) { | |
| 275 | + if (cfg->new_ctrl != hw_dom->ctrl_val[idx]) { | |
| 270 | 276 | cpumask_set_cpu(cpumask_any(&dom->cpu_mask), cpu_mask); |
| 271 | − dc[idx] = cfg->new_ctrl; | |
| 277 | + hw_dom->ctrl_val[idx] = cfg->new_ctrl; | |
| 272 | 278 | |
| 273 | 279 | return true; |
| 274 | 280 | } |
| @@ -276,6 +282,27 @@ static bool apply_config(struct rdt_hw_domain *hw_dom, · 1 unmodified line | ||
| 276 | 282 | return false; |
| 277 | 283 | } |
| 278 | 284 | |
| 285 | +int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, | |
| 286 | + u32 closid, enum resctrl_conf_type t, u32 cfg_val) | |
| 287 | +{ | |
| 288 | + struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | |
| 289 | + struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); | |
| 290 | + u32 idx = get_config_index(closid, t); | |
| 291 | + struct msr_param msr_param; | |
| 292 | + | |
| 293 | + if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask)) | |
| 294 | + return -EINVAL; | |
| 295 | + | |
| 296 | + hw_dom->ctrl_val[idx] = cfg_val; | |
| 297 | + | |
| 298 | + msr_param.res = r; | |
| 299 | + msr_param.low = idx; | |
| 300 | + msr_param.high = idx + 1; | |
| 301 | + hw_res->msr_update(d, &msr_param, r); | |
| 302 | + | |
| 303 | + return 0; | |
| 304 | +} | |
| 305 | + | |
| 279 | 306 | int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid) |
| 280 | 307 | { |
| 281 | 308 | struct resctrl_staged_config *cfg; |
| @@ -284,14 +311,12 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid) · 2 unmodified lines | ||
| 284 | 311 | enum resctrl_conf_type t; |
| 285 | 312 | cpumask_var_t cpu_mask; |
| 286 | 313 | struct rdt_domain *d; |
| 287 | − bool mba_sc; | |
| 288 | 314 | int cpu; |
| 289 | 315 | u32 idx; |
| 290 | 316 | |
| 291 | 317 | if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL)) |
| 292 | 318 | return -ENOMEM; |
| 293 | 319 | |
| 294 | − mba_sc = is_mba_sc(r); | |
| 295 | 320 | msr_param.res = NULL; |
| 296 | 321 | list_for_each_entry(d, &r->domains, list) { |
| 297 | 322 | hw_dom = resctrl_to_arch_dom(d); |
| @@ -301,7 +326,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid) · 3 unmodified lines | ||
| 301 | 326 | continue; |
| 302 | 327 | |
| 303 | 328 | idx = get_config_index(closid, t); |
| 304 | − if (!apply_config(hw_dom, cfg, idx, cpu_mask, mba_sc)) | |
| 329 | + if (!apply_config(hw_dom, cfg, idx, cpu_mask)) | |
| 305 | 330 | continue; |
| 306 | 331 | |
| 307 | 332 | if (!msr_param.res) { |
| @@ -315,11 +340,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid) · 7 unmodified lines | ||
| 315 | 340 | } |
| 316 | 341 | } |
| 317 | 342 | |
| 318 | − /* | |
| 319 | − * Avoid writing the control msr with control values when | |
| 320 | − * MBA software controller is enabled | |
| 321 | − */ | |
| 322 | − if (cpumask_empty(cpu_mask) || mba_sc) | |
| 343 | + if (cpumask_empty(cpu_mask)) | |
| 323 | 344 | goto done; |
| 324 | 345 | cpu = get_cpu(); |
| 325 | 346 | /* Update resource control msr on this CPU if it's in cpu_mask. */ |
| @@ -406,6 +427,14 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, · 80 unmodified lines | ||
| 406 | 427 | |
| 407 | 428 | list_for_each_entry(s, &resctrl_schema_all, list) { |
| 408 | 429 | r = s->res; |
| 430 | + | |
| 431 | + /* | |
| 432 | + * Writes to mba_sc resources update the software controller, | |
| 433 | + * not the control MSR. | |
| 434 | + */ | |
| 435 | + if (is_mba_sc(r)) | |
| 436 | + continue; | |
| 437 | + | |
| 409 | 438 | ret = resctrl_arch_update_domains(r, rdtgrp->closid); |
| 410 | 439 | if (ret) |
| 411 | 440 | goto out; |
| @@ -433,9 +462,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, · 21 unmodified lines | ||
| 433 | 462 | struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); |
| 434 | 463 | u32 idx = get_config_index(closid, type); |
| 435 | 464 | |
| 436 | − if (!is_mba_sc(r)) | |
| 437 | − return hw_dom->ctrl_val[idx]; | |
| 438 | − return hw_dom->mbps_val[idx]; | |
| 465 | + return hw_dom->ctrl_val[idx]; | |
| 439 | 466 | } |
| 440 | 467 | |
| 441 | 468 | static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid) |
| @@ -450,8 +477,12 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo · 8 unmodified lines | ||
| 450 | 477 | if (sep) |
| 451 | 478 | seq_puts(s, ";"); |
| 452 | 479 | |
| 453 | − ctrl_val = resctrl_arch_get_config(r, dom, closid, | |
| 454 | − schema->conf_type); | |
| 480 | + if (is_mba_sc(r)) | |
| 481 | + ctrl_val = dom->mbps_val[closid]; | |
| 482 | + else | |
| 483 | + ctrl_val = resctrl_arch_get_config(r, dom, closid, | |
| 484 | + schema->conf_type); | |
| 485 | + | |
| 455 | 486 | seq_printf(s, r->format_str, dom->id, max_data_width, |
| 456 | 487 | ctrl_val); |
| 457 | 488 | sep = true; |
| @@ -518,7 +549,6 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, · 60 unmodified lines | ||
| 518 | 549 | int rdtgroup_mondata_show(struct seq_file *m, void *arg) |
| 519 | 550 | { |
| 520 | 551 | struct kernfs_open_file *of = m->private; |
| 521 | − struct rdt_hw_resource *hw_res; | |
| 522 | 552 | u32 resid, evtid, domid; |
| 523 | 553 | struct rdtgroup *rdtgrp; |
| 524 | 554 | struct rdt_resource *r; |
| @@ -538,8 +568,7 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg) · 13 unmodified lines | ||
| 538 | 568 | domid = md.u.domid; |
| 539 | 569 | evtid = md.u.evtid; |
| 540 | 570 | |
| 541 | − hw_res = &rdt_resources_all[resid]; | |
| 542 | − r = &hw_res->r_resctrl; | |
| 571 | + r = &rdt_resources_all[resid].r_resctrl; | |
| 543 | 572 | d = rdt_find_domain(r, domid, NULL); |
| 544 | 573 | if (IS_ERR_OR_NULL(d)) { |
| 545 | 574 | ret = -ENOENT; |
| @@ -548,12 +577,12 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg) · 2 unmodified lines | ||
| 548 | 577 | |
| 549 | 578 | mon_event_read(&rr, r, d, rdtgrp, evtid, false); |
| 550 | 579 | |
| 551 | − if (rr.val & RMID_VAL_ERROR) | |
| 580 | + if (rr.err == -EIO) | |
| 552 | 581 | seq_puts(m, "Error\n"); |
| 553 | − else if (rr.val & RMID_VAL_UNAVAIL) | |
| 582 | + else if (rr.err == -EINVAL) | |
| 554 | 583 | seq_puts(m, "Unavailable\n"); |
| 555 | 584 | else |
| 556 | − seq_printf(m, "%llu\n", rr.val * hw_res->mon_scale); | |
| 585 | + seq_printf(m, "%llu\n", rr.val); | |
| 557 | 586 | |
| 558 | 587 | out: |
| 559 | 588 | rdtgroup_kn_unlock(of->kn); |
| @@ -22,21 +22,12 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #define L2_QOS_CDP_ENABLE 0x01ULL |
| 24 | 24 | |
| 25 | −/* | |
| 26 | − * Event IDs are used to program IA32_QM_EVTSEL before reading event | |
| 27 | − * counter from IA32_QM_CTR | |
| 28 | − */ | |
| 29 | −#define QOS_L3_OCCUP_EVENT_ID 0x01 | |
| 30 | −#define QOS_L3_MBM_TOTAL_EVENT_ID 0x02 | |
| 31 | −#define QOS_L3_MBM_LOCAL_EVENT_ID 0x03 | |
| 32 | − | |
| 33 | 25 | #define CQM_LIMBOCHECK_INTERVAL 1000 |
| 34 | 26 | |
| 35 | 27 | #define MBM_CNTR_WIDTH_BASE 24 |
| 36 | 28 | #define MBM_OVERFLOW_INTERVAL 1000 |
| 37 | 29 | #define MAX_MBA_BW 100u |
| 38 | 30 | #define MBA_IS_LINEAR 0x4 |
| 39 | −#define MBA_MAX_MBPS U32_MAX | |
| 40 | 31 | #define MAX_MBA_BW_AMD 0x800 |
| 41 | 32 | #define MBM_CNTR_WIDTH_OFFSET_AMD 20 |
| 42 | 33 | |
| @@ -74,7 +65,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); · 31 unmodified lines | ||
| 74 | 65 | * @list: entry in &rdt_resource->evt_list |
| 75 | 66 | */ |
| 76 | 67 | struct mon_evt { |
| 77 | − u32 evtid; | |
| 68 | + enum resctrl_event_id evtid; | |
| 78 | 69 | char *name; |
| 79 | 70 | struct list_head list; |
| 80 | 71 | }; |
| @@ -91,9 +82,9 @@ struct mon_evt { · 10 unmodified lines | ||
| 91 | 82 | union mon_data_bits { |
| 92 | 83 | void *priv; |
| 93 | 84 | struct { |
| 94 | − unsigned int rid : 10; | |
| 95 | − unsigned int evtid : 8; | |
| 96 | − unsigned int domid : 14; | |
| 85 | + unsigned int rid : 10; | |
| 86 | + enum resctrl_event_id evtid : 8; | |
| 87 | + unsigned int domid : 14; | |
| 97 | 88 | } u; |
| 98 | 89 | }; |
| 99 | 90 | |
| @@ -101,12 +92,12 @@ struct rmid_read { · 1 unmodified line | ||
| 101 | 92 | struct rdtgroup *rgrp; |
| 102 | 93 | struct rdt_resource *r; |
| 103 | 94 | struct rdt_domain *d; |
| 104 | − int evtid; | |
| 95 | + enum resctrl_event_id evtid; | |
| 105 | 96 | bool first; |
| 97 | + int err; | |
| 106 | 98 | u64 val; |
| 107 | 99 | }; |
| 108 | 100 | |
| 109 | −extern unsigned int resctrl_cqm_threshold; | |
| 110 | 101 | extern bool rdt_alloc_capable; |
| 111 | 102 | extern bool rdt_mon_capable; |
| 112 | 103 | extern unsigned int rdt_mon_features; |
| @@ -288,35 +279,45 @@ struct rftype { · 175 unmodified lines | ||
| 288 | 279 | |
| 289 | 280 | /** |
| 290 | 281 | * struct mbm_state - status for each MBM counter in each domain |
| 291 | − * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) | |
| 292 | − * @prev_msr: Value of IA32_QM_CTR for this RMID last time we read it | |
| 293 | − * @prev_bw_msr:Value of previous IA32_QM_CTR for bandwidth counting | |
| 282 | + * @prev_bw_bytes: Previous bytes value read for bandwidth calculation | |
| 294 | 283 | * @prev_bw: The most recent bandwidth in MBps |
| 295 | 284 | * @delta_bw: Difference between the current and previous bandwidth |
| 296 | 285 | * @delta_comp: Indicates whether to compute the delta_bw |
| 297 | 286 | */ |
| 298 | 287 | struct mbm_state { |
| 299 | − u64 chunks; | |
| 300 | − u64 prev_msr; | |
| 301 | − u64 prev_bw_msr; | |
| 288 | + u64 prev_bw_bytes; | |
| 302 | 289 | u32 prev_bw; |
| 303 | 290 | u32 delta_bw; |
| 304 | 291 | bool delta_comp; |
| 305 | 292 | }; |
| 306 | 293 | |
| 294 | +/** | |
| 295 | + * struct arch_mbm_state - values used to compute resctrl_arch_rmid_read()s | |
| 296 | + * return value. | |
| 297 | + * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) | |
| 298 | + * @prev_msr: Value of IA32_QM_CTR last time it was read for the RMID used to | |
| 299 | + * find this struct. | |
| 300 | + */ | |
| 301 | +struct arch_mbm_state { | |
| 302 | + u64 chunks; | |
| 303 | + u64 prev_msr; | |
| 304 | +}; | |
| 305 | + | |
| 307 | 306 | /** |
| 308 | 307 | * struct rdt_hw_domain - Arch private attributes of a set of CPUs that share |
| 309 | 308 | * a resource |
| 310 | 309 | * @d_resctrl: Properties exposed to the resctrl file system |
| 311 | 310 | * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) |
| 312 | − * @mbps_val: When mba_sc is enabled, this holds the bandwidth in MBps | |
| 311 | + * @arch_mbm_total: arch private state for MBM total bandwidth | |
| 312 | + * @arch_mbm_local: arch private state for MBM local bandwidth | |
| 313 | 313 | * |
| 314 | 314 | * Members of this structure are accessed via helpers that provide abstraction. |
| 315 | 315 | */ |
| 316 | 316 | struct rdt_hw_domain { |
| 317 | 317 | struct rdt_domain d_resctrl; |
| 318 | 318 | u32 *ctrl_val; |
| 319 | − u32 *mbps_val; | |
| 319 | + struct arch_mbm_state *arch_mbm_total; | |
| 320 | + struct arch_mbm_state *arch_mbm_local; | |
| 320 | 321 | }; |
| 321 | 322 | |
| 322 | 323 | static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r) |
| @@ -459,14 +460,6 @@ int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable); · 136 unmodified lines | ||
| 459 | 460 | for_each_rdt_resource(r) \ |
| 460 | 461 | if (r->mon_capable) |
| 461 | 462 | |
| 462 | −#define for_each_alloc_enabled_rdt_resource(r) \ | |
| 463 | − for_each_rdt_resource(r) \ | |
| 464 | − if (r->alloc_enabled) | |
| 465 | − | |
| 466 | −#define for_each_mon_enabled_rdt_resource(r) \ | |
| 467 | − for_each_rdt_resource(r) \ | |
| 468 | − if (r->mon_enabled) | |
| 469 | − | |
| 470 | 463 | /* CPUID.(EAX=10H, ECX=ResID=1).EAX */ |
| 471 | 464 | union cpuid_0x10_1_eax { |
| 472 | 465 | struct { |
| @@ -530,10 +523,6 @@ void free_rmid(u32 rmid); · 57 unmodified lines | ||
| 530 | 523 | int rdt_get_mon_l3_config(struct rdt_resource *r); |
| 531 | 524 | void mon_event_count(void *info); |
| 532 | 525 | int rdtgroup_mondata_show(struct seq_file *m, void *arg); |
| 533 | −void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | |
| 534 | − unsigned int dom_id); | |
| 535 | −void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | |
| 536 | − struct rdt_domain *d); | |
| 537 | 526 | void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, |
| 538 | 527 | struct rdt_domain *d, struct rdtgroup *rdtgrp, |
| 539 | 528 | int evtid, int first); |
| @@ -542,8 +531,6 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, · 2 unmodified lines | ||
| 542 | 531 | void mbm_handle_overflow(struct work_struct *work); |
| 543 | 532 | void __init intel_rdt_mbm_apply_quirk(void); |
| 544 | 533 | bool is_mba_sc(struct rdt_resource *r); |
| 545 | −void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm); | |
| 546 | −u32 delay_bw_map(unsigned long bw, struct rdt_resource *r); | |
| 547 | 534 | void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms); |
| 548 | 535 | void cqm_handle_limbo(struct work_struct *work); |
| 549 | 536 | bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d); |
| @@ -16,8 +16,12 @@ · 15 unmodified lines | ||
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | 18 | #include <linux/module.h> |
| 19 | +#include <linux/sizes.h> | |
| 19 | 20 | #include <linux/slab.h> |
| 21 | + | |
| 20 | 22 | #include <asm/cpu_device_id.h> |
| 23 | +#include <asm/resctrl.h> | |
| 24 | + | |
| 21 | 25 | #include "internal.h" |
| 22 | 26 | |
| 23 | 27 | struct rmid_entry { |
| @@ -37,8 +41,8 @@ static LIST_HEAD(rmid_free_lru); · 13 unmodified lines | ||
| 37 | 41 | * @rmid_limbo_count count of currently unused but (potentially) |
| 38 | 42 | * dirty RMIDs. |
| 39 | 43 | * This counts RMIDs that no one is currently using but that |
| 40 | − * may have a occupancy value > intel_cqm_threshold. User can change | |
| 41 | − * the threshold occupancy value. | |
| 44 | + * may have a occupancy value > resctrl_rmid_realloc_threshold. User can | |
| 45 | + * change the threshold occupancy value. | |
| 42 | 46 | */ |
| 43 | 47 | static unsigned int rmid_limbo_count; |
| 44 | 48 | |
| @@ -59,10 +63,15 @@ bool rdt_mon_capable; · 14 unmodified lines | ||
| 59 | 63 | unsigned int rdt_mon_features; |
| 60 | 64 | |
| 61 | 65 | /* |
| 62 | − * This is the threshold cache occupancy at which we will consider an | |
| 66 | + * This is the threshold cache occupancy in bytes at which we will consider an | |
| 63 | 67 | * RMID available for re-allocation. |
| 64 | 68 | */ |
| 65 | −unsigned int resctrl_cqm_threshold; | |
| 69 | +unsigned int resctrl_rmid_realloc_threshold; | |
| 70 | + | |
| 71 | +/* | |
| 72 | + * This is the maximum value for the reallocation threshold, in bytes. | |
| 73 | + */ | |
| 74 | +unsigned int resctrl_rmid_realloc_limit; | |
| 66 | 75 | |
| 67 | 76 | #define CF(cf) ((unsigned long)(1048576 * (cf) + 0.5)) |
| 68 | 77 | |
| @@ -137,9 +146,54 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid) · 68 unmodified lines | ||
| 137 | 146 | return entry; |
| 138 | 147 | } |
| 139 | 148 | |
| 140 | −static u64 __rmid_read(u32 rmid, u32 eventid) | |
| 149 | +static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom, | |
| 150 | + u32 rmid, | |
| 151 | + enum resctrl_event_id eventid) | |
| 141 | 152 | { |
| 142 | − u64 val; | |
| 153 | + switch (eventid) { | |
| 154 | + case QOS_L3_OCCUP_EVENT_ID: | |
| 155 | + return NULL; | |
| 156 | + case QOS_L3_MBM_TOTAL_EVENT_ID: | |
| 157 | + return &hw_dom->arch_mbm_total[rmid]; | |
| 158 | + case QOS_L3_MBM_LOCAL_EVENT_ID: | |
| 159 | + return &hw_dom->arch_mbm_local[rmid]; | |
| 160 | + } | |
| 161 | + | |
| 162 | + /* Never expect to get here */ | |
| 163 | + WARN_ON_ONCE(1); | |
| 164 | + | |
| 165 | + return NULL; | |
| 166 | +} | |
| 167 | + | |
| 168 | +void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d, | |
| 169 | + u32 rmid, enum resctrl_event_id eventid) | |
| 170 | +{ | |
| 171 | + struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); | |
| 172 | + struct arch_mbm_state *am; | |
| 173 | + | |
| 174 | + am = get_arch_mbm_state(hw_dom, rmid, eventid); | |
| 175 | + if (am) | |
| 176 | + memset(am, 0, sizeof(*am)); | |
| 177 | +} | |
| 178 | + | |
| 179 | +static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width) | |
| 180 | +{ | |
| 181 | + u64 shift = 64 - width, chunks; | |
| 182 | + | |
| 183 | + chunks = (cur_msr << shift) - (prev_msr << shift); | |
| 184 | + return chunks >> shift; | |
| 185 | +} | |
| 186 | + | |
| 187 | +int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, | |
| 188 | + u32 rmid, enum resctrl_event_id eventid, u64 *val) | |
| 189 | +{ | |
| 190 | + struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | |
| 191 | + struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); | |
| 192 | + struct arch_mbm_state *am; | |
| 193 | + u64 msr_val, chunks; | |
| 194 | + | |
| 195 | + if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask)) | |
| 196 | + return -EINVAL; | |
| 143 | 197 | |
| 144 | 198 | /* |
| 145 | 199 | * As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured |
| @@ -150,16 +204,26 @@ static u64 __rmid_read(u32 rmid, u32 eventid) · 4 unmodified lines | ||
| 150 | 204 | * are error bits. |
| 151 | 205 | */ |
| 152 | 206 | wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); |
| 153 | − rdmsrl(MSR_IA32_QM_CTR, val); | |
| 154 | − | |
| 155 | − return val; | |
| 156 | −} | |
| 207 | + rdmsrl(MSR_IA32_QM_CTR, msr_val); | |
| 208 | + | |
| 209 | + if (msr_val & RMID_VAL_ERROR) | |
| 210 | + return -EIO; | |
| 211 | + if (msr_val & RMID_VAL_UNAVAIL) | |
| 212 | + return -EINVAL; | |
| 213 | + | |
| 214 | + am = get_arch_mbm_state(hw_dom, rmid, eventid); | |
| 215 | + if (am) { | |
| 216 | + am->chunks += mbm_overflow_count(am->prev_msr, msr_val, | |
| 217 | + hw_res->mbm_width); | |
| 218 | + chunks = get_corrected_mbm_count(rmid, am->chunks); | |
| 219 | + am->prev_msr = msr_val; | |
| 220 | + } else { | |
| 221 | + chunks = msr_val; | |
| 222 | + } | |
| 157 | 223 | |
| 158 | −static bool rmid_dirty(struct rmid_entry *entry) | |
| 159 | −{ | |
| 160 | − u64 val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID); | |
| 224 | + *val = chunks * hw_res->mon_scale; | |
| 161 | 225 | |
| 162 | − return val >= resctrl_cqm_threshold; | |
| 226 | + return 0; | |
| 163 | 227 | } |
| 164 | 228 | |
| 165 | 229 | /* |
| @@ -170,11 +234,11 @@ static bool rmid_dirty(struct rmid_entry *entry) · 4 unmodified lines | ||
| 170 | 234 | */ |
| 171 | 235 | void __check_limbo(struct rdt_domain *d, bool force_free) |
| 172 | 236 | { |
| 237 | + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; | |
| 173 | 238 | struct rmid_entry *entry; |
| 174 | − struct rdt_resource *r; | |
| 175 | 239 | u32 crmid = 1, nrmid; |
| 176 | − | |
| 177 | − r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; | |
| 240 | + bool rmid_dirty; | |
| 241 | + u64 val = 0; | |
| 178 | 242 | |
| 179 | 243 | /* |
| 180 | 244 | * Skip RMID 0 and start from RMID 1 and check all the RMIDs that |
| @@ -188,7 +252,15 @@ void __check_limbo(struct rdt_domain *d, bool force_free) · 7 unmodified lines | ||
| 188 | 252 | break; |
| 189 | 253 | |
| 190 | 254 | entry = __rmid_entry(nrmid); |
| 191 | − if (force_free || !rmid_dirty(entry)) { | |
| 255 | + | |
| 256 | + if (resctrl_arch_rmid_read(r, d, entry->rmid, | |
| 257 | + QOS_L3_OCCUP_EVENT_ID, &val)) { | |
| 258 | + rmid_dirty = true; | |
| 259 | + } else { | |
| 260 | + rmid_dirty = (val >= resctrl_rmid_realloc_threshold); | |
| 261 | + } | |
| 262 | + | |
| 263 | + if (force_free || !rmid_dirty) { | |
| 192 | 264 | clear_bit(entry->rmid, d->rmid_busy_llc); |
| 193 | 265 | if (!--entry->busy) { |
| 194 | 266 | rmid_limbo_count--; |
| @@ -227,19 +299,19 @@ int alloc_rmid(void) · 32 unmodified lines | ||
| 227 | 299 | |
| 228 | 300 | static void add_rmid_to_limbo(struct rmid_entry *entry) |
| 229 | 301 | { |
| 230 | − struct rdt_resource *r; | |
| 302 | + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; | |
| 231 | 303 | struct rdt_domain *d; |
| 232 | − int cpu; | |
| 233 | − u64 val; | |
| 234 | − | |
| 235 | − r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl; | |
| 304 | + int cpu, err; | |
| 305 | + u64 val = 0; | |
| 236 | 306 | |
| 237 | 307 | entry->busy = 0; |
| 238 | 308 | cpu = get_cpu(); |
| 239 | 309 | list_for_each_entry(d, &r->domains, list) { |
| 240 | 310 | if (cpumask_test_cpu(cpu, &d->cpu_mask)) { |
| 241 | − val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID); | |
| 242 | − if (val <= resctrl_cqm_threshold) | |
| 311 | + err = resctrl_arch_rmid_read(r, d, entry->rmid, | |
| 312 | + QOS_L3_OCCUP_EVENT_ID, | |
| 313 | + &val); | |
| 314 | + if (err || val <= resctrl_rmid_realloc_threshold) | |
| 243 | 315 | continue; |
| 244 | 316 | } |
| 245 | 317 | |
| @@ -277,24 +349,18 @@ void free_rmid(u32 rmid) · 31 unmodified lines | ||
| 277 | 349 | list_add_tail(&entry->list, &rmid_free_lru); |
| 278 | 350 | } |
| 279 | 351 | |
| 280 | −static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width) | |
| 352 | +static int __mon_event_count(u32 rmid, struct rmid_read *rr) | |
| 281 | 353 | { |
| 282 | − u64 shift = 64 - width, chunks; | |
| 354 | + struct mbm_state *m; | |
| 355 | + u64 tval = 0; | |
| 283 | 356 | |
| 284 | − chunks = (cur_msr << shift) - (prev_msr << shift); | |
| 285 | − return chunks >> shift; | |
| 286 | −} | |
| 357 | + if (rr->first) | |
| 358 | + resctrl_arch_reset_rmid(rr->r, rr->d, rmid, rr->evtid); | |
| 287 | 359 | |
| 288 | −static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) | |
| 289 | −{ | |
| 290 | − struct rdt_hw_resource *hw_res = resctrl_to_arch_res(rr->r); | |
| 291 | − struct mbm_state *m; | |
| 292 | − u64 chunks, tval; | |
| 360 | + rr->err = resctrl_arch_rmid_read(rr->r, rr->d, rmid, rr->evtid, &tval); | |
| 361 | + if (rr->err) | |
| 362 | + return rr->err; | |
| 293 | 363 | |
| 294 | − tval = __rmid_read(rmid, rr->evtid); | |
| 295 | − if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { | |
| 296 | − return tval; | |
| 297 | − } | |
| 298 | 364 | switch (rr->evtid) { |
| 299 | 365 | case QOS_L3_OCCUP_EVENT_ID: |
| 300 | 366 | rr->val += tval; |
| @@ -308,48 +374,47 @@ static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) · 7 unmodified lines | ||
| 308 | 374 | default: |
| 309 | 375 | /* |
| 310 | 376 | * Code would never reach here because an invalid |
| 311 | − * event id would fail the __rmid_read. | |
| 377 | + * event id would fail in resctrl_arch_rmid_read(). | |
| 312 | 378 | */ |
| 313 | − return RMID_VAL_ERROR; | |
| 379 | + return -EINVAL; | |
| 314 | 380 | } |
| 315 | 381 | |
| 316 | 382 | if (rr->first) { |
| 317 | 383 | memset(m, 0, sizeof(struct mbm_state)); |
| 318 | − m->prev_bw_msr = m->prev_msr = tval; | |
| 319 | 384 | return 0; |
| 320 | 385 | } |
| 321 | 386 | |
| 322 | − chunks = mbm_overflow_count(m->prev_msr, tval, hw_res->mbm_width); | |
| 323 | − m->chunks += chunks; | |
| 324 | − m->prev_msr = tval; | |
| 325 | − | |
| 326 | − rr->val += get_corrected_mbm_count(rmid, m->chunks); | |
| 387 | + rr->val += tval; | |
| 327 | 388 | |
| 328 | 389 | return 0; |
| 329 | 390 | } |
| 330 | 391 | |
| 331 | 392 | /* |
| 393 | + * mbm_bw_count() - Update bw count from values previously read by | |
| 394 | + * __mon_event_count(). | |
| 395 | + * @rmid: The rmid used to identify the cached mbm_state. | |
| 396 | + * @rr: The struct rmid_read populated by __mon_event_count(). | |
| 397 | + * | |
| 332 | 398 | * Supporting function to calculate the memory bandwidth |
| 333 | − * and delta bandwidth in MBps. | |
| 399 | + * and delta bandwidth in MBps. The chunks value previously read by | |
| 400 | + * __mon_event_count() is compared with the chunks value from the previous | |
| 401 | + * invocation. This must be called once per second to maintain values in MBps. | |
| 334 | 402 | */ |
| 335 | 403 | static void mbm_bw_count(u32 rmid, struct rmid_read *rr) |
| 336 | 404 | { |
| 337 | − struct rdt_hw_resource *hw_res = resctrl_to_arch_res(rr->r); | |
| 338 | 405 | struct mbm_state *m = &rr->d->mbm_local[rmid]; |
| 339 | − u64 tval, cur_bw, chunks; | |
| 406 | + u64 cur_bw, bytes, cur_bytes; | |
| 340 | 407 | |
| 341 | − tval = __rmid_read(rmid, rr->evtid); | |
| 342 | − if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) | |
| 343 | − return; | |
| 408 | + cur_bytes = rr->val; | |
| 409 | + bytes = cur_bytes - m->prev_bw_bytes; | |
| 410 | + m->prev_bw_bytes = cur_bytes; | |
| 344 | 411 | |
| 345 | − chunks = mbm_overflow_count(m->prev_bw_msr, tval, hw_res->mbm_width); | |
| 346 | − cur_bw = (get_corrected_mbm_count(rmid, chunks) * hw_res->mon_scale) >> 20; | |
| 412 | + cur_bw = bytes / SZ_1M; | |
| 347 | 413 | |
| 348 | 414 | if (m->delta_comp) |
| 349 | 415 | m->delta_bw = abs(cur_bw - m->prev_bw); |
| 350 | 416 | m->delta_comp = false; |
| 351 | 417 | m->prev_bw = cur_bw; |
| 352 | − m->prev_bw_msr = tval; | |
| 353 | 418 | } |
| 354 | 419 | |
| 355 | 420 | /* |
| @@ -361,11 +426,11 @@ void mon_event_count(void *info) · 5 unmodified lines | ||
| 361 | 426 | struct rdtgroup *rdtgrp, *entry; |
| 362 | 427 | struct rmid_read *rr = info; |
| 363 | 428 | struct list_head *head; |
| 364 | − u64 ret_val; | |
| 429 | + int ret; | |
| 365 | 430 | |
| 366 | 431 | rdtgrp = rr->rgrp; |
| 367 | 432 | |
| 368 | − ret_val = __mon_event_count(rdtgrp->mon.rmid, rr); | |
| 433 | + ret = __mon_event_count(rdtgrp->mon.rmid, rr); | |
| 369 | 434 | |
| 370 | 435 | /* |
| 371 | 436 | * For Ctrl groups read data from child monitor groups and |
| @@ -377,13 +442,17 @@ void mon_event_count(void *info) · 5 unmodified lines | ||
| 377 | 442 | if (rdtgrp->type == RDTCTRL_GROUP) { |
| 378 | 443 | list_for_each_entry(entry, head, mon.crdtgrp_list) { |
| 379 | 444 | if (__mon_event_count(entry->mon.rmid, rr) == 0) |
| 380 | − ret_val = 0; | |
| 445 | + ret = 0; | |
| 381 | 446 | } |
| 382 | 447 | } |
| 383 | 448 | |
| 384 | − /* Report error if none of rmid_reads are successful */ | |
| 385 | − if (ret_val) | |
| 386 | − rr->val = ret_val; | |
| 449 | + /* | |
| 450 | + * __mon_event_count() calls for newly created monitor groups may | |
| 451 | + * report -EINVAL/Unavailable if the monitor hasn't seen any traffic. | |
| 452 | + * Discard error if any of the monitor event reads succeeded. | |
| 453 | + */ | |
| 454 | + if (ret == 0) | |
| 455 | + rr->err = 0; | |
| 387 | 456 | } |
| 388 | 457 | |
| 389 | 458 | /* |
| @@ -420,10 +489,8 @@ void mon_event_count(void *info) · 30 unmodified lines | ||
| 420 | 489 | */ |
| 421 | 490 | static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) |
| 422 | 491 | { |
| 423 | − u32 closid, rmid, cur_msr, cur_msr_val, new_msr_val; | |
| 492 | + u32 closid, rmid, cur_msr_val, new_msr_val; | |
| 424 | 493 | struct mbm_state *pmbm_data, *cmbm_data; |
| 425 | − struct rdt_hw_resource *hw_r_mba; | |
| 426 | − struct rdt_hw_domain *hw_dom_mba; | |
| 427 | 494 | u32 cur_bw, delta_bw, user_bw; |
| 428 | 495 | struct rdt_resource *r_mba; |
| 429 | 496 | struct rdt_domain *dom_mba; |
| @@ -433,8 +500,8 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) · 3 unmodified lines | ||
| 433 | 500 | if (!is_mbm_local_enabled()) |
| 434 | 501 | return; |
| 435 | 502 | |
| 436 | − hw_r_mba = &rdt_resources_all[RDT_RESOURCE_MBA]; | |
| 437 | − r_mba = &hw_r_mba->r_resctrl; | |
| 503 | + r_mba = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl; | |
| 504 | + | |
| 438 | 505 | closid = rgrp->closid; |
| 439 | 506 | rmid = rgrp->mon.rmid; |
| 440 | 507 | pmbm_data = &dom_mbm->mbm_local[rmid]; |
| @@ -444,16 +511,13 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) · 3 unmodified lines | ||
| 444 | 511 | pr_warn_once("Failure to get domain for MBA update\n"); |
| 445 | 512 | return; |
| 446 | 513 | } |
| 447 | − hw_dom_mba = resctrl_to_arch_dom(dom_mba); | |
| 448 | 514 | |
| 449 | 515 | cur_bw = pmbm_data->prev_bw; |
| 450 | − user_bw = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE); | |
| 516 | + user_bw = dom_mba->mbps_val[closid]; | |
| 451 | 517 | delta_bw = pmbm_data->delta_bw; |
| 452 | − /* | |
| 453 | − * resctrl_arch_get_config() chooses the mbps/ctrl value to return | |
| 454 | − * based on is_mba_sc(). For now, reach into the hw_dom. | |
| 455 | − */ | |
| 456 | − cur_msr_val = hw_dom_mba->ctrl_val[closid]; | |
| 518 | + | |
| 519 | + /* MBA resource doesn't support CDP */ | |
| 520 | + cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE); | |
| 457 | 521 | |
| 458 | 522 | /* |
| 459 | 523 | * For Ctrl groups read data from child monitor groups. |
| @@ -488,9 +552,7 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) · 28 unmodified lines | ||
| 488 | 552 | return; |
| 489 | 553 | } |
| 490 | 554 | |
| 491 | − cur_msr = hw_r_mba->msr_base + closid; | |
| 492 | − wrmsrl(cur_msr, delay_bw_map(new_msr_val, r_mba)); | |
| 493 | − hw_dom_mba->ctrl_val[closid] = new_msr_val; | |
| 555 | + resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val); | |
| 494 | 556 | |
| 495 | 557 | /* |
| 496 | 558 | * Delta values are updated dynamically package wise for each |
| @@ -523,10 +585,12 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid) · 26 unmodified lines | ||
| 523 | 585 | */ |
| 524 | 586 | if (is_mbm_total_enabled()) { |
| 525 | 587 | rr.evtid = QOS_L3_MBM_TOTAL_EVENT_ID; |
| 588 | + rr.val = 0; | |
| 526 | 589 | __mon_event_count(rmid, &rr); |
| 527 | 590 | } |
| 528 | 591 | if (is_mbm_local_enabled()) { |
| 529 | 592 | rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID; |
| 593 | + rr.val = 0; | |
| 530 | 594 | __mon_event_count(rmid, &rr); |
| 531 | 595 | |
| 532 | 596 | /* |
| @@ -686,9 +750,10 @@ int rdt_get_mon_l3_config(struct rdt_resource *r) · 153 unmodified lines | ||
| 686 | 750 | { |
| 687 | 751 | unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset; |
| 688 | 752 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 689 | − unsigned int cl_size = boot_cpu_data.x86_cache_size; | |
| 753 | + unsigned int threshold; | |
| 690 | 754 | int ret; |
| 691 | 755 | |
| 756 | + resctrl_rmid_realloc_limit = boot_cpu_data.x86_cache_size * 1024; | |
| 692 | 757 | hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale; |
| 693 | 758 | r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1; |
| 694 | 759 | hw_res->mbm_width = MBM_CNTR_WIDTH_BASE; |
| @@ -705,10 +770,14 @@ int rdt_get_mon_l3_config(struct rdt_resource *r) · 10 unmodified lines | ||
| 705 | 770 | * |
| 706 | 771 | * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC. |
| 707 | 772 | */ |
| 708 | − resctrl_cqm_threshold = cl_size * 1024 / r->num_rmid; | |
| 773 | + threshold = resctrl_rmid_realloc_limit / r->num_rmid; | |
| 709 | 774 | |
| 710 | − /* h/w works in units of "boot_cpu_data.x86_cache_occ_scale" */ | |
| 711 | − resctrl_cqm_threshold /= hw_res->mon_scale; | |
| 775 | + /* | |
| 776 | + * Because num_rmid may not be a power of two, round the value | |
| 777 | + * to the nearest multiple of hw_res->mon_scale so it matches a | |
| 778 | + * value the hardware will measure. mon_scale may not be a power of 2. | |
| 779 | + */ | |
| 780 | + resctrl_rmid_realloc_threshold = resctrl_arch_round_mon_val(threshold); | |
| 712 | 781 | |
| 713 | 782 | ret = dom_data_init(r); |
| 714 | 783 | if (ret) |
| @@ -717,7 +786,6 @@ int rdt_get_mon_l3_config(struct rdt_resource *r) · 2 unmodified lines | ||
| 717 | 786 | l3_mon_evt_init(r); |
| 718 | 787 | |
| 719 | 788 | r->mon_capable = true; |
| 720 | − r->mon_enabled = true; | |
| 721 | 789 | |
| 722 | 790 | return 0; |
| 723 | 791 | } |
| @@ -420,6 +420,7 @@ static int pseudo_lock_fn(void *_rdtgrp) · 419 unmodified lines | ||
| 420 | 420 | struct pseudo_lock_region *plr = rdtgrp->plr; |
| 421 | 421 | u32 rmid_p, closid_p; |
| 422 | 422 | unsigned long i; |
| 423 | + u64 saved_msr; | |
| 423 | 424 | #ifdef CONFIG_KASAN |
| 424 | 425 | /* |
| 425 | 426 | * The registers used for local register variables are also used |
| @@ -463,6 +464,7 @@ static int pseudo_lock_fn(void *_rdtgrp) · 37 unmodified lines | ||
| 463 | 464 | * the buffer and evict pseudo-locked memory read earlier from the |
| 464 | 465 | * cache. |
| 465 | 466 | */ |
| 467 | + saved_msr = __rdmsr(MSR_MISC_FEATURE_CONTROL); | |
| 466 | 468 | __wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); |
| 467 | 469 | closid_p = this_cpu_read(pqr_state.cur_closid); |
| 468 | 470 | rmid_p = this_cpu_read(pqr_state.cur_rmid); |
| @@ -514,7 +516,7 @@ static int pseudo_lock_fn(void *_rdtgrp) · 45 unmodified lines | ||
| 514 | 516 | __wrmsr(IA32_PQR_ASSOC, rmid_p, closid_p); |
| 515 | 517 | |
| 516 | 518 | /* Re-enable the hardware prefetcher(s) */ |
| 517 | − wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); | |
| 519 | + wrmsrl(MSR_MISC_FEATURE_CONTROL, saved_msr); | |
| 518 | 520 | local_irq_enable(); |
| 519 | 521 | |
| 520 | 522 | plr->thread_done = 1; |
| @@ -835,7 +837,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) · 314 unmodified lines | ||
| 835 | 837 | * First determine which cpus have pseudo-locked regions |
| 836 | 838 | * associated with them. |
| 837 | 839 | */ |
| 838 | − for_each_alloc_enabled_rdt_resource(r) { | |
| 840 | + for_each_alloc_capable_rdt_resource(r) { | |
| 839 | 841 | list_for_each_entry(d_i, &r->domains, list) { |
| 840 | 842 | if (d_i->plr) |
| 841 | 843 | cpumask_or(cpu_with_psl, cpu_with_psl, |
| @@ -871,6 +873,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) · 29 unmodified lines | ||
| 871 | 873 | static int measure_cycles_lat_fn(void *_plr) |
| 872 | 874 | { |
| 873 | 875 | struct pseudo_lock_region *plr = _plr; |
| 876 | + u32 saved_low, saved_high; | |
| 874 | 877 | unsigned long i; |
| 875 | 878 | u64 start, end; |
| 876 | 879 | void *mem_r; |
| @@ -879,6 +882,7 @@ static int measure_cycles_lat_fn(void *_plr) · 2 unmodified lines | ||
| 879 | 882 | /* |
| 880 | 883 | * Disable hardware prefetchers. |
| 881 | 884 | */ |
| 885 | + rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); | |
| 882 | 886 | wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); |
| 883 | 887 | mem_r = READ_ONCE(plr->kmem); |
| 884 | 888 | /* |
| @@ -895,7 +899,7 @@ static int measure_cycles_lat_fn(void *_plr) · 10 unmodified lines | ||
| 895 | 899 | end = rdtsc_ordered(); |
| 896 | 900 | trace_pseudo_lock_mem_latency((u32)(end - start)); |
| 897 | 901 | } |
| 898 | − wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); | |
| 902 | + wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); | |
| 899 | 903 | local_irq_enable(); |
| 900 | 904 | plr->thread_done = 1; |
| 901 | 905 | wake_up_interruptible(&plr->lock_thread_wq); |
| @@ -940,6 +944,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr, · 38 unmodified lines | ||
| 940 | 944 | u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0; |
| 941 | 945 | struct perf_event *miss_event, *hit_event; |
| 942 | 946 | int hit_pmcnum, miss_pmcnum; |
| 947 | + u32 saved_low, saved_high; | |
| 943 | 948 | unsigned int line_size; |
| 944 | 949 | unsigned int size; |
| 945 | 950 | unsigned long i; |
| @@ -973,6 +978,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr, · 27 unmodified lines | ||
| 973 | 978 | /* |
| 974 | 979 | * Disable hardware prefetchers. |
| 975 | 980 | */ |
| 981 | + rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); | |
| 976 | 982 | wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); |
| 977 | 983 | |
| 978 | 984 | /* Initialize rest of local variables */ |
| @@ -1031,7 +1037,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr, · 52 unmodified lines | ||
| 1031 | 1037 | */ |
| 1032 | 1038 | rmb(); |
| 1033 | 1039 | /* Re-enable hardware prefetchers */ |
| 1034 | − wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); | |
| 1040 | + wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); | |
| 1035 | 1041 | local_irq_enable(); |
| 1036 | 1042 | out_hit: |
| 1037 | 1043 | perf_event_release_kernel(hit_event); |
| @@ -1030,10 +1030,7 @@ static int rdt_delay_linear_show(struct kernfs_open_file *of, · 1029 unmodified lines | ||
| 1030 | 1030 | static int max_threshold_occ_show(struct kernfs_open_file *of, |
| 1031 | 1031 | struct seq_file *seq, void *v) |
| 1032 | 1032 | { |
| 1033 | − struct rdt_resource *r = of->kn->parent->priv; | |
| 1034 | − struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | |
| 1035 | − | |
| 1036 | − seq_printf(seq, "%u\n", resctrl_cqm_threshold * hw_res->mon_scale); | |
| 1033 | + seq_printf(seq, "%u\n", resctrl_rmid_realloc_threshold); | |
| 1037 | 1034 | |
| 1038 | 1035 | return 0; |
| 1039 | 1036 | } |
| @@ -1055,7 +1052,6 @@ static int rdt_thread_throttle_mode_show(struct kernfs_open_file *of, · 15 unmodified lines | ||
| 1055 | 1052 | static ssize_t max_threshold_occ_write(struct kernfs_open_file *of, |
| 1056 | 1053 | char *buf, size_t nbytes, loff_t off) |
| 1057 | 1054 | { |
| 1058 | − struct rdt_hw_resource *hw_res; | |
| 1059 | 1055 | unsigned int bytes; |
| 1060 | 1056 | int ret; |
| 1061 | 1057 | |
| @@ -1063,11 +1059,10 @@ static ssize_t max_threshold_occ_write(struct kernfs_open_file *of, · 1 unmodified line | ||
| 1063 | 1059 | if (ret) |
| 1064 | 1060 | return ret; |
| 1065 | 1061 | |
| 1066 | − if (bytes > (boot_cpu_data.x86_cache_size * 1024)) | |
| 1062 | + if (bytes > resctrl_rmid_realloc_limit) | |
| 1067 | 1063 | return -EINVAL; |
| 1068 | 1064 | |
| 1069 | − hw_res = resctrl_to_arch_res(of->kn->parent->priv); | |
| 1070 | − resctrl_cqm_threshold = bytes / hw_res->mon_scale; | |
| 1065 | + resctrl_rmid_realloc_threshold = resctrl_arch_round_mon_val(bytes); | |
| 1071 | 1066 | |
| 1072 | 1067 | return nbytes; |
| 1073 | 1068 | } |
| @@ -1356,11 +1351,13 @@ static int rdtgroup_size_show(struct kernfs_open_file *of, · 282 unmodified lines | ||
| 1356 | 1351 | struct seq_file *s, void *v) |
| 1357 | 1352 | { |
| 1358 | 1353 | struct resctrl_schema *schema; |
| 1354 | + enum resctrl_conf_type type; | |
| 1359 | 1355 | struct rdtgroup *rdtgrp; |
| 1360 | 1356 | struct rdt_resource *r; |
| 1361 | 1357 | struct rdt_domain *d; |
| 1362 | 1358 | unsigned int size; |
| 1363 | 1359 | int ret = 0; |
| 1360 | + u32 closid; | |
| 1364 | 1361 | bool sep; |
| 1365 | 1362 | u32 ctrl; |
| 1366 | 1363 | |
| @@ -1386,8 +1383,11 @@ static int rdtgroup_size_show(struct kernfs_open_file *of, · 19 unmodified lines | ||
| 1386 | 1383 | goto out; |
| 1387 | 1384 | } |
| 1388 | 1385 | |
| 1386 | + closid = rdtgrp->closid; | |
| 1387 | + | |
| 1389 | 1388 | list_for_each_entry(schema, &resctrl_schema_all, list) { |
| 1390 | 1389 | r = schema->res; |
| 1390 | + type = schema->conf_type; | |
| 1391 | 1391 | sep = false; |
| 1392 | 1392 | seq_printf(s, "%*s:", max_name_width, schema->name); |
| 1393 | 1393 | list_for_each_entry(d, &r->domains, list) { |
| @@ -1396,9 +1396,12 @@ static int rdtgroup_size_show(struct kernfs_open_file *of, · 2 unmodified lines | ||
| 1396 | 1396 | if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) { |
| 1397 | 1397 | size = 0; |
| 1398 | 1398 | } else { |
| 1399 | − ctrl = resctrl_arch_get_config(r, d, | |
| 1400 | − rdtgrp->closid, | |
| 1401 | − schema->conf_type); | |
| 1399 | + if (is_mba_sc(r)) | |
| 1400 | + ctrl = d->mbps_val[closid]; | |
| 1401 | + else | |
| 1402 | + ctrl = resctrl_arch_get_config(r, d, | |
| 1403 | + closid, | |
| 1404 | + type); | |
| 1402 | 1405 | if (r->rid == RDT_RESOURCE_MBA) |
| 1403 | 1406 | size = ctrl; |
| 1404 | 1407 | else |
| @@ -1756,7 +1759,7 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) · 351 unmodified lines | ||
| 1756 | 1759 | if (ret) |
| 1757 | 1760 | goto out_destroy; |
| 1758 | 1761 | |
| 1759 | − /* loop over enabled controls, these are all alloc_enabled */ | |
| 1762 | + /* loop over enabled controls, these are all alloc_capable */ | |
| 1760 | 1763 | list_for_each_entry(s, &resctrl_schema_all, list) { |
| 1761 | 1764 | r = s->res; |
| 1762 | 1765 | fflags = r->fflags | RF_CTRL_INFO; |
| @@ -1765,7 +1768,7 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) · 2 unmodified lines | ||
| 1765 | 1768 | goto out_destroy; |
| 1766 | 1769 | } |
| 1767 | 1770 | |
| 1768 | − for_each_mon_enabled_rdt_resource(r) { | |
| 1771 | + for_each_mon_capable_rdt_resource(r) { | |
| 1769 | 1772 | fflags = r->fflags | RF_MON_INFO; |
| 1770 | 1773 | sprintf(name, "%s_MON", r->name); |
| 1771 | 1774 | ret = rdtgroup_mkdir_info_resdir(r, name, fflags); |
| @@ -1889,26 +1892,61 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r) · 117 unmodified lines | ||
| 1889 | 1892 | l3_qos_cfg_update(&hw_res->cdp_enabled); |
| 1890 | 1893 | } |
| 1891 | 1894 | |
| 1895 | +static int mba_sc_domain_allocate(struct rdt_resource *r, struct rdt_domain *d) | |
| 1896 | +{ | |
| 1897 | + u32 num_closid = resctrl_arch_get_num_closid(r); | |
| 1898 | + int cpu = cpumask_any(&d->cpu_mask); | |
| 1899 | + int i; | |
| 1900 | + | |
| 1901 | + d->mbps_val = kcalloc_node(num_closid, sizeof(*d->mbps_val), | |
| 1902 | + GFP_KERNEL, cpu_to_node(cpu)); | |
| 1903 | + if (!d->mbps_val) | |
| 1904 | + return -ENOMEM; | |
| 1905 | + | |
| 1906 | + for (i = 0; i < num_closid; i++) | |
| 1907 | + d->mbps_val[i] = MBA_MAX_MBPS; | |
| 1908 | + | |
| 1909 | + return 0; | |
| 1910 | +} | |
| 1911 | + | |
| 1912 | +static void mba_sc_domain_destroy(struct rdt_resource *r, | |
| 1913 | + struct rdt_domain *d) | |
| 1914 | +{ | |
| 1915 | + kfree(d->mbps_val); | |
| 1916 | + d->mbps_val = NULL; | |
| 1917 | +} | |
| 1918 | + | |
| 1892 | 1919 | /* |
| 1893 | − * Enable or disable the MBA software controller | |
| 1894 | − * which helps user specify bandwidth in MBps. | |
| 1895 | 1920 | * MBA software controller is supported only if |
| 1896 | 1921 | * MBM is supported and MBA is in linear scale. |
| 1897 | 1922 | */ |
| 1923 | +static bool supports_mba_mbps(void) | |
| 1924 | +{ | |
| 1925 | + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl; | |
| 1926 | + | |
| 1927 | + return (is_mbm_local_enabled() && | |
| 1928 | + r->alloc_capable && is_mba_linear()); | |
| 1929 | +} | |
| 1930 | + | |
| 1931 | +/* | |
| 1932 | + * Enable or disable the MBA software controller | |
| 1933 | + * which helps user specify bandwidth in MBps. | |
| 1934 | + */ | |
| 1898 | 1935 | static int set_mba_sc(bool mba_sc) |
| 1899 | 1936 | { |
| 1900 | 1937 | struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl; |
| 1901 | − struct rdt_hw_domain *hw_dom; | |
| 1938 | + u32 num_closid = resctrl_arch_get_num_closid(r); | |
| 1902 | 1939 | struct rdt_domain *d; |
| 1940 | + int i; | |
| 1903 | 1941 | |
| 1904 | − if (!is_mbm_enabled() || !is_mba_linear() || | |
| 1905 | − mba_sc == is_mba_sc(r)) | |
| 1942 | + if (!supports_mba_mbps() || mba_sc == is_mba_sc(r)) | |
| 1906 | 1943 | return -EINVAL; |
| 1907 | 1944 | |
| 1908 | 1945 | r->membw.mba_sc = mba_sc; |
| 1946 | + | |
| 1909 | 1947 | list_for_each_entry(d, &r->domains, list) { |
| 1910 | − hw_dom = resctrl_to_arch_dom(d); | |
| 1911 | − setup_default_ctrlval(r, hw_dom->ctrl_val, hw_dom->mbps_val); | |
| 1948 | + for (i = 0; i < num_closid; i++) | |
| 1949 | + d->mbps_val[i] = MBA_MAX_MBPS; | |
| 1912 | 1950 | } |
| 1913 | 1951 | |
| 1914 | 1952 | return 0; |
| @@ -2106,7 +2144,7 @@ static int schemata_list_create(void) · 191 unmodified lines | ||
| 2106 | 2144 | struct rdt_resource *r; |
| 2107 | 2145 | int ret = 0; |
| 2108 | 2146 | |
| 2109 | − for_each_alloc_enabled_rdt_resource(r) { | |
| 2147 | + for_each_alloc_capable_rdt_resource(r) { | |
| 2110 | 2148 | if (resctrl_arch_get_cdp_enabled(r->rid)) { |
| 2111 | 2149 | ret = schemata_list_add(r, CDP_CODE); |
| 2112 | 2150 | if (ret) |
| @@ -2261,7 +2299,7 @@ static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param) · 148 unmodified lines | ||
| 2261 | 2299 | ctx->enable_cdpl2 = true; |
| 2262 | 2300 | return 0; |
| 2263 | 2301 | case Opt_mba_mbps: |
| 2264 | − if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | |
| 2302 | + if (!supports_mba_mbps()) | |
| 2265 | 2303 | return -EINVAL; |
| 2266 | 2304 | ctx->enable_mba_mbps = true; |
| 2267 | 2305 | return 0; |
| @@ -2452,7 +2490,7 @@ static void rdt_kill_sb(struct super_block *sb) · 184 unmodified lines | ||
| 2452 | 2490 | set_mba_sc(false); |
| 2453 | 2491 | |
| 2454 | 2492 | /*Put everything back to default values. */ |
| 2455 | − for_each_alloc_enabled_rdt_resource(r) | |
| 2493 | + for_each_alloc_capable_rdt_resource(r) | |
| 2456 | 2494 | reset_all_ctrls(r); |
| 2457 | 2495 | cdp_disable_all(); |
| 2458 | 2496 | rmdir_all_sub(); |
| @@ -2499,14 +2537,12 @@ static int mon_addfile(struct kernfs_node *parent_kn, const char *name, · 40 unmodified lines | ||
| 2499 | 2537 | * Remove all subdirectories of mon_data of ctrl_mon groups |
| 2500 | 2538 | * and monitor groups with given domain id. |
| 2501 | 2539 | */ |
| 2502 | −void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, unsigned int dom_id) | |
| 2540 | +static void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | |
| 2541 | + unsigned int dom_id) | |
| 2503 | 2542 | { |
| 2504 | 2543 | struct rdtgroup *prgrp, *crgrp; |
| 2505 | 2544 | char name[32]; |
| 2506 | 2545 | |
| 2507 | − if (!r->mon_enabled) | |
| 2508 | − return; | |
| 2509 | − | |
| 2510 | 2546 | list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { |
| 2511 | 2547 | sprintf(name, "mon_%s_%02d", r->name, dom_id); |
| 2512 | 2548 | kernfs_remove_by_name(prgrp->mon.mon_data_kn, name); |
| @@ -2565,16 +2601,13 @@ out_destroy: · 52 unmodified lines | ||
| 2565 | 2601 | * Add all subdirectories of mon_data for "ctrl_mon" groups |
| 2566 | 2602 | * and "monitor" groups with given domain id. |
| 2567 | 2603 | */ |
| 2568 | −void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | |
| 2569 | − struct rdt_domain *d) | |
| 2604 | +static void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | |
| 2605 | + struct rdt_domain *d) | |
| 2570 | 2606 | { |
| 2571 | 2607 | struct kernfs_node *parent_kn; |
| 2572 | 2608 | struct rdtgroup *prgrp, *crgrp; |
| 2573 | 2609 | struct list_head *head; |
| 2574 | 2610 | |
| 2575 | − if (!r->mon_enabled) | |
| 2576 | − return; | |
| 2577 | − | |
| 2578 | 2611 | list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { |
| 2579 | 2612 | parent_kn = prgrp->mon.mon_data_kn; |
| 2580 | 2613 | mkdir_mondata_subdir(parent_kn, d, r, prgrp); |
| @@ -2642,7 +2675,7 @@ static int mkdir_mondata_all(struct kernfs_node *parent_kn, · 61 unmodified lines | ||
| 2642 | 2675 | * Create the subdirectories for each domain. Note that all events |
| 2643 | 2676 | * in a domain like L3 are grouped into a resource whose domain is L3 |
| 2644 | 2677 | */ |
| 2645 | − for_each_mon_enabled_rdt_resource(r) { | |
| 2678 | + for_each_mon_capable_rdt_resource(r) { | |
| 2646 | 2679 | ret = mkdir_mondata_subdir_alldom(kn, r, prgrp); |
| 2647 | 2680 | if (ret) |
| 2648 | 2681 | goto out_destroy; |
| @@ -2786,14 +2819,19 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid) · 137 unmodified lines | ||
| 2786 | 2819 | } |
| 2787 | 2820 | |
| 2788 | 2821 | /* Initialize MBA resource with default values. */ |
| 2789 | −static void rdtgroup_init_mba(struct rdt_resource *r) | |
| 2822 | +static void rdtgroup_init_mba(struct rdt_resource *r, u32 closid) | |
| 2790 | 2823 | { |
| 2791 | 2824 | struct resctrl_staged_config *cfg; |
| 2792 | 2825 | struct rdt_domain *d; |
| 2793 | 2826 | |
| 2794 | 2827 | list_for_each_entry(d, &r->domains, list) { |
| 2828 | + if (is_mba_sc(r)) { | |
| 2829 | + d->mbps_val[closid] = MBA_MAX_MBPS; | |
| 2830 | + continue; | |
| 2831 | + } | |
| 2832 | + | |
| 2795 | 2833 | cfg = &d->staged_config[CDP_NONE]; |
| 2796 | − cfg->new_ctrl = is_mba_sc(r) ? MBA_MAX_MBPS : r->default_ctrl; | |
| 2834 | + cfg->new_ctrl = r->default_ctrl; | |
| 2797 | 2835 | cfg->have_new_ctrl = true; |
| 2798 | 2836 | } |
| 2799 | 2837 | } |
| @@ -2808,7 +2846,9 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp) · 8 unmodified lines | ||
| 2808 | 2846 | list_for_each_entry(s, &resctrl_schema_all, list) { |
| 2809 | 2847 | r = s->res; |
| 2810 | 2848 | if (r->rid == RDT_RESOURCE_MBA) { |
| 2811 | − rdtgroup_init_mba(r); | |
| 2849 | + rdtgroup_init_mba(r, rdtgrp->closid); | |
| 2850 | + if (is_mba_sc(r)) | |
| 2851 | + continue; | |
| 2812 | 2852 | } else { |
| 2813 | 2853 | ret = rdtgroup_init_cat(s, rdtgrp->closid); |
| 2814 | 2854 | if (ret < 0) |
| @@ -3236,6 +3276,110 @@ out: · 421 unmodified lines | ||
| 3236 | 3276 | return ret; |
| 3237 | 3277 | } |
| 3238 | 3278 | |
| 3279 | +static void domain_destroy_mon_state(struct rdt_domain *d) | |
| 3280 | +{ | |
| 3281 | + bitmap_free(d->rmid_busy_llc); | |
| 3282 | + kfree(d->mbm_total); | |
| 3283 | + kfree(d->mbm_local); | |
| 3284 | +} | |
| 3285 | + | |
| 3286 | +void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d) | |
| 3287 | +{ | |
| 3288 | + lockdep_assert_held(&rdtgroup_mutex); | |
| 3289 | + | |
| 3290 | + if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA) | |
| 3291 | + mba_sc_domain_destroy(r, d); | |
| 3292 | + | |
| 3293 | + if (!r->mon_capable) | |
| 3294 | + return; | |
| 3295 | + | |
| 3296 | + /* | |
| 3297 | + * If resctrl is mounted, remove all the | |
| 3298 | + * per domain monitor data directories. | |
| 3299 | + */ | |
| 3300 | + if (static_branch_unlikely(&rdt_mon_enable_key)) | |
| 3301 | + rmdir_mondata_subdir_allrdtgrp(r, d->id); | |
| 3302 | + | |
| 3303 | + if (is_mbm_enabled()) | |
| 3304 | + cancel_delayed_work(&d->mbm_over); | |
| 3305 | + if (is_llc_occupancy_enabled() && has_busy_rmid(r, d)) { | |
| 3306 | + /* | |
| 3307 | + * When a package is going down, forcefully | |
| 3308 | + * decrement rmid->ebusy. There is no way to know | |
| 3309 | + * that the L3 was flushed and hence may lead to | |
| 3310 | + * incorrect counts in rare scenarios, but leaving | |
| 3311 | + * the RMID as busy creates RMID leaks if the | |
| 3312 | + * package never comes back. | |
| 3313 | + */ | |
| 3314 | + __check_limbo(d, true); | |
| 3315 | + cancel_delayed_work(&d->cqm_limbo); | |
| 3316 | + } | |
| 3317 | + | |
| 3318 | + domain_destroy_mon_state(d); | |
| 3319 | +} | |
| 3320 | + | |
| 3321 | +static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) | |
| 3322 | +{ | |
| 3323 | + size_t tsize; | |
| 3324 | + | |
| 3325 | + if (is_llc_occupancy_enabled()) { | |
| 3326 | + d->rmid_busy_llc = bitmap_zalloc(r->num_rmid, GFP_KERNEL); | |
| 3327 | + if (!d->rmid_busy_llc) | |
| 3328 | + return -ENOMEM; | |
| 3329 | + } | |
| 3330 | + if (is_mbm_total_enabled()) { | |
| 3331 | + tsize = sizeof(*d->mbm_total); | |
| 3332 | + d->mbm_total = kcalloc(r->num_rmid, tsize, GFP_KERNEL); | |
| 3333 | + if (!d->mbm_total) { | |
| 3334 | + bitmap_free(d->rmid_busy_llc); | |
| 3335 | + return -ENOMEM; | |
| 3336 | + } | |
| 3337 | + } | |
| 3338 | + if (is_mbm_local_enabled()) { | |
| 3339 | + tsize = sizeof(*d->mbm_local); | |
| 3340 | + d->mbm_local = kcalloc(r->num_rmid, tsize, GFP_KERNEL); | |
| 3341 | + if (!d->mbm_local) { | |
| 3342 | + bitmap_free(d->rmid_busy_llc); | |
| 3343 | + kfree(d->mbm_total); | |
| 3344 | + return -ENOMEM; | |
| 3345 | + } | |
| 3346 | + } | |
| 3347 | + | |
| 3348 | + return 0; | |
| 3349 | +} | |
| 3350 | + | |
| 3351 | +int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d) | |
| 3352 | +{ | |
| 3353 | + int err; | |
| 3354 | + | |
| 3355 | + lockdep_assert_held(&rdtgroup_mutex); | |
| 3356 | + | |
| 3357 | + if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA) | |
| 3358 | + /* RDT_RESOURCE_MBA is never mon_capable */ | |
| 3359 | + return mba_sc_domain_allocate(r, d); | |
| 3360 | + | |
| 3361 | + if (!r->mon_capable) | |
| 3362 | + return 0; | |
| 3363 | + | |
| 3364 | + err = domain_setup_mon_state(r, d); | |
| 3365 | + if (err) | |
| 3366 | + return err; | |
| 3367 | + | |
| 3368 | + if (is_mbm_enabled()) { | |
| 3369 | + INIT_DELAYED_WORK(&d->mbm_over, mbm_handle_overflow); | |
| 3370 | + mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL); | |
| 3371 | + } | |
| 3372 | + | |
| 3373 | + if (is_llc_occupancy_enabled()) | |
| 3374 | + INIT_DELAYED_WORK(&d->cqm_limbo, cqm_handle_limbo); | |
| 3375 | + | |
| 3376 | + /* If resctrl is mounted, add per domain monitor data directories. */ | |
| 3377 | + if (static_branch_unlikely(&rdt_mon_enable_key)) | |
| 3378 | + mkdir_mondata_subdir_allrdtgrp(r, d); | |
| 3379 | + | |
| 3380 | + return 0; | |
| 3381 | +} | |
| 3382 | + | |
| 3239 | 3383 | /* |
| 3240 | 3384 | * rdtgroup_init - rdtgroup initialization |
| 3241 | 3385 | * |
| @@ -12,6 +12,9 @@ · 11 unmodified lines | ||
| 12 | 12 | #include "encls.h" |
| 13 | 13 | #include "sgx.h" |
| 14 | 14 | |
| 15 | +static int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, | |
| 16 | + struct sgx_backing *backing); | |
| 17 | + | |
| 15 | 18 | #define PCMDS_PER_PAGE (PAGE_SIZE / sizeof(struct sgx_pcmd)) |
| 16 | 19 | /* |
| 17 | 20 | * 32 PCMD entries share a PCMD page. PCMD_FIRST_MASK is used to |
| @@ -917,7 +920,7 @@ static struct page *sgx_encl_get_backing_page(struct sgx_encl *encl, · 899 unmodified lines | ||
| 917 | 920 | } |
| 918 | 921 | |
| 919 | 922 | /** |
| 920 | − * sgx_encl_get_backing() - Pin the backing storage | |
| 923 | + * __sgx_encl_get_backing() - Pin the backing storage | |
| 921 | 924 | * @encl: an enclave pointer |
| 922 | 925 | * @page_index: enclave page index |
| 923 | 926 | * @backing: data for accessing backing storage for the page |
| @@ -929,7 +932,7 @@ static struct page *sgx_encl_get_backing_page(struct sgx_encl *encl, · 5 unmodified lines | ||
| 929 | 932 | * 0 on success, |
| 930 | 933 | * -errno otherwise. |
| 931 | 934 | */ |
| 932 | −static int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, | |
| 935 | +static int __sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, | |
| 933 | 936 | struct sgx_backing *backing) |
| 934 | 937 | { |
| 935 | 938 | pgoff_t page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index); |
| @@ -1004,7 +1007,7 @@ static struct mem_cgroup *sgx_encl_get_mem_cgroup(struct sgx_encl *encl) · 68 unmodified lines | ||
| 1004 | 1007 | } |
| 1005 | 1008 | |
| 1006 | 1009 | /** |
| 1007 | − * sgx_encl_alloc_backing() - allocate a new backing storage page | |
| 1010 | + * sgx_encl_alloc_backing() - create a new backing storage page | |
| 1008 | 1011 | * @encl: an enclave pointer |
| 1009 | 1012 | * @page_index: enclave page index |
| 1010 | 1013 | * @backing: data for accessing backing storage for the page |
| @@ -1012,7 +1015,9 @@ static struct mem_cgroup *sgx_encl_get_mem_cgroup(struct sgx_encl *encl) · 1 unmodified line | ||
| 1012 | 1015 | * When called from ksgxd, sets the active memcg from one of the |
| 1013 | 1016 | * mms in the enclave's mm_list prior to any backing page allocation, |
| 1014 | 1017 | * in order to ensure that shmem page allocations are charged to the |
| 1015 | − * enclave. | |
| 1018 | + * enclave. Create a backing page for loading data back into an EPC page with | |
| 1019 | + * ELDU. This function takes a reference on a new backing page which | |
| 1020 | + * must be dropped with a corresponding call to sgx_encl_put_backing(). | |
| 1016 | 1021 | * |
| 1017 | 1022 | * Return: |
| 1018 | 1023 | * 0 on success, |
| @@ -1025,7 +1030,7 @@ int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, · 6 unmodified lines | ||
| 1025 | 1030 | struct mem_cgroup *memcg = set_active_memcg(encl_memcg); |
| 1026 | 1031 | int ret; |
| 1027 | 1032 | |
| 1028 | − ret = sgx_encl_get_backing(encl, page_index, backing); | |
| 1033 | + ret = __sgx_encl_get_backing(encl, page_index, backing); | |
| 1029 | 1034 | |
| 1030 | 1035 | set_active_memcg(memcg); |
| 1031 | 1036 | mem_cgroup_put(encl_memcg); |
| @@ -1043,15 +1048,17 @@ int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, · 11 unmodified lines | ||
| 1043 | 1048 | * It is the caller's responsibility to ensure that it is appropriate to use |
| 1044 | 1049 | * sgx_encl_lookup_backing() rather than sgx_encl_alloc_backing(). If lookup is |
| 1045 | 1050 | * not used correctly, this will cause an allocation which is not accounted for. |
| 1051 | + * This function takes a reference on an existing backing page which must be | |
| 1052 | + * dropped with a corresponding call to sgx_encl_put_backing(). | |
| 1046 | 1053 | * |
| 1047 | 1054 | * Return: |
| 1048 | 1055 | * 0 on success, |
| 1049 | 1056 | * -errno otherwise. |
| 1050 | 1057 | */ |
| 1051 | −int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, | |
| 1058 | +static int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, | |
| 1052 | 1059 | struct sgx_backing *backing) |
| 1053 | 1060 | { |
| 1054 | − return sgx_encl_get_backing(encl, page_index, backing); | |
| 1061 | + return __sgx_encl_get_backing(encl, page_index, backing); | |
| 1055 | 1062 | } |
| 1056 | 1063 | |
| 1057 | 1064 | /** |
| @@ -107,8 +107,6 @@ bool current_is_ksgxd(void); · 106 unmodified lines | ||
| 107 | 107 | void sgx_encl_release(struct kref *ref); |
| 108 | 108 | int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); |
| 109 | 109 | const cpumask_t *sgx_encl_cpumask(struct sgx_encl *encl); |
| 110 | −int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, | |
| 111 | − struct sgx_backing *backing); | |
| 112 | 110 | int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, |
| 113 | 111 | struct sgx_backing *backing); |
| 114 | 112 | void sgx_encl_put_backing(struct sgx_backing *backing); |
| @@ -128,7 +128,7 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) · 127 unmodified lines | ||
| 128 | 128 | /* No access to the user space stack of other tasks. Ignore. */ |
| 129 | 129 | break; |
| 130 | 130 | default: |
| 131 | − printk("%sCode: Unable to access opcode bytes at RIP 0x%lx.\n", | |
| 131 | + printk("%sCode: Unable to access opcode bytes at 0x%lx.\n", | |
| 132 | 132 | loglvl, prologue); |
| 133 | 133 | break; |
| 134 | 134 | } |
| @@ -264,11 +264,11 @@ static __init void early_pci_serial_init(char *s) · 263 unmodified lines | ||
| 264 | 264 | bar0 = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0); |
| 265 | 265 | |
| 266 | 266 | /* |
| 267 | − * Verify it is a UART type device | |
| 267 | + * Verify it is a 16550-UART type device | |
| 268 | 268 | */ |
| 269 | 269 | if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) && |
| 270 | 270 | (classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) || |
| 271 | − (((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ { | |
| 271 | + (((classcode >> 8) & 0xff) != PCI_SERIAL_16550_COMPATIBLE)) { | |
| 272 | 272 | if (!force) |
| 273 | 273 | return; |
| 274 | 274 | } |
| @@ -276,22 +276,22 @@ static __init void early_pci_serial_init(char *s) · 1 unmodified line | ||
| 276 | 276 | /* |
| 277 | 277 | * Determine if it is IO or memory mapped |
| 278 | 278 | */ |
| 279 | − if (bar0 & 0x01) { | |
| 279 | + if ((bar0 & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { | |
| 280 | 280 | /* it is IO mapped */ |
| 281 | 281 | serial_in = io_serial_in; |
| 282 | 282 | serial_out = io_serial_out; |
| 283 | − early_serial_base = bar0&0xfffffffc; | |
| 283 | + early_serial_base = bar0 & PCI_BASE_ADDRESS_IO_MASK; | |
| 284 | 284 | write_pci_config(bus, slot, func, PCI_COMMAND, |
| 285 | − cmdreg|PCI_COMMAND_IO); | |
| 285 | + cmdreg|PCI_COMMAND_IO); | |
| 286 | 286 | } else { |
| 287 | 287 | /* It is memory mapped - assume 32-bit alignment */ |
| 288 | 288 | serial_in = mem32_serial_in; |
| 289 | 289 | serial_out = mem32_serial_out; |
| 290 | 290 | /* WARNING! assuming the address is always in the first 4G */ |
| 291 | 291 | early_serial_base = |
| 292 | − (unsigned long)early_ioremap(bar0 & 0xfffffff0, 0x10); | |
| 292 | + (unsigned long)early_ioremap(bar0 & PCI_BASE_ADDRESS_MEM_MASK, 0x10); | |
| 293 | 293 | write_pci_config(bus, slot, func, PCI_COMMAND, |
| 294 | − cmdreg|PCI_COMMAND_MEMORY); | |
| 294 | + cmdreg|PCI_COMMAND_MEMORY); | |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | 297 | /* |
| @@ -4,11 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | #include <linux/platform_device.h> |
| 6 | 6 | #include <linux/mc146818rtc.h> |
| 7 | −#include <linux/acpi.h> | |
| 8 | −#include <linux/bcd.h> | |
| 9 | 7 | #include <linux/export.h> |
| 10 | 8 | #include <linux/pnp.h> |
| 11 | −#include <linux/of.h> | |
| 12 | 9 | |
| 13 | 10 | #include <asm/vsyscall.h> |
| 14 | 11 | #include <asm/x86_init.h> |
| @@ -20,26 +17,23 @@ · 5 unmodified lines | ||
| 20 | 17 | /* |
| 21 | 18 | * This is a special lock that is owned by the CPU and holds the index |
| 22 | 19 | * register we are working with. It is required for NMI access to the |
| 23 | − * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details. | |
| 20 | + * CMOS/RTC registers. See arch/x86/include/asm/mc146818rtc.h for details. | |
| 24 | 21 | */ |
| 25 | 22 | volatile unsigned long cmos_lock; |
| 26 | 23 | EXPORT_SYMBOL(cmos_lock); |
| 27 | 24 | #endif /* CONFIG_X86_32 */ |
| 28 | 25 | |
| 29 | −/* For two digit years assume time is always after that */ | |
| 30 | −#define CMOS_YEARS_OFFS 2000 | |
| 31 | − | |
| 32 | 26 | DEFINE_SPINLOCK(rtc_lock); |
| 33 | 27 | EXPORT_SYMBOL(rtc_lock); |
| 34 | 28 | |
| 35 | 29 | /* |
| 36 | − * In order to set the CMOS clock precisely, set_rtc_mmss has to be | |
| 30 | + * In order to set the CMOS clock precisely, mach_set_cmos_time has to be | |
| 37 | 31 | * called 500 ms after the second nowtime has started, because when |
| 38 | 32 | * nowtime is written into the registers of the CMOS clock, it will |
| 39 | 33 | * jump to the next second precisely 500 ms later. Check the Motorola |
| 40 | 34 | * MC146818A or Dallas DS12887 data sheet for details. |
| 41 | 35 | */ |
| 42 | −int mach_set_rtc_mmss(const struct timespec64 *now) | |
| 36 | +int mach_set_cmos_time(const struct timespec64 *now) | |
| 43 | 37 | { |
| 44 | 38 | unsigned long long nowtime = now->tv_sec; |
| 45 | 39 | struct rtc_time tm; |
| @@ -62,8 +56,7 @@ int mach_set_rtc_mmss(const struct timespec64 *now) · 16 unmodified lines | ||
| 62 | 56 | |
| 63 | 57 | void mach_get_cmos_time(struct timespec64 *now) |
| 64 | 58 | { |
| 65 | − unsigned int status, year, mon, day, hour, min, sec, century = 0; | |
| 66 | − unsigned long flags; | |
| 59 | + struct rtc_time tm; | |
| 67 | 60 | |
| 68 | 61 | /* |
| 69 | 62 | * If pm_trace abused the RTC as storage, set the timespec to 0, |
| @@ -74,51 +67,13 @@ void mach_get_cmos_time(struct timespec64 *now) · 4 unmodified lines | ||
| 74 | 67 | return; |
| 75 | 68 | } |
| 76 | 69 | |
| 77 | − spin_lock_irqsave(&rtc_lock, flags); | |
| 78 | − | |
| 79 | − /* | |
| 80 | − * If UIP is clear, then we have >= 244 microseconds before | |
| 81 | − * RTC registers will be updated. Spec sheet says that this | |
| 82 | − * is the reliable way to read RTC - registers. If UIP is set | |
| 83 | − * then the register access might be invalid. | |
| 84 | − */ | |
| 85 | − while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) | |
| 86 | − cpu_relax(); | |
| 87 | − | |
| 88 | − sec = CMOS_READ(RTC_SECONDS); | |
| 89 | − min = CMOS_READ(RTC_MINUTES); | |
| 90 | − hour = CMOS_READ(RTC_HOURS); | |
| 91 | − day = CMOS_READ(RTC_DAY_OF_MONTH); | |
| 92 | − mon = CMOS_READ(RTC_MONTH); | |
| 93 | − year = CMOS_READ(RTC_YEAR); | |
| 94 | − | |
| 95 | −#ifdef CONFIG_ACPI | |
| 96 | − if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | |
| 97 | − acpi_gbl_FADT.century) | |
| 98 | − century = CMOS_READ(acpi_gbl_FADT.century); | |
| 99 | −#endif | |
| 100 | − | |
| 101 | − status = CMOS_READ(RTC_CONTROL); | |
| 102 | − WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY)); | |
| 103 | − | |
| 104 | − spin_unlock_irqrestore(&rtc_lock, flags); | |
| 105 | − | |
| 106 | − if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) { | |
| 107 | − sec = bcd2bin(sec); | |
| 108 | − min = bcd2bin(min); | |
| 109 | − hour = bcd2bin(hour); | |
| 110 | − day = bcd2bin(day); | |
| 111 | − mon = bcd2bin(mon); | |
| 112 | − year = bcd2bin(year); | |
| 70 | + if (mc146818_get_time(&tm)) { | |
| 71 | + pr_err("Unable to read current time from RTC\n"); | |
| 72 | + now->tv_sec = now->tv_nsec = 0; | |
| 73 | + return; | |
| 113 | 74 | } |
| 114 | 75 | |
| 115 | − if (century) { | |
| 116 | − century = bcd2bin(century); | |
| 117 | − year += century * 100; | |
| 118 | − } else | |
| 119 | − year += CMOS_YEARS_OFFS; | |
| 120 | − | |
| 121 | − now->tv_sec = mktime64(year, mon, day, hour, min, sec); | |
| 76 | + now->tv_sec = rtc_tm_to_time64(&tm); | |
| 122 | 77 | now->tv_nsec = 0; |
| 123 | 78 | } |
| 124 | 79 | |
| @@ -63,6 +63,7 @@ · 62 unmodified lines | ||
| 63 | 63 | #include <asm/insn-eval.h> |
| 64 | 64 | #include <asm/vdso.h> |
| 65 | 65 | #include <asm/tdx.h> |
| 66 | +#include <asm/cfi.h> | |
| 66 | 67 | |
| 67 | 68 | #ifdef CONFIG_X86_64 |
| 68 | 69 | #include <asm/x86_init.h> |
| @@ -313,7 +314,8 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 244 unmodified lines | ||
| 313 | 314 | */ |
| 314 | 315 | if (regs->flags & X86_EFLAGS_IF) |
| 315 | 316 | raw_local_irq_enable(); |
| 316 | − if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) { | |
| 317 | + if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN || | |
| 318 | + handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) { | |
| 317 | 319 | regs->ip += LEN_UD2; |
| 318 | 320 | handled = true; |
| 319 | 321 | } |
| @@ -138,7 +138,7 @@ struct x86_platform_ops x86_platform __ro_after_init = { · 137 unmodified lines | ||
| 138 | 138 | .calibrate_cpu = native_calibrate_cpu_early, |
| 139 | 139 | .calibrate_tsc = native_calibrate_tsc, |
| 140 | 140 | .get_wallclock = mach_get_cmos_time, |
| 141 | − .set_wallclock = mach_set_rtc_mmss, | |
| 141 | + .set_wallclock = mach_set_cmos_time, | |
| 142 | 142 | .iommu_shutdown = iommu_shutdown_noop, |
| 143 | 143 | .is_untracked_pat_range = is_ISA_range, |
| 144 | 144 | .nmi_init = default_nmi_init, |
| @@ -902,8 +902,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 901 unmodified lines | ||
| 902 | 902 | entry->edx = 0; |
| 903 | 903 | } |
| 904 | 904 | break; |
| 905 | − case 9: | |
| 906 | − break; | |
| 907 | 905 | case 0xa: { /* Architectural Performance Monitoring */ |
| 908 | 906 | union cpuid10_eax eax; |
| 909 | 907 | union cpuid10_edx edx; |
| @@ -2570,7 +2570,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, · 2569 unmodified lines | ||
| 2570 | 2570 | * bits which we consider mandatory enabled. |
| 2571 | 2571 | * The CR0_READ_SHADOW is what L2 should have expected to read given |
| 2572 | 2572 | * the specifications by L1; It's not enough to take |
| 2573 | − * vmcs12->cr0_read_shadow because on our cr0_guest_host_mask we we | |
| 2573 | + * vmcs12->cr0_read_shadow because on our cr0_guest_host_mask we | |
| 2574 | 2574 | * have more bits than L1 expected. |
| 2575 | 2575 | */ |
| 2576 | 2576 | vmx_set_cr0(vcpu, vmcs12->guest_cr0); |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | 2 | #include <linux/linkage.h> |
| 3 | +#include <asm/asm.h> | |
| 3 | 4 | #include <asm/export.h> |
| 4 | 5 | |
| 5 | 6 | /* |
| @@ -50,3 +51,140 @@ SYM_FUNC_START(clear_page_erms) · 44 unmodified lines | ||
| 50 | 51 | RET |
| 51 | 52 | SYM_FUNC_END(clear_page_erms) |
| 52 | 53 | EXPORT_SYMBOL_GPL(clear_page_erms) |
| 54 | + | |
| 55 | +/* | |
| 56 | + * Default clear user-space. | |
| 57 | + * Input: | |
| 58 | + * rdi destination | |
| 59 | + * rcx count | |
| 60 | + * | |
| 61 | + * Output: | |
| 62 | + * rcx: uncleared bytes or 0 if successful. | |
| 63 | + */ | |
| 64 | +SYM_FUNC_START(clear_user_original) | |
| 65 | + /* | |
| 66 | + * Copy only the lower 32 bits of size as that is enough to handle the rest bytes, | |
| 67 | + * i.e., no need for a 'q' suffix and thus a REX prefix. | |
| 68 | + */ | |
| 69 | + mov %ecx,%eax | |
| 70 | + shr $3,%rcx | |
| 71 | + jz .Lrest_bytes | |
| 72 | + | |
| 73 | + # do the qwords first | |
| 74 | + .p2align 4 | |
| 75 | +.Lqwords: | |
| 76 | + movq $0,(%rdi) | |
| 77 | + lea 8(%rdi),%rdi | |
| 78 | + dec %rcx | |
| 79 | + jnz .Lqwords | |
| 80 | + | |
| 81 | +.Lrest_bytes: | |
| 82 | + and $7, %eax | |
| 83 | + jz .Lexit | |
| 84 | + | |
| 85 | + # now do the rest bytes | |
| 86 | +.Lbytes: | |
| 87 | + movb $0,(%rdi) | |
| 88 | + inc %rdi | |
| 89 | + dec %eax | |
| 90 | + jnz .Lbytes | |
| 91 | + | |
| 92 | +.Lexit: | |
| 93 | + /* | |
| 94 | + * %rax still needs to be cleared in the exception case because this function is called | |
| 95 | + * from inline asm and the compiler expects %rax to be zero when exiting the inline asm, | |
| 96 | + * in case it might reuse it somewhere. | |
| 97 | + */ | |
| 98 | + xor %eax,%eax | |
| 99 | + RET | |
| 100 | + | |
| 101 | +.Lqwords_exception: | |
| 102 | + # convert remaining qwords back into bytes to return to caller | |
| 103 | + shl $3, %rcx | |
| 104 | + and $7, %eax | |
| 105 | + add %rax,%rcx | |
| 106 | + jmp .Lexit | |
| 107 | + | |
| 108 | +.Lbytes_exception: | |
| 109 | + mov %eax,%ecx | |
| 110 | + jmp .Lexit | |
| 111 | + | |
| 112 | + _ASM_EXTABLE_UA(.Lqwords, .Lqwords_exception) | |
| 113 | + _ASM_EXTABLE_UA(.Lbytes, .Lbytes_exception) | |
| 114 | +SYM_FUNC_END(clear_user_original) | |
| 115 | +EXPORT_SYMBOL(clear_user_original) | |
| 116 | + | |
| 117 | +/* | |
| 118 | + * Alternative clear user-space when CPU feature X86_FEATURE_REP_GOOD is | |
| 119 | + * present. | |
| 120 | + * Input: | |
| 121 | + * rdi destination | |
| 122 | + * rcx count | |
| 123 | + * | |
| 124 | + * Output: | |
| 125 | + * rcx: uncleared bytes or 0 if successful. | |
| 126 | + */ | |
| 127 | +SYM_FUNC_START(clear_user_rep_good) | |
| 128 | + # call the original thing for less than a cacheline | |
| 129 | + cmp $64, %rcx | |
| 130 | + jb clear_user_original | |
| 131 | + | |
| 132 | +.Lprep: | |
| 133 | + # copy lower 32-bits for rest bytes | |
| 134 | + mov %ecx, %edx | |
| 135 | + shr $3, %rcx | |
| 136 | + jz .Lrep_good_rest_bytes | |
| 137 | + | |
| 138 | +.Lrep_good_qwords: | |
| 139 | + rep stosq | |
| 140 | + | |
| 141 | +.Lrep_good_rest_bytes: | |
| 142 | + and $7, %edx | |
| 143 | + jz .Lrep_good_exit | |
| 144 | + | |
| 145 | +.Lrep_good_bytes: | |
| 146 | + mov %edx, %ecx | |
| 147 | + rep stosb | |
| 148 | + | |
| 149 | +.Lrep_good_exit: | |
| 150 | + # see .Lexit comment above | |
| 151 | + xor %eax, %eax | |
| 152 | + RET | |
| 153 | + | |
| 154 | +.Lrep_good_qwords_exception: | |
| 155 | + # convert remaining qwords back into bytes to return to caller | |
| 156 | + shl $3, %rcx | |
| 157 | + and $7, %edx | |
| 158 | + add %rdx, %rcx | |
| 159 | + jmp .Lrep_good_exit | |
| 160 | + | |
| 161 | + _ASM_EXTABLE_UA(.Lrep_good_qwords, .Lrep_good_qwords_exception) | |
| 162 | + _ASM_EXTABLE_UA(.Lrep_good_bytes, .Lrep_good_exit) | |
| 163 | +SYM_FUNC_END(clear_user_rep_good) | |
| 164 | +EXPORT_SYMBOL(clear_user_rep_good) | |
| 165 | + | |
| 166 | +/* | |
| 167 | + * Alternative clear user-space when CPU feature X86_FEATURE_ERMS is present. | |
| 168 | + * Input: | |
| 169 | + * rdi destination | |
| 170 | + * rcx count | |
| 171 | + * | |
| 172 | + * Output: | |
| 173 | + * rcx: uncleared bytes or 0 if successful. | |
| 174 | + * | |
| 175 | + */ | |
| 176 | +SYM_FUNC_START(clear_user_erms) | |
| 177 | + # call the original thing for less than a cacheline | |
| 178 | + cmp $64, %rcx | |
| 179 | + jb clear_user_original | |
| 180 | + | |
| 181 | +.Lerms_bytes: | |
| 182 | + rep stosb | |
| 183 | + | |
| 184 | +.Lerms_exit: | |
| 185 | + xorl %eax,%eax | |
| 186 | + RET | |
| 187 | + | |
| 188 | + _ASM_EXTABLE_UA(.Lerms_bytes, .Lerms_exit) | |
| 189 | +SYM_FUNC_END(clear_user_erms) | |
| 190 | +EXPORT_SYMBOL(clear_user_erms) | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright 2002 Andi Kleen */ |
| 3 | 3 | |
| 4 | 4 | #include <linux/linkage.h> |
| 5 | +#include <linux/cfi_types.h> | |
| 5 | 6 | #include <asm/errno.h> |
| 6 | 7 | #include <asm/cpufeatures.h> |
| 7 | 8 | #include <asm/alternative.h> |
| @@ -27,7 +28,7 @@ · 19 unmodified lines | ||
| 27 | 28 | * Output: |
| 28 | 29 | * rax original destination |
| 29 | 30 | */ |
| 30 | −SYM_FUNC_START(__memcpy) | |
| 31 | +SYM_TYPED_FUNC_START(__memcpy) | |
| 31 | 32 | ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \ |
| 32 | 33 | "jmp memcpy_erms", X86_FEATURE_ERMS |
| 33 | 34 | |
| @@ -14,46 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | * Zero Userspace |
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | −unsigned long __clear_user(void __user *addr, unsigned long size) | |
| 18 | −{ | |
| 19 | − long __d0; | |
| 20 | − might_fault(); | |
| 21 | − /* no memory constraint because it doesn't change any memory gcc knows | |
| 22 | − about */ | |
| 23 | − stac(); | |
| 24 | − asm volatile( | |
| 25 | − " testq %[size8],%[size8]\n" | |
| 26 | − " jz 4f\n" | |
| 27 | − " .align 16\n" | |
| 28 | − "0: movq $0,(%[dst])\n" | |
| 29 | − " addq $8,%[dst]\n" | |
| 30 | − " decl %%ecx ; jnz 0b\n" | |
| 31 | − "4: movq %[size1],%%rcx\n" | |
| 32 | − " testl %%ecx,%%ecx\n" | |
| 33 | − " jz 2f\n" | |
| 34 | − "1: movb $0,(%[dst])\n" | |
| 35 | − " incq %[dst]\n" | |
| 36 | − " decl %%ecx ; jnz 1b\n" | |
| 37 | − "2:\n" | |
| 38 | − | |
| 39 | − _ASM_EXTABLE_TYPE_REG(0b, 2b, EX_TYPE_UCOPY_LEN8, %[size1]) | |
| 40 | − _ASM_EXTABLE_UA(1b, 2b) | |
| 41 | − | |
| 42 | − : [size8] "=&c"(size), [dst] "=&D" (__d0) | |
| 43 | − : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr)); | |
| 44 | − clac(); | |
| 45 | − return size; | |
| 46 | −} | |
| 47 | −EXPORT_SYMBOL(__clear_user); | |
| 48 | − | |
| 49 | −unsigned long clear_user(void __user *to, unsigned long n) | |
| 50 | −{ | |
| 51 | − if (access_ok(to, n)) | |
| 52 | − return __clear_user(to, n); | |
| 53 | − return n; | |
| 54 | −} | |
| 55 | −EXPORT_SYMBOL(clear_user); | |
| 56 | − | |
| 57 | 17 | #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE |
| 58 | 18 | /** |
| 59 | 19 | * clean_cache_range - write back a cache range with CLWB |
| @@ -769,6 +769,8 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, · 768 unmodified lines | ||
| 769 | 769 | unsigned long address, struct task_struct *tsk) |
| 770 | 770 | { |
| 771 | 771 | const char *loglvl = task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG; |
| 772 | + /* This is a racy snapshot, but it's better than nothing. */ | |
| 773 | + int cpu = raw_smp_processor_id(); | |
| 772 | 774 | |
| 773 | 775 | if (!unhandled_signal(tsk, SIGSEGV)) |
| 774 | 776 | return; |
| @@ -782,6 +784,14 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, · 7 unmodified lines | ||
| 782 | 784 | |
| 783 | 785 | print_vma_addr(KERN_CONT " in ", regs->ip); |
| 784 | 786 | |
| 787 | + /* | |
| 788 | + * Dump the likely CPU where the fatal segfault happened. | |
| 789 | + * This can help identify faulty hardware. | |
| 790 | + */ | |
| 791 | + printk(KERN_CONT " likely on CPU %d (core %d, socket %d)", cpu, | |
| 792 | + topology_core_id(cpu), topology_physical_package_id(cpu)); | |
| 793 | + | |
| 794 | + | |
| 785 | 795 | printk(KERN_CONT "\n"); |
| 786 | 796 | |
| 787 | 797 | show_opcodes(regs, loglvl); |
| @@ -419,7 +419,9 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip) · 418 unmodified lines | ||
| 419 | 419 | OPTIMIZER_HIDE_VAR(reg); |
| 420 | 420 | emit_jump(&prog, &__x86_indirect_thunk_array[reg], ip); |
| 421 | 421 | } else { |
| 422 | − EMIT2(0xFF, 0xE0 + reg); | |
| 422 | + EMIT2(0xFF, 0xE0 + reg); /* jmp *%\reg */ | |
| 423 | + if (IS_ENABLED(CONFIG_RETPOLINE) || IS_ENABLED(CONFIG_SLS)) | |
| 424 | + EMIT1(0xCC); /* int3 */ | |
| 423 | 425 | } |
| 424 | 426 | |
| 425 | 427 | *pprog = prog; |
| @@ -662,7 +664,7 @@ static void emit_mov_imm64(u8 **pprog, u32 dst_reg, · 236 unmodified lines | ||
| 662 | 664 | */ |
| 663 | 665 | emit_mov_imm32(&prog, false, dst_reg, imm32_lo); |
| 664 | 666 | } else { |
| 665 | − /* movabsq %rax, imm64 */ | |
| 667 | + /* movabsq rax, imm64 */ | |
| 666 | 668 | EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg)); |
| 667 | 669 | EMIT(imm32_lo, 4); |
| 668 | 670 | EMIT(imm32_hi, 4); |
| @@ -1751,34 +1753,60 @@ emit_jmp: · 1082 unmodified lines | ||
| 1751 | 1753 | static void save_regs(const struct btf_func_model *m, u8 **prog, int nr_args, |
| 1752 | 1754 | int stack_size) |
| 1753 | 1755 | { |
| 1754 | − int i; | |
| 1756 | + int i, j, arg_size, nr_regs; | |
| 1755 | 1757 | /* Store function arguments to stack. |
| 1756 | 1758 | * For a function that accepts two pointers the sequence will be: |
| 1757 | 1759 | * mov QWORD PTR [rbp-0x10],rdi |
| 1758 | 1760 | * mov QWORD PTR [rbp-0x8],rsi |
| 1759 | 1761 | */ |
| 1760 | − for (i = 0; i < min(nr_args, 6); i++) | |
| 1761 | − emit_stx(prog, bytes_to_bpf_size(m->arg_size[i]), | |
| 1762 | − BPF_REG_FP, | |
| 1763 | − i == 5 ? X86_REG_R9 : BPF_REG_1 + i, | |
| 1764 | − -(stack_size - i * 8)); | |
| 1762 | + for (i = 0, j = 0; i < min(nr_args, 6); i++) { | |
| 1763 | + if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) { | |
| 1764 | + nr_regs = (m->arg_size[i] + 7) / 8; | |
| 1765 | + arg_size = 8; | |
| 1766 | + } else { | |
| 1767 | + nr_regs = 1; | |
| 1768 | + arg_size = m->arg_size[i]; | |
| 1769 | + } | |
| 1770 | + | |
| 1771 | + while (nr_regs) { | |
| 1772 | + emit_stx(prog, bytes_to_bpf_size(arg_size), | |
| 1773 | + BPF_REG_FP, | |
| 1774 | + j == 5 ? X86_REG_R9 : BPF_REG_1 + j, | |
| 1775 | + -(stack_size - j * 8)); | |
| 1776 | + nr_regs--; | |
| 1777 | + j++; | |
| 1778 | + } | |
| 1779 | + } | |
| 1765 | 1780 | } |
| 1766 | 1781 | |
| 1767 | 1782 | static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_args, |
| 1768 | 1783 | int stack_size) |
| 1769 | 1784 | { |
| 1770 | − int i; | |
| 1785 | + int i, j, arg_size, nr_regs; | |
| 1771 | 1786 | |
| 1772 | 1787 | /* Restore function arguments from stack. |
| 1773 | 1788 | * For a function that accepts two pointers the sequence will be: |
| 1774 | 1789 | * EMIT4(0x48, 0x8B, 0x7D, 0xF0); mov rdi,QWORD PTR [rbp-0x10] |
| 1775 | 1790 | * EMIT4(0x48, 0x8B, 0x75, 0xF8); mov rsi,QWORD PTR [rbp-0x8] |
| 1776 | 1791 | */ |
| 1777 | − for (i = 0; i < min(nr_args, 6); i++) | |
| 1778 | − emit_ldx(prog, bytes_to_bpf_size(m->arg_size[i]), | |
| 1779 | − i == 5 ? X86_REG_R9 : BPF_REG_1 + i, | |
| 1780 | − BPF_REG_FP, | |
| 1781 | − -(stack_size - i * 8)); | |
| 1792 | + for (i = 0, j = 0; i < min(nr_args, 6); i++) { | |
| 1793 | + if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) { | |
| 1794 | + nr_regs = (m->arg_size[i] + 7) / 8; | |
| 1795 | + arg_size = 8; | |
| 1796 | + } else { | |
| 1797 | + nr_regs = 1; | |
| 1798 | + arg_size = m->arg_size[i]; | |
| 1799 | + } | |
| 1800 | + | |
| 1801 | + while (nr_regs) { | |
| 1802 | + emit_ldx(prog, bytes_to_bpf_size(arg_size), | |
| 1803 | + j == 5 ? X86_REG_R9 : BPF_REG_1 + j, | |
| 1804 | + BPF_REG_FP, | |
| 1805 | + -(stack_size - j * 8)); | |
| 1806 | + nr_regs--; | |
| 1807 | + j++; | |
| 1808 | + } | |
| 1809 | + } | |
| 1782 | 1810 | } |
| 1783 | 1811 | |
| 1784 | 1812 | static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, |
| @@ -1810,6 +1838,9 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, · 25 unmodified lines | ||
| 1810 | 1838 | if (p->aux->sleepable) { |
| 1811 | 1839 | enter = __bpf_prog_enter_sleepable; |
| 1812 | 1840 | exit = __bpf_prog_exit_sleepable; |
| 1841 | + } else if (p->type == BPF_PROG_TYPE_STRUCT_OPS) { | |
| 1842 | + enter = __bpf_prog_enter_struct_ops; | |
| 1843 | + exit = __bpf_prog_exit_struct_ops; | |
| 1813 | 1844 | } else if (p->expected_attach_type == BPF_LSM_CGROUP) { |
| 1814 | 1845 | enter = __bpf_prog_enter_lsm_cgroup; |
| 1815 | 1846 | exit = __bpf_prog_exit_lsm_cgroup; |
| @@ -2013,13 +2044,14 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog, · 197 unmodified lines | ||
| 2013 | 2044 | int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end, |
| 2014 | 2045 | const struct btf_func_model *m, u32 flags, |
| 2015 | 2046 | struct bpf_tramp_links *tlinks, |
| 2016 | − void *orig_call) | |
| 2047 | + void *func_addr) | |
| 2017 | 2048 | { |
| 2018 | − int ret, i, nr_args = m->nr_args; | |
| 2049 | + int ret, i, nr_args = m->nr_args, extra_nregs = 0; | |
| 2019 | 2050 | int regs_off, ip_off, args_off, stack_size = nr_args * 8, run_ctx_off; |
| 2020 | 2051 | struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; |
| 2021 | 2052 | struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; |
| 2022 | 2053 | struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; |
| 2054 | + void *orig_call = func_addr; | |
| 2023 | 2055 | u8 **branches = NULL; |
| 2024 | 2056 | u8 *prog; |
| 2025 | 2057 | bool save_ret; |
| @@ -2028,6 +2060,14 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i · 2 unmodified lines | ||
| 2028 | 2060 | if (nr_args > 6) |
| 2029 | 2061 | return -ENOTSUPP; |
| 2030 | 2062 | |
| 2063 | + for (i = 0; i < MAX_BPF_FUNC_ARGS; i++) { | |
| 2064 | + if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) | |
| 2065 | + extra_nregs += (m->arg_size[i] + 7) / 8 - 1; | |
| 2066 | + } | |
| 2067 | + if (nr_args + extra_nregs > 6) | |
| 2068 | + return -ENOTSUPP; | |
| 2069 | + stack_size += extra_nregs * 8; | |
| 2070 | + | |
| 2031 | 2071 | /* Generated trampoline stack layout: |
| 2032 | 2072 | * |
| 2033 | 2073 | * RBP + 8 [ return address ] |
| @@ -2040,7 +2080,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i · 6 unmodified lines | ||
| 2040 | 2080 | * [ ... ] |
| 2041 | 2081 | * RBP - regs_off [ reg_arg1 ] program's ctx pointer |
| 2042 | 2082 | * |
| 2043 | − * RBP - args_off [ args count ] always | |
| 2083 | + * RBP - args_off [ arg regs count ] always | |
| 2044 | 2084 | * |
| 2045 | 2085 | * RBP - ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag |
| 2046 | 2086 | * |
| @@ -2083,21 +2123,19 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i · 36 unmodified lines | ||
| 2083 | 2123 | EMIT4(0x48, 0x83, 0xEC, stack_size); /* sub rsp, stack_size */ |
| 2084 | 2124 | EMIT1(0x53); /* push rbx */ |
| 2085 | 2125 | |
| 2086 | − /* Store number of arguments of the traced function: | |
| 2087 | − * mov rax, nr_args | |
| 2126 | + /* Store number of argument registers of the traced function: | |
| 2127 | + * mov rax, nr_args + extra_nregs | |
| 2088 | 2128 | * mov QWORD PTR [rbp - args_off], rax |
| 2089 | 2129 | */ |
| 2090 | − emit_mov_imm64(&prog, BPF_REG_0, 0, (u32) nr_args); | |
| 2130 | + emit_mov_imm64(&prog, BPF_REG_0, 0, (u32) nr_args + extra_nregs); | |
| 2091 | 2131 | emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -args_off); |
| 2092 | 2132 | |
| 2093 | 2133 | if (flags & BPF_TRAMP_F_IP_ARG) { |
| 2094 | 2134 | /* Store IP address of the traced function: |
| 2095 | − * mov rax, QWORD PTR [rbp + 8] | |
| 2096 | − * sub rax, X86_PATCH_SIZE | |
| 2135 | + * movabsq rax, func_addr | |
| 2097 | 2136 | * mov QWORD PTR [rbp - ip_off], rax |
| 2098 | 2137 | */ |
| 2099 | − emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8); | |
| 2100 | − EMIT4(0x48, 0x83, 0xe8, X86_PATCH_SIZE); | |
| 2138 | + emit_mov_imm64(&prog, BPF_REG_0, (long) func_addr >> 32, (u32) (long) func_addr); | |
| 2101 | 2139 | emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off); |
| 2102 | 2140 | } |
| 2103 | 2141 | |
| @@ -2209,7 +2247,7 @@ cleanup: · 105 unmodified lines | ||
| 2209 | 2247 | return ret; |
| 2210 | 2248 | } |
| 2211 | 2249 | |
| 2212 | −static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs) | |
| 2250 | +static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs, u8 *image, u8 *buf) | |
| 2213 | 2251 | { |
| 2214 | 2252 | u8 *jg_reloc, *prog = *pprog; |
| 2215 | 2253 | int pivot, err, jg_bytes = 1; |
| @@ -2225,12 +2263,12 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs) · 9 unmodified lines | ||
| 2225 | 2263 | EMIT2_off32(0x81, add_1reg(0xF8, BPF_REG_3), |
| 2226 | 2264 | progs[a]); |
| 2227 | 2265 | err = emit_cond_near_jump(&prog, /* je func */ |
| 2228 | − (void *)progs[a], prog, | |
| 2266 | + (void *)progs[a], image + (prog - buf), | |
| 2229 | 2267 | X86_JE); |
| 2230 | 2268 | if (err) |
| 2231 | 2269 | return err; |
| 2232 | 2270 | |
| 2233 | − emit_indirect_jump(&prog, 2 /* rdx */, prog); | |
| 2271 | + emit_indirect_jump(&prog, 2 /* rdx */, image + (prog - buf)); | |
| 2234 | 2272 | |
| 2235 | 2273 | *pprog = prog; |
| 2236 | 2274 | return 0; |
| @@ -2255,7 +2293,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs) · 18 unmodified lines | ||
| 2255 | 2293 | jg_reloc = prog; |
| 2256 | 2294 | |
| 2257 | 2295 | err = emit_bpf_dispatcher(&prog, a, a + pivot, /* emit lower_part */ |
| 2258 | − progs); | |
| 2296 | + progs, image, buf); | |
| 2259 | 2297 | if (err) |
| 2260 | 2298 | return err; |
| 2261 | 2299 | |
| @@ -2269,7 +2307,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs) · 7 unmodified lines | ||
| 2269 | 2307 | emit_code(jg_reloc - jg_bytes, jg_offset, jg_bytes); |
| 2270 | 2308 | |
| 2271 | 2309 | err = emit_bpf_dispatcher(&prog, a + pivot + 1, /* emit upper_part */ |
| 2272 | − b, progs); | |
| 2310 | + b, progs, image, buf); | |
| 2273 | 2311 | if (err) |
| 2274 | 2312 | return err; |
| 2275 | 2313 | |
| @@ -2289,12 +2327,12 @@ static int cmp_ips(const void *a, const void *b) · 13 unmodified lines | ||
| 2289 | 2327 | return 0; |
| 2290 | 2328 | } |
| 2291 | 2329 | |
| 2292 | −int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs) | |
| 2330 | +int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs) | |
| 2293 | 2331 | { |
| 2294 | − u8 *prog = image; | |
| 2332 | + u8 *prog = buf; | |
| 2295 | 2333 | |
| 2296 | 2334 | sort(funcs, num_funcs, sizeof(funcs[0]), cmp_ips, NULL); |
| 2297 | − return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs); | |
| 2335 | + return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs, image, buf); | |
| 2298 | 2336 | } |
| 2299 | 2337 | |
| 2300 | 2338 | struct x64_jit_data { |
| @@ -169,7 +169,7 @@ static void __init do_add_efi_memmap(void) · 168 unmodified lines | ||
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | /* |
| 172 | − * Given add_efi_memmap defaults to 0 and there there is no alternative | |
| 172 | + * Given add_efi_memmap defaults to 0 and there is no alternative | |
| 173 | 173 | * e820 mechanism for soft-reserved memory, import the full EFI memory |
| 174 | 174 | * map if soft reservations are present and enabled. Otherwise, the |
| 175 | 175 | * mechanism to disable the kernel's consideration of EFI_MEMORY_SP is |
| @@ -55,6 +55,10 @@ ifdef CONFIG_RETPOLINE · 54 unmodified lines | ||
| 55 | 55 | PURGATORY_CFLAGS_REMOVE += $(RETPOLINE_CFLAGS) |
| 56 | 56 | endif |
| 57 | 57 | |
| 58 | +ifdef CONFIG_CFI_CLANG | |
| 59 | +PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_CFI) | |
| 60 | +endif | |
| 61 | + | |
| 58 | 62 | CFLAGS_REMOVE_purgatory.o += $(PURGATORY_CFLAGS_REMOVE) |
| 59 | 63 | CFLAGS_purgatory.o += $(PURGATORY_CFLAGS) |
| 60 | 64 | |
| @@ -56,6 +56,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { · 55 unmodified lines | ||
| 56 | 56 | "^(xen_irq_disable_direct_reloc$|" |
| 57 | 57 | "xen_save_fl_direct_reloc$|" |
| 58 | 58 | "VDSO|" |
| 59 | + "__kcfi_typeid_|" | |
| 59 | 60 | "__crc_)", |
| 60 | 61 | |
| 61 | 62 | /* |
| @@ -765,6 +765,7 @@ static void xen_load_idt(const struct desc_ptr *desc) · 764 unmodified lines | ||
| 765 | 765 | { |
| 766 | 766 | static DEFINE_SPINLOCK(lock); |
| 767 | 767 | static struct trap_info traps[257]; |
| 768 | + static const struct trap_info zero = { }; | |
| 768 | 769 | unsigned out; |
| 769 | 770 | |
| 770 | 771 | trace_xen_cpu_load_idt(desc); |
| @@ -774,7 +775,7 @@ static void xen_load_idt(const struct desc_ptr *desc) · 3 unmodified lines | ||
| 774 | 775 | memcpy(this_cpu_ptr(&idt_desc), desc, sizeof(idt_desc)); |
| 775 | 776 | |
| 776 | 777 | out = xen_convert_trap_info(desc, traps, false); |
| 777 | − memset(&traps[out], 0, sizeof(traps[0])); | |
| 778 | + traps[out] = zero; | |
| 778 | 779 | |
| 779 | 780 | xen_mc_flush(); |
| 780 | 781 | if (HYPERVISOR_set_trap_table(traps)) |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/namei.h> |
| 27 | 27 | #include <linux/part_stat.h> |
| 28 | 28 | #include <linux/uaccess.h> |
| 29 | +#include <linux/stat.h> | |
| 29 | 30 | #include "../fs/internal.h" |
| 30 | 31 | #include "blk.h" |
| 31 | 32 | |
| @@ -1069,3 +1070,25 @@ void sync_bdevs(bool wait) · 1037 unmodified lines | ||
| 1069 | 1070 | spin_unlock(&blockdev_superblock->s_inode_list_lock); |
| 1070 | 1071 | iput(old_inode); |
| 1071 | 1072 | } |
| 1073 | + | |
| 1074 | +/* | |
| 1075 | + * Handle STATX_DIOALIGN for block devices. | |
| 1076 | + * | |
| 1077 | + * Note that the inode passed to this is the inode of a block device node file, | |
| 1078 | + * not the block device's internal inode. Therefore it is *not* valid to use | |
| 1079 | + * I_BDEV() here; the block device has to be looked up by i_rdev instead. | |
| 1080 | + */ | |
| 1081 | +void bdev_statx_dioalign(struct inode *inode, struct kstat *stat) | |
| 1082 | +{ | |
| 1083 | + struct block_device *bdev; | |
| 1084 | + | |
| 1085 | + bdev = blkdev_get_no_open(inode->i_rdev); | |
| 1086 | + if (!bdev) | |
| 1087 | + return; | |
| 1088 | + | |
| 1089 | + stat->dio_mem_align = bdev_dma_alignment(bdev) + 1; | |
| 1090 | + stat->dio_offset_align = bdev_logical_block_size(bdev); | |
| 1091 | + stat->result_mask |= STATX_DIOALIGN; | |
| 1092 | + | |
| 1093 | + blkdev_put_no_open(bdev); | |
| 1094 | +} | |
| @@ -27,9 +27,6 @@ menuconfig ACPI · 26 unmodified lines | ||
| 27 | 27 | Management (APM) specification. If both ACPI and APM support |
| 28 | 28 | are configured, ACPI is used. |
| 29 | 29 | |
| 30 | − The project home page for the Linux ACPI subsystem is here: | |
| 31 | − <https://01.org/linux-acpi> | |
| 32 | − | |
| 33 | 30 | Linux support for ACPI is based on Intel Corporation's ACPI |
| 34 | 31 | Component Architecture (ACPI CA). For more information on the |
| 35 | 32 | ACPI CA, see: |
| @@ -347,7 +344,6 @@ config ACPI_CUSTOM_DSDT_FILE · 311 unmodified lines | ||
| 347 | 344 | depends on !STANDALONE |
| 348 | 345 | help |
| 349 | 346 | This option supports a custom DSDT by linking it into the kernel. |
| 350 | − See Documentation/admin-guide/acpi/dsdt-override.rst | |
| 351 | 347 | |
| 352 | 348 | Enter the full path name to the file which includes the AmlCode |
| 353 | 349 | or dsdt_aml_code declaration. |
| @@ -36,11 +36,6 @@ static int acpi_ac_add(struct acpi_device *device); · 35 unmodified lines | ||
| 36 | 36 | static int acpi_ac_remove(struct acpi_device *device); |
| 37 | 37 | static void acpi_ac_notify(struct acpi_device *device, u32 event); |
| 38 | 38 | |
| 39 | −struct acpi_ac_bl { | |
| 40 | − const char *hid; | |
| 41 | − int hrv; | |
| 42 | −}; | |
| 43 | − | |
| 44 | 39 | static const struct acpi_device_id ac_device_ids[] = { |
| 45 | 40 | {"ACPI0003", 0}, |
| 46 | 41 | {"", 0}, |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | static const struct acpi_device_id amba_id_list[] = { |
| 23 | 23 | {"ARMH0061", 0}, /* PL061 GPIO Device */ |
| 24 | + {"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */ | |
| 24 | 25 | {"ARMHC500", 0}, /* ARM CoreSight ETM4x */ |
| 25 | 26 | {"ARMHC501", 0}, /* ARM CoreSight ETR */ |
| 26 | 27 | {"ARMHC502", 0}, /* ARM CoreSight STM */ |
| @@ -48,6 +49,7 @@ static void amba_register_dummy_clk(void) · 21 unmodified lines | ||
| 48 | 49 | static int amba_handler_attach(struct acpi_device *adev, |
| 49 | 50 | const struct acpi_device_id *id) |
| 50 | 51 | { |
| 52 | + struct acpi_device *parent = acpi_dev_parent(adev); | |
| 51 | 53 | struct amba_device *dev; |
| 52 | 54 | struct resource_entry *rentry; |
| 53 | 55 | struct list_head resource_list; |
| @@ -97,8 +99,8 @@ static int amba_handler_attach(struct acpi_device *adev, · 43 unmodified lines | ||
| 97 | 99 | * attached to it, that physical device should be the parent of |
| 98 | 100 | * the amba device we are about to create. |
| 99 | 101 | */ |
| 100 | − if (adev->parent) | |
| 101 | − dev->dev.parent = acpi_get_first_physical_node(adev->parent); | |
| 102 | + if (parent) | |
| 103 | + dev->dev.parent = acpi_get_first_physical_node(parent); | |
| 102 | 104 | |
| 103 | 105 | ACPI_COMPANION_SET(&dev->dev, adev); |
| 104 | 106 | |
| @@ -60,12 +60,6 @@ static int acpi_apd_setup(struct apd_private_data *pdata) · 59 unmodified lines | ||
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE |
| 63 | −static int misc_check_res(struct acpi_resource *ares, void *data) | |
| 64 | −{ | |
| 65 | − struct resource res; | |
| 66 | − | |
| 67 | − return !acpi_dev_resource_memory(ares, &res); | |
| 68 | −} | |
| 69 | 63 | |
| 70 | 64 | static int fch_misc_setup(struct apd_private_data *pdata) |
| 71 | 65 | { |
| @@ -82,8 +76,7 @@ static int fch_misc_setup(struct apd_private_data *pdata) · 10 unmodified lines | ||
| 82 | 76 | return -ENOMEM; |
| 83 | 77 | |
| 84 | 78 | INIT_LIST_HEAD(&resource_list); |
| 85 | − ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res, | |
| 86 | − NULL); | |
| 79 | + ret = acpi_dev_get_memory_resources(adev, &resource_list); | |
| 87 | 80 | if (ret < 0) |
| 88 | 81 | return -ENOENT; |
| 89 | 82 | |
| @@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = { · 142 unmodified lines | ||
| 143 | 143 | |
| 144 | 144 | static struct kobject *fpdt_kobj; |
| 145 | 145 | |
| 146 | +#if defined CONFIG_X86 && defined CONFIG_PHYS_ADDR_T_64BIT | |
| 147 | +#include <linux/processor.h> | |
| 148 | +static bool fpdt_address_valid(u64 address) | |
| 149 | +{ | |
| 150 | + /* | |
| 151 | + * On some systems the table contains invalid addresses | |
| 152 | + * with unsuppored high address bits set, check for this. | |
| 153 | + */ | |
| 154 | + return !(address >> boot_cpu_data.x86_phys_bits); | |
| 155 | +} | |
| 156 | +#else | |
| 157 | +static bool fpdt_address_valid(u64 address) | |
| 158 | +{ | |
| 159 | + return true; | |
| 160 | +} | |
| 161 | +#endif | |
| 162 | + | |
| 146 | 163 | static int fpdt_process_subtable(u64 address, u32 subtable_type) |
| 147 | 164 | { |
| 148 | 165 | struct fpdt_subtable_header *subtable_header; |
| @@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) · 2 unmodified lines | ||
| 151 | 168 | u32 length, offset; |
| 152 | 169 | int result; |
| 153 | 170 | |
| 171 | + if (!fpdt_address_valid(address)) { | |
| 172 | + pr_info(FW_BUG "invalid physical address: 0x%llx!\n", address); | |
| 173 | + return -EINVAL; | |
| 174 | + } | |
| 175 | + | |
| 154 | 176 | subtable_header = acpi_os_map_memory(address, sizeof(*subtable_header)); |
| 155 | 177 | if (!subtable_header) |
| 156 | 178 | return -ENOMEM; |
| @@ -167,10 +167,10 @@ static struct pwm_lookup byt_pwm_lookup[] = { · 166 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | static void byt_pwm_setup(struct lpss_private_data *pdata) |
| 169 | 169 | { |
| 170 | − struct acpi_device *adev = pdata->adev; | |
| 170 | + u64 uid; | |
| 171 | 171 | |
| 172 | 172 | /* Only call pwm_add_table for the first PWM controller */ |
| 173 | − if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) | |
| 173 | + if (acpi_dev_uid_to_integer(pdata->adev, &uid) || uid != 1) | |
| 174 | 174 | return; |
| 175 | 175 | |
| 176 | 176 | pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup)); |
| @@ -180,14 +180,13 @@ static void byt_pwm_setup(struct lpss_private_data *pdata) · 3 unmodified lines | ||
| 180 | 180 | |
| 181 | 181 | static void byt_i2c_setup(struct lpss_private_data *pdata) |
| 182 | 182 | { |
| 183 | − const char *uid_str = acpi_device_uid(pdata->adev); | |
| 184 | 183 | acpi_handle handle = pdata->adev->handle; |
| 185 | 184 | unsigned long long shared_host = 0; |
| 186 | 185 | acpi_status status; |
| 187 | − long uid = 0; | |
| 186 | + u64 uid; | |
| 188 | 187 | |
| 189 | − /* Expected to always be true, but better safe then sorry */ | |
| 190 | − if (uid_str && !kstrtol(uid_str, 10, &uid) && uid) { | |
| 188 | + /* Expected to always be successfull, but better safe then sorry */ | |
| 189 | + if (!acpi_dev_uid_to_integer(pdata->adev, &uid) && uid) { | |
| 191 | 190 | /* Detect I2C bus shared with PUNIT and ignore its d3 status */ |
| 192 | 191 | status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host); |
| 193 | 192 | if (ACPI_SUCCESS(status) && shared_host) |
| @@ -211,10 +210,10 @@ static struct pwm_lookup bsw_pwm_lookup[] = { · 17 unmodified lines | ||
| 211 | 210 | |
| 212 | 211 | static void bsw_pwm_setup(struct lpss_private_data *pdata) |
| 213 | 212 | { |
| 214 | − struct acpi_device *adev = pdata->adev; | |
| 213 | + u64 uid; | |
| 215 | 214 | |
| 216 | 215 | /* Only call pwm_add_table for the first PWM controller */ |
| 217 | − if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) | |
| 216 | + if (acpi_dev_uid_to_integer(pdata->adev, &uid) || uid != 1) | |
| 218 | 217 | return; |
| 219 | 218 | |
| 220 | 219 | pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup)); |
| @@ -392,13 +391,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { · 171 unmodified lines | ||
| 392 | 391 | |
| 393 | 392 | #ifdef CONFIG_X86_INTEL_LPSS |
| 394 | 393 | |
| 395 | −static int is_memory(struct acpi_resource *res, void *not_used) | |
| 396 | −{ | |
| 397 | − struct resource r; | |
| 398 | − | |
| 399 | − return !acpi_dev_resource_memory(res, &r); | |
| 400 | −} | |
| 401 | − | |
| 402 | 394 | /* LPSS main clock device. */ |
| 403 | 395 | static struct platform_device *lpss_clk_dev; |
| 404 | 396 | |
| @@ -659,29 +651,25 @@ static int acpi_lpss_create_device(struct acpi_device *adev, · 254 unmodified lines | ||
| 659 | 651 | return -ENOMEM; |
| 660 | 652 | |
| 661 | 653 | INIT_LIST_HEAD(&resource_list); |
| 662 | − ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL); | |
| 654 | + ret = acpi_dev_get_memory_resources(adev, &resource_list); | |
| 663 | 655 | if (ret < 0) |
| 664 | 656 | goto err_out; |
| 665 | 657 | |
| 666 | − list_for_each_entry(rentry, &resource_list, node) | |
| 667 | − if (resource_type(rentry->res) == IORESOURCE_MEM) { | |
| 668 | − if (dev_desc->prv_size_override) | |
| 669 | − pdata->mmio_size = dev_desc->prv_size_override; | |
| 670 | − else | |
| 671 | − pdata->mmio_size = resource_size(rentry->res); | |
| 672 | − pdata->mmio_base = ioremap(rentry->res->start, | |
| 673 | − pdata->mmio_size); | |
| 674 | − break; | |
| 675 | − } | |
| 658 | + rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node); | |
| 659 | + if (rentry) { | |
| 660 | + if (dev_desc->prv_size_override) | |
| 661 | + pdata->mmio_size = dev_desc->prv_size_override; | |
| 662 | + else | |
| 663 | + pdata->mmio_size = resource_size(rentry->res); | |
| 664 | + pdata->mmio_base = ioremap(rentry->res->start, pdata->mmio_size); | |
| 665 | + } | |
| 676 | 666 | |
| 677 | 667 | acpi_dev_free_resource_list(&resource_list); |
| 678 | 668 | |
| 679 | 669 | if (!pdata->mmio_base) { |
| 680 | 670 | /* Avoid acpi_bus_attach() instantiating a pdev for this dev. */ |
| 681 | 671 | adev->pnp.type.platform_id = 0; |
| 682 | − /* Skip the device, but continue the namespace scan. */ | |
| 683 | − ret = 0; | |
| 684 | − goto err_out; | |
| 672 | + goto out_free; | |
| 685 | 673 | } |
| 686 | 674 | |
| 687 | 675 | pdata->adev = adev; |
| @@ -692,11 +680,8 @@ static int acpi_lpss_create_device(struct acpi_device *adev, · 4 unmodified lines | ||
| 692 | 680 | |
| 693 | 681 | if (dev_desc->flags & LPSS_CLK) { |
| 694 | 682 | ret = register_device_clock(adev, pdata); |
| 695 | − if (ret) { | |
| 696 | − /* Skip the device, but continue the namespace scan. */ | |
| 697 | − ret = 0; | |
| 698 | − goto err_out; | |
| 699 | − } | |
| 683 | + if (ret) | |
| 684 | + goto out_free; | |
| 700 | 685 | } |
| 701 | 686 | |
| 702 | 687 | /* |
| @@ -708,15 +693,19 @@ static int acpi_lpss_create_device(struct acpi_device *adev, · 5 unmodified lines | ||
| 708 | 693 | |
| 709 | 694 | adev->driver_data = pdata; |
| 710 | 695 | pdev = acpi_create_platform_device(adev, dev_desc->properties); |
| 711 | − if (!IS_ERR_OR_NULL(pdev)) { | |
| 712 | − acpi_lpss_create_device_links(adev, pdev); | |
| 713 | − return 1; | |
| 696 | + if (IS_ERR_OR_NULL(pdev)) { | |
| 697 | + adev->driver_data = NULL; | |
| 698 | + ret = PTR_ERR(pdev); | |
| 699 | + goto err_out; | |
| 714 | 700 | } |
| 715 | 701 | |
| 716 | − ret = PTR_ERR(pdev); | |
| 717 | − adev->driver_data = NULL; | |
| 702 | + acpi_lpss_create_device_links(adev, pdev); | |
| 703 | + return 1; | |
| 718 | 704 | |
| 719 | − err_out: | |
| 705 | +out_free: | |
| 706 | + /* Skip the device, but continue the namespace scan */ | |
| 707 | + ret = 0; | |
| 708 | +err_out: | |
| 720 | 709 | kfree(pdata); |
| 721 | 710 | return ret; |
| 722 | 711 | } |
| @@ -23,6 +23,12 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <acpi/pcc.h> |
| 25 | 25 | |
| 26 | +/* | |
| 27 | + * Arbitrary retries in case the remote processor is slow to respond | |
| 28 | + * to PCC commands | |
| 29 | + */ | |
| 30 | +#define PCC_CMD_WAIT_RETRIES_NUM 500 | |
| 31 | + | |
| 26 | 32 | struct pcc_data { |
| 27 | 33 | struct pcc_mbox_chan *pcc_chan; |
| 28 | 34 | void __iomem *pcc_comm_addr; |
| @@ -63,6 +69,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function, · 34 unmodified lines | ||
| 63 | 69 | if (IS_ERR(data->pcc_chan)) { |
| 64 | 70 | pr_err("Failed to find PCC channel for subspace %d\n", |
| 65 | 71 | ctx->subspace_id); |
| 72 | + kfree(data); | |
| 66 | 73 | return AE_NOT_FOUND; |
| 67 | 74 | } |
| 68 | 75 | |
| @@ -72,6 +79,8 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function, · 3 unmodified lines | ||
| 72 | 79 | if (!data->pcc_comm_addr) { |
| 73 | 80 | pr_err("Failed to ioremap PCC comm region mem for %d\n", |
| 74 | 81 | ctx->subspace_id); |
| 82 | + pcc_mbox_free_channel(data->pcc_chan); | |
| 83 | + kfree(data); | |
| 75 | 84 | return AE_NO_MEMORY; |
| 76 | 85 | } |
| 77 | 86 | |
| @@ -86,6 +95,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr, · 8 unmodified lines | ||
| 86 | 95 | { |
| 87 | 96 | int ret; |
| 88 | 97 | struct pcc_data *data = region_context; |
| 98 | + u64 usecs_lat; | |
| 89 | 99 | |
| 90 | 100 | reinit_completion(&data->done); |
| 91 | 101 | |
| @@ -96,10 +106,22 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr, · 4 unmodified lines | ||
| 96 | 106 | if (ret < 0) |
| 97 | 107 | return AE_ERROR; |
| 98 | 108 | |
| 99 | − if (data->pcc_chan->mchan->mbox->txdone_irq) | |
| 100 | − wait_for_completion(&data->done); | |
| 109 | + if (data->pcc_chan->mchan->mbox->txdone_irq) { | |
| 110 | + /* | |
| 111 | + * pcc_chan->latency is just a Nominal value. In reality the remote | |
| 112 | + * processor could be much slower to reply. So add an arbitrary | |
| 113 | + * amount of wait on top of Nominal. | |
| 114 | + */ | |
| 115 | + usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency; | |
| 116 | + ret = wait_for_completion_timeout(&data->done, | |
| 117 | + usecs_to_jiffies(usecs_lat)); | |
| 118 | + if (ret == 0) { | |
| 119 | + pr_err("PCC command executed timeout!\n"); | |
| 120 | + return AE_TIME; | |
| 121 | + } | |
| 122 | + } | |
| 101 | 123 | |
| 102 | − mbox_client_txdone(data->pcc_chan->mchan, ret); | |
| 124 | + mbox_chan_txdone(data->pcc_chan->mchan, ret); | |
| 103 | 125 | |
| 104 | 126 | memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length); |
| 105 | 127 | |
| @@ -20,13 +20,13 @@ · 19 unmodified lines | ||
| 20 | 20 | #include "internal.h" |
| 21 | 21 | |
| 22 | 22 | static const struct acpi_device_id forbidden_id_list[] = { |
| 23 | + {"ACPI0009", 0}, /* IOxAPIC */ | |
| 24 | + {"ACPI000A", 0}, /* IOAPIC */ | |
| 23 | 25 | {"PNP0000", 0}, /* PIC */ |
| 24 | 26 | {"PNP0100", 0}, /* Timer */ |
| 25 | 27 | {"PNP0200", 0}, /* AT DMA Controller */ |
| 26 | − {"ACPI0009", 0}, /* IOxAPIC */ | |
| 27 | − {"ACPI000A", 0}, /* IOAPIC */ | |
| 28 | 28 | {"SMB0001", 0}, /* ACPI SMBUS virtual device */ |
| 29 | − {"", 0}, | |
| 29 | + { } | |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | 32 | static struct platform_device *acpi_platform_device_find_by_companion(struct acpi_device *adev) |
| @@ -78,7 +78,7 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, · 45 unmodified lines | ||
| 78 | 78 | * If the device has parent we need to take its resources into |
| 79 | 79 | * account as well because this device might consume part of those. |
| 80 | 80 | */ |
| 81 | − parent = acpi_get_first_physical_node(adev->parent); | |
| 81 | + parent = acpi_get_first_physical_node(acpi_dev_parent(adev)); | |
| 82 | 82 | if (parent && dev_is_pci(parent)) |
| 83 | 83 | dest->parent = pci_find_resource(to_pci_dev(parent), dest); |
| 84 | 84 | } |
| @@ -97,6 +97,7 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, · 12 unmodified lines | ||
| 97 | 97 | struct platform_device *acpi_create_platform_device(struct acpi_device *adev, |
| 98 | 98 | const struct property_entry *properties) |
| 99 | 99 | { |
| 100 | + struct acpi_device *parent = acpi_dev_parent(adev); | |
| 100 | 101 | struct platform_device *pdev = NULL; |
| 101 | 102 | struct platform_device_info pdevinfo; |
| 102 | 103 | struct resource_entry *rentry; |
| @@ -113,13 +114,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, · 10 unmodified lines | ||
| 113 | 114 | |
| 114 | 115 | INIT_LIST_HEAD(&resource_list); |
| 115 | 116 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); |
| 116 | − if (count < 0) { | |
| 117 | + if (count < 0) | |
| 117 | 118 | return NULL; |
| 118 | − } else if (count > 0) { | |
| 119 | − resources = kcalloc(count, sizeof(struct resource), | |
| 120 | − GFP_KERNEL); | |
| 119 | + if (count > 0) { | |
| 120 | + resources = kcalloc(count, sizeof(*resources), GFP_KERNEL); | |
| 121 | 121 | if (!resources) { |
| 122 | − dev_err(&adev->dev, "No memory for resources\n"); | |
| 123 | 122 | acpi_dev_free_resource_list(&resource_list); |
| 124 | 123 | return ERR_PTR(-ENOMEM); |
| 125 | 124 | } |
| @@ -137,10 +136,9 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, · 11 unmodified lines | ||
| 137 | 136 | * attached to it, that physical device should be the parent of the |
| 138 | 137 | * platform device we are about to create. |
| 139 | 138 | */ |
| 140 | − pdevinfo.parent = adev->parent ? | |
| 141 | − acpi_get_first_physical_node(adev->parent) : NULL; | |
| 139 | + pdevinfo.parent = parent ? acpi_get_first_physical_node(parent) : NULL; | |
| 142 | 140 | pdevinfo.name = dev_name(&adev->dev); |
| 143 | − pdevinfo.id = -1; | |
| 141 | + pdevinfo.id = PLATFORM_DEVID_NONE; | |
| 144 | 142 | pdevinfo.res = resources; |
| 145 | 143 | pdevinfo.num_res = count; |
| 146 | 144 | pdevinfo.fwnode = acpi_fwnode_handle(adev); |
| @@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = { · 495 unmodified lines | ||
| 496 | 496 | DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), |
| 497 | 497 | }, |
| 498 | 498 | }, |
| 499 | + { | |
| 500 | + .callback = video_disable_backlight_sysfs_if, | |
| 501 | + .ident = "Toshiba Satellite Z830", | |
| 502 | + .matches = { | |
| 503 | + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
| 504 | + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"), | |
| 505 | + }, | |
| 506 | + }, | |
| 507 | + { | |
| 508 | + .callback = video_disable_backlight_sysfs_if, | |
| 509 | + .ident = "Toshiba Portege Z830", | |
| 510 | + .matches = { | |
| 511 | + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
| 512 | + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"), | |
| 513 | + }, | |
| 514 | + }, | |
| 499 | 515 | /* |
| 500 | 516 | * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set |
| 501 | 517 | * but the IDs actually follow the Device ID Scheme. |
| @@ -2030,7 +2046,7 @@ static int acpi_video_bus_add(struct acpi_device *device) · 1528 unmodified lines | ||
| 2030 | 2046 | acpi_status status; |
| 2031 | 2047 | |
| 2032 | 2048 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, |
| 2033 | − device->parent->handle, 1, | |
| 2049 | + acpi_dev_parent(device)->handle, 1, | |
| 2034 | 2050 | acpi_video_bus_match, NULL, |
| 2035 | 2051 | device, NULL); |
| 2036 | 2052 | if (status == AE_ALREADY_EXISTS) { |
| @@ -125,12 +125,9 @@ EXPORT_SYMBOL_GPL(apei_exec_write_register); · 124 unmodified lines | ||
| 125 | 125 | int apei_exec_write_register_value(struct apei_exec_context *ctx, |
| 126 | 126 | struct acpi_whea_header *entry) |
| 127 | 127 | { |
| 128 | − int rc; | |
| 129 | − | |
| 130 | 128 | ctx->value = entry->value; |
| 131 | − rc = apei_exec_write_register(ctx, entry); | |
| 132 | 129 | |
| 133 | − return rc; | |
| 130 | + return apei_exec_write_register(ctx, entry); | |
| 134 | 131 | } |
| 135 | 132 | EXPORT_SYMBOL_GPL(apei_exec_write_register_value); |
| 136 | 133 | |
| @@ -90,6 +90,9 @@ static void __init bert_print_all(struct acpi_bert_region *region, · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | if (skipped) |
| 92 | 92 | pr_info(HW_ERR "Skipped %d error records\n", skipped); |
| 93 | + | |
| 94 | + if (printed + skipped) | |
| 95 | + pr_info("Total records found: %d\n", printed + skipped); | |
| 93 | 96 | } |
| 94 | 97 | |
| 95 | 98 | static int __init setup_bert_disable(char *str) |
| @@ -1020,14 +1020,10 @@ static int reader_pos; · 1019 unmodified lines | ||
| 1020 | 1020 | |
| 1021 | 1021 | static int erst_open_pstore(struct pstore_info *psi) |
| 1022 | 1022 | { |
| 1023 | − int rc; | |
| 1024 | − | |
| 1025 | 1023 | if (erst_disable) |
| 1026 | 1024 | return -ENODEV; |
| 1027 | 1025 | |
| 1028 | − rc = erst_get_record_id_begin(&reader_pos); | |
| 1029 | − | |
| 1030 | − return rc; | |
| 1026 | + return erst_get_record_id_begin(&reader_pos); | |
| 1031 | 1027 | } |
| 1032 | 1028 | |
| 1033 | 1029 | static int erst_close_pstore(struct pstore_info *psi) |
| @@ -4,11 +4,12 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/device.h> |
| 5 | 5 | #include <linux/dma-direct.h> |
| 6 | 6 | |
| 7 | −void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) | |
| 7 | +void acpi_arch_dma_setup(struct device *dev) | |
| 8 | 8 | { |
| 9 | 9 | int ret; |
| 10 | 10 | u64 end, mask; |
| 11 | − u64 dmaaddr = 0, size = 0, offset = 0; | |
| 11 | + u64 size = 0; | |
| 12 | + const struct bus_dma_region *map = NULL; | |
| 12 | 13 | |
| 13 | 14 | /* |
| 14 | 15 | * If @dev is expected to be DMA-capable then the bus code that created |
| @@ -26,7 +27,19 @@ void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) · 11 unmodified lines | ||
| 26 | 27 | else |
| 27 | 28 | size = 1ULL << 32; |
| 28 | 29 | |
| 29 | − ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size); | |
| 30 | + ret = acpi_dma_get_range(dev, &map); | |
| 31 | + if (!ret && map) { | |
| 32 | + const struct bus_dma_region *r = map; | |
| 33 | + | |
| 34 | + for (end = 0; r->size; r++) { | |
| 35 | + if (r->dma_start + r->size - 1 > end) | |
| 36 | + end = r->dma_start + r->size - 1; | |
| 37 | + } | |
| 38 | + | |
| 39 | + size = end + 1; | |
| 40 | + dev->dma_range_map = map; | |
| 41 | + } | |
| 42 | + | |
| 30 | 43 | if (ret == -ENODEV) |
| 31 | 44 | ret = iort_dma_get_ranges(dev, &size); |
| 32 | 45 | if (!ret) { |
| @@ -34,17 +47,10 @@ void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) · 1 unmodified line | ||
| 34 | 47 | * Limit coherent and dma mask based on size retrieved from |
| 35 | 48 | * firmware. |
| 36 | 49 | */ |
| 37 | − end = dmaaddr + size - 1; | |
| 50 | + end = size - 1; | |
| 38 | 51 | mask = DMA_BIT_MASK(ilog2(end) + 1); |
| 39 | 52 | dev->bus_dma_limit = end; |
| 40 | 53 | dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask); |
| 41 | 54 | *dev->dma_mask = min(*dev->dma_mask, mask); |
| 42 | 55 | } |
| 43 | − | |
| 44 | − *dma_addr = dmaaddr; | |
| 45 | − *dma_size = size; | |
| 46 | − | |
| 47 | − ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size); | |
| 48 | − | |
| 49 | − dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : ""); | |
| 50 | 56 | } |
| @@ -456,7 +456,7 @@ out_free: · 455 unmodified lines | ||
| 456 | 456 | Notification Handling |
| 457 | 457 | -------------------------------------------------------------------------- */ |
| 458 | 458 | |
| 459 | −/** | |
| 459 | +/* | |
| 460 | 460 | * acpi_bus_notify |
| 461 | 461 | * --------------- |
| 462 | 462 | * Callback for all 'system-level' device notifications (values 0x00-0x7F). |
| @@ -511,7 +511,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) · 48 unmodified lines | ||
| 511 | 511 | break; |
| 512 | 512 | } |
| 513 | 513 | |
| 514 | − adev = acpi_bus_get_acpi_device(handle); | |
| 514 | + adev = acpi_get_acpi_dev(handle); | |
| 515 | 515 | if (!adev) |
| 516 | 516 | goto err; |
| 517 | 517 | |
| @@ -524,14 +524,14 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) · 6 unmodified lines | ||
| 524 | 524 | } |
| 525 | 525 | |
| 526 | 526 | if (!hotplug_event) { |
| 527 | − acpi_bus_put_acpi_device(adev); | |
| 527 | + acpi_put_acpi_dev(adev); | |
| 528 | 528 | return; |
| 529 | 529 | } |
| 530 | 530 | |
| 531 | 531 | if (ACPI_SUCCESS(acpi_hotplug_schedule(adev, type))) |
| 532 | 532 | return; |
| 533 | 533 | |
| 534 | − acpi_bus_put_acpi_device(adev); | |
| 534 | + acpi_put_acpi_dev(adev); | |
| 535 | 535 | |
| 536 | 536 | err: |
| 537 | 537 | acpi_evaluate_ost(handle, type, ost_code, NULL); |
| @@ -802,7 +802,7 @@ static bool acpi_of_modalias(struct acpi_device *adev, · 264 unmodified lines | ||
| 802 | 802 | |
| 803 | 803 | str = obj->string.pointer; |
| 804 | 804 | chr = strchr(str, ','); |
| 805 | − strlcpy(modalias, chr ? chr + 1 : str, len); | |
| 805 | + strscpy(modalias, chr ? chr + 1 : str, len); | |
| 806 | 806 | |
| 807 | 807 | return true; |
| 808 | 808 | } |
| @@ -822,7 +822,7 @@ void acpi_set_modalias(struct acpi_device *adev, const char *default_id, · 13 unmodified lines | ||
| 822 | 822 | char *modalias, size_t len) |
| 823 | 823 | { |
| 824 | 824 | if (!acpi_of_modalias(adev, modalias, len)) |
| 825 | − strlcpy(modalias, default_id, len); | |
| 825 | + strscpy(modalias, default_id, len); | |
| 826 | 826 | } |
| 827 | 827 | EXPORT_SYMBOL_GPL(acpi_set_modalias); |
| 828 | 828 | |
| @@ -925,12 +925,13 @@ static const void *acpi_of_device_get_match_data(const struct device *dev) · 96 unmodified lines | ||
| 925 | 925 | |
| 926 | 926 | const void *acpi_device_get_match_data(const struct device *dev) |
| 927 | 927 | { |
| 928 | + const struct acpi_device_id *acpi_ids = dev->driver->acpi_match_table; | |
| 928 | 929 | const struct acpi_device_id *match; |
| 929 | 930 | |
| 930 | − if (!dev->driver->acpi_match_table) | |
| 931 | + if (!acpi_ids) | |
| 931 | 932 | return acpi_of_device_get_match_data(dev); |
| 932 | 933 | |
| 933 | − match = acpi_match_device(dev->driver->acpi_match_table, dev); | |
| 934 | + match = acpi_match_device(acpi_ids, dev); | |
| 934 | 935 | if (!match) |
| 935 | 936 | return NULL; |
| 936 | 937 | |
| @@ -948,14 +949,13 @@ EXPORT_SYMBOL(acpi_match_device_ids); · 11 unmodified lines | ||
| 948 | 949 | bool acpi_driver_match_device(struct device *dev, |
| 949 | 950 | const struct device_driver *drv) |
| 950 | 951 | { |
| 951 | − if (!drv->acpi_match_table) | |
| 952 | − return acpi_of_match_device(ACPI_COMPANION(dev), | |
| 953 | − drv->of_match_table, | |
| 954 | − NULL); | |
| 955 | − | |
| 956 | − return __acpi_match_device(acpi_companion_match(dev), | |
| 957 | − drv->acpi_match_table, drv->of_match_table, | |
| 958 | − NULL, NULL); | |
| 952 | + const struct acpi_device_id *acpi_ids = drv->acpi_match_table; | |
| 953 | + const struct of_device_id *of_ids = drv->of_match_table; | |
| 954 | + | |
| 955 | + if (!acpi_ids) | |
| 956 | + return acpi_of_match_device(ACPI_COMPANION(dev), of_ids, NULL); | |
| 957 | + | |
| 958 | + return __acpi_match_device(acpi_companion_match(dev), acpi_ids, of_ids, NULL, NULL); | |
| 959 | 959 | } |
| 960 | 960 | EXPORT_SYMBOL_GPL(acpi_driver_match_device); |
| 961 | 961 | |
| @@ -973,16 +973,13 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_device); · 11 unmodified lines | ||
| 973 | 973 | */ |
| 974 | 974 | int acpi_bus_register_driver(struct acpi_driver *driver) |
| 975 | 975 | { |
| 976 | − int ret; | |
| 977 | − | |
| 978 | 976 | if (acpi_disabled) |
| 979 | 977 | return -ENODEV; |
| 980 | 978 | driver->drv.name = driver->name; |
| 981 | 979 | driver->drv.bus = &acpi_bus_type; |
| 982 | 980 | driver->drv.owner = driver->owner; |
| 983 | 981 | |
| 984 | − ret = driver_register(&driver->drv); | |
| 985 | − return ret; | |
| 982 | + return driver_register(&driver->drv); | |
| 986 | 983 | } |
| 987 | 984 | |
| 988 | 985 | EXPORT_SYMBOL(acpi_bus_register_driver); |
| @@ -424,6 +424,9 @@ bool acpi_cpc_valid(void) · 423 unmodified lines | ||
| 424 | 424 | struct cpc_desc *cpc_ptr; |
| 425 | 425 | int cpu; |
| 426 | 426 | |
| 427 | + if (acpi_disabled) | |
| 428 | + return false; | |
| 429 | + | |
| 427 | 430 | for_each_present_cpu(cpu) { |
| 428 | 431 | cpc_ptr = per_cpu(cpc_desc_ptr, cpu); |
| 429 | 432 | if (!cpc_ptr) |
| @@ -1240,6 +1243,48 @@ out_err: · 810 unmodified lines | ||
| 1240 | 1243 | } |
| 1241 | 1244 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); |
| 1242 | 1245 | |
| 1246 | +/** | |
| 1247 | + * cppc_perf_ctrs_in_pcc - Check if any perf counters are in a PCC region. | |
| 1248 | + * | |
| 1249 | + * CPPC has flexibility about how CPU performance counters are accessed. | |
| 1250 | + * One of the choices is PCC regions, which can have a high access latency. This | |
| 1251 | + * routine allows callers of cppc_get_perf_ctrs() to know this ahead of time. | |
| 1252 | + * | |
| 1253 | + * Return: true if any of the counters are in PCC regions, false otherwise | |
| 1254 | + */ | |
| 1255 | +bool cppc_perf_ctrs_in_pcc(void) | |
| 1256 | +{ | |
| 1257 | + int cpu; | |
| 1258 | + | |
| 1259 | + for_each_present_cpu(cpu) { | |
| 1260 | + struct cpc_register_resource *ref_perf_reg; | |
| 1261 | + struct cpc_desc *cpc_desc; | |
| 1262 | + | |
| 1263 | + cpc_desc = per_cpu(cpc_desc_ptr, cpu); | |
| 1264 | + | |
| 1265 | + if (CPC_IN_PCC(&cpc_desc->cpc_regs[DELIVERED_CTR]) || | |
| 1266 | + CPC_IN_PCC(&cpc_desc->cpc_regs[REFERENCE_CTR]) || | |
| 1267 | + CPC_IN_PCC(&cpc_desc->cpc_regs[CTR_WRAP_TIME])) | |
| 1268 | + return true; | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; | |
| 1272 | + | |
| 1273 | + /* | |
| 1274 | + * If reference perf register is not supported then we should | |
| 1275 | + * use the nominal perf value | |
| 1276 | + */ | |
| 1277 | + if (!CPC_SUPPORTED(ref_perf_reg)) | |
| 1278 | + ref_perf_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; | |
| 1279 | + | |
| 1280 | + if (CPC_IN_PCC(ref_perf_reg)) | |
| 1281 | + return true; | |
| 1282 | + } | |
| 1283 | + | |
| 1284 | + return false; | |
| 1285 | +} | |
| 1286 | +EXPORT_SYMBOL_GPL(cppc_perf_ctrs_in_pcc); | |
| 1287 | + | |
| 1243 | 1288 | /** |
| 1244 | 1289 | * cppc_get_perf_ctrs - Read a CPU's performance feedback counters. |
| 1245 | 1290 | * @cpunum: CPU from which to read counters. |
| @@ -75,15 +75,17 @@ static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state) · 74 unmodified lines | ||
| 75 | 75 | int acpi_device_get_power(struct acpi_device *device, int *state) |
| 76 | 76 | { |
| 77 | 77 | int result = ACPI_STATE_UNKNOWN; |
| 78 | + struct acpi_device *parent; | |
| 78 | 79 | int error; |
| 79 | 80 | |
| 80 | 81 | if (!device || !state) |
| 81 | 82 | return -EINVAL; |
| 82 | 83 | |
| 84 | + parent = acpi_dev_parent(device); | |
| 85 | + | |
| 83 | 86 | if (!device->flags.power_manageable) { |
| 84 | 87 | /* TBD: Non-recursive algorithm for walking up hierarchy. */ |
| 85 | − *state = device->parent ? | |
| 86 | − device->parent->power.state : ACPI_STATE_D0; | |
| 88 | + *state = parent ? parent->power.state : ACPI_STATE_D0; | |
| 87 | 89 | goto out; |
| 88 | 90 | } |
| 89 | 91 | |
| @@ -122,10 +124,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state) · 32 unmodified lines | ||
| 122 | 124 | * point, the fact that the device is in D0 implies that the parent has |
| 123 | 125 | * to be in D0 too, except if ignore_parent is set. |
| 124 | 126 | */ |
| 125 | − if (!device->power.flags.ignore_parent && device->parent | |
| 126 | − && device->parent->power.state == ACPI_STATE_UNKNOWN | |
| 127 | − && result == ACPI_STATE_D0) | |
| 128 | − device->parent->power.state = ACPI_STATE_D0; | |
| 127 | + if (!device->power.flags.ignore_parent && parent && | |
| 128 | + parent->power.state == ACPI_STATE_UNKNOWN && | |
| 129 | + result == ACPI_STATE_D0) | |
| 130 | + parent->power.state = ACPI_STATE_D0; | |
| 129 | 131 | |
| 130 | 132 | *state = result; |
| 131 | 133 | |
| @@ -191,13 +193,17 @@ int acpi_device_set_power(struct acpi_device *device, int state) · 59 unmodified lines | ||
| 191 | 193 | return -ENODEV; |
| 192 | 194 | } |
| 193 | 195 | |
| 194 | − if (!device->power.flags.ignore_parent && device->parent && | |
| 195 | − state < device->parent->power.state) { | |
| 196 | − acpi_handle_debug(device->handle, | |
| 197 | − "Cannot transition to %s for parent in %s\n", | |
| 198 | − acpi_power_state_string(state), | |
| 199 | − acpi_power_state_string(device->parent->power.state)); | |
| 200 | − return -ENODEV; | |
| 196 | + if (!device->power.flags.ignore_parent) { | |
| 197 | + struct acpi_device *parent; | |
| 198 | + | |
| 199 | + parent = acpi_dev_parent(device); | |
| 200 | + if (parent && state < parent->power.state) { | |
| 201 | + acpi_handle_debug(device->handle, | |
| 202 | + "Cannot transition to %s for parent in %s\n", | |
| 203 | + acpi_power_state_string(state), | |
| 204 | + acpi_power_state_string(parent->power.state)); | |
| 205 | + return -ENODEV; | |
| 206 | + } | |
| 201 | 207 | } |
| 202 | 208 | |
| 203 | 209 | /* |
| @@ -497,7 +503,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) · 293 unmodified lines | ||
| 497 | 503 | |
| 498 | 504 | acpi_handle_debug(handle, "Wake notify\n"); |
| 499 | 505 | |
| 500 | − adev = acpi_bus_get_acpi_device(handle); | |
| 506 | + adev = acpi_get_acpi_dev(handle); | |
| 501 | 507 | if (!adev) |
| 502 | 508 | return; |
| 503 | 509 | |
| @@ -515,7 +521,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) · 11 unmodified lines | ||
| 515 | 521 | |
| 516 | 522 | mutex_unlock(&acpi_pm_notifier_lock); |
| 517 | 523 | |
| 518 | − acpi_bus_put_acpi_device(adev); | |
| 524 | + acpi_put_acpi_dev(adev); | |
| 519 | 525 | } |
| 520 | 526 | |
| 521 | 527 | /** |
| @@ -1460,7 +1466,7 @@ EXPORT_SYMBOL_GPL(acpi_storage_d3); · 938 unmodified lines | ||
| 1460 | 1466 | * not valid to ask for the ACPI power state of the device in that time frame. |
| 1461 | 1467 | * |
| 1462 | 1468 | * This function is intended to be used in a driver's probe or remove |
| 1463 | − * function. See Documentation/firmware-guide/acpi/low-power-probe.rst for | |
| 1469 | + * function. See Documentation/firmware-guide/acpi/non-d0-probe.rst for | |
| 1464 | 1470 | * more information. |
| 1465 | 1471 | */ |
| 1466 | 1472 | bool acpi_dev_state_d0(struct device *dev) |
| @@ -11,9 +11,6 @@ menuconfig ACPI_DPTF · 10 unmodified lines | ||
| 11 | 11 | a coordinated approach for different policies to effect the hardware |
| 12 | 12 | state of a system. |
| 13 | 13 | |
| 14 | − For more information see: | |
| 15 | − <https://01.org/intel%C2%AE-dynamic-platform-and-thermal-framework-dptf-chromium-os/overview> | |
| 16 | − | |
| 17 | 14 | if ACPI_DPTF |
| 18 | 15 | |
| 19 | 16 | config DPTF_POWER |
| @@ -917,14 +917,10 @@ EXPORT_SYMBOL(ec_read); · 916 unmodified lines | ||
| 917 | 917 | |
| 918 | 918 | int ec_write(u8 addr, u8 val) |
| 919 | 919 | { |
| 920 | − int err; | |
| 921 | − | |
| 922 | 920 | if (!first_ec) |
| 923 | 921 | return -ENODEV; |
| 924 | 922 | |
| 925 | − err = acpi_ec_write(first_ec, addr, val); | |
| 926 | − | |
| 927 | − return err; | |
| 923 | + return acpi_ec_write(first_ec, addr, val); | |
| 928 | 924 | } |
| 929 | 925 | EXPORT_SYMBOL(ec_write); |
| 930 | 926 | |
| @@ -19,43 +19,12 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #include "fan.h" |
| 21 | 21 | |
| 22 | −MODULE_AUTHOR("Paul Diefenbaugh"); | |
| 23 | −MODULE_DESCRIPTION("ACPI Fan Driver"); | |
| 24 | −MODULE_LICENSE("GPL"); | |
| 25 | − | |
| 26 | −static int acpi_fan_probe(struct platform_device *pdev); | |
| 27 | −static int acpi_fan_remove(struct platform_device *pdev); | |
| 28 | − | |
| 29 | 22 | static const struct acpi_device_id fan_device_ids[] = { |
| 30 | 23 | ACPI_FAN_DEVICE_IDS, |
| 31 | 24 | {"", 0}, |
| 32 | 25 | }; |
| 33 | 26 | MODULE_DEVICE_TABLE(acpi, fan_device_ids); |
| 34 | 27 | |
| 35 | −#ifdef CONFIG_PM_SLEEP | |
| 36 | −static int acpi_fan_suspend(struct device *dev); | |
| 37 | −static int acpi_fan_resume(struct device *dev); | |
| 38 | −static const struct dev_pm_ops acpi_fan_pm = { | |
| 39 | − .resume = acpi_fan_resume, | |
| 40 | − .freeze = acpi_fan_suspend, | |
| 41 | − .thaw = acpi_fan_resume, | |
| 42 | − .restore = acpi_fan_resume, | |
| 43 | −}; | |
| 44 | −#define FAN_PM_OPS_PTR (&acpi_fan_pm) | |
| 45 | −#else | |
| 46 | −#define FAN_PM_OPS_PTR NULL | |
| 47 | −#endif | |
| 48 | − | |
| 49 | −static struct platform_driver acpi_fan_driver = { | |
| 50 | − .probe = acpi_fan_probe, | |
| 51 | − .remove = acpi_fan_remove, | |
| 52 | − .driver = { | |
| 53 | − .name = "acpi-fan", | |
| 54 | − .acpi_match_table = fan_device_ids, | |
| 55 | − .pm = FAN_PM_OPS_PTR, | |
| 56 | − }, | |
| 57 | −}; | |
| 58 | − | |
| 59 | 28 | /* thermal cooling device callbacks */ |
| 60 | 29 | static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long |
| 61 | 30 | *state) |
| @@ -459,6 +428,33 @@ static int acpi_fan_resume(struct device *dev) · 397 unmodified lines | ||
| 459 | 428 | |
| 460 | 429 | return result; |
| 461 | 430 | } |
| 431 | + | |
| 432 | +static const struct dev_pm_ops acpi_fan_pm = { | |
| 433 | + .resume = acpi_fan_resume, | |
| 434 | + .freeze = acpi_fan_suspend, | |
| 435 | + .thaw = acpi_fan_resume, | |
| 436 | + .restore = acpi_fan_resume, | |
| 437 | +}; | |
| 438 | +#define FAN_PM_OPS_PTR (&acpi_fan_pm) | |
| 439 | + | |
| 440 | +#else | |
| 441 | + | |
| 442 | +#define FAN_PM_OPS_PTR NULL | |
| 443 | + | |
| 462 | 444 | #endif |
| 463 | 445 | |
| 446 | +static struct platform_driver acpi_fan_driver = { | |
| 447 | + .probe = acpi_fan_probe, | |
| 448 | + .remove = acpi_fan_remove, | |
| 449 | + .driver = { | |
| 450 | + .name = "acpi-fan", | |
| 451 | + .acpi_match_table = fan_device_ids, | |
| 452 | + .pm = FAN_PM_OPS_PTR, | |
| 453 | + }, | |
| 454 | +}; | |
| 455 | + | |
| 464 | 456 | module_platform_driver(acpi_fan_driver); |
| 457 | + | |
| 458 | +MODULE_AUTHOR("Paul Diefenbaugh"); | |
| 459 | +MODULE_DESCRIPTION("ACPI Fan Driver"); | |
| 460 | +MODULE_LICENSE("GPL"); | |
| @@ -102,10 +102,10 @@ struct acpi_device_bus_id { · 101 unmodified lines | ||
| 102 | 102 | struct list_head node; |
| 103 | 103 | }; |
| 104 | 104 | |
| 105 | −int acpi_device_add(struct acpi_device *device, | |
| 106 | − void (*release)(struct device *)); | |
| 107 | 105 | void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, |
| 108 | − int type); | |
| 106 | + int type, void (*release)(struct device *)); | |
| 107 | +int acpi_tie_acpi_dev(struct acpi_device *adev); | |
| 108 | +int acpi_device_add(struct acpi_device *device); | |
| 109 | 109 | int acpi_device_setup_files(struct acpi_device *dev); |
| 110 | 110 | void acpi_device_remove_files(struct acpi_device *dev); |
| 111 | 111 | void acpi_device_add_finalize(struct acpi_device *device); |
| @@ -118,12 +118,12 @@ acpi_get_irq_source_fwhandle(const struct acpi_resource_source *source, · 117 unmodified lines | ||
| 118 | 118 | if (WARN_ON(ACPI_FAILURE(status))) |
| 119 | 119 | return NULL; |
| 120 | 120 | |
| 121 | − device = acpi_bus_get_acpi_device(handle); | |
| 121 | + device = acpi_get_acpi_dev(handle); | |
| 122 | 122 | if (WARN_ON(!device)) |
| 123 | 123 | return NULL; |
| 124 | 124 | |
| 125 | 125 | result = &device->fwnode; |
| 126 | − acpi_bus_put_acpi_device(device); | |
| 126 | + acpi_put_acpi_dev(device); | |
| 127 | 127 | return result; |
| 128 | 128 | } |
| 129 | 129 | |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | #define pr_fmt(fmt) "acpi/hmat: " fmt |
| 12 | −#define dev_fmt(fmt) "acpi/hmat: " fmt | |
| 13 | 12 | |
| 14 | 13 | #include <linux/acpi.h> |
| 15 | 14 | #include <linux/bitops.h> |
| @@ -302,7 +301,7 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, · 286 unmodified lines | ||
| 302 | 301 | u8 type, mem_hier; |
| 303 | 302 | |
| 304 | 303 | if (hmat_loc->header.length < sizeof(*hmat_loc)) { |
| 305 | − pr_notice("HMAT: Unexpected locality header length: %u\n", | |
| 304 | + pr_notice("Unexpected locality header length: %u\n", | |
| 306 | 305 | hmat_loc->header.length); |
| 307 | 306 | return -EINVAL; |
| 308 | 307 | } |
| @@ -314,12 +313,12 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, · 5 unmodified lines | ||
| 314 | 313 | total_size = sizeof(*hmat_loc) + sizeof(*entries) * ipds * tpds + |
| 315 | 314 | sizeof(*inits) * ipds + sizeof(*targs) * tpds; |
| 316 | 315 | if (hmat_loc->header.length < total_size) { |
| 317 | − pr_notice("HMAT: Unexpected locality header length:%u, minimum required:%u\n", | |
| 316 | + pr_notice("Unexpected locality header length:%u, minimum required:%u\n", | |
| 318 | 317 | hmat_loc->header.length, total_size); |
| 319 | 318 | return -EINVAL; |
| 320 | 319 | } |
| 321 | 320 | |
| 322 | − pr_info("HMAT: Locality: Flags:%02x Type:%s Initiator Domains:%u Target Domains:%u Base:%lld\n", | |
| 321 | + pr_info("Locality: Flags:%02x Type:%s Initiator Domains:%u Target Domains:%u Base:%lld\n", | |
| 323 | 322 | hmat_loc->flags, hmat_data_type(type), ipds, tpds, |
| 324 | 323 | hmat_loc->entry_base_unit); |
| 325 | 324 | |
| @@ -363,13 +362,13 @@ static __init int hmat_parse_cache(union acpi_subtable_headers *header, · 37 unmodified lines | ||
| 363 | 362 | u32 attrs; |
| 364 | 363 | |
| 365 | 364 | if (cache->header.length < sizeof(*cache)) { |
| 366 | − pr_notice("HMAT: Unexpected cache header length: %u\n", | |
| 365 | + pr_notice("Unexpected cache header length: %u\n", | |
| 367 | 366 | cache->header.length); |
| 368 | 367 | return -EINVAL; |
| 369 | 368 | } |
| 370 | 369 | |
| 371 | 370 | attrs = cache->cache_attributes; |
| 372 | − pr_info("HMAT: Cache: Domain:%u Size:%llu Attrs:%08x SMBIOS Handles:%d\n", | |
| 371 | + pr_info("Cache: Domain:%u Size:%llu Attrs:%08x SMBIOS Handles:%d\n", | |
| 373 | 372 | cache->memory_PD, cache->cache_size, attrs, |
| 374 | 373 | cache->number_of_SMBIOShandles); |
| 375 | 374 | |
| @@ -424,24 +423,24 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade · 48 unmodified lines | ||
| 424 | 423 | struct memory_target *target = NULL; |
| 425 | 424 | |
| 426 | 425 | if (p->header.length != sizeof(*p)) { |
| 427 | − pr_notice("HMAT: Unexpected address range header length: %u\n", | |
| 426 | + pr_notice("Unexpected address range header length: %u\n", | |
| 428 | 427 | p->header.length); |
| 429 | 428 | return -EINVAL; |
| 430 | 429 | } |
| 431 | 430 | |
| 432 | 431 | if (hmat_revision == 1) |
| 433 | − pr_info("HMAT: Memory (%#llx length %#llx) Flags:%04x Processor Domain:%u Memory Domain:%u\n", | |
| 432 | + pr_info("Memory (%#llx length %#llx) Flags:%04x Processor Domain:%u Memory Domain:%u\n", | |
| 434 | 433 | p->reserved3, p->reserved4, p->flags, p->processor_PD, |
| 435 | 434 | p->memory_PD); |
| 436 | 435 | else |
| 437 | − pr_info("HMAT: Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n", | |
| 436 | + pr_info("Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n", | |
| 438 | 437 | p->flags, p->processor_PD, p->memory_PD); |
| 439 | 438 | |
| 440 | 439 | if ((hmat_revision == 1 && p->flags & ACPI_HMAT_MEMORY_PD_VALID) || |
| 441 | 440 | hmat_revision > 1) { |
| 442 | 441 | target = find_mem_target(p->memory_PD); |
| 443 | 442 | if (!target) { |
| 444 | − pr_debug("HMAT: Memory Domain missing from SRAT\n"); | |
| 443 | + pr_debug("Memory Domain missing from SRAT\n"); | |
| 445 | 444 | return -EINVAL; |
| 446 | 445 | } |
| 447 | 446 | } |
| @@ -449,7 +448,7 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade · 1 unmodified line | ||
| 449 | 448 | int p_node = pxm_to_node(p->processor_PD); |
| 450 | 449 | |
| 451 | 450 | if (p_node == NUMA_NO_NODE) { |
| 452 | − pr_debug("HMAT: Invalid Processor Domain\n"); | |
| 451 | + pr_debug("Invalid Processor Domain\n"); | |
| 453 | 452 | return -EINVAL; |
| 454 | 453 | } |
| 455 | 454 | target->processor_pxm = p->processor_PD; |
| @@ -840,7 +839,7 @@ static __init int hmat_init(void) · 384 unmodified lines | ||
| 840 | 839 | case 2: |
| 841 | 840 | break; |
| 842 | 841 | default: |
| 843 | − pr_notice("Ignoring HMAT: Unknown revision:%d\n", hmat_revision); | |
| 842 | + pr_notice("Ignoring: Unknown revision:%d\n", hmat_revision); | |
| 844 | 843 | goto out_put; |
| 845 | 844 | } |
| 846 | 845 | |
| @@ -848,7 +847,7 @@ static __init int hmat_init(void) · 1 unmodified line | ||
| 848 | 847 | if (acpi_table_parse_entries(ACPI_SIG_HMAT, |
| 849 | 848 | sizeof(struct acpi_table_hmat), i, |
| 850 | 849 | hmat_parse_subtable, 0) < 0) { |
| 851 | − pr_notice("Ignoring HMAT: Invalid table"); | |
| 850 | + pr_notice("Ignoring: Invalid table"); | |
| 852 | 851 | goto out_put; |
| 853 | 852 | } |
| 854 | 853 | } |
| @@ -44,30 +44,6 @@ osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { · 43 unmodified lines | ||
| 44 | 44 | {"Processor Device", true}, |
| 45 | 45 | {"3.0 _SCP Extensions", true}, |
| 46 | 46 | {"Processor Aggregator Device", true}, |
| 47 | − /* | |
| 48 | − * Linux-Dell-Video is used by BIOS to disable RTD3 for NVidia graphics | |
| 49 | − * cards as RTD3 is not supported by drivers now. Systems with NVidia | |
| 50 | − * cards will hang without RTD3 disabled. | |
| 51 | − * | |
| 52 | − * Once NVidia drivers officially support RTD3, this _OSI strings can | |
| 53 | − * be removed if both new and old graphics cards are supported. | |
| 54 | − */ | |
| 55 | − {"Linux-Dell-Video", true}, | |
| 56 | − /* | |
| 57 | − * Linux-Lenovo-NV-HDMI-Audio is used by BIOS to power on NVidia's HDMI | |
| 58 | − * audio device which is turned off for power-saving in Windows OS. | |
| 59 | − * This power management feature observed on some Lenovo Thinkpad | |
| 60 | − * systems which will not be able to output audio via HDMI without | |
| 61 | − * a BIOS workaround. | |
| 62 | − */ | |
| 63 | − {"Linux-Lenovo-NV-HDMI-Audio", true}, | |
| 64 | − /* | |
| 65 | − * Linux-HPI-Hybrid-Graphics is used by BIOS to enable dGPU to | |
| 66 | − * output video directly to external monitors on HP Inc. mobile | |
| 67 | − * workstations as Nvidia and AMD VGA drivers provide limited | |
| 68 | − * hybrid graphics supports. | |
| 69 | − */ | |
| 70 | − {"Linux-HPI-Hybrid-Graphics", true}, | |
| 71 | 47 | }; |
| 72 | 48 | |
| 73 | 49 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
| @@ -312,76 +312,25 @@ struct acpi_handle_node { · 311 unmodified lines | ||
| 312 | 312 | */ |
| 313 | 313 | struct pci_dev *acpi_get_pci_dev(acpi_handle handle) |
| 314 | 314 | { |
| 315 | − int dev, fn; | |
| 316 | − unsigned long long adr; | |
| 317 | − acpi_status status; | |
| 318 | − acpi_handle phandle; | |
| 319 | − struct pci_bus *pbus; | |
| 320 | − struct pci_dev *pdev = NULL; | |
| 321 | − struct acpi_handle_node *node, *tmp; | |
| 322 | − struct acpi_pci_root *root; | |
| 323 | − LIST_HEAD(device_list); | |
| 324 | − | |
| 325 | − /* | |
| 326 | − * Walk up the ACPI CA namespace until we reach a PCI root bridge. | |
| 327 | − */ | |
| 328 | − phandle = handle; | |
| 329 | − while (!acpi_is_root_bridge(phandle)) { | |
| 330 | − node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL); | |
| 331 | − if (!node) | |
| 332 | − goto out; | |
| 333 | − | |
| 334 | − INIT_LIST_HEAD(&node->node); | |
| 335 | − node->handle = phandle; | |
| 336 | − list_add(&node->node, &device_list); | |
| 337 | − | |
| 338 | − status = acpi_get_parent(phandle, &phandle); | |
| 339 | − if (ACPI_FAILURE(status)) | |
| 340 | − goto out; | |
| 341 | − } | |
| 342 | − | |
| 343 | − root = acpi_pci_find_root(phandle); | |
| 344 | − if (!root) | |
| 345 | − goto out; | |
| 315 | + struct acpi_device *adev = acpi_fetch_acpi_dev(handle); | |
| 316 | + struct acpi_device_physical_node *pn; | |
| 317 | + struct pci_dev *pci_dev = NULL; | |
| 346 | 318 | |
| 347 | − pbus = root->bus; | |
| 348 | − | |
| 349 | − /* | |
| 350 | − * Now, walk back down the PCI device tree until we return to our | |
| 351 | − * original handle. Assumes that everything between the PCI root | |
| 352 | − * bridge and the device we're looking for must be a P2P bridge. | |
| 353 | − */ | |
| 354 | − list_for_each_entry(node, &device_list, node) { | |
| 355 | − acpi_handle hnd = node->handle; | |
| 356 | − status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr); | |
| 357 | − if (ACPI_FAILURE(status)) | |
| 358 | − goto out; | |
| 359 | − dev = (adr >> 16) & 0xffff; | |
| 360 | − fn = adr & 0xffff; | |
| 361 | − | |
| 362 | − pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); | |
| 363 | − if (!pdev || hnd == handle) | |
| 364 | − break; | |
| 319 | + if (!adev) | |
| 320 | + return NULL; | |
| 365 | 321 | |
| 366 | − pbus = pdev->subordinate; | |
| 367 | − pci_dev_put(pdev); | |
| 322 | + mutex_lock(&adev->physical_node_lock); | |
| 368 | 323 | |
| 369 | − /* | |
| 370 | − * This function may be called for a non-PCI device that has a | |
| 371 | − * PCI parent (eg. a disk under a PCI SATA controller). In that | |
| 372 | − * case pdev->subordinate will be NULL for the parent. | |
| 373 | − */ | |
| 374 | − if (!pbus) { | |
| 375 | − dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n"); | |
| 376 | − pdev = NULL; | |
| 324 | + list_for_each_entry(pn, &adev->physical_node_list, node) { | |
| 325 | + if (dev_is_pci(pn->dev)) { | |
| 326 | + pci_dev = to_pci_dev(pn->dev); | |
| 377 | 327 | break; |
| 378 | 328 | } |
| 379 | 329 | } |
| 380 | −out: | |
| 381 | − list_for_each_entry_safe(node, tmp, &device_list, node) | |
| 382 | − kfree(node); | |
| 383 | 330 | |
| 384 | − return pdev; | |
| 331 | + mutex_unlock(&adev->physical_node_lock); | |
| 332 | + | |
| 333 | + return pci_dev; | |
| 385 | 334 | } |
| 386 | 335 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); |
| 387 | 336 | |
| @@ -944,13 +944,15 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle) · 943 unmodified lines | ||
| 944 | 944 | return NULL; |
| 945 | 945 | |
| 946 | 946 | device = &resource->device; |
| 947 | − acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER); | |
| 947 | + acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER, | |
| 948 | + acpi_release_power_resource); | |
| 948 | 949 | mutex_init(&resource->resource_lock); |
| 949 | 950 | INIT_LIST_HEAD(&resource->list_node); |
| 950 | 951 | INIT_LIST_HEAD(&resource->dependents); |
| 951 | 952 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
| 952 | 953 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
| 953 | 954 | device->power.state = ACPI_STATE_UNKNOWN; |
| 955 | + device->flags.match_driver = true; | |
| 954 | 956 | |
| 955 | 957 | /* Evaluate the object to get the system level and resource order. */ |
| 956 | 958 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); |
| @@ -967,8 +969,11 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle) · 10 unmodified lines | ||
| 967 | 969 | |
| 968 | 970 | pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device)); |
| 969 | 971 | |
| 970 | − device->flags.match_driver = true; | |
| 971 | − result = acpi_device_add(device, acpi_release_power_resource); | |
| 972 | + result = acpi_tie_acpi_dev(device); | |
| 973 | + if (result) | |
| 974 | + goto err; | |
| 975 | + | |
| 976 | + result = acpi_device_add(device); | |
| 972 | 977 | if (result) |
| 973 | 978 | goto err; |
| 974 | 979 | |
| @@ -804,7 +804,7 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr) · 803 unmodified lines | ||
| 804 | 804 | |
| 805 | 805 | state = &drv->states[count]; |
| 806 | 806 | snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); |
| 807 | − strlcpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); | |
| 807 | + strscpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); | |
| 808 | 808 | state->exit_latency = cx->latency; |
| 809 | 809 | state->target_residency = cx->latency * latency_factor; |
| 810 | 810 | state->enter = acpi_idle_enter; |
| @@ -973,7 +973,7 @@ static int acpi_processor_evaluate_lpi(acpi_handle handle, · 162 unmodified lines | ||
| 973 | 973 | |
| 974 | 974 | obj = pkg_elem + 9; |
| 975 | 975 | if (obj->type == ACPI_TYPE_STRING) |
| 976 | − strlcpy(lpi_state->desc, obj->string.pointer, | |
| 976 | + strscpy(lpi_state->desc, obj->string.pointer, | |
| 977 | 977 | ACPI_CX_DESC_LEN); |
| 978 | 978 | |
| 979 | 979 | lpi_state->index = state_idx; |
| @@ -1039,7 +1039,7 @@ static bool combine_lpi_states(struct acpi_lpi_state *local, · 59 unmodified lines | ||
| 1039 | 1039 | result->arch_flags = parent->arch_flags; |
| 1040 | 1040 | result->index = parent->index; |
| 1041 | 1041 | |
| 1042 | − strlcpy(result->desc, local->desc, ACPI_CX_DESC_LEN); | |
| 1042 | + strscpy(result->desc, local->desc, ACPI_CX_DESC_LEN); | |
| 1043 | 1043 | strlcat(result->desc, "+", ACPI_CX_DESC_LEN); |
| 1044 | 1044 | strlcat(result->desc, parent->desc, ACPI_CX_DESC_LEN); |
| 1045 | 1045 | return true; |
| @@ -1213,7 +1213,7 @@ static int acpi_processor_setup_lpi_states(struct acpi_processor *pr) · 167 unmodified lines | ||
| 1213 | 1213 | |
| 1214 | 1214 | state = &drv->states[i]; |
| 1215 | 1215 | snprintf(state->name, CPUIDLE_NAME_LEN, "LPI-%d", i); |
| 1216 | − strlcpy(state->desc, lpi->desc, CPUIDLE_DESC_LEN); | |
| 1216 | + strscpy(state->desc, lpi->desc, CPUIDLE_DESC_LEN); | |
| 1217 | 1217 | state->exit_latency = lpi->wake_latency; |
| 1218 | 1218 | state->target_residency = lpi->min_residency; |
| 1219 | 1219 | if (lpi->arch_flags) |
| @@ -304,8 +304,10 @@ static void acpi_init_of_compatible(struct acpi_device *adev) · 303 unmodified lines | ||
| 304 | 304 | ret = acpi_dev_get_property(adev, "compatible", |
| 305 | 305 | ACPI_TYPE_STRING, &of_compatible); |
| 306 | 306 | if (ret) { |
| 307 | − if (adev->parent | |
| 308 | − && adev->parent->flags.of_compatible_ok) | |
| 307 | + struct acpi_device *parent; | |
| 308 | + | |
| 309 | + parent = acpi_dev_parent(adev); | |
| 310 | + if (parent && parent->flags.of_compatible_ok) | |
| 309 | 311 | goto out; |
| 310 | 312 | |
| 311 | 313 | return; |
| @@ -1267,10 +1269,11 @@ acpi_node_get_parent(const struct fwnode_handle *fwnode) · 955 unmodified lines | ||
| 1267 | 1269 | return to_acpi_data_node(fwnode)->parent; |
| 1268 | 1270 | } |
| 1269 | 1271 | if (is_acpi_device_node(fwnode)) { |
| 1270 | − struct device *dev = to_acpi_device_node(fwnode)->dev.parent; | |
| 1272 | + struct acpi_device *parent; | |
| 1271 | 1273 | |
| 1272 | − if (dev) | |
| 1273 | − return acpi_fwnode_handle(to_acpi_device(dev)); | |
| 1274 | + parent = acpi_dev_parent(to_acpi_device_node(fwnode)); | |
| 1275 | + if (parent) | |
| 1276 | + return acpi_fwnode_handle(parent); | |
| 1274 | 1277 | } |
| 1275 | 1278 | |
| 1276 | 1279 | return NULL; |
| @@ -399,6 +399,31 @@ static const struct dmi_system_id medion_laptop[] = { · 398 unmodified lines | ||
| 399 | 399 | { } |
| 400 | 400 | }; |
| 401 | 401 | |
| 402 | +static const struct dmi_system_id asus_laptop[] = { | |
| 403 | + { | |
| 404 | + .ident = "Asus Vivobook K3402ZA", | |
| 405 | + .matches = { | |
| 406 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 407 | + DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"), | |
| 408 | + }, | |
| 409 | + }, | |
| 410 | + { | |
| 411 | + .ident = "Asus Vivobook K3502ZA", | |
| 412 | + .matches = { | |
| 413 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 414 | + DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"), | |
| 415 | + }, | |
| 416 | + }, | |
| 417 | + { | |
| 418 | + .ident = "Asus Vivobook S5402ZA", | |
| 419 | + .matches = { | |
| 420 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 421 | + DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"), | |
| 422 | + }, | |
| 423 | + }, | |
| 424 | + { } | |
| 425 | +}; | |
| 426 | + | |
| 402 | 427 | struct irq_override_cmp { |
| 403 | 428 | const struct dmi_system_id *system; |
| 404 | 429 | unsigned char irq; |
| @@ -409,6 +434,7 @@ struct irq_override_cmp { · 4 unmodified lines | ||
| 409 | 434 | |
| 410 | 435 | static const struct irq_override_cmp skip_override_table[] = { |
| 411 | 436 | { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, |
| 437 | + { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, | |
| 412 | 438 | }; |
| 413 | 439 | |
| 414 | 440 | static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, |
| @@ -690,6 +716,9 @@ static int is_memory(struct acpi_resource *ares, void *not_used) · 275 unmodified lines | ||
| 690 | 716 | |
| 691 | 717 | memset(&win, 0, sizeof(win)); |
| 692 | 718 | |
| 719 | + if (acpi_dev_filter_resource_type(ares, IORESOURCE_MEM)) | |
| 720 | + return 1; | |
| 721 | + | |
| 693 | 722 | return !(acpi_dev_resource_memory(ares, res) |
| 694 | 723 | || acpi_dev_resource_address_space(ares, &win) |
| 695 | 724 | || acpi_dev_resource_ext_address_space(ares, &win)); |
| @@ -718,6 +747,23 @@ int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list) · 22 unmodified lines | ||
| 718 | 747 | } |
| 719 | 748 | EXPORT_SYMBOL_GPL(acpi_dev_get_dma_resources); |
| 720 | 749 | |
| 750 | +/** | |
| 751 | + * acpi_dev_get_memory_resources - Get current memory resources of a device. | |
| 752 | + * @adev: ACPI device node to get the resources for. | |
| 753 | + * @list: Head of the resultant list of resources (must be empty). | |
| 754 | + * | |
| 755 | + * This is a helper function that locates all memory type resources of @adev | |
| 756 | + * with acpi_dev_get_resources(). | |
| 757 | + * | |
| 758 | + * The number of resources in the output list is returned on success, an error | |
| 759 | + * code reflecting the error condition is returned otherwise. | |
| 760 | + */ | |
| 761 | +int acpi_dev_get_memory_resources(struct acpi_device *adev, struct list_head *list) | |
| 762 | +{ | |
| 763 | + return acpi_dev_get_resources(adev, list, is_memory, NULL); | |
| 764 | +} | |
| 765 | +EXPORT_SYMBOL_GPL(acpi_dev_get_memory_resources); | |
| 766 | + | |
| 721 | 767 | /** |
| 722 | 768 | * acpi_dev_filter_resource_type - Filter ACPI resource according to resource |
| 723 | 769 | * types |
| @@ -632,7 +632,7 @@ static int acpi_sbs_add(struct acpi_device *device) · 631 unmodified lines | ||
| 632 | 632 | |
| 633 | 633 | mutex_init(&sbs->lock); |
| 634 | 634 | |
| 635 | − sbs->hc = acpi_driver_data(device->parent); | |
| 635 | + sbs->hc = acpi_driver_data(acpi_dev_parent(device)); | |
| 636 | 636 | sbs->device = device; |
| 637 | 637 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); |
| 638 | 638 | strcpy(acpi_device_class(device), ACPI_SBS_CLASS); |
| @@ -266,7 +266,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) · 265 unmodified lines | ||
| 266 | 266 | mutex_init(&hc->lock); |
| 267 | 267 | init_waitqueue_head(&hc->wait); |
| 268 | 268 | |
| 269 | − hc->ec = acpi_driver_data(device->parent); | |
| 269 | + hc->ec = acpi_driver_data(acpi_dev_parent(device)); | |
| 270 | 270 | hc->offset = (val >> 8) & 0xff; |
| 271 | 271 | hc->query_bit = val & 0xff; |
| 272 | 272 | device->driver_data = hc; |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/platform_data/x86/apple.h> |
| 21 | 21 | #include <linux/pgtable.h> |
| 22 | 22 | #include <linux/crc32.h> |
| 23 | +#include <linux/dma-direct.h> | |
| 23 | 24 | |
| 24 | 25 | #include "internal.h" |
| 25 | 26 | |
| @@ -29,8 +30,6 @@ extern struct acpi_device *acpi_root; · 3 unmodified lines | ||
| 29 | 30 | #define ACPI_BUS_HID "LNXSYBUS" |
| 30 | 31 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
| 31 | 32 | |
| 32 | −#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) | |
| 33 | − | |
| 34 | 33 | #define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page) |
| 35 | 34 | |
| 36 | 35 | static const char *dummy_hid = "device"; |
| @@ -429,7 +428,7 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src) · 392 unmodified lines | ||
| 429 | 428 | acpi_evaluate_ost(adev->handle, src, ost_code, NULL); |
| 430 | 429 | |
| 431 | 430 | out: |
| 432 | − acpi_bus_put_acpi_device(adev); | |
| 431 | + acpi_put_acpi_dev(adev); | |
| 433 | 432 | mutex_unlock(&acpi_scan_lock); |
| 434 | 433 | unlock_device_hotplug(); |
| 435 | 434 | } |
| @@ -599,11 +598,22 @@ static void get_acpi_device(void *dev) · 163 unmodified lines | ||
| 599 | 598 | acpi_dev_get(dev); |
| 600 | 599 | } |
| 601 | 600 | |
| 602 | −struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) | |
| 601 | +/** | |
| 602 | + * acpi_get_acpi_dev - Retrieve ACPI device object and reference count it. | |
| 603 | + * @handle: ACPI handle associated with the requested ACPI device object. | |
| 604 | + * | |
| 605 | + * Return a pointer to the ACPI device object associated with @handle and bump | |
| 606 | + * up that object's reference counter (under the ACPI Namespace lock), if | |
| 607 | + * present, or return NULL otherwise. | |
| 608 | + * | |
| 609 | + * The ACPI device object reference acquired by this function needs to be | |
| 610 | + * dropped via acpi_dev_put(). | |
| 611 | + */ | |
| 612 | +struct acpi_device *acpi_get_acpi_dev(acpi_handle handle) | |
| 603 | 613 | { |
| 604 | 614 | return handle_to_device(handle, get_acpi_device); |
| 605 | 615 | } |
| 606 | −EXPORT_SYMBOL_GPL(acpi_bus_get_acpi_device); | |
| 616 | +EXPORT_SYMBOL_GPL(acpi_get_acpi_dev); | |
| 607 | 617 | |
| 608 | 618 | static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id) |
| 609 | 619 | { |
| @@ -632,7 +642,7 @@ static int acpi_device_set_name(struct acpi_device *device, · 22 unmodified lines | ||
| 632 | 642 | return 0; |
| 633 | 643 | } |
| 634 | 644 | |
| 635 | −static int acpi_tie_acpi_dev(struct acpi_device *adev) | |
| 645 | +int acpi_tie_acpi_dev(struct acpi_device *adev) | |
| 636 | 646 | { |
| 637 | 647 | acpi_handle handle = adev->handle; |
| 638 | 648 | acpi_status status; |
| @@ -662,8 +672,7 @@ static void acpi_store_pld_crc(struct acpi_device *adev) · 23 unmodified lines | ||
| 662 | 672 | ACPI_FREE(pld); |
| 663 | 673 | } |
| 664 | 674 | |
| 665 | −static int __acpi_device_add(struct acpi_device *device, | |
| 666 | − void (*release)(struct device *)) | |
| 675 | +int acpi_device_add(struct acpi_device *device) | |
| 667 | 676 | { |
| 668 | 677 | struct acpi_device_bus_id *acpi_device_bus_id; |
| 669 | 678 | int result; |
| @@ -719,11 +728,6 @@ static int __acpi_device_add(struct acpi_device *device, · 49 unmodified lines | ||
| 719 | 728 | |
| 720 | 729 | mutex_unlock(&acpi_device_lock); |
| 721 | 730 | |
| 722 | − if (device->parent) | |
| 723 | − device->dev.parent = &device->parent->dev; | |
| 724 | − | |
| 725 | − device->dev.bus = &acpi_bus_type; | |
| 726 | − device->dev.release = release; | |
| 727 | 731 | result = device_add(&device->dev); |
| 728 | 732 | if (result) { |
| 729 | 733 | dev_err(&device->dev, "Error registering device\n"); |
| @@ -750,17 +754,6 @@ err_unlock: · 20 unmodified lines | ||
| 750 | 754 | return result; |
| 751 | 755 | } |
| 752 | 756 | |
| 753 | −int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *)) | |
| 754 | −{ | |
| 755 | − int ret; | |
| 756 | − | |
| 757 | − ret = acpi_tie_acpi_dev(adev); | |
| 758 | − if (ret) | |
| 759 | − return ret; | |
| 760 | − | |
| 761 | − return __acpi_device_add(adev, release); | |
| 762 | −} | |
| 763 | − | |
| 764 | 757 | /* -------------------------------------------------------------------------- |
| 765 | 758 | Device Enumeration |
| 766 | 759 | -------------------------------------------------------------------------- */ |
| @@ -805,10 +798,9 @@ static const char * const acpi_honor_dep_ids[] = { · 38 unmodified lines | ||
| 805 | 798 | NULL |
| 806 | 799 | }; |
| 807 | 800 | |
| 808 | −static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) | |
| 801 | +static struct acpi_device *acpi_find_parent_acpi_dev(acpi_handle handle) | |
| 809 | 802 | { |
| 810 | − struct acpi_device *device; | |
| 811 | − acpi_status status; | |
| 803 | + struct acpi_device *adev; | |
| 812 | 804 | |
| 813 | 805 | /* |
| 814 | 806 | * Fixed hardware devices do not appear in the namespace and do not |
| @@ -819,13 +811,18 @@ static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) · 4 unmodified lines | ||
| 819 | 811 | return acpi_root; |
| 820 | 812 | |
| 821 | 813 | do { |
| 814 | + acpi_status status; | |
| 815 | + | |
| 822 | 816 | status = acpi_get_parent(handle, &handle); |
| 823 | − if (ACPI_FAILURE(status)) | |
| 824 | − return status == AE_NULL_ENTRY ? NULL : acpi_root; | |
| 817 | + if (ACPI_FAILURE(status)) { | |
| 818 | + if (status != AE_NULL_ENTRY) | |
| 819 | + return acpi_root; | |
| 825 | 820 | |
| 826 | − device = acpi_fetch_acpi_dev(handle); | |
| 827 | − } while (!device); | |
| 828 | − return device; | |
| 821 | + return NULL; | |
| 822 | + } | |
| 823 | + adev = acpi_fetch_acpi_dev(handle); | |
| 824 | + } while (!adev); | |
| 825 | + return adev; | |
| 829 | 826 | } |
| 830 | 827 | |
| 831 | 828 | acpi_status |
| @@ -1112,7 +1109,7 @@ static void acpi_device_get_busid(struct acpi_device *device) · 280 unmodified lines | ||
| 1112 | 1109 | * The device's Bus ID is simply the object name. |
| 1113 | 1110 | * TBD: Shouldn't this value be unique (within the ACPI namespace)? |
| 1114 | 1111 | */ |
| 1115 | − if (ACPI_IS_ROOT_DEVICE(device)) { | |
| 1112 | + if (!acpi_dev_parent(device)) { | |
| 1116 | 1113 | strcpy(device->pnp.bus_id, "ACPI"); |
| 1117 | 1114 | return; |
| 1118 | 1115 | } |
| @@ -1467,25 +1464,21 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev) · 348 unmodified lines | ||
| 1467 | 1464 | * acpi_dma_get_range() - Get device DMA parameters. |
| 1468 | 1465 | * |
| 1469 | 1466 | * @dev: device to configure |
| 1470 | − * @dma_addr: pointer device DMA address result | |
| 1471 | − * @offset: pointer to the DMA offset result | |
| 1472 | − * @size: pointer to DMA range size result | |
| 1467 | + * @map: pointer to DMA ranges result | |
| 1473 | 1468 | * |
| 1474 | − * Evaluate DMA regions and return respectively DMA region start, offset | |
| 1475 | − * and size in dma_addr, offset and size on parsing success; it does not | |
| 1476 | − * update the passed in values on failure. | |
| 1469 | + * Evaluate DMA regions and return pointer to DMA regions on | |
| 1470 | + * parsing success; it does not update the passed in values on failure. | |
| 1477 | 1471 | * |
| 1478 | 1472 | * Return 0 on success, < 0 on failure. |
| 1479 | 1473 | */ |
| 1480 | −int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset, | |
| 1481 | − u64 *size) | |
| 1474 | +int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map) | |
| 1482 | 1475 | { |
| 1483 | 1476 | struct acpi_device *adev; |
| 1484 | 1477 | LIST_HEAD(list); |
| 1485 | 1478 | struct resource_entry *rentry; |
| 1486 | 1479 | int ret; |
| 1487 | 1480 | struct device *dma_dev = dev; |
| 1488 | − u64 len, dma_start = U64_MAX, dma_end = 0, dma_offset = 0; | |
| 1481 | + struct bus_dma_region *r; | |
| 1489 | 1482 | |
| 1490 | 1483 | /* |
| 1491 | 1484 | * Walk the device tree chasing an ACPI companion with a _DMA |
| @@ -1510,31 +1503,28 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset, · 18 unmodified lines | ||
| 1510 | 1503 | |
| 1511 | 1504 | ret = acpi_dev_get_dma_resources(adev, &list); |
| 1512 | 1505 | if (ret > 0) { |
| 1506 | + r = kcalloc(ret + 1, sizeof(*r), GFP_KERNEL); | |
| 1507 | + if (!r) { | |
| 1508 | + ret = -ENOMEM; | |
| 1509 | + goto out; | |
| 1510 | + } | |
| 1511 | + | |
| 1513 | 1512 | list_for_each_entry(rentry, &list, node) { |
| 1514 | − if (dma_offset && rentry->offset != dma_offset) { | |
| 1513 | + if (rentry->res->start >= rentry->res->end) { | |
| 1514 | + kfree(r); | |
| 1515 | 1515 | ret = -EINVAL; |
| 1516 | − dev_warn(dma_dev, "Can't handle multiple windows with different offsets\n"); | |
| 1516 | + dev_dbg(dma_dev, "Invalid DMA regions configuration\n"); | |
| 1517 | 1517 | goto out; |
| 1518 | 1518 | } |
| 1519 | − dma_offset = rentry->offset; | |
| 1520 | 1519 | |
| 1521 | − /* Take lower and upper limits */ | |
| 1522 | − if (rentry->res->start < dma_start) | |
| 1523 | − dma_start = rentry->res->start; | |
| 1524 | − if (rentry->res->end > dma_end) | |
| 1525 | − dma_end = rentry->res->end; | |
| 1526 | − } | |
| 1527 | − | |
| 1528 | − if (dma_start >= dma_end) { | |
| 1529 | − ret = -EINVAL; | |
| 1530 | − dev_dbg(dma_dev, "Invalid DMA regions configuration\n"); | |
| 1531 | − goto out; | |
| 1520 | + r->cpu_start = rentry->res->start; | |
| 1521 | + r->dma_start = rentry->res->start - rentry->offset; | |
| 1522 | + r->size = resource_size(rentry->res); | |
| 1523 | + r->offset = rentry->offset; | |
| 1524 | + r++; | |
| 1532 | 1525 | } |
| 1533 | 1526 | |
| 1534 | − *dma_addr = dma_start - dma_offset; | |
| 1535 | − len = dma_end - dma_start; | |
| 1536 | − *size = max(len, len + 1); | |
| 1537 | − *offset = dma_offset; | |
| 1527 | + *map = r; | |
| 1538 | 1528 | } |
| 1539 | 1529 | out: |
| 1540 | 1530 | acpi_dev_free_resource_list(&list); |
| @@ -1624,20 +1614,19 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr, · 83 unmodified lines | ||
| 1624 | 1614 | const u32 *input_id) |
| 1625 | 1615 | { |
| 1626 | 1616 | const struct iommu_ops *iommu; |
| 1627 | − u64 dma_addr = 0, size = 0; | |
| 1628 | 1617 | |
| 1629 | 1618 | if (attr == DEV_DMA_NOT_SUPPORTED) { |
| 1630 | 1619 | set_dma_ops(dev, &dma_dummy_ops); |
| 1631 | 1620 | return 0; |
| 1632 | 1621 | } |
| 1633 | 1622 | |
| 1634 | − acpi_arch_dma_setup(dev, &dma_addr, &size); | |
| 1623 | + acpi_arch_dma_setup(dev); | |
| 1635 | 1624 | |
| 1636 | 1625 | iommu = acpi_iommu_configure_id(dev, input_id); |
| 1637 | 1626 | if (PTR_ERR(iommu) == -EPROBE_DEFER) |
| 1638 | 1627 | return -EPROBE_DEFER; |
| 1639 | 1628 | |
| 1640 | − arch_setup_dma_ops(dev, dma_addr, size, | |
| 1629 | + arch_setup_dma_ops(dev, 0, U64_MAX, | |
| 1641 | 1630 | iommu, attr == DEV_DMA_COHERENT); |
| 1642 | 1631 | |
| 1643 | 1632 | return 0; |
| @@ -1648,7 +1637,7 @@ static void acpi_init_coherency(struct acpi_device *adev) · 4 unmodified lines | ||
| 1648 | 1637 | { |
| 1649 | 1638 | unsigned long long cca = 0; |
| 1650 | 1639 | acpi_status status; |
| 1651 | − struct acpi_device *parent = adev->parent; | |
| 1640 | + struct acpi_device *parent = acpi_dev_parent(adev); | |
| 1652 | 1641 | |
| 1653 | 1642 | if (parent && parent->flags.cca_seen) { |
| 1654 | 1643 | /* |
| @@ -1692,7 +1681,7 @@ static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data) · 37 unmodified lines | ||
| 1692 | 1681 | |
| 1693 | 1682 | static bool acpi_is_indirect_io_slave(struct acpi_device *device) |
| 1694 | 1683 | { |
| 1695 | − struct acpi_device *parent = device->parent; | |
| 1684 | + struct acpi_device *parent = acpi_dev_parent(device); | |
| 1696 | 1685 | static const struct acpi_device_id indirect_io_hosts[] = { |
| 1697 | 1686 | {"HISI0191", 0}, |
| 1698 | 1687 | {} |
| @@ -1762,12 +1751,16 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) · 63 unmodified lines | ||
| 1762 | 1751 | } |
| 1763 | 1752 | |
| 1764 | 1753 | void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, |
| 1765 | − int type) | |
| 1754 | + int type, void (*release)(struct device *)) | |
| 1766 | 1755 | { |
| 1756 | + struct acpi_device *parent = acpi_find_parent_acpi_dev(handle); | |
| 1757 | + | |
| 1767 | 1758 | INIT_LIST_HEAD(&device->pnp.ids); |
| 1768 | 1759 | device->device_type = type; |
| 1769 | 1760 | device->handle = handle; |
| 1770 | − device->parent = acpi_bus_get_parent(handle); | |
| 1761 | + device->dev.parent = parent ? &parent->dev : NULL; | |
| 1762 | + device->dev.release = release; | |
| 1763 | + device->dev.bus = &acpi_bus_type; | |
| 1771 | 1764 | fwnode_init(&device->fwnode, &acpi_device_fwnode_ops); |
| 1772 | 1765 | acpi_set_device_status(device, ACPI_STA_DEFAULT); |
| 1773 | 1766 | acpi_device_get_busid(device); |
| @@ -1821,7 +1814,7 @@ static int acpi_add_single_object(struct acpi_device **child, · 47 unmodified lines | ||
| 1821 | 1814 | if (!device) |
| 1822 | 1815 | return -ENOMEM; |
| 1823 | 1816 | |
| 1824 | − acpi_init_device_object(device, handle, type); | |
| 1817 | + acpi_init_device_object(device, handle, type, acpi_device_release); | |
| 1825 | 1818 | /* |
| 1826 | 1819 | * Getting the status is delayed till here so that we can call |
| 1827 | 1820 | * acpi_bus_get_status() and use its quirk handling. Note that |
| @@ -1851,7 +1844,7 @@ static int acpi_add_single_object(struct acpi_device **child, · 23 unmodified lines | ||
| 1851 | 1844 | mutex_unlock(&acpi_dep_list_lock); |
| 1852 | 1845 | |
| 1853 | 1846 | if (!result) |
| 1854 | − result = __acpi_device_add(device, acpi_device_release); | |
| 1847 | + result = acpi_device_add(device); | |
| 1855 | 1848 | |
| 1856 | 1849 | if (result) { |
| 1857 | 1850 | acpi_device_release(&device->dev); |
| @@ -1862,8 +1855,8 @@ static int acpi_add_single_object(struct acpi_device **child, · 4 unmodified lines | ||
| 1862 | 1855 | acpi_device_add_finalize(device); |
| 1863 | 1856 | |
| 1864 | 1857 | acpi_handle_debug(handle, "Added as %s, parent %s\n", |
| 1865 | − dev_name(&device->dev), device->parent ? | |
| 1866 | − dev_name(&device->parent->dev) : "(null)"); | |
| 1858 | + dev_name(&device->dev), device->dev.parent ? | |
| 1859 | + dev_name(device->dev.parent) : "(null)"); | |
| 1867 | 1860 | |
| 1868 | 1861 | *child = device; |
| 1869 | 1862 | return 0; |
| @@ -2235,11 +2228,24 @@ ok: · 365 unmodified lines | ||
| 2235 | 2228 | return 0; |
| 2236 | 2229 | } |
| 2237 | 2230 | |
| 2238 | −static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data) | |
| 2231 | +static int acpi_dev_get_next_consumer_dev_cb(struct acpi_dep_data *dep, void *data) | |
| 2239 | 2232 | { |
| 2240 | − struct acpi_device *adev; | |
| 2233 | + struct acpi_device **adev_p = data; | |
| 2234 | + struct acpi_device *adev = *adev_p; | |
| 2241 | 2235 | |
| 2242 | − adev = acpi_bus_get_acpi_device(dep->consumer); | |
| 2236 | + /* | |
| 2237 | + * If we're passed a 'previous' consumer device then we need to skip | |
| 2238 | + * any consumers until we meet the previous one, and then NULL @data | |
| 2239 | + * so the next one can be returned. | |
| 2240 | + */ | |
| 2241 | + if (adev) { | |
| 2242 | + if (dep->consumer == adev->handle) | |
| 2243 | + *adev_p = NULL; | |
| 2244 | + | |
| 2245 | + return 0; | |
| 2246 | + } | |
| 2247 | + | |
| 2248 | + adev = acpi_get_acpi_dev(dep->consumer); | |
| 2243 | 2249 | if (adev) { |
| 2244 | 2250 | *(struct acpi_device **)data = adev; |
| 2245 | 2251 | return 1; |
| @@ -2292,7 +2298,7 @@ static bool acpi_scan_clear_dep_queue(struct acpi_device *adev) · 46 unmodified lines | ||
| 2292 | 2298 | |
| 2293 | 2299 | static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data) |
| 2294 | 2300 | { |
| 2295 | − struct acpi_device *adev = acpi_bus_get_acpi_device(dep->consumer); | |
| 2301 | + struct acpi_device *adev = acpi_get_acpi_dev(dep->consumer); | |
| 2296 | 2302 | |
| 2297 | 2303 | if (adev) { |
| 2298 | 2304 | adev->dep_unmet--; |
| @@ -2368,25 +2374,32 @@ bool acpi_dev_ready_for_enumeration(const struct acpi_device *device) · 69 unmodified lines | ||
| 2368 | 2374 | EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration); |
| 2369 | 2375 | |
| 2370 | 2376 | /** |
| 2371 | − * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier | |
| 2377 | + * acpi_dev_get_next_consumer_dev - Return the next adev dependent on @supplier | |
| 2372 | 2378 | * @supplier: Pointer to the dependee device |
| 2379 | + * @start: Pointer to the current dependent device | |
| 2373 | 2380 | * |
| 2374 | − * Returns the first &struct acpi_device which declares itself dependent on | |
| 2381 | + * Returns the next &struct acpi_device which declares itself dependent on | |
| 2375 | 2382 | * @supplier via the _DEP buffer, parsed from the acpi_dep_list. |
| 2376 | 2383 | * |
| 2377 | − * The caller is responsible for putting the reference to adev when it is no | |
| 2378 | − * longer needed. | |
| 2384 | + * If the returned adev is not passed as @start to this function, the caller is | |
| 2385 | + * responsible for putting the reference to adev when it is no longer needed. | |
| 2379 | 2386 | */ |
| 2380 | −struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier) | |
| 2387 | +struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier, | |
| 2388 | + struct acpi_device *start) | |
| 2381 | 2389 | { |
| 2382 | − struct acpi_device *adev = NULL; | |
| 2390 | + struct acpi_device *adev = start; | |
| 2383 | 2391 | |
| 2384 | 2392 | acpi_walk_dep_device_list(supplier->handle, |
| 2385 | − acpi_dev_get_first_consumer_dev_cb, &adev); | |
| 2393 | + acpi_dev_get_next_consumer_dev_cb, &adev); | |
| 2394 | + | |
| 2395 | + acpi_dev_put(start); | |
| 2396 | + | |
| 2397 | + if (adev == start) | |
| 2398 | + return NULL; | |
| 2386 | 2399 | |
| 2387 | 2400 | return adev; |
| 2388 | 2401 | } |
| 2389 | −EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev); | |
| 2402 | +EXPORT_SYMBOL_GPL(acpi_dev_get_next_consumer_dev); | |
| 2390 | 2403 | |
| 2391 | 2404 | /** |
| 2392 | 2405 | * acpi_bus_scan - Add ACPI device node objects in a given namespace scope. |
| @@ -793,6 +793,30 @@ bool acpi_dev_hid_uid_match(struct acpi_device *adev, · 792 unmodified lines | ||
| 793 | 793 | } |
| 794 | 794 | EXPORT_SYMBOL(acpi_dev_hid_uid_match); |
| 795 | 795 | |
| 796 | +/** | |
| 797 | + * acpi_dev_uid_to_integer - treat ACPI device _UID as integer | |
| 798 | + * @adev: ACPI device to get _UID from | |
| 799 | + * @integer: output buffer for integer | |
| 800 | + * | |
| 801 | + * Considers _UID as integer and converts it to @integer. | |
| 802 | + * | |
| 803 | + * Returns 0 on success, or negative error code otherwise. | |
| 804 | + */ | |
| 805 | +int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer) | |
| 806 | +{ | |
| 807 | + const char *uid; | |
| 808 | + | |
| 809 | + if (!adev) | |
| 810 | + return -ENODEV; | |
| 811 | + | |
| 812 | + uid = acpi_device_uid(adev); | |
| 813 | + if (!uid) | |
| 814 | + return -ENODATA; | |
| 815 | + | |
| 816 | + return kstrtou64(uid, 0, integer); | |
| 817 | +} | |
| 818 | +EXPORT_SYMBOL(acpi_dev_uid_to_integer); | |
| 819 | + | |
| 796 | 820 | /** |
| 797 | 821 | * acpi_dev_found - Detect presence of a given ACPI device in the namespace. |
| 798 | 822 | * @hid: Hardware ID of the device. |
| @@ -878,7 +902,7 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) · 79 unmodified lines | ||
| 878 | 902 | struct acpi_dev_match_info match = {}; |
| 879 | 903 | struct device *dev; |
| 880 | 904 | |
| 881 | − strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | |
| 905 | + strscpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | |
| 882 | 906 | match.uid = uid; |
| 883 | 907 | match.hrv = hrv; |
| 884 | 908 | |
| @@ -911,7 +935,7 @@ acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const cha · 26 unmodified lines | ||
| 911 | 935 | struct acpi_dev_match_info match = {}; |
| 912 | 936 | struct device *dev; |
| 913 | 937 | |
| 914 | − strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | |
| 938 | + strscpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | |
| 915 | 939 | match.uid = uid; |
| 916 | 940 | match.hrv = hrv; |
| 917 | 941 | |
| @@ -961,7 +985,7 @@ EXPORT_SYMBOL(acpi_video_backlight_string); · 43 unmodified lines | ||
| 961 | 985 | |
| 962 | 986 | static int __init acpi_backlight(char *str) |
| 963 | 987 | { |
| 964 | − strlcpy(acpi_video_backlight_string, str, | |
| 988 | + strscpy(acpi_video_backlight_string, str, | |
| 965 | 989 | sizeof(acpi_video_backlight_string)); |
| 966 | 990 | return 1; |
| 967 | 991 | } |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/bitmap.h> |
| 9 | 9 | #include <linux/platform_data/x86/apple.h> |
| 10 | 10 | #include <linux/uuid.h> |
| 11 | +#include "../internal.h" | |
| 11 | 12 | |
| 12 | 13 | /* Apple _DSM device properties GUID */ |
| 13 | 14 | static const guid_t apple_prp_guid = |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #include <linux/acpi.h> |
| 19 | 19 | #include <linux/device.h> |
| 20 | +#include <linux/dmi.h> | |
| 20 | 21 | #include <linux/suspend.h> |
| 21 | 22 | |
| 22 | 23 | #include "../sleep.h" |
| @@ -27,6 +28,10 @@ static bool sleep_no_lps0 __read_mostly; · 4 unmodified lines | ||
| 27 | 28 | module_param(sleep_no_lps0, bool, 0644); |
| 28 | 29 | MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface"); |
| 29 | 30 | |
| 31 | +static bool prefer_microsoft_dsm_guid __read_mostly; | |
| 32 | +module_param(prefer_microsoft_dsm_guid, bool, 0644); | |
| 33 | +MODULE_PARM_DESC(prefer_microsoft_dsm_guid, "Prefer using Microsoft GUID in LPS0 device _DSM evaluation"); | |
| 34 | + | |
| 30 | 35 | static const struct acpi_device_id lps0_device_ids[] = { |
| 31 | 36 | {"PNP0D80", }, |
| 32 | 37 | {"", }, |
| @@ -363,40 +368,132 @@ out: · 330 unmodified lines | ||
| 363 | 368 | return ret; |
| 364 | 369 | } |
| 365 | 370 | |
| 371 | +struct amd_lps0_hid_device_data { | |
| 372 | + const unsigned int rev_id; | |
| 373 | + const bool check_off_by_one; | |
| 374 | + const bool prefer_amd_guid; | |
| 375 | +}; | |
| 376 | + | |
| 377 | +static const struct amd_lps0_hid_device_data amd_picasso = { | |
| 378 | + .rev_id = 0, | |
| 379 | + .check_off_by_one = true, | |
| 380 | + .prefer_amd_guid = false, | |
| 381 | +}; | |
| 382 | + | |
| 383 | +static const struct amd_lps0_hid_device_data amd_cezanne = { | |
| 384 | + .rev_id = 0, | |
| 385 | + .check_off_by_one = false, | |
| 386 | + .prefer_amd_guid = false, | |
| 387 | +}; | |
| 388 | + | |
| 389 | +static const struct amd_lps0_hid_device_data amd_rembrandt = { | |
| 390 | + .rev_id = 2, | |
| 391 | + .check_off_by_one = false, | |
| 392 | + .prefer_amd_guid = true, | |
| 393 | +}; | |
| 394 | + | |
| 395 | +static const struct acpi_device_id amd_hid_ids[] = { | |
| 396 | + {"AMD0004", (kernel_ulong_t)&amd_picasso, }, | |
| 397 | + {"AMD0005", (kernel_ulong_t)&amd_picasso, }, | |
| 398 | + {"AMDI0005", (kernel_ulong_t)&amd_picasso, }, | |
| 399 | + {"AMDI0006", (kernel_ulong_t)&amd_cezanne, }, | |
| 400 | + {"AMDI0007", (kernel_ulong_t)&amd_rembrandt, }, | |
| 401 | + {} | |
| 402 | +}; | |
| 403 | + | |
| 404 | +static int lps0_prefer_microsoft(const struct dmi_system_id *id) | |
| 405 | +{ | |
| 406 | + pr_debug("Preferring Microsoft GUID.\n"); | |
| 407 | + prefer_microsoft_dsm_guid = true; | |
| 408 | + return 0; | |
| 409 | +} | |
| 410 | + | |
| 411 | +static const struct dmi_system_id s2idle_dmi_table[] __initconst = { | |
| 412 | + { | |
| 413 | + /* | |
| 414 | + * ASUS TUF Gaming A17 FA707RE | |
| 415 | + * https://bugzilla.kernel.org/show_bug.cgi?id=216101 | |
| 416 | + */ | |
| 417 | + .callback = lps0_prefer_microsoft, | |
| 418 | + .matches = { | |
| 419 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 420 | + DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Gaming A17"), | |
| 421 | + }, | |
| 422 | + }, | |
| 423 | + { | |
| 424 | + /* ASUS ROG Zephyrus G14 (2022) */ | |
| 425 | + .callback = lps0_prefer_microsoft, | |
| 426 | + .matches = { | |
| 427 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 428 | + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus G14 GA402"), | |
| 429 | + }, | |
| 430 | + }, | |
| 431 | + { | |
| 432 | + /* | |
| 433 | + * Lenovo Yoga Slim 7 Pro X 14ARH7 | |
| 434 | + * https://bugzilla.kernel.org/show_bug.cgi?id=216473 : 82V2 | |
| 435 | + * https://bugzilla.kernel.org/show_bug.cgi?id=216438 : 82TL | |
| 436 | + */ | |
| 437 | + .callback = lps0_prefer_microsoft, | |
| 438 | + .matches = { | |
| 439 | + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | |
| 440 | + DMI_MATCH(DMI_PRODUCT_NAME, "82"), | |
| 441 | + }, | |
| 442 | + }, | |
| 443 | + { | |
| 444 | + /* | |
| 445 | + * ASUSTeK COMPUTER INC. ROG Flow X13 GV301RE_GV301RE | |
| 446 | + * https://gitlab.freedesktop.org/drm/amd/-/issues/2148 | |
| 447 | + */ | |
| 448 | + .callback = lps0_prefer_microsoft, | |
| 449 | + .matches = { | |
| 450 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 451 | + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X13 GV301"), | |
| 452 | + }, | |
| 453 | + }, | |
| 454 | + { | |
| 455 | + /* | |
| 456 | + * ASUSTeK COMPUTER INC. ROG Flow X16 GV601RW_GV601RW | |
| 457 | + * https://gitlab.freedesktop.org/drm/amd/-/issues/2148 | |
| 458 | + */ | |
| 459 | + .callback = lps0_prefer_microsoft, | |
| 460 | + .matches = { | |
| 461 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 462 | + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X16 GV601"), | |
| 463 | + }, | |
| 464 | + }, | |
| 465 | + {} | |
| 466 | +}; | |
| 467 | + | |
| 366 | 468 | static int lps0_device_attach(struct acpi_device *adev, |
| 367 | 469 | const struct acpi_device_id *not_used) |
| 368 | 470 | { |
| 369 | 471 | if (lps0_device_handle) |
| 370 | 472 | return 0; |
| 371 | 473 | |
| 474 | + lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, | |
| 475 | + ACPI_LPS0_DSM_UUID_MICROSOFT, 0, | |
| 476 | + &lps0_dsm_guid_microsoft); | |
| 372 | 477 | if (acpi_s2idle_vendor_amd()) { |
| 373 | − /* AMD0004, AMD0005, AMDI0005: | |
| 374 | − * - Should use rev_id 0x0 | |
| 375 | − * - function mask > 0x3: Should use AMD method, but has off by one bug | |
| 376 | − * - function mask = 0x3: Should use Microsoft method | |
| 377 | − * AMDI0006: | |
| 378 | − * - should use rev_id 0x0 | |
| 379 | − * - function mask = 0x3: Should use Microsoft method | |
| 380 | − * AMDI0007: | |
| 381 | − * - Should use rev_id 0x2 | |
| 382 | − * - Should only use AMD method | |
| 383 | − */ | |
| 384 | − const char *hid = acpi_device_hid(adev); | |
| 385 | − rev_id = strcmp(hid, "AMDI0007") ? 0 : 2; | |
| 478 | + static const struct acpi_device_id *dev_id; | |
| 479 | + const struct amd_lps0_hid_device_data *data; | |
| 480 | + | |
| 481 | + for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++) | |
| 482 | + if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL)) | |
| 483 | + break; | |
| 484 | + if (dev_id->id[0]) | |
| 485 | + data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data; | |
| 486 | + else | |
| 487 | + data = &amd_rembrandt; | |
| 488 | + rev_id = data->rev_id; | |
| 386 | 489 | lps0_dsm_func_mask = validate_dsm(adev->handle, |
| 387 | 490 | ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); |
| 388 | − lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, | |
| 389 | − ACPI_LPS0_DSM_UUID_MICROSOFT, 0, | |
| 390 | − &lps0_dsm_guid_microsoft); | |
| 391 | − if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") || | |
| 392 | − !strcmp(hid, "AMD0005") || | |
| 393 | − !strcmp(hid, "AMDI0005"))) { | |
| 491 | + if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) { | |
| 394 | 492 | lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; |
| 395 | 493 | acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", |
| 396 | 494 | ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); |
| 397 | − } else if (lps0_dsm_func_mask_microsoft > 0 && | |
| 398 | − (!strcmp(hid, "AMDI0007") || | |
| 399 | − !strcmp(hid, "AMDI0008"))) { | |
| 495 | + } else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid && | |
| 496 | + !prefer_microsoft_dsm_guid) { | |
| 400 | 497 | lps0_dsm_func_mask_microsoft = -EINVAL; |
| 401 | 498 | acpi_handle_debug(adev->handle, "_DSM Using AMD method\n"); |
| 402 | 499 | } |
| @@ -404,7 +501,8 @@ static int lps0_device_attach(struct acpi_device *adev, · 1 unmodified line | ||
| 404 | 501 | rev_id = 1; |
| 405 | 502 | lps0_dsm_func_mask = validate_dsm(adev->handle, |
| 406 | 503 | ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid); |
| 407 | − lps0_dsm_func_mask_microsoft = -EINVAL; | |
| 504 | + if (!prefer_microsoft_dsm_guid) | |
| 505 | + lps0_dsm_func_mask_microsoft = -EINVAL; | |
| 408 | 506 | } |
| 409 | 507 | |
| 410 | 508 | if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0) |
| @@ -533,8 +631,9 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { · 122 unmodified lines | ||
| 533 | 631 | .end = acpi_s2idle_end, |
| 534 | 632 | }; |
| 535 | 633 | |
| 536 | −void acpi_s2idle_setup(void) | |
| 634 | +void __init acpi_s2idle_setup(void) | |
| 537 | 635 | { |
| 636 | + dmi_check_system(s2idle_dmi_table); | |
| 538 | 637 | acpi_scan_add_handler(&lps0_handler); |
| 539 | 638 | s2idle_set_ops(&acpi_s2idle_ops_lps0); |
| 540 | 639 | } |
| @@ -207,9 +207,26 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = { · 206 unmodified lines | ||
| 207 | 207 | {} |
| 208 | 208 | }; |
| 209 | 209 | |
| 210 | +static const struct dmi_system_id force_storage_d3_dmi[] = { | |
| 211 | + { | |
| 212 | + /* | |
| 213 | + * _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME | |
| 214 | + * but .NVME is needed to get StorageD3Enable node | |
| 215 | + * https://bugzilla.kernel.org/show_bug.cgi?id=216440 | |
| 216 | + */ | |
| 217 | + .matches = { | |
| 218 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 219 | + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"), | |
| 220 | + } | |
| 221 | + }, | |
| 222 | + {} | |
| 223 | +}; | |
| 224 | + | |
| 210 | 225 | bool force_storage_d3(void) |
| 211 | 226 | { |
| 212 | − return x86_match_cpu(storage_d3_cpu_ids); | |
| 227 | + const struct dmi_system_id *dmi_id = dmi_first_match(force_storage_d3_dmi); | |
| 228 | + | |
| 229 | + return dmi_id || x86_match_cpu(storage_d3_cpu_ids); | |
| 213 | 230 | } |
| 214 | 231 | |
| 215 | 232 | /* |
| @@ -351,11 +368,17 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s · 135 unmodified lines | ||
| 351 | 368 | struct acpi_device *adev = ACPI_COMPANION(controller_parent); |
| 352 | 369 | const struct dmi_system_id *dmi_id; |
| 353 | 370 | long quirks = 0; |
| 371 | + u64 uid; | |
| 372 | + int ret; | |
| 354 | 373 | |
| 355 | 374 | *skip = false; |
| 356 | 375 | |
| 357 | − /* !dev_is_platform() to not match on PNP enumerated debug UARTs */ | |
| 358 | − if (!adev || !adev->pnp.unique_id || !dev_is_platform(controller_parent)) | |
| 376 | + ret = acpi_dev_uid_to_integer(adev, &uid); | |
| 377 | + if (ret) | |
| 378 | + return 0; | |
| 379 | + | |
| 380 | + /* to not match on PNP enumerated debug UARTs */ | |
| 381 | + if (!dev_is_platform(controller_parent)) | |
| 359 | 382 | return 0; |
| 360 | 383 | |
| 361 | 384 | dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); |
| @@ -363,10 +386,10 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s · 1 unmodified line | ||
| 363 | 386 | quirks = (unsigned long)dmi_id->driver_data; |
| 364 | 387 | |
| 365 | 388 | if (quirks & ACPI_QUIRK_UART1_TTY_UART2_SKIP) { |
| 366 | − if (!strcmp(adev->pnp.unique_id, "1")) | |
| 389 | + if (uid == 1) | |
| 367 | 390 | return -ENODEV; /* Create tty cdev instead of serdev */ |
| 368 | 391 | |
| 369 | − if (!strcmp(adev->pnp.unique_id, "2")) | |
| 392 | + if (uid == 2) | |
| 370 | 393 | *skip = true; |
| 371 | 394 | } |
| 372 | 395 | |
| @@ -327,7 +327,7 @@ static int read_adc_sum(void *dev, u16 rtune_ctl_reg, void __iomem * mmio) · 326 unmodified lines | ||
| 327 | 327 | } |
| 328 | 328 | |
| 329 | 329 | /* SATA AHCI temperature monitor */ |
| 330 | −static int sata_ahci_read_temperature(void *dev, int *temp) | |
| 330 | +static int __sata_ahci_read_temperature(void *dev, int *temp) | |
| 331 | 331 | { |
| 332 | 332 | u16 mpll_test_reg, rtune_ctl_reg, dac_ctl_reg, read_sum; |
| 333 | 333 | u32 str1, str2, str3, str4; |
| @@ -416,6 +416,11 @@ static int sata_ahci_read_temperature(void *dev, int *temp) · 82 unmodified lines | ||
| 416 | 416 | return 0; |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | +static int sata_ahci_read_temperature(struct thermal_zone_device *tz, int *temp) | |
| 420 | +{ | |
| 421 | + return __sata_ahci_read_temperature(tz->devdata, temp); | |
| 422 | +} | |
| 423 | + | |
| 419 | 424 | static ssize_t sata_ahci_show_temp(struct device *dev, |
| 420 | 425 | struct device_attribute *da, |
| 421 | 426 | char *buf) |
| @@ -423,14 +428,14 @@ static ssize_t sata_ahci_show_temp(struct device *dev, · 1 unmodified line | ||
| 423 | 428 | unsigned int temp = 0; |
| 424 | 429 | int err; |
| 425 | 430 | |
| 426 | − err = sata_ahci_read_temperature(dev, &temp); | |
| 431 | + err = __sata_ahci_read_temperature(dev, &temp); | |
| 427 | 432 | if (err < 0) |
| 428 | 433 | return err; |
| 429 | 434 | |
| 430 | 435 | return sprintf(buf, "%u\n", temp); |
| 431 | 436 | } |
| 432 | 437 | |
| 433 | −static const struct thermal_zone_of_device_ops fsl_sata_ahci_of_thermal_ops = { | |
| 438 | +static const struct thermal_zone_device_ops fsl_sata_ahci_of_thermal_ops = { | |
| 434 | 439 | .get_temp = sata_ahci_read_temperature, |
| 435 | 440 | }; |
| 436 | 441 | |
| @@ -1131,8 +1136,8 @@ static int imx_ahci_probe(struct platform_device *pdev) · 694 unmodified lines | ||
| 1131 | 1136 | ret = PTR_ERR(hwmon_dev); |
| 1132 | 1137 | goto disable_clk; |
| 1133 | 1138 | } |
| 1134 | − devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, | |
| 1135 | − &fsl_sata_ahci_of_thermal_ops); | |
| 1139 | + devm_thermal_of_zone_register(hwmon_dev, 0, hwmon_dev, | |
| 1140 | + &fsl_sata_ahci_of_thermal_ops); | |
| 1136 | 1141 | dev_info(dev, "%s: sensor 'sata_ahci'\n", dev_name(hwmon_dev)); |
| 1137 | 1142 | } |
| 1138 | 1143 | |
| @@ -353,7 +353,7 @@ void topology_init_cpu_capacity_cppc(void) · 352 unmodified lines | ||
| 353 | 353 | struct cppc_perf_caps perf_caps; |
| 354 | 354 | int cpu; |
| 355 | 355 | |
| 356 | − if (likely(acpi_disabled || !acpi_cpc_valid())) | |
| 356 | + if (likely(!acpi_cpc_valid())) | |
| 357 | 357 | return; |
| 358 | 358 | |
| 359 | 359 | raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity), |
| @@ -792,10 +792,13 @@ static int rpm_resume(struct device *dev, int rpmflags) · 791 unmodified lines | ||
| 792 | 792 | DEFINE_WAIT(wait); |
| 793 | 793 | |
| 794 | 794 | if (rpmflags & (RPM_ASYNC | RPM_NOWAIT)) { |
| 795 | − if (dev->power.runtime_status == RPM_SUSPENDING) | |
| 795 | + if (dev->power.runtime_status == RPM_SUSPENDING) { | |
| 796 | 796 | dev->power.deferred_resume = true; |
| 797 | − else | |
| 797 | + if (rpmflags & RPM_NOWAIT) | |
| 798 | + retval = -EINPROGRESS; | |
| 799 | + } else { | |
| 798 | 800 | retval = -EINPROGRESS; |
| 801 | + } | |
| 799 | 802 | goto out; |
| 800 | 803 | } |
| 801 | 804 | |
| @@ -944,6 +944,8 @@ void pm_system_irq_wakeup(unsigned int irq_number) · 943 unmodified lines | ||
| 944 | 944 | else |
| 945 | 945 | irq_number = 0; |
| 946 | 946 | |
| 947 | + pm_pr_dbg("Triggering wakeup from IRQ %d\n", irq_number); | |
| 948 | + | |
| 947 | 949 | raw_spin_unlock_irqrestore(&wakeup_irq_lock, flags); |
| 948 | 950 | |
| 949 | 951 | if (irq_number) |
| @@ -322,14 +322,14 @@ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx, · 321 unmodified lines | ||
| 322 | 322 | if (unlikely(status)) |
| 323 | 323 | return status; |
| 324 | 324 | |
| 325 | − blk_mq_start_request(req); | |
| 326 | − | |
| 327 | 325 | vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr); |
| 328 | 326 | if (unlikely(vbr->sg_table.nents < 0)) { |
| 329 | 327 | virtblk_cleanup_cmd(req); |
| 330 | 328 | return BLK_STS_RESOURCE; |
| 331 | 329 | } |
| 332 | 330 | |
| 331 | + blk_mq_start_request(req); | |
| 332 | + | |
| 333 | 333 | return BLK_STS_OK; |
| 334 | 334 | } |
| 335 | 335 | |
| @@ -391,8 +391,7 @@ static bool virtblk_prep_rq_batch(struct request *req) · 55 unmodified lines | ||
| 391 | 391 | } |
| 392 | 392 | |
| 393 | 393 | static bool virtblk_add_req_batch(struct virtio_blk_vq *vq, |
| 394 | − struct request **rqlist, | |
| 395 | − struct request **requeue_list) | |
| 394 | + struct request **rqlist) | |
| 396 | 395 | { |
| 397 | 396 | unsigned long flags; |
| 398 | 397 | int err; |
| @@ -408,7 +407,7 @@ static bool virtblk_add_req_batch(struct virtio_blk_vq *vq, · 9 unmodified lines | ||
| 408 | 407 | if (err) { |
| 409 | 408 | virtblk_unmap_data(req, vbr); |
| 410 | 409 | virtblk_cleanup_cmd(req); |
| 411 | − rq_list_add(requeue_list, req); | |
| 410 | + blk_mq_requeue_request(req, true); | |
| 412 | 411 | } |
| 413 | 412 | } |
| 414 | 413 | |
| @@ -436,7 +435,7 @@ static void virtio_queue_rqs(struct request **rqlist) · 21 unmodified lines | ||
| 436 | 435 | |
| 437 | 436 | if (!next || req->mq_hctx != next->mq_hctx) { |
| 438 | 437 | req->rq_next = NULL; |
| 439 | − kick = virtblk_add_req_batch(vq, rqlist, &requeue_list); | |
| 438 | + kick = virtblk_add_req_batch(vq, rqlist); | |
| 440 | 439 | if (kick) |
| 441 | 440 | virtqueue_notify(vq->vq); |
| 442 | 441 | |
| @@ -449,6 +449,7 @@ static int btintel_version_info_tlv(struct hci_dev *hdev, · 448 unmodified lines | ||
| 449 | 449 | case 0x17: /* TyP */ |
| 450 | 450 | case 0x18: /* Slr */ |
| 451 | 451 | case 0x19: /* Slr-F */ |
| 452 | + case 0x1b: /* Mgr */ | |
| 452 | 453 | break; |
| 453 | 454 | default: |
| 454 | 455 | bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)", |
| @@ -2330,6 +2331,7 @@ static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant) · 1875 unmodified lines | ||
| 2330 | 2331 | case 0x17: |
| 2331 | 2332 | case 0x18: |
| 2332 | 2333 | case 0x19: |
| 2334 | + case 0x1b: | |
| 2333 | 2335 | hci_set_msft_opcode(hdev, 0xFC1E); |
| 2334 | 2336 | break; |
| 2335 | 2337 | default: |
| @@ -2439,15 +2441,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) · 103 unmodified lines | ||
| 2439 | 2441 | INTEL_ROM_LEGACY_NO_WBS_SUPPORT)) |
| 2440 | 2442 | set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, |
| 2441 | 2443 | &hdev->quirks); |
| 2444 | + if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22) | |
| 2445 | + set_bit(HCI_QUIRK_VALID_LE_STATES, | |
| 2446 | + &hdev->quirks); | |
| 2442 | 2447 | |
| 2443 | 2448 | err = btintel_legacy_rom_setup(hdev, &ver); |
| 2444 | 2449 | break; |
| 2445 | 2450 | case 0x0b: /* SfP */ |
| 2446 | − case 0x0c: /* WsP */ | |
| 2447 | 2451 | case 0x11: /* JfP */ |
| 2448 | 2452 | case 0x12: /* ThP */ |
| 2449 | 2453 | case 0x13: /* HrP */ |
| 2450 | 2454 | case 0x14: /* CcP */ |
| 2455 | + set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); | |
| 2456 | + fallthrough; | |
| 2457 | + case 0x0c: /* WsP */ | |
| 2451 | 2458 | /* Apply the device specific HCI quirks |
| 2452 | 2459 | * |
| 2453 | 2460 | * All Legacy bootloader devices support WBS |
| @@ -2455,11 +2462,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) · 1 unmodified line | ||
| 2455 | 2462 | set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, |
| 2456 | 2463 | &hdev->quirks); |
| 2457 | 2464 | |
| 2458 | − /* Valid LE States quirk for JfP/ThP familiy */ | |
| 2459 | − if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12) | |
| 2460 | − set_bit(HCI_QUIRK_VALID_LE_STATES, | |
| 2461 | − &hdev->quirks); | |
| 2462 | − | |
| 2463 | 2465 | /* Setup MSFT Extension support */ |
| 2464 | 2466 | btintel_set_msft_opcode(hdev, ver.hw_variant); |
| 2465 | 2467 | |
| @@ -2530,9 +2532,8 @@ static int btintel_setup_combined(struct hci_dev *hdev) · 64 unmodified lines | ||
| 2530 | 2532 | */ |
| 2531 | 2533 | set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); |
| 2532 | 2534 | |
| 2533 | − /* Valid LE States quirk for JfP/ThP familiy */ | |
| 2534 | − if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12) | |
| 2535 | − set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); | |
| 2535 | + /* Set Valid LE States quirk */ | |
| 2536 | + set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); | |
| 2536 | 2537 | |
| 2537 | 2538 | /* Setup MSFT Extension support */ |
| 2538 | 2539 | btintel_set_msft_opcode(hdev, ver.hw_variant); |
| @@ -2542,6 +2543,7 @@ static int btintel_setup_combined(struct hci_dev *hdev) · 3 unmodified lines | ||
| 2542 | 2543 | case 0x17: |
| 2543 | 2544 | case 0x18: |
| 2544 | 2545 | case 0x19: |
| 2546 | + case 0x1b: | |
| 2545 | 2547 | /* Display version information of TLV type */ |
| 2546 | 2548 | btintel_version_info_tlv(hdev, &ver_tlv); |
| 2547 | 2549 | |
| @@ -426,6 +426,8 @@ static const struct usb_device_id blacklist_table[] = { · 425 unmodified lines | ||
| 426 | 426 | BTUSB_WIDEBAND_SPEECH }, |
| 427 | 427 | { USB_DEVICE(0x04ca, 0x4006), .driver_info = BTUSB_REALTEK | |
| 428 | 428 | BTUSB_WIDEBAND_SPEECH }, |
| 429 | + { USB_DEVICE(0x0cb8, 0xc549), .driver_info = BTUSB_REALTEK | | |
| 430 | + BTUSB_WIDEBAND_SPEECH }, | |
| 429 | 431 | |
| 430 | 432 | /* Realtek 8852CE Bluetooth devices */ |
| 431 | 433 | { USB_DEVICE(0x04ca, 0x4007), .driver_info = BTUSB_REALTEK | |
| @@ -438,6 +440,8 @@ static const struct usb_device_id blacklist_table[] = { · 6 unmodified lines | ||
| 438 | 440 | BTUSB_WIDEBAND_SPEECH }, |
| 439 | 441 | { USB_DEVICE(0x13d3, 0x3586), .driver_info = BTUSB_REALTEK | |
| 440 | 442 | BTUSB_WIDEBAND_SPEECH }, |
| 443 | + { USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK | | |
| 444 | + BTUSB_WIDEBAND_SPEECH }, | |
| 441 | 445 | |
| 442 | 446 | /* Realtek Bluetooth devices */ |
| 443 | 447 | { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), |
| @@ -466,6 +470,9 @@ static const struct usb_device_id blacklist_table[] = { · 22 unmodified lines | ||
| 466 | 470 | { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK | |
| 467 | 471 | BTUSB_WIDEBAND_SPEECH | |
| 468 | 472 | BTUSB_VALID_LE_STATES }, |
| 473 | + { USB_DEVICE(0x0489, 0xe0e0), .driver_info = BTUSB_MEDIATEK | | |
| 474 | + BTUSB_WIDEBAND_SPEECH | | |
| 475 | + BTUSB_VALID_LE_STATES }, | |
| 469 | 476 | { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK | |
| 470 | 477 | BTUSB_WIDEBAND_SPEECH | |
| 471 | 478 | BTUSB_VALID_LE_STATES }, |
| @@ -478,9 +485,18 @@ static const struct usb_device_id blacklist_table[] = { · 6 unmodified lines | ||
| 478 | 485 | { USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK | |
| 479 | 486 | BTUSB_WIDEBAND_SPEECH | |
| 480 | 487 | BTUSB_VALID_LE_STATES }, |
| 488 | + { USB_DEVICE(0x13d3, 0x3578), .driver_info = BTUSB_MEDIATEK | | |
| 489 | + BTUSB_WIDEBAND_SPEECH | | |
| 490 | + BTUSB_VALID_LE_STATES }, | |
| 491 | + { USB_DEVICE(0x13d3, 0x3583), .driver_info = BTUSB_MEDIATEK | | |
| 492 | + BTUSB_WIDEBAND_SPEECH | | |
| 493 | + BTUSB_VALID_LE_STATES }, | |
| 481 | 494 | { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | |
| 482 | 495 | BTUSB_WIDEBAND_SPEECH | |
| 483 | 496 | BTUSB_VALID_LE_STATES }, |
| 497 | + { USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK | | |
| 498 | + BTUSB_WIDEBAND_SPEECH | | |
| 499 | + BTUSB_VALID_LE_STATES }, | |
| 484 | 500 | |
| 485 | 501 | /* MediaTek MT7922A Bluetooth devices */ |
| 486 | 502 | { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | |
| @@ -516,19 +532,17 @@ static const struct usb_device_id blacklist_table[] = { · 29 unmodified lines | ||
| 516 | 532 | { USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK }, |
| 517 | 533 | { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK }, |
| 518 | 534 | |
| 519 | − /* Additional Realtek 8761B Bluetooth devices */ | |
| 535 | + /* Additional Realtek 8761BUV Bluetooth devices */ | |
| 520 | 536 | { USB_DEVICE(0x2357, 0x0604), .driver_info = BTUSB_REALTEK | |
| 521 | 537 | BTUSB_WIDEBAND_SPEECH }, |
| 522 | − | |
| 523 | − /* Additional Realtek 8761BU Bluetooth devices */ | |
| 524 | 538 | { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK | |
| 525 | 539 | BTUSB_WIDEBAND_SPEECH }, |
| 526 | 540 | { USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK | |
| 527 | 541 | BTUSB_WIDEBAND_SPEECH }, |
| 528 | − | |
| 529 | − /* Additional Realtek 8761BUV Bluetooth devices */ | |
| 530 | 542 | { USB_DEVICE(0x0bda, 0x8771), .driver_info = BTUSB_REALTEK | |
| 531 | 543 | BTUSB_WIDEBAND_SPEECH }, |
| 544 | + { USB_DEVICE(0x7392, 0xc611), .driver_info = BTUSB_REALTEK | | |
| 545 | + BTUSB_WIDEBAND_SPEECH }, | |
| 532 | 546 | |
| 533 | 547 | /* Additional Realtek 8821AE Bluetooth devices */ |
| 534 | 548 | { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, |
| @@ -2477,15 +2491,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, · 1942 unmodified lines | ||
| 2477 | 2491 | |
| 2478 | 2492 | set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); |
| 2479 | 2493 | |
| 2494 | + /* WMT cmd/event doesn't follow up the generic HCI cmd/event handling, | |
| 2495 | + * it needs constantly polling control pipe until the host received the | |
| 2496 | + * WMT event, thus, we should require to specifically acquire PM counter | |
| 2497 | + * on the USB to prevent the interface from entering auto suspended | |
| 2498 | + * while WMT cmd/event in progress. | |
| 2499 | + */ | |
| 2500 | + err = usb_autopm_get_interface(data->intf); | |
| 2501 | + if (err < 0) | |
| 2502 | + goto err_free_wc; | |
| 2503 | + | |
| 2480 | 2504 | err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); |
| 2481 | 2505 | |
| 2482 | 2506 | if (err < 0) { |
| 2483 | 2507 | clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); |
| 2508 | + usb_autopm_put_interface(data->intf); | |
| 2484 | 2509 | goto err_free_wc; |
| 2485 | 2510 | } |
| 2486 | 2511 | |
| 2487 | 2512 | /* Submit control IN URB on demand to process the WMT event */ |
| 2488 | 2513 | err = btusb_mtk_submit_wmt_recv_urb(hdev); |
| 2514 | + | |
| 2515 | + usb_autopm_put_interface(data->intf); | |
| 2516 | + | |
| 2489 | 2517 | if (err < 0) |
| 2490 | 2518 | goto err_free_wc; |
| 2491 | 2519 | |
| @@ -493,6 +493,11 @@ static int hci_uart_tty_open(struct tty_struct *tty) · 492 unmodified lines | ||
| 493 | 493 | BT_ERR("Can't allocate control structure"); |
| 494 | 494 | return -ENFILE; |
| 495 | 495 | } |
| 496 | + if (percpu_init_rwsem(&hu->proto_lock)) { | |
| 497 | + BT_ERR("Can't allocate semaphore structure"); | |
| 498 | + kfree(hu); | |
| 499 | + return -ENOMEM; | |
| 500 | + } | |
| 496 | 501 | |
| 497 | 502 | tty->disc_data = hu; |
| 498 | 503 | hu->tty = tty; |
| @@ -505,8 +510,6 @@ static int hci_uart_tty_open(struct tty_struct *tty) · 6 unmodified lines | ||
| 505 | 510 | INIT_WORK(&hu->init_ready, hci_uart_init_work); |
| 506 | 511 | INIT_WORK(&hu->write_work, hci_uart_write_work); |
| 507 | 512 | |
| 508 | − percpu_init_rwsem(&hu->proto_lock); | |
| 509 | − | |
| 510 | 513 | /* Flush any pending characters in the driver */ |
| 511 | 514 | tty_driver_flush_buffer(tty); |
| 512 | 515 | |
| @@ -310,11 +310,12 @@ int hci_uart_register_device(struct hci_uart *hu, · 309 unmodified lines | ||
| 310 | 310 | |
| 311 | 311 | serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops); |
| 312 | 312 | |
| 313 | + if (percpu_init_rwsem(&hu->proto_lock)) | |
| 314 | + return -ENOMEM; | |
| 315 | + | |
| 313 | 316 | err = serdev_device_open(hu->serdev); |
| 314 | 317 | if (err) |
| 315 | − return err; | |
| 316 | − | |
| 317 | − percpu_init_rwsem(&hu->proto_lock); | |
| 318 | + goto err_rwsem; | |
| 318 | 319 | |
| 319 | 320 | err = p->open(hu); |
| 320 | 321 | if (err) |
| @@ -389,6 +390,8 @@ err_alloc: · 68 unmodified lines | ||
| 389 | 390 | p->close(hu); |
| 390 | 391 | err_open: |
| 391 | 392 | serdev_device_close(hu->serdev); |
| 393 | +err_rwsem: | |
| 394 | + percpu_free_rwsem(&hu->proto_lock); | |
| 392 | 395 | return err; |
| 393 | 396 | } |
| 394 | 397 | EXPORT_SYMBOL_GPL(hci_uart_register_device); |
| @@ -410,5 +413,6 @@ void hci_uart_unregister_device(struct hci_uart *hu) · 15 unmodified lines | ||
| 410 | 413 | clear_bit(HCI_UART_PROTO_READY, &hu->flags); |
| 411 | 414 | serdev_device_close(hu->serdev); |
| 412 | 415 | } |
| 416 | + percpu_free_rwsem(&hu->proto_lock); | |
| 413 | 417 | } |
| 414 | 418 | EXPORT_SYMBOL_GPL(hci_uart_unregister_device); |
| @@ -726,6 +726,7 @@ void iproc_pll_clk_setup(struct device_node *node, · 725 unmodified lines | ||
| 726 | 726 | const char *parent_name; |
| 727 | 727 | struct iproc_clk *iclk_array; |
| 728 | 728 | struct clk_hw_onecell_data *clk_data; |
| 729 | + const char *clk_name; | |
| 729 | 730 | |
| 730 | 731 | if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl)) |
| 731 | 732 | return; |
| @@ -773,7 +774,12 @@ void iproc_pll_clk_setup(struct device_node *node, · 41 unmodified lines | ||
| 773 | 774 | iclk = &iclk_array[0]; |
| 774 | 775 | iclk->pll = pll; |
| 775 | 776 | |
| 776 | − init.name = node->name; | |
| 777 | + ret = of_property_read_string_index(node, "clock-output-names", | |
| 778 | + 0, &clk_name); | |
| 779 | + if (WARN_ON(ret)) | |
| 780 | + goto err_pll_register; | |
| 781 | + | |
| 782 | + init.name = clk_name; | |
| 777 | 783 | init.ops = &iproc_pll_ops; |
| 778 | 784 | init.flags = 0; |
| 779 | 785 | parent_name = of_clk_get_parent_name(node, 0); |
| @@ -793,13 +799,11 @@ void iproc_pll_clk_setup(struct device_node *node, · 13 unmodified lines | ||
| 793 | 799 | goto err_pll_register; |
| 794 | 800 | |
| 795 | 801 | clk_data->hws[0] = &iclk->hw; |
| 802 | + parent_name = clk_name; | |
| 796 | 803 | |
| 797 | 804 | /* now initialize and register all leaf clocks */ |
| 798 | 805 | for (i = 1; i < num_clks; i++) { |
| 799 | − const char *clk_name; | |
| 800 | − | |
| 801 | 806 | memset(&init, 0, sizeof(init)); |
| 802 | − parent_name = node->name; | |
| 803 | 807 | |
| 804 | 808 | ret = of_property_read_string_index(node, "clock-output-names", |
| 805 | 809 | i, &clk_name); |
| @@ -200,7 +200,9 @@ static int tps68470_clk_probe(struct platform_device *pdev) · 199 unmodified lines | ||
| 200 | 200 | .flags = CLK_SET_RATE_GATE, |
| 201 | 201 | }; |
| 202 | 202 | struct tps68470_clkdata *tps68470_clkdata; |
| 203 | + struct tps68470_clk_consumer *consumer; | |
| 203 | 204 | int ret; |
| 205 | + int i; | |
| 204 | 206 | |
| 205 | 207 | tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata), |
| 206 | 208 | GFP_KERNEL); |
| @@ -223,10 +225,13 @@ static int tps68470_clk_probe(struct platform_device *pdev) · 16 unmodified lines | ||
| 223 | 225 | return ret; |
| 224 | 226 | |
| 225 | 227 | if (pdata) { |
| 226 | − ret = devm_clk_hw_register_clkdev(&pdev->dev, | |
| 227 | − &tps68470_clkdata->clkout_hw, | |
| 228 | − pdata->consumer_con_id, | |
| 229 | − pdata->consumer_dev_name); | |
| 228 | + for (i = 0; i < pdata->n_consumers; i++) { | |
| 229 | + consumer = &pdata->consumers[i]; | |
| 230 | + ret = devm_clk_hw_register_clkdev(&pdev->dev, | |
| 231 | + &tps68470_clkdata->clkout_hw, | |
| 232 | + consumer->consumer_con_id, | |
| 233 | + consumer->consumer_dev_name); | |
| 234 | + } | |
| 230 | 235 | } |
| 231 | 236 | |
| 232 | 237 | return ret; |
| @@ -280,13 +280,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) · 279 unmodified lines | ||
| 280 | 280 | hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
| 281 | 281 | hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
| 282 | 282 | hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); |
| 283 | − hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); | |
| 283 | + hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); | |
| 284 | 284 | hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); |
| 285 | 285 | hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); |
| 286 | 286 | hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
| 287 | 287 | hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); |
| 288 | 288 | hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); |
| 289 | − hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); | |
| 289 | + hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels)); | |
| 290 | 290 | hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
| 291 | 291 | hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
| 292 | 292 | hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); |
| @@ -332,7 +332,7 @@ static struct platform_driver imx93_clk_driver = { · 331 unmodified lines | ||
| 332 | 332 | .driver = { |
| 333 | 333 | .name = "imx93-ccm", |
| 334 | 334 | .suppress_bind_attrs = true, |
| 335 | − .of_match_table = of_match_ptr(imx93_clk_of_match), | |
| 335 | + .of_match_table = imx93_clk_of_match, | |
| 336 | 336 | }, |
| 337 | 337 | }; |
| 338 | 338 | module_platform_driver(imx93_clk_driver); |
| @@ -101,15 +101,11 @@ static bool ingenic_tcu_enable_regs(struct clk_hw *hw) · 100 unmodified lines | ||
| 101 | 101 | bool enabled = false; |
| 102 | 102 | |
| 103 | 103 | /* |
| 104 | − * If the SoC has no global TCU clock, we must ungate the channel's | |
| 105 | − * clock to be able to access its registers. | |
| 106 | − * If we have a TCU clock, it will be enabled automatically as it has | |
| 107 | − * been attached to the regmap. | |
| 104 | + * According to the programming manual, a timer channel's registers can | |
| 105 | + * only be accessed when the channel's stop bit is clear. | |
| 108 | 106 | */ |
| 109 | − if (!tcu->clk) { | |
| 110 | − enabled = !!ingenic_tcu_is_enabled(hw); | |
| 111 | − regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); | |
| 112 | − } | |
| 107 | + enabled = !!ingenic_tcu_is_enabled(hw); | |
| 108 | + regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); | |
| 113 | 109 | |
| 114 | 110 | return enabled; |
| 115 | 111 | } |
| @@ -120,8 +116,7 @@ static void ingenic_tcu_disable_regs(struct clk_hw *hw) · 4 unmodified lines | ||
| 120 | 116 | const struct ingenic_tcu_clk_info *info = tcu_clk->info; |
| 121 | 117 | struct ingenic_tcu *tcu = tcu_clk->tcu; |
| 122 | 118 | |
| 123 | − if (!tcu->clk) | |
| 124 | − regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); | |
| 119 | + regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); | |
| 125 | 120 | } |
| 126 | 121 | |
| 127 | 122 | static u8 ingenic_tcu_get_parent(struct clk_hw *hw) |
| @@ -239,6 +239,11 @@ static const struct clk_ops mpfs_clk_cfg_ops = { · 238 unmodified lines | ||
| 239 | 239 | .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \ |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | +#define CLK_CPU_OFFSET 0u | |
| 243 | +#define CLK_AXI_OFFSET 1u | |
| 244 | +#define CLK_AHB_OFFSET 2u | |
| 245 | +#define CLK_RTCREF_OFFSET 3u | |
| 246 | + | |
| 242 | 247 | static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { |
| 243 | 248 | CLK_CFG(CLK_CPU, "clk_cpu", "clk_msspll", 0, 2, mpfs_div_cpu_axi_table, 0, |
| 244 | 249 | REG_CLOCK_CONFIG_CR), |
| @@ -362,7 +367,7 @@ static const struct clk_ops mpfs_periph_clk_ops = { · 117 unmodified lines | ||
| 362 | 367 | _flags), \ |
| 363 | 368 | } |
| 364 | 369 | |
| 365 | −#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw) | |
| 370 | +#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw) | |
| 366 | 371 | |
| 367 | 372 | /* |
| 368 | 373 | * Critical clocks: |
| @@ -370,6 +375,8 @@ static const struct clk_ops mpfs_periph_clk_ops = { · 1 unmodified line | ||
| 370 | 375 | * trap handler |
| 371 | 376 | * - CLK_MMUART0: reserved by the hss |
| 372 | 377 | * - CLK_DDRC: provides clock to the ddr subsystem |
| 378 | + * - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop | |
| 379 | + * if the AHB interface clock is disabled | |
| 373 | 380 | * - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect) |
| 374 | 381 | * clock domain crossers which provide the interface to the FPGA fabric. Disabling them |
| 375 | 382 | * causes the FPGA fabric to go into reset. |
| @@ -394,7 +401,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { · 18 unmodified lines | ||
| 394 | 401 | CLK_PERIPH(CLK_CAN0, "clk_periph_can0", PARENT_CLK(AHB), 14, 0), |
| 395 | 402 | CLK_PERIPH(CLK_CAN1, "clk_periph_can1", PARENT_CLK(AHB), 15, 0), |
| 396 | 403 | CLK_PERIPH(CLK_USB, "clk_periph_usb", PARENT_CLK(AHB), 16, 0), |
| 397 | − CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, 0), | |
| 404 | + CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, CLK_IS_CRITICAL), | |
| 398 | 405 | CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", PARENT_CLK(AHB), 19, 0), |
| 399 | 406 | CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", PARENT_CLK(AHB), 20, 0), |
| 400 | 407 | CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0), |
| @@ -1191,9 +1191,13 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev) · 1190 unmodified lines | ||
| 1191 | 1191 | if (IS_ERR(reg)) |
| 1192 | 1192 | return PTR_ERR(reg); |
| 1193 | 1193 | |
| 1194 | − /* Force PLL_GPU output divider bits to 0 */ | |
| 1194 | + /* | |
| 1195 | + * Force PLL_GPU output divider bits to 0 and adjust | |
| 1196 | + * multiplier to sensible default value of 432 MHz. | |
| 1197 | + */ | |
| 1195 | 1198 | val = readl(reg + SUN50I_H6_PLL_GPU_REG); |
| 1196 | − val &= ~BIT(0); | |
| 1199 | + val &= ~(GENMASK(15, 8) | BIT(0)); | |
| 1200 | + val |= 17 << 8; | |
| 1197 | 1201 | writel(val, reg + SUN50I_H6_PLL_GPU_REG); |
| 1198 | 1202 | |
| 1199 | 1203 | /* Force GPU_CLK divider bits to 0 */ |
| @@ -46,8 +46,8 @@ · 45 unmodified lines | ||
| 46 | 46 | #include <asm/cpu_device_id.h> |
| 47 | 47 | #include "amd-pstate-trace.h" |
| 48 | 48 | |
| 49 | −#define AMD_PSTATE_TRANSITION_LATENCY 0x20000 | |
| 50 | −#define AMD_PSTATE_TRANSITION_DELAY 500 | |
| 49 | +#define AMD_PSTATE_TRANSITION_LATENCY 20000 | |
| 50 | +#define AMD_PSTATE_TRANSITION_DELAY 1000 | |
| 51 | 51 | |
| 52 | 52 | /* |
| 53 | 53 | * TODO: We need more time to fine tune processors with shared memory solution |
| @@ -120,7 +120,7 @@ struct amd_cpudata { · 66 unmodified lines | ||
| 120 | 120 | struct amd_aperf_mperf cur; |
| 121 | 121 | struct amd_aperf_mperf prev; |
| 122 | 122 | |
| 123 | − u64 freq; | |
| 123 | + u64 freq; | |
| 124 | 124 | bool boost_supported; |
| 125 | 125 | }; |
| 126 | 126 | |
| @@ -152,6 +152,7 @@ static inline int amd_pstate_enable(bool enable) · 25 unmodified lines | ||
| 152 | 152 | static int pstate_init_perf(struct amd_cpudata *cpudata) |
| 153 | 153 | { |
| 154 | 154 | u64 cap1; |
| 155 | + u32 highest_perf; | |
| 155 | 156 | |
| 156 | 157 | int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1, |
| 157 | 158 | &cap1); |
| @@ -163,7 +164,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) · 5 unmodified lines | ||
| 163 | 164 | * |
| 164 | 165 | * CPPC entry doesn't indicate the highest performance in some ASICs. |
| 165 | 166 | */ |
| 166 | − WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); | |
| 167 | + highest_perf = amd_get_highest_perf(); | |
| 168 | + if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) | |
| 169 | + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); | |
| 170 | + | |
| 171 | + WRITE_ONCE(cpudata->highest_perf, highest_perf); | |
| 167 | 172 | |
| 168 | 173 | WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); |
| 169 | 174 | WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); |
| @@ -175,12 +180,17 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) · 5 unmodified lines | ||
| 175 | 180 | static int cppc_init_perf(struct amd_cpudata *cpudata) |
| 176 | 181 | { |
| 177 | 182 | struct cppc_perf_caps cppc_perf; |
| 183 | + u32 highest_perf; | |
| 178 | 184 | |
| 179 | 185 | int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); |
| 180 | 186 | if (ret) |
| 181 | 187 | return ret; |
| 182 | 188 | |
| 183 | − WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); | |
| 189 | + highest_perf = amd_get_highest_perf(); | |
| 190 | + if (highest_perf > cppc_perf.highest_perf) | |
| 191 | + highest_perf = cppc_perf.highest_perf; | |
| 192 | + | |
| 193 | + WRITE_ONCE(cpudata->highest_perf, highest_perf); | |
| 184 | 194 | |
| 185 | 195 | WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); |
| 186 | 196 | WRITE_ONCE(cpudata->lowest_nonlinear_perf, |
| @@ -269,6 +279,7 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, · 82 unmodified lines | ||
| 269 | 279 | u64 prev = READ_ONCE(cpudata->cppc_req_cached); |
| 270 | 280 | u64 value = prev; |
| 271 | 281 | |
| 282 | + des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); | |
| 272 | 283 | value &= ~AMD_CPPC_MIN_PERF(~0L); |
| 273 | 284 | value |= AMD_CPPC_MIN_PERF(min_perf); |
| 274 | 285 | |
| @@ -312,7 +323,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy, · 37 unmodified lines | ||
| 312 | 323 | return -ENODEV; |
| 313 | 324 | |
| 314 | 325 | cap_perf = READ_ONCE(cpudata->highest_perf); |
| 315 | − min_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); | |
| 326 | + min_perf = READ_ONCE(cpudata->lowest_perf); | |
| 316 | 327 | max_perf = cap_perf; |
| 317 | 328 | |
| 318 | 329 | freqs.old = policy->cur; |
| @@ -357,8 +368,6 @@ static void amd_pstate_adjust_perf(unsigned int cpu, · 38 unmodified lines | ||
| 357 | 368 | if (max_perf < min_perf) |
| 358 | 369 | max_perf = min_perf; |
| 359 | 370 | |
| 360 | − des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); | |
| 361 | − | |
| 362 | 371 | amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true); |
| 363 | 372 | } |
| 364 | 373 | |
| @@ -555,9 +564,7 @@ free_cpudata1: · 190 unmodified lines | ||
| 555 | 564 | |
| 556 | 565 | static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) |
| 557 | 566 | { |
| 558 | − struct amd_cpudata *cpudata; | |
| 559 | − | |
| 560 | − cpudata = policy->driver_data; | |
| 567 | + struct amd_cpudata *cpudata = policy->driver_data; | |
| 561 | 568 | |
| 562 | 569 | freq_qos_remove_request(&cpudata->req[1]); |
| 563 | 570 | freq_qos_remove_request(&cpudata->req[0]); |
| @@ -599,9 +606,7 @@ static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy, · 35 unmodified lines | ||
| 599 | 606 | char *buf) |
| 600 | 607 | { |
| 601 | 608 | int max_freq; |
| 602 | − struct amd_cpudata *cpudata; | |
| 603 | − | |
| 604 | − cpudata = policy->driver_data; | |
| 609 | + struct amd_cpudata *cpudata = policy->driver_data; | |
| 605 | 610 | |
| 606 | 611 | max_freq = amd_get_max_freq(cpudata); |
| 607 | 612 | if (max_freq < 0) |
| @@ -614,9 +619,7 @@ static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *poli · 6 unmodified lines | ||
| 614 | 619 | char *buf) |
| 615 | 620 | { |
| 616 | 621 | int freq; |
| 617 | − struct amd_cpudata *cpudata; | |
| 618 | − | |
| 619 | − cpudata = policy->driver_data; | |
| 622 | + struct amd_cpudata *cpudata = policy->driver_data; | |
| 620 | 623 | |
| 621 | 624 | freq = amd_get_lowest_nonlinear_freq(cpudata); |
| 622 | 625 | if (freq < 0) |
| @@ -662,7 +665,7 @@ static struct cpufreq_driver amd_pstate_driver = { · 39 unmodified lines | ||
| 662 | 665 | .resume = amd_pstate_cpu_resume, |
| 663 | 666 | .set_boost = amd_pstate_set_boost, |
| 664 | 667 | .name = "amd-pstate", |
| 665 | − .attr = amd_pstate_attr, | |
| 668 | + .attr = amd_pstate_attr, | |
| 666 | 669 | }; |
| 667 | 670 | |
| 668 | 671 | static int __init amd_pstate_init(void) |
| @@ -673,7 +676,7 @@ static int __init amd_pstate_init(void) · 4 unmodified lines | ||
| 673 | 676 | return -ENODEV; |
| 674 | 677 | |
| 675 | 678 | if (!acpi_cpc_valid()) { |
| 676 | − pr_debug("the _CPC object is not present in SBIOS\n"); | |
| 679 | + pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n"); | |
| 677 | 680 | return -ENODEV; |
| 678 | 681 | } |
| 679 | 682 | |
| @@ -156,7 +156,7 @@ static struct cpufreq_driver bmips_cpufreq_driver = { · 155 unmodified lines | ||
| 156 | 156 | .name = BMIPS_CPUFREQ_PREFIX, |
| 157 | 157 | }; |
| 158 | 158 | |
| 159 | −static int __init bmips_cpufreq_probe(void) | |
| 159 | +static int __init bmips_cpufreq_driver_init(void) | |
| 160 | 160 | { |
| 161 | 161 | struct cpufreq_compat *cc; |
| 162 | 162 | struct device_node *np; |
| @@ -176,7 +176,13 @@ static int __init bmips_cpufreq_probe(void) · 13 unmodified lines | ||
| 176 | 176 | |
| 177 | 177 | return cpufreq_register_driver(&bmips_cpufreq_driver); |
| 178 | 178 | } |
| 179 | −device_initcall(bmips_cpufreq_probe); | |
| 179 | +module_init(bmips_cpufreq_driver_init); | |
| 180 | + | |
| 181 | +static void __exit bmips_cpufreq_driver_exit(void) | |
| 182 | +{ | |
| 183 | + cpufreq_unregister_driver(&bmips_cpufreq_driver); | |
| 184 | +} | |
| 185 | +module_exit(bmips_cpufreq_driver_exit); | |
| 180 | 186 | |
| 181 | 187 | MODULE_AUTHOR("Markus Mayer <mmayer@broadcom.com>"); |
| 182 | 188 | MODULE_DESCRIPTION("CPUfreq driver for Broadcom BMIPS SoCs"); |
| @@ -63,7 +63,15 @@ static struct cppc_workaround_oem_info wa_info[] = { · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | static struct cpufreq_driver cppc_cpufreq_driver; |
| 65 | 65 | |
| 66 | +static enum { | |
| 67 | + FIE_UNSET = -1, | |
| 68 | + FIE_ENABLED, | |
| 69 | + FIE_DISABLED | |
| 70 | +} fie_disabled = FIE_UNSET; | |
| 71 | + | |
| 66 | 72 | #ifdef CONFIG_ACPI_CPPC_CPUFREQ_FIE |
| 73 | +module_param(fie_disabled, int, 0444); | |
| 74 | +MODULE_PARM_DESC(fie_disabled, "Disable Frequency Invariance Engine (FIE)"); | |
| 67 | 75 | |
| 68 | 76 | /* Frequency invariance support */ |
| 69 | 77 | struct cppc_freq_invariance { |
| @@ -158,7 +166,7 @@ static void cppc_cpufreq_cpu_fie_init(struct cpufreq_policy *policy) · 88 unmodified lines | ||
| 158 | 166 | struct cppc_freq_invariance *cppc_fi; |
| 159 | 167 | int cpu, ret; |
| 160 | 168 | |
| 161 | − if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate) | |
| 169 | + if (fie_disabled) | |
| 162 | 170 | return; |
| 163 | 171 | |
| 164 | 172 | for_each_cpu(cpu, policy->cpus) { |
| @@ -199,7 +207,7 @@ static void cppc_cpufreq_cpu_fie_exit(struct cpufreq_policy *policy) · 34 unmodified lines | ||
| 199 | 207 | struct cppc_freq_invariance *cppc_fi; |
| 200 | 208 | int cpu; |
| 201 | 209 | |
| 202 | − if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate) | |
| 210 | + if (fie_disabled) | |
| 203 | 211 | return; |
| 204 | 212 | |
| 205 | 213 | /* policy->cpus will be empty here, use related_cpus instead */ |
| @@ -229,7 +237,15 @@ static void __init cppc_freq_invariance_init(void) · 23 unmodified lines | ||
| 229 | 237 | }; |
| 230 | 238 | int ret; |
| 231 | 239 | |
| 232 | − if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate) | |
| 240 | + if (fie_disabled != FIE_ENABLED && fie_disabled != FIE_DISABLED) { | |
| 241 | + fie_disabled = FIE_ENABLED; | |
| 242 | + if (cppc_perf_ctrs_in_pcc()) { | |
| 243 | + pr_info("FIE not enabled on systems with registers in PCC\n"); | |
| 244 | + fie_disabled = FIE_DISABLED; | |
| 245 | + } | |
| 246 | + } | |
| 247 | + | |
| 248 | + if (fie_disabled) | |
| 233 | 249 | return; |
| 234 | 250 | |
| 235 | 251 | kworker_fie = kthread_create_worker(0, "cppc_fie"); |
| @@ -247,7 +263,7 @@ static void __init cppc_freq_invariance_init(void) · 11 unmodified lines | ||
| 247 | 263 | |
| 248 | 264 | static void cppc_freq_invariance_exit(void) |
| 249 | 265 | { |
| 250 | − if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate) | |
| 266 | + if (fie_disabled) | |
| 251 | 267 | return; |
| 252 | 268 | |
| 253 | 269 | kthread_destroy_worker(kworker_fie); |
| @@ -936,6 +952,7 @@ static void cppc_check_hisi_workaround(void) · 682 unmodified lines | ||
| 936 | 952 | wa_info[i].oem_revision == tbl->oem_revision) { |
| 937 | 953 | /* Overwrite the get() callback */ |
| 938 | 954 | cppc_cpufreq_driver.get = hisi_cppc_cpufreq_get_rate; |
| 955 | + fie_disabled = FIE_DISABLED; | |
| 939 | 956 | break; |
| 940 | 957 | } |
| 941 | 958 | } |
| @@ -947,7 +964,7 @@ static int __init cppc_cpufreq_init(void) · 5 unmodified lines | ||
| 947 | 964 | { |
| 948 | 965 | int ret; |
| 949 | 966 | |
| 950 | − if ((acpi_disabled) || !acpi_cpc_valid()) | |
| 967 | + if (!acpi_cpc_valid()) | |
| 951 | 968 | return -ENODEV; |
| 952 | 969 | |
| 953 | 970 | cppc_check_hisi_workaround(); |
| @@ -146,6 +146,7 @@ static const struct of_device_id blocklist[] __initconst = { · 145 unmodified lines | ||
| 146 | 146 | { .compatible = "qcom,sc8180x", }, |
| 147 | 147 | { .compatible = "qcom,sc8280xp", }, |
| 148 | 148 | { .compatible = "qcom,sdm845", }, |
| 149 | + { .compatible = "qcom,sm6115", }, | |
| 149 | 150 | { .compatible = "qcom,sm6350", }, |
| 150 | 151 | { .compatible = "qcom,sm8150", }, |
| 151 | 152 | { .compatible = "qcom,sm8250", }, |
| @@ -55,7 +55,7 @@ static struct notifier_block hb_cpufreq_clk_nb = { · 54 unmodified lines | ||
| 55 | 55 | .notifier_call = hb_cpufreq_clk_notify, |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | −static int hb_cpufreq_driver_init(void) | |
| 58 | +static int __init hb_cpufreq_driver_init(void) | |
| 59 | 59 | { |
| 60 | 60 | struct platform_device_info devinfo = { .name = "cpufreq-dt", }; |
| 61 | 61 | struct device *cpu_dev; |
| @@ -2416,6 +2416,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { · 2415 unmodified lines | ||
| 2416 | 2416 | X86_MATCH(SKYLAKE_X, core_funcs), |
| 2417 | 2417 | X86_MATCH(COMETLAKE, core_funcs), |
| 2418 | 2418 | X86_MATCH(ICELAKE_X, core_funcs), |
| 2419 | + X86_MATCH(TIGERLAKE, core_funcs), | |
| 2419 | 2420 | {} |
| 2420 | 2421 | }; |
| 2421 | 2422 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/of_address.h> |
| 14 | 14 | #include <linux/of_platform.h> |
| 15 | 15 | #include <linux/pm_opp.h> |
| 16 | +#include <linux/pm_qos.h> | |
| 16 | 17 | #include <linux/slab.h> |
| 17 | 18 | #include <linux/spinlock.h> |
| 18 | 19 | #include <linux/units.h> |
| @@ -56,6 +57,8 @@ struct qcom_cpufreq_data { · 37 unmodified lines | ||
| 56 | 57 | struct cpufreq_policy *policy; |
| 57 | 58 | |
| 58 | 59 | bool per_core_dcvs; |
| 60 | + | |
| 61 | + struct freq_qos_request throttle_freq_req; | |
| 59 | 62 | }; |
| 60 | 63 | |
| 61 | 64 | static unsigned long cpu_hw_rate, xo_rate; |
| @@ -316,14 +319,16 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) · 254 unmodified lines | ||
| 316 | 319 | if (IS_ERR(opp)) { |
| 317 | 320 | dev_warn(dev, "Can't find the OPP for throttling: %pe!\n", opp); |
| 318 | 321 | } else { |
| 319 | − throttled_freq = freq_hz / HZ_PER_KHZ; | |
| 320 | − | |
| 321 | − /* Update thermal pressure (the boost frequencies are accepted) */ | |
| 322 | − arch_update_thermal_pressure(policy->related_cpus, throttled_freq); | |
| 323 | − | |
| 324 | 322 | dev_pm_opp_put(opp); |
| 325 | 323 | } |
| 326 | 324 | |
| 325 | + throttled_freq = freq_hz / HZ_PER_KHZ; | |
| 326 | + | |
| 327 | + freq_qos_update_request(&data->throttle_freq_req, throttled_freq); | |
| 328 | + | |
| 329 | + /* Update thermal pressure (the boost frequencies are accepted) */ | |
| 330 | + arch_update_thermal_pressure(policy->related_cpus, throttled_freq); | |
| 331 | + | |
| 327 | 332 | /* |
| 328 | 333 | * In the unlikely case policy is unregistered do not enable |
| 329 | 334 | * polling or h/w interrupt |
| @@ -413,6 +418,14 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index) · 83 unmodified lines | ||
| 413 | 418 | if (data->throttle_irq < 0) |
| 414 | 419 | return data->throttle_irq; |
| 415 | 420 | |
| 421 | + ret = freq_qos_add_request(&policy->constraints, | |
| 422 | + &data->throttle_freq_req, FREQ_QOS_MAX, | |
| 423 | + FREQ_QOS_MAX_DEFAULT_VALUE); | |
| 424 | + if (ret < 0) { | |
| 425 | + dev_err(&pdev->dev, "Failed to add freq constraint (%d)\n", ret); | |
| 426 | + return ret; | |
| 427 | + } | |
| 428 | + | |
| 416 | 429 | data->cancel_throttle = false; |
| 417 | 430 | data->policy = policy; |
| 418 | 431 | |
| @@ -479,6 +492,7 @@ static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) · 60 unmodified lines | ||
| 479 | 492 | if (data->throttle_irq <= 0) |
| 480 | 493 | return; |
| 481 | 494 | |
| 495 | + freq_qos_remove_request(&data->throttle_freq_req); | |
| 482 | 496 | free_irq(data->throttle_irq, data); |
| 483 | 497 | } |
| 484 | 498 | |
| @@ -252,7 +252,7 @@ static int sti_cpufreq_fetch_syscon_registers(void) · 251 unmodified lines | ||
| 252 | 252 | return 0; |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | −static int sti_cpufreq_init(void) | |
| 255 | +static int __init sti_cpufreq_init(void) | |
| 256 | 256 | { |
| 257 | 257 | int ret; |
| 258 | 258 | |
| @@ -38,14 +38,6 @@ · 37 unmodified lines | ||
| 38 | 38 | /* cpufreq transisition latency */ |
| 39 | 39 | #define TEGRA_CPUFREQ_TRANSITION_LATENCY (300 * 1000) /* unit in nanoseconds */ |
| 40 | 40 | |
| 41 | −enum cluster { | |
| 42 | − CLUSTER0, | |
| 43 | − CLUSTER1, | |
| 44 | − CLUSTER2, | |
| 45 | − CLUSTER3, | |
| 46 | − MAX_CLUSTERS, | |
| 47 | −}; | |
| 48 | − | |
| 49 | 41 | struct tegra_cpu_ctr { |
| 50 | 42 | u32 cpu; |
| 51 | 43 | u32 coreclk_cnt, last_coreclk_cnt; |
| @@ -67,12 +59,12 @@ struct tegra_cpufreq_ops { · 15 unmodified lines | ||
| 67 | 59 | struct tegra_cpufreq_soc { |
| 68 | 60 | struct tegra_cpufreq_ops *ops; |
| 69 | 61 | int maxcpus_per_cluster; |
| 62 | + unsigned int num_clusters; | |
| 70 | 63 | phys_addr_t actmon_cntr_base; |
| 71 | 64 | }; |
| 72 | 65 | |
| 73 | 66 | struct tegra194_cpufreq_data { |
| 74 | 67 | void __iomem *regs; |
| 75 | − size_t num_clusters; | |
| 76 | 68 | struct cpufreq_frequency_table **tables; |
| 77 | 69 | const struct tegra_cpufreq_soc *soc; |
| 78 | 70 | }; |
| @@ -166,6 +158,14 @@ static const struct tegra_cpufreq_soc tegra234_cpufreq_soc = { · 87 unmodified lines | ||
| 166 | 158 | .ops = &tegra234_cpufreq_ops, |
| 167 | 159 | .actmon_cntr_base = 0x9000, |
| 168 | 160 | .maxcpus_per_cluster = 4, |
| 161 | + .num_clusters = 3, | |
| 162 | +}; | |
| 163 | + | |
| 164 | +static const struct tegra_cpufreq_soc tegra239_cpufreq_soc = { | |
| 165 | + .ops = &tegra234_cpufreq_ops, | |
| 166 | + .actmon_cntr_base = 0x4000, | |
| 167 | + .maxcpus_per_cluster = 8, | |
| 168 | + .num_clusters = 1, | |
| 169 | 169 | }; |
| 170 | 170 | |
| 171 | 171 | static void tegra194_get_cpu_cluster_id(u32 cpu, u32 *cpuid, u32 *clusterid) |
| @@ -314,11 +314,7 @@ static void tegra194_get_cpu_ndiv_sysreg(void *ndiv) · 142 unmodified lines | ||
| 314 | 314 | |
| 315 | 315 | static int tegra194_get_cpu_ndiv(u32 cpu, u32 cpuid, u32 clusterid, u64 *ndiv) |
| 316 | 316 | { |
| 317 | − int ret; | |
| 318 | − | |
| 319 | − ret = smp_call_function_single(cpu, tegra194_get_cpu_ndiv_sysreg, &ndiv, true); | |
| 320 | − | |
| 321 | − return ret; | |
| 317 | + return smp_call_function_single(cpu, tegra194_get_cpu_ndiv_sysreg, &ndiv, true); | |
| 322 | 318 | } |
| 323 | 319 | |
| 324 | 320 | static void tegra194_set_cpu_ndiv_sysreg(void *data) |
| @@ -382,7 +378,7 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy) · 57 unmodified lines | ||
| 382 | 378 | |
| 383 | 379 | data->soc->ops->get_cpu_cluster_id(policy->cpu, NULL, &clusterid); |
| 384 | 380 | |
| 385 | − if (clusterid >= data->num_clusters || !data->tables[clusterid]) | |
| 381 | + if (clusterid >= data->soc->num_clusters || !data->tables[clusterid]) | |
| 386 | 382 | return -EINVAL; |
| 387 | 383 | |
| 388 | 384 | start_cpu = rounddown(policy->cpu, maxcpus_per_cluster); |
| @@ -433,6 +429,7 @@ static struct tegra_cpufreq_ops tegra194_cpufreq_ops = { · 44 unmodified lines | ||
| 433 | 429 | static const struct tegra_cpufreq_soc tegra194_cpufreq_soc = { |
| 434 | 430 | .ops = &tegra194_cpufreq_ops, |
| 435 | 431 | .maxcpus_per_cluster = 2, |
| 432 | + .num_clusters = 4, | |
| 436 | 433 | }; |
| 437 | 434 | |
| 438 | 435 | static void tegra194_cpufreq_free_resources(void) |
| @@ -525,15 +522,14 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev) · 86 unmodified lines | ||
| 525 | 522 | |
| 526 | 523 | soc = of_device_get_match_data(&pdev->dev); |
| 527 | 524 | |
| 528 | − if (soc->ops && soc->maxcpus_per_cluster) { | |
| 525 | + if (soc->ops && soc->maxcpus_per_cluster && soc->num_clusters) { | |
| 529 | 526 | data->soc = soc; |
| 530 | 527 | } else { |
| 531 | 528 | dev_err(&pdev->dev, "soc data missing\n"); |
| 532 | 529 | return -EINVAL; |
| 533 | 530 | } |
| 534 | 531 | |
| 535 | − data->num_clusters = MAX_CLUSTERS; | |
| 536 | − data->tables = devm_kcalloc(&pdev->dev, data->num_clusters, | |
| 532 | + data->tables = devm_kcalloc(&pdev->dev, data->soc->num_clusters, | |
| 537 | 533 | sizeof(*data->tables), GFP_KERNEL); |
| 538 | 534 | if (!data->tables) |
| 539 | 535 | return -ENOMEM; |
| @@ -558,7 +554,7 @@ static int tegra194_cpufreq_probe(struct platform_device *pdev) · 18 unmodified lines | ||
| 558 | 554 | goto put_bpmp; |
| 559 | 555 | } |
| 560 | 556 | |
| 561 | − for (i = 0; i < data->num_clusters; i++) { | |
| 557 | + for (i = 0; i < data->soc->num_clusters; i++) { | |
| 562 | 558 | data->tables[i] = init_freq_table(pdev, bpmp, i); |
| 563 | 559 | if (IS_ERR(data->tables[i])) { |
| 564 | 560 | err = PTR_ERR(data->tables[i]); |
| @@ -590,6 +586,7 @@ static int tegra194_cpufreq_remove(struct platform_device *pdev) · 25 unmodified lines | ||
| 590 | 586 | static const struct of_device_id tegra194_cpufreq_of_match[] = { |
| 591 | 587 | { .compatible = "nvidia,tegra194-ccplex", .data = &tegra194_cpufreq_soc }, |
| 592 | 588 | { .compatible = "nvidia,tegra234-ccplex-cluster", .data = &tegra234_cpufreq_soc }, |
| 589 | + { .compatible = "nvidia,tegra239-ccplex-cluster", .data = &tegra239_cpufreq_soc }, | |
| 593 | 590 | { /* sentinel */ } |
| 594 | 591 | }; |
| 595 | 592 | |
| @@ -398,7 +398,7 @@ fail_put_node: · 397 unmodified lines | ||
| 398 | 398 | return ret; |
| 399 | 399 | } |
| 400 | 400 | |
| 401 | −static int ti_cpufreq_init(void) | |
| 401 | +static int __init ti_cpufreq_init(void) | |
| 402 | 402 | { |
| 403 | 403 | const struct of_device_id *match; |
| 404 | 404 | |
| @@ -54,7 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | * variable is not locked. It is only written from the cpu that |
| 55 | 55 | * it stores (or by the on/offlining cpu if that cpu is offline), |
| 56 | 56 | * and only read after all the cpus are ready for the coupled idle |
| 57 | − * state are are no longer updating it. | |
| 57 | + * state are no longer updating it. | |
| 58 | 58 | * |
| 59 | 59 | * Three atomic counters are used. alive_count tracks the number |
| 60 | 60 | * of cpus in the coupled set that are currently or soon will be |
| @@ -233,8 +233,8 @@ static inline void add_powernv_state(int index, const char *name, · 232 unmodified lines | ||
| 233 | 233 | unsigned int exit_latency, |
| 234 | 234 | u64 psscr_val, u64 psscr_mask) |
| 235 | 235 | { |
| 236 | − strlcpy(powernv_states[index].name, name, CPUIDLE_NAME_LEN); | |
| 237 | − strlcpy(powernv_states[index].desc, name, CPUIDLE_NAME_LEN); | |
| 236 | + strscpy(powernv_states[index].name, name, CPUIDLE_NAME_LEN); | |
| 237 | + strscpy(powernv_states[index].desc, name, CPUIDLE_NAME_LEN); | |
| 238 | 238 | powernv_states[index].flags = flags; |
| 239 | 239 | powernv_states[index].target_residency = target_residency; |
| 240 | 240 | powernv_states[index].exit_latency = exit_latency; |
| @@ -63,12 +63,11 @@ int cpuidle_switch_governor(struct cpuidle_governor *gov) · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | cpuidle_curr_governor = gov; |
| 65 | 65 | |
| 66 | − if (gov) { | |
| 67 | − list_for_each_entry(dev, &cpuidle_detected_devices, device_list) | |
| 68 | − cpuidle_enable_device(dev); | |
| 69 | − cpuidle_install_idle_handler(); | |
| 70 | − printk(KERN_INFO "cpuidle: using governor %s\n", gov->name); | |
| 71 | − } | |
| 66 | + list_for_each_entry(dev, &cpuidle_detected_devices, device_list) | |
| 67 | + cpuidle_enable_device(dev); | |
| 68 | + | |
| 69 | + cpuidle_install_idle_handler(); | |
| 70 | + pr_info("cpuidle: using governor %s\n", gov->name); | |
| 72 | 71 | |
| 73 | 72 | return 0; |
| 74 | 73 | } |
| @@ -56,6 +56,10 @@ static void virtio_crypto_akcipher_finalize_req( · 55 unmodified lines | ||
| 56 | 56 | struct virtio_crypto_akcipher_request *vc_akcipher_req, |
| 57 | 57 | struct akcipher_request *req, int err) |
| 58 | 58 | { |
| 59 | + kfree(vc_akcipher_req->src_buf); | |
| 60 | + kfree(vc_akcipher_req->dst_buf); | |
| 61 | + vc_akcipher_req->src_buf = NULL; | |
| 62 | + vc_akcipher_req->dst_buf = NULL; | |
| 59 | 63 | virtcrypto_clear_request(&vc_akcipher_req->base); |
| 60 | 64 | |
| 61 | 65 | crypto_finalize_akcipher_request(vc_akcipher_req->base.dataq->engine, req, err); |
| @@ -189,10 +189,9 @@ static int rockchip_dfi_probe(struct platform_device *pdev) · 188 unmodified lines | ||
| 189 | 189 | return PTR_ERR(data->regs); |
| 190 | 190 | |
| 191 | 191 | data->clk = devm_clk_get(dev, "pclk_ddr_mon"); |
| 192 | − if (IS_ERR(data->clk)) { | |
| 193 | − dev_err(dev, "Cannot get the clk dmc_clk\n"); | |
| 194 | − return PTR_ERR(data->clk); | |
| 195 | − } | |
| 192 | + if (IS_ERR(data->clk)) | |
| 193 | + return dev_err_probe(dev, PTR_ERR(data->clk), | |
| 194 | + "Cannot get the clk pclk_ddr_mon\n"); | |
| 196 | 195 | |
| 197 | 196 | /* try to find the optional reference to the pmu syscon */ |
| 198 | 197 | node = of_parse_phandle(np, "rockchip,pmu", 0); |
| @@ -291,9 +291,13 @@ static int mtk_ccifreq_probe(struct platform_device *pdev) · 290 unmodified lines | ||
| 291 | 291 | } |
| 292 | 292 | |
| 293 | 293 | drv->sram_reg = devm_regulator_get_optional(dev, "sram"); |
| 294 | − if (IS_ERR(drv->sram_reg)) | |
| 294 | + if (IS_ERR(drv->sram_reg)) { | |
| 295 | + ret = PTR_ERR(drv->sram_reg); | |
| 296 | + if (ret == -EPROBE_DEFER) | |
| 297 | + goto out_free_resources; | |
| 298 | + | |
| 295 | 299 | drv->sram_reg = NULL; |
| 296 | − else { | |
| 300 | + } else { | |
| 297 | 301 | ret = regulator_enable(drv->sram_reg); |
| 298 | 302 | if (ret) { |
| 299 | 303 | dev_err(dev, "failed to enable sram regulator\n"); |
| @@ -103,7 +103,6 @@ static void edac_mc_dump_dimm(struct dimm_info *dimm) · 102 unmodified lines | ||
| 103 | 103 | edac_dbg(4, " dimm->label = '%s'\n", dimm->label); |
| 104 | 104 | edac_dbg(4, " dimm->nr_pages = 0x%x\n", dimm->nr_pages); |
| 105 | 105 | edac_dbg(4, " dimm->grain = %d\n", dimm->grain); |
| 106 | − edac_dbg(4, " dimm->nr_pages = 0x%x\n", dimm->nr_pages); | |
| 107 | 106 | } |
| 108 | 107 | |
| 109 | 108 | static void edac_mc_dump_csrow(struct csrow_info *csrow) |
| @@ -28,13 +28,9 @@ void edac_mc_sysfs_exit(void); · 27 unmodified lines | ||
| 28 | 28 | extern int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, |
| 29 | 29 | const struct attribute_group **groups); |
| 30 | 30 | extern void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci); |
| 31 | −extern int edac_get_log_ue(void); | |
| 32 | −extern int edac_get_log_ce(void); | |
| 33 | −extern int edac_get_panic_on_ue(void); | |
| 34 | 31 | extern int edac_mc_get_log_ue(void); |
| 35 | 32 | extern int edac_mc_get_log_ce(void); |
| 36 | 33 | extern int edac_mc_get_panic_on_ue(void); |
| 37 | −extern int edac_get_poll_msec(void); | |
| 38 | 34 | extern unsigned int edac_mc_get_poll_msec(void); |
| 39 | 35 | |
| 40 | 36 | unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, |
| @@ -74,31 +74,47 @@ static struct list_head *i10nm_edac_list; · 73 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | static struct res_config *res_cfg; |
| 76 | 76 | static int retry_rd_err_log; |
| 77 | +static int decoding_via_mca; | |
| 78 | +static bool mem_cfg_2lm; | |
| 77 | 79 | |
| 78 | 80 | static u32 offsets_scrub_icx[] = {0x22c60, 0x22c54, 0x22c5c, 0x22c58, 0x22c28, 0x20ed8}; |
| 79 | 81 | static u32 offsets_scrub_spr[] = {0x22c60, 0x22c54, 0x22f08, 0x22c58, 0x22c28, 0x20ed8}; |
| 82 | +static u32 offsets_scrub_spr_hbm0[] = {0x2860, 0x2854, 0x2b08, 0x2858, 0x2828, 0x0ed8}; | |
| 83 | +static u32 offsets_scrub_spr_hbm1[] = {0x2c60, 0x2c54, 0x2f08, 0x2c58, 0x2c28, 0x0fa8}; | |
| 80 | 84 | static u32 offsets_demand_icx[] = {0x22e54, 0x22e60, 0x22e64, 0x22e58, 0x22e5c, 0x20ee0}; |
| 81 | 85 | static u32 offsets_demand_spr[] = {0x22e54, 0x22e60, 0x22f10, 0x22e58, 0x22e5c, 0x20ee0}; |
| 86 | +static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, 0x20f10}; | |
| 87 | +static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0}; | |
| 88 | +static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0}; | |
| 82 | 89 | |
| 83 | −static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable) | |
| 90 | +static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable, | |
| 91 | + u32 *offsets_scrub, u32 *offsets_demand, | |
| 92 | + u32 *offsets_demand2) | |
| 84 | 93 | { |
| 85 | − u32 s, d; | |
| 94 | + u32 s, d, d2; | |
| 86 | 95 | |
| 87 | − if (!imc->mbase) | |
| 88 | − return; | |
| 89 | − | |
| 90 | − s = I10NM_GET_REG32(imc, chan, res_cfg->offsets_scrub[0]); | |
| 91 | − d = I10NM_GET_REG32(imc, chan, res_cfg->offsets_demand[0]); | |
| 96 | + s = I10NM_GET_REG32(imc, chan, offsets_scrub[0]); | |
| 97 | + d = I10NM_GET_REG32(imc, chan, offsets_demand[0]); | |
| 98 | + if (offsets_demand2) | |
| 99 | + d2 = I10NM_GET_REG32(imc, chan, offsets_demand2[0]); | |
| 92 | 100 | |
| 93 | 101 | if (enable) { |
| 94 | 102 | /* Save default configurations */ |
| 95 | 103 | imc->chan[chan].retry_rd_err_log_s = s; |
| 96 | 104 | imc->chan[chan].retry_rd_err_log_d = d; |
| 105 | + if (offsets_demand2) | |
| 106 | + imc->chan[chan].retry_rd_err_log_d2 = d2; | |
| 97 | 107 | |
| 98 | 108 | s &= ~RETRY_RD_ERR_LOG_NOOVER_UC; |
| 99 | 109 | s |= RETRY_RD_ERR_LOG_EN; |
| 100 | 110 | d &= ~RETRY_RD_ERR_LOG_NOOVER_UC; |
| 101 | 111 | d |= RETRY_RD_ERR_LOG_EN; |
| 112 | + | |
| 113 | + if (offsets_demand2) { | |
| 114 | + d2 &= ~RETRY_RD_ERR_LOG_UC; | |
| 115 | + d2 |= RETRY_RD_ERR_LOG_NOOVER; | |
| 116 | + d2 |= RETRY_RD_ERR_LOG_EN; | |
| 117 | + } | |
| 102 | 118 | } else { |
| 103 | 119 | /* Restore default configurations */ |
| 104 | 120 | if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_UC) |
| @@ -113,23 +129,55 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable · 8 unmodified lines | ||
| 113 | 129 | d |= RETRY_RD_ERR_LOG_NOOVER; |
| 114 | 130 | if (!(imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_EN)) |
| 115 | 131 | d &= ~RETRY_RD_ERR_LOG_EN; |
| 132 | + | |
| 133 | + if (offsets_demand2) { | |
| 134 | + if (imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_UC) | |
| 135 | + d2 |= RETRY_RD_ERR_LOG_UC; | |
| 136 | + if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_NOOVER)) | |
| 137 | + d2 &= ~RETRY_RD_ERR_LOG_NOOVER; | |
| 138 | + if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_EN)) | |
| 139 | + d2 &= ~RETRY_RD_ERR_LOG_EN; | |
| 140 | + } | |
| 116 | 141 | } |
| 117 | 142 | |
| 118 | − I10NM_SET_REG32(imc, chan, res_cfg->offsets_scrub[0], s); | |
| 119 | − I10NM_SET_REG32(imc, chan, res_cfg->offsets_demand[0], d); | |
| 143 | + I10NM_SET_REG32(imc, chan, offsets_scrub[0], s); | |
| 144 | + I10NM_SET_REG32(imc, chan, offsets_demand[0], d); | |
| 145 | + if (offsets_demand2) | |
| 146 | + I10NM_SET_REG32(imc, chan, offsets_demand2[0], d2); | |
| 120 | 147 | } |
| 121 | 148 | |
| 122 | 149 | static void enable_retry_rd_err_log(bool enable) |
| 123 | 150 | { |
| 151 | + struct skx_imc *imc; | |
| 124 | 152 | struct skx_dev *d; |
| 125 | 153 | int i, j; |
| 126 | 154 | |
| 127 | 155 | edac_dbg(2, "\n"); |
| 128 | 156 | |
| 129 | 157 | list_for_each_entry(d, i10nm_edac_list, list) |
| 130 | − for (i = 0; i < I10NM_NUM_IMC; i++) | |
| 131 | − for (j = 0; j < I10NM_NUM_CHANNELS; j++) | |
| 132 | − __enable_retry_rd_err_log(&d->imc[i], j, enable); | |
| 158 | + for (i = 0; i < I10NM_NUM_IMC; i++) { | |
| 159 | + imc = &d->imc[i]; | |
| 160 | + if (!imc->mbase) | |
| 161 | + continue; | |
| 162 | + | |
| 163 | + for (j = 0; j < I10NM_NUM_CHANNELS; j++) { | |
| 164 | + if (imc->hbm_mc) { | |
| 165 | + __enable_retry_rd_err_log(imc, j, enable, | |
| 166 | + res_cfg->offsets_scrub_hbm0, | |
| 167 | + res_cfg->offsets_demand_hbm0, | |
| 168 | + NULL); | |
| 169 | + __enable_retry_rd_err_log(imc, j, enable, | |
| 170 | + res_cfg->offsets_scrub_hbm1, | |
| 171 | + res_cfg->offsets_demand_hbm1, | |
| 172 | + NULL); | |
| 173 | + } else { | |
| 174 | + __enable_retry_rd_err_log(imc, j, enable, | |
| 175 | + res_cfg->offsets_scrub, | |
| 176 | + res_cfg->offsets_demand, | |
| 177 | + res_cfg->offsets_demand2); | |
| 178 | + } | |
| 179 | + } | |
| 180 | + } | |
| 133 | 181 | } |
| 134 | 182 | |
| 135 | 183 | static void show_retry_rd_err_log(struct decoded_addr *res, char *msg, |
| @@ -138,14 +186,33 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg, · 2 unmodified lines | ||
| 138 | 186 | struct skx_imc *imc = &res->dev->imc[res->imc]; |
| 139 | 187 | u32 log0, log1, log2, log3, log4; |
| 140 | 188 | u32 corr0, corr1, corr2, corr3; |
| 189 | + u32 lxg0, lxg1, lxg3, lxg4; | |
| 190 | + u32 *xffsets = NULL; | |
| 141 | 191 | u64 log2a, log5; |
| 192 | + u64 lxg2a, lxg5; | |
| 142 | 193 | u32 *offsets; |
| 143 | − int n; | |
| 194 | + int n, pch; | |
| 144 | 195 | |
| 145 | 196 | if (!imc->mbase) |
| 146 | 197 | return; |
| 147 | 198 | |
| 148 | − offsets = scrub_err ? res_cfg->offsets_scrub : res_cfg->offsets_demand; | |
| 199 | + if (imc->hbm_mc) { | |
| 200 | + pch = res->cs & 1; | |
| 201 | + | |
| 202 | + if (pch) | |
| 203 | + offsets = scrub_err ? res_cfg->offsets_scrub_hbm1 : | |
| 204 | + res_cfg->offsets_demand_hbm1; | |
| 205 | + else | |
| 206 | + offsets = scrub_err ? res_cfg->offsets_scrub_hbm0 : | |
| 207 | + res_cfg->offsets_demand_hbm0; | |
| 208 | + } else { | |
| 209 | + if (scrub_err) { | |
| 210 | + offsets = res_cfg->offsets_scrub; | |
| 211 | + } else { | |
| 212 | + offsets = res_cfg->offsets_demand; | |
| 213 | + xffsets = res_cfg->offsets_demand2; | |
| 214 | + } | |
| 215 | + } | |
| 149 | 216 | |
| 150 | 217 | log0 = I10NM_GET_REG32(imc, res->channel, offsets[0]); |
| 151 | 218 | log1 = I10NM_GET_REG32(imc, res->channel, offsets[1]); |
| @@ -153,20 +220,52 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg, · 1 unmodified line | ||
| 153 | 220 | log4 = I10NM_GET_REG32(imc, res->channel, offsets[4]); |
| 154 | 221 | log5 = I10NM_GET_REG64(imc, res->channel, offsets[5]); |
| 155 | 222 | |
| 223 | + if (xffsets) { | |
| 224 | + lxg0 = I10NM_GET_REG32(imc, res->channel, xffsets[0]); | |
| 225 | + lxg1 = I10NM_GET_REG32(imc, res->channel, xffsets[1]); | |
| 226 | + lxg3 = I10NM_GET_REG32(imc, res->channel, xffsets[3]); | |
| 227 | + lxg4 = I10NM_GET_REG32(imc, res->channel, xffsets[4]); | |
| 228 | + lxg5 = I10NM_GET_REG64(imc, res->channel, xffsets[5]); | |
| 229 | + } | |
| 230 | + | |
| 156 | 231 | if (res_cfg->type == SPR) { |
| 157 | 232 | log2a = I10NM_GET_REG64(imc, res->channel, offsets[2]); |
| 158 | − n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx]", | |
| 233 | + n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx", | |
| 159 | 234 | log0, log1, log2a, log3, log4, log5); |
| 235 | + | |
| 236 | + if (len - n > 0) { | |
| 237 | + if (xffsets) { | |
| 238 | + lxg2a = I10NM_GET_REG64(imc, res->channel, xffsets[2]); | |
| 239 | + n += snprintf(msg + n, len - n, " %.8x %.8x %.16llx %.8x %.8x %.16llx]", | |
| 240 | + lxg0, lxg1, lxg2a, lxg3, lxg4, lxg5); | |
| 241 | + } else { | |
| 242 | + n += snprintf(msg + n, len - n, "]"); | |
| 243 | + } | |
| 244 | + } | |
| 160 | 245 | } else { |
| 161 | 246 | log2 = I10NM_GET_REG32(imc, res->channel, offsets[2]); |
| 162 | 247 | n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.8x %.8x %.8x %.16llx]", |
| 163 | 248 | log0, log1, log2, log3, log4, log5); |
| 164 | 249 | } |
| 165 | 250 | |
| 166 | − corr0 = I10NM_GET_REG32(imc, res->channel, 0x22c18); | |
| 167 | − corr1 = I10NM_GET_REG32(imc, res->channel, 0x22c1c); | |
| 168 | − corr2 = I10NM_GET_REG32(imc, res->channel, 0x22c20); | |
| 169 | − corr3 = I10NM_GET_REG32(imc, res->channel, 0x22c24); | |
| 251 | + if (imc->hbm_mc) { | |
| 252 | + if (pch) { | |
| 253 | + corr0 = I10NM_GET_REG32(imc, res->channel, 0x2c18); | |
| 254 | + corr1 = I10NM_GET_REG32(imc, res->channel, 0x2c1c); | |
| 255 | + corr2 = I10NM_GET_REG32(imc, res->channel, 0x2c20); | |
| 256 | + corr3 = I10NM_GET_REG32(imc, res->channel, 0x2c24); | |
| 257 | + } else { | |
| 258 | + corr0 = I10NM_GET_REG32(imc, res->channel, 0x2818); | |
| 259 | + corr1 = I10NM_GET_REG32(imc, res->channel, 0x281c); | |
| 260 | + corr2 = I10NM_GET_REG32(imc, res->channel, 0x2820); | |
| 261 | + corr3 = I10NM_GET_REG32(imc, res->channel, 0x2824); | |
| 262 | + } | |
| 263 | + } else { | |
| 264 | + corr0 = I10NM_GET_REG32(imc, res->channel, 0x22c18); | |
| 265 | + corr1 = I10NM_GET_REG32(imc, res->channel, 0x22c1c); | |
| 266 | + corr2 = I10NM_GET_REG32(imc, res->channel, 0x22c20); | |
| 267 | + corr3 = I10NM_GET_REG32(imc, res->channel, 0x22c24); | |
| 268 | + } | |
| 170 | 269 | |
| 171 | 270 | if (len - n > 0) |
| 172 | 271 | snprintf(msg + n, len - n, |
| @@ -177,9 +276,16 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg, · 4 unmodified lines | ||
| 177 | 276 | corr3 & 0xffff, corr3 >> 16); |
| 178 | 277 | |
| 179 | 278 | /* Clear status bits */ |
| 180 | − if (retry_rd_err_log == 2 && (log0 & RETRY_RD_ERR_LOG_OVER_UC_V)) { | |
| 181 | − log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V; | |
| 182 | − I10NM_SET_REG32(imc, res->channel, offsets[0], log0); | |
| 279 | + if (retry_rd_err_log == 2) { | |
| 280 | + if (log0 & RETRY_RD_ERR_LOG_OVER_UC_V) { | |
| 281 | + log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V; | |
| 282 | + I10NM_SET_REG32(imc, res->channel, offsets[0], log0); | |
| 283 | + } | |
| 284 | + | |
| 285 | + if (xffsets && (lxg0 & RETRY_RD_ERR_LOG_OVER_UC_V)) { | |
| 286 | + lxg0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V; | |
| 287 | + I10NM_SET_REG32(imc, res->channel, xffsets[0], lxg0); | |
| 288 | + } | |
| 183 | 289 | } |
| 184 | 290 | } |
| 185 | 291 | |
| @@ -231,6 +337,103 @@ static bool i10nm_check_2lm(struct res_config *cfg) · 45 unmodified lines | ||
| 231 | 337 | return false; |
| 232 | 338 | } |
| 233 | 339 | |
| 340 | +/* | |
| 341 | + * Check whether the error comes from DDRT by ICX/Tremont model specific error code. | |
| 342 | + * Refer to SDM vol3B 16.11.3 Intel IMC MC error codes for IA32_MCi_STATUS. | |
| 343 | + */ | |
| 344 | +static bool i10nm_mscod_is_ddrt(u32 mscod) | |
| 345 | +{ | |
| 346 | + switch (mscod) { | |
| 347 | + case 0x0106: case 0x0107: | |
| 348 | + case 0x0800: case 0x0804: | |
| 349 | + case 0x0806 ... 0x0808: | |
| 350 | + case 0x080a ... 0x080e: | |
| 351 | + case 0x0810: case 0x0811: | |
| 352 | + case 0x0816: case 0x081e: | |
| 353 | + case 0x081f: | |
| 354 | + return true; | |
| 355 | + } | |
| 356 | + | |
| 357 | + return false; | |
| 358 | +} | |
| 359 | + | |
| 360 | +static bool i10nm_mc_decode_available(struct mce *mce) | |
| 361 | +{ | |
| 362 | + u8 bank; | |
| 363 | + | |
| 364 | + if (!decoding_via_mca || mem_cfg_2lm) | |
| 365 | + return false; | |
| 366 | + | |
| 367 | + if ((mce->status & (MCI_STATUS_MISCV | MCI_STATUS_ADDRV)) | |
| 368 | + != (MCI_STATUS_MISCV | MCI_STATUS_ADDRV)) | |
| 369 | + return false; | |
| 370 | + | |
| 371 | + bank = mce->bank; | |
| 372 | + | |
| 373 | + switch (res_cfg->type) { | |
| 374 | + case I10NM: | |
| 375 | + if (bank < 13 || bank > 26) | |
| 376 | + return false; | |
| 377 | + | |
| 378 | + /* DDRT errors can't be decoded from MCA bank registers */ | |
| 379 | + if (MCI_MISC_ECC_MODE(mce->misc) == MCI_MISC_ECC_DDRT) | |
| 380 | + return false; | |
| 381 | + | |
| 382 | + if (i10nm_mscod_is_ddrt(MCI_STATUS_MSCOD(mce->status))) | |
| 383 | + return false; | |
| 384 | + | |
| 385 | + /* Check whether one of {13,14,17,18,21,22,25,26} */ | |
| 386 | + return ((bank - 13) & BIT(1)) == 0; | |
| 387 | + default: | |
| 388 | + return false; | |
| 389 | + } | |
| 390 | +} | |
| 391 | + | |
| 392 | +static bool i10nm_mc_decode(struct decoded_addr *res) | |
| 393 | +{ | |
| 394 | + struct mce *m = res->mce; | |
| 395 | + struct skx_dev *d; | |
| 396 | + u8 bank; | |
| 397 | + | |
| 398 | + if (!i10nm_mc_decode_available(m)) | |
| 399 | + return false; | |
| 400 | + | |
| 401 | + list_for_each_entry(d, i10nm_edac_list, list) { | |
| 402 | + if (d->imc[0].src_id == m->socketid) { | |
| 403 | + res->socket = m->socketid; | |
| 404 | + res->dev = d; | |
| 405 | + break; | |
| 406 | + } | |
| 407 | + } | |
| 408 | + | |
| 409 | + switch (res_cfg->type) { | |
| 410 | + case I10NM: | |
| 411 | + bank = m->bank - 13; | |
| 412 | + res->imc = bank / 4; | |
| 413 | + res->channel = bank % 2; | |
| 414 | + break; | |
| 415 | + default: | |
| 416 | + return false; | |
| 417 | + } | |
| 418 | + | |
| 419 | + if (!res->dev) { | |
| 420 | + skx_printk(KERN_ERR, "No device for src_id %d imc %d\n", | |
| 421 | + m->socketid, res->imc); | |
| 422 | + return false; | |
| 423 | + } | |
| 424 | + | |
| 425 | + res->column = GET_BITFIELD(m->misc, 9, 18) << 2; | |
| 426 | + res->row = GET_BITFIELD(m->misc, 19, 39); | |
| 427 | + res->bank_group = GET_BITFIELD(m->misc, 40, 41); | |
| 428 | + res->bank_address = GET_BITFIELD(m->misc, 42, 43); | |
| 429 | + res->bank_group |= GET_BITFIELD(m->misc, 44, 44) << 2; | |
| 430 | + res->rank = GET_BITFIELD(m->misc, 56, 58); | |
| 431 | + res->dimm = res->rank >> 2; | |
| 432 | + res->rank = res->rank % 4; | |
| 433 | + | |
| 434 | + return true; | |
| 435 | +} | |
| 436 | + | |
| 234 | 437 | static int i10nm_get_ddr_munits(void) |
| 235 | 438 | { |
| 236 | 439 | struct pci_dev *mdev; |
| @@ -420,7 +623,12 @@ static struct res_config spr_cfg = { · 183 unmodified lines | ||
| 420 | 623 | .sad_all_devfn = PCI_DEVFN(10, 0), |
| 421 | 624 | .sad_all_offset = 0x300, |
| 422 | 625 | .offsets_scrub = offsets_scrub_spr, |
| 626 | + .offsets_scrub_hbm0 = offsets_scrub_spr_hbm0, | |
| 627 | + .offsets_scrub_hbm1 = offsets_scrub_spr_hbm1, | |
| 423 | 628 | .offsets_demand = offsets_demand_spr, |
| 629 | + .offsets_demand2 = offsets_demand2_spr, | |
| 630 | + .offsets_demand_hbm0 = offsets_demand_spr_hbm0, | |
| 631 | + .offsets_demand_hbm1 = offsets_demand_spr_hbm1, | |
| 424 | 632 | }; |
| 425 | 633 | |
| 426 | 634 | static const struct x86_cpu_id i10nm_cpuids[] = { |
| @@ -574,7 +782,8 @@ static int __init i10nm_init(void) · 147 unmodified lines | ||
| 574 | 782 | return -ENODEV; |
| 575 | 783 | } |
| 576 | 784 | |
| 577 | − skx_set_mem_cfg(i10nm_check_2lm(cfg)); | |
| 785 | + mem_cfg_2lm = i10nm_check_2lm(cfg); | |
| 786 | + skx_set_mem_cfg(mem_cfg_2lm); | |
| 578 | 787 | |
| 579 | 788 | rc = i10nm_get_ddr_munits(); |
| 580 | 789 | |
| @@ -626,9 +835,11 @@ static int __init i10nm_init(void) · 45 unmodified lines | ||
| 626 | 835 | setup_i10nm_debug(); |
| 627 | 836 | |
| 628 | 837 | if (retry_rd_err_log && res_cfg->offsets_scrub && res_cfg->offsets_demand) { |
| 629 | − skx_set_decode(NULL, show_retry_rd_err_log); | |
| 838 | + skx_set_decode(i10nm_mc_decode, show_retry_rd_err_log); | |
| 630 | 839 | if (retry_rd_err_log == 2) |
| 631 | 840 | enable_retry_rd_err_log(true); |
| 841 | + } else { | |
| 842 | + skx_set_decode(i10nm_mc_decode, NULL); | |
| 632 | 843 | } |
| 633 | 844 | |
| 634 | 845 | i10nm_printk(KERN_INFO, "%s\n", I10NM_REVISION); |
| @@ -658,6 +869,34 @@ static void __exit i10nm_exit(void) · 23 unmodified lines | ||
| 658 | 869 | module_init(i10nm_init); |
| 659 | 870 | module_exit(i10nm_exit); |
| 660 | 871 | |
31 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 236 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 494 lines aren’t shown here.
This diff is large: its 1602 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 1103 lines aren’t shown here.
This diff is large: its 890 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 367 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 1669 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 196 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 1325 lines aren’t shown here.
This diff is large: its 445 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 426 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 266 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 428 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 405 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 236 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 356 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 317 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 318 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 315 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 1270 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 307 lines aren’t shown here.
This diff is large: its 784 lines aren’t shown here.
This diff is large: its 208 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 430 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 587 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 554 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 467 lines aren’t shown here.
This diff is large: its 460 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 370 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 329 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 470 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 540 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 315 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 382 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 656 lines aren’t shown here.
This diff is large: its 397 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 516 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 487 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 258 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 267 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 403 lines aren’t shown here.
This diff is large: its 1711 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 634 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 779 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 366 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 1074 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 382 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 441 lines aren’t shown here.
This diff is large: its 499 lines aren’t shown here.
This diff is large: its 2029 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 528 lines aren’t shown here.
This diff is large: its 1205 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 367 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 3141 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 289 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 410 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 282 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 259 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 256 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 755 lines aren’t shown here.
This diff is large: its 400 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 277 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 1323 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 209 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 758 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.