diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-01-19 07:57:33 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-01-19 07:57:33 -0500 |
commit | c86d95cb6b7ecda7b7d56e40c24b7d8b9bf9159a (patch) | |
tree | 3d868496a15be09dfb3a471e7b9dce24c0216d89 | |
parent | 388fdb8f882af67ff8394d9420c1e0e42ba35619 (diff) | |
parent | 8f05b9c65d817dd288da5f1c6ecc134b66f8a190 (diff) |
Merge tag 'asoc-v4.16-3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v4.16
Some final updates for the merge window, this brings in some
improvements to the ACPI GPIO handling for Intel and a bunch of fixes.
283 files changed, 3941 insertions, 1099 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index d6d862db3b5d..bfd29bc8d37a 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
@@ -375,3 +375,19 @@ Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | |||
375 | Description: information about CPUs heterogeneity. | 375 | Description: information about CPUs heterogeneity. |
376 | 376 | ||
377 | cpu_capacity: capacity of cpu#. | 377 | cpu_capacity: capacity of cpu#. |
378 | |||
379 | What: /sys/devices/system/cpu/vulnerabilities | ||
380 | /sys/devices/system/cpu/vulnerabilities/meltdown | ||
381 | /sys/devices/system/cpu/vulnerabilities/spectre_v1 | ||
382 | /sys/devices/system/cpu/vulnerabilities/spectre_v2 | ||
383 | Date: January 2018 | ||
384 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | ||
385 | Description: Information about CPU vulnerabilities | ||
386 | |||
387 | The files are named after the code names of CPU | ||
388 | vulnerabilities. The output of those files reflects the | ||
389 | state of the CPUs in the system. Possible output values: | ||
390 | |||
391 | "Not affected" CPU is not affected by the vulnerability | ||
392 | "Vulnerable" CPU is affected and no mitigation in effect | ||
393 | "Mitigation: $M" CPU is affected and mitigation $M is in effect | ||
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index af7104aaffd9..46b26bfee27b 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -713,9 +713,6 @@ | |||
713 | It will be ignored when crashkernel=X,high is not used | 713 | It will be ignored when crashkernel=X,high is not used |
714 | or memory reserved is below 4G. | 714 | or memory reserved is below 4G. |
715 | 715 | ||
716 | crossrelease_fullstack | ||
717 | [KNL] Allow to record full stack trace in cross-release | ||
718 | |||
719 | cryptomgr.notests | 716 | cryptomgr.notests |
720 | [KNL] Disable crypto self-tests | 717 | [KNL] Disable crypto self-tests |
721 | 718 | ||
@@ -2626,6 +2623,11 @@ | |||
2626 | nosmt [KNL,S390] Disable symmetric multithreading (SMT). | 2623 | nosmt [KNL,S390] Disable symmetric multithreading (SMT). |
2627 | Equivalent to smt=1. | 2624 | Equivalent to smt=1. |
2628 | 2625 | ||
2626 | nospectre_v2 [X86] Disable all mitigations for the Spectre variant 2 | ||
2627 | (indirect branch prediction) vulnerability. System may | ||
2628 | allow data leaks with this option, which is equivalent | ||
2629 | to spectre_v2=off. | ||
2630 | |||
2629 | noxsave [BUGS=X86] Disables x86 extended register state save | 2631 | noxsave [BUGS=X86] Disables x86 extended register state save |
2630 | and restore using xsave. The kernel will fallback to | 2632 | and restore using xsave. The kernel will fallback to |
2631 | enabling legacy floating-point and sse state. | 2633 | enabling legacy floating-point and sse state. |
@@ -2712,8 +2714,6 @@ | |||
2712 | steal time is computed, but won't influence scheduler | 2714 | steal time is computed, but won't influence scheduler |
2713 | behaviour | 2715 | behaviour |
2714 | 2716 | ||
2715 | nopti [X86-64] Disable kernel page table isolation | ||
2716 | |||
2717 | nolapic [X86-32,APIC] Do not enable or use the local APIC. | 2717 | nolapic [X86-32,APIC] Do not enable or use the local APIC. |
2718 | 2718 | ||
2719 | nolapic_timer [X86-32,APIC] Do not use the local APIC timer. | 2719 | nolapic_timer [X86-32,APIC] Do not use the local APIC timer. |
@@ -3100,6 +3100,12 @@ | |||
3100 | pcie_scan_all Scan all possible PCIe devices. Otherwise we | 3100 | pcie_scan_all Scan all possible PCIe devices. Otherwise we |
3101 | only look for one device below a PCIe downstream | 3101 | only look for one device below a PCIe downstream |
3102 | port. | 3102 | port. |
3103 | big_root_window Try to add a big 64bit memory window to the PCIe | ||
3104 | root complex on AMD CPUs. Some GFX hardware | ||
3105 | can resize a BAR to allow access to all VRAM. | ||
3106 | Adding the window is slightly risky (it may | ||
3107 | conflict with unreported devices), so this | ||
3108 | taints the kernel. | ||
3103 | 3109 | ||
3104 | pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power | 3110 | pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power |
3105 | Management. | 3111 | Management. |
@@ -3288,11 +3294,20 @@ | |||
3288 | pt. [PARIDE] | 3294 | pt. [PARIDE] |
3289 | See Documentation/blockdev/paride.txt. | 3295 | See Documentation/blockdev/paride.txt. |
3290 | 3296 | ||
3291 | pti= [X86_64] | 3297 | pti= [X86_64] Control Page Table Isolation of user and |
3292 | Control user/kernel address space isolation: | 3298 | kernel address spaces. Disabling this feature |
3293 | on - enable | 3299 | removes hardening, but improves performance of |
3294 | off - disable | 3300 | system calls and interrupts. |
3295 | auto - default setting | 3301 | |
3302 | on - unconditionally enable | ||
3303 | off - unconditionally disable | ||
3304 | auto - kernel detects whether your CPU model is | ||
3305 | vulnerable to issues that PTI mitigates | ||
3306 | |||
3307 | Not specifying this option is equivalent to pti=auto. | ||
3308 | |||
3309 | nopti [X86_64] | ||
3310 | Equivalent to pti=off | ||
3296 | 3311 | ||
3297 | pty.legacy_count= | 3312 | pty.legacy_count= |
3298 | [KNL] Number of legacy pty's. Overwrites compiled-in | 3313 | [KNL] Number of legacy pty's. Overwrites compiled-in |
@@ -3943,6 +3958,29 @@ | |||
3943 | sonypi.*= [HW] Sony Programmable I/O Control Device driver | 3958 | sonypi.*= [HW] Sony Programmable I/O Control Device driver |
3944 | See Documentation/laptops/sonypi.txt | 3959 | See Documentation/laptops/sonypi.txt |
3945 | 3960 | ||
3961 | spectre_v2= [X86] Control mitigation of Spectre variant 2 | ||
3962 | (indirect branch speculation) vulnerability. | ||
3963 | |||
3964 | on - unconditionally enable | ||
3965 | off - unconditionally disable | ||
3966 | auto - kernel detects whether your CPU model is | ||
3967 | vulnerable | ||
3968 | |||
3969 | Selecting 'on' will, and 'auto' may, choose a | ||
3970 | mitigation method at run time according to the | ||
3971 | CPU, the available microcode, the setting of the | ||
3972 | CONFIG_RETPOLINE configuration option, and the | ||
3973 | compiler with which the kernel was built. | ||
3974 | |||
3975 | Specific mitigations can also be selected manually: | ||
3976 | |||
3977 | retpoline - replace indirect branches | ||
3978 | retpoline,generic - google's original retpoline | ||
3979 | retpoline,amd - AMD-specific minimal thunk | ||
3980 | |||
3981 | Not specifying this option is equivalent to | ||
3982 | spectre_v2=auto. | ||
3983 | |||
3946 | spia_io_base= [HW,MTD] | 3984 | spia_io_base= [HW,MTD] |
3947 | spia_fio_base= | 3985 | spia_fio_base= |
3948 | spia_pedr= | 3986 | spia_pedr= |
diff --git a/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt index 601c518eddaa..4eb980bd0287 100644 --- a/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt | |||
@@ -1,10 +1,31 @@ | |||
1 | * Freescale MXS audio complex with SGTL5000 codec | 1 | * Freescale MXS audio complex with SGTL5000 codec |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: "fsl,mxs-audio-sgtl5000" | 4 | - compatible : "fsl,mxs-audio-sgtl5000" |
5 | - model: The user-visible name of this sound complex | 5 | - model : The user-visible name of this sound complex |
6 | - saif-controllers: The phandle list of the MXS SAIF controller | 6 | - saif-controllers : The phandle list of the MXS SAIF controller |
7 | - audio-codec: The phandle of the SGTL5000 audio codec | 7 | - audio-codec : The phandle of the SGTL5000 audio codec |
8 | - audio-routing : A list of the connections between audio components. | ||
9 | Each entry is a pair of strings, the first being the | ||
10 | connection's sink, the second being the connection's | ||
11 | source. Valid names could be power supplies, SGTL5000 | ||
12 | pins, and the jacks on the board: | ||
13 | |||
14 | Power supplies: | ||
15 | * Mic Bias | ||
16 | |||
17 | SGTL5000 pins: | ||
18 | * MIC_IN | ||
19 | * LINE_IN | ||
20 | * HP_OUT | ||
21 | * LINE_OUT | ||
22 | |||
23 | Board connectors: | ||
24 | * Mic Jack | ||
25 | * Line In Jack | ||
26 | * Headphone Jack | ||
27 | * Line Out Jack | ||
28 | * Ext Spk | ||
8 | 29 | ||
9 | Example: | 30 | Example: |
10 | 31 | ||
@@ -14,4 +35,8 @@ sound { | |||
14 | model = "imx28-evk-sgtl5000"; | 35 | model = "imx28-evk-sgtl5000"; |
15 | saif-controllers = <&saif0 &saif1>; | 36 | saif-controllers = <&saif0 &saif1>; |
16 | audio-codec = <&sgtl5000>; | 37 | audio-codec = <&sgtl5000>; |
38 | audio-routing = | ||
39 | "MIC_IN", "Mic Jack", | ||
40 | "Mic Jack", "Mic Bias", | ||
41 | "Headphone Jack", "HP_OUT"; | ||
17 | }; | 42 | }; |
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt index c0727dc36271..f2f3f8592a6f 100644 --- a/Documentation/filesystems/nilfs2.txt +++ b/Documentation/filesystems/nilfs2.txt | |||
@@ -25,8 +25,8 @@ available from the following download page. At least "mkfs.nilfs2", | |||
25 | cleaner or garbage collector) are required. Details on the tools are | 25 | cleaner or garbage collector) are required. Details on the tools are |
26 | described in the man pages included in the package. | 26 | described in the man pages included in the package. |
27 | 27 | ||
28 | Project web page: http://nilfs.sourceforge.net/ | 28 | Project web page: https://nilfs.sourceforge.io/ |
29 | Download page: http://nilfs.sourceforge.net/en/download.html | 29 | Download page: https://nilfs.sourceforge.io/en/download.html |
30 | List info: http://vger.kernel.org/vger-lists.html#linux-nilfs | 30 | List info: http://vger.kernel.org/vger-lists.html#linux-nilfs |
31 | 31 | ||
32 | Caveats | 32 | Caveats |
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index 262722d8867b..c4a293a03c33 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt | |||
@@ -200,10 +200,14 @@ module state. Dependency expressions have the following syntax: | |||
200 | <expr> ::= <symbol> (1) | 200 | <expr> ::= <symbol> (1) |
201 | <symbol> '=' <symbol> (2) | 201 | <symbol> '=' <symbol> (2) |
202 | <symbol> '!=' <symbol> (3) | 202 | <symbol> '!=' <symbol> (3) |
203 | '(' <expr> ')' (4) | 203 | <symbol1> '<' <symbol2> (4) |
204 | '!' <expr> (5) | 204 | <symbol1> '>' <symbol2> (4) |
205 | <expr> '&&' <expr> (6) | 205 | <symbol1> '<=' <symbol2> (4) |
206 | <expr> '||' <expr> (7) | 206 | <symbol1> '>=' <symbol2> (4) |
207 | '(' <expr> ')' (5) | ||
208 | '!' <expr> (6) | ||
209 | <expr> '&&' <expr> (7) | ||
210 | <expr> '||' <expr> (8) | ||
207 | 211 | ||
208 | Expressions are listed in decreasing order of precedence. | 212 | Expressions are listed in decreasing order of precedence. |
209 | 213 | ||
@@ -214,10 +218,13 @@ Expressions are listed in decreasing order of precedence. | |||
214 | otherwise 'n'. | 218 | otherwise 'n'. |
215 | (3) If the values of both symbols are equal, it returns 'n', | 219 | (3) If the values of both symbols are equal, it returns 'n', |
216 | otherwise 'y'. | 220 | otherwise 'y'. |
217 | (4) Returns the value of the expression. Used to override precedence. | 221 | (4) If value of <symbol1> is respectively lower, greater, lower-or-equal, |
218 | (5) Returns the result of (2-/expr/). | 222 | or greater-or-equal than value of <symbol2>, it returns 'y', |
219 | (6) Returns the result of min(/expr/, /expr/). | 223 | otherwise 'n'. |
220 | (7) Returns the result of max(/expr/, /expr/). | 224 | (5) Returns the value of the expression. Used to override precedence. |
225 | (6) Returns the result of (2-/expr/). | ||
226 | (7) Returns the result of min(/expr/, /expr/). | ||
227 | (8) Returns the result of max(/expr/, /expr/). | ||
221 | 228 | ||
222 | An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 | 229 | An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 |
223 | respectively for calculations). A menu entry becomes visible when its | 230 | respectively for calculations). A menu entry becomes visible when its |
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst index 66e620866245..7d4b15977d61 100644 --- a/Documentation/networking/index.rst +++ b/Documentation/networking/index.rst | |||
@@ -9,6 +9,7 @@ Contents: | |||
9 | batman-adv | 9 | batman-adv |
10 | kapi | 10 | kapi |
11 | z8530book | 11 | z8530book |
12 | msg_zerocopy | ||
12 | 13 | ||
13 | .. only:: subproject | 14 | .. only:: subproject |
14 | 15 | ||
@@ -16,4 +17,3 @@ Contents: | |||
16 | ======= | 17 | ======= |
17 | 18 | ||
18 | * :ref:`genindex` | 19 | * :ref:`genindex` |
19 | |||
diff --git a/Documentation/networking/msg_zerocopy.rst b/Documentation/networking/msg_zerocopy.rst index 77f6d7e25cfd..291a01264967 100644 --- a/Documentation/networking/msg_zerocopy.rst +++ b/Documentation/networking/msg_zerocopy.rst | |||
@@ -72,6 +72,10 @@ this flag, a process must first signal intent by setting a socket option: | |||
72 | if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one))) | 72 | if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one))) |
73 | error(1, errno, "setsockopt zerocopy"); | 73 | error(1, errno, "setsockopt zerocopy"); |
74 | 74 | ||
75 | Setting the socket option only works when the socket is in its initial | ||
76 | (TCP_CLOSED) state. Trying to set the option for a socket returned by accept(), | ||
77 | for example, will lead to an EBUSY error. In this case, the option should be set | ||
78 | to the listening socket and it will be inherited by the accepted sockets. | ||
75 | 79 | ||
76 | Transmission | 80 | Transmission |
77 | ------------ | 81 | ------------ |
diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 441a4b9b666f..5908a21fddb6 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt | |||
@@ -693,7 +693,7 @@ such specification consists of a number of lines with an inverval value | |||
693 | in each line. The rules stated above are best illustrated with an example: | 693 | in each line. The rules stated above are best illustrated with an example: |
694 | 694 | ||
695 | # mkdir functions/uvc.usb0/control/header/h | 695 | # mkdir functions/uvc.usb0/control/header/h |
696 | # cd functions/uvc.usb0/control/header/h | 696 | # cd functions/uvc.usb0/control/ |
697 | # ln -s header/h class/fs | 697 | # ln -s header/h class/fs |
698 | # ln -s header/h class/ss | 698 | # ln -s header/h class/ss |
699 | # mkdir -p functions/uvc.usb0/streaming/uncompressed/u/360p | 699 | # mkdir -p functions/uvc.usb0/streaming/uncompressed/u/360p |
diff --git a/Documentation/x86/pti.txt b/Documentation/x86/pti.txt new file mode 100644 index 000000000000..d11eff61fc9a --- /dev/null +++ b/Documentation/x86/pti.txt | |||
@@ -0,0 +1,186 @@ | |||
1 | Overview | ||
2 | ======== | ||
3 | |||
4 | Page Table Isolation (pti, previously known as KAISER[1]) is a | ||
5 | countermeasure against attacks on the shared user/kernel address | ||
6 | space such as the "Meltdown" approach[2]. | ||
7 | |||
8 | To mitigate this class of attacks, we create an independent set of | ||
9 | page tables for use only when running userspace applications. When | ||
10 | the kernel is entered via syscalls, interrupts or exceptions, the | ||
11 | page tables are switched to the full "kernel" copy. When the system | ||
12 | switches back to user mode, the user copy is used again. | ||
13 | |||
14 | The userspace page tables contain only a minimal amount of kernel | ||
15 | data: only what is needed to enter/exit the kernel such as the | ||
16 | entry/exit functions themselves and the interrupt descriptor table | ||
17 | (IDT). There are a few strictly unnecessary things that get mapped | ||
18 | such as the first C function when entering an interrupt (see | ||
19 | comments in pti.c). | ||
20 | |||
21 | This approach helps to ensure that side-channel attacks leveraging | ||
22 | the paging structures do not function when PTI is enabled. It can be | ||
23 | enabled by setting CONFIG_PAGE_TABLE_ISOLATION=y at compile time. | ||
24 | Once enabled at compile-time, it can be disabled at boot with the | ||
25 | 'nopti' or 'pti=' kernel parameters (see kernel-parameters.txt). | ||
26 | |||
27 | Page Table Management | ||
28 | ===================== | ||
29 | |||
30 | When PTI is enabled, the kernel manages two sets of page tables. | ||
31 | The first set is very similar to the single set which is present in | ||
32 | kernels without PTI. This includes a complete mapping of userspace | ||
33 | that the kernel can use for things like copy_to_user(). | ||
34 | |||
35 | Although _complete_, the user portion of the kernel page tables is | ||
36 | crippled by setting the NX bit in the top level. This ensures | ||
37 | that any missed kernel->user CR3 switch will immediately crash | ||
38 | userspace upon executing its first instruction. | ||
39 | |||
40 | The userspace page tables map only the kernel data needed to enter | ||
41 | and exit the kernel. This data is entirely contained in the 'struct | ||
42 | cpu_entry_area' structure which is placed in the fixmap which gives | ||
43 | each CPU's copy of the area a compile-time-fixed virtual address. | ||
44 | |||
45 | For new userspace mappings, the kernel makes the entries in its | ||
46 | page tables like normal. The only difference is when the kernel | ||
47 | makes entries in the top (PGD) level. In addition to setting the | ||
48 | entry in the main kernel PGD, a copy of the entry is made in the | ||
49 | userspace page tables' PGD. | ||
50 | |||
51 | This sharing at the PGD level also inherently shares all the lower | ||
52 | layers of the page tables. This leaves a single, shared set of | ||
53 | userspace page tables to manage. One PTE to lock, one set of | ||
54 | accessed bits, dirty bits, etc... | ||
55 | |||
56 | Overhead | ||
57 | ======== | ||
58 | |||
59 | Protection against side-channel attacks is important. But, | ||
60 | this protection comes at a cost: | ||
61 | |||
62 | 1. Increased Memory Use | ||
63 | a. Each process now needs an order-1 PGD instead of order-0. | ||
64 | (Consumes an additional 4k per process). | ||
65 | b. The 'cpu_entry_area' structure must be 2MB in size and 2MB | ||
66 | aligned so that it can be mapped by setting a single PMD | ||
67 | entry. This consumes nearly 2MB of RAM once the kernel | ||
68 | is decompressed, but no space in the kernel image itself. | ||
69 | |||
70 | 2. Runtime Cost | ||
71 | a. CR3 manipulation to switch between the page table copies | ||
72 | must be done at interrupt, syscall, and exception entry | ||
73 | and exit (it can be skipped when the kernel is interrupted, | ||
74 | though.) Moves to CR3 are on the order of a hundred | ||
75 | cycles, and are required at every entry and exit. | ||
76 | b. A "trampoline" must be used for SYSCALL entry. This | ||
77 | trampoline depends on a smaller set of resources than the | ||
78 | non-PTI SYSCALL entry code, so requires mapping fewer | ||
79 | things into the userspace page tables. The downside is | ||
80 | that stacks must be switched at entry time. | ||
81 | d. Global pages are disabled for all kernel structures not | ||
82 | mapped into both kernel and userspace page tables. This | ||
83 | feature of the MMU allows different processes to share TLB | ||
84 | entries mapping the kernel. Losing the feature means more | ||
85 | TLB misses after a context switch. The actual loss of | ||
86 | performance is very small, however, never exceeding 1%. | ||
87 | d. Process Context IDentifiers (PCID) is a CPU feature that | ||
88 | allows us to skip flushing the entire TLB when switching page | ||
89 | tables by setting a special bit in CR3 when the page tables | ||
90 | are changed. This makes switching the page tables (at context | ||
91 | switch, or kernel entry/exit) cheaper. But, on systems with | ||
92 | PCID support, the context switch code must flush both the user | ||
93 | and kernel entries out of the TLB. The user PCID TLB flush is | ||
94 | deferred until the exit to userspace, minimizing the cost. | ||
95 | See intel.com/sdm for the gory PCID/INVPCID details. | ||
96 | e. The userspace page tables must be populated for each new | ||
97 | process. Even without PTI, the shared kernel mappings | ||
98 | are created by copying top-level (PGD) entries into each | ||
99 | new process. But, with PTI, there are now *two* kernel | ||
100 | mappings: one in the kernel page tables that maps everything | ||
101 | and one for the entry/exit structures. At fork(), we need to | ||
102 | copy both. | ||
103 | f. In addition to the fork()-time copying, there must also | ||
104 | be an update to the userspace PGD any time a set_pgd() is done | ||
105 | on a PGD used to map userspace. This ensures that the kernel | ||
106 | and userspace copies always map the same userspace | ||
107 | memory. | ||
108 | g. On systems without PCID support, each CR3 write flushes | ||
109 | the entire TLB. That means that each syscall, interrupt | ||
110 | or exception flushes the TLB. | ||
111 | h. INVPCID is a TLB-flushing instruction which allows flushing | ||
112 | of TLB entries for non-current PCIDs. Some systems support | ||
113 | PCIDs, but do not support INVPCID. On these systems, addresses | ||
114 | can only be flushed from the TLB for the current PCID. When | ||
115 | flushing a kernel address, we need to flush all PCIDs, so a | ||
116 | single kernel address flush will require a TLB-flushing CR3 | ||
117 | write upon the next use of every PCID. | ||
118 | |||
119 | Possible Future Work | ||
120 | ==================== | ||
121 | 1. We can be more careful about not actually writing to CR3 | ||
122 | unless its value is actually changed. | ||
123 | 2. Allow PTI to be enabled/disabled at runtime in addition to the | ||
124 | boot-time switching. | ||
125 | |||
126 | Testing | ||
127 | ======== | ||
128 | |||
129 | To test stability of PTI, the following test procedure is recommended, | ||
130 | ideally doing all of these in parallel: | ||
131 | |||
132 | 1. Set CONFIG_DEBUG_ENTRY=y | ||
133 | 2. Run several copies of all of the tools/testing/selftests/x86/ tests | ||
134 | (excluding MPX and protection_keys) in a loop on multiple CPUs for | ||
135 | several minutes. These tests frequently uncover corner cases in the | ||
136 | kernel entry code. In general, old kernels might cause these tests | ||
137 | themselves to crash, but they should never crash the kernel. | ||
138 | 3. Run the 'perf' tool in a mode (top or record) that generates many | ||
139 | frequent performance monitoring non-maskable interrupts (see "NMI" | ||
140 | in /proc/interrupts). This exercises the NMI entry/exit code which | ||
141 | is known to trigger bugs in code paths that did not expect to be | ||
142 | interrupted, including nested NMIs. Using "-c" boosts the rate of | ||
143 | NMIs, and using two -c with separate counters encourages nested NMIs | ||
144 | and less deterministic behavior. | ||
145 | |||
146 | while true; do perf record -c 10000 -e instructions,cycles -a sleep 10; done | ||
147 | |||
148 | 4. Launch a KVM virtual machine. | ||
149 | 5. Run 32-bit binaries on systems supporting the SYSCALL instruction. | ||
150 | This has been a lightly-tested code path and needs extra scrutiny. | ||
151 | |||
152 | Debugging | ||
153 | ========= | ||
154 | |||
155 | Bugs in PTI cause a few different signatures of crashes | ||
156 | that are worth noting here. | ||
157 | |||
158 | * Failures of the selftests/x86 code. Usually a bug in one of the | ||
159 | more obscure corners of entry_64.S | ||
160 | * Crashes in early boot, especially around CPU bringup. Bugs | ||
161 | in the trampoline code or mappings cause these. | ||
162 | * Crashes at the first interrupt. Caused by bugs in entry_64.S, | ||
163 | like screwing up a page table switch. Also caused by | ||
164 | incorrectly mapping the IRQ handler entry code. | ||
165 | * Crashes at the first NMI. The NMI code is separate from main | ||
166 | interrupt handlers and can have bugs that do not affect | ||
167 | normal interrupts. Also caused by incorrectly mapping NMI | ||
168 | code. NMIs that interrupt the entry code must be very | ||
169 | careful and can be the cause of crashes that show up when | ||
170 | running perf. | ||
171 | * Kernel crashes at the first exit to userspace. entry_64.S | ||
172 | bugs, or failing to map some of the exit code. | ||
173 | * Crashes at first interrupt that interrupts userspace. The paths | ||
174 | in entry_64.S that return to userspace are sometimes separate | ||
175 | from the ones that return to the kernel. | ||
176 | * Double faults: overflowing the kernel stack because of page | ||
177 | faults upon page faults. Caused by touching non-pti-mapped | ||
178 | data in the entry code, or forgetting to switch to kernel | ||
179 | CR3 before calling into C functions which are not pti-mapped. | ||
180 | * Userspace segfaults early in boot, sometimes manifesting | ||
181 | as mount(8) failing to mount the rootfs. These have | ||
182 | tended to be TLB invalidation issues. Usually invalidating | ||
183 | the wrong PCID, or otherwise missing an invalidation. | ||
184 | |||
185 | 1. https://gruss.cc/files/kaiser.pdf | ||
186 | 2. https://meltdownattack.com/meltdown.pdf | ||
diff --git a/MAINTAINERS b/MAINTAINERS index f4800a4c5065..49f72c59fea6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9638,8 +9638,8 @@ F: include/uapi/linux/sunrpc/ | |||
9638 | NILFS2 FILESYSTEM | 9638 | NILFS2 FILESYSTEM |
9639 | M: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 9639 | M: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> |
9640 | L: linux-nilfs@vger.kernel.org | 9640 | L: linux-nilfs@vger.kernel.org |
9641 | W: http://nilfs.sourceforge.net/ | 9641 | W: https://nilfs.sourceforge.io/ |
9642 | W: http://nilfs.osdn.jp/ | 9642 | W: https://nilfs.osdn.jp/ |
9643 | T: git git://github.com/konis/nilfs2.git | 9643 | T: git git://github.com/konis/nilfs2.git |
9644 | S: Supported | 9644 | S: Supported |
9645 | F: Documentation/filesystems/nilfs2.txt | 9645 | F: Documentation/filesystems/nilfs2.txt |
@@ -10135,7 +10135,7 @@ F: drivers/irqchip/irq-ompic.c | |||
10135 | F: drivers/irqchip/irq-or1k-* | 10135 | F: drivers/irqchip/irq-or1k-* |
10136 | 10136 | ||
10137 | OPENVSWITCH | 10137 | OPENVSWITCH |
10138 | M: Pravin Shelar <pshelar@nicira.com> | 10138 | M: Pravin B Shelar <pshelar@ovn.org> |
10139 | L: netdev@vger.kernel.org | 10139 | L: netdev@vger.kernel.org |
10140 | L: dev@openvswitch.org | 10140 | L: dev@openvswitch.org |
10141 | W: http://openvswitch.org | 10141 | W: http://openvswitch.org |
@@ -2,7 +2,7 @@ | |||
2 | VERSION = 4 | 2 | VERSION = 4 |
3 | PATCHLEVEL = 15 | 3 | PATCHLEVEL = 15 |
4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
5 | EXTRAVERSION = -rc7 | 5 | EXTRAVERSION = -rc8 |
6 | NAME = Fearless Coyote | 6 | NAME = Fearless Coyote |
7 | 7 | ||
8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
@@ -484,26 +484,6 @@ CLANG_GCC_TC := --gcc-toolchain=$(GCC_TOOLCHAIN) | |||
484 | endif | 484 | endif |
485 | KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) | 485 | KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) |
486 | KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) | 486 | KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) |
487 | KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) | ||
488 | KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable) | ||
489 | KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier) | ||
490 | KBUILD_CFLAGS += $(call cc-disable-warning, gnu) | ||
491 | KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) | ||
492 | # Quiet clang warning: comparison of unsigned expression < 0 is always false | ||
493 | KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare) | ||
494 | # CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the | ||
495 | # source of a reference will be _MergedGlobals and not on of the whitelisted names. | ||
496 | # See modpost pattern 2 | ||
497 | KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,) | ||
498 | KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior) | ||
499 | KBUILD_CFLAGS += $(call cc-option, -no-integrated-as) | ||
500 | KBUILD_AFLAGS += $(call cc-option, -no-integrated-as) | ||
501 | else | ||
502 | |||
503 | # These warnings generated too much noise in a regular build. | ||
504 | # Use make W=1 to enable them (see scripts/Makefile.extrawarn) | ||
505 | KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) | ||
506 | KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) | ||
507 | endif | 487 | endif |
508 | 488 | ||
509 | ifeq ($(config-targets),1) | 489 | ifeq ($(config-targets),1) |
@@ -716,6 +696,29 @@ ifdef CONFIG_CC_STACKPROTECTOR | |||
716 | endif | 696 | endif |
717 | KBUILD_CFLAGS += $(stackp-flag) | 697 | KBUILD_CFLAGS += $(stackp-flag) |
718 | 698 | ||
699 | ifeq ($(cc-name),clang) | ||
700 | KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) | ||
701 | KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable) | ||
702 | KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier) | ||
703 | KBUILD_CFLAGS += $(call cc-disable-warning, gnu) | ||
704 | KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) | ||
705 | # Quiet clang warning: comparison of unsigned expression < 0 is always false | ||
706 | KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare) | ||
707 | # CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the | ||
708 | # source of a reference will be _MergedGlobals and not on of the whitelisted names. | ||
709 | # See modpost pattern 2 | ||
710 | KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,) | ||
711 | KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior) | ||
712 | KBUILD_CFLAGS += $(call cc-option, -no-integrated-as) | ||
713 | KBUILD_AFLAGS += $(call cc-option, -no-integrated-as) | ||
714 | else | ||
715 | |||
716 | # These warnings generated too much noise in a regular build. | ||
717 | # Use make W=1 to enable them (see scripts/Makefile.extrawarn) | ||
718 | KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) | ||
719 | KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) | ||
720 | endif | ||
721 | |||
719 | ifdef CONFIG_FRAME_POINTER | 722 | ifdef CONFIG_FRAME_POINTER |
720 | KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls | 723 | KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls |
721 | else | 724 | else |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index c6ecb97151a2..9025699049ca 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -88,7 +88,7 @@ void vtime_flush(struct task_struct *tsk) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | if (ti->softirq_time) { | 90 | if (ti->softirq_time) { |
91 | delta = cycle_to_nsec(ti->softirq_time)); | 91 | delta = cycle_to_nsec(ti->softirq_time); |
92 | account_system_index_time(tsk, delta, CPUTIME_SOFTIRQ); | 92 | account_system_index_time(tsk, delta, CPUTIME_SOFTIRQ); |
93 | } | 93 | } |
94 | 94 | ||
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index c7ed26029cbb..e68e6e04063a 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S | |||
@@ -235,6 +235,7 @@ LEAF(mips_cps_core_init) | |||
235 | has_mt t0, 3f | 235 | has_mt t0, 3f |
236 | 236 | ||
237 | .set push | 237 | .set push |
238 | .set MIPS_ISA_LEVEL_RAW | ||
238 | .set mt | 239 | .set mt |
239 | 240 | ||
240 | /* Only allow 1 TC per VPE to execute... */ | 241 | /* Only allow 1 TC per VPE to execute... */ |
@@ -388,6 +389,7 @@ LEAF(mips_cps_boot_vpes) | |||
388 | #elif defined(CONFIG_MIPS_MT) | 389 | #elif defined(CONFIG_MIPS_MT) |
389 | 390 | ||
390 | .set push | 391 | .set push |
392 | .set MIPS_ISA_LEVEL_RAW | ||
391 | .set mt | 393 | .set mt |
392 | 394 | ||
393 | /* If the core doesn't support MT then return */ | 395 | /* If the core doesn't support MT then return */ |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 45d0b6b037ee..57028d49c202 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -705,6 +705,18 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) | |||
705 | struct task_struct *t; | 705 | struct task_struct *t; |
706 | int max_users; | 706 | int max_users; |
707 | 707 | ||
708 | /* If nothing to change, return right away, successfully. */ | ||
709 | if (value == mips_get_process_fp_mode(task)) | ||
710 | return 0; | ||
711 | |||
712 | /* Only accept a mode change if 64-bit FP enabled for o32. */ | ||
713 | if (!IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT)) | ||
714 | return -EOPNOTSUPP; | ||
715 | |||
716 | /* And only for o32 tasks. */ | ||
717 | if (IS_ENABLED(CONFIG_64BIT) && !test_thread_flag(TIF_32BIT_REGS)) | ||
718 | return -EOPNOTSUPP; | ||
719 | |||
708 | /* Check the value is valid */ | 720 | /* Check the value is valid */ |
709 | if (value & ~known_bits) | 721 | if (value & ~known_bits) |
710 | return -EOPNOTSUPP; | 722 | return -EOPNOTSUPP; |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index efbd8df8b665..0b23b1ad99e6 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -419,63 +419,160 @@ static int gpr64_set(struct task_struct *target, | |||
419 | 419 | ||
420 | #endif /* CONFIG_64BIT */ | 420 | #endif /* CONFIG_64BIT */ |
421 | 421 | ||
422 | /* | ||
423 | * Copy the floating-point context to the supplied NT_PRFPREG buffer, | ||
424 | * !CONFIG_CPU_HAS_MSA variant. FP context's general register slots | ||
425 | * correspond 1:1 to buffer slots. Only general registers are copied. | ||
426 | */ | ||
427 | static int fpr_get_fpa(struct task_struct *target, | ||
428 | unsigned int *pos, unsigned int *count, | ||
429 | void **kbuf, void __user **ubuf) | ||
430 | { | ||
431 | return user_regset_copyout(pos, count, kbuf, ubuf, | ||
432 | &target->thread.fpu, | ||
433 | 0, NUM_FPU_REGS * sizeof(elf_fpreg_t)); | ||
434 | } | ||
435 | |||
436 | /* | ||
437 | * Copy the floating-point context to the supplied NT_PRFPREG buffer, | ||
438 | * CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's | ||
439 | * general register slots are copied to buffer slots. Only general | ||
440 | * registers are copied. | ||
441 | */ | ||
442 | static int fpr_get_msa(struct task_struct *target, | ||
443 | unsigned int *pos, unsigned int *count, | ||
444 | void **kbuf, void __user **ubuf) | ||
445 | { | ||
446 | unsigned int i; | ||
447 | u64 fpr_val; | ||
448 | int err; | ||
449 | |||
450 | BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); | ||
451 | for (i = 0; i < NUM_FPU_REGS; i++) { | ||
452 | fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0); | ||
453 | err = user_regset_copyout(pos, count, kbuf, ubuf, | ||
454 | &fpr_val, i * sizeof(elf_fpreg_t), | ||
455 | (i + 1) * sizeof(elf_fpreg_t)); | ||
456 | if (err) | ||
457 | return err; | ||
458 | } | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | /* | ||
464 | * Copy the floating-point context to the supplied NT_PRFPREG buffer. | ||
465 | * Choose the appropriate helper for general registers, and then copy | ||
466 | * the FCSR register separately. | ||
467 | */ | ||
422 | static int fpr_get(struct task_struct *target, | 468 | static int fpr_get(struct task_struct *target, |
423 | const struct user_regset *regset, | 469 | const struct user_regset *regset, |
424 | unsigned int pos, unsigned int count, | 470 | unsigned int pos, unsigned int count, |
425 | void *kbuf, void __user *ubuf) | 471 | void *kbuf, void __user *ubuf) |
426 | { | 472 | { |
427 | unsigned i; | 473 | const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); |
428 | int err; | 474 | int err; |
429 | u64 fpr_val; | ||
430 | 475 | ||
431 | /* XXX fcr31 */ | 476 | if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) |
477 | err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf); | ||
478 | else | ||
479 | err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf); | ||
480 | if (err) | ||
481 | return err; | ||
432 | 482 | ||
433 | if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) | 483 | err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
434 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 484 | &target->thread.fpu.fcr31, |
435 | &target->thread.fpu, | 485 | fcr31_pos, fcr31_pos + sizeof(u32)); |
436 | 0, sizeof(elf_fpregset_t)); | ||
437 | 486 | ||
438 | for (i = 0; i < NUM_FPU_REGS; i++) { | 487 | return err; |
439 | fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0); | 488 | } |
440 | err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 489 | |
441 | &fpr_val, i * sizeof(elf_fpreg_t), | 490 | /* |
442 | (i + 1) * sizeof(elf_fpreg_t)); | 491 | * Copy the supplied NT_PRFPREG buffer to the floating-point context, |
492 | * !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP | ||
493 | * context's general register slots. Only general registers are copied. | ||
494 | */ | ||
495 | static int fpr_set_fpa(struct task_struct *target, | ||
496 | unsigned int *pos, unsigned int *count, | ||
497 | const void **kbuf, const void __user **ubuf) | ||
498 | { | ||
499 | return user_regset_copyin(pos, count, kbuf, ubuf, | ||
500 | &target->thread.fpu, | ||
501 | 0, NUM_FPU_REGS * sizeof(elf_fpreg_t)); | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Copy the supplied NT_PRFPREG buffer to the floating-point context, | ||
506 | * CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64 | ||
507 | * bits only of FP context's general register slots. Only general | ||
508 | * registers are copied. | ||
509 | */ | ||
510 | static int fpr_set_msa(struct task_struct *target, | ||
511 | unsigned int *pos, unsigned int *count, | ||
512 | const void **kbuf, const void __user **ubuf) | ||
513 | { | ||
514 | unsigned int i; | ||
515 | u64 fpr_val; | ||
516 | int err; | ||
517 | |||
518 | BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); | ||
519 | for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) { | ||
520 | err = user_regset_copyin(pos, count, kbuf, ubuf, | ||
521 | &fpr_val, i * sizeof(elf_fpreg_t), | ||
522 | (i + 1) * sizeof(elf_fpreg_t)); | ||
443 | if (err) | 523 | if (err) |
444 | return err; | 524 | return err; |
525 | set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val); | ||
445 | } | 526 | } |
446 | 527 | ||
447 | return 0; | 528 | return 0; |
448 | } | 529 | } |
449 | 530 | ||
531 | /* | ||
532 | * Copy the supplied NT_PRFPREG buffer to the floating-point context. | ||
533 | * Choose the appropriate helper for general registers, and then copy | ||
534 | * the FCSR register separately. | ||
535 | * | ||
536 | * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0', | ||
537 | * which is supposed to have been guaranteed by the kernel before | ||
538 | * calling us, e.g. in `ptrace_regset'. We enforce that requirement, | ||
539 | * so that we can safely avoid preinitializing temporaries for | ||
540 | * partial register writes. | ||
541 | */ | ||
450 | static int fpr_set(struct task_struct *target, | 542 | static int fpr_set(struct task_struct *target, |
451 | const struct user_regset *regset, | 543 | const struct user_regset *regset, |
452 | unsigned int pos, unsigned int count, | 544 | unsigned int pos, unsigned int count, |
453 | const void *kbuf, const void __user *ubuf) | 545 | const void *kbuf, const void __user *ubuf) |
454 | { | 546 | { |
455 | unsigned i; | 547 | const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); |
548 | u32 fcr31; | ||
456 | int err; | 549 | int err; |
457 | u64 fpr_val; | ||
458 | 550 | ||
459 | /* XXX fcr31 */ | 551 | BUG_ON(count % sizeof(elf_fpreg_t)); |
552 | |||
553 | if (pos + count > sizeof(elf_fpregset_t)) | ||
554 | return -EIO; | ||
460 | 555 | ||
461 | init_fp_ctx(target); | 556 | init_fp_ctx(target); |
462 | 557 | ||
463 | if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) | 558 | if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) |
464 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 559 | err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf); |
465 | &target->thread.fpu, | 560 | else |
466 | 0, sizeof(elf_fpregset_t)); | 561 | err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf); |
562 | if (err) | ||
563 | return err; | ||
467 | 564 | ||
468 | BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); | 565 | if (count > 0) { |
469 | for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) { | ||
470 | err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 566 | err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
471 | &fpr_val, i * sizeof(elf_fpreg_t), | 567 | &fcr31, |
472 | (i + 1) * sizeof(elf_fpreg_t)); | 568 | fcr31_pos, fcr31_pos + sizeof(u32)); |
473 | if (err) | 569 | if (err) |
474 | return err; | 570 | return err; |
475 | set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val); | 571 | |
572 | ptrace_setfcr31(target, fcr31); | ||
476 | } | 573 | } |
477 | 574 | ||
478 | return 0; | 575 | return err; |
479 | } | 576 | } |
480 | 577 | ||
481 | enum mips_regset { | 578 | enum mips_regset { |
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h index a703452d67b6..555e22d5e07f 100644 --- a/arch/powerpc/include/asm/exception-64e.h +++ b/arch/powerpc/include/asm/exception-64e.h | |||
@@ -209,5 +209,11 @@ exc_##label##_book3e: | |||
209 | ori r3,r3,vector_offset@l; \ | 209 | ori r3,r3,vector_offset@l; \ |
210 | mtspr SPRN_IVOR##vector_number,r3; | 210 | mtspr SPRN_IVOR##vector_number,r3; |
211 | 211 | ||
212 | #define RFI_TO_KERNEL \ | ||
213 | rfi | ||
214 | |||
215 | #define RFI_TO_USER \ | ||
216 | rfi | ||
217 | |||
212 | #endif /* _ASM_POWERPC_EXCEPTION_64E_H */ | 218 | #endif /* _ASM_POWERPC_EXCEPTION_64E_H */ |
213 | 219 | ||
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index b27205297e1d..7197b179c1b1 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
@@ -74,6 +74,59 @@ | |||
74 | */ | 74 | */ |
75 | #define EX_R3 EX_DAR | 75 | #define EX_R3 EX_DAR |
76 | 76 | ||
77 | /* | ||
78 | * Macros for annotating the expected destination of (h)rfid | ||
79 | * | ||
80 | * The nop instructions allow us to insert one or more instructions to flush the | ||
81 | * L1-D cache when returning to userspace or a guest. | ||
82 | */ | ||
83 | #define RFI_FLUSH_SLOT \ | ||
84 | RFI_FLUSH_FIXUP_SECTION; \ | ||
85 | nop; \ | ||
86 | nop; \ | ||
87 | nop | ||
88 | |||
89 | #define RFI_TO_KERNEL \ | ||
90 | rfid | ||
91 | |||
92 | #define RFI_TO_USER \ | ||
93 | RFI_FLUSH_SLOT; \ | ||
94 | rfid; \ | ||
95 | b rfi_flush_fallback | ||
96 | |||
97 | #define RFI_TO_USER_OR_KERNEL \ | ||
98 | RFI_FLUSH_SLOT; \ | ||
99 | rfid; \ | ||
100 | b rfi_flush_fallback | ||
101 | |||
102 | #define RFI_TO_GUEST \ | ||
103 | RFI_FLUSH_SLOT; \ | ||
104 | rfid; \ | ||
105 | b rfi_flush_fallback | ||
106 | |||
107 | #define HRFI_TO_KERNEL \ | ||
108 | hrfid | ||
109 | |||
110 | #define HRFI_TO_USER \ | ||
111 | RFI_FLUSH_SLOT; \ | ||
112 | hrfid; \ | ||
113 | b hrfi_flush_fallback | ||
114 | |||
115 | #define HRFI_TO_USER_OR_KERNEL \ | ||
116 | RFI_FLUSH_SLOT; \ | ||
117 | hrfid; \ | ||
118 | b hrfi_flush_fallback | ||
119 | |||
120 | #define HRFI_TO_GUEST \ | ||
121 | RFI_FLUSH_SLOT; \ | ||
122 | hrfid; \ | ||
123 | b hrfi_flush_fallback | ||
124 | |||
125 | #define HRFI_TO_UNKNOWN \ | ||
126 | RFI_FLUSH_SLOT; \ | ||
127 | hrfid; \ | ||
128 | b hrfi_flush_fallback | ||
129 | |||
77 | #ifdef CONFIG_RELOCATABLE | 130 | #ifdef CONFIG_RELOCATABLE |
78 | #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ | 131 | #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ |
79 | mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ | 132 | mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ |
@@ -218,7 +271,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | |||
218 | mtspr SPRN_##h##SRR0,r12; \ | 271 | mtspr SPRN_##h##SRR0,r12; \ |
219 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ | 272 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ |
220 | mtspr SPRN_##h##SRR1,r10; \ | 273 | mtspr SPRN_##h##SRR1,r10; \ |
221 | h##rfid; \ | 274 | h##RFI_TO_KERNEL; \ |
222 | b . /* prevent speculative execution */ | 275 | b . /* prevent speculative execution */ |
223 | #define EXCEPTION_PROLOG_PSERIES_1(label, h) \ | 276 | #define EXCEPTION_PROLOG_PSERIES_1(label, h) \ |
224 | __EXCEPTION_PROLOG_PSERIES_1(label, h) | 277 | __EXCEPTION_PROLOG_PSERIES_1(label, h) |
@@ -232,7 +285,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | |||
232 | mtspr SPRN_##h##SRR0,r12; \ | 285 | mtspr SPRN_##h##SRR0,r12; \ |
233 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ | 286 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ |
234 | mtspr SPRN_##h##SRR1,r10; \ | 287 | mtspr SPRN_##h##SRR1,r10; \ |
235 | h##rfid; \ | 288 | h##RFI_TO_KERNEL; \ |
236 | b . /* prevent speculative execution */ | 289 | b . /* prevent speculative execution */ |
237 | 290 | ||
238 | #define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \ | 291 | #define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \ |
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index 8f88f771cc55..1e82eb3caabd 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h | |||
@@ -187,7 +187,20 @@ label##3: \ | |||
187 | FTR_ENTRY_OFFSET label##1b-label##3b; \ | 187 | FTR_ENTRY_OFFSET label##1b-label##3b; \ |
188 | .popsection; | 188 | .popsection; |
189 | 189 | ||
190 | #define RFI_FLUSH_FIXUP_SECTION \ | ||
191 | 951: \ | ||
192 | .pushsection __rfi_flush_fixup,"a"; \ | ||
193 | .align 2; \ | ||
194 | 952: \ | ||
195 | FTR_ENTRY_OFFSET 951b-952b; \ | ||
196 | .popsection; | ||
197 | |||
198 | |||
190 | #ifndef __ASSEMBLY__ | 199 | #ifndef __ASSEMBLY__ |
200 | #include <linux/types.h> | ||
201 | |||
202 | extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; | ||
203 | |||
191 | void apply_feature_fixups(void); | 204 | void apply_feature_fixups(void); |
192 | void setup_feature_keys(void); | 205 | void setup_feature_keys(void); |
193 | #endif | 206 | #endif |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index a409177be8bd..f0461618bf7b 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -241,6 +241,7 @@ | |||
241 | #define H_GET_HCA_INFO 0x1B8 | 241 | #define H_GET_HCA_INFO 0x1B8 |
242 | #define H_GET_PERF_COUNT 0x1BC | 242 | #define H_GET_PERF_COUNT 0x1BC |
243 | #define H_MANAGE_TRACE 0x1C0 | 243 | #define H_MANAGE_TRACE 0x1C0 |
244 | #define H_GET_CPU_CHARACTERISTICS 0x1C8 | ||
244 | #define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 | 245 | #define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 |
245 | #define H_QUERY_INT_STATE 0x1E4 | 246 | #define H_QUERY_INT_STATE 0x1E4 |
246 | #define H_POLL_PENDING 0x1D8 | 247 | #define H_POLL_PENDING 0x1D8 |
@@ -330,6 +331,17 @@ | |||
330 | #define H_SIGNAL_SYS_RESET_ALL_OTHERS -2 | 331 | #define H_SIGNAL_SYS_RESET_ALL_OTHERS -2 |
331 | /* >= 0 values are CPU number */ | 332 | /* >= 0 values are CPU number */ |
332 | 333 | ||
334 | /* H_GET_CPU_CHARACTERISTICS return values */ | ||
335 | #define H_CPU_CHAR_SPEC_BAR_ORI31 (1ull << 63) // IBM bit 0 | ||
336 | #define H_CPU_CHAR_BCCTRL_SERIALISED (1ull << 62) // IBM bit 1 | ||
337 | #define H_CPU_CHAR_L1D_FLUSH_ORI30 (1ull << 61) // IBM bit 2 | ||
338 | #define H_CPU_CHAR_L1D_FLUSH_TRIG2 (1ull << 60) // IBM bit 3 | ||
339 | #define H_CPU_CHAR_L1D_THREAD_PRIV (1ull << 59) // IBM bit 4 | ||
340 | |||
341 | #define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0 | ||
342 | #define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1 | ||
343 | #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 | ||
344 | |||
333 | /* Flag values used in H_REGISTER_PROC_TBL hcall */ | 345 | /* Flag values used in H_REGISTER_PROC_TBL hcall */ |
334 | #define PROC_TABLE_OP_MASK 0x18 | 346 | #define PROC_TABLE_OP_MASK 0x18 |
335 | #define PROC_TABLE_DEREG 0x10 | 347 | #define PROC_TABLE_DEREG 0x10 |
@@ -436,6 +448,11 @@ static inline unsigned int get_longbusy_msecs(int longbusy_rc) | |||
436 | } | 448 | } |
437 | } | 449 | } |
438 | 450 | ||
451 | struct h_cpu_char_result { | ||
452 | u64 character; | ||
453 | u64 behaviour; | ||
454 | }; | ||
455 | |||
439 | #endif /* __ASSEMBLY__ */ | 456 | #endif /* __ASSEMBLY__ */ |
440 | #endif /* __KERNEL__ */ | 457 | #endif /* __KERNEL__ */ |
441 | #endif /* _ASM_POWERPC_HVCALL_H */ | 458 | #endif /* _ASM_POWERPC_HVCALL_H */ |
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 3892db93b837..23ac7fc0af23 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
@@ -232,6 +232,16 @@ struct paca_struct { | |||
232 | struct sibling_subcore_state *sibling_subcore_state; | 232 | struct sibling_subcore_state *sibling_subcore_state; |
233 | #endif | 233 | #endif |
234 | #endif | 234 | #endif |
235 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
236 | /* | ||
237 | * rfi fallback flush must be in its own cacheline to prevent | ||
238 | * other paca data leaking into the L1d | ||
239 | */ | ||
240 | u64 exrfi[EX_SIZE] __aligned(0x80); | ||
241 | void *rfi_flush_fallback_area; | ||
242 | u64 l1d_flush_congruence; | ||
243 | u64 l1d_flush_sets; | ||
244 | #endif | ||
235 | }; | 245 | }; |
236 | 246 | ||
237 | extern void copy_mm_to_paca(struct mm_struct *mm); | 247 | extern void copy_mm_to_paca(struct mm_struct *mm); |
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h index 7f01b22fa6cb..55eddf50d149 100644 --- a/arch/powerpc/include/asm/plpar_wrappers.h +++ b/arch/powerpc/include/asm/plpar_wrappers.h | |||
@@ -326,4 +326,18 @@ static inline long plapr_signal_sys_reset(long cpu) | |||
326 | return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu); | 326 | return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu); |
327 | } | 327 | } |
328 | 328 | ||
329 | static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p) | ||
330 | { | ||
331 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
332 | long rc; | ||
333 | |||
334 | rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf); | ||
335 | if (rc == H_SUCCESS) { | ||
336 | p->character = retbuf[0]; | ||
337 | p->behaviour = retbuf[1]; | ||
338 | } | ||
339 | |||
340 | return rc; | ||
341 | } | ||
342 | |||
329 | #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ | 343 | #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ |
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index cf00ec26303a..469b7fdc9be4 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h | |||
@@ -39,6 +39,19 @@ static inline void pseries_big_endian_exceptions(void) {} | |||
39 | static inline void pseries_little_endian_exceptions(void) {} | 39 | static inline void pseries_little_endian_exceptions(void) {} |
40 | #endif /* CONFIG_PPC_PSERIES */ | 40 | #endif /* CONFIG_PPC_PSERIES */ |
41 | 41 | ||
42 | void rfi_flush_enable(bool enable); | ||
43 | |||
44 | /* These are bit flags */ | ||
45 | enum l1d_flush_type { | ||
46 | L1D_FLUSH_NONE = 0x1, | ||
47 | L1D_FLUSH_FALLBACK = 0x2, | ||
48 | L1D_FLUSH_ORI = 0x4, | ||
49 | L1D_FLUSH_MTTRIG = 0x8, | ||
50 | }; | ||
51 | |||
52 | void __init setup_rfi_flush(enum l1d_flush_type, bool enable); | ||
53 | void do_rfi_flush_fixups(enum l1d_flush_type types); | ||
54 | |||
42 | #endif /* !__ASSEMBLY__ */ | 55 | #endif /* !__ASSEMBLY__ */ |
43 | 56 | ||
44 | #endif /* _ASM_POWERPC_SETUP_H */ | 57 | #endif /* _ASM_POWERPC_SETUP_H */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 6b958414b4e0..f390d57cf2e1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -237,6 +237,11 @@ int main(void) | |||
237 | OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp); | 237 | OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp); |
238 | OFFSET(PACA_IN_MCE, paca_struct, in_mce); | 238 | OFFSET(PACA_IN_MCE, paca_struct, in_mce); |
239 | OFFSET(PACA_IN_NMI, paca_struct, in_nmi); | 239 | OFFSET(PACA_IN_NMI, paca_struct, in_nmi); |
240 | OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area); | ||
241 | OFFSET(PACA_EXRFI, paca_struct, exrfi); | ||
242 | OFFSET(PACA_L1D_FLUSH_CONGRUENCE, paca_struct, l1d_flush_congruence); | ||
243 | OFFSET(PACA_L1D_FLUSH_SETS, paca_struct, l1d_flush_sets); | ||
244 | |||
240 | #endif | 245 | #endif |
241 | OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id); | 246 | OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id); |
242 | OFFSET(PACAKEXECSTATE, paca_struct, kexec_state); | 247 | OFFSET(PACAKEXECSTATE, paca_struct, kexec_state); |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 3320bcac7192..2748584b767d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -37,6 +37,11 @@ | |||
37 | #include <asm/tm.h> | 37 | #include <asm/tm.h> |
38 | #include <asm/ppc-opcode.h> | 38 | #include <asm/ppc-opcode.h> |
39 | #include <asm/export.h> | 39 | #include <asm/export.h> |
40 | #ifdef CONFIG_PPC_BOOK3S | ||
41 | #include <asm/exception-64s.h> | ||
42 | #else | ||
43 | #include <asm/exception-64e.h> | ||
44 | #endif | ||
40 | 45 | ||
41 | /* | 46 | /* |
42 | * System calls. | 47 | * System calls. |
@@ -262,13 +267,23 @@ BEGIN_FTR_SECTION | |||
262 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | 267 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) |
263 | 268 | ||
264 | ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ | 269 | ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ |
270 | ld r2,GPR2(r1) | ||
271 | ld r1,GPR1(r1) | ||
272 | mtlr r4 | ||
273 | mtcr r5 | ||
274 | mtspr SPRN_SRR0,r7 | ||
275 | mtspr SPRN_SRR1,r8 | ||
276 | RFI_TO_USER | ||
277 | b . /* prevent speculative execution */ | ||
278 | |||
279 | /* exit to kernel */ | ||
265 | 1: ld r2,GPR2(r1) | 280 | 1: ld r2,GPR2(r1) |
266 | ld r1,GPR1(r1) | 281 | ld r1,GPR1(r1) |
267 | mtlr r4 | 282 | mtlr r4 |
268 | mtcr r5 | 283 | mtcr r5 |
269 | mtspr SPRN_SRR0,r7 | 284 | mtspr SPRN_SRR0,r7 |
270 | mtspr SPRN_SRR1,r8 | 285 | mtspr SPRN_SRR1,r8 |
271 | RFI | 286 | RFI_TO_KERNEL |
272 | b . /* prevent speculative execution */ | 287 | b . /* prevent speculative execution */ |
273 | 288 | ||
274 | .Lsyscall_error: | 289 | .Lsyscall_error: |
@@ -397,8 +412,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
397 | mtmsrd r10, 1 | 412 | mtmsrd r10, 1 |
398 | mtspr SPRN_SRR0, r11 | 413 | mtspr SPRN_SRR0, r11 |
399 | mtspr SPRN_SRR1, r12 | 414 | mtspr SPRN_SRR1, r12 |
400 | 415 | RFI_TO_USER | |
401 | rfid | ||
402 | b . /* prevent speculative execution */ | 416 | b . /* prevent speculative execution */ |
403 | #endif | 417 | #endif |
404 | _ASM_NOKPROBE_SYMBOL(system_call_common); | 418 | _ASM_NOKPROBE_SYMBOL(system_call_common); |
@@ -878,7 +892,7 @@ BEGIN_FTR_SECTION | |||
878 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | 892 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) |
879 | ACCOUNT_CPU_USER_EXIT(r13, r2, r4) | 893 | ACCOUNT_CPU_USER_EXIT(r13, r2, r4) |
880 | REST_GPR(13, r1) | 894 | REST_GPR(13, r1) |
881 | 1: | 895 | |
882 | mtspr SPRN_SRR1,r3 | 896 | mtspr SPRN_SRR1,r3 |
883 | 897 | ||
884 | ld r2,_CCR(r1) | 898 | ld r2,_CCR(r1) |
@@ -891,8 +905,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
891 | ld r3,GPR3(r1) | 905 | ld r3,GPR3(r1) |
892 | ld r4,GPR4(r1) | 906 | ld r4,GPR4(r1) |
893 | ld r1,GPR1(r1) | 907 | ld r1,GPR1(r1) |
908 | RFI_TO_USER | ||
909 | b . /* prevent speculative execution */ | ||
894 | 910 | ||
895 | rfid | 911 | 1: mtspr SPRN_SRR1,r3 |
912 | |||
913 | ld r2,_CCR(r1) | ||
914 | mtcrf 0xFF,r2 | ||
915 | ld r2,_NIP(r1) | ||
916 | mtspr SPRN_SRR0,r2 | ||
917 | |||
918 | ld r0,GPR0(r1) | ||
919 | ld r2,GPR2(r1) | ||
920 | ld r3,GPR3(r1) | ||
921 | ld r4,GPR4(r1) | ||
922 | ld r1,GPR1(r1) | ||
923 | RFI_TO_KERNEL | ||
896 | b . /* prevent speculative execution */ | 924 | b . /* prevent speculative execution */ |
897 | 925 | ||
898 | #endif /* CONFIG_PPC_BOOK3E */ | 926 | #endif /* CONFIG_PPC_BOOK3E */ |
@@ -1073,7 +1101,7 @@ __enter_rtas: | |||
1073 | 1101 | ||
1074 | mtspr SPRN_SRR0,r5 | 1102 | mtspr SPRN_SRR0,r5 |
1075 | mtspr SPRN_SRR1,r6 | 1103 | mtspr SPRN_SRR1,r6 |
1076 | rfid | 1104 | RFI_TO_KERNEL |
1077 | b . /* prevent speculative execution */ | 1105 | b . /* prevent speculative execution */ |
1078 | 1106 | ||
1079 | rtas_return_loc: | 1107 | rtas_return_loc: |
@@ -1098,7 +1126,7 @@ rtas_return_loc: | |||
1098 | 1126 | ||
1099 | mtspr SPRN_SRR0,r3 | 1127 | mtspr SPRN_SRR0,r3 |
1100 | mtspr SPRN_SRR1,r4 | 1128 | mtspr SPRN_SRR1,r4 |
1101 | rfid | 1129 | RFI_TO_KERNEL |
1102 | b . /* prevent speculative execution */ | 1130 | b . /* prevent speculative execution */ |
1103 | _ASM_NOKPROBE_SYMBOL(__enter_rtas) | 1131 | _ASM_NOKPROBE_SYMBOL(__enter_rtas) |
1104 | _ASM_NOKPROBE_SYMBOL(rtas_return_loc) | 1132 | _ASM_NOKPROBE_SYMBOL(rtas_return_loc) |
@@ -1171,7 +1199,7 @@ _GLOBAL(enter_prom) | |||
1171 | LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) | 1199 | LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) |
1172 | andc r11,r11,r12 | 1200 | andc r11,r11,r12 |
1173 | mtsrr1 r11 | 1201 | mtsrr1 r11 |
1174 | rfid | 1202 | RFI_TO_KERNEL |
1175 | #endif /* CONFIG_PPC_BOOK3E */ | 1203 | #endif /* CONFIG_PPC_BOOK3E */ |
1176 | 1204 | ||
1177 | 1: /* Return from OF */ | 1205 | 1: /* Return from OF */ |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e441b469dc8f..2dc10bf646b8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -256,7 +256,7 @@ BEGIN_FTR_SECTION | |||
256 | LOAD_HANDLER(r12, machine_check_handle_early) | 256 | LOAD_HANDLER(r12, machine_check_handle_early) |
257 | 1: mtspr SPRN_SRR0,r12 | 257 | 1: mtspr SPRN_SRR0,r12 |
258 | mtspr SPRN_SRR1,r11 | 258 | mtspr SPRN_SRR1,r11 |
259 | rfid | 259 | RFI_TO_KERNEL |
260 | b . /* prevent speculative execution */ | 260 | b . /* prevent speculative execution */ |
261 | 2: | 261 | 2: |
262 | /* Stack overflow. Stay on emergency stack and panic. | 262 | /* Stack overflow. Stay on emergency stack and panic. |
@@ -445,7 +445,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) | |||
445 | li r3,MSR_ME | 445 | li r3,MSR_ME |
446 | andc r10,r10,r3 /* Turn off MSR_ME */ | 446 | andc r10,r10,r3 /* Turn off MSR_ME */ |
447 | mtspr SPRN_SRR1,r10 | 447 | mtspr SPRN_SRR1,r10 |
448 | rfid | 448 | RFI_TO_KERNEL |
449 | b . | 449 | b . |
450 | 2: | 450 | 2: |
451 | /* | 451 | /* |
@@ -463,7 +463,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) | |||
463 | */ | 463 | */ |
464 | bl machine_check_queue_event | 464 | bl machine_check_queue_event |
465 | MACHINE_CHECK_HANDLER_WINDUP | 465 | MACHINE_CHECK_HANDLER_WINDUP |
466 | rfid | 466 | RFI_TO_USER_OR_KERNEL |
467 | 9: | 467 | 9: |
468 | /* Deliver the machine check to host kernel in V mode. */ | 468 | /* Deliver the machine check to host kernel in V mode. */ |
469 | MACHINE_CHECK_HANDLER_WINDUP | 469 | MACHINE_CHECK_HANDLER_WINDUP |
@@ -598,6 +598,9 @@ EXC_COMMON_BEGIN(slb_miss_common) | |||
598 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 598 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
599 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | 599 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ |
600 | 600 | ||
601 | andi. r9,r11,MSR_PR // Check for exception from userspace | ||
602 | cmpdi cr4,r9,MSR_PR // And save the result in CR4 for later | ||
603 | |||
601 | /* | 604 | /* |
602 | * Test MSR_RI before calling slb_allocate_realmode, because the | 605 | * Test MSR_RI before calling slb_allocate_realmode, because the |
603 | * MSR in r11 gets clobbered. However we still want to allocate | 606 | * MSR in r11 gets clobbered. However we still want to allocate |
@@ -624,9 +627,12 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
624 | 627 | ||
625 | /* All done -- return from exception. */ | 628 | /* All done -- return from exception. */ |
626 | 629 | ||
630 | bne cr4,1f /* returning to kernel */ | ||
631 | |||
627 | .machine push | 632 | .machine push |
628 | .machine "power4" | 633 | .machine "power4" |
629 | mtcrf 0x80,r9 | 634 | mtcrf 0x80,r9 |
635 | mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */ | ||
630 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ | 636 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ |
631 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ | 637 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ |
632 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | 638 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ |
@@ -640,9 +646,30 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
640 | ld r11,PACA_EXSLB+EX_R11(r13) | 646 | ld r11,PACA_EXSLB+EX_R11(r13) |
641 | ld r12,PACA_EXSLB+EX_R12(r13) | 647 | ld r12,PACA_EXSLB+EX_R12(r13) |
642 | ld r13,PACA_EXSLB+EX_R13(r13) | 648 | ld r13,PACA_EXSLB+EX_R13(r13) |
643 | rfid | 649 | RFI_TO_USER |
650 | b . /* prevent speculative execution */ | ||
651 | 1: | ||
652 | .machine push | ||
653 | .machine "power4" | ||
654 | mtcrf 0x80,r9 | ||
655 | mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */ | ||
656 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ | ||
657 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ | ||
658 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | ||
659 | .machine pop | ||
660 | |||
661 | RESTORE_CTR(r9, PACA_EXSLB) | ||
662 | RESTORE_PPR_PACA(PACA_EXSLB, r9) | ||
663 | mr r3,r12 | ||
664 | ld r9,PACA_EXSLB+EX_R9(r13) | ||
665 | ld r10,PACA_EXSLB+EX_R10(r13) | ||
666 | ld r11,PACA_EXSLB+EX_R11(r13) | ||
667 | ld r12,PACA_EXSLB+EX_R12(r13) | ||
668 | ld r13,PACA_EXSLB+EX_R13(r13) | ||
669 | RFI_TO_KERNEL | ||
644 | b . /* prevent speculative execution */ | 670 | b . /* prevent speculative execution */ |
645 | 671 | ||
672 | |||
646 | 2: std r3,PACA_EXSLB+EX_DAR(r13) | 673 | 2: std r3,PACA_EXSLB+EX_DAR(r13) |
647 | mr r3,r12 | 674 | mr r3,r12 |
648 | mfspr r11,SPRN_SRR0 | 675 | mfspr r11,SPRN_SRR0 |
@@ -651,7 +678,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
651 | mtspr SPRN_SRR0,r10 | 678 | mtspr SPRN_SRR0,r10 |
652 | ld r10,PACAKMSR(r13) | 679 | ld r10,PACAKMSR(r13) |
653 | mtspr SPRN_SRR1,r10 | 680 | mtspr SPRN_SRR1,r10 |
654 | rfid | 681 | RFI_TO_KERNEL |
655 | b . | 682 | b . |
656 | 683 | ||
657 | 8: std r3,PACA_EXSLB+EX_DAR(r13) | 684 | 8: std r3,PACA_EXSLB+EX_DAR(r13) |
@@ -662,7 +689,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
662 | mtspr SPRN_SRR0,r10 | 689 | mtspr SPRN_SRR0,r10 |
663 | ld r10,PACAKMSR(r13) | 690 | ld r10,PACAKMSR(r13) |
664 | mtspr SPRN_SRR1,r10 | 691 | mtspr SPRN_SRR1,r10 |
665 | rfid | 692 | RFI_TO_KERNEL |
666 | b . | 693 | b . |
667 | 694 | ||
668 | EXC_COMMON_BEGIN(unrecov_slb) | 695 | EXC_COMMON_BEGIN(unrecov_slb) |
@@ -901,7 +928,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) | |||
901 | mtspr SPRN_SRR0,r10 ; \ | 928 | mtspr SPRN_SRR0,r10 ; \ |
902 | ld r10,PACAKMSR(r13) ; \ | 929 | ld r10,PACAKMSR(r13) ; \ |
903 | mtspr SPRN_SRR1,r10 ; \ | 930 | mtspr SPRN_SRR1,r10 ; \ |
904 | rfid ; \ | 931 | RFI_TO_KERNEL ; \ |
905 | b . ; /* prevent speculative execution */ | 932 | b . ; /* prevent speculative execution */ |
906 | 933 | ||
907 | #ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH | 934 | #ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH |
@@ -917,7 +944,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ | |||
917 | xori r12,r12,MSR_LE ; \ | 944 | xori r12,r12,MSR_LE ; \ |
918 | mtspr SPRN_SRR1,r12 ; \ | 945 | mtspr SPRN_SRR1,r12 ; \ |
919 | mr r13,r9 ; \ | 946 | mr r13,r9 ; \ |
920 | rfid ; /* return to userspace */ \ | 947 | RFI_TO_USER ; /* return to userspace */ \ |
921 | b . ; /* prevent speculative execution */ | 948 | b . ; /* prevent speculative execution */ |
922 | #else | 949 | #else |
923 | #define SYSCALL_FASTENDIAN_TEST | 950 | #define SYSCALL_FASTENDIAN_TEST |
@@ -1063,7 +1090,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early) | |||
1063 | mtcr r11 | 1090 | mtcr r11 |
1064 | REST_GPR(11, r1) | 1091 | REST_GPR(11, r1) |
1065 | ld r1,GPR1(r1) | 1092 | ld r1,GPR1(r1) |
1066 | hrfid | 1093 | HRFI_TO_USER_OR_KERNEL |
1067 | 1094 | ||
1068 | 1: mtcr r11 | 1095 | 1: mtcr r11 |
1069 | REST_GPR(11, r1) | 1096 | REST_GPR(11, r1) |
@@ -1314,7 +1341,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) | |||
1314 | ld r11,PACA_EXGEN+EX_R11(r13) | 1341 | ld r11,PACA_EXGEN+EX_R11(r13) |
1315 | ld r12,PACA_EXGEN+EX_R12(r13) | 1342 | ld r12,PACA_EXGEN+EX_R12(r13) |
1316 | ld r13,PACA_EXGEN+EX_R13(r13) | 1343 | ld r13,PACA_EXGEN+EX_R13(r13) |
1317 | HRFID | 1344 | HRFI_TO_UNKNOWN |
1318 | b . | 1345 | b . |
1319 | #endif | 1346 | #endif |
1320 | 1347 | ||
@@ -1418,10 +1445,94 @@ masked_##_H##interrupt: \ | |||
1418 | ld r10,PACA_EXGEN+EX_R10(r13); \ | 1445 | ld r10,PACA_EXGEN+EX_R10(r13); \ |
1419 | ld r11,PACA_EXGEN+EX_R11(r13); \ | 1446 | ld r11,PACA_EXGEN+EX_R11(r13); \ |
1420 | /* returns to kernel where r13 must be set up, so don't restore it */ \ | 1447 | /* returns to kernel where r13 must be set up, so don't restore it */ \ |
1421 | ##_H##rfid; \ | 1448 | ##_H##RFI_TO_KERNEL; \ |
1422 | b .; \ | 1449 | b .; \ |
1423 | MASKED_DEC_HANDLER(_H) | 1450 | MASKED_DEC_HANDLER(_H) |
1424 | 1451 | ||
1452 | TRAMP_REAL_BEGIN(rfi_flush_fallback) | ||
1453 | SET_SCRATCH0(r13); | ||
1454 | GET_PACA(r13); | ||
1455 | std r9,PACA_EXRFI+EX_R9(r13) | ||
1456 | std r10,PACA_EXRFI+EX_R10(r13) | ||
1457 | std r11,PACA_EXRFI+EX_R11(r13) | ||
1458 | std r12,PACA_EXRFI+EX_R12(r13) | ||
1459 | std r8,PACA_EXRFI+EX_R13(r13) | ||
1460 | mfctr r9 | ||
1461 | ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) | ||
1462 | ld r11,PACA_L1D_FLUSH_SETS(r13) | ||
1463 | ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) | ||
1464 | /* | ||
1465 | * The load adresses are at staggered offsets within cachelines, | ||
1466 | * which suits some pipelines better (on others it should not | ||
1467 | * hurt). | ||
1468 | */ | ||
1469 | addi r12,r12,8 | ||
1470 | mtctr r11 | ||
1471 | DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ | ||
1472 | |||
1473 | /* order ld/st prior to dcbt stop all streams with flushing */ | ||
1474 | sync | ||
1475 | 1: li r8,0 | ||
1476 | .rept 8 /* 8-way set associative */ | ||
1477 | ldx r11,r10,r8 | ||
1478 | add r8,r8,r12 | ||
1479 | xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not | ||
1480 | add r8,r8,r11 // Add 0, this creates a dependency on the ldx | ||
1481 | .endr | ||
1482 | addi r10,r10,128 /* 128 byte cache line */ | ||
1483 | bdnz 1b | ||
1484 | |||
1485 | mtctr r9 | ||
1486 | ld r9,PACA_EXRFI+EX_R9(r13) | ||
1487 | ld r10,PACA_EXRFI+EX_R10(r13) | ||
1488 | ld r11,PACA_EXRFI+EX_R11(r13) | ||
1489 | ld r12,PACA_EXRFI+EX_R12(r13) | ||
1490 | ld r8,PACA_EXRFI+EX_R13(r13) | ||
1491 | GET_SCRATCH0(r13); | ||
1492 | rfid | ||
1493 | |||
1494 | TRAMP_REAL_BEGIN(hrfi_flush_fallback) | ||
1495 | SET_SCRATCH0(r13); | ||
1496 | GET_PACA(r13); | ||
1497 | std r9,PACA_EXRFI+EX_R9(r13) | ||
1498 | std r10,PACA_EXRFI+EX_R10(r13) | ||
1499 | std r11,PACA_EXRFI+EX_R11(r13) | ||
1500 | std r12,PACA_EXRFI+EX_R12(r13) | ||
1501 | std r8,PACA_EXRFI+EX_R13(r13) | ||
1502 | mfctr r9 | ||
1503 | ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) | ||
1504 | ld r11,PACA_L1D_FLUSH_SETS(r13) | ||
1505 | ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) | ||
1506 | /* | ||
1507 | * The load adresses are at staggered offsets within cachelines, | ||
1508 | * which suits some pipelines better (on others it should not | ||
1509 | * hurt). | ||
1510 | */ | ||
1511 | addi r12,r12,8 | ||
1512 | mtctr r11 | ||
1513 | DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ | ||
1514 | |||
1515 | /* order ld/st prior to dcbt stop all streams with flushing */ | ||
1516 | sync | ||
1517 | 1: li r8,0 | ||
1518 | .rept 8 /* 8-way set associative */ | ||
1519 | ldx r11,r10,r8 | ||
1520 | add r8,r8,r12 | ||
1521 | xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not | ||
1522 | add r8,r8,r11 // Add 0, this creates a dependency on the ldx | ||
1523 | .endr | ||
1524 | addi r10,r10,128 /* 128 byte cache line */ | ||
1525 | bdnz 1b | ||
1526 | |||
1527 | mtctr r9 | ||
1528 | ld r9,PACA_EXRFI+EX_R9(r13) | ||
1529 | ld r10,PACA_EXRFI+EX_R10(r13) | ||
1530 | ld r11,PACA_EXRFI+EX_R11(r13) | ||
1531 | ld r12,PACA_EXRFI+EX_R12(r13) | ||
1532 | ld r8,PACA_EXRFI+EX_R13(r13) | ||
1533 | GET_SCRATCH0(r13); | ||
1534 | hrfid | ||
1535 | |||
1425 | /* | 1536 | /* |
1426 | * Real mode exceptions actually use this too, but alternate | 1537 | * Real mode exceptions actually use this too, but alternate |
1427 | * instruction code patches (which end up in the common .text area) | 1538 | * instruction code patches (which end up in the common .text area) |
@@ -1441,7 +1552,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt) | |||
1441 | addi r13, r13, 4 | 1552 | addi r13, r13, 4 |
1442 | mtspr SPRN_SRR0, r13 | 1553 | mtspr SPRN_SRR0, r13 |
1443 | GET_SCRATCH0(r13) | 1554 | GET_SCRATCH0(r13) |
1444 | rfid | 1555 | RFI_TO_KERNEL |
1445 | b . | 1556 | b . |
1446 | 1557 | ||
1447 | TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) | 1558 | TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) |
@@ -1453,7 +1564,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) | |||
1453 | addi r13, r13, 4 | 1564 | addi r13, r13, 4 |
1454 | mtspr SPRN_HSRR0, r13 | 1565 | mtspr SPRN_HSRR0, r13 |
1455 | GET_SCRATCH0(r13) | 1566 | GET_SCRATCH0(r13) |
1456 | hrfid | 1567 | HRFI_TO_KERNEL |
1457 | b . | 1568 | b . |
1458 | #endif | 1569 | #endif |
1459 | 1570 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 8956a9856604..491be4179ddd 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -801,3 +801,104 @@ static int __init disable_hardlockup_detector(void) | |||
801 | return 0; | 801 | return 0; |
802 | } | 802 | } |
803 | early_initcall(disable_hardlockup_detector); | 803 | early_initcall(disable_hardlockup_detector); |
804 | |||
805 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
806 | static enum l1d_flush_type enabled_flush_types; | ||
807 | static void *l1d_flush_fallback_area; | ||
808 | static bool no_rfi_flush; | ||
809 | bool rfi_flush; | ||
810 | |||
811 | static int __init handle_no_rfi_flush(char *p) | ||
812 | { | ||
813 | pr_info("rfi-flush: disabled on command line."); | ||
814 | no_rfi_flush = true; | ||
815 | return 0; | ||
816 | } | ||
817 | early_param("no_rfi_flush", handle_no_rfi_flush); | ||
818 | |||
819 | /* | ||
820 | * The RFI flush is not KPTI, but because users will see doco that says to use | ||
821 | * nopti we hijack that option here to also disable the RFI flush. | ||
822 | */ | ||
823 | static int __init handle_no_pti(char *p) | ||
824 | { | ||
825 | pr_info("rfi-flush: disabling due to 'nopti' on command line.\n"); | ||
826 | handle_no_rfi_flush(NULL); | ||
827 | return 0; | ||
828 | } | ||
829 | early_param("nopti", handle_no_pti); | ||
830 | |||
831 | static void do_nothing(void *unused) | ||
832 | { | ||
833 | /* | ||
834 | * We don't need to do the flush explicitly, just enter+exit kernel is | ||
835 | * sufficient, the RFI exit handlers will do the right thing. | ||
836 | */ | ||
837 | } | ||
838 | |||
839 | void rfi_flush_enable(bool enable) | ||
840 | { | ||
841 | if (rfi_flush == enable) | ||
842 | return; | ||
843 | |||
844 | if (enable) { | ||
845 | do_rfi_flush_fixups(enabled_flush_types); | ||
846 | on_each_cpu(do_nothing, NULL, 1); | ||
847 | } else | ||
848 | do_rfi_flush_fixups(L1D_FLUSH_NONE); | ||
849 | |||
850 | rfi_flush = enable; | ||
851 | } | ||
852 | |||
853 | static void init_fallback_flush(void) | ||
854 | { | ||
855 | u64 l1d_size, limit; | ||
856 | int cpu; | ||
857 | |||
858 | l1d_size = ppc64_caches.l1d.size; | ||
859 | limit = min(safe_stack_limit(), ppc64_rma_size); | ||
860 | |||
861 | /* | ||
862 | * Align to L1d size, and size it at 2x L1d size, to catch possible | ||
863 | * hardware prefetch runoff. We don't have a recipe for load patterns to | ||
864 | * reliably avoid the prefetcher. | ||
865 | */ | ||
866 | l1d_flush_fallback_area = __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit)); | ||
867 | memset(l1d_flush_fallback_area, 0, l1d_size * 2); | ||
868 | |||
869 | for_each_possible_cpu(cpu) { | ||
870 | /* | ||
871 | * The fallback flush is currently coded for 8-way | ||
872 | * associativity. Different associativity is possible, but it | ||
873 | * will be treated as 8-way and may not evict the lines as | ||
874 | * effectively. | ||
875 | * | ||
876 | * 128 byte lines are mandatory. | ||
877 | */ | ||
878 | u64 c = l1d_size / 8; | ||
879 | |||
880 | paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area; | ||
881 | paca[cpu].l1d_flush_congruence = c; | ||
882 | paca[cpu].l1d_flush_sets = c / 128; | ||
883 | } | ||
884 | } | ||
885 | |||
886 | void __init setup_rfi_flush(enum l1d_flush_type types, bool enable) | ||
887 | { | ||
888 | if (types & L1D_FLUSH_FALLBACK) { | ||
889 | pr_info("rfi-flush: Using fallback displacement flush\n"); | ||
890 | init_fallback_flush(); | ||
891 | } | ||
892 | |||
893 | if (types & L1D_FLUSH_ORI) | ||
894 | pr_info("rfi-flush: Using ori type flush\n"); | ||
895 | |||
896 | if (types & L1D_FLUSH_MTTRIG) | ||
897 | pr_info("rfi-flush: Using mttrig type flush\n"); | ||
898 | |||
899 | enabled_flush_types = types; | ||
900 | |||
901 | if (!no_rfi_flush) | ||
902 | rfi_flush_enable(enable); | ||
903 | } | ||
904 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 0494e1566ee2..307843d23682 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -132,6 +132,15 @@ SECTIONS | |||
132 | /* Read-only data */ | 132 | /* Read-only data */ |
133 | RO_DATA(PAGE_SIZE) | 133 | RO_DATA(PAGE_SIZE) |
134 | 134 | ||
135 | #ifdef CONFIG_PPC64 | ||
136 | . = ALIGN(8); | ||
137 | __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) { | ||
138 | __start___rfi_flush_fixup = .; | ||
139 | *(__rfi_flush_fixup) | ||
140 | __stop___rfi_flush_fixup = .; | ||
141 | } | ||
142 | #endif | ||
143 | |||
135 | EXCEPTION_TABLE(0) | 144 | EXCEPTION_TABLE(0) |
136 | 145 | ||
137 | NOTES :kernel :notes | 146 | NOTES :kernel :notes |
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 29ebe2fd5867..a93d719edc90 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c | |||
@@ -235,6 +235,7 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
235 | gpte->may_read = true; | 235 | gpte->may_read = true; |
236 | gpte->may_write = true; | 236 | gpte->may_write = true; |
237 | gpte->page_size = MMU_PAGE_4K; | 237 | gpte->page_size = MMU_PAGE_4K; |
238 | gpte->wimg = HPTE_R_M; | ||
238 | 239 | ||
239 | return 0; | 240 | return 0; |
240 | } | 241 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 966097232d21..b73dbc9e797d 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -65,11 +65,17 @@ struct kvm_resize_hpt { | |||
65 | u32 order; | 65 | u32 order; |
66 | 66 | ||
67 | /* These fields protected by kvm->lock */ | 67 | /* These fields protected by kvm->lock */ |
68 | |||
69 | /* Possible values and their usage: | ||
70 | * <0 an error occurred during allocation, | ||
71 | * -EBUSY allocation is in the progress, | ||
72 | * 0 allocation made successfuly. | ||
73 | */ | ||
68 | int error; | 74 | int error; |
69 | bool prepare_done; | ||
70 | 75 | ||
71 | /* Private to the work thread, until prepare_done is true, | 76 | /* Private to the work thread, until error != -EBUSY, |
72 | * then protected by kvm->resize_hpt_sem */ | 77 | * then protected by kvm->lock. |
78 | */ | ||
73 | struct kvm_hpt_info hpt; | 79 | struct kvm_hpt_info hpt; |
74 | }; | 80 | }; |
75 | 81 | ||
@@ -159,8 +165,6 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order) | |||
159 | * Reset all the reverse-mapping chains for all memslots | 165 | * Reset all the reverse-mapping chains for all memslots |
160 | */ | 166 | */ |
161 | kvmppc_rmap_reset(kvm); | 167 | kvmppc_rmap_reset(kvm); |
162 | /* Ensure that each vcpu will flush its TLB on next entry. */ | ||
163 | cpumask_setall(&kvm->arch.need_tlb_flush); | ||
164 | err = 0; | 168 | err = 0; |
165 | goto out; | 169 | goto out; |
166 | } | 170 | } |
@@ -176,6 +180,10 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order) | |||
176 | kvmppc_set_hpt(kvm, &info); | 180 | kvmppc_set_hpt(kvm, &info); |
177 | 181 | ||
178 | out: | 182 | out: |
183 | if (err == 0) | ||
184 | /* Ensure that each vcpu will flush its TLB on next entry. */ | ||
185 | cpumask_setall(&kvm->arch.need_tlb_flush); | ||
186 | |||
179 | mutex_unlock(&kvm->lock); | 187 | mutex_unlock(&kvm->lock); |
180 | return err; | 188 | return err; |
181 | } | 189 | } |
@@ -1413,16 +1421,20 @@ static void resize_hpt_pivot(struct kvm_resize_hpt *resize) | |||
1413 | 1421 | ||
1414 | static void resize_hpt_release(struct kvm *kvm, struct kvm_resize_hpt *resize) | 1422 | static void resize_hpt_release(struct kvm *kvm, struct kvm_resize_hpt *resize) |
1415 | { | 1423 | { |
1416 | BUG_ON(kvm->arch.resize_hpt != resize); | 1424 | if (WARN_ON(!mutex_is_locked(&kvm->lock))) |
1425 | return; | ||
1417 | 1426 | ||
1418 | if (!resize) | 1427 | if (!resize) |
1419 | return; | 1428 | return; |
1420 | 1429 | ||
1421 | if (resize->hpt.virt) | 1430 | if (resize->error != -EBUSY) { |
1422 | kvmppc_free_hpt(&resize->hpt); | 1431 | if (resize->hpt.virt) |
1432 | kvmppc_free_hpt(&resize->hpt); | ||
1433 | kfree(resize); | ||
1434 | } | ||
1423 | 1435 | ||
1424 | kvm->arch.resize_hpt = NULL; | 1436 | if (kvm->arch.resize_hpt == resize) |
1425 | kfree(resize); | 1437 | kvm->arch.resize_hpt = NULL; |
1426 | } | 1438 | } |
1427 | 1439 | ||
1428 | static void resize_hpt_prepare_work(struct work_struct *work) | 1440 | static void resize_hpt_prepare_work(struct work_struct *work) |
@@ -1431,17 +1443,41 @@ static void resize_hpt_prepare_work(struct work_struct *work) | |||
1431 | struct kvm_resize_hpt, | 1443 | struct kvm_resize_hpt, |
1432 | work); | 1444 | work); |
1433 | struct kvm *kvm = resize->kvm; | 1445 | struct kvm *kvm = resize->kvm; |
1434 | int err; | 1446 | int err = 0; |
1435 | 1447 | ||
1436 | resize_hpt_debug(resize, "resize_hpt_prepare_work(): order = %d\n", | 1448 | if (WARN_ON(resize->error != -EBUSY)) |
1437 | resize->order); | 1449 | return; |
1438 | |||
1439 | err = resize_hpt_allocate(resize); | ||
1440 | 1450 | ||
1441 | mutex_lock(&kvm->lock); | 1451 | mutex_lock(&kvm->lock); |
1442 | 1452 | ||
1453 | /* Request is still current? */ | ||
1454 | if (kvm->arch.resize_hpt == resize) { | ||
1455 | /* We may request large allocations here: | ||
1456 | * do not sleep with kvm->lock held for a while. | ||
1457 | */ | ||
1458 | mutex_unlock(&kvm->lock); | ||
1459 | |||
1460 | resize_hpt_debug(resize, "resize_hpt_prepare_work(): order = %d\n", | ||
1461 | resize->order); | ||
1462 | |||
1463 | err = resize_hpt_allocate(resize); | ||
1464 | |||
1465 | /* We have strict assumption about -EBUSY | ||
1466 | * when preparing for HPT resize. | ||
1467 | */ | ||
1468 | if (WARN_ON(err == -EBUSY)) | ||
1469 | err = -EINPROGRESS; | ||
1470 | |||
1471 | mutex_lock(&kvm->lock); | ||
1472 | /* It is possible that kvm->arch.resize_hpt != resize | ||
1473 | * after we grab kvm->lock again. | ||
1474 | */ | ||
1475 | } | ||
1476 | |||
1443 | resize->error = err; | 1477 | resize->error = err; |
1444 | resize->prepare_done = true; | 1478 | |
1479 | if (kvm->arch.resize_hpt != resize) | ||
1480 | resize_hpt_release(kvm, resize); | ||
1445 | 1481 | ||
1446 | mutex_unlock(&kvm->lock); | 1482 | mutex_unlock(&kvm->lock); |
1447 | } | 1483 | } |
@@ -1466,14 +1502,12 @@ long kvm_vm_ioctl_resize_hpt_prepare(struct kvm *kvm, | |||
1466 | 1502 | ||
1467 | if (resize) { | 1503 | if (resize) { |
1468 | if (resize->order == shift) { | 1504 | if (resize->order == shift) { |
1469 | /* Suitable resize in progress */ | 1505 | /* Suitable resize in progress? */ |
1470 | if (resize->prepare_done) { | 1506 | ret = resize->error; |
1471 | ret = resize->error; | 1507 | if (ret == -EBUSY) |
1472 | if (ret != 0) | ||
1473 | resize_hpt_release(kvm, resize); | ||
1474 | } else { | ||
1475 | ret = 100; /* estimated time in ms */ | 1508 | ret = 100; /* estimated time in ms */ |
1476 | } | 1509 | else if (ret) |
1510 | resize_hpt_release(kvm, resize); | ||
1477 | 1511 | ||
1478 | goto out; | 1512 | goto out; |
1479 | } | 1513 | } |
@@ -1493,6 +1527,8 @@ long kvm_vm_ioctl_resize_hpt_prepare(struct kvm *kvm, | |||
1493 | ret = -ENOMEM; | 1527 | ret = -ENOMEM; |
1494 | goto out; | 1528 | goto out; |
1495 | } | 1529 | } |
1530 | |||
1531 | resize->error = -EBUSY; | ||
1496 | resize->order = shift; | 1532 | resize->order = shift; |
1497 | resize->kvm = kvm; | 1533 | resize->kvm = kvm; |
1498 | INIT_WORK(&resize->work, resize_hpt_prepare_work); | 1534 | INIT_WORK(&resize->work, resize_hpt_prepare_work); |
@@ -1547,16 +1583,12 @@ long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm, | |||
1547 | if (!resize || (resize->order != shift)) | 1583 | if (!resize || (resize->order != shift)) |
1548 | goto out; | 1584 | goto out; |
1549 | 1585 | ||
1550 | ret = -EBUSY; | ||
1551 | if (!resize->prepare_done) | ||
1552 | goto out; | ||
1553 | |||
1554 | ret = resize->error; | 1586 | ret = resize->error; |
1555 | if (ret != 0) | 1587 | if (ret) |
1556 | goto out; | 1588 | goto out; |
1557 | 1589 | ||
1558 | ret = resize_hpt_rehash(resize); | 1590 | ret = resize_hpt_rehash(resize); |
1559 | if (ret != 0) | 1591 | if (ret) |
1560 | goto out; | 1592 | goto out; |
1561 | 1593 | ||
1562 | resize_hpt_pivot(resize); | 1594 | resize_hpt_pivot(resize); |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 2659844784b8..9c61f736c75b 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -79,7 +79,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline) | |||
79 | mtmsrd r0,1 /* clear RI in MSR */ | 79 | mtmsrd r0,1 /* clear RI in MSR */ |
80 | mtsrr0 r5 | 80 | mtsrr0 r5 |
81 | mtsrr1 r6 | 81 | mtsrr1 r6 |
82 | RFI | 82 | RFI_TO_KERNEL |
83 | 83 | ||
84 | kvmppc_call_hv_entry: | 84 | kvmppc_call_hv_entry: |
85 | BEGIN_FTR_SECTION | 85 | BEGIN_FTR_SECTION |
@@ -199,7 +199,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
199 | mtmsrd r6, 1 /* Clear RI in MSR */ | 199 | mtmsrd r6, 1 /* Clear RI in MSR */ |
200 | mtsrr0 r8 | 200 | mtsrr0 r8 |
201 | mtsrr1 r7 | 201 | mtsrr1 r7 |
202 | RFI | 202 | RFI_TO_KERNEL |
203 | 203 | ||
204 | /* Virtual-mode return */ | 204 | /* Virtual-mode return */ |
205 | .Lvirt_return: | 205 | .Lvirt_return: |
@@ -1167,8 +1167,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) | |||
1167 | 1167 | ||
1168 | ld r0, VCPU_GPR(R0)(r4) | 1168 | ld r0, VCPU_GPR(R0)(r4) |
1169 | ld r4, VCPU_GPR(R4)(r4) | 1169 | ld r4, VCPU_GPR(R4)(r4) |
1170 | 1170 | HRFI_TO_GUEST | |
1171 | hrfid | ||
1172 | b . | 1171 | b . |
1173 | 1172 | ||
1174 | secondary_too_late: | 1173 | secondary_too_late: |
@@ -3320,7 +3319,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX) | |||
3320 | ld r4, PACAKMSR(r13) | 3319 | ld r4, PACAKMSR(r13) |
3321 | mtspr SPRN_SRR0, r3 | 3320 | mtspr SPRN_SRR0, r3 |
3322 | mtspr SPRN_SRR1, r4 | 3321 | mtspr SPRN_SRR1, r4 |
3323 | rfid | 3322 | RFI_TO_KERNEL |
3324 | 9: addi r3, r1, STACK_FRAME_OVERHEAD | 3323 | 9: addi r3, r1, STACK_FRAME_OVERHEAD |
3325 | bl kvmppc_bad_interrupt | 3324 | bl kvmppc_bad_interrupt |
3326 | b 9b | 3325 | b 9b |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index d0dc8624198f..7deaeeb14b93 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -60,6 +60,7 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); | |||
60 | #define MSR_USER32 MSR_USER | 60 | #define MSR_USER32 MSR_USER |
61 | #define MSR_USER64 MSR_USER | 61 | #define MSR_USER64 MSR_USER |
62 | #define HW_PAGE_SIZE PAGE_SIZE | 62 | #define HW_PAGE_SIZE PAGE_SIZE |
63 | #define HPTE_R_M _PAGE_COHERENT | ||
63 | #endif | 64 | #endif |
64 | 65 | ||
65 | static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu) | 66 | static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu) |
@@ -557,6 +558,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
557 | pte.eaddr = eaddr; | 558 | pte.eaddr = eaddr; |
558 | pte.vpage = eaddr >> 12; | 559 | pte.vpage = eaddr >> 12; |
559 | pte.page_size = MMU_PAGE_64K; | 560 | pte.page_size = MMU_PAGE_64K; |
561 | pte.wimg = HPTE_R_M; | ||
560 | } | 562 | } |
561 | 563 | ||
562 | switch (kvmppc_get_msr(vcpu) & (MSR_DR|MSR_IR)) { | 564 | switch (kvmppc_get_msr(vcpu) & (MSR_DR|MSR_IR)) { |
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index 42a4b237df5f..34a5adeff084 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S | |||
@@ -46,6 +46,9 @@ | |||
46 | 46 | ||
47 | #define FUNC(name) name | 47 | #define FUNC(name) name |
48 | 48 | ||
49 | #define RFI_TO_KERNEL RFI | ||
50 | #define RFI_TO_GUEST RFI | ||
51 | |||
49 | .macro INTERRUPT_TRAMPOLINE intno | 52 | .macro INTERRUPT_TRAMPOLINE intno |
50 | 53 | ||
51 | .global kvmppc_trampoline_\intno | 54 | .global kvmppc_trampoline_\intno |
@@ -141,7 +144,7 @@ kvmppc_handler_skip_ins: | |||
141 | GET_SCRATCH0(r13) | 144 | GET_SCRATCH0(r13) |
142 | 145 | ||
143 | /* And get back into the code */ | 146 | /* And get back into the code */ |
144 | RFI | 147 | RFI_TO_KERNEL |
145 | #endif | 148 | #endif |
146 | 149 | ||
147 | /* | 150 | /* |
@@ -164,6 +167,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline) | |||
164 | ori r5, r5, MSR_EE | 167 | ori r5, r5, MSR_EE |
165 | mtsrr0 r7 | 168 | mtsrr0 r7 |
166 | mtsrr1 r6 | 169 | mtsrr1 r6 |
167 | RFI | 170 | RFI_TO_KERNEL |
168 | 171 | ||
169 | #include "book3s_segment.S" | 172 | #include "book3s_segment.S" |
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 2a2b96d53999..93a180ceefad 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S | |||
@@ -156,7 +156,7 @@ no_dcbz32_on: | |||
156 | PPC_LL r9, SVCPU_R9(r3) | 156 | PPC_LL r9, SVCPU_R9(r3) |
157 | PPC_LL r3, (SVCPU_R3)(r3) | 157 | PPC_LL r3, (SVCPU_R3)(r3) |
158 | 158 | ||
159 | RFI | 159 | RFI_TO_GUEST |
160 | kvmppc_handler_trampoline_enter_end: | 160 | kvmppc_handler_trampoline_enter_end: |
161 | 161 | ||
162 | 162 | ||
@@ -407,5 +407,5 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) | |||
407 | cmpwi r12, BOOK3S_INTERRUPT_DOORBELL | 407 | cmpwi r12, BOOK3S_INTERRUPT_DOORBELL |
408 | beqa BOOK3S_INTERRUPT_DOORBELL | 408 | beqa BOOK3S_INTERRUPT_DOORBELL |
409 | 409 | ||
410 | RFI | 410 | RFI_TO_KERNEL |
411 | kvmppc_handler_trampoline_exit_end: | 411 | kvmppc_handler_trampoline_exit_end: |
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 41cf5ae273cf..a95ea007d654 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c | |||
@@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 | ||
119 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
120 | void do_rfi_flush_fixups(enum l1d_flush_type types) | ||
121 | { | ||
122 | unsigned int instrs[3], *dest; | ||
123 | long *start, *end; | ||
124 | int i; | ||
125 | |||
126 | start = PTRRELOC(&__start___rfi_flush_fixup), | ||
127 | end = PTRRELOC(&__stop___rfi_flush_fixup); | ||
128 | |||
129 | instrs[0] = 0x60000000; /* nop */ | ||
130 | instrs[1] = 0x60000000; /* nop */ | ||
131 | instrs[2] = 0x60000000; /* nop */ | ||
132 | |||
133 | if (types & L1D_FLUSH_FALLBACK) | ||
134 | /* b .+16 to fallback flush */ | ||
135 | instrs[0] = 0x48000010; | ||
136 | |||
137 | i = 0; | ||
138 | if (types & L1D_FLUSH_ORI) { | ||
139 | instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */ | ||
140 | instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/ | ||
141 | } | ||
142 | |||
143 | if (types & L1D_FLUSH_MTTRIG) | ||
144 | instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ | ||
145 | |||
146 | for (i = 0; start < end; start++, i++) { | ||
147 | dest = (void *)start + *start; | ||
148 | |||
149 | pr_devel("patching dest %lx\n", (unsigned long)dest); | ||
150 | |||
151 | patch_instruction(dest, instrs[0]); | ||
152 | patch_instruction(dest + 1, instrs[1]); | ||
153 | patch_instruction(dest + 2, instrs[2]); | ||
154 | } | ||
155 | |||
156 | printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i); | ||
157 | } | ||
158 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
159 | |||
119 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) | 160 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) |
120 | { | 161 | { |
121 | long *start, *end; | 162 | long *start, *end; |
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 1edfbc1e40f4..4fb21e17504a 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c | |||
@@ -37,13 +37,62 @@ | |||
37 | #include <asm/kexec.h> | 37 | #include <asm/kexec.h> |
38 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
39 | #include <asm/tm.h> | 39 | #include <asm/tm.h> |
40 | #include <asm/setup.h> | ||
40 | 41 | ||
41 | #include "powernv.h" | 42 | #include "powernv.h" |
42 | 43 | ||
44 | static void pnv_setup_rfi_flush(void) | ||
45 | { | ||
46 | struct device_node *np, *fw_features; | ||
47 | enum l1d_flush_type type; | ||
48 | int enable; | ||
49 | |||
50 | /* Default to fallback in case fw-features are not available */ | ||
51 | type = L1D_FLUSH_FALLBACK; | ||
52 | enable = 1; | ||
53 | |||
54 | np = of_find_node_by_name(NULL, "ibm,opal"); | ||
55 | fw_features = of_get_child_by_name(np, "fw-features"); | ||
56 | of_node_put(np); | ||
57 | |||
58 | if (fw_features) { | ||
59 | np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2"); | ||
60 | if (np && of_property_read_bool(np, "enabled")) | ||
61 | type = L1D_FLUSH_MTTRIG; | ||
62 | |||
63 | of_node_put(np); | ||
64 | |||
65 | np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0"); | ||
66 | if (np && of_property_read_bool(np, "enabled")) | ||
67 | type = L1D_FLUSH_ORI; | ||
68 | |||
69 | of_node_put(np); | ||
70 | |||
71 | /* Enable unless firmware says NOT to */ | ||
72 | enable = 2; | ||
73 | np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0"); | ||
74 | if (np && of_property_read_bool(np, "disabled")) | ||
75 | enable--; | ||
76 | |||
77 | of_node_put(np); | ||
78 | |||
79 | np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1"); | ||
80 | if (np && of_property_read_bool(np, "disabled")) | ||
81 | enable--; | ||
82 | |||
83 | of_node_put(np); | ||
84 | of_node_put(fw_features); | ||
85 | } | ||
86 | |||
87 | setup_rfi_flush(type, enable > 0); | ||
88 | } | ||
89 | |||
43 | static void __init pnv_setup_arch(void) | 90 | static void __init pnv_setup_arch(void) |
44 | { | 91 | { |
45 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); | 92 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); |
46 | 93 | ||
94 | pnv_setup_rfi_flush(); | ||
95 | |||
47 | /* Initialize SMP */ | 96 | /* Initialize SMP */ |
48 | pnv_smp_init(); | 97 | pnv_smp_init(); |
49 | 98 | ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 6e35780c5962..a0b20c03f078 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -574,11 +574,26 @@ static ssize_t dlpar_show(struct class *class, struct class_attribute *attr, | |||
574 | 574 | ||
575 | static CLASS_ATTR_RW(dlpar); | 575 | static CLASS_ATTR_RW(dlpar); |
576 | 576 | ||
577 | static int __init pseries_dlpar_init(void) | 577 | int __init dlpar_workqueue_init(void) |
578 | { | 578 | { |
579 | if (pseries_hp_wq) | ||
580 | return 0; | ||
581 | |||
579 | pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue", | 582 | pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue", |
580 | WQ_UNBOUND, 1); | 583 | WQ_UNBOUND, 1); |
584 | |||
585 | return pseries_hp_wq ? 0 : -ENOMEM; | ||
586 | } | ||
587 | |||
588 | static int __init dlpar_sysfs_init(void) | ||
589 | { | ||
590 | int rc; | ||
591 | |||
592 | rc = dlpar_workqueue_init(); | ||
593 | if (rc) | ||
594 | return rc; | ||
595 | |||
581 | return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); | 596 | return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); |
582 | } | 597 | } |
583 | machine_device_initcall(pseries, pseries_dlpar_init); | 598 | machine_device_initcall(pseries, dlpar_sysfs_init); |
584 | 599 | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 4470a3194311..1ae1d9f4dbe9 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -98,4 +98,6 @@ static inline unsigned long cmo_get_page_size(void) | |||
98 | return CMO_PageSize; | 98 | return CMO_PageSize; |
99 | } | 99 | } |
100 | 100 | ||
101 | int dlpar_workqueue_init(void); | ||
102 | |||
101 | #endif /* _PSERIES_PSERIES_H */ | 103 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 4923ffe230cf..81d8614e7379 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c | |||
@@ -69,7 +69,8 @@ static int __init init_ras_IRQ(void) | |||
69 | /* Hotplug Events */ | 69 | /* Hotplug Events */ |
70 | np = of_find_node_by_path("/event-sources/hot-plug-events"); | 70 | np = of_find_node_by_path("/event-sources/hot-plug-events"); |
71 | if (np != NULL) { | 71 | if (np != NULL) { |
72 | request_event_sources_irqs(np, ras_hotplug_interrupt, | 72 | if (dlpar_workqueue_init() == 0) |
73 | request_event_sources_irqs(np, ras_hotplug_interrupt, | ||
73 | "RAS_HOTPLUG"); | 74 | "RAS_HOTPLUG"); |
74 | of_node_put(np); | 75 | of_node_put(np); |
75 | } | 76 | } |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index a8531e012658..ae4f596273b5 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -459,6 +459,39 @@ static void __init find_and_init_phbs(void) | |||
459 | of_pci_check_probe_only(); | 459 | of_pci_check_probe_only(); |
460 | } | 460 | } |
461 | 461 | ||
462 | static void pseries_setup_rfi_flush(void) | ||
463 | { | ||
464 | struct h_cpu_char_result result; | ||
465 | enum l1d_flush_type types; | ||
466 | bool enable; | ||
467 | long rc; | ||
468 | |||
469 | /* Enable by default */ | ||
470 | enable = true; | ||
471 | |||
472 | rc = plpar_get_cpu_characteristics(&result); | ||
473 | if (rc == H_SUCCESS) { | ||
474 | types = L1D_FLUSH_NONE; | ||
475 | |||
476 | if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2) | ||
477 | types |= L1D_FLUSH_MTTRIG; | ||
478 | if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30) | ||
479 | types |= L1D_FLUSH_ORI; | ||
480 | |||
481 | /* Use fallback if nothing set in hcall */ | ||
482 | if (types == L1D_FLUSH_NONE) | ||
483 | types = L1D_FLUSH_FALLBACK; | ||
484 | |||
485 | if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) | ||
486 | enable = false; | ||
487 | } else { | ||
488 | /* Default to fallback if case hcall is not available */ | ||
489 | types = L1D_FLUSH_FALLBACK; | ||
490 | } | ||
491 | |||
492 | setup_rfi_flush(types, enable); | ||
493 | } | ||
494 | |||
462 | static void __init pSeries_setup_arch(void) | 495 | static void __init pSeries_setup_arch(void) |
463 | { | 496 | { |
464 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); | 497 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); |
@@ -476,6 +509,8 @@ static void __init pSeries_setup_arch(void) | |||
476 | 509 | ||
477 | fwnmi_init(); | 510 | fwnmi_init(); |
478 | 511 | ||
512 | pseries_setup_rfi_flush(); | ||
513 | |||
479 | /* By default, only probe PCI (can be overridden by rtas_pci) */ | 514 | /* By default, only probe PCI (can be overridden by rtas_pci) */ |
480 | pci_add_flags(PCI_PROBE_ONLY); | 515 | pci_add_flags(PCI_PROBE_ONLY); |
481 | 516 | ||
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index e69de29bb2d1..47dacf06c679 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig | |||
@@ -0,0 +1,75 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_PCI=y | ||
3 | CONFIG_PCIE_XILINX=y | ||
4 | CONFIG_SYSVIPC=y | ||
5 | CONFIG_POSIX_MQUEUE=y | ||
6 | CONFIG_IKCONFIG=y | ||
7 | CONFIG_IKCONFIG_PROC=y | ||
8 | CONFIG_CGROUPS=y | ||
9 | CONFIG_CGROUP_SCHED=y | ||
10 | CONFIG_CFS_BANDWIDTH=y | ||
11 | CONFIG_CGROUP_BPF=y | ||
12 | CONFIG_NAMESPACES=y | ||
13 | CONFIG_USER_NS=y | ||
14 | CONFIG_BLK_DEV_INITRD=y | ||
15 | CONFIG_EXPERT=y | ||
16 | CONFIG_CHECKPOINT_RESTORE=y | ||
17 | CONFIG_BPF_SYSCALL=y | ||
18 | CONFIG_NET=y | ||
19 | CONFIG_PACKET=y | ||
20 | CONFIG_UNIX=y | ||
21 | CONFIG_INET=y | ||
22 | CONFIG_IP_MULTICAST=y | ||
23 | CONFIG_IP_ADVANCED_ROUTER=y | ||
24 | CONFIG_IP_PNP=y | ||
25 | CONFIG_IP_PNP_DHCP=y | ||
26 | CONFIG_IP_PNP_BOOTP=y | ||
27 | CONFIG_IP_PNP_RARP=y | ||
28 | CONFIG_NETLINK_DIAG=y | ||
29 | CONFIG_DEVTMPFS=y | ||
30 | CONFIG_BLK_DEV_LOOP=y | ||
31 | CONFIG_VIRTIO_BLK=y | ||
32 | CONFIG_BLK_DEV_SD=y | ||
33 | CONFIG_BLK_DEV_SR=y | ||
34 | CONFIG_ATA=y | ||
35 | CONFIG_SATA_AHCI=y | ||
36 | CONFIG_SATA_AHCI_PLATFORM=y | ||
37 | CONFIG_NETDEVICES=y | ||
38 | CONFIG_VIRTIO_NET=y | ||
39 | CONFIG_MACB=y | ||
40 | CONFIG_E1000E=y | ||
41 | CONFIG_R8169=y | ||
42 | CONFIG_MICROSEMI_PHY=y | ||
43 | CONFIG_INPUT_MOUSEDEV=y | ||
44 | CONFIG_SERIAL_8250=y | ||
45 | CONFIG_SERIAL_8250_CONSOLE=y | ||
46 | CONFIG_SERIAL_OF_PLATFORM=y | ||
47 | # CONFIG_PTP_1588_CLOCK is not set | ||
48 | CONFIG_DRM=y | ||
49 | CONFIG_DRM_RADEON=y | ||
50 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
51 | CONFIG_USB=y | ||
52 | CONFIG_USB_XHCI_HCD=y | ||
53 | CONFIG_USB_XHCI_PLATFORM=y | ||
54 | CONFIG_USB_EHCI_HCD=y | ||
55 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
56 | CONFIG_USB_OHCI_HCD=y | ||
57 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
58 | CONFIG_USB_STORAGE=y | ||
59 | CONFIG_USB_UAS=y | ||
60 | CONFIG_VIRTIO_MMIO=y | ||
61 | CONFIG_RAS=y | ||
62 | CONFIG_EXT4_FS=y | ||
63 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
64 | CONFIG_AUTOFS4_FS=y | ||
65 | CONFIG_MSDOS_FS=y | ||
66 | CONFIG_VFAT_FS=y | ||
67 | CONFIG_TMPFS=y | ||
68 | CONFIG_TMPFS_POSIX_ACL=y | ||
69 | CONFIG_NFS_FS=y | ||
70 | CONFIG_NFS_V4=y | ||
71 | CONFIG_NFS_V4_1=y | ||
72 | CONFIG_NFS_V4_2=y | ||
73 | CONFIG_ROOT_NFS=y | ||
74 | # CONFIG_RCU_TRACE is not set | ||
75 | CONFIG_CRYPTO_USER_API_HASH=y | ||
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 0d64bc9f4f91..3c7a2c97e377 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h | |||
@@ -17,10 +17,10 @@ | |||
17 | #include <linux/const.h> | 17 | #include <linux/const.h> |
18 | 18 | ||
19 | /* Status register flags */ | 19 | /* Status register flags */ |
20 | #define SR_IE _AC(0x00000002, UL) /* Interrupt Enable */ | 20 | #define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ |
21 | #define SR_PIE _AC(0x00000020, UL) /* Previous IE */ | 21 | #define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ |
22 | #define SR_PS _AC(0x00000100, UL) /* Previously Supervisor */ | 22 | #define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ |
23 | #define SR_SUM _AC(0x00040000, UL) /* Supervisor may access User Memory */ | 23 | #define SR_SUM _AC(0x00040000, UL) /* Supervisor may access User Memory */ |
24 | 24 | ||
25 | #define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ | 25 | #define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ |
26 | #define SR_FS_OFF _AC(0x00000000, UL) | 26 | #define SR_FS_OFF _AC(0x00000000, UL) |
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index a82ce599b639..b269451e7e85 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h | |||
@@ -21,8 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | 23 | ||
24 | #ifdef CONFIG_MMU | ||
25 | |||
26 | extern void __iomem *ioremap(phys_addr_t offset, unsigned long size); | 24 | extern void __iomem *ioremap(phys_addr_t offset, unsigned long size); |
27 | 25 | ||
28 | /* | 26 | /* |
@@ -36,8 +34,6 @@ extern void __iomem *ioremap(phys_addr_t offset, unsigned long size); | |||
36 | 34 | ||
37 | extern void iounmap(volatile void __iomem *addr); | 35 | extern void iounmap(volatile void __iomem *addr); |
38 | 36 | ||
39 | #endif /* CONFIG_MMU */ | ||
40 | |||
41 | /* Generic IO read/write. These perform native-endian accesses. */ | 37 | /* Generic IO read/write. These perform native-endian accesses. */ |
42 | #define __raw_writeb __raw_writeb | 38 | #define __raw_writeb __raw_writeb |
43 | static inline void __raw_writeb(u8 val, volatile void __iomem *addr) | 39 | static inline void __raw_writeb(u8 val, volatile void __iomem *addr) |
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h index 6fdc860d7f84..07a3c6d5706f 100644 --- a/arch/riscv/include/asm/irqflags.h +++ b/arch/riscv/include/asm/irqflags.h | |||
@@ -27,25 +27,25 @@ static inline unsigned long arch_local_save_flags(void) | |||
27 | /* unconditionally enable interrupts */ | 27 | /* unconditionally enable interrupts */ |
28 | static inline void arch_local_irq_enable(void) | 28 | static inline void arch_local_irq_enable(void) |
29 | { | 29 | { |
30 | csr_set(sstatus, SR_IE); | 30 | csr_set(sstatus, SR_SIE); |
31 | } | 31 | } |
32 | 32 | ||
33 | /* unconditionally disable interrupts */ | 33 | /* unconditionally disable interrupts */ |
34 | static inline void arch_local_irq_disable(void) | 34 | static inline void arch_local_irq_disable(void) |
35 | { | 35 | { |
36 | csr_clear(sstatus, SR_IE); | 36 | csr_clear(sstatus, SR_SIE); |
37 | } | 37 | } |
38 | 38 | ||
39 | /* get status and disable interrupts */ | 39 | /* get status and disable interrupts */ |
40 | static inline unsigned long arch_local_irq_save(void) | 40 | static inline unsigned long arch_local_irq_save(void) |
41 | { | 41 | { |
42 | return csr_read_clear(sstatus, SR_IE); | 42 | return csr_read_clear(sstatus, SR_SIE); |
43 | } | 43 | } |
44 | 44 | ||
45 | /* test flags */ | 45 | /* test flags */ |
46 | static inline int arch_irqs_disabled_flags(unsigned long flags) | 46 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
47 | { | 47 | { |
48 | return !(flags & SR_IE); | 48 | return !(flags & SR_SIE); |
49 | } | 49 | } |
50 | 50 | ||
51 | /* test hardware interrupt enable bit */ | 51 | /* test hardware interrupt enable bit */ |
@@ -57,7 +57,7 @@ static inline int arch_irqs_disabled(void) | |||
57 | /* set interrupt enabled status */ | 57 | /* set interrupt enabled status */ |
58 | static inline void arch_local_irq_restore(unsigned long flags) | 58 | static inline void arch_local_irq_restore(unsigned long flags) |
59 | { | 59 | { |
60 | csr_set(sstatus, flags & SR_IE); | 60 | csr_set(sstatus, flags & SR_SIE); |
61 | } | 61 | } |
62 | 62 | ||
63 | #endif /* _ASM_RISCV_IRQFLAGS_H */ | 63 | #endif /* _ASM_RISCV_IRQFLAGS_H */ |
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 2cbd92ed1629..16301966d65b 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h | |||
@@ -20,8 +20,6 @@ | |||
20 | 20 | ||
21 | #ifndef __ASSEMBLY__ | 21 | #ifndef __ASSEMBLY__ |
22 | 22 | ||
23 | #ifdef CONFIG_MMU | ||
24 | |||
25 | /* Page Upper Directory not used in RISC-V */ | 23 | /* Page Upper Directory not used in RISC-V */ |
26 | #include <asm-generic/pgtable-nopud.h> | 24 | #include <asm-generic/pgtable-nopud.h> |
27 | #include <asm/page.h> | 25 | #include <asm/page.h> |
@@ -413,8 +411,6 @@ static inline void pgtable_cache_init(void) | |||
413 | /* No page table caches to initialize */ | 411 | /* No page table caches to initialize */ |
414 | } | 412 | } |
415 | 413 | ||
416 | #endif /* CONFIG_MMU */ | ||
417 | |||
418 | #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) | 414 | #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) |
419 | #define VMALLOC_END (PAGE_OFFSET - 1) | 415 | #define VMALLOC_END (PAGE_OFFSET - 1) |
420 | #define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE) | 416 | #define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE) |
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h index 93b8956e25e4..2c5df945d43c 100644 --- a/arch/riscv/include/asm/ptrace.h +++ b/arch/riscv/include/asm/ptrace.h | |||
@@ -66,7 +66,7 @@ struct pt_regs { | |||
66 | #define REG_FMT "%08lx" | 66 | #define REG_FMT "%08lx" |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | #define user_mode(regs) (((regs)->sstatus & SR_PS) == 0) | 69 | #define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0) |
70 | 70 | ||
71 | 71 | ||
72 | /* Helpers for working with the instruction pointer */ | 72 | /* Helpers for working with the instruction pointer */ |
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h index 715b0f10af58..7b9c24ebdf52 100644 --- a/arch/riscv/include/asm/tlbflush.h +++ b/arch/riscv/include/asm/tlbflush.h | |||
@@ -15,8 +15,6 @@ | |||
15 | #ifndef _ASM_RISCV_TLBFLUSH_H | 15 | #ifndef _ASM_RISCV_TLBFLUSH_H |
16 | #define _ASM_RISCV_TLBFLUSH_H | 16 | #define _ASM_RISCV_TLBFLUSH_H |
17 | 17 | ||
18 | #ifdef CONFIG_MMU | ||
19 | |||
20 | #include <linux/mm_types.h> | 18 | #include <linux/mm_types.h> |
21 | 19 | ||
22 | /* | 20 | /* |
@@ -64,6 +62,4 @@ static inline void flush_tlb_kernel_range(unsigned long start, | |||
64 | flush_tlb_all(); | 62 | flush_tlb_all(); |
65 | } | 63 | } |
66 | 64 | ||
67 | #endif /* CONFIG_MMU */ | ||
68 | |||
69 | #endif /* _ASM_RISCV_TLBFLUSH_H */ | 65 | #endif /* _ASM_RISCV_TLBFLUSH_H */ |
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index 27b90d64814b..14b0b22fb578 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h | |||
@@ -127,7 +127,6 @@ extern int fixup_exception(struct pt_regs *state); | |||
127 | * call. | 127 | * call. |
128 | */ | 128 | */ |
129 | 129 | ||
130 | #ifdef CONFIG_MMU | ||
131 | #define __get_user_asm(insn, x, ptr, err) \ | 130 | #define __get_user_asm(insn, x, ptr, err) \ |
132 | do { \ | 131 | do { \ |
133 | uintptr_t __tmp; \ | 132 | uintptr_t __tmp; \ |
@@ -153,13 +152,11 @@ do { \ | |||
153 | __disable_user_access(); \ | 152 | __disable_user_access(); \ |
154 | (x) = __x; \ | 153 | (x) = __x; \ |
155 | } while (0) | 154 | } while (0) |
156 | #endif /* CONFIG_MMU */ | ||
157 | 155 | ||
158 | #ifdef CONFIG_64BIT | 156 | #ifdef CONFIG_64BIT |
159 | #define __get_user_8(x, ptr, err) \ | 157 | #define __get_user_8(x, ptr, err) \ |
160 | __get_user_asm("ld", x, ptr, err) | 158 | __get_user_asm("ld", x, ptr, err) |
161 | #else /* !CONFIG_64BIT */ | 159 | #else /* !CONFIG_64BIT */ |
162 | #ifdef CONFIG_MMU | ||
163 | #define __get_user_8(x, ptr, err) \ | 160 | #define __get_user_8(x, ptr, err) \ |
164 | do { \ | 161 | do { \ |
165 | u32 __user *__ptr = (u32 __user *)(ptr); \ | 162 | u32 __user *__ptr = (u32 __user *)(ptr); \ |
@@ -193,7 +190,6 @@ do { \ | |||
193 | (x) = (__typeof__(x))((__typeof__((x)-(x)))( \ | 190 | (x) = (__typeof__(x))((__typeof__((x)-(x)))( \ |
194 | (((u64)__hi << 32) | __lo))); \ | 191 | (((u64)__hi << 32) | __lo))); \ |
195 | } while (0) | 192 | } while (0) |
196 | #endif /* CONFIG_MMU */ | ||
197 | #endif /* CONFIG_64BIT */ | 193 | #endif /* CONFIG_64BIT */ |
198 | 194 | ||
199 | 195 | ||
@@ -267,8 +263,6 @@ do { \ | |||
267 | ((x) = 0, -EFAULT); \ | 263 | ((x) = 0, -EFAULT); \ |
268 | }) | 264 | }) |
269 | 265 | ||
270 | |||
271 | #ifdef CONFIG_MMU | ||
272 | #define __put_user_asm(insn, x, ptr, err) \ | 266 | #define __put_user_asm(insn, x, ptr, err) \ |
273 | do { \ | 267 | do { \ |
274 | uintptr_t __tmp; \ | 268 | uintptr_t __tmp; \ |
@@ -292,14 +286,11 @@ do { \ | |||
292 | : "rJ" (__x), "i" (-EFAULT)); \ | 286 | : "rJ" (__x), "i" (-EFAULT)); \ |
293 | __disable_user_access(); \ | 287 | __disable_user_access(); \ |
294 | } while (0) | 288 | } while (0) |
295 | #endif /* CONFIG_MMU */ | ||
296 | |||
297 | 289 | ||
298 | #ifdef CONFIG_64BIT | 290 | #ifdef CONFIG_64BIT |
299 | #define __put_user_8(x, ptr, err) \ | 291 | #define __put_user_8(x, ptr, err) \ |
300 | __put_user_asm("sd", x, ptr, err) | 292 | __put_user_asm("sd", x, ptr, err) |
301 | #else /* !CONFIG_64BIT */ | 293 | #else /* !CONFIG_64BIT */ |
302 | #ifdef CONFIG_MMU | ||
303 | #define __put_user_8(x, ptr, err) \ | 294 | #define __put_user_8(x, ptr, err) \ |
304 | do { \ | 295 | do { \ |
305 | u32 __user *__ptr = (u32 __user *)(ptr); \ | 296 | u32 __user *__ptr = (u32 __user *)(ptr); \ |
@@ -329,7 +320,6 @@ do { \ | |||
329 | : "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \ | 320 | : "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \ |
330 | __disable_user_access(); \ | 321 | __disable_user_access(); \ |
331 | } while (0) | 322 | } while (0) |
332 | #endif /* CONFIG_MMU */ | ||
333 | #endif /* CONFIG_64BIT */ | 323 | #endif /* CONFIG_64BIT */ |
334 | 324 | ||
335 | 325 | ||
@@ -438,7 +428,6 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n) | |||
438 | * will set "err" to -EFAULT, while successful accesses return the previous | 428 | * will set "err" to -EFAULT, while successful accesses return the previous |
439 | * value. | 429 | * value. |
440 | */ | 430 | */ |
441 | #ifdef CONFIG_MMU | ||
442 | #define __cmpxchg_user(ptr, old, new, err, size, lrb, scb) \ | 431 | #define __cmpxchg_user(ptr, old, new, err, size, lrb, scb) \ |
443 | ({ \ | 432 | ({ \ |
444 | __typeof__(ptr) __ptr = (ptr); \ | 433 | __typeof__(ptr) __ptr = (ptr); \ |
@@ -508,6 +497,5 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n) | |||
508 | (err) = __err; \ | 497 | (err) = __err; \ |
509 | __ret; \ | 498 | __ret; \ |
510 | }) | 499 | }) |
511 | #endif /* CONFIG_MMU */ | ||
512 | 500 | ||
513 | #endif /* _ASM_RISCV_UACCESS_H */ | 501 | #endif /* _ASM_RISCV_UACCESS_H */ |
diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h index 9f250ed007cd..2f704a5c4196 100644 --- a/arch/riscv/include/asm/unistd.h +++ b/arch/riscv/include/asm/unistd.h | |||
@@ -14,3 +14,4 @@ | |||
14 | #define __ARCH_HAVE_MMU | 14 | #define __ARCH_HAVE_MMU |
15 | #define __ARCH_WANT_SYS_CLONE | 15 | #define __ARCH_WANT_SYS_CLONE |
16 | #include <uapi/asm/unistd.h> | 16 | #include <uapi/asm/unistd.h> |
17 | #include <uapi/asm/syscalls.h> | ||
diff --git a/arch/riscv/include/asm/vdso-syscalls.h b/arch/riscv/include/asm/vdso-syscalls.h deleted file mode 100644 index a2ccf1894929..000000000000 --- a/arch/riscv/include/asm/vdso-syscalls.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 SiFive | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef _ASM_RISCV_VDSO_SYSCALLS_H | ||
18 | #define _ASM_RISCV_VDSO_SYSCALLS_H | ||
19 | |||
20 | #ifdef CONFIG_SMP | ||
21 | |||
22 | /* These syscalls are only used by the vDSO and are not in the uapi. */ | ||
23 | #define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15) | ||
24 | __SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache) | ||
25 | |||
26 | #endif | ||
27 | |||
28 | #endif /* _ASM_RISCV_VDSO_H */ | ||
diff --git a/arch/riscv/include/uapi/asm/syscalls.h b/arch/riscv/include/uapi/asm/syscalls.h new file mode 100644 index 000000000000..818655b0d535 --- /dev/null +++ b/arch/riscv/include/uapi/asm/syscalls.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 SiFive | ||
4 | */ | ||
5 | |||
6 | #ifndef _ASM__UAPI__SYSCALLS_H | ||
7 | #define _ASM__UAPI__SYSCALLS_H | ||
8 | |||
9 | /* | ||
10 | * Allows the instruction cache to be flushed from userspace. Despite RISC-V | ||
11 | * having a direct 'fence.i' instruction available to userspace (which we | ||
12 | * can't trap!), that's not actually viable when running on Linux because the | ||
13 | * kernel might schedule a process on another hart. There is no way for | ||
14 | * userspace to handle this without invoking the kernel (as it doesn't know the | ||
15 | * thread->hart mappings), so we've defined a RISC-V specific system call to | ||
16 | * flush the instruction cache. | ||
17 | * | ||
18 | * __NR_riscv_flush_icache is defined to flush the instruction cache over an | ||
19 | * address range, with the flush applying to either all threads or just the | ||
20 | * caller. We don't currently do anything with the address range, that's just | ||
21 | * in there for forwards compatibility. | ||
22 | */ | ||
23 | #define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15) | ||
24 | __SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache) | ||
25 | |||
26 | #endif | ||
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 20ee86f782a9..7404ec222406 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S | |||
@@ -196,7 +196,7 @@ handle_syscall: | |||
196 | addi s2, s2, 0x4 | 196 | addi s2, s2, 0x4 |
197 | REG_S s2, PT_SEPC(sp) | 197 | REG_S s2, PT_SEPC(sp) |
198 | /* System calls run with interrupts enabled */ | 198 | /* System calls run with interrupts enabled */ |
199 | csrs sstatus, SR_IE | 199 | csrs sstatus, SR_SIE |
200 | /* Trace syscalls, but only if requested by the user. */ | 200 | /* Trace syscalls, but only if requested by the user. */ |
201 | REG_L t0, TASK_TI_FLAGS(tp) | 201 | REG_L t0, TASK_TI_FLAGS(tp) |
202 | andi t0, t0, _TIF_SYSCALL_TRACE | 202 | andi t0, t0, _TIF_SYSCALL_TRACE |
@@ -224,8 +224,8 @@ ret_from_syscall: | |||
224 | 224 | ||
225 | ret_from_exception: | 225 | ret_from_exception: |
226 | REG_L s0, PT_SSTATUS(sp) | 226 | REG_L s0, PT_SSTATUS(sp) |
227 | csrc sstatus, SR_IE | 227 | csrc sstatus, SR_SIE |
228 | andi s0, s0, SR_PS | 228 | andi s0, s0, SR_SPP |
229 | bnez s0, restore_all | 229 | bnez s0, restore_all |
230 | 230 | ||
231 | resume_userspace: | 231 | resume_userspace: |
@@ -255,7 +255,7 @@ work_pending: | |||
255 | bnez s1, work_resched | 255 | bnez s1, work_resched |
256 | work_notifysig: | 256 | work_notifysig: |
257 | /* Handle pending signals and notify-resume requests */ | 257 | /* Handle pending signals and notify-resume requests */ |
258 | csrs sstatus, SR_IE /* Enable interrupts for do_notify_resume() */ | 258 | csrs sstatus, SR_SIE /* Enable interrupts for do_notify_resume() */ |
259 | move a0, sp /* pt_regs */ | 259 | move a0, sp /* pt_regs */ |
260 | move a1, s0 /* current_thread_info->flags */ | 260 | move a1, s0 /* current_thread_info->flags */ |
261 | tail do_notify_resume | 261 | tail do_notify_resume |
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 0d90dcc1fbd3..d74d4adf2d54 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c | |||
@@ -76,7 +76,7 @@ void show_regs(struct pt_regs *regs) | |||
76 | void start_thread(struct pt_regs *regs, unsigned long pc, | 76 | void start_thread(struct pt_regs *regs, unsigned long pc, |
77 | unsigned long sp) | 77 | unsigned long sp) |
78 | { | 78 | { |
79 | regs->sstatus = SR_PIE /* User mode, irqs on */ | SR_FS_INITIAL; | 79 | regs->sstatus = SR_SPIE /* User mode, irqs on */ | SR_FS_INITIAL; |
80 | regs->sepc = pc; | 80 | regs->sepc = pc; |
81 | regs->sp = sp; | 81 | regs->sp = sp; |
82 | set_fs(USER_DS); | 82 | set_fs(USER_DS); |
@@ -110,7 +110,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
110 | const register unsigned long gp __asm__ ("gp"); | 110 | const register unsigned long gp __asm__ ("gp"); |
111 | memset(childregs, 0, sizeof(struct pt_regs)); | 111 | memset(childregs, 0, sizeof(struct pt_regs)); |
112 | childregs->gp = gp; | 112 | childregs->gp = gp; |
113 | childregs->sstatus = SR_PS | SR_PIE; /* Supervisor, irqs on */ | 113 | childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */ |
114 | 114 | ||
115 | p->thread.ra = (unsigned long)ret_from_kernel_thread; | 115 | p->thread.ra = (unsigned long)ret_from_kernel_thread; |
116 | p->thread.s[0] = usp; /* fn */ | 116 | p->thread.s[0] = usp; /* fn */ |
diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c index a5bd6401f95e..ade52b903a43 100644 --- a/arch/riscv/kernel/syscall_table.c +++ b/arch/riscv/kernel/syscall_table.c | |||
@@ -23,5 +23,4 @@ | |||
23 | void *sys_call_table[__NR_syscalls] = { | 23 | void *sys_call_table[__NR_syscalls] = { |
24 | [0 ... __NR_syscalls - 1] = sys_ni_syscall, | 24 | [0 ... __NR_syscalls - 1] = sys_ni_syscall, |
25 | #include <asm/unistd.h> | 25 | #include <asm/unistd.h> |
26 | #include <asm/vdso-syscalls.h> | ||
27 | }; | 26 | }; |
diff --git a/arch/riscv/kernel/vdso/flush_icache.S b/arch/riscv/kernel/vdso/flush_icache.S index b0fbad74e873..023e4d4aef58 100644 --- a/arch/riscv/kernel/vdso/flush_icache.S +++ b/arch/riscv/kernel/vdso/flush_icache.S | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
15 | #include <asm/unistd.h> | 15 | #include <asm/unistd.h> |
16 | #include <asm/vdso-syscalls.h> | ||
17 | 16 | ||
18 | .text | 17 | .text |
19 | /* int __vdso_flush_icache(void *start, void *end, unsigned long flags); */ | 18 | /* int __vdso_flush_icache(void *start, void *end, unsigned long flags); */ |
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index df2ca3c65048..0713f3c67ab4 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c | |||
@@ -63,7 +63,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs) | |||
63 | goto vmalloc_fault; | 63 | goto vmalloc_fault; |
64 | 64 | ||
65 | /* Enable interrupts if they were enabled in the parent context. */ | 65 | /* Enable interrupts if they were enabled in the parent context. */ |
66 | if (likely(regs->sstatus & SR_PIE)) | 66 | if (likely(regs->sstatus & SR_SPIE)) |
67 | local_irq_enable(); | 67 | local_irq_enable(); |
68 | 68 | ||
69 | /* | 69 | /* |
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c index 77c35350ee77..412326d59e6f 100644 --- a/arch/sh/boards/mach-se/770x/setup.c +++ b/arch/sh/boards/mach-se/770x/setup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/sh_eth.h> | ||
12 | #include <mach-se/mach/se.h> | 13 | #include <mach-se/mach/se.h> |
13 | #include <mach-se/mach/mrshpc.h> | 14 | #include <mach-se/mach/mrshpc.h> |
14 | #include <asm/machvec.h> | 15 | #include <asm/machvec.h> |
@@ -115,13 +116,23 @@ static struct platform_device heartbeat_device = { | |||
115 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\ | 116 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\ |
116 | defined(CONFIG_CPU_SUBTYPE_SH7712) | 117 | defined(CONFIG_CPU_SUBTYPE_SH7712) |
117 | /* SH771X Ethernet driver */ | 118 | /* SH771X Ethernet driver */ |
119 | static struct sh_eth_plat_data sh_eth_plat = { | ||
120 | .phy = PHY_ID, | ||
121 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
122 | }; | ||
123 | |||
118 | static struct resource sh_eth0_resources[] = { | 124 | static struct resource sh_eth0_resources[] = { |
119 | [0] = { | 125 | [0] = { |
120 | .start = SH_ETH0_BASE, | 126 | .start = SH_ETH0_BASE, |
121 | .end = SH_ETH0_BASE + 0x1B8, | 127 | .end = SH_ETH0_BASE + 0x1B8 - 1, |
122 | .flags = IORESOURCE_MEM, | 128 | .flags = IORESOURCE_MEM, |
123 | }, | 129 | }, |
124 | [1] = { | 130 | [1] = { |
131 | .start = SH_TSU_BASE, | ||
132 | .end = SH_TSU_BASE + 0x200 - 1, | ||
133 | .flags = IORESOURCE_MEM, | ||
134 | }, | ||
135 | [2] = { | ||
125 | .start = SH_ETH0_IRQ, | 136 | .start = SH_ETH0_IRQ, |
126 | .end = SH_ETH0_IRQ, | 137 | .end = SH_ETH0_IRQ, |
127 | .flags = IORESOURCE_IRQ, | 138 | .flags = IORESOURCE_IRQ, |
@@ -132,7 +143,7 @@ static struct platform_device sh_eth0_device = { | |||
132 | .name = "sh771x-ether", | 143 | .name = "sh771x-ether", |
133 | .id = 0, | 144 | .id = 0, |
134 | .dev = { | 145 | .dev = { |
135 | .platform_data = PHY_ID, | 146 | .platform_data = &sh_eth_plat, |
136 | }, | 147 | }, |
137 | .num_resources = ARRAY_SIZE(sh_eth0_resources), | 148 | .num_resources = ARRAY_SIZE(sh_eth0_resources), |
138 | .resource = sh_eth0_resources, | 149 | .resource = sh_eth0_resources, |
@@ -141,10 +152,15 @@ static struct platform_device sh_eth0_device = { | |||
141 | static struct resource sh_eth1_resources[] = { | 152 | static struct resource sh_eth1_resources[] = { |
142 | [0] = { | 153 | [0] = { |
143 | .start = SH_ETH1_BASE, | 154 | .start = SH_ETH1_BASE, |
144 | .end = SH_ETH1_BASE + 0x1B8, | 155 | .end = SH_ETH1_BASE + 0x1B8 - 1, |
145 | .flags = IORESOURCE_MEM, | 156 | .flags = IORESOURCE_MEM, |
146 | }, | 157 | }, |
147 | [1] = { | 158 | [1] = { |
159 | .start = SH_TSU_BASE, | ||
160 | .end = SH_TSU_BASE + 0x200 - 1, | ||
161 | .flags = IORESOURCE_MEM, | ||
162 | }, | ||
163 | [2] = { | ||
148 | .start = SH_ETH1_IRQ, | 164 | .start = SH_ETH1_IRQ, |
149 | .end = SH_ETH1_IRQ, | 165 | .end = SH_ETH1_IRQ, |
150 | .flags = IORESOURCE_IRQ, | 166 | .flags = IORESOURCE_IRQ, |
@@ -155,7 +171,7 @@ static struct platform_device sh_eth1_device = { | |||
155 | .name = "sh771x-ether", | 171 | .name = "sh771x-ether", |
156 | .id = 1, | 172 | .id = 1, |
157 | .dev = { | 173 | .dev = { |
158 | .platform_data = PHY_ID, | 174 | .platform_data = &sh_eth_plat, |
159 | }, | 175 | }, |
160 | .num_resources = ARRAY_SIZE(sh_eth1_resources), | 176 | .num_resources = ARRAY_SIZE(sh_eth1_resources), |
161 | .resource = sh_eth1_resources, | 177 | .resource = sh_eth1_resources, |
diff --git a/arch/sh/include/mach-se/mach/se.h b/arch/sh/include/mach-se/mach/se.h index 4246ef9b07a3..aa83fe1ff0b1 100644 --- a/arch/sh/include/mach-se/mach/se.h +++ b/arch/sh/include/mach-se/mach/se.h | |||
@@ -100,6 +100,7 @@ | |||
100 | /* Base address */ | 100 | /* Base address */ |
101 | #define SH_ETH0_BASE 0xA7000000 | 101 | #define SH_ETH0_BASE 0xA7000000 |
102 | #define SH_ETH1_BASE 0xA7000400 | 102 | #define SH_ETH1_BASE 0xA7000400 |
103 | #define SH_TSU_BASE 0xA7000800 | ||
103 | /* PHY ID */ | 104 | /* PHY ID */ |
104 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) | 105 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) |
105 | # define PHY_ID 0x00 | 106 | # define PHY_ID 0x00 |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d4fc98c50378..20da391b5f32 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -55,7 +55,6 @@ config X86 | |||
55 | select ARCH_HAS_GCOV_PROFILE_ALL | 55 | select ARCH_HAS_GCOV_PROFILE_ALL |
56 | select ARCH_HAS_KCOV if X86_64 | 56 | select ARCH_HAS_KCOV if X86_64 |
57 | select ARCH_HAS_PMEM_API if X86_64 | 57 | select ARCH_HAS_PMEM_API if X86_64 |
58 | # Causing hangs/crashes, see the commit that added this change for details. | ||
59 | select ARCH_HAS_REFCOUNT | 58 | select ARCH_HAS_REFCOUNT |
60 | select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 | 59 | select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 |
61 | select ARCH_HAS_SET_MEMORY | 60 | select ARCH_HAS_SET_MEMORY |
@@ -89,6 +88,7 @@ config X86 | |||
89 | select GENERIC_CLOCKEVENTS_MIN_ADJUST | 88 | select GENERIC_CLOCKEVENTS_MIN_ADJUST |
90 | select GENERIC_CMOS_UPDATE | 89 | select GENERIC_CMOS_UPDATE |
91 | select GENERIC_CPU_AUTOPROBE | 90 | select GENERIC_CPU_AUTOPROBE |
91 | select GENERIC_CPU_VULNERABILITIES | ||
92 | select GENERIC_EARLY_IOREMAP | 92 | select GENERIC_EARLY_IOREMAP |
93 | select GENERIC_FIND_FIRST_BIT | 93 | select GENERIC_FIND_FIRST_BIT |
94 | select GENERIC_IOMAP | 94 | select GENERIC_IOMAP |
@@ -429,6 +429,19 @@ config GOLDFISH | |||
429 | def_bool y | 429 | def_bool y |
430 | depends on X86_GOLDFISH | 430 | depends on X86_GOLDFISH |
431 | 431 | ||
432 | config RETPOLINE | ||
433 | bool "Avoid speculative indirect branches in kernel" | ||
434 | default y | ||
435 | help | ||
436 | Compile kernel with the retpoline compiler options to guard against | ||
437 | kernel-to-user data leaks by avoiding speculative indirect | ||
438 | branches. Requires a compiler with -mindirect-branch=thunk-extern | ||
439 | support for full protection. The kernel may run slower. | ||
440 | |||
441 | Without compiler support, at least indirect branches in assembler | ||
442 | code are eliminated. Since this includes the syscall entry path, | ||
443 | it is not entirely pointless. | ||
444 | |||
432 | config INTEL_RDT | 445 | config INTEL_RDT |
433 | bool "Intel Resource Director Technology support" | 446 | bool "Intel Resource Director Technology support" |
434 | default n | 447 | default n |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 3e73bc255e4e..fad55160dcb9 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -230,6 +230,14 @@ KBUILD_CFLAGS += -Wno-sign-compare | |||
230 | # | 230 | # |
231 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables | 231 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables |
232 | 232 | ||
233 | # Avoid indirect branches in kernel to deal with Spectre | ||
234 | ifdef CONFIG_RETPOLINE | ||
235 | RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) | ||
236 | ifneq ($(RETPOLINE_CFLAGS),) | ||
237 | KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE | ||
238 | endif | ||
239 | endif | ||
240 | |||
233 | archscripts: scripts_basic | 241 | archscripts: scripts_basic |
234 | $(Q)$(MAKE) $(build)=arch/x86/tools relocs | 242 | $(Q)$(MAKE) $(build)=arch/x86/tools relocs |
235 | 243 | ||
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 16627fec80b2..3d09e3aca18d 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/linkage.h> | 32 | #include <linux/linkage.h> |
33 | #include <asm/inst.h> | 33 | #include <asm/inst.h> |
34 | #include <asm/frame.h> | 34 | #include <asm/frame.h> |
35 | #include <asm/nospec-branch.h> | ||
35 | 36 | ||
36 | /* | 37 | /* |
37 | * The following macros are used to move an (un)aligned 16 byte value to/from | 38 | * The following macros are used to move an (un)aligned 16 byte value to/from |
@@ -2884,7 +2885,7 @@ ENTRY(aesni_xts_crypt8) | |||
2884 | pxor INC, STATE4 | 2885 | pxor INC, STATE4 |
2885 | movdqu IV, 0x30(OUTP) | 2886 | movdqu IV, 0x30(OUTP) |
2886 | 2887 | ||
2887 | call *%r11 | 2888 | CALL_NOSPEC %r11 |
2888 | 2889 | ||
2889 | movdqu 0x00(OUTP), INC | 2890 | movdqu 0x00(OUTP), INC |
2890 | pxor INC, STATE1 | 2891 | pxor INC, STATE1 |
@@ -2929,7 +2930,7 @@ ENTRY(aesni_xts_crypt8) | |||
2929 | _aesni_gf128mul_x_ble() | 2930 | _aesni_gf128mul_x_ble() |
2930 | movups IV, (IVP) | 2931 | movups IV, (IVP) |
2931 | 2932 | ||
2932 | call *%r11 | 2933 | CALL_NOSPEC %r11 |
2933 | 2934 | ||
2934 | movdqu 0x40(OUTP), INC | 2935 | movdqu 0x40(OUTP), INC |
2935 | pxor INC, STATE1 | 2936 | pxor INC, STATE1 |
diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S index f7c495e2863c..a14af6eb09cb 100644 --- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S +++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
19 | #include <asm/frame.h> | 19 | #include <asm/frame.h> |
20 | #include <asm/nospec-branch.h> | ||
20 | 21 | ||
21 | #define CAMELLIA_TABLE_BYTE_LEN 272 | 22 | #define CAMELLIA_TABLE_BYTE_LEN 272 |
22 | 23 | ||
@@ -1227,7 +1228,7 @@ camellia_xts_crypt_16way: | |||
1227 | vpxor 14 * 16(%rax), %xmm15, %xmm14; | 1228 | vpxor 14 * 16(%rax), %xmm15, %xmm14; |
1228 | vpxor 15 * 16(%rax), %xmm15, %xmm15; | 1229 | vpxor 15 * 16(%rax), %xmm15, %xmm15; |
1229 | 1230 | ||
1230 | call *%r9; | 1231 | CALL_NOSPEC %r9; |
1231 | 1232 | ||
1232 | addq $(16 * 16), %rsp; | 1233 | addq $(16 * 16), %rsp; |
1233 | 1234 | ||
diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S index eee5b3982cfd..b66bbfa62f50 100644 --- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S +++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <asm/frame.h> | 14 | #include <asm/frame.h> |
15 | #include <asm/nospec-branch.h> | ||
15 | 16 | ||
16 | #define CAMELLIA_TABLE_BYTE_LEN 272 | 17 | #define CAMELLIA_TABLE_BYTE_LEN 272 |
17 | 18 | ||
@@ -1343,7 +1344,7 @@ camellia_xts_crypt_32way: | |||
1343 | vpxor 14 * 32(%rax), %ymm15, %ymm14; | 1344 | vpxor 14 * 32(%rax), %ymm15, %ymm14; |
1344 | vpxor 15 * 32(%rax), %ymm15, %ymm15; | 1345 | vpxor 15 * 32(%rax), %ymm15, %ymm15; |
1345 | 1346 | ||
1346 | call *%r9; | 1347 | CALL_NOSPEC %r9; |
1347 | 1348 | ||
1348 | addq $(16 * 32), %rsp; | 1349 | addq $(16 * 32), %rsp; |
1349 | 1350 | ||
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S index 7a7de27c6f41..d9b734d0c8cc 100644 --- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S +++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S | |||
@@ -45,6 +45,7 @@ | |||
45 | 45 | ||
46 | #include <asm/inst.h> | 46 | #include <asm/inst.h> |
47 | #include <linux/linkage.h> | 47 | #include <linux/linkage.h> |
48 | #include <asm/nospec-branch.h> | ||
48 | 49 | ||
49 | ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction | 50 | ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction |
50 | 51 | ||
@@ -172,7 +173,7 @@ continue_block: | |||
172 | movzxw (bufp, %rax, 2), len | 173 | movzxw (bufp, %rax, 2), len |
173 | lea crc_array(%rip), bufp | 174 | lea crc_array(%rip), bufp |
174 | lea (bufp, len, 1), bufp | 175 | lea (bufp, len, 1), bufp |
175 | jmp *bufp | 176 | JMP_NOSPEC bufp |
176 | 177 | ||
177 | ################################################################ | 178 | ################################################################ |
178 | ## 2a) PROCESS FULL BLOCKS: | 179 | ## 2a) PROCESS FULL BLOCKS: |
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 45a63e00a6af..3f48f695d5e6 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h | |||
@@ -198,8 +198,11 @@ For 32-bit we have the following conventions - kernel is built with | |||
198 | * PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two | 198 | * PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two |
199 | * halves: | 199 | * halves: |
200 | */ | 200 | */ |
201 | #define PTI_SWITCH_PGTABLES_MASK (1<<PAGE_SHIFT) | 201 | #define PTI_USER_PGTABLE_BIT PAGE_SHIFT |
202 | #define PTI_SWITCH_MASK (PTI_SWITCH_PGTABLES_MASK|(1<<X86_CR3_PTI_SWITCH_BIT)) | 202 | #define PTI_USER_PGTABLE_MASK (1 << PTI_USER_PGTABLE_BIT) |
203 | #define PTI_USER_PCID_BIT X86_CR3_PTI_PCID_USER_BIT | ||
204 | #define PTI_USER_PCID_MASK (1 << PTI_USER_PCID_BIT) | ||
205 | #define PTI_USER_PGTABLE_AND_PCID_MASK (PTI_USER_PCID_MASK | PTI_USER_PGTABLE_MASK) | ||
203 | 206 | ||
204 | .macro SET_NOFLUSH_BIT reg:req | 207 | .macro SET_NOFLUSH_BIT reg:req |
205 | bts $X86_CR3_PCID_NOFLUSH_BIT, \reg | 208 | bts $X86_CR3_PCID_NOFLUSH_BIT, \reg |
@@ -208,7 +211,7 @@ For 32-bit we have the following conventions - kernel is built with | |||
208 | .macro ADJUST_KERNEL_CR3 reg:req | 211 | .macro ADJUST_KERNEL_CR3 reg:req |
209 | ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID | 212 | ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID |
210 | /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */ | 213 | /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */ |
211 | andq $(~PTI_SWITCH_MASK), \reg | 214 | andq $(~PTI_USER_PGTABLE_AND_PCID_MASK), \reg |
212 | .endm | 215 | .endm |
213 | 216 | ||
214 | .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req | 217 | .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req |
@@ -239,15 +242,19 @@ For 32-bit we have the following conventions - kernel is built with | |||
239 | /* Flush needed, clear the bit */ | 242 | /* Flush needed, clear the bit */ |
240 | btr \scratch_reg, THIS_CPU_user_pcid_flush_mask | 243 | btr \scratch_reg, THIS_CPU_user_pcid_flush_mask |
241 | movq \scratch_reg2, \scratch_reg | 244 | movq \scratch_reg2, \scratch_reg |
242 | jmp .Lwrcr3_\@ | 245 | jmp .Lwrcr3_pcid_\@ |
243 | 246 | ||
244 | .Lnoflush_\@: | 247 | .Lnoflush_\@: |
245 | movq \scratch_reg2, \scratch_reg | 248 | movq \scratch_reg2, \scratch_reg |
246 | SET_NOFLUSH_BIT \scratch_reg | 249 | SET_NOFLUSH_BIT \scratch_reg |
247 | 250 | ||
251 | .Lwrcr3_pcid_\@: | ||
252 | /* Flip the ASID to the user version */ | ||
253 | orq $(PTI_USER_PCID_MASK), \scratch_reg | ||
254 | |||
248 | .Lwrcr3_\@: | 255 | .Lwrcr3_\@: |
249 | /* Flip the PGD and ASID to the user version */ | 256 | /* Flip the PGD to the user version */ |
250 | orq $(PTI_SWITCH_MASK), \scratch_reg | 257 | orq $(PTI_USER_PGTABLE_MASK), \scratch_reg |
251 | mov \scratch_reg, %cr3 | 258 | mov \scratch_reg, %cr3 |
252 | .Lend_\@: | 259 | .Lend_\@: |
253 | .endm | 260 | .endm |
@@ -263,17 +270,12 @@ For 32-bit we have the following conventions - kernel is built with | |||
263 | movq %cr3, \scratch_reg | 270 | movq %cr3, \scratch_reg |
264 | movq \scratch_reg, \save_reg | 271 | movq \scratch_reg, \save_reg |
265 | /* | 272 | /* |
266 | * Is the "switch mask" all zero? That means that both of | 273 | * Test the user pagetable bit. If set, then the user page tables |
267 | * these are zero: | 274 | * are active. If clear CR3 already has the kernel page table |
268 | * | 275 | * active. |
269 | * 1. The user/kernel PCID bit, and | ||
270 | * 2. The user/kernel "bit" that points CR3 to the | ||
271 | * bottom half of the 8k PGD | ||
272 | * | ||
273 | * That indicates a kernel CR3 value, not a user CR3. | ||
274 | */ | 276 | */ |
275 | testq $(PTI_SWITCH_MASK), \scratch_reg | 277 | bt $PTI_USER_PGTABLE_BIT, \scratch_reg |
276 | jz .Ldone_\@ | 278 | jnc .Ldone_\@ |
277 | 279 | ||
278 | ADJUST_KERNEL_CR3 \scratch_reg | 280 | ADJUST_KERNEL_CR3 \scratch_reg |
279 | movq \scratch_reg, %cr3 | 281 | movq \scratch_reg, %cr3 |
@@ -290,7 +292,7 @@ For 32-bit we have the following conventions - kernel is built with | |||
290 | * KERNEL pages can always resume with NOFLUSH as we do | 292 | * KERNEL pages can always resume with NOFLUSH as we do |
291 | * explicit flushes. | 293 | * explicit flushes. |
292 | */ | 294 | */ |
293 | bt $X86_CR3_PTI_SWITCH_BIT, \save_reg | 295 | bt $PTI_USER_PGTABLE_BIT, \save_reg |
294 | jnc .Lnoflush_\@ | 296 | jnc .Lnoflush_\@ |
295 | 297 | ||
296 | /* | 298 | /* |
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index ace8f321a5a1..a1f28a54f23a 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/asm.h> | 44 | #include <asm/asm.h> |
45 | #include <asm/smap.h> | 45 | #include <asm/smap.h> |
46 | #include <asm/frame.h> | 46 | #include <asm/frame.h> |
47 | #include <asm/nospec-branch.h> | ||
47 | 48 | ||
48 | .section .entry.text, "ax" | 49 | .section .entry.text, "ax" |
49 | 50 | ||
@@ -290,7 +291,7 @@ ENTRY(ret_from_fork) | |||
290 | 291 | ||
291 | /* kernel thread */ | 292 | /* kernel thread */ |
292 | 1: movl %edi, %eax | 293 | 1: movl %edi, %eax |
293 | call *%ebx | 294 | CALL_NOSPEC %ebx |
294 | /* | 295 | /* |
295 | * A kernel thread is allowed to return here after successfully | 296 | * A kernel thread is allowed to return here after successfully |
296 | * calling do_execve(). Exit to userspace to complete the execve() | 297 | * calling do_execve(). Exit to userspace to complete the execve() |
@@ -919,7 +920,7 @@ common_exception: | |||
919 | movl %ecx, %es | 920 | movl %ecx, %es |
920 | TRACE_IRQS_OFF | 921 | TRACE_IRQS_OFF |
921 | movl %esp, %eax # pt_regs pointer | 922 | movl %esp, %eax # pt_regs pointer |
922 | call *%edi | 923 | CALL_NOSPEC %edi |
923 | jmp ret_from_exception | 924 | jmp ret_from_exception |
924 | END(common_exception) | 925 | END(common_exception) |
925 | 926 | ||
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index f048e384ff54..4f8e1d35a97c 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/pgtable_types.h> | 37 | #include <asm/pgtable_types.h> |
38 | #include <asm/export.h> | 38 | #include <asm/export.h> |
39 | #include <asm/frame.h> | 39 | #include <asm/frame.h> |
40 | #include <asm/nospec-branch.h> | ||
40 | #include <linux/err.h> | 41 | #include <linux/err.h> |
41 | 42 | ||
42 | #include "calling.h" | 43 | #include "calling.h" |
@@ -191,7 +192,7 @@ ENTRY(entry_SYSCALL_64_trampoline) | |||
191 | */ | 192 | */ |
192 | pushq %rdi | 193 | pushq %rdi |
193 | movq $entry_SYSCALL_64_stage2, %rdi | 194 | movq $entry_SYSCALL_64_stage2, %rdi |
194 | jmp *%rdi | 195 | JMP_NOSPEC %rdi |
195 | END(entry_SYSCALL_64_trampoline) | 196 | END(entry_SYSCALL_64_trampoline) |
196 | 197 | ||
197 | .popsection | 198 | .popsection |
@@ -270,7 +271,12 @@ entry_SYSCALL_64_fastpath: | |||
270 | * It might end up jumping to the slow path. If it jumps, RAX | 271 | * It might end up jumping to the slow path. If it jumps, RAX |
271 | * and all argument registers are clobbered. | 272 | * and all argument registers are clobbered. |
272 | */ | 273 | */ |
274 | #ifdef CONFIG_RETPOLINE | ||
275 | movq sys_call_table(, %rax, 8), %rax | ||
276 | call __x86_indirect_thunk_rax | ||
277 | #else | ||
273 | call *sys_call_table(, %rax, 8) | 278 | call *sys_call_table(, %rax, 8) |
279 | #endif | ||
274 | .Lentry_SYSCALL_64_after_fastpath_call: | 280 | .Lentry_SYSCALL_64_after_fastpath_call: |
275 | 281 | ||
276 | movq %rax, RAX(%rsp) | 282 | movq %rax, RAX(%rsp) |
@@ -442,7 +448,7 @@ ENTRY(stub_ptregs_64) | |||
442 | jmp entry_SYSCALL64_slow_path | 448 | jmp entry_SYSCALL64_slow_path |
443 | 449 | ||
444 | 1: | 450 | 1: |
445 | jmp *%rax /* Called from C */ | 451 | JMP_NOSPEC %rax /* Called from C */ |
446 | END(stub_ptregs_64) | 452 | END(stub_ptregs_64) |
447 | 453 | ||
448 | .macro ptregs_stub func | 454 | .macro ptregs_stub func |
@@ -521,7 +527,7 @@ ENTRY(ret_from_fork) | |||
521 | 1: | 527 | 1: |
522 | /* kernel thread */ | 528 | /* kernel thread */ |
523 | movq %r12, %rdi | 529 | movq %r12, %rdi |
524 | call *%rbx | 530 | CALL_NOSPEC %rbx |
525 | /* | 531 | /* |
526 | * A kernel thread is allowed to return here after successfully | 532 | * A kernel thread is allowed to return here after successfully |
527 | * calling do_execve(). Exit to userspace to complete the execve() | 533 | * calling do_execve(). Exit to userspace to complete the execve() |
diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index 141e07b06216..24ffa1e88cf9 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c | |||
@@ -582,6 +582,24 @@ static __init int bts_init(void) | |||
582 | if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts) | 582 | if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts) |
583 | return -ENODEV; | 583 | return -ENODEV; |
584 | 584 | ||
585 | if (boot_cpu_has(X86_FEATURE_PTI)) { | ||
586 | /* | ||
587 | * BTS hardware writes through a virtual memory map we must | ||
588 | * either use the kernel physical map, or the user mapping of | ||
589 | * the AUX buffer. | ||
590 | * | ||
591 | * However, since this driver supports per-CPU and per-task inherit | ||
592 | * we cannot use the user mapping since it will not be availble | ||
593 | * if we're not running the owning process. | ||
594 | * | ||
595 | * With PTI we can't use the kernal map either, because its not | ||
596 | * there when we run userspace. | ||
597 | * | ||
598 | * For now, disable this driver when using PTI. | ||
599 | */ | ||
600 | return -ENODEV; | ||
601 | } | ||
602 | |||
585 | bts_pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE | | 603 | bts_pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE | |
586 | PERF_PMU_CAP_EXCLUSIVE; | 604 | PERF_PMU_CAP_EXCLUSIVE; |
587 | bts_pmu.task_ctx_nr = perf_sw_context; | 605 | bts_pmu.task_ctx_nr = perf_sw_context; |
diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h index ff700d81e91e..0927cdc4f946 100644 --- a/arch/x86/include/asm/asm-prototypes.h +++ b/arch/x86/include/asm/asm-prototypes.h | |||
@@ -11,7 +11,32 @@ | |||
11 | #include <asm/pgtable.h> | 11 | #include <asm/pgtable.h> |
12 | #include <asm/special_insns.h> | 12 | #include <asm/special_insns.h> |
13 | #include <asm/preempt.h> | 13 | #include <asm/preempt.h> |
14 | #include <asm/asm.h> | ||
14 | 15 | ||
15 | #ifndef CONFIG_X86_CMPXCHG64 | 16 | #ifndef CONFIG_X86_CMPXCHG64 |
16 | extern void cmpxchg8b_emu(void); | 17 | extern void cmpxchg8b_emu(void); |
17 | #endif | 18 | #endif |
19 | |||
20 | #ifdef CONFIG_RETPOLINE | ||
21 | #ifdef CONFIG_X86_32 | ||
22 | #define INDIRECT_THUNK(reg) extern asmlinkage void __x86_indirect_thunk_e ## reg(void); | ||
23 | #else | ||
24 | #define INDIRECT_THUNK(reg) extern asmlinkage void __x86_indirect_thunk_r ## reg(void); | ||
25 | INDIRECT_THUNK(8) | ||
26 | INDIRECT_THUNK(9) | ||
27 | INDIRECT_THUNK(10) | ||
28 | INDIRECT_THUNK(11) | ||
29 | INDIRECT_THUNK(12) | ||
30 | INDIRECT_THUNK(13) | ||
31 | INDIRECT_THUNK(14) | ||
32 | INDIRECT_THUNK(15) | ||
33 | #endif | ||
34 | INDIRECT_THUNK(ax) | ||
35 | INDIRECT_THUNK(bx) | ||
36 | INDIRECT_THUNK(cx) | ||
37 | INDIRECT_THUNK(dx) | ||
38 | INDIRECT_THUNK(si) | ||
39 | INDIRECT_THUNK(di) | ||
40 | INDIRECT_THUNK(bp) | ||
41 | INDIRECT_THUNK(sp) | ||
42 | #endif /* CONFIG_RETPOLINE */ | ||
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 21ac898df2d8..f275447862f4 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h | |||
@@ -203,6 +203,8 @@ | |||
203 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ | 203 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ |
204 | #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ | 204 | #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ |
205 | #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ | 205 | #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ |
206 | #define X86_FEATURE_RETPOLINE ( 7*32+12) /* Generic Retpoline mitigation for Spectre variant 2 */ | ||
207 | #define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* AMD Retpoline mitigation for Spectre variant 2 */ | ||
206 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ | 208 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ |
207 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ | 209 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ |
208 | #define X86_FEATURE_AVX512_4VNNIW ( 7*32+16) /* AVX-512 Neural Network Instructions */ | 210 | #define X86_FEATURE_AVX512_4VNNIW ( 7*32+16) /* AVX-512 Neural Network Instructions */ |
@@ -342,5 +344,7 @@ | |||
342 | #define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */ | 344 | #define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */ |
343 | #define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */ | 345 | #define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */ |
344 | #define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ | 346 | #define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ |
347 | #define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ | ||
348 | #define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ | ||
345 | 349 | ||
346 | #endif /* _ASM_X86_CPUFEATURES_H */ | 350 | #endif /* _ASM_X86_CPUFEATURES_H */ |
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 5400add2885b..8bf450b13d9f 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/nmi.h> | 7 | #include <linux/nmi.h> |
8 | #include <asm/io.h> | 8 | #include <asm/io.h> |
9 | #include <asm/hyperv.h> | 9 | #include <asm/hyperv.h> |
10 | #include <asm/nospec-branch.h> | ||
10 | 11 | ||
11 | /* | 12 | /* |
12 | * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent | 13 | * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent |
@@ -186,10 +187,11 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) | |||
186 | return U64_MAX; | 187 | return U64_MAX; |
187 | 188 | ||
188 | __asm__ __volatile__("mov %4, %%r8\n" | 189 | __asm__ __volatile__("mov %4, %%r8\n" |
189 | "call *%5" | 190 | CALL_NOSPEC |
190 | : "=a" (hv_status), ASM_CALL_CONSTRAINT, | 191 | : "=a" (hv_status), ASM_CALL_CONSTRAINT, |
191 | "+c" (control), "+d" (input_address) | 192 | "+c" (control), "+d" (input_address) |
192 | : "r" (output_address), "m" (hv_hypercall_pg) | 193 | : "r" (output_address), |
194 | THUNK_TARGET(hv_hypercall_pg) | ||
193 | : "cc", "memory", "r8", "r9", "r10", "r11"); | 195 | : "cc", "memory", "r8", "r9", "r10", "r11"); |
194 | #else | 196 | #else |
195 | u32 input_address_hi = upper_32_bits(input_address); | 197 | u32 input_address_hi = upper_32_bits(input_address); |
@@ -200,13 +202,13 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) | |||
200 | if (!hv_hypercall_pg) | 202 | if (!hv_hypercall_pg) |
201 | return U64_MAX; | 203 | return U64_MAX; |
202 | 204 | ||
203 | __asm__ __volatile__("call *%7" | 205 | __asm__ __volatile__(CALL_NOSPEC |
204 | : "=A" (hv_status), | 206 | : "=A" (hv_status), |
205 | "+c" (input_address_lo), ASM_CALL_CONSTRAINT | 207 | "+c" (input_address_lo), ASM_CALL_CONSTRAINT |
206 | : "A" (control), | 208 | : "A" (control), |
207 | "b" (input_address_hi), | 209 | "b" (input_address_hi), |
208 | "D"(output_address_hi), "S"(output_address_lo), | 210 | "D"(output_address_hi), "S"(output_address_lo), |
209 | "m" (hv_hypercall_pg) | 211 | THUNK_TARGET(hv_hypercall_pg) |
210 | : "cc", "memory"); | 212 | : "cc", "memory"); |
211 | #endif /* !x86_64 */ | 213 | #endif /* !x86_64 */ |
212 | return hv_status; | 214 | return hv_status; |
@@ -227,10 +229,10 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) | |||
227 | 229 | ||
228 | #ifdef CONFIG_X86_64 | 230 | #ifdef CONFIG_X86_64 |
229 | { | 231 | { |
230 | __asm__ __volatile__("call *%4" | 232 | __asm__ __volatile__(CALL_NOSPEC |
231 | : "=a" (hv_status), ASM_CALL_CONSTRAINT, | 233 | : "=a" (hv_status), ASM_CALL_CONSTRAINT, |
232 | "+c" (control), "+d" (input1) | 234 | "+c" (control), "+d" (input1) |
233 | : "m" (hv_hypercall_pg) | 235 | : THUNK_TARGET(hv_hypercall_pg) |
234 | : "cc", "r8", "r9", "r10", "r11"); | 236 | : "cc", "r8", "r9", "r10", "r11"); |
235 | } | 237 | } |
236 | #else | 238 | #else |
@@ -238,13 +240,13 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) | |||
238 | u32 input1_hi = upper_32_bits(input1); | 240 | u32 input1_hi = upper_32_bits(input1); |
239 | u32 input1_lo = lower_32_bits(input1); | 241 | u32 input1_lo = lower_32_bits(input1); |
240 | 242 | ||
241 | __asm__ __volatile__ ("call *%5" | 243 | __asm__ __volatile__ (CALL_NOSPEC |
242 | : "=A"(hv_status), | 244 | : "=A"(hv_status), |
243 | "+c"(input1_lo), | 245 | "+c"(input1_lo), |
244 | ASM_CALL_CONSTRAINT | 246 | ASM_CALL_CONSTRAINT |
245 | : "A" (control), | 247 | : "A" (control), |
246 | "b" (input1_hi), | 248 | "b" (input1_hi), |
247 | "m" (hv_hypercall_pg) | 249 | THUNK_TARGET(hv_hypercall_pg) |
248 | : "cc", "edi", "esi"); | 250 | : "cc", "edi", "esi"); |
249 | } | 251 | } |
250 | #endif | 252 | #endif |
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 34c4922bbc3f..e7b983a35506 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
@@ -355,6 +355,9 @@ | |||
355 | #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL | 355 | #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL |
356 | #define FAM10H_MMIO_CONF_BASE_SHIFT 20 | 356 | #define FAM10H_MMIO_CONF_BASE_SHIFT 20 |
357 | #define MSR_FAM10H_NODE_ID 0xc001100c | 357 | #define MSR_FAM10H_NODE_ID 0xc001100c |
358 | #define MSR_F10H_DECFG 0xc0011029 | ||
359 | #define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1 | ||
360 | #define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT) | ||
358 | 361 | ||
359 | /* K8 MSRs */ | 362 | /* K8 MSRs */ |
360 | #define MSR_K8_TOP_MEM1 0xc001001a | 363 | #define MSR_K8_TOP_MEM1 0xc001001a |
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h new file mode 100644 index 000000000000..402a11c803c3 --- /dev/null +++ b/arch/x86/include/asm/nospec-branch.h | |||
@@ -0,0 +1,214 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #ifndef __NOSPEC_BRANCH_H__ | ||
4 | #define __NOSPEC_BRANCH_H__ | ||
5 | |||
6 | #include <asm/alternative.h> | ||
7 | #include <asm/alternative-asm.h> | ||
8 | #include <asm/cpufeatures.h> | ||
9 | |||
10 | /* | ||
11 | * Fill the CPU return stack buffer. | ||
12 | * | ||
13 | * Each entry in the RSB, if used for a speculative 'ret', contains an | ||
14 | * infinite 'pause; jmp' loop to capture speculative execution. | ||
15 | * | ||
16 | * This is required in various cases for retpoline and IBRS-based | ||
17 | * mitigations for the Spectre variant 2 vulnerability. Sometimes to | ||
18 | * eliminate potentially bogus entries from the RSB, and sometimes | ||
19 | * purely to ensure that it doesn't get empty, which on some CPUs would | ||
20 | * allow predictions from other (unwanted!) sources to be used. | ||
21 | * | ||
22 | * We define a CPP macro such that it can be used from both .S files and | ||
23 | * inline assembly. It's possible to do a .macro and then include that | ||
24 | * from C via asm(".include <asm/nospec-branch.h>") but let's not go there. | ||
25 | */ | ||
26 | |||
27 | #define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ | ||
28 | #define RSB_FILL_LOOPS 16 /* To avoid underflow */ | ||
29 | |||
30 | /* | ||
31 | * Google experimented with loop-unrolling and this turned out to be | ||
32 | * the optimal version — two calls, each with their own speculation | ||
33 | * trap should their return address end up getting used, in a loop. | ||
34 | */ | ||
35 | #define __FILL_RETURN_BUFFER(reg, nr, sp) \ | ||
36 | mov $(nr/2), reg; \ | ||
37 | 771: \ | ||
38 | call 772f; \ | ||
39 | 773: /* speculation trap */ \ | ||
40 | pause; \ | ||
41 | jmp 773b; \ | ||
42 | 772: \ | ||
43 | call 774f; \ | ||
44 | 775: /* speculation trap */ \ | ||
45 | pause; \ | ||
46 | jmp 775b; \ | ||
47 | 774: \ | ||
48 | dec reg; \ | ||
49 | jnz 771b; \ | ||
50 | add $(BITS_PER_LONG/8) * nr, sp; | ||
51 | |||
52 | #ifdef __ASSEMBLY__ | ||
53 | |||
54 | /* | ||
55 | * This should be used immediately before a retpoline alternative. It tells | ||
56 | * objtool where the retpolines are so that it can make sense of the control | ||
57 | * flow by just reading the original instruction(s) and ignoring the | ||
58 | * alternatives. | ||
59 | */ | ||
60 | .macro ANNOTATE_NOSPEC_ALTERNATIVE | ||
61 | .Lannotate_\@: | ||
62 | .pushsection .discard.nospec | ||
63 | .long .Lannotate_\@ - . | ||
64 | .popsection | ||
65 | .endm | ||
66 | |||
67 | /* | ||
68 | * These are the bare retpoline primitives for indirect jmp and call. | ||
69 | * Do not use these directly; they only exist to make the ALTERNATIVE | ||
70 | * invocation below less ugly. | ||
71 | */ | ||
72 | .macro RETPOLINE_JMP reg:req | ||
73 | call .Ldo_rop_\@ | ||
74 | .Lspec_trap_\@: | ||
75 | pause | ||
76 | jmp .Lspec_trap_\@ | ||
77 | .Ldo_rop_\@: | ||
78 | mov \reg, (%_ASM_SP) | ||
79 | ret | ||
80 | .endm | ||
81 | |||
82 | /* | ||
83 | * This is a wrapper around RETPOLINE_JMP so the called function in reg | ||
84 | * returns to the instruction after the macro. | ||
85 | */ | ||
86 | .macro RETPOLINE_CALL reg:req | ||
87 | jmp .Ldo_call_\@ | ||
88 | .Ldo_retpoline_jmp_\@: | ||
89 | RETPOLINE_JMP \reg | ||
90 | .Ldo_call_\@: | ||
91 | call .Ldo_retpoline_jmp_\@ | ||
92 | .endm | ||
93 | |||
94 | /* | ||
95 | * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple | ||
96 | * indirect jmp/call which may be susceptible to the Spectre variant 2 | ||
97 | * attack. | ||
98 | */ | ||
99 | .macro JMP_NOSPEC reg:req | ||
100 | #ifdef CONFIG_RETPOLINE | ||
101 | ANNOTATE_NOSPEC_ALTERNATIVE | ||
102 | ALTERNATIVE_2 __stringify(jmp *\reg), \ | ||
103 | __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \ | ||
104 | __stringify(lfence; jmp *\reg), X86_FEATURE_RETPOLINE_AMD | ||
105 | #else | ||
106 | jmp *\reg | ||
107 | #endif | ||
108 | .endm | ||
109 | |||
110 | .macro CALL_NOSPEC reg:req | ||
111 | #ifdef CONFIG_RETPOLINE | ||
112 | ANNOTATE_NOSPEC_ALTERNATIVE | ||
113 | ALTERNATIVE_2 __stringify(call *\reg), \ | ||
114 | __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ | ||
115 | __stringify(lfence; call *\reg), X86_FEATURE_RETPOLINE_AMD | ||
116 | #else | ||
117 | call *\reg | ||
118 | #endif | ||
119 | .endm | ||
120 | |||
121 | /* | ||
122 | * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP | ||
123 | * monstrosity above, manually. | ||
124 | */ | ||
125 | .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req | ||
126 | #ifdef CONFIG_RETPOLINE | ||
127 | ANNOTATE_NOSPEC_ALTERNATIVE | ||
128 | ALTERNATIVE "jmp .Lskip_rsb_\@", \ | ||
129 | __stringify(__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)) \ | ||
130 | \ftr | ||
131 | .Lskip_rsb_\@: | ||
132 | #endif | ||
133 | .endm | ||
134 | |||
135 | #else /* __ASSEMBLY__ */ | ||
136 | |||
137 | #define ANNOTATE_NOSPEC_ALTERNATIVE \ | ||
138 | "999:\n\t" \ | ||
139 | ".pushsection .discard.nospec\n\t" \ | ||
140 | ".long 999b - .\n\t" \ | ||
141 | ".popsection\n\t" | ||
142 | |||
143 | #if defined(CONFIG_X86_64) && defined(RETPOLINE) | ||
144 | |||
145 | /* | ||
146 | * Since the inline asm uses the %V modifier which is only in newer GCC, | ||
147 | * the 64-bit one is dependent on RETPOLINE not CONFIG_RETPOLINE. | ||
148 | */ | ||
149 | # define CALL_NOSPEC \ | ||
150 | ANNOTATE_NOSPEC_ALTERNATIVE \ | ||
151 | ALTERNATIVE( \ | ||
152 | "call *%[thunk_target]\n", \ | ||
153 | "call __x86_indirect_thunk_%V[thunk_target]\n", \ | ||
154 | X86_FEATURE_RETPOLINE) | ||
155 | # define THUNK_TARGET(addr) [thunk_target] "r" (addr) | ||
156 | |||
157 | #elif defined(CONFIG_X86_32) && defined(CONFIG_RETPOLINE) | ||
158 | /* | ||
159 | * For i386 we use the original ret-equivalent retpoline, because | ||
160 | * otherwise we'll run out of registers. We don't care about CET | ||
161 | * here, anyway. | ||
162 | */ | ||
163 | # define CALL_NOSPEC ALTERNATIVE("call *%[thunk_target]\n", \ | ||
164 | " jmp 904f;\n" \ | ||
165 | " .align 16\n" \ | ||
166 | "901: call 903f;\n" \ | ||
167 | "902: pause;\n" \ | ||
168 | " jmp 902b;\n" \ | ||
169 | " .align 16\n" \ | ||
170 | "903: addl $4, %%esp;\n" \ | ||
171 | " pushl %[thunk_target];\n" \ | ||
172 | " ret;\n" \ | ||
173 | " .align 16\n" \ | ||
174 | "904: call 901b;\n", \ | ||
175 | X86_FEATURE_RETPOLINE) | ||
176 | |||
177 | # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) | ||
178 | #else /* No retpoline for C / inline asm */ | ||
179 | # define CALL_NOSPEC "call *%[thunk_target]\n" | ||
180 | # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) | ||
181 | #endif | ||
182 | |||
183 | /* The Spectre V2 mitigation variants */ | ||
184 | enum spectre_v2_mitigation { | ||
185 | SPECTRE_V2_NONE, | ||
186 | SPECTRE_V2_RETPOLINE_MINIMAL, | ||
187 | SPECTRE_V2_RETPOLINE_MINIMAL_AMD, | ||
188 | SPECTRE_V2_RETPOLINE_GENERIC, | ||
189 | SPECTRE_V2_RETPOLINE_AMD, | ||
190 | SPECTRE_V2_IBRS, | ||
191 | }; | ||
192 | |||
193 | /* | ||
194 | * On VMEXIT we must ensure that no RSB predictions learned in the guest | ||
195 | * can be followed in the host, by overwriting the RSB completely. Both | ||
196 | * retpoline and IBRS mitigations for Spectre v2 need this; only on future | ||
197 | * CPUs with IBRS_ATT *might* it be avoided. | ||
198 | */ | ||
199 | static inline void vmexit_fill_RSB(void) | ||
200 | { | ||
201 | #ifdef CONFIG_RETPOLINE | ||
202 | unsigned long loops = RSB_CLEAR_LOOPS / 2; | ||
203 | |||
204 | asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE | ||
205 | ALTERNATIVE("jmp 910f", | ||
206 | __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)), | ||
207 | X86_FEATURE_RETPOLINE) | ||
208 | "910:" | ||
209 | : "=&r" (loops), ASM_CALL_CONSTRAINT | ||
210 | : "r" (loops) : "memory" ); | ||
211 | #endif | ||
212 | } | ||
213 | #endif /* __ASSEMBLY__ */ | ||
214 | #endif /* __NOSPEC_BRANCH_H__ */ | ||
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 7a5d6695abd3..eb66fa9cd0fc 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -38,6 +38,7 @@ do { \ | |||
38 | #define PCI_NOASSIGN_ROMS 0x80000 | 38 | #define PCI_NOASSIGN_ROMS 0x80000 |
39 | #define PCI_ROOT_NO_CRS 0x100000 | 39 | #define PCI_ROOT_NO_CRS 0x100000 |
40 | #define PCI_NOASSIGN_BARS 0x200000 | 40 | #define PCI_NOASSIGN_BARS 0x200000 |
41 | #define PCI_BIG_ROOT_WINDOW 0x400000 | ||
41 | 42 | ||
42 | extern unsigned int pci_probe; | 43 | extern unsigned int pci_probe; |
43 | extern unsigned long pirq_table_addr; | 44 | extern unsigned long pirq_table_addr; |
diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h index 6a60fea90b9d..625a52a5594f 100644 --- a/arch/x86/include/asm/processor-flags.h +++ b/arch/x86/include/asm/processor-flags.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define CR3_NOFLUSH BIT_ULL(63) | 40 | #define CR3_NOFLUSH BIT_ULL(63) |
41 | 41 | ||
42 | #ifdef CONFIG_PAGE_TABLE_ISOLATION | 42 | #ifdef CONFIG_PAGE_TABLE_ISOLATION |
43 | # define X86_CR3_PTI_SWITCH_BIT 11 | 43 | # define X86_CR3_PTI_PCID_USER_BIT 11 |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #else | 46 | #else |
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 4a08dd2ab32a..d33e4a26dc7e 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
@@ -81,13 +81,13 @@ static inline u16 kern_pcid(u16 asid) | |||
81 | * Make sure that the dynamic ASID space does not confict with the | 81 | * Make sure that the dynamic ASID space does not confict with the |
82 | * bit we are using to switch between user and kernel ASIDs. | 82 | * bit we are using to switch between user and kernel ASIDs. |
83 | */ | 83 | */ |
84 | BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_SWITCH_BIT)); | 84 | BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_PCID_USER_BIT)); |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * The ASID being passed in here should have respected the | 87 | * The ASID being passed in here should have respected the |
88 | * MAX_ASID_AVAILABLE and thus never have the switch bit set. | 88 | * MAX_ASID_AVAILABLE and thus never have the switch bit set. |
89 | */ | 89 | */ |
90 | VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_SWITCH_BIT)); | 90 | VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_PCID_USER_BIT)); |
91 | #endif | 91 | #endif |
92 | /* | 92 | /* |
93 | * The dynamically-assigned ASIDs that get passed in are small | 93 | * The dynamically-assigned ASIDs that get passed in are small |
@@ -112,7 +112,7 @@ static inline u16 user_pcid(u16 asid) | |||
112 | { | 112 | { |
113 | u16 ret = kern_pcid(asid); | 113 | u16 ret = kern_pcid(asid); |
114 | #ifdef CONFIG_PAGE_TABLE_ISOLATION | 114 | #ifdef CONFIG_PAGE_TABLE_ISOLATION |
115 | ret |= 1 << X86_CR3_PTI_SWITCH_BIT; | 115 | ret |= 1 << X86_CR3_PTI_PCID_USER_BIT; |
116 | #endif | 116 | #endif |
117 | return ret; | 117 | return ret; |
118 | } | 118 | } |
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 7cb282e9e587..bfd882617613 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/page.h> | 44 | #include <asm/page.h> |
45 | #include <asm/pgtable.h> | 45 | #include <asm/pgtable.h> |
46 | #include <asm/smap.h> | 46 | #include <asm/smap.h> |
47 | #include <asm/nospec-branch.h> | ||
47 | 48 | ||
48 | #include <xen/interface/xen.h> | 49 | #include <xen/interface/xen.h> |
49 | #include <xen/interface/sched.h> | 50 | #include <xen/interface/sched.h> |
@@ -217,9 +218,9 @@ privcmd_call(unsigned call, | |||
217 | __HYPERCALL_5ARG(a1, a2, a3, a4, a5); | 218 | __HYPERCALL_5ARG(a1, a2, a3, a4, a5); |
218 | 219 | ||
219 | stac(); | 220 | stac(); |
220 | asm volatile("call *%[call]" | 221 | asm volatile(CALL_NOSPEC |
221 | : __HYPERCALL_5PARAM | 222 | : __HYPERCALL_5PARAM |
222 | : [call] "a" (&hypercall_page[call]) | 223 | : [thunk_target] "a" (&hypercall_page[call]) |
223 | : __HYPERCALL_CLOBBER5); | 224 | : __HYPERCALL_CLOBBER5); |
224 | clac(); | 225 | clac(); |
225 | 226 | ||
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index dbaf14d69ebd..4817d743c263 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -344,9 +344,12 @@ done: | |||
344 | static void __init_or_module noinline optimize_nops(struct alt_instr *a, u8 *instr) | 344 | static void __init_or_module noinline optimize_nops(struct alt_instr *a, u8 *instr) |
345 | { | 345 | { |
346 | unsigned long flags; | 346 | unsigned long flags; |
347 | int i; | ||
347 | 348 | ||
348 | if (instr[0] != 0x90) | 349 | for (i = 0; i < a->padlen; i++) { |
349 | return; | 350 | if (instr[i] != 0x90) |
351 | return; | ||
352 | } | ||
350 | 353 | ||
351 | local_irq_save(flags); | 354 | local_irq_save(flags); |
352 | add_nops(instr + (a->instrlen - a->padlen), a->padlen); | 355 | add_nops(instr + (a->instrlen - a->padlen), a->padlen); |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index bcb75dc97d44..ea831c858195 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -829,8 +829,32 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
829 | set_cpu_cap(c, X86_FEATURE_K8); | 829 | set_cpu_cap(c, X86_FEATURE_K8); |
830 | 830 | ||
831 | if (cpu_has(c, X86_FEATURE_XMM2)) { | 831 | if (cpu_has(c, X86_FEATURE_XMM2)) { |
832 | /* MFENCE stops RDTSC speculation */ | 832 | unsigned long long val; |
833 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | 833 | int ret; |
834 | |||
835 | /* | ||
836 | * A serializing LFENCE has less overhead than MFENCE, so | ||
837 | * use it for execution serialization. On families which | ||
838 | * don't have that MSR, LFENCE is already serializing. | ||
839 | * msr_set_bit() uses the safe accessors, too, even if the MSR | ||
840 | * is not present. | ||
841 | */ | ||
842 | msr_set_bit(MSR_F10H_DECFG, | ||
843 | MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); | ||
844 | |||
845 | /* | ||
846 | * Verify that the MSR write was successful (could be running | ||
847 | * under a hypervisor) and only then assume that LFENCE is | ||
848 | * serializing. | ||
849 | */ | ||
850 | ret = rdmsrl_safe(MSR_F10H_DECFG, &val); | ||
851 | if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) { | ||
852 | /* A serializing LFENCE stops RDTSC speculation */ | ||
853 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | ||
854 | } else { | ||
855 | /* MFENCE stops RDTSC speculation */ | ||
856 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | ||
857 | } | ||
834 | } | 858 | } |
835 | 859 | ||
836 | /* | 860 | /* |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index ba0b2424c9b0..e4dc26185aa7 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -10,6 +10,10 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/utsname.h> | 12 | #include <linux/utsname.h> |
13 | #include <linux/cpu.h> | ||
14 | |||
15 | #include <asm/nospec-branch.h> | ||
16 | #include <asm/cmdline.h> | ||
13 | #include <asm/bugs.h> | 17 | #include <asm/bugs.h> |
14 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
15 | #include <asm/processor-flags.h> | 19 | #include <asm/processor-flags.h> |
@@ -20,6 +24,8 @@ | |||
20 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
21 | #include <asm/set_memory.h> | 25 | #include <asm/set_memory.h> |
22 | 26 | ||
27 | static void __init spectre_v2_select_mitigation(void); | ||
28 | |||
23 | void __init check_bugs(void) | 29 | void __init check_bugs(void) |
24 | { | 30 | { |
25 | identify_boot_cpu(); | 31 | identify_boot_cpu(); |
@@ -29,6 +35,9 @@ void __init check_bugs(void) | |||
29 | print_cpu_info(&boot_cpu_data); | 35 | print_cpu_info(&boot_cpu_data); |
30 | } | 36 | } |
31 | 37 | ||
38 | /* Select the proper spectre mitigation before patching alternatives */ | ||
39 | spectre_v2_select_mitigation(); | ||
40 | |||
32 | #ifdef CONFIG_X86_32 | 41 | #ifdef CONFIG_X86_32 |
33 | /* | 42 | /* |
34 | * Check whether we are able to run this kernel safely on SMP. | 43 | * Check whether we are able to run this kernel safely on SMP. |
@@ -60,3 +69,179 @@ void __init check_bugs(void) | |||
60 | set_memory_4k((unsigned long)__va(0), 1); | 69 | set_memory_4k((unsigned long)__va(0), 1); |
61 | #endif | 70 | #endif |
62 | } | 71 | } |
72 | |||
73 | /* The kernel command line selection */ | ||
74 | enum spectre_v2_mitigation_cmd { | ||
75 | SPECTRE_V2_CMD_NONE, | ||
76 | SPECTRE_V2_CMD_AUTO, | ||
77 | SPECTRE_V2_CMD_FORCE, | ||
78 | SPECTRE_V2_CMD_RETPOLINE, | ||
79 | SPECTRE_V2_CMD_RETPOLINE_GENERIC, | ||
80 | SPECTRE_V2_CMD_RETPOLINE_AMD, | ||
81 | }; | ||
82 | |||
83 | static const char *spectre_v2_strings[] = { | ||
84 | [SPECTRE_V2_NONE] = "Vulnerable", | ||
85 | [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline", | ||
86 | [SPECTRE_V2_RETPOLINE_MINIMAL_AMD] = "Vulnerable: Minimal AMD ASM retpoline", | ||
87 | [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline", | ||
88 | [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline", | ||
89 | }; | ||
90 | |||
91 | #undef pr_fmt | ||
92 | #define pr_fmt(fmt) "Spectre V2 mitigation: " fmt | ||
93 | |||
94 | static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE; | ||
95 | |||
96 | static void __init spec2_print_if_insecure(const char *reason) | ||
97 | { | ||
98 | if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) | ||
99 | pr_info("%s\n", reason); | ||
100 | } | ||
101 | |||
102 | static void __init spec2_print_if_secure(const char *reason) | ||
103 | { | ||
104 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) | ||
105 | pr_info("%s\n", reason); | ||
106 | } | ||
107 | |||
108 | static inline bool retp_compiler(void) | ||
109 | { | ||
110 | return __is_defined(RETPOLINE); | ||
111 | } | ||
112 | |||
113 | static inline bool match_option(const char *arg, int arglen, const char *opt) | ||
114 | { | ||
115 | int len = strlen(opt); | ||
116 | |||
117 | return len == arglen && !strncmp(arg, opt, len); | ||
118 | } | ||
119 | |||
120 | static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) | ||
121 | { | ||
122 | char arg[20]; | ||
123 | int ret; | ||
124 | |||
125 | ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, | ||
126 | sizeof(arg)); | ||
127 | if (ret > 0) { | ||
128 | if (match_option(arg, ret, "off")) { | ||
129 | goto disable; | ||
130 | } else if (match_option(arg, ret, "on")) { | ||
131 | spec2_print_if_secure("force enabled on command line."); | ||
132 | return SPECTRE_V2_CMD_FORCE; | ||
133 | } else if (match_option(arg, ret, "retpoline")) { | ||
134 | spec2_print_if_insecure("retpoline selected on command line."); | ||
135 | return SPECTRE_V2_CMD_RETPOLINE; | ||
136 | } else if (match_option(arg, ret, "retpoline,amd")) { | ||
137 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { | ||
138 | pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n"); | ||
139 | return SPECTRE_V2_CMD_AUTO; | ||
140 | } | ||
141 | spec2_print_if_insecure("AMD retpoline selected on command line."); | ||
142 | return SPECTRE_V2_CMD_RETPOLINE_AMD; | ||
143 | } else if (match_option(arg, ret, "retpoline,generic")) { | ||
144 | spec2_print_if_insecure("generic retpoline selected on command line."); | ||
145 | return SPECTRE_V2_CMD_RETPOLINE_GENERIC; | ||
146 | } else if (match_option(arg, ret, "auto")) { | ||
147 | return SPECTRE_V2_CMD_AUTO; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if (!cmdline_find_option_bool(boot_command_line, "nospectre_v2")) | ||
152 | return SPECTRE_V2_CMD_AUTO; | ||
153 | disable: | ||
154 | spec2_print_if_insecure("disabled on command line."); | ||
155 | return SPECTRE_V2_CMD_NONE; | ||
156 | } | ||
157 | |||
158 | static void __init spectre_v2_select_mitigation(void) | ||
159 | { | ||
160 | enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); | ||
161 | enum spectre_v2_mitigation mode = SPECTRE_V2_NONE; | ||
162 | |||
163 | /* | ||
164 | * If the CPU is not affected and the command line mode is NONE or AUTO | ||
165 | * then nothing to do. | ||
166 | */ | ||
167 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2) && | ||
168 | (cmd == SPECTRE_V2_CMD_NONE || cmd == SPECTRE_V2_CMD_AUTO)) | ||
169 | return; | ||
170 | |||
171 | switch (cmd) { | ||
172 | case SPECTRE_V2_CMD_NONE: | ||
173 | return; | ||
174 | |||
175 | case SPECTRE_V2_CMD_FORCE: | ||
176 | /* FALLTRHU */ | ||
177 | case SPECTRE_V2_CMD_AUTO: | ||
178 | goto retpoline_auto; | ||
179 | |||
180 | case SPECTRE_V2_CMD_RETPOLINE_AMD: | ||
181 | if (IS_ENABLED(CONFIG_RETPOLINE)) | ||
182 | goto retpoline_amd; | ||
183 | break; | ||
184 | case SPECTRE_V2_CMD_RETPOLINE_GENERIC: | ||
185 | if (IS_ENABLED(CONFIG_RETPOLINE)) | ||
186 | goto retpoline_generic; | ||
187 | break; | ||
188 | case SPECTRE_V2_CMD_RETPOLINE: | ||
189 | if (IS_ENABLED(CONFIG_RETPOLINE)) | ||
190 | goto retpoline_auto; | ||
191 | break; | ||
192 | } | ||
193 | pr_err("kernel not compiled with retpoline; no mitigation available!"); | ||
194 | return; | ||
195 | |||
196 | retpoline_auto: | ||
197 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | ||
198 | retpoline_amd: | ||
199 | if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { | ||
200 | pr_err("LFENCE not serializing. Switching to generic retpoline\n"); | ||
201 | goto retpoline_generic; | ||
202 | } | ||
203 | mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD : | ||
204 | SPECTRE_V2_RETPOLINE_MINIMAL_AMD; | ||
205 | setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD); | ||
206 | setup_force_cpu_cap(X86_FEATURE_RETPOLINE); | ||
207 | } else { | ||
208 | retpoline_generic: | ||
209 | mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_GENERIC : | ||
210 | SPECTRE_V2_RETPOLINE_MINIMAL; | ||
211 | setup_force_cpu_cap(X86_FEATURE_RETPOLINE); | ||
212 | } | ||
213 | |||
214 | spectre_v2_enabled = mode; | ||
215 | pr_info("%s\n", spectre_v2_strings[mode]); | ||
216 | } | ||
217 | |||
218 | #undef pr_fmt | ||
219 | |||
220 | #ifdef CONFIG_SYSFS | ||
221 | ssize_t cpu_show_meltdown(struct device *dev, | ||
222 | struct device_attribute *attr, char *buf) | ||
223 | { | ||
224 | if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN)) | ||
225 | return sprintf(buf, "Not affected\n"); | ||
226 | if (boot_cpu_has(X86_FEATURE_PTI)) | ||
227 | return sprintf(buf, "Mitigation: PTI\n"); | ||
228 | return sprintf(buf, "Vulnerable\n"); | ||
229 | } | ||
230 | |||
231 | ssize_t cpu_show_spectre_v1(struct device *dev, | ||
232 | struct device_attribute *attr, char *buf) | ||
233 | { | ||
234 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1)) | ||
235 | return sprintf(buf, "Not affected\n"); | ||
236 | return sprintf(buf, "Vulnerable\n"); | ||
237 | } | ||
238 | |||
239 | ssize_t cpu_show_spectre_v2(struct device *dev, | ||
240 | struct device_attribute *attr, char *buf) | ||
241 | { | ||
242 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) | ||
243 | return sprintf(buf, "Not affected\n"); | ||
244 | |||
245 | return sprintf(buf, "%s\n", spectre_v2_strings[spectre_v2_enabled]); | ||
246 | } | ||
247 | #endif | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 39d7ea865207..ef29ad001991 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -926,6 +926,9 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
926 | if (c->x86_vendor != X86_VENDOR_AMD) | 926 | if (c->x86_vendor != X86_VENDOR_AMD) |
927 | setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); | 927 | setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); |
928 | 928 | ||
929 | setup_force_cpu_bug(X86_BUG_SPECTRE_V1); | ||
930 | setup_force_cpu_bug(X86_BUG_SPECTRE_V2); | ||
931 | |||
929 | fpu__init_system(c); | 932 | fpu__init_system(c); |
930 | 933 | ||
931 | #ifdef CONFIG_X86_32 | 934 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 8ccdca6d3f9e..d9e460fc7a3b 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -910,8 +910,17 @@ static bool is_blacklisted(unsigned int cpu) | |||
910 | { | 910 | { |
911 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 911 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
912 | 912 | ||
913 | if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) { | 913 | /* |
914 | pr_err_once("late loading on model 79 is disabled.\n"); | 914 | * Late loading on model 79 with microcode revision less than 0x0b000021 |
915 | * may result in a system hang. This behavior is documented in item | ||
916 | * BDF90, #334165 (Intel Xeon Processor E7-8800/4800 v4 Product Family). | ||
917 | */ | ||
918 | if (c->x86 == 6 && | ||
919 | c->x86_model == INTEL_FAM6_BROADWELL_X && | ||
920 | c->x86_mask == 0x01 && | ||
921 | c->microcode < 0x0b000021) { | ||
922 | pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode); | ||
923 | pr_err_once("Please consider either early loading through initrd/built-in or a potential BIOS update.\n"); | ||
915 | return true; | 924 | return true; |
916 | } | 925 | } |
917 | 926 | ||
diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S index b6c6468e10bc..4c8440de3355 100644 --- a/arch/x86/kernel/ftrace_32.S +++ b/arch/x86/kernel/ftrace_32.S | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <asm/segment.h> | 8 | #include <asm/segment.h> |
9 | #include <asm/export.h> | 9 | #include <asm/export.h> |
10 | #include <asm/ftrace.h> | 10 | #include <asm/ftrace.h> |
11 | #include <asm/nospec-branch.h> | ||
11 | 12 | ||
12 | #ifdef CC_USING_FENTRY | 13 | #ifdef CC_USING_FENTRY |
13 | # define function_hook __fentry__ | 14 | # define function_hook __fentry__ |
@@ -197,7 +198,8 @@ ftrace_stub: | |||
197 | movl 0x4(%ebp), %edx | 198 | movl 0x4(%ebp), %edx |
198 | subl $MCOUNT_INSN_SIZE, %eax | 199 | subl $MCOUNT_INSN_SIZE, %eax |
199 | 200 | ||
200 | call *ftrace_trace_function | 201 | movl ftrace_trace_function, %ecx |
202 | CALL_NOSPEC %ecx | ||
201 | 203 | ||
202 | popl %edx | 204 | popl %edx |
203 | popl %ecx | 205 | popl %ecx |
@@ -241,5 +243,5 @@ return_to_handler: | |||
241 | movl %eax, %ecx | 243 | movl %eax, %ecx |
242 | popl %edx | 244 | popl %edx |
243 | popl %eax | 245 | popl %eax |
244 | jmp *%ecx | 246 | JMP_NOSPEC %ecx |
245 | #endif | 247 | #endif |
diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index c832291d948a..7cb8ba08beb9 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <asm/ptrace.h> | 7 | #include <asm/ptrace.h> |
8 | #include <asm/ftrace.h> | 8 | #include <asm/ftrace.h> |
9 | #include <asm/export.h> | 9 | #include <asm/export.h> |
10 | 10 | #include <asm/nospec-branch.h> | |
11 | 11 | ||
12 | .code64 | 12 | .code64 |
13 | .section .entry.text, "ax" | 13 | .section .entry.text, "ax" |
@@ -286,8 +286,8 @@ trace: | |||
286 | * ip and parent ip are used and the list function is called when | 286 | * ip and parent ip are used and the list function is called when |
287 | * function tracing is enabled. | 287 | * function tracing is enabled. |
288 | */ | 288 | */ |
289 | call *ftrace_trace_function | 289 | movq ftrace_trace_function, %r8 |
290 | 290 | CALL_NOSPEC %r8 | |
291 | restore_mcount_regs | 291 | restore_mcount_regs |
292 | 292 | ||
293 | jmp fgraph_trace | 293 | jmp fgraph_trace |
@@ -329,5 +329,5 @@ GLOBAL(return_to_handler) | |||
329 | movq 8(%rsp), %rdx | 329 | movq 8(%rsp), %rdx |
330 | movq (%rsp), %rax | 330 | movq (%rsp), %rax |
331 | addq $24, %rsp | 331 | addq $24, %rsp |
332 | jmp *%rdi | 332 | JMP_NOSPEC %rdi |
333 | #endif | 333 | #endif |
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index a83b3346a0e1..c1bdbd3d3232 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | 21 | ||
22 | #include <asm/apic.h> | 22 | #include <asm/apic.h> |
23 | #include <asm/nospec-branch.h> | ||
23 | 24 | ||
24 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 25 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
25 | 26 | ||
@@ -55,11 +56,11 @@ DEFINE_PER_CPU(struct irq_stack *, softirq_stack); | |||
55 | static void call_on_stack(void *func, void *stack) | 56 | static void call_on_stack(void *func, void *stack) |
56 | { | 57 | { |
57 | asm volatile("xchgl %%ebx,%%esp \n" | 58 | asm volatile("xchgl %%ebx,%%esp \n" |
58 | "call *%%edi \n" | 59 | CALL_NOSPEC |
59 | "movl %%ebx,%%esp \n" | 60 | "movl %%ebx,%%esp \n" |
60 | : "=b" (stack) | 61 | : "=b" (stack) |
61 | : "0" (stack), | 62 | : "0" (stack), |
62 | "D"(func) | 63 | [thunk_target] "D"(func) |
63 | : "memory", "cc", "edx", "ecx", "eax"); | 64 | : "memory", "cc", "edx", "ecx", "eax"); |
64 | } | 65 | } |
65 | 66 | ||
@@ -95,11 +96,11 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) | |||
95 | call_on_stack(print_stack_overflow, isp); | 96 | call_on_stack(print_stack_overflow, isp); |
96 | 97 | ||
97 | asm volatile("xchgl %%ebx,%%esp \n" | 98 | asm volatile("xchgl %%ebx,%%esp \n" |
98 | "call *%%edi \n" | 99 | CALL_NOSPEC |
99 | "movl %%ebx,%%esp \n" | 100 | "movl %%ebx,%%esp \n" |
100 | : "=a" (arg1), "=b" (isp) | 101 | : "=a" (arg1), "=b" (isp) |
101 | : "0" (desc), "1" (isp), | 102 | : "0" (desc), "1" (isp), |
102 | "D" (desc->handle_irq) | 103 | [thunk_target] "D" (desc->handle_irq) |
103 | : "memory", "cc", "ecx"); | 104 | : "memory", "cc", "ecx"); |
104 | return 1; | 105 | return 1; |
105 | } | 106 | } |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index a4eb27918ceb..a2486f444073 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -138,6 +138,17 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn, | |||
138 | return -1; | 138 | return -1; |
139 | set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot)); | 139 | set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot)); |
140 | pte_unmap(pte); | 140 | pte_unmap(pte); |
141 | |||
142 | /* | ||
143 | * PTI poisons low addresses in the kernel page tables in the | ||
144 | * name of making them unusable for userspace. To execute | ||
145 | * code at such a low address, the poison must be cleared. | ||
146 | * | ||
147 | * Note: 'pgd' actually gets set in p4d_alloc() _or_ | ||
148 | * pud_alloc() depending on 4/5-level paging. | ||
149 | */ | ||
150 | pgd->pgd &= ~_PAGE_NX; | ||
151 | |||
141 | return 0; | 152 | return 0; |
142 | } | 153 | } |
143 | 154 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index c4deb1f34faa..2b8eb4da4d08 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -3781,7 +3781,8 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn) | |||
3781 | bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu) | 3781 | bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu) |
3782 | { | 3782 | { |
3783 | if (unlikely(!lapic_in_kernel(vcpu) || | 3783 | if (unlikely(!lapic_in_kernel(vcpu) || |
3784 | kvm_event_needs_reinjection(vcpu))) | 3784 | kvm_event_needs_reinjection(vcpu) || |
3785 | vcpu->arch.exception.pending)) | ||
3785 | return false; | 3786 | return false; |
3786 | 3787 | ||
3787 | if (!vcpu->arch.apf.delivery_as_pf_vmexit && is_guest_mode(vcpu)) | 3788 | if (!vcpu->arch.apf.delivery_as_pf_vmexit && is_guest_mode(vcpu)) |
@@ -5465,30 +5466,34 @@ static void mmu_destroy_caches(void) | |||
5465 | 5466 | ||
5466 | int kvm_mmu_module_init(void) | 5467 | int kvm_mmu_module_init(void) |
5467 | { | 5468 | { |
5469 | int ret = -ENOMEM; | ||
5470 | |||
5468 | kvm_mmu_clear_all_pte_masks(); | 5471 | kvm_mmu_clear_all_pte_masks(); |
5469 | 5472 | ||
5470 | pte_list_desc_cache = kmem_cache_create("pte_list_desc", | 5473 | pte_list_desc_cache = kmem_cache_create("pte_list_desc", |
5471 | sizeof(struct pte_list_desc), | 5474 | sizeof(struct pte_list_desc), |
5472 | 0, SLAB_ACCOUNT, NULL); | 5475 | 0, SLAB_ACCOUNT, NULL); |
5473 | if (!pte_list_desc_cache) | 5476 | if (!pte_list_desc_cache) |
5474 | goto nomem; | 5477 | goto out; |
5475 | 5478 | ||
5476 | mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header", | 5479 | mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header", |
5477 | sizeof(struct kvm_mmu_page), | 5480 | sizeof(struct kvm_mmu_page), |
5478 | 0, SLAB_ACCOUNT, NULL); | 5481 | 0, SLAB_ACCOUNT, NULL); |
5479 | if (!mmu_page_header_cache) | 5482 | if (!mmu_page_header_cache) |
5480 | goto nomem; | 5483 | goto out; |
5481 | 5484 | ||
5482 | if (percpu_counter_init(&kvm_total_used_mmu_pages, 0, GFP_KERNEL)) | 5485 | if (percpu_counter_init(&kvm_total_used_mmu_pages, 0, GFP_KERNEL)) |
5483 | goto nomem; | 5486 | goto out; |
5484 | 5487 | ||
5485 | register_shrinker(&mmu_shrinker); | 5488 | ret = register_shrinker(&mmu_shrinker); |
5489 | if (ret) | ||
5490 | goto out; | ||
5486 | 5491 | ||
5487 | return 0; | 5492 | return 0; |
5488 | 5493 | ||
5489 | nomem: | 5494 | out: |
5490 | mmu_destroy_caches(); | 5495 | mmu_destroy_caches(); |
5491 | return -ENOMEM; | 5496 | return ret; |
5492 | } | 5497 | } |
5493 | 5498 | ||
5494 | /* | 5499 | /* |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bb31c801f1fc..f40d0da1f1d3 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/debugreg.h> | 45 | #include <asm/debugreg.h> |
46 | #include <asm/kvm_para.h> | 46 | #include <asm/kvm_para.h> |
47 | #include <asm/irq_remapping.h> | 47 | #include <asm/irq_remapping.h> |
48 | #include <asm/nospec-branch.h> | ||
48 | 49 | ||
49 | #include <asm/virtext.h> | 50 | #include <asm/virtext.h> |
50 | #include "trace.h" | 51 | #include "trace.h" |
@@ -361,7 +362,6 @@ static void recalc_intercepts(struct vcpu_svm *svm) | |||
361 | { | 362 | { |
362 | struct vmcb_control_area *c, *h; | 363 | struct vmcb_control_area *c, *h; |
363 | struct nested_state *g; | 364 | struct nested_state *g; |
364 | u32 h_intercept_exceptions; | ||
365 | 365 | ||
366 | mark_dirty(svm->vmcb, VMCB_INTERCEPTS); | 366 | mark_dirty(svm->vmcb, VMCB_INTERCEPTS); |
367 | 367 | ||
@@ -372,14 +372,9 @@ static void recalc_intercepts(struct vcpu_svm *svm) | |||
372 | h = &svm->nested.hsave->control; | 372 | h = &svm->nested.hsave->control; |
373 | g = &svm->nested; | 373 | g = &svm->nested; |
374 | 374 | ||
375 | /* No need to intercept #UD if L1 doesn't intercept it */ | ||
376 | h_intercept_exceptions = | ||
377 | h->intercept_exceptions & ~(1U << UD_VECTOR); | ||
378 | |||
379 | c->intercept_cr = h->intercept_cr | g->intercept_cr; | 375 | c->intercept_cr = h->intercept_cr | g->intercept_cr; |
380 | c->intercept_dr = h->intercept_dr | g->intercept_dr; | 376 | c->intercept_dr = h->intercept_dr | g->intercept_dr; |
381 | c->intercept_exceptions = | 377 | c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions; |
382 | h_intercept_exceptions | g->intercept_exceptions; | ||
383 | c->intercept = h->intercept | g->intercept; | 378 | c->intercept = h->intercept | g->intercept; |
384 | } | 379 | } |
385 | 380 | ||
@@ -2202,7 +2197,6 @@ static int ud_interception(struct vcpu_svm *svm) | |||
2202 | { | 2197 | { |
2203 | int er; | 2198 | int er; |
2204 | 2199 | ||
2205 | WARN_ON_ONCE(is_guest_mode(&svm->vcpu)); | ||
2206 | er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD); | 2200 | er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD); |
2207 | if (er == EMULATE_USER_EXIT) | 2201 | if (er == EMULATE_USER_EXIT) |
2208 | return 0; | 2202 | return 0; |
@@ -5034,6 +5028,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
5034 | #endif | 5028 | #endif |
5035 | ); | 5029 | ); |
5036 | 5030 | ||
5031 | /* Eliminate branch target predictions from guest mode */ | ||
5032 | vmexit_fill_RSB(); | ||
5033 | |||
5037 | #ifdef CONFIG_X86_64 | 5034 | #ifdef CONFIG_X86_64 |
5038 | wrmsrl(MSR_GS_BASE, svm->host.gs_base); | 5035 | wrmsrl(MSR_GS_BASE, svm->host.gs_base); |
5039 | #else | 5036 | #else |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5c14d65f676a..c829d89e2e63 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <asm/apic.h> | 50 | #include <asm/apic.h> |
51 | #include <asm/irq_remapping.h> | 51 | #include <asm/irq_remapping.h> |
52 | #include <asm/mmu_context.h> | 52 | #include <asm/mmu_context.h> |
53 | #include <asm/nospec-branch.h> | ||
53 | 54 | ||
54 | #include "trace.h" | 55 | #include "trace.h" |
55 | #include "pmu.h" | 56 | #include "pmu.h" |
@@ -899,8 +900,16 @@ static inline short vmcs_field_to_offset(unsigned long field) | |||
899 | { | 900 | { |
900 | BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX); | 901 | BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX); |
901 | 902 | ||
902 | if (field >= ARRAY_SIZE(vmcs_field_to_offset_table) || | 903 | if (field >= ARRAY_SIZE(vmcs_field_to_offset_table)) |
903 | vmcs_field_to_offset_table[field] == 0) | 904 | return -ENOENT; |
905 | |||
906 | /* | ||
907 | * FIXME: Mitigation for CVE-2017-5753. To be replaced with a | ||
908 | * generic mechanism. | ||
909 | */ | ||
910 | asm("lfence"); | ||
911 | |||
912 | if (vmcs_field_to_offset_table[field] == 0) | ||
904 | return -ENOENT; | 913 | return -ENOENT; |
905 | 914 | ||
906 | return vmcs_field_to_offset_table[field]; | 915 | return vmcs_field_to_offset_table[field]; |
@@ -1887,7 +1896,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) | |||
1887 | { | 1896 | { |
1888 | u32 eb; | 1897 | u32 eb; |
1889 | 1898 | ||
1890 | eb = (1u << PF_VECTOR) | (1u << MC_VECTOR) | | 1899 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) | |
1891 | (1u << DB_VECTOR) | (1u << AC_VECTOR); | 1900 | (1u << DB_VECTOR) | (1u << AC_VECTOR); |
1892 | if ((vcpu->guest_debug & | 1901 | if ((vcpu->guest_debug & |
1893 | (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) == | 1902 | (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) == |
@@ -1905,8 +1914,6 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) | |||
1905 | */ | 1914 | */ |
1906 | if (is_guest_mode(vcpu)) | 1915 | if (is_guest_mode(vcpu)) |
1907 | eb |= get_vmcs12(vcpu)->exception_bitmap; | 1916 | eb |= get_vmcs12(vcpu)->exception_bitmap; |
1908 | else | ||
1909 | eb |= 1u << UD_VECTOR; | ||
1910 | 1917 | ||
1911 | vmcs_write32(EXCEPTION_BITMAP, eb); | 1918 | vmcs_write32(EXCEPTION_BITMAP, eb); |
1912 | } | 1919 | } |
@@ -5917,7 +5924,6 @@ static int handle_exception(struct kvm_vcpu *vcpu) | |||
5917 | return 1; /* already handled by vmx_vcpu_run() */ | 5924 | return 1; /* already handled by vmx_vcpu_run() */ |
5918 | 5925 | ||
5919 | if (is_invalid_opcode(intr_info)) { | 5926 | if (is_invalid_opcode(intr_info)) { |
5920 | WARN_ON_ONCE(is_guest_mode(vcpu)); | ||
5921 | er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); | 5927 | er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); |
5922 | if (er == EMULATE_USER_EXIT) | 5928 | if (er == EMULATE_USER_EXIT) |
5923 | return 0; | 5929 | return 0; |
@@ -9485,6 +9491,9 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
9485 | #endif | 9491 | #endif |
9486 | ); | 9492 | ); |
9487 | 9493 | ||
9494 | /* Eliminate branch target predictions from guest mode */ | ||
9495 | vmexit_fill_RSB(); | ||
9496 | |||
9488 | /* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */ | 9497 | /* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */ |
9489 | if (debugctlmsr) | 9498 | if (debugctlmsr) |
9490 | update_debugctlmsr(debugctlmsr); | 9499 | update_debugctlmsr(debugctlmsr); |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 7b181b61170e..f23934bbaf4e 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -26,6 +26,7 @@ lib-y += memcpy_$(BITS).o | |||
26 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | 26 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o |
27 | lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o | 27 | lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o |
28 | lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o | 28 | lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o |
29 | lib-$(CONFIG_RETPOLINE) += retpoline.o | ||
29 | 30 | ||
30 | obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o | 31 | obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o |
31 | 32 | ||
diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S index 4d34bb548b41..46e71a74e612 100644 --- a/arch/x86/lib/checksum_32.S +++ b/arch/x86/lib/checksum_32.S | |||
@@ -29,7 +29,8 @@ | |||
29 | #include <asm/errno.h> | 29 | #include <asm/errno.h> |
30 | #include <asm/asm.h> | 30 | #include <asm/asm.h> |
31 | #include <asm/export.h> | 31 | #include <asm/export.h> |
32 | 32 | #include <asm/nospec-branch.h> | |
33 | |||
33 | /* | 34 | /* |
34 | * computes a partial checksum, e.g. for TCP/UDP fragments | 35 | * computes a partial checksum, e.g. for TCP/UDP fragments |
35 | */ | 36 | */ |
@@ -156,7 +157,7 @@ ENTRY(csum_partial) | |||
156 | negl %ebx | 157 | negl %ebx |
157 | lea 45f(%ebx,%ebx,2), %ebx | 158 | lea 45f(%ebx,%ebx,2), %ebx |
158 | testl %esi, %esi | 159 | testl %esi, %esi |
159 | jmp *%ebx | 160 | JMP_NOSPEC %ebx |
160 | 161 | ||
161 | # Handle 2-byte-aligned regions | 162 | # Handle 2-byte-aligned regions |
162 | 20: addw (%esi), %ax | 163 | 20: addw (%esi), %ax |
@@ -439,7 +440,7 @@ ENTRY(csum_partial_copy_generic) | |||
439 | andl $-32,%edx | 440 | andl $-32,%edx |
440 | lea 3f(%ebx,%ebx), %ebx | 441 | lea 3f(%ebx,%ebx), %ebx |
441 | testl %esi, %esi | 442 | testl %esi, %esi |
442 | jmp *%ebx | 443 | JMP_NOSPEC %ebx |
443 | 1: addl $64,%esi | 444 | 1: addl $64,%esi |
444 | addl $64,%edi | 445 | addl $64,%edi |
445 | SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) | 446 | SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) |
diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S new file mode 100644 index 000000000000..cb45c6cb465f --- /dev/null +++ b/arch/x86/lib/retpoline.S | |||
@@ -0,0 +1,48 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #include <linux/stringify.h> | ||
4 | #include <linux/linkage.h> | ||
5 | #include <asm/dwarf2.h> | ||
6 | #include <asm/cpufeatures.h> | ||
7 | #include <asm/alternative-asm.h> | ||
8 | #include <asm/export.h> | ||
9 | #include <asm/nospec-branch.h> | ||
10 | |||
11 | .macro THUNK reg | ||
12 | .section .text.__x86.indirect_thunk.\reg | ||
13 | |||
14 | ENTRY(__x86_indirect_thunk_\reg) | ||
15 | CFI_STARTPROC | ||
16 | JMP_NOSPEC %\reg | ||
17 | CFI_ENDPROC | ||
18 | ENDPROC(__x86_indirect_thunk_\reg) | ||
19 | .endm | ||
20 | |||
21 | /* | ||
22 | * Despite being an assembler file we can't just use .irp here | ||
23 | * because __KSYM_DEPS__ only uses the C preprocessor and would | ||
24 | * only see one instance of "__x86_indirect_thunk_\reg" rather | ||
25 | * than one per register with the correct names. So we do it | ||
26 | * the simple and nasty way... | ||
27 | */ | ||
28 | #define EXPORT_THUNK(reg) EXPORT_SYMBOL(__x86_indirect_thunk_ ## reg) | ||
29 | #define GENERATE_THUNK(reg) THUNK reg ; EXPORT_THUNK(reg) | ||
30 | |||
31 | GENERATE_THUNK(_ASM_AX) | ||
32 | GENERATE_THUNK(_ASM_BX) | ||
33 | GENERATE_THUNK(_ASM_CX) | ||
34 | GENERATE_THUNK(_ASM_DX) | ||
35 | GENERATE_THUNK(_ASM_SI) | ||
36 | GENERATE_THUNK(_ASM_DI) | ||
37 | GENERATE_THUNK(_ASM_BP) | ||
38 | GENERATE_THUNK(_ASM_SP) | ||
39 | #ifdef CONFIG_64BIT | ||
40 | GENERATE_THUNK(r8) | ||
41 | GENERATE_THUNK(r9) | ||
42 | GENERATE_THUNK(r10) | ||
43 | GENERATE_THUNK(r11) | ||
44 | GENERATE_THUNK(r12) | ||
45 | GENERATE_THUNK(r13) | ||
46 | GENERATE_THUNK(r14) | ||
47 | GENERATE_THUNK(r15) | ||
48 | #endif | ||
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c index 43d4a4a29037..ce38f165489b 100644 --- a/arch/x86/mm/pti.c +++ b/arch/x86/mm/pti.c | |||
@@ -149,7 +149,7 @@ pgd_t __pti_set_user_pgd(pgd_t *pgdp, pgd_t pgd) | |||
149 | * | 149 | * |
150 | * Returns a pointer to a P4D on success, or NULL on failure. | 150 | * Returns a pointer to a P4D on success, or NULL on failure. |
151 | */ | 151 | */ |
152 | static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) | 152 | static __init p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) |
153 | { | 153 | { |
154 | pgd_t *pgd = kernel_to_user_pgdp(pgd_offset_k(address)); | 154 | pgd_t *pgd = kernel_to_user_pgdp(pgd_offset_k(address)); |
155 | gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); | 155 | gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); |
@@ -164,12 +164,7 @@ static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) | |||
164 | if (!new_p4d_page) | 164 | if (!new_p4d_page) |
165 | return NULL; | 165 | return NULL; |
166 | 166 | ||
167 | if (pgd_none(*pgd)) { | 167 | set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(new_p4d_page))); |
168 | set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(new_p4d_page))); | ||
169 | new_p4d_page = 0; | ||
170 | } | ||
171 | if (new_p4d_page) | ||
172 | free_page(new_p4d_page); | ||
173 | } | 168 | } |
174 | BUILD_BUG_ON(pgd_large(*pgd) != 0); | 169 | BUILD_BUG_ON(pgd_large(*pgd) != 0); |
175 | 170 | ||
@@ -182,7 +177,7 @@ static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) | |||
182 | * | 177 | * |
183 | * Returns a pointer to a PMD on success, or NULL on failure. | 178 | * Returns a pointer to a PMD on success, or NULL on failure. |
184 | */ | 179 | */ |
185 | static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) | 180 | static __init pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) |
186 | { | 181 | { |
187 | gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); | 182 | gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); |
188 | p4d_t *p4d = pti_user_pagetable_walk_p4d(address); | 183 | p4d_t *p4d = pti_user_pagetable_walk_p4d(address); |
@@ -194,12 +189,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) | |||
194 | if (!new_pud_page) | 189 | if (!new_pud_page) |
195 | return NULL; | 190 | return NULL; |
196 | 191 | ||
197 | if (p4d_none(*p4d)) { | 192 | set_p4d(p4d, __p4d(_KERNPG_TABLE | __pa(new_pud_page))); |
198 | set_p4d(p4d, __p4d(_KERNPG_TABLE | __pa(new_pud_page))); | ||
199 | new_pud_page = 0; | ||
200 | } | ||
201 | if (new_pud_page) | ||
202 | free_page(new_pud_page); | ||
203 | } | 193 | } |
204 | 194 | ||
205 | pud = pud_offset(p4d, address); | 195 | pud = pud_offset(p4d, address); |
@@ -213,12 +203,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) | |||
213 | if (!new_pmd_page) | 203 | if (!new_pmd_page) |
214 | return NULL; | 204 | return NULL; |
215 | 205 | ||
216 | if (pud_none(*pud)) { | 206 | set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page))); |
217 | set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page))); | ||
218 | new_pmd_page = 0; | ||
219 | } | ||
220 | if (new_pmd_page) | ||
221 | free_page(new_pmd_page); | ||
222 | } | 207 | } |
223 | 208 | ||
224 | return pmd_offset(pud, address); | 209 | return pmd_offset(pud, address); |
@@ -251,12 +236,7 @@ static __init pte_t *pti_user_pagetable_walk_pte(unsigned long address) | |||
251 | if (!new_pte_page) | 236 | if (!new_pte_page) |
252 | return NULL; | 237 | return NULL; |
253 | 238 | ||
254 | if (pmd_none(*pmd)) { | 239 | set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(new_pte_page))); |
255 | set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(new_pte_page))); | ||
256 | new_pte_page = 0; | ||
257 | } | ||
258 | if (new_pte_page) | ||
259 | free_page(new_pte_page); | ||
260 | } | 240 | } |
261 | 241 | ||
262 | pte = pte_offset_kernel(pmd, address); | 242 | pte = pte_offset_kernel(pmd, address); |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 7a5350d08cef..563049c483a1 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -594,6 +594,11 @@ char *__init pcibios_setup(char *str) | |||
594 | } else if (!strcmp(str, "nocrs")) { | 594 | } else if (!strcmp(str, "nocrs")) { |
595 | pci_probe |= PCI_ROOT_NO_CRS; | 595 | pci_probe |= PCI_ROOT_NO_CRS; |
596 | return NULL; | 596 | return NULL; |
597 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
598 | } else if (!strcmp(str, "big_root_window")) { | ||
599 | pci_probe |= PCI_BIG_ROOT_WINDOW; | ||
600 | return NULL; | ||
601 | #endif | ||
597 | } else if (!strcmp(str, "earlydump")) { | 602 | } else if (!strcmp(str, "earlydump")) { |
598 | pci_early_dump_regs = 1; | 603 | pci_early_dump_regs = 1; |
599 | return NULL; | 604 | return NULL; |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index e663d6bf1328..f6a26e3cb476 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -662,10 +662,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid); | |||
662 | */ | 662 | */ |
663 | static void pci_amd_enable_64bit_bar(struct pci_dev *dev) | 663 | static void pci_amd_enable_64bit_bar(struct pci_dev *dev) |
664 | { | 664 | { |
665 | unsigned i; | ||
666 | u32 base, limit, high; | 665 | u32 base, limit, high; |
667 | struct resource *res, *conflict; | ||
668 | struct pci_dev *other; | 666 | struct pci_dev *other; |
667 | struct resource *res; | ||
668 | unsigned i; | ||
669 | int r; | ||
670 | |||
671 | if (!(pci_probe & PCI_BIG_ROOT_WINDOW)) | ||
672 | return; | ||
669 | 673 | ||
670 | /* Check that we are the only device of that type */ | 674 | /* Check that we are the only device of that type */ |
671 | other = pci_get_device(dev->vendor, dev->device, NULL); | 675 | other = pci_get_device(dev->vendor, dev->device, NULL); |
@@ -699,22 +703,25 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) | |||
699 | if (!res) | 703 | if (!res) |
700 | return; | 704 | return; |
701 | 705 | ||
706 | /* | ||
707 | * Allocate a 256GB window directly below the 0xfd00000000 hardware | ||
708 | * limit (see AMD Family 15h Models 30h-3Fh BKDG, sec 2.4.6). | ||
709 | */ | ||
702 | res->name = "PCI Bus 0000:00"; | 710 | res->name = "PCI Bus 0000:00"; |
703 | res->flags = IORESOURCE_PREFETCH | IORESOURCE_MEM | | 711 | res->flags = IORESOURCE_PREFETCH | IORESOURCE_MEM | |
704 | IORESOURCE_MEM_64 | IORESOURCE_WINDOW; | 712 | IORESOURCE_MEM_64 | IORESOURCE_WINDOW; |
705 | res->start = 0x100000000ull; | 713 | res->start = 0xbd00000000ull; |
706 | res->end = 0xfd00000000ull - 1; | 714 | res->end = 0xfd00000000ull - 1; |
707 | 715 | ||
708 | /* Just grab the free area behind system memory for this */ | 716 | r = request_resource(&iomem_resource, res); |
709 | while ((conflict = request_resource_conflict(&iomem_resource, res))) { | 717 | if (r) { |
710 | if (conflict->end >= res->end) { | 718 | kfree(res); |
711 | kfree(res); | 719 | return; |
712 | return; | ||
713 | } | ||
714 | res->start = conflict->end + 1; | ||
715 | } | 720 | } |
716 | 721 | ||
717 | dev_info(&dev->dev, "adding root bus resource %pR\n", res); | 722 | dev_info(&dev->dev, "adding root bus resource %pR (tainting kernel)\n", |
723 | res); | ||
724 | add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
718 | 725 | ||
719 | base = ((res->start >> 8) & AMD_141b_MMIO_BASE_MMIOBASE_MASK) | | 726 | base = ((res->start >> 8) & AMD_141b_MMIO_BASE_MMIOBASE_MASK) | |
720 | AMD_141b_MMIO_BASE_RE_MASK | AMD_141b_MMIO_BASE_WE_MASK; | 727 | AMD_141b_MMIO_BASE_RE_MASK | AMD_141b_MMIO_BASE_WE_MASK; |
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index d87ac96e37ed..2dd15e967c3f 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -135,7 +135,9 @@ pgd_t * __init efi_call_phys_prolog(void) | |||
135 | pud[j] = *pud_offset(p4d_k, vaddr); | 135 | pud[j] = *pud_offset(p4d_k, vaddr); |
136 | } | 136 | } |
137 | } | 137 | } |
138 | pgd_offset_k(pgd * PGDIR_SIZE)->pgd &= ~_PAGE_NX; | ||
138 | } | 139 | } |
140 | |||
139 | out: | 141 | out: |
140 | __flush_tlb_all(); | 142 | __flush_tlb_all(); |
141 | 143 | ||
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_bt.c b/arch/x86/platform/intel-mid/device_libs/platform_bt.c index dc036e511f48..5a0483e7bf66 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_bt.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_bt.c | |||
@@ -60,7 +60,7 @@ static int __init tng_bt_sfi_setup(struct bt_sfi_data *ddata) | |||
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | static const struct bt_sfi_data tng_bt_sfi_data __initdata = { | 63 | static struct bt_sfi_data tng_bt_sfi_data __initdata = { |
64 | .setup = tng_bt_sfi_setup, | 64 | .setup = tng_bt_sfi_setup, |
65 | }; | 65 | }; |
66 | 66 | ||
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 4d62c071b166..d85076223a69 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -1325,20 +1325,18 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, | |||
1325 | { | 1325 | { |
1326 | struct { | 1326 | struct { |
1327 | struct mmuext_op op; | 1327 | struct mmuext_op op; |
1328 | #ifdef CONFIG_SMP | ||
1329 | DECLARE_BITMAP(mask, num_processors); | ||
1330 | #else | ||
1331 | DECLARE_BITMAP(mask, NR_CPUS); | 1328 | DECLARE_BITMAP(mask, NR_CPUS); |
1332 | #endif | ||
1333 | } *args; | 1329 | } *args; |
1334 | struct multicall_space mcs; | 1330 | struct multicall_space mcs; |
1331 | const size_t mc_entry_size = sizeof(args->op) + | ||
1332 | sizeof(args->mask[0]) * BITS_TO_LONGS(num_possible_cpus()); | ||
1335 | 1333 | ||
1336 | trace_xen_mmu_flush_tlb_others(cpus, info->mm, info->start, info->end); | 1334 | trace_xen_mmu_flush_tlb_others(cpus, info->mm, info->start, info->end); |
1337 | 1335 | ||
1338 | if (cpumask_empty(cpus)) | 1336 | if (cpumask_empty(cpus)) |
1339 | return; /* nothing to do */ | 1337 | return; /* nothing to do */ |
1340 | 1338 | ||
1341 | mcs = xen_mc_entry(sizeof(*args)); | 1339 | mcs = xen_mc_entry(mc_entry_size); |
1342 | args = mcs.args; | 1340 | args = mcs.args; |
1343 | args->op.arg2.vcpumask = to_cpumask(args->mask); | 1341 | args->op.arg2.vcpumask = to_cpumask(args->mask); |
1344 | 1342 | ||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 75011b80660f..3b34745d0a52 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -72,7 +72,7 @@ u64 xen_clocksource_read(void); | |||
72 | void xen_setup_cpu_clockevents(void); | 72 | void xen_setup_cpu_clockevents(void); |
73 | void xen_save_time_memory_area(void); | 73 | void xen_save_time_memory_area(void); |
74 | void xen_restore_time_memory_area(void); | 74 | void xen_restore_time_memory_area(void); |
75 | void __init xen_init_time_ops(void); | 75 | void __ref xen_init_time_ops(void); |
76 | void __init xen_hvm_init_time_ops(void); | 76 | void __init xen_hvm_init_time_ops(void); |
77 | 77 | ||
78 | irqreturn_t xen_debug_interrupt(int irq, void *dev_id); | 78 | irqreturn_t xen_debug_interrupt(int irq, void *dev_id); |
diff --git a/block/blk-core.c b/block/blk-core.c index b8881750a3ac..3ba4326a63b5 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -562,6 +562,13 @@ static void __blk_drain_queue(struct request_queue *q, bool drain_all) | |||
562 | } | 562 | } |
563 | } | 563 | } |
564 | 564 | ||
565 | void blk_drain_queue(struct request_queue *q) | ||
566 | { | ||
567 | spin_lock_irq(q->queue_lock); | ||
568 | __blk_drain_queue(q, true); | ||
569 | spin_unlock_irq(q->queue_lock); | ||
570 | } | ||
571 | |||
565 | /** | 572 | /** |
566 | * blk_queue_bypass_start - enter queue bypass mode | 573 | * blk_queue_bypass_start - enter queue bypass mode |
567 | * @q: queue of interest | 574 | * @q: queue of interest |
@@ -689,8 +696,6 @@ void blk_cleanup_queue(struct request_queue *q) | |||
689 | */ | 696 | */ |
690 | blk_freeze_queue(q); | 697 | blk_freeze_queue(q); |
691 | spin_lock_irq(lock); | 698 | spin_lock_irq(lock); |
692 | if (!q->mq_ops) | ||
693 | __blk_drain_queue(q, true); | ||
694 | queue_flag_set(QUEUE_FLAG_DEAD, q); | 699 | queue_flag_set(QUEUE_FLAG_DEAD, q); |
695 | spin_unlock_irq(lock); | 700 | spin_unlock_irq(lock); |
696 | 701 | ||
diff --git a/block/blk-mq.c b/block/blk-mq.c index 11097477eeab..3d3797327491 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -161,6 +161,8 @@ void blk_freeze_queue(struct request_queue *q) | |||
161 | * exported to drivers as the only user for unfreeze is blk_mq. | 161 | * exported to drivers as the only user for unfreeze is blk_mq. |
162 | */ | 162 | */ |
163 | blk_freeze_queue_start(q); | 163 | blk_freeze_queue_start(q); |
164 | if (!q->mq_ops) | ||
165 | blk_drain_queue(q); | ||
164 | blk_mq_freeze_queue_wait(q); | 166 | blk_mq_freeze_queue_wait(q); |
165 | } | 167 | } |
166 | 168 | ||
diff --git a/block/blk.h b/block/blk.h index 3f1446937aec..442098aa9463 100644 --- a/block/blk.h +++ b/block/blk.h | |||
@@ -330,4 +330,6 @@ static inline void blk_queue_bounce(struct request_queue *q, struct bio **bio) | |||
330 | } | 330 | } |
331 | #endif /* CONFIG_BOUNCE */ | 331 | #endif /* CONFIG_BOUNCE */ |
332 | 332 | ||
333 | extern void blk_drain_queue(struct request_queue *q); | ||
334 | |||
333 | #endif /* BLK_INTERNAL_H */ | 335 | #endif /* BLK_INTERNAL_H */ |
diff --git a/crypto/algapi.c b/crypto/algapi.c index 60d7366ed343..9a636f961572 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c | |||
@@ -167,6 +167,18 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, | |||
167 | 167 | ||
168 | spawn->alg = NULL; | 168 | spawn->alg = NULL; |
169 | spawns = &inst->alg.cra_users; | 169 | spawns = &inst->alg.cra_users; |
170 | |||
171 | /* | ||
172 | * We may encounter an unregistered instance here, since | ||
173 | * an instance's spawns are set up prior to the instance | ||
174 | * being registered. An unregistered instance will have | ||
175 | * NULL ->cra_users.next, since ->cra_users isn't | ||
176 | * properly initialized until registration. But an | ||
177 | * unregistered instance cannot have any users, so treat | ||
178 | * it the same as ->cra_users being empty. | ||
179 | */ | ||
180 | if (spawns->next == NULL) | ||
181 | break; | ||
170 | } | 182 | } |
171 | } while ((spawns = crypto_more_spawns(alg, &stack, &top, | 183 | } while ((spawns = crypto_more_spawns(alg, &stack, &top, |
172 | &secondary_spawns))); | 184 | &secondary_spawns))); |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 9d49a1acebe3..78db97687f26 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -737,16 +737,17 @@ bool acpi_dev_found(const char *hid) | |||
737 | } | 737 | } |
738 | EXPORT_SYMBOL(acpi_dev_found); | 738 | EXPORT_SYMBOL(acpi_dev_found); |
739 | 739 | ||
740 | struct acpi_dev_present_info { | 740 | struct acpi_dev_match_info { |
741 | const char *dev_name; | ||
741 | struct acpi_device_id hid[2]; | 742 | struct acpi_device_id hid[2]; |
742 | const char *uid; | 743 | const char *uid; |
743 | s64 hrv; | 744 | s64 hrv; |
744 | }; | 745 | }; |
745 | 746 | ||
746 | static int acpi_dev_present_cb(struct device *dev, void *data) | 747 | static int acpi_dev_match_cb(struct device *dev, void *data) |
747 | { | 748 | { |
748 | struct acpi_device *adev = to_acpi_device(dev); | 749 | struct acpi_device *adev = to_acpi_device(dev); |
749 | struct acpi_dev_present_info *match = data; | 750 | struct acpi_dev_match_info *match = data; |
750 | unsigned long long hrv; | 751 | unsigned long long hrv; |
751 | acpi_status status; | 752 | acpi_status status; |
752 | 753 | ||
@@ -757,6 +758,8 @@ static int acpi_dev_present_cb(struct device *dev, void *data) | |||
757 | strcmp(adev->pnp.unique_id, match->uid))) | 758 | strcmp(adev->pnp.unique_id, match->uid))) |
758 | return 0; | 759 | return 0; |
759 | 760 | ||
761 | match->dev_name = acpi_dev_name(adev); | ||
762 | |||
760 | if (match->hrv == -1) | 763 | if (match->hrv == -1) |
761 | return 1; | 764 | return 1; |
762 | 765 | ||
@@ -789,20 +792,44 @@ static int acpi_dev_present_cb(struct device *dev, void *data) | |||
789 | */ | 792 | */ |
790 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) | 793 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) |
791 | { | 794 | { |
792 | struct acpi_dev_present_info match = {}; | 795 | struct acpi_dev_match_info match = {}; |
793 | struct device *dev; | 796 | struct device *dev; |
794 | 797 | ||
795 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | 798 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); |
796 | match.uid = uid; | 799 | match.uid = uid; |
797 | match.hrv = hrv; | 800 | match.hrv = hrv; |
798 | 801 | ||
799 | dev = bus_find_device(&acpi_bus_type, NULL, &match, | 802 | dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); |
800 | acpi_dev_present_cb); | ||
801 | |||
802 | return !!dev; | 803 | return !!dev; |
803 | } | 804 | } |
804 | EXPORT_SYMBOL(acpi_dev_present); | 805 | EXPORT_SYMBOL(acpi_dev_present); |
805 | 806 | ||
807 | /** | ||
808 | * acpi_dev_get_first_match_name - Return name of first match of ACPI device | ||
809 | * @hid: Hardware ID of the device. | ||
810 | * @uid: Unique ID of the device, pass NULL to not check _UID | ||
811 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV | ||
812 | * | ||
813 | * Return device name if a matching device was present | ||
814 | * at the moment of invocation, or NULL otherwise. | ||
815 | * | ||
816 | * See additional information in acpi_dev_present() as well. | ||
817 | */ | ||
818 | const char * | ||
819 | acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) | ||
820 | { | ||
821 | struct acpi_dev_match_info match = {}; | ||
822 | struct device *dev; | ||
823 | |||
824 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | ||
825 | match.uid = uid; | ||
826 | match.hrv = hrv; | ||
827 | |||
828 | dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); | ||
829 | return dev ? match.dev_name : NULL; | ||
830 | } | ||
831 | EXPORT_SYMBOL(acpi_dev_get_first_match_name); | ||
832 | |||
806 | /* | 833 | /* |
807 | * acpi_backlight= handling, this is done here rather then in video_detect.c | 834 | * acpi_backlight= handling, this is done here rather then in video_detect.c |
808 | * because __setup cannot be used in modules. | 835 | * because __setup cannot be used in modules. |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index bdc87907d6a1..2415ad9f6dd4 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -236,6 +236,9 @@ config GENERIC_CPU_DEVICES | |||
236 | config GENERIC_CPU_AUTOPROBE | 236 | config GENERIC_CPU_AUTOPROBE |
237 | bool | 237 | bool |
238 | 238 | ||
239 | config GENERIC_CPU_VULNERABILITIES | ||
240 | bool | ||
241 | |||
239 | config SOC_BUS | 242 | config SOC_BUS |
240 | bool | 243 | bool |
241 | select GLOB | 244 | select GLOB |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 58a9b608d821..d99038487a0d 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -511,10 +511,58 @@ static void __init cpu_dev_register_generic(void) | |||
511 | #endif | 511 | #endif |
512 | } | 512 | } |
513 | 513 | ||
514 | #ifdef CONFIG_GENERIC_CPU_VULNERABILITIES | ||
515 | |||
516 | ssize_t __weak cpu_show_meltdown(struct device *dev, | ||
517 | struct device_attribute *attr, char *buf) | ||
518 | { | ||
519 | return sprintf(buf, "Not affected\n"); | ||
520 | } | ||
521 | |||
522 | ssize_t __weak cpu_show_spectre_v1(struct device *dev, | ||
523 | struct device_attribute *attr, char *buf) | ||
524 | { | ||
525 | return sprintf(buf, "Not affected\n"); | ||
526 | } | ||
527 | |||
528 | ssize_t __weak cpu_show_spectre_v2(struct device *dev, | ||
529 | struct device_attribute *attr, char *buf) | ||
530 | { | ||
531 | return sprintf(buf, "Not affected\n"); | ||
532 | } | ||
533 | |||
534 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); | ||
535 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); | ||
536 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); | ||
537 | |||
538 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { | ||
539 | &dev_attr_meltdown.attr, | ||
540 | &dev_attr_spectre_v1.attr, | ||
541 | &dev_attr_spectre_v2.attr, | ||
542 | NULL | ||
543 | }; | ||
544 | |||
545 | static const struct attribute_group cpu_root_vulnerabilities_group = { | ||
546 | .name = "vulnerabilities", | ||
547 | .attrs = cpu_root_vulnerabilities_attrs, | ||
548 | }; | ||
549 | |||
550 | static void __init cpu_register_vulnerabilities(void) | ||
551 | { | ||
552 | if (sysfs_create_group(&cpu_subsys.dev_root->kobj, | ||
553 | &cpu_root_vulnerabilities_group)) | ||
554 | pr_err("Unable to register CPU vulnerabilities\n"); | ||
555 | } | ||
556 | |||
557 | #else | ||
558 | static inline void cpu_register_vulnerabilities(void) { } | ||
559 | #endif | ||
560 | |||
514 | void __init cpu_dev_init(void) | 561 | void __init cpu_dev_init(void) |
515 | { | 562 | { |
516 | if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups)) | 563 | if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups)) |
517 | panic("Failed to register CPU subsystem"); | 564 | panic("Failed to register CPU subsystem"); |
518 | 565 | ||
519 | cpu_dev_register_generic(); | 566 | cpu_dev_register_generic(); |
567 | cpu_register_vulnerabilities(); | ||
520 | } | 568 | } |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bc8e61506968..d5fe720cf149 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -1581,9 +1581,8 @@ out: | |||
1581 | return err; | 1581 | return err; |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | static void lo_release(struct gendisk *disk, fmode_t mode) | 1584 | static void __lo_release(struct loop_device *lo) |
1585 | { | 1585 | { |
1586 | struct loop_device *lo = disk->private_data; | ||
1587 | int err; | 1586 | int err; |
1588 | 1587 | ||
1589 | if (atomic_dec_return(&lo->lo_refcnt)) | 1588 | if (atomic_dec_return(&lo->lo_refcnt)) |
@@ -1610,6 +1609,13 @@ static void lo_release(struct gendisk *disk, fmode_t mode) | |||
1610 | mutex_unlock(&lo->lo_ctl_mutex); | 1609 | mutex_unlock(&lo->lo_ctl_mutex); |
1611 | } | 1610 | } |
1612 | 1611 | ||
1612 | static void lo_release(struct gendisk *disk, fmode_t mode) | ||
1613 | { | ||
1614 | mutex_lock(&loop_index_mutex); | ||
1615 | __lo_release(disk->private_data); | ||
1616 | mutex_unlock(&loop_index_mutex); | ||
1617 | } | ||
1618 | |||
1613 | static const struct block_device_operations lo_fops = { | 1619 | static const struct block_device_operations lo_fops = { |
1614 | .owner = THIS_MODULE, | 1620 | .owner = THIS_MODULE, |
1615 | .open = lo_open, | 1621 | .open = lo_open, |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 38fc5f397fde..cc93522a6d41 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -3047,13 +3047,21 @@ static void format_lock_cookie(struct rbd_device *rbd_dev, char *buf) | |||
3047 | mutex_unlock(&rbd_dev->watch_mutex); | 3047 | mutex_unlock(&rbd_dev->watch_mutex); |
3048 | } | 3048 | } |
3049 | 3049 | ||
3050 | static void __rbd_lock(struct rbd_device *rbd_dev, const char *cookie) | ||
3051 | { | ||
3052 | struct rbd_client_id cid = rbd_get_cid(rbd_dev); | ||
3053 | |||
3054 | strcpy(rbd_dev->lock_cookie, cookie); | ||
3055 | rbd_set_owner_cid(rbd_dev, &cid); | ||
3056 | queue_work(rbd_dev->task_wq, &rbd_dev->acquired_lock_work); | ||
3057 | } | ||
3058 | |||
3050 | /* | 3059 | /* |
3051 | * lock_rwsem must be held for write | 3060 | * lock_rwsem must be held for write |
3052 | */ | 3061 | */ |
3053 | static int rbd_lock(struct rbd_device *rbd_dev) | 3062 | static int rbd_lock(struct rbd_device *rbd_dev) |
3054 | { | 3063 | { |
3055 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; | 3064 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; |
3056 | struct rbd_client_id cid = rbd_get_cid(rbd_dev); | ||
3057 | char cookie[32]; | 3065 | char cookie[32]; |
3058 | int ret; | 3066 | int ret; |
3059 | 3067 | ||
@@ -3068,9 +3076,7 @@ static int rbd_lock(struct rbd_device *rbd_dev) | |||
3068 | return ret; | 3076 | return ret; |
3069 | 3077 | ||
3070 | rbd_dev->lock_state = RBD_LOCK_STATE_LOCKED; | 3078 | rbd_dev->lock_state = RBD_LOCK_STATE_LOCKED; |
3071 | strcpy(rbd_dev->lock_cookie, cookie); | 3079 | __rbd_lock(rbd_dev, cookie); |
3072 | rbd_set_owner_cid(rbd_dev, &cid); | ||
3073 | queue_work(rbd_dev->task_wq, &rbd_dev->acquired_lock_work); | ||
3074 | return 0; | 3080 | return 0; |
3075 | } | 3081 | } |
3076 | 3082 | ||
@@ -3856,7 +3862,7 @@ static void rbd_reacquire_lock(struct rbd_device *rbd_dev) | |||
3856 | queue_delayed_work(rbd_dev->task_wq, | 3862 | queue_delayed_work(rbd_dev->task_wq, |
3857 | &rbd_dev->lock_dwork, 0); | 3863 | &rbd_dev->lock_dwork, 0); |
3858 | } else { | 3864 | } else { |
3859 | strcpy(rbd_dev->lock_cookie, cookie); | 3865 | __rbd_lock(rbd_dev, cookie); |
3860 | } | 3866 | } |
3861 | } | 3867 | } |
3862 | 3868 | ||
@@ -4381,7 +4387,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) | |||
4381 | segment_size = rbd_obj_bytes(&rbd_dev->header); | 4387 | segment_size = rbd_obj_bytes(&rbd_dev->header); |
4382 | blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE); | 4388 | blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE); |
4383 | q->limits.max_sectors = queue_max_hw_sectors(q); | 4389 | q->limits.max_sectors = queue_max_hw_sectors(q); |
4384 | blk_queue_max_segments(q, segment_size / SECTOR_SIZE); | 4390 | blk_queue_max_segments(q, USHRT_MAX); |
4385 | blk_queue_max_segment_size(q, segment_size); | 4391 | blk_queue_max_segment_size(q, segment_size); |
4386 | blk_queue_io_min(q, segment_size); | 4392 | blk_queue_io_min(q, segment_size); |
4387 | blk_queue_io_opt(q, segment_size); | 4393 | blk_queue_io_opt(q, segment_size); |
diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index dd67a31ac337..c38624ea0251 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/acpi.h> | ||
12 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
13 | #include <linux/gpio/driver.h> | 14 | #include <linux/gpio/driver.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -380,9 +381,16 @@ static void mrfld_irq_init_hw(struct mrfld_gpio *priv) | |||
380 | } | 381 | } |
381 | } | 382 | } |
382 | 383 | ||
384 | static const char *mrfld_gpio_get_pinctrl_dev_name(void) | ||
385 | { | ||
386 | const char *dev_name = acpi_dev_get_first_match_name("INTC1002", NULL, -1); | ||
387 | return dev_name ? dev_name : "pinctrl-merrifield"; | ||
388 | } | ||
389 | |||
383 | static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 390 | static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
384 | { | 391 | { |
385 | const struct mrfld_gpio_pinrange *range; | 392 | const struct mrfld_gpio_pinrange *range; |
393 | const char *pinctrl_dev_name; | ||
386 | struct mrfld_gpio *priv; | 394 | struct mrfld_gpio *priv; |
387 | u32 gpio_base, irq_base; | 395 | u32 gpio_base, irq_base; |
388 | void __iomem *base; | 396 | void __iomem *base; |
@@ -439,10 +447,11 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id | |||
439 | return retval; | 447 | return retval; |
440 | } | 448 | } |
441 | 449 | ||
450 | pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(); | ||
442 | for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { | 451 | for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { |
443 | range = &mrfld_gpio_ranges[i]; | 452 | range = &mrfld_gpio_ranges[i]; |
444 | retval = gpiochip_add_pin_range(&priv->chip, | 453 | retval = gpiochip_add_pin_range(&priv->chip, |
445 | "pinctrl-merrifield", | 454 | pinctrl_dev_name, |
446 | range->gpio_base, | 455 | range->gpio_base, |
447 | range->pin_base, | 456 | range->pin_base, |
448 | range->npins); | 457 | range->npins); |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 44332b793718..14532d9576e4 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -2893,6 +2893,27 @@ void gpiod_set_raw_value(struct gpio_desc *desc, int value) | |||
2893 | EXPORT_SYMBOL_GPL(gpiod_set_raw_value); | 2893 | EXPORT_SYMBOL_GPL(gpiod_set_raw_value); |
2894 | 2894 | ||
2895 | /** | 2895 | /** |
2896 | * gpiod_set_value_nocheck() - set a GPIO line value without checking | ||
2897 | * @desc: the descriptor to set the value on | ||
2898 | * @value: value to set | ||
2899 | * | ||
2900 | * This sets the value of a GPIO line backing a descriptor, applying | ||
2901 | * different semantic quirks like active low and open drain/source | ||
2902 | * handling. | ||
2903 | */ | ||
2904 | static void gpiod_set_value_nocheck(struct gpio_desc *desc, int value) | ||
2905 | { | ||
2906 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
2907 | value = !value; | ||
2908 | if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | ||
2909 | gpio_set_open_drain_value_commit(desc, value); | ||
2910 | else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) | ||
2911 | gpio_set_open_source_value_commit(desc, value); | ||
2912 | else | ||
2913 | gpiod_set_raw_value_commit(desc, value); | ||
2914 | } | ||
2915 | |||
2916 | /** | ||
2896 | * gpiod_set_value() - assign a gpio's value | 2917 | * gpiod_set_value() - assign a gpio's value |
2897 | * @desc: gpio whose value will be assigned | 2918 | * @desc: gpio whose value will be assigned |
2898 | * @value: value to assign | 2919 | * @value: value to assign |
@@ -2906,16 +2927,8 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_value); | |||
2906 | void gpiod_set_value(struct gpio_desc *desc, int value) | 2927 | void gpiod_set_value(struct gpio_desc *desc, int value) |
2907 | { | 2928 | { |
2908 | VALIDATE_DESC_VOID(desc); | 2929 | VALIDATE_DESC_VOID(desc); |
2909 | /* Should be using gpiod_set_value_cansleep() */ | ||
2910 | WARN_ON(desc->gdev->chip->can_sleep); | 2930 | WARN_ON(desc->gdev->chip->can_sleep); |
2911 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 2931 | gpiod_set_value_nocheck(desc, value); |
2912 | value = !value; | ||
2913 | if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | ||
2914 | gpio_set_open_drain_value_commit(desc, value); | ||
2915 | else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) | ||
2916 | gpio_set_open_source_value_commit(desc, value); | ||
2917 | else | ||
2918 | gpiod_set_raw_value_commit(desc, value); | ||
2919 | } | 2932 | } |
2920 | EXPORT_SYMBOL_GPL(gpiod_set_value); | 2933 | EXPORT_SYMBOL_GPL(gpiod_set_value); |
2921 | 2934 | ||
@@ -3243,9 +3256,7 @@ void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) | |||
3243 | { | 3256 | { |
3244 | might_sleep_if(extra_checks); | 3257 | might_sleep_if(extra_checks); |
3245 | VALIDATE_DESC_VOID(desc); | 3258 | VALIDATE_DESC_VOID(desc); |
3246 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 3259 | gpiod_set_value_nocheck(desc, value); |
3247 | value = !value; | ||
3248 | gpiod_set_raw_value_commit(desc, value); | ||
3249 | } | 3260 | } |
3250 | EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep); | 3261 | EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep); |
3251 | 3262 | ||
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 85d4c57870fb..49af94627c8a 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
@@ -2777,12 +2777,12 @@ int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) | |||
2777 | } | 2777 | } |
2778 | 2778 | ||
2779 | static struct cmd_info *find_cmd_entry_any_ring(struct intel_gvt *gvt, | 2779 | static struct cmd_info *find_cmd_entry_any_ring(struct intel_gvt *gvt, |
2780 | unsigned int opcode, int rings) | 2780 | unsigned int opcode, unsigned long rings) |
2781 | { | 2781 | { |
2782 | struct cmd_info *info = NULL; | 2782 | struct cmd_info *info = NULL; |
2783 | unsigned int ring; | 2783 | unsigned int ring; |
2784 | 2784 | ||
2785 | for_each_set_bit(ring, (unsigned long *)&rings, I915_NUM_ENGINES) { | 2785 | for_each_set_bit(ring, &rings, I915_NUM_ENGINES) { |
2786 | info = find_cmd_entry(gvt, opcode, ring); | 2786 | info = find_cmd_entry(gvt, opcode, ring); |
2787 | if (info) | 2787 | if (info) |
2788 | break; | 2788 | break; |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 8e331142badb..64d67ff9bf08 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
@@ -1359,12 +1359,15 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp, | |||
1359 | return ret; | 1359 | return ret; |
1360 | } else { | 1360 | } else { |
1361 | if (!test_bit(index, spt->post_shadow_bitmap)) { | 1361 | if (!test_bit(index, spt->post_shadow_bitmap)) { |
1362 | int type = spt->shadow_page.type; | ||
1363 | |||
1362 | ppgtt_get_shadow_entry(spt, &se, index); | 1364 | ppgtt_get_shadow_entry(spt, &se, index); |
1363 | ret = ppgtt_handle_guest_entry_removal(gpt, &se, index); | 1365 | ret = ppgtt_handle_guest_entry_removal(gpt, &se, index); |
1364 | if (ret) | 1366 | if (ret) |
1365 | return ret; | 1367 | return ret; |
1368 | ops->set_pfn(&se, vgpu->gtt.scratch_pt[type].page_mfn); | ||
1369 | ppgtt_set_shadow_entry(spt, &se, index); | ||
1366 | } | 1370 | } |
1367 | |||
1368 | ppgtt_set_post_shadow(spt, index); | 1371 | ppgtt_set_post_shadow(spt, index); |
1369 | } | 1372 | } |
1370 | 1373 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 18de6569d04a..5cfba89ed586 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -467,7 +467,7 @@ static void __fence_set_priority(struct dma_fence *fence, int prio) | |||
467 | struct drm_i915_gem_request *rq; | 467 | struct drm_i915_gem_request *rq; |
468 | struct intel_engine_cs *engine; | 468 | struct intel_engine_cs *engine; |
469 | 469 | ||
470 | if (!dma_fence_is_i915(fence)) | 470 | if (dma_fence_is_signaled(fence) || !dma_fence_is_i915(fence)) |
471 | return; | 471 | return; |
472 | 472 | ||
473 | rq = to_request(fence); | 473 | rq = to_request(fence); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 333f40bc03bb..7923dfd9963c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -7027,6 +7027,8 @@ enum { | |||
7027 | #define GEN9_SLICE_COMMON_ECO_CHICKEN0 _MMIO(0x7308) | 7027 | #define GEN9_SLICE_COMMON_ECO_CHICKEN0 _MMIO(0x7308) |
7028 | #define DISABLE_PIXEL_MASK_CAMMING (1<<14) | 7028 | #define DISABLE_PIXEL_MASK_CAMMING (1<<14) |
7029 | 7029 | ||
7030 | #define GEN9_SLICE_COMMON_ECO_CHICKEN1 _MMIO(0x731c) | ||
7031 | |||
7030 | #define GEN7_L3SQCREG1 _MMIO(0xB010) | 7032 | #define GEN7_L3SQCREG1 _MMIO(0xB010) |
7031 | #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 | 7033 | #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 |
7032 | 7034 | ||
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index ab5bf4e2e28e..6074e04dc99f 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c | |||
@@ -1390,6 +1390,11 @@ static int glk_init_workarounds(struct intel_engine_cs *engine) | |||
1390 | if (ret) | 1390 | if (ret) |
1391 | return ret; | 1391 | return ret; |
1392 | 1392 | ||
1393 | /* WA #0862: Userspace has to set "Barrier Mode" to avoid hangs. */ | ||
1394 | ret = wa_ring_whitelist_reg(engine, GEN9_SLICE_COMMON_ECO_CHICKEN1); | ||
1395 | if (ret) | ||
1396 | return ret; | ||
1397 | |||
1393 | /* WaToEnableHwFixForPushConstHWBug:glk */ | 1398 | /* WaToEnableHwFixForPushConstHWBug:glk */ |
1394 | WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, | 1399 | WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, |
1395 | GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); | 1400 | GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d36e25607435..e71a8cd50498 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -974,6 +974,9 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) | |||
974 | 974 | ||
975 | GEM_BUG_ON(prio == I915_PRIORITY_INVALID); | 975 | GEM_BUG_ON(prio == I915_PRIORITY_INVALID); |
976 | 976 | ||
977 | if (i915_gem_request_completed(request)) | ||
978 | return; | ||
979 | |||
977 | if (prio <= READ_ONCE(request->priotree.priority)) | 980 | if (prio <= READ_ONCE(request->priotree.priority)) |
978 | return; | 981 | return; |
979 | 982 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index a2978a37b4f3..700fc754f28a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | |||
@@ -174,6 +174,7 @@ gf119_sor = { | |||
174 | .links = gf119_sor_dp_links, | 174 | .links = gf119_sor_dp_links, |
175 | .power = g94_sor_dp_power, | 175 | .power = g94_sor_dp_power, |
176 | .pattern = gf119_sor_dp_pattern, | 176 | .pattern = gf119_sor_dp_pattern, |
177 | .drive = gf119_sor_dp_drive, | ||
177 | .vcpi = gf119_sor_dp_vcpi, | 178 | .vcpi = gf119_sor_dp_vcpi, |
178 | .audio = gf119_sor_dp_audio, | 179 | .audio = gf119_sor_dp_audio, |
179 | .audio_sym = gf119_sor_dp_audio_sym, | 180 | .audio_sym = gf119_sor_dp_audio_sym, |
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index b0a1dedac802..476079f1255f 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c | |||
@@ -2656,6 +2656,9 @@ static int tegra_sor_probe(struct platform_device *pdev) | |||
2656 | name, err); | 2656 | name, err); |
2657 | goto remove; | 2657 | goto remove; |
2658 | } | 2658 | } |
2659 | } else { | ||
2660 | /* fall back to the module clock on SOR0 (eDP/LVDS only) */ | ||
2661 | sor->clk_out = sor->clk; | ||
2659 | } | 2662 | } |
2660 | 2663 | ||
2661 | sor->clk_parent = devm_clk_get(&pdev->dev, "parent"); | 2664 | sor->clk_parent = devm_clk_get(&pdev->dev, "parent"); |
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 26eddbb62893..3dd62d75f531 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c | |||
@@ -209,9 +209,6 @@ vc4_irq_postinstall(struct drm_device *dev) | |||
209 | { | 209 | { |
210 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 210 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
211 | 211 | ||
212 | /* Undo the effects of a previous vc4_irq_uninstall. */ | ||
213 | enable_irq(dev->irq); | ||
214 | |||
215 | /* Enable both the render done and out of memory interrupts. */ | 212 | /* Enable both the render done and out of memory interrupts. */ |
216 | V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); | 213 | V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); |
217 | 214 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index 622cd43840b8..493f392b3a0a 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c | |||
@@ -327,6 +327,9 @@ static int vc4_v3d_runtime_resume(struct device *dev) | |||
327 | return ret; | 327 | return ret; |
328 | 328 | ||
329 | vc4_v3d_init_hw(vc4->dev); | 329 | vc4_v3d_init_hw(vc4->dev); |
330 | |||
331 | /* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */ | ||
332 | enable_irq(vc4->dev->irq); | ||
330 | vc4_irq_postinstall(vc4->dev); | 333 | vc4_irq_postinstall(vc4->dev); |
331 | 334 | ||
332 | return 0; | 335 | return 0; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 21c62a34e558..87e8af5776a3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -2731,6 +2731,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, | |||
2731 | } | 2731 | } |
2732 | 2732 | ||
2733 | view_type = vmw_view_cmd_to_type(header->id); | 2733 | view_type = vmw_view_cmd_to_type(header->id); |
2734 | if (view_type == vmw_view_max) | ||
2735 | return -EINVAL; | ||
2734 | cmd = container_of(header, typeof(*cmd), header); | 2736 | cmd = container_of(header, typeof(*cmd), header); |
2735 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, | 2737 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, |
2736 | user_surface_converter, | 2738 | user_surface_converter, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 0545740b3724..641294aef165 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -697,7 +697,6 @@ vmw_du_plane_duplicate_state(struct drm_plane *plane) | |||
697 | vps->pinned = 0; | 697 | vps->pinned = 0; |
698 | 698 | ||
699 | /* Mapping is managed by prepare_fb/cleanup_fb */ | 699 | /* Mapping is managed by prepare_fb/cleanup_fb */ |
700 | memset(&vps->guest_map, 0, sizeof(vps->guest_map)); | ||
701 | memset(&vps->host_map, 0, sizeof(vps->host_map)); | 700 | memset(&vps->host_map, 0, sizeof(vps->host_map)); |
702 | vps->cpp = 0; | 701 | vps->cpp = 0; |
703 | 702 | ||
@@ -760,11 +759,6 @@ vmw_du_plane_destroy_state(struct drm_plane *plane, | |||
760 | 759 | ||
761 | 760 | ||
762 | /* Should have been freed by cleanup_fb */ | 761 | /* Should have been freed by cleanup_fb */ |
763 | if (vps->guest_map.virtual) { | ||
764 | DRM_ERROR("Guest mapping not freed\n"); | ||
765 | ttm_bo_kunmap(&vps->guest_map); | ||
766 | } | ||
767 | |||
768 | if (vps->host_map.virtual) { | 762 | if (vps->host_map.virtual) { |
769 | DRM_ERROR("Host mapping not freed\n"); | 763 | DRM_ERROR("Host mapping not freed\n"); |
770 | ttm_bo_kunmap(&vps->host_map); | 764 | ttm_bo_kunmap(&vps->host_map); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index ff9c8389ff21..cd9da2dd79af 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
@@ -175,7 +175,7 @@ struct vmw_plane_state { | |||
175 | int pinned; | 175 | int pinned; |
176 | 176 | ||
177 | /* For CPU Blit */ | 177 | /* For CPU Blit */ |
178 | struct ttm_bo_kmap_obj host_map, guest_map; | 178 | struct ttm_bo_kmap_obj host_map; |
179 | unsigned int cpp; | 179 | unsigned int cpp; |
180 | }; | 180 | }; |
181 | 181 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 90b5437fd787..b68d74888ab1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | |||
@@ -114,7 +114,7 @@ struct vmw_screen_target_display_unit { | |||
114 | bool defined; | 114 | bool defined; |
115 | 115 | ||
116 | /* For CPU Blit */ | 116 | /* For CPU Blit */ |
117 | struct ttm_bo_kmap_obj host_map, guest_map; | 117 | struct ttm_bo_kmap_obj host_map; |
118 | unsigned int cpp; | 118 | unsigned int cpp; |
119 | }; | 119 | }; |
120 | 120 | ||
@@ -695,7 +695,8 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty) | |||
695 | s32 src_pitch, dst_pitch; | 695 | s32 src_pitch, dst_pitch; |
696 | u8 *src, *dst; | 696 | u8 *src, *dst; |
697 | bool not_used; | 697 | bool not_used; |
698 | 698 | struct ttm_bo_kmap_obj guest_map; | |
699 | int ret; | ||
699 | 700 | ||
700 | if (!dirty->num_hits) | 701 | if (!dirty->num_hits) |
701 | return; | 702 | return; |
@@ -706,6 +707,13 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty) | |||
706 | if (width == 0 || height == 0) | 707 | if (width == 0 || height == 0) |
707 | return; | 708 | return; |
708 | 709 | ||
710 | ret = ttm_bo_kmap(&ddirty->buf->base, 0, ddirty->buf->base.num_pages, | ||
711 | &guest_map); | ||
712 | if (ret) { | ||
713 | DRM_ERROR("Failed mapping framebuffer for blit: %d\n", | ||
714 | ret); | ||
715 | goto out_cleanup; | ||
716 | } | ||
709 | 717 | ||
710 | /* Assume we are blitting from Host (display_srf) to Guest (dmabuf) */ | 718 | /* Assume we are blitting from Host (display_srf) to Guest (dmabuf) */ |
711 | src_pitch = stdu->display_srf->base_size.width * stdu->cpp; | 719 | src_pitch = stdu->display_srf->base_size.width * stdu->cpp; |
@@ -713,7 +721,7 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty) | |||
713 | src += ddirty->top * src_pitch + ddirty->left * stdu->cpp; | 721 | src += ddirty->top * src_pitch + ddirty->left * stdu->cpp; |
714 | 722 | ||
715 | dst_pitch = ddirty->pitch; | 723 | dst_pitch = ddirty->pitch; |
716 | dst = ttm_kmap_obj_virtual(&stdu->guest_map, ¬_used); | 724 | dst = ttm_kmap_obj_virtual(&guest_map, ¬_used); |
717 | dst += ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp; | 725 | dst += ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp; |
718 | 726 | ||
719 | 727 | ||
@@ -772,6 +780,7 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty) | |||
772 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 780 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
773 | } | 781 | } |
774 | 782 | ||
783 | ttm_bo_kunmap(&guest_map); | ||
775 | out_cleanup: | 784 | out_cleanup: |
776 | ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX; | 785 | ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX; |
777 | ddirty->right = ddirty->bottom = S32_MIN; | 786 | ddirty->right = ddirty->bottom = S32_MIN; |
@@ -1109,9 +1118,6 @@ vmw_stdu_primary_plane_cleanup_fb(struct drm_plane *plane, | |||
1109 | { | 1118 | { |
1110 | struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); | 1119 | struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); |
1111 | 1120 | ||
1112 | if (vps->guest_map.virtual) | ||
1113 | ttm_bo_kunmap(&vps->guest_map); | ||
1114 | |||
1115 | if (vps->host_map.virtual) | 1121 | if (vps->host_map.virtual) |
1116 | ttm_bo_kunmap(&vps->host_map); | 1122 | ttm_bo_kunmap(&vps->host_map); |
1117 | 1123 | ||
@@ -1277,33 +1283,11 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, | |||
1277 | */ | 1283 | */ |
1278 | if (vps->content_fb_type == SEPARATE_DMA && | 1284 | if (vps->content_fb_type == SEPARATE_DMA && |
1279 | !(dev_priv->capabilities & SVGA_CAP_3D)) { | 1285 | !(dev_priv->capabilities & SVGA_CAP_3D)) { |
1280 | |||
1281 | struct vmw_framebuffer_dmabuf *new_vfbd; | ||
1282 | |||
1283 | new_vfbd = vmw_framebuffer_to_vfbd(new_fb); | ||
1284 | |||
1285 | ret = ttm_bo_reserve(&new_vfbd->buffer->base, false, false, | ||
1286 | NULL); | ||
1287 | if (ret) | ||
1288 | goto out_srf_unpin; | ||
1289 | |||
1290 | ret = ttm_bo_kmap(&new_vfbd->buffer->base, 0, | ||
1291 | new_vfbd->buffer->base.num_pages, | ||
1292 | &vps->guest_map); | ||
1293 | |||
1294 | ttm_bo_unreserve(&new_vfbd->buffer->base); | ||
1295 | |||
1296 | if (ret) { | ||
1297 | DRM_ERROR("Failed to map content buffer to CPU\n"); | ||
1298 | goto out_srf_unpin; | ||
1299 | } | ||
1300 | |||
1301 | ret = ttm_bo_kmap(&vps->surf->res.backup->base, 0, | 1286 | ret = ttm_bo_kmap(&vps->surf->res.backup->base, 0, |
1302 | vps->surf->res.backup->base.num_pages, | 1287 | vps->surf->res.backup->base.num_pages, |
1303 | &vps->host_map); | 1288 | &vps->host_map); |
1304 | if (ret) { | 1289 | if (ret) { |
1305 | DRM_ERROR("Failed to map display buffer to CPU\n"); | 1290 | DRM_ERROR("Failed to map display buffer to CPU\n"); |
1306 | ttm_bo_kunmap(&vps->guest_map); | ||
1307 | goto out_srf_unpin; | 1291 | goto out_srf_unpin; |
1308 | } | 1292 | } |
1309 | 1293 | ||
@@ -1350,7 +1334,6 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane, | |||
1350 | stdu->display_srf = vps->surf; | 1334 | stdu->display_srf = vps->surf; |
1351 | stdu->content_fb_type = vps->content_fb_type; | 1335 | stdu->content_fb_type = vps->content_fb_type; |
1352 | stdu->cpp = vps->cpp; | 1336 | stdu->cpp = vps->cpp; |
1353 | memcpy(&stdu->guest_map, &vps->guest_map, sizeof(vps->guest_map)); | ||
1354 | memcpy(&stdu->host_map, &vps->host_map, sizeof(vps->host_map)); | 1337 | memcpy(&stdu->host_map, &vps->host_map, sizeof(vps->host_map)); |
1355 | 1338 | ||
1356 | if (!stdu->defined) | 1339 | if (!stdu->defined) |
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 5e871404f565..daa026d6a94f 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c | |||
@@ -1087,18 +1087,11 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev) | |||
1087 | struct device_node *np = dev->of_node; | 1087 | struct device_node *np = dev->of_node; |
1088 | const struct stm32_dfsdm_dev_data *dev_data; | 1088 | const struct stm32_dfsdm_dev_data *dev_data; |
1089 | struct iio_dev *iio; | 1089 | struct iio_dev *iio; |
1090 | const struct of_device_id *of_id; | ||
1091 | char *name; | 1090 | char *name; |
1092 | int ret, irq, val; | 1091 | int ret, irq, val; |
1093 | 1092 | ||
1094 | of_id = of_match_node(stm32_dfsdm_adc_match, np); | ||
1095 | if (!of_id->data) { | ||
1096 | dev_err(&pdev->dev, "Data associated to device is missing\n"); | ||
1097 | return -EINVAL; | ||
1098 | } | ||
1099 | |||
1100 | dev_data = (const struct stm32_dfsdm_dev_data *)of_id->data; | ||
1101 | 1093 | ||
1094 | dev_data = of_device_get_match_data(dev); | ||
1102 | iio = devm_iio_device_alloc(dev, sizeof(*adc)); | 1095 | iio = devm_iio_device_alloc(dev, sizeof(*adc)); |
1103 | if (!iio) { | 1096 | if (!iio) { |
1104 | dev_err(dev, "%s: Failed to allocate IIO\n", __func__); | 1097 | dev_err(dev, "%s: Failed to allocate IIO\n", __func__); |
@@ -1106,10 +1099,6 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev) | |||
1106 | } | 1099 | } |
1107 | 1100 | ||
1108 | adc = iio_priv(iio); | 1101 | adc = iio_priv(iio); |
1109 | if (IS_ERR(adc)) { | ||
1110 | dev_err(dev, "%s: Failed to allocate ADC\n", __func__); | ||
1111 | return PTR_ERR(adc); | ||
1112 | } | ||
1113 | adc->dfsdm = dev_get_drvdata(dev->parent); | 1102 | adc->dfsdm = dev_get_drvdata(dev->parent); |
1114 | 1103 | ||
1115 | iio->dev.parent = dev; | 1104 | iio->dev.parent = dev; |
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index 6cd655f8239b..6290332cfd3f 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c | |||
@@ -242,7 +242,6 @@ MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match); | |||
242 | static int stm32_dfsdm_probe(struct platform_device *pdev) | 242 | static int stm32_dfsdm_probe(struct platform_device *pdev) |
243 | { | 243 | { |
244 | struct dfsdm_priv *priv; | 244 | struct dfsdm_priv *priv; |
245 | const struct of_device_id *of_id; | ||
246 | const struct stm32_dfsdm_dev_data *dev_data; | 245 | const struct stm32_dfsdm_dev_data *dev_data; |
247 | struct stm32_dfsdm *dfsdm; | 246 | struct stm32_dfsdm *dfsdm; |
248 | int ret; | 247 | int ret; |
@@ -253,13 +252,8 @@ static int stm32_dfsdm_probe(struct platform_device *pdev) | |||
253 | 252 | ||
254 | priv->pdev = pdev; | 253 | priv->pdev = pdev; |
255 | 254 | ||
256 | of_id = of_match_node(stm32_dfsdm_of_match, pdev->dev.of_node); | 255 | dev_data = of_device_get_match_data(&pdev->dev); |
257 | if (!of_id->data) { | ||
258 | dev_err(&pdev->dev, "Data associated to device is missing\n"); | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | 256 | ||
262 | dev_data = (const struct stm32_dfsdm_dev_data *)of_id->data; | ||
263 | dfsdm = &priv->dfsdm; | 257 | dfsdm = &priv->dfsdm; |
264 | dfsdm->fl_list = devm_kcalloc(&pdev->dev, dev_data->num_filters, | 258 | dfsdm->fl_list = devm_kcalloc(&pdev->dev, dev_data->num_filters, |
265 | sizeof(*dfsdm->fl_list), GFP_KERNEL); | 259 | sizeof(*dfsdm->fl_list), GFP_KERNEL); |
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index a1d687a664f8..66f0268f37a6 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h | |||
@@ -314,7 +314,7 @@ static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map, | |||
314 | } | 314 | } |
315 | #endif | 315 | #endif |
316 | 316 | ||
317 | struct ib_device *__ib_device_get_by_index(u32 ifindex); | 317 | struct ib_device *ib_device_get_by_index(u32 ifindex); |
318 | /* RDMA device netlink */ | 318 | /* RDMA device netlink */ |
319 | void nldev_init(void); | 319 | void nldev_init(void); |
320 | void nldev_exit(void); | 320 | void nldev_exit(void); |
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 30914f3baa5f..465520627e4b 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
@@ -134,7 +134,7 @@ static int ib_device_check_mandatory(struct ib_device *device) | |||
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | struct ib_device *__ib_device_get_by_index(u32 index) | 137 | static struct ib_device *__ib_device_get_by_index(u32 index) |
138 | { | 138 | { |
139 | struct ib_device *device; | 139 | struct ib_device *device; |
140 | 140 | ||
@@ -145,6 +145,22 @@ struct ib_device *__ib_device_get_by_index(u32 index) | |||
145 | return NULL; | 145 | return NULL; |
146 | } | 146 | } |
147 | 147 | ||
148 | /* | ||
149 | * Caller is responsible to return refrerence count by calling put_device() | ||
150 | */ | ||
151 | struct ib_device *ib_device_get_by_index(u32 index) | ||
152 | { | ||
153 | struct ib_device *device; | ||
154 | |||
155 | down_read(&lists_rwsem); | ||
156 | device = __ib_device_get_by_index(index); | ||
157 | if (device) | ||
158 | get_device(&device->dev); | ||
159 | |||
160 | up_read(&lists_rwsem); | ||
161 | return device; | ||
162 | } | ||
163 | |||
148 | static struct ib_device *__ib_device_get_by_name(const char *name) | 164 | static struct ib_device *__ib_device_get_by_name(const char *name) |
149 | { | 165 | { |
150 | struct ib_device *device; | 166 | struct ib_device *device; |
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 9a05245a1acf..0dcd1aa6f683 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c | |||
@@ -142,27 +142,34 @@ static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
142 | 142 | ||
143 | index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); | 143 | index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); |
144 | 144 | ||
145 | device = __ib_device_get_by_index(index); | 145 | device = ib_device_get_by_index(index); |
146 | if (!device) | 146 | if (!device) |
147 | return -EINVAL; | 147 | return -EINVAL; |
148 | 148 | ||
149 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 149 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
150 | if (!msg) | 150 | if (!msg) { |
151 | return -ENOMEM; | 151 | err = -ENOMEM; |
152 | goto err; | ||
153 | } | ||
152 | 154 | ||
153 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, | 155 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, |
154 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), | 156 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), |
155 | 0, 0); | 157 | 0, 0); |
156 | 158 | ||
157 | err = fill_dev_info(msg, device); | 159 | err = fill_dev_info(msg, device); |
158 | if (err) { | 160 | if (err) |
159 | nlmsg_free(msg); | 161 | goto err_free; |
160 | return err; | ||
161 | } | ||
162 | 162 | ||
163 | nlmsg_end(msg, nlh); | 163 | nlmsg_end(msg, nlh); |
164 | 164 | ||
165 | put_device(&device->dev); | ||
165 | return rdma_nl_unicast(msg, NETLINK_CB(skb).portid); | 166 | return rdma_nl_unicast(msg, NETLINK_CB(skb).portid); |
167 | |||
168 | err_free: | ||
169 | nlmsg_free(msg); | ||
170 | err: | ||
171 | put_device(&device->dev); | ||
172 | return err; | ||
166 | } | 173 | } |
167 | 174 | ||
168 | static int _nldev_get_dumpit(struct ib_device *device, | 175 | static int _nldev_get_dumpit(struct ib_device *device, |
@@ -220,31 +227,40 @@ static int nldev_port_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
220 | return -EINVAL; | 227 | return -EINVAL; |
221 | 228 | ||
222 | index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); | 229 | index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); |
223 | device = __ib_device_get_by_index(index); | 230 | device = ib_device_get_by_index(index); |
224 | if (!device) | 231 | if (!device) |
225 | return -EINVAL; | 232 | return -EINVAL; |
226 | 233 | ||
227 | port = nla_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]); | 234 | port = nla_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]); |
228 | if (!rdma_is_port_valid(device, port)) | 235 | if (!rdma_is_port_valid(device, port)) { |
229 | return -EINVAL; | 236 | err = -EINVAL; |
237 | goto err; | ||
238 | } | ||
230 | 239 | ||
231 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 240 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
232 | if (!msg) | 241 | if (!msg) { |
233 | return -ENOMEM; | 242 | err = -ENOMEM; |
243 | goto err; | ||
244 | } | ||
234 | 245 | ||
235 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, | 246 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, |
236 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), | 247 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), |
237 | 0, 0); | 248 | 0, 0); |
238 | 249 | ||
239 | err = fill_port_info(msg, device, port); | 250 | err = fill_port_info(msg, device, port); |
240 | if (err) { | 251 | if (err) |
241 | nlmsg_free(msg); | 252 | goto err_free; |
242 | return err; | ||
243 | } | ||
244 | 253 | ||
245 | nlmsg_end(msg, nlh); | 254 | nlmsg_end(msg, nlh); |
255 | put_device(&device->dev); | ||
246 | 256 | ||
247 | return rdma_nl_unicast(msg, NETLINK_CB(skb).portid); | 257 | return rdma_nl_unicast(msg, NETLINK_CB(skb).portid); |
258 | |||
259 | err_free: | ||
260 | nlmsg_free(msg); | ||
261 | err: | ||
262 | put_device(&device->dev); | ||
263 | return err; | ||
248 | } | 264 | } |
249 | 265 | ||
250 | static int nldev_port_get_dumpit(struct sk_buff *skb, | 266 | static int nldev_port_get_dumpit(struct sk_buff *skb, |
@@ -265,7 +281,7 @@ static int nldev_port_get_dumpit(struct sk_buff *skb, | |||
265 | return -EINVAL; | 281 | return -EINVAL; |
266 | 282 | ||
267 | ifindex = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); | 283 | ifindex = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); |
268 | device = __ib_device_get_by_index(ifindex); | 284 | device = ib_device_get_by_index(ifindex); |
269 | if (!device) | 285 | if (!device) |
270 | return -EINVAL; | 286 | return -EINVAL; |
271 | 287 | ||
@@ -299,7 +315,9 @@ static int nldev_port_get_dumpit(struct sk_buff *skb, | |||
299 | nlmsg_end(skb, nlh); | 315 | nlmsg_end(skb, nlh); |
300 | } | 316 | } |
301 | 317 | ||
302 | out: cb->args[0] = idx; | 318 | out: |
319 | put_device(&device->dev); | ||
320 | cb->args[0] = idx; | ||
303 | return skb->len; | 321 | return skb->len; |
304 | } | 322 | } |
305 | 323 | ||
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 313bfb9ccb71..4975f3e6596e 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -642,7 +642,6 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, | |||
642 | goto err_free_mr; | 642 | goto err_free_mr; |
643 | 643 | ||
644 | mr->max_pages = max_num_sg; | 644 | mr->max_pages = max_num_sg; |
645 | |||
646 | err = mlx4_mr_enable(dev->dev, &mr->mmr); | 645 | err = mlx4_mr_enable(dev->dev, &mr->mmr); |
647 | if (err) | 646 | if (err) |
648 | goto err_free_pl; | 647 | goto err_free_pl; |
@@ -653,6 +652,7 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, | |||
653 | return &mr->ibmr; | 652 | return &mr->ibmr; |
654 | 653 | ||
655 | err_free_pl: | 654 | err_free_pl: |
655 | mr->ibmr.device = pd->device; | ||
656 | mlx4_free_priv_pages(mr); | 656 | mlx4_free_priv_pages(mr); |
657 | err_free_mr: | 657 | err_free_mr: |
658 | (void) mlx4_mr_free(dev->dev, &mr->mmr); | 658 | (void) mlx4_mr_free(dev->dev, &mr->mmr); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 12b7f911f0e5..8880351df179 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -902,8 +902,8 @@ static int path_rec_start(struct net_device *dev, | |||
902 | return 0; | 902 | return 0; |
903 | } | 903 | } |
904 | 904 | ||
905 | static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | 905 | static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr, |
906 | struct net_device *dev) | 906 | struct net_device *dev) |
907 | { | 907 | { |
908 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 908 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
909 | struct rdma_netdev *rn = netdev_priv(dev); | 909 | struct rdma_netdev *rn = netdev_priv(dev); |
@@ -917,7 +917,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
917 | spin_unlock_irqrestore(&priv->lock, flags); | 917 | spin_unlock_irqrestore(&priv->lock, flags); |
918 | ++dev->stats.tx_dropped; | 918 | ++dev->stats.tx_dropped; |
919 | dev_kfree_skb_any(skb); | 919 | dev_kfree_skb_any(skb); |
920 | return; | 920 | return NULL; |
921 | } | ||
922 | |||
923 | /* To avoid race condition, make sure that the | ||
924 | * neigh will be added only once. | ||
925 | */ | ||
926 | if (unlikely(!list_empty(&neigh->list))) { | ||
927 | spin_unlock_irqrestore(&priv->lock, flags); | ||
928 | return neigh; | ||
921 | } | 929 | } |
922 | 930 | ||
923 | path = __path_find(dev, daddr + 4); | 931 | path = __path_find(dev, daddr + 4); |
@@ -956,7 +964,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
956 | path->ah->last_send = rn->send(dev, skb, path->ah->ah, | 964 | path->ah->last_send = rn->send(dev, skb, path->ah->ah, |
957 | IPOIB_QPN(daddr)); | 965 | IPOIB_QPN(daddr)); |
958 | ipoib_neigh_put(neigh); | 966 | ipoib_neigh_put(neigh); |
959 | return; | 967 | return NULL; |
960 | } | 968 | } |
961 | } else { | 969 | } else { |
962 | neigh->ah = NULL; | 970 | neigh->ah = NULL; |
@@ -973,7 +981,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
973 | 981 | ||
974 | spin_unlock_irqrestore(&priv->lock, flags); | 982 | spin_unlock_irqrestore(&priv->lock, flags); |
975 | ipoib_neigh_put(neigh); | 983 | ipoib_neigh_put(neigh); |
976 | return; | 984 | return NULL; |
977 | 985 | ||
978 | err_path: | 986 | err_path: |
979 | ipoib_neigh_free(neigh); | 987 | ipoib_neigh_free(neigh); |
@@ -983,6 +991,8 @@ err_drop: | |||
983 | 991 | ||
984 | spin_unlock_irqrestore(&priv->lock, flags); | 992 | spin_unlock_irqrestore(&priv->lock, flags); |
985 | ipoib_neigh_put(neigh); | 993 | ipoib_neigh_put(neigh); |
994 | |||
995 | return NULL; | ||
986 | } | 996 | } |
987 | 997 | ||
988 | static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | 998 | static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, |
@@ -1091,8 +1101,9 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1091 | case htons(ETH_P_TIPC): | 1101 | case htons(ETH_P_TIPC): |
1092 | neigh = ipoib_neigh_get(dev, phdr->hwaddr); | 1102 | neigh = ipoib_neigh_get(dev, phdr->hwaddr); |
1093 | if (unlikely(!neigh)) { | 1103 | if (unlikely(!neigh)) { |
1094 | neigh_add_path(skb, phdr->hwaddr, dev); | 1104 | neigh = neigh_add_path(skb, phdr->hwaddr, dev); |
1095 | return NETDEV_TX_OK; | 1105 | if (likely(!neigh)) |
1106 | return NETDEV_TX_OK; | ||
1096 | } | 1107 | } |
1097 | break; | 1108 | break; |
1098 | case htons(ETH_P_ARP): | 1109 | case htons(ETH_P_ARP): |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 93e149efc1f5..9b3f47ae2016 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -816,7 +816,10 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) | |||
816 | spin_lock_irqsave(&priv->lock, flags); | 816 | spin_lock_irqsave(&priv->lock, flags); |
817 | if (!neigh) { | 817 | if (!neigh) { |
818 | neigh = ipoib_neigh_alloc(daddr, dev); | 818 | neigh = ipoib_neigh_alloc(daddr, dev); |
819 | if (neigh) { | 819 | /* Make sure that the neigh will be added only |
820 | * once to mcast list. | ||
821 | */ | ||
822 | if (neigh && list_empty(&neigh->list)) { | ||
820 | kref_get(&mcast->ah->ref); | 823 | kref_get(&mcast->ah->ref); |
821 | neigh->ah = mcast->ah; | 824 | neigh->ah = mcast->ah; |
822 | list_add_tail(&neigh->list, &mcast->neigh_list); | 825 | list_add_tail(&neigh->list, &mcast->neigh_list); |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 8a1bd354b1cc..bfa576aa9f03 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -1013,8 +1013,7 @@ static int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp) | |||
1013 | return -ENOMEM; | 1013 | return -ENOMEM; |
1014 | 1014 | ||
1015 | attr->qp_state = IB_QPS_INIT; | 1015 | attr->qp_state = IB_QPS_INIT; |
1016 | attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ | | 1016 | attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE; |
1017 | IB_ACCESS_REMOTE_WRITE; | ||
1018 | attr->port_num = ch->sport->port; | 1017 | attr->port_num = ch->sport->port; |
1019 | attr->pkey_index = 0; | 1018 | attr->pkey_index = 0; |
1020 | 1019 | ||
@@ -2078,7 +2077,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, | |||
2078 | goto destroy_ib; | 2077 | goto destroy_ib; |
2079 | } | 2078 | } |
2080 | 2079 | ||
2081 | guid = (__be16 *)¶m->primary_path->sgid.global.interface_id; | 2080 | guid = (__be16 *)¶m->primary_path->dgid.global.interface_id; |
2082 | snprintf(ch->ini_guid, sizeof(ch->ini_guid), "%04x:%04x:%04x:%04x", | 2081 | snprintf(ch->ini_guid, sizeof(ch->ini_guid), "%04x:%04x:%04x:%04x", |
2083 | be16_to_cpu(guid[0]), be16_to_cpu(guid[1]), | 2082 | be16_to_cpu(guid[0]), be16_to_cpu(guid[1]), |
2084 | be16_to_cpu(guid[2]), be16_to_cpu(guid[3])); | 2083 | be16_to_cpu(guid[2]), be16_to_cpu(guid[3])); |
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index fcf7235d5742..157e1d9e7725 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/module.h> | ||
27 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
28 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
29 | #include <linux/mmc/host.h> | 30 | #include <linux/mmc/host.h> |
@@ -667,3 +668,5 @@ int renesas_sdhi_remove(struct platform_device *pdev) | |||
667 | return 0; | 668 | return 0; |
668 | } | 669 | } |
669 | EXPORT_SYMBOL_GPL(renesas_sdhi_remove); | 670 | EXPORT_SYMBOL_GPL(renesas_sdhi_remove); |
671 | |||
672 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index f7f157a62a4a..555c7f133eb8 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -1424,7 +1424,9 @@ static const struct file_operations s3cmci_fops_state = { | |||
1424 | struct s3cmci_reg { | 1424 | struct s3cmci_reg { |
1425 | unsigned short addr; | 1425 | unsigned short addr; |
1426 | unsigned char *name; | 1426 | unsigned char *name; |
1427 | } debug_regs[] = { | 1427 | }; |
1428 | |||
1429 | static const struct s3cmci_reg debug_regs[] = { | ||
1428 | DBG_REG(CON), | 1430 | DBG_REG(CON), |
1429 | DBG_REG(PRE), | 1431 | DBG_REG(PRE), |
1430 | DBG_REG(CMDARG), | 1432 | DBG_REG(CMDARG), |
@@ -1446,7 +1448,7 @@ struct s3cmci_reg { | |||
1446 | static int s3cmci_regs_show(struct seq_file *seq, void *v) | 1448 | static int s3cmci_regs_show(struct seq_file *seq, void *v) |
1447 | { | 1449 | { |
1448 | struct s3cmci_host *host = seq->private; | 1450 | struct s3cmci_host *host = seq->private; |
1449 | struct s3cmci_reg *rptr = debug_regs; | 1451 | const struct s3cmci_reg *rptr = debug_regs; |
1450 | 1452 | ||
1451 | for (; rptr->name; rptr++) | 1453 | for (; rptr->name; rptr++) |
1452 | seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name, | 1454 | seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name, |
diff --git a/drivers/mux/core.c b/drivers/mux/core.c index 2260063b0ea8..6e5cf9d9cd99 100644 --- a/drivers/mux/core.c +++ b/drivers/mux/core.c | |||
@@ -413,6 +413,7 @@ static int of_dev_node_match(struct device *dev, const void *data) | |||
413 | return dev->of_node == data; | 413 | return dev->of_node == data; |
414 | } | 414 | } |
415 | 415 | ||
416 | /* Note this function returns a reference to the mux_chip dev. */ | ||
416 | static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np) | 417 | static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np) |
417 | { | 418 | { |
418 | struct device *dev; | 419 | struct device *dev; |
@@ -466,6 +467,7 @@ struct mux_control *mux_control_get(struct device *dev, const char *mux_name) | |||
466 | (!args.args_count && (mux_chip->controllers > 1))) { | 467 | (!args.args_count && (mux_chip->controllers > 1))) { |
467 | dev_err(dev, "%pOF: wrong #mux-control-cells for %pOF\n", | 468 | dev_err(dev, "%pOF: wrong #mux-control-cells for %pOF\n", |
468 | np, args.np); | 469 | np, args.np); |
470 | put_device(&mux_chip->dev); | ||
469 | return ERR_PTR(-EINVAL); | 471 | return ERR_PTR(-EINVAL); |
470 | } | 472 | } |
471 | 473 | ||
@@ -476,10 +478,10 @@ struct mux_control *mux_control_get(struct device *dev, const char *mux_name) | |||
476 | if (controller >= mux_chip->controllers) { | 478 | if (controller >= mux_chip->controllers) { |
477 | dev_err(dev, "%pOF: bad mux controller %u specified in %pOF\n", | 479 | dev_err(dev, "%pOF: bad mux controller %u specified in %pOF\n", |
478 | np, controller, args.np); | 480 | np, controller, args.np); |
481 | put_device(&mux_chip->dev); | ||
479 | return ERR_PTR(-EINVAL); | 482 | return ERR_PTR(-EINVAL); |
480 | } | 483 | } |
481 | 484 | ||
482 | get_device(&mux_chip->dev); | ||
483 | return &mux_chip->mux[controller]; | 485 | return &mux_chip->mux[controller]; |
484 | } | 486 | } |
485 | EXPORT_SYMBOL_GPL(mux_control_get); | 487 | EXPORT_SYMBOL_GPL(mux_control_get); |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 0626dcfd1f3d..760d2c07e3a2 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -526,7 +526,7 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
526 | data = be32_to_cpup((__be32 *)&cf->data[0]); | 526 | data = be32_to_cpup((__be32 *)&cf->data[0]); |
527 | flexcan_write(data, &priv->tx_mb->data[0]); | 527 | flexcan_write(data, &priv->tx_mb->data[0]); |
528 | } | 528 | } |
529 | if (cf->can_dlc > 3) { | 529 | if (cf->can_dlc > 4) { |
530 | data = be32_to_cpup((__be32 *)&cf->data[4]); | 530 | data = be32_to_cpup((__be32 *)&cf->data[4]); |
531 | flexcan_write(data, &priv->tx_mb->data[1]); | 531 | flexcan_write(data, &priv->tx_mb->data[1]); |
532 | } | 532 | } |
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index b00358297424..12ff0020ecd6 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c | |||
@@ -395,6 +395,7 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) | |||
395 | 395 | ||
396 | if (dev->can.state == CAN_STATE_ERROR_WARNING || | 396 | if (dev->can.state == CAN_STATE_ERROR_WARNING || |
397 | dev->can.state == CAN_STATE_ERROR_PASSIVE) { | 397 | dev->can.state == CAN_STATE_ERROR_PASSIVE) { |
398 | cf->can_id |= CAN_ERR_CRTL; | ||
398 | cf->data[1] = (txerr > rxerr) ? | 399 | cf->data[1] = (txerr > rxerr) ? |
399 | CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE; | 400 | CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE; |
400 | } | 401 | } |
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 68ac3e88a8ce..8bf80ad9dc44 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c | |||
@@ -449,7 +449,7 @@ static int gs_usb_set_bittiming(struct net_device *netdev) | |||
449 | dev_err(netdev->dev.parent, "Couldn't set bittimings (err=%d)", | 449 | dev_err(netdev->dev.parent, "Couldn't set bittimings (err=%d)", |
450 | rc); | 450 | rc); |
451 | 451 | ||
452 | return rc; | 452 | return (rc > 0) ? 0 : rc; |
453 | } | 453 | } |
454 | 454 | ||
455 | static void gs_usb_xmit_callback(struct urb *urb) | 455 | static void gs_usb_xmit_callback(struct urb *urb) |
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c index 8404e8852a0f..b4c4a2c76437 100644 --- a/drivers/net/can/vxcan.c +++ b/drivers/net/can/vxcan.c | |||
@@ -194,7 +194,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev, | |||
194 | tbp = peer_tb; | 194 | tbp = peer_tb; |
195 | } | 195 | } |
196 | 196 | ||
197 | if (tbp[IFLA_IFNAME]) { | 197 | if (ifmp && tbp[IFLA_IFNAME]) { |
198 | nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ); | 198 | nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ); |
199 | name_assign_type = NET_NAME_USER; | 199 | name_assign_type = NET_NAME_USER; |
200 | } else { | 200 | } else { |
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index f5a8dd96fd75..4498ab897d94 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c | |||
@@ -1500,10 +1500,13 @@ static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, | |||
1500 | { | 1500 | { |
1501 | struct b53_device *dev = ds->priv; | 1501 | struct b53_device *dev = ds->priv; |
1502 | 1502 | ||
1503 | /* Older models support a different tag format that we do not | 1503 | /* Older models (5325, 5365) support a different tag format that we do |
1504 | * support in net/dsa/tag_brcm.c yet. | 1504 | * not support in net/dsa/tag_brcm.c yet. 539x and 531x5 require managed |
1505 | * mode to be turned on which means we need to specifically manage ARL | ||
1506 | * misses on multicast addresses (TBD). | ||
1505 | */ | 1507 | */ |
1506 | if (is5325(dev) || is5365(dev) || !b53_can_enable_brcm_tags(ds, port)) | 1508 | if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) || |
1509 | !b53_can_enable_brcm_tags(ds, port)) | ||
1507 | return DSA_TAG_PROTO_NONE; | 1510 | return DSA_TAG_PROTO_NONE; |
1508 | 1511 | ||
1509 | /* Broadcom BCM58xx chips have a flow accelerator on Port 8 | 1512 | /* Broadcom BCM58xx chips have a flow accelerator on Port 8 |
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index f4e13a7014bd..36c8950dbd2d 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
@@ -602,7 +602,7 @@ struct vortex_private { | |||
602 | struct sk_buff* rx_skbuff[RX_RING_SIZE]; | 602 | struct sk_buff* rx_skbuff[RX_RING_SIZE]; |
603 | struct sk_buff* tx_skbuff[TX_RING_SIZE]; | 603 | struct sk_buff* tx_skbuff[TX_RING_SIZE]; |
604 | unsigned int cur_rx, cur_tx; /* The next free ring entry */ | 604 | unsigned int cur_rx, cur_tx; /* The next free ring entry */ |
605 | unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ | 605 | unsigned int dirty_tx; /* The ring entries to be free()ed. */ |
606 | struct vortex_extra_stats xstats; /* NIC-specific extra stats */ | 606 | struct vortex_extra_stats xstats; /* NIC-specific extra stats */ |
607 | struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ | 607 | struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ |
608 | dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ | 608 | dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ |
@@ -618,7 +618,6 @@ struct vortex_private { | |||
618 | 618 | ||
619 | /* The remainder are related to chip state, mostly media selection. */ | 619 | /* The remainder are related to chip state, mostly media selection. */ |
620 | struct timer_list timer; /* Media selection timer. */ | 620 | struct timer_list timer; /* Media selection timer. */ |
621 | struct timer_list rx_oom_timer; /* Rx skb allocation retry timer */ | ||
622 | int options; /* User-settable misc. driver options. */ | 621 | int options; /* User-settable misc. driver options. */ |
623 | unsigned int media_override:4, /* Passed-in media type. */ | 622 | unsigned int media_override:4, /* Passed-in media type. */ |
624 | default_media:4, /* Read from the EEPROM/Wn3_Config. */ | 623 | default_media:4, /* Read from the EEPROM/Wn3_Config. */ |
@@ -760,7 +759,6 @@ static void mdio_sync(struct vortex_private *vp, int bits); | |||
760 | static int mdio_read(struct net_device *dev, int phy_id, int location); | 759 | static int mdio_read(struct net_device *dev, int phy_id, int location); |
761 | static void mdio_write(struct net_device *vp, int phy_id, int location, int value); | 760 | static void mdio_write(struct net_device *vp, int phy_id, int location, int value); |
762 | static void vortex_timer(struct timer_list *t); | 761 | static void vortex_timer(struct timer_list *t); |
763 | static void rx_oom_timer(struct timer_list *t); | ||
764 | static netdev_tx_t vortex_start_xmit(struct sk_buff *skb, | 762 | static netdev_tx_t vortex_start_xmit(struct sk_buff *skb, |
765 | struct net_device *dev); | 763 | struct net_device *dev); |
766 | static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb, | 764 | static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb, |
@@ -1601,7 +1599,6 @@ vortex_up(struct net_device *dev) | |||
1601 | 1599 | ||
1602 | timer_setup(&vp->timer, vortex_timer, 0); | 1600 | timer_setup(&vp->timer, vortex_timer, 0); |
1603 | mod_timer(&vp->timer, RUN_AT(media_tbl[dev->if_port].wait)); | 1601 | mod_timer(&vp->timer, RUN_AT(media_tbl[dev->if_port].wait)); |
1604 | timer_setup(&vp->rx_oom_timer, rx_oom_timer, 0); | ||
1605 | 1602 | ||
1606 | if (vortex_debug > 1) | 1603 | if (vortex_debug > 1) |
1607 | pr_debug("%s: Initial media type %s.\n", | 1604 | pr_debug("%s: Initial media type %s.\n", |
@@ -1676,7 +1673,7 @@ vortex_up(struct net_device *dev) | |||
1676 | window_write16(vp, 0x0040, 4, Wn4_NetDiag); | 1673 | window_write16(vp, 0x0040, 4, Wn4_NetDiag); |
1677 | 1674 | ||
1678 | if (vp->full_bus_master_rx) { /* Boomerang bus master. */ | 1675 | if (vp->full_bus_master_rx) { /* Boomerang bus master. */ |
1679 | vp->cur_rx = vp->dirty_rx = 0; | 1676 | vp->cur_rx = 0; |
1680 | /* Initialize the RxEarly register as recommended. */ | 1677 | /* Initialize the RxEarly register as recommended. */ |
1681 | iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD); | 1678 | iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD); |
1682 | iowrite32(0x0020, ioaddr + PktStatus); | 1679 | iowrite32(0x0020, ioaddr + PktStatus); |
@@ -1729,6 +1726,7 @@ vortex_open(struct net_device *dev) | |||
1729 | struct vortex_private *vp = netdev_priv(dev); | 1726 | struct vortex_private *vp = netdev_priv(dev); |
1730 | int i; | 1727 | int i; |
1731 | int retval; | 1728 | int retval; |
1729 | dma_addr_t dma; | ||
1732 | 1730 | ||
1733 | /* Use the now-standard shared IRQ implementation. */ | 1731 | /* Use the now-standard shared IRQ implementation. */ |
1734 | if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ? | 1732 | if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ? |
@@ -1753,7 +1751,11 @@ vortex_open(struct net_device *dev) | |||
1753 | break; /* Bad news! */ | 1751 | break; /* Bad news! */ |
1754 | 1752 | ||
1755 | skb_reserve(skb, NET_IP_ALIGN); /* Align IP on 16 byte boundaries */ | 1753 | skb_reserve(skb, NET_IP_ALIGN); /* Align IP on 16 byte boundaries */ |
1756 | vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); | 1754 | dma = pci_map_single(VORTEX_PCI(vp), skb->data, |
1755 | PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | ||
1756 | if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma)) | ||
1757 | break; | ||
1758 | vp->rx_ring[i].addr = cpu_to_le32(dma); | ||
1757 | } | 1759 | } |
1758 | if (i != RX_RING_SIZE) { | 1760 | if (i != RX_RING_SIZE) { |
1759 | pr_emerg("%s: no memory for rx ring\n", dev->name); | 1761 | pr_emerg("%s: no memory for rx ring\n", dev->name); |
@@ -2067,6 +2069,12 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2067 | int len = (skb->len + 3) & ~3; | 2069 | int len = (skb->len + 3) & ~3; |
2068 | vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, | 2070 | vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, |
2069 | PCI_DMA_TODEVICE); | 2071 | PCI_DMA_TODEVICE); |
2072 | if (dma_mapping_error(&VORTEX_PCI(vp)->dev, vp->tx_skb_dma)) { | ||
2073 | dev_kfree_skb_any(skb); | ||
2074 | dev->stats.tx_dropped++; | ||
2075 | return NETDEV_TX_OK; | ||
2076 | } | ||
2077 | |||
2070 | spin_lock_irq(&vp->window_lock); | 2078 | spin_lock_irq(&vp->window_lock); |
2071 | window_set(vp, 7); | 2079 | window_set(vp, 7); |
2072 | iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr); | 2080 | iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr); |
@@ -2593,7 +2601,7 @@ boomerang_rx(struct net_device *dev) | |||
2593 | int entry = vp->cur_rx % RX_RING_SIZE; | 2601 | int entry = vp->cur_rx % RX_RING_SIZE; |
2594 | void __iomem *ioaddr = vp->ioaddr; | 2602 | void __iomem *ioaddr = vp->ioaddr; |
2595 | int rx_status; | 2603 | int rx_status; |
2596 | int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx; | 2604 | int rx_work_limit = RX_RING_SIZE; |
2597 | 2605 | ||
2598 | if (vortex_debug > 5) | 2606 | if (vortex_debug > 5) |
2599 | pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS)); | 2607 | pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS)); |
@@ -2614,7 +2622,8 @@ boomerang_rx(struct net_device *dev) | |||
2614 | } else { | 2622 | } else { |
2615 | /* The packet length: up to 4.5K!. */ | 2623 | /* The packet length: up to 4.5K!. */ |
2616 | int pkt_len = rx_status & 0x1fff; | 2624 | int pkt_len = rx_status & 0x1fff; |
2617 | struct sk_buff *skb; | 2625 | struct sk_buff *skb, *newskb; |
2626 | dma_addr_t newdma; | ||
2618 | dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr); | 2627 | dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr); |
2619 | 2628 | ||
2620 | if (vortex_debug > 4) | 2629 | if (vortex_debug > 4) |
@@ -2633,9 +2642,27 @@ boomerang_rx(struct net_device *dev) | |||
2633 | pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | 2642 | pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); |
2634 | vp->rx_copy++; | 2643 | vp->rx_copy++; |
2635 | } else { | 2644 | } else { |
2645 | /* Pre-allocate the replacement skb. If it or its | ||
2646 | * mapping fails then recycle the buffer thats already | ||
2647 | * in place | ||
2648 | */ | ||
2649 | newskb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ); | ||
2650 | if (!newskb) { | ||
2651 | dev->stats.rx_dropped++; | ||
2652 | goto clear_complete; | ||
2653 | } | ||
2654 | newdma = pci_map_single(VORTEX_PCI(vp), newskb->data, | ||
2655 | PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | ||
2656 | if (dma_mapping_error(&VORTEX_PCI(vp)->dev, newdma)) { | ||
2657 | dev->stats.rx_dropped++; | ||
2658 | consume_skb(newskb); | ||
2659 | goto clear_complete; | ||
2660 | } | ||
2661 | |||
2636 | /* Pass up the skbuff already on the Rx ring. */ | 2662 | /* Pass up the skbuff already on the Rx ring. */ |
2637 | skb = vp->rx_skbuff[entry]; | 2663 | skb = vp->rx_skbuff[entry]; |
2638 | vp->rx_skbuff[entry] = NULL; | 2664 | vp->rx_skbuff[entry] = newskb; |
2665 | vp->rx_ring[entry].addr = cpu_to_le32(newdma); | ||
2639 | skb_put(skb, pkt_len); | 2666 | skb_put(skb, pkt_len); |
2640 | pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | 2667 | pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); |
2641 | vp->rx_nocopy++; | 2668 | vp->rx_nocopy++; |
@@ -2653,55 +2680,15 @@ boomerang_rx(struct net_device *dev) | |||
2653 | netif_rx(skb); | 2680 | netif_rx(skb); |
2654 | dev->stats.rx_packets++; | 2681 | dev->stats.rx_packets++; |
2655 | } | 2682 | } |
2656 | entry = (++vp->cur_rx) % RX_RING_SIZE; | ||
2657 | } | ||
2658 | /* Refill the Rx ring buffers. */ | ||
2659 | for (; vp->cur_rx - vp->dirty_rx > 0; vp->dirty_rx++) { | ||
2660 | struct sk_buff *skb; | ||
2661 | entry = vp->dirty_rx % RX_RING_SIZE; | ||
2662 | if (vp->rx_skbuff[entry] == NULL) { | ||
2663 | skb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ); | ||
2664 | if (skb == NULL) { | ||
2665 | static unsigned long last_jif; | ||
2666 | if (time_after(jiffies, last_jif + 10 * HZ)) { | ||
2667 | pr_warn("%s: memory shortage\n", | ||
2668 | dev->name); | ||
2669 | last_jif = jiffies; | ||
2670 | } | ||
2671 | if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) | ||
2672 | mod_timer(&vp->rx_oom_timer, RUN_AT(HZ * 1)); | ||
2673 | break; /* Bad news! */ | ||
2674 | } | ||
2675 | 2683 | ||
2676 | vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); | 2684 | clear_complete: |
2677 | vp->rx_skbuff[entry] = skb; | ||
2678 | } | ||
2679 | vp->rx_ring[entry].status = 0; /* Clear complete bit. */ | 2685 | vp->rx_ring[entry].status = 0; /* Clear complete bit. */ |
2680 | iowrite16(UpUnstall, ioaddr + EL3_CMD); | 2686 | iowrite16(UpUnstall, ioaddr + EL3_CMD); |
2687 | entry = (++vp->cur_rx) % RX_RING_SIZE; | ||
2681 | } | 2688 | } |
2682 | return 0; | 2689 | return 0; |
2683 | } | 2690 | } |
2684 | 2691 | ||
2685 | /* | ||
2686 | * If we've hit a total OOM refilling the Rx ring we poll once a second | ||
2687 | * for some memory. Otherwise there is no way to restart the rx process. | ||
2688 | */ | ||
2689 | static void | ||
2690 | rx_oom_timer(struct timer_list *t) | ||
2691 | { | ||
2692 | struct vortex_private *vp = from_timer(vp, t, rx_oom_timer); | ||
2693 | struct net_device *dev = vp->mii.dev; | ||
2694 | |||
2695 | spin_lock_irq(&vp->lock); | ||
2696 | if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */ | ||
2697 | boomerang_rx(dev); | ||
2698 | if (vortex_debug > 1) { | ||
2699 | pr_debug("%s: rx_oom_timer %s\n", dev->name, | ||
2700 | ((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying"); | ||
2701 | } | ||
2702 | spin_unlock_irq(&vp->lock); | ||
2703 | } | ||
2704 | |||
2705 | static void | 2692 | static void |
2706 | vortex_down(struct net_device *dev, int final_down) | 2693 | vortex_down(struct net_device *dev, int final_down) |
2707 | { | 2694 | { |
@@ -2711,7 +2698,6 @@ vortex_down(struct net_device *dev, int final_down) | |||
2711 | netdev_reset_queue(dev); | 2698 | netdev_reset_queue(dev); |
2712 | netif_stop_queue(dev); | 2699 | netif_stop_queue(dev); |
2713 | 2700 | ||
2714 | del_timer_sync(&vp->rx_oom_timer); | ||
2715 | del_timer_sync(&vp->timer); | 2701 | del_timer_sync(&vp->timer); |
2716 | 2702 | ||
2717 | /* Turn off statistics ASAP. We update dev->stats below. */ | 2703 | /* Turn off statistics ASAP. We update dev->stats below. */ |
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 97c5a89a9cf7..fbe21a817bd8 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c | |||
@@ -75,6 +75,9 @@ static struct workqueue_struct *ena_wq; | |||
75 | MODULE_DEVICE_TABLE(pci, ena_pci_tbl); | 75 | MODULE_DEVICE_TABLE(pci, ena_pci_tbl); |
76 | 76 | ||
77 | static int ena_rss_init_default(struct ena_adapter *adapter); | 77 | static int ena_rss_init_default(struct ena_adapter *adapter); |
78 | static void check_for_admin_com_state(struct ena_adapter *adapter); | ||
79 | static void ena_destroy_device(struct ena_adapter *adapter); | ||
80 | static int ena_restore_device(struct ena_adapter *adapter); | ||
78 | 81 | ||
79 | static void ena_tx_timeout(struct net_device *dev) | 82 | static void ena_tx_timeout(struct net_device *dev) |
80 | { | 83 | { |
@@ -1565,7 +1568,7 @@ static int ena_rss_configure(struct ena_adapter *adapter) | |||
1565 | 1568 | ||
1566 | static int ena_up_complete(struct ena_adapter *adapter) | 1569 | static int ena_up_complete(struct ena_adapter *adapter) |
1567 | { | 1570 | { |
1568 | int rc, i; | 1571 | int rc; |
1569 | 1572 | ||
1570 | rc = ena_rss_configure(adapter); | 1573 | rc = ena_rss_configure(adapter); |
1571 | if (rc) | 1574 | if (rc) |
@@ -1584,17 +1587,6 @@ static int ena_up_complete(struct ena_adapter *adapter) | |||
1584 | 1587 | ||
1585 | ena_napi_enable_all(adapter); | 1588 | ena_napi_enable_all(adapter); |
1586 | 1589 | ||
1587 | /* Enable completion queues interrupt */ | ||
1588 | for (i = 0; i < adapter->num_queues; i++) | ||
1589 | ena_unmask_interrupt(&adapter->tx_ring[i], | ||
1590 | &adapter->rx_ring[i]); | ||
1591 | |||
1592 | /* schedule napi in case we had pending packets | ||
1593 | * from the last time we disable napi | ||
1594 | */ | ||
1595 | for (i = 0; i < adapter->num_queues; i++) | ||
1596 | napi_schedule(&adapter->ena_napi[i].napi); | ||
1597 | |||
1598 | return 0; | 1590 | return 0; |
1599 | } | 1591 | } |
1600 | 1592 | ||
@@ -1731,7 +1723,7 @@ create_err: | |||
1731 | 1723 | ||
1732 | static int ena_up(struct ena_adapter *adapter) | 1724 | static int ena_up(struct ena_adapter *adapter) |
1733 | { | 1725 | { |
1734 | int rc; | 1726 | int rc, i; |
1735 | 1727 | ||
1736 | netdev_dbg(adapter->netdev, "%s\n", __func__); | 1728 | netdev_dbg(adapter->netdev, "%s\n", __func__); |
1737 | 1729 | ||
@@ -1774,6 +1766,17 @@ static int ena_up(struct ena_adapter *adapter) | |||
1774 | 1766 | ||
1775 | set_bit(ENA_FLAG_DEV_UP, &adapter->flags); | 1767 | set_bit(ENA_FLAG_DEV_UP, &adapter->flags); |
1776 | 1768 | ||
1769 | /* Enable completion queues interrupt */ | ||
1770 | for (i = 0; i < adapter->num_queues; i++) | ||
1771 | ena_unmask_interrupt(&adapter->tx_ring[i], | ||
1772 | &adapter->rx_ring[i]); | ||
1773 | |||
1774 | /* schedule napi in case we had pending packets | ||
1775 | * from the last time we disable napi | ||
1776 | */ | ||
1777 | for (i = 0; i < adapter->num_queues; i++) | ||
1778 | napi_schedule(&adapter->ena_napi[i].napi); | ||
1779 | |||
1777 | return rc; | 1780 | return rc; |
1778 | 1781 | ||
1779 | err_up: | 1782 | err_up: |
@@ -1884,6 +1887,17 @@ static int ena_close(struct net_device *netdev) | |||
1884 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) | 1887 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) |
1885 | ena_down(adapter); | 1888 | ena_down(adapter); |
1886 | 1889 | ||
1890 | /* Check for device status and issue reset if needed*/ | ||
1891 | check_for_admin_com_state(adapter); | ||
1892 | if (unlikely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { | ||
1893 | netif_err(adapter, ifdown, adapter->netdev, | ||
1894 | "Destroy failure, restarting device\n"); | ||
1895 | ena_dump_stats_to_dmesg(adapter); | ||
1896 | /* rtnl lock already obtained in dev_ioctl() layer */ | ||
1897 | ena_destroy_device(adapter); | ||
1898 | ena_restore_device(adapter); | ||
1899 | } | ||
1900 | |||
1887 | return 0; | 1901 | return 0; |
1888 | } | 1902 | } |
1889 | 1903 | ||
@@ -2544,11 +2558,12 @@ static void ena_destroy_device(struct ena_adapter *adapter) | |||
2544 | 2558 | ||
2545 | ena_com_set_admin_running_state(ena_dev, false); | 2559 | ena_com_set_admin_running_state(ena_dev, false); |
2546 | 2560 | ||
2547 | ena_close(netdev); | 2561 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) |
2562 | ena_down(adapter); | ||
2548 | 2563 | ||
2549 | /* Before releasing the ENA resources, a device reset is required. | 2564 | /* Before releasing the ENA resources, a device reset is required. |
2550 | * (to prevent the device from accessing them). | 2565 | * (to prevent the device from accessing them). |
2551 | * In case the reset flag is set and the device is up, ena_close | 2566 | * In case the reset flag is set and the device is up, ena_down() |
2552 | * already perform the reset, so it can be skipped. | 2567 | * already perform the reset, so it can be skipped. |
2553 | */ | 2568 | */ |
2554 | if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) | 2569 | if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 5ee18660bc33..c9617675f934 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | |||
@@ -70,7 +70,7 @@ static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id) | |||
70 | netdev_err(bp->dev, "vf ndo called though sriov is disabled\n"); | 70 | netdev_err(bp->dev, "vf ndo called though sriov is disabled\n"); |
71 | return -EINVAL; | 71 | return -EINVAL; |
72 | } | 72 | } |
73 | if (vf_id >= bp->pf.max_vfs) { | 73 | if (vf_id >= bp->pf.active_vfs) { |
74 | netdev_err(bp->dev, "Invalid VF id %d\n", vf_id); | 74 | netdev_err(bp->dev, "Invalid VF id %d\n", vf_id); |
75 | return -EINVAL; | 75 | return -EINVAL; |
76 | } | 76 | } |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 3d201d7324bd..d8fee26cd45e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | |||
@@ -421,7 +421,7 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, | |||
421 | } | 421 | } |
422 | 422 | ||
423 | /* If all IP and L4 fields are wildcarded then this is an L2 flow */ | 423 | /* If all IP and L4 fields are wildcarded then this is an L2 flow */ |
424 | if (is_wildcard(&l3_mask, sizeof(l3_mask)) && | 424 | if (is_wildcard(l3_mask, sizeof(*l3_mask)) && |
425 | is_wildcard(&flow->l4_mask, sizeof(flow->l4_mask))) { | 425 | is_wildcard(&flow->l4_mask, sizeof(flow->l4_mask))) { |
426 | flow_flags |= CFA_FLOW_ALLOC_REQ_FLAGS_FLOWTYPE_L2; | 426 | flow_flags |= CFA_FLOW_ALLOC_REQ_FLAGS_FLOWTYPE_L2; |
427 | } else { | 427 | } else { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 6f9fa6e3c42a..d8424ed16c33 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -344,7 +344,6 @@ struct adapter_params { | |||
344 | 344 | ||
345 | unsigned int sf_size; /* serial flash size in bytes */ | 345 | unsigned int sf_size; /* serial flash size in bytes */ |
346 | unsigned int sf_nsec; /* # of flash sectors */ | 346 | unsigned int sf_nsec; /* # of flash sectors */ |
347 | unsigned int sf_fw_start; /* start of FW image in flash */ | ||
348 | 347 | ||
349 | unsigned int fw_vers; /* firmware version */ | 348 | unsigned int fw_vers; /* firmware version */ |
350 | unsigned int bs_vers; /* bootstrap version */ | 349 | unsigned int bs_vers; /* bootstrap version */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index f63210f15579..375ef86a84da 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -2844,8 +2844,6 @@ enum { | |||
2844 | SF_RD_DATA_FAST = 0xb, /* read flash */ | 2844 | SF_RD_DATA_FAST = 0xb, /* read flash */ |
2845 | SF_RD_ID = 0x9f, /* read ID */ | 2845 | SF_RD_ID = 0x9f, /* read ID */ |
2846 | SF_ERASE_SECTOR = 0xd8, /* erase sector */ | 2846 | SF_ERASE_SECTOR = 0xd8, /* erase sector */ |
2847 | |||
2848 | FW_MAX_SIZE = 16 * SF_SEC_SIZE, | ||
2849 | }; | 2847 | }; |
2850 | 2848 | ||
2851 | /** | 2849 | /** |
@@ -3558,8 +3556,9 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) | |||
3558 | const __be32 *p = (const __be32 *)fw_data; | 3556 | const __be32 *p = (const __be32 *)fw_data; |
3559 | const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data; | 3557 | const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data; |
3560 | unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec; | 3558 | unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec; |
3561 | unsigned int fw_img_start = adap->params.sf_fw_start; | 3559 | unsigned int fw_start_sec = FLASH_FW_START_SEC; |
3562 | unsigned int fw_start_sec = fw_img_start / sf_sec_size; | 3560 | unsigned int fw_size = FLASH_FW_MAX_SIZE; |
3561 | unsigned int fw_start = FLASH_FW_START; | ||
3563 | 3562 | ||
3564 | if (!size) { | 3563 | if (!size) { |
3565 | dev_err(adap->pdev_dev, "FW image has no data\n"); | 3564 | dev_err(adap->pdev_dev, "FW image has no data\n"); |
@@ -3575,9 +3574,9 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) | |||
3575 | "FW image size differs from size in FW header\n"); | 3574 | "FW image size differs from size in FW header\n"); |
3576 | return -EINVAL; | 3575 | return -EINVAL; |
3577 | } | 3576 | } |
3578 | if (size > FW_MAX_SIZE) { | 3577 | if (size > fw_size) { |
3579 | dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n", | 3578 | dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n", |
3580 | FW_MAX_SIZE); | 3579 | fw_size); |
3581 | return -EFBIG; | 3580 | return -EFBIG; |
3582 | } | 3581 | } |
3583 | if (!t4_fw_matches_chip(adap, hdr)) | 3582 | if (!t4_fw_matches_chip(adap, hdr)) |
@@ -3604,11 +3603,11 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) | |||
3604 | */ | 3603 | */ |
3605 | memcpy(first_page, fw_data, SF_PAGE_SIZE); | 3604 | memcpy(first_page, fw_data, SF_PAGE_SIZE); |
3606 | ((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff); | 3605 | ((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff); |
3607 | ret = t4_write_flash(adap, fw_img_start, SF_PAGE_SIZE, first_page); | 3606 | ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page); |
3608 | if (ret) | 3607 | if (ret) |
3609 | goto out; | 3608 | goto out; |
3610 | 3609 | ||
3611 | addr = fw_img_start; | 3610 | addr = fw_start; |
3612 | for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { | 3611 | for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { |
3613 | addr += SF_PAGE_SIZE; | 3612 | addr += SF_PAGE_SIZE; |
3614 | fw_data += SF_PAGE_SIZE; | 3613 | fw_data += SF_PAGE_SIZE; |
@@ -3618,7 +3617,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) | |||
3618 | } | 3617 | } |
3619 | 3618 | ||
3620 | ret = t4_write_flash(adap, | 3619 | ret = t4_write_flash(adap, |
3621 | fw_img_start + offsetof(struct fw_hdr, fw_ver), | 3620 | fw_start + offsetof(struct fw_hdr, fw_ver), |
3622 | sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver); | 3621 | sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver); |
3623 | out: | 3622 | out: |
3624 | if (ret) | 3623 | if (ret) |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 8184d2fca9be..a74300a4459c 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -3469,6 +3469,10 @@ fec_probe(struct platform_device *pdev) | |||
3469 | goto failed_regulator; | 3469 | goto failed_regulator; |
3470 | } | 3470 | } |
3471 | } else { | 3471 | } else { |
3472 | if (PTR_ERR(fep->reg_phy) == -EPROBE_DEFER) { | ||
3473 | ret = -EPROBE_DEFER; | ||
3474 | goto failed_regulator; | ||
3475 | } | ||
3472 | fep->reg_phy = NULL; | 3476 | fep->reg_phy = NULL; |
3473 | } | 3477 | } |
3474 | 3478 | ||
@@ -3552,8 +3556,9 @@ failed_clk_ipg: | |||
3552 | failed_clk: | 3556 | failed_clk: |
3553 | if (of_phy_is_fixed_link(np)) | 3557 | if (of_phy_is_fixed_link(np)) |
3554 | of_phy_deregister_fixed_link(np); | 3558 | of_phy_deregister_fixed_link(np); |
3555 | failed_phy: | ||
3556 | of_node_put(phy_node); | 3559 | of_node_put(phy_node); |
3560 | failed_phy: | ||
3561 | dev_id--; | ||
3557 | failed_ioremap: | 3562 | failed_ioremap: |
3558 | free_netdev(ndev); | 3563 | free_netdev(ndev); |
3559 | 3564 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 544114281ea7..9f8d4f8e57e3 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c | |||
@@ -319,11 +319,10 @@ static int ptp_gianfar_adjtime(struct ptp_clock_info *ptp, s64 delta) | |||
319 | now = tmr_cnt_read(etsects); | 319 | now = tmr_cnt_read(etsects); |
320 | now += delta; | 320 | now += delta; |
321 | tmr_cnt_write(etsects, now); | 321 | tmr_cnt_write(etsects, now); |
322 | set_fipers(etsects); | ||
322 | 323 | ||
323 | spin_unlock_irqrestore(&etsects->lock, flags); | 324 | spin_unlock_irqrestore(&etsects->lock, flags); |
324 | 325 | ||
325 | set_fipers(etsects); | ||
326 | |||
327 | return 0; | 326 | return 0; |
328 | } | 327 | } |
329 | 328 | ||
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index d7bdea79e9fa..8fd2458060a0 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h | |||
@@ -331,7 +331,8 @@ struct e1000_adapter { | |||
331 | enum e1000_state_t { | 331 | enum e1000_state_t { |
332 | __E1000_TESTING, | 332 | __E1000_TESTING, |
333 | __E1000_RESETTING, | 333 | __E1000_RESETTING, |
334 | __E1000_DOWN | 334 | __E1000_DOWN, |
335 | __E1000_DISABLED | ||
335 | }; | 336 | }; |
336 | 337 | ||
337 | #undef pr_fmt | 338 | #undef pr_fmt |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 1982f7917a8d..3dd4aeb2706d 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -945,7 +945,7 @@ static int e1000_init_hw_struct(struct e1000_adapter *adapter, | |||
945 | static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 945 | static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
946 | { | 946 | { |
947 | struct net_device *netdev; | 947 | struct net_device *netdev; |
948 | struct e1000_adapter *adapter; | 948 | struct e1000_adapter *adapter = NULL; |
949 | struct e1000_hw *hw; | 949 | struct e1000_hw *hw; |
950 | 950 | ||
951 | static int cards_found; | 951 | static int cards_found; |
@@ -955,6 +955,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
955 | u16 tmp = 0; | 955 | u16 tmp = 0; |
956 | u16 eeprom_apme_mask = E1000_EEPROM_APME; | 956 | u16 eeprom_apme_mask = E1000_EEPROM_APME; |
957 | int bars, need_ioport; | 957 | int bars, need_ioport; |
958 | bool disable_dev = false; | ||
958 | 959 | ||
959 | /* do not allocate ioport bars when not needed */ | 960 | /* do not allocate ioport bars when not needed */ |
960 | need_ioport = e1000_is_need_ioport(pdev); | 961 | need_ioport = e1000_is_need_ioport(pdev); |
@@ -1259,11 +1260,13 @@ err_mdio_ioremap: | |||
1259 | iounmap(hw->ce4100_gbe_mdio_base_virt); | 1260 | iounmap(hw->ce4100_gbe_mdio_base_virt); |
1260 | iounmap(hw->hw_addr); | 1261 | iounmap(hw->hw_addr); |
1261 | err_ioremap: | 1262 | err_ioremap: |
1263 | disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags); | ||
1262 | free_netdev(netdev); | 1264 | free_netdev(netdev); |
1263 | err_alloc_etherdev: | 1265 | err_alloc_etherdev: |
1264 | pci_release_selected_regions(pdev, bars); | 1266 | pci_release_selected_regions(pdev, bars); |
1265 | err_pci_reg: | 1267 | err_pci_reg: |
1266 | pci_disable_device(pdev); | 1268 | if (!adapter || disable_dev) |
1269 | pci_disable_device(pdev); | ||
1267 | return err; | 1270 | return err; |
1268 | } | 1271 | } |
1269 | 1272 | ||
@@ -1281,6 +1284,7 @@ static void e1000_remove(struct pci_dev *pdev) | |||
1281 | struct net_device *netdev = pci_get_drvdata(pdev); | 1284 | struct net_device *netdev = pci_get_drvdata(pdev); |
1282 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1285 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1283 | struct e1000_hw *hw = &adapter->hw; | 1286 | struct e1000_hw *hw = &adapter->hw; |
1287 | bool disable_dev; | ||
1284 | 1288 | ||
1285 | e1000_down_and_stop(adapter); | 1289 | e1000_down_and_stop(adapter); |
1286 | e1000_release_manageability(adapter); | 1290 | e1000_release_manageability(adapter); |
@@ -1299,9 +1303,11 @@ static void e1000_remove(struct pci_dev *pdev) | |||
1299 | iounmap(hw->flash_address); | 1303 | iounmap(hw->flash_address); |
1300 | pci_release_selected_regions(pdev, adapter->bars); | 1304 | pci_release_selected_regions(pdev, adapter->bars); |
1301 | 1305 | ||
1306 | disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags); | ||
1302 | free_netdev(netdev); | 1307 | free_netdev(netdev); |
1303 | 1308 | ||
1304 | pci_disable_device(pdev); | 1309 | if (disable_dev) |
1310 | pci_disable_device(pdev); | ||
1305 | } | 1311 | } |
1306 | 1312 | ||
1307 | /** | 1313 | /** |
@@ -5156,7 +5162,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
5156 | if (netif_running(netdev)) | 5162 | if (netif_running(netdev)) |
5157 | e1000_free_irq(adapter); | 5163 | e1000_free_irq(adapter); |
5158 | 5164 | ||
5159 | pci_disable_device(pdev); | 5165 | if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags)) |
5166 | pci_disable_device(pdev); | ||
5160 | 5167 | ||
5161 | return 0; | 5168 | return 0; |
5162 | } | 5169 | } |
@@ -5200,6 +5207,10 @@ static int e1000_resume(struct pci_dev *pdev) | |||
5200 | pr_err("Cannot enable PCI device from suspend\n"); | 5207 | pr_err("Cannot enable PCI device from suspend\n"); |
5201 | return err; | 5208 | return err; |
5202 | } | 5209 | } |
5210 | |||
5211 | /* flush memory to make sure state is correct */ | ||
5212 | smp_mb__before_atomic(); | ||
5213 | clear_bit(__E1000_DISABLED, &adapter->flags); | ||
5203 | pci_set_master(pdev); | 5214 | pci_set_master(pdev); |
5204 | 5215 | ||
5205 | pci_enable_wake(pdev, PCI_D3hot, 0); | 5216 | pci_enable_wake(pdev, PCI_D3hot, 0); |
@@ -5274,7 +5285,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, | |||
5274 | 5285 | ||
5275 | if (netif_running(netdev)) | 5286 | if (netif_running(netdev)) |
5276 | e1000_down(adapter); | 5287 | e1000_down(adapter); |
5277 | pci_disable_device(pdev); | 5288 | |
5289 | if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags)) | ||
5290 | pci_disable_device(pdev); | ||
5278 | 5291 | ||
5279 | /* Request a slot slot reset. */ | 5292 | /* Request a slot slot reset. */ |
5280 | return PCI_ERS_RESULT_NEED_RESET; | 5293 | return PCI_ERS_RESULT_NEED_RESET; |
@@ -5302,6 +5315,10 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) | |||
5302 | pr_err("Cannot re-enable PCI device after reset.\n"); | 5315 | pr_err("Cannot re-enable PCI device after reset.\n"); |
5303 | return PCI_ERS_RESULT_DISCONNECT; | 5316 | return PCI_ERS_RESULT_DISCONNECT; |
5304 | } | 5317 | } |
5318 | |||
5319 | /* flush memory to make sure state is correct */ | ||
5320 | smp_mb__before_atomic(); | ||
5321 | clear_bit(__E1000_DISABLED, &adapter->flags); | ||
5305 | pci_set_master(pdev); | 5322 | pci_set_master(pdev); |
5306 | 5323 | ||
5307 | pci_enable_wake(pdev, PCI_D3hot, 0); | 5324 | pci_enable_wake(pdev, PCI_D3hot, 0); |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index d6d4ed7acf03..31277d3bb7dc 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -1367,6 +1367,9 @@ out: | |||
1367 | * Checks to see of the link status of the hardware has changed. If a | 1367 | * Checks to see of the link status of the hardware has changed. If a |
1368 | * change in link status has been detected, then we read the PHY registers | 1368 | * change in link status has been detected, then we read the PHY registers |
1369 | * to get the current speed/duplex if link exists. | 1369 | * to get the current speed/duplex if link exists. |
1370 | * | ||
1371 | * Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link | ||
1372 | * up). | ||
1370 | **/ | 1373 | **/ |
1371 | static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | 1374 | static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) |
1372 | { | 1375 | { |
@@ -1382,7 +1385,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
1382 | * Change or Rx Sequence Error interrupt. | 1385 | * Change or Rx Sequence Error interrupt. |
1383 | */ | 1386 | */ |
1384 | if (!mac->get_link_status) | 1387 | if (!mac->get_link_status) |
1385 | return 0; | 1388 | return 1; |
1386 | 1389 | ||
1387 | /* First we want to see if the MII Status Register reports | 1390 | /* First we want to see if the MII Status Register reports |
1388 | * link. If so, then we want to get the current speed/duplex | 1391 | * link. If so, then we want to get the current speed/duplex |
@@ -1613,10 +1616,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
1613 | * different link partner. | 1616 | * different link partner. |
1614 | */ | 1617 | */ |
1615 | ret_val = e1000e_config_fc_after_link_up(hw); | 1618 | ret_val = e1000e_config_fc_after_link_up(hw); |
1616 | if (ret_val) | 1619 | if (ret_val) { |
1617 | e_dbg("Error configuring flow control\n"); | 1620 | e_dbg("Error configuring flow control\n"); |
1621 | return ret_val; | ||
1622 | } | ||
1618 | 1623 | ||
1619 | return ret_val; | 1624 | return 1; |
1620 | } | 1625 | } |
1621 | 1626 | ||
1622 | static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | 1627 | static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 321d8be80871..42dcaefc4c19 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -1573,11 +1573,18 @@ static int i40e_set_mac(struct net_device *netdev, void *p) | |||
1573 | else | 1573 | else |
1574 | netdev_info(netdev, "set new mac address %pM\n", addr->sa_data); | 1574 | netdev_info(netdev, "set new mac address %pM\n", addr->sa_data); |
1575 | 1575 | ||
1576 | /* Copy the address first, so that we avoid a possible race with | ||
1577 | * .set_rx_mode(). If we copy after changing the address in the filter | ||
1578 | * list, we might open ourselves to a narrow race window where | ||
1579 | * .set_rx_mode could delete our dev_addr filter and prevent traffic | ||
1580 | * from passing. | ||
1581 | */ | ||
1582 | ether_addr_copy(netdev->dev_addr, addr->sa_data); | ||
1583 | |||
1576 | spin_lock_bh(&vsi->mac_filter_hash_lock); | 1584 | spin_lock_bh(&vsi->mac_filter_hash_lock); |
1577 | i40e_del_mac_filter(vsi, netdev->dev_addr); | 1585 | i40e_del_mac_filter(vsi, netdev->dev_addr); |
1578 | i40e_add_mac_filter(vsi, addr->sa_data); | 1586 | i40e_add_mac_filter(vsi, addr->sa_data); |
1579 | spin_unlock_bh(&vsi->mac_filter_hash_lock); | 1587 | spin_unlock_bh(&vsi->mac_filter_hash_lock); |
1580 | ether_addr_copy(netdev->dev_addr, addr->sa_data); | ||
1581 | if (vsi->type == I40E_VSI_MAIN) { | 1588 | if (vsi->type == I40E_VSI_MAIN) { |
1582 | i40e_status ret; | 1589 | i40e_status ret; |
1583 | 1590 | ||
@@ -1923,6 +1930,14 @@ static int i40e_addr_unsync(struct net_device *netdev, const u8 *addr) | |||
1923 | struct i40e_netdev_priv *np = netdev_priv(netdev); | 1930 | struct i40e_netdev_priv *np = netdev_priv(netdev); |
1924 | struct i40e_vsi *vsi = np->vsi; | 1931 | struct i40e_vsi *vsi = np->vsi; |
1925 | 1932 | ||
1933 | /* Under some circumstances, we might receive a request to delete | ||
1934 | * our own device address from our uc list. Because we store the | ||
1935 | * device address in the VSI's MAC/VLAN filter list, we need to ignore | ||
1936 | * such requests and not delete our device address from this list. | ||
1937 | */ | ||
1938 | if (ether_addr_equal(addr, netdev->dev_addr)) | ||
1939 | return 0; | ||
1940 | |||
1926 | i40e_del_mac_filter(vsi, addr); | 1941 | i40e_del_mac_filter(vsi, addr); |
1927 | 1942 | ||
1928 | return 0; | 1943 | return 0; |
@@ -6038,8 +6053,8 @@ static int i40e_validate_and_set_switch_mode(struct i40e_vsi *vsi) | |||
6038 | /* Set Bit 7 to be valid */ | 6053 | /* Set Bit 7 to be valid */ |
6039 | mode = I40E_AQ_SET_SWITCH_BIT7_VALID; | 6054 | mode = I40E_AQ_SET_SWITCH_BIT7_VALID; |
6040 | 6055 | ||
6041 | /* Set L4type to both TCP and UDP support */ | 6056 | /* Set L4type for TCP support */ |
6042 | mode |= I40E_AQ_SET_SWITCH_L4_TYPE_BOTH; | 6057 | mode |= I40E_AQ_SET_SWITCH_L4_TYPE_TCP; |
6043 | 6058 | ||
6044 | /* Set cloud filter mode */ | 6059 | /* Set cloud filter mode */ |
6045 | mode |= I40E_AQ_SET_SWITCH_MODE_NON_TUNNEL; | 6060 | mode |= I40E_AQ_SET_SWITCH_MODE_NON_TUNNEL; |
@@ -6969,18 +6984,18 @@ static int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi, | |||
6969 | is_valid_ether_addr(filter->src_mac)) || | 6984 | is_valid_ether_addr(filter->src_mac)) || |
6970 | (is_multicast_ether_addr(filter->dst_mac) && | 6985 | (is_multicast_ether_addr(filter->dst_mac) && |
6971 | is_multicast_ether_addr(filter->src_mac))) | 6986 | is_multicast_ether_addr(filter->src_mac))) |
6972 | return -EINVAL; | 6987 | return -EOPNOTSUPP; |
6973 | 6988 | ||
6974 | /* Make sure port is specified, otherwise bail out, for channel | 6989 | /* Big buffer cloud filter needs 'L4 port' to be non-zero. Also, UDP |
6975 | * specific cloud filter needs 'L4 port' to be non-zero | 6990 | * ports are not supported via big buffer now. |
6976 | */ | 6991 | */ |
6977 | if (!filter->dst_port) | 6992 | if (!filter->dst_port || filter->ip_proto == IPPROTO_UDP) |
6978 | return -EINVAL; | 6993 | return -EOPNOTSUPP; |
6979 | 6994 | ||
6980 | /* adding filter using src_port/src_ip is not supported at this stage */ | 6995 | /* adding filter using src_port/src_ip is not supported at this stage */ |
6981 | if (filter->src_port || filter->src_ipv4 || | 6996 | if (filter->src_port || filter->src_ipv4 || |
6982 | !ipv6_addr_any(&filter->ip.v6.src_ip6)) | 6997 | !ipv6_addr_any(&filter->ip.v6.src_ip6)) |
6983 | return -EINVAL; | 6998 | return -EOPNOTSUPP; |
6984 | 6999 | ||
6985 | /* copy element needed to add cloud filter from filter */ | 7000 | /* copy element needed to add cloud filter from filter */ |
6986 | i40e_set_cld_element(filter, &cld_filter.element); | 7001 | i40e_set_cld_element(filter, &cld_filter.element); |
@@ -6991,7 +7006,7 @@ static int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi, | |||
6991 | is_multicast_ether_addr(filter->src_mac)) { | 7006 | is_multicast_ether_addr(filter->src_mac)) { |
6992 | /* MAC + IP : unsupported mode */ | 7007 | /* MAC + IP : unsupported mode */ |
6993 | if (filter->dst_ipv4) | 7008 | if (filter->dst_ipv4) |
6994 | return -EINVAL; | 7009 | return -EOPNOTSUPP; |
6995 | 7010 | ||
6996 | /* since we validated that L4 port must be valid before | 7011 | /* since we validated that L4 port must be valid before |
6997 | * we get here, start with respective "flags" value | 7012 | * we get here, start with respective "flags" value |
@@ -7356,7 +7371,7 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi, | |||
7356 | 7371 | ||
7357 | if (tc < 0) { | 7372 | if (tc < 0) { |
7358 | dev_err(&vsi->back->pdev->dev, "Invalid traffic class\n"); | 7373 | dev_err(&vsi->back->pdev->dev, "Invalid traffic class\n"); |
7359 | return -EINVAL; | 7374 | return -EOPNOTSUPP; |
7360 | } | 7375 | } |
7361 | 7376 | ||
7362 | if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || | 7377 | if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 4566d66ffc7c..5bc2748ac468 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -3047,10 +3047,30 @@ bool __i40e_chk_linearize(struct sk_buff *skb) | |||
3047 | /* Walk through fragments adding latest fragment, testing it, and | 3047 | /* Walk through fragments adding latest fragment, testing it, and |
3048 | * then removing stale fragments from the sum. | 3048 | * then removing stale fragments from the sum. |
3049 | */ | 3049 | */ |
3050 | stale = &skb_shinfo(skb)->frags[0]; | 3050 | for (stale = &skb_shinfo(skb)->frags[0];; stale++) { |
3051 | for (;;) { | 3051 | int stale_size = skb_frag_size(stale); |
3052 | |||
3052 | sum += skb_frag_size(frag++); | 3053 | sum += skb_frag_size(frag++); |
3053 | 3054 | ||
3055 | /* The stale fragment may present us with a smaller | ||
3056 | * descriptor than the actual fragment size. To account | ||
3057 | * for that we need to remove all the data on the front and | ||
3058 | * figure out what the remainder would be in the last | ||
3059 | * descriptor associated with the fragment. | ||
3060 | */ | ||
3061 | if (stale_size > I40E_MAX_DATA_PER_TXD) { | ||
3062 | int align_pad = -(stale->page_offset) & | ||
3063 | (I40E_MAX_READ_REQ_SIZE - 1); | ||
3064 | |||
3065 | sum -= align_pad; | ||
3066 | stale_size -= align_pad; | ||
3067 | |||
3068 | do { | ||
3069 | sum -= I40E_MAX_DATA_PER_TXD_ALIGNED; | ||
3070 | stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED; | ||
3071 | } while (stale_size > I40E_MAX_DATA_PER_TXD); | ||
3072 | } | ||
3073 | |||
3054 | /* if sum is negative we failed to make sufficient progress */ | 3074 | /* if sum is negative we failed to make sufficient progress */ |
3055 | if (sum < 0) | 3075 | if (sum < 0) |
3056 | return true; | 3076 | return true; |
@@ -3058,7 +3078,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb) | |||
3058 | if (!nr_frags--) | 3078 | if (!nr_frags--) |
3059 | break; | 3079 | break; |
3060 | 3080 | ||
3061 | sum -= skb_frag_size(stale++); | 3081 | sum -= stale_size; |
3062 | } | 3082 | } |
3063 | 3083 | ||
3064 | return false; | 3084 | return false; |
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 50864f99446d..1ba29bb85b67 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c | |||
@@ -2012,10 +2012,30 @@ bool __i40evf_chk_linearize(struct sk_buff *skb) | |||
2012 | /* Walk through fragments adding latest fragment, testing it, and | 2012 | /* Walk through fragments adding latest fragment, testing it, and |
2013 | * then removing stale fragments from the sum. | 2013 | * then removing stale fragments from the sum. |
2014 | */ | 2014 | */ |
2015 | stale = &skb_shinfo(skb)->frags[0]; | 2015 | for (stale = &skb_shinfo(skb)->frags[0];; stale++) { |
2016 | for (;;) { | 2016 | int stale_size = skb_frag_size(stale); |
2017 | |||
2017 | sum += skb_frag_size(frag++); | 2018 | sum += skb_frag_size(frag++); |
2018 | 2019 | ||
2020 | /* The stale fragment may present us with a smaller | ||
2021 | * descriptor than the actual fragment size. To account | ||
2022 | * for that we need to remove all the data on the front and | ||
2023 | * figure out what the remainder would be in the last | ||
2024 | * descriptor associated with the fragment. | ||
2025 | */ | ||
2026 | if (stale_size > I40E_MAX_DATA_PER_TXD) { | ||
2027 | int align_pad = -(stale->page_offset) & | ||
2028 | (I40E_MAX_READ_REQ_SIZE - 1); | ||
2029 | |||
2030 | sum -= align_pad; | ||
2031 | stale_size -= align_pad; | ||
2032 | |||
2033 | do { | ||
2034 | sum -= I40E_MAX_DATA_PER_TXD_ALIGNED; | ||
2035 | stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED; | ||
2036 | } while (stale_size > I40E_MAX_DATA_PER_TXD); | ||
2037 | } | ||
2038 | |||
2019 | /* if sum is negative we failed to make sufficient progress */ | 2039 | /* if sum is negative we failed to make sufficient progress */ |
2020 | if (sum < 0) | 2040 | if (sum < 0) |
2021 | return true; | 2041 | return true; |
@@ -2023,7 +2043,7 @@ bool __i40evf_chk_linearize(struct sk_buff *skb) | |||
2023 | if (!nr_frags--) | 2043 | if (!nr_frags--) |
2024 | break; | 2044 | break; |
2025 | 2045 | ||
2026 | sum -= skb_frag_size(stale++); | 2046 | sum -= stale_size; |
2027 | } | 2047 | } |
2028 | 2048 | ||
2029 | return false; | 2049 | return false; |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 23f7d828cf67..6ef20e5cc77d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c | |||
@@ -1643,7 +1643,12 @@ static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, | |||
1643 | return 0; | 1643 | return 0; |
1644 | } | 1644 | } |
1645 | 1645 | ||
1646 | wmb(); /* reset needs to be written before we read control register */ | 1646 | /* Reset needs to be written before we read control register, and |
1647 | * we must wait for the HW to become responsive once again | ||
1648 | */ | ||
1649 | wmb(); | ||
1650 | msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS); | ||
1651 | |||
1647 | end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); | 1652 | end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); |
1648 | do { | 1653 | do { |
1649 | u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY); | 1654 | u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY); |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h index a6441208e9d9..fb082ad21b00 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h +++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | |||
@@ -59,6 +59,7 @@ | |||
59 | #define MLXSW_PCI_SW_RESET 0xF0010 | 59 | #define MLXSW_PCI_SW_RESET 0xF0010 |
60 | #define MLXSW_PCI_SW_RESET_RST_BIT BIT(0) | 60 | #define MLXSW_PCI_SW_RESET_RST_BIT BIT(0) |
61 | #define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 5000 | 61 | #define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 5000 |
62 | #define MLXSW_PCI_SW_RESET_WAIT_MSECS 100 | ||
62 | #define MLXSW_PCI_FW_READY 0xA1844 | 63 | #define MLXSW_PCI_FW_READY 0xA1844 |
63 | #define MLXSW_PCI_FW_READY_MASK 0xFFFF | 64 | #define MLXSW_PCI_FW_READY_MASK 0xFFFF |
64 | #define MLXSW_PCI_FW_READY_MAGIC 0x5E | 65 | #define MLXSW_PCI_FW_READY_MAGIC 0x5E |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 9bd8d28de152..c3837ca7a705 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
@@ -4376,7 +4376,10 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev, | |||
4376 | } | 4376 | } |
4377 | if (!info->linking) | 4377 | if (!info->linking) |
4378 | break; | 4378 | break; |
4379 | if (netdev_has_any_upper_dev(upper_dev)) { | 4379 | if (netdev_has_any_upper_dev(upper_dev) && |
4380 | (!netif_is_bridge_master(upper_dev) || | ||
4381 | !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, | ||
4382 | upper_dev))) { | ||
4380 | NL_SET_ERR_MSG(extack, | 4383 | NL_SET_ERR_MSG(extack, |
4381 | "spectrum: Enslaving a port to a device that already has an upper device is not supported"); | 4384 | "spectrum: Enslaving a port to a device that already has an upper device is not supported"); |
4382 | return -EINVAL; | 4385 | return -EINVAL; |
@@ -4504,6 +4507,7 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev, | |||
4504 | u16 vid) | 4507 | u16 vid) |
4505 | { | 4508 | { |
4506 | struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); | 4509 | struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); |
4510 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; | ||
4507 | struct netdev_notifier_changeupper_info *info = ptr; | 4511 | struct netdev_notifier_changeupper_info *info = ptr; |
4508 | struct netlink_ext_ack *extack; | 4512 | struct netlink_ext_ack *extack; |
4509 | struct net_device *upper_dev; | 4513 | struct net_device *upper_dev; |
@@ -4520,7 +4524,10 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev, | |||
4520 | } | 4524 | } |
4521 | if (!info->linking) | 4525 | if (!info->linking) |
4522 | break; | 4526 | break; |
4523 | if (netdev_has_any_upper_dev(upper_dev)) { | 4527 | if (netdev_has_any_upper_dev(upper_dev) && |
4528 | (!netif_is_bridge_master(upper_dev) || | ||
4529 | !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, | ||
4530 | upper_dev))) { | ||
4524 | NL_SET_ERR_MSG(extack, "spectrum: Enslaving a port to a device that already has an upper device is not supported"); | 4531 | NL_SET_ERR_MSG(extack, "spectrum: Enslaving a port to a device that already has an upper device is not supported"); |
4525 | return -EINVAL; | 4532 | return -EINVAL; |
4526 | } | 4533 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 432ab9b12b7f..05ce1befd9b3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h | |||
@@ -365,6 +365,8 @@ int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port, | |||
365 | void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port, | 365 | void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port, |
366 | struct net_device *brport_dev, | 366 | struct net_device *brport_dev, |
367 | struct net_device *br_dev); | 367 | struct net_device *br_dev); |
368 | bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp, | ||
369 | const struct net_device *br_dev); | ||
368 | 370 | ||
369 | /* spectrum.c */ | 371 | /* spectrum.c */ |
370 | int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port, | 372 | int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port, |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c index c33beac5def0..b5397da94d7f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c | |||
@@ -46,7 +46,8 @@ mlxsw_sp_tclass_congestion_enable(struct mlxsw_sp_port *mlxsw_sp_port, | |||
46 | int tclass_num, u32 min, u32 max, | 46 | int tclass_num, u32 min, u32 max, |
47 | u32 probability, bool is_ecn) | 47 | u32 probability, bool is_ecn) |
48 | { | 48 | { |
49 | char cwtp_cmd[max_t(u8, MLXSW_REG_CWTP_LEN, MLXSW_REG_CWTPM_LEN)]; | 49 | char cwtpm_cmd[MLXSW_REG_CWTPM_LEN]; |
50 | char cwtp_cmd[MLXSW_REG_CWTP_LEN]; | ||
50 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; | 51 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
51 | int err; | 52 | int err; |
52 | 53 | ||
@@ -60,10 +61,10 @@ mlxsw_sp_tclass_congestion_enable(struct mlxsw_sp_port *mlxsw_sp_port, | |||
60 | if (err) | 61 | if (err) |
61 | return err; | 62 | return err; |
62 | 63 | ||
63 | mlxsw_reg_cwtpm_pack(cwtp_cmd, mlxsw_sp_port->local_port, tclass_num, | 64 | mlxsw_reg_cwtpm_pack(cwtpm_cmd, mlxsw_sp_port->local_port, tclass_num, |
64 | MLXSW_REG_CWTP_DEFAULT_PROFILE, true, is_ecn); | 65 | MLXSW_REG_CWTP_DEFAULT_PROFILE, true, is_ecn); |
65 | 66 | ||
66 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(cwtpm), cwtp_cmd); | 67 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(cwtpm), cwtpm_cmd); |
67 | } | 68 | } |
68 | 69 | ||
69 | static int | 70 | static int |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index be657b8533f0..434b3922b34f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
@@ -3228,7 +3228,7 @@ static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh, | |||
3228 | { | 3228 | { |
3229 | if (!removing) | 3229 | if (!removing) |
3230 | nh->should_offload = 1; | 3230 | nh->should_offload = 1; |
3231 | else if (nh->offloaded) | 3231 | else |
3232 | nh->should_offload = 0; | 3232 | nh->should_offload = 0; |
3233 | nh->update = 1; | 3233 | nh->update = 1; |
3234 | } | 3234 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index 7b8548e25ae7..593ad31be749 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | |||
@@ -152,6 +152,12 @@ mlxsw_sp_bridge_device_find(const struct mlxsw_sp_bridge *bridge, | |||
152 | return NULL; | 152 | return NULL; |
153 | } | 153 | } |
154 | 154 | ||
155 | bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp, | ||
156 | const struct net_device *br_dev) | ||
157 | { | ||
158 | return !!mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev); | ||
159 | } | ||
160 | |||
155 | static struct mlxsw_sp_bridge_device * | 161 | static struct mlxsw_sp_bridge_device * |
156 | mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge, | 162 | mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge, |
157 | struct net_device *br_dev) | 163 | struct net_device *br_dev) |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 1a603fdd9e80..99b0487b6d82 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | |||
@@ -568,6 +568,7 @@ nfp_net_aux_irq_request(struct nfp_net *nn, u32 ctrl_offset, | |||
568 | return err; | 568 | return err; |
569 | } | 569 | } |
570 | nn_writeb(nn, ctrl_offset, entry->entry); | 570 | nn_writeb(nn, ctrl_offset, entry->entry); |
571 | nfp_net_irq_unmask(nn, entry->entry); | ||
571 | 572 | ||
572 | return 0; | 573 | return 0; |
573 | } | 574 | } |
@@ -582,6 +583,7 @@ static void nfp_net_aux_irq_free(struct nfp_net *nn, u32 ctrl_offset, | |||
582 | unsigned int vector_idx) | 583 | unsigned int vector_idx) |
583 | { | 584 | { |
584 | nn_writeb(nn, ctrl_offset, 0xff); | 585 | nn_writeb(nn, ctrl_offset, 0xff); |
586 | nn_pci_flush(nn); | ||
585 | free_irq(nn->irq_entries[vector_idx].vector, nn); | 587 | free_irq(nn->irq_entries[vector_idx].vector, nn); |
586 | } | 588 | } |
587 | 589 | ||
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 75323000c364..b9e2846589f8 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -147,7 +147,7 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
147 | [FWNLCR0] = 0x0090, | 147 | [FWNLCR0] = 0x0090, |
148 | [FWALCR0] = 0x0094, | 148 | [FWALCR0] = 0x0094, |
149 | [TXNLCR1] = 0x00a0, | 149 | [TXNLCR1] = 0x00a0, |
150 | [TXALCR1] = 0x00a0, | 150 | [TXALCR1] = 0x00a4, |
151 | [RXNLCR1] = 0x00a8, | 151 | [RXNLCR1] = 0x00a8, |
152 | [RXALCR1] = 0x00ac, | 152 | [RXALCR1] = 0x00ac, |
153 | [FWNLCR1] = 0x00b0, | 153 | [FWNLCR1] = 0x00b0, |
@@ -399,7 +399,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
399 | [FWNLCR0] = 0x0090, | 399 | [FWNLCR0] = 0x0090, |
400 | [FWALCR0] = 0x0094, | 400 | [FWALCR0] = 0x0094, |
401 | [TXNLCR1] = 0x00a0, | 401 | [TXNLCR1] = 0x00a0, |
402 | [TXALCR1] = 0x00a0, | 402 | [TXALCR1] = 0x00a4, |
403 | [RXNLCR1] = 0x00a8, | 403 | [RXNLCR1] = 0x00a8, |
404 | [RXALCR1] = 0x00ac, | 404 | [RXALCR1] = 0x00ac, |
405 | [FWNLCR1] = 0x00b0, | 405 | [FWNLCR1] = 0x00b0, |
@@ -3225,18 +3225,37 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
3225 | /* ioremap the TSU registers */ | 3225 | /* ioremap the TSU registers */ |
3226 | if (mdp->cd->tsu) { | 3226 | if (mdp->cd->tsu) { |
3227 | struct resource *rtsu; | 3227 | struct resource *rtsu; |
3228 | |||
3228 | rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 3229 | rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
3229 | mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu); | 3230 | if (!rtsu) { |
3230 | if (IS_ERR(mdp->tsu_addr)) { | 3231 | dev_err(&pdev->dev, "no TSU resource\n"); |
3231 | ret = PTR_ERR(mdp->tsu_addr); | 3232 | ret = -ENODEV; |
3233 | goto out_release; | ||
3234 | } | ||
3235 | /* We can only request the TSU region for the first port | ||
3236 | * of the two sharing this TSU for the probe to succeed... | ||
3237 | */ | ||
3238 | if (devno % 2 == 0 && | ||
3239 | !devm_request_mem_region(&pdev->dev, rtsu->start, | ||
3240 | resource_size(rtsu), | ||
3241 | dev_name(&pdev->dev))) { | ||
3242 | dev_err(&pdev->dev, "can't request TSU resource.\n"); | ||
3243 | ret = -EBUSY; | ||
3244 | goto out_release; | ||
3245 | } | ||
3246 | mdp->tsu_addr = devm_ioremap(&pdev->dev, rtsu->start, | ||
3247 | resource_size(rtsu)); | ||
3248 | if (!mdp->tsu_addr) { | ||
3249 | dev_err(&pdev->dev, "TSU region ioremap() failed.\n"); | ||
3250 | ret = -ENOMEM; | ||
3232 | goto out_release; | 3251 | goto out_release; |
3233 | } | 3252 | } |
3234 | mdp->port = devno % 2; | 3253 | mdp->port = devno % 2; |
3235 | ndev->features = NETIF_F_HW_VLAN_CTAG_FILTER; | 3254 | ndev->features = NETIF_F_HW_VLAN_CTAG_FILTER; |
3236 | } | 3255 | } |
3237 | 3256 | ||
3238 | /* initialize first or needed device */ | 3257 | /* Need to init only the first port of the two sharing a TSU */ |
3239 | if (!devno || pd->needs_init) { | 3258 | if (devno % 2 == 0) { |
3240 | if (mdp->cd->chip_reset) | 3259 | if (mdp->cd->chip_reset) |
3241 | mdp->cd->chip_reset(ndev); | 3260 | mdp->cd->chip_reset(ndev); |
3242 | 3261 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 337d53d12e94..c0af0bc4e714 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -364,9 +364,15 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t) | |||
364 | bool stmmac_eee_init(struct stmmac_priv *priv) | 364 | bool stmmac_eee_init(struct stmmac_priv *priv) |
365 | { | 365 | { |
366 | struct net_device *ndev = priv->dev; | 366 | struct net_device *ndev = priv->dev; |
367 | int interface = priv->plat->interface; | ||
367 | unsigned long flags; | 368 | unsigned long flags; |
368 | bool ret = false; | 369 | bool ret = false; |
369 | 370 | ||
371 | if ((interface != PHY_INTERFACE_MODE_MII) && | ||
372 | (interface != PHY_INTERFACE_MODE_GMII) && | ||
373 | !phy_interface_mode_is_rgmii(interface)) | ||
374 | goto out; | ||
375 | |||
370 | /* Using PCS we cannot dial with the phy registers at this stage | 376 | /* Using PCS we cannot dial with the phy registers at this stage |
371 | * so we do not support extra feature like EEE. | 377 | * so we do not support extra feature like EEE. |
372 | */ | 378 | */ |
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index b718a02a6bb6..0a48b3073d3d 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c | |||
@@ -825,6 +825,13 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
825 | if (IS_ERR(rt)) | 825 | if (IS_ERR(rt)) |
826 | return PTR_ERR(rt); | 826 | return PTR_ERR(rt); |
827 | 827 | ||
828 | if (skb_dst(skb)) { | ||
829 | int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) - | ||
830 | GENEVE_BASE_HLEN - info->options_len - 14; | ||
831 | |||
832 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
833 | } | ||
834 | |||
828 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); | 835 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); |
829 | if (geneve->collect_md) { | 836 | if (geneve->collect_md) { |
830 | tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); | 837 | tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); |
@@ -864,6 +871,13 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
864 | if (IS_ERR(dst)) | 871 | if (IS_ERR(dst)) |
865 | return PTR_ERR(dst); | 872 | return PTR_ERR(dst); |
866 | 873 | ||
874 | if (skb_dst(skb)) { | ||
875 | int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) - | ||
876 | GENEVE_BASE_HLEN - info->options_len - 14; | ||
877 | |||
878 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
879 | } | ||
880 | |||
867 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); | 881 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); |
868 | if (geneve->collect_md) { | 882 | if (geneve->collect_md) { |
869 | prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); | 883 | prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index a178c5efd33e..a0f2be81d52e 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -1444,9 +1444,14 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, | |||
1444 | return 0; | 1444 | return 0; |
1445 | 1445 | ||
1446 | unregister_netdev: | 1446 | unregister_netdev: |
1447 | /* macvlan_uninit would free the macvlan port */ | ||
1447 | unregister_netdevice(dev); | 1448 | unregister_netdevice(dev); |
1449 | return err; | ||
1448 | destroy_macvlan_port: | 1450 | destroy_macvlan_port: |
1449 | if (create) | 1451 | /* the macvlan port may be freed by macvlan_uninit when fail to register. |
1452 | * so we destroy the macvlan port only when it's valid. | ||
1453 | */ | ||
1454 | if (create && macvlan_port_get_rtnl(dev)) | ||
1450 | macvlan_port_destroy(port->dev); | 1455 | macvlan_port_destroy(port->dev); |
1451 | return err; | 1456 | return err; |
1452 | } | 1457 | } |
diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index 135296508a7e..6425ce04d3f9 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c | |||
@@ -118,8 +118,10 @@ static int sun4i_mdio_probe(struct platform_device *pdev) | |||
118 | 118 | ||
119 | data->regulator = devm_regulator_get(&pdev->dev, "phy"); | 119 | data->regulator = devm_regulator_get(&pdev->dev, "phy"); |
120 | if (IS_ERR(data->regulator)) { | 120 | if (IS_ERR(data->regulator)) { |
121 | if (PTR_ERR(data->regulator) == -EPROBE_DEFER) | 121 | if (PTR_ERR(data->regulator) == -EPROBE_DEFER) { |
122 | return -EPROBE_DEFER; | 122 | ret = -EPROBE_DEFER; |
123 | goto err_out_free_mdiobus; | ||
124 | } | ||
123 | 125 | ||
124 | dev_info(&pdev->dev, "no regulator found\n"); | 126 | dev_info(&pdev->dev, "no regulator found\n"); |
125 | data->regulator = NULL; | 127 | data->regulator = NULL; |
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 827f3f92560e..249ce5cbea22 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c | |||
@@ -1296,6 +1296,7 @@ int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) | |||
1296 | switch (cmd) { | 1296 | switch (cmd) { |
1297 | case SIOCGMIIPHY: | 1297 | case SIOCGMIIPHY: |
1298 | mii->phy_id = pl->phydev->mdio.addr; | 1298 | mii->phy_id = pl->phydev->mdio.addr; |
1299 | /* fall through */ | ||
1299 | 1300 | ||
1300 | case SIOCGMIIREG: | 1301 | case SIOCGMIIREG: |
1301 | ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); | 1302 | ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); |
@@ -1318,6 +1319,7 @@ int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) | |||
1318 | switch (cmd) { | 1319 | switch (cmd) { |
1319 | case SIOCGMIIPHY: | 1320 | case SIOCGMIIPHY: |
1320 | mii->phy_id = 0; | 1321 | mii->phy_id = 0; |
1322 | /* fall through */ | ||
1321 | 1323 | ||
1322 | case SIOCGMIIREG: | 1324 | case SIOCGMIIREG: |
1323 | ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); | 1325 | ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); |
@@ -1429,9 +1431,8 @@ static void phylink_sfp_link_down(void *upstream) | |||
1429 | WARN_ON(!lockdep_rtnl_is_held()); | 1431 | WARN_ON(!lockdep_rtnl_is_held()); |
1430 | 1432 | ||
1431 | set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); | 1433 | set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); |
1434 | queue_work(system_power_efficient_wq, &pl->resolve); | ||
1432 | flush_work(&pl->resolve); | 1435 | flush_work(&pl->resolve); |
1433 | |||
1434 | netif_carrier_off(pl->netdev); | ||
1435 | } | 1436 | } |
1436 | 1437 | ||
1437 | static void phylink_sfp_link_up(void *upstream) | 1438 | static void phylink_sfp_link_up(void *upstream) |
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 8a1b1f4c1b7c..ab64a142b832 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c | |||
@@ -356,7 +356,8 @@ EXPORT_SYMBOL_GPL(sfp_register_upstream); | |||
356 | void sfp_unregister_upstream(struct sfp_bus *bus) | 356 | void sfp_unregister_upstream(struct sfp_bus *bus) |
357 | { | 357 | { |
358 | rtnl_lock(); | 358 | rtnl_lock(); |
359 | sfp_unregister_bus(bus); | 359 | if (bus->sfp) |
360 | sfp_unregister_bus(bus); | ||
360 | bus->upstream = NULL; | 361 | bus->upstream = NULL; |
361 | bus->netdev = NULL; | 362 | bus->netdev = NULL; |
362 | rtnl_unlock(); | 363 | rtnl_unlock(); |
@@ -459,7 +460,8 @@ EXPORT_SYMBOL_GPL(sfp_register_socket); | |||
459 | void sfp_unregister_socket(struct sfp_bus *bus) | 460 | void sfp_unregister_socket(struct sfp_bus *bus) |
460 | { | 461 | { |
461 | rtnl_lock(); | 462 | rtnl_lock(); |
462 | sfp_unregister_bus(bus); | 463 | if (bus->netdev) |
464 | sfp_unregister_bus(bus); | ||
463 | bus->sfp_dev = NULL; | 465 | bus->sfp_dev = NULL; |
464 | bus->sfp = NULL; | 466 | bus->sfp = NULL; |
465 | bus->socket_ops = NULL; | 467 | bus->socket_ops = NULL; |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3000ddd1c7e2..728819feab44 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -1100,6 +1100,7 @@ static const struct usb_device_id products[] = { | |||
1100 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, | 1100 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, |
1101 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, | 1101 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, |
1102 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, | 1102 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, |
1103 | {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ | ||
1103 | {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, | 1104 | {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, |
1104 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ | 1105 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ |
1105 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ | 1106 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index f7d228b5ba93..987f1252a3cf 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
@@ -384,6 +384,18 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) | |||
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
387 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
388 | list_for_each_entry(tmp, &wcn->vif_list, list) { | ||
389 | vif = wcn36xx_priv_to_vif(tmp); | ||
390 | if (hw->conf.flags & IEEE80211_CONF_PS) { | ||
391 | if (vif->bss_conf.ps) /* ps allowed ? */ | ||
392 | wcn36xx_pmc_enter_bmps_state(wcn, vif); | ||
393 | } else { | ||
394 | wcn36xx_pmc_exit_bmps_state(wcn, vif); | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | |||
387 | mutex_unlock(&wcn->conf_mutex); | 399 | mutex_unlock(&wcn->conf_mutex); |
388 | 400 | ||
389 | return 0; | 401 | return 0; |
@@ -747,17 +759,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
747 | vif_priv->dtim_period = bss_conf->dtim_period; | 759 | vif_priv->dtim_period = bss_conf->dtim_period; |
748 | } | 760 | } |
749 | 761 | ||
750 | if (changed & BSS_CHANGED_PS) { | ||
751 | wcn36xx_dbg(WCN36XX_DBG_MAC, | ||
752 | "mac bss PS set %d\n", | ||
753 | bss_conf->ps); | ||
754 | if (bss_conf->ps) { | ||
755 | wcn36xx_pmc_enter_bmps_state(wcn, vif); | ||
756 | } else { | ||
757 | wcn36xx_pmc_exit_bmps_state(wcn, vif); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | if (changed & BSS_CHANGED_BSSID) { | 762 | if (changed & BSS_CHANGED_BSSID) { |
762 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n", | 763 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n", |
763 | bss_conf->bssid); | 764 | bss_conf->bssid); |
diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c index 589fe5f70971..1976b80c235f 100644 --- a/drivers/net/wireless/ath/wcn36xx/pmc.c +++ b/drivers/net/wireless/ath/wcn36xx/pmc.c | |||
@@ -45,8 +45,10 @@ int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn, | |||
45 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); | 45 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
46 | 46 | ||
47 | if (WCN36XX_BMPS != vif_priv->pw_state) { | 47 | if (WCN36XX_BMPS != vif_priv->pw_state) { |
48 | wcn36xx_err("Not in BMPS mode, no need to exit from BMPS mode!\n"); | 48 | /* Unbalanced call or last BMPS enter failed */ |
49 | return -EINVAL; | 49 | wcn36xx_dbg(WCN36XX_DBG_PMC, |
50 | "Not in BMPS mode, no need to exit\n"); | ||
51 | return -EALREADY; | ||
50 | } | 52 | } |
51 | wcn36xx_smd_exit_bmps(wcn, vif); | 53 | wcn36xx_smd_exit_bmps(wcn, vif); |
52 | vif_priv->pw_state = WCN36XX_FULL_POWER; | 54 | vif_priv->pw_state = WCN36XX_FULL_POWER; |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index d749abeca3ae..403e65c309d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h | |||
@@ -670,11 +670,15 @@ static inline u8 iwl_pcie_get_cmd_index(struct iwl_txq *q, u32 index) | |||
670 | return index & (q->n_window - 1); | 670 | return index & (q->n_window - 1); |
671 | } | 671 | } |
672 | 672 | ||
673 | static inline void *iwl_pcie_get_tfd(struct iwl_trans_pcie *trans_pcie, | 673 | static inline void *iwl_pcie_get_tfd(struct iwl_trans *trans, |
674 | struct iwl_txq *txq, int idx) | 674 | struct iwl_txq *txq, int idx) |
675 | { | 675 | { |
676 | return txq->tfds + trans_pcie->tfd_size * iwl_pcie_get_cmd_index(txq, | 676 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
677 | idx); | 677 | |
678 | if (trans->cfg->use_tfh) | ||
679 | idx = iwl_pcie_get_cmd_index(txq, idx); | ||
680 | |||
681 | return txq->tfds + trans_pcie->tfd_size * idx; | ||
678 | } | 682 | } |
679 | 683 | ||
680 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) | 684 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 16b345f54ff0..6d0a907d5ba5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | |||
@@ -171,8 +171,6 @@ static void iwl_pcie_gen2_tfd_unmap(struct iwl_trans *trans, | |||
171 | 171 | ||
172 | static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) | 172 | static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) |
173 | { | 173 | { |
174 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
175 | |||
176 | /* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and | 174 | /* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and |
177 | * idx is bounded by n_window | 175 | * idx is bounded by n_window |
178 | */ | 176 | */ |
@@ -181,7 +179,7 @@ static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) | |||
181 | lockdep_assert_held(&txq->lock); | 179 | lockdep_assert_held(&txq->lock); |
182 | 180 | ||
183 | iwl_pcie_gen2_tfd_unmap(trans, &txq->entries[idx].meta, | 181 | iwl_pcie_gen2_tfd_unmap(trans, &txq->entries[idx].meta, |
184 | iwl_pcie_get_tfd(trans_pcie, txq, idx)); | 182 | iwl_pcie_get_tfd(trans, txq, idx)); |
185 | 183 | ||
186 | /* free SKB */ | 184 | /* free SKB */ |
187 | if (txq->entries) { | 185 | if (txq->entries) { |
@@ -364,11 +362,9 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, | |||
364 | struct sk_buff *skb, | 362 | struct sk_buff *skb, |
365 | struct iwl_cmd_meta *out_meta) | 363 | struct iwl_cmd_meta *out_meta) |
366 | { | 364 | { |
367 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
368 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 365 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
369 | int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr); | 366 | int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr); |
370 | struct iwl_tfh_tfd *tfd = | 367 | struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, idx); |
371 | iwl_pcie_get_tfd(trans_pcie, txq, idx); | ||
372 | dma_addr_t tb_phys; | 368 | dma_addr_t tb_phys; |
373 | bool amsdu; | 369 | bool amsdu; |
374 | int i, len, tb1_len, tb2_len, hdr_len; | 370 | int i, len, tb1_len, tb2_len, hdr_len; |
@@ -565,8 +561,7 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, | |||
565 | u8 group_id = iwl_cmd_groupid(cmd->id); | 561 | u8 group_id = iwl_cmd_groupid(cmd->id); |
566 | const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; | 562 | const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; |
567 | u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; | 563 | u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; |
568 | struct iwl_tfh_tfd *tfd = | 564 | struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr); |
569 | iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr); | ||
570 | 565 | ||
571 | memset(tfd, 0, sizeof(*tfd)); | 566 | memset(tfd, 0, sizeof(*tfd)); |
572 | 567 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index fed6d842a5e1..3f85713c41dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c | |||
@@ -373,7 +373,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, | |||
373 | { | 373 | { |
374 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 374 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
375 | int i, num_tbs; | 375 | int i, num_tbs; |
376 | void *tfd = iwl_pcie_get_tfd(trans_pcie, txq, index); | 376 | void *tfd = iwl_pcie_get_tfd(trans, txq, index); |
377 | 377 | ||
378 | /* Sanity check on number of chunks */ | 378 | /* Sanity check on number of chunks */ |
379 | num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd); | 379 | num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd); |
@@ -2018,7 +2018,7 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, | |||
2018 | } | 2018 | } |
2019 | 2019 | ||
2020 | trace_iwlwifi_dev_tx(trans->dev, skb, | 2020 | trace_iwlwifi_dev_tx(trans->dev, skb, |
2021 | iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr), | 2021 | iwl_pcie_get_tfd(trans, txq, txq->write_ptr), |
2022 | trans_pcie->tfd_size, | 2022 | trans_pcie->tfd_size, |
2023 | &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, | 2023 | &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, |
2024 | hdr_len); | 2024 | hdr_len); |
@@ -2092,7 +2092,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
2092 | IEEE80211_CCMP_HDR_LEN : 0; | 2092 | IEEE80211_CCMP_HDR_LEN : 0; |
2093 | 2093 | ||
2094 | trace_iwlwifi_dev_tx(trans->dev, skb, | 2094 | trace_iwlwifi_dev_tx(trans->dev, skb, |
2095 | iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr), | 2095 | iwl_pcie_get_tfd(trans, txq, txq->write_ptr), |
2096 | trans_pcie->tfd_size, | 2096 | trans_pcie->tfd_size, |
2097 | &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, 0); | 2097 | &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, 0); |
2098 | 2098 | ||
@@ -2425,7 +2425,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
2425 | memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, | 2425 | memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, |
2426 | IWL_FIRST_TB_SIZE); | 2426 | IWL_FIRST_TB_SIZE); |
2427 | 2427 | ||
2428 | tfd = iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr); | 2428 | tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr); |
2429 | /* Set up entry for this TFD in Tx byte-count array */ | 2429 | /* Set up entry for this TFD in Tx byte-count array */ |
2430 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len), | 2430 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len), |
2431 | iwl_pcie_tfd_get_num_tbs(trans, tfd)); | 2431 | iwl_pcie_tfd_get_num_tbs(trans, tfd)); |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index c5a34671abda..9bd7ddeeb6a5 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -1326,6 +1326,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1326 | 1326 | ||
1327 | netif_carrier_off(netdev); | 1327 | netif_carrier_off(netdev); |
1328 | 1328 | ||
1329 | xenbus_switch_state(dev, XenbusStateInitialising); | ||
1329 | return netdev; | 1330 | return netdev; |
1330 | 1331 | ||
1331 | exit: | 1332 | exit: |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1e46e60b8f10..839650e0926a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
@@ -1335,6 +1335,7 @@ static void nvme_update_disk_info(struct gendisk *disk, | |||
1335 | struct nvme_ns *ns, struct nvme_id_ns *id) | 1335 | struct nvme_ns *ns, struct nvme_id_ns *id) |
1336 | { | 1336 | { |
1337 | sector_t capacity = le64_to_cpup(&id->nsze) << (ns->lba_shift - 9); | 1337 | sector_t capacity = le64_to_cpup(&id->nsze) << (ns->lba_shift - 9); |
1338 | unsigned short bs = 1 << ns->lba_shift; | ||
1338 | unsigned stream_alignment = 0; | 1339 | unsigned stream_alignment = 0; |
1339 | 1340 | ||
1340 | if (ns->ctrl->nr_streams && ns->sws && ns->sgs) | 1341 | if (ns->ctrl->nr_streams && ns->sws && ns->sgs) |
@@ -1343,7 +1344,10 @@ static void nvme_update_disk_info(struct gendisk *disk, | |||
1343 | blk_mq_freeze_queue(disk->queue); | 1344 | blk_mq_freeze_queue(disk->queue); |
1344 | blk_integrity_unregister(disk); | 1345 | blk_integrity_unregister(disk); |
1345 | 1346 | ||
1346 | blk_queue_logical_block_size(disk->queue, 1 << ns->lba_shift); | 1347 | blk_queue_logical_block_size(disk->queue, bs); |
1348 | blk_queue_physical_block_size(disk->queue, bs); | ||
1349 | blk_queue_io_min(disk->queue, bs); | ||
1350 | |||
1347 | if (ns->ms && !ns->ext && | 1351 | if (ns->ms && !ns->ext && |
1348 | (ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) | 1352 | (ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) |
1349 | nvme_init_integrity(disk, ns->ms, ns->pi_type); | 1353 | nvme_init_integrity(disk, ns->ms, ns->pi_type); |
@@ -2987,6 +2991,7 @@ static void nvme_ns_remove(struct nvme_ns *ns) | |||
2987 | mutex_unlock(&ns->ctrl->namespaces_mutex); | 2991 | mutex_unlock(&ns->ctrl->namespaces_mutex); |
2988 | 2992 | ||
2989 | synchronize_srcu(&ns->head->srcu); | 2993 | synchronize_srcu(&ns->head->srcu); |
2994 | nvme_mpath_check_last_path(ns); | ||
2990 | nvme_put_ns(ns); | 2995 | nvme_put_ns(ns); |
2991 | } | 2996 | } |
2992 | 2997 | ||
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 76b4fe6816a0..894c2ccb3891 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c | |||
@@ -74,6 +74,7 @@ static struct nvmf_host *nvmf_host_default(void) | |||
74 | return NULL; | 74 | return NULL; |
75 | 75 | ||
76 | kref_init(&host->ref); | 76 | kref_init(&host->ref); |
77 | uuid_gen(&host->id); | ||
77 | snprintf(host->nqn, NVMF_NQN_SIZE, | 78 | snprintf(host->nqn, NVMF_NQN_SIZE, |
78 | "nqn.2014-08.org.nvmexpress:uuid:%pUb", &host->id); | 79 | "nqn.2014-08.org.nvmexpress:uuid:%pUb", &host->id); |
79 | 80 | ||
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index ea1aa5283e8e..a00eabd06427 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
@@ -417,6 +417,15 @@ static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | |||
417 | rcu_assign_pointer(head->current_path, NULL); | 417 | rcu_assign_pointer(head->current_path, NULL); |
418 | } | 418 | } |
419 | struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); | 419 | struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); |
420 | |||
421 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | ||
422 | { | ||
423 | struct nvme_ns_head *head = ns->head; | ||
424 | |||
425 | if (head->disk && list_empty(&head->list)) | ||
426 | kblockd_schedule_work(&head->requeue_work); | ||
427 | } | ||
428 | |||
420 | #else | 429 | #else |
421 | static inline void nvme_failover_req(struct request *req) | 430 | static inline void nvme_failover_req(struct request *req) |
422 | { | 431 | { |
@@ -448,6 +457,9 @@ static inline void nvme_mpath_remove_disk_links(struct nvme_ns *ns) | |||
448 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | 457 | static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) |
449 | { | 458 | { |
450 | } | 459 | } |
460 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | ||
461 | { | ||
462 | } | ||
451 | #endif /* CONFIG_NVME_MULTIPATH */ | 463 | #endif /* CONFIG_NVME_MULTIPATH */ |
452 | 464 | ||
453 | #ifdef CONFIG_NVM | 465 | #ifdef CONFIG_NVM |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f5800c3c9082..d53550e612bc 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -448,12 +448,31 @@ static void **nvme_pci_iod_list(struct request *req) | |||
448 | return (void **)(iod->sg + blk_rq_nr_phys_segments(req)); | 448 | return (void **)(iod->sg + blk_rq_nr_phys_segments(req)); |
449 | } | 449 | } |
450 | 450 | ||
451 | static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req) | ||
452 | { | ||
453 | struct nvme_iod *iod = blk_mq_rq_to_pdu(req); | ||
454 | unsigned int avg_seg_size; | ||
455 | |||
456 | avg_seg_size = DIV_ROUND_UP(blk_rq_payload_bytes(req), | ||
457 | blk_rq_nr_phys_segments(req)); | ||
458 | |||
459 | if (!(dev->ctrl.sgls & ((1 << 0) | (1 << 1)))) | ||
460 | return false; | ||
461 | if (!iod->nvmeq->qid) | ||
462 | return false; | ||
463 | if (!sgl_threshold || avg_seg_size < sgl_threshold) | ||
464 | return false; | ||
465 | return true; | ||
466 | } | ||
467 | |||
451 | static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) | 468 | static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) |
452 | { | 469 | { |
453 | struct nvme_iod *iod = blk_mq_rq_to_pdu(rq); | 470 | struct nvme_iod *iod = blk_mq_rq_to_pdu(rq); |
454 | int nseg = blk_rq_nr_phys_segments(rq); | 471 | int nseg = blk_rq_nr_phys_segments(rq); |
455 | unsigned int size = blk_rq_payload_bytes(rq); | 472 | unsigned int size = blk_rq_payload_bytes(rq); |
456 | 473 | ||
474 | iod->use_sgl = nvme_pci_use_sgls(dev, rq); | ||
475 | |||
457 | if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) { | 476 | if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) { |
458 | size_t alloc_size = nvme_pci_iod_alloc_size(dev, size, nseg, | 477 | size_t alloc_size = nvme_pci_iod_alloc_size(dev, size, nseg, |
459 | iod->use_sgl); | 478 | iod->use_sgl); |
@@ -604,8 +623,6 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev, | |||
604 | dma_addr_t prp_dma; | 623 | dma_addr_t prp_dma; |
605 | int nprps, i; | 624 | int nprps, i; |
606 | 625 | ||
607 | iod->use_sgl = false; | ||
608 | |||
609 | length -= (page_size - offset); | 626 | length -= (page_size - offset); |
610 | if (length <= 0) { | 627 | if (length <= 0) { |
611 | iod->first_dma = 0; | 628 | iod->first_dma = 0; |
@@ -715,8 +732,6 @@ static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev, | |||
715 | int entries = iod->nents, i = 0; | 732 | int entries = iod->nents, i = 0; |
716 | dma_addr_t sgl_dma; | 733 | dma_addr_t sgl_dma; |
717 | 734 | ||
718 | iod->use_sgl = true; | ||
719 | |||
720 | /* setting the transfer type as SGL */ | 735 | /* setting the transfer type as SGL */ |
721 | cmd->flags = NVME_CMD_SGL_METABUF; | 736 | cmd->flags = NVME_CMD_SGL_METABUF; |
722 | 737 | ||
@@ -770,23 +785,6 @@ static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev, | |||
770 | return BLK_STS_OK; | 785 | return BLK_STS_OK; |
771 | } | 786 | } |
772 | 787 | ||
773 | static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req) | ||
774 | { | ||
775 | struct nvme_iod *iod = blk_mq_rq_to_pdu(req); | ||
776 | unsigned int avg_seg_size; | ||
777 | |||
778 | avg_seg_size = DIV_ROUND_UP(blk_rq_payload_bytes(req), | ||
779 | blk_rq_nr_phys_segments(req)); | ||
780 | |||
781 | if (!(dev->ctrl.sgls & ((1 << 0) | (1 << 1)))) | ||
782 | return false; | ||
783 | if (!iod->nvmeq->qid) | ||
784 | return false; | ||
785 | if (!sgl_threshold || avg_seg_size < sgl_threshold) | ||
786 | return false; | ||
787 | return true; | ||
788 | } | ||
789 | |||
790 | static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, | 788 | static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, |
791 | struct nvme_command *cmnd) | 789 | struct nvme_command *cmnd) |
792 | { | 790 | { |
@@ -806,7 +804,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, | |||
806 | DMA_ATTR_NO_WARN)) | 804 | DMA_ATTR_NO_WARN)) |
807 | goto out; | 805 | goto out; |
808 | 806 | ||
809 | if (nvme_pci_use_sgls(dev, req)) | 807 | if (iod->use_sgl) |
810 | ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw); | 808 | ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw); |
811 | else | 809 | else |
812 | ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); | 810 | ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); |
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 37af56596be6..2a0bba7f50cf 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c | |||
@@ -974,12 +974,18 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) | |||
974 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); | 974 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); |
975 | nvme_start_queues(&ctrl->ctrl); | 975 | nvme_start_queues(&ctrl->ctrl); |
976 | 976 | ||
977 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | ||
978 | /* state change failure should never happen */ | ||
979 | WARN_ON_ONCE(1); | ||
980 | return; | ||
981 | } | ||
982 | |||
977 | nvme_rdma_reconnect_or_remove(ctrl); | 983 | nvme_rdma_reconnect_or_remove(ctrl); |
978 | } | 984 | } |
979 | 985 | ||
980 | static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) | 986 | static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) |
981 | { | 987 | { |
982 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) | 988 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) |
983 | return; | 989 | return; |
984 | 990 | ||
985 | queue_work(nvme_wq, &ctrl->err_work); | 991 | queue_work(nvme_wq, &ctrl->err_work); |
@@ -1753,6 +1759,12 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work) | |||
1753 | nvme_stop_ctrl(&ctrl->ctrl); | 1759 | nvme_stop_ctrl(&ctrl->ctrl); |
1754 | nvme_rdma_shutdown_ctrl(ctrl, false); | 1760 | nvme_rdma_shutdown_ctrl(ctrl, false); |
1755 | 1761 | ||
1762 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) { | ||
1763 | /* state change failure should never happen */ | ||
1764 | WARN_ON_ONCE(1); | ||
1765 | return; | ||
1766 | } | ||
1767 | |||
1756 | ret = nvme_rdma_configure_admin_queue(ctrl, false); | 1768 | ret = nvme_rdma_configure_admin_queue(ctrl, false); |
1757 | if (ret) | 1769 | if (ret) |
1758 | goto out_fail; | 1770 | goto out_fail; |
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index 7b75d9de55ab..6a018a0bd6ce 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c | |||
@@ -1085,7 +1085,7 @@ fcloop_delete_target_port(struct device *dev, struct device_attribute *attr, | |||
1085 | const char *buf, size_t count) | 1085 | const char *buf, size_t count) |
1086 | { | 1086 | { |
1087 | struct fcloop_nport *nport = NULL, *tmpport; | 1087 | struct fcloop_nport *nport = NULL, *tmpport; |
1088 | struct fcloop_tport *tport; | 1088 | struct fcloop_tport *tport = NULL; |
1089 | u64 nodename, portname; | 1089 | u64 nodename, portname; |
1090 | unsigned long flags; | 1090 | unsigned long flags; |
1091 | int ret; | 1091 | int ret; |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 3481e69738b5..a327be1d264b 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -231,7 +231,12 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
231 | rc = of_mdiobus_register_phy(mdio, child, addr); | 231 | rc = of_mdiobus_register_phy(mdio, child, addr); |
232 | else | 232 | else |
233 | rc = of_mdiobus_register_device(mdio, child, addr); | 233 | rc = of_mdiobus_register_device(mdio, child, addr); |
234 | if (rc) | 234 | |
235 | if (rc == -ENODEV) | ||
236 | dev_err(&mdio->dev, | ||
237 | "MDIO device at address %d is missing.\n", | ||
238 | addr); | ||
239 | else if (rc) | ||
235 | goto unregister; | 240 | goto unregister; |
236 | } | 241 | } |
237 | 242 | ||
@@ -255,7 +260,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
255 | 260 | ||
256 | if (of_mdiobus_child_is_phy(child)) { | 261 | if (of_mdiobus_child_is_phy(child)) { |
257 | rc = of_mdiobus_register_phy(mdio, child, addr); | 262 | rc = of_mdiobus_register_phy(mdio, child, addr); |
258 | if (rc) | 263 | if (rc && rc != -ENODEV) |
259 | goto unregister; | 264 | goto unregister; |
260 | } | 265 | } |
261 | } | 266 | } |
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 791449a2370f..daa68acbc900 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -1458,5 +1458,5 @@ static void __exit acpi_wmi_exit(void) | |||
1458 | class_unregister(&wmi_bus_class); | 1458 | class_unregister(&wmi_bus_class); |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | subsys_initcall(acpi_wmi_init); | 1461 | subsys_initcall_sync(acpi_wmi_init); |
1462 | module_exit(acpi_wmi_exit); | 1462 | module_exit(acpi_wmi_exit); |
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 0f695df14c9d..372ce9913e6d 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c | |||
@@ -765,10 +765,12 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
765 | break; | 765 | break; |
766 | case ASHMEM_SET_SIZE: | 766 | case ASHMEM_SET_SIZE: |
767 | ret = -EINVAL; | 767 | ret = -EINVAL; |
768 | mutex_lock(&ashmem_mutex); | ||
768 | if (!asma->file) { | 769 | if (!asma->file) { |
769 | ret = 0; | 770 | ret = 0; |
770 | asma->size = (size_t)arg; | 771 | asma->size = (size_t)arg; |
771 | } | 772 | } |
773 | mutex_unlock(&ashmem_mutex); | ||
772 | break; | 774 | break; |
773 | case ASHMEM_GET_SIZE: | 775 | case ASHMEM_GET_SIZE: |
774 | ret = asma->size; | 776 | ret = asma->size; |
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 93eff7dec2f5..1b3efb14aec7 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c | |||
@@ -1147,11 +1147,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, | |||
1147 | 1147 | ||
1148 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); | 1148 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); |
1149 | if (!udc) | 1149 | if (!udc) |
1150 | goto err1; | 1150 | goto err_put_gadget; |
1151 | |||
1152 | ret = device_add(&gadget->dev); | ||
1153 | if (ret) | ||
1154 | goto err2; | ||
1155 | 1151 | ||
1156 | device_initialize(&udc->dev); | 1152 | device_initialize(&udc->dev); |
1157 | udc->dev.release = usb_udc_release; | 1153 | udc->dev.release = usb_udc_release; |
@@ -1160,7 +1156,11 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, | |||
1160 | udc->dev.parent = parent; | 1156 | udc->dev.parent = parent; |
1161 | ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); | 1157 | ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); |
1162 | if (ret) | 1158 | if (ret) |
1163 | goto err3; | 1159 | goto err_put_udc; |
1160 | |||
1161 | ret = device_add(&gadget->dev); | ||
1162 | if (ret) | ||
1163 | goto err_put_udc; | ||
1164 | 1164 | ||
1165 | udc->gadget = gadget; | 1165 | udc->gadget = gadget; |
1166 | gadget->udc = udc; | 1166 | gadget->udc = udc; |
@@ -1170,7 +1170,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, | |||
1170 | 1170 | ||
1171 | ret = device_add(&udc->dev); | 1171 | ret = device_add(&udc->dev); |
1172 | if (ret) | 1172 | if (ret) |
1173 | goto err4; | 1173 | goto err_unlist_udc; |
1174 | 1174 | ||
1175 | usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); | 1175 | usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); |
1176 | udc->vbus = true; | 1176 | udc->vbus = true; |
@@ -1178,27 +1178,25 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, | |||
1178 | /* pick up one of pending gadget drivers */ | 1178 | /* pick up one of pending gadget drivers */ |
1179 | ret = check_pending_gadget_drivers(udc); | 1179 | ret = check_pending_gadget_drivers(udc); |
1180 | if (ret) | 1180 | if (ret) |
1181 | goto err5; | 1181 | goto err_del_udc; |
1182 | 1182 | ||
1183 | mutex_unlock(&udc_lock); | 1183 | mutex_unlock(&udc_lock); |
1184 | 1184 | ||
1185 | return 0; | 1185 | return 0; |
1186 | 1186 | ||
1187 | err5: | 1187 | err_del_udc: |
1188 | device_del(&udc->dev); | 1188 | device_del(&udc->dev); |
1189 | 1189 | ||
1190 | err4: | 1190 | err_unlist_udc: |
1191 | list_del(&udc->list); | 1191 | list_del(&udc->list); |
1192 | mutex_unlock(&udc_lock); | 1192 | mutex_unlock(&udc_lock); |
1193 | 1193 | ||
1194 | err3: | ||
1195 | put_device(&udc->dev); | ||
1196 | device_del(&gadget->dev); | 1194 | device_del(&gadget->dev); |
1197 | 1195 | ||
1198 | err2: | 1196 | err_put_udc: |
1199 | kfree(udc); | 1197 | put_device(&udc->dev); |
1200 | 1198 | ||
1201 | err1: | 1199 | err_put_gadget: |
1202 | put_device(&gadget->dev); | 1200 | put_device(&gadget->dev); |
1203 | return ret; | 1201 | return ret; |
1204 | } | 1202 | } |
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index 465dbf68b463..f723f7b8c9ac 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c | |||
@@ -279,6 +279,8 @@ static int usb3503_probe(struct usb3503 *hub) | |||
279 | if (gpio_is_valid(hub->gpio_reset)) { | 279 | if (gpio_is_valid(hub->gpio_reset)) { |
280 | err = devm_gpio_request_one(dev, hub->gpio_reset, | 280 | err = devm_gpio_request_one(dev, hub->gpio_reset, |
281 | GPIOF_OUT_INIT_LOW, "usb3503 reset"); | 281 | GPIOF_OUT_INIT_LOW, "usb3503 reset"); |
282 | /* Datasheet defines a hardware reset to be at least 100us */ | ||
283 | usleep_range(100, 10000); | ||
282 | if (err) { | 284 | if (err) { |
283 | dev_err(dev, | 285 | dev_err(dev, |
284 | "unable to request GPIO %d as reset pin (%d)\n", | 286 | "unable to request GPIO %d as reset pin (%d)\n", |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index f6ae753ab99b..f932f40302df 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -1004,7 +1004,9 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
1004 | break; | 1004 | break; |
1005 | 1005 | ||
1006 | case MON_IOCQ_RING_SIZE: | 1006 | case MON_IOCQ_RING_SIZE: |
1007 | mutex_lock(&rp->fetch_lock); | ||
1007 | ret = rp->b_size; | 1008 | ret = rp->b_size; |
1009 | mutex_unlock(&rp->fetch_lock); | ||
1008 | break; | 1010 | break; |
1009 | 1011 | ||
1010 | case MON_IOCT_RING_SIZE: | 1012 | case MON_IOCT_RING_SIZE: |
@@ -1231,12 +1233,16 @@ static int mon_bin_vma_fault(struct vm_fault *vmf) | |||
1231 | unsigned long offset, chunk_idx; | 1233 | unsigned long offset, chunk_idx; |
1232 | struct page *pageptr; | 1234 | struct page *pageptr; |
1233 | 1235 | ||
1236 | mutex_lock(&rp->fetch_lock); | ||
1234 | offset = vmf->pgoff << PAGE_SHIFT; | 1237 | offset = vmf->pgoff << PAGE_SHIFT; |
1235 | if (offset >= rp->b_size) | 1238 | if (offset >= rp->b_size) { |
1239 | mutex_unlock(&rp->fetch_lock); | ||
1236 | return VM_FAULT_SIGBUS; | 1240 | return VM_FAULT_SIGBUS; |
1241 | } | ||
1237 | chunk_idx = offset / CHUNK_SIZE; | 1242 | chunk_idx = offset / CHUNK_SIZE; |
1238 | pageptr = rp->b_vec[chunk_idx].pg; | 1243 | pageptr = rp->b_vec[chunk_idx].pg; |
1239 | get_page(pageptr); | 1244 | get_page(pageptr); |
1245 | mutex_unlock(&rp->fetch_lock); | ||
1240 | vmf->page = pageptr; | 1246 | vmf->page = pageptr; |
1241 | return 0; | 1247 | return 0; |
1242 | } | 1248 | } |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 7c6273bf5beb..06d502b3e913 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -124,6 +124,7 @@ static const struct usb_device_id id_table[] = { | |||
124 | { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ | 124 | { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ |
125 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ | 125 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ |
126 | { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ | 126 | { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ |
127 | { USB_DEVICE(0x10C4, 0x85A7) }, /* LifeScan OneTouch Verio IQ */ | ||
127 | { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ | 128 | { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ |
128 | { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ | 129 | { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ |
129 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ | 130 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ |
@@ -174,6 +175,7 @@ static const struct usb_device_id id_table[] = { | |||
174 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | 175 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ |
175 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | 176 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ |
176 | { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ | 177 | { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ |
178 | { USB_DEVICE(0x18EF, 0xE030) }, /* ELV ALC 8xxx Battery Charger */ | ||
177 | { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ | 179 | { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ |
178 | { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ | 180 | { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ |
179 | { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ | 181 | { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ |
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index e6127fb21c12..a7d08ae0adad 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h | |||
@@ -143,6 +143,13 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, | |||
143 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 143 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
144 | US_FL_NO_ATA_1X), | 144 | US_FL_NO_ATA_1X), |
145 | 145 | ||
146 | /* Reported-by: Icenowy Zheng <icenowy@aosc.io> */ | ||
147 | UNUSUAL_DEV(0x2537, 0x1068, 0x0000, 0x9999, | ||
148 | "Norelsys", | ||
149 | "NS1068X", | ||
150 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
151 | US_FL_IGNORE_UAS), | ||
152 | |||
146 | /* Reported-by: Takeo Nakayama <javhera@gmx.com> */ | 153 | /* Reported-by: Takeo Nakayama <javhera@gmx.com> */ |
147 | UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999, | 154 | UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999, |
148 | "JMicron", | 155 | "JMicron", |
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index 7b219d9109b4..ee2bbce24584 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c | |||
@@ -91,7 +91,7 @@ static void usbip_dump_usb_device(struct usb_device *udev) | |||
91 | dev_dbg(dev, " devnum(%d) devpath(%s) usb speed(%s)", | 91 | dev_dbg(dev, " devnum(%d) devpath(%s) usb speed(%s)", |
92 | udev->devnum, udev->devpath, usb_speed_string(udev->speed)); | 92 | udev->devnum, udev->devpath, usb_speed_string(udev->speed)); |
93 | 93 | ||
94 | pr_debug("tt %p, ttport %d\n", udev->tt, udev->ttport); | 94 | pr_debug("tt hub ttport %d\n", udev->ttport); |
95 | 95 | ||
96 | dev_dbg(dev, " "); | 96 | dev_dbg(dev, " "); |
97 | for (i = 0; i < 16; i++) | 97 | for (i = 0; i < 16; i++) |
@@ -124,12 +124,8 @@ static void usbip_dump_usb_device(struct usb_device *udev) | |||
124 | } | 124 | } |
125 | pr_debug("\n"); | 125 | pr_debug("\n"); |
126 | 126 | ||
127 | dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus); | 127 | dev_dbg(dev, "parent %s, bus %s\n", dev_name(&udev->parent->dev), |
128 | 128 | udev->bus->bus_name); | |
129 | dev_dbg(dev, | ||
130 | "descriptor %p, config %p, actconfig %p, rawdescriptors %p\n", | ||
131 | &udev->descriptor, udev->config, | ||
132 | udev->actconfig, udev->rawdescriptors); | ||
133 | 129 | ||
134 | dev_dbg(dev, "have_langid %d, string_langid %d\n", | 130 | dev_dbg(dev, "have_langid %d, string_langid %d\n", |
135 | udev->have_langid, udev->string_langid); | 131 | udev->have_langid, udev->string_langid); |
@@ -237,9 +233,6 @@ void usbip_dump_urb(struct urb *urb) | |||
237 | 233 | ||
238 | dev = &urb->dev->dev; | 234 | dev = &urb->dev->dev; |
239 | 235 | ||
240 | dev_dbg(dev, " urb :%p\n", urb); | ||
241 | dev_dbg(dev, " dev :%p\n", urb->dev); | ||
242 | |||
243 | usbip_dump_usb_device(urb->dev); | 236 | usbip_dump_usb_device(urb->dev); |
244 | 237 | ||
245 | dev_dbg(dev, " pipe :%08x ", urb->pipe); | 238 | dev_dbg(dev, " pipe :%08x ", urb->pipe); |
@@ -248,11 +241,9 @@ void usbip_dump_urb(struct urb *urb) | |||
248 | 241 | ||
249 | dev_dbg(dev, " status :%d\n", urb->status); | 242 | dev_dbg(dev, " status :%d\n", urb->status); |
250 | dev_dbg(dev, " transfer_flags :%08X\n", urb->transfer_flags); | 243 | dev_dbg(dev, " transfer_flags :%08X\n", urb->transfer_flags); |
251 | dev_dbg(dev, " transfer_buffer :%p\n", urb->transfer_buffer); | ||
252 | dev_dbg(dev, " transfer_buffer_length:%d\n", | 244 | dev_dbg(dev, " transfer_buffer_length:%d\n", |
253 | urb->transfer_buffer_length); | 245 | urb->transfer_buffer_length); |
254 | dev_dbg(dev, " actual_length :%d\n", urb->actual_length); | 246 | dev_dbg(dev, " actual_length :%d\n", urb->actual_length); |
255 | dev_dbg(dev, " setup_packet :%p\n", urb->setup_packet); | ||
256 | 247 | ||
257 | if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL) | 248 | if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL) |
258 | usbip_dump_usb_ctrlrequest( | 249 | usbip_dump_usb_ctrlrequest( |
@@ -262,8 +253,6 @@ void usbip_dump_urb(struct urb *urb) | |||
262 | dev_dbg(dev, " number_of_packets :%d\n", urb->number_of_packets); | 253 | dev_dbg(dev, " number_of_packets :%d\n", urb->number_of_packets); |
263 | dev_dbg(dev, " interval :%d\n", urb->interval); | 254 | dev_dbg(dev, " interval :%d\n", urb->interval); |
264 | dev_dbg(dev, " error_count :%d\n", urb->error_count); | 255 | dev_dbg(dev, " error_count :%d\n", urb->error_count); |
265 | dev_dbg(dev, " context :%p\n", urb->context); | ||
266 | dev_dbg(dev, " complete :%p\n", urb->complete); | ||
267 | } | 256 | } |
268 | EXPORT_SYMBOL_GPL(usbip_dump_urb); | 257 | EXPORT_SYMBOL_GPL(usbip_dump_urb); |
269 | 258 | ||
diff --git a/drivers/usb/usbip/vudc_rx.c b/drivers/usb/usbip/vudc_rx.c index df1e30989148..1e8a23d92cb4 100644 --- a/drivers/usb/usbip/vudc_rx.c +++ b/drivers/usb/usbip/vudc_rx.c | |||
@@ -120,6 +120,25 @@ static int v_recv_cmd_submit(struct vudc *udc, | |||
120 | urb_p->new = 1; | 120 | urb_p->new = 1; |
121 | urb_p->seqnum = pdu->base.seqnum; | 121 | urb_p->seqnum = pdu->base.seqnum; |
122 | 122 | ||
123 | if (urb_p->ep->type == USB_ENDPOINT_XFER_ISOC) { | ||
124 | /* validate packet size and number of packets */ | ||
125 | unsigned int maxp, packets, bytes; | ||
126 | |||
127 | maxp = usb_endpoint_maxp(urb_p->ep->desc); | ||
128 | maxp *= usb_endpoint_maxp_mult(urb_p->ep->desc); | ||
129 | bytes = pdu->u.cmd_submit.transfer_buffer_length; | ||
130 | packets = DIV_ROUND_UP(bytes, maxp); | ||
131 | |||
132 | if (pdu->u.cmd_submit.number_of_packets < 0 || | ||
133 | pdu->u.cmd_submit.number_of_packets > packets) { | ||
134 | dev_err(&udc->gadget.dev, | ||
135 | "CMD_SUBMIT: isoc invalid num packets %d\n", | ||
136 | pdu->u.cmd_submit.number_of_packets); | ||
137 | ret = -EMSGSIZE; | ||
138 | goto free_urbp; | ||
139 | } | ||
140 | } | ||
141 | |||
123 | ret = alloc_urb_from_cmd(&urb_p->urb, pdu, urb_p->ep->type); | 142 | ret = alloc_urb_from_cmd(&urb_p->urb, pdu, urb_p->ep->type); |
124 | if (ret) { | 143 | if (ret) { |
125 | usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC); | 144 | usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC); |
diff --git a/drivers/usb/usbip/vudc_tx.c b/drivers/usb/usbip/vudc_tx.c index 1440ae0919ec..3ccb17c3e840 100644 --- a/drivers/usb/usbip/vudc_tx.c +++ b/drivers/usb/usbip/vudc_tx.c | |||
@@ -85,6 +85,13 @@ static int v_send_ret_submit(struct vudc *udc, struct urbp *urb_p) | |||
85 | memset(&pdu_header, 0, sizeof(pdu_header)); | 85 | memset(&pdu_header, 0, sizeof(pdu_header)); |
86 | memset(&msg, 0, sizeof(msg)); | 86 | memset(&msg, 0, sizeof(msg)); |
87 | 87 | ||
88 | if (urb->actual_length > 0 && !urb->transfer_buffer) { | ||
89 | dev_err(&udc->gadget.dev, | ||
90 | "urb: actual_length %d transfer_buffer null\n", | ||
91 | urb->actual_length); | ||
92 | return -1; | ||
93 | } | ||
94 | |||
88 | if (urb_p->type == USB_ENDPOINT_XFER_ISOC) | 95 | if (urb_p->type == USB_ENDPOINT_XFER_ISOC) |
89 | iovnum = 2 + urb->number_of_packets; | 96 | iovnum = 2 + urb->number_of_packets; |
90 | else | 97 | else |
@@ -100,8 +107,8 @@ static int v_send_ret_submit(struct vudc *udc, struct urbp *urb_p) | |||
100 | 107 | ||
101 | /* 1. setup usbip_header */ | 108 | /* 1. setup usbip_header */ |
102 | setup_ret_submit_pdu(&pdu_header, urb_p); | 109 | setup_ret_submit_pdu(&pdu_header, urb_p); |
103 | usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", | 110 | usbip_dbg_stub_tx("setup txdata seqnum: %d\n", |
104 | pdu_header.base.seqnum, urb); | 111 | pdu_header.base.seqnum); |
105 | usbip_header_correct_endian(&pdu_header, 1); | 112 | usbip_header_correct_endian(&pdu_header, 1); |
106 | 113 | ||
107 | iov[iovnum].iov_base = &pdu_header; | 114 | iov[iovnum].iov_base = &pdu_header; |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 57efbd3b053b..bd56653b9bbc 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -380,10 +380,8 @@ static int unmap_grant_pages(struct grant_map *map, int offset, int pages) | |||
380 | } | 380 | } |
381 | range = 0; | 381 | range = 0; |
382 | while (range < pages) { | 382 | while (range < pages) { |
383 | if (map->unmap_ops[offset+range].handle == -1) { | 383 | if (map->unmap_ops[offset+range].handle == -1) |
384 | range--; | ||
385 | break; | 384 | break; |
386 | } | ||
387 | range++; | 385 | range++; |
388 | } | 386 | } |
389 | err = __unmap_grant_pages(map, offset, range); | 387 | err = __unmap_grant_pages(map, offset, range); |
@@ -1073,8 +1071,10 @@ unlock_out: | |||
1073 | out_unlock_put: | 1071 | out_unlock_put: |
1074 | mutex_unlock(&priv->lock); | 1072 | mutex_unlock(&priv->lock); |
1075 | out_put_map: | 1073 | out_put_map: |
1076 | if (use_ptemod) | 1074 | if (use_ptemod) { |
1077 | map->vma = NULL; | 1075 | map->vma = NULL; |
1076 | unmap_grant_pages(map, 0, map->count); | ||
1077 | } | ||
1078 | gntdev_put_map(priv, map); | 1078 | gntdev_put_map(priv, map); |
1079 | return err; | 1079 | return err; |
1080 | } | 1080 | } |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 79287629c888..c9608b0b80c6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -91,6 +91,9 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev, | |||
91 | bool acpi_dev_found(const char *hid); | 91 | bool acpi_dev_found(const char *hid); |
92 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); | 92 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); |
93 | 93 | ||
94 | const char * | ||
95 | acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv); | ||
96 | |||
94 | #ifdef CONFIG_ACPI | 97 | #ifdef CONFIG_ACPI |
95 | 98 | ||
96 | #include <linux/proc_fs.h> | 99 | #include <linux/proc_fs.h> |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index dc1ebfeeb5ec..d918f1ea84e6 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -640,6 +640,12 @@ static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) | |||
640 | return false; | 640 | return false; |
641 | } | 641 | } |
642 | 642 | ||
643 | static inline const char * | ||
644 | acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) | ||
645 | { | ||
646 | return NULL; | ||
647 | } | ||
648 | |||
643 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) | 649 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) |
644 | { | 650 | { |
645 | return false; | 651 | return false; |
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index b63a592ad29d..0b25cf87b6d6 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
@@ -43,7 +43,14 @@ struct bpf_map_ops { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct bpf_map { | 45 | struct bpf_map { |
46 | atomic_t refcnt; | 46 | /* 1st cacheline with read-mostly members of which some |
47 | * are also accessed in fast-path (e.g. ops, max_entries). | ||
48 | */ | ||
49 | const struct bpf_map_ops *ops ____cacheline_aligned; | ||
50 | struct bpf_map *inner_map_meta; | ||
51 | #ifdef CONFIG_SECURITY | ||
52 | void *security; | ||
53 | #endif | ||
47 | enum bpf_map_type map_type; | 54 | enum bpf_map_type map_type; |
48 | u32 key_size; | 55 | u32 key_size; |
49 | u32 value_size; | 56 | u32 value_size; |
@@ -52,15 +59,17 @@ struct bpf_map { | |||
52 | u32 pages; | 59 | u32 pages; |
53 | u32 id; | 60 | u32 id; |
54 | int numa_node; | 61 | int numa_node; |
55 | struct user_struct *user; | 62 | bool unpriv_array; |
56 | const struct bpf_map_ops *ops; | 63 | /* 7 bytes hole */ |
57 | struct work_struct work; | 64 | |
65 | /* 2nd cacheline with misc members to avoid false sharing | ||
66 | * particularly with refcounting. | ||
67 | */ | ||
68 | struct user_struct *user ____cacheline_aligned; | ||
69 | atomic_t refcnt; | ||
58 | atomic_t usercnt; | 70 | atomic_t usercnt; |
59 | struct bpf_map *inner_map_meta; | 71 | struct work_struct work; |
60 | char name[BPF_OBJ_NAME_LEN]; | 72 | char name[BPF_OBJ_NAME_LEN]; |
61 | #ifdef CONFIG_SECURITY | ||
62 | void *security; | ||
63 | #endif | ||
64 | }; | 73 | }; |
65 | 74 | ||
66 | /* function argument constraints */ | 75 | /* function argument constraints */ |
@@ -221,6 +230,7 @@ struct bpf_prog_aux { | |||
221 | struct bpf_array { | 230 | struct bpf_array { |
222 | struct bpf_map map; | 231 | struct bpf_map map; |
223 | u32 elem_size; | 232 | u32 elem_size; |
233 | u32 index_mask; | ||
224 | /* 'ownership' of prog_array is claimed by the first program that | 234 | /* 'ownership' of prog_array is claimed by the first program that |
225 | * is going to use this map or by the first program which FD is stored | 235 | * is going to use this map or by the first program which FD is stored |
226 | * in the map to make sure that all callers and callees have the same | 236 | * in the map to make sure that all callers and callees have the same |
diff --git a/include/linux/completion.h b/include/linux/completion.h index 94a59ba7d422..519e94915d18 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h | |||
@@ -32,7 +32,6 @@ struct completion { | |||
32 | #define init_completion(x) __init_completion(x) | 32 | #define init_completion(x) __init_completion(x) |
33 | static inline void complete_acquire(struct completion *x) {} | 33 | static inline void complete_acquire(struct completion *x) {} |
34 | static inline void complete_release(struct completion *x) {} | 34 | static inline void complete_release(struct completion *x) {} |
35 | static inline void complete_release_commit(struct completion *x) {} | ||
36 | 35 | ||
37 | #define COMPLETION_INITIALIZER(work) \ | 36 | #define COMPLETION_INITIALIZER(work) \ |
38 | { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } | 37 | { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index a04ef7c15c6a..7b01bc11c692 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -47,6 +47,13 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); | |||
47 | extern int cpu_add_dev_attr_group(struct attribute_group *attrs); | 47 | extern int cpu_add_dev_attr_group(struct attribute_group *attrs); |
48 | extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); | 48 | extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); |
49 | 49 | ||
50 | extern ssize_t cpu_show_meltdown(struct device *dev, | ||
51 | struct device_attribute *attr, char *buf); | ||
52 | extern ssize_t cpu_show_spectre_v1(struct device *dev, | ||
53 | struct device_attribute *attr, char *buf); | ||
54 | extern ssize_t cpu_show_spectre_v2(struct device *dev, | ||
55 | struct device_attribute *attr, char *buf); | ||
56 | |||
50 | extern __printf(4, 5) | 57 | extern __printf(4, 5) |
51 | struct device *cpu_device_create(struct device *parent, void *drvdata, | 58 | struct device *cpu_device_create(struct device *parent, void *drvdata, |
52 | const struct attribute_group **groups, | 59 | const struct attribute_group **groups, |
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index 06097ef30449..b511f6d24b42 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h | |||
@@ -42,6 +42,8 @@ phys_addr_t paddr_vmcoreinfo_note(void); | |||
42 | vmcoreinfo_append_str("PAGESIZE=%ld\n", value) | 42 | vmcoreinfo_append_str("PAGESIZE=%ld\n", value) |
43 | #define VMCOREINFO_SYMBOL(name) \ | 43 | #define VMCOREINFO_SYMBOL(name) \ |
44 | vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name) | 44 | vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name) |
45 | #define VMCOREINFO_SYMBOL_ARRAY(name) \ | ||
46 | vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name) | ||
45 | #define VMCOREINFO_SIZE(name) \ | 47 | #define VMCOREINFO_SIZE(name) \ |
46 | vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \ | 48 | vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \ |
47 | (unsigned long)sizeof(name)) | 49 | (unsigned long)sizeof(name)) |
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 46cb57d5eb13..1b3996ff3f16 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h | |||
@@ -27,22 +27,18 @@ | |||
27 | # define trace_hardirq_enter() \ | 27 | # define trace_hardirq_enter() \ |
28 | do { \ | 28 | do { \ |
29 | current->hardirq_context++; \ | 29 | current->hardirq_context++; \ |
30 | crossrelease_hist_start(XHLOCK_HARD); \ | ||
31 | } while (0) | 30 | } while (0) |
32 | # define trace_hardirq_exit() \ | 31 | # define trace_hardirq_exit() \ |
33 | do { \ | 32 | do { \ |
34 | current->hardirq_context--; \ | 33 | current->hardirq_context--; \ |
35 | crossrelease_hist_end(XHLOCK_HARD); \ | ||
36 | } while (0) | 34 | } while (0) |
37 | # define lockdep_softirq_enter() \ | 35 | # define lockdep_softirq_enter() \ |
38 | do { \ | 36 | do { \ |
39 | current->softirq_context++; \ | 37 | current->softirq_context++; \ |
40 | crossrelease_hist_start(XHLOCK_SOFT); \ | ||
41 | } while (0) | 38 | } while (0) |
42 | # define lockdep_softirq_exit() \ | 39 | # define lockdep_softirq_exit() \ |
43 | do { \ | 40 | do { \ |
44 | current->softirq_context--; \ | 41 | current->softirq_context--; \ |
45 | crossrelease_hist_end(XHLOCK_SOFT); \ | ||
46 | } while (0) | 42 | } while (0) |
47 | # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, | 43 | # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, |
48 | #else | 44 | #else |
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 2e75dc34bff5..3251d9c0d313 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h | |||
@@ -475,8 +475,6 @@ enum xhlock_context_t { | |||
475 | #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ | 475 | #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ |
476 | { .name = (_name), .key = (void *)(_key), } | 476 | { .name = (_name), .key = (void *)(_key), } |
477 | 477 | ||
478 | static inline void crossrelease_hist_start(enum xhlock_context_t c) {} | ||
479 | static inline void crossrelease_hist_end(enum xhlock_context_t c) {} | ||
480 | static inline void lockdep_invariant_state(bool force) {} | 478 | static inline void lockdep_invariant_state(bool force) {} |
481 | static inline void lockdep_init_task(struct task_struct *task) {} | 479 | static inline void lockdep_init_task(struct task_struct *task) {} |
482 | static inline void lockdep_free_task(struct task_struct *task) {} | 480 | static inline void lockdep_free_task(struct task_struct *task) {} |
diff --git a/include/linux/sh_eth.h b/include/linux/sh_eth.h index ff3642d267f7..94081e9a5010 100644 --- a/include/linux/sh_eth.h +++ b/include/linux/sh_eth.h | |||
@@ -17,7 +17,6 @@ struct sh_eth_plat_data { | |||
17 | unsigned char mac_addr[ETH_ALEN]; | 17 | unsigned char mac_addr[ETH_ALEN]; |
18 | unsigned no_ether_link:1; | 18 | unsigned no_ether_link:1; |
19 | unsigned ether_link_active_low:1; | 19 | unsigned ether_link_active_low:1; |
20 | unsigned needs_init:1; | ||
21 | }; | 20 | }; |
22 | 21 | ||
23 | #endif | 22 | #endif |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 2f8f93da5dc2..9a5ccf03a59b 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -966,7 +966,7 @@ void sctp_transport_burst_limited(struct sctp_transport *); | |||
966 | void sctp_transport_burst_reset(struct sctp_transport *); | 966 | void sctp_transport_burst_reset(struct sctp_transport *); |
967 | unsigned long sctp_transport_timeout(struct sctp_transport *); | 967 | unsigned long sctp_transport_timeout(struct sctp_transport *); |
968 | void sctp_transport_reset(struct sctp_transport *t); | 968 | void sctp_transport_reset(struct sctp_transport *t); |
969 | void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu); | 969 | bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu); |
970 | void sctp_transport_immediate_rtx(struct sctp_transport *); | 970 | void sctp_transport_immediate_rtx(struct sctp_transport *); |
971 | void sctp_transport_dst_release(struct sctp_transport *t); | 971 | void sctp_transport_dst_release(struct sctp_transport *t); |
972 | void sctp_transport_dst_confirm(struct sctp_transport *t); | 972 | void sctp_transport_dst_confirm(struct sctp_transport *t); |
diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 13223396dc64..f96391e84a8a 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h | |||
@@ -146,7 +146,7 @@ struct vxlanhdr_gpe { | |||
146 | np_applied:1, | 146 | np_applied:1, |
147 | instance_applied:1, | 147 | instance_applied:1, |
148 | version:2, | 148 | version:2, |
149 | reserved_flags2:2; | 149 | reserved_flags2:2; |
150 | #elif defined(__BIG_ENDIAN_BITFIELD) | 150 | #elif defined(__BIG_ENDIAN_BITFIELD) |
151 | u8 reserved_flags2:2, | 151 | u8 reserved_flags2:2, |
152 | version:2, | 152 | version:2, |
diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h index d1aaf876cd26..082224275f52 100644 --- a/include/sound/soc-acpi.h +++ b/include/sound/soc-acpi.h | |||
@@ -27,17 +27,13 @@ struct snd_soc_acpi_package_context { | |||
27 | bool data_valid; | 27 | bool data_valid; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | /* codec name is used in DAIs is i2c-<HID>:00 with HID being 8 chars */ | ||
31 | #define SND_ACPI_I2C_ID_LEN (4 + ACPI_ID_LEN + 3 + 1) | ||
32 | |||
30 | #if IS_ENABLED(CONFIG_ACPI) | 33 | #if IS_ENABLED(CONFIG_ACPI) |
31 | /* translation fron HID to I2C name, needed for DAI codec_name */ | ||
32 | const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]); | ||
33 | bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | 34 | bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], |
34 | struct snd_soc_acpi_package_context *ctx); | 35 | struct snd_soc_acpi_package_context *ctx); |
35 | #else | 36 | #else |
36 | static inline const char * | ||
37 | snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) | ||
38 | { | ||
39 | return NULL; | ||
40 | } | ||
41 | static inline bool | 37 | static inline bool |
42 | snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | 38 | snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], |
43 | struct snd_soc_acpi_package_context *ctx) | 39 | struct snd_soc_acpi_package_context *ctx) |
diff --git a/include/sound/soc.h b/include/sound/soc.h index a34aa200e113..b655d987fbe7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -804,6 +804,9 @@ struct snd_soc_component_driver { | |||
804 | int (*suspend)(struct snd_soc_component *); | 804 | int (*suspend)(struct snd_soc_component *); |
805 | int (*resume)(struct snd_soc_component *); | 805 | int (*resume)(struct snd_soc_component *); |
806 | 806 | ||
807 | unsigned int (*read)(struct snd_soc_component *, unsigned int); | ||
808 | int (*write)(struct snd_soc_component *, unsigned int, unsigned int); | ||
809 | |||
807 | /* pcm creation and destruction */ | 810 | /* pcm creation and destruction */ |
808 | int (*pcm_new)(struct snd_soc_pcm_runtime *); | 811 | int (*pcm_new)(struct snd_soc_pcm_runtime *); |
809 | void (*pcm_free)(struct snd_pcm *); | 812 | void (*pcm_free)(struct snd_pcm *); |
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 3ee3bf7c8526..144de4d2f385 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #define _UAPI_LINUX_IF_ETHER_H | 23 | #define _UAPI_LINUX_IF_ETHER_H |
24 | 24 | ||
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/libc-compat.h> | ||
26 | 27 | ||
27 | /* | 28 | /* |
28 | * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble | 29 | * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble |
@@ -149,11 +150,13 @@ | |||
149 | * This is an Ethernet frame header. | 150 | * This is an Ethernet frame header. |
150 | */ | 151 | */ |
151 | 152 | ||
153 | #if __UAPI_DEF_ETHHDR | ||
152 | struct ethhdr { | 154 | struct ethhdr { |
153 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ | 155 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ |
154 | unsigned char h_source[ETH_ALEN]; /* source ether addr */ | 156 | unsigned char h_source[ETH_ALEN]; /* source ether addr */ |
155 | __be16 h_proto; /* packet type ID field */ | 157 | __be16 h_proto; /* packet type ID field */ |
156 | } __attribute__((packed)); | 158 | } __attribute__((packed)); |
159 | #endif | ||
157 | 160 | ||
158 | 161 | ||
159 | #endif /* _UAPI_LINUX_IF_ETHER_H */ | 162 | #endif /* _UAPI_LINUX_IF_ETHER_H */ |
diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h index 282875cf8056..fc29efaa918c 100644 --- a/include/uapi/linux/libc-compat.h +++ b/include/uapi/linux/libc-compat.h | |||
@@ -168,47 +168,106 @@ | |||
168 | 168 | ||
169 | /* If we did not see any headers from any supported C libraries, | 169 | /* If we did not see any headers from any supported C libraries, |
170 | * or we are being included in the kernel, then define everything | 170 | * or we are being included in the kernel, then define everything |
171 | * that we need. */ | 171 | * that we need. Check for previous __UAPI_* definitions to give |
172 | * unsupported C libraries a way to opt out of any kernel definition. */ | ||
172 | #else /* !defined(__GLIBC__) */ | 173 | #else /* !defined(__GLIBC__) */ |
173 | 174 | ||
174 | /* Definitions for if.h */ | 175 | /* Definitions for if.h */ |
176 | #ifndef __UAPI_DEF_IF_IFCONF | ||
175 | #define __UAPI_DEF_IF_IFCONF 1 | 177 | #define __UAPI_DEF_IF_IFCONF 1 |
178 | #endif | ||
179 | #ifndef __UAPI_DEF_IF_IFMAP | ||
176 | #define __UAPI_DEF_IF_IFMAP 1 | 180 | #define __UAPI_DEF_IF_IFMAP 1 |
181 | #endif | ||
182 | #ifndef __UAPI_DEF_IF_IFNAMSIZ | ||
177 | #define __UAPI_DEF_IF_IFNAMSIZ 1 | 183 | #define __UAPI_DEF_IF_IFNAMSIZ 1 |
184 | #endif | ||
185 | #ifndef __UAPI_DEF_IF_IFREQ | ||
178 | #define __UAPI_DEF_IF_IFREQ 1 | 186 | #define __UAPI_DEF_IF_IFREQ 1 |
187 | #endif | ||
179 | /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ | 188 | /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ |
189 | #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS | ||
180 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 | 190 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 |
191 | #endif | ||
181 | /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ | 192 | /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ |
193 | #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO | ||
182 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 | 194 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 |
195 | #endif | ||
183 | 196 | ||
184 | /* Definitions for in.h */ | 197 | /* Definitions for in.h */ |
198 | #ifndef __UAPI_DEF_IN_ADDR | ||
185 | #define __UAPI_DEF_IN_ADDR 1 | 199 | #define __UAPI_DEF_IN_ADDR 1 |
200 | #endif | ||
201 | #ifndef __UAPI_DEF_IN_IPPROTO | ||
186 | #define __UAPI_DEF_IN_IPPROTO 1 | 202 | #define __UAPI_DEF_IN_IPPROTO 1 |
203 | #endif | ||
204 | #ifndef __UAPI_DEF_IN_PKTINFO | ||
187 | #define __UAPI_DEF_IN_PKTINFO 1 | 205 | #define __UAPI_DEF_IN_PKTINFO 1 |
206 | #endif | ||
207 | #ifndef __UAPI_DEF_IP_MREQ | ||
188 | #define __UAPI_DEF_IP_MREQ 1 | 208 | #define __UAPI_DEF_IP_MREQ 1 |
209 | #endif | ||
210 | #ifndef __UAPI_DEF_SOCKADDR_IN | ||
189 | #define __UAPI_DEF_SOCKADDR_IN 1 | 211 | #define __UAPI_DEF_SOCKADDR_IN 1 |
212 | #endif | ||
213 | #ifndef __UAPI_DEF_IN_CLASS | ||
190 | #define __UAPI_DEF_IN_CLASS 1 | 214 | #define __UAPI_DEF_IN_CLASS 1 |
215 | #endif | ||
191 | 216 | ||
192 | /* Definitions for in6.h */ | 217 | /* Definitions for in6.h */ |
218 | #ifndef __UAPI_DEF_IN6_ADDR | ||
193 | #define __UAPI_DEF_IN6_ADDR 1 | 219 | #define __UAPI_DEF_IN6_ADDR 1 |
220 | #endif | ||
221 | #ifndef __UAPI_DEF_IN6_ADDR_ALT | ||
194 | #define __UAPI_DEF_IN6_ADDR_ALT 1 | 222 | #define __UAPI_DEF_IN6_ADDR_ALT 1 |
223 | #endif | ||
224 | #ifndef __UAPI_DEF_SOCKADDR_IN6 | ||
195 | #define __UAPI_DEF_SOCKADDR_IN6 1 | 225 | #define __UAPI_DEF_SOCKADDR_IN6 1 |
226 | #endif | ||
227 | #ifndef __UAPI_DEF_IPV6_MREQ | ||
196 | #define __UAPI_DEF_IPV6_MREQ 1 | 228 | #define __UAPI_DEF_IPV6_MREQ 1 |
229 | #endif | ||
230 | #ifndef __UAPI_DEF_IPPROTO_V6 | ||
197 | #define __UAPI_DEF_IPPROTO_V6 1 | 231 | #define __UAPI_DEF_IPPROTO_V6 1 |
232 | #endif | ||
233 | #ifndef __UAPI_DEF_IPV6_OPTIONS | ||
198 | #define __UAPI_DEF_IPV6_OPTIONS 1 | 234 | #define __UAPI_DEF_IPV6_OPTIONS 1 |
235 | #endif | ||
236 | #ifndef __UAPI_DEF_IN6_PKTINFO | ||
199 | #define __UAPI_DEF_IN6_PKTINFO 1 | 237 | #define __UAPI_DEF_IN6_PKTINFO 1 |
238 | #endif | ||
239 | #ifndef __UAPI_DEF_IP6_MTUINFO | ||
200 | #define __UAPI_DEF_IP6_MTUINFO 1 | 240 | #define __UAPI_DEF_IP6_MTUINFO 1 |
241 | #endif | ||
201 | 242 | ||
202 | /* Definitions for ipx.h */ | 243 | /* Definitions for ipx.h */ |
244 | #ifndef __UAPI_DEF_SOCKADDR_IPX | ||
203 | #define __UAPI_DEF_SOCKADDR_IPX 1 | 245 | #define __UAPI_DEF_SOCKADDR_IPX 1 |
246 | #endif | ||
247 | #ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION | ||
204 | #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 | 248 | #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 |
249 | #endif | ||
250 | #ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION | ||
205 | #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 | 251 | #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 |
252 | #endif | ||
253 | #ifndef __UAPI_DEF_IPX_CONFIG_DATA | ||
206 | #define __UAPI_DEF_IPX_CONFIG_DATA 1 | 254 | #define __UAPI_DEF_IPX_CONFIG_DATA 1 |
255 | #endif | ||
256 | #ifndef __UAPI_DEF_IPX_ROUTE_DEF | ||
207 | #define __UAPI_DEF_IPX_ROUTE_DEF 1 | 257 | #define __UAPI_DEF_IPX_ROUTE_DEF 1 |
258 | #endif | ||
208 | 259 | ||
209 | /* Definitions for xattr.h */ | 260 | /* Definitions for xattr.h */ |
261 | #ifndef __UAPI_DEF_XATTR | ||
210 | #define __UAPI_DEF_XATTR 1 | 262 | #define __UAPI_DEF_XATTR 1 |
263 | #endif | ||
211 | 264 | ||
212 | #endif /* __GLIBC__ */ | 265 | #endif /* __GLIBC__ */ |
213 | 266 | ||
267 | /* Definitions for if_ether.h */ | ||
268 | /* allow libcs like musl to deactivate this, glibc does not implement this. */ | ||
269 | #ifndef __UAPI_DEF_ETHHDR | ||
270 | #define __UAPI_DEF_ETHHDR 1 | ||
271 | #endif | ||
272 | |||
214 | #endif /* _UAPI_LIBC_COMPAT_H */ | 273 | #endif /* _UAPI_LIBC_COMPAT_H */ |
diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h index 3fea7709a441..57ccfb32e87f 100644 --- a/include/uapi/linux/netfilter/nf_conntrack_common.h +++ b/include/uapi/linux/netfilter/nf_conntrack_common.h | |||
@@ -36,7 +36,7 @@ enum ip_conntrack_info { | |||
36 | 36 | ||
37 | #define NF_CT_STATE_INVALID_BIT (1 << 0) | 37 | #define NF_CT_STATE_INVALID_BIT (1 << 0) |
38 | #define NF_CT_STATE_BIT(ctinfo) (1 << ((ctinfo) % IP_CT_IS_REPLY + 1)) | 38 | #define NF_CT_STATE_BIT(ctinfo) (1 << ((ctinfo) % IP_CT_IS_REPLY + 1)) |
39 | #define NF_CT_STATE_UNTRACKED_BIT (1 << (IP_CT_UNTRACKED + 1)) | 39 | #define NF_CT_STATE_UNTRACKED_BIT (1 << 6) |
40 | 40 | ||
41 | /* Bitset representing status of connection. */ | 41 | /* Bitset representing status of connection. */ |
42 | enum ip_conntrack_status { | 42 | enum ip_conntrack_status { |
diff --git a/init/Kconfig b/init/Kconfig index 690a381adee0..a9a2e2c86671 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -461,6 +461,7 @@ endmenu # "CPU/Task time and stats accounting" | |||
461 | 461 | ||
462 | config CPU_ISOLATION | 462 | config CPU_ISOLATION |
463 | bool "CPU isolation" | 463 | bool "CPU isolation" |
464 | depends on SMP || COMPILE_TEST | ||
464 | default y | 465 | default y |
465 | help | 466 | help |
466 | Make sure that CPUs running critical tasks are not disturbed by | 467 | Make sure that CPUs running critical tasks are not disturbed by |
@@ -1396,6 +1397,13 @@ config BPF_SYSCALL | |||
1396 | Enable the bpf() system call that allows to manipulate eBPF | 1397 | Enable the bpf() system call that allows to manipulate eBPF |
1397 | programs and maps via file descriptors. | 1398 | programs and maps via file descriptors. |
1398 | 1399 | ||
1400 | config BPF_JIT_ALWAYS_ON | ||
1401 | bool "Permanently enable BPF JIT and remove BPF interpreter" | ||
1402 | depends on BPF_SYSCALL && HAVE_EBPF_JIT && BPF_JIT | ||
1403 | help | ||
1404 | Enables BPF JIT and removes BPF interpreter to avoid | ||
1405 | speculative execution of BPF instructions by the interpreter | ||
1406 | |||
1399 | config USERFAULTFD | 1407 | config USERFAULTFD |
1400 | bool "Enable userfaultfd() system call" | 1408 | bool "Enable userfaultfd() system call" |
1401 | select ANON_INODES | 1409 | select ANON_INODES |
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 7c25426d3cf5..aaa319848e7d 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
@@ -53,9 +53,10 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | |||
53 | { | 53 | { |
54 | bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; | 54 | bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; |
55 | int numa_node = bpf_map_attr_numa_node(attr); | 55 | int numa_node = bpf_map_attr_numa_node(attr); |
56 | u32 elem_size, index_mask, max_entries; | ||
57 | bool unpriv = !capable(CAP_SYS_ADMIN); | ||
56 | struct bpf_array *array; | 58 | struct bpf_array *array; |
57 | u64 array_size; | 59 | u64 array_size; |
58 | u32 elem_size; | ||
59 | 60 | ||
60 | /* check sanity of attributes */ | 61 | /* check sanity of attributes */ |
61 | if (attr->max_entries == 0 || attr->key_size != 4 || | 62 | if (attr->max_entries == 0 || attr->key_size != 4 || |
@@ -72,11 +73,20 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | |||
72 | 73 | ||
73 | elem_size = round_up(attr->value_size, 8); | 74 | elem_size = round_up(attr->value_size, 8); |
74 | 75 | ||
76 | max_entries = attr->max_entries; | ||
77 | index_mask = roundup_pow_of_two(max_entries) - 1; | ||
78 | |||
79 | if (unpriv) | ||
80 | /* round up array size to nearest power of 2, | ||
81 | * since cpu will speculate within index_mask limits | ||
82 | */ | ||
83 | max_entries = index_mask + 1; | ||
84 | |||
75 | array_size = sizeof(*array); | 85 | array_size = sizeof(*array); |
76 | if (percpu) | 86 | if (percpu) |
77 | array_size += (u64) attr->max_entries * sizeof(void *); | 87 | array_size += (u64) max_entries * sizeof(void *); |
78 | else | 88 | else |
79 | array_size += (u64) attr->max_entries * elem_size; | 89 | array_size += (u64) max_entries * elem_size; |
80 | 90 | ||
81 | /* make sure there is no u32 overflow later in round_up() */ | 91 | /* make sure there is no u32 overflow later in round_up() */ |
82 | if (array_size >= U32_MAX - PAGE_SIZE) | 92 | if (array_size >= U32_MAX - PAGE_SIZE) |
@@ -86,6 +96,8 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | |||
86 | array = bpf_map_area_alloc(array_size, numa_node); | 96 | array = bpf_map_area_alloc(array_size, numa_node); |
87 | if (!array) | 97 | if (!array) |
88 | return ERR_PTR(-ENOMEM); | 98 | return ERR_PTR(-ENOMEM); |
99 | array->index_mask = index_mask; | ||
100 | array->map.unpriv_array = unpriv; | ||
89 | 101 | ||
90 | /* copy mandatory map attributes */ | 102 | /* copy mandatory map attributes */ |
91 | array->map.map_type = attr->map_type; | 103 | array->map.map_type = attr->map_type; |
@@ -121,12 +133,13 @@ static void *array_map_lookup_elem(struct bpf_map *map, void *key) | |||
121 | if (unlikely(index >= array->map.max_entries)) | 133 | if (unlikely(index >= array->map.max_entries)) |
122 | return NULL; | 134 | return NULL; |
123 | 135 | ||
124 | return array->value + array->elem_size * index; | 136 | return array->value + array->elem_size * (index & array->index_mask); |
125 | } | 137 | } |
126 | 138 | ||
127 | /* emit BPF instructions equivalent to C code of array_map_lookup_elem() */ | 139 | /* emit BPF instructions equivalent to C code of array_map_lookup_elem() */ |
128 | static u32 array_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) | 140 | static u32 array_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) |
129 | { | 141 | { |
142 | struct bpf_array *array = container_of(map, struct bpf_array, map); | ||
130 | struct bpf_insn *insn = insn_buf; | 143 | struct bpf_insn *insn = insn_buf; |
131 | u32 elem_size = round_up(map->value_size, 8); | 144 | u32 elem_size = round_up(map->value_size, 8); |
132 | const int ret = BPF_REG_0; | 145 | const int ret = BPF_REG_0; |
@@ -135,7 +148,12 @@ static u32 array_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) | |||
135 | 148 | ||
136 | *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, offsetof(struct bpf_array, value)); | 149 | *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, offsetof(struct bpf_array, value)); |
137 | *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); | 150 | *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); |
138 | *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 3); | 151 | if (map->unpriv_array) { |
152 | *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 4); | ||
153 | *insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->index_mask); | ||
154 | } else { | ||
155 | *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 3); | ||
156 | } | ||
139 | 157 | ||
140 | if (is_power_of_2(elem_size)) { | 158 | if (is_power_of_2(elem_size)) { |
141 | *insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(elem_size)); | 159 | *insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(elem_size)); |
@@ -157,7 +175,7 @@ static void *percpu_array_map_lookup_elem(struct bpf_map *map, void *key) | |||
157 | if (unlikely(index >= array->map.max_entries)) | 175 | if (unlikely(index >= array->map.max_entries)) |
158 | return NULL; | 176 | return NULL; |
159 | 177 | ||
160 | return this_cpu_ptr(array->pptrs[index]); | 178 | return this_cpu_ptr(array->pptrs[index & array->index_mask]); |
161 | } | 179 | } |
162 | 180 | ||
163 | int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value) | 181 | int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value) |
@@ -177,7 +195,7 @@ int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value) | |||
177 | */ | 195 | */ |
178 | size = round_up(map->value_size, 8); | 196 | size = round_up(map->value_size, 8); |
179 | rcu_read_lock(); | 197 | rcu_read_lock(); |
180 | pptr = array->pptrs[index]; | 198 | pptr = array->pptrs[index & array->index_mask]; |
181 | for_each_possible_cpu(cpu) { | 199 | for_each_possible_cpu(cpu) { |
182 | bpf_long_memcpy(value + off, per_cpu_ptr(pptr, cpu), size); | 200 | bpf_long_memcpy(value + off, per_cpu_ptr(pptr, cpu), size); |
183 | off += size; | 201 | off += size; |
@@ -225,10 +243,11 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
225 | return -EEXIST; | 243 | return -EEXIST; |
226 | 244 | ||
227 | if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) | 245 | if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) |
228 | memcpy(this_cpu_ptr(array->pptrs[index]), | 246 | memcpy(this_cpu_ptr(array->pptrs[index & array->index_mask]), |
229 | value, map->value_size); | 247 | value, map->value_size); |
230 | else | 248 | else |
231 | memcpy(array->value + array->elem_size * index, | 249 | memcpy(array->value + |
250 | array->elem_size * (index & array->index_mask), | ||
232 | value, map->value_size); | 251 | value, map->value_size); |
233 | return 0; | 252 | return 0; |
234 | } | 253 | } |
@@ -262,7 +281,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value, | |||
262 | */ | 281 | */ |
263 | size = round_up(map->value_size, 8); | 282 | size = round_up(map->value_size, 8); |
264 | rcu_read_lock(); | 283 | rcu_read_lock(); |
265 | pptr = array->pptrs[index]; | 284 | pptr = array->pptrs[index & array->index_mask]; |
266 | for_each_possible_cpu(cpu) { | 285 | for_each_possible_cpu(cpu) { |
267 | bpf_long_memcpy(per_cpu_ptr(pptr, cpu), value + off, size); | 286 | bpf_long_memcpy(per_cpu_ptr(pptr, cpu), value + off, size); |
268 | off += size; | 287 | off += size; |
@@ -613,6 +632,7 @@ static void *array_of_map_lookup_elem(struct bpf_map *map, void *key) | |||
613 | static u32 array_of_map_gen_lookup(struct bpf_map *map, | 632 | static u32 array_of_map_gen_lookup(struct bpf_map *map, |
614 | struct bpf_insn *insn_buf) | 633 | struct bpf_insn *insn_buf) |
615 | { | 634 | { |
635 | struct bpf_array *array = container_of(map, struct bpf_array, map); | ||
616 | u32 elem_size = round_up(map->value_size, 8); | 636 | u32 elem_size = round_up(map->value_size, 8); |
617 | struct bpf_insn *insn = insn_buf; | 637 | struct bpf_insn *insn = insn_buf; |
618 | const int ret = BPF_REG_0; | 638 | const int ret = BPF_REG_0; |
@@ -621,7 +641,12 @@ static u32 array_of_map_gen_lookup(struct bpf_map *map, | |||
621 | 641 | ||
622 | *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, offsetof(struct bpf_array, value)); | 642 | *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, offsetof(struct bpf_array, value)); |
623 | *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); | 643 | *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); |
624 | *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5); | 644 | if (map->unpriv_array) { |
645 | *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 6); | ||
646 | *insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->index_mask); | ||
647 | } else { | ||
648 | *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5); | ||
649 | } | ||
625 | if (is_power_of_2(elem_size)) | 650 | if (is_power_of_2(elem_size)) |
626 | *insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(elem_size)); | 651 | *insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(elem_size)); |
627 | else | 652 | else |
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 86b50aa26ee8..51ec2dda7f08 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
@@ -767,6 +767,7 @@ noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | |||
767 | } | 767 | } |
768 | EXPORT_SYMBOL_GPL(__bpf_call_base); | 768 | EXPORT_SYMBOL_GPL(__bpf_call_base); |
769 | 769 | ||
770 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON | ||
770 | /** | 771 | /** |
771 | * __bpf_prog_run - run eBPF program on a given context | 772 | * __bpf_prog_run - run eBPF program on a given context |
772 | * @ctx: is the data we are operating on | 773 | * @ctx: is the data we are operating on |
@@ -1317,6 +1318,14 @@ EVAL6(PROG_NAME_LIST, 224, 256, 288, 320, 352, 384) | |||
1317 | EVAL4(PROG_NAME_LIST, 416, 448, 480, 512) | 1318 | EVAL4(PROG_NAME_LIST, 416, 448, 480, 512) |
1318 | }; | 1319 | }; |
1319 | 1320 | ||
1321 | #else | ||
1322 | static unsigned int __bpf_prog_ret0(const void *ctx, | ||
1323 | const struct bpf_insn *insn) | ||
1324 | { | ||
1325 | return 0; | ||
1326 | } | ||
1327 | #endif | ||
1328 | |||
1320 | bool bpf_prog_array_compatible(struct bpf_array *array, | 1329 | bool bpf_prog_array_compatible(struct bpf_array *array, |
1321 | const struct bpf_prog *fp) | 1330 | const struct bpf_prog *fp) |
1322 | { | 1331 | { |
@@ -1364,9 +1373,13 @@ static int bpf_check_tail_call(const struct bpf_prog *fp) | |||
1364 | */ | 1373 | */ |
1365 | struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) | 1374 | struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) |
1366 | { | 1375 | { |
1376 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON | ||
1367 | u32 stack_depth = max_t(u32, fp->aux->stack_depth, 1); | 1377 | u32 stack_depth = max_t(u32, fp->aux->stack_depth, 1); |
1368 | 1378 | ||
1369 | fp->bpf_func = interpreters[(round_up(stack_depth, 32) / 32) - 1]; | 1379 | fp->bpf_func = interpreters[(round_up(stack_depth, 32) / 32) - 1]; |
1380 | #else | ||
1381 | fp->bpf_func = __bpf_prog_ret0; | ||
1382 | #endif | ||
1370 | 1383 | ||
1371 | /* eBPF JITs can rewrite the program in case constant | 1384 | /* eBPF JITs can rewrite the program in case constant |
1372 | * blinding is active. However, in case of error during | 1385 | * blinding is active. However, in case of error during |
@@ -1376,6 +1389,12 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) | |||
1376 | */ | 1389 | */ |
1377 | if (!bpf_prog_is_dev_bound(fp->aux)) { | 1390 | if (!bpf_prog_is_dev_bound(fp->aux)) { |
1378 | fp = bpf_int_jit_compile(fp); | 1391 | fp = bpf_int_jit_compile(fp); |
1392 | #ifdef CONFIG_BPF_JIT_ALWAYS_ON | ||
1393 | if (!fp->jited) { | ||
1394 | *err = -ENOTSUPP; | ||
1395 | return fp; | ||
1396 | } | ||
1397 | #endif | ||
1379 | } else { | 1398 | } else { |
1380 | *err = bpf_prog_offload_compile(fp); | 1399 | *err = bpf_prog_offload_compile(fp); |
1381 | if (*err) | 1400 | if (*err) |
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index 5ee2e41893d9..1712d319c2d8 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c | |||
@@ -591,8 +591,15 @@ static void sock_map_free(struct bpf_map *map) | |||
591 | 591 | ||
592 | write_lock_bh(&sock->sk_callback_lock); | 592 | write_lock_bh(&sock->sk_callback_lock); |
593 | psock = smap_psock_sk(sock); | 593 | psock = smap_psock_sk(sock); |
594 | smap_list_remove(psock, &stab->sock_map[i]); | 594 | /* This check handles a racing sock event that can get the |
595 | smap_release_sock(psock, sock); | 595 | * sk_callback_lock before this case but after xchg happens |
596 | * causing the refcnt to hit zero and sock user data (psock) | ||
597 | * to be null and queued for garbage collection. | ||
598 | */ | ||
599 | if (likely(psock)) { | ||
600 | smap_list_remove(psock, &stab->sock_map[i]); | ||
601 | smap_release_sock(psock, sock); | ||
602 | } | ||
596 | write_unlock_bh(&sock->sk_callback_lock); | 603 | write_unlock_bh(&sock->sk_callback_lock); |
597 | } | 604 | } |
598 | rcu_read_unlock(); | 605 | rcu_read_unlock(); |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 04b24876cd23..b414d6b2d470 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -1729,6 +1729,13 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) | |||
1729 | err = check_func_arg(env, BPF_REG_2, fn->arg2_type, &meta); | 1729 | err = check_func_arg(env, BPF_REG_2, fn->arg2_type, &meta); |
1730 | if (err) | 1730 | if (err) |
1731 | return err; | 1731 | return err; |
1732 | if (func_id == BPF_FUNC_tail_call) { | ||
1733 | if (meta.map_ptr == NULL) { | ||
1734 | verbose(env, "verifier bug\n"); | ||
1735 | return -EINVAL; | ||
1736 | } | ||
1737 | env->insn_aux_data[insn_idx].map_ptr = meta.map_ptr; | ||
1738 | } | ||
1732 | err = check_func_arg(env, BPF_REG_3, fn->arg3_type, &meta); | 1739 | err = check_func_arg(env, BPF_REG_3, fn->arg3_type, &meta); |
1733 | if (err) | 1740 | if (err) |
1734 | return err; | 1741 | return err; |
@@ -4456,6 +4463,35 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) | |||
4456 | */ | 4463 | */ |
4457 | insn->imm = 0; | 4464 | insn->imm = 0; |
4458 | insn->code = BPF_JMP | BPF_TAIL_CALL; | 4465 | insn->code = BPF_JMP | BPF_TAIL_CALL; |
4466 | |||
4467 | /* instead of changing every JIT dealing with tail_call | ||
4468 | * emit two extra insns: | ||
4469 | * if (index >= max_entries) goto out; | ||
4470 | * index &= array->index_mask; | ||
4471 | * to avoid out-of-bounds cpu speculation | ||
4472 | */ | ||
4473 | map_ptr = env->insn_aux_data[i + delta].map_ptr; | ||
4474 | if (map_ptr == BPF_MAP_PTR_POISON) { | ||
4475 | verbose(env, "tail_call obusing map_ptr\n"); | ||
4476 | return -EINVAL; | ||
4477 | } | ||
4478 | if (!map_ptr->unpriv_array) | ||
4479 | continue; | ||
4480 | insn_buf[0] = BPF_JMP_IMM(BPF_JGE, BPF_REG_3, | ||
4481 | map_ptr->max_entries, 2); | ||
4482 | insn_buf[1] = BPF_ALU32_IMM(BPF_AND, BPF_REG_3, | ||
4483 | container_of(map_ptr, | ||
4484 | struct bpf_array, | ||
4485 | map)->index_mask); | ||
4486 | insn_buf[2] = *insn; | ||
4487 | cnt = 3; | ||
4488 | new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); | ||
4489 | if (!new_prog) | ||
4490 | return -ENOMEM; | ||
4491 | |||
4492 | delta += cnt - 1; | ||
4493 | env->prog = prog = new_prog; | ||
4494 | insn = new_prog->insnsi + i + delta; | ||
4459 | continue; | 4495 | continue; |
4460 | } | 4496 | } |
4461 | 4497 | ||
diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 024085daab1a..a2c05d2476ac 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c | |||
@@ -123,7 +123,11 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) | |||
123 | */ | 123 | */ |
124 | do { | 124 | do { |
125 | css_task_iter_start(&from->self, 0, &it); | 125 | css_task_iter_start(&from->self, 0, &it); |
126 | task = css_task_iter_next(&it); | 126 | |
127 | do { | ||
128 | task = css_task_iter_next(&it); | ||
129 | } while (task && (task->flags & PF_EXITING)); | ||
130 | |||
127 | if (task) | 131 | if (task) |
128 | get_task_struct(task); | 132 | get_task_struct(task); |
129 | css_task_iter_end(&it); | 133 | css_task_iter_end(&it); |
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 0b1ffe147f24..2cf06c274e4c 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c | |||
@@ -1397,7 +1397,7 @@ static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, | |||
1397 | cgroup_on_dfl(cgrp) ? ss->name : ss->legacy_name, | 1397 | cgroup_on_dfl(cgrp) ? ss->name : ss->legacy_name, |
1398 | cft->name); | 1398 | cft->name); |
1399 | else | 1399 | else |
1400 | strncpy(buf, cft->name, CGROUP_FILE_NAME_MAX); | 1400 | strlcpy(buf, cft->name, CGROUP_FILE_NAME_MAX); |
1401 | return buf; | 1401 | return buf; |
1402 | } | 1402 | } |
1403 | 1403 | ||
@@ -1864,9 +1864,9 @@ void init_cgroup_root(struct cgroup_root *root, struct cgroup_sb_opts *opts) | |||
1864 | 1864 | ||
1865 | root->flags = opts->flags; | 1865 | root->flags = opts->flags; |
1866 | if (opts->release_agent) | 1866 | if (opts->release_agent) |
1867 | strcpy(root->release_agent_path, opts->release_agent); | 1867 | strlcpy(root->release_agent_path, opts->release_agent, PATH_MAX); |
1868 | if (opts->name) | 1868 | if (opts->name) |
1869 | strcpy(root->name, opts->name); | 1869 | strlcpy(root->name, opts->name, MAX_CGROUP_ROOT_NAMELEN); |
1870 | if (opts->cpuset_clone_children) | 1870 | if (opts->cpuset_clone_children) |
1871 | set_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->cgrp.flags); | 1871 | set_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->cgrp.flags); |
1872 | } | 1872 | } |
@@ -4125,26 +4125,24 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it) | |||
4125 | 4125 | ||
4126 | static void css_task_iter_advance(struct css_task_iter *it) | 4126 | static void css_task_iter_advance(struct css_task_iter *it) |
4127 | { | 4127 | { |
4128 | struct list_head *l = it->task_pos; | 4128 | struct list_head *next; |
4129 | 4129 | ||
4130 | lockdep_assert_held(&css_set_lock); | 4130 | lockdep_assert_held(&css_set_lock); |
4131 | WARN_ON_ONCE(!l); | ||
4132 | |||
4133 | repeat: | 4131 | repeat: |
4134 | /* | 4132 | /* |
4135 | * Advance iterator to find next entry. cset->tasks is consumed | 4133 | * Advance iterator to find next entry. cset->tasks is consumed |
4136 | * first and then ->mg_tasks. After ->mg_tasks, we move onto the | 4134 | * first and then ->mg_tasks. After ->mg_tasks, we move onto the |
4137 | * next cset. | 4135 | * next cset. |
4138 | */ | 4136 | */ |
4139 | l = l->next; | 4137 | next = it->task_pos->next; |
4140 | 4138 | ||
4141 | if (l == it->tasks_head) | 4139 | if (next == it->tasks_head) |
4142 | l = it->mg_tasks_head->next; | 4140 | next = it->mg_tasks_head->next; |
4143 | 4141 | ||
4144 | if (l == it->mg_tasks_head) | 4142 | if (next == it->mg_tasks_head) |
4145 | css_task_iter_advance_css_set(it); | 4143 | css_task_iter_advance_css_set(it); |
4146 | else | 4144 | else |
4147 | it->task_pos = l; | 4145 | it->task_pos = next; |
4148 | 4146 | ||
4149 | /* if PROCS, skip over tasks which aren't group leaders */ | 4147 | /* if PROCS, skip over tasks which aren't group leaders */ |
4150 | if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos && | 4148 | if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos && |
diff --git a/kernel/crash_core.c b/kernel/crash_core.c index b3663896278e..4f63597c824d 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c | |||
@@ -410,7 +410,7 @@ static int __init crash_save_vmcoreinfo_init(void) | |||
410 | VMCOREINFO_SYMBOL(contig_page_data); | 410 | VMCOREINFO_SYMBOL(contig_page_data); |
411 | #endif | 411 | #endif |
412 | #ifdef CONFIG_SPARSEMEM | 412 | #ifdef CONFIG_SPARSEMEM |
413 | VMCOREINFO_SYMBOL(mem_section); | 413 | VMCOREINFO_SYMBOL_ARRAY(mem_section); |
414 | VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS); | 414 | VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS); |
415 | VMCOREINFO_STRUCT_SIZE(mem_section); | 415 | VMCOREINFO_STRUCT_SIZE(mem_section); |
416 | VMCOREINFO_OFFSET(mem_section, section_mem_map); | 416 | VMCOREINFO_OFFSET(mem_section, section_mem_map); |
diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c index 2ddaec40956f..0926aef10dad 100644 --- a/kernel/sched/completion.c +++ b/kernel/sched/completion.c | |||
@@ -34,11 +34,6 @@ void complete(struct completion *x) | |||
34 | 34 | ||
35 | spin_lock_irqsave(&x->wait.lock, flags); | 35 | spin_lock_irqsave(&x->wait.lock, flags); |
36 | 36 | ||
37 | /* | ||
38 | * Perform commit of crossrelease here. | ||
39 | */ | ||
40 | complete_release_commit(x); | ||
41 | |||
42 | if (x->done != UINT_MAX) | 37 | if (x->done != UINT_MAX) |
43 | x->done++; | 38 | x->done++; |
44 | __wake_up_locked(&x->wait, TASK_NORMAL, 1); | 39 | __wake_up_locked(&x->wait, TASK_NORMAL, 1); |
diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c index dd7908743dab..9bcbacba82a8 100644 --- a/kernel/sched/membarrier.c +++ b/kernel/sched/membarrier.c | |||
@@ -89,7 +89,9 @@ static int membarrier_private_expedited(void) | |||
89 | rcu_read_unlock(); | 89 | rcu_read_unlock(); |
90 | } | 90 | } |
91 | if (!fallback) { | 91 | if (!fallback) { |
92 | preempt_disable(); | ||
92 | smp_call_function_many(tmpmask, ipi_mb, NULL, 1); | 93 | smp_call_function_many(tmpmask, ipi_mb, NULL, 1); |
94 | preempt_enable(); | ||
93 | free_cpumask_var(tmpmask); | 95 | free_cpumask_var(tmpmask); |
94 | } | 96 | } |
95 | cpus_read_unlock(); | 97 | cpus_read_unlock(); |
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 9e9748089270..f369889e521d 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c | |||
@@ -6250,9 +6250,8 @@ static struct bpf_prog *generate_filter(int which, int *err) | |||
6250 | return NULL; | 6250 | return NULL; |
6251 | } | 6251 | } |
6252 | } | 6252 | } |
6253 | /* We don't expect to fail. */ | ||
6254 | if (*err) { | 6253 | if (*err) { |
6255 | pr_cont("FAIL to attach err=%d len=%d\n", | 6254 | pr_cont("FAIL to prog_create err=%d len=%d\n", |
6256 | *err, fprog.len); | 6255 | *err, fprog.len); |
6257 | return NULL; | 6256 | return NULL; |
6258 | } | 6257 | } |
@@ -6276,6 +6275,10 @@ static struct bpf_prog *generate_filter(int which, int *err) | |||
6276 | * checks. | 6275 | * checks. |
6277 | */ | 6276 | */ |
6278 | fp = bpf_prog_select_runtime(fp, err); | 6277 | fp = bpf_prog_select_runtime(fp, err); |
6278 | if (*err) { | ||
6279 | pr_cont("FAIL to select_runtime err=%d\n", *err); | ||
6280 | return NULL; | ||
6281 | } | ||
6279 | break; | 6282 | break; |
6280 | } | 6283 | } |
6281 | 6284 | ||
@@ -6461,8 +6464,8 @@ static __init int test_bpf(void) | |||
6461 | pass_cnt++; | 6464 | pass_cnt++; |
6462 | continue; | 6465 | continue; |
6463 | } | 6466 | } |
6464 | 6467 | err_cnt++; | |
6465 | return err; | 6468 | continue; |
6466 | } | 6469 | } |
6467 | 6470 | ||
6468 | pr_cont("jited:%u ", fp->jited); | 6471 | pr_cont("jited:%u ", fp->jited); |
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index d73c14294f3a..f656ca27f6c2 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -127,7 +127,7 @@ | |||
127 | /* GFP bitmask for kmemleak internal allocations */ | 127 | /* GFP bitmask for kmemleak internal allocations */ |
128 | #define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \ | 128 | #define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \ |
129 | __GFP_NORETRY | __GFP_NOMEMALLOC | \ | 129 | __GFP_NORETRY | __GFP_NOMEMALLOC | \ |
130 | __GFP_NOWARN) | 130 | __GFP_NOWARN | __GFP_NOFAIL) |
131 | 131 | ||
132 | /* scanning area inside a memory block */ | 132 | /* scanning area inside a memory block */ |
133 | struct kmemleak_scan_area { | 133 | struct kmemleak_scan_area { |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 8dfdd94e430f..bad01b14a4ad 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -111,12 +111,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
111 | vlan_gvrp_uninit_applicant(real_dev); | 111 | vlan_gvrp_uninit_applicant(real_dev); |
112 | } | 112 | } |
113 | 113 | ||
114 | /* Take it out of our own structures, but be sure to interlock with | 114 | vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); |
115 | * HW accelerating devices or SW vlan input packet processing if | ||
116 | * VLAN is not 0 (leave it there for 802.1p). | ||
117 | */ | ||
118 | if (vlan_id) | ||
119 | vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); | ||
120 | 115 | ||
121 | /* Get rid of the vlan's reference to real_dev */ | 116 | /* Get rid of the vlan's reference to real_dev */ |
122 | dev_put(real_dev); | 117 | dev_put(real_dev); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 43ba91c440bc..fc6615d59165 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3363,9 +3363,10 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data | |||
3363 | break; | 3363 | break; |
3364 | 3364 | ||
3365 | case L2CAP_CONF_EFS: | 3365 | case L2CAP_CONF_EFS: |
3366 | remote_efs = 1; | 3366 | if (olen == sizeof(efs)) { |
3367 | if (olen == sizeof(efs)) | 3367 | remote_efs = 1; |
3368 | memcpy(&efs, (void *) val, olen); | 3368 | memcpy(&efs, (void *) val, olen); |
3369 | } | ||
3369 | break; | 3370 | break; |
3370 | 3371 | ||
3371 | case L2CAP_CONF_EWS: | 3372 | case L2CAP_CONF_EWS: |
@@ -3584,16 +3585,17 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, | |||
3584 | break; | 3585 | break; |
3585 | 3586 | ||
3586 | case L2CAP_CONF_EFS: | 3587 | case L2CAP_CONF_EFS: |
3587 | if (olen == sizeof(efs)) | 3588 | if (olen == sizeof(efs)) { |
3588 | memcpy(&efs, (void *)val, olen); | 3589 | memcpy(&efs, (void *)val, olen); |
3589 | 3590 | ||
3590 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | 3591 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && |
3591 | efs.stype != L2CAP_SERV_NOTRAFIC && | 3592 | efs.stype != L2CAP_SERV_NOTRAFIC && |
3592 | efs.stype != chan->local_stype) | 3593 | efs.stype != chan->local_stype) |
3593 | return -ECONNREFUSED; | 3594 | return -ECONNREFUSED; |
3594 | 3595 | ||
3595 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), | 3596 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), |
3596 | (unsigned long) &efs, endptr - ptr); | 3597 | (unsigned long) &efs, endptr - ptr); |
3598 | } | ||
3597 | break; | 3599 | break; |
3598 | 3600 | ||
3599 | case L2CAP_CONF_FCS: | 3601 | case L2CAP_CONF_FCS: |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 2d38b6e34203..e0adcd123f48 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
@@ -334,9 +334,8 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, | |||
334 | mutex_lock(&caifdevs->lock); | 334 | mutex_lock(&caifdevs->lock); |
335 | list_add_rcu(&caifd->list, &caifdevs->list); | 335 | list_add_rcu(&caifd->list, &caifdevs->list); |
336 | 336 | ||
337 | strncpy(caifd->layer.name, dev->name, | 337 | strlcpy(caifd->layer.name, dev->name, |
338 | sizeof(caifd->layer.name) - 1); | 338 | sizeof(caifd->layer.name)); |
339 | caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0; | ||
340 | caifd->layer.transmit = transmit; | 339 | caifd->layer.transmit = transmit; |
341 | cfcnfg_add_phy_layer(cfg, | 340 | cfcnfg_add_phy_layer(cfg, |
342 | dev, | 341 | dev, |
diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c index 5cd44f001f64..1a082a946045 100644 --- a/net/caif/caif_usb.c +++ b/net/caif/caif_usb.c | |||
@@ -176,9 +176,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, | |||
176 | dev_add_pack(&caif_usb_type); | 176 | dev_add_pack(&caif_usb_type); |
177 | pack_added = true; | 177 | pack_added = true; |
178 | 178 | ||
179 | strncpy(layer->name, dev->name, | 179 | strlcpy(layer->name, dev->name, sizeof(layer->name)); |
180 | sizeof(layer->name) - 1); | ||
181 | layer->name[sizeof(layer->name) - 1] = 0; | ||
182 | 180 | ||
183 | return 0; | 181 | return 0; |
184 | } | 182 | } |
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 273cb07f57d8..8f00bea093b9 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
@@ -268,17 +268,15 @@ static int caif_connect_req_to_link_param(struct cfcnfg *cnfg, | |||
268 | case CAIFPROTO_RFM: | 268 | case CAIFPROTO_RFM: |
269 | l->linktype = CFCTRL_SRV_RFM; | 269 | l->linktype = CFCTRL_SRV_RFM; |
270 | l->u.datagram.connid = s->sockaddr.u.rfm.connection_id; | 270 | l->u.datagram.connid = s->sockaddr.u.rfm.connection_id; |
271 | strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume, | 271 | strlcpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume, |
272 | sizeof(l->u.rfm.volume)-1); | 272 | sizeof(l->u.rfm.volume)); |
273 | l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0; | ||
274 | break; | 273 | break; |
275 | case CAIFPROTO_UTIL: | 274 | case CAIFPROTO_UTIL: |
276 | l->linktype = CFCTRL_SRV_UTIL; | 275 | l->linktype = CFCTRL_SRV_UTIL; |
277 | l->endpoint = 0x00; | 276 | l->endpoint = 0x00; |
278 | l->chtype = 0x00; | 277 | l->chtype = 0x00; |
279 | strncpy(l->u.utility.name, s->sockaddr.u.util.service, | 278 | strlcpy(l->u.utility.name, s->sockaddr.u.util.service, |
280 | sizeof(l->u.utility.name)-1); | 279 | sizeof(l->u.utility.name)); |
281 | l->u.utility.name[sizeof(l->u.utility.name)-1] = 0; | ||
282 | caif_assert(sizeof(l->u.utility.name) > 10); | 280 | caif_assert(sizeof(l->u.utility.name) > 10); |
283 | l->u.utility.paramlen = s->param.size; | 281 | l->u.utility.paramlen = s->param.size; |
284 | if (l->u.utility.paramlen > sizeof(l->u.utility.params)) | 282 | if (l->u.utility.paramlen > sizeof(l->u.utility.params)) |
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index f5afda1abc76..655ed7032150 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
@@ -258,8 +258,8 @@ int cfctrl_linkup_request(struct cflayer *layer, | |||
258 | tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs); | 258 | tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs); |
259 | cfpkt_add_body(pkt, &tmp16, 2); | 259 | cfpkt_add_body(pkt, &tmp16, 2); |
260 | memset(utility_name, 0, sizeof(utility_name)); | 260 | memset(utility_name, 0, sizeof(utility_name)); |
261 | strncpy(utility_name, param->u.utility.name, | 261 | strlcpy(utility_name, param->u.utility.name, |
262 | UTILITY_NAME_LENGTH - 1); | 262 | UTILITY_NAME_LENGTH); |
263 | cfpkt_add_body(pkt, utility_name, UTILITY_NAME_LENGTH); | 263 | cfpkt_add_body(pkt, utility_name, UTILITY_NAME_LENGTH); |
264 | tmp8 = param->u.utility.paramlen; | 264 | tmp8 = param->u.utility.paramlen; |
265 | cfpkt_add_body(pkt, &tmp8, 1); | 265 | cfpkt_add_body(pkt, &tmp8, 1); |
diff --git a/net/core/dev.c b/net/core/dev.c index 01ee854454a8..0e0ba36eeac9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1146,7 +1146,19 @@ EXPORT_SYMBOL(dev_alloc_name); | |||
1146 | int dev_get_valid_name(struct net *net, struct net_device *dev, | 1146 | int dev_get_valid_name(struct net *net, struct net_device *dev, |
1147 | const char *name) | 1147 | const char *name) |
1148 | { | 1148 | { |
1149 | return dev_alloc_name_ns(net, dev, name); | 1149 | BUG_ON(!net); |
1150 | |||
1151 | if (!dev_valid_name(name)) | ||
1152 | return -EINVAL; | ||
1153 | |||
1154 | if (strchr(name, '%')) | ||
1155 | return dev_alloc_name_ns(net, dev, name); | ||
1156 | else if (__dev_get_by_name(net, name)) | ||
1157 | return -EEXIST; | ||
1158 | else if (dev->name != name) | ||
1159 | strlcpy(dev->name, name, IFNAMSIZ); | ||
1160 | |||
1161 | return 0; | ||
1150 | } | 1162 | } |
1151 | EXPORT_SYMBOL(dev_get_valid_name); | 1163 | EXPORT_SYMBOL(dev_get_valid_name); |
1152 | 1164 | ||
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f8fcf450a36e..8225416911ae 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -770,15 +770,6 @@ static int ethtool_set_link_ksettings(struct net_device *dev, | |||
770 | return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings); | 770 | return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings); |
771 | } | 771 | } |
772 | 772 | ||
773 | static void | ||
774 | warn_incomplete_ethtool_legacy_settings_conversion(const char *details) | ||
775 | { | ||
776 | char name[sizeof(current->comm)]; | ||
777 | |||
778 | pr_info_once("warning: `%s' uses legacy ethtool link settings API, %s\n", | ||
779 | get_task_comm(name, current), details); | ||
780 | } | ||
781 | |||
782 | /* Query device for its ethtool_cmd settings. | 773 | /* Query device for its ethtool_cmd settings. |
783 | * | 774 | * |
784 | * Backward compatibility note: for compatibility with legacy ethtool, | 775 | * Backward compatibility note: for compatibility with legacy ethtool, |
@@ -805,10 +796,8 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | |||
805 | &link_ksettings); | 796 | &link_ksettings); |
806 | if (err < 0) | 797 | if (err < 0) |
807 | return err; | 798 | return err; |
808 | if (!convert_link_ksettings_to_legacy_settings(&cmd, | 799 | convert_link_ksettings_to_legacy_settings(&cmd, |
809 | &link_ksettings)) | 800 | &link_ksettings); |
810 | warn_incomplete_ethtool_legacy_settings_conversion( | ||
811 | "link modes are only partially reported"); | ||
812 | 801 | ||
813 | /* send a sensible cmd tag back to user */ | 802 | /* send a sensible cmd tag back to user */ |
814 | cmd.cmd = ETHTOOL_GSET; | 803 | cmd.cmd = ETHTOOL_GSET; |
diff --git a/net/core/filter.c b/net/core/filter.c index 6a85e67fafce..d339ef170df6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -1054,11 +1054,9 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp) | |||
1054 | */ | 1054 | */ |
1055 | goto out_err_free; | 1055 | goto out_err_free; |
1056 | 1056 | ||
1057 | /* We are guaranteed to never error here with cBPF to eBPF | ||
1058 | * transitions, since there's no issue with type compatibility | ||
1059 | * checks on program arrays. | ||
1060 | */ | ||
1061 | fp = bpf_prog_select_runtime(fp, &err); | 1057 | fp = bpf_prog_select_runtime(fp, &err); |
1058 | if (err) | ||
1059 | goto out_err_free; | ||
1062 | 1060 | ||
1063 | kfree(old_prog); | 1061 | kfree(old_prog); |
1064 | return fp; | 1062 | return fp; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index dabba2a91fc8..778d7f03404a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1681,18 +1681,18 @@ static bool link_dump_filtered(struct net_device *dev, | |||
1681 | return false; | 1681 | return false; |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static struct net *get_target_net(struct sk_buff *skb, int netnsid) | 1684 | static struct net *get_target_net(struct sock *sk, int netnsid) |
1685 | { | 1685 | { |
1686 | struct net *net; | 1686 | struct net *net; |
1687 | 1687 | ||
1688 | net = get_net_ns_by_id(sock_net(skb->sk), netnsid); | 1688 | net = get_net_ns_by_id(sock_net(sk), netnsid); |
1689 | if (!net) | 1689 | if (!net) |
1690 | return ERR_PTR(-EINVAL); | 1690 | return ERR_PTR(-EINVAL); |
1691 | 1691 | ||
1692 | /* For now, the caller is required to have CAP_NET_ADMIN in | 1692 | /* For now, the caller is required to have CAP_NET_ADMIN in |
1693 | * the user namespace owning the target net ns. | 1693 | * the user namespace owning the target net ns. |
1694 | */ | 1694 | */ |
1695 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { | 1695 | if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) { |
1696 | put_net(net); | 1696 | put_net(net); |
1697 | return ERR_PTR(-EACCES); | 1697 | return ERR_PTR(-EACCES); |
1698 | } | 1698 | } |
@@ -1733,7 +1733,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1733 | ifla_policy, NULL) >= 0) { | 1733 | ifla_policy, NULL) >= 0) { |
1734 | if (tb[IFLA_IF_NETNSID]) { | 1734 | if (tb[IFLA_IF_NETNSID]) { |
1735 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); | 1735 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); |
1736 | tgt_net = get_target_net(skb, netnsid); | 1736 | tgt_net = get_target_net(skb->sk, netnsid); |
1737 | if (IS_ERR(tgt_net)) { | 1737 | if (IS_ERR(tgt_net)) { |
1738 | tgt_net = net; | 1738 | tgt_net = net; |
1739 | netnsid = -1; | 1739 | netnsid = -1; |
@@ -2883,7 +2883,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2883 | 2883 | ||
2884 | if (tb[IFLA_IF_NETNSID]) { | 2884 | if (tb[IFLA_IF_NETNSID]) { |
2885 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); | 2885 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); |
2886 | tgt_net = get_target_net(skb, netnsid); | 2886 | tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid); |
2887 | if (IS_ERR(tgt_net)) | 2887 | if (IS_ERR(tgt_net)) |
2888 | return PTR_ERR(tgt_net); | 2888 | return PTR_ERR(tgt_net); |
2889 | } | 2889 | } |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 217f4e3b82f6..146b50e30659 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -288,7 +288,7 @@ static int sock_diag_bind(struct net *net, int group) | |||
288 | case SKNLGRP_INET6_UDP_DESTROY: | 288 | case SKNLGRP_INET6_UDP_DESTROY: |
289 | if (!sock_diag_handlers[AF_INET6]) | 289 | if (!sock_diag_handlers[AF_INET6]) |
290 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | 290 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, |
291 | NETLINK_SOCK_DIAG, AF_INET); | 291 | NETLINK_SOCK_DIAG, AF_INET6); |
292 | break; | 292 | break; |
293 | } | 293 | } |
294 | return 0; | 294 | return 0; |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index cbc3dde4cfcc..a47ad6cd41c0 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
@@ -325,7 +325,13 @@ static struct ctl_table net_core_table[] = { | |||
325 | .data = &bpf_jit_enable, | 325 | .data = &bpf_jit_enable, |
326 | .maxlen = sizeof(int), | 326 | .maxlen = sizeof(int), |
327 | .mode = 0644, | 327 | .mode = 0644, |
328 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON | ||
328 | .proc_handler = proc_dointvec | 329 | .proc_handler = proc_dointvec |
330 | #else | ||
331 | .proc_handler = proc_dointvec_minmax, | ||
332 | .extra1 = &one, | ||
333 | .extra2 = &one, | ||
334 | #endif | ||
329 | }, | 335 | }, |
330 | # ifdef CONFIG_HAVE_EBPF_JIT | 336 | # ifdef CONFIG_HAVE_EBPF_JIT |
331 | { | 337 | { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 125c1eab3eaa..5e570aa9e43b 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -520,9 +520,11 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
520 | goto out; | 520 | goto out; |
521 | 521 | ||
522 | /* hdrincl should be READ_ONCE(inet->hdrincl) | 522 | /* hdrincl should be READ_ONCE(inet->hdrincl) |
523 | * but READ_ONCE() doesn't work with bit fields | 523 | * but READ_ONCE() doesn't work with bit fields. |
524 | * Doing this indirectly yields the same result. | ||
524 | */ | 525 | */ |
525 | hdrincl = inet->hdrincl; | 526 | hdrincl = inet->hdrincl; |
527 | hdrincl = READ_ONCE(hdrincl); | ||
526 | /* | 528 | /* |
527 | * Check the flags. | 529 | * Check the flags. |
528 | */ | 530 | */ |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 83bd75713535..bc68eb661970 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -925,6 +925,15 @@ static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto, | |||
925 | sr_phdr->segments[0] = **addr_p; | 925 | sr_phdr->segments[0] = **addr_p; |
926 | *addr_p = &sr_ihdr->segments[sr_ihdr->segments_left]; | 926 | *addr_p = &sr_ihdr->segments[sr_ihdr->segments_left]; |
927 | 927 | ||
928 | if (sr_ihdr->hdrlen > hops * 2) { | ||
929 | int tlvs_offset, tlvs_length; | ||
930 | |||
931 | tlvs_offset = (1 + hops * 2) << 3; | ||
932 | tlvs_length = (sr_ihdr->hdrlen - hops * 2) << 3; | ||
933 | memcpy((char *)sr_phdr + tlvs_offset, | ||
934 | (char *)sr_ihdr + tlvs_offset, tlvs_length); | ||
935 | } | ||
936 | |||
928 | #ifdef CONFIG_IPV6_SEG6_HMAC | 937 | #ifdef CONFIG_IPV6_SEG6_HMAC |
929 | if (sr_has_hmac(sr_phdr)) { | 938 | if (sr_has_hmac(sr_phdr)) { |
930 | struct net *net = NULL; | 939 | struct net *net = NULL; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f5285f4e1d08..9dcc3924a975 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -640,6 +640,11 @@ static struct fib6_node *fib6_add_1(struct net *net, | |||
640 | if (!(fn->fn_flags & RTN_RTINFO)) { | 640 | if (!(fn->fn_flags & RTN_RTINFO)) { |
641 | RCU_INIT_POINTER(fn->leaf, NULL); | 641 | RCU_INIT_POINTER(fn->leaf, NULL); |
642 | rt6_release(leaf); | 642 | rt6_release(leaf); |
643 | /* remove null_entry in the root node */ | ||
644 | } else if (fn->fn_flags & RTN_TL_ROOT && | ||
645 | rcu_access_pointer(fn->leaf) == | ||
646 | net->ipv6.ip6_null_entry) { | ||
647 | RCU_INIT_POINTER(fn->leaf, NULL); | ||
643 | } | 648 | } |
644 | 649 | ||
645 | return fn; | 650 | return fn; |
@@ -1241,23 +1246,28 @@ out: | |||
1241 | * If fib6_add_1 has cleared the old leaf pointer in the | 1246 | * If fib6_add_1 has cleared the old leaf pointer in the |
1242 | * super-tree leaf node we have to find a new one for it. | 1247 | * super-tree leaf node we have to find a new one for it. |
1243 | */ | 1248 | */ |
1244 | struct rt6_info *pn_leaf = rcu_dereference_protected(pn->leaf, | 1249 | if (pn != fn) { |
1245 | lockdep_is_held(&table->tb6_lock)); | 1250 | struct rt6_info *pn_leaf = |
1246 | if (pn != fn && pn_leaf == rt) { | 1251 | rcu_dereference_protected(pn->leaf, |
1247 | pn_leaf = NULL; | 1252 | lockdep_is_held(&table->tb6_lock)); |
1248 | RCU_INIT_POINTER(pn->leaf, NULL); | 1253 | if (pn_leaf == rt) { |
1249 | atomic_dec(&rt->rt6i_ref); | 1254 | pn_leaf = NULL; |
1250 | } | 1255 | RCU_INIT_POINTER(pn->leaf, NULL); |
1251 | if (pn != fn && !pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { | 1256 | atomic_dec(&rt->rt6i_ref); |
1252 | pn_leaf = fib6_find_prefix(info->nl_net, table, pn); | ||
1253 | #if RT6_DEBUG >= 2 | ||
1254 | if (!pn_leaf) { | ||
1255 | WARN_ON(!pn_leaf); | ||
1256 | pn_leaf = info->nl_net->ipv6.ip6_null_entry; | ||
1257 | } | 1257 | } |
1258 | if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { | ||
1259 | pn_leaf = fib6_find_prefix(info->nl_net, table, | ||
1260 | pn); | ||
1261 | #if RT6_DEBUG >= 2 | ||
1262 | if (!pn_leaf) { | ||
1263 | WARN_ON(!pn_leaf); | ||
1264 | pn_leaf = | ||
1265 | info->nl_net->ipv6.ip6_null_entry; | ||
1266 | } | ||
1258 | #endif | 1267 | #endif |
1259 | atomic_inc(&pn_leaf->rt6i_ref); | 1268 | atomic_inc(&pn_leaf->rt6i_ref); |
1260 | rcu_assign_pointer(pn->leaf, pn_leaf); | 1269 | rcu_assign_pointer(pn->leaf, pn_leaf); |
1270 | } | ||
1261 | } | 1271 | } |
1262 | #endif | 1272 | #endif |
1263 | goto failure; | 1273 | goto failure; |
@@ -1265,13 +1275,17 @@ out: | |||
1265 | return err; | 1275 | return err; |
1266 | 1276 | ||
1267 | failure: | 1277 | failure: |
1268 | /* fn->leaf could be NULL if fn is an intermediate node and we | 1278 | /* fn->leaf could be NULL and fib6_repair_tree() needs to be called if: |
1269 | * failed to add the new route to it in both subtree creation | 1279 | * 1. fn is an intermediate node and we failed to add the new |
1270 | * failure and fib6_add_rt2node() failure case. | 1280 | * route to it in both subtree creation failure and fib6_add_rt2node() |
1271 | * In both cases, fib6_repair_tree() should be called to fix | 1281 | * failure case. |
1272 | * fn->leaf. | 1282 | * 2. fn is the root node in the table and we fail to add the first |
1283 | * default route to it. | ||
1273 | */ | 1284 | */ |
1274 | if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT))) | 1285 | if (fn && |
1286 | (!(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)) || | ||
1287 | (fn->fn_flags & RTN_TL_ROOT && | ||
1288 | !rcu_access_pointer(fn->leaf)))) | ||
1275 | fib6_repair_tree(info->nl_net, table, fn); | 1289 | fib6_repair_tree(info->nl_net, table, fn); |
1276 | /* Always release dst as dst->__refcnt is guaranteed | 1290 | /* Always release dst as dst->__refcnt is guaranteed |
1277 | * to be taken before entering this function | 1291 | * to be taken before entering this function |
@@ -1526,6 +1540,12 @@ static struct fib6_node *fib6_repair_tree(struct net *net, | |||
1526 | struct fib6_walker *w; | 1540 | struct fib6_walker *w; |
1527 | int iter = 0; | 1541 | int iter = 0; |
1528 | 1542 | ||
1543 | /* Set fn->leaf to null_entry for root node. */ | ||
1544 | if (fn->fn_flags & RTN_TL_ROOT) { | ||
1545 | rcu_assign_pointer(fn->leaf, net->ipv6.ip6_null_entry); | ||
1546 | return fn; | ||
1547 | } | ||
1548 | |||
1529 | for (;;) { | 1549 | for (;;) { |
1530 | struct fib6_node *fn_r = rcu_dereference_protected(fn->right, | 1550 | struct fib6_node *fn_r = rcu_dereference_protected(fn->right, |
1531 | lockdep_is_held(&table->tb6_lock)); | 1551 | lockdep_is_held(&table->tb6_lock)); |
@@ -1680,10 +1700,15 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn, | |||
1680 | } | 1700 | } |
1681 | read_unlock(&net->ipv6.fib6_walker_lock); | 1701 | read_unlock(&net->ipv6.fib6_walker_lock); |
1682 | 1702 | ||
1683 | /* If it was last route, expunge its radix tree node */ | 1703 | /* If it was last route, call fib6_repair_tree() to: |
1704 | * 1. For root node, put back null_entry as how the table was created. | ||
1705 | * 2. For other nodes, expunge its radix tree node. | ||
1706 | */ | ||
1684 | if (!rcu_access_pointer(fn->leaf)) { | 1707 | if (!rcu_access_pointer(fn->leaf)) { |
1685 | fn->fn_flags &= ~RTN_RTINFO; | 1708 | if (!(fn->fn_flags & RTN_TL_ROOT)) { |
1686 | net->ipv6.rt6_stats->fib_route_nodes--; | 1709 | fn->fn_flags &= ~RTN_RTINFO; |
1710 | net->ipv6.rt6_stats->fib_route_nodes--; | ||
1711 | } | ||
1687 | fn = fib6_repair_tree(net, table, fn); | 1712 | fn = fib6_repair_tree(net, table, fn); |
1688 | } | 1713 | } |
1689 | 1714 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index f7dd51c42314..688ba5f7516b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1735,9 +1735,10 @@ struct sk_buff *ip6_make_skb(struct sock *sk, | |||
1735 | cork.base.opt = NULL; | 1735 | cork.base.opt = NULL; |
1736 | v6_cork.opt = NULL; | 1736 | v6_cork.opt = NULL; |
1737 | err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); | 1737 | err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); |
1738 | if (err) | 1738 | if (err) { |
1739 | ip6_cork_release(&cork, &v6_cork); | ||
1739 | return ERR_PTR(err); | 1740 | return ERR_PTR(err); |
1740 | 1741 | } | |
1741 | if (ipc6->dontfrag < 0) | 1742 | if (ipc6->dontfrag < 0) |
1742 | ipc6->dontfrag = inet6_sk(sk)->dontfrag; | 1743 | ipc6->dontfrag = inet6_sk(sk)->dontfrag; |
1743 | 1744 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 931c38f6ff4a..9a7cf355bc8c 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1074,10 +1074,11 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, | |||
1074 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); | 1074 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); |
1075 | neigh_release(neigh); | 1075 | neigh_release(neigh); |
1076 | } | 1076 | } |
1077 | } else if (!(t->parms.flags & | 1077 | } else if (t->parms.proto != 0 && !(t->parms.flags & |
1078 | (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { | 1078 | (IP6_TNL_F_USE_ORIG_TCLASS | |
1079 | /* enable the cache only only if the routing decision does | 1079 | IP6_TNL_F_USE_ORIG_FWMARK))) { |
1080 | * not depend on the current inner header value | 1080 | /* enable the cache only if neither the outer protocol nor the |
1081 | * routing decision depends on the current inner header value | ||
1081 | */ | 1082 | */ |
1082 | use_cache = true; | 1083 | use_cache = true; |
1083 | } | 1084 | } |
@@ -1676,11 +1677,11 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1676 | { | 1677 | { |
1677 | struct ip6_tnl *tnl = netdev_priv(dev); | 1678 | struct ip6_tnl *tnl = netdev_priv(dev); |
1678 | 1679 | ||
1679 | if (tnl->parms.proto == IPPROTO_IPIP) { | 1680 | if (tnl->parms.proto == IPPROTO_IPV6) { |
1680 | if (new_mtu < ETH_MIN_MTU) | 1681 | if (new_mtu < IPV6_MIN_MTU) |
1681 | return -EINVAL; | 1682 | return -EINVAL; |
1682 | } else { | 1683 | } else { |
1683 | if (new_mtu < IPV6_MIN_MTU) | 1684 | if (new_mtu < ETH_MIN_MTU) |
1684 | return -EINVAL; | 1685 | return -EINVAL; |
1685 | } | 1686 | } |
1686 | if (new_mtu > 0xFFF8 - dev->hard_header_len) | 1687 | if (new_mtu > 0xFFF8 - dev->hard_header_len) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 70e9d2ca8bbe..4daafb07602f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) | |||
3632 | } | 3632 | } |
3633 | return true; | 3633 | return true; |
3634 | case NL80211_IFTYPE_MESH_POINT: | 3634 | case NL80211_IFTYPE_MESH_POINT: |
3635 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2)) | ||
3636 | return false; | ||
3635 | if (multicast) | 3637 | if (multicast) |
3636 | return true; | 3638 | return true; |
3637 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); | 3639 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 10798b357481..07bd4138c84e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -2072,7 +2072,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb, | |||
2072 | continue; | 2072 | continue; |
2073 | 2073 | ||
2074 | list_for_each_entry_rcu(chain, &table->chains, list) { | 2074 | list_for_each_entry_rcu(chain, &table->chains, list) { |
2075 | if (ctx && ctx->chain[0] && | 2075 | if (ctx && ctx->chain && |
2076 | strcmp(ctx->chain, chain->name) != 0) | 2076 | strcmp(ctx->chain, chain->name) != 0) |
2077 | continue; | 2077 | continue; |
2078 | 2078 | ||
@@ -4665,8 +4665,10 @@ static int nf_tables_dump_obj_done(struct netlink_callback *cb) | |||
4665 | { | 4665 | { |
4666 | struct nft_obj_filter *filter = cb->data; | 4666 | struct nft_obj_filter *filter = cb->data; |
4667 | 4667 | ||
4668 | kfree(filter->table); | 4668 | if (filter) { |
4669 | kfree(filter); | 4669 | kfree(filter->table); |
4670 | kfree(filter); | ||
4671 | } | ||
4670 | 4672 | ||
4671 | return 0; | 4673 | return 0; |
4672 | } | 4674 | } |
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index bc2f1e0977d6..634cfcb7bba6 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -525,6 +525,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args) | |||
525 | 525 | ||
526 | local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; | 526 | local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; |
527 | 527 | ||
528 | if (args->nr_local == 0) | ||
529 | return -EINVAL; | ||
530 | |||
528 | /* figure out the number of pages in the vector */ | 531 | /* figure out the number of pages in the vector */ |
529 | for (i = 0; i < args->nr_local; i++) { | 532 | for (i = 0; i < args->nr_local; i++) { |
530 | if (copy_from_user(&vec, &local_vec[i], | 533 | if (copy_from_user(&vec, &local_vec[i], |
@@ -874,6 +877,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, | |||
874 | err: | 877 | err: |
875 | if (page) | 878 | if (page) |
876 | put_page(page); | 879 | put_page(page); |
880 | rm->atomic.op_active = 0; | ||
877 | kfree(rm->atomic.op_notifier); | 881 | kfree(rm->atomic.op_notifier); |
878 | 882 | ||
879 | return ret; | 883 | return ret; |
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index e29a48ef7fc3..a0ac42b3ed06 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
@@ -159,7 +159,7 @@ static void tcf_gact_stats_update(struct tc_action *a, u64 bytes, u32 packets, | |||
159 | if (action == TC_ACT_SHOT) | 159 | if (action == TC_ACT_SHOT) |
160 | this_cpu_ptr(gact->common.cpu_qstats)->drops += packets; | 160 | this_cpu_ptr(gact->common.cpu_qstats)->drops += packets; |
161 | 161 | ||
162 | tm->lastuse = lastuse; | 162 | tm->lastuse = max_t(u64, tm->lastuse, lastuse); |
163 | } | 163 | } |
164 | 164 | ||
165 | static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, | 165 | static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 8b3e59388480..08b61849c2a2 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -239,7 +239,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets, | |||
239 | struct tcf_t *tm = &m->tcf_tm; | 239 | struct tcf_t *tm = &m->tcf_tm; |
240 | 240 | ||
241 | _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); | 241 | _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); |
242 | tm->lastuse = lastuse; | 242 | tm->lastuse = max_t(u64, tm->lastuse, lastuse); |
243 | } | 243 | } |
244 | 244 | ||
245 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, | 245 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 621b5ca3fd1c..141c9c466ec1 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -399,20 +399,24 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
399 | return; | 399 | return; |
400 | } | 400 | } |
401 | 401 | ||
402 | if (t->param_flags & SPP_PMTUD_ENABLE) { | 402 | if (!(t->param_flags & SPP_PMTUD_ENABLE)) |
403 | /* Update transports view of the MTU */ | 403 | /* We can't allow retransmitting in such case, as the |
404 | sctp_transport_update_pmtu(t, pmtu); | 404 | * retransmission would be sized just as before, and thus we |
405 | 405 | * would get another icmp, and retransmit again. | |
406 | /* Update association pmtu. */ | 406 | */ |
407 | sctp_assoc_sync_pmtu(asoc); | 407 | return; |
408 | } | ||
409 | 408 | ||
410 | /* Retransmit with the new pmtu setting. | 409 | /* Update transports view of the MTU. Return if no update was needed. |
411 | * Normally, if PMTU discovery is disabled, an ICMP Fragmentation | 410 | * If an update wasn't needed/possible, it also doesn't make sense to |
412 | * Needed will never be sent, but if a message was sent before | 411 | * try to retransmit now. |
413 | * PMTU discovery was disabled that was larger than the PMTU, it | ||
414 | * would not be fragmented, so it must be re-transmitted fragmented. | ||
415 | */ | 412 | */ |
413 | if (!sctp_transport_update_pmtu(t, pmtu)) | ||
414 | return; | ||
415 | |||
416 | /* Update association pmtu. */ | ||
417 | sctp_assoc_sync_pmtu(asoc); | ||
418 | |||
419 | /* Retransmit with the new pmtu setting. */ | ||
416 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | 420 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); |
417 | } | 421 | } |
418 | 422 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b4fb6e4886d2..9b01e994f661 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2277,7 +2277,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2277 | 2277 | ||
2278 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | 2278 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { |
2279 | event = sctp_ulpevent_make_sender_dry_event(asoc, | 2279 | event = sctp_ulpevent_make_sender_dry_event(asoc, |
2280 | GFP_ATOMIC); | 2280 | GFP_USER | __GFP_NOWARN); |
2281 | if (!event) | 2281 | if (!event) |
2282 | return -ENOMEM; | 2282 | return -ENOMEM; |
2283 | 2283 | ||
@@ -3498,6 +3498,8 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3498 | 3498 | ||
3499 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3499 | if (optlen < sizeof(struct sctp_hmacalgo)) |
3500 | return -EINVAL; | 3500 | return -EINVAL; |
3501 | optlen = min_t(unsigned int, optlen, sizeof(struct sctp_hmacalgo) + | ||
3502 | SCTP_AUTH_NUM_HMACS * sizeof(u16)); | ||
3501 | 3503 | ||
3502 | hmacs = memdup_user(optval, optlen); | 3504 | hmacs = memdup_user(optval, optlen); |
3503 | if (IS_ERR(hmacs)) | 3505 | if (IS_ERR(hmacs)) |
@@ -3536,6 +3538,11 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3536 | 3538 | ||
3537 | if (optlen <= sizeof(struct sctp_authkey)) | 3539 | if (optlen <= sizeof(struct sctp_authkey)) |
3538 | return -EINVAL; | 3540 | return -EINVAL; |
3541 | /* authkey->sca_keylength is u16, so optlen can't be bigger than | ||
3542 | * this. | ||
3543 | */ | ||
3544 | optlen = min_t(unsigned int, optlen, USHRT_MAX + | ||
3545 | sizeof(struct sctp_authkey)); | ||
3539 | 3546 | ||
3540 | authkey = memdup_user(optval, optlen); | 3547 | authkey = memdup_user(optval, optlen); |
3541 | if (IS_ERR(authkey)) | 3548 | if (IS_ERR(authkey)) |
@@ -3893,6 +3900,9 @@ static int sctp_setsockopt_reset_streams(struct sock *sk, | |||
3893 | 3900 | ||
3894 | if (optlen < sizeof(*params)) | 3901 | if (optlen < sizeof(*params)) |
3895 | return -EINVAL; | 3902 | return -EINVAL; |
3903 | /* srs_number_streams is u16, so optlen can't be bigger than this. */ | ||
3904 | optlen = min_t(unsigned int, optlen, USHRT_MAX + | ||
3905 | sizeof(__u16) * sizeof(*params)); | ||
3896 | 3906 | ||
3897 | params = memdup_user(optval, optlen); | 3907 | params = memdup_user(optval, optlen); |
3898 | if (IS_ERR(params)) | 3908 | if (IS_ERR(params)) |
@@ -5015,7 +5025,7 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv | |||
5015 | len = sizeof(int); | 5025 | len = sizeof(int); |
5016 | if (put_user(len, optlen)) | 5026 | if (put_user(len, optlen)) |
5017 | return -EFAULT; | 5027 | return -EFAULT; |
5018 | if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int))) | 5028 | if (copy_to_user(optval, &sctp_sk(sk)->autoclose, len)) |
5019 | return -EFAULT; | 5029 | return -EFAULT; |
5020 | return 0; | 5030 | return 0; |
5021 | } | 5031 | } |
@@ -5645,6 +5655,9 @@ copy_getaddrs: | |||
5645 | err = -EFAULT; | 5655 | err = -EFAULT; |
5646 | goto out; | 5656 | goto out; |
5647 | } | 5657 | } |
5658 | /* XXX: We should have accounted for sizeof(struct sctp_getaddrs) too, | ||
5659 | * but we can't change it anymore. | ||
5660 | */ | ||
5648 | if (put_user(bytes_copied, optlen)) | 5661 | if (put_user(bytes_copied, optlen)) |
5649 | err = -EFAULT; | 5662 | err = -EFAULT; |
5650 | out: | 5663 | out: |
@@ -6081,7 +6094,7 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
6081 | params.assoc_id = 0; | 6094 | params.assoc_id = 0; |
6082 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 6095 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
6083 | len = sizeof(struct sctp_assoc_value); | 6096 | len = sizeof(struct sctp_assoc_value); |
6084 | if (copy_from_user(¶ms, optval, sizeof(params))) | 6097 | if (copy_from_user(¶ms, optval, len)) |
6085 | return -EFAULT; | 6098 | return -EFAULT; |
6086 | } else | 6099 | } else |
6087 | return -EINVAL; | 6100 | return -EINVAL; |
@@ -6251,7 +6264,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
6251 | 6264 | ||
6252 | if (len < sizeof(struct sctp_authkeyid)) | 6265 | if (len < sizeof(struct sctp_authkeyid)) |
6253 | return -EINVAL; | 6266 | return -EINVAL; |
6254 | if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) | 6267 | |
6268 | len = sizeof(struct sctp_authkeyid); | ||
6269 | if (copy_from_user(&val, optval, len)) | ||
6255 | return -EFAULT; | 6270 | return -EFAULT; |
6256 | 6271 | ||
6257 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); | 6272 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); |
@@ -6263,7 +6278,6 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
6263 | else | 6278 | else |
6264 | val.scact_keynumber = ep->active_key_id; | 6279 | val.scact_keynumber = ep->active_key_id; |
6265 | 6280 | ||
6266 | len = sizeof(struct sctp_authkeyid); | ||
6267 | if (put_user(len, optlen)) | 6281 | if (put_user(len, optlen)) |
6268 | return -EFAULT; | 6282 | return -EFAULT; |
6269 | if (copy_to_user(optval, &val, len)) | 6283 | if (copy_to_user(optval, &val, len)) |
@@ -6289,7 +6303,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
6289 | if (len < sizeof(struct sctp_authchunks)) | 6303 | if (len < sizeof(struct sctp_authchunks)) |
6290 | return -EINVAL; | 6304 | return -EINVAL; |
6291 | 6305 | ||
6292 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | 6306 | if (copy_from_user(&val, optval, sizeof(val))) |
6293 | return -EFAULT; | 6307 | return -EFAULT; |
6294 | 6308 | ||
6295 | to = p->gauth_chunks; | 6309 | to = p->gauth_chunks; |
@@ -6334,7 +6348,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
6334 | if (len < sizeof(struct sctp_authchunks)) | 6348 | if (len < sizeof(struct sctp_authchunks)) |
6335 | return -EINVAL; | 6349 | return -EINVAL; |
6336 | 6350 | ||
6337 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | 6351 | if (copy_from_user(&val, optval, sizeof(val))) |
6338 | return -EFAULT; | 6352 | return -EFAULT; |
6339 | 6353 | ||
6340 | to = p->gauth_chunks; | 6354 | to = p->gauth_chunks; |
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 76ea66be0bbe..524dfeb94c41 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
@@ -156,9 +156,9 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, | |||
156 | sctp_stream_outq_migrate(stream, NULL, outcnt); | 156 | sctp_stream_outq_migrate(stream, NULL, outcnt); |
157 | sched->sched_all(stream); | 157 | sched->sched_all(stream); |
158 | 158 | ||
159 | i = sctp_stream_alloc_out(stream, outcnt, gfp); | 159 | ret = sctp_stream_alloc_out(stream, outcnt, gfp); |
160 | if (i) | 160 | if (ret) |
161 | return i; | 161 | goto out; |
162 | 162 | ||
163 | stream->outcnt = outcnt; | 163 | stream->outcnt = outcnt; |
164 | for (i = 0; i < stream->outcnt; i++) | 164 | for (i = 0; i < stream->outcnt; i++) |
@@ -170,19 +170,17 @@ in: | |||
170 | if (!incnt) | 170 | if (!incnt) |
171 | goto out; | 171 | goto out; |
172 | 172 | ||
173 | i = sctp_stream_alloc_in(stream, incnt, gfp); | 173 | ret = sctp_stream_alloc_in(stream, incnt, gfp); |
174 | if (i) { | 174 | if (ret) { |
175 | ret = -ENOMEM; | 175 | sched->free(stream); |
176 | goto free; | 176 | kfree(stream->out); |
177 | stream->out = NULL; | ||
178 | stream->outcnt = 0; | ||
179 | goto out; | ||
177 | } | 180 | } |
178 | 181 | ||
179 | stream->incnt = incnt; | 182 | stream->incnt = incnt; |
180 | goto out; | ||
181 | 183 | ||
182 | free: | ||
183 | sched->free(stream); | ||
184 | kfree(stream->out); | ||
185 | stream->out = NULL; | ||
186 | out: | 184 | out: |
187 | return ret; | 185 | return ret; |
188 | } | 186 | } |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 1e5a22430cf5..47f82bd794d9 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -248,28 +248,37 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) | |||
248 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | 248 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
249 | } | 249 | } |
250 | 250 | ||
251 | void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) | 251 | bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) |
252 | { | 252 | { |
253 | struct dst_entry *dst = sctp_transport_dst_check(t); | 253 | struct dst_entry *dst = sctp_transport_dst_check(t); |
254 | bool change = true; | ||
254 | 255 | ||
255 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { | 256 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { |
256 | pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n", | 257 | pr_warn_ratelimited("%s: Reported pmtu %d too low, using default minimum of %d\n", |
257 | __func__, pmtu, SCTP_DEFAULT_MINSEGMENT); | 258 | __func__, pmtu, SCTP_DEFAULT_MINSEGMENT); |
258 | /* Use default minimum segment size and disable | 259 | /* Use default minimum segment instead */ |
259 | * pmtu discovery on this transport. | 260 | pmtu = SCTP_DEFAULT_MINSEGMENT; |
260 | */ | ||
261 | t->pathmtu = SCTP_DEFAULT_MINSEGMENT; | ||
262 | } else { | ||
263 | t->pathmtu = pmtu; | ||
264 | } | 261 | } |
262 | pmtu = SCTP_TRUNC4(pmtu); | ||
265 | 263 | ||
266 | if (dst) { | 264 | if (dst) { |
267 | dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu); | 265 | dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu); |
268 | dst = sctp_transport_dst_check(t); | 266 | dst = sctp_transport_dst_check(t); |
269 | } | 267 | } |
270 | 268 | ||
271 | if (!dst) | 269 | if (!dst) { |
272 | t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk); | 270 | t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk); |
271 | dst = t->dst; | ||
272 | } | ||
273 | |||
274 | if (dst) { | ||
275 | /* Re-fetch, as under layers may have a higher minimum size */ | ||
276 | pmtu = SCTP_TRUNC4(dst_mtu(dst)); | ||
277 | change = t->pathmtu != pmtu; | ||
278 | } | ||
279 | t->pathmtu = pmtu; | ||
280 | |||
281 | return change; | ||
273 | } | 282 | } |
274 | 283 | ||
275 | /* Caches the dst entry and source address for a transport's destination | 284 | /* Caches the dst entry and source address for a transport's destination |
diff --git a/net/socket.c b/net/socket.c index 05f361faec45..6f05d5c4bf30 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -436,8 +436,10 @@ static int sock_map_fd(struct socket *sock, int flags) | |||
436 | { | 436 | { |
437 | struct file *newfile; | 437 | struct file *newfile; |
438 | int fd = get_unused_fd_flags(flags); | 438 | int fd = get_unused_fd_flags(flags); |
439 | if (unlikely(fd < 0)) | 439 | if (unlikely(fd < 0)) { |
440 | sock_release(sock); | ||
440 | return fd; | 441 | return fd; |
442 | } | ||
441 | 443 | ||
442 | newfile = sock_alloc_file(sock, flags, NULL); | 444 | newfile = sock_alloc_file(sock, flags, NULL); |
443 | if (likely(!IS_ERR(newfile))) { | 445 | if (likely(!IS_ERR(newfile))) { |
@@ -2619,6 +2621,15 @@ out_fs: | |||
2619 | 2621 | ||
2620 | core_initcall(sock_init); /* early initcall */ | 2622 | core_initcall(sock_init); /* early initcall */ |
2621 | 2623 | ||
2624 | static int __init jit_init(void) | ||
2625 | { | ||
2626 | #ifdef CONFIG_BPF_JIT_ALWAYS_ON | ||
2627 | bpf_jit_enable = 1; | ||
2628 | #endif | ||
2629 | return 0; | ||
2630 | } | ||
2631 | pure_initcall(jit_init); | ||
2632 | |||
2622 | #ifdef CONFIG_PROC_FS | 2633 | #ifdef CONFIG_PROC_FS |
2623 | void socket_seq_show(struct seq_file *seq) | 2634 | void socket_seq_show(struct seq_file *seq) |
2624 | { | 2635 | { |
diff --git a/net/tipc/group.c b/net/tipc/group.c index 8e12ab55346b..5f4ffae807ee 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -109,7 +109,8 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | |||
109 | static void tipc_group_decr_active(struct tipc_group *grp, | 109 | static void tipc_group_decr_active(struct tipc_group *grp, |
110 | struct tipc_member *m) | 110 | struct tipc_member *m) |
111 | { | 111 | { |
112 | if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING) | 112 | if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING || |
113 | m->state == MBR_REMITTED) | ||
113 | grp->active_cnt--; | 114 | grp->active_cnt--; |
114 | } | 115 | } |
115 | 116 | ||
@@ -562,7 +563,7 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
562 | int max_active = grp->max_active; | 563 | int max_active = grp->max_active; |
563 | int reclaim_limit = max_active * 3 / 4; | 564 | int reclaim_limit = max_active * 3 / 4; |
564 | int active_cnt = grp->active_cnt; | 565 | int active_cnt = grp->active_cnt; |
565 | struct tipc_member *m, *rm; | 566 | struct tipc_member *m, *rm, *pm; |
566 | 567 | ||
567 | m = tipc_group_find_member(grp, node, port); | 568 | m = tipc_group_find_member(grp, node, port); |
568 | if (!m) | 569 | if (!m) |
@@ -605,6 +606,17 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
605 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); | 606 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); |
606 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 607 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
607 | } | 608 | } |
609 | grp->active_cnt--; | ||
610 | list_del_init(&m->list); | ||
611 | if (list_empty(&grp->pending)) | ||
612 | return; | ||
613 | |||
614 | /* Set oldest pending member to active and advertise */ | ||
615 | pm = list_first_entry(&grp->pending, struct tipc_member, list); | ||
616 | pm->state = MBR_ACTIVE; | ||
617 | list_move_tail(&pm->list, &grp->active); | ||
618 | grp->active_cnt++; | ||
619 | tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq); | ||
608 | break; | 620 | break; |
609 | case MBR_RECLAIMING: | 621 | case MBR_RECLAIMING: |
610 | case MBR_DISCOVERED: | 622 | case MBR_DISCOVERED: |
@@ -742,14 +754,14 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
742 | if (!m || m->state != MBR_RECLAIMING) | 754 | if (!m || m->state != MBR_RECLAIMING) |
743 | return; | 755 | return; |
744 | 756 | ||
745 | list_del_init(&m->list); | ||
746 | grp->active_cnt--; | ||
747 | remitted = msg_grp_remitted(hdr); | 757 | remitted = msg_grp_remitted(hdr); |
748 | 758 | ||
749 | /* Messages preceding the REMIT still in receive queue */ | 759 | /* Messages preceding the REMIT still in receive queue */ |
750 | if (m->advertised > remitted) { | 760 | if (m->advertised > remitted) { |
751 | m->state = MBR_REMITTED; | 761 | m->state = MBR_REMITTED; |
752 | in_flight = m->advertised - remitted; | 762 | in_flight = m->advertised - remitted; |
763 | m->advertised = ADV_IDLE + in_flight; | ||
764 | return; | ||
753 | } | 765 | } |
754 | /* All messages preceding the REMIT have been read */ | 766 | /* All messages preceding the REMIT have been read */ |
755 | if (m->advertised <= remitted) { | 767 | if (m->advertised <= remitted) { |
@@ -761,6 +773,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
761 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 773 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
762 | 774 | ||
763 | m->advertised = ADV_IDLE + in_flight; | 775 | m->advertised = ADV_IDLE + in_flight; |
776 | grp->active_cnt--; | ||
777 | list_del_init(&m->list); | ||
764 | 778 | ||
765 | /* Set oldest pending member to active and advertise */ | 779 | /* Set oldest pending member to active and advertise */ |
766 | if (list_empty(&grp->pending)) | 780 | if (list_empty(&grp->pending)) |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 213d0c498c97..2b3dbcd40e46 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -11361,7 +11361,8 @@ static int nl80211_nan_add_func(struct sk_buff *skb, | |||
11361 | break; | 11361 | break; |
11362 | case NL80211_NAN_FUNC_FOLLOW_UP: | 11362 | case NL80211_NAN_FUNC_FOLLOW_UP: |
11363 | if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] || | 11363 | if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] || |
11364 | !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) { | 11364 | !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] || |
11365 | !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) { | ||
11365 | err = -EINVAL; | 11366 | err = -EINVAL; |
11366 | goto out; | 11367 | goto out; |
11367 | } | 11368 | } |
diff --git a/scripts/genksyms/.gitignore b/scripts/genksyms/.gitignore index 86dc07a01b43..e7836b47f060 100644 --- a/scripts/genksyms/.gitignore +++ b/scripts/genksyms/.gitignore | |||
@@ -1,4 +1,3 @@ | |||
1 | *.hash.c | ||
2 | *.lex.c | 1 | *.lex.c |
3 | *.tab.c | 2 | *.tab.c |
4 | *.tab.h | 3 | *.tab.h |
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index cbf4996dd9c1..8cee597d33a5 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c | |||
@@ -893,7 +893,10 @@ static enum string_value_kind expr_parse_string(const char *str, | |||
893 | switch (type) { | 893 | switch (type) { |
894 | case S_BOOLEAN: | 894 | case S_BOOLEAN: |
895 | case S_TRISTATE: | 895 | case S_TRISTATE: |
896 | return k_string; | 896 | val->s = !strcmp(str, "n") ? 0 : |
897 | !strcmp(str, "m") ? 1 : | ||
898 | !strcmp(str, "y") ? 2 : -1; | ||
899 | return k_signed; | ||
897 | case S_INT: | 900 | case S_INT: |
898 | val->s = strtoll(str, &tail, 10); | 901 | val->s = strtoll(str, &tail, 10); |
899 | kind = k_signed; | 902 | kind = k_signed; |
diff --git a/security/Kconfig b/security/Kconfig index 3d4debd0257e..b0cb9a5f9448 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -63,7 +63,7 @@ config PAGE_TABLE_ISOLATION | |||
63 | ensuring that the majority of kernel addresses are not mapped | 63 | ensuring that the majority of kernel addresses are not mapped |
64 | into userspace. | 64 | into userspace. |
65 | 65 | ||
66 | See Documentation/x86/pagetable-isolation.txt for more details. | 66 | See Documentation/x86/pti.txt for more details. |
67 | 67 | ||
68 | config SECURITY_INFINIBAND | 68 | config SECURITY_INFINIBAND |
69 | bool "Infiniband Security Hooks" | 69 | bool "Infiniband Security Hooks" |
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 04ba9d0718ea..6a54d2ffa840 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
@@ -330,10 +330,7 @@ static struct aa_profile *__attach_match(const char *name, | |||
330 | continue; | 330 | continue; |
331 | 331 | ||
332 | if (profile->xmatch) { | 332 | if (profile->xmatch) { |
333 | if (profile->xmatch_len == len) { | 333 | if (profile->xmatch_len >= len) { |
334 | conflict = true; | ||
335 | continue; | ||
336 | } else if (profile->xmatch_len > len) { | ||
337 | unsigned int state; | 334 | unsigned int state; |
338 | u32 perm; | 335 | u32 perm; |
339 | 336 | ||
@@ -342,6 +339,10 @@ static struct aa_profile *__attach_match(const char *name, | |||
342 | perm = dfa_user_allow(profile->xmatch, state); | 339 | perm = dfa_user_allow(profile->xmatch, state); |
343 | /* any accepting state means a valid match. */ | 340 | /* any accepting state means a valid match. */ |
344 | if (perm & MAY_EXEC) { | 341 | if (perm & MAY_EXEC) { |
342 | if (profile->xmatch_len == len) { | ||
343 | conflict = true; | ||
344 | continue; | ||
345 | } | ||
345 | candidate = profile; | 346 | candidate = profile; |
346 | len = profile->xmatch_len; | 347 | len = profile->xmatch_len; |
347 | conflict = false; | 348 | conflict = false; |
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h index 2b27bb79aec4..d7b7e7115160 100644 --- a/security/apparmor/include/perms.h +++ b/security/apparmor/include/perms.h | |||
@@ -133,6 +133,9 @@ extern struct aa_perms allperms; | |||
133 | #define xcheck_labels_profiles(L1, L2, FN, args...) \ | 133 | #define xcheck_labels_profiles(L1, L2, FN, args...) \ |
134 | xcheck_ns_labels((L1), (L2), xcheck_ns_profile_label, (FN), args) | 134 | xcheck_ns_labels((L1), (L2), xcheck_ns_profile_label, (FN), args) |
135 | 135 | ||
136 | #define xcheck_labels(L1, L2, P, FN1, FN2) \ | ||
137 | xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2))) | ||
138 | |||
136 | 139 | ||
137 | void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); | 140 | void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); |
138 | void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); | 141 | void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); |
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c index 7ca0032e7ba9..b40678f3c1d5 100644 --- a/security/apparmor/ipc.c +++ b/security/apparmor/ipc.c | |||
@@ -64,40 +64,48 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va) | |||
64 | FLAGS_NONE, GFP_ATOMIC); | 64 | FLAGS_NONE, GFP_ATOMIC); |
65 | } | 65 | } |
66 | 66 | ||
67 | /* assumes check for PROFILE_MEDIATES is already done */ | ||
67 | /* TODO: conditionals */ | 68 | /* TODO: conditionals */ |
68 | static int profile_ptrace_perm(struct aa_profile *profile, | 69 | static int profile_ptrace_perm(struct aa_profile *profile, |
69 | struct aa_profile *peer, u32 request, | 70 | struct aa_label *peer, u32 request, |
70 | struct common_audit_data *sa) | 71 | struct common_audit_data *sa) |
71 | { | 72 | { |
72 | struct aa_perms perms = { }; | 73 | struct aa_perms perms = { }; |
73 | 74 | ||
74 | /* need because of peer in cross check */ | 75 | aad(sa)->peer = peer; |
75 | if (profile_unconfined(profile) || | 76 | aa_profile_match_label(profile, peer, AA_CLASS_PTRACE, request, |
76 | !PROFILE_MEDIATES(profile, AA_CLASS_PTRACE)) | ||
77 | return 0; | ||
78 | |||
79 | aad(sa)->peer = &peer->label; | ||
80 | aa_profile_match_label(profile, &peer->label, AA_CLASS_PTRACE, request, | ||
81 | &perms); | 77 | &perms); |
82 | aa_apply_modes_to_perms(profile, &perms); | 78 | aa_apply_modes_to_perms(profile, &perms); |
83 | return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb); | 79 | return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb); |
84 | } | 80 | } |
85 | 81 | ||
86 | static int cross_ptrace_perm(struct aa_profile *tracer, | 82 | static int profile_tracee_perm(struct aa_profile *tracee, |
87 | struct aa_profile *tracee, u32 request, | 83 | struct aa_label *tracer, u32 request, |
88 | struct common_audit_data *sa) | 84 | struct common_audit_data *sa) |
89 | { | 85 | { |
86 | if (profile_unconfined(tracee) || unconfined(tracer) || | ||
87 | !PROFILE_MEDIATES(tracee, AA_CLASS_PTRACE)) | ||
88 | return 0; | ||
89 | |||
90 | return profile_ptrace_perm(tracee, tracer, request, sa); | ||
91 | } | ||
92 | |||
93 | static int profile_tracer_perm(struct aa_profile *tracer, | ||
94 | struct aa_label *tracee, u32 request, | ||
95 | struct common_audit_data *sa) | ||
96 | { | ||
97 | if (profile_unconfined(tracer)) | ||
98 | return 0; | ||
99 | |||
90 | if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE)) | 100 | if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE)) |
91 | return xcheck(profile_ptrace_perm(tracer, tracee, request, sa), | 101 | return profile_ptrace_perm(tracer, tracee, request, sa); |
92 | profile_ptrace_perm(tracee, tracer, | 102 | |
93 | request << PTRACE_PERM_SHIFT, | 103 | /* profile uses the old style capability check for ptrace */ |
94 | sa)); | 104 | if (&tracer->label == tracee) |
95 | /* policy uses the old style capability check for ptrace */ | ||
96 | if (profile_unconfined(tracer) || tracer == tracee) | ||
97 | return 0; | 105 | return 0; |
98 | 106 | ||
99 | aad(sa)->label = &tracer->label; | 107 | aad(sa)->label = &tracer->label; |
100 | aad(sa)->peer = &tracee->label; | 108 | aad(sa)->peer = tracee; |
101 | aad(sa)->request = 0; | 109 | aad(sa)->request = 0; |
102 | aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1); | 110 | aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1); |
103 | 111 | ||
@@ -115,10 +123,13 @@ static int cross_ptrace_perm(struct aa_profile *tracer, | |||
115 | int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, | 123 | int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, |
116 | u32 request) | 124 | u32 request) |
117 | { | 125 | { |
126 | struct aa_profile *profile; | ||
127 | u32 xrequest = request << PTRACE_PERM_SHIFT; | ||
118 | DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE); | 128 | DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE); |
119 | 129 | ||
120 | return xcheck_labels_profiles(tracer, tracee, cross_ptrace_perm, | 130 | return xcheck_labels(tracer, tracee, profile, |
121 | request, &sa); | 131 | profile_tracer_perm(profile, tracee, request, &sa), |
132 | profile_tracee_perm(profile, tracer, xrequest, &sa)); | ||
122 | } | 133 | } |
123 | 134 | ||
124 | 135 | ||
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index 29a97d52e8ad..66d6c52e7761 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c | |||
@@ -91,8 +91,8 @@ static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97, | |||
91 | do { | 91 | do { |
92 | mutex_lock(&ctx->lock); | 92 | mutex_lock(&ctx->lock); |
93 | 93 | ||
94 | tmo = 5; | 94 | tmo = 6; |
95 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--) | 95 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo) |
96 | udelay(21); /* wait an ac97 frame time */ | 96 | udelay(21); /* wait an ac97 frame time */ |
97 | if (!tmo) { | 97 | if (!tmo) { |
98 | pr_debug("ac97rd timeout #1\n"); | 98 | pr_debug("ac97rd timeout #1\n"); |
@@ -105,7 +105,7 @@ static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97, | |||
105 | * poll, Forrest, poll... | 105 | * poll, Forrest, poll... |
106 | */ | 106 | */ |
107 | tmo = 0x10000; | 107 | tmo = 0x10000; |
108 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--) | 108 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo) |
109 | asm volatile ("nop"); | 109 | asm volatile ("nop"); |
110 | data = RD(ctx, AC97_CMDRESP); | 110 | data = RD(ctx, AC97_CMDRESP); |
111 | 111 | ||
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index 2e449d7173fc..d5f73a8ab893 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c | |||
@@ -130,6 +130,7 @@ struct bcm2835_i2s_dev { | |||
130 | struct regmap *i2s_regmap; | 130 | struct regmap *i2s_regmap; |
131 | struct clk *clk; | 131 | struct clk *clk; |
132 | bool clk_prepared; | 132 | bool clk_prepared; |
133 | int clk_rate; | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) | 136 | static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) |
@@ -419,10 +420,19 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, | |||
419 | } | 420 | } |
420 | 421 | ||
421 | /* Clock should only be set up here if CPU is clock master */ | 422 | /* Clock should only be set up here if CPU is clock master */ |
422 | if (bit_clock_master) { | 423 | if (bit_clock_master && |
423 | ret = clk_set_rate(dev->clk, bclk_rate); | 424 | (!dev->clk_prepared || dev->clk_rate != bclk_rate)) { |
424 | if (ret) | 425 | if (dev->clk_prepared) |
425 | return ret; | 426 | bcm2835_i2s_stop_clock(dev); |
427 | |||
428 | if (dev->clk_rate != bclk_rate) { | ||
429 | ret = clk_set_rate(dev->clk, bclk_rate); | ||
430 | if (ret) | ||
431 | return ret; | ||
432 | dev->clk_rate = bclk_rate; | ||
433 | } | ||
434 | |||
435 | bcm2835_i2s_start_clock(dev); | ||
426 | } | 436 | } |
427 | 437 | ||
428 | /* Setup the frame format */ | 438 | /* Setup the frame format */ |
@@ -618,8 +628,6 @@ static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream, | |||
618 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | 628 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); |
619 | uint32_t cs_reg; | 629 | uint32_t cs_reg; |
620 | 630 | ||
621 | bcm2835_i2s_start_clock(dev); | ||
622 | |||
623 | /* | 631 | /* |
624 | * Clear both FIFOs if the one that should be started | 632 | * Clear both FIFOs if the one that should be started |
625 | * is not empty at the moment. This should only happen | 633 | * is not empty at the moment. This should only happen |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index dde37e569ade..aebaa97490b6 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1355,7 +1355,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1355 | ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); | 1355 | ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); |
1356 | if (ret < 0) { | 1356 | if (ret < 0) { |
1357 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); | 1357 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); |
1358 | return ret;; | 1358 | return ret; |
1359 | } | 1359 | } |
1360 | 1360 | ||
1361 | dev_info(&i2c_client->dev, | 1361 | dev_info(&i2c_client->dev, |
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 6b6f8e44369b..95bb10ba80dc 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
@@ -28,6 +28,7 @@ | |||
28 | struct cx20442_priv { | 28 | struct cx20442_priv { |
29 | struct tty_struct *tty; | 29 | struct tty_struct *tty; |
30 | struct regulator *por; | 30 | struct regulator *por; |
31 | u8 reg_cache; | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | #define CX20442_PM 0x0 | 34 | #define CX20442_PM 0x0 |
@@ -88,6 +89,17 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = { | |||
88 | {"ADC", NULL, "Input Mixer"}, | 89 | {"ADC", NULL, "Input Mixer"}, |
89 | }; | 90 | }; |
90 | 91 | ||
92 | static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, | ||
93 | unsigned int reg) | ||
94 | { | ||
95 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); | ||
96 | |||
97 | if (reg >= 1) | ||
98 | return -EINVAL; | ||
99 | |||
100 | return cx20442->reg_cache; | ||
101 | } | ||
102 | |||
91 | enum v253_vls { | 103 | enum v253_vls { |
92 | V253_VLS_NONE = 0, | 104 | V253_VLS_NONE = 0, |
93 | V253_VLS_T, | 105 | V253_VLS_T, |
@@ -112,8 +124,6 @@ enum v253_vls { | |||
112 | V253_VLS_TEST, | 124 | V253_VLS_TEST, |
113 | }; | 125 | }; |
114 | 126 | ||
115 | #if 0 | ||
116 | /* FIXME : these function will be re-used */ | ||
117 | static int cx20442_pm_to_v253_vls(u8 value) | 127 | static int cx20442_pm_to_v253_vls(u8 value) |
118 | { | 128 | { |
119 | switch (value & ~(1 << CX20442_AGC)) { | 129 | switch (value & ~(1 << CX20442_AGC)) { |
@@ -147,11 +157,10 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, | |||
147 | unsigned int value) | 157 | unsigned int value) |
148 | { | 158 | { |
149 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); | 159 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); |
150 | u8 *reg_cache = codec->reg_cache; | ||
151 | int vls, vsp, old, len; | 160 | int vls, vsp, old, len; |
152 | char buf[18]; | 161 | char buf[18]; |
153 | 162 | ||
154 | if (reg >= codec->driver->reg_cache_size) | 163 | if (reg >= 1) |
155 | return -EINVAL; | 164 | return -EINVAL; |
156 | 165 | ||
157 | /* tty and write pointers required for talking to the modem | 166 | /* tty and write pointers required for talking to the modem |
@@ -159,8 +168,8 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, | |||
159 | if (!cx20442->tty || !cx20442->tty->ops->write) | 168 | if (!cx20442->tty || !cx20442->tty->ops->write) |
160 | return -EIO; | 169 | return -EIO; |
161 | 170 | ||
162 | old = reg_cache[reg]; | 171 | old = cx20442->reg_cache; |
163 | reg_cache[reg] = value; | 172 | cx20442->reg_cache = value; |
164 | 173 | ||
165 | vls = cx20442_pm_to_v253_vls(value); | 174 | vls = cx20442_pm_to_v253_vls(value); |
166 | if (vls < 0) | 175 | if (vls < 0) |
@@ -190,7 +199,6 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, | |||
190 | 199 | ||
191 | return 0; | 200 | return 0; |
192 | } | 201 | } |
193 | #endif | ||
194 | 202 | ||
195 | /* | 203 | /* |
196 | * Line discpline related code | 204 | * Line discpline related code |
@@ -384,12 +392,12 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) | |||
384 | return 0; | 392 | return 0; |
385 | } | 393 | } |
386 | 394 | ||
387 | static const u8 cx20442_reg; | ||
388 | |||
389 | static const struct snd_soc_codec_driver cx20442_codec_dev = { | 395 | static const struct snd_soc_codec_driver cx20442_codec_dev = { |
390 | .probe = cx20442_codec_probe, | 396 | .probe = cx20442_codec_probe, |
391 | .remove = cx20442_codec_remove, | 397 | .remove = cx20442_codec_remove, |
392 | .set_bias_level = cx20442_set_bias_level, | 398 | .set_bias_level = cx20442_set_bias_level, |
399 | .read = cx20442_read_reg_cache, | ||
400 | .write = cx20442_write, | ||
393 | 401 | ||
394 | .component_driver = { | 402 | .component_driver = { |
395 | .dapm_widgets = cx20442_dapm_widgets, | 403 | .dapm_widgets = cx20442_dapm_widgets, |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index f2bb4feba3b6..633cdcfc933d 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -1332,10 +1332,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, | |||
1332 | sgtl5000->mclk = devm_clk_get(&client->dev, NULL); | 1332 | sgtl5000->mclk = devm_clk_get(&client->dev, NULL); |
1333 | if (IS_ERR(sgtl5000->mclk)) { | 1333 | if (IS_ERR(sgtl5000->mclk)) { |
1334 | ret = PTR_ERR(sgtl5000->mclk); | 1334 | ret = PTR_ERR(sgtl5000->mclk); |
1335 | dev_err(&client->dev, "Failed to get mclock: %d\n", ret); | ||
1336 | /* Defer the probe to see if the clk will be provided later */ | 1335 | /* Defer the probe to see if the clk will be provided later */ |
1337 | if (ret == -ENOENT) | 1336 | if (ret == -ENOENT) |
1338 | ret = -EPROBE_DEFER; | 1337 | ret = -EPROBE_DEFER; |
1338 | |||
1339 | if (ret != -EPROBE_DEFER) | ||
1340 | dev_err(&client->dev, "Failed to get mclock: %d\n", | ||
1341 | ret); | ||
1339 | goto disable_regs; | 1342 | goto disable_regs; |
1340 | } | 1343 | } |
1341 | 1344 | ||
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 675f5b1b90a6..8c71d2f876ff 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -246,6 +246,19 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, | |||
246 | return ret; | 246 | return ret; |
247 | } | 247 | } |
248 | 248 | ||
249 | static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg, | ||
250 | unsigned int value) | ||
251 | { | ||
252 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | ||
253 | int ret; | ||
254 | |||
255 | mutex_lock(&dac33->mutex); | ||
256 | ret = dac33_write(codec, reg, value); | ||
257 | mutex_unlock(&dac33->mutex); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
249 | #define DAC33_I2C_ADDR_AUTOINC 0x80 | 262 | #define DAC33_I2C_ADDR_AUTOINC 0x80 |
250 | static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, | 263 | static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, |
251 | unsigned int value) | 264 | unsigned int value) |
@@ -1422,6 +1435,8 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) | |||
1422 | } | 1435 | } |
1423 | 1436 | ||
1424 | static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | 1437 | static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { |
1438 | .read = dac33_read_reg_cache, | ||
1439 | .write = dac33_write_locked, | ||
1425 | .set_bias_level = dac33_set_bias_level, | 1440 | .set_bias_level = dac33_set_bias_level, |
1426 | .idle_bias_off = true, | 1441 | .idle_bias_off = true, |
1427 | 1442 | ||
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 46a495b4da8d..c73e6a192224 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -726,6 +726,8 @@ static int uda1380_probe(struct snd_soc_codec *codec) | |||
726 | 726 | ||
727 | static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { | 727 | static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { |
728 | .probe = uda1380_probe, | 728 | .probe = uda1380_probe, |
729 | .read = uda1380_read_reg_cache, | ||
730 | .write = uda1380_write, | ||
729 | .set_bias_level = uda1380_set_bias_level, | 731 | .set_bias_level = uda1380_set_bias_level, |
730 | .suspend_bias_off = true, | 732 | .suspend_bias_off = true, |
731 | 733 | ||
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index b0bd1938b71e..f2c9e8c5970a 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -77,7 +77,6 @@ config SND_SST_ATOM_HIFI2_PLATFORM_PCI | |||
77 | depends on X86 && PCI | 77 | depends on X86 && PCI |
78 | select SND_SST_IPC_PCI | 78 | select SND_SST_IPC_PCI |
79 | select SND_SOC_COMPRESS | 79 | select SND_SOC_COMPRESS |
80 | select SND_SOC_INTEL_COMMON | ||
81 | help | 80 | help |
82 | If you have a Intel Medfield or Merrifield/Edison platform, then | 81 | If you have a Intel Medfield or Merrifield/Edison platform, then |
83 | enable this option by saying Y or m. Distros will typically not | 82 | enable this option by saying Y or m. Distros will typically not |
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index de598dcbef30..d4e103615f51 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig | |||
@@ -139,6 +139,7 @@ config SND_SOC_INTEL_BYT_CHT_DA7213_MACH | |||
139 | config SND_SOC_INTEL_BYT_CHT_ES8316_MACH | 139 | config SND_SOC_INTEL_BYT_CHT_ES8316_MACH |
140 | tristate "Baytrail & Cherrytrail with ES8316 codec" | 140 | tristate "Baytrail & Cherrytrail with ES8316 codec" |
141 | depends on X86_INTEL_LPSS && I2C && ACPI | 141 | depends on X86_INTEL_LPSS && I2C && ACPI |
142 | select SND_SOC_ACPI | ||
142 | select SND_SOC_ES8316 | 143 | select SND_SOC_ES8316 |
143 | help | 144 | help |
144 | This adds support for ASoC machine driver for Intel(R) Baytrail & | 145 | This adds support for ASoC machine driver for Intel(R) Baytrail & |
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index c4d82ad41bd7..2179dedb28ad 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c | |||
@@ -219,7 +219,7 @@ static struct snd_soc_card bytcht_da7213_card = { | |||
219 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 219 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 222 | static char codec_name[SND_ACPI_I2C_ID_LEN]; |
223 | 223 | ||
224 | static int bytcht_da7213_probe(struct platform_device *pdev) | 224 | static int bytcht_da7213_probe(struct platform_device *pdev) |
225 | { | 225 | { |
@@ -243,7 +243,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | /* fixup codec name based on HID */ | 245 | /* fixup codec name based on HID */ |
246 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 246 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
247 | if (i2c_name) { | 247 | if (i2c_name) { |
248 | snprintf(codec_name, sizeof(codec_name), | 248 | snprintf(codec_name, sizeof(codec_name), |
249 | "%s%s", "i2c-", i2c_name); | 249 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 8088396717e3..305e7f4fe55a 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c | |||
@@ -232,15 +232,39 @@ static struct snd_soc_card byt_cht_es8316_card = { | |||
232 | .fully_routed = true, | 232 | .fully_routed = true, |
233 | }; | 233 | }; |
234 | 234 | ||
235 | static char codec_name[SND_ACPI_I2C_ID_LEN]; | ||
236 | |||
235 | static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) | 237 | static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) |
236 | { | 238 | { |
237 | int ret = 0; | ||
238 | struct byt_cht_es8316_private *priv; | 239 | struct byt_cht_es8316_private *priv; |
240 | struct snd_soc_acpi_mach *mach; | ||
241 | const char *i2c_name = NULL; | ||
242 | int dai_index = 0; | ||
243 | int i; | ||
244 | int ret = 0; | ||
239 | 245 | ||
240 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); | 246 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); |
241 | if (!priv) | 247 | if (!priv) |
242 | return -ENOMEM; | 248 | return -ENOMEM; |
243 | 249 | ||
250 | mach = (&pdev->dev)->platform_data; | ||
251 | /* fix index of codec dai */ | ||
252 | for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) { | ||
253 | if (!strcmp(byt_cht_es8316_dais[i].codec_name, | ||
254 | "i2c-ESSX8316:00")) { | ||
255 | dai_index = i; | ||
256 | break; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | /* fixup codec name based on HID */ | ||
261 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); | ||
262 | if (i2c_name) { | ||
263 | snprintf(codec_name, sizeof(codec_name), | ||
264 | "%s%s", "i2c-", i2c_name); | ||
265 | byt_cht_es8316_dais[dai_index].codec_name = codec_name; | ||
266 | } | ||
267 | |||
244 | /* register the soc card */ | 268 | /* register the soc card */ |
245 | byt_cht_es8316_card.dev = &pdev->dev; | 269 | byt_cht_es8316_card.dev = &pdev->dev; |
246 | snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv); | 270 | snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv); |
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index f2c0fc415e52..b6a1cfeec830 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c | |||
@@ -713,7 +713,7 @@ static struct snd_soc_card byt_rt5640_card = { | |||
713 | .fully_routed = true, | 713 | .fully_routed = true, |
714 | }; | 714 | }; |
715 | 715 | ||
716 | static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 716 | static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN]; |
717 | static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ | 717 | static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ |
718 | static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ | 718 | static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ |
719 | 719 | ||
@@ -762,7 +762,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | |||
762 | } | 762 | } |
763 | 763 | ||
764 | /* fixup codec name based on HID */ | 764 | /* fixup codec name based on HID */ |
765 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 765 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
766 | if (i2c_name) { | 766 | if (i2c_name) { |
767 | snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), | 767 | snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), |
768 | "%s%s", "i2c-", i2c_name); | 768 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 22c9cc5d135e..456526a93dd5 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c | |||
@@ -509,7 +509,7 @@ static struct snd_soc_card byt_rt5651_card = { | |||
509 | .fully_routed = true, | 509 | .fully_routed = true, |
510 | }; | 510 | }; |
511 | 511 | ||
512 | static char byt_rt5651_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 512 | static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN]; |
513 | 513 | ||
514 | static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) | 514 | static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) |
515 | { | 515 | { |
@@ -539,7 +539,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) | |||
539 | } | 539 | } |
540 | 540 | ||
541 | /* fixup codec name based on HID */ | 541 | /* fixup codec name based on HID */ |
542 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 542 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
543 | if (i2c_name) { | 543 | if (i2c_name) { |
544 | snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), | 544 | snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), |
545 | "%s%s", "i2c-", i2c_name); | 545 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index f898ee140cdc..31641aab62cd 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c | |||
@@ -49,7 +49,7 @@ struct cht_acpi_card { | |||
49 | struct cht_mc_private { | 49 | struct cht_mc_private { |
50 | struct snd_soc_jack jack; | 50 | struct snd_soc_jack jack; |
51 | struct cht_acpi_card *acpi_card; | 51 | struct cht_acpi_card *acpi_card; |
52 | char codec_name[16]; | 52 | char codec_name[SND_ACPI_I2C_ID_LEN]; |
53 | struct clk *mclk; | 53 | struct clk *mclk; |
54 | }; | 54 | }; |
55 | 55 | ||
@@ -506,7 +506,7 @@ static struct cht_acpi_card snd_soc_cards[] = { | |||
506 | {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650}, | 506 | {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650}, |
507 | }; | 507 | }; |
508 | 508 | ||
509 | static char cht_rt5645_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 509 | static char cht_rt5645_codec_name[SND_ACPI_I2C_ID_LEN]; |
510 | static char cht_rt5645_codec_aif_name[12]; /* = "rt5645-aif[1|2]" */ | 510 | static char cht_rt5645_codec_aif_name[12]; /* = "rt5645-aif[1|2]" */ |
511 | static char cht_rt5645_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ | 511 | static char cht_rt5645_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ |
512 | 512 | ||
@@ -573,7 +573,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
573 | } | 573 | } |
574 | 574 | ||
575 | /* fixup codec name based on HID */ | 575 | /* fixup codec name based on HID */ |
576 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 576 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
577 | if (i2c_name) { | 577 | if (i2c_name) { |
578 | snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), | 578 | snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), |
579 | "%s%s", "i2c-", i2c_name); | 579 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index f8f21eee9b2d..c14a52d2f714 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | struct cht_mc_private { | 36 | struct cht_mc_private { |
37 | struct snd_soc_jack headset; | 37 | struct snd_soc_jack headset; |
38 | char codec_name[16]; | 38 | char codec_name[SND_ACPI_I2C_ID_LEN]; |
39 | struct clk *mclk; | 39 | struct clk *mclk; |
40 | }; | 40 | }; |
41 | 41 | ||
@@ -396,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
396 | 396 | ||
397 | /* fixup codec name based on HID */ | 397 | /* fixup codec name based on HID */ |
398 | if (mach) { | 398 | if (mach) { |
399 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 399 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
400 | if (i2c_name) { | 400 | if (i2c_name) { |
401 | snprintf(drv->codec_name, sizeof(drv->codec_name), | 401 | snprintf(drv->codec_name, sizeof(drv->codec_name), |
402 | "i2c-%s", i2c_name); | 402 | "i2c-%s", i2c_name); |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 28bc16a8e09a..73af6e19ebbd 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -190,7 +190,6 @@ skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) | |||
190 | u8 res_idx = mconfig->res_idx; | 190 | u8 res_idx = mconfig->res_idx; |
191 | struct skl_module_res *res = &mconfig->module->resources[res_idx]; | 191 | struct skl_module_res *res = &mconfig->module->resources[res_idx]; |
192 | 192 | ||
193 | res = &mconfig->module->resources[res_idx]; | ||
194 | skl->resource.mcps -= res->cps; | 193 | skl->resource.mcps -= res->cps; |
195 | } | 194 | } |
196 | 195 | ||
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 2ed3240cc682..2b3f2408301a 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c | |||
@@ -93,6 +93,14 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { | |||
93 | }, | 93 | }, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static const struct snd_soc_dapm_widget mxs_sgtl5000_dapm_widgets[] = { | ||
97 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | ||
98 | SND_SOC_DAPM_LINE("Line In Jack", NULL), | ||
99 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
100 | SND_SOC_DAPM_SPK("Line Out Jack", NULL), | ||
101 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
102 | }; | ||
103 | |||
96 | static struct snd_soc_card mxs_sgtl5000 = { | 104 | static struct snd_soc_card mxs_sgtl5000 = { |
97 | .name = "mxs_sgtl5000", | 105 | .name = "mxs_sgtl5000", |
98 | .owner = THIS_MODULE, | 106 | .owner = THIS_MODULE, |
@@ -141,10 +149,23 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev) | |||
141 | 149 | ||
142 | card->dev = &pdev->dev; | 150 | card->dev = &pdev->dev; |
143 | 151 | ||
152 | if (of_find_property(np, "audio-routing", NULL)) { | ||
153 | card->dapm_widgets = mxs_sgtl5000_dapm_widgets; | ||
154 | card->num_dapm_widgets = ARRAY_SIZE(mxs_sgtl5000_dapm_widgets); | ||
155 | |||
156 | ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); | ||
157 | if (ret) { | ||
158 | dev_err(&pdev->dev, "failed to parse audio-routing (%d)\n", | ||
159 | ret); | ||
160 | return ret; | ||
161 | } | ||
162 | } | ||
163 | |||
144 | ret = devm_snd_soc_register_card(&pdev->dev, card); | 164 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
145 | if (ret) { | 165 | if (ret) { |
146 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | 166 | if (ret != -EPROBE_DEFER) |
147 | ret); | 167 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", |
168 | ret); | ||
148 | return ret; | 169 | return ret; |
149 | } | 170 | } |
150 | 171 | ||
diff --git a/sound/soc/soc-acpi.c b/sound/soc/soc-acpi.c index 7f43c9bf3d09..3d7e1ff79139 100644 --- a/sound/soc/soc-acpi.c +++ b/sound/soc/soc-acpi.c | |||
@@ -16,39 +16,6 @@ | |||
16 | 16 | ||
17 | #include <sound/soc-acpi.h> | 17 | #include <sound/soc-acpi.h> |
18 | 18 | ||
19 | static acpi_status snd_soc_acpi_find_name(acpi_handle handle, u32 level, | ||
20 | void *context, void **ret) | ||
21 | { | ||
22 | struct acpi_device *adev; | ||
23 | const char *name = NULL; | ||
24 | |||
25 | if (acpi_bus_get_device(handle, &adev)) | ||
26 | return AE_OK; | ||
27 | |||
28 | if (adev->status.present && adev->status.functional) { | ||
29 | name = acpi_dev_name(adev); | ||
30 | *(const char **)ret = name; | ||
31 | return AE_CTRL_TERMINATE; | ||
32 | } | ||
33 | |||
34 | return AE_OK; | ||
35 | } | ||
36 | |||
37 | const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) | ||
38 | { | ||
39 | const char *name = NULL; | ||
40 | acpi_status status; | ||
41 | |||
42 | status = acpi_get_devices(hid, snd_soc_acpi_find_name, NULL, | ||
43 | (void **)&name); | ||
44 | |||
45 | if (ACPI_FAILURE(status) || name[0] == '\0') | ||
46 | return NULL; | ||
47 | |||
48 | return name; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(snd_soc_acpi_find_name_from_hid); | ||
51 | |||
52 | struct snd_soc_acpi_mach * | 19 | struct snd_soc_acpi_mach * |
53 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) | 20 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) |
54 | { | 21 | { |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d1f7e639d5b1..e91879569a0f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -349,120 +349,84 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component) | |||
349 | "ASoC: Failed to create codec register debugfs file\n"); | 349 | "ASoC: Failed to create codec register debugfs file\n"); |
350 | } | 350 | } |
351 | 351 | ||
352 | static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, | 352 | static int codec_list_seq_show(struct seq_file *m, void *v) |
353 | size_t count, loff_t *ppos) | ||
354 | { | 353 | { |
355 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
356 | ssize_t len, ret = 0; | ||
357 | struct snd_soc_codec *codec; | 354 | struct snd_soc_codec *codec; |
358 | 355 | ||
359 | if (!buf) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | mutex_lock(&client_mutex); | 356 | mutex_lock(&client_mutex); |
363 | 357 | ||
364 | list_for_each_entry(codec, &codec_list, list) { | 358 | list_for_each_entry(codec, &codec_list, list) |
365 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", | 359 | seq_printf(m, "%s\n", codec->component.name); |
366 | codec->component.name); | ||
367 | if (len >= 0) | ||
368 | ret += len; | ||
369 | if (ret > PAGE_SIZE) { | ||
370 | ret = PAGE_SIZE; | ||
371 | break; | ||
372 | } | ||
373 | } | ||
374 | 360 | ||
375 | mutex_unlock(&client_mutex); | 361 | mutex_unlock(&client_mutex); |
376 | 362 | ||
377 | if (ret >= 0) | 363 | return 0; |
378 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 364 | } |
379 | |||
380 | kfree(buf); | ||
381 | 365 | ||
382 | return ret; | 366 | static int codec_list_seq_open(struct inode *inode, struct file *file) |
367 | { | ||
368 | return single_open(file, codec_list_seq_show, NULL); | ||
383 | } | 369 | } |
384 | 370 | ||
385 | static const struct file_operations codec_list_fops = { | 371 | static const struct file_operations codec_list_fops = { |
386 | .read = codec_list_read_file, | 372 | .open = codec_list_seq_open, |
387 | .llseek = default_llseek,/* read accesses f_pos */ | 373 | .read = seq_read, |
374 | .llseek = seq_lseek, | ||
375 | .release = single_release, | ||
388 | }; | 376 | }; |
389 | 377 | ||
390 | static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, | 378 | static int dai_list_seq_show(struct seq_file *m, void *v) |
391 | size_t count, loff_t *ppos) | ||
392 | { | 379 | { |
393 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
394 | ssize_t len, ret = 0; | ||
395 | struct snd_soc_component *component; | 380 | struct snd_soc_component *component; |
396 | struct snd_soc_dai *dai; | 381 | struct snd_soc_dai *dai; |
397 | 382 | ||
398 | if (!buf) | ||
399 | return -ENOMEM; | ||
400 | |||
401 | mutex_lock(&client_mutex); | 383 | mutex_lock(&client_mutex); |
402 | 384 | ||
403 | list_for_each_entry(component, &component_list, list) { | 385 | list_for_each_entry(component, &component_list, list) |
404 | list_for_each_entry(dai, &component->dai_list, list) { | 386 | list_for_each_entry(dai, &component->dai_list, list) |
405 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", | 387 | seq_printf(m, "%s\n", dai->name); |
406 | dai->name); | ||
407 | if (len >= 0) | ||
408 | ret += len; | ||
409 | if (ret > PAGE_SIZE) { | ||
410 | ret = PAGE_SIZE; | ||
411 | break; | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | 388 | ||
416 | mutex_unlock(&client_mutex); | 389 | mutex_unlock(&client_mutex); |
417 | 390 | ||
418 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 391 | return 0; |
419 | 392 | } | |
420 | kfree(buf); | ||
421 | 393 | ||
422 | return ret; | 394 | static int dai_list_seq_open(struct inode *inode, struct file *file) |
395 | { | ||
396 | return single_open(file, dai_list_seq_show, NULL); | ||
423 | } | 397 | } |
424 | 398 | ||
425 | static const struct file_operations dai_list_fops = { | 399 | static const struct file_operations dai_list_fops = { |
426 | .read = dai_list_read_file, | 400 | .open = dai_list_seq_open, |
427 | .llseek = default_llseek,/* read accesses f_pos */ | 401 | .read = seq_read, |
402 | .llseek = seq_lseek, | ||
403 | .release = single_release, | ||
428 | }; | 404 | }; |
429 | 405 | ||
430 | static ssize_t platform_list_read_file(struct file *file, | 406 | static int platform_list_seq_show(struct seq_file *m, void *v) |
431 | char __user *user_buf, | ||
432 | size_t count, loff_t *ppos) | ||
433 | { | 407 | { |
434 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
435 | ssize_t len, ret = 0; | ||
436 | struct snd_soc_platform *platform; | 408 | struct snd_soc_platform *platform; |
437 | 409 | ||
438 | if (!buf) | ||
439 | return -ENOMEM; | ||
440 | |||
441 | mutex_lock(&client_mutex); | 410 | mutex_lock(&client_mutex); |
442 | 411 | ||
443 | list_for_each_entry(platform, &platform_list, list) { | 412 | list_for_each_entry(platform, &platform_list, list) |
444 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", | 413 | seq_printf(m, "%s\n", platform->component.name); |
445 | platform->component.name); | ||
446 | if (len >= 0) | ||
447 | ret += len; | ||
448 | if (ret > PAGE_SIZE) { | ||
449 | ret = PAGE_SIZE; | ||
450 | break; | ||
451 | } | ||
452 | } | ||
453 | 414 | ||
454 | mutex_unlock(&client_mutex); | 415 | mutex_unlock(&client_mutex); |
455 | 416 | ||
456 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 417 | return 0; |
457 | 418 | } | |
458 | kfree(buf); | ||
459 | 419 | ||
460 | return ret; | 420 | static int platform_list_seq_open(struct inode *inode, struct file *file) |
421 | { | ||
422 | return single_open(file, platform_list_seq_show, NULL); | ||
461 | } | 423 | } |
462 | 424 | ||
463 | static const struct file_operations platform_list_fops = { | 425 | static const struct file_operations platform_list_fops = { |
464 | .read = platform_list_read_file, | 426 | .open = platform_list_seq_open, |
465 | .llseek = default_llseek,/* read accesses f_pos */ | 427 | .read = seq_read, |
428 | .llseek = seq_lseek, | ||
429 | .release = single_release, | ||
466 | }; | 430 | }; |
467 | 431 | ||
468 | static void soc_init_card_debugfs(struct snd_soc_card *card) | 432 | static void soc_init_card_debugfs(struct snd_soc_card *card) |
@@ -491,7 +455,6 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card) | |||
491 | debugfs_remove_recursive(card->debugfs_card_root); | 455 | debugfs_remove_recursive(card->debugfs_card_root); |
492 | } | 456 | } |
493 | 457 | ||
494 | |||
495 | static void snd_soc_debugfs_init(void) | 458 | static void snd_soc_debugfs_init(void) |
496 | { | 459 | { |
497 | snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); | 460 | snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); |
@@ -598,6 +561,7 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, | |||
598 | 561 | ||
599 | return NULL; | 562 | return NULL; |
600 | } | 563 | } |
564 | EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup); | ||
601 | 565 | ||
602 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, | 566 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, |
603 | const char *dai_link, int stream) | 567 | const char *dai_link, int stream) |
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 20340ade20a7..2bc1c4c17896 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
@@ -34,6 +34,10 @@ int snd_soc_component_read(struct snd_soc_component *component, | |||
34 | ret = regmap_read(component->regmap, reg, val); | 34 | ret = regmap_read(component->regmap, reg, val); |
35 | else if (component->read) | 35 | else if (component->read) |
36 | ret = component->read(component, reg, val); | 36 | ret = component->read(component, reg, val); |
37 | else if (component->driver->read) { | ||
38 | *val = component->driver->read(component, reg); | ||
39 | ret = 0; | ||
40 | } | ||
37 | else | 41 | else |
38 | ret = -EIO; | 42 | ret = -EIO; |
39 | 43 | ||
@@ -70,6 +74,8 @@ int snd_soc_component_write(struct snd_soc_component *component, | |||
70 | return regmap_write(component->regmap, reg, val); | 74 | return regmap_write(component->regmap, reg, val); |
71 | else if (component->write) | 75 | else if (component->write) |
72 | return component->write(component, reg, val); | 76 | return component->write(component, reg, val); |
77 | else if (component->driver->write) | ||
78 | return component->driver->write(component, reg, val); | ||
73 | else | 79 | else |
74 | return -EIO; | 80 | return -EIO; |
75 | } | 81 | } |
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index ae0272f9a091..e6acc281dd37 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile | |||
@@ -46,7 +46,7 @@ $(OBJTOOL_IN): fixdep FORCE | |||
46 | @$(MAKE) $(build)=objtool | 46 | @$(MAKE) $(build)=objtool |
47 | 47 | ||
48 | $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) | 48 | $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) |
49 | @./sync-check.sh | 49 | @$(CONFIG_SHELL) ./sync-check.sh |
50 | $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ | 50 | $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ |
51 | 51 | ||
52 | 52 | ||
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 9b341584eb1b..f40d46e24bcc 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
@@ -428,6 +428,40 @@ static void add_ignores(struct objtool_file *file) | |||
428 | } | 428 | } |
429 | 429 | ||
430 | /* | 430 | /* |
431 | * FIXME: For now, just ignore any alternatives which add retpolines. This is | ||
432 | * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline. | ||
433 | * But it at least allows objtool to understand the control flow *around* the | ||
434 | * retpoline. | ||
435 | */ | ||
436 | static int add_nospec_ignores(struct objtool_file *file) | ||
437 | { | ||
438 | struct section *sec; | ||
439 | struct rela *rela; | ||
440 | struct instruction *insn; | ||
441 | |||
442 | sec = find_section_by_name(file->elf, ".rela.discard.nospec"); | ||
443 | if (!sec) | ||
444 | return 0; | ||
445 | |||
446 | list_for_each_entry(rela, &sec->rela_list, list) { | ||
447 | if (rela->sym->type != STT_SECTION) { | ||
448 | WARN("unexpected relocation symbol type in %s", sec->name); | ||
449 | return -1; | ||
450 | } | ||
451 | |||
452 | insn = find_insn(file, rela->sym->sec, rela->addend); | ||
453 | if (!insn) { | ||
454 | WARN("bad .discard.nospec entry"); | ||
455 | return -1; | ||
456 | } | ||
457 | |||
458 | insn->ignore_alts = true; | ||
459 | } | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | /* | ||
431 | * Find the destination instructions for all jumps. | 465 | * Find the destination instructions for all jumps. |
432 | */ | 466 | */ |
433 | static int add_jump_destinations(struct objtool_file *file) | 467 | static int add_jump_destinations(struct objtool_file *file) |
@@ -456,6 +490,13 @@ static int add_jump_destinations(struct objtool_file *file) | |||
456 | } else if (rela->sym->sec->idx) { | 490 | } else if (rela->sym->sec->idx) { |
457 | dest_sec = rela->sym->sec; | 491 | dest_sec = rela->sym->sec; |
458 | dest_off = rela->sym->sym.st_value + rela->addend + 4; | 492 | dest_off = rela->sym->sym.st_value + rela->addend + 4; |
493 | } else if (strstr(rela->sym->name, "_indirect_thunk_")) { | ||
494 | /* | ||
495 | * Retpoline jumps are really dynamic jumps in | ||
496 | * disguise, so convert them accordingly. | ||
497 | */ | ||
498 | insn->type = INSN_JUMP_DYNAMIC; | ||
499 | continue; | ||
459 | } else { | 500 | } else { |
460 | /* sibling call */ | 501 | /* sibling call */ |
461 | insn->jump_dest = 0; | 502 | insn->jump_dest = 0; |
@@ -502,11 +543,18 @@ static int add_call_destinations(struct objtool_file *file) | |||
502 | dest_off = insn->offset + insn->len + insn->immediate; | 543 | dest_off = insn->offset + insn->len + insn->immediate; |
503 | insn->call_dest = find_symbol_by_offset(insn->sec, | 544 | insn->call_dest = find_symbol_by_offset(insn->sec, |
504 | dest_off); | 545 | dest_off); |
546 | /* | ||
547 | * FIXME: Thanks to retpolines, it's now considered | ||
548 | * normal for a function to call within itself. So | ||
549 | * disable this warning for now. | ||
550 | */ | ||
551 | #if 0 | ||
505 | if (!insn->call_dest) { | 552 | if (!insn->call_dest) { |
506 | WARN_FUNC("can't find call dest symbol at offset 0x%lx", | 553 | WARN_FUNC("can't find call dest symbol at offset 0x%lx", |
507 | insn->sec, insn->offset, dest_off); | 554 | insn->sec, insn->offset, dest_off); |
508 | return -1; | 555 | return -1; |
509 | } | 556 | } |
557 | #endif | ||
510 | } else if (rela->sym->type == STT_SECTION) { | 558 | } else if (rela->sym->type == STT_SECTION) { |
511 | insn->call_dest = find_symbol_by_offset(rela->sym->sec, | 559 | insn->call_dest = find_symbol_by_offset(rela->sym->sec, |
512 | rela->addend+4); | 560 | rela->addend+4); |
@@ -671,12 +719,6 @@ static int add_special_section_alts(struct objtool_file *file) | |||
671 | return ret; | 719 | return ret; |
672 | 720 | ||
673 | list_for_each_entry_safe(special_alt, tmp, &special_alts, list) { | 721 | list_for_each_entry_safe(special_alt, tmp, &special_alts, list) { |
674 | alt = malloc(sizeof(*alt)); | ||
675 | if (!alt) { | ||
676 | WARN("malloc failed"); | ||
677 | ret = -1; | ||
678 | goto out; | ||
679 | } | ||
680 | 722 | ||
681 | orig_insn = find_insn(file, special_alt->orig_sec, | 723 | orig_insn = find_insn(file, special_alt->orig_sec, |
682 | special_alt->orig_off); | 724 | special_alt->orig_off); |
@@ -687,6 +729,10 @@ static int add_special_section_alts(struct objtool_file *file) | |||
687 | goto out; | 729 | goto out; |
688 | } | 730 | } |
689 | 731 | ||
732 | /* Ignore retpoline alternatives. */ | ||
733 | if (orig_insn->ignore_alts) | ||
734 | continue; | ||
735 | |||
690 | new_insn = NULL; | 736 | new_insn = NULL; |
691 | if (!special_alt->group || special_alt->new_len) { | 737 | if (!special_alt->group || special_alt->new_len) { |
692 | new_insn = find_insn(file, special_alt->new_sec, | 738 | new_insn = find_insn(file, special_alt->new_sec, |
@@ -712,6 +758,13 @@ static int add_special_section_alts(struct objtool_file *file) | |||
712 | goto out; | 758 | goto out; |
713 | } | 759 | } |
714 | 760 | ||
761 | alt = malloc(sizeof(*alt)); | ||
762 | if (!alt) { | ||
763 | WARN("malloc failed"); | ||
764 | ret = -1; | ||
765 | goto out; | ||
766 | } | ||
767 | |||
715 | alt->insn = new_insn; | 768 | alt->insn = new_insn; |
716 | list_add_tail(&alt->list, &orig_insn->alts); | 769 | list_add_tail(&alt->list, &orig_insn->alts); |
717 | 770 | ||
@@ -1028,6 +1081,10 @@ static int decode_sections(struct objtool_file *file) | |||
1028 | 1081 | ||
1029 | add_ignores(file); | 1082 | add_ignores(file); |
1030 | 1083 | ||
1084 | ret = add_nospec_ignores(file); | ||
1085 | if (ret) | ||
1086 | return ret; | ||
1087 | |||
1031 | ret = add_jump_destinations(file); | 1088 | ret = add_jump_destinations(file); |
1032 | if (ret) | 1089 | if (ret) |
1033 | return ret; | 1090 | return ret; |
diff --git a/tools/objtool/check.h b/tools/objtool/check.h index 47d9ea70a83d..dbadb304a410 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h | |||
@@ -44,7 +44,7 @@ struct instruction { | |||
44 | unsigned int len; | 44 | unsigned int len; |
45 | unsigned char type; | 45 | unsigned char type; |
46 | unsigned long immediate; | 46 | unsigned long immediate; |
47 | bool alt_group, visited, dead_end, ignore, hint, save, restore; | 47 | bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; |
48 | struct symbol *call_dest; | 48 | struct symbol *call_dest; |
49 | struct instruction *jump_dest; | 49 | struct instruction *jump_dest; |
50 | struct list_head alts; | 50 | struct list_head alts; |
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c index 8591c89c0828..471bbbdb94db 100644 --- a/tools/testing/selftests/bpf/test_align.c +++ b/tools/testing/selftests/bpf/test_align.c | |||
@@ -474,27 +474,7 @@ static struct bpf_align_test tests[] = { | |||
474 | .result = REJECT, | 474 | .result = REJECT, |
475 | .matches = { | 475 | .matches = { |
476 | {4, "R5=pkt(id=0,off=0,r=0,imm=0)"}, | 476 | {4, "R5=pkt(id=0,off=0,r=0,imm=0)"}, |
477 | /* ptr & 0x40 == either 0 or 0x40 */ | 477 | /* R5 bitwise operator &= on pointer prohibited */ |
478 | {5, "R5=inv(id=0,umax_value=64,var_off=(0x0; 0x40))"}, | ||
479 | /* ptr << 2 == unknown, (4n) */ | ||
480 | {7, "R5=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc))"}, | ||
481 | /* (4n) + 14 == (4n+2). We blow our bounds, because | ||
482 | * the add could overflow. | ||
483 | */ | ||
484 | {8, "R5=inv(id=0,var_off=(0x2; 0xfffffffffffffffc))"}, | ||
485 | /* Checked s>=0 */ | ||
486 | {10, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, | ||
487 | /* packet pointer + nonnegative (4n+2) */ | ||
488 | {12, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, | ||
489 | {14, "R4=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, | ||
490 | /* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine. | ||
491 | * We checked the bounds, but it might have been able | ||
492 | * to overflow if the packet pointer started in the | ||
493 | * upper half of the address space. | ||
494 | * So we did not get a 'range' on R6, and the access | ||
495 | * attempt will fail. | ||
496 | */ | ||
497 | {16, "R6=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc))"}, | ||
498 | } | 478 | } |
499 | }, | 479 | }, |
500 | { | 480 | { |
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 939a337128db..5d4f10ac2af2 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -7,7 +7,7 @@ include ../lib.mk | |||
7 | 7 | ||
8 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ | 8 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ |
9 | check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \ | 9 | check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \ |
10 | protection_keys test_vdso | 10 | protection_keys test_vdso test_vsyscall |
11 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | 11 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ |
12 | test_FCMOV test_FCOMI test_FISTTP \ | 12 | test_FCMOV test_FCOMI test_FISTTP \ |
13 | vdso_restorer | 13 | vdso_restorer |
diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c new file mode 100644 index 000000000000..7a744fa7b786 --- /dev/null +++ b/tools/testing/selftests/x86/test_vsyscall.c | |||
@@ -0,0 +1,500 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #define _GNU_SOURCE | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <sys/time.h> | ||
7 | #include <time.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <sys/syscall.h> | ||
10 | #include <unistd.h> | ||
11 | #include <dlfcn.h> | ||
12 | #include <string.h> | ||
13 | #include <inttypes.h> | ||
14 | #include <signal.h> | ||
15 | #include <sys/ucontext.h> | ||
16 | #include <errno.h> | ||
17 | #include <err.h> | ||
18 | #include <sched.h> | ||
19 | #include <stdbool.h> | ||
20 | #include <setjmp.h> | ||
21 | |||
22 | #ifdef __x86_64__ | ||
23 | # define VSYS(x) (x) | ||
24 | #else | ||
25 | # define VSYS(x) 0 | ||
26 | #endif | ||
27 | |||
28 | #ifndef SYS_getcpu | ||
29 | # ifdef __x86_64__ | ||
30 | # define SYS_getcpu 309 | ||
31 | # else | ||
32 | # define SYS_getcpu 318 | ||
33 | # endif | ||
34 | #endif | ||
35 | |||
36 | static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), | ||
37 | int flags) | ||
38 | { | ||
39 | struct sigaction sa; | ||
40 | memset(&sa, 0, sizeof(sa)); | ||
41 | sa.sa_sigaction = handler; | ||
42 | sa.sa_flags = SA_SIGINFO | flags; | ||
43 | sigemptyset(&sa.sa_mask); | ||
44 | if (sigaction(sig, &sa, 0)) | ||
45 | err(1, "sigaction"); | ||
46 | } | ||
47 | |||
48 | /* vsyscalls and vDSO */ | ||
49 | bool should_read_vsyscall = false; | ||
50 | |||
51 | typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); | ||
52 | gtod_t vgtod = (gtod_t)VSYS(0xffffffffff600000); | ||
53 | gtod_t vdso_gtod; | ||
54 | |||
55 | typedef int (*vgettime_t)(clockid_t, struct timespec *); | ||
56 | vgettime_t vdso_gettime; | ||
57 | |||
58 | typedef long (*time_func_t)(time_t *t); | ||
59 | time_func_t vtime = (time_func_t)VSYS(0xffffffffff600400); | ||
60 | time_func_t vdso_time; | ||
61 | |||
62 | typedef long (*getcpu_t)(unsigned *, unsigned *, void *); | ||
63 | getcpu_t vgetcpu = (getcpu_t)VSYS(0xffffffffff600800); | ||
64 | getcpu_t vdso_getcpu; | ||
65 | |||
66 | static void init_vdso(void) | ||
67 | { | ||
68 | void *vdso = dlopen("linux-vdso.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); | ||
69 | if (!vdso) | ||
70 | vdso = dlopen("linux-gate.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); | ||
71 | if (!vdso) { | ||
72 | printf("[WARN]\tfailed to find vDSO\n"); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | vdso_gtod = (gtod_t)dlsym(vdso, "__vdso_gettimeofday"); | ||
77 | if (!vdso_gtod) | ||
78 | printf("[WARN]\tfailed to find gettimeofday in vDSO\n"); | ||
79 | |||
80 | vdso_gettime = (vgettime_t)dlsym(vdso, "__vdso_clock_gettime"); | ||
81 | if (!vdso_gettime) | ||
82 | printf("[WARN]\tfailed to find clock_gettime in vDSO\n"); | ||
83 | |||
84 | vdso_time = (time_func_t)dlsym(vdso, "__vdso_time"); | ||
85 | if (!vdso_time) | ||
86 | printf("[WARN]\tfailed to find time in vDSO\n"); | ||
87 | |||
88 | vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu"); | ||
89 | if (!vdso_getcpu) { | ||
90 | /* getcpu() was never wired up in the 32-bit vDSO. */ | ||
91 | printf("[%s]\tfailed to find getcpu in vDSO\n", | ||
92 | sizeof(long) == 8 ? "WARN" : "NOTE"); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | static int init_vsys(void) | ||
97 | { | ||
98 | #ifdef __x86_64__ | ||
99 | int nerrs = 0; | ||
100 | FILE *maps; | ||
101 | char line[128]; | ||
102 | bool found = false; | ||
103 | |||
104 | maps = fopen("/proc/self/maps", "r"); | ||
105 | if (!maps) { | ||
106 | printf("[WARN]\tCould not open /proc/self/maps -- assuming vsyscall is r-x\n"); | ||
107 | should_read_vsyscall = true; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | while (fgets(line, sizeof(line), maps)) { | ||
112 | char r, x; | ||
113 | void *start, *end; | ||
114 | char name[128]; | ||
115 | if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s", | ||
116 | &start, &end, &r, &x, name) != 5) | ||
117 | continue; | ||
118 | |||
119 | if (strcmp(name, "[vsyscall]")) | ||
120 | continue; | ||
121 | |||
122 | printf("\tvsyscall map: %s", line); | ||
123 | |||
124 | if (start != (void *)0xffffffffff600000 || | ||
125 | end != (void *)0xffffffffff601000) { | ||
126 | printf("[FAIL]\taddress range is nonsense\n"); | ||
127 | nerrs++; | ||
128 | } | ||
129 | |||
130 | printf("\tvsyscall permissions are %c-%c\n", r, x); | ||
131 | should_read_vsyscall = (r == 'r'); | ||
132 | if (x != 'x') { | ||
133 | vgtod = NULL; | ||
134 | vtime = NULL; | ||
135 | vgetcpu = NULL; | ||
136 | } | ||
137 | |||
138 | found = true; | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | fclose(maps); | ||
143 | |||
144 | if (!found) { | ||
145 | printf("\tno vsyscall map in /proc/self/maps\n"); | ||
146 | should_read_vsyscall = false; | ||
147 | vgtod = NULL; | ||
148 | vtime = NULL; | ||
149 | vgetcpu = NULL; | ||
150 | } | ||
151 | |||
152 | return nerrs; | ||
153 | #else | ||
154 | return 0; | ||
155 | #endif | ||
156 | } | ||
157 | |||
158 | /* syscalls */ | ||
159 | static inline long sys_gtod(struct timeval *tv, struct timezone *tz) | ||
160 | { | ||
161 | return syscall(SYS_gettimeofday, tv, tz); | ||
162 | } | ||
163 | |||
164 | static inline int sys_clock_gettime(clockid_t id, struct timespec *ts) | ||
165 | { | ||
166 | return syscall(SYS_clock_gettime, id, ts); | ||
167 | } | ||
168 | |||
169 | static inline long sys_time(time_t *t) | ||
170 | { | ||
171 | return syscall(SYS_time, t); | ||
172 | } | ||
173 | |||
174 | static inline long sys_getcpu(unsigned * cpu, unsigned * node, | ||
175 | void* cache) | ||
176 | { | ||
177 | return syscall(SYS_getcpu, cpu, node, cache); | ||
178 | } | ||
179 | |||
180 | static jmp_buf jmpbuf; | ||
181 | |||
182 | static void sigsegv(int sig, siginfo_t *info, void *ctx_void) | ||
183 | { | ||
184 | siglongjmp(jmpbuf, 1); | ||
185 | } | ||
186 | |||
187 | static double tv_diff(const struct timeval *a, const struct timeval *b) | ||
188 | { | ||
189 | return (double)(a->tv_sec - b->tv_sec) + | ||
190 | (double)((int)a->tv_usec - (int)b->tv_usec) * 1e-6; | ||
191 | } | ||
192 | |||
193 | static int check_gtod(const struct timeval *tv_sys1, | ||
194 | const struct timeval *tv_sys2, | ||
195 | const struct timezone *tz_sys, | ||
196 | const char *which, | ||
197 | const struct timeval *tv_other, | ||
198 | const struct timezone *tz_other) | ||
199 | { | ||
200 | int nerrs = 0; | ||
201 | double d1, d2; | ||
202 | |||
203 | if (tz_other && (tz_sys->tz_minuteswest != tz_other->tz_minuteswest || tz_sys->tz_dsttime != tz_other->tz_dsttime)) { | ||
204 | printf("[FAIL] %s tz mismatch\n", which); | ||
205 | nerrs++; | ||
206 | } | ||
207 | |||
208 | d1 = tv_diff(tv_other, tv_sys1); | ||
209 | d2 = tv_diff(tv_sys2, tv_other); | ||
210 | printf("\t%s time offsets: %lf %lf\n", which, d1, d2); | ||
211 | |||
212 | if (d1 < 0 || d2 < 0) { | ||
213 | printf("[FAIL]\t%s time was inconsistent with the syscall\n", which); | ||
214 | nerrs++; | ||
215 | } else { | ||
216 | printf("[OK]\t%s gettimeofday()'s timeval was okay\n", which); | ||
217 | } | ||
218 | |||
219 | return nerrs; | ||
220 | } | ||
221 | |||
222 | static int test_gtod(void) | ||
223 | { | ||
224 | struct timeval tv_sys1, tv_sys2, tv_vdso, tv_vsys; | ||
225 | struct timezone tz_sys, tz_vdso, tz_vsys; | ||
226 | long ret_vdso = -1; | ||
227 | long ret_vsys = -1; | ||
228 | int nerrs = 0; | ||
229 | |||
230 | printf("[RUN]\ttest gettimeofday()\n"); | ||
231 | |||
232 | if (sys_gtod(&tv_sys1, &tz_sys) != 0) | ||
233 | err(1, "syscall gettimeofday"); | ||
234 | if (vdso_gtod) | ||
235 | ret_vdso = vdso_gtod(&tv_vdso, &tz_vdso); | ||
236 | if (vgtod) | ||
237 | ret_vsys = vgtod(&tv_vsys, &tz_vsys); | ||
238 | if (sys_gtod(&tv_sys2, &tz_sys) != 0) | ||
239 | err(1, "syscall gettimeofday"); | ||
240 | |||
241 | if (vdso_gtod) { | ||
242 | if (ret_vdso == 0) { | ||
243 | nerrs += check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vDSO", &tv_vdso, &tz_vdso); | ||
244 | } else { | ||
245 | printf("[FAIL]\tvDSO gettimeofday() failed: %ld\n", ret_vdso); | ||
246 | nerrs++; | ||
247 | } | ||
248 | } | ||
249 | |||
250 | if (vgtod) { | ||
251 | if (ret_vsys == 0) { | ||
252 | nerrs += check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vsyscall", &tv_vsys, &tz_vsys); | ||
253 | } else { | ||
254 | printf("[FAIL]\tvsys gettimeofday() failed: %ld\n", ret_vsys); | ||
255 | nerrs++; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return nerrs; | ||
260 | } | ||
261 | |||
262 | static int test_time(void) { | ||
263 | int nerrs = 0; | ||
264 | |||
265 | printf("[RUN]\ttest time()\n"); | ||
266 | long t_sys1, t_sys2, t_vdso = 0, t_vsys = 0; | ||
267 | long t2_sys1 = -1, t2_sys2 = -1, t2_vdso = -1, t2_vsys = -1; | ||
268 | t_sys1 = sys_time(&t2_sys1); | ||
269 | if (vdso_time) | ||
270 | t_vdso = vdso_time(&t2_vdso); | ||
271 | if (vtime) | ||
272 | t_vsys = vtime(&t2_vsys); | ||
273 | t_sys2 = sys_time(&t2_sys2); | ||
274 | if (t_sys1 < 0 || t_sys1 != t2_sys1 || t_sys2 < 0 || t_sys2 != t2_sys2) { | ||
275 | printf("[FAIL]\tsyscall failed (ret1:%ld output1:%ld ret2:%ld output2:%ld)\n", t_sys1, t2_sys1, t_sys2, t2_sys2); | ||
276 | nerrs++; | ||
277 | return nerrs; | ||
278 | } | ||
279 | |||
280 | if (vdso_time) { | ||
281 | if (t_vdso < 0 || t_vdso != t2_vdso) { | ||
282 | printf("[FAIL]\tvDSO failed (ret:%ld output:%ld)\n", t_vdso, t2_vdso); | ||
283 | nerrs++; | ||
284 | } else if (t_vdso < t_sys1 || t_vdso > t_sys2) { | ||
285 | printf("[FAIL]\tvDSO returned the wrong time (%ld %ld %ld)\n", t_sys1, t_vdso, t_sys2); | ||
286 | nerrs++; | ||
287 | } else { | ||
288 | printf("[OK]\tvDSO time() is okay\n"); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if (vtime) { | ||
293 | if (t_vsys < 0 || t_vsys != t2_vsys) { | ||
294 | printf("[FAIL]\tvsyscall failed (ret:%ld output:%ld)\n", t_vsys, t2_vsys); | ||
295 | nerrs++; | ||
296 | } else if (t_vsys < t_sys1 || t_vsys > t_sys2) { | ||
297 | printf("[FAIL]\tvsyscall returned the wrong time (%ld %ld %ld)\n", t_sys1, t_vsys, t_sys2); | ||
298 | nerrs++; | ||
299 | } else { | ||
300 | printf("[OK]\tvsyscall time() is okay\n"); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return nerrs; | ||
305 | } | ||
306 | |||
307 | static int test_getcpu(int cpu) | ||
308 | { | ||
309 | int nerrs = 0; | ||
310 | long ret_sys, ret_vdso = -1, ret_vsys = -1; | ||
311 | |||
312 | printf("[RUN]\tgetcpu() on CPU %d\n", cpu); | ||
313 | |||
314 | cpu_set_t cpuset; | ||
315 | CPU_ZERO(&cpuset); | ||
316 | CPU_SET(cpu, &cpuset); | ||
317 | if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) { | ||
318 | printf("[SKIP]\tfailed to force CPU %d\n", cpu); | ||
319 | return nerrs; | ||
320 | } | ||
321 | |||
322 | unsigned cpu_sys, cpu_vdso, cpu_vsys, node_sys, node_vdso, node_vsys; | ||
323 | unsigned node = 0; | ||
324 | bool have_node = false; | ||
325 | ret_sys = sys_getcpu(&cpu_sys, &node_sys, 0); | ||
326 | if (vdso_getcpu) | ||
327 | ret_vdso = vdso_getcpu(&cpu_vdso, &node_vdso, 0); | ||
328 | if (vgetcpu) | ||
329 | ret_vsys = vgetcpu(&cpu_vsys, &node_vsys, 0); | ||
330 | |||
331 | if (ret_sys == 0) { | ||
332 | if (cpu_sys != cpu) { | ||
333 | printf("[FAIL]\tsyscall reported CPU %hu but should be %d\n", cpu_sys, cpu); | ||
334 | nerrs++; | ||
335 | } | ||
336 | |||
337 | have_node = true; | ||
338 | node = node_sys; | ||
339 | } | ||
340 | |||
341 | if (vdso_getcpu) { | ||
342 | if (ret_vdso) { | ||
343 | printf("[FAIL]\tvDSO getcpu() failed\n"); | ||
344 | nerrs++; | ||
345 | } else { | ||
346 | if (!have_node) { | ||
347 | have_node = true; | ||
348 | node = node_vdso; | ||
349 | } | ||
350 | |||
351 | if (cpu_vdso != cpu) { | ||
352 | printf("[FAIL]\tvDSO reported CPU %hu but should be %d\n", cpu_vdso, cpu); | ||
353 | nerrs++; | ||
354 | } else { | ||
355 | printf("[OK]\tvDSO reported correct CPU\n"); | ||
356 | } | ||
357 | |||
358 | if (node_vdso != node) { | ||
359 | printf("[FAIL]\tvDSO reported node %hu but should be %hu\n", node_vdso, node); | ||
360 | nerrs++; | ||
361 | } else { | ||
362 | printf("[OK]\tvDSO reported correct node\n"); | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
367 | if (vgetcpu) { | ||
368 | if (ret_vsys) { | ||
369 | printf("[FAIL]\tvsyscall getcpu() failed\n"); | ||
370 | nerrs++; | ||
371 | } else { | ||
372 | if (!have_node) { | ||
373 | have_node = true; | ||
374 | node = node_vsys; | ||
375 | } | ||
376 | |||
377 | if (cpu_vsys != cpu) { | ||
378 | printf("[FAIL]\tvsyscall reported CPU %hu but should be %d\n", cpu_vsys, cpu); | ||
379 | nerrs++; | ||
380 | } else { | ||
381 | printf("[OK]\tvsyscall reported correct CPU\n"); | ||
382 | } | ||
383 | |||
384 | if (node_vsys != node) { | ||
385 | printf("[FAIL]\tvsyscall reported node %hu but should be %hu\n", node_vsys, node); | ||
386 | nerrs++; | ||
387 | } else { | ||
388 | printf("[OK]\tvsyscall reported correct node\n"); | ||
389 | } | ||
390 | } | ||
391 | } | ||
392 | |||
393 | return nerrs; | ||
394 | } | ||
395 | |||
396 | static int test_vsys_r(void) | ||
397 | { | ||
398 | #ifdef __x86_64__ | ||
399 | printf("[RUN]\tChecking read access to the vsyscall page\n"); | ||
400 | bool can_read; | ||
401 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
402 | *(volatile int *)0xffffffffff600000; | ||
403 | can_read = true; | ||
404 | } else { | ||
405 | can_read = false; | ||
406 | } | ||
407 | |||
408 | if (can_read && !should_read_vsyscall) { | ||
409 | printf("[FAIL]\tWe have read access, but we shouldn't\n"); | ||
410 | return 1; | ||
411 | } else if (!can_read && should_read_vsyscall) { | ||
412 | printf("[FAIL]\tWe don't have read access, but we should\n"); | ||
413 | return 1; | ||
414 | } else { | ||
415 | printf("[OK]\tgot expected result\n"); | ||
416 | } | ||
417 | #endif | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | |||
423 | #ifdef __x86_64__ | ||
424 | #define X86_EFLAGS_TF (1UL << 8) | ||
425 | static volatile sig_atomic_t num_vsyscall_traps; | ||
426 | |||
427 | static unsigned long get_eflags(void) | ||
428 | { | ||
429 | unsigned long eflags; | ||
430 | asm volatile ("pushfq\n\tpopq %0" : "=rm" (eflags)); | ||
431 | return eflags; | ||
432 | } | ||
433 | |||
434 | static void set_eflags(unsigned long eflags) | ||
435 | { | ||
436 | asm volatile ("pushq %0\n\tpopfq" : : "rm" (eflags) : "flags"); | ||
437 | } | ||
438 | |||
439 | static void sigtrap(int sig, siginfo_t *info, void *ctx_void) | ||
440 | { | ||
441 | ucontext_t *ctx = (ucontext_t *)ctx_void; | ||
442 | unsigned long ip = ctx->uc_mcontext.gregs[REG_RIP]; | ||
443 | |||
444 | if (((ip ^ 0xffffffffff600000UL) & ~0xfffUL) == 0) | ||
445 | num_vsyscall_traps++; | ||
446 | } | ||
447 | |||
448 | static int test_native_vsyscall(void) | ||
449 | { | ||
450 | time_t tmp; | ||
451 | bool is_native; | ||
452 | |||
453 | if (!vtime) | ||
454 | return 0; | ||
455 | |||
456 | printf("[RUN]\tchecking for native vsyscall\n"); | ||
457 | sethandler(SIGTRAP, sigtrap, 0); | ||
458 | set_eflags(get_eflags() | X86_EFLAGS_TF); | ||
459 | vtime(&tmp); | ||
460 | set_eflags(get_eflags() & ~X86_EFLAGS_TF); | ||
461 | |||
462 | /* | ||
463 | * If vsyscalls are emulated, we expect a single trap in the | ||
464 | * vsyscall page -- the call instruction will trap with RIP | ||
465 | * pointing to the entry point before emulation takes over. | ||
466 | * In native mode, we expect two traps, since whatever code | ||
467 | * the vsyscall page contains will be more than just a ret | ||
468 | * instruction. | ||
469 | */ | ||
470 | is_native = (num_vsyscall_traps > 1); | ||
471 | |||
472 | printf("\tvsyscalls are %s (%d instructions in vsyscall page)\n", | ||
473 | (is_native ? "native" : "emulated"), | ||
474 | (int)num_vsyscall_traps); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | #endif | ||
479 | |||
480 | int main(int argc, char **argv) | ||
481 | { | ||
482 | int nerrs = 0; | ||
483 | |||
484 | init_vdso(); | ||
485 | nerrs += init_vsys(); | ||
486 | |||
487 | nerrs += test_gtod(); | ||
488 | nerrs += test_time(); | ||
489 | nerrs += test_getcpu(0); | ||
490 | nerrs += test_getcpu(1); | ||
491 | |||
492 | sethandler(SIGSEGV, sigsegv, 0); | ||
493 | nerrs += test_vsys_r(); | ||
494 | |||
495 | #ifdef __x86_64__ | ||
496 | nerrs += test_native_vsyscall(); | ||
497 | #endif | ||
498 | |||
499 | return nerrs ? 1 : 0; | ||
500 | } | ||