mirror of
https://github.com/Fishwaldo/build.git
synced 2025-05-30 19:01:48 +00:00
15435 lines
511 KiB
Diff
15435 lines
511 KiB
Diff
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
|
|
index 48b424de85bb..cfbc18f0d9c9 100644
|
|
--- a/Documentation/filesystems/fscrypt.rst
|
|
+++ b/Documentation/filesystems/fscrypt.rst
|
|
@@ -191,21 +191,11 @@ Currently, the following pairs of encryption modes are supported:
|
|
|
|
- AES-256-XTS for contents and AES-256-CTS-CBC for filenames
|
|
- AES-128-CBC for contents and AES-128-CTS-CBC for filenames
|
|
-- Speck128/256-XTS for contents and Speck128/256-CTS-CBC for filenames
|
|
|
|
It is strongly recommended to use AES-256-XTS for contents encryption.
|
|
AES-128-CBC was added only for low-powered embedded devices with
|
|
crypto accelerators such as CAAM or CESA that do not support XTS.
|
|
|
|
-Similarly, Speck128/256 support was only added for older or low-end
|
|
-CPUs which cannot do AES fast enough -- especially ARM CPUs which have
|
|
-NEON instructions but not the Cryptography Extensions -- and for which
|
|
-it would not otherwise be feasible to use encryption at all. It is
|
|
-not recommended to use Speck on CPUs that have AES instructions.
|
|
-Speck support is only available if it has been enabled in the crypto
|
|
-API via CONFIG_CRYPTO_SPECK. Also, on ARM platforms, to get
|
|
-acceptable performance CONFIG_CRYPTO_SPECK_NEON must be enabled.
|
|
-
|
|
New encryption modes can be added relatively easily, without changes
|
|
to individual filesystems. However, authenticated encryption (AE)
|
|
modes are not currently supported because of the difficulty of dealing
|
|
diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst
|
|
index e964074cd15b..b25e48afaa08 100644
|
|
--- a/Documentation/media/uapi/cec/cec-ioc-receive.rst
|
|
+++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst
|
|
@@ -16,10 +16,10 @@ CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message
|
|
Synopsis
|
|
========
|
|
|
|
-.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg *argp )
|
|
+.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg \*argp )
|
|
:name: CEC_RECEIVE
|
|
|
|
-.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg *argp )
|
|
+.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg \*argp )
|
|
:name: CEC_TRANSMIT
|
|
|
|
Arguments
|
|
@@ -272,6 +272,19 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
|
|
- The transmit failed after one or more retries. This status bit is
|
|
mutually exclusive with :ref:`CEC_TX_STATUS_OK <CEC-TX-STATUS-OK>`.
|
|
Other bits can still be set to explain which failures were seen.
|
|
+ * .. _`CEC-TX-STATUS-ABORTED`:
|
|
+
|
|
+ - ``CEC_TX_STATUS_ABORTED``
|
|
+ - 0x40
|
|
+ - The transmit was aborted due to an HDMI disconnect, or the adapter
|
|
+ was unconfigured, or a transmit was interrupted, or the driver
|
|
+ returned an error when attempting to start a transmit.
|
|
+ * .. _`CEC-TX-STATUS-TIMEOUT`:
|
|
+
|
|
+ - ``CEC_TX_STATUS_TIMEOUT``
|
|
+ - 0x80
|
|
+ - The transmit timed out. This should not normally happen and this
|
|
+ indicates a driver problem.
|
|
|
|
|
|
.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
|
|
@@ -300,6 +313,14 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
|
|
- The message was received successfully but the reply was
|
|
``CEC_MSG_FEATURE_ABORT``. This status is only set if this message
|
|
was the reply to an earlier transmitted message.
|
|
+ * .. _`CEC-RX-STATUS-ABORTED`:
|
|
+
|
|
+ - ``CEC_RX_STATUS_ABORTED``
|
|
+ - 0x08
|
|
+ - The wait for a reply to an earlier transmitted message was aborted
|
|
+ because the HDMI cable was disconnected, the adapter was unconfigured
|
|
+ or the :ref:`CEC_TRANSMIT <CEC_RECEIVE>` that waited for a
|
|
+ reply was interrupted.
|
|
|
|
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
|
|
index 1cedcfc04327..386d6cf83e9c 100644
|
|
--- a/Documentation/media/uapi/v4l/biblio.rst
|
|
+++ b/Documentation/media/uapi/v4l/biblio.rst
|
|
@@ -226,16 +226,6 @@ xvYCC
|
|
|
|
:author: International Electrotechnical Commission (http://www.iec.ch)
|
|
|
|
-.. _adobergb:
|
|
-
|
|
-AdobeRGB
|
|
-========
|
|
-
|
|
-
|
|
-:title: Adobe© RGB (1998) Color Image Encoding Version 2005-05
|
|
-
|
|
-:author: Adobe Systems Incorporated (http://www.adobe.com)
|
|
-
|
|
.. _oprgb:
|
|
|
|
opRGB
|
|
diff --git a/Documentation/media/uapi/v4l/colorspaces-defs.rst b/Documentation/media/uapi/v4l/colorspaces-defs.rst
|
|
index 410907fe9415..f24615544792 100644
|
|
--- a/Documentation/media/uapi/v4l/colorspaces-defs.rst
|
|
+++ b/Documentation/media/uapi/v4l/colorspaces-defs.rst
|
|
@@ -51,8 +51,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum
|
|
- See :ref:`col-rec709`.
|
|
* - ``V4L2_COLORSPACE_SRGB``
|
|
- See :ref:`col-srgb`.
|
|
- * - ``V4L2_COLORSPACE_ADOBERGB``
|
|
- - See :ref:`col-adobergb`.
|
|
+ * - ``V4L2_COLORSPACE_OPRGB``
|
|
+ - See :ref:`col-oprgb`.
|
|
* - ``V4L2_COLORSPACE_BT2020``
|
|
- See :ref:`col-bt2020`.
|
|
* - ``V4L2_COLORSPACE_DCI_P3``
|
|
@@ -90,8 +90,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum
|
|
- Use the Rec. 709 transfer function.
|
|
* - ``V4L2_XFER_FUNC_SRGB``
|
|
- Use the sRGB transfer function.
|
|
- * - ``V4L2_XFER_FUNC_ADOBERGB``
|
|
- - Use the AdobeRGB transfer function.
|
|
+ * - ``V4L2_XFER_FUNC_OPRGB``
|
|
+ - Use the opRGB transfer function.
|
|
* - ``V4L2_XFER_FUNC_SMPTE240M``
|
|
- Use the SMPTE 240M transfer function.
|
|
* - ``V4L2_XFER_FUNC_NONE``
|
|
diff --git a/Documentation/media/uapi/v4l/colorspaces-details.rst b/Documentation/media/uapi/v4l/colorspaces-details.rst
|
|
index b5d551b9cc8f..09fabf4cd412 100644
|
|
--- a/Documentation/media/uapi/v4l/colorspaces-details.rst
|
|
+++ b/Documentation/media/uapi/v4l/colorspaces-details.rst
|
|
@@ -290,15 +290,14 @@ Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
|
|
170M/BT.601. The Y'CbCr quantization is limited range.
|
|
|
|
|
|
-.. _col-adobergb:
|
|
+.. _col-oprgb:
|
|
|
|
-Colorspace Adobe RGB (V4L2_COLORSPACE_ADOBERGB)
|
|
+Colorspace opRGB (V4L2_COLORSPACE_OPRGB)
|
|
===============================================
|
|
|
|
-The :ref:`adobergb` standard defines the colorspace used by computer
|
|
-graphics that use the AdobeRGB colorspace. This is also known as the
|
|
-:ref:`oprgb` standard. The default transfer function is
|
|
-``V4L2_XFER_FUNC_ADOBERGB``. The default Y'CbCr encoding is
|
|
+The :ref:`oprgb` standard defines the colorspace used by computer
|
|
+graphics that use the opRGB colorspace. The default transfer function is
|
|
+``V4L2_XFER_FUNC_OPRGB``. The default Y'CbCr encoding is
|
|
``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
|
|
range.
|
|
|
|
@@ -312,7 +311,7 @@ The chromaticities of the primary colors and the white reference are:
|
|
|
|
.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
|
|
|
|
-.. flat-table:: Adobe RGB Chromaticities
|
|
+.. flat-table:: opRGB Chromaticities
|
|
:header-rows: 1
|
|
:stub-columns: 0
|
|
:widths: 1 1 2
|
|
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
|
|
index ca9f0edc579e..e420a39f1ebf 100644
|
|
--- a/Documentation/media/videodev2.h.rst.exceptions
|
|
+++ b/Documentation/media/videodev2.h.rst.exceptions
|
|
@@ -56,7 +56,8 @@ replace symbol V4L2_MEMORY_USERPTR :c:type:`v4l2_memory`
|
|
# Documented enum v4l2_colorspace
|
|
replace symbol V4L2_COLORSPACE_470_SYSTEM_BG :c:type:`v4l2_colorspace`
|
|
replace symbol V4L2_COLORSPACE_470_SYSTEM_M :c:type:`v4l2_colorspace`
|
|
-replace symbol V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace`
|
|
+replace symbol V4L2_COLORSPACE_OPRGB :c:type:`v4l2_colorspace`
|
|
+replace define V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace`
|
|
replace symbol V4L2_COLORSPACE_BT2020 :c:type:`v4l2_colorspace`
|
|
replace symbol V4L2_COLORSPACE_DCI_P3 :c:type:`v4l2_colorspace`
|
|
replace symbol V4L2_COLORSPACE_DEFAULT :c:type:`v4l2_colorspace`
|
|
@@ -69,7 +70,8 @@ replace symbol V4L2_COLORSPACE_SRGB :c:type:`v4l2_colorspace`
|
|
|
|
# Documented enum v4l2_xfer_func
|
|
replace symbol V4L2_XFER_FUNC_709 :c:type:`v4l2_xfer_func`
|
|
-replace symbol V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func`
|
|
+replace symbol V4L2_XFER_FUNC_OPRGB :c:type:`v4l2_xfer_func`
|
|
+replace define V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func`
|
|
replace symbol V4L2_XFER_FUNC_DCI_P3 :c:type:`v4l2_xfer_func`
|
|
replace symbol V4L2_XFER_FUNC_DEFAULT :c:type:`v4l2_xfer_func`
|
|
replace symbol V4L2_XFER_FUNC_NONE :c:type:`v4l2_xfer_func`
|
|
diff --git a/Makefile b/Makefile
|
|
index abcd8ca4966f..c8fe567f18ab 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
VERSION = 4
|
|
PATCHLEVEL = 19
|
|
-SUBLEVEL = 1
|
|
+SUBLEVEL = 2
|
|
EXTRAVERSION =
|
|
NAME = "People's Front"
|
|
|
|
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
|
|
index a0ddf497e8cd..2cb45ddd2ae3 100644
|
|
--- a/arch/arm/boot/dts/dra7.dtsi
|
|
+++ b/arch/arm/boot/dts/dra7.dtsi
|
|
@@ -354,7 +354,7 @@
|
|
ti,hwmods = "pcie1";
|
|
phys = <&pcie1_phy>;
|
|
phy-names = "pcie-phy0";
|
|
- ti,syscon-unaligned-access = <&scm_conf1 0x14 2>;
|
|
+ ti,syscon-unaligned-access = <&scm_conf1 0x14 1>;
|
|
status = "disabled";
|
|
};
|
|
};
|
|
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
|
|
index 2ab99f9f3d0a..dd9ec05eb0f7 100644
|
|
--- a/arch/arm/boot/dts/exynos4210-origen.dts
|
|
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
|
|
@@ -151,6 +151,8 @@
|
|
reg = <0x66>;
|
|
interrupt-parent = <&gpx0>;
|
|
interrupts = <4 IRQ_TYPE_NONE>, <3 IRQ_TYPE_NONE>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&max8997_irq>;
|
|
|
|
max8997,pmic-buck1-dvs-voltage = <1350000>;
|
|
max8997,pmic-buck2-dvs-voltage = <1100000>;
|
|
@@ -288,6 +290,13 @@
|
|
};
|
|
};
|
|
|
|
+&pinctrl_1 {
|
|
+ max8997_irq: max8997-irq {
|
|
+ samsung,pins = "gpx0-3", "gpx0-4";
|
|
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
|
|
+ };
|
|
+};
|
|
+
|
|
&sdhci_0 {
|
|
bus-width = <4>;
|
|
pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_cd>;
|
|
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
|
|
index da163a40af15..b85527faa6ea 100644
|
|
--- a/arch/arm/boot/dts/exynos5250.dtsi
|
|
+++ b/arch/arm/boot/dts/exynos5250.dtsi
|
|
@@ -54,62 +54,109 @@
|
|
device_type = "cpu";
|
|
compatible = "arm,cortex-a15";
|
|
reg = <0>;
|
|
- clock-frequency = <1700000000>;
|
|
clocks = <&clock CLK_ARM_CLK>;
|
|
clock-names = "cpu";
|
|
- clock-latency = <140000>;
|
|
-
|
|
- operating-points = <
|
|
- 1700000 1300000
|
|
- 1600000 1250000
|
|
- 1500000 1225000
|
|
- 1400000 1200000
|
|
- 1300000 1150000
|
|
- 1200000 1125000
|
|
- 1100000 1100000
|
|
- 1000000 1075000
|
|
- 900000 1050000
|
|
- 800000 1025000
|
|
- 700000 1012500
|
|
- 600000 1000000
|
|
- 500000 975000
|
|
- 400000 950000
|
|
- 300000 937500
|
|
- 200000 925000
|
|
- >;
|
|
+ operating-points-v2 = <&cpu0_opp_table>;
|
|
#cooling-cells = <2>; /* min followed by max */
|
|
};
|
|
cpu@1 {
|
|
device_type = "cpu";
|
|
compatible = "arm,cortex-a15";
|
|
reg = <1>;
|
|
- clock-frequency = <1700000000>;
|
|
clocks = <&clock CLK_ARM_CLK>;
|
|
clock-names = "cpu";
|
|
- clock-latency = <140000>;
|
|
-
|
|
- operating-points = <
|
|
- 1700000 1300000
|
|
- 1600000 1250000
|
|
- 1500000 1225000
|
|
- 1400000 1200000
|
|
- 1300000 1150000
|
|
- 1200000 1125000
|
|
- 1100000 1100000
|
|
- 1000000 1075000
|
|
- 900000 1050000
|
|
- 800000 1025000
|
|
- 700000 1012500
|
|
- 600000 1000000
|
|
- 500000 975000
|
|
- 400000 950000
|
|
- 300000 937500
|
|
- 200000 925000
|
|
- >;
|
|
+ operating-points-v2 = <&cpu0_opp_table>;
|
|
#cooling-cells = <2>; /* min followed by max */
|
|
};
|
|
};
|
|
|
|
+ cpu0_opp_table: opp_table0 {
|
|
+ compatible = "operating-points-v2";
|
|
+ opp-shared;
|
|
+
|
|
+ opp-200000000 {
|
|
+ opp-hz = /bits/ 64 <200000000>;
|
|
+ opp-microvolt = <925000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-300000000 {
|
|
+ opp-hz = /bits/ 64 <300000000>;
|
|
+ opp-microvolt = <937500>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-400000000 {
|
|
+ opp-hz = /bits/ 64 <400000000>;
|
|
+ opp-microvolt = <950000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-500000000 {
|
|
+ opp-hz = /bits/ 64 <500000000>;
|
|
+ opp-microvolt = <975000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-600000000 {
|
|
+ opp-hz = /bits/ 64 <600000000>;
|
|
+ opp-microvolt = <1000000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-700000000 {
|
|
+ opp-hz = /bits/ 64 <700000000>;
|
|
+ opp-microvolt = <1012500>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-800000000 {
|
|
+ opp-hz = /bits/ 64 <800000000>;
|
|
+ opp-microvolt = <1025000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-900000000 {
|
|
+ opp-hz = /bits/ 64 <900000000>;
|
|
+ opp-microvolt = <1050000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1000000000 {
|
|
+ opp-hz = /bits/ 64 <1000000000>;
|
|
+ opp-microvolt = <1075000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ opp-suspend;
|
|
+ };
|
|
+ opp-1100000000 {
|
|
+ opp-hz = /bits/ 64 <1100000000>;
|
|
+ opp-microvolt = <1100000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1200000000 {
|
|
+ opp-hz = /bits/ 64 <1200000000>;
|
|
+ opp-microvolt = <1125000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1300000000 {
|
|
+ opp-hz = /bits/ 64 <1300000000>;
|
|
+ opp-microvolt = <1150000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1400000000 {
|
|
+ opp-hz = /bits/ 64 <1400000000>;
|
|
+ opp-microvolt = <1200000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1500000000 {
|
|
+ opp-hz = /bits/ 64 <1500000000>;
|
|
+ opp-microvolt = <1225000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1600000000 {
|
|
+ opp-hz = /bits/ 64 <1600000000>;
|
|
+ opp-microvolt = <1250000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ opp-1700000000 {
|
|
+ opp-hz = /bits/ 64 <1700000000>;
|
|
+ opp-microvolt = <1300000>;
|
|
+ clock-latency-ns = <140000>;
|
|
+ };
|
|
+ };
|
|
+
|
|
soc: soc {
|
|
sysram@2020000 {
|
|
compatible = "mmio-sram";
|
|
diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
|
|
index a4dcb68f4322..b4dd3846e8cc 100644
|
|
--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
|
|
+++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
|
|
@@ -613,7 +613,7 @@
|
|
status = "disabled";
|
|
};
|
|
|
|
- sdr: sdr@ffc25000 {
|
|
+ sdr: sdr@ffcfb100 {
|
|
compatible = "altr,sdr-ctl", "syscon";
|
|
reg = <0xffcfb100 0x80>;
|
|
};
|
|
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig
|
|
index 925d1364727a..b8e69fe282b8 100644
|
|
--- a/arch/arm/crypto/Kconfig
|
|
+++ b/arch/arm/crypto/Kconfig
|
|
@@ -121,10 +121,4 @@ config CRYPTO_CHACHA20_NEON
|
|
select CRYPTO_BLKCIPHER
|
|
select CRYPTO_CHACHA20
|
|
|
|
-config CRYPTO_SPECK_NEON
|
|
- tristate "NEON accelerated Speck cipher algorithms"
|
|
- depends on KERNEL_MODE_NEON
|
|
- select CRYPTO_BLKCIPHER
|
|
- select CRYPTO_SPECK
|
|
-
|
|
endif
|
|
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
|
|
index 8de542c48ade..bd5bceef0605 100644
|
|
--- a/arch/arm/crypto/Makefile
|
|
+++ b/arch/arm/crypto/Makefile
|
|
@@ -10,7 +10,6 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
|
|
obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
|
|
obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o
|
|
obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha20-neon.o
|
|
-obj-$(CONFIG_CRYPTO_SPECK_NEON) += speck-neon.o
|
|
|
|
ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
|
|
ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
|
|
@@ -54,7 +53,6 @@ ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
|
|
crct10dif-arm-ce-y := crct10dif-ce-core.o crct10dif-ce-glue.o
|
|
crc32-arm-ce-y:= crc32-ce-core.o crc32-ce-glue.o
|
|
chacha20-neon-y := chacha20-neon-core.o chacha20-neon-glue.o
|
|
-speck-neon-y := speck-neon-core.o speck-neon-glue.o
|
|
|
|
ifdef REGENERATE_ARM_CRYPTO
|
|
quiet_cmd_perl = PERL $@
|
|
diff --git a/arch/arm/crypto/speck-neon-core.S b/arch/arm/crypto/speck-neon-core.S
|
|
deleted file mode 100644
|
|
index 57caa742016e..000000000000
|
|
--- a/arch/arm/crypto/speck-neon-core.S
|
|
+++ /dev/null
|
|
@@ -1,434 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
|
|
- *
|
|
- * Copyright (c) 2018 Google, Inc
|
|
- *
|
|
- * Author: Eric Biggers <ebiggers@google.com>
|
|
- */
|
|
-
|
|
-#include <linux/linkage.h>
|
|
-
|
|
- .text
|
|
- .fpu neon
|
|
-
|
|
- // arguments
|
|
- ROUND_KEYS .req r0 // const {u64,u32} *round_keys
|
|
- NROUNDS .req r1 // int nrounds
|
|
- DST .req r2 // void *dst
|
|
- SRC .req r3 // const void *src
|
|
- NBYTES .req r4 // unsigned int nbytes
|
|
- TWEAK .req r5 // void *tweak
|
|
-
|
|
- // registers which hold the data being encrypted/decrypted
|
|
- X0 .req q0
|
|
- X0_L .req d0
|
|
- X0_H .req d1
|
|
- Y0 .req q1
|
|
- Y0_H .req d3
|
|
- X1 .req q2
|
|
- X1_L .req d4
|
|
- X1_H .req d5
|
|
- Y1 .req q3
|
|
- Y1_H .req d7
|
|
- X2 .req q4
|
|
- X2_L .req d8
|
|
- X2_H .req d9
|
|
- Y2 .req q5
|
|
- Y2_H .req d11
|
|
- X3 .req q6
|
|
- X3_L .req d12
|
|
- X3_H .req d13
|
|
- Y3 .req q7
|
|
- Y3_H .req d15
|
|
-
|
|
- // the round key, duplicated in all lanes
|
|
- ROUND_KEY .req q8
|
|
- ROUND_KEY_L .req d16
|
|
- ROUND_KEY_H .req d17
|
|
-
|
|
- // index vector for vtbl-based 8-bit rotates
|
|
- ROTATE_TABLE .req d18
|
|
-
|
|
- // multiplication table for updating XTS tweaks
|
|
- GF128MUL_TABLE .req d19
|
|
- GF64MUL_TABLE .req d19
|
|
-
|
|
- // current XTS tweak value(s)
|
|
- TWEAKV .req q10
|
|
- TWEAKV_L .req d20
|
|
- TWEAKV_H .req d21
|
|
-
|
|
- TMP0 .req q12
|
|
- TMP0_L .req d24
|
|
- TMP0_H .req d25
|
|
- TMP1 .req q13
|
|
- TMP2 .req q14
|
|
- TMP3 .req q15
|
|
-
|
|
- .align 4
|
|
-.Lror64_8_table:
|
|
- .byte 1, 2, 3, 4, 5, 6, 7, 0
|
|
-.Lror32_8_table:
|
|
- .byte 1, 2, 3, 0, 5, 6, 7, 4
|
|
-.Lrol64_8_table:
|
|
- .byte 7, 0, 1, 2, 3, 4, 5, 6
|
|
-.Lrol32_8_table:
|
|
- .byte 3, 0, 1, 2, 7, 4, 5, 6
|
|
-.Lgf128mul_table:
|
|
- .byte 0, 0x87
|
|
- .fill 14
|
|
-.Lgf64mul_table:
|
|
- .byte 0, 0x1b, (0x1b << 1), (0x1b << 1) ^ 0x1b
|
|
- .fill 12
|
|
-
|
|
-/*
|
|
- * _speck_round_128bytes() - Speck encryption round on 128 bytes at a time
|
|
- *
|
|
- * Do one Speck encryption round on the 128 bytes (8 blocks for Speck128, 16 for
|
|
- * Speck64) stored in X0-X3 and Y0-Y3, using the round key stored in all lanes
|
|
- * of ROUND_KEY. 'n' is the lane size: 64 for Speck128, or 32 for Speck64.
|
|
- *
|
|
- * The 8-bit rotates are implemented using vtbl instead of vshr + vsli because
|
|
- * the vtbl approach is faster on some processors and the same speed on others.
|
|
- */
|
|
-.macro _speck_round_128bytes n
|
|
-
|
|
- // x = ror(x, 8)
|
|
- vtbl.8 X0_L, {X0_L}, ROTATE_TABLE
|
|
- vtbl.8 X0_H, {X0_H}, ROTATE_TABLE
|
|
- vtbl.8 X1_L, {X1_L}, ROTATE_TABLE
|
|
- vtbl.8 X1_H, {X1_H}, ROTATE_TABLE
|
|
- vtbl.8 X2_L, {X2_L}, ROTATE_TABLE
|
|
- vtbl.8 X2_H, {X2_H}, ROTATE_TABLE
|
|
- vtbl.8 X3_L, {X3_L}, ROTATE_TABLE
|
|
- vtbl.8 X3_H, {X3_H}, ROTATE_TABLE
|
|
-
|
|
- // x += y
|
|
- vadd.u\n X0, Y0
|
|
- vadd.u\n X1, Y1
|
|
- vadd.u\n X2, Y2
|
|
- vadd.u\n X3, Y3
|
|
-
|
|
- // x ^= k
|
|
- veor X0, ROUND_KEY
|
|
- veor X1, ROUND_KEY
|
|
- veor X2, ROUND_KEY
|
|
- veor X3, ROUND_KEY
|
|
-
|
|
- // y = rol(y, 3)
|
|
- vshl.u\n TMP0, Y0, #3
|
|
- vshl.u\n TMP1, Y1, #3
|
|
- vshl.u\n TMP2, Y2, #3
|
|
- vshl.u\n TMP3, Y3, #3
|
|
- vsri.u\n TMP0, Y0, #(\n - 3)
|
|
- vsri.u\n TMP1, Y1, #(\n - 3)
|
|
- vsri.u\n TMP2, Y2, #(\n - 3)
|
|
- vsri.u\n TMP3, Y3, #(\n - 3)
|
|
-
|
|
- // y ^= x
|
|
- veor Y0, TMP0, X0
|
|
- veor Y1, TMP1, X1
|
|
- veor Y2, TMP2, X2
|
|
- veor Y3, TMP3, X3
|
|
-.endm
|
|
-
|
|
-/*
|
|
- * _speck_unround_128bytes() - Speck decryption round on 128 bytes at a time
|
|
- *
|
|
- * This is the inverse of _speck_round_128bytes().
|
|
- */
|
|
-.macro _speck_unround_128bytes n
|
|
-
|
|
- // y ^= x
|
|
- veor TMP0, Y0, X0
|
|
- veor TMP1, Y1, X1
|
|
- veor TMP2, Y2, X2
|
|
- veor TMP3, Y3, X3
|
|
-
|
|
- // y = ror(y, 3)
|
|
- vshr.u\n Y0, TMP0, #3
|
|
- vshr.u\n Y1, TMP1, #3
|
|
- vshr.u\n Y2, TMP2, #3
|
|
- vshr.u\n Y3, TMP3, #3
|
|
- vsli.u\n Y0, TMP0, #(\n - 3)
|
|
- vsli.u\n Y1, TMP1, #(\n - 3)
|
|
- vsli.u\n Y2, TMP2, #(\n - 3)
|
|
- vsli.u\n Y3, TMP3, #(\n - 3)
|
|
-
|
|
- // x ^= k
|
|
- veor X0, ROUND_KEY
|
|
- veor X1, ROUND_KEY
|
|
- veor X2, ROUND_KEY
|
|
- veor X3, ROUND_KEY
|
|
-
|
|
- // x -= y
|
|
- vsub.u\n X0, Y0
|
|
- vsub.u\n X1, Y1
|
|
- vsub.u\n X2, Y2
|
|
- vsub.u\n X3, Y3
|
|
-
|
|
- // x = rol(x, 8);
|
|
- vtbl.8 X0_L, {X0_L}, ROTATE_TABLE
|
|
- vtbl.8 X0_H, {X0_H}, ROTATE_TABLE
|
|
- vtbl.8 X1_L, {X1_L}, ROTATE_TABLE
|
|
- vtbl.8 X1_H, {X1_H}, ROTATE_TABLE
|
|
- vtbl.8 X2_L, {X2_L}, ROTATE_TABLE
|
|
- vtbl.8 X2_H, {X2_H}, ROTATE_TABLE
|
|
- vtbl.8 X3_L, {X3_L}, ROTATE_TABLE
|
|
- vtbl.8 X3_H, {X3_H}, ROTATE_TABLE
|
|
-.endm
|
|
-
|
|
-.macro _xts128_precrypt_one dst_reg, tweak_buf, tmp
|
|
-
|
|
- // Load the next source block
|
|
- vld1.8 {\dst_reg}, [SRC]!
|
|
-
|
|
- // Save the current tweak in the tweak buffer
|
|
- vst1.8 {TWEAKV}, [\tweak_buf:128]!
|
|
-
|
|
- // XOR the next source block with the current tweak
|
|
- veor \dst_reg, TWEAKV
|
|
-
|
|
- /*
|
|
- * Calculate the next tweak by multiplying the current one by x,
|
|
- * modulo p(x) = x^128 + x^7 + x^2 + x + 1.
|
|
- */
|
|
- vshr.u64 \tmp, TWEAKV, #63
|
|
- vshl.u64 TWEAKV, #1
|
|
- veor TWEAKV_H, \tmp\()_L
|
|
- vtbl.8 \tmp\()_H, {GF128MUL_TABLE}, \tmp\()_H
|
|
- veor TWEAKV_L, \tmp\()_H
|
|
-.endm
|
|
-
|
|
-.macro _xts64_precrypt_two dst_reg, tweak_buf, tmp
|
|
-
|
|
- // Load the next two source blocks
|
|
- vld1.8 {\dst_reg}, [SRC]!
|
|
-
|
|
- // Save the current two tweaks in the tweak buffer
|
|
- vst1.8 {TWEAKV}, [\tweak_buf:128]!
|
|
-
|
|
- // XOR the next two source blocks with the current two tweaks
|
|
- veor \dst_reg, TWEAKV
|
|
-
|
|
- /*
|
|
- * Calculate the next two tweaks by multiplying the current ones by x^2,
|
|
- * modulo p(x) = x^64 + x^4 + x^3 + x + 1.
|
|
- */
|
|
- vshr.u64 \tmp, TWEAKV, #62
|
|
- vshl.u64 TWEAKV, #2
|
|
- vtbl.8 \tmp\()_L, {GF64MUL_TABLE}, \tmp\()_L
|
|
- vtbl.8 \tmp\()_H, {GF64MUL_TABLE}, \tmp\()_H
|
|
- veor TWEAKV, \tmp
|
|
-.endm
|
|
-
|
|
-/*
|
|
- * _speck_xts_crypt() - Speck-XTS encryption/decryption
|
|
- *
|
|
- * Encrypt or decrypt NBYTES bytes of data from the SRC buffer to the DST buffer
|
|
- * using Speck-XTS, specifically the variant with a block size of '2n' and round
|
|
- * count given by NROUNDS. The expanded round keys are given in ROUND_KEYS, and
|
|
- * the current XTS tweak value is given in TWEAK. It's assumed that NBYTES is a
|
|
- * nonzero multiple of 128.
|
|
- */
|
|
-.macro _speck_xts_crypt n, decrypting
|
|
- push {r4-r7}
|
|
- mov r7, sp
|
|
-
|
|
- /*
|
|
- * The first four parameters were passed in registers r0-r3. Load the
|
|
- * additional parameters, which were passed on the stack.
|
|
- */
|
|
- ldr NBYTES, [sp, #16]
|
|
- ldr TWEAK, [sp, #20]
|
|
-
|
|
- /*
|
|
- * If decrypting, modify the ROUND_KEYS parameter to point to the last
|
|
- * round key rather than the first, since for decryption the round keys
|
|
- * are used in reverse order.
|
|
- */
|
|
-.if \decrypting
|
|
-.if \n == 64
|
|
- add ROUND_KEYS, ROUND_KEYS, NROUNDS, lsl #3
|
|
- sub ROUND_KEYS, #8
|
|
-.else
|
|
- add ROUND_KEYS, ROUND_KEYS, NROUNDS, lsl #2
|
|
- sub ROUND_KEYS, #4
|
|
-.endif
|
|
-.endif
|
|
-
|
|
- // Load the index vector for vtbl-based 8-bit rotates
|
|
-.if \decrypting
|
|
- ldr r12, =.Lrol\n\()_8_table
|
|
-.else
|
|
- ldr r12, =.Lror\n\()_8_table
|
|
-.endif
|
|
- vld1.8 {ROTATE_TABLE}, [r12:64]
|
|
-
|
|
- // One-time XTS preparation
|
|
-
|
|
- /*
|
|
- * Allocate stack space to store 128 bytes worth of tweaks. For
|
|
- * performance, this space is aligned to a 16-byte boundary so that we
|
|
- * can use the load/store instructions that declare 16-byte alignment.
|
|
- * For Thumb2 compatibility, don't do the 'bic' directly on 'sp'.
|
|
- */
|
|
- sub r12, sp, #128
|
|
- bic r12, #0xf
|
|
- mov sp, r12
|
|
-
|
|
-.if \n == 64
|
|
- // Load first tweak
|
|
- vld1.8 {TWEAKV}, [TWEAK]
|
|
-
|
|
- // Load GF(2^128) multiplication table
|
|
- ldr r12, =.Lgf128mul_table
|
|
- vld1.8 {GF128MUL_TABLE}, [r12:64]
|
|
-.else
|
|
- // Load first tweak
|
|
- vld1.8 {TWEAKV_L}, [TWEAK]
|
|
-
|
|
- // Load GF(2^64) multiplication table
|
|
- ldr r12, =.Lgf64mul_table
|
|
- vld1.8 {GF64MUL_TABLE}, [r12:64]
|
|
-
|
|
- // Calculate second tweak, packing it together with the first
|
|
- vshr.u64 TMP0_L, TWEAKV_L, #63
|
|
- vtbl.u8 TMP0_L, {GF64MUL_TABLE}, TMP0_L
|
|
- vshl.u64 TWEAKV_H, TWEAKV_L, #1
|
|
- veor TWEAKV_H, TMP0_L
|
|
-.endif
|
|
-
|
|
-.Lnext_128bytes_\@:
|
|
-
|
|
- /*
|
|
- * Load the source blocks into {X,Y}[0-3], XOR them with their XTS tweak
|
|
- * values, and save the tweaks on the stack for later. Then
|
|
- * de-interleave the 'x' and 'y' elements of each block, i.e. make it so
|
|
- * that the X[0-3] registers contain only the second halves of blocks,
|
|
- * and the Y[0-3] registers contain only the first halves of blocks.
|
|
- * (Speck uses the order (y, x) rather than the more intuitive (x, y).)
|
|
- */
|
|
- mov r12, sp
|
|
-.if \n == 64
|
|
- _xts128_precrypt_one X0, r12, TMP0
|
|
- _xts128_precrypt_one Y0, r12, TMP0
|
|
- _xts128_precrypt_one X1, r12, TMP0
|
|
- _xts128_precrypt_one Y1, r12, TMP0
|
|
- _xts128_precrypt_one X2, r12, TMP0
|
|
- _xts128_precrypt_one Y2, r12, TMP0
|
|
- _xts128_precrypt_one X3, r12, TMP0
|
|
- _xts128_precrypt_one Y3, r12, TMP0
|
|
- vswp X0_L, Y0_H
|
|
- vswp X1_L, Y1_H
|
|
- vswp X2_L, Y2_H
|
|
- vswp X3_L, Y3_H
|
|
-.else
|
|
- _xts64_precrypt_two X0, r12, TMP0
|
|
- _xts64_precrypt_two Y0, r12, TMP0
|
|
- _xts64_precrypt_two X1, r12, TMP0
|
|
- _xts64_precrypt_two Y1, r12, TMP0
|
|
- _xts64_precrypt_two X2, r12, TMP0
|
|
- _xts64_precrypt_two Y2, r12, TMP0
|
|
- _xts64_precrypt_two X3, r12, TMP0
|
|
- _xts64_precrypt_two Y3, r12, TMP0
|
|
- vuzp.32 Y0, X0
|
|
- vuzp.32 Y1, X1
|
|
- vuzp.32 Y2, X2
|
|
- vuzp.32 Y3, X3
|
|
-.endif
|
|
-
|
|
- // Do the cipher rounds
|
|
-
|
|
- mov r12, ROUND_KEYS
|
|
- mov r6, NROUNDS
|
|
-
|
|
-.Lnext_round_\@:
|
|
-.if \decrypting
|
|
-.if \n == 64
|
|
- vld1.64 ROUND_KEY_L, [r12]
|
|
- sub r12, #8
|
|
- vmov ROUND_KEY_H, ROUND_KEY_L
|
|
-.else
|
|
- vld1.32 {ROUND_KEY_L[],ROUND_KEY_H[]}, [r12]
|
|
- sub r12, #4
|
|
-.endif
|
|
- _speck_unround_128bytes \n
|
|
-.else
|
|
-.if \n == 64
|
|
- vld1.64 ROUND_KEY_L, [r12]!
|
|
- vmov ROUND_KEY_H, ROUND_KEY_L
|
|
-.else
|
|
- vld1.32 {ROUND_KEY_L[],ROUND_KEY_H[]}, [r12]!
|
|
-.endif
|
|
- _speck_round_128bytes \n
|
|
-.endif
|
|
- subs r6, r6, #1
|
|
- bne .Lnext_round_\@
|
|
-
|
|
- // Re-interleave the 'x' and 'y' elements of each block
|
|
-.if \n == 64
|
|
- vswp X0_L, Y0_H
|
|
- vswp X1_L, Y1_H
|
|
- vswp X2_L, Y2_H
|
|
- vswp X3_L, Y3_H
|
|
-.else
|
|
- vzip.32 Y0, X0
|
|
- vzip.32 Y1, X1
|
|
- vzip.32 Y2, X2
|
|
- vzip.32 Y3, X3
|
|
-.endif
|
|
-
|
|
- // XOR the encrypted/decrypted blocks with the tweaks we saved earlier
|
|
- mov r12, sp
|
|
- vld1.8 {TMP0, TMP1}, [r12:128]!
|
|
- vld1.8 {TMP2, TMP3}, [r12:128]!
|
|
- veor X0, TMP0
|
|
- veor Y0, TMP1
|
|
- veor X1, TMP2
|
|
- veor Y1, TMP3
|
|
- vld1.8 {TMP0, TMP1}, [r12:128]!
|
|
- vld1.8 {TMP2, TMP3}, [r12:128]!
|
|
- veor X2, TMP0
|
|
- veor Y2, TMP1
|
|
- veor X3, TMP2
|
|
- veor Y3, TMP3
|
|
-
|
|
- // Store the ciphertext in the destination buffer
|
|
- vst1.8 {X0, Y0}, [DST]!
|
|
- vst1.8 {X1, Y1}, [DST]!
|
|
- vst1.8 {X2, Y2}, [DST]!
|
|
- vst1.8 {X3, Y3}, [DST]!
|
|
-
|
|
- // Continue if there are more 128-byte chunks remaining, else return
|
|
- subs NBYTES, #128
|
|
- bne .Lnext_128bytes_\@
|
|
-
|
|
- // Store the next tweak
|
|
-.if \n == 64
|
|
- vst1.8 {TWEAKV}, [TWEAK]
|
|
-.else
|
|
- vst1.8 {TWEAKV_L}, [TWEAK]
|
|
-.endif
|
|
-
|
|
- mov sp, r7
|
|
- pop {r4-r7}
|
|
- bx lr
|
|
-.endm
|
|
-
|
|
-ENTRY(speck128_xts_encrypt_neon)
|
|
- _speck_xts_crypt n=64, decrypting=0
|
|
-ENDPROC(speck128_xts_encrypt_neon)
|
|
-
|
|
-ENTRY(speck128_xts_decrypt_neon)
|
|
- _speck_xts_crypt n=64, decrypting=1
|
|
-ENDPROC(speck128_xts_decrypt_neon)
|
|
-
|
|
-ENTRY(speck64_xts_encrypt_neon)
|
|
- _speck_xts_crypt n=32, decrypting=0
|
|
-ENDPROC(speck64_xts_encrypt_neon)
|
|
-
|
|
-ENTRY(speck64_xts_decrypt_neon)
|
|
- _speck_xts_crypt n=32, decrypting=1
|
|
-ENDPROC(speck64_xts_decrypt_neon)
|
|
diff --git a/arch/arm/crypto/speck-neon-glue.c b/arch/arm/crypto/speck-neon-glue.c
|
|
deleted file mode 100644
|
|
index f012c3ea998f..000000000000
|
|
--- a/arch/arm/crypto/speck-neon-glue.c
|
|
+++ /dev/null
|
|
@@ -1,288 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
|
|
- *
|
|
- * Copyright (c) 2018 Google, Inc
|
|
- *
|
|
- * Note: the NIST recommendation for XTS only specifies a 128-bit block size,
|
|
- * but a 64-bit version (needed for Speck64) is fairly straightforward; the math
|
|
- * is just done in GF(2^64) instead of GF(2^128), with the reducing polynomial
|
|
- * x^64 + x^4 + x^3 + x + 1 from the original XEX paper (Rogaway, 2004:
|
|
- * "Efficient Instantiations of Tweakable Blockciphers and Refinements to Modes
|
|
- * OCB and PMAC"), represented as 0x1B.
|
|
- */
|
|
-
|
|
-#include <asm/hwcap.h>
|
|
-#include <asm/neon.h>
|
|
-#include <asm/simd.h>
|
|
-#include <crypto/algapi.h>
|
|
-#include <crypto/gf128mul.h>
|
|
-#include <crypto/internal/skcipher.h>
|
|
-#include <crypto/speck.h>
|
|
-#include <crypto/xts.h>
|
|
-#include <linux/kernel.h>
|
|
-#include <linux/module.h>
|
|
-
|
|
-/* The assembly functions only handle multiples of 128 bytes */
|
|
-#define SPECK_NEON_CHUNK_SIZE 128
|
|
-
|
|
-/* Speck128 */
|
|
-
|
|
-struct speck128_xts_tfm_ctx {
|
|
- struct speck128_tfm_ctx main_key;
|
|
- struct speck128_tfm_ctx tweak_key;
|
|
-};
|
|
-
|
|
-asmlinkage void speck128_xts_encrypt_neon(const u64 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-asmlinkage void speck128_xts_decrypt_neon(const u64 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-typedef void (*speck128_crypt_one_t)(const struct speck128_tfm_ctx *,
|
|
- u8 *, const u8 *);
|
|
-typedef void (*speck128_xts_crypt_many_t)(const u64 *, int, void *,
|
|
- const void *, unsigned int, void *);
|
|
-
|
|
-static __always_inline int
|
|
-__speck128_xts_crypt(struct skcipher_request *req,
|
|
- speck128_crypt_one_t crypt_one,
|
|
- speck128_xts_crypt_many_t crypt_many)
|
|
-{
|
|
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
|
- const struct speck128_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- struct skcipher_walk walk;
|
|
- le128 tweak;
|
|
- int err;
|
|
-
|
|
- err = skcipher_walk_virt(&walk, req, true);
|
|
-
|
|
- crypto_speck128_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
|
|
-
|
|
- while (walk.nbytes > 0) {
|
|
- unsigned int nbytes = walk.nbytes;
|
|
- u8 *dst = walk.dst.virt.addr;
|
|
- const u8 *src = walk.src.virt.addr;
|
|
-
|
|
- if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
|
|
- unsigned int count;
|
|
-
|
|
- count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
|
|
- kernel_neon_begin();
|
|
- (*crypt_many)(ctx->main_key.round_keys,
|
|
- ctx->main_key.nrounds,
|
|
- dst, src, count, &tweak);
|
|
- kernel_neon_end();
|
|
- dst += count;
|
|
- src += count;
|
|
- nbytes -= count;
|
|
- }
|
|
-
|
|
- /* Handle any remainder with generic code */
|
|
- while (nbytes >= sizeof(tweak)) {
|
|
- le128_xor((le128 *)dst, (const le128 *)src, &tweak);
|
|
- (*crypt_one)(&ctx->main_key, dst, dst);
|
|
- le128_xor((le128 *)dst, (const le128 *)dst, &tweak);
|
|
- gf128mul_x_ble(&tweak, &tweak);
|
|
-
|
|
- dst += sizeof(tweak);
|
|
- src += sizeof(tweak);
|
|
- nbytes -= sizeof(tweak);
|
|
- }
|
|
- err = skcipher_walk_done(&walk, nbytes);
|
|
- }
|
|
-
|
|
- return err;
|
|
-}
|
|
-
|
|
-static int speck128_xts_encrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck128_xts_crypt(req, crypto_speck128_encrypt,
|
|
- speck128_xts_encrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck128_xts_decrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck128_xts_crypt(req, crypto_speck128_decrypt,
|
|
- speck128_xts_decrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck128_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- struct speck128_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- int err;
|
|
-
|
|
- err = xts_verify_key(tfm, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- keylen /= 2;
|
|
-
|
|
- err = crypto_speck128_setkey(&ctx->main_key, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- return crypto_speck128_setkey(&ctx->tweak_key, key + keylen, keylen);
|
|
-}
|
|
-
|
|
-/* Speck64 */
|
|
-
|
|
-struct speck64_xts_tfm_ctx {
|
|
- struct speck64_tfm_ctx main_key;
|
|
- struct speck64_tfm_ctx tweak_key;
|
|
-};
|
|
-
|
|
-asmlinkage void speck64_xts_encrypt_neon(const u32 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-asmlinkage void speck64_xts_decrypt_neon(const u32 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-typedef void (*speck64_crypt_one_t)(const struct speck64_tfm_ctx *,
|
|
- u8 *, const u8 *);
|
|
-typedef void (*speck64_xts_crypt_many_t)(const u32 *, int, void *,
|
|
- const void *, unsigned int, void *);
|
|
-
|
|
-static __always_inline int
|
|
-__speck64_xts_crypt(struct skcipher_request *req, speck64_crypt_one_t crypt_one,
|
|
- speck64_xts_crypt_many_t crypt_many)
|
|
-{
|
|
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
|
- const struct speck64_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- struct skcipher_walk walk;
|
|
- __le64 tweak;
|
|
- int err;
|
|
-
|
|
- err = skcipher_walk_virt(&walk, req, true);
|
|
-
|
|
- crypto_speck64_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
|
|
-
|
|
- while (walk.nbytes > 0) {
|
|
- unsigned int nbytes = walk.nbytes;
|
|
- u8 *dst = walk.dst.virt.addr;
|
|
- const u8 *src = walk.src.virt.addr;
|
|
-
|
|
- if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
|
|
- unsigned int count;
|
|
-
|
|
- count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
|
|
- kernel_neon_begin();
|
|
- (*crypt_many)(ctx->main_key.round_keys,
|
|
- ctx->main_key.nrounds,
|
|
- dst, src, count, &tweak);
|
|
- kernel_neon_end();
|
|
- dst += count;
|
|
- src += count;
|
|
- nbytes -= count;
|
|
- }
|
|
-
|
|
- /* Handle any remainder with generic code */
|
|
- while (nbytes >= sizeof(tweak)) {
|
|
- *(__le64 *)dst = *(__le64 *)src ^ tweak;
|
|
- (*crypt_one)(&ctx->main_key, dst, dst);
|
|
- *(__le64 *)dst ^= tweak;
|
|
- tweak = cpu_to_le64((le64_to_cpu(tweak) << 1) ^
|
|
- ((tweak & cpu_to_le64(1ULL << 63)) ?
|
|
- 0x1B : 0));
|
|
- dst += sizeof(tweak);
|
|
- src += sizeof(tweak);
|
|
- nbytes -= sizeof(tweak);
|
|
- }
|
|
- err = skcipher_walk_done(&walk, nbytes);
|
|
- }
|
|
-
|
|
- return err;
|
|
-}
|
|
-
|
|
-static int speck64_xts_encrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck64_xts_crypt(req, crypto_speck64_encrypt,
|
|
- speck64_xts_encrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck64_xts_decrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck64_xts_crypt(req, crypto_speck64_decrypt,
|
|
- speck64_xts_decrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck64_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- struct speck64_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- int err;
|
|
-
|
|
- err = xts_verify_key(tfm, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- keylen /= 2;
|
|
-
|
|
- err = crypto_speck64_setkey(&ctx->main_key, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- return crypto_speck64_setkey(&ctx->tweak_key, key + keylen, keylen);
|
|
-}
|
|
-
|
|
-static struct skcipher_alg speck_algs[] = {
|
|
- {
|
|
- .base.cra_name = "xts(speck128)",
|
|
- .base.cra_driver_name = "xts-speck128-neon",
|
|
- .base.cra_priority = 300,
|
|
- .base.cra_blocksize = SPECK128_BLOCK_SIZE,
|
|
- .base.cra_ctxsize = sizeof(struct speck128_xts_tfm_ctx),
|
|
- .base.cra_alignmask = 7,
|
|
- .base.cra_module = THIS_MODULE,
|
|
- .min_keysize = 2 * SPECK128_128_KEY_SIZE,
|
|
- .max_keysize = 2 * SPECK128_256_KEY_SIZE,
|
|
- .ivsize = SPECK128_BLOCK_SIZE,
|
|
- .walksize = SPECK_NEON_CHUNK_SIZE,
|
|
- .setkey = speck128_xts_setkey,
|
|
- .encrypt = speck128_xts_encrypt,
|
|
- .decrypt = speck128_xts_decrypt,
|
|
- }, {
|
|
- .base.cra_name = "xts(speck64)",
|
|
- .base.cra_driver_name = "xts-speck64-neon",
|
|
- .base.cra_priority = 300,
|
|
- .base.cra_blocksize = SPECK64_BLOCK_SIZE,
|
|
- .base.cra_ctxsize = sizeof(struct speck64_xts_tfm_ctx),
|
|
- .base.cra_alignmask = 7,
|
|
- .base.cra_module = THIS_MODULE,
|
|
- .min_keysize = 2 * SPECK64_96_KEY_SIZE,
|
|
- .max_keysize = 2 * SPECK64_128_KEY_SIZE,
|
|
- .ivsize = SPECK64_BLOCK_SIZE,
|
|
- .walksize = SPECK_NEON_CHUNK_SIZE,
|
|
- .setkey = speck64_xts_setkey,
|
|
- .encrypt = speck64_xts_encrypt,
|
|
- .decrypt = speck64_xts_decrypt,
|
|
- }
|
|
-};
|
|
-
|
|
-static int __init speck_neon_module_init(void)
|
|
-{
|
|
- if (!(elf_hwcap & HWCAP_NEON))
|
|
- return -ENODEV;
|
|
- return crypto_register_skciphers(speck_algs, ARRAY_SIZE(speck_algs));
|
|
-}
|
|
-
|
|
-static void __exit speck_neon_module_exit(void)
|
|
-{
|
|
- crypto_unregister_skciphers(speck_algs, ARRAY_SIZE(speck_algs));
|
|
-}
|
|
-
|
|
-module_init(speck_neon_module_init);
|
|
-module_exit(speck_neon_module_exit);
|
|
-
|
|
-MODULE_DESCRIPTION("Speck block cipher (NEON-accelerated)");
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
|
|
-MODULE_ALIAS_CRYPTO("xts(speck128)");
|
|
-MODULE_ALIAS_CRYPTO("xts-speck128-neon");
|
|
-MODULE_ALIAS_CRYPTO("xts(speck64)");
|
|
-MODULE_ALIAS_CRYPTO("xts-speck64-neon");
|
|
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
|
|
index d033da401c26..bc6c141d7372 100644
|
|
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
|
|
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
|
|
@@ -335,7 +335,7 @@
|
|
|
|
sysmgr: sysmgr@ffd12000 {
|
|
compatible = "altr,sys-mgr", "syscon";
|
|
- reg = <0xffd12000 0x1000>;
|
|
+ reg = <0xffd12000 0x228>;
|
|
};
|
|
|
|
/* Local timer */
|
|
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
|
|
index e3fdb0fd6f70..d51944ff9f91 100644
|
|
--- a/arch/arm64/crypto/Kconfig
|
|
+++ b/arch/arm64/crypto/Kconfig
|
|
@@ -119,10 +119,4 @@ config CRYPTO_AES_ARM64_BS
|
|
select CRYPTO_AES_ARM64
|
|
select CRYPTO_SIMD
|
|
|
|
-config CRYPTO_SPECK_NEON
|
|
- tristate "NEON accelerated Speck cipher algorithms"
|
|
- depends on KERNEL_MODE_NEON
|
|
- select CRYPTO_BLKCIPHER
|
|
- select CRYPTO_SPECK
|
|
-
|
|
endif
|
|
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
|
|
index bcafd016618e..7bc4bda6d9c6 100644
|
|
--- a/arch/arm64/crypto/Makefile
|
|
+++ b/arch/arm64/crypto/Makefile
|
|
@@ -56,9 +56,6 @@ sha512-arm64-y := sha512-glue.o sha512-core.o
|
|
obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha20-neon.o
|
|
chacha20-neon-y := chacha20-neon-core.o chacha20-neon-glue.o
|
|
|
|
-obj-$(CONFIG_CRYPTO_SPECK_NEON) += speck-neon.o
|
|
-speck-neon-y := speck-neon-core.o speck-neon-glue.o
|
|
-
|
|
obj-$(CONFIG_CRYPTO_AES_ARM64) += aes-arm64.o
|
|
aes-arm64-y := aes-cipher-core.o aes-cipher-glue.o
|
|
|
|
diff --git a/arch/arm64/crypto/speck-neon-core.S b/arch/arm64/crypto/speck-neon-core.S
|
|
deleted file mode 100644
|
|
index b14463438b09..000000000000
|
|
--- a/arch/arm64/crypto/speck-neon-core.S
|
|
+++ /dev/null
|
|
@@ -1,352 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * ARM64 NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
|
|
- *
|
|
- * Copyright (c) 2018 Google, Inc
|
|
- *
|
|
- * Author: Eric Biggers <ebiggers@google.com>
|
|
- */
|
|
-
|
|
-#include <linux/linkage.h>
|
|
-
|
|
- .text
|
|
-
|
|
- // arguments
|
|
- ROUND_KEYS .req x0 // const {u64,u32} *round_keys
|
|
- NROUNDS .req w1 // int nrounds
|
|
- NROUNDS_X .req x1
|
|
- DST .req x2 // void *dst
|
|
- SRC .req x3 // const void *src
|
|
- NBYTES .req w4 // unsigned int nbytes
|
|
- TWEAK .req x5 // void *tweak
|
|
-
|
|
- // registers which hold the data being encrypted/decrypted
|
|
- // (underscores avoid a naming collision with ARM64 registers x0-x3)
|
|
- X_0 .req v0
|
|
- Y_0 .req v1
|
|
- X_1 .req v2
|
|
- Y_1 .req v3
|
|
- X_2 .req v4
|
|
- Y_2 .req v5
|
|
- X_3 .req v6
|
|
- Y_3 .req v7
|
|
-
|
|
- // the round key, duplicated in all lanes
|
|
- ROUND_KEY .req v8
|
|
-
|
|
- // index vector for tbl-based 8-bit rotates
|
|
- ROTATE_TABLE .req v9
|
|
- ROTATE_TABLE_Q .req q9
|
|
-
|
|
- // temporary registers
|
|
- TMP0 .req v10
|
|
- TMP1 .req v11
|
|
- TMP2 .req v12
|
|
- TMP3 .req v13
|
|
-
|
|
- // multiplication table for updating XTS tweaks
|
|
- GFMUL_TABLE .req v14
|
|
- GFMUL_TABLE_Q .req q14
|
|
-
|
|
- // next XTS tweak value(s)
|
|
- TWEAKV_NEXT .req v15
|
|
-
|
|
- // XTS tweaks for the blocks currently being encrypted/decrypted
|
|
- TWEAKV0 .req v16
|
|
- TWEAKV1 .req v17
|
|
- TWEAKV2 .req v18
|
|
- TWEAKV3 .req v19
|
|
- TWEAKV4 .req v20
|
|
- TWEAKV5 .req v21
|
|
- TWEAKV6 .req v22
|
|
- TWEAKV7 .req v23
|
|
-
|
|
- .align 4
|
|
-.Lror64_8_table:
|
|
- .octa 0x080f0e0d0c0b0a090007060504030201
|
|
-.Lror32_8_table:
|
|
- .octa 0x0c0f0e0d080b0a090407060500030201
|
|
-.Lrol64_8_table:
|
|
- .octa 0x0e0d0c0b0a09080f0605040302010007
|
|
-.Lrol32_8_table:
|
|
- .octa 0x0e0d0c0f0a09080b0605040702010003
|
|
-.Lgf128mul_table:
|
|
- .octa 0x00000000000000870000000000000001
|
|
-.Lgf64mul_table:
|
|
- .octa 0x0000000000000000000000002d361b00
|
|
-
|
|
-/*
|
|
- * _speck_round_128bytes() - Speck encryption round on 128 bytes at a time
|
|
- *
|
|
- * Do one Speck encryption round on the 128 bytes (8 blocks for Speck128, 16 for
|
|
- * Speck64) stored in X0-X3 and Y0-Y3, using the round key stored in all lanes
|
|
- * of ROUND_KEY. 'n' is the lane size: 64 for Speck128, or 32 for Speck64.
|
|
- * 'lanes' is the lane specifier: "2d" for Speck128 or "4s" for Speck64.
|
|
- */
|
|
-.macro _speck_round_128bytes n, lanes
|
|
-
|
|
- // x = ror(x, 8)
|
|
- tbl X_0.16b, {X_0.16b}, ROTATE_TABLE.16b
|
|
- tbl X_1.16b, {X_1.16b}, ROTATE_TABLE.16b
|
|
- tbl X_2.16b, {X_2.16b}, ROTATE_TABLE.16b
|
|
- tbl X_3.16b, {X_3.16b}, ROTATE_TABLE.16b
|
|
-
|
|
- // x += y
|
|
- add X_0.\lanes, X_0.\lanes, Y_0.\lanes
|
|
- add X_1.\lanes, X_1.\lanes, Y_1.\lanes
|
|
- add X_2.\lanes, X_2.\lanes, Y_2.\lanes
|
|
- add X_3.\lanes, X_3.\lanes, Y_3.\lanes
|
|
-
|
|
- // x ^= k
|
|
- eor X_0.16b, X_0.16b, ROUND_KEY.16b
|
|
- eor X_1.16b, X_1.16b, ROUND_KEY.16b
|
|
- eor X_2.16b, X_2.16b, ROUND_KEY.16b
|
|
- eor X_3.16b, X_3.16b, ROUND_KEY.16b
|
|
-
|
|
- // y = rol(y, 3)
|
|
- shl TMP0.\lanes, Y_0.\lanes, #3
|
|
- shl TMP1.\lanes, Y_1.\lanes, #3
|
|
- shl TMP2.\lanes, Y_2.\lanes, #3
|
|
- shl TMP3.\lanes, Y_3.\lanes, #3
|
|
- sri TMP0.\lanes, Y_0.\lanes, #(\n - 3)
|
|
- sri TMP1.\lanes, Y_1.\lanes, #(\n - 3)
|
|
- sri TMP2.\lanes, Y_2.\lanes, #(\n - 3)
|
|
- sri TMP3.\lanes, Y_3.\lanes, #(\n - 3)
|
|
-
|
|
- // y ^= x
|
|
- eor Y_0.16b, TMP0.16b, X_0.16b
|
|
- eor Y_1.16b, TMP1.16b, X_1.16b
|
|
- eor Y_2.16b, TMP2.16b, X_2.16b
|
|
- eor Y_3.16b, TMP3.16b, X_3.16b
|
|
-.endm
|
|
-
|
|
-/*
|
|
- * _speck_unround_128bytes() - Speck decryption round on 128 bytes at a time
|
|
- *
|
|
- * This is the inverse of _speck_round_128bytes().
|
|
- */
|
|
-.macro _speck_unround_128bytes n, lanes
|
|
-
|
|
- // y ^= x
|
|
- eor TMP0.16b, Y_0.16b, X_0.16b
|
|
- eor TMP1.16b, Y_1.16b, X_1.16b
|
|
- eor TMP2.16b, Y_2.16b, X_2.16b
|
|
- eor TMP3.16b, Y_3.16b, X_3.16b
|
|
-
|
|
- // y = ror(y, 3)
|
|
- ushr Y_0.\lanes, TMP0.\lanes, #3
|
|
- ushr Y_1.\lanes, TMP1.\lanes, #3
|
|
- ushr Y_2.\lanes, TMP2.\lanes, #3
|
|
- ushr Y_3.\lanes, TMP3.\lanes, #3
|
|
- sli Y_0.\lanes, TMP0.\lanes, #(\n - 3)
|
|
- sli Y_1.\lanes, TMP1.\lanes, #(\n - 3)
|
|
- sli Y_2.\lanes, TMP2.\lanes, #(\n - 3)
|
|
- sli Y_3.\lanes, TMP3.\lanes, #(\n - 3)
|
|
-
|
|
- // x ^= k
|
|
- eor X_0.16b, X_0.16b, ROUND_KEY.16b
|
|
- eor X_1.16b, X_1.16b, ROUND_KEY.16b
|
|
- eor X_2.16b, X_2.16b, ROUND_KEY.16b
|
|
- eor X_3.16b, X_3.16b, ROUND_KEY.16b
|
|
-
|
|
- // x -= y
|
|
- sub X_0.\lanes, X_0.\lanes, Y_0.\lanes
|
|
- sub X_1.\lanes, X_1.\lanes, Y_1.\lanes
|
|
- sub X_2.\lanes, X_2.\lanes, Y_2.\lanes
|
|
- sub X_3.\lanes, X_3.\lanes, Y_3.\lanes
|
|
-
|
|
- // x = rol(x, 8)
|
|
- tbl X_0.16b, {X_0.16b}, ROTATE_TABLE.16b
|
|
- tbl X_1.16b, {X_1.16b}, ROTATE_TABLE.16b
|
|
- tbl X_2.16b, {X_2.16b}, ROTATE_TABLE.16b
|
|
- tbl X_3.16b, {X_3.16b}, ROTATE_TABLE.16b
|
|
-.endm
|
|
-
|
|
-.macro _next_xts_tweak next, cur, tmp, n
|
|
-.if \n == 64
|
|
- /*
|
|
- * Calculate the next tweak by multiplying the current one by x,
|
|
- * modulo p(x) = x^128 + x^7 + x^2 + x + 1.
|
|
- */
|
|
- sshr \tmp\().2d, \cur\().2d, #63
|
|
- and \tmp\().16b, \tmp\().16b, GFMUL_TABLE.16b
|
|
- shl \next\().2d, \cur\().2d, #1
|
|
- ext \tmp\().16b, \tmp\().16b, \tmp\().16b, #8
|
|
- eor \next\().16b, \next\().16b, \tmp\().16b
|
|
-.else
|
|
- /*
|
|
- * Calculate the next two tweaks by multiplying the current ones by x^2,
|
|
- * modulo p(x) = x^64 + x^4 + x^3 + x + 1.
|
|
- */
|
|
- ushr \tmp\().2d, \cur\().2d, #62
|
|
- shl \next\().2d, \cur\().2d, #2
|
|
- tbl \tmp\().16b, {GFMUL_TABLE.16b}, \tmp\().16b
|
|
- eor \next\().16b, \next\().16b, \tmp\().16b
|
|
-.endif
|
|
-.endm
|
|
-
|
|
-/*
|
|
- * _speck_xts_crypt() - Speck-XTS encryption/decryption
|
|
- *
|
|
- * Encrypt or decrypt NBYTES bytes of data from the SRC buffer to the DST buffer
|
|
- * using Speck-XTS, specifically the variant with a block size of '2n' and round
|
|
- * count given by NROUNDS. The expanded round keys are given in ROUND_KEYS, and
|
|
- * the current XTS tweak value is given in TWEAK. It's assumed that NBYTES is a
|
|
- * nonzero multiple of 128.
|
|
- */
|
|
-.macro _speck_xts_crypt n, lanes, decrypting
|
|
-
|
|
- /*
|
|
- * If decrypting, modify the ROUND_KEYS parameter to point to the last
|
|
- * round key rather than the first, since for decryption the round keys
|
|
- * are used in reverse order.
|
|
- */
|
|
-.if \decrypting
|
|
- mov NROUNDS, NROUNDS /* zero the high 32 bits */
|
|
-.if \n == 64
|
|
- add ROUND_KEYS, ROUND_KEYS, NROUNDS_X, lsl #3
|
|
- sub ROUND_KEYS, ROUND_KEYS, #8
|
|
-.else
|
|
- add ROUND_KEYS, ROUND_KEYS, NROUNDS_X, lsl #2
|
|
- sub ROUND_KEYS, ROUND_KEYS, #4
|
|
-.endif
|
|
-.endif
|
|
-
|
|
- // Load the index vector for tbl-based 8-bit rotates
|
|
-.if \decrypting
|
|
- ldr ROTATE_TABLE_Q, .Lrol\n\()_8_table
|
|
-.else
|
|
- ldr ROTATE_TABLE_Q, .Lror\n\()_8_table
|
|
-.endif
|
|
-
|
|
- // One-time XTS preparation
|
|
-.if \n == 64
|
|
- // Load first tweak
|
|
- ld1 {TWEAKV0.16b}, [TWEAK]
|
|
-
|
|
- // Load GF(2^128) multiplication table
|
|
- ldr GFMUL_TABLE_Q, .Lgf128mul_table
|
|
-.else
|
|
- // Load first tweak
|
|
- ld1 {TWEAKV0.8b}, [TWEAK]
|
|
-
|
|
- // Load GF(2^64) multiplication table
|
|
- ldr GFMUL_TABLE_Q, .Lgf64mul_table
|
|
-
|
|
- // Calculate second tweak, packing it together with the first
|
|
- ushr TMP0.2d, TWEAKV0.2d, #63
|
|
- shl TMP1.2d, TWEAKV0.2d, #1
|
|
- tbl TMP0.8b, {GFMUL_TABLE.16b}, TMP0.8b
|
|
- eor TMP0.8b, TMP0.8b, TMP1.8b
|
|
- mov TWEAKV0.d[1], TMP0.d[0]
|
|
-.endif
|
|
-
|
|
-.Lnext_128bytes_\@:
|
|
-
|
|
- // Calculate XTS tweaks for next 128 bytes
|
|
- _next_xts_tweak TWEAKV1, TWEAKV0, TMP0, \n
|
|
- _next_xts_tweak TWEAKV2, TWEAKV1, TMP0, \n
|
|
- _next_xts_tweak TWEAKV3, TWEAKV2, TMP0, \n
|
|
- _next_xts_tweak TWEAKV4, TWEAKV3, TMP0, \n
|
|
- _next_xts_tweak TWEAKV5, TWEAKV4, TMP0, \n
|
|
- _next_xts_tweak TWEAKV6, TWEAKV5, TMP0, \n
|
|
- _next_xts_tweak TWEAKV7, TWEAKV6, TMP0, \n
|
|
- _next_xts_tweak TWEAKV_NEXT, TWEAKV7, TMP0, \n
|
|
-
|
|
- // Load the next source blocks into {X,Y}[0-3]
|
|
- ld1 {X_0.16b-Y_1.16b}, [SRC], #64
|
|
- ld1 {X_2.16b-Y_3.16b}, [SRC], #64
|
|
-
|
|
- // XOR the source blocks with their XTS tweaks
|
|
- eor TMP0.16b, X_0.16b, TWEAKV0.16b
|
|
- eor Y_0.16b, Y_0.16b, TWEAKV1.16b
|
|
- eor TMP1.16b, X_1.16b, TWEAKV2.16b
|
|
- eor Y_1.16b, Y_1.16b, TWEAKV3.16b
|
|
- eor TMP2.16b, X_2.16b, TWEAKV4.16b
|
|
- eor Y_2.16b, Y_2.16b, TWEAKV5.16b
|
|
- eor TMP3.16b, X_3.16b, TWEAKV6.16b
|
|
- eor Y_3.16b, Y_3.16b, TWEAKV7.16b
|
|
-
|
|
- /*
|
|
- * De-interleave the 'x' and 'y' elements of each block, i.e. make it so
|
|
- * that the X[0-3] registers contain only the second halves of blocks,
|
|
- * and the Y[0-3] registers contain only the first halves of blocks.
|
|
- * (Speck uses the order (y, x) rather than the more intuitive (x, y).)
|
|
- */
|
|
- uzp2 X_0.\lanes, TMP0.\lanes, Y_0.\lanes
|
|
- uzp1 Y_0.\lanes, TMP0.\lanes, Y_0.\lanes
|
|
- uzp2 X_1.\lanes, TMP1.\lanes, Y_1.\lanes
|
|
- uzp1 Y_1.\lanes, TMP1.\lanes, Y_1.\lanes
|
|
- uzp2 X_2.\lanes, TMP2.\lanes, Y_2.\lanes
|
|
- uzp1 Y_2.\lanes, TMP2.\lanes, Y_2.\lanes
|
|
- uzp2 X_3.\lanes, TMP3.\lanes, Y_3.\lanes
|
|
- uzp1 Y_3.\lanes, TMP3.\lanes, Y_3.\lanes
|
|
-
|
|
- // Do the cipher rounds
|
|
- mov x6, ROUND_KEYS
|
|
- mov w7, NROUNDS
|
|
-.Lnext_round_\@:
|
|
-.if \decrypting
|
|
- ld1r {ROUND_KEY.\lanes}, [x6]
|
|
- sub x6, x6, #( \n / 8 )
|
|
- _speck_unround_128bytes \n, \lanes
|
|
-.else
|
|
- ld1r {ROUND_KEY.\lanes}, [x6], #( \n / 8 )
|
|
- _speck_round_128bytes \n, \lanes
|
|
-.endif
|
|
- subs w7, w7, #1
|
|
- bne .Lnext_round_\@
|
|
-
|
|
- // Re-interleave the 'x' and 'y' elements of each block
|
|
- zip1 TMP0.\lanes, Y_0.\lanes, X_0.\lanes
|
|
- zip2 Y_0.\lanes, Y_0.\lanes, X_0.\lanes
|
|
- zip1 TMP1.\lanes, Y_1.\lanes, X_1.\lanes
|
|
- zip2 Y_1.\lanes, Y_1.\lanes, X_1.\lanes
|
|
- zip1 TMP2.\lanes, Y_2.\lanes, X_2.\lanes
|
|
- zip2 Y_2.\lanes, Y_2.\lanes, X_2.\lanes
|
|
- zip1 TMP3.\lanes, Y_3.\lanes, X_3.\lanes
|
|
- zip2 Y_3.\lanes, Y_3.\lanes, X_3.\lanes
|
|
-
|
|
- // XOR the encrypted/decrypted blocks with the tweaks calculated earlier
|
|
- eor X_0.16b, TMP0.16b, TWEAKV0.16b
|
|
- eor Y_0.16b, Y_0.16b, TWEAKV1.16b
|
|
- eor X_1.16b, TMP1.16b, TWEAKV2.16b
|
|
- eor Y_1.16b, Y_1.16b, TWEAKV3.16b
|
|
- eor X_2.16b, TMP2.16b, TWEAKV4.16b
|
|
- eor Y_2.16b, Y_2.16b, TWEAKV5.16b
|
|
- eor X_3.16b, TMP3.16b, TWEAKV6.16b
|
|
- eor Y_3.16b, Y_3.16b, TWEAKV7.16b
|
|
- mov TWEAKV0.16b, TWEAKV_NEXT.16b
|
|
-
|
|
- // Store the ciphertext in the destination buffer
|
|
- st1 {X_0.16b-Y_1.16b}, [DST], #64
|
|
- st1 {X_2.16b-Y_3.16b}, [DST], #64
|
|
-
|
|
- // Continue if there are more 128-byte chunks remaining
|
|
- subs NBYTES, NBYTES, #128
|
|
- bne .Lnext_128bytes_\@
|
|
-
|
|
- // Store the next tweak and return
|
|
-.if \n == 64
|
|
- st1 {TWEAKV_NEXT.16b}, [TWEAK]
|
|
-.else
|
|
- st1 {TWEAKV_NEXT.8b}, [TWEAK]
|
|
-.endif
|
|
- ret
|
|
-.endm
|
|
-
|
|
-ENTRY(speck128_xts_encrypt_neon)
|
|
- _speck_xts_crypt n=64, lanes=2d, decrypting=0
|
|
-ENDPROC(speck128_xts_encrypt_neon)
|
|
-
|
|
-ENTRY(speck128_xts_decrypt_neon)
|
|
- _speck_xts_crypt n=64, lanes=2d, decrypting=1
|
|
-ENDPROC(speck128_xts_decrypt_neon)
|
|
-
|
|
-ENTRY(speck64_xts_encrypt_neon)
|
|
- _speck_xts_crypt n=32, lanes=4s, decrypting=0
|
|
-ENDPROC(speck64_xts_encrypt_neon)
|
|
-
|
|
-ENTRY(speck64_xts_decrypt_neon)
|
|
- _speck_xts_crypt n=32, lanes=4s, decrypting=1
|
|
-ENDPROC(speck64_xts_decrypt_neon)
|
|
diff --git a/arch/arm64/crypto/speck-neon-glue.c b/arch/arm64/crypto/speck-neon-glue.c
|
|
deleted file mode 100644
|
|
index 6e233aeb4ff4..000000000000
|
|
--- a/arch/arm64/crypto/speck-neon-glue.c
|
|
+++ /dev/null
|
|
@@ -1,282 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
|
|
- * (64-bit version; based on the 32-bit version)
|
|
- *
|
|
- * Copyright (c) 2018 Google, Inc
|
|
- */
|
|
-
|
|
-#include <asm/hwcap.h>
|
|
-#include <asm/neon.h>
|
|
-#include <asm/simd.h>
|
|
-#include <crypto/algapi.h>
|
|
-#include <crypto/gf128mul.h>
|
|
-#include <crypto/internal/skcipher.h>
|
|
-#include <crypto/speck.h>
|
|
-#include <crypto/xts.h>
|
|
-#include <linux/kernel.h>
|
|
-#include <linux/module.h>
|
|
-
|
|
-/* The assembly functions only handle multiples of 128 bytes */
|
|
-#define SPECK_NEON_CHUNK_SIZE 128
|
|
-
|
|
-/* Speck128 */
|
|
-
|
|
-struct speck128_xts_tfm_ctx {
|
|
- struct speck128_tfm_ctx main_key;
|
|
- struct speck128_tfm_ctx tweak_key;
|
|
-};
|
|
-
|
|
-asmlinkage void speck128_xts_encrypt_neon(const u64 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-asmlinkage void speck128_xts_decrypt_neon(const u64 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-typedef void (*speck128_crypt_one_t)(const struct speck128_tfm_ctx *,
|
|
- u8 *, const u8 *);
|
|
-typedef void (*speck128_xts_crypt_many_t)(const u64 *, int, void *,
|
|
- const void *, unsigned int, void *);
|
|
-
|
|
-static __always_inline int
|
|
-__speck128_xts_crypt(struct skcipher_request *req,
|
|
- speck128_crypt_one_t crypt_one,
|
|
- speck128_xts_crypt_many_t crypt_many)
|
|
-{
|
|
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
|
- const struct speck128_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- struct skcipher_walk walk;
|
|
- le128 tweak;
|
|
- int err;
|
|
-
|
|
- err = skcipher_walk_virt(&walk, req, true);
|
|
-
|
|
- crypto_speck128_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
|
|
-
|
|
- while (walk.nbytes > 0) {
|
|
- unsigned int nbytes = walk.nbytes;
|
|
- u8 *dst = walk.dst.virt.addr;
|
|
- const u8 *src = walk.src.virt.addr;
|
|
-
|
|
- if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
|
|
- unsigned int count;
|
|
-
|
|
- count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
|
|
- kernel_neon_begin();
|
|
- (*crypt_many)(ctx->main_key.round_keys,
|
|
- ctx->main_key.nrounds,
|
|
- dst, src, count, &tweak);
|
|
- kernel_neon_end();
|
|
- dst += count;
|
|
- src += count;
|
|
- nbytes -= count;
|
|
- }
|
|
-
|
|
- /* Handle any remainder with generic code */
|
|
- while (nbytes >= sizeof(tweak)) {
|
|
- le128_xor((le128 *)dst, (const le128 *)src, &tweak);
|
|
- (*crypt_one)(&ctx->main_key, dst, dst);
|
|
- le128_xor((le128 *)dst, (const le128 *)dst, &tweak);
|
|
- gf128mul_x_ble(&tweak, &tweak);
|
|
-
|
|
- dst += sizeof(tweak);
|
|
- src += sizeof(tweak);
|
|
- nbytes -= sizeof(tweak);
|
|
- }
|
|
- err = skcipher_walk_done(&walk, nbytes);
|
|
- }
|
|
-
|
|
- return err;
|
|
-}
|
|
-
|
|
-static int speck128_xts_encrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck128_xts_crypt(req, crypto_speck128_encrypt,
|
|
- speck128_xts_encrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck128_xts_decrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck128_xts_crypt(req, crypto_speck128_decrypt,
|
|
- speck128_xts_decrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck128_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- struct speck128_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- int err;
|
|
-
|
|
- err = xts_verify_key(tfm, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- keylen /= 2;
|
|
-
|
|
- err = crypto_speck128_setkey(&ctx->main_key, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- return crypto_speck128_setkey(&ctx->tweak_key, key + keylen, keylen);
|
|
-}
|
|
-
|
|
-/* Speck64 */
|
|
-
|
|
-struct speck64_xts_tfm_ctx {
|
|
- struct speck64_tfm_ctx main_key;
|
|
- struct speck64_tfm_ctx tweak_key;
|
|
-};
|
|
-
|
|
-asmlinkage void speck64_xts_encrypt_neon(const u32 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-asmlinkage void speck64_xts_decrypt_neon(const u32 *round_keys, int nrounds,
|
|
- void *dst, const void *src,
|
|
- unsigned int nbytes, void *tweak);
|
|
-
|
|
-typedef void (*speck64_crypt_one_t)(const struct speck64_tfm_ctx *,
|
|
- u8 *, const u8 *);
|
|
-typedef void (*speck64_xts_crypt_many_t)(const u32 *, int, void *,
|
|
- const void *, unsigned int, void *);
|
|
-
|
|
-static __always_inline int
|
|
-__speck64_xts_crypt(struct skcipher_request *req, speck64_crypt_one_t crypt_one,
|
|
- speck64_xts_crypt_many_t crypt_many)
|
|
-{
|
|
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
|
- const struct speck64_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- struct skcipher_walk walk;
|
|
- __le64 tweak;
|
|
- int err;
|
|
-
|
|
- err = skcipher_walk_virt(&walk, req, true);
|
|
-
|
|
- crypto_speck64_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
|
|
-
|
|
- while (walk.nbytes > 0) {
|
|
- unsigned int nbytes = walk.nbytes;
|
|
- u8 *dst = walk.dst.virt.addr;
|
|
- const u8 *src = walk.src.virt.addr;
|
|
-
|
|
- if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
|
|
- unsigned int count;
|
|
-
|
|
- count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
|
|
- kernel_neon_begin();
|
|
- (*crypt_many)(ctx->main_key.round_keys,
|
|
- ctx->main_key.nrounds,
|
|
- dst, src, count, &tweak);
|
|
- kernel_neon_end();
|
|
- dst += count;
|
|
- src += count;
|
|
- nbytes -= count;
|
|
- }
|
|
-
|
|
- /* Handle any remainder with generic code */
|
|
- while (nbytes >= sizeof(tweak)) {
|
|
- *(__le64 *)dst = *(__le64 *)src ^ tweak;
|
|
- (*crypt_one)(&ctx->main_key, dst, dst);
|
|
- *(__le64 *)dst ^= tweak;
|
|
- tweak = cpu_to_le64((le64_to_cpu(tweak) << 1) ^
|
|
- ((tweak & cpu_to_le64(1ULL << 63)) ?
|
|
- 0x1B : 0));
|
|
- dst += sizeof(tweak);
|
|
- src += sizeof(tweak);
|
|
- nbytes -= sizeof(tweak);
|
|
- }
|
|
- err = skcipher_walk_done(&walk, nbytes);
|
|
- }
|
|
-
|
|
- return err;
|
|
-}
|
|
-
|
|
-static int speck64_xts_encrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck64_xts_crypt(req, crypto_speck64_encrypt,
|
|
- speck64_xts_encrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck64_xts_decrypt(struct skcipher_request *req)
|
|
-{
|
|
- return __speck64_xts_crypt(req, crypto_speck64_decrypt,
|
|
- speck64_xts_decrypt_neon);
|
|
-}
|
|
-
|
|
-static int speck64_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- struct speck64_xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
- int err;
|
|
-
|
|
- err = xts_verify_key(tfm, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- keylen /= 2;
|
|
-
|
|
- err = crypto_speck64_setkey(&ctx->main_key, key, keylen);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- return crypto_speck64_setkey(&ctx->tweak_key, key + keylen, keylen);
|
|
-}
|
|
-
|
|
-static struct skcipher_alg speck_algs[] = {
|
|
- {
|
|
- .base.cra_name = "xts(speck128)",
|
|
- .base.cra_driver_name = "xts-speck128-neon",
|
|
- .base.cra_priority = 300,
|
|
- .base.cra_blocksize = SPECK128_BLOCK_SIZE,
|
|
- .base.cra_ctxsize = sizeof(struct speck128_xts_tfm_ctx),
|
|
- .base.cra_alignmask = 7,
|
|
- .base.cra_module = THIS_MODULE,
|
|
- .min_keysize = 2 * SPECK128_128_KEY_SIZE,
|
|
- .max_keysize = 2 * SPECK128_256_KEY_SIZE,
|
|
- .ivsize = SPECK128_BLOCK_SIZE,
|
|
- .walksize = SPECK_NEON_CHUNK_SIZE,
|
|
- .setkey = speck128_xts_setkey,
|
|
- .encrypt = speck128_xts_encrypt,
|
|
- .decrypt = speck128_xts_decrypt,
|
|
- }, {
|
|
- .base.cra_name = "xts(speck64)",
|
|
- .base.cra_driver_name = "xts-speck64-neon",
|
|
- .base.cra_priority = 300,
|
|
- .base.cra_blocksize = SPECK64_BLOCK_SIZE,
|
|
- .base.cra_ctxsize = sizeof(struct speck64_xts_tfm_ctx),
|
|
- .base.cra_alignmask = 7,
|
|
- .base.cra_module = THIS_MODULE,
|
|
- .min_keysize = 2 * SPECK64_96_KEY_SIZE,
|
|
- .max_keysize = 2 * SPECK64_128_KEY_SIZE,
|
|
- .ivsize = SPECK64_BLOCK_SIZE,
|
|
- .walksize = SPECK_NEON_CHUNK_SIZE,
|
|
- .setkey = speck64_xts_setkey,
|
|
- .encrypt = speck64_xts_encrypt,
|
|
- .decrypt = speck64_xts_decrypt,
|
|
- }
|
|
-};
|
|
-
|
|
-static int __init speck_neon_module_init(void)
|
|
-{
|
|
- if (!(elf_hwcap & HWCAP_ASIMD))
|
|
- return -ENODEV;
|
|
- return crypto_register_skciphers(speck_algs, ARRAY_SIZE(speck_algs));
|
|
-}
|
|
-
|
|
-static void __exit speck_neon_module_exit(void)
|
|
-{
|
|
- crypto_unregister_skciphers(speck_algs, ARRAY_SIZE(speck_algs));
|
|
-}
|
|
-
|
|
-module_init(speck_neon_module_init);
|
|
-module_exit(speck_neon_module_exit);
|
|
-
|
|
-MODULE_DESCRIPTION("Speck block cipher (NEON-accelerated)");
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
|
|
-MODULE_ALIAS_CRYPTO("xts(speck128)");
|
|
-MODULE_ALIAS_CRYPTO("xts-speck128-neon");
|
|
-MODULE_ALIAS_CRYPTO("xts(speck64)");
|
|
-MODULE_ALIAS_CRYPTO("xts-speck64-neon");
|
|
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
|
|
index e238b7932096..93f69d82225d 100644
|
|
--- a/arch/arm64/kernel/cpufeature.c
|
|
+++ b/arch/arm64/kernel/cpufeature.c
|
|
@@ -848,15 +848,29 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus
|
|
}
|
|
|
|
static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
|
|
- int __unused)
|
|
+ int scope)
|
|
{
|
|
- return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_IDC_SHIFT);
|
|
+ u64 ctr;
|
|
+
|
|
+ if (scope == SCOPE_SYSTEM)
|
|
+ ctr = arm64_ftr_reg_ctrel0.sys_val;
|
|
+ else
|
|
+ ctr = read_cpuid_cachetype();
|
|
+
|
|
+ return ctr & BIT(CTR_IDC_SHIFT);
|
|
}
|
|
|
|
static bool has_cache_dic(const struct arm64_cpu_capabilities *entry,
|
|
- int __unused)
|
|
+ int scope)
|
|
{
|
|
- return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT);
|
|
+ u64 ctr;
|
|
+
|
|
+ if (scope == SCOPE_SYSTEM)
|
|
+ ctr = arm64_ftr_reg_ctrel0.sys_val;
|
|
+ else
|
|
+ ctr = read_cpuid_cachetype();
|
|
+
|
|
+ return ctr & BIT(CTR_DIC_SHIFT);
|
|
}
|
|
|
|
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
|
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
|
|
index 09dbea221a27..8556876c9109 100644
|
|
--- a/arch/arm64/kernel/entry.S
|
|
+++ b/arch/arm64/kernel/entry.S
|
|
@@ -589,7 +589,7 @@ el1_undef:
|
|
inherit_daif pstate=x23, tmp=x2
|
|
mov x0, sp
|
|
bl do_undefinstr
|
|
- ASM_BUG()
|
|
+ kernel_exit 1
|
|
el1_dbg:
|
|
/*
|
|
* Debug exception handling
|
|
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
|
|
index 039e9ff379cc..b9da093e0341 100644
|
|
--- a/arch/arm64/kernel/traps.c
|
|
+++ b/arch/arm64/kernel/traps.c
|
|
@@ -310,10 +310,12 @@ static int call_undef_hook(struct pt_regs *regs)
|
|
int (*fn)(struct pt_regs *regs, u32 instr) = NULL;
|
|
void __user *pc = (void __user *)instruction_pointer(regs);
|
|
|
|
- if (!user_mode(regs))
|
|
- return 1;
|
|
-
|
|
- if (compat_thumb_mode(regs)) {
|
|
+ if (!user_mode(regs)) {
|
|
+ __le32 instr_le;
|
|
+ if (probe_kernel_address((__force __le32 *)pc, instr_le))
|
|
+ goto exit;
|
|
+ instr = le32_to_cpu(instr_le);
|
|
+ } else if (compat_thumb_mode(regs)) {
|
|
/* 16-bit Thumb instruction */
|
|
__le16 instr_le;
|
|
if (get_user(instr_le, (__le16 __user *)pc))
|
|
@@ -407,6 +409,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
|
|
return;
|
|
|
|
force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc);
|
|
+ BUG_ON(!user_mode(regs));
|
|
}
|
|
|
|
void cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused)
|
|
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
|
|
index 68755fd70dcf..5df2d611b77d 100644
|
|
--- a/arch/arm64/lib/Makefile
|
|
+++ b/arch/arm64/lib/Makefile
|
|
@@ -12,7 +12,7 @@ lib-y := clear_user.o delay.o copy_from_user.o \
|
|
# when supported by the CPU. Result and argument registers are handled
|
|
# correctly, based on the function prototype.
|
|
lib-$(CONFIG_ARM64_LSE_ATOMICS) += atomic_ll_sc.o
|
|
-CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2 \
|
|
+CFLAGS_atomic_ll_sc.o := -ffixed-x1 -ffixed-x2 \
|
|
-ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 \
|
|
-ffixed-x7 -fcall-saved-x8 -fcall-saved-x9 \
|
|
-fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12 \
|
|
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
|
|
index 1d5483f6e457..93a3c3c0238c 100644
|
|
--- a/arch/m68k/configs/amiga_defconfig
|
|
+++ b/arch/m68k/configs/amiga_defconfig
|
|
@@ -657,7 +657,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
|
|
index 52a0af127951..e3d0efd6397d 100644
|
|
--- a/arch/m68k/configs/apollo_defconfig
|
|
+++ b/arch/m68k/configs/apollo_defconfig
|
|
@@ -614,7 +614,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
|
|
index b3103e51268a..75ac0c76e884 100644
|
|
--- a/arch/m68k/configs/atari_defconfig
|
|
+++ b/arch/m68k/configs/atari_defconfig
|
|
@@ -635,7 +635,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
|
|
index fb7d651a4cab..c6e492700188 100644
|
|
--- a/arch/m68k/configs/bvme6000_defconfig
|
|
+++ b/arch/m68k/configs/bvme6000_defconfig
|
|
@@ -606,7 +606,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
|
|
index 6b37f5537c39..b00d1c477432 100644
|
|
--- a/arch/m68k/configs/hp300_defconfig
|
|
+++ b/arch/m68k/configs/hp300_defconfig
|
|
@@ -616,7 +616,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
|
|
index c717bf879449..85cac3770d89 100644
|
|
--- a/arch/m68k/configs/mac_defconfig
|
|
+++ b/arch/m68k/configs/mac_defconfig
|
|
@@ -638,7 +638,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
|
|
index 226c994ce794..b3a5d1e99d27 100644
|
|
--- a/arch/m68k/configs/multi_defconfig
|
|
+++ b/arch/m68k/configs/multi_defconfig
|
|
@@ -720,7 +720,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
|
|
index b383327fd77a..0ca22608453f 100644
|
|
--- a/arch/m68k/configs/mvme147_defconfig
|
|
+++ b/arch/m68k/configs/mvme147_defconfig
|
|
@@ -606,7 +606,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
|
|
index 9783d3deb9e9..8e3d10d12d9c 100644
|
|
--- a/arch/m68k/configs/mvme16x_defconfig
|
|
+++ b/arch/m68k/configs/mvme16x_defconfig
|
|
@@ -606,7 +606,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
|
|
index a35d10ee10cb..ff7e653ec7fa 100644
|
|
--- a/arch/m68k/configs/q40_defconfig
|
|
+++ b/arch/m68k/configs/q40_defconfig
|
|
@@ -629,7 +629,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
|
|
index 573bf922d448..612cf46f6d0c 100644
|
|
--- a/arch/m68k/configs/sun3_defconfig
|
|
+++ b/arch/m68k/configs/sun3_defconfig
|
|
@@ -607,7 +607,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
|
|
index efb27a7fcc55..a6a7bb6dc3fd 100644
|
|
--- a/arch/m68k/configs/sun3x_defconfig
|
|
+++ b/arch/m68k/configs/sun3x_defconfig
|
|
@@ -608,7 +608,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_LZO=m
|
|
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
|
index 75108ec669eb..6c79e8a16a26 100644
|
|
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
|
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
|
|
@@ -67,7 +67,7 @@ void (*cvmx_override_pko_queue_priority) (int pko_port,
|
|
void (*cvmx_override_ipd_port_setup) (int ipd_port);
|
|
|
|
/* Port count per interface */
|
|
-static int interface_port_count[5];
|
|
+static int interface_port_count[9];
|
|
|
|
/**
|
|
* Return the number of interfaces the chip has. Each interface
|
|
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
|
|
index 49d6046ca1d0..c373eb605040 100644
|
|
--- a/arch/mips/include/asm/processor.h
|
|
+++ b/arch/mips/include/asm/processor.h
|
|
@@ -81,7 +81,7 @@ extern unsigned int vced_count, vcei_count;
|
|
|
|
#endif
|
|
|
|
-#define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_256M)
|
|
+#define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_64M)
|
|
|
|
extern unsigned long mips_stack_top(void);
|
|
#define STACK_TOP mips_stack_top()
|
|
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
|
|
index 242c5ab65611..d2f92273fe37 100644
|
|
--- a/arch/parisc/kernel/entry.S
|
|
+++ b/arch/parisc/kernel/entry.S
|
|
@@ -186,7 +186,7 @@
|
|
bv,n 0(%r3)
|
|
nop
|
|
.word 0 /* checksum (will be patched) */
|
|
- .word PA(os_hpmc) /* address of handler */
|
|
+ .word 0 /* address of handler */
|
|
.word 0 /* length of handler */
|
|
.endm
|
|
|
|
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
|
|
index 781c3b9a3e46..fde654115564 100644
|
|
--- a/arch/parisc/kernel/hpmc.S
|
|
+++ b/arch/parisc/kernel/hpmc.S
|
|
@@ -85,7 +85,7 @@ END(hpmc_pim_data)
|
|
|
|
.import intr_save, code
|
|
.align 16
|
|
-ENTRY_CFI(os_hpmc)
|
|
+ENTRY(os_hpmc)
|
|
.os_hpmc:
|
|
|
|
/*
|
|
@@ -302,7 +302,6 @@ os_hpmc_6:
|
|
b .
|
|
nop
|
|
.align 16 /* make function length multiple of 16 bytes */
|
|
-ENDPROC_CFI(os_hpmc)
|
|
.os_hpmc_end:
|
|
|
|
|
|
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
|
|
index 68f10f87073d..abeb5321a83f 100644
|
|
--- a/arch/parisc/kernel/traps.c
|
|
+++ b/arch/parisc/kernel/traps.c
|
|
@@ -802,7 +802,8 @@ void __init initialize_ivt(const void *iva)
|
|
* the Length/4 words starting at Address is zero.
|
|
*/
|
|
|
|
- /* Compute Checksum for HPMC handler */
|
|
+ /* Setup IVA and compute checksum for HPMC handler */
|
|
+ ivap[6] = (u32)__pa(os_hpmc);
|
|
length = os_hpmc_size;
|
|
ivap[7] = length;
|
|
|
|
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
|
|
index 74842d28a7a1..aae9b0d71c1e 100644
|
|
--- a/arch/parisc/mm/init.c
|
|
+++ b/arch/parisc/mm/init.c
|
|
@@ -494,12 +494,8 @@ static void __init map_pages(unsigned long start_vaddr,
|
|
pte = pte_mkhuge(pte);
|
|
}
|
|
|
|
- if (address >= end_paddr) {
|
|
- if (force)
|
|
- break;
|
|
- else
|
|
- pte_val(pte) = 0;
|
|
- }
|
|
+ if (address >= end_paddr)
|
|
+ break;
|
|
|
|
set_pte(pg_table, pte);
|
|
|
|
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
|
|
index fad8ddd697ac..0abf2e7fd222 100644
|
|
--- a/arch/powerpc/include/asm/mpic.h
|
|
+++ b/arch/powerpc/include/asm/mpic.h
|
|
@@ -393,7 +393,14 @@ extern struct bus_type mpic_subsys;
|
|
#define MPIC_REGSET_TSI108 MPIC_REGSET(1) /* Tsi108/109 PIC */
|
|
|
|
/* Get the version of primary MPIC */
|
|
+#ifdef CONFIG_MPIC
|
|
extern u32 fsl_mpic_primary_get_version(void);
|
|
+#else
|
|
+static inline u32 fsl_mpic_primary_get_version(void)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
|
|
/* Allocate the controller structure and setup the linux irq descs
|
|
* for the range if interrupts passed in. No HW initialization is
|
|
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
|
|
index 3497c8329c1d..3022d67f0c48 100644
|
|
--- a/arch/powerpc/kernel/mce_power.c
|
|
+++ b/arch/powerpc/kernel/mce_power.c
|
|
@@ -89,6 +89,13 @@ static void flush_and_reload_slb(void)
|
|
|
|
static void flush_erat(void)
|
|
{
|
|
+#ifdef CONFIG_PPC_BOOK3S_64
|
|
+ if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
|
|
+ flush_and_reload_slb();
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+ /* PPC_INVALIDATE_ERAT can only be used on ISA v3 and newer */
|
|
asm volatile(PPC_INVALIDATE_ERAT : : :"memory");
|
|
}
|
|
|
|
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
|
|
index 77371c9ef3d8..2d861a36662e 100644
|
|
--- a/arch/powerpc/kernel/module.c
|
|
+++ b/arch/powerpc/kernel/module.c
|
|
@@ -74,6 +74,14 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|
(void *)sect->sh_addr + sect->sh_size);
|
|
#endif /* CONFIG_PPC64 */
|
|
|
|
+#ifdef PPC64_ELF_ABI_v1
|
|
+ sect = find_section(hdr, sechdrs, ".opd");
|
|
+ if (sect != NULL) {
|
|
+ me->arch.start_opd = sect->sh_addr;
|
|
+ me->arch.end_opd = sect->sh_addr + sect->sh_size;
|
|
+ }
|
|
+#endif /* PPC64_ELF_ABI_v1 */
|
|
+
|
|
#ifdef CONFIG_PPC_BARRIER_NOSPEC
|
|
sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
|
|
if (sect != NULL)
|
|
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
|
|
index b8d61e019d06..2c53de9f3b6a 100644
|
|
--- a/arch/powerpc/kernel/module_64.c
|
|
+++ b/arch/powerpc/kernel/module_64.c
|
|
@@ -360,11 +360,6 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
|
|
else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
|
|
dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
|
|
sechdrs[i].sh_size);
|
|
- else if (!strcmp(secstrings + sechdrs[i].sh_name, ".opd")) {
|
|
- me->arch.start_opd = sechdrs[i].sh_addr;
|
|
- me->arch.end_opd = sechdrs[i].sh_addr +
|
|
- sechdrs[i].sh_size;
|
|
- }
|
|
|
|
/* We don't handle .init for the moment: rename to _init */
|
|
while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
|
|
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
|
|
index 6a501b25dd85..faf00222b324 100644
|
|
--- a/arch/powerpc/kernel/setup_64.c
|
|
+++ b/arch/powerpc/kernel/setup_64.c
|
|
@@ -243,13 +243,19 @@ static void cpu_ready_for_interrupts(void)
|
|
}
|
|
|
|
/*
|
|
- * Fixup HFSCR:TM based on CPU features. The bit is set by our
|
|
- * early asm init because at that point we haven't updated our
|
|
- * CPU features from firmware and device-tree. Here we have,
|
|
- * so let's do it.
|
|
+ * Set HFSCR:TM based on CPU features:
|
|
+ * In the special case of TM no suspend (P9N DD2.1), Linux is
|
|
+ * told TM is off via the dt-ftrs but told to (partially) use
|
|
+ * it via OPAL_REINIT_CPUS_TM_SUSPEND_DISABLED. So HFSCR[TM]
|
|
+ * will be off from dt-ftrs but we need to turn it on for the
|
|
+ * no suspend case.
|
|
*/
|
|
- if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP))
|
|
- mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM);
|
|
+ if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
|
+ if (cpu_has_feature(CPU_FTR_TM_COMP))
|
|
+ mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) | HFSCR_TM);
|
|
+ else
|
|
+ mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM);
|
|
+ }
|
|
|
|
/* Set IR and DR in PACA MSR */
|
|
get_paca()->kernel_msr = MSR_KERNEL;
|
|
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
|
|
index 729f02df8290..aaa28fd918fe 100644
|
|
--- a/arch/powerpc/mm/hash_native_64.c
|
|
+++ b/arch/powerpc/mm/hash_native_64.c
|
|
@@ -115,6 +115,8 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
|
|
tlbiel_hash_set_isa300(0, is, 0, 2, 1);
|
|
|
|
asm volatile("ptesync": : :"memory");
|
|
+
|
|
+ asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
|
|
}
|
|
|
|
void hash__tlbiel_all(unsigned int action)
|
|
@@ -140,8 +142,6 @@ void hash__tlbiel_all(unsigned int action)
|
|
tlbiel_all_isa206(POWER7_TLB_SETS, is);
|
|
else
|
|
WARN(1, "%s called on pre-POWER7 CPU\n", __func__);
|
|
-
|
|
- asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
|
|
}
|
|
|
|
static inline unsigned long ___tlbie(unsigned long vpn, int psize,
|
|
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
|
|
index f40600eb1762..5134c71a4937 100644
|
|
--- a/arch/s390/defconfig
|
|
+++ b/arch/s390/defconfig
|
|
@@ -221,7 +221,6 @@ CONFIG_CRYPTO_SALSA20=m
|
|
CONFIG_CRYPTO_SEED=m
|
|
CONFIG_CRYPTO_SERPENT=m
|
|
CONFIG_CRYPTO_SM4=m
|
|
-CONFIG_CRYPTO_SPECK=m
|
|
CONFIG_CRYPTO_TEA=m
|
|
CONFIG_CRYPTO_TWOFISH=m
|
|
CONFIG_CRYPTO_DEFLATE=m
|
|
diff --git a/arch/s390/kernel/sthyi.c b/arch/s390/kernel/sthyi.c
|
|
index 0859cde36f75..888cc2f166db 100644
|
|
--- a/arch/s390/kernel/sthyi.c
|
|
+++ b/arch/s390/kernel/sthyi.c
|
|
@@ -183,17 +183,19 @@ static void fill_hdr(struct sthyi_sctns *sctns)
|
|
static void fill_stsi_mac(struct sthyi_sctns *sctns,
|
|
struct sysinfo_1_1_1 *sysinfo)
|
|
{
|
|
+ sclp_ocf_cpc_name_copy(sctns->mac.infmname);
|
|
+ if (*(u64 *)sctns->mac.infmname != 0)
|
|
+ sctns->mac.infmval1 |= MAC_NAME_VLD;
|
|
+
|
|
if (stsi(sysinfo, 1, 1, 1))
|
|
return;
|
|
|
|
- sclp_ocf_cpc_name_copy(sctns->mac.infmname);
|
|
-
|
|
memcpy(sctns->mac.infmtype, sysinfo->type, sizeof(sctns->mac.infmtype));
|
|
memcpy(sctns->mac.infmmanu, sysinfo->manufacturer, sizeof(sctns->mac.infmmanu));
|
|
memcpy(sctns->mac.infmpman, sysinfo->plant, sizeof(sctns->mac.infmpman));
|
|
memcpy(sctns->mac.infmseq, sysinfo->sequence, sizeof(sctns->mac.infmseq));
|
|
|
|
- sctns->mac.infmval1 |= MAC_ID_VLD | MAC_NAME_VLD;
|
|
+ sctns->mac.infmval1 |= MAC_ID_VLD;
|
|
}
|
|
|
|
static void fill_stsi_par(struct sthyi_sctns *sctns,
|
|
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
|
|
index 1458b1700fc7..8b4c5e001157 100644
|
|
--- a/arch/x86/boot/compressed/eboot.c
|
|
+++ b/arch/x86/boot/compressed/eboot.c
|
|
@@ -738,6 +738,7 @@ efi_main(struct efi_config *c, struct boot_params *boot_params)
|
|
struct desc_struct *desc;
|
|
void *handle;
|
|
efi_system_table_t *_table;
|
|
+ unsigned long cmdline_paddr;
|
|
|
|
efi_early = c;
|
|
|
|
@@ -755,6 +756,15 @@ efi_main(struct efi_config *c, struct boot_params *boot_params)
|
|
else
|
|
setup_boot_services32(efi_early);
|
|
|
|
+ /*
|
|
+ * make_boot_params() may have been called before efi_main(), in which
|
|
+ * case this is the second time we parse the cmdline. This is ok,
|
|
+ * parsing the cmdline multiple times does not have side-effects.
|
|
+ */
|
|
+ cmdline_paddr = ((u64)hdr->cmd_line_ptr |
|
|
+ ((u64)boot_params->ext_cmd_line_ptr << 32));
|
|
+ efi_parse_options((char *)cmdline_paddr);
|
|
+
|
|
/*
|
|
* If the boot loader gave us a value for secure_boot then we use that,
|
|
* otherwise we ask the BIOS.
|
|
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
|
|
index d4e6cd4577e5..bf0e82400358 100644
|
|
--- a/arch/x86/boot/tools/build.c
|
|
+++ b/arch/x86/boot/tools/build.c
|
|
@@ -391,6 +391,13 @@ int main(int argc, char ** argv)
|
|
die("Unable to mmap '%s': %m", argv[2]);
|
|
/* Number of 16-byte paragraphs, including space for a 4-byte CRC */
|
|
sys_size = (sz + 15 + 4) / 16;
|
|
+#ifdef CONFIG_EFI_STUB
|
|
+ /*
|
|
+ * COFF requires minimum 32-byte alignment of sections, and
|
|
+ * adding a signature is problematic without that alignment.
|
|
+ */
|
|
+ sys_size = (sys_size + 1) & ~1;
|
|
+#endif
|
|
|
|
/* Patch the setup code with the appropriate size parameters */
|
|
buf[0x1f1] = setup_sectors-1;
|
|
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
|
|
index acbe7e8336d8..e4b78f962874 100644
|
|
--- a/arch/x86/crypto/aesni-intel_glue.c
|
|
+++ b/arch/x86/crypto/aesni-intel_glue.c
|
|
@@ -817,7 +817,7 @@ static int gcmaes_crypt_by_sg(bool enc, struct aead_request *req,
|
|
/* Linearize assoc, if not already linear */
|
|
if (req->src->length >= assoclen && req->src->length &&
|
|
(!PageHighMem(sg_page(req->src)) ||
|
|
- req->src->offset + req->src->length < PAGE_SIZE)) {
|
|
+ req->src->offset + req->src->length <= PAGE_SIZE)) {
|
|
scatterwalk_start(&assoc_sg_walk, req->src);
|
|
assoc = scatterwalk_map(&assoc_sg_walk);
|
|
} else {
|
|
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
|
|
index 09b2e3e2cf1b..1c09a0d1771f 100644
|
|
--- a/arch/x86/include/asm/kvm_host.h
|
|
+++ b/arch/x86/include/asm/kvm_host.h
|
|
@@ -177,6 +177,7 @@ enum {
|
|
|
|
#define DR6_BD (1 << 13)
|
|
#define DR6_BS (1 << 14)
|
|
+#define DR6_BT (1 << 15)
|
|
#define DR6_RTM (1 << 16)
|
|
#define DR6_FIXED_1 0xfffe0ff0
|
|
#define DR6_INIT 0xffff0ff0
|
|
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
|
|
index 58ce5288878e..0e2130d8d6b1 100644
|
|
--- a/arch/x86/include/asm/tlbflush.h
|
|
+++ b/arch/x86/include/asm/tlbflush.h
|
|
@@ -469,6 +469,12 @@ static inline void __native_flush_tlb_one_user(unsigned long addr)
|
|
*/
|
|
static inline void __flush_tlb_all(void)
|
|
{
|
|
+ /*
|
|
+ * This is to catch users with enabled preemption and the PGE feature
|
|
+ * and don't trigger the warning in __native_flush_tlb().
|
|
+ */
|
|
+ VM_WARN_ON_ONCE(preemptible());
|
|
+
|
|
if (boot_cpu_has(X86_FEATURE_PGE)) {
|
|
__flush_tlb_global();
|
|
} else {
|
|
diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c
|
|
index 33399426793e..cc8258a5378b 100644
|
|
--- a/arch/x86/kernel/check.c
|
|
+++ b/arch/x86/kernel/check.c
|
|
@@ -31,6 +31,11 @@ static __init int set_corruption_check(char *arg)
|
|
ssize_t ret;
|
|
unsigned long val;
|
|
|
|
+ if (!arg) {
|
|
+ pr_err("memory_corruption_check config string not provided\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
ret = kstrtoul(arg, 10, &val);
|
|
if (ret)
|
|
return ret;
|
|
@@ -45,6 +50,11 @@ static __init int set_corruption_check_period(char *arg)
|
|
ssize_t ret;
|
|
unsigned long val;
|
|
|
|
+ if (!arg) {
|
|
+ pr_err("memory_corruption_check_period config string not provided\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
ret = kstrtoul(arg, 10, &val);
|
|
if (ret)
|
|
return ret;
|
|
@@ -59,6 +69,11 @@ static __init int set_corruption_check_size(char *arg)
|
|
char *end;
|
|
unsigned size;
|
|
|
|
+ if (!arg) {
|
|
+ pr_err("memory_corruption_check_size config string not provided\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
size = memparse(arg, &end);
|
|
|
|
if (*end == '\0')
|
|
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
|
|
index 40bdaea97fe7..53eb14a65610 100644
|
|
--- a/arch/x86/kernel/cpu/bugs.c
|
|
+++ b/arch/x86/kernel/cpu/bugs.c
|
|
@@ -35,12 +35,10 @@ static void __init spectre_v2_select_mitigation(void);
|
|
static void __init ssb_select_mitigation(void);
|
|
static void __init l1tf_select_mitigation(void);
|
|
|
|
-/*
|
|
- * Our boot-time value of the SPEC_CTRL MSR. We read it once so that any
|
|
- * writes to SPEC_CTRL contain whatever reserved bits have been set.
|
|
- */
|
|
-u64 __ro_after_init x86_spec_ctrl_base;
|
|
+/* The base value of the SPEC_CTRL MSR that always has to be preserved. */
|
|
+u64 x86_spec_ctrl_base;
|
|
EXPORT_SYMBOL_GPL(x86_spec_ctrl_base);
|
|
+static DEFINE_MUTEX(spec_ctrl_mutex);
|
|
|
|
/*
|
|
* The vendor and possibly platform specific bits which can be modified in
|
|
@@ -325,6 +323,46 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
|
|
return cmd;
|
|
}
|
|
|
|
+static bool stibp_needed(void)
|
|
+{
|
|
+ if (spectre_v2_enabled == SPECTRE_V2_NONE)
|
|
+ return false;
|
|
+
|
|
+ if (!boot_cpu_has(X86_FEATURE_STIBP))
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static void update_stibp_msr(void *info)
|
|
+{
|
|
+ wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
|
|
+}
|
|
+
|
|
+void arch_smt_update(void)
|
|
+{
|
|
+ u64 mask;
|
|
+
|
|
+ if (!stibp_needed())
|
|
+ return;
|
|
+
|
|
+ mutex_lock(&spec_ctrl_mutex);
|
|
+ mask = x86_spec_ctrl_base;
|
|
+ if (cpu_smt_control == CPU_SMT_ENABLED)
|
|
+ mask |= SPEC_CTRL_STIBP;
|
|
+ else
|
|
+ mask &= ~SPEC_CTRL_STIBP;
|
|
+
|
|
+ if (mask != x86_spec_ctrl_base) {
|
|
+ pr_info("Spectre v2 cross-process SMT mitigation: %s STIBP\n",
|
|
+ cpu_smt_control == CPU_SMT_ENABLED ?
|
|
+ "Enabling" : "Disabling");
|
|
+ x86_spec_ctrl_base = mask;
|
|
+ on_each_cpu(update_stibp_msr, NULL, 1);
|
|
+ }
|
|
+ mutex_unlock(&spec_ctrl_mutex);
|
|
+}
|
|
+
|
|
static void __init spectre_v2_select_mitigation(void)
|
|
{
|
|
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
|
|
@@ -424,6 +462,9 @@ specv2_set_mode:
|
|
setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
|
|
pr_info("Enabling Restricted Speculation for firmware calls\n");
|
|
}
|
|
+
|
|
+ /* Enable STIBP if appropriate */
|
|
+ arch_smt_update();
|
|
}
|
|
|
|
#undef pr_fmt
|
|
@@ -814,6 +855,8 @@ static ssize_t l1tf_show_state(char *buf)
|
|
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
|
|
char *buf, unsigned int bug)
|
|
{
|
|
+ int ret;
|
|
+
|
|
if (!boot_cpu_has_bug(bug))
|
|
return sprintf(buf, "Not affected\n");
|
|
|
|
@@ -831,10 +874,12 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
|
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
|
|
|
case X86_BUG_SPECTRE_V2:
|
|
- return sprintf(buf, "%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
|
|
+ ret = sprintf(buf, "%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
|
|
boot_cpu_has(X86_FEATURE_USE_IBPB) ? ", IBPB" : "",
|
|
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
|
|
+ (x86_spec_ctrl_base & SPEC_CTRL_STIBP) ? ", STIBP" : "",
|
|
spectre_v2_module_string());
|
|
+ return ret;
|
|
|
|
case X86_BUG_SPEC_STORE_BYPASS:
|
|
return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
|
|
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
|
|
index b140c68bc14b..643670fb8943 100644
|
|
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
|
|
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
|
|
@@ -2805,6 +2805,13 @@ static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)
|
|
{
|
|
if (rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled)
|
|
seq_puts(seq, ",cdp");
|
|
+
|
|
+ if (rdt_resources_all[RDT_RESOURCE_L2DATA].alloc_enabled)
|
|
+ seq_puts(seq, ",cdpl2");
|
|
+
|
|
+ if (is_mba_sc(&rdt_resources_all[RDT_RESOURCE_MBA]))
|
|
+ seq_puts(seq, ",mba_MBps");
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
|
|
index eaf02f2e7300..40b16b270656 100644
|
|
--- a/arch/x86/kernel/kprobes/opt.c
|
|
+++ b/arch/x86/kernel/kprobes/opt.c
|
|
@@ -179,7 +179,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
|
opt_pre_handler(&op->kp, regs);
|
|
__this_cpu_write(current_kprobe, NULL);
|
|
}
|
|
- preempt_enable_no_resched();
|
|
+ preempt_enable();
|
|
}
|
|
NOKPROBE_SYMBOL(optimized_callback);
|
|
|
|
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
|
index e665aa7167cf..9f3def7baa6d 100644
|
|
--- a/arch/x86/kvm/vmx.c
|
|
+++ b/arch/x86/kvm/vmx.c
|
|
@@ -3294,10 +3294,13 @@ static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned long *exit
|
|
}
|
|
} else {
|
|
if (vmcs12->exception_bitmap & (1u << nr)) {
|
|
- if (nr == DB_VECTOR)
|
|
+ if (nr == DB_VECTOR) {
|
|
*exit_qual = vcpu->arch.dr6;
|
|
- else
|
|
+ *exit_qual &= ~(DR6_FIXED_1 | DR6_BT);
|
|
+ *exit_qual ^= DR6_RTM;
|
|
+ } else {
|
|
*exit_qual = 0;
|
|
+ }
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -14010,13 +14013,6 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
|
|
if (!page_address_valid(vcpu, kvm_state->vmx.vmxon_pa))
|
|
return -EINVAL;
|
|
|
|
- if (kvm_state->size < sizeof(kvm_state) + sizeof(*vmcs12))
|
|
- return -EINVAL;
|
|
-
|
|
- if (kvm_state->vmx.vmcs_pa == kvm_state->vmx.vmxon_pa ||
|
|
- !page_address_valid(vcpu, kvm_state->vmx.vmcs_pa))
|
|
- return -EINVAL;
|
|
-
|
|
if ((kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) &&
|
|
(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE))
|
|
return -EINVAL;
|
|
@@ -14046,6 +14042,14 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ /* Empty 'VMXON' state is permitted */
|
|
+ if (kvm_state->size < sizeof(kvm_state) + sizeof(*vmcs12))
|
|
+ return 0;
|
|
+
|
|
+ if (kvm_state->vmx.vmcs_pa == kvm_state->vmx.vmxon_pa ||
|
|
+ !page_address_valid(vcpu, kvm_state->vmx.vmcs_pa))
|
|
+ return -EINVAL;
|
|
+
|
|
set_current_vmptr(vmx, kvm_state->vmx.vmcs_pa);
|
|
|
|
if (kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON) {
|
|
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
|
|
index b54d52a2d00a..d71d72cf6c66 100644
|
|
--- a/arch/x86/mm/numa_emulation.c
|
|
+++ b/arch/x86/mm/numa_emulation.c
|
|
@@ -400,9 +400,17 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
|
|
n = simple_strtoul(emu_cmdline, &emu_cmdline, 0);
|
|
ret = -1;
|
|
for_each_node_mask(i, physnode_mask) {
|
|
+ /*
|
|
+ * The reason we pass in blk[0] is due to
|
|
+ * numa_remove_memblk_from() called by
|
|
+ * emu_setup_memblk() will delete entry 0
|
|
+ * and then move everything else up in the pi.blk
|
|
+ * array. Therefore we should always be looking
|
|
+ * at blk[0].
|
|
+ */
|
|
ret = split_nodes_size_interleave_uniform(&ei, &pi,
|
|
- pi.blk[i].start, pi.blk[i].end, 0,
|
|
- n, &pi.blk[i], nid);
|
|
+ pi.blk[0].start, pi.blk[0].end, 0,
|
|
+ n, &pi.blk[0], nid);
|
|
if (ret < 0)
|
|
break;
|
|
if (ret < n) {
|
|
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
|
|
index 51a5a69ecac9..e2d4b25c7aa4 100644
|
|
--- a/arch/x86/mm/pageattr.c
|
|
+++ b/arch/x86/mm/pageattr.c
|
|
@@ -2086,9 +2086,13 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
|
|
|
|
/*
|
|
* We should perform an IPI and flush all tlbs,
|
|
- * but that can deadlock->flush only current cpu:
|
|
+ * but that can deadlock->flush only current cpu.
|
|
+ * Preemption needs to be disabled around __flush_tlb_all() due to
|
|
+ * CR3 reload in __native_flush_tlb().
|
|
*/
|
|
+ preempt_disable();
|
|
__flush_tlb_all();
|
|
+ preempt_enable();
|
|
|
|
arch_flush_lazy_mmu_mode();
|
|
}
|
|
diff --git a/arch/x86/platform/olpc/olpc-xo1-rtc.c b/arch/x86/platform/olpc/olpc-xo1-rtc.c
|
|
index a2b4efddd61a..8e7ddd7e313a 100644
|
|
--- a/arch/x86/platform/olpc/olpc-xo1-rtc.c
|
|
+++ b/arch/x86/platform/olpc/olpc-xo1-rtc.c
|
|
@@ -16,6 +16,7 @@
|
|
|
|
#include <asm/msr.h>
|
|
#include <asm/olpc.h>
|
|
+#include <asm/x86_init.h>
|
|
|
|
static void rtc_wake_on(struct device *dev)
|
|
{
|
|
@@ -75,6 +76,8 @@ static int __init xo1_rtc_init(void)
|
|
if (r)
|
|
return r;
|
|
|
|
+ x86_platform.legacy.rtc = 0;
|
|
+
|
|
device_init_wakeup(&xo1_rtc_device.dev, 1);
|
|
return 0;
|
|
}
|
|
diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c
|
|
index c85d1a88f476..f7f77023288a 100644
|
|
--- a/arch/x86/xen/enlighten_pvh.c
|
|
+++ b/arch/x86/xen/enlighten_pvh.c
|
|
@@ -75,7 +75,7 @@ static void __init init_pvh_bootparams(void)
|
|
* Version 2.12 supports Xen entry point but we will use default x86/PC
|
|
* environment (i.e. hardware_subarch 0).
|
|
*/
|
|
- pvh_bootparams.hdr.version = 0x212;
|
|
+ pvh_bootparams.hdr.version = (2 << 8) | 12;
|
|
pvh_bootparams.hdr.type_of_loader = (9 << 4) | 0; /* Xen loader */
|
|
|
|
x86_init.acpi.get_root_pointer = pvh_get_root_pointer;
|
|
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
|
|
index 33a783c77d96..184b36922397 100644
|
|
--- a/arch/x86/xen/platform-pci-unplug.c
|
|
+++ b/arch/x86/xen/platform-pci-unplug.c
|
|
@@ -146,6 +146,10 @@ void xen_unplug_emulated_devices(void)
|
|
{
|
|
int r;
|
|
|
|
+ /* PVH guests don't have emulated devices. */
|
|
+ if (xen_pvh_domain())
|
|
+ return;
|
|
+
|
|
/* user explicitly requested no unplug */
|
|
if (xen_emul_unplug & XEN_UNPLUG_NEVER)
|
|
return;
|
|
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
|
|
index 973f10e05211..717b4847b473 100644
|
|
--- a/arch/x86/xen/spinlock.c
|
|
+++ b/arch/x86/xen/spinlock.c
|
|
@@ -9,6 +9,7 @@
|
|
#include <linux/log2.h>
|
|
#include <linux/gfp.h>
|
|
#include <linux/slab.h>
|
|
+#include <linux/atomic.h>
|
|
|
|
#include <asm/paravirt.h>
|
|
#include <asm/qspinlock.h>
|
|
@@ -21,6 +22,7 @@
|
|
|
|
static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
|
|
static DEFINE_PER_CPU(char *, irq_name);
|
|
+static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);
|
|
static bool xen_pvspin = true;
|
|
|
|
static void xen_qlock_kick(int cpu)
|
|
@@ -40,33 +42,24 @@ static void xen_qlock_kick(int cpu)
|
|
static void xen_qlock_wait(u8 *byte, u8 val)
|
|
{
|
|
int irq = __this_cpu_read(lock_kicker_irq);
|
|
+ atomic_t *nest_cnt = this_cpu_ptr(&xen_qlock_wait_nest);
|
|
|
|
/* If kicker interrupts not initialized yet, just spin */
|
|
- if (irq == -1)
|
|
+ if (irq == -1 || in_nmi())
|
|
return;
|
|
|
|
- /* clear pending */
|
|
- xen_clear_irq_pending(irq);
|
|
- barrier();
|
|
-
|
|
- /*
|
|
- * We check the byte value after clearing pending IRQ to make sure
|
|
- * that we won't miss a wakeup event because of the clearing.
|
|
- *
|
|
- * The sync_clear_bit() call in xen_clear_irq_pending() is atomic.
|
|
- * So it is effectively a memory barrier for x86.
|
|
- */
|
|
- if (READ_ONCE(*byte) != val)
|
|
- return;
|
|
+ /* Detect reentry. */
|
|
+ atomic_inc(nest_cnt);
|
|
|
|
- /*
|
|
- * If an interrupt happens here, it will leave the wakeup irq
|
|
- * pending, which will cause xen_poll_irq() to return
|
|
- * immediately.
|
|
- */
|
|
+ /* If irq pending already and no nested call clear it. */
|
|
+ if (atomic_read(nest_cnt) == 1 && xen_test_irq_pending(irq)) {
|
|
+ xen_clear_irq_pending(irq);
|
|
+ } else if (READ_ONCE(*byte) == val) {
|
|
+ /* Block until irq becomes pending (or a spurious wakeup) */
|
|
+ xen_poll_irq(irq);
|
|
+ }
|
|
|
|
- /* Block until irq becomes pending (or perhaps a spurious wakeup) */
|
|
- xen_poll_irq(irq);
|
|
+ atomic_dec(nest_cnt);
|
|
}
|
|
|
|
static irqreturn_t dummy_handler(int irq, void *dev_id)
|
|
diff --git a/arch/x86/xen/xen-pvh.S b/arch/x86/xen/xen-pvh.S
|
|
index ca2d3b2bf2af..58722a052f9c 100644
|
|
--- a/arch/x86/xen/xen-pvh.S
|
|
+++ b/arch/x86/xen/xen-pvh.S
|
|
@@ -181,7 +181,7 @@ canary:
|
|
.fill 48, 1, 0
|
|
|
|
early_stack:
|
|
- .fill 256, 1, 0
|
|
+ .fill BOOT_STACK_SIZE, 1, 0
|
|
early_stack_end:
|
|
|
|
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,
|
|
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
|
|
index ae52bff43ce4..ff7c2d470bb8 100644
|
|
--- a/block/bfq-wf2q.c
|
|
+++ b/block/bfq-wf2q.c
|
|
@@ -1181,10 +1181,17 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
|
|
st = bfq_entity_service_tree(entity);
|
|
is_in_service = entity == sd->in_service_entity;
|
|
|
|
- if (is_in_service) {
|
|
- bfq_calc_finish(entity, entity->service);
|
|
+ bfq_calc_finish(entity, entity->service);
|
|
+
|
|
+ if (is_in_service)
|
|
sd->in_service_entity = NULL;
|
|
- }
|
|
+ else
|
|
+ /*
|
|
+ * Non in-service entity: nobody will take care of
|
|
+ * resetting its service counter on expiration. Do it
|
|
+ * now.
|
|
+ */
|
|
+ entity->service = 0;
|
|
|
|
if (entity->tree == &st->active)
|
|
bfq_active_extract(st, entity);
|
|
diff --git a/block/blk-lib.c b/block/blk-lib.c
|
|
index bbd44666f2b5..1f196cf0aa5d 100644
|
|
--- a/block/blk-lib.c
|
|
+++ b/block/blk-lib.c
|
|
@@ -58,8 +58,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|
|
|
if (!req_sects)
|
|
goto fail;
|
|
- if (req_sects > UINT_MAX >> 9)
|
|
- req_sects = UINT_MAX >> 9;
|
|
+ req_sects = min(req_sects, bio_allowed_max_sectors(q));
|
|
|
|
end_sect = sector + req_sects;
|
|
|
|
@@ -162,7 +161,7 @@ static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
|
|
return -EOPNOTSUPP;
|
|
|
|
/* Ensure that max_write_same_sectors doesn't overflow bi_size */
|
|
- max_write_same_sectors = UINT_MAX >> 9;
|
|
+ max_write_same_sectors = bio_allowed_max_sectors(q);
|
|
|
|
while (nr_sects) {
|
|
bio = next_bio(bio, 1, gfp_mask);
|
|
diff --git a/block/blk-merge.c b/block/blk-merge.c
|
|
index aaec38cc37b8..2e042190a4f1 100644
|
|
--- a/block/blk-merge.c
|
|
+++ b/block/blk-merge.c
|
|
@@ -27,7 +27,8 @@ static struct bio *blk_bio_discard_split(struct request_queue *q,
|
|
/* Zero-sector (unknown) and one-sector granularities are the same. */
|
|
granularity = max(q->limits.discard_granularity >> 9, 1U);
|
|
|
|
- max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
|
|
+ max_discard_sectors = min(q->limits.max_discard_sectors,
|
|
+ bio_allowed_max_sectors(q));
|
|
max_discard_sectors -= max_discard_sectors % granularity;
|
|
|
|
if (unlikely(!max_discard_sectors)) {
|
|
diff --git a/block/blk.h b/block/blk.h
|
|
index 9db4e389582c..977d4b5d968d 100644
|
|
--- a/block/blk.h
|
|
+++ b/block/blk.h
|
|
@@ -328,6 +328,16 @@ static inline unsigned long blk_rq_deadline(struct request *rq)
|
|
return rq->__deadline & ~0x1UL;
|
|
}
|
|
|
|
+/*
|
|
+ * The max size one bio can handle is UINT_MAX becasue bvec_iter.bi_size
|
|
+ * is defined as 'unsigned int', meantime it has to aligned to with logical
|
|
+ * block size which is the minimum accepted unit by hardware.
|
|
+ */
|
|
+static inline unsigned int bio_allowed_max_sectors(struct request_queue *q)
|
|
+{
|
|
+ return round_down(UINT_MAX, queue_logical_block_size(q)) >> 9;
|
|
+}
|
|
+
|
|
/*
|
|
* Internal io_context interface
|
|
*/
|
|
diff --git a/block/bounce.c b/block/bounce.c
|
|
index bc63b3a2d18c..418677dcec60 100644
|
|
--- a/block/bounce.c
|
|
+++ b/block/bounce.c
|
|
@@ -31,6 +31,24 @@
|
|
static struct bio_set bounce_bio_set, bounce_bio_split;
|
|
static mempool_t page_pool, isa_page_pool;
|
|
|
|
+static void init_bounce_bioset(void)
|
|
+{
|
|
+ static bool bounce_bs_setup;
|
|
+ int ret;
|
|
+
|
|
+ if (bounce_bs_setup)
|
|
+ return;
|
|
+
|
|
+ ret = bioset_init(&bounce_bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
|
|
+ BUG_ON(ret);
|
|
+ if (bioset_integrity_create(&bounce_bio_set, BIO_POOL_SIZE))
|
|
+ BUG_ON(1);
|
|
+
|
|
+ ret = bioset_init(&bounce_bio_split, BIO_POOL_SIZE, 0, 0);
|
|
+ BUG_ON(ret);
|
|
+ bounce_bs_setup = true;
|
|
+}
|
|
+
|
|
#if defined(CONFIG_HIGHMEM)
|
|
static __init int init_emergency_pool(void)
|
|
{
|
|
@@ -44,14 +62,7 @@ static __init int init_emergency_pool(void)
|
|
BUG_ON(ret);
|
|
pr_info("pool size: %d pages\n", POOL_SIZE);
|
|
|
|
- ret = bioset_init(&bounce_bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
|
|
- BUG_ON(ret);
|
|
- if (bioset_integrity_create(&bounce_bio_set, BIO_POOL_SIZE))
|
|
- BUG_ON(1);
|
|
-
|
|
- ret = bioset_init(&bounce_bio_split, BIO_POOL_SIZE, 0, 0);
|
|
- BUG_ON(ret);
|
|
-
|
|
+ init_bounce_bioset();
|
|
return 0;
|
|
}
|
|
|
|
@@ -86,6 +97,8 @@ static void *mempool_alloc_pages_isa(gfp_t gfp_mask, void *data)
|
|
return mempool_alloc_pages(gfp_mask | GFP_DMA, data);
|
|
}
|
|
|
|
+static DEFINE_MUTEX(isa_mutex);
|
|
+
|
|
/*
|
|
* gets called "every" time someone init's a queue with BLK_BOUNCE_ISA
|
|
* as the max address, so check if the pool has already been created.
|
|
@@ -94,14 +107,20 @@ int init_emergency_isa_pool(void)
|
|
{
|
|
int ret;
|
|
|
|
- if (mempool_initialized(&isa_page_pool))
|
|
+ mutex_lock(&isa_mutex);
|
|
+
|
|
+ if (mempool_initialized(&isa_page_pool)) {
|
|
+ mutex_unlock(&isa_mutex);
|
|
return 0;
|
|
+ }
|
|
|
|
ret = mempool_init(&isa_page_pool, ISA_POOL_SIZE, mempool_alloc_pages_isa,
|
|
mempool_free_pages, (void *) 0);
|
|
BUG_ON(ret);
|
|
|
|
pr_info("isa pool size: %d pages\n", ISA_POOL_SIZE);
|
|
+ init_bounce_bioset();
|
|
+ mutex_unlock(&isa_mutex);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/crypto/Kconfig b/crypto/Kconfig
|
|
index f3e40ac56d93..59e32623a7ce 100644
|
|
--- a/crypto/Kconfig
|
|
+++ b/crypto/Kconfig
|
|
@@ -1590,20 +1590,6 @@ config CRYPTO_SM4
|
|
|
|
If unsure, say N.
|
|
|
|
-config CRYPTO_SPECK
|
|
- tristate "Speck cipher algorithm"
|
|
- select CRYPTO_ALGAPI
|
|
- help
|
|
- Speck is a lightweight block cipher that is tuned for optimal
|
|
- performance in software (rather than hardware).
|
|
-
|
|
- Speck may not be as secure as AES, and should only be used on systems
|
|
- where AES is not fast enough.
|
|
-
|
|
- See also: <https://eprint.iacr.org/2013/404.pdf>
|
|
-
|
|
- If unsure, say N.
|
|
-
|
|
config CRYPTO_TEA
|
|
tristate "TEA, XTEA and XETA cipher algorithms"
|
|
select CRYPTO_ALGAPI
|
|
diff --git a/crypto/Makefile b/crypto/Makefile
|
|
index 6d1d40eeb964..f6a234d08882 100644
|
|
--- a/crypto/Makefile
|
|
+++ b/crypto/Makefile
|
|
@@ -115,7 +115,6 @@ obj-$(CONFIG_CRYPTO_TEA) += tea.o
|
|
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
|
|
obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
|
|
obj-$(CONFIG_CRYPTO_SEED) += seed.o
|
|
-obj-$(CONFIG_CRYPTO_SPECK) += speck.o
|
|
obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
|
|
obj-$(CONFIG_CRYPTO_CHACHA20) += chacha20_generic.o
|
|
obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o
|
|
diff --git a/crypto/aegis.h b/crypto/aegis.h
|
|
index f1c6900ddb80..405e025fc906 100644
|
|
--- a/crypto/aegis.h
|
|
+++ b/crypto/aegis.h
|
|
@@ -21,7 +21,7 @@
|
|
|
|
union aegis_block {
|
|
__le64 words64[AEGIS_BLOCK_SIZE / sizeof(__le64)];
|
|
- u32 words32[AEGIS_BLOCK_SIZE / sizeof(u32)];
|
|
+ __le32 words32[AEGIS_BLOCK_SIZE / sizeof(__le32)];
|
|
u8 bytes[AEGIS_BLOCK_SIZE];
|
|
};
|
|
|
|
@@ -57,24 +57,22 @@ static void crypto_aegis_aesenc(union aegis_block *dst,
|
|
const union aegis_block *src,
|
|
const union aegis_block *key)
|
|
{
|
|
- u32 *d = dst->words32;
|
|
const u8 *s = src->bytes;
|
|
- const u32 *k = key->words32;
|
|
const u32 *t0 = crypto_ft_tab[0];
|
|
const u32 *t1 = crypto_ft_tab[1];
|
|
const u32 *t2 = crypto_ft_tab[2];
|
|
const u32 *t3 = crypto_ft_tab[3];
|
|
u32 d0, d1, d2, d3;
|
|
|
|
- d0 = t0[s[ 0]] ^ t1[s[ 5]] ^ t2[s[10]] ^ t3[s[15]] ^ k[0];
|
|
- d1 = t0[s[ 4]] ^ t1[s[ 9]] ^ t2[s[14]] ^ t3[s[ 3]] ^ k[1];
|
|
- d2 = t0[s[ 8]] ^ t1[s[13]] ^ t2[s[ 2]] ^ t3[s[ 7]] ^ k[2];
|
|
- d3 = t0[s[12]] ^ t1[s[ 1]] ^ t2[s[ 6]] ^ t3[s[11]] ^ k[3];
|
|
+ d0 = t0[s[ 0]] ^ t1[s[ 5]] ^ t2[s[10]] ^ t3[s[15]];
|
|
+ d1 = t0[s[ 4]] ^ t1[s[ 9]] ^ t2[s[14]] ^ t3[s[ 3]];
|
|
+ d2 = t0[s[ 8]] ^ t1[s[13]] ^ t2[s[ 2]] ^ t3[s[ 7]];
|
|
+ d3 = t0[s[12]] ^ t1[s[ 1]] ^ t2[s[ 6]] ^ t3[s[11]];
|
|
|
|
- d[0] = d0;
|
|
- d[1] = d1;
|
|
- d[2] = d2;
|
|
- d[3] = d3;
|
|
+ dst->words32[0] = cpu_to_le32(d0) ^ key->words32[0];
|
|
+ dst->words32[1] = cpu_to_le32(d1) ^ key->words32[1];
|
|
+ dst->words32[2] = cpu_to_le32(d2) ^ key->words32[2];
|
|
+ dst->words32[3] = cpu_to_le32(d3) ^ key->words32[3];
|
|
}
|
|
|
|
#endif /* _CRYPTO_AEGIS_H */
|
|
diff --git a/crypto/lrw.c b/crypto/lrw.c
|
|
index 393a782679c7..5504d1325a56 100644
|
|
--- a/crypto/lrw.c
|
|
+++ b/crypto/lrw.c
|
|
@@ -143,7 +143,12 @@ static inline int get_index128(be128 *block)
|
|
return x + ffz(val);
|
|
}
|
|
|
|
- return x;
|
|
+ /*
|
|
+ * If we get here, then x == 128 and we are incrementing the counter
|
|
+ * from all ones to all zeros. This means we must return index 127, i.e.
|
|
+ * the one corresponding to key2*{ 1,...,1 }.
|
|
+ */
|
|
+ return 127;
|
|
}
|
|
|
|
static int post_crypt(struct skcipher_request *req)
|
|
diff --git a/crypto/morus1280.c b/crypto/morus1280.c
|
|
index d057cf5ac4a8..3889c188f266 100644
|
|
--- a/crypto/morus1280.c
|
|
+++ b/crypto/morus1280.c
|
|
@@ -385,14 +385,11 @@ static void crypto_morus1280_final(struct morus1280_state *state,
|
|
struct morus1280_block *tag_xor,
|
|
u64 assoclen, u64 cryptlen)
|
|
{
|
|
- u64 assocbits = assoclen * 8;
|
|
- u64 cryptbits = cryptlen * 8;
|
|
-
|
|
struct morus1280_block tmp;
|
|
unsigned int i;
|
|
|
|
- tmp.words[0] = cpu_to_le64(assocbits);
|
|
- tmp.words[1] = cpu_to_le64(cryptbits);
|
|
+ tmp.words[0] = assoclen * 8;
|
|
+ tmp.words[1] = cryptlen * 8;
|
|
tmp.words[2] = 0;
|
|
tmp.words[3] = 0;
|
|
|
|
diff --git a/crypto/morus640.c b/crypto/morus640.c
|
|
index 1ca76e54281b..da06ec2f6a80 100644
|
|
--- a/crypto/morus640.c
|
|
+++ b/crypto/morus640.c
|
|
@@ -384,21 +384,13 @@ static void crypto_morus640_final(struct morus640_state *state,
|
|
struct morus640_block *tag_xor,
|
|
u64 assoclen, u64 cryptlen)
|
|
{
|
|
- u64 assocbits = assoclen * 8;
|
|
- u64 cryptbits = cryptlen * 8;
|
|
-
|
|
- u32 assocbits_lo = (u32)assocbits;
|
|
- u32 assocbits_hi = (u32)(assocbits >> 32);
|
|
- u32 cryptbits_lo = (u32)cryptbits;
|
|
- u32 cryptbits_hi = (u32)(cryptbits >> 32);
|
|
-
|
|
struct morus640_block tmp;
|
|
unsigned int i;
|
|
|
|
- tmp.words[0] = cpu_to_le32(assocbits_lo);
|
|
- tmp.words[1] = cpu_to_le32(assocbits_hi);
|
|
- tmp.words[2] = cpu_to_le32(cryptbits_lo);
|
|
- tmp.words[3] = cpu_to_le32(cryptbits_hi);
|
|
+ tmp.words[0] = lower_32_bits(assoclen * 8);
|
|
+ tmp.words[1] = upper_32_bits(assoclen * 8);
|
|
+ tmp.words[2] = lower_32_bits(cryptlen * 8);
|
|
+ tmp.words[3] = upper_32_bits(cryptlen * 8);
|
|
|
|
for (i = 0; i < MORUS_BLOCK_WORDS; i++)
|
|
state->s[4].words[i] ^= state->s[0].words[i];
|
|
diff --git a/crypto/speck.c b/crypto/speck.c
|
|
deleted file mode 100644
|
|
index 58aa9f7f91f7..000000000000
|
|
--- a/crypto/speck.c
|
|
+++ /dev/null
|
|
@@ -1,307 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * Speck: a lightweight block cipher
|
|
- *
|
|
- * Copyright (c) 2018 Google, Inc
|
|
- *
|
|
- * Speck has 10 variants, including 5 block sizes. For now we only implement
|
|
- * the variants Speck128/128, Speck128/192, Speck128/256, Speck64/96, and
|
|
- * Speck64/128. Speck${B}/${K} denotes the variant with a block size of B bits
|
|
- * and a key size of K bits. The Speck128 variants are believed to be the most
|
|
- * secure variants, and they use the same block size and key sizes as AES. The
|
|
- * Speck64 variants are less secure, but on 32-bit processors are usually
|
|
- * faster. The remaining variants (Speck32, Speck48, and Speck96) are even less
|
|
- * secure and/or not as well suited for implementation on either 32-bit or
|
|
- * 64-bit processors, so are omitted.
|
|
- *
|
|
- * Reference: "The Simon and Speck Families of Lightweight Block Ciphers"
|
|
- * https://eprint.iacr.org/2013/404.pdf
|
|
- *
|
|
- * In a correspondence, the Speck designers have also clarified that the words
|
|
- * should be interpreted in little-endian format, and the words should be
|
|
- * ordered such that the first word of each block is 'y' rather than 'x', and
|
|
- * the first key word (rather than the last) becomes the first round key.
|
|
- */
|
|
-
|
|
-#include <asm/unaligned.h>
|
|
-#include <crypto/speck.h>
|
|
-#include <linux/bitops.h>
|
|
-#include <linux/crypto.h>
|
|
-#include <linux/init.h>
|
|
-#include <linux/module.h>
|
|
-
|
|
-/* Speck128 */
|
|
-
|
|
-static __always_inline void speck128_round(u64 *x, u64 *y, u64 k)
|
|
-{
|
|
- *x = ror64(*x, 8);
|
|
- *x += *y;
|
|
- *x ^= k;
|
|
- *y = rol64(*y, 3);
|
|
- *y ^= *x;
|
|
-}
|
|
-
|
|
-static __always_inline void speck128_unround(u64 *x, u64 *y, u64 k)
|
|
-{
|
|
- *y ^= *x;
|
|
- *y = ror64(*y, 3);
|
|
- *x ^= k;
|
|
- *x -= *y;
|
|
- *x = rol64(*x, 8);
|
|
-}
|
|
-
|
|
-void crypto_speck128_encrypt(const struct speck128_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in)
|
|
-{
|
|
- u64 y = get_unaligned_le64(in);
|
|
- u64 x = get_unaligned_le64(in + 8);
|
|
- int i;
|
|
-
|
|
- for (i = 0; i < ctx->nrounds; i++)
|
|
- speck128_round(&x, &y, ctx->round_keys[i]);
|
|
-
|
|
- put_unaligned_le64(y, out);
|
|
- put_unaligned_le64(x, out + 8);
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(crypto_speck128_encrypt);
|
|
-
|
|
-static void speck128_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
|
-{
|
|
- crypto_speck128_encrypt(crypto_tfm_ctx(tfm), out, in);
|
|
-}
|
|
-
|
|
-void crypto_speck128_decrypt(const struct speck128_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in)
|
|
-{
|
|
- u64 y = get_unaligned_le64(in);
|
|
- u64 x = get_unaligned_le64(in + 8);
|
|
- int i;
|
|
-
|
|
- for (i = ctx->nrounds - 1; i >= 0; i--)
|
|
- speck128_unround(&x, &y, ctx->round_keys[i]);
|
|
-
|
|
- put_unaligned_le64(y, out);
|
|
- put_unaligned_le64(x, out + 8);
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(crypto_speck128_decrypt);
|
|
-
|
|
-static void speck128_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
|
-{
|
|
- crypto_speck128_decrypt(crypto_tfm_ctx(tfm), out, in);
|
|
-}
|
|
-
|
|
-int crypto_speck128_setkey(struct speck128_tfm_ctx *ctx, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- u64 l[3];
|
|
- u64 k;
|
|
- int i;
|
|
-
|
|
- switch (keylen) {
|
|
- case SPECK128_128_KEY_SIZE:
|
|
- k = get_unaligned_le64(key);
|
|
- l[0] = get_unaligned_le64(key + 8);
|
|
- ctx->nrounds = SPECK128_128_NROUNDS;
|
|
- for (i = 0; i < ctx->nrounds; i++) {
|
|
- ctx->round_keys[i] = k;
|
|
- speck128_round(&l[0], &k, i);
|
|
- }
|
|
- break;
|
|
- case SPECK128_192_KEY_SIZE:
|
|
- k = get_unaligned_le64(key);
|
|
- l[0] = get_unaligned_le64(key + 8);
|
|
- l[1] = get_unaligned_le64(key + 16);
|
|
- ctx->nrounds = SPECK128_192_NROUNDS;
|
|
- for (i = 0; i < ctx->nrounds; i++) {
|
|
- ctx->round_keys[i] = k;
|
|
- speck128_round(&l[i % 2], &k, i);
|
|
- }
|
|
- break;
|
|
- case SPECK128_256_KEY_SIZE:
|
|
- k = get_unaligned_le64(key);
|
|
- l[0] = get_unaligned_le64(key + 8);
|
|
- l[1] = get_unaligned_le64(key + 16);
|
|
- l[2] = get_unaligned_le64(key + 24);
|
|
- ctx->nrounds = SPECK128_256_NROUNDS;
|
|
- for (i = 0; i < ctx->nrounds; i++) {
|
|
- ctx->round_keys[i] = k;
|
|
- speck128_round(&l[i % 3], &k, i);
|
|
- }
|
|
- break;
|
|
- default:
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(crypto_speck128_setkey);
|
|
-
|
|
-static int speck128_setkey(struct crypto_tfm *tfm, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- return crypto_speck128_setkey(crypto_tfm_ctx(tfm), key, keylen);
|
|
-}
|
|
-
|
|
-/* Speck64 */
|
|
-
|
|
-static __always_inline void speck64_round(u32 *x, u32 *y, u32 k)
|
|
-{
|
|
- *x = ror32(*x, 8);
|
|
- *x += *y;
|
|
- *x ^= k;
|
|
- *y = rol32(*y, 3);
|
|
- *y ^= *x;
|
|
-}
|
|
-
|
|
-static __always_inline void speck64_unround(u32 *x, u32 *y, u32 k)
|
|
-{
|
|
- *y ^= *x;
|
|
- *y = ror32(*y, 3);
|
|
- *x ^= k;
|
|
- *x -= *y;
|
|
- *x = rol32(*x, 8);
|
|
-}
|
|
-
|
|
-void crypto_speck64_encrypt(const struct speck64_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in)
|
|
-{
|
|
- u32 y = get_unaligned_le32(in);
|
|
- u32 x = get_unaligned_le32(in + 4);
|
|
- int i;
|
|
-
|
|
- for (i = 0; i < ctx->nrounds; i++)
|
|
- speck64_round(&x, &y, ctx->round_keys[i]);
|
|
-
|
|
- put_unaligned_le32(y, out);
|
|
- put_unaligned_le32(x, out + 4);
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(crypto_speck64_encrypt);
|
|
-
|
|
-static void speck64_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
|
-{
|
|
- crypto_speck64_encrypt(crypto_tfm_ctx(tfm), out, in);
|
|
-}
|
|
-
|
|
-void crypto_speck64_decrypt(const struct speck64_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in)
|
|
-{
|
|
- u32 y = get_unaligned_le32(in);
|
|
- u32 x = get_unaligned_le32(in + 4);
|
|
- int i;
|
|
-
|
|
- for (i = ctx->nrounds - 1; i >= 0; i--)
|
|
- speck64_unround(&x, &y, ctx->round_keys[i]);
|
|
-
|
|
- put_unaligned_le32(y, out);
|
|
- put_unaligned_le32(x, out + 4);
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(crypto_speck64_decrypt);
|
|
-
|
|
-static void speck64_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
|
-{
|
|
- crypto_speck64_decrypt(crypto_tfm_ctx(tfm), out, in);
|
|
-}
|
|
-
|
|
-int crypto_speck64_setkey(struct speck64_tfm_ctx *ctx, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- u32 l[3];
|
|
- u32 k;
|
|
- int i;
|
|
-
|
|
- switch (keylen) {
|
|
- case SPECK64_96_KEY_SIZE:
|
|
- k = get_unaligned_le32(key);
|
|
- l[0] = get_unaligned_le32(key + 4);
|
|
- l[1] = get_unaligned_le32(key + 8);
|
|
- ctx->nrounds = SPECK64_96_NROUNDS;
|
|
- for (i = 0; i < ctx->nrounds; i++) {
|
|
- ctx->round_keys[i] = k;
|
|
- speck64_round(&l[i % 2], &k, i);
|
|
- }
|
|
- break;
|
|
- case SPECK64_128_KEY_SIZE:
|
|
- k = get_unaligned_le32(key);
|
|
- l[0] = get_unaligned_le32(key + 4);
|
|
- l[1] = get_unaligned_le32(key + 8);
|
|
- l[2] = get_unaligned_le32(key + 12);
|
|
- ctx->nrounds = SPECK64_128_NROUNDS;
|
|
- for (i = 0; i < ctx->nrounds; i++) {
|
|
- ctx->round_keys[i] = k;
|
|
- speck64_round(&l[i % 3], &k, i);
|
|
- }
|
|
- break;
|
|
- default:
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(crypto_speck64_setkey);
|
|
-
|
|
-static int speck64_setkey(struct crypto_tfm *tfm, const u8 *key,
|
|
- unsigned int keylen)
|
|
-{
|
|
- return crypto_speck64_setkey(crypto_tfm_ctx(tfm), key, keylen);
|
|
-}
|
|
-
|
|
-/* Algorithm definitions */
|
|
-
|
|
-static struct crypto_alg speck_algs[] = {
|
|
- {
|
|
- .cra_name = "speck128",
|
|
- .cra_driver_name = "speck128-generic",
|
|
- .cra_priority = 100,
|
|
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
|
- .cra_blocksize = SPECK128_BLOCK_SIZE,
|
|
- .cra_ctxsize = sizeof(struct speck128_tfm_ctx),
|
|
- .cra_module = THIS_MODULE,
|
|
- .cra_u = {
|
|
- .cipher = {
|
|
- .cia_min_keysize = SPECK128_128_KEY_SIZE,
|
|
- .cia_max_keysize = SPECK128_256_KEY_SIZE,
|
|
- .cia_setkey = speck128_setkey,
|
|
- .cia_encrypt = speck128_encrypt,
|
|
- .cia_decrypt = speck128_decrypt
|
|
- }
|
|
- }
|
|
- }, {
|
|
- .cra_name = "speck64",
|
|
- .cra_driver_name = "speck64-generic",
|
|
- .cra_priority = 100,
|
|
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
|
- .cra_blocksize = SPECK64_BLOCK_SIZE,
|
|
- .cra_ctxsize = sizeof(struct speck64_tfm_ctx),
|
|
- .cra_module = THIS_MODULE,
|
|
- .cra_u = {
|
|
- .cipher = {
|
|
- .cia_min_keysize = SPECK64_96_KEY_SIZE,
|
|
- .cia_max_keysize = SPECK64_128_KEY_SIZE,
|
|
- .cia_setkey = speck64_setkey,
|
|
- .cia_encrypt = speck64_encrypt,
|
|
- .cia_decrypt = speck64_decrypt
|
|
- }
|
|
- }
|
|
- }
|
|
-};
|
|
-
|
|
-static int __init speck_module_init(void)
|
|
-{
|
|
- return crypto_register_algs(speck_algs, ARRAY_SIZE(speck_algs));
|
|
-}
|
|
-
|
|
-static void __exit speck_module_exit(void)
|
|
-{
|
|
- crypto_unregister_algs(speck_algs, ARRAY_SIZE(speck_algs));
|
|
-}
|
|
-
|
|
-module_init(speck_module_init);
|
|
-module_exit(speck_module_exit);
|
|
-
|
|
-MODULE_DESCRIPTION("Speck block cipher (generic)");
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
|
|
-MODULE_ALIAS_CRYPTO("speck128");
|
|
-MODULE_ALIAS_CRYPTO("speck128-generic");
|
|
-MODULE_ALIAS_CRYPTO("speck64");
|
|
-MODULE_ALIAS_CRYPTO("speck64-generic");
|
|
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
|
|
index bdde95e8d369..6e0a054bb61d 100644
|
|
--- a/crypto/tcrypt.c
|
|
+++ b/crypto/tcrypt.c
|
|
@@ -1103,6 +1103,9 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
|
|
break;
|
|
}
|
|
|
|
+ if (speed[i].klen)
|
|
+ crypto_ahash_setkey(tfm, tvmem[0], speed[i].klen);
|
|
+
|
|
pr_info("test%3u "
|
|
"(%5u byte blocks,%5u bytes per update,%4u updates): ",
|
|
i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
|
|
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
|
|
index a1d42245082a..1c9bf38e59ea 100644
|
|
--- a/crypto/testmgr.c
|
|
+++ b/crypto/testmgr.c
|
|
@@ -3037,18 +3037,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
|
.suite = {
|
|
.cipher = __VECS(sm4_tv_template)
|
|
}
|
|
- }, {
|
|
- .alg = "ecb(speck128)",
|
|
- .test = alg_test_skcipher,
|
|
- .suite = {
|
|
- .cipher = __VECS(speck128_tv_template)
|
|
- }
|
|
- }, {
|
|
- .alg = "ecb(speck64)",
|
|
- .test = alg_test_skcipher,
|
|
- .suite = {
|
|
- .cipher = __VECS(speck64_tv_template)
|
|
- }
|
|
}, {
|
|
.alg = "ecb(tea)",
|
|
.test = alg_test_skcipher,
|
|
@@ -3576,18 +3564,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
|
.suite = {
|
|
.cipher = __VECS(serpent_xts_tv_template)
|
|
}
|
|
- }, {
|
|
- .alg = "xts(speck128)",
|
|
- .test = alg_test_skcipher,
|
|
- .suite = {
|
|
- .cipher = __VECS(speck128_xts_tv_template)
|
|
- }
|
|
- }, {
|
|
- .alg = "xts(speck64)",
|
|
- .test = alg_test_skcipher,
|
|
- .suite = {
|
|
- .cipher = __VECS(speck64_xts_tv_template)
|
|
- }
|
|
}, {
|
|
.alg = "xts(twofish)",
|
|
.test = alg_test_skcipher,
|
|
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
|
|
index 173111c70746..0b3d7cadbe93 100644
|
|
--- a/crypto/testmgr.h
|
|
+++ b/crypto/testmgr.h
|
|
@@ -10198,744 +10198,6 @@ static const struct cipher_testvec sm4_tv_template[] = {
|
|
}
|
|
};
|
|
|
|
-/*
|
|
- * Speck test vectors taken from the original paper:
|
|
- * "The Simon and Speck Families of Lightweight Block Ciphers"
|
|
- * https://eprint.iacr.org/2013/404.pdf
|
|
- *
|
|
- * Note that the paper does not make byte and word order clear. But it was
|
|
- * confirmed with the authors that the intended orders are little endian byte
|
|
- * order and (y, x) word order. Equivalently, the printed test vectors, when
|
|
- * looking at only the bytes (ignoring the whitespace that divides them into
|
|
- * words), are backwards: the left-most byte is actually the one with the
|
|
- * highest memory address, while the right-most byte is actually the one with
|
|
- * the lowest memory address.
|
|
- */
|
|
-
|
|
-static const struct cipher_testvec speck128_tv_template[] = {
|
|
- { /* Speck128/128 */
|
|
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
|
- .klen = 16,
|
|
- .ptext = "\x20\x6d\x61\x64\x65\x20\x69\x74"
|
|
- "\x20\x65\x71\x75\x69\x76\x61\x6c",
|
|
- .ctext = "\x18\x0d\x57\x5c\xdf\xfe\x60\x78"
|
|
- "\x65\x32\x78\x79\x51\x98\x5d\xa6",
|
|
- .len = 16,
|
|
- }, { /* Speck128/192 */
|
|
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17",
|
|
- .klen = 24,
|
|
- .ptext = "\x65\x6e\x74\x20\x74\x6f\x20\x43"
|
|
- "\x68\x69\x65\x66\x20\x48\x61\x72",
|
|
- .ctext = "\x86\x18\x3c\xe0\x5d\x18\xbc\xf9"
|
|
- "\x66\x55\x13\x13\x3a\xcf\xe4\x1b",
|
|
- .len = 16,
|
|
- }, { /* Speck128/256 */
|
|
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
|
|
- .klen = 32,
|
|
- .ptext = "\x70\x6f\x6f\x6e\x65\x72\x2e\x20"
|
|
- "\x49\x6e\x20\x74\x68\x6f\x73\x65",
|
|
- .ctext = "\x43\x8f\x18\x9c\x8d\xb4\xee\x4e"
|
|
- "\x3e\xf5\xc0\x05\x04\x01\x09\x41",
|
|
- .len = 16,
|
|
- },
|
|
-};
|
|
-
|
|
-/*
|
|
- * Speck128-XTS test vectors, taken from the AES-XTS test vectors with the
|
|
- * ciphertext recomputed with Speck128 as the cipher
|
|
- */
|
|
-static const struct cipher_testvec speck128_xts_tv_template[] = {
|
|
- {
|
|
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .klen = 32,
|
|
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ctext = "\xbe\xa0\xe7\x03\xd7\xfe\xab\x62"
|
|
- "\x3b\x99\x4a\x64\x74\x77\xac\xed"
|
|
- "\xd8\xf4\xa6\xcf\xae\xb9\x07\x42"
|
|
- "\x51\xd9\xb6\x1d\xe0\x5e\xbc\x54",
|
|
- .len = 32,
|
|
- }, {
|
|
- .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
|
|
- "\x11\x11\x11\x11\x11\x11\x11\x11"
|
|
- "\x22\x22\x22\x22\x22\x22\x22\x22"
|
|
- "\x22\x22\x22\x22\x22\x22\x22\x22",
|
|
- .klen = 32,
|
|
- .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44",
|
|
- .ctext = "\xfb\x53\x81\x75\x6f\x9f\x34\xad"
|
|
- "\x7e\x01\xed\x7b\xcc\xda\x4e\x4a"
|
|
- "\xd4\x84\xa4\x53\xd5\x88\x73\x1b"
|
|
- "\xfd\xcb\xae\x0d\xf3\x04\xee\xe6",
|
|
- .len = 32,
|
|
- }, {
|
|
- .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
|
|
- "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
|
|
- "\x22\x22\x22\x22\x22\x22\x22\x22"
|
|
- "\x22\x22\x22\x22\x22\x22\x22\x22",
|
|
- .klen = 32,
|
|
- .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44",
|
|
- .ctext = "\x21\x52\x84\x15\xd1\xf7\x21\x55"
|
|
- "\xd9\x75\x4a\xd3\xc5\xdb\x9f\x7d"
|
|
- "\xda\x63\xb2\xf1\x82\xb0\x89\x59"
|
|
- "\x86\xd4\xaa\xaa\xdd\xff\x4f\x92",
|
|
- .len = 32,
|
|
- }, {
|
|
- .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
|
|
- "\x23\x53\x60\x28\x74\x71\x35\x26"
|
|
- "\x31\x41\x59\x26\x53\x58\x97\x93"
|
|
- "\x23\x84\x62\x64\x33\x83\x27\x95",
|
|
- .klen = 32,
|
|
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
|
- "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
|
- .ctext = "\x57\xb5\xf8\x71\x6e\x6d\xdd\x82"
|
|
- "\x53\xd0\xed\x2d\x30\xc1\x20\xef"
|
|
- "\x70\x67\x5e\xff\x09\x70\xbb\xc1"
|
|
- "\x3a\x7b\x48\x26\xd9\x0b\xf4\x48"
|
|
- "\xbe\xce\xb1\xc7\xb2\x67\xc4\xa7"
|
|
- "\x76\xf8\x36\x30\xb7\xb4\x9a\xd9"
|
|
- "\xf5\x9d\xd0\x7b\xc1\x06\x96\x44"
|
|
- "\x19\xc5\x58\x84\x63\xb9\x12\x68"
|
|
- "\x68\xc7\xaa\x18\x98\xf2\x1f\x5c"
|
|
- "\x39\xa6\xd8\x32\x2b\xc3\x51\xfd"
|
|
- "\x74\x79\x2e\xb4\x44\xd7\x69\xc4"
|
|
- "\xfc\x29\xe6\xed\x26\x1e\xa6\x9d"
|
|
- "\x1c\xbe\x00\x0e\x7f\x3a\xca\xfb"
|
|
- "\x6d\x13\x65\xa0\xf9\x31\x12\xe2"
|
|
- "\x26\xd1\xec\x2b\x0a\x8b\x59\x99"
|
|
- "\xa7\x49\xa0\x0e\x09\x33\x85\x50"
|
|
- "\xc3\x23\xca\x7a\xdd\x13\x45\x5f"
|
|
- "\xde\x4c\xa7\xcb\x00\x8a\x66\x6f"
|
|
- "\xa2\xb6\xb1\x2e\xe1\xa0\x18\xf6"
|
|
- "\xad\xf3\xbd\xeb\xc7\xef\x55\x4f"
|
|
- "\x79\x91\x8d\x36\x13\x7b\xd0\x4a"
|
|
- "\x6c\x39\xfb\x53\xb8\x6f\x02\x51"
|
|
- "\xa5\x20\xac\x24\x1c\x73\x59\x73"
|
|
- "\x58\x61\x3a\x87\x58\xb3\x20\x56"
|
|
- "\x39\x06\x2b\x4d\xd3\x20\x2b\x89"
|
|
- "\x3f\xa2\xf0\x96\xeb\x7f\xa4\xcd"
|
|
- "\x11\xae\xbd\xcb\x3a\xb4\xd9\x91"
|
|
- "\x09\x35\x71\x50\x65\xac\x92\xe3"
|
|
- "\x7b\x32\xc0\x7a\xdd\xd4\xc3\x92"
|
|
- "\x6f\xeb\x79\xde\x6f\xd3\x25\xc9"
|
|
- "\xcd\x63\xf5\x1e\x7a\x3b\x26\x9d"
|
|
- "\x77\x04\x80\xa9\xbf\x38\xb5\xbd"
|
|
- "\xb8\x05\x07\xbd\xfd\xab\x7b\xf8"
|
|
- "\x2a\x26\xcc\x49\x14\x6d\x55\x01"
|
|
- "\x06\x94\xd8\xb2\x2d\x53\x83\x1b"
|
|
- "\x8f\xd4\xdd\x57\x12\x7e\x18\xba"
|
|
- "\x8e\xe2\x4d\x80\xef\x7e\x6b\x9d"
|
|
- "\x24\xa9\x60\xa4\x97\x85\x86\x2a"
|
|
- "\x01\x00\x09\xf1\xcb\x4a\x24\x1c"
|
|
- "\xd8\xf6\xe6\x5b\xe7\x5d\xf2\xc4"
|
|
- "\x97\x1c\x10\xc6\x4d\x66\x4f\x98"
|
|
- "\x87\x30\xac\xd5\xea\x73\x49\x10"
|
|
- "\x80\xea\xe5\x5f\x4d\x5f\x03\x33"
|
|
- "\x66\x02\x35\x3d\x60\x06\x36\x4f"
|
|
- "\x14\x1c\xd8\x07\x1f\x78\xd0\xf8"
|
|
- "\x4f\x6c\x62\x7c\x15\xa5\x7c\x28"
|
|
- "\x7c\xcc\xeb\x1f\xd1\x07\x90\x93"
|
|
- "\x7e\xc2\xa8\x3a\x80\xc0\xf5\x30"
|
|
- "\xcc\x75\xcf\x16\x26\xa9\x26\x3b"
|
|
- "\xe7\x68\x2f\x15\x21\x5b\xe4\x00"
|
|
- "\xbd\x48\x50\xcd\x75\x70\xc4\x62"
|
|
- "\xbb\x41\xfb\x89\x4a\x88\x3b\x3b"
|
|
- "\x51\x66\x02\x69\x04\x97\x36\xd4"
|
|
- "\x75\xae\x0b\xa3\x42\xf8\xca\x79"
|
|
- "\x8f\x93\xe9\xcc\x38\xbd\xd6\xd2"
|
|
- "\xf9\x70\x4e\xc3\x6a\x8e\x25\xbd"
|
|
- "\xea\x15\x5a\xa0\x85\x7e\x81\x0d"
|
|
- "\x03\xe7\x05\x39\xf5\x05\x26\xee"
|
|
- "\xec\xaa\x1f\x3d\xc9\x98\x76\x01"
|
|
- "\x2c\xf4\xfc\xa3\x88\x77\x38\xc4"
|
|
- "\x50\x65\x50\x6d\x04\x1f\xdf\x5a"
|
|
- "\xaa\xf2\x01\xa9\xc1\x8d\xee\xca"
|
|
- "\x47\x26\xef\x39\xb8\xb4\xf2\xd1"
|
|
- "\xd6\xbb\x1b\x2a\xc1\x34\x14\xcf",
|
|
- .len = 512,
|
|
- }, {
|
|
- .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
|
|
- "\x23\x53\x60\x28\x74\x71\x35\x26"
|
|
- "\x62\x49\x77\x57\x24\x70\x93\x69"
|
|
- "\x99\x59\x57\x49\x66\x96\x76\x27"
|
|
- "\x31\x41\x59\x26\x53\x58\x97\x93"
|
|
- "\x23\x84\x62\x64\x33\x83\x27\x95"
|
|
- "\x02\x88\x41\x97\x16\x93\x99\x37"
|
|
- "\x51\x05\x82\x09\x74\x94\x45\x92",
|
|
- .klen = 64,
|
|
- .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
|
- "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
|
- .ctext = "\xc5\x85\x2a\x4b\x73\xe4\xf6\xf1"
|
|
- "\x7e\xf9\xf6\xe9\xa3\x73\x36\xcb"
|
|
- "\xaa\xb6\x22\xb0\x24\x6e\x3d\x73"
|
|
- "\x92\x99\xde\xd3\x76\xed\xcd\x63"
|
|
- "\x64\x3a\x22\x57\xc1\x43\x49\xd4"
|
|
- "\x79\x36\x31\x19\x62\xae\x10\x7e"
|
|
- "\x7d\xcf\x7a\xe2\x6b\xce\x27\xfa"
|
|
- "\xdc\x3d\xd9\x83\xd3\x42\x4c\xe0"
|
|
- "\x1b\xd6\x1d\x1a\x6f\xd2\x03\x00"
|
|
- "\xfc\x81\x99\x8a\x14\x62\xf5\x7e"
|
|
- "\x0d\xe7\x12\xe8\x17\x9d\x0b\xec"
|
|
- "\xe2\xf7\xc9\xa7\x63\xd1\x79\xb6"
|
|
- "\x62\x62\x37\xfe\x0a\x4c\x4a\x37"
|
|
- "\x70\xc7\x5e\x96\x5f\xbc\x8e\x9e"
|
|
- "\x85\x3c\x4f\x26\x64\x85\xbc\x68"
|
|
- "\xb0\xe0\x86\x5e\x26\x41\xce\x11"
|
|
- "\x50\xda\x97\x14\xe9\x9e\xc7\x6d"
|
|
- "\x3b\xdc\x43\xde\x2b\x27\x69\x7d"
|
|
- "\xfc\xb0\x28\xbd\x8f\xb1\xc6\x31"
|
|
- "\x14\x4d\xf0\x74\x37\xfd\x07\x25"
|
|
- "\x96\x55\xe5\xfc\x9e\x27\x2a\x74"
|
|
- "\x1b\x83\x4d\x15\x83\xac\x57\xa0"
|
|
- "\xac\xa5\xd0\x38\xef\x19\x56\x53"
|
|
- "\x25\x4b\xfc\xce\x04\x23\xe5\x6b"
|
|
- "\xf6\xc6\x6c\x32\x0b\xb3\x12\xc5"
|
|
- "\xed\x22\x34\x1c\x5d\xed\x17\x06"
|
|
- "\x36\xa3\xe6\x77\xb9\x97\x46\xb8"
|
|
- "\xe9\x3f\x7e\xc7\xbc\x13\x5c\xdc"
|
|
- "\x6e\x3f\x04\x5e\xd1\x59\xa5\x82"
|
|
- "\x35\x91\x3d\x1b\xe4\x97\x9f\x92"
|
|
- "\x1c\x5e\x5f\x6f\x41\xd4\x62\xa1"
|
|
- "\x8d\x39\xfc\x42\xfb\x38\x80\xb9"
|
|
- "\x0a\xe3\xcc\x6a\x93\xd9\x7a\xb1"
|
|
- "\xe9\x69\xaf\x0a\x6b\x75\x38\xa7"
|
|
- "\xa1\xbf\xf7\xda\x95\x93\x4b\x78"
|
|
- "\x19\xf5\x94\xf9\xd2\x00\x33\x37"
|
|
- "\xcf\xf5\x9e\x9c\xf3\xcc\xa6\xee"
|
|
- "\x42\xb2\x9e\x2c\x5f\x48\x23\x26"
|
|
- "\x15\x25\x17\x03\x3d\xfe\x2c\xfc"
|
|
- "\xeb\xba\xda\xe0\x00\x05\xb6\xa6"
|
|
- "\x07\xb3\xe8\x36\x5b\xec\x5b\xbf"
|
|
- "\xd6\x5b\x00\x74\xc6\x97\xf1\x6a"
|
|
- "\x49\xa1\xc3\xfa\x10\x52\xb9\x14"
|
|
- "\xad\xb7\x73\xf8\x78\x12\xc8\x59"
|
|
- "\x17\x80\x4c\x57\x39\xf1\x6d\x80"
|
|
- "\x25\x77\x0f\x5e\x7d\xf0\xaf\x21"
|
|
- "\xec\xce\xb7\xc8\x02\x8a\xed\x53"
|
|
- "\x2c\x25\x68\x2e\x1f\x85\x5e\x67"
|
|
- "\xd1\x07\x7a\x3a\x89\x08\xe0\x34"
|
|
- "\xdc\xdb\x26\xb4\x6b\x77\xfc\x40"
|
|
- "\x31\x15\x72\xa0\xf0\x73\xd9\x3b"
|
|
- "\xd5\xdb\xfe\xfc\x8f\xa9\x44\xa2"
|
|
- "\x09\x9f\xc6\x33\xe5\xe2\x88\xe8"
|
|
- "\xf3\xf0\x1a\xf4\xce\x12\x0f\xd6"
|
|
- "\xf7\x36\xe6\xa4\xf4\x7a\x10\x58"
|
|
- "\xcc\x1f\x48\x49\x65\x47\x75\xe9"
|
|
- "\x28\xe1\x65\x7b\xf2\xc4\xb5\x07"
|
|
- "\xf2\xec\x76\xd8\x8f\x09\xf3\x16"
|
|
- "\xa1\x51\x89\x3b\xeb\x96\x42\xac"
|
|
- "\x65\xe0\x67\x63\x29\xdc\xb4\x7d"
|
|
- "\xf2\x41\x51\x6a\xcb\xde\x3c\xfb"
|
|
- "\x66\x8d\x13\xca\xe0\x59\x2a\x00"
|
|
- "\xc9\x53\x4c\xe6\x9e\xe2\x73\xd5"
|
|
- "\x67\x19\xb2\xbd\x9a\x63\xd7\x5c",
|
|
- .len = 512,
|
|
- .also_non_np = 1,
|
|
- .np = 3,
|
|
- .tap = { 512 - 20, 4, 16 },
|
|
- }
|
|
-};
|
|
-
|
|
-static const struct cipher_testvec speck64_tv_template[] = {
|
|
- { /* Speck64/96 */
|
|
- .key = "\x00\x01\x02\x03\x08\x09\x0a\x0b"
|
|
- "\x10\x11\x12\x13",
|
|
- .klen = 12,
|
|
- .ptext = "\x65\x61\x6e\x73\x20\x46\x61\x74",
|
|
- .ctext = "\x6c\x94\x75\x41\xec\x52\x79\x9f",
|
|
- .len = 8,
|
|
- }, { /* Speck64/128 */
|
|
- .key = "\x00\x01\x02\x03\x08\x09\x0a\x0b"
|
|
- "\x10\x11\x12\x13\x18\x19\x1a\x1b",
|
|
- .klen = 16,
|
|
- .ptext = "\x2d\x43\x75\x74\x74\x65\x72\x3b",
|
|
- .ctext = "\x8b\x02\x4e\x45\x48\xa5\x6f\x8c",
|
|
- .len = 8,
|
|
- },
|
|
-};
|
|
-
|
|
-/*
|
|
- * Speck64-XTS test vectors, taken from the AES-XTS test vectors with the
|
|
- * ciphertext recomputed with Speck64 as the cipher, and key lengths adjusted
|
|
- */
|
|
-static const struct cipher_testvec speck64_xts_tv_template[] = {
|
|
- {
|
|
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .klen = 24,
|
|
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ctext = "\x84\xaf\x54\x07\x19\xd4\x7c\xa6"
|
|
- "\xe4\xfe\xdf\xc4\x1f\x34\xc3\xc2"
|
|
- "\x80\xf5\x72\xe7\xcd\xf0\x99\x22"
|
|
- "\x35\xa7\x2f\x06\xef\xdc\x51\xaa",
|
|
- .len = 32,
|
|
- }, {
|
|
- .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
|
|
- "\x11\x11\x11\x11\x11\x11\x11\x11"
|
|
- "\x22\x22\x22\x22\x22\x22\x22\x22",
|
|
- .klen = 24,
|
|
- .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44",
|
|
- .ctext = "\x12\x56\x73\xcd\x15\x87\xa8\x59"
|
|
- "\xcf\x84\xae\xd9\x1c\x66\xd6\x9f"
|
|
- "\xb3\x12\x69\x7e\x36\xeb\x52\xff"
|
|
- "\x62\xdd\xba\x90\xb3\xe1\xee\x99",
|
|
- .len = 32,
|
|
- }, {
|
|
- .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
|
|
- "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
|
|
- "\x22\x22\x22\x22\x22\x22\x22\x22",
|
|
- .klen = 24,
|
|
- .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44"
|
|
- "\x44\x44\x44\x44\x44\x44\x44\x44",
|
|
- .ctext = "\x15\x1b\xe4\x2c\xa2\x5a\x2d\x2c"
|
|
- "\x27\x36\xc0\xbf\x5d\xea\x36\x37"
|
|
- "\x2d\x1a\x88\xbc\x66\xb5\xd0\x0b"
|
|
- "\xa1\xbc\x19\xb2\x0f\x3b\x75\x34",
|
|
- .len = 32,
|
|
- }, {
|
|
- .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
|
|
- "\x23\x53\x60\x28\x74\x71\x35\x26"
|
|
- "\x31\x41\x59\x26\x53\x58\x97\x93",
|
|
- .klen = 24,
|
|
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
|
- "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
|
- .ctext = "\xaf\xa1\x81\xa6\x32\xbb\x15\x8e"
|
|
- "\xf8\x95\x2e\xd3\xe6\xee\x7e\x09"
|
|
- "\x0c\x1a\xf5\x02\x97\x8b\xe3\xb3"
|
|
- "\x11\xc7\x39\x96\xd0\x95\xf4\x56"
|
|
- "\xf4\xdd\x03\x38\x01\x44\x2c\xcf"
|
|
- "\x88\xae\x8e\x3c\xcd\xe7\xaa\x66"
|
|
- "\xfe\x3d\xc6\xfb\x01\x23\x51\x43"
|
|
- "\xd5\xd2\x13\x86\x94\x34\xe9\x62"
|
|
- "\xf9\x89\xe3\xd1\x7b\xbe\xf8\xef"
|
|
- "\x76\x35\x04\x3f\xdb\x23\x9d\x0b"
|
|
- "\x85\x42\xb9\x02\xd6\xcc\xdb\x96"
|
|
- "\xa7\x6b\x27\xb6\xd4\x45\x8f\x7d"
|
|
- "\xae\xd2\x04\xd5\xda\xc1\x7e\x24"
|
|
- "\x8c\x73\xbe\x48\x7e\xcf\x65\x28"
|
|
- "\x29\xe5\xbe\x54\x30\xcb\x46\x95"
|
|
- "\x4f\x2e\x8a\x36\xc8\x27\xc5\xbe"
|
|
- "\xd0\x1a\xaf\xab\x26\xcd\x9e\x69"
|
|
- "\xa1\x09\x95\x71\x26\xe9\xc4\xdf"
|
|
- "\xe6\x31\xc3\x46\xda\xaf\x0b\x41"
|
|
- "\x1f\xab\xb1\x8e\xd6\xfc\x0b\xb3"
|
|
- "\x82\xc0\x37\x27\xfc\x91\xa7\x05"
|
|
- "\xfb\xc5\xdc\x2b\x74\x96\x48\x43"
|
|
- "\x5d\x9c\x19\x0f\x60\x63\x3a\x1f"
|
|
- "\x6f\xf0\x03\xbe\x4d\xfd\xc8\x4a"
|
|
- "\xc6\xa4\x81\x6d\xc3\x12\x2a\x5c"
|
|
- "\x07\xff\xf3\x72\x74\x48\xb5\x40"
|
|
- "\x50\xb5\xdd\x90\x43\x31\x18\x15"
|
|
- "\x7b\xf2\xa6\xdb\x83\xc8\x4b\x4a"
|
|
- "\x29\x93\x90\x8b\xda\x07\xf0\x35"
|
|
- "\x6d\x90\x88\x09\x4e\x83\xf5\x5b"
|
|
- "\x94\x12\xbb\x33\x27\x1d\x3f\x23"
|
|
- "\x51\xa8\x7c\x07\xa2\xae\x77\xa6"
|
|
- "\x50\xfd\xcc\xc0\x4f\x80\x7a\x9f"
|
|
- "\x66\xdd\xcd\x75\x24\x8b\x33\xf7"
|
|
- "\x20\xdb\x83\x9b\x4f\x11\x63\x6e"
|
|
- "\xcf\x37\xef\xc9\x11\x01\x5c\x45"
|
|
- "\x32\x99\x7c\x3c\x9e\x42\x89\xe3"
|
|
- "\x70\x6d\x15\x9f\xb1\xe6\xb6\x05"
|
|
- "\xfe\x0c\xb9\x49\x2d\x90\x6d\xcc"
|
|
- "\x5d\x3f\xc1\xfe\x89\x0a\x2e\x2d"
|
|
- "\xa0\xa8\x89\x3b\x73\x39\xa5\x94"
|
|
- "\x4c\xa4\xa6\xbb\xa7\x14\x46\x89"
|
|
- "\x10\xff\xaf\xef\xca\xdd\x4f\x80"
|
|
- "\xb3\xdf\x3b\xab\xd4\xe5\x5a\xc7"
|
|
- "\x33\xca\x00\x8b\x8b\x3f\xea\xec"
|
|
- "\x68\x8a\xc2\x6d\xfd\xd4\x67\x0f"
|
|
- "\x22\x31\xe1\x0e\xfe\x5a\x04\xd5"
|
|
- "\x64\xa3\xf1\x1a\x76\x28\xcc\x35"
|
|
- "\x36\xa7\x0a\x74\xf7\x1c\x44\x9b"
|
|
- "\xc7\x1b\x53\x17\x02\xea\xd1\xad"
|
|
- "\x13\x51\x73\xc0\xa0\xb2\x05\x32"
|
|
- "\xa8\xa2\x37\x2e\xe1\x7a\x3a\x19"
|
|
- "\x26\xb4\x6c\x62\x5d\xb3\x1a\x1d"
|
|
- "\x59\xda\xee\x1a\x22\x18\xda\x0d"
|
|
- "\x88\x0f\x55\x8b\x72\x62\xfd\xc1"
|
|
- "\x69\x13\xcd\x0d\x5f\xc1\x09\x52"
|
|
- "\xee\xd6\xe3\x84\x4d\xee\xf6\x88"
|
|
- "\xaf\x83\xdc\x76\xf4\xc0\x93\x3f"
|
|
- "\x4a\x75\x2f\xb0\x0b\x3e\xc4\x54"
|
|
- "\x7d\x69\x8d\x00\x62\x77\x0d\x14"
|
|
- "\xbe\x7c\xa6\x7d\xc5\x24\x4f\xf3"
|
|
- "\x50\xf7\x5f\xf4\xc2\xca\x41\x97"
|
|
- "\x37\xbe\x75\x74\xcd\xf0\x75\x6e"
|
|
- "\x25\x23\x94\xbd\xda\x8d\xb0\xd4",
|
|
- .len = 512,
|
|
- }, {
|
|
- .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
|
|
- "\x23\x53\x60\x28\x74\x71\x35\x26"
|
|
- "\x62\x49\x77\x57\x24\x70\x93\x69"
|
|
- "\x99\x59\x57\x49\x66\x96\x76\x27",
|
|
- .klen = 32,
|
|
- .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
|
|
- "\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
|
- "\x00\x01\x02\x03\x04\x05\x06\x07"
|
|
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
|
- "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
|
- "\x20\x21\x22\x23\x24\x25\x26\x27"
|
|
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
|
- "\x30\x31\x32\x33\x34\x35\x36\x37"
|
|
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
|
- "\x40\x41\x42\x43\x44\x45\x46\x47"
|
|
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
|
- "\x50\x51\x52\x53\x54\x55\x56\x57"
|
|
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
|
- "\x60\x61\x62\x63\x64\x65\x66\x67"
|
|
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
|
- "\x70\x71\x72\x73\x74\x75\x76\x77"
|
|
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
|
- "\x80\x81\x82\x83\x84\x85\x86\x87"
|
|
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
|
- "\x90\x91\x92\x93\x94\x95\x96\x97"
|
|
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
|
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
|
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
|
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
|
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
|
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
|
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
|
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
|
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
|
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
|
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
|
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
|
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
|
- .ctext = "\x55\xed\x71\xd3\x02\x8e\x15\x3b"
|
|
- "\xc6\x71\x29\x2d\x3e\x89\x9f\x59"
|
|
- "\x68\x6a\xcc\x8a\x56\x97\xf3\x95"
|
|
- "\x4e\x51\x08\xda\x2a\xf8\x6f\x3c"
|
|
- "\x78\x16\xea\x80\xdb\x33\x75\x94"
|
|
- "\xf9\x29\xc4\x2b\x76\x75\x97\xc7"
|
|
- "\xf2\x98\x2c\xf9\xff\xc8\xd5\x2b"
|
|
- "\x18\xf1\xaf\xcf\x7c\xc5\x0b\xee"
|
|
- "\xad\x3c\x76\x7c\xe6\x27\xa2\x2a"
|
|
- "\xe4\x66\xe1\xab\xa2\x39\xfc\x7c"
|
|
- "\xf5\xec\x32\x74\xa3\xb8\x03\x88"
|
|
- "\x52\xfc\x2e\x56\x3f\xa1\xf0\x9f"
|
|
- "\x84\x5e\x46\xed\x20\x89\xb6\x44"
|
|
- "\x8d\xd0\xed\x54\x47\x16\xbe\x95"
|
|
- "\x8a\xb3\x6b\x72\xc4\x32\x52\x13"
|
|
- "\x1b\xb0\x82\xbe\xac\xf9\x70\xa6"
|
|
- "\x44\x18\xdd\x8c\x6e\xca\x6e\x45"
|
|
- "\x8f\x1e\x10\x07\x57\x25\x98\x7b"
|
|
- "\x17\x8c\x78\xdd\x80\xa7\xd9\xd8"
|
|
- "\x63\xaf\xb9\x67\x57\xfd\xbc\xdb"
|
|
- "\x44\xe9\xc5\x65\xd1\xc7\x3b\xff"
|
|
- "\x20\xa0\x80\x1a\xc3\x9a\xad\x5e"
|
|
- "\x5d\x3b\xd3\x07\xd9\xf5\xfd\x3d"
|
|
- "\x4a\x8b\xa8\xd2\x6e\x7a\x51\x65"
|
|
- "\x6c\x8e\x95\xe0\x45\xc9\x5f\x4a"
|
|
- "\x09\x3c\x3d\x71\x7f\x0c\x84\x2a"
|
|
- "\xc8\x48\x52\x1a\xc2\xd5\xd6\x78"
|
|
- "\x92\x1e\xa0\x90\x2e\xea\xf0\xf3"
|
|
- "\xdc\x0f\xb1\xaf\x0d\x9b\x06\x2e"
|
|
- "\x35\x10\x30\x82\x0d\xe7\xc5\x9b"
|
|
- "\xde\x44\x18\xbd\x9f\xd1\x45\xa9"
|
|
- "\x7b\x7a\x4a\xad\x35\x65\x27\xca"
|
|
- "\xb2\xc3\xd4\x9b\x71\x86\x70\xee"
|
|
- "\xf1\x89\x3b\x85\x4b\x5b\xaa\xaf"
|
|
- "\xfc\x42\xc8\x31\x59\xbe\x16\x60"
|
|
- "\x4f\xf9\xfa\x12\xea\xd0\xa7\x14"
|
|
- "\xf0\x7a\xf3\xd5\x8d\xbd\x81\xef"
|
|
- "\x52\x7f\x29\x51\x94\x20\x67\x3c"
|
|
- "\xd1\xaf\x77\x9f\x22\x5a\x4e\x63"
|
|
- "\xe7\xff\x73\x25\xd1\xdd\x96\x8a"
|
|
- "\x98\x52\x6d\xf3\xac\x3e\xf2\x18"
|
|
- "\x6d\xf6\x0a\x29\xa6\x34\x3d\xed"
|
|
- "\xe3\x27\x0d\x9d\x0a\x02\x44\x7e"
|
|
- "\x5a\x7e\x67\x0f\x0a\x9e\xd6\xad"
|
|
- "\x91\xe6\x4d\x81\x8c\x5c\x59\xaa"
|
|
- "\xfb\xeb\x56\x53\xd2\x7d\x4c\x81"
|
|
- "\x65\x53\x0f\x41\x11\xbd\x98\x99"
|
|
- "\xf9\xc6\xfa\x51\x2e\xa3\xdd\x8d"
|
|
- "\x84\x98\xf9\x34\xed\x33\x2a\x1f"
|
|
- "\x82\xed\xc1\x73\x98\xd3\x02\xdc"
|
|
- "\xe6\xc2\x33\x1d\xa2\xb4\xca\x76"
|
|
- "\x63\x51\x34\x9d\x96\x12\xae\xce"
|
|
- "\x83\xc9\x76\x5e\xa4\x1b\x53\x37"
|
|
- "\x17\xd5\xc0\x80\x1d\x62\xf8\x3d"
|
|
- "\x54\x27\x74\xbb\x10\x86\x57\x46"
|
|
- "\x68\xe1\xed\x14\xe7\x9d\xfc\x84"
|
|
- "\x47\xbc\xc2\xf8\x19\x4b\x99\xcf"
|
|
- "\x7a\xe9\xc4\xb8\x8c\x82\x72\x4d"
|
|
- "\x7b\x4f\x38\x55\x36\x71\x64\xc1"
|
|
- "\xfc\x5c\x75\x52\x33\x02\x18\xf8"
|
|
- "\x17\xe1\x2b\xc2\x43\x39\xbd\x76"
|
|
- "\x9b\x63\x76\x32\x2f\x19\x72\x10"
|
|
- "\x9f\x21\x0c\xf1\x66\x50\x7f\xa5"
|
|
- "\x0d\x1f\x46\xe0\xba\xd3\x2f\x3c",
|
|
- .len = 512,
|
|
- .also_non_np = 1,
|
|
- .np = 3,
|
|
- .tap = { 512 - 20, 4, 16 },
|
|
- }
|
|
-};
|
|
-
|
|
/* Cast6 test vectors from RFC 2612 */
|
|
static const struct cipher_testvec cast6_tv_template[] = {
|
|
{
|
|
diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c
|
|
index cf4fc0161164..e43cb71b6972 100644
|
|
--- a/drivers/acpi/acpi_lpit.c
|
|
+++ b/drivers/acpi/acpi_lpit.c
|
|
@@ -117,11 +117,17 @@ static void lpit_update_residency(struct lpit_residency_info *info,
|
|
if (!info->iomem_addr)
|
|
return;
|
|
|
|
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
|
|
+ return;
|
|
+
|
|
/* Silently fail, if cpuidle attribute group is not present */
|
|
sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj,
|
|
&dev_attr_low_power_idle_system_residency_us.attr,
|
|
"cpuidle");
|
|
} else if (info->gaddr.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
|
|
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
|
|
+ return;
|
|
+
|
|
/* Silently fail, if cpuidle attribute group is not present */
|
|
sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj,
|
|
&dev_attr_low_power_idle_cpu_residency_us.attr,
|
|
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
|
|
index bf64cfa30feb..969bf8d515c0 100644
|
|
--- a/drivers/acpi/acpi_lpss.c
|
|
+++ b/drivers/acpi/acpi_lpss.c
|
|
@@ -327,9 +327,11 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
|
{ "INT33FC", },
|
|
|
|
/* Braswell LPSS devices */
|
|
+ { "80862286", LPSS_ADDR(lpss_dma_desc) },
|
|
{ "80862288", LPSS_ADDR(bsw_pwm_dev_desc) },
|
|
{ "8086228A", LPSS_ADDR(bsw_uart_dev_desc) },
|
|
{ "8086228E", LPSS_ADDR(bsw_spi_dev_desc) },
|
|
+ { "808622C0", LPSS_ADDR(lpss_dma_desc) },
|
|
{ "808622C1", LPSS_ADDR(bsw_i2c_dev_desc) },
|
|
|
|
/* Broadwell LPSS devices */
|
|
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
|
|
index 449d86d39965..fc447410ae4d 100644
|
|
--- a/drivers/acpi/acpi_processor.c
|
|
+++ b/drivers/acpi/acpi_processor.c
|
|
@@ -643,7 +643,7 @@ static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,
|
|
|
|
status = acpi_get_type(handle, &acpi_type);
|
|
if (ACPI_FAILURE(status))
|
|
- return false;
|
|
+ return status;
|
|
|
|
switch (acpi_type) {
|
|
case ACPI_TYPE_PROCESSOR:
|
|
@@ -663,11 +663,12 @@ static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,
|
|
}
|
|
|
|
processor_validated_ids_update(uid);
|
|
- return true;
|
|
+ return AE_OK;
|
|
|
|
err:
|
|
+ /* Exit on error, but don't abort the namespace walk */
|
|
acpi_handle_info(handle, "Invalid processor object\n");
|
|
- return false;
|
|
+ return AE_OK;
|
|
|
|
}
|
|
|
|
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
|
|
index e9fb0bf3c8d2..78f9de260d5f 100644
|
|
--- a/drivers/acpi/acpica/dsopcode.c
|
|
+++ b/drivers/acpi/acpica/dsopcode.c
|
|
@@ -417,6 +417,10 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
|
|
ACPI_FORMAT_UINT64(obj_desc->region.address),
|
|
obj_desc->region.length));
|
|
|
|
+ status = acpi_ut_add_address_range(obj_desc->region.space_id,
|
|
+ obj_desc->region.address,
|
|
+ obj_desc->region.length, node);
|
|
+
|
|
/* Now the address and length are valid for this opregion */
|
|
|
|
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
|
|
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
|
|
index 34fc2f7476ed..b0789c483b0f 100644
|
|
--- a/drivers/acpi/acpica/psloop.c
|
|
+++ b/drivers/acpi/acpica/psloop.c
|
|
@@ -417,6 +417,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
|
|
union acpi_parse_object *op = NULL; /* current op */
|
|
struct acpi_parse_state *parser_state;
|
|
u8 *aml_op_start = NULL;
|
|
+ u8 opcode_length;
|
|
|
|
ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
|
|
|
|
@@ -540,8 +541,19 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
|
|
"Skip parsing opcode %s",
|
|
acpi_ps_get_opcode_name
|
|
(walk_state->opcode)));
|
|
+
|
|
+ /*
|
|
+ * Determine the opcode length before skipping the opcode.
|
|
+ * An opcode can be 1 byte or 2 bytes in length.
|
|
+ */
|
|
+ opcode_length = 1;
|
|
+ if ((walk_state->opcode & 0xFF00) ==
|
|
+ AML_EXTENDED_OPCODE) {
|
|
+ opcode_length = 2;
|
|
+ }
|
|
walk_state->parser_state.aml =
|
|
- walk_state->aml + 1;
|
|
+ walk_state->aml + opcode_length;
|
|
+
|
|
walk_state->parser_state.aml =
|
|
acpi_ps_get_next_package_end
|
|
(&walk_state->parser_state);
|
|
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
|
|
index b072cfc5f20e..19b641208d86 100644
|
|
--- a/drivers/acpi/nfit/core.c
|
|
+++ b/drivers/acpi/nfit/core.c
|
|
@@ -2466,7 +2466,8 @@ static int ars_get_cap(struct acpi_nfit_desc *acpi_desc,
|
|
return cmd_rc;
|
|
}
|
|
|
|
-static int ars_start(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa)
|
|
+static int ars_start(struct acpi_nfit_desc *acpi_desc,
|
|
+ struct nfit_spa *nfit_spa, enum nfit_ars_state req_type)
|
|
{
|
|
int rc;
|
|
int cmd_rc;
|
|
@@ -2477,7 +2478,7 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa
|
|
memset(&ars_start, 0, sizeof(ars_start));
|
|
ars_start.address = spa->address;
|
|
ars_start.length = spa->length;
|
|
- if (test_bit(ARS_SHORT, &nfit_spa->ars_state))
|
|
+ if (req_type == ARS_REQ_SHORT)
|
|
ars_start.flags = ND_ARS_RETURN_PREV_DATA;
|
|
if (nfit_spa_type(spa) == NFIT_SPA_PM)
|
|
ars_start.type = ND_ARS_PERSISTENT;
|
|
@@ -2534,6 +2535,15 @@ static void ars_complete(struct acpi_nfit_desc *acpi_desc,
|
|
struct nd_region *nd_region = nfit_spa->nd_region;
|
|
struct device *dev;
|
|
|
|
+ lockdep_assert_held(&acpi_desc->init_mutex);
|
|
+ /*
|
|
+ * Only advance the ARS state for ARS runs initiated by the
|
|
+ * kernel, ignore ARS results from BIOS initiated runs for scrub
|
|
+ * completion tracking.
|
|
+ */
|
|
+ if (acpi_desc->scrub_spa != nfit_spa)
|
|
+ return;
|
|
+
|
|
if ((ars_status->address >= spa->address && ars_status->address
|
|
< spa->address + spa->length)
|
|
|| (ars_status->address < spa->address)) {
|
|
@@ -2553,28 +2563,13 @@ static void ars_complete(struct acpi_nfit_desc *acpi_desc,
|
|
} else
|
|
return;
|
|
|
|
- if (test_bit(ARS_DONE, &nfit_spa->ars_state))
|
|
- return;
|
|
-
|
|
- if (!test_and_clear_bit(ARS_REQ, &nfit_spa->ars_state))
|
|
- return;
|
|
-
|
|
+ acpi_desc->scrub_spa = NULL;
|
|
if (nd_region) {
|
|
dev = nd_region_dev(nd_region);
|
|
nvdimm_region_notify(nd_region, NVDIMM_REVALIDATE_POISON);
|
|
} else
|
|
dev = acpi_desc->dev;
|
|
-
|
|
- dev_dbg(dev, "ARS: range %d %s complete\n", spa->range_index,
|
|
- test_bit(ARS_SHORT, &nfit_spa->ars_state)
|
|
- ? "short" : "long");
|
|
- clear_bit(ARS_SHORT, &nfit_spa->ars_state);
|
|
- if (test_and_clear_bit(ARS_REQ_REDO, &nfit_spa->ars_state)) {
|
|
- set_bit(ARS_SHORT, &nfit_spa->ars_state);
|
|
- set_bit(ARS_REQ, &nfit_spa->ars_state);
|
|
- dev_dbg(dev, "ARS: processing scrub request received while in progress\n");
|
|
- } else
|
|
- set_bit(ARS_DONE, &nfit_spa->ars_state);
|
|
+ dev_dbg(dev, "ARS: range %d complete\n", spa->range_index);
|
|
}
|
|
|
|
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
|
|
@@ -2855,46 +2850,55 @@ static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc)
|
|
return 0;
|
|
}
|
|
|
|
-static int ars_register(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa,
|
|
- int *query_rc)
|
|
+static int ars_register(struct acpi_nfit_desc *acpi_desc,
|
|
+ struct nfit_spa *nfit_spa)
|
|
{
|
|
- int rc = *query_rc;
|
|
+ int rc;
|
|
|
|
- if (no_init_ars)
|
|
+ if (no_init_ars || test_bit(ARS_FAILED, &nfit_spa->ars_state))
|
|
return acpi_nfit_register_region(acpi_desc, nfit_spa);
|
|
|
|
- set_bit(ARS_REQ, &nfit_spa->ars_state);
|
|
- set_bit(ARS_SHORT, &nfit_spa->ars_state);
|
|
+ set_bit(ARS_REQ_SHORT, &nfit_spa->ars_state);
|
|
+ set_bit(ARS_REQ_LONG, &nfit_spa->ars_state);
|
|
|
|
- switch (rc) {
|
|
+ switch (acpi_nfit_query_poison(acpi_desc)) {
|
|
case 0:
|
|
case -EAGAIN:
|
|
- rc = ars_start(acpi_desc, nfit_spa);
|
|
- if (rc == -EBUSY) {
|
|
- *query_rc = rc;
|
|
+ rc = ars_start(acpi_desc, nfit_spa, ARS_REQ_SHORT);
|
|
+ /* shouldn't happen, try again later */
|
|
+ if (rc == -EBUSY)
|
|
break;
|
|
- } else if (rc == 0) {
|
|
- rc = acpi_nfit_query_poison(acpi_desc);
|
|
- } else {
|
|
+ if (rc) {
|
|
set_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
break;
|
|
}
|
|
- if (rc == -EAGAIN)
|
|
- clear_bit(ARS_SHORT, &nfit_spa->ars_state);
|
|
- else if (rc == 0)
|
|
- ars_complete(acpi_desc, nfit_spa);
|
|
+ clear_bit(ARS_REQ_SHORT, &nfit_spa->ars_state);
|
|
+ rc = acpi_nfit_query_poison(acpi_desc);
|
|
+ if (rc)
|
|
+ break;
|
|
+ acpi_desc->scrub_spa = nfit_spa;
|
|
+ ars_complete(acpi_desc, nfit_spa);
|
|
+ /*
|
|
+ * If ars_complete() says we didn't complete the
|
|
+ * short scrub, we'll try again with a long
|
|
+ * request.
|
|
+ */
|
|
+ acpi_desc->scrub_spa = NULL;
|
|
break;
|
|
case -EBUSY:
|
|
+ case -ENOMEM:
|
|
case -ENOSPC:
|
|
+ /*
|
|
+ * BIOS was using ARS, wait for it to complete (or
|
|
+ * resources to become available) and then perform our
|
|
+ * own scrubs.
|
|
+ */
|
|
break;
|
|
default:
|
|
set_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
break;
|
|
}
|
|
|
|
- if (test_and_clear_bit(ARS_DONE, &nfit_spa->ars_state))
|
|
- set_bit(ARS_REQ, &nfit_spa->ars_state);
|
|
-
|
|
return acpi_nfit_register_region(acpi_desc, nfit_spa);
|
|
}
|
|
|
|
@@ -2916,6 +2920,8 @@ static unsigned int __acpi_nfit_scrub(struct acpi_nfit_desc *acpi_desc,
|
|
struct device *dev = acpi_desc->dev;
|
|
struct nfit_spa *nfit_spa;
|
|
|
|
+ lockdep_assert_held(&acpi_desc->init_mutex);
|
|
+
|
|
if (acpi_desc->cancel)
|
|
return 0;
|
|
|
|
@@ -2939,21 +2945,49 @@ static unsigned int __acpi_nfit_scrub(struct acpi_nfit_desc *acpi_desc,
|
|
|
|
ars_complete_all(acpi_desc);
|
|
list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
|
|
+ enum nfit_ars_state req_type;
|
|
+ int rc;
|
|
+
|
|
if (test_bit(ARS_FAILED, &nfit_spa->ars_state))
|
|
continue;
|
|
- if (test_bit(ARS_REQ, &nfit_spa->ars_state)) {
|
|
- int rc = ars_start(acpi_desc, nfit_spa);
|
|
-
|
|
- clear_bit(ARS_DONE, &nfit_spa->ars_state);
|
|
- dev = nd_region_dev(nfit_spa->nd_region);
|
|
- dev_dbg(dev, "ARS: range %d ARS start (%d)\n",
|
|
- nfit_spa->spa->range_index, rc);
|
|
- if (rc == 0 || rc == -EBUSY)
|
|
- return 1;
|
|
- dev_err(dev, "ARS: range %d ARS failed (%d)\n",
|
|
- nfit_spa->spa->range_index, rc);
|
|
- set_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
+
|
|
+ /* prefer short ARS requests first */
|
|
+ if (test_bit(ARS_REQ_SHORT, &nfit_spa->ars_state))
|
|
+ req_type = ARS_REQ_SHORT;
|
|
+ else if (test_bit(ARS_REQ_LONG, &nfit_spa->ars_state))
|
|
+ req_type = ARS_REQ_LONG;
|
|
+ else
|
|
+ continue;
|
|
+ rc = ars_start(acpi_desc, nfit_spa, req_type);
|
|
+
|
|
+ dev = nd_region_dev(nfit_spa->nd_region);
|
|
+ dev_dbg(dev, "ARS: range %d ARS start %s (%d)\n",
|
|
+ nfit_spa->spa->range_index,
|
|
+ req_type == ARS_REQ_SHORT ? "short" : "long",
|
|
+ rc);
|
|
+ /*
|
|
+ * Hmm, we raced someone else starting ARS? Try again in
|
|
+ * a bit.
|
|
+ */
|
|
+ if (rc == -EBUSY)
|
|
+ return 1;
|
|
+ if (rc == 0) {
|
|
+ dev_WARN_ONCE(dev, acpi_desc->scrub_spa,
|
|
+ "scrub start while range %d active\n",
|
|
+ acpi_desc->scrub_spa->spa->range_index);
|
|
+ clear_bit(req_type, &nfit_spa->ars_state);
|
|
+ acpi_desc->scrub_spa = nfit_spa;
|
|
+ /*
|
|
+ * Consider this spa last for future scrub
|
|
+ * requests
|
|
+ */
|
|
+ list_move_tail(&nfit_spa->list, &acpi_desc->spas);
|
|
+ return 1;
|
|
}
|
|
+
|
|
+ dev_err(dev, "ARS: range %d ARS failed (%d)\n",
|
|
+ nfit_spa->spa->range_index, rc);
|
|
+ set_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -3009,6 +3043,7 @@ static void acpi_nfit_init_ars(struct acpi_nfit_desc *acpi_desc,
|
|
struct nd_cmd_ars_cap ars_cap;
|
|
int rc;
|
|
|
|
+ set_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
memset(&ars_cap, 0, sizeof(ars_cap));
|
|
rc = ars_get_cap(acpi_desc, &ars_cap, nfit_spa);
|
|
if (rc < 0)
|
|
@@ -3025,16 +3060,14 @@ static void acpi_nfit_init_ars(struct acpi_nfit_desc *acpi_desc,
|
|
nfit_spa->clear_err_unit = ars_cap.clear_err_unit;
|
|
acpi_desc->max_ars = max(nfit_spa->max_ars, acpi_desc->max_ars);
|
|
clear_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
- set_bit(ARS_REQ, &nfit_spa->ars_state);
|
|
}
|
|
|
|
static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
|
{
|
|
struct nfit_spa *nfit_spa;
|
|
- int rc, query_rc;
|
|
+ int rc;
|
|
|
|
list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
|
|
- set_bit(ARS_FAILED, &nfit_spa->ars_state);
|
|
switch (nfit_spa_type(nfit_spa->spa)) {
|
|
case NFIT_SPA_VOLATILE:
|
|
case NFIT_SPA_PM:
|
|
@@ -3043,20 +3076,12 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
|
}
|
|
}
|
|
|
|
- /*
|
|
- * Reap any results that might be pending before starting new
|
|
- * short requests.
|
|
- */
|
|
- query_rc = acpi_nfit_query_poison(acpi_desc);
|
|
- if (query_rc == 0)
|
|
- ars_complete_all(acpi_desc);
|
|
-
|
|
list_for_each_entry(nfit_spa, &acpi_desc->spas, list)
|
|
switch (nfit_spa_type(nfit_spa->spa)) {
|
|
case NFIT_SPA_VOLATILE:
|
|
case NFIT_SPA_PM:
|
|
/* register regions and kick off initial ARS run */
|
|
- rc = ars_register(acpi_desc, nfit_spa, &query_rc);
|
|
+ rc = ars_register(acpi_desc, nfit_spa);
|
|
if (rc)
|
|
return rc;
|
|
break;
|
|
@@ -3251,7 +3276,8 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
|
|
return 0;
|
|
}
|
|
|
|
-int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags)
|
|
+int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
|
|
+ enum nfit_ars_state req_type)
|
|
{
|
|
struct device *dev = acpi_desc->dev;
|
|
int scheduled = 0, busy = 0;
|
|
@@ -3271,14 +3297,10 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags)
|
|
if (test_bit(ARS_FAILED, &nfit_spa->ars_state))
|
|
continue;
|
|
|
|
- if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state)) {
|
|
+ if (test_and_set_bit(req_type, &nfit_spa->ars_state))
|
|
busy++;
|
|
- set_bit(ARS_REQ_REDO, &nfit_spa->ars_state);
|
|
- } else {
|
|
- if (test_bit(ARS_SHORT, &flags))
|
|
- set_bit(ARS_SHORT, &nfit_spa->ars_state);
|
|
+ else
|
|
scheduled++;
|
|
- }
|
|
}
|
|
if (scheduled) {
|
|
sched_ars(acpi_desc);
|
|
@@ -3464,10 +3486,11 @@ static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
|
|
static void acpi_nfit_uc_error_notify(struct device *dev, acpi_handle handle)
|
|
{
|
|
struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
|
|
- unsigned long flags = (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON) ?
|
|
- 0 : 1 << ARS_SHORT;
|
|
|
|
- acpi_nfit_ars_rescan(acpi_desc, flags);
|
|
+ if (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON)
|
|
+ acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG);
|
|
+ else
|
|
+ acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_SHORT);
|
|
}
|
|
|
|
void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
|
|
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
|
|
index d1274ea2d251..02c10de50386 100644
|
|
--- a/drivers/acpi/nfit/nfit.h
|
|
+++ b/drivers/acpi/nfit/nfit.h
|
|
@@ -118,10 +118,8 @@ enum nfit_dimm_notifiers {
|
|
};
|
|
|
|
enum nfit_ars_state {
|
|
- ARS_REQ,
|
|
- ARS_REQ_REDO,
|
|
- ARS_DONE,
|
|
- ARS_SHORT,
|
|
+ ARS_REQ_SHORT,
|
|
+ ARS_REQ_LONG,
|
|
ARS_FAILED,
|
|
};
|
|
|
|
@@ -198,6 +196,7 @@ struct acpi_nfit_desc {
|
|
struct device *dev;
|
|
u8 ars_start_flags;
|
|
struct nd_cmd_ars_status *ars_status;
|
|
+ struct nfit_spa *scrub_spa;
|
|
struct delayed_work dwork;
|
|
struct list_head list;
|
|
struct kernfs_node *scrub_count_state;
|
|
@@ -252,7 +251,8 @@ struct nfit_blk {
|
|
|
|
extern struct list_head acpi_descs;
|
|
extern struct mutex acpi_desc_lock;
|
|
-int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags);
|
|
+int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
|
|
+ enum nfit_ars_state req_type);
|
|
|
|
#ifdef CONFIG_X86_MCE
|
|
void nfit_mce_register(void);
|
|
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
|
|
index 8df9abfa947b..ed73f6fb0779 100644
|
|
--- a/drivers/acpi/osl.c
|
|
+++ b/drivers/acpi/osl.c
|
|
@@ -617,15 +617,18 @@ void acpi_os_stall(u32 us)
|
|
}
|
|
|
|
/*
|
|
- * Support ACPI 3.0 AML Timer operand
|
|
- * Returns 64-bit free-running, monotonically increasing timer
|
|
- * with 100ns granularity
|
|
+ * Support ACPI 3.0 AML Timer operand. Returns a 64-bit free-running,
|
|
+ * monotonically increasing timer with 100ns granularity. Do not use
|
|
+ * ktime_get() to implement this function because this function may get
|
|
+ * called after timekeeping has been suspended. Note: calling this function
|
|
+ * after timekeeping has been suspended may lead to unexpected results
|
|
+ * because when timekeeping is suspended the jiffies counter is not
|
|
+ * incremented. See also timekeeping_suspend().
|
|
*/
|
|
u64 acpi_os_get_timer(void)
|
|
{
|
|
- u64 time_ns = ktime_to_ns(ktime_get());
|
|
- do_div(time_ns, 100);
|
|
- return time_ns;
|
|
+ return (get_jiffies_64() - INITIAL_JIFFIES) *
|
|
+ (ACPI_100NSEC_PER_SEC / HZ);
|
|
}
|
|
|
|
acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
|
|
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
|
|
index d1e26cb599bf..da031b1df6f5 100644
|
|
--- a/drivers/acpi/pptt.c
|
|
+++ b/drivers/acpi/pptt.c
|
|
@@ -338,9 +338,6 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
|
|
return found;
|
|
}
|
|
|
|
-/* total number of attributes checked by the properties code */
|
|
-#define PPTT_CHECKED_ATTRIBUTES 4
|
|
-
|
|
/**
|
|
* update_cache_properties() - Update cacheinfo for the given processor
|
|
* @this_leaf: Kernel cache info structure being updated
|
|
@@ -357,25 +354,15 @@ static void update_cache_properties(struct cacheinfo *this_leaf,
|
|
struct acpi_pptt_cache *found_cache,
|
|
struct acpi_pptt_processor *cpu_node)
|
|
{
|
|
- int valid_flags = 0;
|
|
-
|
|
this_leaf->fw_token = cpu_node;
|
|
- if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID) {
|
|
+ if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID)
|
|
this_leaf->size = found_cache->size;
|
|
- valid_flags++;
|
|
- }
|
|
- if (found_cache->flags & ACPI_PPTT_LINE_SIZE_VALID) {
|
|
+ if (found_cache->flags & ACPI_PPTT_LINE_SIZE_VALID)
|
|
this_leaf->coherency_line_size = found_cache->line_size;
|
|
- valid_flags++;
|
|
- }
|
|
- if (found_cache->flags & ACPI_PPTT_NUMBER_OF_SETS_VALID) {
|
|
+ if (found_cache->flags & ACPI_PPTT_NUMBER_OF_SETS_VALID)
|
|
this_leaf->number_of_sets = found_cache->number_of_sets;
|
|
- valid_flags++;
|
|
- }
|
|
- if (found_cache->flags & ACPI_PPTT_ASSOCIATIVITY_VALID) {
|
|
+ if (found_cache->flags & ACPI_PPTT_ASSOCIATIVITY_VALID)
|
|
this_leaf->ways_of_associativity = found_cache->associativity;
|
|
- valid_flags++;
|
|
- }
|
|
if (found_cache->flags & ACPI_PPTT_WRITE_POLICY_VALID) {
|
|
switch (found_cache->attributes & ACPI_PPTT_MASK_WRITE_POLICY) {
|
|
case ACPI_PPTT_CACHE_POLICY_WT:
|
|
@@ -402,11 +389,17 @@ static void update_cache_properties(struct cacheinfo *this_leaf,
|
|
}
|
|
}
|
|
/*
|
|
- * If the above flags are valid, and the cache type is NOCACHE
|
|
- * update the cache type as well.
|
|
+ * If cache type is NOCACHE, then the cache hasn't been specified
|
|
+ * via other mechanisms. Update the type if a cache type has been
|
|
+ * provided.
|
|
+ *
|
|
+ * Note, we assume such caches are unified based on conventional system
|
|
+ * design and known examples. Significant work is required elsewhere to
|
|
+ * fully support data/instruction only type caches which are only
|
|
+ * specified in PPTT.
|
|
*/
|
|
if (this_leaf->type == CACHE_TYPE_NOCACHE &&
|
|
- valid_flags == PPTT_CHECKED_ATTRIBUTES)
|
|
+ found_cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)
|
|
this_leaf->type = CACHE_TYPE_UNIFIED;
|
|
}
|
|
|
|
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
|
|
index a9dd4ea7467d..6e594644cb1d 100644
|
|
--- a/drivers/ata/libata-core.c
|
|
+++ b/drivers/ata/libata-core.c
|
|
@@ -4553,6 +4553,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|
/* These specific Samsung models/firmware-revs do not handle LPM well */
|
|
{ "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM, },
|
|
{ "SAMSUNG SSD PM830 mSATA *", "CXM13D1Q", ATA_HORKAGE_NOLPM, },
|
|
+ { "SAMSUNG MZ7TD256HAFV-000L9", "DXT02L5Q", ATA_HORKAGE_NOLPM, },
|
|
|
|
/* devices that don't properly handle queued TRIM commands */
|
|
{ "Micron_M500IT_*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
|
|
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
|
|
index dfb2c2622e5a..822e3060d834 100644
|
|
--- a/drivers/block/ataflop.c
|
|
+++ b/drivers/block/ataflop.c
|
|
@@ -1935,6 +1935,11 @@ static int __init atari_floppy_init (void)
|
|
unit[i].disk = alloc_disk(1);
|
|
if (!unit[i].disk)
|
|
goto Enomem;
|
|
+
|
|
+ unit[i].disk->queue = blk_init_queue(do_fd_request,
|
|
+ &ataflop_lock);
|
|
+ if (!unit[i].disk->queue)
|
|
+ goto Enomem;
|
|
}
|
|
|
|
if (UseTrackbuffer < 0)
|
|
@@ -1966,10 +1971,6 @@ static int __init atari_floppy_init (void)
|
|
sprintf(unit[i].disk->disk_name, "fd%d", i);
|
|
unit[i].disk->fops = &floppy_fops;
|
|
unit[i].disk->private_data = &unit[i];
|
|
- unit[i].disk->queue = blk_init_queue(do_fd_request,
|
|
- &ataflop_lock);
|
|
- if (!unit[i].disk->queue)
|
|
- goto Enomem;
|
|
set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
|
|
add_disk(unit[i].disk);
|
|
}
|
|
@@ -1984,13 +1985,17 @@ static int __init atari_floppy_init (void)
|
|
|
|
return 0;
|
|
Enomem:
|
|
- while (i--) {
|
|
- struct request_queue *q = unit[i].disk->queue;
|
|
+ do {
|
|
+ struct gendisk *disk = unit[i].disk;
|
|
|
|
- put_disk(unit[i].disk);
|
|
- if (q)
|
|
- blk_cleanup_queue(q);
|
|
- }
|
|
+ if (disk) {
|
|
+ if (disk->queue) {
|
|
+ blk_cleanup_queue(disk->queue);
|
|
+ disk->queue = NULL;
|
|
+ }
|
|
+ put_disk(unit[i].disk);
|
|
+ }
|
|
+ } while (i--);
|
|
|
|
unregister_blkdev(FLOPPY_MAJOR, "fd");
|
|
return -ENOMEM;
|
|
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
|
|
index 0e31884a9519..cbe909c51847 100644
|
|
--- a/drivers/block/swim.c
|
|
+++ b/drivers/block/swim.c
|
|
@@ -887,8 +887,17 @@ static int swim_floppy_init(struct swim_priv *swd)
|
|
|
|
exit_put_disks:
|
|
unregister_blkdev(FLOPPY_MAJOR, "fd");
|
|
- while (drive--)
|
|
- put_disk(swd->unit[drive].disk);
|
|
+ do {
|
|
+ struct gendisk *disk = swd->unit[drive].disk;
|
|
+
|
|
+ if (disk) {
|
|
+ if (disk->queue) {
|
|
+ blk_cleanup_queue(disk->queue);
|
|
+ disk->queue = NULL;
|
|
+ }
|
|
+ put_disk(disk);
|
|
+ }
|
|
+ } while (drive--);
|
|
return err;
|
|
}
|
|
|
|
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
|
|
index 429d20131c7e..3e905da33bcb 100644
|
|
--- a/drivers/block/xen-blkfront.c
|
|
+++ b/drivers/block/xen-blkfront.c
|
|
@@ -1919,6 +1919,7 @@ static int negotiate_mq(struct blkfront_info *info)
|
|
GFP_KERNEL);
|
|
if (!info->rinfo) {
|
|
xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
|
|
+ info->nr_rings = 0;
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -2493,6 +2494,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
|
|
|
|
dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename);
|
|
|
|
+ if (!info)
|
|
+ return 0;
|
|
+
|
|
blkif_free(info, 0);
|
|
|
|
mutex_lock(&info->mutex);
|
|
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
|
|
index 99cde1f9467d..e3e4d929e74f 100644
|
|
--- a/drivers/bluetooth/btbcm.c
|
|
+++ b/drivers/bluetooth/btbcm.c
|
|
@@ -324,6 +324,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
|
|
{ 0x4103, "BCM4330B1" }, /* 002.001.003 */
|
|
{ 0x410e, "BCM43341B0" }, /* 002.001.014 */
|
|
{ 0x4406, "BCM4324B3" }, /* 002.004.006 */
|
|
+ { 0x6109, "BCM4335C0" }, /* 003.001.009 */
|
|
{ 0x610c, "BCM4354" }, /* 003.001.012 */
|
|
{ 0x2122, "BCM4343A0" }, /* 001.001.034 */
|
|
{ 0x2209, "BCM43430A1" }, /* 001.002.009 */
|
|
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
|
|
index 2fee65886d50..f0d593c3fa72 100644
|
|
--- a/drivers/bluetooth/hci_qca.c
|
|
+++ b/drivers/bluetooth/hci_qca.c
|
|
@@ -167,7 +167,7 @@ struct qca_serdev {
|
|
};
|
|
|
|
static int qca_power_setup(struct hci_uart *hu, bool on);
|
|
-static void qca_power_shutdown(struct hci_dev *hdev);
|
|
+static void qca_power_shutdown(struct hci_uart *hu);
|
|
|
|
static void __serial_clock_on(struct tty_struct *tty)
|
|
{
|
|
@@ -609,7 +609,7 @@ static int qca_close(struct hci_uart *hu)
|
|
if (hu->serdev) {
|
|
qcadev = serdev_device_get_drvdata(hu->serdev);
|
|
if (qcadev->btsoc_type == QCA_WCN3990)
|
|
- qca_power_shutdown(hu->hdev);
|
|
+ qca_power_shutdown(hu);
|
|
else
|
|
gpiod_set_value_cansleep(qcadev->bt_en, 0);
|
|
|
|
@@ -1232,12 +1232,15 @@ static const struct qca_vreg_data qca_soc_data = {
|
|
.num_vregs = 4,
|
|
};
|
|
|
|
-static void qca_power_shutdown(struct hci_dev *hdev)
|
|
+static void qca_power_shutdown(struct hci_uart *hu)
|
|
{
|
|
- struct hci_uart *hu = hci_get_drvdata(hdev);
|
|
+ struct serdev_device *serdev = hu->serdev;
|
|
+ unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
|
|
|
|
host_set_baudrate(hu, 2400);
|
|
- qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
|
|
+ hci_uart_set_flow_control(hu, true);
|
|
+ serdev_device_write_buf(serdev, &cmd, sizeof(cmd));
|
|
+ hci_uart_set_flow_control(hu, false);
|
|
qca_power_setup(hu, false);
|
|
}
|
|
|
|
@@ -1413,7 +1416,7 @@ static void qca_serdev_remove(struct serdev_device *serdev)
|
|
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
|
|
|
|
if (qcadev->btsoc_type == QCA_WCN3990)
|
|
- qca_power_shutdown(qcadev->serdev_hu.hdev);
|
|
+ qca_power_shutdown(&qcadev->serdev_hu);
|
|
else
|
|
clk_disable_unprepare(qcadev->susclk);
|
|
|
|
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
|
|
index 29e67a80fb20..9b786726e426 100644
|
|
--- a/drivers/char/ipmi/ipmi_ssif.c
|
|
+++ b/drivers/char/ipmi/ipmi_ssif.c
|
|
@@ -606,8 +606,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
|
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
|
|
ssif_info->waiting_alert = true;
|
|
ssif_info->rtc_us_timer = SSIF_MSG_USEC;
|
|
- mod_timer(&ssif_info->retry_timer,
|
|
- jiffies + SSIF_MSG_JIFFIES);
|
|
+ if (!ssif_info->stopping)
|
|
+ mod_timer(&ssif_info->retry_timer,
|
|
+ jiffies + SSIF_MSG_JIFFIES);
|
|
ipmi_ssif_unlock_cond(ssif_info, flags);
|
|
return;
|
|
}
|
|
@@ -939,8 +940,9 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|
ssif_info->waiting_alert = true;
|
|
ssif_info->retries_left = SSIF_RECV_RETRIES;
|
|
ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC;
|
|
- mod_timer(&ssif_info->retry_timer,
|
|
- jiffies + SSIF_MSG_PART_JIFFIES);
|
|
+ if (!ssif_info->stopping)
|
|
+ mod_timer(&ssif_info->retry_timer,
|
|
+ jiffies + SSIF_MSG_PART_JIFFIES);
|
|
ipmi_ssif_unlock_cond(ssif_info, flags);
|
|
}
|
|
}
|
|
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
|
|
index 1a803b0cf980..7d958ff426e0 100644
|
|
--- a/drivers/char/tpm/tpm-interface.c
|
|
+++ b/drivers/char/tpm/tpm-interface.c
|
|
@@ -663,7 +663,8 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
|
|
return len;
|
|
|
|
err = be32_to_cpu(header->return_code);
|
|
- if (err != 0 && desc)
|
|
+ if (err != 0 && err != TPM_ERR_DISABLED && err != TPM_ERR_DEACTIVATED
|
|
+ && desc)
|
|
dev_err(&chip->dev, "A TPM error (%d) occurred %s\n", err,
|
|
desc);
|
|
if (err)
|
|
@@ -1321,7 +1322,8 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
|
|
}
|
|
|
|
rlength = be32_to_cpu(tpm_cmd.header.out.length);
|
|
- if (rlength < offsetof(struct tpm_getrandom_out, rng_data) +
|
|
+ if (rlength < TPM_HEADER_SIZE +
|
|
+ offsetof(struct tpm_getrandom_out, rng_data) +
|
|
recd) {
|
|
total = -EFAULT;
|
|
break;
|
|
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
|
|
index c31b490bd41d..3acf4fd4e5a5 100644
|
|
--- a/drivers/char/tpm/tpm2-cmd.c
|
|
+++ b/drivers/char/tpm/tpm2-cmd.c
|
|
@@ -329,7 +329,9 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
|
|
&buf.data[TPM_HEADER_SIZE];
|
|
recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
|
|
if (tpm_buf_length(&buf) <
|
|
- offsetof(struct tpm2_get_random_out, buffer) + recd) {
|
|
+ TPM_HEADER_SIZE +
|
|
+ offsetof(struct tpm2_get_random_out, buffer) +
|
|
+ recd) {
|
|
err = -EFAULT;
|
|
goto out;
|
|
}
|
|
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
|
|
index 911475d36800..b150f87f38f5 100644
|
|
--- a/drivers/char/tpm/xen-tpmfront.c
|
|
+++ b/drivers/char/tpm/xen-tpmfront.c
|
|
@@ -264,7 +264,7 @@ static int setup_ring(struct xenbus_device *dev, struct tpm_private *priv)
|
|
return -ENOMEM;
|
|
}
|
|
|
|
- rv = xenbus_grant_ring(dev, &priv->shr, 1, &gref);
|
|
+ rv = xenbus_grant_ring(dev, priv->shr, 1, &gref);
|
|
if (rv < 0)
|
|
return rv;
|
|
|
|
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
|
|
index 0a9ebf00be46..e58bfcb1169e 100644
|
|
--- a/drivers/cpufreq/cpufreq-dt.c
|
|
+++ b/drivers/cpufreq/cpufreq-dt.c
|
|
@@ -32,6 +32,7 @@ struct private_data {
|
|
struct device *cpu_dev;
|
|
struct thermal_cooling_device *cdev;
|
|
const char *reg_name;
|
|
+ bool have_static_opps;
|
|
};
|
|
|
|
static struct freq_attr *cpufreq_dt_attr[] = {
|
|
@@ -204,6 +205,15 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
}
|
|
}
|
|
|
|
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
+ if (!priv) {
|
|
+ ret = -ENOMEM;
|
|
+ goto out_put_regulator;
|
|
+ }
|
|
+
|
|
+ priv->reg_name = name;
|
|
+ priv->opp_table = opp_table;
|
|
+
|
|
/*
|
|
* Initialize OPP tables for all policy->cpus. They will be shared by
|
|
* all CPUs which have marked their CPUs shared with OPP bindings.
|
|
@@ -214,7 +224,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
*
|
|
* OPPs might be populated at runtime, don't check for error here
|
|
*/
|
|
- dev_pm_opp_of_cpumask_add_table(policy->cpus);
|
|
+ if (!dev_pm_opp_of_cpumask_add_table(policy->cpus))
|
|
+ priv->have_static_opps = true;
|
|
|
|
/*
|
|
* But we need OPP table to function so if it is not there let's
|
|
@@ -240,19 +251,10 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
__func__, ret);
|
|
}
|
|
|
|
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
- if (!priv) {
|
|
- ret = -ENOMEM;
|
|
- goto out_free_opp;
|
|
- }
|
|
-
|
|
- priv->reg_name = name;
|
|
- priv->opp_table = opp_table;
|
|
-
|
|
ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
|
|
if (ret) {
|
|
dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
|
|
- goto out_free_priv;
|
|
+ goto out_free_opp;
|
|
}
|
|
|
|
priv->cpu_dev = cpu_dev;
|
|
@@ -282,10 +284,11 @@ static int cpufreq_init(struct cpufreq_policy *policy)
|
|
|
|
out_free_cpufreq_table:
|
|
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
|
|
-out_free_priv:
|
|
- kfree(priv);
|
|
out_free_opp:
|
|
- dev_pm_opp_of_cpumask_remove_table(policy->cpus);
|
|
+ if (priv->have_static_opps)
|
|
+ dev_pm_opp_of_cpumask_remove_table(policy->cpus);
|
|
+ kfree(priv);
|
|
+out_put_regulator:
|
|
if (name)
|
|
dev_pm_opp_put_regulators(opp_table);
|
|
out_put_clk:
|
|
@@ -300,7 +303,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
|
|
|
|
cpufreq_cooling_unregister(priv->cdev);
|
|
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
|
|
- dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
|
|
+ if (priv->have_static_opps)
|
|
+ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
|
|
if (priv->reg_name)
|
|
dev_pm_opp_put_regulators(priv->opp_table);
|
|
|
|
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
|
|
index f20f20a77d4d..4268f87e99fc 100644
|
|
--- a/drivers/cpufreq/cpufreq_conservative.c
|
|
+++ b/drivers/cpufreq/cpufreq_conservative.c
|
|
@@ -80,8 +80,10 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
|
|
* changed in the meantime, so fall back to current frequency in that
|
|
* case.
|
|
*/
|
|
- if (requested_freq > policy->max || requested_freq < policy->min)
|
|
+ if (requested_freq > policy->max || requested_freq < policy->min) {
|
|
requested_freq = policy->cur;
|
|
+ dbs_info->requested_freq = requested_freq;
|
|
+ }
|
|
|
|
freq_step = get_freq_step(cs_tuners, policy);
|
|
|
|
@@ -92,7 +94,7 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
|
|
if (policy_dbs->idle_periods < UINT_MAX) {
|
|
unsigned int freq_steps = policy_dbs->idle_periods * freq_step;
|
|
|
|
- if (requested_freq > freq_steps)
|
|
+ if (requested_freq > policy->min + freq_steps)
|
|
requested_freq -= freq_steps;
|
|
else
|
|
requested_freq = policy->min;
|
|
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
|
|
index 4fb91ba39c36..ce3f9ad7120f 100644
|
|
--- a/drivers/crypto/caam/regs.h
|
|
+++ b/drivers/crypto/caam/regs.h
|
|
@@ -70,22 +70,22 @@
|
|
extern bool caam_little_end;
|
|
extern bool caam_imx;
|
|
|
|
-#define caam_to_cpu(len) \
|
|
-static inline u##len caam##len ## _to_cpu(u##len val) \
|
|
-{ \
|
|
- if (caam_little_end) \
|
|
- return le##len ## _to_cpu(val); \
|
|
- else \
|
|
- return be##len ## _to_cpu(val); \
|
|
+#define caam_to_cpu(len) \
|
|
+static inline u##len caam##len ## _to_cpu(u##len val) \
|
|
+{ \
|
|
+ if (caam_little_end) \
|
|
+ return le##len ## _to_cpu((__force __le##len)val); \
|
|
+ else \
|
|
+ return be##len ## _to_cpu((__force __be##len)val); \
|
|
}
|
|
|
|
-#define cpu_to_caam(len) \
|
|
-static inline u##len cpu_to_caam##len(u##len val) \
|
|
-{ \
|
|
- if (caam_little_end) \
|
|
- return cpu_to_le##len(val); \
|
|
- else \
|
|
- return cpu_to_be##len(val); \
|
|
+#define cpu_to_caam(len) \
|
|
+static inline u##len cpu_to_caam##len(u##len val) \
|
|
+{ \
|
|
+ if (caam_little_end) \
|
|
+ return (__force u##len)cpu_to_le##len(val); \
|
|
+ else \
|
|
+ return (__force u##len)cpu_to_be##len(val); \
|
|
}
|
|
|
|
caam_to_cpu(16)
|
|
diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c
|
|
index 85820a2d69d4..987899610b46 100644
|
|
--- a/drivers/dma/dma-jz4780.c
|
|
+++ b/drivers/dma/dma-jz4780.c
|
|
@@ -761,6 +761,11 @@ static int jz4780_dma_probe(struct platform_device *pdev)
|
|
struct resource *res;
|
|
int i, ret;
|
|
|
|
+ if (!dev->of_node) {
|
|
+ dev_err(dev, "This driver must be probed from devicetree\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
jzdma = devm_kzalloc(dev, sizeof(*jzdma), GFP_KERNEL);
|
|
if (!jzdma)
|
|
return -ENOMEM;
|
|
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c
|
|
index 4fa4c06c9edb..21a5708985bc 100644
|
|
--- a/drivers/dma/ioat/init.c
|
|
+++ b/drivers/dma/ioat/init.c
|
|
@@ -1205,8 +1205,15 @@ static void ioat_shutdown(struct pci_dev *pdev)
|
|
|
|
spin_lock_bh(&ioat_chan->prep_lock);
|
|
set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
|
|
- del_timer_sync(&ioat_chan->timer);
|
|
spin_unlock_bh(&ioat_chan->prep_lock);
|
|
+ /*
|
|
+ * Synchronization rule for del_timer_sync():
|
|
+ * - The caller must not hold locks which would prevent
|
|
+ * completion of the timer's handler.
|
|
+ * So prep_lock cannot be held before calling it.
|
|
+ */
|
|
+ del_timer_sync(&ioat_chan->timer);
|
|
+
|
|
/* this should quiesce then reset */
|
|
ioat_reset_hw(ioat_chan);
|
|
}
|
|
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
|
|
index 4cf0d4d0cecf..25610286979f 100644
|
|
--- a/drivers/dma/ppc4xx/adma.c
|
|
+++ b/drivers/dma/ppc4xx/adma.c
|
|
@@ -4360,7 +4360,7 @@ static ssize_t enable_store(struct device_driver *dev, const char *buf,
|
|
}
|
|
static DRIVER_ATTR_RW(enable);
|
|
|
|
-static ssize_t poly_store(struct device_driver *dev, char *buf)
|
|
+static ssize_t poly_show(struct device_driver *dev, char *buf)
|
|
{
|
|
ssize_t size = 0;
|
|
u32 reg;
|
|
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
|
|
index 18aeabb1d5ee..e2addb2bca29 100644
|
|
--- a/drivers/edac/amd64_edac.c
|
|
+++ b/drivers/edac/amd64_edac.c
|
|
@@ -2200,6 +2200,15 @@ static struct amd64_family_type family_types[] = {
|
|
.dbam_to_cs = f17_base_addr_to_cs_size,
|
|
}
|
|
},
|
|
+ [F17_M10H_CPUS] = {
|
|
+ .ctl_name = "F17h_M10h",
|
|
+ .f0_id = PCI_DEVICE_ID_AMD_17H_M10H_DF_F0,
|
|
+ .f6_id = PCI_DEVICE_ID_AMD_17H_M10H_DF_F6,
|
|
+ .ops = {
|
|
+ .early_channel_count = f17_early_channel_count,
|
|
+ .dbam_to_cs = f17_base_addr_to_cs_size,
|
|
+ }
|
|
+ },
|
|
};
|
|
|
|
/*
|
|
@@ -3188,6 +3197,11 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
|
|
break;
|
|
|
|
case 0x17:
|
|
+ if (pvt->model >= 0x10 && pvt->model <= 0x2f) {
|
|
+ fam_type = &family_types[F17_M10H_CPUS];
|
|
+ pvt->ops = &family_types[F17_M10H_CPUS].ops;
|
|
+ break;
|
|
+ }
|
|
fam_type = &family_types[F17_CPUS];
|
|
pvt->ops = &family_types[F17_CPUS].ops;
|
|
break;
|
|
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
|
|
index 1d4b74e9a037..4242f8e39c18 100644
|
|
--- a/drivers/edac/amd64_edac.h
|
|
+++ b/drivers/edac/amd64_edac.h
|
|
@@ -115,6 +115,8 @@
|
|
#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F2 0x1582
|
|
#define PCI_DEVICE_ID_AMD_17H_DF_F0 0x1460
|
|
#define PCI_DEVICE_ID_AMD_17H_DF_F6 0x1466
|
|
+#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F0 0x15e8
|
|
+#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F6 0x15ee
|
|
|
|
/*
|
|
* Function 1 - Address Map
|
|
@@ -281,6 +283,7 @@ enum amd_families {
|
|
F16_CPUS,
|
|
F16_M30H_CPUS,
|
|
F17_CPUS,
|
|
+ F17_M10H_CPUS,
|
|
NUM_FAMILIES,
|
|
};
|
|
|
|
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
|
|
index 8e120bf60624..f1d19504a028 100644
|
|
--- a/drivers/edac/i7core_edac.c
|
|
+++ b/drivers/edac/i7core_edac.c
|
|
@@ -1711,6 +1711,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci,
|
|
u32 errnum = find_first_bit(&error, 32);
|
|
|
|
if (uncorrected_error) {
|
|
+ core_err_cnt = 1;
|
|
if (ripv)
|
|
tp_event = HW_EVENT_ERR_FATAL;
|
|
else
|
|
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
|
|
index 07726fb00321..72cea3cb8622 100644
|
|
--- a/drivers/edac/sb_edac.c
|
|
+++ b/drivers/edac/sb_edac.c
|
|
@@ -2888,6 +2888,7 @@ static void sbridge_mce_output_error(struct mem_ctl_info *mci,
|
|
recoverable = GET_BITFIELD(m->status, 56, 56);
|
|
|
|
if (uncorrected_error) {
|
|
+ core_err_cnt = 1;
|
|
if (ripv) {
|
|
type = "FATAL";
|
|
tp_event = HW_EVENT_ERR_FATAL;
|
|
diff --git a/drivers/edac/skx_edac.c b/drivers/edac/skx_edac.c
|
|
index fae095162c01..4ba92f1dd0f7 100644
|
|
--- a/drivers/edac/skx_edac.c
|
|
+++ b/drivers/edac/skx_edac.c
|
|
@@ -668,7 +668,7 @@ sad_found:
|
|
break;
|
|
case 2:
|
|
lchan = (addr >> shift) % 2;
|
|
- lchan = (lchan << 1) | ~lchan;
|
|
+ lchan = (lchan << 1) | !lchan;
|
|
break;
|
|
case 3:
|
|
lchan = ((addr >> shift) % 2) << 1;
|
|
@@ -959,6 +959,7 @@ static void skx_mce_output_error(struct mem_ctl_info *mci,
|
|
recoverable = GET_BITFIELD(m->status, 56, 56);
|
|
|
|
if (uncorrected_error) {
|
|
+ core_err_cnt = 1;
|
|
if (ripv) {
|
|
type = "FATAL";
|
|
tp_event = HW_EVENT_ERR_FATAL;
|
|
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
|
|
index 19db5709ae28..898bb9abc41f 100644
|
|
--- a/drivers/firmware/google/coreboot_table.c
|
|
+++ b/drivers/firmware/google/coreboot_table.c
|
|
@@ -110,7 +110,8 @@ int coreboot_table_init(struct device *dev, void __iomem *ptr)
|
|
|
|
if (strncmp(header.signature, "LBIO", sizeof(header.signature))) {
|
|
pr_warn("coreboot_table: coreboot table missing or corrupt!\n");
|
|
- return -ENODEV;
|
|
+ ret = -ENODEV;
|
|
+ goto out;
|
|
}
|
|
|
|
ptr_entry = (void *)ptr_header + header.header_bytes;
|
|
@@ -137,7 +138,8 @@ int coreboot_table_init(struct device *dev, void __iomem *ptr)
|
|
|
|
ptr_entry += entry.size;
|
|
}
|
|
-
|
|
+out:
|
|
+ iounmap(ptr);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(coreboot_table_init);
|
|
@@ -146,7 +148,6 @@ int coreboot_table_exit(void)
|
|
{
|
|
if (ptr_header) {
|
|
bus_unregister(&coreboot_bus_type);
|
|
- iounmap(ptr_header);
|
|
ptr_header = NULL;
|
|
}
|
|
|
|
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
|
|
index 16c7f9f49416..af936dcca659 100644
|
|
--- a/drivers/gpio/gpio-brcmstb.c
|
|
+++ b/drivers/gpio/gpio-brcmstb.c
|
|
@@ -664,6 +664,18 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
|
|
struct brcmstb_gpio_bank *bank;
|
|
struct gpio_chip *gc;
|
|
|
|
+ /*
|
|
+ * If bank_width is 0, then there is an empty bank in the
|
|
+ * register block. Special handling for this case.
|
|
+ */
|
|
+ if (bank_width == 0) {
|
|
+ dev_dbg(dev, "Width 0 found: Empty bank @ %d\n",
|
|
+ num_banks);
|
|
+ num_banks++;
|
|
+ gpio_base += MAX_GPIO_PER_BANK;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL);
|
|
if (!bank) {
|
|
err = -ENOMEM;
|
|
@@ -740,9 +752,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
|
|
goto fail;
|
|
}
|
|
|
|
- dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n",
|
|
- num_banks, priv->gpio_base, gpio_base - 1);
|
|
-
|
|
if (priv->parent_wake_irq && need_wakeup_event)
|
|
pm_wakeup_event(dev, 0);
|
|
|
|
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
|
|
index df30490da820..ea874fd033a5 100644
|
|
--- a/drivers/gpio/gpio-mxs.c
|
|
+++ b/drivers/gpio/gpio-mxs.c
|
|
@@ -18,8 +18,6 @@
|
|
#include <linux/platform_device.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/gpio/driver.h>
|
|
-/* FIXME: for gpio_get_value(), replace this by direct register read */
|
|
-#include <linux/gpio.h>
|
|
#include <linux/module.h>
|
|
|
|
#define MXS_SET 0x4
|
|
@@ -86,7 +84,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
|
|
port->both_edges &= ~pin_mask;
|
|
switch (type) {
|
|
case IRQ_TYPE_EDGE_BOTH:
|
|
- val = gpio_get_value(port->gc.base + d->hwirq);
|
|
+ val = port->gc.get(&port->gc, d->hwirq);
|
|
if (val)
|
|
edge = GPIO_INT_FALL_EDGE;
|
|
else
|
|
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
|
|
index 2d45d1dd9554..643f5edd68fe 100644
|
|
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
|
|
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
|
|
@@ -1446,8 +1446,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
|
}
|
|
|
|
/* The CEC module handles HDMI hotplug detection */
|
|
- cec_np = of_find_compatible_node(np->parent, NULL,
|
|
- "mediatek,mt8173-cec");
|
|
+ cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
|
|
if (!cec_np) {
|
|
dev_err(dev, "Failed to find CEC node\n");
|
|
return -EINVAL;
|
|
@@ -1457,8 +1456,10 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
|
if (!cec_pdev) {
|
|
dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
|
|
cec_np);
|
|
+ of_node_put(cec_np);
|
|
return -EPROBE_DEFER;
|
|
}
|
|
+ of_node_put(cec_np);
|
|
hdmi->cec_dev = &cec_pdev->dev;
|
|
|
|
/*
|
|
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
|
|
index cf2a18571d48..a132c37d7334 100644
|
|
--- a/drivers/gpu/vga/vga_switcheroo.c
|
|
+++ b/drivers/gpu/vga/vga_switcheroo.c
|
|
@@ -380,6 +380,9 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
|
|
mutex_unlock(&vgasr_mutex);
|
|
return -EINVAL;
|
|
}
|
|
+ /* notify if GPU has been already bound */
|
|
+ if (ops->gpu_bound)
|
|
+ ops->gpu_bound(pdev, id);
|
|
}
|
|
mutex_unlock(&vgasr_mutex);
|
|
|
|
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
|
|
index 23872d08308c..a746017fac17 100644
|
|
--- a/drivers/hid/usbhid/hiddev.c
|
|
+++ b/drivers/hid/usbhid/hiddev.c
|
|
@@ -512,14 +512,24 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
|
|
if (cmd == HIDIOCGCOLLECTIONINDEX) {
|
|
if (uref->usage_index >= field->maxusage)
|
|
goto inval;
|
|
+ uref->usage_index =
|
|
+ array_index_nospec(uref->usage_index,
|
|
+ field->maxusage);
|
|
} else if (uref->usage_index >= field->report_count)
|
|
goto inval;
|
|
}
|
|
|
|
- if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
|
|
- (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
|
|
- uref->usage_index + uref_multi->num_values > field->report_count))
|
|
- goto inval;
|
|
+ if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
|
|
+ if (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
|
|
+ uref->usage_index + uref_multi->num_values >
|
|
+ field->report_count)
|
|
+ goto inval;
|
|
+
|
|
+ uref->usage_index =
|
|
+ array_index_nospec(uref->usage_index,
|
|
+ field->report_count -
|
|
+ uref_multi->num_values);
|
|
+ }
|
|
|
|
switch (cmd) {
|
|
case HIDIOCGUSAGE:
|
|
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
|
|
index e0a06be5ef5c..5dd3a8245f0f 100644
|
|
--- a/drivers/hid/wacom_wac.c
|
|
+++ b/drivers/hid/wacom_wac.c
|
|
@@ -3335,6 +3335,7 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
|
|
|
|
void wacom_setup_device_quirks(struct wacom *wacom)
|
|
{
|
|
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
|
struct wacom_features *features = &wacom->wacom_wac.features;
|
|
|
|
/* The pen and pad share the same interface on most devices */
|
|
@@ -3464,6 +3465,24 @@ void wacom_setup_device_quirks(struct wacom *wacom)
|
|
|
|
if (features->type == REMOTE)
|
|
features->device_type |= WACOM_DEVICETYPE_WL_MONITOR;
|
|
+
|
|
+ /* HID descriptor for DTK-2451 / DTH-2452 claims to report lots
|
|
+ * of things it shouldn't. Lets fix up the damage...
|
|
+ */
|
|
+ if (wacom->hdev->product == 0x382 || wacom->hdev->product == 0x37d) {
|
|
+ features->quirks &= ~WACOM_QUIRK_TOOLSERIAL;
|
|
+ __clear_bit(BTN_TOOL_BRUSH, wacom_wac->pen_input->keybit);
|
|
+ __clear_bit(BTN_TOOL_PENCIL, wacom_wac->pen_input->keybit);
|
|
+ __clear_bit(BTN_TOOL_AIRBRUSH, wacom_wac->pen_input->keybit);
|
|
+ __clear_bit(ABS_Z, wacom_wac->pen_input->absbit);
|
|
+ __clear_bit(ABS_DISTANCE, wacom_wac->pen_input->absbit);
|
|
+ __clear_bit(ABS_TILT_X, wacom_wac->pen_input->absbit);
|
|
+ __clear_bit(ABS_TILT_Y, wacom_wac->pen_input->absbit);
|
|
+ __clear_bit(ABS_WHEEL, wacom_wac->pen_input->absbit);
|
|
+ __clear_bit(ABS_MISC, wacom_wac->pen_input->absbit);
|
|
+ __clear_bit(MSC_SERIAL, wacom_wac->pen_input->mscbit);
|
|
+ __clear_bit(EV_MSC, wacom_wac->pen_input->evbit);
|
|
+ }
|
|
}
|
|
|
|
int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
|
|
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
|
index 0f0e091c117c..c4a1ebcfffb6 100644
|
|
--- a/drivers/hv/channel_mgmt.c
|
|
+++ b/drivers/hv/channel_mgmt.c
|
|
@@ -606,16 +606,18 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
|
bool perf_chn = vmbus_devs[dev_type].perf_device;
|
|
struct vmbus_channel *primary = channel->primary_channel;
|
|
int next_node;
|
|
- struct cpumask available_mask;
|
|
+ cpumask_var_t available_mask;
|
|
struct cpumask *alloced_mask;
|
|
|
|
if ((vmbus_proto_version == VERSION_WS2008) ||
|
|
- (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
|
|
+ (vmbus_proto_version == VERSION_WIN7) || (!perf_chn) ||
|
|
+ !alloc_cpumask_var(&available_mask, GFP_KERNEL)) {
|
|
/*
|
|
* Prior to win8, all channel interrupts are
|
|
* delivered on cpu 0.
|
|
* Also if the channel is not a performance critical
|
|
* channel, bind it to cpu 0.
|
|
+ * In case alloc_cpumask_var() fails, bind it to cpu 0.
|
|
*/
|
|
channel->numa_node = 0;
|
|
channel->target_cpu = 0;
|
|
@@ -653,7 +655,7 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
|
cpumask_clear(alloced_mask);
|
|
}
|
|
|
|
- cpumask_xor(&available_mask, alloced_mask,
|
|
+ cpumask_xor(available_mask, alloced_mask,
|
|
cpumask_of_node(primary->numa_node));
|
|
|
|
cur_cpu = -1;
|
|
@@ -671,10 +673,10 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
|
}
|
|
|
|
while (true) {
|
|
- cur_cpu = cpumask_next(cur_cpu, &available_mask);
|
|
+ cur_cpu = cpumask_next(cur_cpu, available_mask);
|
|
if (cur_cpu >= nr_cpu_ids) {
|
|
cur_cpu = -1;
|
|
- cpumask_copy(&available_mask,
|
|
+ cpumask_copy(available_mask,
|
|
cpumask_of_node(primary->numa_node));
|
|
continue;
|
|
}
|
|
@@ -704,6 +706,8 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
|
|
|
channel->target_cpu = cur_cpu;
|
|
channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
|
|
+
|
|
+ free_cpumask_var(available_mask);
|
|
}
|
|
|
|
static void vmbus_wait_for_unload(void)
|
|
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
|
|
index 7718e58dbda5..7688dab32f6e 100644
|
|
--- a/drivers/hwmon/pmbus/pmbus.c
|
|
+++ b/drivers/hwmon/pmbus/pmbus.c
|
|
@@ -118,6 +118,8 @@ static int pmbus_identify(struct i2c_client *client,
|
|
} else {
|
|
info->pages = 1;
|
|
}
|
|
+
|
|
+ pmbus_clear_faults(client);
|
|
}
|
|
|
|
if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
|
|
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
|
|
index 82c3754e21e3..2e2b5851139c 100644
|
|
--- a/drivers/hwmon/pmbus/pmbus_core.c
|
|
+++ b/drivers/hwmon/pmbus/pmbus_core.c
|
|
@@ -2015,7 +2015,10 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
|
|
if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK))
|
|
client->flags |= I2C_CLIENT_PEC;
|
|
|
|
- pmbus_clear_faults(client);
|
|
+ if (data->info->pages)
|
|
+ pmbus_clear_faults(client);
|
|
+ else
|
|
+ pmbus_clear_fault_page(client, -1);
|
|
|
|
if (info->identify) {
|
|
ret = (*info->identify)(client, info);
|
|
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
|
|
index 7838af58f92d..9d611dd268e1 100644
|
|
--- a/drivers/hwmon/pwm-fan.c
|
|
+++ b/drivers/hwmon/pwm-fan.c
|
|
@@ -290,9 +290,19 @@ static int pwm_fan_remove(struct platform_device *pdev)
|
|
static int pwm_fan_suspend(struct device *dev)
|
|
{
|
|
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
|
|
+ struct pwm_args args;
|
|
+ int ret;
|
|
+
|
|
+ pwm_get_args(ctx->pwm, &args);
|
|
+
|
|
+ if (ctx->pwm_value) {
|
|
+ ret = pwm_config(ctx->pwm, 0, args.period);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
- if (ctx->pwm_value)
|
|
pwm_disable(ctx->pwm);
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
|
|
index 306119eaf16a..0dad8626bcfb 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-etb10.c
|
|
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
|
|
@@ -147,6 +147,10 @@ static int etb_enable(struct coresight_device *csdev, u32 mode)
|
|
if (val == CS_MODE_PERF)
|
|
return -EBUSY;
|
|
|
|
+ /* Don't let perf disturb sysFS sessions */
|
|
+ if (val == CS_MODE_SYSFS && mode == CS_MODE_PERF)
|
|
+ return -EBUSY;
|
|
+
|
|
/* Nothing to do, the tracer is already enabled. */
|
|
if (val == CS_MODE_SYSFS)
|
|
goto out;
|
|
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
|
|
index 44b516863c9d..75d2f73582a3 100644
|
|
--- a/drivers/iio/adc/at91_adc.c
|
|
+++ b/drivers/iio/adc/at91_adc.c
|
|
@@ -248,12 +248,14 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
|
|
struct iio_poll_func *pf = p;
|
|
struct iio_dev *idev = pf->indio_dev;
|
|
struct at91_adc_state *st = iio_priv(idev);
|
|
+ struct iio_chan_spec const *chan;
|
|
int i, j = 0;
|
|
|
|
for (i = 0; i < idev->masklength; i++) {
|
|
if (!test_bit(i, idev->active_scan_mask))
|
|
continue;
|
|
- st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, i));
|
|
+ chan = idev->channels + i;
|
|
+ st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, chan->channel));
|
|
j++;
|
|
}
|
|
|
|
@@ -279,6 +281,8 @@ static void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
|
|
iio_trigger_poll(idev->trig);
|
|
} else {
|
|
st->last_value = at91_adc_readl(st, AT91_ADC_CHAN(st, st->chnb));
|
|
+ /* Needed to ACK the DRDY interruption */
|
|
+ at91_adc_readl(st, AT91_ADC_LCDR);
|
|
st->done = true;
|
|
wake_up_interruptible(&st->wq_data_avail);
|
|
}
|
|
diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
|
|
index ea264fa9e567..929c617db364 100644
|
|
--- a/drivers/iio/adc/fsl-imx25-gcq.c
|
|
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
|
|
@@ -209,12 +209,14 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
|
|
ret = of_property_read_u32(child, "reg", ®);
|
|
if (ret) {
|
|
dev_err(dev, "Failed to get reg property\n");
|
|
+ of_node_put(child);
|
|
return ret;
|
|
}
|
|
|
|
if (reg >= MX25_NUM_CFGS) {
|
|
dev_err(dev,
|
|
"reg value is greater than the number of available configuration registers\n");
|
|
+ of_node_put(child);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -228,6 +230,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
|
|
if (IS_ERR(priv->vref[refp])) {
|
|
dev_err(dev, "Error, trying to use external voltage reference without a vref-%s regulator.",
|
|
mx25_gcq_refp_names[refp]);
|
|
+ of_node_put(child);
|
|
return PTR_ERR(priv->vref[refp]);
|
|
}
|
|
priv->channel_vref_mv[reg] =
|
|
@@ -240,6 +243,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
|
|
break;
|
|
default:
|
|
dev_err(dev, "Invalid positive reference %d\n", refp);
|
|
+ of_node_put(child);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -254,10 +258,12 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
|
|
|
|
if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
|
|
dev_err(dev, "Invalid fsl,adc-refp property value\n");
|
|
+ of_node_put(child);
|
|
return -EINVAL;
|
|
}
|
|
if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
|
|
dev_err(dev, "Invalid fsl,adc-refn property value\n");
|
|
+ of_node_put(child);
|
|
return -EINVAL;
|
|
}
|
|
|
|
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
|
|
index bf4fc40ec84d..2f98cb2a3b96 100644
|
|
--- a/drivers/iio/dac/ad5064.c
|
|
+++ b/drivers/iio/dac/ad5064.c
|
|
@@ -808,6 +808,40 @@ static int ad5064_set_config(struct ad5064_state *st, unsigned int val)
|
|
return ad5064_write(st, cmd, 0, val, 0);
|
|
}
|
|
|
|
+static int ad5064_request_vref(struct ad5064_state *st, struct device *dev)
|
|
+{
|
|
+ unsigned int i;
|
|
+ int ret;
|
|
+
|
|
+ for (i = 0; i < ad5064_num_vref(st); ++i)
|
|
+ st->vref_reg[i].supply = ad5064_vref_name(st, i);
|
|
+
|
|
+ if (!st->chip_info->internal_vref)
|
|
+ return devm_regulator_bulk_get(dev, ad5064_num_vref(st),
|
|
+ st->vref_reg);
|
|
+
|
|
+ /*
|
|
+ * This assumes that when the regulator has an internal VREF
|
|
+ * there is only one external VREF connection, which is
|
|
+ * currently the case for all supported devices.
|
|
+ */
|
|
+ st->vref_reg[0].consumer = devm_regulator_get_optional(dev, "vref");
|
|
+ if (!IS_ERR(st->vref_reg[0].consumer))
|
|
+ return 0;
|
|
+
|
|
+ ret = PTR_ERR(st->vref_reg[0].consumer);
|
|
+ if (ret != -ENODEV)
|
|
+ return ret;
|
|
+
|
|
+ /* If no external regulator was supplied use the internal VREF */
|
|
+ st->use_internal_vref = true;
|
|
+ ret = ad5064_set_config(st, AD5064_CONFIG_INT_VREF_ENABLE);
|
|
+ if (ret)
|
|
+ dev_err(dev, "Failed to enable internal vref: %d\n", ret);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int ad5064_probe(struct device *dev, enum ad5064_type type,
|
|
const char *name, ad5064_write_func write)
|
|
{
|
|
@@ -828,22 +862,11 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
|
|
st->dev = dev;
|
|
st->write = write;
|
|
|
|
- for (i = 0; i < ad5064_num_vref(st); ++i)
|
|
- st->vref_reg[i].supply = ad5064_vref_name(st, i);
|
|
+ ret = ad5064_request_vref(st, dev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
- ret = devm_regulator_bulk_get(dev, ad5064_num_vref(st),
|
|
- st->vref_reg);
|
|
- if (ret) {
|
|
- if (!st->chip_info->internal_vref)
|
|
- return ret;
|
|
- st->use_internal_vref = true;
|
|
- ret = ad5064_set_config(st, AD5064_CONFIG_INT_VREF_ENABLE);
|
|
- if (ret) {
|
|
- dev_err(dev, "Failed to enable internal vref: %d\n",
|
|
- ret);
|
|
- return ret;
|
|
- }
|
|
- } else {
|
|
+ if (!st->use_internal_vref) {
|
|
ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
|
|
if (ret)
|
|
return ret;
|
|
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
|
|
index 6e39c27dca8e..4c533275d1f2 100644
|
|
--- a/drivers/infiniband/core/cm.c
|
|
+++ b/drivers/infiniband/core/cm.c
|
|
@@ -3292,8 +3292,11 @@ static int cm_lap_handler(struct cm_work *work)
|
|
if (ret)
|
|
goto unlock;
|
|
|
|
- cm_init_av_by_path(param->alternate_path, NULL, &cm_id_priv->alt_av,
|
|
- cm_id_priv);
|
|
+ ret = cm_init_av_by_path(param->alternate_path, NULL,
|
|
+ &cm_id_priv->alt_av, cm_id_priv);
|
|
+ if (ret)
|
|
+ goto unlock;
|
|
+
|
|
cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
|
|
cm_id_priv->tid = lap_msg->hdr.tid;
|
|
ret = atomic_inc_and_test(&cm_id_priv->work_count);
|
|
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
|
|
index 7fd14ead7b37..ace40bb98624 100644
|
|
--- a/drivers/infiniband/core/sysfs.c
|
|
+++ b/drivers/infiniband/core/sysfs.c
|
|
@@ -512,7 +512,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
|
|
ret = get_perf_mad(p->ibdev, p->port_num, tab_attr->attr_id, &data,
|
|
40 + offset / 8, sizeof(data));
|
|
if (ret < 0)
|
|
- return sprintf(buf, "N/A (no PMA)\n");
|
|
+ return ret;
|
|
|
|
switch (width) {
|
|
case 4:
|
|
@@ -1057,10 +1057,12 @@ static int add_port(struct ib_device *device, int port_num,
|
|
goto err_put;
|
|
}
|
|
|
|
- p->pma_table = get_counter_table(device, port_num);
|
|
- ret = sysfs_create_group(&p->kobj, p->pma_table);
|
|
- if (ret)
|
|
- goto err_put_gid_attrs;
|
|
+ if (device->process_mad) {
|
|
+ p->pma_table = get_counter_table(device, port_num);
|
|
+ ret = sysfs_create_group(&p->kobj, p->pma_table);
|
|
+ if (ret)
|
|
+ goto err_put_gid_attrs;
|
|
+ }
|
|
|
|
p->gid_group.name = "gids";
|
|
p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
|
|
@@ -1173,7 +1175,8 @@ err_free_gid:
|
|
p->gid_group.attrs = NULL;
|
|
|
|
err_remove_pma:
|
|
- sysfs_remove_group(&p->kobj, p->pma_table);
|
|
+ if (p->pma_table)
|
|
+ sysfs_remove_group(&p->kobj, p->pma_table);
|
|
|
|
err_put_gid_attrs:
|
|
kobject_put(&p->gid_attr_group->kobj);
|
|
@@ -1285,7 +1288,9 @@ static void free_port_list_attributes(struct ib_device *device)
|
|
kfree(port->hw_stats);
|
|
free_hsag(&port->kobj, port->hw_stats_ag);
|
|
}
|
|
- sysfs_remove_group(p, port->pma_table);
|
|
+
|
|
+ if (port->pma_table)
|
|
+ sysfs_remove_group(p, port->pma_table);
|
|
sysfs_remove_group(p, &port->pkey_group);
|
|
sysfs_remove_group(p, &port->gid_group);
|
|
sysfs_remove_group(&port->gid_attr_group->kobj,
|
|
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
|
index 6ad0d46ab879..249efa0a6aba 100644
|
|
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
|
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
|
@@ -360,7 +360,8 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
|
|
}
|
|
|
|
/* Make sure the HW is stopped! */
|
|
- bnxt_qplib_nq_stop_irq(nq, true);
|
|
+ if (nq->requested)
|
|
+ bnxt_qplib_nq_stop_irq(nq, true);
|
|
|
|
if (nq->bar_reg_iomem)
|
|
iounmap(nq->bar_reg_iomem);
|
|
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
|
|
index 2852d350ada1..6637df77d236 100644
|
|
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
|
|
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
|
|
@@ -309,8 +309,17 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
|
|
rcfw->aeq_handler(rcfw, qp_event, qp);
|
|
break;
|
|
default:
|
|
- /* Command Response */
|
|
- spin_lock_irqsave(&cmdq->lock, flags);
|
|
+ /*
|
|
+ * Command Response
|
|
+ * cmdq->lock needs to be acquired to synchronie
|
|
+ * the command send and completion reaping. This function
|
|
+ * is always called with creq->lock held. Using
|
|
+ * the nested variant of spin_lock.
|
|
+ *
|
|
+ */
|
|
+
|
|
+ spin_lock_irqsave_nested(&cmdq->lock, flags,
|
|
+ SINGLE_DEPTH_NESTING);
|
|
cookie = le16_to_cpu(qp_event->cookie);
|
|
mcookie = qp_event->cookie;
|
|
blocked = cookie & RCFW_CMD_IS_BLOCKING;
|
|
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
|
|
index e22314837645..7df4a4fe4af4 100644
|
|
--- a/drivers/infiniband/hw/mlx5/mr.c
|
|
+++ b/drivers/infiniband/hw/mlx5/mr.c
|
|
@@ -691,7 +691,6 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
|
|
init_completion(&ent->compl);
|
|
INIT_WORK(&ent->work, cache_work_func);
|
|
INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
|
|
- queue_work(cache->wq, &ent->work);
|
|
|
|
if (i > MR_CACHE_LAST_STD_ENTRY) {
|
|
mlx5_odp_init_mr_cache_entry(ent);
|
|
@@ -711,6 +710,7 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
|
|
ent->limit = dev->mdev->profile->mr_cache[i].limit;
|
|
else
|
|
ent->limit = 0;
|
|
+ queue_work(cache->wq, &ent->work);
|
|
}
|
|
|
|
err = mlx5_mr_cache_debugfs_init(dev);
|
|
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
|
|
index 6cba2a02d11b..d53d954ac8af 100644
|
|
--- a/drivers/infiniband/hw/mlx5/qp.c
|
|
+++ b/drivers/infiniband/hw/mlx5/qp.c
|
|
@@ -3243,7 +3243,9 @@ static bool modify_dci_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state new
|
|
int req = IB_QP_STATE;
|
|
int opt = 0;
|
|
|
|
- if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
|
+ if (new_state == IB_QPS_RESET) {
|
|
+ return is_valid_mask(attr_mask, req, opt);
|
|
+ } else if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
|
req |= IB_QP_PKEY_INDEX | IB_QP_PORT;
|
|
return is_valid_mask(attr_mask, req, opt);
|
|
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
|
|
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
|
|
index aa5833318372..fc6c880756da 100644
|
|
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
|
|
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
|
|
@@ -682,6 +682,7 @@ static enum resp_states read_reply(struct rxe_qp *qp,
|
|
rxe_advance_resp_resource(qp);
|
|
|
|
res->type = RXE_READ_MASK;
|
|
+ res->replay = 0;
|
|
|
|
res->read.va = qp->resp.va;
|
|
res->read.va_org = qp->resp.va;
|
|
@@ -752,7 +753,8 @@ static enum resp_states read_reply(struct rxe_qp *qp,
|
|
state = RESPST_DONE;
|
|
} else {
|
|
qp->resp.res = NULL;
|
|
- qp->resp.opcode = -1;
|
|
+ if (!res->replay)
|
|
+ qp->resp.opcode = -1;
|
|
if (psn_compare(res->cur_psn, qp->resp.psn) >= 0)
|
|
qp->resp.psn = res->cur_psn;
|
|
state = RESPST_CLEANUP;
|
|
@@ -814,6 +816,7 @@ static enum resp_states execute(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
|
|
|
|
/* next expected psn, read handles this separately */
|
|
qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK;
|
|
+ qp->resp.ack_psn = qp->resp.psn;
|
|
|
|
qp->resp.opcode = pkt->opcode;
|
|
qp->resp.status = IB_WC_SUCCESS;
|
|
@@ -1065,7 +1068,7 @@ static enum resp_states duplicate_request(struct rxe_qp *qp,
|
|
struct rxe_pkt_info *pkt)
|
|
{
|
|
enum resp_states rc;
|
|
- u32 prev_psn = (qp->resp.psn - 1) & BTH_PSN_MASK;
|
|
+ u32 prev_psn = (qp->resp.ack_psn - 1) & BTH_PSN_MASK;
|
|
|
|
if (pkt->mask & RXE_SEND_MASK ||
|
|
pkt->mask & RXE_WRITE_MASK) {
|
|
@@ -1108,6 +1111,7 @@ static enum resp_states duplicate_request(struct rxe_qp *qp,
|
|
res->state = (pkt->psn == res->first_psn) ?
|
|
rdatm_res_state_new :
|
|
rdatm_res_state_replay;
|
|
+ res->replay = 1;
|
|
|
|
/* Reset the resource, except length. */
|
|
res->read.va_org = iova;
|
|
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
|
|
index af1470d29391..332a16dad2a7 100644
|
|
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
|
|
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
|
|
@@ -171,6 +171,7 @@ enum rdatm_res_state {
|
|
|
|
struct resp_res {
|
|
int type;
|
|
+ int replay;
|
|
u32 first_psn;
|
|
u32 last_psn;
|
|
u32 cur_psn;
|
|
@@ -195,6 +196,7 @@ struct rxe_resp_info {
|
|
enum rxe_qp_state state;
|
|
u32 msn;
|
|
u32 psn;
|
|
+ u32 ack_psn;
|
|
int opcode;
|
|
int drop_msg;
|
|
int goto_error;
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
|
|
index 3d5424f335cb..0428e01e8f69 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
|
|
@@ -1438,11 +1438,15 @@ static void ipoib_cm_skb_reap(struct work_struct *work)
|
|
spin_unlock_irqrestore(&priv->lock, flags);
|
|
netif_tx_unlock_bh(dev);
|
|
|
|
- if (skb->protocol == htons(ETH_P_IP))
|
|
+ if (skb->protocol == htons(ETH_P_IP)) {
|
|
+ memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
|
|
+ }
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
- else if (skb->protocol == htons(ETH_P_IPV6))
|
|
+ else if (skb->protocol == htons(ETH_P_IPV6)) {
|
|
+ memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
|
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
|
|
+ }
|
|
#endif
|
|
dev_kfree_skb_any(skb);
|
|
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
index e3d28f9ad9c0..30f840f874b3 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
@@ -1880,6 +1880,8 @@ static int ipoib_parent_init(struct net_device *ndev)
|
|
sizeof(union ib_gid));
|
|
|
|
SET_NETDEV_DEV(priv->dev, priv->ca->dev.parent);
|
|
+ priv->dev->dev_port = priv->port - 1;
|
|
+ /* Let's set this one too for backwards compatibility. */
|
|
priv->dev->dev_id = priv->port - 1;
|
|
|
|
return 0;
|
|
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
|
|
index fd1b80ef9490..e7cbf4fcf61d 100644
|
|
--- a/drivers/iommu/arm-smmu.c
|
|
+++ b/drivers/iommu/arm-smmu.c
|
|
@@ -469,6 +469,9 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
|
|
bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
|
|
void __iomem *reg = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
|
|
|
|
+ if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
|
|
+ wmb();
|
|
+
|
|
if (stage1) {
|
|
reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
|
|
|
|
@@ -510,6 +513,9 @@ static void arm_smmu_tlb_inv_vmid_nosync(unsigned long iova, size_t size,
|
|
struct arm_smmu_domain *smmu_domain = cookie;
|
|
void __iomem *base = ARM_SMMU_GR0(smmu_domain->smmu);
|
|
|
|
+ if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
|
|
+ wmb();
|
|
+
|
|
writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID);
|
|
}
|
|
|
|
diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
|
|
index b1b47a40a278..faa7d61b9d6c 100644
|
|
--- a/drivers/irqchip/qcom-pdc.c
|
|
+++ b/drivers/irqchip/qcom-pdc.c
|
|
@@ -124,6 +124,7 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
|
|
break;
|
|
case IRQ_TYPE_EDGE_BOTH:
|
|
pdc_type = PDC_EDGE_DUAL;
|
|
+ type = IRQ_TYPE_EDGE_RISING;
|
|
break;
|
|
case IRQ_TYPE_LEVEL_HIGH:
|
|
pdc_type = PDC_LEVEL_HIGH;
|
|
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
|
|
index 00984b486fea..2940cdc87af1 100644
|
|
--- a/drivers/lightnvm/pblk-core.c
|
|
+++ b/drivers/lightnvm/pblk-core.c
|
|
@@ -1539,13 +1539,14 @@ struct pblk_line *pblk_line_replace_data(struct pblk *pblk)
|
|
struct pblk_line *cur, *new = NULL;
|
|
unsigned int left_seblks;
|
|
|
|
- cur = l_mg->data_line;
|
|
new = l_mg->data_next;
|
|
if (!new)
|
|
goto out;
|
|
- l_mg->data_line = new;
|
|
|
|
spin_lock(&l_mg->free_lock);
|
|
+ cur = l_mg->data_line;
|
|
+ l_mg->data_line = new;
|
|
+
|
|
pblk_line_setup_metadata(new, l_mg, &pblk->lm);
|
|
spin_unlock(&l_mg->free_lock);
|
|
|
|
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
|
|
index e232e47e1353..df75d9caec45 100644
|
|
--- a/drivers/lightnvm/pblk-recovery.c
|
|
+++ b/drivers/lightnvm/pblk-recovery.c
|
|
@@ -956,12 +956,14 @@ next:
|
|
}
|
|
}
|
|
|
|
- spin_lock(&l_mg->free_lock);
|
|
if (!open_lines) {
|
|
+ spin_lock(&l_mg->free_lock);
|
|
WARN_ON_ONCE(!test_and_clear_bit(meta_line,
|
|
&l_mg->meta_bitmap));
|
|
+ spin_unlock(&l_mg->free_lock);
|
|
pblk_line_replace_data(pblk);
|
|
} else {
|
|
+ spin_lock(&l_mg->free_lock);
|
|
/* Allocate next line for preparation */
|
|
l_mg->data_next = pblk_line_get(pblk);
|
|
if (l_mg->data_next) {
|
|
@@ -969,8 +971,8 @@ next:
|
|
l_mg->data_next->type = PBLK_LINETYPE_DATA;
|
|
is_next = 1;
|
|
}
|
|
+ spin_unlock(&l_mg->free_lock);
|
|
}
|
|
- spin_unlock(&l_mg->free_lock);
|
|
|
|
if (is_next)
|
|
pblk_line_erase(pblk, l_mg->data_next);
|
|
diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
|
|
index 9fc3dfa168b4..8d2ed510c04b 100644
|
|
--- a/drivers/lightnvm/pblk-sysfs.c
|
|
+++ b/drivers/lightnvm/pblk-sysfs.c
|
|
@@ -262,8 +262,14 @@ static ssize_t pblk_sysfs_lines(struct pblk *pblk, char *page)
|
|
sec_in_line = l_mg->data_line->sec_in_line;
|
|
meta_weight = bitmap_weight(&l_mg->meta_bitmap,
|
|
PBLK_DATA_LINES);
|
|
- map_weight = bitmap_weight(l_mg->data_line->map_bitmap,
|
|
+
|
|
+ spin_lock(&l_mg->data_line->lock);
|
|
+ if (l_mg->data_line->map_bitmap)
|
|
+ map_weight = bitmap_weight(l_mg->data_line->map_bitmap,
|
|
lm->sec_per_line);
|
|
+ else
|
|
+ map_weight = 0;
|
|
+ spin_unlock(&l_mg->data_line->lock);
|
|
}
|
|
spin_unlock(&l_mg->free_lock);
|
|
|
|
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
|
|
index ee774a86cf1e..879227d584e7 100644
|
|
--- a/drivers/lightnvm/pblk-write.c
|
|
+++ b/drivers/lightnvm/pblk-write.c
|
|
@@ -417,12 +417,11 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
|
|
rqd->ppa_list[i] = addr_to_gen_ppa(pblk, paddr, id);
|
|
}
|
|
|
|
+ spin_lock(&l_mg->close_lock);
|
|
emeta->mem += rq_len;
|
|
- if (emeta->mem >= lm->emeta_len[0]) {
|
|
- spin_lock(&l_mg->close_lock);
|
|
+ if (emeta->mem >= lm->emeta_len[0])
|
|
list_del(&meta_line->list);
|
|
- spin_unlock(&l_mg->close_lock);
|
|
- }
|
|
+ spin_unlock(&l_mg->close_lock);
|
|
|
|
pblk_down_page(pblk, rqd->ppa_list, rqd->nr_ppas);
|
|
|
|
@@ -491,14 +490,15 @@ static struct pblk_line *pblk_should_submit_meta_io(struct pblk *pblk,
|
|
struct pblk_line *meta_line;
|
|
|
|
spin_lock(&l_mg->close_lock);
|
|
-retry:
|
|
if (list_empty(&l_mg->emeta_list)) {
|
|
spin_unlock(&l_mg->close_lock);
|
|
return NULL;
|
|
}
|
|
meta_line = list_first_entry(&l_mg->emeta_list, struct pblk_line, list);
|
|
- if (meta_line->emeta->mem >= lm->emeta_len[0])
|
|
- goto retry;
|
|
+ if (meta_line->emeta->mem >= lm->emeta_len[0]) {
|
|
+ spin_unlock(&l_mg->close_lock);
|
|
+ return NULL;
|
|
+ }
|
|
spin_unlock(&l_mg->close_lock);
|
|
|
|
if (!pblk_valid_meta_ppa(pblk, meta_line, data_rqd))
|
|
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
|
|
index 311e91b1a14f..256f18b67e8a 100644
|
|
--- a/drivers/mailbox/pcc.c
|
|
+++ b/drivers/mailbox/pcc.c
|
|
@@ -461,8 +461,11 @@ static int __init acpi_pcc_probe(void)
|
|
count = acpi_table_parse_entries_array(ACPI_SIG_PCCT,
|
|
sizeof(struct acpi_table_pcct), proc,
|
|
ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES);
|
|
- if (count == 0 || count > MAX_PCC_SUBSPACES) {
|
|
- pr_warn("Invalid PCCT: %d PCC subspaces\n", count);
|
|
+ if (count <= 0 || count > MAX_PCC_SUBSPACES) {
|
|
+ if (count < 0)
|
|
+ pr_warn("Error parsing PCC subspaces from PCCT\n");
|
|
+ else
|
|
+ pr_warn("Invalid PCCT: %d PCC subspaces\n", count);
|
|
return -EINVAL;
|
|
}
|
|
|
|
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
|
|
index e7d4817681f2..3f4211b5cd33 100644
|
|
--- a/drivers/md/bcache/btree.c
|
|
+++ b/drivers/md/bcache/btree.c
|
|
@@ -2434,7 +2434,7 @@ static int refill_keybuf_fn(struct btree_op *op, struct btree *b,
|
|
struct keybuf *buf = refill->buf;
|
|
int ret = MAP_CONTINUE;
|
|
|
|
- if (bkey_cmp(k, refill->end) >= 0) {
|
|
+ if (bkey_cmp(k, refill->end) > 0) {
|
|
ret = MAP_DONE;
|
|
goto out;
|
|
}
|
|
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
|
|
index 51be355a3309..22944aa7d8e5 100644
|
|
--- a/drivers/md/bcache/request.c
|
|
+++ b/drivers/md/bcache/request.c
|
|
@@ -850,7 +850,7 @@ static void cached_dev_read_done_bh(struct closure *cl)
|
|
|
|
bch_mark_cache_accounting(s->iop.c, s->d,
|
|
!s->cache_missed, s->iop.bypass);
|
|
- trace_bcache_read(s->orig_bio, !s->cache_miss, s->iop.bypass);
|
|
+ trace_bcache_read(s->orig_bio, !s->cache_missed, s->iop.bypass);
|
|
|
|
if (s->iop.status)
|
|
continue_at_nobarrier(cl, cached_dev_read_error, bcache_wq);
|
|
@@ -1218,6 +1218,9 @@ static int cached_dev_ioctl(struct bcache_device *d, fmode_t mode,
|
|
{
|
|
struct cached_dev *dc = container_of(d, struct cached_dev, disk);
|
|
|
|
+ if (dc->io_disable)
|
|
+ return -EIO;
|
|
+
|
|
return __blkdev_driver_ioctl(dc->bdev, mode, cmd, arg);
|
|
}
|
|
|
|
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
|
|
index 30ba9aeb5ee8..03bb5cee2b83 100644
|
|
--- a/drivers/md/bcache/super.c
|
|
+++ b/drivers/md/bcache/super.c
|
|
@@ -643,10 +643,6 @@ static int ioctl_dev(struct block_device *b, fmode_t mode,
|
|
unsigned int cmd, unsigned long arg)
|
|
{
|
|
struct bcache_device *d = b->bd_disk->private_data;
|
|
- struct cached_dev *dc = container_of(d, struct cached_dev, disk);
|
|
-
|
|
- if (dc->io_disable)
|
|
- return -EIO;
|
|
|
|
return d->ioctl(d, mode, cmd, arg);
|
|
}
|
|
@@ -1152,11 +1148,12 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
|
|
}
|
|
|
|
if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
|
|
- bch_sectors_dirty_init(&dc->disk);
|
|
atomic_set(&dc->has_dirty, 1);
|
|
bch_writeback_queue(dc);
|
|
}
|
|
|
|
+ bch_sectors_dirty_init(&dc->disk);
|
|
+
|
|
bch_cached_dev_run(dc);
|
|
bcache_device_link(&dc->disk, c, "bdev");
|
|
atomic_inc(&c->attached_dev_nr);
|
|
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
|
|
index 150cf4f4cf74..26f035a0c5b9 100644
|
|
--- a/drivers/md/bcache/sysfs.c
|
|
+++ b/drivers/md/bcache/sysfs.c
|
|
@@ -285,6 +285,7 @@ STORE(__cached_dev)
|
|
1, WRITEBACK_RATE_UPDATE_SECS_MAX);
|
|
d_strtoul(writeback_rate_i_term_inverse);
|
|
d_strtoul_nonzero(writeback_rate_p_term_inverse);
|
|
+ d_strtoul_nonzero(writeback_rate_minimum);
|
|
|
|
sysfs_strtoul_clamp(io_error_limit, dc->error_limit, 0, INT_MAX);
|
|
|
|
@@ -412,6 +413,7 @@ static struct attribute *bch_cached_dev_files[] = {
|
|
&sysfs_writeback_rate_update_seconds,
|
|
&sysfs_writeback_rate_i_term_inverse,
|
|
&sysfs_writeback_rate_p_term_inverse,
|
|
+ &sysfs_writeback_rate_minimum,
|
|
&sysfs_writeback_rate_debug,
|
|
&sysfs_errors,
|
|
&sysfs_io_error_limit,
|
|
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
|
|
index b810ea77e6b1..f666778ad237 100644
|
|
--- a/drivers/md/dm-ioctl.c
|
|
+++ b/drivers/md/dm-ioctl.c
|
|
@@ -1720,8 +1720,7 @@ static void free_params(struct dm_ioctl *param, size_t param_size, int param_fla
|
|
}
|
|
|
|
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kernel,
|
|
- int ioctl_flags,
|
|
- struct dm_ioctl **param, int *param_flags)
|
|
+ int ioctl_flags, struct dm_ioctl **param, int *param_flags)
|
|
{
|
|
struct dm_ioctl *dmi;
|
|
int secure_data;
|
|
@@ -1762,18 +1761,13 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
|
|
|
|
*param_flags |= DM_PARAMS_MALLOC;
|
|
|
|
- if (copy_from_user(dmi, user, param_kernel->data_size))
|
|
- goto bad;
|
|
+ /* Copy from param_kernel (which was already copied from user) */
|
|
+ memcpy(dmi, param_kernel, minimum_data_size);
|
|
|
|
-data_copied:
|
|
- /*
|
|
- * Abort if something changed the ioctl data while it was being copied.
|
|
- */
|
|
- if (dmi->data_size != param_kernel->data_size) {
|
|
- DMERR("rejecting ioctl: data size modified while processing parameters");
|
|
+ if (copy_from_user(&dmi->data, (char __user *)user + minimum_data_size,
|
|
+ param_kernel->data_size - minimum_data_size))
|
|
goto bad;
|
|
- }
|
|
-
|
|
+data_copied:
|
|
/* Wipe the user buffer so we do not return it to userspace */
|
|
if (secure_data && clear_user(user, param_kernel->data_size))
|
|
goto bad;
|
|
diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
|
|
index 969954915566..fa68336560c3 100644
|
|
--- a/drivers/md/dm-zoned-metadata.c
|
|
+++ b/drivers/md/dm-zoned-metadata.c
|
|
@@ -99,7 +99,7 @@ struct dmz_mblock {
|
|
struct rb_node node;
|
|
struct list_head link;
|
|
sector_t no;
|
|
- atomic_t ref;
|
|
+ unsigned int ref;
|
|
unsigned long state;
|
|
struct page *page;
|
|
void *data;
|
|
@@ -296,7 +296,7 @@ static struct dmz_mblock *dmz_alloc_mblock(struct dmz_metadata *zmd,
|
|
|
|
RB_CLEAR_NODE(&mblk->node);
|
|
INIT_LIST_HEAD(&mblk->link);
|
|
- atomic_set(&mblk->ref, 0);
|
|
+ mblk->ref = 0;
|
|
mblk->state = 0;
|
|
mblk->no = mblk_no;
|
|
mblk->data = page_address(mblk->page);
|
|
@@ -339,10 +339,11 @@ static void dmz_insert_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk)
|
|
}
|
|
|
|
/*
|
|
- * Lookup a metadata block in the rbtree.
|
|
+ * Lookup a metadata block in the rbtree. If the block is found, increment
|
|
+ * its reference count.
|
|
*/
|
|
-static struct dmz_mblock *dmz_lookup_mblock(struct dmz_metadata *zmd,
|
|
- sector_t mblk_no)
|
|
+static struct dmz_mblock *dmz_get_mblock_fast(struct dmz_metadata *zmd,
|
|
+ sector_t mblk_no)
|
|
{
|
|
struct rb_root *root = &zmd->mblk_rbtree;
|
|
struct rb_node *node = root->rb_node;
|
|
@@ -350,8 +351,17 @@ static struct dmz_mblock *dmz_lookup_mblock(struct dmz_metadata *zmd,
|
|
|
|
while (node) {
|
|
mblk = container_of(node, struct dmz_mblock, node);
|
|
- if (mblk->no == mblk_no)
|
|
+ if (mblk->no == mblk_no) {
|
|
+ /*
|
|
+ * If this is the first reference to the block,
|
|
+ * remove it from the LRU list.
|
|
+ */
|
|
+ mblk->ref++;
|
|
+ if (mblk->ref == 1 &&
|
|
+ !test_bit(DMZ_META_DIRTY, &mblk->state))
|
|
+ list_del_init(&mblk->link);
|
|
return mblk;
|
|
+ }
|
|
node = (mblk->no < mblk_no) ? node->rb_left : node->rb_right;
|
|
}
|
|
|
|
@@ -382,32 +392,47 @@ static void dmz_mblock_bio_end_io(struct bio *bio)
|
|
}
|
|
|
|
/*
|
|
- * Read a metadata block from disk.
|
|
+ * Read an uncached metadata block from disk and add it to the cache.
|
|
*/
|
|
-static struct dmz_mblock *dmz_fetch_mblock(struct dmz_metadata *zmd,
|
|
- sector_t mblk_no)
|
|
+static struct dmz_mblock *dmz_get_mblock_slow(struct dmz_metadata *zmd,
|
|
+ sector_t mblk_no)
|
|
{
|
|
- struct dmz_mblock *mblk;
|
|
+ struct dmz_mblock *mblk, *m;
|
|
sector_t block = zmd->sb[zmd->mblk_primary].block + mblk_no;
|
|
struct bio *bio;
|
|
|
|
- /* Get block and insert it */
|
|
+ /* Get a new block and a BIO to read it */
|
|
mblk = dmz_alloc_mblock(zmd, mblk_no);
|
|
if (!mblk)
|
|
return NULL;
|
|
|
|
- spin_lock(&zmd->mblk_lock);
|
|
- atomic_inc(&mblk->ref);
|
|
- set_bit(DMZ_META_READING, &mblk->state);
|
|
- dmz_insert_mblock(zmd, mblk);
|
|
- spin_unlock(&zmd->mblk_lock);
|
|
-
|
|
bio = bio_alloc(GFP_NOIO, 1);
|
|
if (!bio) {
|
|
dmz_free_mblock(zmd, mblk);
|
|
return NULL;
|
|
}
|
|
|
|
+ spin_lock(&zmd->mblk_lock);
|
|
+
|
|
+ /*
|
|
+ * Make sure that another context did not start reading
|
|
+ * the block already.
|
|
+ */
|
|
+ m = dmz_get_mblock_fast(zmd, mblk_no);
|
|
+ if (m) {
|
|
+ spin_unlock(&zmd->mblk_lock);
|
|
+ dmz_free_mblock(zmd, mblk);
|
|
+ bio_put(bio);
|
|
+ return m;
|
|
+ }
|
|
+
|
|
+ mblk->ref++;
|
|
+ set_bit(DMZ_META_READING, &mblk->state);
|
|
+ dmz_insert_mblock(zmd, mblk);
|
|
+
|
|
+ spin_unlock(&zmd->mblk_lock);
|
|
+
|
|
+ /* Submit read BIO */
|
|
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
|
bio_set_dev(bio, zmd->dev->bdev);
|
|
bio->bi_private = mblk;
|
|
@@ -484,7 +509,8 @@ static void dmz_release_mblock(struct dmz_metadata *zmd,
|
|
|
|
spin_lock(&zmd->mblk_lock);
|
|
|
|
- if (atomic_dec_and_test(&mblk->ref)) {
|
|
+ mblk->ref--;
|
|
+ if (mblk->ref == 0) {
|
|
if (test_bit(DMZ_META_ERROR, &mblk->state)) {
|
|
rb_erase(&mblk->node, &zmd->mblk_rbtree);
|
|
dmz_free_mblock(zmd, mblk);
|
|
@@ -508,18 +534,12 @@ static struct dmz_mblock *dmz_get_mblock(struct dmz_metadata *zmd,
|
|
|
|
/* Check rbtree */
|
|
spin_lock(&zmd->mblk_lock);
|
|
- mblk = dmz_lookup_mblock(zmd, mblk_no);
|
|
- if (mblk) {
|
|
- /* Cache hit: remove block from LRU list */
|
|
- if (atomic_inc_return(&mblk->ref) == 1 &&
|
|
- !test_bit(DMZ_META_DIRTY, &mblk->state))
|
|
- list_del_init(&mblk->link);
|
|
- }
|
|
+ mblk = dmz_get_mblock_fast(zmd, mblk_no);
|
|
spin_unlock(&zmd->mblk_lock);
|
|
|
|
if (!mblk) {
|
|
/* Cache miss: read the block from disk */
|
|
- mblk = dmz_fetch_mblock(zmd, mblk_no);
|
|
+ mblk = dmz_get_mblock_slow(zmd, mblk_no);
|
|
if (!mblk)
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
@@ -753,7 +773,7 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
|
|
|
|
spin_lock(&zmd->mblk_lock);
|
|
clear_bit(DMZ_META_DIRTY, &mblk->state);
|
|
- if (atomic_read(&mblk->ref) == 0)
|
|
+ if (mblk->ref == 0)
|
|
list_add_tail(&mblk->link, &zmd->mblk_lru_list);
|
|
spin_unlock(&zmd->mblk_lock);
|
|
}
|
|
@@ -2308,7 +2328,7 @@ static void dmz_cleanup_metadata(struct dmz_metadata *zmd)
|
|
mblk = list_first_entry(&zmd->mblk_dirty_list,
|
|
struct dmz_mblock, link);
|
|
dmz_dev_warn(zmd->dev, "mblock %llu still in dirty list (ref %u)",
|
|
- (u64)mblk->no, atomic_read(&mblk->ref));
|
|
+ (u64)mblk->no, mblk->ref);
|
|
list_del_init(&mblk->link);
|
|
rb_erase(&mblk->node, &zmd->mblk_rbtree);
|
|
dmz_free_mblock(zmd, mblk);
|
|
@@ -2326,8 +2346,8 @@ static void dmz_cleanup_metadata(struct dmz_metadata *zmd)
|
|
root = &zmd->mblk_rbtree;
|
|
rbtree_postorder_for_each_entry_safe(mblk, next, root, node) {
|
|
dmz_dev_warn(zmd->dev, "mblock %llu ref %u still in rbtree",
|
|
- (u64)mblk->no, atomic_read(&mblk->ref));
|
|
- atomic_set(&mblk->ref, 0);
|
|
+ (u64)mblk->no, mblk->ref);
|
|
+ mblk->ref = 0;
|
|
dmz_free_mblock(zmd, mblk);
|
|
}
|
|
|
|
diff --git a/drivers/md/md.c b/drivers/md/md.c
|
|
index 63ceabb4e020..8668793262d0 100644
|
|
--- a/drivers/md/md.c
|
|
+++ b/drivers/md/md.c
|
|
@@ -452,10 +452,11 @@ static void md_end_flush(struct bio *fbio)
|
|
rdev_dec_pending(rdev, mddev);
|
|
|
|
if (atomic_dec_and_test(&fi->flush_pending)) {
|
|
- if (bio->bi_iter.bi_size == 0)
|
|
+ if (bio->bi_iter.bi_size == 0) {
|
|
/* an empty barrier - all done */
|
|
bio_endio(bio);
|
|
- else {
|
|
+ mempool_free(fi, mddev->flush_pool);
|
|
+ } else {
|
|
INIT_WORK(&fi->flush_work, submit_flushes);
|
|
queue_work(md_wq, &fi->flush_work);
|
|
}
|
|
@@ -509,10 +510,11 @@ void md_flush_request(struct mddev *mddev, struct bio *bio)
|
|
rcu_read_unlock();
|
|
|
|
if (atomic_dec_and_test(&fi->flush_pending)) {
|
|
- if (bio->bi_iter.bi_size == 0)
|
|
+ if (bio->bi_iter.bi_size == 0) {
|
|
/* an empty barrier - all done */
|
|
bio_endio(bio);
|
|
- else {
|
|
+ mempool_free(fi, mddev->flush_pool);
|
|
+ } else {
|
|
INIT_WORK(&fi->flush_work, submit_flushes);
|
|
queue_work(md_wq, &fi->flush_work);
|
|
}
|
|
@@ -5904,14 +5906,6 @@ static void __md_stop(struct mddev *mddev)
|
|
mddev->to_remove = &md_redundancy_group;
|
|
module_put(pers->owner);
|
|
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
|
-}
|
|
-
|
|
-void md_stop(struct mddev *mddev)
|
|
-{
|
|
- /* stop the array and free an attached data structures.
|
|
- * This is called from dm-raid
|
|
- */
|
|
- __md_stop(mddev);
|
|
if (mddev->flush_bio_pool) {
|
|
mempool_destroy(mddev->flush_bio_pool);
|
|
mddev->flush_bio_pool = NULL;
|
|
@@ -5920,6 +5914,14 @@ void md_stop(struct mddev *mddev)
|
|
mempool_destroy(mddev->flush_pool);
|
|
mddev->flush_pool = NULL;
|
|
}
|
|
+}
|
|
+
|
|
+void md_stop(struct mddev *mddev)
|
|
+{
|
|
+ /* stop the array and free an attached data structures.
|
|
+ * This is called from dm-raid
|
|
+ */
|
|
+ __md_stop(mddev);
|
|
bioset_exit(&mddev->bio_set);
|
|
bioset_exit(&mddev->sync_set);
|
|
}
|
|
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
|
|
index 4e990246225e..1d54109071cc 100644
|
|
--- a/drivers/md/raid1.c
|
|
+++ b/drivers/md/raid1.c
|
|
@@ -1734,6 +1734,7 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|
*/
|
|
if (rdev->saved_raid_disk >= 0 &&
|
|
rdev->saved_raid_disk >= first &&
|
|
+ rdev->saved_raid_disk < conf->raid_disks &&
|
|
conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
|
|
first = last = rdev->saved_raid_disk;
|
|
|
|
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
|
|
index d6f7978b4449..811427e53126 100644
|
|
--- a/drivers/md/raid10.c
|
|
+++ b/drivers/md/raid10.c
|
|
@@ -1808,6 +1808,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|
first = last = rdev->raid_disk;
|
|
|
|
if (rdev->saved_raid_disk >= first &&
|
|
+ rdev->saved_raid_disk < conf->geo.raid_disks &&
|
|
conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
|
|
mirror = rdev->saved_raid_disk;
|
|
else
|
|
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
|
|
index 030b2602faf0..dd8bad74a1f0 100644
|
|
--- a/drivers/media/cec/cec-adap.c
|
|
+++ b/drivers/media/cec/cec-adap.c
|
|
@@ -341,7 +341,7 @@ static void cec_data_completed(struct cec_data *data)
|
|
*
|
|
* This function is called with adap->lock held.
|
|
*/
|
|
-static void cec_data_cancel(struct cec_data *data)
|
|
+static void cec_data_cancel(struct cec_data *data, u8 tx_status)
|
|
{
|
|
/*
|
|
* It's either the current transmit, or it is a pending
|
|
@@ -356,13 +356,11 @@ static void cec_data_cancel(struct cec_data *data)
|
|
}
|
|
|
|
if (data->msg.tx_status & CEC_TX_STATUS_OK) {
|
|
- /* Mark the canceled RX as a timeout */
|
|
data->msg.rx_ts = ktime_get_ns();
|
|
- data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
|
|
+ data->msg.rx_status = CEC_RX_STATUS_ABORTED;
|
|
} else {
|
|
- /* Mark the canceled TX as an error */
|
|
data->msg.tx_ts = ktime_get_ns();
|
|
- data->msg.tx_status |= CEC_TX_STATUS_ERROR |
|
|
+ data->msg.tx_status |= tx_status |
|
|
CEC_TX_STATUS_MAX_RETRIES;
|
|
data->msg.tx_error_cnt++;
|
|
data->attempts = 0;
|
|
@@ -390,15 +388,15 @@ static void cec_flush(struct cec_adapter *adap)
|
|
while (!list_empty(&adap->transmit_queue)) {
|
|
data = list_first_entry(&adap->transmit_queue,
|
|
struct cec_data, list);
|
|
- cec_data_cancel(data);
|
|
+ cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
|
|
}
|
|
if (adap->transmitting)
|
|
- cec_data_cancel(adap->transmitting);
|
|
+ cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED);
|
|
|
|
/* Cancel the pending timeout work. */
|
|
list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
|
|
if (cancel_delayed_work(&data->work))
|
|
- cec_data_cancel(data);
|
|
+ cec_data_cancel(data, CEC_TX_STATUS_OK);
|
|
/*
|
|
* If cancel_delayed_work returned false, then
|
|
* the cec_wait_timeout function is running,
|
|
@@ -474,12 +472,13 @@ int cec_thread_func(void *_adap)
|
|
* so much traffic on the bus that the adapter was
|
|
* unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
|
|
*/
|
|
- dprintk(1, "%s: message %*ph timed out\n", __func__,
|
|
+ pr_warn("cec-%s: message %*ph timed out\n", adap->name,
|
|
adap->transmitting->msg.len,
|
|
adap->transmitting->msg.msg);
|
|
adap->tx_timeouts++;
|
|
/* Just give up on this. */
|
|
- cec_data_cancel(adap->transmitting);
|
|
+ cec_data_cancel(adap->transmitting,
|
|
+ CEC_TX_STATUS_TIMEOUT);
|
|
goto unlock;
|
|
}
|
|
|
|
@@ -514,9 +513,11 @@ int cec_thread_func(void *_adap)
|
|
if (data->attempts) {
|
|
/* should be >= 3 data bit periods for a retry */
|
|
signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY;
|
|
- } else if (data->new_initiator) {
|
|
+ } else if (adap->last_initiator !=
|
|
+ cec_msg_initiator(&data->msg)) {
|
|
/* should be >= 5 data bit periods for new initiator */
|
|
signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
|
|
+ adap->last_initiator = cec_msg_initiator(&data->msg);
|
|
} else {
|
|
/*
|
|
* should be >= 7 data bit periods for sending another
|
|
@@ -530,7 +531,7 @@ int cec_thread_func(void *_adap)
|
|
/* Tell the adapter to transmit, cancel on error */
|
|
if (adap->ops->adap_transmit(adap, data->attempts,
|
|
signal_free_time, &data->msg))
|
|
- cec_data_cancel(data);
|
|
+ cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
|
|
|
|
unlock:
|
|
mutex_unlock(&adap->lock);
|
|
@@ -701,9 +702,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|
struct cec_fh *fh, bool block)
|
|
{
|
|
struct cec_data *data;
|
|
- u8 last_initiator = 0xff;
|
|
- unsigned int timeout;
|
|
- int res = 0;
|
|
|
|
msg->rx_ts = 0;
|
|
msg->tx_ts = 0;
|
|
@@ -813,23 +811,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|
data->adap = adap;
|
|
data->blocking = block;
|
|
|
|
- /*
|
|
- * Determine if this message follows a message from the same
|
|
- * initiator. Needed to determine the free signal time later on.
|
|
- */
|
|
- if (msg->len > 1) {
|
|
- if (!(list_empty(&adap->transmit_queue))) {
|
|
- const struct cec_data *last;
|
|
-
|
|
- last = list_last_entry(&adap->transmit_queue,
|
|
- const struct cec_data, list);
|
|
- last_initiator = cec_msg_initiator(&last->msg);
|
|
- } else if (adap->transmitting) {
|
|
- last_initiator =
|
|
- cec_msg_initiator(&adap->transmitting->msg);
|
|
- }
|
|
- }
|
|
- data->new_initiator = last_initiator != cec_msg_initiator(msg);
|
|
init_completion(&data->c);
|
|
INIT_DELAYED_WORK(&data->work, cec_wait_timeout);
|
|
|
|
@@ -845,48 +826,23 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|
if (!block)
|
|
return 0;
|
|
|
|
- /*
|
|
- * If we don't get a completion before this time something is really
|
|
- * wrong and we time out.
|
|
- */
|
|
- timeout = CEC_XFER_TIMEOUT_MS;
|
|
- /* Add the requested timeout if we have to wait for a reply as well */
|
|
- if (msg->timeout)
|
|
- timeout += msg->timeout;
|
|
-
|
|
/*
|
|
* Release the lock and wait, retake the lock afterwards.
|
|
*/
|
|
mutex_unlock(&adap->lock);
|
|
- res = wait_for_completion_killable_timeout(&data->c,
|
|
- msecs_to_jiffies(timeout));
|
|
+ wait_for_completion_killable(&data->c);
|
|
+ if (!data->completed)
|
|
+ cancel_delayed_work_sync(&data->work);
|
|
mutex_lock(&adap->lock);
|
|
|
|
- if (data->completed) {
|
|
- /* The transmit completed (possibly with an error) */
|
|
- *msg = data->msg;
|
|
- kfree(data);
|
|
- return 0;
|
|
- }
|
|
- /*
|
|
- * The wait for completion timed out or was interrupted, so mark this
|
|
- * as non-blocking and disconnect from the filehandle since it is
|
|
- * still 'in flight'. When it finally completes it will just drop the
|
|
- * result silently.
|
|
- */
|
|
- data->blocking = false;
|
|
- if (data->fh)
|
|
- list_del(&data->xfer_list);
|
|
- data->fh = NULL;
|
|
+ /* Cancel the transmit if it was interrupted */
|
|
+ if (!data->completed)
|
|
+ cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
|
|
|
|
- if (res == 0) { /* timed out */
|
|
- /* Check if the reply or the transmit failed */
|
|
- if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK))
|
|
- msg->rx_status = CEC_RX_STATUS_TIMEOUT;
|
|
- else
|
|
- msg->tx_status = CEC_TX_STATUS_MAX_RETRIES;
|
|
- }
|
|
- return res > 0 ? 0 : res;
|
|
+ /* The transmit completed (possibly with an error) */
|
|
+ *msg = data->msg;
|
|
+ kfree(data);
|
|
+ return 0;
|
|
}
|
|
|
|
/* Helper function to be used by drivers and this framework. */
|
|
@@ -1044,6 +1000,8 @@ void cec_received_msg_ts(struct cec_adapter *adap,
|
|
mutex_lock(&adap->lock);
|
|
dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
|
|
|
|
+ adap->last_initiator = 0xff;
|
|
+
|
|
/* Check if this message was for us (directed or broadcast). */
|
|
if (!cec_msg_is_broadcast(msg))
|
|
valid_la = cec_has_log_addr(adap, msg_dest);
|
|
@@ -1506,6 +1464,8 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
|
}
|
|
|
|
mutex_lock(&adap->devnode.lock);
|
|
+ adap->last_initiator = 0xff;
|
|
+
|
|
if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
|
|
adap->ops->adap_enable(adap, true)) {
|
|
mutex_unlock(&adap->devnode.lock);
|
|
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
|
|
index b6536bbad530..4961573850d5 100644
|
|
--- a/drivers/media/cec/cec-api.c
|
|
+++ b/drivers/media/cec/cec-api.c
|
|
@@ -101,6 +101,23 @@ static long cec_adap_g_phys_addr(struct cec_adapter *adap,
|
|
return 0;
|
|
}
|
|
|
|
+static int cec_validate_phys_addr(u16 phys_addr)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (phys_addr == CEC_PHYS_ADDR_INVALID)
|
|
+ return 0;
|
|
+ for (i = 0; i < 16; i += 4)
|
|
+ if (phys_addr & (0xf << i))
|
|
+ break;
|
|
+ if (i == 16)
|
|
+ return 0;
|
|
+ for (i += 4; i < 16; i += 4)
|
|
+ if ((phys_addr & (0xf << i)) == 0)
|
|
+ return -EINVAL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
|
|
bool block, __u16 __user *parg)
|
|
{
|
|
@@ -112,7 +129,7 @@ static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
|
|
if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
|
|
return -EFAULT;
|
|
|
|
- err = cec_phys_addr_validate(phys_addr, NULL, NULL);
|
|
+ err = cec_validate_phys_addr(phys_addr);
|
|
if (err)
|
|
return err;
|
|
mutex_lock(&adap->lock);
|
|
diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c
|
|
index ec72ac1c0b91..f587e8eaefd8 100644
|
|
--- a/drivers/media/cec/cec-edid.c
|
|
+++ b/drivers/media/cec/cec-edid.c
|
|
@@ -10,66 +10,6 @@
|
|
#include <linux/types.h>
|
|
#include <media/cec.h>
|
|
|
|
-/*
|
|
- * This EDID is expected to be a CEA-861 compliant, which means that there are
|
|
- * at least two blocks and one or more of the extensions blocks are CEA-861
|
|
- * blocks.
|
|
- *
|
|
- * The returned location is guaranteed to be < size - 1.
|
|
- */
|
|
-static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size)
|
|
-{
|
|
- unsigned int blocks = size / 128;
|
|
- unsigned int block;
|
|
- u8 d;
|
|
-
|
|
- /* Sanity check: at least 2 blocks and a multiple of the block size */
|
|
- if (blocks < 2 || size % 128)
|
|
- return 0;
|
|
-
|
|
- /*
|
|
- * If there are fewer extension blocks than the size, then update
|
|
- * 'blocks'. It is allowed to have more extension blocks than the size,
|
|
- * since some hardware can only read e.g. 256 bytes of the EDID, even
|
|
- * though more blocks are present. The first CEA-861 extension block
|
|
- * should normally be in block 1 anyway.
|
|
- */
|
|
- if (edid[0x7e] + 1 < blocks)
|
|
- blocks = edid[0x7e] + 1;
|
|
-
|
|
- for (block = 1; block < blocks; block++) {
|
|
- unsigned int offset = block * 128;
|
|
-
|
|
- /* Skip any non-CEA-861 extension blocks */
|
|
- if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
|
|
- continue;
|
|
-
|
|
- /* search Vendor Specific Data Block (tag 3) */
|
|
- d = edid[offset + 2] & 0x7f;
|
|
- /* Check if there are Data Blocks */
|
|
- if (d <= 4)
|
|
- continue;
|
|
- if (d > 4) {
|
|
- unsigned int i = offset + 4;
|
|
- unsigned int end = offset + d;
|
|
-
|
|
- /* Note: 'end' is always < 'size' */
|
|
- do {
|
|
- u8 tag = edid[i] >> 5;
|
|
- u8 len = edid[i] & 0x1f;
|
|
-
|
|
- if (tag == 3 && len >= 5 && i + len <= end &&
|
|
- edid[i + 1] == 0x03 &&
|
|
- edid[i + 2] == 0x0c &&
|
|
- edid[i + 3] == 0x00)
|
|
- return i + 4;
|
|
- i += len + 1;
|
|
- } while (i < end);
|
|
- }
|
|
- }
|
|
- return 0;
|
|
-}
|
|
-
|
|
u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
|
|
unsigned int *offset)
|
|
{
|
|
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
|
|
index 3a3dc23c560c..a4341205c197 100644
|
|
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
|
|
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
|
|
@@ -602,14 +602,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 },
|
|
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 },
|
|
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 },
|
|
- [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 },
|
|
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 },
|
|
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 },
|
|
@@ -658,14 +658,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 },
|
|
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 },
|
|
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 },
|
|
- [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 },
|
|
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 },
|
|
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 },
|
|
@@ -714,14 +714,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 },
|
|
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 },
|
|
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 },
|
|
- [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 },
|
|
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 },
|
|
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 },
|
|
@@ -770,14 +770,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2599, 901, 909 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 991, 0, 2966 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2989, 3120, 1180 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1913, 3011, 3009 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1836, 3099, 1105 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2627, 413, 2966 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2576, 943, 951 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1026, 0, 2942 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][1] = { 2989, 3120, 1180 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][2] = { 1913, 3011, 3009 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][3] = { 1836, 3099, 1105 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][4] = { 2627, 413, 2966 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][5] = { 2576, 943, 951 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][6] = { 1026, 0, 2942 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2879, 3022, 874 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1688, 2903, 2901 },
|
|
@@ -826,14 +826,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][5] = { 3001, 800, 799 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3071 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 776 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][2] = { 1068, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][3] = { 1068, 3033, 776 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][4] = { 2977, 851, 3048 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][5] = { 2977, 851, 851 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3048 },
|
|
- [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 776 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][2] = { 1068, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][3] = { 1068, 3033, 776 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][4] = { 2977, 851, 3048 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][5] = { 2977, 851, 851 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3048 },
|
|
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 423 },
|
|
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][2] = { 749, 2926, 2926 },
|
|
@@ -882,14 +882,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 },
|
|
- [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 },
|
|
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 },
|
|
@@ -922,62 +922,62 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1812, 886, 886 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1812 },
|
|
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 1063 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 1828, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 1828, 3033, 1063 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 2633, 851, 2979 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 2633, 851, 851 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 2979 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 },
|
|
- [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 1063 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][2] = { 1828, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][3] = { 1828, 3033, 1063 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][4] = { 2633, 851, 2979 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][5] = { 2633, 851, 851 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 2979 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 },
|
|
+ [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 },
|
|
@@ -994,14 +994,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][5] = { 2517, 1159, 900 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][6] = { 1042, 870, 2917 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][1] = { 2976, 3018, 1315 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][2] = { 2024, 2942, 3011 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][3] = { 1930, 2926, 1256 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][4] = { 2563, 1227, 2916 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][5] = { 2494, 1183, 943 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][6] = { 1073, 916, 2894 },
|
|
- [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][1] = { 2976, 3018, 1315 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][2] = { 2024, 2942, 3011 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][3] = { 1930, 2926, 1256 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][4] = { 2563, 1227, 2916 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][5] = { 2494, 1183, 943 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][6] = { 1073, 916, 2894 },
|
|
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][1] = { 2864, 2910, 1024 },
|
|
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][2] = { 1811, 2826, 2903 },
|
|
@@ -1050,14 +1050,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
|
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][5] = { 2880, 998, 902 },
|
|
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][6] = { 816, 823, 2940 },
|
|
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][1] = { 3029, 3028, 1255 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][2] = { 1406, 2988, 3011 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][3] = { 1398, 2983, 1190 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][4] = { 2860, 1050, 2939 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][5] = { 2857, 1033, 945 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][6] = { 866, 873, 2916 },
|
|
- [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][1] = { 3029, 3028, 1255 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][2] = { 1406, 2988, 3011 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][3] = { 1398, 2983, 1190 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][4] = { 2860, 1050, 2939 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][5] = { 2857, 1033, 945 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][6] = { 866, 873, 2916 },
|
|
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
|
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
|
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][1] = { 2923, 2921, 957 },
|
|
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][2] = { 1125, 2877, 2902 },
|
|
@@ -1128,7 +1128,7 @@ static const double rec709_to_240m[3][3] = {
|
|
{ 0.0016327, 0.0044133, 0.9939540 },
|
|
};
|
|
|
|
-static const double rec709_to_adobergb[3][3] = {
|
|
+static const double rec709_to_oprgb[3][3] = {
|
|
{ 0.7151627, 0.2848373, -0.0000000 },
|
|
{ 0.0000000, 1.0000000, 0.0000000 },
|
|
{ -0.0000000, 0.0411705, 0.9588295 },
|
|
@@ -1195,7 +1195,7 @@ static double transfer_rec709_to_rgb(double v)
|
|
return (v < 0.081) ? v / 4.5 : pow((v + 0.099) / 1.099, 1.0 / 0.45);
|
|
}
|
|
|
|
-static double transfer_rgb_to_adobergb(double v)
|
|
+static double transfer_rgb_to_oprgb(double v)
|
|
{
|
|
return pow(v, 1.0 / 2.19921875);
|
|
}
|
|
@@ -1251,8 +1251,8 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
|
|
case V4L2_COLORSPACE_470_SYSTEM_M:
|
|
mult_matrix(r, g, b, rec709_to_ntsc1953);
|
|
break;
|
|
- case V4L2_COLORSPACE_ADOBERGB:
|
|
- mult_matrix(r, g, b, rec709_to_adobergb);
|
|
+ case V4L2_COLORSPACE_OPRGB:
|
|
+ mult_matrix(r, g, b, rec709_to_oprgb);
|
|
break;
|
|
case V4L2_COLORSPACE_BT2020:
|
|
mult_matrix(r, g, b, rec709_to_bt2020);
|
|
@@ -1284,10 +1284,10 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
|
|
*g = transfer_rgb_to_srgb(*g);
|
|
*b = transfer_rgb_to_srgb(*b);
|
|
break;
|
|
- case V4L2_XFER_FUNC_ADOBERGB:
|
|
- *r = transfer_rgb_to_adobergb(*r);
|
|
- *g = transfer_rgb_to_adobergb(*g);
|
|
- *b = transfer_rgb_to_adobergb(*b);
|
|
+ case V4L2_XFER_FUNC_OPRGB:
|
|
+ *r = transfer_rgb_to_oprgb(*r);
|
|
+ *g = transfer_rgb_to_oprgb(*g);
|
|
+ *b = transfer_rgb_to_oprgb(*b);
|
|
break;
|
|
case V4L2_XFER_FUNC_DCI_P3:
|
|
*r = transfer_rgb_to_dcip3(*r);
|
|
@@ -1321,7 +1321,7 @@ int main(int argc, char **argv)
|
|
V4L2_COLORSPACE_470_SYSTEM_BG,
|
|
0,
|
|
V4L2_COLORSPACE_SRGB,
|
|
- V4L2_COLORSPACE_ADOBERGB,
|
|
+ V4L2_COLORSPACE_OPRGB,
|
|
V4L2_COLORSPACE_BT2020,
|
|
0,
|
|
V4L2_COLORSPACE_DCI_P3,
|
|
@@ -1336,7 +1336,7 @@ int main(int argc, char **argv)
|
|
"V4L2_COLORSPACE_470_SYSTEM_BG",
|
|
"",
|
|
"V4L2_COLORSPACE_SRGB",
|
|
- "V4L2_COLORSPACE_ADOBERGB",
|
|
+ "V4L2_COLORSPACE_OPRGB",
|
|
"V4L2_COLORSPACE_BT2020",
|
|
"",
|
|
"V4L2_COLORSPACE_DCI_P3",
|
|
@@ -1345,7 +1345,7 @@ int main(int argc, char **argv)
|
|
"",
|
|
"V4L2_XFER_FUNC_709",
|
|
"V4L2_XFER_FUNC_SRGB",
|
|
- "V4L2_XFER_FUNC_ADOBERGB",
|
|
+ "V4L2_XFER_FUNC_OPRGB",
|
|
"V4L2_XFER_FUNC_SMPTE240M",
|
|
"V4L2_XFER_FUNC_NONE",
|
|
"V4L2_XFER_FUNC_DCI_P3",
|
|
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
|
|
index abd4c788dffd..f40ab5704bf0 100644
|
|
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
|
|
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
|
|
@@ -1770,7 +1770,7 @@ typedef struct { u16 __; u8 _; } __packed x24;
|
|
pos[7] = (chr & (0x01 << 0) ? fg : bg); \
|
|
} \
|
|
\
|
|
- pos += (tpg->hflip ? -8 : 8) / hdiv; \
|
|
+ pos += (tpg->hflip ? -8 : 8) / (int)hdiv; \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
|
|
index 55c2ea0720d9..f3899cc84e27 100644
|
|
--- a/drivers/media/i2c/adv7511.c
|
|
+++ b/drivers/media/i2c/adv7511.c
|
|
@@ -1355,10 +1355,10 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd,
|
|
state->xfer_func = format->format.xfer_func;
|
|
|
|
switch (format->format.colorspace) {
|
|
- case V4L2_COLORSPACE_ADOBERGB:
|
|
+ case V4L2_COLORSPACE_OPRGB:
|
|
c = HDMI_COLORIMETRY_EXTENDED;
|
|
- ec = y ? HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601 :
|
|
- HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
|
|
+ ec = y ? HDMI_EXTENDED_COLORIMETRY_OPYCC_601 :
|
|
+ HDMI_EXTENDED_COLORIMETRY_OPRGB;
|
|
break;
|
|
case V4L2_COLORSPACE_SMPTE170M:
|
|
c = y ? HDMI_COLORIMETRY_ITU_601 : HDMI_COLORIMETRY_NONE;
|
|
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
|
|
index 668be2bca57a..c78698199ac5 100644
|
|
--- a/drivers/media/i2c/adv7604.c
|
|
+++ b/drivers/media/i2c/adv7604.c
|
|
@@ -2284,8 +2284,10 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
|
state->aspect_ratio.numerator = 16;
|
|
state->aspect_ratio.denominator = 9;
|
|
|
|
- if (!state->edid.present)
|
|
+ if (!state->edid.present) {
|
|
state->edid.blocks = 0;
|
|
+ cec_phys_addr_invalidate(state->cec_adap);
|
|
+ }
|
|
|
|
v4l2_dbg(2, debug, sd, "%s: clear EDID pad %d, edid.present = 0x%x\n",
|
|
__func__, edid->pad, state->edid.present);
|
|
@@ -2474,7 +2476,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd)
|
|
"YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
|
|
"xvYCC Bt.601", "xvYCC Bt.709",
|
|
"YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
|
|
- "sYCC", "Adobe YCC 601", "AdobeRGB", "invalid", "invalid",
|
|
+ "sYCC", "opYCC 601", "opRGB", "invalid", "invalid",
|
|
"invalid", "invalid", "invalid"
|
|
};
|
|
static const char * const rgb_quantization_range_txt[] = {
|
|
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
|
|
index 4f8fbdd00e35..71fe56565f75 100644
|
|
--- a/drivers/media/i2c/adv7842.c
|
|
+++ b/drivers/media/i2c/adv7842.c
|
|
@@ -786,8 +786,10 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
|
|
/* Disable I2C access to internal EDID ram from HDMI DDC ports */
|
|
rep_write_and_or(sd, 0x77, 0xf3, 0x00);
|
|
|
|
- if (!state->hdmi_edid.present)
|
|
+ if (!state->hdmi_edid.present) {
|
|
+ cec_phys_addr_invalidate(state->cec_adap);
|
|
return 0;
|
|
+ }
|
|
|
|
pa = cec_get_edid_phys_addr(edid, 256, &spa_loc);
|
|
err = cec_phys_addr_validate(pa, &pa, NULL);
|
|
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
|
|
index 31bf577b0bd3..64d1402882c8 100644
|
|
--- a/drivers/media/i2c/ov7670.c
|
|
+++ b/drivers/media/i2c/ov7670.c
|
|
@@ -1808,17 +1808,24 @@ static int ov7670_probe(struct i2c_client *client,
|
|
info->pclk_hb_disable = true;
|
|
}
|
|
|
|
- info->clk = devm_clk_get(&client->dev, "xclk");
|
|
- if (IS_ERR(info->clk))
|
|
- return PTR_ERR(info->clk);
|
|
- ret = clk_prepare_enable(info->clk);
|
|
- if (ret)
|
|
- return ret;
|
|
+ info->clk = devm_clk_get(&client->dev, "xclk"); /* optional */
|
|
+ if (IS_ERR(info->clk)) {
|
|
+ ret = PTR_ERR(info->clk);
|
|
+ if (ret == -ENOENT)
|
|
+ info->clk = NULL;
|
|
+ else
|
|
+ return ret;
|
|
+ }
|
|
+ if (info->clk) {
|
|
+ ret = clk_prepare_enable(info->clk);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
- info->clock_speed = clk_get_rate(info->clk) / 1000000;
|
|
- if (info->clock_speed < 10 || info->clock_speed > 48) {
|
|
- ret = -EINVAL;
|
|
- goto clk_disable;
|
|
+ info->clock_speed = clk_get_rate(info->clk) / 1000000;
|
|
+ if (info->clock_speed < 10 || info->clock_speed > 48) {
|
|
+ ret = -EINVAL;
|
|
+ goto clk_disable;
|
|
+ }
|
|
}
|
|
|
|
ret = ov7670_init_gpio(client, info);
|
|
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
|
|
index 44c41933415a..ff25ea9aca48 100644
|
|
--- a/drivers/media/i2c/tc358743.c
|
|
+++ b/drivers/media/i2c/tc358743.c
|
|
@@ -1243,9 +1243,9 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
|
|
u8 vi_status3 = i2c_rd8(sd, VI_STATUS3);
|
|
const int deep_color_mode[4] = { 8, 10, 12, 16 };
|
|
static const char * const input_color_space[] = {
|
|
- "RGB", "YCbCr 601", "Adobe RGB", "YCbCr 709", "NA (4)",
|
|
+ "RGB", "YCbCr 601", "opRGB", "YCbCr 709", "NA (4)",
|
|
"xvYCC 601", "NA(6)", "xvYCC 709", "NA(8)", "sYCC601",
|
|
- "NA(10)", "NA(11)", "NA(12)", "Adobe YCC 601"};
|
|
+ "NA(10)", "NA(11)", "NA(12)", "opYCC 601"};
|
|
|
|
v4l2_info(sd, "-----Chip status-----\n");
|
|
v4l2_info(sd, "Chip ID: 0x%02x\n",
|
|
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
|
|
index 76e6bed5a1da..805bd9c65940 100644
|
|
--- a/drivers/media/i2c/tvp5150.c
|
|
+++ b/drivers/media/i2c/tvp5150.c
|
|
@@ -1534,7 +1534,7 @@ static int tvp5150_probe(struct i2c_client *c,
|
|
27000000, 1, 27000000);
|
|
v4l2_ctrl_new_std_menu_items(&core->hdl, &tvp5150_ctrl_ops,
|
|
V4L2_CID_TEST_PATTERN,
|
|
- ARRAY_SIZE(tvp5150_test_patterns),
|
|
+ ARRAY_SIZE(tvp5150_test_patterns) - 1,
|
|
0, 0, tvp5150_test_patterns);
|
|
sd->ctrl_handler = &core->hdl;
|
|
if (core->hdl.error) {
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
|
|
index 477c80a4d44c..cd4c8230563c 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.h
|
|
+++ b/drivers/media/platform/vivid/vivid-core.h
|
|
@@ -111,7 +111,7 @@ enum vivid_colorspace {
|
|
VIVID_CS_170M,
|
|
VIVID_CS_709,
|
|
VIVID_CS_SRGB,
|
|
- VIVID_CS_ADOBERGB,
|
|
+ VIVID_CS_OPRGB,
|
|
VIVID_CS_2020,
|
|
VIVID_CS_DCI_P3,
|
|
VIVID_CS_240M,
|
|
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
index 5429193fbb91..999aa101b150 100644
|
|
--- a/drivers/media/platform/vivid/vivid-ctrls.c
|
|
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
@@ -348,7 +348,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
V4L2_COLORSPACE_SMPTE170M,
|
|
V4L2_COLORSPACE_REC709,
|
|
V4L2_COLORSPACE_SRGB,
|
|
- V4L2_COLORSPACE_ADOBERGB,
|
|
+ V4L2_COLORSPACE_OPRGB,
|
|
V4L2_COLORSPACE_BT2020,
|
|
V4L2_COLORSPACE_DCI_P3,
|
|
V4L2_COLORSPACE_SMPTE240M,
|
|
@@ -729,7 +729,7 @@ static const char * const vivid_ctrl_colorspace_strings[] = {
|
|
"SMPTE 170M",
|
|
"Rec. 709",
|
|
"sRGB",
|
|
- "AdobeRGB",
|
|
+ "opRGB",
|
|
"BT.2020",
|
|
"DCI-P3",
|
|
"SMPTE 240M",
|
|
@@ -752,7 +752,7 @@ static const char * const vivid_ctrl_xfer_func_strings[] = {
|
|
"Default",
|
|
"Rec. 709",
|
|
"sRGB",
|
|
- "AdobeRGB",
|
|
+ "opRGB",
|
|
"SMPTE 240M",
|
|
"None",
|
|
"DCI-P3",
|
|
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
|
|
index 51fec66d8d45..50248e2176a0 100644
|
|
--- a/drivers/media/platform/vivid/vivid-vid-out.c
|
|
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
|
|
@@ -413,7 +413,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
|
|
mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
|
|
} else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M &&
|
|
mp->colorspace != V4L2_COLORSPACE_REC709 &&
|
|
- mp->colorspace != V4L2_COLORSPACE_ADOBERGB &&
|
|
+ mp->colorspace != V4L2_COLORSPACE_OPRGB &&
|
|
mp->colorspace != V4L2_COLORSPACE_BT2020 &&
|
|
mp->colorspace != V4L2_COLORSPACE_SRGB) {
|
|
mp->colorspace = V4L2_COLORSPACE_REC709;
|
|
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
|
index 1aa88d94e57f..e28bd8836751 100644
|
|
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
|
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
|
@@ -31,6 +31,7 @@ MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver.");
|
|
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
|
|
|
struct dvbsky_state {
|
|
+ struct mutex stream_mutex;
|
|
u8 ibuf[DVBSKY_BUF_LEN];
|
|
u8 obuf[DVBSKY_BUF_LEN];
|
|
u8 last_lock;
|
|
@@ -67,17 +68,18 @@ static int dvbsky_usb_generic_rw(struct dvb_usb_device *d,
|
|
|
|
static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
|
|
{
|
|
+ struct dvbsky_state *state = d_to_priv(d);
|
|
int ret;
|
|
- static u8 obuf_pre[3] = { 0x37, 0, 0 };
|
|
- static u8 obuf_post[3] = { 0x36, 3, 0 };
|
|
+ u8 obuf_pre[3] = { 0x37, 0, 0 };
|
|
+ u8 obuf_post[3] = { 0x36, 3, 0 };
|
|
|
|
- mutex_lock(&d->usb_mutex);
|
|
- ret = dvb_usbv2_generic_rw_locked(d, obuf_pre, 3, NULL, 0);
|
|
+ mutex_lock(&state->stream_mutex);
|
|
+ ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0);
|
|
if (!ret && onoff) {
|
|
msleep(20);
|
|
- ret = dvb_usbv2_generic_rw_locked(d, obuf_post, 3, NULL, 0);
|
|
+ ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0);
|
|
}
|
|
- mutex_unlock(&d->usb_mutex);
|
|
+ mutex_unlock(&state->stream_mutex);
|
|
return ret;
|
|
}
|
|
|
|
@@ -606,6 +608,8 @@ static int dvbsky_init(struct dvb_usb_device *d)
|
|
if (ret)
|
|
return ret;
|
|
*/
|
|
+ mutex_init(&state->stream_mutex);
|
|
+
|
|
state->last_lock = 0;
|
|
|
|
return 0;
|
|
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
|
|
index 71c829f31d3b..87b887b7604e 100644
|
|
--- a/drivers/media/usb/em28xx/em28xx-cards.c
|
|
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
|
|
@@ -2141,13 +2141,13 @@ const struct em28xx_board em28xx_boards[] = {
|
|
.input = { {
|
|
.type = EM28XX_VMUX_COMPOSITE,
|
|
.vmux = TVP5150_COMPOSITE1,
|
|
- .amux = EM28XX_AUDIO_SRC_LINE,
|
|
+ .amux = EM28XX_AMUX_LINE_IN,
|
|
.gpio = terratec_av350_unmute_gpio,
|
|
|
|
}, {
|
|
.type = EM28XX_VMUX_SVIDEO,
|
|
.vmux = TVP5150_SVIDEO,
|
|
- .amux = EM28XX_AUDIO_SRC_LINE,
|
|
+ .amux = EM28XX_AMUX_LINE_IN,
|
|
.gpio = terratec_av350_unmute_gpio,
|
|
} },
|
|
},
|
|
@@ -3039,6 +3039,9 @@ static int em28xx_hint_board(struct em28xx *dev)
|
|
|
|
static void em28xx_card_setup(struct em28xx *dev)
|
|
{
|
|
+ int i, j, idx;
|
|
+ bool duplicate_entry;
|
|
+
|
|
/*
|
|
* If the device can be a webcam, seek for a sensor.
|
|
* If sensor is not found, then it isn't a webcam.
|
|
@@ -3195,6 +3198,32 @@ static void em28xx_card_setup(struct em28xx *dev)
|
|
/* Allow override tuner type by a module parameter */
|
|
if (tuner >= 0)
|
|
dev->tuner_type = tuner;
|
|
+
|
|
+ /*
|
|
+ * Dynamically generate a list of valid audio inputs for this
|
|
+ * specific board, mapping them via enum em28xx_amux.
|
|
+ */
|
|
+
|
|
+ idx = 0;
|
|
+ for (i = 0; i < MAX_EM28XX_INPUT; i++) {
|
|
+ if (!INPUT(i)->type)
|
|
+ continue;
|
|
+
|
|
+ /* Skip already mapped audio inputs */
|
|
+ duplicate_entry = false;
|
|
+ for (j = 0; j < idx; j++) {
|
|
+ if (INPUT(i)->amux == dev->amux_map[j]) {
|
|
+ duplicate_entry = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (duplicate_entry)
|
|
+ continue;
|
|
+
|
|
+ dev->amux_map[idx++] = INPUT(i)->amux;
|
|
+ }
|
|
+ for (; idx < MAX_EM28XX_INPUT; idx++)
|
|
+ dev->amux_map[idx] = EM28XX_AMUX_UNUSED;
|
|
}
|
|
|
|
void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
|
|
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
|
|
index 68571bf36d28..3bf98ac897ec 100644
|
|
--- a/drivers/media/usb/em28xx/em28xx-video.c
|
|
+++ b/drivers/media/usb/em28xx/em28xx-video.c
|
|
@@ -1093,6 +1093,8 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
|
|
|
|
em28xx_videodbg("%s\n", __func__);
|
|
|
|
+ dev->v4l2->field_count = 0;
|
|
+
|
|
/*
|
|
* Make sure streaming is not already in progress for this type
|
|
* of filehandle (e.g. video, vbi)
|
|
@@ -1471,9 +1473,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
|
if (!fmt) {
|
|
- em28xx_videodbg("Fourcc format (%08x) invalid.\n",
|
|
- f->fmt.pix.pixelformat);
|
|
- return -EINVAL;
|
|
+ fmt = &format[0];
|
|
+ em28xx_videodbg("Fourcc format (%08x) invalid. Using default (%08x).\n",
|
|
+ f->fmt.pix.pixelformat, fmt->fourcc);
|
|
}
|
|
|
|
if (dev->board.is_em2800) {
|
|
@@ -1666,6 +1668,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
|
|
{
|
|
struct em28xx *dev = video_drvdata(file);
|
|
unsigned int n;
|
|
+ int j;
|
|
|
|
n = i->index;
|
|
if (n >= MAX_EM28XX_INPUT)
|
|
@@ -1685,6 +1688,12 @@ static int vidioc_enum_input(struct file *file, void *priv,
|
|
if (dev->is_webcam)
|
|
i->capabilities = 0;
|
|
|
|
+ /* Dynamically generates an audioset bitmask */
|
|
+ i->audioset = 0;
|
|
+ for (j = 0; j < MAX_EM28XX_INPUT; j++)
|
|
+ if (dev->amux_map[j] != EM28XX_AMUX_UNUSED)
|
|
+ i->audioset |= 1 << j;
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1710,11 +1719,24 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
|
|
return 0;
|
|
}
|
|
|
|
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
|
|
+static int em28xx_fill_audio_input(struct em28xx *dev,
|
|
+ const char *s,
|
|
+ struct v4l2_audio *a,
|
|
+ unsigned int index)
|
|
{
|
|
- struct em28xx *dev = video_drvdata(file);
|
|
+ unsigned int idx = dev->amux_map[index];
|
|
+
|
|
+ /*
|
|
+ * With msp3400, almost all mappings use the default (amux = 0).
|
|
+ * The only one may use a different value is WinTV USB2, where it
|
|
+ * can also be SCART1 input.
|
|
+ * As it is very doubtful that we would see new boards with msp3400,
|
|
+ * let's just reuse the existing switch.
|
|
+ */
|
|
+ if (dev->has_msp34xx && idx != EM28XX_AMUX_UNUSED)
|
|
+ idx = EM28XX_AMUX_LINE_IN;
|
|
|
|
- switch (a->index) {
|
|
+ switch (idx) {
|
|
case EM28XX_AMUX_VIDEO:
|
|
strcpy(a->name, "Television");
|
|
break;
|
|
@@ -1739,32 +1761,79 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
|
|
case EM28XX_AMUX_PCM_OUT:
|
|
strcpy(a->name, "PCM");
|
|
break;
|
|
+ case EM28XX_AMUX_UNUSED:
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
-
|
|
- a->index = dev->ctl_ainput;
|
|
+ a->index = index;
|
|
a->capability = V4L2_AUDCAP_STEREO;
|
|
|
|
+ em28xx_videodbg("%s: audio input index %d is '%s'\n",
|
|
+ s, a->index, a->name);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
+static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
|
|
+{
|
|
+ struct em28xx *dev = video_drvdata(file);
|
|
+
|
|
+ if (a->index >= MAX_EM28XX_INPUT)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return em28xx_fill_audio_input(dev, __func__, a, a->index);
|
|
+}
|
|
+
|
|
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
|
|
+{
|
|
+ struct em28xx *dev = video_drvdata(file);
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < MAX_EM28XX_INPUT; i++)
|
|
+ if (dev->ctl_ainput == dev->amux_map[i])
|
|
+ return em28xx_fill_audio_input(dev, __func__, a, i);
|
|
+
|
|
+ /* Should never happen! */
|
|
+ return -EINVAL;
|
|
+}
|
|
+
|
|
static int vidioc_s_audio(struct file *file, void *priv,
|
|
const struct v4l2_audio *a)
|
|
{
|
|
struct em28xx *dev = video_drvdata(file);
|
|
+ int idx, i;
|
|
|
|
if (a->index >= MAX_EM28XX_INPUT)
|
|
return -EINVAL;
|
|
- if (!INPUT(a->index)->type)
|
|
+
|
|
+ idx = dev->amux_map[a->index];
|
|
+
|
|
+ if (idx == EM28XX_AMUX_UNUSED)
|
|
return -EINVAL;
|
|
|
|
- dev->ctl_ainput = INPUT(a->index)->amux;
|
|
- dev->ctl_aoutput = INPUT(a->index)->aout;
|
|
+ dev->ctl_ainput = idx;
|
|
+
|
|
+ /*
|
|
+ * FIXME: This is wrong, as different inputs at em28xx_cards
|
|
+ * may have different audio outputs. So, the right thing
|
|
+ * to do is to implement VIDIOC_G_AUDOUT/VIDIOC_S_AUDOUT.
|
|
+ * With the current board definitions, this would work fine,
|
|
+ * as, currently, all boards fit.
|
|
+ */
|
|
+ for (i = 0; i < MAX_EM28XX_INPUT; i++)
|
|
+ if (idx == dev->amux_map[i])
|
|
+ break;
|
|
+ if (i == MAX_EM28XX_INPUT)
|
|
+ return -EINVAL;
|
|
+
|
|
+ dev->ctl_aoutput = INPUT(i)->aout;
|
|
|
|
if (!dev->ctl_aoutput)
|
|
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
|
|
|
|
+ em28xx_videodbg("%s: set audio input to %d\n", __func__,
|
|
+ dev->ctl_ainput);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -2302,6 +2371,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
|
|
.vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
|
|
.vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
|
|
.vidioc_enum_framesizes = vidioc_enum_framesizes,
|
|
+ .vidioc_enumaudio = vidioc_enumaudio,
|
|
.vidioc_g_audio = vidioc_g_audio,
|
|
.vidioc_s_audio = vidioc_s_audio,
|
|
|
|
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
|
|
index 953caac025f2..a551072e62ed 100644
|
|
--- a/drivers/media/usb/em28xx/em28xx.h
|
|
+++ b/drivers/media/usb/em28xx/em28xx.h
|
|
@@ -335,6 +335,9 @@ enum em28xx_usb_audio_type {
|
|
/**
|
|
* em28xx_amux - describes the type of audio input used by em28xx
|
|
*
|
|
+ * @EM28XX_AMUX_UNUSED:
|
|
+ * Used only on em28xx dev->map field, in order to mark an entry
|
|
+ * as unused.
|
|
* @EM28XX_AMUX_VIDEO:
|
|
* On devices without AC97, this is the only value that it is currently
|
|
* allowed.
|
|
@@ -369,7 +372,8 @@ enum em28xx_usb_audio_type {
|
|
* same time, via the alsa mux.
|
|
*/
|
|
enum em28xx_amux {
|
|
- EM28XX_AMUX_VIDEO,
|
|
+ EM28XX_AMUX_UNUSED = -1,
|
|
+ EM28XX_AMUX_VIDEO = 0,
|
|
EM28XX_AMUX_LINE_IN,
|
|
|
|
/* Some less-common mixer setups */
|
|
@@ -692,6 +696,8 @@ struct em28xx {
|
|
unsigned int ctl_input; // selected input
|
|
unsigned int ctl_ainput;// selected audio input
|
|
unsigned int ctl_aoutput;// selected audio output
|
|
+ enum em28xx_amux amux_map[MAX_EM28XX_INPUT];
|
|
+
|
|
int mute;
|
|
int volume;
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
index c81faea96fba..c7c600c1f63b 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
@@ -837,9 +837,9 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
|
|
switch (avi->colorimetry) {
|
|
case HDMI_COLORIMETRY_EXTENDED:
|
|
switch (avi->extended_colorimetry) {
|
|
- case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB:
|
|
- c.colorspace = V4L2_COLORSPACE_ADOBERGB;
|
|
- c.xfer_func = V4L2_XFER_FUNC_ADOBERGB;
|
|
+ case HDMI_EXTENDED_COLORIMETRY_OPRGB:
|
|
+ c.colorspace = V4L2_COLORSPACE_OPRGB;
|
|
+ c.xfer_func = V4L2_XFER_FUNC_OPRGB;
|
|
break;
|
|
case HDMI_EXTENDED_COLORIMETRY_BT2020:
|
|
c.colorspace = V4L2_COLORSPACE_BT2020;
|
|
@@ -908,10 +908,10 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
|
|
c.ycbcr_enc = V4L2_YCBCR_ENC_601;
|
|
c.xfer_func = V4L2_XFER_FUNC_SRGB;
|
|
break;
|
|
- case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601:
|
|
- c.colorspace = V4L2_COLORSPACE_ADOBERGB;
|
|
+ case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
|
|
+ c.colorspace = V4L2_COLORSPACE_OPRGB;
|
|
c.ycbcr_enc = V4L2_YCBCR_ENC_601;
|
|
- c.xfer_func = V4L2_XFER_FUNC_ADOBERGB;
|
|
+ c.xfer_func = V4L2_XFER_FUNC_OPRGB;
|
|
break;
|
|
case HDMI_EXTENDED_COLORIMETRY_BT2020:
|
|
c.colorspace = V4L2_COLORSPACE_BT2020;
|
|
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
|
|
index 29b7164a823b..d28ebe7ecd21 100644
|
|
--- a/drivers/mfd/menelaus.c
|
|
+++ b/drivers/mfd/menelaus.c
|
|
@@ -1094,6 +1094,7 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
|
|
static inline void menelaus_rtc_init(struct menelaus_chip *m)
|
|
{
|
|
int alarm = (m->client->irq > 0);
|
|
+ int err;
|
|
|
|
/* assume 32KDETEN pin is pulled high */
|
|
if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
|
|
@@ -1101,6 +1102,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
|
|
return;
|
|
}
|
|
|
|
+ m->rtc = devm_rtc_allocate_device(&m->client->dev);
|
|
+ if (IS_ERR(m->rtc))
|
|
+ return;
|
|
+
|
|
+ m->rtc->ops = &menelaus_rtc_ops;
|
|
+
|
|
/* support RTC alarm; it can issue wakeups */
|
|
if (alarm) {
|
|
if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
|
|
@@ -1125,10 +1132,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
|
|
menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
|
|
}
|
|
|
|
- m->rtc = rtc_device_register(DRIVER_NAME,
|
|
- &m->client->dev,
|
|
- &menelaus_rtc_ops, THIS_MODULE);
|
|
- if (IS_ERR(m->rtc)) {
|
|
+ err = rtc_register_device(m->rtc);
|
|
+ if (err) {
|
|
if (alarm) {
|
|
menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
|
|
device_init_wakeup(&m->client->dev, 0);
|
|
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h
|
|
index 120738d6e58b..77ed3967c5b0 100644
|
|
--- a/drivers/misc/genwqe/card_base.h
|
|
+++ b/drivers/misc/genwqe/card_base.h
|
|
@@ -408,7 +408,7 @@ struct genwqe_file {
|
|
struct file *filp;
|
|
|
|
struct fasync_struct *async_queue;
|
|
- struct task_struct *owner;
|
|
+ struct pid *opener;
|
|
struct list_head list; /* entry in list of open files */
|
|
|
|
spinlock_t map_lock; /* lock for dma_mappings */
|
|
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c
|
|
index f453ab82f0d7..8c1b63a4337b 100644
|
|
--- a/drivers/misc/genwqe/card_dev.c
|
|
+++ b/drivers/misc/genwqe/card_dev.c
|
|
@@ -52,7 +52,7 @@ static void genwqe_add_file(struct genwqe_dev *cd, struct genwqe_file *cfile)
|
|
{
|
|
unsigned long flags;
|
|
|
|
- cfile->owner = current;
|
|
+ cfile->opener = get_pid(task_tgid(current));
|
|
spin_lock_irqsave(&cd->file_lock, flags);
|
|
list_add(&cfile->list, &cd->file_list);
|
|
spin_unlock_irqrestore(&cd->file_lock, flags);
|
|
@@ -65,6 +65,7 @@ static int genwqe_del_file(struct genwqe_dev *cd, struct genwqe_file *cfile)
|
|
spin_lock_irqsave(&cd->file_lock, flags);
|
|
list_del(&cfile->list);
|
|
spin_unlock_irqrestore(&cd->file_lock, flags);
|
|
+ put_pid(cfile->opener);
|
|
|
|
return 0;
|
|
}
|
|
@@ -275,7 +276,7 @@ static int genwqe_kill_fasync(struct genwqe_dev *cd, int sig)
|
|
return files;
|
|
}
|
|
|
|
-static int genwqe_force_sig(struct genwqe_dev *cd, int sig)
|
|
+static int genwqe_terminate(struct genwqe_dev *cd)
|
|
{
|
|
unsigned int files = 0;
|
|
unsigned long flags;
|
|
@@ -283,7 +284,7 @@ static int genwqe_force_sig(struct genwqe_dev *cd, int sig)
|
|
|
|
spin_lock_irqsave(&cd->file_lock, flags);
|
|
list_for_each_entry(cfile, &cd->file_list, list) {
|
|
- force_sig(sig, cfile->owner);
|
|
+ kill_pid(cfile->opener, SIGKILL, 1);
|
|
files++;
|
|
}
|
|
spin_unlock_irqrestore(&cd->file_lock, flags);
|
|
@@ -1352,7 +1353,7 @@ static int genwqe_inform_and_stop_processes(struct genwqe_dev *cd)
|
|
dev_warn(&pci_dev->dev,
|
|
"[%s] send SIGKILL and wait ...\n", __func__);
|
|
|
|
- rc = genwqe_force_sig(cd, SIGKILL); /* force terminate */
|
|
+ rc = genwqe_terminate(cd);
|
|
if (rc) {
|
|
/* Give kill_timout more seconds to end processes */
|
|
for (i = 0; (i < GENWQE_KILL_TIMEOUT) &&
|
|
diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
|
|
index 2e30de9c694a..57a6bb1fd3c9 100644
|
|
--- a/drivers/misc/ocxl/config.c
|
|
+++ b/drivers/misc/ocxl/config.c
|
|
@@ -280,7 +280,9 @@ int ocxl_config_check_afu_index(struct pci_dev *dev,
|
|
u32 val;
|
|
int rc, templ_major, templ_minor, len;
|
|
|
|
- pci_write_config_word(dev, fn->dvsec_afu_info_pos, afu_idx);
|
|
+ pci_write_config_byte(dev,
|
|
+ fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
|
|
+ afu_idx);
|
|
rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val);
|
|
if (rc)
|
|
return rc;
|
|
diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vmci_driver.c
|
|
index d7eaf1eb11e7..003bfba40758 100644
|
|
--- a/drivers/misc/vmw_vmci/vmci_driver.c
|
|
+++ b/drivers/misc/vmw_vmci/vmci_driver.c
|
|
@@ -113,5 +113,5 @@ module_exit(vmci_drv_exit);
|
|
|
|
MODULE_AUTHOR("VMware, Inc.");
|
|
MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface.");
|
|
-MODULE_VERSION("1.1.5.0-k");
|
|
+MODULE_VERSION("1.1.6.0-k");
|
|
MODULE_LICENSE("GPL v2");
|
|
diff --git a/drivers/misc/vmw_vmci/vmci_resource.c b/drivers/misc/vmw_vmci/vmci_resource.c
|
|
index 1ab6e8737a5f..da1ee2e1ba99 100644
|
|
--- a/drivers/misc/vmw_vmci/vmci_resource.c
|
|
+++ b/drivers/misc/vmw_vmci/vmci_resource.c
|
|
@@ -57,7 +57,8 @@ static struct vmci_resource *vmci_resource_lookup(struct vmci_handle handle,
|
|
|
|
if (r->type == type &&
|
|
rid == handle.resource &&
|
|
- (cid == handle.context || cid == VMCI_INVALID_ID)) {
|
|
+ (cid == handle.context || cid == VMCI_INVALID_ID ||
|
|
+ handle.context == VMCI_INVALID_ID)) {
|
|
resource = r;
|
|
break;
|
|
}
|
|
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
|
|
index 32321bd596d8..c61109f7b793 100644
|
|
--- a/drivers/mmc/host/sdhci-acpi.c
|
|
+++ b/drivers/mmc/host/sdhci-acpi.c
|
|
@@ -76,6 +76,7 @@ struct sdhci_acpi_slot {
|
|
size_t priv_size;
|
|
int (*probe_slot)(struct platform_device *, const char *, const char *);
|
|
int (*remove_slot)(struct platform_device *);
|
|
+ int (*free_slot)(struct platform_device *pdev);
|
|
int (*setup_host)(struct platform_device *pdev);
|
|
};
|
|
|
|
@@ -756,6 +757,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
|
err_cleanup:
|
|
sdhci_cleanup_host(c->host);
|
|
err_free:
|
|
+ if (c->slot && c->slot->free_slot)
|
|
+ c->slot->free_slot(pdev);
|
|
+
|
|
sdhci_free_host(c->host);
|
|
return err;
|
|
}
|
|
@@ -777,6 +781,10 @@ static int sdhci_acpi_remove(struct platform_device *pdev)
|
|
|
|
dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0);
|
|
sdhci_remove_host(c->host, dead);
|
|
+
|
|
+ if (c->slot && c->slot->free_slot)
|
|
+ c->slot->free_slot(pdev);
|
|
+
|
|
sdhci_free_host(c->host);
|
|
|
|
return 0;
|
|
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c
|
|
index 77e9bc4aaee9..cc3ffeffd7a2 100644
|
|
--- a/drivers/mmc/host/sdhci-pci-o2micro.c
|
|
+++ b/drivers/mmc/host/sdhci-pci-o2micro.c
|
|
@@ -490,6 +490,9 @@ int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
|
|
pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
|
|
break;
|
|
case PCI_DEVICE_ID_O2_SEABIRD0:
|
|
+ if (chip->pdev->revision == 0x01)
|
|
+ chip->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER;
|
|
+ /* fall through */
|
|
case PCI_DEVICE_ID_O2_SEABIRD1:
|
|
/* UnLock WP */
|
|
ret = pci_read_config_byte(chip->pdev,
|
|
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c
|
|
index 9d9723693217..2e3a8da3ce72 100644
|
|
--- a/drivers/mtd/maps/gpio-addr-flash.c
|
|
+++ b/drivers/mtd/maps/gpio-addr-flash.c
|
|
@@ -238,7 +238,7 @@ static int gpio_flash_probe(struct platform_device *pdev)
|
|
state->map.copy_to = gf_copy_to;
|
|
state->map.bankwidth = pdata->width;
|
|
state->map.size = state->win_size * (1 << state->gpio_count);
|
|
- state->map.virt = ioremap_nocache(memory->start, state->map.size);
|
|
+ state->map.virt = ioremap_nocache(memory->start, state->win_size);
|
|
if (!state->map.virt)
|
|
return -ENOMEM;
|
|
|
|
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
|
|
index a068b214ebaa..a594fb1e9a99 100644
|
|
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
|
|
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
|
|
@@ -2063,6 +2063,10 @@ atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller *nc)
|
|
nand_np = dev->of_node;
|
|
nfc_np = of_find_compatible_node(dev->of_node, NULL,
|
|
"atmel,sama5d3-nfc");
|
|
+ if (!nfc_np) {
|
|
+ dev_err(dev, "Could not find device node for sama5d3-nfc\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
|
|
nc->clk = of_clk_get(nfc_np, 0);
|
|
if (IS_ERR(nc->clk)) {
|
|
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
|
|
index b864b93dd289..2242e999a76b 100644
|
|
--- a/drivers/mtd/nand/raw/denali.c
|
|
+++ b/drivers/mtd/nand/raw/denali.c
|
|
@@ -28,6 +28,7 @@
|
|
MODULE_LICENSE("GPL");
|
|
|
|
#define DENALI_NAND_NAME "denali-nand"
|
|
+#define DENALI_DEFAULT_OOB_SKIP_BYTES 8
|
|
|
|
/* for Indexed Addressing */
|
|
#define DENALI_INDEXED_CTRL 0x00
|
|
@@ -1105,12 +1106,17 @@ static void denali_hw_init(struct denali_nand_info *denali)
|
|
denali->revision = swab16(ioread32(denali->reg + REVISION));
|
|
|
|
/*
|
|
- * tell driver how many bit controller will skip before
|
|
- * writing ECC code in OOB, this register may be already
|
|
- * set by firmware. So we read this value out.
|
|
- * if this value is 0, just let it be.
|
|
+ * Set how many bytes should be skipped before writing data in OOB.
|
|
+ * If a non-zero value has already been set (by firmware or something),
|
|
+ * just use it. Otherwise, set the driver default.
|
|
*/
|
|
denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES);
|
|
+ if (!denali->oob_skip_bytes) {
|
|
+ denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES;
|
|
+ iowrite32(denali->oob_skip_bytes,
|
|
+ denali->reg + SPARE_AREA_SKIP_BYTES);
|
|
+ }
|
|
+
|
|
denali_detect_max_banks(denali);
|
|
iowrite32(0x0F, denali->reg + RB_PIN_ENABLED);
|
|
iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
|
|
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
|
|
index bc2ef5209783..c7573ccdbacd 100644
|
|
--- a/drivers/mtd/nand/raw/marvell_nand.c
|
|
+++ b/drivers/mtd/nand/raw/marvell_nand.c
|
|
@@ -686,7 +686,7 @@ static irqreturn_t marvell_nfc_isr(int irq, void *dev_id)
|
|
|
|
marvell_nfc_disable_int(nfc, st & NDCR_ALL_INT);
|
|
|
|
- if (!(st & (NDSR_RDDREQ | NDSR_WRDREQ | NDSR_WRCMDREQ)))
|
|
+ if (st & (NDSR_RDY(0) | NDSR_RDY(1)))
|
|
complete(&nfc->complete);
|
|
|
|
return IRQ_HANDLED;
|
|
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
|
|
index 7d9620c7ff6c..1ff3430f82c8 100644
|
|
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
|
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
|
@@ -478,6 +478,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
|
|
{
|
|
switch (cmd) {
|
|
case SPINOR_OP_READ_1_1_4:
|
|
+ case SPINOR_OP_READ_1_1_4_4B:
|
|
return SEQID_READ;
|
|
case SPINOR_OP_WREN:
|
|
return SEQID_WREN;
|
|
@@ -543,6 +544,9 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
|
|
|
|
/* trigger the LUT now */
|
|
seqid = fsl_qspi_get_seqid(q, cmd);
|
|
+ if (seqid < 0)
|
|
+ return seqid;
|
|
+
|
|
qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
|
|
base + QUADSPI_IPCR);
|
|
|
|
@@ -671,7 +675,7 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
|
|
* causes the controller to clear the buffer, and use the sequence pointed
|
|
* by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
|
|
*/
|
|
-static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
|
|
+static int fsl_qspi_init_ahb_read(struct fsl_qspi *q)
|
|
{
|
|
void __iomem *base = q->iobase;
|
|
int seqid;
|
|
@@ -696,8 +700,13 @@ static void fsl_qspi_init_ahb_read(struct fsl_qspi *q)
|
|
|
|
/* Set the default lut sequence for AHB Read. */
|
|
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
|
|
+ if (seqid < 0)
|
|
+ return seqid;
|
|
+
|
|
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
|
|
q->iobase + QUADSPI_BFGENCR);
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
/* This function was used to prepare and enable QSPI clock */
|
|
@@ -805,9 +814,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
|
|
fsl_qspi_init_lut(q);
|
|
|
|
/* Init for AHB read */
|
|
- fsl_qspi_init_ahb_read(q);
|
|
-
|
|
- return 0;
|
|
+ return fsl_qspi_init_ahb_read(q);
|
|
}
|
|
|
|
static const struct of_device_id fsl_qspi_dt_ids[] = {
|
|
diff --git a/drivers/mtd/spi-nor/intel-spi-pci.c b/drivers/mtd/spi-nor/intel-spi-pci.c
|
|
index c0976f2e3dd1..872b40922608 100644
|
|
--- a/drivers/mtd/spi-nor/intel-spi-pci.c
|
|
+++ b/drivers/mtd/spi-nor/intel-spi-pci.c
|
|
@@ -65,6 +65,7 @@ static void intel_spi_pci_remove(struct pci_dev *pdev)
|
|
static const struct pci_device_id intel_spi_pci_ids[] = {
|
|
{ PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info },
|
|
{ PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
|
|
+ { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },
|
|
{ PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info },
|
|
{ PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info },
|
|
{ },
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/phy.c b/drivers/net/dsa/mv88e6xxx/phy.c
|
|
index 46af8052e535..152a65d46e0b 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/phy.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/phy.c
|
|
@@ -110,6 +110,9 @@ int mv88e6xxx_phy_page_write(struct mv88e6xxx_chip *chip, int phy,
|
|
err = mv88e6xxx_phy_page_get(chip, phy, page);
|
|
if (!err) {
|
|
err = mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_PAGE, page);
|
|
+ if (!err)
|
|
+ err = mv88e6xxx_phy_write(chip, phy, reg, val);
|
|
+
|
|
mv88e6xxx_phy_page_put(chip, phy);
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
|
|
index 34af5f1569c8..de0e24d912fe 100644
|
|
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
|
|
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
|
|
@@ -342,7 +342,7 @@ static struct device_node *bcmgenet_mii_of_find_mdio(struct bcmgenet_priv *priv)
|
|
if (!compat)
|
|
return NULL;
|
|
|
|
- priv->mdio_dn = of_find_compatible_node(dn, NULL, compat);
|
|
+ priv->mdio_dn = of_get_compatible_child(dn, compat);
|
|
kfree(compat);
|
|
if (!priv->mdio_dn) {
|
|
dev_err(kdev, "unable to find MDIO bus node\n");
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
index 955c4ab18b03..b7b2f8254ce1 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
@@ -1915,6 +1915,7 @@ static int is_valid_clean_head(struct hns3_enet_ring *ring, int h)
|
|
bool hns3_clean_tx_ring(struct hns3_enet_ring *ring, int budget)
|
|
{
|
|
struct net_device *netdev = ring->tqp->handle->kinfo.netdev;
|
|
+ struct hns3_nic_priv *priv = netdev_priv(netdev);
|
|
struct netdev_queue *dev_queue;
|
|
int bytes, pkts;
|
|
int head;
|
|
@@ -1961,7 +1962,8 @@ bool hns3_clean_tx_ring(struct hns3_enet_ring *ring, int budget)
|
|
* sees the new next_to_clean.
|
|
*/
|
|
smp_mb();
|
|
- if (netif_tx_queue_stopped(dev_queue)) {
|
|
+ if (netif_tx_queue_stopped(dev_queue) &&
|
|
+ !test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) {
|
|
netif_tx_wake_queue(dev_queue);
|
|
ring->stats.restart_queue++;
|
|
}
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
index f70ee6910ee2..9684ad015c42 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
@@ -309,7 +309,7 @@ static void hns3_self_test(struct net_device *ndev,
|
|
h->flags & HNAE3_SUPPORT_SERDES_LOOPBACK;
|
|
|
|
if (if_running)
|
|
- dev_close(ndev);
|
|
+ ndev->netdev_ops->ndo_stop(ndev);
|
|
|
|
#if IS_ENABLED(CONFIG_VLAN_8021Q)
|
|
/* Disable the vlan filter for selftest does not support it */
|
|
@@ -347,7 +347,7 @@ static void hns3_self_test(struct net_device *ndev,
|
|
#endif
|
|
|
|
if (if_running)
|
|
- dev_open(ndev);
|
|
+ ndev->netdev_ops->ndo_open(ndev);
|
|
}
|
|
|
|
static int hns3_get_sset_count(struct net_device *netdev, int stringset)
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
|
|
index f08ebb7caaaf..92f19384e258 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
|
|
@@ -73,6 +73,7 @@ static int hclge_ieee_getets(struct hnae3_handle *h, struct ieee_ets *ets)
|
|
static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
|
|
u8 *tc, bool *changed)
|
|
{
|
|
+ bool has_ets_tc = false;
|
|
u32 total_ets_bw = 0;
|
|
u8 max_tc = 0;
|
|
u8 i;
|
|
@@ -100,13 +101,14 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
|
|
*changed = true;
|
|
|
|
total_ets_bw += ets->tc_tx_bw[i];
|
|
- break;
|
|
+ has_ets_tc = true;
|
|
+ break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
- if (total_ets_bw != BW_PERCENT)
|
|
+ if (has_ets_tc && total_ets_bw != BW_PERCENT)
|
|
return -EINVAL;
|
|
|
|
*tc = max_tc + 1;
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
index 8577dfc799ad..db763450e5e3 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
@@ -1657,11 +1657,13 @@ static int hclge_tx_buffer_calc(struct hclge_dev *hdev,
|
|
static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
|
struct hclge_pkt_buf_alloc *buf_alloc)
|
|
{
|
|
- u32 rx_all = hdev->pkt_buf_size;
|
|
+#define HCLGE_BUF_SIZE_UNIT 128
|
|
+ u32 rx_all = hdev->pkt_buf_size, aligned_mps;
|
|
int no_pfc_priv_num, pfc_priv_num;
|
|
struct hclge_priv_buf *priv;
|
|
int i;
|
|
|
|
+ aligned_mps = round_up(hdev->mps, HCLGE_BUF_SIZE_UNIT);
|
|
rx_all -= hclge_get_tx_buff_alloced(buf_alloc);
|
|
|
|
/* When DCB is not supported, rx private
|
|
@@ -1680,13 +1682,13 @@ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
|
if (hdev->hw_tc_map & BIT(i)) {
|
|
priv->enable = 1;
|
|
if (hdev->tm_info.hw_pfc_map & BIT(i)) {
|
|
- priv->wl.low = hdev->mps;
|
|
- priv->wl.high = priv->wl.low + hdev->mps;
|
|
+ priv->wl.low = aligned_mps;
|
|
+ priv->wl.high = priv->wl.low + aligned_mps;
|
|
priv->buf_size = priv->wl.high +
|
|
HCLGE_DEFAULT_DV;
|
|
} else {
|
|
priv->wl.low = 0;
|
|
- priv->wl.high = 2 * hdev->mps;
|
|
+ priv->wl.high = 2 * aligned_mps;
|
|
priv->buf_size = priv->wl.high;
|
|
}
|
|
} else {
|
|
@@ -1718,11 +1720,11 @@ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
|
|
|
if (hdev->tm_info.hw_pfc_map & BIT(i)) {
|
|
priv->wl.low = 128;
|
|
- priv->wl.high = priv->wl.low + hdev->mps;
|
|
+ priv->wl.high = priv->wl.low + aligned_mps;
|
|
priv->buf_size = priv->wl.high + HCLGE_DEFAULT_DV;
|
|
} else {
|
|
priv->wl.low = 0;
|
|
- priv->wl.high = hdev->mps;
|
|
+ priv->wl.high = aligned_mps;
|
|
priv->buf_size = priv->wl.high;
|
|
}
|
|
}
|
|
@@ -2360,6 +2362,9 @@ static int hclge_get_mac_phy_link(struct hclge_dev *hdev)
|
|
int mac_state;
|
|
int link_stat;
|
|
|
|
+ if (test_bit(HCLGE_STATE_DOWN, &hdev->state))
|
|
+ return 0;
|
|
+
|
|
mac_state = hclge_get_mac_link_status(hdev);
|
|
|
|
if (hdev->hw.mac.phydev) {
|
|
@@ -3809,6 +3814,8 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
|
|
struct hclge_dev *hdev = vport->back;
|
|
int i;
|
|
|
|
+ set_bit(HCLGE_STATE_DOWN, &hdev->state);
|
|
+
|
|
del_timer_sync(&hdev->service_timer);
|
|
cancel_work_sync(&hdev->service_task);
|
|
clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
|
|
@@ -4686,9 +4693,17 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
|
|
"Add vf vlan filter fail, ret =%d.\n",
|
|
req0->resp_code);
|
|
} else {
|
|
+#define HCLGE_VF_VLAN_DEL_NO_FOUND 1
|
|
if (!req0->resp_code)
|
|
return 0;
|
|
|
|
+ if (req0->resp_code == HCLGE_VF_VLAN_DEL_NO_FOUND) {
|
|
+ dev_warn(&hdev->pdev->dev,
|
|
+ "vlan %d filter is not in vf vlan table\n",
|
|
+ vlan);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
dev_err(&hdev->pdev->dev,
|
|
"Kill vf vlan filter fail, ret =%d.\n",
|
|
req0->resp_code);
|
|
@@ -4732,6 +4747,9 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
|
|
u16 vport_idx, vport_num = 0;
|
|
int ret;
|
|
|
|
+ if (is_kill && !vlan_id)
|
|
+ return 0;
|
|
+
|
|
ret = hclge_set_vf_vlan_common(hdev, vport_id, is_kill, vlan_id,
|
|
0, proto);
|
|
if (ret) {
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
|
|
index 9c0091f2addf..320043e87fc6 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
|
|
@@ -299,6 +299,9 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state)
|
|
|
|
client = handle->client;
|
|
|
|
+ link_state =
|
|
+ test_bit(HCLGEVF_STATE_DOWN, &hdev->state) ? 0 : link_state;
|
|
+
|
|
if (link_state != hdev->hw.mac.link) {
|
|
client->ops->link_status_change(handle, !!link_state);
|
|
hdev->hw.mac.link = link_state;
|
|
@@ -1448,6 +1451,8 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle)
|
|
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
|
int i, queue_id;
|
|
|
|
+ set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
|
|
+
|
|
for (i = 0; i < hdev->num_tqps; i++) {
|
|
/* Ring disable */
|
|
queue_id = hclgevf_get_queue_id(handle->kinfo.tqp[i]);
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
|
index 868f4a1d0f72..67591722c625 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice.h
|
|
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
|
@@ -39,9 +39,9 @@
|
|
extern const char ice_drv_ver[];
|
|
#define ICE_BAR0 0
|
|
#define ICE_DFLT_NUM_DESC 128
|
|
-#define ICE_MIN_NUM_DESC 8
|
|
-#define ICE_MAX_NUM_DESC 8160
|
|
#define ICE_REQ_DESC_MULTIPLE 32
|
|
+#define ICE_MIN_NUM_DESC ICE_REQ_DESC_MULTIPLE
|
|
+#define ICE_MAX_NUM_DESC 8160
|
|
#define ICE_DFLT_TRAFFIC_CLASS BIT(0)
|
|
#define ICE_INT_NAME_STR_LEN (IFNAMSIZ + 16)
|
|
#define ICE_ETHTOOL_FWVER_LEN 32
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c
|
|
index 62be72fdc8f3..e783976c401d 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice_controlq.c
|
|
+++ b/drivers/net/ethernet/intel/ice/ice_controlq.c
|
|
@@ -518,22 +518,31 @@ shutdown_sq_out:
|
|
|
|
/**
|
|
* ice_aq_ver_check - Check the reported AQ API version.
|
|
- * @fw_branch: The "branch" of FW, typically describes the device type
|
|
- * @fw_major: The major version of the FW API
|
|
- * @fw_minor: The minor version increment of the FW API
|
|
+ * @hw: pointer to the hardware structure
|
|
*
|
|
* Checks if the driver should load on a given AQ API version.
|
|
*
|
|
* Return: 'true' iff the driver should attempt to load. 'false' otherwise.
|
|
*/
|
|
-static bool ice_aq_ver_check(u8 fw_branch, u8 fw_major, u8 fw_minor)
|
|
+static bool ice_aq_ver_check(struct ice_hw *hw)
|
|
{
|
|
- if (fw_branch != EXP_FW_API_VER_BRANCH)
|
|
- return false;
|
|
- if (fw_major != EXP_FW_API_VER_MAJOR)
|
|
- return false;
|
|
- if (fw_minor != EXP_FW_API_VER_MINOR)
|
|
+ if (hw->api_maj_ver > EXP_FW_API_VER_MAJOR) {
|
|
+ /* Major API version is newer than expected, don't load */
|
|
+ dev_warn(ice_hw_to_dev(hw),
|
|
+ "The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n");
|
|
return false;
|
|
+ } else if (hw->api_maj_ver == EXP_FW_API_VER_MAJOR) {
|
|
+ if (hw->api_min_ver > (EXP_FW_API_VER_MINOR + 2))
|
|
+ dev_info(ice_hw_to_dev(hw),
|
|
+ "The driver for the device detected a newer version of the NVM image than expected. Please install the most recent version of the network driver.\n");
|
|
+ else if ((hw->api_min_ver + 2) < EXP_FW_API_VER_MINOR)
|
|
+ dev_info(ice_hw_to_dev(hw),
|
|
+ "The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
|
|
+ } else {
|
|
+ /* Major API version is older than expected, log a warning */
|
|
+ dev_info(ice_hw_to_dev(hw),
|
|
+ "The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
|
|
+ }
|
|
return true;
|
|
}
|
|
|
|
@@ -588,8 +597,7 @@ static enum ice_status ice_init_check_adminq(struct ice_hw *hw)
|
|
if (status)
|
|
goto init_ctrlq_free_rq;
|
|
|
|
- if (!ice_aq_ver_check(hw->api_branch, hw->api_maj_ver,
|
|
- hw->api_min_ver)) {
|
|
+ if (!ice_aq_ver_check(hw)) {
|
|
status = ICE_ERR_FW_API_VER;
|
|
goto init_ctrlq_free_rq;
|
|
}
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
|
index c71a9b528d6d..9d6754f65a1a 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
|
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
|
@@ -478,9 +478,11 @@ ice_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
|
|
ring->tx_max_pending = ICE_MAX_NUM_DESC;
|
|
ring->rx_pending = vsi->rx_rings[0]->count;
|
|
ring->tx_pending = vsi->tx_rings[0]->count;
|
|
- ring->rx_mini_pending = ICE_MIN_NUM_DESC;
|
|
+
|
|
+ /* Rx mini and jumbo rings are not supported */
|
|
ring->rx_mini_max_pending = 0;
|
|
ring->rx_jumbo_max_pending = 0;
|
|
+ ring->rx_mini_pending = 0;
|
|
ring->rx_jumbo_pending = 0;
|
|
}
|
|
|
|
@@ -498,14 +500,23 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
|
|
ring->tx_pending < ICE_MIN_NUM_DESC ||
|
|
ring->rx_pending > ICE_MAX_NUM_DESC ||
|
|
ring->rx_pending < ICE_MIN_NUM_DESC) {
|
|
- netdev_err(netdev, "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n",
|
|
+ netdev_err(netdev, "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d] (increment %d)\n",
|
|
ring->tx_pending, ring->rx_pending,
|
|
- ICE_MIN_NUM_DESC, ICE_MAX_NUM_DESC);
|
|
+ ICE_MIN_NUM_DESC, ICE_MAX_NUM_DESC,
|
|
+ ICE_REQ_DESC_MULTIPLE);
|
|
return -EINVAL;
|
|
}
|
|
|
|
new_tx_cnt = ALIGN(ring->tx_pending, ICE_REQ_DESC_MULTIPLE);
|
|
+ if (new_tx_cnt != ring->tx_pending)
|
|
+ netdev_info(netdev,
|
|
+ "Requested Tx descriptor count rounded up to %d\n",
|
|
+ new_tx_cnt);
|
|
new_rx_cnt = ALIGN(ring->rx_pending, ICE_REQ_DESC_MULTIPLE);
|
|
+ if (new_rx_cnt != ring->rx_pending)
|
|
+ netdev_info(netdev,
|
|
+ "Requested Rx descriptor count rounded up to %d\n",
|
|
+ new_rx_cnt);
|
|
|
|
/* if nothing to do return success */
|
|
if (new_tx_cnt == vsi->tx_rings[0]->count &&
|
|
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
|
|
index da4322e4daed..add124e0381d 100644
|
|
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
|
|
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
|
|
@@ -676,6 +676,9 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
|
|
} else {
|
|
struct tx_sa tsa;
|
|
|
|
+ if (adapter->num_vfs)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
/* find the first unused index */
|
|
ret = ixgbe_ipsec_find_empty_idx(ipsec, false);
|
|
if (ret < 0) {
|
|
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
|
|
index 5a228582423b..4093a9c52c18 100644
|
|
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
|
|
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
|
|
@@ -3849,6 +3849,10 @@ static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
|
|
skb_checksum_help(skb);
|
|
goto no_csum;
|
|
}
|
|
+
|
|
+ if (first->protocol == htons(ETH_P_IP))
|
|
+ type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
|
|
+
|
|
/* update TX checksum flag */
|
|
first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
|
|
vlan_macip_lens = skb_checksum_start_offset(skb) -
|
|
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
|
|
index db463e20a876..e9a4179e7e48 100644
|
|
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
|
|
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
|
|
@@ -96,6 +96,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
|
|
{
|
|
struct nfp_pf *pf = devlink_priv(devlink);
|
|
struct nfp_eth_table_port eth_port;
|
|
+ unsigned int lanes;
|
|
int ret;
|
|
|
|
if (count < 2)
|
|
@@ -114,8 +115,12 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
|
|
goto out;
|
|
}
|
|
|
|
- ret = nfp_devlink_set_lanes(pf, eth_port.index,
|
|
- eth_port.port_lanes / count);
|
|
+ /* Special case the 100G CXP -> 2x40G split */
|
|
+ lanes = eth_port.port_lanes / count;
|
|
+ if (eth_port.lanes == 10 && count == 2)
|
|
+ lanes = 8 / count;
|
|
+
|
|
+ ret = nfp_devlink_set_lanes(pf, eth_port.index, lanes);
|
|
out:
|
|
mutex_unlock(&pf->lock);
|
|
|
|
@@ -128,6 +133,7 @@ nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
|
|
{
|
|
struct nfp_pf *pf = devlink_priv(devlink);
|
|
struct nfp_eth_table_port eth_port;
|
|
+ unsigned int lanes;
|
|
int ret;
|
|
|
|
mutex_lock(&pf->lock);
|
|
@@ -143,7 +149,12 @@ nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
|
|
goto out;
|
|
}
|
|
|
|
- ret = nfp_devlink_set_lanes(pf, eth_port.index, eth_port.port_lanes);
|
|
+ /* Special case the 100G CXP -> 2x40G unsplit */
|
|
+ lanes = eth_port.port_lanes;
|
|
+ if (eth_port.port_lanes == 8)
|
|
+ lanes = 10;
|
|
+
|
|
+ ret = nfp_devlink_set_lanes(pf, eth_port.index, lanes);
|
|
out:
|
|
mutex_unlock(&pf->lock);
|
|
|
|
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
|
|
index 4289ccb26e4e..d2caeb9edc04 100644
|
|
--- a/drivers/net/ethernet/socionext/netsec.c
|
|
+++ b/drivers/net/ethernet/socionext/netsec.c
|
|
@@ -940,6 +940,9 @@ static void netsec_uninit_pkt_dring(struct netsec_priv *priv, int id)
|
|
dring->head = 0;
|
|
dring->tail = 0;
|
|
dring->pkt_cnt = 0;
|
|
+
|
|
+ if (id == NETSEC_RING_TX)
|
|
+ netdev_reset_queue(priv->ndev);
|
|
}
|
|
|
|
static void netsec_free_dring(struct netsec_priv *priv, int id)
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
|
index f9a61f90cfbc..0f660af01a4b 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
|
|
@@ -714,8 +714,9 @@ static int get_ephy_nodes(struct stmmac_priv *priv)
|
|
return -ENODEV;
|
|
}
|
|
|
|
- mdio_internal = of_find_compatible_node(mdio_mux, NULL,
|
|
+ mdio_internal = of_get_compatible_child(mdio_mux,
|
|
"allwinner,sun8i-h3-mdio-internal");
|
|
+ of_node_put(mdio_mux);
|
|
if (!mdio_internal) {
|
|
dev_err(priv->device, "Cannot get internal_mdio node\n");
|
|
return -ENODEV;
|
|
@@ -729,13 +730,20 @@ static int get_ephy_nodes(struct stmmac_priv *priv)
|
|
gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL);
|
|
if (IS_ERR(gmac->rst_ephy)) {
|
|
ret = PTR_ERR(gmac->rst_ephy);
|
|
- if (ret == -EPROBE_DEFER)
|
|
+ if (ret == -EPROBE_DEFER) {
|
|
+ of_node_put(iphynode);
|
|
+ of_node_put(mdio_internal);
|
|
return ret;
|
|
+ }
|
|
continue;
|
|
}
|
|
dev_info(priv->device, "Found internal PHY node\n");
|
|
+ of_node_put(iphynode);
|
|
+ of_node_put(mdio_internal);
|
|
return 0;
|
|
}
|
|
+
|
|
+ of_node_put(mdio_internal);
|
|
return -ENODEV;
|
|
}
|
|
|
|
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
|
|
index 3af6d8d15233..1c37a821895b 100644
|
|
--- a/drivers/net/hyperv/netvsc_drv.c
|
|
+++ b/drivers/net/hyperv/netvsc_drv.c
|
|
@@ -2022,14 +2022,15 @@ static void netvsc_vf_setup(struct work_struct *w)
|
|
rtnl_unlock();
|
|
}
|
|
|
|
-/* Find netvsc by VMBus serial number.
|
|
- * The PCI hyperv controller records the serial number as the slot.
|
|
+/* Find netvsc by VF serial number.
|
|
+ * The PCI hyperv controller records the serial number as the slot kobj name.
|
|
*/
|
|
static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
|
|
{
|
|
struct device *parent = vf_netdev->dev.parent;
|
|
struct net_device_context *ndev_ctx;
|
|
struct pci_dev *pdev;
|
|
+ u32 serial;
|
|
|
|
if (!parent || !dev_is_pci(parent))
|
|
return NULL; /* not a PCI device */
|
|
@@ -2040,16 +2041,22 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
|
|
return NULL;
|
|
}
|
|
|
|
+ if (kstrtou32(pci_slot_name(pdev->slot), 10, &serial)) {
|
|
+ netdev_notice(vf_netdev, "Invalid vf serial:%s\n",
|
|
+ pci_slot_name(pdev->slot));
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
|
|
if (!ndev_ctx->vf_alloc)
|
|
continue;
|
|
|
|
- if (ndev_ctx->vf_serial == pdev->slot->number)
|
|
+ if (ndev_ctx->vf_serial == serial)
|
|
return hv_get_drvdata(ndev_ctx->device_ctx);
|
|
}
|
|
|
|
netdev_notice(vf_netdev,
|
|
- "no netdev found for slot %u\n", pdev->slot->number);
|
|
+ "no netdev found for vf serial:%u\n", serial);
|
|
return NULL;
|
|
}
|
|
|
|
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
|
|
index 30612497643c..d192936b76cf 100644
|
|
--- a/drivers/net/loopback.c
|
|
+++ b/drivers/net/loopback.c
|
|
@@ -75,6 +75,10 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
|
|
int len;
|
|
|
|
skb_tx_timestamp(skb);
|
|
+
|
|
+ /* do not fool net_timestamp_check() with various clock bases */
|
|
+ skb->tstamp = 0;
|
|
+
|
|
skb_orphan(skb);
|
|
|
|
/* Before queueing this packet to netif_rx(),
|
|
diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c
|
|
index 7ae1856d1f18..5a749dc25bec 100644
|
|
--- a/drivers/net/net_failover.c
|
|
+++ b/drivers/net/net_failover.c
|
|
@@ -603,6 +603,9 @@ static int net_failover_slave_unregister(struct net_device *slave_dev,
|
|
primary_dev = rtnl_dereference(nfo_info->primary_dev);
|
|
standby_dev = rtnl_dereference(nfo_info->standby_dev);
|
|
|
|
+ if (WARN_ON_ONCE(slave_dev != primary_dev && slave_dev != standby_dev))
|
|
+ return -ENODEV;
|
|
+
|
|
vlan_vids_del_by_dev(slave_dev, failover_dev);
|
|
dev_uc_unsync(slave_dev, failover_dev);
|
|
dev_mc_unsync(slave_dev, failover_dev);
|
|
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
|
|
index 7abca86c3aa9..70f3f90c2ed6 100644
|
|
--- a/drivers/net/phy/phylink.c
|
|
+++ b/drivers/net/phy/phylink.c
|
|
@@ -907,6 +907,9 @@ void phylink_start(struct phylink *pl)
|
|
phylink_an_mode_str(pl->link_an_mode),
|
|
phy_modes(pl->link_config.interface));
|
|
|
|
+ /* Always set the carrier off */
|
|
+ netif_carrier_off(pl->netdev);
|
|
+
|
|
/* Apply the link configuration to the MAC when starting. This allows
|
|
* a fixed-link to start with the correct parameters, and also
|
|
* ensures that we set the appropriate advertisement for Serdes links.
|
|
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
|
|
index 50e9cc19023a..c52207beef88 100644
|
|
--- a/drivers/net/tun.c
|
|
+++ b/drivers/net/tun.c
|
|
@@ -2264,6 +2264,8 @@ static void tun_setup(struct net_device *dev)
|
|
static int tun_validate(struct nlattr *tb[], struct nlattr *data[],
|
|
struct netlink_ext_ack *extack)
|
|
{
|
|
+ if (!data)
|
|
+ return 0;
|
|
return -EINVAL;
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
|
|
index fd612d2905b0..9f31b9a10850 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
|
@@ -1869,6 +1869,12 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
|
|
if (ret)
|
|
dev_kfree_skb_any(skb);
|
|
|
|
+ if (ret == -EAGAIN) {
|
|
+ ath10k_warn(ar, "wmi command %d timeout, restarting hardware\n",
|
|
+ cmd_id);
|
|
+ queue_work(ar->workqueue, &ar->restart_work);
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
@@ -2336,7 +2342,12 @@ static int wmi_process_mgmt_tx_comp(struct ath10k *ar, u32 desc_id,
|
|
dma_unmap_single(ar->dev, pkt_addr->paddr,
|
|
msdu->len, DMA_FROM_DEVICE);
|
|
info = IEEE80211_SKB_CB(msdu);
|
|
- info->flags |= status;
|
|
+
|
|
+ if (status)
|
|
+ info->flags &= ~IEEE80211_TX_STAT_ACK;
|
|
+ else
|
|
+ info->flags |= IEEE80211_TX_STAT_ACK;
|
|
+
|
|
ieee80211_tx_status_irqsafe(ar->hw, msdu);
|
|
|
|
ret = 0;
|
|
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
|
|
index bca61cb44c37..3e7fc2983cbb 100644
|
|
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
|
|
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
|
|
@@ -279,9 +279,6 @@ static void wil_move_all_rx_buff_to_free_list(struct wil6210_priv *wil,
|
|
u16 buff_id;
|
|
|
|
*d = *_d;
|
|
- pa = wil_rx_desc_get_addr_edma(&d->dma);
|
|
- dmalen = le16_to_cpu(d->dma.length);
|
|
- dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE);
|
|
|
|
/* Extract the SKB from the rx_buff management array */
|
|
buff_id = __le16_to_cpu(d->mac.buff_id);
|
|
@@ -291,10 +288,15 @@ static void wil_move_all_rx_buff_to_free_list(struct wil6210_priv *wil,
|
|
}
|
|
skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb;
|
|
wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL;
|
|
- if (unlikely(!skb))
|
|
+ if (unlikely(!skb)) {
|
|
wil_err(wil, "No Rx skb at buff_id %d\n", buff_id);
|
|
- else
|
|
+ } else {
|
|
+ pa = wil_rx_desc_get_addr_edma(&d->dma);
|
|
+ dmalen = le16_to_cpu(d->dma.length);
|
|
+ dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE);
|
|
+
|
|
kfree_skb(skb);
|
|
+ }
|
|
|
|
/* Move the buffer from the active to the free list */
|
|
list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list,
|
|
@@ -906,6 +908,9 @@ again:
|
|
wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL;
|
|
if (!skb) {
|
|
wil_err(wil, "No Rx skb at buff_id %d\n", buff_id);
|
|
+ /* Move the buffer from the active list to the free list */
|
|
+ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list,
|
|
+ &wil->rx_buff_mgmt.free);
|
|
goto again;
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
|
|
index d8b79cb72b58..e7584b842dce 100644
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
|
|
@@ -77,6 +77,8 @@ static u16 d11ac_bw(enum brcmu_chan_bw bw)
|
|
return BRCMU_CHSPEC_D11AC_BW_40;
|
|
case BRCMU_CHAN_BW_80:
|
|
return BRCMU_CHSPEC_D11AC_BW_80;
|
|
+ case BRCMU_CHAN_BW_160:
|
|
+ return BRCMU_CHSPEC_D11AC_BW_160;
|
|
default:
|
|
WARN_ON(1);
|
|
}
|
|
@@ -190,8 +192,38 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
|
break;
|
|
}
|
|
break;
|
|
- case BRCMU_CHSPEC_D11AC_BW_8080:
|
|
case BRCMU_CHSPEC_D11AC_BW_160:
|
|
+ switch (ch->sb) {
|
|
+ case BRCMU_CHAN_SB_LLL:
|
|
+ ch->control_ch_num -= CH_70MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_LLU:
|
|
+ ch->control_ch_num -= CH_50MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_LUL:
|
|
+ ch->control_ch_num -= CH_30MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_LUU:
|
|
+ ch->control_ch_num -= CH_10MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_ULL:
|
|
+ ch->control_ch_num += CH_10MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_ULU:
|
|
+ ch->control_ch_num += CH_30MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_UUL:
|
|
+ ch->control_ch_num += CH_50MHZ_APART;
|
|
+ break;
|
|
+ case BRCMU_CHAN_SB_UUU:
|
|
+ ch->control_ch_num += CH_70MHZ_APART;
|
|
+ break;
|
|
+ default:
|
|
+ WARN_ON_ONCE(1);
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ case BRCMU_CHSPEC_D11AC_BW_8080:
|
|
default:
|
|
WARN_ON_ONCE(1);
|
|
break;
|
|
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
|
|
index 7b9a77981df1..75b2a0438cfa 100644
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
|
|
@@ -29,6 +29,8 @@
|
|
#define CH_UPPER_SB 0x01
|
|
#define CH_LOWER_SB 0x02
|
|
#define CH_EWA_VALID 0x04
|
|
+#define CH_70MHZ_APART 14
|
|
+#define CH_50MHZ_APART 10
|
|
#define CH_30MHZ_APART 6
|
|
#define CH_20MHZ_APART 4
|
|
#define CH_10MHZ_APART 2
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
|
|
index 6bb1a99a197a..48a3611d6a31 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
|
|
@@ -704,8 +704,12 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)
|
|
enabled = !!(wifi_pkg->package.elements[1].integer.value);
|
|
n_profiles = wifi_pkg->package.elements[2].integer.value;
|
|
|
|
- /* in case of BIOS bug */
|
|
- if (n_profiles <= 0) {
|
|
+ /*
|
|
+ * Check the validity of n_profiles. The EWRD profiles start
|
|
+ * from index 1, so the maximum value allowed here is
|
|
+ * ACPI_SAR_PROFILES_NUM - 1.
|
|
+ */
|
|
+ if (n_profiles <= 0 || n_profiles >= ACPI_SAR_PROFILE_NUM) {
|
|
ret = -EINVAL;
|
|
goto out_free;
|
|
}
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
|
index b15b0d84bb7e..155cc2ac0120 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
|
@@ -1233,12 +1233,15 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
|
|
iwl_mvm_del_aux_sta(mvm);
|
|
|
|
/*
|
|
- * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete()
|
|
- * won't be called in this case).
|
|
+ * Clear IN_HW_RESTART and HW_RESTART_REQUESTED flag when stopping the
|
|
+ * hw (as restart_complete() won't be called in this case) and mac80211
|
|
+ * won't execute the restart.
|
|
* But make sure to cleanup interfaces that have gone down before/during
|
|
* HW restart was requested.
|
|
*/
|
|
- if (test_and_clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
|
+ if (test_and_clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
|
|
+ test_and_clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
|
|
+ &mvm->status))
|
|
ieee80211_iterate_interfaces(mvm->hw, 0,
|
|
iwl_mvm_cleanup_iterator, mvm);
|
|
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
|
|
index 30cfd7d50bc9..f2830b5693d2 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
|
|
@@ -1239,7 +1239,11 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|
!(info->flags & IEEE80211_TX_STAT_AMPDU))
|
|
return;
|
|
|
|
- rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate);
|
|
+ if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
|
|
+ &tx_resp_rate)) {
|
|
+ WARN_ON_ONCE(1);
|
|
+ return;
|
|
+ }
|
|
|
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
|
/* Disable last tx check if we are debugging with fixed rate but
|
|
@@ -1290,7 +1294,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|
*/
|
|
table = &lq_sta->lq;
|
|
lq_hwrate = le32_to_cpu(table->rs_table[0]);
|
|
- rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
|
|
+ if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {
|
|
+ WARN_ON_ONCE(1);
|
|
+ return;
|
|
+ }
|
|
|
|
/* Here we actually compare this rate to the latest LQ command */
|
|
if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
|
|
@@ -1392,8 +1399,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|
/* Collect data for each rate used during failed TX attempts */
|
|
for (i = 0; i <= retries; ++i) {
|
|
lq_hwrate = le32_to_cpu(table->rs_table[i]);
|
|
- rs_rate_from_ucode_rate(lq_hwrate, info->band,
|
|
- &lq_rate);
|
|
+ if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
|
|
+ &lq_rate)) {
|
|
+ WARN_ON_ONCE(1);
|
|
+ return;
|
|
+ }
|
|
+
|
|
/*
|
|
* Only collect stats if retried rate is in the same RS
|
|
* table as active/search.
|
|
@@ -3262,7 +3273,10 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
|
|
for (i = 0; i < num_rates; i++)
|
|
lq_cmd->rs_table[i] = ucode_rate_le32;
|
|
|
|
- rs_rate_from_ucode_rate(ucode_rate, band, &rate);
|
|
+ if (rs_rate_from_ucode_rate(ucode_rate, band, &rate)) {
|
|
+ WARN_ON_ONCE(1);
|
|
+ return;
|
|
+ }
|
|
|
|
if (is_mimo(&rate))
|
|
lq_cmd->mimo_delim = num_rates - 1;
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
|
|
index ff193dca2020..2d21f0a1fa00 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
|
|
@@ -1405,6 +1405,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|
while (!skb_queue_empty(&skbs)) {
|
|
struct sk_buff *skb = __skb_dequeue(&skbs);
|
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
|
+ struct ieee80211_hdr *hdr = (void *)skb->data;
|
|
bool flushed = false;
|
|
|
|
skb_freed++;
|
|
@@ -1449,11 +1450,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
|
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
|
|
|
- /* W/A FW bug: seq_ctl is wrong when the status isn't success */
|
|
- if (status != TX_STATUS_SUCCESS) {
|
|
- struct ieee80211_hdr *hdr = (void *)skb->data;
|
|
+ /* W/A FW bug: seq_ctl is wrong upon failure / BAR frame */
|
|
+ if (ieee80211_is_back_req(hdr->frame_control))
|
|
+ seq_ctl = 0;
|
|
+ else if (status != TX_STATUS_SUCCESS)
|
|
seq_ctl = le16_to_cpu(hdr->seq_ctrl);
|
|
- }
|
|
|
|
if (unlikely(!seq_ctl)) {
|
|
struct ieee80211_hdr *hdr = (void *)skb->data;
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
|
index d017aa2a0a8b..d4a31e014c82 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
|
@@ -1144,6 +1144,14 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
|
|
kfree(trans_pcie->rxq);
|
|
}
|
|
|
|
+static void iwl_pcie_rx_move_to_allocator(struct iwl_rxq *rxq,
|
|
+ struct iwl_rb_allocator *rba)
|
|
+{
|
|
+ spin_lock(&rba->lock);
|
|
+ list_splice_tail_init(&rxq->rx_used, &rba->rbd_empty);
|
|
+ spin_unlock(&rba->lock);
|
|
+}
|
|
+
|
|
/*
|
|
* iwl_pcie_rx_reuse_rbd - Recycle used RBDs
|
|
*
|
|
@@ -1175,9 +1183,7 @@ static void iwl_pcie_rx_reuse_rbd(struct iwl_trans *trans,
|
|
if ((rxq->used_count % RX_CLAIM_REQ_ALLOC) == RX_POST_REQ_ALLOC) {
|
|
/* Move the 2 RBDs to the allocator ownership.
|
|
Allocator has another 6 from pool for the request completion*/
|
|
- spin_lock(&rba->lock);
|
|
- list_splice_tail_init(&rxq->rx_used, &rba->rbd_empty);
|
|
- spin_unlock(&rba->lock);
|
|
+ iwl_pcie_rx_move_to_allocator(rxq, rba);
|
|
|
|
atomic_inc(&rba->req_pending);
|
|
queue_work(rba->alloc_wq, &rba->rx_alloc);
|
|
@@ -1396,10 +1402,18 @@ restart:
|
|
IWL_DEBUG_RX(trans, "Q %d: HW = SW = %d\n", rxq->id, r);
|
|
|
|
while (i != r) {
|
|
+ struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
|
struct iwl_rx_mem_buffer *rxb;
|
|
-
|
|
- if (unlikely(rxq->used_count == rxq->queue_size / 2))
|
|
+ /* number of RBDs still waiting for page allocation */
|
|
+ u32 rb_pending_alloc =
|
|
+ atomic_read(&trans_pcie->rba.req_pending) *
|
|
+ RX_CLAIM_REQ_ALLOC;
|
|
+
|
|
+ if (unlikely(rb_pending_alloc >= rxq->queue_size / 2 &&
|
|
+ !emergency)) {
|
|
+ iwl_pcie_rx_move_to_allocator(rxq, rba);
|
|
emergency = true;
|
|
+ }
|
|
|
|
rxb = iwl_pcie_get_rxb(trans, rxq, i);
|
|
if (!rxb)
|
|
@@ -1421,17 +1435,13 @@ restart:
|
|
iwl_pcie_rx_allocator_get(trans, rxq);
|
|
|
|
if (rxq->used_count % RX_CLAIM_REQ_ALLOC == 0 && !emergency) {
|
|
- struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
|
-
|
|
/* Add the remaining empty RBDs for allocator use */
|
|
- spin_lock(&rba->lock);
|
|
- list_splice_tail_init(&rxq->rx_used, &rba->rbd_empty);
|
|
- spin_unlock(&rba->lock);
|
|
+ iwl_pcie_rx_move_to_allocator(rxq, rba);
|
|
} else if (emergency) {
|
|
count++;
|
|
if (count == 8) {
|
|
count = 0;
|
|
- if (rxq->used_count < rxq->queue_size / 3)
|
|
+ if (rb_pending_alloc < rxq->queue_size / 3)
|
|
emergency = false;
|
|
|
|
rxq->read = i;
|
|
diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c
|
|
index c67a8e7be310..3dbfce972c56 100644
|
|
--- a/drivers/net/wireless/marvell/libertas/if_usb.c
|
|
+++ b/drivers/net/wireless/marvell/libertas/if_usb.c
|
|
@@ -456,8 +456,6 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
|
|
MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
|
|
cardp);
|
|
|
|
- cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
|
|
-
|
|
lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
|
|
if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
|
|
lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
|
|
diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
|
|
index e92fc5001171..789337ea676a 100644
|
|
--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c
|
|
+++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
|
|
@@ -605,9 +605,10 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
|
|
{
|
|
unsigned long flags;
|
|
|
|
- if (recvlength > LBS_CMD_BUFFER_SIZE) {
|
|
+ if (recvlength < MESSAGE_HEADER_LEN ||
|
|
+ recvlength > LBS_CMD_BUFFER_SIZE) {
|
|
lbtf_deb_usbd(&cardp->udev->dev,
|
|
- "The receive buffer is too large\n");
|
|
+ "The receive buffer is invalid: %d\n", recvlength);
|
|
kfree_skb(skb);
|
|
return;
|
|
}
|
|
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
|
|
index 23cf437d14f9..1a49d1be042d 100644
|
|
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
|
|
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
|
|
@@ -128,8 +128,7 @@ __mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 bcn_idx, struct sk_buff *skb)
|
|
if (skb) {
|
|
ret = mt76_write_beacon(dev, beacon_addr, skb);
|
|
if (!ret)
|
|
- dev->beacon_data_mask |= BIT(bcn_idx) &
|
|
- dev->beacon_mask;
|
|
+ dev->beacon_data_mask |= BIT(bcn_idx);
|
|
} else {
|
|
dev->beacon_data_mask &= ~BIT(bcn_idx);
|
|
for (i = 0; i < beacon_len; i += 4)
|
|
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c
|
|
index 1428cfdee579..9594433234cc 100644
|
|
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c
|
|
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c
|
|
@@ -107,16 +107,24 @@ static int __maybe_unused mt76x2u_resume(struct usb_interface *intf)
|
|
mt76u_mcu_complete_urb,
|
|
&usb->mcu.cmpl);
|
|
if (err < 0)
|
|
- return err;
|
|
+ goto err;
|
|
|
|
err = mt76u_submit_rx_buffers(&dev->mt76);
|
|
if (err < 0)
|
|
- return err;
|
|
+ goto err;
|
|
|
|
tasklet_enable(&usb->rx_tasklet);
|
|
tasklet_enable(&usb->tx_tasklet);
|
|
|
|
- return mt76x2u_init_hardware(dev);
|
|
+ err = mt76x2u_init_hardware(dev);
|
|
+ if (err < 0)
|
|
+ goto err;
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err:
|
|
+ mt76x2u_cleanup(dev);
|
|
+ return err;
|
|
}
|
|
|
|
MODULE_DEVICE_TABLE(usb, mt76x2u_device_table);
|
|
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
|
|
index c0a163e40402..f360690396dd 100644
|
|
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
|
|
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
|
|
@@ -266,15 +266,17 @@ static void rsi_rx_done_handler(struct urb *urb)
|
|
if (urb->status)
|
|
goto out;
|
|
|
|
- if (urb->actual_length <= 0) {
|
|
- rsi_dbg(INFO_ZONE, "%s: Zero length packet\n", __func__);
|
|
+ if (urb->actual_length <= 0 ||
|
|
+ urb->actual_length > rx_cb->rx_skb->len) {
|
|
+ rsi_dbg(INFO_ZONE, "%s: Invalid packet length = %d\n",
|
|
+ __func__, urb->actual_length);
|
|
goto out;
|
|
}
|
|
if (skb_queue_len(&dev->rx_q) >= RSI_MAX_RX_PKTS) {
|
|
rsi_dbg(INFO_ZONE, "Max RX packets reached\n");
|
|
goto out;
|
|
}
|
|
- skb_put(rx_cb->rx_skb, urb->actual_length);
|
|
+ skb_trim(rx_cb->rx_skb, urb->actual_length);
|
|
skb_queue_tail(&dev->rx_q, rx_cb->rx_skb);
|
|
|
|
rsi_set_event(&dev->rx_thread.event);
|
|
@@ -308,6 +310,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
|
|
if (!skb)
|
|
return -ENOMEM;
|
|
skb_reserve(skb, MAX_DWORD_ALIGN_BYTES);
|
|
+ skb_put(skb, RSI_MAX_RX_USB_PKT_SIZE - MAX_DWORD_ALIGN_BYTES);
|
|
dword_align_bytes = (unsigned long)skb->data & 0x3f;
|
|
if (dword_align_bytes > 0)
|
|
skb_push(skb, dword_align_bytes);
|
|
@@ -319,7 +322,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
|
|
usb_rcvbulkpipe(dev->usbdev,
|
|
dev->bulkin_endpoint_addr[ep_num - 1]),
|
|
urb->transfer_buffer,
|
|
- RSI_MAX_RX_USB_PKT_SIZE,
|
|
+ skb->len,
|
|
rsi_rx_done_handler,
|
|
rx_cb);
|
|
|
|
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
|
|
index 89b0d0fade9f..19e3c5a0b715 100644
|
|
--- a/drivers/net/wireless/ti/wlcore/main.c
|
|
+++ b/drivers/net/wireless/ti/wlcore/main.c
|
|
@@ -957,6 +957,8 @@ static void wl1271_recovery_work(struct work_struct *work)
|
|
BUG_ON(wl->conf.recovery.bug_on_recovery &&
|
|
!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
|
|
|
|
+ clear_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
|
|
+
|
|
if (wl->conf.recovery.no_recovery) {
|
|
wl1271_info("No recovery (chosen on module load). Fw will remain stuck.");
|
|
goto out_unlock;
|
|
@@ -6710,6 +6712,7 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev)
|
|
int ret;
|
|
unsigned long start_time = jiffies;
|
|
bool pending = false;
|
|
+ bool recovery = false;
|
|
|
|
/* Nothing to do if no ELP mode requested */
|
|
if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
|
|
@@ -6726,7 +6729,7 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev)
|
|
|
|
ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
|
|
if (ret < 0) {
|
|
- wl12xx_queue_recovery_work(wl);
|
|
+ recovery = true;
|
|
goto err;
|
|
}
|
|
|
|
@@ -6734,11 +6737,12 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev)
|
|
ret = wait_for_completion_timeout(&compl,
|
|
msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
|
|
if (ret == 0) {
|
|
- wl1271_error("ELP wakeup timeout!");
|
|
- wl12xx_queue_recovery_work(wl);
|
|
+ wl1271_warning("ELP wakeup timeout!");
|
|
|
|
/* Return no error for runtime PM for recovery */
|
|
- return 0;
|
|
+ ret = 0;
|
|
+ recovery = true;
|
|
+ goto err;
|
|
}
|
|
}
|
|
|
|
@@ -6753,6 +6757,12 @@ err:
|
|
spin_lock_irqsave(&wl->wl_lock, flags);
|
|
wl->elp_compl = NULL;
|
|
spin_unlock_irqrestore(&wl->wl_lock, flags);
|
|
+
|
|
+ if (recovery) {
|
|
+ set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
|
|
+ wl12xx_queue_recovery_work(wl);
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
|
|
index 91162f8e0366..9a22056e8d9e 100644
|
|
--- a/drivers/nfc/nfcmrvl/uart.c
|
|
+++ b/drivers/nfc/nfcmrvl/uart.c
|
|
@@ -73,10 +73,9 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
|
|
struct device_node *matched_node;
|
|
int ret;
|
|
|
|
- matched_node = of_find_compatible_node(node, NULL, "marvell,nfc-uart");
|
|
+ matched_node = of_get_compatible_child(node, "marvell,nfc-uart");
|
|
if (!matched_node) {
|
|
- matched_node = of_find_compatible_node(node, NULL,
|
|
- "mrvl,nfc-uart");
|
|
+ matched_node = of_get_compatible_child(node, "mrvl,nfc-uart");
|
|
if (!matched_node)
|
|
return -ENODEV;
|
|
}
|
|
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
|
|
index 8aae6dcc839f..9148015ed803 100644
|
|
--- a/drivers/nvdimm/bus.c
|
|
+++ b/drivers/nvdimm/bus.c
|
|
@@ -488,6 +488,8 @@ static void nd_async_device_register(void *d, async_cookie_t cookie)
|
|
put_device(dev);
|
|
}
|
|
put_device(dev);
|
|
+ if (dev->parent)
|
|
+ put_device(dev->parent);
|
|
}
|
|
|
|
static void nd_async_device_unregister(void *d, async_cookie_t cookie)
|
|
@@ -507,6 +509,8 @@ void __nd_device_register(struct device *dev)
|
|
if (!dev)
|
|
return;
|
|
dev->bus = &nvdimm_bus_type;
|
|
+ if (dev->parent)
|
|
+ get_device(dev->parent);
|
|
get_device(dev);
|
|
async_schedule_domain(nd_async_device_register, dev,
|
|
&nd_async_domain);
|
|
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
|
|
index 6071e2942053..2082ae01b9c8 100644
|
|
--- a/drivers/nvdimm/pmem.c
|
|
+++ b/drivers/nvdimm/pmem.c
|
|
@@ -421,9 +421,11 @@ static int pmem_attach_disk(struct device *dev,
|
|
addr = devm_memremap_pages(dev, &pmem->pgmap);
|
|
pmem->pfn_flags |= PFN_MAP;
|
|
memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
|
|
- } else
|
|
+ } else {
|
|
addr = devm_memremap(dev, pmem->phys_addr,
|
|
pmem->size, ARCH_MEMREMAP_PMEM);
|
|
+ memcpy(&bb_res, &nsio->res, sizeof(bb_res));
|
|
+ }
|
|
|
|
/*
|
|
* At release time the queue must be frozen before
|
|
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
|
|
index fa37afcd43ff..174a418cb171 100644
|
|
--- a/drivers/nvdimm/region_devs.c
|
|
+++ b/drivers/nvdimm/region_devs.c
|
|
@@ -560,10 +560,17 @@ static ssize_t region_badblocks_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct nd_region *nd_region = to_nd_region(dev);
|
|
+ ssize_t rc;
|
|
|
|
- return badblocks_show(&nd_region->bb, buf, 0);
|
|
-}
|
|
+ device_lock(dev);
|
|
+ if (dev->driver)
|
|
+ rc = badblocks_show(&nd_region->bb, buf, 0);
|
|
+ else
|
|
+ rc = -ENXIO;
|
|
+ device_unlock(dev);
|
|
|
|
+ return rc;
|
|
+}
|
|
static DEVICE_ATTR(badblocks, 0444, region_badblocks_show, NULL);
|
|
|
|
static ssize_t resource_show(struct device *dev,
|
|
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
|
|
index 206d63cb1afc..bcd09d3a44da 100644
|
|
--- a/drivers/nvme/host/fabrics.c
|
|
+++ b/drivers/nvme/host/fabrics.c
|
|
@@ -552,8 +552,11 @@ blk_status_t nvmf_fail_nonready_command(struct nvme_ctrl *ctrl,
|
|
ctrl->state != NVME_CTRL_DEAD &&
|
|
!blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH))
|
|
return BLK_STS_RESOURCE;
|
|
- nvme_req(rq)->status = NVME_SC_ABORT_REQ;
|
|
- return BLK_STS_IOERR;
|
|
+
|
|
+ nvme_req(rq)->status = NVME_SC_HOST_PATH_ERROR;
|
|
+ blk_mq_start_request(rq);
|
|
+ nvme_complete_rq(rq);
|
|
+ return BLK_STS_OK;
|
|
}
|
|
EXPORT_SYMBOL_GPL(nvmf_fail_nonready_command);
|
|
|
|
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
|
|
index 9fe3fff818b8..b71c9ad1bf45 100644
|
|
--- a/drivers/nvme/host/multipath.c
|
|
+++ b/drivers/nvme/host/multipath.c
|
|
@@ -77,6 +77,13 @@ void nvme_failover_req(struct request *req)
|
|
queue_work(nvme_wq, &ns->ctrl->ana_work);
|
|
}
|
|
break;
|
|
+ case NVME_SC_HOST_PATH_ERROR:
|
|
+ /*
|
|
+ * Temporary transport disruption in talking to the controller.
|
|
+ * Try to send on a new path.
|
|
+ */
|
|
+ nvme_mpath_clear_current_path(ns);
|
|
+ break;
|
|
default:
|
|
/*
|
|
* Reset the controller for any non-ANA error as we don't know
|
|
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
|
|
index aa1657831b70..7c530c88b3fb 100644
|
|
--- a/drivers/nvmem/core.c
|
|
+++ b/drivers/nvmem/core.c
|
|
@@ -516,11 +516,17 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
|
|
goto err_device_del;
|
|
}
|
|
|
|
- if (config->cells)
|
|
- nvmem_add_cells(nvmem, config->cells, config->ncells);
|
|
+ if (config->cells) {
|
|
+ rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
|
|
+ if (rval)
|
|
+ goto err_teardown_compat;
|
|
+ }
|
|
|
|
return nvmem;
|
|
|
|
+err_teardown_compat:
|
|
+ if (config->compat)
|
|
+ device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
|
|
err_device_del:
|
|
device_del(&nvmem->dev);
|
|
err_put_device:
|
|
diff --git a/drivers/of/base.c b/drivers/of/base.c
|
|
index 74eaedd5b860..70f5fd08891b 100644
|
|
--- a/drivers/of/base.c
|
|
+++ b/drivers/of/base.c
|
|
@@ -67,6 +67,7 @@ bool of_node_name_eq(const struct device_node *np, const char *name)
|
|
|
|
return (strlen(name) == len) && (strncmp(node_name, name, len) == 0);
|
|
}
|
|
+EXPORT_SYMBOL(of_node_name_eq);
|
|
|
|
bool of_node_name_prefix(const struct device_node *np, const char *prefix)
|
|
{
|
|
@@ -75,6 +76,7 @@ bool of_node_name_prefix(const struct device_node *np, const char *prefix)
|
|
|
|
return strncmp(kbasename(np->full_name), prefix, strlen(prefix)) == 0;
|
|
}
|
|
+EXPORT_SYMBOL(of_node_name_prefix);
|
|
|
|
int of_n_addr_cells(struct device_node *np)
|
|
{
|
|
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
|
|
index 7af0ddec936b..20988c426650 100644
|
|
--- a/drivers/opp/of.c
|
|
+++ b/drivers/opp/of.c
|
|
@@ -425,6 +425,7 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
|
|
dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
|
|
count, pstate_count);
|
|
ret = -ENOENT;
|
|
+ _dev_pm_opp_remove_table(opp_table, dev, false);
|
|
goto put_opp_table;
|
|
}
|
|
|
|
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
|
|
index ce9224a36f62..a32d6dde7a57 100644
|
|
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
|
|
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
|
|
@@ -542,7 +542,7 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
|
|
};
|
|
|
|
/*
|
|
- * dra7xx_pcie_ep_unaligned_memaccess: workaround for AM572x/AM571x Errata i870
|
|
+ * dra7xx_pcie_unaligned_memaccess: workaround for AM572x/AM571x Errata i870
|
|
* @dra7xx: the dra7xx device where the workaround should be applied
|
|
*
|
|
* Access to the PCIe slave port that are not 32-bit aligned will result
|
|
@@ -552,7 +552,7 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
|
|
*
|
|
* To avoid this issue set PCIE_SS1_AXI2OCP_LEGACY_MODE_ENABLE to 1.
|
|
*/
|
|
-static int dra7xx_pcie_ep_unaligned_memaccess(struct device *dev)
|
|
+static int dra7xx_pcie_unaligned_memaccess(struct device *dev)
|
|
{
|
|
int ret;
|
|
struct device_node *np = dev->of_node;
|
|
@@ -704,6 +704,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|
|
|
dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
|
|
DEVICE_TYPE_RC);
|
|
+
|
|
+ ret = dra7xx_pcie_unaligned_memaccess(dev);
|
|
+ if (ret)
|
|
+ dev_err(dev, "WA for Errata i870 not applied\n");
|
|
+
|
|
ret = dra7xx_add_pcie_port(dra7xx, pdev);
|
|
if (ret < 0)
|
|
goto err_gpio;
|
|
@@ -717,7 +722,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|
dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
|
|
DEVICE_TYPE_EP);
|
|
|
|
- ret = dra7xx_pcie_ep_unaligned_memaccess(dev);
|
|
+ ret = dra7xx_pcie_unaligned_memaccess(dev);
|
|
if (ret)
|
|
goto err_gpio;
|
|
|
|
diff --git a/drivers/pci/controller/pcie-cadence-ep.c b/drivers/pci/controller/pcie-cadence-ep.c
|
|
index 9e87dd7f9ac3..6692654798d4 100644
|
|
--- a/drivers/pci/controller/pcie-cadence-ep.c
|
|
+++ b/drivers/pci/controller/pcie-cadence-ep.c
|
|
@@ -258,7 +258,6 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
|
|
u8 intx, bool is_asserted)
|
|
{
|
|
struct cdns_pcie *pcie = &ep->pcie;
|
|
- u32 r = ep->max_regions - 1;
|
|
u32 offset;
|
|
u16 status;
|
|
u8 msg_code;
|
|
@@ -268,8 +267,8 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
|
|
/* Set the outbound region if needed. */
|
|
if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
|
|
ep->irq_pci_fn != fn)) {
|
|
- /* Last region was reserved for IRQ writes. */
|
|
- cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, r,
|
|
+ /* First region was reserved for IRQ writes. */
|
|
+ cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, 0,
|
|
ep->irq_phys_addr);
|
|
ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
|
|
ep->irq_pci_fn = fn;
|
|
@@ -347,8 +346,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
|
|
/* Set the outbound region if needed. */
|
|
if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
|
|
ep->irq_pci_fn != fn)) {
|
|
- /* Last region was reserved for IRQ writes. */
|
|
- cdns_pcie_set_outbound_region(pcie, fn, ep->max_regions - 1,
|
|
+ /* First region was reserved for IRQ writes. */
|
|
+ cdns_pcie_set_outbound_region(pcie, fn, 0,
|
|
false,
|
|
ep->irq_phys_addr,
|
|
pci_addr & ~pci_addr_mask,
|
|
@@ -517,6 +516,8 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev)
|
|
goto free_epc_mem;
|
|
}
|
|
ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
|
|
+ /* Reserve region 0 for IRQs */
|
|
+ set_bit(0, &ep->ob_region_map);
|
|
|
|
return 0;
|
|
|
|
diff --git a/drivers/pci/controller/pcie-cadence.c b/drivers/pci/controller/pcie-cadence.c
|
|
index 975bcdd6b5c0..cd795f6fc1e2 100644
|
|
--- a/drivers/pci/controller/pcie-cadence.c
|
|
+++ b/drivers/pci/controller/pcie-cadence.c
|
|
@@ -190,14 +190,16 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
|
|
|
|
for (i = 0; i < phy_count; i++) {
|
|
of_property_read_string_index(np, "phy-names", i, &name);
|
|
- phy[i] = devm_phy_optional_get(dev, name);
|
|
- if (IS_ERR(phy))
|
|
- return PTR_ERR(phy);
|
|
-
|
|
+ phy[i] = devm_phy_get(dev, name);
|
|
+ if (IS_ERR(phy[i])) {
|
|
+ ret = PTR_ERR(phy[i]);
|
|
+ goto err_phy;
|
|
+ }
|
|
link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
|
|
if (!link[i]) {
|
|
+ devm_phy_put(dev, phy[i]);
|
|
ret = -EINVAL;
|
|
- goto err_link;
|
|
+ goto err_phy;
|
|
}
|
|
}
|
|
|
|
@@ -207,13 +209,15 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
|
|
|
|
ret = cdns_pcie_enable_phy(pcie);
|
|
if (ret)
|
|
- goto err_link;
|
|
+ goto err_phy;
|
|
|
|
return 0;
|
|
|
|
-err_link:
|
|
- while (--i >= 0)
|
|
+err_phy:
|
|
+ while (--i >= 0) {
|
|
device_link_del(link[i]);
|
|
+ devm_phy_put(dev, phy[i]);
|
|
+ }
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
|
|
index 861dda69f366..c5ff6ca65eab 100644
|
|
--- a/drivers/pci/controller/pcie-mediatek.c
|
|
+++ b/drivers/pci/controller/pcie-mediatek.c
|
|
@@ -337,6 +337,17 @@ static struct mtk_pcie_port *mtk_pcie_find_port(struct pci_bus *bus,
|
|
{
|
|
struct mtk_pcie *pcie = bus->sysdata;
|
|
struct mtk_pcie_port *port;
|
|
+ struct pci_dev *dev = NULL;
|
|
+
|
|
+ /*
|
|
+ * Walk the bus hierarchy to get the devfn value
|
|
+ * of the port in the root bus.
|
|
+ */
|
|
+ while (bus && bus->number) {
|
|
+ dev = bus->self;
|
|
+ bus = dev->bus;
|
|
+ devfn = dev->devfn;
|
|
+ }
|
|
|
|
list_for_each_entry(port, &pcie->ports, list)
|
|
if (port->slot == PCI_SLOT(devfn))
|
|
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
|
|
index f2ef896464b3..af24ed50a245 100644
|
|
--- a/drivers/pci/msi.c
|
|
+++ b/drivers/pci/msi.c
|
|
@@ -958,7 +958,6 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
|
|
}
|
|
}
|
|
}
|
|
- WARN_ON(!!dev->msix_enabled);
|
|
|
|
/* Check whether driver already requested for MSI irq */
|
|
if (dev->msi_enabled) {
|
|
@@ -1028,8 +1027,6 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
|
if (!pci_msi_supported(dev, minvec))
|
|
return -EINVAL;
|
|
|
|
- WARN_ON(!!dev->msi_enabled);
|
|
-
|
|
/* Check whether driver already requested MSI-X irqs */
|
|
if (dev->msix_enabled) {
|
|
pci_info(dev, "can't enable MSI (MSI-X already enabled)\n");
|
|
@@ -1039,6 +1036,9 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
|
if (maxvec < minvec)
|
|
return -ERANGE;
|
|
|
|
+ if (WARN_ON_ONCE(dev->msi_enabled))
|
|
+ return -EINVAL;
|
|
+
|
|
nvec = pci_msi_vec_count(dev);
|
|
if (nvec < 0)
|
|
return nvec;
|
|
@@ -1087,6 +1087,9 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
|
|
if (maxvec < minvec)
|
|
return -ERANGE;
|
|
|
|
+ if (WARN_ON_ONCE(dev->msix_enabled))
|
|
+ return -EINVAL;
|
|
+
|
|
for (;;) {
|
|
if (affd) {
|
|
nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
|
|
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
|
|
index c2ab57705043..f8436d1c4d45 100644
|
|
--- a/drivers/pci/pci-acpi.c
|
|
+++ b/drivers/pci/pci-acpi.c
|
|
@@ -762,19 +762,33 @@ static void pci_acpi_setup(struct device *dev)
|
|
return;
|
|
|
|
device_set_wakeup_capable(dev, true);
|
|
+ /*
|
|
+ * For bridges that can do D3 we enable wake automatically (as
|
|
+ * we do for the power management itself in that case). The
|
|
+ * reason is that the bridge may have additional methods such as
|
|
+ * _DSW that need to be called.
|
|
+ */
|
|
+ if (pci_dev->bridge_d3)
|
|
+ device_wakeup_enable(dev);
|
|
+
|
|
acpi_pci_wakeup(pci_dev, false);
|
|
}
|
|
|
|
static void pci_acpi_cleanup(struct device *dev)
|
|
{
|
|
struct acpi_device *adev = ACPI_COMPANION(dev);
|
|
+ struct pci_dev *pci_dev = to_pci_dev(dev);
|
|
|
|
if (!adev)
|
|
return;
|
|
|
|
pci_acpi_remove_pm_notifier(adev);
|
|
- if (adev->wakeup.flags.valid)
|
|
+ if (adev->wakeup.flags.valid) {
|
|
+ if (pci_dev->bridge_d3)
|
|
+ device_wakeup_disable(dev);
|
|
+
|
|
device_set_wakeup_capable(dev, false);
|
|
+ }
|
|
}
|
|
|
|
static bool pci_acpi_bus_match(struct device *dev)
|
|
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
|
|
index 5326916715d2..f78860ce884b 100644
|
|
--- a/drivers/pci/pcie/aspm.c
|
|
+++ b/drivers/pci/pcie/aspm.c
|
|
@@ -991,7 +991,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
|
|
* All PCIe functions are in one slot, remove one function will remove
|
|
* the whole slot, so just wait until we are the last function left.
|
|
*/
|
|
- if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
|
|
+ if (!list_empty(&parent->subordinate->devices))
|
|
goto out;
|
|
|
|
link = parent->link_state;
|
|
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
|
|
index 6bc27b7fd452..c0673a717239 100644
|
|
--- a/drivers/pci/quirks.c
|
|
+++ b/drivers/pci/quirks.c
|
|
@@ -3190,7 +3190,11 @@ static void disable_igfx_irq(struct pci_dev *dev)
|
|
|
|
pci_iounmap(dev, regs);
|
|
}
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0042, disable_igfx_irq);
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0046, disable_igfx_irq);
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x004a, disable_igfx_irq);
|
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
|
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0106, disable_igfx_irq);
|
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
|
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq);
|
|
|
|
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
|
|
index 461e7fd2756f..e9c6b120cf45 100644
|
|
--- a/drivers/pci/remove.c
|
|
+++ b/drivers/pci/remove.c
|
|
@@ -25,9 +25,6 @@ static void pci_stop_dev(struct pci_dev *dev)
|
|
|
|
pci_dev_assign_added(dev, false);
|
|
}
|
|
-
|
|
- if (dev->bus->self)
|
|
- pcie_aspm_exit_link_state(dev);
|
|
}
|
|
|
|
static void pci_destroy_dev(struct pci_dev *dev)
|
|
@@ -41,6 +38,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
|
|
list_del(&dev->bus_list);
|
|
up_write(&pci_bus_sem);
|
|
|
|
+ pcie_aspm_exit_link_state(dev);
|
|
pci_bridge_d3_update(dev);
|
|
pci_free_resources(dev);
|
|
put_device(&dev->dev);
|
|
diff --git a/drivers/pcmcia/ricoh.h b/drivers/pcmcia/ricoh.h
|
|
index 01098c841f87..8ac7b138c094 100644
|
|
--- a/drivers/pcmcia/ricoh.h
|
|
+++ b/drivers/pcmcia/ricoh.h
|
|
@@ -119,6 +119,10 @@
|
|
#define RL5C4XX_MISC_CONTROL 0x2F /* 8 bit */
|
|
#define RL5C4XX_ZV_ENABLE 0x08
|
|
|
|
+/* Misc Control 3 Register */
|
|
+#define RL5C4XX_MISC3 0x00A2 /* 16 bit */
|
|
+#define RL5C47X_MISC3_CB_CLKRUN_DIS BIT(1)
|
|
+
|
|
#ifdef __YENTA_H
|
|
|
|
#define rl_misc(socket) ((socket)->private[0])
|
|
@@ -156,6 +160,35 @@ static void ricoh_set_zv(struct yenta_socket *socket)
|
|
}
|
|
}
|
|
|
|
+static void ricoh_set_clkrun(struct yenta_socket *socket, bool quiet)
|
|
+{
|
|
+ u16 misc3;
|
|
+
|
|
+ /*
|
|
+ * RL5C475II likely has this setting, too, however no datasheet
|
|
+ * is publicly available for this chip
|
|
+ */
|
|
+ if (socket->dev->device != PCI_DEVICE_ID_RICOH_RL5C476 &&
|
|
+ socket->dev->device != PCI_DEVICE_ID_RICOH_RL5C478)
|
|
+ return;
|
|
+
|
|
+ if (socket->dev->revision < 0x80)
|
|
+ return;
|
|
+
|
|
+ misc3 = config_readw(socket, RL5C4XX_MISC3);
|
|
+ if (misc3 & RL5C47X_MISC3_CB_CLKRUN_DIS) {
|
|
+ if (!quiet)
|
|
+ dev_dbg(&socket->dev->dev,
|
|
+ "CLKRUN feature already disabled\n");
|
|
+ } else if (disable_clkrun) {
|
|
+ if (!quiet)
|
|
+ dev_info(&socket->dev->dev,
|
|
+ "Disabling CLKRUN feature\n");
|
|
+ misc3 |= RL5C47X_MISC3_CB_CLKRUN_DIS;
|
|
+ config_writew(socket, RL5C4XX_MISC3, misc3);
|
|
+ }
|
|
+}
|
|
+
|
|
static void ricoh_save_state(struct yenta_socket *socket)
|
|
{
|
|
rl_misc(socket) = config_readw(socket, RL5C4XX_MISC);
|
|
@@ -172,6 +205,7 @@ static void ricoh_restore_state(struct yenta_socket *socket)
|
|
config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
|
|
config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
|
|
config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
|
|
+ ricoh_set_clkrun(socket, true);
|
|
}
|
|
|
|
|
|
@@ -197,6 +231,7 @@ static int ricoh_override(struct yenta_socket *socket)
|
|
config_writew(socket, RL5C4XX_CONFIG, config);
|
|
|
|
ricoh_set_zv(socket);
|
|
+ ricoh_set_clkrun(socket, false);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
|
|
index ab3da2262f0f..ac6a3f46b1e6 100644
|
|
--- a/drivers/pcmcia/yenta_socket.c
|
|
+++ b/drivers/pcmcia/yenta_socket.c
|
|
@@ -26,7 +26,8 @@
|
|
|
|
static bool disable_clkrun;
|
|
module_param(disable_clkrun, bool, 0444);
|
|
-MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
|
|
+MODULE_PARM_DESC(disable_clkrun,
|
|
+ "If PC card doesn't function properly, please try this option (TI and Ricoh bridges only)");
|
|
|
|
static bool isa_probe = 1;
|
|
module_param(isa_probe, bool, 0444);
|
|
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
|
|
index 6556dbeae65e..ac251c62bc66 100644
|
|
--- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
|
|
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
|
|
@@ -319,6 +319,8 @@ static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
|
pad->function = function;
|
|
|
|
ret = pmic_mpp_write_mode_ctl(state, pad);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
|
|
|
|
@@ -343,13 +345,12 @@ static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
|
|
|
|
switch (param) {
|
|
case PIN_CONFIG_BIAS_DISABLE:
|
|
- arg = pad->pullup == PMIC_MPP_PULL_UP_OPEN;
|
|
+ if (pad->pullup != PMIC_MPP_PULL_UP_OPEN)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_BIAS_PULL_UP:
|
|
switch (pad->pullup) {
|
|
- case PMIC_MPP_PULL_UP_OPEN:
|
|
- arg = 0;
|
|
- break;
|
|
case PMIC_MPP_PULL_UP_0P6KOHM:
|
|
arg = 600;
|
|
break;
|
|
@@ -364,13 +365,17 @@ static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
|
|
}
|
|
break;
|
|
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
|
|
- arg = !pad->is_enabled;
|
|
+ if (pad->is_enabled)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_POWER_SOURCE:
|
|
arg = pad->power_source;
|
|
break;
|
|
case PIN_CONFIG_INPUT_ENABLE:
|
|
- arg = pad->input_enabled;
|
|
+ if (!pad->input_enabled)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_OUTPUT:
|
|
arg = pad->out_value;
|
|
@@ -382,7 +387,9 @@ static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
|
|
arg = pad->amux_input;
|
|
break;
|
|
case PMIC_MPP_CONF_PAIRED:
|
|
- arg = pad->paired;
|
|
+ if (!pad->paired)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_DRIVE_STRENGTH:
|
|
arg = pad->drive_strength;
|
|
@@ -455,7 +462,7 @@ static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|
pad->dtest = arg;
|
|
break;
|
|
case PIN_CONFIG_DRIVE_STRENGTH:
|
|
- arg = pad->drive_strength;
|
|
+ pad->drive_strength = arg;
|
|
break;
|
|
case PMIC_MPP_CONF_AMUX_ROUTE:
|
|
if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4)
|
|
@@ -502,6 +509,10 @@ static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
+ ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_SINK_CTL, pad->drive_strength);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
|
|
|
|
return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
|
|
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
|
|
index f53e32a9d8fc..0e153bae322e 100644
|
|
--- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
|
|
+++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
|
|
@@ -260,22 +260,32 @@ static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
|
|
|
|
switch (param) {
|
|
case PIN_CONFIG_BIAS_DISABLE:
|
|
- arg = pin->bias == PM8XXX_GPIO_BIAS_NP;
|
|
+ if (pin->bias != PM8XXX_GPIO_BIAS_NP)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_BIAS_PULL_DOWN:
|
|
- arg = pin->bias == PM8XXX_GPIO_BIAS_PD;
|
|
+ if (pin->bias != PM8XXX_GPIO_BIAS_PD)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_BIAS_PULL_UP:
|
|
- arg = pin->bias <= PM8XXX_GPIO_BIAS_PU_1P5_30;
|
|
+ if (pin->bias > PM8XXX_GPIO_BIAS_PU_1P5_30)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PM8XXX_QCOM_PULL_UP_STRENGTH:
|
|
arg = pin->pull_up_strength;
|
|
break;
|
|
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
|
|
- arg = pin->disable;
|
|
+ if (!pin->disable)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_INPUT_ENABLE:
|
|
- arg = pin->mode == PM8XXX_GPIO_MODE_INPUT;
|
|
+ if (pin->mode != PM8XXX_GPIO_MODE_INPUT)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_OUTPUT:
|
|
if (pin->mode & PM8XXX_GPIO_MODE_OUTPUT)
|
|
@@ -290,10 +300,14 @@ static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
|
|
arg = pin->output_strength;
|
|
break;
|
|
case PIN_CONFIG_DRIVE_PUSH_PULL:
|
|
- arg = !pin->open_drain;
|
|
+ if (pin->open_drain)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
|
- arg = pin->open_drain;
|
|
+ if (!pin->open_drain)
|
|
+ return -EINVAL;
|
|
+ arg = 1;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
|
|
index 4d9bf9b3e9f3..26ebedc1f6d3 100644
|
|
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
|
|
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
|
|
@@ -1079,10 +1079,9 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
|
* We suppose that we won't have any more functions than pins,
|
|
* we'll reallocate that later anyway
|
|
*/
|
|
- pctl->functions = devm_kcalloc(&pdev->dev,
|
|
- pctl->ngroups,
|
|
- sizeof(*pctl->functions),
|
|
- GFP_KERNEL);
|
|
+ pctl->functions = kcalloc(pctl->ngroups,
|
|
+ sizeof(*pctl->functions),
|
|
+ GFP_KERNEL);
|
|
if (!pctl->functions)
|
|
return -ENOMEM;
|
|
|
|
@@ -1133,8 +1132,10 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
|
|
|
func_item = sunxi_pinctrl_find_function_by_name(pctl,
|
|
func->name);
|
|
- if (!func_item)
|
|
+ if (!func_item) {
|
|
+ kfree(pctl->functions);
|
|
return -EINVAL;
|
|
+ }
|
|
|
|
if (!func_item->groups) {
|
|
func_item->groups =
|
|
@@ -1142,8 +1143,10 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
|
func_item->ngroups,
|
|
sizeof(*func_item->groups),
|
|
GFP_KERNEL);
|
|
- if (!func_item->groups)
|
|
+ if (!func_item->groups) {
|
|
+ kfree(pctl->functions);
|
|
return -ENOMEM;
|
|
+ }
|
|
}
|
|
|
|
func_grp = func_item->groups;
|
|
diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
|
|
index bbcaee56db9d..b6a7d9f74cf3 100644
|
|
--- a/drivers/power/supply/twl4030_charger.c
|
|
+++ b/drivers/power/supply/twl4030_charger.c
|
|
@@ -996,12 +996,13 @@ static int twl4030_bci_probe(struct platform_device *pdev)
|
|
if (bci->dev->of_node) {
|
|
struct device_node *phynode;
|
|
|
|
- phynode = of_find_compatible_node(bci->dev->of_node->parent,
|
|
- NULL, "ti,twl4030-usb");
|
|
+ phynode = of_get_compatible_child(bci->dev->of_node->parent,
|
|
+ "ti,twl4030-usb");
|
|
if (phynode) {
|
|
bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
|
|
bci->transceiver = devm_usb_get_phy_by_node(
|
|
bci->dev, phynode, &bci->usb_nb);
|
|
+ of_node_put(phynode);
|
|
if (IS_ERR(bci->transceiver)) {
|
|
ret = PTR_ERR(bci->transceiver);
|
|
if (ret == -EPROBE_DEFER)
|
|
diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c
|
|
index 61a760ee4aac..e9ab90c19304 100644
|
|
--- a/drivers/remoteproc/qcom_q6v5.c
|
|
+++ b/drivers/remoteproc/qcom_q6v5.c
|
|
@@ -198,6 +198,9 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
|
|
}
|
|
|
|
q6v5->fatal_irq = platform_get_irq_byname(pdev, "fatal");
|
|
+ if (q6v5->fatal_irq == -EPROBE_DEFER)
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
ret = devm_request_threaded_irq(&pdev->dev, q6v5->fatal_irq,
|
|
NULL, q6v5_fatal_interrupt,
|
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
|
@@ -208,6 +211,9 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
|
|
}
|
|
|
|
q6v5->ready_irq = platform_get_irq_byname(pdev, "ready");
|
|
+ if (q6v5->ready_irq == -EPROBE_DEFER)
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
ret = devm_request_threaded_irq(&pdev->dev, q6v5->ready_irq,
|
|
NULL, q6v5_ready_interrupt,
|
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
|
@@ -218,6 +224,9 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
|
|
}
|
|
|
|
q6v5->handover_irq = platform_get_irq_byname(pdev, "handover");
|
|
+ if (q6v5->handover_irq == -EPROBE_DEFER)
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
ret = devm_request_threaded_irq(&pdev->dev, q6v5->handover_irq,
|
|
NULL, q6v5_handover_interrupt,
|
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
|
@@ -229,6 +238,9 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
|
|
disable_irq(q6v5->handover_irq);
|
|
|
|
q6v5->stop_irq = platform_get_irq_byname(pdev, "stop-ack");
|
|
+ if (q6v5->stop_irq == -EPROBE_DEFER)
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
ret = devm_request_threaded_irq(&pdev->dev, q6v5->stop_irq,
|
|
NULL, q6v5_stop_interrupt,
|
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
|
diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
|
|
index 8da83a4ebadc..b2e5a6abf7d5 100644
|
|
--- a/drivers/rpmsg/qcom_smd.c
|
|
+++ b/drivers/rpmsg/qcom_smd.c
|
|
@@ -1122,8 +1122,10 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
|
|
|
|
channel->edge = edge;
|
|
channel->name = kstrdup(name, GFP_KERNEL);
|
|
- if (!channel->name)
|
|
- return ERR_PTR(-ENOMEM);
|
|
+ if (!channel->name) {
|
|
+ ret = -ENOMEM;
|
|
+ goto free_channel;
|
|
+ }
|
|
|
|
spin_lock_init(&channel->tx_lock);
|
|
spin_lock_init(&channel->recv_lock);
|
|
@@ -1173,6 +1175,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
|
|
|
|
free_name_and_channel:
|
|
kfree(channel->name);
|
|
+free_channel:
|
|
kfree(channel);
|
|
|
|
return ERR_PTR(ret);
|
|
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
|
|
index cd3a2411bc2f..df0c5776d49b 100644
|
|
--- a/drivers/rtc/rtc-cmos.c
|
|
+++ b/drivers/rtc/rtc-cmos.c
|
|
@@ -50,6 +50,7 @@
|
|
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
|
|
#include <linux/mc146818rtc.h>
|
|
|
|
+#ifdef CONFIG_ACPI
|
|
/*
|
|
* Use ACPI SCI to replace HPET interrupt for RTC Alarm event
|
|
*
|
|
@@ -61,6 +62,18 @@
|
|
static bool use_acpi_alarm;
|
|
module_param(use_acpi_alarm, bool, 0444);
|
|
|
|
+static inline int cmos_use_acpi_alarm(void)
|
|
+{
|
|
+ return use_acpi_alarm;
|
|
+}
|
|
+#else /* !CONFIG_ACPI */
|
|
+
|
|
+static inline int cmos_use_acpi_alarm(void)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
struct cmos_rtc {
|
|
struct rtc_device *rtc;
|
|
struct device *dev;
|
|
@@ -167,9 +180,9 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
|
|
#endif
|
|
|
|
/* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */
|
|
-static int use_hpet_alarm(void)
|
|
+static inline int use_hpet_alarm(void)
|
|
{
|
|
- return is_hpet_enabled() && !use_acpi_alarm;
|
|
+ return is_hpet_enabled() && !cmos_use_acpi_alarm();
|
|
}
|
|
|
|
/*----------------------------------------------------------------*/
|
|
@@ -340,7 +353,7 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
|
|
if (use_hpet_alarm())
|
|
hpet_set_rtc_irq_bit(mask);
|
|
|
|
- if ((mask & RTC_AIE) && use_acpi_alarm) {
|
|
+ if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {
|
|
if (cmos->wake_on)
|
|
cmos->wake_on(cmos->dev);
|
|
}
|
|
@@ -358,7 +371,7 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
|
|
if (use_hpet_alarm())
|
|
hpet_mask_rtc_irq_bit(mask);
|
|
|
|
- if ((mask & RTC_AIE) && use_acpi_alarm) {
|
|
+ if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {
|
|
if (cmos->wake_off)
|
|
cmos->wake_off(cmos->dev);
|
|
}
|
|
@@ -980,7 +993,7 @@ static int cmos_suspend(struct device *dev)
|
|
}
|
|
spin_unlock_irq(&rtc_lock);
|
|
|
|
- if ((tmp & RTC_AIE) && !use_acpi_alarm) {
|
|
+ if ((tmp & RTC_AIE) && !cmos_use_acpi_alarm()) {
|
|
cmos->enabled_wake = 1;
|
|
if (cmos->wake_on)
|
|
cmos->wake_on(dev);
|
|
@@ -1031,7 +1044,7 @@ static void cmos_check_wkalrm(struct device *dev)
|
|
* ACPI RTC wake event is cleared after resume from STR,
|
|
* ACK the rtc irq here
|
|
*/
|
|
- if (t_now >= cmos->alarm_expires && use_acpi_alarm) {
|
|
+ if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) {
|
|
cmos_interrupt(0, (void *)cmos->rtc);
|
|
return;
|
|
}
|
|
@@ -1053,7 +1066,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
|
|
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
|
unsigned char tmp;
|
|
|
|
- if (cmos->enabled_wake && !use_acpi_alarm) {
|
|
+ if (cmos->enabled_wake && !cmos_use_acpi_alarm()) {
|
|
if (cmos->wake_off)
|
|
cmos->wake_off(dev);
|
|
else
|
|
@@ -1132,7 +1145,7 @@ static u32 rtc_handler(void *context)
|
|
* Or else, ACPI SCI is enabled during suspend/resume only,
|
|
* update rtc irq in that case.
|
|
*/
|
|
- if (use_acpi_alarm)
|
|
+ if (cmos_use_acpi_alarm())
|
|
cmos_interrupt(0, (void *)cmos->rtc);
|
|
else {
|
|
/* Fix me: can we use cmos_interrupt() here as well? */
|
|
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
|
|
index 4b2b4627daeb..71396b62dc52 100644
|
|
--- a/drivers/rtc/rtc-ds1307.c
|
|
+++ b/drivers/rtc/rtc-ds1307.c
|
|
@@ -1384,7 +1384,6 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
|
|
static const struct regmap_config regmap_config = {
|
|
.reg_bits = 8,
|
|
.val_bits = 8,
|
|
- .max_register = 0x9,
|
|
};
|
|
|
|
static int ds1307_probe(struct i2c_client *client,
|
|
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
|
|
index c3fc34b9964d..9e5d3f7d29ae 100644
|
|
--- a/drivers/scsi/esp_scsi.c
|
|
+++ b/drivers/scsi/esp_scsi.c
|
|
@@ -1338,6 +1338,7 @@ static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent,
|
|
|
|
bytes_sent = esp->data_dma_len;
|
|
bytes_sent -= ecount;
|
|
+ bytes_sent -= esp->send_cmd_residual;
|
|
|
|
/*
|
|
* The am53c974 has a DMA 'pecularity'. The doc states:
|
|
diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
|
|
index 8163dca2071b..a77772777a30 100644
|
|
--- a/drivers/scsi/esp_scsi.h
|
|
+++ b/drivers/scsi/esp_scsi.h
|
|
@@ -540,6 +540,8 @@ struct esp {
|
|
|
|
void *dma;
|
|
int dmarev;
|
|
+
|
|
+ u32 send_cmd_residual;
|
|
};
|
|
|
|
/* A front-end driver for the ESP chip should do the following in
|
|
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
|
|
index 5c7858e735c9..200b5bca1f5f 100644
|
|
--- a/drivers/scsi/lpfc/lpfc_scsi.c
|
|
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
|
|
@@ -4158,9 +4158,17 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|
}
|
|
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
|
|
|
|
- spin_lock_irqsave(&phba->hbalock, flags);
|
|
- lpfc_cmd->pCmd = NULL;
|
|
- spin_unlock_irqrestore(&phba->hbalock, flags);
|
|
+ /* If pCmd was set to NULL from abort path, do not call scsi_done */
|
|
+ if (xchg(&lpfc_cmd->pCmd, NULL) == NULL) {
|
|
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
|
|
+ "0711 FCP cmd already NULL, sid: 0x%06x, "
|
|
+ "did: 0x%06x, oxid: 0x%04x\n",
|
|
+ vport->fc_myDID,
|
|
+ (pnode) ? pnode->nlp_DID : 0,
|
|
+ phba->sli_rev == LPFC_SLI_REV4 ?
|
|
+ lpfc_cmd->cur_iocbq.sli4_xritag : 0xffff);
|
|
+ return;
|
|
+ }
|
|
|
|
/* The sdev is not guaranteed to be valid post scsi_done upcall. */
|
|
cmd->scsi_done(cmd);
|
|
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
|
index 9830bdb6e072..a95c823cd1a4 100644
|
|
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
|
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
|
@@ -3797,6 +3797,7 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba,
|
|
struct hbq_dmabuf *dmabuf;
|
|
struct lpfc_cq_event *cq_event;
|
|
unsigned long iflag;
|
|
+ int count = 0;
|
|
|
|
spin_lock_irqsave(&phba->hbalock, iflag);
|
|
phba->hba_flag &= ~HBA_SP_QUEUE_EVT;
|
|
@@ -3818,16 +3819,22 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba,
|
|
if (irspiocbq)
|
|
lpfc_sli_sp_handle_rspiocb(phba, pring,
|
|
irspiocbq);
|
|
+ count++;
|
|
break;
|
|
case CQE_CODE_RECEIVE:
|
|
case CQE_CODE_RECEIVE_V1:
|
|
dmabuf = container_of(cq_event, struct hbq_dmabuf,
|
|
cq_event);
|
|
lpfc_sli4_handle_received_buffer(phba, dmabuf);
|
|
+ count++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
+
|
|
+ /* Limit the number of events to 64 to avoid soft lockups */
|
|
+ if (count == 64)
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
|
|
index eb551f3cc471..71879f2207e0 100644
|
|
--- a/drivers/scsi/mac_esp.c
|
|
+++ b/drivers/scsi/mac_esp.c
|
|
@@ -427,6 +427,8 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
|
|
scsi_esp_cmd(esp, ESP_CMD_TI);
|
|
}
|
|
}
|
|
+
|
|
+ esp->send_cmd_residual = esp_count;
|
|
}
|
|
|
|
static int mac_esp_irq_pending(struct esp *esp)
|
|
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
|
|
index 9aa9590c5373..f6de7526ded5 100644
|
|
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
|
|
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
|
|
@@ -7523,6 +7523,9 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
|
|
get_user(user_sense_off, &cioc->sense_off))
|
|
return -EFAULT;
|
|
|
|
+ if (local_sense_off != user_sense_off)
|
|
+ return -EINVAL;
|
|
+
|
|
if (local_sense_len) {
|
|
void __user **sense_ioc_ptr =
|
|
(void __user **)((u8 *)((unsigned long)&ioc->frame.raw) + local_sense_off);
|
|
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
|
|
index 2c6c2cd5a0d0..596a9b214df1 100644
|
|
--- a/drivers/scsi/qla2xxx/qla_mbx.c
|
|
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
|
|
@@ -493,7 +493,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
|
qla2xxx_wake_dpc(vha);
|
|
}
|
|
- } else if (!abort_active) {
|
|
+ } else if (current == ha->dpc_thread) {
|
|
/* call abort directly since we are in the DPC thread */
|
|
ql_dbg(ql_dbg_mbx, vha, 0x101d,
|
|
"Timeout, calling abort_isp.\n");
|
|
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
|
|
index c55f38ec391c..54074dd483a7 100644
|
|
--- a/drivers/scsi/ufs/ufshcd.c
|
|
+++ b/drivers/scsi/ufs/ufshcd.c
|
|
@@ -1691,8 +1691,9 @@ static void __ufshcd_release(struct ufs_hba *hba)
|
|
|
|
hba->clk_gating.state = REQ_CLKS_OFF;
|
|
trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state);
|
|
- schedule_delayed_work(&hba->clk_gating.gate_work,
|
|
- msecs_to_jiffies(hba->clk_gating.delay_ms));
|
|
+ queue_delayed_work(hba->clk_gating.clk_gating_workq,
|
|
+ &hba->clk_gating.gate_work,
|
|
+ msecs_to_jiffies(hba->clk_gating.delay_ms));
|
|
}
|
|
|
|
void ufshcd_release(struct ufs_hba *hba)
|
|
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
|
|
index 8a3678c2e83c..97bb5989aa21 100644
|
|
--- a/drivers/soc/qcom/rmtfs_mem.c
|
|
+++ b/drivers/soc/qcom/rmtfs_mem.c
|
|
@@ -212,6 +212,11 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
|
|
dev_err(&pdev->dev, "failed to parse qcom,vmid\n");
|
|
goto remove_cdev;
|
|
} else if (!ret) {
|
|
+ if (!qcom_scm_is_available()) {
|
|
+ ret = -EPROBE_DEFER;
|
|
+ goto remove_cdev;
|
|
+ }
|
|
+
|
|
perms[0].vmid = QCOM_SCM_VMID_HLOS;
|
|
perms[0].perm = QCOM_SCM_PERM_RW;
|
|
perms[1].vmid = vmid;
|
|
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
|
|
index 2d6f3fcf3211..ed71a4c9c8b2 100644
|
|
--- a/drivers/soc/tegra/pmc.c
|
|
+++ b/drivers/soc/tegra/pmc.c
|
|
@@ -1288,7 +1288,7 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
|
|
if (!pmc->soc->has_tsense_reset)
|
|
return;
|
|
|
|
- np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip");
|
|
+ np = of_get_child_by_name(pmc->dev->of_node, "i2c-thermtrip");
|
|
if (!np) {
|
|
dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
|
|
return;
|
|
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
|
|
index 8612525fa4e3..584bcb018a62 100644
|
|
--- a/drivers/spi/spi-bcm-qspi.c
|
|
+++ b/drivers/spi/spi-bcm-qspi.c
|
|
@@ -89,7 +89,7 @@
|
|
#define BSPI_BPP_MODE_SELECT_MASK BIT(8)
|
|
#define BSPI_BPP_ADDR_SELECT_MASK BIT(16)
|
|
|
|
-#define BSPI_READ_LENGTH 512
|
|
+#define BSPI_READ_LENGTH 256
|
|
|
|
/* MSPI register offsets */
|
|
#define MSPI_SPCR0_LSB 0x000
|
|
@@ -355,7 +355,7 @@ static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi,
|
|
int bpc = 0, bpp = 0;
|
|
u8 command = op->cmd.opcode;
|
|
int width = op->cmd.buswidth ? op->cmd.buswidth : SPI_NBITS_SINGLE;
|
|
- int addrlen = op->addr.nbytes * 8;
|
|
+ int addrlen = op->addr.nbytes;
|
|
int flex_mode = 1;
|
|
|
|
dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n",
|
|
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
|
|
index f1526757aaf6..79fc3940245a 100644
|
|
--- a/drivers/spi/spi-ep93xx.c
|
|
+++ b/drivers/spi/spi-ep93xx.c
|
|
@@ -246,6 +246,19 @@ static int ep93xx_spi_read_write(struct spi_master *master)
|
|
return -EINPROGRESS;
|
|
}
|
|
|
|
+static enum dma_transfer_direction
|
|
+ep93xx_dma_data_to_trans_dir(enum dma_data_direction dir)
|
|
+{
|
|
+ switch (dir) {
|
|
+ case DMA_TO_DEVICE:
|
|
+ return DMA_MEM_TO_DEV;
|
|
+ case DMA_FROM_DEVICE:
|
|
+ return DMA_DEV_TO_MEM;
|
|
+ default:
|
|
+ return DMA_TRANS_NONE;
|
|
+ }
|
|
+}
|
|
+
|
|
/**
|
|
* ep93xx_spi_dma_prepare() - prepares a DMA transfer
|
|
* @master: SPI master
|
|
@@ -257,7 +270,7 @@ static int ep93xx_spi_read_write(struct spi_master *master)
|
|
*/
|
|
static struct dma_async_tx_descriptor *
|
|
ep93xx_spi_dma_prepare(struct spi_master *master,
|
|
- enum dma_transfer_direction dir)
|
|
+ enum dma_data_direction dir)
|
|
{
|
|
struct ep93xx_spi *espi = spi_master_get_devdata(master);
|
|
struct spi_transfer *xfer = master->cur_msg->state;
|
|
@@ -277,9 +290,9 @@ ep93xx_spi_dma_prepare(struct spi_master *master,
|
|
buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
|
|
|
memset(&conf, 0, sizeof(conf));
|
|
- conf.direction = dir;
|
|
+ conf.direction = ep93xx_dma_data_to_trans_dir(dir);
|
|
|
|
- if (dir == DMA_DEV_TO_MEM) {
|
|
+ if (dir == DMA_FROM_DEVICE) {
|
|
chan = espi->dma_rx;
|
|
buf = xfer->rx_buf;
|
|
sgt = &espi->rx_sgt;
|
|
@@ -343,7 +356,8 @@ ep93xx_spi_dma_prepare(struct spi_master *master,
|
|
if (!nents)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
- txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, DMA_CTRL_ACK);
|
|
+ txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, conf.direction,
|
|
+ DMA_CTRL_ACK);
|
|
if (!txd) {
|
|
dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir);
|
|
return ERR_PTR(-ENOMEM);
|
|
@@ -360,13 +374,13 @@ ep93xx_spi_dma_prepare(struct spi_master *master,
|
|
* unmapped.
|
|
*/
|
|
static void ep93xx_spi_dma_finish(struct spi_master *master,
|
|
- enum dma_transfer_direction dir)
|
|
+ enum dma_data_direction dir)
|
|
{
|
|
struct ep93xx_spi *espi = spi_master_get_devdata(master);
|
|
struct dma_chan *chan;
|
|
struct sg_table *sgt;
|
|
|
|
- if (dir == DMA_DEV_TO_MEM) {
|
|
+ if (dir == DMA_FROM_DEVICE) {
|
|
chan = espi->dma_rx;
|
|
sgt = &espi->rx_sgt;
|
|
} else {
|
|
@@ -381,8 +395,8 @@ static void ep93xx_spi_dma_callback(void *callback_param)
|
|
{
|
|
struct spi_master *master = callback_param;
|
|
|
|
- ep93xx_spi_dma_finish(master, DMA_MEM_TO_DEV);
|
|
- ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM);
|
|
+ ep93xx_spi_dma_finish(master, DMA_TO_DEVICE);
|
|
+ ep93xx_spi_dma_finish(master, DMA_FROM_DEVICE);
|
|
|
|
spi_finalize_current_transfer(master);
|
|
}
|
|
@@ -392,15 +406,15 @@ static int ep93xx_spi_dma_transfer(struct spi_master *master)
|
|
struct ep93xx_spi *espi = spi_master_get_devdata(master);
|
|
struct dma_async_tx_descriptor *rxd, *txd;
|
|
|
|
- rxd = ep93xx_spi_dma_prepare(master, DMA_DEV_TO_MEM);
|
|
+ rxd = ep93xx_spi_dma_prepare(master, DMA_FROM_DEVICE);
|
|
if (IS_ERR(rxd)) {
|
|
dev_err(&master->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd));
|
|
return PTR_ERR(rxd);
|
|
}
|
|
|
|
- txd = ep93xx_spi_dma_prepare(master, DMA_MEM_TO_DEV);
|
|
+ txd = ep93xx_spi_dma_prepare(master, DMA_TO_DEVICE);
|
|
if (IS_ERR(txd)) {
|
|
- ep93xx_spi_dma_finish(master, DMA_DEV_TO_MEM);
|
|
+ ep93xx_spi_dma_finish(master, DMA_FROM_DEVICE);
|
|
dev_err(&master->dev, "DMA TX failed: %ld\n", PTR_ERR(txd));
|
|
return PTR_ERR(txd);
|
|
}
|
|
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
|
|
index 421bfc7dda67..088772ebef9b 100644
|
|
--- a/drivers/spi/spi-gpio.c
|
|
+++ b/drivers/spi/spi-gpio.c
|
|
@@ -295,9 +295,11 @@ static int spi_gpio_request(struct device *dev,
|
|
spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN);
|
|
if (IS_ERR(spi_gpio->miso))
|
|
return PTR_ERR(spi_gpio->miso);
|
|
- if (!spi_gpio->miso)
|
|
- /* HW configuration without MISO pin */
|
|
- *mflags |= SPI_MASTER_NO_RX;
|
|
+ /*
|
|
+ * No setting SPI_MASTER_NO_RX here - if there is only a MOSI
|
|
+ * pin connected the host can still do RX by changing the
|
|
+ * direction of the line.
|
|
+ */
|
|
|
|
spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
|
|
if (IS_ERR(spi_gpio->sck))
|
|
@@ -423,7 +425,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
|
|
spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
|
|
spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction;
|
|
|
|
- if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
|
|
+ if ((master_flags & SPI_MASTER_NO_TX) == 0) {
|
|
spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
|
|
spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
|
|
spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
|
|
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
|
|
index e43842c7a31a..eb72dba71d83 100644
|
|
--- a/drivers/spi/spi-mem.c
|
|
+++ b/drivers/spi/spi-mem.c
|
|
@@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
|
|
int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
|
|
{
|
|
struct spi_controller *ctlr = mem->spi->controller;
|
|
+ size_t len;
|
|
+
|
|
+ len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
|
|
|
|
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
|
|
return ctlr->mem_ops->adjust_op_size(mem, op);
|
|
|
|
+ if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
|
|
+ if (len > spi_max_transfer_size(mem->spi))
|
|
+ return -EINVAL;
|
|
+
|
|
+ op->data.nbytes = min3((size_t)op->data.nbytes,
|
|
+ spi_max_transfer_size(mem->spi),
|
|
+ spi_max_message_size(mem->spi) -
|
|
+ len);
|
|
+ if (!op->data.nbytes)
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
|
|
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
|
|
index 86c0156e6c88..fc3093d21b96 100644
|
|
--- a/drivers/target/target_core_transport.c
|
|
+++ b/drivers/target/target_core_transport.c
|
|
@@ -2754,7 +2754,7 @@ static void target_release_cmd_kref(struct kref *kref)
|
|
if (se_sess) {
|
|
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
|
list_del_init(&se_cmd->se_cmd_list);
|
|
- if (list_empty(&se_sess->sess_cmd_list))
|
|
+ if (se_sess->sess_tearing_down && list_empty(&se_sess->sess_cmd_list))
|
|
wake_up(&se_sess->cmd_list_wq);
|
|
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
|
}
|
|
@@ -2907,7 +2907,7 @@ void target_wait_for_sess_cmds(struct se_session *se_sess)
|
|
|
|
spin_lock_irq(&se_sess->sess_cmd_lock);
|
|
do {
|
|
- ret = wait_event_interruptible_lock_irq_timeout(
|
|
+ ret = wait_event_lock_irq_timeout(
|
|
se_sess->cmd_list_wq,
|
|
list_empty(&se_sess->sess_cmd_list),
|
|
se_sess->sess_cmd_lock, 180 * HZ);
|
|
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
|
|
index 3be9519654e5..cf3fad2cb871 100644
|
|
--- a/drivers/tc/tc.c
|
|
+++ b/drivers/tc/tc.c
|
|
@@ -2,7 +2,7 @@
|
|
* TURBOchannel bus services.
|
|
*
|
|
* Copyright (c) Harald Koerfgen, 1998
|
|
- * Copyright (c) 2001, 2003, 2005, 2006 Maciej W. Rozycki
|
|
+ * Copyright (c) 2001, 2003, 2005, 2006, 2018 Maciej W. Rozycki
|
|
* Copyright (c) 2005 James Simmons
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU
|
|
@@ -10,6 +10,7 @@
|
|
* directory of this archive for more details.
|
|
*/
|
|
#include <linux/compiler.h>
|
|
+#include <linux/dma-mapping.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/init.h>
|
|
#include <linux/ioport.h>
|
|
@@ -92,6 +93,11 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
|
|
tdev->dev.bus = &tc_bus_type;
|
|
tdev->slot = slot;
|
|
|
|
+ /* TURBOchannel has 34-bit DMA addressing (16GiB space). */
|
|
+ tdev->dma_mask = DMA_BIT_MASK(34);
|
|
+ tdev->dev.dma_mask = &tdev->dma_mask;
|
|
+ tdev->dev.coherent_dma_mask = DMA_BIT_MASK(34);
|
|
+
|
|
for (i = 0; i < 8; i++) {
|
|
tdev->firmware[i] =
|
|
readb(module + offset + TC_FIRM_VER + 4 * i);
|
|
diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c
|
|
index dd8dd947b7f0..01b0cb994457 100644
|
|
--- a/drivers/thermal/da9062-thermal.c
|
|
+++ b/drivers/thermal/da9062-thermal.c
|
|
@@ -106,7 +106,7 @@ static void da9062_thermal_poll_on(struct work_struct *work)
|
|
THERMAL_EVENT_UNSPECIFIED);
|
|
|
|
delay = msecs_to_jiffies(thermal->zone->passive_delay);
|
|
- schedule_delayed_work(&thermal->work, delay);
|
|
+ queue_delayed_work(system_freezable_wq, &thermal->work, delay);
|
|
return;
|
|
}
|
|
|
|
@@ -125,7 +125,7 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
|
|
struct da9062_thermal *thermal = data;
|
|
|
|
disable_irq_nosync(thermal->irq);
|
|
- schedule_delayed_work(&thermal->work, 0);
|
|
+ queue_delayed_work(system_freezable_wq, &thermal->work, 0);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
|
|
index 78f932822d38..8df2ce94c28d 100644
|
|
--- a/drivers/thermal/rcar_thermal.c
|
|
+++ b/drivers/thermal/rcar_thermal.c
|
|
@@ -453,6 +453,7 @@ static int rcar_thermal_remove(struct platform_device *pdev)
|
|
|
|
rcar_thermal_for_each_priv(priv, common) {
|
|
rcar_thermal_irq_disable(priv);
|
|
+ cancel_delayed_work_sync(&priv->work);
|
|
if (priv->chip->use_of_thermal)
|
|
thermal_remove_hwmon_sysfs(priv->zone);
|
|
else
|
|
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
|
|
index b4ba2b1dab76..f4d0ef695225 100644
|
|
--- a/drivers/tty/serial/kgdboc.c
|
|
+++ b/drivers/tty/serial/kgdboc.c
|
|
@@ -130,6 +130,11 @@ static void kgdboc_unregister_kbd(void)
|
|
|
|
static int kgdboc_option_setup(char *opt)
|
|
{
|
|
+ if (!opt) {
|
|
+ pr_err("kgdboc: config string not provided\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
if (strlen(opt) >= MAX_CONFIG_LEN) {
|
|
printk(KERN_ERR "kgdboc: config string too long\n");
|
|
return -ENOSPC;
|
|
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
|
|
index 5f1183b0b89d..476ec4b1b86c 100644
|
|
--- a/drivers/tty/vt/vt.c
|
|
+++ b/drivers/tty/vt/vt.c
|
|
@@ -1551,7 +1551,7 @@ static void csi_K(struct vc_data *vc, int vpar)
|
|
scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count);
|
|
vc->vc_need_wrap = 0;
|
|
if (con_should_update(vc))
|
|
- do_update_region(vc, (unsigned long) start, count);
|
|
+ do_update_region(vc, (unsigned long)(start + offset), count);
|
|
}
|
|
|
|
static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
|
|
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
|
|
index 70a7981b94b3..9916edda5271 100644
|
|
--- a/drivers/uio/uio.c
|
|
+++ b/drivers/uio/uio.c
|
|
@@ -274,6 +274,8 @@ static struct class uio_class = {
|
|
.dev_groups = uio_groups,
|
|
};
|
|
|
|
+bool uio_class_registered;
|
|
+
|
|
/*
|
|
* device functions
|
|
*/
|
|
@@ -876,6 +878,9 @@ static int init_uio_class(void)
|
|
printk(KERN_ERR "class_register failed for uio\n");
|
|
goto err_class_register;
|
|
}
|
|
+
|
|
+ uio_class_registered = true;
|
|
+
|
|
return 0;
|
|
|
|
err_class_register:
|
|
@@ -886,6 +891,7 @@ exit:
|
|
|
|
static void release_uio_class(void)
|
|
{
|
|
+ uio_class_registered = false;
|
|
class_unregister(&uio_class);
|
|
uio_major_cleanup();
|
|
}
|
|
@@ -912,6 +918,9 @@ int __uio_register_device(struct module *owner,
|
|
struct uio_device *idev;
|
|
int ret = 0;
|
|
|
|
+ if (!uio_class_registered)
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
if (!parent || !info || !info->name || !info->version)
|
|
return -EINVAL;
|
|
|
|
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
|
|
index 7e7428e48bfa..4f8b8179ec96 100644
|
|
--- a/drivers/usb/chipidea/otg.h
|
|
+++ b/drivers/usb/chipidea/otg.h
|
|
@@ -17,7 +17,8 @@ void ci_handle_vbus_change(struct ci_hdrc *ci);
|
|
static inline void ci_otg_queue_work(struct ci_hdrc *ci)
|
|
{
|
|
disable_irq_nosync(ci->irq);
|
|
- queue_work(ci->wq, &ci->work);
|
|
+ if (queue_work(ci->wq, &ci->work) == false)
|
|
+ enable_irq(ci->irq);
|
|
}
|
|
|
|
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
|
|
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
|
|
index 2bd6e6bfc241..260010abf9d8 100644
|
|
--- a/drivers/usb/dwc2/hcd.c
|
|
+++ b/drivers/usb/dwc2/hcd.c
|
|
@@ -4393,6 +4393,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
|
|
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
|
|
struct usb_bus *bus = hcd_to_bus(hcd);
|
|
unsigned long flags;
|
|
+ int ret;
|
|
|
|
dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
|
|
|
|
@@ -4408,6 +4409,13 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
|
|
|
|
dwc2_hcd_reinit(hsotg);
|
|
|
|
+ /* enable external vbus supply before resuming root hub */
|
|
+ spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
+ ret = dwc2_vbus_supply_init(hsotg);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ spin_lock_irqsave(&hsotg->lock, flags);
|
|
+
|
|
/* Initialize and connect root hub if one is not already attached */
|
|
if (bus->root_hub) {
|
|
dev_dbg(hsotg->dev, "DWC OTG HCD Has Root Hub\n");
|
|
@@ -4417,7 +4425,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
|
|
|
|
spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
- return dwc2_vbus_supply_init(hsotg);
|
|
+ return 0;
|
|
}
|
|
|
|
/*
|
|
@@ -4482,7 +4490,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
|
|
hprt0 |= HPRT0_SUSP;
|
|
hprt0 &= ~HPRT0_PWR;
|
|
dwc2_writel(hsotg, hprt0, HPRT0);
|
|
+ spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
dwc2_vbus_supply_exit(hsotg);
|
|
+ spin_lock_irqsave(&hsotg->lock, flags);
|
|
}
|
|
|
|
/* Enter partial_power_down */
|
|
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
|
|
index 17147b8c771e..8f267be1745d 100644
|
|
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
|
|
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
|
|
@@ -2017,6 +2017,8 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
|
|
|
|
udc->errata = match->data;
|
|
udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc");
|
|
+ if (IS_ERR(udc->pmc))
|
|
+ udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9rl-pmc");
|
|
if (IS_ERR(udc->pmc))
|
|
udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9x5-pmc");
|
|
if (udc->errata && IS_ERR(udc->pmc))
|
|
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
|
|
index e1656f361e08..67d8a501d994 100644
|
|
--- a/drivers/usb/gadget/udc/renesas_usb3.c
|
|
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
|
|
@@ -2437,6 +2437,9 @@ static ssize_t renesas_usb3_b_device_write(struct file *file,
|
|
else
|
|
usb3->forced_b_device = false;
|
|
|
|
+ if (usb3->workaround_for_vbus)
|
|
+ usb3_disconnect(usb3);
|
|
+
|
|
/* Let this driver call usb3_connect() anyway */
|
|
usb3_check_id(usb3);
|
|
|
|
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
|
|
index e98673954020..ec6739ef3129 100644
|
|
--- a/drivers/usb/host/ohci-at91.c
|
|
+++ b/drivers/usb/host/ohci-at91.c
|
|
@@ -551,6 +551,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
|
|
pdata->overcurrent_pin[i] =
|
|
devm_gpiod_get_index_optional(&pdev->dev, "atmel,oc",
|
|
i, GPIOD_IN);
|
|
+ if (!pdata->overcurrent_pin[i])
|
|
+ continue;
|
|
if (IS_ERR(pdata->overcurrent_pin[i])) {
|
|
err = PTR_ERR(pdata->overcurrent_pin[i]);
|
|
dev_err(&pdev->dev, "unable to claim gpio \"overcurrent\": %d\n", err);
|
|
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
|
|
index 7e2a531ba321..12eea73d9f20 100644
|
|
--- a/drivers/usb/host/xhci-hub.c
|
|
+++ b/drivers/usb/host/xhci-hub.c
|
|
@@ -900,6 +900,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
|
|
set_bit(wIndex, &bus_state->resuming_ports);
|
|
bus_state->resume_done[wIndex] = timeout;
|
|
mod_timer(&hcd->rh_timer, timeout);
|
|
+ usb_hcd_start_port_resume(&hcd->self, wIndex);
|
|
}
|
|
/* Has resume been signalled for USB_RESUME_TIME yet? */
|
|
} else if (time_after_eq(jiffies,
|
|
@@ -940,6 +941,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
|
|
clear_bit(wIndex, &bus_state->rexit_ports);
|
|
}
|
|
|
|
+ usb_hcd_end_port_resume(&hcd->self, wIndex);
|
|
bus_state->port_c_suspend |= 1 << wIndex;
|
|
bus_state->suspended_ports &= ~(1 << wIndex);
|
|
} else {
|
|
@@ -962,6 +964,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
|
|
(raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) {
|
|
bus_state->resume_done[wIndex] = 0;
|
|
clear_bit(wIndex, &bus_state->resuming_ports);
|
|
+ usb_hcd_end_port_resume(&hcd->self, wIndex);
|
|
}
|
|
|
|
|
|
@@ -1337,6 +1340,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
goto error;
|
|
|
|
set_bit(wIndex, &bus_state->resuming_ports);
|
|
+ usb_hcd_start_port_resume(&hcd->self, wIndex);
|
|
xhci_set_link_state(xhci, ports[wIndex],
|
|
XDEV_RESUME);
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
@@ -1345,6 +1349,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
xhci_set_link_state(xhci, ports[wIndex],
|
|
XDEV_U0);
|
|
clear_bit(wIndex, &bus_state->resuming_ports);
|
|
+ usb_hcd_end_port_resume(&hcd->self, wIndex);
|
|
}
|
|
bus_state->port_c_suspend |= 1 << wIndex;
|
|
|
|
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
|
|
index f0a99aa0ac58..cd4659703647 100644
|
|
--- a/drivers/usb/host/xhci-ring.c
|
|
+++ b/drivers/usb/host/xhci-ring.c
|
|
@@ -1602,6 +1602,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
|
|
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
|
|
mod_timer(&hcd->rh_timer,
|
|
bus_state->resume_done[hcd_portnum]);
|
|
+ usb_hcd_start_port_resume(&hcd->self, hcd_portnum);
|
|
bogus_port_status = true;
|
|
}
|
|
}
|
|
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
|
|
index 4f1f4215f3d6..c74cc9c309b1 100644
|
|
--- a/drivers/usb/typec/tcpm.c
|
|
+++ b/drivers/usb/typec/tcpm.c
|
|
@@ -1430,8 +1430,8 @@ static enum pdo_err tcpm_caps_err(struct tcpm_port *port, const u32 *pdo,
|
|
if (pdo_apdo_type(pdo[i]) != APDO_TYPE_PPS)
|
|
break;
|
|
|
|
- if (pdo_pps_apdo_max_current(pdo[i]) <
|
|
- pdo_pps_apdo_max_current(pdo[i - 1]))
|
|
+ if (pdo_pps_apdo_max_voltage(pdo[i]) <
|
|
+ pdo_pps_apdo_max_voltage(pdo[i - 1]))
|
|
return PDO_ERR_PPS_APDO_NOT_SORTED;
|
|
else if (pdo_pps_apdo_min_voltage(pdo[i]) ==
|
|
pdo_pps_apdo_min_voltage(pdo[i - 1]) &&
|
|
@@ -4116,6 +4116,9 @@ static int tcpm_pps_set_op_curr(struct tcpm_port *port, u16 op_curr)
|
|
goto port_unlock;
|
|
}
|
|
|
|
+ /* Round down operating current to align with PPS valid steps */
|
|
+ op_curr = op_curr - (op_curr % RDO_PROG_CURR_MA_STEP);
|
|
+
|
|
reinit_completion(&port->pps_complete);
|
|
port->pps_data.op_curr = op_curr;
|
|
port->pps_status = 0;
|
|
@@ -4169,6 +4172,9 @@ static int tcpm_pps_set_out_volt(struct tcpm_port *port, u16 out_volt)
|
|
goto port_unlock;
|
|
}
|
|
|
|
+ /* Round down output voltage to align with PPS valid steps */
|
|
+ out_volt = out_volt - (out_volt % RDO_PROG_VOLT_MV_STEP);
|
|
+
|
|
reinit_completion(&port->pps_complete);
|
|
port->pps_data.out_volt = out_volt;
|
|
port->pps_status = 0;
|
|
diff --git a/drivers/usb/usbip/vudc_main.c b/drivers/usb/usbip/vudc_main.c
|
|
index 3fc22037a82f..390733e6937e 100644
|
|
--- a/drivers/usb/usbip/vudc_main.c
|
|
+++ b/drivers/usb/usbip/vudc_main.c
|
|
@@ -73,6 +73,10 @@ static int __init init(void)
|
|
cleanup:
|
|
list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
|
|
list_del(&udc_dev->dev_entry);
|
|
+ /*
|
|
+ * Just do platform_device_del() here, put_vudc_device()
|
|
+ * calls the platform_device_put()
|
|
+ */
|
|
platform_device_del(udc_dev->pdev);
|
|
put_vudc_device(udc_dev);
|
|
}
|
|
@@ -89,7 +93,11 @@ static void __exit cleanup(void)
|
|
|
|
list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
|
|
list_del(&udc_dev->dev_entry);
|
|
- platform_device_unregister(udc_dev->pdev);
|
|
+ /*
|
|
+ * Just do platform_device_del() here, put_vudc_device()
|
|
+ * calls the platform_device_put()
|
|
+ */
|
|
+ platform_device_del(udc_dev->pdev);
|
|
put_vudc_device(udc_dev);
|
|
}
|
|
platform_driver_unregister(&vudc_driver);
|
|
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
|
|
index 38716eb50408..8a3e8f61b991 100644
|
|
--- a/drivers/video/hdmi.c
|
|
+++ b/drivers/video/hdmi.c
|
|
@@ -592,10 +592,10 @@ hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)
|
|
return "xvYCC 709";
|
|
case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
|
|
return "sYCC 601";
|
|
- case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601:
|
|
- return "Adobe YCC 601";
|
|
- case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB:
|
|
- return "Adobe RGB";
|
|
+ case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
|
|
+ return "opYCC 601";
|
|
+ case HDMI_EXTENDED_COLORIMETRY_OPRGB:
|
|
+ return "opRGB";
|
|
case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
|
|
return "BT.2020 Constant Luminance";
|
|
case HDMI_EXTENDED_COLORIMETRY_BT2020:
|
|
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
|
|
index 83fc9aab34e8..3099052e1243 100644
|
|
--- a/drivers/w1/masters/omap_hdq.c
|
|
+++ b/drivers/w1/masters/omap_hdq.c
|
|
@@ -763,6 +763,8 @@ static int omap_hdq_remove(struct platform_device *pdev)
|
|
/* remove module dependency */
|
|
pm_runtime_disable(&pdev->dev);
|
|
|
|
+ w1_remove_master_device(&omap_w1_master);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/xen/privcmd-buf.c b/drivers/xen/privcmd-buf.c
|
|
index df1ed37c3269..de01a6d0059d 100644
|
|
--- a/drivers/xen/privcmd-buf.c
|
|
+++ b/drivers/xen/privcmd-buf.c
|
|
@@ -21,15 +21,9 @@
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
-static unsigned int limit = 64;
|
|
-module_param(limit, uint, 0644);
|
|
-MODULE_PARM_DESC(limit, "Maximum number of pages that may be allocated by "
|
|
- "the privcmd-buf device per open file");
|
|
-
|
|
struct privcmd_buf_private {
|
|
struct mutex lock;
|
|
struct list_head list;
|
|
- unsigned int allocated;
|
|
};
|
|
|
|
struct privcmd_buf_vma_private {
|
|
@@ -60,13 +54,10 @@ static void privcmd_buf_vmapriv_free(struct privcmd_buf_vma_private *vma_priv)
|
|
{
|
|
unsigned int i;
|
|
|
|
- vma_priv->file_priv->allocated -= vma_priv->n_pages;
|
|
-
|
|
list_del(&vma_priv->list);
|
|
|
|
for (i = 0; i < vma_priv->n_pages; i++)
|
|
- if (vma_priv->pages[i])
|
|
- __free_page(vma_priv->pages[i]);
|
|
+ __free_page(vma_priv->pages[i]);
|
|
|
|
kfree(vma_priv);
|
|
}
|
|
@@ -146,8 +137,7 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma)
|
|
unsigned int i;
|
|
int ret = 0;
|
|
|
|
- if (!(vma->vm_flags & VM_SHARED) || count > limit ||
|
|
- file_priv->allocated + count > limit)
|
|
+ if (!(vma->vm_flags & VM_SHARED))
|
|
return -EINVAL;
|
|
|
|
vma_priv = kzalloc(sizeof(*vma_priv) + count * sizeof(void *),
|
|
@@ -155,19 +145,15 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma)
|
|
if (!vma_priv)
|
|
return -ENOMEM;
|
|
|
|
- vma_priv->n_pages = count;
|
|
- count = 0;
|
|
- for (i = 0; i < vma_priv->n_pages; i++) {
|
|
+ for (i = 0; i < count; i++) {
|
|
vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
|
if (!vma_priv->pages[i])
|
|
break;
|
|
- count++;
|
|
+ vma_priv->n_pages++;
|
|
}
|
|
|
|
mutex_lock(&file_priv->lock);
|
|
|
|
- file_priv->allocated += count;
|
|
-
|
|
vma_priv->file_priv = file_priv;
|
|
vma_priv->users = 1;
|
|
|
|
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
|
|
index a6f9ba85dc4b..aa081f806728 100644
|
|
--- a/drivers/xen/swiotlb-xen.c
|
|
+++ b/drivers/xen/swiotlb-xen.c
|
|
@@ -303,6 +303,9 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
|
|
*/
|
|
flags &= ~(__GFP_DMA | __GFP_HIGHMEM);
|
|
|
|
+ /* Convert the size to actually allocated. */
|
|
+ size = 1UL << (order + XEN_PAGE_SHIFT);
|
|
+
|
|
/* On ARM this function returns an ioremap'ped virtual address for
|
|
* which virt_to_phys doesn't return the corresponding physical
|
|
* address. In fact on ARM virt_to_phys only works for kernel direct
|
|
@@ -351,6 +354,9 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
|
|
* physical address */
|
|
phys = xen_bus_to_phys(dev_addr);
|
|
|
|
+ /* Convert the size to actually allocated. */
|
|
+ size = 1UL << (order + XEN_PAGE_SHIFT);
|
|
+
|
|
if (((dev_addr + size - 1 <= dma_mask)) ||
|
|
range_straddles_page_boundary(phys, size))
|
|
xen_destroy_contiguous_region(phys, order);
|
|
diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c
|
|
index 63c1494a8d73..2acbfe104e46 100644
|
|
--- a/drivers/xen/xen-balloon.c
|
|
+++ b/drivers/xen/xen-balloon.c
|
|
@@ -76,12 +76,15 @@ static void watch_target(struct xenbus_watch *watch,
|
|
|
|
if (!watch_fired) {
|
|
watch_fired = true;
|
|
- err = xenbus_scanf(XBT_NIL, "memory", "static-max", "%llu",
|
|
- &static_max);
|
|
- if (err != 1)
|
|
- static_max = new_target;
|
|
- else
|
|
+
|
|
+ if ((xenbus_scanf(XBT_NIL, "memory", "static-max",
|
|
+ "%llu", &static_max) == 1) ||
|
|
+ (xenbus_scanf(XBT_NIL, "memory", "memory_static_max",
|
|
+ "%llu", &static_max) == 1))
|
|
static_max >>= PAGE_SHIFT - 10;
|
|
+ else
|
|
+ static_max = new_target;
|
|
+
|
|
target_diff = (xen_pv_domain() || xen_initial_domain()) ? 0
|
|
: static_max - balloon_stats.target_pages;
|
|
}
|
|
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
|
|
index d436fb4c002e..089b46c4d97f 100644
|
|
--- a/fs/btrfs/ctree.c
|
|
+++ b/fs/btrfs/ctree.c
|
|
@@ -1050,9 +1050,26 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
|
if ((root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && parent)
|
|
parent_start = parent->start;
|
|
|
|
+ /*
|
|
+ * If we are COWing a node/leaf from the extent, chunk or device trees,
|
|
+ * make sure that we do not finish block group creation of pending block
|
|
+ * groups. We do this to avoid a deadlock.
|
|
+ * COWing can result in allocation of a new chunk, and flushing pending
|
|
+ * block groups (btrfs_create_pending_block_groups()) can be triggered
|
|
+ * when finishing allocation of a new chunk. Creation of a pending block
|
|
+ * group modifies the extent, chunk and device trees, therefore we could
|
|
+ * deadlock with ourselves since we are holding a lock on an extent
|
|
+ * buffer that btrfs_create_pending_block_groups() may try to COW later.
|
|
+ */
|
|
+ if (root == fs_info->extent_root ||
|
|
+ root == fs_info->chunk_root ||
|
|
+ root == fs_info->dev_root)
|
|
+ trans->can_flush_pending_bgs = false;
|
|
+
|
|
cow = btrfs_alloc_tree_block(trans, root, parent_start,
|
|
root->root_key.objectid, &disk_key, level,
|
|
search_start, empty_size);
|
|
+ trans->can_flush_pending_bgs = true;
|
|
if (IS_ERR(cow))
|
|
return PTR_ERR(cow);
|
|
|
|
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
|
|
index dec01970d8c5..981434764bb9 100644
|
|
--- a/fs/btrfs/dev-replace.c
|
|
+++ b/fs/btrfs/dev-replace.c
|
|
@@ -440,6 +440,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
|
|
break;
|
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
|
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
|
|
+ ASSERT(0);
|
|
ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED;
|
|
goto leave;
|
|
}
|
|
@@ -482,6 +483,10 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
|
|
if (IS_ERR(trans)) {
|
|
ret = PTR_ERR(trans);
|
|
btrfs_dev_replace_write_lock(dev_replace);
|
|
+ dev_replace->replace_state =
|
|
+ BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED;
|
|
+ dev_replace->srcdev = NULL;
|
|
+ dev_replace->tgtdev = NULL;
|
|
goto leave;
|
|
}
|
|
|
|
@@ -503,8 +508,6 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
|
|
return ret;
|
|
|
|
leave:
|
|
- dev_replace->srcdev = NULL;
|
|
- dev_replace->tgtdev = NULL;
|
|
btrfs_dev_replace_write_unlock(dev_replace);
|
|
btrfs_destroy_dev_replace_tgtdev(tgt_device);
|
|
return ret;
|
|
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
|
|
index 2d9074295d7f..51e41e53d4ae 100644
|
|
--- a/fs/btrfs/extent-tree.c
|
|
+++ b/fs/btrfs/extent-tree.c
|
|
@@ -2366,6 +2366,9 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
|
|
insert_reserved);
|
|
else
|
|
BUG();
|
|
+ if (ret && insert_reserved)
|
|
+ btrfs_pin_extent(trans->fs_info, node->bytenr,
|
|
+ node->num_bytes, 1);
|
|
return ret;
|
|
}
|
|
|
|
@@ -2911,7 +2914,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
|
|
struct btrfs_delayed_ref_head *head;
|
|
int ret;
|
|
int run_all = count == (unsigned long)-1;
|
|
- bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
|
|
|
|
/* We'll clean this up in btrfs_cleanup_transaction */
|
|
if (trans->aborted)
|
|
@@ -2928,7 +2930,6 @@ again:
|
|
#ifdef SCRAMBLE_DELAYED_REFS
|
|
delayed_refs->run_delayed_start = find_middle(&delayed_refs->root);
|
|
#endif
|
|
- trans->can_flush_pending_bgs = false;
|
|
ret = __btrfs_run_delayed_refs(trans, count);
|
|
if (ret < 0) {
|
|
btrfs_abort_transaction(trans, ret);
|
|
@@ -2959,7 +2960,6 @@ again:
|
|
goto again;
|
|
}
|
|
out:
|
|
- trans->can_flush_pending_bgs = can_flush_pending_bgs;
|
|
return 0;
|
|
}
|
|
|
|
@@ -4533,6 +4533,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
|
|
goto out;
|
|
} else {
|
|
ret = 1;
|
|
+ space_info->max_extent_size = 0;
|
|
}
|
|
|
|
space_info->force_alloc = CHUNK_ALLOC_NO_FORCE;
|
|
@@ -4554,11 +4555,9 @@ out:
|
|
* the block groups that were made dirty during the lifetime of the
|
|
* transaction.
|
|
*/
|
|
- if (trans->can_flush_pending_bgs &&
|
|
- trans->chunk_bytes_reserved >= (u64)SZ_2M) {
|
|
+ if (trans->chunk_bytes_reserved >= (u64)SZ_2M)
|
|
btrfs_create_pending_block_groups(trans);
|
|
- btrfs_trans_release_chunk_metadata(trans);
|
|
- }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
@@ -6436,6 +6435,7 @@ static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache,
|
|
space_info->bytes_readonly += num_bytes;
|
|
cache->reserved -= num_bytes;
|
|
space_info->bytes_reserved -= num_bytes;
|
|
+ space_info->max_extent_size = 0;
|
|
|
|
if (delalloc)
|
|
cache->delalloc_bytes -= num_bytes;
|
|
@@ -7233,6 +7233,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
|
|
struct btrfs_block_group_cache *block_group = NULL;
|
|
u64 search_start = 0;
|
|
u64 max_extent_size = 0;
|
|
+ u64 max_free_space = 0;
|
|
u64 empty_cluster = 0;
|
|
struct btrfs_space_info *space_info;
|
|
int loop = 0;
|
|
@@ -7528,8 +7529,8 @@ unclustered_alloc:
|
|
spin_lock(&ctl->tree_lock);
|
|
if (ctl->free_space <
|
|
num_bytes + empty_cluster + empty_size) {
|
|
- if (ctl->free_space > max_extent_size)
|
|
- max_extent_size = ctl->free_space;
|
|
+ max_free_space = max(max_free_space,
|
|
+ ctl->free_space);
|
|
spin_unlock(&ctl->tree_lock);
|
|
goto loop;
|
|
}
|
|
@@ -7696,6 +7697,8 @@ loop:
|
|
}
|
|
out:
|
|
if (ret == -ENOSPC) {
|
|
+ if (!max_extent_size)
|
|
+ max_extent_size = max_free_space;
|
|
spin_lock(&space_info->lock);
|
|
space_info->max_extent_size = max_extent_size;
|
|
spin_unlock(&space_info->lock);
|
|
@@ -7977,21 +7980,14 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
|
|
}
|
|
|
|
path = btrfs_alloc_path();
|
|
- if (!path) {
|
|
- btrfs_free_and_pin_reserved_extent(fs_info,
|
|
- extent_key.objectid,
|
|
- fs_info->nodesize);
|
|
+ if (!path)
|
|
return -ENOMEM;
|
|
- }
|
|
|
|
path->leave_spinning = 1;
|
|
ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path,
|
|
&extent_key, size);
|
|
if (ret) {
|
|
btrfs_free_path(path);
|
|
- btrfs_free_and_pin_reserved_extent(fs_info,
|
|
- extent_key.objectid,
|
|
- fs_info->nodesize);
|
|
return ret;
|
|
}
|
|
|
|
@@ -8119,6 +8115,19 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
if (IS_ERR(buf))
|
|
return buf;
|
|
|
|
+ /*
|
|
+ * Extra safety check in case the extent tree is corrupted and extent
|
|
+ * allocator chooses to use a tree block which is already used and
|
|
+ * locked.
|
|
+ */
|
|
+ if (buf->lock_owner == current->pid) {
|
|
+ btrfs_err_rl(fs_info,
|
|
+"tree block %llu owner %llu already locked by pid=%d, extent tree corruption detected",
|
|
+ buf->start, btrfs_header_owner(buf), current->pid);
|
|
+ free_extent_buffer(buf);
|
|
+ return ERR_PTR(-EUCLEAN);
|
|
+ }
|
|
+
|
|
btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level);
|
|
btrfs_tree_lock(buf);
|
|
clean_tree_block(fs_info, buf);
|
|
@@ -8763,15 +8772,14 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
|
|
if (eb == root->node) {
|
|
if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF)
|
|
parent = eb->start;
|
|
- else
|
|
- BUG_ON(root->root_key.objectid !=
|
|
- btrfs_header_owner(eb));
|
|
+ else if (root->root_key.objectid != btrfs_header_owner(eb))
|
|
+ goto owner_mismatch;
|
|
} else {
|
|
if (wc->flags[level + 1] & BTRFS_BLOCK_FLAG_FULL_BACKREF)
|
|
parent = path->nodes[level + 1]->start;
|
|
- else
|
|
- BUG_ON(root->root_key.objectid !=
|
|
- btrfs_header_owner(path->nodes[level + 1]));
|
|
+ else if (root->root_key.objectid !=
|
|
+ btrfs_header_owner(path->nodes[level + 1]))
|
|
+ goto owner_mismatch;
|
|
}
|
|
|
|
btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1);
|
|
@@ -8779,6 +8787,11 @@ out:
|
|
wc->refs[level] = 0;
|
|
wc->flags[level] = 0;
|
|
return 0;
|
|
+
|
|
+owner_mismatch:
|
|
+ btrfs_err_rl(fs_info, "unexpected tree owner, have %llu expect %llu",
|
|
+ btrfs_header_owner(eb), root->root_key.objectid);
|
|
+ return -EUCLEAN;
|
|
}
|
|
|
|
static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
|
|
@@ -8832,6 +8845,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
|
|
ret = walk_up_proc(trans, root, path, wc);
|
|
if (ret > 0)
|
|
return 0;
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
if (path->locks[level]) {
|
|
btrfs_tree_unlock_rw(path->nodes[level],
|
|
@@ -9613,6 +9628,7 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info)
|
|
|
|
block_group = btrfs_lookup_first_block_group(info, last);
|
|
while (block_group) {
|
|
+ wait_block_group_cache_done(block_group);
|
|
spin_lock(&block_group->lock);
|
|
if (block_group->iref)
|
|
break;
|
|
@@ -10074,15 +10090,19 @@ error:
|
|
void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
|
|
{
|
|
struct btrfs_fs_info *fs_info = trans->fs_info;
|
|
- struct btrfs_block_group_cache *block_group, *tmp;
|
|
+ struct btrfs_block_group_cache *block_group;
|
|
struct btrfs_root *extent_root = fs_info->extent_root;
|
|
struct btrfs_block_group_item item;
|
|
struct btrfs_key key;
|
|
int ret = 0;
|
|
- bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
|
|
|
|
- trans->can_flush_pending_bgs = false;
|
|
- list_for_each_entry_safe(block_group, tmp, &trans->new_bgs, bg_list) {
|
|
+ if (!trans->can_flush_pending_bgs)
|
|
+ return;
|
|
+
|
|
+ while (!list_empty(&trans->new_bgs)) {
|
|
+ block_group = list_first_entry(&trans->new_bgs,
|
|
+ struct btrfs_block_group_cache,
|
|
+ bg_list);
|
|
if (ret)
|
|
goto next;
|
|
|
|
@@ -10103,7 +10123,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
|
|
next:
|
|
list_del_init(&block_group->bg_list);
|
|
}
|
|
- trans->can_flush_pending_bgs = can_flush_pending_bgs;
|
|
+ btrfs_trans_release_chunk_metadata(trans);
|
|
}
|
|
|
|
int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
|
|
@@ -10753,14 +10773,16 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
|
|
* We don't want a transaction for this since the discard may take a
|
|
* substantial amount of time. We don't require that a transaction be
|
|
* running, but we do need to take a running transaction into account
|
|
- * to ensure that we're not discarding chunks that were released in
|
|
- * the current transaction.
|
|
+ * to ensure that we're not discarding chunks that were released or
|
|
+ * allocated in the current transaction.
|
|
*
|
|
* Holding the chunks lock will prevent other threads from allocating
|
|
* or releasing chunks, but it won't prevent a running transaction
|
|
* from committing and releasing the memory that the pending chunks
|
|
* list head uses. For that, we need to take a reference to the
|
|
- * transaction.
|
|
+ * transaction and hold the commit root sem. We only need to hold
|
|
+ * it while performing the free space search since we have already
|
|
+ * held back allocations.
|
|
*/
|
|
static int btrfs_trim_free_extents(struct btrfs_device *device,
|
|
u64 minlen, u64 *trimmed)
|
|
@@ -10770,6 +10792,10 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
|
|
|
|
*trimmed = 0;
|
|
|
|
+ /* Discard not supported = nothing to do. */
|
|
+ if (!blk_queue_discard(bdev_get_queue(device->bdev)))
|
|
+ return 0;
|
|
+
|
|
/* Not writeable = nothing to do. */
|
|
if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
|
|
return 0;
|
|
@@ -10787,9 +10813,13 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
|
|
|
|
ret = mutex_lock_interruptible(&fs_info->chunk_mutex);
|
|
if (ret)
|
|
- return ret;
|
|
+ break;
|
|
|
|
- down_read(&fs_info->commit_root_sem);
|
|
+ ret = down_read_killable(&fs_info->commit_root_sem);
|
|
+ if (ret) {
|
|
+ mutex_unlock(&fs_info->chunk_mutex);
|
|
+ break;
|
|
+ }
|
|
|
|
spin_lock(&fs_info->trans_lock);
|
|
trans = fs_info->running_transaction;
|
|
@@ -10797,13 +10827,17 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
|
|
refcount_inc(&trans->use_count);
|
|
spin_unlock(&fs_info->trans_lock);
|
|
|
|
+ if (!trans)
|
|
+ up_read(&fs_info->commit_root_sem);
|
|
+
|
|
ret = find_free_dev_extent_start(trans, device, minlen, start,
|
|
&start, &len);
|
|
- if (trans)
|
|
+ if (trans) {
|
|
+ up_read(&fs_info->commit_root_sem);
|
|
btrfs_put_transaction(trans);
|
|
+ }
|
|
|
|
if (ret) {
|
|
- up_read(&fs_info->commit_root_sem);
|
|
mutex_unlock(&fs_info->chunk_mutex);
|
|
if (ret == -ENOSPC)
|
|
ret = 0;
|
|
@@ -10811,7 +10845,6 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
|
|
}
|
|
|
|
ret = btrfs_issue_discard(device->bdev, start, len, &bytes);
|
|
- up_read(&fs_info->commit_root_sem);
|
|
mutex_unlock(&fs_info->chunk_mutex);
|
|
|
|
if (ret)
|
|
@@ -10831,6 +10864,15 @@ static int btrfs_trim_free_extents(struct btrfs_device *device,
|
|
return ret;
|
|
}
|
|
|
|
+/*
|
|
+ * Trim the whole filesystem by:
|
|
+ * 1) trimming the free space in each block group
|
|
+ * 2) trimming the unallocated space on each device
|
|
+ *
|
|
+ * This will also continue trimming even if a block group or device encounters
|
|
+ * an error. The return value will be the last error, or 0 if nothing bad
|
|
+ * happens.
|
|
+ */
|
|
int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
|
|
{
|
|
struct btrfs_block_group_cache *cache = NULL;
|
|
@@ -10840,18 +10882,14 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
|
|
u64 start;
|
|
u64 end;
|
|
u64 trimmed = 0;
|
|
- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
|
|
+ u64 bg_failed = 0;
|
|
+ u64 dev_failed = 0;
|
|
+ int bg_ret = 0;
|
|
+ int dev_ret = 0;
|
|
int ret = 0;
|
|
|
|
- /*
|
|
- * try to trim all FS space, our block group may start from non-zero.
|
|
- */
|
|
- if (range->len == total_bytes)
|
|
- cache = btrfs_lookup_first_block_group(fs_info, range->start);
|
|
- else
|
|
- cache = btrfs_lookup_block_group(fs_info, range->start);
|
|
-
|
|
- while (cache) {
|
|
+ cache = btrfs_lookup_first_block_group(fs_info, range->start);
|
|
+ for (; cache; cache = next_block_group(fs_info, cache)) {
|
|
if (cache->key.objectid >= (range->start + range->len)) {
|
|
btrfs_put_block_group(cache);
|
|
break;
|
|
@@ -10865,13 +10903,15 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
|
|
if (!block_group_cache_done(cache)) {
|
|
ret = cache_block_group(cache, 0);
|
|
if (ret) {
|
|
- btrfs_put_block_group(cache);
|
|
- break;
|
|
+ bg_failed++;
|
|
+ bg_ret = ret;
|
|
+ continue;
|
|
}
|
|
ret = wait_block_group_cache_done(cache);
|
|
if (ret) {
|
|
- btrfs_put_block_group(cache);
|
|
- break;
|
|
+ bg_failed++;
|
|
+ bg_ret = ret;
|
|
+ continue;
|
|
}
|
|
}
|
|
ret = btrfs_trim_block_group(cache,
|
|
@@ -10882,28 +10922,40 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
|
|
|
|
trimmed += group_trimmed;
|
|
if (ret) {
|
|
- btrfs_put_block_group(cache);
|
|
- break;
|
|
+ bg_failed++;
|
|
+ bg_ret = ret;
|
|
+ continue;
|
|
}
|
|
}
|
|
-
|
|
- cache = next_block_group(fs_info, cache);
|
|
}
|
|
|
|
+ if (bg_failed)
|
|
+ btrfs_warn(fs_info,
|
|
+ "failed to trim %llu block group(s), last error %d",
|
|
+ bg_failed, bg_ret);
|
|
mutex_lock(&fs_info->fs_devices->device_list_mutex);
|
|
- devices = &fs_info->fs_devices->alloc_list;
|
|
- list_for_each_entry(device, devices, dev_alloc_list) {
|
|
+ devices = &fs_info->fs_devices->devices;
|
|
+ list_for_each_entry(device, devices, dev_list) {
|
|
ret = btrfs_trim_free_extents(device, range->minlen,
|
|
&group_trimmed);
|
|
- if (ret)
|
|
+ if (ret) {
|
|
+ dev_failed++;
|
|
+ dev_ret = ret;
|
|
break;
|
|
+ }
|
|
|
|
trimmed += group_trimmed;
|
|
}
|
|
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
|
|
|
|
+ if (dev_failed)
|
|
+ btrfs_warn(fs_info,
|
|
+ "failed to trim %llu device(s), last error %d",
|
|
+ dev_failed, dev_ret);
|
|
range->len = trimmed;
|
|
- return ret;
|
|
+ if (bg_ret)
|
|
+ return bg_ret;
|
|
+ return dev_ret;
|
|
}
|
|
|
|
/*
|
|
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
|
|
index 2be00e873e92..7d81cc415264 100644
|
|
--- a/fs/btrfs/file.c
|
|
+++ b/fs/btrfs/file.c
|
|
@@ -531,6 +531,14 @@ int btrfs_dirty_pages(struct inode *inode, struct page **pages,
|
|
|
|
end_of_last_block = start_pos + num_bytes - 1;
|
|
|
|
+ /*
|
|
+ * The pages may have already been dirty, clear out old accounting so
|
|
+ * we can set things up properly
|
|
+ */
|
|
+ clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos, end_of_last_block,
|
|
+ EXTENT_DIRTY | EXTENT_DELALLOC |
|
|
+ EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0, cached);
|
|
+
|
|
if (!btrfs_is_free_space_inode(BTRFS_I(inode))) {
|
|
if (start_pos >= isize &&
|
|
!(BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC)) {
|
|
@@ -1500,18 +1508,27 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages,
|
|
}
|
|
if (ordered)
|
|
btrfs_put_ordered_extent(ordered);
|
|
- clear_extent_bit(&inode->io_tree, start_pos, last_pos,
|
|
- EXTENT_DIRTY | EXTENT_DELALLOC |
|
|
- EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
|
|
- 0, 0, cached_state);
|
|
+
|
|
*lockstart = start_pos;
|
|
*lockend = last_pos;
|
|
ret = 1;
|
|
}
|
|
|
|
+ /*
|
|
+ * It's possible the pages are dirty right now, but we don't want
|
|
+ * to clean them yet because copy_from_user may catch a page fault
|
|
+ * and we might have to fall back to one page at a time. If that
|
|
+ * happens, we'll unlock these pages and we'd have a window where
|
|
+ * reclaim could sneak in and drop the once-dirty page on the floor
|
|
+ * without writing it.
|
|
+ *
|
|
+ * We have the pages locked and the extent range locked, so there's
|
|
+ * no way someone can start IO on any dirty pages in this range.
|
|
+ *
|
|
+ * We'll call btrfs_dirty_pages() later on, and that will flip around
|
|
+ * delalloc bits and dirty the pages as required.
|
|
+ */
|
|
for (i = 0; i < num_pages; i++) {
|
|
- if (clear_page_dirty_for_io(pages[i]))
|
|
- account_page_redirty(pages[i]);
|
|
set_page_extent_mapped(pages[i]);
|
|
WARN_ON(!PageLocked(pages[i]));
|
|
}
|
|
@@ -2061,6 +2078,14 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
goto out;
|
|
|
|
inode_lock(inode);
|
|
+
|
|
+ /*
|
|
+ * We take the dio_sem here because the tree log stuff can race with
|
|
+ * lockless dio writes and get an extent map logged for an extent we
|
|
+ * never waited on. We need it this high up for lockdep reasons.
|
|
+ */
|
|
+ down_write(&BTRFS_I(inode)->dio_sem);
|
|
+
|
|
atomic_inc(&root->log_batch);
|
|
|
|
/*
|
|
@@ -2069,6 +2094,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
*/
|
|
ret = btrfs_wait_ordered_range(inode, start, len);
|
|
if (ret) {
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
goto out;
|
|
}
|
|
@@ -2092,6 +2118,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
* checked called fsync.
|
|
*/
|
|
ret = filemap_check_wb_err(inode->i_mapping, file->f_wb_err);
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
goto out;
|
|
}
|
|
@@ -2110,6 +2137,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
trans = btrfs_start_transaction(root, 0);
|
|
if (IS_ERR(trans)) {
|
|
ret = PTR_ERR(trans);
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
goto out;
|
|
}
|
|
@@ -2131,6 +2159,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
* file again, but that will end up using the synchronization
|
|
* inside btrfs_sync_log to keep things safe.
|
|
*/
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
|
|
/*
|
|
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
|
|
index 0adf38b00fa0..8ecf8c0e5fe6 100644
|
|
--- a/fs/btrfs/free-space-cache.c
|
|
+++ b/fs/btrfs/free-space-cache.c
|
|
@@ -10,6 +10,7 @@
|
|
#include <linux/math64.h>
|
|
#include <linux/ratelimit.h>
|
|
#include <linux/error-injection.h>
|
|
+#include <linux/sched/mm.h>
|
|
#include "ctree.h"
|
|
#include "free-space-cache.h"
|
|
#include "transaction.h"
|
|
@@ -47,6 +48,7 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
|
|
struct btrfs_free_space_header *header;
|
|
struct extent_buffer *leaf;
|
|
struct inode *inode = NULL;
|
|
+ unsigned nofs_flag;
|
|
int ret;
|
|
|
|
key.objectid = BTRFS_FREE_SPACE_OBJECTID;
|
|
@@ -68,7 +70,13 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
|
|
btrfs_disk_key_to_cpu(&location, &disk_key);
|
|
btrfs_release_path(path);
|
|
|
|
+ /*
|
|
+ * We are often under a trans handle at this point, so we need to make
|
|
+ * sure NOFS is set to keep us from deadlocking.
|
|
+ */
|
|
+ nofs_flag = memalloc_nofs_save();
|
|
inode = btrfs_iget(fs_info->sb, &location, root, NULL);
|
|
+ memalloc_nofs_restore(nofs_flag);
|
|
if (IS_ERR(inode))
|
|
return inode;
|
|
|
|
@@ -1679,6 +1687,8 @@ static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
|
|
bitmap_clear(info->bitmap, start, count);
|
|
|
|
info->bytes -= bytes;
|
|
+ if (info->max_extent_size > ctl->unit)
|
|
+ info->max_extent_size = 0;
|
|
}
|
|
|
|
static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
|
|
@@ -1762,6 +1772,13 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
|
|
return -1;
|
|
}
|
|
|
|
+static inline u64 get_max_extent_size(struct btrfs_free_space *entry)
|
|
+{
|
|
+ if (entry->bitmap)
|
|
+ return entry->max_extent_size;
|
|
+ return entry->bytes;
|
|
+}
|
|
+
|
|
/* Cache the size of the max extent in bytes */
|
|
static struct btrfs_free_space *
|
|
find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
|
|
@@ -1783,8 +1800,8 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
|
|
for (node = &entry->offset_index; node; node = rb_next(node)) {
|
|
entry = rb_entry(node, struct btrfs_free_space, offset_index);
|
|
if (entry->bytes < *bytes) {
|
|
- if (entry->bytes > *max_extent_size)
|
|
- *max_extent_size = entry->bytes;
|
|
+ *max_extent_size = max(get_max_extent_size(entry),
|
|
+ *max_extent_size);
|
|
continue;
|
|
}
|
|
|
|
@@ -1802,8 +1819,8 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
|
|
}
|
|
|
|
if (entry->bytes < *bytes + align_off) {
|
|
- if (entry->bytes > *max_extent_size)
|
|
- *max_extent_size = entry->bytes;
|
|
+ *max_extent_size = max(get_max_extent_size(entry),
|
|
+ *max_extent_size);
|
|
continue;
|
|
}
|
|
|
|
@@ -1815,8 +1832,10 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
|
|
*offset = tmp;
|
|
*bytes = size;
|
|
return entry;
|
|
- } else if (size > *max_extent_size) {
|
|
- *max_extent_size = size;
|
|
+ } else {
|
|
+ *max_extent_size =
|
|
+ max(get_max_extent_size(entry),
|
|
+ *max_extent_size);
|
|
}
|
|
continue;
|
|
}
|
|
@@ -2440,6 +2459,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
|
|
struct rb_node *n;
|
|
int count = 0;
|
|
|
|
+ spin_lock(&ctl->tree_lock);
|
|
for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) {
|
|
info = rb_entry(n, struct btrfs_free_space, offset_index);
|
|
if (info->bytes >= bytes && !block_group->ro)
|
|
@@ -2448,6 +2468,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
|
|
info->offset, info->bytes,
|
|
(info->bitmap) ? "yes" : "no");
|
|
}
|
|
+ spin_unlock(&ctl->tree_lock);
|
|
btrfs_info(fs_info, "block group has cluster?: %s",
|
|
list_empty(&block_group->cluster_list) ? "no" : "yes");
|
|
btrfs_info(fs_info,
|
|
@@ -2676,8 +2697,8 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
|
|
|
|
err = search_bitmap(ctl, entry, &search_start, &search_bytes, true);
|
|
if (err) {
|
|
- if (search_bytes > *max_extent_size)
|
|
- *max_extent_size = search_bytes;
|
|
+ *max_extent_size = max(get_max_extent_size(entry),
|
|
+ *max_extent_size);
|
|
return 0;
|
|
}
|
|
|
|
@@ -2714,8 +2735,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
|
|
|
|
entry = rb_entry(node, struct btrfs_free_space, offset_index);
|
|
while (1) {
|
|
- if (entry->bytes < bytes && entry->bytes > *max_extent_size)
|
|
- *max_extent_size = entry->bytes;
|
|
+ if (entry->bytes < bytes)
|
|
+ *max_extent_size = max(get_max_extent_size(entry),
|
|
+ *max_extent_size);
|
|
|
|
if (entry->bytes < bytes ||
|
|
(!entry->bitmap && entry->offset < min_start)) {
|
|
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
|
|
index 3ea5339603cf..83268d8f48c4 100644
|
|
--- a/fs/btrfs/inode.c
|
|
+++ b/fs/btrfs/inode.c
|
|
@@ -503,6 +503,7 @@ again:
|
|
pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
|
|
if (!pages) {
|
|
/* just bail out to the uncompressed code */
|
|
+ nr_pages = 0;
|
|
goto cont;
|
|
}
|
|
|
|
@@ -2944,6 +2945,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
|
|
bool truncated = false;
|
|
bool range_locked = false;
|
|
bool clear_new_delalloc_bytes = false;
|
|
+ bool clear_reserved_extent = true;
|
|
|
|
if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
|
|
!test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags) &&
|
|
@@ -3047,10 +3049,12 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
|
|
logical_len, logical_len,
|
|
compress_type, 0, 0,
|
|
BTRFS_FILE_EXTENT_REG);
|
|
- if (!ret)
|
|
+ if (!ret) {
|
|
+ clear_reserved_extent = false;
|
|
btrfs_release_delalloc_bytes(fs_info,
|
|
ordered_extent->start,
|
|
ordered_extent->disk_len);
|
|
+ }
|
|
}
|
|
unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
|
|
ordered_extent->file_offset, ordered_extent->len,
|
|
@@ -3111,8 +3115,13 @@ out:
|
|
* wrong we need to return the space for this ordered extent
|
|
* back to the allocator. We only free the extent in the
|
|
* truncated case if we didn't write out the extent at all.
|
|
+ *
|
|
+ * If we made it past insert_reserved_file_extent before we
|
|
+ * errored out then we don't need to do this as the accounting
|
|
+ * has already been done.
|
|
*/
|
|
if ((ret || !logical_len) &&
|
|
+ clear_reserved_extent &&
|
|
!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
|
|
!test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags))
|
|
btrfs_free_reserved_extent(fs_info,
|
|
@@ -5274,11 +5283,13 @@ static void evict_inode_truncate_pages(struct inode *inode)
|
|
struct extent_state *cached_state = NULL;
|
|
u64 start;
|
|
u64 end;
|
|
+ unsigned state_flags;
|
|
|
|
node = rb_first(&io_tree->state);
|
|
state = rb_entry(node, struct extent_state, rb_node);
|
|
start = state->start;
|
|
end = state->end;
|
|
+ state_flags = state->state;
|
|
spin_unlock(&io_tree->lock);
|
|
|
|
lock_extent_bits(io_tree, start, end, &cached_state);
|
|
@@ -5291,7 +5302,7 @@ static void evict_inode_truncate_pages(struct inode *inode)
|
|
*
|
|
* Note, end is the bytenr of last byte, so we need + 1 here.
|
|
*/
|
|
- if (state->state & EXTENT_DELALLOC)
|
|
+ if (state_flags & EXTENT_DELALLOC)
|
|
btrfs_qgroup_free_data(inode, NULL, start, end - start + 1);
|
|
|
|
clear_extent_bit(io_tree, start, end,
|
|
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
|
|
index d60b6caf09e8..bd4767f562cd 100644
|
|
--- a/fs/btrfs/ioctl.c
|
|
+++ b/fs/btrfs/ioctl.c
|
|
@@ -491,7 +491,6 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
|
|
struct fstrim_range range;
|
|
u64 minlen = ULLONG_MAX;
|
|
u64 num_devices = 0;
|
|
- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
|
|
int ret;
|
|
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
@@ -515,11 +514,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
|
|
return -EOPNOTSUPP;
|
|
if (copy_from_user(&range, arg, sizeof(range)))
|
|
return -EFAULT;
|
|
- if (range.start > total_bytes ||
|
|
- range.len < fs_info->sb->s_blocksize)
|
|
+
|
|
+ /*
|
|
+ * NOTE: Don't truncate the range using super->total_bytes. Bytenr of
|
|
+ * block group is in the logical address space, which can be any
|
|
+ * sectorsize aligned bytenr in the range [0, U64_MAX].
|
|
+ */
|
|
+ if (range.len < fs_info->sb->s_blocksize)
|
|
return -EINVAL;
|
|
|
|
- range.len = min(range.len, total_bytes - range.start);
|
|
range.minlen = max(range.minlen, minlen);
|
|
ret = btrfs_trim_fs(fs_info, &range);
|
|
if (ret < 0)
|
|
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
|
|
index d4917c0cddf5..b070401406be 100644
|
|
--- a/fs/btrfs/qgroup.c
|
|
+++ b/fs/btrfs/qgroup.c
|
|
@@ -2897,6 +2897,7 @@ qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info)
|
|
qgroup->rfer_cmpr = 0;
|
|
qgroup->excl = 0;
|
|
qgroup->excl_cmpr = 0;
|
|
+ qgroup_dirty(fs_info, qgroup);
|
|
}
|
|
spin_unlock(&fs_info->qgroup_lock);
|
|
}
|
|
@@ -3106,6 +3107,10 @@ static int __btrfs_qgroup_release_data(struct inode *inode,
|
|
int trace_op = QGROUP_RELEASE;
|
|
int ret;
|
|
|
|
+ if (!test_bit(BTRFS_FS_QUOTA_ENABLED,
|
|
+ &BTRFS_I(inode)->root->fs_info->flags))
|
|
+ return 0;
|
|
+
|
|
/* In release case, we shouldn't have @reserved */
|
|
WARN_ON(!free && reserved);
|
|
if (free && reserved)
|
|
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
|
|
index 54b8bb282c0e..4bbcc1e92a93 100644
|
|
--- a/fs/btrfs/qgroup.h
|
|
+++ b/fs/btrfs/qgroup.h
|
|
@@ -249,6 +249,8 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info,
|
|
static inline void btrfs_qgroup_free_delayed_ref(struct btrfs_fs_info *fs_info,
|
|
u64 ref_root, u64 num_bytes)
|
|
{
|
|
+ if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
+ return;
|
|
trace_btrfs_qgroup_free_delayed_ref(fs_info, ref_root, num_bytes);
|
|
btrfs_qgroup_free_refroot(fs_info, ref_root, num_bytes,
|
|
BTRFS_QGROUP_RSV_DATA);
|
|
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
|
|
index 8783a1776540..60bf8dfe7df4 100644
|
|
--- a/fs/btrfs/relocation.c
|
|
+++ b/fs/btrfs/relocation.c
|
|
@@ -1281,7 +1281,7 @@ static void __del_reloc_root(struct btrfs_root *root)
|
|
struct mapping_node *node = NULL;
|
|
struct reloc_control *rc = fs_info->reloc_ctl;
|
|
|
|
- if (rc) {
|
|
+ if (rc && root->node) {
|
|
spin_lock(&rc->reloc_root_tree.lock);
|
|
rb_node = tree_search(&rc->reloc_root_tree.rb_root,
|
|
root->node->start);
|
|
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
|
|
index 3b84f5015029..bb8f6c020d22 100644
|
|
--- a/fs/btrfs/transaction.c
|
|
+++ b/fs/btrfs/transaction.c
|
|
@@ -1929,6 +1929,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
|
return ret;
|
|
}
|
|
|
|
+ btrfs_trans_release_metadata(trans);
|
|
+ trans->block_rsv = NULL;
|
|
+
|
|
/* make a pass through all the delayed refs we have so far
|
|
* any runnings procs may add more while we are here
|
|
*/
|
|
@@ -1938,9 +1941,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
|
return ret;
|
|
}
|
|
|
|
- btrfs_trans_release_metadata(trans);
|
|
- trans->block_rsv = NULL;
|
|
-
|
|
cur_trans = trans->transaction;
|
|
|
|
/*
|
|
@@ -2280,15 +2280,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
|
|
|
kmem_cache_free(btrfs_trans_handle_cachep, trans);
|
|
|
|
- /*
|
|
- * If fs has been frozen, we can not handle delayed iputs, otherwise
|
|
- * it'll result in deadlock about SB_FREEZE_FS.
|
|
- */
|
|
- if (current != fs_info->transaction_kthread &&
|
|
- current != fs_info->cleaner_kthread &&
|
|
- !test_bit(BTRFS_FS_FROZEN, &fs_info->flags))
|
|
- btrfs_run_delayed_iputs(fs_info);
|
|
-
|
|
return ret;
|
|
|
|
scrub_continue:
|
|
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
|
|
index 3c2ae0e4f25a..d0bcfbfc0e3a 100644
|
|
--- a/fs/btrfs/tree-log.c
|
|
+++ b/fs/btrfs/tree-log.c
|
|
@@ -258,6 +258,13 @@ struct walk_control {
|
|
/* what stage of the replay code we're currently in */
|
|
int stage;
|
|
|
|
+ /*
|
|
+ * Ignore any items from the inode currently being processed. Needs
|
|
+ * to be set every time we find a BTRFS_INODE_ITEM_KEY and we are in
|
|
+ * the LOG_WALK_REPLAY_INODES stage.
|
|
+ */
|
|
+ bool ignore_cur_inode;
|
|
+
|
|
/* the root we are currently replaying */
|
|
struct btrfs_root *replay_dest;
|
|
|
|
@@ -2487,6 +2494,20 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
|
|
|
|
inode_item = btrfs_item_ptr(eb, i,
|
|
struct btrfs_inode_item);
|
|
+ /*
|
|
+ * If we have a tmpfile (O_TMPFILE) that got fsync'ed
|
|
+ * and never got linked before the fsync, skip it, as
|
|
+ * replaying it is pointless since it would be deleted
|
|
+ * later. We skip logging tmpfiles, but it's always
|
|
+ * possible we are replaying a log created with a kernel
|
|
+ * that used to log tmpfiles.
|
|
+ */
|
|
+ if (btrfs_inode_nlink(eb, inode_item) == 0) {
|
|
+ wc->ignore_cur_inode = true;
|
|
+ continue;
|
|
+ } else {
|
|
+ wc->ignore_cur_inode = false;
|
|
+ }
|
|
ret = replay_xattr_deletes(wc->trans, root, log,
|
|
path, key.objectid);
|
|
if (ret)
|
|
@@ -2524,16 +2545,8 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
|
|
root->fs_info->sectorsize);
|
|
ret = btrfs_drop_extents(wc->trans, root, inode,
|
|
from, (u64)-1, 1);
|
|
- /*
|
|
- * If the nlink count is zero here, the iput
|
|
- * will free the inode. We bump it to make
|
|
- * sure it doesn't get freed until the link
|
|
- * count fixup is done.
|
|
- */
|
|
if (!ret) {
|
|
- if (inode->i_nlink == 0)
|
|
- inc_nlink(inode);
|
|
- /* Update link count and nbytes. */
|
|
+ /* Update the inode's nbytes. */
|
|
ret = btrfs_update_inode(wc->trans,
|
|
root, inode);
|
|
}
|
|
@@ -2548,6 +2561,9 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
|
|
break;
|
|
}
|
|
|
|
+ if (wc->ignore_cur_inode)
|
|
+ continue;
|
|
+
|
|
if (key.type == BTRFS_DIR_INDEX_KEY &&
|
|
wc->stage == LOG_WALK_REPLAY_DIR_INDEX) {
|
|
ret = replay_one_dir_item(wc->trans, root, path,
|
|
@@ -3196,9 +3212,12 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
|
|
};
|
|
|
|
ret = walk_log_tree(trans, log, &wc);
|
|
- /* I don't think this can happen but just in case */
|
|
- if (ret)
|
|
- btrfs_abort_transaction(trans, ret);
|
|
+ if (ret) {
|
|
+ if (trans)
|
|
+ btrfs_abort_transaction(trans, ret);
|
|
+ else
|
|
+ btrfs_handle_fs_error(log->fs_info, ret, NULL);
|
|
+ }
|
|
|
|
while (1) {
|
|
ret = find_first_extent_bit(&log->dirty_log_pages,
|
|
@@ -4374,7 +4393,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
|
|
|
INIT_LIST_HEAD(&extents);
|
|
|
|
- down_write(&inode->dio_sem);
|
|
write_lock(&tree->lock);
|
|
test_gen = root->fs_info->last_trans_committed;
|
|
logged_start = start;
|
|
@@ -4440,7 +4458,6 @@ process:
|
|
}
|
|
WARN_ON(!list_empty(&extents));
|
|
write_unlock(&tree->lock);
|
|
- up_write(&inode->dio_sem);
|
|
|
|
btrfs_release_path(path);
|
|
if (!ret)
|
|
@@ -4636,7 +4653,8 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
|
|
ASSERT(len == i_size ||
|
|
(len == fs_info->sectorsize &&
|
|
btrfs_file_extent_compression(leaf, extent) !=
|
|
- BTRFS_COMPRESS_NONE));
|
|
+ BTRFS_COMPRESS_NONE) ||
|
|
+ (len < i_size && i_size < fs_info->sectorsize));
|
|
return 0;
|
|
}
|
|
|
|
@@ -5564,9 +5582,33 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
|
|
|
|
dir_inode = btrfs_iget(fs_info->sb, &inode_key,
|
|
root, NULL);
|
|
- /* If parent inode was deleted, skip it. */
|
|
- if (IS_ERR(dir_inode))
|
|
- continue;
|
|
+ /*
|
|
+ * If the parent inode was deleted, return an error to
|
|
+ * fallback to a transaction commit. This is to prevent
|
|
+ * getting an inode that was moved from one parent A to
|
|
+ * a parent B, got its former parent A deleted and then
|
|
+ * it got fsync'ed, from existing at both parents after
|
|
+ * a log replay (and the old parent still existing).
|
|
+ * Example:
|
|
+ *
|
|
+ * mkdir /mnt/A
|
|
+ * mkdir /mnt/B
|
|
+ * touch /mnt/B/bar
|
|
+ * sync
|
|
+ * mv /mnt/B/bar /mnt/A/bar
|
|
+ * mv -T /mnt/A /mnt/B
|
|
+ * fsync /mnt/B/bar
|
|
+ * <power fail>
|
|
+ *
|
|
+ * If we ignore the old parent B which got deleted,
|
|
+ * after a log replay we would have file bar linked
|
|
+ * at both parents and the old parent B would still
|
|
+ * exist.
|
|
+ */
|
|
+ if (IS_ERR(dir_inode)) {
|
|
+ ret = PTR_ERR(dir_inode);
|
|
+ goto out;
|
|
+ }
|
|
|
|
if (ctx)
|
|
ctx->log_new_dentries = false;
|
|
@@ -5640,7 +5682,13 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
|
|
if (ret)
|
|
goto end_no_trans;
|
|
|
|
- if (btrfs_inode_in_log(inode, trans->transid)) {
|
|
+ /*
|
|
+ * Skip already logged inodes or inodes corresponding to tmpfiles
|
|
+ * (since logging them is pointless, a link count of 0 means they
|
|
+ * will never be accessible).
|
|
+ */
|
|
+ if (btrfs_inode_in_log(inode, trans->transid) ||
|
|
+ inode->vfs_inode.i_nlink == 0) {
|
|
ret = BTRFS_NO_LOG_SYNC;
|
|
goto end_no_trans;
|
|
}
|
|
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
|
|
index f1fbea947fef..06576797cf31 100644
|
|
--- a/fs/cifs/cifs_debug.c
|
|
+++ b/fs/cifs/cifs_debug.c
|
|
@@ -383,6 +383,9 @@ static ssize_t cifs_stats_proc_write(struct file *file,
|
|
atomic_set(&totBufAllocCount, 0);
|
|
atomic_set(&totSmBufAllocCount, 0);
|
|
#endif /* CONFIG_CIFS_STATS2 */
|
|
+ atomic_set(&tcpSesReconnectCount, 0);
|
|
+ atomic_set(&tconInfoReconnectCount, 0);
|
|
+
|
|
spin_lock(&GlobalMid_Lock);
|
|
GlobalMaxActiveXid = 0;
|
|
GlobalCurrentXid = 0;
|
|
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
|
|
index b611fc2e8984..7f01c6e60791 100644
|
|
--- a/fs/cifs/cifs_spnego.c
|
|
+++ b/fs/cifs/cifs_spnego.c
|
|
@@ -147,8 +147,10 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
|
|
sprintf(dp, ";sec=krb5");
|
|
else if (server->sec_mskerberos)
|
|
sprintf(dp, ";sec=mskrb5");
|
|
- else
|
|
- goto out;
|
|
+ else {
|
|
+ cifs_dbg(VFS, "unknown or missing server auth type, use krb5\n");
|
|
+ sprintf(dp, ";sec=krb5");
|
|
+ }
|
|
|
|
dp = description + strlen(description);
|
|
sprintf(dp, ";uid=0x%x",
|
|
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
|
|
index 6e8765f44508..020f49c15b30 100644
|
|
--- a/fs/cifs/inode.c
|
|
+++ b/fs/cifs/inode.c
|
|
@@ -777,7 +777,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
|
} else if (rc == -EREMOTE) {
|
|
cifs_create_dfs_fattr(&fattr, sb);
|
|
rc = 0;
|
|
- } else if (rc == -EACCES && backup_cred(cifs_sb)) {
|
|
+ } else if ((rc == -EACCES) && backup_cred(cifs_sb) &&
|
|
+ (strcmp(server->vals->version_string, SMB1_VERSION_STRING)
|
|
+ == 0)) {
|
|
+ /*
|
|
+ * For SMB2 and later the backup intent flag is already
|
|
+ * sent if needed on open and there is no path based
|
|
+ * FindFirst operation to use to retry with
|
|
+ */
|
|
+
|
|
srchinf = kzalloc(sizeof(struct cifs_search_info),
|
|
GFP_KERNEL);
|
|
if (srchinf == NULL) {
|
|
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
|
|
index b48f43963da6..333729cf46cd 100644
|
|
--- a/fs/cifs/transport.c
|
|
+++ b/fs/cifs/transport.c
|
|
@@ -786,7 +786,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
|
int i, j, rc = 0;
|
|
int timeout, optype;
|
|
struct mid_q_entry *midQ[MAX_COMPOUND];
|
|
- unsigned int credits = 1;
|
|
+ unsigned int credits = 0;
|
|
char *buf;
|
|
|
|
timeout = flags & CIFS_TIMEOUT_MASK;
|
|
@@ -851,17 +851,20 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
|
|
|
mutex_unlock(&ses->server->srv_mutex);
|
|
|
|
- for (i = 0; i < num_rqst; i++) {
|
|
- if (rc < 0)
|
|
- goto out;
|
|
+ if (rc < 0)
|
|
+ goto out;
|
|
|
|
- if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
|
|
- smb311_update_preauth_hash(ses, rqst[i].rq_iov,
|
|
- rqst[i].rq_nvec);
|
|
+ /*
|
|
+ * Compounding is never used during session establish.
|
|
+ */
|
|
+ if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
|
|
+ smb311_update_preauth_hash(ses, rqst[0].rq_iov,
|
|
+ rqst[0].rq_nvec);
|
|
|
|
- if (timeout == CIFS_ASYNC_OP)
|
|
- goto out;
|
|
+ if (timeout == CIFS_ASYNC_OP)
|
|
+ goto out;
|
|
|
|
+ for (i = 0; i < num_rqst; i++) {
|
|
rc = wait_for_response(ses->server, midQ[i]);
|
|
if (rc != 0) {
|
|
cifs_dbg(FYI, "Cancelling wait for mid %llu\n",
|
|
@@ -877,10 +880,21 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
|
}
|
|
spin_unlock(&GlobalMid_Lock);
|
|
}
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < num_rqst; i++)
|
|
+ if (midQ[i]->resp_buf)
|
|
+ credits += ses->server->ops->get_credits(midQ[i]);
|
|
+ if (!credits)
|
|
+ credits = 1;
|
|
+
|
|
+ for (i = 0; i < num_rqst; i++) {
|
|
+ if (rc < 0)
|
|
+ goto out;
|
|
|
|
rc = cifs_sync_mid_result(midQ[i], ses->server);
|
|
if (rc != 0) {
|
|
- add_credits(ses->server, 1, optype);
|
|
+ add_credits(ses->server, credits, optype);
|
|
return rc;
|
|
}
|
|
|
|
@@ -901,23 +915,26 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
|
else
|
|
resp_buf_type[i] = CIFS_SMALL_BUFFER;
|
|
|
|
- if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
|
|
- struct kvec iov = {
|
|
- .iov_base = resp_iov[i].iov_base,
|
|
- .iov_len = resp_iov[i].iov_len
|
|
- };
|
|
- smb311_update_preauth_hash(ses, &iov, 1);
|
|
- }
|
|
-
|
|
- credits = ses->server->ops->get_credits(midQ[i]);
|
|
-
|
|
rc = ses->server->ops->check_receive(midQ[i], ses->server,
|
|
flags & CIFS_LOG_ERROR);
|
|
|
|
/* mark it so buf will not be freed by cifs_delete_mid */
|
|
if ((flags & CIFS_NO_RESP) == 0)
|
|
midQ[i]->resp_buf = NULL;
|
|
+
|
|
}
|
|
+
|
|
+ /*
|
|
+ * Compounding is never used during session establish.
|
|
+ */
|
|
+ if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
|
|
+ struct kvec iov = {
|
|
+ .iov_base = resp_iov[0].iov_base,
|
|
+ .iov_len = resp_iov[0].iov_len
|
|
+ };
|
|
+ smb311_update_preauth_hash(ses, &iov, 1);
|
|
+ }
|
|
+
|
|
out:
|
|
/*
|
|
* This will dequeue all mids. After this it is important that the
|
|
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
|
|
index f408994fc632..6e000392e4a4 100644
|
|
--- a/fs/cramfs/inode.c
|
|
+++ b/fs/cramfs/inode.c
|
|
@@ -202,7 +202,8 @@ static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset,
|
|
continue;
|
|
blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_SHIFT;
|
|
blk_offset += offset;
|
|
- if (blk_offset + len > BUFFER_SIZE)
|
|
+ if (blk_offset > BUFFER_SIZE ||
|
|
+ blk_offset + len > BUFFER_SIZE)
|
|
continue;
|
|
return read_buffers[i] + blk_offset;
|
|
}
|
|
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
|
|
index 39c20ef26db4..79debfc9cef9 100644
|
|
--- a/fs/crypto/fscrypt_private.h
|
|
+++ b/fs/crypto/fscrypt_private.h
|
|
@@ -83,10 +83,6 @@ static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
|
|
filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
|
|
return true;
|
|
|
|
- if (contents_mode == FS_ENCRYPTION_MODE_SPECK128_256_XTS &&
|
|
- filenames_mode == FS_ENCRYPTION_MODE_SPECK128_256_CTS)
|
|
- return true;
|
|
-
|
|
return false;
|
|
}
|
|
|
|
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
|
|
index e997ca51192f..7874c9bb2fc5 100644
|
|
--- a/fs/crypto/keyinfo.c
|
|
+++ b/fs/crypto/keyinfo.c
|
|
@@ -174,16 +174,6 @@ static struct fscrypt_mode {
|
|
.cipher_str = "cts(cbc(aes))",
|
|
.keysize = 16,
|
|
},
|
|
- [FS_ENCRYPTION_MODE_SPECK128_256_XTS] = {
|
|
- .friendly_name = "Speck128/256-XTS",
|
|
- .cipher_str = "xts(speck128)",
|
|
- .keysize = 64,
|
|
- },
|
|
- [FS_ENCRYPTION_MODE_SPECK128_256_CTS] = {
|
|
- .friendly_name = "Speck128/256-CTS-CBC",
|
|
- .cipher_str = "cts(cbc(speck128))",
|
|
- .keysize = 32,
|
|
- },
|
|
};
|
|
|
|
static struct fscrypt_mode *
|
|
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
|
|
index caff935fbeb8..5cfb1e2f6a5b 100644
|
|
--- a/fs/ext4/ext4.h
|
|
+++ b/fs/ext4/ext4.h
|
|
@@ -1401,7 +1401,8 @@ struct ext4_sb_info {
|
|
u32 s_min_batch_time;
|
|
struct block_device *journal_bdev;
|
|
#ifdef CONFIG_QUOTA
|
|
- char *s_qf_names[EXT4_MAXQUOTAS]; /* Names of quota files with journalled quota */
|
|
+ /* Names of quota files with journalled quota */
|
|
+ char __rcu *s_qf_names[EXT4_MAXQUOTAS];
|
|
int s_jquota_fmt; /* Format of quota to use */
|
|
#endif
|
|
unsigned int s_want_extra_isize; /* New inodes should reserve # bytes */
|
|
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
|
|
index 7b4736022761..9c4bac18cc6c 100644
|
|
--- a/fs/ext4/inline.c
|
|
+++ b/fs/ext4/inline.c
|
|
@@ -863,7 +863,7 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
|
handle_t *handle;
|
|
struct page *page;
|
|
struct ext4_iloc iloc;
|
|
- int retries;
|
|
+ int retries = 0;
|
|
|
|
ret = ext4_get_inode_loc(inode, &iloc);
|
|
if (ret)
|
|
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
|
|
index a7074115d6f6..0edee31913d1 100644
|
|
--- a/fs/ext4/ioctl.c
|
|
+++ b/fs/ext4/ioctl.c
|
|
@@ -67,7 +67,6 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2)
|
|
ei1 = EXT4_I(inode1);
|
|
ei2 = EXT4_I(inode2);
|
|
|
|
- swap(inode1->i_flags, inode2->i_flags);
|
|
swap(inode1->i_version, inode2->i_version);
|
|
swap(inode1->i_blocks, inode2->i_blocks);
|
|
swap(inode1->i_bytes, inode2->i_bytes);
|
|
@@ -85,6 +84,21 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2)
|
|
i_size_write(inode2, isize);
|
|
}
|
|
|
|
+static void reset_inode_seed(struct inode *inode)
|
|
+{
|
|
+ struct ext4_inode_info *ei = EXT4_I(inode);
|
|
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
|
+ __le32 inum = cpu_to_le32(inode->i_ino);
|
|
+ __le32 gen = cpu_to_le32(inode->i_generation);
|
|
+ __u32 csum;
|
|
+
|
|
+ if (!ext4_has_metadata_csum(inode->i_sb))
|
|
+ return;
|
|
+
|
|
+ csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&inum, sizeof(inum));
|
|
+ ei->i_csum_seed = ext4_chksum(sbi, csum, (__u8 *)&gen, sizeof(gen));
|
|
+}
|
|
+
|
|
/**
|
|
* Swap the information from the given @inode and the inode
|
|
* EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other
|
|
@@ -102,10 +116,13 @@ static long swap_inode_boot_loader(struct super_block *sb,
|
|
struct inode *inode_bl;
|
|
struct ext4_inode_info *ei_bl;
|
|
|
|
- if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode))
|
|
+ if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
|
|
+ IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
|
|
+ ext4_has_inline_data(inode))
|
|
return -EINVAL;
|
|
|
|
- if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
|
|
+ if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
|
|
+ !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
|
|
return -EPERM;
|
|
|
|
inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO);
|
|
@@ -120,13 +137,13 @@ static long swap_inode_boot_loader(struct super_block *sb,
|
|
* that only 1 swap_inode_boot_loader is running. */
|
|
lock_two_nondirectories(inode, inode_bl);
|
|
|
|
- truncate_inode_pages(&inode->i_data, 0);
|
|
- truncate_inode_pages(&inode_bl->i_data, 0);
|
|
-
|
|
/* Wait for all existing dio workers */
|
|
inode_dio_wait(inode);
|
|
inode_dio_wait(inode_bl);
|
|
|
|
+ truncate_inode_pages(&inode->i_data, 0);
|
|
+ truncate_inode_pages(&inode_bl->i_data, 0);
|
|
+
|
|
handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
|
|
if (IS_ERR(handle)) {
|
|
err = -EINVAL;
|
|
@@ -159,6 +176,8 @@ static long swap_inode_boot_loader(struct super_block *sb,
|
|
|
|
inode->i_generation = prandom_u32();
|
|
inode_bl->i_generation = prandom_u32();
|
|
+ reset_inode_seed(inode);
|
|
+ reset_inode_seed(inode_bl);
|
|
|
|
ext4_discard_preallocations(inode);
|
|
|
|
@@ -169,6 +188,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
|
|
inode->i_ino, err);
|
|
/* Revert all changes: */
|
|
swap_inode_data(inode, inode_bl);
|
|
+ ext4_mark_inode_dirty(handle, inode);
|
|
} else {
|
|
err = ext4_mark_inode_dirty(handle, inode_bl);
|
|
if (err < 0) {
|
|
@@ -178,6 +198,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
|
|
/* Revert all changes: */
|
|
swap_inode_data(inode, inode_bl);
|
|
ext4_mark_inode_dirty(handle, inode);
|
|
+ ext4_mark_inode_dirty(handle, inode_bl);
|
|
}
|
|
}
|
|
ext4_journal_stop(handle);
|
|
@@ -339,19 +360,14 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
|
|
if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
|
|
return 0;
|
|
|
|
- err = mnt_want_write_file(filp);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
err = -EPERM;
|
|
- inode_lock(inode);
|
|
/* Is it quota file? Do not allow user to mess with it */
|
|
if (ext4_is_quota_file(inode))
|
|
- goto out_unlock;
|
|
+ return err;
|
|
|
|
err = ext4_get_inode_loc(inode, &iloc);
|
|
if (err)
|
|
- goto out_unlock;
|
|
+ return err;
|
|
|
|
raw_inode = ext4_raw_inode(&iloc);
|
|
if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
|
|
@@ -359,20 +375,20 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
|
|
EXT4_SB(sb)->s_want_extra_isize,
|
|
&iloc);
|
|
if (err)
|
|
- goto out_unlock;
|
|
+ return err;
|
|
} else {
|
|
brelse(iloc.bh);
|
|
}
|
|
|
|
- dquot_initialize(inode);
|
|
+ err = dquot_initialize(inode);
|
|
+ if (err)
|
|
+ return err;
|
|
|
|
handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
|
|
EXT4_QUOTA_INIT_BLOCKS(sb) +
|
|
EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
|
|
- if (IS_ERR(handle)) {
|
|
- err = PTR_ERR(handle);
|
|
- goto out_unlock;
|
|
- }
|
|
+ if (IS_ERR(handle))
|
|
+ return PTR_ERR(handle);
|
|
|
|
err = ext4_reserve_inode_write(handle, inode, &iloc);
|
|
if (err)
|
|
@@ -400,9 +416,6 @@ out_dirty:
|
|
err = rc;
|
|
out_stop:
|
|
ext4_journal_stop(handle);
|
|
-out_unlock:
|
|
- inode_unlock(inode);
|
|
- mnt_drop_write_file(filp);
|
|
return err;
|
|
}
|
|
#else
|
|
@@ -626,6 +639,30 @@ group_add_out:
|
|
return err;
|
|
}
|
|
|
|
+static int ext4_ioctl_check_project(struct inode *inode, struct fsxattr *fa)
|
|
+{
|
|
+ /*
|
|
+ * Project Quota ID state is only allowed to change from within the init
|
|
+ * namespace. Enforce that restriction only if we are trying to change
|
|
+ * the quota ID state. Everything else is allowed in user namespaces.
|
|
+ */
|
|
+ if (current_user_ns() == &init_user_ns)
|
|
+ return 0;
|
|
+
|
|
+ if (__kprojid_val(EXT4_I(inode)->i_projid) != fa->fsx_projid)
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (ext4_test_inode_flag(inode, EXT4_INODE_PROJINHERIT)) {
|
|
+ if (!(fa->fsx_xflags & FS_XFLAG_PROJINHERIT))
|
|
+ return -EINVAL;
|
|
+ } else {
|
|
+ if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT)
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
struct inode *inode = file_inode(filp);
|
|
@@ -1025,19 +1062,19 @@ resizefs_out:
|
|
return err;
|
|
|
|
inode_lock(inode);
|
|
+ err = ext4_ioctl_check_project(inode, &fa);
|
|
+ if (err)
|
|
+ goto out;
|
|
flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
|
|
(flags & EXT4_FL_XFLAG_VISIBLE);
|
|
err = ext4_ioctl_setflags(inode, flags);
|
|
- inode_unlock(inode);
|
|
- mnt_drop_write_file(filp);
|
|
if (err)
|
|
- return err;
|
|
-
|
|
+ goto out;
|
|
err = ext4_ioctl_setproject(filp, fa.fsx_projid);
|
|
- if (err)
|
|
- return err;
|
|
-
|
|
- return 0;
|
|
+out:
|
|
+ inode_unlock(inode);
|
|
+ mnt_drop_write_file(filp);
|
|
+ return err;
|
|
}
|
|
case EXT4_IOC_SHUTDOWN:
|
|
return ext4_shutdown(sb, arg);
|
|
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
|
|
index a409ff70d67b..2f5be02fc6f6 100644
|
|
--- a/fs/ext4/move_extent.c
|
|
+++ b/fs/ext4/move_extent.c
|
|
@@ -516,9 +516,13 @@ mext_check_arguments(struct inode *orig_inode,
|
|
orig_inode->i_ino, donor_inode->i_ino);
|
|
return -EINVAL;
|
|
}
|
|
- if (orig_eof < orig_start + *len - 1)
|
|
+ if (orig_eof <= orig_start)
|
|
+ *len = 0;
|
|
+ else if (orig_eof < orig_start + *len - 1)
|
|
*len = orig_eof - orig_start;
|
|
- if (donor_eof < donor_start + *len - 1)
|
|
+ if (donor_eof <= donor_start)
|
|
+ *len = 0;
|
|
+ else if (donor_eof < donor_start + *len - 1)
|
|
*len = donor_eof - donor_start;
|
|
if (!*len) {
|
|
ext4_debug("ext4 move extent: len should not be 0 "
|
|
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
|
|
index 1145109968ef..d3d4643ab79b 100644
|
|
--- a/fs/ext4/super.c
|
|
+++ b/fs/ext4/super.c
|
|
@@ -914,6 +914,18 @@ static inline void ext4_quota_off_umount(struct super_block *sb)
|
|
for (type = 0; type < EXT4_MAXQUOTAS; type++)
|
|
ext4_quota_off(sb, type);
|
|
}
|
|
+
|
|
+/*
|
|
+ * This is a helper function which is used in the mount/remount
|
|
+ * codepaths (which holds s_umount) to fetch the quota file name.
|
|
+ */
|
|
+static inline char *get_qf_name(struct super_block *sb,
|
|
+ struct ext4_sb_info *sbi,
|
|
+ int type)
|
|
+{
|
|
+ return rcu_dereference_protected(sbi->s_qf_names[type],
|
|
+ lockdep_is_held(&sb->s_umount));
|
|
+}
|
|
#else
|
|
static inline void ext4_quota_off_umount(struct super_block *sb)
|
|
{
|
|
@@ -965,7 +977,7 @@ static void ext4_put_super(struct super_block *sb)
|
|
percpu_free_rwsem(&sbi->s_journal_flag_rwsem);
|
|
#ifdef CONFIG_QUOTA
|
|
for (i = 0; i < EXT4_MAXQUOTAS; i++)
|
|
- kfree(sbi->s_qf_names[i]);
|
|
+ kfree(get_qf_name(sb, sbi, i));
|
|
#endif
|
|
|
|
/* Debugging code just in case the in-memory inode orphan list
|
|
@@ -1530,11 +1542,10 @@ static const char deprecated_msg[] =
|
|
static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
|
|
{
|
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
- char *qname;
|
|
+ char *qname, *old_qname = get_qf_name(sb, sbi, qtype);
|
|
int ret = -1;
|
|
|
|
- if (sb_any_quota_loaded(sb) &&
|
|
- !sbi->s_qf_names[qtype]) {
|
|
+ if (sb_any_quota_loaded(sb) && !old_qname) {
|
|
ext4_msg(sb, KERN_ERR,
|
|
"Cannot change journaled "
|
|
"quota options when quota turned on");
|
|
@@ -1551,8 +1562,8 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
|
|
"Not enough memory for storing quotafile name");
|
|
return -1;
|
|
}
|
|
- if (sbi->s_qf_names[qtype]) {
|
|
- if (strcmp(sbi->s_qf_names[qtype], qname) == 0)
|
|
+ if (old_qname) {
|
|
+ if (strcmp(old_qname, qname) == 0)
|
|
ret = 1;
|
|
else
|
|
ext4_msg(sb, KERN_ERR,
|
|
@@ -1565,7 +1576,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
|
|
"quotafile must be on filesystem root");
|
|
goto errout;
|
|
}
|
|
- sbi->s_qf_names[qtype] = qname;
|
|
+ rcu_assign_pointer(sbi->s_qf_names[qtype], qname);
|
|
set_opt(sb, QUOTA);
|
|
return 1;
|
|
errout:
|
|
@@ -1577,15 +1588,16 @@ static int clear_qf_name(struct super_block *sb, int qtype)
|
|
{
|
|
|
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
+ char *old_qname = get_qf_name(sb, sbi, qtype);
|
|
|
|
- if (sb_any_quota_loaded(sb) &&
|
|
- sbi->s_qf_names[qtype]) {
|
|
+ if (sb_any_quota_loaded(sb) && old_qname) {
|
|
ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options"
|
|
" when quota turned on");
|
|
return -1;
|
|
}
|
|
- kfree(sbi->s_qf_names[qtype]);
|
|
- sbi->s_qf_names[qtype] = NULL;
|
|
+ rcu_assign_pointer(sbi->s_qf_names[qtype], NULL);
|
|
+ synchronize_rcu();
|
|
+ kfree(old_qname);
|
|
return 1;
|
|
}
|
|
#endif
|
|
@@ -1960,7 +1972,7 @@ static int parse_options(char *options, struct super_block *sb,
|
|
int is_remount)
|
|
{
|
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
- char *p;
|
|
+ char *p, __maybe_unused *usr_qf_name, __maybe_unused *grp_qf_name;
|
|
substring_t args[MAX_OPT_ARGS];
|
|
int token;
|
|
|
|
@@ -1991,11 +2003,13 @@ static int parse_options(char *options, struct super_block *sb,
|
|
"Cannot enable project quota enforcement.");
|
|
return 0;
|
|
}
|
|
- if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
|
|
- if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
|
|
+ usr_qf_name = get_qf_name(sb, sbi, USRQUOTA);
|
|
+ grp_qf_name = get_qf_name(sb, sbi, GRPQUOTA);
|
|
+ if (usr_qf_name || grp_qf_name) {
|
|
+ if (test_opt(sb, USRQUOTA) && usr_qf_name)
|
|
clear_opt(sb, USRQUOTA);
|
|
|
|
- if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
|
|
+ if (test_opt(sb, GRPQUOTA) && grp_qf_name)
|
|
clear_opt(sb, GRPQUOTA);
|
|
|
|
if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
|
|
@@ -2029,6 +2043,7 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
|
|
{
|
|
#if defined(CONFIG_QUOTA)
|
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
+ char *usr_qf_name, *grp_qf_name;
|
|
|
|
if (sbi->s_jquota_fmt) {
|
|
char *fmtname = "";
|
|
@@ -2047,11 +2062,14 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
|
|
seq_printf(seq, ",jqfmt=%s", fmtname);
|
|
}
|
|
|
|
- if (sbi->s_qf_names[USRQUOTA])
|
|
- seq_show_option(seq, "usrjquota", sbi->s_qf_names[USRQUOTA]);
|
|
-
|
|
- if (sbi->s_qf_names[GRPQUOTA])
|
|
- seq_show_option(seq, "grpjquota", sbi->s_qf_names[GRPQUOTA]);
|
|
+ rcu_read_lock();
|
|
+ usr_qf_name = rcu_dereference(sbi->s_qf_names[USRQUOTA]);
|
|
+ grp_qf_name = rcu_dereference(sbi->s_qf_names[GRPQUOTA]);
|
|
+ if (usr_qf_name)
|
|
+ seq_show_option(seq, "usrjquota", usr_qf_name);
|
|
+ if (grp_qf_name)
|
|
+ seq_show_option(seq, "grpjquota", grp_qf_name);
|
|
+ rcu_read_unlock();
|
|
#endif
|
|
}
|
|
|
|
@@ -5103,6 +5121,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|
int err = 0;
|
|
#ifdef CONFIG_QUOTA
|
|
int i, j;
|
|
+ char *to_free[EXT4_MAXQUOTAS];
|
|
#endif
|
|
char *orig_data = kstrdup(data, GFP_KERNEL);
|
|
|
|
@@ -5122,8 +5141,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|
old_opts.s_jquota_fmt = sbi->s_jquota_fmt;
|
|
for (i = 0; i < EXT4_MAXQUOTAS; i++)
|
|
if (sbi->s_qf_names[i]) {
|
|
- old_opts.s_qf_names[i] = kstrdup(sbi->s_qf_names[i],
|
|
- GFP_KERNEL);
|
|
+ char *qf_name = get_qf_name(sb, sbi, i);
|
|
+
|
|
+ old_opts.s_qf_names[i] = kstrdup(qf_name, GFP_KERNEL);
|
|
if (!old_opts.s_qf_names[i]) {
|
|
for (j = 0; j < i; j++)
|
|
kfree(old_opts.s_qf_names[j]);
|
|
@@ -5352,9 +5372,12 @@ restore_opts:
|
|
#ifdef CONFIG_QUOTA
|
|
sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
|
|
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
|
|
- kfree(sbi->s_qf_names[i]);
|
|
- sbi->s_qf_names[i] = old_opts.s_qf_names[i];
|
|
+ to_free[i] = get_qf_name(sb, sbi, i);
|
|
+ rcu_assign_pointer(sbi->s_qf_names[i], old_opts.s_qf_names[i]);
|
|
}
|
|
+ synchronize_rcu();
|
|
+ for (i = 0; i < EXT4_MAXQUOTAS; i++)
|
|
+ kfree(to_free[i]);
|
|
#endif
|
|
kfree(orig_data);
|
|
return err;
|
|
@@ -5545,7 +5568,7 @@ static int ext4_write_info(struct super_block *sb, int type)
|
|
*/
|
|
static int ext4_quota_on_mount(struct super_block *sb, int type)
|
|
{
|
|
- return dquot_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
|
|
+ return dquot_quota_on_mount(sb, get_qf_name(sb, EXT4_SB(sb), type),
|
|
EXT4_SB(sb)->s_jquota_fmt, type);
|
|
}
|
|
|
|
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
|
|
index e8b6b89bddb8..59d0472013f4 100644
|
|
--- a/fs/f2fs/checkpoint.c
|
|
+++ b/fs/f2fs/checkpoint.c
|
|
@@ -696,6 +696,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
|
|
/* clear Orphan Flag */
|
|
clear_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG);
|
|
out:
|
|
+ set_sbi_flag(sbi, SBI_IS_RECOVERED);
|
|
+
|
|
#ifdef CONFIG_QUOTA
|
|
/* Turn quotas off */
|
|
if (quota_enabled)
|
|
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
|
|
index 382c1ef9a9e4..11f28342f641 100644
|
|
--- a/fs/f2fs/data.c
|
|
+++ b/fs/f2fs/data.c
|
|
@@ -80,7 +80,8 @@ static void __read_end_io(struct bio *bio)
|
|
/* PG_error was set if any post_read step failed */
|
|
if (bio->bi_status || PageError(page)) {
|
|
ClearPageUptodate(page);
|
|
- SetPageError(page);
|
|
+ /* will re-read again later */
|
|
+ ClearPageError(page);
|
|
} else {
|
|
SetPageUptodate(page);
|
|
}
|
|
@@ -456,12 +457,16 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
|
|
bio_put(bio);
|
|
return -EFAULT;
|
|
}
|
|
- bio_set_op_attrs(bio, fio->op, fio->op_flags);
|
|
|
|
- __submit_bio(fio->sbi, bio, fio->type);
|
|
+ if (fio->io_wbc && !is_read_io(fio->op))
|
|
+ wbc_account_io(fio->io_wbc, page, PAGE_SIZE);
|
|
+
|
|
+ bio_set_op_attrs(bio, fio->op, fio->op_flags);
|
|
|
|
if (!is_read_io(fio->op))
|
|
inc_page_count(fio->sbi, WB_DATA_TYPE(fio->page));
|
|
+
|
|
+ __submit_bio(fio->sbi, bio, fio->type);
|
|
return 0;
|
|
}
|
|
|
|
@@ -586,6 +591,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
|
|
bio_put(bio);
|
|
return -EFAULT;
|
|
}
|
|
+ ClearPageError(page);
|
|
__submit_bio(F2FS_I_SB(inode), bio, DATA);
|
|
return 0;
|
|
}
|
|
@@ -1561,6 +1567,7 @@ submit_and_realloc:
|
|
if (bio_add_page(bio, page, blocksize, 0) < blocksize)
|
|
goto submit_and_realloc;
|
|
|
|
+ ClearPageError(page);
|
|
last_block_in_bio = block_nr;
|
|
goto next_page;
|
|
set_error_page:
|
|
@@ -2583,10 +2590,6 @@ static int f2fs_set_data_page_dirty(struct page *page)
|
|
if (!PageUptodate(page))
|
|
SetPageUptodate(page);
|
|
|
|
- /* don't remain PG_checked flag which was set during GC */
|
|
- if (is_cold_data(page))
|
|
- clear_cold_data(page);
|
|
-
|
|
if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) {
|
|
if (!IS_ATOMIC_WRITTEN_PAGE(page)) {
|
|
f2fs_register_inmem_page(inode, page);
|
|
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
|
|
index 231b77ef5a53..a70cd2580eae 100644
|
|
--- a/fs/f2fs/extent_cache.c
|
|
+++ b/fs/f2fs/extent_cache.c
|
|
@@ -308,14 +308,13 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
|
|
return count - atomic_read(&et->node_cnt);
|
|
}
|
|
|
|
-static void __drop_largest_extent(struct inode *inode,
|
|
+static void __drop_largest_extent(struct extent_tree *et,
|
|
pgoff_t fofs, unsigned int len)
|
|
{
|
|
- struct extent_info *largest = &F2FS_I(inode)->extent_tree->largest;
|
|
-
|
|
- if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs) {
|
|
- largest->len = 0;
|
|
- f2fs_mark_inode_dirty_sync(inode, true);
|
|
+ if (fofs < et->largest.fofs + et->largest.len &&
|
|
+ fofs + len > et->largest.fofs) {
|
|
+ et->largest.len = 0;
|
|
+ et->largest_updated = true;
|
|
}
|
|
}
|
|
|
|
@@ -416,12 +415,11 @@ out:
|
|
return ret;
|
|
}
|
|
|
|
-static struct extent_node *__try_merge_extent_node(struct inode *inode,
|
|
+static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
|
|
struct extent_tree *et, struct extent_info *ei,
|
|
struct extent_node *prev_ex,
|
|
struct extent_node *next_ex)
|
|
{
|
|
- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
|
struct extent_node *en = NULL;
|
|
|
|
if (prev_ex && __is_back_mergeable(ei, &prev_ex->ei)) {
|
|
@@ -443,7 +441,7 @@ static struct extent_node *__try_merge_extent_node(struct inode *inode,
|
|
if (!en)
|
|
return NULL;
|
|
|
|
- __try_update_largest_extent(inode, et, en);
|
|
+ __try_update_largest_extent(et, en);
|
|
|
|
spin_lock(&sbi->extent_lock);
|
|
if (!list_empty(&en->list)) {
|
|
@@ -454,12 +452,11 @@ static struct extent_node *__try_merge_extent_node(struct inode *inode,
|
|
return en;
|
|
}
|
|
|
|
-static struct extent_node *__insert_extent_tree(struct inode *inode,
|
|
+static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
|
|
struct extent_tree *et, struct extent_info *ei,
|
|
struct rb_node **insert_p,
|
|
struct rb_node *insert_parent)
|
|
{
|
|
- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
|
struct rb_node **p;
|
|
struct rb_node *parent = NULL;
|
|
struct extent_node *en = NULL;
|
|
@@ -476,7 +473,7 @@ do_insert:
|
|
if (!en)
|
|
return NULL;
|
|
|
|
- __try_update_largest_extent(inode, et, en);
|
|
+ __try_update_largest_extent(et, en);
|
|
|
|
/* update in global extent list */
|
|
spin_lock(&sbi->extent_lock);
|
|
@@ -497,6 +494,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
|
|
struct rb_node **insert_p = NULL, *insert_parent = NULL;
|
|
unsigned int end = fofs + len;
|
|
unsigned int pos = (unsigned int)fofs;
|
|
+ bool updated = false;
|
|
|
|
if (!et)
|
|
return;
|
|
@@ -517,7 +515,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
|
|
* drop largest extent before lookup, in case it's already
|
|
* been shrunk from extent tree
|
|
*/
|
|
- __drop_largest_extent(inode, fofs, len);
|
|
+ __drop_largest_extent(et, fofs, len);
|
|
|
|
/* 1. lookup first extent node in range [fofs, fofs + len - 1] */
|
|
en = (struct extent_node *)f2fs_lookup_rb_tree_ret(&et->root,
|
|
@@ -550,7 +548,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
|
|
set_extent_info(&ei, end,
|
|
end - dei.fofs + dei.blk,
|
|
org_end - end);
|
|
- en1 = __insert_extent_tree(inode, et, &ei,
|
|
+ en1 = __insert_extent_tree(sbi, et, &ei,
|
|
NULL, NULL);
|
|
next_en = en1;
|
|
} else {
|
|
@@ -570,7 +568,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
|
|
}
|
|
|
|
if (parts)
|
|
- __try_update_largest_extent(inode, et, en);
|
|
+ __try_update_largest_extent(et, en);
|
|
else
|
|
__release_extent_node(sbi, et, en);
|
|
|
|
@@ -590,15 +588,16 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
|
|
if (blkaddr) {
|
|
|
|
set_extent_info(&ei, fofs, blkaddr, len);
|
|
- if (!__try_merge_extent_node(inode, et, &ei, prev_en, next_en))
|
|
- __insert_extent_tree(inode, et, &ei,
|
|
+ if (!__try_merge_extent_node(sbi, et, &ei, prev_en, next_en))
|
|
+ __insert_extent_tree(sbi, et, &ei,
|
|
insert_p, insert_parent);
|
|
|
|
/* give up extent_cache, if split and small updates happen */
|
|
if (dei.len >= 1 &&
|
|
prev.len < F2FS_MIN_EXTENT_LEN &&
|
|
et->largest.len < F2FS_MIN_EXTENT_LEN) {
|
|
- __drop_largest_extent(inode, 0, UINT_MAX);
|
|
+ et->largest.len = 0;
|
|
+ et->largest_updated = true;
|
|
set_inode_flag(inode, FI_NO_EXTENT);
|
|
}
|
|
}
|
|
@@ -606,7 +605,15 @@ static void f2fs_update_extent_tree_range(struct inode *inode,
|
|
if (is_inode_flag_set(inode, FI_NO_EXTENT))
|
|
__free_extent_tree(sbi, et);
|
|
|
|
+ if (et->largest_updated) {
|
|
+ et->largest_updated = false;
|
|
+ updated = true;
|
|
+ }
|
|
+
|
|
write_unlock(&et->lock);
|
|
+
|
|
+ if (updated)
|
|
+ f2fs_mark_inode_dirty_sync(inode, true);
|
|
}
|
|
|
|
unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
|
|
@@ -705,6 +712,7 @@ void f2fs_drop_extent_tree(struct inode *inode)
|
|
{
|
|
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
|
struct extent_tree *et = F2FS_I(inode)->extent_tree;
|
|
+ bool updated = false;
|
|
|
|
if (!f2fs_may_extent_tree(inode))
|
|
return;
|
|
@@ -713,8 +721,13 @@ void f2fs_drop_extent_tree(struct inode *inode)
|
|
|
|
write_lock(&et->lock);
|
|
__free_extent_tree(sbi, et);
|
|
- __drop_largest_extent(inode, 0, UINT_MAX);
|
|
+ if (et->largest.len) {
|
|
+ et->largest.len = 0;
|
|
+ updated = true;
|
|
+ }
|
|
write_unlock(&et->lock);
|
|
+ if (updated)
|
|
+ f2fs_mark_inode_dirty_sync(inode, true);
|
|
}
|
|
|
|
void f2fs_destroy_extent_tree(struct inode *inode)
|
|
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
|
|
index abf925664d9c..ecb735142276 100644
|
|
--- a/fs/f2fs/f2fs.h
|
|
+++ b/fs/f2fs/f2fs.h
|
|
@@ -572,6 +572,7 @@ struct extent_tree {
|
|
struct list_head list; /* to be used by sbi->zombie_list */
|
|
rwlock_t lock; /* protect extent info rb-tree */
|
|
atomic_t node_cnt; /* # of extent node in rb-tree*/
|
|
+ bool largest_updated; /* largest extent updated */
|
|
};
|
|
|
|
/*
|
|
@@ -754,12 +755,12 @@ static inline bool __is_front_mergeable(struct extent_info *cur,
|
|
}
|
|
|
|
extern void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync);
|
|
-static inline void __try_update_largest_extent(struct inode *inode,
|
|
- struct extent_tree *et, struct extent_node *en)
|
|
+static inline void __try_update_largest_extent(struct extent_tree *et,
|
|
+ struct extent_node *en)
|
|
{
|
|
if (en->ei.len > et->largest.len) {
|
|
et->largest = en->ei;
|
|
- f2fs_mark_inode_dirty_sync(inode, true);
|
|
+ et->largest_updated = true;
|
|
}
|
|
}
|
|
|
|
@@ -1088,6 +1089,7 @@ enum {
|
|
SBI_NEED_SB_WRITE, /* need to recover superblock */
|
|
SBI_NEED_CP, /* need to checkpoint */
|
|
SBI_IS_SHUTDOWN, /* shutdown by ioctl */
|
|
+ SBI_IS_RECOVERED, /* recovered orphan/data */
|
|
};
|
|
|
|
enum {
|
|
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
|
|
index 959df2249875..dd608b819a3c 100644
|
|
--- a/fs/f2fs/inode.c
|
|
+++ b/fs/f2fs/inode.c
|
|
@@ -368,6 +368,12 @@ static int do_read_inode(struct inode *inode)
|
|
if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode))
|
|
__recover_inline_status(inode, node_page);
|
|
|
|
+ /* try to recover cold bit for non-dir inode */
|
|
+ if (!S_ISDIR(inode->i_mode) && !is_cold_node(node_page)) {
|
|
+ set_cold_node(node_page, false);
|
|
+ set_page_dirty(node_page);
|
|
+ }
|
|
+
|
|
/* get rdev by using inline_info */
|
|
__get_inode_rdev(inode, ri);
|
|
|
|
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
|
|
index dd2e45a661aa..42ea42acb487 100644
|
|
--- a/fs/f2fs/node.c
|
|
+++ b/fs/f2fs/node.c
|
|
@@ -1542,8 +1542,10 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
|
|
}
|
|
|
|
if (__is_valid_data_blkaddr(ni.blk_addr) &&
|
|
- !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC))
|
|
+ !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) {
|
|
+ up_read(&sbi->node_write);
|
|
goto redirty_out;
|
|
+ }
|
|
|
|
if (atomic && !test_opt(sbi, NOBARRIER))
|
|
fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
|
|
@@ -2537,7 +2539,7 @@ retry:
|
|
if (!PageUptodate(ipage))
|
|
SetPageUptodate(ipage);
|
|
fill_node_footer(ipage, ino, ino, 0, true);
|
|
- set_cold_node(page, false);
|
|
+ set_cold_node(ipage, false);
|
|
|
|
src = F2FS_INODE(page);
|
|
dst = F2FS_INODE(ipage);
|
|
@@ -2560,6 +2562,13 @@ retry:
|
|
F2FS_FITS_IN_INODE(src, le16_to_cpu(src->i_extra_isize),
|
|
i_projid))
|
|
dst->i_projid = src->i_projid;
|
|
+
|
|
+ if (f2fs_sb_has_inode_crtime(sbi->sb) &&
|
|
+ F2FS_FITS_IN_INODE(src, le16_to_cpu(src->i_extra_isize),
|
|
+ i_crtime_nsec)) {
|
|
+ dst->i_crtime = src->i_crtime;
|
|
+ dst->i_crtime_nsec = src->i_crtime_nsec;
|
|
+ }
|
|
}
|
|
|
|
new_ni = old_ni;
|
|
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
|
|
index 95511ed11a22..9a8579fb3a30 100644
|
|
--- a/fs/f2fs/recovery.c
|
|
+++ b/fs/f2fs/recovery.c
|
|
@@ -221,6 +221,7 @@ static void recover_inode(struct inode *inode, struct page *page)
|
|
inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec);
|
|
|
|
F2FS_I(inode)->i_advise = raw->i_advise;
|
|
+ F2FS_I(inode)->i_flags = le32_to_cpu(raw->i_flags);
|
|
|
|
recover_inline_flags(inode, raw);
|
|
|
|
@@ -697,11 +698,15 @@ skip:
|
|
/* let's drop all the directory inodes for clean checkpoint */
|
|
destroy_fsync_dnodes(&dir_list);
|
|
|
|
- if (!err && need_writecp) {
|
|
- struct cp_control cpc = {
|
|
- .reason = CP_RECOVERY,
|
|
- };
|
|
- err = f2fs_write_checkpoint(sbi, &cpc);
|
|
+ if (need_writecp) {
|
|
+ set_sbi_flag(sbi, SBI_IS_RECOVERED);
|
|
+
|
|
+ if (!err) {
|
|
+ struct cp_control cpc = {
|
|
+ .reason = CP_RECOVERY,
|
|
+ };
|
|
+ err = f2fs_write_checkpoint(sbi, &cpc);
|
|
+ }
|
|
}
|
|
|
|
kmem_cache_destroy(fsync_entry_slab);
|
|
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
|
|
index 896b885f504e..287c9fe9fff9 100644
|
|
--- a/fs/f2fs/super.c
|
|
+++ b/fs/f2fs/super.c
|
|
@@ -1852,7 +1852,9 @@ static int f2fs_quota_off(struct super_block *sb, int type)
|
|
if (!inode || !igrab(inode))
|
|
return dquot_quota_off(sb, type);
|
|
|
|
- f2fs_quota_sync(sb, type);
|
|
+ err = f2fs_quota_sync(sb, type);
|
|
+ if (err)
|
|
+ goto out_put;
|
|
|
|
err = dquot_quota_off(sb, type);
|
|
if (err || f2fs_sb_has_quota_ino(sb))
|
|
@@ -1871,9 +1873,20 @@ out_put:
|
|
void f2fs_quota_off_umount(struct super_block *sb)
|
|
{
|
|
int type;
|
|
+ int err;
|
|
|
|
- for (type = 0; type < MAXQUOTAS; type++)
|
|
- f2fs_quota_off(sb, type);
|
|
+ for (type = 0; type < MAXQUOTAS; type++) {
|
|
+ err = f2fs_quota_off(sb, type);
|
|
+ if (err) {
|
|
+ int ret = dquot_quota_off(sb, type);
|
|
+
|
|
+ f2fs_msg(sb, KERN_ERR,
|
|
+ "Fail to turn off disk quota "
|
|
+ "(type: %d, err: %d, ret:%d), Please "
|
|
+ "run fsck to fix it.", type, err, ret);
|
|
+ set_sbi_flag(F2FS_SB(sb), SBI_NEED_FSCK);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
static int f2fs_get_projid(struct inode *inode, kprojid_t *projid)
|
|
@@ -3175,6 +3188,9 @@ static void kill_f2fs_super(struct super_block *sb)
|
|
};
|
|
f2fs_write_checkpoint(sbi, &cpc);
|
|
}
|
|
+
|
|
+ if (is_sbi_flag_set(sbi, SBI_IS_RECOVERED) && f2fs_readonly(sb))
|
|
+ sb->s_flags &= ~SB_RDONLY;
|
|
}
|
|
kill_block_super(sb);
|
|
}
|
|
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
|
|
index c2469833b4fb..6b84ef6ccff3 100644
|
|
--- a/fs/gfs2/ops_fstype.c
|
|
+++ b/fs/gfs2/ops_fstype.c
|
|
@@ -1333,6 +1333,9 @@ static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type,
|
|
struct path path;
|
|
int error;
|
|
|
|
+ if (!dev_name || !*dev_name)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
|
|
if (error) {
|
|
pr_warn("path_lookup on %s returned error %d\n",
|
|
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
|
|
index c125d662777c..26f8d7e46462 100644
|
|
--- a/fs/jbd2/checkpoint.c
|
|
+++ b/fs/jbd2/checkpoint.c
|
|
@@ -251,8 +251,8 @@ restart:
|
|
bh = jh2bh(jh);
|
|
|
|
if (buffer_locked(bh)) {
|
|
- spin_unlock(&journal->j_list_lock);
|
|
get_bh(bh);
|
|
+ spin_unlock(&journal->j_list_lock);
|
|
wait_on_buffer(bh);
|
|
/* the journal_head may have gone by now */
|
|
BUFFER_TRACE(bh, "brelse");
|
|
@@ -333,8 +333,8 @@ restart2:
|
|
jh = transaction->t_checkpoint_io_list;
|
|
bh = jh2bh(jh);
|
|
if (buffer_locked(bh)) {
|
|
- spin_unlock(&journal->j_list_lock);
|
|
get_bh(bh);
|
|
+ spin_unlock(&journal->j_list_lock);
|
|
wait_on_buffer(bh);
|
|
/* the journal_head may have gone by now */
|
|
BUFFER_TRACE(bh, "brelse");
|
|
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
|
|
index 87bdf0f4cba1..902a7dd10e5c 100644
|
|
--- a/fs/jffs2/super.c
|
|
+++ b/fs/jffs2/super.c
|
|
@@ -285,10 +285,8 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
|
|
sb->s_fs_info = c;
|
|
|
|
ret = jffs2_parse_options(c, data);
|
|
- if (ret) {
|
|
- kfree(c);
|
|
+ if (ret)
|
|
return -EINVAL;
|
|
- }
|
|
|
|
/* Initialize JFFS2 superblock locks, the further initialization will
|
|
* be done later */
|
|
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
|
|
index d35cd6be0675..93fb7cf0b92b 100644
|
|
--- a/fs/lockd/host.c
|
|
+++ b/fs/lockd/host.c
|
|
@@ -341,7 +341,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
|
|
};
|
|
struct lockd_net *ln = net_generic(net, lockd_net_id);
|
|
|
|
- dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__,
|
|
+ dprintk("lockd: %s(host='%.*s', vers=%u, proto=%s)\n", __func__,
|
|
(int)hostname_len, hostname, rqstp->rq_vers,
|
|
(rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp"));
|
|
|
|
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
|
|
index 146e30862234..8f53455c4765 100644
|
|
--- a/fs/nfs/nfs4client.c
|
|
+++ b/fs/nfs/nfs4client.c
|
|
@@ -950,10 +950,10 @@ EXPORT_SYMBOL_GPL(nfs4_set_ds_client);
|
|
|
|
/*
|
|
* Session has been established, and the client marked ready.
|
|
- * Set the mount rsize and wsize with negotiated fore channel
|
|
- * attributes which will be bound checked in nfs_server_set_fsinfo.
|
|
+ * Limit the mount rsize, wsize and dtsize using negotiated fore
|
|
+ * channel attributes.
|
|
*/
|
|
-static void nfs4_session_set_rwsize(struct nfs_server *server)
|
|
+static void nfs4_session_limit_rwsize(struct nfs_server *server)
|
|
{
|
|
#ifdef CONFIG_NFS_V4_1
|
|
struct nfs4_session *sess;
|
|
@@ -966,9 +966,11 @@ static void nfs4_session_set_rwsize(struct nfs_server *server)
|
|
server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
|
|
server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
|
|
|
|
- if (!server->rsize || server->rsize > server_resp_sz)
|
|
+ if (server->dtsize > server_resp_sz)
|
|
+ server->dtsize = server_resp_sz;
|
|
+ if (server->rsize > server_resp_sz)
|
|
server->rsize = server_resp_sz;
|
|
- if (!server->wsize || server->wsize > server_rqst_sz)
|
|
+ if (server->wsize > server_rqst_sz)
|
|
server->wsize = server_rqst_sz;
|
|
#endif /* CONFIG_NFS_V4_1 */
|
|
}
|
|
@@ -1015,12 +1017,12 @@ static int nfs4_server_common_setup(struct nfs_server *server,
|
|
(unsigned long long) server->fsid.minor);
|
|
nfs_display_fhandle(mntfh, "Pseudo-fs root FH");
|
|
|
|
- nfs4_session_set_rwsize(server);
|
|
-
|
|
error = nfs_probe_fsinfo(server, mntfh, fattr);
|
|
if (error < 0)
|
|
goto out;
|
|
|
|
+ nfs4_session_limit_rwsize(server);
|
|
+
|
|
if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
|
|
server->namelen = NFS4_MAXNAMLEN;
|
|
|
|
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
|
|
index bb5476a6d264..3dbd15b47c27 100644
|
|
--- a/fs/nfs/pagelist.c
|
|
+++ b/fs/nfs/pagelist.c
|
|
@@ -1111,6 +1111,20 @@ static int nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc,
|
|
return ret;
|
|
}
|
|
|
|
+static void nfs_pageio_error_cleanup(struct nfs_pageio_descriptor *desc)
|
|
+{
|
|
+ u32 midx;
|
|
+ struct nfs_pgio_mirror *mirror;
|
|
+
|
|
+ if (!desc->pg_error)
|
|
+ return;
|
|
+
|
|
+ for (midx = 0; midx < desc->pg_mirror_count; midx++) {
|
|
+ mirror = &desc->pg_mirrors[midx];
|
|
+ desc->pg_completion_ops->error_cleanup(&mirror->pg_list);
|
|
+ }
|
|
+}
|
|
+
|
|
int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
|
|
struct nfs_page *req)
|
|
{
|
|
@@ -1161,25 +1175,11 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
|
|
return 1;
|
|
|
|
out_failed:
|
|
- /*
|
|
- * We might have failed before sending any reqs over wire.
|
|
- * Clean up rest of the reqs in mirror pg_list.
|
|
- */
|
|
- if (desc->pg_error) {
|
|
- struct nfs_pgio_mirror *mirror;
|
|
- void (*func)(struct list_head *);
|
|
-
|
|
- /* remember fatal errors */
|
|
- if (nfs_error_is_fatal(desc->pg_error))
|
|
- nfs_context_set_write_error(req->wb_context,
|
|
- desc->pg_error);
|
|
-
|
|
- func = desc->pg_completion_ops->error_cleanup;
|
|
- for (midx = 0; midx < desc->pg_mirror_count; midx++) {
|
|
- mirror = &desc->pg_mirrors[midx];
|
|
- func(&mirror->pg_list);
|
|
- }
|
|
- }
|
|
+ /* remember fatal errors */
|
|
+ if (nfs_error_is_fatal(desc->pg_error))
|
|
+ nfs_context_set_write_error(req->wb_context,
|
|
+ desc->pg_error);
|
|
+ nfs_pageio_error_cleanup(desc);
|
|
return 0;
|
|
}
|
|
|
|
@@ -1251,6 +1251,8 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
|
|
for (midx = 0; midx < desc->pg_mirror_count; midx++)
|
|
nfs_pageio_complete_mirror(desc, midx);
|
|
|
|
+ if (desc->pg_error < 0)
|
|
+ nfs_pageio_error_cleanup(desc);
|
|
if (desc->pg_ops->pg_cleanup)
|
|
desc->pg_ops->pg_cleanup(desc);
|
|
nfs_pageio_cleanup_mirroring(desc);
|
|
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
|
|
index b0ca0efd2875..9c6d1d57b598 100644
|
|
--- a/fs/nfsd/nfs4state.c
|
|
+++ b/fs/nfsd/nfs4state.c
|
|
@@ -4364,7 +4364,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
|
|
|
|
fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
|
|
if (!fl)
|
|
- goto out_stid;
|
|
+ goto out_clnt_odstate;
|
|
|
|
status = vfs_setlease(fp->fi_deleg_file, fl->fl_type, &fl, NULL);
|
|
if (fl)
|
|
@@ -4389,7 +4389,6 @@ out_unlock:
|
|
vfs_setlease(fp->fi_deleg_file, F_UNLCK, NULL, (void **)&dp);
|
|
out_clnt_odstate:
|
|
put_clnt_odstate(dp->dl_clnt_odstate);
|
|
-out_stid:
|
|
nfs4_put_stid(&dp->dl_stid);
|
|
out_delegees:
|
|
put_deleg_file(fp);
|
|
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
|
|
index ababdbfab537..f43ea1aad542 100644
|
|
--- a/fs/notify/fsnotify.c
|
|
+++ b/fs/notify/fsnotify.c
|
|
@@ -96,6 +96,9 @@ void fsnotify_unmount_inodes(struct super_block *sb)
|
|
|
|
if (iput_inode)
|
|
iput(iput_inode);
|
|
+ /* Wait for outstanding inode references from connectors */
|
|
+ wait_var_event(&sb->s_fsnotify_inode_refs,
|
|
+ !atomic_long_read(&sb->s_fsnotify_inode_refs));
|
|
}
|
|
|
|
/*
|
|
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
|
|
index 59cdb27826de..09535f6423fc 100644
|
|
--- a/fs/notify/mark.c
|
|
+++ b/fs/notify/mark.c
|
|
@@ -179,17 +179,20 @@ static void fsnotify_connector_destroy_workfn(struct work_struct *work)
|
|
}
|
|
}
|
|
|
|
-static struct inode *fsnotify_detach_connector_from_object(
|
|
- struct fsnotify_mark_connector *conn)
|
|
+static void *fsnotify_detach_connector_from_object(
|
|
+ struct fsnotify_mark_connector *conn,
|
|
+ unsigned int *type)
|
|
{
|
|
struct inode *inode = NULL;
|
|
|
|
+ *type = conn->type;
|
|
if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED)
|
|
return NULL;
|
|
|
|
if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
|
|
inode = fsnotify_conn_inode(conn);
|
|
inode->i_fsnotify_mask = 0;
|
|
+ atomic_long_inc(&inode->i_sb->s_fsnotify_inode_refs);
|
|
} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
|
|
fsnotify_conn_mount(conn)->mnt_fsnotify_mask = 0;
|
|
}
|
|
@@ -211,10 +214,29 @@ static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark)
|
|
fsnotify_put_group(group);
|
|
}
|
|
|
|
+/* Drop object reference originally held by a connector */
|
|
+static void fsnotify_drop_object(unsigned int type, void *objp)
|
|
+{
|
|
+ struct inode *inode;
|
|
+ struct super_block *sb;
|
|
+
|
|
+ if (!objp)
|
|
+ return;
|
|
+ /* Currently only inode references are passed to be dropped */
|
|
+ if (WARN_ON_ONCE(type != FSNOTIFY_OBJ_TYPE_INODE))
|
|
+ return;
|
|
+ inode = objp;
|
|
+ sb = inode->i_sb;
|
|
+ iput(inode);
|
|
+ if (atomic_long_dec_and_test(&sb->s_fsnotify_inode_refs))
|
|
+ wake_up_var(&sb->s_fsnotify_inode_refs);
|
|
+}
|
|
+
|
|
void fsnotify_put_mark(struct fsnotify_mark *mark)
|
|
{
|
|
struct fsnotify_mark_connector *conn;
|
|
- struct inode *inode = NULL;
|
|
+ void *objp = NULL;
|
|
+ unsigned int type = FSNOTIFY_OBJ_TYPE_DETACHED;
|
|
bool free_conn = false;
|
|
|
|
/* Catch marks that were actually never attached to object */
|
|
@@ -234,7 +256,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
|
|
conn = mark->connector;
|
|
hlist_del_init_rcu(&mark->obj_list);
|
|
if (hlist_empty(&conn->list)) {
|
|
- inode = fsnotify_detach_connector_from_object(conn);
|
|
+ objp = fsnotify_detach_connector_from_object(conn, &type);
|
|
free_conn = true;
|
|
} else {
|
|
__fsnotify_recalc_mask(conn);
|
|
@@ -242,7 +264,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
|
|
mark->connector = NULL;
|
|
spin_unlock(&conn->lock);
|
|
|
|
- iput(inode);
|
|
+ fsnotify_drop_object(type, objp);
|
|
|
|
if (free_conn) {
|
|
spin_lock(&destroy_lock);
|
|
@@ -709,7 +731,8 @@ void fsnotify_destroy_marks(fsnotify_connp_t *connp)
|
|
{
|
|
struct fsnotify_mark_connector *conn;
|
|
struct fsnotify_mark *mark, *old_mark = NULL;
|
|
- struct inode *inode;
|
|
+ void *objp;
|
|
+ unsigned int type;
|
|
|
|
conn = fsnotify_grab_connector(connp);
|
|
if (!conn)
|
|
@@ -735,11 +758,11 @@ void fsnotify_destroy_marks(fsnotify_connp_t *connp)
|
|
* mark references get dropped. It would lead to strange results such
|
|
* as delaying inode deletion or blocking unmount.
|
|
*/
|
|
- inode = fsnotify_detach_connector_from_object(conn);
|
|
+ objp = fsnotify_detach_connector_from_object(conn, &type);
|
|
spin_unlock(&conn->lock);
|
|
if (old_mark)
|
|
fsnotify_put_mark(old_mark);
|
|
- iput(inode);
|
|
+ fsnotify_drop_object(type, objp);
|
|
}
|
|
|
|
/*
|
|
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
|
|
index 5ea1d64cb0b4..a027473561c6 100644
|
|
--- a/fs/proc/task_mmu.c
|
|
+++ b/fs/proc/task_mmu.c
|
|
@@ -713,6 +713,8 @@ static void smap_gather_stats(struct vm_area_struct *vma,
|
|
smaps_walk.private = mss;
|
|
|
|
#ifdef CONFIG_SHMEM
|
|
+ /* In case of smaps_rollup, reset the value from previous vma */
|
|
+ mss->check_shmem_swap = false;
|
|
if (vma->vm_file && shmem_mapping(vma->vm_file->f_mapping)) {
|
|
/*
|
|
* For shared or readonly shmem mappings we know that all
|
|
@@ -728,7 +730,7 @@ static void smap_gather_stats(struct vm_area_struct *vma,
|
|
|
|
if (!shmem_swapped || (vma->vm_flags & VM_SHARED) ||
|
|
!(vma->vm_flags & VM_WRITE)) {
|
|
- mss->swap = shmem_swapped;
|
|
+ mss->swap += shmem_swapped;
|
|
} else {
|
|
mss->check_shmem_swap = true;
|
|
smaps_walk.pte_hole = smaps_pte_hole;
|
|
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
|
|
index bfa0ec69f924..356d2b8568c1 100644
|
|
--- a/fs/userfaultfd.c
|
|
+++ b/fs/userfaultfd.c
|
|
@@ -1026,7 +1026,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
|
|
struct userfaultfd_ctx *fork_nctx = NULL;
|
|
|
|
/* always take the fd_wqh lock before the fault_pending_wqh lock */
|
|
- spin_lock(&ctx->fd_wqh.lock);
|
|
+ spin_lock_irq(&ctx->fd_wqh.lock);
|
|
__add_wait_queue(&ctx->fd_wqh, &wait);
|
|
for (;;) {
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
@@ -1112,13 +1112,13 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
|
|
ret = -EAGAIN;
|
|
break;
|
|
}
|
|
- spin_unlock(&ctx->fd_wqh.lock);
|
|
+ spin_unlock_irq(&ctx->fd_wqh.lock);
|
|
schedule();
|
|
- spin_lock(&ctx->fd_wqh.lock);
|
|
+ spin_lock_irq(&ctx->fd_wqh.lock);
|
|
}
|
|
__remove_wait_queue(&ctx->fd_wqh, &wait);
|
|
__set_current_state(TASK_RUNNING);
|
|
- spin_unlock(&ctx->fd_wqh.lock);
|
|
+ spin_unlock_irq(&ctx->fd_wqh.lock);
|
|
|
|
if (!ret && msg->event == UFFD_EVENT_FORK) {
|
|
ret = resolve_userfault_fork(ctx, fork_nctx, msg);
|
|
diff --git a/include/crypto/speck.h b/include/crypto/speck.h
|
|
deleted file mode 100644
|
|
index 73cfc952d405..000000000000
|
|
--- a/include/crypto/speck.h
|
|
+++ /dev/null
|
|
@@ -1,62 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * Common values for the Speck algorithm
|
|
- */
|
|
-
|
|
-#ifndef _CRYPTO_SPECK_H
|
|
-#define _CRYPTO_SPECK_H
|
|
-
|
|
-#include <linux/types.h>
|
|
-
|
|
-/* Speck128 */
|
|
-
|
|
-#define SPECK128_BLOCK_SIZE 16
|
|
-
|
|
-#define SPECK128_128_KEY_SIZE 16
|
|
-#define SPECK128_128_NROUNDS 32
|
|
-
|
|
-#define SPECK128_192_KEY_SIZE 24
|
|
-#define SPECK128_192_NROUNDS 33
|
|
-
|
|
-#define SPECK128_256_KEY_SIZE 32
|
|
-#define SPECK128_256_NROUNDS 34
|
|
-
|
|
-struct speck128_tfm_ctx {
|
|
- u64 round_keys[SPECK128_256_NROUNDS];
|
|
- int nrounds;
|
|
-};
|
|
-
|
|
-void crypto_speck128_encrypt(const struct speck128_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in);
|
|
-
|
|
-void crypto_speck128_decrypt(const struct speck128_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in);
|
|
-
|
|
-int crypto_speck128_setkey(struct speck128_tfm_ctx *ctx, const u8 *key,
|
|
- unsigned int keysize);
|
|
-
|
|
-/* Speck64 */
|
|
-
|
|
-#define SPECK64_BLOCK_SIZE 8
|
|
-
|
|
-#define SPECK64_96_KEY_SIZE 12
|
|
-#define SPECK64_96_NROUNDS 26
|
|
-
|
|
-#define SPECK64_128_KEY_SIZE 16
|
|
-#define SPECK64_128_NROUNDS 27
|
|
-
|
|
-struct speck64_tfm_ctx {
|
|
- u32 round_keys[SPECK64_128_NROUNDS];
|
|
- int nrounds;
|
|
-};
|
|
-
|
|
-void crypto_speck64_encrypt(const struct speck64_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in);
|
|
-
|
|
-void crypto_speck64_decrypt(const struct speck64_tfm_ctx *ctx,
|
|
- u8 *out, const u8 *in);
|
|
-
|
|
-int crypto_speck64_setkey(struct speck64_tfm_ctx *ctx, const u8 *key,
|
|
- unsigned int keysize);
|
|
-
|
|
-#endif /* _CRYPTO_SPECK_H */
|
|
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
|
|
index 38b04f559ad3..1fd6fa822d2c 100644
|
|
--- a/include/linux/bpf_verifier.h
|
|
+++ b/include/linux/bpf_verifier.h
|
|
@@ -50,6 +50,9 @@ struct bpf_reg_state {
|
|
* PTR_TO_MAP_VALUE_OR_NULL
|
|
*/
|
|
struct bpf_map *map_ptr;
|
|
+
|
|
+ /* Max size from any of the above. */
|
|
+ unsigned long raw;
|
|
};
|
|
/* Fixed part of pointer offset, pointer types only */
|
|
s32 off;
|
|
diff --git a/include/linux/compat.h b/include/linux/compat.h
|
|
index 1a3c4f37e908..de0c13bdcd2c 100644
|
|
--- a/include/linux/compat.h
|
|
+++ b/include/linux/compat.h
|
|
@@ -103,6 +103,9 @@ typedef struct compat_sigaltstack {
|
|
compat_size_t ss_size;
|
|
} compat_stack_t;
|
|
#endif
|
|
+#ifndef COMPAT_MINSIGSTKSZ
|
|
+#define COMPAT_MINSIGSTKSZ MINSIGSTKSZ
|
|
+#endif
|
|
|
|
#define compat_jiffies_to_clock_t(x) \
|
|
(((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
|
|
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
|
index 897eae8faee1..7b6084854bfe 100644
|
|
--- a/include/linux/fs.h
|
|
+++ b/include/linux/fs.h
|
|
@@ -1428,6 +1428,9 @@ struct super_block {
|
|
/* Number of inodes with nlink == 0 but still referenced */
|
|
atomic_long_t s_remove_count;
|
|
|
|
+ /* Pending fsnotify inode refs */
|
|
+ atomic_long_t s_fsnotify_inode_refs;
|
|
+
|
|
/* Being remounted read-only */
|
|
int s_readonly_remount;
|
|
|
|
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
|
|
index d271ff23984f..4f3febc0f971 100644
|
|
--- a/include/linux/hdmi.h
|
|
+++ b/include/linux/hdmi.h
|
|
@@ -101,8 +101,8 @@ enum hdmi_extended_colorimetry {
|
|
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
|
|
HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
|
|
HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
|
|
- HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
|
|
- HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
|
|
+ HDMI_EXTENDED_COLORIMETRY_OPYCC_601,
|
|
+ HDMI_EXTENDED_COLORIMETRY_OPRGB,
|
|
|
|
/* The following EC values are only defined in CEA-861-F. */
|
|
HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM,
|
|
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
|
|
index 68e91ef5494c..818dbe9331be 100644
|
|
--- a/include/linux/nvme.h
|
|
+++ b/include/linux/nvme.h
|
|
@@ -1241,6 +1241,7 @@ enum {
|
|
NVME_SC_ANA_PERSISTENT_LOSS = 0x301,
|
|
NVME_SC_ANA_INACCESSIBLE = 0x302,
|
|
NVME_SC_ANA_TRANSITION = 0x303,
|
|
+ NVME_SC_HOST_PATH_ERROR = 0x370,
|
|
|
|
NVME_SC_DNR = 0x4000,
|
|
};
|
|
diff --git a/include/linux/signal.h b/include/linux/signal.h
|
|
index 3d4cd5db30a9..e4d01469ed60 100644
|
|
--- a/include/linux/signal.h
|
|
+++ b/include/linux/signal.h
|
|
@@ -36,7 +36,7 @@ enum siginfo_layout {
|
|
SIL_SYS,
|
|
};
|
|
|
|
-enum siginfo_layout siginfo_layout(int sig, int si_code);
|
|
+enum siginfo_layout siginfo_layout(unsigned sig, int si_code);
|
|
|
|
/*
|
|
* Define some primitives to manipulate sigset_t.
|
|
diff --git a/include/linux/tc.h b/include/linux/tc.h
|
|
index f92511e57cdb..a60639f37963 100644
|
|
--- a/include/linux/tc.h
|
|
+++ b/include/linux/tc.h
|
|
@@ -84,6 +84,7 @@ struct tc_dev {
|
|
device. */
|
|
struct device dev; /* Generic device interface. */
|
|
struct resource resource; /* Address space of this device. */
|
|
+ u64 dma_mask; /* DMA addressable range. */
|
|
char vendor[9];
|
|
char name[9];
|
|
char firmware[9];
|
|
diff --git a/include/linux/wait.h b/include/linux/wait.h
|
|
index d9f131ecf708..ed7c122cb31f 100644
|
|
--- a/include/linux/wait.h
|
|
+++ b/include/linux/wait.h
|
|
@@ -1052,10 +1052,9 @@ do { \
|
|
__ret; \
|
|
})
|
|
|
|
-#define __wait_event_interruptible_lock_irq_timeout(wq_head, condition, \
|
|
- lock, timeout) \
|
|
+#define __wait_event_lock_irq_timeout(wq_head, condition, lock, timeout, state) \
|
|
___wait_event(wq_head, ___wait_cond_timeout(condition), \
|
|
- TASK_INTERRUPTIBLE, 0, timeout, \
|
|
+ state, 0, timeout, \
|
|
spin_unlock_irq(&lock); \
|
|
__ret = schedule_timeout(__ret); \
|
|
spin_lock_irq(&lock));
|
|
@@ -1089,8 +1088,19 @@ do { \
|
|
({ \
|
|
long __ret = timeout; \
|
|
if (!___wait_cond_timeout(condition)) \
|
|
- __ret = __wait_event_interruptible_lock_irq_timeout( \
|
|
- wq_head, condition, lock, timeout); \
|
|
+ __ret = __wait_event_lock_irq_timeout( \
|
|
+ wq_head, condition, lock, timeout, \
|
|
+ TASK_INTERRUPTIBLE); \
|
|
+ __ret; \
|
|
+})
|
|
+
|
|
+#define wait_event_lock_irq_timeout(wq_head, condition, lock, timeout) \
|
|
+({ \
|
|
+ long __ret = timeout; \
|
|
+ if (!___wait_cond_timeout(condition)) \
|
|
+ __ret = __wait_event_lock_irq_timeout( \
|
|
+ wq_head, condition, lock, timeout, \
|
|
+ TASK_UNINTERRUPTIBLE); \
|
|
__ret; \
|
|
})
|
|
|
|
diff --git a/include/media/cec.h b/include/media/cec.h
|
|
index ff9847f7f99d..9b7394a74dca 100644
|
|
--- a/include/media/cec.h
|
|
+++ b/include/media/cec.h
|
|
@@ -63,7 +63,6 @@ struct cec_data {
|
|
struct delayed_work work;
|
|
struct completion c;
|
|
u8 attempts;
|
|
- bool new_initiator;
|
|
bool blocking;
|
|
bool completed;
|
|
};
|
|
@@ -174,6 +173,7 @@ struct cec_adapter {
|
|
bool is_configuring;
|
|
bool is_configured;
|
|
bool cec_pin_is_high;
|
|
+ u8 last_initiator;
|
|
u32 monitor_all_cnt;
|
|
u32 monitor_pin_cnt;
|
|
u32 follower_cnt;
|
|
@@ -461,4 +461,74 @@ static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
|
|
cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
|
|
}
|
|
|
|
+/**
|
|
+ * cec_get_edid_spa_location() - find location of the Source Physical Address
|
|
+ *
|
|
+ * @edid: the EDID
|
|
+ * @size: the size of the EDID
|
|
+ *
|
|
+ * This EDID is expected to be a CEA-861 compliant, which means that there are
|
|
+ * at least two blocks and one or more of the extensions blocks are CEA-861
|
|
+ * blocks.
|
|
+ *
|
|
+ * The returned location is guaranteed to be <= size-2.
|
|
+ *
|
|
+ * This is an inline function since it is used by both CEC and V4L2.
|
|
+ * Ideally this would go in a module shared by both, but it is overkill to do
|
|
+ * that for just a single function.
|
|
+ */
|
|
+static inline unsigned int cec_get_edid_spa_location(const u8 *edid,
|
|
+ unsigned int size)
|
|
+{
|
|
+ unsigned int blocks = size / 128;
|
|
+ unsigned int block;
|
|
+ u8 d;
|
|
+
|
|
+ /* Sanity check: at least 2 blocks and a multiple of the block size */
|
|
+ if (blocks < 2 || size % 128)
|
|
+ return 0;
|
|
+
|
|
+ /*
|
|
+ * If there are fewer extension blocks than the size, then update
|
|
+ * 'blocks'. It is allowed to have more extension blocks than the size,
|
|
+ * since some hardware can only read e.g. 256 bytes of the EDID, even
|
|
+ * though more blocks are present. The first CEA-861 extension block
|
|
+ * should normally be in block 1 anyway.
|
|
+ */
|
|
+ if (edid[0x7e] + 1 < blocks)
|
|
+ blocks = edid[0x7e] + 1;
|
|
+
|
|
+ for (block = 1; block < blocks; block++) {
|
|
+ unsigned int offset = block * 128;
|
|
+
|
|
+ /* Skip any non-CEA-861 extension blocks */
|
|
+ if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
|
|
+ continue;
|
|
+
|
|
+ /* search Vendor Specific Data Block (tag 3) */
|
|
+ d = edid[offset + 2] & 0x7f;
|
|
+ /* Check if there are Data Blocks */
|
|
+ if (d <= 4)
|
|
+ continue;
|
|
+ if (d > 4) {
|
|
+ unsigned int i = offset + 4;
|
|
+ unsigned int end = offset + d;
|
|
+
|
|
+ /* Note: 'end' is always < 'size' */
|
|
+ do {
|
|
+ u8 tag = edid[i] >> 5;
|
|
+ u8 len = edid[i] & 0x1f;
|
|
+
|
|
+ if (tag == 3 && len >= 5 && i + len <= end &&
|
|
+ edid[i + 1] == 0x03 &&
|
|
+ edid[i + 2] == 0x0c &&
|
|
+ edid[i + 3] == 0x00)
|
|
+ return i + 4;
|
|
+ i += len + 1;
|
|
+ } while (i < end);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#endif /* _MEDIA_CEC_H */
|
|
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
|
|
index e950c2a68f06..ec299fcf55f7 100644
|
|
--- a/include/rdma/ib_verbs.h
|
|
+++ b/include/rdma/ib_verbs.h
|
|
@@ -1278,21 +1278,27 @@ struct ib_qp_attr {
|
|
};
|
|
|
|
enum ib_wr_opcode {
|
|
- IB_WR_RDMA_WRITE,
|
|
- IB_WR_RDMA_WRITE_WITH_IMM,
|
|
- IB_WR_SEND,
|
|
- IB_WR_SEND_WITH_IMM,
|
|
- IB_WR_RDMA_READ,
|
|
- IB_WR_ATOMIC_CMP_AND_SWP,
|
|
- IB_WR_ATOMIC_FETCH_AND_ADD,
|
|
- IB_WR_LSO,
|
|
- IB_WR_SEND_WITH_INV,
|
|
- IB_WR_RDMA_READ_WITH_INV,
|
|
- IB_WR_LOCAL_INV,
|
|
- IB_WR_REG_MR,
|
|
- IB_WR_MASKED_ATOMIC_CMP_AND_SWP,
|
|
- IB_WR_MASKED_ATOMIC_FETCH_AND_ADD,
|
|
+ /* These are shared with userspace */
|
|
+ IB_WR_RDMA_WRITE = IB_UVERBS_WR_RDMA_WRITE,
|
|
+ IB_WR_RDMA_WRITE_WITH_IMM = IB_UVERBS_WR_RDMA_WRITE_WITH_IMM,
|
|
+ IB_WR_SEND = IB_UVERBS_WR_SEND,
|
|
+ IB_WR_SEND_WITH_IMM = IB_UVERBS_WR_SEND_WITH_IMM,
|
|
+ IB_WR_RDMA_READ = IB_UVERBS_WR_RDMA_READ,
|
|
+ IB_WR_ATOMIC_CMP_AND_SWP = IB_UVERBS_WR_ATOMIC_CMP_AND_SWP,
|
|
+ IB_WR_ATOMIC_FETCH_AND_ADD = IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD,
|
|
+ IB_WR_LSO = IB_UVERBS_WR_TSO,
|
|
+ IB_WR_SEND_WITH_INV = IB_UVERBS_WR_SEND_WITH_INV,
|
|
+ IB_WR_RDMA_READ_WITH_INV = IB_UVERBS_WR_RDMA_READ_WITH_INV,
|
|
+ IB_WR_LOCAL_INV = IB_UVERBS_WR_LOCAL_INV,
|
|
+ IB_WR_MASKED_ATOMIC_CMP_AND_SWP =
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP,
|
|
+ IB_WR_MASKED_ATOMIC_FETCH_AND_ADD =
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD,
|
|
+
|
|
+ /* These are kernel only and can not be issued by userspace */
|
|
+ IB_WR_REG_MR = 0x20,
|
|
IB_WR_REG_SIG_MR,
|
|
+
|
|
/* reserve values for low level drivers' internal use.
|
|
* These values will not be used at all in the ib core layer.
|
|
*/
|
|
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
|
|
index 097fcd812471..3094af68b6e7 100644
|
|
--- a/include/uapi/linux/cec.h
|
|
+++ b/include/uapi/linux/cec.h
|
|
@@ -152,10 +152,13 @@ static inline void cec_msg_set_reply_to(struct cec_msg *msg,
|
|
#define CEC_TX_STATUS_LOW_DRIVE (1 << 3)
|
|
#define CEC_TX_STATUS_ERROR (1 << 4)
|
|
#define CEC_TX_STATUS_MAX_RETRIES (1 << 5)
|
|
+#define CEC_TX_STATUS_ABORTED (1 << 6)
|
|
+#define CEC_TX_STATUS_TIMEOUT (1 << 7)
|
|
|
|
#define CEC_RX_STATUS_OK (1 << 0)
|
|
#define CEC_RX_STATUS_TIMEOUT (1 << 1)
|
|
#define CEC_RX_STATUS_FEATURE_ABORT (1 << 2)
|
|
+#define CEC_RX_STATUS_ABORTED (1 << 3)
|
|
|
|
static inline int cec_msg_status_is_ok(const struct cec_msg *msg)
|
|
{
|
|
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
|
|
index 73e01918f996..a441ea1bfe6d 100644
|
|
--- a/include/uapi/linux/fs.h
|
|
+++ b/include/uapi/linux/fs.h
|
|
@@ -279,8 +279,8 @@ struct fsxattr {
|
|
#define FS_ENCRYPTION_MODE_AES_256_CTS 4
|
|
#define FS_ENCRYPTION_MODE_AES_128_CBC 5
|
|
#define FS_ENCRYPTION_MODE_AES_128_CTS 6
|
|
-#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7
|
|
-#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8
|
|
+#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7 /* Removed, do not use. */
|
|
+#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8 /* Removed, do not use. */
|
|
|
|
struct fscrypt_policy {
|
|
__u8 version;
|
|
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
|
|
index 7e27070b9440..2f2c43d633c5 100644
|
|
--- a/include/uapi/linux/ndctl.h
|
|
+++ b/include/uapi/linux/ndctl.h
|
|
@@ -128,37 +128,31 @@ enum {
|
|
|
|
static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
|
|
{
|
|
- static const char * const names[] = {
|
|
- [ND_CMD_ARS_CAP] = "ars_cap",
|
|
- [ND_CMD_ARS_START] = "ars_start",
|
|
- [ND_CMD_ARS_STATUS] = "ars_status",
|
|
- [ND_CMD_CLEAR_ERROR] = "clear_error",
|
|
- [ND_CMD_CALL] = "cmd_call",
|
|
- };
|
|
-
|
|
- if (cmd < ARRAY_SIZE(names) && names[cmd])
|
|
- return names[cmd];
|
|
- return "unknown";
|
|
+ switch (cmd) {
|
|
+ case ND_CMD_ARS_CAP: return "ars_cap";
|
|
+ case ND_CMD_ARS_START: return "ars_start";
|
|
+ case ND_CMD_ARS_STATUS: return "ars_status";
|
|
+ case ND_CMD_CLEAR_ERROR: return "clear_error";
|
|
+ case ND_CMD_CALL: return "cmd_call";
|
|
+ default: return "unknown";
|
|
+ }
|
|
}
|
|
|
|
static inline const char *nvdimm_cmd_name(unsigned cmd)
|
|
{
|
|
- static const char * const names[] = {
|
|
- [ND_CMD_SMART] = "smart",
|
|
- [ND_CMD_SMART_THRESHOLD] = "smart_thresh",
|
|
- [ND_CMD_DIMM_FLAGS] = "flags",
|
|
- [ND_CMD_GET_CONFIG_SIZE] = "get_size",
|
|
- [ND_CMD_GET_CONFIG_DATA] = "get_data",
|
|
- [ND_CMD_SET_CONFIG_DATA] = "set_data",
|
|
- [ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
|
|
- [ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
|
|
- [ND_CMD_VENDOR] = "vendor",
|
|
- [ND_CMD_CALL] = "cmd_call",
|
|
- };
|
|
-
|
|
- if (cmd < ARRAY_SIZE(names) && names[cmd])
|
|
- return names[cmd];
|
|
- return "unknown";
|
|
+ switch (cmd) {
|
|
+ case ND_CMD_SMART: return "smart";
|
|
+ case ND_CMD_SMART_THRESHOLD: return "smart_thresh";
|
|
+ case ND_CMD_DIMM_FLAGS: return "flags";
|
|
+ case ND_CMD_GET_CONFIG_SIZE: return "get_size";
|
|
+ case ND_CMD_GET_CONFIG_DATA: return "get_data";
|
|
+ case ND_CMD_SET_CONFIG_DATA: return "set_data";
|
|
+ case ND_CMD_VENDOR_EFFECT_LOG_SIZE: return "effect_size";
|
|
+ case ND_CMD_VENDOR_EFFECT_LOG: return "effect_log";
|
|
+ case ND_CMD_VENDOR: return "vendor";
|
|
+ case ND_CMD_CALL: return "cmd_call";
|
|
+ default: return "unknown";
|
|
+ }
|
|
}
|
|
|
|
#define ND_IOCTL 'N'
|
|
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
|
index 5d1a3685bea9..1aae2e4b8f10 100644
|
|
--- a/include/uapi/linux/videodev2.h
|
|
+++ b/include/uapi/linux/videodev2.h
|
|
@@ -225,8 +225,8 @@ enum v4l2_colorspace {
|
|
/* For RGB colorspaces such as produces by most webcams. */
|
|
V4L2_COLORSPACE_SRGB = 8,
|
|
|
|
- /* AdobeRGB colorspace */
|
|
- V4L2_COLORSPACE_ADOBERGB = 9,
|
|
+ /* opRGB colorspace */
|
|
+ V4L2_COLORSPACE_OPRGB = 9,
|
|
|
|
/* BT.2020 colorspace, used for UHDTV. */
|
|
V4L2_COLORSPACE_BT2020 = 10,
|
|
@@ -258,7 +258,7 @@ enum v4l2_xfer_func {
|
|
*
|
|
* V4L2_COLORSPACE_SRGB, V4L2_COLORSPACE_JPEG: V4L2_XFER_FUNC_SRGB
|
|
*
|
|
- * V4L2_COLORSPACE_ADOBERGB: V4L2_XFER_FUNC_ADOBERGB
|
|
+ * V4L2_COLORSPACE_OPRGB: V4L2_XFER_FUNC_OPRGB
|
|
*
|
|
* V4L2_COLORSPACE_SMPTE240M: V4L2_XFER_FUNC_SMPTE240M
|
|
*
|
|
@@ -269,7 +269,7 @@ enum v4l2_xfer_func {
|
|
V4L2_XFER_FUNC_DEFAULT = 0,
|
|
V4L2_XFER_FUNC_709 = 1,
|
|
V4L2_XFER_FUNC_SRGB = 2,
|
|
- V4L2_XFER_FUNC_ADOBERGB = 3,
|
|
+ V4L2_XFER_FUNC_OPRGB = 3,
|
|
V4L2_XFER_FUNC_SMPTE240M = 4,
|
|
V4L2_XFER_FUNC_NONE = 5,
|
|
V4L2_XFER_FUNC_DCI_P3 = 6,
|
|
@@ -281,7 +281,7 @@ enum v4l2_xfer_func {
|
|
* This depends on the colorspace.
|
|
*/
|
|
#define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) \
|
|
- ((colsp) == V4L2_COLORSPACE_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : \
|
|
+ ((colsp) == V4L2_COLORSPACE_OPRGB ? V4L2_XFER_FUNC_OPRGB : \
|
|
((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : \
|
|
((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : \
|
|
((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : \
|
|
@@ -295,7 +295,7 @@ enum v4l2_ycbcr_encoding {
|
|
*
|
|
* V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M,
|
|
* V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_SRGB,
|
|
- * V4L2_COLORSPACE_ADOBERGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601
|
|
+ * V4L2_COLORSPACE_OPRGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601
|
|
*
|
|
* V4L2_COLORSPACE_REC709 and V4L2_COLORSPACE_DCI_P3: V4L2_YCBCR_ENC_709
|
|
*
|
|
@@ -382,6 +382,17 @@ enum v4l2_quantization {
|
|
(((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \
|
|
V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE))
|
|
|
|
+/*
|
|
+ * Deprecated names for opRGB colorspace (IEC 61966-2-5)
|
|
+ *
|
|
+ * WARNING: Please don't use these deprecated defines in your code, as
|
|
+ * there is a chance we have to remove them in the future.
|
|
+ */
|
|
+#ifndef __KERNEL__
|
|
+#define V4L2_COLORSPACE_ADOBERGB V4L2_COLORSPACE_OPRGB
|
|
+#define V4L2_XFER_FUNC_ADOBERGB V4L2_XFER_FUNC_OPRGB
|
|
+#endif
|
|
+
|
|
enum v4l2_priority {
|
|
V4L2_PRIORITY_UNSET = 0, /* not initialized */
|
|
V4L2_PRIORITY_BACKGROUND = 1,
|
|
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h
|
|
index 25a16760de2a..1254b51a551a 100644
|
|
--- a/include/uapi/rdma/ib_user_verbs.h
|
|
+++ b/include/uapi/rdma/ib_user_verbs.h
|
|
@@ -763,10 +763,28 @@ struct ib_uverbs_sge {
|
|
__u32 lkey;
|
|
};
|
|
|
|
+enum ib_uverbs_wr_opcode {
|
|
+ IB_UVERBS_WR_RDMA_WRITE = 0,
|
|
+ IB_UVERBS_WR_RDMA_WRITE_WITH_IMM = 1,
|
|
+ IB_UVERBS_WR_SEND = 2,
|
|
+ IB_UVERBS_WR_SEND_WITH_IMM = 3,
|
|
+ IB_UVERBS_WR_RDMA_READ = 4,
|
|
+ IB_UVERBS_WR_ATOMIC_CMP_AND_SWP = 5,
|
|
+ IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD = 6,
|
|
+ IB_UVERBS_WR_LOCAL_INV = 7,
|
|
+ IB_UVERBS_WR_BIND_MW = 8,
|
|
+ IB_UVERBS_WR_SEND_WITH_INV = 9,
|
|
+ IB_UVERBS_WR_TSO = 10,
|
|
+ IB_UVERBS_WR_RDMA_READ_WITH_INV = 11,
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12,
|
|
+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13,
|
|
+ /* Review enum ib_wr_opcode before modifying this */
|
|
+};
|
|
+
|
|
struct ib_uverbs_send_wr {
|
|
__aligned_u64 wr_id;
|
|
__u32 num_sge;
|
|
- __u32 opcode;
|
|
+ __u32 opcode; /* see enum ib_uverbs_wr_opcode */
|
|
__u32 send_flags;
|
|
union {
|
|
__be32 imm_data;
|
|
diff --git a/kernel/bounds.c b/kernel/bounds.c
|
|
index c373e887c066..9795d75b09b2 100644
|
|
--- a/kernel/bounds.c
|
|
+++ b/kernel/bounds.c
|
|
@@ -13,7 +13,7 @@
|
|
#include <linux/log2.h>
|
|
#include <linux/spinlock_types.h>
|
|
|
|
-void foo(void)
|
|
+int main(void)
|
|
{
|
|
/* The enum constants to put into include/generated/bounds.h */
|
|
DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS);
|
|
@@ -23,4 +23,6 @@ void foo(void)
|
|
#endif
|
|
DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
|
|
/* End of constants */
|
|
+
|
|
+ return 0;
|
|
}
|
|
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
|
|
index 8339d81cba1d..675eb6d36e47 100644
|
|
--- a/kernel/bpf/syscall.c
|
|
+++ b/kernel/bpf/syscall.c
|
|
@@ -741,6 +741,17 @@ err_put:
|
|
return err;
|
|
}
|
|
|
|
+static void maybe_wait_bpf_programs(struct bpf_map *map)
|
|
+{
|
|
+ /* Wait for any running BPF programs to complete so that
|
|
+ * userspace, when we return to it, knows that all programs
|
|
+ * that could be running use the new map value.
|
|
+ */
|
|
+ if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS ||
|
|
+ map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
|
|
+ synchronize_rcu();
|
|
+}
|
|
+
|
|
#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
|
|
|
|
static int map_update_elem(union bpf_attr *attr)
|
|
@@ -831,6 +842,7 @@ static int map_update_elem(union bpf_attr *attr)
|
|
}
|
|
__this_cpu_dec(bpf_prog_active);
|
|
preempt_enable();
|
|
+ maybe_wait_bpf_programs(map);
|
|
out:
|
|
free_value:
|
|
kfree(value);
|
|
@@ -883,6 +895,7 @@ static int map_delete_elem(union bpf_attr *attr)
|
|
rcu_read_unlock();
|
|
__this_cpu_dec(bpf_prog_active);
|
|
preempt_enable();
|
|
+ maybe_wait_bpf_programs(map);
|
|
out:
|
|
kfree(key);
|
|
err_put:
|
|
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
|
|
index 465952a8e465..5780876ac81a 100644
|
|
--- a/kernel/bpf/verifier.c
|
|
+++ b/kernel/bpf/verifier.c
|
|
@@ -553,7 +553,9 @@ static void __mark_reg_not_init(struct bpf_reg_state *reg);
|
|
*/
|
|
static void __mark_reg_known(struct bpf_reg_state *reg, u64 imm)
|
|
{
|
|
- reg->id = 0;
|
|
+ /* Clear id, off, and union(map_ptr, range) */
|
|
+ memset(((u8 *)reg) + sizeof(reg->type), 0,
|
|
+ offsetof(struct bpf_reg_state, var_off) - sizeof(reg->type));
|
|
reg->var_off = tnum_const(imm);
|
|
reg->smin_value = (s64)imm;
|
|
reg->smax_value = (s64)imm;
|
|
@@ -572,7 +574,6 @@ static void __mark_reg_known_zero(struct bpf_reg_state *reg)
|
|
static void __mark_reg_const_zero(struct bpf_reg_state *reg)
|
|
{
|
|
__mark_reg_known(reg, 0);
|
|
- reg->off = 0;
|
|
reg->type = SCALAR_VALUE;
|
|
}
|
|
|
|
@@ -683,9 +684,12 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg)
|
|
/* Mark a register as having a completely unknown (scalar) value. */
|
|
static void __mark_reg_unknown(struct bpf_reg_state *reg)
|
|
{
|
|
+ /*
|
|
+ * Clear type, id, off, and union(map_ptr, range) and
|
|
+ * padding between 'type' and union
|
|
+ */
|
|
+ memset(reg, 0, offsetof(struct bpf_reg_state, var_off));
|
|
reg->type = SCALAR_VALUE;
|
|
- reg->id = 0;
|
|
- reg->off = 0;
|
|
reg->var_off = tnum_unknown;
|
|
reg->frameno = 0;
|
|
__mark_reg_unbounded(reg);
|
|
@@ -1727,9 +1731,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
|
|
else
|
|
mark_reg_known_zero(env, regs,
|
|
value_regno);
|
|
- regs[value_regno].id = 0;
|
|
- regs[value_regno].off = 0;
|
|
- regs[value_regno].range = 0;
|
|
regs[value_regno].type = reg_type;
|
|
}
|
|
|
|
@@ -2580,7 +2581,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
|
|
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
|
|
/* There is no offset yet applied, variable or fixed */
|
|
mark_reg_known_zero(env, regs, BPF_REG_0);
|
|
- regs[BPF_REG_0].off = 0;
|
|
/* remember map_ptr, so that check_map_access()
|
|
* can check 'value_size' boundary of memory access
|
|
* to map element returned from bpf_map_lookup_elem()
|
|
@@ -2762,7 +2762,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
|
|
dst_reg->umax_value = umax_ptr;
|
|
dst_reg->var_off = ptr_reg->var_off;
|
|
dst_reg->off = ptr_reg->off + smin_val;
|
|
- dst_reg->range = ptr_reg->range;
|
|
+ dst_reg->raw = ptr_reg->raw;
|
|
break;
|
|
}
|
|
/* A new variable offset is created. Note that off_reg->off
|
|
@@ -2792,10 +2792,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
|
|
}
|
|
dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off);
|
|
dst_reg->off = ptr_reg->off;
|
|
+ dst_reg->raw = ptr_reg->raw;
|
|
if (reg_is_pkt_pointer(ptr_reg)) {
|
|
dst_reg->id = ++env->id_gen;
|
|
/* something was added to pkt_ptr, set range to zero */
|
|
- dst_reg->range = 0;
|
|
+ dst_reg->raw = 0;
|
|
}
|
|
break;
|
|
case BPF_SUB:
|
|
@@ -2824,7 +2825,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
|
|
dst_reg->var_off = ptr_reg->var_off;
|
|
dst_reg->id = ptr_reg->id;
|
|
dst_reg->off = ptr_reg->off - smin_val;
|
|
- dst_reg->range = ptr_reg->range;
|
|
+ dst_reg->raw = ptr_reg->raw;
|
|
break;
|
|
}
|
|
/* A new variable offset is created. If the subtrahend is known
|
|
@@ -2850,11 +2851,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
|
|
}
|
|
dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off);
|
|
dst_reg->off = ptr_reg->off;
|
|
+ dst_reg->raw = ptr_reg->raw;
|
|
if (reg_is_pkt_pointer(ptr_reg)) {
|
|
dst_reg->id = ++env->id_gen;
|
|
/* something was added to pkt_ptr, set range to zero */
|
|
if (smin_val < 0)
|
|
- dst_reg->range = 0;
|
|
+ dst_reg->raw = 0;
|
|
}
|
|
break;
|
|
case BPF_AND:
|
|
diff --git a/kernel/cpu.c b/kernel/cpu.c
|
|
index 0097acec1c71..3adecda21444 100644
|
|
--- a/kernel/cpu.c
|
|
+++ b/kernel/cpu.c
|
|
@@ -2026,6 +2026,12 @@ static void cpuhp_online_cpu_device(unsigned int cpu)
|
|
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
|
}
|
|
|
|
+/*
|
|
+ * Architectures that need SMT-specific errata handling during SMT hotplug
|
|
+ * should override this.
|
|
+ */
|
|
+void __weak arch_smt_update(void) { };
|
|
+
|
|
static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
|
{
|
|
int cpu, ret = 0;
|
|
@@ -2052,8 +2058,10 @@ static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
|
*/
|
|
cpuhp_offline_cpu_device(cpu);
|
|
}
|
|
- if (!ret)
|
|
+ if (!ret) {
|
|
cpu_smt_control = ctrlval;
|
|
+ arch_smt_update();
|
|
+ }
|
|
cpu_maps_update_done();
|
|
return ret;
|
|
}
|
|
@@ -2064,6 +2072,7 @@ static int cpuhp_smt_enable(void)
|
|
|
|
cpu_maps_update_begin();
|
|
cpu_smt_control = CPU_SMT_ENABLED;
|
|
+ arch_smt_update();
|
|
for_each_present_cpu(cpu) {
|
|
/* Skip online CPUs and CPUs on offline nodes */
|
|
if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
|
|
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
|
|
index 286d82329eb0..b2a87905846d 100644
|
|
--- a/kernel/dma/contiguous.c
|
|
+++ b/kernel/dma/contiguous.c
|
|
@@ -49,7 +49,11 @@ static phys_addr_t limit_cmdline;
|
|
|
|
static int __init early_cma(char *p)
|
|
{
|
|
- pr_debug("%s(%s)\n", __func__, p);
|
|
+ if (!p) {
|
|
+ pr_err("Config string not provided\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
size_cmdline = memparse(p, &p);
|
|
if (*p != '@')
|
|
return 0;
|
|
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
|
|
index fb86146037a7..9dbdccab3b6a 100644
|
|
--- a/kernel/irq/manage.c
|
|
+++ b/kernel/irq/manage.c
|
|
@@ -927,6 +927,9 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
|
|
|
|
local_bh_disable();
|
|
ret = action->thread_fn(action->irq, action->dev_id);
|
|
+ if (ret == IRQ_HANDLED)
|
|
+ atomic_inc(&desc->threads_handled);
|
|
+
|
|
irq_finalize_oneshot(desc, action);
|
|
local_bh_enable();
|
|
return ret;
|
|
@@ -943,6 +946,9 @@ static irqreturn_t irq_thread_fn(struct irq_desc *desc,
|
|
irqreturn_t ret;
|
|
|
|
ret = action->thread_fn(action->irq, action->dev_id);
|
|
+ if (ret == IRQ_HANDLED)
|
|
+ atomic_inc(&desc->threads_handled);
|
|
+
|
|
irq_finalize_oneshot(desc, action);
|
|
return ret;
|
|
}
|
|
@@ -1020,8 +1026,6 @@ static int irq_thread(void *data)
|
|
irq_thread_check_affinity(desc, action);
|
|
|
|
action_ret = handler_fn(desc, action);
|
|
- if (action_ret == IRQ_HANDLED)
|
|
- atomic_inc(&desc->threads_handled);
|
|
if (action_ret == IRQ_WAKE_THREAD)
|
|
irq_wake_secondary(desc, action);
|
|
|
|
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
|
|
index ab257be4d924..4344381664cc 100644
|
|
--- a/kernel/kprobes.c
|
|
+++ b/kernel/kprobes.c
|
|
@@ -700,9 +700,10 @@ static void unoptimize_kprobe(struct kprobe *p, bool force)
|
|
}
|
|
|
|
/* Cancel unoptimizing for reusing */
|
|
-static void reuse_unused_kprobe(struct kprobe *ap)
|
|
+static int reuse_unused_kprobe(struct kprobe *ap)
|
|
{
|
|
struct optimized_kprobe *op;
|
|
+ int ret;
|
|
|
|
BUG_ON(!kprobe_unused(ap));
|
|
/*
|
|
@@ -714,8 +715,12 @@ static void reuse_unused_kprobe(struct kprobe *ap)
|
|
/* Enable the probe again */
|
|
ap->flags &= ~KPROBE_FLAG_DISABLED;
|
|
/* Optimize it again (remove from op->list) */
|
|
- BUG_ON(!kprobe_optready(ap));
|
|
+ ret = kprobe_optready(ap);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
optimize_kprobe(ap);
|
|
+ return 0;
|
|
}
|
|
|
|
/* Remove optimized instructions */
|
|
@@ -940,11 +945,16 @@ static void __disarm_kprobe(struct kprobe *p, bool reopt)
|
|
#define kprobe_disarmed(p) kprobe_disabled(p)
|
|
#define wait_for_kprobe_optimizer() do {} while (0)
|
|
|
|
-/* There should be no unused kprobes can be reused without optimization */
|
|
-static void reuse_unused_kprobe(struct kprobe *ap)
|
|
+static int reuse_unused_kprobe(struct kprobe *ap)
|
|
{
|
|
+ /*
|
|
+ * If the optimized kprobe is NOT supported, the aggr kprobe is
|
|
+ * released at the same time that the last aggregated kprobe is
|
|
+ * unregistered.
|
|
+ * Thus there should be no chance to reuse unused kprobe.
|
|
+ */
|
|
printk(KERN_ERR "Error: There should be no unused kprobe here.\n");
|
|
- BUG_ON(kprobe_unused(ap));
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
static void free_aggr_kprobe(struct kprobe *p)
|
|
@@ -1318,9 +1328,12 @@ static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p)
|
|
goto out;
|
|
}
|
|
init_aggr_kprobe(ap, orig_p);
|
|
- } else if (kprobe_unused(ap))
|
|
+ } else if (kprobe_unused(ap)) {
|
|
/* This probe is going to die. Rescue it */
|
|
- reuse_unused_kprobe(ap);
|
|
+ ret = reuse_unused_kprobe(ap);
|
|
+ if (ret)
|
|
+ goto out;
|
|
+ }
|
|
|
|
if (kprobe_gone(ap)) {
|
|
/*
|
|
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
|
|
index dd13f865ad40..26b57e24476f 100644
|
|
--- a/kernel/locking/lockdep.c
|
|
+++ b/kernel/locking/lockdep.c
|
|
@@ -4122,7 +4122,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
|
|
{
|
|
unsigned long flags;
|
|
|
|
- if (unlikely(!lock_stat))
|
|
+ if (unlikely(!lock_stat || !debug_locks))
|
|
return;
|
|
|
|
if (unlikely(current->lockdep_recursion))
|
|
@@ -4142,7 +4142,7 @@ void lock_acquired(struct lockdep_map *lock, unsigned long ip)
|
|
{
|
|
unsigned long flags;
|
|
|
|
- if (unlikely(!lock_stat))
|
|
+ if (unlikely(!lock_stat || !debug_locks))
|
|
return;
|
|
|
|
if (unlikely(current->lockdep_recursion))
|
|
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
|
|
index 9bf5404397e0..06045abd1887 100644
|
|
--- a/kernel/printk/printk.c
|
|
+++ b/kernel/printk/printk.c
|
|
@@ -1048,7 +1048,12 @@ static void __init log_buf_len_update(unsigned size)
|
|
/* save requested log_buf_len since it's too early to process it */
|
|
static int __init log_buf_len_setup(char *str)
|
|
{
|
|
- unsigned size = memparse(str, &str);
|
|
+ unsigned int size;
|
|
+
|
|
+ if (!str)
|
|
+ return -EINVAL;
|
|
+
|
|
+ size = memparse(str, &str);
|
|
|
|
log_buf_len_update(size);
|
|
|
|
diff --git a/kernel/signal.c b/kernel/signal.c
|
|
index 5843c541fda9..edc28afc9fb4 100644
|
|
--- a/kernel/signal.c
|
|
+++ b/kernel/signal.c
|
|
@@ -1035,7 +1035,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
|
|
|
result = TRACE_SIGNAL_IGNORED;
|
|
if (!prepare_signal(sig, t,
|
|
- from_ancestor_ns || (info == SEND_SIG_FORCED)))
|
|
+ from_ancestor_ns || (info == SEND_SIG_PRIV) || (info == SEND_SIG_FORCED)))
|
|
goto ret;
|
|
|
|
pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
|
|
@@ -2847,7 +2847,7 @@ COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
|
|
}
|
|
#endif
|
|
|
|
-enum siginfo_layout siginfo_layout(int sig, int si_code)
|
|
+enum siginfo_layout siginfo_layout(unsigned sig, int si_code)
|
|
{
|
|
enum siginfo_layout layout = SIL_KILL;
|
|
if ((si_code > SI_USER) && (si_code < SI_KERNEL)) {
|
|
@@ -3460,7 +3460,8 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
|
|
}
|
|
|
|
static int
|
|
-do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp)
|
|
+do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp,
|
|
+ size_t min_ss_size)
|
|
{
|
|
struct task_struct *t = current;
|
|
|
|
@@ -3490,7 +3491,7 @@ do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp)
|
|
ss_size = 0;
|
|
ss_sp = NULL;
|
|
} else {
|
|
- if (unlikely(ss_size < MINSIGSTKSZ))
|
|
+ if (unlikely(ss_size < min_ss_size))
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -3508,7 +3509,8 @@ SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
|
|
if (uss && copy_from_user(&new, uss, sizeof(stack_t)))
|
|
return -EFAULT;
|
|
err = do_sigaltstack(uss ? &new : NULL, uoss ? &old : NULL,
|
|
- current_user_stack_pointer());
|
|
+ current_user_stack_pointer(),
|
|
+ MINSIGSTKSZ);
|
|
if (!err && uoss && copy_to_user(uoss, &old, sizeof(stack_t)))
|
|
err = -EFAULT;
|
|
return err;
|
|
@@ -3519,7 +3521,8 @@ int restore_altstack(const stack_t __user *uss)
|
|
stack_t new;
|
|
if (copy_from_user(&new, uss, sizeof(stack_t)))
|
|
return -EFAULT;
|
|
- (void)do_sigaltstack(&new, NULL, current_user_stack_pointer());
|
|
+ (void)do_sigaltstack(&new, NULL, current_user_stack_pointer(),
|
|
+ MINSIGSTKSZ);
|
|
/* squash all but EFAULT for now */
|
|
return 0;
|
|
}
|
|
@@ -3553,7 +3556,8 @@ static int do_compat_sigaltstack(const compat_stack_t __user *uss_ptr,
|
|
uss.ss_size = uss32.ss_size;
|
|
}
|
|
ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss,
|
|
- compat_user_stack_pointer());
|
|
+ compat_user_stack_pointer(),
|
|
+ COMPAT_MINSIGSTKSZ);
|
|
if (ret >= 0 && uoss_ptr) {
|
|
compat_stack_t old;
|
|
memset(&old, 0, sizeof(old));
|
|
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
|
|
index d239004aaf29..eb908ef2ecec 100644
|
|
--- a/kernel/trace/trace_events_hist.c
|
|
+++ b/kernel/trace/trace_events_hist.c
|
|
@@ -1063,8 +1063,10 @@ static int create_synth_event(int argc, char **argv)
|
|
event = NULL;
|
|
ret = -EEXIST;
|
|
goto out;
|
|
- } else if (delete_event)
|
|
+ } else if (delete_event) {
|
|
+ ret = -ENOENT;
|
|
goto out;
|
|
+ }
|
|
|
|
if (argc < 2) {
|
|
ret = -EINVAL;
|
|
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
|
|
index e5222b5fb4fe..923414a246e9 100644
|
|
--- a/kernel/user_namespace.c
|
|
+++ b/kernel/user_namespace.c
|
|
@@ -974,10 +974,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
|
|
if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
|
|
goto out;
|
|
|
|
- ret = sort_idmaps(&new_map);
|
|
- if (ret < 0)
|
|
- goto out;
|
|
-
|
|
ret = -EPERM;
|
|
/* Map the lower ids from the parent user namespace to the
|
|
* kernel global id space.
|
|
@@ -1004,6 +1000,14 @@ static ssize_t map_write(struct file *file, const char __user *buf,
|
|
e->lower_first = lower_first;
|
|
}
|
|
|
|
+ /*
|
|
+ * If we want to use binary search for lookup, this clones the extent
|
|
+ * array and sorts both copies.
|
|
+ */
|
|
+ ret = sort_idmaps(&new_map);
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+
|
|
/* Install the map */
|
|
if (new_map.nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS) {
|
|
memcpy(map->extent, new_map.extent,
|
|
diff --git a/lib/debug_locks.c b/lib/debug_locks.c
|
|
index 96c4c633d95e..124fdf238b3d 100644
|
|
--- a/lib/debug_locks.c
|
|
+++ b/lib/debug_locks.c
|
|
@@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(debug_locks_silent);
|
|
*/
|
|
int debug_locks_off(void)
|
|
{
|
|
- if (__debug_locks_off()) {
|
|
+ if (debug_locks && __debug_locks_off()) {
|
|
if (!debug_locks_silent) {
|
|
console_verbose();
|
|
return 1;
|
|
diff --git a/mm/hmm.c b/mm/hmm.c
|
|
index c968e49f7a0c..90193a7fabce 100644
|
|
--- a/mm/hmm.c
|
|
+++ b/mm/hmm.c
|
|
@@ -91,16 +91,6 @@ static struct hmm *hmm_register(struct mm_struct *mm)
|
|
spin_lock_init(&hmm->lock);
|
|
hmm->mm = mm;
|
|
|
|
- /*
|
|
- * We should only get here if hold the mmap_sem in write mode ie on
|
|
- * registration of first mirror through hmm_mirror_register()
|
|
- */
|
|
- hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops;
|
|
- if (__mmu_notifier_register(&hmm->mmu_notifier, mm)) {
|
|
- kfree(hmm);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
spin_lock(&mm->page_table_lock);
|
|
if (!mm->hmm)
|
|
mm->hmm = hmm;
|
|
@@ -108,12 +98,27 @@ static struct hmm *hmm_register(struct mm_struct *mm)
|
|
cleanup = true;
|
|
spin_unlock(&mm->page_table_lock);
|
|
|
|
- if (cleanup) {
|
|
- mmu_notifier_unregister(&hmm->mmu_notifier, mm);
|
|
- kfree(hmm);
|
|
- }
|
|
+ if (cleanup)
|
|
+ goto error;
|
|
+
|
|
+ /*
|
|
+ * We should only get here if hold the mmap_sem in write mode ie on
|
|
+ * registration of first mirror through hmm_mirror_register()
|
|
+ */
|
|
+ hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops;
|
|
+ if (__mmu_notifier_register(&hmm->mmu_notifier, mm))
|
|
+ goto error_mm;
|
|
|
|
return mm->hmm;
|
|
+
|
|
+error_mm:
|
|
+ spin_lock(&mm->page_table_lock);
|
|
+ if (mm->hmm == hmm)
|
|
+ mm->hmm = NULL;
|
|
+ spin_unlock(&mm->page_table_lock);
|
|
+error:
|
|
+ kfree(hmm);
|
|
+ return NULL;
|
|
}
|
|
|
|
void hmm_mm_destroy(struct mm_struct *mm)
|
|
@@ -278,12 +283,13 @@ void hmm_mirror_unregister(struct hmm_mirror *mirror)
|
|
if (!should_unregister || mm == NULL)
|
|
return;
|
|
|
|
+ mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm);
|
|
+
|
|
spin_lock(&mm->page_table_lock);
|
|
if (mm->hmm == hmm)
|
|
mm->hmm = NULL;
|
|
spin_unlock(&mm->page_table_lock);
|
|
|
|
- mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm);
|
|
kfree(hmm);
|
|
}
|
|
EXPORT_SYMBOL(hmm_mirror_unregister);
|
|
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
|
|
index 5c390f5a5207..7b5c0ad9a6bd 100644
|
|
--- a/mm/hugetlb.c
|
|
+++ b/mm/hugetlb.c
|
|
@@ -3690,6 +3690,12 @@ int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
|
|
return err;
|
|
ClearPagePrivate(page);
|
|
|
|
+ /*
|
|
+ * set page dirty so that it will not be removed from cache/file
|
|
+ * by non-hugetlbfs specific code paths.
|
|
+ */
|
|
+ set_page_dirty(page);
|
|
+
|
|
spin_lock(&inode->i_lock);
|
|
inode->i_blocks += blocks_per_huge_page(h);
|
|
spin_unlock(&inode->i_lock);
|
|
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
|
|
index ae3c2a35d61b..11df03e71288 100644
|
|
--- a/mm/page_vma_mapped.c
|
|
+++ b/mm/page_vma_mapped.c
|
|
@@ -21,7 +21,29 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw)
|
|
if (!is_swap_pte(*pvmw->pte))
|
|
return false;
|
|
} else {
|
|
- if (!pte_present(*pvmw->pte))
|
|
+ /*
|
|
+ * We get here when we are trying to unmap a private
|
|
+ * device page from the process address space. Such
|
|
+ * page is not CPU accessible and thus is mapped as
|
|
+ * a special swap entry, nonetheless it still does
|
|
+ * count as a valid regular mapping for the page (and
|
|
+ * is accounted as such in page maps count).
|
|
+ *
|
|
+ * So handle this special case as if it was a normal
|
|
+ * page mapping ie lock CPU page table and returns
|
|
+ * true.
|
|
+ *
|
|
+ * For more details on device private memory see HMM
|
|
+ * (include/linux/hmm.h or mm/hmm.c).
|
|
+ */
|
|
+ if (is_swap_pte(*pvmw->pte)) {
|
|
+ swp_entry_t entry;
|
|
+
|
|
+ /* Handle un-addressable ZONE_DEVICE memory */
|
|
+ entry = pte_to_swp_entry(*pvmw->pte);
|
|
+ if (!is_device_private_entry(entry))
|
|
+ return false;
|
|
+ } else if (!pte_present(*pvmw->pte))
|
|
return false;
|
|
}
|
|
}
|
|
diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c
|
|
index 5e4f04004a49..7bf833598615 100644
|
|
--- a/net/core/netclassid_cgroup.c
|
|
+++ b/net/core/netclassid_cgroup.c
|
|
@@ -106,6 +106,7 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
|
|
iterate_fd(p->files, 0, update_classid_sock,
|
|
(void *)(unsigned long)cs->classid);
|
|
task_unlock(p);
|
|
+ cond_resched();
|
|
}
|
|
css_task_iter_end(&it);
|
|
|
|
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
|
|
index 82178cc69c96..777fa3b7fb13 100644
|
|
--- a/net/ipv4/cipso_ipv4.c
|
|
+++ b/net/ipv4/cipso_ipv4.c
|
|
@@ -1512,7 +1512,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,
|
|
*
|
|
* Description:
|
|
* Parse the packet's IP header looking for a CIPSO option. Returns a pointer
|
|
- * to the start of the CIPSO option on success, NULL if one if not found.
|
|
+ * to the start of the CIPSO option on success, NULL if one is not found.
|
|
*
|
|
*/
|
|
unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
|
|
@@ -1522,10 +1522,8 @@ unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
|
|
int optlen;
|
|
int taglen;
|
|
|
|
- for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 0; ) {
|
|
+ for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 1; ) {
|
|
switch (optptr[0]) {
|
|
- case IPOPT_CIPSO:
|
|
- return optptr;
|
|
case IPOPT_END:
|
|
return NULL;
|
|
case IPOPT_NOOP:
|
|
@@ -1534,6 +1532,11 @@ unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
|
|
default:
|
|
taglen = optptr[1];
|
|
}
|
|
+ if (!taglen || taglen > optlen)
|
|
+ return NULL;
|
|
+ if (optptr[0] == IPOPT_CIPSO)
|
|
+ return optptr;
|
|
+
|
|
optlen -= taglen;
|
|
optptr += taglen;
|
|
}
|
|
diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c
|
|
index 8af9707f8789..ac91170fc8c8 100644
|
|
--- a/net/netfilter/xt_nat.c
|
|
+++ b/net/netfilter/xt_nat.c
|
|
@@ -216,6 +216,8 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = {
|
|
{
|
|
.name = "DNAT",
|
|
.revision = 2,
|
|
+ .checkentry = xt_nat_checkentry,
|
|
+ .destroy = xt_nat_destroy,
|
|
.target = xt_dnat_target_v2,
|
|
.targetsize = sizeof(struct nf_nat_range2),
|
|
.table = "nat",
|
|
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
|
|
index 3dc0acf54245..be7cd140b2a3 100644
|
|
--- a/net/sched/sch_api.c
|
|
+++ b/net/sched/sch_api.c
|
|
@@ -1309,7 +1309,6 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
|
|
|
|
const struct nla_policy rtm_tca_policy[TCA_MAX + 1] = {
|
|
[TCA_KIND] = { .type = NLA_STRING },
|
|
- [TCA_OPTIONS] = { .type = NLA_NESTED },
|
|
[TCA_RATE] = { .type = NLA_BINARY,
|
|
.len = sizeof(struct tc_estimator) },
|
|
[TCA_STAB] = { .type = NLA_NESTED },
|
|
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
|
|
index 5185efb9027b..83ccd0221c98 100644
|
|
--- a/net/sunrpc/svc_xprt.c
|
|
+++ b/net/sunrpc/svc_xprt.c
|
|
@@ -989,7 +989,7 @@ static void call_xpt_users(struct svc_xprt *xprt)
|
|
spin_lock(&xprt->xpt_lock);
|
|
while (!list_empty(&xprt->xpt_users)) {
|
|
u = list_first_entry(&xprt->xpt_users, struct svc_xpt_user, list);
|
|
- list_del(&u->list);
|
|
+ list_del_init(&u->list);
|
|
u->callback(u);
|
|
}
|
|
spin_unlock(&xprt->xpt_lock);
|
|
diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
|
|
index a68180090554..b9827665ff35 100644
|
|
--- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
|
|
+++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
|
|
@@ -248,6 +248,7 @@ static void
|
|
xprt_rdma_bc_close(struct rpc_xprt *xprt)
|
|
{
|
|
dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
|
|
+ xprt->cwnd = RPC_CWNDSHIFT;
|
|
}
|
|
|
|
static void
|
|
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
|
|
index 143ce2579ba9..98cbc7b060ba 100644
|
|
--- a/net/sunrpc/xprtrdma/transport.c
|
|
+++ b/net/sunrpc/xprtrdma/transport.c
|
|
@@ -468,6 +468,12 @@ xprt_rdma_close(struct rpc_xprt *xprt)
|
|
xprt->reestablish_timeout = 0;
|
|
xprt_disconnect_done(xprt);
|
|
rpcrdma_ep_disconnect(ep, ia);
|
|
+
|
|
+ /* Prepare @xprt for the next connection by reinitializing
|
|
+ * its credit grant to one (see RFC 8166, Section 3.3.3).
|
|
+ */
|
|
+ r_xprt->rx_buf.rb_credits = 1;
|
|
+ xprt->cwnd = RPC_CWNDSHIFT;
|
|
}
|
|
|
|
/**
|
|
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
|
|
index 7e7e7e7c250a..d9e7728027c6 100644
|
|
--- a/security/integrity/ima/ima_crypto.c
|
|
+++ b/security/integrity/ima/ima_crypto.c
|
|
@@ -210,7 +210,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
|
|
{
|
|
loff_t i_size, offset;
|
|
char *rbuf[2] = { NULL, };
|
|
- int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
|
|
+ int rc, rbuf_len, active = 0, ahash_rc = 0;
|
|
struct ahash_request *req;
|
|
struct scatterlist sg[1];
|
|
struct crypto_wait wait;
|
|
@@ -257,11 +257,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
|
|
&rbuf_size[1], 0);
|
|
}
|
|
|
|
- if (!(file->f_mode & FMODE_READ)) {
|
|
- file->f_mode |= FMODE_READ;
|
|
- read = 1;
|
|
- }
|
|
-
|
|
for (offset = 0; offset < i_size; offset += rbuf_len) {
|
|
if (!rbuf[1] && offset) {
|
|
/* Not using two buffers, and it is not the first
|
|
@@ -300,8 +295,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
|
|
/* wait for the last update request to complete */
|
|
rc = ahash_wait(ahash_rc, &wait);
|
|
out3:
|
|
- if (read)
|
|
- file->f_mode &= ~FMODE_READ;
|
|
ima_free_pages(rbuf[0], rbuf_size[0]);
|
|
ima_free_pages(rbuf[1], rbuf_size[1]);
|
|
out2:
|
|
@@ -336,7 +329,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
|
|
{
|
|
loff_t i_size, offset = 0;
|
|
char *rbuf;
|
|
- int rc, read = 0;
|
|
+ int rc;
|
|
SHASH_DESC_ON_STACK(shash, tfm);
|
|
|
|
shash->tfm = tfm;
|
|
@@ -357,11 +350,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
|
|
if (!rbuf)
|
|
return -ENOMEM;
|
|
|
|
- if (!(file->f_mode & FMODE_READ)) {
|
|
- file->f_mode |= FMODE_READ;
|
|
- read = 1;
|
|
- }
|
|
-
|
|
while (offset < i_size) {
|
|
int rbuf_len;
|
|
|
|
@@ -378,8 +366,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
|
|
if (rc)
|
|
break;
|
|
}
|
|
- if (read)
|
|
- file->f_mode &= ~FMODE_READ;
|
|
kfree(rbuf);
|
|
out:
|
|
if (!rc)
|
|
@@ -420,6 +406,8 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
|
|
{
|
|
loff_t i_size;
|
|
int rc;
|
|
+ struct file *f = file;
|
|
+ bool new_file_instance = false, modified_flags = false;
|
|
|
|
/*
|
|
* For consistency, fail file's opened with the O_DIRECT flag on
|
|
@@ -431,15 +419,41 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
|
|
return -EINVAL;
|
|
}
|
|
|
|
- i_size = i_size_read(file_inode(file));
|
|
+ /* Open a new file instance in O_RDONLY if we cannot read */
|
|
+ if (!(file->f_mode & FMODE_READ)) {
|
|
+ int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
|
|
+ O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
|
|
+ flags |= O_RDONLY;
|
|
+ f = dentry_open(&file->f_path, flags, file->f_cred);
|
|
+ if (IS_ERR(f)) {
|
|
+ /*
|
|
+ * Cannot open the file again, lets modify f_flags
|
|
+ * of original and continue
|
|
+ */
|
|
+ pr_info_ratelimited("Unable to reopen file for reading.\n");
|
|
+ f = file;
|
|
+ f->f_flags |= FMODE_READ;
|
|
+ modified_flags = true;
|
|
+ } else {
|
|
+ new_file_instance = true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ i_size = i_size_read(file_inode(f));
|
|
|
|
if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
|
|
- rc = ima_calc_file_ahash(file, hash);
|
|
+ rc = ima_calc_file_ahash(f, hash);
|
|
if (!rc)
|
|
- return 0;
|
|
+ goto out;
|
|
}
|
|
|
|
- return ima_calc_file_shash(file, hash);
|
|
+ rc = ima_calc_file_shash(f, hash);
|
|
+out:
|
|
+ if (new_file_instance)
|
|
+ fput(f);
|
|
+ else if (modified_flags)
|
|
+ f->f_flags &= ~FMODE_READ;
|
|
+ return rc;
|
|
}
|
|
|
|
/*
|
|
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
|
|
index ae9d5c766a3c..cfb8cc3b975e 100644
|
|
--- a/security/integrity/ima/ima_fs.c
|
|
+++ b/security/integrity/ima/ima_fs.c
|
|
@@ -42,14 +42,14 @@ static int __init default_canonical_fmt_setup(char *str)
|
|
__setup("ima_canonical_fmt", default_canonical_fmt_setup);
|
|
|
|
static int valid_policy = 1;
|
|
-#define TMPBUFLEN 12
|
|
+
|
|
static ssize_t ima_show_htable_value(char __user *buf, size_t count,
|
|
loff_t *ppos, atomic_long_t *val)
|
|
{
|
|
- char tmpbuf[TMPBUFLEN];
|
|
+ char tmpbuf[32]; /* greater than largest 'long' string value */
|
|
ssize_t len;
|
|
|
|
- len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
|
|
+ len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
|
|
return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
|
|
}
|
|
|
|
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
|
|
index ad9a9b8e9979..18b98b5e1e3c 100644
|
|
--- a/security/selinux/hooks.c
|
|
+++ b/security/selinux/hooks.c
|
|
@@ -1508,6 +1508,11 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
|
|
}
|
|
rc = security_genfs_sid(&selinux_state, sb->s_type->name,
|
|
path, tclass, sid);
|
|
+ if (rc == -ENOENT) {
|
|
+ /* No match in policy, mark as unlabeled. */
|
|
+ *sid = SECINITSID_UNLABELED;
|
|
+ rc = 0;
|
|
+ }
|
|
}
|
|
free_page((unsigned long)buffer);
|
|
return rc;
|
|
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
|
|
index 340fc30ad85d..70d3066e69fe 100644
|
|
--- a/security/smack/smack_lsm.c
|
|
+++ b/security/smack/smack_lsm.c
|
|
@@ -421,6 +421,7 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
|
|
struct smk_audit_info ad, *saip = NULL;
|
|
struct task_smack *tsp;
|
|
struct smack_known *tracer_known;
|
|
+ const struct cred *tracercred;
|
|
|
|
if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
|
|
smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
|
|
@@ -429,7 +430,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
|
|
}
|
|
|
|
rcu_read_lock();
|
|
- tsp = __task_cred(tracer)->security;
|
|
+ tracercred = __task_cred(tracer);
|
|
+ tsp = tracercred->security;
|
|
tracer_known = smk_of_task(tsp);
|
|
|
|
if ((mode & PTRACE_MODE_ATTACH) &&
|
|
@@ -439,7 +441,7 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
|
|
rc = 0;
|
|
else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
|
|
rc = -EACCES;
|
|
- else if (capable(CAP_SYS_PTRACE))
|
|
+ else if (smack_privileged_cred(CAP_SYS_PTRACE, tracercred))
|
|
rc = 0;
|
|
else
|
|
rc = -EACCES;
|
|
@@ -1841,6 +1843,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
|
|
{
|
|
struct smack_known *skp;
|
|
struct smack_known *tkp = smk_of_task(tsk->cred->security);
|
|
+ const struct cred *tcred;
|
|
struct file *file;
|
|
int rc;
|
|
struct smk_audit_info ad;
|
|
@@ -1854,8 +1857,12 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
|
|
skp = file->f_security;
|
|
rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
|
|
rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
|
|
- if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
|
|
+
|
|
+ rcu_read_lock();
|
|
+ tcred = __task_cred(tsk);
|
|
+ if (rc != 0 && smack_privileged_cred(CAP_MAC_OVERRIDE, tcred))
|
|
rc = 0;
|
|
+ rcu_read_unlock();
|
|
|
|
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
|
|
smk_ad_setfield_u_tsk(&ad, tsk);
|
|
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
|
|
index 04402c14cb23..9847b669cf3c 100644
|
|
--- a/sound/pci/ca0106/ca0106.h
|
|
+++ b/sound/pci/ca0106/ca0106.h
|
|
@@ -582,7 +582,7 @@
|
|
#define SPI_PL_BIT_R_R (2<<7) /* right channel = right */
|
|
#define SPI_PL_BIT_R_C (3<<7) /* right channel = (L+R)/2 */
|
|
#define SPI_IZD_REG 2
|
|
-#define SPI_IZD_BIT (1<<4) /* infinite zero detect */
|
|
+#define SPI_IZD_BIT (0<<4) /* infinite zero detect */
|
|
|
|
#define SPI_FMT_REG 3
|
|
#define SPI_FMT_BIT_RJ (0<<0) /* right justified mode */
|
|
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
|
|
index a68e75b00ea3..53c3cd28bc99 100644
|
|
--- a/sound/pci/hda/hda_controller.h
|
|
+++ b/sound/pci/hda/hda_controller.h
|
|
@@ -160,6 +160,7 @@ struct azx {
|
|
unsigned int msi:1;
|
|
unsigned int probing:1; /* codec probing phase */
|
|
unsigned int snoop:1;
|
|
+ unsigned int uc_buffer:1; /* non-cached pages for stream buffers */
|
|
unsigned int align_buffer_size:1;
|
|
unsigned int region_requested:1;
|
|
unsigned int disabled:1; /* disabled by vga_switcheroo */
|
|
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
|
index aa4c672dbaf7..625cb6c7b7d6 100644
|
|
--- a/sound/pci/hda/hda_intel.c
|
|
+++ b/sound/pci/hda/hda_intel.c
|
|
@@ -412,7 +412,7 @@ static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool
|
|
#ifdef CONFIG_SND_DMA_SGBUF
|
|
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
|
|
struct snd_sg_buf *sgbuf = dmab->private_data;
|
|
- if (chip->driver_type == AZX_DRIVER_CMEDIA)
|
|
+ if (!chip->uc_buffer)
|
|
return; /* deal with only CORB/RIRB buffers */
|
|
if (on)
|
|
set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
|
|
@@ -1678,6 +1678,7 @@ static void azx_check_snoop_available(struct azx *chip)
|
|
dev_info(chip->card->dev, "Force to %s mode by module option\n",
|
|
snoop ? "snoop" : "non-snoop");
|
|
chip->snoop = snoop;
|
|
+ chip->uc_buffer = !snoop;
|
|
return;
|
|
}
|
|
|
|
@@ -1698,8 +1699,12 @@ static void azx_check_snoop_available(struct azx *chip)
|
|
snoop = false;
|
|
|
|
chip->snoop = snoop;
|
|
- if (!snoop)
|
|
+ if (!snoop) {
|
|
dev_info(chip->card->dev, "Force to non-snoop mode\n");
|
|
+ /* C-Media requires non-cached pages only for CORB/RIRB */
|
|
+ if (chip->driver_type != AZX_DRIVER_CMEDIA)
|
|
+ chip->uc_buffer = true;
|
|
+ }
|
|
}
|
|
|
|
static void azx_probe_work(struct work_struct *work)
|
|
@@ -2138,7 +2143,7 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
|
|
#ifdef CONFIG_X86
|
|
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
|
|
struct azx *chip = apcm->chip;
|
|
- if (!azx_snoop(chip) && chip->driver_type != AZX_DRIVER_CMEDIA)
|
|
+ if (chip->uc_buffer)
|
|
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
|
|
#endif
|
|
}
|
|
@@ -2257,8 +2262,12 @@ static struct snd_pci_quirk power_save_blacklist[] = {
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1581607 */
|
|
SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", 0),
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
|
+ SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0),
|
|
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
|
/* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */
|
|
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P55A-UD3 / Z87-D3HP", 0),
|
|
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
|
+ SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0),
|
|
/* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */
|
|
SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0),
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */
|
|
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
|
|
index cfd4e4f97f8f..3c5f2a603754 100644
|
|
--- a/sound/pci/hda/patch_conexant.c
|
|
+++ b/sound/pci/hda/patch_conexant.c
|
|
@@ -943,6 +943,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
|
|
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
|
|
SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
|
|
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
|
|
+ SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC),
|
|
SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
|
|
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
|
|
SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
|
|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
|
index 3ac7ba9b342d..1070749c3cf4 100644
|
|
--- a/sound/pci/hda/patch_realtek.c
|
|
+++ b/sound/pci/hda/patch_realtek.c
|
|
@@ -6841,6 +6841,12 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
|
{0x1a, 0x02a11040},
|
|
{0x1b, 0x01014020},
|
|
{0x21, 0x0221101f}),
|
|
+ SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
|
|
+ {0x14, 0x90170110},
|
|
+ {0x19, 0x02a11030},
|
|
+ {0x1a, 0x02a11040},
|
|
+ {0x1b, 0x01011020},
|
|
+ {0x21, 0x0221101f}),
|
|
SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
|
|
{0x14, 0x90170110},
|
|
{0x19, 0x02a11020},
|
|
@@ -7738,6 +7744,8 @@ enum {
|
|
ALC662_FIXUP_ASUS_Nx50,
|
|
ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
|
|
ALC668_FIXUP_ASUS_Nx51,
|
|
+ ALC668_FIXUP_MIC_COEF,
|
|
+ ALC668_FIXUP_ASUS_G751,
|
|
ALC891_FIXUP_HEADSET_MODE,
|
|
ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
|
|
ALC662_FIXUP_ACER_VERITON,
|
|
@@ -8007,6 +8015,23 @@ static const struct hda_fixup alc662_fixups[] = {
|
|
.chained = true,
|
|
.chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
|
|
},
|
|
+ [ALC668_FIXUP_MIC_COEF] = {
|
|
+ .type = HDA_FIXUP_VERBS,
|
|
+ .v.verbs = (const struct hda_verb[]) {
|
|
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
|
|
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
|
|
+ {}
|
|
+ },
|
|
+ },
|
|
+ [ALC668_FIXUP_ASUS_G751] = {
|
|
+ .type = HDA_FIXUP_PINS,
|
|
+ .v.pins = (const struct hda_pintbl[]) {
|
|
+ { 0x16, 0x0421101f }, /* HP */
|
|
+ {}
|
|
+ },
|
|
+ .chained = true,
|
|
+ .chain_id = ALC668_FIXUP_MIC_COEF
|
|
+ },
|
|
[ALC891_FIXUP_HEADSET_MODE] = {
|
|
.type = HDA_FIXUP_FUNC,
|
|
.v.func = alc_fixup_headset_mode,
|
|
@@ -8080,6 +8105,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
|
SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
|
|
SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
|
|
SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
|
|
+ SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
|
|
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
|
|
SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
|
|
SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
|
|
diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c
|
|
index 97f49b751e6e..568575b72f2f 100644
|
|
--- a/sound/pci/hda/thinkpad_helper.c
|
|
+++ b/sound/pci/hda/thinkpad_helper.c
|
|
@@ -58,8 +58,8 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
|
removefunc = false;
|
|
}
|
|
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 &&
|
|
- snd_hda_gen_add_micmute_led(codec,
|
|
- update_tpacpi_micmute) > 0)
|
|
+ !snd_hda_gen_add_micmute_led(codec,
|
|
+ update_tpacpi_micmute))
|
|
removefunc = false;
|
|
}
|
|
|
|
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
|
|
index 77b265bd0505..3135e9eafd18 100644
|
|
--- a/sound/soc/amd/acp-pcm-dma.c
|
|
+++ b/sound/soc/amd/acp-pcm-dma.c
|
|
@@ -1036,16 +1036,22 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
|
|
|
|
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
|
period_bytes = frames_to_bytes(runtime, runtime->period_size);
|
|
- dscr = acp_reg_read(rtd->acp_mmio, rtd->dma_curr_dscr);
|
|
- if (dscr == rtd->dma_dscr_idx_1)
|
|
- pos = period_bytes;
|
|
- else
|
|
- pos = 0;
|
|
bytescount = acp_get_byte_count(rtd);
|
|
- if (bytescount > rtd->bytescount)
|
|
+ if (bytescount >= rtd->bytescount)
|
|
bytescount -= rtd->bytescount;
|
|
- delay = do_div(bytescount, period_bytes);
|
|
- runtime->delay = bytes_to_frames(runtime, delay);
|
|
+ if (bytescount < period_bytes) {
|
|
+ pos = 0;
|
|
+ } else {
|
|
+ dscr = acp_reg_read(rtd->acp_mmio, rtd->dma_curr_dscr);
|
|
+ if (dscr == rtd->dma_dscr_idx_1)
|
|
+ pos = period_bytes;
|
|
+ else
|
|
+ pos = 0;
|
|
+ }
|
|
+ if (bytescount > 0) {
|
|
+ delay = do_div(bytescount, period_bytes);
|
|
+ runtime->delay = bytes_to_frames(runtime, delay);
|
|
+ }
|
|
} else {
|
|
buffersize = frames_to_bytes(runtime, runtime->buffer_size);
|
|
bytescount = acp_get_byte_count(rtd);
|
|
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
|
|
index d5035f2f2b2b..ce508b4cc85c 100644
|
|
--- a/sound/soc/codecs/sta32x.c
|
|
+++ b/sound/soc/codecs/sta32x.c
|
|
@@ -879,6 +879,9 @@ static int sta32x_probe(struct snd_soc_component *component)
|
|
struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
|
|
struct sta32x_platform_data *pdata = sta32x->pdata;
|
|
int i, ret = 0, thermal = 0;
|
|
+
|
|
+ sta32x->component = component;
|
|
+
|
|
ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
|
|
sta32x->supplies);
|
|
if (ret != 0) {
|
|
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
|
|
index 2620d77729c5..f99c600f86e4 100644
|
|
--- a/sound/soc/intel/skylake/skl-topology.c
|
|
+++ b/sound/soc/intel/skylake/skl-topology.c
|
|
@@ -2461,6 +2461,7 @@ static int skl_tplg_get_token(struct device *dev,
|
|
|
|
case SKL_TKN_U8_CORE_ID:
|
|
mconfig->core_id = tkn_elem->value;
|
|
+ break;
|
|
|
|
case SKL_TKN_U8_MOD_TYPE:
|
|
mconfig->m_type = tkn_elem->value;
|
|
diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
|
|
index 3013ac8f83d0..cab7b0aea6ea 100755
|
|
--- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
|
|
+++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
|
|
@@ -48,7 +48,7 @@ trace_libc_inet_pton_backtrace() {
|
|
*)
|
|
eventattr='max-stack=3'
|
|
echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected
|
|
- echo ".*\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected
|
|
+ echo ".*(\+0x[[:xdigit:]]+|\[unknown\])[[:space:]]\(.*/bin/ping.*\)$" >> $expected
|
|
;;
|
|
esac
|
|
|
|
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
|
|
index 3d1cf5bf7f18..9005fbe0780e 100644
|
|
--- a/tools/perf/util/strbuf.c
|
|
+++ b/tools/perf/util/strbuf.c
|
|
@@ -98,19 +98,25 @@ static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
|
|
|
|
va_copy(ap_saved, ap);
|
|
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
|
|
- if (len < 0)
|
|
+ if (len < 0) {
|
|
+ va_end(ap_saved);
|
|
return len;
|
|
+ }
|
|
if (len > strbuf_avail(sb)) {
|
|
ret = strbuf_grow(sb, len);
|
|
- if (ret)
|
|
+ if (ret) {
|
|
+ va_end(ap_saved);
|
|
return ret;
|
|
+ }
|
|
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
|
|
va_end(ap_saved);
|
|
if (len > strbuf_avail(sb)) {
|
|
pr_debug("this should not happen, your vsnprintf is broken");
|
|
+ va_end(ap_saved);
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
+ va_end(ap_saved);
|
|
return strbuf_setlen(sb, sb->len + len);
|
|
}
|
|
|
|
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
|
|
index 7b0ca7cbb7de..8ad8e755127b 100644
|
|
--- a/tools/perf/util/trace-event-info.c
|
|
+++ b/tools/perf/util/trace-event-info.c
|
|
@@ -531,12 +531,14 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
|
|
"/tmp/perf-XXXXXX");
|
|
if (!mkstemp(tdata->temp_file)) {
|
|
pr_debug("Can't make temp file");
|
|
+ free(tdata);
|
|
return NULL;
|
|
}
|
|
|
|
temp_fd = open(tdata->temp_file, O_RDWR);
|
|
if (temp_fd < 0) {
|
|
pr_debug("Can't read '%s'", tdata->temp_file);
|
|
+ free(tdata);
|
|
return NULL;
|
|
}
|
|
|
|
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
|
|
index e76214f8d596..b15a9bf1837b 100644
|
|
--- a/tools/perf/util/trace-event-parse.c
|
|
+++ b/tools/perf/util/trace-event-parse.c
|
|
@@ -158,6 +158,7 @@ void parse_ftrace_printk(struct tep_handle *pevent,
|
|
printk = strdup(fmt+1);
|
|
line = strtok_r(NULL, "\n", &next);
|
|
tep_register_print_string(pevent, printk, addr);
|
|
+ free(printk);
|
|
}
|
|
}
|
|
|
|
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
|
|
index 3dfc1db6b25b..5eb1b2469bba 100644
|
|
--- a/tools/perf/util/trace-event-read.c
|
|
+++ b/tools/perf/util/trace-event-read.c
|
|
@@ -349,9 +349,12 @@ static int read_event_files(struct tep_handle *pevent)
|
|
for (x=0; x < count; x++) {
|
|
size = read8(pevent);
|
|
ret = read_event_file(pevent, sys, size);
|
|
- if (ret)
|
|
+ if (ret) {
|
|
+ free(sys);
|
|
return ret;
|
|
+ }
|
|
}
|
|
+ free(sys);
|
|
}
|
|
return 0;
|
|
}
|
|
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
|
|
index df43cd45d810..ccd08dd00996 100644
|
|
--- a/tools/power/cpupower/utils/cpufreq-info.c
|
|
+++ b/tools/power/cpupower/utils/cpufreq-info.c
|
|
@@ -200,6 +200,8 @@ static int get_boost_mode(unsigned int cpu)
|
|
printf(_(" Boost States: %d\n"), b_states);
|
|
printf(_(" Total States: %d\n"), pstate_no);
|
|
for (i = 0; i < pstate_no; i++) {
|
|
+ if (!pstates[i])
|
|
+ continue;
|
|
if (i < b_states)
|
|
printf(_(" Pstate-Pb%d: %luMHz (boost state)"
|
|
"\n"), i, pstates[i]);
|
|
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c
|
|
index bb41cdd0df6b..9607ada5b29a 100644
|
|
--- a/tools/power/cpupower/utils/helpers/amd.c
|
|
+++ b/tools/power/cpupower/utils/helpers/amd.c
|
|
@@ -33,7 +33,7 @@ union msr_pstate {
|
|
unsigned vid:8;
|
|
unsigned iddval:8;
|
|
unsigned idddiv:2;
|
|
- unsigned res1:30;
|
|
+ unsigned res1:31;
|
|
unsigned en:1;
|
|
} fam17h_bits;
|
|
unsigned long long val;
|
|
@@ -119,6 +119,11 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family,
|
|
}
|
|
if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
|
|
return -1;
|
|
+ if ((cpu_family == 0x17) && (!pstate.fam17h_bits.en))
|
|
+ continue;
|
|
+ else if (!pstate.bits.en)
|
|
+ continue;
|
|
+
|
|
pstates[i] = get_cof(cpu_family, pstate);
|
|
}
|
|
*no = i;
|
|
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc
|
|
index cef11377dcbd..c604438df13b 100644
|
|
--- a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc
|
|
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc
|
|
@@ -35,18 +35,18 @@ fi
|
|
|
|
reset_trigger
|
|
|
|
-echo "Test create synthetic event with an error"
|
|
-echo 'wakeup_latency u64 lat pid_t pid char' > synthetic_events > /dev/null
|
|
+echo "Test remove synthetic event"
|
|
+echo '!wakeup_latency u64 lat pid_t pid char comm[16]' >> synthetic_events
|
|
if [ -d events/synthetic/wakeup_latency ]; then
|
|
- fail "Created wakeup_latency synthetic event with an invalid format"
|
|
+ fail "Failed to delete wakeup_latency synthetic event"
|
|
fi
|
|
|
|
reset_trigger
|
|
|
|
-echo "Test remove synthetic event"
|
|
-echo '!wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events
|
|
+echo "Test create synthetic event with an error"
|
|
+echo 'wakeup_latency u64 lat pid_t pid char' > synthetic_events > /dev/null
|
|
if [ -d events/synthetic/wakeup_latency ]; then
|
|
- fail "Failed to delete wakeup_latency synthetic event"
|
|
+ fail "Created wakeup_latency synthetic event with an invalid format"
|
|
fi
|
|
|
|
do_reset
|
|
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
|
|
index 327fa943c7f3..dbdffa2e2c82 100644
|
|
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
|
|
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
|
|
@@ -67,8 +67,8 @@ trans:
|
|
"3: ;"
|
|
: [res] "=r" (result), [texasr] "=r" (texasr)
|
|
: [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2), [gpr_4]"i"(GPR_4),
|
|
- [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "r" (&a),
|
|
- [flt_2] "r" (&b), [flt_4] "r" (&d)
|
|
+ [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),
|
|
+ [flt_4] "b" (&d)
|
|
: "memory", "r5", "r6", "r7",
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
|
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
|
|
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
|
|
index c92053bc3f96..8fb31a7cc22c 100644
|
|
--- a/virt/kvm/arm/arm.c
|
|
+++ b/virt/kvm/arm/arm.c
|
|
@@ -1295,8 +1295,6 @@ static void cpu_init_hyp_mode(void *dummy)
|
|
|
|
__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
|
|
__cpu_init_stage2();
|
|
-
|
|
- kvm_arm_init_debug();
|
|
}
|
|
|
|
static void cpu_hyp_reset(void)
|
|
@@ -1320,6 +1318,8 @@ static void cpu_hyp_reinit(void)
|
|
cpu_init_hyp_mode(NULL);
|
|
}
|
|
|
|
+ kvm_arm_init_debug();
|
|
+
|
|
if (vgic_present)
|
|
kvm_vgic_init_cpu_hardware();
|
|
}
|
|
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
|
|
index ed162a6c57c5..2f405b0be25c 100644
|
|
--- a/virt/kvm/arm/mmu.c
|
|
+++ b/virt/kvm/arm/mmu.c
|
|
@@ -1230,8 +1230,14 @@ static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
|
|
{
|
|
kvm_pfn_t pfn = *pfnp;
|
|
gfn_t gfn = *ipap >> PAGE_SHIFT;
|
|
+ struct page *page = pfn_to_page(pfn);
|
|
|
|
- if (PageTransCompoundMap(pfn_to_page(pfn))) {
|
|
+ /*
|
|
+ * PageTransCompoungMap() returns true for THP and
|
|
+ * hugetlbfs. Make sure the adjustment is done only for THP
|
|
+ * pages.
|
|
+ */
|
|
+ if (!PageHuge(page) && PageTransCompoundMap(page)) {
|
|
unsigned long mask;
|
|
/*
|
|
* The address we faulted on is backed by a transparent huge
|