diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-03-19 16:15:46 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-03-19 16:15:46 -0400 |
commit | 566b60c04ab230b8cc3845f964306f99504b18df (patch) | |
tree | 1897a526488c3496f4ffe5eebb39a1dd41ab731d | |
parent | 3ba4cea21901d90d703b52e4a806fbafa86037a6 (diff) | |
parent | c7edc9e326d53ca5ef9bed82de0740c6b107d55b (diff) |
Merge branch 'uprobes-v7' of git://git.linaro.org/people/dave.long/linux into devel-stable
This patch series adds basic uprobes support to ARM. It is based on
patches developed earlier by Rabin Vincent. That approach of adding
hooks into the kprobes instruction parsing code was not well received.
This approach separates the ARM instruction parsing code in kprobes out
into a separate set of functions which can be used by both kprobes and
uprobes. Both kprobes and uprobes then provide their own semantic action
tables to process the results of the parsing.
558 files changed, 8919 insertions, 5908 deletions
diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index a2ccec35ffce..ad22fb0ee765 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty | |||
@@ -3,8 +3,7 @@ Date: Nov 2010 | |||
3 | Contact: Kay Sievers <kay.sievers@vrfy.org> | 3 | Contact: Kay Sievers <kay.sievers@vrfy.org> |
4 | Description: | 4 | Description: |
5 | Shows the list of currently configured | 5 | Shows the list of currently configured |
6 | tty devices used for the console, | 6 | console devices, like 'tty1 ttyS0'. |
7 | like 'tty1 ttyS0'. | ||
8 | The last entry in the file is the active | 7 | The last entry in the file is the active |
9 | device connected to /dev/console. | 8 | device connected to /dev/console. |
10 | The file supports poll() to detect virtual | 9 | The file supports poll() to detect virtual |
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a8d01005f480..10a93696e55a 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt | |||
@@ -82,7 +82,19 @@ Most of the hard work is done for the driver in the PCI layer. It simply | |||
82 | has to request that the PCI layer set up the MSI capability for this | 82 | has to request that the PCI layer set up the MSI capability for this |
83 | device. | 83 | device. |
84 | 84 | ||
85 | 4.2.1 pci_enable_msi_range | 85 | 4.2.1 pci_enable_msi |
86 | |||
87 | int pci_enable_msi(struct pci_dev *dev) | ||
88 | |||
89 | A successful call allocates ONE interrupt to the device, regardless | ||
90 | of how many MSIs the device supports. The device is switched from | ||
91 | pin-based interrupt mode to MSI mode. The dev->irq number is changed | ||
92 | to a new number which represents the message signaled interrupt; | ||
93 | consequently, this function should be called before the driver calls | ||
94 | request_irq(), because an MSI is delivered via a vector that is | ||
95 | different from the vector of a pin-based interrupt. | ||
96 | |||
97 | 4.2.2 pci_enable_msi_range | ||
86 | 98 | ||
87 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | 99 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) |
88 | 100 | ||
@@ -147,6 +159,11 @@ static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | |||
147 | return pci_enable_msi_range(pdev, nvec, nvec); | 159 | return pci_enable_msi_range(pdev, nvec, nvec); |
148 | } | 160 | } |
149 | 161 | ||
162 | Note, unlike pci_enable_msi_exact() function, which could be also used to | ||
163 | enable a particular number of MSI-X interrupts, pci_enable_msi_range() | ||
164 | returns either a negative errno or 'nvec' (not negative errno or 0 - as | ||
165 | pci_enable_msi_exact() does). | ||
166 | |||
150 | 4.2.1.3 Single MSI mode | 167 | 4.2.1.3 Single MSI mode |
151 | 168 | ||
152 | The most notorious example of the request type described above is | 169 | The most notorious example of the request type described above is |
@@ -158,7 +175,27 @@ static int foo_driver_enable_single_msi(struct pci_dev *pdev) | |||
158 | return pci_enable_msi_range(pdev, 1, 1); | 175 | return pci_enable_msi_range(pdev, 1, 1); |
159 | } | 176 | } |
160 | 177 | ||
161 | 4.2.2 pci_disable_msi | 178 | Note, unlike pci_enable_msi() function, which could be also used to |
179 | enable the single MSI mode, pci_enable_msi_range() returns either a | ||
180 | negative errno or 1 (not negative errno or 0 - as pci_enable_msi() | ||
181 | does). | ||
182 | |||
183 | 4.2.3 pci_enable_msi_exact | ||
184 | |||
185 | int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
186 | |||
187 | This variation on pci_enable_msi_range() call allows a device driver to | ||
188 | request exactly 'nvec' MSIs. | ||
189 | |||
190 | If this function returns a negative number, it indicates an error and | ||
191 | the driver should not attempt to request any more MSI interrupts for | ||
192 | this device. | ||
193 | |||
194 | By contrast with pci_enable_msi_range() function, pci_enable_msi_exact() | ||
195 | returns zero in case of success, which indicates MSI interrupts have been | ||
196 | successfully allocated. | ||
197 | |||
198 | 4.2.4 pci_disable_msi | ||
162 | 199 | ||
163 | void pci_disable_msi(struct pci_dev *dev) | 200 | void pci_disable_msi(struct pci_dev *dev) |
164 | 201 | ||
@@ -172,7 +209,7 @@ on any interrupt for which it previously called request_irq(). | |||
172 | Failure to do so results in a BUG_ON(), leaving the device with | 209 | Failure to do so results in a BUG_ON(), leaving the device with |
173 | MSI enabled and thus leaking its vector. | 210 | MSI enabled and thus leaking its vector. |
174 | 211 | ||
175 | 4.2.3 pci_msi_vec_count | 212 | 4.2.4 pci_msi_vec_count |
176 | 213 | ||
177 | int pci_msi_vec_count(struct pci_dev *dev) | 214 | int pci_msi_vec_count(struct pci_dev *dev) |
178 | 215 | ||
@@ -257,8 +294,8 @@ possible, likely up to the limit returned by pci_msix_vec_count() function: | |||
257 | 294 | ||
258 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 295 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
259 | { | 296 | { |
260 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | 297 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, |
261 | 1, nvec); | 298 | 1, nvec); |
262 | } | 299 | } |
263 | 300 | ||
264 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, | 301 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, |
@@ -269,8 +306,8 @@ In this case the function could look like this: | |||
269 | 306 | ||
270 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 307 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
271 | { | 308 | { |
272 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | 309 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, |
273 | FOO_DRIVER_MINIMUM_NVEC, nvec); | 310 | FOO_DRIVER_MINIMUM_NVEC, nvec); |
274 | } | 311 | } |
275 | 312 | ||
276 | 4.3.1.2 Exact number of MSI-X interrupts | 313 | 4.3.1.2 Exact number of MSI-X interrupts |
@@ -282,10 +319,15 @@ parameters: | |||
282 | 319 | ||
283 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 320 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
284 | { | 321 | { |
285 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | 322 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, |
286 | nvec, nvec); | 323 | nvec, nvec); |
287 | } | 324 | } |
288 | 325 | ||
326 | Note, unlike pci_enable_msix_exact() function, which could be also used to | ||
327 | enable a particular number of MSI-X interrupts, pci_enable_msix_range() | ||
328 | returns either a negative errno or 'nvec' (not negative errno or 0 - as | ||
329 | pci_enable_msix_exact() does). | ||
330 | |||
289 | 4.3.1.3 Specific requirements to the number of MSI-X interrupts | 331 | 4.3.1.3 Specific requirements to the number of MSI-X interrupts |
290 | 332 | ||
291 | As noted above, there could be devices that can not operate with just any | 333 | As noted above, there could be devices that can not operate with just any |
@@ -332,7 +374,64 @@ Note how pci_enable_msix_range() return value is analized for a fallback - | |||
332 | any error code other than -ENOSPC indicates a fatal error and should not | 374 | any error code other than -ENOSPC indicates a fatal error and should not |
333 | be retried. | 375 | be retried. |
334 | 376 | ||
335 | 4.3.2 pci_disable_msix | 377 | 4.3.2 pci_enable_msix_exact |
378 | |||
379 | int pci_enable_msix_exact(struct pci_dev *dev, | ||
380 | struct msix_entry *entries, int nvec) | ||
381 | |||
382 | This variation on pci_enable_msix_range() call allows a device driver to | ||
383 | request exactly 'nvec' MSI-Xs. | ||
384 | |||
385 | If this function returns a negative number, it indicates an error and | ||
386 | the driver should not attempt to allocate any more MSI-X interrupts for | ||
387 | this device. | ||
388 | |||
389 | By contrast with pci_enable_msix_range() function, pci_enable_msix_exact() | ||
390 | returns zero in case of success, which indicates MSI-X interrupts have been | ||
391 | successfully allocated. | ||
392 | |||
393 | Another version of a routine that enables MSI-X mode for a device with | ||
394 | specific requirements described in chapter 4.3.1.3 might look like this: | ||
395 | |||
396 | /* | ||
397 | * Assume 'minvec' and 'maxvec' are non-zero | ||
398 | */ | ||
399 | static int foo_driver_enable_msix(struct foo_adapter *adapter, | ||
400 | int minvec, int maxvec) | ||
401 | { | ||
402 | int rc; | ||
403 | |||
404 | minvec = roundup_pow_of_two(minvec); | ||
405 | maxvec = rounddown_pow_of_two(maxvec); | ||
406 | |||
407 | if (minvec > maxvec) | ||
408 | return -ERANGE; | ||
409 | |||
410 | retry: | ||
411 | rc = pci_enable_msix_exact(adapter->pdev, | ||
412 | adapter->msix_entries, maxvec); | ||
413 | |||
414 | /* | ||
415 | * -ENOSPC is the only error code allowed to be analyzed | ||
416 | */ | ||
417 | if (rc == -ENOSPC) { | ||
418 | if (maxvec == 1) | ||
419 | return -ENOSPC; | ||
420 | |||
421 | maxvec /= 2; | ||
422 | |||
423 | if (minvec > maxvec) | ||
424 | return -ENOSPC; | ||
425 | |||
426 | goto retry; | ||
427 | } else if (rc < 0) { | ||
428 | return rc; | ||
429 | } | ||
430 | |||
431 | return maxvec; | ||
432 | } | ||
433 | |||
434 | 4.3.3 pci_disable_msix | ||
336 | 435 | ||
337 | void pci_disable_msix(struct pci_dev *dev) | 436 | void pci_disable_msix(struct pci_dev *dev) |
338 | 437 | ||
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt index 34dc40cffdfd..af9b4a0d902b 100644 --- a/Documentation/devicetree/bindings/arm/omap/omap.txt +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt | |||
@@ -91,7 +91,7 @@ Boards: | |||
91 | compatible = "ti,omap3-beagle", "ti,omap3" | 91 | compatible = "ti,omap3-beagle", "ti,omap3" |
92 | 92 | ||
93 | - OMAP3 Tobi with Overo : Commercial expansion board with daughter board | 93 | - OMAP3 Tobi with Overo : Commercial expansion board with daughter board |
94 | compatible = "ti,omap3-tobi", "ti,omap3-overo", "ti,omap3" | 94 | compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap3" |
95 | 95 | ||
96 | - OMAP4 SDP : Software Development Board | 96 | - OMAP4 SDP : Software Development Board |
97 | compatible = "ti,omap4-sdp", "ti,omap4430" | 97 | compatible = "ti,omap4-sdp", "ti,omap4430" |
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt index 68b83ecc3850..ee9be9961524 100644 --- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt | |||
@@ -1,12 +1,16 @@ | |||
1 | * Freescale Smart Direct Memory Access (SDMA) Controller for i.MX | 1 | * Freescale Smart Direct Memory Access (SDMA) Controller for i.MX |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : Should be "fsl,imx31-sdma", "fsl,imx31-to1-sdma", | 4 | - compatible : Should be one of |
5 | "fsl,imx31-to2-sdma", "fsl,imx35-sdma", "fsl,imx35-to1-sdma", | 5 | "fsl,imx25-sdma" |
6 | "fsl,imx35-to2-sdma", "fsl,imx51-sdma", "fsl,imx53-sdma" or | 6 | "fsl,imx31-sdma", "fsl,imx31-to1-sdma", "fsl,imx31-to2-sdma" |
7 | "fsl,imx6q-sdma". The -to variants should be preferred since they | 7 | "fsl,imx35-sdma", "fsl,imx35-to1-sdma", "fsl,imx35-to2-sdma" |
8 | allow to determnine the correct ROM script addresses needed for | 8 | "fsl,imx51-sdma" |
9 | the driver to work without additional firmware. | 9 | "fsl,imx53-sdma" |
10 | "fsl,imx6q-sdma" | ||
11 | The -to variants should be preferred since they allow to determnine the | ||
12 | correct ROM script addresses needed for the driver to work without additional | ||
13 | firmware. | ||
10 | - reg : Should contain SDMA registers location and length | 14 | - reg : Should contain SDMA registers location and length |
11 | - interrupts : Should contain SDMA interrupt | 15 | - interrupts : Should contain SDMA interrupt |
12 | - #dma-cells : Must be <3>. | 16 | - #dma-cells : Must be <3>. |
diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt new file mode 100644 index 000000000000..3dd3d0bf112f --- /dev/null +++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt | |||
@@ -0,0 +1,58 @@ | |||
1 | STMicroelectronics SoC DWMAC glue layer controller | ||
2 | |||
3 | The device node has following properties. | ||
4 | |||
5 | Required properties: | ||
6 | - compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac" or | ||
7 | "st,stid127-dwmac". | ||
8 | - reg : Offset of the glue configuration register map in system | ||
9 | configuration regmap pointed by st,syscon property and size. | ||
10 | |||
11 | - reg-names : Should be "sti-ethconf". | ||
12 | |||
13 | - st,syscon : Should be phandle to system configuration node which | ||
14 | encompases this glue registers. | ||
15 | |||
16 | - st,tx-retime-src: On STi Parts for Giga bit speeds, 125Mhz clocks can be | ||
17 | wired up in from different sources. One via TXCLK pin and other via CLK_125 | ||
18 | pin. This wiring is totally board dependent. However the retiming glue | ||
19 | logic should be configured accordingly. Possible values for this property | ||
20 | |||
21 | "txclk" - if 125Mhz clock is wired up via txclk line. | ||
22 | "clk_125" - if 125Mhz clock is wired up via clk_125 line. | ||
23 | |||
24 | This property is only valid for Giga bit setup( GMII, RGMII), and it is | ||
25 | un-used for non-giga bit (MII and RMII) setups. Also note that internal | ||
26 | clockgen can not generate stable 125Mhz clock. | ||
27 | |||
28 | - st,ext-phyclk: This boolean property indicates who is generating the clock | ||
29 | for tx and rx. This property is only valid for RMII case where the clock can | ||
30 | be generated from the MAC or PHY. | ||
31 | |||
32 | - clock-names: should be "sti-ethclk". | ||
33 | - clocks: Should point to ethernet clockgen which can generate phyclk. | ||
34 | |||
35 | |||
36 | Example: | ||
37 | |||
38 | ethernet0: dwmac@fe810000 { | ||
39 | device_type = "network"; | ||
40 | compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710"; | ||
41 | reg = <0xfe810000 0x8000>, <0x8bc 0x4>; | ||
42 | reg-names = "stmmaceth", "sti-ethconf"; | ||
43 | interrupts = <0 133 0>, <0 134 0>, <0 135 0>; | ||
44 | interrupt-names = "macirq", "eth_wake_irq", "eth_lpi"; | ||
45 | phy-mode = "mii"; | ||
46 | |||
47 | st,syscon = <&syscfg_rear>; | ||
48 | |||
49 | snps,pbl = <32>; | ||
50 | snps,mixed-burst; | ||
51 | |||
52 | resets = <&softreset STIH416_ETH0_SOFTRESET>; | ||
53 | reset-names = "stmmaceth"; | ||
54 | pinctrl-0 = <&pinctrl_mii0>; | ||
55 | pinctrl-names = "default"; | ||
56 | clocks = <&CLK_S_GMAC0_PHY>; | ||
57 | clock-names = "stmmaceth"; | ||
58 | }; | ||
diff --git a/Documentation/networking/3c505.txt b/Documentation/networking/3c505.txt deleted file mode 100644 index 72f38b13101d..000000000000 --- a/Documentation/networking/3c505.txt +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | The 3Com Etherlink Plus (3c505) driver. | ||
2 | |||
3 | This driver now uses DMA. There is currently no support for PIO operation. | ||
4 | The default DMA channel is 6; this is _not_ autoprobed, so you must | ||
5 | make sure you configure it correctly. If loading the driver as a | ||
6 | module, you can do this with "modprobe 3c505 dma=n". If the driver is | ||
7 | linked statically into the kernel, you must either use an "ether=" | ||
8 | statement on the command line, or change the definition of ELP_DMA in 3c505.h. | ||
9 | |||
10 | The driver will warn you if it has to fall back on the compiled in | ||
11 | default DMA channel. | ||
12 | |||
13 | If no base address is given at boot time, the driver will autoprobe | ||
14 | ports 0x300, 0x280 and 0x310 (in that order). If no IRQ is given, the driver | ||
15 | will try to probe for it. | ||
16 | |||
17 | The driver can be used as a loadable module. | ||
18 | |||
19 | Theoretically, one instance of the driver can now run multiple cards, | ||
20 | in the standard way (when loading a module, say "modprobe 3c505 | ||
21 | io=0x300,0x340 irq=10,11 dma=6,7" or whatever). I have not tested | ||
22 | this, though. | ||
23 | |||
24 | The driver may now support revision 2 hardware; the dependency on | ||
25 | being able to read the host control register has been removed. This | ||
26 | is also untested, since I don't have a suitable card. | ||
27 | |||
28 | Known problems: | ||
29 | I still see "DMA upload timed out" messages from time to time. These | ||
30 | seem to be fairly non-fatal though. | ||
31 | The card is old and slow. | ||
32 | |||
33 | To do: | ||
34 | Improve probe/setup code | ||
35 | Test multicast and promiscuous operation | ||
36 | |||
37 | Authors: | ||
38 | The driver is mainly written by Craig Southeren, email | ||
39 | <craigs@ineluki.apana.org.au>. | ||
40 | Parts of the driver (adapting the driver to 1.1.4+ kernels, | ||
41 | IRQ/address detection, some changes) and this README by | ||
42 | Juha Laiho <jlaiho@ichaos.nullnet.fi>. | ||
43 | DMA mode, more fixes, etc, by Philip Blundell <pjb27@cam.ac.uk> | ||
44 | Multicard support, Software configurable DMA, etc., by | ||
45 | Christopher Collins <ccollins@pcug.org.au> | ||
diff --git a/MAINTAINERS b/MAINTAINERS index fb08dcececf1..c6d0e93eff62 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -538,7 +538,7 @@ F: arch/alpha/ | |||
538 | ALTERA UART/JTAG UART SERIAL DRIVERS | 538 | ALTERA UART/JTAG UART SERIAL DRIVERS |
539 | M: Tobias Klauser <tklauser@distanz.ch> | 539 | M: Tobias Klauser <tklauser@distanz.ch> |
540 | L: linux-serial@vger.kernel.org | 540 | L: linux-serial@vger.kernel.org |
541 | L: nios2-dev@sopc.et.ntust.edu.tw (moderated for non-subscribers) | 541 | L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) |
542 | S: Maintained | 542 | S: Maintained |
543 | F: drivers/tty/serial/altera_uart.c | 543 | F: drivers/tty/serial/altera_uart.c |
544 | F: drivers/tty/serial/altera_jtaguart.c | 544 | F: drivers/tty/serial/altera_jtaguart.c |
@@ -1860,6 +1860,7 @@ F: drivers/net/ethernet/broadcom/bnx2x/ | |||
1860 | 1860 | ||
1861 | BROADCOM BCM281XX/BCM11XXX ARM ARCHITECTURE | 1861 | BROADCOM BCM281XX/BCM11XXX ARM ARCHITECTURE |
1862 | M: Christian Daudt <bcm@fixthebug.org> | 1862 | M: Christian Daudt <bcm@fixthebug.org> |
1863 | M: Matt Porter <mporter@linaro.org> | ||
1863 | L: bcm-kernel-feedback-list@broadcom.com | 1864 | L: bcm-kernel-feedback-list@broadcom.com |
1864 | T: git git://git.github.com/broadcom/bcm11351 | 1865 | T: git git://git.github.com/broadcom/bcm11351 |
1865 | S: Maintained | 1866 | S: Maintained |
@@ -2408,8 +2409,10 @@ F: tools/power/cpupower/ | |||
2408 | 2409 | ||
2409 | CPUSETS | 2410 | CPUSETS |
2410 | M: Li Zefan <lizefan@huawei.com> | 2411 | M: Li Zefan <lizefan@huawei.com> |
2412 | L: cgroups@vger.kernel.org | ||
2411 | W: http://www.bullopensource.org/cpuset/ | 2413 | W: http://www.bullopensource.org/cpuset/ |
2412 | W: http://oss.sgi.com/projects/cpusets/ | 2414 | W: http://oss.sgi.com/projects/cpusets/ |
2415 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git | ||
2413 | S: Maintained | 2416 | S: Maintained |
2414 | F: Documentation/cgroups/cpusets.txt | 2417 | F: Documentation/cgroups/cpusets.txt |
2415 | F: include/linux/cpuset.h | 2418 | F: include/linux/cpuset.h |
@@ -2608,9 +2611,9 @@ DC395x SCSI driver | |||
2608 | M: Oliver Neukum <oliver@neukum.org> | 2611 | M: Oliver Neukum <oliver@neukum.org> |
2609 | M: Ali Akcaagac <aliakc@web.de> | 2612 | M: Ali Akcaagac <aliakc@web.de> |
2610 | M: Jamie Lenehan <lenehan@twibble.org> | 2613 | M: Jamie Lenehan <lenehan@twibble.org> |
2611 | W: http://twibble.org/dist/dc395x/ | ||
2612 | L: dc395x@twibble.org | 2614 | L: dc395x@twibble.org |
2613 | L: http://lists.twibble.org/mailman/listinfo/dc395x/ | 2615 | W: http://twibble.org/dist/dc395x/ |
2616 | W: http://lists.twibble.org/mailman/listinfo/dc395x/ | ||
2614 | S: Maintained | 2617 | S: Maintained |
2615 | F: Documentation/scsi/dc395x.txt | 2618 | F: Documentation/scsi/dc395x.txt |
2616 | F: drivers/scsi/dc395x.* | 2619 | F: drivers/scsi/dc395x.* |
@@ -2845,12 +2848,22 @@ F: lib/kobj* | |||
2845 | DRM DRIVERS | 2848 | DRM DRIVERS |
2846 | M: David Airlie <airlied@linux.ie> | 2849 | M: David Airlie <airlied@linux.ie> |
2847 | L: dri-devel@lists.freedesktop.org | 2850 | L: dri-devel@lists.freedesktop.org |
2848 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git | 2851 | T: git git://people.freedesktop.org/~airlied/linux |
2849 | S: Maintained | 2852 | S: Maintained |
2850 | F: drivers/gpu/drm/ | 2853 | F: drivers/gpu/drm/ |
2851 | F: include/drm/ | 2854 | F: include/drm/ |
2852 | F: include/uapi/drm/ | 2855 | F: include/uapi/drm/ |
2853 | 2856 | ||
2857 | RADEON DRM DRIVERS | ||
2858 | M: Alex Deucher <alexander.deucher@amd.com> | ||
2859 | M: Christian König <christian.koenig@amd.com> | ||
2860 | L: dri-devel@lists.freedesktop.org | ||
2861 | T: git git://people.freedesktop.org/~agd5f/linux | ||
2862 | S: Supported | ||
2863 | F: drivers/gpu/drm/radeon/ | ||
2864 | F: include/drm/radeon* | ||
2865 | F: include/uapi/drm/radeon* | ||
2866 | |||
2854 | INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) | 2867 | INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) |
2855 | M: Daniel Vetter <daniel.vetter@ffwll.ch> | 2868 | M: Daniel Vetter <daniel.vetter@ffwll.ch> |
2856 | M: Jani Nikula <jani.nikula@linux.intel.com> | 2869 | M: Jani Nikula <jani.nikula@linux.intel.com> |
@@ -3324,6 +3337,17 @@ S: Maintained | |||
3324 | F: include/linux/netfilter_bridge/ | 3337 | F: include/linux/netfilter_bridge/ |
3325 | F: net/bridge/ | 3338 | F: net/bridge/ |
3326 | 3339 | ||
3340 | ETHERNET PHY LIBRARY | ||
3341 | M: Florian Fainelli <f.fainelli@gmail.com> | ||
3342 | L: netdev@vger.kernel.org | ||
3343 | S: Maintained | ||
3344 | F: include/linux/phy.h | ||
3345 | F: include/linux/phy_fixed.h | ||
3346 | F: drivers/net/phy/ | ||
3347 | F: Documentation/networking/phy.txt | ||
3348 | F: drivers/of/of_mdio.c | ||
3349 | F: drivers/of/of_net.c | ||
3350 | |||
3327 | EXT2 FILE SYSTEM | 3351 | EXT2 FILE SYSTEM |
3328 | M: Jan Kara <jack@suse.cz> | 3352 | M: Jan Kara <jack@suse.cz> |
3329 | L: linux-ext4@vger.kernel.org | 3353 | L: linux-ext4@vger.kernel.org |
@@ -5487,6 +5511,11 @@ W: http://www.kernel.org/doc/man-pages | |||
5487 | L: linux-man@vger.kernel.org | 5511 | L: linux-man@vger.kernel.org |
5488 | S: Maintained | 5512 | S: Maintained |
5489 | 5513 | ||
5514 | MARVELL ARMADA DRM SUPPORT | ||
5515 | M: Russell King <rmk+kernel@arm.linux.org.uk> | ||
5516 | S: Maintained | ||
5517 | F: drivers/gpu/drm/armada/ | ||
5518 | |||
5490 | MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) | 5519 | MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) |
5491 | M: Mirko Lindner <mlindner@marvell.com> | 5520 | M: Mirko Lindner <mlindner@marvell.com> |
5492 | M: Stephen Hemminger <stephen@networkplumber.org> | 5521 | M: Stephen Hemminger <stephen@networkplumber.org> |
@@ -8429,8 +8458,8 @@ TARGET SUBSYSTEM | |||
8429 | M: Nicholas A. Bellinger <nab@linux-iscsi.org> | 8458 | M: Nicholas A. Bellinger <nab@linux-iscsi.org> |
8430 | L: linux-scsi@vger.kernel.org | 8459 | L: linux-scsi@vger.kernel.org |
8431 | L: target-devel@vger.kernel.org | 8460 | L: target-devel@vger.kernel.org |
8432 | L: http://groups.google.com/group/linux-iscsi-target-dev | ||
8433 | W: http://www.linux-iscsi.org | 8461 | W: http://www.linux-iscsi.org |
8462 | W: http://groups.google.com/group/linux-iscsi-target-dev | ||
8434 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master | 8463 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master |
8435 | S: Supported | 8464 | S: Supported |
8436 | F: drivers/target/ | 8465 | F: drivers/target/ |
@@ -9715,7 +9744,6 @@ F: drivers/xen/*swiotlb* | |||
9715 | XFS FILESYSTEM | 9744 | XFS FILESYSTEM |
9716 | P: Silicon Graphics Inc | 9745 | P: Silicon Graphics Inc |
9717 | M: Dave Chinner <david@fromorbit.com> | 9746 | M: Dave Chinner <david@fromorbit.com> |
9718 | M: Ben Myers <bpm@sgi.com> | ||
9719 | M: xfs@oss.sgi.com | 9747 | M: xfs@oss.sgi.com |
9720 | L: xfs@oss.sgi.com | 9748 | L: xfs@oss.sgi.com |
9721 | W: http://oss.sgi.com/projects/xfs | 9749 | W: http://oss.sgi.com/projects/xfs |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 14 | 2 | PATCHLEVEL = 14 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc5 |
5 | NAME = Shuffling Zombie Juror | 5 | NAME = Shuffling Zombie Juror |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
@@ -605,10 +605,11 @@ endif | |||
605 | ifdef CONFIG_CC_STACKPROTECTOR_REGULAR | 605 | ifdef CONFIG_CC_STACKPROTECTOR_REGULAR |
606 | stackp-flag := -fstack-protector | 606 | stackp-flag := -fstack-protector |
607 | ifeq ($(call cc-option, $(stackp-flag)),) | 607 | ifeq ($(call cc-option, $(stackp-flag)),) |
608 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR: \ | 608 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: \ |
609 | -fstack-protector not supported by compiler)) | 609 | -fstack-protector not supported by compiler) |
610 | endif | 610 | endif |
611 | else ifdef CONFIG_CC_STACKPROTECTOR_STRONG | 611 | else |
612 | ifdef CONFIG_CC_STACKPROTECTOR_STRONG | ||
612 | stackp-flag := -fstack-protector-strong | 613 | stackp-flag := -fstack-protector-strong |
613 | ifeq ($(call cc-option, $(stackp-flag)),) | 614 | ifeq ($(call cc-option, $(stackp-flag)),) |
614 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ | 615 | $(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ |
@@ -618,6 +619,7 @@ else | |||
618 | # Force off for distro compilers that enable stack protector by default. | 619 | # Force off for distro compilers that enable stack protector by default. |
619 | stackp-flag := $(call cc-option, -fno-stack-protector) | 620 | stackp-flag := $(call cc-option, -fno-stack-protector) |
620 | endif | 621 | endif |
622 | endif | ||
621 | KBUILD_CFLAGS += $(stackp-flag) | 623 | KBUILD_CFLAGS += $(stackp-flag) |
622 | 624 | ||
623 | # This warning generated too much noise in a regular build. | 625 | # This warning generated too much noise in a regular build. |
diff --git a/arch/Kconfig b/arch/Kconfig index 80bbb8ccd0d1..97ff872c7acc 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -86,9 +86,7 @@ config KPROBES_ON_FTRACE | |||
86 | optimize on top of function tracing. | 86 | optimize on top of function tracing. |
87 | 87 | ||
88 | config UPROBES | 88 | config UPROBES |
89 | bool "Transparent user-space probes (EXPERIMENTAL)" | 89 | def_bool n |
90 | depends on UPROBE_EVENT && PERF_EVENTS | ||
91 | default n | ||
92 | select PERCPU_RWSEM | 90 | select PERCPU_RWSEM |
93 | help | 91 | help |
94 | Uprobes is the user-space counterpart to kprobes: they | 92 | Uprobes is the user-space counterpart to kprobes: they |
@@ -101,8 +99,6 @@ config UPROBES | |||
101 | managed by the kernel and kept transparent to the probed | 99 | managed by the kernel and kept transparent to the probed |
102 | application. ) | 100 | application. ) |
103 | 101 | ||
104 | If in doubt, say "N". | ||
105 | |||
106 | config HAVE_64BIT_ALIGNED_ACCESS | 102 | config HAVE_64BIT_ALIGNED_ACCESS |
107 | def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS | 103 | def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS |
108 | help | 104 | help |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 41266af5dfc8..fac6890b315d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -207,6 +207,9 @@ config ZONE_DMA | |||
207 | config NEED_DMA_MAP_STATE | 207 | config NEED_DMA_MAP_STATE |
208 | def_bool y | 208 | def_bool y |
209 | 209 | ||
210 | config ARCH_SUPPORTS_UPROBES | ||
211 | def_bool y | ||
212 | |||
210 | config ARCH_HAS_DMA_SET_COHERENT_MASK | 213 | config ARCH_HAS_DMA_SET_COHERENT_MASK |
211 | bool | 214 | bool |
212 | 215 | ||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 6d1e43d46187..032030361bef 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile | |||
@@ -209,7 +209,8 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ | |||
209 | omap3-n900.dtb \ | 209 | omap3-n900.dtb \ |
210 | omap3-n9.dtb \ | 210 | omap3-n9.dtb \ |
211 | omap3-n950.dtb \ | 211 | omap3-n950.dtb \ |
212 | omap3-tobi.dtb \ | 212 | omap3-overo-tobi.dtb \ |
213 | omap3-overo-storm-tobi.dtb \ | ||
213 | omap3-gta04.dtb \ | 214 | omap3-gta04.dtb \ |
214 | omap3-igep0020.dtb \ | 215 | omap3-igep0020.dtb \ |
215 | omap3-igep0030.dtb \ | 216 | omap3-igep0030.dtb \ |
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 4718ec4a4dbf..486880b74831 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts | |||
@@ -121,7 +121,7 @@ | |||
121 | ti,model = "AM335x-EVMSK"; | 121 | ti,model = "AM335x-EVMSK"; |
122 | ti,audio-codec = <&tlv320aic3106>; | 122 | ti,audio-codec = <&tlv320aic3106>; |
123 | ti,mcasp-controller = <&mcasp1>; | 123 | ti,mcasp-controller = <&mcasp1>; |
124 | ti,codec-clock-rate = <24576000>; | 124 | ti,codec-clock-rate = <24000000>; |
125 | ti,audio-routing = | 125 | ti,audio-routing = |
126 | "Headphone Jack", "HPLOUT", | 126 | "Headphone Jack", "HPLOUT", |
127 | "Headphone Jack", "HPROUT"; | 127 | "Headphone Jack", "HPROUT"; |
@@ -256,6 +256,12 @@ | |||
256 | >; | 256 | >; |
257 | }; | 257 | }; |
258 | 258 | ||
259 | mmc1_pins: pinmux_mmc1_pins { | ||
260 | pinctrl-single,pins = < | ||
261 | 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ | ||
262 | >; | ||
263 | }; | ||
264 | |||
259 | mcasp1_pins: mcasp1_pins { | 265 | mcasp1_pins: mcasp1_pins { |
260 | pinctrl-single,pins = < | 266 | pinctrl-single,pins = < |
261 | 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */ | 267 | 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */ |
@@ -456,6 +462,9 @@ | |||
456 | status = "okay"; | 462 | status = "okay"; |
457 | vmmc-supply = <&vmmc_reg>; | 463 | vmmc-supply = <&vmmc_reg>; |
458 | bus-width = <4>; | 464 | bus-width = <4>; |
465 | pinctrl-names = "default"; | ||
466 | pinctrl-0 = <&mmc1_pins>; | ||
467 | cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; | ||
459 | }; | 468 | }; |
460 | 469 | ||
461 | &sham { | 470 | &sham { |
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 66609684d41b..9480cf891f8c 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi | |||
@@ -23,6 +23,7 @@ | |||
23 | gpio0 = &gpio0; | 23 | gpio0 = &gpio0; |
24 | gpio1 = &gpio1; | 24 | gpio1 = &gpio1; |
25 | gpio2 = &gpio2; | 25 | gpio2 = &gpio2; |
26 | eth3 = ð3; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | cpus { | 29 | cpus { |
@@ -291,7 +292,7 @@ | |||
291 | interrupts = <91>; | 292 | interrupts = <91>; |
292 | }; | 293 | }; |
293 | 294 | ||
294 | ethernet@34000 { | 295 | eth3: ethernet@34000 { |
295 | compatible = "marvell,armada-370-neta"; | 296 | compatible = "marvell,armada-370-neta"; |
296 | reg = <0x34000 0x4000>; | 297 | reg = <0x34000 0x4000>; |
297 | interrupts = <14>; | 298 | interrupts = <14>; |
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 2b76524f4aa7..187fd46b7b5e 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi | |||
@@ -379,15 +379,6 @@ | |||
379 | #clock-cells = <1>; | 379 | #clock-cells = <1>; |
380 | }; | 380 | }; |
381 | 381 | ||
382 | pmu_intc: pmu-interrupt-ctrl@d0050 { | ||
383 | compatible = "marvell,dove-pmu-intc"; | ||
384 | interrupt-controller; | ||
385 | #interrupt-cells = <1>; | ||
386 | reg = <0xd0050 0x8>; | ||
387 | interrupts = <33>; | ||
388 | marvell,#interrupts = <7>; | ||
389 | }; | ||
390 | |||
391 | pinctrl: pin-ctrl@d0200 { | 382 | pinctrl: pin-ctrl@d0200 { |
392 | compatible = "marvell,dove-pinctrl"; | 383 | compatible = "marvell,dove-pinctrl"; |
393 | reg = <0xd0200 0x10>; | 384 | reg = <0xd0200 0x10>; |
@@ -610,8 +601,6 @@ | |||
610 | rtc: real-time-clock@d8500 { | 601 | rtc: real-time-clock@d8500 { |
611 | compatible = "marvell,orion-rtc"; | 602 | compatible = "marvell,orion-rtc"; |
612 | reg = <0xd8500 0x20>; | 603 | reg = <0xd8500 0x20>; |
613 | interrupt-parent = <&pmu_intc>; | ||
614 | interrupts = <5>; | ||
615 | }; | 604 | }; |
616 | 605 | ||
617 | gpio2: gpio-ctrl@e8400 { | 606 | gpio2: gpio-ctrl@e8400 { |
diff --git a/arch/arm/boot/dts/imx6dl-hummingboard.dts b/arch/arm/boot/dts/imx6dl-hummingboard.dts index fd8fc7cd53f3..5bfae54fb780 100644 --- a/arch/arm/boot/dts/imx6dl-hummingboard.dts +++ b/arch/arm/boot/dts/imx6dl-hummingboard.dts | |||
@@ -52,12 +52,6 @@ | |||
52 | }; | 52 | }; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | codec: spdif-transmitter { | ||
56 | compatible = "linux,spdif-dit"; | ||
57 | pinctrl-names = "default"; | ||
58 | pinctrl-0 = <&pinctrl_hummingboard_spdif>; | ||
59 | }; | ||
60 | |||
61 | sound-spdif { | 55 | sound-spdif { |
62 | compatible = "fsl,imx-audio-spdif"; | 56 | compatible = "fsl,imx-audio-spdif"; |
63 | model = "imx-spdif"; | 57 | model = "imx-spdif"; |
@@ -111,7 +105,7 @@ | |||
111 | }; | 105 | }; |
112 | 106 | ||
113 | pinctrl_hummingboard_spdif: hummingboard-spdif { | 107 | pinctrl_hummingboard_spdif: hummingboard-spdif { |
114 | fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0>; | 108 | fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>; |
115 | }; | 109 | }; |
116 | 110 | ||
117 | pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus { | 111 | pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus { |
@@ -142,6 +136,8 @@ | |||
142 | }; | 136 | }; |
143 | 137 | ||
144 | &spdif { | 138 | &spdif { |
139 | pinctrl-names = "default"; | ||
140 | pinctrl-0 = <&pinctrl_hummingboard_spdif>; | ||
145 | status = "okay"; | 141 | status = "okay"; |
146 | }; | 142 | }; |
147 | 143 | ||
diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi index 64daa3b311f6..c2a24888a276 100644 --- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi | |||
@@ -46,12 +46,6 @@ | |||
46 | }; | 46 | }; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | codec: spdif-transmitter { | ||
50 | compatible = "linux,spdif-dit"; | ||
51 | pinctrl-names = "default"; | ||
52 | pinctrl-0 = <&pinctrl_cubox_i_spdif>; | ||
53 | }; | ||
54 | |||
55 | sound-spdif { | 49 | sound-spdif { |
56 | compatible = "fsl,imx-audio-spdif"; | 50 | compatible = "fsl,imx-audio-spdif"; |
57 | model = "imx-spdif"; | 51 | model = "imx-spdif"; |
@@ -89,7 +83,7 @@ | |||
89 | }; | 83 | }; |
90 | 84 | ||
91 | pinctrl_cubox_i_spdif: cubox-i-spdif { | 85 | pinctrl_cubox_i_spdif: cubox-i-spdif { |
92 | fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0>; | 86 | fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>; |
93 | }; | 87 | }; |
94 | 88 | ||
95 | pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus { | 89 | pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus { |
@@ -121,6 +115,8 @@ | |||
121 | }; | 115 | }; |
122 | 116 | ||
123 | &spdif { | 117 | &spdif { |
118 | pinctrl-names = "default"; | ||
119 | pinctrl-0 = <&pinctrl_cubox_i_spdif>; | ||
124 | status = "okay"; | 120 | status = "okay"; |
125 | }; | 121 | }; |
126 | 122 | ||
diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index b9b55c95a566..c551e4af4d83 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts | |||
@@ -32,7 +32,7 @@ | |||
32 | aux-button { | 32 | aux-button { |
33 | label = "aux"; | 33 | label = "aux"; |
34 | linux,code = <169>; | 34 | linux,code = <169>; |
35 | gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; | 35 | gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; |
36 | gpio-key,wakeup; | 36 | gpio-key,wakeup; |
37 | }; | 37 | }; |
38 | }; | 38 | }; |
@@ -92,6 +92,8 @@ | |||
92 | bmp085@77 { | 92 | bmp085@77 { |
93 | compatible = "bosch,bmp085"; | 93 | compatible = "bosch,bmp085"; |
94 | reg = <0x77>; | 94 | reg = <0x77>; |
95 | interrupt-parent = <&gpio4>; | ||
96 | interrupts = <17 IRQ_TYPE_EDGE_RISING>; | ||
95 | }; | 97 | }; |
96 | 98 | ||
97 | /* leds */ | 99 | /* leds */ |
@@ -141,8 +143,8 @@ | |||
141 | pinctrl-names = "default"; | 143 | pinctrl-names = "default"; |
142 | pinctrl-0 = <&mmc1_pins>; | 144 | pinctrl-0 = <&mmc1_pins>; |
143 | vmmc-supply = <&vmmc1>; | 145 | vmmc-supply = <&vmmc1>; |
144 | vmmc_aux-supply = <&vsim>; | ||
145 | bus-width = <4>; | 146 | bus-width = <4>; |
147 | ti,non-removable; | ||
146 | }; | 148 | }; |
147 | 149 | ||
148 | &mmc2 { | 150 | &mmc2 { |
diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts index 39828ce464ee..9938b5dc1909 100644 --- a/arch/arm/boot/dts/omap3-n9.dts +++ b/arch/arm/boot/dts/omap3-n9.dts | |||
@@ -14,5 +14,5 @@ | |||
14 | 14 | ||
15 | / { | 15 | / { |
16 | model = "Nokia N9"; | 16 | model = "Nokia N9"; |
17 | compatible = "nokia,omap3-n9", "ti,omap3"; | 17 | compatible = "nokia,omap3-n9", "ti,omap36xx", "ti,omap3"; |
18 | }; | 18 | }; |
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 6fc85f963530..0bf40c90faba 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2013 Pavel Machek <pavel@ucw.cz> | 2 | * Copyright (C) 2013 Pavel Machek <pavel@ucw.cz> |
3 | * Copyright 2013 Aaro Koskinen <aaro.koskinen@iki.fi> | 3 | * Copyright (C) 2013-2014 Aaro Koskinen <aaro.koskinen@iki.fi> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 (or later) as | 6 | * it under the terms of the GNU General Public License version 2 (or later) as |
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | / { | 14 | / { |
15 | model = "Nokia N900"; | 15 | model = "Nokia N900"; |
16 | compatible = "nokia,omap3-n900", "ti,omap3"; | 16 | compatible = "nokia,omap3-n900", "ti,omap3430", "ti,omap3"; |
17 | 17 | ||
18 | cpus { | 18 | cpus { |
19 | cpu@0 { | 19 | cpu@0 { |
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts index b076a526b999..261c5589bfa3 100644 --- a/arch/arm/boot/dts/omap3-n950.dts +++ b/arch/arm/boot/dts/omap3-n950.dts | |||
@@ -14,5 +14,5 @@ | |||
14 | 14 | ||
15 | / { | 15 | / { |
16 | model = "Nokia N950"; | 16 | model = "Nokia N950"; |
17 | compatible = "nokia,omap3-n950", "ti,omap3"; | 17 | compatible = "nokia,omap3-n950", "ti,omap36xx", "ti,omap3"; |
18 | }; | 18 | }; |
diff --git a/arch/arm/boot/dts/omap3-overo-storm-tobi.dts b/arch/arm/boot/dts/omap3-overo-storm-tobi.dts new file mode 100644 index 000000000000..966b5c9cd96a --- /dev/null +++ b/arch/arm/boot/dts/omap3-overo-storm-tobi.dts | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Florian Vaussard, EPFL Mobots group | ||
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 | |||
9 | /* | ||
10 | * Tobi expansion board is manufactured by Gumstix Inc. | ||
11 | */ | ||
12 | |||
13 | /dts-v1/; | ||
14 | |||
15 | #include "omap36xx.dtsi" | ||
16 | #include "omap3-overo-tobi-common.dtsi" | ||
17 | |||
18 | / { | ||
19 | model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Tobi"; | ||
20 | compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3"; | ||
21 | }; | ||
22 | |||
diff --git a/arch/arm/boot/dts/omap3-tobi.dts b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi index 7e4ad2aec37a..4edc013a91c1 100644 --- a/arch/arm/boot/dts/omap3-tobi.dts +++ b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi | |||
@@ -13,9 +13,6 @@ | |||
13 | #include "omap3-overo.dtsi" | 13 | #include "omap3-overo.dtsi" |
14 | 14 | ||
15 | / { | 15 | / { |
16 | model = "TI OMAP3 Gumstix Overo on Tobi"; | ||
17 | compatible = "ti,omap3-tobi", "ti,omap3-overo", "ti,omap3"; | ||
18 | |||
19 | leds { | 16 | leds { |
20 | compatible = "gpio-leds"; | 17 | compatible = "gpio-leds"; |
21 | heartbeat { | 18 | heartbeat { |
diff --git a/arch/arm/boot/dts/omap3-overo-tobi.dts b/arch/arm/boot/dts/omap3-overo-tobi.dts new file mode 100644 index 000000000000..de5653e1b5ca --- /dev/null +++ b/arch/arm/boot/dts/omap3-overo-tobi.dts | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Florian Vaussard, EPFL Mobots group | ||
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 | |||
9 | /* | ||
10 | * Tobi expansion board is manufactured by Gumstix Inc. | ||
11 | */ | ||
12 | |||
13 | /dts-v1/; | ||
14 | |||
15 | #include "omap34xx.dtsi" | ||
16 | #include "omap3-overo-tobi-common.dtsi" | ||
17 | |||
18 | / { | ||
19 | model = "OMAP35xx Gumstix Overo on Tobi"; | ||
20 | compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3"; | ||
21 | }; | ||
22 | |||
diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi index a461d2fd1fb0..597099907f8e 100644 --- a/arch/arm/boot/dts/omap3-overo.dtsi +++ b/arch/arm/boot/dts/omap3-overo.dtsi | |||
@@ -9,9 +9,6 @@ | |||
9 | /* | 9 | /* |
10 | * The Gumstix Overo must be combined with an expansion board. | 10 | * The Gumstix Overo must be combined with an expansion board. |
11 | */ | 11 | */ |
12 | /dts-v1/; | ||
13 | |||
14 | #include "omap34xx.dtsi" | ||
15 | 12 | ||
16 | / { | 13 | / { |
17 | pwmleds { | 14 | pwmleds { |
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 389e987ec281..44ec401ec366 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi | |||
@@ -57,6 +57,8 @@ | |||
57 | resets = <&tegra_car 27>; | 57 | resets = <&tegra_car 27>; |
58 | reset-names = "dc"; | 58 | reset-names = "dc"; |
59 | 59 | ||
60 | nvidia,head = <0>; | ||
61 | |||
60 | rgb { | 62 | rgb { |
61 | status = "disabled"; | 63 | status = "disabled"; |
62 | }; | 64 | }; |
@@ -72,6 +74,8 @@ | |||
72 | resets = <&tegra_car 26>; | 74 | resets = <&tegra_car 26>; |
73 | reset-names = "dc"; | 75 | reset-names = "dc"; |
74 | 76 | ||
77 | nvidia,head = <1>; | ||
78 | |||
75 | rgb { | 79 | rgb { |
76 | status = "disabled"; | 80 | status = "disabled"; |
77 | }; | 81 | }; |
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 480ecda3416b..48d2a7f4d0c0 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
@@ -94,6 +94,8 @@ | |||
94 | resets = <&tegra_car 27>; | 94 | resets = <&tegra_car 27>; |
95 | reset-names = "dc"; | 95 | reset-names = "dc"; |
96 | 96 | ||
97 | nvidia,head = <0>; | ||
98 | |||
97 | rgb { | 99 | rgb { |
98 | status = "disabled"; | 100 | status = "disabled"; |
99 | }; | 101 | }; |
@@ -109,6 +111,8 @@ | |||
109 | resets = <&tegra_car 26>; | 111 | resets = <&tegra_car 26>; |
110 | reset-names = "dc"; | 112 | reset-names = "dc"; |
111 | 113 | ||
114 | nvidia,head = <1>; | ||
115 | |||
112 | rgb { | 116 | rgb { |
113 | status = "disabled"; | 117 | status = "disabled"; |
114 | }; | 118 | }; |
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index 9104224124ee..1e156d9d0506 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi | |||
@@ -28,7 +28,7 @@ | |||
28 | compatible = "nvidia,cardhu", "nvidia,tegra30"; | 28 | compatible = "nvidia,cardhu", "nvidia,tegra30"; |
29 | 29 | ||
30 | aliases { | 30 | aliases { |
31 | rtc0 = "/i2c@7000d000/tps6586x@34"; | 31 | rtc0 = "/i2c@7000d000/tps65911@2d"; |
32 | rtc1 = "/rtc@7000e000"; | 32 | rtc1 = "/rtc@7000e000"; |
33 | }; | 33 | }; |
34 | 34 | ||
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index ed8e7700b46d..19a84e933f4e 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi | |||
@@ -170,6 +170,8 @@ | |||
170 | resets = <&tegra_car 27>; | 170 | resets = <&tegra_car 27>; |
171 | reset-names = "dc"; | 171 | reset-names = "dc"; |
172 | 172 | ||
173 | nvidia,head = <0>; | ||
174 | |||
173 | rgb { | 175 | rgb { |
174 | status = "disabled"; | 176 | status = "disabled"; |
175 | }; | 177 | }; |
@@ -185,6 +187,8 @@ | |||
185 | resets = <&tegra_car 26>; | 187 | resets = <&tegra_car 26>; |
186 | reset-names = "dc"; | 188 | reset-names = "dc"; |
187 | 189 | ||
190 | nvidia,head = <1>; | ||
191 | |||
188 | rgb { | 192 | rgb { |
189 | status = "disabled"; | 193 | status = "disabled"; |
190 | }; | 194 | }; |
diff --git a/arch/arm/boot/dts/testcases/tests.dtsi b/arch/arm/boot/dts/testcases/tests.dtsi deleted file mode 100644 index 3f123ecc9dd7..000000000000 --- a/arch/arm/boot/dts/testcases/tests.dtsi +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | /include/ "tests-phandle.dtsi" | ||
2 | /include/ "tests-interrupts.dtsi" | ||
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index f43907c40c93..65f657711323 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts | |||
@@ -1,4 +1,4 @@ | |||
1 | /include/ "versatile-ab.dts" | 1 | #include <versatile-ab.dts> |
2 | 2 | ||
3 | / { | 3 | / { |
4 | model = "ARM Versatile PB"; | 4 | model = "ARM Versatile PB"; |
@@ -47,4 +47,4 @@ | |||
47 | }; | 47 | }; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /include/ "testcases/tests.dtsi" | 50 | #include <testcases.dtsi> |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index e9a49fe0284e..8b8b61685a34 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -212,6 +212,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, | |||
212 | static inline void __flush_icache_all(void) | 212 | static inline void __flush_icache_all(void) |
213 | { | 213 | { |
214 | __flush_icache_preferred(); | 214 | __flush_icache_preferred(); |
215 | dsb(); | ||
215 | } | 216 | } |
216 | 217 | ||
217 | /* | 218 | /* |
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h index f82ec22eeb11..49fa0dfaad33 100644 --- a/arch/arm/include/asm/kprobes.h +++ b/arch/arm/include/asm/kprobes.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
21 | #include <linux/percpu.h> | 21 | #include <linux/notifier.h> |
22 | 22 | ||
23 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 23 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
24 | #define MAX_INSN_SIZE 2 | 24 | #define MAX_INSN_SIZE 2 |
@@ -28,21 +28,10 @@ | |||
28 | #define kretprobe_blacklist_size 0 | 28 | #define kretprobe_blacklist_size 0 |
29 | 29 | ||
30 | typedef u32 kprobe_opcode_t; | 30 | typedef u32 kprobe_opcode_t; |
31 | |||
32 | struct kprobe; | 31 | struct kprobe; |
33 | typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); | 32 | #include <asm/probes.h> |
34 | typedef unsigned long (kprobe_check_cc)(unsigned long); | ||
35 | typedef void (kprobe_insn_singlestep_t)(struct kprobe *, struct pt_regs *); | ||
36 | typedef void (kprobe_insn_fn_t)(void); | ||
37 | 33 | ||
38 | /* Architecture specific copy of original instruction. */ | 34 | #define arch_specific_insn arch_probes_insn |
39 | struct arch_specific_insn { | ||
40 | kprobe_opcode_t *insn; | ||
41 | kprobe_insn_handler_t *insn_handler; | ||
42 | kprobe_check_cc *insn_check_cc; | ||
43 | kprobe_insn_singlestep_t *insn_singlestep; | ||
44 | kprobe_insn_fn_t *insn_fn; | ||
45 | }; | ||
46 | 35 | ||
47 | struct prev_kprobe { | 36 | struct prev_kprobe { |
48 | struct kprobe *kp; | 37 | struct kprobe *kp; |
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 03243f7eeddf..85c60adc8b60 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h | |||
@@ -120,13 +120,16 @@ | |||
120 | /* | 120 | /* |
121 | * 2nd stage PTE definitions for LPAE. | 121 | * 2nd stage PTE definitions for LPAE. |
122 | */ | 122 | */ |
123 | #define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x5) << 2) /* MemAttr[3:0] */ | 123 | #define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x0) << 2) /* strongly ordered */ |
124 | #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */ | 124 | #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* normal inner write-through */ |
125 | #define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */ | 125 | #define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* normal inner write-back */ |
126 | #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ | 126 | #define L_PTE_S2_MT_DEV_SHARED (_AT(pteval_t, 0x1) << 2) /* device */ |
127 | #define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ | 127 | #define L_PTE_S2_MT_MASK (_AT(pteval_t, 0xf) << 2) |
128 | 128 | ||
129 | #define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */ | 129 | #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ |
130 | #define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ | ||
131 | |||
132 | #define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */ | ||
130 | 133 | ||
131 | /* | 134 | /* |
132 | * Hyp-mode PL2 PTE definitions for LPAE. | 135 | * Hyp-mode PL2 PTE definitions for LPAE. |
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h new file mode 100644 index 000000000000..806cfe622a9e --- /dev/null +++ b/arch/arm/include/asm/probes.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/probes.h | ||
3 | * | ||
4 | * Original contents copied from arch/arm/include/asm/kprobes.h | ||
5 | * which contains the following notice... | ||
6 | * | ||
7 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #ifndef _ASM_PROBES_H | ||
20 | #define _ASM_PROBES_H | ||
21 | |||
22 | typedef u32 probes_opcode_t; | ||
23 | |||
24 | struct arch_probes_insn; | ||
25 | typedef void (probes_insn_handler_t)(probes_opcode_t, | ||
26 | struct arch_probes_insn *, | ||
27 | struct pt_regs *); | ||
28 | typedef unsigned long (probes_check_cc)(unsigned long); | ||
29 | typedef void (probes_insn_singlestep_t)(probes_opcode_t, | ||
30 | struct arch_probes_insn *, | ||
31 | struct pt_regs *); | ||
32 | typedef void (probes_insn_fn_t)(void); | ||
33 | |||
34 | /* Architecture specific copy of original instruction. */ | ||
35 | struct arch_probes_insn { | ||
36 | probes_opcode_t *insn; | ||
37 | probes_insn_handler_t *insn_handler; | ||
38 | probes_check_cc *insn_check_cc; | ||
39 | probes_insn_singlestep_t *insn_singlestep; | ||
40 | probes_insn_fn_t *insn_fn; | ||
41 | }; | ||
42 | |||
43 | #endif | ||
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 627a03ebb987..c877654fe3bf 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
@@ -84,6 +84,12 @@ static inline long regs_return_value(struct pt_regs *regs) | |||
84 | 84 | ||
85 | #define instruction_pointer(regs) (regs)->ARM_pc | 85 | #define instruction_pointer(regs) (regs)->ARM_pc |
86 | 86 | ||
87 | static inline void instruction_pointer_set(struct pt_regs *regs, | ||
88 | unsigned long val) | ||
89 | { | ||
90 | instruction_pointer(regs) = val; | ||
91 | } | ||
92 | |||
87 | #ifdef CONFIG_SMP | 93 | #ifdef CONFIG_SMP |
88 | extern unsigned long profile_pc(struct pt_regs *regs); | 94 | extern unsigned long profile_pc(struct pt_regs *regs); |
89 | #else | 95 | #else |
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index ef3c6072aa45..ac4bfae26702 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h | |||
@@ -37,18 +37,9 @@ | |||
37 | 37 | ||
38 | static inline void dsb_sev(void) | 38 | static inline void dsb_sev(void) |
39 | { | 39 | { |
40 | #if __LINUX_ARM_ARCH__ >= 7 | 40 | |
41 | __asm__ __volatile__ ( | 41 | dsb(ishst); |
42 | "dsb ishst\n" | 42 | __asm__(SEV); |
43 | SEV | ||
44 | ); | ||
45 | #else | ||
46 | __asm__ __volatile__ ( | ||
47 | "mcr p15, 0, %0, c7, c10, 4\n" | ||
48 | SEV | ||
49 | : : "r" (0) | ||
50 | ); | ||
51 | #endif | ||
52 | } | 43 | } |
53 | 44 | ||
54 | /* | 45 | /* |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 71a06b293489..f989d7c22dc5 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -153,6 +153,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
153 | #define TIF_SIGPENDING 0 | 153 | #define TIF_SIGPENDING 0 |
154 | #define TIF_NEED_RESCHED 1 | 154 | #define TIF_NEED_RESCHED 1 |
155 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ | 155 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ |
156 | #define TIF_UPROBE 7 | ||
156 | #define TIF_SYSCALL_TRACE 8 | 157 | #define TIF_SYSCALL_TRACE 8 |
157 | #define TIF_SYSCALL_AUDIT 9 | 158 | #define TIF_SYSCALL_AUDIT 9 |
158 | #define TIF_SYSCALL_TRACEPOINT 10 | 159 | #define TIF_SYSCALL_TRACEPOINT 10 |
@@ -165,6 +166,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
165 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 166 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
166 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) | 167 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
167 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | 168 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) |
169 | #define _TIF_UPROBE (1 << TIF_UPROBE) | ||
168 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 170 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
169 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 171 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
170 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) | 172 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) |
@@ -178,7 +180,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
178 | /* | 180 | /* |
179 | * Change these and you break ASM code in entry-common.S | 181 | * Change these and you break ASM code in entry-common.S |
180 | */ | 182 | */ |
181 | #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) | 183 | #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ |
184 | _TIF_NOTIFY_RESUME | _TIF_UPROBE) | ||
182 | 185 | ||
183 | #endif /* __KERNEL__ */ | 186 | #endif /* __KERNEL__ */ |
184 | #endif /* __ASM_ARM_THREAD_INFO_H */ | 187 | #endif /* __ASM_ARM_THREAD_INFO_H */ |
diff --git a/arch/arm/include/asm/uprobes.h b/arch/arm/include/asm/uprobes.h new file mode 100644 index 000000000000..9472c20b7d49 --- /dev/null +++ b/arch/arm/include/asm/uprobes.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Rabin Vincent <rabin at rab.in> | ||
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 | |||
9 | #ifndef _ASM_UPROBES_H | ||
10 | #define _ASM_UPROBES_H | ||
11 | |||
12 | #include <asm/probes.h> | ||
13 | #include <asm/opcodes.h> | ||
14 | |||
15 | typedef u32 uprobe_opcode_t; | ||
16 | |||
17 | #define MAX_UINSN_BYTES 4 | ||
18 | #define UPROBE_XOL_SLOT_BYTES 64 | ||
19 | |||
20 | #define UPROBE_SWBP_ARM_INSN 0xe7f001f9 | ||
21 | #define UPROBE_SS_ARM_INSN 0xe7f001fa | ||
22 | #define UPROBE_SWBP_INSN __opcode_to_mem_arm(UPROBE_SWBP_ARM_INSN) | ||
23 | #define UPROBE_SWBP_INSN_SIZE 4 | ||
24 | |||
25 | struct arch_uprobe_task { | ||
26 | u32 backup; | ||
27 | unsigned long saved_trap_no; | ||
28 | }; | ||
29 | |||
30 | struct arch_uprobe { | ||
31 | u8 insn[MAX_UINSN_BYTES]; | ||
32 | unsigned long ixol[2]; | ||
33 | uprobe_opcode_t bpinsn; | ||
34 | bool simulate; | ||
35 | u32 pcreg; | ||
36 | void (*prehandler)(struct arch_uprobe *auprobe, | ||
37 | struct arch_uprobe_task *autask, | ||
38 | struct pt_regs *regs); | ||
39 | void (*posthandler)(struct arch_uprobe *auprobe, | ||
40 | struct arch_uprobe_task *autask, | ||
41 | struct pt_regs *regs); | ||
42 | struct arch_probes_insn asi; | ||
43 | }; | ||
44 | |||
45 | #endif | ||
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a30fc9be9e9e..a766bcbaf8ad 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -50,11 +50,12 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o | |||
50 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o | 50 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o |
51 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o | 51 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o |
52 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | 52 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o |
53 | obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o | 53 | obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o |
54 | obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o | ||
54 | ifdef CONFIG_THUMB2_KERNEL | 55 | ifdef CONFIG_THUMB2_KERNEL |
55 | obj-$(CONFIG_KPROBES) += kprobes-thumb.o | 56 | obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o |
56 | else | 57 | else |
57 | obj-$(CONFIG_KPROBES) += kprobes-arm.o | 58 | obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o |
58 | endif | 59 | endif |
59 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o | 60 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o |
60 | test-kprobes-objs := kprobes-test.o | 61 | test-kprobes-objs := kprobes-test.o |
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c index 8a30c89da70e..ac300c60d656 100644 --- a/arch/arm/kernel/kprobes-arm.c +++ b/arch/arm/kernel/kprobes-arm.c | |||
@@ -60,13 +60,10 @@ | |||
60 | 60 | ||
61 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
62 | #include <linux/kprobes.h> | 62 | #include <linux/kprobes.h> |
63 | #include <linux/module.h> | 63 | #include <linux/ptrace.h> |
64 | 64 | ||
65 | #include "kprobes.h" | 65 | #include "kprobes.h" |
66 | 66 | #include "probes-arm.h" | |
67 | #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit))))) | ||
68 | |||
69 | #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) | ||
70 | 67 | ||
71 | #if __LINUX_ARM_ARCH__ >= 6 | 68 | #if __LINUX_ARM_ARCH__ >= 6 |
72 | #define BLX(reg) "blx "reg" \n\t" | 69 | #define BLX(reg) "blx "reg" \n\t" |
@@ -75,92 +72,11 @@ | |||
75 | "mov pc, "reg" \n\t" | 72 | "mov pc, "reg" \n\t" |
76 | #endif | 73 | #endif |
77 | 74 | ||
78 | /* | ||
79 | * To avoid the complications of mimicing single-stepping on a | ||
80 | * processor without a Next-PC or a single-step mode, and to | ||
81 | * avoid having to deal with the side-effects of boosting, we | ||
82 | * simulate or emulate (almost) all ARM instructions. | ||
83 | * | ||
84 | * "Simulation" is where the instruction's behavior is duplicated in | ||
85 | * C code. "Emulation" is where the original instruction is rewritten | ||
86 | * and executed, often by altering its registers. | ||
87 | * | ||
88 | * By having all behavior of the kprobe'd instruction completed before | ||
89 | * returning from the kprobe_handler(), all locks (scheduler and | ||
90 | * interrupt) can safely be released. There is no need for secondary | ||
91 | * breakpoints, no race with MP or preemptable kernels, nor having to | ||
92 | * clean up resources counts at a later time impacting overall system | ||
93 | * performance. By rewriting the instruction, only the minimum registers | ||
94 | * need to be loaded and saved back optimizing performance. | ||
95 | * | ||
96 | * Calling the insnslot_*_rwflags version of a function doesn't hurt | ||
97 | * anything even when the CPSR flags aren't updated by the | ||
98 | * instruction. It's just a little slower in return for saving | ||
99 | * a little space by not having a duplicate function that doesn't | ||
100 | * update the flags. (The same optimization can be said for | ||
101 | * instructions that do or don't perform register writeback) | ||
102 | * Also, instructions can either read the flags, only write the | ||
103 | * flags, or read and write the flags. To save combinations | ||
104 | * rather than for sheer performance, flag functions just assume | ||
105 | * read and write of flags. | ||
106 | */ | ||
107 | |||
108 | static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) | ||
109 | { | ||
110 | kprobe_opcode_t insn = p->opcode; | ||
111 | long iaddr = (long)p->addr; | ||
112 | int disp = branch_displacement(insn); | ||
113 | |||
114 | if (insn & (1 << 24)) | ||
115 | regs->ARM_lr = iaddr + 4; | ||
116 | |||
117 | regs->ARM_pc = iaddr + 8 + disp; | ||
118 | } | ||
119 | |||
120 | static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs) | ||
121 | { | ||
122 | kprobe_opcode_t insn = p->opcode; | ||
123 | long iaddr = (long)p->addr; | ||
124 | int disp = branch_displacement(insn); | ||
125 | |||
126 | regs->ARM_lr = iaddr + 4; | ||
127 | regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2); | ||
128 | regs->ARM_cpsr |= PSR_T_BIT; | ||
129 | } | ||
130 | |||
131 | static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) | ||
132 | { | ||
133 | kprobe_opcode_t insn = p->opcode; | ||
134 | int rm = insn & 0xf; | ||
135 | long rmv = regs->uregs[rm]; | ||
136 | |||
137 | if (insn & (1 << 5)) | ||
138 | regs->ARM_lr = (long)p->addr + 4; | ||
139 | |||
140 | regs->ARM_pc = rmv & ~0x1; | ||
141 | regs->ARM_cpsr &= ~PSR_T_BIT; | ||
142 | if (rmv & 0x1) | ||
143 | regs->ARM_cpsr |= PSR_T_BIT; | ||
144 | } | ||
145 | |||
146 | static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs) | ||
147 | { | ||
148 | kprobe_opcode_t insn = p->opcode; | ||
149 | int rd = (insn >> 12) & 0xf; | ||
150 | unsigned long mask = 0xf8ff03df; /* Mask out execution state */ | ||
151 | regs->uregs[rd] = regs->ARM_cpsr & mask; | ||
152 | } | ||
153 | |||
154 | static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs) | ||
155 | { | ||
156 | regs->uregs[12] = regs->uregs[13]; | ||
157 | } | ||
158 | |||
159 | static void __kprobes | 75 | static void __kprobes |
160 | emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) | 76 | emulate_ldrdstrd(probes_opcode_t insn, |
77 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
161 | { | 78 | { |
162 | kprobe_opcode_t insn = p->opcode; | 79 | unsigned long pc = regs->ARM_pc + 4; |
163 | unsigned long pc = (unsigned long)p->addr + 8; | ||
164 | int rt = (insn >> 12) & 0xf; | 80 | int rt = (insn >> 12) & 0xf; |
165 | int rn = (insn >> 16) & 0xf; | 81 | int rn = (insn >> 16) & 0xf; |
166 | int rm = insn & 0xf; | 82 | int rm = insn & 0xf; |
@@ -175,7 +91,7 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) | |||
175 | BLX("%[fn]") | 91 | BLX("%[fn]") |
176 | : "=r" (rtv), "=r" (rt2v), "=r" (rnv) | 92 | : "=r" (rtv), "=r" (rt2v), "=r" (rnv) |
177 | : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv), | 93 | : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv), |
178 | [fn] "r" (p->ainsn.insn_fn) | 94 | [fn] "r" (asi->insn_fn) |
179 | : "lr", "memory", "cc" | 95 | : "lr", "memory", "cc" |
180 | ); | 96 | ); |
181 | 97 | ||
@@ -186,10 +102,10 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) | |||
186 | } | 102 | } |
187 | 103 | ||
188 | static void __kprobes | 104 | static void __kprobes |
189 | emulate_ldr(struct kprobe *p, struct pt_regs *regs) | 105 | emulate_ldr(probes_opcode_t insn, |
106 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
190 | { | 107 | { |
191 | kprobe_opcode_t insn = p->opcode; | 108 | unsigned long pc = regs->ARM_pc + 4; |
192 | unsigned long pc = (unsigned long)p->addr + 8; | ||
193 | int rt = (insn >> 12) & 0xf; | 109 | int rt = (insn >> 12) & 0xf; |
194 | int rn = (insn >> 16) & 0xf; | 110 | int rn = (insn >> 16) & 0xf; |
195 | int rm = insn & 0xf; | 111 | int rm = insn & 0xf; |
@@ -202,7 +118,7 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs) | |||
202 | __asm__ __volatile__ ( | 118 | __asm__ __volatile__ ( |
203 | BLX("%[fn]") | 119 | BLX("%[fn]") |
204 | : "=r" (rtv), "=r" (rnv) | 120 | : "=r" (rtv), "=r" (rnv) |
205 | : "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) | 121 | : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn) |
206 | : "lr", "memory", "cc" | 122 | : "lr", "memory", "cc" |
207 | ); | 123 | ); |
208 | 124 | ||
@@ -216,11 +132,11 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs) | |||
216 | } | 132 | } |
217 | 133 | ||
218 | static void __kprobes | 134 | static void __kprobes |
219 | emulate_str(struct kprobe *p, struct pt_regs *regs) | 135 | emulate_str(probes_opcode_t insn, |
136 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
220 | { | 137 | { |
221 | kprobe_opcode_t insn = p->opcode; | 138 | unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset; |
222 | unsigned long rtpc = (unsigned long)p->addr + str_pc_offset; | 139 | unsigned long rnpc = regs->ARM_pc + 4; |
223 | unsigned long rnpc = (unsigned long)p->addr + 8; | ||
224 | int rt = (insn >> 12) & 0xf; | 140 | int rt = (insn >> 12) & 0xf; |
225 | int rn = (insn >> 16) & 0xf; | 141 | int rn = (insn >> 16) & 0xf; |
226 | int rm = insn & 0xf; | 142 | int rm = insn & 0xf; |
@@ -234,7 +150,7 @@ emulate_str(struct kprobe *p, struct pt_regs *regs) | |||
234 | __asm__ __volatile__ ( | 150 | __asm__ __volatile__ ( |
235 | BLX("%[fn]") | 151 | BLX("%[fn]") |
236 | : "=r" (rnv) | 152 | : "=r" (rnv) |
237 | : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) | 153 | : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn) |
238 | : "lr", "memory", "cc" | 154 | : "lr", "memory", "cc" |
239 | ); | 155 | ); |
240 | 156 | ||
@@ -243,10 +159,10 @@ emulate_str(struct kprobe *p, struct pt_regs *regs) | |||
243 | } | 159 | } |
244 | 160 | ||
245 | static void __kprobes | 161 | static void __kprobes |
246 | emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) | 162 | emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn, |
163 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
247 | { | 164 | { |
248 | kprobe_opcode_t insn = p->opcode; | 165 | unsigned long pc = regs->ARM_pc + 4; |
249 | unsigned long pc = (unsigned long)p->addr + 8; | ||
250 | int rd = (insn >> 12) & 0xf; | 166 | int rd = (insn >> 12) & 0xf; |
251 | int rn = (insn >> 16) & 0xf; | 167 | int rn = (insn >> 16) & 0xf; |
252 | int rm = insn & 0xf; | 168 | int rm = insn & 0xf; |
@@ -266,7 +182,7 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) | |||
266 | "mrs %[cpsr], cpsr \n\t" | 182 | "mrs %[cpsr], cpsr \n\t" |
267 | : "=r" (rdv), [cpsr] "=r" (cpsr) | 183 | : "=r" (rdv), [cpsr] "=r" (cpsr) |
268 | : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), | 184 | : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), |
269 | "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) | 185 | "1" (cpsr), [fn] "r" (asi->insn_fn) |
270 | : "lr", "memory", "cc" | 186 | : "lr", "memory", "cc" |
271 | ); | 187 | ); |
272 | 188 | ||
@@ -278,9 +194,9 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) | |||
278 | } | 194 | } |
279 | 195 | ||
280 | static void __kprobes | 196 | static void __kprobes |
281 | emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | 197 | emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn, |
198 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
282 | { | 199 | { |
283 | kprobe_opcode_t insn = p->opcode; | ||
284 | int rd = (insn >> 12) & 0xf; | 200 | int rd = (insn >> 12) & 0xf; |
285 | int rn = (insn >> 16) & 0xf; | 201 | int rn = (insn >> 16) & 0xf; |
286 | int rm = insn & 0xf; | 202 | int rm = insn & 0xf; |
@@ -296,7 +212,7 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
296 | "mrs %[cpsr], cpsr \n\t" | 212 | "mrs %[cpsr], cpsr \n\t" |
297 | : "=r" (rdv), [cpsr] "=r" (cpsr) | 213 | : "=r" (rdv), [cpsr] "=r" (cpsr) |
298 | : "0" (rdv), "r" (rnv), "r" (rmv), | 214 | : "0" (rdv), "r" (rnv), "r" (rmv), |
299 | "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) | 215 | "1" (cpsr), [fn] "r" (asi->insn_fn) |
300 | : "lr", "memory", "cc" | 216 | : "lr", "memory", "cc" |
301 | ); | 217 | ); |
302 | 218 | ||
@@ -305,9 +221,10 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
305 | } | 221 | } |
306 | 222 | ||
307 | static void __kprobes | 223 | static void __kprobes |
308 | emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | 224 | emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn, |
225 | struct arch_probes_insn *asi, | ||
226 | struct pt_regs *regs) | ||
309 | { | 227 | { |
310 | kprobe_opcode_t insn = p->opcode; | ||
311 | int rd = (insn >> 16) & 0xf; | 228 | int rd = (insn >> 16) & 0xf; |
312 | int rn = (insn >> 12) & 0xf; | 229 | int rn = (insn >> 12) & 0xf; |
313 | int rm = insn & 0xf; | 230 | int rm = insn & 0xf; |
@@ -325,7 +242,7 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
325 | "mrs %[cpsr], cpsr \n\t" | 242 | "mrs %[cpsr], cpsr \n\t" |
326 | : "=r" (rdv), [cpsr] "=r" (cpsr) | 243 | : "=r" (rdv), [cpsr] "=r" (cpsr) |
327 | : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), | 244 | : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), |
328 | "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) | 245 | "1" (cpsr), [fn] "r" (asi->insn_fn) |
329 | : "lr", "memory", "cc" | 246 | : "lr", "memory", "cc" |
330 | ); | 247 | ); |
331 | 248 | ||
@@ -334,9 +251,9 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
334 | } | 251 | } |
335 | 252 | ||
336 | static void __kprobes | 253 | static void __kprobes |
337 | emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs) | 254 | emulate_rd12rm0_noflags_nopc(probes_opcode_t insn, |
255 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
338 | { | 256 | { |
339 | kprobe_opcode_t insn = p->opcode; | ||
340 | int rd = (insn >> 12) & 0xf; | 257 | int rd = (insn >> 12) & 0xf; |
341 | int rm = insn & 0xf; | 258 | int rm = insn & 0xf; |
342 | 259 | ||
@@ -346,7 +263,7 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
346 | __asm__ __volatile__ ( | 263 | __asm__ __volatile__ ( |
347 | BLX("%[fn]") | 264 | BLX("%[fn]") |
348 | : "=r" (rdv) | 265 | : "=r" (rdv) |
349 | : "0" (rdv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) | 266 | : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn) |
350 | : "lr", "memory", "cc" | 267 | : "lr", "memory", "cc" |
351 | ); | 268 | ); |
352 | 269 | ||
@@ -354,9 +271,10 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
354 | } | 271 | } |
355 | 272 | ||
356 | static void __kprobes | 273 | static void __kprobes |
357 | emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | 274 | emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn, |
275 | struct arch_probes_insn *asi, | ||
276 | struct pt_regs *regs) | ||
358 | { | 277 | { |
359 | kprobe_opcode_t insn = p->opcode; | ||
360 | int rdlo = (insn >> 12) & 0xf; | 278 | int rdlo = (insn >> 12) & 0xf; |
361 | int rdhi = (insn >> 16) & 0xf; | 279 | int rdhi = (insn >> 16) & 0xf; |
362 | int rn = insn & 0xf; | 280 | int rn = insn & 0xf; |
@@ -374,7 +292,7 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
374 | "mrs %[cpsr], cpsr \n\t" | 292 | "mrs %[cpsr], cpsr \n\t" |
375 | : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr) | 293 | : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr) |
376 | : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), | 294 | : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), |
377 | "2" (cpsr), [fn] "r" (p->ainsn.insn_fn) | 295 | "2" (cpsr), [fn] "r" (asi->insn_fn) |
378 | : "lr", "memory", "cc" | 296 | : "lr", "memory", "cc" |
379 | ); | 297 | ); |
380 | 298 | ||
@@ -383,623 +301,43 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) | |||
383 | regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); | 301 | regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); |
384 | } | 302 | } |
385 | 303 | ||
386 | /* | 304 | const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { |
387 | * For the instruction masking and comparisons in all the "space_*" | 305 | [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none}, |
388 | * functions below, Do _not_ rearrange the order of tests unless | 306 | [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop}, |
389 | * you're very, very sure of what you are doing. For the sake of | 307 | [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop}, |
390 | * efficiency, the masks for some tests sometimes assume other test | 308 | [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop}, |
391 | * have been done prior to them so the number of patterns to test | 309 | [PROBES_BRANCH_IMM] = {.handler = simulate_blx1}, |
392 | * for an instruction set can be as broad as possible to reduce the | 310 | [PROBES_MRS] = {.handler = simulate_mrs}, |
393 | * number of tests needed. | 311 | [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx}, |
394 | */ | 312 | [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc}, |
395 | 313 | [PROBES_SATURATING_ARITHMETIC] = { | |
396 | static const union decode_item arm_1111_table[] = { | 314 | .handler = emulate_rd12rn16rm0_rwflags_nopc}, |
397 | /* Unconditional instructions */ | 315 | [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc}, |
398 | 316 | [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc}, | |
399 | /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */ | 317 | [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc}, |
400 | /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */ | 318 | [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd}, |
401 | /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */ | 319 | [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr}, |
402 | /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */ | 320 | [PROBES_LOAD] = {.handler = emulate_ldr}, |
403 | DECODE_SIMULATE (0xfe300000, 0xf4100000, kprobe_simulate_nop), | 321 | [PROBES_STORE_EXTRA] = {.handler = emulate_str}, |
404 | 322 | [PROBES_STORE] = {.handler = emulate_str}, | |
405 | /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */ | 323 | [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp}, |
406 | /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */ | 324 | [PROBES_DATA_PROCESSING_REG] = { |
407 | /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */ | 325 | .handler = emulate_rd12rn16rm0rs8_rwflags}, |
408 | /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */ | 326 | [PROBES_DATA_PROCESSING_IMM] = { |
409 | DECODE_SIMULATE (0xfe300010, 0xf6100000, kprobe_simulate_nop), | 327 | .handler = emulate_rd12rn16rm0rs8_rwflags}, |
410 | 328 | [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc}, | |
411 | /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */ | 329 | [PROBES_SEV] = {.handler = probes_emulate_none}, |
412 | DECODE_SIMULATE (0xfe000000, 0xfa000000, simulate_blx1), | 330 | [PROBES_WFE] = {.handler = probes_simulate_nop}, |
413 | 331 | [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc}, | |
414 | /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ | 332 | [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc}, |
415 | /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ | 333 | [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc}, |
416 | /* SRS 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ | 334 | [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc}, |
417 | /* RFE 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ | 335 | [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc}, |
418 | 336 | [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc}, | |
419 | /* Coprocessor instructions... */ | 337 | [PROBES_MUL_ADD_LONG] = { |
420 | /* MCRR2 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */ | 338 | .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc}, |
421 | /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */ | 339 | [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc}, |
422 | /* LDC2 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | 340 | [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc}, |
423 | /* STC2 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | 341 | [PROBES_BRANCH] = {.handler = simulate_bbl}, |
424 | /* CDP2 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | 342 | [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} |
425 | /* MCR2 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | ||
426 | /* MRC2 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | ||
427 | |||
428 | /* Other unallocated instructions... */ | ||
429 | DECODE_END | ||
430 | }; | ||
431 | |||
432 | static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = { | ||
433 | /* Miscellaneous instructions */ | ||
434 | |||
435 | /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ | ||
436 | DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs, | ||
437 | REGS(0, NOPC, 0, 0, 0)), | ||
438 | |||
439 | /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ | ||
440 | DECODE_SIMULATE (0x0ff000f0, 0x01200010, simulate_blx2bx), | ||
441 | |||
442 | /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ | ||
443 | DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx, | ||
444 | REGS(0, 0, 0, 0, NOPC)), | ||
445 | |||
446 | /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ | ||
447 | DECODE_EMULATEX (0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc, | ||
448 | REGS(0, NOPC, 0, 0, NOPC)), | ||
449 | |||
450 | /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */ | ||
451 | /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */ | ||
452 | /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */ | ||
453 | /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */ | ||
454 | DECODE_EMULATEX (0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc, | ||
455 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
456 | |||
457 | /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | ||
458 | /* MSR cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | ||
459 | /* MRS spsr cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ | ||
460 | /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
461 | /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */ | ||
462 | /* And unallocated instructions... */ | ||
463 | DECODE_END | ||
464 | }; | ||
465 | |||
466 | static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = { | ||
467 | /* Halfword multiply and multiply-accumulate */ | ||
468 | |||
469 | /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ | ||
470 | DECODE_EMULATEX (0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc, | ||
471 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
472 | |||
473 | /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ | ||
474 | DECODE_OR (0x0ff000b0, 0x012000a0), | ||
475 | /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ | ||
476 | DECODE_EMULATEX (0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
477 | REGS(NOPC, 0, NOPC, 0, NOPC)), | ||
478 | |||
479 | /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */ | ||
480 | DECODE_OR (0x0ff00090, 0x01000080), | ||
481 | /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */ | ||
482 | DECODE_EMULATEX (0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
483 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
484 | |||
485 | DECODE_END | ||
486 | }; | 343 | }; |
487 | |||
488 | static const union decode_item arm_cccc_0000_____1001_table[] = { | ||
489 | /* Multiply and multiply-accumulate */ | ||
490 | |||
491 | /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */ | ||
492 | /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */ | ||
493 | DECODE_EMULATEX (0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
494 | REGS(NOPC, 0, NOPC, 0, NOPC)), | ||
495 | |||
496 | /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */ | ||
497 | /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */ | ||
498 | DECODE_OR (0x0fe000f0, 0x00200090), | ||
499 | /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */ | ||
500 | DECODE_EMULATEX (0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
501 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
502 | |||
503 | /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */ | ||
504 | DECODE_OR (0x0ff000f0, 0x00400090), | ||
505 | /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */ | ||
506 | /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */ | ||
507 | /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */ | ||
508 | /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */ | ||
509 | /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */ | ||
510 | /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */ | ||
511 | /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */ | ||
512 | /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */ | ||
513 | DECODE_EMULATEX (0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc, | ||
514 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
515 | |||
516 | DECODE_END | ||
517 | }; | ||
518 | |||
519 | static const union decode_item arm_cccc_0001_____1001_table[] = { | ||
520 | /* Synchronization primitives */ | ||
521 | |||
522 | #if __LINUX_ARM_ARCH__ < 6 | ||
523 | /* Deprecated on ARMv6 and may be UNDEFINED on v7 */ | ||
524 | /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */ | ||
525 | DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc, | ||
526 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
527 | #endif | ||
528 | /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */ | ||
529 | /* And unallocated instructions... */ | ||
530 | DECODE_END | ||
531 | }; | ||
532 | |||
533 | static const union decode_item arm_cccc_000x_____1xx1_table[] = { | ||
534 | /* Extra load/store instructions */ | ||
535 | |||
536 | /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */ | ||
537 | /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */ | ||
538 | /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */ | ||
539 | /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */ | ||
540 | /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */ | ||
541 | DECODE_REJECT (0x0f200090, 0x00200090), | ||
542 | |||
543 | /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */ | ||
544 | DECODE_REJECT (0x0e10e0d0, 0x0000e0d0), | ||
545 | |||
546 | /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */ | ||
547 | /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */ | ||
548 | DECODE_EMULATEX (0x0e5000d0, 0x000000d0, emulate_ldrdstrd, | ||
549 | REGS(NOPCWB, NOPCX, 0, 0, NOPC)), | ||
550 | |||
551 | /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */ | ||
552 | /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */ | ||
553 | DECODE_EMULATEX (0x0e5000d0, 0x004000d0, emulate_ldrdstrd, | ||
554 | REGS(NOPCWB, NOPCX, 0, 0, 0)), | ||
555 | |||
556 | /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */ | ||
557 | DECODE_EMULATEX (0x0e5000f0, 0x000000b0, emulate_str, | ||
558 | REGS(NOPCWB, NOPC, 0, 0, NOPC)), | ||
559 | |||
560 | /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */ | ||
561 | /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */ | ||
562 | /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */ | ||
563 | DECODE_EMULATEX (0x0e500090, 0x00100090, emulate_ldr, | ||
564 | REGS(NOPCWB, NOPC, 0, 0, NOPC)), | ||
565 | |||
566 | /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */ | ||
567 | DECODE_EMULATEX (0x0e5000f0, 0x004000b0, emulate_str, | ||
568 | REGS(NOPCWB, NOPC, 0, 0, 0)), | ||
569 | |||
570 | /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */ | ||
571 | /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */ | ||
572 | /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */ | ||
573 | DECODE_EMULATEX (0x0e500090, 0x00500090, emulate_ldr, | ||
574 | REGS(NOPCWB, NOPC, 0, 0, 0)), | ||
575 | |||
576 | DECODE_END | ||
577 | }; | ||
578 | |||
579 | static const union decode_item arm_cccc_000x_table[] = { | ||
580 | /* Data-processing (register) */ | ||
581 | |||
582 | /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */ | ||
583 | DECODE_REJECT (0x0e10f000, 0x0010f000), | ||
584 | |||
585 | /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */ | ||
586 | DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, simulate_mov_ipsp), | ||
587 | |||
588 | /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */ | ||
589 | /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */ | ||
590 | /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */ | ||
591 | /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */ | ||
592 | DECODE_EMULATEX (0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags, | ||
593 | REGS(ANY, 0, 0, 0, ANY)), | ||
594 | |||
595 | /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */ | ||
596 | /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */ | ||
597 | DECODE_EMULATEX (0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags, | ||
598 | REGS(0, ANY, 0, 0, ANY)), | ||
599 | |||
600 | /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */ | ||
601 | /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */ | ||
602 | /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */ | ||
603 | /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */ | ||
604 | /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */ | ||
605 | /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */ | ||
606 | /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */ | ||
607 | /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */ | ||
608 | /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */ | ||
609 | /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */ | ||
610 | DECODE_EMULATEX (0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags, | ||
611 | REGS(ANY, ANY, 0, 0, ANY)), | ||
612 | |||
613 | /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */ | ||
614 | /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */ | ||
615 | /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */ | ||
616 | /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */ | ||
617 | DECODE_EMULATEX (0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags, | ||
618 | REGS(ANY, 0, NOPC, 0, ANY)), | ||
619 | |||
620 | /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */ | ||
621 | /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */ | ||
622 | DECODE_EMULATEX (0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags, | ||
623 | REGS(0, ANY, NOPC, 0, ANY)), | ||
624 | |||
625 | /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */ | ||
626 | /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */ | ||
627 | /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */ | ||
628 | /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */ | ||
629 | /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */ | ||
630 | /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */ | ||
631 | /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */ | ||
632 | /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */ | ||
633 | /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */ | ||
634 | /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */ | ||
635 | DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags, | ||
636 | REGS(ANY, ANY, NOPC, 0, ANY)), | ||
637 | |||
638 | DECODE_END | ||
639 | }; | ||
640 | |||
641 | static const union decode_item arm_cccc_001x_table[] = { | ||
642 | /* Data-processing (immediate) */ | ||
643 | |||
644 | /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ | ||
645 | /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
646 | DECODE_EMULATEX (0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc, | ||
647 | REGS(0, NOPC, 0, 0, 0)), | ||
648 | |||
649 | /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ | ||
650 | DECODE_OR (0x0fff00ff, 0x03200001), | ||
651 | /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ | ||
652 | DECODE_EMULATE (0x0fff00ff, 0x03200004, kprobe_emulate_none), | ||
653 | /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ | ||
654 | /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ | ||
655 | /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ | ||
656 | DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop), | ||
657 | /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */ | ||
658 | /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ | ||
659 | /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */ | ||
660 | DECODE_REJECT (0x0fb00000, 0x03200000), | ||
661 | |||
662 | /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */ | ||
663 | DECODE_REJECT (0x0e10f000, 0x0210f000), | ||
664 | |||
665 | /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */ | ||
666 | /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */ | ||
667 | /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
668 | /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */ | ||
669 | DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags, | ||
670 | REGS(ANY, 0, 0, 0, 0)), | ||
671 | |||
672 | /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */ | ||
673 | /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */ | ||
674 | DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags, | ||
675 | REGS(0, ANY, 0, 0, 0)), | ||
676 | |||
677 | /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */ | ||
678 | /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */ | ||
679 | /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */ | ||
680 | /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */ | ||
681 | /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */ | ||
682 | /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */ | ||
683 | /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */ | ||
684 | /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */ | ||
685 | /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */ | ||
686 | /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */ | ||
687 | DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags, | ||
688 | REGS(ANY, ANY, 0, 0, 0)), | ||
689 | |||
690 | DECODE_END | ||
691 | }; | ||
692 | |||
693 | static const union decode_item arm_cccc_0110_____xxx1_table[] = { | ||
694 | /* Media instructions */ | ||
695 | |||
696 | /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */ | ||
697 | DECODE_EMULATEX (0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc, | ||
698 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
699 | |||
700 | /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */ | ||
701 | /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */ | ||
702 | DECODE_OR(0x0fa00030, 0x06a00010), | ||
703 | /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */ | ||
704 | /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */ | ||
705 | DECODE_EMULATEX (0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc, | ||
706 | REGS(0, NOPC, 0, 0, NOPC)), | ||
707 | |||
708 | /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ | ||
709 | /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ | ||
710 | /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */ | ||
711 | /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ | ||
712 | DECODE_EMULATEX (0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc, | ||
713 | REGS(0, NOPC, 0, 0, NOPC)), | ||
714 | |||
715 | /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */ | ||
716 | DECODE_REJECT (0x0fb00010, 0x06000010), | ||
717 | /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */ | ||
718 | DECODE_REJECT (0x0f8000f0, 0x060000b0), | ||
719 | /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */ | ||
720 | DECODE_REJECT (0x0f8000f0, 0x060000d0), | ||
721 | /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */ | ||
722 | /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */ | ||
723 | /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */ | ||
724 | /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */ | ||
725 | /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */ | ||
726 | /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */ | ||
727 | /* QADD16 cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */ | ||
728 | /* QADDSUBX cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */ | ||
729 | /* QSUBADDX cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */ | ||
730 | /* QSUB16 cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
731 | /* QADD8 cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */ | ||
732 | /* QSUB8 cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */ | ||
733 | /* SHADD16 cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */ | ||
734 | /* SHADDSUBX cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */ | ||
735 | /* SHSUBADDX cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */ | ||
736 | /* SHSUB16 cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */ | ||
737 | /* SHADD8 cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */ | ||
738 | /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */ | ||
739 | /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */ | ||
740 | /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */ | ||
741 | /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */ | ||
742 | /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */ | ||
743 | /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */ | ||
744 | /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */ | ||
745 | /* UQADD16 cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */ | ||
746 | /* UQADDSUBX cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */ | ||
747 | /* UQSUBADDX cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */ | ||
748 | /* UQSUB16 cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */ | ||
749 | /* UQADD8 cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */ | ||
750 | /* UQSUB8 cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */ | ||
751 | /* UHADD16 cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */ | ||
752 | /* UHADDSUBX cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */ | ||
753 | /* UHSUBADDX cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */ | ||
754 | /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */ | ||
755 | /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */ | ||
756 | /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */ | ||
757 | DECODE_EMULATEX (0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc, | ||
758 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
759 | |||
760 | /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */ | ||
761 | /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */ | ||
762 | DECODE_EMULATEX (0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc, | ||
763 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
764 | |||
765 | /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */ | ||
766 | /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */ | ||
767 | DECODE_REJECT (0x0fb000f0, 0x06900070), | ||
768 | |||
769 | /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */ | ||
770 | /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */ | ||
771 | /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */ | ||
772 | /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */ | ||
773 | /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */ | ||
774 | /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */ | ||
775 | DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc, | ||
776 | REGS(0, NOPC, 0, 0, NOPC)), | ||
777 | |||
778 | /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */ | ||
779 | /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */ | ||
780 | /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */ | ||
781 | /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */ | ||
782 | /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */ | ||
783 | /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */ | ||
784 | DECODE_EMULATEX (0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc, | ||
785 | REGS(NOPCX, NOPC, 0, 0, NOPC)), | ||
786 | |||
787 | DECODE_END | ||
788 | }; | ||
789 | |||
790 | static const union decode_item arm_cccc_0111_____xxx1_table[] = { | ||
791 | /* Media instructions */ | ||
792 | |||
793 | /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */ | ||
794 | DECODE_REJECT (0x0ff000f0, 0x07f000f0), | ||
795 | |||
796 | /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ | ||
797 | /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ | ||
798 | DECODE_EMULATEX (0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc, | ||
799 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
800 | |||
801 | /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */ | ||
802 | /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */ | ||
803 | DECODE_OR (0x0ff0f090, 0x0700f010), | ||
804 | /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */ | ||
805 | DECODE_OR (0x0ff0f0d0, 0x0750f010), | ||
806 | /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ | ||
807 | DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
808 | REGS(NOPC, 0, NOPC, 0, NOPC)), | ||
809 | |||
810 | /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */ | ||
811 | /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */ | ||
812 | DECODE_OR (0x0ff00090, 0x07000010), | ||
813 | /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */ | ||
814 | DECODE_OR (0x0ff000d0, 0x07500010), | ||
815 | /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ | ||
816 | DECODE_EMULATEX (0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
817 | REGS(NOPC, NOPCX, NOPC, 0, NOPC)), | ||
818 | |||
819 | /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */ | ||
820 | DECODE_EMULATEX (0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc, | ||
821 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
822 | |||
823 | /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */ | ||
824 | /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */ | ||
825 | DECODE_EMULATEX (0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc, | ||
826 | REGS(0, NOPC, 0, 0, NOPC)), | ||
827 | |||
828 | /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */ | ||
829 | DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc, | ||
830 | REGS(0, NOPC, 0, 0, 0)), | ||
831 | |||
832 | /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */ | ||
833 | DECODE_EMULATEX (0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc, | ||
834 | REGS(0, NOPC, 0, 0, NOPCX)), | ||
835 | |||
836 | DECODE_END | ||
837 | }; | ||
838 | |||
839 | static const union decode_item arm_cccc_01xx_table[] = { | ||
840 | /* Load/store word and unsigned byte */ | ||
841 | |||
842 | /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */ | ||
843 | DECODE_REJECT (0x0c40f000, 0x0440f000), | ||
844 | |||
845 | /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ | ||
846 | /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */ | ||
847 | /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ | ||
848 | /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */ | ||
849 | DECODE_REJECT (0x0d200000, 0x04200000), | ||
850 | |||
851 | /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
852 | /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
853 | DECODE_EMULATEX (0x0e100000, 0x04000000, emulate_str, | ||
854 | REGS(NOPCWB, ANY, 0, 0, 0)), | ||
855 | |||
856 | /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
857 | /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
858 | DECODE_EMULATEX (0x0e100000, 0x04100000, emulate_ldr, | ||
859 | REGS(NOPCWB, ANY, 0, 0, 0)), | ||
860 | |||
861 | /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
862 | /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
863 | DECODE_EMULATEX (0x0e100000, 0x06000000, emulate_str, | ||
864 | REGS(NOPCWB, ANY, 0, 0, NOPC)), | ||
865 | |||
866 | /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
867 | /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
868 | DECODE_EMULATEX (0x0e100000, 0x06100000, emulate_ldr, | ||
869 | REGS(NOPCWB, ANY, 0, 0, NOPC)), | ||
870 | |||
871 | DECODE_END | ||
872 | }; | ||
873 | |||
874 | static const union decode_item arm_cccc_100x_table[] = { | ||
875 | /* Block data transfer instructions */ | ||
876 | |||
877 | /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
878 | /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
879 | DECODE_CUSTOM (0x0e400000, 0x08000000, kprobe_decode_ldmstm), | ||
880 | |||
881 | /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
882 | /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */ | ||
883 | /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */ | ||
884 | DECODE_END | ||
885 | }; | ||
886 | |||
887 | const union decode_item kprobe_decode_arm_table[] = { | ||
888 | /* | ||
889 | * Unconditional instructions | ||
890 | * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx | ||
891 | */ | ||
892 | DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table), | ||
893 | |||
894 | /* | ||
895 | * Miscellaneous instructions | ||
896 | * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx | ||
897 | */ | ||
898 | DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table), | ||
899 | |||
900 | /* | ||
901 | * Halfword multiply and multiply-accumulate | ||
902 | * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx | ||
903 | */ | ||
904 | DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table), | ||
905 | |||
906 | /* | ||
907 | * Multiply and multiply-accumulate | ||
908 | * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx | ||
909 | */ | ||
910 | DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table), | ||
911 | |||
912 | /* | ||
913 | * Synchronization primitives | ||
914 | * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx | ||
915 | */ | ||
916 | DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table), | ||
917 | |||
918 | /* | ||
919 | * Extra load/store instructions | ||
920 | * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx | ||
921 | */ | ||
922 | DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table), | ||
923 | |||
924 | /* | ||
925 | * Data-processing (register) | ||
926 | * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx | ||
927 | * Data-processing (register-shifted register) | ||
928 | * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx | ||
929 | */ | ||
930 | DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table), | ||
931 | |||
932 | /* | ||
933 | * Data-processing (immediate) | ||
934 | * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx | ||
935 | */ | ||
936 | DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table), | ||
937 | |||
938 | /* | ||
939 | * Media instructions | ||
940 | * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx | ||
941 | */ | ||
942 | DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table), | ||
943 | DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table), | ||
944 | |||
945 | /* | ||
946 | * Load/store word and unsigned byte | ||
947 | * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx | ||
948 | */ | ||
949 | DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table), | ||
950 | |||
951 | /* | ||
952 | * Block data transfer instructions | ||
953 | * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx | ||
954 | */ | ||
955 | DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table), | ||
956 | |||
957 | /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
958 | /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
959 | DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl), | ||
960 | |||
961 | /* | ||
962 | * Supervisor Call, and coprocessor instructions | ||
963 | */ | ||
964 | |||
965 | /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
966 | /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
967 | /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | ||
968 | /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | ||
969 | /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | ||
970 | /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | ||
971 | /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | ||
972 | /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
973 | DECODE_REJECT (0x0c000000, 0x0c000000), | ||
974 | |||
975 | DECODE_END | ||
976 | }; | ||
977 | #ifdef CONFIG_ARM_KPROBES_TEST_MODULE | ||
978 | EXPORT_SYMBOL_GPL(kprobe_decode_arm_table); | ||
979 | #endif | ||
980 | |||
981 | static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs) | ||
982 | { | ||
983 | regs->ARM_pc += 4; | ||
984 | p->ainsn.insn_handler(p, regs); | ||
985 | } | ||
986 | |||
987 | /* Return: | ||
988 | * INSN_REJECTED If instruction is one not allowed to kprobe, | ||
989 | * INSN_GOOD If instruction is supported and uses instruction slot, | ||
990 | * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot. | ||
991 | * | ||
992 | * For instructions we don't want to kprobe (INSN_REJECTED return result): | ||
993 | * These are generally ones that modify the processor state making | ||
994 | * them "hard" to simulate such as switches processor modes or | ||
995 | * make accesses in alternate modes. Any of these could be simulated | ||
996 | * if the work was put into it, but low return considering they | ||
997 | * should also be very rare. | ||
998 | */ | ||
999 | enum kprobe_insn __kprobes | ||
1000 | arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1001 | { | ||
1002 | asi->insn_singlestep = arm_singlestep; | ||
1003 | asi->insn_check_cc = kprobe_condition_checks[insn>>28]; | ||
1004 | return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false); | ||
1005 | } | ||
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c index 18a76282970e..c311ed94ff1c 100644 --- a/arch/arm/kernel/kprobes-common.c +++ b/arch/arm/kernel/kprobes-common.c | |||
@@ -13,178 +13,14 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/kprobes.h> | 15 | #include <linux/kprobes.h> |
16 | #include <asm/system_info.h> | ||
17 | 16 | ||
18 | #include "kprobes.h" | 17 | #include "kprobes.h" |
19 | 18 | ||
20 | 19 | ||
21 | #ifndef find_str_pc_offset | 20 | static void __kprobes simulate_ldm1stm1(probes_opcode_t insn, |
22 | 21 | struct arch_probes_insn *asi, | |
23 | /* | 22 | struct pt_regs *regs) |
24 | * For STR and STM instructions, an ARM core may choose to use either | ||
25 | * a +8 or a +12 displacement from the current instruction's address. | ||
26 | * Whichever value is chosen for a given core, it must be the same for | ||
27 | * both instructions and may not change. This function measures it. | ||
28 | */ | ||
29 | |||
30 | int str_pc_offset; | ||
31 | |||
32 | void __init find_str_pc_offset(void) | ||
33 | { | ||
34 | int addr, scratch, ret; | ||
35 | |||
36 | __asm__ ( | ||
37 | "sub %[ret], pc, #4 \n\t" | ||
38 | "str pc, %[addr] \n\t" | ||
39 | "ldr %[scr], %[addr] \n\t" | ||
40 | "sub %[ret], %[scr], %[ret] \n\t" | ||
41 | : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr)); | ||
42 | |||
43 | str_pc_offset = ret; | ||
44 | } | ||
45 | |||
46 | #endif /* !find_str_pc_offset */ | ||
47 | |||
48 | |||
49 | #ifndef test_load_write_pc_interworking | ||
50 | |||
51 | bool load_write_pc_interworks; | ||
52 | |||
53 | void __init test_load_write_pc_interworking(void) | ||
54 | { | ||
55 | int arch = cpu_architecture(); | ||
56 | BUG_ON(arch == CPU_ARCH_UNKNOWN); | ||
57 | load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T; | ||
58 | } | ||
59 | |||
60 | #endif /* !test_load_write_pc_interworking */ | ||
61 | |||
62 | |||
63 | #ifndef test_alu_write_pc_interworking | ||
64 | |||
65 | bool alu_write_pc_interworks; | ||
66 | |||
67 | void __init test_alu_write_pc_interworking(void) | ||
68 | { | ||
69 | int arch = cpu_architecture(); | ||
70 | BUG_ON(arch == CPU_ARCH_UNKNOWN); | ||
71 | alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7; | ||
72 | } | ||
73 | |||
74 | #endif /* !test_alu_write_pc_interworking */ | ||
75 | |||
76 | |||
77 | void __init arm_kprobe_decode_init(void) | ||
78 | { | ||
79 | find_str_pc_offset(); | ||
80 | test_load_write_pc_interworking(); | ||
81 | test_alu_write_pc_interworking(); | ||
82 | } | ||
83 | |||
84 | |||
85 | static unsigned long __kprobes __check_eq(unsigned long cpsr) | ||
86 | { | ||
87 | return cpsr & PSR_Z_BIT; | ||
88 | } | ||
89 | |||
90 | static unsigned long __kprobes __check_ne(unsigned long cpsr) | ||
91 | { | ||
92 | return (~cpsr) & PSR_Z_BIT; | ||
93 | } | ||
94 | |||
95 | static unsigned long __kprobes __check_cs(unsigned long cpsr) | ||
96 | { | ||
97 | return cpsr & PSR_C_BIT; | ||
98 | } | ||
99 | |||
100 | static unsigned long __kprobes __check_cc(unsigned long cpsr) | ||
101 | { | ||
102 | return (~cpsr) & PSR_C_BIT; | ||
103 | } | ||
104 | |||
105 | static unsigned long __kprobes __check_mi(unsigned long cpsr) | ||
106 | { | ||
107 | return cpsr & PSR_N_BIT; | ||
108 | } | ||
109 | |||
110 | static unsigned long __kprobes __check_pl(unsigned long cpsr) | ||
111 | { | ||
112 | return (~cpsr) & PSR_N_BIT; | ||
113 | } | ||
114 | |||
115 | static unsigned long __kprobes __check_vs(unsigned long cpsr) | ||
116 | { | ||
117 | return cpsr & PSR_V_BIT; | ||
118 | } | ||
119 | |||
120 | static unsigned long __kprobes __check_vc(unsigned long cpsr) | ||
121 | { | ||
122 | return (~cpsr) & PSR_V_BIT; | ||
123 | } | ||
124 | |||
125 | static unsigned long __kprobes __check_hi(unsigned long cpsr) | ||
126 | { | ||
127 | cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | ||
128 | return cpsr & PSR_C_BIT; | ||
129 | } | ||
130 | |||
131 | static unsigned long __kprobes __check_ls(unsigned long cpsr) | ||
132 | { | ||
133 | cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | ||
134 | return (~cpsr) & PSR_C_BIT; | ||
135 | } | ||
136 | |||
137 | static unsigned long __kprobes __check_ge(unsigned long cpsr) | ||
138 | { | ||
139 | cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
140 | return (~cpsr) & PSR_N_BIT; | ||
141 | } | ||
142 | |||
143 | static unsigned long __kprobes __check_lt(unsigned long cpsr) | ||
144 | { | ||
145 | cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
146 | return cpsr & PSR_N_BIT; | ||
147 | } | ||
148 | |||
149 | static unsigned long __kprobes __check_gt(unsigned long cpsr) | ||
150 | { | ||
151 | unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
152 | temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | ||
153 | return (~temp) & PSR_N_BIT; | ||
154 | } | ||
155 | |||
156 | static unsigned long __kprobes __check_le(unsigned long cpsr) | ||
157 | { | ||
158 | unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
159 | temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | ||
160 | return temp & PSR_N_BIT; | ||
161 | } | ||
162 | |||
163 | static unsigned long __kprobes __check_al(unsigned long cpsr) | ||
164 | { | ||
165 | return true; | ||
166 | } | ||
167 | |||
168 | kprobe_check_cc * const kprobe_condition_checks[16] = { | ||
169 | &__check_eq, &__check_ne, &__check_cs, &__check_cc, | ||
170 | &__check_mi, &__check_pl, &__check_vs, &__check_vc, | ||
171 | &__check_hi, &__check_ls, &__check_ge, &__check_lt, | ||
172 | &__check_gt, &__check_le, &__check_al, &__check_al | ||
173 | }; | ||
174 | |||
175 | |||
176 | void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs) | ||
177 | { | ||
178 | } | ||
179 | |||
180 | void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs) | ||
181 | { | ||
182 | p->ainsn.insn_fn(); | ||
183 | } | ||
184 | |||
185 | static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) | ||
186 | { | 23 | { |
187 | kprobe_opcode_t insn = p->opcode; | ||
188 | int rn = (insn >> 16) & 0xf; | 24 | int rn = (insn >> 16) & 0xf; |
189 | int lbit = insn & (1 << 20); | 25 | int lbit = insn & (1 << 20); |
190 | int wbit = insn & (1 << 21); | 26 | int wbit = insn & (1 << 21); |
@@ -223,24 +59,31 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) | |||
223 | } | 59 | } |
224 | } | 60 | } |
225 | 61 | ||
226 | static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) | 62 | static void __kprobes simulate_stm1_pc(probes_opcode_t insn, |
63 | struct arch_probes_insn *asi, | ||
64 | struct pt_regs *regs) | ||
227 | { | 65 | { |
228 | regs->ARM_pc = (long)p->addr + str_pc_offset; | 66 | unsigned long addr = regs->ARM_pc - 4; |
229 | simulate_ldm1stm1(p, regs); | 67 | |
230 | regs->ARM_pc = (long)p->addr + 4; | 68 | regs->ARM_pc = (long)addr + str_pc_offset; |
69 | simulate_ldm1stm1(insn, asi, regs); | ||
70 | regs->ARM_pc = (long)addr + 4; | ||
231 | } | 71 | } |
232 | 72 | ||
233 | static void __kprobes simulate_ldm1_pc(struct kprobe *p, struct pt_regs *regs) | 73 | static void __kprobes simulate_ldm1_pc(probes_opcode_t insn, |
74 | struct arch_probes_insn *asi, | ||
75 | struct pt_regs *regs) | ||
234 | { | 76 | { |
235 | simulate_ldm1stm1(p, regs); | 77 | simulate_ldm1stm1(insn, asi, regs); |
236 | load_write_pc(regs->ARM_pc, regs); | 78 | load_write_pc(regs->ARM_pc, regs); |
237 | } | 79 | } |
238 | 80 | ||
239 | static void __kprobes | 81 | static void __kprobes |
240 | emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs) | 82 | emulate_generic_r0_12_noflags(probes_opcode_t insn, |
83 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
241 | { | 84 | { |
242 | register void *rregs asm("r1") = regs; | 85 | register void *rregs asm("r1") = regs; |
243 | register void *rfn asm("lr") = p->ainsn.insn_fn; | 86 | register void *rfn asm("lr") = asi->insn_fn; |
244 | 87 | ||
245 | __asm__ __volatile__ ( | 88 | __asm__ __volatile__ ( |
246 | "stmdb sp!, {%[regs], r11} \n\t" | 89 | "stmdb sp!, {%[regs], r11} \n\t" |
@@ -264,22 +107,27 @@ emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs) | |||
264 | } | 107 | } |
265 | 108 | ||
266 | static void __kprobes | 109 | static void __kprobes |
267 | emulate_generic_r2_14_noflags(struct kprobe *p, struct pt_regs *regs) | 110 | emulate_generic_r2_14_noflags(probes_opcode_t insn, |
111 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
268 | { | 112 | { |
269 | emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+2)); | 113 | emulate_generic_r0_12_noflags(insn, asi, |
114 | (struct pt_regs *)(regs->uregs+2)); | ||
270 | } | 115 | } |
271 | 116 | ||
272 | static void __kprobes | 117 | static void __kprobes |
273 | emulate_ldm_r3_15(struct kprobe *p, struct pt_regs *regs) | 118 | emulate_ldm_r3_15(probes_opcode_t insn, |
119 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
274 | { | 120 | { |
275 | emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+3)); | 121 | emulate_generic_r0_12_noflags(insn, asi, |
122 | (struct pt_regs *)(regs->uregs+3)); | ||
276 | load_write_pc(regs->ARM_pc, regs); | 123 | load_write_pc(regs->ARM_pc, regs); |
277 | } | 124 | } |
278 | 125 | ||
279 | enum kprobe_insn __kprobes | 126 | enum probes_insn __kprobes |
280 | kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 127 | kprobe_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi, |
128 | const struct decode_header *h) | ||
281 | { | 129 | { |
282 | kprobe_insn_handler_t *handler = 0; | 130 | probes_insn_handler_t *handler = 0; |
283 | unsigned reglist = insn & 0xffff; | 131 | unsigned reglist = insn & 0xffff; |
284 | int is_ldm = insn & 0x100000; | 132 | int is_ldm = insn & 0x100000; |
285 | int rn = (insn >> 16) & 0xf; | 133 | int rn = (insn >> 16) & 0xf; |
@@ -319,260 +167,3 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
319 | return INSN_GOOD_NO_SLOT; | 167 | return INSN_GOOD_NO_SLOT; |
320 | } | 168 | } |
321 | 169 | ||
322 | |||
323 | /* | ||
324 | * Prepare an instruction slot to receive an instruction for emulating. | ||
325 | * This is done by placing a subroutine return after the location where the | ||
326 | * instruction will be placed. We also modify ARM instructions to be | ||
327 | * unconditional as the condition code will already be checked before any | ||
328 | * emulation handler is called. | ||
329 | */ | ||
330 | static kprobe_opcode_t __kprobes | ||
331 | prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
332 | bool thumb) | ||
333 | { | ||
334 | #ifdef CONFIG_THUMB2_KERNEL | ||
335 | if (thumb) { | ||
336 | u16 *thumb_insn = (u16 *)asi->insn; | ||
337 | thumb_insn[1] = 0x4770; /* Thumb bx lr */ | ||
338 | thumb_insn[2] = 0x4770; /* Thumb bx lr */ | ||
339 | return insn; | ||
340 | } | ||
341 | asi->insn[1] = 0xe12fff1e; /* ARM bx lr */ | ||
342 | #else | ||
343 | asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */ | ||
344 | #endif | ||
345 | /* Make an ARM instruction unconditional */ | ||
346 | if (insn < 0xe0000000) | ||
347 | insn = (insn | 0xe0000000) & ~0x10000000; | ||
348 | return insn; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * Write a (probably modified) instruction into the slot previously prepared by | ||
353 | * prepare_emulated_insn | ||
354 | */ | ||
355 | static void __kprobes | ||
356 | set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
357 | bool thumb) | ||
358 | { | ||
359 | #ifdef CONFIG_THUMB2_KERNEL | ||
360 | if (thumb) { | ||
361 | u16 *ip = (u16 *)asi->insn; | ||
362 | if (is_wide_instruction(insn)) | ||
363 | *ip++ = insn >> 16; | ||
364 | *ip++ = insn; | ||
365 | return; | ||
366 | } | ||
367 | #endif | ||
368 | asi->insn[0] = insn; | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * When we modify the register numbers encoded in an instruction to be emulated, | ||
373 | * the new values come from this define. For ARM and 32-bit Thumb instructions | ||
374 | * this gives... | ||
375 | * | ||
376 | * bit position 16 12 8 4 0 | ||
377 | * ---------------+---+---+---+---+---+ | ||
378 | * register r2 r0 r1 -- r3 | ||
379 | */ | ||
380 | #define INSN_NEW_BITS 0x00020103 | ||
381 | |||
382 | /* Each nibble has same value as that at INSN_NEW_BITS bit 16 */ | ||
383 | #define INSN_SAMEAS16_BITS 0x22222222 | ||
384 | |||
385 | /* | ||
386 | * Validate and modify each of the registers encoded in an instruction. | ||
387 | * | ||
388 | * Each nibble in regs contains a value from enum decode_reg_type. For each | ||
389 | * non-zero value, the corresponding nibble in pinsn is validated and modified | ||
390 | * according to the type. | ||
391 | */ | ||
392 | static bool __kprobes decode_regs(kprobe_opcode_t* pinsn, u32 regs) | ||
393 | { | ||
394 | kprobe_opcode_t insn = *pinsn; | ||
395 | kprobe_opcode_t mask = 0xf; /* Start at least significant nibble */ | ||
396 | |||
397 | for (; regs != 0; regs >>= 4, mask <<= 4) { | ||
398 | |||
399 | kprobe_opcode_t new_bits = INSN_NEW_BITS; | ||
400 | |||
401 | switch (regs & 0xf) { | ||
402 | |||
403 | case REG_TYPE_NONE: | ||
404 | /* Nibble not a register, skip to next */ | ||
405 | continue; | ||
406 | |||
407 | case REG_TYPE_ANY: | ||
408 | /* Any register is allowed */ | ||
409 | break; | ||
410 | |||
411 | case REG_TYPE_SAMEAS16: | ||
412 | /* Replace register with same as at bit position 16 */ | ||
413 | new_bits = INSN_SAMEAS16_BITS; | ||
414 | break; | ||
415 | |||
416 | case REG_TYPE_SP: | ||
417 | /* Only allow SP (R13) */ | ||
418 | if ((insn ^ 0xdddddddd) & mask) | ||
419 | goto reject; | ||
420 | break; | ||
421 | |||
422 | case REG_TYPE_PC: | ||
423 | /* Only allow PC (R15) */ | ||
424 | if ((insn ^ 0xffffffff) & mask) | ||
425 | goto reject; | ||
426 | break; | ||
427 | |||
428 | case REG_TYPE_NOSP: | ||
429 | /* Reject SP (R13) */ | ||
430 | if (((insn ^ 0xdddddddd) & mask) == 0) | ||
431 | goto reject; | ||
432 | break; | ||
433 | |||
434 | case REG_TYPE_NOSPPC: | ||
435 | case REG_TYPE_NOSPPCX: | ||
436 | /* Reject SP and PC (R13 and R15) */ | ||
437 | if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0) | ||
438 | goto reject; | ||
439 | break; | ||
440 | |||
441 | case REG_TYPE_NOPCWB: | ||
442 | if (!is_writeback(insn)) | ||
443 | break; /* No writeback, so any register is OK */ | ||
444 | /* fall through... */ | ||
445 | case REG_TYPE_NOPC: | ||
446 | case REG_TYPE_NOPCX: | ||
447 | /* Reject PC (R15) */ | ||
448 | if (((insn ^ 0xffffffff) & mask) == 0) | ||
449 | goto reject; | ||
450 | break; | ||
451 | } | ||
452 | |||
453 | /* Replace value of nibble with new register number... */ | ||
454 | insn &= ~mask; | ||
455 | insn |= new_bits & mask; | ||
456 | } | ||
457 | |||
458 | *pinsn = insn; | ||
459 | return true; | ||
460 | |||
461 | reject: | ||
462 | return false; | ||
463 | } | ||
464 | |||
465 | static const int decode_struct_sizes[NUM_DECODE_TYPES] = { | ||
466 | [DECODE_TYPE_TABLE] = sizeof(struct decode_table), | ||
467 | [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom), | ||
468 | [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate), | ||
469 | [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate), | ||
470 | [DECODE_TYPE_OR] = sizeof(struct decode_or), | ||
471 | [DECODE_TYPE_REJECT] = sizeof(struct decode_reject) | ||
472 | }; | ||
473 | |||
474 | /* | ||
475 | * kprobe_decode_insn operates on data tables in order to decode an ARM | ||
476 | * architecture instruction onto which a kprobe has been placed. | ||
477 | * | ||
478 | * These instruction decoding tables are a concatenation of entries each | ||
479 | * of which consist of one of the following structs: | ||
480 | * | ||
481 | * decode_table | ||
482 | * decode_custom | ||
483 | * decode_simulate | ||
484 | * decode_emulate | ||
485 | * decode_or | ||
486 | * decode_reject | ||
487 | * | ||
488 | * Each of these starts with a struct decode_header which has the following | ||
489 | * fields: | ||
490 | * | ||
491 | * type_regs | ||
492 | * mask | ||
493 | * value | ||
494 | * | ||
495 | * The least significant DECODE_TYPE_BITS of type_regs contains a value | ||
496 | * from enum decode_type, this indicates which of the decode_* structs | ||
497 | * the entry contains. The value DECODE_TYPE_END indicates the end of the | ||
498 | * table. | ||
499 | * | ||
500 | * When the table is parsed, each entry is checked in turn to see if it | ||
501 | * matches the instruction to be decoded using the test: | ||
502 | * | ||
503 | * (insn & mask) == value | ||
504 | * | ||
505 | * If no match is found before the end of the table is reached then decoding | ||
506 | * fails with INSN_REJECTED. | ||
507 | * | ||
508 | * When a match is found, decode_regs() is called to validate and modify each | ||
509 | * of the registers encoded in the instruction; the data it uses to do this | ||
510 | * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding | ||
511 | * to fail with INSN_REJECTED. | ||
512 | * | ||
513 | * Once the instruction has passed the above tests, further processing | ||
514 | * depends on the type of the table entry's decode struct. | ||
515 | * | ||
516 | */ | ||
517 | int __kprobes | ||
518 | kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
519 | const union decode_item *table, bool thumb) | ||
520 | { | ||
521 | const struct decode_header *h = (struct decode_header *)table; | ||
522 | const struct decode_header *next; | ||
523 | bool matched = false; | ||
524 | |||
525 | insn = prepare_emulated_insn(insn, asi, thumb); | ||
526 | |||
527 | for (;; h = next) { | ||
528 | enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; | ||
529 | u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS; | ||
530 | |||
531 | if (type == DECODE_TYPE_END) | ||
532 | return INSN_REJECTED; | ||
533 | |||
534 | next = (struct decode_header *) | ||
535 | ((uintptr_t)h + decode_struct_sizes[type]); | ||
536 | |||
537 | if (!matched && (insn & h->mask.bits) != h->value.bits) | ||
538 | continue; | ||
539 | |||
540 | if (!decode_regs(&insn, regs)) | ||
541 | return INSN_REJECTED; | ||
542 | |||
543 | switch (type) { | ||
544 | |||
545 | case DECODE_TYPE_TABLE: { | ||
546 | struct decode_table *d = (struct decode_table *)h; | ||
547 | next = (struct decode_header *)d->table.table; | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | case DECODE_TYPE_CUSTOM: { | ||
552 | struct decode_custom *d = (struct decode_custom *)h; | ||
553 | return (*d->decoder.decoder)(insn, asi); | ||
554 | } | ||
555 | |||
556 | case DECODE_TYPE_SIMULATE: { | ||
557 | struct decode_simulate *d = (struct decode_simulate *)h; | ||
558 | asi->insn_handler = d->handler.handler; | ||
559 | return INSN_GOOD_NO_SLOT; | ||
560 | } | ||
561 | |||
562 | case DECODE_TYPE_EMULATE: { | ||
563 | struct decode_emulate *d = (struct decode_emulate *)h; | ||
564 | asi->insn_handler = d->handler.handler; | ||
565 | set_emulated_insn(insn, asi, thumb); | ||
566 | return INSN_GOOD; | ||
567 | } | ||
568 | |||
569 | case DECODE_TYPE_OR: | ||
570 | matched = true; | ||
571 | break; | ||
572 | |||
573 | case DECODE_TYPE_REJECT: | ||
574 | default: | ||
575 | return INSN_REJECTED; | ||
576 | } | ||
577 | } | ||
578 | } | ||
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/kernel/kprobes-test-arm.c index 839312905067..87839de77e5f 100644 --- a/arch/arm/kernel/kprobes-test-arm.c +++ b/arch/arm/kernel/kprobes-test-arm.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <asm/system_info.h> | ||
13 | 14 | ||
14 | #include "kprobes-test.h" | 15 | #include "kprobes-test.h" |
15 | 16 | ||
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c index 0cd63d080c7b..c2fd06b4c389 100644 --- a/arch/arm/kernel/kprobes-test.c +++ b/arch/arm/kernel/kprobes-test.c | |||
@@ -201,10 +201,14 @@ | |||
201 | #include <linux/module.h> | 201 | #include <linux/module.h> |
202 | #include <linux/slab.h> | 202 | #include <linux/slab.h> |
203 | #include <linux/kprobes.h> | 203 | #include <linux/kprobes.h> |
204 | 204 | #include <linux/errno.h> | |
205 | #include <linux/stddef.h> | ||
206 | #include <linux/bug.h> | ||
205 | #include <asm/opcodes.h> | 207 | #include <asm/opcodes.h> |
206 | 208 | ||
207 | #include "kprobes.h" | 209 | #include "kprobes.h" |
210 | #include "probes-arm.h" | ||
211 | #include "probes-thumb.h" | ||
208 | #include "kprobes-test.h" | 212 | #include "kprobes-test.h" |
209 | 213 | ||
210 | 214 | ||
@@ -1608,7 +1612,7 @@ static int __init run_all_tests(void) | |||
1608 | goto out; | 1612 | goto out; |
1609 | 1613 | ||
1610 | pr_info("ARM instruction simulation\n"); | 1614 | pr_info("ARM instruction simulation\n"); |
1611 | ret = run_test_cases(kprobe_arm_test_cases, kprobe_decode_arm_table); | 1615 | ret = run_test_cases(kprobe_arm_test_cases, probes_decode_arm_table); |
1612 | if (ret) | 1616 | if (ret) |
1613 | goto out; | 1617 | goto out; |
1614 | 1618 | ||
@@ -1631,13 +1635,13 @@ static int __init run_all_tests(void) | |||
1631 | 1635 | ||
1632 | pr_info("16-bit Thumb instruction simulation\n"); | 1636 | pr_info("16-bit Thumb instruction simulation\n"); |
1633 | ret = run_test_cases(kprobe_thumb16_test_cases, | 1637 | ret = run_test_cases(kprobe_thumb16_test_cases, |
1634 | kprobe_decode_thumb16_table); | 1638 | probes_decode_thumb16_table); |
1635 | if (ret) | 1639 | if (ret) |
1636 | goto out; | 1640 | goto out; |
1637 | 1641 | ||
1638 | pr_info("32-bit Thumb instruction simulation\n"); | 1642 | pr_info("32-bit Thumb instruction simulation\n"); |
1639 | ret = run_test_cases(kprobe_thumb32_test_cases, | 1643 | ret = run_test_cases(kprobe_thumb32_test_cases, |
1640 | kprobe_decode_thumb32_table); | 1644 | probes_decode_thumb32_table); |
1641 | if (ret) | 1645 | if (ret) |
1642 | goto out; | 1646 | goto out; |
1643 | #endif | 1647 | #endif |
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 6123daf397a7..6619188619ae 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c | |||
@@ -8,41 +8,25 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/types.h> | ||
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/ptrace.h> | ||
12 | #include <linux/kprobes.h> | 14 | #include <linux/kprobes.h> |
13 | #include <linux/module.h> | ||
14 | 15 | ||
15 | #include "kprobes.h" | 16 | #include "kprobes.h" |
17 | #include "probes-thumb.h" | ||
16 | 18 | ||
19 | /* These emulation encodings are functionally equivalent... */ | ||
20 | #define t32_emulate_rd8rn16rm0ra12_noflags \ | ||
21 | t32_emulate_rdlo12rdhi8rn16rm0_noflags | ||
17 | 22 | ||
18 | /* | 23 | /* t32 thumb actions */ |
19 | * True if current instruction is in an IT block. | ||
20 | */ | ||
21 | #define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000) | ||
22 | |||
23 | /* | ||
24 | * Return the condition code to check for the currently executing instruction. | ||
25 | * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if | ||
26 | * in_it_block returns true. | ||
27 | */ | ||
28 | #define current_cond(cpsr) ((cpsr >> 12) & 0xf) | ||
29 | |||
30 | /* | ||
31 | * Return the PC value for a probe in thumb code. | ||
32 | * This is the address of the probed instruction plus 4. | ||
33 | * We subtract one because the address will have bit zero set to indicate | ||
34 | * a pointer to thumb code. | ||
35 | */ | ||
36 | static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p) | ||
37 | { | ||
38 | return (unsigned long)p->addr - 1 + 4; | ||
39 | } | ||
40 | 24 | ||
41 | static void __kprobes | 25 | static void __kprobes |
42 | t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) | 26 | t32_simulate_table_branch(probes_opcode_t insn, |
27 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
43 | { | 28 | { |
44 | kprobe_opcode_t insn = p->opcode; | 29 | unsigned long pc = regs->ARM_pc; |
45 | unsigned long pc = thumb_probe_pc(p); | ||
46 | int rn = (insn >> 16) & 0xf; | 30 | int rn = (insn >> 16) & 0xf; |
47 | int rm = insn & 0xf; | 31 | int rm = insn & 0xf; |
48 | 32 | ||
@@ -59,19 +43,19 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) | |||
59 | } | 43 | } |
60 | 44 | ||
61 | static void __kprobes | 45 | static void __kprobes |
62 | t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs) | 46 | t32_simulate_mrs(probes_opcode_t insn, |
47 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
63 | { | 48 | { |
64 | kprobe_opcode_t insn = p->opcode; | ||
65 | int rd = (insn >> 8) & 0xf; | 49 | int rd = (insn >> 8) & 0xf; |
66 | unsigned long mask = 0xf8ff03df; /* Mask out execution state */ | 50 | unsigned long mask = 0xf8ff03df; /* Mask out execution state */ |
67 | regs->uregs[rd] = regs->ARM_cpsr & mask; | 51 | regs->uregs[rd] = regs->ARM_cpsr & mask; |
68 | } | 52 | } |
69 | 53 | ||
70 | static void __kprobes | 54 | static void __kprobes |
71 | t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) | 55 | t32_simulate_cond_branch(probes_opcode_t insn, |
56 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
72 | { | 57 | { |
73 | kprobe_opcode_t insn = p->opcode; | 58 | unsigned long pc = regs->ARM_pc; |
74 | unsigned long pc = thumb_probe_pc(p); | ||
75 | 59 | ||
76 | long offset = insn & 0x7ff; /* imm11 */ | 60 | long offset = insn & 0x7ff; /* imm11 */ |
77 | offset += (insn & 0x003f0000) >> 5; /* imm6 */ | 61 | offset += (insn & 0x003f0000) >> 5; /* imm6 */ |
@@ -82,20 +66,21 @@ t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) | |||
82 | regs->ARM_pc = pc + (offset * 2); | 66 | regs->ARM_pc = pc + (offset * 2); |
83 | } | 67 | } |
84 | 68 | ||
85 | static enum kprobe_insn __kprobes | 69 | static enum probes_insn __kprobes |
86 | t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 70 | t32_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi, |
71 | const struct decode_header *d) | ||
87 | { | 72 | { |
88 | int cc = (insn >> 22) & 0xf; | 73 | int cc = (insn >> 22) & 0xf; |
89 | asi->insn_check_cc = kprobe_condition_checks[cc]; | 74 | asi->insn_check_cc = probes_condition_checks[cc]; |
90 | asi->insn_handler = t32_simulate_cond_branch; | 75 | asi->insn_handler = t32_simulate_cond_branch; |
91 | return INSN_GOOD_NO_SLOT; | 76 | return INSN_GOOD_NO_SLOT; |
92 | } | 77 | } |
93 | 78 | ||
94 | static void __kprobes | 79 | static void __kprobes |
95 | t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) | 80 | t32_simulate_branch(probes_opcode_t insn, |
81 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
96 | { | 82 | { |
97 | kprobe_opcode_t insn = p->opcode; | 83 | unsigned long pc = regs->ARM_pc; |
98 | unsigned long pc = thumb_probe_pc(p); | ||
99 | 84 | ||
100 | long offset = insn & 0x7ff; /* imm11 */ | 85 | long offset = insn & 0x7ff; /* imm11 */ |
101 | offset += (insn & 0x03ff0000) >> 5; /* imm10 */ | 86 | offset += (insn & 0x03ff0000) >> 5; /* imm10 */ |
@@ -108,7 +93,7 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) | |||
108 | 93 | ||
109 | if (insn & (1 << 14)) { | 94 | if (insn & (1 << 14)) { |
110 | /* BL or BLX */ | 95 | /* BL or BLX */ |
111 | regs->ARM_lr = (unsigned long)p->addr + 4; | 96 | regs->ARM_lr = regs->ARM_pc | 1; |
112 | if (!(insn & (1 << 12))) { | 97 | if (!(insn & (1 << 12))) { |
113 | /* BLX so switch to ARM mode */ | 98 | /* BLX so switch to ARM mode */ |
114 | regs->ARM_cpsr &= ~PSR_T_BIT; | 99 | regs->ARM_cpsr &= ~PSR_T_BIT; |
@@ -120,10 +105,10 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) | |||
120 | } | 105 | } |
121 | 106 | ||
122 | static void __kprobes | 107 | static void __kprobes |
123 | t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) | 108 | t32_simulate_ldr_literal(probes_opcode_t insn, |
109 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
124 | { | 110 | { |
125 | kprobe_opcode_t insn = p->opcode; | 111 | unsigned long addr = regs->ARM_pc & ~3; |
126 | unsigned long addr = thumb_probe_pc(p) & ~3; | ||
127 | int rt = (insn >> 12) & 0xf; | 112 | int rt = (insn >> 12) & 0xf; |
128 | unsigned long rtv; | 113 | unsigned long rtv; |
129 | 114 | ||
@@ -157,10 +142,11 @@ t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) | |||
157 | regs->uregs[rt] = rtv; | 142 | regs->uregs[rt] = rtv; |
158 | } | 143 | } |
159 | 144 | ||
160 | static enum kprobe_insn __kprobes | 145 | static enum probes_insn __kprobes |
161 | t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 146 | t32_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi, |
147 | const struct decode_header *d) | ||
162 | { | 148 | { |
163 | enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi); | 149 | enum probes_insn ret = kprobe_decode_ldmstm(insn, asi, d); |
164 | 150 | ||
165 | /* Fixup modified instruction to have halfwords in correct order...*/ | 151 | /* Fixup modified instruction to have halfwords in correct order...*/ |
166 | insn = asi->insn[0]; | 152 | insn = asi->insn[0]; |
@@ -171,10 +157,10 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
171 | } | 157 | } |
172 | 158 | ||
173 | static void __kprobes | 159 | static void __kprobes |
174 | t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) | 160 | t32_emulate_ldrdstrd(probes_opcode_t insn, |
161 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
175 | { | 162 | { |
176 | kprobe_opcode_t insn = p->opcode; | 163 | unsigned long pc = regs->ARM_pc & ~3; |
177 | unsigned long pc = thumb_probe_pc(p) & ~3; | ||
178 | int rt1 = (insn >> 12) & 0xf; | 164 | int rt1 = (insn >> 12) & 0xf; |
179 | int rt2 = (insn >> 8) & 0xf; | 165 | int rt2 = (insn >> 8) & 0xf; |
180 | int rn = (insn >> 16) & 0xf; | 166 | int rn = (insn >> 16) & 0xf; |
@@ -187,7 +173,7 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) | |||
187 | __asm__ __volatile__ ( | 173 | __asm__ __volatile__ ( |
188 | "blx %[fn]" | 174 | "blx %[fn]" |
189 | : "=r" (rt1v), "=r" (rt2v), "=r" (rnv) | 175 | : "=r" (rt1v), "=r" (rt2v), "=r" (rnv) |
190 | : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (p->ainsn.insn_fn) | 176 | : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (asi->insn_fn) |
191 | : "lr", "memory", "cc" | 177 | : "lr", "memory", "cc" |
192 | ); | 178 | ); |
193 | 179 | ||
@@ -198,9 +184,9 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) | |||
198 | } | 184 | } |
199 | 185 | ||
200 | static void __kprobes | 186 | static void __kprobes |
201 | t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) | 187 | t32_emulate_ldrstr(probes_opcode_t insn, |
188 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
202 | { | 189 | { |
203 | kprobe_opcode_t insn = p->opcode; | ||
204 | int rt = (insn >> 12) & 0xf; | 190 | int rt = (insn >> 12) & 0xf; |
205 | int rn = (insn >> 16) & 0xf; | 191 | int rn = (insn >> 16) & 0xf; |
206 | int rm = insn & 0xf; | 192 | int rm = insn & 0xf; |
@@ -212,7 +198,7 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) | |||
212 | __asm__ __volatile__ ( | 198 | __asm__ __volatile__ ( |
213 | "blx %[fn]" | 199 | "blx %[fn]" |
214 | : "=r" (rtv), "=r" (rnv) | 200 | : "=r" (rtv), "=r" (rnv) |
215 | : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) | 201 | : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn) |
216 | : "lr", "memory", "cc" | 202 | : "lr", "memory", "cc" |
217 | ); | 203 | ); |
218 | 204 | ||
@@ -224,9 +210,9 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) | |||
224 | } | 210 | } |
225 | 211 | ||
226 | static void __kprobes | 212 | static void __kprobes |
227 | t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | 213 | t32_emulate_rd8rn16rm0_rwflags(probes_opcode_t insn, |
214 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
228 | { | 215 | { |
229 | kprobe_opcode_t insn = p->opcode; | ||
230 | int rd = (insn >> 8) & 0xf; | 216 | int rd = (insn >> 8) & 0xf; |
231 | int rn = (insn >> 16) & 0xf; | 217 | int rn = (insn >> 16) & 0xf; |
232 | int rm = insn & 0xf; | 218 | int rm = insn & 0xf; |
@@ -242,7 +228,7 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | |||
242 | "mrs %[cpsr], cpsr \n\t" | 228 | "mrs %[cpsr], cpsr \n\t" |
243 | : "=r" (rdv), [cpsr] "=r" (cpsr) | 229 | : "=r" (rdv), [cpsr] "=r" (cpsr) |
244 | : "0" (rdv), "r" (rnv), "r" (rmv), | 230 | : "0" (rdv), "r" (rnv), "r" (rmv), |
245 | "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) | 231 | "1" (cpsr), [fn] "r" (asi->insn_fn) |
246 | : "lr", "memory", "cc" | 232 | : "lr", "memory", "cc" |
247 | ); | 233 | ); |
248 | 234 | ||
@@ -251,10 +237,10 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | |||
251 | } | 237 | } |
252 | 238 | ||
253 | static void __kprobes | 239 | static void __kprobes |
254 | t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) | 240 | t32_emulate_rd8pc16_noflags(probes_opcode_t insn, |
241 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
255 | { | 242 | { |
256 | kprobe_opcode_t insn = p->opcode; | 243 | unsigned long pc = regs->ARM_pc; |
257 | unsigned long pc = thumb_probe_pc(p); | ||
258 | int rd = (insn >> 8) & 0xf; | 244 | int rd = (insn >> 8) & 0xf; |
259 | 245 | ||
260 | register unsigned long rdv asm("r1") = regs->uregs[rd]; | 246 | register unsigned long rdv asm("r1") = regs->uregs[rd]; |
@@ -263,7 +249,7 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) | |||
263 | __asm__ __volatile__ ( | 249 | __asm__ __volatile__ ( |
264 | "blx %[fn]" | 250 | "blx %[fn]" |
265 | : "=r" (rdv) | 251 | : "=r" (rdv) |
266 | : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn) | 252 | : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn) |
267 | : "lr", "memory", "cc" | 253 | : "lr", "memory", "cc" |
268 | ); | 254 | ); |
269 | 255 | ||
@@ -271,9 +257,9 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) | |||
271 | } | 257 | } |
272 | 258 | ||
273 | static void __kprobes | 259 | static void __kprobes |
274 | t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) | 260 | t32_emulate_rd8rn16_noflags(probes_opcode_t insn, |
261 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
275 | { | 262 | { |
276 | kprobe_opcode_t insn = p->opcode; | ||
277 | int rd = (insn >> 8) & 0xf; | 263 | int rd = (insn >> 8) & 0xf; |
278 | int rn = (insn >> 16) & 0xf; | 264 | int rn = (insn >> 16) & 0xf; |
279 | 265 | ||
@@ -283,7 +269,7 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) | |||
283 | __asm__ __volatile__ ( | 269 | __asm__ __volatile__ ( |
284 | "blx %[fn]" | 270 | "blx %[fn]" |
285 | : "=r" (rdv) | 271 | : "=r" (rdv) |
286 | : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn) | 272 | : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn) |
287 | : "lr", "memory", "cc" | 273 | : "lr", "memory", "cc" |
288 | ); | 274 | ); |
289 | 275 | ||
@@ -291,9 +277,10 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) | |||
291 | } | 277 | } |
292 | 278 | ||
293 | static void __kprobes | 279 | static void __kprobes |
294 | t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) | 280 | t32_emulate_rdlo12rdhi8rn16rm0_noflags(probes_opcode_t insn, |
281 | struct arch_probes_insn *asi, | ||
282 | struct pt_regs *regs) | ||
295 | { | 283 | { |
296 | kprobe_opcode_t insn = p->opcode; | ||
297 | int rdlo = (insn >> 12) & 0xf; | 284 | int rdlo = (insn >> 12) & 0xf; |
298 | int rdhi = (insn >> 8) & 0xf; | 285 | int rdhi = (insn >> 8) & 0xf; |
299 | int rn = (insn >> 16) & 0xf; | 286 | int rn = (insn >> 16) & 0xf; |
@@ -308,674 +295,43 @@ t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) | |||
308 | "blx %[fn]" | 295 | "blx %[fn]" |
309 | : "=r" (rdlov), "=r" (rdhiv) | 296 | : "=r" (rdlov), "=r" (rdhiv) |
310 | : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), | 297 | : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), |
311 | [fn] "r" (p->ainsn.insn_fn) | 298 | [fn] "r" (asi->insn_fn) |
312 | : "lr", "memory", "cc" | 299 | : "lr", "memory", "cc" |
313 | ); | 300 | ); |
314 | 301 | ||
315 | regs->uregs[rdlo] = rdlov; | 302 | regs->uregs[rdlo] = rdlov; |
316 | regs->uregs[rdhi] = rdhiv; | 303 | regs->uregs[rdhi] = rdhiv; |
317 | } | 304 | } |
318 | 305 | /* t16 thumb actions */ | |
319 | /* These emulation encodings are functionally equivalent... */ | ||
320 | #define t32_emulate_rd8rn16rm0ra12_noflags \ | ||
321 | t32_emulate_rdlo12rdhi8rn16rm0_noflags | ||
322 | |||
323 | static const union decode_item t32_table_1110_100x_x0xx[] = { | ||
324 | /* Load/store multiple instructions */ | ||
325 | |||
326 | /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */ | ||
327 | DECODE_REJECT (0xfe4f0000, 0xe80f0000), | ||
328 | |||
329 | /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */ | ||
330 | /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */ | ||
331 | DECODE_REJECT (0xffc00000, 0xe8000000), | ||
332 | /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */ | ||
333 | /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */ | ||
334 | DECODE_REJECT (0xffc00000, 0xe9800000), | ||
335 | |||
336 | /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */ | ||
337 | DECODE_REJECT (0xfe508000, 0xe8008000), | ||
338 | /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */ | ||
339 | DECODE_REJECT (0xfe50c000, 0xe810c000), | ||
340 | /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */ | ||
341 | DECODE_REJECT (0xfe402000, 0xe8002000), | ||
342 | |||
343 | /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */ | ||
344 | /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */ | ||
345 | /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */ | ||
346 | /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */ | ||
347 | DECODE_CUSTOM (0xfe400000, 0xe8000000, t32_decode_ldmstm), | ||
348 | |||
349 | DECODE_END | ||
350 | }; | ||
351 | |||
352 | static const union decode_item t32_table_1110_100x_x1xx[] = { | ||
353 | /* Load/store dual, load/store exclusive, table branch */ | ||
354 | |||
355 | /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */ | ||
356 | /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */ | ||
357 | DECODE_OR (0xff600000, 0xe8600000), | ||
358 | /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
359 | /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
360 | DECODE_EMULATEX (0xff400000, 0xe9400000, t32_emulate_ldrdstrd, | ||
361 | REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)), | ||
362 | |||
363 | /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */ | ||
364 | /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */ | ||
365 | DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, t32_simulate_table_branch, | ||
366 | REGS(NOSP, 0, 0, 0, NOSPPC)), | ||
367 | |||
368 | /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
369 | /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
370 | /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */ | ||
371 | /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */ | ||
372 | /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */ | ||
373 | /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */ | ||
374 | /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */ | ||
375 | /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */ | ||
376 | /* And unallocated instructions... */ | ||
377 | DECODE_END | ||
378 | }; | ||
379 | |||
380 | static const union decode_item t32_table_1110_101x[] = { | ||
381 | /* Data-processing (shifted register) */ | ||
382 | |||
383 | /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */ | ||
384 | /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */ | ||
385 | DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags, | ||
386 | REGS(NOSPPC, 0, 0, 0, NOSPPC)), | ||
387 | |||
388 | /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */ | ||
389 | DECODE_OR (0xfff00f00, 0xeb100f00), | ||
390 | /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */ | ||
391 | DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags, | ||
392 | REGS(NOPC, 0, 0, 0, NOSPPC)), | ||
393 | |||
394 | /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */ | ||
395 | /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */ | ||
396 | DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags, | ||
397 | REGS(0, 0, NOSPPC, 0, NOSPPC)), | ||
398 | |||
399 | /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */ | ||
400 | /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */ | ||
401 | DECODE_REJECT (0xffa00000, 0xeaa00000), | ||
402 | /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */ | ||
403 | DECODE_REJECT (0xffe00000, 0xeb200000), | ||
404 | /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */ | ||
405 | DECODE_REJECT (0xffe00000, 0xeb800000), | ||
406 | /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */ | ||
407 | DECODE_REJECT (0xffe00000, 0xebe00000), | ||
408 | |||
409 | /* ADD/SUB SP, SP, Rm, LSL #0..3 */ | ||
410 | /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */ | ||
411 | DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags, | ||
412 | REGS(SP, 0, SP, 0, NOSPPC)), | ||
413 | |||
414 | /* ADD/SUB SP, SP, Rm, shift */ | ||
415 | /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */ | ||
416 | DECODE_REJECT (0xff4f0f00, 0xeb0d0d00), | ||
417 | |||
418 | /* ADD/SUB Rd, SP, Rm, shift */ | ||
419 | /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */ | ||
420 | DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags, | ||
421 | REGS(SP, 0, NOPC, 0, NOSPPC)), | ||
422 | |||
423 | /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */ | ||
424 | /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */ | ||
425 | /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */ | ||
426 | /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */ | ||
427 | /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */ | ||
428 | /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */ | ||
429 | /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */ | ||
430 | /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */ | ||
431 | /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */ | ||
432 | /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */ | ||
433 | /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */ | ||
434 | DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags, | ||
435 | REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), | ||
436 | |||
437 | DECODE_END | ||
438 | }; | ||
439 | |||
440 | static const union decode_item t32_table_1111_0x0x___0[] = { | ||
441 | /* Data-processing (modified immediate) */ | ||
442 | |||
443 | /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */ | ||
444 | /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */ | ||
445 | DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags, | ||
446 | REGS(NOSPPC, 0, 0, 0, 0)), | ||
447 | |||
448 | /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */ | ||
449 | DECODE_OR (0xfbf08f00, 0xf1100f00), | ||
450 | /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */ | ||
451 | DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags, | ||
452 | REGS(NOPC, 0, 0, 0, 0)), | ||
453 | |||
454 | /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */ | ||
455 | /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */ | ||
456 | DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags, | ||
457 | REGS(0, 0, NOSPPC, 0, 0)), | ||
458 | |||
459 | /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */ | ||
460 | DECODE_REJECT (0xfbe08000, 0xf0a00000), | ||
461 | /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */ | ||
462 | /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */ | ||
463 | DECODE_REJECT (0xfbc08000, 0xf0c00000), | ||
464 | /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */ | ||
465 | DECODE_REJECT (0xfbe08000, 0xf1200000), | ||
466 | /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */ | ||
467 | DECODE_REJECT (0xfbe08000, 0xf1800000), | ||
468 | /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */ | ||
469 | DECODE_REJECT (0xfbe08000, 0xf1e00000), | ||
470 | |||
471 | /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */ | ||
472 | /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */ | ||
473 | DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags, | ||
474 | REGS(SP, 0, NOPC, 0, 0)), | ||
475 | |||
476 | /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */ | ||
477 | /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */ | ||
478 | /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */ | ||
479 | /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */ | ||
480 | /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */ | ||
481 | /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */ | ||
482 | /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */ | ||
483 | /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */ | ||
484 | /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */ | ||
485 | /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */ | ||
486 | DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags, | ||
487 | REGS(NOSPPC, 0, NOSPPC, 0, 0)), | ||
488 | |||
489 | DECODE_END | ||
490 | }; | ||
491 | |||
492 | static const union decode_item t32_table_1111_0x1x___0[] = { | ||
493 | /* Data-processing (plain binary immediate) */ | ||
494 | |||
495 | /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */ | ||
496 | DECODE_OR (0xfbff8000, 0xf20f0000), | ||
497 | /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */ | ||
498 | DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags, | ||
499 | REGS(PC, 0, NOSPPC, 0, 0)), | ||
500 | |||
501 | /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */ | ||
502 | DECODE_OR (0xfbff8f00, 0xf20d0d00), | ||
503 | /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */ | ||
504 | DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags, | ||
505 | REGS(SP, 0, SP, 0, 0)), | ||
506 | |||
507 | /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */ | ||
508 | DECODE_OR (0xfbf08000, 0xf2000000), | ||
509 | /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */ | ||
510 | DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags, | ||
511 | REGS(NOPCX, 0, NOSPPC, 0, 0)), | ||
512 | |||
513 | /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */ | ||
514 | /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */ | ||
515 | DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags, | ||
516 | REGS(0, 0, NOSPPC, 0, 0)), | ||
517 | |||
518 | /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */ | ||
519 | /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */ | ||
520 | /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */ | ||
521 | /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */ | ||
522 | DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags, | ||
523 | REGS(NOSPPC, 0, NOSPPC, 0, 0)), | ||
524 | |||
525 | /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */ | ||
526 | /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */ | ||
527 | DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags, | ||
528 | REGS(NOSPPC, 0, NOSPPC, 0, 0)), | ||
529 | |||
530 | /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */ | ||
531 | DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags, | ||
532 | REGS(0, 0, NOSPPC, 0, 0)), | ||
533 | |||
534 | /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */ | ||
535 | DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags, | ||
536 | REGS(NOSPPCX, 0, NOSPPC, 0, 0)), | ||
537 | |||
538 | DECODE_END | ||
539 | }; | ||
540 | |||
541 | static const union decode_item t32_table_1111_0xxx___1[] = { | ||
542 | /* Branches and miscellaneous control */ | ||
543 | |||
544 | /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */ | ||
545 | DECODE_OR (0xfff0d7ff, 0xf3a08001), | ||
546 | /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */ | ||
547 | DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, kprobe_emulate_none), | ||
548 | /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */ | ||
549 | /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */ | ||
550 | /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */ | ||
551 | DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, kprobe_simulate_nop), | ||
552 | |||
553 | /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */ | ||
554 | DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, t32_simulate_mrs, | ||
555 | REGS(0, 0, NOSPPC, 0, 0)), | ||
556 | |||
557 | /* | ||
558 | * Unsupported instructions | ||
559 | * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx | ||
560 | * | ||
561 | * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx | ||
562 | * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx | ||
563 | * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx | ||
564 | * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx | ||
565 | * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx | ||
566 | * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx | ||
567 | * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx | ||
568 | * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx | ||
569 | * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx | ||
570 | * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx | ||
571 | * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx | ||
572 | */ | ||
573 | DECODE_REJECT (0xfb80d000, 0xf3808000), | ||
574 | |||
575 | /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */ | ||
576 | DECODE_CUSTOM (0xf800d000, 0xf0008000, t32_decode_cond_branch), | ||
577 | |||
578 | /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */ | ||
579 | DECODE_OR (0xf800d001, 0xf000c000), | ||
580 | /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */ | ||
581 | /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */ | ||
582 | DECODE_SIMULATE (0xf8009000, 0xf0009000, t32_simulate_branch), | ||
583 | |||
584 | DECODE_END | ||
585 | }; | ||
586 | |||
587 | static const union decode_item t32_table_1111_100x_x0x1__1111[] = { | ||
588 | /* Memory hints */ | ||
589 | |||
590 | /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */ | ||
591 | /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */ | ||
592 | DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, kprobe_simulate_nop), | ||
593 | |||
594 | /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */ | ||
595 | DECODE_OR (0xffd0f000, 0xf890f000), | ||
596 | /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */ | ||
597 | DECODE_OR (0xffd0ff00, 0xf810fc00), | ||
598 | /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */ | ||
599 | DECODE_OR (0xfff0f000, 0xf990f000), | ||
600 | /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */ | ||
601 | DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, kprobe_simulate_nop, | ||
602 | REGS(NOPCX, 0, 0, 0, 0)), | ||
603 | |||
604 | /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */ | ||
605 | DECODE_OR (0xffd0ffc0, 0xf810f000), | ||
606 | /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */ | ||
607 | DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, kprobe_simulate_nop, | ||
608 | REGS(NOPCX, 0, 0, 0, NOSPPC)), | ||
609 | |||
610 | /* Other unallocated instructions... */ | ||
611 | DECODE_END | ||
612 | }; | ||
613 | |||
614 | static const union decode_item t32_table_1111_100x[] = { | ||
615 | /* Store/Load single data item */ | ||
616 | |||
617 | /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */ | ||
618 | DECODE_REJECT (0xfe600000, 0xf8600000), | ||
619 | |||
620 | /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
621 | DECODE_REJECT (0xfff00000, 0xf9500000), | ||
622 | |||
623 | /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */ | ||
624 | DECODE_REJECT (0xfe800d00, 0xf8000800), | ||
625 | |||
626 | /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */ | ||
627 | /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */ | ||
628 | /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */ | ||
629 | /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */ | ||
630 | /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */ | ||
631 | /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */ | ||
632 | /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */ | ||
633 | /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */ | ||
634 | DECODE_REJECT (0xfe800f00, 0xf8000e00), | ||
635 | |||
636 | /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */ | ||
637 | DECODE_REJECT (0xff1f0000, 0xf80f0000), | ||
638 | |||
639 | /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */ | ||
640 | DECODE_REJECT (0xff10f000, 0xf800f000), | ||
641 | |||
642 | /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */ | ||
643 | DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, t32_simulate_ldr_literal, | ||
644 | REGS(PC, ANY, 0, 0, 0)), | ||
645 | |||
646 | /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */ | ||
647 | /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */ | ||
648 | DECODE_OR (0xffe00800, 0xf8400800), | ||
649 | /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */ | ||
650 | /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */ | ||
651 | DECODE_EMULATEX (0xffe00000, 0xf8c00000, t32_emulate_ldrstr, | ||
652 | REGS(NOPCX, ANY, 0, 0, 0)), | ||
653 | |||
654 | /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */ | ||
655 | /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */ | ||
656 | DECODE_EMULATEX (0xffe00fc0, 0xf8400000, t32_emulate_ldrstr, | ||
657 | REGS(NOPCX, ANY, 0, 0, NOSPPC)), | ||
658 | |||
659 | /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */ | ||
660 | /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ | ||
661 | /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ | ||
662 | /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ | ||
663 | DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, | ||
664 | REGS(PC, NOSPPCX, 0, 0, 0)), | ||
665 | |||
666 | /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ | ||
667 | /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */ | ||
668 | /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */ | ||
669 | /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */ | ||
670 | /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */ | ||
671 | /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */ | ||
672 | DECODE_OR (0xfec00800, 0xf8000800), | ||
673 | /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */ | ||
674 | /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */ | ||
675 | /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */ | ||
676 | /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */ | ||
677 | /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */ | ||
678 | /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */ | ||
679 | DECODE_EMULATEX (0xfec00000, 0xf8800000, t32_emulate_ldrstr, | ||
680 | REGS(NOPCX, NOSPPCX, 0, 0, 0)), | ||
681 | |||
682 | /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */ | ||
683 | /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */ | ||
684 | /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */ | ||
685 | /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */ | ||
686 | /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */ | ||
687 | /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */ | ||
688 | DECODE_EMULATEX (0xfe800fc0, 0xf8000000, t32_emulate_ldrstr, | ||
689 | REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)), | ||
690 | |||
691 | /* Other unallocated instructions... */ | ||
692 | DECODE_END | ||
693 | }; | ||
694 | |||
695 | static const union decode_item t32_table_1111_1010___1111[] = { | ||
696 | /* Data-processing (register) */ | ||
697 | |||
698 | /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */ | ||
699 | DECODE_REJECT (0xffe0f080, 0xfa60f080), | ||
700 | |||
701 | /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */ | ||
702 | /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */ | ||
703 | /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */ | ||
704 | /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */ | ||
705 | /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */ | ||
706 | /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */ | ||
707 | DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags, | ||
708 | REGS(0, 0, NOSPPC, 0, NOSPPC)), | ||
709 | |||
710 | |||
711 | /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */ | ||
712 | DECODE_REJECT (0xff80f0b0, 0xfa80f030), | ||
713 | /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */ | ||
714 | DECODE_REJECT (0xffb0f080, 0xfab0f000), | ||
715 | |||
716 | /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */ | ||
717 | /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */ | ||
718 | /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */ | ||
719 | /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */ | ||
720 | /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */ | ||
721 | /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */ | ||
722 | |||
723 | /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */ | ||
724 | /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */ | ||
725 | /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */ | ||
726 | /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */ | ||
727 | /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */ | ||
728 | /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */ | ||
729 | |||
730 | /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */ | ||
731 | /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */ | ||
732 | /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */ | ||
733 | /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */ | ||
734 | /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */ | ||
735 | /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */ | ||
736 | |||
737 | /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */ | ||
738 | /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */ | ||
739 | /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */ | ||
740 | /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */ | ||
741 | /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */ | ||
742 | /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */ | ||
743 | |||
744 | /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */ | ||
745 | /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */ | ||
746 | /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */ | ||
747 | /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */ | ||
748 | /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */ | ||
749 | /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */ | ||
750 | |||
751 | /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */ | ||
752 | /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */ | ||
753 | /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */ | ||
754 | /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */ | ||
755 | /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */ | ||
756 | /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */ | ||
757 | DECODE_OR (0xff80f080, 0xfa80f000), | ||
758 | |||
759 | /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */ | ||
760 | /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */ | ||
761 | /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */ | ||
762 | /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */ | ||
763 | /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */ | ||
764 | /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */ | ||
765 | DECODE_OR (0xff80f080, 0xfa00f080), | ||
766 | |||
767 | /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */ | ||
768 | /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */ | ||
769 | /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */ | ||
770 | /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */ | ||
771 | DECODE_OR (0xfff0f0c0, 0xfa80f080), | ||
772 | |||
773 | /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */ | ||
774 | DECODE_OR (0xfff0f0f0, 0xfaa0f080), | ||
775 | |||
776 | /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */ | ||
777 | /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */ | ||
778 | /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */ | ||
779 | /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */ | ||
780 | DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags, | ||
781 | REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), | ||
782 | |||
783 | /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */ | ||
784 | DECODE_OR (0xfff0f0f0, 0xfab0f080), | ||
785 | |||
786 | /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */ | ||
787 | /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */ | ||
788 | /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */ | ||
789 | /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */ | ||
790 | DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, t32_emulate_rd8rn16_noflags, | ||
791 | REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)), | ||
792 | |||
793 | /* Other unallocated instructions... */ | ||
794 | DECODE_END | ||
795 | }; | ||
796 | |||
797 | static const union decode_item t32_table_1111_1011_0[] = { | ||
798 | /* Multiply, multiply accumulate, and absolute difference */ | ||
799 | |||
800 | /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */ | ||
801 | DECODE_REJECT (0xfff0f0f0, 0xfb00f010), | ||
802 | /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */ | ||
803 | DECODE_REJECT (0xfff0f0f0, 0xfb70f010), | ||
804 | |||
805 | /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */ | ||
806 | DECODE_OR (0xfff0f0c0, 0xfb10f000), | ||
807 | /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */ | ||
808 | /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */ | ||
809 | /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */ | ||
810 | /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */ | ||
811 | /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */ | ||
812 | /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */ | ||
813 | DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags, | ||
814 | REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), | ||
815 | |||
816 | /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */ | ||
817 | DECODE_REJECT (0xfff000f0, 0xfb700010), | ||
818 | |||
819 | /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */ | ||
820 | DECODE_OR (0xfff000c0, 0xfb100000), | ||
821 | /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */ | ||
822 | /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */ | ||
823 | /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */ | ||
824 | /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */ | ||
825 | /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */ | ||
826 | /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */ | ||
827 | /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */ | ||
828 | /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */ | ||
829 | DECODE_EMULATEX (0xff8000c0, 0xfb000000, t32_emulate_rd8rn16rm0ra12_noflags, | ||
830 | REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)), | ||
831 | |||
832 | /* Other unallocated instructions... */ | ||
833 | DECODE_END | ||
834 | }; | ||
835 | |||
836 | static const union decode_item t32_table_1111_1011_1[] = { | ||
837 | /* Long multiply, long multiply accumulate, and divide */ | ||
838 | |||
839 | /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */ | ||
840 | DECODE_OR (0xfff000f0, 0xfbe00060), | ||
841 | /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */ | ||
842 | DECODE_OR (0xfff000c0, 0xfbc00080), | ||
843 | /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */ | ||
844 | /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */ | ||
845 | DECODE_OR (0xffe000e0, 0xfbc000c0), | ||
846 | /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */ | ||
847 | /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */ | ||
848 | /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */ | ||
849 | /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */ | ||
850 | DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags, | ||
851 | REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)), | ||
852 | |||
853 | /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */ | ||
854 | /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */ | ||
855 | /* Other unallocated instructions... */ | ||
856 | DECODE_END | ||
857 | }; | ||
858 | |||
859 | const union decode_item kprobe_decode_thumb32_table[] = { | ||
860 | |||
861 | /* | ||
862 | * Load/store multiple instructions | ||
863 | * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx | ||
864 | */ | ||
865 | DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx), | ||
866 | |||
867 | /* | ||
868 | * Load/store dual, load/store exclusive, table branch | ||
869 | * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx | ||
870 | */ | ||
871 | DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx), | ||
872 | |||
873 | /* | ||
874 | * Data-processing (shifted register) | ||
875 | * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx | ||
876 | */ | ||
877 | DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x), | ||
878 | |||
879 | /* | ||
880 | * Coprocessor instructions | ||
881 | * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx | ||
882 | */ | ||
883 | DECODE_REJECT (0xfc000000, 0xec000000), | ||
884 | |||
885 | /* | ||
886 | * Data-processing (modified immediate) | ||
887 | * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx | ||
888 | */ | ||
889 | DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0), | ||
890 | |||
891 | /* | ||
892 | * Data-processing (plain binary immediate) | ||
893 | * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx | ||
894 | */ | ||
895 | DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0), | ||
896 | |||
897 | /* | ||
898 | * Branches and miscellaneous control | ||
899 | * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx | ||
900 | */ | ||
901 | DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1), | ||
902 | |||
903 | /* | ||
904 | * Advanced SIMD element or structure load/store instructions | ||
905 | * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx | ||
906 | */ | ||
907 | DECODE_REJECT (0xff100000, 0xf9000000), | ||
908 | |||
909 | /* | ||
910 | * Memory hints | ||
911 | * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx | ||
912 | */ | ||
913 | DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111), | ||
914 | |||
915 | /* | ||
916 | * Store single data item | ||
917 | * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx | ||
918 | * Load single data items | ||
919 | * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx | ||
920 | */ | ||
921 | DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x), | ||
922 | |||
923 | /* | ||
924 | * Data-processing (register) | ||
925 | * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx | ||
926 | */ | ||
927 | DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111), | ||
928 | |||
929 | /* | ||
930 | * Multiply, multiply accumulate, and absolute difference | ||
931 | * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx | ||
932 | */ | ||
933 | DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0), | ||
934 | |||
935 | /* | ||
936 | * Long multiply, long multiply accumulate, and divide | ||
937 | * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx | ||
938 | */ | ||
939 | DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1), | ||
940 | |||
941 | /* | ||
942 | * Coprocessor instructions | ||
943 | * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx | ||
944 | */ | ||
945 | DECODE_END | ||
946 | }; | ||
947 | #ifdef CONFIG_ARM_KPROBES_TEST_MODULE | ||
948 | EXPORT_SYMBOL_GPL(kprobe_decode_thumb32_table); | ||
949 | #endif | ||
950 | 306 | ||
951 | static void __kprobes | 307 | static void __kprobes |
952 | t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) | 308 | t16_simulate_bxblx(probes_opcode_t insn, |
309 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
953 | { | 310 | { |
954 | kprobe_opcode_t insn = p->opcode; | 311 | unsigned long pc = regs->ARM_pc + 2; |
955 | unsigned long pc = thumb_probe_pc(p); | ||
956 | int rm = (insn >> 3) & 0xf; | 312 | int rm = (insn >> 3) & 0xf; |
957 | unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm]; | 313 | unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm]; |
958 | 314 | ||
959 | if (insn & (1 << 7)) /* BLX ? */ | 315 | if (insn & (1 << 7)) /* BLX ? */ |
960 | regs->ARM_lr = (unsigned long)p->addr + 2; | 316 | regs->ARM_lr = regs->ARM_pc | 1; |
961 | 317 | ||
962 | bx_write_pc(rmv, regs); | 318 | bx_write_pc(rmv, regs); |
963 | } | 319 | } |
964 | 320 | ||
965 | static void __kprobes | 321 | static void __kprobes |
966 | t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) | 322 | t16_simulate_ldr_literal(probes_opcode_t insn, |
323 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
967 | { | 324 | { |
968 | kprobe_opcode_t insn = p->opcode; | 325 | unsigned long *base = (unsigned long *)((regs->ARM_pc + 2) & ~3); |
969 | unsigned long* base = (unsigned long *)(thumb_probe_pc(p) & ~3); | ||
970 | long index = insn & 0xff; | 326 | long index = insn & 0xff; |
971 | int rt = (insn >> 8) & 0x7; | 327 | int rt = (insn >> 8) & 0x7; |
972 | regs->uregs[rt] = base[index]; | 328 | regs->uregs[rt] = base[index]; |
973 | } | 329 | } |
974 | 330 | ||
975 | static void __kprobes | 331 | static void __kprobes |
976 | t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) | 332 | t16_simulate_ldrstr_sp_relative(probes_opcode_t insn, |
333 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
977 | { | 334 | { |
978 | kprobe_opcode_t insn = p->opcode; | ||
979 | unsigned long* base = (unsigned long *)regs->ARM_sp; | 335 | unsigned long* base = (unsigned long *)regs->ARM_sp; |
980 | long index = insn & 0xff; | 336 | long index = insn & 0xff; |
981 | int rt = (insn >> 8) & 0x7; | 337 | int rt = (insn >> 8) & 0x7; |
@@ -986,20 +342,20 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) | |||
986 | } | 342 | } |
987 | 343 | ||
988 | static void __kprobes | 344 | static void __kprobes |
989 | t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs) | 345 | t16_simulate_reladr(probes_opcode_t insn, |
346 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
990 | { | 347 | { |
991 | kprobe_opcode_t insn = p->opcode; | ||
992 | unsigned long base = (insn & 0x800) ? regs->ARM_sp | 348 | unsigned long base = (insn & 0x800) ? regs->ARM_sp |
993 | : (thumb_probe_pc(p) & ~3); | 349 | : ((regs->ARM_pc + 2) & ~3); |
994 | long offset = insn & 0xff; | 350 | long offset = insn & 0xff; |
995 | int rt = (insn >> 8) & 0x7; | 351 | int rt = (insn >> 8) & 0x7; |
996 | regs->uregs[rt] = base + offset * 4; | 352 | regs->uregs[rt] = base + offset * 4; |
997 | } | 353 | } |
998 | 354 | ||
999 | static void __kprobes | 355 | static void __kprobes |
1000 | t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) | 356 | t16_simulate_add_sp_imm(probes_opcode_t insn, |
357 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1001 | { | 358 | { |
1002 | kprobe_opcode_t insn = p->opcode; | ||
1003 | long imm = insn & 0x7f; | 359 | long imm = insn & 0x7f; |
1004 | if (insn & 0x80) /* SUB */ | 360 | if (insn & 0x80) /* SUB */ |
1005 | regs->ARM_sp -= imm * 4; | 361 | regs->ARM_sp -= imm * 4; |
@@ -1008,21 +364,22 @@ t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) | |||
1008 | } | 364 | } |
1009 | 365 | ||
1010 | static void __kprobes | 366 | static void __kprobes |
1011 | t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs) | 367 | t16_simulate_cbz(probes_opcode_t insn, |
368 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1012 | { | 369 | { |
1013 | kprobe_opcode_t insn = p->opcode; | ||
1014 | int rn = insn & 0x7; | 370 | int rn = insn & 0x7; |
1015 | kprobe_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn; | 371 | probes_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn; |
1016 | if (nonzero & 0x800) { | 372 | if (nonzero & 0x800) { |
1017 | long i = insn & 0x200; | 373 | long i = insn & 0x200; |
1018 | long imm5 = insn & 0xf8; | 374 | long imm5 = insn & 0xf8; |
1019 | unsigned long pc = thumb_probe_pc(p); | 375 | unsigned long pc = regs->ARM_pc + 2; |
1020 | regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2); | 376 | regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2); |
1021 | } | 377 | } |
1022 | } | 378 | } |
1023 | 379 | ||
1024 | static void __kprobes | 380 | static void __kprobes |
1025 | t16_simulate_it(struct kprobe *p, struct pt_regs *regs) | 381 | t16_simulate_it(probes_opcode_t insn, |
382 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1026 | { | 383 | { |
1027 | /* | 384 | /* |
1028 | * The 8 IT state bits are split into two parts in CPSR: | 385 | * The 8 IT state bits are split into two parts in CPSR: |
@@ -1030,7 +387,6 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs) | |||
1030 | * ITSTATE<7:2> are in CPSR<15:10> | 387 | * ITSTATE<7:2> are in CPSR<15:10> |
1031 | * The new IT state is in the lower byte of insn. | 388 | * The new IT state is in the lower byte of insn. |
1032 | */ | 389 | */ |
1033 | kprobe_opcode_t insn = p->opcode; | ||
1034 | unsigned long cpsr = regs->ARM_cpsr; | 390 | unsigned long cpsr = regs->ARM_cpsr; |
1035 | cpsr &= ~PSR_IT_MASK; | 391 | cpsr &= ~PSR_IT_MASK; |
1036 | cpsr |= (insn & 0xfc) << 8; | 392 | cpsr |= (insn & 0xfc) << 8; |
@@ -1039,50 +395,54 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs) | |||
1039 | } | 395 | } |
1040 | 396 | ||
1041 | static void __kprobes | 397 | static void __kprobes |
1042 | t16_singlestep_it(struct kprobe *p, struct pt_regs *regs) | 398 | t16_singlestep_it(probes_opcode_t insn, |
399 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1043 | { | 400 | { |
1044 | regs->ARM_pc += 2; | 401 | regs->ARM_pc += 2; |
1045 | t16_simulate_it(p, regs); | 402 | t16_simulate_it(insn, asi, regs); |
1046 | } | 403 | } |
1047 | 404 | ||
1048 | static enum kprobe_insn __kprobes | 405 | static enum probes_insn __kprobes |
1049 | t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 406 | t16_decode_it(probes_opcode_t insn, struct arch_probes_insn *asi, |
407 | const struct decode_header *d) | ||
1050 | { | 408 | { |
1051 | asi->insn_singlestep = t16_singlestep_it; | 409 | asi->insn_singlestep = t16_singlestep_it; |
1052 | return INSN_GOOD_NO_SLOT; | 410 | return INSN_GOOD_NO_SLOT; |
1053 | } | 411 | } |
1054 | 412 | ||
1055 | static void __kprobes | 413 | static void __kprobes |
1056 | t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) | 414 | t16_simulate_cond_branch(probes_opcode_t insn, |
415 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1057 | { | 416 | { |
1058 | kprobe_opcode_t insn = p->opcode; | 417 | unsigned long pc = regs->ARM_pc + 2; |
1059 | unsigned long pc = thumb_probe_pc(p); | ||
1060 | long offset = insn & 0x7f; | 418 | long offset = insn & 0x7f; |
1061 | offset -= insn & 0x80; /* Apply sign bit */ | 419 | offset -= insn & 0x80; /* Apply sign bit */ |
1062 | regs->ARM_pc = pc + (offset * 2); | 420 | regs->ARM_pc = pc + (offset * 2); |
1063 | } | 421 | } |
1064 | 422 | ||
1065 | static enum kprobe_insn __kprobes | 423 | static enum probes_insn __kprobes |
1066 | t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 424 | t16_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi, |
425 | const struct decode_header *d) | ||
1067 | { | 426 | { |
1068 | int cc = (insn >> 8) & 0xf; | 427 | int cc = (insn >> 8) & 0xf; |
1069 | asi->insn_check_cc = kprobe_condition_checks[cc]; | 428 | asi->insn_check_cc = probes_condition_checks[cc]; |
1070 | asi->insn_handler = t16_simulate_cond_branch; | 429 | asi->insn_handler = t16_simulate_cond_branch; |
1071 | return INSN_GOOD_NO_SLOT; | 430 | return INSN_GOOD_NO_SLOT; |
1072 | } | 431 | } |
1073 | 432 | ||
1074 | static void __kprobes | 433 | static void __kprobes |
1075 | t16_simulate_branch(struct kprobe *p, struct pt_regs *regs) | 434 | t16_simulate_branch(probes_opcode_t insn, |
435 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1076 | { | 436 | { |
1077 | kprobe_opcode_t insn = p->opcode; | 437 | unsigned long pc = regs->ARM_pc + 2; |
1078 | unsigned long pc = thumb_probe_pc(p); | ||
1079 | long offset = insn & 0x3ff; | 438 | long offset = insn & 0x3ff; |
1080 | offset -= insn & 0x400; /* Apply sign bit */ | 439 | offset -= insn & 0x400; /* Apply sign bit */ |
1081 | regs->ARM_pc = pc + (offset * 2); | 440 | regs->ARM_pc = pc + (offset * 2); |
1082 | } | 441 | } |
1083 | 442 | ||
1084 | static unsigned long __kprobes | 443 | static unsigned long __kprobes |
1085 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) | 444 | t16_emulate_loregs(probes_opcode_t insn, |
445 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1086 | { | 446 | { |
1087 | unsigned long oldcpsr = regs->ARM_cpsr; | 447 | unsigned long oldcpsr = regs->ARM_cpsr; |
1088 | unsigned long newcpsr; | 448 | unsigned long newcpsr; |
@@ -1095,7 +455,7 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) | |||
1095 | "mrs %[newcpsr], cpsr \n\t" | 455 | "mrs %[newcpsr], cpsr \n\t" |
1096 | : [newcpsr] "=r" (newcpsr) | 456 | : [newcpsr] "=r" (newcpsr) |
1097 | : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs), | 457 | : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs), |
1098 | [fn] "r" (p->ainsn.insn_fn) | 458 | [fn] "r" (asi->insn_fn) |
1099 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | 459 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
1100 | "lr", "memory", "cc" | 460 | "lr", "memory", "cc" |
1101 | ); | 461 | ); |
@@ -1104,24 +464,26 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) | |||
1104 | } | 464 | } |
1105 | 465 | ||
1106 | static void __kprobes | 466 | static void __kprobes |
1107 | t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs) | 467 | t16_emulate_loregs_rwflags(probes_opcode_t insn, |
468 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1108 | { | 469 | { |
1109 | regs->ARM_cpsr = t16_emulate_loregs(p, regs); | 470 | regs->ARM_cpsr = t16_emulate_loregs(insn, asi, regs); |
1110 | } | 471 | } |
1111 | 472 | ||
1112 | static void __kprobes | 473 | static void __kprobes |
1113 | t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs) | 474 | t16_emulate_loregs_noitrwflags(probes_opcode_t insn, |
475 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1114 | { | 476 | { |
1115 | unsigned long cpsr = t16_emulate_loregs(p, regs); | 477 | unsigned long cpsr = t16_emulate_loregs(insn, asi, regs); |
1116 | if (!in_it_block(cpsr)) | 478 | if (!in_it_block(cpsr)) |
1117 | regs->ARM_cpsr = cpsr; | 479 | regs->ARM_cpsr = cpsr; |
1118 | } | 480 | } |
1119 | 481 | ||
1120 | static void __kprobes | 482 | static void __kprobes |
1121 | t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) | 483 | t16_emulate_hiregs(probes_opcode_t insn, |
484 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1122 | { | 485 | { |
1123 | kprobe_opcode_t insn = p->opcode; | 486 | unsigned long pc = regs->ARM_pc + 2; |
1124 | unsigned long pc = thumb_probe_pc(p); | ||
1125 | int rdn = (insn & 0x7) | ((insn & 0x80) >> 4); | 487 | int rdn = (insn & 0x7) | ((insn & 0x80) >> 4); |
1126 | int rm = (insn >> 3) & 0xf; | 488 | int rm = (insn >> 3) & 0xf; |
1127 | 489 | ||
@@ -1137,7 +499,7 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) | |||
1137 | "blx %[fn] \n\t" | 499 | "blx %[fn] \n\t" |
1138 | "mrs %[cpsr], cpsr \n\t" | 500 | "mrs %[cpsr], cpsr \n\t" |
1139 | : "=r" (rdnv), [cpsr] "=r" (cpsr) | 501 | : "=r" (rdnv), [cpsr] "=r" (cpsr) |
1140 | : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) | 502 | : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (asi->insn_fn) |
1141 | : "lr", "memory", "cc" | 503 | : "lr", "memory", "cc" |
1142 | ); | 504 | ); |
1143 | 505 | ||
@@ -1148,8 +510,9 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) | |||
1148 | regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); | 510 | regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); |
1149 | } | 511 | } |
1150 | 512 | ||
1151 | static enum kprobe_insn __kprobes | 513 | static enum probes_insn __kprobes |
1152 | t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 514 | t16_decode_hiregs(probes_opcode_t insn, struct arch_probes_insn *asi, |
515 | const struct decode_header *d) | ||
1153 | { | 516 | { |
1154 | insn &= ~0x00ff; | 517 | insn &= ~0x00ff; |
1155 | insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */ | 518 | insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */ |
@@ -1159,7 +522,8 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
1159 | } | 522 | } |
1160 | 523 | ||
1161 | static void __kprobes | 524 | static void __kprobes |
1162 | t16_emulate_push(struct kprobe *p, struct pt_regs *regs) | 525 | t16_emulate_push(probes_opcode_t insn, |
526 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1163 | { | 527 | { |
1164 | __asm__ __volatile__ ( | 528 | __asm__ __volatile__ ( |
1165 | "ldr r9, [%[regs], #13*4] \n\t" | 529 | "ldr r9, [%[regs], #13*4] \n\t" |
@@ -1168,14 +532,15 @@ t16_emulate_push(struct kprobe *p, struct pt_regs *regs) | |||
1168 | "blx %[fn] \n\t" | 532 | "blx %[fn] \n\t" |
1169 | "str r9, [%[regs], #13*4] \n\t" | 533 | "str r9, [%[regs], #13*4] \n\t" |
1170 | : | 534 | : |
1171 | : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) | 535 | : [regs] "r" (regs), [fn] "r" (asi->insn_fn) |
1172 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", | 536 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", |
1173 | "lr", "memory", "cc" | 537 | "lr", "memory", "cc" |
1174 | ); | 538 | ); |
1175 | } | 539 | } |
1176 | 540 | ||
1177 | static enum kprobe_insn __kprobes | 541 | static enum probes_insn __kprobes |
1178 | t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 542 | t16_decode_push(probes_opcode_t insn, struct arch_probes_insn *asi, |
543 | const struct decode_header *d) | ||
1179 | { | 544 | { |
1180 | /* | 545 | /* |
1181 | * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}" | 546 | * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}" |
@@ -1189,7 +554,8 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
1189 | } | 554 | } |
1190 | 555 | ||
1191 | static void __kprobes | 556 | static void __kprobes |
1192 | t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs) | 557 | t16_emulate_pop_nopc(probes_opcode_t insn, |
558 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1193 | { | 559 | { |
1194 | __asm__ __volatile__ ( | 560 | __asm__ __volatile__ ( |
1195 | "ldr r9, [%[regs], #13*4] \n\t" | 561 | "ldr r9, [%[regs], #13*4] \n\t" |
@@ -1198,14 +564,15 @@ t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs) | |||
1198 | "stmia %[regs], {r0-r7} \n\t" | 564 | "stmia %[regs], {r0-r7} \n\t" |
1199 | "str r9, [%[regs], #13*4] \n\t" | 565 | "str r9, [%[regs], #13*4] \n\t" |
1200 | : | 566 | : |
1201 | : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) | 567 | : [regs] "r" (regs), [fn] "r" (asi->insn_fn) |
1202 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", | 568 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", |
1203 | "lr", "memory", "cc" | 569 | "lr", "memory", "cc" |
1204 | ); | 570 | ); |
1205 | } | 571 | } |
1206 | 572 | ||
1207 | static void __kprobes | 573 | static void __kprobes |
1208 | t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) | 574 | t16_emulate_pop_pc(probes_opcode_t insn, |
575 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
1209 | { | 576 | { |
1210 | register unsigned long pc asm("r8"); | 577 | register unsigned long pc asm("r8"); |
1211 | 578 | ||
@@ -1216,7 +583,7 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) | |||
1216 | "stmia %[regs], {r0-r7} \n\t" | 583 | "stmia %[regs], {r0-r7} \n\t" |
1217 | "str r9, [%[regs], #13*4] \n\t" | 584 | "str r9, [%[regs], #13*4] \n\t" |
1218 | : "=r" (pc) | 585 | : "=r" (pc) |
1219 | : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) | 586 | : [regs] "r" (regs), [fn] "r" (asi->insn_fn) |
1220 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", | 587 | : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", |
1221 | "lr", "memory", "cc" | 588 | "lr", "memory", "cc" |
1222 | ); | 589 | ); |
@@ -1224,8 +591,9 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) | |||
1224 | bx_write_pc(pc, regs); | 591 | bx_write_pc(pc, regs); |
1225 | } | 592 | } |
1226 | 593 | ||
1227 | static enum kprobe_insn __kprobes | 594 | static enum probes_insn __kprobes |
1228 | t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) | 595 | t16_decode_pop(probes_opcode_t insn, struct arch_probes_insn *asi, |
596 | const struct decode_header *d) | ||
1229 | { | 597 | { |
1230 | /* | 598 | /* |
1231 | * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}" | 599 | * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}" |
@@ -1239,231 +607,56 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
1239 | return INSN_GOOD; | 607 | return INSN_GOOD; |
1240 | } | 608 | } |
1241 | 609 | ||
1242 | static const union decode_item t16_table_1011[] = { | 610 | const union decode_action kprobes_t16_actions[NUM_PROBES_T16_ACTIONS] = { |
1243 | /* Miscellaneous 16-bit instructions */ | 611 | [PROBES_T16_ADD_SP] = {.handler = t16_simulate_add_sp_imm}, |
1244 | 612 | [PROBES_T16_CBZ] = {.handler = t16_simulate_cbz}, | |
1245 | /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */ | 613 | [PROBES_T16_SIGN_EXTEND] = {.handler = t16_emulate_loregs_rwflags}, |
1246 | /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */ | 614 | [PROBES_T16_PUSH] = {.decoder = t16_decode_push}, |
1247 | DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm), | 615 | [PROBES_T16_POP] = {.decoder = t16_decode_pop}, |
1248 | 616 | [PROBES_T16_SEV] = {.handler = probes_emulate_none}, | |
1249 | /* CBZ 1011 00x1 xxxx xxxx */ | 617 | [PROBES_T16_WFE] = {.handler = probes_simulate_nop}, |
1250 | /* CBNZ 1011 10x1 xxxx xxxx */ | 618 | [PROBES_T16_IT] = {.decoder = t16_decode_it}, |
1251 | DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz), | 619 | [PROBES_T16_CMP] = {.handler = t16_emulate_loregs_rwflags}, |
1252 | 620 | [PROBES_T16_ADDSUB] = {.handler = t16_emulate_loregs_noitrwflags}, | |
1253 | /* SXTH 1011 0010 00xx xxxx */ | 621 | [PROBES_T16_LOGICAL] = {.handler = t16_emulate_loregs_noitrwflags}, |
1254 | /* SXTB 1011 0010 01xx xxxx */ | 622 | [PROBES_T16_LDR_LIT] = {.handler = t16_simulate_ldr_literal}, |
1255 | /* UXTH 1011 0010 10xx xxxx */ | 623 | [PROBES_T16_BLX] = {.handler = t16_simulate_bxblx}, |
1256 | /* UXTB 1011 0010 11xx xxxx */ | 624 | [PROBES_T16_HIREGOPS] = {.decoder = t16_decode_hiregs}, |
1257 | /* REV 1011 1010 00xx xxxx */ | 625 | [PROBES_T16_LDRHSTRH] = {.handler = t16_emulate_loregs_rwflags}, |
1258 | /* REV16 1011 1010 01xx xxxx */ | 626 | [PROBES_T16_LDRSTR] = {.handler = t16_simulate_ldrstr_sp_relative}, |
1259 | /* ??? 1011 1010 10xx xxxx */ | 627 | [PROBES_T16_ADR] = {.handler = t16_simulate_reladr}, |
1260 | /* REVSH 1011 1010 11xx xxxx */ | 628 | [PROBES_T16_LDMSTM] = {.handler = t16_emulate_loregs_rwflags}, |
1261 | DECODE_REJECT (0xffc0, 0xba80), | 629 | [PROBES_T16_BRANCH_COND] = {.decoder = t16_decode_cond_branch}, |
1262 | DECODE_EMULATE (0xf500, 0xb000, t16_emulate_loregs_rwflags), | 630 | [PROBES_T16_BRANCH] = {.handler = t16_simulate_branch}, |
1263 | |||
1264 | /* PUSH 1011 010x xxxx xxxx */ | ||
1265 | DECODE_CUSTOM (0xfe00, 0xb400, t16_decode_push), | ||
1266 | /* POP 1011 110x xxxx xxxx */ | ||
1267 | DECODE_CUSTOM (0xfe00, 0xbc00, t16_decode_pop), | ||
1268 | |||
1269 | /* | ||
1270 | * If-Then, and hints | ||
1271 | * 1011 1111 xxxx xxxx | ||
1272 | */ | ||
1273 | |||
1274 | /* YIELD 1011 1111 0001 0000 */ | ||
1275 | DECODE_OR (0xffff, 0xbf10), | ||
1276 | /* SEV 1011 1111 0100 0000 */ | ||
1277 | DECODE_EMULATE (0xffff, 0xbf40, kprobe_emulate_none), | ||
1278 | /* NOP 1011 1111 0000 0000 */ | ||
1279 | /* WFE 1011 1111 0010 0000 */ | ||
1280 | /* WFI 1011 1111 0011 0000 */ | ||
1281 | DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop), | ||
1282 | /* Unassigned hints 1011 1111 xxxx 0000 */ | ||
1283 | DECODE_REJECT (0xff0f, 0xbf00), | ||
1284 | /* IT 1011 1111 xxxx xxxx */ | ||
1285 | DECODE_CUSTOM (0xff00, 0xbf00, t16_decode_it), | ||
1286 | |||
1287 | /* SETEND 1011 0110 010x xxxx */ | ||
1288 | /* CPS 1011 0110 011x xxxx */ | ||
1289 | /* BKPT 1011 1110 xxxx xxxx */ | ||
1290 | /* And unallocated instructions... */ | ||
1291 | DECODE_END | ||
1292 | }; | 631 | }; |
1293 | 632 | ||
1294 | const union decode_item kprobe_decode_thumb16_table[] = { | 633 | const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = { |
1295 | 634 | [PROBES_T32_LDMSTM] = {.decoder = t32_decode_ldmstm}, | |
1296 | /* | 635 | [PROBES_T32_LDRDSTRD] = {.handler = t32_emulate_ldrdstrd}, |
1297 | * Shift (immediate), add, subtract, move, and compare | 636 | [PROBES_T32_TABLE_BRANCH] = {.handler = t32_simulate_table_branch}, |
1298 | * 00xx xxxx xxxx xxxx | 637 | [PROBES_T32_TST] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1299 | */ | 638 | [PROBES_T32_MOV] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1300 | 639 | [PROBES_T32_ADDSUB] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, | |
1301 | /* CMP (immediate) 0010 1xxx xxxx xxxx */ | 640 | [PROBES_T32_LOGICAL] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1302 | DECODE_EMULATE (0xf800, 0x2800, t16_emulate_loregs_rwflags), | 641 | [PROBES_T32_CMP] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1303 | 642 | [PROBES_T32_ADDWSUBW_PC] = {.handler = t32_emulate_rd8pc16_noflags,}, | |
1304 | /* ADD (register) 0001 100x xxxx xxxx */ | 643 | [PROBES_T32_ADDWSUBW] = {.handler = t32_emulate_rd8rn16_noflags}, |
1305 | /* SUB (register) 0001 101x xxxx xxxx */ | 644 | [PROBES_T32_MOVW] = {.handler = t32_emulate_rd8rn16_noflags}, |
1306 | /* LSL (immediate) 0000 0xxx xxxx xxxx */ | 645 | [PROBES_T32_SAT] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1307 | /* LSR (immediate) 0000 1xxx xxxx xxxx */ | 646 | [PROBES_T32_BITFIELD] = {.handler = t32_emulate_rd8rn16_noflags}, |
1308 | /* ASR (immediate) 0001 0xxx xxxx xxxx */ | 647 | [PROBES_T32_SEV] = {.handler = probes_emulate_none}, |
1309 | /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */ | 648 | [PROBES_T32_WFE] = {.handler = probes_simulate_nop}, |
1310 | /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */ | 649 | [PROBES_T32_MRS] = {.handler = t32_simulate_mrs}, |
1311 | /* MOV (immediate) 0010 0xxx xxxx xxxx */ | 650 | [PROBES_T32_BRANCH_COND] = {.decoder = t32_decode_cond_branch}, |
1312 | /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */ | 651 | [PROBES_T32_BRANCH] = {.handler = t32_simulate_branch}, |
1313 | /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */ | 652 | [PROBES_T32_PLDI] = {.handler = probes_simulate_nop}, |
1314 | DECODE_EMULATE (0xc000, 0x0000, t16_emulate_loregs_noitrwflags), | 653 | [PROBES_T32_LDR_LIT] = {.handler = t32_simulate_ldr_literal}, |
1315 | 654 | [PROBES_T32_LDRSTR] = {.handler = t32_emulate_ldrstr}, | |
1316 | /* | 655 | [PROBES_T32_SIGN_EXTEND] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1317 | * 16-bit Thumb data-processing instructions | 656 | [PROBES_T32_MEDIA] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1318 | * 0100 00xx xxxx xxxx | 657 | [PROBES_T32_REVERSE] = {.handler = t32_emulate_rd8rn16_noflags}, |
1319 | */ | 658 | [PROBES_T32_MUL_ADD] = {.handler = t32_emulate_rd8rn16rm0_rwflags}, |
1320 | 659 | [PROBES_T32_MUL_ADD2] = {.handler = t32_emulate_rd8rn16rm0ra12_noflags}, | |
1321 | /* TST (register) 0100 0010 00xx xxxx */ | 660 | [PROBES_T32_MUL_ADD_LONG] = { |
1322 | DECODE_EMULATE (0xffc0, 0x4200, t16_emulate_loregs_rwflags), | 661 | .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, |
1323 | /* CMP (register) 0100 0010 10xx xxxx */ | ||
1324 | /* CMN (register) 0100 0010 11xx xxxx */ | ||
1325 | DECODE_EMULATE (0xff80, 0x4280, t16_emulate_loregs_rwflags), | ||
1326 | /* AND (register) 0100 0000 00xx xxxx */ | ||
1327 | /* EOR (register) 0100 0000 01xx xxxx */ | ||
1328 | /* LSL (register) 0100 0000 10xx xxxx */ | ||
1329 | /* LSR (register) 0100 0000 11xx xxxx */ | ||
1330 | /* ASR (register) 0100 0001 00xx xxxx */ | ||
1331 | /* ADC (register) 0100 0001 01xx xxxx */ | ||
1332 | /* SBC (register) 0100 0001 10xx xxxx */ | ||
1333 | /* ROR (register) 0100 0001 11xx xxxx */ | ||
1334 | /* RSB (immediate) 0100 0010 01xx xxxx */ | ||
1335 | /* ORR (register) 0100 0011 00xx xxxx */ | ||
1336 | /* MUL 0100 0011 00xx xxxx */ | ||
1337 | /* BIC (register) 0100 0011 10xx xxxx */ | ||
1338 | /* MVN (register) 0100 0011 10xx xxxx */ | ||
1339 | DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags), | ||
1340 | |||
1341 | /* | ||
1342 | * Special data instructions and branch and exchange | ||
1343 | * 0100 01xx xxxx xxxx | ||
1344 | */ | ||
1345 | |||
1346 | /* BLX pc 0100 0111 1111 1xxx */ | ||
1347 | DECODE_REJECT (0xfff8, 0x47f8), | ||
1348 | |||
1349 | /* BX (register) 0100 0111 0xxx xxxx */ | ||
1350 | /* BLX (register) 0100 0111 1xxx xxxx */ | ||
1351 | DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx), | ||
1352 | |||
1353 | /* ADD pc, pc 0100 0100 1111 1111 */ | ||
1354 | DECODE_REJECT (0xffff, 0x44ff), | ||
1355 | |||
1356 | /* ADD (register) 0100 0100 xxxx xxxx */ | ||
1357 | /* CMP (register) 0100 0101 xxxx xxxx */ | ||
1358 | /* MOV (register) 0100 0110 xxxx xxxx */ | ||
1359 | DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs), | ||
1360 | |||
1361 | /* | ||
1362 | * Load from Literal Pool | ||
1363 | * LDR (literal) 0100 1xxx xxxx xxxx | ||
1364 | */ | ||
1365 | DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal), | ||
1366 | |||
1367 | /* | ||
1368 | * 16-bit Thumb Load/store instructions | ||
1369 | * 0101 xxxx xxxx xxxx | ||
1370 | * 011x xxxx xxxx xxxx | ||
1371 | * 100x xxxx xxxx xxxx | ||
1372 | */ | ||
1373 | |||
1374 | /* STR (register) 0101 000x xxxx xxxx */ | ||
1375 | /* STRH (register) 0101 001x xxxx xxxx */ | ||
1376 | /* STRB (register) 0101 010x xxxx xxxx */ | ||
1377 | /* LDRSB (register) 0101 011x xxxx xxxx */ | ||
1378 | /* LDR (register) 0101 100x xxxx xxxx */ | ||
1379 | /* LDRH (register) 0101 101x xxxx xxxx */ | ||
1380 | /* LDRB (register) 0101 110x xxxx xxxx */ | ||
1381 | /* LDRSH (register) 0101 111x xxxx xxxx */ | ||
1382 | /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */ | ||
1383 | /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */ | ||
1384 | /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */ | ||
1385 | /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */ | ||
1386 | DECODE_EMULATE (0xc000, 0x4000, t16_emulate_loregs_rwflags), | ||
1387 | /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */ | ||
1388 | /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */ | ||
1389 | DECODE_EMULATE (0xf000, 0x8000, t16_emulate_loregs_rwflags), | ||
1390 | /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */ | ||
1391 | /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */ | ||
1392 | DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative), | ||
1393 | |||
1394 | /* | ||
1395 | * Generate PC-/SP-relative address | ||
1396 | * ADR (literal) 1010 0xxx xxxx xxxx | ||
1397 | * ADD (SP plus immediate) 1010 1xxx xxxx xxxx | ||
1398 | */ | ||
1399 | DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr), | ||
1400 | |||
1401 | /* | ||
1402 | * Miscellaneous 16-bit instructions | ||
1403 | * 1011 xxxx xxxx xxxx | ||
1404 | */ | ||
1405 | DECODE_TABLE (0xf000, 0xb000, t16_table_1011), | ||
1406 | |||
1407 | /* STM 1100 0xxx xxxx xxxx */ | ||
1408 | /* LDM 1100 1xxx xxxx xxxx */ | ||
1409 | DECODE_EMULATE (0xf000, 0xc000, t16_emulate_loregs_rwflags), | ||
1410 | |||
1411 | /* | ||
1412 | * Conditional branch, and Supervisor Call | ||
1413 | */ | ||
1414 | |||
1415 | /* Permanently UNDEFINED 1101 1110 xxxx xxxx */ | ||
1416 | /* SVC 1101 1111 xxxx xxxx */ | ||
1417 | DECODE_REJECT (0xfe00, 0xde00), | ||
1418 | |||
1419 | /* Conditional branch 1101 xxxx xxxx xxxx */ | ||
1420 | DECODE_CUSTOM (0xf000, 0xd000, t16_decode_cond_branch), | ||
1421 | |||
1422 | /* | ||
1423 | * Unconditional branch | ||
1424 | * B 1110 0xxx xxxx xxxx | ||
1425 | */ | ||
1426 | DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch), | ||
1427 | |||
1428 | DECODE_END | ||
1429 | }; | 662 | }; |
1430 | #ifdef CONFIG_ARM_KPROBES_TEST_MODULE | ||
1431 | EXPORT_SYMBOL_GPL(kprobe_decode_thumb16_table); | ||
1432 | #endif | ||
1433 | |||
1434 | static unsigned long __kprobes thumb_check_cc(unsigned long cpsr) | ||
1435 | { | ||
1436 | if (unlikely(in_it_block(cpsr))) | ||
1437 | return kprobe_condition_checks[current_cond(cpsr)](cpsr); | ||
1438 | return true; | ||
1439 | } | ||
1440 | |||
1441 | static void __kprobes thumb16_singlestep(struct kprobe *p, struct pt_regs *regs) | ||
1442 | { | ||
1443 | regs->ARM_pc += 2; | ||
1444 | p->ainsn.insn_handler(p, regs); | ||
1445 | regs->ARM_cpsr = it_advance(regs->ARM_cpsr); | ||
1446 | } | ||
1447 | |||
1448 | static void __kprobes thumb32_singlestep(struct kprobe *p, struct pt_regs *regs) | ||
1449 | { | ||
1450 | regs->ARM_pc += 4; | ||
1451 | p->ainsn.insn_handler(p, regs); | ||
1452 | regs->ARM_cpsr = it_advance(regs->ARM_cpsr); | ||
1453 | } | ||
1454 | |||
1455 | enum kprobe_insn __kprobes | ||
1456 | thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1457 | { | ||
1458 | asi->insn_singlestep = thumb16_singlestep; | ||
1459 | asi->insn_check_cc = thumb_check_cc; | ||
1460 | return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true); | ||
1461 | } | ||
1462 | |||
1463 | enum kprobe_insn __kprobes | ||
1464 | thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1465 | { | ||
1466 | asi->insn_singlestep = thumb32_singlestep; | ||
1467 | asi->insn_check_cc = thumb_check_cc; | ||
1468 | return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true); | ||
1469 | } | ||
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index a7b621ece23d..8795f9f819d5 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c | |||
@@ -27,8 +27,12 @@ | |||
27 | #include <linux/stringify.h> | 27 | #include <linux/stringify.h> |
28 | #include <asm/traps.h> | 28 | #include <asm/traps.h> |
29 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
30 | #include <linux/percpu.h> | ||
31 | #include <linux/bug.h> | ||
30 | 32 | ||
31 | #include "kprobes.h" | 33 | #include "kprobes.h" |
34 | #include "probes-arm.h" | ||
35 | #include "probes-thumb.h" | ||
32 | #include "patch.h" | 36 | #include "patch.h" |
33 | 37 | ||
34 | #define MIN_STACK_SIZE(addr) \ | 38 | #define MIN_STACK_SIZE(addr) \ |
@@ -54,6 +58,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
54 | unsigned long addr = (unsigned long)p->addr; | 58 | unsigned long addr = (unsigned long)p->addr; |
55 | bool thumb; | 59 | bool thumb; |
56 | kprobe_decode_insn_t *decode_insn; | 60 | kprobe_decode_insn_t *decode_insn; |
61 | const union decode_action *actions; | ||
57 | int is; | 62 | int is; |
58 | 63 | ||
59 | if (in_exception_text(addr)) | 64 | if (in_exception_text(addr)) |
@@ -66,21 +71,25 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
66 | if (is_wide_instruction(insn)) { | 71 | if (is_wide_instruction(insn)) { |
67 | insn <<= 16; | 72 | insn <<= 16; |
68 | insn |= ((u16 *)addr)[1]; | 73 | insn |= ((u16 *)addr)[1]; |
69 | decode_insn = thumb32_kprobe_decode_insn; | 74 | decode_insn = thumb32_probes_decode_insn; |
70 | } else | 75 | actions = kprobes_t32_actions; |
71 | decode_insn = thumb16_kprobe_decode_insn; | 76 | } else { |
77 | decode_insn = thumb16_probes_decode_insn; | ||
78 | actions = kprobes_t16_actions; | ||
79 | } | ||
72 | #else /* !CONFIG_THUMB2_KERNEL */ | 80 | #else /* !CONFIG_THUMB2_KERNEL */ |
73 | thumb = false; | 81 | thumb = false; |
74 | if (addr & 0x3) | 82 | if (addr & 0x3) |
75 | return -EINVAL; | 83 | return -EINVAL; |
76 | insn = *p->addr; | 84 | insn = *p->addr; |
77 | decode_insn = arm_kprobe_decode_insn; | 85 | decode_insn = arm_probes_decode_insn; |
86 | actions = kprobes_arm_actions; | ||
78 | #endif | 87 | #endif |
79 | 88 | ||
80 | p->opcode = insn; | 89 | p->opcode = insn; |
81 | p->ainsn.insn = tmp_insn; | 90 | p->ainsn.insn = tmp_insn; |
82 | 91 | ||
83 | switch ((*decode_insn)(insn, &p->ainsn)) { | 92 | switch ((*decode_insn)(insn, &p->ainsn, true, actions)) { |
84 | case INSN_REJECTED: /* not supported */ | 93 | case INSN_REJECTED: /* not supported */ |
85 | return -EINVAL; | 94 | return -EINVAL; |
86 | 95 | ||
@@ -92,7 +101,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
92 | p->ainsn.insn[is] = tmp_insn[is]; | 101 | p->ainsn.insn[is] = tmp_insn[is]; |
93 | flush_insns(p->ainsn.insn, | 102 | flush_insns(p->ainsn.insn, |
94 | sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE); | 103 | sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE); |
95 | p->ainsn.insn_fn = (kprobe_insn_fn_t *) | 104 | p->ainsn.insn_fn = (probes_insn_fn_t *) |
96 | ((uintptr_t)p->ainsn.insn | thumb); | 105 | ((uintptr_t)p->ainsn.insn | thumb); |
97 | break; | 106 | break; |
98 | 107 | ||
@@ -197,7 +206,7 @@ singlestep_skip(struct kprobe *p, struct pt_regs *regs) | |||
197 | static inline void __kprobes | 206 | static inline void __kprobes |
198 | singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) | 207 | singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) |
199 | { | 208 | { |
200 | p->ainsn.insn_singlestep(p, regs); | 209 | p->ainsn.insn_singlestep(p->opcode, &p->ainsn, regs); |
201 | } | 210 | } |
202 | 211 | ||
203 | /* | 212 | /* |
@@ -607,7 +616,7 @@ static struct undef_hook kprobes_arm_break_hook = { | |||
607 | 616 | ||
608 | int __init arch_init_kprobes() | 617 | int __init arch_init_kprobes() |
609 | { | 618 | { |
610 | arm_kprobe_decode_init(); | 619 | arm_probes_decode_init(); |
611 | #ifdef CONFIG_THUMB2_KERNEL | 620 | #ifdef CONFIG_THUMB2_KERNEL |
612 | register_undef_hook(&kprobes_thumb16_break_hook); | 621 | register_undef_hook(&kprobes_thumb16_break_hook); |
613 | register_undef_hook(&kprobes_thumb32_break_hook); | 622 | register_undef_hook(&kprobes_thumb32_break_hook); |
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h index 38945f78f9f1..9a2712ecefc3 100644 --- a/arch/arm/kernel/kprobes.h +++ b/arch/arm/kernel/kprobes.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef _ARM_KERNEL_KPROBES_H | 19 | #ifndef _ARM_KERNEL_KPROBES_H |
20 | #define _ARM_KERNEL_KPROBES_H | 20 | #define _ARM_KERNEL_KPROBES_H |
21 | 21 | ||
22 | #include "probes.h" | ||
23 | |||
22 | /* | 24 | /* |
23 | * These undefined instructions must be unique and | 25 | * These undefined instructions must be unique and |
24 | * reserved solely for kprobes' use. | 26 | * reserved solely for kprobes' use. |
@@ -27,402 +29,24 @@ | |||
27 | #define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18 | 29 | #define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18 |
28 | #define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 | 30 | #define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 |
29 | 31 | ||
32 | enum probes_insn __kprobes | ||
33 | kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi, | ||
34 | const struct decode_header *h); | ||
30 | 35 | ||
31 | enum kprobe_insn { | 36 | typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t, |
32 | INSN_REJECTED, | 37 | struct arch_probes_insn *, |
33 | INSN_GOOD, | 38 | bool, |
34 | INSN_GOOD_NO_SLOT | 39 | const union decode_action *); |
35 | }; | ||
36 | |||
37 | typedef enum kprobe_insn (kprobe_decode_insn_t)(kprobe_opcode_t, | ||
38 | struct arch_specific_insn *); | ||
39 | 40 | ||
40 | #ifdef CONFIG_THUMB2_KERNEL | 41 | #ifdef CONFIG_THUMB2_KERNEL |
41 | 42 | ||
42 | enum kprobe_insn thumb16_kprobe_decode_insn(kprobe_opcode_t, | 43 | extern const union decode_action kprobes_t32_actions[]; |
43 | struct arch_specific_insn *); | 44 | extern const union decode_action kprobes_t16_actions[]; |
44 | enum kprobe_insn thumb32_kprobe_decode_insn(kprobe_opcode_t, | ||
45 | struct arch_specific_insn *); | ||
46 | 45 | ||
47 | #else /* !CONFIG_THUMB2_KERNEL */ | 46 | #else /* !CONFIG_THUMB2_KERNEL */ |
48 | 47 | ||
49 | enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t, | 48 | extern const union decode_action kprobes_arm_actions[]; |
50 | struct arch_specific_insn *); | ||
51 | #endif | ||
52 | |||
53 | void __init arm_kprobe_decode_init(void); | ||
54 | |||
55 | extern kprobe_check_cc * const kprobe_condition_checks[16]; | ||
56 | |||
57 | |||
58 | #if __LINUX_ARM_ARCH__ >= 7 | ||
59 | |||
60 | /* str_pc_offset is architecturally defined from ARMv7 onwards */ | ||
61 | #define str_pc_offset 8 | ||
62 | #define find_str_pc_offset() | ||
63 | |||
64 | #else /* __LINUX_ARM_ARCH__ < 7 */ | ||
65 | |||
66 | /* We need a run-time check to determine str_pc_offset */ | ||
67 | extern int str_pc_offset; | ||
68 | void __init find_str_pc_offset(void); | ||
69 | 49 | ||
70 | #endif | 50 | #endif |
71 | 51 | ||
72 | |||
73 | /* | ||
74 | * Update ITSTATE after normal execution of an IT block instruction. | ||
75 | * | ||
76 | * The 8 IT state bits are split into two parts in CPSR: | ||
77 | * ITSTATE<1:0> are in CPSR<26:25> | ||
78 | * ITSTATE<7:2> are in CPSR<15:10> | ||
79 | */ | ||
80 | static inline unsigned long it_advance(unsigned long cpsr) | ||
81 | { | ||
82 | if ((cpsr & 0x06000400) == 0) { | ||
83 | /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */ | ||
84 | cpsr &= ~PSR_IT_MASK; | ||
85 | } else { | ||
86 | /* We need to shift left ITSTATE<4:0> */ | ||
87 | const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */ | ||
88 | unsigned long it = cpsr & mask; | ||
89 | it <<= 1; | ||
90 | it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */ | ||
91 | it &= mask; | ||
92 | cpsr &= ~mask; | ||
93 | cpsr |= it; | ||
94 | } | ||
95 | return cpsr; | ||
96 | } | ||
97 | |||
98 | static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs) | ||
99 | { | ||
100 | long cpsr = regs->ARM_cpsr; | ||
101 | if (pcv & 0x1) { | ||
102 | cpsr |= PSR_T_BIT; | ||
103 | pcv &= ~0x1; | ||
104 | } else { | ||
105 | cpsr &= ~PSR_T_BIT; | ||
106 | pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */ | ||
107 | } | ||
108 | regs->ARM_cpsr = cpsr; | ||
109 | regs->ARM_pc = pcv; | ||
110 | } | ||
111 | |||
112 | |||
113 | #if __LINUX_ARM_ARCH__ >= 6 | ||
114 | |||
115 | /* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */ | ||
116 | #define load_write_pc_interworks true | ||
117 | #define test_load_write_pc_interworking() | ||
118 | |||
119 | #else /* __LINUX_ARM_ARCH__ < 6 */ | ||
120 | |||
121 | /* We need run-time testing to determine if load_write_pc() should interwork. */ | ||
122 | extern bool load_write_pc_interworks; | ||
123 | void __init test_load_write_pc_interworking(void); | ||
124 | |||
125 | #endif | ||
126 | |||
127 | static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs) | ||
128 | { | ||
129 | if (load_write_pc_interworks) | ||
130 | bx_write_pc(pcv, regs); | ||
131 | else | ||
132 | regs->ARM_pc = pcv; | ||
133 | } | ||
134 | |||
135 | |||
136 | #if __LINUX_ARM_ARCH__ >= 7 | ||
137 | |||
138 | #define alu_write_pc_interworks true | ||
139 | #define test_alu_write_pc_interworking() | ||
140 | |||
141 | #elif __LINUX_ARM_ARCH__ <= 5 | ||
142 | |||
143 | /* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */ | ||
144 | #define alu_write_pc_interworks false | ||
145 | #define test_alu_write_pc_interworking() | ||
146 | |||
147 | #else /* __LINUX_ARM_ARCH__ == 6 */ | ||
148 | |||
149 | /* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */ | ||
150 | extern bool alu_write_pc_interworks; | ||
151 | void __init test_alu_write_pc_interworking(void); | ||
152 | |||
153 | #endif /* __LINUX_ARM_ARCH__ == 6 */ | ||
154 | |||
155 | static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs) | ||
156 | { | ||
157 | if (alu_write_pc_interworks) | ||
158 | bx_write_pc(pcv, regs); | ||
159 | else | ||
160 | regs->ARM_pc = pcv; | ||
161 | } | ||
162 | |||
163 | |||
164 | void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs); | ||
165 | void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs); | ||
166 | |||
167 | enum kprobe_insn __kprobes | ||
168 | kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi); | ||
169 | |||
170 | /* | ||
171 | * Test if load/store instructions writeback the address register. | ||
172 | * if P (bit 24) == 0 or W (bit 21) == 1 | ||
173 | */ | ||
174 | #define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) | ||
175 | |||
176 | /* | ||
177 | * The following definitions and macros are used to build instruction | ||
178 | * decoding tables for use by kprobe_decode_insn. | ||
179 | * | ||
180 | * These tables are a concatenation of entries each of which consist of one of | ||
181 | * the decode_* structs. All of the fields in every type of decode structure | ||
182 | * are of the union type decode_item, therefore the entire decode table can be | ||
183 | * viewed as an array of these and declared like: | ||
184 | * | ||
185 | * static const union decode_item table_name[] = {}; | ||
186 | * | ||
187 | * In order to construct each entry in the table, macros are used to | ||
188 | * initialise a number of sequential decode_item values in a layout which | ||
189 | * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct | ||
190 | * decode_simulate by initialising four decode_item objects like this... | ||
191 | * | ||
192 | * {.bits = _type}, | ||
193 | * {.bits = _mask}, | ||
194 | * {.bits = _value}, | ||
195 | * {.handler = _handler}, | ||
196 | * | ||
197 | * Initialising a specified member of the union means that the compiler | ||
198 | * will produce a warning if the argument is of an incorrect type. | ||
199 | * | ||
200 | * Below is a list of each of the macros used to initialise entries and a | ||
201 | * description of the action performed when that entry is matched to an | ||
202 | * instruction. A match is found when (instruction & mask) == value. | ||
203 | * | ||
204 | * DECODE_TABLE(mask, value, table) | ||
205 | * Instruction decoding jumps to parsing the new sub-table 'table'. | ||
206 | * | ||
207 | * DECODE_CUSTOM(mask, value, decoder) | ||
208 | * The custom function 'decoder' is called to the complete decoding | ||
209 | * of an instruction. | ||
210 | * | ||
211 | * DECODE_SIMULATE(mask, value, handler) | ||
212 | * Set the probes instruction handler to 'handler', this will be used | ||
213 | * to simulate the instruction when the probe is hit. Decoding returns | ||
214 | * with INSN_GOOD_NO_SLOT. | ||
215 | * | ||
216 | * DECODE_EMULATE(mask, value, handler) | ||
217 | * Set the probes instruction handler to 'handler', this will be used | ||
218 | * to emulate the instruction when the probe is hit. The modified | ||
219 | * instruction (see below) is placed in the probes instruction slot so it | ||
220 | * may be called by the emulation code. Decoding returns with INSN_GOOD. | ||
221 | * | ||
222 | * DECODE_REJECT(mask, value) | ||
223 | * Instruction decoding fails with INSN_REJECTED | ||
224 | * | ||
225 | * DECODE_OR(mask, value) | ||
226 | * This allows the mask/value test of multiple table entries to be | ||
227 | * logically ORed. Once an 'or' entry is matched the decoding action to | ||
228 | * be performed is that of the next entry which isn't an 'or'. E.g. | ||
229 | * | ||
230 | * DECODE_OR (mask1, value1) | ||
231 | * DECODE_OR (mask2, value2) | ||
232 | * DECODE_SIMULATE (mask3, value3, simulation_handler) | ||
233 | * | ||
234 | * This means that if any of the three mask/value pairs match the | ||
235 | * instruction being decoded, then 'simulation_handler' will be used | ||
236 | * for it. | ||
237 | * | ||
238 | * Both the SIMULATE and EMULATE macros have a second form which take an | ||
239 | * additional 'regs' argument. | ||
240 | * | ||
241 | * DECODE_SIMULATEX(mask, value, handler, regs) | ||
242 | * DECODE_EMULATEX (mask, value, handler, regs) | ||
243 | * | ||
244 | * These are used to specify what kind of CPU register is encoded in each of the | ||
245 | * least significant 5 nibbles of the instruction being decoded. The regs value | ||
246 | * is specified using the REGS macro, this takes any of the REG_TYPE_* values | ||
247 | * from enum decode_reg_type as arguments; only the '*' part of the name is | ||
248 | * given. E.g. | ||
249 | * | ||
250 | * REGS(0, ANY, NOPC, 0, ANY) | ||
251 | * | ||
252 | * This indicates an instruction is encoded like: | ||
253 | * | ||
254 | * bits 19..16 ignore | ||
255 | * bits 15..12 any register allowed here | ||
256 | * bits 11.. 8 any register except PC allowed here | ||
257 | * bits 7.. 4 ignore | ||
258 | * bits 3.. 0 any register allowed here | ||
259 | * | ||
260 | * This register specification is checked after a decode table entry is found to | ||
261 | * match an instruction (through the mask/value test). Any invalid register then | ||
262 | * found in the instruction will cause decoding to fail with INSN_REJECTED. In | ||
263 | * the above example this would happen if bits 11..8 of the instruction were | ||
264 | * 1111, indicating R15 or PC. | ||
265 | * | ||
266 | * As well as checking for legal combinations of registers, this data is also | ||
267 | * used to modify the registers encoded in the instructions so that an | ||
268 | * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.) | ||
269 | * | ||
270 | * Here is a real example which matches ARM instructions of the form | ||
271 | * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>" | ||
272 | * | ||
273 | * DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags, | ||
274 | * REGS(ANY, ANY, NOPC, 0, ANY)), | ||
275 | * ^ ^ ^ ^ | ||
276 | * Rn Rd Rs Rm | ||
277 | * | ||
278 | * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because | ||
279 | * Rs == R15 | ||
280 | * | ||
281 | * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the | ||
282 | * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into | ||
283 | * the kprobes instruction slot. This can then be called later by the handler | ||
284 | * function emulate_rd12rn16rm0rs8_rwflags in order to simulate the instruction. | ||
285 | */ | ||
286 | |||
287 | enum decode_type { | ||
288 | DECODE_TYPE_END, | ||
289 | DECODE_TYPE_TABLE, | ||
290 | DECODE_TYPE_CUSTOM, | ||
291 | DECODE_TYPE_SIMULATE, | ||
292 | DECODE_TYPE_EMULATE, | ||
293 | DECODE_TYPE_OR, | ||
294 | DECODE_TYPE_REJECT, | ||
295 | NUM_DECODE_TYPES /* Must be last enum */ | ||
296 | }; | ||
297 | |||
298 | #define DECODE_TYPE_BITS 4 | ||
299 | #define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1) | ||
300 | |||
301 | enum decode_reg_type { | ||
302 | REG_TYPE_NONE = 0, /* Not a register, ignore */ | ||
303 | REG_TYPE_ANY, /* Any register allowed */ | ||
304 | REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */ | ||
305 | REG_TYPE_SP, /* Register must be SP */ | ||
306 | REG_TYPE_PC, /* Register must be PC */ | ||
307 | REG_TYPE_NOSP, /* Register must not be SP */ | ||
308 | REG_TYPE_NOSPPC, /* Register must not be SP or PC */ | ||
309 | REG_TYPE_NOPC, /* Register must not be PC */ | ||
310 | REG_TYPE_NOPCWB, /* No PC if load/store write-back flag also set */ | ||
311 | |||
312 | /* The following types are used when the encoding for PC indicates | ||
313 | * another instruction form. This distiction only matters for test | ||
314 | * case coverage checks. | ||
315 | */ | ||
316 | REG_TYPE_NOPCX, /* Register must not be PC */ | ||
317 | REG_TYPE_NOSPPCX, /* Register must not be SP or PC */ | ||
318 | |||
319 | /* Alias to allow '0' arg to be used in REGS macro. */ | ||
320 | REG_TYPE_0 = REG_TYPE_NONE | ||
321 | }; | ||
322 | |||
323 | #define REGS(r16, r12, r8, r4, r0) \ | ||
324 | ((REG_TYPE_##r16) << 16) + \ | ||
325 | ((REG_TYPE_##r12) << 12) + \ | ||
326 | ((REG_TYPE_##r8) << 8) + \ | ||
327 | ((REG_TYPE_##r4) << 4) + \ | ||
328 | (REG_TYPE_##r0) | ||
329 | |||
330 | union decode_item { | ||
331 | u32 bits; | ||
332 | const union decode_item *table; | ||
333 | kprobe_insn_handler_t *handler; | ||
334 | kprobe_decode_insn_t *decoder; | ||
335 | }; | ||
336 | |||
337 | |||
338 | #define DECODE_END \ | ||
339 | {.bits = DECODE_TYPE_END} | ||
340 | |||
341 | |||
342 | struct decode_header { | ||
343 | union decode_item type_regs; | ||
344 | union decode_item mask; | ||
345 | union decode_item value; | ||
346 | }; | ||
347 | |||
348 | #define DECODE_HEADER(_type, _mask, _value, _regs) \ | ||
349 | {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \ | ||
350 | {.bits = (_mask)}, \ | ||
351 | {.bits = (_value)} | ||
352 | |||
353 | |||
354 | struct decode_table { | ||
355 | struct decode_header header; | ||
356 | union decode_item table; | ||
357 | }; | ||
358 | |||
359 | #define DECODE_TABLE(_mask, _value, _table) \ | ||
360 | DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \ | ||
361 | {.table = (_table)} | ||
362 | |||
363 | |||
364 | struct decode_custom { | ||
365 | struct decode_header header; | ||
366 | union decode_item decoder; | ||
367 | }; | ||
368 | |||
369 | #define DECODE_CUSTOM(_mask, _value, _decoder) \ | ||
370 | DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \ | ||
371 | {.decoder = (_decoder)} | ||
372 | |||
373 | |||
374 | struct decode_simulate { | ||
375 | struct decode_header header; | ||
376 | union decode_item handler; | ||
377 | }; | ||
378 | |||
379 | #define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \ | ||
380 | DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \ | ||
381 | {.handler = (_handler)} | ||
382 | |||
383 | #define DECODE_SIMULATE(_mask, _value, _handler) \ | ||
384 | DECODE_SIMULATEX(_mask, _value, _handler, 0) | ||
385 | |||
386 | |||
387 | struct decode_emulate { | ||
388 | struct decode_header header; | ||
389 | union decode_item handler; | ||
390 | }; | ||
391 | |||
392 | #define DECODE_EMULATEX(_mask, _value, _handler, _regs) \ | ||
393 | DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \ | ||
394 | {.handler = (_handler)} | ||
395 | |||
396 | #define DECODE_EMULATE(_mask, _value, _handler) \ | ||
397 | DECODE_EMULATEX(_mask, _value, _handler, 0) | ||
398 | |||
399 | |||
400 | struct decode_or { | ||
401 | struct decode_header header; | ||
402 | }; | ||
403 | |||
404 | #define DECODE_OR(_mask, _value) \ | ||
405 | DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0) | ||
406 | |||
407 | |||
408 | struct decode_reject { | ||
409 | struct decode_header header; | ||
410 | }; | ||
411 | |||
412 | #define DECODE_REJECT(_mask, _value) \ | ||
413 | DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0) | ||
414 | |||
415 | |||
416 | #ifdef CONFIG_THUMB2_KERNEL | ||
417 | extern const union decode_item kprobe_decode_thumb16_table[]; | ||
418 | extern const union decode_item kprobe_decode_thumb32_table[]; | ||
419 | #else | ||
420 | extern const union decode_item kprobe_decode_arm_table[]; | ||
421 | #endif | ||
422 | |||
423 | |||
424 | int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
425 | const union decode_item *table, bool thumb16); | ||
426 | |||
427 | |||
428 | #endif /* _ARM_KERNEL_KPROBES_H */ | 52 | #endif /* _ARM_KERNEL_KPROBES_H */ |
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/kernel/probes-arm.c new file mode 100644 index 000000000000..51a13a027989 --- /dev/null +++ b/arch/arm/kernel/probes-arm.c | |||
@@ -0,0 +1,734 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/probes-arm.c | ||
3 | * | ||
4 | * Some code moved here from arch/arm/kernel/kprobes-arm.c | ||
5 | * | ||
6 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/stddef.h> | ||
21 | #include <linux/ptrace.h> | ||
22 | |||
23 | #include "probes.h" | ||
24 | #include "probes-arm.h" | ||
25 | |||
26 | #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit))))) | ||
27 | |||
28 | #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) | ||
29 | |||
30 | /* | ||
31 | * To avoid the complications of mimicing single-stepping on a | ||
32 | * processor without a Next-PC or a single-step mode, and to | ||
33 | * avoid having to deal with the side-effects of boosting, we | ||
34 | * simulate or emulate (almost) all ARM instructions. | ||
35 | * | ||
36 | * "Simulation" is where the instruction's behavior is duplicated in | ||
37 | * C code. "Emulation" is where the original instruction is rewritten | ||
38 | * and executed, often by altering its registers. | ||
39 | * | ||
40 | * By having all behavior of the kprobe'd instruction completed before | ||
41 | * returning from the kprobe_handler(), all locks (scheduler and | ||
42 | * interrupt) can safely be released. There is no need for secondary | ||
43 | * breakpoints, no race with MP or preemptable kernels, nor having to | ||
44 | * clean up resources counts at a later time impacting overall system | ||
45 | * performance. By rewriting the instruction, only the minimum registers | ||
46 | * need to be loaded and saved back optimizing performance. | ||
47 | * | ||
48 | * Calling the insnslot_*_rwflags version of a function doesn't hurt | ||
49 | * anything even when the CPSR flags aren't updated by the | ||
50 | * instruction. It's just a little slower in return for saving | ||
51 | * a little space by not having a duplicate function that doesn't | ||
52 | * update the flags. (The same optimization can be said for | ||
53 | * instructions that do or don't perform register writeback) | ||
54 | * Also, instructions can either read the flags, only write the | ||
55 | * flags, or read and write the flags. To save combinations | ||
56 | * rather than for sheer performance, flag functions just assume | ||
57 | * read and write of flags. | ||
58 | */ | ||
59 | |||
60 | void __kprobes simulate_bbl(probes_opcode_t insn, | ||
61 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
62 | { | ||
63 | long iaddr = (long) regs->ARM_pc - 4; | ||
64 | int disp = branch_displacement(insn); | ||
65 | |||
66 | if (insn & (1 << 24)) | ||
67 | regs->ARM_lr = iaddr + 4; | ||
68 | |||
69 | regs->ARM_pc = iaddr + 8 + disp; | ||
70 | } | ||
71 | |||
72 | void __kprobes simulate_blx1(probes_opcode_t insn, | ||
73 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
74 | { | ||
75 | long iaddr = (long) regs->ARM_pc - 4; | ||
76 | int disp = branch_displacement(insn); | ||
77 | |||
78 | regs->ARM_lr = iaddr + 4; | ||
79 | regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2); | ||
80 | regs->ARM_cpsr |= PSR_T_BIT; | ||
81 | } | ||
82 | |||
83 | void __kprobes simulate_blx2bx(probes_opcode_t insn, | ||
84 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
85 | { | ||
86 | int rm = insn & 0xf; | ||
87 | long rmv = regs->uregs[rm]; | ||
88 | |||
89 | if (insn & (1 << 5)) | ||
90 | regs->ARM_lr = (long) regs->ARM_pc; | ||
91 | |||
92 | regs->ARM_pc = rmv & ~0x1; | ||
93 | regs->ARM_cpsr &= ~PSR_T_BIT; | ||
94 | if (rmv & 0x1) | ||
95 | regs->ARM_cpsr |= PSR_T_BIT; | ||
96 | } | ||
97 | |||
98 | void __kprobes simulate_mrs(probes_opcode_t insn, | ||
99 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
100 | { | ||
101 | int rd = (insn >> 12) & 0xf; | ||
102 | unsigned long mask = 0xf8ff03df; /* Mask out execution state */ | ||
103 | regs->uregs[rd] = regs->ARM_cpsr & mask; | ||
104 | } | ||
105 | |||
106 | void __kprobes simulate_mov_ipsp(probes_opcode_t insn, | ||
107 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
108 | { | ||
109 | regs->uregs[12] = regs->uregs[13]; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * For the instruction masking and comparisons in all the "space_*" | ||
114 | * functions below, Do _not_ rearrange the order of tests unless | ||
115 | * you're very, very sure of what you are doing. For the sake of | ||
116 | * efficiency, the masks for some tests sometimes assume other test | ||
117 | * have been done prior to them so the number of patterns to test | ||
118 | * for an instruction set can be as broad as possible to reduce the | ||
119 | * number of tests needed. | ||
120 | */ | ||
121 | |||
122 | static const union decode_item arm_1111_table[] = { | ||
123 | /* Unconditional instructions */ | ||
124 | |||
125 | /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */ | ||
126 | /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */ | ||
127 | /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */ | ||
128 | /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */ | ||
129 | DECODE_SIMULATE (0xfe300000, 0xf4100000, PROBES_PRELOAD_IMM), | ||
130 | |||
131 | /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */ | ||
132 | /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */ | ||
133 | /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */ | ||
134 | /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */ | ||
135 | DECODE_SIMULATE (0xfe300010, 0xf6100000, PROBES_PRELOAD_REG), | ||
136 | |||
137 | /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
138 | DECODE_SIMULATE (0xfe000000, 0xfa000000, PROBES_BRANCH_IMM), | ||
139 | |||
140 | /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ | ||
141 | /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ | ||
142 | /* SRS 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
143 | /* RFE 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
144 | |||
145 | /* Coprocessor instructions... */ | ||
146 | /* MCRR2 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
147 | /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
148 | /* LDC2 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | ||
149 | /* STC2 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | ||
150 | /* CDP2 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | ||
151 | /* MCR2 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | ||
152 | /* MRC2 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | ||
153 | |||
154 | /* Other unallocated instructions... */ | ||
155 | DECODE_END | ||
156 | }; | ||
157 | |||
158 | static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = { | ||
159 | /* Miscellaneous instructions */ | ||
160 | |||
161 | /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ | ||
162 | DECODE_SIMULATEX(0x0ff000f0, 0x01000000, PROBES_MRS, | ||
163 | REGS(0, NOPC, 0, 0, 0)), | ||
164 | |||
165 | /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ | ||
166 | DECODE_SIMULATE (0x0ff000f0, 0x01200010, PROBES_BRANCH_REG), | ||
167 | |||
168 | /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ | ||
169 | DECODE_SIMULATEX(0x0ff000f0, 0x01200030, PROBES_BRANCH_REG, | ||
170 | REGS(0, 0, 0, 0, NOPC)), | ||
171 | |||
172 | /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ | ||
173 | DECODE_EMULATEX (0x0ff000f0, 0x01600010, PROBES_CLZ, | ||
174 | REGS(0, NOPC, 0, 0, NOPC)), | ||
175 | |||
176 | /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */ | ||
177 | /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */ | ||
178 | /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */ | ||
179 | /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */ | ||
180 | DECODE_EMULATEX (0x0f9000f0, 0x01000050, PROBES_SATURATING_ARITHMETIC, | ||
181 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
182 | |||
183 | /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | ||
184 | /* MSR cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | ||
185 | /* MRS spsr cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ | ||
186 | /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
187 | /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */ | ||
188 | /* And unallocated instructions... */ | ||
189 | DECODE_END | ||
190 | }; | ||
191 | |||
192 | static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = { | ||
193 | /* Halfword multiply and multiply-accumulate */ | ||
194 | |||
195 | /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ | ||
196 | DECODE_EMULATEX (0x0ff00090, 0x01400080, PROBES_MUL1, | ||
197 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
198 | |||
199 | /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ | ||
200 | DECODE_OR (0x0ff000b0, 0x012000a0), | ||
201 | /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ | ||
202 | DECODE_EMULATEX (0x0ff00090, 0x01600080, PROBES_MUL2, | ||
203 | REGS(NOPC, 0, NOPC, 0, NOPC)), | ||
204 | |||
205 | /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */ | ||
206 | DECODE_OR (0x0ff00090, 0x01000080), | ||
207 | /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */ | ||
208 | DECODE_EMULATEX (0x0ff000b0, 0x01200080, PROBES_MUL2, | ||
209 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
210 | |||
211 | DECODE_END | ||
212 | }; | ||
213 | |||
214 | static const union decode_item arm_cccc_0000_____1001_table[] = { | ||
215 | /* Multiply and multiply-accumulate */ | ||
216 | |||
217 | /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */ | ||
218 | /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */ | ||
219 | DECODE_EMULATEX (0x0fe000f0, 0x00000090, PROBES_MUL2, | ||
220 | REGS(NOPC, 0, NOPC, 0, NOPC)), | ||
221 | |||
222 | /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */ | ||
223 | /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */ | ||
224 | DECODE_OR (0x0fe000f0, 0x00200090), | ||
225 | /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */ | ||
226 | DECODE_EMULATEX (0x0ff000f0, 0x00600090, PROBES_MUL2, | ||
227 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
228 | |||
229 | /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */ | ||
230 | DECODE_OR (0x0ff000f0, 0x00400090), | ||
231 | /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */ | ||
232 | /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */ | ||
233 | /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */ | ||
234 | /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */ | ||
235 | /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */ | ||
236 | /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */ | ||
237 | /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */ | ||
238 | /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */ | ||
239 | DECODE_EMULATEX (0x0f8000f0, 0x00800090, PROBES_MUL1, | ||
240 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
241 | |||
242 | DECODE_END | ||
243 | }; | ||
244 | |||
245 | static const union decode_item arm_cccc_0001_____1001_table[] = { | ||
246 | /* Synchronization primitives */ | ||
247 | |||
248 | #if __LINUX_ARM_ARCH__ < 6 | ||
249 | /* Deprecated on ARMv6 and may be UNDEFINED on v7 */ | ||
250 | /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */ | ||
251 | DECODE_EMULATEX (0x0fb000f0, 0x01000090, PROBES_SWP, | ||
252 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
253 | #endif | ||
254 | /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */ | ||
255 | /* And unallocated instructions... */ | ||
256 | DECODE_END | ||
257 | }; | ||
258 | |||
259 | static const union decode_item arm_cccc_000x_____1xx1_table[] = { | ||
260 | /* Extra load/store instructions */ | ||
261 | |||
262 | /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */ | ||
263 | /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */ | ||
264 | /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */ | ||
265 | /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */ | ||
266 | /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */ | ||
267 | DECODE_REJECT (0x0f200090, 0x00200090), | ||
268 | |||
269 | /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */ | ||
270 | DECODE_REJECT (0x0e10e0d0, 0x0000e0d0), | ||
271 | |||
272 | /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */ | ||
273 | /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */ | ||
274 | DECODE_EMULATEX (0x0e5000d0, 0x000000d0, PROBES_LDRSTRD, | ||
275 | REGS(NOPCWB, NOPCX, 0, 0, NOPC)), | ||
276 | |||
277 | /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */ | ||
278 | /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */ | ||
279 | DECODE_EMULATEX (0x0e5000d0, 0x004000d0, PROBES_LDRSTRD, | ||
280 | REGS(NOPCWB, NOPCX, 0, 0, 0)), | ||
281 | |||
282 | /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */ | ||
283 | DECODE_EMULATEX (0x0e5000f0, 0x000000b0, PROBES_STORE_EXTRA, | ||
284 | REGS(NOPCWB, NOPC, 0, 0, NOPC)), | ||
285 | |||
286 | /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */ | ||
287 | /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */ | ||
288 | /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */ | ||
289 | DECODE_EMULATEX (0x0e500090, 0x00100090, PROBES_LOAD_EXTRA, | ||
290 | REGS(NOPCWB, NOPC, 0, 0, NOPC)), | ||
291 | |||
292 | /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */ | ||
293 | DECODE_EMULATEX (0x0e5000f0, 0x004000b0, PROBES_STORE_EXTRA, | ||
294 | REGS(NOPCWB, NOPC, 0, 0, 0)), | ||
295 | |||
296 | /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */ | ||
297 | /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */ | ||
298 | /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */ | ||
299 | DECODE_EMULATEX (0x0e500090, 0x00500090, PROBES_LOAD_EXTRA, | ||
300 | REGS(NOPCWB, NOPC, 0, 0, 0)), | ||
301 | |||
302 | DECODE_END | ||
303 | }; | ||
304 | |||
305 | static const union decode_item arm_cccc_000x_table[] = { | ||
306 | /* Data-processing (register) */ | ||
307 | |||
308 | /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */ | ||
309 | DECODE_REJECT (0x0e10f000, 0x0010f000), | ||
310 | |||
311 | /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */ | ||
312 | DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, PROBES_MOV_IP_SP), | ||
313 | |||
314 | /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */ | ||
315 | /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */ | ||
316 | /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */ | ||
317 | /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */ | ||
318 | DECODE_EMULATEX (0x0f900010, 0x01100000, PROBES_DATA_PROCESSING_REG, | ||
319 | REGS(ANY, 0, 0, 0, ANY)), | ||
320 | |||
321 | /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */ | ||
322 | /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */ | ||
323 | DECODE_EMULATEX (0x0fa00010, 0x01a00000, PROBES_DATA_PROCESSING_REG, | ||
324 | REGS(0, ANY, 0, 0, ANY)), | ||
325 | |||
326 | /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */ | ||
327 | /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */ | ||
328 | /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */ | ||
329 | /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */ | ||
330 | /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */ | ||
331 | /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */ | ||
332 | /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */ | ||
333 | /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */ | ||
334 | /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */ | ||
335 | /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */ | ||
336 | DECODE_EMULATEX (0x0e000010, 0x00000000, PROBES_DATA_PROCESSING_REG, | ||
337 | REGS(ANY, ANY, 0, 0, ANY)), | ||
338 | |||
339 | /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */ | ||
340 | /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */ | ||
341 | /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */ | ||
342 | /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */ | ||
343 | DECODE_EMULATEX (0x0f900090, 0x01100010, PROBES_DATA_PROCESSING_REG, | ||
344 | REGS(ANY, 0, NOPC, 0, ANY)), | ||
345 | |||
346 | /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */ | ||
347 | /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */ | ||
348 | DECODE_EMULATEX (0x0fa00090, 0x01a00010, PROBES_DATA_PROCESSING_REG, | ||
349 | REGS(0, ANY, NOPC, 0, ANY)), | ||
350 | |||
351 | /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */ | ||
352 | /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */ | ||
353 | /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */ | ||
354 | /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */ | ||
355 | /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */ | ||
356 | /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */ | ||
357 | /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */ | ||
358 | /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */ | ||
359 | /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */ | ||
360 | /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */ | ||
361 | DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG, | ||
362 | REGS(ANY, ANY, NOPC, 0, ANY)), | ||
363 | |||
364 | DECODE_END | ||
365 | }; | ||
366 | |||
367 | static const union decode_item arm_cccc_001x_table[] = { | ||
368 | /* Data-processing (immediate) */ | ||
369 | |||
370 | /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ | ||
371 | /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
372 | DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM, | ||
373 | REGS(0, NOPC, 0, 0, 0)), | ||
374 | |||
375 | /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ | ||
376 | DECODE_OR (0x0fff00ff, 0x03200001), | ||
377 | /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ | ||
378 | DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE), | ||
379 | /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ | ||
380 | /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ | ||
381 | /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ | ||
382 | DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP), | ||
383 | /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */ | ||
384 | /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ | ||
385 | /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */ | ||
386 | DECODE_REJECT (0x0fb00000, 0x03200000), | ||
387 | |||
388 | /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */ | ||
389 | DECODE_REJECT (0x0e10f000, 0x0210f000), | ||
390 | |||
391 | /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */ | ||
392 | /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */ | ||
393 | /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
394 | /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */ | ||
395 | DECODE_EMULATEX (0x0f900000, 0x03100000, PROBES_DATA_PROCESSING_IMM, | ||
396 | REGS(ANY, 0, 0, 0, 0)), | ||
397 | |||
398 | /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */ | ||
399 | /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */ | ||
400 | DECODE_EMULATEX (0x0fa00000, 0x03a00000, PROBES_DATA_PROCESSING_IMM, | ||
401 | REGS(0, ANY, 0, 0, 0)), | ||
402 | |||
403 | /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */ | ||
404 | /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */ | ||
405 | /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */ | ||
406 | /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */ | ||
407 | /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */ | ||
408 | /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */ | ||
409 | /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */ | ||
410 | /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */ | ||
411 | /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */ | ||
412 | /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */ | ||
413 | DECODE_EMULATEX (0x0e000000, 0x02000000, PROBES_DATA_PROCESSING_IMM, | ||
414 | REGS(ANY, ANY, 0, 0, 0)), | ||
415 | |||
416 | DECODE_END | ||
417 | }; | ||
418 | |||
419 | static const union decode_item arm_cccc_0110_____xxx1_table[] = { | ||
420 | /* Media instructions */ | ||
421 | |||
422 | /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */ | ||
423 | DECODE_EMULATEX (0x0ff000f0, 0x068000b0, PROBES_SATURATE, | ||
424 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
425 | |||
426 | /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */ | ||
427 | /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */ | ||
428 | DECODE_OR(0x0fa00030, 0x06a00010), | ||
429 | /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */ | ||
430 | /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */ | ||
431 | DECODE_EMULATEX (0x0fb000f0, 0x06a00030, PROBES_SATURATE, | ||
432 | REGS(0, NOPC, 0, 0, NOPC)), | ||
433 | |||
434 | /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ | ||
435 | /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ | ||
436 | /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */ | ||
437 | /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ | ||
438 | DECODE_EMULATEX (0x0fb00070, 0x06b00030, PROBES_REV, | ||
439 | REGS(0, NOPC, 0, 0, NOPC)), | ||
440 | |||
441 | /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */ | ||
442 | DECODE_REJECT (0x0fb00010, 0x06000010), | ||
443 | /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */ | ||
444 | DECODE_REJECT (0x0f8000f0, 0x060000b0), | ||
445 | /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */ | ||
446 | DECODE_REJECT (0x0f8000f0, 0x060000d0), | ||
447 | /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */ | ||
448 | /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */ | ||
449 | /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */ | ||
450 | /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */ | ||
451 | /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */ | ||
452 | /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */ | ||
453 | /* QADD16 cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */ | ||
454 | /* QADDSUBX cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */ | ||
455 | /* QSUBADDX cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */ | ||
456 | /* QSUB16 cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
457 | /* QADD8 cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */ | ||
458 | /* QSUB8 cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */ | ||
459 | /* SHADD16 cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */ | ||
460 | /* SHADDSUBX cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */ | ||
461 | /* SHSUBADDX cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */ | ||
462 | /* SHSUB16 cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */ | ||
463 | /* SHADD8 cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */ | ||
464 | /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */ | ||
465 | /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */ | ||
466 | /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */ | ||
467 | /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */ | ||
468 | /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */ | ||
469 | /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */ | ||
470 | /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */ | ||
471 | /* UQADD16 cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */ | ||
472 | /* UQADDSUBX cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */ | ||
473 | /* UQSUBADDX cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */ | ||
474 | /* UQSUB16 cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */ | ||
475 | /* UQADD8 cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */ | ||
476 | /* UQSUB8 cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */ | ||
477 | /* UHADD16 cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */ | ||
478 | /* UHADDSUBX cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */ | ||
479 | /* UHSUBADDX cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */ | ||
480 | /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */ | ||
481 | /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */ | ||
482 | /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */ | ||
483 | DECODE_EMULATEX (0x0f800010, 0x06000010, PROBES_MMI, | ||
484 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
485 | |||
486 | /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */ | ||
487 | /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */ | ||
488 | DECODE_EMULATEX (0x0ff00030, 0x06800010, PROBES_PACK, | ||
489 | REGS(NOPC, NOPC, 0, 0, NOPC)), | ||
490 | |||
491 | /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */ | ||
492 | /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */ | ||
493 | DECODE_REJECT (0x0fb000f0, 0x06900070), | ||
494 | |||
495 | /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */ | ||
496 | /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */ | ||
497 | /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */ | ||
498 | /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */ | ||
499 | /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */ | ||
500 | /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */ | ||
501 | DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, PROBES_EXTEND, | ||
502 | REGS(0, NOPC, 0, 0, NOPC)), | ||
503 | |||
504 | /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */ | ||
505 | /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */ | ||
506 | /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */ | ||
507 | /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */ | ||
508 | /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */ | ||
509 | /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */ | ||
510 | DECODE_EMULATEX (0x0f8000f0, 0x06800070, PROBES_EXTEND_ADD, | ||
511 | REGS(NOPCX, NOPC, 0, 0, NOPC)), | ||
512 | |||
513 | DECODE_END | ||
514 | }; | ||
515 | |||
516 | static const union decode_item arm_cccc_0111_____xxx1_table[] = { | ||
517 | /* Media instructions */ | ||
518 | |||
519 | /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */ | ||
520 | DECODE_REJECT (0x0ff000f0, 0x07f000f0), | ||
521 | |||
522 | /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ | ||
523 | /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ | ||
524 | DECODE_EMULATEX (0x0ff00090, 0x07400010, PROBES_MUL_ADD_LONG, | ||
525 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
526 | |||
527 | /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */ | ||
528 | /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */ | ||
529 | DECODE_OR (0x0ff0f090, 0x0700f010), | ||
530 | /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */ | ||
531 | DECODE_OR (0x0ff0f0d0, 0x0750f010), | ||
532 | /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ | ||
533 | DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, PROBES_MUL_ADD, | ||
534 | REGS(NOPC, 0, NOPC, 0, NOPC)), | ||
535 | |||
536 | /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */ | ||
537 | /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */ | ||
538 | DECODE_OR (0x0ff00090, 0x07000010), | ||
539 | /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */ | ||
540 | DECODE_OR (0x0ff000d0, 0x07500010), | ||
541 | /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ | ||
542 | DECODE_EMULATEX (0x0ff000f0, 0x07800010, PROBES_MUL_ADD, | ||
543 | REGS(NOPC, NOPCX, NOPC, 0, NOPC)), | ||
544 | |||
545 | /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */ | ||
546 | DECODE_EMULATEX (0x0ff000d0, 0x075000d0, PROBES_MUL_ADD, | ||
547 | REGS(NOPC, NOPC, NOPC, 0, NOPC)), | ||
548 | |||
549 | /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */ | ||
550 | /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */ | ||
551 | DECODE_EMULATEX (0x0fa00070, 0x07a00050, PROBES_BITFIELD, | ||
552 | REGS(0, NOPC, 0, 0, NOPC)), | ||
553 | |||
554 | /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */ | ||
555 | DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, PROBES_BITFIELD, | ||
556 | REGS(0, NOPC, 0, 0, 0)), | ||
557 | |||
558 | /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */ | ||
559 | DECODE_EMULATEX (0x0fe00070, 0x07c00010, PROBES_BITFIELD, | ||
560 | REGS(0, NOPC, 0, 0, NOPCX)), | ||
561 | |||
562 | DECODE_END | ||
563 | }; | ||
564 | |||
565 | static const union decode_item arm_cccc_01xx_table[] = { | ||
566 | /* Load/store word and unsigned byte */ | ||
567 | |||
568 | /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */ | ||
569 | DECODE_REJECT (0x0c40f000, 0x0440f000), | ||
570 | |||
571 | /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ | ||
572 | /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */ | ||
573 | /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ | ||
574 | /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */ | ||
575 | DECODE_REJECT (0x0d200000, 0x04200000), | ||
576 | |||
577 | /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
578 | /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
579 | DECODE_EMULATEX (0x0e100000, 0x04000000, PROBES_STORE, | ||
580 | REGS(NOPCWB, ANY, 0, 0, 0)), | ||
581 | |||
582 | /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
583 | /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
584 | DECODE_EMULATEX (0x0e100000, 0x04100000, PROBES_LOAD, | ||
585 | REGS(NOPCWB, ANY, 0, 0, 0)), | ||
586 | |||
587 | /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
588 | /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
589 | DECODE_EMULATEX (0x0e100000, 0x06000000, PROBES_STORE, | ||
590 | REGS(NOPCWB, ANY, 0, 0, NOPC)), | ||
591 | |||
592 | /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
593 | /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
594 | DECODE_EMULATEX (0x0e100000, 0x06100000, PROBES_LOAD, | ||
595 | REGS(NOPCWB, ANY, 0, 0, NOPC)), | ||
596 | |||
597 | DECODE_END | ||
598 | }; | ||
599 | |||
600 | static const union decode_item arm_cccc_100x_table[] = { | ||
601 | /* Block data transfer instructions */ | ||
602 | |||
603 | /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
604 | /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
605 | DECODE_CUSTOM (0x0e400000, 0x08000000, PROBES_LDMSTM), | ||
606 | |||
607 | /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
608 | /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */ | ||
609 | /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */ | ||
610 | DECODE_END | ||
611 | }; | ||
612 | |||
613 | const union decode_item probes_decode_arm_table[] = { | ||
614 | /* | ||
615 | * Unconditional instructions | ||
616 | * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx | ||
617 | */ | ||
618 | DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table), | ||
619 | |||
620 | /* | ||
621 | * Miscellaneous instructions | ||
622 | * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx | ||
623 | */ | ||
624 | DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table), | ||
625 | |||
626 | /* | ||
627 | * Halfword multiply and multiply-accumulate | ||
628 | * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx | ||
629 | */ | ||
630 | DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table), | ||
631 | |||
632 | /* | ||
633 | * Multiply and multiply-accumulate | ||
634 | * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx | ||
635 | */ | ||
636 | DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table), | ||
637 | |||
638 | /* | ||
639 | * Synchronization primitives | ||
640 | * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx | ||
641 | */ | ||
642 | DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table), | ||
643 | |||
644 | /* | ||
645 | * Extra load/store instructions | ||
646 | * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx | ||
647 | */ | ||
648 | DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table), | ||
649 | |||
650 | /* | ||
651 | * Data-processing (register) | ||
652 | * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx | ||
653 | * Data-processing (register-shifted register) | ||
654 | * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx | ||
655 | */ | ||
656 | DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table), | ||
657 | |||
658 | /* | ||
659 | * Data-processing (immediate) | ||
660 | * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx | ||
661 | */ | ||
662 | DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table), | ||
663 | |||
664 | /* | ||
665 | * Media instructions | ||
666 | * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx | ||
667 | */ | ||
668 | DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table), | ||
669 | DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table), | ||
670 | |||
671 | /* | ||
672 | * Load/store word and unsigned byte | ||
673 | * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx | ||
674 | */ | ||
675 | DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table), | ||
676 | |||
677 | /* | ||
678 | * Block data transfer instructions | ||
679 | * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx | ||
680 | */ | ||
681 | DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table), | ||
682 | |||
683 | /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
684 | /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
685 | DECODE_SIMULATE (0x0e000000, 0x0a000000, PROBES_BRANCH), | ||
686 | |||
687 | /* | ||
688 | * Supervisor Call, and coprocessor instructions | ||
689 | */ | ||
690 | |||
691 | /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
692 | /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
693 | /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | ||
694 | /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | ||
695 | /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | ||
696 | /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | ||
697 | /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | ||
698 | /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
699 | DECODE_REJECT (0x0c000000, 0x0c000000), | ||
700 | |||
701 | DECODE_END | ||
702 | }; | ||
703 | #ifdef CONFIG_ARM_KPROBES_TEST_MODULE | ||
704 | EXPORT_SYMBOL_GPL(probes_decode_arm_table); | ||
705 | #endif | ||
706 | |||
707 | static void __kprobes arm_singlestep(probes_opcode_t insn, | ||
708 | struct arch_probes_insn *asi, struct pt_regs *regs) | ||
709 | { | ||
710 | regs->ARM_pc += 4; | ||
711 | asi->insn_handler(insn, asi, regs); | ||
712 | } | ||
713 | |||
714 | /* Return: | ||
715 | * INSN_REJECTED If instruction is one not allowed to kprobe, | ||
716 | * INSN_GOOD If instruction is supported and uses instruction slot, | ||
717 | * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot. | ||
718 | * | ||
719 | * For instructions we don't want to kprobe (INSN_REJECTED return result): | ||
720 | * These are generally ones that modify the processor state making | ||
721 | * them "hard" to simulate such as switches processor modes or | ||
722 | * make accesses in alternate modes. Any of these could be simulated | ||
723 | * if the work was put into it, but low return considering they | ||
724 | * should also be very rare. | ||
725 | */ | ||
726 | enum probes_insn __kprobes | ||
727 | arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
728 | bool emulate, const union decode_action *actions) | ||
729 | { | ||
730 | asi->insn_singlestep = arm_singlestep; | ||
731 | asi->insn_check_cc = probes_condition_checks[insn>>28]; | ||
732 | return probes_decode_insn(insn, asi, probes_decode_arm_table, false, | ||
733 | emulate, actions); | ||
734 | } | ||
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/kernel/probes-arm.h new file mode 100644 index 000000000000..ace6572f6e26 --- /dev/null +++ b/arch/arm/kernel/probes-arm.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/probes-arm.h | ||
3 | * | ||
4 | * Copyright 2013 Linaro Ltd. | ||
5 | * Written by: David A. Long | ||
6 | * | ||
7 | * The code contained herein is licensed under the GNU General Public | ||
8 | * License. You may obtain a copy of the GNU General Public License | ||
9 | * Version 2 or later at the following locations: | ||
10 | * | ||
11 | * http://www.opensource.org/licenses/gpl-license.html | ||
12 | * http://www.gnu.org/copyleft/gpl.html | ||
13 | */ | ||
14 | |||
15 | #ifndef _ARM_KERNEL_PROBES_ARM_H | ||
16 | #define _ARM_KERNEL_PROBES_ARM_H | ||
17 | |||
18 | enum probes_arm_action { | ||
19 | PROBES_EMULATE_NONE, | ||
20 | PROBES_SIMULATE_NOP, | ||
21 | PROBES_PRELOAD_IMM, | ||
22 | PROBES_PRELOAD_REG, | ||
23 | PROBES_BRANCH_IMM, | ||
24 | PROBES_BRANCH_REG, | ||
25 | PROBES_MRS, | ||
26 | PROBES_CLZ, | ||
27 | PROBES_SATURATING_ARITHMETIC, | ||
28 | PROBES_MUL1, | ||
29 | PROBES_MUL2, | ||
30 | PROBES_SWP, | ||
31 | PROBES_LDRSTRD, | ||
32 | PROBES_LOAD, | ||
33 | PROBES_STORE, | ||
34 | PROBES_LOAD_EXTRA, | ||
35 | PROBES_STORE_EXTRA, | ||
36 | PROBES_MOV_IP_SP, | ||
37 | PROBES_DATA_PROCESSING_REG, | ||
38 | PROBES_DATA_PROCESSING_IMM, | ||
39 | PROBES_MOV_HALFWORD, | ||
40 | PROBES_SEV, | ||
41 | PROBES_WFE, | ||
42 | PROBES_SATURATE, | ||
43 | PROBES_REV, | ||
44 | PROBES_MMI, | ||
45 | PROBES_PACK, | ||
46 | PROBES_EXTEND, | ||
47 | PROBES_EXTEND_ADD, | ||
48 | PROBES_MUL_ADD_LONG, | ||
49 | PROBES_MUL_ADD, | ||
50 | PROBES_BITFIELD, | ||
51 | PROBES_BRANCH, | ||
52 | PROBES_LDMSTM, | ||
53 | NUM_PROBES_ARM_ACTIONS | ||
54 | }; | ||
55 | |||
56 | void __kprobes simulate_bbl(probes_opcode_t opcode, | ||
57 | struct arch_probes_insn *asi, struct pt_regs *regs); | ||
58 | void __kprobes simulate_blx1(probes_opcode_t opcode, | ||
59 | struct arch_probes_insn *asi, struct pt_regs *regs); | ||
60 | void __kprobes simulate_blx2bx(probes_opcode_t opcode, | ||
61 | struct arch_probes_insn *asi, struct pt_regs *regs); | ||
62 | void __kprobes simulate_mrs(probes_opcode_t opcode, | ||
63 | struct arch_probes_insn *asi, struct pt_regs *regs); | ||
64 | void __kprobes simulate_mov_ipsp(probes_opcode_t opcode, | ||
65 | struct arch_probes_insn *asi, struct pt_regs *regs); | ||
66 | |||
67 | extern const union decode_item probes_decode_arm_table[]; | ||
68 | |||
69 | enum probes_insn arm_probes_decode_insn(probes_opcode_t, | ||
70 | struct arch_probes_insn *, bool emulate, | ||
71 | const union decode_action *actions); | ||
72 | |||
73 | #endif | ||
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/kernel/probes-thumb.c new file mode 100644 index 000000000000..4131351e812f --- /dev/null +++ b/arch/arm/kernel/probes-thumb.c | |||
@@ -0,0 +1,882 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/probes-thumb.c | ||
3 | * | ||
4 | * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/stddef.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | |||
15 | #include "probes.h" | ||
16 | #include "probes-thumb.h" | ||
17 | |||
18 | |||
19 | static const union decode_item t32_table_1110_100x_x0xx[] = { | ||
20 | /* Load/store multiple instructions */ | ||
21 | |||
22 | /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */ | ||
23 | DECODE_REJECT (0xfe4f0000, 0xe80f0000), | ||
24 | |||
25 | /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */ | ||
26 | /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */ | ||
27 | DECODE_REJECT (0xffc00000, 0xe8000000), | ||
28 | /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */ | ||
29 | /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */ | ||
30 | DECODE_REJECT (0xffc00000, 0xe9800000), | ||
31 | |||
32 | /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */ | ||
33 | DECODE_REJECT (0xfe508000, 0xe8008000), | ||
34 | /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */ | ||
35 | DECODE_REJECT (0xfe50c000, 0xe810c000), | ||
36 | /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */ | ||
37 | DECODE_REJECT (0xfe402000, 0xe8002000), | ||
38 | |||
39 | /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */ | ||
40 | /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */ | ||
41 | /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */ | ||
42 | /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */ | ||
43 | DECODE_CUSTOM (0xfe400000, 0xe8000000, PROBES_T32_LDMSTM), | ||
44 | |||
45 | DECODE_END | ||
46 | }; | ||
47 | |||
48 | static const union decode_item t32_table_1110_100x_x1xx[] = { | ||
49 | /* Load/store dual, load/store exclusive, table branch */ | ||
50 | |||
51 | /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */ | ||
52 | /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */ | ||
53 | DECODE_OR (0xff600000, 0xe8600000), | ||
54 | /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
55 | /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
56 | DECODE_EMULATEX (0xff400000, 0xe9400000, PROBES_T32_LDRDSTRD, | ||
57 | REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)), | ||
58 | |||
59 | /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */ | ||
60 | /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */ | ||
61 | DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, PROBES_T32_TABLE_BRANCH, | ||
62 | REGS(NOSP, 0, 0, 0, NOSPPC)), | ||
63 | |||
64 | /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */ | ||
65 | /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
66 | /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */ | ||
67 | /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */ | ||
68 | /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */ | ||
69 | /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */ | ||
70 | /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */ | ||
71 | /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */ | ||
72 | /* And unallocated instructions... */ | ||
73 | DECODE_END | ||
74 | }; | ||
75 | |||
76 | static const union decode_item t32_table_1110_101x[] = { | ||
77 | /* Data-processing (shifted register) */ | ||
78 | |||
79 | /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */ | ||
80 | /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */ | ||
81 | DECODE_EMULATEX (0xff700f00, 0xea100f00, PROBES_T32_TST, | ||
82 | REGS(NOSPPC, 0, 0, 0, NOSPPC)), | ||
83 | |||
84 | /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */ | ||
85 | DECODE_OR (0xfff00f00, 0xeb100f00), | ||
86 | /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */ | ||
87 | DECODE_EMULATEX (0xfff00f00, 0xebb00f00, PROBES_T32_TST, | ||
88 | REGS(NOPC, 0, 0, 0, NOSPPC)), | ||
89 | |||
90 | /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */ | ||
91 | /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */ | ||
92 | DECODE_EMULATEX (0xffcf0000, 0xea4f0000, PROBES_T32_MOV, | ||
93 | REGS(0, 0, NOSPPC, 0, NOSPPC)), | ||
94 | |||
95 | /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */ | ||
96 | /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */ | ||
97 | DECODE_REJECT (0xffa00000, 0xeaa00000), | ||
98 | /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */ | ||
99 | DECODE_REJECT (0xffe00000, 0xeb200000), | ||
100 | /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */ | ||
101 | DECODE_REJECT (0xffe00000, 0xeb800000), | ||
102 | /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */ | ||
103 | DECODE_REJECT (0xffe00000, 0xebe00000), | ||
104 | |||
105 | /* ADD/SUB SP, SP, Rm, LSL #0..3 */ | ||
106 | /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */ | ||
107 | DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, PROBES_T32_ADDSUB, | ||
108 | REGS(SP, 0, SP, 0, NOSPPC)), | ||
109 | |||
110 | /* ADD/SUB SP, SP, Rm, shift */ | ||
111 | /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */ | ||
112 | DECODE_REJECT (0xff4f0f00, 0xeb0d0d00), | ||
113 | |||
114 | /* ADD/SUB Rd, SP, Rm, shift */ | ||
115 | /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */ | ||
116 | DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, PROBES_T32_ADDSUB, | ||
117 | REGS(SP, 0, NOPC, 0, NOSPPC)), | ||
118 | |||
119 | /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */ | ||
120 | /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */ | ||
121 | /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */ | ||
122 | /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */ | ||
123 | /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */ | ||
124 | /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */ | ||
125 | /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */ | ||
126 | /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */ | ||
127 | /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */ | ||
128 | /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */ | ||
129 | /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */ | ||
130 | DECODE_EMULATEX (0xfe000000, 0xea000000, PROBES_T32_LOGICAL, | ||
131 | REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), | ||
132 | |||
133 | DECODE_END | ||
134 | }; | ||
135 | |||
136 | static const union decode_item t32_table_1111_0x0x___0[] = { | ||
137 | /* Data-processing (modified immediate) */ | ||
138 | |||
139 | /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */ | ||
140 | /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */ | ||
141 | DECODE_EMULATEX (0xfb708f00, 0xf0100f00, PROBES_T32_TST, | ||
142 | REGS(NOSPPC, 0, 0, 0, 0)), | ||
143 | |||
144 | /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */ | ||
145 | DECODE_OR (0xfbf08f00, 0xf1100f00), | ||
146 | /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */ | ||
147 | DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, PROBES_T32_CMP, | ||
148 | REGS(NOPC, 0, 0, 0, 0)), | ||
149 | |||
150 | /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */ | ||
151 | /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */ | ||
152 | DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, PROBES_T32_MOV, | ||
153 | REGS(0, 0, NOSPPC, 0, 0)), | ||
154 | |||
155 | /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */ | ||
156 | DECODE_REJECT (0xfbe08000, 0xf0a00000), | ||
157 | /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */ | ||
158 | /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */ | ||
159 | DECODE_REJECT (0xfbc08000, 0xf0c00000), | ||
160 | /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */ | ||
161 | DECODE_REJECT (0xfbe08000, 0xf1200000), | ||
162 | /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */ | ||
163 | DECODE_REJECT (0xfbe08000, 0xf1800000), | ||
164 | /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */ | ||
165 | DECODE_REJECT (0xfbe08000, 0xf1e00000), | ||
166 | |||
167 | /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */ | ||
168 | /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */ | ||
169 | DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, PROBES_T32_ADDSUB, | ||
170 | REGS(SP, 0, NOPC, 0, 0)), | ||
171 | |||
172 | /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */ | ||
173 | /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */ | ||
174 | /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */ | ||
175 | /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */ | ||
176 | /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */ | ||
177 | /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */ | ||
178 | /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */ | ||
179 | /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */ | ||
180 | /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */ | ||
181 | /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */ | ||
182 | DECODE_EMULATEX (0xfa008000, 0xf0000000, PROBES_T32_LOGICAL, | ||
183 | REGS(NOSPPC, 0, NOSPPC, 0, 0)), | ||
184 | |||
185 | DECODE_END | ||
186 | }; | ||
187 | |||
188 | static const union decode_item t32_table_1111_0x1x___0[] = { | ||
189 | /* Data-processing (plain binary immediate) */ | ||
190 | |||
191 | /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */ | ||
192 | DECODE_OR (0xfbff8000, 0xf20f0000), | ||
193 | /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */ | ||
194 | DECODE_EMULATEX (0xfbff8000, 0xf2af0000, PROBES_T32_ADDWSUBW_PC, | ||
195 | REGS(PC, 0, NOSPPC, 0, 0)), | ||
196 | |||
197 | /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */ | ||
198 | DECODE_OR (0xfbff8f00, 0xf20d0d00), | ||
199 | /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */ | ||
200 | DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, PROBES_T32_ADDWSUBW, | ||
201 | REGS(SP, 0, SP, 0, 0)), | ||
202 | |||
203 | /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */ | ||
204 | DECODE_OR (0xfbf08000, 0xf2000000), | ||
205 | /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */ | ||
206 | DECODE_EMULATEX (0xfbf08000, 0xf2a00000, PROBES_T32_ADDWSUBW, | ||
207 | REGS(NOPCX, 0, NOSPPC, 0, 0)), | ||
208 | |||
209 | /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */ | ||
210 | /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */ | ||
211 | DECODE_EMULATEX (0xfb708000, 0xf2400000, PROBES_T32_MOVW, | ||
212 | REGS(0, 0, NOSPPC, 0, 0)), | ||
213 | |||
214 | /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */ | ||
215 | /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */ | ||
216 | /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */ | ||
217 | /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */ | ||
218 | DECODE_EMULATEX (0xfb508000, 0xf3000000, PROBES_T32_SAT, | ||
219 | REGS(NOSPPC, 0, NOSPPC, 0, 0)), | ||
220 | |||
221 | /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */ | ||
222 | /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */ | ||
223 | DECODE_EMULATEX (0xfb708000, 0xf3400000, PROBES_T32_BITFIELD, | ||
224 | REGS(NOSPPC, 0, NOSPPC, 0, 0)), | ||
225 | |||
226 | /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */ | ||
227 | DECODE_EMULATEX (0xfbff8000, 0xf36f0000, PROBES_T32_BITFIELD, | ||
228 | REGS(0, 0, NOSPPC, 0, 0)), | ||
229 | |||
230 | /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */ | ||
231 | DECODE_EMULATEX (0xfbf08000, 0xf3600000, PROBES_T32_BITFIELD, | ||
232 | REGS(NOSPPCX, 0, NOSPPC, 0, 0)), | ||
233 | |||
234 | DECODE_END | ||
235 | }; | ||
236 | |||
237 | static const union decode_item t32_table_1111_0xxx___1[] = { | ||
238 | /* Branches and miscellaneous control */ | ||
239 | |||
240 | /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */ | ||
241 | DECODE_OR (0xfff0d7ff, 0xf3a08001), | ||
242 | /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */ | ||
243 | DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, PROBES_T32_SEV), | ||
244 | /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */ | ||
245 | /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */ | ||
246 | /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */ | ||
247 | DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, PROBES_T32_WFE), | ||
248 | |||
249 | /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */ | ||
250 | DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, PROBES_T32_MRS, | ||
251 | REGS(0, 0, NOSPPC, 0, 0)), | ||
252 | |||
253 | /* | ||
254 | * Unsupported instructions | ||
255 | * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx | ||
256 | * | ||
257 | * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx | ||
258 | * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx | ||
259 | * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx | ||
260 | * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx | ||
261 | * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx | ||
262 | * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx | ||
263 | * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx | ||
264 | * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx | ||
265 | * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx | ||
266 | * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx | ||
267 | * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx | ||
268 | */ | ||
269 | DECODE_REJECT (0xfb80d000, 0xf3808000), | ||
270 | |||
271 | /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */ | ||
272 | DECODE_CUSTOM (0xf800d000, 0xf0008000, PROBES_T32_BRANCH_COND), | ||
273 | |||
274 | /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */ | ||
275 | DECODE_OR (0xf800d001, 0xf000c000), | ||
276 | /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */ | ||
277 | /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */ | ||
278 | DECODE_SIMULATE (0xf8009000, 0xf0009000, PROBES_T32_BRANCH), | ||
279 | |||
280 | DECODE_END | ||
281 | }; | ||
282 | |||
283 | static const union decode_item t32_table_1111_100x_x0x1__1111[] = { | ||
284 | /* Memory hints */ | ||
285 | |||
286 | /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */ | ||
287 | /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */ | ||
288 | DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, PROBES_T32_PLDI), | ||
289 | |||
290 | /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */ | ||
291 | DECODE_OR (0xffd0f000, 0xf890f000), | ||
292 | /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */ | ||
293 | DECODE_OR (0xffd0ff00, 0xf810fc00), | ||
294 | /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */ | ||
295 | DECODE_OR (0xfff0f000, 0xf990f000), | ||
296 | /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */ | ||
297 | DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, PROBES_T32_PLDI, | ||
298 | REGS(NOPCX, 0, 0, 0, 0)), | ||
299 | |||
300 | /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */ | ||
301 | DECODE_OR (0xffd0ffc0, 0xf810f000), | ||
302 | /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */ | ||
303 | DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, PROBES_T32_PLDI, | ||
304 | REGS(NOPCX, 0, 0, 0, NOSPPC)), | ||
305 | |||
306 | /* Other unallocated instructions... */ | ||
307 | DECODE_END | ||
308 | }; | ||
309 | |||
310 | static const union decode_item t32_table_1111_100x[] = { | ||
311 | /* Store/Load single data item */ | ||
312 | |||
313 | /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */ | ||
314 | DECODE_REJECT (0xfe600000, 0xf8600000), | ||
315 | |||
316 | /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */ | ||
317 | DECODE_REJECT (0xfff00000, 0xf9500000), | ||
318 | |||
319 | /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */ | ||
320 | DECODE_REJECT (0xfe800d00, 0xf8000800), | ||
321 | |||
322 | /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */ | ||
323 | /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */ | ||
324 | /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */ | ||
325 | /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */ | ||
326 | /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */ | ||
327 | /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */ | ||
328 | /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */ | ||
329 | /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */ | ||
330 | DECODE_REJECT (0xfe800f00, 0xf8000e00), | ||
331 | |||
332 | /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */ | ||
333 | DECODE_REJECT (0xff1f0000, 0xf80f0000), | ||
334 | |||
335 | /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */ | ||
336 | DECODE_REJECT (0xff10f000, 0xf800f000), | ||
337 | |||
338 | /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */ | ||
339 | DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, PROBES_T32_LDR_LIT, | ||
340 | REGS(PC, ANY, 0, 0, 0)), | ||
341 | |||
342 | /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */ | ||
343 | /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */ | ||
344 | DECODE_OR (0xffe00800, 0xf8400800), | ||
345 | /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */ | ||
346 | /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */ | ||
347 | DECODE_EMULATEX (0xffe00000, 0xf8c00000, PROBES_T32_LDRSTR, | ||
348 | REGS(NOPCX, ANY, 0, 0, 0)), | ||
349 | |||
350 | /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */ | ||
351 | /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */ | ||
352 | DECODE_EMULATEX (0xffe00fc0, 0xf8400000, PROBES_T32_LDRSTR, | ||
353 | REGS(NOPCX, ANY, 0, 0, NOSPPC)), | ||
354 | |||
355 | /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */ | ||
356 | /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ | ||
357 | /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ | ||
358 | /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ | ||
359 | DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, PROBES_T32_LDR_LIT, | ||
360 | REGS(PC, NOSPPCX, 0, 0, 0)), | ||
361 | |||
362 | /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ | ||
363 | /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */ | ||
364 | /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */ | ||
365 | /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */ | ||
366 | /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */ | ||
367 | /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */ | ||
368 | DECODE_OR (0xfec00800, 0xf8000800), | ||
369 | /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */ | ||
370 | /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */ | ||
371 | /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */ | ||
372 | /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */ | ||
373 | /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */ | ||
374 | /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */ | ||
375 | DECODE_EMULATEX (0xfec00000, 0xf8800000, PROBES_T32_LDRSTR, | ||
376 | REGS(NOPCX, NOSPPCX, 0, 0, 0)), | ||
377 | |||
378 | /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */ | ||
379 | /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */ | ||
380 | /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */ | ||
381 | /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */ | ||
382 | /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */ | ||
383 | /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */ | ||
384 | DECODE_EMULATEX (0xfe800fc0, 0xf8000000, PROBES_T32_LDRSTR, | ||
385 | REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)), | ||
386 | |||
387 | /* Other unallocated instructions... */ | ||
388 | DECODE_END | ||
389 | }; | ||
390 | |||
391 | static const union decode_item t32_table_1111_1010___1111[] = { | ||
392 | /* Data-processing (register) */ | ||
393 | |||
394 | /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */ | ||
395 | DECODE_REJECT (0xffe0f080, 0xfa60f080), | ||
396 | |||
397 | /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */ | ||
398 | /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */ | ||
399 | /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */ | ||
400 | /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */ | ||
401 | /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */ | ||
402 | /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */ | ||
403 | DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, PROBES_T32_SIGN_EXTEND, | ||
404 | REGS(0, 0, NOSPPC, 0, NOSPPC)), | ||
405 | |||
406 | |||
407 | /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */ | ||
408 | DECODE_REJECT (0xff80f0b0, 0xfa80f030), | ||
409 | /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */ | ||
410 | DECODE_REJECT (0xffb0f080, 0xfab0f000), | ||
411 | |||
412 | /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */ | ||
413 | /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */ | ||
414 | /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */ | ||
415 | /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */ | ||
416 | /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */ | ||
417 | /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */ | ||
418 | |||
419 | /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */ | ||
420 | /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */ | ||
421 | /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */ | ||
422 | /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */ | ||
423 | /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */ | ||
424 | /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */ | ||
425 | |||
426 | /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */ | ||
427 | /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */ | ||
428 | /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */ | ||
429 | /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */ | ||
430 | /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */ | ||
431 | /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */ | ||
432 | |||
433 | /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */ | ||
434 | /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */ | ||
435 | /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */ | ||
436 | /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */ | ||
437 | /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */ | ||
438 | /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */ | ||
439 | |||
440 | /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */ | ||
441 | /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */ | ||
442 | /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */ | ||
443 | /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */ | ||
444 | /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */ | ||
445 | /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */ | ||
446 | |||
447 | /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */ | ||
448 | /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */ | ||
449 | /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */ | ||
450 | /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */ | ||
451 | /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */ | ||
452 | /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */ | ||
453 | DECODE_OR (0xff80f080, 0xfa80f000), | ||
454 | |||
455 | /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */ | ||
456 | /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */ | ||
457 | /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */ | ||
458 | /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */ | ||
459 | /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */ | ||
460 | /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */ | ||
461 | DECODE_OR (0xff80f080, 0xfa00f080), | ||
462 | |||
463 | /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */ | ||
464 | /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */ | ||
465 | /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */ | ||
466 | /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */ | ||
467 | DECODE_OR (0xfff0f0c0, 0xfa80f080), | ||
468 | |||
469 | /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */ | ||
470 | DECODE_OR (0xfff0f0f0, 0xfaa0f080), | ||
471 | |||
472 | /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */ | ||
473 | /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */ | ||
474 | /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */ | ||
475 | /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */ | ||
476 | DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, PROBES_T32_MEDIA, | ||
477 | REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), | ||
478 | |||
479 | /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */ | ||
480 | DECODE_OR (0xfff0f0f0, 0xfab0f080), | ||
481 | |||
482 | /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */ | ||
483 | /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */ | ||
484 | /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */ | ||
485 | /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */ | ||
486 | DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, PROBES_T32_REVERSE, | ||
487 | REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)), | ||
488 | |||
489 | /* Other unallocated instructions... */ | ||
490 | DECODE_END | ||
491 | }; | ||
492 | |||
493 | static const union decode_item t32_table_1111_1011_0[] = { | ||
494 | /* Multiply, multiply accumulate, and absolute difference */ | ||
495 | |||
496 | /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */ | ||
497 | DECODE_REJECT (0xfff0f0f0, 0xfb00f010), | ||
498 | /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */ | ||
499 | DECODE_REJECT (0xfff0f0f0, 0xfb70f010), | ||
500 | |||
501 | /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */ | ||
502 | DECODE_OR (0xfff0f0c0, 0xfb10f000), | ||
503 | /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */ | ||
504 | /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */ | ||
505 | /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */ | ||
506 | /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */ | ||
507 | /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */ | ||
508 | /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */ | ||
509 | DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, PROBES_T32_MUL_ADD, | ||
510 | REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), | ||
511 | |||
512 | /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */ | ||
513 | DECODE_REJECT (0xfff000f0, 0xfb700010), | ||
514 | |||
515 | /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */ | ||
516 | DECODE_OR (0xfff000c0, 0xfb100000), | ||
517 | /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */ | ||
518 | /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */ | ||
519 | /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */ | ||
520 | /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */ | ||
521 | /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */ | ||
522 | /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */ | ||
523 | /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */ | ||
524 | /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */ | ||
525 | DECODE_EMULATEX (0xff8000c0, 0xfb000000, PROBES_T32_MUL_ADD2, | ||
526 | REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)), | ||
527 | |||
528 | /* Other unallocated instructions... */ | ||
529 | DECODE_END | ||
530 | }; | ||
531 | |||
532 | static const union decode_item t32_table_1111_1011_1[] = { | ||
533 | /* Long multiply, long multiply accumulate, and divide */ | ||
534 | |||
535 | /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */ | ||
536 | DECODE_OR (0xfff000f0, 0xfbe00060), | ||
537 | /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */ | ||
538 | DECODE_OR (0xfff000c0, 0xfbc00080), | ||
539 | /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */ | ||
540 | /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */ | ||
541 | DECODE_OR (0xffe000e0, 0xfbc000c0), | ||
542 | /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */ | ||
543 | /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */ | ||
544 | /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */ | ||
545 | /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */ | ||
546 | DECODE_EMULATEX (0xff9000f0, 0xfb800000, PROBES_T32_MUL_ADD_LONG, | ||
547 | REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)), | ||
548 | |||
549 | /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */ | ||
550 | /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */ | ||
551 | /* Other unallocated instructions... */ | ||
552 | DECODE_END | ||
553 | }; | ||
554 | |||
555 | const union decode_item probes_decode_thumb32_table[] = { | ||
556 | |||
557 | /* | ||
558 | * Load/store multiple instructions | ||
559 | * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx | ||
560 | */ | ||
561 | DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx), | ||
562 | |||
563 | /* | ||
564 | * Load/store dual, load/store exclusive, table branch | ||
565 | * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx | ||
566 | */ | ||
567 | DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx), | ||
568 | |||
569 | /* | ||
570 | * Data-processing (shifted register) | ||
571 | * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx | ||
572 | */ | ||
573 | DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x), | ||
574 | |||
575 | /* | ||
576 | * Coprocessor instructions | ||
577 | * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx | ||
578 | */ | ||
579 | DECODE_REJECT (0xfc000000, 0xec000000), | ||
580 | |||
581 | /* | ||
582 | * Data-processing (modified immediate) | ||
583 | * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx | ||
584 | */ | ||
585 | DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0), | ||
586 | |||
587 | /* | ||
588 | * Data-processing (plain binary immediate) | ||
589 | * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx | ||
590 | */ | ||
591 | DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0), | ||
592 | |||
593 | /* | ||
594 | * Branches and miscellaneous control | ||
595 | * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx | ||
596 | */ | ||
597 | DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1), | ||
598 | |||
599 | /* | ||
600 | * Advanced SIMD element or structure load/store instructions | ||
601 | * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx | ||
602 | */ | ||
603 | DECODE_REJECT (0xff100000, 0xf9000000), | ||
604 | |||
605 | /* | ||
606 | * Memory hints | ||
607 | * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx | ||
608 | */ | ||
609 | DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111), | ||
610 | |||
611 | /* | ||
612 | * Store single data item | ||
613 | * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx | ||
614 | * Load single data items | ||
615 | * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx | ||
616 | */ | ||
617 | DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x), | ||
618 | |||
619 | /* | ||
620 | * Data-processing (register) | ||
621 | * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx | ||
622 | */ | ||
623 | DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111), | ||
624 | |||
625 | /* | ||
626 | * Multiply, multiply accumulate, and absolute difference | ||
627 | * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx | ||
628 | */ | ||
629 | DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0), | ||
630 | |||
631 | /* | ||
632 | * Long multiply, long multiply accumulate, and divide | ||
633 | * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx | ||
634 | */ | ||
635 | DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1), | ||
636 | |||
637 | /* | ||
638 | * Coprocessor instructions | ||
639 | * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx | ||
640 | */ | ||
641 | DECODE_END | ||
642 | }; | ||
643 | #ifdef CONFIG_ARM_KPROBES_TEST_MODULE | ||
644 | EXPORT_SYMBOL_GPL(probes_decode_thumb32_table); | ||
645 | #endif | ||
646 | |||
647 | static const union decode_item t16_table_1011[] = { | ||
648 | /* Miscellaneous 16-bit instructions */ | ||
649 | |||
650 | /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */ | ||
651 | /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */ | ||
652 | DECODE_SIMULATE (0xff00, 0xb000, PROBES_T16_ADD_SP), | ||
653 | |||
654 | /* CBZ 1011 00x1 xxxx xxxx */ | ||
655 | /* CBNZ 1011 10x1 xxxx xxxx */ | ||
656 | DECODE_SIMULATE (0xf500, 0xb100, PROBES_T16_CBZ), | ||
657 | |||
658 | /* SXTH 1011 0010 00xx xxxx */ | ||
659 | /* SXTB 1011 0010 01xx xxxx */ | ||
660 | /* UXTH 1011 0010 10xx xxxx */ | ||
661 | /* UXTB 1011 0010 11xx xxxx */ | ||
662 | /* REV 1011 1010 00xx xxxx */ | ||
663 | /* REV16 1011 1010 01xx xxxx */ | ||
664 | /* ??? 1011 1010 10xx xxxx */ | ||
665 | /* REVSH 1011 1010 11xx xxxx */ | ||
666 | DECODE_REJECT (0xffc0, 0xba80), | ||
667 | DECODE_EMULATE (0xf500, 0xb000, PROBES_T16_SIGN_EXTEND), | ||
668 | |||
669 | /* PUSH 1011 010x xxxx xxxx */ | ||
670 | DECODE_CUSTOM (0xfe00, 0xb400, PROBES_T16_PUSH), | ||
671 | /* POP 1011 110x xxxx xxxx */ | ||
672 | DECODE_CUSTOM (0xfe00, 0xbc00, PROBES_T16_POP), | ||
673 | |||
674 | /* | ||
675 | * If-Then, and hints | ||
676 | * 1011 1111 xxxx xxxx | ||
677 | */ | ||
678 | |||
679 | /* YIELD 1011 1111 0001 0000 */ | ||
680 | DECODE_OR (0xffff, 0xbf10), | ||
681 | /* SEV 1011 1111 0100 0000 */ | ||
682 | DECODE_EMULATE (0xffff, 0xbf40, PROBES_T16_SEV), | ||
683 | /* NOP 1011 1111 0000 0000 */ | ||
684 | /* WFE 1011 1111 0010 0000 */ | ||
685 | /* WFI 1011 1111 0011 0000 */ | ||
686 | DECODE_SIMULATE (0xffcf, 0xbf00, PROBES_T16_WFE), | ||
687 | /* Unassigned hints 1011 1111 xxxx 0000 */ | ||
688 | DECODE_REJECT (0xff0f, 0xbf00), | ||
689 | /* IT 1011 1111 xxxx xxxx */ | ||
690 | DECODE_CUSTOM (0xff00, 0xbf00, PROBES_T16_IT), | ||
691 | |||
692 | /* SETEND 1011 0110 010x xxxx */ | ||
693 | /* CPS 1011 0110 011x xxxx */ | ||
694 | /* BKPT 1011 1110 xxxx xxxx */ | ||
695 | /* And unallocated instructions... */ | ||
696 | DECODE_END | ||
697 | }; | ||
698 | |||
699 | const union decode_item probes_decode_thumb16_table[] = { | ||
700 | |||
701 | /* | ||
702 | * Shift (immediate), add, subtract, move, and compare | ||
703 | * 00xx xxxx xxxx xxxx | ||
704 | */ | ||
705 | |||
706 | /* CMP (immediate) 0010 1xxx xxxx xxxx */ | ||
707 | DECODE_EMULATE (0xf800, 0x2800, PROBES_T16_CMP), | ||
708 | |||
709 | /* ADD (register) 0001 100x xxxx xxxx */ | ||
710 | /* SUB (register) 0001 101x xxxx xxxx */ | ||
711 | /* LSL (immediate) 0000 0xxx xxxx xxxx */ | ||
712 | /* LSR (immediate) 0000 1xxx xxxx xxxx */ | ||
713 | /* ASR (immediate) 0001 0xxx xxxx xxxx */ | ||
714 | /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */ | ||
715 | /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */ | ||
716 | /* MOV (immediate) 0010 0xxx xxxx xxxx */ | ||
717 | /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */ | ||
718 | /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */ | ||
719 | DECODE_EMULATE (0xc000, 0x0000, PROBES_T16_ADDSUB), | ||
720 | |||
721 | /* | ||
722 | * 16-bit Thumb data-processing instructions | ||
723 | * 0100 00xx xxxx xxxx | ||
724 | */ | ||
725 | |||
726 | /* TST (register) 0100 0010 00xx xxxx */ | ||
727 | DECODE_EMULATE (0xffc0, 0x4200, PROBES_T16_CMP), | ||
728 | /* CMP (register) 0100 0010 10xx xxxx */ | ||
729 | /* CMN (register) 0100 0010 11xx xxxx */ | ||
730 | DECODE_EMULATE (0xff80, 0x4280, PROBES_T16_CMP), | ||
731 | /* AND (register) 0100 0000 00xx xxxx */ | ||
732 | /* EOR (register) 0100 0000 01xx xxxx */ | ||
733 | /* LSL (register) 0100 0000 10xx xxxx */ | ||
734 | /* LSR (register) 0100 0000 11xx xxxx */ | ||
735 | /* ASR (register) 0100 0001 00xx xxxx */ | ||
736 | /* ADC (register) 0100 0001 01xx xxxx */ | ||
737 | /* SBC (register) 0100 0001 10xx xxxx */ | ||
738 | /* ROR (register) 0100 0001 11xx xxxx */ | ||
739 | /* RSB (immediate) 0100 0010 01xx xxxx */ | ||
740 | /* ORR (register) 0100 0011 00xx xxxx */ | ||
741 | /* MUL 0100 0011 00xx xxxx */ | ||
742 | /* BIC (register) 0100 0011 10xx xxxx */ | ||
743 | /* MVN (register) 0100 0011 10xx xxxx */ | ||
744 | DECODE_EMULATE (0xfc00, 0x4000, PROBES_T16_LOGICAL), | ||
745 | |||
746 | /* | ||
747 | * Special data instructions and branch and exchange | ||
748 | * 0100 01xx xxxx xxxx | ||
749 | */ | ||
750 | |||
751 | /* BLX pc 0100 0111 1111 1xxx */ | ||
752 | DECODE_REJECT (0xfff8, 0x47f8), | ||
753 | |||
754 | /* BX (register) 0100 0111 0xxx xxxx */ | ||
755 | /* BLX (register) 0100 0111 1xxx xxxx */ | ||
756 | DECODE_SIMULATE (0xff00, 0x4700, PROBES_T16_BLX), | ||
757 | |||
758 | /* ADD pc, pc 0100 0100 1111 1111 */ | ||
759 | DECODE_REJECT (0xffff, 0x44ff), | ||
760 | |||
761 | /* ADD (register) 0100 0100 xxxx xxxx */ | ||
762 | /* CMP (register) 0100 0101 xxxx xxxx */ | ||
763 | /* MOV (register) 0100 0110 xxxx xxxx */ | ||
764 | DECODE_CUSTOM (0xfc00, 0x4400, PROBES_T16_HIREGOPS), | ||
765 | |||
766 | /* | ||
767 | * Load from Literal Pool | ||
768 | * LDR (literal) 0100 1xxx xxxx xxxx | ||
769 | */ | ||
770 | DECODE_SIMULATE (0xf800, 0x4800, PROBES_T16_LDR_LIT), | ||
771 | |||
772 | /* | ||
773 | * 16-bit Thumb Load/store instructions | ||
774 | * 0101 xxxx xxxx xxxx | ||
775 | * 011x xxxx xxxx xxxx | ||
776 | * 100x xxxx xxxx xxxx | ||
777 | */ | ||
778 | |||
779 | /* STR (register) 0101 000x xxxx xxxx */ | ||
780 | /* STRH (register) 0101 001x xxxx xxxx */ | ||
781 | /* STRB (register) 0101 010x xxxx xxxx */ | ||
782 | /* LDRSB (register) 0101 011x xxxx xxxx */ | ||
783 | /* LDR (register) 0101 100x xxxx xxxx */ | ||
784 | /* LDRH (register) 0101 101x xxxx xxxx */ | ||
785 | /* LDRB (register) 0101 110x xxxx xxxx */ | ||
786 | /* LDRSH (register) 0101 111x xxxx xxxx */ | ||
787 | /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */ | ||
788 | /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */ | ||
789 | /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */ | ||
790 | /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */ | ||
791 | DECODE_EMULATE (0xc000, 0x4000, PROBES_T16_LDRHSTRH), | ||
792 | /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */ | ||
793 | /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */ | ||
794 | DECODE_EMULATE (0xf000, 0x8000, PROBES_T16_LDRHSTRH), | ||
795 | /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */ | ||
796 | /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */ | ||
797 | DECODE_SIMULATE (0xf000, 0x9000, PROBES_T16_LDRSTR), | ||
798 | |||
799 | /* | ||
800 | * Generate PC-/SP-relative address | ||
801 | * ADR (literal) 1010 0xxx xxxx xxxx | ||
802 | * ADD (SP plus immediate) 1010 1xxx xxxx xxxx | ||
803 | */ | ||
804 | DECODE_SIMULATE (0xf000, 0xa000, PROBES_T16_ADR), | ||
805 | |||
806 | /* | ||
807 | * Miscellaneous 16-bit instructions | ||
808 | * 1011 xxxx xxxx xxxx | ||
809 | */ | ||
810 | DECODE_TABLE (0xf000, 0xb000, t16_table_1011), | ||
811 | |||
812 | /* STM 1100 0xxx xxxx xxxx */ | ||
813 | /* LDM 1100 1xxx xxxx xxxx */ | ||
814 | DECODE_EMULATE (0xf000, 0xc000, PROBES_T16_LDMSTM), | ||
815 | |||
816 | /* | ||
817 | * Conditional branch, and Supervisor Call | ||
818 | */ | ||
819 | |||
820 | /* Permanently UNDEFINED 1101 1110 xxxx xxxx */ | ||
821 | /* SVC 1101 1111 xxxx xxxx */ | ||
822 | DECODE_REJECT (0xfe00, 0xde00), | ||
823 | |||
824 | /* Conditional branch 1101 xxxx xxxx xxxx */ | ||
825 | DECODE_CUSTOM (0xf000, 0xd000, PROBES_T16_BRANCH_COND), | ||
826 | |||
827 | /* | ||
828 | * Unconditional branch | ||
829 | * B 1110 0xxx xxxx xxxx | ||
830 | */ | ||
831 | DECODE_SIMULATE (0xf800, 0xe000, PROBES_T16_BRANCH), | ||
832 | |||
833 | DECODE_END | ||
834 | }; | ||
835 | #ifdef CONFIG_ARM_KPROBES_TEST_MODULE | ||
836 | EXPORT_SYMBOL_GPL(probes_decode_thumb16_table); | ||
837 | #endif | ||
838 | |||
839 | static unsigned long __kprobes thumb_check_cc(unsigned long cpsr) | ||
840 | { | ||
841 | if (unlikely(in_it_block(cpsr))) | ||
842 | return probes_condition_checks[current_cond(cpsr)](cpsr); | ||
843 | return true; | ||
844 | } | ||
845 | |||
846 | static void __kprobes thumb16_singlestep(probes_opcode_t opcode, | ||
847 | struct arch_probes_insn *asi, | ||
848 | struct pt_regs *regs) | ||
849 | { | ||
850 | regs->ARM_pc += 2; | ||
851 | asi->insn_handler(opcode, asi, regs); | ||
852 | regs->ARM_cpsr = it_advance(regs->ARM_cpsr); | ||
853 | } | ||
854 | |||
855 | static void __kprobes thumb32_singlestep(probes_opcode_t opcode, | ||
856 | struct arch_probes_insn *asi, | ||
857 | struct pt_regs *regs) | ||
858 | { | ||
859 | regs->ARM_pc += 4; | ||
860 | asi->insn_handler(opcode, asi, regs); | ||
861 | regs->ARM_cpsr = it_advance(regs->ARM_cpsr); | ||
862 | } | ||
863 | |||
864 | enum probes_insn __kprobes | ||
865 | thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
866 | bool emulate, const union decode_action *actions) | ||
867 | { | ||
868 | asi->insn_singlestep = thumb16_singlestep; | ||
869 | asi->insn_check_cc = thumb_check_cc; | ||
870 | return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true, | ||
871 | emulate, actions); | ||
872 | } | ||
873 | |||
874 | enum probes_insn __kprobes | ||
875 | thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
876 | bool emulate, const union decode_action *actions) | ||
877 | { | ||
878 | asi->insn_singlestep = thumb32_singlestep; | ||
879 | asi->insn_check_cc = thumb_check_cc; | ||
880 | return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true, | ||
881 | emulate, actions); | ||
882 | } | ||
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/kernel/probes-thumb.h new file mode 100644 index 000000000000..7c6f6ebe514f --- /dev/null +++ b/arch/arm/kernel/probes-thumb.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/probes-thumb.h | ||
3 | * | ||
4 | * Copyright 2013 Linaro Ltd. | ||
5 | * Written by: David A. Long | ||
6 | * | ||
7 | * The code contained herein is licensed under the GNU General Public | ||
8 | * License. You may obtain a copy of the GNU General Public License | ||
9 | * Version 2 or later at the following locations: | ||
10 | * | ||
11 | * http://www.opensource.org/licenses/gpl-license.html | ||
12 | * http://www.gnu.org/copyleft/gpl.html | ||
13 | */ | ||
14 | |||
15 | #ifndef _ARM_KERNEL_PROBES_THUMB_H | ||
16 | #define _ARM_KERNEL_PROBES_THUMB_H | ||
17 | |||
18 | /* | ||
19 | * True if current instruction is in an IT block. | ||
20 | */ | ||
21 | #define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000) | ||
22 | |||
23 | /* | ||
24 | * Return the condition code to check for the currently executing instruction. | ||
25 | * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if | ||
26 | * in_it_block returns true. | ||
27 | */ | ||
28 | #define current_cond(cpsr) ((cpsr >> 12) & 0xf) | ||
29 | |||
30 | enum probes_t32_action { | ||
31 | PROBES_T32_EMULATE_NONE, | ||
32 | PROBES_T32_SIMULATE_NOP, | ||
33 | PROBES_T32_LDMSTM, | ||
34 | PROBES_T32_LDRDSTRD, | ||
35 | PROBES_T32_TABLE_BRANCH, | ||
36 | PROBES_T32_TST, | ||
37 | PROBES_T32_CMP, | ||
38 | PROBES_T32_MOV, | ||
39 | PROBES_T32_ADDSUB, | ||
40 | PROBES_T32_LOGICAL, | ||
41 | PROBES_T32_ADDWSUBW_PC, | ||
42 | PROBES_T32_ADDWSUBW, | ||
43 | PROBES_T32_MOVW, | ||
44 | PROBES_T32_SAT, | ||
45 | PROBES_T32_BITFIELD, | ||
46 | PROBES_T32_SEV, | ||
47 | PROBES_T32_WFE, | ||
48 | PROBES_T32_MRS, | ||
49 | PROBES_T32_BRANCH_COND, | ||
50 | PROBES_T32_BRANCH, | ||
51 | PROBES_T32_PLDI, | ||
52 | PROBES_T32_LDR_LIT, | ||
53 | PROBES_T32_LDRSTR, | ||
54 | PROBES_T32_SIGN_EXTEND, | ||
55 | PROBES_T32_MEDIA, | ||
56 | PROBES_T32_REVERSE, | ||
57 | PROBES_T32_MUL_ADD, | ||
58 | PROBES_T32_MUL_ADD2, | ||
59 | PROBES_T32_MUL_ADD_LONG, | ||
60 | NUM_PROBES_T32_ACTIONS | ||
61 | }; | ||
62 | |||
63 | enum probes_t16_action { | ||
64 | PROBES_T16_ADD_SP, | ||
65 | PROBES_T16_CBZ, | ||
66 | PROBES_T16_SIGN_EXTEND, | ||
67 | PROBES_T16_PUSH, | ||
68 | PROBES_T16_POP, | ||
69 | PROBES_T16_SEV, | ||
70 | PROBES_T16_WFE, | ||
71 | PROBES_T16_IT, | ||
72 | PROBES_T16_CMP, | ||
73 | PROBES_T16_ADDSUB, | ||
74 | PROBES_T16_LOGICAL, | ||
75 | PROBES_T16_BLX, | ||
76 | PROBES_T16_HIREGOPS, | ||
77 | PROBES_T16_LDR_LIT, | ||
78 | PROBES_T16_LDRHSTRH, | ||
79 | PROBES_T16_LDRSTR, | ||
80 | PROBES_T16_ADR, | ||
81 | PROBES_T16_LDMSTM, | ||
82 | PROBES_T16_BRANCH_COND, | ||
83 | PROBES_T16_BRANCH, | ||
84 | NUM_PROBES_T16_ACTIONS | ||
85 | }; | ||
86 | |||
87 | extern const union decode_item probes_decode_thumb32_table[]; | ||
88 | extern const union decode_item probes_decode_thumb16_table[]; | ||
89 | |||
90 | enum probes_insn __kprobes | ||
91 | thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
92 | bool emulate, const union decode_action *actions); | ||
93 | enum probes_insn __kprobes | ||
94 | thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
95 | bool emulate, const union decode_action *actions); | ||
96 | |||
97 | #endif | ||
diff --git a/arch/arm/kernel/probes.c b/arch/arm/kernel/probes.c new file mode 100644 index 000000000000..b41873f33e69 --- /dev/null +++ b/arch/arm/kernel/probes.c | |||
@@ -0,0 +1,455 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/probes.c | ||
3 | * | ||
4 | * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. | ||
5 | * | ||
6 | * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is | ||
7 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/system_info.h> | ||
17 | #include <asm/ptrace.h> | ||
18 | #include <linux/bug.h> | ||
19 | |||
20 | #include "probes.h" | ||
21 | |||
22 | |||
23 | #ifndef find_str_pc_offset | ||
24 | |||
25 | /* | ||
26 | * For STR and STM instructions, an ARM core may choose to use either | ||
27 | * a +8 or a +12 displacement from the current instruction's address. | ||
28 | * Whichever value is chosen for a given core, it must be the same for | ||
29 | * both instructions and may not change. This function measures it. | ||
30 | */ | ||
31 | |||
32 | int str_pc_offset; | ||
33 | |||
34 | void __init find_str_pc_offset(void) | ||
35 | { | ||
36 | int addr, scratch, ret; | ||
37 | |||
38 | __asm__ ( | ||
39 | "sub %[ret], pc, #4 \n\t" | ||
40 | "str pc, %[addr] \n\t" | ||
41 | "ldr %[scr], %[addr] \n\t" | ||
42 | "sub %[ret], %[scr], %[ret] \n\t" | ||
43 | : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr)); | ||
44 | |||
45 | str_pc_offset = ret; | ||
46 | } | ||
47 | |||
48 | #endif /* !find_str_pc_offset */ | ||
49 | |||
50 | |||
51 | #ifndef test_load_write_pc_interworking | ||
52 | |||
53 | bool load_write_pc_interworks; | ||
54 | |||
55 | void __init test_load_write_pc_interworking(void) | ||
56 | { | ||
57 | int arch = cpu_architecture(); | ||
58 | BUG_ON(arch == CPU_ARCH_UNKNOWN); | ||
59 | load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T; | ||
60 | } | ||
61 | |||
62 | #endif /* !test_load_write_pc_interworking */ | ||
63 | |||
64 | |||
65 | #ifndef test_alu_write_pc_interworking | ||
66 | |||
67 | bool alu_write_pc_interworks; | ||
68 | |||
69 | void __init test_alu_write_pc_interworking(void) | ||
70 | { | ||
71 | int arch = cpu_architecture(); | ||
72 | BUG_ON(arch == CPU_ARCH_UNKNOWN); | ||
73 | alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7; | ||
74 | } | ||
75 | |||
76 | #endif /* !test_alu_write_pc_interworking */ | ||
77 | |||
78 | |||
79 | void __init arm_probes_decode_init(void) | ||
80 | { | ||
81 | find_str_pc_offset(); | ||
82 | test_load_write_pc_interworking(); | ||
83 | test_alu_write_pc_interworking(); | ||
84 | } | ||
85 | |||
86 | |||
87 | static unsigned long __kprobes __check_eq(unsigned long cpsr) | ||
88 | { | ||
89 | return cpsr & PSR_Z_BIT; | ||
90 | } | ||
91 | |||
92 | static unsigned long __kprobes __check_ne(unsigned long cpsr) | ||
93 | { | ||
94 | return (~cpsr) & PSR_Z_BIT; | ||
95 | } | ||
96 | |||
97 | static unsigned long __kprobes __check_cs(unsigned long cpsr) | ||
98 | { | ||
99 | return cpsr & PSR_C_BIT; | ||
100 | } | ||
101 | |||
102 | static unsigned long __kprobes __check_cc(unsigned long cpsr) | ||
103 | { | ||
104 | return (~cpsr) & PSR_C_BIT; | ||
105 | } | ||
106 | |||
107 | static unsigned long __kprobes __check_mi(unsigned long cpsr) | ||
108 | { | ||
109 | return cpsr & PSR_N_BIT; | ||
110 | } | ||
111 | |||
112 | static unsigned long __kprobes __check_pl(unsigned long cpsr) | ||
113 | { | ||
114 | return (~cpsr) & PSR_N_BIT; | ||
115 | } | ||
116 | |||
117 | static unsigned long __kprobes __check_vs(unsigned long cpsr) | ||
118 | { | ||
119 | return cpsr & PSR_V_BIT; | ||
120 | } | ||
121 | |||
122 | static unsigned long __kprobes __check_vc(unsigned long cpsr) | ||
123 | { | ||
124 | return (~cpsr) & PSR_V_BIT; | ||
125 | } | ||
126 | |||
127 | static unsigned long __kprobes __check_hi(unsigned long cpsr) | ||
128 | { | ||
129 | cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | ||
130 | return cpsr & PSR_C_BIT; | ||
131 | } | ||
132 | |||
133 | static unsigned long __kprobes __check_ls(unsigned long cpsr) | ||
134 | { | ||
135 | cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | ||
136 | return (~cpsr) & PSR_C_BIT; | ||
137 | } | ||
138 | |||
139 | static unsigned long __kprobes __check_ge(unsigned long cpsr) | ||
140 | { | ||
141 | cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
142 | return (~cpsr) & PSR_N_BIT; | ||
143 | } | ||
144 | |||
145 | static unsigned long __kprobes __check_lt(unsigned long cpsr) | ||
146 | { | ||
147 | cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
148 | return cpsr & PSR_N_BIT; | ||
149 | } | ||
150 | |||
151 | static unsigned long __kprobes __check_gt(unsigned long cpsr) | ||
152 | { | ||
153 | unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
154 | temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | ||
155 | return (~temp) & PSR_N_BIT; | ||
156 | } | ||
157 | |||
158 | static unsigned long __kprobes __check_le(unsigned long cpsr) | ||
159 | { | ||
160 | unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | ||
161 | temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | ||
162 | return temp & PSR_N_BIT; | ||
163 | } | ||
164 | |||
165 | static unsigned long __kprobes __check_al(unsigned long cpsr) | ||
166 | { | ||
167 | return true; | ||
168 | } | ||
169 | |||
170 | probes_check_cc * const probes_condition_checks[16] = { | ||
171 | &__check_eq, &__check_ne, &__check_cs, &__check_cc, | ||
172 | &__check_mi, &__check_pl, &__check_vs, &__check_vc, | ||
173 | &__check_hi, &__check_ls, &__check_ge, &__check_lt, | ||
174 | &__check_gt, &__check_le, &__check_al, &__check_al | ||
175 | }; | ||
176 | |||
177 | |||
178 | void __kprobes probes_simulate_nop(probes_opcode_t opcode, | ||
179 | struct arch_probes_insn *asi, | ||
180 | struct pt_regs *regs) | ||
181 | { | ||
182 | } | ||
183 | |||
184 | void __kprobes probes_emulate_none(probes_opcode_t opcode, | ||
185 | struct arch_probes_insn *asi, | ||
186 | struct pt_regs *regs) | ||
187 | { | ||
188 | asi->insn_fn(); | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Prepare an instruction slot to receive an instruction for emulating. | ||
193 | * This is done by placing a subroutine return after the location where the | ||
194 | * instruction will be placed. We also modify ARM instructions to be | ||
195 | * unconditional as the condition code will already be checked before any | ||
196 | * emulation handler is called. | ||
197 | */ | ||
198 | static probes_opcode_t __kprobes | ||
199 | prepare_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
200 | bool thumb) | ||
201 | { | ||
202 | #ifdef CONFIG_THUMB2_KERNEL | ||
203 | if (thumb) { | ||
204 | u16 *thumb_insn = (u16 *)asi->insn; | ||
205 | thumb_insn[1] = 0x4770; /* Thumb bx lr */ | ||
206 | thumb_insn[2] = 0x4770; /* Thumb bx lr */ | ||
207 | return insn; | ||
208 | } | ||
209 | asi->insn[1] = 0xe12fff1e; /* ARM bx lr */ | ||
210 | #else | ||
211 | asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */ | ||
212 | #endif | ||
213 | /* Make an ARM instruction unconditional */ | ||
214 | if (insn < 0xe0000000) | ||
215 | insn = (insn | 0xe0000000) & ~0x10000000; | ||
216 | return insn; | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Write a (probably modified) instruction into the slot previously prepared by | ||
221 | * prepare_emulated_insn | ||
222 | */ | ||
223 | static void __kprobes | ||
224 | set_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
225 | bool thumb) | ||
226 | { | ||
227 | #ifdef CONFIG_THUMB2_KERNEL | ||
228 | if (thumb) { | ||
229 | u16 *ip = (u16 *)asi->insn; | ||
230 | if (is_wide_instruction(insn)) | ||
231 | *ip++ = insn >> 16; | ||
232 | *ip++ = insn; | ||
233 | return; | ||
234 | } | ||
235 | #endif | ||
236 | asi->insn[0] = insn; | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * When we modify the register numbers encoded in an instruction to be emulated, | ||
241 | * the new values come from this define. For ARM and 32-bit Thumb instructions | ||
242 | * this gives... | ||
243 | * | ||
244 | * bit position 16 12 8 4 0 | ||
245 | * ---------------+---+---+---+---+---+ | ||
246 | * register r2 r0 r1 -- r3 | ||
247 | */ | ||
248 | #define INSN_NEW_BITS 0x00020103 | ||
249 | |||
250 | /* Each nibble has same value as that at INSN_NEW_BITS bit 16 */ | ||
251 | #define INSN_SAMEAS16_BITS 0x22222222 | ||
252 | |||
253 | /* | ||
254 | * Validate and modify each of the registers encoded in an instruction. | ||
255 | * | ||
256 | * Each nibble in regs contains a value from enum decode_reg_type. For each | ||
257 | * non-zero value, the corresponding nibble in pinsn is validated and modified | ||
258 | * according to the type. | ||
259 | */ | ||
260 | static bool __kprobes decode_regs(probes_opcode_t *pinsn, u32 regs, bool modify) | ||
261 | { | ||
262 | probes_opcode_t insn = *pinsn; | ||
263 | probes_opcode_t mask = 0xf; /* Start at least significant nibble */ | ||
264 | |||
265 | for (; regs != 0; regs >>= 4, mask <<= 4) { | ||
266 | |||
267 | probes_opcode_t new_bits = INSN_NEW_BITS; | ||
268 | |||
269 | switch (regs & 0xf) { | ||
270 | |||
271 | case REG_TYPE_NONE: | ||
272 | /* Nibble not a register, skip to next */ | ||
273 | continue; | ||
274 | |||
275 | case REG_TYPE_ANY: | ||
276 | /* Any register is allowed */ | ||
277 | break; | ||
278 | |||
279 | case REG_TYPE_SAMEAS16: | ||
280 | /* Replace register with same as at bit position 16 */ | ||
281 | new_bits = INSN_SAMEAS16_BITS; | ||
282 | break; | ||
283 | |||
284 | case REG_TYPE_SP: | ||
285 | /* Only allow SP (R13) */ | ||
286 | if ((insn ^ 0xdddddddd) & mask) | ||
287 | goto reject; | ||
288 | break; | ||
289 | |||
290 | case REG_TYPE_PC: | ||
291 | /* Only allow PC (R15) */ | ||
292 | if ((insn ^ 0xffffffff) & mask) | ||
293 | goto reject; | ||
294 | break; | ||
295 | |||
296 | case REG_TYPE_NOSP: | ||
297 | /* Reject SP (R13) */ | ||
298 | if (((insn ^ 0xdddddddd) & mask) == 0) | ||
299 | goto reject; | ||
300 | break; | ||
301 | |||
302 | case REG_TYPE_NOSPPC: | ||
303 | case REG_TYPE_NOSPPCX: | ||
304 | /* Reject SP and PC (R13 and R15) */ | ||
305 | if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0) | ||
306 | goto reject; | ||
307 | break; | ||
308 | |||
309 | case REG_TYPE_NOPCWB: | ||
310 | if (!is_writeback(insn)) | ||
311 | break; /* No writeback, so any register is OK */ | ||
312 | /* fall through... */ | ||
313 | case REG_TYPE_NOPC: | ||
314 | case REG_TYPE_NOPCX: | ||
315 | /* Reject PC (R15) */ | ||
316 | if (((insn ^ 0xffffffff) & mask) == 0) | ||
317 | goto reject; | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | /* Replace value of nibble with new register number... */ | ||
322 | insn &= ~mask; | ||
323 | insn |= new_bits & mask; | ||
324 | } | ||
325 | |||
326 | if (modify) | ||
327 | *pinsn = insn; | ||
328 | |||
329 | return true; | ||
330 | |||
331 | reject: | ||
332 | return false; | ||
333 | } | ||
334 | |||
335 | static const int decode_struct_sizes[NUM_DECODE_TYPES] = { | ||
336 | [DECODE_TYPE_TABLE] = sizeof(struct decode_table), | ||
337 | [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom), | ||
338 | [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate), | ||
339 | [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate), | ||
340 | [DECODE_TYPE_OR] = sizeof(struct decode_or), | ||
341 | [DECODE_TYPE_REJECT] = sizeof(struct decode_reject) | ||
342 | }; | ||
343 | |||
344 | /* | ||
345 | * probes_decode_insn operates on data tables in order to decode an ARM | ||
346 | * architecture instruction onto which a kprobe has been placed. | ||
347 | * | ||
348 | * These instruction decoding tables are a concatenation of entries each | ||
349 | * of which consist of one of the following structs: | ||
350 | * | ||
351 | * decode_table | ||
352 | * decode_custom | ||
353 | * decode_simulate | ||
354 | * decode_emulate | ||
355 | * decode_or | ||
356 | * decode_reject | ||
357 | * | ||
358 | * Each of these starts with a struct decode_header which has the following | ||
359 | * fields: | ||
360 | * | ||
361 | * type_regs | ||
362 | * mask | ||
363 | * value | ||
364 | * | ||
365 | * The least significant DECODE_TYPE_BITS of type_regs contains a value | ||
366 | * from enum decode_type, this indicates which of the decode_* structs | ||
367 | * the entry contains. The value DECODE_TYPE_END indicates the end of the | ||
368 | * table. | ||
369 | * | ||
370 | * When the table is parsed, each entry is checked in turn to see if it | ||
371 | * matches the instruction to be decoded using the test: | ||
372 | * | ||
373 | * (insn & mask) == value | ||
374 | * | ||
375 | * If no match is found before the end of the table is reached then decoding | ||
376 | * fails with INSN_REJECTED. | ||
377 | * | ||
378 | * When a match is found, decode_regs() is called to validate and modify each | ||
379 | * of the registers encoded in the instruction; the data it uses to do this | ||
380 | * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding | ||
381 | * to fail with INSN_REJECTED. | ||
382 | * | ||
383 | * Once the instruction has passed the above tests, further processing | ||
384 | * depends on the type of the table entry's decode struct. | ||
385 | * | ||
386 | */ | ||
387 | int __kprobes | ||
388 | probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
389 | const union decode_item *table, bool thumb, | ||
390 | bool emulate, const union decode_action *actions) | ||
391 | { | ||
392 | const struct decode_header *h = (struct decode_header *)table; | ||
393 | const struct decode_header *next; | ||
394 | bool matched = false; | ||
395 | |||
396 | if (emulate) | ||
397 | insn = prepare_emulated_insn(insn, asi, thumb); | ||
398 | |||
399 | for (;; h = next) { | ||
400 | enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; | ||
401 | u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS; | ||
402 | |||
403 | if (type == DECODE_TYPE_END) | ||
404 | return INSN_REJECTED; | ||
405 | |||
406 | next = (struct decode_header *) | ||
407 | ((uintptr_t)h + decode_struct_sizes[type]); | ||
408 | |||
409 | if (!matched && (insn & h->mask.bits) != h->value.bits) | ||
410 | continue; | ||
411 | |||
412 | if (!decode_regs(&insn, regs, emulate)) | ||
413 | return INSN_REJECTED; | ||
414 | |||
415 | switch (type) { | ||
416 | |||
417 | case DECODE_TYPE_TABLE: { | ||
418 | struct decode_table *d = (struct decode_table *)h; | ||
419 | next = (struct decode_header *)d->table.table; | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | case DECODE_TYPE_CUSTOM: { | ||
424 | struct decode_custom *d = (struct decode_custom *)h; | ||
425 | return actions[d->decoder.action].decoder(insn, asi, h); | ||
426 | } | ||
427 | |||
428 | case DECODE_TYPE_SIMULATE: { | ||
429 | struct decode_simulate *d = (struct decode_simulate *)h; | ||
430 | asi->insn_handler = actions[d->handler.action].handler; | ||
431 | return INSN_GOOD_NO_SLOT; | ||
432 | } | ||
433 | |||
434 | case DECODE_TYPE_EMULATE: { | ||
435 | struct decode_emulate *d = (struct decode_emulate *)h; | ||
436 | |||
437 | if (!emulate) | ||
438 | return actions[d->handler.action].decoder(insn, | ||
439 | asi, h); | ||
440 | |||
441 | asi->insn_handler = actions[d->handler.action].handler; | ||
442 | set_emulated_insn(insn, asi, thumb); | ||
443 | return INSN_GOOD; | ||
444 | } | ||
445 | |||
446 | case DECODE_TYPE_OR: | ||
447 | matched = true; | ||
448 | break; | ||
449 | |||
450 | case DECODE_TYPE_REJECT: | ||
451 | default: | ||
452 | return INSN_REJECTED; | ||
453 | } | ||
454 | } | ||
455 | } | ||
diff --git a/arch/arm/kernel/probes.h b/arch/arm/kernel/probes.h new file mode 100644 index 000000000000..dba9f2466a93 --- /dev/null +++ b/arch/arm/kernel/probes.h | |||
@@ -0,0 +1,407 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/probes.h | ||
3 | * | ||
4 | * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. | ||
5 | * | ||
6 | * Some contents moved here from arch/arm/include/asm/kprobes.h which is | ||
7 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #ifndef _ARM_KERNEL_PROBES_H | ||
20 | #define _ARM_KERNEL_PROBES_H | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/stddef.h> | ||
24 | #include <asm/probes.h> | ||
25 | |||
26 | void __init arm_probes_decode_init(void); | ||
27 | |||
28 | extern probes_check_cc * const probes_condition_checks[16]; | ||
29 | |||
30 | #if __LINUX_ARM_ARCH__ >= 7 | ||
31 | |||
32 | /* str_pc_offset is architecturally defined from ARMv7 onwards */ | ||
33 | #define str_pc_offset 8 | ||
34 | #define find_str_pc_offset() | ||
35 | |||
36 | #else /* __LINUX_ARM_ARCH__ < 7 */ | ||
37 | |||
38 | /* We need a run-time check to determine str_pc_offset */ | ||
39 | extern int str_pc_offset; | ||
40 | void __init find_str_pc_offset(void); | ||
41 | |||
42 | #endif | ||
43 | |||
44 | |||
45 | /* | ||
46 | * Update ITSTATE after normal execution of an IT block instruction. | ||
47 | * | ||
48 | * The 8 IT state bits are split into two parts in CPSR: | ||
49 | * ITSTATE<1:0> are in CPSR<26:25> | ||
50 | * ITSTATE<7:2> are in CPSR<15:10> | ||
51 | */ | ||
52 | static inline unsigned long it_advance(unsigned long cpsr) | ||
53 | { | ||
54 | if ((cpsr & 0x06000400) == 0) { | ||
55 | /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */ | ||
56 | cpsr &= ~PSR_IT_MASK; | ||
57 | } else { | ||
58 | /* We need to shift left ITSTATE<4:0> */ | ||
59 | const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */ | ||
60 | unsigned long it = cpsr & mask; | ||
61 | it <<= 1; | ||
62 | it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */ | ||
63 | it &= mask; | ||
64 | cpsr &= ~mask; | ||
65 | cpsr |= it; | ||
66 | } | ||
67 | return cpsr; | ||
68 | } | ||
69 | |||
70 | static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs) | ||
71 | { | ||
72 | long cpsr = regs->ARM_cpsr; | ||
73 | if (pcv & 0x1) { | ||
74 | cpsr |= PSR_T_BIT; | ||
75 | pcv &= ~0x1; | ||
76 | } else { | ||
77 | cpsr &= ~PSR_T_BIT; | ||
78 | pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */ | ||
79 | } | ||
80 | regs->ARM_cpsr = cpsr; | ||
81 | regs->ARM_pc = pcv; | ||
82 | } | ||
83 | |||
84 | |||
85 | #if __LINUX_ARM_ARCH__ >= 6 | ||
86 | |||
87 | /* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */ | ||
88 | #define load_write_pc_interworks true | ||
89 | #define test_load_write_pc_interworking() | ||
90 | |||
91 | #else /* __LINUX_ARM_ARCH__ < 6 */ | ||
92 | |||
93 | /* We need run-time testing to determine if load_write_pc() should interwork. */ | ||
94 | extern bool load_write_pc_interworks; | ||
95 | void __init test_load_write_pc_interworking(void); | ||
96 | |||
97 | #endif | ||
98 | |||
99 | static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs) | ||
100 | { | ||
101 | if (load_write_pc_interworks) | ||
102 | bx_write_pc(pcv, regs); | ||
103 | else | ||
104 | regs->ARM_pc = pcv; | ||
105 | } | ||
106 | |||
107 | |||
108 | #if __LINUX_ARM_ARCH__ >= 7 | ||
109 | |||
110 | #define alu_write_pc_interworks true | ||
111 | #define test_alu_write_pc_interworking() | ||
112 | |||
113 | #elif __LINUX_ARM_ARCH__ <= 5 | ||
114 | |||
115 | /* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */ | ||
116 | #define alu_write_pc_interworks false | ||
117 | #define test_alu_write_pc_interworking() | ||
118 | |||
119 | #else /* __LINUX_ARM_ARCH__ == 6 */ | ||
120 | |||
121 | /* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */ | ||
122 | extern bool alu_write_pc_interworks; | ||
123 | void __init test_alu_write_pc_interworking(void); | ||
124 | |||
125 | #endif /* __LINUX_ARM_ARCH__ == 6 */ | ||
126 | |||
127 | static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs) | ||
128 | { | ||
129 | if (alu_write_pc_interworks) | ||
130 | bx_write_pc(pcv, regs); | ||
131 | else | ||
132 | regs->ARM_pc = pcv; | ||
133 | } | ||
134 | |||
135 | |||
136 | /* | ||
137 | * Test if load/store instructions writeback the address register. | ||
138 | * if P (bit 24) == 0 or W (bit 21) == 1 | ||
139 | */ | ||
140 | #define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) | ||
141 | |||
142 | /* | ||
143 | * The following definitions and macros are used to build instruction | ||
144 | * decoding tables for use by probes_decode_insn. | ||
145 | * | ||
146 | * These tables are a concatenation of entries each of which consist of one of | ||
147 | * the decode_* structs. All of the fields in every type of decode structure | ||
148 | * are of the union type decode_item, therefore the entire decode table can be | ||
149 | * viewed as an array of these and declared like: | ||
150 | * | ||
151 | * static const union decode_item table_name[] = {}; | ||
152 | * | ||
153 | * In order to construct each entry in the table, macros are used to | ||
154 | * initialise a number of sequential decode_item values in a layout which | ||
155 | * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct | ||
156 | * decode_simulate by initialising four decode_item objects like this... | ||
157 | * | ||
158 | * {.bits = _type}, | ||
159 | * {.bits = _mask}, | ||
160 | * {.bits = _value}, | ||
161 | * {.action = _handler}, | ||
162 | * | ||
163 | * Initialising a specified member of the union means that the compiler | ||
164 | * will produce a warning if the argument is of an incorrect type. | ||
165 | * | ||
166 | * Below is a list of each of the macros used to initialise entries and a | ||
167 | * description of the action performed when that entry is matched to an | ||
168 | * instruction. A match is found when (instruction & mask) == value. | ||
169 | * | ||
170 | * DECODE_TABLE(mask, value, table) | ||
171 | * Instruction decoding jumps to parsing the new sub-table 'table'. | ||
172 | * | ||
173 | * DECODE_CUSTOM(mask, value, decoder) | ||
174 | * The value of 'decoder' is used as an index into the array of | ||
175 | * action functions, and the retrieved decoder function is invoked | ||
176 | * to complete decoding of the instruction. | ||
177 | * | ||
178 | * DECODE_SIMULATE(mask, value, handler) | ||
179 | * The probes instruction handler is set to the value found by | ||
180 | * indexing into the action array using the value of 'handler'. This | ||
181 | * will be used to simulate the instruction when the probe is hit. | ||
182 | * Decoding returns with INSN_GOOD_NO_SLOT. | ||
183 | * | ||
184 | * DECODE_EMULATE(mask, value, handler) | ||
185 | * The probes instruction handler is set to the value found by | ||
186 | * indexing into the action array using the value of 'handler'. This | ||
187 | * will be used to emulate the instruction when the probe is hit. The | ||
188 | * modified instruction (see below) is placed in the probes instruction | ||
189 | * slot so it may be called by the emulation code. Decoding returns | ||
190 | * with INSN_GOOD. | ||
191 | * | ||
192 | * DECODE_REJECT(mask, value) | ||
193 | * Instruction decoding fails with INSN_REJECTED | ||
194 | * | ||
195 | * DECODE_OR(mask, value) | ||
196 | * This allows the mask/value test of multiple table entries to be | ||
197 | * logically ORed. Once an 'or' entry is matched the decoding action to | ||
198 | * be performed is that of the next entry which isn't an 'or'. E.g. | ||
199 | * | ||
200 | * DECODE_OR (mask1, value1) | ||
201 | * DECODE_OR (mask2, value2) | ||
202 | * DECODE_SIMULATE (mask3, value3, simulation_handler) | ||
203 | * | ||
204 | * This means that if any of the three mask/value pairs match the | ||
205 | * instruction being decoded, then 'simulation_handler' will be used | ||
206 | * for it. | ||
207 | * | ||
208 | * Both the SIMULATE and EMULATE macros have a second form which take an | ||
209 | * additional 'regs' argument. | ||
210 | * | ||
211 | * DECODE_SIMULATEX(mask, value, handler, regs) | ||
212 | * DECODE_EMULATEX (mask, value, handler, regs) | ||
213 | * | ||
214 | * These are used to specify what kind of CPU register is encoded in each of the | ||
215 | * least significant 5 nibbles of the instruction being decoded. The regs value | ||
216 | * is specified using the REGS macro, this takes any of the REG_TYPE_* values | ||
217 | * from enum decode_reg_type as arguments; only the '*' part of the name is | ||
218 | * given. E.g. | ||
219 | * | ||
220 | * REGS(0, ANY, NOPC, 0, ANY) | ||
221 | * | ||
222 | * This indicates an instruction is encoded like: | ||
223 | * | ||
224 | * bits 19..16 ignore | ||
225 | * bits 15..12 any register allowed here | ||
226 | * bits 11.. 8 any register except PC allowed here | ||
227 | * bits 7.. 4 ignore | ||
228 | * bits 3.. 0 any register allowed here | ||
229 | * | ||
230 | * This register specification is checked after a decode table entry is found to | ||
231 | * match an instruction (through the mask/value test). Any invalid register then | ||
232 | * found in the instruction will cause decoding to fail with INSN_REJECTED. In | ||
233 | * the above example this would happen if bits 11..8 of the instruction were | ||
234 | * 1111, indicating R15 or PC. | ||
235 | * | ||
236 | * As well as checking for legal combinations of registers, this data is also | ||
237 | * used to modify the registers encoded in the instructions so that an | ||
238 | * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.) | ||
239 | * | ||
240 | * Here is a real example which matches ARM instructions of the form | ||
241 | * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>" | ||
242 | * | ||
243 | * DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG, | ||
244 | * REGS(ANY, ANY, NOPC, 0, ANY)), | ||
245 | * ^ ^ ^ ^ | ||
246 | * Rn Rd Rs Rm | ||
247 | * | ||
248 | * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because | ||
249 | * Rs == R15 | ||
250 | * | ||
251 | * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the | ||
252 | * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into | ||
253 | * the kprobes instruction slot. This can then be called later by the handler | ||
254 | * function emulate_rd12rn16rm0rs8_rwflags (a pointer to which is retrieved from | ||
255 | * the indicated slot in the action array), in order to simulate the instruction. | ||
256 | */ | ||
257 | |||
258 | enum decode_type { | ||
259 | DECODE_TYPE_END, | ||
260 | DECODE_TYPE_TABLE, | ||
261 | DECODE_TYPE_CUSTOM, | ||
262 | DECODE_TYPE_SIMULATE, | ||
263 | DECODE_TYPE_EMULATE, | ||
264 | DECODE_TYPE_OR, | ||
265 | DECODE_TYPE_REJECT, | ||
266 | NUM_DECODE_TYPES /* Must be last enum */ | ||
267 | }; | ||
268 | |||
269 | #define DECODE_TYPE_BITS 4 | ||
270 | #define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1) | ||
271 | |||
272 | enum decode_reg_type { | ||
273 | REG_TYPE_NONE = 0, /* Not a register, ignore */ | ||
274 | REG_TYPE_ANY, /* Any register allowed */ | ||
275 | REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */ | ||
276 | REG_TYPE_SP, /* Register must be SP */ | ||
277 | REG_TYPE_PC, /* Register must be PC */ | ||
278 | REG_TYPE_NOSP, /* Register must not be SP */ | ||
279 | REG_TYPE_NOSPPC, /* Register must not be SP or PC */ | ||
280 | REG_TYPE_NOPC, /* Register must not be PC */ | ||
281 | REG_TYPE_NOPCWB, /* No PC if load/store write-back flag also set */ | ||
282 | |||
283 | /* The following types are used when the encoding for PC indicates | ||
284 | * another instruction form. This distiction only matters for test | ||
285 | * case coverage checks. | ||
286 | */ | ||
287 | REG_TYPE_NOPCX, /* Register must not be PC */ | ||
288 | REG_TYPE_NOSPPCX, /* Register must not be SP or PC */ | ||
289 | |||
290 | /* Alias to allow '0' arg to be used in REGS macro. */ | ||
291 | REG_TYPE_0 = REG_TYPE_NONE | ||
292 | }; | ||
293 | |||
294 | #define REGS(r16, r12, r8, r4, r0) \ | ||
295 | (((REG_TYPE_##r16) << 16) + \ | ||
296 | ((REG_TYPE_##r12) << 12) + \ | ||
297 | ((REG_TYPE_##r8) << 8) + \ | ||
298 | ((REG_TYPE_##r4) << 4) + \ | ||
299 | (REG_TYPE_##r0)) | ||
300 | |||
301 | union decode_item { | ||
302 | u32 bits; | ||
303 | const union decode_item *table; | ||
304 | int action; | ||
305 | }; | ||
306 | |||
307 | struct decode_header; | ||
308 | typedef enum probes_insn (probes_custom_decode_t)(probes_opcode_t, | ||
309 | struct arch_probes_insn *, | ||
310 | const struct decode_header *); | ||
311 | |||
312 | union decode_action { | ||
313 | probes_insn_handler_t *handler; | ||
314 | probes_custom_decode_t *decoder; | ||
315 | }; | ||
316 | |||
317 | #define DECODE_END \ | ||
318 | {.bits = DECODE_TYPE_END} | ||
319 | |||
320 | |||
321 | struct decode_header { | ||
322 | union decode_item type_regs; | ||
323 | union decode_item mask; | ||
324 | union decode_item value; | ||
325 | }; | ||
326 | |||
327 | #define DECODE_HEADER(_type, _mask, _value, _regs) \ | ||
328 | {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \ | ||
329 | {.bits = (_mask)}, \ | ||
330 | {.bits = (_value)} | ||
331 | |||
332 | |||
333 | struct decode_table { | ||
334 | struct decode_header header; | ||
335 | union decode_item table; | ||
336 | }; | ||
337 | |||
338 | #define DECODE_TABLE(_mask, _value, _table) \ | ||
339 | DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \ | ||
340 | {.table = (_table)} | ||
341 | |||
342 | |||
343 | struct decode_custom { | ||
344 | struct decode_header header; | ||
345 | union decode_item decoder; | ||
346 | }; | ||
347 | |||
348 | #define DECODE_CUSTOM(_mask, _value, _decoder) \ | ||
349 | DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \ | ||
350 | {.action = (_decoder)} | ||
351 | |||
352 | |||
353 | struct decode_simulate { | ||
354 | struct decode_header header; | ||
355 | union decode_item handler; | ||
356 | }; | ||
357 | |||
358 | #define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \ | ||
359 | DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \ | ||
360 | {.action = (_handler)} | ||
361 | |||
362 | #define DECODE_SIMULATE(_mask, _value, _handler) \ | ||
363 | DECODE_SIMULATEX(_mask, _value, _handler, 0) | ||
364 | |||
365 | |||
366 | struct decode_emulate { | ||
367 | struct decode_header header; | ||
368 | union decode_item handler; | ||
369 | }; | ||
370 | |||
371 | #define DECODE_EMULATEX(_mask, _value, _handler, _regs) \ | ||
372 | DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \ | ||
373 | {.action = (_handler)} | ||
374 | |||
375 | #define DECODE_EMULATE(_mask, _value, _handler) \ | ||
376 | DECODE_EMULATEX(_mask, _value, _handler, 0) | ||
377 | |||
378 | |||
379 | struct decode_or { | ||
380 | struct decode_header header; | ||
381 | }; | ||
382 | |||
383 | #define DECODE_OR(_mask, _value) \ | ||
384 | DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0) | ||
385 | |||
386 | enum probes_insn { | ||
387 | INSN_REJECTED, | ||
388 | INSN_GOOD, | ||
389 | INSN_GOOD_NO_SLOT | ||
390 | }; | ||
391 | |||
392 | struct decode_reject { | ||
393 | struct decode_header header; | ||
394 | }; | ||
395 | |||
396 | #define DECODE_REJECT(_mask, _value) \ | ||
397 | DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0) | ||
398 | |||
399 | probes_insn_handler_t probes_simulate_nop; | ||
400 | probes_insn_handler_t probes_emulate_none; | ||
401 | |||
402 | int __kprobes | ||
403 | probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
404 | const union decode_item *table, bool thumb, bool emulate, | ||
405 | const union decode_action *actions); | ||
406 | |||
407 | #endif | ||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b0df9761de6d..1e8b030dbefd 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -731,7 +731,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) | |||
731 | kernel_data.end = virt_to_phys(_end - 1); | 731 | kernel_data.end = virt_to_phys(_end - 1); |
732 | 732 | ||
733 | for_each_memblock(memory, region) { | 733 | for_each_memblock(memory, region) { |
734 | res = memblock_virt_alloc_low(sizeof(*res), 0); | 734 | res = memblock_virt_alloc(sizeof(*res), 0); |
735 | res->name = "System RAM"; | 735 | res->name = "System RAM"; |
736 | res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); | 736 | res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); |
737 | res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; | 737 | res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 04d63880037f..bd1983437205 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/personality.h> | 13 | #include <linux/personality.h> |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <linux/tracehook.h> | 15 | #include <linux/tracehook.h> |
16 | #include <linux/uprobes.h> | ||
16 | 17 | ||
17 | #include <asm/elf.h> | 18 | #include <asm/elf.h> |
18 | #include <asm/cacheflush.h> | 19 | #include <asm/cacheflush.h> |
@@ -590,6 +591,9 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) | |||
590 | return restart; | 591 | return restart; |
591 | } | 592 | } |
592 | syscall = 0; | 593 | syscall = 0; |
594 | } else if (thread_flags & _TIF_UPROBE) { | ||
595 | clear_thread_flag(TIF_UPROBE); | ||
596 | uprobe_notify_resume(regs); | ||
593 | } else { | 597 | } else { |
594 | clear_thread_flag(TIF_NOTIFY_RESUME); | 598 | clear_thread_flag(TIF_NOTIFY_RESUME); |
595 | tracehook_notify_resume(regs); | 599 | tracehook_notify_resume(regs); |
diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/kernel/uprobes-arm.c new file mode 100644 index 000000000000..d3b655ff17da --- /dev/null +++ b/arch/arm/kernel/uprobes-arm.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Rabin Vincent <rabin at rab.in> | ||
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 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/stddef.h> | ||
12 | #include <linux/wait.h> | ||
13 | #include <linux/uprobes.h> | ||
14 | #include <linux/module.h> | ||
15 | |||
16 | #include "probes.h" | ||
17 | #include "probes-arm.h" | ||
18 | #include "uprobes.h" | ||
19 | |||
20 | static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs) | ||
21 | { | ||
22 | probes_opcode_t insn = __mem_to_opcode_arm(*pinsn); | ||
23 | probes_opcode_t temp; | ||
24 | probes_opcode_t mask; | ||
25 | int freereg; | ||
26 | u32 free = 0xffff; | ||
27 | u32 regs; | ||
28 | |||
29 | for (regs = oregs; regs; regs >>= 4, insn >>= 4) { | ||
30 | if ((regs & 0xf) == REG_TYPE_NONE) | ||
31 | continue; | ||
32 | |||
33 | free &= ~(1 << (insn & 0xf)); | ||
34 | } | ||
35 | |||
36 | /* No PC, no problem */ | ||
37 | if (free & (1 << 15)) | ||
38 | return 15; | ||
39 | |||
40 | if (!free) | ||
41 | return -1; | ||
42 | |||
43 | /* | ||
44 | * fls instead of ffs ensures that for "ldrd r0, r1, [pc]" we would | ||
45 | * pick LR instead of R1. | ||
46 | */ | ||
47 | freereg = free = fls(free) - 1; | ||
48 | |||
49 | temp = __mem_to_opcode_arm(*pinsn); | ||
50 | insn = temp; | ||
51 | regs = oregs; | ||
52 | mask = 0xf; | ||
53 | |||
54 | for (; regs; regs >>= 4, mask <<= 4, free <<= 4, temp >>= 4) { | ||
55 | if ((regs & 0xf) == REG_TYPE_NONE) | ||
56 | continue; | ||
57 | |||
58 | if ((temp & 0xf) != 15) | ||
59 | continue; | ||
60 | |||
61 | insn &= ~mask; | ||
62 | insn |= free & mask; | ||
63 | } | ||
64 | |||
65 | *pinsn = __opcode_to_mem_arm(insn); | ||
66 | return freereg; | ||
67 | } | ||
68 | |||
69 | static void uprobe_set_pc(struct arch_uprobe *auprobe, | ||
70 | struct arch_uprobe_task *autask, | ||
71 | struct pt_regs *regs) | ||
72 | { | ||
73 | u32 pcreg = auprobe->pcreg; | ||
74 | |||
75 | autask->backup = regs->uregs[pcreg]; | ||
76 | regs->uregs[pcreg] = regs->ARM_pc + 8; | ||
77 | } | ||
78 | |||
79 | static void uprobe_unset_pc(struct arch_uprobe *auprobe, | ||
80 | struct arch_uprobe_task *autask, | ||
81 | struct pt_regs *regs) | ||
82 | { | ||
83 | /* PC will be taken care of by common code */ | ||
84 | regs->uregs[auprobe->pcreg] = autask->backup; | ||
85 | } | ||
86 | |||
87 | static void uprobe_aluwrite_pc(struct arch_uprobe *auprobe, | ||
88 | struct arch_uprobe_task *autask, | ||
89 | struct pt_regs *regs) | ||
90 | { | ||
91 | u32 pcreg = auprobe->pcreg; | ||
92 | |||
93 | alu_write_pc(regs->uregs[pcreg], regs); | ||
94 | regs->uregs[pcreg] = autask->backup; | ||
95 | } | ||
96 | |||
97 | static void uprobe_write_pc(struct arch_uprobe *auprobe, | ||
98 | struct arch_uprobe_task *autask, | ||
99 | struct pt_regs *regs) | ||
100 | { | ||
101 | u32 pcreg = auprobe->pcreg; | ||
102 | |||
103 | load_write_pc(regs->uregs[pcreg], regs); | ||
104 | regs->uregs[pcreg] = autask->backup; | ||
105 | } | ||
106 | |||
107 | enum probes_insn | ||
108 | decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
109 | const struct decode_header *d) | ||
110 | { | ||
111 | struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe, | ||
112 | asi); | ||
113 | struct decode_emulate *decode = (struct decode_emulate *) d; | ||
114 | u32 regs = decode->header.type_regs.bits >> DECODE_TYPE_BITS; | ||
115 | int reg; | ||
116 | |||
117 | reg = uprobes_substitute_pc(&auprobe->ixol[0], regs); | ||
118 | if (reg == 15) | ||
119 | return INSN_GOOD; | ||
120 | |||
121 | if (reg == -1) | ||
122 | return INSN_REJECTED; | ||
123 | |||
124 | auprobe->pcreg = reg; | ||
125 | auprobe->prehandler = uprobe_set_pc; | ||
126 | auprobe->posthandler = uprobe_unset_pc; | ||
127 | |||
128 | return INSN_GOOD; | ||
129 | } | ||
130 | |||
131 | enum probes_insn | ||
132 | decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
133 | const struct decode_header *d, bool alu) | ||
134 | { | ||
135 | struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe, | ||
136 | asi); | ||
137 | enum probes_insn ret = decode_pc_ro(insn, asi, d); | ||
138 | |||
139 | if (((insn >> 12) & 0xf) == 15) | ||
140 | auprobe->posthandler = alu ? uprobe_aluwrite_pc | ||
141 | : uprobe_write_pc; | ||
142 | |||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | enum probes_insn | ||
147 | decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn, | ||
148 | struct arch_probes_insn *asi, | ||
149 | const struct decode_header *d) | ||
150 | { | ||
151 | return decode_wb_pc(insn, asi, d, true); | ||
152 | } | ||
153 | |||
154 | enum probes_insn | ||
155 | decode_ldr(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
156 | const struct decode_header *d) | ||
157 | { | ||
158 | return decode_wb_pc(insn, asi, d, false); | ||
159 | } | ||
160 | |||
161 | enum probes_insn | ||
162 | uprobe_decode_ldmstm(probes_opcode_t insn, | ||
163 | struct arch_probes_insn *asi, | ||
164 | const struct decode_header *d) | ||
165 | { | ||
166 | struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe, | ||
167 | asi); | ||
168 | unsigned reglist = insn & 0xffff; | ||
169 | int rn = (insn >> 16) & 0xf; | ||
170 | int lbit = insn & (1 << 20); | ||
171 | unsigned used = reglist | (1 << rn); | ||
172 | |||
173 | if (rn == 15) | ||
174 | return INSN_REJECTED; | ||
175 | |||
176 | if (!(used & (1 << 15))) | ||
177 | return INSN_GOOD; | ||
178 | |||
179 | if (used & (1 << 14)) | ||
180 | return INSN_REJECTED; | ||
181 | |||
182 | /* Use LR instead of PC */ | ||
183 | insn ^= 0xc000; | ||
184 | |||
185 | auprobe->pcreg = 14; | ||
186 | auprobe->ixol[0] = __opcode_to_mem_arm(insn); | ||
187 | |||
188 | auprobe->prehandler = uprobe_set_pc; | ||
189 | if (lbit) | ||
190 | auprobe->posthandler = uprobe_write_pc; | ||
191 | else | ||
192 | auprobe->posthandler = uprobe_unset_pc; | ||
193 | |||
194 | return INSN_GOOD; | ||
195 | } | ||
196 | |||
197 | const union decode_action uprobes_probes_actions[] = { | ||
198 | [PROBES_EMULATE_NONE] = {.handler = probes_simulate_nop}, | ||
199 | [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop}, | ||
200 | [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop}, | ||
201 | [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop}, | ||
202 | [PROBES_BRANCH_IMM] = {.handler = simulate_blx1}, | ||
203 | [PROBES_MRS] = {.handler = simulate_mrs}, | ||
204 | [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx}, | ||
205 | [PROBES_CLZ] = {.handler = probes_simulate_nop}, | ||
206 | [PROBES_SATURATING_ARITHMETIC] = {.handler = probes_simulate_nop}, | ||
207 | [PROBES_MUL1] = {.handler = probes_simulate_nop}, | ||
208 | [PROBES_MUL2] = {.handler = probes_simulate_nop}, | ||
209 | [PROBES_SWP] = {.handler = probes_simulate_nop}, | ||
210 | [PROBES_LDRSTRD] = {.decoder = decode_pc_ro}, | ||
211 | [PROBES_LOAD_EXTRA] = {.decoder = decode_pc_ro}, | ||
212 | [PROBES_LOAD] = {.decoder = decode_ldr}, | ||
213 | [PROBES_STORE_EXTRA] = {.decoder = decode_pc_ro}, | ||
214 | [PROBES_STORE] = {.decoder = decode_pc_ro}, | ||
215 | [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp}, | ||
216 | [PROBES_DATA_PROCESSING_REG] = { | ||
217 | .decoder = decode_rd12rn16rm0rs8_rwflags}, | ||
218 | [PROBES_DATA_PROCESSING_IMM] = { | ||
219 | .decoder = decode_rd12rn16rm0rs8_rwflags}, | ||
220 | [PROBES_MOV_HALFWORD] = {.handler = probes_simulate_nop}, | ||
221 | [PROBES_SEV] = {.handler = probes_simulate_nop}, | ||
222 | [PROBES_WFE] = {.handler = probes_simulate_nop}, | ||
223 | [PROBES_SATURATE] = {.handler = probes_simulate_nop}, | ||
224 | [PROBES_REV] = {.handler = probes_simulate_nop}, | ||
225 | [PROBES_MMI] = {.handler = probes_simulate_nop}, | ||
226 | [PROBES_PACK] = {.handler = probes_simulate_nop}, | ||
227 | [PROBES_EXTEND] = {.handler = probes_simulate_nop}, | ||
228 | [PROBES_EXTEND_ADD] = {.handler = probes_simulate_nop}, | ||
229 | [PROBES_MUL_ADD_LONG] = {.handler = probes_simulate_nop}, | ||
230 | [PROBES_MUL_ADD] = {.handler = probes_simulate_nop}, | ||
231 | [PROBES_BITFIELD] = {.handler = probes_simulate_nop}, | ||
232 | [PROBES_BRANCH] = {.handler = simulate_bbl}, | ||
233 | [PROBES_LDMSTM] = {.decoder = uprobe_decode_ldmstm} | ||
234 | }; | ||
diff --git a/arch/arm/kernel/uprobes.c b/arch/arm/kernel/uprobes.c new file mode 100644 index 000000000000..f9bacee973bf --- /dev/null +++ b/arch/arm/kernel/uprobes.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Rabin Vincent <rabin at rab.in> | ||
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 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/stddef.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/highmem.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/uprobes.h> | ||
15 | #include <linux/notifier.h> | ||
16 | |||
17 | #include <asm/opcodes.h> | ||
18 | #include <asm/traps.h> | ||
19 | |||
20 | #include "probes.h" | ||
21 | #include "probes-arm.h" | ||
22 | #include "uprobes.h" | ||
23 | |||
24 | #define UPROBE_TRAP_NR UINT_MAX | ||
25 | |||
26 | bool is_swbp_insn(uprobe_opcode_t *insn) | ||
27 | { | ||
28 | return (__mem_to_opcode_arm(*insn) & 0x0fffffff) == | ||
29 | (UPROBE_SWBP_ARM_INSN & 0x0fffffff); | ||
30 | } | ||
31 | |||
32 | int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, | ||
33 | unsigned long vaddr) | ||
34 | { | ||
35 | return uprobe_write_opcode(mm, vaddr, | ||
36 | __opcode_to_mem_arm(auprobe->bpinsn)); | ||
37 | } | ||
38 | |||
39 | bool arch_uprobe_ignore(struct arch_uprobe *auprobe, struct pt_regs *regs) | ||
40 | { | ||
41 | if (!auprobe->asi.insn_check_cc(regs->ARM_cpsr)) { | ||
42 | regs->ARM_pc += 4; | ||
43 | return true; | ||
44 | } | ||
45 | |||
46 | return false; | ||
47 | } | ||
48 | |||
49 | bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) | ||
50 | { | ||
51 | probes_opcode_t opcode; | ||
52 | |||
53 | if (!auprobe->simulate) | ||
54 | return false; | ||
55 | |||
56 | opcode = __mem_to_opcode_arm(*(unsigned int *) auprobe->insn); | ||
57 | |||
58 | auprobe->asi.insn_singlestep(opcode, &auprobe->asi, regs); | ||
59 | |||
60 | return true; | ||
61 | } | ||
62 | |||
63 | unsigned long | ||
64 | arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, | ||
65 | struct pt_regs *regs) | ||
66 | { | ||
67 | unsigned long orig_ret_vaddr; | ||
68 | |||
69 | orig_ret_vaddr = regs->ARM_lr; | ||
70 | /* Replace the return addr with trampoline addr */ | ||
71 | regs->ARM_lr = trampoline_vaddr; | ||
72 | return orig_ret_vaddr; | ||
73 | } | ||
74 | |||
75 | int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, | ||
76 | unsigned long addr) | ||
77 | { | ||
78 | unsigned int insn; | ||
79 | unsigned int bpinsn; | ||
80 | enum probes_insn ret; | ||
81 | |||
82 | /* Thumb not yet support */ | ||
83 | if (addr & 0x3) | ||
84 | return -EINVAL; | ||
85 | |||
86 | insn = __mem_to_opcode_arm(*(unsigned int *)auprobe->insn); | ||
87 | auprobe->ixol[0] = __opcode_to_mem_arm(insn); | ||
88 | auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN); | ||
89 | |||
90 | ret = arm_probes_decode_insn(insn, &auprobe->asi, false, | ||
91 | uprobes_probes_actions); | ||
92 | switch (ret) { | ||
93 | case INSN_REJECTED: | ||
94 | return -EINVAL; | ||
95 | |||
96 | case INSN_GOOD_NO_SLOT: | ||
97 | auprobe->simulate = true; | ||
98 | break; | ||
99 | |||
100 | case INSN_GOOD: | ||
101 | default: | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | bpinsn = UPROBE_SWBP_ARM_INSN & 0x0fffffff; | ||
106 | if (insn >= 0xe0000000) | ||
107 | bpinsn |= 0xe0000000; /* Unconditional instruction */ | ||
108 | else | ||
109 | bpinsn |= insn & 0xf0000000; /* Copy condition from insn */ | ||
110 | |||
111 | auprobe->bpinsn = bpinsn; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) | ||
117 | { | ||
118 | struct uprobe_task *utask = current->utask; | ||
119 | |||
120 | if (auprobe->prehandler) | ||
121 | auprobe->prehandler(auprobe, &utask->autask, regs); | ||
122 | |||
123 | utask->autask.saved_trap_no = current->thread.trap_no; | ||
124 | current->thread.trap_no = UPROBE_TRAP_NR; | ||
125 | regs->ARM_pc = utask->xol_vaddr; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) | ||
131 | { | ||
132 | struct uprobe_task *utask = current->utask; | ||
133 | |||
134 | WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NR); | ||
135 | |||
136 | current->thread.trap_no = utask->autask.saved_trap_no; | ||
137 | regs->ARM_pc = utask->vaddr + 4; | ||
138 | |||
139 | if (auprobe->posthandler) | ||
140 | auprobe->posthandler(auprobe, &utask->autask, regs); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | bool arch_uprobe_xol_was_trapped(struct task_struct *t) | ||
146 | { | ||
147 | if (t->thread.trap_no != UPROBE_TRAP_NR) | ||
148 | return true; | ||
149 | |||
150 | return false; | ||
151 | } | ||
152 | |||
153 | void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) | ||
154 | { | ||
155 | struct uprobe_task *utask = current->utask; | ||
156 | |||
157 | current->thread.trap_no = utask->autask.saved_trap_no; | ||
158 | instruction_pointer_set(regs, utask->vaddr); | ||
159 | } | ||
160 | |||
161 | int arch_uprobe_exception_notify(struct notifier_block *self, | ||
162 | unsigned long val, void *data) | ||
163 | { | ||
164 | return NOTIFY_DONE; | ||
165 | } | ||
166 | |||
167 | static int uprobe_trap_handler(struct pt_regs *regs, unsigned int instr) | ||
168 | { | ||
169 | unsigned long flags; | ||
170 | |||
171 | local_irq_save(flags); | ||
172 | instr &= 0x0fffffff; | ||
173 | if (instr == (UPROBE_SWBP_ARM_INSN & 0x0fffffff)) | ||
174 | uprobe_pre_sstep_notifier(regs); | ||
175 | else if (instr == (UPROBE_SS_ARM_INSN & 0x0fffffff)) | ||
176 | uprobe_post_sstep_notifier(regs); | ||
177 | local_irq_restore(flags); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) | ||
183 | { | ||
184 | return instruction_pointer(regs); | ||
185 | } | ||
186 | |||
187 | static struct undef_hook uprobes_arm_break_hook = { | ||
188 | .instr_mask = 0x0fffffff, | ||
189 | .instr_val = (UPROBE_SWBP_ARM_INSN & 0x0fffffff), | ||
190 | .cpsr_mask = MODE_MASK, | ||
191 | .cpsr_val = USR_MODE, | ||
192 | .fn = uprobe_trap_handler, | ||
193 | }; | ||
194 | |||
195 | static struct undef_hook uprobes_arm_ss_hook = { | ||
196 | .instr_mask = 0x0fffffff, | ||
197 | .instr_val = (UPROBE_SS_ARM_INSN & 0x0fffffff), | ||
198 | .cpsr_mask = MODE_MASK, | ||
199 | .cpsr_val = USR_MODE, | ||
200 | .fn = uprobe_trap_handler, | ||
201 | }; | ||
202 | |||
203 | static int arch_uprobes_init(void) | ||
204 | { | ||
205 | register_undef_hook(&uprobes_arm_break_hook); | ||
206 | register_undef_hook(&uprobes_arm_ss_hook); | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | device_initcall(arch_uprobes_init); | ||
diff --git a/arch/arm/kernel/uprobes.h b/arch/arm/kernel/uprobes.h new file mode 100644 index 000000000000..1d0c12dfbd03 --- /dev/null +++ b/arch/arm/kernel/uprobes.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Rabin Vincent <rabin at rab.in> | ||
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 | |||
9 | #ifndef __ARM_KERNEL_UPROBES_H | ||
10 | #define __ARM_KERNEL_UPROBES_H | ||
11 | |||
12 | enum probes_insn uprobe_decode_ldmstm(probes_opcode_t insn, | ||
13 | struct arch_probes_insn *asi, | ||
14 | const struct decode_header *d); | ||
15 | |||
16 | enum probes_insn decode_ldr(probes_opcode_t insn, | ||
17 | struct arch_probes_insn *asi, | ||
18 | const struct decode_header *d); | ||
19 | |||
20 | enum probes_insn | ||
21 | decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn, | ||
22 | struct arch_probes_insn *asi, | ||
23 | const struct decode_header *d); | ||
24 | |||
25 | enum probes_insn | ||
26 | decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
27 | const struct decode_header *d, bool alu); | ||
28 | |||
29 | enum probes_insn | ||
30 | decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi, | ||
31 | const struct decode_header *d); | ||
32 | |||
33 | extern const union decode_action uprobes_probes_actions[]; | ||
34 | |||
35 | #endif | ||
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 1d8248ea5669..bd18bb8b2770 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -878,7 +878,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, | |||
878 | unsigned long cmd, | 878 | unsigned long cmd, |
879 | void *v) | 879 | void *v) |
880 | { | 880 | { |
881 | if (cmd == CPU_PM_EXIT) { | 881 | if (cmd == CPU_PM_EXIT && |
882 | __hyp_get_vectors() == hyp_default_vectors) { | ||
882 | cpu_init_hyp_mode(NULL); | 883 | cpu_init_hyp_mode(NULL); |
883 | return NOTIFY_OK; | 884 | return NOTIFY_OK; |
884 | } | 885 | } |
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index ddc15539bad2..0d68d4073068 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S | |||
@@ -220,6 +220,10 @@ after_vfp_restore: | |||
220 | * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are | 220 | * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are |
221 | * passed in r0 and r1. | 221 | * passed in r0 and r1. |
222 | * | 222 | * |
223 | * A function pointer with a value of 0xffffffff has a special meaning, | ||
224 | * and is used to implement __hyp_get_vectors in the same way as in | ||
225 | * arch/arm/kernel/hyp_stub.S. | ||
226 | * | ||
223 | * The calling convention follows the standard AAPCS: | 227 | * The calling convention follows the standard AAPCS: |
224 | * r0 - r3: caller save | 228 | * r0 - r3: caller save |
225 | * r12: caller save | 229 | * r12: caller save |
@@ -363,6 +367,11 @@ hyp_hvc: | |||
363 | host_switch_to_hyp: | 367 | host_switch_to_hyp: |
364 | pop {r0, r1, r2} | 368 | pop {r0, r1, r2} |
365 | 369 | ||
370 | /* Check for __hyp_get_vectors */ | ||
371 | cmp r0, #-1 | ||
372 | mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR | ||
373 | beq 1f | ||
374 | |||
366 | push {lr} | 375 | push {lr} |
367 | mrs lr, SPSR | 376 | mrs lr, SPSR |
368 | push {lr} | 377 | push {lr} |
@@ -378,7 +387,7 @@ THUMB( orr lr, #1) | |||
378 | pop {lr} | 387 | pop {lr} |
379 | msr SPSR_csxf, lr | 388 | msr SPSR_csxf, lr |
380 | pop {lr} | 389 | pop {lr} |
381 | eret | 390 | 1: eret |
382 | 391 | ||
383 | guest_trap: | 392 | guest_trap: |
384 | load_vcpu @ Load VCPU pointer to r0 | 393 | load_vcpu @ Load VCPU pointer to r0 |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index befcaf5d0574..ec419649320f 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
@@ -101,11 +101,9 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | |||
101 | obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o | 101 | obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o |
102 | obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o | 102 | obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o |
103 | 103 | ||
104 | ifeq ($(CONFIG_PM),y) | ||
105 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o | 104 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o |
106 | # i.MX6SL reuses i.MX6Q code | 105 | # i.MX6SL reuses i.MX6Q code |
107 | obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o | 106 | obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o |
108 | endif | ||
109 | 107 | ||
110 | # i.MX5 based machines | 108 | # i.MX5 based machines |
111 | obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o | 109 | obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o |
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 59c3b9b26bb4..baf439dc22d8 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -144,13 +144,11 @@ void imx6q_set_chicken_bit(void); | |||
144 | void imx_cpu_die(unsigned int cpu); | 144 | void imx_cpu_die(unsigned int cpu); |
145 | int imx_cpu_kill(unsigned int cpu); | 145 | int imx_cpu_kill(unsigned int cpu); |
146 | 146 | ||
147 | #ifdef CONFIG_PM | ||
148 | void imx6q_pm_init(void); | 147 | void imx6q_pm_init(void); |
149 | void imx6q_pm_set_ccm_base(void __iomem *base); | 148 | void imx6q_pm_set_ccm_base(void __iomem *base); |
149 | #ifdef CONFIG_PM | ||
150 | void imx5_pm_init(void); | 150 | void imx5_pm_init(void); |
151 | #else | 151 | #else |
152 | static inline void imx6q_pm_init(void) {} | ||
153 | static inline void imx6q_pm_set_ccm_base(void __iomem *base) {} | ||
154 | static inline void imx5_pm_init(void) {} | 152 | static inline void imx5_pm_init(void) {} |
155 | #endif | 153 | #endif |
156 | 154 | ||
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 91449c5cb70f..85089d821982 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c | |||
@@ -156,6 +156,7 @@ static struct omap_usb_config nokia770_usb_config __initdata = { | |||
156 | .register_dev = 1, | 156 | .register_dev = 1, |
157 | .hmc_mode = 16, | 157 | .hmc_mode = 16, |
158 | .pins[0] = 6, | 158 | .pins[0] = 6, |
159 | .extcon = "tahvo-usb", | ||
159 | }; | 160 | }; |
160 | 161 | ||
161 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) | 162 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index e2ce4f8366a7..0af7ca02314d 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -50,6 +50,7 @@ config SOC_OMAP5 | |||
50 | bool "TI OMAP5" | 50 | bool "TI OMAP5" |
51 | depends on ARCH_MULTI_V7 | 51 | depends on ARCH_MULTI_V7 |
52 | select ARCH_OMAP2PLUS | 52 | select ARCH_OMAP2PLUS |
53 | select ARCH_HAS_OPP | ||
53 | select ARM_CPU_SUSPEND if PM | 54 | select ARM_CPU_SUSPEND if PM |
54 | select ARM_GIC | 55 | select ARM_GIC |
55 | select CPU_V7 | 56 | select CPU_V7 |
@@ -63,6 +64,7 @@ config SOC_AM33XX | |||
63 | bool "TI AM33XX" | 64 | bool "TI AM33XX" |
64 | depends on ARCH_MULTI_V7 | 65 | depends on ARCH_MULTI_V7 |
65 | select ARCH_OMAP2PLUS | 66 | select ARCH_OMAP2PLUS |
67 | select ARCH_HAS_OPP | ||
66 | select ARM_CPU_SUSPEND if PM | 68 | select ARM_CPU_SUSPEND if PM |
67 | select CPU_V7 | 69 | select CPU_V7 |
68 | select MULTI_IRQ_HANDLER | 70 | select MULTI_IRQ_HANDLER |
@@ -72,6 +74,7 @@ config SOC_AM43XX | |||
72 | depends on ARCH_MULTI_V7 | 74 | depends on ARCH_MULTI_V7 |
73 | select CPU_V7 | 75 | select CPU_V7 |
74 | select ARCH_OMAP2PLUS | 76 | select ARCH_OMAP2PLUS |
77 | select ARCH_HAS_OPP | ||
75 | select MULTI_IRQ_HANDLER | 78 | select MULTI_IRQ_HANDLER |
76 | select ARM_GIC | 79 | select ARM_GIC |
77 | select MACH_OMAP_GENERIC | 80 | select MACH_OMAP_GENERIC |
@@ -80,6 +83,7 @@ config SOC_DRA7XX | |||
80 | bool "TI DRA7XX" | 83 | bool "TI DRA7XX" |
81 | depends on ARCH_MULTI_V7 | 84 | depends on ARCH_MULTI_V7 |
82 | select ARCH_OMAP2PLUS | 85 | select ARCH_OMAP2PLUS |
86 | select ARCH_HAS_OPP | ||
83 | select ARM_CPU_SUSPEND if PM | 87 | select ARM_CPU_SUSPEND if PM |
84 | select ARM_GIC | 88 | select ARM_GIC |
85 | select CPU_V7 | 89 | select CPU_V7 |
@@ -268,9 +272,6 @@ config MACH_OMAP_3430SDP | |||
268 | default y | 272 | default y |
269 | select OMAP_PACKAGE_CBB | 273 | select OMAP_PACKAGE_CBB |
270 | 274 | ||
271 | config MACH_NOKIA_N800 | ||
272 | bool | ||
273 | |||
274 | config MACH_NOKIA_N810 | 275 | config MACH_NOKIA_N810 |
275 | bool | 276 | bool |
276 | 277 | ||
@@ -281,7 +282,6 @@ config MACH_NOKIA_N8X0 | |||
281 | bool "Nokia N800/N810" | 282 | bool "Nokia N800/N810" |
282 | depends on SOC_OMAP2420 | 283 | depends on SOC_OMAP2420 |
283 | default y | 284 | default y |
284 | select MACH_NOKIA_N800 | ||
285 | select MACH_NOKIA_N810 | 285 | select MACH_NOKIA_N810 |
286 | select MACH_NOKIA_N810_WIMAX | 286 | select MACH_NOKIA_N810_WIMAX |
287 | select OMAP_PACKAGE_ZAC | 287 | select OMAP_PACKAGE_ZAC |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index d24926e6340f..ab43755364f5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -1339,7 +1339,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, | |||
1339 | of_property_read_bool(np, "gpmc,time-para-granularity"); | 1339 | of_property_read_bool(np, "gpmc,time-para-granularity"); |
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | #ifdef CONFIG_MTD_NAND | 1342 | #if IS_ENABLED(CONFIG_MTD_NAND) |
1343 | 1343 | ||
1344 | static const char * const nand_xfer_types[] = { | 1344 | static const char * const nand_xfer_types[] = { |
1345 | [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", | 1345 | [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", |
@@ -1429,7 +1429,7 @@ static int gpmc_probe_nand_child(struct platform_device *pdev, | |||
1429 | } | 1429 | } |
1430 | #endif | 1430 | #endif |
1431 | 1431 | ||
1432 | #ifdef CONFIG_MTD_ONENAND | 1432 | #if IS_ENABLED(CONFIG_MTD_ONENAND) |
1433 | static int gpmc_probe_onenand_child(struct platform_device *pdev, | 1433 | static int gpmc_probe_onenand_child(struct platform_device *pdev, |
1434 | struct device_node *child) | 1434 | struct device_node *child) |
1435 | { | 1435 | { |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index d408b15b4fbf..af432b191255 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -179,15 +179,6 @@ static struct map_desc omap34xx_io_desc[] __initdata = { | |||
179 | .length = L4_EMU_34XX_SIZE, | 179 | .length = L4_EMU_34XX_SIZE, |
180 | .type = MT_DEVICE | 180 | .type = MT_DEVICE |
181 | }, | 181 | }, |
182 | #if defined(CONFIG_DEBUG_LL) && \ | ||
183 | (defined(CONFIG_MACH_OMAP_ZOOM2) || defined(CONFIG_MACH_OMAP_ZOOM3)) | ||
184 | { | ||
185 | .virtual = ZOOM_UART_VIRT, | ||
186 | .pfn = __phys_to_pfn(ZOOM_UART_BASE), | ||
187 | .length = SZ_1M, | ||
188 | .type = MT_DEVICE | ||
189 | }, | ||
190 | #endif | ||
191 | }; | 182 | }; |
192 | #endif | 183 | #endif |
193 | 184 | ||
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index f70583fee59f..29997bde277d 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/mtd/physmap.h> | 38 | #include <linux/mtd/physmap.h> |
39 | #include <linux/usb/gpio_vbus.h> | 39 | #include <linux/usb/gpio_vbus.h> |
40 | #include <linux/reboot.h> | 40 | #include <linux/reboot.h> |
41 | #include <linux/regulator/fixed.h> | ||
41 | #include <linux/regulator/max1586.h> | 42 | #include <linux/regulator/max1586.h> |
42 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
43 | #include <linux/i2c/pxa-i2c.h> | 44 | #include <linux/i2c/pxa-i2c.h> |
@@ -714,6 +715,10 @@ static struct gpio global_gpios[] = { | |||
714 | { GPIO56_MT9M111_nOE, GPIOF_OUT_INIT_LOW, "Camera nOE" }, | 715 | { GPIO56_MT9M111_nOE, GPIOF_OUT_INIT_LOW, "Camera nOE" }, |
715 | }; | 716 | }; |
716 | 717 | ||
718 | static struct regulator_consumer_supply fixed_5v0_consumers[] = { | ||
719 | REGULATOR_SUPPLY("power", "pwm-backlight"), | ||
720 | }; | ||
721 | |||
717 | static void __init mioa701_machine_init(void) | 722 | static void __init mioa701_machine_init(void) |
718 | { | 723 | { |
719 | int rc; | 724 | int rc; |
@@ -753,6 +758,10 @@ static void __init mioa701_machine_init(void) | |||
753 | pxa_set_i2c_info(&i2c_pdata); | 758 | pxa_set_i2c_info(&i2c_pdata); |
754 | pxa27x_set_i2c_power_info(NULL); | 759 | pxa27x_set_i2c_power_info(NULL); |
755 | pxa_set_camera_info(&mioa701_pxacamera_platform_data); | 760 | pxa_set_camera_info(&mioa701_pxacamera_platform_data); |
761 | |||
762 | regulator_register_always_on(0, "fixed-5.0V", fixed_5v0_consumers, | ||
763 | ARRAY_SIZE(fixed_5v0_consumers), | ||
764 | 5000000); | ||
756 | } | 765 | } |
757 | 766 | ||
758 | static void mioa701_machine_exit(void) | 767 | static void mioa701_machine_exit(void) |
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 4ae0286b468d..f55b05a29b55 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpu_pm.h> | 24 | #include <linux/cpu_pm.h> |
25 | #include <linux/suspend.h> | 25 | #include <linux/suspend.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/slab.h> | ||
27 | #include <linux/clk/tegra.h> | 28 | #include <linux/clk/tegra.h> |
28 | 29 | ||
29 | #include <asm/smp_plat.h> | 30 | #include <asm/smp_plat.h> |
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 303a285d80fd..6191603379e1 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c | |||
@@ -73,10 +73,20 @@ u32 tegra_uart_config[3] = { | |||
73 | static void __init tegra_init_cache(void) | 73 | static void __init tegra_init_cache(void) |
74 | { | 74 | { |
75 | #ifdef CONFIG_CACHE_L2X0 | 75 | #ifdef CONFIG_CACHE_L2X0 |
76 | static const struct of_device_id pl310_ids[] __initconst = { | ||
77 | { .compatible = "arm,pl310-cache", }, | ||
78 | {} | ||
79 | }; | ||
80 | |||
81 | struct device_node *np; | ||
76 | int ret; | 82 | int ret; |
77 | void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; | 83 | void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; |
78 | u32 aux_ctrl, cache_type; | 84 | u32 aux_ctrl, cache_type; |
79 | 85 | ||
86 | np = of_find_matching_node(NULL, pl310_ids); | ||
87 | if (!np) | ||
88 | return; | ||
89 | |||
80 | cache_type = readl(p + L2X0_CACHE_TYPE); | 90 | cache_type = readl(p + L2X0_CACHE_TYPE); |
81 | aux_ctrl = (cache_type & 0x700) << (17-8); | 91 | aux_ctrl = (cache_type & 0x700) << (17-8); |
82 | aux_ctrl |= 0x7C400001; | 92 | aux_ctrl |= 0x7C400001; |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1a77450e728a..11b3914660d2 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -1358,7 +1358,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | |||
1358 | *handle = DMA_ERROR_CODE; | 1358 | *handle = DMA_ERROR_CODE; |
1359 | size = PAGE_ALIGN(size); | 1359 | size = PAGE_ALIGN(size); |
1360 | 1360 | ||
1361 | if (gfp & GFP_ATOMIC) | 1361 | if (!(gfp & __GFP_WAIT)) |
1362 | return __iommu_alloc_atomic(dev, size, handle); | 1362 | return __iommu_alloc_atomic(dev, size, handle); |
1363 | 1363 | ||
1364 | /* | 1364 | /* |
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index d5a982d15a88..7ea641b7aa7d 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h | |||
@@ -38,6 +38,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt) | |||
38 | 38 | ||
39 | struct mem_type { | 39 | struct mem_type { |
40 | pteval_t prot_pte; | 40 | pteval_t prot_pte; |
41 | pteval_t prot_pte_s2; | ||
41 | pmdval_t prot_l1; | 42 | pmdval_t prot_l1; |
42 | pmdval_t prot_sect; | 43 | pmdval_t prot_sect; |
43 | unsigned int domain; | 44 | unsigned int domain; |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4f08c133cc25..a623cb3ad012 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -232,12 +232,16 @@ __setup("noalign", noalign_setup); | |||
232 | #endif /* ifdef CONFIG_CPU_CP15 / else */ | 232 | #endif /* ifdef CONFIG_CPU_CP15 / else */ |
233 | 233 | ||
234 | #define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN | 234 | #define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN |
235 | #define PROT_PTE_S2_DEVICE PROT_PTE_DEVICE | ||
235 | #define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE | 236 | #define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE |
236 | 237 | ||
237 | static struct mem_type mem_types[] = { | 238 | static struct mem_type mem_types[] = { |
238 | [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */ | 239 | [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */ |
239 | .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED | | 240 | .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED | |
240 | L_PTE_SHARED, | 241 | L_PTE_SHARED, |
242 | .prot_pte_s2 = s2_policy(PROT_PTE_S2_DEVICE) | | ||
243 | s2_policy(L_PTE_S2_MT_DEV_SHARED) | | ||
244 | L_PTE_SHARED, | ||
241 | .prot_l1 = PMD_TYPE_TABLE, | 245 | .prot_l1 = PMD_TYPE_TABLE, |
242 | .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S, | 246 | .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S, |
243 | .domain = DOMAIN_IO, | 247 | .domain = DOMAIN_IO, |
@@ -508,7 +512,8 @@ static void __init build_mem_type_table(void) | |||
508 | cp = &cache_policies[cachepolicy]; | 512 | cp = &cache_policies[cachepolicy]; |
509 | vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; | 513 | vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; |
510 | s2_pgprot = cp->pte_s2; | 514 | s2_pgprot = cp->pte_s2; |
511 | hyp_device_pgprot = s2_device_pgprot = mem_types[MT_DEVICE].prot_pte; | 515 | hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte; |
516 | s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2; | ||
512 | 517 | ||
513 | /* | 518 | /* |
514 | * ARMv6 and above have extended page tables. | 519 | * ARMv6 and above have extended page tables. |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 45dc29f85d56..32b3558321c4 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -208,7 +208,6 @@ __v6_setup: | |||
208 | mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache | 208 | mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache |
209 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | 209 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache |
210 | mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache | 210 | mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache |
211 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
212 | #ifdef CONFIG_MMU | 211 | #ifdef CONFIG_MMU |
213 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs | 212 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs |
214 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register | 213 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register |
@@ -218,6 +217,8 @@ __v6_setup: | |||
218 | ALT_UP(orr r8, r8, #TTB_FLAGS_UP) | 217 | ALT_UP(orr r8, r8, #TTB_FLAGS_UP) |
219 | mcr p15, 0, r8, c2, c0, 1 @ load TTB1 | 218 | mcr p15, 0, r8, c2, c0, 1 @ load TTB1 |
220 | #endif /* CONFIG_MMU */ | 219 | #endif /* CONFIG_MMU */ |
220 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer and | ||
221 | @ complete invalidations | ||
221 | adr r5, v6_crval | 222 | adr r5, v6_crval |
222 | ldmia r5, {r5, r6} | 223 | ldmia r5, {r5, r6} |
223 | ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables | 224 | ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index bd1781979a39..74f6033e76dd 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -351,7 +351,6 @@ __v7_setup: | |||
351 | 351 | ||
352 | 4: mov r10, #0 | 352 | 4: mov r10, #0 |
353 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate | 353 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate |
354 | dsb | ||
355 | #ifdef CONFIG_MMU | 354 | #ifdef CONFIG_MMU |
356 | mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs | 355 | mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs |
357 | v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup | 356 | v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup |
@@ -360,6 +359,7 @@ __v7_setup: | |||
360 | mcr p15, 0, r5, c10, c2, 0 @ write PRRR | 359 | mcr p15, 0, r5, c10, c2, 0 @ write PRRR |
361 | mcr p15, 0, r6, c10, c2, 1 @ write NMRR | 360 | mcr p15, 0, r6, c10, c2, 1 @ write NMRR |
362 | #endif | 361 | #endif |
362 | dsb @ Complete invalidations | ||
363 | #ifndef CONFIG_ARM_THUMBEE | 363 | #ifndef CONFIG_ARM_THUMBEE |
364 | mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE | 364 | mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE |
365 | and r0, r0, #(0xf << 12) @ ThumbEE enabled field | 365 | and r0, r0, #(0xf << 12) @ ThumbEE enabled field |
diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 13fb0b3efc5f..453a179469a3 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #ifndef __ASM_PERCPU_H | 16 | #ifndef __ASM_PERCPU_H |
17 | #define __ASM_PERCPU_H | 17 | #define __ASM_PERCPU_H |
18 | 18 | ||
19 | #ifdef CONFIG_SMP | ||
20 | |||
19 | static inline void set_my_cpu_offset(unsigned long off) | 21 | static inline void set_my_cpu_offset(unsigned long off) |
20 | { | 22 | { |
21 | asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory"); | 23 | asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory"); |
@@ -36,6 +38,12 @@ static inline unsigned long __my_cpu_offset(void) | |||
36 | } | 38 | } |
37 | #define __my_cpu_offset __my_cpu_offset() | 39 | #define __my_cpu_offset __my_cpu_offset() |
38 | 40 | ||
41 | #else /* !CONFIG_SMP */ | ||
42 | |||
43 | #define set_my_cpu_offset(x) do { } while (0) | ||
44 | |||
45 | #endif /* CONFIG_SMP */ | ||
46 | |||
39 | #include <asm-generic/percpu.h> | 47 | #include <asm-generic/percpu.h> |
40 | 48 | ||
41 | #endif /* __ASM_PERCPU_H */ | 49 | #endif /* __ASM_PERCPU_H */ |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index b524dcd17243..aa3917c8b623 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -136,11 +136,11 @@ extern struct page *empty_zero_page; | |||
136 | /* | 136 | /* |
137 | * The following only work if pte_present(). Undefined behaviour otherwise. | 137 | * The following only work if pte_present(). Undefined behaviour otherwise. |
138 | */ | 138 | */ |
139 | #define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) | 139 | #define pte_present(pte) (!!(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))) |
140 | #define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) | 140 | #define pte_dirty(pte) (!!(pte_val(pte) & PTE_DIRTY)) |
141 | #define pte_young(pte) (pte_val(pte) & PTE_AF) | 141 | #define pte_young(pte) (!!(pte_val(pte) & PTE_AF)) |
142 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) | 142 | #define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL)) |
143 | #define pte_write(pte) (pte_val(pte) & PTE_WRITE) | 143 | #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) |
144 | #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) | 144 | #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) |
145 | 145 | ||
146 | #define pte_valid_user(pte) \ | 146 | #define pte_valid_user(pte) \ |
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index c3b6c63ea5fb..38f0558f0c0a 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c | |||
@@ -48,7 +48,11 @@ int unwind_frame(struct stackframe *frame) | |||
48 | 48 | ||
49 | frame->sp = fp + 0x10; | 49 | frame->sp = fp + 0x10; |
50 | frame->fp = *(unsigned long *)(fp); | 50 | frame->fp = *(unsigned long *)(fp); |
51 | frame->pc = *(unsigned long *)(fp + 8); | 51 | /* |
52 | * -4 here because we care about the PC at time of bl, | ||
53 | * not where the return will go. | ||
54 | */ | ||
55 | frame->pc = *(unsigned long *)(fp + 8) - 4; | ||
52 | 56 | ||
53 | return 0; | 57 | return 0; |
54 | } | 58 | } |
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index 3b47c36e10ff..2c56012cb2d2 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S | |||
@@ -694,6 +694,24 @@ __hyp_panic_str: | |||
694 | 694 | ||
695 | .align 2 | 695 | .align 2 |
696 | 696 | ||
697 | /* | ||
698 | * u64 kvm_call_hyp(void *hypfn, ...); | ||
699 | * | ||
700 | * This is not really a variadic function in the classic C-way and care must | ||
701 | * be taken when calling this to ensure parameters are passed in registers | ||
702 | * only, since the stack will change between the caller and the callee. | ||
703 | * | ||
704 | * Call the function with the first argument containing a pointer to the | ||
705 | * function you wish to call in Hyp mode, and subsequent arguments will be | ||
706 | * passed as x0, x1, and x2 (a maximum of 3 arguments in addition to the | ||
707 | * function pointer can be passed). The function being called must be mapped | ||
708 | * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are | ||
709 | * passed in r0 and r1. | ||
710 | * | ||
711 | * A function pointer with a value of 0 has a special meaning, and is | ||
712 | * used to implement __hyp_get_vectors in the same way as in | ||
713 | * arch/arm64/kernel/hyp_stub.S. | ||
714 | */ | ||
697 | ENTRY(kvm_call_hyp) | 715 | ENTRY(kvm_call_hyp) |
698 | hvc #0 | 716 | hvc #0 |
699 | ret | 717 | ret |
@@ -737,7 +755,12 @@ el1_sync: // Guest trapped into EL2 | |||
737 | pop x2, x3 | 755 | pop x2, x3 |
738 | pop x0, x1 | 756 | pop x0, x1 |
739 | 757 | ||
740 | push lr, xzr | 758 | /* Check for __hyp_get_vectors */ |
759 | cbnz x0, 1f | ||
760 | mrs x0, vbar_el2 | ||
761 | b 2f | ||
762 | |||
763 | 1: push lr, xzr | ||
741 | 764 | ||
742 | /* | 765 | /* |
743 | * Compute the function address in EL2, and shuffle the parameters. | 766 | * Compute the function address in EL2, and shuffle the parameters. |
@@ -750,7 +773,7 @@ el1_sync: // Guest trapped into EL2 | |||
750 | blr lr | 773 | blr lr |
751 | 774 | ||
752 | pop lr, xzr | 775 | pop lr, xzr |
753 | eret | 776 | 2: eret |
754 | 777 | ||
755 | el1_trap: | 778 | el1_trap: |
756 | /* | 779 | /* |
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile index 22fb66590dcd..dba48a5d5bb9 100644 --- a/arch/avr32/Makefile +++ b/arch/avr32/Makefile | |||
@@ -11,7 +11,7 @@ all: uImage vmlinux.elf | |||
11 | 11 | ||
12 | KBUILD_DEFCONFIG := atstk1002_defconfig | 12 | KBUILD_DEFCONFIG := atstk1002_defconfig |
13 | 13 | ||
14 | KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic | 14 | KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic -D__linux__ |
15 | KBUILD_AFLAGS += -mrelax -mno-pic | 15 | KBUILD_AFLAGS += -mrelax -mno-pic |
16 | KBUILD_CFLAGS_MODULE += -mno-relax | 16 | KBUILD_CFLAGS_MODULE += -mno-relax |
17 | LDFLAGS_vmlinux += --relax | 17 | LDFLAGS_vmlinux += --relax |
diff --git a/arch/avr32/boards/mimc200/fram.c b/arch/avr32/boards/mimc200/fram.c index 9764a1a1073e..c1466a872b9c 100644 --- a/arch/avr32/boards/mimc200/fram.c +++ b/arch/avr32/boards/mimc200/fram.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #define FRAM_VERSION "1.0" | 11 | #define FRAM_VERSION "1.0" |
12 | 12 | ||
13 | #include <linux/miscdevice.h> | 13 | #include <linux/miscdevice.h> |
14 | #include <linux/module.h> | ||
14 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
15 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
16 | #include <linux/io.h> | 17 | #include <linux/io.h> |
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index cfb9fe1b8df9..c7c64a63c29f 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild | |||
@@ -17,5 +17,6 @@ generic-y += scatterlist.h | |||
17 | generic-y += sections.h | 17 | generic-y += sections.h |
18 | generic-y += topology.h | 18 | generic-y += topology.h |
19 | generic-y += trace_clock.h | 19 | generic-y += trace_clock.h |
20 | generic-y += vga.h | ||
20 | generic-y += xor.h | 21 | generic-y += xor.h |
21 | generic-y += hash.h | 22 | generic-y += hash.h |
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h index fc6483f83ccc..4f5ec2bb7172 100644 --- a/arch/avr32/include/asm/io.h +++ b/arch/avr32/include/asm/io.h | |||
@@ -295,6 +295,8 @@ extern void __iounmap(void __iomem *addr); | |||
295 | #define iounmap(addr) \ | 295 | #define iounmap(addr) \ |
296 | __iounmap(addr) | 296 | __iounmap(addr) |
297 | 297 | ||
298 | #define ioremap_wc ioremap_nocache | ||
299 | |||
298 | #define cached(addr) P1SEGADDR(addr) | 300 | #define cached(addr) P1SEGADDR(addr) |
299 | #define uncached(addr) P2SEGADDR(addr) | 301 | #define uncached(addr) P2SEGADDR(addr) |
300 | 302 | ||
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 7cc8c364924d..6fb9e813a910 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild | |||
@@ -1,4 +1,4 @@ | |||
1 | 1 | generic-y += barrier.h | |
2 | generic-y += bitsperlong.h | 2 | generic-y += bitsperlong.h |
3 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
4 | generic-y += cputime.h | 4 | generic-y += cputime.h |
@@ -6,6 +6,7 @@ generic-y += device.h | |||
6 | generic-y += emergency-restart.h | 6 | generic-y += emergency-restart.h |
7 | generic-y += errno.h | 7 | generic-y += errno.h |
8 | generic-y += exec.h | 8 | generic-y += exec.h |
9 | generic-y += hash.h | ||
9 | generic-y += hw_irq.h | 10 | generic-y += hw_irq.h |
10 | generic-y += ioctl.h | 11 | generic-y += ioctl.h |
11 | generic-y += ipcbuf.h | 12 | generic-y += ipcbuf.h |
@@ -18,6 +19,7 @@ generic-y += local.h | |||
18 | generic-y += mman.h | 19 | generic-y += mman.h |
19 | generic-y += mutex.h | 20 | generic-y += mutex.h |
20 | generic-y += percpu.h | 21 | generic-y += percpu.h |
22 | generic-y += preempt.h | ||
21 | generic-y += resource.h | 23 | generic-y += resource.h |
22 | generic-y += scatterlist.h | 24 | generic-y += scatterlist.h |
23 | generic-y += sections.h | 25 | generic-y += sections.h |
@@ -31,5 +33,3 @@ generic-y += trace_clock.h | |||
31 | generic-y += types.h | 33 | generic-y += types.h |
32 | generic-y += word-at-a-time.h | 34 | generic-y += word-at-a-time.h |
33 | generic-y += xor.h | 35 | generic-y += xor.h |
34 | generic-y += preempt.h | ||
35 | generic-y += hash.h | ||
diff --git a/arch/m68k/include/asm/barrier.h b/arch/m68k/include/asm/barrier.h deleted file mode 100644 index 15c5f77c1614..000000000000 --- a/arch/m68k/include/asm/barrier.h +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | #ifndef _M68K_BARRIER_H | ||
2 | #define _M68K_BARRIER_H | ||
3 | |||
4 | #define nop() do { asm volatile ("nop"); barrier(); } while (0) | ||
5 | |||
6 | #include <asm-generic/barrier.h> | ||
7 | |||
8 | #endif /* _M68K_BARRIER_H */ | ||
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 014f288fc813..9d38b73989eb 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <uapi/asm/unistd.h> | 4 | #include <uapi/asm/unistd.h> |
5 | 5 | ||
6 | 6 | ||
7 | #define NR_syscalls 349 | 7 | #define NR_syscalls 351 |
8 | 8 | ||
9 | #define __ARCH_WANT_OLD_READDIR | 9 | #define __ARCH_WANT_OLD_READDIR |
10 | #define __ARCH_WANT_OLD_STAT | 10 | #define __ARCH_WANT_OLD_STAT |
diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index 625f321001dc..b932dd470041 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h | |||
@@ -354,5 +354,7 @@ | |||
354 | #define __NR_process_vm_writev 346 | 354 | #define __NR_process_vm_writev 346 |
355 | #define __NR_kcmp 347 | 355 | #define __NR_kcmp 347 |
356 | #define __NR_finit_module 348 | 356 | #define __NR_finit_module 348 |
357 | #define __NR_sched_setattr 349 | ||
358 | #define __NR_sched_getattr 350 | ||
357 | 359 | ||
358 | #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ | 360 | #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ |
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 3f04ea0ab802..b6223dc41d82 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S | |||
@@ -369,4 +369,6 @@ ENTRY(sys_call_table) | |||
369 | .long sys_process_vm_writev | 369 | .long sys_process_vm_writev |
370 | .long sys_kcmp | 370 | .long sys_kcmp |
371 | .long sys_finit_module | 371 | .long sys_finit_module |
372 | .long sys_sched_setattr | ||
373 | .long sys_sched_getattr /* 350 */ | ||
372 | 374 | ||
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 84fdf6857c31..a613d2c82fd9 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h | |||
@@ -200,10 +200,11 @@ static inline void __user *arch_compat_alloc_user_space(long len) | |||
200 | 200 | ||
201 | /* | 201 | /* |
202 | * We can't access below the stack pointer in the 32bit ABI and | 202 | * We can't access below the stack pointer in the 32bit ABI and |
203 | * can access 288 bytes in the 64bit ABI | 203 | * can access 288 bytes in the 64bit big-endian ABI, |
204 | * or 512 bytes with the new ELFv2 little-endian ABI. | ||
204 | */ | 205 | */ |
205 | if (!is_32bit_task()) | 206 | if (!is_32bit_task()) |
206 | usp -= 288; | 207 | usp -= USER_REDZONE_SIZE; |
207 | 208 | ||
208 | return (void __user *) (usp - len); | 209 | return (void __user *) (usp - len); |
209 | } | 210 | } |
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 9e39ceb1d19f..d4dd41fb951b 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -172,10 +172,20 @@ struct eeh_ops { | |||
172 | }; | 172 | }; |
173 | 173 | ||
174 | extern struct eeh_ops *eeh_ops; | 174 | extern struct eeh_ops *eeh_ops; |
175 | extern int eeh_subsystem_enabled; | 175 | extern bool eeh_subsystem_enabled; |
176 | extern raw_spinlock_t confirm_error_lock; | 176 | extern raw_spinlock_t confirm_error_lock; |
177 | extern int eeh_probe_mode; | 177 | extern int eeh_probe_mode; |
178 | 178 | ||
179 | static inline bool eeh_enabled(void) | ||
180 | { | ||
181 | return eeh_subsystem_enabled; | ||
182 | } | ||
183 | |||
184 | static inline void eeh_set_enable(bool mode) | ||
185 | { | ||
186 | eeh_subsystem_enabled = mode; | ||
187 | } | ||
188 | |||
179 | #define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */ | 189 | #define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */ |
180 | #define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */ | 190 | #define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */ |
181 | 191 | ||
@@ -246,7 +256,7 @@ void eeh_remove_device(struct pci_dev *); | |||
246 | * If this macro yields TRUE, the caller relays to eeh_check_failure() | 256 | * If this macro yields TRUE, the caller relays to eeh_check_failure() |
247 | * which does further tests out of line. | 257 | * which does further tests out of line. |
248 | */ | 258 | */ |
249 | #define EEH_POSSIBLE_ERROR(val, type) ((val) == (type)~0 && eeh_subsystem_enabled) | 259 | #define EEH_POSSIBLE_ERROR(val, type) ((val) == (type)~0 && eeh_enabled()) |
250 | 260 | ||
251 | /* | 261 | /* |
252 | * Reads from a device which has been isolated by EEH will return | 262 | * Reads from a device which has been isolated by EEH will return |
@@ -257,6 +267,13 @@ void eeh_remove_device(struct pci_dev *); | |||
257 | 267 | ||
258 | #else /* !CONFIG_EEH */ | 268 | #else /* !CONFIG_EEH */ |
259 | 269 | ||
270 | static inline bool eeh_enabled(void) | ||
271 | { | ||
272 | return false; | ||
273 | } | ||
274 | |||
275 | static inline void eeh_set_enable(bool mode) { } | ||
276 | |||
260 | static inline int eeh_init(void) | 277 | static inline int eeh_init(void) |
261 | { | 278 | { |
262 | return 0; | 279 | return 0; |
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index d750336b171d..623f2971ce0e 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h | |||
@@ -127,7 +127,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | |||
127 | unsigned long addr, pte_t *ptep) | 127 | unsigned long addr, pte_t *ptep) |
128 | { | 128 | { |
129 | #ifdef CONFIG_PPC64 | 129 | #ifdef CONFIG_PPC64 |
130 | return __pte(pte_update(mm, addr, ptep, ~0UL, 1)); | 130 | return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1)); |
131 | #else | 131 | #else |
132 | return __pte(pte_update(ptep, ~0UL, 0)); | 132 | return __pte(pte_update(ptep, ~0UL, 0)); |
133 | #endif | 133 | #endif |
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 40157e2ca691..ed82142a3251 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -816,8 +816,8 @@ int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe, | |||
816 | int64_t opal_pci_poll(uint64_t phb_id); | 816 | int64_t opal_pci_poll(uint64_t phb_id); |
817 | int64_t opal_return_cpu(void); | 817 | int64_t opal_return_cpu(void); |
818 | 818 | ||
819 | int64_t opal_xscom_read(uint32_t gcid, uint32_t pcb_addr, __be64 *val); | 819 | int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); |
820 | int64_t opal_xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val); | 820 | int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); |
821 | 821 | ||
822 | int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, | 822 | int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, |
823 | uint32_t addr, uint32_t data, uint32_t sz); | 823 | uint32_t addr, uint32_t data, uint32_t sz); |
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index bc141c950b1e..eb9261024f51 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h | |||
@@ -195,6 +195,7 @@ extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, | |||
195 | static inline unsigned long pte_update(struct mm_struct *mm, | 195 | static inline unsigned long pte_update(struct mm_struct *mm, |
196 | unsigned long addr, | 196 | unsigned long addr, |
197 | pte_t *ptep, unsigned long clr, | 197 | pte_t *ptep, unsigned long clr, |
198 | unsigned long set, | ||
198 | int huge) | 199 | int huge) |
199 | { | 200 | { |
200 | #ifdef PTE_ATOMIC_UPDATES | 201 | #ifdef PTE_ATOMIC_UPDATES |
@@ -205,14 +206,15 @@ static inline unsigned long pte_update(struct mm_struct *mm, | |||
205 | andi. %1,%0,%6\n\ | 206 | andi. %1,%0,%6\n\ |
206 | bne- 1b \n\ | 207 | bne- 1b \n\ |
207 | andc %1,%0,%4 \n\ | 208 | andc %1,%0,%4 \n\ |
209 | or %1,%1,%7\n\ | ||
208 | stdcx. %1,0,%3 \n\ | 210 | stdcx. %1,0,%3 \n\ |
209 | bne- 1b" | 211 | bne- 1b" |
210 | : "=&r" (old), "=&r" (tmp), "=m" (*ptep) | 212 | : "=&r" (old), "=&r" (tmp), "=m" (*ptep) |
211 | : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY) | 213 | : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set) |
212 | : "cc" ); | 214 | : "cc" ); |
213 | #else | 215 | #else |
214 | unsigned long old = pte_val(*ptep); | 216 | unsigned long old = pte_val(*ptep); |
215 | *ptep = __pte(old & ~clr); | 217 | *ptep = __pte((old & ~clr) | set); |
216 | #endif | 218 | #endif |
217 | /* huge pages use the old page table lock */ | 219 | /* huge pages use the old page table lock */ |
218 | if (!huge) | 220 | if (!huge) |
@@ -231,9 +233,9 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, | |||
231 | { | 233 | { |
232 | unsigned long old; | 234 | unsigned long old; |
233 | 235 | ||
234 | if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) | 236 | if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) |
235 | return 0; | 237 | return 0; |
236 | old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0); | 238 | old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); |
237 | return (old & _PAGE_ACCESSED) != 0; | 239 | return (old & _PAGE_ACCESSED) != 0; |
238 | } | 240 | } |
239 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 241 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
@@ -252,7 +254,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |||
252 | if ((pte_val(*ptep) & _PAGE_RW) == 0) | 254 | if ((pte_val(*ptep) & _PAGE_RW) == 0) |
253 | return; | 255 | return; |
254 | 256 | ||
255 | pte_update(mm, addr, ptep, _PAGE_RW, 0); | 257 | pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); |
256 | } | 258 | } |
257 | 259 | ||
258 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, | 260 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, |
@@ -261,7 +263,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, | |||
261 | if ((pte_val(*ptep) & _PAGE_RW) == 0) | 263 | if ((pte_val(*ptep) & _PAGE_RW) == 0) |
262 | return; | 264 | return; |
263 | 265 | ||
264 | pte_update(mm, addr, ptep, _PAGE_RW, 1); | 266 | pte_update(mm, addr, ptep, _PAGE_RW, 0, 1); |
265 | } | 267 | } |
266 | 268 | ||
267 | /* | 269 | /* |
@@ -284,14 +286,14 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, | |||
284 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, | 286 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, |
285 | unsigned long addr, pte_t *ptep) | 287 | unsigned long addr, pte_t *ptep) |
286 | { | 288 | { |
287 | unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0); | 289 | unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0); |
288 | return __pte(old); | 290 | return __pte(old); |
289 | } | 291 | } |
290 | 292 | ||
291 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, | 293 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, |
292 | pte_t * ptep) | 294 | pte_t * ptep) |
293 | { | 295 | { |
294 | pte_update(mm, addr, ptep, ~0UL, 0); | 296 | pte_update(mm, addr, ptep, ~0UL, 0, 0); |
295 | } | 297 | } |
296 | 298 | ||
297 | 299 | ||
@@ -506,7 +508,9 @@ extern int pmdp_set_access_flags(struct vm_area_struct *vma, | |||
506 | 508 | ||
507 | extern unsigned long pmd_hugepage_update(struct mm_struct *mm, | 509 | extern unsigned long pmd_hugepage_update(struct mm_struct *mm, |
508 | unsigned long addr, | 510 | unsigned long addr, |
509 | pmd_t *pmdp, unsigned long clr); | 511 | pmd_t *pmdp, |
512 | unsigned long clr, | ||
513 | unsigned long set); | ||
510 | 514 | ||
511 | static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, | 515 | static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, |
512 | unsigned long addr, pmd_t *pmdp) | 516 | unsigned long addr, pmd_t *pmdp) |
@@ -515,7 +519,7 @@ static inline int __pmdp_test_and_clear_young(struct mm_struct *mm, | |||
515 | 519 | ||
516 | if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) | 520 | if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) |
517 | return 0; | 521 | return 0; |
518 | old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED); | 522 | old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0); |
519 | return ((old & _PAGE_ACCESSED) != 0); | 523 | return ((old & _PAGE_ACCESSED) != 0); |
520 | } | 524 | } |
521 | 525 | ||
@@ -542,7 +546,7 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |||
542 | if ((pmd_val(*pmdp) & _PAGE_RW) == 0) | 546 | if ((pmd_val(*pmdp) & _PAGE_RW) == 0) |
543 | return; | 547 | return; |
544 | 548 | ||
545 | pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW); | 549 | pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0); |
546 | } | 550 | } |
547 | 551 | ||
548 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH | 552 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH |
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index f83b6f3e1b39..3ebb188c3ff5 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h | |||
@@ -75,12 +75,34 @@ static inline pte_t pte_mknuma(pte_t pte) | |||
75 | return pte; | 75 | return pte; |
76 | } | 76 | } |
77 | 77 | ||
78 | #define ptep_set_numa ptep_set_numa | ||
79 | static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr, | ||
80 | pte_t *ptep) | ||
81 | { | ||
82 | if ((pte_val(*ptep) & _PAGE_PRESENT) == 0) | ||
83 | VM_BUG_ON(1); | ||
84 | |||
85 | pte_update(mm, addr, ptep, _PAGE_PRESENT, _PAGE_NUMA, 0); | ||
86 | return; | ||
87 | } | ||
88 | |||
78 | #define pmd_numa pmd_numa | 89 | #define pmd_numa pmd_numa |
79 | static inline int pmd_numa(pmd_t pmd) | 90 | static inline int pmd_numa(pmd_t pmd) |
80 | { | 91 | { |
81 | return pte_numa(pmd_pte(pmd)); | 92 | return pte_numa(pmd_pte(pmd)); |
82 | } | 93 | } |
83 | 94 | ||
95 | #define pmdp_set_numa pmdp_set_numa | ||
96 | static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr, | ||
97 | pmd_t *pmdp) | ||
98 | { | ||
99 | if ((pmd_val(*pmdp) & _PAGE_PRESENT) == 0) | ||
100 | VM_BUG_ON(1); | ||
101 | |||
102 | pmd_hugepage_update(mm, addr, pmdp, _PAGE_PRESENT, _PAGE_NUMA); | ||
103 | return; | ||
104 | } | ||
105 | |||
84 | #define pmd_mknonnuma pmd_mknonnuma | 106 | #define pmd_mknonnuma pmd_mknonnuma |
85 | static inline pmd_t pmd_mknonnuma(pmd_t pmd) | 107 | static inline pmd_t pmd_mknonnuma(pmd_t pmd) |
86 | { | 108 | { |
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index becc08e6a65c..279b80f3bb29 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -28,11 +28,23 @@ | |||
28 | 28 | ||
29 | #ifdef __powerpc64__ | 29 | #ifdef __powerpc64__ |
30 | 30 | ||
31 | /* | ||
32 | * Size of redzone that userspace is allowed to use below the stack | ||
33 | * pointer. This is 288 in the 64-bit big-endian ELF ABI, and 512 in | ||
34 | * the new ELFv2 little-endian ABI, so we allow the larger amount. | ||
35 | * | ||
36 | * For kernel code we allow a 288-byte redzone, in order to conserve | ||
37 | * kernel stack space; gcc currently only uses 288 bytes, and will | ||
38 | * hopefully allow explicit control of the redzone size in future. | ||
39 | */ | ||
40 | #define USER_REDZONE_SIZE 512 | ||
41 | #define KERNEL_REDZONE_SIZE 288 | ||
42 | |||
31 | #define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ | 43 | #define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ |
32 | #define STACK_FRAME_LR_SAVE 2 /* Location of LR in stack frame */ | 44 | #define STACK_FRAME_LR_SAVE 2 /* Location of LR in stack frame */ |
33 | #define STACK_FRAME_REGS_MARKER ASM_CONST(0x7265677368657265) | 45 | #define STACK_FRAME_REGS_MARKER ASM_CONST(0x7265677368657265) |
34 | #define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + \ | 46 | #define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + \ |
35 | STACK_FRAME_OVERHEAD + 288) | 47 | STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE) |
36 | #define STACK_FRAME_MARKER 12 | 48 | #define STACK_FRAME_MARKER 12 |
37 | 49 | ||
38 | /* Size of dummy stack frame allocated when calling signal handler. */ | 50 | /* Size of dummy stack frame allocated when calling signal handler. */ |
@@ -41,6 +53,8 @@ | |||
41 | 53 | ||
42 | #else /* __powerpc64__ */ | 54 | #else /* __powerpc64__ */ |
43 | 55 | ||
56 | #define USER_REDZONE_SIZE 0 | ||
57 | #define KERNEL_REDZONE_SIZE 0 | ||
44 | #define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ | 58 | #define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ |
45 | #define STACK_FRAME_LR_SAVE 1 /* Location of LR in stack frame */ | 59 | #define STACK_FRAME_LR_SAVE 1 /* Location of LR in stack frame */ |
46 | #define STACK_FRAME_REGS_MARKER ASM_CONST(0x72656773) | 60 | #define STACK_FRAME_REGS_MARKER ASM_CONST(0x72656773) |
diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h index 0d9cecddf8a4..c53f5f6d1761 100644 --- a/arch/powerpc/include/asm/vdso.h +++ b/arch/powerpc/include/asm/vdso.h | |||
@@ -4,11 +4,11 @@ | |||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | 5 | ||
6 | /* Default link addresses for the vDSOs */ | 6 | /* Default link addresses for the vDSOs */ |
7 | #define VDSO32_LBASE 0x100000 | 7 | #define VDSO32_LBASE 0x0 |
8 | #define VDSO64_LBASE 0x100000 | 8 | #define VDSO64_LBASE 0x0 |
9 | 9 | ||
10 | /* Default map addresses for 32bit vDSO */ | 10 | /* Default map addresses for 32bit vDSO */ |
11 | #define VDSO32_MBASE VDSO32_LBASE | 11 | #define VDSO32_MBASE 0x100000 |
12 | 12 | ||
13 | #define VDSO_VERSION_STRING LINUX_2.6.15 | 13 | #define VDSO_VERSION_STRING LINUX_2.6.15 |
14 | 14 | ||
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 11c1d069d920..7a13f378ca2c 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -98,17 +98,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
98 | size_t csize, unsigned long offset, int userbuf) | 98 | size_t csize, unsigned long offset, int userbuf) |
99 | { | 99 | { |
100 | void *vaddr; | 100 | void *vaddr; |
101 | phys_addr_t paddr; | ||
101 | 102 | ||
102 | if (!csize) | 103 | if (!csize) |
103 | return 0; | 104 | return 0; |
104 | 105 | ||
105 | csize = min_t(size_t, csize, PAGE_SIZE); | 106 | csize = min_t(size_t, csize, PAGE_SIZE); |
107 | paddr = pfn << PAGE_SHIFT; | ||
106 | 108 | ||
107 | if ((min_low_pfn < pfn) && (pfn < max_pfn)) { | 109 | if (memblock_is_region_memory(paddr, csize)) { |
108 | vaddr = __va(pfn << PAGE_SHIFT); | 110 | vaddr = __va(paddr); |
109 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); | 111 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); |
110 | } else { | 112 | } else { |
111 | vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0); | 113 | vaddr = __ioremap(paddr, PAGE_SIZE, 0); |
112 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); | 114 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); |
113 | iounmap(vaddr); | 115 | iounmap(vaddr); |
114 | } | 116 | } |
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 148db72a8c43..e7b76a6bf150 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/proc_fs.h> | 29 | #include <linux/proc_fs.h> |
30 | #include <linux/rbtree.h> | 30 | #include <linux/rbtree.h> |
31 | #include <linux/reboot.h> | ||
31 | #include <linux/seq_file.h> | 32 | #include <linux/seq_file.h> |
32 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
33 | #include <linux/export.h> | 34 | #include <linux/export.h> |
@@ -89,7 +90,7 @@ | |||
89 | /* Platform dependent EEH operations */ | 90 | /* Platform dependent EEH operations */ |
90 | struct eeh_ops *eeh_ops = NULL; | 91 | struct eeh_ops *eeh_ops = NULL; |
91 | 92 | ||
92 | int eeh_subsystem_enabled; | 93 | bool eeh_subsystem_enabled = false; |
93 | EXPORT_SYMBOL(eeh_subsystem_enabled); | 94 | EXPORT_SYMBOL(eeh_subsystem_enabled); |
94 | 95 | ||
95 | /* | 96 | /* |
@@ -364,7 +365,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) | |||
364 | 365 | ||
365 | eeh_stats.total_mmio_ffs++; | 366 | eeh_stats.total_mmio_ffs++; |
366 | 367 | ||
367 | if (!eeh_subsystem_enabled) | 368 | if (!eeh_enabled()) |
368 | return 0; | 369 | return 0; |
369 | 370 | ||
370 | if (!edev) { | 371 | if (!edev) { |
@@ -747,6 +748,17 @@ int __exit eeh_ops_unregister(const char *name) | |||
747 | return -EEXIST; | 748 | return -EEXIST; |
748 | } | 749 | } |
749 | 750 | ||
751 | static int eeh_reboot_notifier(struct notifier_block *nb, | ||
752 | unsigned long action, void *unused) | ||
753 | { | ||
754 | eeh_set_enable(false); | ||
755 | return NOTIFY_DONE; | ||
756 | } | ||
757 | |||
758 | static struct notifier_block eeh_reboot_nb = { | ||
759 | .notifier_call = eeh_reboot_notifier, | ||
760 | }; | ||
761 | |||
750 | /** | 762 | /** |
751 | * eeh_init - EEH initialization | 763 | * eeh_init - EEH initialization |
752 | * | 764 | * |
@@ -778,6 +790,14 @@ int eeh_init(void) | |||
778 | if (machine_is(powernv) && cnt++ <= 0) | 790 | if (machine_is(powernv) && cnt++ <= 0) |
779 | return ret; | 791 | return ret; |
780 | 792 | ||
793 | /* Register reboot notifier */ | ||
794 | ret = register_reboot_notifier(&eeh_reboot_nb); | ||
795 | if (ret) { | ||
796 | pr_warn("%s: Failed to register notifier (%d)\n", | ||
797 | __func__, ret); | ||
798 | return ret; | ||
799 | } | ||
800 | |||
781 | /* call platform initialization function */ | 801 | /* call platform initialization function */ |
782 | if (!eeh_ops) { | 802 | if (!eeh_ops) { |
783 | pr_warning("%s: Platform EEH operation not found\n", | 803 | pr_warning("%s: Platform EEH operation not found\n", |
@@ -822,7 +842,7 @@ int eeh_init(void) | |||
822 | return ret; | 842 | return ret; |
823 | } | 843 | } |
824 | 844 | ||
825 | if (eeh_subsystem_enabled) | 845 | if (eeh_enabled()) |
826 | pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n"); | 846 | pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n"); |
827 | else | 847 | else |
828 | pr_warning("EEH: No capable adapters found\n"); | 848 | pr_warning("EEH: No capable adapters found\n"); |
@@ -897,7 +917,7 @@ void eeh_add_device_late(struct pci_dev *dev) | |||
897 | struct device_node *dn; | 917 | struct device_node *dn; |
898 | struct eeh_dev *edev; | 918 | struct eeh_dev *edev; |
899 | 919 | ||
900 | if (!dev || !eeh_subsystem_enabled) | 920 | if (!dev || !eeh_enabled()) |
901 | return; | 921 | return; |
902 | 922 | ||
903 | pr_debug("EEH: Adding device %s\n", pci_name(dev)); | 923 | pr_debug("EEH: Adding device %s\n", pci_name(dev)); |
@@ -1005,7 +1025,7 @@ void eeh_remove_device(struct pci_dev *dev) | |||
1005 | { | 1025 | { |
1006 | struct eeh_dev *edev; | 1026 | struct eeh_dev *edev; |
1007 | 1027 | ||
1008 | if (!dev || !eeh_subsystem_enabled) | 1028 | if (!dev || !eeh_enabled()) |
1009 | return; | 1029 | return; |
1010 | edev = pci_dev_to_eeh_dev(dev); | 1030 | edev = pci_dev_to_eeh_dev(dev); |
1011 | 1031 | ||
@@ -1045,7 +1065,7 @@ void eeh_remove_device(struct pci_dev *dev) | |||
1045 | 1065 | ||
1046 | static int proc_eeh_show(struct seq_file *m, void *v) | 1066 | static int proc_eeh_show(struct seq_file *m, void *v) |
1047 | { | 1067 | { |
1048 | if (0 == eeh_subsystem_enabled) { | 1068 | if (!eeh_enabled()) { |
1049 | seq_printf(m, "EEH Subsystem is globally disabled\n"); | 1069 | seq_printf(m, "EEH Subsystem is globally disabled\n"); |
1050 | seq_printf(m, "eeh_total_mmio_ffs=%llu\n", eeh_stats.total_mmio_ffs); | 1070 | seq_printf(m, "eeh_total_mmio_ffs=%llu\n", eeh_stats.total_mmio_ffs); |
1051 | } else { | 1071 | } else { |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 9b27b293a922..b0ded97ee4e1 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -74,6 +74,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) | |||
74 | */ | 74 | */ |
75 | static int test_24bit_addr(unsigned long ip, unsigned long addr) | 75 | static int test_24bit_addr(unsigned long ip, unsigned long addr) |
76 | { | 76 | { |
77 | addr = ppc_function_entry((void *)addr); | ||
77 | 78 | ||
78 | /* use the create_branch to verify that this offset can be branched */ | 79 | /* use the create_branch to verify that this offset can be branched */ |
79 | return create_branch((unsigned int *)ip, addr, 0); | 80 | return create_branch((unsigned int *)ip, addr, 0); |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 879f09620f83..7c6bb4b17b49 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -57,11 +57,14 @@ _GLOBAL(call_do_softirq) | |||
57 | mtlr r0 | 57 | mtlr r0 |
58 | blr | 58 | blr |
59 | 59 | ||
60 | /* | ||
61 | * void call_do_irq(struct pt_regs *regs, struct thread_info *irqtp); | ||
62 | */ | ||
60 | _GLOBAL(call_do_irq) | 63 | _GLOBAL(call_do_irq) |
61 | mflr r0 | 64 | mflr r0 |
62 | stw r0,4(r1) | 65 | stw r0,4(r1) |
63 | lwz r10,THREAD+KSP_LIMIT(r2) | 66 | lwz r10,THREAD+KSP_LIMIT(r2) |
64 | addi r11,r3,THREAD_INFO_GAP | 67 | addi r11,r4,THREAD_INFO_GAP |
65 | stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) | 68 | stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) |
66 | mr r1,r4 | 69 | mr r1,r4 |
67 | stw r10,8(r1) | 70 | stw r10,8(r1) |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index e35bf773df7a..8d253c29649b 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -65,8 +65,8 @@ struct rt_sigframe { | |||
65 | struct siginfo __user *pinfo; | 65 | struct siginfo __user *pinfo; |
66 | void __user *puc; | 66 | void __user *puc; |
67 | struct siginfo info; | 67 | struct siginfo info; |
68 | /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ | 68 | /* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */ |
69 | char abigap[288]; | 69 | char abigap[USER_REDZONE_SIZE]; |
70 | } __attribute__ ((aligned (16))); | 70 | } __attribute__ ((aligned (16))); |
71 | 71 | ||
72 | static const char fmt32[] = KERN_INFO \ | 72 | static const char fmt32[] = KERN_INFO \ |
diff --git a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S index 79683d0393f5..6ac107ac402a 100644 --- a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S +++ b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S | |||
@@ -6,7 +6,7 @@ | |||
6 | .globl vdso32_start, vdso32_end | 6 | .globl vdso32_start, vdso32_end |
7 | .balign PAGE_SIZE | 7 | .balign PAGE_SIZE |
8 | vdso32_start: | 8 | vdso32_start: |
9 | .incbin "arch/powerpc/kernel/vdso32/vdso32.so" | 9 | .incbin "arch/powerpc/kernel/vdso32/vdso32.so.dbg" |
10 | .balign PAGE_SIZE | 10 | .balign PAGE_SIZE |
11 | vdso32_end: | 11 | vdso32_end: |
12 | 12 | ||
diff --git a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S index 8df9e2463007..df60fca6a13d 100644 --- a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S +++ b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S | |||
@@ -6,7 +6,7 @@ | |||
6 | .globl vdso64_start, vdso64_end | 6 | .globl vdso64_start, vdso64_end |
7 | .balign PAGE_SIZE | 7 | .balign PAGE_SIZE |
8 | vdso64_start: | 8 | vdso64_start: |
9 | .incbin "arch/powerpc/kernel/vdso64/vdso64.so" | 9 | .incbin "arch/powerpc/kernel/vdso64/vdso64.so.dbg" |
10 | .balign PAGE_SIZE | 10 | .balign PAGE_SIZE |
11 | vdso64_end: | 11 | vdso64_end: |
12 | 12 | ||
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 65b7b65e8708..62bf5e8e78da 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
@@ -510,7 +510,8 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address, | |||
510 | } | 510 | } |
511 | 511 | ||
512 | unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, | 512 | unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, |
513 | pmd_t *pmdp, unsigned long clr) | 513 | pmd_t *pmdp, unsigned long clr, |
514 | unsigned long set) | ||
514 | { | 515 | { |
515 | 516 | ||
516 | unsigned long old, tmp; | 517 | unsigned long old, tmp; |
@@ -526,14 +527,15 @@ unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, | |||
526 | andi. %1,%0,%6\n\ | 527 | andi. %1,%0,%6\n\ |
527 | bne- 1b \n\ | 528 | bne- 1b \n\ |
528 | andc %1,%0,%4 \n\ | 529 | andc %1,%0,%4 \n\ |
530 | or %1,%1,%7\n\ | ||
529 | stdcx. %1,0,%3 \n\ | 531 | stdcx. %1,0,%3 \n\ |
530 | bne- 1b" | 532 | bne- 1b" |
531 | : "=&r" (old), "=&r" (tmp), "=m" (*pmdp) | 533 | : "=&r" (old), "=&r" (tmp), "=m" (*pmdp) |
532 | : "r" (pmdp), "r" (clr), "m" (*pmdp), "i" (_PAGE_BUSY) | 534 | : "r" (pmdp), "r" (clr), "m" (*pmdp), "i" (_PAGE_BUSY), "r" (set) |
533 | : "cc" ); | 535 | : "cc" ); |
534 | #else | 536 | #else |
535 | old = pmd_val(*pmdp); | 537 | old = pmd_val(*pmdp); |
536 | *pmdp = __pmd(old & ~clr); | 538 | *pmdp = __pmd((old & ~clr) | set); |
537 | #endif | 539 | #endif |
538 | if (old & _PAGE_HASHPTE) | 540 | if (old & _PAGE_HASHPTE) |
539 | hpte_do_hugepage_flush(mm, addr, pmdp); | 541 | hpte_do_hugepage_flush(mm, addr, pmdp); |
@@ -708,7 +710,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
708 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 710 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
709 | pmd_t *pmdp) | 711 | pmd_t *pmdp) |
710 | { | 712 | { |
711 | pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT); | 713 | pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0); |
712 | } | 714 | } |
713 | 715 | ||
714 | /* | 716 | /* |
@@ -835,7 +837,7 @@ pmd_t pmdp_get_and_clear(struct mm_struct *mm, | |||
835 | unsigned long old; | 837 | unsigned long old; |
836 | pgtable_t *pgtable_slot; | 838 | pgtable_t *pgtable_slot; |
837 | 839 | ||
838 | old = pmd_hugepage_update(mm, addr, pmdp, ~0UL); | 840 | old = pmd_hugepage_update(mm, addr, pmdp, ~0UL, 0); |
839 | old_pmd = __pmd(old); | 841 | old_pmd = __pmd(old); |
840 | /* | 842 | /* |
841 | * We have pmd == none and we are holding page_table_lock. | 843 | * We have pmd == none and we are holding page_table_lock. |
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c index a770df2dae70..6c0b1f5f8d2c 100644 --- a/arch/powerpc/mm/subpage-prot.c +++ b/arch/powerpc/mm/subpage-prot.c | |||
@@ -78,7 +78,7 @@ static void hpte_flush_range(struct mm_struct *mm, unsigned long addr, | |||
78 | pte = pte_offset_map_lock(mm, pmd, addr, &ptl); | 78 | pte = pte_offset_map_lock(mm, pmd, addr, &ptl); |
79 | arch_enter_lazy_mmu_mode(); | 79 | arch_enter_lazy_mmu_mode(); |
80 | for (; npages > 0; --npages) { | 80 | for (; npages > 0; --npages) { |
81 | pte_update(mm, addr, pte, 0, 0); | 81 | pte_update(mm, addr, pte, 0, 0, 0); |
82 | addr += PAGE_SIZE; | 82 | addr += PAGE_SIZE; |
83 | ++pte; | 83 | ++pte; |
84 | } | 84 | } |
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index e1e71618b70c..253fefe3d1a0 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
@@ -44,7 +44,8 @@ static int ioda_eeh_event(struct notifier_block *nb, | |||
44 | 44 | ||
45 | /* We simply send special EEH event */ | 45 | /* We simply send special EEH event */ |
46 | if ((changed_evts & OPAL_EVENT_PCI_ERROR) && | 46 | if ((changed_evts & OPAL_EVENT_PCI_ERROR) && |
47 | (events & OPAL_EVENT_PCI_ERROR)) | 47 | (events & OPAL_EVENT_PCI_ERROR) && |
48 | eeh_enabled()) | ||
48 | eeh_send_failure_event(NULL); | 49 | eeh_send_failure_event(NULL); |
49 | 50 | ||
50 | return 0; | 51 | return 0; |
@@ -113,6 +114,7 @@ DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, ioda_eeh_inbB_dbgfs_get, | |||
113 | ioda_eeh_inbB_dbgfs_set, "0x%llx\n"); | 114 | ioda_eeh_inbB_dbgfs_set, "0x%llx\n"); |
114 | #endif /* CONFIG_DEBUG_FS */ | 115 | #endif /* CONFIG_DEBUG_FS */ |
115 | 116 | ||
117 | |||
116 | /** | 118 | /** |
117 | * ioda_eeh_post_init - Chip dependent post initialization | 119 | * ioda_eeh_post_init - Chip dependent post initialization |
118 | * @hose: PCI controller | 120 | * @hose: PCI controller |
@@ -220,6 +222,22 @@ static int ioda_eeh_set_option(struct eeh_pe *pe, int option) | |||
220 | return ret; | 222 | return ret; |
221 | } | 223 | } |
222 | 224 | ||
225 | static void ioda_eeh_phb_diag(struct pci_controller *hose) | ||
226 | { | ||
227 | struct pnv_phb *phb = hose->private_data; | ||
228 | long rc; | ||
229 | |||
230 | rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, | ||
231 | PNV_PCI_DIAG_BUF_SIZE); | ||
232 | if (rc != OPAL_SUCCESS) { | ||
233 | pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", | ||
234 | __func__, hose->global_number, rc); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); | ||
239 | } | ||
240 | |||
223 | /** | 241 | /** |
224 | * ioda_eeh_get_state - Retrieve the state of PE | 242 | * ioda_eeh_get_state - Retrieve the state of PE |
225 | * @pe: EEH PE | 243 | * @pe: EEH PE |
@@ -271,6 +289,9 @@ static int ioda_eeh_get_state(struct eeh_pe *pe) | |||
271 | result |= EEH_STATE_DMA_ACTIVE; | 289 | result |= EEH_STATE_DMA_ACTIVE; |
272 | result |= EEH_STATE_MMIO_ENABLED; | 290 | result |= EEH_STATE_MMIO_ENABLED; |
273 | result |= EEH_STATE_DMA_ENABLED; | 291 | result |= EEH_STATE_DMA_ENABLED; |
292 | } else if (!(pe->state & EEH_PE_ISOLATED)) { | ||
293 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); | ||
294 | ioda_eeh_phb_diag(hose); | ||
274 | } | 295 | } |
275 | 296 | ||
276 | return result; | 297 | return result; |
@@ -314,6 +335,15 @@ static int ioda_eeh_get_state(struct eeh_pe *pe) | |||
314 | __func__, fstate, hose->global_number, pe_no); | 335 | __func__, fstate, hose->global_number, pe_no); |
315 | } | 336 | } |
316 | 337 | ||
338 | /* Dump PHB diag-data for frozen PE */ | ||
339 | if (result != EEH_STATE_NOT_SUPPORT && | ||
340 | (result & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) != | ||
341 | (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE) && | ||
342 | !(pe->state & EEH_PE_ISOLATED)) { | ||
343 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); | ||
344 | ioda_eeh_phb_diag(hose); | ||
345 | } | ||
346 | |||
317 | return result; | 347 | return result; |
318 | } | 348 | } |
319 | 349 | ||
@@ -489,8 +519,7 @@ static int ioda_eeh_bridge_reset(struct pci_controller *hose, | |||
489 | static int ioda_eeh_reset(struct eeh_pe *pe, int option) | 519 | static int ioda_eeh_reset(struct eeh_pe *pe, int option) |
490 | { | 520 | { |
491 | struct pci_controller *hose = pe->phb; | 521 | struct pci_controller *hose = pe->phb; |
492 | struct eeh_dev *edev; | 522 | struct pci_bus *bus; |
493 | struct pci_dev *dev; | ||
494 | int ret; | 523 | int ret; |
495 | 524 | ||
496 | /* | 525 | /* |
@@ -519,73 +548,17 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) | |||
519 | if (pe->type & EEH_PE_PHB) { | 548 | if (pe->type & EEH_PE_PHB) { |
520 | ret = ioda_eeh_phb_reset(hose, option); | 549 | ret = ioda_eeh_phb_reset(hose, option); |
521 | } else { | 550 | } else { |
522 | if (pe->type & EEH_PE_DEVICE) { | 551 | bus = eeh_pe_bus_get(pe); |
523 | /* | 552 | if (pci_is_root_bus(bus)) |
524 | * If it's device PE, we didn't refer to the parent | ||
525 | * PCI bus yet. So we have to figure it out indirectly. | ||
526 | */ | ||
527 | edev = list_first_entry(&pe->edevs, | ||
528 | struct eeh_dev, list); | ||
529 | dev = eeh_dev_to_pci_dev(edev); | ||
530 | dev = dev->bus->self; | ||
531 | } else { | ||
532 | /* | ||
533 | * If it's bus PE, the parent PCI bus is already there | ||
534 | * and just pick it up. | ||
535 | */ | ||
536 | dev = pe->bus->self; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Do reset based on the fact that the direct upstream bridge | ||
541 | * is root bridge (port) or not. | ||
542 | */ | ||
543 | if (dev->bus->number == 0) | ||
544 | ret = ioda_eeh_root_reset(hose, option); | 553 | ret = ioda_eeh_root_reset(hose, option); |
545 | else | 554 | else |
546 | ret = ioda_eeh_bridge_reset(hose, dev, option); | 555 | ret = ioda_eeh_bridge_reset(hose, bus->self, option); |
547 | } | 556 | } |
548 | 557 | ||
549 | return ret; | 558 | return ret; |
550 | } | 559 | } |
551 | 560 | ||
552 | /** | 561 | /** |
553 | * ioda_eeh_get_log - Retrieve error log | ||
554 | * @pe: EEH PE | ||
555 | * @severity: Severity level of the log | ||
556 | * @drv_log: buffer to store the log | ||
557 | * @len: space of the log buffer | ||
558 | * | ||
559 | * The function is used to retrieve error log from P7IOC. | ||
560 | */ | ||
561 | static int ioda_eeh_get_log(struct eeh_pe *pe, int severity, | ||
562 | char *drv_log, unsigned long len) | ||
563 | { | ||
564 | s64 ret; | ||
565 | unsigned long flags; | ||
566 | struct pci_controller *hose = pe->phb; | ||
567 | struct pnv_phb *phb = hose->private_data; | ||
568 | |||
569 | spin_lock_irqsave(&phb->lock, flags); | ||
570 | |||
571 | ret = opal_pci_get_phb_diag_data2(phb->opal_id, | ||
572 | phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); | ||
573 | if (ret) { | ||
574 | spin_unlock_irqrestore(&phb->lock, flags); | ||
575 | pr_warning("%s: Can't get log for PHB#%x-PE#%x (%lld)\n", | ||
576 | __func__, hose->global_number, pe->addr, ret); | ||
577 | return -EIO; | ||
578 | } | ||
579 | |||
580 | /* The PHB diag-data is always indicative */ | ||
581 | pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); | ||
582 | |||
583 | spin_unlock_irqrestore(&phb->lock, flags); | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE | 562 | * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE |
590 | * @pe: EEH PE | 563 | * @pe: EEH PE |
591 | * | 564 | * |
@@ -666,22 +639,6 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose) | |||
666 | } | 639 | } |
667 | } | 640 | } |
668 | 641 | ||
669 | static void ioda_eeh_phb_diag(struct pci_controller *hose) | ||
670 | { | ||
671 | struct pnv_phb *phb = hose->private_data; | ||
672 | long rc; | ||
673 | |||
674 | rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, | ||
675 | PNV_PCI_DIAG_BUF_SIZE); | ||
676 | if (rc != OPAL_SUCCESS) { | ||
677 | pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", | ||
678 | __func__, hose->global_number, rc); | ||
679 | return; | ||
680 | } | ||
681 | |||
682 | pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); | ||
683 | } | ||
684 | |||
685 | static int ioda_eeh_get_phb_pe(struct pci_controller *hose, | 642 | static int ioda_eeh_get_phb_pe(struct pci_controller *hose, |
686 | struct eeh_pe **pe) | 643 | struct eeh_pe **pe) |
687 | { | 644 | { |
@@ -855,6 +812,20 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
855 | } | 812 | } |
856 | 813 | ||
857 | /* | 814 | /* |
815 | * EEH core will try recover from fenced PHB or | ||
816 | * frozen PE. In the time for frozen PE, EEH core | ||
817 | * enable IO path for that before collecting logs, | ||
818 | * but it ruins the site. So we have to dump the | ||
819 | * log in advance here. | ||
820 | */ | ||
821 | if ((ret == EEH_NEXT_ERR_FROZEN_PE || | ||
822 | ret == EEH_NEXT_ERR_FENCED_PHB) && | ||
823 | !((*pe)->state & EEH_PE_ISOLATED)) { | ||
824 | eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); | ||
825 | ioda_eeh_phb_diag(hose); | ||
826 | } | ||
827 | |||
828 | /* | ||
858 | * If we have no errors on the specific PHB or only | 829 | * If we have no errors on the specific PHB or only |
859 | * informative error there, we continue poking it. | 830 | * informative error there, we continue poking it. |
860 | * Otherwise, we need actions to be taken by upper | 831 | * Otherwise, we need actions to be taken by upper |
@@ -872,7 +843,6 @@ struct pnv_eeh_ops ioda_eeh_ops = { | |||
872 | .set_option = ioda_eeh_set_option, | 843 | .set_option = ioda_eeh_set_option, |
873 | .get_state = ioda_eeh_get_state, | 844 | .get_state = ioda_eeh_get_state, |
874 | .reset = ioda_eeh_reset, | 845 | .reset = ioda_eeh_reset, |
875 | .get_log = ioda_eeh_get_log, | ||
876 | .configure_bridge = ioda_eeh_configure_bridge, | 846 | .configure_bridge = ioda_eeh_configure_bridge, |
877 | .next_error = ioda_eeh_next_error | 847 | .next_error = ioda_eeh_next_error |
878 | }; | 848 | }; |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index a79fddc5e74e..a59788e83b8b 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
@@ -145,7 +145,7 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
145 | * Enable EEH explicitly so that we will do EEH check | 145 | * Enable EEH explicitly so that we will do EEH check |
146 | * while accessing I/O stuff | 146 | * while accessing I/O stuff |
147 | */ | 147 | */ |
148 | eeh_subsystem_enabled = 1; | 148 | eeh_set_enable(true); |
149 | 149 | ||
150 | /* Save memory bars */ | 150 | /* Save memory bars */ |
151 | eeh_save_bars(edev); | 151 | eeh_save_bars(edev); |
diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 4fbf276ac99e..4cd2ea6c0dbe 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c | |||
@@ -71,11 +71,11 @@ static int opal_xscom_err_xlate(int64_t rc) | |||
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | static u64 opal_scom_unmangle(u64 reg) | 74 | static u64 opal_scom_unmangle(u64 addr) |
75 | { | 75 | { |
76 | /* | 76 | /* |
77 | * XSCOM indirect addresses have the top bit set. Additionally | 77 | * XSCOM indirect addresses have the top bit set. Additionally |
78 | * the reset of the top 3 nibbles is always 0. | 78 | * the rest of the top 3 nibbles is always 0. |
79 | * | 79 | * |
80 | * Because the debugfs interface uses signed offsets and shifts | 80 | * Because the debugfs interface uses signed offsets and shifts |
81 | * the address left by 3, we basically cannot use the top 4 bits | 81 | * the address left by 3, we basically cannot use the top 4 bits |
@@ -86,10 +86,13 @@ static u64 opal_scom_unmangle(u64 reg) | |||
86 | * conversion here. To leave room for further xscom address | 86 | * conversion here. To leave room for further xscom address |
87 | * expansion, we only clear out the top byte | 87 | * expansion, we only clear out the top byte |
88 | * | 88 | * |
89 | * For in-kernel use, we also support the real indirect bit, so | ||
90 | * we test for any of the top 5 bits | ||
91 | * | ||
89 | */ | 92 | */ |
90 | if (reg & (1ull << 59)) | 93 | if (addr & (0x1full << 59)) |
91 | reg = (reg & ~(0xffull << 56)) | (1ull << 63); | 94 | addr = (addr & ~(0xffull << 56)) | (1ull << 63); |
92 | return reg; | 95 | return addr; |
93 | } | 96 | } |
94 | 97 | ||
95 | static int opal_scom_read(scom_map_t map, u64 reg, u64 *value) | 98 | static int opal_scom_read(scom_map_t map, u64 reg, u64 *value) |
@@ -98,8 +101,8 @@ static int opal_scom_read(scom_map_t map, u64 reg, u64 *value) | |||
98 | int64_t rc; | 101 | int64_t rc; |
99 | __be64 v; | 102 | __be64 v; |
100 | 103 | ||
101 | reg = opal_scom_unmangle(reg); | 104 | reg = opal_scom_unmangle(m->addr + reg); |
102 | rc = opal_xscom_read(m->chip, m->addr + reg, (__be64 *)__pa(&v)); | 105 | rc = opal_xscom_read(m->chip, reg, (__be64 *)__pa(&v)); |
103 | *value = be64_to_cpu(v); | 106 | *value = be64_to_cpu(v); |
104 | return opal_xscom_err_xlate(rc); | 107 | return opal_xscom_err_xlate(rc); |
105 | } | 108 | } |
@@ -109,8 +112,8 @@ static int opal_scom_write(scom_map_t map, u64 reg, u64 value) | |||
109 | struct opal_scom_map *m = map; | 112 | struct opal_scom_map *m = map; |
110 | int64_t rc; | 113 | int64_t rc; |
111 | 114 | ||
112 | reg = opal_scom_unmangle(reg); | 115 | reg = opal_scom_unmangle(m->addr + reg); |
113 | rc = opal_xscom_write(m->chip, m->addr + reg, value); | 116 | rc = opal_xscom_write(m->chip, reg, value); |
114 | return opal_xscom_err_xlate(rc); | 117 | return opal_xscom_err_xlate(rc); |
115 | } | 118 | } |
116 | 119 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 95633d79ef5d..8518817dcdfd 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -134,57 +134,72 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose, | |||
134 | pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n\n", | 134 | pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n\n", |
135 | hose->global_number, common->version); | 135 | hose->global_number, common->version); |
136 | 136 | ||
137 | pr_info(" brdgCtl: %08x\n", data->brdgCtl); | 137 | if (data->brdgCtl) |
138 | 138 | pr_info(" brdgCtl: %08x\n", | |
139 | pr_info(" portStatusReg: %08x\n", data->portStatusReg); | 139 | data->brdgCtl); |
140 | pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); | 140 | if (data->portStatusReg || data->rootCmplxStatus || |
141 | pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); | 141 | data->busAgentStatus) |
142 | 142 | pr_info(" UtlSts: %08x %08x %08x\n", | |
143 | pr_info(" deviceStatus: %08x\n", data->deviceStatus); | 143 | data->portStatusReg, data->rootCmplxStatus, |
144 | pr_info(" slotStatus: %08x\n", data->slotStatus); | 144 | data->busAgentStatus); |
145 | pr_info(" linkStatus: %08x\n", data->linkStatus); | 145 | if (data->deviceStatus || data->slotStatus || |
146 | pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); | 146 | data->linkStatus || data->devCmdStatus || |
147 | pr_info(" devSecStatus: %08x\n", data->devSecStatus); | 147 | data->devSecStatus) |
148 | 148 | pr_info(" RootSts: %08x %08x %08x %08x %08x\n", | |
149 | pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); | 149 | data->deviceStatus, data->slotStatus, |
150 | pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); | 150 | data->linkStatus, data->devCmdStatus, |
151 | pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); | 151 | data->devSecStatus); |
152 | pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); | 152 | if (data->rootErrorStatus || data->uncorrErrorStatus || |
153 | pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); | 153 | data->corrErrorStatus) |
154 | pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); | 154 | pr_info(" RootErrSts: %08x %08x %08x\n", |
155 | pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); | 155 | data->rootErrorStatus, data->uncorrErrorStatus, |
156 | pr_info(" sourceId: %08x\n", data->sourceId); | 156 | data->corrErrorStatus); |
157 | pr_info(" errorClass: %016llx\n", data->errorClass); | 157 | if (data->tlpHdr1 || data->tlpHdr2 || |
158 | pr_info(" correlator: %016llx\n", data->correlator); | 158 | data->tlpHdr3 || data->tlpHdr4) |
159 | pr_info(" p7iocPlssr: %016llx\n", data->p7iocPlssr); | 159 | pr_info(" RootErrLog: %08x %08x %08x %08x\n", |
160 | pr_info(" p7iocCsr: %016llx\n", data->p7iocCsr); | 160 | data->tlpHdr1, data->tlpHdr2, |
161 | pr_info(" lemFir: %016llx\n", data->lemFir); | 161 | data->tlpHdr3, data->tlpHdr4); |
162 | pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); | 162 | if (data->sourceId || data->errorClass || |
163 | pr_info(" lemWOF: %016llx\n", data->lemWOF); | 163 | data->correlator) |
164 | pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); | 164 | pr_info(" RootErrLog1: %08x %016llx %016llx\n", |
165 | pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); | 165 | data->sourceId, data->errorClass, |
166 | pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); | 166 | data->correlator); |
167 | pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); | 167 | if (data->p7iocPlssr || data->p7iocCsr) |
168 | pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); | 168 | pr_info(" PhbSts: %016llx %016llx\n", |
169 | pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); | 169 | data->p7iocPlssr, data->p7iocCsr); |
170 | pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); | 170 | if (data->lemFir || data->lemErrorMask || |
171 | pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); | 171 | data->lemWOF) |
172 | pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); | 172 | pr_info(" Lem: %016llx %016llx %016llx\n", |
173 | pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); | 173 | data->lemFir, data->lemErrorMask, |
174 | pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); | 174 | data->lemWOF); |
175 | pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); | 175 | if (data->phbErrorStatus || data->phbFirstErrorStatus || |
176 | pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); | 176 | data->phbErrorLog0 || data->phbErrorLog1) |
177 | pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); | 177 | pr_info(" PhbErr: %016llx %016llx %016llx %016llx\n", |
178 | pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); | 178 | data->phbErrorStatus, data->phbFirstErrorStatus, |
179 | pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); | 179 | data->phbErrorLog0, data->phbErrorLog1); |
180 | if (data->mmioErrorStatus || data->mmioFirstErrorStatus || | ||
181 | data->mmioErrorLog0 || data->mmioErrorLog1) | ||
182 | pr_info(" OutErr: %016llx %016llx %016llx %016llx\n", | ||
183 | data->mmioErrorStatus, data->mmioFirstErrorStatus, | ||
184 | data->mmioErrorLog0, data->mmioErrorLog1); | ||
185 | if (data->dma0ErrorStatus || data->dma0FirstErrorStatus || | ||
186 | data->dma0ErrorLog0 || data->dma0ErrorLog1) | ||
187 | pr_info(" InAErr: %016llx %016llx %016llx %016llx\n", | ||
188 | data->dma0ErrorStatus, data->dma0FirstErrorStatus, | ||
189 | data->dma0ErrorLog0, data->dma0ErrorLog1); | ||
190 | if (data->dma1ErrorStatus || data->dma1FirstErrorStatus || | ||
191 | data->dma1ErrorLog0 || data->dma1ErrorLog1) | ||
192 | pr_info(" InBErr: %016llx %016llx %016llx %016llx\n", | ||
193 | data->dma1ErrorStatus, data->dma1FirstErrorStatus, | ||
194 | data->dma1ErrorLog0, data->dma1ErrorLog1); | ||
180 | 195 | ||
181 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { | 196 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { |
182 | if ((data->pestA[i] >> 63) == 0 && | 197 | if ((data->pestA[i] >> 63) == 0 && |
183 | (data->pestB[i] >> 63) == 0) | 198 | (data->pestB[i] >> 63) == 0) |
184 | continue; | 199 | continue; |
185 | 200 | ||
186 | pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); | 201 | pr_info(" PE[%3d] A/B: %016llx %016llx\n", |
187 | pr_info(" PESTB: %016llx\n", data->pestB[i]); | 202 | i, data->pestA[i], data->pestB[i]); |
188 | } | 203 | } |
189 | } | 204 | } |
190 | 205 | ||
@@ -197,62 +212,77 @@ static void pnv_pci_dump_phb3_diag_data(struct pci_controller *hose, | |||
197 | data = (struct OpalIoPhb3ErrorData*)common; | 212 | data = (struct OpalIoPhb3ErrorData*)common; |
198 | pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n\n", | 213 | pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n\n", |
199 | hose->global_number, common->version); | 214 | hose->global_number, common->version); |
200 | 215 | if (data->brdgCtl) | |
201 | pr_info(" brdgCtl: %08x\n", data->brdgCtl); | 216 | pr_info(" brdgCtl: %08x\n", |
202 | 217 | data->brdgCtl); | |
203 | pr_info(" portStatusReg: %08x\n", data->portStatusReg); | 218 | if (data->portStatusReg || data->rootCmplxStatus || |
204 | pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); | 219 | data->busAgentStatus) |
205 | pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); | 220 | pr_info(" UtlSts: %08x %08x %08x\n", |
206 | 221 | data->portStatusReg, data->rootCmplxStatus, | |
207 | pr_info(" deviceStatus: %08x\n", data->deviceStatus); | 222 | data->busAgentStatus); |
208 | pr_info(" slotStatus: %08x\n", data->slotStatus); | 223 | if (data->deviceStatus || data->slotStatus || |
209 | pr_info(" linkStatus: %08x\n", data->linkStatus); | 224 | data->linkStatus || data->devCmdStatus || |
210 | pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); | 225 | data->devSecStatus) |
211 | pr_info(" devSecStatus: %08x\n", data->devSecStatus); | 226 | pr_info(" RootSts: %08x %08x %08x %08x %08x\n", |
212 | 227 | data->deviceStatus, data->slotStatus, | |
213 | pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); | 228 | data->linkStatus, data->devCmdStatus, |
214 | pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); | 229 | data->devSecStatus); |
215 | pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); | 230 | if (data->rootErrorStatus || data->uncorrErrorStatus || |
216 | pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); | 231 | data->corrErrorStatus) |
217 | pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); | 232 | pr_info(" RootErrSts: %08x %08x %08x\n", |
218 | pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); | 233 | data->rootErrorStatus, data->uncorrErrorStatus, |
219 | pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); | 234 | data->corrErrorStatus); |
220 | pr_info(" sourceId: %08x\n", data->sourceId); | 235 | if (data->tlpHdr1 || data->tlpHdr2 || |
221 | pr_info(" errorClass: %016llx\n", data->errorClass); | 236 | data->tlpHdr3 || data->tlpHdr4) |
222 | pr_info(" correlator: %016llx\n", data->correlator); | 237 | pr_info(" RootErrLog: %08x %08x %08x %08x\n", |
223 | 238 | data->tlpHdr1, data->tlpHdr2, | |
224 | pr_info(" nFir: %016llx\n", data->nFir); | 239 | data->tlpHdr3, data->tlpHdr4); |
225 | pr_info(" nFirMask: %016llx\n", data->nFirMask); | 240 | if (data->sourceId || data->errorClass || |
226 | pr_info(" nFirWOF: %016llx\n", data->nFirWOF); | 241 | data->correlator) |
227 | pr_info(" PhbPlssr: %016llx\n", data->phbPlssr); | 242 | pr_info(" RootErrLog1: %08x %016llx %016llx\n", |
228 | pr_info(" PhbCsr: %016llx\n", data->phbCsr); | 243 | data->sourceId, data->errorClass, |
229 | pr_info(" lemFir: %016llx\n", data->lemFir); | 244 | data->correlator); |
230 | pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); | 245 | if (data->nFir || data->nFirMask || |
231 | pr_info(" lemWOF: %016llx\n", data->lemWOF); | 246 | data->nFirWOF) |
232 | pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); | 247 | pr_info(" nFir: %016llx %016llx %016llx\n", |
233 | pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); | 248 | data->nFir, data->nFirMask, |
234 | pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); | 249 | data->nFirWOF); |
235 | pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); | 250 | if (data->phbPlssr || data->phbCsr) |
236 | pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); | 251 | pr_info(" PhbSts: %016llx %016llx\n", |
237 | pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); | 252 | data->phbPlssr, data->phbCsr); |
238 | pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); | 253 | if (data->lemFir || data->lemErrorMask || |
239 | pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); | 254 | data->lemWOF) |
240 | pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); | 255 | pr_info(" Lem: %016llx %016llx %016llx\n", |
241 | pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); | 256 | data->lemFir, data->lemErrorMask, |
242 | pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); | 257 | data->lemWOF); |
243 | pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); | 258 | if (data->phbErrorStatus || data->phbFirstErrorStatus || |
244 | pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); | 259 | data->phbErrorLog0 || data->phbErrorLog1) |
245 | pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); | 260 | pr_info(" PhbErr: %016llx %016llx %016llx %016llx\n", |
246 | pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); | 261 | data->phbErrorStatus, data->phbFirstErrorStatus, |
247 | pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); | 262 | data->phbErrorLog0, data->phbErrorLog1); |
263 | if (data->mmioErrorStatus || data->mmioFirstErrorStatus || | ||
264 | data->mmioErrorLog0 || data->mmioErrorLog1) | ||
265 | pr_info(" OutErr: %016llx %016llx %016llx %016llx\n", | ||
266 | data->mmioErrorStatus, data->mmioFirstErrorStatus, | ||
267 | data->mmioErrorLog0, data->mmioErrorLog1); | ||
268 | if (data->dma0ErrorStatus || data->dma0FirstErrorStatus || | ||
269 | data->dma0ErrorLog0 || data->dma0ErrorLog1) | ||
270 | pr_info(" InAErr: %016llx %016llx %016llx %016llx\n", | ||
271 | data->dma0ErrorStatus, data->dma0FirstErrorStatus, | ||
272 | data->dma0ErrorLog0, data->dma0ErrorLog1); | ||
273 | if (data->dma1ErrorStatus || data->dma1FirstErrorStatus || | ||
274 | data->dma1ErrorLog0 || data->dma1ErrorLog1) | ||
275 | pr_info(" InBErr: %016llx %016llx %016llx %016llx\n", | ||
276 | data->dma1ErrorStatus, data->dma1FirstErrorStatus, | ||
277 | data->dma1ErrorLog0, data->dma1ErrorLog1); | ||
248 | 278 | ||
249 | for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { | 279 | for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { |
250 | if ((data->pestA[i] >> 63) == 0 && | 280 | if ((data->pestA[i] >> 63) == 0 && |
251 | (data->pestB[i] >> 63) == 0) | 281 | (data->pestB[i] >> 63) == 0) |
252 | continue; | 282 | continue; |
253 | 283 | ||
254 | pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); | 284 | pr_info(" PE[%3d] A/B: %016llx %016llx\n", |
255 | pr_info(" PESTB: %016llx\n", data->pestB[i]); | 285 | i, data->pestA[i], data->pestB[i]); |
256 | } | 286 | } |
257 | } | 287 | } |
258 | 288 | ||
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 9ef3cc8ebc11..8a8f0472d98f 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c | |||
@@ -265,7 +265,7 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) | |||
265 | enable = 1; | 265 | enable = 1; |
266 | 266 | ||
267 | if (enable) { | 267 | if (enable) { |
268 | eeh_subsystem_enabled = 1; | 268 | eeh_set_enable(true); |
269 | eeh_add_to_parent_pe(edev); | 269 | eeh_add_to_parent_pe(edev); |
270 | 270 | ||
271 | pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", | 271 | pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 82789e79e539..0ea99e3d4815 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -35,12 +35,7 @@ | |||
35 | #include "offline_states.h" | 35 | #include "offline_states.h" |
36 | 36 | ||
37 | /* This version can't take the spinlock, because it never returns */ | 37 | /* This version can't take the spinlock, because it never returns */ |
38 | static struct rtas_args rtas_stop_self_args = { | 38 | static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE; |
39 | .token = RTAS_UNKNOWN_SERVICE, | ||
40 | .nargs = 0, | ||
41 | .nret = 1, | ||
42 | .rets = &rtas_stop_self_args.args[0], | ||
43 | }; | ||
44 | 39 | ||
45 | static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) = | 40 | static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) = |
46 | CPU_STATE_OFFLINE; | 41 | CPU_STATE_OFFLINE; |
@@ -93,15 +88,20 @@ void set_default_offline_state(int cpu) | |||
93 | 88 | ||
94 | static void rtas_stop_self(void) | 89 | static void rtas_stop_self(void) |
95 | { | 90 | { |
96 | struct rtas_args *args = &rtas_stop_self_args; | 91 | struct rtas_args args = { |
92 | .token = cpu_to_be32(rtas_stop_self_token), | ||
93 | .nargs = 0, | ||
94 | .nret = 1, | ||
95 | .rets = &args.args[0], | ||
96 | }; | ||
97 | 97 | ||
98 | local_irq_disable(); | 98 | local_irq_disable(); |
99 | 99 | ||
100 | BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); | 100 | BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); |
101 | 101 | ||
102 | printk("cpu %u (hwid %u) Ready to die...\n", | 102 | printk("cpu %u (hwid %u) Ready to die...\n", |
103 | smp_processor_id(), hard_smp_processor_id()); | 103 | smp_processor_id(), hard_smp_processor_id()); |
104 | enter_rtas(__pa(args)); | 104 | enter_rtas(__pa(&args)); |
105 | 105 | ||
106 | panic("Alas, I survived.\n"); | 106 | panic("Alas, I survived.\n"); |
107 | } | 107 | } |
@@ -392,10 +392,10 @@ static int __init pseries_cpu_hotplug_init(void) | |||
392 | } | 392 | } |
393 | } | 393 | } |
394 | 394 | ||
395 | rtas_stop_self_args.token = rtas_token("stop-self"); | 395 | rtas_stop_self_token = rtas_token("stop-self"); |
396 | qcss_tok = rtas_token("query-cpu-stopped-state"); | 396 | qcss_tok = rtas_token("query-cpu-stopped-state"); |
397 | 397 | ||
398 | if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || | 398 | if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE || |
399 | qcss_tok == RTAS_UNKNOWN_SERVICE) { | 399 | qcss_tok == RTAS_UNKNOWN_SERVICE) { |
400 | printk(KERN_INFO "CPU Hotplug not supported by firmware " | 400 | printk(KERN_INFO "CPU Hotplug not supported by firmware " |
401 | "- disabling.\n"); | 401 | "- disabling.\n"); |
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 70670a2d9cf2..c413ec158ff5 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c | |||
@@ -113,7 +113,8 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
113 | { | 113 | { |
114 | struct device_node *dn, *pdn; | 114 | struct device_node *dn, *pdn; |
115 | struct pci_bus *bus; | 115 | struct pci_bus *bus; |
116 | const __be32 *pcie_link_speed_stats; | 116 | u32 pcie_link_speed_stats[2]; |
117 | int rc; | ||
117 | 118 | ||
118 | bus = bridge->bus; | 119 | bus = bridge->bus; |
119 | 120 | ||
@@ -122,38 +123,45 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
122 | return 0; | 123 | return 0; |
123 | 124 | ||
124 | for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) { | 125 | for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) { |
125 | pcie_link_speed_stats = of_get_property(pdn, | 126 | rc = of_property_read_u32_array(pdn, |
126 | "ibm,pcie-link-speed-stats", NULL); | 127 | "ibm,pcie-link-speed-stats", |
127 | if (pcie_link_speed_stats) | 128 | &pcie_link_speed_stats[0], 2); |
129 | if (!rc) | ||
128 | break; | 130 | break; |
129 | } | 131 | } |
130 | 132 | ||
131 | of_node_put(pdn); | 133 | of_node_put(pdn); |
132 | 134 | ||
133 | if (!pcie_link_speed_stats) { | 135 | if (rc) { |
134 | pr_err("no ibm,pcie-link-speed-stats property\n"); | 136 | pr_err("no ibm,pcie-link-speed-stats property\n"); |
135 | return 0; | 137 | return 0; |
136 | } | 138 | } |
137 | 139 | ||
138 | switch (be32_to_cpup(pcie_link_speed_stats)) { | 140 | switch (pcie_link_speed_stats[0]) { |
139 | case 0x01: | 141 | case 0x01: |
140 | bus->max_bus_speed = PCIE_SPEED_2_5GT; | 142 | bus->max_bus_speed = PCIE_SPEED_2_5GT; |
141 | break; | 143 | break; |
142 | case 0x02: | 144 | case 0x02: |
143 | bus->max_bus_speed = PCIE_SPEED_5_0GT; | 145 | bus->max_bus_speed = PCIE_SPEED_5_0GT; |
144 | break; | 146 | break; |
147 | case 0x04: | ||
148 | bus->max_bus_speed = PCIE_SPEED_8_0GT; | ||
149 | break; | ||
145 | default: | 150 | default: |
146 | bus->max_bus_speed = PCI_SPEED_UNKNOWN; | 151 | bus->max_bus_speed = PCI_SPEED_UNKNOWN; |
147 | break; | 152 | break; |
148 | } | 153 | } |
149 | 154 | ||
150 | switch (be32_to_cpup(pcie_link_speed_stats)) { | 155 | switch (pcie_link_speed_stats[1]) { |
151 | case 0x01: | 156 | case 0x01: |
152 | bus->cur_bus_speed = PCIE_SPEED_2_5GT; | 157 | bus->cur_bus_speed = PCIE_SPEED_2_5GT; |
153 | break; | 158 | break; |
154 | case 0x02: | 159 | case 0x02: |
155 | bus->cur_bus_speed = PCIE_SPEED_5_0GT; | 160 | bus->cur_bus_speed = PCIE_SPEED_5_0GT; |
156 | break; | 161 | break; |
162 | case 0x04: | ||
163 | bus->cur_bus_speed = PCIE_SPEED_8_0GT; | ||
164 | break; | ||
157 | default: | 165 | default: |
158 | bus->cur_bus_speed = PCI_SPEED_UNKNOWN; | 166 | bus->cur_bus_speed = PCI_SPEED_UNKNOWN; |
159 | break; | 167 | break; |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 59c8efce1b99..0248949a756d 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1421,5 +1421,5 @@ ENTRY(sys_sched_setattr_wrapper) | |||
1421 | ENTRY(sys_sched_getattr_wrapper) | 1421 | ENTRY(sys_sched_getattr_wrapper) |
1422 | lgfr %r2,%r2 # pid_t | 1422 | lgfr %r2,%r2 # pid_t |
1423 | llgtr %r3,%r3 # const char __user * | 1423 | llgtr %r3,%r3 # const char __user * |
1424 | llgfr %r3,%r3 # unsigned int | 1424 | llgfr %r4,%r4 # unsigned int |
1425 | jg sys_sched_getattr | 1425 | jg sys_sched_getattr |
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 60c11a629d96..f91c03119804 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c | |||
@@ -206,11 +206,13 @@ static void dma_cleanup_tables(struct zpci_dev *zdev) | |||
206 | zdev->dma_table = NULL; | 206 | zdev->dma_table = NULL; |
207 | } | 207 | } |
208 | 208 | ||
209 | static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev, unsigned long start, | 209 | static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev, |
210 | int size) | 210 | unsigned long start, int size) |
211 | { | 211 | { |
212 | unsigned long boundary_size = 0x1000000; | 212 | unsigned long boundary_size; |
213 | 213 | ||
214 | boundary_size = ALIGN(dma_get_seg_boundary(&zdev->pdev->dev) + 1, | ||
215 | PAGE_SIZE) >> PAGE_SHIFT; | ||
214 | return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages, | 216 | return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages, |
215 | start, size, 0, boundary_size, 0); | 217 | start, size, 0, boundary_size, 0); |
216 | } | 218 | } |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index c51efdcd07a2..7d8b7e94b93b 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -27,7 +27,7 @@ config SPARC | |||
27 | select RTC_DRV_M48T59 | 27 | select RTC_DRV_M48T59 |
28 | select HAVE_DMA_ATTRS | 28 | select HAVE_DMA_ATTRS |
29 | select HAVE_DMA_API_DEBUG | 29 | select HAVE_DMA_API_DEBUG |
30 | select HAVE_ARCH_JUMP_LABEL | 30 | select HAVE_ARCH_JUMP_LABEL if SPARC64 |
31 | select GENERIC_IRQ_SHOW | 31 | select GENERIC_IRQ_SHOW |
32 | select ARCH_WANT_IPC_PARSE_VERSION | 32 | select ARCH_WANT_IPC_PARSE_VERSION |
33 | select GENERIC_PCI_IOMAP | 33 | select GENERIC_PCI_IOMAP |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 869023abe5a4..cfbe53c17b0d 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
15 | #include <linux/vmalloc.h> | 15 | #include <linux/vmalloc.h> |
16 | #include <linux/kdebug.h> | 16 | #include <linux/kdebug.h> |
17 | #include <linux/export.h> | ||
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/log2.h> | 20 | #include <linux/log2.h> |
@@ -62,6 +63,7 @@ extern unsigned long last_valid_pfn; | |||
62 | static pgd_t *srmmu_swapper_pg_dir; | 63 | static pgd_t *srmmu_swapper_pg_dir; |
63 | 64 | ||
64 | const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops; | 65 | const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops; |
66 | EXPORT_SYMBOL(sparc32_cachetlb_ops); | ||
65 | 67 | ||
66 | #ifdef CONFIG_SMP | 68 | #ifdef CONFIG_SMP |
67 | const struct sparc32_cachetlb_ops *local_ops; | 69 | const struct sparc32_cachetlb_ops *local_ops; |
diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index 90a21f430117..4dbf967da50d 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c | |||
@@ -111,7 +111,7 @@ struct mem_vector { | |||
111 | }; | 111 | }; |
112 | 112 | ||
113 | #define MEM_AVOID_MAX 5 | 113 | #define MEM_AVOID_MAX 5 |
114 | struct mem_vector mem_avoid[MEM_AVOID_MAX]; | 114 | static struct mem_vector mem_avoid[MEM_AVOID_MAX]; |
115 | 115 | ||
116 | static bool mem_contains(struct mem_vector *region, struct mem_vector *item) | 116 | static bool mem_contains(struct mem_vector *region, struct mem_vector *item) |
117 | { | 117 | { |
@@ -180,7 +180,7 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, | |||
180 | } | 180 | } |
181 | 181 | ||
182 | /* Does this memory vector overlap a known avoided area? */ | 182 | /* Does this memory vector overlap a known avoided area? */ |
183 | bool mem_avoid_overlap(struct mem_vector *img) | 183 | static bool mem_avoid_overlap(struct mem_vector *img) |
184 | { | 184 | { |
185 | int i; | 185 | int i; |
186 | 186 | ||
@@ -192,8 +192,9 @@ bool mem_avoid_overlap(struct mem_vector *img) | |||
192 | return false; | 192 | return false; |
193 | } | 193 | } |
194 | 194 | ||
195 | unsigned long slots[CONFIG_RANDOMIZE_BASE_MAX_OFFSET / CONFIG_PHYSICAL_ALIGN]; | 195 | static unsigned long slots[CONFIG_RANDOMIZE_BASE_MAX_OFFSET / |
196 | unsigned long slot_max = 0; | 196 | CONFIG_PHYSICAL_ALIGN]; |
197 | static unsigned long slot_max; | ||
197 | 198 | ||
198 | static void slots_append(unsigned long addr) | 199 | static void slots_append(unsigned long addr) |
199 | { | 200 | { |
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index 57ae63cd6ee2..94605c0e9cee 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h | |||
@@ -66,6 +66,6 @@ extern void tsc_save_sched_clock_state(void); | |||
66 | extern void tsc_restore_sched_clock_state(void); | 66 | extern void tsc_restore_sched_clock_state(void); |
67 | 67 | ||
68 | /* MSR based TSC calibration for Intel Atom SoC platforms */ | 68 | /* MSR based TSC calibration for Intel Atom SoC platforms */ |
69 | int try_msr_calibrate_tsc(unsigned long *fast_calibrate); | 69 | unsigned long try_msr_calibrate_tsc(void); |
70 | 70 | ||
71 | #endif /* _ASM_X86_TSC_H */ | 71 | #endif /* _ASM_X86_TSC_H */ |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b88645191fe5..79f9f848bee4 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1192,6 +1192,9 @@ static void x86_pmu_del(struct perf_event *event, int flags) | |||
1192 | for (i = 0; i < cpuc->n_events; i++) { | 1192 | for (i = 0; i < cpuc->n_events; i++) { |
1193 | if (event == cpuc->event_list[i]) { | 1193 | if (event == cpuc->event_list[i]) { |
1194 | 1194 | ||
1195 | if (i >= cpuc->n_events - cpuc->n_added) | ||
1196 | --cpuc->n_added; | ||
1197 | |||
1195 | if (x86_pmu.put_event_constraints) | 1198 | if (x86_pmu.put_event_constraints) |
1196 | x86_pmu.put_event_constraints(cpuc, event); | 1199 | x86_pmu.put_event_constraints(cpuc, event); |
1197 | 1200 | ||
@@ -1521,6 +1524,8 @@ static int __init init_hw_perf_events(void) | |||
1521 | 1524 | ||
1522 | pr_cont("%s PMU driver.\n", x86_pmu.name); | 1525 | pr_cont("%s PMU driver.\n", x86_pmu.name); |
1523 | 1526 | ||
1527 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | ||
1528 | |||
1524 | for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) | 1529 | for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) |
1525 | quirk->func(); | 1530 | quirk->func(); |
1526 | 1531 | ||
@@ -1534,7 +1539,6 @@ static int __init init_hw_perf_events(void) | |||
1534 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, | 1539 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, |
1535 | 0, x86_pmu.num_counters, 0, 0); | 1540 | 0, x86_pmu.num_counters, 0, 0); |
1536 | 1541 | ||
1537 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | ||
1538 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; | 1542 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; |
1539 | 1543 | ||
1540 | if (x86_pmu.event_attrs) | 1544 | if (x86_pmu.event_attrs) |
@@ -1820,9 +1824,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev, | |||
1820 | if (ret) | 1824 | if (ret) |
1821 | return ret; | 1825 | return ret; |
1822 | 1826 | ||
1827 | if (x86_pmu.attr_rdpmc_broken) | ||
1828 | return -ENOTSUPP; | ||
1829 | |||
1823 | if (!!val != !!x86_pmu.attr_rdpmc) { | 1830 | if (!!val != !!x86_pmu.attr_rdpmc) { |
1824 | x86_pmu.attr_rdpmc = !!val; | 1831 | x86_pmu.attr_rdpmc = !!val; |
1825 | smp_call_function(change_rdpmc, (void *)val, 1); | 1832 | on_each_cpu(change_rdpmc, (void *)val, 1); |
1826 | } | 1833 | } |
1827 | 1834 | ||
1828 | return count; | 1835 | return count; |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index c1a861829d81..4972c244d0bc 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -409,6 +409,7 @@ struct x86_pmu { | |||
409 | /* | 409 | /* |
410 | * sysfs attrs | 410 | * sysfs attrs |
411 | */ | 411 | */ |
412 | int attr_rdpmc_broken; | ||
412 | int attr_rdpmc; | 413 | int attr_rdpmc; |
413 | struct attribute **format_attrs; | 414 | struct attribute **format_attrs; |
414 | struct attribute **event_attrs; | 415 | struct attribute **event_attrs; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 0fa4f242f050..aa333d966886 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1361,10 +1361,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
1361 | intel_pmu_disable_all(); | 1361 | intel_pmu_disable_all(); |
1362 | handled = intel_pmu_drain_bts_buffer(); | 1362 | handled = intel_pmu_drain_bts_buffer(); |
1363 | status = intel_pmu_get_status(); | 1363 | status = intel_pmu_get_status(); |
1364 | if (!status) { | 1364 | if (!status) |
1365 | intel_pmu_enable_all(0); | 1365 | goto done; |
1366 | return handled; | ||
1367 | } | ||
1368 | 1366 | ||
1369 | loops = 0; | 1367 | loops = 0; |
1370 | again: | 1368 | again: |
@@ -2310,10 +2308,7 @@ __init int intel_pmu_init(void) | |||
2310 | if (version > 1) | 2308 | if (version > 1) |
2311 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); | 2309 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); |
2312 | 2310 | ||
2313 | /* | 2311 | if (boot_cpu_has(X86_FEATURE_PDCM)) { |
2314 | * v2 and above have a perf capabilities MSR | ||
2315 | */ | ||
2316 | if (version > 1) { | ||
2317 | u64 capabilities; | 2312 | u64 capabilities; |
2318 | 2313 | ||
2319 | rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); | 2314 | rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 29c248799ced..c88f7f4b03ee 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -501,8 +501,11 @@ static struct extra_reg snbep_uncore_cbox_extra_regs[] = { | |||
501 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, | 501 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, |
502 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), | 502 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), |
503 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | 503 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), |
504 | SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6), | ||
504 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | 505 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), |
506 | SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6), | ||
505 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | 507 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), |
508 | SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6), | ||
506 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), | 509 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), |
507 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), | 510 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), |
508 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), | 511 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), |
@@ -1178,10 +1181,15 @@ static struct extra_reg ivt_uncore_cbox_extra_regs[] = { | |||
1178 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, | 1181 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, |
1179 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), | 1182 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), |
1180 | SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), | 1183 | SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), |
1184 | SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4), | ||
1185 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), | ||
1186 | SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc), | ||
1181 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | 1187 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), |
1188 | SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc), | ||
1182 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | 1189 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), |
1190 | SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc), | ||
1183 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | 1191 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), |
1184 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), | 1192 | SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc), |
1185 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), | 1193 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), |
1186 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), | 1194 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), |
1187 | SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), | 1195 | SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), |
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index b1e2fe115323..7c1a0c07b607 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -231,31 +231,49 @@ static __initconst const struct x86_pmu p6_pmu = { | |||
231 | 231 | ||
232 | }; | 232 | }; |
233 | 233 | ||
234 | static __init void p6_pmu_rdpmc_quirk(void) | ||
235 | { | ||
236 | if (boot_cpu_data.x86_mask < 9) { | ||
237 | /* | ||
238 | * PPro erratum 26; fixed in stepping 9 and above. | ||
239 | */ | ||
240 | pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n"); | ||
241 | x86_pmu.attr_rdpmc_broken = 1; | ||
242 | x86_pmu.attr_rdpmc = 0; | ||
243 | } | ||
244 | } | ||
245 | |||
234 | __init int p6_pmu_init(void) | 246 | __init int p6_pmu_init(void) |
235 | { | 247 | { |
248 | x86_pmu = p6_pmu; | ||
249 | |||
236 | switch (boot_cpu_data.x86_model) { | 250 | switch (boot_cpu_data.x86_model) { |
237 | case 1: | 251 | case 1: /* Pentium Pro */ |
238 | case 3: /* Pentium Pro */ | 252 | x86_add_quirk(p6_pmu_rdpmc_quirk); |
239 | case 5: | 253 | break; |
240 | case 6: /* Pentium II */ | 254 | |
241 | case 7: | 255 | case 3: /* Pentium II - Klamath */ |
242 | case 8: | 256 | case 5: /* Pentium II - Deschutes */ |
243 | case 11: /* Pentium III */ | 257 | case 6: /* Pentium II - Mendocino */ |
244 | case 9: | ||
245 | case 13: | ||
246 | /* Pentium M */ | ||
247 | break; | 258 | break; |
259 | |||
260 | case 7: /* Pentium III - Katmai */ | ||
261 | case 8: /* Pentium III - Coppermine */ | ||
262 | case 10: /* Pentium III Xeon */ | ||
263 | case 11: /* Pentium III - Tualatin */ | ||
264 | break; | ||
265 | |||
266 | case 9: /* Pentium M - Banias */ | ||
267 | case 13: /* Pentium M - Dothan */ | ||
268 | break; | ||
269 | |||
248 | default: | 270 | default: |
249 | pr_cont("unsupported p6 CPU model %d ", | 271 | pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model); |
250 | boot_cpu_data.x86_model); | ||
251 | return -ENODEV; | 272 | return -ENODEV; |
252 | } | 273 | } |
253 | 274 | ||
254 | x86_pmu = p6_pmu; | ||
255 | |||
256 | memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, | 275 | memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, |
257 | sizeof(hw_cache_event_ids)); | 276 | sizeof(hw_cache_event_ids)); |
258 | 277 | ||
259 | |||
260 | return 0; | 278 | return 0; |
261 | } | 279 | } |
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 4eabc160696f..679cef0791cd 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c | |||
@@ -279,5 +279,7 @@ void arch_crash_save_vmcoreinfo(void) | |||
279 | VMCOREINFO_SYMBOL(node_data); | 279 | VMCOREINFO_SYMBOL(node_data); |
280 | VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); | 280 | VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); |
281 | #endif | 281 | #endif |
282 | vmcoreinfo_append_str("KERNELOFFSET=%lx\n", | ||
283 | (unsigned long)&_text - __START_KERNEL); | ||
282 | } | 284 | } |
283 | 285 | ||
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 872079a67e4d..f7d0672481fd 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -100,8 +100,10 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, | |||
100 | flag |= __GFP_ZERO; | 100 | flag |= __GFP_ZERO; |
101 | again: | 101 | again: |
102 | page = NULL; | 102 | page = NULL; |
103 | if (!(flag & GFP_ATOMIC)) | 103 | /* CMA can be used only in the context which permits sleeping */ |
104 | if (flag & __GFP_WAIT) | ||
104 | page = dma_alloc_from_contiguous(dev, count, get_order(size)); | 105 | page = dma_alloc_from_contiguous(dev, count, get_order(size)); |
106 | /* fallback */ | ||
105 | if (!page) | 107 | if (!page) |
106 | page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); | 108 | page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); |
107 | if (!page) | 109 | if (!page) |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index acb3b606613e..cfbe99f88830 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -653,13 +653,10 @@ unsigned long native_calibrate_tsc(void) | |||
653 | 653 | ||
654 | /* Calibrate TSC using MSR for Intel Atom SoCs */ | 654 | /* Calibrate TSC using MSR for Intel Atom SoCs */ |
655 | local_irq_save(flags); | 655 | local_irq_save(flags); |
656 | i = try_msr_calibrate_tsc(&fast_calibrate); | 656 | fast_calibrate = try_msr_calibrate_tsc(); |
657 | local_irq_restore(flags); | 657 | local_irq_restore(flags); |
658 | if (i >= 0) { | 658 | if (fast_calibrate) |
659 | if (i == 0) | ||
660 | pr_warn("Fast TSC calibration using MSR failed\n"); | ||
661 | return fast_calibrate; | 659 | return fast_calibrate; |
662 | } | ||
663 | 660 | ||
664 | local_irq_save(flags); | 661 | local_irq_save(flags); |
665 | fast_calibrate = quick_pit_calibrate(); | 662 | fast_calibrate = quick_pit_calibrate(); |
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c index 8b5434f4389f..92ae6acac8a7 100644 --- a/arch/x86/kernel/tsc_msr.c +++ b/arch/x86/kernel/tsc_msr.c | |||
@@ -53,7 +53,7 @@ static struct freq_desc freq_desc_tables[] = { | |||
53 | /* TNG */ | 53 | /* TNG */ |
54 | { 6, 0x4a, 1, { 0, FREQ_100, FREQ_133, 0, 0, 0, 0, 0 } }, | 54 | { 6, 0x4a, 1, { 0, FREQ_100, FREQ_133, 0, 0, 0, 0, 0 } }, |
55 | /* VLV2 */ | 55 | /* VLV2 */ |
56 | { 6, 0x37, 1, { 0, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } }, | 56 | { 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } }, |
57 | /* ANN */ | 57 | /* ANN */ |
58 | { 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } }, | 58 | { 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } }, |
59 | }; | 59 | }; |
@@ -77,21 +77,18 @@ static int match_cpu(u8 family, u8 model) | |||
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Do MSR calibration only for known/supported CPUs. | 79 | * Do MSR calibration only for known/supported CPUs. |
80 | * Return values: | 80 | * |
81 | * -1: CPU is unknown/unsupported for MSR based calibration | 81 | * Returns the calibration value or 0 if MSR calibration failed. |
82 | * 0: CPU is known/supported, but calibration failed | ||
83 | * 1: CPU is known/supported, and calibration succeeded | ||
84 | */ | 82 | */ |
85 | int try_msr_calibrate_tsc(unsigned long *fast_calibrate) | 83 | unsigned long try_msr_calibrate_tsc(void) |
86 | { | 84 | { |
87 | int cpu_index; | ||
88 | u32 lo, hi, ratio, freq_id, freq; | 85 | u32 lo, hi, ratio, freq_id, freq; |
86 | unsigned long res; | ||
87 | int cpu_index; | ||
89 | 88 | ||
90 | cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model); | 89 | cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model); |
91 | if (cpu_index < 0) | 90 | if (cpu_index < 0) |
92 | return -1; | 91 | return 0; |
93 | |||
94 | *fast_calibrate = 0; | ||
95 | 92 | ||
96 | if (freq_desc_tables[cpu_index].msr_plat) { | 93 | if (freq_desc_tables[cpu_index].msr_plat) { |
97 | rdmsr(MSR_PLATFORM_INFO, lo, hi); | 94 | rdmsr(MSR_PLATFORM_INFO, lo, hi); |
@@ -103,7 +100,7 @@ int try_msr_calibrate_tsc(unsigned long *fast_calibrate) | |||
103 | pr_info("Maximum core-clock to bus-clock ratio: 0x%x\n", ratio); | 100 | pr_info("Maximum core-clock to bus-clock ratio: 0x%x\n", ratio); |
104 | 101 | ||
105 | if (!ratio) | 102 | if (!ratio) |
106 | return 0; | 103 | goto fail; |
107 | 104 | ||
108 | /* Get FSB FREQ ID */ | 105 | /* Get FSB FREQ ID */ |
109 | rdmsr(MSR_FSB_FREQ, lo, hi); | 106 | rdmsr(MSR_FSB_FREQ, lo, hi); |
@@ -112,16 +109,19 @@ int try_msr_calibrate_tsc(unsigned long *fast_calibrate) | |||
112 | pr_info("Resolved frequency ID: %u, frequency: %u KHz\n", | 109 | pr_info("Resolved frequency ID: %u, frequency: %u KHz\n", |
113 | freq_id, freq); | 110 | freq_id, freq); |
114 | if (!freq) | 111 | if (!freq) |
115 | return 0; | 112 | goto fail; |
116 | 113 | ||
117 | /* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ | 114 | /* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ |
118 | *fast_calibrate = freq * ratio; | 115 | res = freq * ratio; |
119 | pr_info("TSC runs at %lu KHz\n", *fast_calibrate); | 116 | pr_info("TSC runs at %lu KHz\n", res); |
120 | 117 | ||
121 | #ifdef CONFIG_X86_LOCAL_APIC | 118 | #ifdef CONFIG_X86_LOCAL_APIC |
122 | lapic_timer_frequency = (freq * 1000) / HZ; | 119 | lapic_timer_frequency = (freq * 1000) / HZ; |
123 | pr_info("lapic_timer_frequency = %d\n", lapic_timer_frequency); | 120 | pr_info("lapic_timer_frequency = %d\n", lapic_timer_frequency); |
124 | #endif | 121 | #endif |
122 | return res; | ||
125 | 123 | ||
126 | return 1; | 124 | fail: |
125 | pr_warn("Fast TSC calibration using MSR failed\n"); | ||
126 | return 0; | ||
127 | } | 127 | } |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index e50425d0f5f7..9b531351a587 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -2672,6 +2672,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
2672 | break; | 2672 | break; |
2673 | } | 2673 | } |
2674 | 2674 | ||
2675 | drop_large_spte(vcpu, iterator.sptep); | ||
2675 | if (!is_shadow_present_pte(*iterator.sptep)) { | 2676 | if (!is_shadow_present_pte(*iterator.sptep)) { |
2676 | u64 base_addr = iterator.addr; | 2677 | u64 base_addr = iterator.addr; |
2677 | 2678 | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a06f101ef64b..392752834751 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -6688,7 +6688,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
6688 | else if (is_page_fault(intr_info)) | 6688 | else if (is_page_fault(intr_info)) |
6689 | return enable_ept; | 6689 | return enable_ept; |
6690 | else if (is_no_device(intr_info) && | 6690 | else if (is_no_device(intr_info) && |
6691 | !(nested_read_cr0(vmcs12) & X86_CR0_TS)) | 6691 | !(vmcs12->guest_cr0 & X86_CR0_TS)) |
6692 | return 0; | 6692 | return 0; |
6693 | return vmcs12->exception_bitmap & | 6693 | return vmcs12->exception_bitmap & |
6694 | (1u << (intr_info & INTR_INFO_VECTOR_MASK)); | 6694 | (1u << (intr_info & INTR_INFO_VECTOR_MASK)); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 39c28f09dfd5..2b8578432d5b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -6186,7 +6186,7 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) | |||
6186 | frag->len -= len; | 6186 | frag->len -= len; |
6187 | } | 6187 | } |
6188 | 6188 | ||
6189 | if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { | 6189 | if (vcpu->mmio_cur_fragment >= vcpu->mmio_nr_fragments) { |
6190 | vcpu->mmio_needed = 0; | 6190 | vcpu->mmio_needed = 0; |
6191 | 6191 | ||
6192 | /* FIXME: return into emulator if single-stepping. */ | 6192 | /* FIXME: return into emulator if single-stepping. */ |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index ba56e11cbf77..c87ae7c6e5f9 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -20,6 +20,7 @@ config XTENSA | |||
20 | select HAVE_FUNCTION_TRACER | 20 | select HAVE_FUNCTION_TRACER |
21 | select HAVE_IRQ_TIME_ACCOUNTING | 21 | select HAVE_IRQ_TIME_ACCOUNTING |
22 | select HAVE_PERF_EVENTS | 22 | select HAVE_PERF_EVENTS |
23 | select COMMON_CLK | ||
23 | help | 24 | help |
24 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 25 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
25 | primarily for embedded systems. These processors are both | 26 | primarily for embedded systems. These processors are both |
@@ -80,7 +81,6 @@ choice | |||
80 | config XTENSA_VARIANT_FSF | 81 | config XTENSA_VARIANT_FSF |
81 | bool "fsf - default (not generic) configuration" | 82 | bool "fsf - default (not generic) configuration" |
82 | select MMU | 83 | select MMU |
83 | select HAVE_XTENSA_GPIO32 | ||
84 | 84 | ||
85 | config XTENSA_VARIANT_DC232B | 85 | config XTENSA_VARIANT_DC232B |
86 | bool "dc232b - Diamond 232L Standard Core Rev.B (LE)" | 86 | bool "dc232b - Diamond 232L Standard Core Rev.B (LE)" |
@@ -135,7 +135,6 @@ config HAVE_SMP | |||
135 | config SMP | 135 | config SMP |
136 | bool "Enable Symmetric multi-processing support" | 136 | bool "Enable Symmetric multi-processing support" |
137 | depends on HAVE_SMP | 137 | depends on HAVE_SMP |
138 | select USE_GENERIC_SMP_HELPERS | ||
139 | select GENERIC_SMP_IDLE_THREAD | 138 | select GENERIC_SMP_IDLE_THREAD |
140 | help | 139 | help |
141 | Enabled SMP Software; allows more than one CPU/CORE | 140 | Enabled SMP Software; allows more than one CPU/CORE |
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index 46b4f5eab421..e7370b11348e 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi | |||
@@ -35,6 +35,13 @@ | |||
35 | interrupt-controller; | 35 | interrupt-controller; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | clocks { | ||
39 | osc: main-oscillator { | ||
40 | #clock-cells = <0>; | ||
41 | compatible = "fixed-clock"; | ||
42 | }; | ||
43 | }; | ||
44 | |||
38 | serial0: serial@fd050020 { | 45 | serial0: serial@fd050020 { |
39 | device_type = "serial"; | 46 | device_type = "serial"; |
40 | compatible = "ns16550a"; | 47 | compatible = "ns16550a"; |
@@ -42,9 +49,7 @@ | |||
42 | reg = <0xfd050020 0x20>; | 49 | reg = <0xfd050020 0x20>; |
43 | reg-shift = <2>; | 50 | reg-shift = <2>; |
44 | interrupts = <0 1>; /* external irq 0 */ | 51 | interrupts = <0 1>; /* external irq 0 */ |
45 | /* Filled in by platform_setup from FPGA register | 52 | clocks = <&osc>; |
46 | * clock-frequency = <100000000>; | ||
47 | */ | ||
48 | }; | 53 | }; |
49 | 54 | ||
50 | enet0: ethoc@fd030000 { | 55 | enet0: ethoc@fd030000 { |
@@ -52,5 +57,6 @@ | |||
52 | reg = <0xfd030000 0x4000 0xfd800000 0x4000>; | 57 | reg = <0xfd030000 0x4000 0xfd800000 0x4000>; |
53 | interrupts = <1 1>; /* external irq 1 */ | 58 | interrupts = <1 1>; /* external irq 1 */ |
54 | local-mac-address = [00 50 c2 13 6f 00]; | 59 | local-mac-address = [00 50 c2 13 6f 00]; |
60 | clocks = <&osc>; | ||
55 | }; | 61 | }; |
56 | }; | 62 | }; |
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index 2a042d430c25..74944207167e 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #ifdef CONFIG_MMU | 26 | #ifdef CONFIG_MMU |
27 | 27 | ||
28 | #if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF | 28 | #if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) |
29 | extern unsigned long xtensa_kio_paddr; | 29 | extern unsigned long xtensa_kio_paddr; |
30 | 30 | ||
31 | static inline unsigned long xtensa_get_kio_paddr(void) | 31 | static inline unsigned long xtensa_get_kio_paddr(void) |
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h index 8c194f6af45e..677bfcf4ee5d 100644 --- a/arch/xtensa/include/asm/traps.h +++ b/arch/xtensa/include/asm/traps.h | |||
@@ -23,25 +23,37 @@ void secondary_trap_init(void); | |||
23 | 23 | ||
24 | static inline void spill_registers(void) | 24 | static inline void spill_registers(void) |
25 | { | 25 | { |
26 | 26 | #if XCHAL_NUM_AREGS > 16 | |
27 | __asm__ __volatile__ ( | 27 | __asm__ __volatile__ ( |
28 | "movi a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t" | 28 | " call12 1f\n" |
29 | "mov a12, a0\n\t" | 29 | " _j 2f\n" |
30 | "rsr a13, sar\n\t" | 30 | " retw\n" |
31 | "xsr a14, ps\n\t" | 31 | " .align 4\n" |
32 | "movi a0, _spill_registers\n\t" | 32 | "1:\n" |
33 | "rsync\n\t" | 33 | " _entry a1, 48\n" |
34 | "callx0 a0\n\t" | 34 | " addi a12, a0, 3\n" |
35 | "mov a0, a12\n\t" | 35 | #if XCHAL_NUM_AREGS > 32 |
36 | "wsr a13, sar\n\t" | 36 | " .rept (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n" |
37 | "wsr a14, ps\n\t" | 37 | " _entry a1, 48\n" |
38 | : : | 38 | " mov a12, a0\n" |
39 | #if defined(CONFIG_FRAME_POINTER) | 39 | " .endr\n" |
40 | : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15", | 40 | #endif |
41 | " _entry a1, 48\n" | ||
42 | #if XCHAL_NUM_AREGS % 12 == 0 | ||
43 | " mov a8, a8\n" | ||
44 | #elif XCHAL_NUM_AREGS % 12 == 4 | ||
45 | " mov a12, a12\n" | ||
46 | #elif XCHAL_NUM_AREGS % 12 == 8 | ||
47 | " mov a4, a4\n" | ||
48 | #endif | ||
49 | " retw\n" | ||
50 | "2:\n" | ||
51 | : : : "a12", "a13", "memory"); | ||
41 | #else | 52 | #else |
42 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", | 53 | __asm__ __volatile__ ( |
54 | " mov a12, a12\n" | ||
55 | : : : "memory"); | ||
43 | #endif | 56 | #endif |
44 | "memory"); | ||
45 | } | 57 | } |
46 | 58 | ||
47 | #endif /* _XTENSA_TRAPS_H */ | 59 | #endif /* _XTENSA_TRAPS_H */ |
diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h index 5791b45d5a5d..f74ddfbb92ef 100644 --- a/arch/xtensa/include/asm/vectors.h +++ b/arch/xtensa/include/asm/vectors.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #define XCHAL_KIO_DEFAULT_PADDR 0xf0000000 | 25 | #define XCHAL_KIO_DEFAULT_PADDR 0xf0000000 |
26 | #define XCHAL_KIO_SIZE 0x10000000 | 26 | #define XCHAL_KIO_SIZE 0x10000000 |
27 | 27 | ||
28 | #if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF | 28 | #if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) |
29 | #define XCHAL_KIO_PADDR xtensa_get_kio_paddr() | 29 | #define XCHAL_KIO_PADDR xtensa_get_kio_paddr() |
30 | #else | 30 | #else |
31 | #define XCHAL_KIO_PADDR XCHAL_KIO_DEFAULT_PADDR | 31 | #define XCHAL_KIO_PADDR XCHAL_KIO_DEFAULT_PADDR |
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 51940fec6990..b9395529f02d 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h | |||
@@ -734,7 +734,12 @@ __SYSCALL(332, sys_finit_module, 3) | |||
734 | #define __NR_accept4 333 | 734 | #define __NR_accept4 333 |
735 | __SYSCALL(333, sys_accept4, 4) | 735 | __SYSCALL(333, sys_accept4, 4) |
736 | 736 | ||
737 | #define __NR_syscall_count 334 | 737 | #define __NR_sched_setattr 334 |
738 | __SYSCALL(334, sys_sched_setattr, 2) | ||
739 | #define __NR_sched_getattr 335 | ||
740 | __SYSCALL(335, sys_sched_getattr, 3) | ||
741 | |||
742 | #define __NR_syscall_count 336 | ||
738 | 743 | ||
739 | /* | 744 | /* |
740 | * sysxtensa syscall handler | 745 | * sysxtensa syscall handler |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 21dbe6bdb8ed..ef7f4990722b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -1081,196 +1081,53 @@ ENTRY(fast_syscall_spill_registers) | |||
1081 | 1081 | ||
1082 | rsr a0, sar | 1082 | rsr a0, sar |
1083 | s32i a3, a2, PT_AREG3 | 1083 | s32i a3, a2, PT_AREG3 |
1084 | s32i a4, a2, PT_AREG4 | 1084 | s32i a0, a2, PT_SAR |
1085 | s32i a0, a2, PT_AREG5 # store SAR to PT_AREG5 | ||
1086 | 1085 | ||
1087 | /* The spill routine might clobber a7, a11, and a15. */ | 1086 | /* The spill routine might clobber a4, a7, a8, a11, a12, and a15. */ |
1088 | 1087 | ||
1088 | s32i a4, a2, PT_AREG4 | ||
1089 | s32i a7, a2, PT_AREG7 | 1089 | s32i a7, a2, PT_AREG7 |
1090 | s32i a8, a2, PT_AREG8 | ||
1090 | s32i a11, a2, PT_AREG11 | 1091 | s32i a11, a2, PT_AREG11 |
1092 | s32i a12, a2, PT_AREG12 | ||
1091 | s32i a15, a2, PT_AREG15 | 1093 | s32i a15, a2, PT_AREG15 |
1092 | 1094 | ||
1093 | call0 _spill_registers # destroys a3, a4, and SAR | ||
1094 | |||
1095 | /* Advance PC, restore registers and SAR, and return from exception. */ | ||
1096 | |||
1097 | l32i a3, a2, PT_AREG5 | ||
1098 | l32i a4, a2, PT_AREG4 | ||
1099 | l32i a0, a2, PT_AREG0 | ||
1100 | wsr a3, sar | ||
1101 | l32i a3, a2, PT_AREG3 | ||
1102 | |||
1103 | /* Restore clobbered registers. */ | ||
1104 | |||
1105 | l32i a7, a2, PT_AREG7 | ||
1106 | l32i a11, a2, PT_AREG11 | ||
1107 | l32i a15, a2, PT_AREG15 | ||
1108 | |||
1109 | movi a2, 0 | ||
1110 | rfe | ||
1111 | |||
1112 | ENDPROC(fast_syscall_spill_registers) | ||
1113 | |||
1114 | /* Fixup handler. | ||
1115 | * | ||
1116 | * We get here if the spill routine causes an exception, e.g. tlb miss. | ||
1117 | * We basically restore WINDOWBASE and WINDOWSTART to the condition when | ||
1118 | * we entered the spill routine and jump to the user exception handler. | ||
1119 | * | ||
1120 | * a0: value of depc, original value in depc | ||
1121 | * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE | ||
1122 | * a3: exctable, original value in excsave1 | ||
1123 | */ | ||
1124 | |||
1125 | ENTRY(fast_syscall_spill_registers_fixup) | ||
1126 | |||
1127 | rsr a2, windowbase # get current windowbase (a2 is saved) | ||
1128 | xsr a0, depc # restore depc and a0 | ||
1129 | ssl a2 # set shift (32 - WB) | ||
1130 | |||
1131 | /* We need to make sure the current registers (a0-a3) are preserved. | ||
1132 | * To do this, we simply set the bit for the current window frame | ||
1133 | * in WS, so that the exception handlers save them to the task stack. | ||
1134 | */ | ||
1135 | |||
1136 | xsr a3, excsave1 # get spill-mask | ||
1137 | slli a3, a3, 1 # shift left by one | ||
1138 | |||
1139 | slli a2, a3, 32-WSBITS | ||
1140 | src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... | ||
1141 | wsr a2, windowstart # set corrected windowstart | ||
1142 | |||
1143 | srli a3, a3, 1 | ||
1144 | rsr a2, excsave1 | ||
1145 | l32i a2, a2, EXC_TABLE_DOUBLE_SAVE # restore a2 | ||
1146 | xsr a2, excsave1 | ||
1147 | s32i a3, a2, EXC_TABLE_DOUBLE_SAVE # save a3 | ||
1148 | l32i a3, a2, EXC_TABLE_PARAM # original WB (in user task) | ||
1149 | xsr a2, excsave1 | ||
1150 | |||
1151 | /* Return to the original (user task) WINDOWBASE. | ||
1152 | * We leave the following frame behind: | ||
1153 | * a0, a1, a2 same | ||
1154 | * a3: trashed (saved in EXC_TABLE_DOUBLE_SAVE) | ||
1155 | * depc: depc (we have to return to that address) | ||
1156 | * excsave_1: exctable | ||
1157 | */ | ||
1158 | |||
1159 | wsr a3, windowbase | ||
1160 | rsync | ||
1161 | |||
1162 | /* We are now in the original frame when we entered _spill_registers: | ||
1163 | * a0: return address | ||
1164 | * a1: used, stack pointer | ||
1165 | * a2: kernel stack pointer | ||
1166 | * a3: available | ||
1167 | * depc: exception address | ||
1168 | * excsave: exctable | ||
1169 | * Note: This frame might be the same as above. | ||
1170 | */ | ||
1171 | |||
1172 | /* Setup stack pointer. */ | ||
1173 | |||
1174 | addi a2, a2, -PT_USER_SIZE | ||
1175 | s32i a0, a2, PT_AREG0 | ||
1176 | |||
1177 | /* Make sure we return to this fixup handler. */ | ||
1178 | |||
1179 | movi a3, fast_syscall_spill_registers_fixup_return | ||
1180 | s32i a3, a2, PT_DEPC # setup depc | ||
1181 | |||
1182 | /* Jump to the exception handler. */ | ||
1183 | |||
1184 | rsr a3, excsave1 | ||
1185 | rsr a0, exccause | ||
1186 | addx4 a0, a0, a3 # find entry in table | ||
1187 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | ||
1188 | l32i a3, a3, EXC_TABLE_DOUBLE_SAVE | ||
1189 | jx a0 | ||
1190 | |||
1191 | ENDPROC(fast_syscall_spill_registers_fixup) | ||
1192 | |||
1193 | ENTRY(fast_syscall_spill_registers_fixup_return) | ||
1194 | |||
1195 | /* When we return here, all registers have been restored (a2: DEPC) */ | ||
1196 | |||
1197 | wsr a2, depc # exception address | ||
1198 | |||
1199 | /* Restore fixup handler. */ | ||
1200 | |||
1201 | rsr a2, excsave1 | ||
1202 | s32i a3, a2, EXC_TABLE_DOUBLE_SAVE | ||
1203 | movi a3, fast_syscall_spill_registers_fixup | ||
1204 | s32i a3, a2, EXC_TABLE_FIXUP | ||
1205 | rsr a3, windowbase | ||
1206 | s32i a3, a2, EXC_TABLE_PARAM | ||
1207 | l32i a2, a2, EXC_TABLE_KSTK | ||
1208 | |||
1209 | /* Load WB at the time the exception occurred. */ | ||
1210 | |||
1211 | rsr a3, sar # WB is still in SAR | ||
1212 | neg a3, a3 | ||
1213 | wsr a3, windowbase | ||
1214 | rsync | ||
1215 | |||
1216 | rsr a3, excsave1 | ||
1217 | l32i a3, a3, EXC_TABLE_DOUBLE_SAVE | ||
1218 | |||
1219 | rfde | ||
1220 | |||
1221 | ENDPROC(fast_syscall_spill_registers_fixup_return) | ||
1222 | |||
1223 | /* | ||
1224 | * spill all registers. | ||
1225 | * | ||
1226 | * This is not a real function. The following conditions must be met: | ||
1227 | * | ||
1228 | * - must be called with call0. | ||
1229 | * - uses a3, a4 and SAR. | ||
1230 | * - the last 'valid' register of each frame are clobbered. | ||
1231 | * - the caller must have registered a fixup handler | ||
1232 | * (or be inside a critical section) | ||
1233 | * - PS_EXCM must be set (PS_WOE cleared?) | ||
1234 | */ | ||
1235 | |||
1236 | ENTRY(_spill_registers) | ||
1237 | |||
1238 | /* | 1095 | /* |
1239 | * Rotate ws so that the current windowbase is at bit 0. | 1096 | * Rotate ws so that the current windowbase is at bit 0. |
1240 | * Assume ws = xxxwww1yy (www1 current window frame). | 1097 | * Assume ws = xxxwww1yy (www1 current window frame). |
1241 | * Rotate ws right so that a4 = yyxxxwww1. | 1098 | * Rotate ws right so that a4 = yyxxxwww1. |
1242 | */ | 1099 | */ |
1243 | 1100 | ||
1244 | rsr a4, windowbase | 1101 | rsr a0, windowbase |
1245 | rsr a3, windowstart # a3 = xxxwww1yy | 1102 | rsr a3, windowstart # a3 = xxxwww1yy |
1246 | ssr a4 # holds WB | 1103 | ssr a0 # holds WB |
1247 | slli a4, a3, WSBITS | 1104 | slli a0, a3, WSBITS |
1248 | or a3, a3, a4 # a3 = xxxwww1yyxxxwww1yy | 1105 | or a3, a3, a0 # a3 = xxxwww1yyxxxwww1yy |
1249 | srl a3, a3 # a3 = 00xxxwww1yyxxxwww1 | 1106 | srl a3, a3 # a3 = 00xxxwww1yyxxxwww1 |
1250 | 1107 | ||
1251 | /* We are done if there are no more than the current register frame. */ | 1108 | /* We are done if there are no more than the current register frame. */ |
1252 | 1109 | ||
1253 | extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww | 1110 | extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww |
1254 | movi a4, (1 << (WSBITS-1)) | 1111 | movi a0, (1 << (WSBITS-1)) |
1255 | _beqz a3, .Lnospill # only one active frame? jump | 1112 | _beqz a3, .Lnospill # only one active frame? jump |
1256 | 1113 | ||
1257 | /* We want 1 at the top, so that we return to the current windowbase */ | 1114 | /* We want 1 at the top, so that we return to the current windowbase */ |
1258 | 1115 | ||
1259 | or a3, a3, a4 # 1yyxxxwww | 1116 | or a3, a3, a0 # 1yyxxxwww |
1260 | 1117 | ||
1261 | /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */ | 1118 | /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */ |
1262 | 1119 | ||
1263 | wsr a3, windowstart # save shifted windowstart | 1120 | wsr a3, windowstart # save shifted windowstart |
1264 | neg a4, a3 | 1121 | neg a0, a3 |
1265 | and a3, a4, a3 # first bit set from right: 000010000 | 1122 | and a3, a0, a3 # first bit set from right: 000010000 |
1266 | 1123 | ||
1267 | ffs_ws a4, a3 # a4: shifts to skip empty frames | 1124 | ffs_ws a0, a3 # a0: shifts to skip empty frames |
1268 | movi a3, WSBITS | 1125 | movi a3, WSBITS |
1269 | sub a4, a3, a4 # WSBITS-a4:number of 0-bits from right | 1126 | sub a0, a3, a0 # WSBITS-a0:number of 0-bits from right |
1270 | ssr a4 # save in SAR for later. | 1127 | ssr a0 # save in SAR for later. |
1271 | 1128 | ||
1272 | rsr a3, windowbase | 1129 | rsr a3, windowbase |
1273 | add a3, a3, a4 | 1130 | add a3, a3, a0 |
1274 | wsr a3, windowbase | 1131 | wsr a3, windowbase |
1275 | rsync | 1132 | rsync |
1276 | 1133 | ||
@@ -1285,22 +1142,6 @@ ENTRY(_spill_registers) | |||
1285 | * we have to save 4,8. or 12 registers. | 1142 | * we have to save 4,8. or 12 registers. |
1286 | */ | 1143 | */ |
1287 | 1144 | ||
1288 | _bbsi.l a3, 1, .Lc4 | ||
1289 | _bbsi.l a3, 2, .Lc8 | ||
1290 | |||
1291 | /* Special case: we have a call12-frame starting at a4. */ | ||
1292 | |||
1293 | _bbci.l a3, 3, .Lc12 # bit 3 shouldn't be zero! (Jump to Lc12 first) | ||
1294 | |||
1295 | s32e a4, a1, -16 # a1 is valid with an empty spill area | ||
1296 | l32e a4, a5, -12 | ||
1297 | s32e a8, a4, -48 | ||
1298 | mov a8, a4 | ||
1299 | l32e a4, a1, -16 | ||
1300 | j .Lc12c | ||
1301 | |||
1302 | .Lnospill: | ||
1303 | ret | ||
1304 | 1145 | ||
1305 | .Lloop: _bbsi.l a3, 1, .Lc4 | 1146 | .Lloop: _bbsi.l a3, 1, .Lc4 |
1306 | _bbci.l a3, 2, .Lc12 | 1147 | _bbci.l a3, 2, .Lc12 |
@@ -1314,20 +1155,10 @@ ENTRY(_spill_registers) | |||
1314 | s32e a9, a4, -28 | 1155 | s32e a9, a4, -28 |
1315 | s32e a10, a4, -24 | 1156 | s32e a10, a4, -24 |
1316 | s32e a11, a4, -20 | 1157 | s32e a11, a4, -20 |
1317 | |||
1318 | srli a11, a3, 2 # shift windowbase by 2 | 1158 | srli a11, a3, 2 # shift windowbase by 2 |
1319 | rotw 2 | 1159 | rotw 2 |
1320 | _bnei a3, 1, .Lloop | 1160 | _bnei a3, 1, .Lloop |
1321 | 1161 | j .Lexit | |
1322 | .Lexit: /* Done. Do the final rotation, set WS, and return. */ | ||
1323 | |||
1324 | rotw 1 | ||
1325 | rsr a3, windowbase | ||
1326 | ssl a3 | ||
1327 | movi a3, 1 | ||
1328 | sll a3, a3 | ||
1329 | wsr a3, windowstart | ||
1330 | ret | ||
1331 | 1162 | ||
1332 | .Lc4: s32e a4, a9, -16 | 1163 | .Lc4: s32e a4, a9, -16 |
1333 | s32e a5, a9, -12 | 1164 | s32e a5, a9, -12 |
@@ -1343,11 +1174,11 @@ ENTRY(_spill_registers) | |||
1343 | 1174 | ||
1344 | /* 12-register frame (call12) */ | 1175 | /* 12-register frame (call12) */ |
1345 | 1176 | ||
1346 | l32e a2, a5, -12 | 1177 | l32e a0, a5, -12 |
1347 | s32e a8, a2, -48 | 1178 | s32e a8, a0, -48 |
1348 | mov a8, a2 | 1179 | mov a8, a0 |
1349 | 1180 | ||
1350 | .Lc12c: s32e a9, a8, -44 | 1181 | s32e a9, a8, -44 |
1351 | s32e a10, a8, -40 | 1182 | s32e a10, a8, -40 |
1352 | s32e a11, a8, -36 | 1183 | s32e a11, a8, -36 |
1353 | s32e a12, a8, -32 | 1184 | s32e a12, a8, -32 |
@@ -1367,30 +1198,54 @@ ENTRY(_spill_registers) | |||
1367 | */ | 1198 | */ |
1368 | 1199 | ||
1369 | rotw 1 | 1200 | rotw 1 |
1370 | mov a5, a13 | 1201 | mov a4, a13 |
1371 | rotw -1 | 1202 | rotw -1 |
1372 | 1203 | ||
1373 | s32e a4, a9, -16 | 1204 | s32e a4, a8, -16 |
1374 | s32e a5, a9, -12 | 1205 | s32e a5, a8, -12 |
1375 | s32e a6, a9, -8 | 1206 | s32e a6, a8, -8 |
1376 | s32e a7, a9, -4 | 1207 | s32e a7, a8, -4 |
1377 | 1208 | ||
1378 | rotw 3 | 1209 | rotw 3 |
1379 | 1210 | ||
1380 | _beqi a3, 1, .Lexit | 1211 | _beqi a3, 1, .Lexit |
1381 | j .Lloop | 1212 | j .Lloop |
1382 | 1213 | ||
1383 | .Linvalid_mask: | 1214 | .Lexit: |
1384 | 1215 | ||
1385 | /* We get here because of an unrecoverable error in the window | 1216 | /* Done. Do the final rotation and set WS */ |
1386 | * registers. If we are in user space, we kill the application, | 1217 | |
1387 | * however, this condition is unrecoverable in kernel space. | 1218 | rotw 1 |
1388 | */ | 1219 | rsr a3, windowbase |
1220 | ssl a3 | ||
1221 | movi a3, 1 | ||
1222 | sll a3, a3 | ||
1223 | wsr a3, windowstart | ||
1224 | .Lnospill: | ||
1225 | |||
1226 | /* Advance PC, restore registers and SAR, and return from exception. */ | ||
1227 | |||
1228 | l32i a3, a2, PT_SAR | ||
1229 | l32i a0, a2, PT_AREG0 | ||
1230 | wsr a3, sar | ||
1231 | l32i a3, a2, PT_AREG3 | ||
1389 | 1232 | ||
1390 | rsr a0, ps | 1233 | /* Restore clobbered registers. */ |
1391 | _bbci.l a0, PS_UM_BIT, 1f | ||
1392 | 1234 | ||
1393 | /* User space: Setup a dummy frame and kill application. | 1235 | l32i a4, a2, PT_AREG4 |
1236 | l32i a7, a2, PT_AREG7 | ||
1237 | l32i a8, a2, PT_AREG8 | ||
1238 | l32i a11, a2, PT_AREG11 | ||
1239 | l32i a12, a2, PT_AREG12 | ||
1240 | l32i a15, a2, PT_AREG15 | ||
1241 | |||
1242 | movi a2, 0 | ||
1243 | rfe | ||
1244 | |||
1245 | .Linvalid_mask: | ||
1246 | |||
1247 | /* We get here because of an unrecoverable error in the window | ||
1248 | * registers, so set up a dummy frame and kill the user application. | ||
1394 | * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. | 1249 | * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. |
1395 | */ | 1250 | */ |
1396 | 1251 | ||
@@ -1414,14 +1269,136 @@ ENTRY(_spill_registers) | |||
1414 | movi a4, do_exit | 1269 | movi a4, do_exit |
1415 | callx4 a4 | 1270 | callx4 a4 |
1416 | 1271 | ||
1417 | 1: /* Kernel space: PANIC! */ | 1272 | /* shouldn't return, so panic */ |
1418 | 1273 | ||
1419 | wsr a0, excsave1 | 1274 | wsr a0, excsave1 |
1420 | movi a0, unrecoverable_exception | 1275 | movi a0, unrecoverable_exception |
1421 | callx0 a0 # should not return | 1276 | callx0 a0 # should not return |
1422 | 1: j 1b | 1277 | 1: j 1b |
1423 | 1278 | ||
1424 | ENDPROC(_spill_registers) | 1279 | |
1280 | ENDPROC(fast_syscall_spill_registers) | ||
1281 | |||
1282 | /* Fixup handler. | ||
1283 | * | ||
1284 | * We get here if the spill routine causes an exception, e.g. tlb miss. | ||
1285 | * We basically restore WINDOWBASE and WINDOWSTART to the condition when | ||
1286 | * we entered the spill routine and jump to the user exception handler. | ||
1287 | * | ||
1288 | * Note that we only need to restore the bits in windowstart that have not | ||
1289 | * been spilled yet by the _spill_register routine. Luckily, a3 contains a | ||
1290 | * rotated windowstart with only those bits set for frames that haven't been | ||
1291 | * spilled yet. Because a3 is rotated such that bit 0 represents the register | ||
1292 | * frame for the current windowbase - 1, we need to rotate a3 left by the | ||
1293 | * value of the current windowbase + 1 and move it to windowstart. | ||
1294 | * | ||
1295 | * a0: value of depc, original value in depc | ||
1296 | * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE | ||
1297 | * a3: exctable, original value in excsave1 | ||
1298 | */ | ||
1299 | |||
1300 | ENTRY(fast_syscall_spill_registers_fixup) | ||
1301 | |||
1302 | rsr a2, windowbase # get current windowbase (a2 is saved) | ||
1303 | xsr a0, depc # restore depc and a0 | ||
1304 | ssl a2 # set shift (32 - WB) | ||
1305 | |||
1306 | /* We need to make sure the current registers (a0-a3) are preserved. | ||
1307 | * To do this, we simply set the bit for the current window frame | ||
1308 | * in WS, so that the exception handlers save them to the task stack. | ||
1309 | * | ||
1310 | * Note: we use a3 to set the windowbase, so we take a special care | ||
1311 | * of it, saving it in the original _spill_registers frame across | ||
1312 | * the exception handler call. | ||
1313 | */ | ||
1314 | |||
1315 | xsr a3, excsave1 # get spill-mask | ||
1316 | slli a3, a3, 1 # shift left by one | ||
1317 | addi a3, a3, 1 # set the bit for the current window frame | ||
1318 | |||
1319 | slli a2, a3, 32-WSBITS | ||
1320 | src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... | ||
1321 | wsr a2, windowstart # set corrected windowstart | ||
1322 | |||
1323 | srli a3, a3, 1 | ||
1324 | rsr a2, excsave1 | ||
1325 | l32i a2, a2, EXC_TABLE_DOUBLE_SAVE # restore a2 | ||
1326 | xsr a2, excsave1 | ||
1327 | s32i a3, a2, EXC_TABLE_DOUBLE_SAVE # save a3 | ||
1328 | l32i a3, a2, EXC_TABLE_PARAM # original WB (in user task) | ||
1329 | xsr a2, excsave1 | ||
1330 | |||
1331 | /* Return to the original (user task) WINDOWBASE. | ||
1332 | * We leave the following frame behind: | ||
1333 | * a0, a1, a2 same | ||
1334 | * a3: trashed (saved in EXC_TABLE_DOUBLE_SAVE) | ||
1335 | * depc: depc (we have to return to that address) | ||
1336 | * excsave_1: exctable | ||
1337 | */ | ||
1338 | |||
1339 | wsr a3, windowbase | ||
1340 | rsync | ||
1341 | |||
1342 | /* We are now in the original frame when we entered _spill_registers: | ||
1343 | * a0: return address | ||
1344 | * a1: used, stack pointer | ||
1345 | * a2: kernel stack pointer | ||
1346 | * a3: available | ||
1347 | * depc: exception address | ||
1348 | * excsave: exctable | ||
1349 | * Note: This frame might be the same as above. | ||
1350 | */ | ||
1351 | |||
1352 | /* Setup stack pointer. */ | ||
1353 | |||
1354 | addi a2, a2, -PT_USER_SIZE | ||
1355 | s32i a0, a2, PT_AREG0 | ||
1356 | |||
1357 | /* Make sure we return to this fixup handler. */ | ||
1358 | |||
1359 | movi a3, fast_syscall_spill_registers_fixup_return | ||
1360 | s32i a3, a2, PT_DEPC # setup depc | ||
1361 | |||
1362 | /* Jump to the exception handler. */ | ||
1363 | |||
1364 | rsr a3, excsave1 | ||
1365 | rsr a0, exccause | ||
1366 | addx4 a0, a0, a3 # find entry in table | ||
1367 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | ||
1368 | l32i a3, a3, EXC_TABLE_DOUBLE_SAVE | ||
1369 | jx a0 | ||
1370 | |||
1371 | ENDPROC(fast_syscall_spill_registers_fixup) | ||
1372 | |||
1373 | ENTRY(fast_syscall_spill_registers_fixup_return) | ||
1374 | |||
1375 | /* When we return here, all registers have been restored (a2: DEPC) */ | ||
1376 | |||
1377 | wsr a2, depc # exception address | ||
1378 | |||
1379 | /* Restore fixup handler. */ | ||
1380 | |||
1381 | rsr a2, excsave1 | ||
1382 | s32i a3, a2, EXC_TABLE_DOUBLE_SAVE | ||
1383 | movi a3, fast_syscall_spill_registers_fixup | ||
1384 | s32i a3, a2, EXC_TABLE_FIXUP | ||
1385 | rsr a3, windowbase | ||
1386 | s32i a3, a2, EXC_TABLE_PARAM | ||
1387 | l32i a2, a2, EXC_TABLE_KSTK | ||
1388 | |||
1389 | /* Load WB at the time the exception occurred. */ | ||
1390 | |||
1391 | rsr a3, sar # WB is still in SAR | ||
1392 | neg a3, a3 | ||
1393 | wsr a3, windowbase | ||
1394 | rsync | ||
1395 | |||
1396 | rsr a3, excsave1 | ||
1397 | l32i a3, a3, EXC_TABLE_DOUBLE_SAVE | ||
1398 | |||
1399 | rfde | ||
1400 | |||
1401 | ENDPROC(fast_syscall_spill_registers_fixup_return) | ||
1425 | 1402 | ||
1426 | #ifdef CONFIG_MMU | 1403 | #ifdef CONFIG_MMU |
1427 | /* | 1404 | /* |
@@ -1794,6 +1771,43 @@ ENTRY(system_call) | |||
1794 | 1771 | ||
1795 | ENDPROC(system_call) | 1772 | ENDPROC(system_call) |
1796 | 1773 | ||
1774 | /* | ||
1775 | * Spill live registers on the kernel stack macro. | ||
1776 | * | ||
1777 | * Entry condition: ps.woe is set, ps.excm is cleared | ||
1778 | * Exit condition: windowstart has single bit set | ||
1779 | * May clobber: a12, a13 | ||
1780 | */ | ||
1781 | .macro spill_registers_kernel | ||
1782 | |||
1783 | #if XCHAL_NUM_AREGS > 16 | ||
1784 | call12 1f | ||
1785 | _j 2f | ||
1786 | retw | ||
1787 | .align 4 | ||
1788 | 1: | ||
1789 | _entry a1, 48 | ||
1790 | addi a12, a0, 3 | ||
1791 | #if XCHAL_NUM_AREGS > 32 | ||
1792 | .rept (XCHAL_NUM_AREGS - 32) / 12 | ||
1793 | _entry a1, 48 | ||
1794 | mov a12, a0 | ||
1795 | .endr | ||
1796 | #endif | ||
1797 | _entry a1, 48 | ||
1798 | #if XCHAL_NUM_AREGS % 12 == 0 | ||
1799 | mov a8, a8 | ||
1800 | #elif XCHAL_NUM_AREGS % 12 == 4 | ||
1801 | mov a12, a12 | ||
1802 | #elif XCHAL_NUM_AREGS % 12 == 8 | ||
1803 | mov a4, a4 | ||
1804 | #endif | ||
1805 | retw | ||
1806 | 2: | ||
1807 | #else | ||
1808 | mov a12, a12 | ||
1809 | #endif | ||
1810 | .endm | ||
1797 | 1811 | ||
1798 | /* | 1812 | /* |
1799 | * Task switch. | 1813 | * Task switch. |
@@ -1806,21 +1820,20 @@ ENTRY(_switch_to) | |||
1806 | 1820 | ||
1807 | entry a1, 16 | 1821 | entry a1, 16 |
1808 | 1822 | ||
1809 | mov a12, a2 # preserve 'prev' (a2) | 1823 | mov a10, a2 # preserve 'prev' (a2) |
1810 | mov a13, a3 # and 'next' (a3) | 1824 | mov a11, a3 # and 'next' (a3) |
1811 | 1825 | ||
1812 | l32i a4, a2, TASK_THREAD_INFO | 1826 | l32i a4, a2, TASK_THREAD_INFO |
1813 | l32i a5, a3, TASK_THREAD_INFO | 1827 | l32i a5, a3, TASK_THREAD_INFO |
1814 | 1828 | ||
1815 | save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER | 1829 | save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER |
1816 | 1830 | ||
1817 | s32i a0, a12, THREAD_RA # save return address | 1831 | s32i a0, a10, THREAD_RA # save return address |
1818 | s32i a1, a12, THREAD_SP # save stack pointer | 1832 | s32i a1, a10, THREAD_SP # save stack pointer |
1819 | 1833 | ||
1820 | /* Disable ints while we manipulate the stack pointer. */ | 1834 | /* Disable ints while we manipulate the stack pointer. */ |
1821 | 1835 | ||
1822 | movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL | 1836 | rsil a14, LOCKLEVEL |
1823 | xsr a14, ps | ||
1824 | rsr a3, excsave1 | 1837 | rsr a3, excsave1 |
1825 | rsync | 1838 | rsync |
1826 | s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */ | 1839 | s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */ |
@@ -1835,7 +1848,7 @@ ENTRY(_switch_to) | |||
1835 | 1848 | ||
1836 | /* Flush register file. */ | 1849 | /* Flush register file. */ |
1837 | 1850 | ||
1838 | call0 _spill_registers # destroys a3, a4, and SAR | 1851 | spill_registers_kernel |
1839 | 1852 | ||
1840 | /* Set kernel stack (and leave critical section) | 1853 | /* Set kernel stack (and leave critical section) |
1841 | * Note: It's save to set it here. The stack will not be overwritten | 1854 | * Note: It's save to set it here. The stack will not be overwritten |
@@ -1851,13 +1864,13 @@ ENTRY(_switch_to) | |||
1851 | 1864 | ||
1852 | /* restore context of the task 'next' */ | 1865 | /* restore context of the task 'next' */ |
1853 | 1866 | ||
1854 | l32i a0, a13, THREAD_RA # restore return address | 1867 | l32i a0, a11, THREAD_RA # restore return address |
1855 | l32i a1, a13, THREAD_SP # restore stack pointer | 1868 | l32i a1, a11, THREAD_SP # restore stack pointer |
1856 | 1869 | ||
1857 | load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER | 1870 | load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER |
1858 | 1871 | ||
1859 | wsr a14, ps | 1872 | wsr a14, ps |
1860 | mov a2, a12 # return 'prev' | 1873 | mov a2, a10 # return 'prev' |
1861 | rsync | 1874 | rsync |
1862 | 1875 | ||
1863 | retw | 1876 | retw |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 7d12af1317f1..84fe931bb60e 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/bootmem.h> | 22 | #include <linux/bootmem.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/percpu.h> | 24 | #include <linux/percpu.h> |
25 | #include <linux/clk-provider.h> | ||
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
26 | #include <linux/of_fdt.h> | 27 | #include <linux/of_fdt.h> |
27 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
@@ -276,6 +277,7 @@ void __init early_init_devtree(void *params) | |||
276 | 277 | ||
277 | static int __init xtensa_device_probe(void) | 278 | static int __init xtensa_device_probe(void) |
278 | { | 279 | { |
280 | of_clk_init(NULL); | ||
279 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 281 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
280 | return 0; | 282 | return 0; |
281 | } | 283 | } |
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 08b769d3b3a1..2a1823de69cc 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/platform.h> | 30 | #include <asm/platform.h> |
31 | 31 | ||
32 | unsigned long ccount_freq; /* ccount Hz */ | 32 | unsigned long ccount_freq; /* ccount Hz */ |
33 | EXPORT_SYMBOL(ccount_freq); | ||
33 | 34 | ||
34 | static cycle_t ccount_read(struct clocksource *cs) | 35 | static cycle_t ccount_read(struct clocksource *cs) |
35 | { | 36 | { |
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index cb8fd44caabc..f9e1ec346e35 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S | |||
@@ -235,7 +235,7 @@ ENTRY(_DoubleExceptionVector) | |||
235 | 235 | ||
236 | /* Check for overflow/underflow exception, jump if overflow. */ | 236 | /* Check for overflow/underflow exception, jump if overflow. */ |
237 | 237 | ||
238 | _bbci.l a0, 6, _DoubleExceptionVector_WindowOverflow | 238 | bbci.l a0, 6, _DoubleExceptionVector_WindowOverflow |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * Restart window underflow exception. | 241 | * Restart window underflow exception. |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 74a60c7e085e..80b33ed51f31 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -122,9 +122,7 @@ EXPORT_SYMBOL(insw); | |||
122 | EXPORT_SYMBOL(insl); | 122 | EXPORT_SYMBOL(insl); |
123 | 123 | ||
124 | extern long common_exception_return; | 124 | extern long common_exception_return; |
125 | extern long _spill_registers; | ||
126 | EXPORT_SYMBOL(common_exception_return); | 125 | EXPORT_SYMBOL(common_exception_return); |
127 | EXPORT_SYMBOL(_spill_registers); | ||
128 | 126 | ||
129 | #ifdef CONFIG_FUNCTION_TRACER | 127 | #ifdef CONFIG_FUNCTION_TRACER |
130 | EXPORT_SYMBOL(_mcount); | 128 | EXPORT_SYMBOL(_mcount); |
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 479d7537a32a..aff108df92d3 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -90,7 +90,7 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) | |||
90 | 90 | ||
91 | 91 | ||
92 | /* | 92 | /* |
93 | * Initialize the bootmem system and give it all the memory we have available. | 93 | * Initialize the bootmem system and give it all low memory we have available. |
94 | */ | 94 | */ |
95 | 95 | ||
96 | void __init bootmem_init(void) | 96 | void __init bootmem_init(void) |
@@ -142,9 +142,14 @@ void __init bootmem_init(void) | |||
142 | 142 | ||
143 | /* Add all remaining memory pieces into the bootmem map */ | 143 | /* Add all remaining memory pieces into the bootmem map */ |
144 | 144 | ||
145 | for (i=0; i<sysmem.nr_banks; i++) | 145 | for (i = 0; i < sysmem.nr_banks; i++) { |
146 | free_bootmem(sysmem.bank[i].start, | 146 | if (sysmem.bank[i].start >> PAGE_SHIFT < max_low_pfn) { |
147 | sysmem.bank[i].end - sysmem.bank[i].start); | 147 | unsigned long end = min(max_low_pfn << PAGE_SHIFT, |
148 | sysmem.bank[i].end); | ||
149 | free_bootmem(sysmem.bank[i].start, | ||
150 | end - sysmem.bank[i].start); | ||
151 | } | ||
152 | } | ||
148 | 153 | ||
149 | } | 154 | } |
150 | 155 | ||
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 36ec171698b8..861203e958da 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
@@ -39,7 +39,7 @@ void init_mmu(void) | |||
39 | set_itlbcfg_register(0); | 39 | set_itlbcfg_register(0); |
40 | set_dtlbcfg_register(0); | 40 | set_dtlbcfg_register(0); |
41 | #endif | 41 | #endif |
42 | #if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF | 42 | #if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) |
43 | /* | 43 | /* |
44 | * Update the IO area mapping in case xtensa_kio_paddr has changed | 44 | * Update the IO area mapping in case xtensa_kio_paddr has changed |
45 | */ | 45 | */ |
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 800227862fe8..57fd08b36f51 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c | |||
@@ -135,11 +135,11 @@ static void __init update_local_mac(struct device_node *node) | |||
135 | 135 | ||
136 | static int __init machine_setup(void) | 136 | static int __init machine_setup(void) |
137 | { | 137 | { |
138 | struct device_node *serial; | 138 | struct device_node *clock; |
139 | struct device_node *eth = NULL; | 139 | struct device_node *eth = NULL; |
140 | 140 | ||
141 | for_each_compatible_node(serial, NULL, "ns16550a") | 141 | for_each_node_by_name(clock, "main-oscillator") |
142 | update_clock_frequency(serial); | 142 | update_clock_frequency(clock); |
143 | 143 | ||
144 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) | 144 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) |
145 | update_local_mac(eth); | 145 | update_local_mac(eth); |
@@ -290,6 +290,7 @@ static int __init xtavnet_init(void) | |||
290 | * knows whether they set it correctly on the DIP switches. | 290 | * knows whether they set it correctly on the DIP switches. |
291 | */ | 291 | */ |
292 | pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); | 292 | pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); |
293 | ethoc_pdata.eth_clkfreq = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
293 | 294 | ||
294 | return 0; | 295 | return 0; |
295 | } | 296 | } |
diff --git a/arch/xtensa/variants/fsf/include/variant/tie.h b/arch/xtensa/variants/fsf/include/variant/tie.h index bf4020116df5..244cdea4dee5 100644 --- a/arch/xtensa/variants/fsf/include/variant/tie.h +++ b/arch/xtensa/variants/fsf/include/variant/tie.h | |||
@@ -18,13 +18,6 @@ | |||
18 | #define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */ | 18 | #define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */ |
19 | #define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ | 19 | #define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ |
20 | 20 | ||
21 | /* Basic parameters of each coprocessor: */ | ||
22 | #define XCHAL_CP7_NAME "XTIOP" | ||
23 | #define XCHAL_CP7_IDENT XTIOP | ||
24 | #define XCHAL_CP7_SA_SIZE 0 /* size of state save area */ | ||
25 | #define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */ | ||
26 | #define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */ | ||
27 | |||
28 | /* Filler info for unassigned coprocessors, to simplify arrays etc: */ | 21 | /* Filler info for unassigned coprocessors, to simplify arrays etc: */ |
29 | #define XCHAL_NCP_SA_SIZE 0 | 22 | #define XCHAL_NCP_SA_SIZE 0 |
30 | #define XCHAL_NCP_SA_ALIGN 1 | 23 | #define XCHAL_NCP_SA_ALIGN 1 |
@@ -42,6 +35,8 @@ | |||
42 | #define XCHAL_CP5_SA_ALIGN 1 | 35 | #define XCHAL_CP5_SA_ALIGN 1 |
43 | #define XCHAL_CP6_SA_SIZE 0 | 36 | #define XCHAL_CP6_SA_SIZE 0 |
44 | #define XCHAL_CP6_SA_ALIGN 1 | 37 | #define XCHAL_CP6_SA_ALIGN 1 |
38 | #define XCHAL_CP7_SA_SIZE 0 | ||
39 | #define XCHAL_CP7_SA_ALIGN 1 | ||
45 | 40 | ||
46 | /* Save area for non-coprocessor optional and custom (TIE) state: */ | 41 | /* Save area for non-coprocessor optional and custom (TIE) state: */ |
47 | #define XCHAL_NCP_SA_SIZE 0 | 42 | #define XCHAL_NCP_SA_SIZE 0 |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index e7515aa43d6b..6f190bc2b8b7 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -243,6 +243,8 @@ static int acpi_ac_resume(struct device *dev) | |||
243 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 243 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
244 | return 0; | 244 | return 0; |
245 | } | 245 | } |
246 | #else | ||
247 | #define acpi_ac_resume NULL | ||
246 | #endif | 248 | #endif |
247 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); | 249 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); |
248 | 250 | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 018a42883706..797a6938d051 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -841,6 +841,8 @@ static int acpi_battery_resume(struct device *dev) | |||
841 | acpi_battery_update(battery); | 841 | acpi_battery_update(battery); |
842 | return 0; | 842 | return 0; |
843 | } | 843 | } |
844 | #else | ||
845 | #define acpi_battery_resume NULL | ||
844 | #endif | 846 | #endif |
845 | 847 | ||
846 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); | 848 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 10e4964d051a..afec4526c48a 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -260,14 +260,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
260 | }, | 260 | }, |
261 | { | 261 | { |
262 | .callback = dmi_disable_osi_win8, | 262 | .callback = dmi_disable_osi_win8, |
263 | .ident = "Dell Inspiron 15R SE", | ||
264 | .matches = { | ||
265 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
266 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), | ||
267 | }, | ||
268 | }, | ||
269 | { | ||
270 | .callback = dmi_disable_osi_win8, | ||
271 | .ident = "ThinkPad Edge E530", | 263 | .ident = "ThinkPad Edge E530", |
272 | .matches = { | 264 | .matches = { |
273 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 265 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
@@ -322,56 +314,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
322 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), | 314 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), |
323 | }, | 315 | }, |
324 | }, | 316 | }, |
325 | { | ||
326 | .callback = dmi_disable_osi_win8, | ||
327 | .ident = "HP ProBook 2013 models", | ||
328 | .matches = { | ||
329 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
330 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook "), | ||
331 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
332 | }, | ||
333 | }, | ||
334 | { | ||
335 | .callback = dmi_disable_osi_win8, | ||
336 | .ident = "HP EliteBook 2013 models", | ||
337 | .matches = { | ||
338 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
339 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), | ||
340 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
341 | }, | ||
342 | }, | ||
343 | { | ||
344 | .callback = dmi_disable_osi_win8, | ||
345 | .ident = "HP ZBook 14", | ||
346 | .matches = { | ||
347 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
348 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 14"), | ||
349 | }, | ||
350 | }, | ||
351 | { | ||
352 | .callback = dmi_disable_osi_win8, | ||
353 | .ident = "HP ZBook 15", | ||
354 | .matches = { | ||
355 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
356 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 15"), | ||
357 | }, | ||
358 | }, | ||
359 | { | ||
360 | .callback = dmi_disable_osi_win8, | ||
361 | .ident = "HP ZBook 17", | ||
362 | .matches = { | ||
363 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
364 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 17"), | ||
365 | }, | ||
366 | }, | ||
367 | { | ||
368 | .callback = dmi_disable_osi_win8, | ||
369 | .ident = "HP EliteBook 8780w", | ||
370 | .matches = { | ||
371 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
372 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), | ||
373 | }, | ||
374 | }, | ||
375 | 317 | ||
376 | /* | 318 | /* |
377 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 319 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 11c11f6b8fa1..714e957a871a 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -80,6 +80,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event); | |||
80 | 80 | ||
81 | #ifdef CONFIG_PM_SLEEP | 81 | #ifdef CONFIG_PM_SLEEP |
82 | static int acpi_button_resume(struct device *dev); | 82 | static int acpi_button_resume(struct device *dev); |
83 | #else | ||
84 | #define acpi_button_resume NULL | ||
83 | #endif | 85 | #endif |
84 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); | 86 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); |
85 | 87 | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index e9b3081c4fe9..5bfd769fc91f 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -713,13 +713,11 @@ static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl, | |||
713 | static ssize_t show_docked(struct device *dev, | 713 | static ssize_t show_docked(struct device *dev, |
714 | struct device_attribute *attr, char *buf) | 714 | struct device_attribute *attr, char *buf) |
715 | { | 715 | { |
716 | struct acpi_device *tmp; | ||
717 | |||
718 | struct dock_station *dock_station = dev->platform_data; | 716 | struct dock_station *dock_station = dev->platform_data; |
717 | struct acpi_device *adev = NULL; | ||
719 | 718 | ||
720 | if (!acpi_bus_get_device(dock_station->handle, &tmp)) | 719 | acpi_bus_get_device(dock_station->handle, &adev); |
721 | return snprintf(buf, PAGE_SIZE, "1\n"); | 720 | return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev)); |
722 | return snprintf(buf, PAGE_SIZE, "0\n"); | ||
723 | } | 721 | } |
724 | static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | 722 | static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); |
725 | 723 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 1fb62900f32a..09e423f3d8ad 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -55,6 +55,9 @@ MODULE_DEVICE_TABLE(acpi, fan_device_ids); | |||
55 | #ifdef CONFIG_PM_SLEEP | 55 | #ifdef CONFIG_PM_SLEEP |
56 | static int acpi_fan_suspend(struct device *dev); | 56 | static int acpi_fan_suspend(struct device *dev); |
57 | static int acpi_fan_resume(struct device *dev); | 57 | static int acpi_fan_resume(struct device *dev); |
58 | #else | ||
59 | #define acpi_fan_suspend NULL | ||
60 | #define acpi_fan_resume NULL | ||
58 | #endif | 61 | #endif |
59 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); | 62 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); |
60 | 63 | ||
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 52d45ea2bc4f..361b40c10c3f 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -430,6 +430,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
430 | pin_name(pin)); | 430 | pin_name(pin)); |
431 | } | 431 | } |
432 | 432 | ||
433 | kfree(entry); | ||
433 | return 0; | 434 | return 0; |
434 | } | 435 | } |
435 | 436 | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 28baa05b8018..84243c32e29c 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -56,6 +56,12 @@ struct throttling_tstate { | |||
56 | int target_state; /* target T-state */ | 56 | int target_state; /* target T-state */ |
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct acpi_processor_throttling_arg { | ||
60 | struct acpi_processor *pr; | ||
61 | int target_state; | ||
62 | bool force; | ||
63 | }; | ||
64 | |||
59 | #define THROTTLING_PRECHANGE (1) | 65 | #define THROTTLING_PRECHANGE (1) |
60 | #define THROTTLING_POSTCHANGE (2) | 66 | #define THROTTLING_POSTCHANGE (2) |
61 | 67 | ||
@@ -1060,16 +1066,24 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | |||
1060 | return 0; | 1066 | return 0; |
1061 | } | 1067 | } |
1062 | 1068 | ||
1069 | static long acpi_processor_throttling_fn(void *data) | ||
1070 | { | ||
1071 | struct acpi_processor_throttling_arg *arg = data; | ||
1072 | struct acpi_processor *pr = arg->pr; | ||
1073 | |||
1074 | return pr->throttling.acpi_processor_set_throttling(pr, | ||
1075 | arg->target_state, arg->force); | ||
1076 | } | ||
1077 | |||
1063 | int acpi_processor_set_throttling(struct acpi_processor *pr, | 1078 | int acpi_processor_set_throttling(struct acpi_processor *pr, |
1064 | int state, bool force) | 1079 | int state, bool force) |
1065 | { | 1080 | { |
1066 | cpumask_var_t saved_mask; | ||
1067 | int ret = 0; | 1081 | int ret = 0; |
1068 | unsigned int i; | 1082 | unsigned int i; |
1069 | struct acpi_processor *match_pr; | 1083 | struct acpi_processor *match_pr; |
1070 | struct acpi_processor_throttling *p_throttling; | 1084 | struct acpi_processor_throttling *p_throttling; |
1085 | struct acpi_processor_throttling_arg arg; | ||
1071 | struct throttling_tstate t_state; | 1086 | struct throttling_tstate t_state; |
1072 | cpumask_var_t online_throttling_cpus; | ||
1073 | 1087 | ||
1074 | if (!pr) | 1088 | if (!pr) |
1075 | return -EINVAL; | 1089 | return -EINVAL; |
@@ -1080,14 +1094,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1080 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) | 1094 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) |
1081 | return -EINVAL; | 1095 | return -EINVAL; |
1082 | 1096 | ||
1083 | if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) | ||
1084 | return -ENOMEM; | ||
1085 | |||
1086 | if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) { | ||
1087 | free_cpumask_var(saved_mask); | ||
1088 | return -ENOMEM; | ||
1089 | } | ||
1090 | |||
1091 | if (cpu_is_offline(pr->id)) { | 1097 | if (cpu_is_offline(pr->id)) { |
1092 | /* | 1098 | /* |
1093 | * the cpu pointed by pr->id is offline. Unnecessary to change | 1099 | * the cpu pointed by pr->id is offline. Unnecessary to change |
@@ -1096,17 +1102,15 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1096 | return -ENODEV; | 1102 | return -ENODEV; |
1097 | } | 1103 | } |
1098 | 1104 | ||
1099 | cpumask_copy(saved_mask, ¤t->cpus_allowed); | ||
1100 | t_state.target_state = state; | 1105 | t_state.target_state = state; |
1101 | p_throttling = &(pr->throttling); | 1106 | p_throttling = &(pr->throttling); |
1102 | cpumask_and(online_throttling_cpus, cpu_online_mask, | 1107 | |
1103 | p_throttling->shared_cpu_map); | ||
1104 | /* | 1108 | /* |
1105 | * The throttling notifier will be called for every | 1109 | * The throttling notifier will be called for every |
1106 | * affected cpu in order to get one proper T-state. | 1110 | * affected cpu in order to get one proper T-state. |
1107 | * The notifier event is THROTTLING_PRECHANGE. | 1111 | * The notifier event is THROTTLING_PRECHANGE. |
1108 | */ | 1112 | */ |
1109 | for_each_cpu(i, online_throttling_cpus) { | 1113 | for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) { |
1110 | t_state.cpu = i; | 1114 | t_state.cpu = i; |
1111 | acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, | 1115 | acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, |
1112 | &t_state); | 1116 | &t_state); |
@@ -1118,21 +1122,18 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1118 | * it can be called only for the cpu pointed by pr. | 1122 | * it can be called only for the cpu pointed by pr. |
1119 | */ | 1123 | */ |
1120 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { | 1124 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { |
1121 | /* FIXME: use work_on_cpu() */ | 1125 | arg.pr = pr; |
1122 | if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { | 1126 | arg.target_state = state; |
1123 | /* Can't migrate to the pr->id CPU. Exit */ | 1127 | arg.force = force; |
1124 | ret = -ENODEV; | 1128 | ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg); |
1125 | goto exit; | ||
1126 | } | ||
1127 | ret = p_throttling->acpi_processor_set_throttling(pr, | ||
1128 | t_state.target_state, force); | ||
1129 | } else { | 1129 | } else { |
1130 | /* | 1130 | /* |
1131 | * When the T-state coordination is SW_ALL or HW_ALL, | 1131 | * When the T-state coordination is SW_ALL or HW_ALL, |
1132 | * it is necessary to set T-state for every affected | 1132 | * it is necessary to set T-state for every affected |
1133 | * cpus. | 1133 | * cpus. |
1134 | */ | 1134 | */ |
1135 | for_each_cpu(i, online_throttling_cpus) { | 1135 | for_each_cpu_and(i, cpu_online_mask, |
1136 | p_throttling->shared_cpu_map) { | ||
1136 | match_pr = per_cpu(processors, i); | 1137 | match_pr = per_cpu(processors, i); |
1137 | /* | 1138 | /* |
1138 | * If the pointer is invalid, we will report the | 1139 | * If the pointer is invalid, we will report the |
@@ -1153,13 +1154,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1153 | "on CPU %d\n", i)); | 1154 | "on CPU %d\n", i)); |
1154 | continue; | 1155 | continue; |
1155 | } | 1156 | } |
1156 | t_state.cpu = i; | 1157 | |
1157 | /* FIXME: use work_on_cpu() */ | 1158 | arg.pr = match_pr; |
1158 | if (set_cpus_allowed_ptr(current, cpumask_of(i))) | 1159 | arg.target_state = state; |
1159 | continue; | 1160 | arg.force = force; |
1160 | ret = match_pr->throttling. | 1161 | ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, |
1161 | acpi_processor_set_throttling( | 1162 | &arg); |
1162 | match_pr, t_state.target_state, force); | ||
1163 | } | 1163 | } |
1164 | } | 1164 | } |
1165 | /* | 1165 | /* |
@@ -1168,17 +1168,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1168 | * affected cpu to update the T-states. | 1168 | * affected cpu to update the T-states. |
1169 | * The notifier event is THROTTLING_POSTCHANGE | 1169 | * The notifier event is THROTTLING_POSTCHANGE |
1170 | */ | 1170 | */ |
1171 | for_each_cpu(i, online_throttling_cpus) { | 1171 | for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) { |
1172 | t_state.cpu = i; | 1172 | t_state.cpu = i; |
1173 | acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, | 1173 | acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, |
1174 | &t_state); | 1174 | &t_state); |
1175 | } | 1175 | } |
1176 | /* restore the previous state */ | 1176 | |
1177 | /* FIXME: use work_on_cpu() */ | ||
1178 | set_cpus_allowed_ptr(current, saved_mask); | ||
1179 | exit: | ||
1180 | free_cpumask_var(online_throttling_cpus); | ||
1181 | free_cpumask_var(saved_mask); | ||
1182 | return ret; | 1177 | return ret; |
1183 | } | 1178 | } |
1184 | 1179 | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index d465ae6cdd00..dbd48498b938 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -450,7 +450,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
450 | { | 450 | { |
451 | unsigned long x; | 451 | unsigned long x; |
452 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); | 452 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); |
453 | if (sscanf(buf, "%ld\n", &x) == 1) | 453 | if (sscanf(buf, "%lu\n", &x) == 1) |
454 | battery->alarm_capacity = x / | 454 | battery->alarm_capacity = x / |
455 | (1000 * acpi_battery_scale(battery)); | 455 | (1000 * acpi_battery_scale(battery)); |
456 | if (battery->present) | 456 | if (battery->present) |
@@ -668,6 +668,8 @@ static int acpi_sbs_resume(struct device *dev) | |||
668 | acpi_sbs_callback(sbs); | 668 | acpi_sbs_callback(sbs); |
669 | return 0; | 669 | return 0; |
670 | } | 670 | } |
671 | #else | ||
672 | #define acpi_sbs_resume NULL | ||
671 | #endif | 673 | #endif |
672 | 674 | ||
673 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); | 675 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 8349a555b92b..08626c851be7 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -102,6 +102,8 @@ MODULE_DEVICE_TABLE(acpi, thermal_device_ids); | |||
102 | 102 | ||
103 | #ifdef CONFIG_PM_SLEEP | 103 | #ifdef CONFIG_PM_SLEEP |
104 | static int acpi_thermal_resume(struct device *dev); | 104 | static int acpi_thermal_resume(struct device *dev); |
105 | #else | ||
106 | #define acpi_thermal_resume NULL | ||
105 | #endif | 107 | #endif |
106 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); | 108 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); |
107 | 109 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index b727d105046d..b6ba88ed31ae 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -81,11 +81,12 @@ static bool allow_duplicates; | |||
81 | module_param(allow_duplicates, bool, 0644); | 81 | module_param(allow_duplicates, bool, 0644); |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * For Windows 8 systems: if set ture and the GPU driver has | 84 | * For Windows 8 systems: used to decide if video module |
85 | * registered a backlight interface, skip registering ACPI video's. | 85 | * should skip registering backlight interface of its own. |
86 | */ | 86 | */ |
87 | static bool use_native_backlight = false; | 87 | static int use_native_backlight_param = -1; |
88 | module_param(use_native_backlight, bool, 0644); | 88 | module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); |
89 | static bool use_native_backlight_dmi = false; | ||
89 | 90 | ||
90 | static int register_count; | 91 | static int register_count; |
91 | static struct mutex video_list_lock; | 92 | static struct mutex video_list_lock; |
@@ -231,9 +232,17 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
231 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 232 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
232 | int event); | 233 | int event); |
233 | 234 | ||
235 | static bool acpi_video_use_native_backlight(void) | ||
236 | { | ||
237 | if (use_native_backlight_param != -1) | ||
238 | return use_native_backlight_param; | ||
239 | else | ||
240 | return use_native_backlight_dmi; | ||
241 | } | ||
242 | |||
234 | static bool acpi_video_verify_backlight_support(void) | 243 | static bool acpi_video_verify_backlight_support(void) |
235 | { | 244 | { |
236 | if (acpi_osi_is_win8() && use_native_backlight && | 245 | if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && |
237 | backlight_device_registered(BACKLIGHT_RAW)) | 246 | backlight_device_registered(BACKLIGHT_RAW)) |
238 | return false; | 247 | return false; |
239 | return acpi_video_backlight_support(); | 248 | return acpi_video_backlight_support(); |
@@ -398,6 +407,12 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d) | |||
398 | return 0; | 407 | return 0; |
399 | } | 408 | } |
400 | 409 | ||
410 | static int __init video_set_use_native_backlight(const struct dmi_system_id *d) | ||
411 | { | ||
412 | use_native_backlight_dmi = true; | ||
413 | return 0; | ||
414 | } | ||
415 | |||
401 | static struct dmi_system_id video_dmi_table[] __initdata = { | 416 | static struct dmi_system_id video_dmi_table[] __initdata = { |
402 | /* | 417 | /* |
403 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 | 418 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 |
@@ -442,6 +457,120 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
442 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), | 457 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), |
443 | }, | 458 | }, |
444 | }, | 459 | }, |
460 | { | ||
461 | .callback = video_set_use_native_backlight, | ||
462 | .ident = "ThinkPad T430s", | ||
463 | .matches = { | ||
464 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
465 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), | ||
466 | }, | ||
467 | }, | ||
468 | { | ||
469 | .callback = video_set_use_native_backlight, | ||
470 | .ident = "ThinkPad X230", | ||
471 | .matches = { | ||
472 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
473 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), | ||
474 | }, | ||
475 | }, | ||
476 | { | ||
477 | .callback = video_set_use_native_backlight, | ||
478 | .ident = "ThinkPad X1 Carbon", | ||
479 | .matches = { | ||
480 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
481 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), | ||
482 | }, | ||
483 | }, | ||
484 | { | ||
485 | .callback = video_set_use_native_backlight, | ||
486 | .ident = "Lenovo Yoga 13", | ||
487 | .matches = { | ||
488 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
489 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"), | ||
490 | }, | ||
491 | }, | ||
492 | { | ||
493 | .callback = video_set_use_native_backlight, | ||
494 | .ident = "Dell Inspiron 7520", | ||
495 | .matches = { | ||
496 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
497 | DMI_MATCH(DMI_PRODUCT_VERSION, "Inspiron 7520"), | ||
498 | }, | ||
499 | }, | ||
500 | { | ||
501 | .callback = video_set_use_native_backlight, | ||
502 | .ident = "Acer Aspire 5733Z", | ||
503 | .matches = { | ||
504 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
505 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5733Z"), | ||
506 | }, | ||
507 | }, | ||
508 | { | ||
509 | .callback = video_set_use_native_backlight, | ||
510 | .ident = "Acer Aspire V5-431", | ||
511 | .matches = { | ||
512 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
513 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-431"), | ||
514 | }, | ||
515 | }, | ||
516 | { | ||
517 | .callback = video_set_use_native_backlight, | ||
518 | .ident = "HP ProBook 4340s", | ||
519 | .matches = { | ||
520 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
521 | DMI_MATCH(DMI_PRODUCT_VERSION, "HP ProBook 4340s"), | ||
522 | }, | ||
523 | }, | ||
524 | { | ||
525 | .callback = video_set_use_native_backlight, | ||
526 | .ident = "HP ProBook 2013 models", | ||
527 | .matches = { | ||
528 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
529 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook "), | ||
530 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
531 | }, | ||
532 | }, | ||
533 | { | ||
534 | .callback = video_set_use_native_backlight, | ||
535 | .ident = "HP EliteBook 2013 models", | ||
536 | .matches = { | ||
537 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
538 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), | ||
539 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
540 | }, | ||
541 | }, | ||
542 | { | ||
543 | .callback = video_set_use_native_backlight, | ||
544 | .ident = "HP ZBook 14", | ||
545 | .matches = { | ||
546 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
547 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 14"), | ||
548 | }, | ||
549 | }, | ||
550 | { | ||
551 | .callback = video_set_use_native_backlight, | ||
552 | .ident = "HP ZBook 15", | ||
553 | .matches = { | ||
554 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
555 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 15"), | ||
556 | }, | ||
557 | }, | ||
558 | { | ||
559 | .callback = video_set_use_native_backlight, | ||
560 | .ident = "HP ZBook 17", | ||
561 | .matches = { | ||
562 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
563 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 17"), | ||
564 | }, | ||
565 | }, | ||
566 | { | ||
567 | .callback = video_set_use_native_backlight, | ||
568 | .ident = "HP EliteBook 8780w", | ||
569 | .matches = { | ||
570 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
571 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), | ||
572 | }, | ||
573 | }, | ||
445 | {} | 574 | {} |
446 | }; | 575 | }; |
447 | 576 | ||
@@ -685,6 +814,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
685 | union acpi_object *o; | 814 | union acpi_object *o; |
686 | struct acpi_video_device_brightness *br = NULL; | 815 | struct acpi_video_device_brightness *br = NULL; |
687 | int result = -EINVAL; | 816 | int result = -EINVAL; |
817 | u32 value; | ||
688 | 818 | ||
689 | if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { | 819 | if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { |
690 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " | 820 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " |
@@ -715,7 +845,12 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
715 | printk(KERN_ERR PREFIX "Invalid data\n"); | 845 | printk(KERN_ERR PREFIX "Invalid data\n"); |
716 | continue; | 846 | continue; |
717 | } | 847 | } |
718 | br->levels[count] = (u32) o->integer.value; | 848 | value = (u32) o->integer.value; |
849 | /* Skip duplicate entries */ | ||
850 | if (count > 2 && br->levels[count - 1] == value) | ||
851 | continue; | ||
852 | |||
853 | br->levels[count] = value; | ||
719 | 854 | ||
720 | if (br->levels[count] > max_level) | 855 | if (br->levels[count] > max_level) |
721 | max_level = br->levels[count]; | 856 | max_level = br->levels[count]; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index a697b77b8865..19080c8e2f2a 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -168,22 +168,6 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
168 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), | 168 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), |
169 | }, | 169 | }, |
170 | }, | 170 | }, |
171 | { | ||
172 | .callback = video_detect_force_vendor, | ||
173 | .ident = "HP EliteBook Revolve 810", | ||
174 | .matches = { | ||
175 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
176 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Revolve 810 G1"), | ||
177 | }, | ||
178 | }, | ||
179 | { | ||
180 | .callback = video_detect_force_vendor, | ||
181 | .ident = "Lenovo Yoga 13", | ||
182 | .matches = { | ||
183 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
184 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"), | ||
185 | }, | ||
186 | }, | ||
187 | { }, | 171 | { }, |
188 | }; | 172 | }; |
189 | 173 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 4e737728aee2..868429a47be4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -247,6 +247,7 @@ config SATA_HIGHBANK | |||
247 | 247 | ||
248 | config SATA_MV | 248 | config SATA_MV |
249 | tristate "Marvell SATA support" | 249 | tristate "Marvell SATA support" |
250 | select GENERIC_PHY | ||
250 | help | 251 | help |
251 | This option enables support for the Marvell Serial ATA family. | 252 | This option enables support for the Marvell Serial ATA family. |
252 | Currently supports 88SX[56]0[48][01] PCI(-X) chips, | 253 | Currently supports 88SX[56]0[48][01] PCI(-X) chips, |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index dc2756fb6f33..c81d809c111b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -61,6 +61,7 @@ enum board_ids { | |||
61 | /* board IDs by feature in alphabetical order */ | 61 | /* board IDs by feature in alphabetical order */ |
62 | board_ahci, | 62 | board_ahci, |
63 | board_ahci_ign_iferr, | 63 | board_ahci_ign_iferr, |
64 | board_ahci_noncq, | ||
64 | board_ahci_nosntf, | 65 | board_ahci_nosntf, |
65 | board_ahci_yes_fbs, | 66 | board_ahci_yes_fbs, |
66 | 67 | ||
@@ -121,6 +122,13 @@ static const struct ata_port_info ahci_port_info[] = { | |||
121 | .udma_mask = ATA_UDMA6, | 122 | .udma_mask = ATA_UDMA6, |
122 | .port_ops = &ahci_ops, | 123 | .port_ops = &ahci_ops, |
123 | }, | 124 | }, |
125 | [board_ahci_noncq] = { | ||
126 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), | ||
127 | .flags = AHCI_FLAG_COMMON, | ||
128 | .pio_mask = ATA_PIO4, | ||
129 | .udma_mask = ATA_UDMA6, | ||
130 | .port_ops = &ahci_ops, | ||
131 | }, | ||
124 | [board_ahci_nosntf] = { | 132 | [board_ahci_nosntf] = { |
125 | AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF), | 133 | AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF), |
126 | .flags = AHCI_FLAG_COMMON, | 134 | .flags = AHCI_FLAG_COMMON, |
@@ -452,6 +460,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
452 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ | 460 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ |
453 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | 461 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ |
454 | 462 | ||
463 | /* | ||
464 | * Samsung SSDs found on some macbooks. NCQ times out. | ||
465 | * https://bugzilla.kernel.org/show_bug.cgi?id=60731 | ||
466 | */ | ||
467 | { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq }, | ||
468 | |||
455 | /* Enmotus */ | 469 | /* Enmotus */ |
456 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, | 470 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, |
457 | 471 | ||
@@ -1170,8 +1184,10 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1170 | 1184 | ||
1171 | nvec = rc; | 1185 | nvec = rc; |
1172 | rc = pci_enable_msi_block(pdev, nvec); | 1186 | rc = pci_enable_msi_block(pdev, nvec); |
1173 | if (rc) | 1187 | if (rc < 0) |
1174 | goto intx; | 1188 | goto intx; |
1189 | else if (rc > 0) | ||
1190 | goto single_msi; | ||
1175 | 1191 | ||
1176 | return nvec; | 1192 | return nvec; |
1177 | 1193 | ||
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 20fd337a5731..7ccc084bf1df 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
@@ -447,8 +447,11 @@ static void sata_pmp_quirks(struct ata_port *ap) | |||
447 | * otherwise. Don't try hard to recover it. | 447 | * otherwise. Don't try hard to recover it. |
448 | */ | 448 | */ |
449 | ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; | 449 | ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; |
450 | } else if (vendor == 0x197b && devid == 0x2352) { | 450 | } else if (vendor == 0x197b && (devid == 0x2352 || devid == 0x0325)) { |
451 | /* chip found in Thermaltake BlackX Duet, jmicron JMB350? */ | 451 | /* |
452 | * 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350? | ||
453 | * 0x0325: jmicron JMB394. | ||
454 | */ | ||
452 | ata_for_each_link(link, ap, EDGE) { | 455 | ata_for_each_link(link, ap, EDGE) { |
453 | /* SRST breaks detection and disks get misclassified | 456 | /* SRST breaks detection and disks get misclassified |
454 | * LPM disabled to avoid potential problems | 457 | * LPM disabled to avoid potential problems |
diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index 26386f0b89a8..b0b18ec5465f 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c | |||
@@ -119,7 +119,9 @@ static int pata_imx_probe(struct platform_device *pdev) | |||
119 | return PTR_ERR(priv->clk); | 119 | return PTR_ERR(priv->clk); |
120 | } | 120 | } |
121 | 121 | ||
122 | clk_prepare_enable(priv->clk); | 122 | ret = clk_prepare_enable(priv->clk); |
123 | if (ret) | ||
124 | return ret; | ||
123 | 125 | ||
124 | host = ata_host_alloc(&pdev->dev, 1); | 126 | host = ata_host_alloc(&pdev->dev, 1); |
125 | if (!host) { | 127 | if (!host) { |
@@ -212,7 +214,9 @@ static int pata_imx_resume(struct device *dev) | |||
212 | struct ata_host *host = dev_get_drvdata(dev); | 214 | struct ata_host *host = dev_get_drvdata(dev); |
213 | struct pata_imx_priv *priv = host->private_data; | 215 | struct pata_imx_priv *priv = host->private_data; |
214 | 216 | ||
215 | clk_prepare_enable(priv->clk); | 217 | int ret = clk_prepare_enable(priv->clk); |
218 | if (ret) | ||
219 | return ret; | ||
216 | 220 | ||
217 | __raw_writel(priv->ata_ctl, priv->host_regs + PATA_IMX_ATA_CONTROL); | 221 | __raw_writel(priv->ata_ctl, priv->host_regs + PATA_IMX_ATA_CONTROL); |
218 | 222 | ||
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 52b8181ddafd..05c8a44adf8e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -4104,7 +4104,6 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4104 | if (!hpriv->port_phys) | 4104 | if (!hpriv->port_phys) |
4105 | return -ENOMEM; | 4105 | return -ENOMEM; |
4106 | host->private_data = hpriv; | 4106 | host->private_data = hpriv; |
4107 | hpriv->n_ports = n_ports; | ||
4108 | hpriv->board_idx = chip_soc; | 4107 | hpriv->board_idx = chip_soc; |
4109 | 4108 | ||
4110 | host->iomap = NULL; | 4109 | host->iomap = NULL; |
@@ -4132,13 +4131,18 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4132 | rc = PTR_ERR(hpriv->port_phys[port]); | 4131 | rc = PTR_ERR(hpriv->port_phys[port]); |
4133 | hpriv->port_phys[port] = NULL; | 4132 | hpriv->port_phys[port] = NULL; |
4134 | if (rc != -EPROBE_DEFER) | 4133 | if (rc != -EPROBE_DEFER) |
4135 | dev_warn(&pdev->dev, "error getting phy %d", | 4134 | dev_warn(&pdev->dev, "error getting phy %d", rc); |
4136 | rc); | 4135 | |
4136 | /* Cleanup only the initialized ports */ | ||
4137 | hpriv->n_ports = port; | ||
4137 | goto err; | 4138 | goto err; |
4138 | } else | 4139 | } else |
4139 | phy_power_on(hpriv->port_phys[port]); | 4140 | phy_power_on(hpriv->port_phys[port]); |
4140 | } | 4141 | } |
4141 | 4142 | ||
4143 | /* All the ports have been initialized */ | ||
4144 | hpriv->n_ports = n_ports; | ||
4145 | |||
4142 | /* | 4146 | /* |
4143 | * (Re-)program MBUS remapping windows if we are asked to. | 4147 | * (Re-)program MBUS remapping windows if we are asked to. |
4144 | */ | 4148 | */ |
@@ -4176,7 +4180,7 @@ err: | |||
4176 | clk_disable_unprepare(hpriv->clk); | 4180 | clk_disable_unprepare(hpriv->clk); |
4177 | clk_put(hpriv->clk); | 4181 | clk_put(hpriv->clk); |
4178 | } | 4182 | } |
4179 | for (port = 0; port < n_ports; port++) { | 4183 | for (port = 0; port < hpriv->n_ports; port++) { |
4180 | if (!IS_ERR(hpriv->port_clks[port])) { | 4184 | if (!IS_ERR(hpriv->port_clks[port])) { |
4181 | clk_disable_unprepare(hpriv->port_clks[port]); | 4185 | clk_disable_unprepare(hpriv->port_clks[port]); |
4182 | clk_put(hpriv->port_clks[port]); | 4186 | clk_put(hpriv->port_clks[port]); |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index d67fc351343c..b7695e804635 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -157,6 +157,7 @@ static const struct sil_drivelist { | |||
157 | { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, | 157 | { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, |
158 | { "ST3120022ASL", SIL_QUIRK_MOD15WRITE }, | 158 | { "ST3120022ASL", SIL_QUIRK_MOD15WRITE }, |
159 | { "ST3160021ASL", SIL_QUIRK_MOD15WRITE }, | 159 | { "ST3160021ASL", SIL_QUIRK_MOD15WRITE }, |
160 | { "TOSHIBA MK2561GSYN", SIL_QUIRK_MOD15WRITE }, | ||
160 | { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX }, | 161 | { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX }, |
161 | { } | 162 | { } |
162 | }; | 163 | }; |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 1e16cbd61da2..61d6d62cc0d3 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -616,36 +616,35 @@ static int dma_buf_describe(struct seq_file *s) | |||
616 | if (ret) | 616 | if (ret) |
617 | return ret; | 617 | return ret; |
618 | 618 | ||
619 | seq_printf(s, "\nDma-buf Objects:\n"); | 619 | seq_puts(s, "\nDma-buf Objects:\n"); |
620 | seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n"); | 620 | seq_puts(s, "size\tflags\tmode\tcount\texp_name\n"); |
621 | 621 | ||
622 | list_for_each_entry(buf_obj, &db_list.head, list_node) { | 622 | list_for_each_entry(buf_obj, &db_list.head, list_node) { |
623 | ret = mutex_lock_interruptible(&buf_obj->lock); | 623 | ret = mutex_lock_interruptible(&buf_obj->lock); |
624 | 624 | ||
625 | if (ret) { | 625 | if (ret) { |
626 | seq_printf(s, | 626 | seq_puts(s, |
627 | "\tERROR locking buffer object: skipping\n"); | 627 | "\tERROR locking buffer object: skipping\n"); |
628 | continue; | 628 | continue; |
629 | } | 629 | } |
630 | 630 | ||
631 | seq_printf(s, "\t"); | 631 | seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n", |
632 | 632 | buf_obj->size, | |
633 | seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08ld\n", | ||
634 | buf_obj->exp_name, buf_obj->size, | ||
635 | buf_obj->file->f_flags, buf_obj->file->f_mode, | 633 | buf_obj->file->f_flags, buf_obj->file->f_mode, |
636 | (long)(buf_obj->file->f_count.counter)); | 634 | (long)(buf_obj->file->f_count.counter), |
635 | buf_obj->exp_name); | ||
637 | 636 | ||
638 | seq_printf(s, "\t\tAttached Devices:\n"); | 637 | seq_puts(s, "\tAttached Devices:\n"); |
639 | attach_count = 0; | 638 | attach_count = 0; |
640 | 639 | ||
641 | list_for_each_entry(attach_obj, &buf_obj->attachments, node) { | 640 | list_for_each_entry(attach_obj, &buf_obj->attachments, node) { |
642 | seq_printf(s, "\t\t"); | 641 | seq_puts(s, "\t"); |
643 | 642 | ||
644 | seq_printf(s, "%s\n", attach_obj->dev->init_name); | 643 | seq_printf(s, "%s\n", dev_name(attach_obj->dev)); |
645 | attach_count++; | 644 | attach_count++; |
646 | } | 645 | } |
647 | 646 | ||
648 | seq_printf(s, "\n\t\tTotal %d devices attached\n", | 647 | seq_printf(s, "Total %d devices attached\n\n", |
649 | attach_count); | 648 | attach_count); |
650 | 649 | ||
651 | count++; | 650 | count++; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 8a97ddfa6122..c30df50e4440 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -1580,6 +1580,7 @@ static int fw_pm_notify(struct notifier_block *notify_block, | |||
1580 | switch (mode) { | 1580 | switch (mode) { |
1581 | case PM_HIBERNATION_PREPARE: | 1581 | case PM_HIBERNATION_PREPARE: |
1582 | case PM_SUSPEND_PREPARE: | 1582 | case PM_SUSPEND_PREPARE: |
1583 | case PM_RESTORE_PREPARE: | ||
1583 | kill_requests_without_uevent(); | 1584 | kill_requests_without_uevent(); |
1584 | device_cache_fw_images(); | 1585 | device_cache_fw_images(); |
1585 | break; | 1586 | break; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 08ca8c9f41cd..cb003a6b72c8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1323,8 +1323,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, | |||
1323 | up_read(&policy->rwsem); | 1323 | up_read(&policy->rwsem); |
1324 | 1324 | ||
1325 | if (cpu != policy->cpu) { | 1325 | if (cpu != policy->cpu) { |
1326 | if (!frozen) | 1326 | sysfs_remove_link(&dev->kobj, "cpufreq"); |
1327 | sysfs_remove_link(&dev->kobj, "cpufreq"); | ||
1328 | } else if (cpus > 1) { | 1327 | } else if (cpus > 1) { |
1329 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); | 1328 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); |
1330 | if (new_cpu >= 0) { | 1329 | if (new_cpu >= 0) { |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index c788abf1c457..2cd36b9297f3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -34,12 +34,15 @@ | |||
34 | 34 | ||
35 | #define SAMPLE_COUNT 3 | 35 | #define SAMPLE_COUNT 3 |
36 | 36 | ||
37 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
38 | #define BYT_VIDS 0x66b | 38 | #define BYT_VIDS 0x66b |
39 | #define BYT_TURBO_RATIOS 0x66c | ||
39 | 40 | ||
40 | #define FRAC_BITS 8 | 41 | |
42 | #define FRAC_BITS 6 | ||
41 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 43 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
42 | #define fp_toint(X) ((X) >> FRAC_BITS) | 44 | #define fp_toint(X) ((X) >> FRAC_BITS) |
45 | #define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) | ||
43 | 46 | ||
44 | static inline int32_t mul_fp(int32_t x, int32_t y) | 47 | static inline int32_t mul_fp(int32_t x, int32_t y) |
45 | { | 48 | { |
@@ -357,7 +360,7 @@ static int byt_get_min_pstate(void) | |||
357 | { | 360 | { |
358 | u64 value; | 361 | u64 value; |
359 | rdmsrl(BYT_RATIOS, value); | 362 | rdmsrl(BYT_RATIOS, value); |
360 | return value & 0xFF; | 363 | return (value >> 8) & 0xFF; |
361 | } | 364 | } |
362 | 365 | ||
363 | static int byt_get_max_pstate(void) | 366 | static int byt_get_max_pstate(void) |
@@ -367,6 +370,13 @@ static int byt_get_max_pstate(void) | |||
367 | return (value >> 16) & 0xFF; | 370 | return (value >> 16) & 0xFF; |
368 | } | 371 | } |
369 | 372 | ||
373 | static int byt_get_turbo_pstate(void) | ||
374 | { | ||
375 | u64 value; | ||
376 | rdmsrl(BYT_TURBO_RATIOS, value); | ||
377 | return value & 0x3F; | ||
378 | } | ||
379 | |||
370 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) | 380 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) |
371 | { | 381 | { |
372 | u64 val; | 382 | u64 val; |
@@ -469,7 +479,7 @@ static struct cpu_defaults byt_params = { | |||
469 | .funcs = { | 479 | .funcs = { |
470 | .get_max = byt_get_max_pstate, | 480 | .get_max = byt_get_max_pstate, |
471 | .get_min = byt_get_min_pstate, | 481 | .get_min = byt_get_min_pstate, |
472 | .get_turbo = byt_get_max_pstate, | 482 | .get_turbo = byt_get_turbo_pstate, |
473 | .set = byt_set_pstate, | 483 | .set = byt_set_pstate, |
474 | .get_vid = byt_get_vid, | 484 | .get_vid = byt_get_vid, |
475 | }, | 485 | }, |
@@ -547,18 +557,20 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
547 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 557 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
548 | struct sample *sample) | 558 | struct sample *sample) |
549 | { | 559 | { |
550 | u64 core_pct; | 560 | int32_t core_pct; |
551 | u64 c0_pct; | 561 | int32_t c0_pct; |
552 | 562 | ||
553 | core_pct = div64_u64(sample->aperf * 100, sample->mperf); | 563 | core_pct = div_fp(int_tofp((sample->aperf)), |
564 | int_tofp((sample->mperf))); | ||
565 | core_pct = mul_fp(core_pct, int_tofp(100)); | ||
566 | FP_ROUNDUP(core_pct); | ||
567 | |||
568 | c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc)); | ||
554 | 569 | ||
555 | c0_pct = div64_u64(sample->mperf * 100, sample->tsc); | ||
556 | sample->freq = fp_toint( | 570 | sample->freq = fp_toint( |
557 | mul_fp(int_tofp(cpu->pstate.max_pstate), | 571 | mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); |
558 | int_tofp(core_pct * 1000))); | ||
559 | 572 | ||
560 | sample->core_pct_busy = mul_fp(int_tofp(core_pct), | 573 | sample->core_pct_busy = mul_fp(core_pct, c0_pct); |
561 | div_fp(int_tofp(c0_pct + 1), int_tofp(100))); | ||
562 | } | 574 | } |
563 | 575 | ||
564 | static inline void intel_pstate_sample(struct cpudata *cpu) | 576 | static inline void intel_pstate_sample(struct cpudata *cpu) |
@@ -570,6 +582,10 @@ static inline void intel_pstate_sample(struct cpudata *cpu) | |||
570 | rdmsrl(MSR_IA32_MPERF, mperf); | 582 | rdmsrl(MSR_IA32_MPERF, mperf); |
571 | tsc = native_read_tsc(); | 583 | tsc = native_read_tsc(); |
572 | 584 | ||
585 | aperf = aperf >> FRAC_BITS; | ||
586 | mperf = mperf >> FRAC_BITS; | ||
587 | tsc = tsc >> FRAC_BITS; | ||
588 | |||
573 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 589 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
574 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 590 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
575 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 591 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
@@ -601,7 +617,8 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) | |||
601 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; | 617 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; |
602 | max_pstate = int_tofp(cpu->pstate.max_pstate); | 618 | max_pstate = int_tofp(cpu->pstate.max_pstate); |
603 | current_pstate = int_tofp(cpu->pstate.current_pstate); | 619 | current_pstate = int_tofp(cpu->pstate.current_pstate); |
604 | return mul_fp(core_busy, div_fp(max_pstate, current_pstate)); | 620 | core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); |
621 | return FP_ROUNDUP(core_busy); | ||
605 | } | 622 | } |
606 | 623 | ||
607 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | 624 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index e10b646634d7..6684e0342792 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -1076,7 +1076,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1076 | { | 1076 | { |
1077 | struct powernow_k8_data *data; | 1077 | struct powernow_k8_data *data; |
1078 | struct init_on_cpu init_on_cpu; | 1078 | struct init_on_cpu init_on_cpu; |
1079 | int rc; | 1079 | int rc, cpu; |
1080 | 1080 | ||
1081 | smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); | 1081 | smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); |
1082 | if (rc) | 1082 | if (rc) |
@@ -1140,7 +1140,9 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1140 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1140 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1141 | data->currfid, data->currvid); | 1141 | data->currfid, data->currvid); |
1142 | 1142 | ||
1143 | per_cpu(powernow_data, pol->cpu) = data; | 1143 | /* Point all the CPUs in this policy to the same data */ |
1144 | for_each_cpu(cpu, pol->cpus) | ||
1145 | per_cpu(powernow_data, cpu) = data; | ||
1144 | 1146 | ||
1145 | return 0; | 1147 | return 0; |
1146 | 1148 | ||
@@ -1155,6 +1157,7 @@ err_out: | |||
1155 | static int powernowk8_cpu_exit(struct cpufreq_policy *pol) | 1157 | static int powernowk8_cpu_exit(struct cpufreq_policy *pol) |
1156 | { | 1158 | { |
1157 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1159 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1160 | int cpu; | ||
1158 | 1161 | ||
1159 | if (!data) | 1162 | if (!data) |
1160 | return -EINVAL; | 1163 | return -EINVAL; |
@@ -1165,7 +1168,8 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol) | |||
1165 | 1168 | ||
1166 | kfree(data->powernow_table); | 1169 | kfree(data->powernow_table); |
1167 | kfree(data); | 1170 | kfree(data); |
1168 | per_cpu(powernow_data, pol->cpu) = NULL; | 1171 | for_each_cpu(cpu, pol->cpus) |
1172 | per_cpu(powernow_data, cpu) = NULL; | ||
1169 | 1173 | ||
1170 | return 0; | 1174 | return 0; |
1171 | } | 1175 | } |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 4e7918339b12..19041cefabb1 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -449,6 +449,7 @@ static const struct of_device_id sdma_dt_ids[] = { | |||
449 | { .compatible = "fsl,imx51-sdma", .data = &sdma_imx51, }, | 449 | { .compatible = "fsl,imx51-sdma", .data = &sdma_imx51, }, |
450 | { .compatible = "fsl,imx35-sdma", .data = &sdma_imx35, }, | 450 | { .compatible = "fsl,imx35-sdma", .data = &sdma_imx35, }, |
451 | { .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, }, | 451 | { .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, }, |
452 | { .compatible = "fsl,imx25-sdma", .data = &sdma_imx25, }, | ||
452 | { /* sentinel */ } | 453 | { /* sentinel */ } |
453 | }; | 454 | }; |
454 | MODULE_DEVICE_TABLE(of, sdma_dt_ids); | 455 | MODULE_DEVICE_TABLE(of, sdma_dt_ids); |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 87529181efcc..4e3549a16132 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -77,7 +77,8 @@ static irqreturn_t ioat_dma_do_interrupt(int irq, void *data) | |||
77 | attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET); | 77 | attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET); |
78 | for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) { | 78 | for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) { |
79 | chan = ioat_chan_by_index(instance, bit); | 79 | chan = ioat_chan_by_index(instance, bit); |
80 | tasklet_schedule(&chan->cleanup_task); | 80 | if (test_bit(IOAT_RUN, &chan->state)) |
81 | tasklet_schedule(&chan->cleanup_task); | ||
81 | } | 82 | } |
82 | 83 | ||
83 | writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET); | 84 | writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET); |
@@ -93,7 +94,8 @@ static irqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data) | |||
93 | { | 94 | { |
94 | struct ioat_chan_common *chan = data; | 95 | struct ioat_chan_common *chan = data; |
95 | 96 | ||
96 | tasklet_schedule(&chan->cleanup_task); | 97 | if (test_bit(IOAT_RUN, &chan->state)) |
98 | tasklet_schedule(&chan->cleanup_task); | ||
97 | 99 | ||
98 | return IRQ_HANDLED; | 100 | return IRQ_HANDLED; |
99 | } | 101 | } |
@@ -116,7 +118,6 @@ void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *c | |||
116 | chan->timer.function = device->timer_fn; | 118 | chan->timer.function = device->timer_fn; |
117 | chan->timer.data = data; | 119 | chan->timer.data = data; |
118 | tasklet_init(&chan->cleanup_task, device->cleanup_fn, data); | 120 | tasklet_init(&chan->cleanup_task, device->cleanup_fn, data); |
119 | tasklet_disable(&chan->cleanup_task); | ||
120 | } | 121 | } |
121 | 122 | ||
122 | /** | 123 | /** |
@@ -354,13 +355,49 @@ static int ioat1_dma_alloc_chan_resources(struct dma_chan *c) | |||
354 | writel(((u64) chan->completion_dma) >> 32, | 355 | writel(((u64) chan->completion_dma) >> 32, |
355 | chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); | 356 | chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); |
356 | 357 | ||
357 | tasklet_enable(&chan->cleanup_task); | 358 | set_bit(IOAT_RUN, &chan->state); |
358 | ioat1_dma_start_null_desc(ioat); /* give chain to dma device */ | 359 | ioat1_dma_start_null_desc(ioat); /* give chain to dma device */ |
359 | dev_dbg(to_dev(chan), "%s: allocated %d descriptors\n", | 360 | dev_dbg(to_dev(chan), "%s: allocated %d descriptors\n", |
360 | __func__, ioat->desccount); | 361 | __func__, ioat->desccount); |
361 | return ioat->desccount; | 362 | return ioat->desccount; |
362 | } | 363 | } |
363 | 364 | ||
365 | void ioat_stop(struct ioat_chan_common *chan) | ||
366 | { | ||
367 | struct ioatdma_device *device = chan->device; | ||
368 | struct pci_dev *pdev = device->pdev; | ||
369 | int chan_id = chan_num(chan); | ||
370 | struct msix_entry *msix; | ||
371 | |||
372 | /* 1/ stop irq from firing tasklets | ||
373 | * 2/ stop the tasklet from re-arming irqs | ||
374 | */ | ||
375 | clear_bit(IOAT_RUN, &chan->state); | ||
376 | |||
377 | /* flush inflight interrupts */ | ||
378 | switch (device->irq_mode) { | ||
379 | case IOAT_MSIX: | ||
380 | msix = &device->msix_entries[chan_id]; | ||
381 | synchronize_irq(msix->vector); | ||
382 | break; | ||
383 | case IOAT_MSI: | ||
384 | case IOAT_INTX: | ||
385 | synchronize_irq(pdev->irq); | ||
386 | break; | ||
387 | default: | ||
388 | break; | ||
389 | } | ||
390 | |||
391 | /* flush inflight timers */ | ||
392 | del_timer_sync(&chan->timer); | ||
393 | |||
394 | /* flush inflight tasklet runs */ | ||
395 | tasklet_kill(&chan->cleanup_task); | ||
396 | |||
397 | /* final cleanup now that everything is quiesced and can't re-arm */ | ||
398 | device->cleanup_fn((unsigned long) &chan->common); | ||
399 | } | ||
400 | |||
364 | /** | 401 | /** |
365 | * ioat1_dma_free_chan_resources - release all the descriptors | 402 | * ioat1_dma_free_chan_resources - release all the descriptors |
366 | * @chan: the channel to be cleaned | 403 | * @chan: the channel to be cleaned |
@@ -379,9 +416,7 @@ static void ioat1_dma_free_chan_resources(struct dma_chan *c) | |||
379 | if (ioat->desccount == 0) | 416 | if (ioat->desccount == 0) |
380 | return; | 417 | return; |
381 | 418 | ||
382 | tasklet_disable(&chan->cleanup_task); | 419 | ioat_stop(chan); |
383 | del_timer_sync(&chan->timer); | ||
384 | ioat1_cleanup(ioat); | ||
385 | 420 | ||
386 | /* Delay 100ms after reset to allow internal DMA logic to quiesce | 421 | /* Delay 100ms after reset to allow internal DMA logic to quiesce |
387 | * before removing DMA descriptor resources. | 422 | * before removing DMA descriptor resources. |
@@ -526,8 +561,11 @@ ioat1_dma_prep_memcpy(struct dma_chan *c, dma_addr_t dma_dest, | |||
526 | static void ioat1_cleanup_event(unsigned long data) | 561 | static void ioat1_cleanup_event(unsigned long data) |
527 | { | 562 | { |
528 | struct ioat_dma_chan *ioat = to_ioat_chan((void *) data); | 563 | struct ioat_dma_chan *ioat = to_ioat_chan((void *) data); |
564 | struct ioat_chan_common *chan = &ioat->base; | ||
529 | 565 | ||
530 | ioat1_cleanup(ioat); | 566 | ioat1_cleanup(ioat); |
567 | if (!test_bit(IOAT_RUN, &chan->state)) | ||
568 | return; | ||
531 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); | 569 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); |
532 | } | 570 | } |
533 | 571 | ||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 11fb877ddca9..e982f00a9843 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -356,6 +356,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, | |||
356 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); | 356 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); |
357 | void ioat_kobject_del(struct ioatdma_device *device); | 357 | void ioat_kobject_del(struct ioatdma_device *device); |
358 | int ioat_dma_setup_interrupts(struct ioatdma_device *device); | 358 | int ioat_dma_setup_interrupts(struct ioatdma_device *device); |
359 | void ioat_stop(struct ioat_chan_common *chan); | ||
359 | extern const struct sysfs_ops ioat_sysfs_ops; | 360 | extern const struct sysfs_ops ioat_sysfs_ops; |
360 | extern struct ioat_sysfs_entry ioat_version_attr; | 361 | extern struct ioat_sysfs_entry ioat_version_attr; |
361 | extern struct ioat_sysfs_entry ioat_cap_attr; | 362 | extern struct ioat_sysfs_entry ioat_cap_attr; |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 5d3affe7e976..8d1058085eeb 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -190,8 +190,11 @@ static void ioat2_cleanup(struct ioat2_dma_chan *ioat) | |||
190 | void ioat2_cleanup_event(unsigned long data) | 190 | void ioat2_cleanup_event(unsigned long data) |
191 | { | 191 | { |
192 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); | 192 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); |
193 | struct ioat_chan_common *chan = &ioat->base; | ||
193 | 194 | ||
194 | ioat2_cleanup(ioat); | 195 | ioat2_cleanup(ioat); |
196 | if (!test_bit(IOAT_RUN, &chan->state)) | ||
197 | return; | ||
195 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); | 198 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); |
196 | } | 199 | } |
197 | 200 | ||
@@ -553,10 +556,10 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
553 | ioat->issued = 0; | 556 | ioat->issued = 0; |
554 | ioat->tail = 0; | 557 | ioat->tail = 0; |
555 | ioat->alloc_order = order; | 558 | ioat->alloc_order = order; |
559 | set_bit(IOAT_RUN, &chan->state); | ||
556 | spin_unlock_bh(&ioat->prep_lock); | 560 | spin_unlock_bh(&ioat->prep_lock); |
557 | spin_unlock_bh(&chan->cleanup_lock); | 561 | spin_unlock_bh(&chan->cleanup_lock); |
558 | 562 | ||
559 | tasklet_enable(&chan->cleanup_task); | ||
560 | ioat2_start_null_desc(ioat); | 563 | ioat2_start_null_desc(ioat); |
561 | 564 | ||
562 | /* check that we got off the ground */ | 565 | /* check that we got off the ground */ |
@@ -566,7 +569,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
566 | } while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status)); | 569 | } while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status)); |
567 | 570 | ||
568 | if (is_ioat_active(status) || is_ioat_idle(status)) { | 571 | if (is_ioat_active(status) || is_ioat_idle(status)) { |
569 | set_bit(IOAT_RUN, &chan->state); | ||
570 | return 1 << ioat->alloc_order; | 572 | return 1 << ioat->alloc_order; |
571 | } else { | 573 | } else { |
572 | u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 574 | u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
@@ -809,11 +811,8 @@ void ioat2_free_chan_resources(struct dma_chan *c) | |||
809 | if (!ioat->ring) | 811 | if (!ioat->ring) |
810 | return; | 812 | return; |
811 | 813 | ||
812 | tasklet_disable(&chan->cleanup_task); | 814 | ioat_stop(chan); |
813 | del_timer_sync(&chan->timer); | ||
814 | device->cleanup_fn((unsigned long) c); | ||
815 | device->reset_hw(chan); | 815 | device->reset_hw(chan); |
816 | clear_bit(IOAT_RUN, &chan->state); | ||
817 | 816 | ||
818 | spin_lock_bh(&chan->cleanup_lock); | 817 | spin_lock_bh(&chan->cleanup_lock); |
819 | spin_lock_bh(&ioat->prep_lock); | 818 | spin_lock_bh(&ioat->prep_lock); |
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 820817e97e62..b9b38a1cf92f 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -464,8 +464,11 @@ static void ioat3_cleanup(struct ioat2_dma_chan *ioat) | |||
464 | static void ioat3_cleanup_event(unsigned long data) | 464 | static void ioat3_cleanup_event(unsigned long data) |
465 | { | 465 | { |
466 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); | 466 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); |
467 | struct ioat_chan_common *chan = &ioat->base; | ||
467 | 468 | ||
468 | ioat3_cleanup(ioat); | 469 | ioat3_cleanup(ioat); |
470 | if (!test_bit(IOAT_RUN, &chan->state)) | ||
471 | return; | ||
469 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); | 472 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); |
470 | } | 473 | } |
471 | 474 | ||
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 00a2de957b23..bf18c786ed40 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -1641,6 +1641,7 @@ static void dma_tasklet(unsigned long data) | |||
1641 | struct d40_chan *d40c = (struct d40_chan *) data; | 1641 | struct d40_chan *d40c = (struct d40_chan *) data; |
1642 | struct d40_desc *d40d; | 1642 | struct d40_desc *d40d; |
1643 | unsigned long flags; | 1643 | unsigned long flags; |
1644 | bool callback_active; | ||
1644 | dma_async_tx_callback callback; | 1645 | dma_async_tx_callback callback; |
1645 | void *callback_param; | 1646 | void *callback_param; |
1646 | 1647 | ||
@@ -1668,6 +1669,7 @@ static void dma_tasklet(unsigned long data) | |||
1668 | } | 1669 | } |
1669 | 1670 | ||
1670 | /* Callback to client */ | 1671 | /* Callback to client */ |
1672 | callback_active = !!(d40d->txd.flags & DMA_PREP_INTERRUPT); | ||
1671 | callback = d40d->txd.callback; | 1673 | callback = d40d->txd.callback; |
1672 | callback_param = d40d->txd.callback_param; | 1674 | callback_param = d40d->txd.callback_param; |
1673 | 1675 | ||
@@ -1690,7 +1692,7 @@ static void dma_tasklet(unsigned long data) | |||
1690 | 1692 | ||
1691 | spin_unlock_irqrestore(&d40c->lock, flags); | 1693 | spin_unlock_irqrestore(&d40c->lock, flags); |
1692 | 1694 | ||
1693 | if (callback && (d40d->txd.flags & DMA_PREP_INTERRUPT)) | 1695 | if (callback_active && callback) |
1694 | callback(callback_param); | 1696 | callback(callback_param); |
1695 | 1697 | ||
1696 | return; | 1698 | return; |
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index d63f4798f7d0..57e96a3350f0 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
@@ -943,33 +943,35 @@ static int i7300_get_devices(struct mem_ctl_info *mci) | |||
943 | 943 | ||
944 | /* Attempt to 'get' the MCH register we want */ | 944 | /* Attempt to 'get' the MCH register we want */ |
945 | pdev = NULL; | 945 | pdev = NULL; |
946 | while (!pvt->pci_dev_16_1_fsb_addr_map || | 946 | while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
947 | !pvt->pci_dev_16_2_fsb_err_regs) { | 947 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, |
948 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 948 | pdev))) { |
949 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev); | ||
950 | if (!pdev) { | ||
951 | /* End of list, leave */ | ||
952 | i7300_printk(KERN_ERR, | ||
953 | "'system address,Process Bus' " | ||
954 | "device not found:" | ||
955 | "vendor 0x%x device 0x%x ERR funcs " | ||
956 | "(broken BIOS?)\n", | ||
957 | PCI_VENDOR_ID_INTEL, | ||
958 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); | ||
959 | goto error; | ||
960 | } | ||
961 | |||
962 | /* Store device 16 funcs 1 and 2 */ | 949 | /* Store device 16 funcs 1 and 2 */ |
963 | switch (PCI_FUNC(pdev->devfn)) { | 950 | switch (PCI_FUNC(pdev->devfn)) { |
964 | case 1: | 951 | case 1: |
965 | pvt->pci_dev_16_1_fsb_addr_map = pdev; | 952 | if (!pvt->pci_dev_16_1_fsb_addr_map) |
953 | pvt->pci_dev_16_1_fsb_addr_map = | ||
954 | pci_dev_get(pdev); | ||
966 | break; | 955 | break; |
967 | case 2: | 956 | case 2: |
968 | pvt->pci_dev_16_2_fsb_err_regs = pdev; | 957 | if (!pvt->pci_dev_16_2_fsb_err_regs) |
958 | pvt->pci_dev_16_2_fsb_err_regs = | ||
959 | pci_dev_get(pdev); | ||
969 | break; | 960 | break; |
970 | } | 961 | } |
971 | } | 962 | } |
972 | 963 | ||
964 | if (!pvt->pci_dev_16_1_fsb_addr_map || | ||
965 | !pvt->pci_dev_16_2_fsb_err_regs) { | ||
966 | /* At least one device was not found */ | ||
967 | i7300_printk(KERN_ERR, | ||
968 | "'system address,Process Bus' device not found:" | ||
969 | "vendor 0x%x device 0x%x ERR funcs (broken BIOS?)\n", | ||
970 | PCI_VENDOR_ID_INTEL, | ||
971 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); | ||
972 | goto error; | ||
973 | } | ||
974 | |||
973 | edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", | 975 | edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", |
974 | pci_name(pvt->pci_dev_16_0_fsb_ctlr), | 976 | pci_name(pvt->pci_dev_16_0_fsb_ctlr), |
975 | pvt->pci_dev_16_0_fsb_ctlr->vendor, | 977 | pvt->pci_dev_16_0_fsb_ctlr->vendor, |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 87533ca7752e..d871275196f6 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1334,14 +1334,19 @@ static int i7core_get_onedevice(struct pci_dev **prev, | |||
1334 | * is at addr 8086:2c40, instead of 8086:2c41. So, we need | 1334 | * is at addr 8086:2c40, instead of 8086:2c41. So, we need |
1335 | * to probe for the alternate address in case of failure | 1335 | * to probe for the alternate address in case of failure |
1336 | */ | 1336 | */ |
1337 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) | 1337 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) { |
1338 | pci_dev_get(*prev); /* pci_get_device will put it */ | ||
1338 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1339 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1339 | PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); | 1340 | PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); |
1341 | } | ||
1340 | 1342 | ||
1341 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) | 1343 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && |
1344 | !pdev) { | ||
1345 | pci_dev_get(*prev); /* pci_get_device will put it */ | ||
1342 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1346 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1343 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, | 1347 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, |
1344 | *prev); | 1348 | *prev); |
1349 | } | ||
1345 | 1350 | ||
1346 | if (!pdev) { | 1351 | if (!pdev) { |
1347 | if (*prev) { | 1352 | if (*prev) { |
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index c20602f601ee..98a14f6143a7 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -222,27 +222,19 @@ static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info) | |||
222 | struct snd_soc_dapm_context *dapm = arizona->dapm; | 222 | struct snd_soc_dapm_context *dapm = arizona->dapm; |
223 | int ret; | 223 | int ret; |
224 | 224 | ||
225 | mutex_lock(&dapm->card->dapm_mutex); | ||
226 | |||
227 | ret = snd_soc_dapm_force_enable_pin(dapm, widget); | 225 | ret = snd_soc_dapm_force_enable_pin(dapm, widget); |
228 | if (ret != 0) | 226 | if (ret != 0) |
229 | dev_warn(arizona->dev, "Failed to enable %s: %d\n", | 227 | dev_warn(arizona->dev, "Failed to enable %s: %d\n", |
230 | widget, ret); | 228 | widget, ret); |
231 | 229 | ||
232 | mutex_unlock(&dapm->card->dapm_mutex); | ||
233 | |||
234 | snd_soc_dapm_sync(dapm); | 230 | snd_soc_dapm_sync(dapm); |
235 | 231 | ||
236 | if (!arizona->pdata.micd_force_micbias) { | 232 | if (!arizona->pdata.micd_force_micbias) { |
237 | mutex_lock(&dapm->card->dapm_mutex); | ||
238 | |||
239 | ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); | 233 | ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); |
240 | if (ret != 0) | 234 | if (ret != 0) |
241 | dev_warn(arizona->dev, "Failed to disable %s: %d\n", | 235 | dev_warn(arizona->dev, "Failed to disable %s: %d\n", |
242 | widget, ret); | 236 | widget, ret); |
243 | 237 | ||
244 | mutex_unlock(&dapm->card->dapm_mutex); | ||
245 | |||
246 | snd_soc_dapm_sync(dapm); | 238 | snd_soc_dapm_sync(dapm); |
247 | } | 239 | } |
248 | } | 240 | } |
@@ -304,16 +296,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info) | |||
304 | ARIZONA_MICD_ENA, 0, | 296 | ARIZONA_MICD_ENA, 0, |
305 | &change); | 297 | &change); |
306 | 298 | ||
307 | mutex_lock(&dapm->card->dapm_mutex); | ||
308 | |||
309 | ret = snd_soc_dapm_disable_pin(dapm, widget); | 299 | ret = snd_soc_dapm_disable_pin(dapm, widget); |
310 | if (ret != 0) | 300 | if (ret != 0) |
311 | dev_warn(arizona->dev, | 301 | dev_warn(arizona->dev, |
312 | "Failed to disable %s: %d\n", | 302 | "Failed to disable %s: %d\n", |
313 | widget, ret); | 303 | widget, ret); |
314 | 304 | ||
315 | mutex_unlock(&dapm->card->dapm_mutex); | ||
316 | |||
317 | snd_soc_dapm_sync(dapm); | 305 | snd_soc_dapm_sync(dapm); |
318 | 306 | ||
319 | if (info->micd_reva) { | 307 | if (info->micd_reva) { |
diff --git a/drivers/fmc/fmc-write-eeprom.c b/drivers/fmc/fmc-write-eeprom.c index ee5b47904130..9bb2cbd5c9f2 100644 --- a/drivers/fmc/fmc-write-eeprom.c +++ b/drivers/fmc/fmc-write-eeprom.c | |||
@@ -27,7 +27,7 @@ FMC_PARAM_BUSID(fwe_drv); | |||
27 | /* The "file=" is like the generic "gateware=" used elsewhere */ | 27 | /* The "file=" is like the generic "gateware=" used elsewhere */ |
28 | static char *fwe_file[FMC_MAX_CARDS]; | 28 | static char *fwe_file[FMC_MAX_CARDS]; |
29 | static int fwe_file_n; | 29 | static int fwe_file_n; |
30 | module_param_array_named(file, fwe_file, charp, &fwe_file_n, 444); | 30 | module_param_array_named(file, fwe_file, charp, &fwe_file_n, 0444); |
31 | 31 | ||
32 | static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw, | 32 | static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw, |
33 | int write) | 33 | int write) |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index dffc836144cc..f4dc9b7a3831 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -296,6 +296,18 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
296 | case DRM_CAP_ASYNC_PAGE_FLIP: | 296 | case DRM_CAP_ASYNC_PAGE_FLIP: |
297 | req->value = dev->mode_config.async_page_flip; | 297 | req->value = dev->mode_config.async_page_flip; |
298 | break; | 298 | break; |
299 | case DRM_CAP_CURSOR_WIDTH: | ||
300 | if (dev->mode_config.cursor_width) | ||
301 | req->value = dev->mode_config.cursor_width; | ||
302 | else | ||
303 | req->value = 64; | ||
304 | break; | ||
305 | case DRM_CAP_CURSOR_HEIGHT: | ||
306 | if (dev->mode_config.cursor_height) | ||
307 | req->value = dev->mode_config.cursor_height; | ||
308 | else | ||
309 | req->value = 64; | ||
310 | break; | ||
299 | default: | 311 | default: |
300 | return -EINVAL; | 312 | return -EINVAL; |
301 | } | 313 | } |
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index fa18cf374470..faa77f543a07 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -1151,8 +1151,10 @@ tda998x_encoder_init(struct i2c_client *client, | |||
1151 | 1151 | ||
1152 | priv->current_page = 0xff; | 1152 | priv->current_page = 0xff; |
1153 | priv->cec = i2c_new_dummy(client->adapter, 0x34); | 1153 | priv->cec = i2c_new_dummy(client->adapter, 0x34); |
1154 | if (!priv->cec) | 1154 | if (!priv->cec) { |
1155 | kfree(priv); | ||
1155 | return -ENODEV; | 1156 | return -ENODEV; |
1157 | } | ||
1156 | priv->dpms = DRM_MODE_DPMS_OFF; | 1158 | priv->dpms = DRM_MODE_DPMS_OFF; |
1157 | 1159 | ||
1158 | encoder_slave->slave_priv = priv; | 1160 | encoder_slave->slave_priv = priv; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9fa24347963a..4c1672809493 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -8586,6 +8586,20 @@ static int intel_gen7_queue_flip(struct drm_device *dev, | |||
8586 | if (ring->id == RCS) | 8586 | if (ring->id == RCS) |
8587 | len += 6; | 8587 | len += 6; |
8588 | 8588 | ||
8589 | /* | ||
8590 | * BSpec MI_DISPLAY_FLIP for IVB: | ||
8591 | * "The full packet must be contained within the same cache line." | ||
8592 | * | ||
8593 | * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same | ||
8594 | * cacheline, if we ever start emitting more commands before | ||
8595 | * the MI_DISPLAY_FLIP we may need to first emit everything else, | ||
8596 | * then do the cacheline alignment, and finally emit the | ||
8597 | * MI_DISPLAY_FLIP. | ||
8598 | */ | ||
8599 | ret = intel_ring_cacheline_align(ring); | ||
8600 | if (ret) | ||
8601 | goto err_unpin; | ||
8602 | |||
8589 | ret = intel_ring_begin(ring, len); | 8603 | ret = intel_ring_begin(ring, len); |
8590 | if (ret) | 8604 | if (ret) |
8591 | goto err_unpin; | 8605 | goto err_unpin; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2f517b85b3f4..57552eb386b0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -537,6 +537,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp, | |||
537 | uint8_t msg[20]; | 537 | uint8_t msg[20]; |
538 | int msg_bytes; | 538 | int msg_bytes; |
539 | uint8_t ack; | 539 | uint8_t ack; |
540 | int retry; | ||
540 | 541 | ||
541 | if (WARN_ON(send_bytes > 16)) | 542 | if (WARN_ON(send_bytes > 16)) |
542 | return -E2BIG; | 543 | return -E2BIG; |
@@ -548,19 +549,21 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp, | |||
548 | msg[3] = send_bytes - 1; | 549 | msg[3] = send_bytes - 1; |
549 | memcpy(&msg[4], send, send_bytes); | 550 | memcpy(&msg[4], send, send_bytes); |
550 | msg_bytes = send_bytes + 4; | 551 | msg_bytes = send_bytes + 4; |
551 | for (;;) { | 552 | for (retry = 0; retry < 7; retry++) { |
552 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); | 553 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
553 | if (ret < 0) | 554 | if (ret < 0) |
554 | return ret; | 555 | return ret; |
555 | ack >>= 4; | 556 | ack >>= 4; |
556 | if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) | 557 | if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) |
557 | break; | 558 | return send_bytes; |
558 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) | 559 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) |
559 | udelay(100); | 560 | usleep_range(400, 500); |
560 | else | 561 | else |
561 | return -EIO; | 562 | return -EIO; |
562 | } | 563 | } |
563 | return send_bytes; | 564 | |
565 | DRM_ERROR("too many retries, giving up\n"); | ||
566 | return -EIO; | ||
564 | } | 567 | } |
565 | 568 | ||
566 | /* Write a single byte to the aux channel in native mode */ | 569 | /* Write a single byte to the aux channel in native mode */ |
@@ -582,6 +585,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
582 | int reply_bytes; | 585 | int reply_bytes; |
583 | uint8_t ack; | 586 | uint8_t ack; |
584 | int ret; | 587 | int ret; |
588 | int retry; | ||
585 | 589 | ||
586 | if (WARN_ON(recv_bytes > 19)) | 590 | if (WARN_ON(recv_bytes > 19)) |
587 | return -E2BIG; | 591 | return -E2BIG; |
@@ -595,7 +599,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
595 | msg_bytes = 4; | 599 | msg_bytes = 4; |
596 | reply_bytes = recv_bytes + 1; | 600 | reply_bytes = recv_bytes + 1; |
597 | 601 | ||
598 | for (;;) { | 602 | for (retry = 0; retry < 7; retry++) { |
599 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, | 603 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
600 | reply, reply_bytes); | 604 | reply, reply_bytes); |
601 | if (ret == 0) | 605 | if (ret == 0) |
@@ -608,10 +612,13 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
608 | return ret - 1; | 612 | return ret - 1; |
609 | } | 613 | } |
610 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) | 614 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) |
611 | udelay(100); | 615 | usleep_range(400, 500); |
612 | else | 616 | else |
613 | return -EIO; | 617 | return -EIO; |
614 | } | 618 | } |
619 | |||
620 | DRM_ERROR("too many retries, giving up\n"); | ||
621 | return -EIO; | ||
615 | } | 622 | } |
616 | 623 | ||
617 | static int | 624 | static int |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b7f1742caf87..31b36c5ac894 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -1653,6 +1653,27 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
1653 | return 0; | 1653 | return 0; |
1654 | } | 1654 | } |
1655 | 1655 | ||
1656 | /* Align the ring tail to a cacheline boundary */ | ||
1657 | int intel_ring_cacheline_align(struct intel_ring_buffer *ring) | ||
1658 | { | ||
1659 | int num_dwords = (64 - (ring->tail & 63)) / sizeof(uint32_t); | ||
1660 | int ret; | ||
1661 | |||
1662 | if (num_dwords == 0) | ||
1663 | return 0; | ||
1664 | |||
1665 | ret = intel_ring_begin(ring, num_dwords); | ||
1666 | if (ret) | ||
1667 | return ret; | ||
1668 | |||
1669 | while (num_dwords--) | ||
1670 | intel_ring_emit(ring, MI_NOOP); | ||
1671 | |||
1672 | intel_ring_advance(ring); | ||
1673 | |||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1656 | void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) | 1677 | void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) |
1657 | { | 1678 | { |
1658 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 1679 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 71a73f4fe252..0b243ce33714 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -233,6 +233,7 @@ intel_write_status_page(struct intel_ring_buffer *ring, | |||
233 | void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); | 233 | void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); |
234 | 234 | ||
235 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); | 235 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); |
236 | int __must_check intel_ring_cacheline_align(struct intel_ring_buffer *ring); | ||
236 | static inline void intel_ring_emit(struct intel_ring_buffer *ring, | 237 | static inline void intel_ring_emit(struct intel_ring_buffer *ring, |
237 | u32 data) | 238 | u32 data) |
238 | { | 239 | { |
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e88145ba1bf5..d310c195bdfe 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -141,6 +141,7 @@ nouveau-y += core/subdev/mc/base.o | |||
141 | nouveau-y += core/subdev/mc/nv04.o | 141 | nouveau-y += core/subdev/mc/nv04.o |
142 | nouveau-y += core/subdev/mc/nv40.o | 142 | nouveau-y += core/subdev/mc/nv40.o |
143 | nouveau-y += core/subdev/mc/nv44.o | 143 | nouveau-y += core/subdev/mc/nv44.o |
144 | nouveau-y += core/subdev/mc/nv4c.o | ||
144 | nouveau-y += core/subdev/mc/nv50.o | 145 | nouveau-y += core/subdev/mc/nv50.o |
145 | nouveau-y += core/subdev/mc/nv94.o | 146 | nouveau-y += core/subdev/mc/nv94.o |
146 | nouveau-y += core/subdev/mc/nv98.o | 147 | nouveau-y += core/subdev/mc/nv98.o |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index 1b653dd74a70..08b88591ed60 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c | |||
@@ -311,7 +311,7 @@ nv40_identify(struct nouveau_device *device) | |||
311 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 311 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
312 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 312 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
313 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 313 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
314 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 314 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
315 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 315 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
316 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 316 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
317 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 317 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
@@ -334,7 +334,7 @@ nv40_identify(struct nouveau_device *device) | |||
334 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 334 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
335 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 335 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
336 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 336 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
337 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 337 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
338 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 338 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
339 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 339 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
340 | device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass; | 340 | device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass; |
@@ -357,7 +357,7 @@ nv40_identify(struct nouveau_device *device) | |||
357 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 357 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
358 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 358 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
359 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 359 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
360 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 360 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
361 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 361 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
362 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 362 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
363 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 363 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
@@ -380,7 +380,7 @@ nv40_identify(struct nouveau_device *device) | |||
380 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 380 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
381 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 381 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
382 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 382 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
383 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 383 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
384 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 384 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
385 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 385 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
386 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 386 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
@@ -403,7 +403,7 @@ nv40_identify(struct nouveau_device *device) | |||
403 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 403 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
404 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 404 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
405 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 405 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
406 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 406 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
407 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 407 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
408 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 408 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
409 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 409 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 940eaa5d8b9a..9ad722e4e087 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -1142,7 +1142,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) | |||
1142 | if (conf != ~0) { | 1142 | if (conf != ~0) { |
1143 | if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { | 1143 | if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { |
1144 | u32 soff = (ffs(outp.or) - 1) * 0x08; | 1144 | u32 soff = (ffs(outp.or) - 1) * 0x08; |
1145 | u32 ctrl = nv_rd32(priv, 0x610798 + soff); | 1145 | u32 ctrl = nv_rd32(priv, 0x610794 + soff); |
1146 | u32 datarate; | 1146 | u32 datarate; |
1147 | 1147 | ||
1148 | switch ((ctrl & 0x000f0000) >> 16) { | 1148 | switch ((ctrl & 0x000f0000) >> 16) { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 9a850fe19515..54c1b5b471cd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | |||
@@ -112,7 +112,7 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine) | |||
112 | 112 | ||
113 | nv_wr32(priv, 0x002270, cur->addr >> 12); | 113 | nv_wr32(priv, 0x002270, cur->addr >> 12); |
114 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); | 114 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); |
115 | if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) | 115 | if (!nv_wait(priv, 0x002284 + (engine * 8), 0x00100000, 0x00000000)) |
116 | nv_error(priv, "runlist %d update timeout\n", engine); | 116 | nv_error(priv, "runlist %d update timeout\n", engine); |
117 | mutex_unlock(&nv_subdev(priv)->mutex); | 117 | mutex_unlock(&nv_subdev(priv)->mutex); |
118 | } | 118 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index 30ed19c52e05..7a367c402978 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c | |||
@@ -539,7 +539,7 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, | |||
539 | ustatus &= ~0x04030000; | 539 | ustatus &= ~0x04030000; |
540 | } | 540 | } |
541 | if (ustatus && display) { | 541 | if (ustatus && display) { |
542 | nv_error("%s - TP%d:", name, i); | 542 | nv_error(priv, "%s - TP%d:", name, i); |
543 | nouveau_bitfield_print(nv50_mpc_traps, ustatus); | 543 | nouveau_bitfield_print(nv50_mpc_traps, ustatus); |
544 | pr_cont("\n"); | 544 | pr_cont("\n"); |
545 | ustatus = 0; | 545 | ustatus = 0; |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h index adc88b73d911..3c6738edd127 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h | |||
@@ -47,6 +47,7 @@ struct nouveau_mc_oclass { | |||
47 | extern struct nouveau_oclass *nv04_mc_oclass; | 47 | extern struct nouveau_oclass *nv04_mc_oclass; |
48 | extern struct nouveau_oclass *nv40_mc_oclass; | 48 | extern struct nouveau_oclass *nv40_mc_oclass; |
49 | extern struct nouveau_oclass *nv44_mc_oclass; | 49 | extern struct nouveau_oclass *nv44_mc_oclass; |
50 | extern struct nouveau_oclass *nv4c_mc_oclass; | ||
50 | extern struct nouveau_oclass *nv50_mc_oclass; | 51 | extern struct nouveau_oclass *nv50_mc_oclass; |
51 | extern struct nouveau_oclass *nv94_mc_oclass; | 52 | extern struct nouveau_oclass *nv94_mc_oclass; |
52 | extern struct nouveau_oclass *nv98_mc_oclass; | 53 | extern struct nouveau_oclass *nv98_mc_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index aa0fbbec7f08..ef0c9c4a8cc3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c | |||
@@ -130,6 +130,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) | |||
130 | u16 pcir; | 130 | u16 pcir; |
131 | int i; | 131 | int i; |
132 | 132 | ||
133 | /* there is no prom on nv4x IGP's */ | ||
134 | if (device->card_type == NV_40 && device->chipset >= 0x4c) | ||
135 | return; | ||
136 | |||
133 | /* enable access to rom */ | 137 | /* enable access to rom */ |
134 | if (device->card_type >= NV_50) | 138 | if (device->card_type >= NV_50) |
135 | pcireg = 0x088050; | 139 | pcireg = 0x088050; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c index 9159a5ccee93..265d1253624a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c | |||
@@ -36,7 +36,7 @@ nv1a_fb_oclass = &(struct nv04_fb_impl) { | |||
36 | .fini = _nouveau_fb_fini, | 36 | .fini = _nouveau_fb_fini, |
37 | }, | 37 | }, |
38 | .base.memtype = nv04_fb_memtype_valid, | 38 | .base.memtype = nv04_fb_memtype_valid, |
39 | .base.ram = &nv10_ram_oclass, | 39 | .base.ram = &nv1a_ram_oclass, |
40 | .tile.regions = 8, | 40 | .tile.regions = 8, |
41 | .tile.init = nv10_fb_tile_init, | 41 | .tile.init = nv10_fb_tile_init, |
42 | .tile.fini = nv10_fb_tile_fini, | 42 | .tile.fini = nv10_fb_tile_fini, |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h index b0d5c31606c1..81a408e7d034 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h | |||
@@ -14,6 +14,7 @@ int nv04_mc_ctor(struct nouveau_object *, struct nouveau_object *, | |||
14 | extern const struct nouveau_mc_intr nv04_mc_intr[]; | 14 | extern const struct nouveau_mc_intr nv04_mc_intr[]; |
15 | int nv04_mc_init(struct nouveau_object *); | 15 | int nv04_mc_init(struct nouveau_object *); |
16 | void nv40_mc_msi_rearm(struct nouveau_mc *); | 16 | void nv40_mc_msi_rearm(struct nouveau_mc *); |
17 | int nv44_mc_init(struct nouveau_object *object); | ||
17 | int nv50_mc_init(struct nouveau_object *); | 18 | int nv50_mc_init(struct nouveau_object *); |
18 | extern const struct nouveau_mc_intr nv50_mc_intr[]; | 19 | extern const struct nouveau_mc_intr nv50_mc_intr[]; |
19 | extern const struct nouveau_mc_intr nvc0_mc_intr[]; | 20 | extern const struct nouveau_mc_intr nvc0_mc_intr[]; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c index 3bfee5c6c4f2..cc4d0d2d886e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "nv04.h" | 25 | #include "nv04.h" |
26 | 26 | ||
27 | static int | 27 | int |
28 | nv44_mc_init(struct nouveau_object *object) | 28 | nv44_mc_init(struct nouveau_object *object) |
29 | { | 29 | { |
30 | struct nv04_mc_priv *priv = (void *)object; | 30 | struct nv04_mc_priv *priv = (void *)object; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c new file mode 100644 index 000000000000..a75c35ccf25c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Ilia Mirkin | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ilia Mirkin | ||
23 | */ | ||
24 | |||
25 | #include "nv04.h" | ||
26 | |||
27 | static void | ||
28 | nv4c_mc_msi_rearm(struct nouveau_mc *pmc) | ||
29 | { | ||
30 | struct nv04_mc_priv *priv = (void *)pmc; | ||
31 | nv_wr08(priv, 0x088050, 0xff); | ||
32 | } | ||
33 | |||
34 | struct nouveau_oclass * | ||
35 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { | ||
36 | .base.handle = NV_SUBDEV(MC, 0x4c), | ||
37 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
38 | .ctor = nv04_mc_ctor, | ||
39 | .dtor = _nouveau_mc_dtor, | ||
40 | .init = nv44_mc_init, | ||
41 | .fini = _nouveau_mc_fini, | ||
42 | }, | ||
43 | .intr = nv04_mc_intr, | ||
44 | .msi_rearm = nv4c_mc_msi_rearm, | ||
45 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 4ef83df2b246..83face3f608f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -106,6 +106,29 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * | |||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | /* | ||
110 | * On some platforms, _DSM(nouveau_op_dsm_muid, func0) has special | ||
111 | * requirements on the fourth parameter, so a private implementation | ||
112 | * instead of using acpi_check_dsm(). | ||
113 | */ | ||
114 | static int nouveau_check_optimus_dsm(acpi_handle handle) | ||
115 | { | ||
116 | int result; | ||
117 | |||
118 | /* | ||
119 | * Function 0 returns a Buffer containing available functions. | ||
120 | * The args parameter is ignored for function 0, so just put 0 in it | ||
121 | */ | ||
122 | if (nouveau_optimus_dsm(handle, 0, 0, &result)) | ||
123 | return 0; | ||
124 | |||
125 | /* | ||
126 | * ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. | ||
127 | * If the n-th bit is enabled, function n is supported | ||
128 | */ | ||
129 | return result & 1 && result & (1 << NOUVEAU_DSM_OPTIMUS_CAPS); | ||
130 | } | ||
131 | |||
109 | static int nouveau_dsm(acpi_handle handle, int func, int arg) | 132 | static int nouveau_dsm(acpi_handle handle, int func, int arg) |
110 | { | 133 | { |
111 | int ret = 0; | 134 | int ret = 0; |
@@ -207,8 +230,7 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
207 | 1 << NOUVEAU_DSM_POWER)) | 230 | 1 << NOUVEAU_DSM_POWER)) |
208 | retval |= NOUVEAU_DSM_HAS_MUX; | 231 | retval |= NOUVEAU_DSM_HAS_MUX; |
209 | 232 | ||
210 | if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100, | 233 | if (nouveau_check_optimus_dsm(dhandle)) |
211 | 1 << NOUVEAU_DSM_OPTIMUS_CAPS)) | ||
212 | retval |= NOUVEAU_DSM_HAS_OPT; | 234 | retval |= NOUVEAU_DSM_HAS_OPT; |
213 | 235 | ||
214 | if (retval & NOUVEAU_DSM_HAS_OPT) { | 236 | if (retval & NOUVEAU_DSM_HAS_OPT) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 488686d490c0..4aed1714b9ab 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -1249,7 +1249,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | |||
1249 | mem->bus.is_iomem = !dev->agp->cant_use_aperture; | 1249 | mem->bus.is_iomem = !dev->agp->cant_use_aperture; |
1250 | } | 1250 | } |
1251 | #endif | 1251 | #endif |
1252 | if (!node->memtype) | 1252 | if (nv_device(drm->device)->card_type < NV_50 || !node->memtype) |
1253 | /* untiled */ | 1253 | /* untiled */ |
1254 | break; | 1254 | break; |
1255 | /* fallthrough, tiled memory */ | 1255 | /* fallthrough, tiled memory */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 78c8e7146d56..89c484d8ac26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -376,6 +376,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) | |||
376 | if (ret) | 376 | if (ret) |
377 | goto fail_device; | 377 | goto fail_device; |
378 | 378 | ||
379 | dev->irq_enabled = true; | ||
380 | |||
379 | /* workaround an odd issue on nvc1 by disabling the device's | 381 | /* workaround an odd issue on nvc1 by disabling the device's |
380 | * nosnoop capability. hopefully won't cause issues until a | 382 | * nosnoop capability. hopefully won't cause issues until a |
381 | * better fix is found - assuming there is one... | 383 | * better fix is found - assuming there is one... |
@@ -475,6 +477,7 @@ nouveau_drm_remove(struct pci_dev *pdev) | |||
475 | struct nouveau_drm *drm = nouveau_drm(dev); | 477 | struct nouveau_drm *drm = nouveau_drm(dev); |
476 | struct nouveau_object *device; | 478 | struct nouveau_object *device; |
477 | 479 | ||
480 | dev->irq_enabled = false; | ||
478 | device = drm->client.base.device; | 481 | device = drm->client.base.device; |
479 | drm_put_dev(dev); | 482 | drm_put_dev(dev); |
480 | 483 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index 81638d7f2eff..471347edc27e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c | |||
@@ -14,7 +14,9 @@ nouveau_vga_set_decode(void *priv, bool state) | |||
14 | { | 14 | { |
15 | struct nouveau_device *device = nouveau_dev(priv); | 15 | struct nouveau_device *device = nouveau_dev(priv); |
16 | 16 | ||
17 | if (device->chipset >= 0x40) | 17 | if (device->card_type == NV_40 && device->chipset >= 0x4c) |
18 | nv_wr32(device, 0x088060, state); | ||
19 | else if (device->chipset >= 0x40) | ||
18 | nv_wr32(device, 0x088054, state); | 20 | nv_wr32(device, 0x088054, state); |
19 | else | 21 | else |
20 | nv_wr32(device, 0x001854, state); | 22 | nv_wr32(device, 0x001854, state); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a9338c85630f..daa4dd375ab1 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -559,7 +559,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
559 | u32 adjusted_clock = mode->clock; | 559 | u32 adjusted_clock = mode->clock; |
560 | int encoder_mode = atombios_get_encoder_mode(encoder); | 560 | int encoder_mode = atombios_get_encoder_mode(encoder); |
561 | u32 dp_clock = mode->clock; | 561 | u32 dp_clock = mode->clock; |
562 | int bpc = radeon_get_monitor_bpc(connector); | 562 | int bpc = radeon_crtc->bpc; |
563 | bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | 563 | bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); |
564 | 564 | ||
565 | /* reset the pll flags */ | 565 | /* reset the pll flags */ |
@@ -1176,7 +1176,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1176 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); | 1176 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); |
1177 | 1177 | ||
1178 | /* Set NUM_BANKS. */ | 1178 | /* Set NUM_BANKS. */ |
1179 | if (rdev->family >= CHIP_BONAIRE) { | 1179 | if (rdev->family >= CHIP_TAHITI) { |
1180 | unsigned tileb, index, num_banks, tile_split_bytes; | 1180 | unsigned tileb, index, num_banks, tile_split_bytes; |
1181 | 1181 | ||
1182 | /* Calculate the macrotile mode index. */ | 1182 | /* Calculate the macrotile mode index. */ |
@@ -1194,13 +1194,14 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1194 | return -EINVAL; | 1194 | return -EINVAL; |
1195 | } | 1195 | } |
1196 | 1196 | ||
1197 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; | 1197 | if (rdev->family >= CHIP_BONAIRE) |
1198 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; | ||
1199 | else | ||
1200 | num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3; | ||
1198 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); | 1201 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); |
1199 | } else { | 1202 | } else { |
1200 | /* SI and older. */ | 1203 | /* NI and older. */ |
1201 | if (rdev->family >= CHIP_TAHITI) | 1204 | if (rdev->family >= CHIP_CAYMAN) |
1202 | tmp = rdev->config.si.tile_config; | ||
1203 | else if (rdev->family >= CHIP_CAYMAN) | ||
1204 | tmp = rdev->config.cayman.tile_config; | 1205 | tmp = rdev->config.cayman.tile_config; |
1205 | else | 1206 | else |
1206 | tmp = rdev->config.evergreen.tile_config; | 1207 | tmp = rdev->config.evergreen.tile_config; |
@@ -1773,6 +1774,20 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1773 | return ATOM_PPLL1; | 1774 | return ATOM_PPLL1; |
1774 | DRM_ERROR("unable to allocate a PPLL\n"); | 1775 | DRM_ERROR("unable to allocate a PPLL\n"); |
1775 | return ATOM_PPLL_INVALID; | 1776 | return ATOM_PPLL_INVALID; |
1777 | } else if (ASIC_IS_DCE41(rdev)) { | ||
1778 | /* Don't share PLLs on DCE4.1 chips */ | ||
1779 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | ||
1780 | if (rdev->clock.dp_extclk) | ||
1781 | /* skip PPLL programming if using ext clock */ | ||
1782 | return ATOM_PPLL_INVALID; | ||
1783 | } | ||
1784 | pll_in_use = radeon_get_pll_use_mask(crtc); | ||
1785 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | ||
1786 | return ATOM_PPLL1; | ||
1787 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1788 | return ATOM_PPLL2; | ||
1789 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
1790 | return ATOM_PPLL_INVALID; | ||
1776 | } else if (ASIC_IS_DCE4(rdev)) { | 1791 | } else if (ASIC_IS_DCE4(rdev)) { |
1777 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, | 1792 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1778 | * depending on the asic: | 1793 | * depending on the asic: |
@@ -1800,7 +1815,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1800 | if (pll != ATOM_PPLL_INVALID) | 1815 | if (pll != ATOM_PPLL_INVALID) |
1801 | return pll; | 1816 | return pll; |
1802 | } | 1817 | } |
1803 | } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */ | 1818 | } else { |
1804 | /* use the same PPLL for all monitors with the same clock */ | 1819 | /* use the same PPLL for all monitors with the same clock */ |
1805 | pll = radeon_get_shared_nondp_ppll(crtc); | 1820 | pll = radeon_get_shared_nondp_ppll(crtc); |
1806 | if (pll != ATOM_PPLL_INVALID) | 1821 | if (pll != ATOM_PPLL_INVALID) |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index a42d61571f49..2cec2ab02f80 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -464,11 +464,12 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
464 | 464 | ||
465 | static u8 radeon_atom_get_bpc(struct drm_encoder *encoder) | 465 | static u8 radeon_atom_get_bpc(struct drm_encoder *encoder) |
466 | { | 466 | { |
467 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
468 | int bpc = 8; | 467 | int bpc = 8; |
469 | 468 | ||
470 | if (connector) | 469 | if (encoder->crtc) { |
471 | bpc = radeon_get_monitor_bpc(connector); | 470 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
471 | bpc = radeon_crtc->bpc; | ||
472 | } | ||
472 | 473 | ||
473 | switch (bpc) { | 474 | switch (bpc) { |
474 | case 0: | 475 | case 0: |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 713a5d359901..94e858751994 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -278,13 +278,15 @@ static int dce6_audio_chipset_supported(struct radeon_device *rdev) | |||
278 | return !ASIC_IS_NODCE(rdev); | 278 | return !ASIC_IS_NODCE(rdev); |
279 | } | 279 | } |
280 | 280 | ||
281 | static void dce6_audio_enable(struct radeon_device *rdev, | 281 | void dce6_audio_enable(struct radeon_device *rdev, |
282 | struct r600_audio_pin *pin, | 282 | struct r600_audio_pin *pin, |
283 | bool enable) | 283 | bool enable) |
284 | { | 284 | { |
285 | if (!pin) | ||
286 | return; | ||
287 | |||
285 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL, | 288 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL, |
286 | AUDIO_ENABLED); | 289 | enable ? AUDIO_ENABLED : 0); |
287 | DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id); | ||
288 | } | 290 | } |
289 | 291 | ||
290 | static const u32 pin_offsets[7] = | 292 | static const u32 pin_offsets[7] = |
@@ -323,7 +325,8 @@ int dce6_audio_init(struct radeon_device *rdev) | |||
323 | rdev->audio.pin[i].connected = false; | 325 | rdev->audio.pin[i].connected = false; |
324 | rdev->audio.pin[i].offset = pin_offsets[i]; | 326 | rdev->audio.pin[i].offset = pin_offsets[i]; |
325 | rdev->audio.pin[i].id = i; | 327 | rdev->audio.pin[i].id = i; |
326 | dce6_audio_enable(rdev, &rdev->audio.pin[i], true); | 328 | /* disable audio. it will be set up later */ |
329 | dce6_audio_enable(rdev, &rdev->audio.pin[i], false); | ||
327 | } | 330 | } |
328 | 331 | ||
329 | return 0; | 332 | return 0; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f2b9e21ce4da..8a2c010b7dc5 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1680,7 +1680,7 @@ bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | |||
1680 | case RADEON_HPD_6: | 1680 | case RADEON_HPD_6: |
1681 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) | 1681 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) |
1682 | connected = true; | 1682 | connected = true; |
1683 | break; | 1683 | break; |
1684 | default: | 1684 | default: |
1685 | break; | 1685 | break; |
1686 | } | 1686 | } |
@@ -5475,9 +5475,9 @@ void evergreen_fini(struct radeon_device *rdev) | |||
5475 | radeon_wb_fini(rdev); | 5475 | radeon_wb_fini(rdev); |
5476 | radeon_ib_pool_fini(rdev); | 5476 | radeon_ib_pool_fini(rdev); |
5477 | radeon_irq_kms_fini(rdev); | 5477 | radeon_irq_kms_fini(rdev); |
5478 | evergreen_pcie_gart_fini(rdev); | ||
5479 | uvd_v1_0_fini(rdev); | 5478 | uvd_v1_0_fini(rdev); |
5480 | radeon_uvd_fini(rdev); | 5479 | radeon_uvd_fini(rdev); |
5480 | evergreen_pcie_gart_fini(rdev); | ||
5481 | r600_vram_scratch_fini(rdev); | 5481 | r600_vram_scratch_fini(rdev); |
5482 | radeon_gem_fini(rdev); | 5482 | radeon_gem_fini(rdev); |
5483 | radeon_fence_driver_fini(rdev); | 5483 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 0c6d5cef4cf1..05b0c95813fd 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -306,6 +306,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
306 | return; | 306 | return; |
307 | offset = dig->afmt->offset; | 307 | offset = dig->afmt->offset; |
308 | 308 | ||
309 | /* disable audio prior to setting up hw */ | ||
310 | if (ASIC_IS_DCE6(rdev)) { | ||
311 | dig->afmt->pin = dce6_audio_get_pin(rdev); | ||
312 | dce6_audio_enable(rdev, dig->afmt->pin, false); | ||
313 | } else { | ||
314 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
315 | r600_audio_enable(rdev, dig->afmt->pin, false); | ||
316 | } | ||
317 | |||
309 | evergreen_audio_set_dto(encoder, mode->clock); | 318 | evergreen_audio_set_dto(encoder, mode->clock); |
310 | 319 | ||
311 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, | 320 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, |
@@ -409,12 +418,16 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
409 | WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); | 418 | WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); |
410 | WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); | 419 | WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); |
411 | WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); | 420 | WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); |
421 | |||
422 | /* enable audio after to setting up hw */ | ||
423 | if (ASIC_IS_DCE6(rdev)) | ||
424 | dce6_audio_enable(rdev, dig->afmt->pin, true); | ||
425 | else | ||
426 | r600_audio_enable(rdev, dig->afmt->pin, true); | ||
412 | } | 427 | } |
413 | 428 | ||
414 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | 429 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) |
415 | { | 430 | { |
416 | struct drm_device *dev = encoder->dev; | ||
417 | struct radeon_device *rdev = dev->dev_private; | ||
418 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 431 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
419 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 432 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
420 | 433 | ||
@@ -427,15 +440,6 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
427 | if (!enable && !dig->afmt->enabled) | 440 | if (!enable && !dig->afmt->enabled) |
428 | return; | 441 | return; |
429 | 442 | ||
430 | if (enable) { | ||
431 | if (ASIC_IS_DCE6(rdev)) | ||
432 | dig->afmt->pin = dce6_audio_get_pin(rdev); | ||
433 | else | ||
434 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
435 | } else { | ||
436 | dig->afmt->pin = NULL; | ||
437 | } | ||
438 | |||
439 | dig->afmt->enabled = enable; | 443 | dig->afmt->enabled = enable; |
440 | 444 | ||
441 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 445 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 1217fbcbdcca..ca814276b075 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
@@ -2588,7 +2588,7 @@ static int ni_populate_sq_ramping_values(struct radeon_device *rdev, | |||
2588 | if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) | 2588 | if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) |
2589 | enable_sq_ramping = false; | 2589 | enable_sq_ramping = false; |
2590 | 2590 | ||
2591 | if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) | 2591 | if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) |
2592 | enable_sq_ramping = false; | 2592 | enable_sq_ramping = false; |
2593 | 2593 | ||
2594 | for (i = 0; i < state->performance_level_count; i++) { | 2594 | for (i = 0; i < state->performance_level_count; i++) { |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 47fc2b886979..bffac10c4296 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -142,12 +142,15 @@ void r600_audio_update_hdmi(struct work_struct *work) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | /* enable the audio stream */ | 144 | /* enable the audio stream */ |
145 | static void r600_audio_enable(struct radeon_device *rdev, | 145 | void r600_audio_enable(struct radeon_device *rdev, |
146 | struct r600_audio_pin *pin, | 146 | struct r600_audio_pin *pin, |
147 | bool enable) | 147 | bool enable) |
148 | { | 148 | { |
149 | u32 value = 0; | 149 | u32 value = 0; |
150 | 150 | ||
151 | if (!pin) | ||
152 | return; | ||
153 | |||
151 | if (ASIC_IS_DCE4(rdev)) { | 154 | if (ASIC_IS_DCE4(rdev)) { |
152 | if (enable) { | 155 | if (enable) { |
153 | value |= 0x81000000; /* Required to enable audio */ | 156 | value |= 0x81000000; /* Required to enable audio */ |
@@ -158,7 +161,6 @@ static void r600_audio_enable(struct radeon_device *rdev, | |||
158 | WREG32_P(R600_AUDIO_ENABLE, | 161 | WREG32_P(R600_AUDIO_ENABLE, |
159 | enable ? 0x81000000 : 0x0, ~0x81000000); | 162 | enable ? 0x81000000 : 0x0, ~0x81000000); |
160 | } | 163 | } |
161 | DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id); | ||
162 | } | 164 | } |
163 | 165 | ||
164 | /* | 166 | /* |
@@ -178,8 +180,8 @@ int r600_audio_init(struct radeon_device *rdev) | |||
178 | rdev->audio.pin[0].status_bits = 0; | 180 | rdev->audio.pin[0].status_bits = 0; |
179 | rdev->audio.pin[0].category_code = 0; | 181 | rdev->audio.pin[0].category_code = 0; |
180 | rdev->audio.pin[0].id = 0; | 182 | rdev->audio.pin[0].id = 0; |
181 | 183 | /* disable audio. it will be set up later */ | |
182 | r600_audio_enable(rdev, &rdev->audio.pin[0], true); | 184 | r600_audio_enable(rdev, &rdev->audio.pin[0], false); |
183 | 185 | ||
184 | return 0; | 186 | return 0; |
185 | } | 187 | } |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 3016fc14f502..85a2bb28aed2 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -329,9 +329,6 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
329 | u8 *sadb; | 329 | u8 *sadb; |
330 | int sad_count; | 330 | int sad_count; |
331 | 331 | ||
332 | /* XXX: setting this register causes hangs on some asics */ | ||
333 | return; | ||
334 | |||
335 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 332 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
336 | if (connector->encoder == encoder) { | 333 | if (connector->encoder == encoder) { |
337 | radeon_connector = to_radeon_connector(connector); | 334 | radeon_connector = to_radeon_connector(connector); |
@@ -460,6 +457,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
460 | return; | 457 | return; |
461 | offset = dig->afmt->offset; | 458 | offset = dig->afmt->offset; |
462 | 459 | ||
460 | /* disable audio prior to setting up hw */ | ||
461 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
462 | r600_audio_enable(rdev, dig->afmt->pin, false); | ||
463 | |||
463 | r600_audio_set_dto(encoder, mode->clock); | 464 | r600_audio_set_dto(encoder, mode->clock); |
464 | 465 | ||
465 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, | 466 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, |
@@ -531,6 +532,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
531 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); | 532 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); |
532 | 533 | ||
533 | r600_hdmi_audio_workaround(encoder); | 534 | r600_hdmi_audio_workaround(encoder); |
535 | |||
536 | /* enable audio after to setting up hw */ | ||
537 | r600_audio_enable(rdev, dig->afmt->pin, true); | ||
534 | } | 538 | } |
535 | 539 | ||
536 | /* | 540 | /* |
@@ -651,11 +655,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
651 | if (!enable && !dig->afmt->enabled) | 655 | if (!enable && !dig->afmt->enabled) |
652 | return; | 656 | return; |
653 | 657 | ||
654 | if (enable) | ||
655 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
656 | else | ||
657 | dig->afmt->pin = NULL; | ||
658 | |||
659 | /* Older chipsets require setting HDMI and routing manually */ | 658 | /* Older chipsets require setting HDMI and routing manually */ |
660 | if (!ASIC_IS_DCE3(rdev)) { | 659 | if (!ASIC_IS_DCE3(rdev)) { |
661 | if (enable) | 660 | if (enable) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4a8ac1cd6b4c..e887d027b6d0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -135,6 +135,9 @@ extern int radeon_hard_reset; | |||
135 | /* R600+ */ | 135 | /* R600+ */ |
136 | #define R600_RING_TYPE_UVD_INDEX 5 | 136 | #define R600_RING_TYPE_UVD_INDEX 5 |
137 | 137 | ||
138 | /* number of hw syncs before falling back on blocking */ | ||
139 | #define RADEON_NUM_SYNCS 4 | ||
140 | |||
138 | /* hardcode those limit for now */ | 141 | /* hardcode those limit for now */ |
139 | #define RADEON_VA_IB_OFFSET (1 << 20) | 142 | #define RADEON_VA_IB_OFFSET (1 << 20) |
140 | #define RADEON_VA_RESERVED_SIZE (8 << 20) | 143 | #define RADEON_VA_RESERVED_SIZE (8 << 20) |
@@ -554,7 +557,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, | |||
554 | /* | 557 | /* |
555 | * Semaphores. | 558 | * Semaphores. |
556 | */ | 559 | */ |
557 | /* everything here is constant */ | ||
558 | struct radeon_semaphore { | 560 | struct radeon_semaphore { |
559 | struct radeon_sa_bo *sa_bo; | 561 | struct radeon_sa_bo *sa_bo; |
560 | signed waiters; | 562 | signed waiters; |
@@ -2745,6 +2747,12 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
2745 | void r600_audio_update_hdmi(struct work_struct *work); | 2747 | void r600_audio_update_hdmi(struct work_struct *work); |
2746 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); | 2748 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); |
2747 | struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); | 2749 | struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); |
2750 | void r600_audio_enable(struct radeon_device *rdev, | ||
2751 | struct r600_audio_pin *pin, | ||
2752 | bool enable); | ||
2753 | void dce6_audio_enable(struct radeon_device *rdev, | ||
2754 | struct r600_audio_pin *pin, | ||
2755 | bool enable); | ||
2748 | 2756 | ||
2749 | /* | 2757 | /* |
2750 | * R600 vram scratch functions | 2758 | * R600 vram scratch functions |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 485848f889f5..fa9a9c02751e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -219,7 +219,8 @@ static int radeon_atpx_verify_interface(struct radeon_atpx *atpx) | |||
219 | memcpy(&output, info->buffer.pointer, size); | 219 | memcpy(&output, info->buffer.pointer, size); |
220 | 220 | ||
221 | /* TODO: check version? */ | 221 | /* TODO: check version? */ |
222 | printk("ATPX version %u\n", output.version); | 222 | printk("ATPX version %u, functions 0x%08x\n", |
223 | output.version, output.function_bits); | ||
223 | 224 | ||
224 | radeon_atpx_parse_functions(&atpx->functions, output.function_bits); | 225 | radeon_atpx_parse_functions(&atpx->functions, output.function_bits); |
225 | 226 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d680608f6f5b..fbd8b930f2be 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -571,6 +571,8 @@ static void radeon_crtc_init(struct drm_device *dev, int index) | |||
571 | radeon_crtc->max_cursor_width = CURSOR_WIDTH; | 571 | radeon_crtc->max_cursor_width = CURSOR_WIDTH; |
572 | radeon_crtc->max_cursor_height = CURSOR_HEIGHT; | 572 | radeon_crtc->max_cursor_height = CURSOR_HEIGHT; |
573 | } | 573 | } |
574 | dev->mode_config.cursor_width = radeon_crtc->max_cursor_width; | ||
575 | dev->mode_config.cursor_height = radeon_crtc->max_cursor_height; | ||
574 | 576 | ||
575 | #if 0 | 577 | #if 0 |
576 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; | 578 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 114d1672d616..2aecd6dc2610 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -537,6 +537,10 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
537 | 537 | ||
538 | radeon_vm_init(rdev, &fpriv->vm); | 538 | radeon_vm_init(rdev, &fpriv->vm); |
539 | 539 | ||
540 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | ||
541 | if (r) | ||
542 | return r; | ||
543 | |||
540 | /* map the ib pool buffer read only into | 544 | /* map the ib pool buffer read only into |
541 | * virtual address space */ | 545 | * virtual address space */ |
542 | bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, | 546 | bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, |
@@ -544,6 +548,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
544 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, | 548 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, |
545 | RADEON_VM_PAGE_READABLE | | 549 | RADEON_VM_PAGE_READABLE | |
546 | RADEON_VM_PAGE_SNOOPED); | 550 | RADEON_VM_PAGE_SNOOPED); |
551 | |||
552 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
547 | if (r) { | 553 | if (r) { |
548 | radeon_vm_fini(rdev, &fpriv->vm); | 554 | radeon_vm_fini(rdev, &fpriv->vm); |
549 | kfree(fpriv); | 555 | kfree(fpriv); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 1b783f0e6d3a..15e44a7281ab 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -139,7 +139,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /* 64 dwords should be enough for fence too */ | 141 | /* 64 dwords should be enough for fence too */ |
142 | r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8); | 142 | r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8); |
143 | if (r) { | 143 | if (r) { |
144 | dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); | 144 | dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); |
145 | return r; | 145 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 2b42aa1914f2..9006b32d5eed 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -34,14 +34,15 @@ | |||
34 | int radeon_semaphore_create(struct radeon_device *rdev, | 34 | int radeon_semaphore_create(struct radeon_device *rdev, |
35 | struct radeon_semaphore **semaphore) | 35 | struct radeon_semaphore **semaphore) |
36 | { | 36 | { |
37 | uint32_t *cpu_addr; | ||
37 | int i, r; | 38 | int i, r; |
38 | 39 | ||
39 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); | 40 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); |
40 | if (*semaphore == NULL) { | 41 | if (*semaphore == NULL) { |
41 | return -ENOMEM; | 42 | return -ENOMEM; |
42 | } | 43 | } |
43 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, | 44 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, |
44 | &(*semaphore)->sa_bo, 8, 8, true); | 45 | 8 * RADEON_NUM_SYNCS, 8, true); |
45 | if (r) { | 46 | if (r) { |
46 | kfree(*semaphore); | 47 | kfree(*semaphore); |
47 | *semaphore = NULL; | 48 | *semaphore = NULL; |
@@ -49,7 +50,10 @@ int radeon_semaphore_create(struct radeon_device *rdev, | |||
49 | } | 50 | } |
50 | (*semaphore)->waiters = 0; | 51 | (*semaphore)->waiters = 0; |
51 | (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); | 52 | (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); |
52 | *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; | 53 | |
54 | cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); | ||
55 | for (i = 0; i < RADEON_NUM_SYNCS; ++i) | ||
56 | cpu_addr[i] = 0; | ||
53 | 57 | ||
54 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | 58 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
55 | (*semaphore)->sync_to[i] = NULL; | 59 | (*semaphore)->sync_to[i] = NULL; |
@@ -125,6 +129,7 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
125 | struct radeon_semaphore *semaphore, | 129 | struct radeon_semaphore *semaphore, |
126 | int ring) | 130 | int ring) |
127 | { | 131 | { |
132 | unsigned count = 0; | ||
128 | int i, r; | 133 | int i, r; |
129 | 134 | ||
130 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 135 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
@@ -140,6 +145,12 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
140 | return -EINVAL; | 145 | return -EINVAL; |
141 | } | 146 | } |
142 | 147 | ||
148 | if (++count > RADEON_NUM_SYNCS) { | ||
149 | /* not enough room, wait manually */ | ||
150 | radeon_fence_wait_locked(fence); | ||
151 | continue; | ||
152 | } | ||
153 | |||
143 | /* allocate enough space for sync command */ | 154 | /* allocate enough space for sync command */ |
144 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); | 155 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); |
145 | if (r) { | 156 | if (r) { |
@@ -164,6 +175,8 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
164 | 175 | ||
165 | radeon_ring_commit(rdev, &rdev->ring[i]); | 176 | radeon_ring_commit(rdev, &rdev->ring[i]); |
166 | radeon_fence_note_sync(fence, ring); | 177 | radeon_fence_note_sync(fence, ring); |
178 | |||
179 | semaphore->gpu_addr += 8; | ||
167 | } | 180 | } |
168 | 181 | ||
169 | return 0; | 182 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 6781fee1eaad..3e6804b2b2ef 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -171,6 +171,8 @@ void radeon_uvd_fini(struct radeon_device *rdev) | |||
171 | 171 | ||
172 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | 172 | radeon_bo_unref(&rdev->uvd.vcpu_bo); |
173 | 173 | ||
174 | radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]); | ||
175 | |||
174 | release_firmware(rdev->uvd_fw); | 176 | release_firmware(rdev->uvd_fw); |
175 | } | 177 | } |
176 | 178 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 6c772e58c784..4e37a42305d8 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -1955,9 +1955,9 @@ void rv770_fini(struct radeon_device *rdev) | |||
1955 | radeon_wb_fini(rdev); | 1955 | radeon_wb_fini(rdev); |
1956 | radeon_ib_pool_fini(rdev); | 1956 | radeon_ib_pool_fini(rdev); |
1957 | radeon_irq_kms_fini(rdev); | 1957 | radeon_irq_kms_fini(rdev); |
1958 | rv770_pcie_gart_fini(rdev); | ||
1959 | uvd_v1_0_fini(rdev); | 1958 | uvd_v1_0_fini(rdev); |
1960 | radeon_uvd_fini(rdev); | 1959 | radeon_uvd_fini(rdev); |
1960 | rv770_pcie_gart_fini(rdev); | ||
1961 | r600_vram_scratch_fini(rdev); | 1961 | r600_vram_scratch_fini(rdev); |
1962 | radeon_gem_fini(rdev); | 1962 | radeon_gem_fini(rdev); |
1963 | radeon_fence_driver_fini(rdev); | 1963 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 5b2ea8ac0731..b5f63f5e22a3 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -2526,14 +2526,7 @@ u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low) | |||
2526 | bool rv770_dpm_vblank_too_short(struct radeon_device *rdev) | 2526 | bool rv770_dpm_vblank_too_short(struct radeon_device *rdev) |
2527 | { | 2527 | { |
2528 | u32 vblank_time = r600_dpm_get_vblank_time(rdev); | 2528 | u32 vblank_time = r600_dpm_get_vblank_time(rdev); |
2529 | u32 switch_limit = 300; | 2529 | u32 switch_limit = 200; /* 300 */ |
2530 | |||
2531 | /* quirks */ | ||
2532 | /* ASUS K70AF */ | ||
2533 | if ((rdev->pdev->device == 0x9553) && | ||
2534 | (rdev->pdev->subsystem_vendor == 0x1043) && | ||
2535 | (rdev->pdev->subsystem_device == 0x1c42)) | ||
2536 | switch_limit = 200; | ||
2537 | 2530 | ||
2538 | /* RV770 */ | 2531 | /* RV770 */ |
2539 | /* mclk switching doesn't seem to work reliably on desktop RV770s */ | 2532 | /* mclk switching doesn't seem to work reliably on desktop RV770s */ |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index eafb0e6bc67e..0a2f5b4bca43 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -2395,7 +2395,7 @@ static int si_populate_sq_ramping_values(struct radeon_device *rdev, | |||
2395 | if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) | 2395 | if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) |
2396 | enable_sq_ramping = false; | 2396 | enable_sq_ramping = false; |
2397 | 2397 | ||
2398 | if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) | 2398 | if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) |
2399 | enable_sq_ramping = false; | 2399 | enable_sq_ramping = false; |
2400 | 2400 | ||
2401 | for (i = 0; i < state->performance_level_count; i++) { | 2401 | for (i = 0; i < state->performance_level_count; i++) { |
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 88a529008ce0..c71594754f46 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
@@ -104,7 +104,7 @@ static void tegra_drm_context_free(struct tegra_drm_context *context) | |||
104 | 104 | ||
105 | static void tegra_drm_lastclose(struct drm_device *drm) | 105 | static void tegra_drm_lastclose(struct drm_device *drm) |
106 | { | 106 | { |
107 | #ifdef CONFIG_TEGRA_DRM_FBDEV | 107 | #ifdef CONFIG_DRM_TEGRA_FBDEV |
108 | struct tegra_drm *tegra = drm->dev_private; | 108 | struct tegra_drm *tegra = drm->dev_private; |
109 | 109 | ||
110 | tegra_fbdev_restore_mode(tegra->fbdev); | 110 | tegra_fbdev_restore_mode(tegra->fbdev); |
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 338f7f6561d7..0266fb40479e 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c | |||
@@ -15,6 +15,7 @@ | |||
15 | struct tegra_rgb { | 15 | struct tegra_rgb { |
16 | struct tegra_output output; | 16 | struct tegra_output output; |
17 | struct tegra_dc *dc; | 17 | struct tegra_dc *dc; |
18 | bool enabled; | ||
18 | 19 | ||
19 | struct clk *clk_parent; | 20 | struct clk *clk_parent; |
20 | struct clk *clk; | 21 | struct clk *clk; |
@@ -89,6 +90,9 @@ static int tegra_output_rgb_enable(struct tegra_output *output) | |||
89 | struct tegra_rgb *rgb = to_rgb(output); | 90 | struct tegra_rgb *rgb = to_rgb(output); |
90 | unsigned long value; | 91 | unsigned long value; |
91 | 92 | ||
93 | if (rgb->enabled) | ||
94 | return 0; | ||
95 | |||
92 | tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); | 96 | tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); |
93 | 97 | ||
94 | value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; | 98 | value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; |
@@ -122,6 +126,8 @@ static int tegra_output_rgb_enable(struct tegra_output *output) | |||
122 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); | 126 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); |
123 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); | 127 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); |
124 | 128 | ||
129 | rgb->enabled = true; | ||
130 | |||
125 | return 0; | 131 | return 0; |
126 | } | 132 | } |
127 | 133 | ||
@@ -130,6 +136,9 @@ static int tegra_output_rgb_disable(struct tegra_output *output) | |||
130 | struct tegra_rgb *rgb = to_rgb(output); | 136 | struct tegra_rgb *rgb = to_rgb(output); |
131 | unsigned long value; | 137 | unsigned long value; |
132 | 138 | ||
139 | if (!rgb->enabled) | ||
140 | return 0; | ||
141 | |||
133 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL); | 142 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL); |
134 | value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | 143 | value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | |
135 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); | 144 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); |
@@ -144,6 +153,8 @@ static int tegra_output_rgb_disable(struct tegra_output *output) | |||
144 | 153 | ||
145 | tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); | 154 | tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); |
146 | 155 | ||
156 | rgb->enabled = false; | ||
157 | |||
147 | return 0; | 158 | return 0; |
148 | } | 159 | } |
149 | 160 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index 3302f99e7497..764be36397fd 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c | |||
@@ -126,6 +126,7 @@ struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev, | |||
126 | agp_be->ttm.func = &ttm_agp_func; | 126 | agp_be->ttm.func = &ttm_agp_func; |
127 | 127 | ||
128 | if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) { | 128 | if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) { |
129 | kfree(agp_be); | ||
129 | return NULL; | 130 | return NULL; |
130 | } | 131 | } |
131 | 132 | ||
diff --git a/drivers/gpu/drm/vmwgfx/svga3d_reg.h b/drivers/gpu/drm/vmwgfx/svga3d_reg.h index b645647b7776..f58dc7dd15c5 100644 --- a/drivers/gpu/drm/vmwgfx/svga3d_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga3d_reg.h | |||
@@ -261,12 +261,7 @@ typedef enum SVGA3dSurfaceFormat { | |||
261 | /* Planar video formats. */ | 261 | /* Planar video formats. */ |
262 | SVGA3D_YV12 = 121, | 262 | SVGA3D_YV12 = 121, |
263 | 263 | ||
264 | /* Shader constant formats. */ | 264 | SVGA3D_FORMAT_MAX = 122, |
265 | SVGA3D_SURFACE_SHADERCONST_FLOAT = 122, | ||
266 | SVGA3D_SURFACE_SHADERCONST_INT = 123, | ||
267 | SVGA3D_SURFACE_SHADERCONST_BOOL = 124, | ||
268 | |||
269 | SVGA3D_FORMAT_MAX = 125, | ||
270 | } SVGA3dSurfaceFormat; | 265 | } SVGA3dSurfaceFormat; |
271 | 266 | ||
272 | typedef uint32 SVGA3dColor; /* a, r, g, b */ | 267 | typedef uint32 SVGA3dColor; /* a, r, g, b */ |
@@ -1223,9 +1218,19 @@ typedef enum { | |||
1223 | #define SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL 1129 | 1218 | #define SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL 1129 |
1224 | 1219 | ||
1225 | #define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130 | 1220 | #define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130 |
1226 | 1221 | #define SVGA_3D_CMD_GB_SCREEN_DMA 1131 | |
1222 | #define SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH 1132 | ||
1223 | #define SVGA_3D_CMD_GB_MOB_FENCE 1133 | ||
1224 | #define SVGA_3D_CMD_DEFINE_GB_SURFACE_V2 1134 | ||
1227 | #define SVGA_3D_CMD_DEFINE_GB_MOB64 1135 | 1225 | #define SVGA_3D_CMD_DEFINE_GB_MOB64 1135 |
1228 | #define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136 | 1226 | #define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136 |
1227 | #define SVGA_3D_CMD_NOP_ERROR 1137 | ||
1228 | |||
1229 | #define SVGA_3D_CMD_RESERVED1 1138 | ||
1230 | #define SVGA_3D_CMD_RESERVED2 1139 | ||
1231 | #define SVGA_3D_CMD_RESERVED3 1140 | ||
1232 | #define SVGA_3D_CMD_RESERVED4 1141 | ||
1233 | #define SVGA_3D_CMD_RESERVED5 1142 | ||
1229 | 1234 | ||
1230 | #define SVGA_3D_CMD_MAX 1142 | 1235 | #define SVGA_3D_CMD_MAX 1142 |
1231 | #define SVGA_3D_CMD_FUTURE_MAX 3000 | 1236 | #define SVGA_3D_CMD_FUTURE_MAX 3000 |
@@ -1973,8 +1978,7 @@ struct { | |||
1973 | uint32 sizeInBytes; | 1978 | uint32 sizeInBytes; |
1974 | uint32 validSizeInBytes; | 1979 | uint32 validSizeInBytes; |
1975 | SVGAMobFormat ptDepth; | 1980 | SVGAMobFormat ptDepth; |
1976 | } | 1981 | } __packed |
1977 | __attribute__((__packed__)) | ||
1978 | SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */ | 1982 | SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */ |
1979 | 1983 | ||
1980 | typedef | 1984 | typedef |
@@ -1984,15 +1988,13 @@ struct { | |||
1984 | uint32 sizeInBytes; | 1988 | uint32 sizeInBytes; |
1985 | uint32 validSizeInBytes; | 1989 | uint32 validSizeInBytes; |
1986 | SVGAMobFormat ptDepth; | 1990 | SVGAMobFormat ptDepth; |
1987 | } | 1991 | } __packed |
1988 | __attribute__((__packed__)) | ||
1989 | SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */ | 1992 | SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */ |
1990 | 1993 | ||
1991 | typedef | 1994 | typedef |
1992 | struct { | 1995 | struct { |
1993 | SVGAOTableType type; | 1996 | SVGAOTableType type; |
1994 | } | 1997 | } __packed |
1995 | __attribute__((__packed__)) | ||
1996 | SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */ | 1998 | SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */ |
1997 | 1999 | ||
1998 | /* | 2000 | /* |
@@ -2005,8 +2007,7 @@ struct SVGA3dCmdDefineGBMob { | |||
2005 | SVGAMobFormat ptDepth; | 2007 | SVGAMobFormat ptDepth; |
2006 | PPN base; | 2008 | PPN base; |
2007 | uint32 sizeInBytes; | 2009 | uint32 sizeInBytes; |
2008 | } | 2010 | } __packed |
2009 | __attribute__((__packed__)) | ||
2010 | SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */ | 2011 | SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */ |
2011 | 2012 | ||
2012 | 2013 | ||
@@ -2017,8 +2018,7 @@ SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */ | |||
2017 | typedef | 2018 | typedef |
2018 | struct SVGA3dCmdDestroyGBMob { | 2019 | struct SVGA3dCmdDestroyGBMob { |
2019 | SVGAMobId mobid; | 2020 | SVGAMobId mobid; |
2020 | } | 2021 | } __packed |
2021 | __attribute__((__packed__)) | ||
2022 | SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */ | 2022 | SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */ |
2023 | 2023 | ||
2024 | /* | 2024 | /* |
@@ -2031,8 +2031,7 @@ struct SVGA3dCmdRedefineGBMob { | |||
2031 | SVGAMobFormat ptDepth; | 2031 | SVGAMobFormat ptDepth; |
2032 | PPN base; | 2032 | PPN base; |
2033 | uint32 sizeInBytes; | 2033 | uint32 sizeInBytes; |
2034 | } | 2034 | } __packed |
2035 | __attribute__((__packed__)) | ||
2036 | SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */ | 2035 | SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */ |
2037 | 2036 | ||
2038 | /* | 2037 | /* |
@@ -2045,8 +2044,7 @@ struct SVGA3dCmdDefineGBMob64 { | |||
2045 | SVGAMobFormat ptDepth; | 2044 | SVGAMobFormat ptDepth; |
2046 | PPN64 base; | 2045 | PPN64 base; |
2047 | uint32 sizeInBytes; | 2046 | uint32 sizeInBytes; |
2048 | } | 2047 | } __packed |
2049 | __attribute__((__packed__)) | ||
2050 | SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */ | 2048 | SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */ |
2051 | 2049 | ||
2052 | /* | 2050 | /* |
@@ -2059,8 +2057,7 @@ struct SVGA3dCmdRedefineGBMob64 { | |||
2059 | SVGAMobFormat ptDepth; | 2057 | SVGAMobFormat ptDepth; |
2060 | PPN64 base; | 2058 | PPN64 base; |
2061 | uint32 sizeInBytes; | 2059 | uint32 sizeInBytes; |
2062 | } | 2060 | } __packed |
2063 | __attribute__((__packed__)) | ||
2064 | SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */ | 2061 | SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */ |
2065 | 2062 | ||
2066 | /* | 2063 | /* |
@@ -2070,8 +2067,7 @@ SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */ | |||
2070 | typedef | 2067 | typedef |
2071 | struct SVGA3dCmdUpdateGBMobMapping { | 2068 | struct SVGA3dCmdUpdateGBMobMapping { |
2072 | SVGAMobId mobid; | 2069 | SVGAMobId mobid; |
2073 | } | 2070 | } __packed |
2074 | __attribute__((__packed__)) | ||
2075 | SVGA3dCmdUpdateGBMobMapping; /* SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING */ | 2071 | SVGA3dCmdUpdateGBMobMapping; /* SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING */ |
2076 | 2072 | ||
2077 | /* | 2073 | /* |
@@ -2087,7 +2083,8 @@ struct SVGA3dCmdDefineGBSurface { | |||
2087 | uint32 multisampleCount; | 2083 | uint32 multisampleCount; |
2088 | SVGA3dTextureFilter autogenFilter; | 2084 | SVGA3dTextureFilter autogenFilter; |
2089 | SVGA3dSize size; | 2085 | SVGA3dSize size; |
2090 | } SVGA3dCmdDefineGBSurface; /* SVGA_3D_CMD_DEFINE_GB_SURFACE */ | 2086 | } __packed |
2087 | SVGA3dCmdDefineGBSurface; /* SVGA_3D_CMD_DEFINE_GB_SURFACE */ | ||
2091 | 2088 | ||
2092 | /* | 2089 | /* |
2093 | * Destroy a guest-backed surface. | 2090 | * Destroy a guest-backed surface. |
@@ -2096,7 +2093,8 @@ struct SVGA3dCmdDefineGBSurface { | |||
2096 | typedef | 2093 | typedef |
2097 | struct SVGA3dCmdDestroyGBSurface { | 2094 | struct SVGA3dCmdDestroyGBSurface { |
2098 | uint32 sid; | 2095 | uint32 sid; |
2099 | } SVGA3dCmdDestroyGBSurface; /* SVGA_3D_CMD_DESTROY_GB_SURFACE */ | 2096 | } __packed |
2097 | SVGA3dCmdDestroyGBSurface; /* SVGA_3D_CMD_DESTROY_GB_SURFACE */ | ||
2100 | 2098 | ||
2101 | /* | 2099 | /* |
2102 | * Bind a guest-backed surface to an object. | 2100 | * Bind a guest-backed surface to an object. |
@@ -2106,7 +2104,8 @@ typedef | |||
2106 | struct SVGA3dCmdBindGBSurface { | 2104 | struct SVGA3dCmdBindGBSurface { |
2107 | uint32 sid; | 2105 | uint32 sid; |
2108 | SVGAMobId mobid; | 2106 | SVGAMobId mobid; |
2109 | } SVGA3dCmdBindGBSurface; /* SVGA_3D_CMD_BIND_GB_SURFACE */ | 2107 | } __packed |
2108 | SVGA3dCmdBindGBSurface; /* SVGA_3D_CMD_BIND_GB_SURFACE */ | ||
2110 | 2109 | ||
2111 | /* | 2110 | /* |
2112 | * Conditionally bind a mob to a guest backed surface if testMobid | 2111 | * Conditionally bind a mob to a guest backed surface if testMobid |
@@ -2123,7 +2122,7 @@ struct{ | |||
2123 | SVGAMobId testMobid; | 2122 | SVGAMobId testMobid; |
2124 | SVGAMobId mobid; | 2123 | SVGAMobId mobid; |
2125 | uint32 flags; | 2124 | uint32 flags; |
2126 | } | 2125 | } __packed |
2127 | SVGA3dCmdCondBindGBSurface; /* SVGA_3D_CMD_COND_BIND_GB_SURFACE */ | 2126 | SVGA3dCmdCondBindGBSurface; /* SVGA_3D_CMD_COND_BIND_GB_SURFACE */ |
2128 | 2127 | ||
2129 | /* | 2128 | /* |
@@ -2135,7 +2134,8 @@ typedef | |||
2135 | struct SVGA3dCmdUpdateGBImage { | 2134 | struct SVGA3dCmdUpdateGBImage { |
2136 | SVGA3dSurfaceImageId image; | 2135 | SVGA3dSurfaceImageId image; |
2137 | SVGA3dBox box; | 2136 | SVGA3dBox box; |
2138 | } SVGA3dCmdUpdateGBImage; /* SVGA_3D_CMD_UPDATE_GB_IMAGE */ | 2137 | } __packed |
2138 | SVGA3dCmdUpdateGBImage; /* SVGA_3D_CMD_UPDATE_GB_IMAGE */ | ||
2139 | 2139 | ||
2140 | /* | 2140 | /* |
2141 | * Update an entire guest-backed surface. | 2141 | * Update an entire guest-backed surface. |
@@ -2145,7 +2145,8 @@ struct SVGA3dCmdUpdateGBImage { | |||
2145 | typedef | 2145 | typedef |
2146 | struct SVGA3dCmdUpdateGBSurface { | 2146 | struct SVGA3dCmdUpdateGBSurface { |
2147 | uint32 sid; | 2147 | uint32 sid; |
2148 | } SVGA3dCmdUpdateGBSurface; /* SVGA_3D_CMD_UPDATE_GB_SURFACE */ | 2148 | } __packed |
2149 | SVGA3dCmdUpdateGBSurface; /* SVGA_3D_CMD_UPDATE_GB_SURFACE */ | ||
2149 | 2150 | ||
2150 | /* | 2151 | /* |
2151 | * Readback an image in a guest-backed surface. | 2152 | * Readback an image in a guest-backed surface. |
@@ -2155,7 +2156,8 @@ struct SVGA3dCmdUpdateGBSurface { | |||
2155 | typedef | 2156 | typedef |
2156 | struct SVGA3dCmdReadbackGBImage { | 2157 | struct SVGA3dCmdReadbackGBImage { |
2157 | SVGA3dSurfaceImageId image; | 2158 | SVGA3dSurfaceImageId image; |
2158 | } SVGA3dCmdReadbackGBImage; /* SVGA_3D_CMD_READBACK_GB_IMAGE*/ | 2159 | } __packed |
2160 | SVGA3dCmdReadbackGBImage; /* SVGA_3D_CMD_READBACK_GB_IMAGE*/ | ||
2159 | 2161 | ||
2160 | /* | 2162 | /* |
2161 | * Readback an entire guest-backed surface. | 2163 | * Readback an entire guest-backed surface. |
@@ -2165,7 +2167,8 @@ struct SVGA3dCmdReadbackGBImage { | |||
2165 | typedef | 2167 | typedef |
2166 | struct SVGA3dCmdReadbackGBSurface { | 2168 | struct SVGA3dCmdReadbackGBSurface { |
2167 | uint32 sid; | 2169 | uint32 sid; |
2168 | } SVGA3dCmdReadbackGBSurface; /* SVGA_3D_CMD_READBACK_GB_SURFACE */ | 2170 | } __packed |
2171 | SVGA3dCmdReadbackGBSurface; /* SVGA_3D_CMD_READBACK_GB_SURFACE */ | ||
2169 | 2172 | ||
2170 | /* | 2173 | /* |
2171 | * Readback a sub rect of an image in a guest-backed surface. After | 2174 | * Readback a sub rect of an image in a guest-backed surface. After |
@@ -2179,7 +2182,7 @@ struct SVGA3dCmdReadbackGBImagePartial { | |||
2179 | SVGA3dSurfaceImageId image; | 2182 | SVGA3dSurfaceImageId image; |
2180 | SVGA3dBox box; | 2183 | SVGA3dBox box; |
2181 | uint32 invertBox; | 2184 | uint32 invertBox; |
2182 | } | 2185 | } __packed |
2183 | SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */ | 2186 | SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */ |
2184 | 2187 | ||
2185 | /* | 2188 | /* |
@@ -2190,7 +2193,8 @@ SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */ | |||
2190 | typedef | 2193 | typedef |
2191 | struct SVGA3dCmdInvalidateGBImage { | 2194 | struct SVGA3dCmdInvalidateGBImage { |
2192 | SVGA3dSurfaceImageId image; | 2195 | SVGA3dSurfaceImageId image; |
2193 | } SVGA3dCmdInvalidateGBImage; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE */ | 2196 | } __packed |
2197 | SVGA3dCmdInvalidateGBImage; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE */ | ||
2194 | 2198 | ||
2195 | /* | 2199 | /* |
2196 | * Invalidate an entire guest-backed surface. | 2200 | * Invalidate an entire guest-backed surface. |
@@ -2200,7 +2204,8 @@ struct SVGA3dCmdInvalidateGBImage { | |||
2200 | typedef | 2204 | typedef |
2201 | struct SVGA3dCmdInvalidateGBSurface { | 2205 | struct SVGA3dCmdInvalidateGBSurface { |
2202 | uint32 sid; | 2206 | uint32 sid; |
2203 | } SVGA3dCmdInvalidateGBSurface; /* SVGA_3D_CMD_INVALIDATE_GB_SURFACE */ | 2207 | } __packed |
2208 | SVGA3dCmdInvalidateGBSurface; /* SVGA_3D_CMD_INVALIDATE_GB_SURFACE */ | ||
2204 | 2209 | ||
2205 | /* | 2210 | /* |
2206 | * Invalidate a sub rect of an image in a guest-backed surface. After | 2211 | * Invalidate a sub rect of an image in a guest-backed surface. After |
@@ -2214,7 +2219,7 @@ struct SVGA3dCmdInvalidateGBImagePartial { | |||
2214 | SVGA3dSurfaceImageId image; | 2219 | SVGA3dSurfaceImageId image; |
2215 | SVGA3dBox box; | 2220 | SVGA3dBox box; |
2216 | uint32 invertBox; | 2221 | uint32 invertBox; |
2217 | } | 2222 | } __packed |
2218 | SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */ | 2223 | SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */ |
2219 | 2224 | ||
2220 | /* | 2225 | /* |
@@ -2224,7 +2229,8 @@ SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */ | |||
2224 | typedef | 2229 | typedef |
2225 | struct SVGA3dCmdDefineGBContext { | 2230 | struct SVGA3dCmdDefineGBContext { |
2226 | uint32 cid; | 2231 | uint32 cid; |
2227 | } SVGA3dCmdDefineGBContext; /* SVGA_3D_CMD_DEFINE_GB_CONTEXT */ | 2232 | } __packed |
2233 | SVGA3dCmdDefineGBContext; /* SVGA_3D_CMD_DEFINE_GB_CONTEXT */ | ||
2228 | 2234 | ||
2229 | /* | 2235 | /* |
2230 | * Destroy a guest-backed context. | 2236 | * Destroy a guest-backed context. |
@@ -2233,7 +2239,8 @@ struct SVGA3dCmdDefineGBContext { | |||
2233 | typedef | 2239 | typedef |
2234 | struct SVGA3dCmdDestroyGBContext { | 2240 | struct SVGA3dCmdDestroyGBContext { |
2235 | uint32 cid; | 2241 | uint32 cid; |
2236 | } SVGA3dCmdDestroyGBContext; /* SVGA_3D_CMD_DESTROY_GB_CONTEXT */ | 2242 | } __packed |
2243 | SVGA3dCmdDestroyGBContext; /* SVGA_3D_CMD_DESTROY_GB_CONTEXT */ | ||
2237 | 2244 | ||
2238 | /* | 2245 | /* |
2239 | * Bind a guest-backed context. | 2246 | * Bind a guest-backed context. |
@@ -2252,7 +2259,8 @@ struct SVGA3dCmdBindGBContext { | |||
2252 | uint32 cid; | 2259 | uint32 cid; |
2253 | SVGAMobId mobid; | 2260 | SVGAMobId mobid; |
2254 | uint32 validContents; | 2261 | uint32 validContents; |
2255 | } SVGA3dCmdBindGBContext; /* SVGA_3D_CMD_BIND_GB_CONTEXT */ | 2262 | } __packed |
2263 | SVGA3dCmdBindGBContext; /* SVGA_3D_CMD_BIND_GB_CONTEXT */ | ||
2256 | 2264 | ||
2257 | /* | 2265 | /* |
2258 | * Readback a guest-backed context. | 2266 | * Readback a guest-backed context. |
@@ -2262,7 +2270,8 @@ struct SVGA3dCmdBindGBContext { | |||
2262 | typedef | 2270 | typedef |
2263 | struct SVGA3dCmdReadbackGBContext { | 2271 | struct SVGA3dCmdReadbackGBContext { |
2264 | uint32 cid; | 2272 | uint32 cid; |
2265 | } SVGA3dCmdReadbackGBContext; /* SVGA_3D_CMD_READBACK_GB_CONTEXT */ | 2273 | } __packed |
2274 | SVGA3dCmdReadbackGBContext; /* SVGA_3D_CMD_READBACK_GB_CONTEXT */ | ||
2266 | 2275 | ||
2267 | /* | 2276 | /* |
2268 | * Invalidate a guest-backed context. | 2277 | * Invalidate a guest-backed context. |
@@ -2270,7 +2279,8 @@ struct SVGA3dCmdReadbackGBContext { | |||
2270 | typedef | 2279 | typedef |
2271 | struct SVGA3dCmdInvalidateGBContext { | 2280 | struct SVGA3dCmdInvalidateGBContext { |
2272 | uint32 cid; | 2281 | uint32 cid; |
2273 | } SVGA3dCmdInvalidateGBContext; /* SVGA_3D_CMD_INVALIDATE_GB_CONTEXT */ | 2282 | } __packed |
2283 | SVGA3dCmdInvalidateGBContext; /* SVGA_3D_CMD_INVALIDATE_GB_CONTEXT */ | ||
2274 | 2284 | ||
2275 | /* | 2285 | /* |
2276 | * Define a guest-backed shader. | 2286 | * Define a guest-backed shader. |
@@ -2281,7 +2291,8 @@ struct SVGA3dCmdDefineGBShader { | |||
2281 | uint32 shid; | 2291 | uint32 shid; |
2282 | SVGA3dShaderType type; | 2292 | SVGA3dShaderType type; |
2283 | uint32 sizeInBytes; | 2293 | uint32 sizeInBytes; |
2284 | } SVGA3dCmdDefineGBShader; /* SVGA_3D_CMD_DEFINE_GB_SHADER */ | 2294 | } __packed |
2295 | SVGA3dCmdDefineGBShader; /* SVGA_3D_CMD_DEFINE_GB_SHADER */ | ||
2285 | 2296 | ||
2286 | /* | 2297 | /* |
2287 | * Bind a guest-backed shader. | 2298 | * Bind a guest-backed shader. |
@@ -2291,7 +2302,8 @@ typedef struct SVGA3dCmdBindGBShader { | |||
2291 | uint32 shid; | 2302 | uint32 shid; |
2292 | SVGAMobId mobid; | 2303 | SVGAMobId mobid; |
2293 | uint32 offsetInBytes; | 2304 | uint32 offsetInBytes; |
2294 | } SVGA3dCmdBindGBShader; /* SVGA_3D_CMD_BIND_GB_SHADER */ | 2305 | } __packed |
2306 | SVGA3dCmdBindGBShader; /* SVGA_3D_CMD_BIND_GB_SHADER */ | ||
2295 | 2307 | ||
2296 | /* | 2308 | /* |
2297 | * Destroy a guest-backed shader. | 2309 | * Destroy a guest-backed shader. |
@@ -2299,7 +2311,8 @@ typedef struct SVGA3dCmdBindGBShader { | |||
2299 | 2311 | ||
2300 | typedef struct SVGA3dCmdDestroyGBShader { | 2312 | typedef struct SVGA3dCmdDestroyGBShader { |
2301 | uint32 shid; | 2313 | uint32 shid; |
2302 | } SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */ | 2314 | } __packed |
2315 | SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */ | ||
2303 | 2316 | ||
2304 | typedef | 2317 | typedef |
2305 | struct { | 2318 | struct { |
@@ -2314,14 +2327,16 @@ struct { | |||
2314 | * Note that FLOAT and INT constants are 4-dwords in length, while | 2327 | * Note that FLOAT and INT constants are 4-dwords in length, while |
2315 | * BOOL constants are 1-dword in length. | 2328 | * BOOL constants are 1-dword in length. |
2316 | */ | 2329 | */ |
2317 | } SVGA3dCmdSetGBShaderConstInline; | 2330 | } __packed |
2331 | SVGA3dCmdSetGBShaderConstInline; | ||
2318 | /* SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE */ | 2332 | /* SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE */ |
2319 | 2333 | ||
2320 | typedef | 2334 | typedef |
2321 | struct { | 2335 | struct { |
2322 | uint32 cid; | 2336 | uint32 cid; |
2323 | SVGA3dQueryType type; | 2337 | SVGA3dQueryType type; |
2324 | } SVGA3dCmdBeginGBQuery; /* SVGA_3D_CMD_BEGIN_GB_QUERY */ | 2338 | } __packed |
2339 | SVGA3dCmdBeginGBQuery; /* SVGA_3D_CMD_BEGIN_GB_QUERY */ | ||
2325 | 2340 | ||
2326 | typedef | 2341 | typedef |
2327 | struct { | 2342 | struct { |
@@ -2329,7 +2344,8 @@ struct { | |||
2329 | SVGA3dQueryType type; | 2344 | SVGA3dQueryType type; |
2330 | SVGAMobId mobid; | 2345 | SVGAMobId mobid; |
2331 | uint32 offset; | 2346 | uint32 offset; |
2332 | } SVGA3dCmdEndGBQuery; /* SVGA_3D_CMD_END_GB_QUERY */ | 2347 | } __packed |
2348 | SVGA3dCmdEndGBQuery; /* SVGA_3D_CMD_END_GB_QUERY */ | ||
2333 | 2349 | ||
2334 | 2350 | ||
2335 | /* | 2351 | /* |
@@ -2346,21 +2362,22 @@ struct { | |||
2346 | SVGA3dQueryType type; | 2362 | SVGA3dQueryType type; |
2347 | SVGAMobId mobid; | 2363 | SVGAMobId mobid; |
2348 | uint32 offset; | 2364 | uint32 offset; |
2349 | } SVGA3dCmdWaitForGBQuery; /* SVGA_3D_CMD_WAIT_FOR_GB_QUERY */ | 2365 | } __packed |
2366 | SVGA3dCmdWaitForGBQuery; /* SVGA_3D_CMD_WAIT_FOR_GB_QUERY */ | ||
2350 | 2367 | ||
2351 | typedef | 2368 | typedef |
2352 | struct { | 2369 | struct { |
2353 | SVGAMobId mobid; | 2370 | SVGAMobId mobid; |
2354 | uint32 fbOffset; | 2371 | uint32 fbOffset; |
2355 | uint32 initalized; | 2372 | uint32 initalized; |
2356 | } | 2373 | } __packed |
2357 | SVGA3dCmdEnableGart; /* SVGA_3D_CMD_ENABLE_GART */ | 2374 | SVGA3dCmdEnableGart; /* SVGA_3D_CMD_ENABLE_GART */ |
2358 | 2375 | ||
2359 | typedef | 2376 | typedef |
2360 | struct { | 2377 | struct { |
2361 | SVGAMobId mobid; | 2378 | SVGAMobId mobid; |
2362 | uint32 gartOffset; | 2379 | uint32 gartOffset; |
2363 | } | 2380 | } __packed |
2364 | SVGA3dCmdMapMobIntoGart; /* SVGA_3D_CMD_MAP_MOB_INTO_GART */ | 2381 | SVGA3dCmdMapMobIntoGart; /* SVGA_3D_CMD_MAP_MOB_INTO_GART */ |
2365 | 2382 | ||
2366 | 2383 | ||
@@ -2368,7 +2385,7 @@ typedef | |||
2368 | struct { | 2385 | struct { |
2369 | uint32 gartOffset; | 2386 | uint32 gartOffset; |
2370 | uint32 numPages; | 2387 | uint32 numPages; |
2371 | } | 2388 | } __packed |
2372 | SVGA3dCmdUnmapGartRange; /* SVGA_3D_CMD_UNMAP_GART_RANGE */ | 2389 | SVGA3dCmdUnmapGartRange; /* SVGA_3D_CMD_UNMAP_GART_RANGE */ |
2373 | 2390 | ||
2374 | 2391 | ||
@@ -2385,27 +2402,27 @@ struct { | |||
2385 | int32 xRoot; | 2402 | int32 xRoot; |
2386 | int32 yRoot; | 2403 | int32 yRoot; |
2387 | uint32 flags; | 2404 | uint32 flags; |
2388 | } | 2405 | } __packed |
2389 | SVGA3dCmdDefineGBScreenTarget; /* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET */ | 2406 | SVGA3dCmdDefineGBScreenTarget; /* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET */ |
2390 | 2407 | ||
2391 | typedef | 2408 | typedef |
2392 | struct { | 2409 | struct { |
2393 | uint32 stid; | 2410 | uint32 stid; |
2394 | } | 2411 | } __packed |
2395 | SVGA3dCmdDestroyGBScreenTarget; /* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET */ | 2412 | SVGA3dCmdDestroyGBScreenTarget; /* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET */ |
2396 | 2413 | ||
2397 | typedef | 2414 | typedef |
2398 | struct { | 2415 | struct { |
2399 | uint32 stid; | 2416 | uint32 stid; |
2400 | SVGA3dSurfaceImageId image; | 2417 | SVGA3dSurfaceImageId image; |
2401 | } | 2418 | } __packed |
2402 | SVGA3dCmdBindGBScreenTarget; /* SVGA_3D_CMD_BIND_GB_SCREENTARGET */ | 2419 | SVGA3dCmdBindGBScreenTarget; /* SVGA_3D_CMD_BIND_GB_SCREENTARGET */ |
2403 | 2420 | ||
2404 | typedef | 2421 | typedef |
2405 | struct { | 2422 | struct { |
2406 | uint32 stid; | 2423 | uint32 stid; |
2407 | SVGA3dBox box; | 2424 | SVGA3dBox box; |
2408 | } | 2425 | } __packed |
2409 | SVGA3dCmdUpdateGBScreenTarget; /* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET */ | 2426 | SVGA3dCmdUpdateGBScreenTarget; /* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET */ |
2410 | 2427 | ||
2411 | /* | 2428 | /* |
diff --git a/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h index 8369c3ba10fe..ef3385096145 100644 --- a/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h +++ b/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h | |||
@@ -38,8 +38,11 @@ | |||
38 | 38 | ||
39 | #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) | 39 | #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) |
40 | #define max_t(type, x, y) ((x) > (y) ? (x) : (y)) | 40 | #define max_t(type, x, y) ((x) > (y) ? (x) : (y)) |
41 | #define min_t(type, x, y) ((x) < (y) ? (x) : (y)) | ||
41 | #define surf_size_struct SVGA3dSize | 42 | #define surf_size_struct SVGA3dSize |
42 | #define u32 uint32 | 43 | #define u32 uint32 |
44 | #define u64 uint64_t | ||
45 | #define U32_MAX ((u32)~0U) | ||
43 | 46 | ||
44 | #endif /* __KERNEL__ */ | 47 | #endif /* __KERNEL__ */ |
45 | 48 | ||
@@ -704,8 +707,8 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { | |||
704 | 707 | ||
705 | static inline u32 clamped_umul32(u32 a, u32 b) | 708 | static inline u32 clamped_umul32(u32 a, u32 b) |
706 | { | 709 | { |
707 | uint64_t tmp = (uint64_t) a*b; | 710 | u64 tmp = (u64) a*b; |
708 | return (tmp > (uint64_t) ((u32) -1)) ? (u32) -1 : tmp; | 711 | return (tmp > (u64) U32_MAX) ? U32_MAX : tmp; |
709 | } | 712 | } |
710 | 713 | ||
711 | static inline const struct svga3d_surface_desc * | 714 | static inline const struct svga3d_surface_desc * |
@@ -834,7 +837,7 @@ svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format, | |||
834 | bool cubemap) | 837 | bool cubemap) |
835 | { | 838 | { |
836 | const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format); | 839 | const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format); |
837 | u32 total_size = 0; | 840 | u64 total_size = 0; |
838 | u32 mip; | 841 | u32 mip; |
839 | 842 | ||
840 | for (mip = 0; mip < num_mip_levels; mip++) { | 843 | for (mip = 0; mip < num_mip_levels; mip++) { |
@@ -847,7 +850,7 @@ svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format, | |||
847 | if (cubemap) | 850 | if (cubemap) |
848 | total_size *= SVGA3D_MAX_SURFACE_FACES; | 851 | total_size *= SVGA3D_MAX_SURFACE_FACES; |
849 | 852 | ||
850 | return total_size; | 853 | return (u32) min_t(u64, total_size, (u64) U32_MAX); |
851 | } | 854 | } |
852 | 855 | ||
853 | 856 | ||
diff --git a/drivers/gpu/drm/vmwgfx/svga_reg.h b/drivers/gpu/drm/vmwgfx/svga_reg.h index 71defa4d2d75..11323dd5196f 100644 --- a/drivers/gpu/drm/vmwgfx/svga_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga_reg.h | |||
@@ -169,10 +169,17 @@ enum { | |||
169 | SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ | 169 | SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ |
170 | SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */ | 170 | SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */ |
171 | SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */ | 171 | SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */ |
172 | SVGA_REG_COMMAND_LOW = 48, /* Lower 32 bits and submits commands */ | ||
173 | SVGA_REG_COMMAND_HIGH = 49, /* Upper 32 bits of command buffer PA */ | ||
172 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM = 50, /* Max primary memory */ | 174 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM = 50, /* Max primary memory */ |
173 | SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, /* Suggested limit on mob mem */ | 175 | SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, /* Suggested limit on mob mem */ |
174 | SVGA_REG_DEV_CAP = 52, /* Write dev cap index, read value */ | 176 | SVGA_REG_DEV_CAP = 52, /* Write dev cap index, read value */ |
175 | SVGA_REG_TOP = 53, /* Must be 1 more than the last register */ | 177 | SVGA_REG_CMD_PREPEND_LOW = 53, |
178 | SVGA_REG_CMD_PREPEND_HIGH = 54, | ||
179 | SVGA_REG_SCREENTARGET_MAX_WIDTH = 55, | ||
180 | SVGA_REG_SCREENTARGET_MAX_HEIGHT = 56, | ||
181 | SVGA_REG_MOB_MAX_SIZE = 57, | ||
182 | SVGA_REG_TOP = 58, /* Must be 1 more than the last register */ | ||
176 | 183 | ||
177 | SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ | 184 | SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ |
178 | /* Next 768 (== 256*3) registers exist for colormap */ | 185 | /* Next 768 (== 256*3) registers exist for colormap */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 9426c53fb483..1e80152674b5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c | |||
@@ -551,8 +551,7 @@ static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind) | |||
551 | cmd->header.size = sizeof(cmd->body); | 551 | cmd->header.size = sizeof(cmd->body); |
552 | cmd->body.cid = bi->ctx->id; | 552 | cmd->body.cid = bi->ctx->id; |
553 | cmd->body.type = bi->i1.shader_type; | 553 | cmd->body.type = bi->i1.shader_type; |
554 | cmd->body.shid = | 554 | cmd->body.shid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID); |
555 | cpu_to_le32((rebind) ? bi->res->id : SVGA3D_INVALID_ID); | ||
556 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 555 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
557 | 556 | ||
558 | return 0; | 557 | return 0; |
@@ -585,8 +584,7 @@ static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi, | |||
585 | cmd->header.size = sizeof(cmd->body); | 584 | cmd->header.size = sizeof(cmd->body); |
586 | cmd->body.cid = bi->ctx->id; | 585 | cmd->body.cid = bi->ctx->id; |
587 | cmd->body.type = bi->i1.rt_type; | 586 | cmd->body.type = bi->i1.rt_type; |
588 | cmd->body.target.sid = | 587 | cmd->body.target.sid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID); |
589 | cpu_to_le32((rebind) ? bi->res->id : SVGA3D_INVALID_ID); | ||
590 | cmd->body.target.face = 0; | 588 | cmd->body.target.face = 0; |
591 | cmd->body.target.mipmap = 0; | 589 | cmd->body.target.mipmap = 0; |
592 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 590 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
@@ -628,8 +626,7 @@ static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi, | |||
628 | cmd->body.c.cid = bi->ctx->id; | 626 | cmd->body.c.cid = bi->ctx->id; |
629 | cmd->body.s1.stage = bi->i1.texture_stage; | 627 | cmd->body.s1.stage = bi->i1.texture_stage; |
630 | cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE; | 628 | cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE; |
631 | cmd->body.s1.value = | 629 | cmd->body.s1.value = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID); |
632 | cpu_to_le32((rebind) ? bi->res->id : SVGA3D_INVALID_ID); | ||
633 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 630 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
634 | 631 | ||
635 | return 0; | 632 | return 0; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 3bdc0adc656d..0083cbf99edf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -667,6 +667,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
667 | dev_priv->memory_size = 512*1024*1024; | 667 | dev_priv->memory_size = 512*1024*1024; |
668 | } | 668 | } |
669 | dev_priv->max_mob_pages = 0; | 669 | dev_priv->max_mob_pages = 0; |
670 | dev_priv->max_mob_size = 0; | ||
670 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { | 671 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { |
671 | uint64_t mem_size = | 672 | uint64_t mem_size = |
672 | vmw_read(dev_priv, | 673 | vmw_read(dev_priv, |
@@ -676,6 +677,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
676 | dev_priv->prim_bb_mem = | 677 | dev_priv->prim_bb_mem = |
677 | vmw_read(dev_priv, | 678 | vmw_read(dev_priv, |
678 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); | 679 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); |
680 | dev_priv->max_mob_size = | ||
681 | vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE); | ||
679 | } else | 682 | } else |
680 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 683 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
681 | 684 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index ecaa302a6154..07831554dad7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <drm/ttm/ttm_module.h> | 40 | #include <drm/ttm/ttm_module.h> |
41 | #include "vmwgfx_fence.h" | 41 | #include "vmwgfx_fence.h" |
42 | 42 | ||
43 | #define VMWGFX_DRIVER_DATE "20121114" | 43 | #define VMWGFX_DRIVER_DATE "20140228" |
44 | #define VMWGFX_DRIVER_MAJOR 2 | 44 | #define VMWGFX_DRIVER_MAJOR 2 |
45 | #define VMWGFX_DRIVER_MINOR 5 | 45 | #define VMWGFX_DRIVER_MINOR 5 |
46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
@@ -386,6 +386,7 @@ struct vmw_private { | |||
386 | uint32_t max_gmr_ids; | 386 | uint32_t max_gmr_ids; |
387 | uint32_t max_gmr_pages; | 387 | uint32_t max_gmr_pages; |
388 | uint32_t max_mob_pages; | 388 | uint32_t max_mob_pages; |
389 | uint32_t max_mob_size; | ||
389 | uint32_t memory_size; | 390 | uint32_t memory_size; |
390 | bool has_gmr; | 391 | bool has_gmr; |
391 | bool has_mob; | 392 | bool has_mob; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 269b85cc875a..efb575a7996c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -602,7 +602,7 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, | |||
602 | { | 602 | { |
603 | struct vmw_cid_cmd { | 603 | struct vmw_cid_cmd { |
604 | SVGA3dCmdHeader header; | 604 | SVGA3dCmdHeader header; |
605 | __le32 cid; | 605 | uint32_t cid; |
606 | } *cmd; | 606 | } *cmd; |
607 | 607 | ||
608 | cmd = container_of(header, struct vmw_cid_cmd, header); | 608 | cmd = container_of(header, struct vmw_cid_cmd, header); |
@@ -1835,7 +1835,7 @@ static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, | |||
1835 | return 0; | 1835 | return 0; |
1836 | } | 1836 | } |
1837 | 1837 | ||
1838 | static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = { | 1838 | static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { |
1839 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid, | 1839 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid, |
1840 | false, false, false), | 1840 | false, false, false), |
1841 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid, | 1841 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid, |
@@ -2032,6 +2032,9 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, | |||
2032 | goto out_invalid; | 2032 | goto out_invalid; |
2033 | 2033 | ||
2034 | entry = &vmw_cmd_entries[cmd_id]; | 2034 | entry = &vmw_cmd_entries[cmd_id]; |
2035 | if (unlikely(!entry->func)) | ||
2036 | goto out_invalid; | ||
2037 | |||
2035 | if (unlikely(!entry->user_allow && !sw_context->kernel)) | 2038 | if (unlikely(!entry->user_allow && !sw_context->kernel)) |
2036 | goto out_privileged; | 2039 | goto out_privileged; |
2037 | 2040 | ||
@@ -2469,7 +2472,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2469 | if (dev_priv->has_mob) { | 2472 | if (dev_priv->has_mob) { |
2470 | ret = vmw_rebind_contexts(sw_context); | 2473 | ret = vmw_rebind_contexts(sw_context); |
2471 | if (unlikely(ret != 0)) | 2474 | if (unlikely(ret != 0)) |
2472 | goto out_err; | 2475 | goto out_unlock_binding; |
2473 | } | 2476 | } |
2474 | 2477 | ||
2475 | cmd = vmw_fifo_reserve(dev_priv, command_size); | 2478 | cmd = vmw_fifo_reserve(dev_priv, command_size); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index f9881f9e62bd..47b70949bf3a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -102,6 +102,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
102 | vmw_fp->gb_aware = true; | 102 | vmw_fp->gb_aware = true; |
103 | param->value = dev_priv->max_mob_pages * PAGE_SIZE; | 103 | param->value = dev_priv->max_mob_pages * PAGE_SIZE; |
104 | break; | 104 | break; |
105 | case DRM_VMW_PARAM_MAX_MOB_SIZE: | ||
106 | param->value = dev_priv->max_mob_size; | ||
107 | break; | ||
105 | default: | 108 | default: |
106 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", | 109 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", |
107 | param->param); | 110 | param->param); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index d4a5a19cb8c3..04a64b8cd3cd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | |||
@@ -188,18 +188,20 @@ static void vmw_takedown_otable_base(struct vmw_private *dev_priv, | |||
188 | 188 | ||
189 | bo = otable->page_table->pt_bo; | 189 | bo = otable->page_table->pt_bo; |
190 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 190 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
191 | if (unlikely(cmd == NULL)) | 191 | if (unlikely(cmd == NULL)) { |
192 | DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); | 192 | DRM_ERROR("Failed reserving FIFO space for OTable " |
193 | 193 | "takedown.\n"); | |
194 | memset(cmd, 0, sizeof(*cmd)); | 194 | } else { |
195 | cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; | 195 | memset(cmd, 0, sizeof(*cmd)); |
196 | cmd->header.size = sizeof(cmd->body); | 196 | cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; |
197 | cmd->body.type = type; | 197 | cmd->header.size = sizeof(cmd->body); |
198 | cmd->body.baseAddress = 0; | 198 | cmd->body.type = type; |
199 | cmd->body.sizeInBytes = 0; | 199 | cmd->body.baseAddress = 0; |
200 | cmd->body.validSizeInBytes = 0; | 200 | cmd->body.sizeInBytes = 0; |
201 | cmd->body.ptDepth = SVGA3D_MOBFMT_INVALID; | 201 | cmd->body.validSizeInBytes = 0; |
202 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 202 | cmd->body.ptDepth = SVGA3D_MOBFMT_INVALID; |
203 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
204 | } | ||
203 | 205 | ||
204 | if (bo) { | 206 | if (bo) { |
205 | int ret; | 207 | int ret; |
@@ -562,11 +564,12 @@ void vmw_mob_unbind(struct vmw_private *dev_priv, | |||
562 | if (unlikely(cmd == NULL)) { | 564 | if (unlikely(cmd == NULL)) { |
563 | DRM_ERROR("Failed reserving FIFO space for Memory " | 565 | DRM_ERROR("Failed reserving FIFO space for Memory " |
564 | "Object unbinding.\n"); | 566 | "Object unbinding.\n"); |
567 | } else { | ||
568 | cmd->header.id = SVGA_3D_CMD_DESTROY_GB_MOB; | ||
569 | cmd->header.size = sizeof(cmd->body); | ||
570 | cmd->body.mobid = mob->id; | ||
571 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
565 | } | 572 | } |
566 | cmd->header.id = SVGA_3D_CMD_DESTROY_GB_MOB; | ||
567 | cmd->header.size = sizeof(cmd->body); | ||
568 | cmd->body.mobid = mob->id; | ||
569 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
570 | if (bo) { | 573 | if (bo) { |
571 | vmw_fence_single_bo(bo, NULL); | 574 | vmw_fence_single_bo(bo, NULL); |
572 | ttm_bo_unreserve(bo); | 575 | ttm_bo_unreserve(bo); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 2aa4bc6a4d60..9757b57f8388 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -427,8 +427,7 @@ int vmw_dmabuf_init(struct vmw_private *dev_priv, | |||
427 | INIT_LIST_HEAD(&vmw_bo->res_list); | 427 | INIT_LIST_HEAD(&vmw_bo->res_list); |
428 | 428 | ||
429 | ret = ttm_bo_init(bdev, &vmw_bo->base, size, | 429 | ret = ttm_bo_init(bdev, &vmw_bo->base, size, |
430 | (user) ? ttm_bo_type_device : | 430 | ttm_bo_type_device, placement, |
431 | ttm_bo_type_kernel, placement, | ||
432 | 0, interruptible, | 431 | 0, interruptible, |
433 | NULL, acc_size, NULL, bo_free); | 432 | NULL, acc_size, NULL, bo_free); |
434 | return ret; | 433 | return ret; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index 217d941b8176..ee3856578a12 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | |||
@@ -371,13 +371,13 @@ int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, | |||
371 | TTM_REF_USAGE); | 371 | TTM_REF_USAGE); |
372 | } | 372 | } |
373 | 373 | ||
374 | int vmw_shader_alloc(struct vmw_private *dev_priv, | 374 | static int vmw_shader_alloc(struct vmw_private *dev_priv, |
375 | struct vmw_dma_buffer *buffer, | 375 | struct vmw_dma_buffer *buffer, |
376 | size_t shader_size, | 376 | size_t shader_size, |
377 | size_t offset, | 377 | size_t offset, |
378 | SVGA3dShaderType shader_type, | 378 | SVGA3dShaderType shader_type, |
379 | struct ttm_object_file *tfile, | 379 | struct ttm_object_file *tfile, |
380 | u32 *handle) | 380 | u32 *handle) |
381 | { | 381 | { |
382 | struct vmw_user_shader *ushader; | 382 | struct vmw_user_shader *ushader; |
383 | struct vmw_resource *res, *tmp; | 383 | struct vmw_resource *res, *tmp; |
@@ -779,6 +779,8 @@ vmw_compat_shader_man_create(struct vmw_private *dev_priv) | |||
779 | int ret; | 779 | int ret; |
780 | 780 | ||
781 | man = kzalloc(sizeof(*man), GFP_KERNEL); | 781 | man = kzalloc(sizeof(*man), GFP_KERNEL); |
782 | if (man == NULL) | ||
783 | return ERR_PTR(-ENOMEM); | ||
782 | 784 | ||
783 | man->dev_priv = dev_priv; | 785 | man->dev_priv = dev_priv; |
784 | INIT_LIST_HEAD(&man->list); | 786 | INIT_LIST_HEAD(&man->list); |
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index 1146e3bba6e1..112f27e51bc7 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c | |||
@@ -538,7 +538,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev) | |||
538 | 538 | ||
539 | g->base = job->gather_addr_phys[i]; | 539 | g->base = job->gather_addr_phys[i]; |
540 | 540 | ||
541 | for (j = 0; j < job->num_gathers; j++) | 541 | for (j = i + 1; j < job->num_gathers; j++) |
542 | if (job->gathers[j].bo == g->bo) | 542 | if (job->gathers[j].bo == g->bo) |
543 | job->gathers[j].handled = true; | 543 | job->gathers[j].handled = true; |
544 | 544 | ||
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 497558127bb3..f822fd2a1ada 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
@@ -469,6 +469,9 @@ static const struct hid_device_id apple_devices[] = { | |||
469 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 469 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
470 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 470 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
471 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 471 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
472 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
473 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS), | ||
474 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | ||
472 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), | 475 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
473 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 476 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
474 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 477 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3bfac3accd22..cc32a6f96c64 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1679,6 +1679,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1679 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1679 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
1680 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, | 1680 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, |
1681 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, | 1681 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, |
1682 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) }, | ||
1682 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1683 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1683 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1684 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1684 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | 1685 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
@@ -1779,6 +1780,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1779 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, | 1780 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, |
1780 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, | 1781 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, |
1781 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1782 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
1783 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2) }, | ||
1784 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2) }, | ||
1782 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1785 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1783 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1786 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
1784 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, | 1787 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, |
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 8fae6d1414cc..c24908f14934 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c | |||
@@ -157,6 +157,7 @@ struct mousevsc_dev { | |||
157 | u32 report_desc_size; | 157 | u32 report_desc_size; |
158 | struct hv_input_dev_info hid_dev_info; | 158 | struct hv_input_dev_info hid_dev_info; |
159 | struct hid_device *hid_device; | 159 | struct hid_device *hid_device; |
160 | u8 input_buf[HID_MAX_BUFFER_SIZE]; | ||
160 | }; | 161 | }; |
161 | 162 | ||
162 | 163 | ||
@@ -256,6 +257,7 @@ static void mousevsc_on_receive(struct hv_device *device, | |||
256 | struct synthhid_msg *hid_msg; | 257 | struct synthhid_msg *hid_msg; |
257 | struct mousevsc_dev *input_dev = hv_get_drvdata(device); | 258 | struct mousevsc_dev *input_dev = hv_get_drvdata(device); |
258 | struct synthhid_input_report *input_report; | 259 | struct synthhid_input_report *input_report; |
260 | size_t len; | ||
259 | 261 | ||
260 | pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet + | 262 | pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet + |
261 | (packet->offset8 << 3)); | 263 | (packet->offset8 << 3)); |
@@ -300,9 +302,12 @@ static void mousevsc_on_receive(struct hv_device *device, | |||
300 | (struct synthhid_input_report *)pipe_msg->data; | 302 | (struct synthhid_input_report *)pipe_msg->data; |
301 | if (!input_dev->init_complete) | 303 | if (!input_dev->init_complete) |
302 | break; | 304 | break; |
303 | hid_input_report(input_dev->hid_device, | 305 | |
304 | HID_INPUT_REPORT, input_report->buffer, | 306 | len = min(input_report->header.size, |
305 | input_report->header.size, 1); | 307 | (u32)sizeof(input_dev->input_buf)); |
308 | memcpy(input_dev->input_buf, input_report->buffer, len); | ||
309 | hid_input_report(input_dev->hid_device, HID_INPUT_REPORT, | ||
310 | input_dev->input_buf, len, 1); | ||
306 | break; | 311 | break; |
307 | default: | 312 | default: |
308 | pr_err("unsupported hid msg type - type %d len %d", | 313 | pr_err("unsupported hid msg type - type %d len %d", |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5a5248f2cc07..22f28d6b33a8 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -135,6 +135,7 @@ | |||
135 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b | 135 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b |
136 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 | 136 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 |
137 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 | 137 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 |
138 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257 | ||
138 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 | 139 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 |
139 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 | 140 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 |
140 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 | 141 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 |
@@ -240,6 +241,7 @@ | |||
240 | 241 | ||
241 | #define USB_VENDOR_ID_CYGNAL 0x10c4 | 242 | #define USB_VENDOR_ID_CYGNAL 0x10c4 |
242 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a | 243 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a |
244 | #define USB_DEVICE_ID_FOCALTECH_FTXXXX_MULTITOUCH 0x81b9 | ||
243 | 245 | ||
244 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI4713 0x8244 | 246 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI4713 0x8244 |
245 | 247 | ||
@@ -451,6 +453,9 @@ | |||
451 | #define USB_VENDOR_ID_INTEL_1 0x8087 | 453 | #define USB_VENDOR_ID_INTEL_1 0x8087 |
452 | #define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa | 454 | #define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa |
453 | 455 | ||
456 | #define USB_VENDOR_ID_STM_0 0x0483 | ||
457 | #define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1 | ||
458 | |||
454 | #define USB_VENDOR_ID_ION 0x15e4 | 459 | #define USB_VENDOR_ID_ION 0x15e4 |
455 | #define USB_DEVICE_ID_ICADE 0x0132 | 460 | #define USB_DEVICE_ID_ICADE 0x0132 |
456 | 461 | ||
@@ -619,6 +624,8 @@ | |||
619 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | 624 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 |
620 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 | 625 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 |
621 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c | 626 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c |
627 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | ||
628 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | ||
622 | 629 | ||
623 | #define USB_VENDOR_ID_MOJO 0x8282 | 630 | #define USB_VENDOR_ID_MOJO 0x8282 |
624 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 631 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
@@ -644,6 +651,7 @@ | |||
644 | 651 | ||
645 | #define USB_VENDOR_ID_NEXIO 0x1870 | 652 | #define USB_VENDOR_ID_NEXIO 0x1870 |
646 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d | 653 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d |
654 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750 0x0110 | ||
647 | 655 | ||
648 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 | 656 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 |
649 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 | 657 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d50e7313b171..a713e6211419 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -1178,7 +1178,7 @@ static void hidinput_led_worker(struct work_struct *work) | |||
1178 | 1178 | ||
1179 | /* fall back to generic raw-output-report */ | 1179 | /* fall back to generic raw-output-report */ |
1180 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 1180 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
1181 | buf = kmalloc(len, GFP_KERNEL); | 1181 | buf = hid_alloc_report_buf(report, GFP_KERNEL); |
1182 | if (!buf) | 1182 | if (!buf) |
1183 | return; | 1183 | return; |
1184 | 1184 | ||
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index c6ef6eed3091..404a3a8a82f1 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
@@ -208,6 +208,10 @@ static const struct hid_device_id ms_devices[] = { | |||
208 | .driver_data = MS_NOGET }, | 208 | .driver_data = MS_NOGET }, |
209 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), | 209 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
210 | .driver_data = MS_DUPLICATE_USAGES }, | 210 | .driver_data = MS_DUPLICATE_USAGES }, |
211 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), | ||
212 | .driver_data = 0 }, | ||
213 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), | ||
214 | .driver_data = 0 }, | ||
211 | 215 | ||
212 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), | 216 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), |
213 | .driver_data = MS_PRESENTER }, | 217 | .driver_data = MS_PRESENTER }, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index f134d73beca1..221d503f1c24 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1166,6 +1166,11 @@ static const struct hid_device_id mt_devices[] = { | |||
1166 | MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG, | 1166 | MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG, |
1167 | USB_DEVICE_ID_MULTITOUCH_3200) }, | 1167 | USB_DEVICE_ID_MULTITOUCH_3200) }, |
1168 | 1168 | ||
1169 | /* FocalTech Panels */ | ||
1170 | { .driver_data = MT_CLS_SERIAL, | ||
1171 | MT_USB_DEVICE(USB_VENDOR_ID_CYGNAL, | ||
1172 | USB_DEVICE_ID_FOCALTECH_FTXXXX_MULTITOUCH) }, | ||
1173 | |||
1169 | /* GeneralTouch panel */ | 1174 | /* GeneralTouch panel */ |
1170 | { .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS, | 1175 | { .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS, |
1171 | MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | 1176 | MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 46f4480035bc..9c22e14c57f0 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -665,6 +665,9 @@ static const struct hid_device_id sensor_hub_devices[] = { | |||
665 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, | 665 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, |
666 | USB_DEVICE_ID_INTEL_HID_SENSOR), | 666 | USB_DEVICE_ID_INTEL_HID_SENSOR), |
667 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | 667 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
668 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, | ||
669 | USB_DEVICE_ID_STM_HID_SENSOR), | ||
670 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
668 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, | 671 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
669 | HID_ANY_ID) }, | 672 | HID_ANY_ID) }, |
670 | { } | 673 | { } |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d1f81f52481a..42eebd14de1f 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -582,7 +582,7 @@ static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, | |||
582 | int ret; | 582 | int ret; |
583 | int len = i2c_hid_get_report_length(rep) - 2; | 583 | int len = i2c_hid_get_report_length(rep) - 2; |
584 | 584 | ||
585 | buf = kzalloc(len, GFP_KERNEL); | 585 | buf = hid_alloc_report_buf(rep, GFP_KERNEL); |
586 | if (!buf) | 586 | if (!buf) |
587 | return; | 587 | return; |
588 | 588 | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 175ec0afb70c..dbd83878ff99 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -74,6 +74,7 @@ static const struct hid_blacklist { | |||
74 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, | 74 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
75 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | 75 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
76 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, | 76 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
77 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, | ||
77 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | 78 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |
78 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, | 79 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
79 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, | 80 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c index a7626358c95d..029b65e6c589 100644 --- a/drivers/hwmon/max1668.c +++ b/drivers/hwmon/max1668.c | |||
@@ -243,7 +243,7 @@ static ssize_t set_temp_min(struct device *dev, | |||
243 | data->temp_min[index] = clamp_val(temp/1000, -128, 127); | 243 | data->temp_min[index] = clamp_val(temp/1000, -128, 127); |
244 | if (i2c_smbus_write_byte_data(client, | 244 | if (i2c_smbus_write_byte_data(client, |
245 | MAX1668_REG_LIML_WR(index), | 245 | MAX1668_REG_LIML_WR(index), |
246 | data->temp_max[index])) | 246 | data->temp_min[index])) |
247 | count = -EIO; | 247 | count = -EIO; |
248 | mutex_unlock(&data->update_lock); | 248 | mutex_unlock(&data->update_lock); |
249 | 249 | ||
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 41c64a43bcab..ac2d69e34c8c 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig | |||
@@ -70,7 +70,7 @@ config IIO_ST_GYRO_3AXIS | |||
70 | select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) | 70 | select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) |
71 | help | 71 | help |
72 | Say yes here to build support for STMicroelectronics gyroscopes: | 72 | Say yes here to build support for STMicroelectronics gyroscopes: |
73 | L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330. | 73 | L3G4200D, LSM330DL, L3GD20, LSM330DLC, L3G4IS, LSM330. |
74 | 74 | ||
75 | This driver can also be built as a module. If so, these modules | 75 | This driver can also be built as a module. If so, these modules |
76 | will be created: | 76 | will be created: |
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h index f8f2bf84a5a2..c197360c450b 100644 --- a/drivers/iio/gyro/st_gyro.h +++ b/drivers/iio/gyro/st_gyro.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro" | 19 | #define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro" |
20 | #define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro" | 20 | #define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro" |
21 | #define L3GD20_GYRO_DEV_NAME "l3gd20" | 21 | #define L3GD20_GYRO_DEV_NAME "l3gd20" |
22 | #define L3GD20H_GYRO_DEV_NAME "l3gd20h" | ||
23 | #define L3G4IS_GYRO_DEV_NAME "l3g4is_ui" | 22 | #define L3G4IS_GYRO_DEV_NAME "l3g4is_ui" |
24 | #define LSM330_GYRO_DEV_NAME "lsm330_gyro" | 23 | #define LSM330_GYRO_DEV_NAME "lsm330_gyro" |
25 | 24 | ||
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index d53d91adfb55..a8e174a47bc4 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c | |||
@@ -167,11 +167,10 @@ static const struct st_sensors st_gyro_sensors[] = { | |||
167 | .wai = ST_GYRO_2_WAI_EXP, | 167 | .wai = ST_GYRO_2_WAI_EXP, |
168 | .sensors_supported = { | 168 | .sensors_supported = { |
169 | [0] = L3GD20_GYRO_DEV_NAME, | 169 | [0] = L3GD20_GYRO_DEV_NAME, |
170 | [1] = L3GD20H_GYRO_DEV_NAME, | 170 | [1] = LSM330D_GYRO_DEV_NAME, |
171 | [2] = LSM330D_GYRO_DEV_NAME, | 171 | [2] = LSM330DLC_GYRO_DEV_NAME, |
172 | [3] = LSM330DLC_GYRO_DEV_NAME, | 172 | [3] = L3G4IS_GYRO_DEV_NAME, |
173 | [4] = L3G4IS_GYRO_DEV_NAME, | 173 | [4] = LSM330_GYRO_DEV_NAME, |
174 | [5] = LSM330_GYRO_DEV_NAME, | ||
175 | }, | 174 | }, |
176 | .ch = (struct iio_chan_spec *)st_gyro_16bit_channels, | 175 | .ch = (struct iio_chan_spec *)st_gyro_16bit_channels, |
177 | .odr = { | 176 | .odr = { |
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 16b8b8d70bf1..23c12f361b05 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c | |||
@@ -55,7 +55,6 @@ static const struct i2c_device_id st_gyro_id_table[] = { | |||
55 | { LSM330DL_GYRO_DEV_NAME }, | 55 | { LSM330DL_GYRO_DEV_NAME }, |
56 | { LSM330DLC_GYRO_DEV_NAME }, | 56 | { LSM330DLC_GYRO_DEV_NAME }, |
57 | { L3GD20_GYRO_DEV_NAME }, | 57 | { L3GD20_GYRO_DEV_NAME }, |
58 | { L3GD20H_GYRO_DEV_NAME }, | ||
59 | { L3G4IS_GYRO_DEV_NAME }, | 58 | { L3G4IS_GYRO_DEV_NAME }, |
60 | { LSM330_GYRO_DEV_NAME }, | 59 | { LSM330_GYRO_DEV_NAME }, |
61 | {}, | 60 | {}, |
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index 94763e25caf9..b4ad3be26687 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c | |||
@@ -54,7 +54,6 @@ static const struct spi_device_id st_gyro_id_table[] = { | |||
54 | { LSM330DL_GYRO_DEV_NAME }, | 54 | { LSM330DL_GYRO_DEV_NAME }, |
55 | { LSM330DLC_GYRO_DEV_NAME }, | 55 | { LSM330DLC_GYRO_DEV_NAME }, |
56 | { L3GD20_GYRO_DEV_NAME }, | 56 | { L3GD20_GYRO_DEV_NAME }, |
57 | { L3GD20H_GYRO_DEV_NAME }, | ||
58 | { L3G4IS_GYRO_DEV_NAME }, | 57 | { L3G4IS_GYRO_DEV_NAME }, |
59 | { LSM330_GYRO_DEV_NAME }, | 58 | { LSM330_GYRO_DEV_NAME }, |
60 | {}, | 59 | {}, |
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index f17b4e6183c6..47a6dbac2d0c 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c | |||
@@ -103,13 +103,13 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181) | |||
103 | /** | 103 | /** |
104 | * cm32181_read_als_it() - Get sensor integration time (ms) | 104 | * cm32181_read_als_it() - Get sensor integration time (ms) |
105 | * @cm32181: pointer of struct cm32181 | 105 | * @cm32181: pointer of struct cm32181 |
106 | * @val: pointer of int to load the als_it value. | 106 | * @val2: pointer of int to load the als_it value. |
107 | * | 107 | * |
108 | * Report the current integartion time by millisecond. | 108 | * Report the current integartion time by millisecond. |
109 | * | 109 | * |
110 | * Return: IIO_VAL_INT for success, otherwise -EINVAL. | 110 | * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL. |
111 | */ | 111 | */ |
112 | static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val) | 112 | static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2) |
113 | { | 113 | { |
114 | u16 als_it; | 114 | u16 als_it; |
115 | int i; | 115 | int i; |
@@ -119,8 +119,8 @@ static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val) | |||
119 | als_it >>= CM32181_CMD_ALS_IT_SHIFT; | 119 | als_it >>= CM32181_CMD_ALS_IT_SHIFT; |
120 | for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) { | 120 | for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) { |
121 | if (als_it == als_it_bits[i]) { | 121 | if (als_it == als_it_bits[i]) { |
122 | *val = als_it_value[i]; | 122 | *val2 = als_it_value[i]; |
123 | return IIO_VAL_INT; | 123 | return IIO_VAL_INT_PLUS_MICRO; |
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
@@ -221,7 +221,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev, | |||
221 | *val = cm32181->calibscale; | 221 | *val = cm32181->calibscale; |
222 | return IIO_VAL_INT; | 222 | return IIO_VAL_INT; |
223 | case IIO_CHAN_INFO_INT_TIME: | 223 | case IIO_CHAN_INFO_INT_TIME: |
224 | ret = cm32181_read_als_it(cm32181, val); | 224 | ret = cm32181_read_als_it(cm32181, val2); |
225 | return ret; | 225 | return ret; |
226 | } | 226 | } |
227 | 227 | ||
@@ -240,7 +240,7 @@ static int cm32181_write_raw(struct iio_dev *indio_dev, | |||
240 | cm32181->calibscale = val; | 240 | cm32181->calibscale = val; |
241 | return val; | 241 | return val; |
242 | case IIO_CHAN_INFO_INT_TIME: | 242 | case IIO_CHAN_INFO_INT_TIME: |
243 | ret = cm32181_write_als_it(cm32181, val); | 243 | ret = cm32181_write_als_it(cm32181, val2); |
244 | return ret; | 244 | return ret; |
245 | } | 245 | } |
246 | 246 | ||
@@ -264,7 +264,7 @@ static ssize_t cm32181_get_it_available(struct device *dev, | |||
264 | 264 | ||
265 | n = ARRAY_SIZE(als_it_value); | 265 | n = ARRAY_SIZE(als_it_value); |
266 | for (i = 0, len = 0; i < n; i++) | 266 | for (i = 0, len = 0; i < n; i++) |
267 | len += sprintf(buf + len, "%d ", als_it_value[i]); | 267 | len += sprintf(buf + len, "0.%06u ", als_it_value[i]); |
268 | return len + sprintf(buf + len, "\n"); | 268 | return len + sprintf(buf + len, "\n"); |
269 | } | 269 | } |
270 | 270 | ||
diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 0a142af83e25..a45e07492db3 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c | |||
@@ -50,10 +50,10 @@ | |||
50 | #define CM36651_CS_CONF2_DEFAULT_BIT 0x08 | 50 | #define CM36651_CS_CONF2_DEFAULT_BIT 0x08 |
51 | 51 | ||
52 | /* CS_CONF3 channel integration time */ | 52 | /* CS_CONF3 channel integration time */ |
53 | #define CM36651_CS_IT1 0x00 /* Integration time 80000 usec */ | 53 | #define CM36651_CS_IT1 0x00 /* Integration time 80 msec */ |
54 | #define CM36651_CS_IT2 0x40 /* Integration time 160000 usec */ | 54 | #define CM36651_CS_IT2 0x40 /* Integration time 160 msec */ |
55 | #define CM36651_CS_IT3 0x80 /* Integration time 320000 usec */ | 55 | #define CM36651_CS_IT3 0x80 /* Integration time 320 msec */ |
56 | #define CM36651_CS_IT4 0xC0 /* Integration time 640000 usec */ | 56 | #define CM36651_CS_IT4 0xC0 /* Integration time 640 msec */ |
57 | 57 | ||
58 | /* PS_CONF1 command code */ | 58 | /* PS_CONF1 command code */ |
59 | #define CM36651_PS_ENABLE 0x00 | 59 | #define CM36651_PS_ENABLE 0x00 |
@@ -64,10 +64,10 @@ | |||
64 | #define CM36651_PS_PERS4 0x0C | 64 | #define CM36651_PS_PERS4 0x0C |
65 | 65 | ||
66 | /* PS_CONF1 command code: integration time */ | 66 | /* PS_CONF1 command code: integration time */ |
67 | #define CM36651_PS_IT1 0x00 /* Integration time 320 usec */ | 67 | #define CM36651_PS_IT1 0x00 /* Integration time 0.32 msec */ |
68 | #define CM36651_PS_IT2 0x10 /* Integration time 420 usec */ | 68 | #define CM36651_PS_IT2 0x10 /* Integration time 0.42 msec */ |
69 | #define CM36651_PS_IT3 0x20 /* Integration time 520 usec */ | 69 | #define CM36651_PS_IT3 0x20 /* Integration time 0.52 msec */ |
70 | #define CM36651_PS_IT4 0x30 /* Integration time 640 usec */ | 70 | #define CM36651_PS_IT4 0x30 /* Integration time 0.64 msec */ |
71 | 71 | ||
72 | /* PS_CONF1 command code: duty ratio */ | 72 | /* PS_CONF1 command code: duty ratio */ |
73 | #define CM36651_PS_DR1 0x00 /* Duty ratio 1/80 */ | 73 | #define CM36651_PS_DR1 0x00 /* Duty ratio 1/80 */ |
@@ -93,8 +93,8 @@ | |||
93 | #define CM36651_CLOSE_PROXIMITY 0x32 | 93 | #define CM36651_CLOSE_PROXIMITY 0x32 |
94 | #define CM36651_FAR_PROXIMITY 0x33 | 94 | #define CM36651_FAR_PROXIMITY 0x33 |
95 | 95 | ||
96 | #define CM36651_CS_INT_TIME_AVAIL "80000 160000 320000 640000" | 96 | #define CM36651_CS_INT_TIME_AVAIL "0.08 0.16 0.32 0.64" |
97 | #define CM36651_PS_INT_TIME_AVAIL "320 420 520 640" | 97 | #define CM36651_PS_INT_TIME_AVAIL "0.000320 0.000420 0.000520 0.000640" |
98 | 98 | ||
99 | enum cm36651_operation_mode { | 99 | enum cm36651_operation_mode { |
100 | CM36651_LIGHT_EN, | 100 | CM36651_LIGHT_EN, |
@@ -356,30 +356,30 @@ static int cm36651_read_channel(struct cm36651_data *cm36651, | |||
356 | } | 356 | } |
357 | 357 | ||
358 | static int cm36651_read_int_time(struct cm36651_data *cm36651, | 358 | static int cm36651_read_int_time(struct cm36651_data *cm36651, |
359 | struct iio_chan_spec const *chan, int *val) | 359 | struct iio_chan_spec const *chan, int *val2) |
360 | { | 360 | { |
361 | switch (chan->type) { | 361 | switch (chan->type) { |
362 | case IIO_LIGHT: | 362 | case IIO_LIGHT: |
363 | if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1) | 363 | if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1) |
364 | *val = 80000; | 364 | *val2 = 80000; |
365 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2) | 365 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2) |
366 | *val = 160000; | 366 | *val2 = 160000; |
367 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3) | 367 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3) |
368 | *val = 320000; | 368 | *val2 = 320000; |
369 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4) | 369 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4) |
370 | *val = 640000; | 370 | *val2 = 640000; |
371 | else | 371 | else |
372 | return -EINVAL; | 372 | return -EINVAL; |
373 | break; | 373 | break; |
374 | case IIO_PROXIMITY: | 374 | case IIO_PROXIMITY: |
375 | if (cm36651->ps_int_time == CM36651_PS_IT1) | 375 | if (cm36651->ps_int_time == CM36651_PS_IT1) |
376 | *val = 320; | 376 | *val2 = 320; |
377 | else if (cm36651->ps_int_time == CM36651_PS_IT2) | 377 | else if (cm36651->ps_int_time == CM36651_PS_IT2) |
378 | *val = 420; | 378 | *val2 = 420; |
379 | else if (cm36651->ps_int_time == CM36651_PS_IT3) | 379 | else if (cm36651->ps_int_time == CM36651_PS_IT3) |
380 | *val = 520; | 380 | *val2 = 520; |
381 | else if (cm36651->ps_int_time == CM36651_PS_IT4) | 381 | else if (cm36651->ps_int_time == CM36651_PS_IT4) |
382 | *val = 640; | 382 | *val2 = 640; |
383 | else | 383 | else |
384 | return -EINVAL; | 384 | return -EINVAL; |
385 | break; | 385 | break; |
@@ -387,7 +387,7 @@ static int cm36651_read_int_time(struct cm36651_data *cm36651, | |||
387 | return -EINVAL; | 387 | return -EINVAL; |
388 | } | 388 | } |
389 | 389 | ||
390 | return IIO_VAL_INT; | 390 | return IIO_VAL_INT_PLUS_MICRO; |
391 | } | 391 | } |
392 | 392 | ||
393 | static int cm36651_write_int_time(struct cm36651_data *cm36651, | 393 | static int cm36651_write_int_time(struct cm36651_data *cm36651, |
@@ -459,7 +459,8 @@ static int cm36651_read_raw(struct iio_dev *indio_dev, | |||
459 | ret = cm36651_read_channel(cm36651, chan, val); | 459 | ret = cm36651_read_channel(cm36651, chan, val); |
460 | break; | 460 | break; |
461 | case IIO_CHAN_INFO_INT_TIME: | 461 | case IIO_CHAN_INFO_INT_TIME: |
462 | ret = cm36651_read_int_time(cm36651, chan, val); | 462 | *val = 0; |
463 | ret = cm36651_read_int_time(cm36651, chan, val2); | ||
463 | break; | 464 | break; |
464 | default: | 465 | default: |
465 | ret = -EINVAL; | 466 | ret = -EINVAL; |
@@ -479,7 +480,7 @@ static int cm36651_write_raw(struct iio_dev *indio_dev, | |||
479 | int ret = -EINVAL; | 480 | int ret = -EINVAL; |
480 | 481 | ||
481 | if (mask == IIO_CHAN_INFO_INT_TIME) { | 482 | if (mask == IIO_CHAN_INFO_INT_TIME) { |
482 | ret = cm36651_write_int_time(cm36651, chan, val); | 483 | ret = cm36651_write_int_time(cm36651, chan, val2); |
483 | if (ret < 0) | 484 | if (ret < 0) |
484 | dev_err(&client->dev, "Integration time write failed\n"); | 485 | dev_err(&client->dev, "Integration time write failed\n"); |
485 | } | 486 | } |
diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index 7a04f54ef961..ef2e281b0a43 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c | |||
@@ -37,7 +37,6 @@ static void arizona_haptics_work(struct work_struct *work) | |||
37 | struct arizona_haptics, | 37 | struct arizona_haptics, |
38 | work); | 38 | work); |
39 | struct arizona *arizona = haptics->arizona; | 39 | struct arizona *arizona = haptics->arizona; |
40 | struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex; | ||
41 | int ret; | 40 | int ret; |
42 | 41 | ||
43 | if (!haptics->arizona->dapm) { | 42 | if (!haptics->arizona->dapm) { |
@@ -67,13 +66,10 @@ static void arizona_haptics_work(struct work_struct *work) | |||
67 | return; | 66 | return; |
68 | } | 67 | } |
69 | 68 | ||
70 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
71 | |||
72 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); | 69 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); |
73 | if (ret != 0) { | 70 | if (ret != 0) { |
74 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", | 71 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", |
75 | ret); | 72 | ret); |
76 | mutex_unlock(dapm_mutex); | ||
77 | return; | 73 | return; |
78 | } | 74 | } |
79 | 75 | ||
@@ -81,21 +77,14 @@ static void arizona_haptics_work(struct work_struct *work) | |||
81 | if (ret != 0) { | 77 | if (ret != 0) { |
82 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | 78 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", |
83 | ret); | 79 | ret); |
84 | mutex_unlock(dapm_mutex); | ||
85 | return; | 80 | return; |
86 | } | 81 | } |
87 | |||
88 | mutex_unlock(dapm_mutex); | ||
89 | |||
90 | } else { | 82 | } else { |
91 | /* This disable sequence will be a noop if already enabled */ | 83 | /* This disable sequence will be a noop if already enabled */ |
92 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
93 | |||
94 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); | 84 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); |
95 | if (ret != 0) { | 85 | if (ret != 0) { |
96 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", | 86 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", |
97 | ret); | 87 | ret); |
98 | mutex_unlock(dapm_mutex); | ||
99 | return; | 88 | return; |
100 | } | 89 | } |
101 | 90 | ||
@@ -103,12 +92,9 @@ static void arizona_haptics_work(struct work_struct *work) | |||
103 | if (ret != 0) { | 92 | if (ret != 0) { |
104 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | 93 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", |
105 | ret); | 94 | ret); |
106 | mutex_unlock(dapm_mutex); | ||
107 | return; | 95 | return; |
108 | } | 96 | } |
109 | 97 | ||
110 | mutex_unlock(dapm_mutex); | ||
111 | |||
112 | ret = regmap_update_bits(arizona->regmap, | 98 | ret = regmap_update_bits(arizona->regmap, |
113 | ARIZONA_HAPTICS_CONTROL_1, | 99 | ARIZONA_HAPTICS_CONTROL_1, |
114 | ARIZONA_HAP_CTRL_MASK, | 100 | ARIZONA_HAP_CTRL_MASK, |
@@ -155,16 +141,11 @@ static int arizona_haptics_play(struct input_dev *input, void *data, | |||
155 | static void arizona_haptics_close(struct input_dev *input) | 141 | static void arizona_haptics_close(struct input_dev *input) |
156 | { | 142 | { |
157 | struct arizona_haptics *haptics = input_get_drvdata(input); | 143 | struct arizona_haptics *haptics = input_get_drvdata(input); |
158 | struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex; | ||
159 | 144 | ||
160 | cancel_work_sync(&haptics->work); | 145 | cancel_work_sync(&haptics->work); |
161 | 146 | ||
162 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
163 | |||
164 | if (haptics->arizona->dapm) | 147 | if (haptics->arizona->dapm) |
165 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); | 148 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); |
166 | |||
167 | mutex_unlock(dapm_mutex); | ||
168 | } | 149 | } |
169 | 150 | ||
170 | static int arizona_haptics_probe(struct platform_device *pdev) | 151 | static int arizona_haptics_probe(struct platform_device *pdev) |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 8911850c9444..1d9ab39af29f 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -79,7 +79,6 @@ | |||
79 | 79 | ||
80 | #define ARM_SMMU_PTE_CONT_SIZE (PAGE_SIZE * ARM_SMMU_PTE_CONT_ENTRIES) | 80 | #define ARM_SMMU_PTE_CONT_SIZE (PAGE_SIZE * ARM_SMMU_PTE_CONT_ENTRIES) |
81 | #define ARM_SMMU_PTE_CONT_MASK (~(ARM_SMMU_PTE_CONT_SIZE - 1)) | 81 | #define ARM_SMMU_PTE_CONT_MASK (~(ARM_SMMU_PTE_CONT_SIZE - 1)) |
82 | #define ARM_SMMU_PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(pte_t)) | ||
83 | 82 | ||
84 | /* Stage-1 PTE */ | 83 | /* Stage-1 PTE */ |
85 | #define ARM_SMMU_PTE_AP_UNPRIV (((pteval_t)1) << 6) | 84 | #define ARM_SMMU_PTE_AP_UNPRIV (((pteval_t)1) << 6) |
@@ -191,6 +190,9 @@ | |||
191 | #define ARM_SMMU_GR1_CBAR(n) (0x0 + ((n) << 2)) | 190 | #define ARM_SMMU_GR1_CBAR(n) (0x0 + ((n) << 2)) |
192 | #define CBAR_VMID_SHIFT 0 | 191 | #define CBAR_VMID_SHIFT 0 |
193 | #define CBAR_VMID_MASK 0xff | 192 | #define CBAR_VMID_MASK 0xff |
193 | #define CBAR_S1_BPSHCFG_SHIFT 8 | ||
194 | #define CBAR_S1_BPSHCFG_MASK 3 | ||
195 | #define CBAR_S1_BPSHCFG_NSH 3 | ||
194 | #define CBAR_S1_MEMATTR_SHIFT 12 | 196 | #define CBAR_S1_MEMATTR_SHIFT 12 |
195 | #define CBAR_S1_MEMATTR_MASK 0xf | 197 | #define CBAR_S1_MEMATTR_MASK 0xf |
196 | #define CBAR_S1_MEMATTR_WB 0xf | 198 | #define CBAR_S1_MEMATTR_WB 0xf |
@@ -393,7 +395,7 @@ struct arm_smmu_domain { | |||
393 | struct arm_smmu_cfg root_cfg; | 395 | struct arm_smmu_cfg root_cfg; |
394 | phys_addr_t output_mask; | 396 | phys_addr_t output_mask; |
395 | 397 | ||
396 | struct mutex lock; | 398 | spinlock_t lock; |
397 | }; | 399 | }; |
398 | 400 | ||
399 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); | 401 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); |
@@ -632,6 +634,28 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev) | |||
632 | return IRQ_HANDLED; | 634 | return IRQ_HANDLED; |
633 | } | 635 | } |
634 | 636 | ||
637 | static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr, | ||
638 | size_t size) | ||
639 | { | ||
640 | unsigned long offset = (unsigned long)addr & ~PAGE_MASK; | ||
641 | |||
642 | |||
643 | /* Ensure new page tables are visible to the hardware walker */ | ||
644 | if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) { | ||
645 | dsb(); | ||
646 | } else { | ||
647 | /* | ||
648 | * If the SMMU can't walk tables in the CPU caches, treat them | ||
649 | * like non-coherent DMA since we need to flush the new entries | ||
650 | * all the way out to memory. There's no possibility of | ||
651 | * recursion here as the SMMU table walker will not be wired | ||
652 | * through another SMMU. | ||
653 | */ | ||
654 | dma_map_page(smmu->dev, virt_to_page(addr), offset, size, | ||
655 | DMA_TO_DEVICE); | ||
656 | } | ||
657 | } | ||
658 | |||
635 | static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | 659 | static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) |
636 | { | 660 | { |
637 | u32 reg; | 661 | u32 reg; |
@@ -650,11 +674,16 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
650 | if (smmu->version == 1) | 674 | if (smmu->version == 1) |
651 | reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT; | 675 | reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT; |
652 | 676 | ||
653 | /* Use the weakest memory type, so it is overridden by the pte */ | 677 | /* |
654 | if (stage1) | 678 | * Use the weakest shareability/memory types, so they are |
655 | reg |= (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); | 679 | * overridden by the ttbcr/pte. |
656 | else | 680 | */ |
681 | if (stage1) { | ||
682 | reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) | | ||
683 | (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); | ||
684 | } else { | ||
657 | reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT; | 685 | reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT; |
686 | } | ||
658 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx)); | 687 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx)); |
659 | 688 | ||
660 | if (smmu->version > 1) { | 689 | if (smmu->version > 1) { |
@@ -715,6 +744,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
715 | } | 744 | } |
716 | 745 | ||
717 | /* TTBR0 */ | 746 | /* TTBR0 */ |
747 | arm_smmu_flush_pgtable(smmu, root_cfg->pgd, | ||
748 | PTRS_PER_PGD * sizeof(pgd_t)); | ||
718 | reg = __pa(root_cfg->pgd); | 749 | reg = __pa(root_cfg->pgd); |
719 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); | 750 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); |
720 | reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32; | 751 | reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32; |
@@ -901,7 +932,7 @@ static int arm_smmu_domain_init(struct iommu_domain *domain) | |||
901 | goto out_free_domain; | 932 | goto out_free_domain; |
902 | smmu_domain->root_cfg.pgd = pgd; | 933 | smmu_domain->root_cfg.pgd = pgd; |
903 | 934 | ||
904 | mutex_init(&smmu_domain->lock); | 935 | spin_lock_init(&smmu_domain->lock); |
905 | domain->priv = smmu_domain; | 936 | domain->priv = smmu_domain; |
906 | return 0; | 937 | return 0; |
907 | 938 | ||
@@ -1128,6 +1159,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1128 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1159 | struct arm_smmu_domain *smmu_domain = domain->priv; |
1129 | struct arm_smmu_device *device_smmu = dev->archdata.iommu; | 1160 | struct arm_smmu_device *device_smmu = dev->archdata.iommu; |
1130 | struct arm_smmu_master *master; | 1161 | struct arm_smmu_master *master; |
1162 | unsigned long flags; | ||
1131 | 1163 | ||
1132 | if (!device_smmu) { | 1164 | if (!device_smmu) { |
1133 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); | 1165 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); |
@@ -1138,7 +1170,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1138 | * Sanity check the domain. We don't currently support domains | 1170 | * Sanity check the domain. We don't currently support domains |
1139 | * that cross between different SMMU chains. | 1171 | * that cross between different SMMU chains. |
1140 | */ | 1172 | */ |
1141 | mutex_lock(&smmu_domain->lock); | 1173 | spin_lock_irqsave(&smmu_domain->lock, flags); |
1142 | if (!smmu_domain->leaf_smmu) { | 1174 | if (!smmu_domain->leaf_smmu) { |
1143 | /* Now that we have a master, we can finalise the domain */ | 1175 | /* Now that we have a master, we can finalise the domain */ |
1144 | ret = arm_smmu_init_domain_context(domain, dev); | 1176 | ret = arm_smmu_init_domain_context(domain, dev); |
@@ -1153,7 +1185,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1153 | dev_name(device_smmu->dev)); | 1185 | dev_name(device_smmu->dev)); |
1154 | goto err_unlock; | 1186 | goto err_unlock; |
1155 | } | 1187 | } |
1156 | mutex_unlock(&smmu_domain->lock); | 1188 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
1157 | 1189 | ||
1158 | /* Looks ok, so add the device to the domain */ | 1190 | /* Looks ok, so add the device to the domain */ |
1159 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); | 1191 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); |
@@ -1163,7 +1195,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1163 | return arm_smmu_domain_add_master(smmu_domain, master); | 1195 | return arm_smmu_domain_add_master(smmu_domain, master); |
1164 | 1196 | ||
1165 | err_unlock: | 1197 | err_unlock: |
1166 | mutex_unlock(&smmu_domain->lock); | 1198 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
1167 | return ret; | 1199 | return ret; |
1168 | } | 1200 | } |
1169 | 1201 | ||
@@ -1177,23 +1209,6 @@ static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) | |||
1177 | arm_smmu_domain_remove_master(smmu_domain, master); | 1209 | arm_smmu_domain_remove_master(smmu_domain, master); |
1178 | } | 1210 | } |
1179 | 1211 | ||
1180 | static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr, | ||
1181 | size_t size) | ||
1182 | { | ||
1183 | unsigned long offset = (unsigned long)addr & ~PAGE_MASK; | ||
1184 | |||
1185 | /* | ||
1186 | * If the SMMU can't walk tables in the CPU caches, treat them | ||
1187 | * like non-coherent DMA since we need to flush the new entries | ||
1188 | * all the way out to memory. There's no possibility of recursion | ||
1189 | * here as the SMMU table walker will not be wired through another | ||
1190 | * SMMU. | ||
1191 | */ | ||
1192 | if (!(smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)) | ||
1193 | dma_map_page(smmu->dev, virt_to_page(addr), offset, size, | ||
1194 | DMA_TO_DEVICE); | ||
1195 | } | ||
1196 | |||
1197 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, | 1212 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, |
1198 | unsigned long end) | 1213 | unsigned long end) |
1199 | { | 1214 | { |
@@ -1210,12 +1225,11 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, | |||
1210 | 1225 | ||
1211 | if (pmd_none(*pmd)) { | 1226 | if (pmd_none(*pmd)) { |
1212 | /* Allocate a new set of tables */ | 1227 | /* Allocate a new set of tables */ |
1213 | pgtable_t table = alloc_page(PGALLOC_GFP); | 1228 | pgtable_t table = alloc_page(GFP_ATOMIC|__GFP_ZERO); |
1214 | if (!table) | 1229 | if (!table) |
1215 | return -ENOMEM; | 1230 | return -ENOMEM; |
1216 | 1231 | ||
1217 | arm_smmu_flush_pgtable(smmu, page_address(table), | 1232 | arm_smmu_flush_pgtable(smmu, page_address(table), PAGE_SIZE); |
1218 | ARM_SMMU_PTE_HWTABLE_SIZE); | ||
1219 | if (!pgtable_page_ctor(table)) { | 1233 | if (!pgtable_page_ctor(table)) { |
1220 | __free_page(table); | 1234 | __free_page(table); |
1221 | return -ENOMEM; | 1235 | return -ENOMEM; |
@@ -1317,9 +1331,15 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud, | |||
1317 | 1331 | ||
1318 | #ifndef __PAGETABLE_PMD_FOLDED | 1332 | #ifndef __PAGETABLE_PMD_FOLDED |
1319 | if (pud_none(*pud)) { | 1333 | if (pud_none(*pud)) { |
1320 | pmd = pmd_alloc_one(NULL, addr); | 1334 | pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC); |
1321 | if (!pmd) | 1335 | if (!pmd) |
1322 | return -ENOMEM; | 1336 | return -ENOMEM; |
1337 | |||
1338 | arm_smmu_flush_pgtable(smmu, pmd, PAGE_SIZE); | ||
1339 | pud_populate(NULL, pud, pmd); | ||
1340 | arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud)); | ||
1341 | |||
1342 | pmd += pmd_index(addr); | ||
1323 | } else | 1343 | } else |
1324 | #endif | 1344 | #endif |
1325 | pmd = pmd_offset(pud, addr); | 1345 | pmd = pmd_offset(pud, addr); |
@@ -1328,8 +1348,6 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud, | |||
1328 | next = pmd_addr_end(addr, end); | 1348 | next = pmd_addr_end(addr, end); |
1329 | ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn, | 1349 | ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn, |
1330 | flags, stage); | 1350 | flags, stage); |
1331 | pud_populate(NULL, pud, pmd); | ||
1332 | arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud)); | ||
1333 | phys += next - addr; | 1351 | phys += next - addr; |
1334 | } while (pmd++, addr = next, addr < end); | 1352 | } while (pmd++, addr = next, addr < end); |
1335 | 1353 | ||
@@ -1346,9 +1364,15 @@ static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd, | |||
1346 | 1364 | ||
1347 | #ifndef __PAGETABLE_PUD_FOLDED | 1365 | #ifndef __PAGETABLE_PUD_FOLDED |
1348 | if (pgd_none(*pgd)) { | 1366 | if (pgd_none(*pgd)) { |
1349 | pud = pud_alloc_one(NULL, addr); | 1367 | pud = (pud_t *)get_zeroed_page(GFP_ATOMIC); |
1350 | if (!pud) | 1368 | if (!pud) |
1351 | return -ENOMEM; | 1369 | return -ENOMEM; |
1370 | |||
1371 | arm_smmu_flush_pgtable(smmu, pud, PAGE_SIZE); | ||
1372 | pgd_populate(NULL, pgd, pud); | ||
1373 | arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd)); | ||
1374 | |||
1375 | pud += pud_index(addr); | ||
1352 | } else | 1376 | } else |
1353 | #endif | 1377 | #endif |
1354 | pud = pud_offset(pgd, addr); | 1378 | pud = pud_offset(pgd, addr); |
@@ -1357,8 +1381,6 @@ static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd, | |||
1357 | next = pud_addr_end(addr, end); | 1381 | next = pud_addr_end(addr, end); |
1358 | ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys, | 1382 | ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys, |
1359 | flags, stage); | 1383 | flags, stage); |
1360 | pgd_populate(NULL, pud, pgd); | ||
1361 | arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd)); | ||
1362 | phys += next - addr; | 1384 | phys += next - addr; |
1363 | } while (pud++, addr = next, addr < end); | 1385 | } while (pud++, addr = next, addr < end); |
1364 | 1386 | ||
@@ -1375,6 +1397,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
1375 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 1397 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; |
1376 | pgd_t *pgd = root_cfg->pgd; | 1398 | pgd_t *pgd = root_cfg->pgd; |
1377 | struct arm_smmu_device *smmu = root_cfg->smmu; | 1399 | struct arm_smmu_device *smmu = root_cfg->smmu; |
1400 | unsigned long irqflags; | ||
1378 | 1401 | ||
1379 | if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) { | 1402 | if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) { |
1380 | stage = 2; | 1403 | stage = 2; |
@@ -1397,7 +1420,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
1397 | if (paddr & ~output_mask) | 1420 | if (paddr & ~output_mask) |
1398 | return -ERANGE; | 1421 | return -ERANGE; |
1399 | 1422 | ||
1400 | mutex_lock(&smmu_domain->lock); | 1423 | spin_lock_irqsave(&smmu_domain->lock, irqflags); |
1401 | pgd += pgd_index(iova); | 1424 | pgd += pgd_index(iova); |
1402 | end = iova + size; | 1425 | end = iova + size; |
1403 | do { | 1426 | do { |
@@ -1413,11 +1436,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
1413 | } while (pgd++, iova != end); | 1436 | } while (pgd++, iova != end); |
1414 | 1437 | ||
1415 | out_unlock: | 1438 | out_unlock: |
1416 | mutex_unlock(&smmu_domain->lock); | 1439 | spin_unlock_irqrestore(&smmu_domain->lock, irqflags); |
1417 | |||
1418 | /* Ensure new page tables are visible to the hardware walker */ | ||
1419 | if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) | ||
1420 | dsb(); | ||
1421 | 1440 | ||
1422 | return ret; | 1441 | return ret; |
1423 | } | 1442 | } |
@@ -1987,8 +2006,10 @@ static int __init arm_smmu_init(void) | |||
1987 | if (!iommu_present(&platform_bus_type)) | 2006 | if (!iommu_present(&platform_bus_type)) |
1988 | bus_set_iommu(&platform_bus_type, &arm_smmu_ops); | 2007 | bus_set_iommu(&platform_bus_type, &arm_smmu_ops); |
1989 | 2008 | ||
2009 | #ifdef CONFIG_ARM_AMBA | ||
1990 | if (!iommu_present(&amba_bustype)) | 2010 | if (!iommu_present(&amba_bustype)) |
1991 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); | 2011 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); |
2012 | #endif | ||
1992 | 2013 | ||
1993 | return 0; | 2014 | return 0; |
1994 | } | 2015 | } |
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index d97fbe4fb9b1..80fffba7f12d 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c | |||
@@ -354,8 +354,8 @@ DEBUG_FOPS(mem); | |||
354 | return -ENOMEM; \ | 354 | return -ENOMEM; \ |
355 | } | 355 | } |
356 | 356 | ||
357 | #define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 600) | 357 | #define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 0600) |
358 | #define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 400) | 358 | #define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400) |
359 | 359 | ||
360 | static int iommu_debug_register(struct device *dev, void *data) | 360 | static int iommu_debug_register(struct device *dev, void *data) |
361 | { | 361 | { |
diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c index 92c41ab4dbfd..2cb474ad8809 100644 --- a/drivers/irqchip/irq-metag-ext.c +++ b/drivers/irqchip/irq-metag-ext.c | |||
@@ -515,7 +515,7 @@ static int meta_intc_set_affinity(struct irq_data *data, | |||
515 | * one cpu (the interrupt code doesn't support it), so we just | 515 | * one cpu (the interrupt code doesn't support it), so we just |
516 | * pick the first cpu we find in 'cpumask'. | 516 | * pick the first cpu we find in 'cpumask'. |
517 | */ | 517 | */ |
518 | cpu = cpumask_any(cpumask); | 518 | cpu = cpumask_any_and(cpumask, cpu_online_mask); |
519 | thread = cpu_2_hwthread_id[cpu]; | 519 | thread = cpu_2_hwthread_id[cpu]; |
520 | 520 | ||
521 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); | 521 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); |
diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c index 8e94d7a3b20d..c16c186d97d3 100644 --- a/drivers/irqchip/irq-metag.c +++ b/drivers/irqchip/irq-metag.c | |||
@@ -201,7 +201,7 @@ static int metag_internal_irq_set_affinity(struct irq_data *data, | |||
201 | * one cpu (the interrupt code doesn't support it), so we just | 201 | * one cpu (the interrupt code doesn't support it), so we just |
202 | * pick the first cpu we find in 'cpumask'. | 202 | * pick the first cpu we find in 'cpumask'. |
203 | */ | 203 | */ |
204 | cpu = cpumask_any(cpumask); | 204 | cpu = cpumask_any_and(cpumask, cpu_online_mask); |
205 | thread = cpu_2_hwthread_id[cpu]; | 205 | thread = cpu_2_hwthread_id[cpu]; |
206 | 206 | ||
207 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR1(thread)), | 207 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR1(thread)), |
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index e51d40031884..8e41be62812e 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c | |||
@@ -111,7 +111,8 @@ IRQCHIP_DECLARE(orion_intc, "marvell,orion-intc", orion_irq_init); | |||
111 | static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) | 111 | static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) |
112 | { | 112 | { |
113 | struct irq_domain *d = irq_get_handler_data(irq); | 113 | struct irq_domain *d = irq_get_handler_data(irq); |
114 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq); | 114 | |
115 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); | ||
115 | u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & | 116 | u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & |
116 | gc->mask_cache; | 117 | gc->mask_cache; |
117 | 118 | ||
@@ -123,6 +124,19 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
123 | } | 124 | } |
124 | } | 125 | } |
125 | 126 | ||
127 | /* | ||
128 | * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register. | ||
129 | * To avoid interrupt events on stale irqs, we clear them before unmask. | ||
130 | */ | ||
131 | static unsigned int orion_bridge_irq_startup(struct irq_data *d) | ||
132 | { | ||
133 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | ||
134 | |||
135 | ct->chip.irq_ack(d); | ||
136 | ct->chip.irq_unmask(d); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
126 | static int __init orion_bridge_irq_init(struct device_node *np, | 140 | static int __init orion_bridge_irq_init(struct device_node *np, |
127 | struct device_node *parent) | 141 | struct device_node *parent) |
128 | { | 142 | { |
@@ -143,7 +157,7 @@ static int __init orion_bridge_irq_init(struct device_node *np, | |||
143 | } | 157 | } |
144 | 158 | ||
145 | ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, | 159 | ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, |
146 | handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); | 160 | handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); |
147 | if (ret) { | 161 | if (ret) { |
148 | pr_err("%s: unable to alloc irq domain gc\n", np->name); | 162 | pr_err("%s: unable to alloc irq domain gc\n", np->name); |
149 | return ret; | 163 | return ret; |
@@ -176,12 +190,14 @@ static int __init orion_bridge_irq_init(struct device_node *np, | |||
176 | 190 | ||
177 | gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; | 191 | gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; |
178 | gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; | 192 | gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; |
193 | gc->chip_types[0].chip.irq_startup = orion_bridge_irq_startup; | ||
179 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; | 194 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; |
180 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | 195 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; |
181 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | 196 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; |
182 | 197 | ||
183 | /* mask all interrupts */ | 198 | /* mask and clear all interrupts */ |
184 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); | 199 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); |
200 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); | ||
185 | 201 | ||
186 | irq_set_handler_data(irq, domain); | 202 | irq_set_handler_data(irq, domain); |
187 | irq_set_chained_handler(irq, orion_bridge_irq_handler); | 203 | irq_set_chained_handler(irq, orion_bridge_irq_handler); |
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index ffd472e015ca..1af70145fab9 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c | |||
@@ -289,6 +289,7 @@ struct per_bio_data { | |||
289 | bool tick:1; | 289 | bool tick:1; |
290 | unsigned req_nr:2; | 290 | unsigned req_nr:2; |
291 | struct dm_deferred_entry *all_io_entry; | 291 | struct dm_deferred_entry *all_io_entry; |
292 | struct dm_hook_info hook_info; | ||
292 | 293 | ||
293 | /* | 294 | /* |
294 | * writethrough fields. These MUST remain at the end of this | 295 | * writethrough fields. These MUST remain at the end of this |
@@ -297,7 +298,6 @@ struct per_bio_data { | |||
297 | */ | 298 | */ |
298 | struct cache *cache; | 299 | struct cache *cache; |
299 | dm_cblock_t cblock; | 300 | dm_cblock_t cblock; |
300 | struct dm_hook_info hook_info; | ||
301 | struct dm_bio_details bio_details; | 301 | struct dm_bio_details bio_details; |
302 | }; | 302 | }; |
303 | 303 | ||
@@ -671,15 +671,16 @@ static void remap_to_cache(struct cache *cache, struct bio *bio, | |||
671 | dm_cblock_t cblock) | 671 | dm_cblock_t cblock) |
672 | { | 672 | { |
673 | sector_t bi_sector = bio->bi_iter.bi_sector; | 673 | sector_t bi_sector = bio->bi_iter.bi_sector; |
674 | sector_t block = from_cblock(cblock); | ||
674 | 675 | ||
675 | bio->bi_bdev = cache->cache_dev->bdev; | 676 | bio->bi_bdev = cache->cache_dev->bdev; |
676 | if (!block_size_is_power_of_two(cache)) | 677 | if (!block_size_is_power_of_two(cache)) |
677 | bio->bi_iter.bi_sector = | 678 | bio->bi_iter.bi_sector = |
678 | (from_cblock(cblock) * cache->sectors_per_block) + | 679 | (block * cache->sectors_per_block) + |
679 | sector_div(bi_sector, cache->sectors_per_block); | 680 | sector_div(bi_sector, cache->sectors_per_block); |
680 | else | 681 | else |
681 | bio->bi_iter.bi_sector = | 682 | bio->bi_iter.bi_sector = |
682 | (from_cblock(cblock) << cache->sectors_per_block_shift) | | 683 | (block << cache->sectors_per_block_shift) | |
683 | (bi_sector & (cache->sectors_per_block - 1)); | 684 | (bi_sector & (cache->sectors_per_block - 1)); |
684 | } | 685 | } |
685 | 686 | ||
@@ -1010,13 +1011,15 @@ static void overwrite_endio(struct bio *bio, int err) | |||
1010 | struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); | 1011 | struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); |
1011 | unsigned long flags; | 1012 | unsigned long flags; |
1012 | 1013 | ||
1014 | dm_unhook_bio(&pb->hook_info, bio); | ||
1015 | |||
1013 | if (err) | 1016 | if (err) |
1014 | mg->err = true; | 1017 | mg->err = true; |
1015 | 1018 | ||
1019 | mg->requeue_holder = false; | ||
1020 | |||
1016 | spin_lock_irqsave(&cache->lock, flags); | 1021 | spin_lock_irqsave(&cache->lock, flags); |
1017 | list_add_tail(&mg->list, &cache->completed_migrations); | 1022 | list_add_tail(&mg->list, &cache->completed_migrations); |
1018 | dm_unhook_bio(&pb->hook_info, bio); | ||
1019 | mg->requeue_holder = false; | ||
1020 | spin_unlock_irqrestore(&cache->lock, flags); | 1023 | spin_unlock_irqrestore(&cache->lock, flags); |
1021 | 1024 | ||
1022 | wake_worker(cache); | 1025 | wake_worker(cache); |
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index b2b8a10e8427..3842ac738f98 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -201,29 +201,28 @@ static void list_dp_init(struct dpages *dp, struct page_list *pl, unsigned offse | |||
201 | /* | 201 | /* |
202 | * Functions for getting the pages from a bvec. | 202 | * Functions for getting the pages from a bvec. |
203 | */ | 203 | */ |
204 | static void bio_get_page(struct dpages *dp, | 204 | static void bio_get_page(struct dpages *dp, struct page **p, |
205 | struct page **p, unsigned long *len, unsigned *offset) | 205 | unsigned long *len, unsigned *offset) |
206 | { | 206 | { |
207 | struct bio *bio = dp->context_ptr; | 207 | struct bio_vec *bvec = dp->context_ptr; |
208 | struct bio_vec bvec = bio_iovec(bio); | 208 | *p = bvec->bv_page; |
209 | *p = bvec.bv_page; | 209 | *len = bvec->bv_len - dp->context_u; |
210 | *len = bvec.bv_len; | 210 | *offset = bvec->bv_offset + dp->context_u; |
211 | *offset = bvec.bv_offset; | ||
212 | } | 211 | } |
213 | 212 | ||
214 | static void bio_next_page(struct dpages *dp) | 213 | static void bio_next_page(struct dpages *dp) |
215 | { | 214 | { |
216 | struct bio *bio = dp->context_ptr; | 215 | struct bio_vec *bvec = dp->context_ptr; |
217 | struct bio_vec bvec = bio_iovec(bio); | 216 | dp->context_ptr = bvec + 1; |
218 | 217 | dp->context_u = 0; | |
219 | bio_advance(bio, bvec.bv_len); | ||
220 | } | 218 | } |
221 | 219 | ||
222 | static void bio_dp_init(struct dpages *dp, struct bio *bio) | 220 | static void bio_dp_init(struct dpages *dp, struct bio *bio) |
223 | { | 221 | { |
224 | dp->get_page = bio_get_page; | 222 | dp->get_page = bio_get_page; |
225 | dp->next_page = bio_next_page; | 223 | dp->next_page = bio_next_page; |
226 | dp->context_ptr = bio; | 224 | dp->context_ptr = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); |
225 | dp->context_u = bio->bi_iter.bi_bvec_done; | ||
227 | } | 226 | } |
228 | 227 | ||
229 | /* | 228 | /* |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 6eb9dc9ef8f3..422a9fdeb53e 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1626,8 +1626,11 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1626 | /* | 1626 | /* |
1627 | * Only pass ioctls through if the device sizes match exactly. | 1627 | * Only pass ioctls through if the device sizes match exactly. |
1628 | */ | 1628 | */ |
1629 | if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) | 1629 | if (!bdev || ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) { |
1630 | r = scsi_verify_blk_ioctl(NULL, cmd); | 1630 | int err = scsi_verify_blk_ioctl(NULL, cmd); |
1631 | if (err) | ||
1632 | r = err; | ||
1633 | } | ||
1631 | 1634 | ||
1632 | if (r == -ENOTCONN && !fatal_signal_pending(current)) | 1635 | if (r == -ENOTCONN && !fatal_signal_pending(current)) |
1633 | queue_work(kmultipathd, &m->process_queued_ios); | 1636 | queue_work(kmultipathd, &m->process_queued_ios); |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index f284e0bfb25f..7dfdb5c746d6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1244,6 +1244,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) | |||
1244 | 1244 | ||
1245 | dm_bio_restore(bd, bio); | 1245 | dm_bio_restore(bd, bio); |
1246 | bio_record->details.bi_bdev = NULL; | 1246 | bio_record->details.bi_bdev = NULL; |
1247 | |||
1248 | atomic_inc(&bio->bi_remaining); | ||
1249 | |||
1247 | queue_bio(ms, bio, rw); | 1250 | queue_bio(ms, bio, rw); |
1248 | return DM_ENDIO_INCOMPLETE; | 1251 | return DM_ENDIO_INCOMPLETE; |
1249 | } | 1252 | } |
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 7da347665552..baa87ff12816 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -483,7 +483,7 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd) | |||
483 | 483 | ||
484 | disk_super->data_mapping_root = cpu_to_le64(pmd->root); | 484 | disk_super->data_mapping_root = cpu_to_le64(pmd->root); |
485 | disk_super->device_details_root = cpu_to_le64(pmd->details_root); | 485 | disk_super->device_details_root = cpu_to_le64(pmd->details_root); |
486 | disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); | 486 | disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE); |
487 | disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT); | 487 | disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT); |
488 | disk_super->data_block_size = cpu_to_le32(pmd->data_block_size); | 488 | disk_super->data_block_size = cpu_to_le32(pmd->data_block_size); |
489 | 489 | ||
@@ -651,7 +651,7 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f | |||
651 | { | 651 | { |
652 | int r; | 652 | int r; |
653 | 653 | ||
654 | pmd->bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE, | 654 | pmd->bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT, |
655 | THIN_METADATA_CACHE_SIZE, | 655 | THIN_METADATA_CACHE_SIZE, |
656 | THIN_MAX_CONCURRENT_LOCKS); | 656 | THIN_MAX_CONCURRENT_LOCKS); |
657 | if (IS_ERR(pmd->bm)) { | 657 | if (IS_ERR(pmd->bm)) { |
@@ -1489,6 +1489,23 @@ bool dm_thin_changed_this_transaction(struct dm_thin_device *td) | |||
1489 | return r; | 1489 | return r; |
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | bool dm_pool_changed_this_transaction(struct dm_pool_metadata *pmd) | ||
1493 | { | ||
1494 | bool r = false; | ||
1495 | struct dm_thin_device *td, *tmp; | ||
1496 | |||
1497 | down_read(&pmd->root_lock); | ||
1498 | list_for_each_entry_safe(td, tmp, &pmd->thin_devices, list) { | ||
1499 | if (td->changed) { | ||
1500 | r = td->changed; | ||
1501 | break; | ||
1502 | } | ||
1503 | } | ||
1504 | up_read(&pmd->root_lock); | ||
1505 | |||
1506 | return r; | ||
1507 | } | ||
1508 | |||
1492 | bool dm_thin_aborted_changes(struct dm_thin_device *td) | 1509 | bool dm_thin_aborted_changes(struct dm_thin_device *td) |
1493 | { | 1510 | { |
1494 | bool r; | 1511 | bool r; |
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index 9a368567632f..82ea384d36ff 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h | |||
@@ -9,16 +9,14 @@ | |||
9 | 9 | ||
10 | #include "persistent-data/dm-block-manager.h" | 10 | #include "persistent-data/dm-block-manager.h" |
11 | #include "persistent-data/dm-space-map.h" | 11 | #include "persistent-data/dm-space-map.h" |
12 | #include "persistent-data/dm-space-map-metadata.h" | ||
12 | 13 | ||
13 | #define THIN_METADATA_BLOCK_SIZE 4096 | 14 | #define THIN_METADATA_BLOCK_SIZE DM_SM_METADATA_BLOCK_SIZE |
14 | 15 | ||
15 | /* | 16 | /* |
16 | * The metadata device is currently limited in size. | 17 | * The metadata device is currently limited in size. |
17 | * | ||
18 | * We have one block of index, which can hold 255 index entries. Each | ||
19 | * index entry contains allocation info about 16k metadata blocks. | ||
20 | */ | 18 | */ |
21 | #define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT))) | 19 | #define THIN_METADATA_MAX_SECTORS DM_SM_METADATA_MAX_SECTORS |
22 | 20 | ||
23 | /* | 21 | /* |
24 | * A metadata device larger than 16GB triggers a warning. | 22 | * A metadata device larger than 16GB triggers a warning. |
@@ -161,6 +159,8 @@ int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block); | |||
161 | */ | 159 | */ |
162 | bool dm_thin_changed_this_transaction(struct dm_thin_device *td); | 160 | bool dm_thin_changed_this_transaction(struct dm_thin_device *td); |
163 | 161 | ||
162 | bool dm_pool_changed_this_transaction(struct dm_pool_metadata *pmd); | ||
163 | |||
164 | bool dm_thin_aborted_changes(struct dm_thin_device *td); | 164 | bool dm_thin_aborted_changes(struct dm_thin_device *td); |
165 | 165 | ||
166 | int dm_thin_get_highest_mapped_block(struct dm_thin_device *td, | 166 | int dm_thin_get_highest_mapped_block(struct dm_thin_device *td, |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index faaf944597ab..7e84baccf0ad 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -1357,7 +1357,8 @@ static void process_deferred_bios(struct pool *pool) | |||
1357 | bio_list_init(&pool->deferred_flush_bios); | 1357 | bio_list_init(&pool->deferred_flush_bios); |
1358 | spin_unlock_irqrestore(&pool->lock, flags); | 1358 | spin_unlock_irqrestore(&pool->lock, flags); |
1359 | 1359 | ||
1360 | if (bio_list_empty(&bios) && !need_commit_due_to_time(pool)) | 1360 | if (bio_list_empty(&bios) && |
1361 | !(dm_pool_changed_this_transaction(pool->pmd) && need_commit_due_to_time(pool))) | ||
1361 | return; | 1362 | return; |
1362 | 1363 | ||
1363 | if (commit(pool)) { | 1364 | if (commit(pool)) { |
@@ -1999,16 +2000,27 @@ static void metadata_low_callback(void *context) | |||
1999 | dm_table_event(pool->ti->table); | 2000 | dm_table_event(pool->ti->table); |
2000 | } | 2001 | } |
2001 | 2002 | ||
2002 | static sector_t get_metadata_dev_size(struct block_device *bdev) | 2003 | static sector_t get_dev_size(struct block_device *bdev) |
2004 | { | ||
2005 | return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | ||
2006 | } | ||
2007 | |||
2008 | static void warn_if_metadata_device_too_big(struct block_device *bdev) | ||
2003 | { | 2009 | { |
2004 | sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | 2010 | sector_t metadata_dev_size = get_dev_size(bdev); |
2005 | char buffer[BDEVNAME_SIZE]; | 2011 | char buffer[BDEVNAME_SIZE]; |
2006 | 2012 | ||
2007 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) { | 2013 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) |
2008 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", | 2014 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", |
2009 | bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); | 2015 | bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); |
2010 | metadata_dev_size = THIN_METADATA_MAX_SECTORS_WARNING; | 2016 | } |
2011 | } | 2017 | |
2018 | static sector_t get_metadata_dev_size(struct block_device *bdev) | ||
2019 | { | ||
2020 | sector_t metadata_dev_size = get_dev_size(bdev); | ||
2021 | |||
2022 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS) | ||
2023 | metadata_dev_size = THIN_METADATA_MAX_SECTORS; | ||
2012 | 2024 | ||
2013 | return metadata_dev_size; | 2025 | return metadata_dev_size; |
2014 | } | 2026 | } |
@@ -2017,7 +2029,7 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev) | |||
2017 | { | 2029 | { |
2018 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); | 2030 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); |
2019 | 2031 | ||
2020 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); | 2032 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE); |
2021 | 2033 | ||
2022 | return metadata_dev_size; | 2034 | return metadata_dev_size; |
2023 | } | 2035 | } |
@@ -2095,12 +2107,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2095 | ti->error = "Error opening metadata block device"; | 2107 | ti->error = "Error opening metadata block device"; |
2096 | goto out_unlock; | 2108 | goto out_unlock; |
2097 | } | 2109 | } |
2098 | 2110 | warn_if_metadata_device_too_big(metadata_dev->bdev); | |
2099 | /* | ||
2100 | * Run for the side-effect of possibly issuing a warning if the | ||
2101 | * device is too big. | ||
2102 | */ | ||
2103 | (void) get_metadata_dev_size(metadata_dev->bdev); | ||
2104 | 2111 | ||
2105 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); | 2112 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); |
2106 | if (r) { | 2113 | if (r) { |
@@ -2287,6 +2294,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit) | |||
2287 | return -EINVAL; | 2294 | return -EINVAL; |
2288 | 2295 | ||
2289 | } else if (metadata_dev_size > sb_metadata_dev_size) { | 2296 | } else if (metadata_dev_size > sb_metadata_dev_size) { |
2297 | warn_if_metadata_device_too_big(pool->md_dev); | ||
2290 | DMINFO("%s: growing the metadata device from %llu to %llu blocks", | 2298 | DMINFO("%s: growing the metadata device from %llu to %llu blocks", |
2291 | dm_device_name(pool->pool_md), | 2299 | dm_device_name(pool->pool_md), |
2292 | sb_metadata_dev_size, metadata_dev_size); | 2300 | sb_metadata_dev_size, metadata_dev_size); |
@@ -2894,6 +2902,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2894 | 2902 | ||
2895 | if (get_pool_mode(tc->pool) == PM_FAIL) { | 2903 | if (get_pool_mode(tc->pool) == PM_FAIL) { |
2896 | ti->error = "Couldn't open thin device, Pool is in fail mode"; | 2904 | ti->error = "Couldn't open thin device, Pool is in fail mode"; |
2905 | r = -EINVAL; | ||
2897 | goto bad_thin_open; | 2906 | goto bad_thin_open; |
2898 | } | 2907 | } |
2899 | 2908 | ||
@@ -2905,7 +2914,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2905 | 2914 | ||
2906 | r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block); | 2915 | r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block); |
2907 | if (r) | 2916 | if (r) |
2908 | goto bad_thin_open; | 2917 | goto bad_target_max_io_len; |
2909 | 2918 | ||
2910 | ti->num_flush_bios = 1; | 2919 | ti->num_flush_bios = 1; |
2911 | ti->flush_supported = true; | 2920 | ti->flush_supported = true; |
@@ -2926,6 +2935,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2926 | 2935 | ||
2927 | return 0; | 2936 | return 0; |
2928 | 2937 | ||
2938 | bad_target_max_io_len: | ||
2939 | dm_pool_close_thin_device(tc->td); | ||
2929 | bad_thin_open: | 2940 | bad_thin_open: |
2930 | __pool_dec(tc->pool); | 2941 | __pool_dec(tc->pool); |
2931 | bad_pool_lookup: | 2942 | bad_pool_lookup: |
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c index 536782e3bcb7..e9bdd462f4f5 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c | |||
@@ -680,6 +680,8 @@ int dm_sm_metadata_create(struct dm_space_map *sm, | |||
680 | if (r) | 680 | if (r) |
681 | return r; | 681 | return r; |
682 | 682 | ||
683 | if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS) | ||
684 | nr_blocks = DM_SM_METADATA_MAX_BLOCKS; | ||
683 | r = sm_ll_extend(&smm->ll, nr_blocks); | 685 | r = sm_ll_extend(&smm->ll, nr_blocks); |
684 | if (r) | 686 | if (r) |
685 | return r; | 687 | return r; |
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.h b/drivers/md/persistent-data/dm-space-map-metadata.h index 39bba0801cf2..64df923974d8 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.h +++ b/drivers/md/persistent-data/dm-space-map-metadata.h | |||
@@ -9,6 +9,17 @@ | |||
9 | 9 | ||
10 | #include "dm-transaction-manager.h" | 10 | #include "dm-transaction-manager.h" |
11 | 11 | ||
12 | #define DM_SM_METADATA_BLOCK_SIZE (4096 >> SECTOR_SHIFT) | ||
13 | |||
14 | /* | ||
15 | * The metadata device is currently limited in size. | ||
16 | * | ||
17 | * We have one block of index, which can hold 255 index entries. Each | ||
18 | * index entry contains allocation info about ~16k metadata blocks. | ||
19 | */ | ||
20 | #define DM_SM_METADATA_MAX_BLOCKS (255 * ((1 << 14) - 64)) | ||
21 | #define DM_SM_METADATA_MAX_SECTORS (DM_SM_METADATA_MAX_BLOCKS * DM_SM_METADATA_BLOCK_SIZE) | ||
22 | |||
12 | /* | 23 | /* |
13 | * Unfortunately we have to use two-phase construction due to the cycle | 24 | * Unfortunately we have to use two-phase construction due to the cycle |
14 | * between the tm and sm. | 25 | * between the tm and sm. |
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c index 13af7e50021e..8103e4362132 100644 --- a/drivers/mfd/da9055-i2c.c +++ b/drivers/mfd/da9055-i2c.c | |||
@@ -53,17 +53,25 @@ static int da9055_i2c_remove(struct i2c_client *i2c) | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* | ||
57 | * DO NOT change the device Ids. The naming is intentionally specific as both | ||
58 | * the PMIC and CODEC parts of this chip are instantiated separately as I2C | ||
59 | * devices (both have configurable I2C addresses, and are to all intents and | ||
60 | * purposes separate). As a result there are specific DA9055 ids for PMIC | ||
61 | * and CODEC, which must be different to operate together. | ||
62 | */ | ||
56 | static struct i2c_device_id da9055_i2c_id[] = { | 63 | static struct i2c_device_id da9055_i2c_id[] = { |
57 | {"da9055", 0}, | 64 | {"da9055-pmic", 0}, |
58 | { } | 65 | { } |
59 | }; | 66 | }; |
67 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | ||
60 | 68 | ||
61 | static struct i2c_driver da9055_i2c_driver = { | 69 | static struct i2c_driver da9055_i2c_driver = { |
62 | .probe = da9055_i2c_probe, | 70 | .probe = da9055_i2c_probe, |
63 | .remove = da9055_i2c_remove, | 71 | .remove = da9055_i2c_remove, |
64 | .id_table = da9055_i2c_id, | 72 | .id_table = da9055_i2c_id, |
65 | .driver = { | 73 | .driver = { |
66 | .name = "da9055", | 74 | .name = "da9055-pmic", |
67 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
68 | }, | 76 | }, |
69 | }; | 77 | }; |
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index ac514fb2b877..71aa14a6bfbb 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c | |||
@@ -173,6 +173,7 @@ static const struct i2c_device_id max14577_i2c_id[] = { | |||
173 | }; | 173 | }; |
174 | MODULE_DEVICE_TABLE(i2c, max14577_i2c_id); | 174 | MODULE_DEVICE_TABLE(i2c, max14577_i2c_id); |
175 | 175 | ||
176 | #ifdef CONFIG_PM_SLEEP | ||
176 | static int max14577_suspend(struct device *dev) | 177 | static int max14577_suspend(struct device *dev) |
177 | { | 178 | { |
178 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 179 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
@@ -208,6 +209,7 @@ static int max14577_resume(struct device *dev) | |||
208 | 209 | ||
209 | return 0; | 210 | return 0; |
210 | } | 211 | } |
212 | #endif /* CONFIG_PM_SLEEP */ | ||
211 | 213 | ||
212 | static struct of_device_id max14577_dt_match[] = { | 214 | static struct of_device_id max14577_dt_match[] = { |
213 | { .compatible = "maxim,max14577", }, | 215 | { .compatible = "maxim,max14577", }, |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index be88a3bf7b85..5adede0fb04c 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -164,15 +164,15 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( | |||
164 | return pd; | 164 | return pd; |
165 | } | 165 | } |
166 | 166 | ||
167 | static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c, | 167 | static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c, |
168 | const struct i2c_device_id *id) | 168 | const struct i2c_device_id *id) |
169 | { | 169 | { |
170 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { | 170 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { |
171 | const struct of_device_id *match; | 171 | const struct of_device_id *match; |
172 | match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node); | 172 | match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node); |
173 | return (int)match->data; | 173 | return (unsigned long)match->data; |
174 | } | 174 | } |
175 | return (int)id->driver_data; | 175 | return id->driver_data; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int max8997_i2c_probe(struct i2c_client *i2c, | 178 | static int max8997_i2c_probe(struct i2c_client *i2c, |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 612ca404e150..5d5e186b5d8b 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -169,16 +169,16 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata( | |||
169 | return pd; | 169 | return pd; |
170 | } | 170 | } |
171 | 171 | ||
172 | static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c, | 172 | static inline unsigned long max8998_i2c_get_driver_data(struct i2c_client *i2c, |
173 | const struct i2c_device_id *id) | 173 | const struct i2c_device_id *id) |
174 | { | 174 | { |
175 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { | 175 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { |
176 | const struct of_device_id *match; | 176 | const struct of_device_id *match; |
177 | match = of_match_node(max8998_dt_match, i2c->dev.of_node); | 177 | match = of_match_node(max8998_dt_match, i2c->dev.of_node); |
178 | return (int)(long)match->data; | 178 | return (unsigned long)match->data; |
179 | } | 179 | } |
180 | 180 | ||
181 | return (int)id->driver_data; | 181 | return id->driver_data; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int max8998_i2c_probe(struct i2c_client *i2c, | 184 | static int max8998_i2c_probe(struct i2c_client *i2c, |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index a139798b8065..714e2135210e 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -315,6 +315,7 @@ static int sec_pmic_remove(struct i2c_client *i2c) | |||
315 | return 0; | 315 | return 0; |
316 | } | 316 | } |
317 | 317 | ||
318 | #ifdef CONFIG_PM_SLEEP | ||
318 | static int sec_pmic_suspend(struct device *dev) | 319 | static int sec_pmic_suspend(struct device *dev) |
319 | { | 320 | { |
320 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 321 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
@@ -349,6 +350,7 @@ static int sec_pmic_resume(struct device *dev) | |||
349 | 350 | ||
350 | return 0; | 351 | return 0; |
351 | } | 352 | } |
353 | #endif /* CONFIG_PM_SLEEP */ | ||
352 | 354 | ||
353 | static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); | 355 | static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); |
354 | 356 | ||
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 966cf65c5c36..3cc4c7084b92 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -158,7 +158,7 @@ static int tps65217_probe(struct i2c_client *client, | |||
158 | { | 158 | { |
159 | struct tps65217 *tps; | 159 | struct tps65217 *tps; |
160 | unsigned int version; | 160 | unsigned int version; |
161 | unsigned int chip_id = ids->driver_data; | 161 | unsigned long chip_id = ids->driver_data; |
162 | const struct of_device_id *match; | 162 | const struct of_device_id *match; |
163 | bool status_off = false; | 163 | bool status_off = false; |
164 | int ret; | 164 | int ret; |
@@ -170,7 +170,7 @@ static int tps65217_probe(struct i2c_client *client, | |||
170 | "Failed to find matching dt id\n"); | 170 | "Failed to find matching dt id\n"); |
171 | return -EINVAL; | 171 | return -EINVAL; |
172 | } | 172 | } |
173 | chip_id = (unsigned int)(unsigned long)match->data; | 173 | chip_id = (unsigned long)match->data; |
174 | status_off = of_property_read_bool(client->dev.of_node, | 174 | status_off = of_property_read_bool(client->dev.of_node, |
175 | "ti,pmic-shutdown-controller"); | 175 | "ti,pmic-shutdown-controller"); |
176 | } | 176 | } |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index ba04f1bc70eb..e6fab94e2c8a 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -636,7 +636,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, | |||
636 | if (i2c->dev.of_node) { | 636 | if (i2c->dev.of_node) { |
637 | of_id = of_match_device(wm8994_of_match, &i2c->dev); | 637 | of_id = of_match_device(wm8994_of_match, &i2c->dev); |
638 | if (of_id) | 638 | if (of_id) |
639 | wm8994->type = (int)of_id->data; | 639 | wm8994->type = (enum wm8994_type)of_id->data; |
640 | } else { | 640 | } else { |
641 | wm8994->type = id->driver_data; | 641 | wm8994->type = id->driver_data; |
642 | } | 642 | } |
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 9b809cfc2899..89a557972d1b 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -666,7 +666,6 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) | |||
666 | goto err; | 666 | goto err; |
667 | 667 | ||
668 | cb->fop_type = MEI_FOP_READ; | 668 | cb->fop_type = MEI_FOP_READ; |
669 | cl->read_cb = cb; | ||
670 | if (dev->hbuf_is_ready) { | 669 | if (dev->hbuf_is_ready) { |
671 | dev->hbuf_is_ready = false; | 670 | dev->hbuf_is_ready = false; |
672 | if (mei_hbm_cl_flow_control_req(dev, cl)) { | 671 | if (mei_hbm_cl_flow_control_req(dev, cl)) { |
@@ -678,6 +677,9 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) | |||
678 | } else { | 677 | } else { |
679 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | 678 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); |
680 | } | 679 | } |
680 | |||
681 | cl->read_cb = cb; | ||
682 | |||
681 | return rets; | 683 | return rets; |
682 | err: | 684 | err: |
683 | mei_io_cb_free(cb); | 685 | mei_io_cb_free(cb); |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 357bbc54fe4b..3e049c13429c 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -197,7 +197,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, | |||
197 | struct mmc_queue_req *mqrq_prev = &mq->mqrq[1]; | 197 | struct mmc_queue_req *mqrq_prev = &mq->mqrq[1]; |
198 | 198 | ||
199 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) | 199 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) |
200 | limit = dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; | 200 | limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; |
201 | 201 | ||
202 | mq->card = card; | 202 | mq->card = card; |
203 | mq->queue = blk_init_queue(mmc_request_fn, lock); | 203 | mq->queue = blk_init_queue(mmc_request_fn, lock); |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 59eba5d2c685..9715a7ba164a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1584,7 +1584,7 @@ read_retry: | |||
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | if (mtd->ecc_stats.failed - ecc_failures) { | 1586 | if (mtd->ecc_stats.failed - ecc_failures) { |
1587 | if (retry_mode + 1 <= chip->read_retries) { | 1587 | if (retry_mode + 1 < chip->read_retries) { |
1588 | retry_mode++; | 1588 | retry_mode++; |
1589 | ret = nand_setup_read_retry(mtd, | 1589 | ret = nand_setup_read_retry(mtd, |
1590 | retry_mode); | 1590 | retry_mode); |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index ef4190a02b7b..bf642ceef681 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1633,6 +1633,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1633 | int i; | 1633 | int i; |
1634 | dma_cap_mask_t mask; | 1634 | dma_cap_mask_t mask; |
1635 | unsigned sig; | 1635 | unsigned sig; |
1636 | unsigned oob_index; | ||
1636 | struct resource *res; | 1637 | struct resource *res; |
1637 | struct mtd_part_parser_data ppdata = {}; | 1638 | struct mtd_part_parser_data ppdata = {}; |
1638 | 1639 | ||
@@ -1826,11 +1827,14 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1826 | (mtd->writesize / | 1827 | (mtd->writesize / |
1827 | nand_chip->ecc.size); | 1828 | nand_chip->ecc.size); |
1828 | if (nand_chip->options & NAND_BUSWIDTH_16) | 1829 | if (nand_chip->options & NAND_BUSWIDTH_16) |
1829 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1830 | oob_index = BADBLOCK_MARKER_LENGTH; |
1830 | else | 1831 | else |
1831 | ecclayout->eccpos[0] = 1; | 1832 | oob_index = 1; |
1832 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1833 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1833 | ecclayout->eccbytes; | 1834 | ecclayout->eccpos[i] = oob_index; |
1835 | /* no reserved-marker in ecclayout for this ecc-scheme */ | ||
1836 | ecclayout->oobfree->offset = | ||
1837 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1834 | break; | 1838 | break; |
1835 | 1839 | ||
1836 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | 1840 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: |
@@ -1847,9 +1851,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1847 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1851 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1848 | (mtd->writesize / | 1852 | (mtd->writesize / |
1849 | nand_chip->ecc.size); | 1853 | nand_chip->ecc.size); |
1850 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1854 | oob_index = BADBLOCK_MARKER_LENGTH; |
1851 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1855 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) { |
1852 | ecclayout->eccbytes; | 1856 | ecclayout->eccpos[i] = oob_index; |
1857 | if (((i + 1) % nand_chip->ecc.bytes) == 0) | ||
1858 | oob_index++; | ||
1859 | } | ||
1860 | /* include reserved-marker in ecclayout->oobfree calculation */ | ||
1861 | ecclayout->oobfree->offset = 1 + | ||
1862 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1853 | /* software bch library is used for locating errors */ | 1863 | /* software bch library is used for locating errors */ |
1854 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1864 | nand_chip->ecc.priv = nand_bch_init(mtd, |
1855 | nand_chip->ecc.size, | 1865 | nand_chip->ecc.size, |
@@ -1883,9 +1893,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1883 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1893 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1884 | (mtd->writesize / | 1894 | (mtd->writesize / |
1885 | nand_chip->ecc.size); | 1895 | nand_chip->ecc.size); |
1886 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1896 | oob_index = BADBLOCK_MARKER_LENGTH; |
1887 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1897 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1888 | ecclayout->eccbytes; | 1898 | ecclayout->eccpos[i] = oob_index; |
1899 | /* reserved marker already included in ecclayout->eccbytes */ | ||
1900 | ecclayout->oobfree->offset = | ||
1901 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1889 | /* This ECC scheme requires ELM H/W block */ | 1902 | /* This ECC scheme requires ELM H/W block */ |
1890 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { | 1903 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { |
1891 | pr_err("nand: error: could not initialize ELM\n"); | 1904 | pr_err("nand: error: could not initialize ELM\n"); |
@@ -1913,9 +1926,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1913 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1926 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1914 | (mtd->writesize / | 1927 | (mtd->writesize / |
1915 | nand_chip->ecc.size); | 1928 | nand_chip->ecc.size); |
1916 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1929 | oob_index = BADBLOCK_MARKER_LENGTH; |
1917 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1930 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) { |
1918 | ecclayout->eccbytes; | 1931 | ecclayout->eccpos[i] = oob_index; |
1932 | if (((i + 1) % nand_chip->ecc.bytes) == 0) | ||
1933 | oob_index++; | ||
1934 | } | ||
1935 | /* include reserved-marker in ecclayout->oobfree calculation */ | ||
1936 | ecclayout->oobfree->offset = 1 + | ||
1937 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1919 | /* software bch library is used for locating errors */ | 1938 | /* software bch library is used for locating errors */ |
1920 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1939 | nand_chip->ecc.priv = nand_bch_init(mtd, |
1921 | nand_chip->ecc.size, | 1940 | nand_chip->ecc.size, |
@@ -1956,9 +1975,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1956 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1975 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1957 | (mtd->writesize / | 1976 | (mtd->writesize / |
1958 | nand_chip->ecc.size); | 1977 | nand_chip->ecc.size); |
1959 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1978 | oob_index = BADBLOCK_MARKER_LENGTH; |
1960 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1979 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1961 | ecclayout->eccbytes; | 1980 | ecclayout->eccpos[i] = oob_index; |
1981 | /* reserved marker already included in ecclayout->eccbytes */ | ||
1982 | ecclayout->oobfree->offset = | ||
1983 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1962 | break; | 1984 | break; |
1963 | #else | 1985 | #else |
1964 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | 1986 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); |
@@ -1972,11 +1994,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1972 | goto return_error; | 1994 | goto return_error; |
1973 | } | 1995 | } |
1974 | 1996 | ||
1975 | /* populate remaining ECC layout data */ | 1997 | /* all OOB bytes from oobfree->offset till end off OOB are free */ |
1976 | ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH + | 1998 | ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; |
1977 | ecclayout->eccbytes); | ||
1978 | for (i = 1; i < ecclayout->eccbytes; i++) | ||
1979 | ecclayout->eccpos[i] = ecclayout->eccpos[0] + i; | ||
1980 | /* check if NAND device's OOB is enough to store ECC signatures */ | 1999 | /* check if NAND device's OOB is enough to store ECC signatures */ |
1981 | if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { | 2000 | if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { |
1982 | pr_err("not enough OOB bytes required = %d, available=%d\n", | 2001 | pr_err("not enough OOB bytes required = %d, available=%d\n", |
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index ead861307b3c..c5dad652614d 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
@@ -463,8 +463,8 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
463 | } | 463 | } |
464 | } | 464 | } |
465 | if (found_orphan) { | 465 | if (found_orphan) { |
466 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
467 | list_del(&tmp_aeb->u.list); | 466 | list_del(&tmp_aeb->u.list); |
467 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
468 | } | 468 | } |
469 | 469 | ||
470 | new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, | 470 | new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, |
@@ -846,16 +846,16 @@ fail_bad: | |||
846 | ret = UBI_BAD_FASTMAP; | 846 | ret = UBI_BAD_FASTMAP; |
847 | fail: | 847 | fail: |
848 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { | 848 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { |
849 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
850 | list_del(&tmp_aeb->u.list); | 849 | list_del(&tmp_aeb->u.list); |
850 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
851 | } | 851 | } |
852 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { | 852 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { |
853 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
854 | list_del(&tmp_aeb->u.list); | 853 | list_del(&tmp_aeb->u.list); |
854 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
855 | } | 855 | } |
856 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { | 856 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { |
857 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
858 | list_del(&tmp_aeb->u.list); | 857 | list_del(&tmp_aeb->u.list); |
858 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
859 | } | 859 | } |
860 | 860 | ||
861 | return ret; | 861 | return ret; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f342278539d5..494b888a6568 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -139,7 +139,7 @@ config MACVTAP | |||
139 | This adds a specialized tap character device driver that is based | 139 | This adds a specialized tap character device driver that is based |
140 | on the MAC-VLAN network interface, called macvtap. A macvtap device | 140 | on the MAC-VLAN network interface, called macvtap. A macvtap device |
141 | can be added in the same way as a macvlan device, using 'type | 141 | can be added in the same way as a macvlan device, using 'type |
142 | macvlan', and then be accessed through the tap user space interface. | 142 | macvtap', and then be accessed through the tap user space interface. |
143 | 143 | ||
144 | To compile this driver as a module, choose M here: the module | 144 | To compile this driver as a module, choose M here: the module |
145 | will be called macvtap. | 145 | will be called macvtap. |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index cce1f1bf90b4..6d20fbde8d43 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -1796,8 +1796,6 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) | |||
1796 | BOND_AD_INFO(bond).agg_select_timer = timeout; | 1796 | BOND_AD_INFO(bond).agg_select_timer = timeout; |
1797 | } | 1797 | } |
1798 | 1798 | ||
1799 | static u16 aggregator_identifier; | ||
1800 | |||
1801 | /** | 1799 | /** |
1802 | * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures | 1800 | * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures |
1803 | * @bond: bonding struct to work on | 1801 | * @bond: bonding struct to work on |
@@ -1811,7 +1809,7 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) | |||
1811 | if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), | 1809 | if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), |
1812 | bond->dev->dev_addr)) { | 1810 | bond->dev->dev_addr)) { |
1813 | 1811 | ||
1814 | aggregator_identifier = 0; | 1812 | BOND_AD_INFO(bond).aggregator_identifier = 0; |
1815 | 1813 | ||
1816 | BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; | 1814 | BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; |
1817 | BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); | 1815 | BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); |
@@ -1880,7 +1878,7 @@ void bond_3ad_bind_slave(struct slave *slave) | |||
1880 | ad_initialize_agg(aggregator); | 1878 | ad_initialize_agg(aggregator); |
1881 | 1879 | ||
1882 | aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); | 1880 | aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); |
1883 | aggregator->aggregator_identifier = (++aggregator_identifier); | 1881 | aggregator->aggregator_identifier = ++BOND_AD_INFO(bond).aggregator_identifier; |
1884 | aggregator->slave = slave; | 1882 | aggregator->slave = slave; |
1885 | aggregator->is_active = 0; | 1883 | aggregator->is_active = 0; |
1886 | aggregator->num_of_ports = 0; | 1884 | aggregator->num_of_ports = 0; |
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 13dc9d3c5e34..f4dd9592ac62 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -253,6 +253,7 @@ struct ad_system { | |||
253 | struct ad_bond_info { | 253 | struct ad_bond_info { |
254 | struct ad_system system; /* 802.3ad system structure */ | 254 | struct ad_system system; /* 802.3ad system structure */ |
255 | u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes | 255 | u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes |
256 | u16 aggregator_identifier; | ||
256 | }; | 257 | }; |
257 | 258 | ||
258 | struct ad_slave_info { | 259 | struct ad_slave_info { |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 71ba18efa15b..1c6104d3501d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1543,9 +1543,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1543 | bond_set_carrier(bond); | 1543 | bond_set_carrier(bond); |
1544 | 1544 | ||
1545 | if (USES_PRIMARY(bond->params.mode)) { | 1545 | if (USES_PRIMARY(bond->params.mode)) { |
1546 | block_netpoll_tx(); | ||
1546 | write_lock_bh(&bond->curr_slave_lock); | 1547 | write_lock_bh(&bond->curr_slave_lock); |
1547 | bond_select_active_slave(bond); | 1548 | bond_select_active_slave(bond); |
1548 | write_unlock_bh(&bond->curr_slave_lock); | 1549 | write_unlock_bh(&bond->curr_slave_lock); |
1550 | unblock_netpoll_tx(); | ||
1549 | } | 1551 | } |
1550 | 1552 | ||
1551 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1553 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", |
@@ -1571,10 +1573,12 @@ err_detach: | |||
1571 | if (bond->primary_slave == new_slave) | 1573 | if (bond->primary_slave == new_slave) |
1572 | bond->primary_slave = NULL; | 1574 | bond->primary_slave = NULL; |
1573 | if (bond->curr_active_slave == new_slave) { | 1575 | if (bond->curr_active_slave == new_slave) { |
1576 | block_netpoll_tx(); | ||
1574 | write_lock_bh(&bond->curr_slave_lock); | 1577 | write_lock_bh(&bond->curr_slave_lock); |
1575 | bond_change_active_slave(bond, NULL); | 1578 | bond_change_active_slave(bond, NULL); |
1576 | bond_select_active_slave(bond); | 1579 | bond_select_active_slave(bond); |
1577 | write_unlock_bh(&bond->curr_slave_lock); | 1580 | write_unlock_bh(&bond->curr_slave_lock); |
1581 | unblock_netpoll_tx(); | ||
1578 | } | 1582 | } |
1579 | slave_disable_netpoll(new_slave); | 1583 | slave_disable_netpoll(new_slave); |
1580 | 1584 | ||
@@ -2864,9 +2868,12 @@ static int bond_slave_netdev_event(unsigned long event, | |||
2864 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", | 2868 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", |
2865 | bond->dev->name, bond->primary_slave ? slave_dev->name : | 2869 | bond->dev->name, bond->primary_slave ? slave_dev->name : |
2866 | "none"); | 2870 | "none"); |
2871 | |||
2872 | block_netpoll_tx(); | ||
2867 | write_lock_bh(&bond->curr_slave_lock); | 2873 | write_lock_bh(&bond->curr_slave_lock); |
2868 | bond_select_active_slave(bond); | 2874 | bond_select_active_slave(bond); |
2869 | write_unlock_bh(&bond->curr_slave_lock); | 2875 | write_unlock_bh(&bond->curr_slave_lock); |
2876 | unblock_netpoll_tx(); | ||
2870 | break; | 2877 | break; |
2871 | case NETDEV_FEAT_CHANGE: | 2878 | case NETDEV_FEAT_CHANGE: |
2872 | bond_compute_features(bond); | 2879 | bond_compute_features(bond); |
@@ -3700,7 +3707,7 @@ static inline int bond_slave_override(struct bonding *bond, | |||
3700 | 3707 | ||
3701 | 3708 | ||
3702 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, | 3709 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, |
3703 | void *accel_priv) | 3710 | void *accel_priv, select_queue_fallback_t fallback) |
3704 | { | 3711 | { |
3705 | /* | 3712 | /* |
3706 | * This helper function exists to help dev_pick_tx get the correct | 3713 | * This helper function exists to help dev_pick_tx get the correct |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 11cb943222d5..c37878432717 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/if.h> | 15 | #include <linux/if.h> |
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/rwlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
19 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
20 | #include <linux/inet.h> | 20 | #include <linux/inet.h> |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 6c859bba8b65..e77d11049747 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
@@ -473,6 +473,8 @@ static int kvaser_usb_get_card_info(struct kvaser_usb *dev) | |||
473 | return err; | 473 | return err; |
474 | 474 | ||
475 | dev->nchannels = msg.u.cardinfo.nchannels; | 475 | dev->nchannels = msg.u.cardinfo.nchannels; |
476 | if (dev->nchannels > MAX_NET_DEVICES) | ||
477 | return -EINVAL; | ||
476 | 478 | ||
477 | return 0; | 479 | return 0; |
478 | } | 480 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 9d7419e0390b..66c0df78c3ff 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -1873,7 +1873,7 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) | |||
1873 | } | 1873 | } |
1874 | 1874 | ||
1875 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | 1875 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
1876 | void *accel_priv) | 1876 | void *accel_priv, select_queue_fallback_t fallback) |
1877 | { | 1877 | { |
1878 | struct bnx2x *bp = netdev_priv(dev); | 1878 | struct bnx2x *bp = netdev_priv(dev); |
1879 | 1879 | ||
@@ -1895,7 +1895,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
1895 | } | 1895 | } |
1896 | 1896 | ||
1897 | /* select a non-FCoE queue */ | 1897 | /* select a non-FCoE queue */ |
1898 | return __netdev_pick_tx(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); | 1898 | return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); |
1899 | } | 1899 | } |
1900 | 1900 | ||
1901 | void bnx2x_set_num_queues(struct bnx2x *bp) | 1901 | void bnx2x_set_num_queues(struct bnx2x *bp) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bfc58d488bb5..a89a40f88c25 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -496,7 +496,7 @@ int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); | |||
496 | 496 | ||
497 | /* select_queue callback */ | 497 | /* select_queue callback */ |
498 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | 498 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
499 | void *accel_priv); | 499 | void *accel_priv, select_queue_fallback_t fallback); |
500 | 500 | ||
501 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, | 501 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, |
502 | struct bnx2x_fastpath *fp, | 502 | struct bnx2x_fastpath *fp, |
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index add05f14b38b..1642de78aac8 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c | |||
@@ -1939,6 +1939,7 @@ static void tulip_remove_one(struct pci_dev *pdev) | |||
1939 | pci_iounmap(pdev, tp->base_addr); | 1939 | pci_iounmap(pdev, tp->base_addr); |
1940 | free_netdev (dev); | 1940 | free_netdev (dev); |
1941 | pci_release_regions (pdev); | 1941 | pci_release_regions (pdev); |
1942 | pci_disable_device(pdev); | ||
1942 | 1943 | ||
1943 | /* pci_power_off (pdev, -1); */ | 1944 | /* pci_power_off (pdev, -1); */ |
1944 | } | 1945 | } |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index d4782b42401b..903362a7b584 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -1778,8 +1778,6 @@ fec_enet_open(struct net_device *ndev) | |||
1778 | struct fec_enet_private *fep = netdev_priv(ndev); | 1778 | struct fec_enet_private *fep = netdev_priv(ndev); |
1779 | int ret; | 1779 | int ret; |
1780 | 1780 | ||
1781 | napi_enable(&fep->napi); | ||
1782 | |||
1783 | /* I should reset the ring buffers here, but I don't yet know | 1781 | /* I should reset the ring buffers here, but I don't yet know |
1784 | * a simple way to do that. | 1782 | * a simple way to do that. |
1785 | */ | 1783 | */ |
@@ -1794,6 +1792,8 @@ fec_enet_open(struct net_device *ndev) | |||
1794 | fec_enet_free_buffers(ndev); | 1792 | fec_enet_free_buffers(ndev); |
1795 | return ret; | 1793 | return ret; |
1796 | } | 1794 | } |
1795 | |||
1796 | napi_enable(&fep->napi); | ||
1797 | phy_start(fep->phy_dev); | 1797 | phy_start(fep->phy_dev); |
1798 | netif_start_queue(ndev); | 1798 | netif_start_queue(ndev); |
1799 | fep->opened = 1; | 1799 | fep->opened = 1; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 6d4ada72dfd0..18076c4178b4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -6881,7 +6881,7 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) | |||
6881 | } | 6881 | } |
6882 | 6882 | ||
6883 | static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | 6883 | static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, |
6884 | void *accel_priv) | 6884 | void *accel_priv, select_queue_fallback_t fallback) |
6885 | { | 6885 | { |
6886 | struct ixgbe_fwd_adapter *fwd_adapter = accel_priv; | 6886 | struct ixgbe_fwd_adapter *fwd_adapter = accel_priv; |
6887 | #ifdef IXGBE_FCOE | 6887 | #ifdef IXGBE_FCOE |
@@ -6907,7 +6907,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
6907 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) | 6907 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) |
6908 | break; | 6908 | break; |
6909 | default: | 6909 | default: |
6910 | return __netdev_pick_tx(dev, skb); | 6910 | return fallback(dev, skb); |
6911 | } | 6911 | } |
6912 | 6912 | ||
6913 | f = &adapter->ring_feature[RING_F_FCOE]; | 6913 | f = &adapter->ring_feature[RING_F_FCOE]; |
@@ -6920,7 +6920,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
6920 | 6920 | ||
6921 | return txq + f->offset; | 6921 | return txq + f->offset; |
6922 | #else | 6922 | #else |
6923 | return __netdev_pick_tx(dev, skb); | 6923 | return fallback(dev, skb); |
6924 | #endif | 6924 | #endif |
6925 | } | 6925 | } |
6926 | 6926 | ||
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 8f9266c64c75..fd4b6aecf6ee 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c | |||
@@ -619,7 +619,7 @@ ltq_etop_set_multicast_list(struct net_device *dev) | |||
619 | 619 | ||
620 | static u16 | 620 | static u16 |
621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, | 621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, |
622 | void *accel_priv) | 622 | void *accel_priv, select_queue_fallback_t fallback) |
623 | { | 623 | { |
624 | /* we are currently only using the first queue */ | 624 | /* we are currently only using the first queue */ |
625 | return 0; | 625 | return 0; |
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index 6300fd27f2db..68e6a6613e9a 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig | |||
@@ -43,12 +43,12 @@ config MVMDIO | |||
43 | This driver is used by the MV643XX_ETH and MVNETA drivers. | 43 | This driver is used by the MV643XX_ETH and MVNETA drivers. |
44 | 44 | ||
45 | config MVNETA | 45 | config MVNETA |
46 | tristate "Marvell Armada 370/XP network interface support" | 46 | tristate "Marvell Armada 370/38x/XP network interface support" |
47 | depends on MACH_ARMADA_370_XP | 47 | depends on PLAT_ORION |
48 | select MVMDIO | 48 | select MVMDIO |
49 | ---help--- | 49 | ---help--- |
50 | This driver supports the network interface units in the | 50 | This driver supports the network interface units in the |
51 | Marvell ARMADA XP and ARMADA 370 SoC family. | 51 | Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. |
52 | 52 | ||
53 | Note that this driver is distinct from the mv643xx_eth | 53 | Note that this driver is distinct from the mv643xx_eth |
54 | driver, which should be used for the older Marvell SoCs | 54 | driver, which should be used for the older Marvell SoCs |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 8e8a7eb43a2c..13457032d15f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -629,7 +629,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk | |||
629 | } | 629 | } |
630 | 630 | ||
631 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | 631 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, |
632 | void *accel_priv) | 632 | void *accel_priv, select_queue_fallback_t fallback) |
633 | { | 633 | { |
634 | struct mlx4_en_priv *priv = netdev_priv(dev); | 634 | struct mlx4_en_priv *priv = netdev_priv(dev); |
635 | u16 rings_p_up = priv->num_tx_rings_p_up; | 635 | u16 rings_p_up = priv->num_tx_rings_p_up; |
@@ -641,7 +641,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
641 | if (vlan_tx_tag_present(skb)) | 641 | if (vlan_tx_tag_present(skb)) |
642 | up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; | 642 | up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; |
643 | 643 | ||
644 | return __netdev_pick_tx(dev, skb) % rings_p_up + up * rings_p_up; | 644 | return fallback(dev, skb) % rings_p_up + up * rings_p_up; |
645 | } | 645 | } |
646 | 646 | ||
647 | static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) | 647 | static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 3af04c3f42ea..9ca223bc90fc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -723,7 +723,7 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | |||
723 | 723 | ||
724 | void mlx4_en_tx_irq(struct mlx4_cq *mcq); | 724 | void mlx4_en_tx_irq(struct mlx4_cq *mcq); |
725 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | 725 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, |
726 | void *accel_priv); | 726 | void *accel_priv, select_queue_fallback_t fallback); |
727 | netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); | 727 | netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); |
728 | 728 | ||
729 | int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, | 729 | int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, |
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index e2f202e3932f..f2d7c702c77f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
@@ -37,6 +37,17 @@ config DWMAC_SUNXI | |||
37 | stmmac device driver. This driver is used for A20/A31 | 37 | stmmac device driver. This driver is used for A20/A31 |
38 | GMAC ethernet controller. | 38 | GMAC ethernet controller. |
39 | 39 | ||
40 | config DWMAC_STI | ||
41 | bool "STi GMAC support" | ||
42 | depends on STMMAC_PLATFORM && ARCH_STI | ||
43 | default y | ||
44 | ---help--- | ||
45 | Support for ethernet controller on STi SOCs. | ||
46 | |||
47 | This selects STi SoC glue layer support for the stmmac | ||
48 | device driver. This driver is used on for the STi series | ||
49 | SOCs GMAC ethernet controller. | ||
50 | |||
40 | config STMMAC_PCI | 51 | config STMMAC_PCI |
41 | bool "STMMAC PCI bus support" | 52 | bool "STMMAC PCI bus support" |
42 | depends on STMMAC_ETH && PCI | 53 | depends on STMMAC_ETH && PCI |
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index ecadecea79b2..dcef28775dad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile | |||
@@ -2,6 +2,7 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o | |||
2 | stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o | 2 | stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o |
3 | stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o | 3 | stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o |
4 | stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o | 4 | stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o |
5 | stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o | ||
5 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ | 6 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ |
6 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ | 7 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ |
7 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ | 8 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c new file mode 100644 index 000000000000..552bbc17863c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | |||
@@ -0,0 +1,330 @@ | |||
1 | /** | ||
2 | * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer | ||
3 | * | ||
4 | * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited | ||
5 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
6 | * | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/stmmac.h> | ||
18 | #include <linux/phy.h> | ||
19 | #include <linux/mfd/syscon.h> | ||
20 | #include <linux/regmap.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_net.h> | ||
24 | |||
25 | /** | ||
26 | * STi GMAC glue logic. | ||
27 | * -------------------- | ||
28 | * | ||
29 | * _ | ||
30 | * | \ | ||
31 | * --------|0 \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK | ||
32 | * phyclk | |___________________________________________ | ||
33 | * | | | (phyclk-in) | ||
34 | * --------|1 / | | ||
35 | * int-clk |_ / | | ||
36 | * | _ | ||
37 | * | | \ | ||
38 | * |_______|1 \ ETH_SEL_TX_RETIME_CLK | ||
39 | * | |___________________________ | ||
40 | * | | (tx-retime-clk) | ||
41 | * _______|0 / | ||
42 | * | |_ / | ||
43 | * _ | | ||
44 | * | \ | | ||
45 | * --------|0 \ | | ||
46 | * clk_125 | |__| | ||
47 | * | | ETH_SEL_TXCLK_NOT_CLK125 | ||
48 | * --------|1 / | ||
49 | * txclk |_ / | ||
50 | * | ||
51 | * | ||
52 | * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can | ||
53 | * generate 50MHz clock or MAC can generate it. | ||
54 | * This bit is configured by "st,ext-phyclk" property. | ||
55 | * | ||
56 | * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz | ||
57 | * clock either comes from clk-125 pin or txclk pin. This configuration is | ||
58 | * totally driven by the board wiring. This bit is configured by | ||
59 | * "st,tx-retime-src" property. | ||
60 | * | ||
61 | * TXCLK configuration is different for different phy interface modes | ||
62 | * and changes according to link speed in modes like RGMII. | ||
63 | * | ||
64 | * Below table summarizes the clock requirement and clock sources for | ||
65 | * supported phy interface modes with link speeds. | ||
66 | * ________________________________________________ | ||
67 | *| PHY_MODE | 1000 Mbit Link | 100 Mbit Link | | ||
68 | * ------------------------------------------------ | ||
69 | *| MII | n/a | 25Mhz | | ||
70 | *| | | txclk | | ||
71 | * ------------------------------------------------ | ||
72 | *| GMII | 125Mhz | 25Mhz | | ||
73 | *| | clk-125/txclk | txclk | | ||
74 | * ------------------------------------------------ | ||
75 | *| RGMII | 125Mhz | 25Mhz | | ||
76 | *| | clk-125/txclk | clkgen | | ||
77 | * ------------------------------------------------ | ||
78 | *| RMII | n/a | 25Mhz | | ||
79 | *| | |clkgen/phyclk-in | | ||
80 | * ------------------------------------------------ | ||
81 | * | ||
82 | * TX lines are always retimed with a clk, which can vary depending | ||
83 | * on the board configuration. Below is the table of these bits | ||
84 | * in eth configuration register depending on source of retime clk. | ||
85 | * | ||
86 | *--------------------------------------------------------------- | ||
87 | * src | tx_rt_clk | int_not_ext_phyclk | txclk_n_clk125| | ||
88 | *--------------------------------------------------------------- | ||
89 | * txclk | 0 | n/a | 1 | | ||
90 | *--------------------------------------------------------------- | ||
91 | * ck_125| 0 | n/a | 0 | | ||
92 | *--------------------------------------------------------------- | ||
93 | * phyclk| 1 | 0 | n/a | | ||
94 | *--------------------------------------------------------------- | ||
95 | * clkgen| 1 | 1 | n/a | | ||
96 | *--------------------------------------------------------------- | ||
97 | */ | ||
98 | |||
99 | /* Register definition */ | ||
100 | |||
101 | /* 3 bits [8:6] | ||
102 | * [6:6] ETH_SEL_TXCLK_NOT_CLK125 | ||
103 | * [7:7] ETH_SEL_INTERNAL_NOTEXT_PHYCLK | ||
104 | * [8:8] ETH_SEL_TX_RETIME_CLK | ||
105 | * | ||
106 | */ | ||
107 | |||
108 | #define TX_RETIME_SRC_MASK GENMASK(8, 6) | ||
109 | #define ETH_SEL_TX_RETIME_CLK BIT(8) | ||
110 | #define ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7) | ||
111 | #define ETH_SEL_TXCLK_NOT_CLK125 BIT(6) | ||
112 | |||
113 | #define ENMII_MASK GENMASK(5, 5) | ||
114 | #define ENMII BIT(5) | ||
115 | |||
116 | /** | ||
117 | * 3 bits [4:2] | ||
118 | * 000-GMII/MII | ||
119 | * 001-RGMII | ||
120 | * 010-SGMII | ||
121 | * 100-RMII | ||
122 | */ | ||
123 | #define MII_PHY_SEL_MASK GENMASK(4, 2) | ||
124 | #define ETH_PHY_SEL_RMII BIT(4) | ||
125 | #define ETH_PHY_SEL_SGMII BIT(3) | ||
126 | #define ETH_PHY_SEL_RGMII BIT(2) | ||
127 | #define ETH_PHY_SEL_GMII 0x0 | ||
128 | #define ETH_PHY_SEL_MII 0x0 | ||
129 | |||
130 | #define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \ | ||
131 | iface == PHY_INTERFACE_MODE_RGMII_ID || \ | ||
132 | iface == PHY_INTERFACE_MODE_RGMII_RXID || \ | ||
133 | iface == PHY_INTERFACE_MODE_RGMII_TXID) | ||
134 | |||
135 | #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \ | ||
136 | iface == PHY_INTERFACE_MODE_GMII) | ||
137 | |||
138 | struct sti_dwmac { | ||
139 | int interface; | ||
140 | bool ext_phyclk; | ||
141 | bool is_tx_retime_src_clk_125; | ||
142 | struct clk *clk; | ||
143 | int reg; | ||
144 | struct device *dev; | ||
145 | struct regmap *regmap; | ||
146 | }; | ||
147 | |||
148 | static u32 phy_intf_sels[] = { | ||
149 | [PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII, | ||
150 | [PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII, | ||
151 | [PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII, | ||
152 | [PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII, | ||
153 | [PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII, | ||
154 | [PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII, | ||
155 | }; | ||
156 | |||
157 | enum { | ||
158 | TX_RETIME_SRC_NA = 0, | ||
159 | TX_RETIME_SRC_TXCLK = 1, | ||
160 | TX_RETIME_SRC_CLK_125, | ||
161 | TX_RETIME_SRC_PHYCLK, | ||
162 | TX_RETIME_SRC_CLKGEN, | ||
163 | }; | ||
164 | |||
165 | static const char *const tx_retime_srcs[] = { | ||
166 | [TX_RETIME_SRC_NA] = "", | ||
167 | [TX_RETIME_SRC_TXCLK] = "txclk", | ||
168 | [TX_RETIME_SRC_CLK_125] = "clk_125", | ||
169 | [TX_RETIME_SRC_PHYCLK] = "phyclk", | ||
170 | [TX_RETIME_SRC_CLKGEN] = "clkgen", | ||
171 | }; | ||
172 | |||
173 | static u32 tx_retime_val[] = { | ||
174 | [TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125, | ||
175 | [TX_RETIME_SRC_CLK_125] = 0x0, | ||
176 | [TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK, | ||
177 | [TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK | | ||
178 | ETH_SEL_INTERNAL_NOTEXT_PHYCLK, | ||
179 | }; | ||
180 | |||
181 | static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd) | ||
182 | { | ||
183 | u32 src = 0, freq = 0; | ||
184 | |||
185 | if (spd == SPEED_100) { | ||
186 | if (dwmac->interface == PHY_INTERFACE_MODE_MII || | ||
187 | dwmac->interface == PHY_INTERFACE_MODE_GMII) { | ||
188 | src = TX_RETIME_SRC_TXCLK; | ||
189 | } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { | ||
190 | if (dwmac->ext_phyclk) { | ||
191 | src = TX_RETIME_SRC_PHYCLK; | ||
192 | } else { | ||
193 | src = TX_RETIME_SRC_CLKGEN; | ||
194 | freq = 50000000; | ||
195 | } | ||
196 | |||
197 | } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) { | ||
198 | src = TX_RETIME_SRC_CLKGEN; | ||
199 | freq = 25000000; | ||
200 | } | ||
201 | |||
202 | if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk) | ||
203 | clk_set_rate(dwmac->clk, freq); | ||
204 | |||
205 | } else if (spd == SPEED_1000) { | ||
206 | if (dwmac->is_tx_retime_src_clk_125) | ||
207 | src = TX_RETIME_SRC_CLK_125; | ||
208 | else | ||
209 | src = TX_RETIME_SRC_TXCLK; | ||
210 | } | ||
211 | |||
212 | regmap_update_bits(dwmac->regmap, dwmac->reg, | ||
213 | TX_RETIME_SRC_MASK, tx_retime_val[src]); | ||
214 | } | ||
215 | |||
216 | static void sti_dwmac_exit(struct platform_device *pdev, void *priv) | ||
217 | { | ||
218 | struct sti_dwmac *dwmac = priv; | ||
219 | |||
220 | if (dwmac->clk) | ||
221 | clk_disable_unprepare(dwmac->clk); | ||
222 | } | ||
223 | |||
224 | static void sti_fix_mac_speed(void *priv, unsigned int spd) | ||
225 | { | ||
226 | struct sti_dwmac *dwmac = priv; | ||
227 | |||
228 | setup_retime_src(dwmac, spd); | ||
229 | |||
230 | return; | ||
231 | } | ||
232 | |||
233 | static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, | ||
234 | struct platform_device *pdev) | ||
235 | { | ||
236 | struct resource *res; | ||
237 | struct device *dev = &pdev->dev; | ||
238 | struct device_node *np = dev->of_node; | ||
239 | struct regmap *regmap; | ||
240 | int err; | ||
241 | |||
242 | if (!np) | ||
243 | return -EINVAL; | ||
244 | |||
245 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf"); | ||
246 | if (!res) | ||
247 | return -ENODATA; | ||
248 | |||
249 | regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); | ||
250 | if (IS_ERR(regmap)) | ||
251 | return PTR_ERR(regmap); | ||
252 | |||
253 | dwmac->dev = dev; | ||
254 | dwmac->interface = of_get_phy_mode(np); | ||
255 | dwmac->regmap = regmap; | ||
256 | dwmac->reg = res->start; | ||
257 | dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); | ||
258 | dwmac->is_tx_retime_src_clk_125 = false; | ||
259 | |||
260 | if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { | ||
261 | const char *rs; | ||
262 | |||
263 | err = of_property_read_string(np, "st,tx-retime-src", &rs); | ||
264 | if (err < 0) { | ||
265 | dev_err(dev, "st,tx-retime-src not specified\n"); | ||
266 | return err; | ||
267 | } | ||
268 | |||
269 | if (!strcasecmp(rs, "clk_125")) | ||
270 | dwmac->is_tx_retime_src_clk_125 = true; | ||
271 | } | ||
272 | |||
273 | dwmac->clk = devm_clk_get(dev, "sti-ethclk"); | ||
274 | |||
275 | if (IS_ERR(dwmac->clk)) | ||
276 | dwmac->clk = NULL; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int sti_dwmac_init(struct platform_device *pdev, void *priv) | ||
282 | { | ||
283 | struct sti_dwmac *dwmac = priv; | ||
284 | struct regmap *regmap = dwmac->regmap; | ||
285 | int iface = dwmac->interface; | ||
286 | u32 reg = dwmac->reg; | ||
287 | u32 val, spd; | ||
288 | |||
289 | if (dwmac->clk) | ||
290 | clk_prepare_enable(dwmac->clk); | ||
291 | |||
292 | regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]); | ||
293 | |||
294 | val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII; | ||
295 | regmap_update_bits(regmap, reg, ENMII_MASK, val); | ||
296 | |||
297 | if (IS_PHY_IF_MODE_GBIT(iface)) | ||
298 | spd = SPEED_1000; | ||
299 | else | ||
300 | spd = SPEED_100; | ||
301 | |||
302 | setup_retime_src(dwmac, spd); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void *sti_dwmac_setup(struct platform_device *pdev) | ||
308 | { | ||
309 | struct sti_dwmac *dwmac; | ||
310 | int ret; | ||
311 | |||
312 | dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); | ||
313 | if (!dwmac) | ||
314 | return ERR_PTR(-ENOMEM); | ||
315 | |||
316 | ret = sti_dwmac_parse_data(dwmac, pdev); | ||
317 | if (ret) { | ||
318 | dev_err(&pdev->dev, "Unable to parse OF data\n"); | ||
319 | return ERR_PTR(ret); | ||
320 | } | ||
321 | |||
322 | return dwmac; | ||
323 | } | ||
324 | |||
325 | const struct stmmac_of_data sti_gmac_data = { | ||
326 | .fix_mac_speed = sti_fix_mac_speed, | ||
327 | .setup = sti_dwmac_setup, | ||
328 | .init = sti_dwmac_init, | ||
329 | .exit = sti_dwmac_exit, | ||
330 | }; | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index d9af26ed58ee..f9e60d7918c4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
@@ -133,6 +133,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv); | |||
133 | #ifdef CONFIG_DWMAC_SUNXI | 133 | #ifdef CONFIG_DWMAC_SUNXI |
134 | extern const struct stmmac_of_data sun7i_gmac_data; | 134 | extern const struct stmmac_of_data sun7i_gmac_data; |
135 | #endif | 135 | #endif |
136 | #ifdef CONFIG_DWMAC_STI | ||
137 | extern const struct stmmac_of_data sti_gmac_data; | ||
138 | #endif | ||
136 | extern struct platform_driver stmmac_pltfr_driver; | 139 | extern struct platform_driver stmmac_pltfr_driver; |
137 | static inline int stmmac_register_platform(void) | 140 | static inline int stmmac_register_platform(void) |
138 | { | 141 | { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 5884a7d2063b..c61bc72b8e90 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -33,6 +33,11 @@ static const struct of_device_id stmmac_dt_ids[] = { | |||
33 | #ifdef CONFIG_DWMAC_SUNXI | 33 | #ifdef CONFIG_DWMAC_SUNXI |
34 | { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, | 34 | { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, |
35 | #endif | 35 | #endif |
36 | #ifdef CONFIG_DWMAC_STI | ||
37 | { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data}, | ||
38 | { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, | ||
39 | { .compatible = "st,stih127-dwmac", .data = &sti_gmac_data}, | ||
40 | #endif | ||
36 | /* SoC specific glue layers should come before generic bindings */ | 41 | /* SoC specific glue layers should come before generic bindings */ |
37 | { .compatible = "st,spear600-gmac"}, | 42 | { .compatible = "st,spear600-gmac"}, |
38 | { .compatible = "snps,dwmac-3.610"}, | 43 | { .compatible = "snps,dwmac-3.610"}, |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 1d860ce914ed..651087b5c8da 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -554,7 +554,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
554 | * common for both the interface as the interface shares | 554 | * common for both the interface as the interface shares |
555 | * the same hardware resource. | 555 | * the same hardware resource. |
556 | */ | 556 | */ |
557 | for (i = 0; i <= priv->data.slaves; i++) | 557 | for (i = 0; i < priv->data.slaves; i++) |
558 | if (priv->slaves[i].ndev->flags & IFF_PROMISC) | 558 | if (priv->slaves[i].ndev->flags & IFF_PROMISC) |
559 | flag = true; | 559 | flag = true; |
560 | 560 | ||
@@ -578,7 +578,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
578 | unsigned long timeout = jiffies + HZ; | 578 | unsigned long timeout = jiffies + HZ; |
579 | 579 | ||
580 | /* Disable Learn for all ports */ | 580 | /* Disable Learn for all ports */ |
581 | for (i = 0; i <= priv->data.slaves; i++) { | 581 | for (i = 0; i < priv->data.slaves; i++) { |
582 | cpsw_ale_control_set(ale, i, | 582 | cpsw_ale_control_set(ale, i, |
583 | ALE_PORT_NOLEARN, 1); | 583 | ALE_PORT_NOLEARN, 1); |
584 | cpsw_ale_control_set(ale, i, | 584 | cpsw_ale_control_set(ale, i, |
@@ -606,7 +606,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
606 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); | 606 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); |
607 | 607 | ||
608 | /* Enable Learn for all ports */ | 608 | /* Enable Learn for all ports */ |
609 | for (i = 0; i <= priv->data.slaves; i++) { | 609 | for (i = 0; i < priv->data.slaves; i++) { |
610 | cpsw_ale_control_set(ale, i, | 610 | cpsw_ale_control_set(ale, i, |
611 | ALE_PORT_NOLEARN, 0); | 611 | ALE_PORT_NOLEARN, 0); |
612 | cpsw_ale_control_set(ale, i, | 612 | cpsw_ale_control_set(ale, i, |
@@ -1896,6 +1896,11 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
1896 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); | 1896 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); |
1897 | 1897 | ||
1898 | slave_data->phy_if = of_get_phy_mode(slave_node); | 1898 | slave_data->phy_if = of_get_phy_mode(slave_node); |
1899 | if (slave_data->phy_if < 0) { | ||
1900 | pr_err("Missing or malformed slave[%d] phy-mode property\n", | ||
1901 | i); | ||
1902 | return slave_data->phy_if; | ||
1903 | } | ||
1899 | 1904 | ||
1900 | if (data->dual_emac) { | 1905 | if (data->dual_emac) { |
1901 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", | 1906 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", |
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 023237a65720..17503da9f7a5 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c | |||
@@ -2071,7 +2071,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) | |||
2071 | 2071 | ||
2072 | /* Return subqueue id on this core (one per core). */ | 2072 | /* Return subqueue id on this core (one per core). */ |
2073 | static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, | 2073 | static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, |
2074 | void *accel_priv) | 2074 | void *accel_priv, select_queue_fallback_t fallback) |
2075 | { | 2075 | { |
2076 | return smp_processor_id(); | 2076 | return smp_processor_id(); |
2077 | } | 2077 | } |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1ec65feebb9e..4bfdf8c7ada0 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
27 | #include <linux/of_mdio.h> | 27 | #include <linux/of_mdio.h> |
28 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
29 | #include <linux/of_irq.h> | ||
29 | #include <linux/of_address.h> | 30 | #include <linux/of_address.h> |
30 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
31 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
@@ -600,7 +601,8 @@ static void axienet_start_xmit_done(struct net_device *ndev) | |||
600 | size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; | 601 | size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; |
601 | packets++; | 602 | packets++; |
602 | 603 | ||
603 | lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM; | 604 | ++lp->tx_bd_ci; |
605 | lp->tx_bd_ci %= TX_BD_NUM; | ||
604 | cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | 606 | cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; |
605 | status = cur_p->status; | 607 | status = cur_p->status; |
606 | } | 608 | } |
@@ -686,7 +688,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
686 | skb_headlen(skb), DMA_TO_DEVICE); | 688 | skb_headlen(skb), DMA_TO_DEVICE); |
687 | 689 | ||
688 | for (ii = 0; ii < num_frag; ii++) { | 690 | for (ii = 0; ii < num_frag; ii++) { |
689 | lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; | 691 | ++lp->tx_bd_tail; |
692 | lp->tx_bd_tail %= TX_BD_NUM; | ||
690 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | 693 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
691 | frag = &skb_shinfo(skb)->frags[ii]; | 694 | frag = &skb_shinfo(skb)->frags[ii]; |
692 | cur_p->phys = dma_map_single(ndev->dev.parent, | 695 | cur_p->phys = dma_map_single(ndev->dev.parent, |
@@ -702,7 +705,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
702 | tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | 705 | tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; |
703 | /* Start the transfer */ | 706 | /* Start the transfer */ |
704 | axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); | 707 | axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); |
705 | lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; | 708 | ++lp->tx_bd_tail; |
709 | lp->tx_bd_tail %= TX_BD_NUM; | ||
706 | 710 | ||
707 | return NETDEV_TX_OK; | 711 | return NETDEV_TX_OK; |
708 | } | 712 | } |
@@ -774,7 +778,8 @@ static void axienet_recv(struct net_device *ndev) | |||
774 | cur_p->status = 0; | 778 | cur_p->status = 0; |
775 | cur_p->sw_id_offset = (u32) new_skb; | 779 | cur_p->sw_id_offset = (u32) new_skb; |
776 | 780 | ||
777 | lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM; | 781 | ++lp->rx_bd_ci; |
782 | lp->rx_bd_ci %= RX_BD_NUM; | ||
778 | cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | 783 | cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; |
779 | } | 784 | } |
780 | 785 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 7756118c2f0a..7141a1937360 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -88,8 +88,12 @@ static int netvsc_open(struct net_device *net) | |||
88 | { | 88 | { |
89 | struct net_device_context *net_device_ctx = netdev_priv(net); | 89 | struct net_device_context *net_device_ctx = netdev_priv(net); |
90 | struct hv_device *device_obj = net_device_ctx->device_ctx; | 90 | struct hv_device *device_obj = net_device_ctx->device_ctx; |
91 | struct netvsc_device *nvdev; | ||
92 | struct rndis_device *rdev; | ||
91 | int ret = 0; | 93 | int ret = 0; |
92 | 94 | ||
95 | netif_carrier_off(net); | ||
96 | |||
93 | /* Open up the device */ | 97 | /* Open up the device */ |
94 | ret = rndis_filter_open(device_obj); | 98 | ret = rndis_filter_open(device_obj); |
95 | if (ret != 0) { | 99 | if (ret != 0) { |
@@ -99,6 +103,11 @@ static int netvsc_open(struct net_device *net) | |||
99 | 103 | ||
100 | netif_start_queue(net); | 104 | netif_start_queue(net); |
101 | 105 | ||
106 | nvdev = hv_get_drvdata(device_obj); | ||
107 | rdev = nvdev->extension; | ||
108 | if (!rdev->link_state) | ||
109 | netif_carrier_on(net); | ||
110 | |||
102 | return ret; | 111 | return ret; |
103 | } | 112 | } |
104 | 113 | ||
@@ -229,23 +238,24 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, | |||
229 | struct net_device *net; | 238 | struct net_device *net; |
230 | struct net_device_context *ndev_ctx; | 239 | struct net_device_context *ndev_ctx; |
231 | struct netvsc_device *net_device; | 240 | struct netvsc_device *net_device; |
241 | struct rndis_device *rdev; | ||
232 | 242 | ||
233 | net_device = hv_get_drvdata(device_obj); | 243 | net_device = hv_get_drvdata(device_obj); |
244 | rdev = net_device->extension; | ||
245 | |||
246 | rdev->link_state = status != 1; | ||
247 | |||
234 | net = net_device->ndev; | 248 | net = net_device->ndev; |
235 | 249 | ||
236 | if (!net) { | 250 | if (!net || net->reg_state != NETREG_REGISTERED) |
237 | netdev_err(net, "got link status but net device " | ||
238 | "not initialized yet\n"); | ||
239 | return; | 251 | return; |
240 | } | ||
241 | 252 | ||
253 | ndev_ctx = netdev_priv(net); | ||
242 | if (status == 1) { | 254 | if (status == 1) { |
243 | netif_carrier_on(net); | ||
244 | ndev_ctx = netdev_priv(net); | ||
245 | schedule_delayed_work(&ndev_ctx->dwork, 0); | 255 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
246 | schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); | 256 | schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); |
247 | } else { | 257 | } else { |
248 | netif_carrier_off(net); | 258 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
249 | } | 259 | } |
250 | } | 260 | } |
251 | 261 | ||
@@ -388,17 +398,35 @@ static const struct net_device_ops device_ops = { | |||
388 | * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add | 398 | * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add |
389 | * another netif_notify_peers() into a delayed work, otherwise GARP packet | 399 | * another netif_notify_peers() into a delayed work, otherwise GARP packet |
390 | * will not be sent after quick migration, and cause network disconnection. | 400 | * will not be sent after quick migration, and cause network disconnection. |
401 | * Also, we update the carrier status here. | ||
391 | */ | 402 | */ |
392 | static void netvsc_send_garp(struct work_struct *w) | 403 | static void netvsc_link_change(struct work_struct *w) |
393 | { | 404 | { |
394 | struct net_device_context *ndev_ctx; | 405 | struct net_device_context *ndev_ctx; |
395 | struct net_device *net; | 406 | struct net_device *net; |
396 | struct netvsc_device *net_device; | 407 | struct netvsc_device *net_device; |
408 | struct rndis_device *rdev; | ||
409 | bool notify; | ||
410 | |||
411 | rtnl_lock(); | ||
397 | 412 | ||
398 | ndev_ctx = container_of(w, struct net_device_context, dwork.work); | 413 | ndev_ctx = container_of(w, struct net_device_context, dwork.work); |
399 | net_device = hv_get_drvdata(ndev_ctx->device_ctx); | 414 | net_device = hv_get_drvdata(ndev_ctx->device_ctx); |
415 | rdev = net_device->extension; | ||
400 | net = net_device->ndev; | 416 | net = net_device->ndev; |
401 | netdev_notify_peers(net); | 417 | |
418 | if (rdev->link_state) { | ||
419 | netif_carrier_off(net); | ||
420 | notify = false; | ||
421 | } else { | ||
422 | netif_carrier_on(net); | ||
423 | notify = true; | ||
424 | } | ||
425 | |||
426 | rtnl_unlock(); | ||
427 | |||
428 | if (notify) | ||
429 | netdev_notify_peers(net); | ||
402 | } | 430 | } |
403 | 431 | ||
404 | 432 | ||
@@ -414,13 +442,10 @@ static int netvsc_probe(struct hv_device *dev, | |||
414 | if (!net) | 442 | if (!net) |
415 | return -ENOMEM; | 443 | return -ENOMEM; |
416 | 444 | ||
417 | /* Set initial state */ | ||
418 | netif_carrier_off(net); | ||
419 | |||
420 | net_device_ctx = netdev_priv(net); | 445 | net_device_ctx = netdev_priv(net); |
421 | net_device_ctx->device_ctx = dev; | 446 | net_device_ctx->device_ctx = dev; |
422 | hv_set_drvdata(dev, net); | 447 | hv_set_drvdata(dev, net); |
423 | INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); | 448 | INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); |
424 | INIT_WORK(&net_device_ctx->work, do_set_multicast); | 449 | INIT_WORK(&net_device_ctx->work, do_set_multicast); |
425 | 450 | ||
426 | net->netdev_ops = &device_ops; | 451 | net->netdev_ops = &device_ops; |
@@ -443,8 +468,6 @@ static int netvsc_probe(struct hv_device *dev, | |||
443 | } | 468 | } |
444 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); | 469 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); |
445 | 470 | ||
446 | netif_carrier_on(net); | ||
447 | |||
448 | ret = register_netdev(net); | 471 | ret = register_netdev(net); |
449 | if (ret != 0) { | 472 | if (ret != 0) { |
450 | pr_err("Unable to register netdev.\n"); | 473 | pr_err("Unable to register netdev.\n"); |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 177441afeb96..24b6dddd7f2f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -522,7 +522,6 @@ static void irtty_close(struct tty_struct *tty) | |||
522 | sirdev_put_instance(priv->dev); | 522 | sirdev_put_instance(priv->dev); |
523 | 523 | ||
524 | /* Stop tty */ | 524 | /* Stop tty */ |
525 | irtty_stop_receiver(tty, TRUE); | ||
526 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 525 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
527 | if (tty->ops->stop) | 526 | if (tty->ops->stop) |
528 | tty->ops->stop(tty); | 527 | tty->ops->stop(tty); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 8433de4509c7..a5d21893670d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -879,14 +879,15 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, | |||
879 | dev->priv_flags |= IFF_MACVLAN; | 879 | dev->priv_flags |= IFF_MACVLAN; |
880 | err = netdev_upper_dev_link(lowerdev, dev); | 880 | err = netdev_upper_dev_link(lowerdev, dev); |
881 | if (err) | 881 | if (err) |
882 | goto destroy_port; | 882 | goto unregister_netdev; |
883 | |||
884 | 883 | ||
885 | list_add_tail_rcu(&vlan->list, &port->vlans); | 884 | list_add_tail_rcu(&vlan->list, &port->vlans); |
886 | netif_stacked_transfer_operstate(lowerdev, dev); | 885 | netif_stacked_transfer_operstate(lowerdev, dev); |
887 | 886 | ||
888 | return 0; | 887 | return 0; |
889 | 888 | ||
889 | unregister_netdev: | ||
890 | unregister_netdevice(dev); | ||
890 | destroy_port: | 891 | destroy_port: |
891 | port->count -= 1; | 892 | port->count -= 1; |
892 | if (!port->count) | 893 | if (!port->count) |
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 9414fa272160..98e7cbf720a5 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
@@ -1006,11 +1006,6 @@ static int dp83640_probe(struct phy_device *phydev) | |||
1006 | } else | 1006 | } else |
1007 | list_add_tail(&dp83640->list, &clock->phylist); | 1007 | list_add_tail(&dp83640->list, &clock->phylist); |
1008 | 1008 | ||
1009 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
1010 | recalibrate(clock); | ||
1011 | else | ||
1012 | enable_broadcast(dp83640->phydev, clock->page, 1); | ||
1013 | |||
1014 | dp83640_clock_put(clock); | 1009 | dp83640_clock_put(clock); |
1015 | return 0; | 1010 | return 0; |
1016 | 1011 | ||
@@ -1063,6 +1058,14 @@ static void dp83640_remove(struct phy_device *phydev) | |||
1063 | 1058 | ||
1064 | static int dp83640_config_init(struct phy_device *phydev) | 1059 | static int dp83640_config_init(struct phy_device *phydev) |
1065 | { | 1060 | { |
1061 | struct dp83640_private *dp83640 = phydev->priv; | ||
1062 | struct dp83640_clock *clock = dp83640->clock; | ||
1063 | |||
1064 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
1065 | recalibrate(clock); | ||
1066 | else | ||
1067 | enable_broadcast(phydev, clock->page, 1); | ||
1068 | |||
1066 | enable_status_frames(phydev, true); | 1069 | enable_status_frames(phydev, true); |
1067 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | 1070 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); |
1068 | return 0; | 1071 | return 0; |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 28407426fd6f..c8624a8235ab 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -1648,7 +1648,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb, | 1650 | static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb, |
1651 | void *accel_priv) | 1651 | void *accel_priv, select_queue_fallback_t fallback) |
1652 | { | 1652 | { |
1653 | /* | 1653 | /* |
1654 | * This helper function exists to help dev_pick_tx get the correct | 1654 | * This helper function exists to help dev_pick_tx get the correct |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 44c4db8450f0..8fe9cb7d0f72 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -366,7 +366,7 @@ static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) | |||
366 | * hope the rxq no. may help here. | 366 | * hope the rxq no. may help here. |
367 | */ | 367 | */ |
368 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, | 368 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, |
369 | void *accel_priv) | 369 | void *accel_priv, select_queue_fallback_t fallback) |
370 | { | 370 | { |
371 | struct tun_struct *tun = netdev_priv(dev); | 371 | struct tun_struct *tun = netdev_priv(dev); |
372 | struct tun_flow_entry *e; | 372 | struct tun_flow_entry *e; |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 409499fdb157..7e7269fd3707 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -296,7 +296,6 @@ config USB_NET_SR9800 | |||
296 | tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" | 296 | tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" |
297 | depends on USB_USBNET | 297 | depends on USB_USBNET |
298 | select CRC32 | 298 | select CRC32 |
299 | default y | ||
300 | ---help--- | 299 | ---help--- |
301 | Say Y if you want to use one of the following 100Mbps USB Ethernet | 300 | Say Y if you want to use one of the following 100Mbps USB Ethernet |
302 | device based on the CoreChip-sz SR9800 chip. | 301 | device based on the CoreChip-sz SR9800 chip. |
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 9765a7d4766d..5d194093f3e1 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c | |||
@@ -917,7 +917,8 @@ static const struct driver_info ax88178_info = { | |||
917 | .status = asix_status, | 917 | .status = asix_status, |
918 | .link_reset = ax88178_link_reset, | 918 | .link_reset = ax88178_link_reset, |
919 | .reset = ax88178_reset, | 919 | .reset = ax88178_reset, |
920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, | 920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | |
921 | FLAG_MULTI_PACKET, | ||
921 | .rx_fixup = asix_rx_fixup_common, | 922 | .rx_fixup = asix_rx_fixup_common, |
922 | .tx_fixup = asix_tx_fixup, | 923 | .tx_fixup = asix_tx_fixup, |
923 | }; | 924 | }; |
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index d6f64dad05bc..955df81a4358 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c | |||
@@ -1118,6 +1118,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1118 | u16 hdr_off; | 1118 | u16 hdr_off; |
1119 | u32 *pkt_hdr; | 1119 | u32 *pkt_hdr; |
1120 | 1120 | ||
1121 | /* This check is no longer done by usbnet */ | ||
1122 | if (skb->len < dev->net->hard_header_len) | ||
1123 | return 0; | ||
1124 | |||
1121 | skb_trim(skb, skb->len - 4); | 1125 | skb_trim(skb, skb->len - 4); |
1122 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); | 1126 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); |
1123 | le32_to_cpus(&rx_hdr); | 1127 | le32_to_cpus(&rx_hdr); |
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index e4a8a93fbaf7..1cc24e6f23e2 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c | |||
@@ -84,6 +84,10 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
84 | u32 size; | 84 | u32 size; |
85 | u32 count; | 85 | u32 count; |
86 | 86 | ||
87 | /* This check is no longer done by usbnet */ | ||
88 | if (skb->len < dev->net->hard_header_len) | ||
89 | return 0; | ||
90 | |||
87 | header = (struct gl_header *) skb->data; | 91 | header = (struct gl_header *) skb->data; |
88 | 92 | ||
89 | // get the packet count of the received skb | 93 | // get the packet count of the received skb |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index a305a7b2dae6..82d844a8ebd0 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -526,8 +526,9 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
526 | { | 526 | { |
527 | u8 status; | 527 | u8 status; |
528 | 528 | ||
529 | if (skb->len == 0) { | 529 | /* This check is no longer done by usbnet */ |
530 | dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); | 530 | if (skb->len < dev->net->hard_header_len) { |
531 | dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); | ||
531 | return 0; | 532 | return 0; |
532 | } | 533 | } |
533 | 534 | ||
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index 0a85d9227775..4cbdb1307f3e 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
@@ -364,6 +364,10 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
364 | struct nc_trailer *trailer; | 364 | struct nc_trailer *trailer; |
365 | u16 hdr_len, packet_len; | 365 | u16 hdr_len, packet_len; |
366 | 366 | ||
367 | /* This check is no longer done by usbnet */ | ||
368 | if (skb->len < dev->net->hard_header_len) | ||
369 | return 0; | ||
370 | |||
367 | if (!(skb->len & 0x01)) { | 371 | if (!(skb->len & 0x01)) { |
368 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", | 372 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", |
369 | skb->len, dev->net->hard_header_len, dev->hard_mtu, | 373 | skb->len, dev->net->hard_header_len, dev->hard_mtu, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index ff5c87128ffe..313cb6cd4848 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -80,10 +80,10 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
80 | { | 80 | { |
81 | __be16 proto; | 81 | __be16 proto; |
82 | 82 | ||
83 | /* usbnet rx_complete guarantees that skb->len is at least | 83 | /* This check is no longer done by usbnet */ |
84 | * hard_header_len, so we can inspect the dest address without | 84 | if (skb->len < dev->net->hard_header_len) |
85 | * checking skb->len | 85 | return 0; |
86 | */ | 86 | |
87 | switch (skb->data[0] & 0xf0) { | 87 | switch (skb->data[0] & 0xf0) { |
88 | case 0x40: | 88 | case 0x40: |
89 | proto = htons(ETH_P_IP); | 89 | proto = htons(ETH_P_IP); |
@@ -732,6 +732,7 @@ static const struct usb_device_id products[] = { | |||
732 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 732 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
733 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ | 733 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ |
734 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ | 734 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ |
735 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ | ||
735 | 736 | ||
736 | /* 4. Gobi 1000 devices */ | 737 | /* 4. Gobi 1000 devices */ |
737 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 738 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a48bc0f20c1a..524a47a28120 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -492,6 +492,10 @@ EXPORT_SYMBOL_GPL(rndis_unbind); | |||
492 | */ | 492 | */ |
493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
494 | { | 494 | { |
495 | /* This check is no longer done by usbnet */ | ||
496 | if (skb->len < dev->net->hard_header_len) | ||
497 | return 0; | ||
498 | |||
495 | /* peripheral may have batched packets to us... */ | 499 | /* peripheral may have batched packets to us... */ |
496 | while (likely(skb->len)) { | 500 | while (likely(skb->len)) { |
497 | struct rndis_data_hdr *hdr = (void *)skb->data; | 501 | struct rndis_data_hdr *hdr = (void *)skb->data; |
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index f17b9e02dd34..d9e7892262fa 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
@@ -2106,6 +2106,10 @@ static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, | |||
2106 | 2106 | ||
2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
2108 | { | 2108 | { |
2109 | /* This check is no longer done by usbnet */ | ||
2110 | if (skb->len < dev->net->hard_header_len) | ||
2111 | return 0; | ||
2112 | |||
2109 | while (skb->len > 0) { | 2113 | while (skb->len > 0) { |
2110 | u32 rx_cmd_a, rx_cmd_b, align_count, size; | 2114 | u32 rx_cmd_a, rx_cmd_b, align_count, size; |
2111 | struct sk_buff *ax_skb; | 2115 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 8dd54a0f7b29..424db65e4396 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -1723,6 +1723,10 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) | |||
1723 | 1723 | ||
1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
1725 | { | 1725 | { |
1726 | /* This check is no longer done by usbnet */ | ||
1727 | if (skb->len < dev->net->hard_header_len) | ||
1728 | return 0; | ||
1729 | |||
1726 | while (skb->len > 0) { | 1730 | while (skb->len > 0) { |
1727 | u32 header, align_count; | 1731 | u32 header, align_count; |
1728 | struct sk_buff *ax_skb; | 1732 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c index 4175eb9fdeca..b94a0fbb8b3b 100644 --- a/drivers/net/usb/sr9800.c +++ b/drivers/net/usb/sr9800.c | |||
@@ -63,6 +63,10 @@ static int sr_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
63 | { | 63 | { |
64 | int offset = 0; | 64 | int offset = 0; |
65 | 65 | ||
66 | /* This check is no longer done by usbnet */ | ||
67 | if (skb->len < dev->net->hard_header_len) | ||
68 | return 0; | ||
69 | |||
66 | while (offset + sizeof(u32) < skb->len) { | 70 | while (offset + sizeof(u32) < skb->len) { |
67 | struct sk_buff *sr_skb; | 71 | struct sk_buff *sr_skb; |
68 | u16 size; | 72 | u16 size; |
@@ -823,7 +827,7 @@ static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) | |||
823 | dev->rx_urb_size = | 827 | dev->rx_urb_size = |
824 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; | 828 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; |
825 | } | 829 | } |
826 | netdev_dbg(dev->net, "%s : setting rx_urb_size with : %ld\n", __func__, | 830 | netdev_dbg(dev->net, "%s : setting rx_urb_size with : %zu\n", __func__, |
827 | dev->rx_urb_size); | 831 | dev->rx_urb_size); |
828 | return 0; | 832 | return 0; |
829 | 833 | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 4671da755e7b..dd10d5817d2a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -542,17 +542,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
542 | } | 542 | } |
543 | // else network stack removes extra byte if we forced a short packet | 543 | // else network stack removes extra byte if we forced a short packet |
544 | 544 | ||
545 | if (skb->len) { | 545 | /* all data was already cloned from skb inside the driver */ |
546 | /* all data was already cloned from skb inside the driver */ | 546 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) |
547 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) | 547 | goto done; |
548 | dev_kfree_skb_any(skb); | 548 | |
549 | else | 549 | if (skb->len < ETH_HLEN) { |
550 | usbnet_skb_return(dev, skb); | 550 | dev->net->stats.rx_errors++; |
551 | dev->net->stats.rx_length_errors++; | ||
552 | netif_dbg(dev, rx_err, dev->net, "rx length %d\n", skb->len); | ||
553 | } else { | ||
554 | usbnet_skb_return(dev, skb); | ||
551 | return; | 555 | return; |
552 | } | 556 | } |
553 | 557 | ||
554 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | ||
555 | dev->net->stats.rx_errors++; | ||
556 | done: | 558 | done: |
557 | skb_queue_tail(&dev->done, skb); | 559 | skb_queue_tail(&dev->done, skb); |
558 | } | 560 | } |
@@ -574,13 +576,6 @@ static void rx_complete (struct urb *urb) | |||
574 | switch (urb_status) { | 576 | switch (urb_status) { |
575 | /* success */ | 577 | /* success */ |
576 | case 0: | 578 | case 0: |
577 | if (skb->len < dev->net->hard_header_len) { | ||
578 | state = rx_cleanup; | ||
579 | dev->net->stats.rx_errors++; | ||
580 | dev->net->stats.rx_length_errors++; | ||
581 | netif_dbg(dev, rx_err, dev->net, | ||
582 | "rx length %d\n", skb->len); | ||
583 | } | ||
584 | break; | 579 | break; |
585 | 580 | ||
586 | /* stalls need manual reset. this is rare ... except that | 581 | /* stalls need manual reset. this is rare ... except that |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index d6bc7cb61bfb..1a2973b7acf2 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -110,7 +110,7 @@ ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band) | |||
110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); | 110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); |
111 | 111 | ||
112 | if (ah->ah_version == AR5K_AR5210) { | 112 | if (ah->ah_version == AR5K_AR5210) { |
113 | srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; | 113 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf; |
114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; | 114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; |
115 | } else { | 115 | } else { |
116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; | 116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; |
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index aa7ad3a7a69b..4e5c0f8c9496 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
@@ -496,7 +496,7 @@ void hostap_init_proc(local_info_t *local) | |||
496 | 496 | ||
497 | void hostap_remove_proc(local_info_t *local) | 497 | void hostap_remove_proc(local_info_t *local) |
498 | { | 498 | { |
499 | remove_proc_subtree(local->ddev->name, hostap_proc); | 499 | proc_remove(local->proc); |
500 | } | 500 | } |
501 | 501 | ||
502 | 502 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c24d1d3d55f6..73086c1629ca 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -696,6 +696,24 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
696 | return ret; | 696 | return ret; |
697 | } | 697 | } |
698 | 698 | ||
699 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
700 | { | ||
701 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
702 | return false; | ||
703 | return true; | ||
704 | } | ||
705 | |||
706 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
707 | { | ||
708 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
709 | return false; | ||
710 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
711 | return true; | ||
712 | |||
713 | /* disabled by default */ | ||
714 | return false; | ||
715 | } | ||
716 | |||
699 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 717 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
700 | struct ieee80211_vif *vif, | 718 | struct ieee80211_vif *vif, |
701 | enum ieee80211_ampdu_mlme_action action, | 719 | enum ieee80211_ampdu_mlme_action action, |
@@ -717,7 +735,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
717 | 735 | ||
718 | switch (action) { | 736 | switch (action) { |
719 | case IEEE80211_AMPDU_RX_START: | 737 | case IEEE80211_AMPDU_RX_START: |
720 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | 738 | if (!iwl_enable_rx_ampdu(priv->cfg)) |
721 | break; | 739 | break; |
722 | IWL_DEBUG_HT(priv, "start Rx\n"); | 740 | IWL_DEBUG_HT(priv, "start Rx\n"); |
723 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | 741 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); |
@@ -729,7 +747,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
729 | case IEEE80211_AMPDU_TX_START: | 747 | case IEEE80211_AMPDU_TX_START: |
730 | if (!priv->trans->ops->txq_enable) | 748 | if (!priv->trans->ops->txq_enable) |
731 | break; | 749 | break; |
732 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 750 | if (!iwl_enable_tx_ampdu(priv->cfg)) |
733 | break; | 751 | break; |
734 | IWL_DEBUG_HT(priv, "start Tx\n"); | 752 | IWL_DEBUG_HT(priv, "start Tx\n"); |
735 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 753 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index c3728163be46..75103554cd63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -1286,7 +1286,7 @@ module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO); | |||
1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); | 1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); |
1288 | MODULE_PARM_DESC(11n_disable, | 1288 | MODULE_PARM_DESC(11n_disable, |
1289 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1289 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); |
1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, | 1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, |
1291 | int, S_IRUGO); | 1291 | int, S_IRUGO); |
1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); | 1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 0a84ade7edac..b29075c3da8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
@@ -79,9 +79,12 @@ enum iwl_power_level { | |||
79 | IWL_POWER_NUM | 79 | IWL_POWER_NUM |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #define IWL_DISABLE_HT_ALL BIT(0) | 82 | enum iwl_disable_11n { |
83 | #define IWL_DISABLE_HT_TXAGG BIT(1) | 83 | IWL_DISABLE_HT_ALL = BIT(0), |
84 | #define IWL_DISABLE_HT_RXAGG BIT(2) | 84 | IWL_DISABLE_HT_TXAGG = BIT(1), |
85 | IWL_DISABLE_HT_RXAGG = BIT(2), | ||
86 | IWL_ENABLE_HT_TXAGG = BIT(3), | ||
87 | }; | ||
85 | 88 | ||
86 | /** | 89 | /** |
87 | * struct iwl_mod_params | 90 | * struct iwl_mod_params |
@@ -90,7 +93,7 @@ enum iwl_power_level { | |||
90 | * | 93 | * |
91 | * @sw_crypto: using hardware encryption, default = 0 | 94 | * @sw_crypto: using hardware encryption, default = 0 |
92 | * @disable_11n: disable 11n capabilities, default = 0, | 95 | * @disable_11n: disable 11n capabilities, default = 0, |
93 | * use IWL_DISABLE_HT_* constants | 96 | * use IWL_[DIS,EN]ABLE_HT_* constants |
94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 | 97 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 |
95 | * @restart_fw: restart firmware, default = 1 | 98 | * @restart_fw: restart firmware, default = 1 |
96 | * @wd_disable: enable stuck queue check, default = 0 | 99 | * @wd_disable: enable stuck queue check, default = 0 |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 6bf9766e5982..c35b8661b395 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -328,6 +328,24 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, | |||
328 | ieee80211_free_txskb(hw, skb); | 328 | ieee80211_free_txskb(hw, skb); |
329 | } | 329 | } |
330 | 330 | ||
331 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
332 | { | ||
333 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
334 | return false; | ||
335 | return true; | ||
336 | } | ||
337 | |||
338 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
339 | { | ||
340 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
341 | return false; | ||
342 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
343 | return true; | ||
344 | |||
345 | /* enabled by default */ | ||
346 | return true; | ||
347 | } | ||
348 | |||
331 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | 349 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, |
332 | struct ieee80211_vif *vif, | 350 | struct ieee80211_vif *vif, |
333 | enum ieee80211_ampdu_mlme_action action, | 351 | enum ieee80211_ampdu_mlme_action action, |
@@ -347,7 +365,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
347 | 365 | ||
348 | switch (action) { | 366 | switch (action) { |
349 | case IEEE80211_AMPDU_RX_START: | 367 | case IEEE80211_AMPDU_RX_START: |
350 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) { | 368 | if (!iwl_enable_rx_ampdu(mvm->cfg)) { |
351 | ret = -EINVAL; | 369 | ret = -EINVAL; |
352 | break; | 370 | break; |
353 | } | 371 | } |
@@ -357,7 +375,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
357 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); | 375 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); |
358 | break; | 376 | break; |
359 | case IEEE80211_AMPDU_TX_START: | 377 | case IEEE80211_AMPDU_TX_START: |
360 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { | 378 | if (!iwl_enable_tx_ampdu(mvm->cfg)) { |
361 | ret = -EINVAL; | 379 | ret = -EINVAL; |
362 | break; | 380 | break; |
363 | } | 381 | } |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 4d79761b9c87..9d3d2758ec35 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -748,7 +748,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
748 | 748 | ||
749 | static u16 | 749 | static u16 |
750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, | 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, |
751 | void *accel_priv) | 751 | void *accel_priv, select_queue_fallback_t fallback) |
752 | { | 752 | { |
753 | skb->priority = cfg80211_classify8021d(skb, NULL); | 753 | skb->priority = cfg80211_classify8021d(skb, NULL); |
754 | return mwifiex_1d_to_wmm_queue[skb->priority]; | 754 | return mwifiex_1d_to_wmm_queue[skb->priority]; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index 56aee067f324..a6ad79f61bf9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #ifndef RTL8187_H | 15 | #ifndef RTL8187_H |
16 | #define RTL8187_H | 16 | #define RTL8187_H |
17 | 17 | ||
18 | #include <linux/cache.h> | ||
19 | |||
18 | #include "rtl818x.h" | 20 | #include "rtl818x.h" |
19 | #include "leds.h" | 21 | #include "leds.h" |
20 | 22 | ||
@@ -139,7 +141,10 @@ struct rtl8187_priv { | |||
139 | u8 aifsn[4]; | 141 | u8 aifsn[4]; |
140 | u8 rfkill_mask; | 142 | u8 rfkill_mask; |
141 | struct { | 143 | struct { |
142 | __le64 buf; | 144 | union { |
145 | __le64 buf; | ||
146 | u8 dummy1[L1_CACHE_BYTES]; | ||
147 | } ____cacheline_aligned; | ||
143 | struct sk_buff_head queue; | 148 | struct sk_buff_head queue; |
144 | } b_tx_status; /* This queue is used by both -b and non-b devices */ | 149 | } b_tx_status; /* This queue is used by both -b and non-b devices */ |
145 | struct mutex io_mutex; | 150 | struct mutex io_mutex; |
@@ -147,7 +152,8 @@ struct rtl8187_priv { | |||
147 | u8 bits8; | 152 | u8 bits8; |
148 | __le16 bits16; | 153 | __le16 bits16; |
149 | __le32 bits32; | 154 | __le32 bits32; |
150 | } *io_dmabuf; | 155 | u8 dummy2[L1_CACHE_BYTES]; |
156 | } *io_dmabuf ____cacheline_aligned; | ||
151 | bool rfkill_off; | 157 | bool rfkill_off; |
152 | u16 seqno; | 158 | u16 seqno; |
153 | }; | 159 | }; |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index deedae3c5449..d1c0191a195b 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
48 | 48 | ||
49 | /*<2> Enable Adapter */ | 49 | /*<2> Enable Adapter */ |
50 | if (rtlpriv->cfg->ops->hw_init(hw)) | 50 | if (rtlpriv->cfg->ops->hw_init(hw)) |
51 | return 1; | 51 | return false; |
52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
53 | 53 | ||
54 | /*<3> Enable Interrupt */ | 54 | /*<3> Enable Interrupt */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a82b30a1996c..2eb0b38384dd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
937 | bool is92c; | 937 | bool is92c; |
938 | int err; | 938 | int err; |
939 | u8 tmp_u1b; | 939 | u8 tmp_u1b; |
940 | unsigned long flags; | ||
940 | 941 | ||
941 | rtlpci->being_init_adapter = true; | 942 | rtlpci->being_init_adapter = true; |
943 | |||
944 | /* Since this function can take a very long time (up to 350 ms) | ||
945 | * and can be called with irqs disabled, reenable the irqs | ||
946 | * to let the other devices continue being serviced. | ||
947 | * | ||
948 | * It is safe doing so since our own interrupts will only be enabled | ||
949 | * in a subsequent step. | ||
950 | */ | ||
951 | local_save_flags(flags); | ||
952 | local_irq_enable(); | ||
953 | |||
942 | rtlpriv->intf_ops->disable_aspm(hw); | 954 | rtlpriv->intf_ops->disable_aspm(hw); |
943 | rtstatus = _rtl92ce_init_mac(hw); | 955 | rtstatus = _rtl92ce_init_mac(hw); |
944 | if (!rtstatus) { | 956 | if (!rtstatus) { |
945 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); | 957 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); |
946 | err = 1; | 958 | err = 1; |
947 | return err; | 959 | goto exit; |
948 | } | 960 | } |
949 | 961 | ||
950 | err = rtl92c_download_fw(hw); | 962 | err = rtl92c_download_fw(hw); |
@@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
952 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 964 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
953 | "Failed to download FW. Init HW without FW now..\n"); | 965 | "Failed to download FW. Init HW without FW now..\n"); |
954 | err = 1; | 966 | err = 1; |
955 | return err; | 967 | goto exit; |
956 | } | 968 | } |
957 | 969 | ||
958 | rtlhal->last_hmeboxnum = 0; | 970 | rtlhal->last_hmeboxnum = 0; |
@@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
1032 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); | 1044 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); |
1033 | } | 1045 | } |
1034 | rtl92c_dm_init(hw); | 1046 | rtl92c_dm_init(hw); |
1047 | exit: | ||
1048 | local_irq_restore(flags); | ||
1035 | rtlpci->being_init_adapter = false; | 1049 | rtlpci->being_init_adapter = false; |
1036 | return err; | 1050 | return err; |
1037 | } | 1051 | } |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 10b51106c854..89e888a78899 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -342,27 +342,72 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
342 | } | 342 | } |
343 | EXPORT_SYMBOL(of_get_cpu_node); | 343 | EXPORT_SYMBOL(of_get_cpu_node); |
344 | 344 | ||
345 | /** Checks if the given "compat" string matches one of the strings in | 345 | /** |
346 | * the device's "compatible" property | 346 | * __of_device_is_compatible() - Check if the node matches given constraints |
347 | * @device: pointer to node | ||
348 | * @compat: required compatible string, NULL or "" for any match | ||
349 | * @type: required device_type value, NULL or "" for any match | ||
350 | * @name: required node name, NULL or "" for any match | ||
351 | * | ||
352 | * Checks if the given @compat, @type and @name strings match the | ||
353 | * properties of the given @device. A constraints can be skipped by | ||
354 | * passing NULL or an empty string as the constraint. | ||
355 | * | ||
356 | * Returns 0 for no match, and a positive integer on match. The return | ||
357 | * value is a relative score with larger values indicating better | ||
358 | * matches. The score is weighted for the most specific compatible value | ||
359 | * to get the highest score. Matching type is next, followed by matching | ||
360 | * name. Practically speaking, this results in the following priority | ||
361 | * order for matches: | ||
362 | * | ||
363 | * 1. specific compatible && type && name | ||
364 | * 2. specific compatible && type | ||
365 | * 3. specific compatible && name | ||
366 | * 4. specific compatible | ||
367 | * 5. general compatible && type && name | ||
368 | * 6. general compatible && type | ||
369 | * 7. general compatible && name | ||
370 | * 8. general compatible | ||
371 | * 9. type && name | ||
372 | * 10. type | ||
373 | * 11. name | ||
347 | */ | 374 | */ |
348 | static int __of_device_is_compatible(const struct device_node *device, | 375 | static int __of_device_is_compatible(const struct device_node *device, |
349 | const char *compat) | 376 | const char *compat, const char *type, const char *name) |
350 | { | 377 | { |
351 | const char* cp; | 378 | struct property *prop; |
352 | int cplen, l; | 379 | const char *cp; |
380 | int index = 0, score = 0; | ||
381 | |||
382 | /* Compatible match has highest priority */ | ||
383 | if (compat && compat[0]) { | ||
384 | prop = __of_find_property(device, "compatible", NULL); | ||
385 | for (cp = of_prop_next_string(prop, NULL); cp; | ||
386 | cp = of_prop_next_string(prop, cp), index++) { | ||
387 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { | ||
388 | score = INT_MAX/2 - (index << 2); | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | if (!score) | ||
393 | return 0; | ||
394 | } | ||
353 | 395 | ||
354 | cp = __of_get_property(device, "compatible", &cplen); | 396 | /* Matching type is better than matching name */ |
355 | if (cp == NULL) | 397 | if (type && type[0]) { |
356 | return 0; | 398 | if (!device->type || of_node_cmp(type, device->type)) |
357 | while (cplen > 0) { | 399 | return 0; |
358 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) | 400 | score += 2; |
359 | return 1; | ||
360 | l = strlen(cp) + 1; | ||
361 | cp += l; | ||
362 | cplen -= l; | ||
363 | } | 401 | } |
364 | 402 | ||
365 | return 0; | 403 | /* Matching name is a bit better than not */ |
404 | if (name && name[0]) { | ||
405 | if (!device->name || of_node_cmp(name, device->name)) | ||
406 | return 0; | ||
407 | score++; | ||
408 | } | ||
409 | |||
410 | return score; | ||
366 | } | 411 | } |
367 | 412 | ||
368 | /** Checks if the given "compat" string matches one of the strings in | 413 | /** Checks if the given "compat" string matches one of the strings in |
@@ -375,7 +420,7 @@ int of_device_is_compatible(const struct device_node *device, | |||
375 | int res; | 420 | int res; |
376 | 421 | ||
377 | raw_spin_lock_irqsave(&devtree_lock, flags); | 422 | raw_spin_lock_irqsave(&devtree_lock, flags); |
378 | res = __of_device_is_compatible(device, compat); | 423 | res = __of_device_is_compatible(device, compat, NULL, NULL); |
379 | raw_spin_unlock_irqrestore(&devtree_lock, flags); | 424 | raw_spin_unlock_irqrestore(&devtree_lock, flags); |
380 | return res; | 425 | return res; |
381 | } | 426 | } |
@@ -681,10 +726,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
681 | raw_spin_lock_irqsave(&devtree_lock, flags); | 726 | raw_spin_lock_irqsave(&devtree_lock, flags); |
682 | np = from ? from->allnext : of_allnodes; | 727 | np = from ? from->allnext : of_allnodes; |
683 | for (; np; np = np->allnext) { | 728 | for (; np; np = np->allnext) { |
684 | if (type | 729 | if (__of_device_is_compatible(np, compatible, type, NULL) && |
685 | && !(np->type && (of_node_cmp(np->type, type) == 0))) | ||
686 | continue; | ||
687 | if (__of_device_is_compatible(np, compatible) && | ||
688 | of_node_get(np)) | 730 | of_node_get(np)) |
689 | break; | 731 | break; |
690 | } | 732 | } |
@@ -730,65 +772,26 @@ out: | |||
730 | } | 772 | } |
731 | EXPORT_SYMBOL(of_find_node_with_property); | 773 | EXPORT_SYMBOL(of_find_node_with_property); |
732 | 774 | ||
733 | static const struct of_device_id * | ||
734 | of_match_compatible(const struct of_device_id *matches, | ||
735 | const struct device_node *node) | ||
736 | { | ||
737 | const char *cp; | ||
738 | int cplen, l; | ||
739 | const struct of_device_id *m; | ||
740 | |||
741 | cp = __of_get_property(node, "compatible", &cplen); | ||
742 | while (cp && (cplen > 0)) { | ||
743 | m = matches; | ||
744 | while (m->name[0] || m->type[0] || m->compatible[0]) { | ||
745 | /* Only match for the entries without type and name */ | ||
746 | if (m->name[0] || m->type[0] || | ||
747 | of_compat_cmp(m->compatible, cp, | ||
748 | strlen(m->compatible))) | ||
749 | m++; | ||
750 | else | ||
751 | return m; | ||
752 | } | ||
753 | |||
754 | /* Get node's next compatible string */ | ||
755 | l = strlen(cp) + 1; | ||
756 | cp += l; | ||
757 | cplen -= l; | ||
758 | } | ||
759 | |||
760 | return NULL; | ||
761 | } | ||
762 | |||
763 | static | 775 | static |
764 | const struct of_device_id *__of_match_node(const struct of_device_id *matches, | 776 | const struct of_device_id *__of_match_node(const struct of_device_id *matches, |
765 | const struct device_node *node) | 777 | const struct device_node *node) |
766 | { | 778 | { |
767 | const struct of_device_id *m; | 779 | const struct of_device_id *best_match = NULL; |
780 | int score, best_score = 0; | ||
768 | 781 | ||
769 | if (!matches) | 782 | if (!matches) |
770 | return NULL; | 783 | return NULL; |
771 | 784 | ||
772 | m = of_match_compatible(matches, node); | 785 | for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) { |
773 | if (m) | 786 | score = __of_device_is_compatible(node, matches->compatible, |
774 | return m; | 787 | matches->type, matches->name); |
775 | 788 | if (score > best_score) { | |
776 | while (matches->name[0] || matches->type[0] || matches->compatible[0]) { | 789 | best_match = matches; |
777 | int match = 1; | 790 | best_score = score; |
778 | if (matches->name[0]) | 791 | } |
779 | match &= node->name | ||
780 | && !strcmp(matches->name, node->name); | ||
781 | if (matches->type[0]) | ||
782 | match &= node->type | ||
783 | && !strcmp(matches->type, node->type); | ||
784 | if (matches->compatible[0]) | ||
785 | match &= __of_device_is_compatible(node, | ||
786 | matches->compatible); | ||
787 | if (match) | ||
788 | return matches; | ||
789 | matches++; | ||
790 | } | 792 | } |
791 | return NULL; | 793 | |
794 | return best_match; | ||
792 | } | 795 | } |
793 | 796 | ||
794 | /** | 797 | /** |
@@ -796,12 +799,7 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches, | |||
796 | * @matches: array of of device match structures to search in | 799 | * @matches: array of of device match structures to search in |
797 | * @node: the of device structure to match against | 800 | * @node: the of device structure to match against |
798 | * | 801 | * |
799 | * Low level utility function used by device matching. We have two ways | 802 | * Low level utility function used by device matching. |
800 | * of matching: | ||
801 | * - Try to find the best compatible match by comparing each compatible | ||
802 | * string of device node with all the given matches respectively. | ||
803 | * - If the above method failed, then try to match the compatible by using | ||
804 | * __of_device_is_compatible() besides the match in type and name. | ||
805 | */ | 803 | */ |
806 | const struct of_device_id *of_match_node(const struct of_device_id *matches, | 804 | const struct of_device_id *of_match_node(const struct of_device_id *matches, |
807 | const struct device_node *node) | 805 | const struct device_node *node) |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 875b7b6f0d2a..5b3c24f3cde5 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -24,7 +24,11 @@ MODULE_LICENSE("GPL"); | |||
24 | 24 | ||
25 | static void of_set_phy_supported(struct phy_device *phydev, u32 max_speed) | 25 | static void of_set_phy_supported(struct phy_device *phydev, u32 max_speed) |
26 | { | 26 | { |
27 | phydev->supported |= PHY_DEFAULT_FEATURES; | 27 | /* The default values for phydev->supported are provided by the PHY |
28 | * driver "features" member, we want to reset to sane defaults fist | ||
29 | * before supporting higher speeds. | ||
30 | */ | ||
31 | phydev->supported &= PHY_DEFAULT_FEATURES; | ||
28 | 32 | ||
29 | switch (max_speed) { | 33 | switch (max_speed) { |
30 | default: | 34 | default: |
@@ -44,7 +48,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi | |||
44 | { | 48 | { |
45 | struct phy_device *phy; | 49 | struct phy_device *phy; |
46 | bool is_c45; | 50 | bool is_c45; |
47 | int rc, prev_irq; | 51 | int rc; |
48 | u32 max_speed = 0; | 52 | u32 max_speed = 0; |
49 | 53 | ||
50 | is_c45 = of_device_is_compatible(child, | 54 | is_c45 = of_device_is_compatible(child, |
@@ -54,12 +58,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi | |||
54 | if (!phy || IS_ERR(phy)) | 58 | if (!phy || IS_ERR(phy)) |
55 | return 1; | 59 | return 1; |
56 | 60 | ||
57 | if (mdio->irq) { | 61 | rc = irq_of_parse_and_map(child, 0); |
58 | prev_irq = mdio->irq[addr]; | 62 | if (rc > 0) { |
59 | mdio->irq[addr] = | 63 | phy->irq = rc; |
60 | irq_of_parse_and_map(child, 0); | 64 | if (mdio->irq) |
61 | if (!mdio->irq[addr]) | 65 | mdio->irq[addr] = rc; |
62 | mdio->irq[addr] = prev_irq; | 66 | } else { |
67 | if (mdio->irq) | ||
68 | phy->irq = mdio->irq[addr]; | ||
63 | } | 69 | } |
64 | 70 | ||
65 | /* Associate the OF node with the device structure so it | 71 | /* Associate the OF node with the device structure so it |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index e21012bde639..6643d1920985 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -300,6 +300,72 @@ static void __init of_selftest_parse_interrupts_extended(void) | |||
300 | of_node_put(np); | 300 | of_node_put(np); |
301 | } | 301 | } |
302 | 302 | ||
303 | static struct of_device_id match_node_table[] = { | ||
304 | { .data = "A", .name = "name0", }, /* Name alone is lowest priority */ | ||
305 | { .data = "B", .type = "type1", }, /* followed by type alone */ | ||
306 | |||
307 | { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */ | ||
308 | { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */ | ||
309 | { .data = "Cc", .name = "name2", .type = "type2", }, | ||
310 | |||
311 | { .data = "E", .compatible = "compat3" }, | ||
312 | { .data = "G", .compatible = "compat2", }, | ||
313 | { .data = "H", .compatible = "compat2", .name = "name5", }, | ||
314 | { .data = "I", .compatible = "compat2", .type = "type1", }, | ||
315 | { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", }, | ||
316 | { .data = "K", .compatible = "compat2", .name = "name9", }, | ||
317 | {} | ||
318 | }; | ||
319 | |||
320 | static struct { | ||
321 | const char *path; | ||
322 | const char *data; | ||
323 | } match_node_tests[] = { | ||
324 | { .path = "/testcase-data/match-node/name0", .data = "A", }, | ||
325 | { .path = "/testcase-data/match-node/name1", .data = "B", }, | ||
326 | { .path = "/testcase-data/match-node/a/name2", .data = "Ca", }, | ||
327 | { .path = "/testcase-data/match-node/b/name2", .data = "Cb", }, | ||
328 | { .path = "/testcase-data/match-node/c/name2", .data = "Cc", }, | ||
329 | { .path = "/testcase-data/match-node/name3", .data = "E", }, | ||
330 | { .path = "/testcase-data/match-node/name4", .data = "G", }, | ||
331 | { .path = "/testcase-data/match-node/name5", .data = "H", }, | ||
332 | { .path = "/testcase-data/match-node/name6", .data = "G", }, | ||
333 | { .path = "/testcase-data/match-node/name7", .data = "I", }, | ||
334 | { .path = "/testcase-data/match-node/name8", .data = "J", }, | ||
335 | { .path = "/testcase-data/match-node/name9", .data = "K", }, | ||
336 | }; | ||
337 | |||
338 | static void __init of_selftest_match_node(void) | ||
339 | { | ||
340 | struct device_node *np; | ||
341 | const struct of_device_id *match; | ||
342 | int i; | ||
343 | |||
344 | for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) { | ||
345 | np = of_find_node_by_path(match_node_tests[i].path); | ||
346 | if (!np) { | ||
347 | selftest(0, "missing testcase node %s\n", | ||
348 | match_node_tests[i].path); | ||
349 | continue; | ||
350 | } | ||
351 | |||
352 | match = of_match_node(match_node_table, np); | ||
353 | if (!match) { | ||
354 | selftest(0, "%s didn't match anything\n", | ||
355 | match_node_tests[i].path); | ||
356 | continue; | ||
357 | } | ||
358 | |||
359 | if (strcmp(match->data, match_node_tests[i].data) != 0) { | ||
360 | selftest(0, "%s got wrong match. expected %s, got %s\n", | ||
361 | match_node_tests[i].path, match_node_tests[i].data, | ||
362 | (const char *)match->data); | ||
363 | continue; | ||
364 | } | ||
365 | selftest(1, "passed"); | ||
366 | } | ||
367 | } | ||
368 | |||
303 | static int __init of_selftest(void) | 369 | static int __init of_selftest(void) |
304 | { | 370 | { |
305 | struct device_node *np; | 371 | struct device_node *np; |
@@ -316,6 +382,7 @@ static int __init of_selftest(void) | |||
316 | of_selftest_property_match_string(); | 382 | of_selftest_property_match_string(); |
317 | of_selftest_parse_interrupts(); | 383 | of_selftest_parse_interrupts(); |
318 | of_selftest_parse_interrupts_extended(); | 384 | of_selftest_parse_interrupts_extended(); |
385 | of_selftest_match_node(); | ||
319 | pr_info("end of selftest - %i passed, %i failed\n", | 386 | pr_info("end of selftest - %i passed, %i failed\n", |
320 | selftest_results.passed, selftest_results.failed); | 387 | selftest_results.passed, selftest_results.failed); |
321 | return 0; | 388 | return 0; |
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dtsi new file mode 100644 index 000000000000..3a5b75a8e4d7 --- /dev/null +++ b/drivers/of/testcase-data/testcases.dtsi | |||
@@ -0,0 +1,3 @@ | |||
1 | #include "tests-phandle.dtsi" | ||
2 | #include "tests-interrupts.dtsi" | ||
3 | #include "tests-match.dtsi" | ||
diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/drivers/of/testcase-data/tests-interrupts.dtsi index c843720bd3e5..c843720bd3e5 100644 --- a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi +++ b/drivers/of/testcase-data/tests-interrupts.dtsi | |||
diff --git a/drivers/of/testcase-data/tests-match.dtsi b/drivers/of/testcase-data/tests-match.dtsi new file mode 100644 index 000000000000..c9e541129534 --- /dev/null +++ b/drivers/of/testcase-data/tests-match.dtsi | |||
@@ -0,0 +1,19 @@ | |||
1 | |||
2 | / { | ||
3 | testcase-data { | ||
4 | match-node { | ||
5 | name0 { }; | ||
6 | name1 { device_type = "type1"; }; | ||
7 | a { name2 { device_type = "type1"; }; }; | ||
8 | b { name2 { }; }; | ||
9 | c { name2 { device_type = "type2"; }; }; | ||
10 | name3 { compatible = "compat3"; }; | ||
11 | name4 { compatible = "compat2", "compat3"; }; | ||
12 | name5 { compatible = "compat2", "compat3"; }; | ||
13 | name6 { compatible = "compat1", "compat2", "compat3"; }; | ||
14 | name7 { compatible = "compat2"; device_type = "type1"; }; | ||
15 | name8 { compatible = "compat2"; device_type = "type1"; }; | ||
16 | name9 { compatible = "compat2"; }; | ||
17 | }; | ||
18 | }; | ||
19 | }; | ||
diff --git a/arch/arm/boot/dts/testcases/tests-phandle.dtsi b/drivers/of/testcase-data/tests-phandle.dtsi index 0007d3cd7dc2..0007d3cd7dc2 100644 --- a/arch/arm/boot/dts/testcases/tests-phandle.dtsi +++ b/drivers/of/testcase-data/tests-phandle.dtsi | |||
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 13478ecd4113..0e79665afd44 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -60,14 +60,6 @@ | |||
60 | #define PCIE_DEBUG_CTRL 0x1a60 | 60 | #define PCIE_DEBUG_CTRL 0x1a60 |
61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) | 61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) |
62 | 62 | ||
63 | /* | ||
64 | * This product ID is registered by Marvell, and used when the Marvell | ||
65 | * SoC is not the root complex, but an endpoint on the PCIe bus. It is | ||
66 | * therefore safe to re-use this PCI ID for our emulated PCI-to-PCI | ||
67 | * bridge. | ||
68 | */ | ||
69 | #define MARVELL_EMULATED_PCI_PCI_BRIDGE_ID 0x7846 | ||
70 | |||
71 | /* PCI configuration space of a PCI-to-PCI bridge */ | 63 | /* PCI configuration space of a PCI-to-PCI bridge */ |
72 | struct mvebu_sw_pci_bridge { | 64 | struct mvebu_sw_pci_bridge { |
73 | u16 vendor; | 65 | u16 vendor; |
@@ -388,7 +380,8 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) | |||
388 | 380 | ||
389 | bridge->class = PCI_CLASS_BRIDGE_PCI; | 381 | bridge->class = PCI_CLASS_BRIDGE_PCI; |
390 | bridge->vendor = PCI_VENDOR_ID_MARVELL; | 382 | bridge->vendor = PCI_VENDOR_ID_MARVELL; |
391 | bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID; | 383 | bridge->device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; |
384 | bridge->revision = mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; | ||
392 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; | 385 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; |
393 | bridge->cache_line_size = 0x10; | 386 | bridge->cache_line_size = 0x10; |
394 | 387 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a0fec6ce571..955ab7990c5b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -545,9 +545,15 @@ static int populate_msi_sysfs(struct pci_dev *pdev) | |||
545 | return -ENOMEM; | 545 | return -ENOMEM; |
546 | list_for_each_entry(entry, &pdev->msi_list, list) { | 546 | list_for_each_entry(entry, &pdev->msi_list, list) { |
547 | char *name = kmalloc(20, GFP_KERNEL); | 547 | char *name = kmalloc(20, GFP_KERNEL); |
548 | if (!name) | ||
549 | goto error_attrs; | ||
550 | |||
548 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); | 551 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); |
549 | if (!msi_dev_attr) | 552 | if (!msi_dev_attr) { |
553 | kfree(name); | ||
550 | goto error_attrs; | 554 | goto error_attrs; |
555 | } | ||
556 | |||
551 | sprintf(name, "%d", entry->irq); | 557 | sprintf(name, "%d", entry->irq); |
552 | sysfs_attr_init(&msi_dev_attr->attr); | 558 | sysfs_attr_init(&msi_dev_attr->attr); |
553 | msi_dev_attr->attr.name = name; | 559 | msi_dev_attr->attr.name = name; |
@@ -589,6 +595,7 @@ error_attrs: | |||
589 | ++count; | 595 | ++count; |
590 | msi_attr = msi_attrs[count]; | 596 | msi_attr = msi_attrs[count]; |
591 | } | 597 | } |
598 | kfree(msi_attrs); | ||
592 | return ret; | 599 | return ret; |
593 | } | 600 | } |
594 | 601 | ||
@@ -959,7 +966,6 @@ EXPORT_SYMBOL(pci_disable_msi); | |||
959 | /** | 966 | /** |
960 | * pci_msix_vec_count - return the number of device's MSI-X table entries | 967 | * pci_msix_vec_count - return the number of device's MSI-X table entries |
961 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 968 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
962 | |||
963 | * This function returns the number of device's MSI-X table entries and | 969 | * This function returns the number of device's MSI-X table entries and |
964 | * therefore the number of MSI-X vectors device is capable of sending. | 970 | * therefore the number of MSI-X vectors device is capable of sending. |
965 | * It returns a negative errno if the device is not capable of sending MSI-X | 971 | * It returns a negative errno if the device is not capable of sending MSI-X |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1febe90831b4..6b05f6134b68 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1181,6 +1181,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); | |||
1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
1182 | { | 1182 | { |
1183 | int err; | 1183 | int err; |
1184 | u16 cmd; | ||
1185 | u8 pin; | ||
1184 | 1186 | ||
1185 | err = pci_set_power_state(dev, PCI_D0); | 1187 | err = pci_set_power_state(dev, PCI_D0); |
1186 | if (err < 0 && err != -EIO) | 1188 | if (err < 0 && err != -EIO) |
@@ -1190,6 +1192,14 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) | |||
1190 | return err; | 1192 | return err; |
1191 | pci_fixup_device(pci_fixup_enable, dev); | 1193 | pci_fixup_device(pci_fixup_enable, dev); |
1192 | 1194 | ||
1195 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | ||
1196 | if (pin) { | ||
1197 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
1198 | if (cmd & PCI_COMMAND_INTX_DISABLE) | ||
1199 | pci_write_config_word(dev, PCI_COMMAND, | ||
1200 | cmd & ~PCI_COMMAND_INTX_DISABLE); | ||
1201 | } | ||
1202 | |||
1193 | return 0; | 1203 | return 0; |
1194 | } | 1204 | } |
1195 | 1205 | ||
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index afa2354f6600..c7a551c2d5f1 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | menu "PHY Subsystem" | 5 | menu "PHY Subsystem" |
6 | 6 | ||
7 | config GENERIC_PHY | 7 | config GENERIC_PHY |
8 | tristate "PHY Core" | 8 | bool "PHY Core" |
9 | help | 9 | help |
10 | Generic PHY support. | 10 | Generic PHY support. |
11 | 11 | ||
@@ -61,6 +61,7 @@ config PHY_EXYNOS_DP_VIDEO | |||
61 | config BCM_KONA_USB2_PHY | 61 | config BCM_KONA_USB2_PHY |
62 | tristate "Broadcom Kona USB2 PHY Driver" | 62 | tristate "Broadcom Kona USB2 PHY Driver" |
63 | depends on GENERIC_PHY | 63 | depends on GENERIC_PHY |
64 | depends on HAS_IOMEM | ||
64 | help | 65 | help |
65 | Enable this to support the Broadcom Kona USB 2.0 PHY. | 66 | Enable this to support the Broadcom Kona USB 2.0 PHY. |
66 | 67 | ||
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 5f5b0f4be5be..6c738376daff 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -176,6 +176,8 @@ int phy_init(struct phy *phy) | |||
176 | dev_err(&phy->dev, "phy init failed --> %d\n", ret); | 176 | dev_err(&phy->dev, "phy init failed --> %d\n", ret); |
177 | goto out; | 177 | goto out; |
178 | } | 178 | } |
179 | } else { | ||
180 | ret = 0; /* Override possible ret == -ENOTSUPP */ | ||
179 | } | 181 | } |
180 | ++phy->init_count; | 182 | ++phy->init_count; |
181 | 183 | ||
@@ -232,6 +234,8 @@ int phy_power_on(struct phy *phy) | |||
232 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); | 234 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); |
233 | goto out; | 235 | goto out; |
234 | } | 236 | } |
237 | } else { | ||
238 | ret = 0; /* Override possible ret == -ENOTSUPP */ | ||
235 | } | 239 | } |
236 | ++phy->power_count; | 240 | ++phy->power_count; |
237 | mutex_unlock(&phy->mutex); | 241 | mutex_unlock(&phy->mutex); |
@@ -404,17 +408,11 @@ struct phy *phy_get(struct device *dev, const char *string) | |||
404 | index = of_property_match_string(dev->of_node, "phy-names", | 408 | index = of_property_match_string(dev->of_node, "phy-names", |
405 | string); | 409 | string); |
406 | phy = of_phy_get(dev, index); | 410 | phy = of_phy_get(dev, index); |
407 | if (IS_ERR(phy)) { | ||
408 | dev_err(dev, "unable to find phy\n"); | ||
409 | return phy; | ||
410 | } | ||
411 | } else { | 411 | } else { |
412 | phy = phy_lookup(dev, string); | 412 | phy = phy_lookup(dev, string); |
413 | if (IS_ERR(phy)) { | ||
414 | dev_err(dev, "unable to find phy\n"); | ||
415 | return phy; | ||
416 | } | ||
417 | } | 413 | } |
414 | if (IS_ERR(phy)) | ||
415 | return phy; | ||
418 | 416 | ||
419 | if (!try_module_get(phy->ops->owner)) | 417 | if (!try_module_get(phy->ops->owner)) |
420 | return ERR_PTR(-EPROBE_DEFER); | 418 | return ERR_PTR(-EPROBE_DEFER); |
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c index 1dbe6ce7b2ce..0786fef842e7 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/phy-exynos-dp-video.c | |||
@@ -76,10 +76,6 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev) | |||
76 | if (IS_ERR(state->regs)) | 76 | if (IS_ERR(state->regs)) |
77 | return PTR_ERR(state->regs); | 77 | return PTR_ERR(state->regs); |
78 | 78 | ||
79 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
80 | if (IS_ERR(phy_provider)) | ||
81 | return PTR_ERR(phy_provider); | ||
82 | |||
83 | phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL); | 79 | phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL); |
84 | if (IS_ERR(phy)) { | 80 | if (IS_ERR(phy)) { |
85 | dev_err(dev, "failed to create Display Port PHY\n"); | 81 | dev_err(dev, "failed to create Display Port PHY\n"); |
@@ -87,6 +83,10 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev) | |||
87 | } | 83 | } |
88 | phy_set_drvdata(phy, state); | 84 | phy_set_drvdata(phy, state); |
89 | 85 | ||
86 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
87 | if (IS_ERR(phy_provider)) | ||
88 | return PTR_ERR(phy_provider); | ||
89 | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 0c5efab11af1..7f139326a642 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c | |||
@@ -134,11 +134,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
134 | dev_set_drvdata(dev, state); | 134 | dev_set_drvdata(dev, state); |
135 | spin_lock_init(&state->slock); | 135 | spin_lock_init(&state->slock); |
136 | 136 | ||
137 | phy_provider = devm_of_phy_provider_register(dev, | ||
138 | exynos_mipi_video_phy_xlate); | ||
139 | if (IS_ERR(phy_provider)) | ||
140 | return PTR_ERR(phy_provider); | ||
141 | |||
142 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { | 137 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { |
143 | struct phy *phy = devm_phy_create(dev, | 138 | struct phy *phy = devm_phy_create(dev, |
144 | &exynos_mipi_video_phy_ops, NULL); | 139 | &exynos_mipi_video_phy_ops, NULL); |
@@ -152,6 +147,11 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
152 | phy_set_drvdata(phy, &state->phys[i]); | 147 | phy_set_drvdata(phy, &state->phys[i]); |
153 | } | 148 | } |
154 | 149 | ||
150 | phy_provider = devm_of_phy_provider_register(dev, | ||
151 | exynos_mipi_video_phy_xlate); | ||
152 | if (IS_ERR(phy_provider)) | ||
153 | return PTR_ERR(phy_provider); | ||
154 | |||
155 | return 0; | 155 | return 0; |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c index d43786f62437..d70ecd6a1b3f 100644 --- a/drivers/phy/phy-mvebu-sata.c +++ b/drivers/phy/phy-mvebu-sata.c | |||
@@ -99,17 +99,17 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev) | |||
99 | if (IS_ERR(priv->clk)) | 99 | if (IS_ERR(priv->clk)) |
100 | return PTR_ERR(priv->clk); | 100 | return PTR_ERR(priv->clk); |
101 | 101 | ||
102 | phy_provider = devm_of_phy_provider_register(&pdev->dev, | ||
103 | of_phy_simple_xlate); | ||
104 | if (IS_ERR(phy_provider)) | ||
105 | return PTR_ERR(phy_provider); | ||
106 | |||
107 | phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL); | 102 | phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL); |
108 | if (IS_ERR(phy)) | 103 | if (IS_ERR(phy)) |
109 | return PTR_ERR(phy); | 104 | return PTR_ERR(phy); |
110 | 105 | ||
111 | phy_set_drvdata(phy, priv); | 106 | phy_set_drvdata(phy, priv); |
112 | 107 | ||
108 | phy_provider = devm_of_phy_provider_register(&pdev->dev, | ||
109 | of_phy_simple_xlate); | ||
110 | if (IS_ERR(phy_provider)) | ||
111 | return PTR_ERR(phy_provider); | ||
112 | |||
113 | /* The boot loader may of left it on. Turn it off. */ | 113 | /* The boot loader may of left it on. Turn it off. */ |
114 | phy_mvebu_sata_power_off(phy); | 114 | phy_mvebu_sata_power_off(phy); |
115 | 115 | ||
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index bfc5c337f99a..7699752fba11 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c | |||
@@ -177,11 +177,6 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
177 | phy->phy.otg = otg; | 177 | phy->phy.otg = otg; |
178 | phy->phy.type = USB_PHY_TYPE_USB2; | 178 | phy->phy.type = USB_PHY_TYPE_USB2; |
179 | 179 | ||
180 | phy_provider = devm_of_phy_provider_register(phy->dev, | ||
181 | of_phy_simple_xlate); | ||
182 | if (IS_ERR(phy_provider)) | ||
183 | return PTR_ERR(phy_provider); | ||
184 | |||
185 | control_node = of_parse_phandle(node, "ctrl-module", 0); | 180 | control_node = of_parse_phandle(node, "ctrl-module", 0); |
186 | if (!control_node) { | 181 | if (!control_node) { |
187 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); | 182 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); |
@@ -214,6 +209,11 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
214 | 209 | ||
215 | phy_set_drvdata(generic_phy, phy); | 210 | phy_set_drvdata(generic_phy, phy); |
216 | 211 | ||
212 | phy_provider = devm_of_phy_provider_register(phy->dev, | ||
213 | of_phy_simple_xlate); | ||
214 | if (IS_ERR(phy_provider)) | ||
215 | return PTR_ERR(phy_provider); | ||
216 | |||
217 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); | 217 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); |
218 | if (IS_ERR(phy->wkupclk)) { | 218 | if (IS_ERR(phy->wkupclk)) { |
219 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); | 219 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); |
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index daf65e68aaab..c3ace1db8136 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
@@ -695,11 +695,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
695 | otg->set_host = twl4030_set_host; | 695 | otg->set_host = twl4030_set_host; |
696 | otg->set_peripheral = twl4030_set_peripheral; | 696 | otg->set_peripheral = twl4030_set_peripheral; |
697 | 697 | ||
698 | phy_provider = devm_of_phy_provider_register(twl->dev, | ||
699 | of_phy_simple_xlate); | ||
700 | if (IS_ERR(phy_provider)) | ||
701 | return PTR_ERR(phy_provider); | ||
702 | |||
703 | phy = devm_phy_create(twl->dev, &ops, init_data); | 698 | phy = devm_phy_create(twl->dev, &ops, init_data); |
704 | if (IS_ERR(phy)) { | 699 | if (IS_ERR(phy)) { |
705 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); | 700 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); |
@@ -708,6 +703,11 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
708 | 703 | ||
709 | phy_set_drvdata(phy, twl); | 704 | phy_set_drvdata(phy, twl); |
710 | 705 | ||
706 | phy_provider = devm_of_phy_provider_register(twl->dev, | ||
707 | of_phy_simple_xlate); | ||
708 | if (IS_ERR(phy_provider)) | ||
709 | return PTR_ERR(phy_provider); | ||
710 | |||
711 | /* init spinlock for workqueue */ | 711 | /* init spinlock for workqueue */ |
712 | spin_lock_init(&twl->lock); | 712 | spin_lock_init(&twl->lock); |
713 | 713 | ||
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 8a843a04c224..a40b9c34e9ff 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c | |||
@@ -52,8 +52,10 @@ lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm) | |||
52 | offset = pwm_map->output[i]; | 52 | offset = pwm_map->output[i]; |
53 | 53 | ||
54 | /* Return an error if the pin is already assigned */ | 54 | /* Return an error if the pin is already assigned */ |
55 | if (test_and_set_bit(offset, &lp3943->pin_used)) | 55 | if (test_and_set_bit(offset, &lp3943->pin_used)) { |
56 | kfree(pwm_map); | ||
56 | return ERR_PTR(-EBUSY); | 57 | return ERR_PTR(-EBUSY); |
58 | } | ||
57 | } | 59 | } |
58 | 60 | ||
59 | return pwm_map; | 61 | return pwm_map; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 16a309e5c024..d1ac4caaf1b0 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -1359,7 +1359,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1359 | goto found; | 1359 | goto found; |
1360 | /* Don't log an error when called from regulator_get_optional() */ | 1360 | /* Don't log an error when called from regulator_get_optional() */ |
1361 | } else if (!have_full_constraints() || exclusive) { | 1361 | } else if (!have_full_constraints() || exclusive) { |
1362 | dev_err(dev, "dummy supplies not allowed\n"); | 1362 | dev_warn(dev, "dummy supplies not allowed\n"); |
1363 | } | 1363 | } |
1364 | 1364 | ||
1365 | mutex_unlock(®ulator_list_mutex); | 1365 | mutex_unlock(®ulator_list_mutex); |
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 56727eb745df..91e99a2c8dc1 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * Regulator driver for DA9063 PMIC series | 3 | * Regulator driver for DA9063 PMIC series |
3 | * | 4 | * |
@@ -60,7 +61,8 @@ struct da9063_regulator_info { | |||
60 | .desc.ops = &da9063_ldo_ops, \ | 61 | .desc.ops = &da9063_ldo_ops, \ |
61 | .desc.min_uV = (min_mV) * 1000, \ | 62 | .desc.min_uV = (min_mV) * 1000, \ |
62 | .desc.uV_step = (step_mV) * 1000, \ | 63 | .desc.uV_step = (step_mV) * 1000, \ |
63 | .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1), \ | 64 | .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1 \ |
65 | + (DA9063_V##regl_name##_BIAS)), \ | ||
64 | .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ | 66 | .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ |
65 | .desc.enable_mask = DA9063_LDO_EN, \ | 67 | .desc.enable_mask = DA9063_LDO_EN, \ |
66 | .desc.vsel_reg = DA9063_REG_V##regl_name##_A, \ | 68 | .desc.vsel_reg = DA9063_REG_V##regl_name##_A, \ |
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index 186df8785a91..e0619526708c 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c | |||
@@ -166,9 +166,10 @@ static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) | |||
166 | 166 | ||
167 | ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, | 167 | ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, |
168 | MAX14577_REG_MAX); | 168 | MAX14577_REG_MAX); |
169 | if (ret < 0) { | 169 | if (ret < 0) |
170 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); | 170 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); |
171 | } | 171 | else |
172 | ret = 0; | ||
172 | 173 | ||
173 | of_node_put(np); | 174 | of_node_put(np); |
174 | 175 | ||
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index d7164bb75d3e..d958dfa05125 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c | |||
@@ -535,7 +535,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
535 | return -ENODEV; | 535 | return -ENODEV; |
536 | } | 536 | } |
537 | 537 | ||
538 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | 538 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); |
539 | if (!regulators_np) { | 539 | if (!regulators_np) { |
540 | dev_err(iodev->dev, "could not find regulators sub-node\n"); | 540 | dev_err(iodev->dev, "could not find regulators sub-node\n"); |
541 | return -EINVAL; | 541 | return -EINVAL; |
@@ -591,6 +591,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
591 | rmode++; | 591 | rmode++; |
592 | } | 592 | } |
593 | 593 | ||
594 | of_node_put(regulators_np); | ||
595 | |||
594 | if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { | 596 | if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { |
595 | pdata->buck2_gpiodvs = true; | 597 | pdata->buck2_gpiodvs = true; |
596 | 598 | ||
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index f6b9188c5af5..9f0ea6cb6922 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -610,6 +610,7 @@ void chsc_chp_online(struct chp_id chpid) | |||
610 | css_wait_for_slow_path(); | 610 | css_wait_for_slow_path(); |
611 | for_each_subchannel_staged(__s390_process_res_acc, NULL, | 611 | for_each_subchannel_staged(__s390_process_res_acc, NULL, |
612 | &link); | 612 | &link); |
613 | css_schedule_reprobe(); | ||
613 | } | 614 | } |
614 | } | 615 | } |
615 | 616 | ||
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index dc542e0a3055..0bc91e46395a 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c | |||
@@ -311,7 +311,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
311 | } __packed * msg = ap_msg->message; | 311 | } __packed * msg = ap_msg->message; |
312 | 312 | ||
313 | int rcblen = CEIL4(xcRB->request_control_blk_length); | 313 | int rcblen = CEIL4(xcRB->request_control_blk_length); |
314 | int replylen; | 314 | int replylen, req_sumlen, resp_sumlen; |
315 | char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; | 315 | char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; |
316 | char *function_code; | 316 | char *function_code; |
317 | 317 | ||
@@ -321,12 +321,34 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
321 | xcRB->request_data_length; | 321 | xcRB->request_data_length; |
322 | if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) | 322 | if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) |
323 | return -EINVAL; | 323 | return -EINVAL; |
324 | |||
325 | /* Overflow check | ||
326 | sum must be greater (or equal) than the largest operand */ | ||
327 | req_sumlen = CEIL4(xcRB->request_control_blk_length) + | ||
328 | xcRB->request_data_length; | ||
329 | if ((CEIL4(xcRB->request_control_blk_length) <= | ||
330 | xcRB->request_data_length) ? | ||
331 | (req_sumlen < xcRB->request_data_length) : | ||
332 | (req_sumlen < CEIL4(xcRB->request_control_blk_length))) { | ||
333 | return -EINVAL; | ||
334 | } | ||
335 | |||
324 | replylen = sizeof(struct type86_fmt2_msg) + | 336 | replylen = sizeof(struct type86_fmt2_msg) + |
325 | CEIL4(xcRB->reply_control_blk_length) + | 337 | CEIL4(xcRB->reply_control_blk_length) + |
326 | xcRB->reply_data_length; | 338 | xcRB->reply_data_length; |
327 | if (replylen > MSGTYPE06_MAX_MSG_SIZE) | 339 | if (replylen > MSGTYPE06_MAX_MSG_SIZE) |
328 | return -EINVAL; | 340 | return -EINVAL; |
329 | 341 | ||
342 | /* Overflow check | ||
343 | sum must be greater (or equal) than the largest operand */ | ||
344 | resp_sumlen = CEIL4(xcRB->reply_control_blk_length) + | ||
345 | xcRB->reply_data_length; | ||
346 | if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ? | ||
347 | (resp_sumlen < xcRB->reply_data_length) : | ||
348 | (resp_sumlen < CEIL4(xcRB->reply_control_blk_length))) { | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
330 | /* prepare type6 header */ | 352 | /* prepare type6 header */ |
331 | msg->hdr = static_type6_hdrX; | 353 | msg->hdr = static_type6_hdrX; |
332 | memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); | 354 | memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); |
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 6b4678a7900a..4ccb5d869389 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c | |||
@@ -507,7 +507,6 @@ static int jsflash_init(void) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | /* Let us be really paranoid for modifications to probing code. */ | 509 | /* Let us be really paranoid for modifications to probing code. */ |
510 | /* extern enum sparc_cpu sparc_cpu_model; */ /* in <asm/system.h> */ | ||
511 | if (sparc_cpu_model != sun4m) { | 510 | if (sparc_cpu_model != sun4m) { |
512 | /* We must be on sun4m because we use MMU Bypass ASI. */ | 511 | /* We must be on sun4m because we use MMU Bypass ASI. */ |
513 | return -ENXIO; | 512 | return -ENXIO; |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 2eb97d7e8d12..0cb73074c199 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -790,17 +790,32 @@ static inline int test_tgt_sess_count(struct qla_tgt *tgt) | |||
790 | } | 790 | } |
791 | 791 | ||
792 | /* Called by tcm_qla2xxx configfs code */ | 792 | /* Called by tcm_qla2xxx configfs code */ |
793 | void qlt_stop_phase1(struct qla_tgt *tgt) | 793 | int qlt_stop_phase1(struct qla_tgt *tgt) |
794 | { | 794 | { |
795 | struct scsi_qla_host *vha = tgt->vha; | 795 | struct scsi_qla_host *vha = tgt->vha; |
796 | struct qla_hw_data *ha = tgt->ha; | 796 | struct qla_hw_data *ha = tgt->ha; |
797 | unsigned long flags; | 797 | unsigned long flags; |
798 | 798 | ||
799 | mutex_lock(&qla_tgt_mutex); | ||
800 | if (!vha->fc_vport) { | ||
801 | struct Scsi_Host *sh = vha->host; | ||
802 | struct fc_host_attrs *fc_host = shost_to_fc_host(sh); | ||
803 | bool npiv_vports; | ||
804 | |||
805 | spin_lock_irqsave(sh->host_lock, flags); | ||
806 | npiv_vports = (fc_host->npiv_vports_inuse); | ||
807 | spin_unlock_irqrestore(sh->host_lock, flags); | ||
808 | |||
809 | if (npiv_vports) { | ||
810 | mutex_unlock(&qla_tgt_mutex); | ||
811 | return -EPERM; | ||
812 | } | ||
813 | } | ||
799 | if (tgt->tgt_stop || tgt->tgt_stopped) { | 814 | if (tgt->tgt_stop || tgt->tgt_stopped) { |
800 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, | 815 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, |
801 | "Already in tgt->tgt_stop or tgt_stopped state\n"); | 816 | "Already in tgt->tgt_stop or tgt_stopped state\n"); |
802 | dump_stack(); | 817 | mutex_unlock(&qla_tgt_mutex); |
803 | return; | 818 | return -EPERM; |
804 | } | 819 | } |
805 | 820 | ||
806 | ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", | 821 | ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", |
@@ -815,6 +830,7 @@ void qlt_stop_phase1(struct qla_tgt *tgt) | |||
815 | qlt_clear_tgt_db(tgt, true); | 830 | qlt_clear_tgt_db(tgt, true); |
816 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 831 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
817 | mutex_unlock(&vha->vha_tgt.tgt_mutex); | 832 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
833 | mutex_unlock(&qla_tgt_mutex); | ||
818 | 834 | ||
819 | flush_delayed_work(&tgt->sess_del_work); | 835 | flush_delayed_work(&tgt->sess_del_work); |
820 | 836 | ||
@@ -841,6 +857,7 @@ void qlt_stop_phase1(struct qla_tgt *tgt) | |||
841 | 857 | ||
842 | /* Wait for sessions to clear out (just in case) */ | 858 | /* Wait for sessions to clear out (just in case) */ |
843 | wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); | 859 | wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); |
860 | return 0; | ||
844 | } | 861 | } |
845 | EXPORT_SYMBOL(qlt_stop_phase1); | 862 | EXPORT_SYMBOL(qlt_stop_phase1); |
846 | 863 | ||
@@ -3185,7 +3202,8 @@ restart: | |||
3185 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, | 3202 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, |
3186 | "SRR cmd %p (se_cmd %p, tag %d, op %x), " | 3203 | "SRR cmd %p (se_cmd %p, tag %d, op %x), " |
3187 | "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, | 3204 | "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, |
3188 | se_cmd->t_task_cdb[0], cmd->sg_cnt, cmd->offset); | 3205 | se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, |
3206 | cmd->sg_cnt, cmd->offset); | ||
3189 | 3207 | ||
3190 | qlt_handle_srr(vha, sctio, imm); | 3208 | qlt_handle_srr(vha, sctio, imm); |
3191 | 3209 | ||
@@ -4181,6 +4199,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
4181 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; | 4199 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; |
4182 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; | 4200 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; |
4183 | 4201 | ||
4202 | if (base_vha->fc_vport) | ||
4203 | return 0; | ||
4204 | |||
4184 | mutex_lock(&qla_tgt_mutex); | 4205 | mutex_lock(&qla_tgt_mutex); |
4185 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); | 4206 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); |
4186 | mutex_unlock(&qla_tgt_mutex); | 4207 | mutex_unlock(&qla_tgt_mutex); |
@@ -4194,6 +4215,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) | |||
4194 | if (!vha->vha_tgt.qla_tgt) | 4215 | if (!vha->vha_tgt.qla_tgt) |
4195 | return 0; | 4216 | return 0; |
4196 | 4217 | ||
4218 | if (vha->fc_vport) { | ||
4219 | qlt_release(vha->vha_tgt.qla_tgt); | ||
4220 | return 0; | ||
4221 | } | ||
4197 | mutex_lock(&qla_tgt_mutex); | 4222 | mutex_lock(&qla_tgt_mutex); |
4198 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); | 4223 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); |
4199 | mutex_unlock(&qla_tgt_mutex); | 4224 | mutex_unlock(&qla_tgt_mutex); |
@@ -4265,6 +4290,12 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | |||
4265 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4290 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4266 | continue; | 4291 | continue; |
4267 | } | 4292 | } |
4293 | if (tgt->tgt_stop) { | ||
4294 | pr_debug("MODE_TARGET in shutdown on qla2xxx(%d)\n", | ||
4295 | host->host_no); | ||
4296 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4297 | continue; | ||
4298 | } | ||
4268 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4299 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4269 | 4300 | ||
4270 | if (!scsi_host_get(host)) { | 4301 | if (!scsi_host_get(host)) { |
@@ -4279,12 +4310,11 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | |||
4279 | scsi_host_put(host); | 4310 | scsi_host_put(host); |
4280 | continue; | 4311 | continue; |
4281 | } | 4312 | } |
4282 | mutex_unlock(&qla_tgt_mutex); | ||
4283 | |||
4284 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); | 4313 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); |
4285 | if (rc != 0) | 4314 | if (rc != 0) |
4286 | scsi_host_put(host); | 4315 | scsi_host_put(host); |
4287 | 4316 | ||
4317 | mutex_unlock(&qla_tgt_mutex); | ||
4288 | return rc; | 4318 | return rc; |
4289 | } | 4319 | } |
4290 | mutex_unlock(&qla_tgt_mutex); | 4320 | mutex_unlock(&qla_tgt_mutex); |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 66e755cdde57..ce33d8c26406 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -1001,7 +1001,7 @@ extern void qlt_modify_vp_config(struct scsi_qla_host *, | |||
1001 | extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); | 1001 | extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); |
1002 | extern int qlt_mem_alloc(struct qla_hw_data *); | 1002 | extern int qlt_mem_alloc(struct qla_hw_data *); |
1003 | extern void qlt_mem_free(struct qla_hw_data *); | 1003 | extern void qlt_mem_free(struct qla_hw_data *); |
1004 | extern void qlt_stop_phase1(struct qla_tgt *); | 1004 | extern int qlt_stop_phase1(struct qla_tgt *); |
1005 | extern void qlt_stop_phase2(struct qla_tgt *); | 1005 | extern void qlt_stop_phase2(struct qla_tgt *); |
1006 | extern irqreturn_t qla83xx_msix_atio_q(int, void *); | 1006 | extern irqreturn_t qla83xx_msix_atio_q(int, void *); |
1007 | extern void qlt_83xx_iospace_config(struct qla_hw_data *); | 1007 | extern void qlt_83xx_iospace_config(struct qla_hw_data *); |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 75a141bbe74d..788c4fe2b0c9 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -182,20 +182,6 @@ static int tcm_qla2xxx_npiv_parse_wwn( | |||
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
184 | 184 | ||
185 | static ssize_t tcm_qla2xxx_npiv_format_wwn(char *buf, size_t len, | ||
186 | u64 wwpn, u64 wwnn) | ||
187 | { | ||
188 | u8 b[8], b2[8]; | ||
189 | |||
190 | put_unaligned_be64(wwpn, b); | ||
191 | put_unaligned_be64(wwnn, b2); | ||
192 | return snprintf(buf, len, | ||
193 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x," | ||
194 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", | ||
195 | b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], | ||
196 | b2[0], b2[1], b2[2], b2[3], b2[4], b2[5], b2[6], b2[7]); | ||
197 | } | ||
198 | |||
199 | static char *tcm_qla2xxx_npiv_get_fabric_name(void) | 185 | static char *tcm_qla2xxx_npiv_get_fabric_name(void) |
200 | { | 186 | { |
201 | return "qla2xxx_npiv"; | 187 | return "qla2xxx_npiv"; |
@@ -227,15 +213,6 @@ static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) | |||
227 | return lport->lport_naa_name; | 213 | return lport->lport_naa_name; |
228 | } | 214 | } |
229 | 215 | ||
230 | static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) | ||
231 | { | ||
232 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | ||
233 | struct tcm_qla2xxx_tpg, se_tpg); | ||
234 | struct tcm_qla2xxx_lport *lport = tpg->lport; | ||
235 | |||
236 | return &lport->lport_npiv_name[0]; | ||
237 | } | ||
238 | |||
239 | static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg) | 216 | static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg) |
240 | { | 217 | { |
241 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | 218 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, |
@@ -941,15 +918,41 @@ static ssize_t tcm_qla2xxx_tpg_show_enable( | |||
941 | atomic_read(&tpg->lport_tpg_enabled)); | 918 | atomic_read(&tpg->lport_tpg_enabled)); |
942 | } | 919 | } |
943 | 920 | ||
921 | static void tcm_qla2xxx_depend_tpg(struct work_struct *work) | ||
922 | { | ||
923 | struct tcm_qla2xxx_tpg *base_tpg = container_of(work, | ||
924 | struct tcm_qla2xxx_tpg, tpg_base_work); | ||
925 | struct se_portal_group *se_tpg = &base_tpg->se_tpg; | ||
926 | struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; | ||
927 | |||
928 | if (!configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys, | ||
929 | &se_tpg->tpg_group.cg_item)) { | ||
930 | atomic_set(&base_tpg->lport_tpg_enabled, 1); | ||
931 | qlt_enable_vha(base_vha); | ||
932 | } | ||
933 | complete(&base_tpg->tpg_base_comp); | ||
934 | } | ||
935 | |||
936 | static void tcm_qla2xxx_undepend_tpg(struct work_struct *work) | ||
937 | { | ||
938 | struct tcm_qla2xxx_tpg *base_tpg = container_of(work, | ||
939 | struct tcm_qla2xxx_tpg, tpg_base_work); | ||
940 | struct se_portal_group *se_tpg = &base_tpg->se_tpg; | ||
941 | struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; | ||
942 | |||
943 | if (!qlt_stop_phase1(base_vha->vha_tgt.qla_tgt)) { | ||
944 | atomic_set(&base_tpg->lport_tpg_enabled, 0); | ||
945 | configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys, | ||
946 | &se_tpg->tpg_group.cg_item); | ||
947 | } | ||
948 | complete(&base_tpg->tpg_base_comp); | ||
949 | } | ||
950 | |||
944 | static ssize_t tcm_qla2xxx_tpg_store_enable( | 951 | static ssize_t tcm_qla2xxx_tpg_store_enable( |
945 | struct se_portal_group *se_tpg, | 952 | struct se_portal_group *se_tpg, |
946 | const char *page, | 953 | const char *page, |
947 | size_t count) | 954 | size_t count) |
948 | { | 955 | { |
949 | struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; | ||
950 | struct tcm_qla2xxx_lport *lport = container_of(se_wwn, | ||
951 | struct tcm_qla2xxx_lport, lport_wwn); | ||
952 | struct scsi_qla_host *vha = lport->qla_vha; | ||
953 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | 956 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, |
954 | struct tcm_qla2xxx_tpg, se_tpg); | 957 | struct tcm_qla2xxx_tpg, se_tpg); |
955 | unsigned long op; | 958 | unsigned long op; |
@@ -964,19 +967,28 @@ static ssize_t tcm_qla2xxx_tpg_store_enable( | |||
964 | pr_err("Illegal value for tpg_enable: %lu\n", op); | 967 | pr_err("Illegal value for tpg_enable: %lu\n", op); |
965 | return -EINVAL; | 968 | return -EINVAL; |
966 | } | 969 | } |
967 | |||
968 | if (op) { | 970 | if (op) { |
969 | atomic_set(&tpg->lport_tpg_enabled, 1); | 971 | if (atomic_read(&tpg->lport_tpg_enabled)) |
970 | qlt_enable_vha(vha); | 972 | return -EEXIST; |
973 | |||
974 | INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_depend_tpg); | ||
971 | } else { | 975 | } else { |
972 | if (!vha->vha_tgt.qla_tgt) { | 976 | if (!atomic_read(&tpg->lport_tpg_enabled)) |
973 | pr_err("struct qla_hw_data *vha->vha_tgt.qla_tgt is NULL\n"); | 977 | return count; |
974 | return -ENODEV; | 978 | |
975 | } | 979 | INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_undepend_tpg); |
976 | atomic_set(&tpg->lport_tpg_enabled, 0); | ||
977 | qlt_stop_phase1(vha->vha_tgt.qla_tgt); | ||
978 | } | 980 | } |
981 | init_completion(&tpg->tpg_base_comp); | ||
982 | schedule_work(&tpg->tpg_base_work); | ||
983 | wait_for_completion(&tpg->tpg_base_comp); | ||
979 | 984 | ||
985 | if (op) { | ||
986 | if (!atomic_read(&tpg->lport_tpg_enabled)) | ||
987 | return -ENODEV; | ||
988 | } else { | ||
989 | if (atomic_read(&tpg->lport_tpg_enabled)) | ||
990 | return -EPERM; | ||
991 | } | ||
980 | return count; | 992 | return count; |
981 | } | 993 | } |
982 | 994 | ||
@@ -1053,11 +1065,64 @@ static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg) | |||
1053 | /* | 1065 | /* |
1054 | * Clear local TPG=1 pointer for non NPIV mode. | 1066 | * Clear local TPG=1 pointer for non NPIV mode. |
1055 | */ | 1067 | */ |
1056 | lport->tpg_1 = NULL; | 1068 | lport->tpg_1 = NULL; |
1057 | |||
1058 | kfree(tpg); | 1069 | kfree(tpg); |
1059 | } | 1070 | } |
1060 | 1071 | ||
1072 | static ssize_t tcm_qla2xxx_npiv_tpg_show_enable( | ||
1073 | struct se_portal_group *se_tpg, | ||
1074 | char *page) | ||
1075 | { | ||
1076 | return tcm_qla2xxx_tpg_show_enable(se_tpg, page); | ||
1077 | } | ||
1078 | |||
1079 | static ssize_t tcm_qla2xxx_npiv_tpg_store_enable( | ||
1080 | struct se_portal_group *se_tpg, | ||
1081 | const char *page, | ||
1082 | size_t count) | ||
1083 | { | ||
1084 | struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; | ||
1085 | struct tcm_qla2xxx_lport *lport = container_of(se_wwn, | ||
1086 | struct tcm_qla2xxx_lport, lport_wwn); | ||
1087 | struct scsi_qla_host *vha = lport->qla_vha; | ||
1088 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | ||
1089 | struct tcm_qla2xxx_tpg, se_tpg); | ||
1090 | unsigned long op; | ||
1091 | int rc; | ||
1092 | |||
1093 | rc = kstrtoul(page, 0, &op); | ||
1094 | if (rc < 0) { | ||
1095 | pr_err("kstrtoul() returned %d\n", rc); | ||
1096 | return -EINVAL; | ||
1097 | } | ||
1098 | if ((op != 1) && (op != 0)) { | ||
1099 | pr_err("Illegal value for tpg_enable: %lu\n", op); | ||
1100 | return -EINVAL; | ||
1101 | } | ||
1102 | if (op) { | ||
1103 | if (atomic_read(&tpg->lport_tpg_enabled)) | ||
1104 | return -EEXIST; | ||
1105 | |||
1106 | atomic_set(&tpg->lport_tpg_enabled, 1); | ||
1107 | qlt_enable_vha(vha); | ||
1108 | } else { | ||
1109 | if (!atomic_read(&tpg->lport_tpg_enabled)) | ||
1110 | return count; | ||
1111 | |||
1112 | atomic_set(&tpg->lport_tpg_enabled, 0); | ||
1113 | qlt_stop_phase1(vha->vha_tgt.qla_tgt); | ||
1114 | } | ||
1115 | |||
1116 | return count; | ||
1117 | } | ||
1118 | |||
1119 | TF_TPG_BASE_ATTR(tcm_qla2xxx_npiv, enable, S_IRUGO | S_IWUSR); | ||
1120 | |||
1121 | static struct configfs_attribute *tcm_qla2xxx_npiv_tpg_attrs[] = { | ||
1122 | &tcm_qla2xxx_npiv_tpg_enable.attr, | ||
1123 | NULL, | ||
1124 | }; | ||
1125 | |||
1061 | static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( | 1126 | static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( |
1062 | struct se_wwn *wwn, | 1127 | struct se_wwn *wwn, |
1063 | struct config_group *group, | 1128 | struct config_group *group, |
@@ -1650,6 +1715,9 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1650 | struct scsi_qla_host *npiv_vha; | 1715 | struct scsi_qla_host *npiv_vha; |
1651 | struct tcm_qla2xxx_lport *lport = | 1716 | struct tcm_qla2xxx_lport *lport = |
1652 | (struct tcm_qla2xxx_lport *)target_lport_ptr; | 1717 | (struct tcm_qla2xxx_lport *)target_lport_ptr; |
1718 | struct tcm_qla2xxx_lport *base_lport = | ||
1719 | (struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr; | ||
1720 | struct tcm_qla2xxx_tpg *base_tpg; | ||
1653 | struct fc_vport_identifiers vport_id; | 1721 | struct fc_vport_identifiers vport_id; |
1654 | 1722 | ||
1655 | if (!qla_tgt_mode_enabled(base_vha)) { | 1723 | if (!qla_tgt_mode_enabled(base_vha)) { |
@@ -1657,6 +1725,13 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1657 | return -EPERM; | 1725 | return -EPERM; |
1658 | } | 1726 | } |
1659 | 1727 | ||
1728 | if (!base_lport || !base_lport->tpg_1 || | ||
1729 | !atomic_read(&base_lport->tpg_1->lport_tpg_enabled)) { | ||
1730 | pr_err("qla2xxx base_lport or tpg_1 not available\n"); | ||
1731 | return -EPERM; | ||
1732 | } | ||
1733 | base_tpg = base_lport->tpg_1; | ||
1734 | |||
1660 | memset(&vport_id, 0, sizeof(vport_id)); | 1735 | memset(&vport_id, 0, sizeof(vport_id)); |
1661 | vport_id.port_name = npiv_wwpn; | 1736 | vport_id.port_name = npiv_wwpn; |
1662 | vport_id.node_name = npiv_wwnn; | 1737 | vport_id.node_name = npiv_wwnn; |
@@ -1675,7 +1750,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1675 | npiv_vha = (struct scsi_qla_host *)vport->dd_data; | 1750 | npiv_vha = (struct scsi_qla_host *)vport->dd_data; |
1676 | npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr; | 1751 | npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr; |
1677 | lport->qla_vha = npiv_vha; | 1752 | lport->qla_vha = npiv_vha; |
1678 | |||
1679 | scsi_host_get(npiv_vha->host); | 1753 | scsi_host_get(npiv_vha->host); |
1680 | return 0; | 1754 | return 0; |
1681 | } | 1755 | } |
@@ -1714,8 +1788,6 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( | |||
1714 | } | 1788 | } |
1715 | lport->lport_npiv_wwpn = npiv_wwpn; | 1789 | lport->lport_npiv_wwpn = npiv_wwpn; |
1716 | lport->lport_npiv_wwnn = npiv_wwnn; | 1790 | lport->lport_npiv_wwnn = npiv_wwnn; |
1717 | tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], | ||
1718 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); | ||
1719 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); | 1791 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); |
1720 | 1792 | ||
1721 | ret = tcm_qla2xxx_init_lport(lport); | 1793 | ret = tcm_qla2xxx_init_lport(lport); |
@@ -1824,7 +1896,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { | |||
1824 | static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | 1896 | static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { |
1825 | .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, | 1897 | .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, |
1826 | .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, | 1898 | .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, |
1827 | .tpg_get_wwn = tcm_qla2xxx_npiv_get_fabric_wwn, | 1899 | .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, |
1828 | .tpg_get_tag = tcm_qla2xxx_get_tag, | 1900 | .tpg_get_tag = tcm_qla2xxx_get_tag, |
1829 | .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, | 1901 | .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, |
1830 | .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, | 1902 | .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, |
@@ -1935,7 +2007,7 @@ static int tcm_qla2xxx_register_configfs(void) | |||
1935 | */ | 2007 | */ |
1936 | npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; | 2008 | npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; |
1937 | npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = | 2009 | npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = |
1938 | tcm_qla2xxx_tpg_attrs; | 2010 | tcm_qla2xxx_npiv_tpg_attrs; |
1939 | npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | 2011 | npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; |
1940 | npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | 2012 | npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; |
1941 | npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | 2013 | npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 275d8b9a7a34..33aaac8c7d59 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #define TCM_QLA2XXX_VERSION "v0.1" | 4 | #define TCM_QLA2XXX_VERSION "v0.1" |
5 | /* length of ASCII WWPNs including pad */ | 5 | /* length of ASCII WWPNs including pad */ |
6 | #define TCM_QLA2XXX_NAMELEN 32 | 6 | #define TCM_QLA2XXX_NAMELEN 32 |
7 | /* lenth of ASCII NPIV 'WWPN+WWNN' including pad */ | ||
8 | #define TCM_QLA2XXX_NPIV_NAMELEN 66 | ||
9 | 7 | ||
10 | #include "qla_target.h" | 8 | #include "qla_target.h" |
11 | 9 | ||
@@ -43,6 +41,9 @@ struct tcm_qla2xxx_tpg { | |||
43 | struct tcm_qla2xxx_tpg_attrib tpg_attrib; | 41 | struct tcm_qla2xxx_tpg_attrib tpg_attrib; |
44 | /* Returned by tcm_qla2xxx_make_tpg() */ | 42 | /* Returned by tcm_qla2xxx_make_tpg() */ |
45 | struct se_portal_group se_tpg; | 43 | struct se_portal_group se_tpg; |
44 | /* Items for dealing with configfs_depend_item */ | ||
45 | struct completion tpg_base_comp; | ||
46 | struct work_struct tpg_base_work; | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | struct tcm_qla2xxx_fc_loopid { | 49 | struct tcm_qla2xxx_fc_loopid { |
@@ -62,8 +63,6 @@ struct tcm_qla2xxx_lport { | |||
62 | char lport_name[TCM_QLA2XXX_NAMELEN]; | 63 | char lport_name[TCM_QLA2XXX_NAMELEN]; |
63 | /* ASCII formatted naa WWPN for VPD page 83 etc */ | 64 | /* ASCII formatted naa WWPN for VPD page 83 etc */ |
64 | char lport_naa_name[TCM_QLA2XXX_NAMELEN]; | 65 | char lport_naa_name[TCM_QLA2XXX_NAMELEN]; |
65 | /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ | ||
66 | char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; | ||
67 | /* map for fc_port pointers in 24-bit FC Port ID space */ | 66 | /* map for fc_port pointers in 24-bit FC Port ID space */ |
68 | struct btree_head32 lport_fcport_map; | 67 | struct btree_head32 lport_fcport_map; |
69 | /* vmalloc-ed memory for fc_port pointers for 16-bit FC loop ID */ | 68 | /* vmalloc-ed memory for fc_port pointers for 16-bit FC loop ID */ |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7bd7f0d5f050..62ec84b42e31 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1684,7 +1684,7 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) | |||
1684 | 1684 | ||
1685 | host_dev = scsi_get_device(shost); | 1685 | host_dev = scsi_get_device(shost); |
1686 | if (host_dev && host_dev->dma_mask) | 1686 | if (host_dev && host_dev->dma_mask) |
1687 | bounce_limit = dma_max_pfn(host_dev) << PAGE_SHIFT; | 1687 | bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT; |
1688 | 1688 | ||
1689 | return bounce_limit; | 1689 | return bounce_limit; |
1690 | } | 1690 | } |
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index eaec1dab7fe4..1432d956769c 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -2904,7 +2904,7 @@ static int binder_node_release(struct binder_node *node, int refs) | |||
2904 | refs++; | 2904 | refs++; |
2905 | 2905 | ||
2906 | if (!ref->death) | 2906 | if (!ref->death) |
2907 | goto out; | 2907 | continue; |
2908 | 2908 | ||
2909 | death++; | 2909 | death++; |
2910 | 2910 | ||
@@ -2917,7 +2917,6 @@ static int binder_node_release(struct binder_node *node, int refs) | |||
2917 | BUG(); | 2917 | BUG(); |
2918 | } | 2918 | } |
2919 | 2919 | ||
2920 | out: | ||
2921 | binder_debug(BINDER_DEBUG_DEAD_BINDER, | 2920 | binder_debug(BINDER_DEBUG_DEAD_BINDER, |
2922 | "node %d now dead, refs %d, death %d\n", | 2921 | "node %d now dead, refs %d, death %d\n", |
2923 | node->debug_id, refs, death); | 2922 | node->debug_id, refs, death); |
diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 8dfdd2732bdc..95a2358267ba 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c | |||
@@ -40,7 +40,7 @@ static INT bcm_close(struct net_device *dev) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb, | 42 | static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb, |
43 | void *accel_priv) | 43 | void *accel_priv, select_queue_fallback_t fallback) |
44 | { | 44 | { |
45 | return ClassifyPacket(netdev_priv(dev), skb); | 45 | return ClassifyPacket(netdev_priv(dev), skb); |
46 | } | 46 | } |
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 7fc66a6a6e36..514844efac75 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c | |||
@@ -757,6 +757,7 @@ static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid) | |||
757 | } | 757 | } |
758 | 758 | ||
759 | /* if it is released, wait for the next touch via IRQ */ | 759 | /* if it is released, wait for the next touch via IRQ */ |
760 | lradc->cur_plate = LRADC_TOUCH; | ||
760 | mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1); | 761 | mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1); |
761 | mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); | 762 | mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); |
762 | } | 763 | } |
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index d8ea25486a33..31b269a5fff7 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c | |||
@@ -307,7 +307,7 @@ static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb, | |||
307 | } | 307 | } |
308 | 308 | ||
309 | static u16 xlr_net_select_queue(struct net_device *ndev, struct sk_buff *skb, | 309 | static u16 xlr_net_select_queue(struct net_device *ndev, struct sk_buff *skb, |
310 | void *accel_priv) | 310 | void *accel_priv, select_queue_fallback_t fallback) |
311 | { | 311 | { |
312 | return (u16)smp_processor_id(); | 312 | return (u16)smp_processor_id(); |
313 | } | 313 | } |
diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 68f98fa114d2..7c9ee58f47bb 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c | |||
@@ -653,7 +653,7 @@ static unsigned int rtw_classify8021d(struct sk_buff *skb) | |||
653 | } | 653 | } |
654 | 654 | ||
655 | static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, | 655 | static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, |
656 | void *accel_priv) | 656 | void *accel_priv, select_queue_fallback_t fallback) |
657 | { | 657 | { |
658 | struct adapter *padapter = rtw_netdev_priv(dev); | 658 | struct adapter *padapter = rtw_netdev_priv(dev); |
659 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | 659 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; |
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index a70dcef1419e..2f40ff5901d6 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c | |||
@@ -55,6 +55,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = { | |||
55 | /****** 8188EUS ********/ | 55 | /****** 8188EUS ********/ |
56 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ | 56 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ |
57 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ | 57 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ |
58 | {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ | ||
58 | {} /* Terminating entry */ | 59 | {} /* Terminating entry */ |
59 | }; | 60 | }; |
60 | 61 | ||
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a4489444ffbc..42f18fc1067b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -1074,7 +1074,7 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, | |||
1074 | struct scatterlist *psg; | 1074 | struct scatterlist *psg; |
1075 | void *paddr, *addr; | 1075 | void *paddr, *addr; |
1076 | unsigned int i, len, left; | 1076 | unsigned int i, len, left; |
1077 | unsigned int offset = 0; | 1077 | unsigned int offset = sg_off; |
1078 | 1078 | ||
1079 | left = sectors * dev->prot_length; | 1079 | left = sectors * dev->prot_length; |
1080 | 1080 | ||
@@ -1084,11 +1084,10 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, | |||
1084 | if (offset >= sg->length) { | 1084 | if (offset >= sg->length) { |
1085 | sg = sg_next(sg); | 1085 | sg = sg_next(sg); |
1086 | offset = 0; | 1086 | offset = 0; |
1087 | sg_off = sg->offset; | ||
1088 | } | 1087 | } |
1089 | 1088 | ||
1090 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; | 1089 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; |
1091 | addr = kmap_atomic(sg_page(sg)) + sg_off; | 1090 | addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; |
1092 | 1091 | ||
1093 | if (read) | 1092 | if (read) |
1094 | memcpy(paddr, addr, len); | 1093 | memcpy(paddr, addr, len); |
@@ -1163,7 +1162,7 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1163 | { | 1162 | { |
1164 | struct se_device *dev = cmd->se_dev; | 1163 | struct se_device *dev = cmd->se_dev; |
1165 | struct se_dif_v1_tuple *sdt; | 1164 | struct se_dif_v1_tuple *sdt; |
1166 | struct scatterlist *dsg; | 1165 | struct scatterlist *dsg, *psg = sg; |
1167 | sector_t sector = start; | 1166 | sector_t sector = start; |
1168 | void *daddr, *paddr; | 1167 | void *daddr, *paddr; |
1169 | int i, j, offset = sg_off; | 1168 | int i, j, offset = sg_off; |
@@ -1171,14 +1170,14 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1171 | 1170 | ||
1172 | for_each_sg(cmd->t_data_sg, dsg, cmd->t_data_nents, i) { | 1171 | for_each_sg(cmd->t_data_sg, dsg, cmd->t_data_nents, i) { |
1173 | daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; | 1172 | daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; |
1174 | paddr = kmap_atomic(sg_page(sg)) + sg->offset; | 1173 | paddr = kmap_atomic(sg_page(psg)) + sg->offset; |
1175 | 1174 | ||
1176 | for (j = 0; j < dsg->length; j += dev->dev_attrib.block_size) { | 1175 | for (j = 0; j < dsg->length; j += dev->dev_attrib.block_size) { |
1177 | 1176 | ||
1178 | if (offset >= sg->length) { | 1177 | if (offset >= psg->length) { |
1179 | kunmap_atomic(paddr); | 1178 | kunmap_atomic(paddr); |
1180 | sg = sg_next(sg); | 1179 | psg = sg_next(psg); |
1181 | paddr = kmap_atomic(sg_page(sg)) + sg->offset; | 1180 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; |
1182 | offset = 0; | 1181 | offset = 0; |
1183 | } | 1182 | } |
1184 | 1183 | ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 24b4f65d8777..2956250b7225 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1601,6 +1601,9 @@ void transport_generic_request_failure(struct se_cmd *cmd, | |||
1601 | case TCM_CHECK_CONDITION_ABORT_CMD: | 1601 | case TCM_CHECK_CONDITION_ABORT_CMD: |
1602 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: | 1602 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: |
1603 | case TCM_CHECK_CONDITION_NOT_READY: | 1603 | case TCM_CHECK_CONDITION_NOT_READY: |
1604 | case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED: | ||
1605 | case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: | ||
1606 | case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: | ||
1604 | break; | 1607 | break; |
1605 | case TCM_OUT_OF_RESOURCES: | 1608 | case TCM_OUT_OF_RESOURCES: |
1606 | sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1609 | sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index bd2715a9d8e5..c74a00ad7add 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1267,17 +1267,16 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1267 | * @p: output buffer of at least 7 bytes | 1267 | * @p: output buffer of at least 7 bytes |
1268 | * | 1268 | * |
1269 | * Generate a name from a driver reference and write it to the output | 1269 | * Generate a name from a driver reference and write it to the output |
1270 | * buffer. Return the number of bytes written. | 1270 | * buffer. |
1271 | * | 1271 | * |
1272 | * Locking: None | 1272 | * Locking: None |
1273 | */ | 1273 | */ |
1274 | static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p) | 1274 | static void tty_line_name(struct tty_driver *driver, int index, char *p) |
1275 | { | 1275 | { |
1276 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) | 1276 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) |
1277 | return sprintf(p, "%s", driver->name); | 1277 | strcpy(p, driver->name); |
1278 | else | 1278 | else |
1279 | return sprintf(p, "%s%d", driver->name, | 1279 | sprintf(p, "%s%d", driver->name, index + driver->name_base); |
1280 | index + driver->name_base); | ||
1281 | } | 1280 | } |
1282 | 1281 | ||
1283 | /** | 1282 | /** |
@@ -3546,19 +3545,9 @@ static ssize_t show_cons_active(struct device *dev, | |||
3546 | if (i >= ARRAY_SIZE(cs)) | 3545 | if (i >= ARRAY_SIZE(cs)) |
3547 | break; | 3546 | break; |
3548 | } | 3547 | } |
3549 | while (i--) { | 3548 | while (i--) |
3550 | struct tty_driver *driver; | 3549 | count += sprintf(buf + count, "%s%d%c", |
3551 | const char *name = cs[i]->name; | 3550 | cs[i]->name, cs[i]->index, i ? ' ':'\n'); |
3552 | int index = cs[i]->index; | ||
3553 | |||
3554 | driver = cs[i]->device(cs[i], &index); | ||
3555 | if (driver) { | ||
3556 | count += tty_line_name(driver, index, buf + count); | ||
3557 | count += sprintf(buf + count, "%c", i ? ' ':'\n'); | ||
3558 | } else | ||
3559 | count += sprintf(buf + count, "%s%d%c", | ||
3560 | name, index, i ? ' ':'\n'); | ||
3561 | } | ||
3562 | console_unlock(); | 3551 | console_unlock(); |
3563 | 3552 | ||
3564 | return count; | 3553 | return count; |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 80de2f88ed2c..4ab2cb62dfce 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -105,7 +105,7 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) | |||
105 | 105 | ||
106 | do { | 106 | do { |
107 | /* flush any pending transfer */ | 107 | /* flush any pending transfer */ |
108 | hw_write(ci, OP_ENDPTFLUSH, BIT(n), BIT(n)); | 108 | hw_write(ci, OP_ENDPTFLUSH, ~0, BIT(n)); |
109 | while (hw_read(ci, OP_ENDPTFLUSH, BIT(n))) | 109 | while (hw_read(ci, OP_ENDPTFLUSH, BIT(n))) |
110 | cpu_relax(); | 110 | cpu_relax(); |
111 | } while (hw_read(ci, OP_ENDPTSTAT, BIT(n))); | 111 | } while (hw_read(ci, OP_ENDPTSTAT, BIT(n))); |
@@ -205,7 +205,7 @@ static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl) | |||
205 | if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num))) | 205 | if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num))) |
206 | return -EAGAIN; | 206 | return -EAGAIN; |
207 | 207 | ||
208 | hw_write(ci, OP_ENDPTPRIME, BIT(n), BIT(n)); | 208 | hw_write(ci, OP_ENDPTPRIME, ~0, BIT(n)); |
209 | 209 | ||
210 | while (hw_read(ci, OP_ENDPTPRIME, BIT(n))) | 210 | while (hw_read(ci, OP_ENDPTPRIME, BIT(n))) |
211 | cpu_relax(); | 211 | cpu_relax(); |
diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 888fbb43b338..e969eb809a85 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c | |||
@@ -360,24 +360,30 @@ static inline void usb_dma_writel(struct bcm63xx_udc *udc, u32 val, u32 off) | |||
360 | bcm_writel(val, udc->iudma_regs + off); | 360 | bcm_writel(val, udc->iudma_regs + off); |
361 | } | 361 | } |
362 | 362 | ||
363 | static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off) | 363 | static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off, int chan) |
364 | { | 364 | { |
365 | return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off); | 365 | return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off + |
366 | (ENETDMA_CHAN_WIDTH * chan)); | ||
366 | } | 367 | } |
367 | 368 | ||
368 | static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off) | 369 | static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off, |
370 | int chan) | ||
369 | { | 371 | { |
370 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off); | 372 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off + |
373 | (ENETDMA_CHAN_WIDTH * chan)); | ||
371 | } | 374 | } |
372 | 375 | ||
373 | static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off) | 376 | static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off, int chan) |
374 | { | 377 | { |
375 | return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off); | 378 | return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off + |
379 | (ENETDMA_CHAN_WIDTH * chan)); | ||
376 | } | 380 | } |
377 | 381 | ||
378 | static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off) | 382 | static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off, |
383 | int chan) | ||
379 | { | 384 | { |
380 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off); | 385 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off + |
386 | (ENETDMA_CHAN_WIDTH * chan)); | ||
381 | } | 387 | } |
382 | 388 | ||
383 | static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled) | 389 | static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled) |
@@ -638,7 +644,7 @@ static void iudma_write(struct bcm63xx_udc *udc, struct iudma_ch *iudma, | |||
638 | } while (!last_bd); | 644 | } while (!last_bd); |
639 | 645 | ||
640 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK, | 646 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK, |
641 | ENETDMAC_CHANCFG_REG(iudma->ch_idx)); | 647 | ENETDMAC_CHANCFG_REG, iudma->ch_idx); |
642 | } | 648 | } |
643 | 649 | ||
644 | /** | 650 | /** |
@@ -694,9 +700,9 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) | |||
694 | bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num)); | 700 | bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num)); |
695 | 701 | ||
696 | /* stop DMA, then wait for the hardware to wrap up */ | 702 | /* stop DMA, then wait for the hardware to wrap up */ |
697 | usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG(ch_idx)); | 703 | usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG, ch_idx); |
698 | 704 | ||
699 | while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)) & | 705 | while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx) & |
700 | ENETDMAC_CHANCFG_EN_MASK) { | 706 | ENETDMAC_CHANCFG_EN_MASK) { |
701 | udelay(1); | 707 | udelay(1); |
702 | 708 | ||
@@ -713,10 +719,10 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) | |||
713 | dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n", | 719 | dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n", |
714 | ch_idx); | 720 | ch_idx); |
715 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK, | 721 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK, |
716 | ENETDMAC_CHANCFG_REG(ch_idx)); | 722 | ENETDMAC_CHANCFG_REG, ch_idx); |
717 | } | 723 | } |
718 | } | 724 | } |
719 | usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG(ch_idx)); | 725 | usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG, ch_idx); |
720 | 726 | ||
721 | /* don't leave "live" HW-owned entries for the next guy to step on */ | 727 | /* don't leave "live" HW-owned entries for the next guy to step on */ |
722 | for (d = iudma->bd_ring; d <= iudma->end_bd; d++) | 728 | for (d = iudma->bd_ring; d <= iudma->end_bd; d++) |
@@ -728,11 +734,11 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) | |||
728 | 734 | ||
729 | /* set up IRQs, UBUS burst size, and BD base for this channel */ | 735 | /* set up IRQs, UBUS burst size, and BD base for this channel */ |
730 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, | 736 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, |
731 | ENETDMAC_IRMASK_REG(ch_idx)); | 737 | ENETDMAC_IRMASK_REG, ch_idx); |
732 | usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG(ch_idx)); | 738 | usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG, ch_idx); |
733 | 739 | ||
734 | usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG(ch_idx)); | 740 | usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG, ch_idx); |
735 | usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG(ch_idx)); | 741 | usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG, ch_idx); |
736 | } | 742 | } |
737 | 743 | ||
738 | /** | 744 | /** |
@@ -2035,7 +2041,7 @@ static irqreturn_t bcm63xx_udc_data_isr(int irq, void *dev_id) | |||
2035 | spin_lock(&udc->lock); | 2041 | spin_lock(&udc->lock); |
2036 | 2042 | ||
2037 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, | 2043 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, |
2038 | ENETDMAC_IR_REG(iudma->ch_idx)); | 2044 | ENETDMAC_IR_REG, iudma->ch_idx); |
2039 | bep = iudma->bep; | 2045 | bep = iudma->bep; |
2040 | rc = iudma_read(udc, iudma); | 2046 | rc = iudma_read(udc, iudma); |
2041 | 2047 | ||
@@ -2175,18 +2181,18 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) | |||
2175 | seq_printf(s, " [ep%d]:\n", | 2181 | seq_printf(s, " [ep%d]:\n", |
2176 | max_t(int, iudma_defaults[ch_idx].ep_num, 0)); | 2182 | max_t(int, iudma_defaults[ch_idx].ep_num, 0)); |
2177 | seq_printf(s, " cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n", | 2183 | seq_printf(s, " cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n", |
2178 | usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)), | 2184 | usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx), |
2179 | usb_dmac_readl(udc, ENETDMAC_IR_REG(ch_idx)), | 2185 | usb_dmac_readl(udc, ENETDMAC_IR_REG, ch_idx), |
2180 | usb_dmac_readl(udc, ENETDMAC_IRMASK_REG(ch_idx)), | 2186 | usb_dmac_readl(udc, ENETDMAC_IRMASK_REG, ch_idx), |
2181 | usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG(ch_idx))); | 2187 | usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG, ch_idx)); |
2182 | 2188 | ||
2183 | sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG(ch_idx)); | 2189 | sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG, ch_idx); |
2184 | sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG(ch_idx)); | 2190 | sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG, ch_idx); |
2185 | seq_printf(s, " base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n", | 2191 | seq_printf(s, " base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n", |
2186 | usb_dmas_readl(udc, ENETDMAS_RSTART_REG(ch_idx)), | 2192 | usb_dmas_readl(udc, ENETDMAS_RSTART_REG, ch_idx), |
2187 | sram2 >> 16, sram2 & 0xffff, | 2193 | sram2 >> 16, sram2 & 0xffff, |
2188 | sram3 >> 16, sram3 & 0xffff, | 2194 | sram3 >> 16, sram3 & 0xffff, |
2189 | usb_dmas_readl(udc, ENETDMAS_SRAM4_REG(ch_idx))); | 2195 | usb_dmas_readl(udc, ENETDMAS_SRAM4_REG, ch_idx)); |
2190 | seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, | 2196 | seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, |
2191 | iudma->n_bds); | 2197 | iudma->n_bds); |
2192 | 2198 | ||
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 306a2b52125c..2b4334394076 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -585,7 +585,6 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
585 | char __user *buf, size_t len, int read) | 585 | char __user *buf, size_t len, int read) |
586 | { | 586 | { |
587 | struct ffs_epfile *epfile = file->private_data; | 587 | struct ffs_epfile *epfile = file->private_data; |
588 | struct usb_gadget *gadget = epfile->ffs->gadget; | ||
589 | struct ffs_ep *ep; | 588 | struct ffs_ep *ep; |
590 | char *data = NULL; | 589 | char *data = NULL; |
591 | ssize_t ret, data_len; | 590 | ssize_t ret, data_len; |
@@ -622,6 +621,12 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
622 | /* Allocate & copy */ | 621 | /* Allocate & copy */ |
623 | if (!halt) { | 622 | if (!halt) { |
624 | /* | 623 | /* |
624 | * if we _do_ wait above, the epfile->ffs->gadget might be NULL | ||
625 | * before the waiting completes, so do not assign to 'gadget' earlier | ||
626 | */ | ||
627 | struct usb_gadget *gadget = epfile->ffs->gadget; | ||
628 | |||
629 | /* | ||
625 | * Controller may require buffer size to be aligned to | 630 | * Controller may require buffer size to be aligned to |
626 | * maxpacketsize of an out endpoint. | 631 | * maxpacketsize of an out endpoint. |
627 | */ | 632 | */ |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index bf7a56b6d48a..69b76efd11e9 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -1157,7 +1157,7 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1157 | 1157 | ||
1158 | usb_gadget_set_selfpowered(gadget); | 1158 | usb_gadget_set_selfpowered(gadget); |
1159 | 1159 | ||
1160 | if (gadget->is_otg) { | 1160 | if (gadget_is_otg(gadget)) { |
1161 | otg_descriptor.bmAttributes |= USB_OTG_HNP; | 1161 | otg_descriptor.bmAttributes |= USB_OTG_HNP; |
1162 | printer_cfg_driver.descriptors = otg_desc; | 1162 | printer_cfg_driver.descriptors = otg_desc; |
1163 | printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1163 | printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index f04b2c3154de..dd9678f85c58 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -1629,7 +1629,7 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev) | |||
1629 | ep->ep.desc = NULL; | 1629 | ep->ep.desc = NULL; |
1630 | ep->halted = 0; | 1630 | ep->halted = 0; |
1631 | INIT_LIST_HEAD(&ep->queue); | 1631 | INIT_LIST_HEAD(&ep->queue); |
1632 | usb_ep_set_maxpacket_limit(&ep->ep, &ep->ep.maxpacket); | 1632 | usb_ep_set_maxpacket_limit(&ep->ep, ep->ep.maxpacket); |
1633 | } | 1633 | } |
1634 | } | 1634 | } |
1635 | 1635 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 471142725ffe..81cda09b47e3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -685,8 +685,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
685 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 685 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
686 | u32 status, masked_status, pcd_status = 0, cmd; | 686 | u32 status, masked_status, pcd_status = 0, cmd; |
687 | int bh; | 687 | int bh; |
688 | unsigned long flags; | ||
688 | 689 | ||
689 | spin_lock (&ehci->lock); | 690 | /* |
691 | * For threadirqs option we use spin_lock_irqsave() variant to prevent | ||
692 | * deadlock with ehci hrtimer callback, because hrtimer callbacks run | ||
693 | * in interrupt context even when threadirqs is specified. We can go | ||
694 | * back to spin_lock() variant when hrtimer callbacks become threaded. | ||
695 | */ | ||
696 | spin_lock_irqsave(&ehci->lock, flags); | ||
690 | 697 | ||
691 | status = ehci_readl(ehci, &ehci->regs->status); | 698 | status = ehci_readl(ehci, &ehci->regs->status); |
692 | 699 | ||
@@ -704,7 +711,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
704 | 711 | ||
705 | /* Shared IRQ? */ | 712 | /* Shared IRQ? */ |
706 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { | 713 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { |
707 | spin_unlock(&ehci->lock); | 714 | spin_unlock_irqrestore(&ehci->lock, flags); |
708 | return IRQ_NONE; | 715 | return IRQ_NONE; |
709 | } | 716 | } |
710 | 717 | ||
@@ -815,7 +822,7 @@ dead: | |||
815 | 822 | ||
816 | if (bh) | 823 | if (bh) |
817 | ehci_work (ehci); | 824 | ehci_work (ehci); |
818 | spin_unlock (&ehci->lock); | 825 | spin_unlock_irqrestore(&ehci->lock, flags); |
819 | if (pcd_status) | 826 | if (pcd_status) |
820 | usb_hcd_poll_rh_status(hcd); | 827 | usb_hcd_poll_rh_status(hcd); |
821 | return IRQ_HANDLED; | 828 | return IRQ_HANDLED; |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 47b858fc50b2..7ae0c4d51741 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -238,6 +238,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
238 | int port; | 238 | int port; |
239 | int mask; | 239 | int mask; |
240 | int changed; | 240 | int changed; |
241 | bool fs_idle_delay; | ||
241 | 242 | ||
242 | ehci_dbg(ehci, "suspend root hub\n"); | 243 | ehci_dbg(ehci, "suspend root hub\n"); |
243 | 244 | ||
@@ -272,6 +273,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
272 | ehci->bus_suspended = 0; | 273 | ehci->bus_suspended = 0; |
273 | ehci->owned_ports = 0; | 274 | ehci->owned_ports = 0; |
274 | changed = 0; | 275 | changed = 0; |
276 | fs_idle_delay = false; | ||
275 | port = HCS_N_PORTS(ehci->hcs_params); | 277 | port = HCS_N_PORTS(ehci->hcs_params); |
276 | while (port--) { | 278 | while (port--) { |
277 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 279 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
@@ -300,16 +302,32 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
300 | } | 302 | } |
301 | 303 | ||
302 | if (t1 != t2) { | 304 | if (t1 != t2) { |
305 | /* | ||
306 | * On some controllers, Wake-On-Disconnect will | ||
307 | * generate false wakeup signals until the bus | ||
308 | * switches over to full-speed idle. For their | ||
309 | * sake, add a delay if we need one. | ||
310 | */ | ||
311 | if ((t2 & PORT_WKDISC_E) && | ||
312 | ehci_port_speed(ehci, t2) == | ||
313 | USB_PORT_STAT_HIGH_SPEED) | ||
314 | fs_idle_delay = true; | ||
303 | ehci_writel(ehci, t2, reg); | 315 | ehci_writel(ehci, t2, reg); |
304 | changed = 1; | 316 | changed = 1; |
305 | } | 317 | } |
306 | } | 318 | } |
319 | spin_unlock_irq(&ehci->lock); | ||
320 | |||
321 | if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) { | ||
322 | /* | ||
323 | * Wait for HCD to enter low-power mode or for the bus | ||
324 | * to switch to full-speed idle. | ||
325 | */ | ||
326 | usleep_range(5000, 5500); | ||
327 | } | ||
307 | 328 | ||
308 | if (changed && ehci->has_tdi_phy_lpm) { | 329 | if (changed && ehci->has_tdi_phy_lpm) { |
309 | spin_unlock_irq(&ehci->lock); | ||
310 | msleep(5); /* 5 ms for HCD to enter low-power mode */ | ||
311 | spin_lock_irq(&ehci->lock); | 330 | spin_lock_irq(&ehci->lock); |
312 | |||
313 | port = HCS_N_PORTS(ehci->hcs_params); | 331 | port = HCS_N_PORTS(ehci->hcs_params); |
314 | while (port--) { | 332 | while (port--) { |
315 | u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; | 333 | u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; |
@@ -322,8 +340,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
322 | port, (t3 & HOSTPC_PHCD) ? | 340 | port, (t3 & HOSTPC_PHCD) ? |
323 | "succeeded" : "failed"); | 341 | "succeeded" : "failed"); |
324 | } | 342 | } |
343 | spin_unlock_irq(&ehci->lock); | ||
325 | } | 344 | } |
326 | spin_unlock_irq(&ehci->lock); | ||
327 | 345 | ||
328 | /* Apparently some devices need a >= 1-uframe delay here */ | 346 | /* Apparently some devices need a >= 1-uframe delay here */ |
329 | if (ehci->bus_suspended) | 347 | if (ehci->bus_suspended) |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fc192ad9cc6a..239ad0b1ceb6 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -477,8 +477,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
477 | musb->port1_status |= | 477 | musb->port1_status |= |
478 | (USB_PORT_STAT_C_SUSPEND << 16) | 478 | (USB_PORT_STAT_C_SUSPEND << 16) |
479 | | MUSB_PORT_STAT_RESUME; | 479 | | MUSB_PORT_STAT_RESUME; |
480 | musb->rh_timer = jiffies | ||
481 | + msecs_to_jiffies(20); | ||
480 | schedule_delayed_work( | 482 | schedule_delayed_work( |
481 | &musb->finish_resume_work, 20); | 483 | &musb->finish_resume_work, |
484 | msecs_to_jiffies(20)); | ||
482 | 485 | ||
483 | musb->xceiv->state = OTG_STATE_A_HOST; | 486 | musb->xceiv->state = OTG_STATE_A_HOST; |
484 | musb->is_active = 1; | 487 | musb->is_active = 1; |
@@ -2157,11 +2160,19 @@ static void musb_restore_context(struct musb *musb) | |||
2157 | void __iomem *musb_base = musb->mregs; | 2160 | void __iomem *musb_base = musb->mregs; |
2158 | void __iomem *ep_target_regs; | 2161 | void __iomem *ep_target_regs; |
2159 | void __iomem *epio; | 2162 | void __iomem *epio; |
2163 | u8 power; | ||
2160 | 2164 | ||
2161 | musb_writew(musb_base, MUSB_FRAME, musb->context.frame); | 2165 | musb_writew(musb_base, MUSB_FRAME, musb->context.frame); |
2162 | musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); | 2166 | musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); |
2163 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); | 2167 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); |
2164 | musb_writeb(musb_base, MUSB_POWER, musb->context.power); | 2168 | |
2169 | /* Don't affect SUSPENDM/RESUME bits in POWER reg */ | ||
2170 | power = musb_readb(musb_base, MUSB_POWER); | ||
2171 | power &= MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME; | ||
2172 | musb->context.power &= ~(MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME); | ||
2173 | power |= musb->context.power; | ||
2174 | musb_writeb(musb_base, MUSB_POWER, power); | ||
2175 | |||
2165 | musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); | 2176 | musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); |
2166 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); | 2177 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); |
2167 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); | 2178 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ed455724017b..abb38c3833ef 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -1183,6 +1183,9 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
1183 | csr = MUSB_CSR0_H_STATUSPKT | 1183 | csr = MUSB_CSR0_H_STATUSPKT |
1184 | | MUSB_CSR0_TXPKTRDY; | 1184 | | MUSB_CSR0_TXPKTRDY; |
1185 | 1185 | ||
1186 | /* disable ping token in status phase */ | ||
1187 | csr |= MUSB_CSR0_H_DIS_PING; | ||
1188 | |||
1186 | /* flag status stage */ | 1189 | /* flag status stage */ |
1187 | musb->ep0_stage = MUSB_EP0_STATUS; | 1190 | musb->ep0_stage = MUSB_EP0_STATUS; |
1188 | 1191 | ||
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index eb634433ef09..e2d2d8c9891b 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -135,7 +135,8 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) | |||
135 | 135 | ||
136 | /* later, GetPortStatus will stop RESUME signaling */ | 136 | /* later, GetPortStatus will stop RESUME signaling */ |
137 | musb->port1_status |= MUSB_PORT_STAT_RESUME; | 137 | musb->port1_status |= MUSB_PORT_STAT_RESUME; |
138 | schedule_delayed_work(&musb->finish_resume_work, 20); | 138 | schedule_delayed_work(&musb->finish_resume_work, |
139 | msecs_to_jiffies(20)); | ||
139 | } | 140 | } |
140 | } | 141 | } |
141 | 142 | ||
@@ -158,7 +159,6 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
158 | */ | 159 | */ |
159 | power = musb_readb(mbase, MUSB_POWER); | 160 | power = musb_readb(mbase, MUSB_POWER); |
160 | if (do_reset) { | 161 | if (do_reset) { |
161 | |||
162 | /* | 162 | /* |
163 | * If RESUME is set, we must make sure it stays minimum 20 ms. | 163 | * If RESUME is set, we must make sure it stays minimum 20 ms. |
164 | * Then we must clear RESUME and wait a bit to let musb start | 164 | * Then we must clear RESUME and wait a bit to let musb start |
@@ -167,11 +167,22 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
167 | * detected". | 167 | * detected". |
168 | */ | 168 | */ |
169 | if (power & MUSB_POWER_RESUME) { | 169 | if (power & MUSB_POWER_RESUME) { |
170 | while (time_before(jiffies, musb->rh_timer)) | 170 | long remain = (unsigned long) musb->rh_timer - jiffies; |
171 | msleep(1); | 171 | |
172 | if (musb->rh_timer > 0 && remain > 0) { | ||
173 | /* take into account the minimum delay after resume */ | ||
174 | schedule_delayed_work( | ||
175 | &musb->deassert_reset_work, remain); | ||
176 | return; | ||
177 | } | ||
178 | |||
172 | musb_writeb(mbase, MUSB_POWER, | 179 | musb_writeb(mbase, MUSB_POWER, |
173 | power & ~MUSB_POWER_RESUME); | 180 | power & ~MUSB_POWER_RESUME); |
174 | msleep(1); | 181 | |
182 | /* Give the core 1 ms to clear MUSB_POWER_RESUME */ | ||
183 | schedule_delayed_work(&musb->deassert_reset_work, | ||
184 | msecs_to_jiffies(1)); | ||
185 | return; | ||
175 | } | 186 | } |
176 | 187 | ||
177 | power &= 0xf0; | 188 | power &= 0xf0; |
@@ -180,7 +191,8 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
180 | 191 | ||
181 | musb->port1_status |= USB_PORT_STAT_RESET; | 192 | musb->port1_status |= USB_PORT_STAT_RESET; |
182 | musb->port1_status &= ~USB_PORT_STAT_ENABLE; | 193 | musb->port1_status &= ~USB_PORT_STAT_ENABLE; |
183 | schedule_delayed_work(&musb->deassert_reset_work, 50); | 194 | schedule_delayed_work(&musb->deassert_reset_work, |
195 | msecs_to_jiffies(50)); | ||
184 | } else { | 196 | } else { |
185 | dev_dbg(musb->controller, "root port reset stopped\n"); | 197 | dev_dbg(musb->controller, "root port reset stopped\n"); |
186 | musb_writeb(mbase, MUSB_POWER, | 198 | musb_writeb(mbase, MUSB_POWER, |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2a408cdaf7b2..8aa59a2c5eb2 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -659,7 +659,6 @@ static int omap2430_runtime_suspend(struct device *dev) | |||
659 | OTG_INTERFSEL); | 659 | OTG_INTERFSEL); |
660 | 660 | ||
661 | omap2430_low_level_exit(musb); | 661 | omap2430_low_level_exit(musb); |
662 | phy_power_off(musb->phy); | ||
663 | } | 662 | } |
664 | 663 | ||
665 | return 0; | 664 | return 0; |
@@ -674,7 +673,6 @@ static int omap2430_runtime_resume(struct device *dev) | |||
674 | omap2430_low_level_init(musb); | 673 | omap2430_low_level_init(musb); |
675 | musb_writel(musb->mregs, OTG_INTERFSEL, | 674 | musb_writel(musb->mregs, OTG_INTERFSEL, |
676 | musb->context.otg_interfsel); | 675 | musb->context.otg_interfsel); |
677 | phy_power_on(musb->phy); | ||
678 | } | 676 | } |
679 | 677 | ||
680 | return 0; | 678 | return 0; |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 8546c8dccd51..d204f745ed05 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -159,32 +159,6 @@ put_3p3: | |||
159 | return rc; | 159 | return rc; |
160 | } | 160 | } |
161 | 161 | ||
162 | #ifdef CONFIG_PM_SLEEP | ||
163 | #define USB_PHY_SUSP_DIG_VOL 500000 | ||
164 | static int msm_hsusb_config_vddcx(int high) | ||
165 | { | ||
166 | int max_vol = USB_PHY_VDD_DIG_VOL_MAX; | ||
167 | int min_vol; | ||
168 | int ret; | ||
169 | |||
170 | if (high) | ||
171 | min_vol = USB_PHY_VDD_DIG_VOL_MIN; | ||
172 | else | ||
173 | min_vol = USB_PHY_SUSP_DIG_VOL; | ||
174 | |||
175 | ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); | ||
176 | if (ret) { | ||
177 | pr_err("%s: unable to set the voltage for regulator " | ||
178 | "HSUSB_VDDCX\n", __func__); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | static int msm_hsusb_ldo_set_mode(int on) | 162 | static int msm_hsusb_ldo_set_mode(int on) |
189 | { | 163 | { |
190 | int ret = 0; | 164 | int ret = 0; |
@@ -440,7 +414,32 @@ static int msm_otg_reset(struct usb_phy *phy) | |||
440 | #define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) | 414 | #define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) |
441 | #define PHY_RESUME_TIMEOUT_USEC (100 * 1000) | 415 | #define PHY_RESUME_TIMEOUT_USEC (100 * 1000) |
442 | 416 | ||
443 | #ifdef CONFIG_PM_SLEEP | 417 | #ifdef CONFIG_PM |
418 | |||
419 | #define USB_PHY_SUSP_DIG_VOL 500000 | ||
420 | static int msm_hsusb_config_vddcx(int high) | ||
421 | { | ||
422 | int max_vol = USB_PHY_VDD_DIG_VOL_MAX; | ||
423 | int min_vol; | ||
424 | int ret; | ||
425 | |||
426 | if (high) | ||
427 | min_vol = USB_PHY_VDD_DIG_VOL_MIN; | ||
428 | else | ||
429 | min_vol = USB_PHY_SUSP_DIG_VOL; | ||
430 | |||
431 | ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); | ||
432 | if (ret) { | ||
433 | pr_err("%s: unable to set the voltage for regulator " | ||
434 | "HSUSB_VDDCX\n", __func__); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); | ||
439 | |||
440 | return ret; | ||
441 | } | ||
442 | |||
444 | static int msm_otg_suspend(struct msm_otg *motg) | 443 | static int msm_otg_suspend(struct msm_otg *motg) |
445 | { | 444 | { |
446 | struct usb_phy *phy = &motg->phy; | 445 | struct usb_phy *phy = &motg->phy; |
@@ -1733,22 +1732,18 @@ static int msm_otg_pm_resume(struct device *dev) | |||
1733 | } | 1732 | } |
1734 | #endif | 1733 | #endif |
1735 | 1734 | ||
1736 | #ifdef CONFIG_PM | ||
1737 | static const struct dev_pm_ops msm_otg_dev_pm_ops = { | 1735 | static const struct dev_pm_ops msm_otg_dev_pm_ops = { |
1738 | SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) | 1736 | SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) |
1739 | SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, | 1737 | SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, |
1740 | msm_otg_runtime_idle) | 1738 | msm_otg_runtime_idle) |
1741 | }; | 1739 | }; |
1742 | #endif | ||
1743 | 1740 | ||
1744 | static struct platform_driver msm_otg_driver = { | 1741 | static struct platform_driver msm_otg_driver = { |
1745 | .remove = msm_otg_remove, | 1742 | .remove = msm_otg_remove, |
1746 | .driver = { | 1743 | .driver = { |
1747 | .name = DRIVER_NAME, | 1744 | .name = DRIVER_NAME, |
1748 | .owner = THIS_MODULE, | 1745 | .owner = THIS_MODULE, |
1749 | #ifdef CONFIG_PM | ||
1750 | .pm = &msm_otg_dev_pm_ops, | 1746 | .pm = &msm_otg_dev_pm_ops, |
1751 | #endif | ||
1752 | }, | 1747 | }, |
1753 | }; | 1748 | }; |
1754 | 1749 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ee1f00f03c43..44ab12986805 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -907,6 +907,8 @@ static const struct usb_device_id id_table_combined[] = { | |||
907 | /* Crucible Devices */ | 907 | /* Crucible Devices */ |
908 | { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, | 908 | { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, |
909 | { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, | 909 | { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, |
910 | /* Cressi Devices */ | ||
911 | { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) }, | ||
910 | { } /* Terminating entry */ | 912 | { } /* Terminating entry */ |
911 | }; | 913 | }; |
912 | 914 | ||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 1e2d369df86e..e599fbfcde5f 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -1320,3 +1320,9 @@ | |||
1320 | * Manufacturer: Smart GSM Team | 1320 | * Manufacturer: Smart GSM Team |
1321 | */ | 1321 | */ |
1322 | #define FTDI_Z3X_PID 0x0011 | 1322 | #define FTDI_Z3X_PID 0x0011 |
1323 | |||
1324 | /* | ||
1325 | * Product: Cressi PC Interface | ||
1326 | * Manufacturer: Cressi | ||
1327 | */ | ||
1328 | #define FTDI_CRESSI_PID 0x87d0 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 216d20affba8..68fc9fe65936 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -1526,7 +1526,8 @@ static const struct usb_device_id option_ids[] = { | |||
1526 | /* Cinterion */ | 1526 | /* Cinterion */ |
1527 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, | 1527 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, |
1528 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, | 1528 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, |
1529 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, | 1529 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), |
1530 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
1530 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, | 1531 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, |
1531 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), | 1532 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), |
1532 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1533 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 9a68409580d5..a0fa5de210cf 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -70,7 +70,12 @@ enum { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct vhost_net_ubuf_ref { | 72 | struct vhost_net_ubuf_ref { |
73 | struct kref kref; | 73 | /* refcount follows semantics similar to kref: |
74 | * 0: object is released | ||
75 | * 1: no outstanding ubufs | ||
76 | * >1: outstanding ubufs | ||
77 | */ | ||
78 | atomic_t refcount; | ||
74 | wait_queue_head_t wait; | 79 | wait_queue_head_t wait; |
75 | struct vhost_virtqueue *vq; | 80 | struct vhost_virtqueue *vq; |
76 | }; | 81 | }; |
@@ -116,14 +121,6 @@ static void vhost_net_enable_zcopy(int vq) | |||
116 | vhost_net_zcopy_mask |= 0x1 << vq; | 121 | vhost_net_zcopy_mask |= 0x1 << vq; |
117 | } | 122 | } |
118 | 123 | ||
119 | static void vhost_net_zerocopy_done_signal(struct kref *kref) | ||
120 | { | ||
121 | struct vhost_net_ubuf_ref *ubufs; | ||
122 | |||
123 | ubufs = container_of(kref, struct vhost_net_ubuf_ref, kref); | ||
124 | wake_up(&ubufs->wait); | ||
125 | } | ||
126 | |||
127 | static struct vhost_net_ubuf_ref * | 124 | static struct vhost_net_ubuf_ref * |
128 | vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) | 125 | vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) |
129 | { | 126 | { |
@@ -134,21 +131,24 @@ vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) | |||
134 | ubufs = kmalloc(sizeof(*ubufs), GFP_KERNEL); | 131 | ubufs = kmalloc(sizeof(*ubufs), GFP_KERNEL); |
135 | if (!ubufs) | 132 | if (!ubufs) |
136 | return ERR_PTR(-ENOMEM); | 133 | return ERR_PTR(-ENOMEM); |
137 | kref_init(&ubufs->kref); | 134 | atomic_set(&ubufs->refcount, 1); |
138 | init_waitqueue_head(&ubufs->wait); | 135 | init_waitqueue_head(&ubufs->wait); |
139 | ubufs->vq = vq; | 136 | ubufs->vq = vq; |
140 | return ubufs; | 137 | return ubufs; |
141 | } | 138 | } |
142 | 139 | ||
143 | static void vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs) | 140 | static int vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs) |
144 | { | 141 | { |
145 | kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal); | 142 | int r = atomic_sub_return(1, &ubufs->refcount); |
143 | if (unlikely(!r)) | ||
144 | wake_up(&ubufs->wait); | ||
145 | return r; | ||
146 | } | 146 | } |
147 | 147 | ||
148 | static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs) | 148 | static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs) |
149 | { | 149 | { |
150 | kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal); | 150 | vhost_net_ubuf_put(ubufs); |
151 | wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount)); | 151 | wait_event(ubufs->wait, !atomic_read(&ubufs->refcount)); |
152 | } | 152 | } |
153 | 153 | ||
154 | static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs) | 154 | static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs) |
@@ -306,23 +306,26 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) | |||
306 | { | 306 | { |
307 | struct vhost_net_ubuf_ref *ubufs = ubuf->ctx; | 307 | struct vhost_net_ubuf_ref *ubufs = ubuf->ctx; |
308 | struct vhost_virtqueue *vq = ubufs->vq; | 308 | struct vhost_virtqueue *vq = ubufs->vq; |
309 | int cnt = atomic_read(&ubufs->kref.refcount); | 309 | int cnt; |
310 | |||
311 | rcu_read_lock_bh(); | ||
310 | 312 | ||
311 | /* set len to mark this desc buffers done DMA */ | 313 | /* set len to mark this desc buffers done DMA */ |
312 | vq->heads[ubuf->desc].len = success ? | 314 | vq->heads[ubuf->desc].len = success ? |
313 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; | 315 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; |
314 | vhost_net_ubuf_put(ubufs); | 316 | cnt = vhost_net_ubuf_put(ubufs); |
315 | 317 | ||
316 | /* | 318 | /* |
317 | * Trigger polling thread if guest stopped submitting new buffers: | 319 | * Trigger polling thread if guest stopped submitting new buffers: |
318 | * in this case, the refcount after decrement will eventually reach 1 | 320 | * in this case, the refcount after decrement will eventually reach 1. |
319 | * so here it is 2. | ||
320 | * We also trigger polling periodically after each 16 packets | 321 | * We also trigger polling periodically after each 16 packets |
321 | * (the value 16 here is more or less arbitrary, it's tuned to trigger | 322 | * (the value 16 here is more or less arbitrary, it's tuned to trigger |
322 | * less than 10% of times). | 323 | * less than 10% of times). |
323 | */ | 324 | */ |
324 | if (cnt <= 2 || !(cnt % 16)) | 325 | if (cnt <= 1 || !(cnt % 16)) |
325 | vhost_poll_queue(&vq->poll); | 326 | vhost_poll_queue(&vq->poll); |
327 | |||
328 | rcu_read_unlock_bh(); | ||
326 | } | 329 | } |
327 | 330 | ||
328 | /* Expects to be always run from workqueue - which acts as | 331 | /* Expects to be always run from workqueue - which acts as |
@@ -420,7 +423,7 @@ static void handle_tx(struct vhost_net *net) | |||
420 | msg.msg_control = ubuf; | 423 | msg.msg_control = ubuf; |
421 | msg.msg_controllen = sizeof(ubuf); | 424 | msg.msg_controllen = sizeof(ubuf); |
422 | ubufs = nvq->ubufs; | 425 | ubufs = nvq->ubufs; |
423 | kref_get(&ubufs->kref); | 426 | atomic_inc(&ubufs->refcount); |
424 | nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV; | 427 | nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV; |
425 | } else { | 428 | } else { |
426 | msg.msg_control = NULL; | 429 | msg.msg_control = NULL; |
@@ -780,7 +783,7 @@ static void vhost_net_flush(struct vhost_net *n) | |||
780 | vhost_net_ubuf_put_and_wait(n->vqs[VHOST_NET_VQ_TX].ubufs); | 783 | vhost_net_ubuf_put_and_wait(n->vqs[VHOST_NET_VQ_TX].ubufs); |
781 | mutex_lock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); | 784 | mutex_lock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); |
782 | n->tx_flush = false; | 785 | n->tx_flush = false; |
783 | kref_init(&n->vqs[VHOST_NET_VQ_TX].ubufs->kref); | 786 | atomic_set(&n->vqs[VHOST_NET_VQ_TX].ubufs->refcount, 1); |
784 | mutex_unlock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); | 787 | mutex_unlock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); |
785 | } | 788 | } |
786 | } | 789 | } |
@@ -800,6 +803,8 @@ static int vhost_net_release(struct inode *inode, struct file *f) | |||
800 | fput(tx_sock->file); | 803 | fput(tx_sock->file); |
801 | if (rx_sock) | 804 | if (rx_sock) |
802 | fput(rx_sock->file); | 805 | fput(rx_sock->file); |
806 | /* Make sure no callbacks are outstanding */ | ||
807 | synchronize_rcu_bh(); | ||
803 | /* We do an extra flush before freeing memory, | 808 | /* We do an extra flush before freeing memory, |
804 | * since jobs can re-queue themselves. */ | 809 | * since jobs can re-queue themselves. */ |
805 | vhost_net_flush(n); | 810 | vhost_net_flush(n); |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 0a025b8e2a12..e48d4a672580 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -1001,6 +1001,12 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) | |||
1001 | break; | 1001 | break; |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ | ||
1005 | if (unlikely(v_req.lun[0] != 1)) { | ||
1006 | vhost_scsi_send_bad_target(vs, vq, head, out); | ||
1007 | continue; | ||
1008 | } | ||
1009 | |||
1004 | /* Extract the tpgt */ | 1010 | /* Extract the tpgt */ |
1005 | target = v_req.lun[1]; | 1011 | target = v_req.lun[1]; |
1006 | tpg = ACCESS_ONCE(vs_tpg[target]); | 1012 | tpg = ACCESS_ONCE(vs_tpg[target]); |
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index aaf2995d37f4..68b45fc9ba6a 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c | |||
@@ -402,7 +402,7 @@ static int __init wdt_init(void) | |||
402 | 402 | ||
403 | if (!found) { | 403 | if (!found) { |
404 | pr_err("No W83697HF/HG could be found\n"); | 404 | pr_err("No W83697HF/HG could be found\n"); |
405 | ret = -EIO; | 405 | ret = -ENODEV; |
406 | goto out; | 406 | goto out; |
407 | } | 407 | } |
408 | 408 | ||
diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c index 4c2d452c4bfc..21887d63dad5 100644 --- a/fs/ceph/acl.c +++ b/fs/ceph/acl.c | |||
@@ -54,11 +54,6 @@ static inline struct posix_acl *ceph_get_cached_acl(struct inode *inode, | |||
54 | return acl; | 54 | return acl; |
55 | } | 55 | } |
56 | 56 | ||
57 | void ceph_forget_all_cached_acls(struct inode *inode) | ||
58 | { | ||
59 | forget_all_cached_acls(inode); | ||
60 | } | ||
61 | |||
62 | struct posix_acl *ceph_get_acl(struct inode *inode, int type) | 57 | struct posix_acl *ceph_get_acl(struct inode *inode, int type) |
63 | { | 58 | { |
64 | int size; | 59 | int size; |
@@ -160,11 +155,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) | |||
160 | goto out_dput; | 155 | goto out_dput; |
161 | } | 156 | } |
162 | 157 | ||
163 | if (value) | 158 | ret = __ceph_setxattr(dentry, name, value, size, 0); |
164 | ret = __ceph_setxattr(dentry, name, value, size, 0); | ||
165 | else | ||
166 | ret = __ceph_removexattr(dentry, name); | ||
167 | |||
168 | if (ret) { | 159 | if (ret) { |
169 | if (new_mode != old_mode) { | 160 | if (new_mode != old_mode) { |
170 | newattrs.ia_mode = old_mode; | 161 | newattrs.ia_mode = old_mode; |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 6da4df84ba30..45eda6d7a40c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -100,6 +100,14 @@ static unsigned fpos_off(loff_t p) | |||
100 | return p & 0xffffffff; | 100 | return p & 0xffffffff; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int fpos_cmp(loff_t l, loff_t r) | ||
104 | { | ||
105 | int v = ceph_frag_compare(fpos_frag(l), fpos_frag(r)); | ||
106 | if (v) | ||
107 | return v; | ||
108 | return (int)(fpos_off(l) - fpos_off(r)); | ||
109 | } | ||
110 | |||
103 | /* | 111 | /* |
104 | * When possible, we try to satisfy a readdir by peeking at the | 112 | * When possible, we try to satisfy a readdir by peeking at the |
105 | * dcache. We make this work by carefully ordering dentries on | 113 | * dcache. We make this work by carefully ordering dentries on |
@@ -156,7 +164,7 @@ more: | |||
156 | if (!d_unhashed(dentry) && dentry->d_inode && | 164 | if (!d_unhashed(dentry) && dentry->d_inode && |
157 | ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && | 165 | ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && |
158 | ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && | 166 | ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && |
159 | ctx->pos <= di->offset) | 167 | fpos_cmp(ctx->pos, di->offset) <= 0) |
160 | break; | 168 | break; |
161 | dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, | 169 | dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, |
162 | dentry->d_name.len, dentry->d_name.name, di->offset, | 170 | dentry->d_name.len, dentry->d_name.name, di->offset, |
@@ -695,9 +703,8 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry, | |||
695 | ceph_mdsc_put_request(req); | 703 | ceph_mdsc_put_request(req); |
696 | 704 | ||
697 | if (!err) | 705 | if (!err) |
698 | err = ceph_init_acl(dentry, dentry->d_inode, dir); | 706 | ceph_init_acl(dentry, dentry->d_inode, dir); |
699 | 707 | else | |
700 | if (err) | ||
701 | d_drop(dentry); | 708 | d_drop(dentry); |
702 | return err; | 709 | return err; |
703 | } | 710 | } |
@@ -735,7 +742,9 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry, | |||
735 | if (!err && !req->r_reply_info.head->is_dentry) | 742 | if (!err && !req->r_reply_info.head->is_dentry) |
736 | err = ceph_handle_notrace_create(dir, dentry); | 743 | err = ceph_handle_notrace_create(dir, dentry); |
737 | ceph_mdsc_put_request(req); | 744 | ceph_mdsc_put_request(req); |
738 | if (err) | 745 | if (!err) |
746 | ceph_init_acl(dentry, dentry->d_inode, dir); | ||
747 | else | ||
739 | d_drop(dentry); | 748 | d_drop(dentry); |
740 | return err; | 749 | return err; |
741 | } | 750 | } |
@@ -776,7 +785,9 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
776 | err = ceph_handle_notrace_create(dir, dentry); | 785 | err = ceph_handle_notrace_create(dir, dentry); |
777 | ceph_mdsc_put_request(req); | 786 | ceph_mdsc_put_request(req); |
778 | out: | 787 | out: |
779 | if (err < 0) | 788 | if (!err) |
789 | ceph_init_acl(dentry, dentry->d_inode, dir); | ||
790 | else | ||
780 | d_drop(dentry); | 791 | d_drop(dentry); |
781 | return err; | 792 | return err; |
782 | } | 793 | } |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index dfd2ce3419f8..09c7afe32e49 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -286,6 +286,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
286 | } else { | 286 | } else { |
287 | dout("atomic_open finish_open on dn %p\n", dn); | 287 | dout("atomic_open finish_open on dn %p\n", dn); |
288 | if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) { | 288 | if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) { |
289 | ceph_init_acl(dentry, dentry->d_inode, dir); | ||
289 | *opened |= FILE_CREATED; | 290 | *opened |= FILE_CREATED; |
290 | } | 291 | } |
291 | err = finish_open(file, dentry, ceph_open, opened); | 292 | err = finish_open(file, dentry, ceph_open, opened); |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 2df963f1cf5a..10a4ccbf38da 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -144,7 +144,11 @@ enum { | |||
144 | Opt_ino32, | 144 | Opt_ino32, |
145 | Opt_noino32, | 145 | Opt_noino32, |
146 | Opt_fscache, | 146 | Opt_fscache, |
147 | Opt_nofscache | 147 | Opt_nofscache, |
148 | #ifdef CONFIG_CEPH_FS_POSIX_ACL | ||
149 | Opt_acl, | ||
150 | #endif | ||
151 | Opt_noacl | ||
148 | }; | 152 | }; |
149 | 153 | ||
150 | static match_table_t fsopt_tokens = { | 154 | static match_table_t fsopt_tokens = { |
@@ -172,6 +176,10 @@ static match_table_t fsopt_tokens = { | |||
172 | {Opt_noino32, "noino32"}, | 176 | {Opt_noino32, "noino32"}, |
173 | {Opt_fscache, "fsc"}, | 177 | {Opt_fscache, "fsc"}, |
174 | {Opt_nofscache, "nofsc"}, | 178 | {Opt_nofscache, "nofsc"}, |
179 | #ifdef CONFIG_CEPH_FS_POSIX_ACL | ||
180 | {Opt_acl, "acl"}, | ||
181 | #endif | ||
182 | {Opt_noacl, "noacl"}, | ||
175 | {-1, NULL} | 183 | {-1, NULL} |
176 | }; | 184 | }; |
177 | 185 | ||
@@ -271,6 +279,14 @@ static int parse_fsopt_token(char *c, void *private) | |||
271 | case Opt_nofscache: | 279 | case Opt_nofscache: |
272 | fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE; | 280 | fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE; |
273 | break; | 281 | break; |
282 | #ifdef CONFIG_CEPH_FS_POSIX_ACL | ||
283 | case Opt_acl: | ||
284 | fsopt->sb_flags |= MS_POSIXACL; | ||
285 | break; | ||
286 | #endif | ||
287 | case Opt_noacl: | ||
288 | fsopt->sb_flags &= ~MS_POSIXACL; | ||
289 | break; | ||
274 | default: | 290 | default: |
275 | BUG_ON(token); | 291 | BUG_ON(token); |
276 | } | 292 | } |
@@ -438,6 +454,13 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) | |||
438 | else | 454 | else |
439 | seq_puts(m, ",nofsc"); | 455 | seq_puts(m, ",nofsc"); |
440 | 456 | ||
457 | #ifdef CONFIG_CEPH_FS_POSIX_ACL | ||
458 | if (fsopt->sb_flags & MS_POSIXACL) | ||
459 | seq_puts(m, ",acl"); | ||
460 | else | ||
461 | seq_puts(m, ",noacl"); | ||
462 | #endif | ||
463 | |||
441 | if (fsopt->wsize) | 464 | if (fsopt->wsize) |
442 | seq_printf(m, ",wsize=%d", fsopt->wsize); | 465 | seq_printf(m, ",wsize=%d", fsopt->wsize); |
443 | if (fsopt->rsize != CEPH_RSIZE_DEFAULT) | 466 | if (fsopt->rsize != CEPH_RSIZE_DEFAULT) |
@@ -819,9 +842,6 @@ static int ceph_set_super(struct super_block *s, void *data) | |||
819 | 842 | ||
820 | s->s_flags = fsc->mount_options->sb_flags; | 843 | s->s_flags = fsc->mount_options->sb_flags; |
821 | s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ | 844 | s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ |
822 | #ifdef CONFIG_CEPH_FS_POSIX_ACL | ||
823 | s->s_flags |= MS_POSIXACL; | ||
824 | #endif | ||
825 | 845 | ||
826 | s->s_xattr = ceph_xattr_handlers; | 846 | s->s_xattr = ceph_xattr_handlers; |
827 | s->s_fs_info = fsc; | 847 | s->s_fs_info = fsc; |
@@ -911,6 +931,10 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type, | |||
911 | struct ceph_options *opt = NULL; | 931 | struct ceph_options *opt = NULL; |
912 | 932 | ||
913 | dout("ceph_mount\n"); | 933 | dout("ceph_mount\n"); |
934 | |||
935 | #ifdef CONFIG_CEPH_FS_POSIX_ACL | ||
936 | flags |= MS_POSIXACL; | ||
937 | #endif | ||
914 | err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path); | 938 | err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path); |
915 | if (err < 0) { | 939 | if (err < 0) { |
916 | res = ERR_PTR(err); | 940 | res = ERR_PTR(err); |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 19793b56d0a7..d8801a95b685 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/wait.h> | 13 | #include <linux/wait.h> |
14 | #include <linux/writeback.h> | 14 | #include <linux/writeback.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/posix_acl.h> | ||
16 | 17 | ||
17 | #include <linux/ceph/libceph.h> | 18 | #include <linux/ceph/libceph.h> |
18 | 19 | ||
@@ -743,7 +744,11 @@ extern const struct xattr_handler *ceph_xattr_handlers[]; | |||
743 | struct posix_acl *ceph_get_acl(struct inode *, int); | 744 | struct posix_acl *ceph_get_acl(struct inode *, int); |
744 | int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type); | 745 | int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
745 | int ceph_init_acl(struct dentry *, struct inode *, struct inode *); | 746 | int ceph_init_acl(struct dentry *, struct inode *, struct inode *); |
746 | void ceph_forget_all_cached_acls(struct inode *inode); | 747 | |
748 | static inline void ceph_forget_all_cached_acls(struct inode *inode) | ||
749 | { | ||
750 | forget_all_cached_acls(inode); | ||
751 | } | ||
747 | 752 | ||
748 | #else | 753 | #else |
749 | 754 | ||
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 898b6565ad3e..a55ec37378c6 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -12,6 +12,9 @@ | |||
12 | #define XATTR_CEPH_PREFIX "ceph." | 12 | #define XATTR_CEPH_PREFIX "ceph." |
13 | #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1) | 13 | #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1) |
14 | 14 | ||
15 | static int __remove_xattr(struct ceph_inode_info *ci, | ||
16 | struct ceph_inode_xattr *xattr); | ||
17 | |||
15 | /* | 18 | /* |
16 | * List of handlers for synthetic system.* attributes. Other | 19 | * List of handlers for synthetic system.* attributes. Other |
17 | * attributes are handled directly. | 20 | * attributes are handled directly. |
@@ -319,8 +322,7 @@ static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode, | |||
319 | static int __set_xattr(struct ceph_inode_info *ci, | 322 | static int __set_xattr(struct ceph_inode_info *ci, |
320 | const char *name, int name_len, | 323 | const char *name, int name_len, |
321 | const char *val, int val_len, | 324 | const char *val, int val_len, |
322 | int dirty, | 325 | int flags, int update_xattr, |
323 | int should_free_name, int should_free_val, | ||
324 | struct ceph_inode_xattr **newxattr) | 326 | struct ceph_inode_xattr **newxattr) |
325 | { | 327 | { |
326 | struct rb_node **p; | 328 | struct rb_node **p; |
@@ -349,12 +351,31 @@ static int __set_xattr(struct ceph_inode_info *ci, | |||
349 | xattr = NULL; | 351 | xattr = NULL; |
350 | } | 352 | } |
351 | 353 | ||
354 | if (update_xattr) { | ||
355 | int err = 0; | ||
356 | if (xattr && (flags & XATTR_CREATE)) | ||
357 | err = -EEXIST; | ||
358 | else if (!xattr && (flags & XATTR_REPLACE)) | ||
359 | err = -ENODATA; | ||
360 | if (err) { | ||
361 | kfree(name); | ||
362 | kfree(val); | ||
363 | return err; | ||
364 | } | ||
365 | if (update_xattr < 0) { | ||
366 | if (xattr) | ||
367 | __remove_xattr(ci, xattr); | ||
368 | kfree(name); | ||
369 | return 0; | ||
370 | } | ||
371 | } | ||
372 | |||
352 | if (!xattr) { | 373 | if (!xattr) { |
353 | new = 1; | 374 | new = 1; |
354 | xattr = *newxattr; | 375 | xattr = *newxattr; |
355 | xattr->name = name; | 376 | xattr->name = name; |
356 | xattr->name_len = name_len; | 377 | xattr->name_len = name_len; |
357 | xattr->should_free_name = should_free_name; | 378 | xattr->should_free_name = update_xattr; |
358 | 379 | ||
359 | ci->i_xattrs.count++; | 380 | ci->i_xattrs.count++; |
360 | dout("__set_xattr count=%d\n", ci->i_xattrs.count); | 381 | dout("__set_xattr count=%d\n", ci->i_xattrs.count); |
@@ -364,7 +385,7 @@ static int __set_xattr(struct ceph_inode_info *ci, | |||
364 | if (xattr->should_free_val) | 385 | if (xattr->should_free_val) |
365 | kfree((void *)xattr->val); | 386 | kfree((void *)xattr->val); |
366 | 387 | ||
367 | if (should_free_name) { | 388 | if (update_xattr) { |
368 | kfree((void *)name); | 389 | kfree((void *)name); |
369 | name = xattr->name; | 390 | name = xattr->name; |
370 | } | 391 | } |
@@ -379,8 +400,8 @@ static int __set_xattr(struct ceph_inode_info *ci, | |||
379 | xattr->val = ""; | 400 | xattr->val = ""; |
380 | 401 | ||
381 | xattr->val_len = val_len; | 402 | xattr->val_len = val_len; |
382 | xattr->dirty = dirty; | 403 | xattr->dirty = update_xattr; |
383 | xattr->should_free_val = (val && should_free_val); | 404 | xattr->should_free_val = (val && update_xattr); |
384 | 405 | ||
385 | if (new) { | 406 | if (new) { |
386 | rb_link_node(&xattr->node, parent, p); | 407 | rb_link_node(&xattr->node, parent, p); |
@@ -442,7 +463,7 @@ static int __remove_xattr(struct ceph_inode_info *ci, | |||
442 | struct ceph_inode_xattr *xattr) | 463 | struct ceph_inode_xattr *xattr) |
443 | { | 464 | { |
444 | if (!xattr) | 465 | if (!xattr) |
445 | return -EOPNOTSUPP; | 466 | return -ENODATA; |
446 | 467 | ||
447 | rb_erase(&xattr->node, &ci->i_xattrs.index); | 468 | rb_erase(&xattr->node, &ci->i_xattrs.index); |
448 | 469 | ||
@@ -588,7 +609,7 @@ start: | |||
588 | p += len; | 609 | p += len; |
589 | 610 | ||
590 | err = __set_xattr(ci, name, namelen, val, len, | 611 | err = __set_xattr(ci, name, namelen, val, len, |
591 | 0, 0, 0, &xattrs[numattr]); | 612 | 0, 0, &xattrs[numattr]); |
592 | 613 | ||
593 | if (err < 0) | 614 | if (err < 0) |
594 | goto bad; | 615 | goto bad; |
@@ -850,6 +871,9 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, | |||
850 | 871 | ||
851 | dout("setxattr value=%.*s\n", (int)size, value); | 872 | dout("setxattr value=%.*s\n", (int)size, value); |
852 | 873 | ||
874 | if (!value) | ||
875 | flags |= CEPH_XATTR_REMOVE; | ||
876 | |||
853 | /* do request */ | 877 | /* do request */ |
854 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, | 878 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, |
855 | USE_AUTH_MDS); | 879 | USE_AUTH_MDS); |
@@ -892,7 +916,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name, | |||
892 | struct ceph_inode_info *ci = ceph_inode(inode); | 916 | struct ceph_inode_info *ci = ceph_inode(inode); |
893 | int issued; | 917 | int issued; |
894 | int err; | 918 | int err; |
895 | int dirty; | 919 | int dirty = 0; |
896 | int name_len = strlen(name); | 920 | int name_len = strlen(name); |
897 | int val_len = size; | 921 | int val_len = size; |
898 | char *newname = NULL; | 922 | char *newname = NULL; |
@@ -953,12 +977,14 @@ retry: | |||
953 | goto retry; | 977 | goto retry; |
954 | } | 978 | } |
955 | 979 | ||
956 | err = __set_xattr(ci, newname, name_len, newval, | 980 | err = __set_xattr(ci, newname, name_len, newval, val_len, |
957 | val_len, 1, 1, 1, &xattr); | 981 | flags, value ? 1 : -1, &xattr); |
958 | 982 | ||
959 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); | 983 | if (!err) { |
960 | ci->i_xattrs.dirty = true; | 984 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); |
961 | inode->i_ctime = CURRENT_TIME; | 985 | ci->i_xattrs.dirty = true; |
986 | inode->i_ctime = CURRENT_TIME; | ||
987 | } | ||
962 | 988 | ||
963 | spin_unlock(&ci->i_ceph_lock); | 989 | spin_unlock(&ci->i_ceph_lock); |
964 | if (dirty) | 990 | if (dirty) |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index c819b0bd491a..7ff866dbb89e 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -865,8 +865,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
865 | return rc; | 865 | return rc; |
866 | } | 866 | } |
867 | 867 | ||
868 | static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, | 868 | struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, |
869 | __u16 fid, u32 *pacllen) | 869 | const struct cifs_fid *cifsfid, u32 *pacllen) |
870 | { | 870 | { |
871 | struct cifs_ntsd *pntsd = NULL; | 871 | struct cifs_ntsd *pntsd = NULL; |
872 | unsigned int xid; | 872 | unsigned int xid; |
@@ -877,7 +877,8 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, | |||
877 | return ERR_CAST(tlink); | 877 | return ERR_CAST(tlink); |
878 | 878 | ||
879 | xid = get_xid(); | 879 | xid = get_xid(); |
880 | rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen); | 880 | rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd, |
881 | pacllen); | ||
881 | free_xid(xid); | 882 | free_xid(xid); |
882 | 883 | ||
883 | cifs_put_tlink(tlink); | 884 | cifs_put_tlink(tlink); |
@@ -946,7 +947,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, | |||
946 | if (!open_file) | 947 | if (!open_file) |
947 | return get_cifs_acl_by_path(cifs_sb, path, pacllen); | 948 | return get_cifs_acl_by_path(cifs_sb, path, pacllen); |
948 | 949 | ||
949 | pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen); | 950 | pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen); |
950 | cifsFileInfo_put(open_file); | 951 | cifsFileInfo_put(open_file); |
951 | return pntsd; | 952 | return pntsd; |
952 | } | 953 | } |
@@ -1006,19 +1007,31 @@ out: | |||
1006 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 1007 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
1007 | int | 1008 | int |
1008 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | 1009 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, |
1009 | struct inode *inode, const char *path, const __u16 *pfid) | 1010 | struct inode *inode, const char *path, |
1011 | const struct cifs_fid *pfid) | ||
1010 | { | 1012 | { |
1011 | struct cifs_ntsd *pntsd = NULL; | 1013 | struct cifs_ntsd *pntsd = NULL; |
1012 | u32 acllen = 0; | 1014 | u32 acllen = 0; |
1013 | int rc = 0; | 1015 | int rc = 0; |
1016 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
1017 | struct cifs_tcon *tcon; | ||
1014 | 1018 | ||
1015 | cifs_dbg(NOISY, "converting ACL to mode for %s\n", path); | 1019 | cifs_dbg(NOISY, "converting ACL to mode for %s\n", path); |
1016 | 1020 | ||
1017 | if (pfid) | 1021 | if (IS_ERR(tlink)) |
1018 | pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen); | 1022 | return PTR_ERR(tlink); |
1019 | else | 1023 | tcon = tlink_tcon(tlink); |
1020 | pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen); | ||
1021 | 1024 | ||
1025 | if (pfid && (tcon->ses->server->ops->get_acl_by_fid)) | ||
1026 | pntsd = tcon->ses->server->ops->get_acl_by_fid(cifs_sb, pfid, | ||
1027 | &acllen); | ||
1028 | else if (tcon->ses->server->ops->get_acl) | ||
1029 | pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path, | ||
1030 | &acllen); | ||
1031 | else { | ||
1032 | cifs_put_tlink(tlink); | ||
1033 | return -EOPNOTSUPP; | ||
1034 | } | ||
1022 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 1035 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
1023 | if (IS_ERR(pntsd)) { | 1036 | if (IS_ERR(pntsd)) { |
1024 | rc = PTR_ERR(pntsd); | 1037 | rc = PTR_ERR(pntsd); |
@@ -1030,6 +1043,8 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | |||
1030 | cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); | 1043 | cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); |
1031 | } | 1044 | } |
1032 | 1045 | ||
1046 | cifs_put_tlink(tlink); | ||
1047 | |||
1033 | return rc; | 1048 | return rc; |
1034 | } | 1049 | } |
1035 | 1050 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 86dc28c7aa5c..cf32f0393369 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -398,6 +398,8 @@ struct smb_version_operations { | |||
398 | const struct nls_table *, int); | 398 | const struct nls_table *, int); |
399 | struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, | 399 | struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, |
400 | const char *, u32 *); | 400 | const char *, u32 *); |
401 | struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, | ||
402 | const struct cifs_fid *, u32 *); | ||
401 | int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, | 403 | int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, |
402 | int); | 404 | int); |
403 | }; | 405 | }; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index d00e09dfc452..acc4ee8ed075 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -151,7 +151,7 @@ extern struct inode *cifs_iget(struct super_block *sb, | |||
151 | 151 | ||
152 | extern int cifs_get_inode_info(struct inode **inode, const char *full_path, | 152 | extern int cifs_get_inode_info(struct inode **inode, const char *full_path, |
153 | FILE_ALL_INFO *data, struct super_block *sb, | 153 | FILE_ALL_INFO *data, struct super_block *sb, |
154 | int xid, const __u16 *fid); | 154 | int xid, const struct cifs_fid *fid); |
155 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 155 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
156 | const unsigned char *search_path, | 156 | const unsigned char *search_path, |
157 | struct super_block *sb, unsigned int xid); | 157 | struct super_block *sb, unsigned int xid); |
@@ -162,11 +162,13 @@ extern int cifs_rename_pending_delete(const char *full_path, | |||
162 | const unsigned int xid); | 162 | const unsigned int xid); |
163 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, | 163 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, |
164 | struct cifs_fattr *fattr, struct inode *inode, | 164 | struct cifs_fattr *fattr, struct inode *inode, |
165 | const char *path, const __u16 *pfid); | 165 | const char *path, const struct cifs_fid *pfid); |
166 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, | 166 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, |
167 | kuid_t, kgid_t); | 167 | kuid_t, kgid_t); |
168 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, | 168 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, |
169 | const char *, u32 *); | 169 | const char *, u32 *); |
170 | extern struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *, | ||
171 | const struct cifs_fid *, u32 *); | ||
170 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | 172 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, |
171 | const char *, int); | 173 | const char *, int); |
172 | 174 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index d3a6796caa5a..3db0c5fd9a11 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -378,7 +378,7 @@ cifs_create_get_file_info: | |||
378 | xid); | 378 | xid); |
379 | else { | 379 | else { |
380 | rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, | 380 | rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, |
381 | xid, &fid->netfid); | 381 | xid, fid); |
382 | if (newinode) { | 382 | if (newinode) { |
383 | if (server->ops->set_lease_key) | 383 | if (server->ops->set_lease_key) |
384 | server->ops->set_lease_key(newinode, fid); | 384 | server->ops->set_lease_key(newinode, fid); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 755584684f6c..53c15074bb36 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -244,7 +244,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, | |||
244 | xid); | 244 | xid); |
245 | else | 245 | else |
246 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, | 246 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
247 | xid, &fid->netfid); | 247 | xid, fid); |
248 | 248 | ||
249 | out: | 249 | out: |
250 | kfree(buf); | 250 | kfree(buf); |
@@ -2389,7 +2389,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
2389 | unsigned long nr_segs, loff_t *poffset) | 2389 | unsigned long nr_segs, loff_t *poffset) |
2390 | { | 2390 | { |
2391 | unsigned long nr_pages, i; | 2391 | unsigned long nr_pages, i; |
2392 | size_t copied, len, cur_len; | 2392 | size_t bytes, copied, len, cur_len; |
2393 | ssize_t total_written = 0; | 2393 | ssize_t total_written = 0; |
2394 | loff_t offset; | 2394 | loff_t offset; |
2395 | struct iov_iter it; | 2395 | struct iov_iter it; |
@@ -2444,14 +2444,45 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
2444 | 2444 | ||
2445 | save_len = cur_len; | 2445 | save_len = cur_len; |
2446 | for (i = 0; i < nr_pages; i++) { | 2446 | for (i = 0; i < nr_pages; i++) { |
2447 | copied = min_t(const size_t, cur_len, PAGE_SIZE); | 2447 | bytes = min_t(const size_t, cur_len, PAGE_SIZE); |
2448 | copied = iov_iter_copy_from_user(wdata->pages[i], &it, | 2448 | copied = iov_iter_copy_from_user(wdata->pages[i], &it, |
2449 | 0, copied); | 2449 | 0, bytes); |
2450 | cur_len -= copied; | 2450 | cur_len -= copied; |
2451 | iov_iter_advance(&it, copied); | 2451 | iov_iter_advance(&it, copied); |
2452 | /* | ||
2453 | * If we didn't copy as much as we expected, then that | ||
2454 | * may mean we trod into an unmapped area. Stop copying | ||
2455 | * at that point. On the next pass through the big | ||
2456 | * loop, we'll likely end up getting a zero-length | ||
2457 | * write and bailing out of it. | ||
2458 | */ | ||
2459 | if (copied < bytes) | ||
2460 | break; | ||
2452 | } | 2461 | } |
2453 | cur_len = save_len - cur_len; | 2462 | cur_len = save_len - cur_len; |
2454 | 2463 | ||
2464 | /* | ||
2465 | * If we have no data to send, then that probably means that | ||
2466 | * the copy above failed altogether. That's most likely because | ||
2467 | * the address in the iovec was bogus. Set the rc to -EFAULT, | ||
2468 | * free anything we allocated and bail out. | ||
2469 | */ | ||
2470 | if (!cur_len) { | ||
2471 | for (i = 0; i < nr_pages; i++) | ||
2472 | put_page(wdata->pages[i]); | ||
2473 | kfree(wdata); | ||
2474 | rc = -EFAULT; | ||
2475 | break; | ||
2476 | } | ||
2477 | |||
2478 | /* | ||
2479 | * i + 1 now represents the number of pages we actually used in | ||
2480 | * the copy phase above. Bring nr_pages down to that, and free | ||
2481 | * any pages that we didn't use. | ||
2482 | */ | ||
2483 | for ( ; nr_pages > i + 1; nr_pages--) | ||
2484 | put_page(wdata->pages[nr_pages - 1]); | ||
2485 | |||
2455 | wdata->sync_mode = WB_SYNC_ALL; | 2486 | wdata->sync_mode = WB_SYNC_ALL; |
2456 | wdata->nr_pages = nr_pages; | 2487 | wdata->nr_pages = nr_pages; |
2457 | wdata->offset = (__u64)offset; | 2488 | wdata->offset = (__u64)offset; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index be58b8fcdb3c..aadc2b68678b 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -677,7 +677,7 @@ cgfi_exit: | |||
677 | int | 677 | int |
678 | cifs_get_inode_info(struct inode **inode, const char *full_path, | 678 | cifs_get_inode_info(struct inode **inode, const char *full_path, |
679 | FILE_ALL_INFO *data, struct super_block *sb, int xid, | 679 | FILE_ALL_INFO *data, struct super_block *sb, int xid, |
680 | const __u16 *fid) | 680 | const struct cifs_fid *fid) |
681 | { | 681 | { |
682 | bool validinum = false; | 682 | bool validinum = false; |
683 | __u16 srchflgs; | 683 | __u16 srchflgs; |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index bfd66d84831e..526fb89f9230 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -1073,6 +1073,7 @@ struct smb_version_operations smb1_operations = { | |||
1073 | #endif /* CIFS_XATTR */ | 1073 | #endif /* CIFS_XATTR */ |
1074 | #ifdef CONFIG_CIFS_ACL | 1074 | #ifdef CONFIG_CIFS_ACL |
1075 | .get_acl = get_cifs_acl, | 1075 | .get_acl = get_cifs_acl, |
1076 | .get_acl_by_fid = get_cifs_acl_by_fid, | ||
1076 | .set_acl = set_cifs_acl, | 1077 | .set_acl = set_cifs_acl, |
1077 | #endif /* CIFS_ACL */ | 1078 | #endif /* CIFS_ACL */ |
1078 | }; | 1079 | }; |
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h index c38350851b08..bc0bb9c34f72 100644 --- a/fs/cifs/smb2glob.h +++ b/fs/cifs/smb2glob.h | |||
@@ -57,4 +57,7 @@ | |||
57 | #define SMB2_CMACAES_SIZE (16) | 57 | #define SMB2_CMACAES_SIZE (16) |
58 | #define SMB3_SIGNKEY_SIZE (16) | 58 | #define SMB3_SIGNKEY_SIZE (16) |
59 | 59 | ||
60 | /* Maximum buffer size value we can send with 1 credit */ | ||
61 | #define SMB2_MAX_BUFFER_SIZE 65536 | ||
62 | |||
60 | #endif /* _SMB2_GLOB_H */ | 63 | #endif /* _SMB2_GLOB_H */ |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 757da3e54d3d..192f51a12cf1 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -182,11 +182,8 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) | |||
182 | /* start with specified wsize, or default */ | 182 | /* start with specified wsize, or default */ |
183 | wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; | 183 | wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; |
184 | wsize = min_t(unsigned int, wsize, server->max_write); | 184 | wsize = min_t(unsigned int, wsize, server->max_write); |
185 | /* | 185 | /* set it to the maximum buffer size value we can send with 1 credit */ |
186 | * limit write size to 2 ** 16, because we don't support multicredit | 186 | wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); |
187 | * requests now. | ||
188 | */ | ||
189 | wsize = min_t(unsigned int, wsize, 2 << 15); | ||
190 | 187 | ||
191 | return wsize; | 188 | return wsize; |
192 | } | 189 | } |
@@ -200,11 +197,8 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) | |||
200 | /* start with specified rsize, or default */ | 197 | /* start with specified rsize, or default */ |
201 | rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; | 198 | rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; |
202 | rsize = min_t(unsigned int, rsize, server->max_read); | 199 | rsize = min_t(unsigned int, rsize, server->max_read); |
203 | /* | 200 | /* set it to the maximum buffer size value we can send with 1 credit */ |
204 | * limit write size to 2 ** 16, because we don't support multicredit | 201 | rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE); |
205 | * requests now. | ||
206 | */ | ||
207 | rsize = min_t(unsigned int, rsize, 2 << 15); | ||
208 | 202 | ||
209 | return rsize; | 203 | return rsize; |
210 | } | 204 | } |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a3f7a9c3cc69..860344701067 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -413,7 +413,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
413 | 413 | ||
414 | /* SMB2 only has an extended negflavor */ | 414 | /* SMB2 only has an extended negflavor */ |
415 | server->negflavor = CIFS_NEGFLAVOR_EXTENDED; | 415 | server->negflavor = CIFS_NEGFLAVOR_EXTENDED; |
416 | server->maxBuf = le32_to_cpu(rsp->MaxTransactSize); | 416 | /* set it to the maximum buffer size value we can send with 1 credit */ |
417 | server->maxBuf = min_t(unsigned int, le32_to_cpu(rsp->MaxTransactSize), | ||
418 | SMB2_MAX_BUFFER_SIZE); | ||
417 | server->max_read = le32_to_cpu(rsp->MaxReadSize); | 419 | server->max_read = le32_to_cpu(rsp->MaxReadSize); |
418 | server->max_write = le32_to_cpu(rsp->MaxWriteSize); | 420 | server->max_write = le32_to_cpu(rsp->MaxWriteSize); |
419 | /* BB Do we need to validate the SecurityMode? */ | 421 | /* BB Do we need to validate the SecurityMode? */ |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ece55565b9cd..d3a534fdc5ff 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -771,6 +771,8 @@ do { \ | |||
771 | if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \ | 771 | if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \ |
772 | (einode)->xtime.tv_sec = \ | 772 | (einode)->xtime.tv_sec = \ |
773 | (signed)le32_to_cpu((raw_inode)->xtime); \ | 773 | (signed)le32_to_cpu((raw_inode)->xtime); \ |
774 | else \ | ||
775 | (einode)->xtime.tv_sec = 0; \ | ||
774 | if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ | 776 | if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ |
775 | ext4_decode_extra_time(&(einode)->xtime, \ | 777 | ext4_decode_extra_time(&(einode)->xtime, \ |
776 | raw_inode->xtime ## _extra); \ | 778 | raw_inode->xtime ## _extra); \ |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 10cff4736b11..74bc2d549c58 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3906,6 +3906,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
3906 | } else | 3906 | } else |
3907 | err = ret; | 3907 | err = ret; |
3908 | map->m_flags |= EXT4_MAP_MAPPED; | 3908 | map->m_flags |= EXT4_MAP_MAPPED; |
3909 | map->m_pblk = newblock; | ||
3909 | if (allocated > map->m_len) | 3910 | if (allocated > map->m_len) |
3910 | allocated = map->m_len; | 3911 | allocated = map->m_len; |
3911 | map->m_len = allocated; | 3912 | map->m_len = allocated; |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 6bea80614d77..a2a837f00407 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -140,7 +140,7 @@ static long swap_inode_boot_loader(struct super_block *sb, | |||
140 | handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2); | 140 | handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2); |
141 | if (IS_ERR(handle)) { | 141 | if (IS_ERR(handle)) { |
142 | err = -EINVAL; | 142 | err = -EINVAL; |
143 | goto swap_boot_out; | 143 | goto journal_err_out; |
144 | } | 144 | } |
145 | 145 | ||
146 | /* Protect extent tree against block allocations via delalloc */ | 146 | /* Protect extent tree against block allocations via delalloc */ |
@@ -198,6 +198,7 @@ static long swap_inode_boot_loader(struct super_block *sb, | |||
198 | 198 | ||
199 | ext4_double_up_write_data_sem(inode, inode_bl); | 199 | ext4_double_up_write_data_sem(inode, inode_bl); |
200 | 200 | ||
201 | journal_err_out: | ||
201 | ext4_inode_resume_unlocked_dio(inode); | 202 | ext4_inode_resume_unlocked_dio(inode); |
202 | ext4_inode_resume_unlocked_dio(inode_bl); | 203 | ext4_inode_resume_unlocked_dio(inode_bl); |
203 | 204 | ||
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index c5adbb318a90..f3b84cd9de56 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -243,6 +243,7 @@ static int ext4_alloc_group_tables(struct super_block *sb, | |||
243 | ext4_group_t group; | 243 | ext4_group_t group; |
244 | ext4_group_t last_group; | 244 | ext4_group_t last_group; |
245 | unsigned overhead; | 245 | unsigned overhead; |
246 | __u16 uninit_mask = (flexbg_size > 1) ? ~EXT4_BG_BLOCK_UNINIT : ~0; | ||
246 | 247 | ||
247 | BUG_ON(flex_gd->count == 0 || group_data == NULL); | 248 | BUG_ON(flex_gd->count == 0 || group_data == NULL); |
248 | 249 | ||
@@ -266,7 +267,7 @@ next_group: | |||
266 | src_group++; | 267 | src_group++; |
267 | for (; src_group <= last_group; src_group++) { | 268 | for (; src_group <= last_group; src_group++) { |
268 | overhead = ext4_group_overhead_blocks(sb, src_group); | 269 | overhead = ext4_group_overhead_blocks(sb, src_group); |
269 | if (overhead != 0) | 270 | if (overhead == 0) |
270 | last_blk += group_data[src_group - group].blocks_count; | 271 | last_blk += group_data[src_group - group].blocks_count; |
271 | else | 272 | else |
272 | break; | 273 | break; |
@@ -280,8 +281,7 @@ next_group: | |||
280 | group = ext4_get_group_number(sb, start_blk - 1); | 281 | group = ext4_get_group_number(sb, start_blk - 1); |
281 | group -= group_data[0].group; | 282 | group -= group_data[0].group; |
282 | group_data[group].free_blocks_count--; | 283 | group_data[group].free_blocks_count--; |
283 | if (flexbg_size > 1) | 284 | flex_gd->bg_flags[group] &= uninit_mask; |
284 | flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT; | ||
285 | } | 285 | } |
286 | 286 | ||
287 | /* Allocate inode bitmaps */ | 287 | /* Allocate inode bitmaps */ |
@@ -292,22 +292,30 @@ next_group: | |||
292 | group = ext4_get_group_number(sb, start_blk - 1); | 292 | group = ext4_get_group_number(sb, start_blk - 1); |
293 | group -= group_data[0].group; | 293 | group -= group_data[0].group; |
294 | group_data[group].free_blocks_count--; | 294 | group_data[group].free_blocks_count--; |
295 | if (flexbg_size > 1) | 295 | flex_gd->bg_flags[group] &= uninit_mask; |
296 | flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT; | ||
297 | } | 296 | } |
298 | 297 | ||
299 | /* Allocate inode tables */ | 298 | /* Allocate inode tables */ |
300 | for (; it_index < flex_gd->count; it_index++) { | 299 | for (; it_index < flex_gd->count; it_index++) { |
301 | if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk) | 300 | unsigned int itb = EXT4_SB(sb)->s_itb_per_group; |
301 | ext4_fsblk_t next_group_start; | ||
302 | |||
303 | if (start_blk + itb > last_blk) | ||
302 | goto next_group; | 304 | goto next_group; |
303 | group_data[it_index].inode_table = start_blk; | 305 | group_data[it_index].inode_table = start_blk; |
304 | group = ext4_get_group_number(sb, start_blk - 1); | 306 | group = ext4_get_group_number(sb, start_blk); |
307 | next_group_start = ext4_group_first_block_no(sb, group + 1); | ||
305 | group -= group_data[0].group; | 308 | group -= group_data[0].group; |
306 | group_data[group].free_blocks_count -= | ||
307 | EXT4_SB(sb)->s_itb_per_group; | ||
308 | if (flexbg_size > 1) | ||
309 | flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT; | ||
310 | 309 | ||
310 | if (start_blk + itb > next_group_start) { | ||
311 | flex_gd->bg_flags[group + 1] &= uninit_mask; | ||
312 | overhead = start_blk + itb - next_group_start; | ||
313 | group_data[group + 1].free_blocks_count -= overhead; | ||
314 | itb -= overhead; | ||
315 | } | ||
316 | |||
317 | group_data[group].free_blocks_count -= itb; | ||
318 | flex_gd->bg_flags[group] &= uninit_mask; | ||
311 | start_blk += EXT4_SB(sb)->s_itb_per_group; | 319 | start_blk += EXT4_SB(sb)->s_itb_per_group; |
312 | } | 320 | } |
313 | 321 | ||
@@ -401,7 +409,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle, | |||
401 | start = ext4_group_first_block_no(sb, group); | 409 | start = ext4_group_first_block_no(sb, group); |
402 | group -= flex_gd->groups[0].group; | 410 | group -= flex_gd->groups[0].group; |
403 | 411 | ||
404 | count2 = sb->s_blocksize * 8 - (block - start); | 412 | count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start); |
405 | if (count2 > count) | 413 | if (count2 > count) |
406 | count2 = count; | 414 | count2 = count; |
407 | 415 | ||
@@ -620,7 +628,7 @@ handle_ib: | |||
620 | if (err) | 628 | if (err) |
621 | goto out; | 629 | goto out; |
622 | count = group_table_count[j]; | 630 | count = group_table_count[j]; |
623 | start = group_data[i].block_bitmap; | 631 | start = (&group_data[i].block_bitmap)[j]; |
624 | block = start; | 632 | block = start; |
625 | } | 633 | } |
626 | 634 | ||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1f7784de05b6..710fed2377d4 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3695,16 +3695,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3695 | for (i = 0; i < 4; i++) | 3695 | for (i = 0; i < 4; i++) |
3696 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); | 3696 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); |
3697 | sbi->s_def_hash_version = es->s_def_hash_version; | 3697 | sbi->s_def_hash_version = es->s_def_hash_version; |
3698 | i = le32_to_cpu(es->s_flags); | 3698 | if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) { |
3699 | if (i & EXT2_FLAGS_UNSIGNED_HASH) | 3699 | i = le32_to_cpu(es->s_flags); |
3700 | sbi->s_hash_unsigned = 3; | 3700 | if (i & EXT2_FLAGS_UNSIGNED_HASH) |
3701 | else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { | 3701 | sbi->s_hash_unsigned = 3; |
3702 | else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { | ||
3702 | #ifdef __CHAR_UNSIGNED__ | 3703 | #ifdef __CHAR_UNSIGNED__ |
3703 | es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); | 3704 | if (!(sb->s_flags & MS_RDONLY)) |
3704 | sbi->s_hash_unsigned = 3; | 3705 | es->s_flags |= |
3706 | cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); | ||
3707 | sbi->s_hash_unsigned = 3; | ||
3705 | #else | 3708 | #else |
3706 | es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); | 3709 | if (!(sb->s_flags & MS_RDONLY)) |
3710 | es->s_flags |= | ||
3711 | cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); | ||
3707 | #endif | 3712 | #endif |
3713 | } | ||
3708 | } | 3714 | } |
3709 | 3715 | ||
3710 | /* Handle clustersize */ | 3716 | /* Handle clustersize */ |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index e0259a163f98..d754e3cf99a8 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -40,18 +40,13 @@ | |||
40 | struct wb_writeback_work { | 40 | struct wb_writeback_work { |
41 | long nr_pages; | 41 | long nr_pages; |
42 | struct super_block *sb; | 42 | struct super_block *sb; |
43 | /* | 43 | unsigned long *older_than_this; |
44 | * Write only inodes dirtied before this time. Don't forget to set | ||
45 | * older_than_this_is_set when you set this. | ||
46 | */ | ||
47 | unsigned long older_than_this; | ||
48 | enum writeback_sync_modes sync_mode; | 44 | enum writeback_sync_modes sync_mode; |
49 | unsigned int tagged_writepages:1; | 45 | unsigned int tagged_writepages:1; |
50 | unsigned int for_kupdate:1; | 46 | unsigned int for_kupdate:1; |
51 | unsigned int range_cyclic:1; | 47 | unsigned int range_cyclic:1; |
52 | unsigned int for_background:1; | 48 | unsigned int for_background:1; |
53 | unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ | 49 | unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ |
54 | unsigned int older_than_this_is_set:1; | ||
55 | enum wb_reason reason; /* why was writeback initiated? */ | 50 | enum wb_reason reason; /* why was writeback initiated? */ |
56 | 51 | ||
57 | struct list_head list; /* pending work list */ | 52 | struct list_head list; /* pending work list */ |
@@ -252,10 +247,10 @@ static int move_expired_inodes(struct list_head *delaying_queue, | |||
252 | int do_sb_sort = 0; | 247 | int do_sb_sort = 0; |
253 | int moved = 0; | 248 | int moved = 0; |
254 | 249 | ||
255 | WARN_ON_ONCE(!work->older_than_this_is_set); | ||
256 | while (!list_empty(delaying_queue)) { | 250 | while (!list_empty(delaying_queue)) { |
257 | inode = wb_inode(delaying_queue->prev); | 251 | inode = wb_inode(delaying_queue->prev); |
258 | if (inode_dirtied_after(inode, work->older_than_this)) | 252 | if (work->older_than_this && |
253 | inode_dirtied_after(inode, *work->older_than_this)) | ||
259 | break; | 254 | break; |
260 | list_move(&inode->i_wb_list, &tmp); | 255 | list_move(&inode->i_wb_list, &tmp); |
261 | moved++; | 256 | moved++; |
@@ -742,8 +737,6 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, | |||
742 | .sync_mode = WB_SYNC_NONE, | 737 | .sync_mode = WB_SYNC_NONE, |
743 | .range_cyclic = 1, | 738 | .range_cyclic = 1, |
744 | .reason = reason, | 739 | .reason = reason, |
745 | .older_than_this = jiffies, | ||
746 | .older_than_this_is_set = 1, | ||
747 | }; | 740 | }; |
748 | 741 | ||
749 | spin_lock(&wb->list_lock); | 742 | spin_lock(&wb->list_lock); |
@@ -802,13 +795,12 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
802 | { | 795 | { |
803 | unsigned long wb_start = jiffies; | 796 | unsigned long wb_start = jiffies; |
804 | long nr_pages = work->nr_pages; | 797 | long nr_pages = work->nr_pages; |
798 | unsigned long oldest_jif; | ||
805 | struct inode *inode; | 799 | struct inode *inode; |
806 | long progress; | 800 | long progress; |
807 | 801 | ||
808 | if (!work->older_than_this_is_set) { | 802 | oldest_jif = jiffies; |
809 | work->older_than_this = jiffies; | 803 | work->older_than_this = &oldest_jif; |
810 | work->older_than_this_is_set = 1; | ||
811 | } | ||
812 | 804 | ||
813 | spin_lock(&wb->list_lock); | 805 | spin_lock(&wb->list_lock); |
814 | for (;;) { | 806 | for (;;) { |
@@ -842,10 +834,10 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
842 | * safe. | 834 | * safe. |
843 | */ | 835 | */ |
844 | if (work->for_kupdate) { | 836 | if (work->for_kupdate) { |
845 | work->older_than_this = jiffies - | 837 | oldest_jif = jiffies - |
846 | msecs_to_jiffies(dirty_expire_interval * 10); | 838 | msecs_to_jiffies(dirty_expire_interval * 10); |
847 | } else if (work->for_background) | 839 | } else if (work->for_background) |
848 | work->older_than_this = jiffies; | 840 | oldest_jif = jiffies; |
849 | 841 | ||
850 | trace_writeback_start(wb->bdi, work); | 842 | trace_writeback_start(wb->bdi, work); |
851 | if (list_empty(&wb->b_io)) | 843 | if (list_empty(&wb->b_io)) |
@@ -1357,21 +1349,18 @@ EXPORT_SYMBOL(try_to_writeback_inodes_sb); | |||
1357 | 1349 | ||
1358 | /** | 1350 | /** |
1359 | * sync_inodes_sb - sync sb inode pages | 1351 | * sync_inodes_sb - sync sb inode pages |
1360 | * @sb: the superblock | 1352 | * @sb: the superblock |
1361 | * @older_than_this: timestamp | ||
1362 | * | 1353 | * |
1363 | * This function writes and waits on any dirty inode belonging to this | 1354 | * This function writes and waits on any dirty inode belonging to this |
1364 | * superblock that has been dirtied before given timestamp. | 1355 | * super_block. |
1365 | */ | 1356 | */ |
1366 | void sync_inodes_sb(struct super_block *sb, unsigned long older_than_this) | 1357 | void sync_inodes_sb(struct super_block *sb) |
1367 | { | 1358 | { |
1368 | DECLARE_COMPLETION_ONSTACK(done); | 1359 | DECLARE_COMPLETION_ONSTACK(done); |
1369 | struct wb_writeback_work work = { | 1360 | struct wb_writeback_work work = { |
1370 | .sb = sb, | 1361 | .sb = sb, |
1371 | .sync_mode = WB_SYNC_ALL, | 1362 | .sync_mode = WB_SYNC_ALL, |
1372 | .nr_pages = LONG_MAX, | 1363 | .nr_pages = LONG_MAX, |
1373 | .older_than_this = older_than_this, | ||
1374 | .older_than_this_is_set = 1, | ||
1375 | .range_cyclic = 0, | 1364 | .range_cyclic = 0, |
1376 | .done = &done, | 1365 | .done = &done, |
1377 | .reason = WB_REASON_SYNC, | 1366 | .reason = WB_REASON_SYNC, |
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c index e1959efad64f..b5ebc2d7d80d 100644 --- a/fs/fscache/object-list.c +++ b/fs/fscache/object-list.c | |||
@@ -50,6 +50,8 @@ void fscache_objlist_add(struct fscache_object *obj) | |||
50 | struct fscache_object *xobj; | 50 | struct fscache_object *xobj; |
51 | struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL; | 51 | struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL; |
52 | 52 | ||
53 | ASSERT(RB_EMPTY_NODE(&obj->objlist_link)); | ||
54 | |||
53 | write_lock(&fscache_object_list_lock); | 55 | write_lock(&fscache_object_list_lock); |
54 | 56 | ||
55 | while (*p) { | 57 | while (*p) { |
@@ -75,6 +77,9 @@ void fscache_objlist_add(struct fscache_object *obj) | |||
75 | */ | 77 | */ |
76 | void fscache_objlist_remove(struct fscache_object *obj) | 78 | void fscache_objlist_remove(struct fscache_object *obj) |
77 | { | 79 | { |
80 | if (RB_EMPTY_NODE(&obj->objlist_link)) | ||
81 | return; | ||
82 | |||
78 | write_lock(&fscache_object_list_lock); | 83 | write_lock(&fscache_object_list_lock); |
79 | 84 | ||
80 | BUG_ON(RB_EMPTY_ROOT(&fscache_object_list)); | 85 | BUG_ON(RB_EMPTY_ROOT(&fscache_object_list)); |
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 53d35c504240..d3b4539f1651 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
@@ -314,6 +314,9 @@ void fscache_object_init(struct fscache_object *object, | |||
314 | object->cache = cache; | 314 | object->cache = cache; |
315 | object->cookie = cookie; | 315 | object->cookie = cookie; |
316 | object->parent = NULL; | 316 | object->parent = NULL; |
317 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
318 | RB_CLEAR_NODE(&object->objlist_link); | ||
319 | #endif | ||
317 | 320 | ||
318 | object->oob_event_mask = 0; | 321 | object->oob_event_mask = 0; |
319 | for (t = object->oob_table; t->events; t++) | 322 | for (t = object->oob_table; t->events; t++) |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 8360674c85bc..60bb365f54a5 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -514,11 +514,13 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type, | |||
514 | * similarly constrained call sites | 514 | * similarly constrained call sites |
515 | */ | 515 | */ |
516 | ret = start_this_handle(journal, handle, GFP_NOFS); | 516 | ret = start_this_handle(journal, handle, GFP_NOFS); |
517 | if (ret < 0) | 517 | if (ret < 0) { |
518 | jbd2_journal_free_reserved(handle); | 518 | jbd2_journal_free_reserved(handle); |
519 | return ret; | ||
520 | } | ||
519 | handle->h_type = type; | 521 | handle->h_type = type; |
520 | handle->h_line_no = line_no; | 522 | handle->h_line_no = line_no; |
521 | return ret; | 523 | return 0; |
522 | } | 524 | } |
523 | EXPORT_SYMBOL(jbd2_journal_start_reserved); | 525 | EXPORT_SYMBOL(jbd2_journal_start_reserved); |
524 | 526 | ||
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index e973b85d6afd..5a8ea16eedbc 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
@@ -86,6 +86,8 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type, | |||
86 | rc = posix_acl_equiv_mode(acl, &inode->i_mode); | 86 | rc = posix_acl_equiv_mode(acl, &inode->i_mode); |
87 | if (rc < 0) | 87 | if (rc < 0) |
88 | return rc; | 88 | return rc; |
89 | inode->i_ctime = CURRENT_TIME; | ||
90 | mark_inode_dirty(inode); | ||
89 | if (rc == 0) | 91 | if (rc == 0) |
90 | acl = NULL; | 92 | acl = NULL; |
91 | break; | 93 | break; |
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 0d6ce895a9ee..0f4152defe7b 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c | |||
@@ -94,6 +94,7 @@ const void *kernfs_super_ns(struct super_block *sb) | |||
94 | * @fs_type: file_system_type of the fs being mounted | 94 | * @fs_type: file_system_type of the fs being mounted |
95 | * @flags: mount flags specified for the mount | 95 | * @flags: mount flags specified for the mount |
96 | * @root: kernfs_root of the hierarchy being mounted | 96 | * @root: kernfs_root of the hierarchy being mounted |
97 | * @new_sb_created: tell the caller if we allocated a new superblock | ||
97 | * @ns: optional namespace tag of the mount | 98 | * @ns: optional namespace tag of the mount |
98 | * | 99 | * |
99 | * This is to be called from each kernfs user's file_system_type->mount() | 100 | * This is to be called from each kernfs user's file_system_type->mount() |
@@ -104,7 +105,8 @@ const void *kernfs_super_ns(struct super_block *sb) | |||
104 | * The return value can be passed to the vfs layer verbatim. | 105 | * The return value can be passed to the vfs layer verbatim. |
105 | */ | 106 | */ |
106 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | 107 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, |
107 | struct kernfs_root *root, const void *ns) | 108 | struct kernfs_root *root, bool *new_sb_created, |
109 | const void *ns) | ||
108 | { | 110 | { |
109 | struct super_block *sb; | 111 | struct super_block *sb; |
110 | struct kernfs_super_info *info; | 112 | struct kernfs_super_info *info; |
@@ -122,6 +124,10 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | |||
122 | kfree(info); | 124 | kfree(info); |
123 | if (IS_ERR(sb)) | 125 | if (IS_ERR(sb)) |
124 | return ERR_CAST(sb); | 126 | return ERR_CAST(sb); |
127 | |||
128 | if (new_sb_created) | ||
129 | *new_sb_created = !sb->s_root; | ||
130 | |||
125 | if (!sb->s_root) { | 131 | if (!sb->s_root) { |
126 | error = kernfs_fill_super(sb); | 132 | error = kernfs_fill_super(sb); |
127 | if (error) { | 133 | if (error) { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 28a0a3cbd3b7..360114ae8b82 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -164,17 +164,16 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { |
165 | nfs_fscache_invalidate(inode); | 165 | nfs_fscache_invalidate(inode); |
166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
167 | | NFS_INO_INVALID_LABEL | ||
168 | | NFS_INO_INVALID_DATA | 167 | | NFS_INO_INVALID_DATA |
169 | | NFS_INO_INVALID_ACCESS | 168 | | NFS_INO_INVALID_ACCESS |
170 | | NFS_INO_INVALID_ACL | 169 | | NFS_INO_INVALID_ACL |
171 | | NFS_INO_REVAL_PAGECACHE; | 170 | | NFS_INO_REVAL_PAGECACHE; |
172 | } else | 171 | } else |
173 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 172 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
174 | | NFS_INO_INVALID_LABEL | ||
175 | | NFS_INO_INVALID_ACCESS | 173 | | NFS_INO_INVALID_ACCESS |
176 | | NFS_INO_INVALID_ACL | 174 | | NFS_INO_INVALID_ACL |
177 | | NFS_INO_REVAL_PAGECACHE; | 175 | | NFS_INO_REVAL_PAGECACHE; |
176 | nfs_zap_label_cache_locked(nfsi); | ||
178 | } | 177 | } |
179 | 178 | ||
180 | void nfs_zap_caches(struct inode *inode) | 179 | void nfs_zap_caches(struct inode *inode) |
@@ -266,6 +265,13 @@ nfs_init_locked(struct inode *inode, void *opaque) | |||
266 | } | 265 | } |
267 | 266 | ||
268 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL | 267 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL |
268 | static void nfs_clear_label_invalid(struct inode *inode) | ||
269 | { | ||
270 | spin_lock(&inode->i_lock); | ||
271 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_LABEL; | ||
272 | spin_unlock(&inode->i_lock); | ||
273 | } | ||
274 | |||
269 | void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | 275 | void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, |
270 | struct nfs4_label *label) | 276 | struct nfs4_label *label) |
271 | { | 277 | { |
@@ -283,6 +289,7 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | |||
283 | __func__, | 289 | __func__, |
284 | (char *)label->label, | 290 | (char *)label->label, |
285 | label->len, error); | 291 | label->len, error); |
292 | nfs_clear_label_invalid(inode); | ||
286 | } | 293 | } |
287 | } | 294 | } |
288 | 295 | ||
@@ -1648,7 +1655,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1648 | inode->i_blocks = fattr->du.nfs2.blocks; | 1655 | inode->i_blocks = fattr->du.nfs2.blocks; |
1649 | 1656 | ||
1650 | /* Update attrtimeo value if we're out of the unstable period */ | 1657 | /* Update attrtimeo value if we're out of the unstable period */ |
1651 | if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) { | 1658 | if (invalid & NFS_INO_INVALID_ATTR) { |
1652 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); | 1659 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); |
1653 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 1660 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
1654 | nfsi->attrtimeo_timestamp = now; | 1661 | nfsi->attrtimeo_timestamp = now; |
@@ -1661,7 +1668,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1661 | } | 1668 | } |
1662 | } | 1669 | } |
1663 | invalid &= ~NFS_INO_INVALID_ATTR; | 1670 | invalid &= ~NFS_INO_INVALID_ATTR; |
1664 | invalid &= ~NFS_INO_INVALID_LABEL; | ||
1665 | /* Don't invalidate the data if we were to blame */ | 1671 | /* Don't invalidate the data if we were to blame */ |
1666 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1672 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1667 | || S_ISLNK(inode->i_mode))) | 1673 | || S_ISLNK(inode->i_mode))) |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 8b5cc04a8611..b46cf5a67329 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -176,7 +176,8 @@ extern struct nfs_server *nfs4_create_server( | |||
176 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, | 176 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, |
177 | struct nfs_fh *); | 177 | struct nfs_fh *); |
178 | extern int nfs4_update_server(struct nfs_server *server, const char *hostname, | 178 | extern int nfs4_update_server(struct nfs_server *server, const char *hostname, |
179 | struct sockaddr *sap, size_t salen); | 179 | struct sockaddr *sap, size_t salen, |
180 | struct net *net); | ||
180 | extern void nfs_free_server(struct nfs_server *server); | 181 | extern void nfs_free_server(struct nfs_server *server); |
181 | extern struct nfs_server *nfs_clone_server(struct nfs_server *, | 182 | extern struct nfs_server *nfs_clone_server(struct nfs_server *, |
182 | struct nfs_fh *, | 183 | struct nfs_fh *, |
@@ -279,9 +280,18 @@ static inline void nfs4_label_free(struct nfs4_label *label) | |||
279 | } | 280 | } |
280 | return; | 281 | return; |
281 | } | 282 | } |
283 | |||
284 | static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi) | ||
285 | { | ||
286 | if (nfs_server_capable(&nfsi->vfs_inode, NFS_CAP_SECURITY_LABEL)) | ||
287 | nfsi->cache_validity |= NFS_INO_INVALID_LABEL; | ||
288 | } | ||
282 | #else | 289 | #else |
283 | static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; } | 290 | static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; } |
284 | static inline void nfs4_label_free(void *label) {} | 291 | static inline void nfs4_label_free(void *label) {} |
292 | static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi) | ||
293 | { | ||
294 | } | ||
285 | #endif /* CONFIG_NFS_V4_SECURITY_LABEL */ | 295 | #endif /* CONFIG_NFS_V4_SECURITY_LABEL */ |
286 | 296 | ||
287 | /* proc.c */ | 297 | /* proc.c */ |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index aa9bc973f36a..a462ef0fb5d6 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/lockd/bind.h> | 18 | #include <linux/lockd/bind.h> |
19 | #include <linux/nfs_mount.h> | 19 | #include <linux/nfs_mount.h> |
20 | #include <linux/freezer.h> | 20 | #include <linux/freezer.h> |
21 | #include <linux/xattr.h> | ||
21 | 22 | ||
22 | #include "iostat.h" | 23 | #include "iostat.h" |
23 | #include "internal.h" | 24 | #include "internal.h" |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 860ad26a5590..0e46d3d1b6cc 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -1135,6 +1135,7 @@ static int nfs_probe_destination(struct nfs_server *server) | |||
1135 | * @hostname: new end-point's hostname | 1135 | * @hostname: new end-point's hostname |
1136 | * @sap: new end-point's socket address | 1136 | * @sap: new end-point's socket address |
1137 | * @salen: size of "sap" | 1137 | * @salen: size of "sap" |
1138 | * @net: net namespace | ||
1138 | * | 1139 | * |
1139 | * The nfs_server must be quiescent before this function is invoked. | 1140 | * The nfs_server must be quiescent before this function is invoked. |
1140 | * Either its session is drained (NFSv4.1+), or its transport is | 1141 | * Either its session is drained (NFSv4.1+), or its transport is |
@@ -1143,13 +1144,13 @@ static int nfs_probe_destination(struct nfs_server *server) | |||
1143 | * Returns zero on success, or a negative errno value. | 1144 | * Returns zero on success, or a negative errno value. |
1144 | */ | 1145 | */ |
1145 | int nfs4_update_server(struct nfs_server *server, const char *hostname, | 1146 | int nfs4_update_server(struct nfs_server *server, const char *hostname, |
1146 | struct sockaddr *sap, size_t salen) | 1147 | struct sockaddr *sap, size_t salen, struct net *net) |
1147 | { | 1148 | { |
1148 | struct nfs_client *clp = server->nfs_client; | 1149 | struct nfs_client *clp = server->nfs_client; |
1149 | struct rpc_clnt *clnt = server->client; | 1150 | struct rpc_clnt *clnt = server->client; |
1150 | struct xprt_create xargs = { | 1151 | struct xprt_create xargs = { |
1151 | .ident = clp->cl_proto, | 1152 | .ident = clp->cl_proto, |
1152 | .net = &init_net, | 1153 | .net = net, |
1153 | .dstaddr = sap, | 1154 | .dstaddr = sap, |
1154 | .addrlen = salen, | 1155 | .addrlen = salen, |
1155 | .servername = hostname, | 1156 | .servername = hostname, |
@@ -1189,7 +1190,7 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname, | |||
1189 | error = nfs4_set_client(server, hostname, sap, salen, buf, | 1190 | error = nfs4_set_client(server, hostname, sap, salen, buf, |
1190 | clp->cl_rpcclient->cl_auth->au_flavor, | 1191 | clp->cl_rpcclient->cl_auth->au_flavor, |
1191 | clp->cl_proto, clnt->cl_timeout, | 1192 | clp->cl_proto, clnt->cl_timeout, |
1192 | clp->cl_minorversion, clp->cl_net); | 1193 | clp->cl_minorversion, net); |
1193 | nfs_put_client(clp); | 1194 | nfs_put_client(clp); |
1194 | if (error != 0) { | 1195 | if (error != 0) { |
1195 | nfs_server_insert_lists(server); | 1196 | nfs_server_insert_lists(server); |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 4e7f05d3e9db..3d5dbf80d46a 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
@@ -121,9 +121,8 @@ static int nfs4_validate_fspath(struct dentry *dentry, | |||
121 | } | 121 | } |
122 | 122 | ||
123 | static size_t nfs_parse_server_name(char *string, size_t len, | 123 | static size_t nfs_parse_server_name(char *string, size_t len, |
124 | struct sockaddr *sa, size_t salen, struct nfs_server *server) | 124 | struct sockaddr *sa, size_t salen, struct net *net) |
125 | { | 125 | { |
126 | struct net *net = rpc_net_ns(server->client); | ||
127 | ssize_t ret; | 126 | ssize_t ret; |
128 | 127 | ||
129 | ret = rpc_pton(net, string, len, sa, salen); | 128 | ret = rpc_pton(net, string, len, sa, salen); |
@@ -223,6 +222,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
223 | const struct nfs4_fs_location *location) | 222 | const struct nfs4_fs_location *location) |
224 | { | 223 | { |
225 | const size_t addr_bufsize = sizeof(struct sockaddr_storage); | 224 | const size_t addr_bufsize = sizeof(struct sockaddr_storage); |
225 | struct net *net = rpc_net_ns(NFS_SB(mountdata->sb)->client); | ||
226 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 226 | struct vfsmount *mnt = ERR_PTR(-ENOENT); |
227 | char *mnt_path; | 227 | char *mnt_path; |
228 | unsigned int maxbuflen; | 228 | unsigned int maxbuflen; |
@@ -248,8 +248,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
248 | continue; | 248 | continue; |
249 | 249 | ||
250 | mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len, | 250 | mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len, |
251 | mountdata->addr, addr_bufsize, | 251 | mountdata->addr, addr_bufsize, net); |
252 | NFS_SB(mountdata->sb)); | ||
253 | if (mountdata->addrlen == 0) | 252 | if (mountdata->addrlen == 0) |
254 | continue; | 253 | continue; |
255 | 254 | ||
@@ -419,6 +418,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server, | |||
419 | const struct nfs4_fs_location *location) | 418 | const struct nfs4_fs_location *location) |
420 | { | 419 | { |
421 | const size_t addr_bufsize = sizeof(struct sockaddr_storage); | 420 | const size_t addr_bufsize = sizeof(struct sockaddr_storage); |
421 | struct net *net = rpc_net_ns(server->client); | ||
422 | struct sockaddr *sap; | 422 | struct sockaddr *sap; |
423 | unsigned int s; | 423 | unsigned int s; |
424 | size_t salen; | 424 | size_t salen; |
@@ -440,7 +440,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server, | |||
440 | continue; | 440 | continue; |
441 | 441 | ||
442 | salen = nfs_parse_server_name(buf->data, buf->len, | 442 | salen = nfs_parse_server_name(buf->data, buf->len, |
443 | sap, addr_bufsize, server); | 443 | sap, addr_bufsize, net); |
444 | if (salen == 0) | 444 | if (salen == 0) |
445 | continue; | 445 | continue; |
446 | rpc_set_port(sap, NFS_PORT); | 446 | rpc_set_port(sap, NFS_PORT); |
@@ -450,7 +450,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server, | |||
450 | if (hostname == NULL) | 450 | if (hostname == NULL) |
451 | break; | 451 | break; |
452 | 452 | ||
453 | error = nfs4_update_server(server, hostname, sap, salen); | 453 | error = nfs4_update_server(server, hostname, sap, salen, net); |
454 | kfree(hostname); | 454 | kfree(hostname); |
455 | if (error == 0) | 455 | if (error == 0) |
456 | break; | 456 | break; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e5be72518bd7..e1a47217c05e 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1015,8 +1015,11 @@ int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, | |||
1015 | if (ret == -EIO) | 1015 | if (ret == -EIO) |
1016 | /* A lost lock - don't even consider delegations */ | 1016 | /* A lost lock - don't even consider delegations */ |
1017 | goto out; | 1017 | goto out; |
1018 | if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) | 1018 | /* returns true if delegation stateid found and copied */ |
1019 | if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) { | ||
1020 | ret = 0; | ||
1019 | goto out; | 1021 | goto out; |
1022 | } | ||
1020 | if (ret != -ENOENT) | 1023 | if (ret != -ENOENT) |
1021 | /* nfs4_copy_delegation_stateid() didn't over-write | 1024 | /* nfs4_copy_delegation_stateid() didn't over-write |
1022 | * dst, so it still has the lock stateid which we now | 1025 | * dst, so it still has the lock stateid which we now |
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 0b9ff4395e6a..abc8cbcfe90e 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -86,7 +86,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, | |||
86 | struct fsnotify_mark *inode_mark, | 86 | struct fsnotify_mark *inode_mark, |
87 | struct fsnotify_mark *vfsmount_mark, | 87 | struct fsnotify_mark *vfsmount_mark, |
88 | u32 mask, void *data, int data_type, | 88 | u32 mask, void *data, int data_type, |
89 | const unsigned char *file_name) | 89 | const unsigned char *file_name, u32 cookie) |
90 | { | 90 | { |
91 | struct dnotify_mark *dn_mark; | 91 | struct dnotify_mark *dn_mark; |
92 | struct dnotify_struct *dn; | 92 | struct dnotify_struct *dn; |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 0e792f5e3147..dc638f786d5c 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -147,7 +147,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
147 | struct fsnotify_mark *inode_mark, | 147 | struct fsnotify_mark *inode_mark, |
148 | struct fsnotify_mark *fanotify_mark, | 148 | struct fsnotify_mark *fanotify_mark, |
149 | u32 mask, void *data, int data_type, | 149 | u32 mask, void *data, int data_type, |
150 | const unsigned char *file_name) | 150 | const unsigned char *file_name, u32 cookie) |
151 | { | 151 | { |
152 | int ret = 0; | 152 | int ret = 0; |
153 | struct fanotify_event_info *event; | 153 | struct fanotify_event_info *event; |
@@ -192,10 +192,12 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
192 | 192 | ||
193 | ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); | 193 | ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); |
194 | if (ret) { | 194 | if (ret) { |
195 | BUG_ON(mask & FAN_ALL_PERM_EVENTS); | 195 | /* Permission events shouldn't be merged */ |
196 | BUG_ON(ret == 1 && mask & FAN_ALL_PERM_EVENTS); | ||
196 | /* Our event wasn't used in the end. Free it. */ | 197 | /* Our event wasn't used in the end. Free it. */ |
197 | fsnotify_destroy_event(group, fsn_event); | 198 | fsnotify_destroy_event(group, fsn_event); |
198 | ret = 0; | 199 | |
200 | return 0; | ||
199 | } | 201 | } |
200 | 202 | ||
201 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 203 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index b6175fa11bf8..287a22c04149 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -698,6 +698,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
698 | struct fsnotify_group *group; | 698 | struct fsnotify_group *group; |
699 | int f_flags, fd; | 699 | int f_flags, fd; |
700 | struct user_struct *user; | 700 | struct user_struct *user; |
701 | struct fanotify_event_info *oevent; | ||
701 | 702 | ||
702 | pr_debug("%s: flags=%d event_f_flags=%d\n", | 703 | pr_debug("%s: flags=%d event_f_flags=%d\n", |
703 | __func__, flags, event_f_flags); | 704 | __func__, flags, event_f_flags); |
@@ -730,8 +731,20 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
730 | group->fanotify_data.user = user; | 731 | group->fanotify_data.user = user; |
731 | atomic_inc(&user->fanotify_listeners); | 732 | atomic_inc(&user->fanotify_listeners); |
732 | 733 | ||
734 | oevent = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL); | ||
735 | if (unlikely(!oevent)) { | ||
736 | fd = -ENOMEM; | ||
737 | goto out_destroy_group; | ||
738 | } | ||
739 | group->overflow_event = &oevent->fse; | ||
740 | fsnotify_init_event(group->overflow_event, NULL, FS_Q_OVERFLOW); | ||
741 | oevent->tgid = get_pid(task_tgid(current)); | ||
742 | oevent->path.mnt = NULL; | ||
743 | oevent->path.dentry = NULL; | ||
744 | |||
733 | group->fanotify_data.f_flags = event_f_flags; | 745 | group->fanotify_data.f_flags = event_f_flags; |
734 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 746 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
747 | oevent->response = 0; | ||
735 | mutex_init(&group->fanotify_data.access_mutex); | 748 | mutex_init(&group->fanotify_data.access_mutex); |
736 | init_waitqueue_head(&group->fanotify_data.access_waitq); | 749 | init_waitqueue_head(&group->fanotify_data.access_waitq); |
737 | INIT_LIST_HEAD(&group->fanotify_data.access_list); | 750 | INIT_LIST_HEAD(&group->fanotify_data.access_list); |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 1d4e1ea2f37c..9d3e9c50066a 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -179,7 +179,7 @@ static int send_to_group(struct inode *to_tell, | |||
179 | 179 | ||
180 | return group->ops->handle_event(group, to_tell, inode_mark, | 180 | return group->ops->handle_event(group, to_tell, inode_mark, |
181 | vfsmount_mark, mask, data, data_is, | 181 | vfsmount_mark, mask, data, data_is, |
182 | file_name); | 182 | file_name, cookie); |
183 | } | 183 | } |
184 | 184 | ||
185 | /* | 185 | /* |
diff --git a/fs/notify/group.c b/fs/notify/group.c index ee674fe2cec7..ad1995980456 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c | |||
@@ -55,6 +55,13 @@ void fsnotify_destroy_group(struct fsnotify_group *group) | |||
55 | /* clear the notification queue of all events */ | 55 | /* clear the notification queue of all events */ |
56 | fsnotify_flush_notify(group); | 56 | fsnotify_flush_notify(group); |
57 | 57 | ||
58 | /* | ||
59 | * Destroy overflow event (we cannot use fsnotify_destroy_event() as | ||
60 | * that deliberately ignores overflow events. | ||
61 | */ | ||
62 | if (group->overflow_event) | ||
63 | group->ops->free_event(group->overflow_event); | ||
64 | |||
58 | fsnotify_put_group(group); | 65 | fsnotify_put_group(group); |
59 | } | 66 | } |
60 | 67 | ||
@@ -99,7 +106,6 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) | |||
99 | INIT_LIST_HEAD(&group->marks_list); | 106 | INIT_LIST_HEAD(&group->marks_list); |
100 | 107 | ||
101 | group->ops = ops; | 108 | group->ops = ops; |
102 | fsnotify_init_event(&group->overflow_event, NULL, FS_Q_OVERFLOW); | ||
103 | 109 | ||
104 | return group; | 110 | return group; |
105 | } | 111 | } |
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index 485eef3f4407..ed855ef6f077 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h | |||
@@ -27,6 +27,6 @@ extern int inotify_handle_event(struct fsnotify_group *group, | |||
27 | struct fsnotify_mark *inode_mark, | 27 | struct fsnotify_mark *inode_mark, |
28 | struct fsnotify_mark *vfsmount_mark, | 28 | struct fsnotify_mark *vfsmount_mark, |
29 | u32 mask, void *data, int data_type, | 29 | u32 mask, void *data, int data_type, |
30 | const unsigned char *file_name); | 30 | const unsigned char *file_name, u32 cookie); |
31 | 31 | ||
32 | extern const struct fsnotify_ops inotify_fsnotify_ops; | 32 | extern const struct fsnotify_ops inotify_fsnotify_ops; |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index d5ee56348bb8..43ab1e1a07a2 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -67,7 +67,7 @@ int inotify_handle_event(struct fsnotify_group *group, | |||
67 | struct fsnotify_mark *inode_mark, | 67 | struct fsnotify_mark *inode_mark, |
68 | struct fsnotify_mark *vfsmount_mark, | 68 | struct fsnotify_mark *vfsmount_mark, |
69 | u32 mask, void *data, int data_type, | 69 | u32 mask, void *data, int data_type, |
70 | const unsigned char *file_name) | 70 | const unsigned char *file_name, u32 cookie) |
71 | { | 71 | { |
72 | struct inotify_inode_mark *i_mark; | 72 | struct inotify_inode_mark *i_mark; |
73 | struct inotify_event_info *event; | 73 | struct inotify_event_info *event; |
@@ -103,6 +103,7 @@ int inotify_handle_event(struct fsnotify_group *group, | |||
103 | fsn_event = &event->fse; | 103 | fsn_event = &event->fse; |
104 | fsnotify_init_event(fsn_event, inode, mask); | 104 | fsnotify_init_event(fsn_event, inode, mask); |
105 | event->wd = i_mark->wd; | 105 | event->wd = i_mark->wd; |
106 | event->sync_cookie = cookie; | ||
106 | event->name_len = len; | 107 | event->name_len = len; |
107 | if (len) | 108 | if (len) |
108 | strcpy(event->name, file_name); | 109 | strcpy(event->name, file_name); |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 497395c8274b..78a2ca3966c3 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -495,7 +495,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, | |||
495 | 495 | ||
496 | /* Queue ignore event for the watch */ | 496 | /* Queue ignore event for the watch */ |
497 | inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED, | 497 | inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED, |
498 | NULL, FSNOTIFY_EVENT_NONE, NULL); | 498 | NULL, FSNOTIFY_EVENT_NONE, NULL, 0); |
499 | 499 | ||
500 | i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); | 500 | i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); |
501 | /* remove this mark from the idr */ | 501 | /* remove this mark from the idr */ |
@@ -633,11 +633,23 @@ static int inotify_update_watch(struct fsnotify_group *group, struct inode *inod | |||
633 | static struct fsnotify_group *inotify_new_group(unsigned int max_events) | 633 | static struct fsnotify_group *inotify_new_group(unsigned int max_events) |
634 | { | 634 | { |
635 | struct fsnotify_group *group; | 635 | struct fsnotify_group *group; |
636 | struct inotify_event_info *oevent; | ||
636 | 637 | ||
637 | group = fsnotify_alloc_group(&inotify_fsnotify_ops); | 638 | group = fsnotify_alloc_group(&inotify_fsnotify_ops); |
638 | if (IS_ERR(group)) | 639 | if (IS_ERR(group)) |
639 | return group; | 640 | return group; |
640 | 641 | ||
642 | oevent = kmalloc(sizeof(struct inotify_event_info), GFP_KERNEL); | ||
643 | if (unlikely(!oevent)) { | ||
644 | fsnotify_destroy_group(group); | ||
645 | return ERR_PTR(-ENOMEM); | ||
646 | } | ||
647 | group->overflow_event = &oevent->fse; | ||
648 | fsnotify_init_event(group->overflow_event, NULL, FS_Q_OVERFLOW); | ||
649 | oevent->wd = -1; | ||
650 | oevent->sync_cookie = 0; | ||
651 | oevent->name_len = 0; | ||
652 | |||
641 | group->max_events = max_events; | 653 | group->max_events = max_events; |
642 | 654 | ||
643 | spin_lock_init(&group->inotify_data.idr_lock); | 655 | spin_lock_init(&group->inotify_data.idr_lock); |
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index 18b3c4427dca..1e58402171a5 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
@@ -80,7 +80,8 @@ void fsnotify_destroy_event(struct fsnotify_group *group, | |||
80 | /* | 80 | /* |
81 | * Add an event to the group notification queue. The group can later pull this | 81 | * Add an event to the group notification queue. The group can later pull this |
82 | * event off the queue to deal with. The function returns 0 if the event was | 82 | * event off the queue to deal with. The function returns 0 if the event was |
83 | * added to the queue, 1 if the event was merged with some other queued event. | 83 | * added to the queue, 1 if the event was merged with some other queued event, |
84 | * 2 if the queue of events has overflown. | ||
84 | */ | 85 | */ |
85 | int fsnotify_add_notify_event(struct fsnotify_group *group, | 86 | int fsnotify_add_notify_event(struct fsnotify_group *group, |
86 | struct fsnotify_event *event, | 87 | struct fsnotify_event *event, |
@@ -95,10 +96,14 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, | |||
95 | mutex_lock(&group->notification_mutex); | 96 | mutex_lock(&group->notification_mutex); |
96 | 97 | ||
97 | if (group->q_len >= group->max_events) { | 98 | if (group->q_len >= group->max_events) { |
99 | ret = 2; | ||
98 | /* Queue overflow event only if it isn't already queued */ | 100 | /* Queue overflow event only if it isn't already queued */ |
99 | if (list_empty(&group->overflow_event.list)) | 101 | if (!list_empty(&group->overflow_event->list)) { |
100 | event = &group->overflow_event; | 102 | mutex_unlock(&group->notification_mutex); |
101 | ret = 1; | 103 | return ret; |
104 | } | ||
105 | event = group->overflow_event; | ||
106 | goto queue; | ||
102 | } | 107 | } |
103 | 108 | ||
104 | if (!list_empty(list) && merge) { | 109 | if (!list_empty(list) && merge) { |
@@ -109,6 +114,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, | |||
109 | } | 114 | } |
110 | } | 115 | } |
111 | 116 | ||
117 | queue: | ||
112 | group->q_len++; | 118 | group->q_len++; |
113 | list_add_tail(&event->list, list); | 119 | list_add_tail(&event->list, list); |
114 | mutex_unlock(&group->notification_mutex); | 120 | mutex_unlock(&group->notification_mutex); |
@@ -132,7 +138,11 @@ struct fsnotify_event *fsnotify_remove_notify_event(struct fsnotify_group *group | |||
132 | 138 | ||
133 | event = list_first_entry(&group->notification_list, | 139 | event = list_first_entry(&group->notification_list, |
134 | struct fsnotify_event, list); | 140 | struct fsnotify_event, list); |
135 | list_del(&event->list); | 141 | /* |
142 | * We need to init list head for the case of overflow event so that | ||
143 | * check in fsnotify_add_notify_events() works | ||
144 | */ | ||
145 | list_del_init(&event->list); | ||
136 | group->q_len--; | 146 | group->q_len--; |
137 | 147 | ||
138 | return event; | 148 | return event; |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 831d49a4111f..cfc8dcc16043 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -581,9 +581,17 @@ int dquot_scan_active(struct super_block *sb, | |||
581 | dqstats_inc(DQST_LOOKUPS); | 581 | dqstats_inc(DQST_LOOKUPS); |
582 | dqput(old_dquot); | 582 | dqput(old_dquot); |
583 | old_dquot = dquot; | 583 | old_dquot = dquot; |
584 | ret = fn(dquot, priv); | 584 | /* |
585 | if (ret < 0) | 585 | * ->release_dquot() can be racing with us. Our reference |
586 | goto out; | 586 | * protects us from new calls to it so just wait for any |
587 | * outstanding call and recheck the DQ_ACTIVE_B after that. | ||
588 | */ | ||
589 | wait_on_dquot(dquot); | ||
590 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | ||
591 | ret = fn(dquot, priv); | ||
592 | if (ret < 0) | ||
593 | goto out; | ||
594 | } | ||
587 | spin_lock(&dq_list_lock); | 595 | spin_lock(&dq_list_lock); |
588 | /* We are safe to continue now because our dquot could not | 596 | /* We are safe to continue now because our dquot could not |
589 | * be moved out of the inuse list while we hold the reference */ | 597 | * be moved out of the inuse list while we hold the reference */ |
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 2b7882b508db..9a3c68cf6026 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
@@ -324,23 +324,17 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
324 | switch (flag) { | 324 | switch (flag) { |
325 | case M_INSERT: /* insert item into L[0] */ | 325 | case M_INSERT: /* insert item into L[0] */ |
326 | 326 | ||
327 | if (item_pos == tb->lnum[0] - 1 | 327 | if (item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) { |
328 | && tb->lbytes != -1) { | ||
329 | /* part of new item falls into L[0] */ | 328 | /* part of new item falls into L[0] */ |
330 | int new_item_len; | 329 | int new_item_len; |
331 | int version; | 330 | int version; |
332 | 331 | ||
333 | ret_val = | 332 | ret_val = leaf_shift_left(tb, tb->lnum[0] - 1, -1); |
334 | leaf_shift_left(tb, tb->lnum[0] - 1, | ||
335 | -1); | ||
336 | 333 | ||
337 | /* Calculate item length to insert to S[0] */ | 334 | /* Calculate item length to insert to S[0] */ |
338 | new_item_len = | 335 | new_item_len = ih_item_len(ih) - tb->lbytes; |
339 | ih_item_len(ih) - tb->lbytes; | ||
340 | /* Calculate and check item length to insert to L[0] */ | 336 | /* Calculate and check item length to insert to L[0] */ |
341 | put_ih_item_len(ih, | 337 | put_ih_item_len(ih, ih_item_len(ih) - new_item_len); |
342 | ih_item_len(ih) - | ||
343 | new_item_len); | ||
344 | 338 | ||
345 | RFALSE(ih_item_len(ih) <= 0, | 339 | RFALSE(ih_item_len(ih) <= 0, |
346 | "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d", | 340 | "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d", |
@@ -349,30 +343,18 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
349 | /* Insert new item into L[0] */ | 343 | /* Insert new item into L[0] */ |
350 | buffer_info_init_left(tb, &bi); | 344 | buffer_info_init_left(tb, &bi); |
351 | leaf_insert_into_buf(&bi, | 345 | leaf_insert_into_buf(&bi, |
352 | n + item_pos - | 346 | n + item_pos - ret_val, ih, body, |
353 | ret_val, ih, body, | 347 | zeros_num > ih_item_len(ih) ? ih_item_len(ih) : zeros_num); |
354 | zeros_num > | ||
355 | ih_item_len(ih) ? | ||
356 | ih_item_len(ih) : | ||
357 | zeros_num); | ||
358 | 348 | ||
359 | version = ih_version(ih); | 349 | version = ih_version(ih); |
360 | 350 | ||
361 | /* Calculate key component, item length and body to insert into S[0] */ | 351 | /* Calculate key component, item length and body to insert into S[0] */ |
362 | set_le_ih_k_offset(ih, | 352 | set_le_ih_k_offset(ih, le_ih_k_offset(ih) + |
363 | le_ih_k_offset(ih) + | 353 | (tb-> lbytes << (is_indirect_le_ih(ih) ? tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT : 0))); |
364 | (tb-> | ||
365 | lbytes << | ||
366 | (is_indirect_le_ih | ||
367 | (ih) ? tb->tb_sb-> | ||
368 | s_blocksize_bits - | ||
369 | UNFM_P_SHIFT : | ||
370 | 0))); | ||
371 | 354 | ||
372 | put_ih_item_len(ih, new_item_len); | 355 | put_ih_item_len(ih, new_item_len); |
373 | if (tb->lbytes > zeros_num) { | 356 | if (tb->lbytes > zeros_num) { |
374 | body += | 357 | body += (tb->lbytes - zeros_num); |
375 | (tb->lbytes - zeros_num); | ||
376 | zeros_num = 0; | 358 | zeros_num = 0; |
377 | } else | 359 | } else |
378 | zeros_num -= tb->lbytes; | 360 | zeros_num -= tb->lbytes; |
@@ -383,15 +365,10 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
383 | } else { | 365 | } else { |
384 | /* new item in whole falls into L[0] */ | 366 | /* new item in whole falls into L[0] */ |
385 | /* Shift lnum[0]-1 items to L[0] */ | 367 | /* Shift lnum[0]-1 items to L[0] */ |
386 | ret_val = | 368 | ret_val = leaf_shift_left(tb, tb->lnum[0] - 1, tb->lbytes); |
387 | leaf_shift_left(tb, tb->lnum[0] - 1, | ||
388 | tb->lbytes); | ||
389 | /* Insert new item into L[0] */ | 369 | /* Insert new item into L[0] */ |
390 | buffer_info_init_left(tb, &bi); | 370 | buffer_info_init_left(tb, &bi); |
391 | leaf_insert_into_buf(&bi, | 371 | leaf_insert_into_buf(&bi, n + item_pos - ret_val, ih, body, zeros_num); |
392 | n + item_pos - | ||
393 | ret_val, ih, body, | ||
394 | zeros_num); | ||
395 | tb->insert_size[0] = 0; | 372 | tb->insert_size[0] = 0; |
396 | zeros_num = 0; | 373 | zeros_num = 0; |
397 | } | 374 | } |
@@ -399,264 +376,117 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
399 | 376 | ||
400 | case M_PASTE: /* append item in L[0] */ | 377 | case M_PASTE: /* append item in L[0] */ |
401 | 378 | ||
402 | if (item_pos == tb->lnum[0] - 1 | 379 | if (item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) { |
403 | && tb->lbytes != -1) { | ||
404 | /* we must shift the part of the appended item */ | 380 | /* we must shift the part of the appended item */ |
405 | if (is_direntry_le_ih | 381 | if (is_direntry_le_ih(B_N_PITEM_HEAD(tbS0, item_pos))) { |
406 | (B_N_PITEM_HEAD(tbS0, item_pos))) { | ||
407 | 382 | ||
408 | RFALSE(zeros_num, | 383 | RFALSE(zeros_num, |
409 | "PAP-12090: invalid parameter in case of a directory"); | 384 | "PAP-12090: invalid parameter in case of a directory"); |
410 | /* directory item */ | 385 | /* directory item */ |
411 | if (tb->lbytes > pos_in_item) { | 386 | if (tb->lbytes > pos_in_item) { |
412 | /* new directory entry falls into L[0] */ | 387 | /* new directory entry falls into L[0] */ |
413 | struct item_head | 388 | struct item_head *pasted; |
414 | *pasted; | 389 | int l_pos_in_item = pos_in_item; |
415 | int l_pos_in_item = | ||
416 | pos_in_item; | ||
417 | 390 | ||
418 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */ | 391 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */ |
419 | ret_val = | 392 | ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes-1); |
420 | leaf_shift_left(tb, | 393 | if (ret_val && !item_pos) { |
421 | tb-> | 394 | pasted = B_N_PITEM_HEAD(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1); |
422 | lnum | 395 | l_pos_in_item += I_ENTRY_COUNT(pasted) - (tb->lbytes -1); |
423 | [0], | ||
424 | tb-> | ||
425 | lbytes | ||
426 | - | ||
427 | 1); | ||
428 | if (ret_val | ||
429 | && !item_pos) { | ||
430 | pasted = | ||
431 | B_N_PITEM_HEAD | ||
432 | (tb->L[0], | ||
433 | B_NR_ITEMS | ||
434 | (tb-> | ||
435 | L[0]) - | ||
436 | 1); | ||
437 | l_pos_in_item += | ||
438 | I_ENTRY_COUNT | ||
439 | (pasted) - | ||
440 | (tb-> | ||
441 | lbytes - | ||
442 | 1); | ||
443 | } | 396 | } |
444 | 397 | ||
445 | /* Append given directory entry to directory item */ | 398 | /* Append given directory entry to directory item */ |
446 | buffer_info_init_left(tb, &bi); | 399 | buffer_info_init_left(tb, &bi); |
447 | leaf_paste_in_buffer | 400 | leaf_paste_in_buffer(&bi, n + item_pos - ret_val, l_pos_in_item, tb->insert_size[0], body, zeros_num); |
448 | (&bi, | ||
449 | n + item_pos - | ||
450 | ret_val, | ||
451 | l_pos_in_item, | ||
452 | tb->insert_size[0], | ||
453 | body, zeros_num); | ||
454 | 401 | ||
455 | /* previous string prepared space for pasting new entry, following string pastes this entry */ | 402 | /* previous string prepared space for pasting new entry, following string pastes this entry */ |
456 | 403 | ||
457 | /* when we have merge directory item, pos_in_item has been changed too */ | 404 | /* when we have merge directory item, pos_in_item has been changed too */ |
458 | 405 | ||
459 | /* paste new directory entry. 1 is entry number */ | 406 | /* paste new directory entry. 1 is entry number */ |
460 | leaf_paste_entries(&bi, | 407 | leaf_paste_entries(&bi, n + item_pos - ret_val, l_pos_in_item, |
461 | n + | 408 | 1, (struct reiserfs_de_head *) body, |
462 | item_pos | 409 | body + DEH_SIZE, tb->insert_size[0]); |
463 | - | ||
464 | ret_val, | ||
465 | l_pos_in_item, | ||
466 | 1, | ||
467 | (struct | ||
468 | reiserfs_de_head | ||
469 | *) | ||
470 | body, | ||
471 | body | ||
472 | + | ||
473 | DEH_SIZE, | ||
474 | tb-> | ||
475 | insert_size | ||
476 | [0] | ||
477 | ); | ||
478 | tb->insert_size[0] = 0; | 410 | tb->insert_size[0] = 0; |
479 | } else { | 411 | } else { |
480 | /* new directory item doesn't fall into L[0] */ | 412 | /* new directory item doesn't fall into L[0] */ |
481 | /* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */ | 413 | /* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */ |
482 | leaf_shift_left(tb, | 414 | leaf_shift_left(tb, tb->lnum[0], tb->lbytes); |
483 | tb-> | ||
484 | lnum[0], | ||
485 | tb-> | ||
486 | lbytes); | ||
487 | } | 415 | } |
488 | /* Calculate new position to append in item body */ | 416 | /* Calculate new position to append in item body */ |
489 | pos_in_item -= tb->lbytes; | 417 | pos_in_item -= tb->lbytes; |
490 | } else { | 418 | } else { |
491 | /* regular object */ | 419 | /* regular object */ |
492 | RFALSE(tb->lbytes <= 0, | 420 | RFALSE(tb->lbytes <= 0, "PAP-12095: there is nothing to shift to L[0]. lbytes=%d", tb->lbytes); |
493 | "PAP-12095: there is nothing to shift to L[0]. lbytes=%d", | 421 | RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)), |
494 | tb->lbytes); | ||
495 | RFALSE(pos_in_item != | ||
496 | ih_item_len | ||
497 | (B_N_PITEM_HEAD | ||
498 | (tbS0, item_pos)), | ||
499 | "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d", | 422 | "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d", |
500 | ih_item_len | 423 | ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)),pos_in_item); |
501 | (B_N_PITEM_HEAD | ||
502 | (tbS0, item_pos)), | ||
503 | pos_in_item); | ||
504 | 424 | ||
505 | if (tb->lbytes >= pos_in_item) { | 425 | if (tb->lbytes >= pos_in_item) { |
506 | /* appended item will be in L[0] in whole */ | 426 | /* appended item will be in L[0] in whole */ |
507 | int l_n; | 427 | int l_n; |
508 | 428 | ||
509 | /* this bytes number must be appended to the last item of L[h] */ | 429 | /* this bytes number must be appended to the last item of L[h] */ |
510 | l_n = | 430 | l_n = tb->lbytes - pos_in_item; |
511 | tb->lbytes - | ||
512 | pos_in_item; | ||
513 | 431 | ||
514 | /* Calculate new insert_size[0] */ | 432 | /* Calculate new insert_size[0] */ |
515 | tb->insert_size[0] -= | 433 | tb->insert_size[0] -= l_n; |
516 | l_n; | ||
517 | 434 | ||
518 | RFALSE(tb-> | 435 | RFALSE(tb->insert_size[0] <= 0, |
519 | insert_size[0] <= | ||
520 | 0, | ||
521 | "PAP-12105: there is nothing to paste into L[0]. insert_size=%d", | 436 | "PAP-12105: there is nothing to paste into L[0]. insert_size=%d", |
522 | tb-> | 437 | tb->insert_size[0]); |
523 | insert_size[0]); | 438 | ret_val = leaf_shift_left(tb, tb->lnum[0], ih_item_len |
524 | ret_val = | 439 | (B_N_PITEM_HEAD(tbS0, item_pos))); |
525 | leaf_shift_left(tb, | ||
526 | tb-> | ||
527 | lnum | ||
528 | [0], | ||
529 | ih_item_len | ||
530 | (B_N_PITEM_HEAD | ||
531 | (tbS0, | ||
532 | item_pos))); | ||
533 | /* Append to body of item in L[0] */ | 440 | /* Append to body of item in L[0] */ |
534 | buffer_info_init_left(tb, &bi); | 441 | buffer_info_init_left(tb, &bi); |
535 | leaf_paste_in_buffer | 442 | leaf_paste_in_buffer |
536 | (&bi, | 443 | (&bi, n + item_pos - ret_val, ih_item_len |
537 | n + item_pos - | 444 | (B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val)), |
538 | ret_val, | 445 | l_n, body, |
539 | ih_item_len | 446 | zeros_num > l_n ? l_n : zeros_num); |
540 | (B_N_PITEM_HEAD | ||
541 | (tb->L[0], | ||
542 | n + item_pos - | ||
543 | ret_val)), l_n, | ||
544 | body, | ||
545 | zeros_num > | ||
546 | l_n ? l_n : | ||
547 | zeros_num); | ||
548 | /* 0-th item in S0 can be only of DIRECT type when l_n != 0 */ | 447 | /* 0-th item in S0 can be only of DIRECT type when l_n != 0 */ |
549 | { | 448 | { |
550 | int version; | 449 | int version; |
551 | int temp_l = | 450 | int temp_l = l_n; |
552 | l_n; | 451 | |
553 | 452 | RFALSE(ih_item_len(B_N_PITEM_HEAD(tbS0, 0)), | |
554 | RFALSE | ||
555 | (ih_item_len | ||
556 | (B_N_PITEM_HEAD | ||
557 | (tbS0, | ||
558 | 0)), | ||
559 | "PAP-12106: item length must be 0"); | 453 | "PAP-12106: item length must be 0"); |
560 | RFALSE | 454 | RFALSE(comp_short_le_keys(B_N_PKEY(tbS0, 0), B_N_PKEY |
561 | (comp_short_le_keys | 455 | (tb->L[0], n + item_pos - ret_val)), |
562 | (B_N_PKEY | ||
563 | (tbS0, 0), | ||
564 | B_N_PKEY | ||
565 | (tb->L[0], | ||
566 | n + | ||
567 | item_pos | ||
568 | - | ||
569 | ret_val)), | ||
570 | "PAP-12107: items must be of the same file"); | 456 | "PAP-12107: items must be of the same file"); |
571 | if (is_indirect_le_ih(B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val))) { | 457 | if (is_indirect_le_ih(B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val))) { |
572 | temp_l = | 458 | temp_l = l_n << (tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT); |
573 | l_n | ||
574 | << | ||
575 | (tb-> | ||
576 | tb_sb-> | ||
577 | s_blocksize_bits | ||
578 | - | ||
579 | UNFM_P_SHIFT); | ||
580 | } | 459 | } |
581 | /* update key of first item in S0 */ | 460 | /* update key of first item in S0 */ |
582 | version = | 461 | version = ih_version(B_N_PITEM_HEAD(tbS0, 0)); |
583 | ih_version | 462 | set_le_key_k_offset(version, B_N_PKEY(tbS0, 0), |
584 | (B_N_PITEM_HEAD | 463 | le_key_k_offset(version,B_N_PKEY(tbS0, 0)) + temp_l); |
585 | (tbS0, 0)); | ||
586 | set_le_key_k_offset | ||
587 | (version, | ||
588 | B_N_PKEY | ||
589 | (tbS0, 0), | ||
590 | le_key_k_offset | ||
591 | (version, | ||
592 | B_N_PKEY | ||
593 | (tbS0, | ||
594 | 0)) + | ||
595 | temp_l); | ||
596 | /* update left delimiting key */ | 464 | /* update left delimiting key */ |
597 | set_le_key_k_offset | 465 | set_le_key_k_offset(version, B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0]), |
598 | (version, | 466 | le_key_k_offset(version, B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0])) + temp_l); |
599 | B_N_PDELIM_KEY | ||
600 | (tb-> | ||
601 | CFL[0], | ||
602 | tb-> | ||
603 | lkey[0]), | ||
604 | le_key_k_offset | ||
605 | (version, | ||
606 | B_N_PDELIM_KEY | ||
607 | (tb-> | ||
608 | CFL[0], | ||
609 | tb-> | ||
610 | lkey[0])) | ||
611 | + temp_l); | ||
612 | } | 467 | } |
613 | 468 | ||
614 | /* Calculate new body, position in item and insert_size[0] */ | 469 | /* Calculate new body, position in item and insert_size[0] */ |
615 | if (l_n > zeros_num) { | 470 | if (l_n > zeros_num) { |
616 | body += | 471 | body += (l_n - zeros_num); |
617 | (l_n - | ||
618 | zeros_num); | ||
619 | zeros_num = 0; | 472 | zeros_num = 0; |
620 | } else | 473 | } else |
621 | zeros_num -= | 474 | zeros_num -= l_n; |
622 | l_n; | ||
623 | pos_in_item = 0; | 475 | pos_in_item = 0; |
624 | 476 | ||
625 | RFALSE | 477 | RFALSE(comp_short_le_keys(B_N_PKEY(tbS0, 0), B_N_PKEY(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1)) |
626 | (comp_short_le_keys | 478 | || !op_is_left_mergeable(B_N_PKEY(tbS0, 0), tbS0->b_size) |
627 | (B_N_PKEY(tbS0, 0), | 479 | || !op_is_left_mergeable(B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0]), tbS0->b_size), |
628 | B_N_PKEY(tb->L[0], | ||
629 | B_NR_ITEMS | ||
630 | (tb-> | ||
631 | L[0]) - | ||
632 | 1)) | ||
633 | || | ||
634 | !op_is_left_mergeable | ||
635 | (B_N_PKEY(tbS0, 0), | ||
636 | tbS0->b_size) | ||
637 | || | ||
638 | !op_is_left_mergeable | ||
639 | (B_N_PDELIM_KEY | ||
640 | (tb->CFL[0], | ||
641 | tb->lkey[0]), | ||
642 | tbS0->b_size), | ||
643 | "PAP-12120: item must be merge-able with left neighboring item"); | 480 | "PAP-12120: item must be merge-able with left neighboring item"); |
644 | } else { /* only part of the appended item will be in L[0] */ | 481 | } else { /* only part of the appended item will be in L[0] */ |
645 | 482 | ||
646 | /* Calculate position in item for append in S[0] */ | 483 | /* Calculate position in item for append in S[0] */ |
647 | pos_in_item -= | 484 | pos_in_item -= tb->lbytes; |
648 | tb->lbytes; | ||
649 | 485 | ||
650 | RFALSE(pos_in_item <= 0, | 486 | RFALSE(pos_in_item <= 0, "PAP-12125: no place for paste. pos_in_item=%d", pos_in_item); |
651 | "PAP-12125: no place for paste. pos_in_item=%d", | ||
652 | pos_in_item); | ||
653 | 487 | ||
654 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */ | 488 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */ |
655 | leaf_shift_left(tb, | 489 | leaf_shift_left(tb, tb->lnum[0], tb->lbytes); |
656 | tb-> | ||
657 | lnum[0], | ||
658 | tb-> | ||
659 | lbytes); | ||
660 | } | 490 | } |
661 | } | 491 | } |
662 | } else { /* appended item will be in L[0] in whole */ | 492 | } else { /* appended item will be in L[0] in whole */ |
@@ -665,52 +495,30 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
665 | 495 | ||
666 | if (!item_pos && op_is_left_mergeable(B_N_PKEY(tbS0, 0), tbS0->b_size)) { /* if we paste into first item of S[0] and it is left mergable */ | 496 | if (!item_pos && op_is_left_mergeable(B_N_PKEY(tbS0, 0), tbS0->b_size)) { /* if we paste into first item of S[0] and it is left mergable */ |
667 | /* then increment pos_in_item by the size of the last item in L[0] */ | 497 | /* then increment pos_in_item by the size of the last item in L[0] */ |
668 | pasted = | 498 | pasted = B_N_PITEM_HEAD(tb->L[0], n - 1); |
669 | B_N_PITEM_HEAD(tb->L[0], | ||
670 | n - 1); | ||
671 | if (is_direntry_le_ih(pasted)) | 499 | if (is_direntry_le_ih(pasted)) |
672 | pos_in_item += | 500 | pos_in_item += ih_entry_count(pasted); |
673 | ih_entry_count | ||
674 | (pasted); | ||
675 | else | 501 | else |
676 | pos_in_item += | 502 | pos_in_item += ih_item_len(pasted); |
677 | ih_item_len(pasted); | ||
678 | } | 503 | } |
679 | 504 | ||
680 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */ | 505 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */ |
681 | ret_val = | 506 | ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes); |
682 | leaf_shift_left(tb, tb->lnum[0], | ||
683 | tb->lbytes); | ||
684 | /* Append to body of item in L[0] */ | 507 | /* Append to body of item in L[0] */ |
685 | buffer_info_init_left(tb, &bi); | 508 | buffer_info_init_left(tb, &bi); |
686 | leaf_paste_in_buffer(&bi, | 509 | leaf_paste_in_buffer(&bi, n + item_pos - ret_val, |
687 | n + item_pos - | ||
688 | ret_val, | ||
689 | pos_in_item, | 510 | pos_in_item, |
690 | tb->insert_size[0], | 511 | tb->insert_size[0], |
691 | body, zeros_num); | 512 | body, zeros_num); |
692 | 513 | ||
693 | /* if appended item is directory, paste entry */ | 514 | /* if appended item is directory, paste entry */ |
694 | pasted = | 515 | pasted = B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val); |
695 | B_N_PITEM_HEAD(tb->L[0], | ||
696 | n + item_pos - | ||
697 | ret_val); | ||
698 | if (is_direntry_le_ih(pasted)) | 516 | if (is_direntry_le_ih(pasted)) |
699 | leaf_paste_entries(&bi, | 517 | leaf_paste_entries(&bi, n + item_pos - ret_val, |
700 | n + | 518 | pos_in_item, 1, |
701 | item_pos - | 519 | (struct reiserfs_de_head *) body, |
702 | ret_val, | 520 | body + DEH_SIZE, |
703 | pos_in_item, | 521 | tb->insert_size[0]); |
704 | 1, | ||
705 | (struct | ||
706 | reiserfs_de_head | ||
707 | *)body, | ||
708 | body + | ||
709 | DEH_SIZE, | ||
710 | tb-> | ||
711 | insert_size | ||
712 | [0] | ||
713 | ); | ||
714 | /* if appended item is indirect item, put unformatted node into un list */ | 522 | /* if appended item is indirect item, put unformatted node into un list */ |
715 | if (is_indirect_le_ih(pasted)) | 523 | if (is_indirect_le_ih(pasted)) |
716 | set_ih_free_space(pasted, 0); | 524 | set_ih_free_space(pasted, 0); |
@@ -722,13 +530,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
722 | reiserfs_panic(tb->tb_sb, "PAP-12130", | 530 | reiserfs_panic(tb->tb_sb, "PAP-12130", |
723 | "lnum > 0: unexpected mode: " | 531 | "lnum > 0: unexpected mode: " |
724 | " %s(%d)", | 532 | " %s(%d)", |
725 | (flag == | 533 | (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag); |
726 | M_DELETE) ? "DELETE" : ((flag == | ||
727 | M_CUT) | ||
728 | ? "CUT" | ||
729 | : | ||
730 | "UNKNOWN"), | ||
731 | flag); | ||
732 | } | 534 | } |
733 | } else { | 535 | } else { |
734 | /* new item doesn't fall into L[0] */ | 536 | /* new item doesn't fall into L[0] */ |
@@ -748,14 +550,12 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
748 | case M_INSERT: /* insert item */ | 550 | case M_INSERT: /* insert item */ |
749 | if (n - tb->rnum[0] < item_pos) { /* new item or its part falls to R[0] */ | 551 | if (n - tb->rnum[0] < item_pos) { /* new item or its part falls to R[0] */ |
750 | if (item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1) { /* part of new item falls into R[0] */ | 552 | if (item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1) { /* part of new item falls into R[0] */ |
751 | loff_t old_key_comp, old_len, | 553 | loff_t old_key_comp, old_len, r_zeros_number; |
752 | r_zeros_number; | ||
753 | const char *r_body; | 554 | const char *r_body; |
754 | int version; | 555 | int version; |
755 | loff_t offset; | 556 | loff_t offset; |
756 | 557 | ||
757 | leaf_shift_right(tb, tb->rnum[0] - 1, | 558 | leaf_shift_right(tb, tb->rnum[0] - 1, -1); |
758 | -1); | ||
759 | 559 | ||
760 | version = ih_version(ih); | 560 | version = ih_version(ih); |
761 | /* Remember key component and item length */ | 561 | /* Remember key component and item length */ |
@@ -763,29 +563,17 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
763 | old_len = ih_item_len(ih); | 563 | old_len = ih_item_len(ih); |
764 | 564 | ||
765 | /* Calculate key component and item length to insert into R[0] */ | 565 | /* Calculate key component and item length to insert into R[0] */ |
766 | offset = | 566 | offset = le_ih_k_offset(ih) + ((old_len - tb->rbytes) << (is_indirect_le_ih(ih) ? tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT : 0)); |
767 | le_ih_k_offset(ih) + | ||
768 | ((old_len - | ||
769 | tb-> | ||
770 | rbytes) << (is_indirect_le_ih(ih) | ||
771 | ? tb->tb_sb-> | ||
772 | s_blocksize_bits - | ||
773 | UNFM_P_SHIFT : 0)); | ||
774 | set_le_ih_k_offset(ih, offset); | 567 | set_le_ih_k_offset(ih, offset); |
775 | put_ih_item_len(ih, tb->rbytes); | 568 | put_ih_item_len(ih, tb->rbytes); |
776 | /* Insert part of the item into R[0] */ | 569 | /* Insert part of the item into R[0] */ |
777 | buffer_info_init_right(tb, &bi); | 570 | buffer_info_init_right(tb, &bi); |
778 | if ((old_len - tb->rbytes) > zeros_num) { | 571 | if ((old_len - tb->rbytes) > zeros_num) { |
779 | r_zeros_number = 0; | 572 | r_zeros_number = 0; |
780 | r_body = | 573 | r_body = body + (old_len - tb->rbytes) - zeros_num; |
781 | body + (old_len - | ||
782 | tb->rbytes) - | ||
783 | zeros_num; | ||
784 | } else { | 574 | } else { |
785 | r_body = body; | 575 | r_body = body; |
786 | r_zeros_number = | 576 | r_zeros_number = zeros_num - (old_len - tb->rbytes); |
787 | zeros_num - (old_len - | ||
788 | tb->rbytes); | ||
789 | zeros_num -= r_zeros_number; | 577 | zeros_num -= r_zeros_number; |
790 | } | 578 | } |
791 | 579 | ||
@@ -798,25 +586,18 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
798 | 586 | ||
799 | /* Calculate key component and item length to insert into S[0] */ | 587 | /* Calculate key component and item length to insert into S[0] */ |
800 | set_le_ih_k_offset(ih, old_key_comp); | 588 | set_le_ih_k_offset(ih, old_key_comp); |
801 | put_ih_item_len(ih, | 589 | put_ih_item_len(ih, old_len - tb->rbytes); |
802 | old_len - tb->rbytes); | ||
803 | 590 | ||
804 | tb->insert_size[0] -= tb->rbytes; | 591 | tb->insert_size[0] -= tb->rbytes; |
805 | 592 | ||
806 | } else { /* whole new item falls into R[0] */ | 593 | } else { /* whole new item falls into R[0] */ |
807 | 594 | ||
808 | /* Shift rnum[0]-1 items to R[0] */ | 595 | /* Shift rnum[0]-1 items to R[0] */ |
809 | ret_val = | 596 | ret_val = leaf_shift_right(tb, tb->rnum[0] - 1, tb->rbytes); |
810 | leaf_shift_right(tb, | ||
811 | tb->rnum[0] - 1, | ||
812 | tb->rbytes); | ||
813 | /* Insert new item into R[0] */ | 597 | /* Insert new item into R[0] */ |
814 | buffer_info_init_right(tb, &bi); | 598 | buffer_info_init_right(tb, &bi); |
815 | leaf_insert_into_buf(&bi, | 599 | leaf_insert_into_buf(&bi, item_pos - n + tb->rnum[0] - 1, |
816 | item_pos - n + | 600 | ih, body, zeros_num); |
817 | tb->rnum[0] - 1, | ||
818 | ih, body, | ||
819 | zeros_num); | ||
820 | 601 | ||
821 | if (item_pos - n + tb->rnum[0] - 1 == 0) { | 602 | if (item_pos - n + tb->rnum[0] - 1 == 0) { |
822 | replace_key(tb, tb->CFR[0], | 603 | replace_key(tb, tb->CFR[0], |
@@ -841,200 +622,97 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
841 | 622 | ||
842 | RFALSE(zeros_num, | 623 | RFALSE(zeros_num, |
843 | "PAP-12145: invalid parameter in case of a directory"); | 624 | "PAP-12145: invalid parameter in case of a directory"); |
844 | entry_count = | 625 | entry_count = I_ENTRY_COUNT(B_N_PITEM_HEAD |
845 | I_ENTRY_COUNT(B_N_PITEM_HEAD | 626 | (tbS0, item_pos)); |
846 | (tbS0, | ||
847 | item_pos)); | ||
848 | if (entry_count - tb->rbytes < | 627 | if (entry_count - tb->rbytes < |
849 | pos_in_item) | 628 | pos_in_item) |
850 | /* new directory entry falls into R[0] */ | 629 | /* new directory entry falls into R[0] */ |
851 | { | 630 | { |
852 | int paste_entry_position; | 631 | int paste_entry_position; |
853 | 632 | ||
854 | RFALSE(tb->rbytes - 1 >= | 633 | RFALSE(tb->rbytes - 1 >= entry_count || !tb-> insert_size[0], |
855 | entry_count | ||
856 | || !tb-> | ||
857 | insert_size[0], | ||
858 | "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d", | 634 | "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d", |
859 | tb->rbytes, | 635 | tb->rbytes, entry_count); |
860 | entry_count); | ||
861 | /* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */ | 636 | /* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */ |
862 | leaf_shift_right(tb, | 637 | leaf_shift_right(tb, tb->rnum[0], tb->rbytes - 1); |
863 | tb-> | ||
864 | rnum | ||
865 | [0], | ||
866 | tb-> | ||
867 | rbytes | ||
868 | - 1); | ||
869 | /* Paste given directory entry to directory item */ | 638 | /* Paste given directory entry to directory item */ |
870 | paste_entry_position = | 639 | paste_entry_position = pos_in_item - entry_count + tb->rbytes - 1; |
871 | pos_in_item - | ||
872 | entry_count + | ||
873 | tb->rbytes - 1; | ||
874 | buffer_info_init_right(tb, &bi); | 640 | buffer_info_init_right(tb, &bi); |
875 | leaf_paste_in_buffer | 641 | leaf_paste_in_buffer(&bi, 0, paste_entry_position, tb->insert_size[0], body, zeros_num); |
876 | (&bi, 0, | ||
877 | paste_entry_position, | ||
878 | tb->insert_size[0], | ||
879 | body, zeros_num); | ||
880 | /* paste entry */ | 642 | /* paste entry */ |
881 | leaf_paste_entries(&bi, | 643 | leaf_paste_entries(&bi, 0, paste_entry_position, 1, |
882 | 0, | 644 | (struct reiserfs_de_head *) body, |
883 | paste_entry_position, | 645 | body + DEH_SIZE, tb->insert_size[0]); |
884 | 1, | 646 | |
885 | (struct | 647 | if (paste_entry_position == 0) { |
886 | reiserfs_de_head | ||
887 | *) | ||
888 | body, | ||
889 | body | ||
890 | + | ||
891 | DEH_SIZE, | ||
892 | tb-> | ||
893 | insert_size | ||
894 | [0] | ||
895 | ); | ||
896 | |||
897 | if (paste_entry_position | ||
898 | == 0) { | ||
899 | /* change delimiting keys */ | 648 | /* change delimiting keys */ |
900 | replace_key(tb, | 649 | replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0],0); |
901 | tb-> | ||
902 | CFR | ||
903 | [0], | ||
904 | tb-> | ||
905 | rkey | ||
906 | [0], | ||
907 | tb-> | ||
908 | R | ||
909 | [0], | ||
910 | 0); | ||
911 | } | 650 | } |
912 | 651 | ||
913 | tb->insert_size[0] = 0; | 652 | tb->insert_size[0] = 0; |
914 | pos_in_item++; | 653 | pos_in_item++; |
915 | } else { /* new directory entry doesn't fall into R[0] */ | 654 | } else { /* new directory entry doesn't fall into R[0] */ |
916 | 655 | ||
917 | leaf_shift_right(tb, | 656 | leaf_shift_right(tb, tb->rnum[0], tb->rbytes); |
918 | tb-> | ||
919 | rnum | ||
920 | [0], | ||
921 | tb-> | ||
922 | rbytes); | ||
923 | } | 657 | } |
924 | } else { /* regular object */ | 658 | } else { /* regular object */ |
925 | 659 | ||
926 | int n_shift, n_rem, | 660 | int n_shift, n_rem, r_zeros_number; |
927 | r_zeros_number; | ||
928 | const char *r_body; | 661 | const char *r_body; |
929 | 662 | ||
930 | /* Calculate number of bytes which must be shifted from appended item */ | 663 | /* Calculate number of bytes which must be shifted from appended item */ |
931 | if ((n_shift = | 664 | if ((n_shift = tb->rbytes - tb->insert_size[0]) < 0) |
932 | tb->rbytes - | ||
933 | tb->insert_size[0]) < 0) | ||
934 | n_shift = 0; | 665 | n_shift = 0; |
935 | 666 | ||
936 | RFALSE(pos_in_item != | 667 | RFALSE(pos_in_item != ih_item_len |
937 | ih_item_len | 668 | (B_N_PITEM_HEAD(tbS0, item_pos)), |
938 | (B_N_PITEM_HEAD | ||
939 | (tbS0, item_pos)), | ||
940 | "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d", | 669 | "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d", |
941 | pos_in_item, | 670 | pos_in_item, ih_item_len |
942 | ih_item_len | 671 | (B_N_PITEM_HEAD(tbS0, item_pos))); |
943 | (B_N_PITEM_HEAD | 672 | |
944 | (tbS0, item_pos))); | 673 | leaf_shift_right(tb, tb->rnum[0], n_shift); |
945 | |||
946 | leaf_shift_right(tb, | ||
947 | tb->rnum[0], | ||
948 | n_shift); | ||
949 | /* Calculate number of bytes which must remain in body after appending to R[0] */ | 674 | /* Calculate number of bytes which must remain in body after appending to R[0] */ |
950 | if ((n_rem = | 675 | if ((n_rem = tb->insert_size[0] - tb->rbytes) < 0) |
951 | tb->insert_size[0] - | ||
952 | tb->rbytes) < 0) | ||
953 | n_rem = 0; | 676 | n_rem = 0; |
954 | 677 | ||
955 | { | 678 | { |
956 | int version; | 679 | int version; |
957 | unsigned long temp_rem = | 680 | unsigned long temp_rem = n_rem; |
958 | n_rem; | 681 | |
959 | 682 | version = ih_version(B_N_PITEM_HEAD(tb->R[0], 0)); | |
960 | version = | 683 | if (is_indirect_le_key(version, B_N_PKEY(tb->R[0], 0))) { |
961 | ih_version | 684 | temp_rem = n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT); |
962 | (B_N_PITEM_HEAD | ||
963 | (tb->R[0], 0)); | ||
964 | if (is_indirect_le_key | ||
965 | (version, | ||
966 | B_N_PKEY(tb->R[0], | ||
967 | 0))) { | ||
968 | temp_rem = | ||
969 | n_rem << | ||
970 | (tb->tb_sb-> | ||
971 | s_blocksize_bits | ||
972 | - | ||
973 | UNFM_P_SHIFT); | ||
974 | } | 685 | } |
975 | set_le_key_k_offset | 686 | set_le_key_k_offset(version, B_N_PKEY(tb->R[0], 0), |
976 | (version, | 687 | le_key_k_offset(version, B_N_PKEY(tb->R[0], 0)) + temp_rem); |
977 | B_N_PKEY(tb->R[0], | 688 | set_le_key_k_offset(version, B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0]), |
978 | 0), | 689 | le_key_k_offset(version, B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0])) + temp_rem); |
979 | le_key_k_offset | ||
980 | (version, | ||
981 | B_N_PKEY(tb->R[0], | ||
982 | 0)) + | ||
983 | temp_rem); | ||
984 | set_le_key_k_offset | ||
985 | (version, | ||
986 | B_N_PDELIM_KEY(tb-> | ||
987 | CFR | ||
988 | [0], | ||
989 | tb-> | ||
990 | rkey | ||
991 | [0]), | ||
992 | le_key_k_offset | ||
993 | (version, | ||
994 | B_N_PDELIM_KEY | ||
995 | (tb->CFR[0], | ||
996 | tb->rkey[0])) + | ||
997 | temp_rem); | ||
998 | } | 690 | } |
999 | /* k_offset (B_N_PKEY(tb->R[0],0)) += n_rem; | 691 | /* k_offset (B_N_PKEY(tb->R[0],0)) += n_rem; |
1000 | k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/ | 692 | k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/ |
1001 | do_balance_mark_internal_dirty | 693 | do_balance_mark_internal_dirty(tb, tb->CFR[0], 0); |
1002 | (tb, tb->CFR[0], 0); | ||
1003 | 694 | ||
1004 | /* Append part of body into R[0] */ | 695 | /* Append part of body into R[0] */ |
1005 | buffer_info_init_right(tb, &bi); | 696 | buffer_info_init_right(tb, &bi); |
1006 | if (n_rem > zeros_num) { | 697 | if (n_rem > zeros_num) { |
1007 | r_zeros_number = 0; | 698 | r_zeros_number = 0; |
1008 | r_body = | 699 | r_body = body + n_rem - zeros_num; |
1009 | body + n_rem - | ||
1010 | zeros_num; | ||
1011 | } else { | 700 | } else { |
1012 | r_body = body; | 701 | r_body = body; |
1013 | r_zeros_number = | 702 | r_zeros_number = zeros_num - n_rem; |
1014 | zeros_num - n_rem; | 703 | zeros_num -= r_zeros_number; |
1015 | zeros_num -= | ||
1016 | r_zeros_number; | ||
1017 | } | 704 | } |
1018 | 705 | ||
1019 | leaf_paste_in_buffer(&bi, 0, | 706 | leaf_paste_in_buffer(&bi, 0, n_shift, |
1020 | n_shift, | 707 | tb->insert_size[0] - n_rem, |
1021 | tb-> | 708 | r_body, r_zeros_number); |
1022 | insert_size | 709 | |
1023 | [0] - | 710 | if (is_indirect_le_ih(B_N_PITEM_HEAD(tb->R[0], 0))) { |
1024 | n_rem, | ||
1025 | r_body, | ||
1026 | r_zeros_number); | ||
1027 | |||
1028 | if (is_indirect_le_ih | ||
1029 | (B_N_PITEM_HEAD | ||
1030 | (tb->R[0], 0))) { | ||
1031 | #if 0 | 711 | #if 0 |
1032 | RFALSE(n_rem, | 712 | RFALSE(n_rem, |
1033 | "PAP-12160: paste more than one unformatted node pointer"); | 713 | "PAP-12160: paste more than one unformatted node pointer"); |
1034 | #endif | 714 | #endif |
1035 | set_ih_free_space | 715 | set_ih_free_space(B_N_PITEM_HEAD(tb->R[0], 0), 0); |
1036 | (B_N_PITEM_HEAD | ||
1037 | (tb->R[0], 0), 0); | ||
1038 | } | 716 | } |
1039 | tb->insert_size[0] = n_rem; | 717 | tb->insert_size[0] = n_rem; |
1040 | if (!n_rem) | 718 | if (!n_rem) |
@@ -1044,58 +722,28 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1044 | 722 | ||
1045 | struct item_head *pasted; | 723 | struct item_head *pasted; |
1046 | 724 | ||
1047 | ret_val = | 725 | ret_val = leaf_shift_right(tb, tb->rnum[0], tb->rbytes); |
1048 | leaf_shift_right(tb, tb->rnum[0], | ||
1049 | tb->rbytes); | ||
1050 | /* append item in R[0] */ | 726 | /* append item in R[0] */ |
1051 | if (pos_in_item >= 0) { | 727 | if (pos_in_item >= 0) { |
1052 | buffer_info_init_right(tb, &bi); | 728 | buffer_info_init_right(tb, &bi); |
1053 | leaf_paste_in_buffer(&bi, | 729 | leaf_paste_in_buffer(&bi, item_pos - n + tb->rnum[0], pos_in_item, |
1054 | item_pos - | 730 | tb->insert_size[0], body, zeros_num); |
1055 | n + | ||
1056 | tb-> | ||
1057 | rnum[0], | ||
1058 | pos_in_item, | ||
1059 | tb-> | ||
1060 | insert_size | ||
1061 | [0], body, | ||
1062 | zeros_num); | ||
1063 | } | 731 | } |
1064 | 732 | ||
1065 | /* paste new entry, if item is directory item */ | 733 | /* paste new entry, if item is directory item */ |
1066 | pasted = | 734 | pasted = B_N_PITEM_HEAD(tb->R[0], item_pos - n + tb->rnum[0]); |
1067 | B_N_PITEM_HEAD(tb->R[0], | 735 | if (is_direntry_le_ih(pasted) && pos_in_item >= 0) { |
1068 | item_pos - n + | 736 | leaf_paste_entries(&bi, item_pos - n + tb->rnum[0], |
1069 | tb->rnum[0]); | 737 | pos_in_item, 1, |
1070 | if (is_direntry_le_ih(pasted) | 738 | (struct reiserfs_de_head *) body, |
1071 | && pos_in_item >= 0) { | 739 | body + DEH_SIZE, tb->insert_size[0]); |
1072 | leaf_paste_entries(&bi, | ||
1073 | item_pos - | ||
1074 | n + | ||
1075 | tb->rnum[0], | ||
1076 | pos_in_item, | ||
1077 | 1, | ||
1078 | (struct | ||
1079 | reiserfs_de_head | ||
1080 | *)body, | ||
1081 | body + | ||
1082 | DEH_SIZE, | ||
1083 | tb-> | ||
1084 | insert_size | ||
1085 | [0] | ||
1086 | ); | ||
1087 | if (!pos_in_item) { | 740 | if (!pos_in_item) { |
1088 | 741 | ||
1089 | RFALSE(item_pos - n + | 742 | RFALSE(item_pos - n + tb->rnum[0], |
1090 | tb->rnum[0], | ||
1091 | "PAP-12165: directory item must be first item of node when pasting is in 0th position"); | 743 | "PAP-12165: directory item must be first item of node when pasting is in 0th position"); |
1092 | 744 | ||
1093 | /* update delimiting keys */ | 745 | /* update delimiting keys */ |
1094 | replace_key(tb, | 746 | replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0); |
1095 | tb->CFR[0], | ||
1096 | tb->rkey[0], | ||
1097 | tb->R[0], | ||
1098 | 0); | ||
1099 | } | 747 | } |
1100 | } | 748 | } |
1101 | 749 | ||
@@ -1111,22 +759,16 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1111 | default: /* cases d and t */ | 759 | default: /* cases d and t */ |
1112 | reiserfs_panic(tb->tb_sb, "PAP-12175", | 760 | reiserfs_panic(tb->tb_sb, "PAP-12175", |
1113 | "rnum > 0: unexpected mode: %s(%d)", | 761 | "rnum > 0: unexpected mode: %s(%d)", |
1114 | (flag == | 762 | (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag); |
1115 | M_DELETE) ? "DELETE" : ((flag == | ||
1116 | M_CUT) ? "CUT" | ||
1117 | : "UNKNOWN"), | ||
1118 | flag); | ||
1119 | } | 763 | } |
1120 | 764 | ||
1121 | } | 765 | } |
1122 | 766 | ||
1123 | /* tb->rnum[0] > 0 */ | 767 | /* tb->rnum[0] > 0 */ |
1124 | RFALSE(tb->blknum[0] > 3, | 768 | RFALSE(tb->blknum[0] > 3, |
1125 | "PAP-12180: blknum can not be %d. It must be <= 3", | 769 | "PAP-12180: blknum can not be %d. It must be <= 3", tb->blknum[0]); |
1126 | tb->blknum[0]); | ||
1127 | RFALSE(tb->blknum[0] < 0, | 770 | RFALSE(tb->blknum[0] < 0, |
1128 | "PAP-12185: blknum can not be %d. It must be >= 0", | 771 | "PAP-12185: blknum can not be %d. It must be >= 0", tb->blknum[0]); |
1129 | tb->blknum[0]); | ||
1130 | 772 | ||
1131 | /* if while adding to a node we discover that it is possible to split | 773 | /* if while adding to a node we discover that it is possible to split |
1132 | it in two, and merge the left part into the left neighbor and the | 774 | it in two, and merge the left part into the left neighbor and the |
@@ -1177,8 +819,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1177 | 819 | ||
1178 | if (n - snum[i] < item_pos) { /* new item or it's part falls to first new node S_new[i] */ | 820 | if (n - snum[i] < item_pos) { /* new item or it's part falls to first new node S_new[i] */ |
1179 | if (item_pos == n - snum[i] + 1 && sbytes[i] != -1) { /* part of new item falls into S_new[i] */ | 821 | if (item_pos == n - snum[i] + 1 && sbytes[i] != -1) { /* part of new item falls into S_new[i] */ |
1180 | int old_key_comp, old_len, | 822 | int old_key_comp, old_len, r_zeros_number; |
1181 | r_zeros_number; | ||
1182 | const char *r_body; | 823 | const char *r_body; |
1183 | int version; | 824 | int version; |
1184 | 825 | ||
@@ -1192,15 +833,8 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1192 | old_len = ih_item_len(ih); | 833 | old_len = ih_item_len(ih); |
1193 | 834 | ||
1194 | /* Calculate key component and item length to insert into S_new[i] */ | 835 | /* Calculate key component and item length to insert into S_new[i] */ |
1195 | set_le_ih_k_offset(ih, | 836 | set_le_ih_k_offset(ih, le_ih_k_offset(ih) + |
1196 | le_ih_k_offset(ih) + | 837 | ((old_len - sbytes[i]) << (is_indirect_le_ih(ih) ? tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT : 0))); |
1197 | ((old_len - | ||
1198 | sbytes[i]) << | ||
1199 | (is_indirect_le_ih | ||
1200 | (ih) ? tb->tb_sb-> | ||
1201 | s_blocksize_bits - | ||
1202 | UNFM_P_SHIFT : | ||
1203 | 0))); | ||
1204 | 838 | ||
1205 | put_ih_item_len(ih, sbytes[i]); | 839 | put_ih_item_len(ih, sbytes[i]); |
1206 | 840 | ||
@@ -1209,39 +843,29 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1209 | 843 | ||
1210 | if ((old_len - sbytes[i]) > zeros_num) { | 844 | if ((old_len - sbytes[i]) > zeros_num) { |
1211 | r_zeros_number = 0; | 845 | r_zeros_number = 0; |
1212 | r_body = | 846 | r_body = body + (old_len - sbytes[i]) - zeros_num; |
1213 | body + (old_len - | ||
1214 | sbytes[i]) - | ||
1215 | zeros_num; | ||
1216 | } else { | 847 | } else { |
1217 | r_body = body; | 848 | r_body = body; |
1218 | r_zeros_number = | 849 | r_zeros_number = zeros_num - (old_len - sbytes[i]); |
1219 | zeros_num - (old_len - | ||
1220 | sbytes[i]); | ||
1221 | zeros_num -= r_zeros_number; | 850 | zeros_num -= r_zeros_number; |
1222 | } | 851 | } |
1223 | 852 | ||
1224 | leaf_insert_into_buf(&bi, 0, ih, r_body, | 853 | leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeros_number); |
1225 | r_zeros_number); | ||
1226 | 854 | ||
1227 | /* Calculate key component and item length to insert into S[i] */ | 855 | /* Calculate key component and item length to insert into S[i] */ |
1228 | set_le_ih_k_offset(ih, old_key_comp); | 856 | set_le_ih_k_offset(ih, old_key_comp); |
1229 | put_ih_item_len(ih, | 857 | put_ih_item_len(ih, old_len - sbytes[i]); |
1230 | old_len - sbytes[i]); | ||
1231 | tb->insert_size[0] -= sbytes[i]; | 858 | tb->insert_size[0] -= sbytes[i]; |
1232 | } else { /* whole new item falls into S_new[i] */ | 859 | } else { /* whole new item falls into S_new[i] */ |
1233 | 860 | ||
1234 | /* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */ | 861 | /* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */ |
1235 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | 862 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, |
1236 | snum[i] - 1, sbytes[i], | 863 | snum[i] - 1, sbytes[i], S_new[i]); |
1237 | S_new[i]); | ||
1238 | 864 | ||
1239 | /* Insert new item into S_new[i] */ | 865 | /* Insert new item into S_new[i] */ |
1240 | buffer_info_init_bh(tb, &bi, S_new[i]); | 866 | buffer_info_init_bh(tb, &bi, S_new[i]); |
1241 | leaf_insert_into_buf(&bi, | 867 | leaf_insert_into_buf(&bi, item_pos - n + snum[i] - 1, |
1242 | item_pos - n + | 868 | ih, body, zeros_num); |
1243 | snum[i] - 1, ih, | ||
1244 | body, zeros_num); | ||
1245 | 869 | ||
1246 | zeros_num = tb->insert_size[0] = 0; | 870 | zeros_num = tb->insert_size[0] = 0; |
1247 | } | 871 | } |
@@ -1268,150 +892,73 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1268 | 892 | ||
1269 | int entry_count; | 893 | int entry_count; |
1270 | 894 | ||
1271 | entry_count = | 895 | entry_count = ih_entry_count(aux_ih); |
1272 | ih_entry_count(aux_ih); | ||
1273 | 896 | ||
1274 | if (entry_count - sbytes[i] < | 897 | if (entry_count - sbytes[i] < pos_in_item && pos_in_item <= entry_count) { |
1275 | pos_in_item | ||
1276 | && pos_in_item <= | ||
1277 | entry_count) { | ||
1278 | /* new directory entry falls into S_new[i] */ | 898 | /* new directory entry falls into S_new[i] */ |
1279 | 899 | ||
1280 | RFALSE(!tb-> | 900 | RFALSE(!tb->insert_size[0], "PAP-12215: insert_size is already 0"); |
1281 | insert_size[0], | 901 | RFALSE(sbytes[i] - 1 >= entry_count, |
1282 | "PAP-12215: insert_size is already 0"); | ||
1283 | RFALSE(sbytes[i] - 1 >= | ||
1284 | entry_count, | ||
1285 | "PAP-12220: there are no so much entries (%d), only %d", | 902 | "PAP-12220: there are no so much entries (%d), only %d", |
1286 | sbytes[i] - 1, | 903 | sbytes[i] - 1, entry_count); |
1287 | entry_count); | ||
1288 | 904 | ||
1289 | /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */ | 905 | /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */ |
1290 | leaf_move_items | 906 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i] - 1, S_new[i]); |
1291 | (LEAF_FROM_S_TO_SNEW, | ||
1292 | tb, snum[i], | ||
1293 | sbytes[i] - 1, | ||
1294 | S_new[i]); | ||
1295 | /* Paste given directory entry to directory item */ | 907 | /* Paste given directory entry to directory item */ |
1296 | buffer_info_init_bh(tb, &bi, S_new[i]); | 908 | buffer_info_init_bh(tb, &bi, S_new[i]); |
1297 | leaf_paste_in_buffer | 909 | leaf_paste_in_buffer(&bi, 0, pos_in_item - entry_count + sbytes[i] - 1, |
1298 | (&bi, 0, | 910 | tb->insert_size[0], body, zeros_num); |
1299 | pos_in_item - | ||
1300 | entry_count + | ||
1301 | sbytes[i] - 1, | ||
1302 | tb->insert_size[0], | ||
1303 | body, zeros_num); | ||
1304 | /* paste new directory entry */ | 911 | /* paste new directory entry */ |
1305 | leaf_paste_entries(&bi, | 912 | leaf_paste_entries(&bi, 0, pos_in_item - entry_count + sbytes[i] - 1, 1, |
1306 | 0, | 913 | (struct reiserfs_de_head *) body, |
1307 | pos_in_item | 914 | body + DEH_SIZE, tb->insert_size[0]); |
1308 | - | ||
1309 | entry_count | ||
1310 | + | ||
1311 | sbytes | ||
1312 | [i] - | ||
1313 | 1, 1, | ||
1314 | (struct | ||
1315 | reiserfs_de_head | ||
1316 | *) | ||
1317 | body, | ||
1318 | body | ||
1319 | + | ||
1320 | DEH_SIZE, | ||
1321 | tb-> | ||
1322 | insert_size | ||
1323 | [0] | ||
1324 | ); | ||
1325 | tb->insert_size[0] = 0; | 915 | tb->insert_size[0] = 0; |
1326 | pos_in_item++; | 916 | pos_in_item++; |
1327 | } else { /* new directory entry doesn't fall into S_new[i] */ | 917 | } else { /* new directory entry doesn't fall into S_new[i] */ |
1328 | leaf_move_items | 918 | leaf_move_items(LEAF_FROM_S_TO_SNEW,tb, snum[i], sbytes[i], S_new[i]); |
1329 | (LEAF_FROM_S_TO_SNEW, | ||
1330 | tb, snum[i], | ||
1331 | sbytes[i], | ||
1332 | S_new[i]); | ||
1333 | } | 919 | } |
1334 | } else { /* regular object */ | 920 | } else { /* regular object */ |
1335 | 921 | ||
1336 | int n_shift, n_rem, | 922 | int n_shift, n_rem, r_zeros_number; |
1337 | r_zeros_number; | ||
1338 | const char *r_body; | 923 | const char *r_body; |
1339 | 924 | ||
1340 | RFALSE(pos_in_item != | 925 | RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)) || tb->insert_size[0] <= 0, |
1341 | ih_item_len | ||
1342 | (B_N_PITEM_HEAD | ||
1343 | (tbS0, item_pos)) | ||
1344 | || tb->insert_size[0] <= | ||
1345 | 0, | ||
1346 | "PAP-12225: item too short or insert_size <= 0"); | 926 | "PAP-12225: item too short or insert_size <= 0"); |
1347 | 927 | ||
1348 | /* Calculate number of bytes which must be shifted from appended item */ | 928 | /* Calculate number of bytes which must be shifted from appended item */ |
1349 | n_shift = | 929 | n_shift = sbytes[i] - tb->insert_size[0]; |
1350 | sbytes[i] - | ||
1351 | tb->insert_size[0]; | ||
1352 | if (n_shift < 0) | 930 | if (n_shift < 0) |
1353 | n_shift = 0; | 931 | n_shift = 0; |
1354 | leaf_move_items | 932 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, snum[i], n_shift, S_new[i]); |
1355 | (LEAF_FROM_S_TO_SNEW, tb, | ||
1356 | snum[i], n_shift, | ||
1357 | S_new[i]); | ||
1358 | 933 | ||
1359 | /* Calculate number of bytes which must remain in body after append to S_new[i] */ | 934 | /* Calculate number of bytes which must remain in body after append to S_new[i] */ |
1360 | n_rem = | 935 | n_rem = tb->insert_size[0] - sbytes[i]; |
1361 | tb->insert_size[0] - | ||
1362 | sbytes[i]; | ||
1363 | if (n_rem < 0) | 936 | if (n_rem < 0) |
1364 | n_rem = 0; | 937 | n_rem = 0; |
1365 | /* Append part of body into S_new[0] */ | 938 | /* Append part of body into S_new[0] */ |
1366 | buffer_info_init_bh(tb, &bi, S_new[i]); | 939 | buffer_info_init_bh(tb, &bi, S_new[i]); |
1367 | if (n_rem > zeros_num) { | 940 | if (n_rem > zeros_num) { |
1368 | r_zeros_number = 0; | 941 | r_zeros_number = 0; |
1369 | r_body = | 942 | r_body = body + n_rem - zeros_num; |
1370 | body + n_rem - | ||
1371 | zeros_num; | ||
1372 | } else { | 943 | } else { |
1373 | r_body = body; | 944 | r_body = body; |
1374 | r_zeros_number = | 945 | r_zeros_number = zeros_num - n_rem; |
1375 | zeros_num - n_rem; | 946 | zeros_num -= r_zeros_number; |
1376 | zeros_num -= | ||
1377 | r_zeros_number; | ||
1378 | } | 947 | } |
1379 | 948 | ||
1380 | leaf_paste_in_buffer(&bi, 0, | 949 | leaf_paste_in_buffer(&bi, 0, n_shift, |
1381 | n_shift, | 950 | tb->insert_size[0] - n_rem, |
1382 | tb-> | 951 | r_body, r_zeros_number); |
1383 | insert_size | ||
1384 | [0] - | ||
1385 | n_rem, | ||
1386 | r_body, | ||
1387 | r_zeros_number); | ||
1388 | { | 952 | { |
1389 | struct item_head *tmp; | 953 | struct item_head *tmp; |
1390 | 954 | ||
1391 | tmp = | 955 | tmp = B_N_PITEM_HEAD(S_new[i], 0); |
1392 | B_N_PITEM_HEAD(S_new | ||
1393 | [i], | ||
1394 | 0); | ||
1395 | if (is_indirect_le_ih | 956 | if (is_indirect_le_ih |
1396 | (tmp)) { | 957 | (tmp)) { |
1397 | set_ih_free_space | 958 | set_ih_free_space(tmp, 0); |
1398 | (tmp, 0); | 959 | set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT))); |
1399 | set_le_ih_k_offset | ||
1400 | (tmp, | ||
1401 | le_ih_k_offset | ||
1402 | (tmp) + | ||
1403 | (n_rem << | ||
1404 | (tb-> | ||
1405 | tb_sb-> | ||
1406 | s_blocksize_bits | ||
1407 | - | ||
1408 | UNFM_P_SHIFT))); | ||
1409 | } else { | 960 | } else { |
1410 | set_le_ih_k_offset | 961 | set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + n_rem); |
1411 | (tmp, | ||
1412 | le_ih_k_offset | ||
1413 | (tmp) + | ||
1414 | n_rem); | ||
1415 | } | 962 | } |
1416 | } | 963 | } |
1417 | 964 | ||
@@ -1426,8 +973,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1426 | struct item_head *pasted; | 973 | struct item_head *pasted; |
1427 | 974 | ||
1428 | #ifdef CONFIG_REISERFS_CHECK | 975 | #ifdef CONFIG_REISERFS_CHECK |
1429 | struct item_head *ih_check = | 976 | struct item_head *ih_check = B_N_PITEM_HEAD(tbS0, item_pos); |
1430 | B_N_PITEM_HEAD(tbS0, item_pos); | ||
1431 | 977 | ||
1432 | if (!is_direntry_le_ih(ih_check) | 978 | if (!is_direntry_le_ih(ih_check) |
1433 | && (pos_in_item != ih_item_len(ih_check) | 979 | && (pos_in_item != ih_item_len(ih_check) |
@@ -1439,8 +985,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1439 | "to ih_item_len"); | 985 | "to ih_item_len"); |
1440 | #endif /* CONFIG_REISERFS_CHECK */ | 986 | #endif /* CONFIG_REISERFS_CHECK */ |
1441 | 987 | ||
1442 | leaf_mi = | 988 | leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW, |
1443 | leaf_move_items(LEAF_FROM_S_TO_SNEW, | ||
1444 | tb, snum[i], | 989 | tb, snum[i], |
1445 | sbytes[i], | 990 | sbytes[i], |
1446 | S_new[i]); | 991 | S_new[i]); |
@@ -1452,30 +997,19 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1452 | /* paste into item */ | 997 | /* paste into item */ |
1453 | buffer_info_init_bh(tb, &bi, S_new[i]); | 998 | buffer_info_init_bh(tb, &bi, S_new[i]); |
1454 | leaf_paste_in_buffer(&bi, | 999 | leaf_paste_in_buffer(&bi, |
1455 | item_pos - n + | 1000 | item_pos - n + snum[i], |
1456 | snum[i], | ||
1457 | pos_in_item, | 1001 | pos_in_item, |
1458 | tb->insert_size[0], | 1002 | tb->insert_size[0], |
1459 | body, zeros_num); | 1003 | body, zeros_num); |
1460 | 1004 | ||
1461 | pasted = | 1005 | pasted = B_N_PITEM_HEAD(S_new[i], item_pos - n + snum[i]); |
1462 | B_N_PITEM_HEAD(S_new[i], | ||
1463 | item_pos - n + | ||
1464 | snum[i]); | ||
1465 | if (is_direntry_le_ih(pasted)) { | 1006 | if (is_direntry_le_ih(pasted)) { |
1466 | leaf_paste_entries(&bi, | 1007 | leaf_paste_entries(&bi, |
1467 | item_pos - | 1008 | item_pos - n + snum[i], |
1468 | n + snum[i], | 1009 | pos_in_item, 1, |
1469 | pos_in_item, | 1010 | (struct reiserfs_de_head *)body, |
1470 | 1, | 1011 | body + DEH_SIZE, |
1471 | (struct | 1012 | tb->insert_size[0] |
1472 | reiserfs_de_head | ||
1473 | *)body, | ||
1474 | body + | ||
1475 | DEH_SIZE, | ||
1476 | tb-> | ||
1477 | insert_size | ||
1478 | [0] | ||
1479 | ); | 1013 | ); |
1480 | } | 1014 | } |
1481 | 1015 | ||
@@ -1495,11 +1029,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1495 | default: /* cases d and t */ | 1029 | default: /* cases d and t */ |
1496 | reiserfs_panic(tb->tb_sb, "PAP-12245", | 1030 | reiserfs_panic(tb->tb_sb, "PAP-12245", |
1497 | "blknum > 2: unexpected mode: %s(%d)", | 1031 | "blknum > 2: unexpected mode: %s(%d)", |
1498 | (flag == | 1032 | (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag); |
1499 | M_DELETE) ? "DELETE" : ((flag == | ||
1500 | M_CUT) ? "CUT" | ||
1501 | : "UNKNOWN"), | ||
1502 | flag); | ||
1503 | } | 1033 | } |
1504 | 1034 | ||
1505 | memcpy(insert_key + i, B_N_PKEY(S_new[i], 0), KEY_SIZE); | 1035 | memcpy(insert_key + i, B_N_PKEY(S_new[i], 0), KEY_SIZE); |
@@ -1524,9 +1054,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1524 | /* If we insert the first key change the delimiting key */ | 1054 | /* If we insert the first key change the delimiting key */ |
1525 | if (item_pos == 0) { | 1055 | if (item_pos == 0) { |
1526 | if (tb->CFL[0]) /* can be 0 in reiserfsck */ | 1056 | if (tb->CFL[0]) /* can be 0 in reiserfsck */ |
1527 | replace_key(tb, tb->CFL[0], tb->lkey[0], | 1057 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); |
1528 | tbS0, 0); | ||
1529 | |||
1530 | } | 1058 | } |
1531 | break; | 1059 | break; |
1532 | 1060 | ||
@@ -1536,53 +1064,27 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1536 | pasted = B_N_PITEM_HEAD(tbS0, item_pos); | 1064 | pasted = B_N_PITEM_HEAD(tbS0, item_pos); |
1537 | /* when directory, may be new entry already pasted */ | 1065 | /* when directory, may be new entry already pasted */ |
1538 | if (is_direntry_le_ih(pasted)) { | 1066 | if (is_direntry_le_ih(pasted)) { |
1539 | if (pos_in_item >= 0 && | 1067 | if (pos_in_item >= 0 && pos_in_item <= ih_entry_count(pasted)) { |
1540 | pos_in_item <= | ||
1541 | ih_entry_count(pasted)) { | ||
1542 | 1068 | ||
1543 | RFALSE(!tb->insert_size[0], | 1069 | RFALSE(!tb->insert_size[0], |
1544 | "PAP-12260: insert_size is 0 already"); | 1070 | "PAP-12260: insert_size is 0 already"); |
1545 | 1071 | ||
1546 | /* prepare space */ | 1072 | /* prepare space */ |
1547 | buffer_info_init_tbS0(tb, &bi); | 1073 | buffer_info_init_tbS0(tb, &bi); |
1548 | leaf_paste_in_buffer(&bi, | 1074 | leaf_paste_in_buffer(&bi, item_pos, pos_in_item, |
1549 | item_pos, | 1075 | tb->insert_size[0], body, |
1550 | pos_in_item, | ||
1551 | tb-> | ||
1552 | insert_size | ||
1553 | [0], body, | ||
1554 | zeros_num); | 1076 | zeros_num); |
1555 | 1077 | ||
1556 | /* paste entry */ | 1078 | /* paste entry */ |
1557 | leaf_paste_entries(&bi, | 1079 | leaf_paste_entries(&bi, item_pos, pos_in_item, 1, |
1558 | item_pos, | 1080 | (struct reiserfs_de_head *)body, |
1559 | pos_in_item, | 1081 | body + DEH_SIZE, |
1560 | 1, | 1082 | tb->insert_size[0]); |
1561 | (struct | ||
1562 | reiserfs_de_head | ||
1563 | *)body, | ||
1564 | body + | ||
1565 | DEH_SIZE, | ||
1566 | tb-> | ||
1567 | insert_size | ||
1568 | [0] | ||
1569 | ); | ||
1570 | if (!item_pos && !pos_in_item) { | 1083 | if (!item_pos && !pos_in_item) { |
1571 | RFALSE(!tb->CFL[0] | 1084 | RFALSE(!tb->CFL[0] || !tb->L[0], |
1572 | || !tb->L[0], | ||
1573 | "PAP-12270: CFL[0]/L[0] must be specified"); | 1085 | "PAP-12270: CFL[0]/L[0] must be specified"); |
1574 | if (tb->CFL[0]) { | 1086 | if (tb->CFL[0]) |
1575 | replace_key(tb, | 1087 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); |
1576 | tb-> | ||
1577 | CFL | ||
1578 | [0], | ||
1579 | tb-> | ||
1580 | lkey | ||
1581 | [0], | ||
1582 | tbS0, | ||
1583 | 0); | ||
1584 | |||
1585 | } | ||
1586 | } | 1088 | } |
1587 | tb->insert_size[0] = 0; | 1089 | tb->insert_size[0] = 0; |
1588 | } | 1090 | } |
@@ -1593,13 +1095,8 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1593 | "PAP-12275: insert size must not be %d", | 1095 | "PAP-12275: insert size must not be %d", |
1594 | tb->insert_size[0]); | 1096 | tb->insert_size[0]); |
1595 | buffer_info_init_tbS0(tb, &bi); | 1097 | buffer_info_init_tbS0(tb, &bi); |
1596 | leaf_paste_in_buffer(&bi, | 1098 | leaf_paste_in_buffer(&bi, item_pos, pos_in_item, |
1597 | item_pos, | 1099 | tb->insert_size[0], body, zeros_num); |
1598 | pos_in_item, | ||
1599 | tb-> | ||
1600 | insert_size | ||
1601 | [0], body, | ||
1602 | zeros_num); | ||
1603 | 1100 | ||
1604 | if (is_indirect_le_ih(pasted)) { | 1101 | if (is_indirect_le_ih(pasted)) { |
1605 | #if 0 | 1102 | #if 0 |
@@ -1611,8 +1108,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1611 | tb-> | 1108 | tb-> |
1612 | insert_size[0]); | 1109 | insert_size[0]); |
1613 | #endif | 1110 | #endif |
1614 | set_ih_free_space | 1111 | set_ih_free_space(pasted, 0); |
1615 | (pasted, 0); | ||
1616 | } | 1112 | } |
1617 | tb->insert_size[0] = 0; | 1113 | tb->insert_size[0] = 0; |
1618 | } | 1114 | } |
@@ -1620,8 +1116,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
1620 | else { | 1116 | else { |
1621 | if (tb->insert_size[0]) { | 1117 | if (tb->insert_size[0]) { |
1622 | print_cur_tb("12285"); | 1118 | print_cur_tb("12285"); |
1623 | reiserfs_panic(tb-> | 1119 | reiserfs_panic(tb->tb_sb, |
1624 | tb_sb, | ||
1625 | "PAP-12285", | 1120 | "PAP-12285", |
1626 | "insert_size " | 1121 | "insert_size " |
1627 | "must be 0 " | 1122 | "must be 0 " |
@@ -27,11 +27,10 @@ | |||
27 | * wait == 1 case since in that case write_inode() functions do | 27 | * wait == 1 case since in that case write_inode() functions do |
28 | * sync_dirty_buffer() and thus effectively write one block at a time. | 28 | * sync_dirty_buffer() and thus effectively write one block at a time. |
29 | */ | 29 | */ |
30 | static int __sync_filesystem(struct super_block *sb, int wait, | 30 | static int __sync_filesystem(struct super_block *sb, int wait) |
31 | unsigned long start) | ||
32 | { | 31 | { |
33 | if (wait) | 32 | if (wait) |
34 | sync_inodes_sb(sb, start); | 33 | sync_inodes_sb(sb); |
35 | else | 34 | else |
36 | writeback_inodes_sb(sb, WB_REASON_SYNC); | 35 | writeback_inodes_sb(sb, WB_REASON_SYNC); |
37 | 36 | ||
@@ -48,7 +47,6 @@ static int __sync_filesystem(struct super_block *sb, int wait, | |||
48 | int sync_filesystem(struct super_block *sb) | 47 | int sync_filesystem(struct super_block *sb) |
49 | { | 48 | { |
50 | int ret; | 49 | int ret; |
51 | unsigned long start = jiffies; | ||
52 | 50 | ||
53 | /* | 51 | /* |
54 | * We need to be protected against the filesystem going from | 52 | * We need to be protected against the filesystem going from |
@@ -62,17 +60,17 @@ int sync_filesystem(struct super_block *sb) | |||
62 | if (sb->s_flags & MS_RDONLY) | 60 | if (sb->s_flags & MS_RDONLY) |
63 | return 0; | 61 | return 0; |
64 | 62 | ||
65 | ret = __sync_filesystem(sb, 0, start); | 63 | ret = __sync_filesystem(sb, 0); |
66 | if (ret < 0) | 64 | if (ret < 0) |
67 | return ret; | 65 | return ret; |
68 | return __sync_filesystem(sb, 1, start); | 66 | return __sync_filesystem(sb, 1); |
69 | } | 67 | } |
70 | EXPORT_SYMBOL_GPL(sync_filesystem); | 68 | EXPORT_SYMBOL_GPL(sync_filesystem); |
71 | 69 | ||
72 | static void sync_inodes_one_sb(struct super_block *sb, void *arg) | 70 | static void sync_inodes_one_sb(struct super_block *sb, void *arg) |
73 | { | 71 | { |
74 | if (!(sb->s_flags & MS_RDONLY)) | 72 | if (!(sb->s_flags & MS_RDONLY)) |
75 | sync_inodes_sb(sb, *((unsigned long *)arg)); | 73 | sync_inodes_sb(sb); |
76 | } | 74 | } |
77 | 75 | ||
78 | static void sync_fs_one_sb(struct super_block *sb, void *arg) | 76 | static void sync_fs_one_sb(struct super_block *sb, void *arg) |
@@ -104,10 +102,9 @@ static void fdatawait_one_bdev(struct block_device *bdev, void *arg) | |||
104 | SYSCALL_DEFINE0(sync) | 102 | SYSCALL_DEFINE0(sync) |
105 | { | 103 | { |
106 | int nowait = 0, wait = 1; | 104 | int nowait = 0, wait = 1; |
107 | unsigned long start = jiffies; | ||
108 | 105 | ||
109 | wakeup_flusher_threads(0, WB_REASON_SYNC); | 106 | wakeup_flusher_threads(0, WB_REASON_SYNC); |
110 | iterate_supers(sync_inodes_one_sb, &start); | 107 | iterate_supers(sync_inodes_one_sb, NULL); |
111 | iterate_supers(sync_fs_one_sb, &nowait); | 108 | iterate_supers(sync_fs_one_sb, &nowait); |
112 | iterate_supers(sync_fs_one_sb, &wait); | 109 | iterate_supers(sync_fs_one_sb, &wait); |
113 | iterate_bdevs(fdatawrite_one_bdev, NULL); | 110 | iterate_bdevs(fdatawrite_one_bdev, NULL); |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 6211230814fd..3eaf5c6622eb 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -27,6 +27,7 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
27 | { | 27 | { |
28 | struct dentry *root; | 28 | struct dentry *root; |
29 | void *ns; | 29 | void *ns; |
30 | bool new_sb; | ||
30 | 31 | ||
31 | if (!(flags & MS_KERNMOUNT)) { | 32 | if (!(flags & MS_KERNMOUNT)) { |
32 | if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type)) | 33 | if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type)) |
@@ -37,8 +38,8 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
37 | } | 38 | } |
38 | 39 | ||
39 | ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET); | 40 | ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET); |
40 | root = kernfs_mount_ns(fs_type, flags, sysfs_root, ns); | 41 | root = kernfs_mount_ns(fs_type, flags, sysfs_root, &new_sb, ns); |
41 | if (IS_ERR(root)) | 42 | if (IS_ERR(root) || !new_sb) |
42 | kobj_ns_drop(KOBJ_NS_TYPE_NET, ns); | 43 | kobj_ns_drop(KOBJ_NS_TYPE_NET, ns); |
43 | return root; | 44 | return root; |
44 | } | 45 | } |
diff --git a/fs/udf/file.c b/fs/udf/file.c index c02a27a19c6d..1037637957c7 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -144,6 +144,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
144 | size_t count = iocb->ki_nbytes; | 144 | size_t count = iocb->ki_nbytes; |
145 | struct udf_inode_info *iinfo = UDF_I(inode); | 145 | struct udf_inode_info *iinfo = UDF_I(inode); |
146 | 146 | ||
147 | mutex_lock(&inode->i_mutex); | ||
147 | down_write(&iinfo->i_data_sem); | 148 | down_write(&iinfo->i_data_sem); |
148 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 149 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
149 | if (file->f_flags & O_APPEND) | 150 | if (file->f_flags & O_APPEND) |
@@ -156,6 +157,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
156 | pos + count)) { | 157 | pos + count)) { |
157 | err = udf_expand_file_adinicb(inode); | 158 | err = udf_expand_file_adinicb(inode); |
158 | if (err) { | 159 | if (err) { |
160 | mutex_unlock(&inode->i_mutex); | ||
159 | udf_debug("udf_expand_adinicb: err=%d\n", err); | 161 | udf_debug("udf_expand_adinicb: err=%d\n", err); |
160 | return err; | 162 | return err; |
161 | } | 163 | } |
@@ -169,9 +171,17 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
169 | } else | 171 | } else |
170 | up_write(&iinfo->i_data_sem); | 172 | up_write(&iinfo->i_data_sem); |
171 | 173 | ||
172 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); | 174 | retval = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
173 | if (retval > 0) | 175 | mutex_unlock(&inode->i_mutex); |
176 | |||
177 | if (retval > 0) { | ||
178 | ssize_t err; | ||
179 | |||
174 | mark_inode_dirty(inode); | 180 | mark_inode_dirty(inode); |
181 | err = generic_write_sync(file, iocb->ki_pos - retval, retval); | ||
182 | if (err < 0) | ||
183 | retval = err; | ||
184 | } | ||
175 | 185 | ||
176 | return retval; | 186 | return retval; |
177 | } | 187 | } |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 062b7925bca0..982ce05c87ed 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -265,6 +265,7 @@ int udf_expand_file_adinicb(struct inode *inode) | |||
265 | .nr_to_write = 1, | 265 | .nr_to_write = 1, |
266 | }; | 266 | }; |
267 | 267 | ||
268 | WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); | ||
268 | if (!iinfo->i_lenAlloc) { | 269 | if (!iinfo->i_lenAlloc) { |
269 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 270 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
270 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; | 271 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index f35d5c953ff9..9ddfb8190ca1 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -705,7 +705,6 @@ xfs_setattr_size( | |||
705 | { | 705 | { |
706 | struct xfs_mount *mp = ip->i_mount; | 706 | struct xfs_mount *mp = ip->i_mount; |
707 | struct inode *inode = VFS_I(ip); | 707 | struct inode *inode = VFS_I(ip); |
708 | int mask = iattr->ia_valid; | ||
709 | xfs_off_t oldsize, newsize; | 708 | xfs_off_t oldsize, newsize; |
710 | struct xfs_trans *tp; | 709 | struct xfs_trans *tp; |
711 | int error; | 710 | int error; |
@@ -726,8 +725,8 @@ xfs_setattr_size( | |||
726 | 725 | ||
727 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | 726 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
728 | ASSERT(S_ISREG(ip->i_d.di_mode)); | 727 | ASSERT(S_ISREG(ip->i_d.di_mode)); |
729 | ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| | 728 | ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| |
730 | ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); | 729 | ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); |
731 | 730 | ||
732 | oldsize = inode->i_size; | 731 | oldsize = inode->i_size; |
733 | newsize = iattr->ia_size; | 732 | newsize = iattr->ia_size; |
@@ -736,7 +735,7 @@ xfs_setattr_size( | |||
736 | * Short circuit the truncate case for zero length files. | 735 | * Short circuit the truncate case for zero length files. |
737 | */ | 736 | */ |
738 | if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { | 737 | if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { |
739 | if (!(mask & (ATTR_CTIME|ATTR_MTIME))) | 738 | if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) |
740 | return 0; | 739 | return 0; |
741 | 740 | ||
742 | /* | 741 | /* |
@@ -824,10 +823,11 @@ xfs_setattr_size( | |||
824 | * these flags set. For all other operations the VFS set these flags | 823 | * these flags set. For all other operations the VFS set these flags |
825 | * explicitly if it wants a timestamp update. | 824 | * explicitly if it wants a timestamp update. |
826 | */ | 825 | */ |
827 | if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) { | 826 | if (newsize != oldsize && |
827 | !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) { | ||
828 | iattr->ia_ctime = iattr->ia_mtime = | 828 | iattr->ia_ctime = iattr->ia_mtime = |
829 | current_fs_time(inode->i_sb); | 829 | current_fs_time(inode->i_sb); |
830 | mask |= ATTR_CTIME | ATTR_MTIME; | 830 | iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; |
831 | } | 831 | } |
832 | 832 | ||
833 | /* | 833 | /* |
@@ -863,9 +863,9 @@ xfs_setattr_size( | |||
863 | xfs_inode_clear_eofblocks_tag(ip); | 863 | xfs_inode_clear_eofblocks_tag(ip); |
864 | } | 864 | } |
865 | 865 | ||
866 | if (mask & ATTR_MODE) | 866 | if (iattr->ia_valid & ATTR_MODE) |
867 | xfs_setattr_mode(ip, iattr); | 867 | xfs_setattr_mode(ip, iattr); |
868 | if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) | 868 | if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) |
869 | xfs_setattr_time(ip, iattr); | 869 | xfs_setattr_time(ip, iattr); |
870 | 870 | ||
871 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 871 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index cdebd832c3db..4ef6fdbced78 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -205,16 +205,25 @@ xlog_cil_insert_format_items( | |||
205 | /* | 205 | /* |
206 | * We 64-bit align the length of each iovec so that the start | 206 | * We 64-bit align the length of each iovec so that the start |
207 | * of the next one is naturally aligned. We'll need to | 207 | * of the next one is naturally aligned. We'll need to |
208 | * account for that slack space here. | 208 | * account for that slack space here. Then round nbytes up |
209 | * to 64-bit alignment so that the initial buffer alignment is | ||
210 | * easy to calculate and verify. | ||
209 | */ | 211 | */ |
210 | nbytes += niovecs * sizeof(uint64_t); | 212 | nbytes += niovecs * sizeof(uint64_t); |
213 | nbytes = round_up(nbytes, sizeof(uint64_t)); | ||
211 | 214 | ||
212 | /* grab the old item if it exists for reservation accounting */ | 215 | /* grab the old item if it exists for reservation accounting */ |
213 | old_lv = lip->li_lv; | 216 | old_lv = lip->li_lv; |
214 | 217 | ||
215 | /* calc buffer size */ | 218 | /* |
216 | buf_size = sizeof(struct xfs_log_vec) + nbytes + | 219 | * The data buffer needs to start 64-bit aligned, so round up |
217 | niovecs * sizeof(struct xfs_log_iovec); | 220 | * that space to ensure we can align it appropriately and not |
221 | * overrun the buffer. | ||
222 | */ | ||
223 | buf_size = nbytes + | ||
224 | round_up((sizeof(struct xfs_log_vec) + | ||
225 | niovecs * sizeof(struct xfs_log_iovec)), | ||
226 | sizeof(uint64_t)); | ||
218 | 227 | ||
219 | /* compare to existing item size */ | 228 | /* compare to existing item size */ |
220 | if (lip->li_lv && buf_size <= lip->li_lv->lv_size) { | 229 | if (lip->li_lv && buf_size <= lip->li_lv->lv_size) { |
@@ -251,6 +260,8 @@ xlog_cil_insert_format_items( | |||
251 | /* The allocated data region lies beyond the iovec region */ | 260 | /* The allocated data region lies beyond the iovec region */ |
252 | lv->lv_buf_len = 0; | 261 | lv->lv_buf_len = 0; |
253 | lv->lv_buf = (char *)lv + buf_size - nbytes; | 262 | lv->lv_buf = (char *)lv + buf_size - nbytes; |
263 | ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t))); | ||
264 | |||
254 | lip->li_ops->iop_format(lip, lv); | 265 | lip->li_ops->iop_format(lip, lv); |
255 | insert: | 266 | insert: |
256 | ASSERT(lv->lv_buf_len <= nbytes); | 267 | ASSERT(lv->lv_buf_len <= nbytes); |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 02df7b408a26..f96c05669a9e 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -282,22 +282,29 @@ xfs_readsb( | |||
282 | struct xfs_sb *sbp = &mp->m_sb; | 282 | struct xfs_sb *sbp = &mp->m_sb; |
283 | int error; | 283 | int error; |
284 | int loud = !(flags & XFS_MFSI_QUIET); | 284 | int loud = !(flags & XFS_MFSI_QUIET); |
285 | const struct xfs_buf_ops *buf_ops; | ||
285 | 286 | ||
286 | ASSERT(mp->m_sb_bp == NULL); | 287 | ASSERT(mp->m_sb_bp == NULL); |
287 | ASSERT(mp->m_ddev_targp != NULL); | 288 | ASSERT(mp->m_ddev_targp != NULL); |
288 | 289 | ||
289 | /* | 290 | /* |
291 | * For the initial read, we must guess at the sector | ||
292 | * size based on the block device. It's enough to | ||
293 | * get the sb_sectsize out of the superblock and | ||
294 | * then reread with the proper length. | ||
295 | * We don't verify it yet, because it may not be complete. | ||
296 | */ | ||
297 | sector_size = xfs_getsize_buftarg(mp->m_ddev_targp); | ||
298 | buf_ops = NULL; | ||
299 | |||
300 | /* | ||
290 | * Allocate a (locked) buffer to hold the superblock. | 301 | * Allocate a (locked) buffer to hold the superblock. |
291 | * This will be kept around at all times to optimize | 302 | * This will be kept around at all times to optimize |
292 | * access to the superblock. | 303 | * access to the superblock. |
293 | */ | 304 | */ |
294 | sector_size = xfs_getsize_buftarg(mp->m_ddev_targp); | ||
295 | |||
296 | reread: | 305 | reread: |
297 | bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, | 306 | bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, |
298 | BTOBB(sector_size), 0, | 307 | BTOBB(sector_size), 0, buf_ops); |
299 | loud ? &xfs_sb_buf_ops | ||
300 | : &xfs_sb_quiet_buf_ops); | ||
301 | if (!bp) { | 308 | if (!bp) { |
302 | if (loud) | 309 | if (loud) |
303 | xfs_warn(mp, "SB buffer read failed"); | 310 | xfs_warn(mp, "SB buffer read failed"); |
@@ -328,12 +335,13 @@ reread: | |||
328 | } | 335 | } |
329 | 336 | ||
330 | /* | 337 | /* |
331 | * If device sector size is smaller than the superblock size, | 338 | * Re-read the superblock so the buffer is correctly sized, |
332 | * re-read the superblock so the buffer is correctly sized. | 339 | * and properly verified. |
333 | */ | 340 | */ |
334 | if (sector_size < sbp->sb_sectsize) { | 341 | if (buf_ops == NULL) { |
335 | xfs_buf_relse(bp); | 342 | xfs_buf_relse(bp); |
336 | sector_size = sbp->sb_sectsize; | 343 | sector_size = sbp->sb_sectsize; |
344 | buf_ops = loud ? &xfs_sb_buf_ops : &xfs_sb_quiet_buf_ops; | ||
337 | goto reread; | 345 | goto reread; |
338 | } | 346 | } |
339 | 347 | ||
diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c index b7c9aea77f8f..1e116794bb66 100644 --- a/fs/xfs/xfs_sb.c +++ b/fs/xfs/xfs_sb.c | |||
@@ -295,8 +295,7 @@ xfs_mount_validate_sb( | |||
295 | sbp->sb_dblocks == 0 || | 295 | sbp->sb_dblocks == 0 || |
296 | sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) || | 296 | sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) || |
297 | sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) { | 297 | sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) { |
298 | XFS_CORRUPTION_ERROR("SB sanity check failed", | 298 | xfs_notice(mp, "SB sanity check failed"); |
299 | XFS_ERRLEVEL_LOW, mp, sbp); | ||
300 | return XFS_ERROR(EFSCORRUPTED); | 299 | return XFS_ERROR(EFSCORRUPTED); |
301 | } | 300 | } |
302 | 301 | ||
@@ -611,10 +610,10 @@ xfs_sb_read_verify( | |||
611 | XFS_SB_VERSION_5) || | 610 | XFS_SB_VERSION_5) || |
612 | dsb->sb_crc != 0)) { | 611 | dsb->sb_crc != 0)) { |
613 | 612 | ||
614 | if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize), | 613 | if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), |
615 | offsetof(struct xfs_sb, sb_crc))) { | 614 | offsetof(struct xfs_sb, sb_crc))) { |
616 | /* Only fail bad secondaries on a known V5 filesystem */ | 615 | /* Only fail bad secondaries on a known V5 filesystem */ |
617 | if (bp->b_bn != XFS_SB_DADDR && | 616 | if (bp->b_bn == XFS_SB_DADDR || |
618 | xfs_sb_version_hascrc(&mp->m_sb)) { | 617 | xfs_sb_version_hascrc(&mp->m_sb)) { |
619 | error = EFSCORRUPTED; | 618 | error = EFSCORRUPTED; |
620 | goto out_error; | 619 | goto out_error; |
@@ -625,7 +624,7 @@ xfs_sb_read_verify( | |||
625 | 624 | ||
626 | out_error: | 625 | out_error: |
627 | if (error) { | 626 | if (error) { |
628 | if (error != EWRONGFS) | 627 | if (error == EFSCORRUPTED) |
629 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, | 628 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, |
630 | mp, bp->b_addr); | 629 | mp, bp->b_addr); |
631 | xfs_buf_ioerror(bp, error); | 630 | xfs_buf_ioerror(bp, error); |
@@ -644,7 +643,6 @@ xfs_sb_quiet_read_verify( | |||
644 | { | 643 | { |
645 | struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); | 644 | struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); |
646 | 645 | ||
647 | |||
648 | if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) { | 646 | if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) { |
649 | /* XFS filesystem, verify noisily! */ | 647 | /* XFS filesystem, verify noisily! */ |
650 | xfs_sb_read_verify(bp); | 648 | xfs_sb_read_verify(bp); |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index f317488263dd..d971f4932b5d 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -913,7 +913,7 @@ xfs_flush_inodes( | |||
913 | struct super_block *sb = mp->m_super; | 913 | struct super_block *sb = mp->m_super; |
914 | 914 | ||
915 | if (down_read_trylock(&sb->s_umount)) { | 915 | if (down_read_trylock(&sb->s_umount)) { |
916 | sync_inodes_sb(sb, jiffies); | 916 | sync_inodes_sb(sb); |
917 | up_read(&sb->s_umount); | 917 | up_read(&sb->s_umount); |
918 | } | 918 | } |
919 | } | 919 | } |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 8e4f41d9af4d..34c7bdc06014 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -701,6 +701,18 @@ static inline pte_t pte_mknuma(pte_t pte) | |||
701 | } | 701 | } |
702 | #endif | 702 | #endif |
703 | 703 | ||
704 | #ifndef ptep_set_numa | ||
705 | static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr, | ||
706 | pte_t *ptep) | ||
707 | { | ||
708 | pte_t ptent = *ptep; | ||
709 | |||
710 | ptent = pte_mknuma(ptent); | ||
711 | set_pte_at(mm, addr, ptep, ptent); | ||
712 | return; | ||
713 | } | ||
714 | #endif | ||
715 | |||
704 | #ifndef pmd_mknuma | 716 | #ifndef pmd_mknuma |
705 | static inline pmd_t pmd_mknuma(pmd_t pmd) | 717 | static inline pmd_t pmd_mknuma(pmd_t pmd) |
706 | { | 718 | { |
@@ -708,6 +720,18 @@ static inline pmd_t pmd_mknuma(pmd_t pmd) | |||
708 | return pmd_clear_flags(pmd, _PAGE_PRESENT); | 720 | return pmd_clear_flags(pmd, _PAGE_PRESENT); |
709 | } | 721 | } |
710 | #endif | 722 | #endif |
723 | |||
724 | #ifndef pmdp_set_numa | ||
725 | static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr, | ||
726 | pmd_t *pmdp) | ||
727 | { | ||
728 | pmd_t pmd = *pmdp; | ||
729 | |||
730 | pmd = pmd_mknuma(pmd); | ||
731 | set_pmd_at(mm, addr, pmdp, pmd); | ||
732 | return; | ||
733 | } | ||
734 | #endif | ||
711 | #else | 735 | #else |
712 | extern int pte_numa(pte_t pte); | 736 | extern int pte_numa(pte_t pte); |
713 | extern int pmd_numa(pmd_t pmd); | 737 | extern int pmd_numa(pmd_t pmd); |
@@ -715,6 +739,8 @@ extern pte_t pte_mknonnuma(pte_t pte); | |||
715 | extern pmd_t pmd_mknonnuma(pmd_t pmd); | 739 | extern pmd_t pmd_mknonnuma(pmd_t pmd); |
716 | extern pte_t pte_mknuma(pte_t pte); | 740 | extern pte_t pte_mknuma(pte_t pte); |
717 | extern pmd_t pmd_mknuma(pmd_t pmd); | 741 | extern pmd_t pmd_mknuma(pmd_t pmd); |
742 | extern void ptep_set_numa(struct mm_struct *mm, unsigned long addr, pte_t *ptep); | ||
743 | extern void pmdp_set_numa(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp); | ||
718 | #endif /* CONFIG_ARCH_USES_NUMA_PROT_NONE */ | 744 | #endif /* CONFIG_ARCH_USES_NUMA_PROT_NONE */ |
719 | #else | 745 | #else |
720 | static inline int pmd_numa(pmd_t pmd) | 746 | static inline int pmd_numa(pmd_t pmd) |
@@ -742,10 +768,23 @@ static inline pte_t pte_mknuma(pte_t pte) | |||
742 | return pte; | 768 | return pte; |
743 | } | 769 | } |
744 | 770 | ||
771 | static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr, | ||
772 | pte_t *ptep) | ||
773 | { | ||
774 | return; | ||
775 | } | ||
776 | |||
777 | |||
745 | static inline pmd_t pmd_mknuma(pmd_t pmd) | 778 | static inline pmd_t pmd_mknuma(pmd_t pmd) |
746 | { | 779 | { |
747 | return pmd; | 780 | return pmd; |
748 | } | 781 | } |
782 | |||
783 | static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr, | ||
784 | pmd_t *pmdp) | ||
785 | { | ||
786 | return ; | ||
787 | } | ||
749 | #endif /* CONFIG_NUMA_BALANCING */ | 788 | #endif /* CONFIG_NUMA_BALANCING */ |
750 | 789 | ||
751 | #endif /* CONFIG_MMU */ | 790 | #endif /* CONFIG_MMU */ |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 71727b6210ae..8f3dee097579 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -907,6 +907,9 @@ struct drm_mode_config { | |||
907 | 907 | ||
908 | /* whether async page flip is supported or not */ | 908 | /* whether async page flip is supported or not */ |
909 | bool async_page_flip; | 909 | bool async_page_flip; |
910 | |||
911 | /* cursor size */ | ||
912 | uint32_t cursor_width, cursor_height; | ||
910 | }; | 913 | }; |
911 | 914 | ||
912 | #define obj_to_crtc(x) container_of(x, struct drm_crtc, base) | 915 | #define obj_to_crtc(x) container_of(x, struct drm_crtc, base) |
diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h index d1f61bfe0ebe..49a828425fa2 100644 --- a/include/drm/ttm/ttm_page_alloc.h +++ b/include/drm/ttm/ttm_page_alloc.h | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <drm/ttm/ttm_bo_driver.h> | 29 | #include <drm/ttm/ttm_bo_driver.h> |
30 | #include <drm/ttm/ttm_memory.h> | 30 | #include <drm/ttm/ttm_memory.h> |
31 | 31 | ||
32 | struct device; | ||
33 | |||
32 | /** | 34 | /** |
33 | * Initialize pool allocator. | 35 | * Initialize pool allocator. |
34 | */ | 36 | */ |
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index 2623cffc73a1..25bfb0eff772 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h | |||
@@ -373,8 +373,9 @@ extern const char *ceph_mds_op_name(int op); | |||
373 | /* | 373 | /* |
374 | * Ceph setxattr request flags. | 374 | * Ceph setxattr request flags. |
375 | */ | 375 | */ |
376 | #define CEPH_XATTR_CREATE 1 | 376 | #define CEPH_XATTR_CREATE (1 << 0) |
377 | #define CEPH_XATTR_REPLACE 2 | 377 | #define CEPH_XATTR_REPLACE (1 << 1) |
378 | #define CEPH_XATTR_REMOVE (1 << 31) | ||
378 | 379 | ||
379 | union ceph_mds_request_args { | 380 | union ceph_mds_request_args { |
380 | struct { | 381 | struct { |
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5c097596104b..9450f025fe0c 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -166,6 +166,8 @@ struct cgroup { | |||
166 | * | 166 | * |
167 | * The ID of the root cgroup is always 0, and a new cgroup | 167 | * The ID of the root cgroup is always 0, and a new cgroup |
168 | * will be assigned with a smallest available ID. | 168 | * will be assigned with a smallest available ID. |
169 | * | ||
170 | * Allocating/Removing ID must be protected by cgroup_mutex. | ||
169 | */ | 171 | */ |
170 | int id; | 172 | int id; |
171 | 173 | ||
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index dfac5ed31120..f886985a28b2 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h | |||
@@ -171,7 +171,7 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops, | |||
171 | size_t size, int flags, const char *); | 171 | size_t size, int flags, const char *); |
172 | 172 | ||
173 | #define dma_buf_export(priv, ops, size, flags) \ | 173 | #define dma_buf_export(priv, ops, size, flags) \ |
174 | dma_buf_export_named(priv, ops, size, flags, __FILE__) | 174 | dma_buf_export_named(priv, ops, size, flags, KBUILD_MODNAME) |
175 | 175 | ||
176 | int dma_buf_fd(struct dma_buf *dmabuf, int flags); | 176 | int dma_buf_fd(struct dma_buf *dmabuf, int flags); |
177 | struct dma_buf *dma_buf_get(int fd); | 177 | struct dma_buf *dma_buf_get(int fd); |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 3d286ff49ab0..64cf3ef50696 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -99,7 +99,7 @@ struct fsnotify_ops { | |||
99 | struct fsnotify_mark *inode_mark, | 99 | struct fsnotify_mark *inode_mark, |
100 | struct fsnotify_mark *vfsmount_mark, | 100 | struct fsnotify_mark *vfsmount_mark, |
101 | u32 mask, void *data, int data_type, | 101 | u32 mask, void *data, int data_type, |
102 | const unsigned char *file_name); | 102 | const unsigned char *file_name, u32 cookie); |
103 | void (*free_group_priv)(struct fsnotify_group *group); | 103 | void (*free_group_priv)(struct fsnotify_group *group); |
104 | void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); | 104 | void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); |
105 | void (*free_event)(struct fsnotify_event *event); | 105 | void (*free_event)(struct fsnotify_event *event); |
@@ -160,7 +160,7 @@ struct fsnotify_group { | |||
160 | 160 | ||
161 | struct fasync_struct *fsn_fa; /* async notification */ | 161 | struct fasync_struct *fsn_fa; /* async notification */ |
162 | 162 | ||
163 | struct fsnotify_event overflow_event; /* Event we queue when the | 163 | struct fsnotify_event *overflow_event; /* Event we queue when the |
164 | * notification list is too | 164 | * notification list is too |
165 | * full */ | 165 | * full */ |
166 | 166 | ||
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index e7831d203737..35e7eca4e33b 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h | |||
@@ -118,9 +118,7 @@ extern int mq_init_ns(struct ipc_namespace *ns); | |||
118 | * the new maximum will handle anyone else. I may have to revisit this | 118 | * the new maximum will handle anyone else. I may have to revisit this |
119 | * in the future. | 119 | * in the future. |
120 | */ | 120 | */ |
121 | #define MIN_QUEUESMAX 1 | ||
122 | #define DFLT_QUEUESMAX 256 | 121 | #define DFLT_QUEUESMAX 256 |
123 | #define HARD_QUEUESMAX 1024 | ||
124 | #define MIN_MSGMAX 1 | 122 | #define MIN_MSGMAX 1 |
125 | #define DFLT_MSG 10U | 123 | #define DFLT_MSG 10U |
126 | #define DFLT_MSGMAX 10 | 124 | #define DFLT_MSGMAX 10 |
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 5be9f0228a3b..d267623c28cf 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
@@ -249,7 +249,8 @@ void kernfs_notify(struct kernfs_node *kn); | |||
249 | 249 | ||
250 | const void *kernfs_super_ns(struct super_block *sb); | 250 | const void *kernfs_super_ns(struct super_block *sb); |
251 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | 251 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, |
252 | struct kernfs_root *root, const void *ns); | 252 | struct kernfs_root *root, bool *new_sb_created, |
253 | const void *ns); | ||
253 | void kernfs_kill_sb(struct super_block *sb); | 254 | void kernfs_kill_sb(struct super_block *sb); |
254 | 255 | ||
255 | void kernfs_init(void); | 256 | void kernfs_init(void); |
@@ -317,7 +318,7 @@ static inline const void *kernfs_super_ns(struct super_block *sb) | |||
317 | 318 | ||
318 | static inline struct dentry * | 319 | static inline struct dentry * |
319 | kernfs_mount_ns(struct file_system_type *fs_type, int flags, | 320 | kernfs_mount_ns(struct file_system_type *fs_type, int flags, |
320 | struct kernfs_root *root, const void *ns) | 321 | struct kernfs_root *root, bool *new_sb_created, const void *ns) |
321 | { return ERR_PTR(-ENOSYS); } | 322 | { return ERR_PTR(-ENOSYS); } |
322 | 323 | ||
323 | static inline void kernfs_kill_sb(struct super_block *sb) { } | 324 | static inline void kernfs_kill_sb(struct super_block *sb) { } |
@@ -368,9 +369,9 @@ static inline int kernfs_remove_by_name(struct kernfs_node *parent, | |||
368 | 369 | ||
369 | static inline struct dentry * | 370 | static inline struct dentry * |
370 | kernfs_mount(struct file_system_type *fs_type, int flags, | 371 | kernfs_mount(struct file_system_type *fs_type, int flags, |
371 | struct kernfs_root *root) | 372 | struct kernfs_root *root, bool *new_sb_created) |
372 | { | 373 | { |
373 | return kernfs_mount_ns(fs_type, flags, root, NULL); | 374 | return kernfs_mount_ns(fs_type, flags, root, new_sb_created, NULL); |
374 | } | 375 | } |
375 | 376 | ||
376 | #endif /* __LINUX_KERNFS_H */ | 377 | #endif /* __LINUX_KERNFS_H */ |
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index ad1ae7f345ad..78c76cd4d37b 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h | |||
@@ -387,7 +387,7 @@ struct max8997_dev { | |||
387 | struct i2c_client *muic; /* slave addr 0x4a */ | 387 | struct i2c_client *muic; /* slave addr 0x4a */ |
388 | struct mutex iolock; | 388 | struct mutex iolock; |
389 | 389 | ||
390 | int type; | 390 | unsigned long type; |
391 | struct platform_device *battery; /* battery control (not fuel gauge) */ | 391 | struct platform_device *battery; /* battery control (not fuel gauge) */ |
392 | 392 | ||
393 | int irq; | 393 | int irq; |
diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h index 4ecb24b4b863..d68ada502ff3 100644 --- a/include/linux/mfd/max8998-private.h +++ b/include/linux/mfd/max8998-private.h | |||
@@ -163,7 +163,7 @@ struct max8998_dev { | |||
163 | int ono; | 163 | int ono; |
164 | u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; | 164 | u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; |
165 | u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; | 165 | u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; |
166 | int type; | 166 | unsigned long type; |
167 | bool wakeup; | 167 | bool wakeup; |
168 | }; | 168 | }; |
169 | 169 | ||
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index a5a7f0130e96..54b5458ec084 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h | |||
@@ -252,7 +252,7 @@ struct tps65217_board { | |||
252 | struct tps65217 { | 252 | struct tps65217 { |
253 | struct device *dev; | 253 | struct device *dev; |
254 | struct tps65217_board *pdata; | 254 | struct tps65217_board *pdata; |
255 | unsigned int id; | 255 | unsigned long id; |
256 | struct regulator_desc desc[TPS65217_NUM_REGULATOR]; | 256 | struct regulator_desc desc[TPS65217_NUM_REGULATOR]; |
257 | struct regulator_dev *rdev[TPS65217_NUM_REGULATOR]; | 257 | struct regulator_dev *rdev[TPS65217_NUM_REGULATOR]; |
258 | struct regmap *regmap; | 258 | struct regmap *regmap; |
@@ -263,7 +263,7 @@ static inline struct tps65217 *dev_to_tps65217(struct device *dev) | |||
263 | return dev_get_drvdata(dev); | 263 | return dev_get_drvdata(dev); |
264 | } | 264 | } |
265 | 265 | ||
266 | static inline int tps65217_chip_id(struct tps65217 *tps65217) | 266 | static inline unsigned long tps65217_chip_id(struct tps65217 *tps65217) |
267 | { | 267 | { |
268 | return tps65217->id; | 268 | return tps65217->id; |
269 | } | 269 | } |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 440a02ee6f92..e8eeebd49a98 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -752,6 +752,9 @@ struct netdev_phys_port_id { | |||
752 | unsigned char id_len; | 752 | unsigned char id_len; |
753 | }; | 753 | }; |
754 | 754 | ||
755 | typedef u16 (*select_queue_fallback_t)(struct net_device *dev, | ||
756 | struct sk_buff *skb); | ||
757 | |||
755 | /* | 758 | /* |
756 | * This structure defines the management hooks for network devices. | 759 | * This structure defines the management hooks for network devices. |
757 | * The following hooks can be defined; unless noted otherwise, they are | 760 | * The following hooks can be defined; unless noted otherwise, they are |
@@ -783,7 +786,7 @@ struct netdev_phys_port_id { | |||
783 | * Required can not be NULL. | 786 | * Required can not be NULL. |
784 | * | 787 | * |
785 | * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, | 788 | * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, |
786 | * void *accel_priv); | 789 | * void *accel_priv, select_queue_fallback_t fallback); |
787 | * Called to decide which queue to when device supports multiple | 790 | * Called to decide which queue to when device supports multiple |
788 | * transmit queues. | 791 | * transmit queues. |
789 | * | 792 | * |
@@ -1005,7 +1008,8 @@ struct net_device_ops { | |||
1005 | struct net_device *dev); | 1008 | struct net_device *dev); |
1006 | u16 (*ndo_select_queue)(struct net_device *dev, | 1009 | u16 (*ndo_select_queue)(struct net_device *dev, |
1007 | struct sk_buff *skb, | 1010 | struct sk_buff *skb, |
1008 | void *accel_priv); | 1011 | void *accel_priv, |
1012 | select_queue_fallback_t fallback); | ||
1009 | void (*ndo_change_rx_flags)(struct net_device *dev, | 1013 | void (*ndo_change_rx_flags)(struct net_device *dev, |
1010 | int flags); | 1014 | int flags); |
1011 | void (*ndo_set_rx_mode)(struct net_device *dev); | 1015 | void (*ndo_set_rx_mode)(struct net_device *dev); |
@@ -1551,7 +1555,6 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev, | |||
1551 | struct netdev_queue *netdev_pick_tx(struct net_device *dev, | 1555 | struct netdev_queue *netdev_pick_tx(struct net_device *dev, |
1552 | struct sk_buff *skb, | 1556 | struct sk_buff *skb, |
1553 | void *accel_priv); | 1557 | void *accel_priv); |
1554 | u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb); | ||
1555 | 1558 | ||
1556 | /* | 1559 | /* |
1557 | * Net namespace inlines | 1560 | * Net namespace inlines |
@@ -2276,6 +2279,26 @@ static inline void netdev_reset_queue(struct net_device *dev_queue) | |||
2276 | } | 2279 | } |
2277 | 2280 | ||
2278 | /** | 2281 | /** |
2282 | * netdev_cap_txqueue - check if selected tx queue exceeds device queues | ||
2283 | * @dev: network device | ||
2284 | * @queue_index: given tx queue index | ||
2285 | * | ||
2286 | * Returns 0 if given tx queue index >= number of device tx queues, | ||
2287 | * otherwise returns the originally passed tx queue index. | ||
2288 | */ | ||
2289 | static inline u16 netdev_cap_txqueue(struct net_device *dev, u16 queue_index) | ||
2290 | { | ||
2291 | if (unlikely(queue_index >= dev->real_num_tx_queues)) { | ||
2292 | net_warn_ratelimited("%s selects TX queue %d, but real number of TX queues is %d\n", | ||
2293 | dev->name, queue_index, | ||
2294 | dev->real_num_tx_queues); | ||
2295 | return 0; | ||
2296 | } | ||
2297 | |||
2298 | return queue_index; | ||
2299 | } | ||
2300 | |||
2301 | /** | ||
2279 | * netif_running - test if up | 2302 | * netif_running - test if up |
2280 | * @dev: network device | 2303 | * @dev: network device |
2281 | * | 2304 | * |
@@ -3068,7 +3091,12 @@ void netdev_change_features(struct net_device *dev); | |||
3068 | void netif_stacked_transfer_operstate(const struct net_device *rootdev, | 3091 | void netif_stacked_transfer_operstate(const struct net_device *rootdev, |
3069 | struct net_device *dev); | 3092 | struct net_device *dev); |
3070 | 3093 | ||
3071 | netdev_features_t netif_skb_features(struct sk_buff *skb); | 3094 | netdev_features_t netif_skb_dev_features(struct sk_buff *skb, |
3095 | const struct net_device *dev); | ||
3096 | static inline netdev_features_t netif_skb_features(struct sk_buff *skb) | ||
3097 | { | ||
3098 | return netif_skb_dev_features(skb, skb->dev); | ||
3099 | } | ||
3072 | 3100 | ||
3073 | static inline bool net_gso_ok(netdev_features_t features, int gso_type) | 3101 | static inline bool net_gso_ok(netdev_features_t features, int gso_type) |
3074 | { | 3102 | { |
diff --git a/include/linux/pci.h b/include/linux/pci.h index fb57c892b214..33aa2caf0f0c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1169,8 +1169,23 @@ void msi_remove_pci_irq_vectors(struct pci_dev *dev); | |||
1169 | void pci_restore_msi_state(struct pci_dev *dev); | 1169 | void pci_restore_msi_state(struct pci_dev *dev); |
1170 | int pci_msi_enabled(void); | 1170 | int pci_msi_enabled(void); |
1171 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); | 1171 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); |
1172 | static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
1173 | { | ||
1174 | int rc = pci_enable_msi_range(dev, nvec, nvec); | ||
1175 | if (rc < 0) | ||
1176 | return rc; | ||
1177 | return 0; | ||
1178 | } | ||
1172 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | 1179 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, |
1173 | int minvec, int maxvec); | 1180 | int minvec, int maxvec); |
1181 | static inline int pci_enable_msix_exact(struct pci_dev *dev, | ||
1182 | struct msix_entry *entries, int nvec) | ||
1183 | { | ||
1184 | int rc = pci_enable_msix_range(dev, entries, nvec, nvec); | ||
1185 | if (rc < 0) | ||
1186 | return rc; | ||
1187 | return 0; | ||
1188 | } | ||
1174 | #else | 1189 | #else |
1175 | static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } | 1190 | static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } |
1176 | static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) | 1191 | static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) |
@@ -1189,9 +1204,14 @@ static inline int pci_msi_enabled(void) { return 0; } | |||
1189 | static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, | 1204 | static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, |
1190 | int maxvec) | 1205 | int maxvec) |
1191 | { return -ENOSYS; } | 1206 | { return -ENOSYS; } |
1207 | static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
1208 | { return -ENOSYS; } | ||
1192 | static inline int pci_enable_msix_range(struct pci_dev *dev, | 1209 | static inline int pci_enable_msix_range(struct pci_dev *dev, |
1193 | struct msix_entry *entries, int minvec, int maxvec) | 1210 | struct msix_entry *entries, int minvec, int maxvec) |
1194 | { return -ENOSYS; } | 1211 | { return -ENOSYS; } |
1212 | static inline int pci_enable_msix_exact(struct pci_dev *dev, | ||
1213 | struct msix_entry *entries, int nvec) | ||
1214 | { return -ENOSYS; } | ||
1195 | #endif | 1215 | #endif |
1196 | 1216 | ||
1197 | #ifdef CONFIG_PCIEPORTBUS | 1217 | #ifdef CONFIG_PCIEPORTBUS |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f589c9af8cbf..3ebbbe7b6d05 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -2916,5 +2916,22 @@ static inline bool skb_head_is_locked(const struct sk_buff *skb) | |||
2916 | { | 2916 | { |
2917 | return !skb->head_frag || skb_cloned(skb); | 2917 | return !skb->head_frag || skb_cloned(skb); |
2918 | } | 2918 | } |
2919 | |||
2920 | /** | ||
2921 | * skb_gso_network_seglen - Return length of individual segments of a gso packet | ||
2922 | * | ||
2923 | * @skb: GSO skb | ||
2924 | * | ||
2925 | * skb_gso_network_seglen is used to determine the real size of the | ||
2926 | * individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP). | ||
2927 | * | ||
2928 | * The MAC/L2 header is not accounted for. | ||
2929 | */ | ||
2930 | static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb) | ||
2931 | { | ||
2932 | unsigned int hdr_len = skb_transport_header(skb) - | ||
2933 | skb_network_header(skb); | ||
2934 | return hdr_len + skb_gso_transport_seglen(skb); | ||
2935 | } | ||
2919 | #endif /* __KERNEL__ */ | 2936 | #endif /* __KERNEL__ */ |
2920 | #endif /* _LINUX_SKBUFF_H */ | 2937 | #endif /* _LINUX_SKBUFF_H */ |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 40ed9e9a77e5..a747a77ea584 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -281,13 +281,15 @@ asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, | |||
281 | asmlinkage long sys_sched_setparam(pid_t pid, | 281 | asmlinkage long sys_sched_setparam(pid_t pid, |
282 | struct sched_param __user *param); | 282 | struct sched_param __user *param); |
283 | asmlinkage long sys_sched_setattr(pid_t pid, | 283 | asmlinkage long sys_sched_setattr(pid_t pid, |
284 | struct sched_attr __user *attr); | 284 | struct sched_attr __user *attr, |
285 | unsigned int flags); | ||
285 | asmlinkage long sys_sched_getscheduler(pid_t pid); | 286 | asmlinkage long sys_sched_getscheduler(pid_t pid); |
286 | asmlinkage long sys_sched_getparam(pid_t pid, | 287 | asmlinkage long sys_sched_getparam(pid_t pid, |
287 | struct sched_param __user *param); | 288 | struct sched_param __user *param); |
288 | asmlinkage long sys_sched_getattr(pid_t pid, | 289 | asmlinkage long sys_sched_getattr(pid_t pid, |
289 | struct sched_attr __user *attr, | 290 | struct sched_attr __user *attr, |
290 | unsigned int size); | 291 | unsigned int size, |
292 | unsigned int flags); | ||
291 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, | 293 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, |
292 | unsigned long __user *user_mask_ptr); | 294 | unsigned long __user *user_mask_ptr); |
293 | asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, | 295 | asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, |
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index e32251e00e62..edff2b97b864 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h | |||
@@ -126,6 +126,7 @@ extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); | |||
126 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); | 126 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); |
127 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); | 127 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); |
128 | extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); | 128 | extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); |
129 | extern bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs); | ||
129 | #else /* !CONFIG_UPROBES */ | 130 | #else /* !CONFIG_UPROBES */ |
130 | struct uprobes_state { | 131 | struct uprobes_state { |
131 | }; | 132 | }; |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 594521ba0d43..704f4f652d0a 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -419,10 +419,7 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active, | |||
419 | static struct lock_class_key __key; \ | 419 | static struct lock_class_key __key; \ |
420 | const char *__lock_name; \ | 420 | const char *__lock_name; \ |
421 | \ | 421 | \ |
422 | if (__builtin_constant_p(fmt)) \ | 422 | __lock_name = #fmt#args; \ |
423 | __lock_name = (fmt); \ | ||
424 | else \ | ||
425 | __lock_name = #fmt; \ | ||
426 | \ | 423 | \ |
427 | __alloc_workqueue_key((fmt), (flags), (max_active), \ | 424 | __alloc_workqueue_key((fmt), (flags), (max_active), \ |
428 | &__key, __lock_name, ##args); \ | 425 | &__key, __lock_name, ##args); \ |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index fc0e4320aa6d..021b8a319b9e 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -97,7 +97,7 @@ void writeback_inodes_sb_nr(struct super_block *, unsigned long nr, | |||
97 | int try_to_writeback_inodes_sb(struct super_block *, enum wb_reason reason); | 97 | int try_to_writeback_inodes_sb(struct super_block *, enum wb_reason reason); |
98 | int try_to_writeback_inodes_sb_nr(struct super_block *, unsigned long nr, | 98 | int try_to_writeback_inodes_sb_nr(struct super_block *, unsigned long nr, |
99 | enum wb_reason reason); | 99 | enum wb_reason reason); |
100 | void sync_inodes_sb(struct super_block *sb, unsigned long older_than_this); | 100 | void sync_inodes_sb(struct super_block *); |
101 | void wakeup_flusher_threads(long nr_pages, enum wb_reason reason); | 101 | void wakeup_flusher_threads(long nr_pages, enum wb_reason reason); |
102 | void inode_wait_for_writeback(struct inode *inode); | 102 | void inode_wait_for_writeback(struct inode *inode); |
103 | 103 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index d992ca3145fe..6ee76c804893 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -1653,17 +1653,6 @@ struct sctp_association { | |||
1653 | /* This is the last advertised value of rwnd over a SACK chunk. */ | 1653 | /* This is the last advertised value of rwnd over a SACK chunk. */ |
1654 | __u32 a_rwnd; | 1654 | __u32 a_rwnd; |
1655 | 1655 | ||
1656 | /* Number of bytes by which the rwnd has slopped. The rwnd is allowed | ||
1657 | * to slop over a maximum of the association's frag_point. | ||
1658 | */ | ||
1659 | __u32 rwnd_over; | ||
1660 | |||
1661 | /* Keeps treack of rwnd pressure. This happens when we have | ||
1662 | * a window, but not recevie buffer (i.e small packets). This one | ||
1663 | * is releases slowly (1 PMTU at a time ). | ||
1664 | */ | ||
1665 | __u32 rwnd_press; | ||
1666 | |||
1667 | /* This is the sndbuf size in use for the association. | 1656 | /* This is the sndbuf size in use for the association. |
1668 | * This corresponds to the sndbuf size for the association, | 1657 | * This corresponds to the sndbuf size for the association, |
1669 | * as specified in the sk->sndbuf. | 1658 | * as specified in the sk->sndbuf. |
@@ -1892,8 +1881,7 @@ void sctp_assoc_update(struct sctp_association *old, | |||
1892 | __u32 sctp_association_get_next_tsn(struct sctp_association *); | 1881 | __u32 sctp_association_get_next_tsn(struct sctp_association *); |
1893 | 1882 | ||
1894 | void sctp_assoc_sync_pmtu(struct sock *, struct sctp_association *); | 1883 | void sctp_assoc_sync_pmtu(struct sock *, struct sctp_association *); |
1895 | void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int); | 1884 | void sctp_assoc_rwnd_update(struct sctp_association *, bool); |
1896 | void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned int); | ||
1897 | void sctp_assoc_set_primary(struct sctp_association *, | 1885 | void sctp_assoc_set_primary(struct sctp_association *, |
1898 | struct sctp_transport *); | 1886 | struct sctp_transport *); |
1899 | void sctp_assoc_del_nonprimary_peers(struct sctp_association *, | 1887 | void sctp_assoc_del_nonprimary_peers(struct sctp_association *, |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 68d92e36facd..6e89ef6c11c1 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -449,14 +449,22 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, | |||
449 | /* dapm audio pin control and status */ | 449 | /* dapm audio pin control and status */ |
450 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, | 450 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, |
451 | const char *pin); | 451 | const char *pin); |
452 | int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
453 | const char *pin); | ||
452 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, | 454 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, |
453 | const char *pin); | 455 | const char *pin); |
456 | int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
457 | const char *pin); | ||
454 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); | 458 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); |
459 | int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
460 | const char *pin); | ||
455 | int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, | 461 | int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, |
456 | const char *pin); | 462 | const char *pin); |
457 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); | 463 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); |
458 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | 464 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, |
459 | const char *pin); | 465 | const char *pin); |
466 | int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
467 | const char *pin); | ||
460 | int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | 468 | int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, |
461 | const char *pin); | 469 | const char *pin); |
462 | void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec); | 470 | void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec); |
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index c7bbbe794e65..464ea82e10db 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h | |||
@@ -287,11 +287,11 @@ TRACE_EVENT(writeback_queue_io, | |||
287 | __field(int, reason) | 287 | __field(int, reason) |
288 | ), | 288 | ), |
289 | TP_fast_assign( | 289 | TP_fast_assign( |
290 | unsigned long older_than_this = work->older_than_this; | 290 | unsigned long *older_than_this = work->older_than_this; |
291 | strncpy(__entry->name, dev_name(wb->bdi->dev), 32); | 291 | strncpy(__entry->name, dev_name(wb->bdi->dev), 32); |
292 | __entry->older = older_than_this; | 292 | __entry->older = older_than_this ? *older_than_this : 0; |
293 | __entry->age = older_than_this ? | 293 | __entry->age = older_than_this ? |
294 | (jiffies - older_than_this) * 1000 / HZ : -1; | 294 | (jiffies - *older_than_this) * 1000 / HZ : -1; |
295 | __entry->moved = moved; | 295 | __entry->moved = moved; |
296 | __entry->reason = work->reason; | 296 | __entry->reason = work->reason; |
297 | ), | 297 | ), |
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index a20a9b4d3871..dde8041f40d2 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h | |||
@@ -692,9 +692,13 @@ __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \ | |||
692 | __SYSCALL(__NR_kcmp, sys_kcmp) | 692 | __SYSCALL(__NR_kcmp, sys_kcmp) |
693 | #define __NR_finit_module 273 | 693 | #define __NR_finit_module 273 |
694 | __SYSCALL(__NR_finit_module, sys_finit_module) | 694 | __SYSCALL(__NR_finit_module, sys_finit_module) |
695 | #define __NR_sched_setattr 274 | ||
696 | __SYSCALL(__NR_sched_setattr, sys_sched_setattr) | ||
697 | #define __NR_sched_getattr 275 | ||
698 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) | ||
695 | 699 | ||
696 | #undef __NR_syscalls | 700 | #undef __NR_syscalls |
697 | #define __NR_syscalls 274 | 701 | #define __NR_syscalls 276 |
698 | 702 | ||
699 | /* | 703 | /* |
700 | * All syscalls below here should go away really, | 704 | * All syscalls below here should go away really, |
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 3c9a833992e8..b06c8ed68707 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h | |||
@@ -619,6 +619,8 @@ struct drm_gem_open { | |||
619 | #define DRM_PRIME_CAP_EXPORT 0x2 | 619 | #define DRM_PRIME_CAP_EXPORT 0x2 |
620 | #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 | 620 | #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 |
621 | #define DRM_CAP_ASYNC_PAGE_FLIP 0x7 | 621 | #define DRM_CAP_ASYNC_PAGE_FLIP 0x7 |
622 | #define DRM_CAP_CURSOR_WIDTH 0x8 | ||
623 | #define DRM_CAP_CURSOR_HEIGHT 0x9 | ||
622 | 624 | ||
623 | /** DRM_IOCTL_GET_CAP ioctl argument type */ | 625 | /** DRM_IOCTL_GET_CAP ioctl argument type */ |
624 | struct drm_get_cap { | 626 | struct drm_get_cap { |
diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index 9971c560ed9a..87792a5fee3b 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h | |||
@@ -87,6 +87,7 @@ | |||
87 | #define DRM_VMW_PARAM_MAX_SURF_MEMORY 7 | 87 | #define DRM_VMW_PARAM_MAX_SURF_MEMORY 7 |
88 | #define DRM_VMW_PARAM_3D_CAPS_SIZE 8 | 88 | #define DRM_VMW_PARAM_3D_CAPS_SIZE 8 |
89 | #define DRM_VMW_PARAM_MAX_MOB_MEMORY 9 | 89 | #define DRM_VMW_PARAM_MAX_MOB_MEMORY 9 |
90 | #define DRM_VMW_PARAM_MAX_MOB_SIZE 10 | ||
90 | 91 | ||
91 | /** | 92 | /** |
92 | * struct drm_vmw_getparam_arg | 93 | * struct drm_vmw_getparam_arg |
diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c index 383d638340b8..5bb8bfe67149 100644 --- a/ipc/mq_sysctl.c +++ b/ipc/mq_sysctl.c | |||
@@ -22,6 +22,16 @@ static void *get_mq(ctl_table *table) | |||
22 | return which; | 22 | return which; |
23 | } | 23 | } |
24 | 24 | ||
25 | static int proc_mq_dointvec(ctl_table *table, int write, | ||
26 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
27 | { | ||
28 | struct ctl_table mq_table; | ||
29 | memcpy(&mq_table, table, sizeof(mq_table)); | ||
30 | mq_table.data = get_mq(table); | ||
31 | |||
32 | return proc_dointvec(&mq_table, write, buffer, lenp, ppos); | ||
33 | } | ||
34 | |||
25 | static int proc_mq_dointvec_minmax(ctl_table *table, int write, | 35 | static int proc_mq_dointvec_minmax(ctl_table *table, int write, |
26 | void __user *buffer, size_t *lenp, loff_t *ppos) | 36 | void __user *buffer, size_t *lenp, loff_t *ppos) |
27 | { | 37 | { |
@@ -33,12 +43,10 @@ static int proc_mq_dointvec_minmax(ctl_table *table, int write, | |||
33 | lenp, ppos); | 43 | lenp, ppos); |
34 | } | 44 | } |
35 | #else | 45 | #else |
46 | #define proc_mq_dointvec NULL | ||
36 | #define proc_mq_dointvec_minmax NULL | 47 | #define proc_mq_dointvec_minmax NULL |
37 | #endif | 48 | #endif |
38 | 49 | ||
39 | static int msg_queues_limit_min = MIN_QUEUESMAX; | ||
40 | static int msg_queues_limit_max = HARD_QUEUESMAX; | ||
41 | |||
42 | static int msg_max_limit_min = MIN_MSGMAX; | 50 | static int msg_max_limit_min = MIN_MSGMAX; |
43 | static int msg_max_limit_max = HARD_MSGMAX; | 51 | static int msg_max_limit_max = HARD_MSGMAX; |
44 | 52 | ||
@@ -51,9 +59,7 @@ static ctl_table mq_sysctls[] = { | |||
51 | .data = &init_ipc_ns.mq_queues_max, | 59 | .data = &init_ipc_ns.mq_queues_max, |
52 | .maxlen = sizeof(int), | 60 | .maxlen = sizeof(int), |
53 | .mode = 0644, | 61 | .mode = 0644, |
54 | .proc_handler = proc_mq_dointvec_minmax, | 62 | .proc_handler = proc_mq_dointvec, |
55 | .extra1 = &msg_queues_limit_min, | ||
56 | .extra2 = &msg_queues_limit_max, | ||
57 | }, | 63 | }, |
58 | { | 64 | { |
59 | .procname = "msg_max", | 65 | .procname = "msg_max", |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index ccf1f9fd263a..c3b31179122c 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -433,9 +433,9 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry, | |||
433 | error = -EACCES; | 433 | error = -EACCES; |
434 | goto out_unlock; | 434 | goto out_unlock; |
435 | } | 435 | } |
436 | if (ipc_ns->mq_queues_count >= HARD_QUEUESMAX || | 436 | |
437 | (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max && | 437 | if (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max && |
438 | !capable(CAP_SYS_RESOURCE))) { | 438 | !capable(CAP_SYS_RESOURCE)) { |
439 | error = -ENOSPC; | 439 | error = -ENOSPC; |
440 | goto out_unlock; | 440 | goto out_unlock; |
441 | } | 441 | } |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 67ccf0e7cca9..135944a7b28a 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -916,7 +916,7 @@ static int audit_tree_handle_event(struct fsnotify_group *group, | |||
916 | struct fsnotify_mark *inode_mark, | 916 | struct fsnotify_mark *inode_mark, |
917 | struct fsnotify_mark *vfsmount_mark, | 917 | struct fsnotify_mark *vfsmount_mark, |
918 | u32 mask, void *data, int data_type, | 918 | u32 mask, void *data, int data_type, |
919 | const unsigned char *file_name) | 919 | const unsigned char *file_name, u32 cookie) |
920 | { | 920 | { |
921 | return 0; | 921 | return 0; |
922 | } | 922 | } |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 2596fac5dcb4..70b4554d2fbe 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -471,7 +471,7 @@ static int audit_watch_handle_event(struct fsnotify_group *group, | |||
471 | struct fsnotify_mark *inode_mark, | 471 | struct fsnotify_mark *inode_mark, |
472 | struct fsnotify_mark *vfsmount_mark, | 472 | struct fsnotify_mark *vfsmount_mark, |
473 | u32 mask, void *data, int data_type, | 473 | u32 mask, void *data, int data_type, |
474 | const unsigned char *dname) | 474 | const unsigned char *dname, u32 cookie) |
475 | { | 475 | { |
476 | struct inode *inode; | 476 | struct inode *inode; |
477 | struct audit_parent *parent; | 477 | struct audit_parent *parent; |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e2f46ba37f72..105f273b6f86 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -886,7 +886,9 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
886 | * per-subsystem and moved to css->id so that lookups are | 886 | * per-subsystem and moved to css->id so that lookups are |
887 | * successful until the target css is released. | 887 | * successful until the target css is released. |
888 | */ | 888 | */ |
889 | mutex_lock(&cgroup_mutex); | ||
889 | idr_remove(&cgrp->root->cgroup_idr, cgrp->id); | 890 | idr_remove(&cgrp->root->cgroup_idr, cgrp->id); |
891 | mutex_unlock(&cgroup_mutex); | ||
890 | cgrp->id = -1; | 892 | cgrp->id = -1; |
891 | 893 | ||
892 | call_rcu(&cgrp->rcu_head, cgroup_free_rcu); | 894 | call_rcu(&cgrp->rcu_head, cgroup_free_rcu); |
@@ -1566,10 +1568,10 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, | |||
1566 | mutex_lock(&cgroup_mutex); | 1568 | mutex_lock(&cgroup_mutex); |
1567 | mutex_lock(&cgroup_root_mutex); | 1569 | mutex_lock(&cgroup_root_mutex); |
1568 | 1570 | ||
1569 | root_cgrp->id = idr_alloc(&root->cgroup_idr, root_cgrp, | 1571 | ret = idr_alloc(&root->cgroup_idr, root_cgrp, 0, 1, GFP_KERNEL); |
1570 | 0, 1, GFP_KERNEL); | 1572 | if (ret < 0) |
1571 | if (root_cgrp->id < 0) | ||
1572 | goto unlock_drop; | 1573 | goto unlock_drop; |
1574 | root_cgrp->id = ret; | ||
1573 | 1575 | ||
1574 | /* Check for name clashes with existing mounts */ | 1576 | /* Check for name clashes with existing mounts */ |
1575 | ret = -EBUSY; | 1577 | ret = -EBUSY; |
@@ -2763,10 +2765,7 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) | |||
2763 | */ | 2765 | */ |
2764 | update_before = cgroup_serial_nr_next; | 2766 | update_before = cgroup_serial_nr_next; |
2765 | 2767 | ||
2766 | mutex_unlock(&cgroup_mutex); | ||
2767 | |||
2768 | /* add/rm files for all cgroups created before */ | 2768 | /* add/rm files for all cgroups created before */ |
2769 | rcu_read_lock(); | ||
2770 | css_for_each_descendant_pre(css, cgroup_css(root, ss)) { | 2769 | css_for_each_descendant_pre(css, cgroup_css(root, ss)) { |
2771 | struct cgroup *cgrp = css->cgroup; | 2770 | struct cgroup *cgrp = css->cgroup; |
2772 | 2771 | ||
@@ -2775,23 +2774,19 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) | |||
2775 | 2774 | ||
2776 | inode = cgrp->dentry->d_inode; | 2775 | inode = cgrp->dentry->d_inode; |
2777 | dget(cgrp->dentry); | 2776 | dget(cgrp->dentry); |
2778 | rcu_read_unlock(); | ||
2779 | |||
2780 | dput(prev); | 2777 | dput(prev); |
2781 | prev = cgrp->dentry; | 2778 | prev = cgrp->dentry; |
2782 | 2779 | ||
2780 | mutex_unlock(&cgroup_mutex); | ||
2783 | mutex_lock(&inode->i_mutex); | 2781 | mutex_lock(&inode->i_mutex); |
2784 | mutex_lock(&cgroup_mutex); | 2782 | mutex_lock(&cgroup_mutex); |
2785 | if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp)) | 2783 | if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp)) |
2786 | ret = cgroup_addrm_files(cgrp, cfts, is_add); | 2784 | ret = cgroup_addrm_files(cgrp, cfts, is_add); |
2787 | mutex_unlock(&cgroup_mutex); | ||
2788 | mutex_unlock(&inode->i_mutex); | 2785 | mutex_unlock(&inode->i_mutex); |
2789 | |||
2790 | rcu_read_lock(); | ||
2791 | if (ret) | 2786 | if (ret) |
2792 | break; | 2787 | break; |
2793 | } | 2788 | } |
2794 | rcu_read_unlock(); | 2789 | mutex_unlock(&cgroup_mutex); |
2795 | dput(prev); | 2790 | dput(prev); |
2796 | deactivate_super(sb); | 2791 | deactivate_super(sb); |
2797 | return ret; | 2792 | return ret; |
@@ -2910,9 +2905,14 @@ static void cgroup_enable_task_cg_lists(void) | |||
2910 | * We should check if the process is exiting, otherwise | 2905 | * We should check if the process is exiting, otherwise |
2911 | * it will race with cgroup_exit() in that the list | 2906 | * it will race with cgroup_exit() in that the list |
2912 | * entry won't be deleted though the process has exited. | 2907 | * entry won't be deleted though the process has exited. |
2908 | * Do it while holding siglock so that we don't end up | ||
2909 | * racing against cgroup_exit(). | ||
2913 | */ | 2910 | */ |
2911 | spin_lock_irq(&p->sighand->siglock); | ||
2914 | if (!(p->flags & PF_EXITING) && list_empty(&p->cg_list)) | 2912 | if (!(p->flags & PF_EXITING) && list_empty(&p->cg_list)) |
2915 | list_add(&p->cg_list, &task_css_set(p)->tasks); | 2913 | list_add(&p->cg_list, &task_css_set(p)->tasks); |
2914 | spin_unlock_irq(&p->sighand->siglock); | ||
2915 | |||
2916 | task_unlock(p); | 2916 | task_unlock(p); |
2917 | } while_each_thread(g, p); | 2917 | } while_each_thread(g, p); |
2918 | read_unlock(&tasklist_lock); | 2918 | read_unlock(&tasklist_lock); |
@@ -4158,7 +4158,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4158 | struct cgroup *cgrp; | 4158 | struct cgroup *cgrp; |
4159 | struct cgroup_name *name; | 4159 | struct cgroup_name *name; |
4160 | struct cgroupfs_root *root = parent->root; | 4160 | struct cgroupfs_root *root = parent->root; |
4161 | int ssid, err = 0; | 4161 | int ssid, err; |
4162 | struct cgroup_subsys *ss; | 4162 | struct cgroup_subsys *ss; |
4163 | struct super_block *sb = root->sb; | 4163 | struct super_block *sb = root->sb; |
4164 | 4164 | ||
@@ -4168,19 +4168,13 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4168 | return -ENOMEM; | 4168 | return -ENOMEM; |
4169 | 4169 | ||
4170 | name = cgroup_alloc_name(dentry); | 4170 | name = cgroup_alloc_name(dentry); |
4171 | if (!name) | 4171 | if (!name) { |
4172 | err = -ENOMEM; | ||
4172 | goto err_free_cgrp; | 4173 | goto err_free_cgrp; |
4174 | } | ||
4173 | rcu_assign_pointer(cgrp->name, name); | 4175 | rcu_assign_pointer(cgrp->name, name); |
4174 | 4176 | ||
4175 | /* | 4177 | /* |
4176 | * Temporarily set the pointer to NULL, so idr_find() won't return | ||
4177 | * a half-baked cgroup. | ||
4178 | */ | ||
4179 | cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL); | ||
4180 | if (cgrp->id < 0) | ||
4181 | goto err_free_name; | ||
4182 | |||
4183 | /* | ||
4184 | * Only live parents can have children. Note that the liveliness | 4178 | * Only live parents can have children. Note that the liveliness |
4185 | * check isn't strictly necessary because cgroup_mkdir() and | 4179 | * check isn't strictly necessary because cgroup_mkdir() and |
4186 | * cgroup_rmdir() are fully synchronized by i_mutex; however, do it | 4180 | * cgroup_rmdir() are fully synchronized by i_mutex; however, do it |
@@ -4189,7 +4183,17 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4189 | */ | 4183 | */ |
4190 | if (!cgroup_lock_live_group(parent)) { | 4184 | if (!cgroup_lock_live_group(parent)) { |
4191 | err = -ENODEV; | 4185 | err = -ENODEV; |
4192 | goto err_free_id; | 4186 | goto err_free_name; |
4187 | } | ||
4188 | |||
4189 | /* | ||
4190 | * Temporarily set the pointer to NULL, so idr_find() won't return | ||
4191 | * a half-baked cgroup. | ||
4192 | */ | ||
4193 | cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL); | ||
4194 | if (cgrp->id < 0) { | ||
4195 | err = -ENOMEM; | ||
4196 | goto err_unlock; | ||
4193 | } | 4197 | } |
4194 | 4198 | ||
4195 | /* Grab a reference on the superblock so the hierarchy doesn't | 4199 | /* Grab a reference on the superblock so the hierarchy doesn't |
@@ -4221,7 +4225,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4221 | */ | 4225 | */ |
4222 | err = cgroup_create_file(dentry, S_IFDIR | mode, sb); | 4226 | err = cgroup_create_file(dentry, S_IFDIR | mode, sb); |
4223 | if (err < 0) | 4227 | if (err < 0) |
4224 | goto err_unlock; | 4228 | goto err_free_id; |
4225 | lockdep_assert_held(&dentry->d_inode->i_mutex); | 4229 | lockdep_assert_held(&dentry->d_inode->i_mutex); |
4226 | 4230 | ||
4227 | cgrp->serial_nr = cgroup_serial_nr_next++; | 4231 | cgrp->serial_nr = cgroup_serial_nr_next++; |
@@ -4257,12 +4261,12 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4257 | 4261 | ||
4258 | return 0; | 4262 | return 0; |
4259 | 4263 | ||
4260 | err_unlock: | ||
4261 | mutex_unlock(&cgroup_mutex); | ||
4262 | /* Release the reference count that we took on the superblock */ | ||
4263 | deactivate_super(sb); | ||
4264 | err_free_id: | 4264 | err_free_id: |
4265 | idr_remove(&root->cgroup_idr, cgrp->id); | 4265 | idr_remove(&root->cgroup_idr, cgrp->id); |
4266 | /* Release the reference count that we took on the superblock */ | ||
4267 | deactivate_super(sb); | ||
4268 | err_unlock: | ||
4269 | mutex_unlock(&cgroup_mutex); | ||
4266 | err_free_name: | 4270 | err_free_name: |
4267 | kfree(rcu_dereference_raw(cgrp->name)); | 4271 | kfree(rcu_dereference_raw(cgrp->name)); |
4268 | err_free_cgrp: | 4272 | err_free_cgrp: |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 56003c6edfd3..fa0b2d4ad83c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -7856,14 +7856,14 @@ static void perf_pmu_rotate_stop(struct pmu *pmu) | |||
7856 | static void __perf_event_exit_context(void *__info) | 7856 | static void __perf_event_exit_context(void *__info) |
7857 | { | 7857 | { |
7858 | struct perf_event_context *ctx = __info; | 7858 | struct perf_event_context *ctx = __info; |
7859 | struct perf_event *event, *tmp; | 7859 | struct perf_event *event; |
7860 | 7860 | ||
7861 | perf_pmu_rotate_stop(ctx->pmu); | 7861 | perf_pmu_rotate_stop(ctx->pmu); |
7862 | 7862 | ||
7863 | list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry) | 7863 | rcu_read_lock(); |
7864 | __perf_remove_from_context(event); | 7864 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) |
7865 | list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, group_entry) | ||
7866 | __perf_remove_from_context(event); | 7865 | __perf_remove_from_context(event); |
7866 | rcu_read_unlock(); | ||
7867 | } | 7867 | } |
7868 | 7868 | ||
7869 | static void perf_event_exit_cpu_context(int cpu) | 7869 | static void perf_event_exit_cpu_context(int cpu) |
@@ -7887,11 +7887,11 @@ static void perf_event_exit_cpu(int cpu) | |||
7887 | { | 7887 | { |
7888 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); | 7888 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
7889 | 7889 | ||
7890 | perf_event_exit_cpu_context(cpu); | ||
7891 | |||
7890 | mutex_lock(&swhash->hlist_mutex); | 7892 | mutex_lock(&swhash->hlist_mutex); |
7891 | swevent_hlist_release(swhash); | 7893 | swevent_hlist_release(swhash); |
7892 | mutex_unlock(&swhash->hlist_mutex); | 7894 | mutex_unlock(&swhash->hlist_mutex); |
7893 | |||
7894 | perf_event_exit_cpu_context(cpu); | ||
7895 | } | 7895 | } |
7896 | #else | 7896 | #else |
7897 | static inline void perf_event_exit_cpu(int cpu) { } | 7897 | static inline void perf_event_exit_cpu(int cpu) { } |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 307d87c0991a..04709b66369d 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1804,6 +1804,11 @@ static bool handle_trampoline(struct pt_regs *regs) | |||
1804 | return true; | 1804 | return true; |
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs) | ||
1808 | { | ||
1809 | return false; | ||
1810 | } | ||
1811 | |||
1807 | /* | 1812 | /* |
1808 | * Run handler and ask thread to singlestep. | 1813 | * Run handler and ask thread to singlestep. |
1809 | * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. | 1814 | * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. |
@@ -1858,7 +1863,11 @@ static void handle_swbp(struct pt_regs *regs) | |||
1858 | if (!get_utask()) | 1863 | if (!get_utask()) |
1859 | goto out; | 1864 | goto out; |
1860 | 1865 | ||
1866 | if (arch_uprobe_ignore(&uprobe->arch, regs)) | ||
1867 | goto out; | ||
1868 | |||
1861 | handler_chain(uprobe, regs); | 1869 | handler_chain(uprobe, regs); |
1870 | |||
1862 | if (can_skip_sstep(uprobe, regs)) | 1871 | if (can_skip_sstep(uprobe, regs)) |
1863 | goto out; | 1872 | goto out; |
1864 | 1873 | ||
diff --git a/kernel/power/console.c b/kernel/power/console.c index eacb8bd8cab4..aba9c545a0e3 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/kbd_kern.h> | 9 | #include <linux/kbd_kern.h> |
10 | #include <linux/vt.h> | 10 | #include <linux/vt.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/slab.h> | ||
12 | #include "power.h" | 13 | #include "power.h" |
13 | 14 | ||
14 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) | 15 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) |
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index b1d255f04135..4dae9cbe9259 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -1076,7 +1076,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear) | |||
1076 | next_seq = log_next_seq; | 1076 | next_seq = log_next_seq; |
1077 | 1077 | ||
1078 | len = 0; | 1078 | len = 0; |
1079 | prev = 0; | ||
1080 | while (len >= 0 && seq < next_seq) { | 1079 | while (len >= 0 && seq < next_seq) { |
1081 | struct printk_log *msg = log_from_idx(idx); | 1080 | struct printk_log *msg = log_from_idx(idx); |
1082 | int textlen; | 1081 | int textlen; |
@@ -2788,7 +2787,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, | |||
2788 | next_idx = idx; | 2787 | next_idx = idx; |
2789 | 2788 | ||
2790 | l = 0; | 2789 | l = 0; |
2791 | prev = 0; | ||
2792 | while (seq < dumper->next_seq) { | 2790 | while (seq < dumper->next_seq) { |
2793 | struct printk_log *msg = log_from_idx(idx); | 2791 | struct printk_log *msg = log_from_idx(idx); |
2794 | 2792 | ||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index b46131ef6aab..6edbef296ece 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -1952,7 +1952,7 @@ static int dl_overflow(struct task_struct *p, int policy, | |||
1952 | { | 1952 | { |
1953 | 1953 | ||
1954 | struct dl_bw *dl_b = dl_bw_of(task_cpu(p)); | 1954 | struct dl_bw *dl_b = dl_bw_of(task_cpu(p)); |
1955 | u64 period = attr->sched_period; | 1955 | u64 period = attr->sched_period ?: attr->sched_deadline; |
1956 | u64 runtime = attr->sched_runtime; | 1956 | u64 runtime = attr->sched_runtime; |
1957 | u64 new_bw = dl_policy(policy) ? to_ratio(period, runtime) : 0; | 1957 | u64 new_bw = dl_policy(policy) ? to_ratio(period, runtime) : 0; |
1958 | int cpus, err = -1; | 1958 | int cpus, err = -1; |
@@ -3661,13 +3661,14 @@ SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param) | |||
3661 | * @pid: the pid in question. | 3661 | * @pid: the pid in question. |
3662 | * @uattr: structure containing the extended parameters. | 3662 | * @uattr: structure containing the extended parameters. |
3663 | */ | 3663 | */ |
3664 | SYSCALL_DEFINE2(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr) | 3664 | SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, |
3665 | unsigned int, flags) | ||
3665 | { | 3666 | { |
3666 | struct sched_attr attr; | 3667 | struct sched_attr attr; |
3667 | struct task_struct *p; | 3668 | struct task_struct *p; |
3668 | int retval; | 3669 | int retval; |
3669 | 3670 | ||
3670 | if (!uattr || pid < 0) | 3671 | if (!uattr || pid < 0 || flags) |
3671 | return -EINVAL; | 3672 | return -EINVAL; |
3672 | 3673 | ||
3673 | if (sched_copy_attr(uattr, &attr)) | 3674 | if (sched_copy_attr(uattr, &attr)) |
@@ -3786,7 +3787,7 @@ static int sched_read_attr(struct sched_attr __user *uattr, | |||
3786 | attr->size = usize; | 3787 | attr->size = usize; |
3787 | } | 3788 | } |
3788 | 3789 | ||
3789 | ret = copy_to_user(uattr, attr, usize); | 3790 | ret = copy_to_user(uattr, attr, attr->size); |
3790 | if (ret) | 3791 | if (ret) |
3791 | return -EFAULT; | 3792 | return -EFAULT; |
3792 | 3793 | ||
@@ -3804,8 +3805,8 @@ err_size: | |||
3804 | * @uattr: structure containing the extended parameters. | 3805 | * @uattr: structure containing the extended parameters. |
3805 | * @size: sizeof(attr) for fwd/bwd comp. | 3806 | * @size: sizeof(attr) for fwd/bwd comp. |
3806 | */ | 3807 | */ |
3807 | SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, | 3808 | SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, |
3808 | unsigned int, size) | 3809 | unsigned int, size, unsigned int, flags) |
3809 | { | 3810 | { |
3810 | struct sched_attr attr = { | 3811 | struct sched_attr attr = { |
3811 | .size = sizeof(struct sched_attr), | 3812 | .size = sizeof(struct sched_attr), |
@@ -3814,7 +3815,7 @@ SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, | |||
3814 | int retval; | 3815 | int retval; |
3815 | 3816 | ||
3816 | if (!uattr || pid < 0 || size > PAGE_SIZE || | 3817 | if (!uattr || pid < 0 || size > PAGE_SIZE || |
3817 | size < SCHED_ATTR_SIZE_VER0) | 3818 | size < SCHED_ATTR_SIZE_VER0 || flags) |
3818 | return -EINVAL; | 3819 | return -EINVAL; |
3819 | 3820 | ||
3820 | rcu_read_lock(); | 3821 | rcu_read_lock(); |
@@ -7422,6 +7423,7 @@ static int sched_dl_global_constraints(void) | |||
7422 | u64 period = global_rt_period(); | 7423 | u64 period = global_rt_period(); |
7423 | u64 new_bw = to_ratio(period, runtime); | 7424 | u64 new_bw = to_ratio(period, runtime); |
7424 | int cpu, ret = 0; | 7425 | int cpu, ret = 0; |
7426 | unsigned long flags; | ||
7425 | 7427 | ||
7426 | /* | 7428 | /* |
7427 | * Here we want to check the bandwidth not being set to some | 7429 | * Here we want to check the bandwidth not being set to some |
@@ -7435,10 +7437,10 @@ static int sched_dl_global_constraints(void) | |||
7435 | for_each_possible_cpu(cpu) { | 7437 | for_each_possible_cpu(cpu) { |
7436 | struct dl_bw *dl_b = dl_bw_of(cpu); | 7438 | struct dl_bw *dl_b = dl_bw_of(cpu); |
7437 | 7439 | ||
7438 | raw_spin_lock(&dl_b->lock); | 7440 | raw_spin_lock_irqsave(&dl_b->lock, flags); |
7439 | if (new_bw < dl_b->total_bw) | 7441 | if (new_bw < dl_b->total_bw) |
7440 | ret = -EBUSY; | 7442 | ret = -EBUSY; |
7441 | raw_spin_unlock(&dl_b->lock); | 7443 | raw_spin_unlock_irqrestore(&dl_b->lock, flags); |
7442 | 7444 | ||
7443 | if (ret) | 7445 | if (ret) |
7444 | break; | 7446 | break; |
@@ -7451,6 +7453,7 @@ static void sched_dl_do_global(void) | |||
7451 | { | 7453 | { |
7452 | u64 new_bw = -1; | 7454 | u64 new_bw = -1; |
7453 | int cpu; | 7455 | int cpu; |
7456 | unsigned long flags; | ||
7454 | 7457 | ||
7455 | def_dl_bandwidth.dl_period = global_rt_period(); | 7458 | def_dl_bandwidth.dl_period = global_rt_period(); |
7456 | def_dl_bandwidth.dl_runtime = global_rt_runtime(); | 7459 | def_dl_bandwidth.dl_runtime = global_rt_runtime(); |
@@ -7464,9 +7467,9 @@ static void sched_dl_do_global(void) | |||
7464 | for_each_possible_cpu(cpu) { | 7467 | for_each_possible_cpu(cpu) { |
7465 | struct dl_bw *dl_b = dl_bw_of(cpu); | 7468 | struct dl_bw *dl_b = dl_bw_of(cpu); |
7466 | 7469 | ||
7467 | raw_spin_lock(&dl_b->lock); | 7470 | raw_spin_lock_irqsave(&dl_b->lock, flags); |
7468 | dl_b->bw = new_bw; | 7471 | dl_b->bw = new_bw; |
7469 | raw_spin_unlock(&dl_b->lock); | 7472 | raw_spin_unlock_irqrestore(&dl_b->lock, flags); |
7470 | } | 7473 | } |
7471 | } | 7474 | } |
7472 | 7475 | ||
@@ -7475,7 +7478,8 @@ static int sched_rt_global_validate(void) | |||
7475 | if (sysctl_sched_rt_period <= 0) | 7478 | if (sysctl_sched_rt_period <= 0) |
7476 | return -EINVAL; | 7479 | return -EINVAL; |
7477 | 7480 | ||
7478 | if (sysctl_sched_rt_runtime > sysctl_sched_rt_period) | 7481 | if ((sysctl_sched_rt_runtime != RUNTIME_INF) && |
7482 | (sysctl_sched_rt_runtime > sysctl_sched_rt_period)) | ||
7479 | return -EINVAL; | 7483 | return -EINVAL; |
7480 | 7484 | ||
7481 | return 0; | 7485 | return 0; |
diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c index 045fc74e3f09..5b8838b56d1c 100644 --- a/kernel/sched/cpudeadline.c +++ b/kernel/sched/cpudeadline.c | |||
@@ -70,7 +70,7 @@ static void cpudl_heapify(struct cpudl *cp, int idx) | |||
70 | 70 | ||
71 | static void cpudl_change_key(struct cpudl *cp, int idx, u64 new_dl) | 71 | static void cpudl_change_key(struct cpudl *cp, int idx, u64 new_dl) |
72 | { | 72 | { |
73 | WARN_ON(idx > num_present_cpus() || idx == IDX_INVALID); | 73 | WARN_ON(!cpu_present(idx) || idx == IDX_INVALID); |
74 | 74 | ||
75 | if (dl_time_before(new_dl, cp->elements[idx].dl)) { | 75 | if (dl_time_before(new_dl, cp->elements[idx].dl)) { |
76 | cp->elements[idx].dl = new_dl; | 76 | cp->elements[idx].dl = new_dl; |
@@ -117,7 +117,7 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, | |||
117 | } | 117 | } |
118 | 118 | ||
119 | out: | 119 | out: |
120 | WARN_ON(best_cpu > num_present_cpus() && best_cpu != -1); | 120 | WARN_ON(!cpu_present(best_cpu) && best_cpu != -1); |
121 | 121 | ||
122 | return best_cpu; | 122 | return best_cpu; |
123 | } | 123 | } |
@@ -137,7 +137,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid) | |||
137 | int old_idx, new_cpu; | 137 | int old_idx, new_cpu; |
138 | unsigned long flags; | 138 | unsigned long flags; |
139 | 139 | ||
140 | WARN_ON(cpu > num_present_cpus()); | 140 | WARN_ON(!cpu_present(cpu)); |
141 | 141 | ||
142 | raw_spin_lock_irqsave(&cp->lock, flags); | 142 | raw_spin_lock_irqsave(&cp->lock, flags); |
143 | old_idx = cp->cpu_to_idx[cpu]; | 143 | old_idx = cp->cpu_to_idx[cpu]; |
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 0dd5e0971a07..15cbc17fbf84 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c | |||
@@ -121,7 +121,7 @@ static inline void dl_clear_overload(struct rq *rq) | |||
121 | 121 | ||
122 | static void update_dl_migration(struct dl_rq *dl_rq) | 122 | static void update_dl_migration(struct dl_rq *dl_rq) |
123 | { | 123 | { |
124 | if (dl_rq->dl_nr_migratory && dl_rq->dl_nr_total > 1) { | 124 | if (dl_rq->dl_nr_migratory && dl_rq->dl_nr_running > 1) { |
125 | if (!dl_rq->overloaded) { | 125 | if (!dl_rq->overloaded) { |
126 | dl_set_overload(rq_of_dl_rq(dl_rq)); | 126 | dl_set_overload(rq_of_dl_rq(dl_rq)); |
127 | dl_rq->overloaded = 1; | 127 | dl_rq->overloaded = 1; |
@@ -137,7 +137,6 @@ static void inc_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) | |||
137 | struct task_struct *p = dl_task_of(dl_se); | 137 | struct task_struct *p = dl_task_of(dl_se); |
138 | dl_rq = &rq_of_dl_rq(dl_rq)->dl; | 138 | dl_rq = &rq_of_dl_rq(dl_rq)->dl; |
139 | 139 | ||
140 | dl_rq->dl_nr_total++; | ||
141 | if (p->nr_cpus_allowed > 1) | 140 | if (p->nr_cpus_allowed > 1) |
142 | dl_rq->dl_nr_migratory++; | 141 | dl_rq->dl_nr_migratory++; |
143 | 142 | ||
@@ -149,7 +148,6 @@ static void dec_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) | |||
149 | struct task_struct *p = dl_task_of(dl_se); | 148 | struct task_struct *p = dl_task_of(dl_se); |
150 | dl_rq = &rq_of_dl_rq(dl_rq)->dl; | 149 | dl_rq = &rq_of_dl_rq(dl_rq)->dl; |
151 | 150 | ||
152 | dl_rq->dl_nr_total--; | ||
153 | if (p->nr_cpus_allowed > 1) | 151 | if (p->nr_cpus_allowed > 1) |
154 | dl_rq->dl_nr_migratory--; | 152 | dl_rq->dl_nr_migratory--; |
155 | 153 | ||
@@ -717,6 +715,7 @@ void inc_dl_tasks(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) | |||
717 | 715 | ||
718 | WARN_ON(!dl_prio(prio)); | 716 | WARN_ON(!dl_prio(prio)); |
719 | dl_rq->dl_nr_running++; | 717 | dl_rq->dl_nr_running++; |
718 | inc_nr_running(rq_of_dl_rq(dl_rq)); | ||
720 | 719 | ||
721 | inc_dl_deadline(dl_rq, deadline); | 720 | inc_dl_deadline(dl_rq, deadline); |
722 | inc_dl_migration(dl_se, dl_rq); | 721 | inc_dl_migration(dl_se, dl_rq); |
@@ -730,6 +729,7 @@ void dec_dl_tasks(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) | |||
730 | WARN_ON(!dl_prio(prio)); | 729 | WARN_ON(!dl_prio(prio)); |
731 | WARN_ON(!dl_rq->dl_nr_running); | 730 | WARN_ON(!dl_rq->dl_nr_running); |
732 | dl_rq->dl_nr_running--; | 731 | dl_rq->dl_nr_running--; |
732 | dec_nr_running(rq_of_dl_rq(dl_rq)); | ||
733 | 733 | ||
734 | dec_dl_deadline(dl_rq, dl_se->deadline); | 734 | dec_dl_deadline(dl_rq, dl_se->deadline); |
735 | dec_dl_migration(dl_se, dl_rq); | 735 | dec_dl_migration(dl_se, dl_rq); |
@@ -836,8 +836,6 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) | |||
836 | 836 | ||
837 | if (!task_current(rq, p) && p->nr_cpus_allowed > 1) | 837 | if (!task_current(rq, p) && p->nr_cpus_allowed > 1) |
838 | enqueue_pushable_dl_task(rq, p); | 838 | enqueue_pushable_dl_task(rq, p); |
839 | |||
840 | inc_nr_running(rq); | ||
841 | } | 839 | } |
842 | 840 | ||
843 | static void __dequeue_task_dl(struct rq *rq, struct task_struct *p, int flags) | 841 | static void __dequeue_task_dl(struct rq *rq, struct task_struct *p, int flags) |
@@ -850,8 +848,6 @@ static void dequeue_task_dl(struct rq *rq, struct task_struct *p, int flags) | |||
850 | { | 848 | { |
851 | update_curr_dl(rq); | 849 | update_curr_dl(rq); |
852 | __dequeue_task_dl(rq, p, flags); | 850 | __dequeue_task_dl(rq, p, flags); |
853 | |||
854 | dec_nr_running(rq); | ||
855 | } | 851 | } |
856 | 852 | ||
857 | /* | 853 | /* |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 966cc2bfcb77..78157099b167 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -1757,6 +1757,8 @@ void task_numa_work(struct callback_head *work) | |||
1757 | start = end; | 1757 | start = end; |
1758 | if (pages <= 0) | 1758 | if (pages <= 0) |
1759 | goto out; | 1759 | goto out; |
1760 | |||
1761 | cond_resched(); | ||
1760 | } while (end != vma->vm_end); | 1762 | } while (end != vma->vm_end); |
1761 | } | 1763 | } |
1762 | 1764 | ||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index c2119fd20f8b..f964add50f38 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -462,7 +462,6 @@ struct dl_rq { | |||
462 | } earliest_dl; | 462 | } earliest_dl; |
463 | 463 | ||
464 | unsigned long dl_nr_migratory; | 464 | unsigned long dl_nr_migratory; |
465 | unsigned long dl_nr_total; | ||
466 | int overloaded; | 465 | int overloaded; |
467 | 466 | ||
468 | /* | 467 | /* |
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c index 0abb36464281..4d23dc4d8139 100644 --- a/kernel/time/sched_clock.c +++ b/kernel/time/sched_clock.c | |||
@@ -116,20 +116,42 @@ static enum hrtimer_restart sched_clock_poll(struct hrtimer *hrt) | |||
116 | void __init sched_clock_register(u64 (*read)(void), int bits, | 116 | void __init sched_clock_register(u64 (*read)(void), int bits, |
117 | unsigned long rate) | 117 | unsigned long rate) |
118 | { | 118 | { |
119 | u64 res, wrap, new_mask, new_epoch, cyc, ns; | ||
120 | u32 new_mult, new_shift; | ||
121 | ktime_t new_wrap_kt; | ||
119 | unsigned long r; | 122 | unsigned long r; |
120 | u64 res, wrap; | ||
121 | char r_unit; | 123 | char r_unit; |
122 | 124 | ||
123 | if (cd.rate > rate) | 125 | if (cd.rate > rate) |
124 | return; | 126 | return; |
125 | 127 | ||
126 | WARN_ON(!irqs_disabled()); | 128 | WARN_ON(!irqs_disabled()); |
127 | read_sched_clock = read; | ||
128 | sched_clock_mask = CLOCKSOURCE_MASK(bits); | ||
129 | cd.rate = rate; | ||
130 | 129 | ||
131 | /* calculate the mult/shift to convert counter ticks to ns. */ | 130 | /* calculate the mult/shift to convert counter ticks to ns. */ |
132 | clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 3600); | 131 | clocks_calc_mult_shift(&new_mult, &new_shift, rate, NSEC_PER_SEC, 3600); |
132 | |||
133 | new_mask = CLOCKSOURCE_MASK(bits); | ||
134 | |||
135 | /* calculate how many ns until we wrap */ | ||
136 | wrap = clocks_calc_max_nsecs(new_mult, new_shift, 0, new_mask); | ||
137 | new_wrap_kt = ns_to_ktime(wrap - (wrap >> 3)); | ||
138 | |||
139 | /* update epoch for new counter and update epoch_ns from old counter*/ | ||
140 | new_epoch = read(); | ||
141 | cyc = read_sched_clock(); | ||
142 | ns = cd.epoch_ns + cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask, | ||
143 | cd.mult, cd.shift); | ||
144 | |||
145 | raw_write_seqcount_begin(&cd.seq); | ||
146 | read_sched_clock = read; | ||
147 | sched_clock_mask = new_mask; | ||
148 | cd.rate = rate; | ||
149 | cd.wrap_kt = new_wrap_kt; | ||
150 | cd.mult = new_mult; | ||
151 | cd.shift = new_shift; | ||
152 | cd.epoch_cyc = new_epoch; | ||
153 | cd.epoch_ns = ns; | ||
154 | raw_write_seqcount_end(&cd.seq); | ||
133 | 155 | ||
134 | r = rate; | 156 | r = rate; |
135 | if (r >= 4000000) { | 157 | if (r >= 4000000) { |
@@ -141,22 +163,12 @@ void __init sched_clock_register(u64 (*read)(void), int bits, | |||
141 | } else | 163 | } else |
142 | r_unit = ' '; | 164 | r_unit = ' '; |
143 | 165 | ||
144 | /* calculate how many ns until we wrap */ | ||
145 | wrap = clocks_calc_max_nsecs(cd.mult, cd.shift, 0, sched_clock_mask); | ||
146 | cd.wrap_kt = ns_to_ktime(wrap - (wrap >> 3)); | ||
147 | |||
148 | /* calculate the ns resolution of this counter */ | 166 | /* calculate the ns resolution of this counter */ |
149 | res = cyc_to_ns(1ULL, cd.mult, cd.shift); | 167 | res = cyc_to_ns(1ULL, new_mult, new_shift); |
168 | |||
150 | pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lluns\n", | 169 | pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lluns\n", |
151 | bits, r, r_unit, res, wrap); | 170 | bits, r, r_unit, res, wrap); |
152 | 171 | ||
153 | update_sched_clock(); | ||
154 | |||
155 | /* | ||
156 | * Ensure that sched_clock() starts off at 0ns | ||
157 | */ | ||
158 | cd.epoch_ns = 0; | ||
159 | |||
160 | /* Enable IRQ time accounting if we have a fast enough sched_clock */ | 172 | /* Enable IRQ time accounting if we have a fast enough sched_clock */ |
161 | if (irqtime > 0 || (irqtime == -1 && rate >= 1000000)) | 173 | if (irqtime > 0 || (irqtime == -1 && rate >= 1000000)) |
162 | enable_sched_clock_irqtime(); | 174 | enable_sched_clock_irqtime(); |
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 015f85aaca08..8639819f6cef 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
@@ -424,6 +424,7 @@ config UPROBE_EVENT | |||
424 | bool "Enable uprobes-based dynamic events" | 424 | bool "Enable uprobes-based dynamic events" |
425 | depends on ARCH_SUPPORTS_UPROBES | 425 | depends on ARCH_SUPPORTS_UPROBES |
426 | depends on MMU | 426 | depends on MMU |
427 | depends on PERF_EVENTS | ||
427 | select UPROBES | 428 | select UPROBES |
428 | select PROBE_EVENTS | 429 | select PROBE_EVENTS |
429 | select TRACING | 430 | select TRACING |
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 240fb62cf394..dd06439b9c84 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c | |||
@@ -225,7 +225,7 @@ static u32 map_id_up(struct uid_gid_map *map, u32 id) | |||
225 | * | 225 | * |
226 | * When there is no mapping defined for the user-namespace uid | 226 | * When there is no mapping defined for the user-namespace uid |
227 | * pair INVALID_UID is returned. Callers are expected to test | 227 | * pair INVALID_UID is returned. Callers are expected to test |
228 | * for and handle handle INVALID_UID being returned. INVALID_UID | 228 | * for and handle INVALID_UID being returned. INVALID_UID |
229 | * may be tested for using uid_valid(). | 229 | * may be tested for using uid_valid(). |
230 | */ | 230 | */ |
231 | kuid_t make_kuid(struct user_namespace *ns, uid_t uid) | 231 | kuid_t make_kuid(struct user_namespace *ns, uid_t uid) |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 82ef9f3b7473..193e977a10ea 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -1851,6 +1851,12 @@ static void destroy_worker(struct worker *worker) | |||
1851 | if (worker->flags & WORKER_IDLE) | 1851 | if (worker->flags & WORKER_IDLE) |
1852 | pool->nr_idle--; | 1852 | pool->nr_idle--; |
1853 | 1853 | ||
1854 | /* | ||
1855 | * Once WORKER_DIE is set, the kworker may destroy itself at any | ||
1856 | * point. Pin to ensure the task stays until we're done with it. | ||
1857 | */ | ||
1858 | get_task_struct(worker->task); | ||
1859 | |||
1854 | list_del_init(&worker->entry); | 1860 | list_del_init(&worker->entry); |
1855 | worker->flags |= WORKER_DIE; | 1861 | worker->flags |= WORKER_DIE; |
1856 | 1862 | ||
@@ -1859,6 +1865,7 @@ static void destroy_worker(struct worker *worker) | |||
1859 | spin_unlock_irq(&pool->lock); | 1865 | spin_unlock_irq(&pool->lock); |
1860 | 1866 | ||
1861 | kthread_stop(worker->task); | 1867 | kthread_stop(worker->task); |
1868 | put_task_struct(worker->task); | ||
1862 | kfree(worker); | 1869 | kfree(worker); |
1863 | 1870 | ||
1864 | spin_lock_irq(&pool->lock); | 1871 | spin_lock_irq(&pool->lock); |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 82166bf974e1..4df39b1bde91 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1166,8 +1166,10 @@ alloc: | |||
1166 | } else { | 1166 | } else { |
1167 | ret = do_huge_pmd_wp_page_fallback(mm, vma, address, | 1167 | ret = do_huge_pmd_wp_page_fallback(mm, vma, address, |
1168 | pmd, orig_pmd, page, haddr); | 1168 | pmd, orig_pmd, page, haddr); |
1169 | if (ret & VM_FAULT_OOM) | 1169 | if (ret & VM_FAULT_OOM) { |
1170 | split_huge_page(page); | 1170 | split_huge_page(page); |
1171 | ret |= VM_FAULT_FALLBACK; | ||
1172 | } | ||
1171 | put_page(page); | 1173 | put_page(page); |
1172 | } | 1174 | } |
1173 | count_vm_event(THP_FAULT_FALLBACK); | 1175 | count_vm_event(THP_FAULT_FALLBACK); |
@@ -1179,9 +1181,10 @@ alloc: | |||
1179 | if (page) { | 1181 | if (page) { |
1180 | split_huge_page(page); | 1182 | split_huge_page(page); |
1181 | put_page(page); | 1183 | put_page(page); |
1182 | } | 1184 | } else |
1185 | split_huge_page_pmd(vma, address, pmd); | ||
1186 | ret |= VM_FAULT_FALLBACK; | ||
1183 | count_vm_event(THP_FAULT_FALLBACK); | 1187 | count_vm_event(THP_FAULT_FALLBACK); |
1184 | ret |= VM_FAULT_OOM; | ||
1185 | goto out; | 1188 | goto out; |
1186 | } | 1189 | } |
1187 | 1190 | ||
@@ -1545,6 +1548,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | |||
1545 | entry = pmd_mknonnuma(entry); | 1548 | entry = pmd_mknonnuma(entry); |
1546 | entry = pmd_modify(entry, newprot); | 1549 | entry = pmd_modify(entry, newprot); |
1547 | ret = HPAGE_PMD_NR; | 1550 | ret = HPAGE_PMD_NR; |
1551 | set_pmd_at(mm, addr, pmd, entry); | ||
1548 | BUG_ON(pmd_write(entry)); | 1552 | BUG_ON(pmd_write(entry)); |
1549 | } else { | 1553 | } else { |
1550 | struct page *page = pmd_page(*pmd); | 1554 | struct page *page = pmd_page(*pmd); |
@@ -1557,16 +1561,10 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | |||
1557 | */ | 1561 | */ |
1558 | if (!is_huge_zero_page(page) && | 1562 | if (!is_huge_zero_page(page) && |
1559 | !pmd_numa(*pmd)) { | 1563 | !pmd_numa(*pmd)) { |
1560 | entry = *pmd; | 1564 | pmdp_set_numa(mm, addr, pmd); |
1561 | entry = pmd_mknuma(entry); | ||
1562 | ret = HPAGE_PMD_NR; | 1565 | ret = HPAGE_PMD_NR; |
1563 | } | 1566 | } |
1564 | } | 1567 | } |
1565 | |||
1566 | /* Set PMD if cleared earlier */ | ||
1567 | if (ret == HPAGE_PMD_NR) | ||
1568 | set_pmd_at(mm, addr, pmd, entry); | ||
1569 | |||
1570 | spin_unlock(ptl); | 1568 | spin_unlock(ptl); |
1571 | } | 1569 | } |
1572 | 1570 | ||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 53385cd4e6f0..ce7a8cc7b404 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1687,7 +1687,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) | |||
1687 | * protects memcg_name and makes sure that parallel ooms do not | 1687 | * protects memcg_name and makes sure that parallel ooms do not |
1688 | * interleave | 1688 | * interleave |
1689 | */ | 1689 | */ |
1690 | static DEFINE_SPINLOCK(oom_info_lock); | 1690 | static DEFINE_MUTEX(oom_info_lock); |
1691 | struct cgroup *task_cgrp; | 1691 | struct cgroup *task_cgrp; |
1692 | struct cgroup *mem_cgrp; | 1692 | struct cgroup *mem_cgrp; |
1693 | static char memcg_name[PATH_MAX]; | 1693 | static char memcg_name[PATH_MAX]; |
@@ -1698,7 +1698,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) | |||
1698 | if (!p) | 1698 | if (!p) |
1699 | return; | 1699 | return; |
1700 | 1700 | ||
1701 | spin_lock(&oom_info_lock); | 1701 | mutex_lock(&oom_info_lock); |
1702 | rcu_read_lock(); | 1702 | rcu_read_lock(); |
1703 | 1703 | ||
1704 | mem_cgrp = memcg->css.cgroup; | 1704 | mem_cgrp = memcg->css.cgroup; |
@@ -1767,7 +1767,7 @@ done: | |||
1767 | 1767 | ||
1768 | pr_cont("\n"); | 1768 | pr_cont("\n"); |
1769 | } | 1769 | } |
1770 | spin_unlock(&oom_info_lock); | 1770 | mutex_unlock(&oom_info_lock); |
1771 | } | 1771 | } |
1772 | 1772 | ||
1773 | /* | 1773 | /* |
diff --git a/mm/memory.c b/mm/memory.c index be6a0c0d4ae0..22dfa617bddb 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3348,6 +3348,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3348 | if (ret & VM_FAULT_LOCKED) | 3348 | if (ret & VM_FAULT_LOCKED) |
3349 | unlock_page(vmf.page); | 3349 | unlock_page(vmf.page); |
3350 | ret = VM_FAULT_HWPOISON; | 3350 | ret = VM_FAULT_HWPOISON; |
3351 | page_cache_release(vmf.page); | ||
3351 | goto uncharge_out; | 3352 | goto uncharge_out; |
3352 | } | 3353 | } |
3353 | 3354 | ||
@@ -3703,7 +3704,6 @@ static int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3703 | if (unlikely(is_vm_hugetlb_page(vma))) | 3704 | if (unlikely(is_vm_hugetlb_page(vma))) |
3704 | return hugetlb_fault(mm, vma, address, flags); | 3705 | return hugetlb_fault(mm, vma, address, flags); |
3705 | 3706 | ||
3706 | retry: | ||
3707 | pgd = pgd_offset(mm, address); | 3707 | pgd = pgd_offset(mm, address); |
3708 | pud = pud_alloc(mm, pgd, address); | 3708 | pud = pud_alloc(mm, pgd, address); |
3709 | if (!pud) | 3709 | if (!pud) |
@@ -3741,20 +3741,13 @@ retry: | |||
3741 | if (dirty && !pmd_write(orig_pmd)) { | 3741 | if (dirty && !pmd_write(orig_pmd)) { |
3742 | ret = do_huge_pmd_wp_page(mm, vma, address, pmd, | 3742 | ret = do_huge_pmd_wp_page(mm, vma, address, pmd, |
3743 | orig_pmd); | 3743 | orig_pmd); |
3744 | /* | 3744 | if (!(ret & VM_FAULT_FALLBACK)) |
3745 | * If COW results in an oom, the huge pmd will | 3745 | return ret; |
3746 | * have been split, so retry the fault on the | ||
3747 | * pte for a smaller charge. | ||
3748 | */ | ||
3749 | if (unlikely(ret & VM_FAULT_OOM)) | ||
3750 | goto retry; | ||
3751 | return ret; | ||
3752 | } else { | 3746 | } else { |
3753 | huge_pmd_set_accessed(mm, vma, address, pmd, | 3747 | huge_pmd_set_accessed(mm, vma, address, pmd, |
3754 | orig_pmd, dirty); | 3748 | orig_pmd, dirty); |
3749 | return 0; | ||
3755 | } | 3750 | } |
3756 | |||
3757 | return 0; | ||
3758 | } | 3751 | } |
3759 | } | 3752 | } |
3760 | 3753 | ||
diff --git a/mm/mprotect.c b/mm/mprotect.c index 7332c1785744..769a67a15803 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -58,36 +58,27 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
58 | if (pte_numa(ptent)) | 58 | if (pte_numa(ptent)) |
59 | ptent = pte_mknonnuma(ptent); | 59 | ptent = pte_mknonnuma(ptent); |
60 | ptent = pte_modify(ptent, newprot); | 60 | ptent = pte_modify(ptent, newprot); |
61 | /* | ||
62 | * Avoid taking write faults for pages we | ||
63 | * know to be dirty. | ||
64 | */ | ||
65 | if (dirty_accountable && pte_dirty(ptent)) | ||
66 | ptent = pte_mkwrite(ptent); | ||
67 | ptep_modify_prot_commit(mm, addr, pte, ptent); | ||
61 | updated = true; | 68 | updated = true; |
62 | } else { | 69 | } else { |
63 | struct page *page; | 70 | struct page *page; |
64 | 71 | ||
65 | ptent = *pte; | ||
66 | page = vm_normal_page(vma, addr, oldpte); | 72 | page = vm_normal_page(vma, addr, oldpte); |
67 | if (page && !PageKsm(page)) { | 73 | if (page && !PageKsm(page)) { |
68 | if (!pte_numa(oldpte)) { | 74 | if (!pte_numa(oldpte)) { |
69 | ptent = pte_mknuma(ptent); | 75 | ptep_set_numa(mm, addr, pte); |
70 | set_pte_at(mm, addr, pte, ptent); | ||
71 | updated = true; | 76 | updated = true; |
72 | } | 77 | } |
73 | } | 78 | } |
74 | } | 79 | } |
75 | |||
76 | /* | ||
77 | * Avoid taking write faults for pages we know to be | ||
78 | * dirty. | ||
79 | */ | ||
80 | if (dirty_accountable && pte_dirty(ptent)) { | ||
81 | ptent = pte_mkwrite(ptent); | ||
82 | updated = true; | ||
83 | } | ||
84 | |||
85 | if (updated) | 80 | if (updated) |
86 | pages++; | 81 | pages++; |
87 | |||
88 | /* Only !prot_numa always clears the pte */ | ||
89 | if (!prot_numa) | ||
90 | ptep_modify_prot_commit(mm, addr, pte, ptent); | ||
91 | } else if (IS_ENABLED(CONFIG_MIGRATION) && !pte_file(oldpte)) { | 82 | } else if (IS_ENABLED(CONFIG_MIGRATION) && !pte_file(oldpte)) { |
92 | swp_entry_t entry = pte_to_swp_entry(oldpte); | 83 | swp_entry_t entry = pte_to_swp_entry(oldpte); |
93 | 84 | ||
diff --git a/mm/vmpressure.c b/mm/vmpressure.c index 196970a4541f..d4042e75f7c7 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/vmstat.h> | 20 | #include <linux/vmstat.h> |
21 | #include <linux/eventfd.h> | 21 | #include <linux/eventfd.h> |
22 | #include <linux/slab.h> | ||
22 | #include <linux/swap.h> | 23 | #include <linux/swap.h> |
23 | #include <linux/printk.h> | 24 | #include <linux/printk.h> |
24 | #include <linux/vmpressure.h> | 25 | #include <linux/vmpressure.h> |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 512159bf607f..8323bced8e5b 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -241,19 +241,19 @@ batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr) | |||
241 | size = bat_priv->num_ifaces * sizeof(uint8_t); | 241 | size = bat_priv->num_ifaces * sizeof(uint8_t); |
242 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); | 242 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); |
243 | if (!orig_node->bat_iv.bcast_own_sum) | 243 | if (!orig_node->bat_iv.bcast_own_sum) |
244 | goto free_bcast_own; | 244 | goto free_orig_node; |
245 | 245 | ||
246 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, | 246 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, |
247 | batadv_choose_orig, orig_node, | 247 | batadv_choose_orig, orig_node, |
248 | &orig_node->hash_entry); | 248 | &orig_node->hash_entry); |
249 | if (hash_added != 0) | 249 | if (hash_added != 0) |
250 | goto free_bcast_own; | 250 | goto free_orig_node; |
251 | 251 | ||
252 | return orig_node; | 252 | return orig_node; |
253 | 253 | ||
254 | free_bcast_own: | ||
255 | kfree(orig_node->bat_iv.bcast_own); | ||
256 | free_orig_node: | 254 | free_orig_node: |
255 | /* free twice, as batadv_orig_node_new sets refcount to 2 */ | ||
256 | batadv_orig_node_free_ref(orig_node); | ||
257 | batadv_orig_node_free_ref(orig_node); | 257 | batadv_orig_node_free_ref(orig_node); |
258 | 258 | ||
259 | return NULL; | 259 | return NULL; |
@@ -266,7 +266,7 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, | |||
266 | struct batadv_orig_node *orig_neigh) | 266 | struct batadv_orig_node *orig_neigh) |
267 | { | 267 | { |
268 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 268 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
269 | struct batadv_neigh_node *neigh_node; | 269 | struct batadv_neigh_node *neigh_node, *tmp_neigh_node; |
270 | 270 | ||
271 | neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node); | 271 | neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node); |
272 | if (!neigh_node) | 272 | if (!neigh_node) |
@@ -281,14 +281,24 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, | |||
281 | neigh_node->orig_node = orig_neigh; | 281 | neigh_node->orig_node = orig_neigh; |
282 | neigh_node->if_incoming = hard_iface; | 282 | neigh_node->if_incoming = hard_iface; |
283 | 283 | ||
284 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
285 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", | ||
286 | neigh_addr, orig_node->orig, hard_iface->net_dev->name); | ||
287 | |||
288 | spin_lock_bh(&orig_node->neigh_list_lock); | 284 | spin_lock_bh(&orig_node->neigh_list_lock); |
289 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | 285 | tmp_neigh_node = batadv_neigh_node_get(orig_node, hard_iface, |
286 | neigh_addr); | ||
287 | if (!tmp_neigh_node) { | ||
288 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | ||
289 | } else { | ||
290 | kfree(neigh_node); | ||
291 | batadv_hardif_free_ref(hard_iface); | ||
292 | neigh_node = tmp_neigh_node; | ||
293 | } | ||
290 | spin_unlock_bh(&orig_node->neigh_list_lock); | 294 | spin_unlock_bh(&orig_node->neigh_list_lock); |
291 | 295 | ||
296 | if (!tmp_neigh_node) | ||
297 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
298 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", | ||
299 | neigh_addr, orig_node->orig, | ||
300 | hard_iface->net_dev->name); | ||
301 | |||
292 | out: | 302 | out: |
293 | return neigh_node; | 303 | return neigh_node; |
294 | } | 304 | } |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 3d417d3641c6..b851cc580853 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -241,7 +241,7 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface) | |||
241 | { | 241 | { |
242 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 242 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
243 | const struct batadv_hard_iface *hard_iface; | 243 | const struct batadv_hard_iface *hard_iface; |
244 | int min_mtu = ETH_DATA_LEN; | 244 | int min_mtu = INT_MAX; |
245 | 245 | ||
246 | rcu_read_lock(); | 246 | rcu_read_lock(); |
247 | list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { | 247 | list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { |
@@ -256,8 +256,6 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface) | |||
256 | } | 256 | } |
257 | rcu_read_unlock(); | 257 | rcu_read_unlock(); |
258 | 258 | ||
259 | atomic_set(&bat_priv->packet_size_max, min_mtu); | ||
260 | |||
261 | if (atomic_read(&bat_priv->fragmentation) == 0) | 259 | if (atomic_read(&bat_priv->fragmentation) == 0) |
262 | goto out; | 260 | goto out; |
263 | 261 | ||
@@ -268,13 +266,21 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface) | |||
268 | min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE); | 266 | min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE); |
269 | min_mtu -= sizeof(struct batadv_frag_packet); | 267 | min_mtu -= sizeof(struct batadv_frag_packet); |
270 | min_mtu *= BATADV_FRAG_MAX_FRAGMENTS; | 268 | min_mtu *= BATADV_FRAG_MAX_FRAGMENTS; |
271 | atomic_set(&bat_priv->packet_size_max, min_mtu); | ||
272 | |||
273 | /* with fragmentation enabled we can fragment external packets easily */ | ||
274 | min_mtu = min_t(int, min_mtu, ETH_DATA_LEN); | ||
275 | 269 | ||
276 | out: | 270 | out: |
277 | return min_mtu - batadv_max_header_len(); | 271 | /* report to the other components the maximum amount of bytes that |
272 | * batman-adv can send over the wire (without considering the payload | ||
273 | * overhead). For example, this value is used by TT to compute the | ||
274 | * maximum local table table size | ||
275 | */ | ||
276 | atomic_set(&bat_priv->packet_size_max, min_mtu); | ||
277 | |||
278 | /* the real soft-interface MTU is computed by removing the payload | ||
279 | * overhead from the maximum amount of bytes that was just computed. | ||
280 | * | ||
281 | * However batman-adv does not support MTUs bigger than ETH_DATA_LEN | ||
282 | */ | ||
283 | return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN); | ||
278 | } | 284 | } |
279 | 285 | ||
280 | /* adjusts the MTU if a new interface with a smaller MTU appeared. */ | 286 | /* adjusts the MTU if a new interface with a smaller MTU appeared. */ |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 6df12a2e3605..853941629dc1 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -458,6 +458,42 @@ out: | |||
458 | } | 458 | } |
459 | 459 | ||
460 | /** | 460 | /** |
461 | * batadv_neigh_node_get - retrieve a neighbour from the list | ||
462 | * @orig_node: originator which the neighbour belongs to | ||
463 | * @hard_iface: the interface where this neighbour is connected to | ||
464 | * @addr: the address of the neighbour | ||
465 | * | ||
466 | * Looks for and possibly returns a neighbour belonging to this originator list | ||
467 | * which is connected through the provided hard interface. | ||
468 | * Returns NULL if the neighbour is not found. | ||
469 | */ | ||
470 | struct batadv_neigh_node * | ||
471 | batadv_neigh_node_get(const struct batadv_orig_node *orig_node, | ||
472 | const struct batadv_hard_iface *hard_iface, | ||
473 | const uint8_t *addr) | ||
474 | { | ||
475 | struct batadv_neigh_node *tmp_neigh_node, *res = NULL; | ||
476 | |||
477 | rcu_read_lock(); | ||
478 | hlist_for_each_entry_rcu(tmp_neigh_node, &orig_node->neigh_list, list) { | ||
479 | if (!batadv_compare_eth(tmp_neigh_node->addr, addr)) | ||
480 | continue; | ||
481 | |||
482 | if (tmp_neigh_node->if_incoming != hard_iface) | ||
483 | continue; | ||
484 | |||
485 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) | ||
486 | continue; | ||
487 | |||
488 | res = tmp_neigh_node; | ||
489 | break; | ||
490 | } | ||
491 | rcu_read_unlock(); | ||
492 | |||
493 | return res; | ||
494 | } | ||
495 | |||
496 | /** | ||
461 | * batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object | 497 | * batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object |
462 | * @rcu: rcu pointer of the orig_ifinfo object | 498 | * @rcu: rcu pointer of the orig_ifinfo object |
463 | */ | 499 | */ |
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 37be290f63f6..db3a9ed734cb 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h | |||
@@ -29,6 +29,10 @@ void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node); | |||
29 | struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, | 29 | struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, |
30 | const uint8_t *addr); | 30 | const uint8_t *addr); |
31 | struct batadv_neigh_node * | 31 | struct batadv_neigh_node * |
32 | batadv_neigh_node_get(const struct batadv_orig_node *orig_node, | ||
33 | const struct batadv_hard_iface *hard_iface, | ||
34 | const uint8_t *addr); | ||
35 | struct batadv_neigh_node * | ||
32 | batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, | 36 | batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, |
33 | const uint8_t *neigh_addr, | 37 | const uint8_t *neigh_addr, |
34 | struct batadv_orig_node *orig_node); | 38 | struct batadv_orig_node *orig_node); |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 1ed9f7c9ecea..a953d5b196a3 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -688,7 +688,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
688 | int is_old_ttvn; | 688 | int is_old_ttvn; |
689 | 689 | ||
690 | /* check if there is enough data before accessing it */ | 690 | /* check if there is enough data before accessing it */ |
691 | if (pskb_may_pull(skb, hdr_len + ETH_HLEN) < 0) | 691 | if (!pskb_may_pull(skb, hdr_len + ETH_HLEN)) |
692 | return 0; | 692 | return 0; |
693 | 693 | ||
694 | /* create a copy of the skb (in case of for re-routing) to modify it. */ | 694 | /* create a copy of the skb (in case of for re-routing) to modify it. */ |
@@ -918,6 +918,8 @@ int batadv_recv_unicast_tvlv(struct sk_buff *skb, | |||
918 | 918 | ||
919 | if (ret != NET_RX_SUCCESS) | 919 | if (ret != NET_RX_SUCCESS) |
920 | ret = batadv_route_unicast_packet(skb, recv_if); | 920 | ret = batadv_route_unicast_packet(skb, recv_if); |
921 | else | ||
922 | consume_skb(skb); | ||
921 | 923 | ||
922 | return ret; | 924 | return ret; |
923 | } | 925 | } |
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 579f5f00a385..843febd1e519 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -254,9 +254,9 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, | |||
254 | struct batadv_orig_node *orig_node, | 254 | struct batadv_orig_node *orig_node, |
255 | unsigned short vid) | 255 | unsigned short vid) |
256 | { | 256 | { |
257 | struct ethhdr *ethhdr = (struct ethhdr *)skb->data; | 257 | struct ethhdr *ethhdr; |
258 | struct batadv_unicast_packet *unicast_packet; | 258 | struct batadv_unicast_packet *unicast_packet; |
259 | int ret = NET_XMIT_DROP; | 259 | int ret = NET_XMIT_DROP, hdr_size; |
260 | 260 | ||
261 | if (!orig_node) | 261 | if (!orig_node) |
262 | goto out; | 262 | goto out; |
@@ -265,12 +265,16 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, | |||
265 | case BATADV_UNICAST: | 265 | case BATADV_UNICAST: |
266 | if (!batadv_send_skb_prepare_unicast(skb, orig_node)) | 266 | if (!batadv_send_skb_prepare_unicast(skb, orig_node)) |
267 | goto out; | 267 | goto out; |
268 | |||
269 | hdr_size = sizeof(*unicast_packet); | ||
268 | break; | 270 | break; |
269 | case BATADV_UNICAST_4ADDR: | 271 | case BATADV_UNICAST_4ADDR: |
270 | if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, | 272 | if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, |
271 | orig_node, | 273 | orig_node, |
272 | packet_subtype)) | 274 | packet_subtype)) |
273 | goto out; | 275 | goto out; |
276 | |||
277 | hdr_size = sizeof(struct batadv_unicast_4addr_packet); | ||
274 | break; | 278 | break; |
275 | default: | 279 | default: |
276 | /* this function supports UNICAST and UNICAST_4ADDR only. It | 280 | /* this function supports UNICAST and UNICAST_4ADDR only. It |
@@ -279,6 +283,7 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, | |||
279 | goto out; | 283 | goto out; |
280 | } | 284 | } |
281 | 285 | ||
286 | ethhdr = (struct ethhdr *)(skb->data + hdr_size); | ||
282 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 287 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
283 | 288 | ||
284 | /* inform the destination node that we are still missing a correct route | 289 | /* inform the destination node that we are still missing a correct route |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index b6071f675a3e..959dde721c46 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -1975,6 +1975,7 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv, | |||
1975 | struct hlist_head *head; | 1975 | struct hlist_head *head; |
1976 | uint32_t i, crc_tmp, crc = 0; | 1976 | uint32_t i, crc_tmp, crc = 0; |
1977 | uint8_t flags; | 1977 | uint8_t flags; |
1978 | __be16 tmp_vid; | ||
1978 | 1979 | ||
1979 | for (i = 0; i < hash->size; i++) { | 1980 | for (i = 0; i < hash->size; i++) { |
1980 | head = &hash->table[i]; | 1981 | head = &hash->table[i]; |
@@ -2011,8 +2012,11 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv, | |||
2011 | orig_node)) | 2012 | orig_node)) |
2012 | continue; | 2013 | continue; |
2013 | 2014 | ||
2014 | crc_tmp = crc32c(0, &tt_common->vid, | 2015 | /* use network order to read the VID: this ensures that |
2015 | sizeof(tt_common->vid)); | 2016 | * every node reads the bytes in the same order. |
2017 | */ | ||
2018 | tmp_vid = htons(tt_common->vid); | ||
2019 | crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid)); | ||
2016 | 2020 | ||
2017 | /* compute the CRC on flags that have to be kept in sync | 2021 | /* compute the CRC on flags that have to be kept in sync |
2018 | * among nodes | 2022 | * among nodes |
@@ -2046,6 +2050,7 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv, | |||
2046 | struct hlist_head *head; | 2050 | struct hlist_head *head; |
2047 | uint32_t i, crc_tmp, crc = 0; | 2051 | uint32_t i, crc_tmp, crc = 0; |
2048 | uint8_t flags; | 2052 | uint8_t flags; |
2053 | __be16 tmp_vid; | ||
2049 | 2054 | ||
2050 | for (i = 0; i < hash->size; i++) { | 2055 | for (i = 0; i < hash->size; i++) { |
2051 | head = &hash->table[i]; | 2056 | head = &hash->table[i]; |
@@ -2064,8 +2069,11 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv, | |||
2064 | if (tt_common->flags & BATADV_TT_CLIENT_NEW) | 2069 | if (tt_common->flags & BATADV_TT_CLIENT_NEW) |
2065 | continue; | 2070 | continue; |
2066 | 2071 | ||
2067 | crc_tmp = crc32c(0, &tt_common->vid, | 2072 | /* use network order to read the VID: this ensures that |
2068 | sizeof(tt_common->vid)); | 2073 | * every node reads the bytes in the same order. |
2074 | */ | ||
2075 | tmp_vid = htons(tt_common->vid); | ||
2076 | crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid)); | ||
2069 | 2077 | ||
2070 | /* compute the CRC on flags that have to be kept in sync | 2078 | /* compute the CRC on flags that have to be kept in sync |
2071 | * among nodes | 2079 | * among nodes |
@@ -2262,6 +2270,7 @@ static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node, | |||
2262 | { | 2270 | { |
2263 | struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp; | 2271 | struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp; |
2264 | struct batadv_orig_node_vlan *vlan; | 2272 | struct batadv_orig_node_vlan *vlan; |
2273 | uint32_t crc; | ||
2265 | int i; | 2274 | int i; |
2266 | 2275 | ||
2267 | /* check if each received CRC matches the locally stored one */ | 2276 | /* check if each received CRC matches the locally stored one */ |
@@ -2281,7 +2290,10 @@ static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node, | |||
2281 | if (!vlan) | 2290 | if (!vlan) |
2282 | return false; | 2291 | return false; |
2283 | 2292 | ||
2284 | if (vlan->tt.crc != ntohl(tt_vlan_tmp->crc)) | 2293 | crc = vlan->tt.crc; |
2294 | batadv_orig_node_vlan_free_ref(vlan); | ||
2295 | |||
2296 | if (crc != ntohl(tt_vlan_tmp->crc)) | ||
2285 | return false; | 2297 | return false; |
2286 | } | 2298 | } |
2287 | 2299 | ||
@@ -3218,7 +3230,6 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv, | |||
3218 | 3230 | ||
3219 | spin_lock_bh(&orig_node->tt_lock); | 3231 | spin_lock_bh(&orig_node->tt_lock); |
3220 | 3232 | ||
3221 | tt_change = (struct batadv_tvlv_tt_change *)tt_buff; | ||
3222 | batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, | 3233 | batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, |
3223 | ttvn, tt_change); | 3234 | ttvn, tt_change); |
3224 | 3235 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 292e619db896..d9fb93451442 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -430,6 +430,16 @@ static void hidp_del_timer(struct hidp_session *session) | |||
430 | del_timer(&session->timer); | 430 | del_timer(&session->timer); |
431 | } | 431 | } |
432 | 432 | ||
433 | static void hidp_process_report(struct hidp_session *session, | ||
434 | int type, const u8 *data, int len, int intr) | ||
435 | { | ||
436 | if (len > HID_MAX_BUFFER_SIZE) | ||
437 | len = HID_MAX_BUFFER_SIZE; | ||
438 | |||
439 | memcpy(session->input_buf, data, len); | ||
440 | hid_input_report(session->hid, type, session->input_buf, len, intr); | ||
441 | } | ||
442 | |||
433 | static void hidp_process_handshake(struct hidp_session *session, | 443 | static void hidp_process_handshake(struct hidp_session *session, |
434 | unsigned char param) | 444 | unsigned char param) |
435 | { | 445 | { |
@@ -502,7 +512,8 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, | |||
502 | hidp_input_report(session, skb); | 512 | hidp_input_report(session, skb); |
503 | 513 | ||
504 | if (session->hid) | 514 | if (session->hid) |
505 | hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0); | 515 | hidp_process_report(session, HID_INPUT_REPORT, |
516 | skb->data, skb->len, 0); | ||
506 | break; | 517 | break; |
507 | 518 | ||
508 | case HIDP_DATA_RTYPE_OTHER: | 519 | case HIDP_DATA_RTYPE_OTHER: |
@@ -584,7 +595,8 @@ static void hidp_recv_intr_frame(struct hidp_session *session, | |||
584 | hidp_input_report(session, skb); | 595 | hidp_input_report(session, skb); |
585 | 596 | ||
586 | if (session->hid) { | 597 | if (session->hid) { |
587 | hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 1); | 598 | hidp_process_report(session, HID_INPUT_REPORT, |
599 | skb->data, skb->len, 1); | ||
588 | BT_DBG("report len %d", skb->len); | 600 | BT_DBG("report len %d", skb->len); |
589 | } | 601 | } |
590 | } else { | 602 | } else { |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index ab5241400cf7..8798492a6e99 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define __HIDP_H | 24 | #define __HIDP_H |
25 | 25 | ||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/hid.h> | ||
27 | #include <linux/kref.h> | 28 | #include <linux/kref.h> |
28 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
29 | #include <net/bluetooth/l2cap.h> | 30 | #include <net/bluetooth/l2cap.h> |
@@ -179,6 +180,9 @@ struct hidp_session { | |||
179 | 180 | ||
180 | /* Used in hidp_output_raw_report() */ | 181 | /* Used in hidp_output_raw_report() */ |
181 | int output_report_success; /* boolean */ | 182 | int output_report_success; /* boolean */ |
183 | |||
184 | /* temporary input buffer */ | ||
185 | u8 input_buf[HID_MAX_BUFFER_SIZE]; | ||
182 | }; | 186 | }; |
183 | 187 | ||
184 | /* HIDP init defines */ | 188 | /* HIDP init defines */ |
diff --git a/net/core/dev.c b/net/core/dev.c index 4ad1b78c9c77..b1b0c8d4d7df 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2420,7 +2420,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault); | |||
2420 | * 2. No high memory really exists on this machine. | 2420 | * 2. No high memory really exists on this machine. |
2421 | */ | 2421 | */ |
2422 | 2422 | ||
2423 | static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) | 2423 | static int illegal_highdma(const struct net_device *dev, struct sk_buff *skb) |
2424 | { | 2424 | { |
2425 | #ifdef CONFIG_HIGHMEM | 2425 | #ifdef CONFIG_HIGHMEM |
2426 | int i; | 2426 | int i; |
@@ -2495,34 +2495,36 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) | |||
2495 | } | 2495 | } |
2496 | 2496 | ||
2497 | static netdev_features_t harmonize_features(struct sk_buff *skb, | 2497 | static netdev_features_t harmonize_features(struct sk_buff *skb, |
2498 | netdev_features_t features) | 2498 | const struct net_device *dev, |
2499 | netdev_features_t features) | ||
2499 | { | 2500 | { |
2500 | if (skb->ip_summed != CHECKSUM_NONE && | 2501 | if (skb->ip_summed != CHECKSUM_NONE && |
2501 | !can_checksum_protocol(features, skb_network_protocol(skb))) { | 2502 | !can_checksum_protocol(features, skb_network_protocol(skb))) { |
2502 | features &= ~NETIF_F_ALL_CSUM; | 2503 | features &= ~NETIF_F_ALL_CSUM; |
2503 | } else if (illegal_highdma(skb->dev, skb)) { | 2504 | } else if (illegal_highdma(dev, skb)) { |
2504 | features &= ~NETIF_F_SG; | 2505 | features &= ~NETIF_F_SG; |
2505 | } | 2506 | } |
2506 | 2507 | ||
2507 | return features; | 2508 | return features; |
2508 | } | 2509 | } |
2509 | 2510 | ||
2510 | netdev_features_t netif_skb_features(struct sk_buff *skb) | 2511 | netdev_features_t netif_skb_dev_features(struct sk_buff *skb, |
2512 | const struct net_device *dev) | ||
2511 | { | 2513 | { |
2512 | __be16 protocol = skb->protocol; | 2514 | __be16 protocol = skb->protocol; |
2513 | netdev_features_t features = skb->dev->features; | 2515 | netdev_features_t features = dev->features; |
2514 | 2516 | ||
2515 | if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) | 2517 | if (skb_shinfo(skb)->gso_segs > dev->gso_max_segs) |
2516 | features &= ~NETIF_F_GSO_MASK; | 2518 | features &= ~NETIF_F_GSO_MASK; |
2517 | 2519 | ||
2518 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { | 2520 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { |
2519 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2521 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
2520 | protocol = veh->h_vlan_encapsulated_proto; | 2522 | protocol = veh->h_vlan_encapsulated_proto; |
2521 | } else if (!vlan_tx_tag_present(skb)) { | 2523 | } else if (!vlan_tx_tag_present(skb)) { |
2522 | return harmonize_features(skb, features); | 2524 | return harmonize_features(skb, dev, features); |
2523 | } | 2525 | } |
2524 | 2526 | ||
2525 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | | 2527 | features &= (dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | |
2526 | NETIF_F_HW_VLAN_STAG_TX); | 2528 | NETIF_F_HW_VLAN_STAG_TX); |
2527 | 2529 | ||
2528 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) | 2530 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) |
@@ -2530,9 +2532,9 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2530 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | | 2532 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | |
2531 | NETIF_F_HW_VLAN_STAG_TX; | 2533 | NETIF_F_HW_VLAN_STAG_TX; |
2532 | 2534 | ||
2533 | return harmonize_features(skb, features); | 2535 | return harmonize_features(skb, dev, features); |
2534 | } | 2536 | } |
2535 | EXPORT_SYMBOL(netif_skb_features); | 2537 | EXPORT_SYMBOL(netif_skb_dev_features); |
2536 | 2538 | ||
2537 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 2539 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |
2538 | struct netdev_queue *txq) | 2540 | struct netdev_queue *txq) |
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 87577d447554..e29e810663d7 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -323,17 +323,6 @@ u32 __skb_get_poff(const struct sk_buff *skb) | |||
323 | return poff; | 323 | return poff; |
324 | } | 324 | } |
325 | 325 | ||
326 | static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) | ||
327 | { | ||
328 | if (unlikely(queue_index >= dev->real_num_tx_queues)) { | ||
329 | net_warn_ratelimited("%s selects TX queue %d, but real number of TX queues is %d\n", | ||
330 | dev->name, queue_index, | ||
331 | dev->real_num_tx_queues); | ||
332 | return 0; | ||
333 | } | ||
334 | return queue_index; | ||
335 | } | ||
336 | |||
337 | static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) | 326 | static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) |
338 | { | 327 | { |
339 | #ifdef CONFIG_XPS | 328 | #ifdef CONFIG_XPS |
@@ -372,7 +361,7 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) | |||
372 | #endif | 361 | #endif |
373 | } | 362 | } |
374 | 363 | ||
375 | u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) | 364 | static u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) |
376 | { | 365 | { |
377 | struct sock *sk = skb->sk; | 366 | struct sock *sk = skb->sk; |
378 | int queue_index = sk_tx_queue_get(sk); | 367 | int queue_index = sk_tx_queue_get(sk); |
@@ -392,7 +381,6 @@ u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) | |||
392 | 381 | ||
393 | return queue_index; | 382 | return queue_index; |
394 | } | 383 | } |
395 | EXPORT_SYMBOL(__netdev_pick_tx); | ||
396 | 384 | ||
397 | struct netdev_queue *netdev_pick_tx(struct net_device *dev, | 385 | struct netdev_queue *netdev_pick_tx(struct net_device *dev, |
398 | struct sk_buff *skb, | 386 | struct sk_buff *skb, |
@@ -403,13 +391,13 @@ struct netdev_queue *netdev_pick_tx(struct net_device *dev, | |||
403 | if (dev->real_num_tx_queues != 1) { | 391 | if (dev->real_num_tx_queues != 1) { |
404 | const struct net_device_ops *ops = dev->netdev_ops; | 392 | const struct net_device_ops *ops = dev->netdev_ops; |
405 | if (ops->ndo_select_queue) | 393 | if (ops->ndo_select_queue) |
406 | queue_index = ops->ndo_select_queue(dev, skb, | 394 | queue_index = ops->ndo_select_queue(dev, skb, accel_priv, |
407 | accel_priv); | 395 | __netdev_pick_tx); |
408 | else | 396 | else |
409 | queue_index = __netdev_pick_tx(dev, skb); | 397 | queue_index = __netdev_pick_tx(dev, skb); |
410 | 398 | ||
411 | if (!accel_priv) | 399 | if (!accel_priv) |
412 | queue_index = dev_cap_txqueue(dev, queue_index); | 400 | queue_index = netdev_cap_txqueue(dev, queue_index); |
413 | } | 401 | } |
414 | 402 | ||
415 | skb_set_queue_mapping(skb, queue_index); | 403 | skb_set_queue_mapping(skb, queue_index); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 048dc8d183aa..1a0dac2ef9ad 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1963,16 +1963,21 @@ replay: | |||
1963 | 1963 | ||
1964 | dev->ifindex = ifm->ifi_index; | 1964 | dev->ifindex = ifm->ifi_index; |
1965 | 1965 | ||
1966 | if (ops->newlink) | 1966 | if (ops->newlink) { |
1967 | err = ops->newlink(net, dev, tb, data); | 1967 | err = ops->newlink(net, dev, tb, data); |
1968 | else | 1968 | /* Drivers should call free_netdev() in ->destructor |
1969 | * and unregister it on failure so that device could be | ||
1970 | * finally freed in rtnl_unlock. | ||
1971 | */ | ||
1972 | if (err < 0) | ||
1973 | goto out; | ||
1974 | } else { | ||
1969 | err = register_netdevice(dev); | 1975 | err = register_netdevice(dev); |
1970 | 1976 | if (err < 0) { | |
1971 | if (err < 0) { | 1977 | free_netdev(dev); |
1972 | free_netdev(dev); | 1978 | goto out; |
1973 | goto out; | 1979 | } |
1974 | } | 1980 | } |
1975 | |||
1976 | err = rtnl_configure_link(dev, ifm); | 1981 | err = rtnl_configure_link(dev, ifm); |
1977 | if (err < 0) | 1982 | if (err < 0) |
1978 | unregister_netdevice(dev); | 1983 | unregister_netdevice(dev); |
diff --git a/net/dccp/ccids/lib/tfrc.c b/net/dccp/ccids/lib/tfrc.c index c073b81a1f3e..62b5828acde0 100644 --- a/net/dccp/ccids/lib/tfrc.c +++ b/net/dccp/ccids/lib/tfrc.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include "tfrc.h" | 8 | #include "tfrc.h" |
9 | 9 | ||
10 | #ifdef CONFIG_IP_DCCP_TFRC_DEBUG | 10 | #ifdef CONFIG_IP_DCCP_TFRC_DEBUG |
11 | static bool tfrc_debug; | 11 | bool tfrc_debug; |
12 | module_param(tfrc_debug, bool, 0644); | 12 | module_param(tfrc_debug, bool, 0644); |
13 | MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages"); | 13 | MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages"); |
14 | #endif | 14 | #endif |
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h index a3d8f7c76ae0..40ee7d62b652 100644 --- a/net/dccp/ccids/lib/tfrc.h +++ b/net/dccp/ccids/lib/tfrc.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "packet_history.h" | 21 | #include "packet_history.h" |
22 | 22 | ||
23 | #ifdef CONFIG_IP_DCCP_TFRC_DEBUG | 23 | #ifdef CONFIG_IP_DCCP_TFRC_DEBUG |
24 | extern bool tfrc_debug; | ||
24 | #define tfrc_pr_debug(format, a...) DCCP_PR_DEBUG(tfrc_debug, format, ##a) | 25 | #define tfrc_pr_debug(format, a...) DCCP_PR_DEBUG(tfrc_debug, format, ##a) |
25 | #else | 26 | #else |
26 | #define tfrc_pr_debug(format, a...) | 27 | #define tfrc_pr_debug(format, a...) |
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index e9f1217a8afd..f3869c186d97 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
@@ -39,6 +39,71 @@ | |||
39 | #include <net/route.h> | 39 | #include <net/route.h> |
40 | #include <net/xfrm.h> | 40 | #include <net/xfrm.h> |
41 | 41 | ||
42 | static bool ip_may_fragment(const struct sk_buff *skb) | ||
43 | { | ||
44 | return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) || | ||
45 | !skb->local_df; | ||
46 | } | ||
47 | |||
48 | static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) | ||
49 | { | ||
50 | if (skb->len <= mtu || skb->local_df) | ||
51 | return false; | ||
52 | |||
53 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) | ||
54 | return false; | ||
55 | |||
56 | return true; | ||
57 | } | ||
58 | |||
59 | static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb) | ||
60 | { | ||
61 | unsigned int mtu; | ||
62 | |||
63 | if (skb->local_df || !skb_is_gso(skb)) | ||
64 | return false; | ||
65 | |||
66 | mtu = ip_dst_mtu_maybe_forward(skb_dst(skb), true); | ||
67 | |||
68 | /* if seglen > mtu, do software segmentation for IP fragmentation on | ||
69 | * output. DF bit cannot be set since ip_forward would have sent | ||
70 | * icmp error. | ||
71 | */ | ||
72 | return skb_gso_network_seglen(skb) > mtu; | ||
73 | } | ||
74 | |||
75 | /* called if GSO skb needs to be fragmented on forward */ | ||
76 | static int ip_forward_finish_gso(struct sk_buff *skb) | ||
77 | { | ||
78 | struct dst_entry *dst = skb_dst(skb); | ||
79 | netdev_features_t features; | ||
80 | struct sk_buff *segs; | ||
81 | int ret = 0; | ||
82 | |||
83 | features = netif_skb_dev_features(skb, dst->dev); | ||
84 | segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); | ||
85 | if (IS_ERR(segs)) { | ||
86 | kfree_skb(skb); | ||
87 | return -ENOMEM; | ||
88 | } | ||
89 | |||
90 | consume_skb(skb); | ||
91 | |||
92 | do { | ||
93 | struct sk_buff *nskb = segs->next; | ||
94 | int err; | ||
95 | |||
96 | segs->next = NULL; | ||
97 | err = dst_output(segs); | ||
98 | |||
99 | if (err && ret == 0) | ||
100 | ret = err; | ||
101 | segs = nskb; | ||
102 | } while (segs); | ||
103 | |||
104 | return ret; | ||
105 | } | ||
106 | |||
42 | static int ip_forward_finish(struct sk_buff *skb) | 107 | static int ip_forward_finish(struct sk_buff *skb) |
43 | { | 108 | { |
44 | struct ip_options *opt = &(IPCB(skb)->opt); | 109 | struct ip_options *opt = &(IPCB(skb)->opt); |
@@ -49,6 +114,9 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
49 | if (unlikely(opt->optlen)) | 114 | if (unlikely(opt->optlen)) |
50 | ip_forward_options(skb); | 115 | ip_forward_options(skb); |
51 | 116 | ||
117 | if (ip_gso_exceeds_dst_mtu(skb)) | ||
118 | return ip_forward_finish_gso(skb); | ||
119 | |||
52 | return dst_output(skb); | 120 | return dst_output(skb); |
53 | } | 121 | } |
54 | 122 | ||
@@ -91,8 +159,7 @@ int ip_forward(struct sk_buff *skb) | |||
91 | 159 | ||
92 | IPCB(skb)->flags |= IPSKB_FORWARDED; | 160 | IPCB(skb)->flags |= IPSKB_FORWARDED; |
93 | mtu = ip_dst_mtu_maybe_forward(&rt->dst, true); | 161 | mtu = ip_dst_mtu_maybe_forward(&rt->dst, true); |
94 | if (unlikely(skb->len > mtu && !skb_is_gso(skb) && | 162 | if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, mtu)) { |
95 | (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { | ||
96 | IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS); | 163 | IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS); |
97 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 164 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
98 | htonl(mtu)); | 165 | htonl(mtu)); |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index efa1138fa523..b3e86ea7b71b 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -273,7 +273,7 @@ static int __init ic_open_devs(void) | |||
273 | 273 | ||
274 | msleep(1); | 274 | msleep(1); |
275 | 275 | ||
276 | if time_before(jiffies, next_msg) | 276 | if (time_before(jiffies, next_msg)) |
277 | continue; | 277 | continue; |
278 | 278 | ||
279 | elapsed = jiffies_to_msecs(jiffies - start); | 279 | elapsed = jiffies_to_msecs(jiffies - start); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 25071b48921c..4c011ec69ed4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1597,6 +1597,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1597 | rth->rt_gateway = 0; | 1597 | rth->rt_gateway = 0; |
1598 | rth->rt_uses_gateway = 0; | 1598 | rth->rt_uses_gateway = 0; |
1599 | INIT_LIST_HEAD(&rth->rt_uncached); | 1599 | INIT_LIST_HEAD(&rth->rt_uncached); |
1600 | RT_CACHE_STAT_INC(in_slow_tot); | ||
1600 | 1601 | ||
1601 | rth->dst.input = ip_forward; | 1602 | rth->dst.input = ip_forward; |
1602 | rth->dst.output = ip_output; | 1603 | rth->dst.output = ip_output; |
@@ -1695,10 +1696,11 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1695 | fl4.daddr = daddr; | 1696 | fl4.daddr = daddr; |
1696 | fl4.saddr = saddr; | 1697 | fl4.saddr = saddr; |
1697 | err = fib_lookup(net, &fl4, &res); | 1698 | err = fib_lookup(net, &fl4, &res); |
1698 | if (err != 0) | 1699 | if (err != 0) { |
1700 | if (!IN_DEV_FORWARD(in_dev)) | ||
1701 | err = -EHOSTUNREACH; | ||
1699 | goto no_route; | 1702 | goto no_route; |
1700 | 1703 | } | |
1701 | RT_CACHE_STAT_INC(in_slow_tot); | ||
1702 | 1704 | ||
1703 | if (res.type == RTN_BROADCAST) | 1705 | if (res.type == RTN_BROADCAST) |
1704 | goto brd_input; | 1706 | goto brd_input; |
@@ -1712,8 +1714,10 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1712 | goto local_input; | 1714 | goto local_input; |
1713 | } | 1715 | } |
1714 | 1716 | ||
1715 | if (!IN_DEV_FORWARD(in_dev)) | 1717 | if (!IN_DEV_FORWARD(in_dev)) { |
1718 | err = -EHOSTUNREACH; | ||
1716 | goto no_route; | 1719 | goto no_route; |
1720 | } | ||
1717 | if (res.type != RTN_UNICAST) | 1721 | if (res.type != RTN_UNICAST) |
1718 | goto martian_destination; | 1722 | goto martian_destination; |
1719 | 1723 | ||
@@ -1768,6 +1772,7 @@ local_input: | |||
1768 | rth->rt_gateway = 0; | 1772 | rth->rt_gateway = 0; |
1769 | rth->rt_uses_gateway = 0; | 1773 | rth->rt_uses_gateway = 0; |
1770 | INIT_LIST_HEAD(&rth->rt_uncached); | 1774 | INIT_LIST_HEAD(&rth->rt_uncached); |
1775 | RT_CACHE_STAT_INC(in_slow_tot); | ||
1771 | if (res.type == RTN_UNREACHABLE) { | 1776 | if (res.type == RTN_UNREACHABLE) { |
1772 | rth->dst.input= ip_error; | 1777 | rth->dst.input= ip_error; |
1773 | rth->dst.error= -err; | 1778 | rth->dst.error= -err; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ad235690684c..fdbfeca36d63 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2783,6 +2783,8 @@ static void addrconf_gre_config(struct net_device *dev) | |||
2783 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); | 2783 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); |
2784 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) | 2784 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) |
2785 | addrconf_add_linklocal(idev, &addr); | 2785 | addrconf_add_linklocal(idev, &addr); |
2786 | else | ||
2787 | addrconf_prefix_route(&addr, 64, dev, 0, 0); | ||
2786 | } | 2788 | } |
2787 | #endif | 2789 | #endif |
2788 | 2790 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index ef02b26ccf81..070a2fae2375 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -342,6 +342,20 @@ static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) | |||
342 | return mtu; | 342 | return mtu; |
343 | } | 343 | } |
344 | 344 | ||
345 | static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) | ||
346 | { | ||
347 | if (skb->len <= mtu || skb->local_df) | ||
348 | return false; | ||
349 | |||
350 | if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) | ||
351 | return true; | ||
352 | |||
353 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) | ||
354 | return false; | ||
355 | |||
356 | return true; | ||
357 | } | ||
358 | |||
345 | int ip6_forward(struct sk_buff *skb) | 359 | int ip6_forward(struct sk_buff *skb) |
346 | { | 360 | { |
347 | struct dst_entry *dst = skb_dst(skb); | 361 | struct dst_entry *dst = skb_dst(skb); |
@@ -466,8 +480,7 @@ int ip6_forward(struct sk_buff *skb) | |||
466 | if (mtu < IPV6_MIN_MTU) | 480 | if (mtu < IPV6_MIN_MTU) |
467 | mtu = IPV6_MIN_MTU; | 481 | mtu = IPV6_MIN_MTU; |
468 | 482 | ||
469 | if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) || | 483 | if (ip6_pkt_too_big(skb, mtu)) { |
470 | (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) { | ||
471 | /* Again, force OUTPUT device used as source address */ | 484 | /* Again, force OUTPUT device used as source address */ |
472 | skb->dev = dst->dev; | 485 | skb->dev = dst->dev; |
473 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 486 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d6d1f1df9119..ce1c44370610 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1057,7 +1057,8 @@ static void ieee80211_uninit(struct net_device *dev) | |||
1057 | 1057 | ||
1058 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, | 1058 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, |
1059 | struct sk_buff *skb, | 1059 | struct sk_buff *skb, |
1060 | void *accel_priv) | 1060 | void *accel_priv, |
1061 | select_queue_fallback_t fallback) | ||
1061 | { | 1062 | { |
1062 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); | 1063 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); |
1063 | } | 1064 | } |
@@ -1075,7 +1076,8 @@ static const struct net_device_ops ieee80211_dataif_ops = { | |||
1075 | 1076 | ||
1076 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, | 1077 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, |
1077 | struct sk_buff *skb, | 1078 | struct sk_buff *skb, |
1078 | void *accel_priv) | 1079 | void *accel_priv, |
1080 | select_queue_fallback_t fallback) | ||
1079 | { | 1081 | { |
1080 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1082 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1081 | struct ieee80211_local *local = sdata->local; | 1083 | struct ieee80211_local *local = sdata->local; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 6a2bb37506c5..48a6a93db296 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -308,11 +308,27 @@ static bool packet_use_direct_xmit(const struct packet_sock *po) | |||
308 | return po->xmit == packet_direct_xmit; | 308 | return po->xmit == packet_direct_xmit; |
309 | } | 309 | } |
310 | 310 | ||
311 | static u16 packet_pick_tx_queue(struct net_device *dev) | 311 | static u16 __packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb) |
312 | { | 312 | { |
313 | return (u16) raw_smp_processor_id() % dev->real_num_tx_queues; | 313 | return (u16) raw_smp_processor_id() % dev->real_num_tx_queues; |
314 | } | 314 | } |
315 | 315 | ||
316 | static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb) | ||
317 | { | ||
318 | const struct net_device_ops *ops = dev->netdev_ops; | ||
319 | u16 queue_index; | ||
320 | |||
321 | if (ops->ndo_select_queue) { | ||
322 | queue_index = ops->ndo_select_queue(dev, skb, NULL, | ||
323 | __packet_pick_tx_queue); | ||
324 | queue_index = netdev_cap_txqueue(dev, queue_index); | ||
325 | } else { | ||
326 | queue_index = __packet_pick_tx_queue(dev, skb); | ||
327 | } | ||
328 | |||
329 | skb_set_queue_mapping(skb, queue_index); | ||
330 | } | ||
331 | |||
316 | /* register_prot_hook must be invoked with the po->bind_lock held, | 332 | /* register_prot_hook must be invoked with the po->bind_lock held, |
317 | * or from a context in which asynchronous accesses to the packet | 333 | * or from a context in which asynchronous accesses to the packet |
318 | * socket is not possible (packet_create()). | 334 | * socket is not possible (packet_create()). |
@@ -2285,7 +2301,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2285 | } | 2301 | } |
2286 | } | 2302 | } |
2287 | 2303 | ||
2288 | skb_set_queue_mapping(skb, packet_pick_tx_queue(dev)); | 2304 | packet_pick_tx_queue(dev, skb); |
2305 | |||
2289 | skb->destructor = tpacket_destruct_skb; | 2306 | skb->destructor = tpacket_destruct_skb; |
2290 | __packet_set_status(po, ph, TP_STATUS_SENDING); | 2307 | __packet_set_status(po, ph, TP_STATUS_SENDING); |
2291 | packet_inc_pending(&po->tx_ring); | 2308 | packet_inc_pending(&po->tx_ring); |
@@ -2499,7 +2516,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2499 | skb->dev = dev; | 2516 | skb->dev = dev; |
2500 | skb->priority = sk->sk_priority; | 2517 | skb->priority = sk->sk_priority; |
2501 | skb->mark = sk->sk_mark; | 2518 | skb->mark = sk->sk_mark; |
2502 | skb_set_queue_mapping(skb, packet_pick_tx_queue(dev)); | 2519 | |
2520 | packet_pick_tx_queue(dev, skb); | ||
2503 | 2521 | ||
2504 | if (po->has_vnet_hdr) { | 2522 | if (po->has_vnet_hdr) { |
2505 | if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { | 2523 | if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { |
@@ -3786,7 +3804,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
3786 | */ | 3804 | */ |
3787 | if (!tx_ring) | 3805 | if (!tx_ring) |
3788 | init_prb_bdqc(po, rb, pg_vec, req_u, tx_ring); | 3806 | init_prb_bdqc(po, rb, pg_vec, req_u, tx_ring); |
3789 | break; | 3807 | break; |
3790 | default: | 3808 | default: |
3791 | break; | 3809 | break; |
3792 | } | 3810 | } |
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c index a255d0200a59..fefeeb73f15f 100644 --- a/net/sched/sch_pie.c +++ b/net/sched/sch_pie.c | |||
@@ -15,6 +15,11 @@ | |||
15 | * | 15 | * |
16 | * ECN support is added by Naeem Khademi <naeemk@ifi.uio.no> | 16 | * ECN support is added by Naeem Khademi <naeemk@ifi.uio.no> |
17 | * University of Oslo, Norway. | 17 | * University of Oslo, Norway. |
18 | * | ||
19 | * References: | ||
20 | * IETF draft submission: http://tools.ietf.org/html/draft-pan-aqm-pie-00 | ||
21 | * IEEE Conference on High Performance Switching and Routing 2013 : | ||
22 | * "PIE: A * Lightweight Control Scheme to Address the Bufferbloat Problem" | ||
18 | */ | 23 | */ |
19 | 24 | ||
20 | #include <linux/module.h> | 25 | #include <linux/module.h> |
@@ -36,7 +41,7 @@ struct pie_params { | |||
36 | psched_time_t target; /* user specified target delay in pschedtime */ | 41 | psched_time_t target; /* user specified target delay in pschedtime */ |
37 | u32 tupdate; /* timer frequency (in jiffies) */ | 42 | u32 tupdate; /* timer frequency (in jiffies) */ |
38 | u32 limit; /* number of packets that can be enqueued */ | 43 | u32 limit; /* number of packets that can be enqueued */ |
39 | u32 alpha; /* alpha and beta are between -4 and 4 */ | 44 | u32 alpha; /* alpha and beta are between 0 and 32 */ |
40 | u32 beta; /* and are used for shift relative to 1 */ | 45 | u32 beta; /* and are used for shift relative to 1 */ |
41 | bool ecn; /* true if ecn is enabled */ | 46 | bool ecn; /* true if ecn is enabled */ |
42 | bool bytemode; /* to scale drop early prob based on pkt size */ | 47 | bool bytemode; /* to scale drop early prob based on pkt size */ |
@@ -326,10 +331,16 @@ static void calculate_probability(struct Qdisc *sch) | |||
326 | if (qdelay == 0 && qlen != 0) | 331 | if (qdelay == 0 && qlen != 0) |
327 | update_prob = false; | 332 | update_prob = false; |
328 | 333 | ||
329 | /* Add ranges for alpha and beta, more aggressive for high dropping | 334 | /* In the algorithm, alpha and beta are between 0 and 2 with typical |
330 | * mode and gentle steps for light dropping mode | 335 | * value for alpha as 0.125. In this implementation, we use values 0-32 |
331 | * In light dropping mode, take gentle steps; in medium dropping mode, | 336 | * passed from user space to represent this. Also, alpha and beta have |
332 | * take medium steps; in high dropping mode, take big steps. | 337 | * unit of HZ and need to be scaled before they can used to update |
338 | * probability. alpha/beta are updated locally below by 1) scaling them | ||
339 | * appropriately 2) scaling down by 16 to come to 0-2 range. | ||
340 | * Please see paper for details. | ||
341 | * | ||
342 | * We scale alpha and beta differently depending on whether we are in | ||
343 | * light, medium or high dropping mode. | ||
333 | */ | 344 | */ |
334 | if (q->vars.prob < MAX_PROB / 100) { | 345 | if (q->vars.prob < MAX_PROB / 100) { |
335 | alpha = | 346 | alpha = |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 5ae609200674..f558433537b8 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -1367,44 +1367,35 @@ static inline bool sctp_peer_needs_update(struct sctp_association *asoc) | |||
1367 | return false; | 1367 | return false; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | /* Increase asoc's rwnd by len and send any window update SACK if needed. */ | 1370 | /* Update asoc's rwnd for the approximated state in the buffer, |
1371 | void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned int len) | 1371 | * and check whether SACK needs to be sent. |
1372 | */ | ||
1373 | void sctp_assoc_rwnd_update(struct sctp_association *asoc, bool update_peer) | ||
1372 | { | 1374 | { |
1375 | int rx_count; | ||
1373 | struct sctp_chunk *sack; | 1376 | struct sctp_chunk *sack; |
1374 | struct timer_list *timer; | 1377 | struct timer_list *timer; |
1375 | 1378 | ||
1376 | if (asoc->rwnd_over) { | 1379 | if (asoc->ep->rcvbuf_policy) |
1377 | if (asoc->rwnd_over >= len) { | 1380 | rx_count = atomic_read(&asoc->rmem_alloc); |
1378 | asoc->rwnd_over -= len; | 1381 | else |
1379 | } else { | 1382 | rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); |
1380 | asoc->rwnd += (len - asoc->rwnd_over); | ||
1381 | asoc->rwnd_over = 0; | ||
1382 | } | ||
1383 | } else { | ||
1384 | asoc->rwnd += len; | ||
1385 | } | ||
1386 | 1383 | ||
1387 | /* If we had window pressure, start recovering it | 1384 | if ((asoc->base.sk->sk_rcvbuf - rx_count) > 0) |
1388 | * once our rwnd had reached the accumulated pressure | 1385 | asoc->rwnd = (asoc->base.sk->sk_rcvbuf - rx_count) >> 1; |
1389 | * threshold. The idea is to recover slowly, but up | 1386 | else |
1390 | * to the initial advertised window. | 1387 | asoc->rwnd = 0; |
1391 | */ | ||
1392 | if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) { | ||
1393 | int change = min(asoc->pathmtu, asoc->rwnd_press); | ||
1394 | asoc->rwnd += change; | ||
1395 | asoc->rwnd_press -= change; | ||
1396 | } | ||
1397 | 1388 | ||
1398 | pr_debug("%s: asoc:%p rwnd increased by %d to (%u, %u) - %u\n", | 1389 | pr_debug("%s: asoc:%p rwnd=%u, rx_count=%d, sk_rcvbuf=%d\n", |
1399 | __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, | 1390 | __func__, asoc, asoc->rwnd, rx_count, |
1400 | asoc->a_rwnd); | 1391 | asoc->base.sk->sk_rcvbuf); |
1401 | 1392 | ||
1402 | /* Send a window update SACK if the rwnd has increased by at least the | 1393 | /* Send a window update SACK if the rwnd has increased by at least the |
1403 | * minimum of the association's PMTU and half of the receive buffer. | 1394 | * minimum of the association's PMTU and half of the receive buffer. |
1404 | * The algorithm used is similar to the one described in | 1395 | * The algorithm used is similar to the one described in |
1405 | * Section 4.2.3.3 of RFC 1122. | 1396 | * Section 4.2.3.3 of RFC 1122. |
1406 | */ | 1397 | */ |
1407 | if (sctp_peer_needs_update(asoc)) { | 1398 | if (update_peer && sctp_peer_needs_update(asoc)) { |
1408 | asoc->a_rwnd = asoc->rwnd; | 1399 | asoc->a_rwnd = asoc->rwnd; |
1409 | 1400 | ||
1410 | pr_debug("%s: sending window update SACK- asoc:%p rwnd:%u " | 1401 | pr_debug("%s: sending window update SACK- asoc:%p rwnd:%u " |
@@ -1426,45 +1417,6 @@ void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned int len) | |||
1426 | } | 1417 | } |
1427 | } | 1418 | } |
1428 | 1419 | ||
1429 | /* Decrease asoc's rwnd by len. */ | ||
1430 | void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len) | ||
1431 | { | ||
1432 | int rx_count; | ||
1433 | int over = 0; | ||
1434 | |||
1435 | if (unlikely(!asoc->rwnd || asoc->rwnd_over)) | ||
1436 | pr_debug("%s: association:%p has asoc->rwnd:%u, " | ||
1437 | "asoc->rwnd_over:%u!\n", __func__, asoc, | ||
1438 | asoc->rwnd, asoc->rwnd_over); | ||
1439 | |||
1440 | if (asoc->ep->rcvbuf_policy) | ||
1441 | rx_count = atomic_read(&asoc->rmem_alloc); | ||
1442 | else | ||
1443 | rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); | ||
1444 | |||
1445 | /* If we've reached or overflowed our receive buffer, announce | ||
1446 | * a 0 rwnd if rwnd would still be positive. Store the | ||
1447 | * the potential pressure overflow so that the window can be restored | ||
1448 | * back to original value. | ||
1449 | */ | ||
1450 | if (rx_count >= asoc->base.sk->sk_rcvbuf) | ||
1451 | over = 1; | ||
1452 | |||
1453 | if (asoc->rwnd >= len) { | ||
1454 | asoc->rwnd -= len; | ||
1455 | if (over) { | ||
1456 | asoc->rwnd_press += asoc->rwnd; | ||
1457 | asoc->rwnd = 0; | ||
1458 | } | ||
1459 | } else { | ||
1460 | asoc->rwnd_over = len - asoc->rwnd; | ||
1461 | asoc->rwnd = 0; | ||
1462 | } | ||
1463 | |||
1464 | pr_debug("%s: asoc:%p rwnd decreased by %d to (%u, %u, %u)\n", | ||
1465 | __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, | ||
1466 | asoc->rwnd_press); | ||
1467 | } | ||
1468 | 1420 | ||
1469 | /* Build the bind address list for the association based on info from the | 1421 | /* Build the bind address list for the association based on info from the |
1470 | * local endpoint and the remote peer. | 1422 | * local endpoint and the remote peer. |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 483dcd71b3c5..591b44d3b7de 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -6176,7 +6176,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
6176 | * PMTU. In cases, such as loopback, this might be a rather | 6176 | * PMTU. In cases, such as loopback, this might be a rather |
6177 | * large spill over. | 6177 | * large spill over. |
6178 | */ | 6178 | */ |
6179 | if ((!chunk->data_accepted) && (!asoc->rwnd || asoc->rwnd_over || | 6179 | if ((!chunk->data_accepted) && (!asoc->rwnd || |
6180 | (datalen > asoc->rwnd + asoc->frag_point))) { | 6180 | (datalen > asoc->rwnd + asoc->frag_point))) { |
6181 | 6181 | ||
6182 | /* If this is the next TSN, consider reneging to make | 6182 | /* If this is the next TSN, consider reneging to make |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9e91d6e5df63..981aaf8b6ace 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/crypto.h> | 64 | #include <linux/crypto.h> |
65 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
66 | #include <linux/file.h> | 66 | #include <linux/file.h> |
67 | #include <linux/compat.h> | ||
67 | 68 | ||
68 | #include <net/ip.h> | 69 | #include <net/ip.h> |
69 | #include <net/icmp.h> | 70 | #include <net/icmp.h> |
@@ -1368,11 +1369,19 @@ static int sctp_setsockopt_connectx(struct sock *sk, | |||
1368 | /* | 1369 | /* |
1369 | * New (hopefully final) interface for the API. | 1370 | * New (hopefully final) interface for the API. |
1370 | * We use the sctp_getaddrs_old structure so that use-space library | 1371 | * We use the sctp_getaddrs_old structure so that use-space library |
1371 | * can avoid any unnecessary allocations. The only defferent part | 1372 | * can avoid any unnecessary allocations. The only different part |
1372 | * is that we store the actual length of the address buffer into the | 1373 | * is that we store the actual length of the address buffer into the |
1373 | * addrs_num structure member. That way we can re-use the existing | 1374 | * addrs_num structure member. That way we can re-use the existing |
1374 | * code. | 1375 | * code. |
1375 | */ | 1376 | */ |
1377 | #ifdef CONFIG_COMPAT | ||
1378 | struct compat_sctp_getaddrs_old { | ||
1379 | sctp_assoc_t assoc_id; | ||
1380 | s32 addr_num; | ||
1381 | compat_uptr_t addrs; /* struct sockaddr * */ | ||
1382 | }; | ||
1383 | #endif | ||
1384 | |||
1376 | static int sctp_getsockopt_connectx3(struct sock *sk, int len, | 1385 | static int sctp_getsockopt_connectx3(struct sock *sk, int len, |
1377 | char __user *optval, | 1386 | char __user *optval, |
1378 | int __user *optlen) | 1387 | int __user *optlen) |
@@ -1381,16 +1390,30 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len, | |||
1381 | sctp_assoc_t assoc_id = 0; | 1390 | sctp_assoc_t assoc_id = 0; |
1382 | int err = 0; | 1391 | int err = 0; |
1383 | 1392 | ||
1384 | if (len < sizeof(param)) | 1393 | #ifdef CONFIG_COMPAT |
1385 | return -EINVAL; | 1394 | if (is_compat_task()) { |
1395 | struct compat_sctp_getaddrs_old param32; | ||
1386 | 1396 | ||
1387 | if (copy_from_user(¶m, optval, sizeof(param))) | 1397 | if (len < sizeof(param32)) |
1388 | return -EFAULT; | 1398 | return -EINVAL; |
1399 | if (copy_from_user(¶m32, optval, sizeof(param32))) | ||
1400 | return -EFAULT; | ||
1389 | 1401 | ||
1390 | err = __sctp_setsockopt_connectx(sk, | 1402 | param.assoc_id = param32.assoc_id; |
1391 | (struct sockaddr __user *)param.addrs, | 1403 | param.addr_num = param32.addr_num; |
1392 | param.addr_num, &assoc_id); | 1404 | param.addrs = compat_ptr(param32.addrs); |
1405 | } else | ||
1406 | #endif | ||
1407 | { | ||
1408 | if (len < sizeof(param)) | ||
1409 | return -EINVAL; | ||
1410 | if (copy_from_user(¶m, optval, sizeof(param))) | ||
1411 | return -EFAULT; | ||
1412 | } | ||
1393 | 1413 | ||
1414 | err = __sctp_setsockopt_connectx(sk, (struct sockaddr __user *) | ||
1415 | param.addrs, param.addr_num, | ||
1416 | &assoc_id); | ||
1394 | if (err == 0 || err == -EINPROGRESS) { | 1417 | if (err == 0 || err == -EINPROGRESS) { |
1395 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) | 1418 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) |
1396 | return -EFAULT; | 1419 | return -EFAULT; |
@@ -2092,12 +2115,6 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
2092 | sctp_skb_pull(skb, copied); | 2115 | sctp_skb_pull(skb, copied); |
2093 | skb_queue_head(&sk->sk_receive_queue, skb); | 2116 | skb_queue_head(&sk->sk_receive_queue, skb); |
2094 | 2117 | ||
2095 | /* When only partial message is copied to the user, increase | ||
2096 | * rwnd by that amount. If all the data in the skb is read, | ||
2097 | * rwnd is updated when the event is freed. | ||
2098 | */ | ||
2099 | if (!sctp_ulpevent_is_notification(event)) | ||
2100 | sctp_assoc_rwnd_increase(event->asoc, copied); | ||
2101 | goto out; | 2118 | goto out; |
2102 | } else if ((event->msg_flags & MSG_NOTIFICATION) || | 2119 | } else if ((event->msg_flags & MSG_NOTIFICATION) || |
2103 | (event->msg_flags & MSG_EOR)) | 2120 | (event->msg_flags & MSG_EOR)) |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 7135e617ab0f..35c8923b5554 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -151,6 +151,7 @@ static struct ctl_table sctp_net_table[] = { | |||
151 | }, | 151 | }, |
152 | { | 152 | { |
153 | .procname = "cookie_hmac_alg", | 153 | .procname = "cookie_hmac_alg", |
154 | .data = &init_net.sctp.sctp_hmac_alg, | ||
154 | .maxlen = 8, | 155 | .maxlen = 8, |
155 | .mode = 0644, | 156 | .mode = 0644, |
156 | .proc_handler = proc_sctp_do_hmac_alg, | 157 | .proc_handler = proc_sctp_do_hmac_alg, |
@@ -401,15 +402,18 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | |||
401 | 402 | ||
402 | int sctp_sysctl_net_register(struct net *net) | 403 | int sctp_sysctl_net_register(struct net *net) |
403 | { | 404 | { |
404 | struct ctl_table *table; | 405 | struct ctl_table *table = sctp_net_table; |
405 | int i; | 406 | |
407 | if (!net_eq(net, &init_net)) { | ||
408 | int i; | ||
406 | 409 | ||
407 | table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); | 410 | table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); |
408 | if (!table) | 411 | if (!table) |
409 | return -ENOMEM; | 412 | return -ENOMEM; |
410 | 413 | ||
411 | for (i = 0; table[i].data; i++) | 414 | for (i = 0; table[i].data; i++) |
412 | table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; | 415 | table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; |
416 | } | ||
413 | 417 | ||
414 | net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); | 418 | net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); |
415 | return 0; | 419 | return 0; |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 85c64658bd0b..8d198ae03606 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -989,7 +989,7 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | |||
989 | skb = sctp_event2skb(event); | 989 | skb = sctp_event2skb(event); |
990 | /* Set the owner and charge rwnd for bytes received. */ | 990 | /* Set the owner and charge rwnd for bytes received. */ |
991 | sctp_ulpevent_set_owner(event, asoc); | 991 | sctp_ulpevent_set_owner(event, asoc); |
992 | sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb)); | 992 | sctp_assoc_rwnd_update(asoc, false); |
993 | 993 | ||
994 | if (!skb->data_len) | 994 | if (!skb->data_len) |
995 | return; | 995 | return; |
@@ -1011,6 +1011,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
1011 | { | 1011 | { |
1012 | struct sk_buff *skb, *frag; | 1012 | struct sk_buff *skb, *frag; |
1013 | unsigned int len; | 1013 | unsigned int len; |
1014 | struct sctp_association *asoc; | ||
1014 | 1015 | ||
1015 | /* Current stack structures assume that the rcv buffer is | 1016 | /* Current stack structures assume that the rcv buffer is |
1016 | * per socket. For UDP style sockets this is not true as | 1017 | * per socket. For UDP style sockets this is not true as |
@@ -1035,8 +1036,11 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
1035 | } | 1036 | } |
1036 | 1037 | ||
1037 | done: | 1038 | done: |
1038 | sctp_assoc_rwnd_increase(event->asoc, len); | 1039 | asoc = event->asoc; |
1040 | sctp_association_hold(asoc); | ||
1039 | sctp_ulpevent_release_owner(event); | 1041 | sctp_ulpevent_release_owner(event); |
1042 | sctp_assoc_rwnd_update(asoc, true); | ||
1043 | sctp_association_put(asoc); | ||
1040 | } | 1044 | } |
1041 | 1045 | ||
1042 | static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) | 1046 | static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 6c0513a7f992..36e431ee1c90 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -108,6 +108,7 @@ struct gss_auth { | |||
108 | static DEFINE_SPINLOCK(pipe_version_lock); | 108 | static DEFINE_SPINLOCK(pipe_version_lock); |
109 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; | 109 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; |
110 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); | 110 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); |
111 | static void gss_put_auth(struct gss_auth *gss_auth); | ||
111 | 112 | ||
112 | static void gss_free_ctx(struct gss_cl_ctx *); | 113 | static void gss_free_ctx(struct gss_cl_ctx *); |
113 | static const struct rpc_pipe_ops gss_upcall_ops_v0; | 114 | static const struct rpc_pipe_ops gss_upcall_ops_v0; |
@@ -320,6 +321,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
320 | if (gss_msg->ctx != NULL) | 321 | if (gss_msg->ctx != NULL) |
321 | gss_put_ctx(gss_msg->ctx); | 322 | gss_put_ctx(gss_msg->ctx); |
322 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); | 323 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); |
324 | gss_put_auth(gss_msg->auth); | ||
323 | kfree(gss_msg); | 325 | kfree(gss_msg); |
324 | } | 326 | } |
325 | 327 | ||
@@ -498,9 +500,12 @@ gss_alloc_msg(struct gss_auth *gss_auth, | |||
498 | default: | 500 | default: |
499 | err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); | 501 | err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); |
500 | if (err) | 502 | if (err) |
501 | goto err_free_msg; | 503 | goto err_put_pipe_version; |
502 | }; | 504 | }; |
505 | kref_get(&gss_auth->kref); | ||
503 | return gss_msg; | 506 | return gss_msg; |
507 | err_put_pipe_version: | ||
508 | put_pipe_version(gss_auth->net); | ||
504 | err_free_msg: | 509 | err_free_msg: |
505 | kfree(gss_msg); | 510 | kfree(gss_msg); |
506 | err: | 511 | err: |
@@ -991,6 +996,8 @@ gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | |||
991 | gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); | 996 | gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); |
992 | if (gss_auth->service == 0) | 997 | if (gss_auth->service == 0) |
993 | goto err_put_mech; | 998 | goto err_put_mech; |
999 | if (!gssd_running(gss_auth->net)) | ||
1000 | goto err_put_mech; | ||
994 | auth = &gss_auth->rpc_auth; | 1001 | auth = &gss_auth->rpc_auth; |
995 | auth->au_cslack = GSS_CRED_SLACK >> 2; | 1002 | auth->au_cslack = GSS_CRED_SLACK >> 2; |
996 | auth->au_rslack = GSS_VERF_SLACK >> 2; | 1003 | auth->au_rslack = GSS_VERF_SLACK >> 2; |
@@ -1062,6 +1069,12 @@ gss_free_callback(struct kref *kref) | |||
1062 | } | 1069 | } |
1063 | 1070 | ||
1064 | static void | 1071 | static void |
1072 | gss_put_auth(struct gss_auth *gss_auth) | ||
1073 | { | ||
1074 | kref_put(&gss_auth->kref, gss_free_callback); | ||
1075 | } | ||
1076 | |||
1077 | static void | ||
1065 | gss_destroy(struct rpc_auth *auth) | 1078 | gss_destroy(struct rpc_auth *auth) |
1066 | { | 1079 | { |
1067 | struct gss_auth *gss_auth = container_of(auth, | 1080 | struct gss_auth *gss_auth = container_of(auth, |
@@ -1082,7 +1095,7 @@ gss_destroy(struct rpc_auth *auth) | |||
1082 | gss_auth->gss_pipe[1] = NULL; | 1095 | gss_auth->gss_pipe[1] = NULL; |
1083 | rpcauth_destroy_credcache(auth); | 1096 | rpcauth_destroy_credcache(auth); |
1084 | 1097 | ||
1085 | kref_put(&gss_auth->kref, gss_free_callback); | 1098 | gss_put_auth(gss_auth); |
1086 | } | 1099 | } |
1087 | 1100 | ||
1088 | /* | 1101 | /* |
@@ -1253,7 +1266,7 @@ gss_destroy_nullcred(struct rpc_cred *cred) | |||
1253 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); | 1266 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); |
1254 | if (ctx) | 1267 | if (ctx) |
1255 | gss_put_ctx(ctx); | 1268 | gss_put_ctx(ctx); |
1256 | kref_put(&gss_auth->kref, gss_free_callback); | 1269 | gss_put_auth(gss_auth); |
1257 | } | 1270 | } |
1258 | 1271 | ||
1259 | static void | 1272 | static void |
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 890a29912d5a..e860d4f7ed2a 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
@@ -64,7 +64,6 @@ static void xprt_free_allocation(struct rpc_rqst *req) | |||
64 | free_page((unsigned long)xbufp->head[0].iov_base); | 64 | free_page((unsigned long)xbufp->head[0].iov_base); |
65 | xbufp = &req->rq_snd_buf; | 65 | xbufp = &req->rq_snd_buf; |
66 | free_page((unsigned long)xbufp->head[0].iov_base); | 66 | free_page((unsigned long)xbufp->head[0].iov_base); |
67 | list_del(&req->rq_bc_pa_list); | ||
68 | kfree(req); | 67 | kfree(req); |
69 | } | 68 | } |
70 | 69 | ||
@@ -168,8 +167,10 @@ out_free: | |||
168 | /* | 167 | /* |
169 | * Memory allocation failed, free the temporary list | 168 | * Memory allocation failed, free the temporary list |
170 | */ | 169 | */ |
171 | list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) | 170 | list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) { |
171 | list_del(&req->rq_bc_pa_list); | ||
172 | xprt_free_allocation(req); | 172 | xprt_free_allocation(req); |
173 | } | ||
173 | 174 | ||
174 | dprintk("RPC: setup backchannel transport failed\n"); | 175 | dprintk("RPC: setup backchannel transport failed\n"); |
175 | return -ENOMEM; | 176 | return -ENOMEM; |
@@ -198,6 +199,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs) | |||
198 | xprt_dec_alloc_count(xprt, max_reqs); | 199 | xprt_dec_alloc_count(xprt, max_reqs); |
199 | list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { | 200 | list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { |
200 | dprintk("RPC: req=%p\n", req); | 201 | dprintk("RPC: req=%p\n", req); |
202 | list_del(&req->rq_bc_pa_list); | ||
201 | xprt_free_allocation(req); | 203 | xprt_free_allocation(req); |
202 | if (--max_reqs == 0) | 204 | if (--max_reqs == 0) |
203 | break; | 205 | break; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 817a1e523969..0addefca8e77 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -510,6 +510,7 @@ static int xs_nospace(struct rpc_task *task) | |||
510 | struct rpc_rqst *req = task->tk_rqstp; | 510 | struct rpc_rqst *req = task->tk_rqstp; |
511 | struct rpc_xprt *xprt = req->rq_xprt; | 511 | struct rpc_xprt *xprt = req->rq_xprt; |
512 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 512 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
513 | struct sock *sk = transport->inet; | ||
513 | int ret = -EAGAIN; | 514 | int ret = -EAGAIN; |
514 | 515 | ||
515 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", | 516 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", |
@@ -527,7 +528,7 @@ static int xs_nospace(struct rpc_task *task) | |||
527 | * window size | 528 | * window size |
528 | */ | 529 | */ |
529 | set_bit(SOCK_NOSPACE, &transport->sock->flags); | 530 | set_bit(SOCK_NOSPACE, &transport->sock->flags); |
530 | transport->inet->sk_write_pending++; | 531 | sk->sk_write_pending++; |
531 | /* ...and wait for more buffer space */ | 532 | /* ...and wait for more buffer space */ |
532 | xprt_wait_for_buffer_space(task, xs_nospace_callback); | 533 | xprt_wait_for_buffer_space(task, xs_nospace_callback); |
533 | } | 534 | } |
@@ -537,6 +538,9 @@ static int xs_nospace(struct rpc_task *task) | |||
537 | } | 538 | } |
538 | 539 | ||
539 | spin_unlock_bh(&xprt->transport_lock); | 540 | spin_unlock_bh(&xprt->transport_lock); |
541 | |||
542 | /* Race breaker in case memory is freed before above code is called */ | ||
543 | sk->sk_write_space(sk); | ||
540 | return ret; | 544 | return ret; |
541 | } | 545 | } |
542 | 546 | ||
diff --git a/net/tipc/core.h b/net/tipc/core.h index 1ff477b0450d..5569d96b4da3 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -192,6 +192,7 @@ static inline void k_term_timer(struct timer_list *timer) | |||
192 | 192 | ||
193 | struct tipc_skb_cb { | 193 | struct tipc_skb_cb { |
194 | void *handle; | 194 | void *handle; |
195 | bool deferred; | ||
195 | }; | 196 | }; |
196 | 197 | ||
197 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) | 198 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) |
diff --git a/net/tipc/link.c b/net/tipc/link.c index d4b5de41b682..da6018beb6eb 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1391,6 +1391,12 @@ static int link_recv_buf_validate(struct sk_buff *buf) | |||
1391 | u32 hdr_size; | 1391 | u32 hdr_size; |
1392 | u32 min_hdr_size; | 1392 | u32 min_hdr_size; |
1393 | 1393 | ||
1394 | /* If this packet comes from the defer queue, the skb has already | ||
1395 | * been validated | ||
1396 | */ | ||
1397 | if (unlikely(TIPC_SKB_CB(buf)->deferred)) | ||
1398 | return 1; | ||
1399 | |||
1394 | if (unlikely(buf->len < MIN_H_SIZE)) | 1400 | if (unlikely(buf->len < MIN_H_SIZE)) |
1395 | return 0; | 1401 | return 0; |
1396 | 1402 | ||
@@ -1703,6 +1709,7 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, | |||
1703 | &l_ptr->newest_deferred_in, buf)) { | 1709 | &l_ptr->newest_deferred_in, buf)) { |
1704 | l_ptr->deferred_inqueue_sz++; | 1710 | l_ptr->deferred_inqueue_sz++; |
1705 | l_ptr->stats.deferred_recv++; | 1711 | l_ptr->stats.deferred_recv++; |
1712 | TIPC_SKB_CB(buf)->deferred = true; | ||
1706 | if ((l_ptr->deferred_inqueue_sz % 16) == 1) | 1713 | if ((l_ptr->deferred_inqueue_sz % 16) == 1) |
1707 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); | 1714 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); |
1708 | } else | 1715 | } else |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 49392ecbef17..79c059e70860 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -152,6 +152,7 @@ ld_flags = $(LDFLAGS) $(ldflags-y) | |||
152 | dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ | 152 | dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ |
153 | -I$(srctree)/arch/$(SRCARCH)/boot/dts \ | 153 | -I$(srctree)/arch/$(SRCARCH)/boot/dts \ |
154 | -I$(srctree)/arch/$(SRCARCH)/boot/dts/include \ | 154 | -I$(srctree)/arch/$(SRCARCH)/boot/dts/include \ |
155 | -I$(srctree)/drivers/of/testcase-data \ | ||
155 | -undef -D__DTS__ | 156 | -undef -D__DTS__ |
156 | 157 | ||
157 | # Finds the multi-part object the current object will be linked into | 158 | # Finds the multi-part object the current object will be linked into |
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index c0f498842129..9c5cdc2caaef 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -3338,10 +3338,10 @@ static int filename_write_helper(void *key, void *data, void *ptr) | |||
3338 | if (rc) | 3338 | if (rc) |
3339 | return rc; | 3339 | return rc; |
3340 | 3340 | ||
3341 | buf[0] = ft->stype; | 3341 | buf[0] = cpu_to_le32(ft->stype); |
3342 | buf[1] = ft->ttype; | 3342 | buf[1] = cpu_to_le32(ft->ttype); |
3343 | buf[2] = ft->tclass; | 3343 | buf[2] = cpu_to_le32(ft->tclass); |
3344 | buf[3] = otype->otype; | 3344 | buf[3] = cpu_to_le32(otype->otype); |
3345 | 3345 | ||
3346 | rc = put_entry(buf, sizeof(u32), 4, fp); | 3346 | rc = put_entry(buf, sizeof(u32), 4, fp); |
3347 | if (rc) | 3347 | if (rc) |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 54d14793725a..46ecdbb9053f 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -2662,60 +2662,6 @@ static bool dspload_wait_loaded(struct hda_codec *codec) | |||
2662 | } | 2662 | } |
2663 | 2663 | ||
2664 | /* | 2664 | /* |
2665 | * PCM stuffs | ||
2666 | */ | ||
2667 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | ||
2668 | u32 stream_tag, | ||
2669 | int channel_id, int format) | ||
2670 | { | ||
2671 | unsigned int oldval, newval; | ||
2672 | |||
2673 | if (!nid) | ||
2674 | return; | ||
2675 | |||
2676 | snd_printdd( | ||
2677 | "ca0132_setup_stream: NID=0x%x, stream=0x%x, " | ||
2678 | "channel=%d, format=0x%x\n", | ||
2679 | nid, stream_tag, channel_id, format); | ||
2680 | |||
2681 | /* update the format-id if changed */ | ||
2682 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
2683 | AC_VERB_GET_STREAM_FORMAT, | ||
2684 | 0); | ||
2685 | if (oldval != format) { | ||
2686 | msleep(20); | ||
2687 | snd_hda_codec_write(codec, nid, 0, | ||
2688 | AC_VERB_SET_STREAM_FORMAT, | ||
2689 | format); | ||
2690 | } | ||
2691 | |||
2692 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
2693 | newval = (stream_tag << 4) | channel_id; | ||
2694 | if (oldval != newval) { | ||
2695 | snd_hda_codec_write(codec, nid, 0, | ||
2696 | AC_VERB_SET_CHANNEL_STREAMID, | ||
2697 | newval); | ||
2698 | } | ||
2699 | } | ||
2700 | |||
2701 | static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) | ||
2702 | { | ||
2703 | unsigned int val; | ||
2704 | |||
2705 | if (!nid) | ||
2706 | return; | ||
2707 | |||
2708 | snd_printdd(KERN_INFO "ca0132_cleanup_stream: NID=0x%x\n", nid); | ||
2709 | |||
2710 | val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
2711 | if (!val) | ||
2712 | return; | ||
2713 | |||
2714 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); | ||
2715 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
2716 | } | ||
2717 | |||
2718 | /* | ||
2719 | * PCM callbacks | 2665 | * PCM callbacks |
2720 | */ | 2666 | */ |
2721 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 2667 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
@@ -2726,7 +2672,7 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2726 | { | 2672 | { |
2727 | struct ca0132_spec *spec = codec->spec; | 2673 | struct ca0132_spec *spec = codec->spec; |
2728 | 2674 | ||
2729 | ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); | 2675 | snd_hda_codec_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); |
2730 | 2676 | ||
2731 | return 0; | 2677 | return 0; |
2732 | } | 2678 | } |
@@ -2745,7 +2691,7 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2745 | if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) | 2691 | if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) |
2746 | msleep(50); | 2692 | msleep(50); |
2747 | 2693 | ||
2748 | ca0132_cleanup_stream(codec, spec->dacs[0]); | 2694 | snd_hda_codec_cleanup_stream(codec, spec->dacs[0]); |
2749 | 2695 | ||
2750 | return 0; | 2696 | return 0; |
2751 | } | 2697 | } |
@@ -2822,10 +2768,8 @@ static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2822 | unsigned int format, | 2768 | unsigned int format, |
2823 | struct snd_pcm_substream *substream) | 2769 | struct snd_pcm_substream *substream) |
2824 | { | 2770 | { |
2825 | struct ca0132_spec *spec = codec->spec; | 2771 | snd_hda_codec_setup_stream(codec, hinfo->nid, |
2826 | 2772 | stream_tag, 0, format); | |
2827 | ca0132_setup_stream(codec, spec->adcs[substream->number], | ||
2828 | stream_tag, 0, format); | ||
2829 | 2773 | ||
2830 | return 0; | 2774 | return 0; |
2831 | } | 2775 | } |
@@ -2839,7 +2783,7 @@ static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2839 | if (spec->dsp_state == DSP_DOWNLOADING) | 2783 | if (spec->dsp_state == DSP_DOWNLOADING) |
2840 | return 0; | 2784 | return 0; |
2841 | 2785 | ||
2842 | ca0132_cleanup_stream(codec, hinfo->nid); | 2786 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); |
2843 | return 0; | 2787 | return 0; |
2844 | } | 2788 | } |
2845 | 2789 | ||
@@ -4742,6 +4686,8 @@ static int patch_ca0132(struct hda_codec *codec) | |||
4742 | return err; | 4686 | return err; |
4743 | 4687 | ||
4744 | codec->patch_ops = ca0132_patch_ops; | 4688 | codec->patch_ops = ca0132_patch_ops; |
4689 | codec->pcm_format_first = 1; | ||
4690 | codec->no_sticky_stream = 1; | ||
4745 | 4691 | ||
4746 | return 0; | 4692 | return 0; |
4747 | } | 4693 | } |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a9a83b85517a..ec304f3ae3b4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4308,7 +4308,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4308 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4308 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4309 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4309 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4310 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4310 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4311 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4311 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4312 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4313 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4312 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4314 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4313 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4315 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4314 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4316 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
@@ -4317,6 +4319,54 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4317 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4319 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4318 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4320 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4319 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), | 4321 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), |
4322 | /* ALC282 */ | ||
4323 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4324 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4325 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4326 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4327 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4328 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4329 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4330 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4331 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4332 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4333 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4334 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4335 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4336 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4337 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4338 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4339 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4340 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4341 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4342 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4343 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4344 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4345 | /* ALC290 */ | ||
4346 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4347 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4348 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4349 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4350 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4351 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4352 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4353 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4354 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4355 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4356 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4357 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4358 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4359 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4360 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4361 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4362 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4363 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4364 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4365 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4366 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4367 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4368 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4369 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | ||
4320 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 4370 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
4321 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 4371 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
4322 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4372 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7311badf6a94..3bc29c9b2529 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -83,6 +83,7 @@ enum { | |||
83 | STAC_DELL_M6_BOTH, | 83 | STAC_DELL_M6_BOTH, |
84 | STAC_DELL_EQ, | 84 | STAC_DELL_EQ, |
85 | STAC_ALIENWARE_M17X, | 85 | STAC_ALIENWARE_M17X, |
86 | STAC_92HD89XX_HP_FRONT_JACK, | ||
86 | STAC_92HD73XX_MODELS | 87 | STAC_92HD73XX_MODELS |
87 | }; | 88 | }; |
88 | 89 | ||
@@ -97,6 +98,7 @@ enum { | |||
97 | STAC_92HD83XXX_HP_LED, | 98 | STAC_92HD83XXX_HP_LED, |
98 | STAC_92HD83XXX_HP_INV_LED, | 99 | STAC_92HD83XXX_HP_INV_LED, |
99 | STAC_92HD83XXX_HP_MIC_LED, | 100 | STAC_92HD83XXX_HP_MIC_LED, |
101 | STAC_HP_LED_GPIO10, | ||
100 | STAC_92HD83XXX_HEADSET_JACK, | 102 | STAC_92HD83XXX_HEADSET_JACK, |
101 | STAC_92HD83XXX_HP, | 103 | STAC_92HD83XXX_HP, |
102 | STAC_HP_ENVY_BASS, | 104 | STAC_HP_ENVY_BASS, |
@@ -1795,6 +1797,12 @@ static const struct hda_pintbl intel_dg45id_pin_configs[] = { | |||
1795 | {} | 1797 | {} |
1796 | }; | 1798 | }; |
1797 | 1799 | ||
1800 | static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = { | ||
1801 | { 0x0a, 0x02214030 }, | ||
1802 | { 0x0b, 0x02A19010 }, | ||
1803 | {} | ||
1804 | }; | ||
1805 | |||
1798 | static void stac92hd73xx_fixup_ref(struct hda_codec *codec, | 1806 | static void stac92hd73xx_fixup_ref(struct hda_codec *codec, |
1799 | const struct hda_fixup *fix, int action) | 1807 | const struct hda_fixup *fix, int action) |
1800 | { | 1808 | { |
@@ -1913,6 +1921,10 @@ static const struct hda_fixup stac92hd73xx_fixups[] = { | |||
1913 | [STAC_92HD73XX_NO_JD] = { | 1921 | [STAC_92HD73XX_NO_JD] = { |
1914 | .type = HDA_FIXUP_FUNC, | 1922 | .type = HDA_FIXUP_FUNC, |
1915 | .v.func = stac92hd73xx_fixup_no_jd, | 1923 | .v.func = stac92hd73xx_fixup_no_jd, |
1924 | }, | ||
1925 | [STAC_92HD89XX_HP_FRONT_JACK] = { | ||
1926 | .type = HDA_FIXUP_PINS, | ||
1927 | .v.pins = stac92hd89xx_hp_front_jack_pin_configs, | ||
1916 | } | 1928 | } |
1917 | }; | 1929 | }; |
1918 | 1930 | ||
@@ -1973,6 +1985,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { | |||
1973 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1985 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1974 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, | 1986 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, |
1975 | "Alienware M17x R3", STAC_DELL_EQ), | 1987 | "Alienware M17x R3", STAC_DELL_EQ), |
1988 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, | ||
1989 | "unknown HP", STAC_92HD89XX_HP_FRONT_JACK), | ||
1976 | {} /* terminator */ | 1990 | {} /* terminator */ |
1977 | }; | 1991 | }; |
1978 | 1992 | ||
@@ -2117,6 +2131,17 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec, | |||
2117 | } | 2131 | } |
2118 | } | 2132 | } |
2119 | 2133 | ||
2134 | static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec, | ||
2135 | const struct hda_fixup *fix, int action) | ||
2136 | { | ||
2137 | struct sigmatel_spec *spec = codec->spec; | ||
2138 | |||
2139 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2140 | spec->gpio_led = 0x10; /* GPIO4 */ | ||
2141 | spec->default_polarity = 0; | ||
2142 | } | ||
2143 | } | ||
2144 | |||
2120 | static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, | 2145 | static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, |
2121 | const struct hda_fixup *fix, int action) | 2146 | const struct hda_fixup *fix, int action) |
2122 | { | 2147 | { |
@@ -2611,6 +2636,12 @@ static const struct hda_fixup stac92hd83xxx_fixups[] = { | |||
2611 | .chained = true, | 2636 | .chained = true, |
2612 | .chain_id = STAC_92HD83XXX_HP, | 2637 | .chain_id = STAC_92HD83XXX_HP, |
2613 | }, | 2638 | }, |
2639 | [STAC_HP_LED_GPIO10] = { | ||
2640 | .type = HDA_FIXUP_FUNC, | ||
2641 | .v.func = stac92hd83xxx_fixup_hp_led_gpio10, | ||
2642 | .chained = true, | ||
2643 | .chain_id = STAC_92HD83XXX_HP, | ||
2644 | }, | ||
2614 | [STAC_92HD83XXX_HEADSET_JACK] = { | 2645 | [STAC_92HD83XXX_HEADSET_JACK] = { |
2615 | .type = HDA_FIXUP_FUNC, | 2646 | .type = HDA_FIXUP_FUNC, |
2616 | .v.func = stac92hd83xxx_fixup_headset_jack, | 2647 | .v.func = stac92hd83xxx_fixup_headset_jack, |
@@ -2689,6 +2720,8 @@ static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = { | |||
2689 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 2720 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
2690 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, | 2721 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, |
2691 | "HP Envy Spectre", STAC_HP_ENVY_BASS), | 2722 | "HP Envy Spectre", STAC_HP_ENVY_BASS), |
2723 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899, | ||
2724 | "HP Folio 13", STAC_HP_LED_GPIO10), | ||
2692 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, | 2725 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, |
2693 | "HP Folio", STAC_HP_BNB13_EQ), | 2726 | "HP Folio", STAC_HP_BNB13_EQ), |
2694 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8, | 2727 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8, |
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig index 54f74f8cbb75..4544d8eb1452 100644 --- a/sound/soc/blackfin/Kconfig +++ b/sound/soc/blackfin/Kconfig | |||
@@ -11,7 +11,7 @@ config SND_BF5XX_I2S | |||
11 | 11 | ||
12 | config SND_BF5XX_SOC_SSM2602 | 12 | config SND_BF5XX_SOC_SSM2602 |
13 | tristate "SoC SSM2602 Audio Codec Add-On Card support" | 13 | tristate "SoC SSM2602 Audio Codec Add-On Card support" |
14 | depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) | 14 | depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI |
15 | select SND_BF5XX_SOC_I2S if !BF60x | 15 | select SND_BF5XX_SOC_I2S if !BF60x |
16 | select SND_BF6XX_SOC_I2S if BF60x | 16 | select SND_BF6XX_SOC_I2S if BF60x |
17 | select SND_SOC_SSM2602 | 17 | select SND_SOC_SSM2602 |
@@ -21,10 +21,9 @@ config SND_BF5XX_SOC_SSM2602 | |||
21 | 21 | ||
22 | config SND_SOC_BFIN_EVAL_ADAU1701 | 22 | config SND_SOC_BFIN_EVAL_ADAU1701 |
23 | tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" | 23 | tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" |
24 | depends on SND_BF5XX_I2S | 24 | depends on SND_BF5XX_I2S && I2C |
25 | select SND_BF5XX_SOC_I2S | 25 | select SND_BF5XX_SOC_I2S |
26 | select SND_SOC_ADAU1701 | 26 | select SND_SOC_ADAU1701 |
27 | select I2C | ||
28 | help | 27 | help |
29 | Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ | 28 | Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ |
30 | board connected to one of the Blackfin evaluation boards like the | 29 | board connected to one of the Blackfin evaluation boards like the |
@@ -45,7 +44,7 @@ config SND_SOC_BFIN_EVAL_ADAU1373 | |||
45 | 44 | ||
46 | config SND_SOC_BFIN_EVAL_ADAV80X | 45 | config SND_SOC_BFIN_EVAL_ADAV80X |
47 | tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" | 46 | tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" |
48 | depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) | 47 | depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI |
49 | select SND_BF5XX_SOC_I2S | 48 | select SND_BF5XX_SOC_I2S |
50 | select SND_SOC_ADAV80X | 49 | select SND_SOC_ADAV80X |
51 | help | 50 | help |
@@ -58,7 +57,7 @@ config SND_SOC_BFIN_EVAL_ADAV80X | |||
58 | 57 | ||
59 | config SND_BF5XX_SOC_AD1836 | 58 | config SND_BF5XX_SOC_AD1836 |
60 | tristate "SoC AD1836 Audio support for BF5xx" | 59 | tristate "SoC AD1836 Audio support for BF5xx" |
61 | depends on SND_BF5XX_I2S | 60 | depends on SND_BF5XX_I2S && SPI_MASTER |
62 | select SND_BF5XX_SOC_I2S | 61 | select SND_BF5XX_SOC_I2S |
63 | select SND_SOC_AD1836 | 62 | select SND_SOC_AD1836 |
64 | help | 63 | help |
@@ -66,7 +65,7 @@ config SND_BF5XX_SOC_AD1836 | |||
66 | 65 | ||
67 | config SND_BF5XX_SOC_AD193X | 66 | config SND_BF5XX_SOC_AD193X |
68 | tristate "SoC AD193X Audio support for Blackfin" | 67 | tristate "SoC AD193X Audio support for Blackfin" |
69 | depends on SND_BF5XX_I2S | 68 | depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI |
70 | select SND_BF5XX_SOC_I2S | 69 | select SND_BF5XX_SOC_I2S |
71 | select SND_SOC_AD193X | 70 | select SND_SOC_AD193X |
72 | help | 71 | help |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 7257a8885f42..34d965a4a040 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = { | |||
57 | static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", | 57 | static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", |
58 | "Stereo Mix", "Mono Mix", "Phone"}; | 58 | "Stereo Mix", "Mono Mix", "Phone"}; |
59 | 59 | ||
60 | static const struct soc_enum ad1980_cap_src = | 60 | static SOC_ENUM_DOUBLE_DECL(ad1980_cap_src, |
61 | SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel); | 61 | AC97_REC_SEL, 8, 0, ad1980_rec_sel); |
62 | 62 | ||
63 | static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { | 63 | static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { |
64 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), | 64 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index f295b6569910..f4d965ebc29e 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -1268,11 +1268,23 @@ static struct snd_soc_dai_driver da732x_dai[] = { | |||
1268 | }, | 1268 | }, |
1269 | }; | 1269 | }; |
1270 | 1270 | ||
1271 | static bool da732x_volatile(struct device *dev, unsigned int reg) | ||
1272 | { | ||
1273 | switch (reg) { | ||
1274 | case DA732X_REG_HPL_DAC_OFF_CNTL: | ||
1275 | case DA732X_REG_HPR_DAC_OFF_CNTL: | ||
1276 | return true; | ||
1277 | default: | ||
1278 | return false; | ||
1279 | } | ||
1280 | } | ||
1281 | |||
1271 | static const struct regmap_config da732x_regmap = { | 1282 | static const struct regmap_config da732x_regmap = { |
1272 | .reg_bits = 8, | 1283 | .reg_bits = 8, |
1273 | .val_bits = 8, | 1284 | .val_bits = 8, |
1274 | 1285 | ||
1275 | .max_register = DA732X_MAX_REG, | 1286 | .max_register = DA732X_MAX_REG, |
1287 | .volatile_reg = da732x_volatile, | ||
1276 | .reg_defaults = da732x_reg_cache, | 1288 | .reg_defaults = da732x_reg_cache, |
1277 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), | 1289 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), |
1278 | .cache_type = REGCACHE_RBTREE, | 1290 | .cache_type = REGCACHE_RBTREE, |
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 52b79a487ac7..422812613a28 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -1523,8 +1523,15 @@ static int da9055_remove(struct i2c_client *client) | |||
1523 | return 0; | 1523 | return 0; |
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | /* | ||
1527 | * DO NOT change the device Ids. The naming is intentionally specific as both | ||
1528 | * the CODEC and PMIC parts of this chip are instantiated separately as I2C | ||
1529 | * devices (both have configurable I2C addresses, and are to all intents and | ||
1530 | * purposes separate). As a result there are specific DA9055 Ids for CODEC | ||
1531 | * and PMIC, which must be different to operate together. | ||
1532 | */ | ||
1526 | static const struct i2c_device_id da9055_i2c_id[] = { | 1533 | static const struct i2c_device_id da9055_i2c_id[] = { |
1527 | { "da9055", 0 }, | 1534 | { "da9055-codec", 0 }, |
1528 | { } | 1535 | { } |
1529 | }; | 1536 | }; |
1530 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | 1537 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); |
@@ -1532,7 +1539,7 @@ MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | |||
1532 | /* I2C codec control layer */ | 1539 | /* I2C codec control layer */ |
1533 | static struct i2c_driver da9055_i2c_driver = { | 1540 | static struct i2c_driver da9055_i2c_driver = { |
1534 | .driver = { | 1541 | .driver = { |
1535 | .name = "da9055", | 1542 | .name = "da9055-codec", |
1536 | .owner = THIS_MODULE, | 1543 | .owner = THIS_MODULE, |
1537 | }, | 1544 | }, |
1538 | .probe = da9055_i2c_probe, | 1545 | .probe = da9055_i2c_probe, |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 5839048ec467..cb736ddc446d 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"}; | |||
140 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; | 140 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; |
141 | 141 | ||
142 | static const struct soc_enum isabelle_rx1_enum[] = { | 142 | static const struct soc_enum isabelle_rx1_enum[] = { |
143 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), | 143 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, |
144 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), | 144 | ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts), |
145 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, | ||
146 | ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts), | ||
145 | }; | 147 | }; |
146 | 148 | ||
147 | static const struct soc_enum isabelle_rx2_enum[] = { | 149 | static const struct soc_enum isabelle_rx2_enum[] = { |
148 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), | 150 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, |
149 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), | 151 | ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts), |
152 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, | ||
153 | ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts), | ||
150 | }; | 154 | }; |
151 | 155 | ||
152 | /* Headset DAC playback switches */ | 156 | /* Headset DAC playback switches */ |
@@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"}; | |||
161 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; | 165 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; |
162 | 166 | ||
163 | static const struct soc_enum isabelle_atx_enum[] = { | 167 | static const struct soc_enum isabelle_atx_enum[] = { |
164 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), | 168 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, |
165 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), | 169 | ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts), |
170 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, | ||
171 | ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts), | ||
166 | }; | 172 | }; |
167 | 173 | ||
168 | static const struct soc_enum isabelle_vtx_enum[] = { | 174 | static const struct soc_enum isabelle_vtx_enum[] = { |
169 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), | 175 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, |
170 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), | 176 | ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts), |
177 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, | ||
178 | ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts), | ||
171 | }; | 179 | }; |
172 | 180 | ||
173 | static const struct snd_kcontrol_new atx_mux_controls = | 181 | static const struct snd_kcontrol_new atx_mux_controls = |
@@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = { | |||
183 | /* Left analog microphone selection */ | 191 | /* Left analog microphone selection */ |
184 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; | 192 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; |
185 | 193 | ||
186 | static const struct soc_enum isabelle_amic1_enum[] = { | 194 | static SOC_ENUM_SINGLE_DECL(isabelle_amic1_enum, |
187 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, | 195 | ISABELLE_AMIC_CFG_REG, 5, |
188 | ARRAY_SIZE(isabelle_amic1_texts), | 196 | isabelle_amic1_texts); |
189 | isabelle_amic1_texts), | ||
190 | }; | ||
191 | 197 | ||
192 | static const struct soc_enum isabelle_amic2_enum[] = { | 198 | static SOC_ENUM_SINGLE_DECL(isabelle_amic2_enum, |
193 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, | 199 | ISABELLE_AMIC_CFG_REG, 4, |
194 | ARRAY_SIZE(isabelle_amic2_texts), | 200 | isabelle_amic2_texts); |
195 | isabelle_amic2_texts), | ||
196 | }; | ||
197 | 201 | ||
198 | static const struct snd_kcontrol_new amic1_control = | 202 | static const struct snd_kcontrol_new amic1_control = |
199 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); | 203 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); |
@@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"}; | |||
206 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; | 210 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; |
207 | 211 | ||
208 | static const struct soc_enum isabelle_st_audio_enum[] = { | 212 | static const struct soc_enum isabelle_st_audio_enum[] = { |
209 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, | 213 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, |
214 | ARRAY_SIZE(isabelle_st_audio_texts), | ||
210 | isabelle_st_audio_texts), | 215 | isabelle_st_audio_texts), |
211 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, | 216 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, |
217 | ARRAY_SIZE(isabelle_st_audio_texts), | ||
212 | isabelle_st_audio_texts), | 218 | isabelle_st_audio_texts), |
213 | }; | 219 | }; |
214 | 220 | ||
215 | static const struct soc_enum isabelle_st_voice_enum[] = { | 221 | static const struct soc_enum isabelle_st_voice_enum[] = { |
216 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, | 222 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, |
223 | ARRAY_SIZE(isabelle_st_voice_texts), | ||
217 | isabelle_st_voice_texts), | 224 | isabelle_st_voice_texts), |
218 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, | 225 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, |
226 | ARRAY_SIZE(isabelle_st_voice_texts), | ||
219 | isabelle_st_voice_texts), | 227 | isabelle_st_voice_texts), |
220 | }; | 228 | }; |
221 | 229 | ||
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 51f9b3d16b41..9f714ea86613 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -336,6 +336,7 @@ static bool max98090_readable_register(struct device *dev, unsigned int reg) | |||
336 | case M98090_REG_RECORD_TDM_SLOT: | 336 | case M98090_REG_RECORD_TDM_SLOT: |
337 | case M98090_REG_SAMPLE_RATE: | 337 | case M98090_REG_SAMPLE_RATE: |
338 | case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: | 338 | case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: |
339 | case M98090_REG_REVISION_ID: | ||
339 | return true; | 340 | return true; |
340 | default: | 341 | default: |
341 | return false; | 342 | return false; |
@@ -1769,16 +1770,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1769 | 1770 | ||
1770 | switch (level) { | 1771 | switch (level) { |
1771 | case SND_SOC_BIAS_ON: | 1772 | case SND_SOC_BIAS_ON: |
1772 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1773 | ret = regcache_sync(max98090->regmap); | ||
1774 | |||
1775 | if (ret != 0) { | ||
1776 | dev_err(codec->dev, | ||
1777 | "Failed to sync cache: %d\n", ret); | ||
1778 | return ret; | ||
1779 | } | ||
1780 | } | ||
1781 | |||
1782 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { | 1773 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { |
1783 | /* | 1774 | /* |
1784 | * Set to normal bias level. | 1775 | * Set to normal bias level. |
@@ -1792,6 +1783,16 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1792 | break; | 1783 | break; |
1793 | 1784 | ||
1794 | case SND_SOC_BIAS_STANDBY: | 1785 | case SND_SOC_BIAS_STANDBY: |
1786 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1787 | ret = regcache_sync(max98090->regmap); | ||
1788 | if (ret != 0) { | ||
1789 | dev_err(codec->dev, | ||
1790 | "Failed to sync cache: %d\n", ret); | ||
1791 | return ret; | ||
1792 | } | ||
1793 | } | ||
1794 | break; | ||
1795 | |||
1795 | case SND_SOC_BIAS_OFF: | 1796 | case SND_SOC_BIAS_OFF: |
1796 | /* Set internal pull-up to lowest power mode */ | 1797 | /* Set internal pull-up to lowest power mode */ |
1797 | snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, | 1798 | snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a3fb41179636..886924934aa5 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -2093,6 +2093,7 @@ MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); | |||
2093 | #ifdef CONFIG_ACPI | 2093 | #ifdef CONFIG_ACPI |
2094 | static struct acpi_device_id rt5640_acpi_match[] = { | 2094 | static struct acpi_device_id rt5640_acpi_match[] = { |
2095 | { "INT33CA", 0 }, | 2095 | { "INT33CA", 0 }, |
2096 | { "10EC5640", 0 }, | ||
2096 | { }, | 2097 | { }, |
2097 | }; | 2098 | }; |
2098 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); | 2099 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 06edb396e733..2735361a4c3c 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = { | |||
187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), | 187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static const struct soc_enum sta32x_drc_ac_enum = | 190 | static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, |
191 | SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, | 191 | STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, |
192 | 2, sta32x_drc_ac); | 192 | sta32x_drc_ac); |
193 | static const struct soc_enum sta32x_auto_eq_enum = | 193 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum, |
194 | SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, | 194 | STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, |
195 | 3, sta32x_auto_eq_mode); | 195 | sta32x_auto_eq_mode); |
196 | static const struct soc_enum sta32x_auto_gc_enum = | 196 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum, |
197 | SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, | 197 | STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, |
198 | 4, sta32x_auto_gc_mode); | 198 | sta32x_auto_gc_mode); |
199 | static const struct soc_enum sta32x_auto_xo_enum = | 199 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum, |
200 | SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, | 200 | STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, |
201 | 16, sta32x_auto_xo_mode); | 201 | sta32x_auto_xo_mode); |
202 | static const struct soc_enum sta32x_preset_eq_enum = | 202 | static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum, |
203 | SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, | 203 | STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, |
204 | 32, sta32x_preset_eq_mode); | 204 | sta32x_preset_eq_mode); |
205 | static const struct soc_enum sta32x_limiter_ch1_enum = | 205 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum, |
206 | SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, | 206 | STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, |
207 | 3, sta32x_limiter_select); | 207 | sta32x_limiter_select); |
208 | static const struct soc_enum sta32x_limiter_ch2_enum = | 208 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum, |
209 | SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, | 209 | STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, |
210 | 3, sta32x_limiter_select); | 210 | sta32x_limiter_select); |
211 | static const struct soc_enum sta32x_limiter_ch3_enum = | 211 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum, |
212 | SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, | 212 | STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, |
213 | 3, sta32x_limiter_select); | 213 | sta32x_limiter_select); |
214 | static const struct soc_enum sta32x_limiter1_attack_rate_enum = | 214 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum, |
215 | SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT, | 215 | STA32X_L1AR, STA32X_LxA_SHIFT, |
216 | 16, sta32x_limiter_attack_rate); | 216 | sta32x_limiter_attack_rate); |
217 | static const struct soc_enum sta32x_limiter2_attack_rate_enum = | 217 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum, |
218 | SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT, | 218 | STA32X_L2AR, STA32X_LxA_SHIFT, |
219 | 16, sta32x_limiter_attack_rate); | 219 | sta32x_limiter_attack_rate); |
220 | static const struct soc_enum sta32x_limiter1_release_rate_enum = | 220 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum, |
221 | SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT, | 221 | STA32X_L1AR, STA32X_LxR_SHIFT, |
222 | 16, sta32x_limiter_release_rate); | 222 | sta32x_limiter_release_rate); |
223 | static const struct soc_enum sta32x_limiter2_release_rate_enum = | 223 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum, |
224 | SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT, | 224 | STA32X_L2AR, STA32X_LxR_SHIFT, |
225 | 16, sta32x_limiter_release_rate); | 225 | sta32x_limiter_release_rate); |
226 | 226 | ||
227 | /* byte array controls for setting biquad, mixer, scaling coefficients; | 227 | /* byte array controls for setting biquad, mixer, scaling coefficients; |
228 | * for biquads all five coefficients need to be set in one go, | 228 | * for biquads all five coefficients need to be set in one go, |
@@ -331,7 +331,7 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) | |||
331 | 331 | ||
332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) | 332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) |
333 | { | 333 | { |
334 | struct sta32x_priv *sta32x = codec->control_data; | 334 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
335 | unsigned int mute; | 335 | unsigned int mute; |
336 | int rc; | 336 | int rc; |
337 | 337 | ||
@@ -434,7 +434,7 @@ SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, | |||
434 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), | 434 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), |
435 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), | 435 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), |
436 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), | 436 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), |
437 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), | 437 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter2_release_rate_enum), |
438 | 438 | ||
439 | /* depending on mode, the attack/release thresholds have | 439 | /* depending on mode, the attack/release thresholds have |
440 | * two different enum definitions; provide both | 440 | * two different enum definitions; provide both |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 48dc7d2fee36..6d684d934f4d 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | |||
117 | static const char *wm8400_digital_sidetone[] = | 117 | static const char *wm8400_digital_sidetone[] = |
118 | {"None", "Left ADC", "Right ADC", "Reserved"}; | 118 | {"None", "Left ADC", "Right ADC", "Reserved"}; |
119 | 119 | ||
120 | static const struct soc_enum wm8400_left_digital_sidetone_enum = | 120 | static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum, |
121 | SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, | 121 | WM8400_DIGITAL_SIDE_TONE, |
122 | WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); | 122 | WM8400_ADC_TO_DACL_SHIFT, |
123 | wm8400_digital_sidetone); | ||
123 | 124 | ||
124 | static const struct soc_enum wm8400_right_digital_sidetone_enum = | 125 | static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum, |
125 | SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, | 126 | WM8400_DIGITAL_SIDE_TONE, |
126 | WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); | 127 | WM8400_ADC_TO_DACR_SHIFT, |
128 | wm8400_digital_sidetone); | ||
127 | 129 | ||
128 | static const char *wm8400_adcmode[] = | 130 | static const char *wm8400_adcmode[] = |
129 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; | 131 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; |
130 | 132 | ||
131 | static const struct soc_enum wm8400_right_adcmode_enum = | 133 | static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum, |
132 | SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); | 134 | WM8400_ADC_CTRL, |
135 | WM8400_ADC_HPF_CUT_SHIFT, | ||
136 | wm8400_adcmode); | ||
133 | 137 | ||
134 | static const struct snd_kcontrol_new wm8400_snd_controls[] = { | 138 | static const struct snd_kcontrol_new wm8400_snd_controls[] = { |
135 | /* INMIXL */ | 139 | /* INMIXL */ |
@@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, | |||
422 | static const char *wm8400_ainlmux[] = | 426 | static const char *wm8400_ainlmux[] = |
423 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; | 427 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; |
424 | 428 | ||
425 | static const struct soc_enum wm8400_ainlmux_enum = | 429 | static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum, |
426 | SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, | 430 | WM8400_INPUT_MIXER1, |
427 | ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); | 431 | WM8400_AINLMODE_SHIFT, |
432 | wm8400_ainlmux); | ||
428 | 433 | ||
429 | static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = | 434 | static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = |
430 | SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); | 435 | SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); |
@@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); | |||
435 | static const char *wm8400_ainrmux[] = | 440 | static const char *wm8400_ainrmux[] = |
436 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; | 441 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; |
437 | 442 | ||
438 | static const struct soc_enum wm8400_ainrmux_enum = | 443 | static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum, |
439 | SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, | 444 | WM8400_INPUT_MIXER1, |
440 | ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); | 445 | WM8400_AINRMODE_SHIFT, |
446 | wm8400_ainrmux); | ||
441 | 447 | ||
442 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = | 448 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = |
443 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); | 449 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 89a18d82f303..5bce21013485 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -196,8 +196,8 @@ static const char *ain_text[] = { | |||
196 | "AIN5", "AIN6", "AIN7", "AIN8" | 196 | "AIN5", "AIN6", "AIN7", "AIN8" |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static const struct soc_enum ain_enum = | 199 | static SOC_ENUM_DOUBLE_DECL(ain_enum, |
200 | SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); | 200 | WM8770_ADCMUX, 0, 4, ain_text); |
201 | 201 | ||
202 | static const struct snd_kcontrol_new ain_mux = | 202 | static const struct snd_kcontrol_new ain_mux = |
203 | SOC_DAPM_ENUM("Capture Mux", ain_enum); | 203 | SOC_DAPM_ENUM("Capture Mux", ain_enum); |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index e98bc7038a08..43c2201cb901 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -304,53 +304,53 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1); | |||
304 | 304 | ||
305 | static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; | 305 | static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; |
306 | 306 | ||
307 | static const struct soc_enum mic_bias_level = | 307 | static SOC_ENUM_SINGLE_DECL(mic_bias_level, |
308 | SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt); | 308 | WM8900_REG_INCTL, 8, mic_bias_level_txt); |
309 | 309 | ||
310 | static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; | 310 | static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; |
311 | 311 | ||
312 | static const struct soc_enum dac_mute_rate = | 312 | static SOC_ENUM_SINGLE_DECL(dac_mute_rate, |
313 | SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt); | 313 | WM8900_REG_DACCTRL, 7, dac_mute_rate_txt); |
314 | 314 | ||
315 | static const char *dac_deemphasis_txt[] = { | 315 | static const char *dac_deemphasis_txt[] = { |
316 | "Disabled", "32kHz", "44.1kHz", "48kHz" | 316 | "Disabled", "32kHz", "44.1kHz", "48kHz" |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static const struct soc_enum dac_deemphasis = | 319 | static SOC_ENUM_SINGLE_DECL(dac_deemphasis, |
320 | SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt); | 320 | WM8900_REG_DACCTRL, 4, dac_deemphasis_txt); |
321 | 321 | ||
322 | static const char *adc_hpf_cut_txt[] = { | 322 | static const char *adc_hpf_cut_txt[] = { |
323 | "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" | 323 | "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" |
324 | }; | 324 | }; |
325 | 325 | ||
326 | static const struct soc_enum adc_hpf_cut = | 326 | static SOC_ENUM_SINGLE_DECL(adc_hpf_cut, |
327 | SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt); | 327 | WM8900_REG_ADCCTRL, 5, adc_hpf_cut_txt); |
328 | 328 | ||
329 | static const char *lr_txt[] = { | 329 | static const char *lr_txt[] = { |
330 | "Left", "Right" | 330 | "Left", "Right" |
331 | }; | 331 | }; |
332 | 332 | ||
333 | static const struct soc_enum aifl_src = | 333 | static SOC_ENUM_SINGLE_DECL(aifl_src, |
334 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt); | 334 | WM8900_REG_AUDIO1, 15, lr_txt); |
335 | 335 | ||
336 | static const struct soc_enum aifr_src = | 336 | static SOC_ENUM_SINGLE_DECL(aifr_src, |
337 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt); | 337 | WM8900_REG_AUDIO1, 14, lr_txt); |
338 | 338 | ||
339 | static const struct soc_enum dacl_src = | 339 | static SOC_ENUM_SINGLE_DECL(dacl_src, |
340 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt); | 340 | WM8900_REG_AUDIO2, 15, lr_txt); |
341 | 341 | ||
342 | static const struct soc_enum dacr_src = | 342 | static SOC_ENUM_SINGLE_DECL(dacr_src, |
343 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt); | 343 | WM8900_REG_AUDIO2, 14, lr_txt); |
344 | 344 | ||
345 | static const char *sidetone_txt[] = { | 345 | static const char *sidetone_txt[] = { |
346 | "Disabled", "Left ADC", "Right ADC" | 346 | "Disabled", "Left ADC", "Right ADC" |
347 | }; | 347 | }; |
348 | 348 | ||
349 | static const struct soc_enum dacl_sidetone = | 349 | static SOC_ENUM_SINGLE_DECL(dacl_sidetone, |
350 | SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt); | 350 | WM8900_REG_SIDETONE, 2, sidetone_txt); |
351 | 351 | ||
352 | static const struct soc_enum dacr_sidetone = | 352 | static SOC_ENUM_SINGLE_DECL(dacr_sidetone, |
353 | SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt); | 353 | WM8900_REG_SIDETONE, 0, sidetone_txt); |
354 | 354 | ||
355 | static const struct snd_kcontrol_new wm8900_snd_controls[] = { | 355 | static const struct snd_kcontrol_new wm8900_snd_controls[] = { |
356 | SOC_ENUM("Mic Bias Level", mic_bias_level), | 356 | SOC_ENUM("Mic Bias Level", mic_bias_level), |
@@ -496,8 +496,8 @@ SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), | |||
496 | 496 | ||
497 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; | 497 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; |
498 | 498 | ||
499 | static const struct soc_enum wm8900_lineout2_lp_mux = | 499 | static SOC_ENUM_SINGLE_DECL(wm8900_lineout2_lp_mux, |
500 | SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux); | 500 | WM8900_REG_LOUTMIXCTL1, 1, wm8900_lp_mux); |
501 | 501 | ||
502 | static const struct snd_kcontrol_new wm8900_lineout2_lp = | 502 | static const struct snd_kcontrol_new wm8900_lineout2_lp = |
503 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); | 503 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index b7488f190d2b..d4248e00160e 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -153,7 +153,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
153 | 153 | ||
154 | data32 &= 0xffffff; | 154 | data32 &= 0xffffff; |
155 | 155 | ||
156 | wm8994_bulk_write(codec->control_data, | 156 | wm8994_bulk_write(wm8994->wm8994, |
157 | data32 & 0xffffff, | 157 | data32 & 0xffffff, |
158 | block_len / 2, | 158 | block_len / 2, |
159 | (void *)(data + 8)); | 159 | (void *)(data + 8)); |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 433d59a0f3ef..2ee23a39622c 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1562,7 +1562,6 @@ static int wm8993_remove(struct snd_soc_codec *codec) | |||
1562 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 1562 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1563 | 1563 | ||
1564 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1564 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1565 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1566 | return 0; | 1565 | return 0; |
1567 | } | 1566 | } |
1568 | 1567 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b9be9cbc4603..adb72063d44e 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = { | |||
265 | "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" | 265 | "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" |
266 | }; | 266 | }; |
267 | 267 | ||
268 | static const struct soc_enum sidetone_hpf = | 268 | static SOC_ENUM_SINGLE_DECL(sidetone_hpf, |
269 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); | 269 | WM8994_SIDETONE, 7, sidetone_hpf_text); |
270 | 270 | ||
271 | static const char *adc_hpf_text[] = { | 271 | static const char *adc_hpf_text[] = { |
272 | "HiFi", "Voice 1", "Voice 2", "Voice 3" | 272 | "HiFi", "Voice 1", "Voice 2", "Voice 3" |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static const struct soc_enum aif1adc1_hpf = | 275 | static SOC_ENUM_SINGLE_DECL(aif1adc1_hpf, |
276 | SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text); | 276 | WM8994_AIF1_ADC1_FILTERS, 13, adc_hpf_text); |
277 | 277 | ||
278 | static const struct soc_enum aif1adc2_hpf = | 278 | static SOC_ENUM_SINGLE_DECL(aif1adc2_hpf, |
279 | SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text); | 279 | WM8994_AIF1_ADC2_FILTERS, 13, adc_hpf_text); |
280 | 280 | ||
281 | static const struct soc_enum aif2adc_hpf = | 281 | static SOC_ENUM_SINGLE_DECL(aif2adc_hpf, |
282 | SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text); | 282 | WM8994_AIF2_ADC_FILTERS, 13, adc_hpf_text); |
283 | 283 | ||
284 | static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); | 284 | static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); |
285 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | 285 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); |
@@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = { | |||
501 | "Left", "Right" | 501 | "Left", "Right" |
502 | }; | 502 | }; |
503 | 503 | ||
504 | static const struct soc_enum aif1adcl_src = | 504 | static SOC_ENUM_SINGLE_DECL(aif1adcl_src, |
505 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); | 505 | WM8994_AIF1_CONTROL_1, 15, aif_chan_src_text); |
506 | 506 | ||
507 | static const struct soc_enum aif1adcr_src = | 507 | static SOC_ENUM_SINGLE_DECL(aif1adcr_src, |
508 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); | 508 | WM8994_AIF1_CONTROL_1, 14, aif_chan_src_text); |
509 | 509 | ||
510 | static const struct soc_enum aif2adcl_src = | 510 | static SOC_ENUM_SINGLE_DECL(aif2adcl_src, |
511 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); | 511 | WM8994_AIF2_CONTROL_1, 15, aif_chan_src_text); |
512 | 512 | ||
513 | static const struct soc_enum aif2adcr_src = | 513 | static SOC_ENUM_SINGLE_DECL(aif2adcr_src, |
514 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); | 514 | WM8994_AIF2_CONTROL_1, 14, aif_chan_src_text); |
515 | 515 | ||
516 | static const struct soc_enum aif1dacl_src = | 516 | static SOC_ENUM_SINGLE_DECL(aif1dacl_src, |
517 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); | 517 | WM8994_AIF1_CONTROL_2, 15, aif_chan_src_text); |
518 | 518 | ||
519 | static const struct soc_enum aif1dacr_src = | 519 | static SOC_ENUM_SINGLE_DECL(aif1dacr_src, |
520 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); | 520 | WM8994_AIF1_CONTROL_2, 14, aif_chan_src_text); |
521 | 521 | ||
522 | static const struct soc_enum aif2dacl_src = | 522 | static SOC_ENUM_SINGLE_DECL(aif2dacl_src, |
523 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); | 523 | WM8994_AIF2_CONTROL_2, 15, aif_chan_src_text); |
524 | 524 | ||
525 | static const struct soc_enum aif2dacr_src = | 525 | static SOC_ENUM_SINGLE_DECL(aif2dacr_src, |
526 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); | 526 | WM8994_AIF2_CONTROL_2, 14, aif_chan_src_text); |
527 | 527 | ||
528 | static const char *osr_text[] = { | 528 | static const char *osr_text[] = { |
529 | "Low Power", "High Performance", | 529 | "Low Power", "High Performance", |
530 | }; | 530 | }; |
531 | 531 | ||
532 | static const struct soc_enum dac_osr = | 532 | static SOC_ENUM_SINGLE_DECL(dac_osr, |
533 | SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text); | 533 | WM8994_OVERSAMPLING, 0, osr_text); |
534 | 534 | ||
535 | static const struct soc_enum adc_osr = | 535 | static SOC_ENUM_SINGLE_DECL(adc_osr, |
536 | SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); | 536 | WM8994_OVERSAMPLING, 1, osr_text); |
537 | 537 | ||
538 | static const struct snd_kcontrol_new wm8994_snd_controls[] = { | 538 | static const struct snd_kcontrol_new wm8994_snd_controls[] = { |
539 | SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, | 539 | SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, |
@@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = { | |||
690 | "30ms", "125ms", "250ms", "500ms", | 690 | "30ms", "125ms", "250ms", "500ms", |
691 | }; | 691 | }; |
692 | 692 | ||
693 | static const struct soc_enum wm8958_aif1dac1_ng_hold = | 693 | static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac1_ng_hold, |
694 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE, | 694 | WM8958_AIF1_DAC1_NOISE_GATE, |
695 | WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text); | 695 | WM8958_AIF1DAC1_NG_THR_SHIFT, |
696 | wm8958_ng_text); | ||
696 | 697 | ||
697 | static const struct soc_enum wm8958_aif1dac2_ng_hold = | 698 | static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac2_ng_hold, |
698 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE, | 699 | WM8958_AIF1_DAC2_NOISE_GATE, |
699 | WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text); | 700 | WM8958_AIF1DAC2_NG_THR_SHIFT, |
701 | wm8958_ng_text); | ||
700 | 702 | ||
701 | static const struct soc_enum wm8958_aif2dac_ng_hold = | 703 | static SOC_ENUM_SINGLE_DECL(wm8958_aif2dac_ng_hold, |
702 | SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE, | 704 | WM8958_AIF2_DAC_NOISE_GATE, |
703 | WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text); | 705 | WM8958_AIF2DAC_NG_THR_SHIFT, |
706 | wm8958_ng_text); | ||
704 | 707 | ||
705 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { | 708 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { |
706 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), | 709 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), |
@@ -1341,8 +1344,8 @@ static const char *adc_mux_text[] = { | |||
1341 | "DMIC", | 1344 | "DMIC", |
1342 | }; | 1345 | }; |
1343 | 1346 | ||
1344 | static const struct soc_enum adc_enum = | 1347 | static SOC_ENUM_SINGLE_DECL(adc_enum, |
1345 | SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); | 1348 | 0, 0, adc_mux_text); |
1346 | 1349 | ||
1347 | static const struct snd_kcontrol_new adcl_mux = | 1350 | static const struct snd_kcontrol_new adcl_mux = |
1348 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 1351 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); |
@@ -1478,14 +1481,14 @@ static const char *sidetone_text[] = { | |||
1478 | "ADC/DMIC1", "DMIC2", | 1481 | "ADC/DMIC1", "DMIC2", |
1479 | }; | 1482 | }; |
1480 | 1483 | ||
1481 | static const struct soc_enum sidetone1_enum = | 1484 | static SOC_ENUM_SINGLE_DECL(sidetone1_enum, |
1482 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text); | 1485 | WM8994_SIDETONE, 0, sidetone_text); |
1483 | 1486 | ||
1484 | static const struct snd_kcontrol_new sidetone1_mux = | 1487 | static const struct snd_kcontrol_new sidetone1_mux = |
1485 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); | 1488 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); |
1486 | 1489 | ||
1487 | static const struct soc_enum sidetone2_enum = | 1490 | static SOC_ENUM_SINGLE_DECL(sidetone2_enum, |
1488 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text); | 1491 | WM8994_SIDETONE, 1, sidetone_text); |
1489 | 1492 | ||
1490 | static const struct snd_kcontrol_new sidetone2_mux = | 1493 | static const struct snd_kcontrol_new sidetone2_mux = |
1491 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); | 1494 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); |
@@ -1498,22 +1501,24 @@ static const char *loopback_text[] = { | |||
1498 | "None", "ADCDAT", | 1501 | "None", "ADCDAT", |
1499 | }; | 1502 | }; |
1500 | 1503 | ||
1501 | static const struct soc_enum aif1_loopback_enum = | 1504 | static SOC_ENUM_SINGLE_DECL(aif1_loopback_enum, |
1502 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2, | 1505 | WM8994_AIF1_CONTROL_2, |
1503 | loopback_text); | 1506 | WM8994_AIF1_LOOPBACK_SHIFT, |
1507 | loopback_text); | ||
1504 | 1508 | ||
1505 | static const struct snd_kcontrol_new aif1_loopback = | 1509 | static const struct snd_kcontrol_new aif1_loopback = |
1506 | SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); | 1510 | SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); |
1507 | 1511 | ||
1508 | static const struct soc_enum aif2_loopback_enum = | 1512 | static SOC_ENUM_SINGLE_DECL(aif2_loopback_enum, |
1509 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2, | 1513 | WM8994_AIF2_CONTROL_2, |
1510 | loopback_text); | 1514 | WM8994_AIF2_LOOPBACK_SHIFT, |
1515 | loopback_text); | ||
1511 | 1516 | ||
1512 | static const struct snd_kcontrol_new aif2_loopback = | 1517 | static const struct snd_kcontrol_new aif2_loopback = |
1513 | SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); | 1518 | SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); |
1514 | 1519 | ||
1515 | static const struct soc_enum aif1dac_enum = | 1520 | static SOC_ENUM_SINGLE_DECL(aif1dac_enum, |
1516 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); | 1521 | WM8994_POWER_MANAGEMENT_6, 0, aif1dac_text); |
1517 | 1522 | ||
1518 | static const struct snd_kcontrol_new aif1dac_mux = | 1523 | static const struct snd_kcontrol_new aif1dac_mux = |
1519 | SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); | 1524 | SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); |
@@ -1522,8 +1527,8 @@ static const char *aif2dac_text[] = { | |||
1522 | "AIF2DACDAT", "AIF3DACDAT", | 1527 | "AIF2DACDAT", "AIF3DACDAT", |
1523 | }; | 1528 | }; |
1524 | 1529 | ||
1525 | static const struct soc_enum aif2dac_enum = | 1530 | static SOC_ENUM_SINGLE_DECL(aif2dac_enum, |
1526 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text); | 1531 | WM8994_POWER_MANAGEMENT_6, 1, aif2dac_text); |
1527 | 1532 | ||
1528 | static const struct snd_kcontrol_new aif2dac_mux = | 1533 | static const struct snd_kcontrol_new aif2dac_mux = |
1529 | SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); | 1534 | SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); |
@@ -1532,8 +1537,8 @@ static const char *aif2adc_text[] = { | |||
1532 | "AIF2ADCDAT", "AIF3DACDAT", | 1537 | "AIF2ADCDAT", "AIF3DACDAT", |
1533 | }; | 1538 | }; |
1534 | 1539 | ||
1535 | static const struct soc_enum aif2adc_enum = | 1540 | static SOC_ENUM_SINGLE_DECL(aif2adc_enum, |
1536 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text); | 1541 | WM8994_POWER_MANAGEMENT_6, 2, aif2adc_text); |
1537 | 1542 | ||
1538 | static const struct snd_kcontrol_new aif2adc_mux = | 1543 | static const struct snd_kcontrol_new aif2adc_mux = |
1539 | SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); | 1544 | SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); |
@@ -1542,14 +1547,14 @@ static const char *aif3adc_text[] = { | |||
1542 | "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", | 1547 | "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", |
1543 | }; | 1548 | }; |
1544 | 1549 | ||
1545 | static const struct soc_enum wm8994_aif3adc_enum = | 1550 | static SOC_ENUM_SINGLE_DECL(wm8994_aif3adc_enum, |
1546 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); | 1551 | WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text); |
1547 | 1552 | ||
1548 | static const struct snd_kcontrol_new wm8994_aif3adc_mux = | 1553 | static const struct snd_kcontrol_new wm8994_aif3adc_mux = |
1549 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); | 1554 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); |
1550 | 1555 | ||
1551 | static const struct soc_enum wm8958_aif3adc_enum = | 1556 | static SOC_ENUM_SINGLE_DECL(wm8958_aif3adc_enum, |
1552 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text); | 1557 | WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text); |
1553 | 1558 | ||
1554 | static const struct snd_kcontrol_new wm8958_aif3adc_mux = | 1559 | static const struct snd_kcontrol_new wm8958_aif3adc_mux = |
1555 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); | 1560 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); |
@@ -1558,8 +1563,8 @@ static const char *mono_pcm_out_text[] = { | |||
1558 | "None", "AIF2ADCL", "AIF2ADCR", | 1563 | "None", "AIF2ADCL", "AIF2ADCR", |
1559 | }; | 1564 | }; |
1560 | 1565 | ||
1561 | static const struct soc_enum mono_pcm_out_enum = | 1566 | static SOC_ENUM_SINGLE_DECL(mono_pcm_out_enum, |
1562 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text); | 1567 | WM8994_POWER_MANAGEMENT_6, 9, mono_pcm_out_text); |
1563 | 1568 | ||
1564 | static const struct snd_kcontrol_new mono_pcm_out_mux = | 1569 | static const struct snd_kcontrol_new mono_pcm_out_mux = |
1565 | SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); | 1570 | SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); |
@@ -1569,14 +1574,14 @@ static const char *aif2dac_src_text[] = { | |||
1569 | }; | 1574 | }; |
1570 | 1575 | ||
1571 | /* Note that these two control shouldn't be simultaneously switched to AIF3 */ | 1576 | /* Note that these two control shouldn't be simultaneously switched to AIF3 */ |
1572 | static const struct soc_enum aif2dacl_src_enum = | 1577 | static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum, |
1573 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text); | 1578 | WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text); |
1574 | 1579 | ||
1575 | static const struct snd_kcontrol_new aif2dacl_src_mux = | 1580 | static const struct snd_kcontrol_new aif2dacl_src_mux = |
1576 | SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); | 1581 | SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); |
1577 | 1582 | ||
1578 | static const struct soc_enum aif2dacr_src_enum = | 1583 | static SOC_ENUM_SINGLE_DECL(aif2dacr_src_enum, |
1579 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text); | 1584 | WM8994_POWER_MANAGEMENT_6, 8, aif2dac_src_text); |
1580 | 1585 | ||
1581 | static const struct snd_kcontrol_new aif2dacr_src_mux = | 1586 | static const struct snd_kcontrol_new aif2dacr_src_mux = |
1582 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); | 1587 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 70ff3772079f..5e3bc3c6801a 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -399,6 +399,7 @@ static struct platform_driver davinci_evm_driver = { | |||
399 | .driver = { | 399 | .driver = { |
400 | .name = "davinci_evm", | 400 | .name = "davinci_evm", |
401 | .owner = THIS_MODULE, | 401 | .owner = THIS_MODULE, |
402 | .pm = &snd_soc_pm_ops, | ||
402 | .of_match_table = of_match_ptr(davinci_evm_dt_ids), | 403 | .of_match_table = of_match_ptr(davinci_evm_dt_ids), |
403 | }, | 404 | }, |
404 | }; | 405 | }; |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b7858bfa0295..670afa29e30d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -263,7 +263,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
263 | unsigned int fmt) | 263 | unsigned int fmt) |
264 | { | 264 | { |
265 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 265 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
266 | int ret = 0; | ||
266 | 267 | ||
268 | pm_runtime_get_sync(mcasp->dev); | ||
267 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 269 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
268 | case SND_SOC_DAIFMT_DSP_B: | 270 | case SND_SOC_DAIFMT_DSP_B: |
269 | case SND_SOC_DAIFMT_AC97: | 271 | case SND_SOC_DAIFMT_AC97: |
@@ -317,7 +319,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
317 | break; | 319 | break; |
318 | 320 | ||
319 | default: | 321 | default: |
320 | return -EINVAL; | 322 | ret = -EINVAL; |
323 | goto out; | ||
321 | } | 324 | } |
322 | 325 | ||
323 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 326 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -354,10 +357,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
354 | break; | 357 | break; |
355 | 358 | ||
356 | default: | 359 | default: |
357 | return -EINVAL; | 360 | ret = -EINVAL; |
361 | break; | ||
358 | } | 362 | } |
359 | 363 | out: | |
360 | return 0; | 364 | pm_runtime_put_sync(mcasp->dev); |
365 | return ret; | ||
361 | } | 366 | } |
362 | 367 | ||
363 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | 368 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) |
@@ -448,7 +453,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | |||
448 | return 0; | 453 | return 0; |
449 | } | 454 | } |
450 | 455 | ||
451 | static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | 456 | static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, |
452 | int channels) | 457 | int channels) |
453 | { | 458 | { |
454 | int i; | 459 | int i; |
@@ -524,12 +529,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | |||
524 | return 0; | 529 | return 0; |
525 | } | 530 | } |
526 | 531 | ||
527 | static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | 532 | static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) |
528 | { | 533 | { |
529 | int i, active_slots; | 534 | int i, active_slots; |
530 | u32 mask = 0; | 535 | u32 mask = 0; |
531 | u32 busel = 0; | 536 | u32 busel = 0; |
532 | 537 | ||
538 | if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) { | ||
539 | dev_err(mcasp->dev, "tdm slot %d not supported\n", | ||
540 | mcasp->tdm_slots); | ||
541 | return -EINVAL; | ||
542 | } | ||
543 | |||
533 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; | 544 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; |
534 | for (i = 0; i < active_slots; i++) | 545 | for (i = 0; i < active_slots; i++) |
535 | mask |= (1 << i); | 546 | mask |= (1 << i); |
@@ -539,35 +550,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | |||
539 | if (!mcasp->dat_port) | 550 | if (!mcasp->dat_port) |
540 | busel = TXSEL; | 551 | busel = TXSEL; |
541 | 552 | ||
542 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 553 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); |
543 | /* bit stream is MSB first with no delay */ | 554 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); |
544 | /* DSP_B mode */ | 555 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, |
545 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); | 556 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); |
546 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); | 557 | |
547 | 558 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | |
548 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | 559 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); |
549 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, | 560 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, |
550 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); | 561 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); |
551 | else | 562 | |
552 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 563 | return 0; |
553 | mcasp->tdm_slots); | ||
554 | } else { | ||
555 | /* bit stream is MSB first with no delay */ | ||
556 | /* DSP_B mode */ | ||
557 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); | ||
558 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | ||
559 | |||
560 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | ||
561 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, | ||
562 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); | ||
563 | else | ||
564 | printk(KERN_ERR "capture tdm slot %d not supported\n", | ||
565 | mcasp->tdm_slots); | ||
566 | } | ||
567 | } | 564 | } |
568 | 565 | ||
569 | /* S/PDIF */ | 566 | /* S/PDIF */ |
570 | static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | 567 | static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp) |
571 | { | 568 | { |
572 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 | 569 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 |
573 | and LSB first */ | 570 | and LSB first */ |
@@ -589,6 +586,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | |||
589 | 586 | ||
590 | /* Enable the DIT */ | 587 | /* Enable the DIT */ |
591 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); | 588 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); |
589 | |||
590 | return 0; | ||
592 | } | 591 | } |
593 | 592 | ||
594 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | 593 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, |
@@ -605,13 +604,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
605 | u8 slots = mcasp->tdm_slots; | 604 | u8 slots = mcasp->tdm_slots; |
606 | u8 active_serializers; | 605 | u8 active_serializers; |
607 | int channels; | 606 | int channels; |
607 | int ret; | ||
608 | struct snd_interval *pcm_channels = hw_param_interval(params, | 608 | struct snd_interval *pcm_channels = hw_param_interval(params, |
609 | SNDRV_PCM_HW_PARAM_CHANNELS); | 609 | SNDRV_PCM_HW_PARAM_CHANNELS); |
610 | channels = pcm_channels->min; | 610 | channels = pcm_channels->min; |
611 | 611 | ||
612 | active_serializers = (channels + slots - 1) / slots; | 612 | active_serializers = (channels + slots - 1) / slots; |
613 | 613 | ||
614 | if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) | 614 | if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL) |
615 | return -EINVAL; | 615 | return -EINVAL; |
616 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 616 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
617 | fifo_level = mcasp->txnumevt * active_serializers; | 617 | fifo_level = mcasp->txnumevt * active_serializers; |
@@ -619,9 +619,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
619 | fifo_level = mcasp->rxnumevt * active_serializers; | 619 | fifo_level = mcasp->rxnumevt * active_serializers; |
620 | 620 | ||
621 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) | 621 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
622 | davinci_hw_dit_param(mcasp); | 622 | ret = mcasp_dit_hw_param(mcasp); |
623 | else | 623 | else |
624 | davinci_hw_param(mcasp, substream->stream); | 624 | ret = mcasp_i2s_hw_param(mcasp, substream->stream); |
625 | |||
626 | if (ret) | ||
627 | return ret; | ||
625 | 628 | ||
626 | switch (params_format(params)) { | 629 | switch (params_format(params)) { |
627 | case SNDRV_PCM_FORMAT_U8: | 630 | case SNDRV_PCM_FORMAT_U8: |
@@ -678,19 +681,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
678 | case SNDRV_PCM_TRIGGER_RESUME: | 681 | case SNDRV_PCM_TRIGGER_RESUME: |
679 | case SNDRV_PCM_TRIGGER_START: | 682 | case SNDRV_PCM_TRIGGER_START: |
680 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 683 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
681 | ret = pm_runtime_get_sync(mcasp->dev); | ||
682 | if (IS_ERR_VALUE(ret)) | ||
683 | dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n"); | ||
684 | davinci_mcasp_start(mcasp, substream->stream); | 684 | davinci_mcasp_start(mcasp, substream->stream); |
685 | break; | 685 | break; |
686 | |||
687 | case SNDRV_PCM_TRIGGER_SUSPEND: | 686 | case SNDRV_PCM_TRIGGER_SUSPEND: |
688 | davinci_mcasp_stop(mcasp, substream->stream); | ||
689 | ret = pm_runtime_put_sync(mcasp->dev); | ||
690 | if (IS_ERR_VALUE(ret)) | ||
691 | dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n"); | ||
692 | break; | ||
693 | |||
694 | case SNDRV_PCM_TRIGGER_STOP: | 687 | case SNDRV_PCM_TRIGGER_STOP: |
695 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 688 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
696 | davinci_mcasp_stop(mcasp, substream->stream); | 689 | davinci_mcasp_stop(mcasp, substream->stream); |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index d0c72ed261e7..c84026c99134 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -326,7 +326,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, | 326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, |
327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); | 327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); |
328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, | 328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, |
329 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask)); | 329 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); |
330 | 330 | ||
331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, | 331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
@@ -334,7 +334,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, | 334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, |
335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); | 335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); |
336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, | 336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, |
337 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask)); | 337 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); |
338 | 338 | ||
339 | esai_priv->slot_width = slot_width; | 339 | esai_priv->slot_width = slot_width; |
340 | 340 | ||
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 9c9f957fcae1..75e14033e8d8 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h | |||
@@ -322,7 +322,7 @@ | |||
322 | #define ESAI_xSMB_xS_SHIFT 0 | 322 | #define ESAI_xSMB_xS_SHIFT 0 |
323 | #define ESAI_xSMB_xS_WIDTH 16 | 323 | #define ESAI_xSMB_xS_WIDTH 16 |
324 | #define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) | 324 | #define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) |
325 | #define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK) | 325 | #define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMB_xS_MASK) |
326 | 326 | ||
327 | /* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ | 327 | /* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ |
328 | #define ESAI_PRRC_PDC_SHIFT 0 | 328 | #define ESAI_PRRC_PDC_SHIFT 0 |
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index 79cee782dbbf..a2fd7321b5a9 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c | |||
@@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = { | |||
160 | .driver = { | 160 | .driver = { |
161 | .name = "imx_mc13783", | 161 | .name = "imx_mc13783", |
162 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
163 | .pm = &snd_soc_pm_ops, | ||
164 | }, | 163 | }, |
165 | .probe = imx_mc13783_probe, | 164 | .probe = imx_mc13783_probe, |
166 | .remove = imx_mc13783_remove | 165 | .remove = imx_mc13783_remove |
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index f2beae78969f..1cb22dd034eb 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -33,8 +33,7 @@ struct imx_sgtl5000_data { | |||
33 | 33 | ||
34 | static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) | 34 | static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) |
35 | { | 35 | { |
36 | struct imx_sgtl5000_data *data = container_of(rtd->card, | 36 | struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card); |
37 | struct imx_sgtl5000_data, card); | ||
38 | struct device *dev = rtd->card->dev; | 37 | struct device *dev = rtd->card->dev; |
39 | int ret; | 38 | int ret; |
40 | 39 | ||
@@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) | |||
159 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; | 158 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; |
160 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); | 159 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); |
161 | 160 | ||
161 | platform_set_drvdata(pdev, &data->card); | ||
162 | snd_soc_card_set_drvdata(&data->card, data); | ||
163 | |||
162 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); | 164 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); |
163 | if (ret) { | 165 | if (ret) { |
164 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 166 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
165 | goto fail; | 167 | goto fail; |
166 | } | 168 | } |
167 | 169 | ||
168 | platform_set_drvdata(pdev, data); | ||
169 | of_node_put(ssi_np); | 170 | of_node_put(ssi_np); |
170 | of_node_put(codec_np); | 171 | of_node_put(codec_np); |
171 | 172 | ||
@@ -184,7 +185,8 @@ fail: | |||
184 | 185 | ||
185 | static int imx_sgtl5000_remove(struct platform_device *pdev) | 186 | static int imx_sgtl5000_remove(struct platform_device *pdev) |
186 | { | 187 | { |
187 | struct imx_sgtl5000_data *data = platform_get_drvdata(pdev); | 188 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
189 | struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card); | ||
188 | 190 | ||
189 | clk_put(data->codec_clk); | 191 | clk_put(data->codec_clk); |
190 | 192 | ||
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 3fd76bc391de..3a3d17ce6ba4 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c | |||
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card, | |||
71 | { | 71 | { |
72 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 72 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
73 | struct imx_priv *priv = &card_priv; | 73 | struct imx_priv *priv = &card_priv; |
74 | struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); | 74 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); |
75 | struct device *dev = &priv->pdev->dev; | 75 | struct device *dev = &priv->pdev->dev; |
76 | unsigned int pll_out; | 76 | unsigned int pll_out; |
77 | int ret; | 77 | int ret; |
@@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card) | |||
137 | { | 137 | { |
138 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 138 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
139 | struct imx_priv *priv = &card_priv; | 139 | struct imx_priv *priv = &card_priv; |
140 | struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); | 140 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); |
141 | struct device *dev = &priv->pdev->dev; | 141 | struct device *dev = &priv->pdev->dev; |
142 | int ret; | 142 | int ret; |
143 | 143 | ||
@@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev) | |||
264 | data->card.late_probe = imx_wm8962_late_probe; | 264 | data->card.late_probe = imx_wm8962_late_probe; |
265 | data->card.set_bias_level = imx_wm8962_set_bias_level; | 265 | data->card.set_bias_level = imx_wm8962_set_bias_level; |
266 | 266 | ||
267 | platform_set_drvdata(pdev, &data->card); | ||
268 | snd_soc_card_set_drvdata(&data->card, data); | ||
269 | |||
267 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); | 270 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); |
268 | if (ret) { | 271 | if (ret) { |
269 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 272 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
270 | goto clk_fail; | 273 | goto clk_fail; |
271 | } | 274 | } |
272 | 275 | ||
273 | platform_set_drvdata(pdev, data); | ||
274 | of_node_put(ssi_np); | 276 | of_node_put(ssi_np); |
275 | of_node_put(codec_np); | 277 | of_node_put(codec_np); |
276 | 278 | ||
@@ -289,7 +291,8 @@ fail: | |||
289 | 291 | ||
290 | static int imx_wm8962_remove(struct platform_device *pdev) | 292 | static int imx_wm8962_remove(struct platform_device *pdev) |
291 | { | 293 | { |
292 | struct imx_wm8962_data *data = platform_get_drvdata(pdev); | 294 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
295 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); | ||
293 | 296 | ||
294 | if (!IS_ERR(data->codec_clk)) | 297 | if (!IS_ERR(data->codec_clk)) |
295 | clk_disable_unprepare(data->codec_clk); | 298 | clk_disable_unprepare(data->codec_clk); |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 454f41cfc828..350757400391 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -59,7 +59,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
59 | select SND_SOC_WM8750 | 59 | select SND_SOC_WM8750 |
60 | select SND_S3C2412_SOC_I2S | 60 | select SND_S3C2412_SOC_I2S |
61 | help | 61 | help |
62 | Sat Y if you want to add support for SoC audio on the Jive. | 62 | Say Y if you want to add support for SoC audio on the Jive. |
63 | 63 | ||
64 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 64 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
65 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 65 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
@@ -145,11 +145,11 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380 | |||
145 | 145 | ||
146 | config SND_SOC_SAMSUNG_SMDK_WM9713 | 146 | config SND_SOC_SAMSUNG_SMDK_WM9713 |
147 | tristate "SoC AC97 Audio support for SMDK with WM9713" | 147 | tristate "SoC AC97 Audio support for SMDK with WM9713" |
148 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210) | 148 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) |
149 | select SND_SOC_WM9713 | 149 | select SND_SOC_WM9713 |
150 | select SND_SAMSUNG_AC97 | 150 | select SND_SAMSUNG_AC97 |
151 | help | 151 | help |
152 | Sat Y if you want to add support for SoC audio on the SMDK. | 152 | Say Y if you want to add support for SoC audio on the SMDK. |
153 | 153 | ||
154 | config SND_SOC_SMARTQ | 154 | config SND_SOC_SMARTQ |
155 | tristate "SoC I2S Audio support for SmartQ board" | 155 | tristate "SoC I2S Audio support for SmartQ board" |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index dc8ff13187f7..b9dc6acbba8c 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -1218,7 +1218,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1218 | ret = regulator_allow_bypass(w->regulator, false); | 1218 | ret = regulator_allow_bypass(w->regulator, false); |
1219 | if (ret != 0) | 1219 | if (ret != 0) |
1220 | dev_warn(w->dapm->dev, | 1220 | dev_warn(w->dapm->dev, |
1221 | "ASoC: Failed to bypass %s: %d\n", | 1221 | "ASoC: Failed to unbypass %s: %d\n", |
1222 | w->name, ret); | 1222 | w->name, ret); |
1223 | } | 1223 | } |
1224 | 1224 | ||
@@ -1228,7 +1228,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1228 | ret = regulator_allow_bypass(w->regulator, true); | 1228 | ret = regulator_allow_bypass(w->regulator, true); |
1229 | if (ret != 0) | 1229 | if (ret != 0) |
1230 | dev_warn(w->dapm->dev, | 1230 | dev_warn(w->dapm->dev, |
1231 | "ASoC: Failed to unbypass %s: %d\n", | 1231 | "ASoC: Failed to bypass %s: %d\n", |
1232 | w->name, ret); | 1232 | w->name, ret); |
1233 | } | 1233 | } |
1234 | 1234 | ||
@@ -3210,15 +3210,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, | |||
3210 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); | 3210 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
3211 | const char *pin = (const char *)kcontrol->private_value; | 3211 | const char *pin = (const char *)kcontrol->private_value; |
3212 | 3212 | ||
3213 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3214 | |||
3215 | if (ucontrol->value.integer.value[0]) | 3213 | if (ucontrol->value.integer.value[0]) |
3216 | snd_soc_dapm_enable_pin(&card->dapm, pin); | 3214 | snd_soc_dapm_enable_pin(&card->dapm, pin); |
3217 | else | 3215 | else |
3218 | snd_soc_dapm_disable_pin(&card->dapm, pin); | 3216 | snd_soc_dapm_disable_pin(&card->dapm, pin); |
3219 | 3217 | ||
3220 | mutex_unlock(&card->dapm_mutex); | ||
3221 | |||
3222 | snd_soc_dapm_sync(&card->dapm); | 3218 | snd_soc_dapm_sync(&card->dapm); |
3223 | return 0; | 3219 | return 0; |
3224 | } | 3220 | } |
@@ -3248,7 +3244,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3248 | ret = regulator_allow_bypass(w->regulator, true); | 3244 | ret = regulator_allow_bypass(w->regulator, true); |
3249 | if (ret != 0) | 3245 | if (ret != 0) |
3250 | dev_warn(w->dapm->dev, | 3246 | dev_warn(w->dapm->dev, |
3251 | "ASoC: Failed to unbypass %s: %d\n", | 3247 | "ASoC: Failed to bypass %s: %d\n", |
3252 | w->name, ret); | 3248 | w->name, ret); |
3253 | } | 3249 | } |
3254 | break; | 3250 | break; |
@@ -3767,23 +3763,52 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, | |||
3767 | } | 3763 | } |
3768 | 3764 | ||
3769 | /** | 3765 | /** |
3766 | * snd_soc_dapm_enable_pin_unlocked - enable pin. | ||
3767 | * @dapm: DAPM context | ||
3768 | * @pin: pin name | ||
3769 | * | ||
3770 | * Enables input/output pin and its parents or children widgets iff there is | ||
3771 | * a valid audio route and active audio stream. | ||
3772 | * | ||
3773 | * Requires external locking. | ||
3774 | * | ||
3775 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3776 | * do any widget power switching. | ||
3777 | */ | ||
3778 | int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
3779 | const char *pin) | ||
3780 | { | ||
3781 | return snd_soc_dapm_set_pin(dapm, pin, 1); | ||
3782 | } | ||
3783 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked); | ||
3784 | |||
3785 | /** | ||
3770 | * snd_soc_dapm_enable_pin - enable pin. | 3786 | * snd_soc_dapm_enable_pin - enable pin. |
3771 | * @dapm: DAPM context | 3787 | * @dapm: DAPM context |
3772 | * @pin: pin name | 3788 | * @pin: pin name |
3773 | * | 3789 | * |
3774 | * Enables input/output pin and its parents or children widgets iff there is | 3790 | * Enables input/output pin and its parents or children widgets iff there is |
3775 | * a valid audio route and active audio stream. | 3791 | * a valid audio route and active audio stream. |
3792 | * | ||
3776 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 3793 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
3777 | * do any widget power switching. | 3794 | * do any widget power switching. |
3778 | */ | 3795 | */ |
3779 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) | 3796 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) |
3780 | { | 3797 | { |
3781 | return snd_soc_dapm_set_pin(dapm, pin, 1); | 3798 | int ret; |
3799 | |||
3800 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3801 | |||
3802 | ret = snd_soc_dapm_set_pin(dapm, pin, 1); | ||
3803 | |||
3804 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3805 | |||
3806 | return ret; | ||
3782 | } | 3807 | } |
3783 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); | 3808 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); |
3784 | 3809 | ||
3785 | /** | 3810 | /** |
3786 | * snd_soc_dapm_force_enable_pin - force a pin to be enabled | 3811 | * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled |
3787 | * @dapm: DAPM context | 3812 | * @dapm: DAPM context |
3788 | * @pin: pin name | 3813 | * @pin: pin name |
3789 | * | 3814 | * |
@@ -3791,11 +3816,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); | |||
3791 | * intended for use with microphone bias supplies used in microphone | 3816 | * intended for use with microphone bias supplies used in microphone |
3792 | * jack detection. | 3817 | * jack detection. |
3793 | * | 3818 | * |
3819 | * Requires external locking. | ||
3820 | * | ||
3794 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 3821 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
3795 | * do any widget power switching. | 3822 | * do any widget power switching. |
3796 | */ | 3823 | */ |
3797 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | 3824 | int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, |
3798 | const char *pin) | 3825 | const char *pin) |
3799 | { | 3826 | { |
3800 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); | 3827 | struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
3801 | 3828 | ||
@@ -3811,25 +3838,103 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | |||
3811 | 3838 | ||
3812 | return 0; | 3839 | return 0; |
3813 | } | 3840 | } |
3841 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked); | ||
3842 | |||
3843 | /** | ||
3844 | * snd_soc_dapm_force_enable_pin - force a pin to be enabled | ||
3845 | * @dapm: DAPM context | ||
3846 | * @pin: pin name | ||
3847 | * | ||
3848 | * Enables input/output pin regardless of any other state. This is | ||
3849 | * intended for use with microphone bias supplies used in microphone | ||
3850 | * jack detection. | ||
3851 | * | ||
3852 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3853 | * do any widget power switching. | ||
3854 | */ | ||
3855 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | ||
3856 | const char *pin) | ||
3857 | { | ||
3858 | int ret; | ||
3859 | |||
3860 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3861 | |||
3862 | ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); | ||
3863 | |||
3864 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3865 | |||
3866 | return ret; | ||
3867 | } | ||
3814 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); | 3868 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); |
3815 | 3869 | ||
3816 | /** | 3870 | /** |
3871 | * snd_soc_dapm_disable_pin_unlocked - disable pin. | ||
3872 | * @dapm: DAPM context | ||
3873 | * @pin: pin name | ||
3874 | * | ||
3875 | * Disables input/output pin and its parents or children widgets. | ||
3876 | * | ||
3877 | * Requires external locking. | ||
3878 | * | ||
3879 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3880 | * do any widget power switching. | ||
3881 | */ | ||
3882 | int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
3883 | const char *pin) | ||
3884 | { | ||
3885 | return snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3886 | } | ||
3887 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked); | ||
3888 | |||
3889 | /** | ||
3817 | * snd_soc_dapm_disable_pin - disable pin. | 3890 | * snd_soc_dapm_disable_pin - disable pin. |
3818 | * @dapm: DAPM context | 3891 | * @dapm: DAPM context |
3819 | * @pin: pin name | 3892 | * @pin: pin name |
3820 | * | 3893 | * |
3821 | * Disables input/output pin and its parents or children widgets. | 3894 | * Disables input/output pin and its parents or children widgets. |
3895 | * | ||
3822 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | 3896 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to |
3823 | * do any widget power switching. | 3897 | * do any widget power switching. |
3824 | */ | 3898 | */ |
3825 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, | 3899 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, |
3826 | const char *pin) | 3900 | const char *pin) |
3827 | { | 3901 | { |
3828 | return snd_soc_dapm_set_pin(dapm, pin, 0); | 3902 | int ret; |
3903 | |||
3904 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3905 | |||
3906 | ret = snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3907 | |||
3908 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3909 | |||
3910 | return ret; | ||
3829 | } | 3911 | } |
3830 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); | 3912 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); |
3831 | 3913 | ||
3832 | /** | 3914 | /** |
3915 | * snd_soc_dapm_nc_pin_unlocked - permanently disable pin. | ||
3916 | * @dapm: DAPM context | ||
3917 | * @pin: pin name | ||
3918 | * | ||
3919 | * Marks the specified pin as being not connected, disabling it along | ||
3920 | * any parent or child widgets. At present this is identical to | ||
3921 | * snd_soc_dapm_disable_pin() but in future it will be extended to do | ||
3922 | * additional things such as disabling controls which only affect | ||
3923 | * paths through the pin. | ||
3924 | * | ||
3925 | * Requires external locking. | ||
3926 | * | ||
3927 | * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to | ||
3928 | * do any widget power switching. | ||
3929 | */ | ||
3930 | int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
3931 | const char *pin) | ||
3932 | { | ||
3933 | return snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3934 | } | ||
3935 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked); | ||
3936 | |||
3937 | /** | ||
3833 | * snd_soc_dapm_nc_pin - permanently disable pin. | 3938 | * snd_soc_dapm_nc_pin - permanently disable pin. |
3834 | * @dapm: DAPM context | 3939 | * @dapm: DAPM context |
3835 | * @pin: pin name | 3940 | * @pin: pin name |
@@ -3845,7 +3950,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); | |||
3845 | */ | 3950 | */ |
3846 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) | 3951 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) |
3847 | { | 3952 | { |
3848 | return snd_soc_dapm_set_pin(dapm, pin, 0); | 3953 | int ret; |
3954 | |||
3955 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
3956 | |||
3957 | ret = snd_soc_dapm_set_pin(dapm, pin, 0); | ||
3958 | |||
3959 | mutex_unlock(&dapm->card->dapm_mutex); | ||
3960 | |||
3961 | return ret; | ||
3849 | } | 3962 | } |
3850 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); | 3963 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); |
3851 | 3964 | ||
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index e0305a148568..9edd68db9f48 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c | |||
@@ -183,14 +183,16 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) | |||
183 | irq = platform_get_irq(pdev, 0); | 183 | irq = platform_get_irq(pdev, 0); |
184 | if (irq < 0) | 184 | if (irq < 0) |
185 | return irq; | 185 | return irq; |
186 | |||
187 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
188 | if (!drvdata) | ||
189 | return -ENOMEM; | ||
190 | |||
186 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 191 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
187 | drvdata->base = devm_ioremap_resource(&pdev->dev, r); | 192 | drvdata->base = devm_ioremap_resource(&pdev->dev, r); |
188 | if (IS_ERR(drvdata->base)) | 193 | if (IS_ERR(drvdata->base)) |
189 | return PTR_ERR(drvdata->base); | 194 | return PTR_ERR(drvdata->base); |
190 | 195 | ||
191 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
192 | if (!drvdata) | ||
193 | return -ENOMEM; | ||
194 | platform_set_drvdata(pdev, drvdata); | 196 | platform_set_drvdata(pdev, drvdata); |
195 | drvdata->physbase = r->start; | 197 | drvdata->physbase = r->start; |
196 | if (sizeof(drvdata->physbase) > sizeof(r->start) && | 198 | if (sizeof(drvdata->physbase) > sizeof(r->start) && |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 32af6b741ef5..d1d72ff50347 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -328,6 +328,11 @@ static struct usbmix_name_map gamecom780_map[] = { | |||
328 | {} | 328 | {} |
329 | }; | 329 | }; |
330 | 330 | ||
331 | static const struct usbmix_name_map kef_x300a_map[] = { | ||
332 | { 10, NULL }, /* firmware locks up (?) when we try to access this FU */ | ||
333 | { 0 } | ||
334 | }; | ||
335 | |||
331 | /* | 336 | /* |
332 | * Control map entries | 337 | * Control map entries |
333 | */ | 338 | */ |
@@ -419,6 +424,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
419 | .id = USB_ID(0x200c, 0x1018), | 424 | .id = USB_ID(0x200c, 0x1018), |
420 | .map = ebox44_map, | 425 | .map = ebox44_map, |
421 | }, | 426 | }, |
427 | { | ||
428 | .id = USB_ID(0x27ac, 0x1000), | ||
429 | .map = kef_x300a_map, | ||
430 | }, | ||
422 | { 0 } /* terminator */ | 431 | { 0 } /* terminator */ |
423 | }; | 432 | }; |
424 | 433 | ||
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3c53ec268fbc..02f985f3a396 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -113,14 +113,16 @@ static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_locati | |||
113 | if (!he) | 113 | if (!he) |
114 | return -ENOMEM; | 114 | return -ENOMEM; |
115 | 115 | ||
116 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | 116 | if (ui__has_annotation()) { |
117 | if (err) | 117 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
118 | goto out; | 118 | if (err) |
119 | goto out; | ||
119 | 120 | ||
120 | mx = he->mem_info; | 121 | mx = he->mem_info; |
121 | err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx); | 122 | err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx); |
122 | if (err) | 123 | if (err) |
123 | goto out; | 124 | goto out; |
125 | } | ||
124 | 126 | ||
125 | evsel->hists.stats.total_period += cost; | 127 | evsel->hists.stats.total_period += cost; |
126 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 128 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
@@ -164,14 +166,18 @@ static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_loc | |||
164 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, | 166 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, |
165 | 1, 1, 0); | 167 | 1, 1, 0); |
166 | if (he) { | 168 | if (he) { |
167 | bx = he->branch_info; | 169 | if (ui__has_annotation()) { |
168 | err = addr_map_symbol__inc_samples(&bx->from, evsel->idx); | 170 | bx = he->branch_info; |
169 | if (err) | 171 | err = addr_map_symbol__inc_samples(&bx->from, |
170 | goto out; | 172 | evsel->idx); |
171 | 173 | if (err) | |
172 | err = addr_map_symbol__inc_samples(&bx->to, evsel->idx); | 174 | goto out; |
173 | if (err) | 175 | |
174 | goto out; | 176 | err = addr_map_symbol__inc_samples(&bx->to, |
177 | evsel->idx); | ||
178 | if (err) | ||
179 | goto out; | ||
180 | } | ||
175 | 181 | ||
176 | evsel->hists.stats.total_period += 1; | 182 | evsel->hists.stats.total_period += 1; |
177 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 183 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
@@ -205,7 +211,9 @@ static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evs | |||
205 | if (err) | 211 | if (err) |
206 | goto out; | 212 | goto out; |
207 | 213 | ||
208 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | 214 | if (ui__has_annotation()) |
215 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
216 | |||
209 | evsel->hists.stats.total_period += sample->period; | 217 | evsel->hists.stats.total_period += sample->period; |
210 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 218 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
211 | out: | 219 | out: |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 76cd510d34d0..5f989a7d8bc2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -176,7 +176,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
176 | { | 176 | { |
177 | struct annotation *notes; | 177 | struct annotation *notes; |
178 | struct symbol *sym; | 178 | struct symbol *sym; |
179 | int err; | 179 | int err = 0; |
180 | 180 | ||
181 | if (he == NULL || he->ms.sym == NULL || | 181 | if (he == NULL || he->ms.sym == NULL || |
182 | ((top->sym_filter_entry == NULL || | 182 | ((top->sym_filter_entry == NULL || |
@@ -190,7 +190,9 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
190 | return; | 190 | return; |
191 | 191 | ||
192 | ip = he->ms.map->map_ip(he->ms.map, ip); | 192 | ip = he->ms.map->map_ip(he->ms.map, ip); |
193 | err = hist_entry__inc_addr_samples(he, counter, ip); | 193 | |
194 | if (ui__has_annotation()) | ||
195 | err = hist_entry__inc_addr_samples(he, counter, ip); | ||
194 | 196 | ||
195 | pthread_mutex_unlock(¬es->lock); | 197 | pthread_mutex_unlock(¬es->lock); |
196 | 198 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 896f27047ed6..6aa6fb6f7bd9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -37,6 +37,10 @@ | |||
37 | # define MADV_UNMERGEABLE 13 | 37 | # define MADV_UNMERGEABLE 13 |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifndef EFD_SEMAPHORE | ||
41 | # define EFD_SEMAPHORE 1 | ||
42 | #endif | ||
43 | |||
40 | struct tp_field { | 44 | struct tp_field { |
41 | int offset; | 45 | int offset; |
42 | union { | 46 | union { |
@@ -279,6 +283,11 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, | |||
279 | 283 | ||
280 | #define SCA_STRARRAY syscall_arg__scnprintf_strarray | 284 | #define SCA_STRARRAY syscall_arg__scnprintf_strarray |
281 | 285 | ||
286 | #if defined(__i386__) || defined(__x86_64__) | ||
287 | /* | ||
288 | * FIXME: Make this available to all arches as soon as the ioctl beautifier | ||
289 | * gets rewritten to support all arches. | ||
290 | */ | ||
282 | static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, | 291 | static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, |
283 | struct syscall_arg *arg) | 292 | struct syscall_arg *arg) |
284 | { | 293 | { |
@@ -286,6 +295,7 @@ static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, | |||
286 | } | 295 | } |
287 | 296 | ||
288 | #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray | 297 | #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray |
298 | #endif /* defined(__i386__) || defined(__x86_64__) */ | ||
289 | 299 | ||
290 | static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, | 300 | static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, |
291 | struct syscall_arg *arg); | 301 | struct syscall_arg *arg); |
@@ -839,6 +849,10 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscal | |||
839 | 849 | ||
840 | #define SCA_SIGNUM syscall_arg__scnprintf_signum | 850 | #define SCA_SIGNUM syscall_arg__scnprintf_signum |
841 | 851 | ||
852 | #if defined(__i386__) || defined(__x86_64__) | ||
853 | /* | ||
854 | * FIXME: Make this available to all arches. | ||
855 | */ | ||
842 | #define TCGETS 0x5401 | 856 | #define TCGETS 0x5401 |
843 | 857 | ||
844 | static const char *tioctls[] = { | 858 | static const char *tioctls[] = { |
@@ -860,6 +874,7 @@ static const char *tioctls[] = { | |||
860 | }; | 874 | }; |
861 | 875 | ||
862 | static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); | 876 | static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); |
877 | #endif /* defined(__i386__) || defined(__x86_64__) */ | ||
863 | 878 | ||
864 | #define STRARRAY(arg, name, array) \ | 879 | #define STRARRAY(arg, name, array) \ |
865 | .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ | 880 | .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ |
@@ -941,9 +956,16 @@ static struct syscall_fmt { | |||
941 | { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, | 956 | { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, |
942 | { .name = "ioctl", .errmsg = true, | 957 | { .name = "ioctl", .errmsg = true, |
943 | .arg_scnprintf = { [0] = SCA_FD, /* fd */ | 958 | .arg_scnprintf = { [0] = SCA_FD, /* fd */ |
959 | #if defined(__i386__) || defined(__x86_64__) | ||
960 | /* | ||
961 | * FIXME: Make this available to all arches. | ||
962 | */ | ||
944 | [1] = SCA_STRHEXARRAY, /* cmd */ | 963 | [1] = SCA_STRHEXARRAY, /* cmd */ |
945 | [2] = SCA_HEX, /* arg */ }, | 964 | [2] = SCA_HEX, /* arg */ }, |
946 | .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, | 965 | .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, |
966 | #else | ||
967 | [2] = SCA_HEX, /* arg */ }, }, | ||
968 | #endif | ||
947 | { .name = "kill", .errmsg = true, | 969 | { .name = "kill", .errmsg = true, |
948 | .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, | 970 | .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, |
949 | { .name = "linkat", .errmsg = true, | 971 | { .name = "linkat", .errmsg = true, |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index c48d44958172..0331ea2701a3 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -478,7 +478,7 @@ else | |||
478 | endif | 478 | endif |
479 | 479 | ||
480 | ifeq ($(feature-libbfd), 1) | 480 | ifeq ($(feature-libbfd), 1) |
481 | EXTLIBS += -lbfd | 481 | EXTLIBS += -lbfd -lz -liberty |
482 | endif | 482 | endif |
483 | 483 | ||
484 | ifdef NO_DEMANGLE | 484 | ifdef NO_DEMANGLE |
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 12e551346fa6..523b7bc10553 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile | |||
@@ -121,7 +121,7 @@ test-libpython-version.bin: | |||
121 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 121 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
122 | 122 | ||
123 | test-libbfd.bin: | 123 | test-libbfd.bin: |
124 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl | 124 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl |
125 | 125 | ||
126 | test-liberty.bin: | 126 | test-liberty.bin: |
127 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty | 127 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 469eb679fb9d..3aa555ff9d89 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -8,6 +8,8 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "util.h" | 10 | #include "util.h" |
11 | #include "ui/ui.h" | ||
12 | #include "sort.h" | ||
11 | #include "build-id.h" | 13 | #include "build-id.h" |
12 | #include "color.h" | 14 | #include "color.h" |
13 | #include "cache.h" | 15 | #include "cache.h" |
@@ -489,7 +491,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
489 | { | 491 | { |
490 | struct annotation *notes; | 492 | struct annotation *notes; |
491 | 493 | ||
492 | if (sym == NULL || use_browser != 1 || !sort__has_sym) | 494 | if (sym == NULL) |
493 | return 0; | 495 | return 0; |
494 | 496 | ||
495 | notes = symbol__annotation(sym); | 497 | notes = symbol__annotation(sym); |
@@ -1399,3 +1401,8 @@ int hist_entry__annotate(struct hist_entry *he, size_t privsize) | |||
1399 | { | 1401 | { |
1400 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | 1402 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); |
1401 | } | 1403 | } |
1404 | |||
1405 | bool ui__has_annotation(void) | ||
1406 | { | ||
1407 | return use_browser == 1 && sort__has_sym; | ||
1408 | } | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index b2aef59d6bb2..56ad4f5287de 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -151,6 +151,8 @@ void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); | |||
151 | void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); | 151 | void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); |
152 | void disasm__purge(struct list_head *head); | 152 | void disasm__purge(struct list_head *head); |
153 | 153 | ||
154 | bool ui__has_annotation(void); | ||
155 | |||
154 | int symbol__tty_annotate(struct symbol *sym, struct map *map, | 156 | int symbol__tty_annotate(struct symbol *sym, struct map *map, |
155 | struct perf_evsel *evsel, bool print_lines, | 157 | struct perf_evsel *evsel, bool print_lines, |
156 | bool full_paths, int min_pcnt, int max_lines); | 158 | bool full_paths, int min_pcnt, int max_lines); |
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index 45cf10a562bd..dadfa7e54287 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h | |||
@@ -87,13 +87,15 @@ static __always_inline unsigned long __ffs(unsigned long word) | |||
87 | return num; | 87 | return num; |
88 | } | 88 | } |
89 | 89 | ||
90 | typedef const unsigned long __attribute__((__may_alias__)) long_alias_t; | ||
91 | |||
90 | /* | 92 | /* |
91 | * Find the first set bit in a memory region. | 93 | * Find the first set bit in a memory region. |
92 | */ | 94 | */ |
93 | static inline unsigned long | 95 | static inline unsigned long |
94 | find_first_bit(const unsigned long *addr, unsigned long size) | 96 | find_first_bit(const unsigned long *addr, unsigned long size) |
95 | { | 97 | { |
96 | const unsigned long *p = addr; | 98 | long_alias_t *p = (long_alias_t *) addr; |
97 | unsigned long result = 0; | 99 | unsigned long result = 0; |
98 | unsigned long tmp; | 100 | unsigned long tmp; |
99 | 101 | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d248fca6d7ed..1e15df10a88c 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1091,12 +1091,12 @@ int is_valid_tracepoint(const char *event_string) | |||
1091 | static bool is_event_supported(u8 type, unsigned config) | 1091 | static bool is_event_supported(u8 type, unsigned config) |
1092 | { | 1092 | { |
1093 | bool ret = true; | 1093 | bool ret = true; |
1094 | int open_return; | ||
1094 | struct perf_evsel *evsel; | 1095 | struct perf_evsel *evsel; |
1095 | struct perf_event_attr attr = { | 1096 | struct perf_event_attr attr = { |
1096 | .type = type, | 1097 | .type = type, |
1097 | .config = config, | 1098 | .config = config, |
1098 | .disabled = 1, | 1099 | .disabled = 1, |
1099 | .exclude_kernel = 1, | ||
1100 | }; | 1100 | }; |
1101 | struct { | 1101 | struct { |
1102 | struct thread_map map; | 1102 | struct thread_map map; |
@@ -1108,7 +1108,20 @@ static bool is_event_supported(u8 type, unsigned config) | |||
1108 | 1108 | ||
1109 | evsel = perf_evsel__new(&attr); | 1109 | evsel = perf_evsel__new(&attr); |
1110 | if (evsel) { | 1110 | if (evsel) { |
1111 | ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; | 1111 | open_return = perf_evsel__open(evsel, NULL, &tmap.map); |
1112 | ret = open_return >= 0; | ||
1113 | |||
1114 | if (open_return == -EACCES) { | ||
1115 | /* | ||
1116 | * This happens if the paranoid value | ||
1117 | * /proc/sys/kernel/perf_event_paranoid is set to 2 | ||
1118 | * Re-run with exclude_kernel set; we don't do that | ||
1119 | * by default as some ARM machines do not support it. | ||
1120 | * | ||
1121 | */ | ||
1122 | evsel->attr.exclude_kernel = 1; | ||
1123 | ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; | ||
1124 | } | ||
1112 | perf_evsel__delete(evsel); | 1125 | perf_evsel__delete(evsel); |
1113 | } | 1126 | } |
1114 | 1127 | ||
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a8a9b6cd93a8..d8b048c20cde 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -336,8 +336,8 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, | |||
336 | return ret; | 336 | return ret; |
337 | 337 | ||
338 | for (i = 0; i < ntevs && ret >= 0; i++) { | 338 | for (i = 0; i < ntevs && ret >= 0; i++) { |
339 | /* point.address is the addres of point.symbol + point.offset */ | ||
339 | offset = tevs[i].point.address - stext; | 340 | offset = tevs[i].point.address - stext; |
340 | offset += tevs[i].point.offset; | ||
341 | tevs[i].point.offset = 0; | 341 | tevs[i].point.offset = 0; |
342 | zfree(&tevs[i].point.symbol); | 342 | zfree(&tevs[i].point.symbol); |
343 | ret = e_snprintf(buf, 32, "0x%lx", offset); | 343 | ret = e_snprintf(buf, 32, "0x%lx", offset); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0b39a48e5110..5da6ce74c676 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1008,6 +1008,12 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
1008 | if (err == 0) | 1008 | if (err == 0) |
1009 | perf_session__set_id_hdr_size(session); | 1009 | perf_session__set_id_hdr_size(session); |
1010 | return err; | 1010 | return err; |
1011 | case PERF_RECORD_HEADER_EVENT_TYPE: | ||
1012 | /* | ||
1013 | * Depreceated, but we need to handle it for sake | ||
1014 | * of old data files create in pipe mode. | ||
1015 | */ | ||
1016 | return 0; | ||
1011 | case PERF_RECORD_HEADER_TRACING_DATA: | 1017 | case PERF_RECORD_HEADER_TRACING_DATA: |
1012 | /* setup for reading amidst mmap */ | 1018 | /* setup for reading amidst mmap */ |
1013 | lseek(fd, file_offset, SEEK_SET); | 1019 | lseek(fd, file_offset, SEEK_SET); |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a9d758a3b371..e89afc097d8a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1336,6 +1336,8 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | |||
1336 | 1336 | ||
1337 | if (syms_ss && runtime_ss) | 1337 | if (syms_ss && runtime_ss) |
1338 | break; | 1338 | break; |
1339 | } else { | ||
1340 | symsrc__destroy(ss); | ||
1339 | } | 1341 | } |
1340 | 1342 | ||
1341 | } | 1343 | } |