From 04142312762064baaf4765e13b479d9e03cfad47 Mon Sep 17 00:00:00 2001 From: "Horst G. Burkhardt" Date: Sat, 11 Jun 2022 20:53:24 -0500 Subject: system/easy-kernel: Update to 5.15.44-mc2 --- system/easy-kernel/0100-linux-5.15.28.patch | 174425 ----------- system/easy-kernel/0100-linux.5.15.44.patch | 270104 ++++++++++++++++++ system/easy-kernel/0130-lrng.patch | 28362 -- system/easy-kernel/0250-projectc-5.15-r1.patch | 9746 - .../0251-projectc-5.15-r1-zv-fix-5.15.28.patch | 125 - system/easy-kernel/0500-print-fw-info.patch | 6 +- system/easy-kernel/1000-version.patch | 4 +- system/easy-kernel/APKBUILD | 20 +- 8 files changed, 270115 insertions(+), 212677 deletions(-) delete mode 100644 system/easy-kernel/0100-linux-5.15.28.patch create mode 100644 system/easy-kernel/0100-linux.5.15.44.patch delete mode 100644 system/easy-kernel/0130-lrng.patch delete mode 100644 system/easy-kernel/0250-projectc-5.15-r1.patch delete mode 100644 system/easy-kernel/0251-projectc-5.15-r1-zv-fix-5.15.28.patch diff --git a/system/easy-kernel/0100-linux-5.15.28.patch b/system/easy-kernel/0100-linux-5.15.28.patch deleted file mode 100644 index 5e307cfc9..000000000 --- a/system/easy-kernel/0100-linux-5.15.28.patch +++ /dev/null @@ -1,174425 +0,0 @@ -diff --git a/Documentation/accounting/psi.rst b/Documentation/accounting/psi.rst -index f2b3439edcc2c..860fe651d6453 100644 ---- a/Documentation/accounting/psi.rst -+++ b/Documentation/accounting/psi.rst -@@ -92,7 +92,8 @@ Triggers can be set on more than one psi metric and more than one trigger - for the same psi metric can be specified. However for each trigger a separate - file descriptor is required to be able to poll it separately from others, - therefore for each trigger a separate open() syscall should be made even --when opening the same psi interface file. -+when opening the same psi interface file. Write operations to a file descriptor -+with an already existing psi trigger will fail with EBUSY. - - Monitors activate only when system enters stall state for the monitored - psi metric and deactivates upon exit from the stall state. While system is -diff --git a/Documentation/admin-guide/cifs/usage.rst b/Documentation/admin-guide/cifs/usage.rst -index f170d88202588..3766bf8a1c20e 100644 ---- a/Documentation/admin-guide/cifs/usage.rst -+++ b/Documentation/admin-guide/cifs/usage.rst -@@ -734,10 +734,9 @@ SecurityFlags Flags which control security negotiation and - using weaker password hashes is 0x37037 (lanman, - plaintext, ntlm, ntlmv2, signing allowed). Some - SecurityFlags require the corresponding menuconfig -- options to be enabled (lanman and plaintext require -- CONFIG_CIFS_WEAK_PW_HASH for example). Enabling -- plaintext authentication currently requires also -- enabling lanman authentication in the security flags -+ options to be enabled. Enabling plaintext -+ authentication currently requires also enabling -+ lanman authentication in the security flags - because the cifs module only supports sending - laintext passwords using the older lanman dialect - form of the session setup SMB. (e.g. for authentication -diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt -index 922c23bb4372a..c07dc0ee860e7 100644 ---- a/Documentation/admin-guide/devices.txt -+++ b/Documentation/admin-guide/devices.txt -@@ -2339,13 +2339,7 @@ - disks (see major number 3) except that the limit on - partitions is 31. - -- 162 char Raw block device interface -- 0 = /dev/rawctl Raw I/O control device -- 1 = /dev/raw/raw1 First raw I/O device -- 2 = /dev/raw/raw2 Second raw I/O device -- ... -- max minor number of raw device is set by kernel config -- MAX_RAW_DEVS or raw module parameter 'max_raw_devs' -+ 162 char Used for (now removed) raw block device interface - - 163 char - -diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst -index e05e581af5cfe..6bd97cd50d625 100644 ---- a/Documentation/admin-guide/hw-vuln/spectre.rst -+++ b/Documentation/admin-guide/hw-vuln/spectre.rst -@@ -60,8 +60,8 @@ privileged data touched during the speculative execution. - Spectre variant 1 attacks take advantage of speculative execution of - conditional branches, while Spectre variant 2 attacks use speculative - execution of indirect branches to leak privileged memory. --See :ref:`[1] ` :ref:`[5] ` :ref:`[7] ` --:ref:`[10] ` :ref:`[11] `. -+See :ref:`[1] ` :ref:`[5] ` :ref:`[6] ` -+:ref:`[7] ` :ref:`[10] ` :ref:`[11] `. - - Spectre variant 1 (Bounds Check Bypass) - --------------------------------------- -@@ -131,6 +131,19 @@ steer its indirect branch speculations to gadget code, and measure the - speculative execution's side effects left in level 1 cache to infer the - victim's data. - -+Yet another variant 2 attack vector is for the attacker to poison the -+Branch History Buffer (BHB) to speculatively steer an indirect branch -+to a specific Branch Target Buffer (BTB) entry, even if the entry isn't -+associated with the source address of the indirect branch. Specifically, -+the BHB might be shared across privilege levels even in the presence of -+Enhanced IBRS. -+ -+Currently the only known real-world BHB attack vector is via -+unprivileged eBPF. Therefore, it's highly recommended to not enable -+unprivileged eBPF, especially when eIBRS is used (without retpolines). -+For a full mitigation against BHB attacks, it's recommended to use -+retpolines (or eIBRS combined with retpolines). -+ - Attack scenarios - ---------------- - -@@ -364,13 +377,15 @@ The possible values in this file are: - - - Kernel status: - -- ==================================== ================================= -- 'Not affected' The processor is not vulnerable -- 'Vulnerable' Vulnerable, no mitigation -- 'Mitigation: Full generic retpoline' Software-focused mitigation -- 'Mitigation: Full AMD retpoline' AMD-specific software mitigation -- 'Mitigation: Enhanced IBRS' Hardware-focused mitigation -- ==================================== ================================= -+ ======================================== ================================= -+ 'Not affected' The processor is not vulnerable -+ 'Mitigation: None' Vulnerable, no mitigation -+ 'Mitigation: Retpolines' Use Retpoline thunks -+ 'Mitigation: LFENCE' Use LFENCE instructions -+ 'Mitigation: Enhanced IBRS' Hardware-focused mitigation -+ 'Mitigation: Enhanced IBRS + Retpolines' Hardware-focused + Retpolines -+ 'Mitigation: Enhanced IBRS + LFENCE' Hardware-focused + LFENCE -+ ======================================== ================================= - - - Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is - used to protect against Spectre variant 2 attacks when calling firmware (x86 only). -@@ -468,7 +483,7 @@ Spectre variant 2 - before invoking any firmware code to prevent Spectre variant 2 exploits - using the firmware. - -- Using kernel address space randomization (CONFIG_RANDOMIZE_SLAB=y -+ Using kernel address space randomization (CONFIG_RANDOMIZE_BASE=y - and CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makes - attacks on the kernel generally more difficult. - -@@ -584,12 +599,13 @@ kernel command line. - - Specific mitigations can also be selected manually: - -- retpoline -- replace indirect branches -- retpoline,generic -- google's original retpoline -- retpoline,amd -- AMD-specific minimal thunk -+ retpoline auto pick between generic,lfence -+ retpoline,generic Retpolines -+ retpoline,lfence LFENCE; indirect branch -+ retpoline,amd alias for retpoline,lfence -+ eibrs enhanced IBRS -+ eibrs,retpoline enhanced IBRS + Retpolines -+ eibrs,lfence enhanced IBRS + LFENCE - - Not specifying this option is equivalent to - spectre_v2=auto. -@@ -730,7 +746,7 @@ AMD white papers: - - .. _spec_ref6: - --[6] `Software techniques for managing speculation on AMD processors `_. -+[6] `Software techniques for managing speculation on AMD processors `_. - - ARM white papers: - -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 43dc35fe5bc03..ed55ea20352bc 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -1690,6 +1690,8 @@ - architectures force reset to be always executed - i8042.unlock [HW] Unlock (ignore) the keylock - i8042.kbdreset [HW] Reset device connected to KBD port -+ i8042.probe_defer -+ [HW] Allow deferred probing upon i8042 probe errors - - i810= [HW,DRM] - -@@ -2403,8 +2405,12 @@ - Default is 1 (enabled) - - kvm-intel.emulate_invalid_guest_state= -- [KVM,Intel] Enable emulation of invalid guest states -- Default is 0 (disabled) -+ [KVM,Intel] Disable emulation of invalid guest state. -+ Ignored if kvm-intel.enable_unrestricted_guest=1, as -+ guest state is never invalid for unrestricted guests. -+ This param doesn't apply to nested guests (L2), as KVM -+ never emulates invalid L2 guest state. -+ Default is 1 (enabled) - - kvm-intel.flexpriority= - [KVM,Intel] Disable FlexPriority feature (TPR shadow). -@@ -5261,8 +5267,12 @@ - Specific mitigations can also be selected manually: - - retpoline - replace indirect branches -- retpoline,generic - google's original retpoline -- retpoline,amd - AMD-specific minimal thunk -+ retpoline,generic - Retpolines -+ retpoline,lfence - LFENCE; indirect branch -+ retpoline,amd - alias for retpoline,lfence -+ eibrs - enhanced IBRS -+ eibrs,retpoline - enhanced IBRS + Retpolines -+ eibrs,lfence - enhanced IBRS + LFENCE - - Not specifying this option is equivalent to - spectre_v2=auto. -@@ -6349,6 +6359,13 @@ - improve timer resolution at the expense of processing - more timer interrupts. - -+ xen.balloon_boot_timeout= [XEN] -+ The time (in seconds) to wait before giving up to boot -+ in case initial ballooning fails to free enough memory. -+ Applies only when running as HVM or PVH guest and -+ started with less memory configured than allowed at -+ max. Default is 180. -+ - xen.event_eoi_delay= [XEN] - How long to delay EOI handling in case of event - storms (jiffies). Default is 10. -diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst -index fb578fbbb76ca..49857ce1cd03e 100644 ---- a/Documentation/admin-guide/mm/pagemap.rst -+++ b/Documentation/admin-guide/mm/pagemap.rst -@@ -23,7 +23,7 @@ There are four components to pagemap: - * Bit 56 page exclusively mapped (since 4.2) - * Bit 57 pte is uffd-wp write-protected (since 5.13) (see - :ref:`Documentation/admin-guide/mm/userfaultfd.rst `) -- * Bits 57-60 zero -+ * Bits 58-60 zero - * Bit 61 page is file-page or shared-anon (since 3.5) - * Bit 62 page swapped - * Bit 63 page present -diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst -index 426162009ce99..0e486f41185ef 100644 ---- a/Documentation/admin-guide/sysctl/kernel.rst -+++ b/Documentation/admin-guide/sysctl/kernel.rst -@@ -1099,7 +1099,7 @@ task_delayacct - =============== - - Enables/disables task delay accounting (see --:doc:`accounting/delay-accounting.rst`). Enabling this feature incurs -+Documentation/accounting/delay-accounting.rst. Enabling this feature incurs - a small amount of overhead in the scheduler but is useful for debugging - and performance tuning. It is required by some tools such as iotop. - -diff --git a/Documentation/arm64/cpu-feature-registers.rst b/Documentation/arm64/cpu-feature-registers.rst -index 328e0c454fbd4..749ae970c3195 100644 ---- a/Documentation/arm64/cpu-feature-registers.rst -+++ b/Documentation/arm64/cpu-feature-registers.rst -@@ -235,7 +235,15 @@ infrastructure: - | DPB | [3-0] | y | - +------------------------------+---------+---------+ - -- 6) ID_AA64MMFR2_EL1 - Memory model feature register 2 -+ 6) ID_AA64MMFR0_EL1 - Memory model feature register 0 -+ -+ +------------------------------+---------+---------+ -+ | Name | bits | visible | -+ +------------------------------+---------+---------+ -+ | ECV | [63-60] | y | -+ +------------------------------+---------+---------+ -+ -+ 7) ID_AA64MMFR2_EL1 - Memory model feature register 2 - - +------------------------------+---------+---------+ - | Name | bits | visible | -@@ -243,7 +251,7 @@ infrastructure: - | AT | [35-32] | y | - +------------------------------+---------+---------+ - -- 7) ID_AA64ZFR0_EL1 - SVE feature ID register 0 -+ 8) ID_AA64ZFR0_EL1 - SVE feature ID register 0 - - +------------------------------+---------+---------+ - | Name | bits | visible | -@@ -267,6 +275,23 @@ infrastructure: - | SVEVer | [3-0] | y | - +------------------------------+---------+---------+ - -+ 8) ID_AA64MMFR1_EL1 - Memory model feature register 1 -+ -+ +------------------------------+---------+---------+ -+ | Name | bits | visible | -+ +------------------------------+---------+---------+ -+ | AFP | [47-44] | y | -+ +------------------------------+---------+---------+ -+ -+ 9) ID_AA64ISAR2_EL1 - Instruction set attribute register 2 -+ -+ +------------------------------+---------+---------+ -+ | Name | bits | visible | -+ +------------------------------+---------+---------+ -+ | RPRES | [7-4] | y | -+ +------------------------------+---------+---------+ -+ -+ - Appendix I: Example - ------------------- - -diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst -index ec1a5a63c1d09..b72ff17d600ae 100644 ---- a/Documentation/arm64/elf_hwcaps.rst -+++ b/Documentation/arm64/elf_hwcaps.rst -@@ -247,6 +247,18 @@ HWCAP2_MTE - Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010, as described - by Documentation/arm64/memory-tagging-extension.rst. - -+HWCAP2_ECV -+ -+ Functionality implied by ID_AA64MMFR0_EL1.ECV == 0b0001. -+ -+HWCAP2_AFP -+ -+ Functionality implied by ID_AA64MFR1_EL1.AFP == 0b0001. -+ -+HWCAP2_RPRES -+ -+ Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001. -+ - 4. Unused AT_HWCAP bits - ----------------------- - -diff --git a/Documentation/dev-tools/kfence.rst b/Documentation/dev-tools/kfence.rst -index 0fbe3308bf37f..48244d32780f6 100644 ---- a/Documentation/dev-tools/kfence.rst -+++ b/Documentation/dev-tools/kfence.rst -@@ -231,10 +231,14 @@ Guarded allocations are set up based on the sample interval. After expiration - of the sample interval, the next allocation through the main allocator (SLAB or - SLUB) returns a guarded allocation from the KFENCE object pool (allocation - sizes up to PAGE_SIZE are supported). At this point, the timer is reset, and --the next allocation is set up after the expiration of the interval. To "gate" a --KFENCE allocation through the main allocator's fast-path without overhead, --KFENCE relies on static branches via the static keys infrastructure. The static --branch is toggled to redirect the allocation to KFENCE. -+the next allocation is set up after the expiration of the interval. -+ -+When using ``CONFIG_KFENCE_STATIC_KEYS=y``, KFENCE allocations are "gated" -+through the main allocator's fast-path by relying on static branches via the -+static keys infrastructure. The static branch is toggled to redirect the -+allocation to KFENCE. Depending on sample interval, target workloads, and -+system architecture, this may perform better than the simple dynamic branch. -+Careful benchmarking is recommended. - - KFENCE objects each reside on a dedicated page, at either the left or right - page boundaries selected at random. The pages to the left and right of the -diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt -index e77635c5422c6..fa8b31660cadd 100644 ---- a/Documentation/devicetree/bindings/arm/omap/omap.txt -+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt -@@ -119,6 +119,9 @@ Boards (incomplete list of examples): - - OMAP3 BeagleBoard : Low cost community board - compatible = "ti,omap3-beagle", "ti,omap3430", "ti,omap3" - -+- OMAP3 BeagleBoard A to B4 : Early BeagleBoard revisions A to B4 with a timer quirk -+ compatible = "ti,omap3-beagle-ab4", "ti,omap3-beagle", "ti,omap3430", "ti,omap3" -+ - - OMAP3 Tobi with Overo : Commercial expansion board with daughter board - compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3" - -diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml -index cf5a208f2f105..343598c9f473b 100644 ---- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml -+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml -@@ -10,6 +10,9 @@ title: Amlogic specific extensions to the Synopsys Designware HDMI Controller - maintainers: - - Neil Armstrong - -+allOf: -+ - $ref: /schemas/sound/name-prefix.yaml# -+ - description: | - The Amlogic Meson Synopsys Designware Integration is composed of - - A Synopsys DesignWare HDMI Controller IP -@@ -99,6 +102,8 @@ properties: - "#sound-dai-cells": - const: 0 - -+ sound-name-prefix: true -+ - required: - - compatible - - reg -diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -index 851cb07812173..047fd69e03770 100644 ---- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -@@ -78,6 +78,10 @@ properties: - interrupts: - maxItems: 1 - -+ amlogic,canvas: -+ description: should point to a canvas provider node -+ $ref: /schemas/types.yaml#/definitions/phandle -+ - power-domains: - maxItems: 1 - description: phandle to the associated power domain -@@ -106,6 +110,7 @@ required: - - port@1 - - "#address-cells" - - "#size-cells" -+ - amlogic,canvas - - additionalProperties: false - -@@ -118,6 +123,7 @@ examples: - interrupts = <3>; - #address-cells = <1>; - #size-cells = <0>; -+ amlogic,canvas = <&canvas>; - - /* CVBS VDAC output port */ - port@0 { -diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml -index d5c54813ce872..a8f7720d1e3e2 100644 ---- a/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml -+++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml -@@ -54,7 +54,7 @@ examples: - - ad5766@0 { - compatible = "adi,ad5766"; -- output-range-microvolts = <(-5000) 5000>; -+ output-range-microvolts = <(-5000000) 5000000>; - reg = <0>; - spi-cpol; - spi-max-frequency = <1000000>; -diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt b/Documentation/devicetree/bindings/input/hid-over-i2c.txt -index c76bafaf98d2f..34c43d3bddfd1 100644 ---- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt -+++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt -@@ -32,6 +32,8 @@ device-specific compatible properties, which should be used in addition to the - - vdd-supply: phandle of the regulator that provides the supply voltage. - - post-power-on-delay-ms: time required by the device after enabling its regulators - or powering it on, before it is ready for communication. -+- touchscreen-inverted-x: See touchscreen.txt -+- touchscreen-inverted-y: See touchscreen.txt - - Example: - -diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml -index 877183cf42787..1ef849dc74d7e 100644 ---- a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml -+++ b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml -@@ -79,6 +79,8 @@ properties: - - properties: - data-lanes: -+ description: -+ Note that 'fsl,imx7-mipi-csi2' only supports up to 2 data lines. - items: - minItems: 1 - maxItems: 4 -@@ -91,18 +93,6 @@ properties: - required: - - data-lanes - -- allOf: -- - if: -- properties: -- compatible: -- contains: -- const: fsl,imx7-mipi-csi2 -- then: -- properties: -- data-lanes: -- items: -- maxItems: 2 -- - port@1: - $ref: /schemas/graph.yaml#/properties/port - description: -diff --git a/Documentation/devicetree/bindings/net/can/tcan4x5x.txt b/Documentation/devicetree/bindings/net/can/tcan4x5x.txt -index 0968b40aef1e8..e3501bfa22e90 100644 ---- a/Documentation/devicetree/bindings/net/can/tcan4x5x.txt -+++ b/Documentation/devicetree/bindings/net/can/tcan4x5x.txt -@@ -31,7 +31,7 @@ tcan4x5x: tcan4x5x@0 { - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <10000000>; -- bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; -+ bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>; - interrupt-parent = <&gpio1>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW>; - device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; -diff --git a/Documentation/devicetree/bindings/net/ethernet-phy.yaml b/Documentation/devicetree/bindings/net/ethernet-phy.yaml -index 2766fe45bb98b..ee42328a109dc 100644 ---- a/Documentation/devicetree/bindings/net/ethernet-phy.yaml -+++ b/Documentation/devicetree/bindings/net/ethernet-phy.yaml -@@ -91,6 +91,14 @@ properties: - compensate for the board being designed with the lanes - swapped. - -+ enet-phy-lane-no-swap: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ If set, indicates that PHY will disable swap of the -+ TX/RX lanes. This property allows the PHY to work correcly after -+ e.g. wrong bootstrap configuration caused by issues in PCB -+ layout design. -+ - eee-broken-100tx: - $ref: /schemas/types.yaml#/definitions/flag - description: -diff --git a/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt b/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt -index 093edda0c8dfc..6cd83d920155f 100644 ---- a/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt -+++ b/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt -@@ -13,6 +13,14 @@ common regulator binding documented in: - - - Required properties of the main device node (the parent!): -+ - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used -+ for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. -+ -+ [1] If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional -+ property is specified, then all the eight voltage values for the -+ 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. -+ -+Optional properties of the main device node (the parent!): - - s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV) - units for buck2 when changing voltage using gpio dvs. Refer to [1] below - for additional information. -@@ -25,26 +33,13 @@ Required properties of the main device node (the parent!): - units for buck4 when changing voltage using gpio dvs. Refer to [1] below - for additional information. - -- - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used -- for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. -- -- [1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional -- property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage' -- property should specify atleast one voltage level (which would be a -- safe operating voltage). -- -- If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional -- property is specified, then all the eight voltage values for the -- 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. -- --Optional properties of the main device node (the parent!): - - s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. - - s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs. - - s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs. - - Additional properties required if either of the optional properties are used: - -- - s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from -+ - s5m8767,pmic-buck-default-dvs-idx: Default voltage setting selected from - the possible 8 options selectable by the dvs gpios. The value of this - property should be between 0 and 7. If not specified or if out of range, the - default value of this property is set to 0. -diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml -index a07de5ed0ca6a..2d34f3ccb2572 100644 ---- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml -+++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml -@@ -199,12 +199,11 @@ patternProperties: - - contribution: - $ref: /schemas/types.yaml#/definitions/uint32 -- minimum: 0 -- maximum: 100 - description: -- The percentage contribution of the cooling devices at the -- specific trip temperature referenced in this map -- to this thermal zone -+ The cooling contribution to the thermal zone of the referred -+ cooling device at the referred trip point. The contribution is -+ a ratio of the sum of all cooling contributions within a -+ thermal zone. - - required: - - trip -diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml -index 76cb9586ee00c..93cd77a6e92c0 100644 ---- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml -+++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml -@@ -39,8 +39,8 @@ properties: - samsung,syscon-phandle: - $ref: /schemas/types.yaml#/definitions/phandle - description: -- Phandle to the PMU system controller node (in case of Exynos5250 -- and Exynos5420). -+ Phandle to the PMU system controller node (in case of Exynos5250, -+ Exynos5420 and Exynos7). - - required: - - compatible -@@ -58,6 +58,7 @@ allOf: - enum: - - samsung,exynos5250-wdt - - samsung,exynos5420-wdt -+ - samsung,exynos7-wdt - then: - required: - - samsung,syscon-phandle -diff --git a/Documentation/driver-api/dmaengine/dmatest.rst b/Documentation/driver-api/dmaengine/dmatest.rst -index ee268d445d38b..d2e1d8b58e7dc 100644 ---- a/Documentation/driver-api/dmaengine/dmatest.rst -+++ b/Documentation/driver-api/dmaengine/dmatest.rst -@@ -143,13 +143,14 @@ Part 5 - Handling channel allocation - Allocating Channels - ------------------- - --Channels are required to be configured prior to starting the test run. --Attempting to run the test without configuring the channels will fail. -+Channels do not need to be configured prior to starting a test run. Attempting -+to run the test without configuring the channels will result in testing any -+channels that are available. - - Example:: - - % echo 1 > /sys/module/dmatest/parameters/run -- dmatest: Could not start test, no channels configured -+ dmatest: No channels configured, continue with any - - Channels are registered using the "channel" parameter. Channels can be requested by their - name, once requested, the channel is registered and a pending thread is added to the test list. -diff --git a/Documentation/driver-api/firewire.rst b/Documentation/driver-api/firewire.rst -index 94a2d7f01d999..d3cfa73cbb2b4 100644 ---- a/Documentation/driver-api/firewire.rst -+++ b/Documentation/driver-api/firewire.rst -@@ -19,7 +19,7 @@ of kernel interfaces is available via exported symbols in `firewire-core` module - Firewire char device data structures - ==================================== - --.. include:: /ABI/stable/firewire-cdev -+.. include:: ../ABI/stable/firewire-cdev - :literal: - - .. kernel-doc:: include/uapi/linux/firewire-cdev.h -@@ -28,7 +28,7 @@ Firewire char device data structures - Firewire device probing and sysfs interfaces - ============================================ - --.. include:: /ABI/stable/sysfs-bus-firewire -+.. include:: ../ABI/stable/sysfs-bus-firewire - :literal: - - .. kernel-doc:: drivers/firewire/core-device.c -diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst -index 0eb799d9d05a2..7940a45d39522 100644 ---- a/Documentation/filesystems/fscrypt.rst -+++ b/Documentation/filesystems/fscrypt.rst -@@ -176,11 +176,11 @@ Master Keys - - Each encrypted directory tree is protected by a *master key*. Master - keys can be up to 64 bytes long, and must be at least as long as the --greater of the key length needed by the contents and filenames --encryption modes being used. For example, if AES-256-XTS is used for --contents encryption, the master key must be 64 bytes (512 bits). Note --that the XTS mode is defined to require a key twice as long as that --required by the underlying block cipher. -+greater of the security strength of the contents and filenames -+encryption modes being used. For example, if any AES-256 mode is -+used, the master key must be at least 256 bits, i.e. 32 bytes. A -+stricter requirement applies if the key is used by a v1 encryption -+policy and AES-256-XTS is used; such keys must be 64 bytes. - - To "unlock" an encrypted directory tree, userspace must provide the - appropriate master key. There can be any number of master keys, each -diff --git a/Documentation/firmware-guide/acpi/dsd/data-node-references.rst b/Documentation/firmware-guide/acpi/dsd/data-node-references.rst -index b7ad47df49de0..8b65b32e6e40e 100644 ---- a/Documentation/firmware-guide/acpi/dsd/data-node-references.rst -+++ b/Documentation/firmware-guide/acpi/dsd/data-node-references.rst -@@ -5,7 +5,7 @@ - Referencing hierarchical data nodes - =================================== - --:Copyright: |copy| 2018 Intel Corporation -+:Copyright: |copy| 2018, 2021 Intel Corporation - :Author: Sakari Ailus - - ACPI in general allows referring to device objects in the tree only. -@@ -52,12 +52,14 @@ the ANOD object which is also the final target node of the reference. - Name (NOD0, Package() { - ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { -+ Package () { "reg", 0 }, - Package () { "random-property", 3 }, - } - }) - Name (NOD1, Package() { - ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package () { -+ Package () { "reg", 1 }, - Package () { "anothernode", "ANOD" }, - } - }) -@@ -74,7 +76,11 @@ the ANOD object which is also the final target node of the reference. - Name (_DSD, Package () { - ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { -- Package () { "reference", ^DEV0, "node@1", "anothernode" }, -+ Package () { -+ "reference", Package () { -+ ^DEV0, "node@1", "anothernode" -+ } -+ }, - } - }) - } -diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst -index 204ebdaadb45a..03021dfa0dd81 100644 ---- a/Documentation/gpu/i915.rst -+++ b/Documentation/gpu/i915.rst -@@ -183,25 +183,25 @@ Frame Buffer Compression (FBC) - Display Refresh Rate Switching (DRRS) - ------------------------------------- - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :doc: Display Refresh Rate Switching (DRRS) - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_dp_set_drrs_state - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_enable - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_disable - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_invalidate - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_flush - --.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c -+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_dp_drrs_init - - DPIO -diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst -index 12e61869939e8..67de1e94fdf76 100644 ---- a/Documentation/gpu/todo.rst -+++ b/Documentation/gpu/todo.rst -@@ -311,27 +311,6 @@ Contact: Daniel Vetter, Noralf Tronnes - - Level: Advanced - --Garbage collect fbdev scrolling acceleration ---------------------------------------------- -- --Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode = --SCROLL_REDRAW. There's a ton of code this will allow us to remove: -- --- lots of code in fbcon.c -- --- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called -- directly instead of the function table (with a switch on p->rotate) -- --- fb_copyarea is unused after this, and can be deleted from all drivers -- --Note that not all acceleration code can be deleted, since clearing and cursor --support is still accelerated, which might be good candidates for further --deletion projects. -- --Contact: Daniel Vetter -- --Level: Intermediate -- - idr_init_base() - --------------- - -diff --git a/Documentation/hwmon/lm90.rst b/Documentation/hwmon/lm90.rst -index 3da8c6e06a365..05391fb4042d9 100644 ---- a/Documentation/hwmon/lm90.rst -+++ b/Documentation/hwmon/lm90.rst -@@ -265,6 +265,16 @@ Supported chips: - - https://www.ti.com/litv/pdf/sbos686 - -+ * Texas Instruments TMP461 -+ -+ Prefix: 'tmp461' -+ -+ Addresses scanned: I2C 0x48 through 0x4F -+ -+ Datasheet: Publicly available at TI website -+ -+ https://www.ti.com/lit/gpn/tmp461 -+ - Author: Jean Delvare - - -diff --git a/Documentation/locking/locktypes.rst b/Documentation/locking/locktypes.rst -index ddada4a537493..4fd7b70fcde19 100644 ---- a/Documentation/locking/locktypes.rst -+++ b/Documentation/locking/locktypes.rst -@@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels:: - spin_lock(&p->lock); - p->count += this_cpu_read(var2); - --On a non-PREEMPT_RT kernel migrate_disable() maps to preempt_disable() --which makes the above code fully equivalent. On a PREEMPT_RT kernel - migrate_disable() ensures that the task is pinned on the current CPU which - in turn guarantees that the per-CPU access to var1 and var2 are staying on --the same CPU. -+the same CPU while the task remains preemptible. - - The migrate_disable() substitution is not valid for the following - scenario:: -@@ -456,9 +454,8 @@ scenario:: - p = this_cpu_ptr(&var1); - p->val = func2(); - --While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because --here migrate_disable() does not protect against reentrancy from a --preempting task. A correct substitution for this case is:: -+This breaks because migrate_disable() does not protect against reentrancy from -+a preempting task. A correct substitution for this case is:: - - func() - { -diff --git a/Documentation/networking/bonding.rst b/Documentation/networking/bonding.rst -index 31cfd7d674a6c..c0a789b008063 100644 ---- a/Documentation/networking/bonding.rst -+++ b/Documentation/networking/bonding.rst -@@ -196,11 +196,12 @@ ad_actor_sys_prio - ad_actor_system - - In an AD system, this specifies the mac-address for the actor in -- protocol packet exchanges (LACPDUs). The value cannot be NULL or -- multicast. It is preferred to have the local-admin bit set for this -- mac but driver does not enforce it. If the value is not given then -- system defaults to using the masters' mac address as actors' system -- address. -+ protocol packet exchanges (LACPDUs). The value cannot be a multicast -+ address. If the all-zeroes MAC is specified, bonding will internally -+ use the MAC of the bond itself. It is preferred to have the -+ local-admin bit set for this mac but driver does not enforce it. If -+ the value is not given then system defaults to using the masters' -+ mac address as actors' system address. - - This parameter has effect only in 802.3ad mode and is available through - SysFs interface. -diff --git a/Documentation/networking/device_drivers/ethernet/intel/ixgbe.rst b/Documentation/networking/device_drivers/ethernet/intel/ixgbe.rst -index f1d5233e5e510..0a233b17c664e 100644 ---- a/Documentation/networking/device_drivers/ethernet/intel/ixgbe.rst -+++ b/Documentation/networking/device_drivers/ethernet/intel/ixgbe.rst -@@ -440,6 +440,22 @@ NOTE: For 82599-based network connections, if you are enabling jumbo frames in - a virtual function (VF), jumbo frames must first be enabled in the physical - function (PF). The VF MTU setting cannot be larger than the PF MTU. - -+NBASE-T Support -+--------------- -+The ixgbe driver supports NBASE-T on some devices. However, the advertisement -+of NBASE-T speeds is suppressed by default, to accommodate broken network -+switches which cannot cope with advertised NBASE-T speeds. Use the ethtool -+command to enable advertising NBASE-T speeds on devices which support it:: -+ -+ ethtool -s eth? advertise 0x1800000001028 -+ -+On Linux systems with INTERFACES(5), this can be specified as a pre-up command -+in /etc/network/interfaces so that the interface is always brought up with -+NBASE-T support, e.g.:: -+ -+ iface eth? inet dhcp -+ pre-up ethtool -s eth? advertise 0x1800000001028 || true -+ - Generic Receive Offload, aka GRO - -------------------------------- - The driver supports the in-kernel software implementation of GRO. GRO has -diff --git a/Documentation/networking/ipvs-sysctl.rst b/Documentation/networking/ipvs-sysctl.rst -index 2afccc63856ee..1cfbf1add2fc9 100644 ---- a/Documentation/networking/ipvs-sysctl.rst -+++ b/Documentation/networking/ipvs-sysctl.rst -@@ -37,8 +37,7 @@ conn_reuse_mode - INTEGER - - 0: disable any special handling on port reuse. The new - connection will be delivered to the same real server that was -- servicing the previous connection. This will effectively -- disable expire_nodest_conn. -+ servicing the previous connection. - - bit 1: enable rescheduling of new connections when it is safe. - That is, whenever expire_nodest_conn and for TCP sockets, when -diff --git a/Documentation/sound/hd-audio/models.rst b/Documentation/sound/hd-audio/models.rst -index 0ea967d345838..d25335993e553 100644 ---- a/Documentation/sound/hd-audio/models.rst -+++ b/Documentation/sound/hd-audio/models.rst -@@ -326,6 +326,8 @@ usi-headset - Headset support on USI machines - dual-codecs - Lenovo laptops with dual codecs -+alc285-hp-amp-init -+ HP laptops which require speaker amplifier initialization (ALC285) - - ALC680 - ====== -diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst -index a4e3ef2952401..6ed13398ca2ce 100644 ---- a/Documentation/trace/coresight/coresight-config.rst -+++ b/Documentation/trace/coresight/coresight-config.rst -@@ -211,19 +211,13 @@ also declared in the perf 'cs_etm' event infrastructure so that they can - be selected when running trace under perf:: - - $ ls /sys/devices/cs_etm -- configurations format perf_event_mux_interval_ms sinks type -- events nr_addr_filters power -+ cpu0 cpu2 events nr_addr_filters power subsystem uevent -+ cpu1 cpu3 format perf_event_mux_interval_ms sinks type - --Key directories here are 'configurations' - which lists the loaded --configurations, and 'events' - a generic perf directory which allows --selection on the perf command line.:: -+The key directory here is 'events' - a generic perf directory which allows -+selection on the perf command line. As with the sinks entries, this provides -+a hash of the configuration name. - -- $ ls configurations/ -- autofdo -- $ cat configurations/autofdo -- 0xa7c3dddd -- --As with the sinks entries, this provides a hash of the configuration name. - The entry in the 'events' directory uses perfs built in syntax generator - to substitute the syntax for the name when evaluating the command:: - -diff --git a/Documentation/trace/events.rst b/Documentation/trace/events.rst -index 8ddb9b09451c8..c47f381d0c002 100644 ---- a/Documentation/trace/events.rst -+++ b/Documentation/trace/events.rst -@@ -198,6 +198,15 @@ The glob (~) accepts a wild card character (\*,?) and character classes - prev_comm ~ "*sh*" - prev_comm ~ "ba*sh" - -+If the field is a pointer that points into user space (for example -+"filename" from sys_enter_openat), then you have to append ".ustring" to the -+field name:: -+ -+ filename.ustring ~ "password" -+ -+As the kernel will have to know how to retrieve the memory that the pointer -+is at from user space. -+ - 5.2 Setting filters - ------------------- - -@@ -230,6 +239,16 @@ Currently the caret ('^') for an error always appears at the beginning of - the filter string; the error message should still be useful though - even without more accurate position info. - -+5.2.1 Filter limitations -+------------------------ -+ -+If a filter is placed on a string pointer ``(char *)`` that does not point -+to a string on the ring buffer, but instead points to kernel or user space -+memory, then, for safety reasons, at most 1024 bytes of the content is -+copied onto a temporary buffer to do the compare. If the copy of the memory -+faults (the pointer points to memory that should not be accessed), then the -+string compare will be treated as not matching. -+ - 5.3 Clearing filters - -------------------- - -diff --git a/MAINTAINERS b/MAINTAINERS -index 3b79fd441dde8..c8103e57a70be 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -7024,7 +7024,6 @@ F: drivers/net/mdio/fwnode_mdio.c - F: drivers/net/mdio/of_mdio.c - F: drivers/net/pcs/ - F: drivers/net/phy/ --F: drivers/of/of_net.c - F: include/dt-bindings/net/qca-ar803x.h - F: include/linux/*mdio*.h - F: include/linux/mdio/*.h -@@ -7036,6 +7035,7 @@ F: include/linux/platform_data/mdio-gpio.h - F: include/trace/events/mdio.h - F: include/uapi/linux/mdio.h - F: include/uapi/linux/mii.h -+F: net/core/of_net.c - - EXFAT FILE SYSTEM - M: Namjae Jeon -diff --git a/Makefile b/Makefile -index ed6e7ec60eff6..ad64687080cff 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 5 - PATCHLEVEL = 15 --SUBLEVEL = 0 -+SUBLEVEL = 28 - EXTRAVERSION = - NAME = Trick or Treat - -diff --git a/arch/Kconfig b/arch/Kconfig -index 8df1c71026435..d1e69d6e8498b 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -1234,6 +1234,9 @@ config RELR - config ARCH_HAS_MEM_ENCRYPT - bool - -+config ARCH_HAS_CC_PLATFORM -+ bool -+ - config HAVE_SPARSE_SYSCALL_NR - bool - help -diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c -index 3793876f42d9b..8e90052f6f056 100644 ---- a/arch/arc/kernel/process.c -+++ b/arch/arc/kernel/process.c -@@ -294,7 +294,7 @@ int elf_check_arch(const struct elf32_hdr *x) - eflags = x->e_flags; - if ((eflags & EF_ARC_OSABI_MSK) != EF_ARC_OSABI_CURRENT) { - pr_err("ABI mismatch - you need newer toolchain\n"); -- force_sigsegv(SIGSEGV); -+ force_fatal_sig(SIGSEGV); - return 0; - } - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index dcf2df6da98f0..4ebd512043be5 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -1455,6 +1455,7 @@ config HIGHMEM - bool "High Memory Support" - depends on MMU - select KMAP_LOCAL -+ select KMAP_LOCAL_NON_LINEAR_PTE_ARRAY - help - The address space of ARM processors is only 4 Gigabytes large - and it has to accommodate user address space, kernel address -diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index 98436702e0c7e..644875d73ba15 100644 ---- a/arch/arm/Kconfig.debug -+++ b/arch/arm/Kconfig.debug -@@ -410,12 +410,12 @@ choice - Say Y here if you want kernel low-level debugging support - on i.MX25. - -- config DEBUG_IMX21_IMX27_UART -- bool "i.MX21 and i.MX27 Debug UART" -- depends on SOC_IMX21 || SOC_IMX27 -+ config DEBUG_IMX27_UART -+ bool "i.MX27 Debug UART" -+ depends on SOC_IMX27 - help - Say Y here if you want kernel low-level debugging support -- on i.MX21 or i.MX27. -+ on i.MX27. - - config DEBUG_IMX28_UART - bool "i.MX28 Debug UART" -@@ -1481,7 +1481,7 @@ config DEBUG_IMX_UART_PORT - int "i.MX Debug UART Port Selection" - depends on DEBUG_IMX1_UART || \ - DEBUG_IMX25_UART || \ -- DEBUG_IMX21_IMX27_UART || \ -+ DEBUG_IMX27_UART || \ - DEBUG_IMX31_UART || \ - DEBUG_IMX35_UART || \ - DEBUG_IMX50_UART || \ -@@ -1540,12 +1540,12 @@ config DEBUG_LL_INCLUDE - default "debug/icedcc.S" if DEBUG_ICEDCC - default "debug/imx.S" if DEBUG_IMX1_UART || \ - DEBUG_IMX25_UART || \ -- DEBUG_IMX21_IMX27_UART || \ -+ DEBUG_IMX27_UART || \ - DEBUG_IMX31_UART || \ - DEBUG_IMX35_UART || \ - DEBUG_IMX50_UART || \ - DEBUG_IMX51_UART || \ -- DEBUG_IMX53_UART ||\ -+ DEBUG_IMX53_UART || \ - DEBUG_IMX6Q_UART || \ - DEBUG_IMX6SL_UART || \ - DEBUG_IMX6SX_UART || \ -diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 847c31e7c3687..fa45837b8065c 100644 ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -60,15 +60,15 @@ KBUILD_CFLAGS += $(call cc-option,-fno-ipa-sra) - # Note that GCC does not numerically define an architecture version - # macro, but instead defines a whole series of macros which makes - # testing for a specific architecture or later rather impossible. --arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m --arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) --arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) -+arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -+arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -march=armv7-a -+arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 -march=armv6 - # Only override the compiler option if ARMv6. The ARMv6K extensions are - # always available in ARMv7 - ifeq ($(CONFIG_CPU_32v6),y) --arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) -+arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 -march=armv6k - endif --arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) -+arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 -march=armv5te - arch-$(CONFIG_CPU_32v4T) =-D__LINUX_ARM_ARCH__=4 -march=armv4t - arch-$(CONFIG_CPU_32v4) =-D__LINUX_ARM_ARCH__=4 -march=armv4 - arch-$(CONFIG_CPU_32v3) =-D__LINUX_ARM_ARCH__=3 -march=armv3m -@@ -82,7 +82,7 @@ tune-$(CONFIG_CPU_ARM720T) =-mtune=arm7tdmi - tune-$(CONFIG_CPU_ARM740T) =-mtune=arm7tdmi - tune-$(CONFIG_CPU_ARM9TDMI) =-mtune=arm9tdmi - tune-$(CONFIG_CPU_ARM940T) =-mtune=arm9tdmi --tune-$(CONFIG_CPU_ARM946E) =$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) -+tune-$(CONFIG_CPU_ARM946E) =-mtune=arm9e - tune-$(CONFIG_CPU_ARM920T) =-mtune=arm9tdmi - tune-$(CONFIG_CPU_ARM922T) =-mtune=arm9tdmi - tune-$(CONFIG_CPU_ARM925T) =-mtune=arm9tdmi -@@ -90,11 +90,11 @@ tune-$(CONFIG_CPU_ARM926T) =-mtune=arm9tdmi - tune-$(CONFIG_CPU_FA526) =-mtune=arm9tdmi - tune-$(CONFIG_CPU_SA110) =-mtune=strongarm110 - tune-$(CONFIG_CPU_SA1100) =-mtune=strongarm1100 --tune-$(CONFIG_CPU_XSCALE) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale --tune-$(CONFIG_CPU_XSC3) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale --tune-$(CONFIG_CPU_FEROCEON) =$(call cc-option,-mtune=marvell-f,-mtune=xscale) --tune-$(CONFIG_CPU_V6) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) --tune-$(CONFIG_CPU_V6K) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) -+tune-$(CONFIG_CPU_XSCALE) =-mtune=xscale -+tune-$(CONFIG_CPU_XSC3) =-mtune=xscale -+tune-$(CONFIG_CPU_FEROCEON) =-mtune=xscale -+tune-$(CONFIG_CPU_V6) =-mtune=arm1136j-s -+tune-$(CONFIG_CPU_V6K) =-mtune=arm1136j-s - - # Evaluate tune cc-option calls now - tune-y := $(tune-y) -diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S -index c0e7a745103e2..230030c130853 100644 ---- a/arch/arm/boot/compressed/efi-header.S -+++ b/arch/arm/boot/compressed/efi-header.S -@@ -9,16 +9,22 @@ - #include - - .macro __nop --#ifdef CONFIG_EFI_STUB -- @ This is almost but not quite a NOP, since it does clobber the -- @ condition flags. But it is the best we can do for EFI, since -- @ PE/COFF expects the magic string "MZ" at offset 0, while the -- @ ARM/Linux boot protocol expects an executable instruction -- @ there. -- .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000 --#else - AR_CLASS( mov r0, r0 ) - M_CLASS( nop.w ) -+ .endm -+ -+ .macro __initial_nops -+#ifdef CONFIG_EFI_STUB -+ @ This is a two-instruction NOP, which happens to bear the -+ @ PE/COFF signature "MZ" in the first two bytes, so the kernel -+ @ is accepted as an EFI binary. Booting via the UEFI stub -+ @ will not execute those instructions, but the ARM/Linux -+ @ boot protocol does, so we need some NOPs here. -+ .inst MZ_MAGIC | (0xe225 << 16) @ eor r5, r5, 0x4d000 -+ eor r5, r5, 0x4d000 @ undo previous insn -+#else -+ __nop -+ __nop - #endif - .endm - -diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S -index b1cb1972361b8..bf79f2f78d232 100644 ---- a/arch/arm/boot/compressed/head.S -+++ b/arch/arm/boot/compressed/head.S -@@ -203,7 +203,8 @@ start: - * were patching the initial instructions of the kernel, i.e - * had started to exploit this "patch area". - */ -- .rept 7 -+ __initial_nops -+ .rept 5 - __nop - .endr - #ifndef CONFIG_THUMB2_KERNEL -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 7e0934180724d..27ca1ca6e827c 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -779,6 +779,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \ - logicpd-som-lv-37xx-devkit.dtb \ - omap3430-sdp.dtb \ - omap3-beagle.dtb \ -+ omap3-beagle-ab4.dtb \ - omap3-beagle-xm.dtb \ - omap3-beagle-xm-ab.dtb \ - omap3-cm-t3517.dtb \ -diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi -index 9b1a24cc5e91f..df3c8d1d8f641 100644 ---- a/arch/arm/boot/dts/armada-38x.dtsi -+++ b/arch/arm/boot/dts/armada-38x.dtsi -@@ -168,7 +168,7 @@ - }; - - uart0: serial@12000 { -- compatible = "marvell,armada-38x-uart"; -+ compatible = "marvell,armada-38x-uart", "ns16550a"; - reg = <0x12000 0x100>; - reg-shift = <2>; - interrupts = ; -@@ -178,7 +178,7 @@ - }; - - uart1: serial@12100 { -- compatible = "marvell,armada-38x-uart"; -+ compatible = "marvell,armada-38x-uart", "ns16550a"; - reg = <0x12100 0x100>; - reg-shift = <2>; - interrupts = ; -diff --git a/arch/arm/boot/dts/at91-tse850-3.dts b/arch/arm/boot/dts/at91-tse850-3.dts -index 3ca97b47c69ce..7e5c598e7e68f 100644 ---- a/arch/arm/boot/dts/at91-tse850-3.dts -+++ b/arch/arm/boot/dts/at91-tse850-3.dts -@@ -262,7 +262,7 @@ - &macb1 { - status = "okay"; - -- phy-mode = "rgmii"; -+ phy-mode = "rmii"; - - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi -index 748df7955ae67..e96ddb2e26e2c 100644 ---- a/arch/arm/boot/dts/bcm-nsp.dtsi -+++ b/arch/arm/boot/dts/bcm-nsp.dtsi -@@ -77,7 +77,7 @@ - interrupt-affinity = <&cpu0>, <&cpu1>; - }; - -- mpcore@19000000 { -+ mpcore-bus@19000000 { - compatible = "simple-bus"; - ranges = <0x00000000 0x19000000 0x00023000>; - #address-cells = <1>; -@@ -219,7 +219,7 @@ - status = "disabled"; - }; - -- sdio: sdhci@21000 { -+ sdio: mmc@21000 { - compatible = "brcm,sdhci-iproc-cygnus"; - reg = <0x21000 0x100>; - interrupts = ; -diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi -index 3b60297af7f60..dff18fc9a9065 100644 ---- a/arch/arm/boot/dts/bcm2711.dtsi -+++ b/arch/arm/boot/dts/bcm2711.dtsi -@@ -506,11 +506,17 @@ - #address-cells = <3>; - #interrupt-cells = <1>; - #size-cells = <2>; -- interrupts = , -+ interrupts = , - ; - interrupt-names = "pcie", "msi"; - interrupt-map-mask = <0x0 0x0 0x0 0x7>; - interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 -+ IRQ_TYPE_LEVEL_HIGH>, -+ <0 0 0 2 &gicv2 GIC_SPI 144 -+ IRQ_TYPE_LEVEL_HIGH>, -+ <0 0 0 3 &gicv2 GIC_SPI 145 -+ IRQ_TYPE_LEVEL_HIGH>, -+ <0 0 0 4 &gicv2 GIC_SPI 146 - IRQ_TYPE_LEVEL_HIGH>; - msi-controller; - msi-parent = <&pcie0>; -@@ -576,6 +582,8 @@ - , - ; - -+ gpio-ranges = <&gpio 0 0 58>; -+ - gpclk0_gpio49: gpclk0_gpio49 { - pin-gpclk { - pins = "gpio49"; -diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi -index a3e06b6809476..c113661a6668f 100644 ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -126,6 +126,8 @@ - interrupt-controller; - #interrupt-cells = <2>; - -+ gpio-ranges = <&gpio 0 0 54>; -+ - /* Defines common pin muxing groups - * - * While each pin can have its mux selected -diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts -index 61c7b137607e5..7900aac4f35a9 100644 ---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts -+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts -@@ -20,7 +20,7 @@ - bootargs = "console=ttyS0,115200 earlycon"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x08000000>; -diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts -index 6c6bb7b17d27a..7546c8d07bcd7 100644 ---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts -+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts -@@ -19,7 +19,7 @@ - bootargs = "console=ttyS0,115200"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x08000000>; -diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts -index d29e7f80ea6aa..beae9eab9cb8c 100644 ---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts -+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts -@@ -19,7 +19,7 @@ - bootargs = "console=ttyS0,115200"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x18000000>; -diff --git a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts -index 9b6887d477d86..7879f7d7d9c33 100644 ---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts -+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts -@@ -16,7 +16,7 @@ - bootargs = "console=ttyS0,115200"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x08000000>; -diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts -index 7989a53597d4f..56d309dbc6b0d 100644 ---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts -+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts -@@ -19,7 +19,7 @@ - bootargs = "console=ttyS0,115200"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x08000000>; -diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts -index 87b655be674c5..184e3039aa864 100644 ---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts -+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts -@@ -30,7 +30,7 @@ - bootargs = "console=ttyS0,115200"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x08000000>; -diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts -index f806be5da7237..c2a266a439d05 100644 ---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts -+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts -@@ -15,7 +15,7 @@ - bootargs = "console=ttyS0,115200 earlycon"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>; - }; -diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts -index 05d4f2931772b..9bef6b9bfa8d9 100644 ---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts -+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts -@@ -129,7 +129,7 @@ - }; - }; - -- mdio-bus-mux@18003000 { -+ mdio-mux@18003000 { - - /* BIT(9) = 1 => external mdio */ - mdio@200 { -diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts -index 452b8d0ab180e..b0d8a688141d3 100644 ---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts -+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts -@@ -16,7 +16,7 @@ - bootargs = "earlycon"; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>, - <0x88000000 0x18000000>; -diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts -index 3b978dc8997a4..577a4dc604d93 100644 ---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts -+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts -@@ -20,7 +20,7 @@ - bootargs = " console=ttyS0,115200n8 earlycon"; - }; - -- memory { -+ memory@0 { - reg = <0x00000000 0x08000000>; - device_type = "memory"; - }; -@@ -195,3 +195,25 @@ - }; - }; - }; -+ -+&srab { -+ status = "okay"; -+ -+ ports { -+ port@0 { -+ reg = <0>; -+ label = "poe"; -+ }; -+ -+ port@5 { -+ reg = <5>; -+ label = "cpu"; -+ ethernet = <&gmac0>; -+ -+ fixed-link { -+ speed = <1000>; -+ duplex-full; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi -index f92089290ccd5..f69d2af3c1fa4 100644 ---- a/arch/arm/boot/dts/bcm5301x.dtsi -+++ b/arch/arm/boot/dts/bcm5301x.dtsi -@@ -19,7 +19,7 @@ - #size-cells = <1>; - interrupt-parent = <&gic>; - -- chipcommonA@18000000 { -+ chipcommon-a-bus@18000000 { - compatible = "simple-bus"; - ranges = <0x00000000 0x18000000 0x00001000>; - #address-cells = <1>; -@@ -44,7 +44,7 @@ - }; - }; - -- mpcore@19000000 { -+ mpcore-bus@19000000 { - compatible = "simple-bus"; - ranges = <0x00000000 0x19000000 0x00023000>; - #address-cells = <1>; -@@ -242,6 +242,8 @@ - - gpio-controller; - #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; - }; - - pcie0: pcie@12000 { -@@ -369,8 +371,8 @@ - #address-cells = <1>; - }; - -- mdio-bus-mux@18003000 { -- compatible = "mdio-mux-mmioreg"; -+ mdio-mux@18003000 { -+ compatible = "mdio-mux-mmioreg", "mdio-mux"; - mdio-parent-bus = <&mdio>; - #address-cells = <1>; - #size-cells = <0>; -@@ -408,14 +410,14 @@ - i2c0: i2c@18009000 { - compatible = "brcm,iproc-i2c"; - reg = <0x18009000 0x50>; -- interrupts = ; -+ interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clock-frequency = <100000>; - status = "disabled"; - }; - -- dmu@1800c000 { -+ dmu-bus@1800c000 { - compatible = "simple-bus"; - ranges = <0 0x1800c000 0x1000>; - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm94708.dts b/arch/arm/boot/dts/bcm94708.dts -index 3d13e46c69494..d9eb2040b9631 100644 ---- a/arch/arm/boot/dts/bcm94708.dts -+++ b/arch/arm/boot/dts/bcm94708.dts -@@ -38,7 +38,7 @@ - model = "NorthStar SVK (BCM94708)"; - compatible = "brcm,bcm94708", "brcm,bcm4708"; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>; - }; -diff --git a/arch/arm/boot/dts/bcm94709.dts b/arch/arm/boot/dts/bcm94709.dts -index 5017b7b259cbe..618c812eef73e 100644 ---- a/arch/arm/boot/dts/bcm94709.dts -+++ b/arch/arm/boot/dts/bcm94709.dts -@@ -38,7 +38,7 @@ - model = "NorthStar SVK (BCM94709)"; - compatible = "brcm,bcm94709", "brcm,bcm4709", "brcm,bcm4708"; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>; - }; -diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts -index 55922176807e6..5f5d9b1357365 100644 ---- a/arch/arm/boot/dts/exynos4210-i9100.dts -+++ b/arch/arm/boot/dts/exynos4210-i9100.dts -@@ -827,7 +827,7 @@ - compatible = "brcm,bcm4330-bt"; - - shutdown-gpios = <&gpl0 4 GPIO_ACTIVE_HIGH>; -- reset-gpios = <&gpl1 0 GPIO_ACTIVE_HIGH>; -+ reset-gpios = <&gpl1 0 GPIO_ACTIVE_LOW>; - device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>; - host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>; - }; -diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts -index 13112a8a5dd88..6544c730340fa 100644 ---- a/arch/arm/boot/dts/gemini-nas4220b.dts -+++ b/arch/arm/boot/dts/gemini-nas4220b.dts -@@ -84,7 +84,7 @@ - partitions { - compatible = "redboot-fis"; - /* Eraseblock at 0xfe0000 */ -- fis-index-block = <0x1fc>; -+ fis-index-block = <0x7f>; - }; - }; - -diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts -index 8cbaf1c811745..3b609d987d883 100644 ---- a/arch/arm/boot/dts/imx23-evk.dts -+++ b/arch/arm/boot/dts/imx23-evk.dts -@@ -79,7 +79,6 @@ - MX23_PAD_LCD_RESET__GPIO_1_18 - MX23_PAD_PWM3__GPIO_1_29 - MX23_PAD_PWM4__GPIO_1_30 -- MX23_PAD_SSP1_DETECT__SSP1_DETECT - >; - fsl,drive-strength = ; - fsl,voltage = ; -diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi -index d07d8f83456d2..ccfa8e320be62 100644 ---- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi -@@ -5,6 +5,8 @@ - * Author: Fabio Estevam - */ - -+#include -+ - / { - aliases { - backlight = &backlight; -@@ -226,6 +228,7 @@ - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 -+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 - >; - }; - -@@ -304,7 +307,7 @@ - &usdhc3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc3>; -- non-removable; -+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; - status = "okay"; - }; - -diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi -index b62a0dbb033ff..ec6fba5ee8fde 100644 ---- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi -@@ -309,6 +309,7 @@ - - ethphy: ethernet-phy@1 { - reg = <1>; -+ qca,clk-out-frequency = <125000000>; - }; - }; - }; -diff --git a/arch/arm/boot/dts/imx6ull-pinfunc.h b/arch/arm/boot/dts/imx6ull-pinfunc.h -index eb025a9d47592..7328d4ef8559f 100644 ---- a/arch/arm/boot/dts/imx6ull-pinfunc.h -+++ b/arch/arm/boot/dts/imx6ull-pinfunc.h -@@ -82,6 +82,6 @@ - #define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0 - #define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0 - #define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0 --#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0 -+#define MX6ULL_PAD_CSI_DATA07__ESAI_TX0 0x0200 0x048C 0x0000 0x9 0x0 - - #endif /* __DTS_IMX6ULL_PINFUNC_H */ -diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi -index b7ea37ad4e55c..bcec98b964114 100644 ---- a/arch/arm/boot/dts/imx7ulp.dtsi -+++ b/arch/arm/boot/dts/imx7ulp.dtsi -@@ -259,7 +259,7 @@ - interrupts = ; - clocks = <&pcc2 IMX7ULP_CLK_WDG1>; - assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>; -- assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>; -+ assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>; - timeout-sec = <40>; - }; - -diff --git a/arch/arm/boot/dts/ls1021a-tsn.dts b/arch/arm/boot/dts/ls1021a-tsn.dts -index 9d8f0c2a8aba3..aca78b5eddf20 100644 ---- a/arch/arm/boot/dts/ls1021a-tsn.dts -+++ b/arch/arm/boot/dts/ls1021a-tsn.dts -@@ -251,7 +251,7 @@ - - flash@0 { - /* Rev. A uses 64MB flash, Rev. B & C use 32MB flash */ -- compatible = "jedec,spi-nor", "s25fl256s1", "s25fl512s"; -+ compatible = "jedec,spi-nor"; - spi-max-frequency = <20000000>; - #address-cells = <1>; - #size-cells = <1>; -diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi -index 4fce81422943b..f3b8540750b61 100644 ---- a/arch/arm/boot/dts/ls1021a.dtsi -+++ b/arch/arm/boot/dts/ls1021a.dtsi -@@ -329,39 +329,6 @@ - #thermal-sensor-cells = <1>; - }; - -- thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <1000>; -- polling-delay = <5000>; -- -- thermal-sensors = <&tmu 0>; -- -- trips { -- cpu_alert: cpu-alert { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- cpu_crit: cpu-crit { -- temperature = <95000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&cpu_alert>; -- cooling-device = -- <&cpu0 THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu1 THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>; -- }; -- }; -- }; -- }; -- - dspi0: spi@2100000 { - compatible = "fsl,ls1021a-v1.0-dspi"; - #address-cells = <1>; -@@ -1016,4 +983,37 @@ - big-endian; - }; - }; -+ -+ thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ -+ thermal-sensors = <&tmu 0>; -+ -+ trips { -+ cpu_alert: cpu-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ cpu_crit: cpu-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&cpu_alert>; -+ cooling-device = -+ <&cpu0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ }; - }; -diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi -index 3be7cba603d5a..26eaba3fa96f3 100644 ---- a/arch/arm/boot/dts/meson.dtsi -+++ b/arch/arm/boot/dts/meson.dtsi -@@ -59,7 +59,7 @@ - }; - - uart_A: serial@84c0 { -- compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; -+ compatible = "amlogic,meson6-uart"; - reg = <0x84c0 0x18>; - interrupts = ; - fifo-size = <128>; -@@ -67,7 +67,7 @@ - }; - - uart_B: serial@84dc { -- compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; -+ compatible = "amlogic,meson6-uart"; - reg = <0x84dc 0x18>; - interrupts = ; - status = "disabled"; -@@ -105,7 +105,7 @@ - }; - - uart_C: serial@8700 { -- compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; -+ compatible = "amlogic,meson6-uart"; - reg = <0x8700 0x18>; - interrupts = ; - status = "disabled"; -@@ -228,7 +228,7 @@ - }; - - uart_AO: serial@4c0 { -- compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; -+ compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart"; - reg = <0x4c0 0x18>; - interrupts = ; - status = "disabled"; -diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi -index f80ddc98d3a2b..9997a5d0333a3 100644 ---- a/arch/arm/boot/dts/meson8.dtsi -+++ b/arch/arm/boot/dts/meson8.dtsi -@@ -736,27 +736,27 @@ - }; - - &uart_AO { -- compatible = "amlogic,meson8-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8-uart", "amlogic,meson-ao-uart"; -+ clocks = <&xtal>, <&clkc CLKID_CLK81>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &uart_A { -- compatible = "amlogic,meson8-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8-uart"; -+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &uart_B { -- compatible = "amlogic,meson8-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8-uart"; -+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &uart_C { -- compatible = "amlogic,meson8-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8-uart"; -+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &usb0 { -diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi -index b49b7cbaed4ee..94f1c03deccef 100644 ---- a/arch/arm/boot/dts/meson8b.dtsi -+++ b/arch/arm/boot/dts/meson8b.dtsi -@@ -724,27 +724,27 @@ - }; - - &uart_AO { -- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8b-uart", "amlogic,meson-ao-uart"; -+ clocks = <&xtal>, <&clkc CLKID_CLK81>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &uart_A { -- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8b-uart"; -+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &uart_B { -- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8b-uart"; -+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &uart_C { -- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart"; -- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>; -- clock-names = "baud", "xtal", "pclk"; -+ compatible = "amlogic,meson8b-uart"; -+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; -+ clock-names = "xtal", "pclk", "baud"; - }; - - &usb0 { -diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi -index 7f6aefd134514..e7534fe9c53cf 100644 ---- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi -+++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi -@@ -29,7 +29,7 @@ - compatible = "smsc,lan9221","smsc,lan9115"; - bank-width = <2>; - -- gpmc,mux-add-data; -+ gpmc,mux-add-data = <0>; - gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <42>; - gpmc,cs-wr-off-ns = <36>; -diff --git a/arch/arm/boot/dts/omap3-beagle-ab4.dts b/arch/arm/boot/dts/omap3-beagle-ab4.dts -new file mode 100644 -index 0000000000000..990ff2d846868 ---- /dev/null -+++ b/arch/arm/boot/dts/omap3-beagle-ab4.dts -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/dts-v1/; -+ -+#include "omap3-beagle.dts" -+ -+/ { -+ model = "TI OMAP3 BeagleBoard A to B4"; -+ compatible = "ti,omap3-beagle-ab4", "ti,omap3-beagle", "ti,omap3430", "ti,omap3"; -+}; -+ -+/* -+ * Workaround for capacitor C70 issue, see "Boards revision A and < B5" -+ * section at https://elinux.org/BeagleBoard_Community -+ */ -+ -+/* Unusable as clocksource because of unreliable oscillator */ -+&counter32k { -+ status = "disabled"; -+}; -+ -+/* Unusable as clockevent because of unreliable oscillator, allow to idle */ -+&timer1_target { -+ /delete-property/ti,no-reset-on-init; -+ /delete-property/ti,no-idle; -+ timer@0 { -+ /delete-property/ti,timer-alwon; -+ }; -+}; -+ -+/* Preferred always-on timer for clocksource */ -+&timer12_target { -+ ti,no-reset-on-init; -+ ti,no-idle; -+ timer@0 { -+ /* Always clocked by secure_32k_fck */ -+ }; -+}; -+ -+/* Preferred timer for clockevent */ -+&timer2_target { -+ ti,no-reset-on-init; -+ ti,no-idle; -+ timer@0 { -+ assigned-clocks = <&gpt2_fck>; -+ assigned-clock-parents = <&sys_ck>; -+ }; -+}; -diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts -index f9f34b8458e91..0548b391334fd 100644 ---- a/arch/arm/boot/dts/omap3-beagle.dts -+++ b/arch/arm/boot/dts/omap3-beagle.dts -@@ -304,39 +304,6 @@ - phys = <0 &hsusb2_phy>; - }; - --/* Unusable as clocksource because of unreliable oscillator */ --&counter32k { -- status = "disabled"; --}; -- --/* Unusable as clockevent because if unreliable oscillator, allow to idle */ --&timer1_target { -- /delete-property/ti,no-reset-on-init; -- /delete-property/ti,no-idle; -- timer@0 { -- /delete-property/ti,timer-alwon; -- }; --}; -- --/* Preferred always-on timer for clocksource */ --&timer12_target { -- ti,no-reset-on-init; -- ti,no-idle; -- timer@0 { -- /* Always clocked by secure_32k_fck */ -- }; --}; -- --/* Preferred timer for clockevent */ --&timer2_target { -- ti,no-reset-on-init; -- ti,no-idle; -- timer@0 { -- assigned-clocks = <&gpt2_fck>; -- assigned-clock-parents = <&sys_ck>; -- }; --}; -- - &twl_gpio { - ti,use-leds; - /* pullups: BIT(1) */ -diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi -index 2c19d6e255bdc..6883ccb45600b 100644 ---- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi -+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi -@@ -158,6 +158,24 @@ - status = "disabled"; - }; - -+/* Unusable as clockevent because if unreliable oscillator, allow to idle */ -+&timer1_target { -+ /delete-property/ti,no-reset-on-init; -+ /delete-property/ti,no-idle; -+ timer@0 { -+ /delete-property/ti,timer-alwon; -+ }; -+}; -+ -+/* Preferred timer for clockevent */ -+&timer12_target { -+ ti,no-reset-on-init; -+ ti,no-idle; -+ timer@0 { -+ /* Always clocked by secure_32k_fck */ -+ }; -+}; -+ - &twl_gpio { - ti,use-leds; - /* -diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts -index c2995a280729d..162d0726b0080 100644 ---- a/arch/arm/boot/dts/omap3-devkit8000.dts -+++ b/arch/arm/boot/dts/omap3-devkit8000.dts -@@ -14,36 +14,3 @@ - display2 = &tv0; - }; - }; -- --/* Unusable as clocksource because of unreliable oscillator */ --&counter32k { -- status = "disabled"; --}; -- --/* Unusable as clockevent because if unreliable oscillator, allow to idle */ --&timer1_target { -- /delete-property/ti,no-reset-on-init; -- /delete-property/ti,no-idle; -- timer@0 { -- /delete-property/ti,timer-alwon; -- }; --}; -- --/* Preferred always-on timer for clocksource */ --&timer12_target { -- ti,no-reset-on-init; -- ti,no-idle; -- timer@0 { -- /* Always clocked by secure_32k_fck */ -- }; --}; -- --/* Preferred timer for clockevent */ --&timer2_target { -- ti,no-reset-on-init; -- ti,no-idle; -- timer@0 { -- assigned-clocks = <&gpt2_fck>; -- assigned-clock-parents = <&sys_ck>; -- }; --}; -diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi -index 938cc691bb2fe..23ab27fe4ee5d 100644 ---- a/arch/arm/boot/dts/omap3-gta04.dtsi -+++ b/arch/arm/boot/dts/omap3-gta04.dtsi -@@ -515,7 +515,7 @@ - compatible = "bosch,bma180"; - reg = <0x41>; - pinctrl-names = "default"; -- pintcrl-0 = <&bma180_pins>; -+ pinctrl-0 = <&bma180_pins>; - interrupt-parent = <&gpio4>; - interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_115 */ - }; -diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts -index 32335d4ce478b..d40c3d2c4914e 100644 ---- a/arch/arm/boot/dts/omap3-n900.dts -+++ b/arch/arm/boot/dts/omap3-n900.dts -@@ -8,6 +8,7 @@ - - #include "omap34xx.dtsi" - #include -+#include - - /* - * Default secure signed bootloader (Nokia X-Loader) does not enable L3 firewall -@@ -630,63 +631,92 @@ - }; - - lp5523: lp5523@32 { -+ #address-cells = <1>; -+ #size-cells = <0>; - compatible = "national,lp5523"; - reg = <0x32>; - clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */ -- enable-gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */ -+ enable-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */ - -- chan0 { -+ led@0 { -+ reg = <0>; - chan-name = "lp5523:kb1"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_KBD_BACKLIGHT; - }; - -- chan1 { -+ led@1 { -+ reg = <1>; - chan-name = "lp5523:kb2"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_KBD_BACKLIGHT; - }; - -- chan2 { -+ led@2 { -+ reg = <2>; - chan-name = "lp5523:kb3"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_KBD_BACKLIGHT; - }; - -- chan3 { -+ led@3 { -+ reg = <3>; - chan-name = "lp5523:kb4"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_KBD_BACKLIGHT; - }; - -- chan4 { -+ led@4 { -+ reg = <4>; - chan-name = "lp5523:b"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_STATUS; - }; - -- chan5 { -+ led@5 { -+ reg = <5>; - chan-name = "lp5523:g"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_STATUS; - }; - -- chan6 { -+ led@6 { -+ reg = <6>; - chan-name = "lp5523:r"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_STATUS; - }; - -- chan7 { -+ led@7 { -+ reg = <7>; - chan-name = "lp5523:kb5"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_KBD_BACKLIGHT; - }; - -- chan8 { -+ led@8 { -+ reg = <8>; - chan-name = "lp5523:kb6"; - led-cur = /bits/ 8 <50>; - max-cur = /bits/ 8 <100>; -+ color = ; -+ function = LED_FUNCTION_KBD_BACKLIGHT; - }; - }; - -diff --git a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi -index e5da3bc6f1050..218a10c0d8159 100644 ---- a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi -+++ b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi -@@ -22,7 +22,7 @@ - compatible = "smsc,lan9221","smsc,lan9115"; - bank-width = <2>; - -- gpmc,mux-add-data; -+ gpmc,mux-add-data = <0>; - gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <42>; - gpmc,cs-wr-off-ns = <36>; -diff --git a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts -index f7ea2e5dd1914..971d2e2292600 100644 ---- a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts -@@ -19,12 +19,12 @@ - stdout-path = "serial0:115200n8"; - }; - -- memory@0 { -+ memory@42000000 { - reg = <0x42000000 0x3e000000>; - device_type = "memory"; - }; - -- mdio0: mdio@0 { -+ mdio0: mdio-0 { - status = "okay"; - compatible = "virtual,mdio-gpio"; - gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH>, -@@ -91,7 +91,7 @@ - }; - }; - -- mdio1: mdio@1 { -+ mdio1: mdio-1 { - status = "okay"; - compatible = "virtual,mdio-gpio"; - gpios = <&qcom_pinmux 11 GPIO_ACTIVE_HIGH>, -diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi -index 78ec496d5bc30..2b01bc29ddf23 100644 ---- a/arch/arm/boot/dts/qcom-msm8974.dtsi -+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi -@@ -1589,8 +1589,8 @@ - #phy-cells = <0>; - qcom,dsi-phy-index = <0>; - -- clocks = <&mmcc MDSS_AHB_CLK>; -- clock-names = "iface"; -+ clocks = <&mmcc MDSS_AHB_CLK>, <&xo_board>; -+ clock-names = "iface", "ref"; - }; - }; - -diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi -index 1e6ce035f76a9..b5b784c5c65e4 100644 ---- a/arch/arm/boot/dts/qcom-sdx55.dtsi -+++ b/arch/arm/boot/dts/qcom-sdx55.dtsi -@@ -334,12 +334,10 @@ - clocks = <&rpmhcc RPMH_IPA_CLK>; - clock-names = "core"; - -- interconnects = <&system_noc MASTER_IPA &system_noc SLAVE_SNOC_MEM_NOC_GC>, -- <&mem_noc MASTER_SNOC_GC_MEM_NOC &mc_virt SLAVE_EBI_CH0>, -+ interconnects = <&system_noc MASTER_IPA &mc_virt SLAVE_EBI_CH0>, - <&system_noc MASTER_IPA &system_noc SLAVE_OCIMEM>, - <&mem_noc MASTER_AMPSS_M0 &system_noc SLAVE_IPA_CFG>; -- interconnect-names = "memory-a", -- "memory-b", -+ interconnect-names = "memory", - "imem", - "config"; - -diff --git a/arch/arm/boot/dts/sama7g5-pinfunc.h b/arch/arm/boot/dts/sama7g5-pinfunc.h -index 22fe9e522a97b..4eb30445d2057 100644 ---- a/arch/arm/boot/dts/sama7g5-pinfunc.h -+++ b/arch/arm/boot/dts/sama7g5-pinfunc.h -@@ -765,7 +765,7 @@ - #define PIN_PD20__PCK0 PINMUX_PIN(PIN_PD20, 1, 3) - #define PIN_PD20__FLEXCOM2_IO3 PINMUX_PIN(PIN_PD20, 2, 2) - #define PIN_PD20__PWMH3 PINMUX_PIN(PIN_PD20, 3, 4) --#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 5, 2) -+#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 4, 2) - #define PIN_PD20__FLEXCOM5_IO0 PINMUX_PIN(PIN_PD20, 6, 5) - #define PIN_PD21 117 - #define PIN_PD21__GPIO PINMUX_PIN(PIN_PD21, 0, 0) -diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts b/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts -index 2b645642b9352..2a745522404d6 100644 ---- a/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts -+++ b/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts -@@ -12,7 +12,7 @@ - flash0: n25q00@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q00aa"; -+ compatible = "micron,mt25qu02g", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <100000000>; - -diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts -index 90e676e7019f2..1b02d46496a85 100644 ---- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts -+++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts -@@ -119,7 +119,7 @@ - flash: flash@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q256a"; -+ compatible = "micron,n25q256a", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <100000000>; - -diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts -index 6f138b2b26163..51bb436784e24 100644 ---- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts -+++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts -@@ -124,7 +124,7 @@ - flash0: n25q00@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q00"; -+ compatible = "micron,mt25qu02g", "jedec,spi-nor"; - reg = <0>; /* chip select */ - spi-max-frequency = <100000000>; - -diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts -index c155ff02eb6e0..cae9ddd5ed38b 100644 ---- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts -+++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts -@@ -169,7 +169,7 @@ - flash: flash@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q00"; -+ compatible = "micron,mt25qu02g", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <100000000>; - -diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts -index 8d5d3996f6f27..ca18b959e6559 100644 ---- a/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts -+++ b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts -@@ -80,7 +80,7 @@ - flash: flash@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q256a"; -+ compatible = "micron,n25q256a", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <100000000>; - m25p,fast-read; -diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts -index 99a71757cdf46..3f7aa7bf0863a 100644 ---- a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts -+++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts -@@ -116,7 +116,7 @@ - flash0: n25q512a@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q512a"; -+ compatible = "micron,n25q512a", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <100000000>; - -diff --git a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts -index a060718758b67..25874e1b9c829 100644 ---- a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts -+++ b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts -@@ -224,7 +224,7 @@ - n25q128@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q128"; -+ compatible = "micron,n25q128", "jedec,spi-nor"; - reg = <0>; /* chip select */ - spi-max-frequency = <100000000>; - m25p,fast-read; -@@ -241,7 +241,7 @@ - n25q00@1 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "n25q00"; -+ compatible = "micron,mt25qu02g", "jedec,spi-nor"; - reg = <1>; /* chip select */ - spi-max-frequency = <100000000>; - m25p,fast-read; -diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts -index 264f3e9b5fce5..7fab746e0570e 100644 ---- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts -+++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts -@@ -181,10 +181,6 @@ - cap-sd-highspeed; - cap-mmc-highspeed; - /* All direction control is used */ -- st,sig-dir-cmd; -- st,sig-dir-dat0; -- st,sig-dir-dat2; -- st,sig-dir-dat31; - st,sig-pin-fbclk; - full-pwr-cycle; - vmmc-supply = <&ab8500_ldo_aux3_reg>; -@@ -292,10 +288,10 @@ - }; - - ab8500_ldo_aux2 { -- /* Supplies the Cypress TMA140 touchscreen only with 3.3V */ -+ /* Supplies the Cypress TMA140 touchscreen only with 3.0V */ - regulator-name = "AUX2"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; - }; - - ab8500_ldo_aux3 { -@@ -314,9 +310,9 @@ - - ab8500_ldo_aux5 { - regulator-name = "AUX5"; -+ /* Intended for 1V8 for touchscreen but actually left unused */ - regulator-min-microvolt = <1050000>; - regulator-max-microvolt = <2790000>; -- regulator-always-on; - }; - - ab8500_ldo_aux6 { -diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts -index 075ac57d0bf4a..6435e099c6326 100644 ---- a/arch/arm/boot/dts/stm32f429-disco.dts -+++ b/arch/arm/boot/dts/stm32f429-disco.dts -@@ -192,7 +192,7 @@ - - display: display@1{ - /* Connect panel-ilitek-9341 to ltdc */ -- compatible = "st,sf-tc240t-9370-t"; -+ compatible = "st,sf-tc240t-9370-t", "ilitek,ili9341"; - reg = <1>; - spi-3wire; - spi-max-frequency = <10000000>; -diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -index 5b60ecbd718f0..2ebafe27a865b 100644 ---- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -@@ -1179,7 +1179,7 @@ - }; - }; - -- sai2a_pins_c: sai2a-4 { -+ sai2a_pins_c: sai2a-2 { - pins { - pinmux = , /* SAI2_SCK_A */ - , /* SAI2_SD_A */ -@@ -1190,7 +1190,7 @@ - }; - }; - -- sai2a_sleep_pins_c: sai2a-5 { -+ sai2a_sleep_pins_c: sai2a-2 { - pins { - pinmux = , /* SAI2_SCK_A */ - , /* SAI2_SD_A */ -@@ -1235,14 +1235,14 @@ - }; - }; - -- sai2b_pins_c: sai2a-4 { -+ sai2b_pins_c: sai2b-2 { - pins1 { - pinmux = ; /* SAI2_SD_B */ - bias-disable; - }; - }; - -- sai2b_sleep_pins_c: sai2a-sleep-5 { -+ sai2b_sleep_pins_c: sai2b-sleep-2 { - pins { - pinmux = ; /* SAI2_SD_B */ - }; -diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi -index bd289bf5d2690..6992a4b0ba79b 100644 ---- a/arch/arm/boot/dts/stm32mp151.dtsi -+++ b/arch/arm/boot/dts/stm32mp151.dtsi -@@ -824,7 +824,7 @@ - #sound-dai-cells = <0>; - - compatible = "st,stm32-sai-sub-a"; -- reg = <0x4 0x1c>; -+ reg = <0x4 0x20>; - clocks = <&rcc SAI1_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 87 0x400 0x01>; -@@ -834,7 +834,7 @@ - sai1b: audio-controller@4400a024 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; -- reg = <0x24 0x1c>; -+ reg = <0x24 0x20>; - clocks = <&rcc SAI1_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 88 0x400 0x01>; -@@ -855,7 +855,7 @@ - sai2a: audio-controller@4400b004 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-a"; -- reg = <0x4 0x1c>; -+ reg = <0x4 0x20>; - clocks = <&rcc SAI2_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 89 0x400 0x01>; -@@ -865,7 +865,7 @@ - sai2b: audio-controller@4400b024 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; -- reg = <0x24 0x1c>; -+ reg = <0x24 0x20>; - clocks = <&rcc SAI2_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 90 0x400 0x01>; -@@ -886,7 +886,7 @@ - sai3a: audio-controller@4400c004 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-a"; -- reg = <0x04 0x1c>; -+ reg = <0x04 0x20>; - clocks = <&rcc SAI3_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 113 0x400 0x01>; -@@ -896,7 +896,7 @@ - sai3b: audio-controller@4400c024 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; -- reg = <0x24 0x1c>; -+ reg = <0x24 0x20>; - clocks = <&rcc SAI3_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 114 0x400 0x01>; -@@ -1271,7 +1271,7 @@ - sai4a: audio-controller@50027004 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-a"; -- reg = <0x04 0x1c>; -+ reg = <0x04 0x20>; - clocks = <&rcc SAI4_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 99 0x400 0x01>; -@@ -1281,7 +1281,7 @@ - sai4b: audio-controller@50027024 { - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; -- reg = <0x24 0x1c>; -+ reg = <0x24 0x20>; - clocks = <&rcc SAI4_K>; - clock-names = "sai_ck"; - dmas = <&dmamux1 100 0x400 0x01>; -diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi -index 2b0ac605549d7..44ecc47085871 100644 ---- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi -+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi -@@ -202,7 +202,7 @@ - compatible = "jedec,spi-nor"; - reg = <0>; - spi-rx-bus-width = <4>; -- spi-max-frequency = <108000000>; -+ spi-max-frequency = <50000000>; - #address-cells = <1>; - #size-cells = <1>; - }; -diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi -index 899bfe04aeb91..48beed0f1f30a 100644 ---- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi -+++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi -@@ -249,7 +249,7 @@ - stusb1600@28 { - compatible = "st,stusb1600"; - reg = <0x28>; -- interrupts = <11 IRQ_TYPE_EDGE_FALLING>; -+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; - interrupt-parent = <&gpioi>; - pinctrl-names = "default"; - pinctrl-0 = <&stusb1600_pins_a>; -diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi -index 2beddbb3c5183..b3d1bdfb5118e 100644 ---- a/arch/arm/boot/dts/sun8i-a33.dtsi -+++ b/arch/arm/boot/dts/sun8i-a33.dtsi -@@ -46,7 +46,7 @@ - #include - - / { -- cpu0_opp_table: opp_table0 { -+ cpu0_opp_table: opp-table-cpu { - compatible = "operating-points-v2"; - opp-shared; - -@@ -164,7 +164,7 @@ - io-channels = <&ths>; - }; - -- mali_opp_table: gpu-opp-table { -+ mali_opp_table: opp-table-gpu { - compatible = "operating-points-v2"; - - opp-144000000 { -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index ac97eac91349b..82fdb04122caa 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -200,7 +200,7 @@ - status = "disabled"; - }; - -- cpu0_opp_table: opp_table0 { -+ cpu0_opp_table: opp-table-cluster0 { - compatible = "operating-points-v2"; - opp-shared; - -@@ -253,7 +253,7 @@ - }; - }; - -- cpu1_opp_table: opp_table1 { -+ cpu1_opp_table: opp-table-cluster1 { - compatible = "operating-points-v2"; - opp-shared; - -diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi -index 4e89701df91f8..ae4f933abb895 100644 ---- a/arch/arm/boot/dts/sun8i-h3.dtsi -+++ b/arch/arm/boot/dts/sun8i-h3.dtsi -@@ -44,7 +44,7 @@ - #include - - / { -- cpu0_opp_table: opp_table0 { -+ cpu0_opp_table: opp-table-cpu { - compatible = "operating-points-v2"; - opp-shared; - -@@ -112,7 +112,7 @@ - }; - }; - -- gpu_opp_table: gpu-opp-table { -+ gpu_opp_table: opp-table-gpu { - compatible = "operating-points-v2"; - - opp-120000000 { -diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts -index 1d2aac2cb6d03..fdc1d64dfff9d 100644 ---- a/arch/arm/boot/dts/tegra124-nyan-big.dts -+++ b/arch/arm/boot/dts/tegra124-nyan-big.dts -@@ -13,12 +13,15 @@ - "google,nyan-big-rev1", "google,nyan-big-rev0", - "google,nyan-big", "google,nyan", "nvidia,tegra124"; - -- panel: panel { -- compatible = "auo,b133xtn01"; -- -- power-supply = <&vdd_3v3_panel>; -- backlight = <&backlight>; -- ddc-i2c-bus = <&dpaux>; -+ host1x@50000000 { -+ dpaux@545c0000 { -+ aux-bus { -+ panel: panel { -+ compatible = "auo,b133xtn01"; -+ backlight = <&backlight>; -+ }; -+ }; -+ }; - }; - - mmc@700b0400 { /* SD Card on this bus */ -diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze.dts b/arch/arm/boot/dts/tegra124-nyan-blaze.dts -index 677babde6460e..abdf4456826f8 100644 ---- a/arch/arm/boot/dts/tegra124-nyan-blaze.dts -+++ b/arch/arm/boot/dts/tegra124-nyan-blaze.dts -@@ -15,12 +15,15 @@ - "google,nyan-blaze-rev0", "google,nyan-blaze", - "google,nyan", "nvidia,tegra124"; - -- panel: panel { -- compatible = "samsung,ltn140at29-301"; -- -- power-supply = <&vdd_3v3_panel>; -- backlight = <&backlight>; -- ddc-i2c-bus = <&dpaux>; -+ host1x@50000000 { -+ dpaux@545c0000 { -+ aux-bus { -+ panel: panel { -+ compatible = "samsung,ltn140at29-301"; -+ backlight = <&backlight>; -+ }; -+ }; -+ }; - }; - - sound { -diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts -index e6b54ac1ebd1a..84e2d24065e9a 100644 ---- a/arch/arm/boot/dts/tegra124-venice2.dts -+++ b/arch/arm/boot/dts/tegra124-venice2.dts -@@ -48,6 +48,13 @@ - dpaux@545c0000 { - vdd-supply = <&vdd_3v3_panel>; - status = "okay"; -+ -+ aux-bus { -+ panel: panel { -+ compatible = "lg,lp129qe"; -+ backlight = <&backlight>; -+ }; -+ }; - }; - }; - -@@ -1079,13 +1086,6 @@ - }; - }; - -- panel: panel { -- compatible = "lg,lp129qe"; -- power-supply = <&vdd_3v3_panel>; -- backlight = <&backlight>; -- ddc-i2c-bus = <&dpaux>; -- }; -- - vdd_mux: regulator@0 { - compatible = "regulator-fixed"; - regulator-name = "+VDD_MUX"; -diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig -index 502a9d870ca44..45769d0ddd4ef 100644 ---- a/arch/arm/configs/cm_x300_defconfig -+++ b/arch/arm/configs/cm_x300_defconfig -@@ -146,7 +146,6 @@ CONFIG_NFS_V3_ACL=y - CONFIG_NFS_V4=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_NLS_CODEPAGE_437=m - CONFIG_NLS_ISO8859_1=m -diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig -index a49e699e52de3..ec84d80096b1c 100644 ---- a/arch/arm/configs/ezx_defconfig -+++ b/arch/arm/configs/ezx_defconfig -@@ -314,7 +314,6 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_SMB_FS=m - CONFIG_CIFS=m - CONFIG_CIFS_STATS=y --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig -index 118c4c927f264..6db871d4e0775 100644 ---- a/arch/arm/configs/imote2_defconfig -+++ b/arch/arm/configs/imote2_defconfig -@@ -288,7 +288,6 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_SMB_FS=m - CONFIG_CIFS=m - CONFIG_CIFS_STATS=y --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig -index 23595fc5a29a9..907d6512821ad 100644 ---- a/arch/arm/configs/nhk8815_defconfig -+++ b/arch/arm/configs/nhk8815_defconfig -@@ -127,7 +127,6 @@ CONFIG_NFS_FS=y - CONFIG_NFS_V3_ACL=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_NLS_CODEPAGE_437=y - CONFIG_NLS_ASCII=y - CONFIG_NLS_ISO8859_1=y -diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig -index 58f4834289e63..dedaaae3d0d8a 100644 ---- a/arch/arm/configs/pxa_defconfig -+++ b/arch/arm/configs/pxa_defconfig -@@ -699,7 +699,6 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m - CONFIG_CIFS_STATS=y --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_DEFAULT="utf8" -diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig -index 3b206a31902ff..065553326b391 100644 ---- a/arch/arm/configs/spear13xx_defconfig -+++ b/arch/arm/configs/spear13xx_defconfig -@@ -61,7 +61,6 @@ CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - # CONFIG_HW_RANDOM is not set - CONFIG_RAW_DRIVER=y --CONFIG_MAX_RAW_DEVS=8192 - CONFIG_I2C=y - CONFIG_I2C_DESIGNWARE_PLATFORM=y - CONFIG_SPI=y -diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig -index fc5f71c765edc..afca722d6605c 100644 ---- a/arch/arm/configs/spear3xx_defconfig -+++ b/arch/arm/configs/spear3xx_defconfig -@@ -41,7 +41,6 @@ CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - # CONFIG_HW_RANDOM is not set - CONFIG_RAW_DRIVER=y --CONFIG_MAX_RAW_DEVS=8192 - CONFIG_I2C=y - CONFIG_I2C_DESIGNWARE_PLATFORM=y - CONFIG_SPI=y -diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig -index 52a56b8ce6a71..bc32c02cb86b1 100644 ---- a/arch/arm/configs/spear6xx_defconfig -+++ b/arch/arm/configs/spear6xx_defconfig -@@ -36,7 +36,6 @@ CONFIG_INPUT_FF_MEMLESS=y - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_RAW_DRIVER=y --CONFIG_MAX_RAW_DEVS=8192 - CONFIG_I2C=y - CONFIG_I2C_DESIGNWARE_PLATFORM=y - CONFIG_SPI=y -diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h -index e2b1fd558bf3c..09c241280ed9c 100644 ---- a/arch/arm/include/asm/assembler.h -+++ b/arch/arm/include/asm/assembler.h -@@ -107,6 +107,16 @@ - .endm - #endif - -+#if __LINUX_ARM_ARCH__ < 7 -+ .macro dsb, args -+ mcr p15, 0, r0, c7, c10, 4 -+ .endm -+ -+ .macro isb, args -+ mcr p15, 0, r0, c7, c5, 4 -+ .endm -+#endif -+ - .macro asm_trace_hardirqs_off, save=1 - #if defined(CONFIG_TRACE_IRQFLAGS) - .if \save -@@ -259,6 +269,7 @@ - */ - #define ALT_UP(instr...) \ - .pushsection ".alt.smp.init", "a" ;\ -+ .align 2 ;\ - .long 9998b - . ;\ - 9997: instr ;\ - .if . - 9997b == 2 ;\ -@@ -270,6 +281,7 @@ - .popsection - #define ALT_UP_B(label) \ - .pushsection ".alt.smp.init", "a" ;\ -+ .align 2 ;\ - .long 9998b - . ;\ - W(b) . + (label - 9998b) ;\ - .popsection -diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h -index a6f3b179e8a94..27218eabbf9a0 100644 ---- a/arch/arm/include/asm/efi.h -+++ b/arch/arm/include/asm/efi.h -@@ -17,7 +17,6 @@ - - #ifdef CONFIG_EFI - void efi_init(void); --extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt); - - int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); - int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); -diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h -index 9e6b972863077..8aeff55aebfaf 100644 ---- a/arch/arm/include/asm/processor.h -+++ b/arch/arm/include/asm/processor.h -@@ -96,6 +96,7 @@ unsigned long get_wchan(struct task_struct *p); - #define __ALT_SMP_ASM(smp, up) \ - "9998: " smp "\n" \ - " .pushsection \".alt.smp.init\", \"a\"\n" \ -+ " .align 2\n" \ - " .long 9998b - .\n" \ - " " up "\n" \ - " .popsection\n" -diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h -new file mode 100644 -index 0000000000000..d1fa5607d3aa3 ---- /dev/null -+++ b/arch/arm/include/asm/spectre.h -@@ -0,0 +1,32 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#ifndef __ASM_SPECTRE_H -+#define __ASM_SPECTRE_H -+ -+enum { -+ SPECTRE_UNAFFECTED, -+ SPECTRE_MITIGATED, -+ SPECTRE_VULNERABLE, -+}; -+ -+enum { -+ __SPECTRE_V2_METHOD_BPIALL, -+ __SPECTRE_V2_METHOD_ICIALLU, -+ __SPECTRE_V2_METHOD_SMC, -+ __SPECTRE_V2_METHOD_HVC, -+ __SPECTRE_V2_METHOD_LOOP8, -+}; -+ -+enum { -+ SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL), -+ SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU), -+ SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC), -+ SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC), -+ SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8), -+}; -+ -+void spectre_v2_update_state(unsigned int state, unsigned int methods); -+ -+int spectre_bhb_update_vectors(unsigned int method); -+ -+#endif -diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h -index 36fbc33292526..32dbfd81f42a4 100644 ---- a/arch/arm/include/asm/uaccess.h -+++ b/arch/arm/include/asm/uaccess.h -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -497,7 +498,10 @@ do { \ - } \ - default: __err = __get_user_bad(); break; \ - } \ -- *(type *)(dst) = __val; \ -+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) \ -+ put_unaligned(__val, (type *)(dst)); \ -+ else \ -+ *(type *)(dst) = __val; /* aligned by caller */ \ - if (__err) \ - goto err_label; \ - } while (0) -@@ -507,7 +511,9 @@ do { \ - const type *__pk_ptr = (dst); \ - unsigned long __dst = (unsigned long)__pk_ptr; \ - int __err = 0; \ -- type __val = *(type *)src; \ -+ type __val = IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \ -+ ? get_unaligned((type *)(src)) \ -+ : *(type *)(src); /* aligned by caller */ \ - switch (sizeof(type)) { \ - case 1: __put_user_asm_byte(__val, __dst, __err, ""); break; \ - case 2: __put_user_asm_half(__val, __dst, __err, ""); break; \ -diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h -index 4a91428c324db..fad45c884e988 100644 ---- a/arch/arm/include/asm/vmlinux.lds.h -+++ b/arch/arm/include/asm/vmlinux.lds.h -@@ -26,6 +26,19 @@ - #define ARM_MMU_DISCARD(x) x - #endif - -+/* -+ * ld.lld does not support NOCROSSREFS: -+ * https://github.com/ClangBuiltLinux/linux/issues/1609 -+ */ -+#ifdef CONFIG_LD_IS_LLD -+#define NOCROSSREFS -+#endif -+ -+/* Set start/end symbol names to the LMA for the section */ -+#define ARM_LMA(sym, section) \ -+ sym##_start = LOADADDR(section); \ -+ sym##_end = LOADADDR(section) + SIZEOF(section) -+ - #define PROC_INFO \ - . = ALIGN(4); \ - __proc_info_begin = .; \ -@@ -110,19 +123,31 @@ - * only thing that matters is their relative offsets - */ - #define ARM_VECTORS \ -- __vectors_start = .; \ -- .vectors 0xffff0000 : AT(__vectors_start) { \ -- *(.vectors) \ -+ __vectors_lma = .; \ -+ OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \ -+ .vectors { \ -+ *(.vectors) \ -+ } \ -+ .vectors.bhb.loop8 { \ -+ *(.vectors.bhb.loop8) \ -+ } \ -+ .vectors.bhb.bpiall { \ -+ *(.vectors.bhb.bpiall) \ -+ } \ - } \ -- . = __vectors_start + SIZEOF(.vectors); \ -- __vectors_end = .; \ -+ ARM_LMA(__vectors, .vectors); \ -+ ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8); \ -+ ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall); \ -+ . = __vectors_lma + SIZEOF(.vectors) + \ -+ SIZEOF(.vectors.bhb.loop8) + \ -+ SIZEOF(.vectors.bhb.bpiall); \ - \ -- __stubs_start = .; \ -- .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { \ -+ __stubs_lma = .; \ -+ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \ - *(.stubs) \ - } \ -- . = __stubs_start + SIZEOF(.stubs); \ -- __stubs_end = .; \ -+ ARM_LMA(__stubs, .stubs); \ -+ . = __stubs_lma + SIZEOF(.stubs); \ - \ - PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors)); - -diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h -index c8eb83d4b8964..3edbb3c5b42bf 100644 ---- a/arch/arm/include/debug/imx-uart.h -+++ b/arch/arm/include/debug/imx-uart.h -@@ -11,13 +11,6 @@ - #define IMX1_UART_BASE_ADDR(n) IMX1_UART##n##_BASE_ADDR - #define IMX1_UART_BASE(n) IMX1_UART_BASE_ADDR(n) - --#define IMX21_UART1_BASE_ADDR 0x1000a000 --#define IMX21_UART2_BASE_ADDR 0x1000b000 --#define IMX21_UART3_BASE_ADDR 0x1000c000 --#define IMX21_UART4_BASE_ADDR 0x1000d000 --#define IMX21_UART_BASE_ADDR(n) IMX21_UART##n##_BASE_ADDR --#define IMX21_UART_BASE(n) IMX21_UART_BASE_ADDR(n) -- - #define IMX25_UART1_BASE_ADDR 0x43f90000 - #define IMX25_UART2_BASE_ADDR 0x43f94000 - #define IMX25_UART3_BASE_ADDR 0x5000c000 -@@ -26,6 +19,13 @@ - #define IMX25_UART_BASE_ADDR(n) IMX25_UART##n##_BASE_ADDR - #define IMX25_UART_BASE(n) IMX25_UART_BASE_ADDR(n) - -+#define IMX27_UART1_BASE_ADDR 0x1000a000 -+#define IMX27_UART2_BASE_ADDR 0x1000b000 -+#define IMX27_UART3_BASE_ADDR 0x1000c000 -+#define IMX27_UART4_BASE_ADDR 0x1000d000 -+#define IMX27_UART_BASE_ADDR(n) IMX27_UART##n##_BASE_ADDR -+#define IMX27_UART_BASE(n) IMX27_UART_BASE_ADDR(n) -+ - #define IMX31_UART1_BASE_ADDR 0x43f90000 - #define IMX31_UART2_BASE_ADDR 0x43f94000 - #define IMX31_UART3_BASE_ADDR 0x5000c000 -@@ -112,10 +112,10 @@ - - #ifdef CONFIG_DEBUG_IMX1_UART - #define UART_PADDR IMX_DEBUG_UART_BASE(IMX1) --#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART) --#define UART_PADDR IMX_DEBUG_UART_BASE(IMX21) - #elif defined(CONFIG_DEBUG_IMX25_UART) - #define UART_PADDR IMX_DEBUG_UART_BASE(IMX25) -+#elif defined(CONFIG_DEBUG_IMX27_UART) -+#define UART_PADDR IMX_DEBUG_UART_BASE(IMX27) - #elif defined(CONFIG_DEBUG_IMX31_UART) - #define UART_PADDR IMX_DEBUG_UART_BASE(IMX31) - #elif defined(CONFIG_DEBUG_IMX35_UART) -diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile -index ae295a3bcfefd..6ef3b535b7bf7 100644 ---- a/arch/arm/kernel/Makefile -+++ b/arch/arm/kernel/Makefile -@@ -106,4 +106,6 @@ endif - - obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o - -+obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o -+ - extra-y := $(head-y) vmlinux.lds -diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S -index 241b73d64df73..a0654ab1074f9 100644 ---- a/arch/arm/kernel/entry-armv.S -+++ b/arch/arm/kernel/entry-armv.S -@@ -597,11 +597,9 @@ call_fpe: - tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2 - reteq lr - and r8, r0, #0x00000f00 @ mask out CP number -- THUMB( lsr r8, r8, #8 ) - mov r7, #1 -- add r6, r10, #TI_USED_CP -- ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[] -- THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[] -+ add r6, r10, r8, lsr #8 @ add used_cp[] array offset first -+ strb r7, [r6, #TI_USED_CP] @ set appropriate used_cp[] - #ifdef CONFIG_IWMMXT - @ Test if we need to give access to iWMMXt coprocessors - ldr r5, [r10, #TI_FLAGS] -@@ -610,7 +608,7 @@ call_fpe: - bcs iwmmxt_task_enable - #endif - ARM( add pc, pc, r8, lsr #6 ) -- THUMB( lsl r8, r8, #2 ) -+ THUMB( lsr r8, r8, #6 ) - THUMB( add pc, r8 ) - nop - -@@ -1002,12 +1000,11 @@ vector_\name: - sub lr, lr, #\correction - .endif - -- @ -- @ Save r0, lr_ (parent PC) and spsr_ -- @ (parent CPSR) -- @ -+ @ Save r0, lr_ (parent PC) - stmia sp, {r0, lr} @ save r0, lr -- mrs lr, spsr -+ -+ @ Save spsr_ (parent CPSR) -+2: mrs lr, spsr - str lr, [sp, #8] @ save spsr - - @ -@@ -1028,6 +1025,44 @@ vector_\name: - movs pc, lr @ branch to handler in SVC mode - ENDPROC(vector_\name) - -+#ifdef CONFIG_HARDEN_BRANCH_HISTORY -+ .subsection 1 -+ .align 5 -+vector_bhb_loop8_\name: -+ .if \correction -+ sub lr, lr, #\correction -+ .endif -+ -+ @ Save r0, lr_ (parent PC) -+ stmia sp, {r0, lr} -+ -+ @ bhb workaround -+ mov r0, #8 -+1: b . + 4 -+ subs r0, r0, #1 -+ bne 1b -+ dsb -+ isb -+ b 2b -+ENDPROC(vector_bhb_loop8_\name) -+ -+vector_bhb_bpiall_\name: -+ .if \correction -+ sub lr, lr, #\correction -+ .endif -+ -+ @ Save r0, lr_ (parent PC) -+ stmia sp, {r0, lr} -+ -+ @ bhb workaround -+ mcr p15, 0, r0, c7, c5, 6 @ BPIALL -+ @ isb not needed due to "movs pc, lr" in the vector stub -+ @ which gives a "context synchronisation". -+ b 2b -+ENDPROC(vector_bhb_bpiall_\name) -+ .previous -+#endif -+ - .align 2 - @ handler addresses follow this label - 1: -@@ -1036,6 +1071,10 @@ ENDPROC(vector_\name) - .section .stubs, "ax", %progbits - @ This must be the first word - .word vector_swi -+#ifdef CONFIG_HARDEN_BRANCH_HISTORY -+ .word vector_bhb_loop8_swi -+ .word vector_bhb_bpiall_swi -+#endif - - vector_rst: - ARM( swi SYS_ERROR0 ) -@@ -1150,8 +1189,10 @@ vector_addrexcptn: - * FIQ "NMI" handler - *----------------------------------------------------------------------------- - * Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86 -- * systems. -+ * systems. This must be the last vector stub, so lets place it in its own -+ * subsection. - */ -+ .subsection 2 - vector_stub fiq, FIQ_MODE, 4 - - .long __fiq_usr @ 0 (USR_26 / USR_32) -@@ -1184,6 +1225,30 @@ vector_addrexcptn: - W(b) vector_irq - W(b) vector_fiq - -+#ifdef CONFIG_HARDEN_BRANCH_HISTORY -+ .section .vectors.bhb.loop8, "ax", %progbits -+.L__vectors_bhb_loop8_start: -+ W(b) vector_rst -+ W(b) vector_bhb_loop8_und -+ W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004 -+ W(b) vector_bhb_loop8_pabt -+ W(b) vector_bhb_loop8_dabt -+ W(b) vector_addrexcptn -+ W(b) vector_bhb_loop8_irq -+ W(b) vector_bhb_loop8_fiq -+ -+ .section .vectors.bhb.bpiall, "ax", %progbits -+.L__vectors_bhb_bpiall_start: -+ W(b) vector_rst -+ W(b) vector_bhb_bpiall_und -+ W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008 -+ W(b) vector_bhb_bpiall_pabt -+ W(b) vector_bhb_bpiall_dabt -+ W(b) vector_addrexcptn -+ W(b) vector_bhb_bpiall_irq -+ W(b) vector_bhb_bpiall_fiq -+#endif -+ - .data - .align 2 - -diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S -index d9c99db50243f..fde7ac271b147 100644 ---- a/arch/arm/kernel/entry-common.S -+++ b/arch/arm/kernel/entry-common.S -@@ -153,6 +153,29 @@ ENDPROC(ret_from_fork) - *----------------------------------------------------------------------------- - */ - -+ .align 5 -+#ifdef CONFIG_HARDEN_BRANCH_HISTORY -+ENTRY(vector_bhb_loop8_swi) -+ sub sp, sp, #PT_REGS_SIZE -+ stmia sp, {r0 - r12} -+ mov r8, #8 -+1: b 2f -+2: subs r8, r8, #1 -+ bne 1b -+ dsb -+ isb -+ b 3f -+ENDPROC(vector_bhb_loop8_swi) -+ -+ .align 5 -+ENTRY(vector_bhb_bpiall_swi) -+ sub sp, sp, #PT_REGS_SIZE -+ stmia sp, {r0 - r12} -+ mcr p15, 0, r8, c7, c5, 6 @ BPIALL -+ isb -+ b 3f -+ENDPROC(vector_bhb_bpiall_swi) -+#endif - .align 5 - ENTRY(vector_swi) - #ifdef CONFIG_CPU_V7M -@@ -160,6 +183,7 @@ ENTRY(vector_swi) - #else - sub sp, sp, #PT_REGS_SIZE - stmia sp, {r0 - r12} @ Calling r0 - r12 -+3: - ARM( add r8, sp, #S_PC ) - ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr - THUMB( mov r8, sp ) -diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S -index 0fc814bbc34b1..8796a69c78e00 100644 ---- a/arch/arm/kernel/head-nommu.S -+++ b/arch/arm/kernel/head-nommu.S -@@ -114,6 +114,7 @@ ENTRY(secondary_startup) - add r12, r12, r10 - ret r12 - 1: bl __after_proc_init -+ ldr r7, __secondary_data @ reload r7 - ldr sp, [r7, #12] @ set up the stack pointer - mov fp, #0 - b secondary_start_kernel -diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c -index 7bd30c0a4280d..22f937e6f3ffb 100644 ---- a/arch/arm/kernel/kgdb.c -+++ b/arch/arm/kernel/kgdb.c -@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr) - return 0; - } - --static struct undef_hook kgdb_brkpt_hook = { -+static struct undef_hook kgdb_brkpt_arm_hook = { - .instr_mask = 0xffffffff, - .instr_val = KGDB_BREAKINST, -- .cpsr_mask = MODE_MASK, -+ .cpsr_mask = PSR_T_BIT | MODE_MASK, - .cpsr_val = SVC_MODE, - .fn = kgdb_brk_fn - }; - --static struct undef_hook kgdb_compiled_brkpt_hook = { -+static struct undef_hook kgdb_brkpt_thumb_hook = { -+ .instr_mask = 0xffff, -+ .instr_val = KGDB_BREAKINST & 0xffff, -+ .cpsr_mask = PSR_T_BIT | MODE_MASK, -+ .cpsr_val = PSR_T_BIT | SVC_MODE, -+ .fn = kgdb_brk_fn -+}; -+ -+static struct undef_hook kgdb_compiled_brkpt_arm_hook = { - .instr_mask = 0xffffffff, - .instr_val = KGDB_COMPILED_BREAK, -- .cpsr_mask = MODE_MASK, -+ .cpsr_mask = PSR_T_BIT | MODE_MASK, - .cpsr_val = SVC_MODE, - .fn = kgdb_compiled_brk_fn - }; - -+static struct undef_hook kgdb_compiled_brkpt_thumb_hook = { -+ .instr_mask = 0xffff, -+ .instr_val = KGDB_COMPILED_BREAK & 0xffff, -+ .cpsr_mask = PSR_T_BIT | MODE_MASK, -+ .cpsr_val = PSR_T_BIT | SVC_MODE, -+ .fn = kgdb_compiled_brk_fn -+}; -+ - static int __kgdb_notify(struct die_args *args, unsigned long cmd) - { - struct pt_regs *regs = args->regs; -@@ -210,8 +226,10 @@ int kgdb_arch_init(void) - if (ret != 0) - return ret; - -- register_undef_hook(&kgdb_brkpt_hook); -- register_undef_hook(&kgdb_compiled_brkpt_hook); -+ register_undef_hook(&kgdb_brkpt_arm_hook); -+ register_undef_hook(&kgdb_brkpt_thumb_hook); -+ register_undef_hook(&kgdb_compiled_brkpt_arm_hook); -+ register_undef_hook(&kgdb_compiled_brkpt_thumb_hook); - - return 0; - } -@@ -224,8 +242,10 @@ int kgdb_arch_init(void) - */ - void kgdb_arch_exit(void) - { -- unregister_undef_hook(&kgdb_brkpt_hook); -- unregister_undef_hook(&kgdb_compiled_brkpt_hook); -+ unregister_undef_hook(&kgdb_brkpt_arm_hook); -+ unregister_undef_hook(&kgdb_brkpt_thumb_hook); -+ unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook); -+ unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook); - unregister_die_notifier(&kgdb_notifier); - } - -diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c -index 3b69a76d341e7..1626dfc6f6ce6 100644 ---- a/arch/arm/kernel/perf_callchain.c -+++ b/arch/arm/kernel/perf_callchain.c -@@ -62,9 +62,10 @@ user_backtrace(struct frame_tail __user *tail, - void - perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct frame_tail __user *tail; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* We don't support guest os callchain now */ - return; - } -@@ -98,9 +99,10 @@ callchain_trace(struct stackframe *fr, - void - perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct stackframe fr; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* We don't support guest os callchain now */ - return; - } -@@ -111,18 +113,21 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re - - unsigned long perf_instruction_pointer(struct pt_regs *regs) - { -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) -- return perf_guest_cbs->get_guest_ip(); -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); -+ -+ if (guest_cbs && guest_cbs->is_in_guest()) -+ return guest_cbs->get_guest_ip(); - - return instruction_pointer(regs); - } - - unsigned long perf_misc_flags(struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - int misc = 0; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -- if (perf_guest_cbs->is_user_mode()) -+ if (guest_cbs && guest_cbs->is_in_guest()) { -+ if (guest_cbs->is_user_mode()) - misc |= PERF_RECORD_MISC_GUEST_USER; - else - misc |= PERF_RECORD_MISC_GUEST_KERNEL; -diff --git a/arch/arm/kernel/spectre.c b/arch/arm/kernel/spectre.c -new file mode 100644 -index 0000000000000..0dcefc36fb7a0 ---- /dev/null -+++ b/arch/arm/kernel/spectre.c -@@ -0,0 +1,71 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include -+#include -+#include -+ -+#include -+ -+static bool _unprivileged_ebpf_enabled(void) -+{ -+#ifdef CONFIG_BPF_SYSCALL -+ return !sysctl_unprivileged_bpf_disabled; -+#else -+ return false; -+#endif -+} -+ -+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ return sprintf(buf, "Mitigation: __user pointer sanitization\n"); -+} -+ -+static unsigned int spectre_v2_state; -+static unsigned int spectre_v2_methods; -+ -+void spectre_v2_update_state(unsigned int state, unsigned int method) -+{ -+ if (state > spectre_v2_state) -+ spectre_v2_state = state; -+ spectre_v2_methods |= method; -+} -+ -+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ const char *method; -+ -+ if (spectre_v2_state == SPECTRE_UNAFFECTED) -+ return sprintf(buf, "%s\n", "Not affected"); -+ -+ if (spectre_v2_state != SPECTRE_MITIGATED) -+ return sprintf(buf, "%s\n", "Vulnerable"); -+ -+ if (_unprivileged_ebpf_enabled()) -+ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); -+ -+ switch (spectre_v2_methods) { -+ case SPECTRE_V2_METHOD_BPIALL: -+ method = "Branch predictor hardening"; -+ break; -+ -+ case SPECTRE_V2_METHOD_ICIALLU: -+ method = "I-cache invalidation"; -+ break; -+ -+ case SPECTRE_V2_METHOD_SMC: -+ case SPECTRE_V2_METHOD_HVC: -+ method = "Firmware call"; -+ break; -+ -+ case SPECTRE_V2_METHOD_LOOP8: -+ method = "History overwrite"; -+ break; -+ -+ default: -+ method = "Multiple mitigations"; -+ break; -+ } -+ -+ return sprintf(buf, "Mitigation: %s\n", method); -+} -diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c -index 76ea4178a55cb..db798eac74315 100644 ---- a/arch/arm/kernel/stacktrace.c -+++ b/arch/arm/kernel/stacktrace.c -@@ -54,8 +54,7 @@ int notrace unwind_frame(struct stackframe *frame) - - frame->sp = frame->fp; - frame->fp = *(unsigned long *)(fp); -- frame->pc = frame->lr; -- frame->lr = *(unsigned long *)(fp + 4); -+ frame->pc = *(unsigned long *)(fp + 4); - #else - /* check current frame pointer is within bounds */ - if (fp < low + 12 || fp > high - 4) -diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c -index 195dff58bafc7..655c4fe0b4d08 100644 ---- a/arch/arm/kernel/traps.c -+++ b/arch/arm/kernel/traps.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -787,10 +788,59 @@ static inline void __init kuser_init(void *vectors) - } - #endif - -+#ifndef CONFIG_CPU_V7M -+static void copy_from_lma(void *vma, void *lma_start, void *lma_end) -+{ -+ memcpy(vma, lma_start, lma_end - lma_start); -+} -+ -+static void flush_vectors(void *vma, size_t offset, size_t size) -+{ -+ unsigned long start = (unsigned long)vma + offset; -+ unsigned long end = start + size; -+ -+ flush_icache_range(start, end); -+} -+ -+#ifdef CONFIG_HARDEN_BRANCH_HISTORY -+int spectre_bhb_update_vectors(unsigned int method) -+{ -+ extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[]; -+ extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[]; -+ void *vec_start, *vec_end; -+ -+ if (system_state > SYSTEM_SCHEDULING) { -+ pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n", -+ smp_processor_id()); -+ return SPECTRE_VULNERABLE; -+ } -+ -+ switch (method) { -+ case SPECTRE_V2_METHOD_LOOP8: -+ vec_start = __vectors_bhb_loop8_start; -+ vec_end = __vectors_bhb_loop8_end; -+ break; -+ -+ case SPECTRE_V2_METHOD_BPIALL: -+ vec_start = __vectors_bhb_bpiall_start; -+ vec_end = __vectors_bhb_bpiall_end; -+ break; -+ -+ default: -+ pr_err("CPU%u: unknown Spectre BHB state %d\n", -+ smp_processor_id(), method); -+ return SPECTRE_VULNERABLE; -+ } -+ -+ copy_from_lma(vectors_page, vec_start, vec_end); -+ flush_vectors(vectors_page, 0, vec_end - vec_start); -+ -+ return SPECTRE_MITIGATED; -+} -+#endif -+ - void __init early_trap_init(void *vectors_base) - { --#ifndef CONFIG_CPU_V7M -- unsigned long vectors = (unsigned long)vectors_base; - extern char __stubs_start[], __stubs_end[]; - extern char __vectors_start[], __vectors_end[]; - unsigned i; -@@ -811,17 +861,20 @@ void __init early_trap_init(void *vectors_base) - * into the vector page, mapped at 0xffff0000, and ensure these - * are visible to the instruction stream. - */ -- memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); -- memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); -+ copy_from_lma(vectors_base, __vectors_start, __vectors_end); -+ copy_from_lma(vectors_base + 0x1000, __stubs_start, __stubs_end); - - kuser_init(vectors_base); - -- flush_icache_range(vectors, vectors + PAGE_SIZE * 2); -+ flush_vectors(vectors_base, 0, PAGE_SIZE * 2); -+} - #else /* ifndef CONFIG_CPU_V7M */ -+void __init early_trap_init(void *vectors_base) -+{ - /* - * on V7-M there is no need to copy the vector table to a dedicated - * memory area. The address is configurable and so a table in the kernel - * image can be used. - */ --#endif - } -+#endif -diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c -index 6daaa645ae5d9..21413a9b7b6c6 100644 ---- a/arch/arm/mach-omap2/display.c -+++ b/arch/arm/mach-omap2/display.c -@@ -263,9 +263,9 @@ static int __init omapdss_init_of(void) - } - - r = of_platform_populate(node, NULL, NULL, &pdev->dev); -+ put_device(&pdev->dev); - if (r) { - pr_err("Unable to populate DSS submodule devices\n"); -- put_device(&pdev->dev); - return r; - } - -diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c -index 0c2936c7a3799..a5e9cffcac10c 100644 ---- a/arch/arm/mach-omap2/omap_hwmod.c -+++ b/arch/arm/mach-omap2/omap_hwmod.c -@@ -752,8 +752,10 @@ static int __init _init_clkctrl_providers(void) - - for_each_matching_node(np, ti_clkctrl_match_table) { - ret = _setup_clkctrl_provider(np); -- if (ret) -+ if (ret) { -+ of_node_put(np); - break; -+ } - } - - return ret; -diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c -index 3edc5f614eefc..c1c2f041ad3b1 100644 ---- a/arch/arm/mach-s3c/irq-s3c24xx.c -+++ b/arch/arm/mach-s3c/irq-s3c24xx.c -@@ -361,11 +361,25 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, - static asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) - { - do { -- if (likely(s3c_intc[0])) -- if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) -- continue; -+ /* -+ * For platform based machines, neither ERR nor NULL can happen here. -+ * The s3c24xx_handle_irq() will be set as IRQ handler iff this succeeds: -+ * -+ * s3c_intc[0] = s3c24xx_init_intc() -+ * -+ * If this fails, the next calls to s3c24xx_init_intc() won't be executed. -+ * -+ * For DT machine, s3c_init_intc_of() could set the IRQ handler without -+ * setting s3c_intc[0] only if it was called with num_ctrl=0. There is no -+ * such code path, so again the s3c_intc[0] will have a valid pointer if -+ * set_handle_irq() is called. -+ * -+ * Therefore in s3c24xx_handle_irq(), the s3c_intc[0] is always something. -+ */ -+ if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) -+ continue; - -- if (s3c_intc[2]) -+ if (!IS_ERR_OR_NULL(s3c_intc[2])) - if (s3c24xx_handle_intc(s3c_intc[2], regs, 64)) - continue; - -diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c -index ee949255ced3f..09ef73b99dd86 100644 ---- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c -+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c -@@ -154,8 +154,10 @@ static int __init rcar_gen2_regulator_quirk(void) - return -ENODEV; - - for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) { -- if (!of_device_is_available(np)) -+ if (!of_device_is_available(np)) { -+ of_node_put(np); - break; -+ } - - ret = of_property_read_u32(np, "reg", &addr); - if (ret) /* Skip invalid entry and continue */ -@@ -164,6 +166,7 @@ static int __init rcar_gen2_regulator_quirk(void) - quirk = kzalloc(sizeof(*quirk), GFP_KERNEL); - if (!quirk) { - ret = -ENOMEM; -+ of_node_put(np); - goto err_mem; - } - -diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig -index 43ddec677c0b3..594edf9bbea44 100644 ---- a/arch/arm/mach-socfpga/Kconfig -+++ b/arch/arm/mach-socfpga/Kconfig -@@ -2,6 +2,7 @@ - menuconfig ARCH_INTEL_SOCFPGA - bool "Altera SOCFPGA family" - depends on ARCH_MULTI_V7 -+ select ARCH_HAS_RESET_CONTROLLER - select ARCH_SUPPORTS_BIG_ENDIAN - select ARM_AMBA - select ARM_GIC -@@ -18,6 +19,7 @@ menuconfig ARCH_INTEL_SOCFPGA - select PL310_ERRATA_727915 - select PL310_ERRATA_753970 if PL310 - select PL310_ERRATA_769419 -+ select RESET_CONTROLLER - - if ARCH_INTEL_SOCFPGA - config SOCFPGA_SUSPEND -diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h -index fc2608b18a0d0..18f01190dcfd4 100644 ---- a/arch/arm/mach-socfpga/core.h -+++ b/arch/arm/mach-socfpga/core.h -@@ -33,7 +33,7 @@ extern void __iomem *sdr_ctl_base_addr; - u32 socfpga_sdram_self_refresh(u32 sdr_base); - extern unsigned int socfpga_sdram_self_refresh_sz; - --extern char secondary_trampoline, secondary_trampoline_end; -+extern char secondary_trampoline[], secondary_trampoline_end[]; - - extern unsigned long socfpga_cpu1start_addr; - -diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c -index fbb80b883e5dd..201191cf68f32 100644 ---- a/arch/arm/mach-socfpga/platsmp.c -+++ b/arch/arm/mach-socfpga/platsmp.c -@@ -20,14 +20,14 @@ - - static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) - { -- int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; -+ int trampoline_size = secondary_trampoline_end - secondary_trampoline; - - if (socfpga_cpu1start_addr) { - /* This will put CPU #1 into reset. */ - writel(RSTMGR_MPUMODRST_CPU1, - rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST); - -- memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); -+ memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size); - - writel(__pa_symbol(secondary_startup), - sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff)); -@@ -45,12 +45,12 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) - - static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle) - { -- int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; -+ int trampoline_size = secondary_trampoline_end - secondary_trampoline; - - if (socfpga_cpu1start_addr) { - writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr + - SOCFPGA_A10_RSTMGR_MODMPURST); -- memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); -+ memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size); - - writel(__pa_symbol(secondary_startup), - sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff)); -diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index 8355c38958942..f43cdc1cfbaed 100644 ---- a/arch/arm/mm/Kconfig -+++ b/arch/arm/mm/Kconfig -@@ -750,7 +750,7 @@ config CPU_BIG_ENDIAN - config CPU_ENDIAN_BE8 - bool - depends on CPU_BIG_ENDIAN -- default CPU_V6 || CPU_V6K || CPU_V7 -+ default CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M - help - Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors. - -@@ -830,6 +830,7 @@ config CPU_BPREDICT_DISABLE - - config CPU_SPECTRE - bool -+ select GENERIC_CPU_VULNERABILITIES - - config HARDEN_BRANCH_PREDICTOR - bool "Harden the branch predictor against aliasing attacks" if EXPERT -@@ -850,6 +851,16 @@ config HARDEN_BRANCH_PREDICTOR - - If unsure, say Y. - -+config HARDEN_BRANCH_HISTORY -+ bool "Harden Spectre style attacks against branch history" if EXPERT -+ depends on CPU_SPECTRE -+ default y -+ help -+ Speculation attacks against some high-performance processors can -+ make use of branch history to influence future speculation. When -+ taking an exception, a sequence of branches overwrites the branch -+ history, or branch history is invalidated. -+ - config TLS_REG_EMUL - bool - select NEED_KUSER_HELPERS -diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c -index 9c348042a7244..4b1619584b23c 100644 ---- a/arch/arm/mm/kasan_init.c -+++ b/arch/arm/mm/kasan_init.c -@@ -226,7 +226,7 @@ void __init kasan_init(void) - BUILD_BUG_ON(pgd_index(KASAN_SHADOW_START) != - pgd_index(KASAN_SHADOW_END)); - memcpy(tmp_pmd_table, -- pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)), -+ (void*)pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)), - sizeof(tmp_pmd_table)); - set_pgd(&tmp_pgd_table[pgd_index(KASAN_SHADOW_START)], - __pgd(__pa(tmp_pmd_table) | PMD_TYPE_TABLE | L_PGD_SWAPPER)); -diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c -index a4e0060051070..5e2be37a198e2 100644 ---- a/arch/arm/mm/mmu.c -+++ b/arch/arm/mm/mmu.c -@@ -212,12 +212,14 @@ early_param("ecc", early_ecc); - static int __init early_cachepolicy(char *p) - { - pr_warn("cachepolicy kernel parameter not supported without cp15\n"); -+ return 0; - } - early_param("cachepolicy", early_cachepolicy); - - static int __init noalign_setup(char *__unused) - { - pr_warn("noalign kernel parameter not supported without cp15\n"); -+ return 1; - } - __setup("noalign", noalign_setup); - -@@ -390,9 +392,9 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) - BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) < FIXADDR_START); - BUG_ON(idx >= __end_of_fixed_addresses); - -- /* we only support device mappings until pgprot_kernel has been set */ -+ /* We support only device mappings before pgprot_kernel is set. */ - if (WARN_ON(pgprot_val(prot) != pgprot_val(FIXMAP_PAGE_IO) && -- pgprot_val(pgprot_kernel) == 0)) -+ pgprot_val(prot) && pgprot_val(pgprot_kernel) == 0)) - return; - - if (pgprot_val(prot)) -diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c -index 114c05ab4dd91..06dbfb968182d 100644 ---- a/arch/arm/mm/proc-v7-bugs.c -+++ b/arch/arm/mm/proc-v7-bugs.c -@@ -6,8 +6,35 @@ - #include - #include - #include -+#include - #include - -+#ifdef CONFIG_ARM_PSCI -+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) -+{ -+ struct arm_smccc_res res; -+ -+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, -+ ARM_SMCCC_ARCH_WORKAROUND_1, &res); -+ -+ switch ((int)res.a0) { -+ case SMCCC_RET_SUCCESS: -+ return SPECTRE_MITIGATED; -+ -+ case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: -+ return SPECTRE_UNAFFECTED; -+ -+ default: -+ return SPECTRE_VULNERABLE; -+ } -+} -+#else -+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) -+{ -+ return SPECTRE_VULNERABLE; -+} -+#endif -+ - #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR - DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn); - -@@ -36,13 +63,61 @@ static void __maybe_unused call_hvc_arch_workaround_1(void) - arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); - } - --static void cpu_v7_spectre_init(void) -+static unsigned int spectre_v2_install_workaround(unsigned int method) - { - const char *spectre_v2_method = NULL; - int cpu = smp_processor_id(); - - if (per_cpu(harden_branch_predictor_fn, cpu)) -- return; -+ return SPECTRE_MITIGATED; -+ -+ switch (method) { -+ case SPECTRE_V2_METHOD_BPIALL: -+ per_cpu(harden_branch_predictor_fn, cpu) = -+ harden_branch_predictor_bpiall; -+ spectre_v2_method = "BPIALL"; -+ break; -+ -+ case SPECTRE_V2_METHOD_ICIALLU: -+ per_cpu(harden_branch_predictor_fn, cpu) = -+ harden_branch_predictor_iciallu; -+ spectre_v2_method = "ICIALLU"; -+ break; -+ -+ case SPECTRE_V2_METHOD_HVC: -+ per_cpu(harden_branch_predictor_fn, cpu) = -+ call_hvc_arch_workaround_1; -+ cpu_do_switch_mm = cpu_v7_hvc_switch_mm; -+ spectre_v2_method = "hypervisor"; -+ break; -+ -+ case SPECTRE_V2_METHOD_SMC: -+ per_cpu(harden_branch_predictor_fn, cpu) = -+ call_smc_arch_workaround_1; -+ cpu_do_switch_mm = cpu_v7_smc_switch_mm; -+ spectre_v2_method = "firmware"; -+ break; -+ } -+ -+ if (spectre_v2_method) -+ pr_info("CPU%u: Spectre v2: using %s workaround\n", -+ smp_processor_id(), spectre_v2_method); -+ -+ return SPECTRE_MITIGATED; -+} -+#else -+static unsigned int spectre_v2_install_workaround(unsigned int method) -+{ -+ pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n", -+ smp_processor_id()); -+ -+ return SPECTRE_VULNERABLE; -+} -+#endif -+ -+static void cpu_v7_spectre_v2_init(void) -+{ -+ unsigned int state, method = 0; - - switch (read_cpuid_part()) { - case ARM_CPU_PART_CORTEX_A8: -@@ -51,69 +126,133 @@ static void cpu_v7_spectre_init(void) - case ARM_CPU_PART_CORTEX_A17: - case ARM_CPU_PART_CORTEX_A73: - case ARM_CPU_PART_CORTEX_A75: -- per_cpu(harden_branch_predictor_fn, cpu) = -- harden_branch_predictor_bpiall; -- spectre_v2_method = "BPIALL"; -+ state = SPECTRE_MITIGATED; -+ method = SPECTRE_V2_METHOD_BPIALL; - break; - - case ARM_CPU_PART_CORTEX_A15: - case ARM_CPU_PART_BRAHMA_B15: -- per_cpu(harden_branch_predictor_fn, cpu) = -- harden_branch_predictor_iciallu; -- spectre_v2_method = "ICIALLU"; -+ state = SPECTRE_MITIGATED; -+ method = SPECTRE_V2_METHOD_ICIALLU; - break; - --#ifdef CONFIG_ARM_PSCI - case ARM_CPU_PART_BRAHMA_B53: - /* Requires no workaround */ -+ state = SPECTRE_UNAFFECTED; - break; -+ - default: - /* Other ARM CPUs require no workaround */ -- if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) -+ if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) { -+ state = SPECTRE_UNAFFECTED; - break; -+ } -+ - fallthrough; -- /* Cortex A57/A72 require firmware workaround */ -- case ARM_CPU_PART_CORTEX_A57: -- case ARM_CPU_PART_CORTEX_A72: { -- struct arm_smccc_res res; - -- arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, -- ARM_SMCCC_ARCH_WORKAROUND_1, &res); -- if ((int)res.a0 != 0) -- return; -+ /* Cortex A57/A72 require firmware workaround */ -+ case ARM_CPU_PART_CORTEX_A57: -+ case ARM_CPU_PART_CORTEX_A72: -+ state = spectre_v2_get_cpu_fw_mitigation_state(); -+ if (state != SPECTRE_MITIGATED) -+ break; - - switch (arm_smccc_1_1_get_conduit()) { - case SMCCC_CONDUIT_HVC: -- per_cpu(harden_branch_predictor_fn, cpu) = -- call_hvc_arch_workaround_1; -- cpu_do_switch_mm = cpu_v7_hvc_switch_mm; -- spectre_v2_method = "hypervisor"; -+ method = SPECTRE_V2_METHOD_HVC; - break; - - case SMCCC_CONDUIT_SMC: -- per_cpu(harden_branch_predictor_fn, cpu) = -- call_smc_arch_workaround_1; -- cpu_do_switch_mm = cpu_v7_smc_switch_mm; -- spectre_v2_method = "firmware"; -+ method = SPECTRE_V2_METHOD_SMC; - break; - - default: -+ state = SPECTRE_VULNERABLE; - break; - } - } --#endif -+ -+ if (state == SPECTRE_MITIGATED) -+ state = spectre_v2_install_workaround(method); -+ -+ spectre_v2_update_state(state, method); -+} -+ -+#ifdef CONFIG_HARDEN_BRANCH_HISTORY -+static int spectre_bhb_method; -+ -+static const char *spectre_bhb_method_name(int method) -+{ -+ switch (method) { -+ case SPECTRE_V2_METHOD_LOOP8: -+ return "loop"; -+ -+ case SPECTRE_V2_METHOD_BPIALL: -+ return "BPIALL"; -+ -+ default: -+ return "unknown"; - } -+} - -- if (spectre_v2_method) -- pr_info("CPU%u: Spectre v2: using %s workaround\n", -- smp_processor_id(), spectre_v2_method); -+static int spectre_bhb_install_workaround(int method) -+{ -+ if (spectre_bhb_method != method) { -+ if (spectre_bhb_method) { -+ pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n", -+ smp_processor_id()); -+ -+ return SPECTRE_VULNERABLE; -+ } -+ -+ if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE) -+ return SPECTRE_VULNERABLE; -+ -+ spectre_bhb_method = method; -+ } -+ -+ pr_info("CPU%u: Spectre BHB: using %s workaround\n", -+ smp_processor_id(), spectre_bhb_method_name(method)); -+ -+ return SPECTRE_MITIGATED; - } - #else --static void cpu_v7_spectre_init(void) -+static int spectre_bhb_install_workaround(int method) - { -+ return SPECTRE_VULNERABLE; - } - #endif - -+static void cpu_v7_spectre_bhb_init(void) -+{ -+ unsigned int state, method = 0; -+ -+ switch (read_cpuid_part()) { -+ case ARM_CPU_PART_CORTEX_A15: -+ case ARM_CPU_PART_BRAHMA_B15: -+ case ARM_CPU_PART_CORTEX_A57: -+ case ARM_CPU_PART_CORTEX_A72: -+ state = SPECTRE_MITIGATED; -+ method = SPECTRE_V2_METHOD_LOOP8; -+ break; -+ -+ case ARM_CPU_PART_CORTEX_A73: -+ case ARM_CPU_PART_CORTEX_A75: -+ state = SPECTRE_MITIGATED; -+ method = SPECTRE_V2_METHOD_BPIALL; -+ break; -+ -+ default: -+ state = SPECTRE_UNAFFECTED; -+ break; -+ } -+ -+ if (state == SPECTRE_MITIGATED) -+ state = spectre_bhb_install_workaround(method); -+ -+ spectre_v2_update_state(state, method); -+} -+ - static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned, - u32 mask, const char *msg) - { -@@ -142,16 +281,17 @@ static bool check_spectre_auxcr(bool *warned, u32 bit) - void cpu_v7_ca8_ibe(void) - { - if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6))) -- cpu_v7_spectre_init(); -+ cpu_v7_spectre_v2_init(); - } - - void cpu_v7_ca15_ibe(void) - { - if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0))) -- cpu_v7_spectre_init(); -+ cpu_v7_spectre_v2_init(); - } - - void cpu_v7_bugs_init(void) - { -- cpu_v7_spectre_init(); -+ cpu_v7_spectre_v2_init(); -+ cpu_v7_spectre_bhb_init(); - } -diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile -index 14db56f49f0a3..6159010dac4a6 100644 ---- a/arch/arm/probes/kprobes/Makefile -+++ b/arch/arm/probes/kprobes/Makefile -@@ -1,4 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 -+KASAN_SANITIZE_actions-common.o := n -+KASAN_SANITIZE_actions-arm.o := n -+KASAN_SANITIZE_actions-thumb.o := n - obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o - obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o - test-kprobes-objs := test-core.o -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index fee914c716aa2..b68d5cbbeca6a 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -1184,6 +1184,15 @@ config UNMAP_KERNEL_AT_EL0 - - If unsure, say Y. - -+config MITIGATE_SPECTRE_BRANCH_HISTORY -+ bool "Mitigate Spectre style attacks against branch history" if EXPERT -+ default y -+ help -+ Speculation attacks against some high-performance processors can -+ make use of branch history to influence future speculation. -+ When taking an exception from user-space, a sequence of branches -+ or a firmware call overwrites the branch history. -+ - config RODATA_FULL_DEFAULT_ENABLED - bool "Apply r/o permissions of VM areas also to their linear aliases" - default y -@@ -1264,7 +1273,8 @@ config KUSER_HELPERS - - config COMPAT_VDSO - bool "Enable vDSO for 32-bit applications" -- depends on !CPU_BIG_ENDIAN && "$(CROSS_COMPILE_COMPAT)" != "" -+ depends on !CPU_BIG_ENDIAN -+ depends on (CC_IS_CLANG && LD_IS_LLD) || "$(CROSS_COMPILE_COMPAT)" != "" - select GENERIC_COMPAT_VDSO - default y - help -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi -index cc321c04f1219..f6d7d7f7fdabe 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi -@@ -343,19 +343,19 @@ - }; - - thermal-zones { -- cpu-thermal-zone { -+ cpu-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&ths 0>; - }; - -- ddr-thermal-zone { -+ ddr-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&ths 2>; - }; - -- gpu-thermal-zone { -+ gpu-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&ths 1>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi -index 578c37490d901..e39db51eb4489 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi -@@ -4,7 +4,7 @@ - */ - - / { -- cpu0_opp_table: opp_table0 { -+ cpu0_opp_table: opp-table-cpu { - compatible = "operating-points-v2"; - opp-shared; - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi -index b2657201957eb..1afad8b437d72 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi -@@ -2,7 +2,7 @@ - // Copyright (C) 2020 Chen-Yu Tsai - - / { -- cpu_opp_table: cpu-opp-table { -+ cpu_opp_table: opp-table-cpu { - compatible = "operating-points-v2"; - opp-shared; - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts -index d13980ed7a79a..7ec5ac850a0dc 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts -@@ -69,7 +69,7 @@ - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; -- phy-mode = "rgmii"; -+ phy-mode = "rgmii-id"; - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index 578a63dedf466..9988e87ea7b3d 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -217,7 +217,7 @@ - }; - }; - -- gpu_thermal { -+ gpu-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&ths 1>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi -index 8c6e8536b69fa..0baf0f8e4d272 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi -@@ -3,7 +3,7 @@ - // Copyright (C) 2020 Clément Péron - - / { -- cpu_opp_table: cpu-opp-table { -+ cpu_opp_table: opp-table-cpu { - compatible = "allwinner,sun50i-h6-operating-points"; - nvmem-cells = <&cpu_speed_grade>; - opp-shared; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi -index 00c6f53290d43..a3a1ea0f21340 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi -@@ -58,7 +58,7 @@ - secure-monitor = <&sm>; - }; - -- gpu_opp_table: gpu-opp-table { -+ gpu_opp_table: opp-table-gpu { - compatible = "operating-points-v2"; - - opp-124999998 { -@@ -107,6 +107,12 @@ - no-map; - }; - -+ /* 32 MiB reserved for ARM Trusted Firmware (BL32) */ -+ secmon_reserved_bl32: secmon@5300000 { -+ reg = <0x0 0x05300000 0x0 0x2000000>; -+ no-map; -+ }; -+ - linux,cma { - compatible = "shared-dma-pool"; - reusable; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts -index 81269ccc24968..4fb31c2ba31c4 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts -@@ -139,7 +139,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&dc_in>; -+ pwm-supply = <&dc_in>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -@@ -157,14 +157,6 @@ - regulator-always-on; - }; - -- reserved-memory { -- /* TEE Reserved Memory */ -- bl32_reserved: bl32@5000000 { -- reg = <0x0 0x05300000 0x0 0x2000000>; -- no-map; -- }; -- }; -- - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts -index a26bfe72550fe..4b5d11e56364d 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts -@@ -139,7 +139,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&main_12v>; -+ pwm-supply = <&main_12v>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts -index 579f3d02d613e..b4e86196e3468 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts -@@ -139,7 +139,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&dc_in>; -+ pwm-supply = <&dc_in>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi -index f42cf4b8af2d4..16dd409051b40 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi -@@ -18,7 +18,7 @@ - regulator-min-microvolt = <690000>; - regulator-max-microvolt = <1050000>; - -- vin-supply = <&dc_in>; -+ pwm-supply = <&dc_in>; - - pwms = <&pwm_ab 0 1250 0>; - pwm-dutycycle-range = <100 0>; -@@ -37,7 +37,7 @@ - regulator-min-microvolt = <690000>; - regulator-max-microvolt = <1050000>; - -- vin-supply = <&vsys_3v3>; -+ pwm-supply = <&vsys_3v3>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi -index 344573e157a7b..d33e54b5e1969 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi -@@ -17,7 +17,7 @@ - rtc1 = &vrtc; - }; - -- dioo2133: audio-amplifier-0 { -+ dio2133: audio-amplifier-0 { - compatible = "simple-audio-amplifier"; - enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; - VCC-supply = <&vcc_5v>; -@@ -130,7 +130,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&main_12v>; -+ pwm-supply = <&main_12v>; - - pwms = <&pwm_ab 0 1250 0>; - pwm-dutycycle-range = <100 0>; -@@ -149,7 +149,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&main_12v>; -+ pwm-supply = <&main_12v>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -@@ -217,7 +217,7 @@ - audio-widgets = "Line", "Lineout"; - audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>, - <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>, -- <&dioo2133>; -+ <&dio2133>; - audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", - "TDMOUT_B IN 1", "FRDDR_B OUT 1", - "TDMOUT_B IN 2", "FRDDR_C OUT 1", -@@ -607,7 +607,7 @@ - pinctrl-0 = <&nor_pins>; - pinctrl-names = "default"; - -- mx25u64: spi-flash@0 { -+ mx25u64: flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi -index feb0885047400..b40d2c1002c92 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi -@@ -96,7 +96,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&main_12v>; -+ pwm-supply = <&main_12v>; - - pwms = <&pwm_ab 0 1250 0>; - pwm-dutycycle-range = <100 0>; -@@ -115,7 +115,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&main_12v>; -+ pwm-supply = <&main_12v>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -index 6b457b2c30a4b..aa14ea017a613 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -49,6 +49,12 @@ - no-map; - }; - -+ /* 32 MiB reserved for ARM Trusted Firmware (BL32) */ -+ secmon_reserved_bl32: secmon@5300000 { -+ reg = <0x0 0x05300000 0x0 0x2000000>; -+ no-map; -+ }; -+ - linux,cma { - compatible = "shared-dma-pool"; - reusable; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi -index a350fee1264d7..a4d34398da358 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi -@@ -6,6 +6,7 @@ - */ - - #include "meson-gxbb.dtsi" -+#include - - / { - aliases { -@@ -64,6 +65,7 @@ - regulator-name = "VDDIO_AO18"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -+ regulator-always-on; - }; - - vcc_3v3: regulator-vcc_3v3 { -@@ -161,6 +163,7 @@ - status = "okay"; - pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; - pinctrl-names = "default"; -+ hdmi-supply = <&vddio_ao18>; - }; - - &hdmi_tx_tmds_port { -diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts -index effaa138b5f98..5751c48620edf 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts -@@ -123,7 +123,7 @@ - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - -- enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>; -+ enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-always-on; - -@@ -173,7 +173,7 @@ - regulator-min-microvolt = <690000>; - regulator-max-microvolt = <1050000>; - -- vin-supply = <&dc_in>; -+ pwm-supply = <&dc_in>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts -index f2c0981435944..9c0b544e22098 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts -@@ -24,7 +24,7 @@ - regulator-min-microvolt = <690000>; - regulator-max-microvolt = <1050000>; - -- vin-supply = <&vsys_3v3>; -+ pwm-supply = <&vsys_3v3>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi -index fd0ad85c165ba..76ad052fbf0c9 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi -@@ -48,7 +48,7 @@ - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc_5v>; - -- enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>; -+ enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>; - enable-active-high; - regulator-always-on; - -@@ -116,7 +116,7 @@ - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - -- vin-supply = <&main_12v>; -+ pwm-supply = <&main_12v>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; -@@ -263,6 +263,10 @@ - reg = <0>; - max-speed = <1000>; - -+ reset-assert-us = <10000>; -+ reset-deassert-us = <80000>; -+ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; -+ - interrupt-parent = <&gpio_intc>; - /* MAC_INTR on GPIOZ_14 */ - interrupts = <26 IRQ_TYPE_LEVEL_LOW>; -diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts -index 2194a778973f1..a5d79f2f7c196 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts -@@ -185,7 +185,7 @@ - regulator-min-microvolt = <690000>; - regulator-max-microvolt = <1050000>; - -- vin-supply = <&dc_in>; -+ pwm-supply = <&dc_in>; - - pwms = <&pwm_AO_cd 1 1500 0>; - pwm-dutycycle-range = <100 0>; -@@ -203,14 +203,6 @@ - regulator-always-on; - }; - -- reserved-memory { -- /* TEE Reserved Memory */ -- bl32_reserved: bl32@5000000 { -- reg = <0x0 0x05300000 0x0 0x2000000>; -- no-map; -- }; -- }; -- - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; -diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi -index 6288e104a0893..a2635b14da309 100644 ---- a/arch/arm64/boot/dts/arm/juno-base.dtsi -+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi -@@ -543,8 +543,7 @@ - <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, - <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; - /* Standard AXI Translation entries as programmed by EDK2 */ -- dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>, -- <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>, -+ dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>, - <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; -diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi -index a5a64d17d9ea6..5118816b1ed76 100644 ---- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi -+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi -@@ -292,7 +292,7 @@ - reg = <0x640 0x18>; - interrupts = ; - clocks = <&periph_clk>; -- clock-names = "periph"; -+ clock-names = "refclk"; - status = "okay"; - }; - -@@ -326,12 +326,12 @@ - #reset-cells = <1>; - }; - }; -+ }; - -- reboot { -- compatible = "syscon-reboot"; -- regmap = <&timer>; -- offset = <0x34>; -- mask = <1>; -- }; -+ reboot { -+ compatible = "syscon-reboot"; -+ regmap = <&timer>; -+ offset = <0x34>; -+ mask = <1>; - }; - }; -diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -index 79f155dedb2d0..e662677a6e28f 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -15,6 +15,7 @@ - compatible = "fsl,ls1012a-rdb", "fsl,ls1012a"; - - aliases { -+ serial0 = &duart0; - mmc0 = &esdhc0; - mmc1 = &esdhc1; - }; -diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -index bfd14b64567e4..2f92e62ecafe9 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -272,11 +272,6 @@ - vcc-supply = <&sb_3v3>; - }; - -- rtc@51 { -- compatible = "nxp,pcf2129"; -- reg = <0x51>; -- }; -- - eeprom@56 { - compatible = "atmel,24c512"; - reg = <0x56>; -@@ -318,6 +313,15 @@ - - }; - -+&i2c1 { -+ status = "okay"; -+ -+ rtc@51 { -+ compatible = "nxp,pcf2129"; -+ reg = <0x51>; -+ }; -+}; -+ - &enetc_port1 { - phy-handle = <&qds_phy1>; - phy-connection-type = "rgmii-id"; -diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts -index 3063851c2fb91..d3f03dcbb8c38 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts -@@ -38,7 +38,6 @@ - powerdn { - label = "External Power Down"; - gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; -- interrupts = <&gpio1 17 IRQ_TYPE_EDGE_FALLING>; - linux,code = ; - }; - -@@ -46,7 +45,6 @@ - admin { - label = "ADMIN button"; - gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>; -- interrupts = <&gpio3 8 IRQ_TYPE_EDGE_RISING>; - linux,code = ; - }; - }; -diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -index f85e437f80b73..6050723172436 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -847,7 +847,7 @@ - }; - - cluster1_core0_watchdog: wdt@c000000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc000000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -857,7 +857,7 @@ - }; - - cluster1_core1_watchdog: wdt@c010000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc010000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -867,7 +867,7 @@ - }; - - cluster1_core2_watchdog: wdt@c020000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc020000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -877,7 +877,7 @@ - }; - - cluster1_core3_watchdog: wdt@c030000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc030000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -887,7 +887,7 @@ - }; - - cluster2_core0_watchdog: wdt@c100000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc100000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -897,7 +897,7 @@ - }; - - cluster2_core1_watchdog: wdt@c110000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc110000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -907,7 +907,7 @@ - }; - - cluster2_core2_watchdog: wdt@c120000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc120000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -@@ -917,7 +917,7 @@ - }; - - cluster2_core3_watchdog: wdt@c130000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc130000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>, -diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -index 801ba9612d361..1282b61da8a55 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -387,7 +387,7 @@ - }; - - cluster1_core0_watchdog: wdt@c000000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc000000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -397,7 +397,7 @@ - }; - - cluster1_core1_watchdog: wdt@c010000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc010000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -407,7 +407,7 @@ - }; - - cluster2_core0_watchdog: wdt@c100000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc100000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -417,7 +417,7 @@ - }; - - cluster2_core1_watchdog: wdt@c110000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc110000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -427,7 +427,7 @@ - }; - - cluster3_core0_watchdog: wdt@c200000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc200000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -437,7 +437,7 @@ - }; - - cluster3_core1_watchdog: wdt@c210000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc210000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -447,7 +447,7 @@ - }; - - cluster4_core0_watchdog: wdt@c300000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc300000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -@@ -457,7 +457,7 @@ - }; - - cluster4_core1_watchdog: wdt@c310000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xc310000 0x0 0x1000>; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(4)>, -diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -index c4b1a59ba424b..51c4f61007cdb 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -719,7 +719,7 @@ - clock-names = "i2c"; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>; -- scl-gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>; -+ scl-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; - status = "disabled"; - }; - -@@ -768,7 +768,7 @@ - clock-names = "i2c"; - clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL - QORIQ_CLK_PLL_DIV(16)>; -- scl-gpio = <&gpio2 16 GPIO_ACTIVE_HIGH>; -+ scl-gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>; - status = "disabled"; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts -index e99e7644ff392..49d7470812eef 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts -@@ -123,8 +123,8 @@ - - ethphy: ethernet-phy@0 { - reg = <0>; -- reset-assert-us = <100>; -- reset-deassert-us = <100>; -+ reset-assert-us = <1>; -+ reset-deassert-us = <15000>; - reset-gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; - }; - }; -diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -index 4066b16126552..fd38092bb247e 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -@@ -524,11 +524,9 @@ - <&clk IMX8MQ_VIDEO_PLL1>, - <&clk IMX8MQ_VIDEO_PLL1_OUT>; - assigned-clock-rates = <0>, <0>, <0>, <594000000>; -- interconnects = <&noc IMX8MQ_ICM_LCDIF &noc IMX8MQ_ICS_DRAM>; -- interconnect-names = "dram"; - status = "disabled"; - -- port@0 { -+ port { - lcdif_mipi_dsi: endpoint { - remote-endpoint = <&mipi_dsi_lcdif_in>; - }; -@@ -1125,8 +1123,8 @@ - #address-cells = <1>; - #size-cells = <0>; - -- port@0 { -- reg = <0>; -+ port@1 { -+ reg = <1>; - - csi1_mipi_ep: endpoint { - remote-endpoint = <&csi1_ep>; -@@ -1177,8 +1175,8 @@ - #address-cells = <1>; - #size-cells = <0>; - -- port@0 { -- reg = <0>; -+ port@1 { -+ reg = <1>; - - csi2_mipi_ep: endpoint { - remote-endpoint = <&csi2_ep>; -diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi -index 2d5c1a348716a..6eabec2602e23 100644 ---- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi -+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi -@@ -1087,7 +1087,7 @@ - }; - - watchdog0: watchdog@e8a06000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xe8a06000 0x0 0x1000>; - interrupts = ; - clocks = <&crg_ctrl HI3660_OSC32K>, -@@ -1096,7 +1096,7 @@ - }; - - watchdog1: watchdog@e8a07000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xe8a07000 0x0 0x1000>; - interrupts = ; - clocks = <&crg_ctrl HI3660_OSC32K>, -diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi -index dde9371dc5451..e4860b8a638ec 100644 ---- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi -+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi -@@ -840,7 +840,7 @@ - }; - - watchdog0: watchdog@f8005000 { -- compatible = "arm,sp805-wdt", "arm,primecell"; -+ compatible = "arm,sp805", "arm,primecell"; - reg = <0x0 0xf8005000 0x0 0x1000>; - interrupts = ; - clocks = <&ao_ctrl HI6220_WDT0_PCLK>, -diff --git a/arch/arm64/boot/dts/marvell/cn9130.dtsi b/arch/arm64/boot/dts/marvell/cn9130.dtsi -index a2b7e5ec979d3..327b04134134f 100644 ---- a/arch/arm64/boot/dts/marvell/cn9130.dtsi -+++ b/arch/arm64/boot/dts/marvell/cn9130.dtsi -@@ -11,6 +11,13 @@ - model = "Marvell Armada CN9130 SoC"; - compatible = "marvell,cn9130", "marvell,armada-ap807-quad", - "marvell,armada-ap807"; -+ -+ aliases { -+ gpio1 = &cp0_gpio1; -+ gpio2 = &cp0_gpio2; -+ spi1 = &cp0_spi0; -+ spi2 = &cp0_spi1; -+ }; - }; - - /* -@@ -35,3 +42,11 @@ - #undef CP11X_PCIE0_BASE - #undef CP11X_PCIE1_BASE - #undef CP11X_PCIE2_BASE -+ -+&cp0_gpio1 { -+ status = "okay"; -+}; -+ -+&cp0_gpio2 { -+ status = "okay"; -+}; -diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi -index e94f8add1a400..062e87e893316 100644 ---- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi -+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi -@@ -1079,7 +1079,7 @@ - - ccplex@e000000 { - compatible = "nvidia,tegra186-ccplex-cluster"; -- reg = <0x0 0x0e000000 0x0 0x3fffff>; -+ reg = <0x0 0x0e000000 0x0 0x400000>; - - nvidia,bpmp = <&bpmp>; - }; -diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi -index c8250a3f7891f..510d2974470cd 100644 ---- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi -+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi -@@ -818,9 +818,8 @@ - <&bpmp TEGRA194_CLK_HDA2CODEC_2X>; - clock-names = "hda", "hda2hdmi", "hda2codec_2x"; - resets = <&bpmp TEGRA194_RESET_HDA>, -- <&bpmp TEGRA194_RESET_HDA2HDMICODEC>, -- <&bpmp TEGRA194_RESET_HDA2CODEC_2X>; -- reset-names = "hda", "hda2hdmi", "hda2codec_2x"; -+ <&bpmp TEGRA194_RESET_HDA2HDMICODEC>; -+ reset-names = "hda", "hda2hdmi"; - power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>; - interconnects = <&mc TEGRA194_MEMORY_CLIENT_HDAR &emc>, - <&mc TEGRA194_MEMORY_CLIENT_HDAW &emc>; -diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -index d2fe58e0eb7aa..ce4c2b4a5fc07 100644 ---- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -200,7 +200,7 @@ - clock-names = "bam_clk"; - #dma-cells = <1>; - qcom,ee = <1>; -- qcom,controlled-remotely = <1>; -+ qcom,controlled-remotely; - qcom,config-pipe-trust-reg = <0>; - }; - -@@ -221,7 +221,7 @@ - interrupts = ; - gpio-controller; - #gpio-cells = <2>; -- gpio-ranges = <&tlmm 0 80>; -+ gpio-ranges = <&tlmm 0 0 80>; - interrupt-controller; - #interrupt-cells = <2>; - -diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -index db333001df4d6..97f99663c132e 100644 ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -@@ -220,7 +220,7 @@ - clock-names = "bam_clk"; - #dma-cells = <1>; - qcom,ee = <1>; -- qcom,controlled-remotely = <1>; -+ qcom,controlled-remotely; - status = "disabled"; - }; - -diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi -index 3f85e34a8ce6f..8b27242724641 100644 ---- a/arch/arm64/boot/dts/qcom/msm8916.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi -@@ -19,8 +19,8 @@ - #size-cells = <2>; - - aliases { -- sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ -- sdhc2 = &sdhc_2; /* SDC2 SD card slot */ -+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */ -+ mmc1 = &sdhc_2; /* SDC2 SD card slot */ - }; - - chosen { }; -@@ -445,7 +445,7 @@ - }; - }; - -- rpm_msg_ram: memory@60000 { -+ rpm_msg_ram: sram@60000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x00060000 0x8000>; - }; -@@ -1384,11 +1384,17 @@ - lpass: audio-controller@7708000 { - status = "disabled"; - compatible = "qcom,lpass-cpu-apq8016"; -+ -+ /* -+ * Note: Unlike the name would suggest, the SEC_I2S_CLK -+ * is actually only used by Tertiary MI2S while -+ * Primary/Secondary MI2S both use the PRI_I2S_CLK. -+ */ - clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, - <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, - <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, -- <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, -+ <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>; - -diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi -index 986fe60dec5fb..5a9a5ed0565f6 100644 ---- a/arch/arm64/boot/dts/qcom/msm8994.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi -@@ -715,7 +715,7 @@ - reg = <0xfc400000 0x2000>; - }; - -- rpm_msg_ram: memory@fc428000 { -+ rpm_msg_ram: sram@fc428000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0xfc428000 0x4000>; - }; -diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi -index 52df22ab3f6ae..6077c36019514 100644 ---- a/arch/arm64/boot/dts/qcom/msm8996.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi -@@ -638,7 +638,7 @@ - }; - }; - -- rpm_msg_ram: memory@68000 { -+ rpm_msg_ram: sram@68000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x00068000 0x6000>; - }; -@@ -965,9 +965,6 @@ - nvmem-cells = <&speedbin_efuse>; - nvmem-cell-names = "speed_bin"; - -- qcom,gpu-quirk-two-pass-use-wfi; -- qcom,gpu-quirk-fault-detect-mask; -- - operating-points-v2 = <&gpu_opp_table>; - - status = "disabled"; -diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi -index 34039b5c80175..228339f81c327 100644 ---- a/arch/arm64/boot/dts/qcom/msm8998.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi -@@ -308,38 +308,42 @@ - LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 { - compatible = "arm,idle-state"; - idle-state-name = "little-retention"; -+ /* CPU Retention (C2D), L2 Active */ - arm,psci-suspend-param = <0x00000002>; - entry-latency-us = <81>; - exit-latency-us = <86>; -- min-residency-us = <200>; -+ min-residency-us = <504>; - }; - - LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 { - compatible = "arm,idle-state"; - idle-state-name = "little-power-collapse"; -+ /* CPU + L2 Power Collapse (C3, D4) */ - arm,psci-suspend-param = <0x40000003>; -- entry-latency-us = <273>; -- exit-latency-us = <612>; -- min-residency-us = <1000>; -+ entry-latency-us = <814>; -+ exit-latency-us = <4562>; -+ min-residency-us = <9183>; - local-timer-stop; - }; - - BIG_CPU_SLEEP_0: cpu-sleep-1-0 { - compatible = "arm,idle-state"; - idle-state-name = "big-retention"; -+ /* CPU Retention (C2D), L2 Active */ - arm,psci-suspend-param = <0x00000002>; - entry-latency-us = <79>; - exit-latency-us = <82>; -- min-residency-us = <200>; -+ min-residency-us = <1302>; - }; - - BIG_CPU_SLEEP_1: cpu-sleep-1-1 { - compatible = "arm,idle-state"; - idle-state-name = "big-power-collapse"; -+ /* CPU + L2 Power Collapse (C3, D4) */ - arm,psci-suspend-param = <0x40000003>; -- entry-latency-us = <336>; -- exit-latency-us = <525>; -- min-residency-us = <1000>; -+ entry-latency-us = <724>; -+ exit-latency-us = <2027>; -+ min-residency-us = <9419>; - local-timer-stop; - }; - }; -@@ -857,7 +861,7 @@ - reg = <0x00100000 0xb0000>; - }; - -- rpm_msg_ram: memory@778000 { -+ rpm_msg_ram: sram@778000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x00778000 0x7000>; - }; -diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi -index f931cb0de231f..42180f1b5dbbb 100644 ---- a/arch/arm64/boot/dts/qcom/pm8916.dtsi -+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi -@@ -86,7 +86,6 @@ - rtc@6000 { - compatible = "qcom,pm8941-rtc"; - reg = <0x6000>; -- reg-names = "rtc", "alarm"; - interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; - }; - -diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi -index b4ac900ab115f..a06ea9adae810 100644 ---- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi -+++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi -@@ -42,7 +42,7 @@ - /* Yes, all four strings *have to* be defined or things won't work. */ - qcom,enabled-strings = <0 1 2 3>; - qcom,cabc; -- qcom,eternal-pfet; -+ qcom,external-pfet; - status = "disabled"; - }; - }; -diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi -index 339790ba585de..ca5be16479809 100644 ---- a/arch/arm64/boot/dts/qcom/qcs404.dtsi -+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi -@@ -318,7 +318,7 @@ - status = "disabled"; - }; - -- rpm_msg_ram: memory@60000 { -+ rpm_msg_ram: sram@60000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x00060000 0x6000>; - }; -diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi -index a758e4d226122..81098aa9687ba 100644 ---- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi -@@ -33,7 +33,7 @@ ap_h1_spi: &spi0 {}; - polling-delay = <0>; - - thermal-sensors = <&pm6150_adc_tm 1>; -- sustainable-power = <814>; -+ sustainable-power = <965>; - - trips { - skin_temp_alert0: trip-point0 { -diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi -index a246dbd74cc11..b7b5264888b7c 100644 ---- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi -@@ -44,7 +44,7 @@ ap_h1_spi: &spi0 {}; - }; - - &cpu6_thermal { -- sustainable-power = <948>; -+ sustainable-power = <1124>; - }; - - &cpu7_alert0 { -@@ -56,7 +56,7 @@ ap_h1_spi: &spi0 {}; - }; - - &cpu7_thermal { -- sustainable-power = <948>; -+ sustainable-power = <1124>; - }; - - &cpu8_alert0 { -@@ -68,7 +68,7 @@ ap_h1_spi: &spi0 {}; - }; - - &cpu8_thermal { -- sustainable-power = <948>; -+ sustainable-power = <1124>; - }; - - &cpu9_alert0 { -@@ -80,7 +80,7 @@ ap_h1_spi: &spi0 {}; - }; - - &cpu9_thermal { -- sustainable-power = <948>; -+ sustainable-power = <1124>; - }; - - &gpio_keys { -diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi -index c8921e2d6480f..495c15deacb7d 100644 ---- a/arch/arm64/boot/dts/qcom/sc7180.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi -@@ -137,8 +137,8 @@ - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1024>; -- dynamic-power-coefficient = <100>; -+ capacity-dmips-mhz = <415>; -+ dynamic-power-coefficient = <137>; - operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, - <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; -@@ -162,8 +162,8 @@ - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1024>; -- dynamic-power-coefficient = <100>; -+ capacity-dmips-mhz = <415>; -+ dynamic-power-coefficient = <137>; - next-level-cache = <&L2_100>; - operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -184,8 +184,8 @@ - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1024>; -- dynamic-power-coefficient = <100>; -+ capacity-dmips-mhz = <415>; -+ dynamic-power-coefficient = <137>; - next-level-cache = <&L2_200>; - operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -206,8 +206,8 @@ - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1024>; -- dynamic-power-coefficient = <100>; -+ capacity-dmips-mhz = <415>; -+ dynamic-power-coefficient = <137>; - next-level-cache = <&L2_300>; - operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -228,8 +228,8 @@ - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1024>; -- dynamic-power-coefficient = <100>; -+ capacity-dmips-mhz = <415>; -+ dynamic-power-coefficient = <137>; - next-level-cache = <&L2_400>; - operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -250,8 +250,8 @@ - cpu-idle-states = <&LITTLE_CPU_SLEEP_0 - &LITTLE_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1024>; -- dynamic-power-coefficient = <100>; -+ capacity-dmips-mhz = <415>; -+ dynamic-power-coefficient = <137>; - next-level-cache = <&L2_500>; - operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -272,8 +272,8 @@ - cpu-idle-states = <&BIG_CPU_SLEEP_0 - &BIG_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1740>; -- dynamic-power-coefficient = <405>; -+ capacity-dmips-mhz = <1024>; -+ dynamic-power-coefficient = <480>; - next-level-cache = <&L2_600>; - operating-points-v2 = <&cpu6_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -294,8 +294,8 @@ - cpu-idle-states = <&BIG_CPU_SLEEP_0 - &BIG_CPU_SLEEP_1 - &CLUSTER_SLEEP_0>; -- capacity-dmips-mhz = <1740>; -- dynamic-power-coefficient = <405>; -+ capacity-dmips-mhz = <1024>; -+ dynamic-power-coefficient = <480>; - next-level-cache = <&L2_700>; - operating-points-v2 = <&cpu6_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, -@@ -3616,7 +3616,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 1>; -- sustainable-power = <768>; -+ sustainable-power = <1052>; - - trips { - cpu0_alert0: trip-point0 { -@@ -3665,7 +3665,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 2>; -- sustainable-power = <768>; -+ sustainable-power = <1052>; - - trips { - cpu1_alert0: trip-point0 { -@@ -3714,7 +3714,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 3>; -- sustainable-power = <768>; -+ sustainable-power = <1052>; - - trips { - cpu2_alert0: trip-point0 { -@@ -3763,7 +3763,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 4>; -- sustainable-power = <768>; -+ sustainable-power = <1052>; - - trips { - cpu3_alert0: trip-point0 { -@@ -3812,7 +3812,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 5>; -- sustainable-power = <768>; -+ sustainable-power = <1052>; - - trips { - cpu4_alert0: trip-point0 { -@@ -3861,7 +3861,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 6>; -- sustainable-power = <768>; -+ sustainable-power = <1052>; - - trips { - cpu5_alert0: trip-point0 { -@@ -3910,7 +3910,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 9>; -- sustainable-power = <1202>; -+ sustainable-power = <1425>; - - trips { - cpu6_alert0: trip-point0 { -@@ -3951,7 +3951,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 10>; -- sustainable-power = <1202>; -+ sustainable-power = <1425>; - - trips { - cpu7_alert0: trip-point0 { -@@ -3992,7 +3992,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 11>; -- sustainable-power = <1202>; -+ sustainable-power = <1425>; - - trips { - cpu8_alert0: trip-point0 { -@@ -4033,7 +4033,7 @@ - polling-delay = <0>; - - thermal-sensors = <&tsens0 12>; -- sustainable-power = <1202>; -+ sustainable-power = <1425>; - - trips { - cpu9_alert0: trip-point0 { -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index fd78f16181ddd..692973c4f4344 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -429,7 +429,7 @@ - <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, - <0>, <0>, <0>, <0>, <0>, <0>; - clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", -- "pcie_0_pipe_clk", "pcie_1_pipe-clk", -+ "pcie_0_pipe_clk", "pcie_1_pipe_clk", - "ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk", - "ufs_phy_tx_symbol_0_clk", - "usb3_phy_wrapper_gcc_usb30_pipe_clk"; -@@ -1258,15 +1258,11 @@ - dp_phy: dp-phy@88ea200 { - reg = <0 0x088ea200 0 0x200>, - <0 0x088ea400 0 0x200>, -- <0 0x088eac00 0 0x400>, -+ <0 0x088eaa00 0 0x200>, - <0 0x088ea600 0 0x200>, -- <0 0x088ea800 0 0x200>, -- <0 0x088eaa00 0 0x100>; -+ <0 0x088ea800 0 0x200>; - #phy-cells = <0>; - #clock-cells = <1>; -- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; -- clock-names = "pipe0"; -- clock-output-names = "usb3_phy_pipe_clk_src"; - }; - }; - -diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi -index 9c7f87e42fccd..a8724fd60645f 100644 ---- a/arch/arm64/boot/dts/qcom/sdm630.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi -@@ -541,7 +541,7 @@ - <&sleep_clk>; - }; - -- rpm_msg_ram: memory@778000 { -+ rpm_msg_ram: sram@778000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x00778000 0x7000>; - }; -diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi -index b3b9119261844..519ca9a705b4f 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi -@@ -2316,11 +2316,11 @@ - compatible = "qcom,bam-v1.7.0"; - reg = <0 0x01dc4000 0 0x24000>; - interrupts = ; -- clocks = <&rpmhcc 15>; -+ clocks = <&rpmhcc RPMH_CE_CLK>; - clock-names = "bam_clk"; - #dma-cells = <1>; - qcom,ee = <0>; -- qcom,controlled-remotely = <1>; -+ qcom,controlled-remotely; - iommus = <&apps_smmu 0x704 0x1>, - <&apps_smmu 0x706 0x1>, - <&apps_smmu 0x714 0x1>, -@@ -2331,8 +2331,8 @@ - compatible = "qcom,crypto-v5.4"; - reg = <0 0x01dfa000 0 0x6000>; - clocks = <&gcc GCC_CE1_AHB_CLK>, -- <&gcc GCC_CE1_AHB_CLK>, -- <&rpmhcc 15>; -+ <&gcc GCC_CE1_AXI_CLK>, -+ <&rpmhcc RPMH_CE_CLK>; - clock-names = "iface", "bus", "core"; - dmas = <&cryptobam 6>, <&cryptobam 7>; - dma-names = "rx", "tx"; -diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts -index 2ba23aa582a18..617a634ac9051 100644 ---- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts -+++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts -@@ -518,6 +518,10 @@ - dai@1 { - reg = <1>; - }; -+ -+ dai@2 { -+ reg = <2>; -+ }; - }; - - &sound { -@@ -530,6 +534,7 @@ - "SpkrLeft IN", "SPK1 OUT", - "SpkrRight IN", "SPK2 OUT", - "MM_DL1", "MultiMedia1 Playback", -+ "MM_DL3", "MultiMedia3 Playback", - "MultiMedia2 Capture", "MM_UL2"; - - mm1-dai-link { -@@ -546,6 +551,13 @@ - }; - }; - -+ mm3-dai-link { -+ link-name = "MultiMedia3"; -+ cpu { -+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; -+ }; -+ }; -+ - slim-dai-link { - link-name = "SLIM Playback"; - cpu { -@@ -575,6 +587,21 @@ - sound-dai = <&wcd9340 1>; - }; - }; -+ -+ slim-wcd-dai-link { -+ link-name = "SLIM WCD Playback"; -+ cpu { -+ sound-dai = <&q6afedai SLIMBUS_1_RX>; -+ }; -+ -+ platform { -+ sound-dai = <&q6routing>; -+ }; -+ -+ codec { -+ sound-dai = <&wcd9340 2>; -+ }; -+ }; - }; - - &tlmm { -diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi -index 2b37ce6a9f9c5..9f476e3d0720b 100644 ---- a/arch/arm64/boot/dts/qcom/sm6125.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi -@@ -380,7 +380,7 @@ - status = "disabled"; - }; - -- rpm_msg_ram: memory@45f0000 { -+ rpm_msg_ram: sram@45f0000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x045f0000 0x7000>; - }; -diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi -index e91cd8a5e5356..296ffb0e9888c 100644 ---- a/arch/arm64/boot/dts/qcom/sm8350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi -@@ -2185,7 +2185,7 @@ - }; - }; - -- camera-thermal-bottom { -+ cam-thermal-bottom { - polling-delay-passive = <250>; - polling-delay = <1000>; - -diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi -index 090dc9c4f57b5..937d17a426b66 100644 ---- a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi -+++ b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi -@@ -50,6 +50,7 @@ - &avb { - pinctrl-0 = <&avb_pins>; - pinctrl-names = "default"; -+ phy-mode = "rgmii-rxid"; - phy-handle = <&phy0>; - rx-internal-delay-ps = <1800>; - tx-internal-delay-ps = <2000>; -diff --git a/arch/arm64/boot/dts/renesas/cat875.dtsi b/arch/arm64/boot/dts/renesas/cat875.dtsi -index 801ea54b027c4..20f8adc635e72 100644 ---- a/arch/arm64/boot/dts/renesas/cat875.dtsi -+++ b/arch/arm64/boot/dts/renesas/cat875.dtsi -@@ -18,6 +18,7 @@ - pinctrl-names = "default"; - renesas,no-ether-link; - phy-handle = <&phy0>; -+ phy-mode = "rgmii-id"; - status = "okay"; - - phy0: ethernet-phy@0 { -diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi -index 6f4fffacfca21..e70aa5a087402 100644 ---- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi -@@ -2784,7 +2784,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -2799,7 +2799,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -2814,7 +2814,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi -index 0f7bdfc90a0dc..6c5694fa66900 100644 ---- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi -@@ -2629,7 +2629,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -2644,7 +2644,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -2659,7 +2659,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi -index 379a1300272ba..62209ab6deb9a 100644 ---- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi -@@ -2904,7 +2904,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -2919,7 +2919,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -2934,7 +2934,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi -index 1768a3e6bb8da..193d81be40fc4 100644 ---- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi -@@ -3375,7 +3375,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -3390,7 +3390,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -3405,7 +3405,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi -index 2bd8169735d35..b526e4f0ee6a8 100644 ---- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi -@@ -2972,7 +2972,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -2987,7 +2987,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -3002,7 +3002,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi -index 041473aa5cd09..21fc95397c3c2 100644 ---- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi -@@ -2719,7 +2719,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -2734,7 +2734,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -2749,7 +2749,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi -index 08df75606430b..f9679a4dd85fa 100644 ---- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi -@@ -2784,7 +2784,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -2799,7 +2799,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -2814,7 +2814,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi -index 6347d15e66b64..21fe602bd25af 100644 ---- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi -@@ -1580,7 +1580,7 @@ - }; - - thermal-zones { -- thermal-sensor-1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -1599,7 +1599,7 @@ - }; - }; - -- thermal-sensor-2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi -index 631d520cebee5..26899fb768a73 100644 ---- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi -@@ -1149,7 +1149,7 @@ - }; - - thermal-zones { -- sensor_thermal1: sensor-thermal1 { -+ sensor1_thermal: sensor1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; -@@ -1163,7 +1163,7 @@ - }; - }; - -- sensor_thermal2: sensor-thermal2 { -+ sensor2_thermal: sensor2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 1>; -@@ -1177,7 +1177,7 @@ - }; - }; - -- sensor_thermal3: sensor-thermal3 { -+ sensor3_thermal: sensor3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 2>; -@@ -1191,7 +1191,7 @@ - }; - }; - -- sensor_thermal4: sensor-thermal4 { -+ sensor4_thermal: sensor4-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 3>; -@@ -1205,7 +1205,7 @@ - }; - }; - -- sensor_thermal5: sensor-thermal5 { -+ sensor5_thermal: sensor5-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 4>; -diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts -index 665b2e69455dd..ea6820902ede0 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts -@@ -97,7 +97,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; -- vim-supply = <&vcc_io>; -+ vin-supply = <&vcc_io>; - }; - - vdd_core: vdd-core { -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 8c821acb21ffb..da84be6f4715e 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -599,7 +599,7 @@ - - gpu: gpu@ff300000 { - compatible = "rockchip,rk3328-mali", "arm,mali-450"; -- reg = <0x0 0xff300000 0x0 0x40000>; -+ reg = <0x0 0xff300000 0x0 0x30000>; - interrupts = , - , - , -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi -index c1bcc8ca3769d..2f8e117109699 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi -@@ -286,7 +286,7 @@ - - sound: sound { - compatible = "rockchip,rk3399-gru-sound"; -- rockchip,cpu = <&i2s0 &i2s2>; -+ rockchip,cpu = <&i2s0 &spdif>; - }; - }; - -@@ -437,10 +437,6 @@ ap_i2c_audio: &i2c8 { - status = "okay"; - }; - --&i2s2 { -- status = "okay"; --}; -- - &io_domains { - status = "okay"; - -@@ -537,6 +533,17 @@ ap_i2c_audio: &i2c8 { - vqmmc-supply = <&ppvar_sd_card_io>; - }; - -+&spdif { -+ status = "okay"; -+ -+ /* -+ * SPDIF is routed internally to DP; we either don't use these pins, or -+ * mux them to something else. -+ */ -+ /delete-property/ pinctrl-0; -+ /delete-property/ pinctrl-names; -+}; -+ - &spi1 { - status = "okay"; - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -index d5c7648c841dc..f1fcc6b5b402c 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -@@ -705,7 +705,6 @@ - &sdhci { - bus-width = <8>; - mmc-hs400-1_8v; -- mmc-hs400-enhanced-strobe; - non-removable; - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -index 738cfd21df3ef..354f54767bad8 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts -@@ -269,6 +269,7 @@ - clock-output-names = "xin32k", "rk808-clkout2"; - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>; -+ rockchip,system-power-controller; - vcc1-supply = <&vcc5v0_sys>; - vcc2-supply = <&vcc5v0_sys>; - vcc3-supply = <&vcc5v0_sys>; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts b/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts -index 7c93f840bc64f..e890166e7fd43 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts -@@ -55,7 +55,7 @@ - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- vim-supply = <&vcc3v3_sys>; -+ vin-supply = <&vcc3v3_sys>; - }; - - vcc3v3_sys: vcc3v3-sys { -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -index 2b5f001ff4a61..9e5d07f5712e6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts -@@ -385,10 +385,6 @@ - }; - }; - --&cdn_dp { -- status = "okay"; --}; -- - &cpu_b0 { - cpu-supply = <&vdd_cpu_b>; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index b28888ea9262e..100a769165ef9 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -457,7 +457,7 @@ - status = "okay"; - - bt656-supply = <&vcc_3v0>; -- audio-supply = <&vcc_3v0>; -+ audio-supply = <&vcc1v8_codec>; - sdmmc-supply = <&vcc_sdio>; - gpio1830-supply = <&vcc_3v0>; - }; -diff --git a/arch/arm64/boot/dts/ti/k3-am642.dtsi b/arch/arm64/boot/dts/ti/k3-am642.dtsi -index e2b397c884018..8a76f4821b11b 100644 ---- a/arch/arm64/boot/dts/ti/k3-am642.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am642.dtsi -@@ -60,6 +60,6 @@ - cache-level = <2>; - cache-size = <0x40000>; - cache-line-size = <64>; -- cache-sets = <512>; -+ cache-sets = <256>; - }; - }; -diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -index e8a41d09b45f2..7daa280220442 100644 ---- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -@@ -32,7 +32,7 @@ - #size-cells = <1>; - ranges = <0x00 0x00 0x00100000 0x1c000>; - -- serdes_ln_ctrl: serdes-ln-ctrl@4080 { -+ serdes_ln_ctrl: mux-controller@4080 { - compatible = "mmio-mux"; - #mux-control-cells = <1>; - mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */ -@@ -606,10 +606,10 @@ - clock-names = "fck"; - #address-cells = <3>; - #size-cells = <2>; -- bus-range = <0x0 0xf>; -+ bus-range = <0x0 0xff>; - cdns,no-bar-match-nbits = <64>; -- vendor-id = /bits/ 16 <0x104c>; -- device-id = /bits/ 16 <0xb00f>; -+ vendor-id = <0x104c>; -+ device-id = <0xb00f>; - msi-map = <0x0 &gic_its 0x0 0x10000>; - dma-coherent; - ranges = <0x01000000 0x0 0x18001000 0x00 0x18001000 0x0 0x0010000>, -diff --git a/arch/arm64/boot/dts/ti/k3-j7200.dtsi b/arch/arm64/boot/dts/ti/k3-j7200.dtsi -index b7005b8031495..7586b5aea446f 100644 ---- a/arch/arm64/boot/dts/ti/k3-j7200.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j7200.dtsi -@@ -60,7 +60,7 @@ - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; -- d-cache-sets = <128>; -+ d-cache-sets = <256>; - next-level-cache = <&L2_0>; - }; - -@@ -74,7 +74,7 @@ - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; -- d-cache-sets = <128>; -+ d-cache-sets = <256>; - next-level-cache = <&L2_0>; - }; - }; -@@ -84,7 +84,7 @@ - cache-level = <2>; - cache-size = <0x100000>; - cache-line-size = <64>; -- cache-sets = <2048>; -+ cache-sets = <1024>; - next-level-cache = <&msmc_l3>; - }; - -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -index cf3482376c1e6..e85c89eebfa31 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -@@ -42,7 +42,7 @@ - #size-cells = <1>; - ranges = <0x0 0x0 0x00100000 0x1c000>; - -- serdes_ln_ctrl: mux@4080 { -+ serdes_ln_ctrl: mux-controller@4080 { - compatible = "mmio-mux"; - reg = <0x00004080 0x50>; - #mux-control-cells = <1>; -@@ -610,7 +610,7 @@ - clock-names = "fck"; - #address-cells = <3>; - #size-cells = <2>; -- bus-range = <0x0 0xf>; -+ bus-range = <0x0 0xff>; - vendor-id = <0x104c>; - device-id = <0xb00d>; - msi-map = <0x0 &gic_its 0x0 0x10000>; -@@ -636,7 +636,7 @@ - clocks = <&k3_clks 239 1>; - clock-names = "fck"; - max-functions = /bits/ 8 <6>; -- max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; -+ max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; - dma-coherent; - }; - -@@ -658,7 +658,7 @@ - clock-names = "fck"; - #address-cells = <3>; - #size-cells = <2>; -- bus-range = <0x0 0xf>; -+ bus-range = <0x0 0xff>; - vendor-id = <0x104c>; - device-id = <0xb00d>; - msi-map = <0x0 &gic_its 0x10000 0x10000>; -@@ -684,7 +684,7 @@ - clocks = <&k3_clks 240 1>; - clock-names = "fck"; - max-functions = /bits/ 8 <6>; -- max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; -+ max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; - dma-coherent; - }; - -@@ -706,7 +706,7 @@ - clock-names = "fck"; - #address-cells = <3>; - #size-cells = <2>; -- bus-range = <0x0 0xf>; -+ bus-range = <0x0 0xff>; - vendor-id = <0x104c>; - device-id = <0xb00d>; - msi-map = <0x0 &gic_its 0x20000 0x10000>; -@@ -732,7 +732,7 @@ - clocks = <&k3_clks 241 1>; - clock-names = "fck"; - max-functions = /bits/ 8 <6>; -- max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; -+ max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; - dma-coherent; - }; - -@@ -754,7 +754,7 @@ - clock-names = "fck"; - #address-cells = <3>; - #size-cells = <2>; -- bus-range = <0x0 0xf>; -+ bus-range = <0x0 0xff>; - vendor-id = <0x104c>; - device-id = <0xb00d>; - msi-map = <0x0 &gic_its 0x30000 0x10000>; -@@ -780,7 +780,7 @@ - clocks = <&k3_clks 242 1>; - clock-names = "fck"; - max-functions = /bits/ 8 <6>; -- max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; -+ max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; - dma-coherent; - #address-cells = <2>; - #size-cells = <2>; -diff --git a/arch/arm64/boot/dts/ti/k3-j721e.dtsi b/arch/arm64/boot/dts/ti/k3-j721e.dtsi -index f0587fde147e6..69ce048a2136e 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e.dtsi -@@ -61,7 +61,7 @@ - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; -- d-cache-sets = <128>; -+ d-cache-sets = <256>; - next-level-cache = <&L2_0>; - }; - -@@ -75,7 +75,7 @@ - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; -- d-cache-sets = <128>; -+ d-cache-sets = <256>; - next-level-cache = <&L2_0>; - }; - }; -@@ -85,7 +85,7 @@ - cache-level = <2>; - cache-size = <0x100000>; - cache-line-size = <64>; -- cache-sets = <2048>; -+ cache-sets = <1024>; - next-level-cache = <&msmc_l3>; - }; - -diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts -index 4a86efa32d687..f7124e15f0ff6 100644 ---- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts -+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts -@@ -131,7 +131,7 @@ - reg = <0>; - - partition@0 { -- label = "data"; -+ label = "spi0-data"; - reg = <0x0 0x100000>; - }; - }; -@@ -149,7 +149,7 @@ - reg = <0>; - - partition@0 { -- label = "data"; -+ label = "spi1-data"; - reg = <0x0 0x84000>; - }; - }; -diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi -index 28dccb891a535..8278876ad33fa 100644 ---- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi -+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi -@@ -792,7 +792,7 @@ - }; - - uart0: serial@ff000000 { -- compatible = "cdns,uart-r1p12", "xlnx,xuartps"; -+ compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12"; - status = "disabled"; - interrupt-parent = <&gic>; - interrupts = <0 21 4>; -@@ -802,7 +802,7 @@ - }; - - uart1: serial@ff010000 { -- compatible = "cdns,uart-r1p12", "xlnx,xuartps"; -+ compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12"; - status = "disabled"; - interrupt-parent = <&gic>; - interrupts = <0 22 4>; -diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h -index bfa58409a4d4d..448a575db8e8e 100644 ---- a/arch/arm64/include/asm/assembler.h -+++ b/arch/arm64/include/asm/assembler.h -@@ -107,6 +107,13 @@ - hint #20 - .endm - -+/* -+ * Clear Branch History instruction -+ */ -+ .macro clearbhb -+ hint #22 -+ .endm -+ - /* - * Speculation barrier - */ -@@ -830,4 +837,50 @@ alternative_endif - - #endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */ - -+ .macro __mitigate_spectre_bhb_loop tmp -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+alternative_cb spectre_bhb_patch_loop_iter -+ mov \tmp, #32 // Patched to correct the immediate -+alternative_cb_end -+.Lspectre_bhb_loop\@: -+ b . + 4 -+ subs \tmp, \tmp, #1 -+ b.ne .Lspectre_bhb_loop\@ -+ sb -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ .endm -+ -+ .macro mitigate_spectre_bhb_loop tmp -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+alternative_cb spectre_bhb_patch_loop_mitigation_enable -+ b .L_spectre_bhb_loop_done\@ // Patched to NOP -+alternative_cb_end -+ __mitigate_spectre_bhb_loop \tmp -+.L_spectre_bhb_loop_done\@: -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ .endm -+ -+ /* Save/restores x0-x3 to the stack */ -+ .macro __mitigate_spectre_bhb_fw -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+ stp x0, x1, [sp, #-16]! -+ stp x2, x3, [sp, #-16]! -+ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3 -+alternative_cb smccc_patch_fw_mitigation_conduit -+ nop // Patched to SMC/HVC #0 -+alternative_cb_end -+ ldp x2, x3, [sp], #16 -+ ldp x0, x1, [sp], #16 -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ .endm -+ -+ .macro mitigate_spectre_bhb_clear_insn -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+alternative_cb spectre_bhb_patch_clearbhb -+ /* Patched to NOP when not supported */ -+ clearbhb -+ isb -+alternative_cb_end -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ .endm - #endif /* __ASM_ASSEMBLER_H */ -diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h -index 0f6d16faa5402..a58e366f0b074 100644 ---- a/arch/arm64/include/asm/cpu.h -+++ b/arch/arm64/include/asm/cpu.h -@@ -51,6 +51,7 @@ struct cpuinfo_arm64 { - u64 reg_id_aa64dfr1; - u64 reg_id_aa64isar0; - u64 reg_id_aa64isar1; -+ u64 reg_id_aa64isar2; - u64 reg_id_aa64mmfr0; - u64 reg_id_aa64mmfr1; - u64 reg_id_aa64mmfr2; -diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h -index ef6be92b1921a..a77b5f49b3a6c 100644 ---- a/arch/arm64/include/asm/cpufeature.h -+++ b/arch/arm64/include/asm/cpufeature.h -@@ -637,6 +637,35 @@ static inline bool cpu_supports_mixed_endian_el0(void) - return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1)); - } - -+ -+static inline bool supports_csv2p3(int scope) -+{ -+ u64 pfr0; -+ u8 csv2_val; -+ -+ if (scope == SCOPE_LOCAL_CPU) -+ pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1); -+ else -+ pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); -+ -+ csv2_val = cpuid_feature_extract_unsigned_field(pfr0, -+ ID_AA64PFR0_CSV2_SHIFT); -+ return csv2_val == 3; -+} -+ -+static inline bool supports_clearbhb(int scope) -+{ -+ u64 isar2; -+ -+ if (scope == SCOPE_LOCAL_CPU) -+ isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1); -+ else -+ isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); -+ -+ return cpuid_feature_extract_unsigned_field(isar2, -+ ID_AA64ISAR2_CLEARBHB_SHIFT); -+} -+ - const struct cpumask *system_32bit_el0_cpumask(void); - DECLARE_STATIC_KEY_FALSE(arm64_mismatched_32bit_el0); - -diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h -index 6231e1f0abe7e..bfbf0c4c7c5e5 100644 ---- a/arch/arm64/include/asm/cputype.h -+++ b/arch/arm64/include/asm/cputype.h -@@ -73,6 +73,14 @@ - #define ARM_CPU_PART_CORTEX_A76 0xD0B - #define ARM_CPU_PART_NEOVERSE_N1 0xD0C - #define ARM_CPU_PART_CORTEX_A77 0xD0D -+#define ARM_CPU_PART_NEOVERSE_V1 0xD40 -+#define ARM_CPU_PART_CORTEX_A78 0xD41 -+#define ARM_CPU_PART_CORTEX_X1 0xD44 -+#define ARM_CPU_PART_CORTEX_A510 0xD46 -+#define ARM_CPU_PART_CORTEX_A710 0xD47 -+#define ARM_CPU_PART_CORTEX_X2 0xD48 -+#define ARM_CPU_PART_NEOVERSE_N2 0xD49 -+#define ARM_CPU_PART_CORTEX_A78C 0xD4B - - #define APM_CPU_PART_POTENZA 0x000 - -@@ -113,6 +121,14 @@ - #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) - #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) - #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) -+#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1) -+#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) -+#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) -+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) -+#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) -+#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) -+#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) -+#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) - #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) - #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) - #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) -diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h -index d3e1825337be3..ad55079abe476 100644 ---- a/arch/arm64/include/asm/efi.h -+++ b/arch/arm64/include/asm/efi.h -@@ -14,7 +14,6 @@ - - #ifdef CONFIG_EFI - extern void efi_init(void); --extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt); - #else - #define efi_init() - #endif -diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h -index 3198acb2aad8c..7f3c87f7a0cec 100644 ---- a/arch/arm64/include/asm/el2_setup.h -+++ b/arch/arm64/include/asm/el2_setup.h -@@ -106,7 +106,7 @@ - msr_s SYS_ICC_SRE_EL2, x0 - isb // Make sure SRE is now set - mrs_s x0, SYS_ICC_SRE_EL2 // Read SRE back, -- tbz x0, #0, 1f // and check that it sticks -+ tbz x0, #0, .Lskip_gicv3_\@ // and check that it sticks - msr_s SYS_ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults - .Lskip_gicv3_\@: - .endm -diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h -index 29f97eb3dad41..8f59bbeba7a7e 100644 ---- a/arch/arm64/include/asm/esr.h -+++ b/arch/arm64/include/asm/esr.h -@@ -68,6 +68,7 @@ - #define ESR_ELx_EC_MAX (0x3F) - - #define ESR_ELx_EC_SHIFT (26) -+#define ESR_ELx_EC_WIDTH (6) - #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) - #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) - -diff --git a/arch/arm64/include/asm/extable.h b/arch/arm64/include/asm/extable.h -index b15eb4a3e6b20..840a35ed92ec8 100644 ---- a/arch/arm64/include/asm/extable.h -+++ b/arch/arm64/include/asm/extable.h -@@ -22,15 +22,6 @@ struct exception_table_entry - - #define ARCH_HAS_RELATIVE_EXTABLE - --static inline bool in_bpf_jit(struct pt_regs *regs) --{ -- if (!IS_ENABLED(CONFIG_BPF_JIT)) -- return false; -- -- return regs->pc >= BPF_JIT_REGION_START && -- regs->pc < BPF_JIT_REGION_END; --} -- - #ifdef CONFIG_BPF_JIT - int arm64_bpf_fixup_exception(const struct exception_table_entry *ex, - struct pt_regs *regs); -diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h -index 4335800201c97..daff882883f92 100644 ---- a/arch/arm64/include/asm/fixmap.h -+++ b/arch/arm64/include/asm/fixmap.h -@@ -62,9 +62,11 @@ enum fixed_addresses { - #endif /* CONFIG_ACPI_APEI_GHES */ - - #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -+ FIX_ENTRY_TRAMP_TEXT3, -+ FIX_ENTRY_TRAMP_TEXT2, -+ FIX_ENTRY_TRAMP_TEXT1, - FIX_ENTRY_TRAMP_DATA, -- FIX_ENTRY_TRAMP_TEXT, --#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT)) -+#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1)) - #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ - __end_of_permanent_fixed_addresses, - -diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h -index 8c129db8232a6..f68fbb2074730 100644 ---- a/arch/arm64/include/asm/hwcap.h -+++ b/arch/arm64/include/asm/hwcap.h -@@ -105,6 +105,9 @@ - #define KERNEL_HWCAP_RNG __khwcap2_feature(RNG) - #define KERNEL_HWCAP_BTI __khwcap2_feature(BTI) - #define KERNEL_HWCAP_MTE __khwcap2_feature(MTE) -+#define KERNEL_HWCAP_ECV __khwcap2_feature(ECV) -+#define KERNEL_HWCAP_AFP __khwcap2_feature(AFP) -+#define KERNEL_HWCAP_RPRES __khwcap2_feature(RPRES) - - /* - * This yields a mask that user programs can use to figure out what -diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h -index 6b776c8667b20..b02f0c328c8e4 100644 ---- a/arch/arm64/include/asm/insn.h -+++ b/arch/arm64/include/asm/insn.h -@@ -65,6 +65,7 @@ enum aarch64_insn_hint_cr_op { - AARCH64_INSN_HINT_PSB = 0x11 << 5, - AARCH64_INSN_HINT_TSB = 0x12 << 5, - AARCH64_INSN_HINT_CSDB = 0x14 << 5, -+ AARCH64_INSN_HINT_CLEARBHB = 0x16 << 5, - - AARCH64_INSN_HINT_BTI = 0x20 << 5, - AARCH64_INSN_HINT_BTIC = 0x22 << 5, -diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h -index 327120c0089fe..f67a561e0935e 100644 ---- a/arch/arm64/include/asm/kvm_arm.h -+++ b/arch/arm64/include/asm/kvm_arm.h -@@ -91,7 +91,7 @@ - #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) - - /* TCR_EL2 Registers bits */ --#define TCR_EL2_RES1 ((1 << 31) | (1 << 23)) -+#define TCR_EL2_RES1 ((1U << 31) | (1 << 23)) - #define TCR_EL2_TBI (1 << 20) - #define TCR_EL2_PS_SHIFT 16 - #define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT) -@@ -276,7 +276,7 @@ - #define CPTR_EL2_TFP_SHIFT 10 - - /* Hyp Coprocessor Trap Register */ --#define CPTR_EL2_TCPAC (1 << 31) -+#define CPTR_EL2_TCPAC (1U << 31) - #define CPTR_EL2_TAM (1 << 30) - #define CPTR_EL2_TTA (1 << 20) - #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) -diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h -index f8be56d5342ba..fc6ee6c5972d0 100644 ---- a/arch/arm64/include/asm/kvm_host.h -+++ b/arch/arm64/include/asm/kvm_host.h -@@ -711,6 +711,11 @@ static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt) - ctxt_sys_reg(cpu_ctxt, MPIDR_EL1) = read_cpuid_mpidr(); - } - -+static inline bool kvm_system_needs_idmapped_vectors(void) -+{ -+ return cpus_have_const_cap(ARM64_SPECTRE_V3A); -+} -+ - void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu); - - static inline void kvm_arch_hardware_unsetup(void) {} -diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h -index f1745a8434144..05886322c300c 100644 ---- a/arch/arm64/include/asm/memory.h -+++ b/arch/arm64/include/asm/memory.h -@@ -44,11 +44,8 @@ - #define _PAGE_OFFSET(va) (-(UL(1) << (va))) - #define PAGE_OFFSET (_PAGE_OFFSET(VA_BITS)) - #define KIMAGE_VADDR (MODULES_END) --#define BPF_JIT_REGION_START (_PAGE_END(VA_BITS_MIN)) --#define BPF_JIT_REGION_SIZE (SZ_128M) --#define BPF_JIT_REGION_END (BPF_JIT_REGION_START + BPF_JIT_REGION_SIZE) - #define MODULES_END (MODULES_VADDR + MODULES_VSIZE) --#define MODULES_VADDR (BPF_JIT_REGION_END) -+#define MODULES_VADDR (_PAGE_END(VA_BITS_MIN)) - #define MODULES_VSIZE (SZ_128M) - #define VMEMMAP_START (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT))) - #define VMEMMAP_END (VMEMMAP_START + VMEMMAP_SIZE) -diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h -index 22420e1f8c037..26e013e540ae2 100644 ---- a/arch/arm64/include/asm/mte-kasan.h -+++ b/arch/arm64/include/asm/mte-kasan.h -@@ -84,10 +84,12 @@ static inline void __dc_gzva(u64 p) - static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag, - bool init) - { -- u64 curr, mask, dczid_bs, end1, end2, end3; -+ u64 curr, mask, dczid, dczid_bs, dczid_dzp, end1, end2, end3; - - /* Read DC G(Z)VA block size from the system register. */ -- dczid_bs = 4ul << (read_cpuid(DCZID_EL0) & 0xf); -+ dczid = read_cpuid(DCZID_EL0); -+ dczid_bs = 4ul << (dczid & 0xf); -+ dczid_dzp = (dczid >> 4) & 1; - - curr = (u64)__tag_set(addr, tag); - mask = dczid_bs - 1; -@@ -106,7 +108,7 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag, - */ - #define SET_MEMTAG_RANGE(stg_post, dc_gva) \ - do { \ -- if (size >= 2 * dczid_bs) { \ -+ if (!dczid_dzp && size >= 2 * dczid_bs) {\ - do { \ - curr = stg_post(curr); \ - } while (curr < end1); \ -diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h -index 8433a2058eb15..237224484d0f6 100644 ---- a/arch/arm64/include/asm/pgalloc.h -+++ b/arch/arm64/include/asm/pgalloc.h -@@ -76,7 +76,7 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep, - static inline void - pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) - { -- VM_BUG_ON(mm != &init_mm); -+ VM_BUG_ON(mm && mm != &init_mm); - __pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN); - } - -diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h -index dfa76afa0ccff..72f95c6a70519 100644 ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -67,9 +67,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; - * page table entry, taking care of 52-bit addresses. - */ - #ifdef CONFIG_ARM64_PA_BITS_52 --#define __pte_to_phys(pte) \ -- ((pte_val(pte) & PTE_ADDR_LOW) | ((pte_val(pte) & PTE_ADDR_HIGH) << 36)) --#define __phys_to_pte_val(phys) (((phys) | ((phys) >> 36)) & PTE_ADDR_MASK) -+static inline phys_addr_t __pte_to_phys(pte_t pte) -+{ -+ return (pte_val(pte) & PTE_ADDR_LOW) | -+ ((pte_val(pte) & PTE_ADDR_HIGH) << 36); -+} -+static inline pteval_t __phys_to_pte_val(phys_addr_t phys) -+{ -+ return (phys | (phys >> 36)) & PTE_ADDR_MASK; -+} - #else - #define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK) - #define __phys_to_pte_val(phys) (phys) -diff --git a/arch/arm64/include/asm/rwonce.h b/arch/arm64/include/asm/rwonce.h -index 1bce62fa908a3..56f7b1d4d54b9 100644 ---- a/arch/arm64/include/asm/rwonce.h -+++ b/arch/arm64/include/asm/rwonce.h -@@ -5,7 +5,7 @@ - #ifndef __ASM_RWONCE_H - #define __ASM_RWONCE_H - --#ifdef CONFIG_LTO -+#if defined(CONFIG_LTO) && !defined(__ASSEMBLY__) - - #include - #include -@@ -66,7 +66,7 @@ - }) - - #endif /* !BUILD_VDSO */ --#endif /* CONFIG_LTO */ -+#endif /* CONFIG_LTO && !__ASSEMBLY__ */ - - #include - -diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h -index e4ad9db53af1d..552891e626e53 100644 ---- a/arch/arm64/include/asm/sections.h -+++ b/arch/arm64/include/asm/sections.h -@@ -22,4 +22,9 @@ extern char __irqentry_text_start[], __irqentry_text_end[]; - extern char __mmuoff_data_start[], __mmuoff_data_end[]; - extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; - -+static inline size_t entry_tramp_text_size(void) -+{ -+ return __entry_tramp_text_end - __entry_tramp_text_start; -+} -+ - #endif /* __ASM_SECTIONS_H */ -diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h -index f62ca39da6c5a..86e0cc9b9c685 100644 ---- a/arch/arm64/include/asm/spectre.h -+++ b/arch/arm64/include/asm/spectre.h -@@ -93,5 +93,9 @@ void spectre_v4_enable_task_mitigation(struct task_struct *tsk); - - enum mitigation_state arm64_get_meltdown_state(void); - -+enum mitigation_state arm64_get_spectre_bhb_state(void); -+bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope); -+u8 spectre_bhb_loop_affected(int scope); -+void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused); - #endif /* __ASSEMBLY__ */ - #endif /* __ASM_SPECTRE_H */ -diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h -index b268082d67edd..394fc5998a4b2 100644 ---- a/arch/arm64/include/asm/sysreg.h -+++ b/arch/arm64/include/asm/sysreg.h -@@ -180,6 +180,7 @@ - - #define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0) - #define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1) -+#define SYS_ID_AA64ISAR2_EL1 sys_reg(3, 0, 0, 6, 2) - - #define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0) - #define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1) -@@ -764,6 +765,21 @@ - #define ID_AA64ISAR1_GPI_NI 0x0 - #define ID_AA64ISAR1_GPI_IMP_DEF 0x1 - -+/* id_aa64isar2 */ -+#define ID_AA64ISAR2_CLEARBHB_SHIFT 28 -+#define ID_AA64ISAR2_RPRES_SHIFT 4 -+#define ID_AA64ISAR2_WFXT_SHIFT 0 -+ -+#define ID_AA64ISAR2_RPRES_8BIT 0x0 -+#define ID_AA64ISAR2_RPRES_12BIT 0x1 -+/* -+ * Value 0x1 has been removed from the architecture, and is -+ * reserved, but has not yet been removed from the ARM ARM -+ * as of ARM DDI 0487G.b. -+ */ -+#define ID_AA64ISAR2_WFXT_NI 0x0 -+#define ID_AA64ISAR2_WFXT_SUPPORTED 0x2 -+ - /* id_aa64pfr0 */ - #define ID_AA64PFR0_CSV3_SHIFT 60 - #define ID_AA64PFR0_CSV2_SHIFT 56 -@@ -881,6 +897,8 @@ - #endif - - /* id_aa64mmfr1 */ -+#define ID_AA64MMFR1_ECBHB_SHIFT 60 -+#define ID_AA64MMFR1_AFP_SHIFT 44 - #define ID_AA64MMFR1_ETS_SHIFT 36 - #define ID_AA64MMFR1_TWED_SHIFT 32 - #define ID_AA64MMFR1_XNX_SHIFT 28 -diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h -index 190b494e22ab9..0fd6056ba412b 100644 ---- a/arch/arm64/include/asm/uaccess.h -+++ b/arch/arm64/include/asm/uaccess.h -@@ -292,12 +292,22 @@ do { \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ - } while (0) - -+/* -+ * We must not call into the scheduler between uaccess_ttbr0_enable() and -+ * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, -+ * we must evaluate these outside of the critical section. -+ */ - #define __raw_get_user(x, ptr, err) \ - do { \ -+ __typeof__(*(ptr)) __user *__rgu_ptr = (ptr); \ -+ __typeof__(x) __rgu_val; \ - __chk_user_ptr(ptr); \ -+ \ - uaccess_ttbr0_enable(); \ -- __raw_get_mem("ldtr", x, ptr, err); \ -+ __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, err); \ - uaccess_ttbr0_disable(); \ -+ \ -+ (x) = __rgu_val; \ - } while (0) - - #define __get_user_error(x, ptr, err) \ -@@ -321,14 +331,22 @@ do { \ - - #define get_user __get_user - -+/* -+ * We must not call into the scheduler between __uaccess_enable_tco_async() and -+ * __uaccess_disable_tco_async(). As `dst` and `src` may contain blocking -+ * functions, we must evaluate these outside of the critical section. -+ */ - #define __get_kernel_nofault(dst, src, type, err_label) \ - do { \ -+ __typeof__(dst) __gkn_dst = (dst); \ -+ __typeof__(src) __gkn_src = (src); \ - int __gkn_err = 0; \ - \ - __uaccess_enable_tco_async(); \ -- __raw_get_mem("ldr", *((type *)(dst)), \ -- (__force type *)(src), __gkn_err); \ -+ __raw_get_mem("ldr", *((type *)(__gkn_dst)), \ -+ (__force type *)(__gkn_src), __gkn_err); \ - __uaccess_disable_tco_async(); \ -+ \ - if (unlikely(__gkn_err)) \ - goto err_label; \ - } while (0) -@@ -367,11 +385,19 @@ do { \ - } \ - } while (0) - -+/* -+ * We must not call into the scheduler between uaccess_ttbr0_enable() and -+ * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, -+ * we must evaluate these outside of the critical section. -+ */ - #define __raw_put_user(x, ptr, err) \ - do { \ -- __chk_user_ptr(ptr); \ -+ __typeof__(*(ptr)) __user *__rpu_ptr = (ptr); \ -+ __typeof__(*(ptr)) __rpu_val = (x); \ -+ __chk_user_ptr(__rpu_ptr); \ -+ \ - uaccess_ttbr0_enable(); \ -- __raw_put_mem("sttr", x, ptr, err); \ -+ __raw_put_mem("sttr", __rpu_val, __rpu_ptr, err); \ - uaccess_ttbr0_disable(); \ - } while (0) - -@@ -396,14 +422,22 @@ do { \ - - #define put_user __put_user - -+/* -+ * We must not call into the scheduler between __uaccess_enable_tco_async() and -+ * __uaccess_disable_tco_async(). As `dst` and `src` may contain blocking -+ * functions, we must evaluate these outside of the critical section. -+ */ - #define __put_kernel_nofault(dst, src, type, err_label) \ - do { \ -+ __typeof__(dst) __pkn_dst = (dst); \ -+ __typeof__(src) __pkn_src = (src); \ - int __pkn_err = 0; \ - \ - __uaccess_enable_tco_async(); \ -- __raw_put_mem("str", *((type *)(src)), \ -- (__force type *)(dst), __pkn_err); \ -+ __raw_put_mem("str", *((type *)(__pkn_src)), \ -+ (__force type *)(__pkn_dst), __pkn_err); \ - __uaccess_disable_tco_async(); \ -+ \ - if (unlikely(__pkn_err)) \ - goto err_label; \ - } while(0) -diff --git a/arch/arm64/include/asm/vectors.h b/arch/arm64/include/asm/vectors.h -new file mode 100644 -index 0000000000000..f64613a96d530 ---- /dev/null -+++ b/arch/arm64/include/asm/vectors.h -@@ -0,0 +1,73 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (C) 2022 ARM Ltd. -+ */ -+#ifndef __ASM_VECTORS_H -+#define __ASM_VECTORS_H -+ -+#include -+#include -+ -+#include -+ -+extern char vectors[]; -+extern char tramp_vectors[]; -+extern char __bp_harden_el1_vectors[]; -+ -+/* -+ * Note: the order of this enum corresponds to two arrays in entry.S: -+ * tramp_vecs and __bp_harden_el1_vectors. By default the canonical -+ * 'full fat' vectors are used directly. -+ */ -+enum arm64_bp_harden_el1_vectors { -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+ /* -+ * Perform the BHB loop mitigation, before branching to the canonical -+ * vectors. -+ */ -+ EL1_VECTOR_BHB_LOOP, -+ -+ /* -+ * Make the SMC call for firmware mitigation, before branching to the -+ * canonical vectors. -+ */ -+ EL1_VECTOR_BHB_FW, -+ -+ /* -+ * Use the ClearBHB instruction, before branching to the canonical -+ * vectors. -+ */ -+ EL1_VECTOR_BHB_CLEAR_INSN, -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ -+ /* -+ * Remap the kernel before branching to the canonical vectors. -+ */ -+ EL1_VECTOR_KPTI, -+}; -+ -+#ifndef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+#define EL1_VECTOR_BHB_LOOP -1 -+#define EL1_VECTOR_BHB_FW -1 -+#define EL1_VECTOR_BHB_CLEAR_INSN -1 -+#endif /* !CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ -+/* The vectors to use on return from EL0. e.g. to remap the kernel */ -+DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector); -+ -+#ifndef CONFIG_UNMAP_KERNEL_AT_EL0 -+#define TRAMP_VALIAS 0 -+#endif -+ -+static inline const char * -+arm64_get_bp_hardening_vector(enum arm64_bp_harden_el1_vectors slot) -+{ -+ if (arm64_kernel_unmapped_at_el0()) -+ return (char *)TRAMP_VALIAS + SZ_2K * slot; -+ -+ WARN_ON_ONCE(slot == EL1_VECTOR_KPTI); -+ -+ return __bp_harden_el1_vectors + SZ_2K * slot; -+} -+ -+#endif /* __ASM_VECTORS_H */ -diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h -index b8f41aa234ee1..f03731847d9df 100644 ---- a/arch/arm64/include/uapi/asm/hwcap.h -+++ b/arch/arm64/include/uapi/asm/hwcap.h -@@ -75,5 +75,8 @@ - #define HWCAP2_RNG (1 << 16) - #define HWCAP2_BTI (1 << 17) - #define HWCAP2_MTE (1 << 18) -+#define HWCAP2_ECV (1 << 19) -+#define HWCAP2_AFP (1 << 20) -+#define HWCAP2_RPRES (1 << 21) - - #endif /* _UAPI__ASM_HWCAP_H */ -diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h -index b3edde68bc3e0..323e251ed37bc 100644 ---- a/arch/arm64/include/uapi/asm/kvm.h -+++ b/arch/arm64/include/uapi/asm/kvm.h -@@ -281,6 +281,11 @@ struct kvm_arm_copy_mte_tags { - #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 - #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4) - -+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 KVM_REG_ARM_FW_REG(3) -+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL 0 -+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL 1 -+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED 2 -+ - /* SVE registers */ - #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) - -diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c -index e2c20c036442f..a33d7b8f3b935 100644 ---- a/arch/arm64/kernel/cpu_errata.c -+++ b/arch/arm64/kernel/cpu_errata.c -@@ -464,6 +464,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { - .matches = has_spectre_v4, - .cpu_enable = spectre_v4_enable_mitigation, - }, -+ { -+ .desc = "Spectre-BHB", -+ .capability = ARM64_SPECTRE_BHB, -+ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, -+ .matches = is_spectre_bhb_affected, -+ .cpu_enable = spectre_bhb_enable_mitigation, -+ }, - #ifdef CONFIG_ARM64_ERRATUM_1418040 - { - .desc = "ARM erratum 1418040", -diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index 6ec7036ef7e18..e71c9cfb46e8c 100644 ---- a/arch/arm64/kernel/cpufeature.c -+++ b/arch/arm64/kernel/cpufeature.c -@@ -73,6 +73,8 @@ - #include - #include - #include -+#include -+ - #include - #include - #include -@@ -85,6 +87,7 @@ - #include - #include - #include -+#include - #include - - /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ -@@ -110,6 +113,8 @@ DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE); - bool arm64_use_ng_mappings = false; - EXPORT_SYMBOL(arm64_use_ng_mappings); - -+DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors; -+ - /* - * Permit PER_LINUX32 and execve() of 32-bit binaries even if not all CPUs - * support it? -@@ -225,6 +230,12 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { - ARM64_FTR_END, - }; - -+static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { -+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_CLEARBHB_SHIFT, 4, 0), -+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_RPRES_SHIFT, 4, 0), -+ ARM64_FTR_END, -+}; -+ - static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { - ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV2_SHIFT, 4, 0), -@@ -279,7 +290,7 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { - }; - - static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { -- ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0), -+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_FGT_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_EXS_SHIFT, 4, 0), - /* -@@ -325,6 +336,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { - }; - - static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { -+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_AFP_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_ETS_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TWED_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_XNX_SHIFT, 4, 0), -@@ -573,15 +585,19 @@ static const struct arm64_ftr_bits ftr_raz[] = { - ARM64_FTR_END, - }; - --#define ARM64_FTR_REG_OVERRIDE(id, table, ovr) { \ -+#define __ARM64_FTR_REG_OVERRIDE(id_str, id, table, ovr) { \ - .sys_id = id, \ - .reg = &(struct arm64_ftr_reg){ \ -- .name = #id, \ -+ .name = id_str, \ - .override = (ovr), \ - .ftr_bits = &((table)[0]), \ - }} - --#define ARM64_FTR_REG(id, table) ARM64_FTR_REG_OVERRIDE(id, table, &no_override) -+#define ARM64_FTR_REG_OVERRIDE(id, table, ovr) \ -+ __ARM64_FTR_REG_OVERRIDE(#id, id, table, ovr) -+ -+#define ARM64_FTR_REG(id, table) \ -+ __ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override) - - struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override; - struct arm64_ftr_override __ro_after_init id_aa64pfr1_override; -@@ -633,6 +649,7 @@ static const struct __ftr_reg_entry { - ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0), - ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1, - &id_aa64isar1_override), -+ ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2), - - /* Op1 = 0, CRn = 0, CRm = 7 */ - ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0), -@@ -929,6 +946,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) - init_cpu_ftr_reg(SYS_ID_AA64DFR1_EL1, info->reg_id_aa64dfr1); - init_cpu_ftr_reg(SYS_ID_AA64ISAR0_EL1, info->reg_id_aa64isar0); - init_cpu_ftr_reg(SYS_ID_AA64ISAR1_EL1, info->reg_id_aa64isar1); -+ init_cpu_ftr_reg(SYS_ID_AA64ISAR2_EL1, info->reg_id_aa64isar2); - init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0); - init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1); - init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2); -@@ -1147,6 +1165,8 @@ void update_cpu_features(int cpu, - info->reg_id_aa64isar0, boot->reg_id_aa64isar0); - taint |= check_update_ftr_reg(SYS_ID_AA64ISAR1_EL1, cpu, - info->reg_id_aa64isar1, boot->reg_id_aa64isar1); -+ taint |= check_update_ftr_reg(SYS_ID_AA64ISAR2_EL1, cpu, -+ info->reg_id_aa64isar2, boot->reg_id_aa64isar2); - - /* - * Differing PARange support is fine as long as all peripherals and -@@ -1268,6 +1288,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id) - read_sysreg_case(SYS_ID_AA64MMFR2_EL1); - read_sysreg_case(SYS_ID_AA64ISAR0_EL1); - read_sysreg_case(SYS_ID_AA64ISAR1_EL1); -+ read_sysreg_case(SYS_ID_AA64ISAR2_EL1); - - read_sysreg_case(SYS_CNTFRQ_EL0); - read_sysreg_case(SYS_CTR_EL0); -@@ -1575,6 +1596,12 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused) - - int cpu = smp_processor_id(); - -+ if (__this_cpu_read(this_cpu_vector) == vectors) { -+ const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI); -+ -+ __this_cpu_write(this_cpu_vector, v); -+ } -+ - /* - * We don't need to rewrite the page-tables if either we've done - * it already or we have KASLR enabled and therefore have not -@@ -2451,6 +2478,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { - #ifdef CONFIG_ARM64_MTE - HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE), - #endif /* CONFIG_ARM64_MTE */ -+ HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV), -+ HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP), -+ HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES), - {}, - }; - -diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c -index 87731fea5e418..591c18a889a56 100644 ---- a/arch/arm64/kernel/cpuinfo.c -+++ b/arch/arm64/kernel/cpuinfo.c -@@ -94,6 +94,9 @@ static const char *const hwcap_str[] = { - [KERNEL_HWCAP_RNG] = "rng", - [KERNEL_HWCAP_BTI] = "bti", - [KERNEL_HWCAP_MTE] = "mte", -+ [KERNEL_HWCAP_ECV] = "ecv", -+ [KERNEL_HWCAP_AFP] = "afp", -+ [KERNEL_HWCAP_RPRES] = "rpres", - }; - - #ifdef CONFIG_COMPAT -@@ -390,6 +393,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) - info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1); - info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1); - info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1); -+ info->reg_id_aa64isar2 = read_cpuid(ID_AA64ISAR2_EL1); - info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); - info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); - info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1); -diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S -index b3e4f9a088b1a..8cf970d219f5d 100644 ---- a/arch/arm64/kernel/entry-ftrace.S -+++ b/arch/arm64/kernel/entry-ftrace.S -@@ -77,11 +77,17 @@ - .endm - - SYM_CODE_START(ftrace_regs_caller) -+#ifdef BTI_C -+ BTI_C -+#endif - ftrace_regs_entry 1 - b ftrace_common - SYM_CODE_END(ftrace_regs_caller) - - SYM_CODE_START(ftrace_caller) -+#ifdef BTI_C -+ BTI_C -+#endif - ftrace_regs_entry 0 - b ftrace_common - SYM_CODE_END(ftrace_caller) -diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index bc6d5a970a131..34e38eb00f056 100644 ---- a/arch/arm64/kernel/entry.S -+++ b/arch/arm64/kernel/entry.S -@@ -37,18 +37,21 @@ - - .macro kernel_ventry, el:req, ht:req, regsize:req, label:req - .align 7 --#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -+.Lventry_start\@: - .if \el == 0 --alternative_if ARM64_UNMAP_KERNEL_AT_EL0 -+ /* -+ * This must be the first instruction of the EL0 vector entries. It is -+ * skipped by the trampoline vectors, to trigger the cleanup. -+ */ -+ b .Lskip_tramp_vectors_cleanup\@ - .if \regsize == 64 - mrs x30, tpidrro_el0 - msr tpidrro_el0, xzr - .else - mov x30, xzr - .endif --alternative_else_nop_endif -+.Lskip_tramp_vectors_cleanup\@: - .endif --#endif - - sub sp, sp, #PT_REGS_SIZE - #ifdef CONFIG_VMAP_STACK -@@ -95,11 +98,15 @@ alternative_else_nop_endif - mrs x0, tpidrro_el0 - #endif - b el\el\ht\()_\regsize\()_\label -+.org .Lventry_start\@ + 128 // Did we overflow the ventry slot? - .endm - -- .macro tramp_alias, dst, sym -+ .macro tramp_alias, dst, sym, tmp - mov_q \dst, TRAMP_VALIAS -- add \dst, \dst, #(\sym - .entry.tramp.text) -+ adr_l \tmp, \sym -+ add \dst, \dst, \tmp -+ adr_l \tmp, .entry.tramp.text -+ sub \dst, \dst, \tmp - .endm - - /* -@@ -116,7 +123,7 @@ alternative_cb_end - tbnz \tmp2, #TIF_SSBD, .L__asm_ssbd_skip\@ - mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2 - mov w1, #\state --alternative_cb spectre_v4_patch_fw_mitigation_conduit -+alternative_cb smccc_patch_fw_mitigation_conduit - nop // Patched to SMC/HVC #0 - alternative_cb_end - .L__asm_ssbd_skip\@: -@@ -413,21 +420,26 @@ alternative_else_nop_endif - ldp x24, x25, [sp, #16 * 12] - ldp x26, x27, [sp, #16 * 13] - ldp x28, x29, [sp, #16 * 14] -- ldr lr, [sp, #S_LR] -- add sp, sp, #PT_REGS_SIZE // restore sp - - .if \el == 0 --alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 -+alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 -+ ldr lr, [sp, #S_LR] -+ add sp, sp, #PT_REGS_SIZE // restore sp -+ eret -+alternative_else_nop_endif - #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 - bne 4f -- msr far_el1, x30 -- tramp_alias x30, tramp_exit_native -+ msr far_el1, x29 -+ tramp_alias x30, tramp_exit_native, x29 - br x30 - 4: -- tramp_alias x30, tramp_exit_compat -+ tramp_alias x30, tramp_exit_compat, x29 - br x30 - #endif - .else -+ ldr lr, [sp, #S_LR] -+ add sp, sp, #PT_REGS_SIZE // restore sp -+ - /* Ensure any device/NC reads complete */ - alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412 - -@@ -594,12 +606,6 @@ SYM_CODE_END(ret_to_user) - - .popsection // .entry.text - --#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 --/* -- * Exception vectors trampoline. -- */ -- .pushsection ".entry.tramp.text", "ax" -- - // Move from tramp_pg_dir to swapper_pg_dir - .macro tramp_map_kernel, tmp - mrs \tmp, ttbr1_el1 -@@ -633,12 +639,47 @@ alternative_else_nop_endif - */ - .endm - -- .macro tramp_ventry, regsize = 64 -+ .macro tramp_data_page dst -+ adr_l \dst, .entry.tramp.text -+ sub \dst, \dst, PAGE_SIZE -+ .endm -+ -+ .macro tramp_data_read_var dst, var -+#ifdef CONFIG_RANDOMIZE_BASE -+ tramp_data_page \dst -+ add \dst, \dst, #:lo12:__entry_tramp_data_\var -+ ldr \dst, [\dst] -+#else -+ ldr \dst, =\var -+#endif -+ .endm -+ -+#define BHB_MITIGATION_NONE 0 -+#define BHB_MITIGATION_LOOP 1 -+#define BHB_MITIGATION_FW 2 -+#define BHB_MITIGATION_INSN 3 -+ -+ .macro tramp_ventry, vector_start, regsize, kpti, bhb - .align 7 - 1: - .if \regsize == 64 - msr tpidrro_el0, x30 // Restored in kernel_ventry - .endif -+ -+ .if \bhb == BHB_MITIGATION_LOOP -+ /* -+ * This sequence must appear before the first indirect branch. i.e. the -+ * ret out of tramp_ventry. It appears here because x30 is free. -+ */ -+ __mitigate_spectre_bhb_loop x30 -+ .endif // \bhb == BHB_MITIGATION_LOOP -+ -+ .if \bhb == BHB_MITIGATION_INSN -+ clearbhb -+ isb -+ .endif // \bhb == BHB_MITIGATION_INSN -+ -+ .if \kpti == 1 - /* - * Defend against branch aliasing attacks by pushing a dummy - * entry onto the return stack and using a RET instruction to -@@ -648,46 +689,75 @@ alternative_else_nop_endif - b . - 2: - tramp_map_kernel x30 --#ifdef CONFIG_RANDOMIZE_BASE -- adr x30, tramp_vectors + PAGE_SIZE - alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003 -- ldr x30, [x30] --#else -- ldr x30, =vectors --#endif -+ tramp_data_read_var x30, vectors - alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM -- prfm plil1strm, [x30, #(1b - tramp_vectors)] -+ prfm plil1strm, [x30, #(1b - \vector_start)] - alternative_else_nop_endif -+ - msr vbar_el1, x30 -- add x30, x30, #(1b - tramp_vectors) - isb -+ .else -+ ldr x30, =vectors -+ .endif // \kpti == 1 -+ -+ .if \bhb == BHB_MITIGATION_FW -+ /* -+ * The firmware sequence must appear before the first indirect branch. -+ * i.e. the ret out of tramp_ventry. But it also needs the stack to be -+ * mapped to save/restore the registers the SMC clobbers. -+ */ -+ __mitigate_spectre_bhb_fw -+ .endif // \bhb == BHB_MITIGATION_FW -+ -+ add x30, x30, #(1b - \vector_start + 4) - ret -+.org 1b + 128 // Did we overflow the ventry slot? - .endm - - .macro tramp_exit, regsize = 64 -- adr x30, tramp_vectors -+ tramp_data_read_var x30, this_cpu_vector -+ get_this_cpu_offset x29 -+ ldr x30, [x30, x29] -+ - msr vbar_el1, x30 -- tramp_unmap_kernel x30 -+ ldr lr, [sp, #S_LR] -+ tramp_unmap_kernel x29 - .if \regsize == 64 -- mrs x30, far_el1 -+ mrs x29, far_el1 - .endif -+ add sp, sp, #PT_REGS_SIZE // restore sp - eret - sb - .endm - -- .align 11 --SYM_CODE_START_NOALIGN(tramp_vectors) -+ .macro generate_tramp_vector, kpti, bhb -+.Lvector_start\@: - .space 0x400 - -- tramp_ventry -- tramp_ventry -- tramp_ventry -- tramp_ventry -+ .rept 4 -+ tramp_ventry .Lvector_start\@, 64, \kpti, \bhb -+ .endr -+ .rept 4 -+ tramp_ventry .Lvector_start\@, 32, \kpti, \bhb -+ .endr -+ .endm - -- tramp_ventry 32 -- tramp_ventry 32 -- tramp_ventry 32 -- tramp_ventry 32 -+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -+/* -+ * Exception vectors trampoline. -+ * The order must match __bp_harden_el1_vectors and the -+ * arm64_bp_harden_el1_vectors enum. -+ */ -+ .pushsection ".entry.tramp.text", "ax" -+ .align 11 -+SYM_CODE_START_NOALIGN(tramp_vectors) -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_LOOP -+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_FW -+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_INSN -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_NONE - SYM_CODE_END(tramp_vectors) - - SYM_CODE_START(tramp_exit_native) -@@ -704,12 +774,56 @@ SYM_CODE_END(tramp_exit_compat) - .pushsection ".rodata", "a" - .align PAGE_SHIFT - SYM_DATA_START(__entry_tramp_data_start) -+__entry_tramp_data_vectors: - .quad vectors -+#ifdef CONFIG_ARM_SDE_INTERFACE -+__entry_tramp_data___sdei_asm_handler: -+ .quad __sdei_asm_handler -+#endif /* CONFIG_ARM_SDE_INTERFACE */ -+__entry_tramp_data_this_cpu_vector: -+ .quad this_cpu_vector - SYM_DATA_END(__entry_tramp_data_start) - .popsection // .rodata - #endif /* CONFIG_RANDOMIZE_BASE */ - #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ - -+/* -+ * Exception vectors for spectre mitigations on entry from EL1 when -+ * kpti is not in use. -+ */ -+ .macro generate_el1_vector, bhb -+.Lvector_start\@: -+ kernel_ventry 1, t, 64, sync // Synchronous EL1t -+ kernel_ventry 1, t, 64, irq // IRQ EL1t -+ kernel_ventry 1, t, 64, fiq // FIQ EL1h -+ kernel_ventry 1, t, 64, error // Error EL1t -+ -+ kernel_ventry 1, h, 64, sync // Synchronous EL1h -+ kernel_ventry 1, h, 64, irq // IRQ EL1h -+ kernel_ventry 1, h, 64, fiq // FIQ EL1h -+ kernel_ventry 1, h, 64, error // Error EL1h -+ -+ .rept 4 -+ tramp_ventry .Lvector_start\@, 64, 0, \bhb -+ .endr -+ .rept 4 -+ tramp_ventry .Lvector_start\@, 32, 0, \bhb -+ .endr -+ .endm -+ -+/* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */ -+ .pushsection ".entry.text", "ax" -+ .align 11 -+SYM_CODE_START(__bp_harden_el1_vectors) -+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY -+ generate_el1_vector bhb=BHB_MITIGATION_LOOP -+ generate_el1_vector bhb=BHB_MITIGATION_FW -+ generate_el1_vector bhb=BHB_MITIGATION_INSN -+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ -+SYM_CODE_END(__bp_harden_el1_vectors) -+ .popsection -+ -+ - /* - * Register switch for AArch64. The callee-saved registers need to be saved - * and restored. On entry: -@@ -835,14 +949,7 @@ SYM_CODE_START(__sdei_asm_entry_trampoline) - * Remember whether to unmap the kernel on exit. - */ - 1: str x4, [x1, #(SDEI_EVENT_INTREGS + S_SDEI_TTBR1)] -- --#ifdef CONFIG_RANDOMIZE_BASE -- adr x4, tramp_vectors + PAGE_SIZE -- add x4, x4, #:lo12:__sdei_asm_trampoline_next_handler -- ldr x4, [x4] --#else -- ldr x4, =__sdei_asm_handler --#endif -+ tramp_data_read_var x4, __sdei_asm_handler - br x4 - SYM_CODE_END(__sdei_asm_entry_trampoline) - NOKPROBE(__sdei_asm_entry_trampoline) -@@ -865,13 +972,6 @@ SYM_CODE_END(__sdei_asm_exit_trampoline) - NOKPROBE(__sdei_asm_exit_trampoline) - .ltorg - .popsection // .entry.tramp.text --#ifdef CONFIG_RANDOMIZE_BASE --.pushsection ".rodata", "a" --SYM_DATA_START(__sdei_asm_trampoline_next_handler) -- .quad __sdei_asm_handler --SYM_DATA_END(__sdei_asm_trampoline_next_handler) --.popsection // .rodata --#endif /* CONFIG_RANDOMIZE_BASE */ - #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ - - /* -@@ -979,7 +1079,7 @@ alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 - alternative_else_nop_endif - - #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -- tramp_alias dst=x5, sym=__sdei_asm_exit_trampoline -+ tramp_alias dst=x5, sym=__sdei_asm_exit_trampoline, tmp=x3 - br x5 - #endif - SYM_CODE_END(__sdei_asm_handler) -diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h -index c96a9a0043bf4..e03e60f9482b4 100644 ---- a/arch/arm64/kernel/image-vars.h -+++ b/arch/arm64/kernel/image-vars.h -@@ -66,6 +66,10 @@ KVM_NVHE_ALIAS(kvm_patch_vector_branch); - KVM_NVHE_ALIAS(kvm_update_va_mask); - KVM_NVHE_ALIAS(kvm_get_kimage_voffset); - KVM_NVHE_ALIAS(kvm_compute_final_ctr_el0); -+KVM_NVHE_ALIAS(spectre_bhb_patch_loop_iter); -+KVM_NVHE_ALIAS(spectre_bhb_patch_loop_mitigation_enable); -+KVM_NVHE_ALIAS(spectre_bhb_patch_wa3); -+KVM_NVHE_ALIAS(spectre_bhb_patch_clearbhb); - - /* Global kernel state accessed by nVHE hyp code. */ - KVM_NVHE_ALIAS(kvm_vgic_global_state); -diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c -index 63634b4d72c15..59c648d518488 100644 ---- a/arch/arm64/kernel/machine_kexec_file.c -+++ b/arch/arm64/kernel/machine_kexec_file.c -@@ -149,6 +149,7 @@ int load_other_segments(struct kimage *image, - initrd_len, cmdline, 0); - if (!dtb) { - pr_err("Preparing for new dtb failed\n"); -+ ret = -EINVAL; - goto out_err; - } - -diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c -index b5ec010c481f3..309a27553c875 100644 ---- a/arch/arm64/kernel/module.c -+++ b/arch/arm64/kernel/module.c -@@ -36,7 +36,7 @@ void *module_alloc(unsigned long size) - module_alloc_end = MODULES_END; - - p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base, -- module_alloc_end, gfp_mask, PAGE_KERNEL, 0, -+ module_alloc_end, gfp_mask, PAGE_KERNEL, VM_DEFER_KMEMLEAK, - NUMA_NO_NODE, __builtin_return_address(0)); - - if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && -@@ -58,7 +58,7 @@ void *module_alloc(unsigned long size) - PAGE_KERNEL, 0, NUMA_NO_NODE, - __builtin_return_address(0)); - -- if (p && (kasan_module_alloc(p, size) < 0)) { -+ if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) { - vfree(p); - return NULL; - } -diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c -index 4a72c27273097..86d9f20131723 100644 ---- a/arch/arm64/kernel/perf_callchain.c -+++ b/arch/arm64/kernel/perf_callchain.c -@@ -102,7 +102,9 @@ compat_user_backtrace(struct compat_frame_tail __user *tail, - void perf_callchain_user(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); -+ -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* We don't support guest os callchain now */ - return; - } -@@ -147,9 +149,10 @@ static bool callchain_trace(void *data, unsigned long pc) - void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct stackframe frame; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* We don't support guest os callchain now */ - return; - } -@@ -160,18 +163,21 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - - unsigned long perf_instruction_pointer(struct pt_regs *regs) - { -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) -- return perf_guest_cbs->get_guest_ip(); -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); -+ -+ if (guest_cbs && guest_cbs->is_in_guest()) -+ return guest_cbs->get_guest_ip(); - - return instruction_pointer(regs); - } - - unsigned long perf_misc_flags(struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - int misc = 0; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -- if (perf_guest_cbs->is_user_mode()) -+ if (guest_cbs && guest_cbs->is_in_guest()) { -+ if (guest_cbs->is_user_mode()) - misc |= PERF_RECORD_MISC_GUEST_USER; - else - misc |= PERF_RECORD_MISC_GUEST_KERNEL; -diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c -index 40adb8cdbf5af..23efabcb00b85 100644 ---- a/arch/arm64/kernel/process.c -+++ b/arch/arm64/kernel/process.c -@@ -439,34 +439,26 @@ static void entry_task_switch(struct task_struct *next) - - /* - * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT. -- * Assuming the virtual counter is enabled at the beginning of times: -- * -- * - disable access when switching from a 64bit task to a 32bit task -- * - enable access when switching from a 32bit task to a 64bit task -+ * Ensure access is disabled when switching to a 32bit task, ensure -+ * access is enabled when switching to a 64bit task. - */ --static void erratum_1418040_thread_switch(struct task_struct *prev, -- struct task_struct *next) -+static void erratum_1418040_thread_switch(struct task_struct *next) - { -- bool prev32, next32; -- u64 val; -- -- if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) -- return; -- -- prev32 = is_compat_thread(task_thread_info(prev)); -- next32 = is_compat_thread(task_thread_info(next)); -- -- if (prev32 == next32 || !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) -+ if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) || -+ !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) - return; - -- val = read_sysreg(cntkctl_el1); -- -- if (!next32) -- val |= ARCH_TIMER_USR_VCT_ACCESS_EN; -+ if (is_compat_thread(task_thread_info(next))) -+ sysreg_clear_set(cntkctl_el1, ARCH_TIMER_USR_VCT_ACCESS_EN, 0); - else -- val &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; -+ sysreg_clear_set(cntkctl_el1, 0, ARCH_TIMER_USR_VCT_ACCESS_EN); -+} - -- write_sysreg(val, cntkctl_el1); -+static void erratum_1418040_new_exec(void) -+{ -+ preempt_disable(); -+ erratum_1418040_thread_switch(current); -+ preempt_enable(); - } - - /* -@@ -501,7 +493,7 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, - contextidr_thread_switch(next); - entry_task_switch(next); - ssbs_thread_switch(next); -- erratum_1418040_thread_switch(prev, next); -+ erratum_1418040_thread_switch(next); - ptrauth_thread_switch_user(next); - - /* -@@ -613,6 +605,7 @@ void arch_setup_new_exec(void) - current->mm->context.flags = mmflags; - ptrauth_thread_init_user(); - mte_thread_init_user(); -+ erratum_1418040_new_exec(); - - if (task_spec_ssb_noexec(current)) { - arch_prctl_spec_ctrl_set(current, PR_SPEC_STORE_BYPASS, -diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c -index 902e4084c4775..6d45c63c64548 100644 ---- a/arch/arm64/kernel/proton-pack.c -+++ b/arch/arm64/kernel/proton-pack.c -@@ -18,15 +18,18 @@ - */ - - #include -+#include - #include - #include - #include - #include - #include - -+#include - #include - #include - #include -+#include - #include - - /* -@@ -96,14 +99,51 @@ static bool spectre_v2_mitigations_off(void) - return ret; - } - -+static const char *get_bhb_affected_string(enum mitigation_state bhb_state) -+{ -+ switch (bhb_state) { -+ case SPECTRE_UNAFFECTED: -+ return ""; -+ default: -+ case SPECTRE_VULNERABLE: -+ return ", but not BHB"; -+ case SPECTRE_MITIGATED: -+ return ", BHB"; -+ } -+} -+ -+static bool _unprivileged_ebpf_enabled(void) -+{ -+#ifdef CONFIG_BPF_SYSCALL -+ return !sysctl_unprivileged_bpf_disabled; -+#else -+ return false; -+#endif -+} -+ - ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, - char *buf) - { -+ enum mitigation_state bhb_state = arm64_get_spectre_bhb_state(); -+ const char *bhb_str = get_bhb_affected_string(bhb_state); -+ const char *v2_str = "Branch predictor hardening"; -+ - switch (spectre_v2_state) { - case SPECTRE_UNAFFECTED: -- return sprintf(buf, "Not affected\n"); -+ if (bhb_state == SPECTRE_UNAFFECTED) -+ return sprintf(buf, "Not affected\n"); -+ -+ /* -+ * Platforms affected by Spectre-BHB can't report -+ * "Not affected" for Spectre-v2. -+ */ -+ v2_str = "CSV2"; -+ fallthrough; - case SPECTRE_MITIGATED: -- return sprintf(buf, "Mitigation: Branch predictor hardening\n"); -+ if (bhb_state == SPECTRE_MITIGATED && _unprivileged_ebpf_enabled()) -+ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); -+ -+ return sprintf(buf, "Mitigation: %s%s\n", v2_str, bhb_str); - case SPECTRE_VULNERABLE: - fallthrough; - default: -@@ -554,9 +594,9 @@ void __init spectre_v4_patch_fw_mitigation_enable(struct alt_instr *alt, - * Patch a NOP in the Spectre-v4 mitigation code with an SMC/HVC instruction - * to call into firmware to adjust the mitigation state. - */ --void __init spectre_v4_patch_fw_mitigation_conduit(struct alt_instr *alt, -- __le32 *origptr, -- __le32 *updptr, int nr_inst) -+void __init smccc_patch_fw_mitigation_conduit(struct alt_instr *alt, -+ __le32 *origptr, -+ __le32 *updptr, int nr_inst) - { - u32 insn; - -@@ -770,3 +810,344 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) - return -ENODEV; - } - } -+ -+/* -+ * Spectre BHB. -+ * -+ * A CPU is either: -+ * - Mitigated by a branchy loop a CPU specific number of times, and listed -+ * in our "loop mitigated list". -+ * - Mitigated in software by the firmware Spectre v2 call. -+ * - Has the ClearBHB instruction to perform the mitigation. -+ * - Has the 'Exception Clears Branch History Buffer' (ECBHB) feature, so no -+ * software mitigation in the vectors is needed. -+ * - Has CSV2.3, so is unaffected. -+ */ -+static enum mitigation_state spectre_bhb_state; -+ -+enum mitigation_state arm64_get_spectre_bhb_state(void) -+{ -+ return spectre_bhb_state; -+} -+ -+enum bhb_mitigation_bits { -+ BHB_LOOP, -+ BHB_FW, -+ BHB_HW, -+ BHB_INSN, -+}; -+static unsigned long system_bhb_mitigations; -+ -+/* -+ * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any -+ * SCOPE_SYSTEM call will give the right answer. -+ */ -+u8 spectre_bhb_loop_affected(int scope) -+{ -+ u8 k = 0; -+ static u8 max_bhb_k; -+ -+ if (scope == SCOPE_LOCAL_CPU) { -+ static const struct midr_range spectre_bhb_k32_list[] = { -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), -+ {}, -+ }; -+ static const struct midr_range spectre_bhb_k24_list[] = { -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), -+ {}, -+ }; -+ static const struct midr_range spectre_bhb_k8_list[] = { -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), -+ {}, -+ }; -+ -+ if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list)) -+ k = 32; -+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list)) -+ k = 24; -+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list)) -+ k = 8; -+ -+ max_bhb_k = max(max_bhb_k, k); -+ } else { -+ k = max_bhb_k; -+ } -+ -+ return k; -+} -+ -+static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void) -+{ -+ int ret; -+ struct arm_smccc_res res; -+ -+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, -+ ARM_SMCCC_ARCH_WORKAROUND_3, &res); -+ -+ ret = res.a0; -+ switch (ret) { -+ case SMCCC_RET_SUCCESS: -+ return SPECTRE_MITIGATED; -+ case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: -+ return SPECTRE_UNAFFECTED; -+ default: -+ fallthrough; -+ case SMCCC_RET_NOT_SUPPORTED: -+ return SPECTRE_VULNERABLE; -+ } -+} -+ -+static bool is_spectre_bhb_fw_affected(int scope) -+{ -+ static bool system_affected; -+ enum mitigation_state fw_state; -+ bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE; -+ static const struct midr_range spectre_bhb_firmware_mitigated_list[] = { -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A75), -+ {}, -+ }; -+ bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(), -+ spectre_bhb_firmware_mitigated_list); -+ -+ if (scope != SCOPE_LOCAL_CPU) -+ return system_affected; -+ -+ fw_state = spectre_bhb_get_cpu_fw_mitigation_state(); -+ if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) { -+ system_affected = true; -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool supports_ecbhb(int scope) -+{ -+ u64 mmfr1; -+ -+ if (scope == SCOPE_LOCAL_CPU) -+ mmfr1 = read_sysreg_s(SYS_ID_AA64MMFR1_EL1); -+ else -+ mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); -+ -+ return cpuid_feature_extract_unsigned_field(mmfr1, -+ ID_AA64MMFR1_ECBHB_SHIFT); -+} -+ -+bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, -+ int scope) -+{ -+ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); -+ -+ if (supports_csv2p3(scope)) -+ return false; -+ -+ if (supports_clearbhb(scope)) -+ return true; -+ -+ if (spectre_bhb_loop_affected(scope)) -+ return true; -+ -+ if (is_spectre_bhb_fw_affected(scope)) -+ return true; -+ -+ return false; -+} -+ -+static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) -+{ -+ const char *v = arm64_get_bp_hardening_vector(slot); -+ -+ if (slot < 0) -+ return; -+ -+ __this_cpu_write(this_cpu_vector, v); -+ -+ /* -+ * When KPTI is in use, the vectors are switched when exiting to -+ * user-space. -+ */ -+ if (arm64_kernel_unmapped_at_el0()) -+ return; -+ -+ write_sysreg(v, vbar_el1); -+ isb(); -+} -+ -+void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry) -+{ -+ bp_hardening_cb_t cpu_cb; -+ enum mitigation_state fw_state, state = SPECTRE_VULNERABLE; -+ struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data); -+ -+ if (!is_spectre_bhb_affected(entry, SCOPE_LOCAL_CPU)) -+ return; -+ -+ if (arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) { -+ /* No point mitigating Spectre-BHB alone. */ -+ } else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) { -+ pr_info_once("spectre-bhb mitigation disabled by compile time option\n"); -+ } else if (cpu_mitigations_off()) { -+ pr_info_once("spectre-bhb mitigation disabled by command line option\n"); -+ } else if (supports_ecbhb(SCOPE_LOCAL_CPU)) { -+ state = SPECTRE_MITIGATED; -+ set_bit(BHB_HW, &system_bhb_mitigations); -+ } else if (supports_clearbhb(SCOPE_LOCAL_CPU)) { -+ /* -+ * Ensure KVM uses the indirect vector which will have ClearBHB -+ * added. -+ */ -+ if (!data->slot) -+ data->slot = HYP_VECTOR_INDIRECT; -+ -+ this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN); -+ state = SPECTRE_MITIGATED; -+ set_bit(BHB_INSN, &system_bhb_mitigations); -+ } else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) { -+ /* -+ * Ensure KVM uses the indirect vector which will have the -+ * branchy-loop added. A57/A72-r0 will already have selected -+ * the spectre-indirect vector, which is sufficient for BHB -+ * too. -+ */ -+ if (!data->slot) -+ data->slot = HYP_VECTOR_INDIRECT; -+ -+ this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP); -+ state = SPECTRE_MITIGATED; -+ set_bit(BHB_LOOP, &system_bhb_mitigations); -+ } else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) { -+ fw_state = spectre_bhb_get_cpu_fw_mitigation_state(); -+ if (fw_state == SPECTRE_MITIGATED) { -+ /* -+ * Ensure KVM uses one of the spectre bp_hardening -+ * vectors. The indirect vector doesn't include the EL3 -+ * call, so needs upgrading to -+ * HYP_VECTOR_SPECTRE_INDIRECT. -+ */ -+ if (!data->slot || data->slot == HYP_VECTOR_INDIRECT) -+ data->slot += 1; -+ -+ this_cpu_set_vectors(EL1_VECTOR_BHB_FW); -+ -+ /* -+ * The WA3 call in the vectors supersedes the WA1 call -+ * made during context-switch. Uninstall any firmware -+ * bp_hardening callback. -+ */ -+ cpu_cb = spectre_v2_get_sw_mitigation_cb(); -+ if (__this_cpu_read(bp_hardening_data.fn) != cpu_cb) -+ __this_cpu_write(bp_hardening_data.fn, NULL); -+ -+ state = SPECTRE_MITIGATED; -+ set_bit(BHB_FW, &system_bhb_mitigations); -+ } -+ } -+ -+ update_mitigation_state(&spectre_bhb_state, state); -+} -+ -+/* Patched to NOP when enabled */ -+void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt, -+ __le32 *origptr, -+ __le32 *updptr, int nr_inst) -+{ -+ BUG_ON(nr_inst != 1); -+ -+ if (test_bit(BHB_LOOP, &system_bhb_mitigations)) -+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop()); -+} -+ -+/* Patched to NOP when enabled */ -+void noinstr spectre_bhb_patch_fw_mitigation_enabled(struct alt_instr *alt, -+ __le32 *origptr, -+ __le32 *updptr, int nr_inst) -+{ -+ BUG_ON(nr_inst != 1); -+ -+ if (test_bit(BHB_FW, &system_bhb_mitigations)) -+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop()); -+} -+ -+/* Patched to correct the immediate */ -+void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt, -+ __le32 *origptr, __le32 *updptr, int nr_inst) -+{ -+ u8 rd; -+ u32 insn; -+ u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM); -+ -+ BUG_ON(nr_inst != 1); /* MOV -> MOV */ -+ -+ if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) -+ return; -+ -+ insn = le32_to_cpu(*origptr); -+ rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn); -+ insn = aarch64_insn_gen_movewide(rd, loop_count, 0, -+ AARCH64_INSN_VARIANT_64BIT, -+ AARCH64_INSN_MOVEWIDE_ZERO); -+ *updptr++ = cpu_to_le32(insn); -+} -+ -+/* Patched to mov WA3 when supported */ -+void noinstr spectre_bhb_patch_wa3(struct alt_instr *alt, -+ __le32 *origptr, __le32 *updptr, int nr_inst) -+{ -+ u8 rd; -+ u32 insn; -+ -+ BUG_ON(nr_inst != 1); /* MOV -> MOV */ -+ -+ if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY) || -+ !test_bit(BHB_FW, &system_bhb_mitigations)) -+ return; -+ -+ insn = le32_to_cpu(*origptr); -+ rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn); -+ -+ insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_ORR, -+ AARCH64_INSN_VARIANT_32BIT, -+ AARCH64_INSN_REG_ZR, rd, -+ ARM_SMCCC_ARCH_WORKAROUND_3); -+ if (WARN_ON_ONCE(insn == AARCH64_BREAK_FAULT)) -+ return; -+ -+ *updptr++ = cpu_to_le32(insn); -+} -+ -+/* Patched to NOP when not supported */ -+void __init spectre_bhb_patch_clearbhb(struct alt_instr *alt, -+ __le32 *origptr, __le32 *updptr, int nr_inst) -+{ -+ BUG_ON(nr_inst != 2); -+ -+ if (test_bit(BHB_INSN, &system_bhb_mitigations)) -+ return; -+ -+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop()); -+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop()); -+} -+ -+#ifdef CONFIG_BPF_SYSCALL -+#define EBPF_WARN "Unprivileged eBPF is enabled, data leaks possible via Spectre v2 BHB attacks!\n" -+void unpriv_ebpf_notify(int new_state) -+{ -+ if (spectre_v2_state == SPECTRE_VULNERABLE || -+ spectre_bhb_state != SPECTRE_MITIGATED) -+ return; -+ -+ if (!new_state) -+ pr_err("WARNING: %s", EBPF_WARN); -+} -+#endif -diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c -index 8982a2b78acfc..3b8dc538a4c42 100644 ---- a/arch/arm64/kernel/stacktrace.c -+++ b/arch/arm64/kernel/stacktrace.c -@@ -33,7 +33,7 @@ - */ - - --void start_backtrace(struct stackframe *frame, unsigned long fp, -+notrace void start_backtrace(struct stackframe *frame, unsigned long fp, - unsigned long pc) - { - frame->fp = fp; -@@ -55,6 +55,7 @@ void start_backtrace(struct stackframe *frame, unsigned long fp, - frame->prev_fp = 0; - frame->prev_type = STACK_TYPE_UNKNOWN; - } -+NOKPROBE_SYMBOL(start_backtrace); - - /* - * Unwind from one frame record (A) to the next frame record (B). -diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c -index b03e383d944ab..fe0cd0568813e 100644 ---- a/arch/arm64/kernel/traps.c -+++ b/arch/arm64/kernel/traps.c -@@ -988,7 +988,7 @@ static struct break_hook bug_break_hook = { - static int reserved_fault_handler(struct pt_regs *regs, unsigned int esr) - { - pr_err("%s generated an invalid instruction at %pS!\n", -- in_bpf_jit(regs) ? "BPF JIT" : "Kernel text patching", -+ "Kernel text patching", - (void *)instruction_pointer(regs)); - - /* We cannot handle this */ -diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile -index 3dba0c4f8f42b..3514269ac75fb 100644 ---- a/arch/arm64/kernel/vdso32/Makefile -+++ b/arch/arm64/kernel/vdso32/Makefile -@@ -10,18 +10,15 @@ include $(srctree)/lib/vdso/Makefile - - # Same as cc-*option, but using CC_COMPAT instead of CC - ifeq ($(CONFIG_CC_IS_CLANG), y) --CC_COMPAT_CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%)) -- - CC_COMPAT ?= $(CC) --CC_COMPAT += $(CC_COMPAT_CLANG_FLAGS) -- --ifneq ($(LLVM),) --LD_COMPAT ?= $(LD) -+CC_COMPAT += --target=arm-linux-gnueabi - else --LD_COMPAT ?= $(CROSS_COMPILE_COMPAT)ld -+CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc - endif -+ -+ifeq ($(CONFIG_LD_IS_LLD), y) -+LD_COMPAT ?= $(LD) - else --CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc - LD_COMPAT ?= $(CROSS_COMPILE_COMPAT)ld - endif - -@@ -40,16 +37,13 @@ cc32-as-instr = $(call try-run,\ - # As a result we set our own flags here. - - # KBUILD_CPPFLAGS and NOSTDINC_FLAGS from top-level Makefile --VDSO_CPPFLAGS := -DBUILD_VDSO -D__KERNEL__ -nostdinc -isystem $(shell $(CC_COMPAT) -print-file-name=include) -+VDSO_CPPFLAGS := -DBUILD_VDSO -D__KERNEL__ -nostdinc -+VDSO_CPPFLAGS += -isystem $(shell $(CC_COMPAT) -print-file-name=include 2>/dev/null) - VDSO_CPPFLAGS += $(LINUXINCLUDE) - - # Common C and assembly flags - # From top-level Makefile - VDSO_CAFLAGS := $(VDSO_CPPFLAGS) --ifneq ($(shell $(CC_COMPAT) --version 2>&1 | head -n 1 | grep clang),) --VDSO_CAFLAGS += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%)) --endif -- - VDSO_CAFLAGS += $(call cc32-option,-fno-PIE) - ifdef CONFIG_DEBUG_INFO - VDSO_CAFLAGS += -g -diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S -index f6b1a88245db2..184abd7c4206e 100644 ---- a/arch/arm64/kernel/vmlinux.lds.S -+++ b/arch/arm64/kernel/vmlinux.lds.S -@@ -330,7 +330,7 @@ ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1)) - <= SZ_4K, "Hibernate exit text too big or misaligned") - #endif - #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 --ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE, -+ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE, - "Entry trampoline text too big") - #endif - #ifdef CONFIG_KVM -diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c -index fe102cd2e5183..0b2f684cd8ca5 100644 ---- a/arch/arm64/kvm/arm.c -+++ b/arch/arm64/kvm/arm.c -@@ -755,6 +755,24 @@ static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret) - xfer_to_guest_mode_work_pending(); - } - -+/* -+ * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while -+ * the vCPU is running. -+ * -+ * This must be noinstr as instrumentation may make use of RCU, and this is not -+ * safe during the EQS. -+ */ -+static int noinstr kvm_arm_vcpu_enter_exit(struct kvm_vcpu *vcpu) -+{ -+ int ret; -+ -+ guest_state_enter_irqoff(); -+ ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu); -+ guest_state_exit_irqoff(); -+ -+ return ret; -+} -+ - /** - * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code - * @vcpu: The VCPU pointer -@@ -845,9 +863,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) - * Enter the guest - */ - trace_kvm_entry(*vcpu_pc(vcpu)); -- guest_enter_irqoff(); -+ guest_timing_enter_irqoff(); - -- ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu); -+ ret = kvm_arm_vcpu_enter_exit(vcpu); - - vcpu->mode = OUTSIDE_GUEST_MODE; - vcpu->stat.exits++; -@@ -882,26 +900,23 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) - kvm_arch_vcpu_ctxsync_fp(vcpu); - - /* -- * We may have taken a host interrupt in HYP mode (ie -- * while executing the guest). This interrupt is still -- * pending, as we haven't serviced it yet! -+ * We must ensure that any pending interrupts are taken before -+ * we exit guest timing so that timer ticks are accounted as -+ * guest time. Transiently unmask interrupts so that any -+ * pending interrupts are taken. - * -- * We're now back in SVC mode, with interrupts -- * disabled. Enabling the interrupts now will have -- * the effect of taking the interrupt again, in SVC -- * mode this time. -+ * Per ARM DDI 0487G.b section D1.13.4, an ISB (or other -+ * context synchronization event) is necessary to ensure that -+ * pending interrupts are taken. - */ - local_irq_enable(); -+ isb(); -+ local_irq_disable(); -+ -+ guest_timing_exit_irqoff(); -+ -+ local_irq_enable(); - -- /* -- * We do local_irq_enable() before calling guest_exit() so -- * that if a timer interrupt hits while running the guest we -- * account that tick as being spent in the guest. We enable -- * preemption after calling guest_exit() so that if we get -- * preempted we make sure ticks after that is not counted as -- * guest time. -- */ -- guest_exit(); - trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); - - /* Exit types that need handling before we can be preempted */ -@@ -1443,10 +1458,7 @@ static int kvm_init_vector_slots(void) - base = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs)); - kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_DIRECT); - -- if (!cpus_have_const_cap(ARM64_SPECTRE_V3A)) -- return 0; -- -- if (!has_vhe()) { -+ if (kvm_system_needs_idmapped_vectors() && !has_vhe()) { - err = create_hyp_exec_mappings(__pa_symbol(__bp_harden_hyp_vecs), - __BP_HARDEN_HYP_VECS_SZ, &base); - if (err) -@@ -1971,9 +1983,25 @@ out_err: - return err; - } - --static void _kvm_host_prot_finalize(void *discard) -+static void _kvm_host_prot_finalize(void *arg) -+{ -+ int *err = arg; -+ -+ if (WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize))) -+ WRITE_ONCE(*err, -EINVAL); -+} -+ -+static int pkvm_drop_host_privileges(void) - { -- WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)); -+ int ret = 0; -+ -+ /* -+ * Flip the static key upfront as that may no longer be possible -+ * once the host stage 2 is installed. -+ */ -+ static_branch_enable(&kvm_protected_mode_initialized); -+ on_each_cpu(_kvm_host_prot_finalize, &ret, 1); -+ return ret; - } - - static int finalize_hyp_mode(void) -@@ -1987,15 +2015,7 @@ static int finalize_hyp_mode(void) - * None of other sections should ever be introspected. - */ - kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); -- -- /* -- * Flip the static key upfront as that may no longer be possible -- * once the host stage 2 is installed. -- */ -- static_branch_enable(&kvm_protected_mode_initialized); -- on_each_cpu(_kvm_host_prot_finalize, NULL, 1); -- -- return 0; -+ return pkvm_drop_host_privileges(); - } - - struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr) -diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c -index 275a27368a04c..a5ab5215094ee 100644 ---- a/arch/arm64/kvm/handle_exit.c -+++ b/arch/arm64/kvm/handle_exit.c -@@ -226,6 +226,14 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index) - { - struct kvm_run *run = vcpu->run; - -+ if (ARM_SERROR_PENDING(exception_index)) { -+ /* -+ * The SError is handled by handle_exit_early(). If the guest -+ * survives it will re-execute the original instruction. -+ */ -+ return 1; -+ } -+ - exception_index = ARM_EXCEPTION_CODE(exception_index); - - switch (exception_index) { -diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c -index 0418399e0a201..c5d0097154020 100644 ---- a/arch/arm64/kvm/hyp/exception.c -+++ b/arch/arm64/kvm/hyp/exception.c -@@ -38,7 +38,10 @@ static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) - - static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val) - { -- write_sysreg_el1(val, SYS_SPSR); -+ if (has_vhe()) -+ write_sysreg_el1(val, SYS_SPSR); -+ else -+ __vcpu_sys_reg(vcpu, SPSR_EL1) = val; - } - - static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val) -diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S -index 9aa9b73475c95..7839d075729b1 100644 ---- a/arch/arm64/kvm/hyp/hyp-entry.S -+++ b/arch/arm64/kvm/hyp/hyp-entry.S -@@ -44,7 +44,7 @@ - el1_sync: // Guest trapped into EL2 - - mrs x0, esr_el2 -- lsr x0, x0, #ESR_ELx_EC_SHIFT -+ ubfx x0, x0, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH - cmp x0, #ESR_ELx_EC_HVC64 - ccmp x0, #ESR_ELx_EC_HVC32, #4, ne - b.ne el1_trap -@@ -62,6 +62,10 @@ el1_sync: // Guest trapped into EL2 - /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */ - eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \ - ARM_SMCCC_ARCH_WORKAROUND_2) -+ cbz w1, wa_epilogue -+ -+ eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_2 ^ \ -+ ARM_SMCCC_ARCH_WORKAROUND_3) - cbnz w1, el1_trap - - wa_epilogue: -@@ -192,7 +196,10 @@ SYM_CODE_END(__kvm_hyp_vector) - sub sp, sp, #(8 * 4) - stp x2, x3, [sp, #(8 * 0)] - stp x0, x1, [sp, #(8 * 2)] -+ alternative_cb spectre_bhb_patch_wa3 -+ /* Patched to mov WA3 when supported */ - mov w0, #ARM_SMCCC_ARCH_WORKAROUND_1 -+ alternative_cb_end - smc #0 - ldp x2, x3, [sp, #(8 * 0)] - add sp, sp, #(8 * 2) -@@ -205,6 +212,8 @@ SYM_CODE_END(__kvm_hyp_vector) - spectrev2_smccc_wa1_smc - .else - stp x0, x1, [sp, #-16]! -+ mitigate_spectre_bhb_loop x0 -+ mitigate_spectre_bhb_clear_insn - .endif - .if \indirect != 0 - alternative_cb kvm_patch_vector_branch -diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h -index a0e78a6027be0..ecd41844eda09 100644 ---- a/arch/arm64/kvm/hyp/include/hyp/switch.h -+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h -@@ -416,10 +416,17 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu) - */ - static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) - { -+ /* -+ * Save PSTATE early so that we can evaluate the vcpu mode -+ * early on. -+ */ -+ vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR); -+ - if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) - vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR); - -- if (ARM_SERROR_PENDING(*exit_code)) { -+ if (ARM_SERROR_PENDING(*exit_code) && -+ ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) { - u8 esr_ec = kvm_vcpu_trap_get_class(vcpu); - - /* -diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h -index de7e14c862e6c..7ecca8b078519 100644 ---- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h -+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h -@@ -70,7 +70,12 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) - static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt) - { - ctxt->regs.pc = read_sysreg_el2(SYS_ELR); -- ctxt->regs.pstate = read_sysreg_el2(SYS_SPSR); -+ /* -+ * Guest PSTATE gets saved at guest fixup time in all -+ * cases. We still need to handle the nVHE host side here. -+ */ -+ if (!has_vhe() && ctxt->__hyp_running_vcpu) -+ ctxt->regs.pstate = read_sysreg_el2(SYS_SPSR); - - if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) - ctxt_sys_reg(ctxt, DISR_EL1) = read_sysreg_s(SYS_VDISR_EL2); -diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S -index 4b652ffb591d4..d310d2b2c8b40 100644 ---- a/arch/arm64/kvm/hyp/nvhe/host.S -+++ b/arch/arm64/kvm/hyp/nvhe/host.S -@@ -115,7 +115,7 @@ SYM_FUNC_END(__hyp_do_panic) - .L__vect_start\@: - stp x0, x1, [sp, #-16]! - mrs x0, esr_el2 -- lsr x0, x0, #ESR_ELx_EC_SHIFT -+ ubfx x0, x0, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH - cmp x0, #ESR_ELx_EC_HVC64 - b.ne __host_exit - -diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c -index 2fabeceb889a9..5146fb1705054 100644 ---- a/arch/arm64/kvm/hyp/nvhe/mm.c -+++ b/arch/arm64/kvm/hyp/nvhe/mm.c -@@ -146,8 +146,10 @@ int hyp_map_vectors(void) - phys_addr_t phys; - void *bp_base; - -- if (!cpus_have_const_cap(ARM64_SPECTRE_V3A)) -+ if (!kvm_system_needs_idmapped_vectors()) { -+ __hyp_bp_vect_base = __bp_harden_hyp_vecs; - return 0; -+ } - - phys = __hyp_pa(__bp_harden_hyp_vecs); - bp_base = (void *)__pkvm_create_private_mapping(phys, -diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c -index 57c27846320f4..58ad9c5ba3112 100644 ---- a/arch/arm64/kvm/hyp/nvhe/setup.c -+++ b/arch/arm64/kvm/hyp/nvhe/setup.c -@@ -177,7 +177,7 @@ static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level, - - phys = kvm_pte_to_phys(pte); - if (!addr_is_memory(phys)) -- return 0; -+ return -EINVAL; - - /* - * Adjust the host stage-2 mappings to match the ownership attributes -@@ -206,8 +206,18 @@ static int finalize_host_mappings(void) - .cb = finalize_host_mappings_walker, - .flags = KVM_PGTABLE_WALK_LEAF, - }; -+ int i, ret; -+ -+ for (i = 0; i < hyp_memblock_nr; i++) { -+ struct memblock_region *reg = &hyp_memory[i]; -+ u64 start = (u64)hyp_phys_to_virt(reg->base); -+ -+ ret = kvm_pgtable_walk(&pkvm_pgtable, start, reg->size, &walker); -+ if (ret) -+ return ret; -+ } - -- return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker); -+ return 0; - } - - void __noreturn __pkvm_init_finalise(void) -diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c -index f8ceebe4982eb..4c77ff556f0ae 100644 ---- a/arch/arm64/kvm/hyp/pgtable.c -+++ b/arch/arm64/kvm/hyp/pgtable.c -@@ -921,13 +921,9 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, - */ - stage2_put_pte(ptep, mmu, addr, level, mm_ops); - -- if (need_flush) { -- kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops); -- -- dcache_clean_inval_poc((unsigned long)pte_follow, -- (unsigned long)pte_follow + -- kvm_granule_size(level)); -- } -+ if (need_flush && mm_ops->dcache_clean_inval_poc) -+ mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops), -+ kvm_granule_size(level)); - - if (childp) - mm_ops->put_page(childp); -@@ -1089,15 +1085,13 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, - struct kvm_pgtable *pgt = arg; - struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops; - kvm_pte_t pte = *ptep; -- kvm_pte_t *pte_follow; - - if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte)) - return 0; - -- pte_follow = kvm_pte_follow(pte, mm_ops); -- dcache_clean_inval_poc((unsigned long)pte_follow, -- (unsigned long)pte_follow + -- kvm_granule_size(level)); -+ if (mm_ops->dcache_clean_inval_poc) -+ mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops), -+ kvm_granule_size(level)); - return 0; - } - -diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c -index ded2c66675f06..d88d3c143a735 100644 ---- a/arch/arm64/kvm/hyp/vhe/switch.c -+++ b/arch/arm64/kvm/hyp/vhe/switch.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -25,6 +26,7 @@ - #include - #include - #include -+#include - - /* VHE specific context */ - DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data); -@@ -68,7 +70,7 @@ NOKPROBE_SYMBOL(__activate_traps); - - static void __deactivate_traps(struct kvm_vcpu *vcpu) - { -- extern char vectors[]; /* kernel exception vectors */ -+ const char *host_vectors = vectors; - - ___deactivate_traps(vcpu); - -@@ -82,7 +84,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) - asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); - - write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); -- write_sysreg(vectors, vbar_el1); -+ -+ if (!arm64_kernel_unmapped_at_el0()) -+ host_vectors = __this_cpu_read(this_cpu_vector); -+ write_sysreg(host_vectors, vbar_el1); - } - NOKPROBE_SYMBOL(__deactivate_traps); - -diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c -index 30da78f72b3b3..202b8c455724b 100644 ---- a/arch/arm64/kvm/hypercalls.c -+++ b/arch/arm64/kvm/hypercalls.c -@@ -107,6 +107,18 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) - break; - } - break; -+ case ARM_SMCCC_ARCH_WORKAROUND_3: -+ switch (arm64_get_spectre_bhb_state()) { -+ case SPECTRE_VULNERABLE: -+ break; -+ case SPECTRE_MITIGATED: -+ val[0] = SMCCC_RET_SUCCESS; -+ break; -+ case SPECTRE_UNAFFECTED: -+ val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; -+ break; -+ } -+ break; - case ARM_SMCCC_HV_PV_TIME_FEATURES: - val[0] = SMCCC_RET_SUCCESS; - break; -diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c -index 74c47d4202534..44efe12dfc066 100644 ---- a/arch/arm64/kvm/psci.c -+++ b/arch/arm64/kvm/psci.c -@@ -406,7 +406,7 @@ int kvm_psci_call(struct kvm_vcpu *vcpu) - - int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) - { -- return 3; /* PSCI version and two workaround registers */ -+ return 4; /* PSCI version and three workaround registers */ - } - - int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) -@@ -420,6 +420,9 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) - if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++)) - return -EFAULT; - -+ if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, uindices++)) -+ return -EFAULT; -+ - return 0; - } - -@@ -459,6 +462,17 @@ static int get_kernel_wa_level(u64 regid) - case SPECTRE_VULNERABLE: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; - } -+ break; -+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: -+ switch (arm64_get_spectre_bhb_state()) { -+ case SPECTRE_VULNERABLE: -+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; -+ case SPECTRE_MITIGATED: -+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL; -+ case SPECTRE_UNAFFECTED: -+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED; -+ } -+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; - } - - return -EINVAL; -@@ -475,6 +489,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) - break; - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: -+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: - val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; - break; - default: -@@ -520,6 +535,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) - } - - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: -+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: - if (val & ~KVM_REG_FEATURE_LEVEL_MASK) - return -EINVAL; - -diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c -index 1d46e185f31e1..7c18e429b4493 100644 ---- a/arch/arm64/kvm/sys_regs.c -+++ b/arch/arm64/kvm/sys_regs.c -@@ -1518,7 +1518,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { - /* CRm=6 */ - ID_SANITISED(ID_AA64ISAR0_EL1), - ID_SANITISED(ID_AA64ISAR1_EL1), -- ID_UNALLOCATED(6,2), -+ ID_SANITISED(ID_AA64ISAR2_EL1), - ID_UNALLOCATED(6,3), - ID_UNALLOCATED(6,4), - ID_UNALLOCATED(6,5), -diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c -index 48c6067fc5ecb..f972992682746 100644 ---- a/arch/arm64/kvm/vgic/vgic-mmio.c -+++ b/arch/arm64/kvm/vgic/vgic-mmio.c -@@ -248,6 +248,8 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, - IRQCHIP_STATE_PENDING, - &val); - WARN_RATELIMIT(err, "IRQ %d", irq->host_irq); -+ } else if (vgic_irq_is_mapped_level(irq)) { -+ val = vgic_get_phys_line_level(irq); - } else { - val = irq_is_pending(irq); - } -diff --git a/arch/arm64/lib/clear_page.S b/arch/arm64/lib/clear_page.S -index b84b179edba3a..1fd5d790ab800 100644 ---- a/arch/arm64/lib/clear_page.S -+++ b/arch/arm64/lib/clear_page.S -@@ -16,6 +16,7 @@ - */ - SYM_FUNC_START_PI(clear_page) - mrs x1, dczid_el0 -+ tbnz x1, #4, 2f /* Branch if DC ZVA is prohibited */ - and w1, w1, #0xf - mov x2, #4 - lsl x1, x2, x1 -@@ -25,5 +26,14 @@ SYM_FUNC_START_PI(clear_page) - tst x0, #(PAGE_SIZE - 1) - b.ne 1b - ret -+ -+2: stnp xzr, xzr, [x0] -+ stnp xzr, xzr, [x0, #16] -+ stnp xzr, xzr, [x0, #32] -+ stnp xzr, xzr, [x0, #48] -+ add x0, x0, #64 -+ tst x0, #(PAGE_SIZE - 1) -+ b.ne 2b -+ ret - SYM_FUNC_END_PI(clear_page) - EXPORT_SYMBOL(clear_page) -diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S -index e83643b3995f4..f531dcb95174a 100644 ---- a/arch/arm64/lib/mte.S -+++ b/arch/arm64/lib/mte.S -@@ -43,17 +43,23 @@ SYM_FUNC_END(mte_clear_page_tags) - * x0 - address to the beginning of the page - */ - SYM_FUNC_START(mte_zero_clear_page_tags) -+ and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag - mrs x1, dczid_el0 -+ tbnz x1, #4, 2f // Branch if DC GZVA is prohibited - and w1, w1, #0xf - mov x2, #4 - lsl x1, x2, x1 -- and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag - - 1: dc gzva, x0 - add x0, x0, x1 - tst x0, #(PAGE_SIZE - 1) - b.ne 1b - ret -+ -+2: stz2g x0, [x0], #(MTE_GRANULE_SIZE * 2) -+ tst x0, #(PAGE_SIZE - 1) -+ b.ne 2b -+ ret - SYM_FUNC_END(mte_zero_clear_page_tags) - - /* -diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c -index aa0060178343a..60a8b6a8a42b5 100644 ---- a/arch/arm64/mm/extable.c -+++ b/arch/arm64/mm/extable.c -@@ -9,14 +9,19 @@ - int fixup_exception(struct pt_regs *regs) - { - const struct exception_table_entry *fixup; -+ unsigned long addr; - -- fixup = search_exception_tables(instruction_pointer(regs)); -- if (!fixup) -- return 0; -+ addr = instruction_pointer(regs); - -- if (in_bpf_jit(regs)) -+ /* Search the BPF tables first, these are formatted differently */ -+ fixup = search_bpf_extables(addr); -+ if (fixup) - return arm64_bpf_fixup_exception(fixup, regs); - -+ fixup = search_exception_tables(addr); -+ if (!fixup) -+ return 0; -+ - regs->pc = (unsigned long)&fixup->fixup + fixup->fixup; - return 1; - } -diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c -index cfd9deb347c38..9d03806316905 100644 ---- a/arch/arm64/mm/mmu.c -+++ b/arch/arm64/mm/mmu.c -@@ -616,6 +616,8 @@ early_param("rodata", parse_rodata); - #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 - static int __init map_entry_trampoline(void) - { -+ int i; -+ - pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; - phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); - -@@ -624,11 +626,15 @@ static int __init map_entry_trampoline(void) - - /* Map only the text into the trampoline page table */ - memset(tramp_pg_dir, 0, PGD_SIZE); -- __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE, -- prot, __pgd_pgtable_alloc, 0); -+ __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, -+ entry_tramp_text_size(), prot, -+ __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); - - /* Map both the text and data into the kernel page table */ -- __set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot); -+ for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) -+ __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, -+ pa_start + i * PAGE_SIZE, prot); -+ - if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { - extern char __entry_tramp_data_start[]; - -@@ -1499,6 +1505,11 @@ int arch_add_memory(int nid, u64 start, u64 size, - if (ret) - __remove_pgd_mapping(swapper_pg_dir, - __phys_to_virt(start), size); -+ else { -+ max_pfn = PFN_UP(start + size); -+ max_low_pfn = max_pfn; -+ } -+ - return ret; - } - -diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c -index 1c403536c9bb0..9bc4066c5bf33 100644 ---- a/arch/arm64/mm/ptdump.c -+++ b/arch/arm64/mm/ptdump.c -@@ -41,8 +41,6 @@ static struct addr_marker address_markers[] = { - { 0 /* KASAN_SHADOW_START */, "Kasan shadow start" }, - { KASAN_SHADOW_END, "Kasan shadow end" }, - #endif -- { BPF_JIT_REGION_START, "BPF start" }, -- { BPF_JIT_REGION_END, "BPF end" }, - { MODULES_VADDR, "Modules start" }, - { MODULES_END, "Modules end" }, - { VMALLOC_START, "vmalloc() area" }, -diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c -index 803e7773fa869..465c44d0c72fc 100644 ---- a/arch/arm64/net/bpf_jit_comp.c -+++ b/arch/arm64/net/bpf_jit_comp.c -@@ -1138,15 +1138,12 @@ out: - - u64 bpf_jit_alloc_exec_limit(void) - { -- return BPF_JIT_REGION_SIZE; -+ return VMALLOC_END - VMALLOC_START; - } - - void *bpf_jit_alloc_exec(unsigned long size) - { -- return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START, -- BPF_JIT_REGION_END, GFP_KERNEL, -- PAGE_KERNEL, 0, NUMA_NO_NODE, -- __builtin_return_address(0)); -+ return vmalloc(size); - } - - void bpf_jit_free_exec(void *addr) -diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps -index 49305c2e6dfd3..b71c6cbb23095 100644 ---- a/arch/arm64/tools/cpucaps -+++ b/arch/arm64/tools/cpucaps -@@ -42,6 +42,7 @@ MTE - SPECTRE_V2 - SPECTRE_V3A - SPECTRE_V4 -+SPECTRE_BHB - SSBS - SVE - UNMAP_KERNEL_AT_EL0 -diff --git a/arch/csky/kernel/perf_callchain.c b/arch/csky/kernel/perf_callchain.c -index ab55e98ee8f62..35318a635a5fa 100644 ---- a/arch/csky/kernel/perf_callchain.c -+++ b/arch/csky/kernel/perf_callchain.c -@@ -86,10 +86,11 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry, - void perf_callchain_user(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - unsigned long fp = 0; - - /* C-SKY does not support virtualization. */ -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) -+ if (guest_cbs && guest_cbs->is_in_guest()) - return; - - fp = regs->regs[4]; -@@ -110,10 +111,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, - void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct stackframe fr; - - /* C-SKY does not support virtualization. */ -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - pr_warn("C-SKY does not support perf in guest mode!"); - return; - } -diff --git a/arch/csky/kernel/traps.c b/arch/csky/kernel/traps.c -index e5fbf8653a215..2020af88b6361 100644 ---- a/arch/csky/kernel/traps.c -+++ b/arch/csky/kernel/traps.c -@@ -209,7 +209,7 @@ asmlinkage void do_trap_illinsn(struct pt_regs *regs) - - asmlinkage void do_trap_fpe(struct pt_regs *regs) - { --#ifdef CONFIG_CPU_HAS_FP -+#ifdef CONFIG_CPU_HAS_FPU - return fpu_fpe(regs); - #else - do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->pc, -@@ -219,7 +219,7 @@ asmlinkage void do_trap_fpe(struct pt_regs *regs) - - asmlinkage void do_trap_priv(struct pt_regs *regs) - { --#ifdef CONFIG_CPU_HAS_FP -+#ifdef CONFIG_CPU_HAS_FPU - if (user_mode(regs) && fpu_libc_helper(regs)) - return; - #endif -diff --git a/arch/hexagon/include/asm/timer-regs.h b/arch/hexagon/include/asm/timer-regs.h -deleted file mode 100644 -index ee6c61423a058..0000000000000 ---- a/arch/hexagon/include/asm/timer-regs.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * Timer support for Hexagon -- * -- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. -- */ -- --#ifndef _ASM_TIMER_REGS_H --#define _ASM_TIMER_REGS_H -- --/* This stuff should go into a platform specific file */ --#define TCX0_CLK_RATE 19200 --#define TIMER_ENABLE 0 --#define TIMER_CLR_ON_MATCH 1 -- --/* -- * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until -- * release 1.1, and then it's "adjustable" and probably not defaulted. -- */ --#define RTOS_TIMER_INT 3 --#ifdef CONFIG_HEXAGON_COMET --#define RTOS_TIMER_REGS_ADDR 0xAB000000UL --#endif --#define SLEEP_CLK_RATE 32000 -- --#endif -diff --git a/arch/hexagon/include/asm/timex.h b/arch/hexagon/include/asm/timex.h -index 8d4ec76fceb45..dfe69e118b2be 100644 ---- a/arch/hexagon/include/asm/timex.h -+++ b/arch/hexagon/include/asm/timex.h -@@ -7,11 +7,10 @@ - #define _ASM_TIMEX_H - - #include --#include - #include - - /* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */ --#define CLOCK_TICK_RATE TCX0_CLK_RATE -+#define CLOCK_TICK_RATE 19200 - - #define ARCH_HAS_READ_CURRENT_TIMER - -diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c -index feffe527ac929..febc95714d756 100644 ---- a/arch/hexagon/kernel/time.c -+++ b/arch/hexagon/kernel/time.c -@@ -17,9 +17,10 @@ - #include - #include - --#include - #include - -+#define TIMER_ENABLE BIT(0) -+ - /* - * For the clocksource we need: - * pcycle frequency (600MHz) -@@ -33,6 +34,13 @@ cycles_t pcycle_freq_mhz; - cycles_t thread_freq_mhz; - cycles_t sleep_clk_freq; - -+/* -+ * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until -+ * release 1.1, and then it's "adjustable" and probably not defaulted. -+ */ -+#define RTOS_TIMER_INT 3 -+#define RTOS_TIMER_REGS_ADDR 0xAB000000UL -+ - static struct resource rtos_timer_resources[] = { - { - .start = RTOS_TIMER_REGS_ADDR, -@@ -80,7 +88,7 @@ static int set_next_event(unsigned long delta, struct clock_event_device *evt) - iowrite32(0, &rtos_timer->clear); - - iowrite32(delta, &rtos_timer->match); -- iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable); -+ iowrite32(TIMER_ENABLE, &rtos_timer->enable); - return 0; - } - -diff --git a/arch/hexagon/lib/io.c b/arch/hexagon/lib/io.c -index d35d69d6588c4..55f75392857b0 100644 ---- a/arch/hexagon/lib/io.c -+++ b/arch/hexagon/lib/io.c -@@ -27,6 +27,7 @@ void __raw_readsw(const void __iomem *addr, void *data, int len) - *dst++ = *src; - - } -+EXPORT_SYMBOL(__raw_readsw); - - /* - * __raw_writesw - read words a short at a time -@@ -47,6 +48,7 @@ void __raw_writesw(void __iomem *addr, const void *data, int len) - - - } -+EXPORT_SYMBOL(__raw_writesw); - - /* Pretty sure len is pre-adjusted for the length of the access already */ - void __raw_readsl(const void __iomem *addr, void *data, int len) -@@ -62,6 +64,7 @@ void __raw_readsl(const void __iomem *addr, void *data, int len) - - - } -+EXPORT_SYMBOL(__raw_readsl); - - void __raw_writesl(void __iomem *addr, const void *data, int len) - { -@@ -76,3 +79,4 @@ void __raw_writesl(void __iomem *addr, const void *data, int len) - - - } -+EXPORT_SYMBOL(__raw_writesl); -diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug -index 40ca23bd228d6..2ce008e2d1644 100644 ---- a/arch/ia64/Kconfig.debug -+++ b/arch/ia64/Kconfig.debug -@@ -39,7 +39,7 @@ config DISABLE_VHPT - - config IA64_DEBUG_CMPXCHG - bool "Turn on compare-and-exchange bug checking (slow!)" -- depends on DEBUG_KERNEL -+ depends on DEBUG_KERNEL && PRINTK - help - Selecting this option turns on bug checking for the IA-64 - compare-and-exchange instructions. This is slow! Itaniums -diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c -index 441ed04b10378..d4048518a1d7d 100644 ---- a/arch/ia64/kernel/kprobes.c -+++ b/arch/ia64/kernel/kprobes.c -@@ -398,7 +398,8 @@ static void kretprobe_trampoline(void) - - int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) - { -- regs->cr_iip = __kretprobe_trampoline_handler(regs, kretprobe_trampoline, NULL); -+ regs->cr_iip = __kretprobe_trampoline_handler(regs, -+ dereference_function_descriptor(kretprobe_trampoline), NULL); - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler -@@ -414,7 +415,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, - ri->fp = NULL; - - /* Replace the return addr with trampoline addr */ -- regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; -+ regs->b0 = (unsigned long)dereference_function_descriptor(kretprobe_trampoline); - } - - /* Check the instruction in the slot is break */ -@@ -902,14 +903,14 @@ static struct kprobe trampoline_p = { - int __init arch_init_kprobes(void) - { - trampoline_p.addr = -- (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; -+ dereference_function_descriptor(kretprobe_trampoline); - return register_kprobe(&trampoline_p); - } - - int __kprobes arch_trampoline_kprobe(struct kprobe *p) - { - if (p->addr == -- (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip) -+ dereference_function_descriptor(kretprobe_trampoline)) - return 1; - - return 0; -diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c -index acb55a41260dd..2bcdd7d3a1ada 100644 ---- a/arch/ia64/pci/fixup.c -+++ b/arch/ia64/pci/fixup.c -@@ -76,5 +76,5 @@ static void pci_fixup_video(struct pci_dev *pdev) - } - } - } --DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, -- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); -+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, -+ PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); -diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine -index 36fa0c3ef1296..eeab4f3e6c197 100644 ---- a/arch/m68k/Kconfig.machine -+++ b/arch/m68k/Kconfig.machine -@@ -203,6 +203,7 @@ config INIT_LCD - config MEMORY_RESERVE - int "Memory reservation (MiB)" - depends on (UCSIMM || UCDIMM) -+ default 0 - help - Reserve certain memory regions on 68x328 based boards. - -diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c -index 9718ce94cc845..34d6458340b0f 100644 ---- a/arch/m68k/kernel/traps.c -+++ b/arch/m68k/kernel/traps.c -@@ -1145,7 +1145,7 @@ asmlinkage void set_esp0(unsigned long ssp) - */ - asmlinkage void fpsp040_die(void) - { -- force_sigsegv(SIGSEGV); -+ force_exit_sig(SIGSEGV); - } - - #ifdef CONFIG_M68KFPU_EMU -diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms -index 584081df89c28..6e3f36c841e5d 100644 ---- a/arch/mips/Kbuild.platforms -+++ b/arch/mips/Kbuild.platforms -@@ -38,4 +38,4 @@ platform-$(CONFIG_MACH_TX49XX) += txx9/ - platform-$(CONFIG_MACH_VR41XX) += vr41xx/ - - # include the platform specific files --include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platform-y)) -+include $(patsubst %/, $(srctree)/arch/mips/%/Platform, $(platform-y)) -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 6b8f591c5054c..393eb2133243f 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -332,6 +332,9 @@ config BCM63XX - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_HAS_EARLY_PRINTK -+ select SYS_HAS_CPU_BMIPS32_3300 -+ select SYS_HAS_CPU_BMIPS4350 -+ select SYS_HAS_CPU_BMIPS4380 - select SWAP_IO_SPACE - select GPIOLIB - select MIPS_L1_CACHE_SHIFT_4 -@@ -1379,6 +1382,7 @@ config CPU_LOONGSON64 - select MIPS_ASID_BITS_VARIABLE - select MIPS_PGD_C0_CONTEXT - select MIPS_L1_CACHE_SHIFT_6 -+ select MIPS_FP_SUPPORT - select GPIOLIB - select SWIOTLB - select HAVE_KVM -@@ -1989,6 +1993,10 @@ config SYS_HAS_CPU_MIPS64_R1 - config SYS_HAS_CPU_MIPS64_R2 - bool - -+config SYS_HAS_CPU_MIPS64_R5 -+ bool -+ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT -+ - config SYS_HAS_CPU_MIPS64_R6 - bool - select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT -@@ -2153,7 +2161,7 @@ config CPU_SUPPORTS_ADDRWINCFG - bool - config CPU_SUPPORTS_HUGEPAGES - bool -- depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA)) -+ depends on !(32BIT && (PHYS_ADDR_T_64BIT || EVA)) - config MIPS_PGD_C0_CONTEXT - bool - depends on 64BIT -@@ -3185,7 +3193,7 @@ config STACKTRACE_SUPPORT - config PGTABLE_LEVELS - int - default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48 -- default 3 if 64BIT && !PAGE_SIZE_64KB -+ default 3 if 64BIT && (!PAGE_SIZE_64KB || MIPS_VA_BITS_48) - default 2 - - config MIPS_AUTO_PFN_OFFSET -diff --git a/arch/mips/Makefile b/arch/mips/Makefile -index ea3cd080a1c7d..f7b58da2f3889 100644 ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -254,7 +254,9 @@ endif - # - # Board-dependent options and extra files - # -+ifdef need-compiler - include $(srctree)/arch/mips/Kbuild.platforms -+endif - - ifdef CONFIG_PHYSICAL_START - load-y = $(CONFIG_PHYSICAL_START) -diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c -index 5a3e325275d0d..6e6756e8fa0a9 100644 ---- a/arch/mips/bcm63xx/clk.c -+++ b/arch/mips/bcm63xx/clk.c -@@ -381,6 +381,18 @@ void clk_disable(struct clk *clk) - - EXPORT_SYMBOL(clk_disable); - -+struct clk *clk_get_parent(struct clk *clk) -+{ -+ return NULL; -+} -+EXPORT_SYMBOL(clk_get_parent); -+ -+int clk_set_parent(struct clk *clk, struct clk *parent) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(clk_set_parent); -+ - unsigned long clk_get_rate(struct clk *clk) - { - if (!clk) -diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile -index 3548b3b452699..705b9e7f8035a 100644 ---- a/arch/mips/boot/compressed/Makefile -+++ b/arch/mips/boot/compressed/Makefile -@@ -56,6 +56,8 @@ $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c - - vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o - -+vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o $(obj)/ashldi3.o $(obj)/clz_ctz.o -+ - extra-y += ashldi3.c - $(obj)/ashldi3.c: $(obj)/%.c: $(srctree)/lib/%.c FORCE - $(call if_changed,shipped) -@@ -64,6 +66,10 @@ extra-y += bswapsi.c - $(obj)/bswapsi.c: $(obj)/%.c: $(srctree)/arch/mips/lib/%.c FORCE - $(call if_changed,shipped) - -+extra-y += bswapdi.c -+$(obj)/bswapdi.c: $(obj)/%.c: $(srctree)/arch/mips/lib/%.c FORCE -+ $(call if_changed,shipped) -+ - targets := $(notdir $(vmlinuzobjs-y)) - - targets += vmlinux.bin -diff --git a/arch/mips/boot/compressed/clz_ctz.c b/arch/mips/boot/compressed/clz_ctz.c -new file mode 100644 -index 0000000000000..b4a1b6eb2f8ad ---- /dev/null -+++ b/arch/mips/boot/compressed/clz_ctz.c -@@ -0,0 +1,2 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include "../../../../lib/clz_ctz.c" -diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S -index 0a515cde1c183..25860fba6218d 100644 ---- a/arch/mips/cavium-octeon/octeon-memcpy.S -+++ b/arch/mips/cavium-octeon/octeon-memcpy.S -@@ -74,7 +74,7 @@ - #define EXC(inst_reg,addr,handler) \ - 9: inst_reg, addr; \ - .section __ex_table,"a"; \ -- PTR 9b, handler; \ -+ PTR_WD 9b, handler; \ - .previous - - /* -diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c -index d56e9b9d2e434..a994022e32c9f 100644 ---- a/arch/mips/cavium-octeon/octeon-platform.c -+++ b/arch/mips/cavium-octeon/octeon-platform.c -@@ -328,6 +328,7 @@ static int __init octeon_ehci_device_init(void) - - pd->dev.platform_data = &octeon_ehci_pdata; - octeon_ehci_hw_start(&pd->dev); -+ put_device(&pd->dev); - - return ret; - } -@@ -391,6 +392,7 @@ static int __init octeon_ohci_device_init(void) - - pd->dev.platform_data = &octeon_ohci_pdata; - octeon_ohci_hw_start(&pd->dev); -+ put_device(&pd->dev); - - return ret; - } -diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c -index 6e4d3619137af..4df919d26b082 100644 ---- a/arch/mips/cavium-octeon/octeon-usb.c -+++ b/arch/mips/cavium-octeon/octeon-usb.c -@@ -537,6 +537,7 @@ static int __init dwc3_octeon_device_init(void) - devm_iounmap(&pdev->dev, base); - devm_release_mem_region(&pdev->dev, res->start, - resource_size(res)); -+ put_device(&pdev->dev); - } - } while (node != NULL); - -diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig -index 5c24ac7fdf56d..ba47c5e929b7f 100644 ---- a/arch/mips/configs/fuloong2e_defconfig -+++ b/arch/mips/configs/fuloong2e_defconfig -@@ -206,7 +206,6 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m - CONFIG_CIFS_STATS2=y --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_CIFS_DEBUG2=y -diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig -index 614af02d83e6e..6fb9bc29f4a03 100644 ---- a/arch/mips/configs/malta_qemu_32r6_defconfig -+++ b/arch/mips/configs/malta_qemu_32r6_defconfig -@@ -165,7 +165,6 @@ CONFIG_TMPFS=y - CONFIG_NFS_FS=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig -index 9c051f8fd3300..eb72df528243a 100644 ---- a/arch/mips/configs/maltaaprp_defconfig -+++ b/arch/mips/configs/maltaaprp_defconfig -@@ -166,7 +166,6 @@ CONFIG_TMPFS=y - CONFIG_NFS_FS=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig -index 2e90d97551d6f..1fb40d310f49c 100644 ---- a/arch/mips/configs/maltasmvp_defconfig -+++ b/arch/mips/configs/maltasmvp_defconfig -@@ -167,7 +167,6 @@ CONFIG_TMPFS=y - CONFIG_NFS_FS=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig -index d1f7fdb27284b..75cb778c61496 100644 ---- a/arch/mips/configs/maltasmvp_eva_defconfig -+++ b/arch/mips/configs/maltasmvp_eva_defconfig -@@ -169,7 +169,6 @@ CONFIG_TMPFS=y - CONFIG_NFS_FS=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig -index 48e5bd4924522..7b4f247dc60cc 100644 ---- a/arch/mips/configs/maltaup_defconfig -+++ b/arch/mips/configs/maltaup_defconfig -@@ -165,7 +165,6 @@ CONFIG_TMPFS=y - CONFIG_NFS_FS=y - CONFIG_ROOT_NFS=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_NLS_CODEPAGE_437=m -diff --git a/arch/mips/generic/yamon-dt.c b/arch/mips/generic/yamon-dt.c -index a3aa22c77cadc..a07a5edbcda78 100644 ---- a/arch/mips/generic/yamon-dt.c -+++ b/arch/mips/generic/yamon-dt.c -@@ -75,7 +75,7 @@ static unsigned int __init gen_fdt_mem_array( - __init int yamon_dt_append_memory(void *fdt, - const struct yamon_mem_region *regions) - { -- unsigned long phys_memsize, memsize; -+ unsigned long phys_memsize = 0, memsize; - __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; - unsigned int mem_entries; - int i, err, mem_off; -diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h -index 2f8ce94ebaafe..cc69f1deb1ca8 100644 ---- a/arch/mips/include/asm/asm.h -+++ b/arch/mips/include/asm/asm.h -@@ -276,7 +276,7 @@ symbol = value - - #define PTR_SCALESHIFT 2 - --#define PTR .word -+#define PTR_WD .word - #define PTRSIZE 4 - #define PTRLOG 2 - #endif -@@ -301,7 +301,7 @@ symbol = value - - #define PTR_SCALESHIFT 3 - --#define PTR .dword -+#define PTR_WD .dword - #define PTRSIZE 8 - #define PTRLOG 3 - #endif -diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h -index 0b983800f48b7..66a8b293fd80b 100644 ---- a/arch/mips/include/asm/cmpxchg.h -+++ b/arch/mips/include/asm/cmpxchg.h -@@ -249,6 +249,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, - /* Load 64 bits from ptr */ - " " __SYNC(full, loongson3_war) " \n" - "1: lld %L0, %3 # __cmpxchg64 \n" -+ " .set pop \n" - /* - * Split the 64 bit value we loaded into the 2 registers that hold the - * ret variable. -@@ -276,12 +277,14 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, - " or %L1, %L1, $at \n" - " .set at \n" - # endif -+ " .set push \n" -+ " .set " MIPS_ISA_ARCH_LEVEL " \n" - /* Attempt to store new at ptr */ - " scd %L1, %2 \n" - /* If we failed, loop! */ - "\t" __SC_BEQZ "%L1, 1b \n" -- " .set pop \n" - "2: " __SYNC(full, loongson3_war) " \n" -+ " .set pop \n" - : "=&r"(ret), - "=&r"(tmp), - "=" GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr) -diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h -index b463f2aa5a613..db497a8167da2 100644 ---- a/arch/mips/include/asm/ftrace.h -+++ b/arch/mips/include/asm/ftrace.h -@@ -32,7 +32,7 @@ do { \ - ".previous\n" \ - \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR) "\t1b, 3b\n\t" \ -+ STR(PTR_WD) "\t1b, 3b\n\t" \ - ".previous\n" \ - \ - : [tmp_dst] "=&r" (dst), [tmp_err] "=r" (error)\ -@@ -54,7 +54,7 @@ do { \ - ".previous\n" \ - \ - ".section\t__ex_table,\"a\"\n\t"\ -- STR(PTR) "\t1b, 3b\n\t" \ -+ STR(PTR_WD) "\t1b, 3b\n\t" \ - ".previous\n" \ - \ - : [tmp_err] "=r" (error) \ -diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h -index ecda7295ddcd1..3fa6340903882 100644 ---- a/arch/mips/include/asm/local.h -+++ b/arch/mips/include/asm/local.h -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -39,7 +40,7 @@ static __inline__ long local_add_return(long i, local_t * l) - " .set arch=r4000 \n" - __SYNC(full, loongson3_war) " \n" - "1:" __LL "%1, %2 # local_add_return \n" -- " addu %0, %1, %3 \n" -+ __stringify(LONG_ADDU) " %0, %1, %3 \n" - __SC "%0, %2 \n" - " beqzl %0, 1b \n" - " addu %0, %1, %3 \n" -@@ -55,7 +56,7 @@ static __inline__ long local_add_return(long i, local_t * l) - " .set "MIPS_ISA_ARCH_LEVEL" \n" - __SYNC(full, loongson3_war) " \n" - "1:" __LL "%1, %2 # local_add_return \n" -- " addu %0, %1, %3 \n" -+ __stringify(LONG_ADDU) " %0, %1, %3 \n" - __SC "%0, %2 \n" - " beqz %0, 1b \n" - " addu %0, %1, %3 \n" -@@ -88,7 +89,7 @@ static __inline__ long local_sub_return(long i, local_t * l) - " .set arch=r4000 \n" - __SYNC(full, loongson3_war) " \n" - "1:" __LL "%1, %2 # local_sub_return \n" -- " subu %0, %1, %3 \n" -+ __stringify(LONG_SUBU) " %0, %1, %3 \n" - __SC "%0, %2 \n" - " beqzl %0, 1b \n" - " subu %0, %1, %3 \n" -@@ -104,7 +105,7 @@ static __inline__ long local_sub_return(long i, local_t * l) - " .set "MIPS_ISA_ARCH_LEVEL" \n" - __SYNC(full, loongson3_war) " \n" - "1:" __LL "%1, %2 # local_sub_return \n" -- " subu %0, %1, %3 \n" -+ __stringify(LONG_SUBU) " %0, %1, %3 \n" - __SC "%0, %2 \n" - " beqz %0, 1b \n" - " subu %0, %1, %3 \n" -diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h -index 13373c5144f89..efb41b3519747 100644 ---- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h -+++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h -@@ -32,7 +32,7 @@ - nop - /* Loongson-3A R2/R3 */ - andi t0, (PRID_IMP_MASK | PRID_REV_MASK) -- slti t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) -+ slti t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) - bnez t0, 2f - nop - 1: -@@ -63,7 +63,7 @@ - nop - /* Loongson-3A R2/R3 */ - andi t0, (PRID_IMP_MASK | PRID_REV_MASK) -- slti t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) -+ slti t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) - bnez t0, 2f - nop - 1: -diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h -index aeae2effa123d..23c67c0871b17 100644 ---- a/arch/mips/include/asm/mips-cm.h -+++ b/arch/mips/include/asm/mips-cm.h -@@ -11,6 +11,7 @@ - #ifndef __MIPS_ASM_MIPS_CM_H__ - #define __MIPS_ASM_MIPS_CM_H__ - -+#include - #include - #include - -@@ -153,8 +154,8 @@ GCR_ACCESSOR_RO(32, 0x030, rev) - #define CM_GCR_REV_MINOR GENMASK(7, 0) - - #define CM_ENCODE_REV(major, minor) \ -- (((major) << __ffs(CM_GCR_REV_MAJOR)) | \ -- ((minor) << __ffs(CM_GCR_REV_MINOR))) -+ (FIELD_PREP(CM_GCR_REV_MAJOR, major) | \ -+ FIELD_PREP(CM_GCR_REV_MINOR, minor)) - - #define CM_REV_CM2 CM_ENCODE_REV(6, 0) - #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) -@@ -362,10 +363,10 @@ static inline int mips_cm_revision(void) - static inline unsigned int mips_cm_max_vp_width(void) - { - extern int smp_num_siblings; -- uint32_t cfg; - - if (mips_cm_revision() >= CM_REV_CM3) -- return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW; -+ return FIELD_GET(CM_GCR_SYS_CONFIG2_MAXVPW, -+ read_gcr_sys_config2()); - - if (mips_cm_present()) { - /* -@@ -373,8 +374,7 @@ static inline unsigned int mips_cm_max_vp_width(void) - * number of VP(E)s, and if that ever changes then this will - * need revisiting. - */ -- cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE; -- return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1; -+ return FIELD_GET(CM_GCR_Cx_CONFIG_PVPE, read_gcr_cl_config()) + 1; - } - - if (IS_ENABLED(CONFIG_SMP)) -diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h -index 0e6bf220db618..6c61e0a639249 100644 ---- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h -+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h -@@ -318,7 +318,7 @@ enum cvmx_chip_types_enum { - - /* Functions to return string based on type */ - #define ENUM_BRD_TYPE_CASE(x) \ -- case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */ -+ case x: return (&#x[16]); /* Skip CVMX_BOARD_TYPE_ */ - static inline const char *cvmx_board_type_to_string(enum - cvmx_board_types_enum type) - { -@@ -410,7 +410,7 @@ static inline const char *cvmx_board_type_to_string(enum - } - - #define ENUM_CHIP_TYPE_CASE(x) \ -- case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */ -+ case x: return (&#x[15]); /* Skip CVMX_CHIP_TYPE */ - static inline const char *cvmx_chip_type_to_string(enum - cvmx_chip_types_enum type) - { -diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h -index af3788589ee6d..431a1c9d53fc7 100644 ---- a/arch/mips/include/asm/r4kcache.h -+++ b/arch/mips/include/asm/r4kcache.h -@@ -119,7 +119,7 @@ static inline void flush_scache_line(unsigned long addr) - " j 2b \n" \ - " .previous \n" \ - " .section __ex_table,\"a\" \n" \ -- " "STR(PTR)" 1b, 3b \n" \ -+ " "STR(PTR_WD)" 1b, 3b \n" \ - " .previous" \ - : "+r" (__err) \ - : "i" (op), "r" (addr), "i" (-EFAULT)); \ -@@ -142,7 +142,7 @@ static inline void flush_scache_line(unsigned long addr) - " j 2b \n" \ - " .previous \n" \ - " .section __ex_table,\"a\" \n" \ -- " "STR(PTR)" 1b, 3b \n" \ -+ " "STR(PTR_WD)" 1b, 3b \n" \ - " .previous" \ - : "+r" (__err) \ - : "i" (op), "r" (addr), "i" (-EFAULT)); \ -diff --git a/arch/mips/include/asm/unaligned-emul.h b/arch/mips/include/asm/unaligned-emul.h -index 2022b18944b97..9af0f4d3d288c 100644 ---- a/arch/mips/include/asm/unaligned-emul.h -+++ b/arch/mips/include/asm/unaligned-emul.h -@@ -20,8 +20,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -41,8 +41,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -74,10 +74,10 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -102,8 +102,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -125,8 +125,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -145,8 +145,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -178,10 +178,10 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -223,14 +223,14 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -- STR(PTR)"\t5b, 11b\n\t" \ -- STR(PTR)"\t6b, 11b\n\t" \ -- STR(PTR)"\t7b, 11b\n\t" \ -- STR(PTR)"\t8b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t5b, 11b\n\t" \ -+ STR(PTR_WD)"\t6b, 11b\n\t" \ -+ STR(PTR_WD)"\t7b, 11b\n\t" \ -+ STR(PTR_WD)"\t8b, 11b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -255,8 +255,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT));\ -@@ -276,8 +276,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); \ -@@ -296,8 +296,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); \ -@@ -325,10 +325,10 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ - ".previous" \ - : "=&r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT) \ -@@ -365,14 +365,14 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -- STR(PTR)"\t5b, 11b\n\t" \ -- STR(PTR)"\t6b, 11b\n\t" \ -- STR(PTR)"\t7b, 11b\n\t" \ -- STR(PTR)"\t8b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t5b, 11b\n\t" \ -+ STR(PTR_WD)"\t6b, 11b\n\t" \ -+ STR(PTR_WD)"\t7b, 11b\n\t" \ -+ STR(PTR_WD)"\t8b, 11b\n\t" \ - ".previous" \ - : "=&r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT) \ -@@ -398,8 +398,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -419,8 +419,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -452,10 +452,10 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -481,8 +481,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -504,8 +504,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -524,8 +524,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -557,10 +557,10 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -602,14 +602,14 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -- STR(PTR)"\t5b, 11b\n\t" \ -- STR(PTR)"\t6b, 11b\n\t" \ -- STR(PTR)"\t7b, 11b\n\t" \ -- STR(PTR)"\t8b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t5b, 11b\n\t" \ -+ STR(PTR_WD)"\t6b, 11b\n\t" \ -+ STR(PTR_WD)"\t7b, 11b\n\t" \ -+ STR(PTR_WD)"\t8b, 11b\n\t" \ - ".previous" \ - : "=&r" (value), "=r" (res) \ - : "r" (addr), "i" (-EFAULT)); \ -@@ -632,8 +632,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT));\ -@@ -653,8 +653,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); \ -@@ -673,8 +673,8 @@ do { \ - "j\t3b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 4b\n\t" \ -- STR(PTR)"\t2b, 4b\n\t" \ -+ STR(PTR_WD)"\t1b, 4b\n\t" \ -+ STR(PTR_WD)"\t2b, 4b\n\t" \ - ".previous" \ - : "=r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT)); \ -@@ -703,10 +703,10 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ - ".previous" \ - : "=&r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT) \ -@@ -743,14 +743,14 @@ do { \ - "j\t10b\n\t" \ - ".previous\n\t" \ - ".section\t__ex_table,\"a\"\n\t" \ -- STR(PTR)"\t1b, 11b\n\t" \ -- STR(PTR)"\t2b, 11b\n\t" \ -- STR(PTR)"\t3b, 11b\n\t" \ -- STR(PTR)"\t4b, 11b\n\t" \ -- STR(PTR)"\t5b, 11b\n\t" \ -- STR(PTR)"\t6b, 11b\n\t" \ -- STR(PTR)"\t7b, 11b\n\t" \ -- STR(PTR)"\t8b, 11b\n\t" \ -+ STR(PTR_WD)"\t1b, 11b\n\t" \ -+ STR(PTR_WD)"\t2b, 11b\n\t" \ -+ STR(PTR_WD)"\t3b, 11b\n\t" \ -+ STR(PTR_WD)"\t4b, 11b\n\t" \ -+ STR(PTR_WD)"\t5b, 11b\n\t" \ -+ STR(PTR_WD)"\t6b, 11b\n\t" \ -+ STR(PTR_WD)"\t7b, 11b\n\t" \ -+ STR(PTR_WD)"\t8b, 11b\n\t" \ - ".previous" \ - : "=&r" (res) \ - : "r" (value), "r" (addr), "i" (-EFAULT) \ -diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c -index 630fcb4cb30e7..7c861e6a89529 100644 ---- a/arch/mips/kernel/cpu-probe.c -+++ b/arch/mips/kernel/cpu-probe.c -@@ -1734,8 +1734,6 @@ static inline void decode_cpucfg(struct cpuinfo_mips *c) - - static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) - { -- decode_configs(c); -- - /* All Loongson processors covered here define ExcCode 16 as GSExc. */ - c->options |= MIPS_CPU_GSEXCEX; - -@@ -1796,6 +1794,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) - panic("Unknown Loongson Processor ID!"); - break; - } -+ -+ decode_configs(c); - } - #else - static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { } -diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c -index 90f1c3df1f0e4..b4f7d950c8468 100644 ---- a/arch/mips/kernel/mips-cm.c -+++ b/arch/mips/kernel/mips-cm.c -@@ -221,8 +221,7 @@ static void mips_cm_probe_l2sync(void) - phys_addr_t addr; - - /* L2-only sync was introduced with CM major revision 6 */ -- major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >> -- __ffs(CM_GCR_REV_MAJOR); -+ major_rev = FIELD_GET(CM_GCR_REV_MAJOR, read_gcr_rev()); - if (major_rev < 6) - return; - -@@ -306,13 +305,13 @@ void mips_cm_lock_other(unsigned int cluster, unsigned int core, - preempt_disable(); - - if (cm_rev >= CM_REV_CM3) { -- val = core << __ffs(CM3_GCR_Cx_OTHER_CORE); -- val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP); -+ val = FIELD_PREP(CM3_GCR_Cx_OTHER_CORE, core) | -+ FIELD_PREP(CM3_GCR_Cx_OTHER_VP, vp); - - if (cm_rev >= CM_REV_CM3_5) { - val |= CM_GCR_Cx_OTHER_CLUSTER_EN; -- val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER); -- val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK); -+ val |= FIELD_PREP(CM_GCR_Cx_OTHER_CLUSTER, cluster); -+ val |= FIELD_PREP(CM_GCR_Cx_OTHER_BLOCK, block); - } else { - WARN_ON(cluster != 0); - WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); -@@ -342,7 +341,7 @@ void mips_cm_lock_other(unsigned int cluster, unsigned int core, - spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), - per_cpu(cm_core_lock_flags, curr_core)); - -- val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM); -+ val = FIELD_PREP(CM_GCR_Cx_OTHER_CORENUM, core); - } - - write_gcr_cl_other(val); -@@ -386,8 +385,8 @@ void mips_cm_error_report(void) - cm_other = read_gcr_error_mult(); - - if (revision < CM_REV_CM3) { /* CM2 */ -- cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE); -- ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); -+ cause = FIELD_GET(CM_GCR_ERROR_CAUSE_ERRTYPE, cm_error); -+ ocause = FIELD_GET(CM_GCR_ERROR_MULT_ERR2ND, cm_other); - - if (!cause) - return; -@@ -445,8 +444,8 @@ void mips_cm_error_report(void) - ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; - ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit; - -- cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE); -- ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); -+ cause = FIELD_GET(CM3_GCR_ERROR_CAUSE_ERRTYPE, cm_error); -+ ocause = FIELD_GET(CM_GCR_ERROR_MULT_ERR2ND, cm_other); - - if (!cause) - return; -diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c -index a39ec755e4c24..750fe569862b6 100644 ---- a/arch/mips/kernel/mips-r2-to-r6-emul.c -+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c -@@ -1258,10 +1258,10 @@ fpu_emul: - " j 10b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1333,10 +1333,10 @@ fpu_emul: - " j 10b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1404,10 +1404,10 @@ fpu_emul: - " j 9b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1474,10 +1474,10 @@ fpu_emul: - " j 9b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1589,14 +1589,14 @@ fpu_emul: - " j 9b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -- STR(PTR) " 5b,8b\n" -- STR(PTR) " 6b,8b\n" -- STR(PTR) " 7b,8b\n" -- STR(PTR) " 0b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" -+ STR(PTR_WD) " 5b,8b\n" -+ STR(PTR_WD) " 6b,8b\n" -+ STR(PTR_WD) " 7b,8b\n" -+ STR(PTR_WD) " 0b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1708,14 +1708,14 @@ fpu_emul: - " j 9b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -- STR(PTR) " 5b,8b\n" -- STR(PTR) " 6b,8b\n" -- STR(PTR) " 7b,8b\n" -- STR(PTR) " 0b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" -+ STR(PTR_WD) " 5b,8b\n" -+ STR(PTR_WD) " 6b,8b\n" -+ STR(PTR_WD) " 7b,8b\n" -+ STR(PTR_WD) " 0b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1827,14 +1827,14 @@ fpu_emul: - " j 9b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -- STR(PTR) " 5b,8b\n" -- STR(PTR) " 6b,8b\n" -- STR(PTR) " 7b,8b\n" -- STR(PTR) " 0b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" -+ STR(PTR_WD) " 5b,8b\n" -+ STR(PTR_WD) " 6b,8b\n" -+ STR(PTR_WD) " 7b,8b\n" -+ STR(PTR_WD) " 0b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -1945,14 +1945,14 @@ fpu_emul: - " j 9b\n" - " .previous\n" - " .section __ex_table,\"a\"\n" -- STR(PTR) " 1b,8b\n" -- STR(PTR) " 2b,8b\n" -- STR(PTR) " 3b,8b\n" -- STR(PTR) " 4b,8b\n" -- STR(PTR) " 5b,8b\n" -- STR(PTR) " 6b,8b\n" -- STR(PTR) " 7b,8b\n" -- STR(PTR) " 0b,8b\n" -+ STR(PTR_WD) " 1b,8b\n" -+ STR(PTR_WD) " 2b,8b\n" -+ STR(PTR_WD) " 3b,8b\n" -+ STR(PTR_WD) " 4b,8b\n" -+ STR(PTR_WD) " 5b,8b\n" -+ STR(PTR_WD) " 6b,8b\n" -+ STR(PTR_WD) " 7b,8b\n" -+ STR(PTR_WD) " 0b,8b\n" - " .previous\n" - " .set pop\n" - : "+&r"(rt), "=&r"(rs), -@@ -2007,7 +2007,7 @@ fpu_emul: - "j 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" -- STR(PTR) " 1b,3b\n" -+ STR(PTR_WD) " 1b,3b\n" - ".previous\n" - : "=&r"(res), "+&r"(err) - : "r"(vaddr), "i"(SIGSEGV) -@@ -2065,7 +2065,7 @@ fpu_emul: - "j 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" -- STR(PTR) " 1b,3b\n" -+ STR(PTR_WD) " 1b,3b\n" - ".previous\n" - : "+&r"(res), "+&r"(err) - : "r"(vaddr), "i"(SIGSEGV)); -@@ -2126,7 +2126,7 @@ fpu_emul: - "j 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" -- STR(PTR) " 1b,3b\n" -+ STR(PTR_WD) " 1b,3b\n" - ".previous\n" - : "=&r"(res), "+&r"(err) - : "r"(vaddr), "i"(SIGSEGV) -@@ -2189,7 +2189,7 @@ fpu_emul: - "j 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" -- STR(PTR) " 1b,3b\n" -+ STR(PTR_WD) " 1b,3b\n" - ".previous\n" - : "+&r"(res), "+&r"(err) - : "r"(vaddr), "i"(SIGSEGV)); -diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S -index 12e58053544fc..2748c55820c24 100644 ---- a/arch/mips/kernel/r2300_fpu.S -+++ b/arch/mips/kernel/r2300_fpu.S -@@ -23,14 +23,14 @@ - #define EX(a,b) \ - 9: a,##b; \ - .section __ex_table,"a"; \ -- PTR 9b,fault; \ -+ PTR_WD 9b,fault; \ - .previous - - #define EX2(a,b) \ - 9: a,##b; \ - .section __ex_table,"a"; \ -- PTR 9b,bad_stack; \ -- PTR 9b+4,bad_stack; \ -+ PTR_WD 9b,fault; \ -+ PTR_WD 9b+4,fault; \ - .previous - - .set mips1 -diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S -index b91e911064756..2e687c60bc4f1 100644 ---- a/arch/mips/kernel/r4k_fpu.S -+++ b/arch/mips/kernel/r4k_fpu.S -@@ -31,7 +31,7 @@ - .ex\@: \insn \reg, \src - .set pop - .section __ex_table,"a" -- PTR .ex\@, fault -+ PTR_WD .ex\@, fault - .previous - .endm - -diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S -index f3c908abdbb80..cfde14b48fd8d 100644 ---- a/arch/mips/kernel/relocate_kernel.S -+++ b/arch/mips/kernel/relocate_kernel.S -@@ -147,10 +147,10 @@ LEAF(kexec_smp_wait) - - kexec_args: - EXPORT(kexec_args) --arg0: PTR 0x0 --arg1: PTR 0x0 --arg2: PTR 0x0 --arg3: PTR 0x0 -+arg0: PTR_WD 0x0 -+arg1: PTR_WD 0x0 -+arg2: PTR_WD 0x0 -+arg3: PTR_WD 0x0 - .size kexec_args,PTRSIZE*4 - - #ifdef CONFIG_SMP -@@ -161,10 +161,10 @@ arg3: PTR 0x0 - */ - secondary_kexec_args: - EXPORT(secondary_kexec_args) --s_arg0: PTR 0x0 --s_arg1: PTR 0x0 --s_arg2: PTR 0x0 --s_arg3: PTR 0x0 -+s_arg0: PTR_WD 0x0 -+s_arg1: PTR_WD 0x0 -+s_arg2: PTR_WD 0x0 -+s_arg3: PTR_WD 0x0 - .size secondary_kexec_args,PTRSIZE*4 - kexec_flag: - LONG 0x1 -@@ -173,17 +173,17 @@ kexec_flag: - - kexec_start_address: - EXPORT(kexec_start_address) -- PTR 0x0 -+ PTR_WD 0x0 - .size kexec_start_address, PTRSIZE - - kexec_indirection_page: - EXPORT(kexec_indirection_page) -- PTR 0 -+ PTR_WD 0 - .size kexec_indirection_page, PTRSIZE - - relocate_new_kernel_end: - - relocate_new_kernel_size: - EXPORT(relocate_new_kernel_size) -- PTR relocate_new_kernel_end - relocate_new_kernel -+ PTR_WD relocate_new_kernel_end - relocate_new_kernel - .size relocate_new_kernel_size, PTRSIZE -diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S -index b1b2e106f7118..9bfce5f75f601 100644 ---- a/arch/mips/kernel/scall32-o32.S -+++ b/arch/mips/kernel/scall32-o32.S -@@ -72,10 +72,10 @@ loads_done: - .set pop - - .section __ex_table,"a" -- PTR load_a4, bad_stack_a4 -- PTR load_a5, bad_stack_a5 -- PTR load_a6, bad_stack_a6 -- PTR load_a7, bad_stack_a7 -+ PTR_WD load_a4, bad_stack_a4 -+ PTR_WD load_a5, bad_stack_a5 -+ PTR_WD load_a6, bad_stack_a6 -+ PTR_WD load_a7, bad_stack_a7 - .previous - - lw t0, TI_FLAGS($28) # syscall tracing enabled? -@@ -216,7 +216,7 @@ einval: li v0, -ENOSYS - #endif /* CONFIG_MIPS_MT_FPAFF */ - - #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) --#define __SYSCALL(nr, entry) PTR entry -+#define __SYSCALL(nr, entry) PTR_WD entry - .align 2 - .type sys_call_table, @object - EXPORT(sys_call_table) -diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S -index f650c55a17dc5..97456b2ca7dc3 100644 ---- a/arch/mips/kernel/scall64-n32.S -+++ b/arch/mips/kernel/scall64-n32.S -@@ -101,7 +101,7 @@ not_n32_scall: - - END(handle_sysn32) - --#define __SYSCALL(nr, entry) PTR entry -+#define __SYSCALL(nr, entry) PTR_WD entry - .type sysn32_call_table, @object - EXPORT(sysn32_call_table) - #include -diff --git a/arch/mips/kernel/scall64-n64.S b/arch/mips/kernel/scall64-n64.S -index 5d7bfc65e4d0b..5f6ed4b4c3993 100644 ---- a/arch/mips/kernel/scall64-n64.S -+++ b/arch/mips/kernel/scall64-n64.S -@@ -109,7 +109,7 @@ illegal_syscall: - j n64_syscall_exit - END(handle_sys64) - --#define __SYSCALL(nr, entry) PTR entry -+#define __SYSCALL(nr, entry) PTR_WD entry - .align 3 - .type sys_call_table, @object - EXPORT(sys_call_table) -diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S -index cedc8bd888046..d3c2616cba226 100644 ---- a/arch/mips/kernel/scall64-o32.S -+++ b/arch/mips/kernel/scall64-o32.S -@@ -73,10 +73,10 @@ load_a7: lw a7, 28(t0) # argument #8 from usp - loads_done: - - .section __ex_table,"a" -- PTR load_a4, bad_stack_a4 -- PTR load_a5, bad_stack_a5 -- PTR load_a6, bad_stack_a6 -- PTR load_a7, bad_stack_a7 -+ PTR_WD load_a4, bad_stack_a4 -+ PTR_WD load_a5, bad_stack_a5 -+ PTR_WD load_a6, bad_stack_a6 -+ PTR_WD load_a7, bad_stack_a7 - .previous - - li t1, _TIF_WORK_SYSCALL_ENTRY -@@ -214,7 +214,7 @@ einval: li v0, -ENOSYS - END(sys32_syscall) - - #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat) --#define __SYSCALL(nr, entry) PTR entry -+#define __SYSCALL(nr, entry) PTR_WD entry - .align 3 - .type sys32_call_table,@object - EXPORT(sys32_call_table) -diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c -index f979adfd4fc20..ef73ba1e0ec10 100644 ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -803,7 +803,7 @@ early_param("coherentio", setcoherentio); - - static int __init setnocoherentio(char *str) - { -- dma_default_coherent = true; -+ dma_default_coherent = false; - pr_info("Software DMA cache coherency (command line)\n"); - return 0; - } -diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c -index 2afa3eef486a9..ae93a607ddf7e 100644 ---- a/arch/mips/kernel/syscall.c -+++ b/arch/mips/kernel/syscall.c -@@ -122,8 +122,8 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) - " j 3b \n" - " .previous \n" - " .section __ex_table,\"a\" \n" -- " "STR(PTR)" 1b, 4b \n" -- " "STR(PTR)" 2b, 4b \n" -+ " "STR(PTR_WD)" 1b, 4b \n" -+ " "STR(PTR_WD)" 2b, 4b \n" - " .previous \n" - " .set pop \n" - : [old] "=&r" (old), -@@ -152,8 +152,8 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) - " j 3b \n" - " .previous \n" - " .section __ex_table,\"a\" \n" -- " "STR(PTR)" 1b, 5b \n" -- " "STR(PTR)" 2b, 5b \n" -+ " "STR(PTR_WD)" 1b, 5b \n" -+ " "STR(PTR_WD)" 2b, 5b \n" - " .previous \n" - " .set pop \n" - : [old] "=&r" (old), -@@ -240,12 +240,3 @@ SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op) - { - return -ENOSYS; - } -- --/* -- * If we ever come here the user sp is bad. Zap the process right away. -- * Due to the bad stack signaling wouldn't work. -- */ --asmlinkage void bad_stack(void) --{ -- do_exit(SIGSEGV); --} -diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c -index dd819e31fcbbf..7a623684d9b5e 100644 ---- a/arch/mips/lantiq/clk.c -+++ b/arch/mips/lantiq/clk.c -@@ -158,6 +158,18 @@ void clk_deactivate(struct clk *clk) - } - EXPORT_SYMBOL(clk_deactivate); - -+struct clk *clk_get_parent(struct clk *clk) -+{ -+ return NULL; -+} -+EXPORT_SYMBOL(clk_get_parent); -+ -+int clk_set_parent(struct clk *clk, struct clk *parent) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(clk_set_parent); -+ - static inline u32 get_counter_resolution(void) - { - u32 res; -diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c -index 63dccb2ed08b2..53fcc672a2944 100644 ---- a/arch/mips/lantiq/xway/dma.c -+++ b/arch/mips/lantiq/xway/dma.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -30,6 +31,7 @@ - #define LTQ_DMA_PCTRL 0x44 - #define LTQ_DMA_IRNEN 0xf4 - -+#define DMA_ID_CHNR GENMASK(26, 20) /* channel number */ - #define DMA_DESCPT BIT(3) /* descriptor complete irq */ - #define DMA_TX BIT(8) /* TX channel direction */ - #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ -@@ -39,8 +41,11 @@ - #define DMA_IRQ_ACK 0x7e /* IRQ status register */ - #define DMA_POLL BIT(31) /* turn on channel polling */ - #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ --#define DMA_2W_BURST BIT(1) /* 2 word burst length */ --#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ -+#define DMA_PCTRL_2W_BURST 0x1 /* 2 word burst length */ -+#define DMA_PCTRL_4W_BURST 0x2 /* 4 word burst length */ -+#define DMA_PCTRL_8W_BURST 0x3 /* 8 word burst length */ -+#define DMA_TX_BURST_SHIFT 4 /* tx burst shift */ -+#define DMA_RX_BURST_SHIFT 2 /* rx burst shift */ - #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ - #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ - -@@ -191,7 +196,8 @@ ltq_dma_init_port(int p) - break; - - case DMA_PORT_DEU: -- ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2), -+ ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) | -+ (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), - LTQ_DMA_PCTRL); - break; - -@@ -206,7 +212,7 @@ ltq_dma_init(struct platform_device *pdev) - { - struct clk *clk; - struct resource *res; -- unsigned id; -+ unsigned int id, nchannels; - int i; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -222,21 +228,24 @@ ltq_dma_init(struct platform_device *pdev) - clk_enable(clk); - ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); - -+ usleep_range(1, 10); -+ - /* disable all interrupts */ - ltq_dma_w32(0, LTQ_DMA_IRNEN); - - /* reset/configure each channel */ -- for (i = 0; i < DMA_MAX_CHANNEL; i++) { -+ id = ltq_dma_r32(LTQ_DMA_ID); -+ nchannels = ((id & DMA_ID_CHNR) >> 20); -+ for (i = 0; i < nchannels; i++) { - ltq_dma_w32(i, LTQ_DMA_CS); - ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); - ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); - ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); - } - -- id = ltq_dma_r32(LTQ_DMA_ID); - dev_info(&pdev->dev, - "Init done - hw rev: %X, ports: %d, channels: %d\n", -- id & 0x1f, (id >> 16) & 0xf, id >> 20); -+ id & 0x1f, (id >> 16) & 0xf, nchannels); - - return 0; - } -diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S -index a46db08071953..7767137c3e49a 100644 ---- a/arch/mips/lib/csum_partial.S -+++ b/arch/mips/lib/csum_partial.S -@@ -347,7 +347,7 @@ EXPORT_SYMBOL(csum_partial) - .if \mode == LEGACY_MODE; \ - 9: insn reg, addr; \ - .section __ex_table,"a"; \ -- PTR 9b, .L_exc; \ -+ PTR_WD 9b, .L_exc; \ - .previous; \ - /* This is enabled in EVA mode */ \ - .else; \ -@@ -356,7 +356,7 @@ EXPORT_SYMBOL(csum_partial) - ((\to == USEROP) && (type == ST_INSN)); \ - 9: __BUILD_EVA_INSN(insn##e, reg, addr); \ - .section __ex_table,"a"; \ -- PTR 9b, .L_exc; \ -+ PTR_WD 9b, .L_exc; \ - .previous; \ - .else; \ - /* EVA without exception */ \ -diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S -index 277c32296636d..18a43f2e29c81 100644 ---- a/arch/mips/lib/memcpy.S -+++ b/arch/mips/lib/memcpy.S -@@ -116,7 +116,7 @@ - .if \mode == LEGACY_MODE; \ - 9: insn reg, addr; \ - .section __ex_table,"a"; \ -- PTR 9b, handler; \ -+ PTR_WD 9b, handler; \ - .previous; \ - /* This is assembled in EVA mode */ \ - .else; \ -@@ -125,7 +125,7 @@ - ((\to == USEROP) && (type == ST_INSN)); \ - 9: __BUILD_EVA_INSN(insn##e, reg, addr); \ - .section __ex_table,"a"; \ -- PTR 9b, handler; \ -+ PTR_WD 9b, handler; \ - .previous; \ - .else; \ - /* \ -diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S -index b0baa3c79fad0..0b342bae9a98c 100644 ---- a/arch/mips/lib/memset.S -+++ b/arch/mips/lib/memset.S -@@ -52,7 +52,7 @@ - 9: ___BUILD_EVA_INSN(insn, reg, addr); \ - .endif; \ - .section __ex_table,"a"; \ -- PTR 9b, handler; \ -+ PTR_WD 9b, handler; \ - .previous - - .macro f_fill64 dst, offset, val, fixup, mode -diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S -index 556acf684d7be..13aaa9927ad12 100644 ---- a/arch/mips/lib/strncpy_user.S -+++ b/arch/mips/lib/strncpy_user.S -@@ -15,7 +15,7 @@ - #define EX(insn,reg,addr,handler) \ - 9: insn reg, addr; \ - .section __ex_table,"a"; \ -- PTR 9b, handler; \ -+ PTR_WD 9b, handler; \ - .previous - - /* -@@ -59,7 +59,7 @@ LEAF(__strncpy_from_user_asm) - jr ra - - .section __ex_table,"a" -- PTR 1b, .Lfault -+ PTR_WD 1b, .Lfault - .previous - - EXPORT_SYMBOL(__strncpy_from_user_asm) -diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S -index 92b63f20ec05f..6de31b616f9c1 100644 ---- a/arch/mips/lib/strnlen_user.S -+++ b/arch/mips/lib/strnlen_user.S -@@ -14,7 +14,7 @@ - #define EX(insn,reg,addr,handler) \ - 9: insn reg, addr; \ - .section __ex_table,"a"; \ -- PTR 9b, handler; \ -+ PTR_WD 9b, handler; \ - .previous - - /* -diff --git a/arch/mips/loongson64/vbios_quirk.c b/arch/mips/loongson64/vbios_quirk.c -index 9a29e94d3db1d..3115d4de982c5 100644 ---- a/arch/mips/loongson64/vbios_quirk.c -+++ b/arch/mips/loongson64/vbios_quirk.c -@@ -3,7 +3,7 @@ - #include - #include - --static void pci_fixup_radeon(struct pci_dev *pdev) -+static void pci_fixup_video(struct pci_dev *pdev) - { - struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - -@@ -22,8 +22,7 @@ static void pci_fixup_radeon(struct pci_dev *pdev) - res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | - IORESOURCE_PCI_FIXED; - -- dev_info(&pdev->dev, "BAR %d: assigned %pR for Radeon ROM\n", -- PCI_ROM_RESOURCE, res); -+ dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n", res); - } --DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, 0x9615, -- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_radeon); -+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, 0x9615, -+ PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); -diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c -index bd71f5b142383..4c83786612193 100644 ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -20,31 +20,41 @@ - - #include "common.h" - --static void *detect_magic __initdata = detect_memory_region; -+#define MT7621_MEM_TEST_PATTERN 0xaa5555aa -+ -+static u32 detect_magic __initdata; - - phys_addr_t mips_cpc_default_phys_base(void) - { - panic("Cannot detect cpc address"); - } - -+static bool __init mt7621_addr_wraparound_test(phys_addr_t size) -+{ -+ void *dm = (void *)KSEG1ADDR(&detect_magic); -+ -+ if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE) -+ return true; -+ __raw_writel(MT7621_MEM_TEST_PATTERN, dm); -+ if (__raw_readl(dm) != __raw_readl(dm + size)) -+ return false; -+ __raw_writel(~MT7621_MEM_TEST_PATTERN, dm); -+ return __raw_readl(dm) == __raw_readl(dm + size); -+} -+ - static void __init mt7621_memory_detect(void) - { -- void *dm = &detect_magic; - phys_addr_t size; - -- for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) { -- if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic))) -- break; -+ for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) { -+ if (mt7621_addr_wraparound_test(size)) { -+ memblock_add(MT7621_LOWMEM_BASE, size); -+ return; -+ } - } - -- if ((size == 256 * SZ_1M) && -- (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) && -- __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) { -- memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE); -- memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE); -- } else { -- memblock_add(MT7621_LOWMEM_BASE, size); -- } -+ memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE); -+ memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE); - } - - void __init ralink_of_remap(void) -diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c -index 240bb68ec2478..ff3ba7e778901 100644 ---- a/arch/mips/sni/time.c -+++ b/arch/mips/sni/time.c -@@ -18,14 +18,14 @@ static int a20r_set_periodic(struct clock_event_device *evt) - { - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; - wmb(); -- *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV; -+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV & 0xff; - wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8; - wmb(); - - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; - wmb(); -- *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV; -+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV & 0xff; - wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8; - wmb(); -diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c -index 0ce6f9f307e6a..f387919607813 100644 ---- a/arch/nds32/kernel/perf_event_cpu.c -+++ b/arch/nds32/kernel/perf_event_cpu.c -@@ -1363,6 +1363,7 @@ void - perf_callchain_user(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - unsigned long fp = 0; - unsigned long gp = 0; - unsigned long lp = 0; -@@ -1371,7 +1372,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, - - leaf_fp = 0; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* We don't support guest os callchain now */ - return; - } -@@ -1479,9 +1480,10 @@ void - perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct stackframe fr; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* We don't support guest os callchain now */ - return; - } -@@ -1493,20 +1495,23 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - - unsigned long perf_instruction_pointer(struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); -+ - /* However, NDS32 does not support virtualization */ -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) -- return perf_guest_cbs->get_guest_ip(); -+ if (guest_cbs && guest_cbs->is_in_guest()) -+ return guest_cbs->get_guest_ip(); - - return instruction_pointer(regs); - } - - unsigned long perf_misc_flags(struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - int misc = 0; - - /* However, NDS32 does not support virtualization */ -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -- if (perf_guest_cbs->is_user_mode()) -+ if (guest_cbs && guest_cbs->is_in_guest()) { -+ if (guest_cbs->is_user_mode()) - misc |= PERF_RECORD_MISC_GUEST_USER; - else - misc |= PERF_RECORD_MISC_GUEST_KERNEL; -diff --git a/arch/openrisc/include/asm/syscalls.h b/arch/openrisc/include/asm/syscalls.h -index 3a7eeae6f56a8..aa1c7e98722e3 100644 ---- a/arch/openrisc/include/asm/syscalls.h -+++ b/arch/openrisc/include/asm/syscalls.h -@@ -22,9 +22,11 @@ asmlinkage long sys_or1k_atomic(unsigned long type, unsigned long *v1, - - asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid, int tls); -+asmlinkage long __sys_clone3(struct clone_args __user *uargs, size_t size); - asmlinkage long __sys_fork(void); - - #define sys_clone __sys_clone -+#define sys_clone3 __sys_clone3 - #define sys_fork __sys_fork - - #endif /* __ASM_OPENRISC_SYSCALLS_H */ -diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c -index 1b16d97e7da7f..a82b2caaa560d 100644 ---- a/arch/openrisc/kernel/dma.c -+++ b/arch/openrisc/kernel/dma.c -@@ -33,7 +33,7 @@ page_set_nocache(pte_t *pte, unsigned long addr, - * Flush the page out of the TLB so that the new page flags get - * picked up next time there's an access - */ -- flush_tlb_page(NULL, addr); -+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE); - - /* Flush page out of dcache */ - for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo->dcache_block_size) -@@ -56,7 +56,7 @@ page_clear_nocache(pte_t *pte, unsigned long addr, - * Flush the page out of the TLB so that the new page flags get - * picked up next time there's an access - */ -- flush_tlb_page(NULL, addr); -+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE); - - return 0; - } -diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S -index edaa775a648e6..c68f3349c1741 100644 ---- a/arch/openrisc/kernel/entry.S -+++ b/arch/openrisc/kernel/entry.S -@@ -1170,6 +1170,11 @@ ENTRY(__sys_clone) - l.j _fork_save_extra_regs_and_call - l.nop - -+ENTRY(__sys_clone3) -+ l.movhi r29,hi(sys_clone3) -+ l.j _fork_save_extra_regs_and_call -+ l.ori r29,r29,lo(sys_clone3) -+ - ENTRY(__sys_fork) - l.movhi r29,hi(sys_fork) - l.ori r29,r29,lo(sys_fork) -diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c -index 415e209732a3d..ba78766cf00b5 100644 ---- a/arch/openrisc/kernel/smp.c -+++ b/arch/openrisc/kernel/smp.c -@@ -272,7 +272,7 @@ static inline void ipi_flush_tlb_range(void *info) - local_flush_tlb_range(NULL, fd->addr1, fd->addr2); - } - --static void smp_flush_tlb_range(struct cpumask *cmask, unsigned long start, -+static void smp_flush_tlb_range(const struct cpumask *cmask, unsigned long start, - unsigned long end) - { - unsigned int cpuid; -@@ -320,7 +320,9 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) - void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) - { -- smp_flush_tlb_range(mm_cpumask(vma->vm_mm), start, end); -+ const struct cpumask *cmask = vma ? mm_cpumask(vma->vm_mm) -+ : cpu_online_mask; -+ smp_flush_tlb_range(cmask, start, end); - } - - /* Instruction cache invalidate - performed on each cpu */ -diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile -index fcde3ffa02213..fadb098de1545 100644 ---- a/arch/parisc/Makefile -+++ b/arch/parisc/Makefile -@@ -17,7 +17,12 @@ - # Mike Shaver, Helge Deller and Martin K. Petersen - # - -+ifdef CONFIG_PARISC_SELF_EXTRACT -+boot := arch/parisc/boot -+KBUILD_IMAGE := $(boot)/bzImage -+else - KBUILD_IMAGE := vmlinuz -+endif - - NM = sh $(srctree)/arch/parisc/nm - CHECKFLAGS += -D__hppa__=1 -diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bitops.h -index aa4e883431c1a..5779d463b341f 100644 ---- a/arch/parisc/include/asm/bitops.h -+++ b/arch/parisc/include/asm/bitops.h -@@ -12,6 +12,14 @@ - #include - #include - -+/* compiler build environment sanity checks: */ -+#if !defined(CONFIG_64BIT) && defined(__LP64__) -+#error "Please use 'ARCH=parisc' to build the 32-bit kernel." -+#endif -+#if defined(CONFIG_64BIT) && !defined(__LP64__) -+#error "Please use 'ARCH=parisc64' to build the 64-bit kernel." -+#endif -+ - /* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion - * on use of volatile and __*_bit() (set/clear/change): - * *_bit() want use of volatile. -diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h -index fceb9cf02fb3a..71aa0921d6c72 100644 ---- a/arch/parisc/include/asm/futex.h -+++ b/arch/parisc/include/asm/futex.h -@@ -16,7 +16,7 @@ static inline void - _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) - { - extern u32 lws_lock_start[]; -- long index = ((long)uaddr & 0x3f8) >> 1; -+ long index = ((long)uaddr & 0x7f8) >> 1; - arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; - local_irq_save(*flags); - arch_spin_lock(s); -@@ -26,7 +26,7 @@ static inline void - _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) - { - extern u32 lws_lock_start[]; -- long index = ((long)uaddr & 0x3f8) >> 1; -+ long index = ((long)uaddr & 0x7f8) >> 1; - arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; - arch_spin_unlock(s); - local_irq_restore(*flags); -diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h -index 7badd872f05ac..3e7cf882639fb 100644 ---- a/arch/parisc/include/asm/pgtable.h -+++ b/arch/parisc/include/asm/pgtable.h -@@ -76,6 +76,8 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) - purge_tlb_end(flags); - } - -+extern void __update_cache(pte_t pte); -+ - /* Certain architectures need to do special things when PTEs - * within a page table are directly modified. Thus, the following - * hook is made available. -@@ -83,11 +85,14 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) - #define set_pte(pteptr, pteval) \ - do { \ - *(pteptr) = (pteval); \ -- barrier(); \ -+ mb(); \ - } while(0) - - #define set_pte_at(mm, addr, pteptr, pteval) \ - do { \ -+ if (pte_present(pteval) && \ -+ pte_user(pteval)) \ -+ __update_cache(pteval); \ - *(pteptr) = (pteval); \ - purge_tlb_entries(mm, addr); \ - } while (0) -@@ -303,6 +308,7 @@ extern unsigned long *empty_zero_page; - - #define pte_none(x) (pte_val(x) == 0) - #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) -+#define pte_user(x) (pte_val(x) & _PAGE_USER) - #define pte_clear(mm, addr, xp) set_pte_at(mm, addr, xp, __pte(0)) - - #define pmd_flag(x) (pmd_val(x) & PxD_FLAG_MASK) -@@ -410,7 +416,7 @@ extern void paging_init (void); - - #define PG_dcache_dirty PG_arch_1 - --extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); -+#define update_mmu_cache(vms,addr,ptep) __update_cache(*ptep) - - /* Encode and de-code a swap entry */ - -diff --git a/arch/parisc/include/asm/rt_sigframe.h b/arch/parisc/include/asm/rt_sigframe.h -index 4b9e3d707571b..2b3010ade00e7 100644 ---- a/arch/parisc/include/asm/rt_sigframe.h -+++ b/arch/parisc/include/asm/rt_sigframe.h -@@ -2,7 +2,7 @@ - #ifndef _ASM_PARISC_RT_SIGFRAME_H - #define _ASM_PARISC_RT_SIGFRAME_H - --#define SIGRETURN_TRAMP 3 -+#define SIGRETURN_TRAMP 4 - #define SIGRESTARTBLOCK_TRAMP 5 - #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP) - -diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h -index a303ae9a77f41..16ee41e77174f 100644 ---- a/arch/parisc/include/asm/special_insns.h -+++ b/arch/parisc/include/asm/special_insns.h -@@ -2,28 +2,32 @@ - #ifndef __PARISC_SPECIAL_INSNS_H - #define __PARISC_SPECIAL_INSNS_H - --#define lpa(va) ({ \ -- unsigned long pa; \ -- __asm__ __volatile__( \ -- "copy %%r0,%0\n\t" \ -- "lpa %%r0(%1),%0" \ -- : "=r" (pa) \ -- : "r" (va) \ -- : "memory" \ -- ); \ -- pa; \ -+#define lpa(va) ({ \ -+ unsigned long pa; \ -+ __asm__ __volatile__( \ -+ "copy %%r0,%0\n" \ -+ "8:\tlpa %%r0(%1),%0\n" \ -+ "9:\n" \ -+ ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ -+ : "=&r" (pa) \ -+ : "r" (va) \ -+ : "memory" \ -+ ); \ -+ pa; \ - }) - --#define lpa_user(va) ({ \ -- unsigned long pa; \ -- __asm__ __volatile__( \ -- "copy %%r0,%0\n\t" \ -- "lpa %%r0(%%sr3,%1),%0" \ -- : "=r" (pa) \ -- : "r" (va) \ -- : "memory" \ -- ); \ -- pa; \ -+#define lpa_user(va) ({ \ -+ unsigned long pa; \ -+ __asm__ __volatile__( \ -+ "copy %%r0,%0\n" \ -+ "8:\tlpa %%r0(%%sr3,%1),%0\n" \ -+ "9:\n" \ -+ ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ -+ : "=&r" (pa) \ -+ : "r" (va) \ -+ : "memory" \ -+ ); \ -+ pa; \ - }) - - #define mfctl(reg) ({ \ -diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh -index 056d588befdd6..70d3cffb02515 100644 ---- a/arch/parisc/install.sh -+++ b/arch/parisc/install.sh -@@ -39,6 +39,7 @@ verify "$3" - if [ -n "${INSTALLKERNEL}" ]; then - if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi - if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi -+ if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi - fi - - # Default install -diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c -index 39e02227e2310..4ed4942d8312b 100644 ---- a/arch/parisc/kernel/cache.c -+++ b/arch/parisc/kernel/cache.c -@@ -83,9 +83,9 @@ EXPORT_SYMBOL(flush_cache_all_local); - #define pfn_va(pfn) __va(PFN_PHYS(pfn)) - - void --update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) -+__update_cache(pte_t pte) - { -- unsigned long pfn = pte_pfn(*ptep); -+ unsigned long pfn = pte_pfn(pte); - struct page *page; - - /* We don't have pte special. As a result, we can be called with -diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S -index 9f939afe6b88c..437c8d31f3907 100644 ---- a/arch/parisc/kernel/entry.S -+++ b/arch/parisc/kernel/entry.S -@@ -1834,8 +1834,8 @@ syscall_restore: - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - - /* Are we being ptraced? */ -- ldw TASK_FLAGS(%r1),%r19 -- ldi _TIF_SYSCALL_TRACE_MASK,%r2 -+ LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 -+ ldi _TIF_SINGLESTEP|_TIF_BLOCKSTEP,%r2 - and,COND(=) %r19,%r2,%r0 - b,n syscall_restore_rfi - -diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c -index bbfe23c40c016..0fb06d87b3a5c 100644 ---- a/arch/parisc/kernel/signal.c -+++ b/arch/parisc/kernel/signal.c -@@ -288,21 +288,22 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, - already in userspace. The first words of tramp are used to - save the previous sigrestartblock trampoline that might be - on the stack. We start the sigreturn trampoline at -- SIGRESTARTBLOCK_TRAMP. */ -+ SIGRESTARTBLOCK_TRAMP+X. */ - err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0, - &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]); -- err |= __put_user(INSN_BLE_SR2_R0, -- &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]); - err |= __put_user(INSN_LDI_R20, -+ &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]); -+ err |= __put_user(INSN_BLE_SR2_R0, - &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]); -+ err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]); - -- start = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]; -- end = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]; -+ start = (unsigned long) &frame->tramp[0]; -+ end = (unsigned long) &frame->tramp[TRAMP_SIZE]; - flush_user_dcache_range_asm(start, end); - flush_user_icache_range_asm(start, end); - - /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP -- * TRAMP Words 5-7, Length 3 = SIGRETURN_TRAMP -+ * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP - * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP - */ - rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP]; -diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h -index a5bdbb5678b72..f166250f2d064 100644 ---- a/arch/parisc/kernel/signal32.h -+++ b/arch/parisc/kernel/signal32.h -@@ -36,7 +36,7 @@ struct compat_regfile { - compat_int_t rf_sar; - }; - --#define COMPAT_SIGRETURN_TRAMP 3 -+#define COMPAT_SIGRETURN_TRAMP 4 - #define COMPAT_SIGRESTARTBLOCK_TRAMP 5 - #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ - COMPAT_SIGRESTARTBLOCK_TRAMP) -diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c -index 1405b603b91b6..cf92ece20b757 100644 ---- a/arch/parisc/kernel/smp.c -+++ b/arch/parisc/kernel/smp.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -69,7 +70,10 @@ enum ipi_message_type { - IPI_CALL_FUNC, - IPI_CPU_START, - IPI_CPU_STOP, -- IPI_CPU_TEST -+ IPI_CPU_TEST, -+#ifdef CONFIG_KGDB -+ IPI_ENTER_KGDB, -+#endif - }; - - -@@ -167,7 +171,12 @@ ipi_interrupt(int irq, void *dev_id) - case IPI_CPU_TEST: - smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu); - break; -- -+#ifdef CONFIG_KGDB -+ case IPI_ENTER_KGDB: -+ smp_debug(100, KERN_DEBUG "CPU%d ENTER_KGDB\n", this_cpu); -+ kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); -+ break; -+#endif - default: - printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", - this_cpu, which); -@@ -226,6 +235,12 @@ send_IPI_allbutself(enum ipi_message_type op) - } - } - -+#ifdef CONFIG_KGDB -+void kgdb_roundup_cpus(void) -+{ -+ send_IPI_allbutself(IPI_ENTER_KGDB); -+} -+#endif - - inline void - smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); } -diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S -index 3f24a0af1e047..9842dcb2041e5 100644 ---- a/arch/parisc/kernel/syscall.S -+++ b/arch/parisc/kernel/syscall.S -@@ -478,7 +478,7 @@ lws_start: - extrd,u %r1,PSW_W_BIT,1,%r1 - /* sp must be aligned on 4, so deposit the W bit setting into - * the bottom of sp temporarily */ -- or,ev %r1,%r30,%r30 -+ or,od %r1,%r30,%r30 - - /* Clip LWS number to a 32-bit value for 32-bit processes */ - depdi 0, 31, 32, %r20 -diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c -index 9fb1e794831b0..061119a56fbe8 100644 ---- a/arch/parisc/kernel/time.c -+++ b/arch/parisc/kernel/time.c -@@ -249,30 +249,16 @@ void __init time_init(void) - static int __init init_cr16_clocksource(void) - { - /* -- * The cr16 interval timers are not syncronized across CPUs on -- * different sockets, so mark them unstable and lower rating on -- * multi-socket SMP systems. -+ * The cr16 interval timers are not syncronized across CPUs, even if -+ * they share the same socket. - */ - if (num_online_cpus() > 1 && !running_on_qemu) { -- int cpu; -- unsigned long cpu0_loc; -- cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; -- -- for_each_online_cpu(cpu) { -- if (cpu == 0) -- continue; -- if ((cpu0_loc != 0) && -- (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)) -- continue; -- -- /* mark sched_clock unstable */ -- clear_sched_clock_stable(); -- -- clocksource_cr16.name = "cr16_unstable"; -- clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; -- clocksource_cr16.rating = 0; -- break; -- } -+ /* mark sched_clock unstable */ -+ clear_sched_clock_stable(); -+ -+ clocksource_cr16.name = "cr16_unstable"; -+ clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; -+ clocksource_cr16.rating = 0; - } - - /* register at clocksource framework */ -diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c -index 747c328fb8862..afe8b902a8fc4 100644 ---- a/arch/parisc/kernel/traps.c -+++ b/arch/parisc/kernel/traps.c -@@ -729,6 +729,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs) - } - mmap_read_unlock(current->mm); - } -+ /* CPU could not fetch instruction, so clear stale IIR value. */ -+ regs->iir = 0xbaadf00d; - fallthrough; - case 27: - /* Data memory protection ID trap */ -@@ -782,7 +784,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) - * unless pagefault_disable() was called before. - */ - -- if (fault_space == 0 && !faulthandler_disabled()) -+ if (faulthandler_disabled() || fault_space == 0) - { - /* Clean up and return if in exception table. */ - if (fixup_exception(regs)) -diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c -index 237d20dd5622d..286cec4d86d7b 100644 ---- a/arch/parisc/kernel/unaligned.c -+++ b/arch/parisc/kernel/unaligned.c -@@ -340,7 +340,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) - : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); - -- return 0; -+ return ret; - } - static int emulate_std(struct pt_regs *regs, int frreg, int flop) - { -@@ -397,7 +397,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) - __asm__ __volatile__ ( - " mtsp %4, %%sr1\n" - " zdep %2, 29, 2, %%r19\n" --" dep %%r0, 31, 2, %2\n" -+" dep %%r0, 31, 2, %3\n" - " mtsar %%r19\n" - " zvdepi -2, 32, %%r19\n" - "1: ldw 0(%%sr1,%3),%%r20\n" -@@ -409,7 +409,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) - " andcm %%r21, %%r19, %%r21\n" - " or %1, %%r20, %1\n" - " or %2, %%r21, %2\n" --"3: stw %1,0(%%sr1,%1)\n" -+"3: stw %1,0(%%sr1,%3)\n" - "4: stw %%r1,4(%%sr1,%3)\n" - "5: stw %2,8(%%sr1,%3)\n" - " copy %%r0, %0\n" -@@ -596,7 +596,6 @@ void handle_unaligned(struct pt_regs *regs) - ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */ - break; - } --#ifdef CONFIG_PA20 - switch (regs->iir & OPCODE2_MASK) - { - case OPCODE_FLDD_L: -@@ -607,22 +606,23 @@ void handle_unaligned(struct pt_regs *regs) - flop=1; - ret = emulate_std(regs, R2(regs->iir),1); - break; -+#ifdef CONFIG_PA20 - case OPCODE_LDD_L: - ret = emulate_ldd(regs, R2(regs->iir),0); - break; - case OPCODE_STD_L: - ret = emulate_std(regs, R2(regs->iir),0); - break; -- } - #endif -+ } - switch (regs->iir & OPCODE3_MASK) - { - case OPCODE_FLDW_L: - flop=1; -- ret = emulate_ldw(regs, R2(regs->iir),0); -+ ret = emulate_ldw(regs, R2(regs->iir), 1); - break; - case OPCODE_LDW_M: -- ret = emulate_ldw(regs, R2(regs->iir),1); -+ ret = emulate_ldw(regs, R2(regs->iir), 0); - break; - - case OPCODE_FSTW_L: -diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c -index 87ae476d1c4f5..86a57fb0e6fae 100644 ---- a/arch/parisc/kernel/unwind.c -+++ b/arch/parisc/kernel/unwind.c -@@ -21,6 +21,8 @@ - #include - - #include -+#include -+#include - - /* #define DEBUG 1 */ - #ifdef DEBUG -@@ -203,6 +205,11 @@ int __init unwind_init(void) - return 0; - } - -+static bool pc_is_kernel_fn(unsigned long pc, void *fn) -+{ -+ return (unsigned long)dereference_kernel_function_descriptor(fn) == pc; -+} -+ - static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size) - { - /* -@@ -221,7 +228,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int - extern void * const _call_on_stack; - #endif /* CONFIG_IRQSTACKS */ - -- if (pc == (unsigned long) &handle_interruption) { -+ if (pc_is_kernel_fn(pc, handle_interruption)) { - struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); - dbg("Unwinding through handle_interruption()\n"); - info->prev_sp = regs->gr[30]; -@@ -229,13 +236,13 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int - return 1; - } - -- if (pc == (unsigned long) &ret_from_kernel_thread || -- pc == (unsigned long) &syscall_exit) { -+ if (pc_is_kernel_fn(pc, ret_from_kernel_thread) || -+ pc_is_kernel_fn(pc, syscall_exit)) { - info->prev_sp = info->prev_ip = 0; - return 1; - } - -- if (pc == (unsigned long) &intr_return) { -+ if (pc_is_kernel_fn(pc, intr_return)) { - struct pt_regs *regs; - - dbg("Found intr_return()\n"); -@@ -246,20 +253,20 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int - return 1; - } - -- if (pc == (unsigned long) &_switch_to_ret) { -+ if (pc_is_kernel_fn(pc, _switch_to) || -+ pc_is_kernel_fn(pc, _switch_to_ret)) { - info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; - info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); - return 1; - } - - #ifdef CONFIG_IRQSTACKS -- if (pc == (unsigned long) &_call_on_stack) { -+ if (pc_is_kernel_fn(pc, _call_on_stack)) { - info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); - info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); - return 1; - } - #endif -- - return 0; - } - -diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c -index 367f6397bda7a..8603850580857 100644 ---- a/arch/parisc/lib/iomap.c -+++ b/arch/parisc/lib/iomap.c -@@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr) - return *((u64 *)addr); - } - -+u64 ioread64_lo_hi(const void __iomem *addr) -+{ -+ u32 low, high; -+ -+ low = ioread32(addr); -+ high = ioread32(addr + sizeof(u32)); -+ -+ return low + ((u64)high << 32); -+} -+ - u64 ioread64_hi_lo(const void __iomem *addr) - { - u32 low, high; -@@ -419,6 +429,12 @@ void iowrite64be(u64 datum, void __iomem *addr) - } - } - -+void iowrite64_lo_hi(u64 val, void __iomem *addr) -+{ -+ iowrite32(val, addr); -+ iowrite32(val >> 32, addr + sizeof(u32)); -+} -+ - void iowrite64_hi_lo(u64 val, void __iomem *addr) - { - iowrite32(val >> 32, addr + sizeof(u32)); -@@ -530,6 +546,7 @@ EXPORT_SYMBOL(ioread32); - EXPORT_SYMBOL(ioread32be); - EXPORT_SYMBOL(ioread64); - EXPORT_SYMBOL(ioread64be); -+EXPORT_SYMBOL(ioread64_lo_hi); - EXPORT_SYMBOL(ioread64_hi_lo); - EXPORT_SYMBOL(iowrite8); - EXPORT_SYMBOL(iowrite16); -@@ -538,6 +555,7 @@ EXPORT_SYMBOL(iowrite32); - EXPORT_SYMBOL(iowrite32be); - EXPORT_SYMBOL(iowrite64); - EXPORT_SYMBOL(iowrite64be); -+EXPORT_SYMBOL(iowrite64_lo_hi); - EXPORT_SYMBOL(iowrite64_hi_lo); - EXPORT_SYMBOL(ioread8_rep); - EXPORT_SYMBOL(ioread16_rep); -diff --git a/arch/parisc/mm/fixmap.c b/arch/parisc/mm/fixmap.c -index 24426a7e1a5e5..cc15d737fda64 100644 ---- a/arch/parisc/mm/fixmap.c -+++ b/arch/parisc/mm/fixmap.c -@@ -20,12 +20,9 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys) - pte_t *pte; - - if (pmd_none(*pmd)) -- pmd = pmd_alloc(NULL, pud, vaddr); -- -- pte = pte_offset_kernel(pmd, vaddr); -- if (pte_none(*pte)) - pte = pte_alloc_kernel(pmd, vaddr); - -+ pte = pte_offset_kernel(pmd, vaddr); - set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX)); - flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); - } -diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c -index 3f7d6d5b56ac8..e5c18313b5d4f 100644 ---- a/arch/parisc/mm/init.c -+++ b/arch/parisc/mm/init.c -@@ -341,9 +341,9 @@ static void __init setup_bootmem(void) - - static bool kernel_set_to_readonly; - --static void __init map_pages(unsigned long start_vaddr, -- unsigned long start_paddr, unsigned long size, -- pgprot_t pgprot, int force) -+static void __ref map_pages(unsigned long start_vaddr, -+ unsigned long start_paddr, unsigned long size, -+ pgprot_t pgprot, int force) - { - pmd_t *pmd; - pte_t *pg_table; -@@ -453,7 +453,7 @@ void __init set_kernel_text_rw(int enable_read_write) - flush_tlb_all(); - } - --void __ref free_initmem(void) -+void free_initmem(void) - { - unsigned long init_begin = (unsigned long)__init_begin; - unsigned long init_end = (unsigned long)__init_end; -@@ -467,7 +467,6 @@ void __ref free_initmem(void) - /* The init text pages are marked R-X. We have to - * flush the icache and mark them RW- - * -- * This is tricky, because map_pages is in the init section. - * Do a dummy remap of the data section first (the data - * section is already PAGE_KERNEL) to pull in the TLB entries - * for map_kernel */ -@@ -842,9 +841,9 @@ void flush_tlb_all(void) - { - int do_recycle; - -- __inc_irq_stat(irq_tlb_count); - do_recycle = 0; - spin_lock(&sid_lock); -+ __inc_irq_stat(irq_tlb_count); - if (dirty_space_ids > RECYCLE_THRESHOLD) { - BUG_ON(recycle_inuse); /* FIXME: Use a semaphore/wait queue here */ - get_dirty_sids(&recycle_ndirty,recycle_dirty_array); -@@ -863,8 +862,8 @@ void flush_tlb_all(void) - #else - void flush_tlb_all(void) - { -- __inc_irq_stat(irq_tlb_count); - spin_lock(&sid_lock); -+ __inc_irq_stat(irq_tlb_count); - flush_tlb_all_local(NULL); - recycle_sids(); - spin_unlock(&sid_lock); -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index ba5b661893588..6b9f523882c58 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -138,7 +138,7 @@ config PPC - select ARCH_HAS_PTE_SPECIAL - select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 - select ARCH_HAS_SET_MEMORY -- select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) -+ select ARCH_HAS_STRICT_KERNEL_RWX if (PPC_BOOK3S || PPC_8xx || 40x) && !HIBERNATION - select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_32 - select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select ARCH_HAS_UACCESS_FLUSHCACHE -@@ -150,7 +150,7 @@ config PPC - select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX - select ARCH_STACKWALK - select ARCH_SUPPORTS_ATOMIC_RMW -- select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC32 || PPC_BOOK3S_64 -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx || 40x - select ARCH_USE_BUILTIN_BSWAP - select ARCH_USE_CMPXCHG_LOCKREF if PPC64 - select ARCH_USE_MEMTEST -@@ -190,7 +190,7 @@ config PPC - select HAVE_ARCH_JUMP_LABEL_RELATIVE - select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14 - select HAVE_ARCH_KASAN_VMALLOC if PPC32 && PPC_PAGE_SHIFT <= 14 -- select HAVE_ARCH_KFENCE if PPC32 -+ select HAVE_ARCH_KFENCE if PPC_BOOK3S_32 || PPC_8xx || 40x - select HAVE_ARCH_KGDB - select HAVE_ARCH_MMAP_RND_BITS - select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT -diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts -index 408b486b13dff..cd589539f313f 100644 ---- a/arch/powerpc/boot/dts/charon.dts -+++ b/arch/powerpc/boot/dts/charon.dts -@@ -35,7 +35,7 @@ - }; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>; // 128MB - }; -diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts -index 0e5e9d3acf79f..19a14e62e65f4 100644 ---- a/arch/powerpc/boot/dts/digsy_mtc.dts -+++ b/arch/powerpc/boot/dts/digsy_mtc.dts -@@ -16,7 +16,7 @@ - model = "intercontrol,digsy-mtc"; - compatible = "intercontrol,digsy-mtc"; - -- memory { -+ memory@0 { - reg = <0x00000000 0x02000000>; // 32MB - }; - -diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi -index c90702b04a530..48e5cd61599c6 100644 ---- a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi -+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi -@@ -79,6 +79,7 @@ fman0: fman@400000 { - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; - reg = <0xfc000 0x1000>; -+ fsl,erratum-a009885; - }; - - xmdio0: mdio@fd000 { -@@ -86,6 +87,7 @@ fman0: fman@400000 { - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; - reg = <0xfd000 0x1000>; -+ fsl,erratum-a009885; - }; - }; - -diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts -index cb2782dd6132c..e7b194775d783 100644 ---- a/arch/powerpc/boot/dts/lite5200.dts -+++ b/arch/powerpc/boot/dts/lite5200.dts -@@ -32,7 +32,7 @@ - }; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x04000000>; // 64MB - }; -diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts -index 2b86c81f90485..547cbe726ff23 100644 ---- a/arch/powerpc/boot/dts/lite5200b.dts -+++ b/arch/powerpc/boot/dts/lite5200b.dts -@@ -31,7 +31,7 @@ - led4 { gpios = <&gpio_simple 2 1>; }; - }; - -- memory { -+ memory@0 { - reg = <0x00000000 0x10000000>; // 256MB - }; - -diff --git a/arch/powerpc/boot/dts/media5200.dts b/arch/powerpc/boot/dts/media5200.dts -index 61cae9dcddef4..f3188018faceb 100644 ---- a/arch/powerpc/boot/dts/media5200.dts -+++ b/arch/powerpc/boot/dts/media5200.dts -@@ -32,7 +32,7 @@ - }; - }; - -- memory { -+ memory@0 { - reg = <0x00000000 0x08000000>; // 128MB RAM - }; - -diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi -index 648fe31795f49..8b796f3b11da7 100644 ---- a/arch/powerpc/boot/dts/mpc5200b.dtsi -+++ b/arch/powerpc/boot/dts/mpc5200b.dtsi -@@ -33,7 +33,7 @@ - }; - }; - -- memory: memory { -+ memory: memory@0 { - device_type = "memory"; - reg = <0x00000000 0x04000000>; // 64MB - }; -diff --git a/arch/powerpc/boot/dts/o2d.dts b/arch/powerpc/boot/dts/o2d.dts -index 24a46f65e5299..e0a8d3034417f 100644 ---- a/arch/powerpc/boot/dts/o2d.dts -+++ b/arch/powerpc/boot/dts/o2d.dts -@@ -12,7 +12,7 @@ - model = "ifm,o2d"; - compatible = "ifm,o2d"; - -- memory { -+ memory@0 { - reg = <0x00000000 0x08000000>; // 128MB - }; - -diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi -index 6661955a2be47..b55a9e5bd828c 100644 ---- a/arch/powerpc/boot/dts/o2d.dtsi -+++ b/arch/powerpc/boot/dts/o2d.dtsi -@@ -19,7 +19,7 @@ - model = "ifm,o2d"; - compatible = "ifm,o2d"; - -- memory { -+ memory@0 { - reg = <0x00000000 0x04000000>; // 64MB - }; - -diff --git a/arch/powerpc/boot/dts/o2dnt2.dts b/arch/powerpc/boot/dts/o2dnt2.dts -index eeba7f5507d5d..c2eedbd1f5fcb 100644 ---- a/arch/powerpc/boot/dts/o2dnt2.dts -+++ b/arch/powerpc/boot/dts/o2dnt2.dts -@@ -12,7 +12,7 @@ - model = "ifm,o2dnt2"; - compatible = "ifm,o2d"; - -- memory { -+ memory@0 { - reg = <0x00000000 0x08000000>; // 128MB - }; - -diff --git a/arch/powerpc/boot/dts/o3dnt.dts b/arch/powerpc/boot/dts/o3dnt.dts -index fd00396b0593e..e4c1bdd412716 100644 ---- a/arch/powerpc/boot/dts/o3dnt.dts -+++ b/arch/powerpc/boot/dts/o3dnt.dts -@@ -12,7 +12,7 @@ - model = "ifm,o3dnt"; - compatible = "ifm,o2d"; - -- memory { -+ memory@0 { - reg = <0x00000000 0x04000000>; // 64MB - }; - -diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts -index 780e13d99e7b8..1895bc95900cc 100644 ---- a/arch/powerpc/boot/dts/pcm032.dts -+++ b/arch/powerpc/boot/dts/pcm032.dts -@@ -20,7 +20,7 @@ - model = "phytec,pcm032"; - compatible = "phytec,pcm032"; - -- memory { -+ memory@0 { - reg = <0x00000000 0x08000000>; // 128MB - }; - -diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts -index 9ed0bc78967e1..5bb25a9e40a01 100644 ---- a/arch/powerpc/boot/dts/tqm5200.dts -+++ b/arch/powerpc/boot/dts/tqm5200.dts -@@ -32,7 +32,7 @@ - }; - }; - -- memory { -+ memory@0 { - device_type = "memory"; - reg = <0x00000000 0x04000000>; // 64MB - }; -diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig -index 6697c5e6682f1..bb549cb1c3e33 100644 ---- a/arch/powerpc/configs/ppc6xx_defconfig -+++ b/arch/powerpc/configs/ppc6xx_defconfig -@@ -1022,7 +1022,6 @@ CONFIG_NFSD=m - CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y -diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig -index b183629f1bcfb..d0494fbb49617 100644 ---- a/arch/powerpc/configs/pseries_defconfig -+++ b/arch/powerpc/configs/pseries_defconfig -@@ -190,7 +190,6 @@ CONFIG_HVCS=m - CONFIG_VIRTIO_CONSOLE=m - CONFIG_IBM_BSR=m - CONFIG_RAW_DRIVER=y --CONFIG_MAX_RAW_DEVS=1024 - CONFIG_I2C_CHARDEV=y - CONFIG_FB=y - CONFIG_FIRMWARE_EDID=y -diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h -index f5be185cbdf8d..94ad7acfd0565 100644 ---- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h -+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h -@@ -143,6 +143,8 @@ static __always_inline void update_user_segments(u32 val) - update_user_segment(15, val); - } - -+int __init find_free_bat(void); -+unsigned int bat_block_size(unsigned long base, unsigned long top); - #endif /* !__ASSEMBLY__ */ - - /* We happily ignore the smaller BATs on 601, we don't actually use -diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h -index 609c80f671943..f8b94f78403f1 100644 ---- a/arch/powerpc/include/asm/book3s/32/pgtable.h -+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h -@@ -178,6 +178,7 @@ static inline bool pte_user(pte_t pte) - #ifndef __ASSEMBLY__ - - int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); -+void unmap_kernel_page(unsigned long va); - - #endif /* !__ASSEMBLY__ */ - -diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h -index 5d34a8646f081..6866d860d4f30 100644 ---- a/arch/powerpc/include/asm/book3s/64/pgtable.h -+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h -@@ -1082,6 +1082,8 @@ static inline int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t p - return hash__map_kernel_page(ea, pa, prot); - } - -+void unmap_kernel_page(unsigned long va); -+ - static inline int __meminit vmemmap_create_mapping(unsigned long start, - unsigned long page_size, - unsigned long phys) -diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h -index 947b5b9c44241..a832aeafe5601 100644 ---- a/arch/powerpc/include/asm/fixmap.h -+++ b/arch/powerpc/include/asm/fixmap.h -@@ -111,8 +111,10 @@ static inline void __set_fixmap(enum fixed_addresses idx, - BUILD_BUG_ON(idx >= __end_of_fixed_addresses); - else if (WARN_ON(idx >= __end_of_fixed_addresses)) - return; -- -- map_kernel_page(__fix_to_virt(idx), phys, flags); -+ if (pgprot_val(flags)) -+ map_kernel_page(__fix_to_virt(idx), phys, flags); -+ else -+ unmap_kernel_page(__fix_to_virt(idx)); - } - - #define __early_set_fixmap __set_fixmap -diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h -index 21cc571ea9c2d..5c98a950eca0d 100644 ---- a/arch/powerpc/include/asm/hw_irq.h -+++ b/arch/powerpc/include/asm/hw_irq.h -@@ -224,6 +224,42 @@ static inline bool arch_irqs_disabled(void) - return arch_irqs_disabled_flags(arch_local_save_flags()); - } - -+static inline void set_pmi_irq_pending(void) -+{ -+ /* -+ * Invoked from PMU callback functions to set PMI bit in the paca. -+ * This has to be called with irq's disabled (via hard_irq_disable()). -+ */ -+ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) -+ WARN_ON_ONCE(mfmsr() & MSR_EE); -+ -+ get_paca()->irq_happened |= PACA_IRQ_PMI; -+} -+ -+static inline void clear_pmi_irq_pending(void) -+{ -+ /* -+ * Invoked from PMU callback functions to clear the pending PMI bit -+ * in the paca. -+ */ -+ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) -+ WARN_ON_ONCE(mfmsr() & MSR_EE); -+ -+ get_paca()->irq_happened &= ~PACA_IRQ_PMI; -+} -+ -+static inline bool pmi_irq_pending(void) -+{ -+ /* -+ * Invoked from PMU callback functions to check if there is a pending -+ * PMI bit in the paca. -+ */ -+ if (get_paca()->irq_happened & PACA_IRQ_PMI) -+ return true; -+ -+ return false; -+} -+ - #ifdef CONFIG_PPC_BOOK3S - /* - * To support disabling and enabling of irq with PMI, set of -@@ -408,6 +444,10 @@ static inline void do_hard_irq_enable(void) - BUILD_BUG(); - } - -+static inline void clear_pmi_irq_pending(void) { } -+static inline void set_pmi_irq_pending(void) { } -+static inline bool pmi_irq_pending(void) { return false; } -+ - static inline void irq_soft_mask_regs_set_state(struct pt_regs *regs, unsigned long val) - { - } -diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h -index 19b6942c6969a..eaf3a562bf1ed 100644 ---- a/arch/powerpc/include/asm/kvm_book3s_64.h -+++ b/arch/powerpc/include/asm/kvm_book3s_64.h -@@ -39,7 +39,6 @@ struct kvm_nested_guest { - pgd_t *shadow_pgtable; /* our page table for this guest */ - u64 l1_gr_to_hr; /* L1's addr of part'n-scoped table */ - u64 process_table; /* process table entry for this guest */ -- u64 hfscr; /* HFSCR that the L1 requested for this nested guest */ - long refcnt; /* number of pointers to this struct */ - struct mutex tlb_lock; /* serialize page faults and tlbies */ - struct kvm_nested_guest *next; -diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h -index 080a7feb77318..0d81a9bf37650 100644 ---- a/arch/powerpc/include/asm/kvm_host.h -+++ b/arch/powerpc/include/asm/kvm_host.h -@@ -814,6 +814,7 @@ struct kvm_vcpu_arch { - - /* For support of nested guests */ - struct kvm_nested_guest *nested; -+ u64 nested_hfscr; /* HFSCR that the L1 requested for the nested guest */ - u32 nested_vcpu_id; - gpa_t nested_io_gpr; - #endif -diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h -index f06ae00f2a65e..63ea4693ccea6 100644 ---- a/arch/powerpc/include/asm/nohash/32/pgtable.h -+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h -@@ -64,6 +64,7 @@ extern int icache_44x_need_flush; - #ifndef __ASSEMBLY__ - - int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); -+void unmap_kernel_page(unsigned long va); - - #endif /* !__ASSEMBLY__ */ - -@@ -193,10 +194,12 @@ static inline pte_t pte_wrprotect(pte_t pte) - } - #endif - -+#ifndef pte_mkexec - static inline pte_t pte_mkexec(pte_t pte) - { - return __pte(pte_val(pte) | _PAGE_EXEC); - } -+#endif - - #define pmd_none(pmd) (!pmd_val(pmd)) - #define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) -@@ -306,30 +309,29 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, - } - - #define __HAVE_ARCH_PTEP_SET_WRPROTECT -+#ifndef ptep_set_wrprotect - static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) - { -- unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0))); -- unsigned long set = pte_val(pte_wrprotect(__pte(0))); -- -- pte_update(mm, addr, ptep, clr, set, 0); -+ pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); - } -+#endif - -+#ifndef __ptep_set_access_flags - static inline void __ptep_set_access_flags(struct vm_area_struct *vma, - pte_t *ptep, pte_t entry, - unsigned long address, - int psize) - { -- pte_t pte_set = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(0))))); -- pte_t pte_clr = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0))))); -- unsigned long set = pte_val(entry) & pte_val(pte_set); -- unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr); -+ unsigned long set = pte_val(entry) & -+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); - int huge = psize > mmu_virtual_psize ? 1 : 0; - -- pte_update(vma->vm_mm, address, ptep, clr, set, huge); -+ pte_update(vma->vm_mm, address, ptep, 0, set, huge); - - flush_tlb_page(vma, address); - } -+#endif - - static inline int pte_young(pte_t pte) - { -diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h -index fcc48d590d888..1a89ebdc3acc9 100644 ---- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h -+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h -@@ -136,6 +136,28 @@ static inline pte_t pte_mkhuge(pte_t pte) - - #define pte_mkhuge pte_mkhuge - -+static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p, -+ unsigned long clr, unsigned long set, int huge); -+ -+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -+{ -+ pte_update(mm, addr, ptep, 0, _PAGE_RO, 0); -+} -+#define ptep_set_wrprotect ptep_set_wrprotect -+ -+static inline void __ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, -+ pte_t entry, unsigned long address, int psize) -+{ -+ unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_EXEC); -+ unsigned long clr = ~pte_val(entry) & _PAGE_RO; -+ int huge = psize > mmu_virtual_psize ? 1 : 0; -+ -+ pte_update(vma->vm_mm, address, ptep, clr, set, huge); -+ -+ flush_tlb_page(vma, address); -+} -+#define __ptep_set_access_flags __ptep_set_access_flags -+ - static inline unsigned long pgd_leaf_size(pgd_t pgd) - { - if (pgd_val(pgd) & _PMD_PAGE_8M) -diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h -index d081704b13fb9..2225991c69b55 100644 ---- a/arch/powerpc/include/asm/nohash/64/pgtable.h -+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h -@@ -118,11 +118,6 @@ static inline pte_t pte_wrprotect(pte_t pte) - return __pte(pte_val(pte) & ~_PAGE_RW); - } - --static inline pte_t pte_mkexec(pte_t pte) --{ -- return __pte(pte_val(pte) | _PAGE_EXEC); --} -- - #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) - #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) - -@@ -313,6 +308,7 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma, - #define __swp_entry_to_pte(x) __pte((x).val) - - int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot); -+void unmap_kernel_page(unsigned long va); - extern int __meminit vmemmap_create_mapping(unsigned long start, - unsigned long page_size, - unsigned long phys); -diff --git a/arch/powerpc/include/asm/nohash/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h -index 813918f407653..f798640422c2d 100644 ---- a/arch/powerpc/include/asm/nohash/pte-book3e.h -+++ b/arch/powerpc/include/asm/nohash/pte-book3e.h -@@ -48,7 +48,7 @@ - #define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */ - - /* "Higher level" linux bit combinations */ --#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */ -+#define _PAGE_EXEC (_PAGE_BAP_SX | _PAGE_BAP_UX) /* .. and was cache cleaned */ - #define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */ - #define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY) - #define _PAGE_KERNEL_RO (_PAGE_BAP_SR) -@@ -93,11 +93,11 @@ - /* Permission masks used to generate the __P and __S table */ - #define PAGE_NONE __pgprot(_PAGE_BASE) - #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) --#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) -+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_BAP_UX) - #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) --#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) -+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_BAP_UX) - #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) --#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) -+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_BAP_UX) - - #ifndef __ASSEMBLY__ - static inline pte_t pte_mkprivileged(pte_t pte) -@@ -113,6 +113,16 @@ static inline pte_t pte_mkuser(pte_t pte) - } - - #define pte_mkuser pte_mkuser -+ -+static inline pte_t pte_mkexec(pte_t pte) -+{ -+ if (pte_val(pte) & _PAGE_BAP_UR) -+ return __pte((pte_val(pte) & ~_PAGE_BAP_SX) | _PAGE_BAP_UX); -+ else -+ return __pte((pte_val(pte) & ~_PAGE_BAP_UX) | _PAGE_BAP_SX); -+} -+#define pte_mkexec pte_mkexec -+ - #endif /* __ASSEMBLY__ */ - - #endif /* __KERNEL__ */ -diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h -index bcb7b5f917be6..b325022ffa2b0 100644 ---- a/arch/powerpc/include/asm/paravirt.h -+++ b/arch/powerpc/include/asm/paravirt.h -@@ -97,7 +97,23 @@ static inline bool vcpu_is_preempted(int cpu) - - #ifdef CONFIG_PPC_SPLPAR - if (!is_kvm_guest()) { -- int first_cpu = cpu_first_thread_sibling(smp_processor_id()); -+ int first_cpu; -+ -+ /* -+ * The result of vcpu_is_preempted() is used in a -+ * speculative way, and is always subject to invalidation -+ * by events internal and external to Linux. While we can -+ * be called in preemptable context (in the Linux sense), -+ * we're not accessing per-cpu resources in a way that can -+ * race destructively with Linux scheduler preemption and -+ * migration, and callers can tolerate the potential for -+ * error introduced by sampling the CPU index without -+ * pinning the task to it. So it is permissible to use -+ * raw_smp_processor_id() here to defeat the preempt debug -+ * warnings that can arise from using smp_processor_id() -+ * in arbitrary contexts. -+ */ -+ first_cpu = cpu_first_thread_sibling(raw_smp_processor_id()); - - /* - * Preemption can only happen at core granularity. This CPU -diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h -index baea657bc8687..bca31a61e57f8 100644 ---- a/arch/powerpc/include/asm/ppc-opcode.h -+++ b/arch/powerpc/include/asm/ppc-opcode.h -@@ -498,6 +498,7 @@ - #define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) - #define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) - #define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) -+#define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) - #define PPC_RAW_LDBRX(r, base, b) (0x7c000428 | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) - #define PPC_RAW_STWCX(s, a, b) (0x7c00012d | ___PPC_RS(s) | ___PPC_RA(a) | ___PPC_RB(b)) - #define PPC_RAW_CMPWI(a, i) (0x2c000000 | ___PPC_RA(a) | IMM_L(i)) -diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h -index c60ebd04b2ed9..61b968d9fba7c 100644 ---- a/arch/powerpc/include/asm/syscall.h -+++ b/arch/powerpc/include/asm/syscall.h -@@ -90,7 +90,7 @@ static inline void syscall_get_arguments(struct task_struct *task, - unsigned long val, mask = -1UL; - unsigned int n = 6; - -- if (is_32bit_task()) -+ if (is_tsk_32bit_task(task)) - mask = 0xffffffff; - - while (n--) { -@@ -115,7 +115,7 @@ static inline void syscall_set_arguments(struct task_struct *task, - - static inline int syscall_get_arch(struct task_struct *task) - { -- if (is_32bit_task()) -+ if (is_tsk_32bit_task(task)) - return AUDIT_ARCH_PPC; - else if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) - return AUDIT_ARCH_PPC64LE; -diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h -index b4ec6c7dd72ee..2a4ea0e213a92 100644 ---- a/arch/powerpc/include/asm/thread_info.h -+++ b/arch/powerpc/include/asm/thread_info.h -@@ -165,8 +165,10 @@ static inline bool test_thread_local_flags(unsigned int flags) - - #ifdef CONFIG_COMPAT - #define is_32bit_task() (test_thread_flag(TIF_32BIT)) -+#define is_tsk_32bit_task(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT)) - #else - #define is_32bit_task() (IS_ENABLED(CONFIG_PPC32)) -+#define is_tsk_32bit_task(tsk) (IS_ENABLED(CONFIG_PPC32)) - #endif - - #if defined(CONFIG_PPC64) -diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile -index 7be36c1e1db6d..b1b23b4d56ba2 100644 ---- a/arch/powerpc/kernel/Makefile -+++ b/arch/powerpc/kernel/Makefile -@@ -11,6 +11,7 @@ CFLAGS_prom_init.o += -fPIC - CFLAGS_btext.o += -fPIC - endif - -+CFLAGS_early_32.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) - CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) - CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) - CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) -@@ -196,3 +197,6 @@ clean-files := vmlinux.lds - # Force dependency (incbin is bad) - $(obj)/vdso32_wrapper.o : $(obj)/vdso32/vdso32.so.dbg - $(obj)/vdso64_wrapper.o : $(obj)/vdso64/vdso64.so.dbg -+ -+# for cleaning -+subdir- += vdso32 vdso64 -diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c -index 803c2a45b22ac..1cffb5e7c38d6 100644 ---- a/arch/powerpc/kernel/btext.c -+++ b/arch/powerpc/kernel/btext.c -@@ -241,8 +241,10 @@ int __init btext_find_display(int allow_nonstdout) - rc = btext_initialize(np); - printk("result: %d\n", rc); - } -- if (rc == 0) -+ if (rc == 0) { -+ of_node_put(np); - break; -+ } - } - return rc; - } -diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c -index b7ceb041743c9..60f5fc14aa235 100644 ---- a/arch/powerpc/kernel/fadump.c -+++ b/arch/powerpc/kernel/fadump.c -@@ -1641,6 +1641,14 @@ int __init setup_fadump(void) - else if (fw_dump.reserve_dump_area_size) - fw_dump.ops->fadump_init_mem_struct(&fw_dump); - -+ /* -+ * In case of panic, fadump is triggered via ppc_panic_event() -+ * panic notifier. Setting crash_kexec_post_notifiers to 'true' -+ * lets panic() function take crash friendly path before panic -+ * notifiers are invoked. -+ */ -+ crash_kexec_post_notifiers = true; -+ - return 1; - } - subsys_initcall(setup_fadump); -diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c -index c7022c41cc314..20328f72f9f2b 100644 ---- a/arch/powerpc/kernel/firmware.c -+++ b/arch/powerpc/kernel/firmware.c -@@ -31,11 +31,10 @@ int __init check_kvm_guest(void) - if (!hyper_node) - return 0; - -- if (!of_device_is_compatible(hyper_node, "linux,kvm")) -- return 0; -- -- static_branch_enable(&kvm_guest); -+ if (of_device_is_compatible(hyper_node, "linux,kvm")) -+ static_branch_enable(&kvm_guest); - -+ of_node_put(hyper_node); - return 0; - } - core_initcall(check_kvm_guest); // before kvm_guest_init() -diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h -index 6b1ec9e3541b9..349c4a820231b 100644 ---- a/arch/powerpc/kernel/head_32.h -+++ b/arch/powerpc/kernel/head_32.h -@@ -202,11 +202,11 @@ vmap_stack_overflow: - mfspr r1, SPRN_SPRG_THREAD - lwz r1, TASK_CPU - THREAD(r1) - slwi r1, r1, 3 -- addis r1, r1, emergency_ctx@ha -+ addis r1, r1, emergency_ctx-PAGE_OFFSET@ha - #else -- lis r1, emergency_ctx@ha -+ lis r1, emergency_ctx-PAGE_OFFSET@ha - #endif -- lwz r1, emergency_ctx@l(r1) -+ lwz r1, emergency_ctx-PAGE_OFFSET@l(r1) - addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE - EXCEPTION_PROLOG_2 0 vmap_stack_overflow - prepare_transfer_to_handler -diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S -index 7d72ee5ab387c..e783860bea838 100644 ---- a/arch/powerpc/kernel/head_40x.S -+++ b/arch/powerpc/kernel/head_40x.S -@@ -27,6 +27,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -650,7 +651,7 @@ start_here: - b . /* prevent prefetch past rfi */ - - /* Set up the initial MMU state so we can do the first level of -- * kernel initialization. This maps the first 16 MBytes of memory 1:1 -+ * kernel initialization. This maps the first 32 MBytes of memory 1:1 - * virtual to physical and more importantly sets the cache mode. - */ - initial_mmu: -@@ -687,6 +688,12 @@ initial_mmu: - tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ - tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ - -+ li r0,62 /* TLB slot 62 */ -+ addis r4,r4,SZ_16M@h -+ addis r3,r3,SZ_16M@h -+ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ -+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ -+ - isync - - /* Establish the exception vector base -diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S -index 9bdb95f5694f7..0d073b9fd52c5 100644 ---- a/arch/powerpc/kernel/head_8xx.S -+++ b/arch/powerpc/kernel/head_8xx.S -@@ -733,6 +733,7 @@ _GLOBAL(mmu_pin_tlb) - #ifdef CONFIG_PIN_TLB_DATA - LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) - LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED) -+ li r8, 0 - #ifdef CONFIG_PIN_TLB_IMMR - li r0, 3 - #else -@@ -741,26 +742,26 @@ _GLOBAL(mmu_pin_tlb) - mtctr r0 - cmpwi r4, 0 - beq 4f -- LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) - LOAD_REG_ADDR(r9, _sinittext) - - 2: ori r0, r6, MD_EVALID -+ ori r12, r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT - mtspr SPRN_MD_CTR, r5 - mtspr SPRN_MD_EPN, r0 - mtspr SPRN_MD_TWC, r7 -- mtspr SPRN_MD_RPN, r8 -+ mtspr SPRN_MD_RPN, r12 - addi r5, r5, 0x100 - addis r6, r6, SZ_8M@h - addis r8, r8, SZ_8M@h - cmplw r6, r9 - bdnzt lt, 2b -- --4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) -+4: - 2: ori r0, r6, MD_EVALID -+ ori r12, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT - mtspr SPRN_MD_CTR, r5 - mtspr SPRN_MD_EPN, r0 - mtspr SPRN_MD_TWC, r7 -- mtspr SPRN_MD_RPN, r8 -+ mtspr SPRN_MD_RPN, r12 - addi r5, r5, 0x100 - addis r6, r6, SZ_8M@h - addis r8, r8, SZ_8M@h -@@ -781,7 +782,7 @@ _GLOBAL(mmu_pin_tlb) - #endif - #if defined(CONFIG_PIN_TLB_IMMR) || defined(CONFIG_PIN_TLB_DATA) - lis r0, (MD_RSV4I | MD_TWAM)@h -- mtspr SPRN_MI_CTR, r0 -+ mtspr SPRN_MD_CTR, r0 - #endif - mtspr SPRN_SRR1, r10 - mtspr SPRN_SRR0, r11 -diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S -index 68e5c0a7e99d1..2e2a8211b17be 100644 ---- a/arch/powerpc/kernel/head_book3s_32.S -+++ b/arch/powerpc/kernel/head_book3s_32.S -@@ -421,14 +421,14 @@ InstructionTLBMiss: - */ - /* Get PTE (linux-style) and check access */ - mfspr r3,SPRN_IMISS --#ifdef CONFIG_MODULES -+#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) - lis r1, TASK_SIZE@h /* check if kernel address */ - cmplw 0,r1,r3 - #endif - mfspr r2, SPRN_SDR1 - li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER - rlwinm r2, r2, 28, 0xfffff000 --#ifdef CONFIG_MODULES -+#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) - bgt- 112f - lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ - li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC -diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h -index e5503420b6c6d..ef8d1b1c234e7 100644 ---- a/arch/powerpc/kernel/head_booke.h -+++ b/arch/powerpc/kernel/head_booke.h -@@ -465,12 +465,21 @@ label: - bl do_page_fault; \ - b interrupt_return - -+/* -+ * Instruction TLB Error interrupt handlers may call InstructionStorage -+ * directly without clearing ESR, so the ESR at this point may be left over -+ * from a prior interrupt. -+ * -+ * In any case, do_page_fault for BOOK3E does not use ESR and always expects -+ * dsisr to be 0. ESR_DST from a prior store in particular would confuse fault -+ * handling. -+ */ - #define INSTRUCTION_STORAGE_EXCEPTION \ - START_EXCEPTION(InstructionStorage) \ -- NORMAL_EXCEPTION_PROLOG(0x400, INST_STORAGE); \ -- mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ -+ NORMAL_EXCEPTION_PROLOG(0x400, INST_STORAGE); \ -+ li r5,0; /* Store 0 in regs->esr (dsisr) */ \ - stw r5,_ESR(r11); \ -- stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \ -+ stw r12, _DEAR(r11); /* Set regs->dear (dar) to SRR0 */ \ - prepare_transfer_to_handler; \ - bl do_page_fault; \ - b interrupt_return -diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c -index de10a26972581..df048e331cbfe 100644 ---- a/arch/powerpc/kernel/interrupt.c -+++ b/arch/powerpc/kernel/interrupt.c -@@ -148,7 +148,7 @@ notrace long system_call_exception(long r3, long r4, long r5, - */ - if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && - unlikely(MSR_TM_TRANSACTIONAL(regs->msr))) -- current_thread_info()->flags |= _TIF_RESTOREALL; -+ set_bits(_TIF_RESTOREALL, ¤t_thread_info()->flags); - - /* - * If the system call was made with a transaction active, doom it and -@@ -266,7 +266,7 @@ static void check_return_regs_valid(struct pt_regs *regs) - if (trap_is_scv(regs)) - return; - -- trap = regs->trap; -+ trap = TRAP(regs); - // EE in HV mode sets HSRRs like 0xea0 - if (cpu_has_feature(CPU_FTR_HVMODE) && trap == INTERRUPT_EXTERNAL) - trap = 0xea0; -diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S -index ec950b08a8dcc..4c6d1a8dcefed 100644 ---- a/arch/powerpc/kernel/interrupt_64.S -+++ b/arch/powerpc/kernel/interrupt_64.S -@@ -30,21 +30,25 @@ COMPAT_SYS_CALL_TABLE: - .ifc \srr,srr - mfspr r11,SPRN_SRR0 - ld r12,_NIP(r1) -+ clrrdi r11,r11,2 -+ clrrdi r12,r12,2 - 100: tdne r11,r12 -- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) -+ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) - mfspr r11,SPRN_SRR1 - ld r12,_MSR(r1) - 100: tdne r11,r12 -- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) -+ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) - .else - mfspr r11,SPRN_HSRR0 - ld r12,_NIP(r1) -+ clrrdi r11,r11,2 -+ clrrdi r12,r12,2 - 100: tdne r11,r12 -- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) -+ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) - mfspr r11,SPRN_HSRR1 - ld r12,_MSR(r1) - 100: tdne r11,r12 -- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) -+ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) - .endif - #endif - .endm -diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c -index ed04a3ba66fe8..40a583e9d3c70 100644 ---- a/arch/powerpc/kernel/module.c -+++ b/arch/powerpc/kernel/module.c -@@ -90,16 +90,17 @@ int module_finalize(const Elf_Ehdr *hdr, - } - - static __always_inline void * --__module_alloc(unsigned long size, unsigned long start, unsigned long end) -+__module_alloc(unsigned long size, unsigned long start, unsigned long end, bool nowarn) - { - pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC; -+ gfp_t gfp = GFP_KERNEL | (nowarn ? __GFP_NOWARN : 0); - - /* - * Don't do huge page allocations for modules yet until more testing - * is done. STRICT_MODULE_RWX may require extra work to support this - * too. - */ -- return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, prot, -+ return __vmalloc_node_range(size, 1, start, end, gfp, prot, - VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, - NUMA_NO_NODE, __builtin_return_address(0)); - } -@@ -114,13 +115,13 @@ void *module_alloc(unsigned long size) - - /* First try within 32M limit from _etext to avoid branch trampolines */ - if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) -- ptr = __module_alloc(size, limit, MODULES_END); -+ ptr = __module_alloc(size, limit, MODULES_END, true); - - if (!ptr) -- ptr = __module_alloc(size, MODULES_VADDR, MODULES_END); -+ ptr = __module_alloc(size, MODULES_VADDR, MODULES_END, false); - - return ptr; - #else -- return __module_alloc(size, VMALLOC_START, VMALLOC_END); -+ return __module_alloc(size, VMALLOC_START, VMALLOC_END, false); - #endif - } -diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c -index 6baa676e7cb60..5d77d3f5fbb56 100644 ---- a/arch/powerpc/kernel/module_64.c -+++ b/arch/powerpc/kernel/module_64.c -@@ -422,11 +422,17 @@ static inline int create_stub(const Elf64_Shdr *sechdrs, - const char *name) - { - long reladdr; -+ func_desc_t desc; -+ int i; - - if (is_mprofile_ftrace_call(name)) - return create_ftrace_stub(entry, addr, me); - -- memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns)); -+ for (i = 0; i < sizeof(ppc64_stub_insns) / sizeof(u32); i++) { -+ if (patch_instruction(&entry->jump[i], -+ ppc_inst(ppc64_stub_insns[i]))) -+ return 0; -+ } - - /* Stub uses address relative to r2. */ - reladdr = (unsigned long)entry - my_r2(sechdrs, me); -@@ -437,10 +443,24 @@ static inline int create_stub(const Elf64_Shdr *sechdrs, - } - pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); - -- entry->jump[0] |= PPC_HA(reladdr); -- entry->jump[1] |= PPC_LO(reladdr); -- entry->funcdata = func_desc(addr); -- entry->magic = STUB_MAGIC; -+ if (patch_instruction(&entry->jump[0], -+ ppc_inst(entry->jump[0] | PPC_HA(reladdr)))) -+ return 0; -+ -+ if (patch_instruction(&entry->jump[1], -+ ppc_inst(entry->jump[1] | PPC_LO(reladdr)))) -+ return 0; -+ -+ // func_desc_t is 8 bytes if ABIv2, else 16 bytes -+ desc = func_desc(addr); -+ for (i = 0; i < sizeof(func_desc_t) / sizeof(u32); i++) { -+ if (patch_instruction(((u32 *)&entry->funcdata) + i, -+ ppc_inst(((u32 *)(&desc))[i]))) -+ return 0; -+ } -+ -+ if (patch_instruction(&entry->magic, ppc_inst(STUB_MAGIC))) -+ return 0; - - return 1; - } -@@ -495,8 +515,11 @@ static int restore_r2(const char *name, u32 *instruction, struct module *me) - me->name, *instruction, instruction); - return 0; - } -+ - /* ld r2,R2_STACK_OFFSET(r1) */ -- *instruction = PPC_INST_LD_TOC; -+ if (patch_instruction(instruction, ppc_inst(PPC_INST_LD_TOC))) -+ return 0; -+ - return 1; - } - -@@ -636,9 +659,12 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, - } - - /* Only replace bits 2 through 26 */ -- *(uint32_t *)location -- = (*(uint32_t *)location & ~0x03fffffc) -+ value = (*(uint32_t *)location & ~0x03fffffc) - | (value & 0x03fffffc); -+ -+ if (patch_instruction((u32 *)location, ppc_inst(value))) -+ return -EFAULT; -+ - break; - - case R_PPC64_REL64: -diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c -index 18b04b08b9833..f845065c860e3 100644 ---- a/arch/powerpc/kernel/prom_init.c -+++ b/arch/powerpc/kernel/prom_init.c -@@ -2991,7 +2991,7 @@ static void __init fixup_device_tree_efika_add_phy(void) - - /* Check if the phy-handle property exists - bail if it does */ - rv = prom_getprop(node, "phy-handle", prop, sizeof(prop)); -- if (!rv) -+ if (rv <= 0) - return; - - /* -diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h -index 1f07317964e49..618aeccdf6918 100644 ---- a/arch/powerpc/kernel/signal.h -+++ b/arch/powerpc/kernel/signal.h -@@ -25,8 +25,14 @@ static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src) - - return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]); - } --#define unsafe_get_user_sigset(dst, src, label) \ -- unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label) -+#define unsafe_get_user_sigset(dst, src, label) do { \ -+ sigset_t *__dst = dst; \ -+ const sigset_t __user *__src = src; \ -+ int i; \ -+ \ -+ for (i = 0; i < _NSIG_WORDS; i++) \ -+ unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \ -+} while (0) - - #ifdef CONFIG_VSX - extern unsigned long copy_vsx_to_user(void __user *to, -diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c -index 0608581967f09..f2da879264bcd 100644 ---- a/arch/powerpc/kernel/signal_32.c -+++ b/arch/powerpc/kernel/signal_32.c -@@ -1062,8 +1062,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, - * or if another thread unmaps the region containing the context. - * We kill the task with a SIGSEGV in this situation. - */ -- if (do_setcontext(new_ctx, regs, 0)) -- do_exit(SIGSEGV); -+ if (do_setcontext(new_ctx, regs, 0)) { -+ force_exit_sig(SIGSEGV); -+ return -EFAULT; -+ } - - set_thread_flag(TIF_RESTOREALL); - return 0; -diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c -index 1831bba0582e1..bb9c077ac1322 100644 ---- a/arch/powerpc/kernel/signal_64.c -+++ b/arch/powerpc/kernel/signal_64.c -@@ -703,15 +703,18 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, - * We kill the task with a SIGSEGV in this situation. - */ - -- if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) -- do_exit(SIGSEGV); -+ if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) { -+ force_exit_sig(SIGSEGV); -+ return -EFAULT; -+ } - set_current_blocked(&set); - - if (!user_read_access_begin(new_ctx, ctx_size)) - return -EFAULT; - if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) { - user_read_access_end(); -- do_exit(SIGSEGV); -+ force_exit_sig(SIGSEGV); -+ return -EFAULT; - } - user_read_access_end(); - -diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c -index 605bab448f847..fb95f92dcfac6 100644 ---- a/arch/powerpc/kernel/smp.c -+++ b/arch/powerpc/kernel/smp.c -@@ -61,6 +61,7 @@ - #include - #include - #include -+#include - - #ifdef DEBUG - #include -@@ -620,6 +621,45 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) - } - #endif - -+#ifdef CONFIG_NMI_IPI -+static void crash_stop_this_cpu(struct pt_regs *regs) -+#else -+static void crash_stop_this_cpu(void *dummy) -+#endif -+{ -+ /* -+ * Just busy wait here and avoid marking CPU as offline to ensure -+ * register data is captured appropriately. -+ */ -+ while (1) -+ cpu_relax(); -+} -+ -+void crash_smp_send_stop(void) -+{ -+ static bool stopped = false; -+ -+ /* -+ * In case of fadump, register data for all CPUs is captured by f/w -+ * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before -+ * this rtas call to avoid tricky post processing of those CPUs' -+ * backtraces. -+ */ -+ if (should_fadump_crash()) -+ return; -+ -+ if (stopped) -+ return; -+ -+ stopped = true; -+ -+#ifdef CONFIG_NMI_IPI -+ smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 1000000); -+#else -+ smp_call_function(crash_stop_this_cpu, NULL, 0); -+#endif /* CONFIG_NMI_IPI */ -+} -+ - #ifdef CONFIG_NMI_IPI - static void nmi_stop_this_cpu(struct pt_regs *regs) - { -@@ -1640,10 +1680,12 @@ void start_secondary(void *unused) - BUG(); - } - -+#ifdef CONFIG_PROFILING - int setup_profiling_timer(unsigned int multiplier) - { - return 0; - } -+#endif - - static void fixup_topology(void) - { -diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c -index f9ea0e5357f92..ad94a2c6b7337 100644 ---- a/arch/powerpc/kernel/watchdog.c -+++ b/arch/powerpc/kernel/watchdog.c -@@ -135,6 +135,10 @@ static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb) - { - cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask); - cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask); -+ /* -+ * See wd_smp_clear_cpu_pending() -+ */ -+ smp_mb(); - if (cpumask_empty(&wd_smp_cpus_pending)) { - wd_smp_last_reset_tb = tb; - cpumask_andnot(&wd_smp_cpus_pending, -@@ -187,6 +191,12 @@ static void watchdog_smp_panic(int cpu, u64 tb) - if (sysctl_hardlockup_all_cpu_backtrace) - trigger_allbutself_cpu_backtrace(); - -+ /* -+ * Force flush any remote buffers that might be stuck in IRQ context -+ * and therefore could not run their irq_work. -+ */ -+ printk_trigger_flush(); -+ - if (hardlockup_panic) - nmi_panic(NULL, "Hard LOCKUP"); - -@@ -215,13 +225,44 @@ static void wd_smp_clear_cpu_pending(int cpu, u64 tb) - - cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck); - wd_smp_unlock(&flags); -+ } else { -+ /* -+ * The last CPU to clear pending should have reset the -+ * watchdog so we generally should not find it empty -+ * here if our CPU was clear. However it could happen -+ * due to a rare race with another CPU taking the -+ * last CPU out of the mask concurrently. -+ * -+ * We can't add a warning for it. But just in case -+ * there is a problem with the watchdog that is causing -+ * the mask to not be reset, try to kick it along here. -+ */ -+ if (unlikely(cpumask_empty(&wd_smp_cpus_pending))) -+ goto none_pending; - } - return; - } -+ - cpumask_clear_cpu(cpu, &wd_smp_cpus_pending); -+ -+ /* -+ * Order the store to clear pending with the load(s) to check all -+ * words in the pending mask to check they are all empty. This orders -+ * with the same barrier on another CPU. This prevents two CPUs -+ * clearing the last 2 pending bits, but neither seeing the other's -+ * store when checking if the mask is empty, and missing an empty -+ * mask, which ends with a false positive. -+ */ -+ smp_mb(); - if (cpumask_empty(&wd_smp_cpus_pending)) { - unsigned long flags; - -+none_pending: -+ /* -+ * Double check under lock because more than one CPU could see -+ * a clear mask with the lockless check after clearing their -+ * pending bits. -+ */ - wd_smp_lock(&flags); - if (cpumask_empty(&wd_smp_cpus_pending)) { - wd_smp_last_reset_tb = tb; -@@ -312,8 +353,12 @@ void arch_touch_nmi_watchdog(void) - { - unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000; - int cpu = smp_processor_id(); -- u64 tb = get_tb(); -+ u64 tb; - -+ if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) -+ return; -+ -+ tb = get_tb(); - if (tb - per_cpu(wd_timer_tb, cpu) >= ticks) { - per_cpu(wd_timer_tb, cpu) = tb; - wd_smp_clear_cpu_pending(cpu, tb); -diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c -index 2acb1c96cfafd..a2fd1db29f7e8 100644 ---- a/arch/powerpc/kvm/book3s_hv.c -+++ b/arch/powerpc/kvm/book3s_hv.c -@@ -1731,7 +1731,6 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, - - static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) - { -- struct kvm_nested_guest *nested = vcpu->arch.nested; - int r; - int srcu_idx; - -@@ -1831,7 +1830,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) - * it into a HEAI. - */ - if (!(vcpu->arch.hfscr_permitted & (1UL << cause)) || -- (nested->hfscr & (1UL << cause))) { -+ (vcpu->arch.nested_hfscr & (1UL << cause))) { - vcpu->arch.trap = BOOK3S_INTERRUPT_H_EMUL_ASSIST; - - /* -@@ -3726,7 +3725,20 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) - - kvmppc_set_host_core(pcpu); - -- guest_exit_irqoff(); -+ context_tracking_guest_exit(); -+ if (!vtime_accounting_enabled_this_cpu()) { -+ local_irq_enable(); -+ /* -+ * Service IRQs here before vtime_account_guest_exit() so any -+ * ticks that occurred while running the guest are accounted to -+ * the guest. If vtime accounting is enabled, accounting uses -+ * TB rather than ticks, so it can be done without enabling -+ * interrupts here, which has the problem that it accounts -+ * interrupt processing overhead to the host. -+ */ -+ local_irq_disable(); -+ } -+ vtime_account_guest_exit(); - - local_irq_enable(); - -@@ -4510,7 +4522,20 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, - - kvmppc_set_host_core(pcpu); - -- guest_exit_irqoff(); -+ context_tracking_guest_exit(); -+ if (!vtime_accounting_enabled_this_cpu()) { -+ local_irq_enable(); -+ /* -+ * Service IRQs here before vtime_account_guest_exit() so any -+ * ticks that occurred while running the guest are accounted to -+ * the guest. If vtime accounting is enabled, accounting uses -+ * TB rather than ticks, so it can be done without enabling -+ * interrupts here, which has the problem that it accounts -+ * interrupt processing overhead to the host. -+ */ -+ local_irq_disable(); -+ } -+ vtime_account_guest_exit(); - - local_irq_enable(); - -@@ -4835,8 +4860,12 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, - unsigned long npages = mem->memory_size >> PAGE_SHIFT; - - if (change == KVM_MR_CREATE) { -- slot->arch.rmap = vzalloc(array_size(npages, -- sizeof(*slot->arch.rmap))); -+ unsigned long size = array_size(npages, sizeof(*slot->arch.rmap)); -+ -+ if ((size >> PAGE_SHIFT) > totalram_pages()) -+ return -ENOMEM; -+ -+ slot->arch.rmap = vzalloc(size); - if (!slot->arch.rmap) - return -ENOMEM; - } -diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c -index fcf4760a3a0ea..70b7a8f971538 100644 ---- a/arch/powerpc/kvm/book3s_hv_builtin.c -+++ b/arch/powerpc/kvm/book3s_hv_builtin.c -@@ -695,6 +695,7 @@ static void flush_guest_tlb(struct kvm *kvm) - "r" (0) : "memory"); - } - asm volatile("ptesync": : :"memory"); -+ // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now. - asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory"); - } else { - for (set = 0; set < kvm->arch.tlb_sets; ++set) { -@@ -705,7 +706,9 @@ static void flush_guest_tlb(struct kvm *kvm) - rb += PPC_BIT(51); /* increment set number */ - } - asm volatile("ptesync": : :"memory"); -- asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); -+ // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now. -+ if (cpu_has_feature(CPU_FTR_ARCH_300)) -+ asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); - } - } - -diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c -index ed8a2c9f56299..6c4e0e93105ff 100644 ---- a/arch/powerpc/kvm/book3s_hv_nested.c -+++ b/arch/powerpc/kvm/book3s_hv_nested.c -@@ -362,7 +362,7 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) - /* set L1 state to L2 state */ - vcpu->arch.nested = l2; - vcpu->arch.nested_vcpu_id = l2_hv.vcpu_token; -- l2->hfscr = l2_hv.hfscr; -+ vcpu->arch.nested_hfscr = l2_hv.hfscr; - vcpu->arch.regs = l2_regs; - - /* Guest must always run with ME enabled, HV disabled. */ -@@ -582,7 +582,7 @@ long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu) - if (eaddr & (0xFFFUL << 52)) - return H_PARAMETER; - -- buf = kzalloc(n, GFP_KERNEL); -+ buf = kzalloc(n, GFP_KERNEL | __GFP_NOWARN); - if (!buf) - return H_NO_MEM; - -diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -index eb776d0c5d8e9..32a4b4d412b92 100644 ---- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S -+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -@@ -2005,7 +2005,7 @@ hcall_real_table: - .globl hcall_real_table_end - hcall_real_table_end: - --_GLOBAL(kvmppc_h_set_xdabr) -+_GLOBAL_TOC(kvmppc_h_set_xdabr) - EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) - andi. r0, r5, DABRX_USER | DABRX_KERNEL - beq 6f -@@ -2015,7 +2015,7 @@ EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) - 6: li r3, H_PARAMETER - blr - --_GLOBAL(kvmppc_h_set_dabr) -+_GLOBAL_TOC(kvmppc_h_set_dabr) - EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr) - li r5, DABRX_USER | DABRX_KERNEL - 3: -diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c -index 977801c83aff8..8c15c90dd3a97 100644 ---- a/arch/powerpc/kvm/booke.c -+++ b/arch/powerpc/kvm/booke.c -@@ -1042,7 +1042,21 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr) - } - - trace_kvm_exit(exit_nr, vcpu); -- guest_exit_irqoff(); -+ -+ context_tracking_guest_exit(); -+ if (!vtime_accounting_enabled_this_cpu()) { -+ local_irq_enable(); -+ /* -+ * Service IRQs here before vtime_account_guest_exit() so any -+ * ticks that occurred while running the guest are accounted to -+ * the guest. If vtime accounting is enabled, accounting uses -+ * TB rather than ticks, so it can be done without enabling -+ * interrupts here, which has the problem that it accounts -+ * interrupt processing overhead to the host. -+ */ -+ local_irq_disable(); -+ } -+ vtime_account_guest_exit(); - - local_irq_enable(); - -diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile -index 99a7c9132422c..54be64203b2ab 100644 ---- a/arch/powerpc/lib/Makefile -+++ b/arch/powerpc/lib/Makefile -@@ -19,6 +19,9 @@ CFLAGS_code-patching.o += -DDISABLE_BRANCH_PROFILING - CFLAGS_feature-fixups.o += -DDISABLE_BRANCH_PROFILING - endif - -+CFLAGS_code-patching.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) -+CFLAGS_feature-fixups.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) -+ - obj-y += alloc.o code-patching.o feature-fixups.o pmem.o test_code-patching.o - - ifndef CONFIG_KASAN -diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c -index cda17bee5afea..c3e06922468b3 100644 ---- a/arch/powerpc/lib/feature-fixups.c -+++ b/arch/powerpc/lib/feature-fixups.c -@@ -228,6 +228,7 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types) - - static bool stf_exit_reentrant = false; - static bool rfi_exit_reentrant = false; -+static DEFINE_MUTEX(exit_flush_lock); - - static int __do_stf_barrier_fixups(void *data) - { -@@ -253,6 +254,9 @@ void do_stf_barrier_fixups(enum stf_barrier_type types) - * low level interrupt exit code before patching. After the patching, - * if allowed, then flip the branch to allow fast exits. - */ -+ -+ // Prevent static key update races with do_rfi_flush_fixups() -+ mutex_lock(&exit_flush_lock); - static_branch_enable(&interrupt_exit_not_reentrant); - - stop_machine(__do_stf_barrier_fixups, &types, NULL); -@@ -264,6 +268,8 @@ void do_stf_barrier_fixups(enum stf_barrier_type types) - - if (stf_exit_reentrant && rfi_exit_reentrant) - static_branch_disable(&interrupt_exit_not_reentrant); -+ -+ mutex_unlock(&exit_flush_lock); - } - - void do_uaccess_flush_fixups(enum l1d_flush_type types) -@@ -486,6 +492,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types) - * without stop_machine, so this could be achieved with a broadcast - * IPI instead, but this matches the stf sequence. - */ -+ -+ // Prevent static key update races with do_stf_barrier_fixups() -+ mutex_lock(&exit_flush_lock); - static_branch_enable(&interrupt_exit_not_reentrant); - - stop_machine(__do_rfi_flush_fixups, &types, NULL); -@@ -497,6 +506,8 @@ void do_rfi_flush_fixups(enum l1d_flush_type types) - - if (stf_exit_reentrant && rfi_exit_reentrant) - static_branch_disable(&interrupt_exit_not_reentrant); -+ -+ mutex_unlock(&exit_flush_lock); - } - - void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end) -diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c -index d8d5f901cee1c..d8cc49f39fe47 100644 ---- a/arch/powerpc/lib/sstep.c -+++ b/arch/powerpc/lib/sstep.c -@@ -3181,12 +3181,14 @@ void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op) - case BARRIER_EIEIO: - eieio(); - break; -+#ifdef CONFIG_PPC64 - case BARRIER_LWSYNC: - asm volatile("lwsync" : : : "memory"); - break; - case BARRIER_PTESYNC: - asm volatile("ptesync" : : : "memory"); - break; -+#endif - } - break; - -diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c -index 27061583a0107..203735caf6915 100644 ---- a/arch/powerpc/mm/book3s32/mmu.c -+++ b/arch/powerpc/mm/book3s32/mmu.c -@@ -76,7 +76,7 @@ unsigned long p_block_mapped(phys_addr_t pa) - return 0; - } - --static int find_free_bat(void) -+int __init find_free_bat(void) - { - int b; - int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4; -@@ -100,7 +100,7 @@ static int find_free_bat(void) - * - block size has to be a power of two. This is calculated by finding the - * highest bit set to 1. - */ --static unsigned int block_size(unsigned long base, unsigned long top) -+unsigned int bat_block_size(unsigned long base, unsigned long top) - { - unsigned int max_size = SZ_256M; - unsigned int base_shift = (ffs(base) - 1) & 31; -@@ -145,7 +145,7 @@ static unsigned long __init __mmu_mapin_ram(unsigned long base, unsigned long to - int idx; - - while ((idx = find_free_bat()) != -1 && base != top) { -- unsigned int size = block_size(base, top); -+ unsigned int size = bat_block_size(base, top); - - if (size < 128 << 10) - break; -@@ -196,18 +196,17 @@ void mmu_mark_initmem_nx(void) - int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4; - int i; - unsigned long base = (unsigned long)_stext - PAGE_OFFSET; -- unsigned long top = (unsigned long)_etext - PAGE_OFFSET; -+ unsigned long top = ALIGN((unsigned long)_etext - PAGE_OFFSET, SZ_128K); - unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET; - unsigned long size; - -- for (i = 0; i < nb - 1 && base < top && top - base > (128 << 10);) { -- size = block_size(base, top); -+ for (i = 0; i < nb - 1 && base < top;) { -+ size = bat_block_size(base, top); - setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT); - base += size; - } - if (base < top) { -- size = block_size(base, top); -- size = max(size, 128UL << 10); -+ size = bat_block_size(base, top); - if ((top - base) > size) { - size <<= 1; - if (strict_kernel_rwx_enabled() && base + size > border) -diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c -index ae20add7954a0..795d18a84f556 100644 ---- a/arch/powerpc/mm/book3s64/radix_pgtable.c -+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c -@@ -1093,7 +1093,7 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) - - int pud_clear_huge(pud_t *pud) - { -- if (pud_huge(*pud)) { -+ if (pud_is_leaf(*pud)) { - pud_clear(pud); - return 1; - } -@@ -1140,7 +1140,7 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) - - int pmd_clear_huge(pmd_t *pmd) - { -- if (pmd_huge(*pmd)) { -+ if (pmd_is_leaf(*pmd)) { - pmd_clear(pmd); - return 1; - } -diff --git a/arch/powerpc/mm/kasan/book3s_32.c b/arch/powerpc/mm/kasan/book3s_32.c -index 202bd260a0095..450a67ef0bbe1 100644 ---- a/arch/powerpc/mm/kasan/book3s_32.c -+++ b/arch/powerpc/mm/kasan/book3s_32.c -@@ -10,47 +10,51 @@ int __init kasan_init_region(void *start, size_t size) - { - unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start); - unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size); -- unsigned long k_cur = k_start; -- int k_size = k_end - k_start; -- int k_size_base = 1 << (ffs(k_size) - 1); -+ unsigned long k_nobat = k_start; -+ unsigned long k_cur; -+ phys_addr_t phys; - int ret; -- void *block; - -- block = memblock_alloc(k_size, k_size_base); -- -- if (block && k_size_base >= SZ_128K && k_start == ALIGN(k_start, k_size_base)) { -- int k_size_more = 1 << (ffs(k_size - k_size_base) - 1); -- -- setbat(-1, k_start, __pa(block), k_size_base, PAGE_KERNEL); -- if (k_size_more >= SZ_128K) -- setbat(-1, k_start + k_size_base, __pa(block) + k_size_base, -- k_size_more, PAGE_KERNEL); -- if (v_block_mapped(k_start)) -- k_cur = k_start + k_size_base; -- if (v_block_mapped(k_start + k_size_base)) -- k_cur = k_start + k_size_base + k_size_more; -- -- update_bats(); -+ while (k_nobat < k_end) { -+ unsigned int k_size = bat_block_size(k_nobat, k_end); -+ int idx = find_free_bat(); -+ -+ if (idx == -1) -+ break; -+ if (k_size < SZ_128K) -+ break; -+ phys = memblock_phys_alloc_range(k_size, k_size, 0, -+ MEMBLOCK_ALLOC_ANYWHERE); -+ if (!phys) -+ break; -+ -+ setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL); -+ k_nobat += k_size; - } -+ if (k_nobat != k_start) -+ update_bats(); - -- if (!block) -- block = memblock_alloc(k_size, PAGE_SIZE); -- if (!block) -- return -ENOMEM; -+ if (k_nobat < k_end) { -+ phys = memblock_phys_alloc_range(k_end - k_nobat, PAGE_SIZE, 0, -+ MEMBLOCK_ALLOC_ANYWHERE); -+ if (!phys) -+ return -ENOMEM; -+ } - - ret = kasan_init_shadow_page_tables(k_start, k_end); - if (ret) - return ret; - -- kasan_update_early_region(k_start, k_cur, __pte(0)); -+ kasan_update_early_region(k_start, k_nobat, __pte(0)); - -- for (; k_cur < k_end; k_cur += PAGE_SIZE) { -+ for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) { - pmd_t *pmd = pmd_off_k(k_cur); -- void *va = block + k_cur - k_start; -- pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL); -+ pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL); - - __set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0); - } - flush_tlb_kernel_range(k_start, k_end); -+ memset(kasan_mem_to_shadow(start), 0, k_end - k_start); -+ - return 0; - } -diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c -index c3c4e31462eca..05b9c3f31456c 100644 ---- a/arch/powerpc/mm/mem.c -+++ b/arch/powerpc/mm/mem.c -@@ -20,8 +20,8 @@ - #include - #include - #include --#include - #include -+#include - - #include - -diff --git a/arch/powerpc/mm/nohash/tlb_low_64e.S b/arch/powerpc/mm/nohash/tlb_low_64e.S -index bf24451f3e71f..9235e720e3572 100644 ---- a/arch/powerpc/mm/nohash/tlb_low_64e.S -+++ b/arch/powerpc/mm/nohash/tlb_low_64e.S -@@ -222,7 +222,7 @@ tlb_miss_kernel_bolted: - - tlb_miss_fault_bolted: - /* We need to check if it was an instruction miss */ -- andi. r10,r11,_PAGE_EXEC|_PAGE_BAP_SX -+ andi. r10,r11,_PAGE_BAP_UX|_PAGE_BAP_SX - bne itlb_miss_fault_bolted - dtlb_miss_fault_bolted: - tlb_epilog_bolted -@@ -239,7 +239,7 @@ itlb_miss_fault_bolted: - srdi r15,r16,60 /* get region */ - bne- itlb_miss_fault_bolted - -- li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */ -+ li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */ - - /* We do the user/kernel test for the PID here along with the RW test - */ -@@ -614,7 +614,7 @@ itlb_miss_fault_e6500: - - /* We do the user/kernel test for the PID here along with the RW test - */ -- li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */ -+ li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */ - oris r11,r11,_PAGE_ACCESSED@h - - cmpldi cr0,r15,0 /* Check for user region */ -@@ -734,7 +734,7 @@ normal_tlb_miss_done: - - normal_tlb_miss_access_fault: - /* We need to check if it was an instruction miss */ -- andi. r10,r11,_PAGE_EXEC -+ andi. r10,r11,_PAGE_BAP_UX - bne 1f - ld r14,EX_TLB_DEAR(r12) - ld r15,EX_TLB_ESR(r12) -diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c -index 6f14c8fb6359d..59d3cfcd78879 100644 ---- a/arch/powerpc/mm/numa.c -+++ b/arch/powerpc/mm/numa.c -@@ -376,9 +376,9 @@ static void initialize_form2_numa_distance_lookup_table(void) - { - int i, j; - struct device_node *root; -- const __u8 *numa_dist_table; -+ const __u8 *form2_distances; - const __be32 *numa_lookup_index; -- int numa_dist_table_length; -+ int form2_distances_length; - int max_numa_index, distance_index; - - if (firmware_has_feature(FW_FEATURE_OPAL)) -@@ -392,45 +392,41 @@ static void initialize_form2_numa_distance_lookup_table(void) - max_numa_index = of_read_number(&numa_lookup_index[0], 1); - - /* first element of the array is the size and is encode-int */ -- numa_dist_table = of_get_property(root, "ibm,numa-distance-table", NULL); -- numa_dist_table_length = of_read_number((const __be32 *)&numa_dist_table[0], 1); -+ form2_distances = of_get_property(root, "ibm,numa-distance-table", NULL); -+ form2_distances_length = of_read_number((const __be32 *)&form2_distances[0], 1); - /* Skip the size which is encoded int */ -- numa_dist_table += sizeof(__be32); -+ form2_distances += sizeof(__be32); - -- pr_debug("numa_dist_table_len = %d, numa_dist_indexes_len = %d\n", -- numa_dist_table_length, max_numa_index); -+ pr_debug("form2_distances_len = %d, numa_dist_indexes_len = %d\n", -+ form2_distances_length, max_numa_index); - - for (i = 0; i < max_numa_index; i++) - /* +1 skip the max_numa_index in the property */ - numa_id_index_table[i] = of_read_number(&numa_lookup_index[i + 1], 1); - - -- if (numa_dist_table_length != max_numa_index * max_numa_index) { -+ if (form2_distances_length != max_numa_index * max_numa_index) { - WARN(1, "Wrong NUMA distance information\n"); -- /* consider everybody else just remote. */ -- for (i = 0; i < max_numa_index; i++) { -- for (j = 0; j < max_numa_index; j++) { -- int nodeA = numa_id_index_table[i]; -- int nodeB = numa_id_index_table[j]; -- -- if (nodeA == nodeB) -- numa_distance_table[nodeA][nodeB] = LOCAL_DISTANCE; -- else -- numa_distance_table[nodeA][nodeB] = REMOTE_DISTANCE; -- } -- } -+ form2_distances = NULL; // don't use it - } -- - distance_index = 0; - for (i = 0; i < max_numa_index; i++) { - for (j = 0; j < max_numa_index; j++) { - int nodeA = numa_id_index_table[i]; - int nodeB = numa_id_index_table[j]; -- -- numa_distance_table[nodeA][nodeB] = numa_dist_table[distance_index++]; -- pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]); -+ int dist; -+ -+ if (form2_distances) -+ dist = form2_distances[distance_index++]; -+ else if (nodeA == nodeB) -+ dist = LOCAL_DISTANCE; -+ else -+ dist = REMOTE_DISTANCE; -+ numa_distance_table[nodeA][nodeB] = dist; -+ pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, dist); - } - } -+ - of_node_put(root); - } - -diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c -index cd16b407f47e1..9a93c1a5aa1d1 100644 ---- a/arch/powerpc/mm/pgtable.c -+++ b/arch/powerpc/mm/pgtable.c -@@ -203,6 +203,15 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, - __set_pte_at(mm, addr, ptep, pte, 0); - } - -+void unmap_kernel_page(unsigned long va) -+{ -+ pmd_t *pmdp = pmd_off_k(va); -+ pte_t *ptep = pte_offset_kernel(pmdp, va); -+ -+ pte_clear(&init_mm, va, ptep); -+ flush_tlb_kernel_range(va, va + PAGE_SIZE); -+} -+ - /* - * This is called when relaxing access to a PTE. It's also called in the page - * fault path when we don't hit any of the major fault cases, ie, a minor -diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c -index dcf5ecca19d99..fde1ed445ca46 100644 ---- a/arch/powerpc/mm/pgtable_32.c -+++ b/arch/powerpc/mm/pgtable_32.c -@@ -173,7 +173,7 @@ void mark_rodata_ro(void) - } - #endif - --#ifdef CONFIG_DEBUG_PAGEALLOC -+#if defined(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) && defined(CONFIG_DEBUG_PAGEALLOC) - void __kernel_map_pages(struct page *page, int numpages, int enable) - { - unsigned long addr = (unsigned long)page_address(page); -diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c -index 78c8cf01db5f9..175aabf101e87 100644 ---- a/arch/powerpc/mm/pgtable_64.c -+++ b/arch/powerpc/mm/pgtable_64.c -@@ -102,7 +102,8 @@ EXPORT_SYMBOL(__pte_frag_size_shift); - struct page *p4d_page(p4d_t p4d) - { - if (p4d_is_leaf(p4d)) { -- VM_WARN_ON(!p4d_huge(p4d)); -+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) -+ VM_WARN_ON(!p4d_huge(p4d)); - return pte_page(p4d_pte(p4d)); - } - return virt_to_page(p4d_pgtable(p4d)); -@@ -112,7 +113,8 @@ struct page *p4d_page(p4d_t p4d) - struct page *pud_page(pud_t pud) - { - if (pud_is_leaf(pud)) { -- VM_WARN_ON(!pud_huge(pud)); -+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) -+ VM_WARN_ON(!pud_huge(pud)); - return pte_page(pud_pte(pud)); - } - return virt_to_page(pud_pgtable(pud)); -@@ -125,7 +127,13 @@ struct page *pud_page(pud_t pud) - struct page *pmd_page(pmd_t pmd) - { - if (pmd_is_leaf(pmd)) { -- VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd))); -+ /* -+ * vmalloc_to_page may be called on any vmap address (not only -+ * vmalloc), and it uses pmd_page() etc., when huge vmap is -+ * enabled so these checks can't be used. -+ */ -+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) -+ VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd))); - return pte_page(pmd_pte(pmd)); - } - return virt_to_page(pmd_page_vaddr(pmd)); -diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c -index bf251191e78d9..32bfb215c4858 100644 ---- a/arch/powerpc/mm/ptdump/ptdump.c -+++ b/arch/powerpc/mm/ptdump/ptdump.c -@@ -183,7 +183,7 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr) - { - pte_t pte = __pte(st->current_flags); - -- if (!IS_ENABLED(CONFIG_PPC_DEBUG_WX) || !st->check_wx) -+ if (!IS_ENABLED(CONFIG_DEBUG_WX) || !st->check_wx) - return; - - if (!pte_write(pte) || !pte_exec(pte)) -diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c -index fcbf7a917c566..8acf8a611a265 100644 ---- a/arch/powerpc/net/bpf_jit_comp.c -+++ b/arch/powerpc/net/bpf_jit_comp.c -@@ -23,15 +23,15 @@ static void bpf_jit_fill_ill_insns(void *area, unsigned int size) - memset32(area, BREAKPOINT_INSTRUCTION, size / 4); - } - --/* Fix the branch target addresses for subprog calls */ --static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image, -- struct codegen_context *ctx, u32 *addrs) -+/* Fix updated addresses (for subprog calls, ldimm64, et al) during extra pass */ -+static int bpf_jit_fixup_addresses(struct bpf_prog *fp, u32 *image, -+ struct codegen_context *ctx, u32 *addrs) - { - const struct bpf_insn *insn = fp->insnsi; - bool func_addr_fixed; - u64 func_addr; - u32 tmp_idx; -- int i, ret; -+ int i, j, ret; - - for (i = 0; i < fp->len; i++) { - /* -@@ -66,6 +66,23 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image, - * of the JITed sequence remains unchanged. - */ - ctx->idx = tmp_idx; -+ } else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) { -+ tmp_idx = ctx->idx; -+ ctx->idx = addrs[i] / 4; -+#ifdef CONFIG_PPC32 -+ PPC_LI32(ctx->b2p[insn[i].dst_reg] - 1, (u32)insn[i + 1].imm); -+ PPC_LI32(ctx->b2p[insn[i].dst_reg], (u32)insn[i].imm); -+ for (j = ctx->idx - addrs[i] / 4; j < 4; j++) -+ EMIT(PPC_RAW_NOP()); -+#else -+ func_addr = ((u64)(u32)insn[i].imm) | (((u64)(u32)insn[i + 1].imm) << 32); -+ PPC_LI64(b2p[insn[i].dst_reg], func_addr); -+ /* overwrite rest with nops */ -+ for (j = ctx->idx - addrs[i] / 4; j < 5; j++) -+ EMIT(PPC_RAW_NOP()); -+#endif -+ ctx->idx = tmp_idx; -+ i++; - } - } - -@@ -193,13 +210,13 @@ skip_init_ctx: - /* - * Do not touch the prologue and epilogue as they will remain - * unchanged. Only fix the branch target address for subprog -- * calls in the body. -+ * calls in the body, and ldimm64 instructions. - * - * This does not change the offsets and lengths of the subprog - * call instruction sequences and hence, the size of the JITed - * image as well. - */ -- bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs); -+ bpf_jit_fixup_addresses(fp, code_base, &cgctx, addrs); - - /* There is no need to perform the usual passes. */ - goto skip_codegen_passes; -@@ -241,8 +258,8 @@ skip_codegen_passes: - fp->jited_len = alloclen; - - bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE)); -- bpf_jit_binary_lock_ro(bpf_hdr); - if (!fp->is_func || extra_pass) { -+ bpf_jit_binary_lock_ro(bpf_hdr); - bpf_prog_fill_jited_linfo(fp, addrs); - out_addrs: - kfree(addrs); -diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c -index 0da31d41d4131..bce5eda85170f 100644 ---- a/arch/powerpc/net/bpf_jit_comp32.c -+++ b/arch/powerpc/net/bpf_jit_comp32.c -@@ -191,6 +191,9 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun - - if (image && rel < 0x2000000 && rel >= -0x2000000) { - PPC_BL_ABS(func); -+ EMIT(PPC_RAW_NOP()); -+ EMIT(PPC_RAW_NOP()); -+ EMIT(PPC_RAW_NOP()); - } else { - /* Load function address into r0 */ - EMIT(PPC_RAW_LIS(_R0, IMM_H(func))); -@@ -289,6 +292,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * - bool func_addr_fixed; - u64 func_addr; - u32 true_cond; -+ u32 tmp_idx; -+ int j; - - /* - * addrs[] maps a BPF bytecode address into a real offset from -@@ -836,8 +841,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * - * 16 byte instruction that uses two 'struct bpf_insn' - */ - case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */ -+ tmp_idx = ctx->idx; - PPC_LI32(dst_reg_h, (u32)insn[i + 1].imm); - PPC_LI32(dst_reg, (u32)insn[i].imm); -+ /* padding to allow full 4 instructions for later patching */ -+ for (j = ctx->idx - tmp_idx; j < 4; j++) -+ EMIT(PPC_RAW_NOP()); - /* Adjust for two bpf instructions */ - addrs[++i] = ctx->idx * 4; - break; -diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c -index 8b5157ccfebae..57e1b6680365c 100644 ---- a/arch/powerpc/net/bpf_jit_comp64.c -+++ b/arch/powerpc/net/bpf_jit_comp64.c -@@ -318,6 +318,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * - u64 imm64; - u32 true_cond; - u32 tmp_idx; -+ int j; - - /* - * addrs[] maps a BPF bytecode address into a real offset from -@@ -632,17 +633,21 @@ bpf_alu32_trunc: - EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1])); - break; - case 64: -- /* -- * Way easier and faster(?) to store the value -- * into stack and then use ldbrx -- * -- * ctx->seen will be reliable in pass2, but -- * the instructions generated will remain the -- * same across all passes -- */ -+ /* Store the value to stack and then use byte-reverse loads */ - PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx)); - EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx))); -- EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1])); -+ if (cpu_has_feature(CPU_FTR_ARCH_206)) { -+ EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1])); -+ } else { -+ EMIT(PPC_RAW_LWBRX(dst_reg, 0, b2p[TMP_REG_1])); -+ if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) -+ EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, 32)); -+ EMIT(PPC_RAW_LI(b2p[TMP_REG_2], 4)); -+ EMIT(PPC_RAW_LWBRX(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p[TMP_REG_1])); -+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) -+ EMIT(PPC_RAW_SLDI(b2p[TMP_REG_2], b2p[TMP_REG_2], 32)); -+ EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_2])); -+ } - break; - } - break; -@@ -806,9 +811,13 @@ emit_clear: - case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */ - imm64 = ((u64)(u32) insn[i].imm) | - (((u64)(u32) insn[i+1].imm) << 32); -+ tmp_idx = ctx->idx; -+ PPC_LI64(dst_reg, imm64); -+ /* padding to allow full 5 instructions for later patching */ -+ for (j = ctx->idx - tmp_idx; j < 5; j++) -+ EMIT(PPC_RAW_NOP()); - /* Adjust for two bpf instructions */ - addrs[++i] = ctx->idx * 4; -- PPC_LI64(dst_reg, imm64); - break; - - /* -diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c -index 73e62e9b179bc..e78de70509472 100644 ---- a/arch/powerpc/perf/core-book3s.c -+++ b/arch/powerpc/perf/core-book3s.c -@@ -857,6 +857,19 @@ static void write_pmc(int idx, unsigned long val) - } - } - -+static int any_pmc_overflown(struct cpu_hw_events *cpuhw) -+{ -+ int i, idx; -+ -+ for (i = 0; i < cpuhw->n_events; i++) { -+ idx = cpuhw->event[i]->hw.idx; -+ if ((idx) && ((int)read_pmc(idx) < 0)) -+ return idx; -+ } -+ -+ return 0; -+} -+ - /* Called from sysrq_handle_showregs() */ - void perf_event_print_debug(void) - { -@@ -1281,11 +1294,13 @@ static void power_pmu_disable(struct pmu *pmu) - - /* - * Set the 'freeze counters' bit, clear EBE/BHRBA/PMCC/PMAO/FC56 -+ * Also clear PMXE to disable PMI's getting triggered in some -+ * corner cases during PMU disable. - */ - val = mmcr0 = mfspr(SPRN_MMCR0); - val |= MMCR0_FC; - val &= ~(MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC | MMCR0_PMAO | -- MMCR0_FC56); -+ MMCR0_PMXE | MMCR0_FC56); - /* Set mmcr0 PMCCEXT for p10 */ - if (ppmu->flags & PPMU_ARCH_31) - val |= MMCR0_PMCCEXT; -@@ -1299,6 +1314,34 @@ static void power_pmu_disable(struct pmu *pmu) - mb(); - isync(); - -+ /* -+ * Some corner cases could clear the PMU counter overflow -+ * while a masked PMI is pending. One such case is when -+ * a PMI happens during interrupt replay and perf counter -+ * values are cleared by PMU callbacks before replay. -+ * -+ * If any PMC corresponding to the active PMU events are -+ * overflown, disable the interrupt by clearing the paca -+ * bit for PMI since we are disabling the PMU now. -+ * Otherwise provide a warning if there is PMI pending, but -+ * no counter is found overflown. -+ */ -+ if (any_pmc_overflown(cpuhw)) { -+ /* -+ * Since power_pmu_disable runs under local_irq_save, it -+ * could happen that code hits a PMC overflow without PMI -+ * pending in paca. Hence only clear PMI pending if it was -+ * set. -+ * -+ * If a PMI is pending, then MSR[EE] must be disabled (because -+ * the masked PMI handler disabling EE). So it is safe to -+ * call clear_pmi_irq_pending(). -+ */ -+ if (pmi_irq_pending()) -+ clear_pmi_irq_pending(); -+ } else -+ WARN_ON(pmi_irq_pending()); -+ - val = mmcra = cpuhw->mmcr.mmcra; - - /* -@@ -1390,6 +1433,15 @@ static void power_pmu_enable(struct pmu *pmu) - * (possibly updated for removal of events). - */ - if (!cpuhw->n_added) { -+ /* -+ * If there is any active event with an overflown PMC -+ * value, set back PACA_IRQ_PMI which would have been -+ * cleared in power_pmu_disable(). -+ */ -+ hard_irq_disable(); -+ if (any_pmc_overflown(cpuhw)) -+ set_pmi_irq_pending(); -+ - mtspr(SPRN_MMCRA, cpuhw->mmcr.mmcra & ~MMCRA_SAMPLE_ENABLE); - mtspr(SPRN_MMCR1, cpuhw->mmcr.mmcr1); - if (ppmu->flags & PPMU_ARCH_31) -@@ -2337,6 +2389,14 @@ static void __perf_event_interrupt(struct pt_regs *regs) - break; - } - } -+ -+ /* -+ * Clear PACA_IRQ_PMI in case it was set by -+ * set_pmi_irq_pending() when PMU was enabled -+ * after accounting for interrupts. -+ */ -+ clear_pmi_irq_pending(); -+ - if (!active) - /* reset non active counters that have overflowed */ - write_pmc(i + 1, 0); -@@ -2356,6 +2416,13 @@ static void __perf_event_interrupt(struct pt_regs *regs) - } - } - } -+ -+ /* -+ * During system wide profling or while specific CPU is monitored for an -+ * event, some corner cases could cause PMC to overflow in idle path. This -+ * will trigger a PMI after waking up from idle. Since counter values are _not_ -+ * saved/restored in idle path, can lead to below "Can't find PMC" message. -+ */ - if (unlikely(!found) && !arch_irq_disabled_regs(regs)) - printk_ratelimited(KERN_WARNING "Can't find PMC that caused IRQ\n"); - -diff --git a/arch/powerpc/perf/power10-events-list.h b/arch/powerpc/perf/power10-events-list.h -index 93be7197d2502..564f14097f07b 100644 ---- a/arch/powerpc/perf/power10-events-list.h -+++ b/arch/powerpc/perf/power10-events-list.h -@@ -9,10 +9,10 @@ - /* - * Power10 event codes. - */ --EVENT(PM_RUN_CYC, 0x600f4); -+EVENT(PM_CYC, 0x600f4); - EVENT(PM_DISP_STALL_CYC, 0x100f8); - EVENT(PM_EXEC_STALL, 0x30008); --EVENT(PM_RUN_INST_CMPL, 0x500fa); -+EVENT(PM_INST_CMPL, 0x500fa); - EVENT(PM_BR_CMPL, 0x4d05e); - EVENT(PM_BR_MPRED_CMPL, 0x400f6); - EVENT(PM_BR_FIN, 0x2f04a); -@@ -50,8 +50,8 @@ EVENT(PM_DTLB_MISS, 0x300fc); - /* ITLB Reloaded */ - EVENT(PM_ITLB_MISS, 0x400fc); - --EVENT(PM_RUN_CYC_ALT, 0x0001e); --EVENT(PM_RUN_INST_CMPL_ALT, 0x00002); -+EVENT(PM_CYC_ALT, 0x0001e); -+EVENT(PM_INST_CMPL_ALT, 0x00002); - - /* - * Memory Access Events -diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c -index f9d64c63bb4a7..9dd75f3858372 100644 ---- a/arch/powerpc/perf/power10-pmu.c -+++ b/arch/powerpc/perf/power10-pmu.c -@@ -91,8 +91,8 @@ extern u64 PERF_REG_EXTENDED_MASK; - - /* Table of alternatives, sorted by column 0 */ - static const unsigned int power10_event_alternatives[][MAX_ALT] = { -- { PM_RUN_CYC_ALT, PM_RUN_CYC }, -- { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL }, -+ { PM_CYC_ALT, PM_CYC }, -+ { PM_INST_CMPL_ALT, PM_INST_CMPL }, - }; - - static int power10_get_alternatives(u64 event, unsigned int flags, u64 alt[]) -@@ -118,8 +118,8 @@ static int power10_check_attr_config(struct perf_event *ev) - return 0; - } - --GENERIC_EVENT_ATTR(cpu-cycles, PM_RUN_CYC); --GENERIC_EVENT_ATTR(instructions, PM_RUN_INST_CMPL); -+GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); -+GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); - GENERIC_EVENT_ATTR(branch-instructions, PM_BR_CMPL); - GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL); - GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); -@@ -148,8 +148,8 @@ CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); - CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS); - - static struct attribute *power10_events_attr_dd1[] = { -- GENERIC_EVENT_PTR(PM_RUN_CYC), -- GENERIC_EVENT_PTR(PM_RUN_INST_CMPL), -+ GENERIC_EVENT_PTR(PM_CYC), -+ GENERIC_EVENT_PTR(PM_INST_CMPL), - GENERIC_EVENT_PTR(PM_BR_CMPL), - GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL), - GENERIC_EVENT_PTR(PM_LD_REF_L1), -@@ -173,8 +173,8 @@ static struct attribute *power10_events_attr_dd1[] = { - }; - - static struct attribute *power10_events_attr[] = { -- GENERIC_EVENT_PTR(PM_RUN_CYC), -- GENERIC_EVENT_PTR(PM_RUN_INST_CMPL), -+ GENERIC_EVENT_PTR(PM_CYC), -+ GENERIC_EVENT_PTR(PM_INST_CMPL), - GENERIC_EVENT_PTR(PM_BR_FIN), - GENERIC_EVENT_PTR(PM_MPRED_BR_FIN), - GENERIC_EVENT_PTR(PM_LD_REF_L1), -@@ -271,8 +271,8 @@ static const struct attribute_group *power10_pmu_attr_groups[] = { - }; - - static int power10_generic_events_dd1[] = { -- [PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC, -- [PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL, -+ [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, -+ [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL, - [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL, - [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, -@@ -280,8 +280,8 @@ static int power10_generic_events_dd1[] = { - }; - - static int power10_generic_events[] = { -- [PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC, -- [PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL, -+ [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, -+ [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_FIN, - [PERF_COUNT_HW_BRANCH_MISSES] = PM_MPRED_BR_FIN, - [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, -@@ -548,6 +548,24 @@ static u64 power10_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { - - #undef C - -+/* -+ * Set the MMCR0[CC56RUN] bit to enable counting for -+ * PMC5 and PMC6 regardless of the state of CTRL[RUN], -+ * so that we can use counters 5 and 6 as PM_INST_CMPL and -+ * PM_CYC. -+ */ -+static int power10_compute_mmcr(u64 event[], int n_ev, -+ unsigned int hwc[], struct mmcr_regs *mmcr, -+ struct perf_event *pevents[], u32 flags) -+{ -+ int ret; -+ -+ ret = isa207_compute_mmcr(event, n_ev, hwc, mmcr, pevents, flags); -+ if (!ret) -+ mmcr->mmcr0 |= MMCR0_C56RUN; -+ return ret; -+} -+ - static struct power_pmu power10_pmu = { - .name = "POWER10", - .n_counter = MAX_PMU_COUNTERS, -@@ -555,7 +573,7 @@ static struct power_pmu power10_pmu = { - .test_adder = ISA207_TEST_ADDER, - .group_constraint_mask = CNST_CACHE_PMC4_MASK, - .group_constraint_val = CNST_CACHE_PMC4_VAL, -- .compute_mmcr = isa207_compute_mmcr, -+ .compute_mmcr = power10_compute_mmcr, - .config_bhrb = power10_config_bhrb, - .bhrb_filter_map = power10_bhrb_filter_map, - .get_constraint = isa207_get_constraint, -diff --git a/arch/powerpc/platforms/44x/fsp2.c b/arch/powerpc/platforms/44x/fsp2.c -index b299e43f5ef94..823397c802def 100644 ---- a/arch/powerpc/platforms/44x/fsp2.c -+++ b/arch/powerpc/platforms/44x/fsp2.c -@@ -208,6 +208,7 @@ static void node_irq_request(const char *compat, irq_handler_t errirq_handler) - if (irq == NO_IRQ) { - pr_err("device tree node %pOFn is missing a interrupt", - np); -+ of_node_put(np); - return; - } - -@@ -215,6 +216,7 @@ static void node_irq_request(const char *compat, irq_handler_t errirq_handler) - if (rc) { - pr_err("fsp_of_probe: request_irq failed: np=%pOF rc=%d", - np, rc); -+ of_node_put(np); - return; - } - } -diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile -index 60e4e97a929db..260fbad7967b2 100644 ---- a/arch/powerpc/platforms/85xx/Makefile -+++ b/arch/powerpc/platforms/85xx/Makefile -@@ -3,7 +3,9 @@ - # Makefile for the PowerPC 85xx linux kernel. - # - obj-$(CONFIG_SMP) += smp.o --obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o -+ifneq ($(CONFIG_FSL_CORENET_RCPM),y) -+obj-$(CONFIG_SMP) += mpc85xx_pm_ops.o -+endif - - obj-y += common.o - -diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c -index 7c0133f558d02..4a8af80011a6f 100644 ---- a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c -+++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c -@@ -17,6 +17,7 @@ - - static struct ccsr_guts __iomem *guts; - -+#ifdef CONFIG_FSL_PMC - static void mpc85xx_irq_mask(int cpu) - { - -@@ -49,6 +50,7 @@ static void mpc85xx_cpu_up_prepare(int cpu) - { - - } -+#endif - - static void mpc85xx_freeze_time_base(bool freeze) - { -@@ -76,10 +78,12 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = { - - static const struct fsl_pm_ops mpc85xx_pm_ops = { - .freeze_time_base = mpc85xx_freeze_time_base, -+#ifdef CONFIG_FSL_PMC - .irq_mask = mpc85xx_irq_mask, - .irq_unmask = mpc85xx_irq_unmask, - .cpu_die = mpc85xx_cpu_die, - .cpu_up_prepare = mpc85xx_cpu_up_prepare, -+#endif - }; - - int __init mpc85xx_setup_pmc(void) -@@ -94,9 +98,8 @@ int __init mpc85xx_setup_pmc(void) - pr_err("Could not map guts node address\n"); - return -ENOMEM; - } -+ qoriq_pm_ops = &mpc85xx_pm_ops; - } - -- qoriq_pm_ops = &mpc85xx_pm_ops; -- - return 0; - } -diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c -index c6df294054fe9..d7081e9af65c7 100644 ---- a/arch/powerpc/platforms/85xx/smp.c -+++ b/arch/powerpc/platforms/85xx/smp.c -@@ -40,7 +40,6 @@ struct epapr_spin_table { - u32 pir; - }; - --#ifdef CONFIG_HOTPLUG_CPU - static u64 timebase; - static int tb_req; - static int tb_valid; -@@ -112,6 +111,7 @@ static void mpc85xx_take_timebase(void) - local_irq_restore(flags); - } - -+#ifdef CONFIG_HOTPLUG_CPU - static void smp_85xx_cpu_offline_self(void) - { - unsigned int cpu = smp_processor_id(); -@@ -220,7 +220,7 @@ static int smp_85xx_start_cpu(int cpu) - local_irq_save(flags); - hard_irq_disable(); - -- if (qoriq_pm_ops) -+ if (qoriq_pm_ops && qoriq_pm_ops->cpu_up_prepare) - qoriq_pm_ops->cpu_up_prepare(cpu); - - /* if cpu is not spinning, reset it */ -@@ -292,7 +292,7 @@ static int smp_85xx_kick_cpu(int nr) - booting_thread_hwid = cpu_thread_in_core(nr); - primary = cpu_first_thread_sibling(nr); - -- if (qoriq_pm_ops) -+ if (qoriq_pm_ops && qoriq_pm_ops->cpu_up_prepare) - qoriq_pm_ops->cpu_up_prepare(nr); - - /* -@@ -495,21 +495,21 @@ void __init mpc85xx_smp_init(void) - smp_85xx_ops.probe = NULL; - } - --#ifdef CONFIG_HOTPLUG_CPU - #ifdef CONFIG_FSL_CORENET_RCPM -+ /* Assign a value to qoriq_pm_ops on PPC_E500MC */ - fsl_rcpm_init(); --#endif -- --#ifdef CONFIG_FSL_PMC -+#else -+ /* Assign a value to qoriq_pm_ops on !PPC_E500MC */ - mpc85xx_setup_pmc(); - #endif - if (qoriq_pm_ops) { - smp_85xx_ops.give_timebase = mpc85xx_give_timebase; - smp_85xx_ops.take_timebase = mpc85xx_take_timebase; -+#ifdef CONFIG_HOTPLUG_CPU - smp_85xx_ops.cpu_offline_self = smp_85xx_cpu_offline_self; - smp_85xx_ops.cpu_die = qoriq_cpu_kill; -- } - #endif -+ } - smp_ops = &smp_85xx_ops; - - #ifdef CONFIG_KEXEC_CORE -diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c -index 30172e52e16b7..4d82c92ddd523 100644 ---- a/arch/powerpc/platforms/book3s/vas-api.c -+++ b/arch/powerpc/platforms/book3s/vas-api.c -@@ -303,7 +303,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg) - return -EINVAL; - } - -- if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->open_win) { -+ if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->open_win) { - pr_err("VAS API is not registered\n"); - return -EACCES; - } -@@ -373,7 +373,7 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) - return -EINVAL; - } - -- if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->paste_addr) { -+ if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->paste_addr) { - pr_err("%s(): VAS API is not registered\n", __func__); - return -EACCES; - } -diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c -index fa08699aedeb8..d32f24de84798 100644 ---- a/arch/powerpc/platforms/cell/iommu.c -+++ b/arch/powerpc/platforms/cell/iommu.c -@@ -977,6 +977,7 @@ static int __init cell_iommu_fixed_mapping_init(void) - if (hbase < dbase || (hend > (dbase + dsize))) { - pr_debug("iommu: hash window doesn't fit in" - "real DMA window\n"); -+ of_node_put(np); - return -1; - } - } -diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c -index 5b9a7e9f144b3..dff8d5e7ab82b 100644 ---- a/arch/powerpc/platforms/cell/pervasive.c -+++ b/arch/powerpc/platforms/cell/pervasive.c -@@ -78,6 +78,7 @@ static int cbe_system_reset_exception(struct pt_regs *regs) - switch (regs->msr & SRR1_WAKEMASK) { - case SRR1_WAKEDEC: - set_dec(1); -+ break; - case SRR1_WAKEEE: - /* - * Handle these when interrupts get re-enabled and we take -diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c -index 15396333a90bd..a4b020e4b6af0 100644 ---- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c -+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c -@@ -214,6 +214,7 @@ void hlwd_pic_probe(void) - irq_set_chained_handler(cascade_virq, - hlwd_pic_irq_cascade); - hlwd_irq_host = host; -+ of_node_put(np); - break; - } - } -diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c -index f77a59b5c2e1a..df89d916236d9 100644 ---- a/arch/powerpc/platforms/powermac/low_i2c.c -+++ b/arch/powerpc/platforms/powermac/low_i2c.c -@@ -582,6 +582,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host, - bus->close = kw_i2c_close; - bus->xfer = kw_i2c_xfer; - mutex_init(&bus->mutex); -+ lockdep_register_key(&bus->lock_key); - lockdep_set_class(&bus->mutex, &bus->lock_key); - if (controller == busnode) - bus->flags = pmac_i2c_multibus; -@@ -810,6 +811,7 @@ static void __init pmu_i2c_probe(void) - bus->hostdata = bus + 1; - bus->xfer = pmu_i2c_xfer; - mutex_init(&bus->mutex); -+ lockdep_register_key(&bus->lock_key); - lockdep_set_class(&bus->mutex, &bus->lock_key); - bus->flags = pmac_i2c_multibus; - list_add(&bus->link, &pmac_i2c_busses); -@@ -933,6 +935,7 @@ static void __init smu_i2c_probe(void) - bus->hostdata = bus + 1; - bus->xfer = smu_i2c_xfer; - mutex_init(&bus->mutex); -+ lockdep_register_key(&bus->lock_key); - lockdep_set_class(&bus->mutex, &bus->lock_key); - bus->flags = 0; - list_add(&bus->link, &pmac_i2c_busses); -diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c -index 1e5d51db40f84..5390c888db162 100644 ---- a/arch/powerpc/platforms/powernv/opal-lpc.c -+++ b/arch/powerpc/platforms/powernv/opal-lpc.c -@@ -396,6 +396,7 @@ void __init opal_lpc_init(void) - if (!of_get_property(np, "primary", NULL)) - continue; - opal_lpc_chip_id = of_get_ibm_chip_id(np); -+ of_node_put(np); - break; - } - if (opal_lpc_chip_id < 0) -diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c -index a191f4c60ce71..113bdb151f687 100644 ---- a/arch/powerpc/platforms/powernv/opal-prd.c -+++ b/arch/powerpc/platforms/powernv/opal-prd.c -@@ -369,6 +369,12 @@ static struct notifier_block opal_prd_event_nb = { - .priority = 0, - }; - -+static struct notifier_block opal_prd_event_nb2 = { -+ .notifier_call = opal_prd_msg_notifier, -+ .next = NULL, -+ .priority = 0, -+}; -+ - static int opal_prd_probe(struct platform_device *pdev) - { - int rc; -@@ -390,9 +396,10 @@ static int opal_prd_probe(struct platform_device *pdev) - return rc; - } - -- rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb); -+ rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb2); - if (rc) { - pr_err("Couldn't register PRD2 event notifier\n"); -+ opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); - return rc; - } - -@@ -401,6 +408,8 @@ static int opal_prd_probe(struct platform_device *pdev) - pr_err("failed to register miscdev\n"); - opal_message_notifier_unregister(OPAL_MSG_PRD, - &opal_prd_event_nb); -+ opal_message_notifier_unregister(OPAL_MSG_PRD2, -+ &opal_prd_event_nb2); - return rc; - } - -@@ -411,6 +420,7 @@ static int opal_prd_remove(struct platform_device *pdev) - { - misc_deregister(&opal_prd_dev); - opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); -+ opal_message_notifier_unregister(OPAL_MSG_PRD2, &opal_prd_event_nb2); - return 0; - } - -diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c -index a52af8fbf5711..8322ca86d5acf 100644 ---- a/arch/powerpc/platforms/pseries/iommu.c -+++ b/arch/powerpc/platforms/pseries/iommu.c -@@ -1092,15 +1092,6 @@ static phys_addr_t ddw_memory_hotplug_max(void) - phys_addr_t max_addr = memory_hotplug_max(); - struct device_node *memory; - -- /* -- * The "ibm,pmemory" can appear anywhere in the address space. -- * Assuming it is still backed by page structs, set the upper limit -- * for the huge DMA window as MAX_PHYSMEM_BITS. -- */ -- if (of_find_node_by_type(NULL, "ibm,pmemory")) -- return (sizeof(phys_addr_t) * 8 <= MAX_PHYSMEM_BITS) ? -- (phys_addr_t) -1 : (1ULL << MAX_PHYSMEM_BITS); -- - for_each_node_by_type(memory, "memory") { - unsigned long start, size; - int n_mem_addr_cells, n_mem_size_cells, len; -@@ -1365,8 +1356,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) - len = order_base_2(query.largest_available_block << page_shift); - win_name = DMA64_PROPNAME; - } else { -- direct_mapping = true; -- win_name = DIRECT64_PROPNAME; -+ direct_mapping = !default_win_removed || -+ (len == MAX_PHYSMEM_BITS) || -+ (!pmem_present && (len == max_ram_len)); -+ win_name = direct_mapping ? DIRECT64_PROPNAME : DMA64_PROPNAME; - } - - ret = create_ddw(dev, ddw_avail, &create, page_shift, len); -diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c -index e83e0891272d3..210a37a065fb7 100644 ---- a/arch/powerpc/platforms/pseries/mobility.c -+++ b/arch/powerpc/platforms/pseries/mobility.c -@@ -63,6 +63,27 @@ static int mobility_rtas_call(int token, char *buf, s32 scope) - - static int delete_dt_node(struct device_node *dn) - { -+ struct device_node *pdn; -+ bool is_platfac; -+ -+ pdn = of_get_parent(dn); -+ is_platfac = of_node_is_type(dn, "ibm,platform-facilities") || -+ of_node_is_type(pdn, "ibm,platform-facilities"); -+ of_node_put(pdn); -+ -+ /* -+ * The drivers that bind to nodes in the platform-facilities -+ * hierarchy don't support node removal, and the removal directive -+ * from firmware is always followed by an add of an equivalent -+ * node. The capability (e.g. RNG, encryption, compression) -+ * represented by the node is never interrupted by the migration. -+ * So ignore changes to this part of the tree. -+ */ -+ if (is_platfac) { -+ pr_notice("ignoring remove operation for %pOFfp\n", dn); -+ return 0; -+ } -+ - pr_debug("removing node %pOFfp\n", dn); - dlpar_detach_node(dn); - return 0; -@@ -222,6 +243,19 @@ static int add_dt_node(struct device_node *parent_dn, __be32 drc_index) - if (!dn) - return -ENOENT; - -+ /* -+ * Since delete_dt_node() ignores this node type, this is the -+ * necessary counterpart. We also know that a platform-facilities -+ * node returned from dlpar_configure_connector() has children -+ * attached, and dlpar_attach_node() only adds the parent, leaking -+ * the children. So ignore these on the add side for now. -+ */ -+ if (of_node_is_type(dn, "ibm,platform-facilities")) { -+ pr_notice("ignoring add operation for %pOF\n", dn); -+ dlpar_free_cc_nodes(dn); -+ return 0; -+ } -+ - rc = dlpar_attach_node(dn, parent_dn); - if (rc) - dlpar_free_cc_nodes(dn); -diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S -index efeeb1b885a17..329b9c4ae5429 100644 ---- a/arch/powerpc/sysdev/dcr-low.S -+++ b/arch/powerpc/sysdev/dcr-low.S -@@ -11,7 +11,7 @@ - #include - - #define DCR_ACCESS_PROLOG(table) \ -- cmpli cr0,r3,1024; \ -+ cmplwi cr0,r3,1024; \ - rlwinm r3,r3,4,18,27; \ - lis r5,table@h; \ - ori r5,r5,table@l; \ -diff --git a/arch/powerpc/sysdev/xive/Kconfig b/arch/powerpc/sysdev/xive/Kconfig -index 97796c6b63f04..785c292d104b7 100644 ---- a/arch/powerpc/sysdev/xive/Kconfig -+++ b/arch/powerpc/sysdev/xive/Kconfig -@@ -3,7 +3,6 @@ config PPC_XIVE - bool - select PPC_SMP_MUXED_IPI - select HARDIRQS_SW_RESEND -- select IRQ_DOMAIN_NOMAP - - config PPC_XIVE_NATIVE - bool -diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c -index c5d75c02ad8b5..7b69299c29123 100644 ---- a/arch/powerpc/sysdev/xive/common.c -+++ b/arch/powerpc/sysdev/xive/common.c -@@ -1443,8 +1443,7 @@ static const struct irq_domain_ops xive_irq_domain_ops = { - - static void __init xive_init_host(struct device_node *np) - { -- xive_irq_domain = irq_domain_add_nomap(np, XIVE_MAX_IRQ, -- &xive_irq_domain_ops, NULL); -+ xive_irq_domain = irq_domain_add_tree(np, &xive_irq_domain_ops, NULL); - if (WARN_ON(xive_irq_domain == NULL)) - return; - irq_set_default_host(xive_irq_domain); -diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c -index f143b6f111ac0..1179632560b8d 100644 ---- a/arch/powerpc/sysdev/xive/spapr.c -+++ b/arch/powerpc/sysdev/xive/spapr.c -@@ -653,6 +653,9 @@ static int xive_spapr_debug_show(struct seq_file *m, void *private) - struct xive_irq_bitmap *xibm; - char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - -+ if (!buf) -+ return -ENOMEM; -+ - list_for_each_entry(xibm, &xive_irq_bitmaps, list) { - memset(buf, 0, PAGE_SIZE); - bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count); -diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c -index dd8241c009e53..8b28ff9d98d16 100644 ---- a/arch/powerpc/xmon/xmon.c -+++ b/arch/powerpc/xmon/xmon.c -@@ -3264,8 +3264,7 @@ static void show_task(struct task_struct *volatile tsk) - * appropriate for calling from xmon. This could be moved - * to a common, generic, routine used by both. - */ -- state = (p_state == 0) ? 'R' : -- (p_state < 0) ? 'U' : -+ state = (p_state == TASK_RUNNING) ? 'R' : - (p_state & TASK_UNINTERRUPTIBLE) ? 'D' : - (p_state & TASK_STOPPED) ? 'T' : - (p_state & TASK_TRACED) ? 'C' : -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index f076cee11af69..20bc4b8c13b92 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -158,10 +158,9 @@ config PA_BITS - - config PAGE_OFFSET - hex -- default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB -+ default 0xC0000000 if 32BIT - default 0x80000000 if 64BIT && !MMU -- default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB -- default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB -+ default 0xffffffe000000000 if 64BIT - - config KASAN_SHADOW_OFFSET - hex -@@ -270,24 +269,6 @@ config MODULE_SECTIONS - bool - select HAVE_MOD_ARCH_SPECIFIC - --choice -- prompt "Maximum Physical Memory" -- default MAXPHYSMEM_1GB if 32BIT -- default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW -- default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY -- -- config MAXPHYSMEM_1GB -- depends on 32BIT -- bool "1GiB" -- config MAXPHYSMEM_2GB -- depends on 64BIT && CMODEL_MEDLOW -- bool "2GiB" -- config MAXPHYSMEM_128GB -- depends on 64BIT && CMODEL_MEDANY -- bool "128GiB" --endchoice -- -- - config SMP - bool "Symmetric Multi-Processing" - help -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 0eb4568fbd290..e03f45f7711aa 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -52,6 +52,12 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima - riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima - riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd - riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c -+ -+# Newer binutils versions default to ISA spec version 20191213 which moves some -+# instructions from the I extension to the Zicsr and Zifencei extensions. -+toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei) -+riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei -+ - KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) - KBUILD_AFLAGS += -march=$(riscv-march-y) - -@@ -108,11 +114,13 @@ PHONY += vdso_install - vdso_install: - $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ - -+ifeq ($(KBUILD_EXTMOD),) - ifeq ($(CONFIG_MMU),y) - prepare: vdso_prepare - vdso_prepare: prepare0 - $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h - endif -+endif - - ifneq ($(CONFIG_XIP_KERNEL),y) - ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy) -diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts -index b254c60589a1c..cce5eca31f257 100644 ---- a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts -+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts -@@ -12,7 +12,7 @@ - #address-cells = <2>; - #size-cells = <2>; - model = "Microchip PolarFire-SoC Icicle Kit"; -- compatible = "microchip,mpfs-icicle-kit"; -+ compatible = "microchip,mpfs-icicle-kit", "microchip,mpfs"; - - aliases { - ethernet0 = &emac1; -@@ -56,8 +56,17 @@ - status = "okay"; - }; - --&sdcard { -+&mmc { - status = "okay"; -+ -+ bus-width = <4>; -+ disable-wp; -+ cap-sd-highspeed; -+ card-detect-delay = <200>; -+ sd-uhs-sdr12; -+ sd-uhs-sdr25; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; - }; - - &emac0 { -diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi -index 9d2fbbc1f7778..4ef4bcb748729 100644 ---- a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi -+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi -@@ -6,11 +6,8 @@ - / { - #address-cells = <2>; - #size-cells = <2>; -- model = "Microchip MPFS Icicle Kit"; -- compatible = "microchip,mpfs-icicle-kit"; -- -- chosen { -- }; -+ model = "Microchip PolarFire SoC"; -+ compatible = "microchip,mpfs"; - - cpus { - #address-cells = <1>; -@@ -262,39 +259,14 @@ - status = "disabled"; - }; - -- emmc: mmc@20008000 { -+ /* Common node entry for emmc/sd */ -+ mmc: mmc@20008000 { - compatible = "cdns,sd4hc"; - reg = <0x0 0x20008000 0x0 0x1000>; - interrupt-parent = <&plic>; - interrupts = <88 89>; - pinctrl-names = "default"; - clocks = <&clkcfg 6>; -- bus-width = <4>; -- cap-mmc-highspeed; -- mmc-ddr-3_3v; -- max-frequency = <200000000>; -- non-removable; -- no-sd; -- no-sdio; -- voltage-ranges = <3300 3300>; -- status = "disabled"; -- }; -- -- sdcard: sdhc@20008000 { -- compatible = "cdns,sd4hc"; -- reg = <0x0 0x20008000 0x0 0x1000>; -- interrupt-parent = <&plic>; -- interrupts = <88>; -- pinctrl-names = "default"; -- clocks = <&clkcfg 6>; -- bus-width = <4>; -- disable-wp; -- cap-sd-highspeed; -- card-detect-delay = <200>; -- sd-uhs-sdr12; -- sd-uhs-sdr25; -- sd-uhs-sdr50; -- sd-uhs-sdr104; - max-frequency = <200000000>; - status = "disabled"; - }; -diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts -index 60846e88ae4b1..22f971e971614 100644 ---- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts -+++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts -@@ -80,6 +80,7 @@ - spi-max-frequency = <20000000>; - voltage-ranges = <3300 3300>; - disable-wp; -+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>; - }; - }; - -diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -index 2e4ea84f27e77..b40990210fb50 100644 ---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -@@ -2,6 +2,7 @@ - /* Copyright (c) 2020 SiFive, Inc */ - - #include "fu740-c000.dtsi" -+#include - #include - - /* Clock frequency (in Hz) of the PCB crystal for rtcclk */ -@@ -228,6 +229,7 @@ - spi-max-frequency = <20000000>; - voltage-ranges = <3300 3300>; - disable-wp; -+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>; - }; - }; - -diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig -index b16a2a12c82a8..3b9f83221f9c2 100644 ---- a/arch/riscv/configs/nommu_k210_defconfig -+++ b/arch/riscv/configs/nommu_k210_defconfig -@@ -29,8 +29,6 @@ CONFIG_EMBEDDED=y - CONFIG_SLOB=y - # CONFIG_MMU is not set - CONFIG_SOC_CANAAN=y --CONFIG_SOC_CANAAN_K210_DTB_SOURCE="k210_generic" --CONFIG_MAXPHYSMEM_2GB=y - CONFIG_SMP=y - CONFIG_NR_CPUS=2 - CONFIG_CMDLINE="earlycon console=ttySIF0" -diff --git a/arch/riscv/configs/nommu_k210_sdcard_defconfig b/arch/riscv/configs/nommu_k210_sdcard_defconfig -index 61f887f654199..15d1fd0a70184 100644 ---- a/arch/riscv/configs/nommu_k210_sdcard_defconfig -+++ b/arch/riscv/configs/nommu_k210_sdcard_defconfig -@@ -21,11 +21,9 @@ CONFIG_EMBEDDED=y - CONFIG_SLOB=y - # CONFIG_MMU is not set - CONFIG_SOC_CANAAN=y --CONFIG_SOC_CANAAN_K210_DTB_SOURCE="k210_generic" --CONFIG_MAXPHYSMEM_2GB=y - CONFIG_SMP=y - CONFIG_NR_CPUS=2 --CONFIG_CMDLINE="earlycon console=ttySIF0 rootdelay=2 root=/dev/mmcblk0p1 ro" -+CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro" - CONFIG_CMDLINE_FORCE=y - # CONFIG_SECCOMP is not set - # CONFIG_STACKPROTECTOR is not set -diff --git a/arch/riscv/configs/nommu_virt_defconfig b/arch/riscv/configs/nommu_virt_defconfig -index e046a0babde43..f224be697785f 100644 ---- a/arch/riscv/configs/nommu_virt_defconfig -+++ b/arch/riscv/configs/nommu_virt_defconfig -@@ -27,7 +27,6 @@ CONFIG_SLOB=y - # CONFIG_SLAB_MERGE_DEFAULT is not set - # CONFIG_MMU is not set - CONFIG_SOC_VIRT=y --CONFIG_MAXPHYSMEM_2GB=y - CONFIG_SMP=y - CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0" - CONFIG_CMDLINE_FORCE=y -diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h -index 49b398fe99f1b..cc4f6787f9371 100644 ---- a/arch/riscv/include/asm/efi.h -+++ b/arch/riscv/include/asm/efi.h -@@ -13,7 +13,6 @@ - - #ifdef CONFIG_EFI - extern void efi_init(void); --extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt); - #else - #define efi_init() - #endif -diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h -index a7d2811f35365..62d0e6e61da83 100644 ---- a/arch/riscv/include/asm/smp.h -+++ b/arch/riscv/include/asm/smp.h -@@ -43,7 +43,6 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask); - void arch_send_call_function_single_ipi(int cpu); - - int riscv_hartid_to_cpuid(int hartid); --void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); - - /* Set custom IPI operations */ - void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops); -@@ -85,13 +84,6 @@ static inline unsigned long cpuid_to_hartid_map(int cpu) - return boot_cpu_hartid; - } - --static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in, -- struct cpumask *out) --{ -- cpumask_clear(out); -- cpumask_set_cpu(boot_cpu_hartid, out); --} -- - static inline void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops) - { - } -@@ -102,6 +94,8 @@ static inline void riscv_clear_ipi(void) - - #endif /* CONFIG_SMP */ - -+void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); -+ - #if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP) - bool cpu_has_hotplug(unsigned int cpu); - #else -diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile -index 3397ddac1a30c..16308ef1e5787 100644 ---- a/arch/riscv/kernel/Makefile -+++ b/arch/riscv/kernel/Makefile -@@ -50,6 +50,8 @@ obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o - obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o - obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o - -+obj-$(CONFIG_TRACE_IRQFLAGS) += trace_irq.o -+ - obj-$(CONFIG_RISCV_BASE_PMU) += perf_event.o - obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o - obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o -diff --git a/arch/riscv/kernel/cpu-hotplug.c b/arch/riscv/kernel/cpu-hotplug.c -index df84e0c13db18..66ddfba1cfbef 100644 ---- a/arch/riscv/kernel/cpu-hotplug.c -+++ b/arch/riscv/kernel/cpu-hotplug.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - - void cpu_stop(void); -@@ -46,6 +47,7 @@ int __cpu_disable(void) - return ret; - - remove_cpu_topology(cpu); -+ numa_remove_cpu(cpu); - set_cpu_online(cpu, false); - irq_migrate_all_off_this_cpu(); - -diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S -index 98f502654edd3..7e52ad5d61adb 100644 ---- a/arch/riscv/kernel/entry.S -+++ b/arch/riscv/kernel/entry.S -@@ -108,7 +108,7 @@ _save_context: - .option pop - - #ifdef CONFIG_TRACE_IRQFLAGS -- call trace_hardirqs_off -+ call __trace_hardirqs_off - #endif - - #ifdef CONFIG_CONTEXT_TRACKING -@@ -144,7 +144,7 @@ skip_context_tracking: - li t0, EXC_BREAKPOINT - beq s4, t0, 1f - #ifdef CONFIG_TRACE_IRQFLAGS -- call trace_hardirqs_on -+ call __trace_hardirqs_on - #endif - csrs CSR_STATUS, SR_IE - -@@ -235,7 +235,7 @@ ret_from_exception: - REG_L s0, PT_STATUS(sp) - csrc CSR_STATUS, SR_IE - #ifdef CONFIG_TRACE_IRQFLAGS -- call trace_hardirqs_off -+ call __trace_hardirqs_off - #endif - #ifdef CONFIG_RISCV_M_MODE - /* the MPP value is too large to be used as an immediate arg for addi */ -@@ -271,10 +271,10 @@ restore_all: - REG_L s1, PT_STATUS(sp) - andi t0, s1, SR_PIE - beqz t0, 1f -- call trace_hardirqs_on -+ call __trace_hardirqs_on - j 2f - 1: -- call trace_hardirqs_off -+ call __trace_hardirqs_off - 2: - #endif - REG_L a0, PT_STATUS(sp) -diff --git a/arch/riscv/kernel/kexec_relocate.S b/arch/riscv/kernel/kexec_relocate.S -index a80b52a74f58c..059c5e216ae75 100644 ---- a/arch/riscv/kernel/kexec_relocate.S -+++ b/arch/riscv/kernel/kexec_relocate.S -@@ -159,25 +159,15 @@ SYM_CODE_START(riscv_kexec_norelocate) - * s0: (const) Phys address to jump to - * s1: (const) Phys address of the FDT image - * s2: (const) The hartid of the current hart -- * s3: (const) kernel_map.va_pa_offset, used when switching MMU off - */ - mv s0, a1 - mv s1, a2 - mv s2, a3 -- mv s3, a4 - - /* Disable / cleanup interrupts */ - csrw CSR_SIE, zero - csrw CSR_SIP, zero - -- /* Switch to physical addressing */ -- la s4, 1f -- sub s4, s4, s3 -- csrw CSR_STVEC, s4 -- csrw CSR_SATP, zero -- --.align 2 --1: - /* Pass the arguments to the next kernel / Cleanup*/ - mv a0, s2 - mv a1, s1 -@@ -214,7 +204,15 @@ SYM_CODE_START(riscv_kexec_norelocate) - csrw CSR_SCAUSE, zero - csrw CSR_SSCRATCH, zero - -- jalr zero, a2, 0 -+ /* -+ * Switch to physical addressing -+ * This will also trigger a jump to CSR_STVEC -+ * which in this case is the address of the new -+ * kernel. -+ */ -+ csrw CSR_STVEC, a2 -+ csrw CSR_SATP, zero -+ - SYM_CODE_END(riscv_kexec_norelocate) - - .section ".rodata" -diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c -index e6eca271a4d60..cbef0fc73afa8 100644 ---- a/arch/riscv/kernel/machine_kexec.c -+++ b/arch/riscv/kernel/machine_kexec.c -@@ -169,7 +169,8 @@ machine_kexec(struct kimage *image) - struct kimage_arch *internal = &image->arch; - unsigned long jump_addr = (unsigned long) image->start; - unsigned long first_ind_entry = (unsigned long) &image->head; -- unsigned long this_hart_id = raw_smp_processor_id(); -+ unsigned long this_cpu_id = smp_processor_id(); -+ unsigned long this_hart_id = cpuid_to_hartid_map(this_cpu_id); - unsigned long fdt_addr = internal->fdt_addr; - void *control_code_buffer = page_address(image->control_code_page); - riscv_kexec_method kexec_method = NULL; -diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c -index 0bb1854dce833..8ecfc4c128bc5 100644 ---- a/arch/riscv/kernel/perf_callchain.c -+++ b/arch/riscv/kernel/perf_callchain.c -@@ -56,10 +56,11 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry, - void perf_callchain_user(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - unsigned long fp = 0; - - /* RISC-V does not support perf in guest mode. */ -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) -+ if (guest_cbs && guest_cbs->is_in_guest()) - return; - - fp = regs->s0; -@@ -78,8 +79,10 @@ static bool fill_callchain(void *entry, unsigned long pc) - void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); -+ - /* RISC-V does not support perf in guest mode. */ -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - pr_warn("RISC-V does not support perf in guest mode!"); - return; - } -diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c -index b9620e5f00baf..6c5caf5eb9061 100644 ---- a/arch/riscv/kernel/setup.c -+++ b/arch/riscv/kernel/setup.c -@@ -59,6 +59,16 @@ atomic_t hart_lottery __section(".sdata") - unsigned long boot_cpu_hartid; - static DEFINE_PER_CPU(struct cpu, cpu_devices); - -+void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) -+{ -+ int cpu; -+ -+ cpumask_clear(out); -+ for_each_cpu(cpu, in) -+ cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); -+} -+EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); -+ - /* - * Place kernel memory regions on the resource tree so that - * kexec-tools can retrieve them from /proc/iomem. While there -diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c -index 921d9d7df4001..d0147294691d9 100644 ---- a/arch/riscv/kernel/smp.c -+++ b/arch/riscv/kernel/smp.c -@@ -59,16 +59,6 @@ int riscv_hartid_to_cpuid(int hartid) - return -ENOENT; - } - --void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) --{ -- int cpu; -- -- cpumask_clear(out); -- for_each_cpu(cpu, in) -- cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); --} --EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); -- - bool arch_match_cpu_phys_id(int cpu, u64 phys_id) - { - return phys_id == cpuid_to_hartid_map(cpu); -diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c -index 315db3d0229bf..c2601150b91c8 100644 ---- a/arch/riscv/kernel/stacktrace.c -+++ b/arch/riscv/kernel/stacktrace.c -@@ -22,15 +22,16 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, - bool (*fn)(void *, unsigned long), void *arg) - { - unsigned long fp, sp, pc; -+ int level = 0; - - if (regs) { - fp = frame_pointer(regs); - sp = user_stack_pointer(regs); - pc = instruction_pointer(regs); - } else if (task == NULL || task == current) { -- fp = (unsigned long)__builtin_frame_address(1); -- sp = (unsigned long)__builtin_frame_address(0); -- pc = (unsigned long)__builtin_return_address(0); -+ fp = (unsigned long)__builtin_frame_address(0); -+ sp = sp_in_global; -+ pc = (unsigned long)walk_stackframe; - } else { - /* task blocked in __switch_to */ - fp = task->thread.s[0]; -@@ -42,7 +43,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, - unsigned long low, high; - struct stackframe *frame; - -- if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc))) -+ if (unlikely(!__kernel_text_address(pc) || (level++ >= 1 && !fn(arg, pc)))) - break; - - /* Validate frame pointer */ -diff --git a/arch/riscv/kernel/trace_irq.c b/arch/riscv/kernel/trace_irq.c -new file mode 100644 -index 0000000000000..095ac976d7da1 ---- /dev/null -+++ b/arch/riscv/kernel/trace_irq.c -@@ -0,0 +1,27 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2022 Changbin Du -+ */ -+ -+#include -+#include -+#include "trace_irq.h" -+ -+/* -+ * trace_hardirqs_on/off require the caller to setup frame pointer properly. -+ * Otherwise, CALLER_ADDR1 might trigger an pagging exception in kernel. -+ * Here we add one extra level so they can be safely called by low -+ * level entry code which $fp is used for other purpose. -+ */ -+ -+void __trace_hardirqs_on(void) -+{ -+ trace_hardirqs_on(); -+} -+NOKPROBE_SYMBOL(__trace_hardirqs_on); -+ -+void __trace_hardirqs_off(void) -+{ -+ trace_hardirqs_off(); -+} -+NOKPROBE_SYMBOL(__trace_hardirqs_off); -diff --git a/arch/riscv/kernel/trace_irq.h b/arch/riscv/kernel/trace_irq.h -new file mode 100644 -index 0000000000000..99fe67377e5ed ---- /dev/null -+++ b/arch/riscv/kernel/trace_irq.h -@@ -0,0 +1,11 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2022 Changbin Du -+ */ -+#ifndef __TRACE_IRQ_H -+#define __TRACE_IRQ_H -+ -+void __trace_hardirqs_on(void); -+void __trace_hardirqs_off(void); -+ -+#endif /* __TRACE_IRQ_H */ -diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile -index 7ebaef10ea1b6..ac7a25298a04a 100644 ---- a/arch/riscv/mm/Makefile -+++ b/arch/riscv/mm/Makefile -@@ -24,6 +24,9 @@ obj-$(CONFIG_KASAN) += kasan_init.o - ifdef CONFIG_KASAN - KASAN_SANITIZE_kasan_init.o := n - KASAN_SANITIZE_init.o := n -+ifdef CONFIG_DEBUG_VIRTUAL -+KASAN_SANITIZE_physaddr.o := n -+endif - endif - - obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o -diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c -index c0cddf0fc22db..3de593b26850e 100644 ---- a/arch/riscv/mm/init.c -+++ b/arch/riscv/mm/init.c -@@ -187,10 +187,10 @@ static void __init setup_bootmem(void) - - - phys_ram_end = memblock_end_of_DRAM(); --#ifndef CONFIG_64BIT - #ifndef CONFIG_XIP_KERNEL - phys_ram_base = memblock_start_of_DRAM(); - #endif -+#ifndef CONFIG_64BIT - /* - * memblock allocator is not aware of the fact that last 4K bytes of - * the addressable memory can not be mapped because of IS_ERR_VALUE -@@ -451,6 +451,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) - } - - #ifdef CONFIG_XIP_KERNEL -+#define phys_ram_base (*(phys_addr_t *)XIP_FIXUP(&phys_ram_base)) - /* called from head.S with MMU off */ - asmlinkage void __init __copy_data(void) - { -@@ -813,13 +814,22 @@ static void __init reserve_crashkernel(void) - /* - * Current riscv boot protocol requires 2MB alignment for - * RV64 and 4MB alignment for RV32 (hugepage size) -+ * -+ * Try to alloc from 32bit addressible physical memory so that -+ * swiotlb can work on the crash kernel. - */ - crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, -- search_start, search_end); -+ search_start, -+ min(search_end, (unsigned long) SZ_4G)); - if (crash_base == 0) { -- pr_warn("crashkernel: couldn't allocate %lldKB\n", -- crash_size >> 10); -- return; -+ /* Try again without restricting region to 32bit addressible memory */ -+ crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, -+ search_start, search_end); -+ if (crash_base == 0) { -+ pr_warn("crashkernel: couldn't allocate %lldKB\n", -+ crash_size >> 10); -+ return; -+ } - } - - pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n", -diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c -index 54294f83513d1..e26e367a3d9ef 100644 ---- a/arch/riscv/mm/kasan_init.c -+++ b/arch/riscv/mm/kasan_init.c -@@ -22,8 +22,7 @@ asmlinkage void __init kasan_early_init(void) - - for (i = 0; i < PTRS_PER_PTE; ++i) - set_pte(kasan_early_shadow_pte + i, -- mk_pte(virt_to_page(kasan_early_shadow_page), -- PAGE_KERNEL)); -+ pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL)); - - for (i = 0; i < PTRS_PER_PMD; ++i) - set_pmd(kasan_early_shadow_pmd + i, -diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig -index b86de61b8caa2..797041b5109a2 100644 ---- a/arch/s390/Kconfig -+++ b/arch/s390/Kconfig -@@ -47,7 +47,7 @@ config ARCH_SUPPORTS_UPROBES - config KASAN_SHADOW_OFFSET - hex - depends on KASAN -- default 0x18000000000000 -+ default 0x1C000000000000 - - config S390 - def_bool y -diff --git a/arch/s390/Makefile b/arch/s390/Makefile -index 450b351dfa8ef..d4fd1426a8226 100644 ---- a/arch/s390/Makefile -+++ b/arch/s390/Makefile -@@ -79,10 +79,12 @@ KBUILD_AFLAGS_DECOMPRESSOR += $(aflags-y) - KBUILD_CFLAGS_DECOMPRESSOR += $(cflags-y) - - ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),) --cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE) --ifeq ($(call cc-option,-mstack-size=8192),) --cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD) --endif -+ CC_FLAGS_CHECK_STACK := -mstack-size=$(STACK_SIZE) -+ ifeq ($(call cc-option,-mstack-size=8192),) -+ CC_FLAGS_CHECK_STACK += -mstack-guard=$(CONFIG_STACK_GUARD) -+ endif -+ export CC_FLAGS_CHECK_STACK -+ cflags-$(CONFIG_CHECK_STACK) += $(CC_FLAGS_CHECK_STACK) - endif - - ifdef CONFIG_EXPOLINE -diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c -index 6dc8d0a538640..b13352dd1e1cf 100644 ---- a/arch/s390/boot/startup.c -+++ b/arch/s390/boot/startup.c -@@ -148,82 +148,56 @@ static void setup_ident_map_size(unsigned long max_physmem_end) - - static void setup_kernel_memory_layout(void) - { -- bool vmalloc_size_verified = false; -- unsigned long vmemmap_off; -- unsigned long vspace_left; -+ unsigned long vmemmap_start; - unsigned long rte_size; - unsigned long pages; -- unsigned long vmax; - - pages = ident_map_size / PAGE_SIZE; - /* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */ - vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page); - - /* choose kernel address space layout: 4 or 3 levels. */ -- vmemmap_off = round_up(ident_map_size, _REGION3_SIZE); -+ vmemmap_start = round_up(ident_map_size, _REGION3_SIZE); - if (IS_ENABLED(CONFIG_KASAN) || - vmalloc_size > _REGION2_SIZE || -- vmemmap_off + vmemmap_size + vmalloc_size + MODULES_LEN > _REGION2_SIZE) -- vmax = _REGION1_SIZE; -- else -- vmax = _REGION2_SIZE; -- -- /* keep vmemmap_off aligned to a top level region table entry */ -- rte_size = vmax == _REGION1_SIZE ? _REGION2_SIZE : _REGION3_SIZE; -- MODULES_END = vmax; -- if (is_prot_virt_host()) { -- /* -- * forcing modules and vmalloc area under the ultravisor -- * secure storage limit, so that any vmalloc allocation -- * we do could be used to back secure guest storage. -- */ -- adjust_to_uv_max(&MODULES_END); -- } -- --#ifdef CONFIG_KASAN -- if (MODULES_END < vmax) { -- /* force vmalloc and modules below kasan shadow */ -- MODULES_END = min(MODULES_END, KASAN_SHADOW_START); -+ vmemmap_start + vmemmap_size + vmalloc_size + MODULES_LEN > -+ _REGION2_SIZE) { -+ MODULES_END = _REGION1_SIZE; -+ rte_size = _REGION2_SIZE; - } else { -- /* -- * leave vmalloc and modules above kasan shadow but make -- * sure they don't overlap with it -- */ -- vmalloc_size = min(vmalloc_size, vmax - KASAN_SHADOW_END - MODULES_LEN); -- vmalloc_size_verified = true; -- vspace_left = KASAN_SHADOW_START; -+ MODULES_END = _REGION2_SIZE; -+ rte_size = _REGION3_SIZE; - } -+ /* -+ * forcing modules and vmalloc area under the ultravisor -+ * secure storage limit, so that any vmalloc allocation -+ * we do could be used to back secure guest storage. -+ */ -+ adjust_to_uv_max(&MODULES_END); -+#ifdef CONFIG_KASAN -+ /* force vmalloc and modules below kasan shadow */ -+ MODULES_END = min(MODULES_END, KASAN_SHADOW_START); - #endif - MODULES_VADDR = MODULES_END - MODULES_LEN; - VMALLOC_END = MODULES_VADDR; - -- if (vmalloc_size_verified) { -- VMALLOC_START = VMALLOC_END - vmalloc_size; -- } else { -- vmemmap_off = round_up(ident_map_size, rte_size); -- -- if (vmemmap_off + vmemmap_size > VMALLOC_END || -- vmalloc_size > VMALLOC_END - vmemmap_off - vmemmap_size) { -- /* -- * allow vmalloc area to occupy up to 1/2 of -- * the rest virtual space left. -- */ -- vmalloc_size = min(vmalloc_size, VMALLOC_END / 2); -- } -- VMALLOC_START = VMALLOC_END - vmalloc_size; -- vspace_left = VMALLOC_START; -- } -+ /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */ -+ vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE)); -+ VMALLOC_START = VMALLOC_END - vmalloc_size; - -- pages = vspace_left / (PAGE_SIZE + sizeof(struct page)); -+ /* split remaining virtual space between 1:1 mapping & vmemmap array */ -+ pages = VMALLOC_START / (PAGE_SIZE + sizeof(struct page)); - pages = SECTION_ALIGN_UP(pages); -- vmemmap_off = round_up(vspace_left - pages * sizeof(struct page), rte_size); -- /* keep vmemmap left most starting from a fresh region table entry */ -- vmemmap_off = min(vmemmap_off, round_up(ident_map_size, rte_size)); -- /* take care that identity map is lower then vmemmap */ -- ident_map_size = min(ident_map_size, vmemmap_off); -+ /* keep vmemmap_start aligned to a top level region table entry */ -+ vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size); -+ /* vmemmap_start is the future VMEM_MAX_PHYS, make sure it is within MAX_PHYSMEM */ -+ vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS); -+ /* make sure identity map doesn't overlay with vmemmap */ -+ ident_map_size = min(ident_map_size, vmemmap_start); - vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page); -- VMALLOC_START = max(vmemmap_off + vmemmap_size, VMALLOC_START); -- vmemmap = (struct page *)vmemmap_off; -+ /* make sure vmemmap doesn't overlay with vmalloc area */ -+ VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START); -+ vmemmap = (struct page *)vmemmap_start; - } - - /* -diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c -index 33f973ff97442..e8f15dbb89d02 100644 ---- a/arch/s390/hypfs/hypfs_vm.c -+++ b/arch/s390/hypfs/hypfs_vm.c -@@ -20,6 +20,7 @@ - - static char local_guest[] = " "; - static char all_guests[] = "* "; -+static char *all_groups = all_guests; - static char *guest_query; - - struct diag2fc_data { -@@ -62,10 +63,11 @@ static int diag2fc(int size, char* query, void *addr) - - memcpy(parm_list.userid, query, NAME_LEN); - ASCEBC(parm_list.userid, NAME_LEN); -- parm_list.addr = (unsigned long) addr ; -+ memcpy(parm_list.aci_grp, all_groups, NAME_LEN); -+ ASCEBC(parm_list.aci_grp, NAME_LEN); -+ parm_list.addr = (unsigned long)addr; - parm_list.size = size; - parm_list.fmt = 0x02; -- memset(parm_list.aci_grp, 0x40, NAME_LEN); - rc = -1; - - diag_stat_inc(DIAG_STAT_X2FC); -diff --git a/arch/s390/include/asm/extable.h b/arch/s390/include/asm/extable.h -index 16dc57dd90b30..8511f0e59290f 100644 ---- a/arch/s390/include/asm/extable.h -+++ b/arch/s390/include/asm/extable.h -@@ -69,8 +69,13 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a, - { - a->fixup = b->fixup + delta; - b->fixup = tmp.fixup - delta; -- a->handler = b->handler + delta; -- b->handler = tmp.handler - delta; -+ a->handler = b->handler; -+ if (a->handler) -+ a->handler += delta; -+ b->handler = tmp.handler; -+ if (b->handler) -+ b->handler -= delta; - } -+#define swap_ex_entry_fixup swap_ex_entry_fixup - - #endif -diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h -index ea398a05f6432..7f3c9ac34bd8d 100644 ---- a/arch/s390/include/asm/kexec.h -+++ b/arch/s390/include/asm/kexec.h -@@ -74,6 +74,12 @@ void *kexec_file_add_components(struct kimage *image, - int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, - unsigned long addr); - -+#define ARCH_HAS_KIMAGE_ARCH -+ -+struct kimage_arch { -+ void *ipl_buf; -+}; -+ - extern const struct kexec_file_ops s390_kexec_image_ops; - extern const struct kexec_file_ops s390_kexec_elf_ops; - -diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h -index e4dc64cc9c555..287bb88f76986 100644 ---- a/arch/s390/include/asm/pci_io.h -+++ b/arch/s390/include/asm/pci_io.h -@@ -14,12 +14,13 @@ - - /* I/O Map */ - #define ZPCI_IOMAP_SHIFT 48 --#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL -+#define ZPCI_IOMAP_ADDR_SHIFT 62 -+#define ZPCI_IOMAP_ADDR_BASE (1UL << ZPCI_IOMAP_ADDR_SHIFT) - #define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) - #define ZPCI_IOMAP_MAX_ENTRIES \ -- ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) -+ (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT)) - #define ZPCI_IOMAP_ADDR_IDX_MASK \ -- (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE) -+ ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK) - - struct zpci_iomap_entry { - u32 fh; -diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c -index d72a6df058d79..785d54c9350c4 100644 ---- a/arch/s390/kernel/crash_dump.c -+++ b/arch/s390/kernel/crash_dump.c -@@ -191,8 +191,8 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count) - return rc; - } else { - /* Check for swapped kdump oldmem areas */ -- if (oldmem_data.start && from - oldmem_data.size < oldmem_data.size) { -- from -= oldmem_data.size; -+ if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) { -+ from -= oldmem_data.start; - len = min(count, oldmem_data.size - from); - } else if (oldmem_data.start && from < oldmem_data.size) { - len = min(count, oldmem_data.size - from); -diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c -index e2cc35775b996..5ad1dde23dc59 100644 ---- a/arch/s390/kernel/ipl.c -+++ b/arch/s390/kernel/ipl.c -@@ -2156,7 +2156,7 @@ void *ipl_report_finish(struct ipl_report *report) - - buf = vzalloc(report->size); - if (!buf) -- return ERR_PTR(-ENOMEM); -+ goto out; - ptr = buf; - - memcpy(ptr, report->ipib, report->ipib->hdr.len); -@@ -2195,6 +2195,7 @@ void *ipl_report_finish(struct ipl_report *report) - } - - BUG_ON(ptr > buf + report->size); -+out: - return buf; - } - -diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c -index 3a3145c4a3ba4..be5d432b902e0 100644 ---- a/arch/s390/kernel/irq.c -+++ b/arch/s390/kernel/irq.c -@@ -138,7 +138,7 @@ void noinstr do_io_irq(struct pt_regs *regs) - struct pt_regs *old_regs = set_irq_regs(regs); - int from_idle; - -- irq_enter(); -+ irq_enter_rcu(); - - if (user_mode(regs)) - update_timer_sys(); -@@ -155,7 +155,8 @@ void noinstr do_io_irq(struct pt_regs *regs) - do_irq_async(regs, IO_INTERRUPT); - } while (MACHINE_IS_LPAR && irq_pending(regs)); - -- irq_exit(); -+ irq_exit_rcu(); -+ - set_irq_regs(old_regs); - irqentry_exit(regs, state); - -@@ -169,7 +170,7 @@ void noinstr do_ext_irq(struct pt_regs *regs) - struct pt_regs *old_regs = set_irq_regs(regs); - int from_idle; - -- irq_enter(); -+ irq_enter_rcu(); - - if (user_mode(regs)) - update_timer_sys(); -@@ -184,7 +185,7 @@ void noinstr do_ext_irq(struct pt_regs *regs) - - do_irq_async(regs, EXT_INTERRUPT); - -- irq_exit(); -+ irq_exit_rcu(); - set_irq_regs(old_regs); - irqentry_exit(regs, state); - -diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c -index f9e4baa64b675..a81d6c43b9b61 100644 ---- a/arch/s390/kernel/machine_kexec_file.c -+++ b/arch/s390/kernel/machine_kexec_file.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -170,6 +171,7 @@ static int kexec_file_add_ipl_report(struct kimage *image, - struct kexec_buf buf; - unsigned long addr; - void *ptr, *end; -+ int ret; - - buf.image = image; - -@@ -199,9 +201,13 @@ static int kexec_file_add_ipl_report(struct kimage *image, - ptr += len; - } - -+ ret = -ENOMEM; - buf.buffer = ipl_report_finish(data->report); -+ if (!buf.buffer) -+ goto out; - buf.bufsz = data->report->size; - buf.memsz = buf.bufsz; -+ image->arch.ipl_buf = buf.buffer; - - data->memsz += buf.memsz; - -@@ -209,7 +215,9 @@ static int kexec_file_add_ipl_report(struct kimage *image, - data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr); - *lc_ipl_parmblock_ptr = (__u32)buf.mem; - -- return kexec_add_buffer(&buf); -+ ret = kexec_add_buffer(&buf); -+out: -+ return ret; - } - - void *kexec_file_add_components(struct kimage *image, -@@ -269,6 +277,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, - { - Elf_Rela *relas; - int i, r_type; -+ int ret; - - relas = (void *)pi->ehdr + relsec->sh_offset; - -@@ -303,7 +312,15 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, - addr = section->sh_addr + relas[i].r_offset; - - r_type = ELF64_R_TYPE(relas[i].r_info); -- arch_kexec_do_relocs(r_type, loc, val, addr); -+ -+ if (r_type == R_390_PLT32DBL) -+ r_type = R_390_PC32DBL; -+ -+ ret = arch_kexec_do_relocs(r_type, loc, val, addr); -+ if (ret) { -+ pr_err("Unknown rela relocation: %d\n", r_type); -+ return -ENOEXEC; -+ } - } - return 0; - } -@@ -321,3 +338,11 @@ int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, - - return kexec_image_probe_default(image, buf, buf_len); - } -+ -+int arch_kimage_file_post_load_cleanup(struct kimage *image) -+{ -+ vfree(image->arch.ipl_buf); -+ image->arch.ipl_buf = NULL; -+ -+ return kexec_image_post_load_cleanup_default(image); -+} -diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c -index b01ba460b7cad..b032e556eeb71 100644 ---- a/arch/s390/kernel/module.c -+++ b/arch/s390/kernel/module.c -@@ -33,18 +33,19 @@ - #define DEBUGP(fmt , ...) - #endif - --#define PLT_ENTRY_SIZE 20 -+#define PLT_ENTRY_SIZE 22 - - void *module_alloc(unsigned long size) - { -+ gfp_t gfp_mask = GFP_KERNEL; - void *p; - - if (PAGE_ALIGN(size) > MODULES_LEN) - return NULL; - p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END, -- GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE, -+ gfp_mask, PAGE_KERNEL_EXEC, VM_DEFER_KMEMLEAK, NUMA_NO_NODE, - __builtin_return_address(0)); -- if (p && (kasan_module_alloc(p, size) < 0)) { -+ if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) { - vfree(p); - return NULL; - } -@@ -340,27 +341,26 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, - case R_390_PLTOFF32: /* 32 bit offset from GOT to PLT. */ - case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */ - if (info->plt_initialized == 0) { -- unsigned int insn[5]; -- unsigned int *ip = me->core_layout.base + -- me->arch.plt_offset + -- info->plt_offset; -- -- insn[0] = 0x0d10e310; /* basr 1,0 */ -- insn[1] = 0x100a0004; /* lg 1,10(1) */ -+ unsigned char insn[PLT_ENTRY_SIZE]; -+ char *plt_base; -+ char *ip; -+ -+ plt_base = me->core_layout.base + me->arch.plt_offset; -+ ip = plt_base + info->plt_offset; -+ *(int *)insn = 0x0d10e310; /* basr 1,0 */ -+ *(int *)&insn[4] = 0x100c0004; /* lg 1,12(1) */ - if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) { -- unsigned int *ij; -- ij = me->core_layout.base + -- me->arch.plt_offset + -- me->arch.plt_size - PLT_ENTRY_SIZE; -- insn[2] = 0xa7f40000 + /* j __jump_r1 */ -- (unsigned int)(u16) -- (((unsigned long) ij - 8 - -- (unsigned long) ip) / 2); -+ char *jump_r1; -+ -+ jump_r1 = plt_base + me->arch.plt_size - -+ PLT_ENTRY_SIZE; -+ /* brcl 0xf,__jump_r1 */ -+ *(short *)&insn[8] = 0xc0f4; -+ *(int *)&insn[10] = (jump_r1 - (ip + 8)) / 2; - } else { -- insn[2] = 0x07f10000; /* br %r1 */ -+ *(int *)&insn[8] = 0x07f10000; /* br %r1 */ - } -- insn[3] = (unsigned int) (val >> 32); -- insn[4] = (unsigned int) val; -+ *(long *)&insn[14] = val; - - write(ip, insn, sizeof(insn)); - info->plt_initialized = 1; -diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c -index 20f8e1868853f..a50f2ff1b00e8 100644 ---- a/arch/s390/kernel/nmi.c -+++ b/arch/s390/kernel/nmi.c -@@ -273,7 +273,14 @@ static int notrace s390_validate_registers(union mci mci, int umode) - /* Validate vector registers */ - union ctlreg0 cr0; - -- if (!mci.vr) { -+ /* -+ * The vector validity must only be checked if not running a -+ * KVM guest. For KVM guests the machine check is forwarded by -+ * KVM and it is the responsibility of the guest to take -+ * appropriate actions. The host vector or FPU values have been -+ * saved by KVM and will be restored by KVM. -+ */ -+ if (!mci.vr && !test_cpu_flag(CIF_MCCK_GUEST)) { - /* - * Vector registers can't be restored. If the kernel - * currently uses vector registers the system is -@@ -316,11 +323,21 @@ static int notrace s390_validate_registers(union mci mci, int umode) - if (cr2.gse) { - if (!mci.gs) { - /* -- * Guarded storage register can't be restored and -- * the current processes uses guarded storage. -- * It has to be terminated. -+ * 2 cases: -+ * - machine check in kernel or userspace -+ * - machine check while running SIE (KVM guest) -+ * For kernel or userspace the userspace values of -+ * guarded storage control can not be recreated, the -+ * process must be terminated. -+ * For SIE the guest values of guarded storage can not -+ * be recreated. This is either due to a bug or due to -+ * GS being disabled in the guest. The guest will be -+ * notified by KVM code and the guests machine check -+ * handling must take care of this. The host values -+ * are saved by KVM and are not affected. - */ -- kill_task = 1; -+ if (!test_cpu_flag(CIF_MCCK_GUEST)) -+ kill_task = 1; - } else { - load_gs_cb((struct gs_cb *)mcesa->guarded_storage_save_area); - } -diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c -index 4a99154fe6514..cceb8ec707e4b 100644 ---- a/arch/s390/kernel/perf_cpum_cf.c -+++ b/arch/s390/kernel/perf_cpum_cf.c -@@ -687,8 +687,10 @@ static void cpumf_pmu_stop(struct perf_event *event, int flags) - false); - if (cfdiag_diffctr(cpuhw, event->hw.config_base)) - cfdiag_push_sample(event, cpuhw); -- } else -+ } else if (cpuhw->flags & PMU_F_RESERVED) { -+ /* Only update when PMU not hotplugged off */ - hw_perf_event_update(event); -+ } - hwc->state |= PERF_HES_UPTODATE; - } - } -diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c -index 67e5fff96ee06..ee67215a678a5 100644 ---- a/arch/s390/kernel/setup.c -+++ b/arch/s390/kernel/setup.c -@@ -633,14 +633,6 @@ static struct notifier_block kdump_mem_nb = { - - #endif - --/* -- * Make sure that the area above identity mapping is protected -- */ --static void __init reserve_above_ident_map(void) --{ -- memblock_reserve(ident_map_size, ULONG_MAX); --} -- - /* - * Reserve memory for kdump kernel to be loaded with kexec - */ -@@ -824,9 +816,6 @@ static void __init setup_memory(void) - storage_key_init_range(start, end); - - psw_set_key(PAGE_DEFAULT_KEY); -- -- /* Only cosmetics */ -- memblock_enforce_memory_limit(memblock_end_of_DRAM()); - } - - static void __init relocate_amode31_section(void) -@@ -1005,11 +994,11 @@ void __init setup_arch(char **cmdline_p) - setup_control_program_code(); - - /* Do some memory reservations *before* memory is added to memblock */ -- reserve_above_ident_map(); - reserve_kernel(); - reserve_initrd(); - reserve_certificate_list(); - reserve_mem_detect_info(); -+ memblock_set_current_limit(ident_map_size); - memblock_allow_resize(); - - /* Get information about *all* installed memory */ -diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c -index bcefc2173de45..12d28ff5281fa 100644 ---- a/arch/s390/kernel/traps.c -+++ b/arch/s390/kernel/traps.c -@@ -84,7 +84,7 @@ static void default_trap_handler(struct pt_regs *regs) - { - if (user_mode(regs)) { - report_user_fault(regs, SIGSEGV, 0); -- do_exit(SIGSEGV); -+ force_exit_sig(SIGSEGV); - } else - die(regs, "Unknown program exception"); - } -diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c -index 5a656c7b7a67a..f95ccbd396925 100644 ---- a/arch/s390/kernel/uv.c -+++ b/arch/s390/kernel/uv.c -@@ -212,7 +212,7 @@ again: - uaddr = __gmap_translate(gmap, gaddr); - if (IS_ERR_VALUE(uaddr)) - goto out; -- vma = find_vma(gmap->mm, uaddr); -+ vma = vma_lookup(gmap->mm, uaddr); - if (!vma) - goto out; - /* -diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile -index 6568de2367010..0dea82b87e54b 100644 ---- a/arch/s390/kernel/vdso64/Makefile -+++ b/arch/s390/kernel/vdso64/Makefile -@@ -8,8 +8,9 @@ ARCH_REL_TYPE_ABS += R_390_GOT|R_390_PLT - include $(srctree)/lib/vdso/Makefile - obj-vdso64 = vdso_user_wrapper.o note.o - obj-cvdso64 = vdso64_generic.o getcpu.o --CFLAGS_REMOVE_getcpu.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) --CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) -+VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) $(CC_FLAGS_CHECK_STACK) -+CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE) -+CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE) - - # Build rules - -diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c -index 2245f4b8d3629..8ce03a5ca8634 100644 ---- a/arch/s390/kvm/interrupt.c -+++ b/arch/s390/kvm/interrupt.c -@@ -2115,6 +2115,13 @@ int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu) - return test_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs); - } - -+int kvm_s390_is_restart_irq_pending(struct kvm_vcpu *vcpu) -+{ -+ struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -+ -+ return test_bit(IRQ_PEND_RESTART, &li->pending_irqs); -+} -+ - void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu) - { - struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c -index 1c97493d21e10..402597f9d0505 100644 ---- a/arch/s390/kvm/kvm-s390.c -+++ b/arch/s390/kvm/kvm-s390.c -@@ -3447,7 +3447,7 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu) - { - /* do not poll with more than halt_poll_max_steal percent of steal time */ - if (S390_lowcore.avg_steal_timer * 100 / (TICK_USEC << 12) >= -- halt_poll_max_steal) { -+ READ_ONCE(halt_poll_max_steal)) { - vcpu->stat.halt_no_poll_steal++; - return true; - } -@@ -4642,10 +4642,15 @@ int kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu) - } - } - -- /* SIGP STOP and SIGP STOP AND STORE STATUS has been fully processed */ -+ /* -+ * Set the VCPU to STOPPED and THEN clear the interrupt flag, -+ * now that the SIGP STOP and SIGP STOP AND STORE STATUS orders -+ * have been fully processed. This will ensure that the VCPU -+ * is kept BUSY if another VCPU is inquiring with SIGP SENSE. -+ */ -+ kvm_s390_set_cpuflags(vcpu, CPUSTAT_STOPPED); - kvm_s390_clear_stop_irq(vcpu); - -- kvm_s390_set_cpuflags(vcpu, CPUSTAT_STOPPED); - __disable_ibs_on_vcpu(vcpu); - - for (i = 0; i < online_vcpus; i++) { -@@ -4703,6 +4708,8 @@ static long kvm_s390_guest_sida_op(struct kvm_vcpu *vcpu, - return -EINVAL; - if (mop->size + mop->sida_offset > sida_size(vcpu->arch.sie_block)) - return -E2BIG; -+ if (!kvm_s390_pv_cpu_is_protected(vcpu)) -+ return -EINVAL; - - switch (mop->op) { - case KVM_S390_MEMOP_SIDA_READ: -diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h -index 52bc8fbaa60ac..1539dd981104f 100644 ---- a/arch/s390/kvm/kvm-s390.h -+++ b/arch/s390/kvm/kvm-s390.h -@@ -418,6 +418,7 @@ void kvm_s390_destroy_adapters(struct kvm *kvm); - int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu); - extern struct kvm_device_ops kvm_flic_ops; - int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu); -+int kvm_s390_is_restart_irq_pending(struct kvm_vcpu *vcpu); - void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu); - int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, - void __user *buf, int len); -diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c -index 53da4ceb16a3a..417154b314a64 100644 ---- a/arch/s390/kvm/priv.c -+++ b/arch/s390/kvm/priv.c -@@ -397,6 +397,8 @@ static int handle_sske(struct kvm_vcpu *vcpu) - mmap_read_unlock(current->mm); - if (rc == -EFAULT) - return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); -+ if (rc == -EAGAIN) -+ continue; - if (rc < 0) - return rc; - start += PAGE_SIZE; -diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c -index c8841f476e913..00d272d134c24 100644 ---- a/arch/s390/kvm/pv.c -+++ b/arch/s390/kvm/pv.c -@@ -16,18 +16,17 @@ - - int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) - { -- int cc = 0; -+ int cc; - -- if (kvm_s390_pv_cpu_get_handle(vcpu)) { -- cc = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), -- UVC_CMD_DESTROY_SEC_CPU, rc, rrc); -+ if (!kvm_s390_pv_cpu_get_handle(vcpu)) -+ return 0; -+ -+ cc = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), UVC_CMD_DESTROY_SEC_CPU, rc, rrc); -+ -+ KVM_UV_EVENT(vcpu->kvm, 3, "PROTVIRT DESTROY VCPU %d: rc %x rrc %x", -+ vcpu->vcpu_id, *rc, *rrc); -+ WARN_ONCE(cc, "protvirt destroy cpu failed rc %x rrc %x", *rc, *rrc); - -- KVM_UV_EVENT(vcpu->kvm, 3, -- "PROTVIRT DESTROY VCPU %d: rc %x rrc %x", -- vcpu->vcpu_id, *rc, *rrc); -- WARN_ONCE(cc, "protvirt destroy cpu failed rc %x rrc %x", -- *rc, *rrc); -- } - /* Intended memory leak for something that should never happen. */ - if (!cc) - free_pages(vcpu->arch.pv.stor_base, -@@ -196,7 +195,7 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc) - uvcb.conf_base_stor_origin = (u64)kvm->arch.pv.stor_base; - uvcb.conf_virt_stor_origin = (u64)kvm->arch.pv.stor_var; - -- cc = uv_call(0, (u64)&uvcb); -+ cc = uv_call_sched(0, (u64)&uvcb); - *rc = uvcb.header.rc; - *rrc = uvcb.header.rrc; - KVM_UV_EVENT(kvm, 3, "PROTVIRT CREATE VM: handle %llx len %llx rc %x rrc %x", -diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c -index 683036c1c92a8..3dc921e853b6e 100644 ---- a/arch/s390/kvm/sigp.c -+++ b/arch/s390/kvm/sigp.c -@@ -288,6 +288,34 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; - -+ /* -+ * SIGP RESTART, SIGP STOP, and SIGP STOP AND STORE STATUS orders -+ * are processed asynchronously. Until the affected VCPU finishes -+ * its work and calls back into KVM to clear the (RESTART or STOP) -+ * interrupt, we need to return any new non-reset orders "busy". -+ * -+ * This is important because a single VCPU could issue: -+ * 1) SIGP STOP $DESTINATION -+ * 2) SIGP SENSE $DESTINATION -+ * -+ * If the SIGP SENSE would not be rejected as "busy", it could -+ * return an incorrect answer as to whether the VCPU is STOPPED -+ * or OPERATING. -+ */ -+ if (order_code != SIGP_INITIAL_CPU_RESET && -+ order_code != SIGP_CPU_RESET) { -+ /* -+ * Lockless check. Both SIGP STOP and SIGP (RE)START -+ * properly synchronize everything while processing -+ * their orders, while the guest cannot observe a -+ * difference when issuing other orders from two -+ * different VCPUs. -+ */ -+ if (kvm_s390_is_stop_irq_pending(dst_vcpu) || -+ kvm_s390_is_restart_irq_pending(dst_vcpu)) -+ return SIGP_CC_BUSY; -+ } -+ - switch (order_code) { - case SIGP_SENSE: - vcpu->stat.instruction_sigp_sense++; -diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c -index ecf327d743a03..c0635cf787e31 100644 ---- a/arch/s390/lib/test_unwind.c -+++ b/arch/s390/lib/test_unwind.c -@@ -171,10 +171,11 @@ static noinline int unwindme_func4(struct unwindme *u) - } - - /* -- * trigger specification exception -+ * Trigger operation exception; use insn notation to bypass -+ * llvm's integrated assembler sanity checks. - */ - asm volatile( -- " mvcl %%r1,%%r1\n" -+ " .insn e,0x0000\n" /* illegal opcode */ - "0: nopr %%r7\n" - EX_TABLE(0b, 0b) - :); -diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c -index 4d3b33ce81c62..d63c0ccc5ccda 100644 ---- a/arch/s390/mm/gmap.c -+++ b/arch/s390/mm/gmap.c -@@ -672,6 +672,7 @@ EXPORT_SYMBOL_GPL(gmap_fault); - */ - void __gmap_zap(struct gmap *gmap, unsigned long gaddr) - { -+ struct vm_area_struct *vma; - unsigned long vmaddr; - spinlock_t *ptl; - pte_t *ptep; -@@ -681,11 +682,17 @@ void __gmap_zap(struct gmap *gmap, unsigned long gaddr) - gaddr >> PMD_SHIFT); - if (vmaddr) { - vmaddr |= gaddr & ~PMD_MASK; -+ -+ vma = vma_lookup(gmap->mm, vmaddr); -+ if (!vma || is_vm_hugetlb_page(vma)) -+ return; -+ - /* Get pointer to the page table entry */ - ptep = get_locked_pte(gmap->mm, vmaddr, &ptl); -- if (likely(ptep)) -+ if (likely(ptep)) { - ptep_zap_unused(gmap->mm, vmaddr, ptep, 0); -- pte_unmap_unlock(ptep, ptl); -+ pte_unmap_unlock(ptep, ptl); -+ } - } - } - EXPORT_SYMBOL_GPL(__gmap_zap); -diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c -index 781965f7210eb..91e478e09b54b 100644 ---- a/arch/s390/mm/pgalloc.c -+++ b/arch/s390/mm/pgalloc.c -@@ -244,13 +244,15 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) - /* Free 2K page table fragment of a 4K page */ - bit = ((unsigned long) table & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)); - spin_lock_bh(&mm->context.lock); -- mask = atomic_xor_bits(&page->_refcount, 1U << (bit + 24)); -+ mask = atomic_xor_bits(&page->_refcount, 0x11U << (bit + 24)); - mask >>= 24; - if (mask & 3) - list_add(&page->lru, &mm->context.pgtable_list); - else - list_del(&page->lru); - spin_unlock_bh(&mm->context.lock); -+ mask = atomic_xor_bits(&page->_refcount, 0x10U << (bit + 24)); -+ mask >>= 24; - if (mask != 0) - return; - } else { -diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c -index 034721a68d8fd..6ad634a27d5b9 100644 ---- a/arch/s390/mm/pgtable.c -+++ b/arch/s390/mm/pgtable.c -@@ -429,22 +429,36 @@ static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm, - } - - #ifdef CONFIG_PGSTE --static pmd_t *pmd_alloc_map(struct mm_struct *mm, unsigned long addr) -+static int pmd_lookup(struct mm_struct *mm, unsigned long addr, pmd_t **pmdp) - { -+ struct vm_area_struct *vma; - pgd_t *pgd; - p4d_t *p4d; - pud_t *pud; -- pmd_t *pmd; -+ -+ /* We need a valid VMA, otherwise this is clearly a fault. */ -+ vma = vma_lookup(mm, addr); -+ if (!vma) -+ return -EFAULT; - - pgd = pgd_offset(mm, addr); -- p4d = p4d_alloc(mm, pgd, addr); -- if (!p4d) -- return NULL; -- pud = pud_alloc(mm, p4d, addr); -- if (!pud) -- return NULL; -- pmd = pmd_alloc(mm, pud, addr); -- return pmd; -+ if (!pgd_present(*pgd)) -+ return -ENOENT; -+ -+ p4d = p4d_offset(pgd, addr); -+ if (!p4d_present(*p4d)) -+ return -ENOENT; -+ -+ pud = pud_offset(p4d, addr); -+ if (!pud_present(*pud)) -+ return -ENOENT; -+ -+ /* Large PUDs are not supported yet. */ -+ if (pud_large(*pud)) -+ return -EFAULT; -+ -+ *pmdp = pmd_offset(pud, addr); -+ return 0; - } - #endif - -@@ -778,8 +792,7 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp; - pte_t *ptep; - -- pmdp = pmd_alloc_map(mm, addr); -- if (unlikely(!pmdp)) -+ if (pmd_lookup(mm, addr, &pmdp)) - return -EFAULT; - - ptl = pmd_lock(mm, pmdp); -@@ -881,8 +894,7 @@ int reset_guest_reference_bit(struct mm_struct *mm, unsigned long addr) - pte_t *ptep; - int cc = 0; - -- pmdp = pmd_alloc_map(mm, addr); -- if (unlikely(!pmdp)) -+ if (pmd_lookup(mm, addr, &pmdp)) - return -EFAULT; - - ptl = pmd_lock(mm, pmdp); -@@ -935,15 +947,24 @@ int get_guest_storage_key(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp; - pte_t *ptep; - -- pmdp = pmd_alloc_map(mm, addr); -- if (unlikely(!pmdp)) -+ /* -+ * If we don't have a PTE table and if there is no huge page mapped, -+ * the storage key is 0. -+ */ -+ *key = 0; -+ -+ switch (pmd_lookup(mm, addr, &pmdp)) { -+ case -ENOENT: -+ return 0; -+ case 0: -+ break; -+ default: - return -EFAULT; -+ } - - ptl = pmd_lock(mm, pmdp); - if (!pmd_present(*pmdp)) { -- /* Not yet mapped memory has a zero key */ - spin_unlock(ptl); -- *key = 0; - return 0; - } - -@@ -988,6 +1009,7 @@ EXPORT_SYMBOL(get_guest_storage_key); - int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, - unsigned long *oldpte, unsigned long *oldpgste) - { -+ struct vm_area_struct *vma; - unsigned long pgstev; - spinlock_t *ptl; - pgste_t pgste; -@@ -997,6 +1019,10 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, - WARN_ON_ONCE(orc > ESSA_MAX); - if (unlikely(orc > ESSA_MAX)) - return -EINVAL; -+ -+ vma = vma_lookup(mm, hva); -+ if (!vma || is_vm_hugetlb_page(vma)) -+ return -EFAULT; - ptep = get_locked_pte(mm, hva, &ptl); - if (unlikely(!ptep)) - return -EFAULT; -@@ -1089,10 +1115,14 @@ EXPORT_SYMBOL(pgste_perform_essa); - int set_pgste_bits(struct mm_struct *mm, unsigned long hva, - unsigned long bits, unsigned long value) - { -+ struct vm_area_struct *vma; - spinlock_t *ptl; - pgste_t new; - pte_t *ptep; - -+ vma = vma_lookup(mm, hva); -+ if (!vma || is_vm_hugetlb_page(vma)) -+ return -EFAULT; - ptep = get_locked_pte(mm, hva, &ptl); - if (unlikely(!ptep)) - return -EFAULT; -@@ -1117,9 +1147,13 @@ EXPORT_SYMBOL(set_pgste_bits); - */ - int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep) - { -+ struct vm_area_struct *vma; - spinlock_t *ptl; - pte_t *ptep; - -+ vma = vma_lookup(mm, hva); -+ if (!vma || is_vm_hugetlb_page(vma)) -+ return -EFAULT; - ptep = get_locked_pte(mm, hva, &ptl); - if (unlikely(!ptep)) - return -EFAULT; -diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug -index 958f790273ab9..10290e5c1f438 100644 ---- a/arch/sh/Kconfig.debug -+++ b/arch/sh/Kconfig.debug -@@ -54,6 +54,7 @@ config DUMP_CODE - - config DWARF_UNWINDER - bool "Enable the DWARF unwinder for stacktraces" -+ depends on DEBUG_KERNEL - select FRAME_POINTER - default n - help -diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig -index ba887f1351be6..cd5c58916c65a 100644 ---- a/arch/sh/configs/titan_defconfig -+++ b/arch/sh/configs/titan_defconfig -@@ -242,7 +242,6 @@ CONFIG_NFSD=y - CONFIG_NFSD_V3=y - CONFIG_SMB_FS=m - CONFIG_CIFS=m --CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_NLS_CODEPAGE_437=m - CONFIG_NLS_ASCII=m -diff --git a/arch/sh/include/asm/sfp-machine.h b/arch/sh/include/asm/sfp-machine.h -index cbc7cf8c97ce6..2d2423478b71d 100644 ---- a/arch/sh/include/asm/sfp-machine.h -+++ b/arch/sh/include/asm/sfp-machine.h -@@ -13,6 +13,14 @@ - #ifndef _SFP_MACHINE_H - #define _SFP_MACHINE_H - -+#ifdef __BIG_ENDIAN__ -+#define __BYTE_ORDER __BIG_ENDIAN -+#define __LITTLE_ENDIAN 0 -+#else -+#define __BYTE_ORDER __LITTLE_ENDIAN -+#define __BIG_ENDIAN 0 -+#endif -+ - #define _FP_W_TYPE_SIZE 32 - #define _FP_W_TYPE unsigned long - #define _FP_WS_TYPE signed long -diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c -index ae354a2931e7e..fd6db0ab19288 100644 ---- a/arch/sh/kernel/cpu/fpu.c -+++ b/arch/sh/kernel/cpu/fpu.c -@@ -62,18 +62,20 @@ void fpu_state_restore(struct pt_regs *regs) - } - - if (!tsk_used_math(tsk)) { -- local_irq_enable(); -+ int ret; - /* - * does a slab alloc which can sleep - */ -- if (init_fpu(tsk)) { -+ local_irq_enable(); -+ ret = init_fpu(tsk); -+ local_irq_disable(); -+ if (ret) { - /* - * ran out of memory! - */ -- do_group_exit(SIGKILL); -+ force_sig(SIGKILL); - return; - } -- local_irq_disable(); - } - - grab_fpu(regs); -diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c -index f8a2bec0f260b..1261dc7b84e8b 100644 ---- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c -+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c -@@ -73,8 +73,9 @@ static void shx3_prepare_cpus(unsigned int max_cpus) - BUILD_BUG_ON(SMP_MSG_NR >= 8); - - for (i = 0; i < SMP_MSG_NR; i++) -- request_irq(104 + i, ipi_interrupt_handler, -- IRQF_PERCPU, "IPI", (void *)(long)i); -+ if (request_irq(104 + i, ipi_interrupt_handler, -+ IRQF_PERCPU, "IPI", (void *)(long)i)) -+ pr_err("Failed to request irq %d\n", i); - - for (i = 0; i < max_cpus; i++) - set_cpu_present(i, true); -diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c -index e8be0eca0444a..615ba932c398e 100644 ---- a/arch/sh/math-emu/math.c -+++ b/arch/sh/math-emu/math.c -@@ -467,109 +467,6 @@ static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_reg - return id_sys(fregs, regs, code); - } - --/** -- * denormal_to_double - Given denormalized float number, -- * store double float -- * -- * @fpu: Pointer to sh_fpu_soft structure -- * @n: Index to FP register -- */ --static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n) --{ -- unsigned long du, dl; -- unsigned long x = fpu->fpul; -- int exp = 1023 - 126; -- -- if (x != 0 && (x & 0x7f800000) == 0) { -- du = (x & 0x80000000); -- while ((x & 0x00800000) == 0) { -- x <<= 1; -- exp--; -- } -- x &= 0x007fffff; -- du |= (exp << 20) | (x >> 3); -- dl = x << 29; -- -- fpu->fp_regs[n] = du; -- fpu->fp_regs[n+1] = dl; -- } --} -- --/** -- * ieee_fpe_handler - Handle denormalized number exception -- * -- * @regs: Pointer to register structure -- * -- * Returns 1 when it's handled (should not cause exception). -- */ --static int ieee_fpe_handler(struct pt_regs *regs) --{ -- unsigned short insn = *(unsigned short *)regs->pc; -- unsigned short finsn; -- unsigned long nextpc; -- int nib[4] = { -- (insn >> 12) & 0xf, -- (insn >> 8) & 0xf, -- (insn >> 4) & 0xf, -- insn & 0xf}; -- -- if (nib[0] == 0xb || -- (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */ -- regs->pr = regs->pc + 4; -- -- if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */ -- nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3); -- finsn = *(unsigned short *) (regs->pc + 2); -- } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */ -- if (regs->sr & 1) -- nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); -- else -- nextpc = regs->pc + 4; -- finsn = *(unsigned short *) (regs->pc + 2); -- } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */ -- if (regs->sr & 1) -- nextpc = regs->pc + 4; -- else -- nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); -- finsn = *(unsigned short *) (regs->pc + 2); -- } else if (nib[0] == 0x4 && nib[3] == 0xb && -- (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */ -- nextpc = regs->regs[nib[1]]; -- finsn = *(unsigned short *) (regs->pc + 2); -- } else if (nib[0] == 0x0 && nib[3] == 0x3 && -- (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */ -- nextpc = regs->pc + 4 + regs->regs[nib[1]]; -- finsn = *(unsigned short *) (regs->pc + 2); -- } else if (insn == 0x000b) { /* rts */ -- nextpc = regs->pr; -- finsn = *(unsigned short *) (regs->pc + 2); -- } else { -- nextpc = regs->pc + 2; -- finsn = insn; -- } -- -- if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ -- struct task_struct *tsk = current; -- -- if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) { -- /* FPU error */ -- denormal_to_double (&tsk->thread.xstate->softfpu, -- (finsn >> 8) & 0xf); -- tsk->thread.xstate->softfpu.fpscr &= -- ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); -- task_thread_info(tsk)->status |= TS_USEDFPU; -- } else { -- force_sig_fault(SIGFPE, FPE_FLTINV, -- (void __user *)regs->pc); -- } -- -- regs->pc = nextpc; -- return 1; -- } -- -- return 0; --} -- - /** - * fpu_init - Initialize FPU registers - * @fpu: Pointer to software emulated FPU registers. -diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile -index 849236d4eca48..45e5c76d449ea 100644 ---- a/arch/sparc/boot/Makefile -+++ b/arch/sparc/boot/Makefile -@@ -22,7 +22,7 @@ ifeq ($(CONFIG_SPARC64),y) - - # Actual linking - --$(obj)/zImage: $(obj)/image -+$(obj)/zImage: $(obj)/image FORCE - $(call if_changed,gzip) - @echo ' kernel: $@ is ready' - -@@ -31,7 +31,7 @@ $(obj)/vmlinux.aout: vmlinux FORCE - @echo ' kernel: $@ is ready' - else - --$(obj)/zImage: $(obj)/image -+$(obj)/zImage: $(obj)/image FORCE - $(call if_changed,strip) - @echo ' kernel: $@ is ready' - -@@ -44,7 +44,7 @@ OBJCOPYFLAGS_image.bin := -S -O binary -R .note -R .comment - $(obj)/image.bin: $(obj)/image FORCE - $(call if_changed,objcopy) - --$(obj)/image.gz: $(obj)/image.bin -+$(obj)/image.gz: $(obj)/image.bin FORCE - $(call if_changed,gzip) - - UIMAGE_LOADADDR = $(CONFIG_UBOOT_LOAD_ADDR) -@@ -56,7 +56,7 @@ quiet_cmd_uimage.o = UIMAGE.O $@ - -r -b binary $@ -o $@.o - - targets += uImage --$(obj)/uImage: $(obj)/image.gz -+$(obj)/uImage: $(obj)/image.gz FORCE - $(call if_changed,uimage) - $(call if_changed,uimage.o) - @echo ' Image $@ is ready' -diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c -index 02f3ad55dfe31..ffab16369beac 100644 ---- a/arch/sparc/kernel/signal_32.c -+++ b/arch/sparc/kernel/signal_32.c -@@ -244,7 +244,7 @@ static int setup_frame(struct ksignal *ksig, struct pt_regs *regs, - get_sigframe(ksig, regs, sigframe_size); - - if (invalid_frame_pointer(sf, sigframe_size)) { -- do_exit(SIGILL); -+ force_exit_sig(SIGILL); - return -EINVAL; - } - -@@ -336,7 +336,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, - sf = (struct rt_signal_frame __user *) - get_sigframe(ksig, regs, sigframe_size); - if (invalid_frame_pointer(sf, sigframe_size)) { -- do_exit(SIGILL); -+ force_exit_sig(SIGILL); - return -EINVAL; - } - -diff --git a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c -index 69a6ba6e92937..8f20862ccc83e 100644 ---- a/arch/sparc/kernel/windows.c -+++ b/arch/sparc/kernel/windows.c -@@ -121,8 +121,10 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who) - - if ((sp & 7) || - copy_to_user((char __user *) sp, &tp->reg_window[window], -- sizeof(struct reg_window32))) -- do_exit(SIGILL); -+ sizeof(struct reg_window32))) { -+ force_exit_sig(SIGILL); -+ return; -+ } - } - tp->w_saved = 0; - } -diff --git a/arch/um/.gitignore b/arch/um/.gitignore -index 6323e5571887e..d69ea5b562cee 100644 ---- a/arch/um/.gitignore -+++ b/arch/um/.gitignore -@@ -2,3 +2,4 @@ - kernel/config.c - kernel/config.tmp - kernel/vmlinux.lds -+kernel/capflags.c -diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c -index c080666330234..0ab58016db22f 100644 ---- a/arch/um/drivers/virt-pci.c -+++ b/arch/um/drivers/virt-pci.c -@@ -181,15 +181,15 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, - /* buf->data is maximum size - we may only use parts of it */ - struct um_pci_message_buffer *buf; - u8 *data; -- unsigned long ret = ~0ULL; -+ unsigned long ret = ULONG_MAX; - - if (!dev) -- return ~0ULL; -+ return ULONG_MAX; - - buf = get_cpu_var(um_pci_msg_bufs); - data = buf->data; - -- memset(data, 0xff, sizeof(data)); -+ memset(buf->data, 0xff, sizeof(buf->data)); - - switch (size) { - case 1: -@@ -304,7 +304,7 @@ static unsigned long um_pci_bar_read(void *priv, unsigned int offset, - /* buf->data is maximum size - we may only use parts of it */ - struct um_pci_message_buffer *buf; - u8 *data; -- unsigned long ret = ~0ULL; -+ unsigned long ret = ULONG_MAX; - - buf = get_cpu_var(um_pci_msg_bufs); - data = buf->data; -diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c -index d51e445df7976..7755cb4ff9fc6 100644 ---- a/arch/um/drivers/virtio_uml.c -+++ b/arch/um/drivers/virtio_uml.c -@@ -1090,6 +1090,8 @@ static void virtio_uml_release_dev(struct device *d) - container_of(d, struct virtio_device, dev); - struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev); - -+ time_travel_propagate_time(); -+ - /* might not have been opened due to not negotiating the feature */ - if (vu_dev->req_fd >= 0) { - um_free_irq(vu_dev->irq, vu_dev); -@@ -1136,6 +1138,8 @@ static int virtio_uml_probe(struct platform_device *pdev) - vu_dev->pdev = pdev; - vu_dev->req_fd = -1; - -+ time_travel_propagate_time(); -+ - do { - rc = os_connect_socket(pdata->socket_path); - } while (rc == -EINTR); -diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h -index 56fc2b8f2dd01..e79b2ab6f40c8 100644 ---- a/arch/um/include/asm/delay.h -+++ b/arch/um/include/asm/delay.h -@@ -14,7 +14,7 @@ static inline void um_ndelay(unsigned long nsecs) - ndelay(nsecs); - } - #undef ndelay --#define ndelay um_ndelay -+#define ndelay(n) um_ndelay(n) - - static inline void um_udelay(unsigned long usecs) - { -@@ -26,5 +26,5 @@ static inline void um_udelay(unsigned long usecs) - udelay(usecs); - } - #undef udelay --#define udelay um_udelay -+#define udelay(n) um_udelay(n) - #endif /* __UM_DELAY_H */ -diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h -index dab5744e9253d..1e69ef5bc35e0 100644 ---- a/arch/um/include/asm/irqflags.h -+++ b/arch/um/include/asm/irqflags.h -@@ -3,7 +3,7 @@ - #define __UM_IRQFLAGS_H - - extern int signals_enabled; --int set_signals(int enable); -+int um_set_signals(int enable); - void block_signals(void); - void unblock_signals(void); - -@@ -16,7 +16,7 @@ static inline unsigned long arch_local_save_flags(void) - #define arch_local_irq_restore arch_local_irq_restore - static inline void arch_local_irq_restore(unsigned long flags) - { -- set_signals(flags); -+ um_set_signals(flags); - } - - #define arch_local_irq_enable arch_local_irq_enable -diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h -index bdb2869b72b31..8863319039f3d 100644 ---- a/arch/um/include/shared/longjmp.h -+++ b/arch/um/include/shared/longjmp.h -@@ -18,7 +18,7 @@ extern void longjmp(jmp_buf, int); - enable = *(volatile int *)&signals_enabled; \ - n = setjmp(*buf); \ - if(n != 0) \ -- set_signals_trace(enable); \ -+ um_set_signals_trace(enable); \ - n; }) - - #endif -diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h -index 96d400387c93e..03ffbdddcc480 100644 ---- a/arch/um/include/shared/os.h -+++ b/arch/um/include/shared/os.h -@@ -238,8 +238,8 @@ extern void send_sigio_to_self(void); - extern int change_sig(int signal, int on); - extern void block_signals(void); - extern void unblock_signals(void); --extern int set_signals(int enable); --extern int set_signals_trace(int enable); -+extern int um_set_signals(int enable); -+extern int um_set_signals_trace(int enable); - extern int os_is_signal_stack(void); - extern void deliver_alarm(void); - extern void register_pm_wake_signal(void); -diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h -index 0c50fa6e8a55b..fbb709a222839 100644 ---- a/arch/um/include/shared/registers.h -+++ b/arch/um/include/shared/registers.h -@@ -16,8 +16,8 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); - extern int save_fpx_registers(int pid, unsigned long *fp_regs); - extern int restore_fpx_registers(int pid, unsigned long *fp_regs); - extern int save_registers(int pid, struct uml_pt_regs *regs); --extern int restore_registers(int pid, struct uml_pt_regs *regs); --extern int init_registers(int pid); -+extern int restore_pid_registers(int pid, struct uml_pt_regs *regs); -+extern int init_pid_registers(int pid); - extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); - extern unsigned long get_thread_reg(int reg, jmp_buf *buf); - extern int get_fp_registers(int pid, unsigned long *regs); -diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c -index b1e5634398d09..3a85bde3e1734 100644 ---- a/arch/um/kernel/ksyms.c -+++ b/arch/um/kernel/ksyms.c -@@ -6,7 +6,7 @@ - #include - #include - --EXPORT_SYMBOL(set_signals); -+EXPORT_SYMBOL(um_set_signals); - EXPORT_SYMBOL(signals_enabled); - - EXPORT_SYMBOL(os_stat_fd); -diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c -index 3198c47673879..c32efb09db214 100644 ---- a/arch/um/kernel/trap.c -+++ b/arch/um/kernel/trap.c -@@ -158,7 +158,7 @@ static void bad_segv(struct faultinfo fi, unsigned long ip) - - void fatal_sigsegv(void) - { -- force_sigsegv(SIGSEGV); -+ force_fatal_sig(SIGSEGV); - do_signal(¤t->thread.regs); - /* - * This is to tell gcc that we're not returning - do_signal -diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c -index 2d9270508e156..b123955be7acc 100644 ---- a/arch/um/os-Linux/registers.c -+++ b/arch/um/os-Linux/registers.c -@@ -21,7 +21,7 @@ int save_registers(int pid, struct uml_pt_regs *regs) - return 0; - } - --int restore_registers(int pid, struct uml_pt_regs *regs) -+int restore_pid_registers(int pid, struct uml_pt_regs *regs) - { - int err; - -@@ -36,7 +36,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) - static unsigned long exec_regs[MAX_REG_NR]; - static unsigned long exec_fp_regs[FP_SIZE]; - --int init_registers(int pid) -+int init_pid_registers(int pid) - { - int err; - -diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c -index 6597ea1986ffa..9e71794839e87 100644 ---- a/arch/um/os-Linux/sigio.c -+++ b/arch/um/os-Linux/sigio.c -@@ -132,7 +132,7 @@ static void update_thread(void) - int n; - char c; - -- flags = set_signals_trace(0); -+ flags = um_set_signals_trace(0); - CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c))); - if (n != sizeof(c)) { - printk(UM_KERN_ERR "update_thread : write failed, err = %d\n", -@@ -147,7 +147,7 @@ static void update_thread(void) - goto fail; - } - -- set_signals_trace(flags); -+ um_set_signals_trace(flags); - return; - fail: - /* Critical section start */ -@@ -161,7 +161,7 @@ static void update_thread(void) - close(write_sigio_fds[0]); - close(write_sigio_fds[1]); - /* Critical section end */ -- set_signals_trace(flags); -+ um_set_signals_trace(flags); - } - - int __add_sigio_fd(int fd) -diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c -index 6cf098c23a394..24a403a70a020 100644 ---- a/arch/um/os-Linux/signal.c -+++ b/arch/um/os-Linux/signal.c -@@ -94,7 +94,7 @@ void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) - - sig_handler_common(sig, si, mc); - -- set_signals_trace(enabled); -+ um_set_signals_trace(enabled); - } - - static void timer_real_alarm_handler(mcontext_t *mc) -@@ -126,7 +126,7 @@ void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) - - signals_active &= ~SIGALRM_MASK; - -- set_signals_trace(enabled); -+ um_set_signals_trace(enabled); - } - - void deliver_alarm(void) { -@@ -348,7 +348,7 @@ void unblock_signals(void) - } - } - --int set_signals(int enable) -+int um_set_signals(int enable) - { - int ret; - if (signals_enabled == enable) -@@ -362,7 +362,7 @@ int set_signals(int enable) - return ret; - } - --int set_signals_trace(int enable) -+int um_set_signals_trace(int enable) - { - int ret; - if (signals_enabled == enable) -diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c -index 8a72c99994eb1..e3ee4db58b40d 100644 ---- a/arch/um/os-Linux/start_up.c -+++ b/arch/um/os-Linux/start_up.c -@@ -368,7 +368,7 @@ void __init os_early_checks(void) - check_tmpexec(); - - pid = start_ptraced_child(); -- if (init_registers(pid)) -+ if (init_pid_registers(pid)) - fatal("Failed to initialize default registers"); - stop_ptraced_child(pid, 1, 1); - } -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index d9830e7e1060f..1f96809606ac5 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -1256,7 +1256,8 @@ config TOSHIBA - - config I8K - tristate "Dell i8k legacy laptop support" -- select HWMON -+ depends on HWMON -+ depends on PROC_FS - select SENSORS_DELL_SMM - help - This option enables legacy /proc/i8k userspace interface in hwmon -@@ -1518,6 +1519,7 @@ config AMD_MEM_ENCRYPT - select ARCH_HAS_FORCE_DMA_UNENCRYPTED - select INSTRUCTION_DECODER - select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS -+ select ARCH_HAS_CC_PLATFORM - help - Say yes to enable support for the encryption of system memory. - This requires an AMD processor that supports Secure Memory -@@ -1917,6 +1919,7 @@ config EFI - depends on ACPI - select UCS2_STRING - select EFI_RUNTIME_WRAPPERS -+ select ARCH_USE_MEMREMAP_PROT - help - This enables the kernel to use EFI runtime services that are - available (such as the EFI variable services). -diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile -index 431bf7f846c3c..e118136460518 100644 ---- a/arch/x86/boot/compressed/Makefile -+++ b/arch/x86/boot/compressed/Makefile -@@ -28,7 +28,11 @@ KCOV_INSTRUMENT := n - targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ - vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst - --KBUILD_CFLAGS := -m$(BITS) -O2 -+# CLANG_FLAGS must come before any cc-disable-warning or cc-option calls in -+# case of cross compiling, as it has the '--target=' flag, which is needed to -+# avoid errors with '-march=i386', and future flags may depend on the target to -+# be valid. -+KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) - KBUILD_CFLAGS += -fno-strict-aliasing -fPIE - KBUILD_CFLAGS += -Wundef - KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING -@@ -47,7 +51,6 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS - # Disable relocation relaxation in case the link is not PIE. - KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no) - KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h --KBUILD_CFLAGS += $(CLANG_FLAGS) - - # sev.c indirectly inludes inat-table.h which is generated during - # compilation and stored in $(objtree). Add the directory to the includes so -diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig -index e81885384f604..99398cbdae434 100644 ---- a/arch/x86/configs/i386_defconfig -+++ b/arch/x86/configs/i386_defconfig -@@ -262,3 +262,4 @@ CONFIG_BLK_DEV_IO_TRACE=y - CONFIG_PROVIDE_OHCI1394_DMA_INIT=y - CONFIG_EARLY_PRINTK_DBGP=y - CONFIG_DEBUG_BOOT_PARAMS=y -+CONFIG_KALLSYMS_ALL=y -diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig -index e8a7a0af2bdaa..d7298b104a456 100644 ---- a/arch/x86/configs/x86_64_defconfig -+++ b/arch/x86/configs/x86_64_defconfig -@@ -258,3 +258,4 @@ CONFIG_BLK_DEV_IO_TRACE=y - CONFIG_PROVIDE_OHCI1394_DMA_INIT=y - CONFIG_EARLY_PRINTK_DBGP=y - CONFIG_DEBUG_BOOT_PARAMS=y -+CONFIG_KALLSYMS_ALL=y -diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c -index 0fc961bef299c..41901ba9d3a2c 100644 ---- a/arch/x86/crypto/aesni-intel_glue.c -+++ b/arch/x86/crypto/aesni-intel_glue.c -@@ -866,7 +866,7 @@ static int xts_crypt(struct skcipher_request *req, bool encrypt) - req = &subreq; - - err = skcipher_walk_virt(&walk, req, false); -- if (err) -+ if (!walk.nbytes) - return err; - } else { - tail = 0; -@@ -1107,7 +1107,7 @@ static struct aead_alg aesni_aeads[] = { { - .cra_flags = CRYPTO_ALG_INTERNAL, - .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx), -- .cra_alignmask = AESNI_ALIGN - 1, -+ .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - }, { -@@ -1124,7 +1124,7 @@ static struct aead_alg aesni_aeads[] = { { - .cra_flags = CRYPTO_ALG_INTERNAL, - .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct generic_gcmaes_ctx), -- .cra_alignmask = AESNI_ALIGN - 1, -+ .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - } }; -diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S -index e38a4cf795d96..97b1f84bb53f8 100644 ---- a/arch/x86/entry/entry_64.S -+++ b/arch/x86/entry/entry_64.S -@@ -574,6 +574,10 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) - ud2 - 1: - #endif -+#ifdef CONFIG_XEN_PV -+ ALTERNATIVE "", "jmp xenpv_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV -+#endif -+ - POP_REGS pop_rdi=0 - - /* -@@ -890,6 +894,7 @@ SYM_CODE_START_LOCAL(paranoid_entry) - .Lparanoid_entry_checkgs: - /* EBX = 1 -> kernel GSBASE active, no restore required */ - movl $1, %ebx -+ - /* - * The kernel-enforced convention is a negative GSBASE indicates - * a kernel value. No SWAPGS needed on entry and exit. -@@ -897,21 +902,14 @@ SYM_CODE_START_LOCAL(paranoid_entry) - movl $MSR_GS_BASE, %ecx - rdmsr - testl %edx, %edx -- jns .Lparanoid_entry_swapgs -- ret -+ js .Lparanoid_kernel_gsbase - --.Lparanoid_entry_swapgs: -+ /* EBX = 0 -> SWAPGS required on exit */ -+ xorl %ebx, %ebx - swapgs -+.Lparanoid_kernel_gsbase: - -- /* -- * The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an -- * unconditional CR3 write, even in the PTI case. So do an lfence -- * to prevent GS speculation, regardless of whether PTI is enabled. -- */ - FENCE_SWAPGS_KERNEL_ENTRY -- -- /* EBX = 0 -> SWAPGS required on exit */ -- xorl %ebx, %ebx - ret - SYM_CODE_END(paranoid_entry) - -@@ -993,11 +991,6 @@ SYM_CODE_START_LOCAL(error_entry) - pushq %r12 - ret - --.Lerror_entry_done_lfence: -- FENCE_SWAPGS_KERNEL_ENTRY --.Lerror_entry_done: -- ret -- - /* - * There are two places in the kernel that can potentially fault with - * usergs. Handle them here. B stepping K8s sometimes report a -@@ -1020,8 +1013,14 @@ SYM_CODE_START_LOCAL(error_entry) - * .Lgs_change's error handler with kernel gsbase. - */ - SWAPGS -- FENCE_SWAPGS_USER_ENTRY -- jmp .Lerror_entry_done -+ -+ /* -+ * Issue an LFENCE to prevent GS speculation, regardless of whether it is a -+ * kernel or user gsbase. -+ */ -+.Lerror_entry_done_lfence: -+ FENCE_SWAPGS_KERNEL_ENTRY -+ ret - - .Lbstep_iret: - /* Fix truncated RIP */ -diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c -index 1b40b92970831..fd2ee9408e914 100644 ---- a/arch/x86/entry/vsyscall/vsyscall_64.c -+++ b/arch/x86/entry/vsyscall/vsyscall_64.c -@@ -226,7 +226,8 @@ bool emulate_vsyscall(unsigned long error_code, - if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) { - warn_bad_vsyscall(KERN_DEBUG, regs, - "seccomp tried to change syscall nr or ip"); -- do_exit(SIGSYS); -+ force_exit_sig(SIGSYS); -+ return true; - } - regs->orig_ax = -1; - if (tmp) -diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c -index 6dfa8ddaa60f7..81d5e0a1f48cd 100644 ---- a/arch/x86/events/core.c -+++ b/arch/x86/events/core.c -@@ -2762,10 +2762,11 @@ static bool perf_hw_regs(struct pt_regs *regs) - void - perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct unwind_state state; - unsigned long addr; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* TODO: We don't support guest os callchain now */ - return; - } -@@ -2865,10 +2866,11 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent - void - perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - struct stack_frame frame; - const struct stack_frame __user *fp; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -+ if (guest_cbs && guest_cbs->is_in_guest()) { - /* TODO: We don't support guest os callchain now */ - return; - } -@@ -2945,18 +2947,21 @@ static unsigned long code_segment_base(struct pt_regs *regs) - - unsigned long perf_instruction_pointer(struct pt_regs *regs) - { -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) -- return perf_guest_cbs->get_guest_ip(); -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); -+ -+ if (guest_cbs && guest_cbs->is_in_guest()) -+ return guest_cbs->get_guest_ip(); - - return regs->ip + code_segment_base(regs); - } - - unsigned long perf_misc_flags(struct pt_regs *regs) - { -+ struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); - int misc = 0; - -- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { -- if (perf_guest_cbs->is_user_mode()) -+ if (guest_cbs && guest_cbs->is_in_guest()) { -+ if (guest_cbs->is_user_mode()) - misc |= PERF_RECORD_MISC_GUEST_USER; - else - misc |= PERF_RECORD_MISC_GUEST_KERNEL; -diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c -index 9a044438072ba..97ede6fb15f26 100644 ---- a/arch/x86/events/intel/core.c -+++ b/arch/x86/events/intel/core.c -@@ -243,7 +243,8 @@ static struct extra_reg intel_skl_extra_regs[] __read_mostly = { - - static struct event_constraint intel_icl_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ -- FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ -+ FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* old INST_RETIRED.PREC_DIST */ -+ FIXED_EVENT_CONSTRAINT(0x0100, 0), /* INST_RETIRED.PREC_DIST */ - FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ - FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ - FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ -@@ -288,7 +289,7 @@ static struct extra_reg intel_spr_extra_regs[] __read_mostly = { - - static struct event_constraint intel_spr_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ -- FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ -+ FIXED_EVENT_CONSTRAINT(0x0100, 0), /* INST_RETIRED.PREC_DIST */ - FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ - FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ - FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ -@@ -2787,6 +2788,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) - { - struct perf_sample_data data; - struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); -+ struct perf_guest_info_callbacks *guest_cbs; - int bit; - int handled = 0; - u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl); -@@ -2853,9 +2855,11 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) - */ - if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) { - handled++; -- if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() && -- perf_guest_cbs->handle_intel_pt_intr)) -- perf_guest_cbs->handle_intel_pt_intr(); -+ -+ guest_cbs = perf_get_guest_cbs(); -+ if (unlikely(guest_cbs && guest_cbs->is_in_guest() && -+ guest_cbs->handle_intel_pt_intr)) -+ guest_cbs->handle_intel_pt_intr(); - else - intel_pt_interrupt(); - } -@@ -2998,8 +3002,10 @@ intel_vlbr_constraints(struct perf_event *event) - { - struct event_constraint *c = &vlbr_constraint; - -- if (unlikely(constraint_match(c, event->hw.config))) -+ if (unlikely(constraint_match(c, event->hw.config))) { -+ event->hw.flags |= c->flags; - return c; -+ } - - return NULL; - } -@@ -4648,6 +4654,19 @@ static __initconst const struct x86_pmu intel_pmu = { - .lbr_read = intel_pmu_lbr_read_64, - .lbr_save = intel_pmu_lbr_save, - .lbr_restore = intel_pmu_lbr_restore, -+ -+ /* -+ * SMM has access to all 4 rings and while traditionally SMM code only -+ * ran in CPL0, 2021-era firmware is starting to make use of CPL3 in SMM. -+ * -+ * Since the EVENTSEL.{USR,OS} CPL filtering makes no distinction -+ * between SMM or not, this results in what should be pure userspace -+ * counters including SMM data. -+ * -+ * This is a clear privilege issue, therefore globally disable -+ * counting SMM by default. -+ */ -+ .attr_freeze_on_smi = 1, - }; - - static __init void intel_clovertown_quirk(void) -@@ -6181,6 +6200,19 @@ __init int intel_pmu_init(void) - pmu->num_counters = x86_pmu.num_counters; - pmu->num_counters_fixed = x86_pmu.num_counters_fixed; - } -+ -+ /* -+ * Quirk: For some Alder Lake machine, when all E-cores are disabled in -+ * a BIOS, the leaf 0xA will enumerate all counters of P-cores. However, -+ * the X86_FEATURE_HYBRID_CPU is still set. The above codes will -+ * mistakenly add extra counters for P-cores. Correct the number of -+ * counters here. -+ */ -+ if ((pmu->num_counters > 8) || (pmu->num_counters_fixed > 4)) { -+ pmu->num_counters = x86_pmu.num_counters; -+ pmu->num_counters_fixed = x86_pmu.num_counters_fixed; -+ } -+ - pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters); - pmu->unconstrained = (struct event_constraint) - __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1, -diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c -index 8647713276a73..4dbb55a43dad2 100644 ---- a/arch/x86/events/intel/ds.c -+++ b/arch/x86/events/intel/ds.c -@@ -923,7 +923,8 @@ struct event_constraint intel_skl_pebs_event_constraints[] = { - }; - - struct event_constraint intel_icl_pebs_event_constraints[] = { -- INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */ -+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x100000000ULL), /* old INST_RETIRED.PREC_DIST */ -+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0100, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */ - INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), /* SLOTS */ - - INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ -@@ -943,7 +944,7 @@ struct event_constraint intel_icl_pebs_event_constraints[] = { - }; - - struct event_constraint intel_spr_pebs_event_constraints[] = { -- INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x100000000ULL), -+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */ - INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), - - INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe), -diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c -index 9e6d6eaeb4cb6..f455dd93f9219 100644 ---- a/arch/x86/events/intel/lbr.c -+++ b/arch/x86/events/intel/lbr.c -@@ -1734,6 +1734,9 @@ static bool is_arch_lbr_xsave_available(void) - * Check the LBR state with the corresponding software structure. - * Disable LBR XSAVES support if the size doesn't match. - */ -+ if (xfeature_size(XFEATURE_LBR) == 0) -+ return false; -+ - if (WARN_ON(xfeature_size(XFEATURE_LBR) != get_lbr_state_size())) - return false; - -diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c -index 7f406c14715fd..2d33bba9a1440 100644 ---- a/arch/x86/events/intel/pt.c -+++ b/arch/x86/events/intel/pt.c -@@ -897,8 +897,9 @@ static void pt_handle_status(struct pt *pt) - * means we are already losing data; need to let the decoder - * know. - */ -- if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) || -- buf->output_off == pt_buffer_region_size(buf)) { -+ if (!buf->single && -+ (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) || -+ buf->output_off == pt_buffer_region_size(buf))) { - perf_aux_output_flag(&pt->handle, - PERF_AUX_FLAG_TRUNCATED); - advance++; -diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h -index 7280c8a3c8310..6d735611c281c 100644 ---- a/arch/x86/events/intel/uncore_discovery.h -+++ b/arch/x86/events/intel/uncore_discovery.h -@@ -30,7 +30,7 @@ - - - #define uncore_discovery_invalid_unit(unit) \ -- (!unit.table1 || !unit.ctl || !unit.table3 || \ -+ (!unit.table1 || !unit.ctl || \ - unit.table1 == -1ULL || unit.ctl == -1ULL || \ - unit.table3 == -1ULL) - -diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c -index 5ddc0f30db6fc..ed869443efb21 100644 ---- a/arch/x86/events/intel/uncore_snbep.c -+++ b/arch/x86/events/intel/uncore_snbep.c -@@ -452,7 +452,7 @@ - #define ICX_M3UPI_PCI_PMON_BOX_CTL 0xa0 - - /* ICX IMC */ --#define ICX_NUMBER_IMC_CHN 2 -+#define ICX_NUMBER_IMC_CHN 3 - #define ICX_IMC_MEM_STRIDE 0x4 - - /* SPR */ -@@ -3608,6 +3608,9 @@ static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *ev - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct extra_reg *er; - int idx = 0; -+ /* Any of the CHA events may be filtered by Thread/Core-ID.*/ -+ if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN) -+ idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID; - - for (er = skx_uncore_cha_extra_regs; er->msr; er++) { - if (er->event != (event->hw.config & er->config_mask)) -@@ -3675,6 +3678,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), - UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), - UNCORE_EVENT_CONSTRAINT(0xd4, 0xc), -+ UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), - EVENT_CONSTRAINT_END - }; - -@@ -4525,6 +4529,13 @@ static void snr_iio_cleanup_mapping(struct intel_uncore_type *type) - pmu_iio_cleanup_mapping(type, &snr_iio_mapping_group); - } - -+static struct event_constraint snr_uncore_iio_constraints[] = { -+ UNCORE_EVENT_CONSTRAINT(0x83, 0x3), -+ UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), -+ UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), -+ EVENT_CONSTRAINT_END -+}; -+ - static struct intel_uncore_type snr_uncore_iio = { - .name = "iio", - .num_counters = 4, -@@ -4536,6 +4547,7 @@ static struct intel_uncore_type snr_uncore_iio = { - .event_mask_ext = SNR_IIO_PMON_RAW_EVENT_MASK_EXT, - .box_ctl = SNR_IIO_MSR_PMON_BOX_CTL, - .msr_offset = SNR_IIO_MSR_OFFSET, -+ .constraints = snr_uncore_iio_constraints, - .ops = &ivbep_uncore_msr_ops, - .format_group = &snr_uncore_iio_format_group, - .attr_update = snr_iio_attr_update, -@@ -5076,8 +5088,10 @@ static struct event_constraint icx_uncore_iio_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x02, 0x3), - UNCORE_EVENT_CONSTRAINT(0x03, 0x3), - UNCORE_EVENT_CONSTRAINT(0x83, 0x3), -+ UNCORE_EVENT_CONSTRAINT(0x88, 0xc), - UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), - UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), -+ UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), - EVENT_CONSTRAINT_END - }; - -@@ -5463,12 +5477,12 @@ static struct intel_uncore_ops icx_uncore_mmio_ops = { - static struct intel_uncore_type icx_uncore_imc = { - .name = "imc", - .num_counters = 4, -- .num_boxes = 8, -+ .num_boxes = 12, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR, - .fixed_ctl = SNR_IMC_MMIO_PMON_FIXED_CTL, -- .event_descs = hswep_uncore_imc_events, -+ .event_descs = snr_uncore_imc_events, - .perf_ctr = SNR_IMC_MMIO_PMON_CTR0, - .event_ctl = SNR_IMC_MMIO_PMON_CTL0, - .event_mask = SNBEP_PMON_RAW_EVENT_MASK, -@@ -5647,6 +5661,7 @@ static struct intel_uncore_type spr_uncore_chabox = { - .event_mask = SPR_CHA_PMON_EVENT_MASK, - .event_mask_ext = SPR_RAW_EVENT_MASK_EXT, - .num_shared_regs = 1, -+ .constraints = skx_uncore_chabox_constraints, - .ops = &spr_uncore_chabox_ops, - .format_group = &spr_uncore_chabox_format_group, - .attr_update = uncore_alias_groups, -@@ -5658,6 +5673,7 @@ static struct intel_uncore_type spr_uncore_iio = { - .event_mask_ext = SNR_IIO_PMON_RAW_EVENT_MASK_EXT, - .format_group = &snr_uncore_iio_format_group, - .attr_update = uncore_alias_groups, -+ .constraints = icx_uncore_iio_constraints, - }; - - static struct attribute *spr_uncore_raw_formats_attr[] = { -@@ -5686,9 +5702,16 @@ static struct intel_uncore_type spr_uncore_irp = { - - }; - -+static struct event_constraint spr_uncore_m2pcie_constraints[] = { -+ UNCORE_EVENT_CONSTRAINT(0x14, 0x3), -+ UNCORE_EVENT_CONSTRAINT(0x2d, 0x3), -+ EVENT_CONSTRAINT_END -+}; -+ - static struct intel_uncore_type spr_uncore_m2pcie = { - SPR_UNCORE_COMMON_FORMAT(), - .name = "m2pcie", -+ .constraints = spr_uncore_m2pcie_constraints, - }; - - static struct intel_uncore_type spr_uncore_pcu = { -@@ -5765,6 +5788,7 @@ static struct intel_uncore_type spr_uncore_upi = { - static struct intel_uncore_type spr_uncore_m3upi = { - SPR_UNCORE_PCI_COMMON_FORMAT(), - .name = "m3upi", -+ .constraints = icx_uncore_m3upi_constraints, - }; - - static struct intel_uncore_type spr_uncore_mdf = { -diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c -index 85feafacc445d..77e3a47af5ad5 100644 ---- a/arch/x86/events/rapl.c -+++ b/arch/x86/events/rapl.c -@@ -536,11 +536,14 @@ static struct perf_msr intel_rapl_spr_msrs[] = { - * - perf_msr_probe(PERF_RAPL_MAX) - * - want to use same event codes across both architectures - */ --static struct perf_msr amd_rapl_msrs[PERF_RAPL_MAX] = { -- [PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr }, -+static struct perf_msr amd_rapl_msrs[] = { -+ [PERF_RAPL_PP0] = { 0, &rapl_events_cores_group, 0, false, 0 }, -+ [PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr, false, RAPL_MSR_MASK }, -+ [PERF_RAPL_RAM] = { 0, &rapl_events_ram_group, 0, false, 0 }, -+ [PERF_RAPL_PP1] = { 0, &rapl_events_gpu_group, 0, false, 0 }, -+ [PERF_RAPL_PSYS] = { 0, &rapl_events_psys_group, 0, false, 0 }, - }; - -- - static int rapl_cpu_offline(unsigned int cpu) - { - struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); -diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c -index 708a2712a516d..b6d48ca5b0f17 100644 ---- a/arch/x86/hyperv/hv_init.c -+++ b/arch/x86/hyperv/hv_init.c -@@ -139,7 +139,6 @@ void set_hv_tscchange_cb(void (*cb)(void)) - struct hv_reenlightenment_control re_ctrl = { - .vector = HYPERV_REENLIGHTENMENT_VECTOR, - .enabled = 1, -- .target_vp = hv_vp_index[smp_processor_id()] - }; - struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1}; - -@@ -148,13 +147,20 @@ void set_hv_tscchange_cb(void (*cb)(void)) - return; - } - -+ if (!hv_vp_index) -+ return; -+ - hv_reenlightenment_cb = cb; - - /* Make sure callback is registered before we write to MSRs */ - wmb(); - -+ re_ctrl.target_vp = hv_vp_index[get_cpu()]; -+ - wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl)); - wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl)); -+ -+ put_cpu(); - } - EXPORT_SYMBOL_GPL(set_hv_tscchange_cb); - -@@ -342,20 +348,13 @@ static void __init hv_get_partition_id(void) - */ - void __init hyperv_init(void) - { -- u64 guest_id, required_msrs; -+ u64 guest_id; - union hv_x64_msr_hypercall_contents hypercall_msr; - int cpuhp; - - if (x86_hyper_type != X86_HYPER_MS_HYPERV) - return; - -- /* Absolutely required MSRs */ -- required_msrs = HV_MSR_HYPERCALL_AVAILABLE | -- HV_MSR_VP_INDEX_AVAILABLE; -- -- if ((ms_hyperv.features & required_msrs) != required_msrs) -- return; -- - if (hv_common_init()) - return; - -diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c -index bd13736d0c054..0ad2378fe6ad7 100644 ---- a/arch/x86/hyperv/mmu.c -+++ b/arch/x86/hyperv/mmu.c -@@ -68,15 +68,6 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus, - - local_irq_save(flags); - -- /* -- * Only check the mask _after_ interrupt has been disabled to avoid the -- * mask changing under our feet. -- */ -- if (cpumask_empty(cpus)) { -- local_irq_restore(flags); -- return; -- } -- - flush_pcpu = (struct hv_tlb_flush **) - this_cpu_ptr(hyperv_pcpu_input_arg); - -@@ -115,7 +106,9 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus, - * must. We will also check all VP numbers when walking the - * supplied CPU set to remain correct in all cases. - */ -- if (hv_cpu_number_to_vp_number(cpumask_last(cpus)) >= 64) -+ cpu = cpumask_last(cpus); -+ -+ if (cpu < nr_cpumask_bits && hv_cpu_number_to_vp_number(cpu) >= 64) - goto do_ex_hypercall; - - for_each_cpu(cpu, cpus) { -@@ -131,6 +124,12 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus, - __set_bit(vcpu, (unsigned long *) - &flush->processor_mask); - } -+ -+ /* nothing to flush if 'processor_mask' ends up being empty */ -+ if (!flush->processor_mask) { -+ local_irq_restore(flags); -+ return; -+ } - } - - /* -diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h -index 84b87538a15de..bab883c0b6fee 100644 ---- a/arch/x86/include/asm/bug.h -+++ b/arch/x86/include/asm/bug.h -@@ -22,7 +22,7 @@ - - #ifdef CONFIG_DEBUG_BUGVERBOSE - --#define _BUG_FLAGS(ins, flags) \ -+#define _BUG_FLAGS(ins, flags, extra) \ - do { \ - asm_inline volatile("1:\t" ins "\n" \ - ".pushsection __bug_table,\"aw\"\n" \ -@@ -31,7 +31,8 @@ do { \ - "\t.word %c1" "\t# bug_entry::line\n" \ - "\t.word %c2" "\t# bug_entry::flags\n" \ - "\t.org 2b+%c3\n" \ -- ".popsection" \ -+ ".popsection\n" \ -+ extra \ - : : "i" (__FILE__), "i" (__LINE__), \ - "i" (flags), \ - "i" (sizeof(struct bug_entry))); \ -@@ -39,14 +40,15 @@ do { \ - - #else /* !CONFIG_DEBUG_BUGVERBOSE */ - --#define _BUG_FLAGS(ins, flags) \ -+#define _BUG_FLAGS(ins, flags, extra) \ - do { \ - asm_inline volatile("1:\t" ins "\n" \ - ".pushsection __bug_table,\"aw\"\n" \ - "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ - "\t.word %c0" "\t# bug_entry::flags\n" \ - "\t.org 2b+%c1\n" \ -- ".popsection" \ -+ ".popsection\n" \ -+ extra \ - : : "i" (flags), \ - "i" (sizeof(struct bug_entry))); \ - } while (0) -@@ -55,7 +57,7 @@ do { \ - - #else - --#define _BUG_FLAGS(ins, flags) asm volatile(ins) -+#define _BUG_FLAGS(ins, flags, extra) asm volatile(ins) - - #endif /* CONFIG_GENERIC_BUG */ - -@@ -63,8 +65,8 @@ do { \ - #define BUG() \ - do { \ - instrumentation_begin(); \ -- _BUG_FLAGS(ASM_UD2, 0); \ -- unreachable(); \ -+ _BUG_FLAGS(ASM_UD2, 0, ""); \ -+ __builtin_unreachable(); \ - } while (0) - - /* -@@ -75,9 +77,9 @@ do { \ - */ - #define __WARN_FLAGS(flags) \ - do { \ -+ __auto_type f = BUGFLAG_WARNING|(flags); \ - instrumentation_begin(); \ -- _BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags)); \ -- annotate_reachable(); \ -+ _BUG_FLAGS(ASM_UD2, f, ASM_REACHABLE); \ - instrumentation_end(); \ - } while (0) - -diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/cpu_entry_area.h -index 3d52b094850a9..dd5ea1bdf04c5 100644 ---- a/arch/x86/include/asm/cpu_entry_area.h -+++ b/arch/x86/include/asm/cpu_entry_area.h -@@ -10,6 +10,12 @@ - - #ifdef CONFIG_X86_64 - -+#ifdef CONFIG_AMD_MEM_ENCRYPT -+#define VC_EXCEPTION_STKSZ EXCEPTION_STKSZ -+#else -+#define VC_EXCEPTION_STKSZ 0 -+#endif -+ - /* Macro to enforce the same ordering and stack sizes */ - #define ESTACKS_MEMBERS(guardsize, optional_stack_size) \ - char DF_stack_guard[guardsize]; \ -@@ -28,7 +34,7 @@ - - /* The exception stacks' physical storage. No guard pages required */ - struct exception_stacks { -- ESTACKS_MEMBERS(0, 0) -+ ESTACKS_MEMBERS(0, VC_EXCEPTION_STKSZ) - }; - - /* The effective cpu entry area mapping with guard pages. */ -diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h -index d0ce5cfd3ac14..4423759f619cc 100644 ---- a/arch/x86/include/asm/cpufeatures.h -+++ b/arch/x86/include/asm/cpufeatures.h -@@ -204,7 +204,7 @@ - /* FREE! ( 7*32+10) */ - #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ - #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ --#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ -+#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCE for Spectre variant 2 */ - #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ - #define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */ - #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ -diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h -index 4d0b126835b8a..63158fd558567 100644 ---- a/arch/x86/include/asm/efi.h -+++ b/arch/x86/include/asm/efi.h -@@ -197,8 +197,6 @@ static inline bool efi_runtime_supported(void) - - extern void parse_efi_setup(u64 phys_addr, u32 data_len); - --extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt); -- - extern void efi_thunk_runtime_setup(void); - efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, - unsigned long descriptor_size, -diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h -index 91d7182ad2d6e..4ec3613551e3b 100644 ---- a/arch/x86/include/asm/insn-eval.h -+++ b/arch/x86/include/asm/insn-eval.h -@@ -21,6 +21,7 @@ int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); - int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); - unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); - int insn_get_code_seg_params(struct pt_regs *regs); -+int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip); - int insn_fetch_from_user(struct pt_regs *regs, - unsigned char buf[MAX_INSN_SIZE]); - int insn_fetch_from_user_inatomic(struct pt_regs *regs, -diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h -index 562854c608082..8d55bd11848cb 100644 ---- a/arch/x86/include/asm/irq_stack.h -+++ b/arch/x86/include/asm/irq_stack.h -@@ -77,11 +77,11 @@ - * Function calls can clobber anything except the callee-saved - * registers. Tell the compiler. - */ --#define call_on_irqstack(func, asm_call, argconstr...) \ -+#define call_on_stack(stack, func, asm_call, argconstr...) \ - { \ - register void *tos asm("r11"); \ - \ -- tos = ((void *)__this_cpu_read(hardirq_stack_ptr)); \ -+ tos = ((void *)(stack)); \ - \ - asm_inline volatile( \ - "movq %%rsp, (%[tos]) \n" \ -@@ -98,6 +98,25 @@ - ); \ - } - -+#define ASM_CALL_ARG0 \ -+ "call %P[__func] \n" -+ -+#define ASM_CALL_ARG1 \ -+ "movq %[arg1], %%rdi \n" \ -+ ASM_CALL_ARG0 -+ -+#define ASM_CALL_ARG2 \ -+ "movq %[arg2], %%rsi \n" \ -+ ASM_CALL_ARG1 -+ -+#define ASM_CALL_ARG3 \ -+ "movq %[arg3], %%rdx \n" \ -+ ASM_CALL_ARG2 -+ -+#define call_on_irqstack(func, asm_call, argconstr...) \ -+ call_on_stack(__this_cpu_read(hardirq_stack_ptr), \ -+ func, asm_call, argconstr) -+ - /* Macros to assert type correctness for run_*_on_irqstack macros */ - #define assert_function_type(func, proto) \ - static_assert(__builtin_types_compatible_p(typeof(&func), proto)) -@@ -147,8 +166,7 @@ - */ - #define ASM_CALL_SYSVEC \ - "call irq_enter_rcu \n" \ -- "movq %[arg1], %%rdi \n" \ -- "call %P[__func] \n" \ -+ ASM_CALL_ARG1 \ - "call irq_exit_rcu \n" - - #define SYSVEC_CONSTRAINTS , [arg1] "r" (regs) -@@ -168,12 +186,10 @@ - */ - #define ASM_CALL_IRQ \ - "call irq_enter_rcu \n" \ -- "movq %[arg1], %%rdi \n" \ -- "movl %[arg2], %%esi \n" \ -- "call %P[__func] \n" \ -+ ASM_CALL_ARG2 \ - "call irq_exit_rcu \n" - --#define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" (vector) -+#define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" ((unsigned long)vector) - - #define run_irq_on_irqstack_cond(func, regs, vector) \ - { \ -@@ -185,9 +201,6 @@ - IRQ_CONSTRAINTS, regs, vector); \ - } - --#define ASM_CALL_SOFTIRQ \ -- "call %P[__func] \n" -- - /* - * Macro to invoke __do_softirq on the irq stack. This is only called from - * task context when bottom halves are about to be reenabled and soft -@@ -197,7 +210,7 @@ - #define do_softirq_own_stack() \ - { \ - __this_cpu_write(hardirq_stack_inuse, true); \ -- call_on_irqstack(__do_softirq, ASM_CALL_SOFTIRQ); \ -+ call_on_irqstack(__do_softirq, ASM_CALL_ARG0); \ - __this_cpu_write(hardirq_stack_inuse, false); \ - } - -diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h -index cefe1d81e2e8b..9e50da3ed01a3 100644 ---- a/arch/x86/include/asm/kvm-x86-ops.h -+++ b/arch/x86/include/asm/kvm-x86-ops.h -@@ -47,6 +47,7 @@ KVM_X86_OP(set_dr7) - KVM_X86_OP(cache_reg) - KVM_X86_OP(get_rflags) - KVM_X86_OP(set_rflags) -+KVM_X86_OP(get_if_flag) - KVM_X86_OP(tlb_flush_all) - KVM_X86_OP(tlb_flush_current) - KVM_X86_OP_NULL(tlb_remote_flush) -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 13f64654dfff8..01759199d7238 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -98,7 +98,7 @@ - KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) - #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) - #define KVM_REQ_TLB_FLUSH_GUEST \ -- KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP) -+ KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) - #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) - #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) - #define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \ -@@ -364,6 +364,7 @@ union kvm_mmu_extended_role { - unsigned int cr4_smap:1; - unsigned int cr4_smep:1; - unsigned int cr4_la57:1; -+ unsigned int efer_lma:1; - }; - }; - -@@ -751,7 +752,7 @@ struct kvm_vcpu_arch { - u8 preempted; - u64 msr_val; - u64 last_steal; -- struct gfn_to_pfn_cache cache; -+ struct gfn_to_hva_cache cache; - } st; - - u64 l1_tsc_offset; -@@ -1340,6 +1341,7 @@ struct kvm_x86_ops { - void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); - unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); - void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); -+ bool (*get_if_flag)(struct kvm_vcpu *vcpu); - - void (*tlb_flush_all)(struct kvm_vcpu *vcpu); - void (*tlb_flush_current)(struct kvm_vcpu *vcpu); -@@ -1485,6 +1487,7 @@ struct kvm_x86_ops { - }; - - struct kvm_x86_nested_ops { -+ void (*leave_nested)(struct kvm_vcpu *vcpu); - int (*check_events)(struct kvm_vcpu *vcpu); - bool (*hv_timer_pending)(struct kvm_vcpu *vcpu); - void (*triple_fault)(struct kvm_vcpu *vcpu); -@@ -1507,6 +1510,7 @@ struct kvm_x86_init_ops { - int (*disabled_by_bios)(void); - int (*check_processor_compatibility)(void); - int (*hardware_setup)(void); -+ bool (*intel_pt_intr_in_guest)(void); - - struct kvm_x86_ops *runtime_ops; - }; -diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h -index 9c80c68d75b54..3fb9f5ebefa42 100644 ---- a/arch/x86/include/asm/mem_encrypt.h -+++ b/arch/x86/include/asm/mem_encrypt.h -@@ -13,6 +13,7 @@ - #ifndef __ASSEMBLY__ - - #include -+#include - - #include - -diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h -index ec2d5c8c66947..b3dd514f80a0b 100644 ---- a/arch/x86/include/asm/nospec-branch.h -+++ b/arch/x86/include/asm/nospec-branch.h -@@ -81,7 +81,7 @@ - #ifdef CONFIG_RETPOLINE - ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ - __stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \ -- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD -+ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE - #else - jmp *%\reg - #endif -@@ -91,7 +91,7 @@ - #ifdef CONFIG_RETPOLINE - ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \ - __stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \ -- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_AMD -+ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_LFENCE - #else - call *%\reg - #endif -@@ -133,7 +133,7 @@ - "lfence;\n" \ - ANNOTATE_RETPOLINE_SAFE \ - "call *%[thunk_target]\n", \ -- X86_FEATURE_RETPOLINE_AMD) -+ X86_FEATURE_RETPOLINE_LFENCE) - - # define THUNK_TARGET(addr) [thunk_target] "r" (addr) - -@@ -163,7 +163,7 @@ - "lfence;\n" \ - ANNOTATE_RETPOLINE_SAFE \ - "call *%[thunk_target]\n", \ -- X86_FEATURE_RETPOLINE_AMD) -+ X86_FEATURE_RETPOLINE_LFENCE) - - # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) - #endif -@@ -175,9 +175,11 @@ - /* The Spectre V2 mitigation variants */ - enum spectre_v2_mitigation { - SPECTRE_V2_NONE, -- SPECTRE_V2_RETPOLINE_GENERIC, -- SPECTRE_V2_RETPOLINE_AMD, -- SPECTRE_V2_IBRS_ENHANCED, -+ SPECTRE_V2_RETPOLINE, -+ SPECTRE_V2_LFENCE, -+ SPECTRE_V2_EIBRS, -+ SPECTRE_V2_EIBRS_RETPOLINE, -+ SPECTRE_V2_EIBRS_LFENCE, - }; - - /* The indirect branch speculation control variants */ -diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h -index a8d4ad8565681..e9e2c3ba59239 100644 ---- a/arch/x86/include/asm/page_64_types.h -+++ b/arch/x86/include/asm/page_64_types.h -@@ -15,7 +15,7 @@ - #define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) - #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) - --#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER) -+#define EXCEPTION_STACK_ORDER (1 + KASAN_STACK_ORDER) - #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) - - #define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER) -diff --git a/arch/x86/include/asm/pkru.h b/arch/x86/include/asm/pkru.h -index ccc539faa5bbc..4d8b9448fe8d2 100644 ---- a/arch/x86/include/asm/pkru.h -+++ b/arch/x86/include/asm/pkru.h -@@ -4,8 +4,8 @@ - - #include - --#define PKRU_AD_BIT 0x1 --#define PKRU_WD_BIT 0x2 -+#define PKRU_AD_BIT 0x1u -+#define PKRU_WD_BIT 0x2u - #define PKRU_BITS_PER_PKEY 2 - - #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS -diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h -index 9ad2acaaae9b8..577f342dbfb27 100644 ---- a/arch/x86/include/asm/processor.h -+++ b/arch/x86/include/asm/processor.h -@@ -518,6 +518,7 @@ struct thread_struct { - */ - unsigned long iopl_emul; - -+ unsigned int iopl_warn:1; - unsigned int sig_on_uaccess_err:1; - - /* -diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h -index 5db5d083c8732..331474b150f16 100644 ---- a/arch/x86/include/asm/realmode.h -+++ b/arch/x86/include/asm/realmode.h -@@ -89,6 +89,7 @@ static inline void set_real_mode_mem(phys_addr_t mem) - } - - void reserve_real_mode(void); -+void load_trampoline_pgtable(void); - - #endif /* __ASSEMBLY__ */ - -diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h -index f248eb2ac2d4a..3881b5333eb81 100644 ---- a/arch/x86/include/asm/stacktrace.h -+++ b/arch/x86/include/asm/stacktrace.h -@@ -38,6 +38,16 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, - bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, - struct stack_info *info); - -+static __always_inline -+bool get_stack_guard_info(unsigned long *stack, struct stack_info *info) -+{ -+ /* make sure it's not in the stack proper */ -+ if (get_stack_info_noinstr(stack, current, info)) -+ return false; -+ /* but if it is in the page below it, we hit a guard */ -+ return get_stack_info_noinstr((void *)stack + PAGE_SIZE, current, info); -+} -+ - const char *stack_type_name(enum stack_type type); - - static inline bool on_stack(struct stack_info *info, void *addr, size_t len) -diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h -index 9239399e54914..55160445ea78b 100644 ---- a/arch/x86/include/asm/topology.h -+++ b/arch/x86/include/asm/topology.h -@@ -218,7 +218,7 @@ static inline void arch_set_max_freq_ratio(bool turbo_disabled) - } - #endif - --#ifdef CONFIG_ACPI_CPPC_LIB -+#if defined(CONFIG_ACPI_CPPC_LIB) && defined(CONFIG_SMP) - void init_freq_invariance_cppc(void); - #define init_freq_invariance_cppc init_freq_invariance_cppc - #endif -diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h -index 7f7200021bd13..6221be7cafc3b 100644 ---- a/arch/x86/include/asm/traps.h -+++ b/arch/x86/include/asm/traps.h -@@ -40,9 +40,9 @@ void math_emulate(struct math_emu_info *); - bool fault_in_kernel_space(unsigned long address); - - #ifdef CONFIG_VMAP_STACK --void __noreturn handle_stack_overflow(const char *message, -- struct pt_regs *regs, -- unsigned long fault_address); -+void __noreturn handle_stack_overflow(struct pt_regs *regs, -+ unsigned long fault_address, -+ struct stack_info *info); - #endif - - #endif /* _ASM_X86_TRAPS_H */ -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 5c95d242f38d7..bb1430283c726 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -314,11 +314,12 @@ do { \ - do { \ - __chk_user_ptr(ptr); \ - switch (size) { \ -- unsigned char x_u8__; \ -- case 1: \ -+ case 1: { \ -+ unsigned char x_u8__; \ - __get_user_asm(x_u8__, ptr, "b", "=q", label); \ - (x) = x_u8__; \ - break; \ -+ } \ - case 2: \ - __get_user_asm(x, ptr, "w", "=r", label); \ - break; \ -diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h -index ff4b52e37e60d..5adab895127e1 100644 ---- a/arch/x86/include/asm/xen/hypervisor.h -+++ b/arch/x86/include/asm/xen/hypervisor.h -@@ -62,4 +62,9 @@ void xen_arch_register_cpu(int num); - void xen_arch_unregister_cpu(int num); - #endif - -+#ifdef CONFIG_PVH -+void __init xen_pvh_init(struct boot_params *boot_params); -+void __init mem_map_via_hcall(struct boot_params *boot_params_p); -+#endif -+ - #endif /* _ASM_X86_XEN_HYPERVISOR_H */ -diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile -index 8f4e8fa6ed759..2ff3e600f4269 100644 ---- a/arch/x86/kernel/Makefile -+++ b/arch/x86/kernel/Makefile -@@ -21,6 +21,7 @@ CFLAGS_REMOVE_ftrace.o = -pg - CFLAGS_REMOVE_early_printk.o = -pg - CFLAGS_REMOVE_head64.o = -pg - CFLAGS_REMOVE_sev.o = -pg -+CFLAGS_REMOVE_cc_platform.o = -pg - endif - - KASAN_SANITIZE_head$(BITS).o := n -@@ -29,6 +30,7 @@ KASAN_SANITIZE_dumpstack_$(BITS).o := n - KASAN_SANITIZE_stacktrace.o := n - KASAN_SANITIZE_paravirt.o := n - KASAN_SANITIZE_sev.o := n -+KASAN_SANITIZE_cc_platform.o := n - - # With some compiler versions the generated code results in boot hangs, caused - # by several compilation units. To be safe, disable all instrumentation. -@@ -47,6 +49,7 @@ endif - KCOV_INSTRUMENT := n - - CFLAGS_head$(BITS).o += -fno-stack-protector -+CFLAGS_cc_platform.o += -fno-stack-protector - - CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace - -@@ -147,6 +150,9 @@ obj-$(CONFIG_UNWINDER_FRAME_POINTER) += unwind_frame.o - obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o - - obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev.o -+ -+obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += cc_platform.o -+ - ### - # 64 bit specific files - ifeq ($(CONFIG_X86_64),y) -diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c -new file mode 100644 -index 0000000000000..03bb2f343ddb7 ---- /dev/null -+++ b/arch/x86/kernel/cc_platform.c -@@ -0,0 +1,69 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Confidential Computing Platform Capability checks -+ * -+ * Copyright (C) 2021 Advanced Micro Devices, Inc. -+ * -+ * Author: Tom Lendacky -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr) -+{ -+#ifdef CONFIG_INTEL_TDX_GUEST -+ return false; -+#else -+ return false; -+#endif -+} -+ -+/* -+ * SME and SEV are very similar but they are not the same, so there are -+ * times that the kernel will need to distinguish between SME and SEV. The -+ * cc_platform_has() function is used for this. When a distinction isn't -+ * needed, the CC_ATTR_MEM_ENCRYPT attribute can be used. -+ * -+ * The trampoline code is a good example for this requirement. Before -+ * paging is activated, SME will access all memory as decrypted, but SEV -+ * will access all memory as encrypted. So, when APs are being brought -+ * up under SME the trampoline area cannot be encrypted, whereas under SEV -+ * the trampoline area must be encrypted. -+ */ -+static bool amd_cc_platform_has(enum cc_attr attr) -+{ -+#ifdef CONFIG_AMD_MEM_ENCRYPT -+ switch (attr) { -+ case CC_ATTR_MEM_ENCRYPT: -+ return sme_me_mask; -+ -+ case CC_ATTR_HOST_MEM_ENCRYPT: -+ return sme_me_mask && !(sev_status & MSR_AMD64_SEV_ENABLED); -+ -+ case CC_ATTR_GUEST_MEM_ENCRYPT: -+ return sev_status & MSR_AMD64_SEV_ENABLED; -+ -+ case CC_ATTR_GUEST_STATE_ENCRYPT: -+ return sev_status & MSR_AMD64_SEV_ES_ENABLED; -+ -+ default: -+ return false; -+ } -+#else -+ return false; -+#endif -+} -+ -+ -+bool cc_platform_has(enum cc_attr attr) -+{ -+ if (sme_me_mask) -+ return amd_cc_platform_has(attr); -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(cc_platform_has); -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index 2131af9f2fa23..4edb6f0f628c2 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -989,6 +989,8 @@ static void init_amd(struct cpuinfo_x86 *c) - if (cpu_has(c, X86_FEATURE_IRPERF) && - !cpu_has_amd_erratum(c, amd_erratum_1054)) - msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); -+ -+ check_null_seg_clears_base(c); - } - - #ifdef CONFIG_X86_32 -diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c -index ecfca3bbcd968..13320a06e14bd 100644 ---- a/arch/x86/kernel/cpu/bugs.c -+++ b/arch/x86/kernel/cpu/bugs.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -650,6 +651,32 @@ static inline const char *spectre_v2_module_string(void) - static inline const char *spectre_v2_module_string(void) { return ""; } - #endif - -+#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n" -+#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n" -+#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n" -+ -+#ifdef CONFIG_BPF_SYSCALL -+void unpriv_ebpf_notify(int new_state) -+{ -+ if (new_state) -+ return; -+ -+ /* Unprivileged eBPF is enabled */ -+ -+ switch (spectre_v2_enabled) { -+ case SPECTRE_V2_EIBRS: -+ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); -+ break; -+ case SPECTRE_V2_EIBRS_LFENCE: -+ if (sched_smt_active()) -+ pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); -+ break; -+ default: -+ break; -+ } -+} -+#endif -+ - static inline bool match_option(const char *arg, int arglen, const char *opt) - { - int len = strlen(opt); -@@ -664,7 +691,10 @@ enum spectre_v2_mitigation_cmd { - SPECTRE_V2_CMD_FORCE, - SPECTRE_V2_CMD_RETPOLINE, - SPECTRE_V2_CMD_RETPOLINE_GENERIC, -- SPECTRE_V2_CMD_RETPOLINE_AMD, -+ SPECTRE_V2_CMD_RETPOLINE_LFENCE, -+ SPECTRE_V2_CMD_EIBRS, -+ SPECTRE_V2_CMD_EIBRS_RETPOLINE, -+ SPECTRE_V2_CMD_EIBRS_LFENCE, - }; - - enum spectre_v2_user_cmd { -@@ -737,6 +767,13 @@ spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd) - return SPECTRE_V2_USER_CMD_AUTO; - } - -+static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) -+{ -+ return (mode == SPECTRE_V2_EIBRS || -+ mode == SPECTRE_V2_EIBRS_RETPOLINE || -+ mode == SPECTRE_V2_EIBRS_LFENCE); -+} -+ - static void __init - spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) - { -@@ -804,7 +841,7 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) - */ - if (!boot_cpu_has(X86_FEATURE_STIBP) || - !smt_possible || -- spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) -+ spectre_v2_in_eibrs_mode(spectre_v2_enabled)) - return; - - /* -@@ -824,9 +861,11 @@ set_mode: - - static const char * const spectre_v2_strings[] = { - [SPECTRE_V2_NONE] = "Vulnerable", -- [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline", -- [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline", -- [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS", -+ [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines", -+ [SPECTRE_V2_LFENCE] = "Mitigation: LFENCE", -+ [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS", -+ [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE", -+ [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines", - }; - - static const struct { -@@ -837,8 +876,12 @@ static const struct { - { "off", SPECTRE_V2_CMD_NONE, false }, - { "on", SPECTRE_V2_CMD_FORCE, true }, - { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false }, -- { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false }, -+ { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, -+ { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, - { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false }, -+ { "eibrs", SPECTRE_V2_CMD_EIBRS, false }, -+ { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false }, -+ { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false }, - { "auto", SPECTRE_V2_CMD_AUTO, false }, - }; - -@@ -875,17 +918,30 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) - } - - if ((cmd == SPECTRE_V2_CMD_RETPOLINE || -- cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || -- cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && -+ cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || -+ cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC || -+ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || -+ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && - !IS_ENABLED(CONFIG_RETPOLINE)) { -- pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); -+ pr_err("%s selected but not compiled in. Switching to AUTO select\n", -+ mitigation_options[i].option); - return SPECTRE_V2_CMD_AUTO; - } - -- if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD && -- boot_cpu_data.x86_vendor != X86_VENDOR_HYGON && -- boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { -- pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n"); -+ if ((cmd == SPECTRE_V2_CMD_EIBRS || -+ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || -+ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && -+ !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { -+ pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n", -+ mitigation_options[i].option); -+ return SPECTRE_V2_CMD_AUTO; -+ } -+ -+ if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || -+ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) && -+ !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { -+ pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", -+ mitigation_options[i].option); - return SPECTRE_V2_CMD_AUTO; - } - -@@ -894,6 +950,16 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) - return cmd; - } - -+static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void) -+{ -+ if (!IS_ENABLED(CONFIG_RETPOLINE)) { -+ pr_err("Kernel not compiled with retpoline; no mitigation available!"); -+ return SPECTRE_V2_NONE; -+ } -+ -+ return SPECTRE_V2_RETPOLINE; -+} -+ - static void __init spectre_v2_select_mitigation(void) - { - enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); -@@ -914,49 +980,64 @@ static void __init spectre_v2_select_mitigation(void) - case SPECTRE_V2_CMD_FORCE: - case SPECTRE_V2_CMD_AUTO: - if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { -- mode = SPECTRE_V2_IBRS_ENHANCED; -- /* Force it so VMEXIT will restore correctly */ -- x86_spec_ctrl_base |= SPEC_CTRL_IBRS; -- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); -- goto specv2_set_mode; -+ mode = SPECTRE_V2_EIBRS; -+ break; - } -- if (IS_ENABLED(CONFIG_RETPOLINE)) -- goto retpoline_auto; -+ -+ mode = spectre_v2_select_retpoline(); - break; -- case SPECTRE_V2_CMD_RETPOLINE_AMD: -- if (IS_ENABLED(CONFIG_RETPOLINE)) -- goto retpoline_amd; -+ -+ case SPECTRE_V2_CMD_RETPOLINE_LFENCE: -+ pr_err(SPECTRE_V2_LFENCE_MSG); -+ mode = SPECTRE_V2_LFENCE; - break; -+ - case SPECTRE_V2_CMD_RETPOLINE_GENERIC: -- if (IS_ENABLED(CONFIG_RETPOLINE)) -- goto retpoline_generic; -+ mode = SPECTRE_V2_RETPOLINE; - break; -+ - case SPECTRE_V2_CMD_RETPOLINE: -- if (IS_ENABLED(CONFIG_RETPOLINE)) -- goto retpoline_auto; -+ mode = spectre_v2_select_retpoline(); -+ break; -+ -+ case SPECTRE_V2_CMD_EIBRS: -+ mode = SPECTRE_V2_EIBRS; -+ break; -+ -+ case SPECTRE_V2_CMD_EIBRS_LFENCE: -+ mode = SPECTRE_V2_EIBRS_LFENCE; -+ break; -+ -+ case SPECTRE_V2_CMD_EIBRS_RETPOLINE: -+ mode = SPECTRE_V2_EIBRS_RETPOLINE; - break; - } -- pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!"); -- return; - --retpoline_auto: -- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || -- boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { -- retpoline_amd: -- if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { -- pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); -- goto retpoline_generic; -- } -- mode = SPECTRE_V2_RETPOLINE_AMD; -- setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD); -- setup_force_cpu_cap(X86_FEATURE_RETPOLINE); -- } else { -- retpoline_generic: -- mode = SPECTRE_V2_RETPOLINE_GENERIC; -+ if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) -+ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); -+ -+ if (spectre_v2_in_eibrs_mode(mode)) { -+ /* Force it so VMEXIT will restore correctly */ -+ x86_spec_ctrl_base |= SPEC_CTRL_IBRS; -+ wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); -+ } -+ -+ switch (mode) { -+ case SPECTRE_V2_NONE: -+ case SPECTRE_V2_EIBRS: -+ break; -+ -+ case SPECTRE_V2_LFENCE: -+ case SPECTRE_V2_EIBRS_LFENCE: -+ setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE); -+ fallthrough; -+ -+ case SPECTRE_V2_RETPOLINE: -+ case SPECTRE_V2_EIBRS_RETPOLINE: - setup_force_cpu_cap(X86_FEATURE_RETPOLINE); -+ break; - } - --specv2_set_mode: - spectre_v2_enabled = mode; - pr_info("%s\n", spectre_v2_strings[mode]); - -@@ -982,7 +1063,7 @@ specv2_set_mode: - * the CPU supports Enhanced IBRS, kernel might un-intentionally not - * enable IBRS around firmware calls. - */ -- if (boot_cpu_has(X86_FEATURE_IBRS) && mode != SPECTRE_V2_IBRS_ENHANCED) { -+ if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_eibrs_mode(mode)) { - setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); - pr_info("Enabling Restricted Speculation for firmware calls\n"); - } -@@ -1052,6 +1133,10 @@ void cpu_bugs_smt_update(void) - { - mutex_lock(&spec_ctrl_mutex); - -+ if (sched_smt_active() && unprivileged_ebpf_enabled() && -+ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) -+ pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); -+ - switch (spectre_v2_user_stibp) { - case SPECTRE_V2_USER_NONE: - break; -@@ -1691,7 +1776,7 @@ static ssize_t tsx_async_abort_show_state(char *buf) - - static char *stibp_state(void) - { -- if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) -+ if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) - return ""; - - switch (spectre_v2_user_stibp) { -@@ -1721,6 +1806,27 @@ static char *ibpb_state(void) - return ""; - } - -+static ssize_t spectre_v2_show_state(char *buf) -+{ -+ if (spectre_v2_enabled == SPECTRE_V2_LFENCE) -+ return sprintf(buf, "Vulnerable: LFENCE\n"); -+ -+ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) -+ return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n"); -+ -+ if (sched_smt_active() && unprivileged_ebpf_enabled() && -+ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) -+ return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); -+ -+ return sprintf(buf, "%s%s%s%s%s%s\n", -+ spectre_v2_strings[spectre_v2_enabled], -+ ibpb_state(), -+ boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", -+ stibp_state(), -+ boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", -+ spectre_v2_module_string()); -+} -+ - static ssize_t srbds_show_state(char *buf) - { - return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]); -@@ -1746,12 +1852,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr - return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); - - case X86_BUG_SPECTRE_V2: -- return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], -- ibpb_state(), -- boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", -- stibp_state(), -- boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", -- spectre_v2_module_string()); -+ return spectre_v2_show_state(buf); - - case X86_BUG_SPEC_STORE_BYPASS: - return sprintf(buf, "%s\n", ssb_strings[ssb_mode]); -diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c -index b3410f1ac2175..58b1416c05da4 100644 ---- a/arch/x86/kernel/cpu/common.c -+++ b/arch/x86/kernel/cpu/common.c -@@ -1396,9 +1396,8 @@ void __init early_cpu_init(void) - early_identify_cpu(&boot_cpu_data); - } - --static void detect_null_seg_behavior(struct cpuinfo_x86 *c) -+static bool detect_null_seg_behavior(void) - { --#ifdef CONFIG_X86_64 - /* - * Empirically, writing zero to a segment selector on AMD does - * not clear the base, whereas writing zero to a segment -@@ -1419,10 +1418,43 @@ static void detect_null_seg_behavior(struct cpuinfo_x86 *c) - wrmsrl(MSR_FS_BASE, 1); - loadsegment(fs, 0); - rdmsrl(MSR_FS_BASE, tmp); -- if (tmp != 0) -- set_cpu_bug(c, X86_BUG_NULL_SEG); - wrmsrl(MSR_FS_BASE, old_base); --#endif -+ return tmp == 0; -+} -+ -+void check_null_seg_clears_base(struct cpuinfo_x86 *c) -+{ -+ /* BUG_NULL_SEG is only relevant with 64bit userspace */ -+ if (!IS_ENABLED(CONFIG_X86_64)) -+ return; -+ -+ /* Zen3 CPUs advertise Null Selector Clears Base in CPUID. */ -+ if (c->extended_cpuid_level >= 0x80000021 && -+ cpuid_eax(0x80000021) & BIT(6)) -+ return; -+ -+ /* -+ * CPUID bit above wasn't set. If this kernel is still running -+ * as a HV guest, then the HV has decided not to advertize -+ * that CPUID bit for whatever reason. For example, one -+ * member of the migration pool might be vulnerable. Which -+ * means, the bug is present: set the BUG flag and return. -+ */ -+ if (cpu_has(c, X86_FEATURE_HYPERVISOR)) { -+ set_cpu_bug(c, X86_BUG_NULL_SEG); -+ return; -+ } -+ -+ /* -+ * Zen2 CPUs also have this behaviour, but no CPUID bit. -+ * 0x18 is the respective family for Hygon. -+ */ -+ if ((c->x86 == 0x17 || c->x86 == 0x18) && -+ detect_null_seg_behavior()) -+ return; -+ -+ /* All the remaining ones are affected */ -+ set_cpu_bug(c, X86_BUG_NULL_SEG); - } - - static void generic_identify(struct cpuinfo_x86 *c) -@@ -1458,8 +1490,6 @@ static void generic_identify(struct cpuinfo_x86 *c) - - get_model_name(c); /* Default name */ - -- detect_null_seg_behavior(c); -- - /* - * ESPFIX is a strange bug. All real CPUs have it. Paravirt - * systems that run Linux at CPL > 0 may or may not have the -diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h -index 95521302630d4..ee6f23f7587d4 100644 ---- a/arch/x86/kernel/cpu/cpu.h -+++ b/arch/x86/kernel/cpu/cpu.h -@@ -75,6 +75,7 @@ extern int detect_extended_topology_early(struct cpuinfo_x86 *c); - extern int detect_extended_topology(struct cpuinfo_x86 *c); - extern int detect_ht_early(struct cpuinfo_x86 *c); - extern void detect_ht(struct cpuinfo_x86 *c); -+extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); - - unsigned int aperfmperf_get_khz(int cpu); - -diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c -index 6d50136f7ab98..3fcdda4c1e114 100644 ---- a/arch/x86/kernel/cpu/hygon.c -+++ b/arch/x86/kernel/cpu/hygon.c -@@ -335,6 +335,8 @@ static void init_hygon(struct cpuinfo_x86 *c) - /* Hygon CPUs don't reset SS attributes on SYSRET, Xen does. */ - if (!cpu_has(c, X86_FEATURE_XENPV)) - set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); -+ -+ check_null_seg_clears_base(c); - } - - static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c) -diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c -index 08831acc1d036..c0c57bd05f02d 100644 ---- a/arch/x86/kernel/cpu/mce/amd.c -+++ b/arch/x86/kernel/cpu/mce/amd.c -@@ -400,7 +400,7 @@ static void threshold_restart_bank(void *_tr) - u32 hi, lo; - - /* sysfs write might race against an offline operation */ -- if (this_cpu_read(threshold_banks)) -+ if (!this_cpu_read(threshold_banks) && !tr->set_lvt_off) - return; - - rdmsr(tr->b->address, lo, hi); -diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c -index 193204aee8801..e23e74e2f928d 100644 ---- a/arch/x86/kernel/cpu/mce/core.c -+++ b/arch/x86/kernel/cpu/mce/core.c -@@ -295,11 +295,17 @@ static void wait_for_panic(void) - panic("Panicing machine check CPU died"); - } - --static void mce_panic(const char *msg, struct mce *final, char *exp) -+static noinstr void mce_panic(const char *msg, struct mce *final, char *exp) - { -- int apei_err = 0; - struct llist_node *pending; - struct mce_evt_llist *l; -+ int apei_err = 0; -+ -+ /* -+ * Allow instrumentation around external facilities usage. Not that it -+ * matters a whole lot since the machine is going to panic anyway. -+ */ -+ instrumentation_begin(); - - if (!fake_panic) { - /* -@@ -314,7 +320,7 @@ static void mce_panic(const char *msg, struct mce *final, char *exp) - } else { - /* Don't log too much for fake panic */ - if (atomic_inc_return(&mce_fake_panicked) > 1) -- return; -+ goto out; - } - pending = mce_gen_pool_prepare_records(); - /* First print corrected ones that are still unlogged */ -@@ -352,6 +358,9 @@ static void mce_panic(const char *msg, struct mce *final, char *exp) - panic(msg); - } else - pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); -+ -+out: -+ instrumentation_end(); - } - - /* Support code for software error injection */ -@@ -682,7 +691,7 @@ static struct notifier_block mce_default_nb = { - /* - * Read ADDR and MISC registers. - */ --static void mce_read_aux(struct mce *m, int i) -+static noinstr void mce_read_aux(struct mce *m, int i) - { - if (m->status & MCI_STATUS_MISCV) - m->misc = mce_rdmsrl(msr_ops.misc(i)); -@@ -1072,10 +1081,13 @@ static int mce_start(int *no_way_out) - * Synchronize between CPUs after main scanning loop. - * This invokes the bulk of the Monarch processing. - */ --static int mce_end(int order) -+static noinstr int mce_end(int order) - { -- int ret = -1; - u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; -+ int ret = -1; -+ -+ /* Allow instrumentation around external facilities. */ -+ instrumentation_begin(); - - if (!timeout) - goto reset; -@@ -1119,7 +1131,8 @@ static int mce_end(int order) - /* - * Don't reset anything. That's done by the Monarch. - */ -- return 0; -+ ret = 0; -+ goto out; - } - - /* -@@ -1135,6 +1148,10 @@ reset: - * Let others run again. - */ - atomic_set(&mce_executing, 0); -+ -+out: -+ instrumentation_end(); -+ - return ret; - } - -@@ -1454,6 +1471,14 @@ noinstr void do_machine_check(struct pt_regs *regs) - if (worst != MCE_AR_SEVERITY && !kill_current_task) - goto out; - -+ /* -+ * Enable instrumentation around the external facilities like -+ * task_work_add() (via queue_task_work()), fixup_exception() etc. -+ * For now, that is. Fixing this properly would need a lot more involved -+ * reorganization. -+ */ -+ instrumentation_begin(); -+ - /* Fault was in user mode and we need to take some action */ - if ((m.cs & 3) == 3) { - /* If this triggers there is no way to recover. Die hard. */ -@@ -1479,6 +1504,9 @@ noinstr void do_machine_check(struct pt_regs *regs) - if (m.kflags & MCE_IN_KERNEL_COPYIN) - queue_task_work(&m, msg, kill_current_task); - } -+ -+ instrumentation_end(); -+ - out: - mce_wrmsrl(MSR_IA32_MCG_STATUS, 0); - } -diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c -index 0bfc14041bbb4..b63b548497c14 100644 ---- a/arch/x86/kernel/cpu/mce/inject.c -+++ b/arch/x86/kernel/cpu/mce/inject.c -@@ -350,7 +350,7 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf, - char buf[MAX_FLAG_OPT_SIZE], *__buf; - int err; - -- if (cnt > MAX_FLAG_OPT_SIZE) -+ if (!cnt || cnt > MAX_FLAG_OPT_SIZE) - return -EINVAL; - - if (copy_from_user(&buf, ubuf, cnt)) -diff --git a/arch/x86/kernel/cpu/mce/intel.c b/arch/x86/kernel/cpu/mce/intel.c -index acfd5d9f93c68..baafbb37be678 100644 ---- a/arch/x86/kernel/cpu/mce/intel.c -+++ b/arch/x86/kernel/cpu/mce/intel.c -@@ -486,6 +486,7 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) - case INTEL_FAM6_BROADWELL_X: - case INTEL_FAM6_SKYLAKE_X: - case INTEL_FAM6_ICELAKE_X: -+ case INTEL_FAM6_ICELAKE_D: - case INTEL_FAM6_SAPPHIRERAPIDS_X: - case INTEL_FAM6_XEON_PHI_KNL: - case INTEL_FAM6_XEON_PHI_KNM: -@@ -547,12 +548,13 @@ bool intel_filter_mce(struct mce *m) - { - struct cpuinfo_x86 *c = &boot_cpu_data; - -- /* MCE errata HSD131, HSM142, HSW131, BDM48, and HSM142 */ -+ /* MCE errata HSD131, HSM142, HSW131, BDM48, HSM142 and SKX37 */ - if ((c->x86 == 6) && - ((c->x86_model == INTEL_FAM6_HASWELL) || - (c->x86_model == INTEL_FAM6_HASWELL_L) || - (c->x86_model == INTEL_FAM6_BROADWELL) || -- (c->x86_model == INTEL_FAM6_HASWELL_G)) && -+ (c->x86_model == INTEL_FAM6_HASWELL_G) || -+ (c->x86_model == INTEL_FAM6_SKYLAKE_X)) && - (m->bank == 0) && - ((m->status & 0xa0000000ffffffff) == 0x80000000000f0005)) - return true; -diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c -index e095c28d27ae8..ef6316fef99ff 100644 ---- a/arch/x86/kernel/cpu/mshyperv.c -+++ b/arch/x86/kernel/cpu/mshyperv.c -@@ -163,12 +163,22 @@ static uint32_t __init ms_hyperv_platform(void) - cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, - &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); - -- if (eax >= HYPERV_CPUID_MIN && -- eax <= HYPERV_CPUID_MAX && -- !memcmp("Microsoft Hv", hyp_signature, 12)) -- return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; -+ if (eax < HYPERV_CPUID_MIN || eax > HYPERV_CPUID_MAX || -+ memcmp("Microsoft Hv", hyp_signature, 12)) -+ return 0; - -- return 0; -+ /* HYPERCALL and VP_INDEX MSRs are mandatory for all features. */ -+ eax = cpuid_eax(HYPERV_CPUID_FEATURES); -+ if (!(eax & HV_MSR_HYPERCALL_AVAILABLE)) { -+ pr_warn("x86/hyperv: HYPERCALL MSR not available.\n"); -+ return 0; -+ } -+ if (!(eax & HV_MSR_VP_INDEX_AVAILABLE)) { -+ pr_warn("x86/hyperv: VP_INDEX MSR not available.\n"); -+ return 0; -+ } -+ -+ return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; - } - - static unsigned char hv_get_nmi_reason(void) -diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c -index 001808e3901cc..48afe96ae0f0f 100644 ---- a/arch/x86/kernel/cpu/sgx/encl.c -+++ b/arch/x86/kernel/cpu/sgx/encl.c -@@ -410,6 +410,8 @@ void sgx_encl_release(struct kref *ref) - } - - kfree(entry); -+ /* Invoke scheduler to prevent soft lockups. */ -+ cond_resched(); - } - - xa_destroy(&encl->page_array); -diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c -index 63d3de02bbccb..8471a8b9b48e8 100644 ---- a/arch/x86/kernel/cpu/sgx/main.c -+++ b/arch/x86/kernel/cpu/sgx/main.c -@@ -28,8 +28,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ksgxd_waitq); - static LIST_HEAD(sgx_active_page_list); - static DEFINE_SPINLOCK(sgx_reclaimer_lock); - --/* The free page list lock protected variables prepend the lock. */ --static unsigned long sgx_nr_free_pages; -+static atomic_long_t sgx_nr_free_pages = ATOMIC_LONG_INIT(0); - - /* Nodes with one or more EPC sections. */ - static nodemask_t sgx_numa_mask; -@@ -403,14 +402,15 @@ skip: - - spin_lock(&node->lock); - list_add_tail(&epc_page->list, &node->free_page_list); -- sgx_nr_free_pages++; - spin_unlock(&node->lock); -+ atomic_long_inc(&sgx_nr_free_pages); - } - } - - static bool sgx_should_reclaim(unsigned long watermark) - { -- return sgx_nr_free_pages < watermark && !list_empty(&sgx_active_page_list); -+ return atomic_long_read(&sgx_nr_free_pages) < watermark && -+ !list_empty(&sgx_active_page_list); - } - - static int ksgxd(void *p) -@@ -471,9 +471,9 @@ static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid) - - page = list_first_entry(&node->free_page_list, struct sgx_epc_page, list); - list_del_init(&page->list); -- sgx_nr_free_pages--; - - spin_unlock(&node->lock); -+ atomic_long_dec(&sgx_nr_free_pages); - - return page; - } -@@ -625,9 +625,9 @@ void sgx_free_epc_page(struct sgx_epc_page *page) - spin_lock(&node->lock); - - list_add_tail(&page->list, &node->free_page_list); -- sgx_nr_free_pages++; - - spin_unlock(&node->lock); -+ atomic_long_inc(&sgx_nr_free_pages); - } - - static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size, -diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c -index 5601b95944fae..6c5defd6569a3 100644 ---- a/arch/x86/kernel/dumpstack_64.c -+++ b/arch/x86/kernel/dumpstack_64.c -@@ -32,9 +32,15 @@ const char *stack_type_name(enum stack_type type) - { - BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); - -+ if (type == STACK_TYPE_TASK) -+ return "TASK"; -+ - if (type == STACK_TYPE_IRQ) - return "IRQ"; - -+ if (type == STACK_TYPE_SOFTIRQ) -+ return "SOFTIRQ"; -+ - if (type == STACK_TYPE_ENTRY) { - /* - * On 64-bit, we have a generic entry stack that we -diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c -index 391a4e2b86049..8690fab95ae4b 100644 ---- a/arch/x86/kernel/early-quirks.c -+++ b/arch/x86/kernel/early-quirks.c -@@ -515,6 +515,7 @@ static const struct intel_early_ops gen11_early_ops __initconst = { - .stolen_size = gen9_stolen_size, - }; - -+/* Intel integrated GPUs for which we need to reserve "stolen memory" */ - static const struct pci_device_id intel_early_ids[] __initconst = { - INTEL_I830_IDS(&i830_early_ops), - INTEL_I845G_IDS(&i845_early_ops), -@@ -591,6 +592,13 @@ static void __init intel_graphics_quirks(int num, int slot, int func) - u16 device; - int i; - -+ /* -+ * Reserve "stolen memory" for an integrated GPU. If we've already -+ * found one, there's nothing to do for other (discrete) GPUs. -+ */ -+ if (resource_size(&intel_graphics_stolen_res)) -+ return; -+ - device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); - - for (i = 0; i < ARRAY_SIZE(intel_early_ids); i++) { -@@ -703,7 +711,7 @@ static struct chipset early_qrk[] __initdata = { - { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST, - PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, - { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, -- QFLAG_APPLY_ONCE, intel_graphics_quirks }, -+ 0, intel_graphics_quirks }, - /* - * HPET on the current version of the Baytrail platform has accuracy - * problems: it will halt in deep idle state - so we disable it. -diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c -index 66ed317ebc0d3..125cbbe10fefa 100644 ---- a/arch/x86/kernel/fpu/regset.c -+++ b/arch/x86/kernel/fpu/regset.c -@@ -87,11 +87,9 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, - const void *kbuf, const void __user *ubuf) - { - struct fpu *fpu = &target->thread.fpu; -- struct user32_fxsr_struct newstate; -+ struct fxregs_state newstate; - int ret; - -- BUILD_BUG_ON(sizeof(newstate) != sizeof(struct fxregs_state)); -- - if (!cpu_feature_enabled(X86_FEATURE_FXSR)) - return -ENODEV; - -@@ -112,9 +110,10 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, - /* Copy the state */ - memcpy(&fpu->state.fxsave, &newstate, sizeof(newstate)); - -- /* Clear xmm8..15 */ -+ /* Clear xmm8..15 for 32-bit callers */ - BUILD_BUG_ON(sizeof(fpu->state.fxsave.xmm_space) != 16 * 16); -- memset(&fpu->state.fxsave.xmm_space[8], 0, 8 * 16); -+ if (in_ia32_syscall()) -+ memset(&fpu->state.fxsave.xmm_space[8*4], 0, 8 * 16); - - /* Mark FP and SSE as in use when XSAVE is enabled */ - if (use_xsave()) -diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c -index e28f6a5d14f1b..766ffe3ba3137 100644 ---- a/arch/x86/kernel/irq.c -+++ b/arch/x86/kernel/irq.c -@@ -291,8 +291,10 @@ void kvm_set_posted_intr_wakeup_handler(void (*handler)(void)) - { - if (handler) - kvm_posted_intr_wakeup_handler = handler; -- else -+ else { - kvm_posted_intr_wakeup_handler = dummy_handler; -+ synchronize_rcu(); -+ } - } - EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wakeup_handler); - -diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c -index 5e9a34b5bd741..867a341a0c7e8 100644 ---- a/arch/x86/kernel/module.c -+++ b/arch/x86/kernel/module.c -@@ -67,6 +67,7 @@ static unsigned long int get_module_load_offset(void) - - void *module_alloc(unsigned long size) - { -+ gfp_t gfp_mask = GFP_KERNEL; - void *p; - - if (PAGE_ALIGN(size) > MODULES_LEN) -@@ -74,10 +75,10 @@ void *module_alloc(unsigned long size) - - p = __vmalloc_node_range(size, MODULE_ALIGN, - MODULES_VADDR + get_module_load_offset(), -- MODULES_END, GFP_KERNEL, -- PAGE_KERNEL, 0, NUMA_NO_NODE, -+ MODULES_END, gfp_mask, -+ PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE, - __builtin_return_address(0)); -- if (p && (kasan_module_alloc(p, size) < 0)) { -+ if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) { - vfree(p); - return NULL; - } -diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c -index 1d9463e3096b6..f2f733bcb2b95 100644 ---- a/arch/x86/kernel/process.c -+++ b/arch/x86/kernel/process.c -@@ -132,6 +132,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, - frame->ret_addr = (unsigned long) ret_from_fork; - p->thread.sp = (unsigned long) fork_frame; - p->thread.io_bitmap = NULL; -+ p->thread.iopl_warn = 0; - memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); - - #ifdef CONFIG_X86_64 -diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c -index 4c208ea3bd9f3..033d9c6a94689 100644 ---- a/arch/x86/kernel/ptrace.c -+++ b/arch/x86/kernel/ptrace.c -@@ -1224,7 +1224,7 @@ static struct user_regset x86_64_regsets[] __ro_after_init = { - }, - [REGSET_FP] = { - .core_note_type = NT_PRFPREG, -- .n = sizeof(struct user_i387_struct) / sizeof(long), -+ .n = sizeof(struct fxregs_state) / sizeof(long), - .size = sizeof(long), .align = sizeof(long), - .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set - }, -@@ -1271,7 +1271,7 @@ static struct user_regset x86_32_regsets[] __ro_after_init = { - }, - [REGSET_XFP] = { - .core_note_type = NT_PRXFPREG, -- .n = sizeof(struct user32_fxsr_struct) / sizeof(u32), -+ .n = sizeof(struct fxregs_state) / sizeof(u32), - .size = sizeof(u32), .align = sizeof(u32), - .active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set - }, -diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c -index 0a40df66a40de..fa700b46588e0 100644 ---- a/arch/x86/kernel/reboot.c -+++ b/arch/x86/kernel/reboot.c -@@ -113,17 +113,9 @@ void __noreturn machine_real_restart(unsigned int type) - spin_unlock(&rtc_lock); - - /* -- * Switch back to the initial page table. -+ * Switch to the trampoline page table. - */ --#ifdef CONFIG_X86_32 -- load_cr3(initial_page_table); --#else -- write_cr3(real_mode_header->trampoline_pgd); -- -- /* Exiting long mode will fail if CR4.PCIDE is set. */ -- if (boot_cpu_has(X86_FEATURE_PCID)) -- cr4_clear_bits(X86_CR4_PCIDE); --#endif -+ load_trampoline_pgtable(); - - /* Jump to the identity-mapped low memory code */ - #ifdef CONFIG_X86_32 -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 40ed44ead0631..48596f9fddf45 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -713,9 +713,6 @@ static void __init early_reserve_memory(void) - - early_reserve_initrd(); - -- if (efi_enabled(EFI_BOOT)) -- efi_memblock_x86_reserve_range(); -- - memblock_x86_reserve_range_setup_data(); - - reserve_ibft_region(); -@@ -890,6 +887,9 @@ void __init setup_arch(char **cmdline_p) - - parse_early_param(); - -+ if (efi_enabled(EFI_BOOT)) -+ efi_memblock_x86_reserve_range(); -+ - #ifdef CONFIG_MEMORY_HOTPLUG - /* - * Memory used by the kernel cannot be hot-removed because Linux -diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c -index a6895e440bc35..a0064cf77e562 100644 ---- a/arch/x86/kernel/sev.c -+++ b/arch/x86/kernel/sev.c -@@ -46,16 +46,6 @@ static struct ghcb __initdata *boot_ghcb; - struct sev_es_runtime_data { - struct ghcb ghcb_page; - -- /* Physical storage for the per-CPU IST stack of the #VC handler */ -- char ist_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); -- -- /* -- * Physical storage for the per-CPU fall-back stack of the #VC handler. -- * The fall-back stack is used when it is not safe to switch back to the -- * interrupted stack in the #VC entry code. -- */ -- char fallback_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); -- - /* - * Reserve one page per CPU as backup storage for the unencrypted GHCB. - * It is needed when an NMI happens while the #VC handler uses the real -@@ -99,27 +89,6 @@ DEFINE_STATIC_KEY_FALSE(sev_es_enable_key); - /* Needed in vc_early_forward_exception */ - void do_early_exception(struct pt_regs *regs, int trapnr); - --static void __init setup_vc_stacks(int cpu) --{ -- struct sev_es_runtime_data *data; -- struct cpu_entry_area *cea; -- unsigned long vaddr; -- phys_addr_t pa; -- -- data = per_cpu(runtime_data, cpu); -- cea = get_cpu_entry_area(cpu); -- -- /* Map #VC IST stack */ -- vaddr = CEA_ESTACK_BOT(&cea->estacks, VC); -- pa = __pa(data->ist_stack); -- cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); -- -- /* Map VC fall-back stack */ -- vaddr = CEA_ESTACK_BOT(&cea->estacks, VC2); -- pa = __pa(data->fallback_stack); -- cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); --} -- - static __always_inline bool on_vc_stack(struct pt_regs *regs) - { - unsigned long sp = regs->sp; -@@ -325,11 +294,6 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, - char *dst, char *buf, size_t size) - { - unsigned long error_code = X86_PF_PROT | X86_PF_WRITE; -- char __user *target = (char __user *)dst; -- u64 d8; -- u32 d4; -- u16 d2; -- u8 d1; - - /* - * This function uses __put_user() independent of whether kernel or user -@@ -351,26 +315,42 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, - * instructions here would cause infinite nesting. - */ - switch (size) { -- case 1: -+ case 1: { -+ u8 d1; -+ u8 __user *target = (u8 __user *)dst; -+ - memcpy(&d1, buf, 1); - if (__put_user(d1, target)) - goto fault; - break; -- case 2: -+ } -+ case 2: { -+ u16 d2; -+ u16 __user *target = (u16 __user *)dst; -+ - memcpy(&d2, buf, 2); - if (__put_user(d2, target)) - goto fault; - break; -- case 4: -+ } -+ case 4: { -+ u32 d4; -+ u32 __user *target = (u32 __user *)dst; -+ - memcpy(&d4, buf, 4); - if (__put_user(d4, target)) - goto fault; - break; -- case 8: -+ } -+ case 8: { -+ u64 d8; -+ u64 __user *target = (u64 __user *)dst; -+ - memcpy(&d8, buf, 8); - if (__put_user(d8, target)) - goto fault; - break; -+ } - default: - WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); - return ES_UNSUPPORTED; -@@ -393,11 +373,6 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, - char *src, char *buf, size_t size) - { - unsigned long error_code = X86_PF_PROT; -- char __user *s = (char __user *)src; -- u64 d8; -- u32 d4; -- u16 d2; -- u8 d1; - - /* - * This function uses __get_user() independent of whether kernel or user -@@ -419,26 +394,41 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, - * instructions here would cause infinite nesting. - */ - switch (size) { -- case 1: -+ case 1: { -+ u8 d1; -+ u8 __user *s = (u8 __user *)src; -+ - if (__get_user(d1, s)) - goto fault; - memcpy(buf, &d1, 1); - break; -- case 2: -+ } -+ case 2: { -+ u16 d2; -+ u16 __user *s = (u16 __user *)src; -+ - if (__get_user(d2, s)) - goto fault; - memcpy(buf, &d2, 2); - break; -- case 4: -+ } -+ case 4: { -+ u32 d4; -+ u32 __user *s = (u32 __user *)src; -+ - if (__get_user(d4, s)) - goto fault; - memcpy(buf, &d4, 4); - break; -- case 8: -+ } -+ case 8: { -+ u64 d8; -+ u64 __user *s = (u64 __user *)src; - if (__get_user(d8, s)) - goto fault; - memcpy(buf, &d8, 8); - break; -+ } - default: - WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); - return ES_UNSUPPORTED; -@@ -787,7 +777,6 @@ void __init sev_es_init_vc_handling(void) - for_each_possible_cpu(cpu) { - alloc_runtime_data(cpu); - init_ghcb(cpu); -- setup_vc_stacks(cpu); - } - - sev_es_setup_play_dead(); -diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c -index a58800973aed3..5b1984d468227 100644 ---- a/arch/x86/kernel/traps.c -+++ b/arch/x86/kernel/traps.c -@@ -313,17 +313,19 @@ out: - } - - #ifdef CONFIG_VMAP_STACK --__visible void __noreturn handle_stack_overflow(const char *message, -- struct pt_regs *regs, -- unsigned long fault_address) -+__visible void __noreturn handle_stack_overflow(struct pt_regs *regs, -+ unsigned long fault_address, -+ struct stack_info *info) - { -- printk(KERN_EMERG "BUG: stack guard page was hit at %p (stack is %p..%p)\n", -- (void *)fault_address, current->stack, -- (char *)current->stack + THREAD_SIZE - 1); -- die(message, regs, 0); -+ const char *name = stack_type_name(info->type); -+ -+ printk(KERN_EMERG "BUG: %s stack guard page was hit at %p (stack is %p..%p)\n", -+ name, (void *)fault_address, info->begin, info->end); -+ -+ die("stack guard page", regs, 0); - - /* Be absolutely certain we don't return. */ -- panic("%s", message); -+ panic("%s stack guard hit", name); - } - #endif - -@@ -353,6 +355,7 @@ DEFINE_IDTENTRY_DF(exc_double_fault) - - #ifdef CONFIG_VMAP_STACK - unsigned long address = read_cr2(); -+ struct stack_info info; - #endif - - #ifdef CONFIG_X86_ESPFIX64 -@@ -455,10 +458,8 @@ DEFINE_IDTENTRY_DF(exc_double_fault) - * stack even if the actual trigger for the double fault was - * something else. - */ -- if ((unsigned long)task_stack_page(tsk) - 1 - address < PAGE_SIZE) { -- handle_stack_overflow("kernel stack overflow (double-fault)", -- regs, address); -- } -+ if (get_stack_guard_info((void *)address, &info)) -+ handle_stack_overflow(regs, address, &info); - #endif - - pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code); -@@ -528,6 +529,36 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs, - - #define GPFSTR "general protection fault" - -+static bool fixup_iopl_exception(struct pt_regs *regs) -+{ -+ struct thread_struct *t = ¤t->thread; -+ unsigned char byte; -+ unsigned long ip; -+ -+ if (!IS_ENABLED(CONFIG_X86_IOPL_IOPERM) || t->iopl_emul != 3) -+ return false; -+ -+ if (insn_get_effective_ip(regs, &ip)) -+ return false; -+ -+ if (get_user(byte, (const char __user *)ip)) -+ return false; -+ -+ if (byte != 0xfa && byte != 0xfb) -+ return false; -+ -+ if (!t->iopl_warn && printk_ratelimit()) { -+ pr_err("%s[%d] attempts to use CLI/STI, pretending it's a NOP, ip:%lx", -+ current->comm, task_pid_nr(current), ip); -+ print_vma_addr(KERN_CONT " in ", ip); -+ pr_cont("\n"); -+ t->iopl_warn = 1; -+ } -+ -+ regs->ip += 1; -+ return true; -+} -+ - DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) - { - char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR; -@@ -553,6 +584,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) - tsk = current; - - if (user_mode(regs)) { -+ if (fixup_iopl_exception(regs)) -+ goto exit; -+ - tsk->thread.error_code = error_code; - tsk->thread.trap_nr = X86_TRAP_GP; - -@@ -709,7 +743,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r - stack = (unsigned long *)sp; - - if (!get_stack_info_noinstr(stack, current, &info) || info.type == STACK_TYPE_ENTRY || -- info.type >= STACK_TYPE_EXCEPTION_LAST) -+ info.type > STACK_TYPE_EXCEPTION_LAST) - sp = __this_cpu_ist_top_va(VC2); - - sync: -diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c -index 2e076a459a0c0..a698196377be9 100644 ---- a/arch/x86/kernel/tsc.c -+++ b/arch/x86/kernel/tsc.c -@@ -1180,6 +1180,12 @@ void mark_tsc_unstable(char *reason) - - EXPORT_SYMBOL_GPL(mark_tsc_unstable); - -+static void __init tsc_disable_clocksource_watchdog(void) -+{ -+ clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -+ clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -+} -+ - static void __init check_system_tsc_reliable(void) - { - #if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC) -@@ -1196,6 +1202,23 @@ static void __init check_system_tsc_reliable(void) - #endif - if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) - tsc_clocksource_reliable = 1; -+ -+ /* -+ * Disable the clocksource watchdog when the system has: -+ * - TSC running at constant frequency -+ * - TSC which does not stop in C-States -+ * - the TSC_ADJUST register which allows to detect even minimal -+ * modifications -+ * - not more than two sockets. As the number of sockets cannot be -+ * evaluated at the early boot stage where this has to be -+ * invoked, check the number of online memory nodes as a -+ * fallback solution which is an reasonable estimate. -+ */ -+ if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && -+ boot_cpu_has(X86_FEATURE_NONSTOP_TSC) && -+ boot_cpu_has(X86_FEATURE_TSC_ADJUST) && -+ nr_online_nodes <= 2) -+ tsc_disable_clocksource_watchdog(); - } - - /* -@@ -1387,9 +1410,6 @@ static int __init init_tsc_clocksource(void) - if (tsc_unstable) - goto unreg; - -- if (tsc_clocksource_reliable || no_tsc_watchdog) -- clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -- - if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) - clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; - -@@ -1527,7 +1547,7 @@ void __init tsc_init(void) - } - - if (tsc_clocksource_reliable || no_tsc_watchdog) -- clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -+ tsc_disable_clocksource_watchdog(); - - clocksource_register_khz(&clocksource_tsc_early, tsc_khz); - detect_art(); -diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c -index 50a4515fe0ad1..9452dc9664b51 100644 ---- a/arch/x86/kernel/tsc_sync.c -+++ b/arch/x86/kernel/tsc_sync.c -@@ -30,6 +30,7 @@ struct tsc_adjust { - }; - - static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust); -+static struct timer_list tsc_sync_check_timer; - - /* - * TSC's on different sockets may be reset asynchronously. -@@ -77,6 +78,46 @@ void tsc_verify_tsc_adjust(bool resume) - } - } - -+/* -+ * Normally the tsc_sync will be checked every time system enters idle -+ * state, but there is still caveat that a system won't enter idle, -+ * either because it's too busy or configured purposely to not enter -+ * idle. -+ * -+ * So setup a periodic timer (every 10 minutes) to make sure the check -+ * is always on. -+ */ -+ -+#define SYNC_CHECK_INTERVAL (HZ * 600) -+ -+static void tsc_sync_check_timer_fn(struct timer_list *unused) -+{ -+ int next_cpu; -+ -+ tsc_verify_tsc_adjust(false); -+ -+ /* Run the check for all onlined CPUs in turn */ -+ next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask); -+ if (next_cpu >= nr_cpu_ids) -+ next_cpu = cpumask_first(cpu_online_mask); -+ -+ tsc_sync_check_timer.expires += SYNC_CHECK_INTERVAL; -+ add_timer_on(&tsc_sync_check_timer, next_cpu); -+} -+ -+static int __init start_sync_check_timer(void) -+{ -+ if (!cpu_feature_enabled(X86_FEATURE_TSC_ADJUST) || tsc_clocksource_reliable) -+ return 0; -+ -+ timer_setup(&tsc_sync_check_timer, tsc_sync_check_timer_fn, 0); -+ tsc_sync_check_timer.expires = jiffies + SYNC_CHECK_INTERVAL; -+ add_timer(&tsc_sync_check_timer); -+ -+ return 0; -+} -+late_initcall(start_sync_check_timer); -+ - static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval, - unsigned int cpu, bool bootcpu) - { -diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c -index e5a7a10a0164d..17d58740891e2 100644 ---- a/arch/x86/kernel/vm86_32.c -+++ b/arch/x86/kernel/vm86_32.c -@@ -142,6 +142,7 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval) - - user_access_end(); - -+exit_vm86: - preempt_disable(); - tsk->thread.sp0 = vm86->saved_sp0; - tsk->thread.sysenter_cs = __KERNEL_CS; -@@ -161,7 +162,8 @@ Efault_end: - user_access_end(); - Efault: - pr_alert("could not access userspace vm86 info\n"); -- do_exit(SIGSEGV); -+ force_exit_sig(SIGSEGV); -+ goto exit_vm86; - } - - static int do_vm86_irq_handling(int subfunction, int irqnumber); -diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c -index 751aa85a30012..5f1d4a5aa8716 100644 ---- a/arch/x86/kvm/cpuid.c -+++ b/arch/x86/kvm/cpuid.c -@@ -232,6 +232,25 @@ u64 kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu *vcpu) - return rsvd_bits(cpuid_maxphyaddr(vcpu), 63); - } - -+static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2, -+ int nent) -+{ -+ int r; -+ -+ r = kvm_check_cpuid(e2, nent); -+ if (r) -+ return r; -+ -+ kvfree(vcpu->arch.cpuid_entries); -+ vcpu->arch.cpuid_entries = e2; -+ vcpu->arch.cpuid_nent = nent; -+ -+ kvm_update_cpuid_runtime(vcpu); -+ kvm_vcpu_after_set_cpuid(vcpu); -+ -+ return 0; -+} -+ - /* when an old userspace process fills a new kernel module */ - int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, - struct kvm_cpuid *cpuid, -@@ -268,18 +287,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, - e2[i].padding[2] = 0; - } - -- r = kvm_check_cpuid(e2, cpuid->nent); -- if (r) { -+ r = kvm_set_cpuid(vcpu, e2, cpuid->nent); -+ if (r) - kvfree(e2); -- goto out_free_cpuid; -- } -- -- kvfree(vcpu->arch.cpuid_entries); -- vcpu->arch.cpuid_entries = e2; -- vcpu->arch.cpuid_nent = cpuid->nent; -- -- kvm_update_cpuid_runtime(vcpu); -- kvm_vcpu_after_set_cpuid(vcpu); - - out_free_cpuid: - kvfree(e); -@@ -303,20 +313,11 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, - return PTR_ERR(e2); - } - -- r = kvm_check_cpuid(e2, cpuid->nent); -- if (r) { -+ r = kvm_set_cpuid(vcpu, e2, cpuid->nent); -+ if (r) - kvfree(e2); -- return r; -- } -- -- kvfree(vcpu->arch.cpuid_entries); -- vcpu->arch.cpuid_entries = e2; -- vcpu->arch.cpuid_nent = cpuid->nent; - -- kvm_update_cpuid_runtime(vcpu); -- kvm_vcpu_after_set_cpuid(vcpu); -- -- return 0; -+ return r; - } - - int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, -@@ -420,12 +421,13 @@ void kvm_set_cpu_caps(void) - ); - - kvm_cpu_cap_mask(CPUID_7_0_EBX, -- F(FSGSBASE) | F(SGX) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | -- F(BMI2) | F(ERMS) | F(INVPCID) | F(RTM) | 0 /*MPX*/ | F(RDSEED) | -- F(ADX) | F(SMAP) | F(AVX512IFMA) | F(AVX512F) | F(AVX512PF) | -- F(AVX512ER) | F(AVX512CD) | F(CLFLUSHOPT) | F(CLWB) | F(AVX512DQ) | -- F(SHA_NI) | F(AVX512BW) | F(AVX512VL) | 0 /*INTEL_PT*/ -- ); -+ F(FSGSBASE) | F(SGX) | F(BMI1) | F(HLE) | F(AVX2) | -+ F(FDP_EXCPTN_ONLY) | F(SMEP) | F(BMI2) | F(ERMS) | F(INVPCID) | -+ F(RTM) | F(ZERO_FCS_FDS) | 0 /*MPX*/ | F(AVX512F) | -+ F(AVX512DQ) | F(RDSEED) | F(ADX) | F(SMAP) | F(AVX512IFMA) | -+ F(CLFLUSHOPT) | F(CLWB) | 0 /*INTEL_PT*/ | F(AVX512PF) | -+ F(AVX512ER) | F(AVX512CD) | F(SHA_NI) | F(AVX512BW) | -+ F(AVX512VL)); - - kvm_cpu_cap_mask(CPUID_7_ECX, - F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) | -diff --git a/arch/x86/kvm/debugfs.c b/arch/x86/kvm/debugfs.c -index 54a83a7445384..f33c804a922ac 100644 ---- a/arch/x86/kvm/debugfs.c -+++ b/arch/x86/kvm/debugfs.c -@@ -95,6 +95,9 @@ static int kvm_mmu_rmaps_stat_show(struct seq_file *m, void *v) - unsigned int *log[KVM_NR_PAGE_SIZES], *cur; - int i, j, k, l, ret; - -+ if (!kvm_memslots_have_rmaps(kvm)) -+ return 0; -+ - ret = -ENOMEM; - memset(log, 0, sizeof(log)); - for (i = 0; i < KVM_NR_PAGE_SIZES; i++) { -diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c -index d5124b520f761..2092834efba11 100644 ---- a/arch/x86/kvm/hyperv.c -+++ b/arch/x86/kvm/hyperv.c -@@ -1922,11 +1922,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool - - all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; - -+ if (all_cpus) -+ goto check_and_send_ipi; -+ - if (!sparse_banks_len) - goto ret_success; - -- if (!all_cpus && -- kvm_read_guest(kvm, -+ if (kvm_read_guest(kvm, - hc->ingpa + offsetof(struct hv_send_ipi_ex, - vp_set.bank_contents), - sparse_banks, -@@ -1934,6 +1936,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool - return HV_STATUS_INVALID_HYPERCALL_INPUT; - } - -+check_and_send_ipi: - if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) - return HV_STATUS_INVALID_HYPERCALL_INPUT; - -@@ -2022,7 +2025,7 @@ static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result) - { - bool longmode; - -- longmode = is_64_bit_mode(vcpu); -+ longmode = is_64_bit_hypercall(vcpu); - if (longmode) - kvm_rax_write(vcpu, result); - else { -@@ -2171,7 +2174,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) - } - - #ifdef CONFIG_X86_64 -- if (is_64_bit_mode(vcpu)) { -+ if (is_64_bit_hypercall(vcpu)) { - hc.param = kvm_rcx_read(vcpu); - hc.ingpa = kvm_rdx_read(vcpu); - hc.outgpa = kvm_r8_read(vcpu); -diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c -index 8c065da73f8e5..4e0f52660842b 100644 ---- a/arch/x86/kvm/ioapic.c -+++ b/arch/x86/kvm/ioapic.c -@@ -96,7 +96,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, - static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) - { - ioapic->rtc_status.pending_eoi = 0; -- bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID + 1); -+ bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID); - } - - static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); -diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h -index bbd4a5d18b5dc..f1b2b2a6ff4db 100644 ---- a/arch/x86/kvm/ioapic.h -+++ b/arch/x86/kvm/ioapic.h -@@ -39,13 +39,13 @@ struct kvm_vcpu; - - struct dest_map { - /* vcpu bitmap where IRQ has been sent */ -- DECLARE_BITMAP(map, KVM_MAX_VCPU_ID + 1); -+ DECLARE_BITMAP(map, KVM_MAX_VCPU_ID); - - /* - * Vector sent to a given vcpu, only valid when - * the vcpu's bit in map is set - */ -- u8 vectors[KVM_MAX_VCPU_ID + 1]; -+ u8 vectors[KVM_MAX_VCPU_ID]; - }; - - -@@ -81,7 +81,6 @@ struct kvm_ioapic { - unsigned long irq_states[IOAPIC_NUM_PINS]; - struct kvm_io_device dev; - struct kvm *kvm; -- void (*ack_notifier)(void *opaque, int irq); - spinlock_t lock; - struct rtc_status rtc_status; - struct delayed_work eoi_inject; -diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h -index 650642b18d151..c2d7cfe82d004 100644 ---- a/arch/x86/kvm/irq.h -+++ b/arch/x86/kvm/irq.h -@@ -56,7 +56,6 @@ struct kvm_pic { - struct kvm_io_device dev_master; - struct kvm_io_device dev_slave; - struct kvm_io_device dev_elcr; -- void (*ack_notifier)(void *opaque, int irq); - unsigned long irq_states[PIC_NUM_PINS]; - }; - -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index d6ac32f3f650c..91c2dc9f198df 100644 ---- a/arch/x86/kvm/lapic.c -+++ b/arch/x86/kvm/lapic.c -@@ -676,38 +676,32 @@ static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu) - static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) - { - u8 val; -- if (pv_eoi_get_user(vcpu, &val) < 0) { -- printk(KERN_WARNING "Can't read EOI MSR value: 0x%llx\n", -- (unsigned long long)vcpu->arch.pv_eoi.msr_val); -+ if (pv_eoi_get_user(vcpu, &val) < 0) - return false; -- } -+ - return val & KVM_PV_EOI_ENABLED; - } - - static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) - { -- if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) { -- printk(KERN_WARNING "Can't set EOI MSR value: 0x%llx\n", -- (unsigned long long)vcpu->arch.pv_eoi.msr_val); -+ if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) - return; -- } -+ - __set_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); - } - - static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) - { -- if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) { -- printk(KERN_WARNING "Can't clear EOI MSR value: 0x%llx\n", -- (unsigned long long)vcpu->arch.pv_eoi.msr_val); -+ if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) - return; -- } -+ - __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); - } - - static int apic_has_interrupt_for_ppr(struct kvm_lapic *apic, u32 ppr) - { - int highest_irr; -- if (apic->vcpu->arch.apicv_active) -+ if (kvm_x86_ops.sync_pir_to_irr) - highest_irr = static_call(kvm_x86_sync_pir_to_irr)(apic->vcpu); - else - highest_irr = apic_find_highest_irr(apic); -@@ -2629,7 +2623,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) - kvm_apic_set_version(vcpu); - - apic_update_ppr(apic); -- hrtimer_cancel(&apic->lapic_timer.timer); -+ cancel_apic_timer(apic); - apic->lapic_timer.expired_tscdeadline = 0; - apic_update_lvtt(apic); - apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 0cc58901bf7a7..2297dd90fe4a5 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -1592,7 +1592,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) - flush = kvm_handle_gfn_range(kvm, range, kvm_unmap_rmapp); - - if (is_tdp_mmu_enabled(kvm)) -- flush |= kvm_tdp_mmu_unmap_gfn_range(kvm, range, flush); -+ flush = kvm_tdp_mmu_unmap_gfn_range(kvm, range, flush); - - return flush; - } -@@ -2188,10 +2188,10 @@ static void shadow_walk_init_using_root(struct kvm_shadow_walk_iterator *iterato - iterator->shadow_addr = root; - iterator->level = vcpu->arch.mmu->shadow_root_level; - -- if (iterator->level == PT64_ROOT_4LEVEL && -+ if (iterator->level >= PT64_ROOT_4LEVEL && - vcpu->arch.mmu->root_level < PT64_ROOT_4LEVEL && - !vcpu->arch.mmu->direct_map) -- --iterator->level; -+ iterator->level = PT32E_ROOT_LEVEL; - - if (iterator->level == PT32E_ROOT_LEVEL) { - /* -@@ -3579,7 +3579,7 @@ set_root_pgd: - out_unlock: - write_unlock(&vcpu->kvm->mmu_lock); - -- return 0; -+ return r; - } - - static int mmu_alloc_special_roots(struct kvm_vcpu *vcpu) -@@ -3889,12 +3889,23 @@ static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr) - walk_shadow_page_lockless_end(vcpu); - } - -+static u32 alloc_apf_token(struct kvm_vcpu *vcpu) -+{ -+ /* make sure the token value is not 0 */ -+ u32 id = vcpu->arch.apf.id; -+ -+ if (id << 12 == 0) -+ vcpu->arch.apf.id = 1; -+ -+ return (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id; -+} -+ - static bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, - gfn_t gfn) - { - struct kvm_arch_async_pf arch; - -- arch.token = (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id; -+ arch.token = alloc_apf_token(vcpu); - arch.gfn = gfn; - arch.direct_map = vcpu->arch.mmu->direct_map; - arch.cr3 = vcpu->arch.mmu->get_guest_pgd(vcpu); -@@ -4679,6 +4690,7 @@ static union kvm_mmu_extended_role kvm_calc_mmu_role_ext(struct kvm_vcpu *vcpu, - /* PKEY and LA57 are active iff long mode is active. */ - ext.cr4_pke = ____is_efer_lma(regs) && ____is_cr4_pke(regs); - ext.cr4_la57 = ____is_efer_lma(regs) && ____is_cr4_la57(regs); -+ ext.efer_lma = ____is_efer_lma(regs); - } - - ext.valid = 1; -@@ -4851,7 +4863,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, - struct kvm_mmu *context = &vcpu->arch.guest_mmu; - struct kvm_mmu_role_regs regs = { - .cr0 = cr0, -- .cr4 = cr4, -+ .cr4 = cr4 & ~X86_CR4_PKE, - .efer = efer, - }; - union kvm_mmu_role new_role; -@@ -4915,7 +4927,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, - context->direct_map = false; - - update_permission_bitmask(context, true); -- update_pkru_bitmask(context); -+ context->pkru_mask = 0; - reset_rsvds_bits_mask_ept(vcpu, context, execonly); - reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); - } -@@ -5368,7 +5380,7 @@ void kvm_mmu_invalidate_gva(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - - void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva) - { -- kvm_mmu_invalidate_gva(vcpu, vcpu->arch.mmu, gva, INVALID_PAGE); -+ kvm_mmu_invalidate_gva(vcpu, vcpu->arch.walk_mmu, gva, INVALID_PAGE); - ++vcpu->stat.invlpg; - } - EXPORT_SYMBOL_GPL(kvm_mmu_invlpg); -@@ -5473,8 +5485,8 @@ slot_handle_level(struct kvm *kvm, const struct kvm_memory_slot *memslot, - } - - static __always_inline bool --slot_handle_leaf(struct kvm *kvm, const struct kvm_memory_slot *memslot, -- slot_level_handler fn, bool flush_on_yield) -+slot_handle_level_4k(struct kvm *kvm, const struct kvm_memory_slot *memslot, -+ slot_level_handler fn, bool flush_on_yield) - { - return slot_handle_level(kvm, memslot, fn, PG_LEVEL_4K, - PG_LEVEL_4K, flush_on_yield); -@@ -5758,13 +5770,11 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) - for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) - flush = kvm_tdp_mmu_zap_gfn_range(kvm, i, gfn_start, - gfn_end, flush); -- if (flush) -- kvm_flush_remote_tlbs_with_address(kvm, gfn_start, -- gfn_end - gfn_start); - } - - if (flush) -- kvm_flush_remote_tlbs_with_address(kvm, gfn_start, gfn_end); -+ kvm_flush_remote_tlbs_with_address(kvm, gfn_start, -+ gfn_end - gfn_start); - - kvm_dec_notifier_count(kvm, gfn_start, gfn_end); - -@@ -5856,21 +5866,21 @@ restart: - void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, - const struct kvm_memory_slot *slot) - { -- bool flush = false; -- - if (kvm_memslots_have_rmaps(kvm)) { - write_lock(&kvm->mmu_lock); -- flush = slot_handle_leaf(kvm, slot, kvm_mmu_zap_collapsible_spte, true); -- if (flush) -+ /* -+ * Zap only 4k SPTEs since the legacy MMU only supports dirty -+ * logging at a 4k granularity and never creates collapsible -+ * 2m SPTEs during dirty logging. -+ */ -+ if (slot_handle_level_4k(kvm, slot, kvm_mmu_zap_collapsible_spte, true)) - kvm_arch_flush_remote_tlbs_memslot(kvm, slot); - write_unlock(&kvm->mmu_lock); - } - - if (is_tdp_mmu_enabled(kvm)) { - read_lock(&kvm->mmu_lock); -- flush = kvm_tdp_mmu_zap_collapsible_sptes(kvm, slot, flush); -- if (flush) -- kvm_arch_flush_remote_tlbs_memslot(kvm, slot); -+ kvm_tdp_mmu_zap_collapsible_sptes(kvm, slot); - read_unlock(&kvm->mmu_lock); - } - } -@@ -5897,8 +5907,11 @@ void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, - - if (kvm_memslots_have_rmaps(kvm)) { - write_lock(&kvm->mmu_lock); -- flush = slot_handle_leaf(kvm, memslot, __rmap_clear_dirty, -- false); -+ /* -+ * Clear dirty bits only on 4k SPTEs since the legacy MMU only -+ * support dirty logging at a 4k granularity. -+ */ -+ flush = slot_handle_level_4k(kvm, memslot, __rmap_clear_dirty, false); - write_unlock(&kvm->mmu_lock); - } - -diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h -index eb7b227fc6cfe..31d6456d8ac33 100644 ---- a/arch/x86/kvm/mmu/spte.h -+++ b/arch/x86/kvm/mmu/spte.h -@@ -310,12 +310,7 @@ static inline bool __is_bad_mt_xwr(struct rsvd_bits_validate *rsvd_check, - static __always_inline bool is_rsvd_spte(struct rsvd_bits_validate *rsvd_check, - u64 spte, int level) - { -- /* -- * Use a bitwise-OR instead of a logical-OR to aggregate the reserved -- * bits and EPT's invalid memtype/XWR checks to avoid an extra Jcc -- * (this is extremely unlikely to be short-circuited as true). -- */ -- return __is_bad_mt_xwr(rsvd_check, spte) | -+ return __is_bad_mt_xwr(rsvd_check, spte) || - __is_rsvd_bits_set(rsvd_check, spte, level); - } - -diff --git a/arch/x86/kvm/mmu/tdp_iter.c b/arch/x86/kvm/mmu/tdp_iter.c -index b3ed302c1a359..caa96c270b954 100644 ---- a/arch/x86/kvm/mmu/tdp_iter.c -+++ b/arch/x86/kvm/mmu/tdp_iter.c -@@ -26,6 +26,7 @@ static gfn_t round_gfn_for_level(gfn_t gfn, int level) - */ - void tdp_iter_restart(struct tdp_iter *iter) - { -+ iter->yielded = false; - iter->yielded_gfn = iter->next_last_level_gfn; - iter->level = iter->root_level; - -@@ -160,6 +161,11 @@ static bool try_step_up(struct tdp_iter *iter) - */ - void tdp_iter_next(struct tdp_iter *iter) - { -+ if (iter->yielded) { -+ tdp_iter_restart(iter); -+ return; -+ } -+ - if (try_step_down(iter)) - return; - -diff --git a/arch/x86/kvm/mmu/tdp_iter.h b/arch/x86/kvm/mmu/tdp_iter.h -index b1748b988d3ae..e19cabbcb65c8 100644 ---- a/arch/x86/kvm/mmu/tdp_iter.h -+++ b/arch/x86/kvm/mmu/tdp_iter.h -@@ -45,6 +45,12 @@ struct tdp_iter { - * iterator walks off the end of the paging structure. - */ - bool valid; -+ /* -+ * True if KVM dropped mmu_lock and yielded in the middle of a walk, in -+ * which case tdp_iter_next() needs to restart the walk at the root -+ * level instead of advancing to the next entry. -+ */ -+ bool yielded; - }; - - /* -diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c -index 64ccfc1fa5535..d479b2b121259 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.c -+++ b/arch/x86/kvm/mmu/tdp_mmu.c -@@ -316,9 +316,6 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, - struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(pt)); - int level = sp->role.level; - gfn_t base_gfn = sp->gfn; -- u64 old_child_spte; -- u64 *sptep; -- gfn_t gfn; - int i; - - trace_kvm_mmu_prepare_zap_page(sp); -@@ -326,8 +323,9 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, - tdp_mmu_unlink_page(kvm, sp, shared); - - for (i = 0; i < PT64_ENT_PER_PAGE; i++) { -- sptep = rcu_dereference(pt) + i; -- gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); -+ u64 *sptep = rcu_dereference(pt) + i; -+ gfn_t gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); -+ u64 old_child_spte; - - if (shared) { - /* -@@ -373,7 +371,7 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, - shared); - } - -- kvm_flush_remote_tlbs_with_address(kvm, gfn, -+ kvm_flush_remote_tlbs_with_address(kvm, base_gfn, - KVM_PAGES_PER_HPAGE(level + 1)); - - call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback); -@@ -503,6 +501,8 @@ static inline bool tdp_mmu_set_spte_atomic_no_dirty_log(struct kvm *kvm, - struct tdp_iter *iter, - u64 new_spte) - { -+ WARN_ON_ONCE(iter->yielded); -+ - lockdep_assert_held_read(&kvm->mmu_lock); - - /* -@@ -613,6 +613,8 @@ static inline void __tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, - u64 new_spte, bool record_acc_track, - bool record_dirty_log) - { -+ WARN_ON_ONCE(iter->yielded); -+ - lockdep_assert_held_write(&kvm->mmu_lock); - - /* -@@ -678,18 +680,19 @@ static inline void tdp_mmu_set_spte_no_dirty_log(struct kvm *kvm, - * If this function should yield and flush is set, it will perform a remote - * TLB flush before yielding. - * -- * If this function yields, it will also reset the tdp_iter's walk over the -- * paging structure and the calling function should skip to the next -- * iteration to allow the iterator to continue its traversal from the -- * paging structure root. -+ * If this function yields, iter->yielded is set and the caller must skip to -+ * the next iteration, where tdp_iter_next() will reset the tdp_iter's walk -+ * over the paging structures to allow the iterator to continue its traversal -+ * from the paging structure root. - * -- * Return true if this function yielded and the iterator's traversal was reset. -- * Return false if a yield was not needed. -+ * Returns true if this function yielded. - */ --static inline bool tdp_mmu_iter_cond_resched(struct kvm *kvm, -- struct tdp_iter *iter, bool flush, -- bool shared) -+static inline bool __must_check tdp_mmu_iter_cond_resched(struct kvm *kvm, -+ struct tdp_iter *iter, -+ bool flush, bool shared) - { -+ WARN_ON(iter->yielded); -+ - /* Ensure forward progress has been made before yielding. */ - if (iter->next_last_level_gfn == iter->yielded_gfn) - return false; -@@ -709,12 +712,10 @@ static inline bool tdp_mmu_iter_cond_resched(struct kvm *kvm, - - WARN_ON(iter->gfn > iter->next_last_level_gfn); - -- tdp_iter_restart(iter); -- -- return true; -+ iter->yielded = true; - } - -- return false; -+ return iter->yielded; - } - - /* -@@ -1083,8 +1084,8 @@ bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, - struct kvm_mmu_page *root; - - for_each_tdp_mmu_root(kvm, root, range->slot->as_id) -- flush |= zap_gfn_range(kvm, root, range->start, range->end, -- range->may_block, flush, false); -+ flush = zap_gfn_range(kvm, root, range->start, range->end, -+ range->may_block, flush, false); - - return flush; - } -@@ -1415,10 +1416,9 @@ void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, - * Clear leaf entries which could be replaced by large mappings, for - * GFNs within the slot. - */ --static bool zap_collapsible_spte_range(struct kvm *kvm, -+static void zap_collapsible_spte_range(struct kvm *kvm, - struct kvm_mmu_page *root, -- const struct kvm_memory_slot *slot, -- bool flush) -+ const struct kvm_memory_slot *slot) - { - gfn_t start = slot->base_gfn; - gfn_t end = start + slot->npages; -@@ -1429,10 +1429,8 @@ static bool zap_collapsible_spte_range(struct kvm *kvm, - - tdp_root_for_each_pte(iter, root, start, end) { - retry: -- if (tdp_mmu_iter_cond_resched(kvm, &iter, flush, true)) { -- flush = false; -+ if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true)) - continue; -- } - - if (!is_shadow_present_pte(iter.old_spte) || - !is_last_spte(iter.old_spte, iter.level)) -@@ -1444,6 +1442,7 @@ retry: - pfn, PG_LEVEL_NUM)) - continue; - -+ /* Note, a successful atomic zap also does a remote TLB flush. */ - if (!tdp_mmu_zap_spte_atomic(kvm, &iter)) { - /* - * The iter must explicitly re-read the SPTE because -@@ -1452,30 +1451,24 @@ retry: - iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep)); - goto retry; - } -- flush = true; - } - - rcu_read_unlock(); -- -- return flush; - } - - /* - * Clear non-leaf entries (and free associated page tables) which could - * be replaced by large mappings, for GFNs within the slot. - */ --bool kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, -- const struct kvm_memory_slot *slot, -- bool flush) -+void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, -+ const struct kvm_memory_slot *slot) - { - struct kvm_mmu_page *root; - - lockdep_assert_held_read(&kvm->mmu_lock); - - for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true) -- flush = zap_collapsible_spte_range(kvm, root, slot, flush); -- -- return flush; -+ zap_collapsible_spte_range(kvm, root, slot); - } - - /* -@@ -1500,12 +1493,12 @@ static bool write_protect_gfn(struct kvm *kvm, struct kvm_mmu_page *root, - !is_last_spte(iter.old_spte, iter.level)) - continue; - -- if (!is_writable_pte(iter.old_spte)) -- break; -- - new_spte = iter.old_spte & - ~(PT_WRITABLE_MASK | shadow_mmu_writable_mask); - -+ if (new_spte == iter.old_spte) -+ break; -+ - tdp_mmu_set_spte(kvm, &iter, new_spte); - spte_set = true; - } -diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h -index 358f447d40120..ba3681cd38ab4 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.h -+++ b/arch/x86/kvm/mmu/tdp_mmu.h -@@ -66,9 +66,8 @@ void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, - struct kvm_memory_slot *slot, - gfn_t gfn, unsigned long mask, - bool wrprot); --bool kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, -- const struct kvm_memory_slot *slot, -- bool flush); -+void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, -+ const struct kvm_memory_slot *slot); - - bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, - struct kvm_memory_slot *slot, gfn_t gfn, -diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c -index 0772bad9165c5..f256f01056bdb 100644 ---- a/arch/x86/kvm/pmu.c -+++ b/arch/x86/kvm/pmu.c -@@ -95,7 +95,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event, - } - - static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type, -- unsigned config, bool exclude_user, -+ u64 config, bool exclude_user, - bool exclude_kernel, bool intr, - bool in_tx, bool in_tx_cp) - { -@@ -173,8 +173,8 @@ static bool pmc_resume_counter(struct kvm_pmc *pmc) - - void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) - { -- unsigned config, type = PERF_TYPE_RAW; -- u8 event_select, unit_mask; -+ u64 config; -+ u32 type = PERF_TYPE_RAW; - struct kvm *kvm = pmc->vcpu->kvm; - struct kvm_pmu_event_filter *filter; - int i; -@@ -206,23 +206,18 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) - if (!allow_event) - return; - -- event_select = eventsel & ARCH_PERFMON_EVENTSEL_EVENT; -- unit_mask = (eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; -- - if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE | - ARCH_PERFMON_EVENTSEL_INV | - ARCH_PERFMON_EVENTSEL_CMASK | - HSW_IN_TX | - HSW_IN_TX_CHECKPOINTED))) { -- config = kvm_x86_ops.pmu_ops->find_arch_event(pmc_to_pmu(pmc), -- event_select, -- unit_mask); -+ config = kvm_x86_ops.pmu_ops->pmc_perf_hw_id(pmc); - if (config != PERF_COUNT_HW_MAX) - type = PERF_TYPE_HARDWARE; - } - - if (type == PERF_TYPE_RAW) -- config = eventsel & X86_RAW_EVENT_MASK; -+ config = eventsel & AMD64_RAW_EVENT_MASK; - - if (pmc->current_config == eventsel && pmc_resume_counter(pmc)) - return; -diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h -index 0e4f2b1fa9fbd..a06d95165ac7c 100644 ---- a/arch/x86/kvm/pmu.h -+++ b/arch/x86/kvm/pmu.h -@@ -24,8 +24,7 @@ struct kvm_event_hw_type_mapping { - }; - - struct kvm_pmu_ops { -- unsigned (*find_arch_event)(struct kvm_pmu *pmu, u8 event_select, -- u8 unit_mask); -+ unsigned int (*pmc_perf_hw_id)(struct kvm_pmc *pmc); - unsigned (*find_fixed_event)(int idx); - bool (*pmc_is_enabled)(struct kvm_pmc *pmc); - struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx); -diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c -index 8052d92069e01..cdbb48e12745c 100644 ---- a/arch/x86/kvm/svm/avic.c -+++ b/arch/x86/kvm/svm/avic.c -@@ -342,8 +342,6 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu) - avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh); - break; - case AVIC_IPI_FAILURE_INVALID_TARGET: -- WARN_ONCE(1, "Invalid IPI target: index=%u, vcpu=%d, icr=%#0x:%#0x\n", -- index, vcpu->vcpu_id, icrh, icrl); - break; - case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE: - WARN_ONCE(1, "Invalid backing page\n"); -@@ -988,16 +986,18 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu) - static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run) - { - struct vcpu_svm *svm = to_svm(vcpu); -+ int cpu = get_cpu(); - -+ WARN_ON(cpu != vcpu->cpu); - svm->avic_is_running = is_run; - -- if (!kvm_vcpu_apicv_active(vcpu)) -- return; -- -- if (is_run) -- avic_vcpu_load(vcpu, vcpu->cpu); -- else -- avic_vcpu_put(vcpu); -+ if (kvm_vcpu_apicv_active(vcpu)) { -+ if (is_run) -+ avic_vcpu_load(vcpu, cpu); -+ else -+ avic_vcpu_put(vcpu); -+ } -+ put_cpu(); - } - - void svm_vcpu_blocking(struct kvm_vcpu *vcpu) -diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c -index 510b833cbd399..556e7a3f35627 100644 ---- a/arch/x86/kvm/svm/nested.c -+++ b/arch/x86/kvm/svm/nested.c -@@ -942,9 +942,9 @@ void svm_free_nested(struct vcpu_svm *svm) - /* - * Forcibly leave nested mode in order to be able to reset the VCPU later on. - */ --void svm_leave_nested(struct vcpu_svm *svm) -+void svm_leave_nested(struct kvm_vcpu *vcpu) - { -- struct kvm_vcpu *vcpu = &svm->vcpu; -+ struct vcpu_svm *svm = to_svm(vcpu); - - if (is_guest_mode(vcpu)) { - svm->nested.nested_run_pending = 0; -@@ -1313,7 +1313,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, - return -EINVAL; - - if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) { -- svm_leave_nested(svm); -+ svm_leave_nested(vcpu); - svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET)); - return 0; - } -@@ -1357,18 +1357,6 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, - !nested_vmcb_valid_sregs(vcpu, save)) - goto out_free; - -- /* -- * While the nested guest CR3 is already checked and set by -- * KVM_SET_SREGS, it was set when nested state was yet loaded, -- * thus MMU might not be initialized correctly. -- * Set it again to fix this. -- */ -- -- ret = nested_svm_load_cr3(&svm->vcpu, vcpu->arch.cr3, -- nested_npt_enabled(svm), false); -- if (WARN_ON_ONCE(ret)) -- goto out_free; -- - - /* - * All checks done, we can enter guest mode. Userspace provides -@@ -1378,7 +1366,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, - */ - - if (is_guest_mode(vcpu)) -- svm_leave_nested(svm); -+ svm_leave_nested(vcpu); - else - svm->nested.vmcb02.ptr->save = svm->vmcb01.ptr->save; - -@@ -1394,6 +1382,20 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, - - svm_switch_vmcb(svm, &svm->nested.vmcb02); - nested_vmcb02_prepare_control(svm); -+ -+ /* -+ * While the nested guest CR3 is already checked and set by -+ * KVM_SET_SREGS, it was set when nested state was yet loaded, -+ * thus MMU might not be initialized correctly. -+ * Set it again to fix this. -+ */ -+ -+ ret = nested_svm_load_cr3(&svm->vcpu, vcpu->arch.cr3, -+ nested_npt_enabled(svm), false); -+ if (WARN_ON_ONCE(ret)) -+ goto out_free; -+ -+ - kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); - ret = 0; - out_free: -@@ -1432,6 +1434,7 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) - } - - struct kvm_x86_nested_ops svm_nested_ops = { -+ .leave_nested = svm_leave_nested, - .check_events = svm_check_nested_events, - .triple_fault = nested_svm_triple_fault, - .get_nested_state_pages = svm_get_nested_state_pages, -diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c -index fdf587f19c5fb..06f8034f62e4f 100644 ---- a/arch/x86/kvm/svm/pmu.c -+++ b/arch/x86/kvm/svm/pmu.c -@@ -134,10 +134,10 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, - return &pmu->gp_counters[msr_to_index(msr)]; - } - --static unsigned amd_find_arch_event(struct kvm_pmu *pmu, -- u8 event_select, -- u8 unit_mask) -+static unsigned int amd_pmc_perf_hw_id(struct kvm_pmc *pmc) - { -+ u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT; -+ u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; - int i; - - for (i = 0; i < ARRAY_SIZE(amd_event_mapping); i++) -@@ -282,7 +282,7 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu) - pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS; - - pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1; -- pmu->reserved_bits = 0xffffffff00200000ull; -+ pmu->reserved_bits = 0xfffffff000280000ull; - pmu->version = 1; - /* not applicable to AMD; but clean them to prevent any fall out */ - pmu->counter_bitmask[KVM_PMC_FIXED] = 0; -@@ -320,7 +320,7 @@ static void amd_pmu_reset(struct kvm_vcpu *vcpu) - } - - struct kvm_pmu_ops amd_pmu_ops = { -- .find_arch_event = amd_find_arch_event, -+ .pmc_perf_hw_id = amd_pmc_perf_hw_id, - .find_fixed_event = amd_find_fixed_event, - .pmc_is_enabled = amd_pmc_is_enabled, - .pmc_idx_to_pmc = amd_pmc_idx_to_pmc, -diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c -index 7e34d7163adab..134c4ea5e6ad8 100644 ---- a/arch/x86/kvm/svm/sev.c -+++ b/arch/x86/kvm/svm/sev.c -@@ -1787,7 +1787,12 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd) - mutex_unlock(&source_kvm->lock); - mutex_lock(&kvm->lock); - -- if (sev_guest(kvm)) { -+ /* -+ * Disallow out-of-band SEV/SEV-ES init if the target is already an -+ * SEV guest, or if vCPUs have been created. KVM relies on vCPUs being -+ * created after SEV/SEV-ES initialization, e.g. to init intercepts. -+ */ -+ if (sev_guest(kvm) || kvm->created_vcpus) { - ret = -EINVAL; - goto e_mirror_unlock; - } -@@ -1800,6 +1805,7 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd) - mirror_sev->fd = source_sev.fd; - mirror_sev->es_active = source_sev.es_active; - mirror_sev->handle = source_sev.handle; -+ INIT_LIST_HEAD(&mirror_sev->regions_list); - /* - * Do not copy ap_jump_table. Since the mirror does not share the same - * KVM contexts as the original, and they may have different -@@ -2311,7 +2317,7 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) - } - - #define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE) --static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) -+static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) - { - struct vmcb_control_area *control = &svm->vmcb->control; - struct ghcb *ghcb = svm->ghcb; -@@ -2322,14 +2328,14 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) - scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); - if (!scratch_gpa_beg) { - pr_err("vmgexit: scratch gpa not provided\n"); -- return false; -+ return -EINVAL; - } - - scratch_gpa_end = scratch_gpa_beg + len; - if (scratch_gpa_end < scratch_gpa_beg) { - pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n", - len, scratch_gpa_beg); -- return false; -+ return -EINVAL; - } - - if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) { -@@ -2347,7 +2353,7 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) - scratch_gpa_end > ghcb_scratch_end) { - pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n", - scratch_gpa_beg, scratch_gpa_end); -- return false; -+ return -EINVAL; - } - - scratch_va = (void *)svm->ghcb; -@@ -2360,18 +2366,18 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) - if (len > GHCB_SCRATCH_AREA_LIMIT) { - pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n", - len, GHCB_SCRATCH_AREA_LIMIT); -- return false; -+ return -EINVAL; - } - scratch_va = kzalloc(len, GFP_KERNEL_ACCOUNT); - if (!scratch_va) -- return false; -+ return -ENOMEM; - - if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) { - /* Unable to copy scratch area from guest */ - pr_err("vmgexit: kvm_read_guest for scratch area failed\n"); - - kfree(scratch_va); -- return false; -+ return -EFAULT; - } - - /* -@@ -2387,7 +2393,7 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) - svm->ghcb_sa = scratch_va; - svm->ghcb_sa_len = len; - -- return true; -+ return 0; - } - - static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask, -@@ -2526,10 +2532,10 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) - ghcb_set_sw_exit_info_1(ghcb, 0); - ghcb_set_sw_exit_info_2(ghcb, 0); - -- ret = -EINVAL; - switch (exit_code) { - case SVM_VMGEXIT_MMIO_READ: -- if (!setup_vmgexit_scratch(svm, true, control->exit_info_2)) -+ ret = setup_vmgexit_scratch(svm, true, control->exit_info_2); -+ if (ret) - break; - - ret = kvm_sev_es_mmio_read(vcpu, -@@ -2538,7 +2544,8 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) - svm->ghcb_sa); - break; - case SVM_VMGEXIT_MMIO_WRITE: -- if (!setup_vmgexit_scratch(svm, false, control->exit_info_2)) -+ ret = setup_vmgexit_scratch(svm, false, control->exit_info_2); -+ if (ret) - break; - - ret = kvm_sev_es_mmio_write(vcpu, -@@ -2581,6 +2588,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) - vcpu_unimpl(vcpu, - "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n", - control->exit_info_1, control->exit_info_2); -+ ret = -EINVAL; - break; - default: - ret = svm_invoke_exit_handler(vcpu, exit_code); -@@ -2593,6 +2601,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) - { - int count; - int bytes; -+ int r; - - if (svm->vmcb->control.exit_info_2 > INT_MAX) - return -EINVAL; -@@ -2601,8 +2610,9 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) - if (unlikely(check_mul_overflow(count, size, &bytes))) - return -EINVAL; - -- if (!setup_vmgexit_scratch(svm, in, bytes)) -- return -EINVAL; -+ r = setup_vmgexit_scratch(svm, in, bytes); -+ if (r) -+ return r; - - return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->ghcb_sa, count, in); - } -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index 989685098b3ea..26f2da1590eda 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -281,7 +281,7 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) - - if ((old_efer & EFER_SVME) != (efer & EFER_SVME)) { - if (!(efer & EFER_SVME)) { -- svm_leave_nested(svm); -+ svm_leave_nested(vcpu); - svm_set_gif(svm, true); - /* #GP intercept is still needed for vmware backdoor */ - if (!enable_vmware_backdoor) -@@ -303,7 +303,11 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) - return ret; - } - -- if (svm_gp_erratum_intercept) -+ /* -+ * Never intercept #GP for SEV guests, KVM can't -+ * decrypt guest memory to workaround the erratum. -+ */ -+ if (svm_gp_erratum_intercept && !sev_guest(vcpu->kvm)) - set_exception_intercept(svm, GP_VECTOR); - } - } -@@ -1176,9 +1180,10 @@ static void init_vmcb(struct kvm_vcpu *vcpu) - * Guest access to VMware backdoor ports could legitimately - * trigger #GP because of TSS I/O permission bitmap. - * We intercept those #GP and allow access to them anyway -- * as VMware does. -+ * as VMware does. Don't intercept #GP for SEV guests as KVM can't -+ * decrypt guest memory to decode the faulting instruction. - */ -- if (enable_vmware_backdoor) -+ if (enable_vmware_backdoor && !sev_guest(vcpu->kvm)) - set_exception_intercept(svm, GP_VECTOR); - - svm_set_intercept(svm, INTERCEPT_INTR); -@@ -1517,6 +1522,15 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) - to_svm(vcpu)->vmcb->save.rflags = rflags; - } - -+static bool svm_get_if_flag(struct kvm_vcpu *vcpu) -+{ -+ struct vmcb *vmcb = to_svm(vcpu)->vmcb; -+ -+ return sev_es_guest(vcpu->kvm) -+ ? vmcb->control.int_state & SVM_GUEST_INTERRUPT_MASK -+ : kvm_get_rflags(vcpu) & X86_EFLAGS_IF; -+} -+ - static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) - { - switch (reg) { -@@ -1713,6 +1727,7 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) - { - struct vcpu_svm *svm = to_svm(vcpu); - u64 hcr0 = cr0; -+ bool old_paging = is_paging(vcpu); - - #ifdef CONFIG_X86_64 - if (vcpu->arch.efer & EFER_LME && !vcpu->arch.guest_state_protected) { -@@ -1729,8 +1744,11 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) - #endif - vcpu->arch.cr0 = cr0; - -- if (!npt_enabled) -+ if (!npt_enabled) { - hcr0 |= X86_CR0_PG | X86_CR0_WP; -+ if (old_paging != is_paging(vcpu)) -+ svm_set_cr4(vcpu, kvm_read_cr4(vcpu)); -+ } - - /* - * re-enable caching here because the QEMU bios -@@ -1774,8 +1792,12 @@ void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) - svm_flush_tlb(vcpu); - - vcpu->arch.cr4 = cr4; -- if (!npt_enabled) -+ if (!npt_enabled) { - cr4 |= X86_CR4_PAE; -+ -+ if (!is_paging(vcpu)) -+ cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE); -+ } - cr4 |= host_cr4_mce; - to_svm(vcpu)->vmcb->save.cr4 = cr4; - vmcb_mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR); -@@ -2224,10 +2246,6 @@ static int gp_interception(struct kvm_vcpu *vcpu) - if (error_code) - goto reinject; - -- /* All SVM instructions expect page aligned RAX */ -- if (svm->vmcb->save.rax & ~PAGE_MASK) -- goto reinject; -- - /* Decode the instruction for usage later */ - if (x86_decode_emulated_instruction(vcpu, 0, NULL, 0) != EMULATION_OK) - goto reinject; -@@ -2245,8 +2263,13 @@ static int gp_interception(struct kvm_vcpu *vcpu) - if (!is_guest_mode(vcpu)) - return kvm_emulate_instruction(vcpu, - EMULTYPE_VMWARE_GP | EMULTYPE_NO_DECODE); -- } else -+ } else { -+ /* All SVM instructions expect page aligned RAX */ -+ if (svm->vmcb->save.rax & ~PAGE_MASK) -+ goto reinject; -+ - return emulate_svm_instr(vcpu, opcode); -+ } - - reinject: - kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); -@@ -3485,14 +3508,7 @@ bool svm_interrupt_blocked(struct kvm_vcpu *vcpu) - if (!gif_set(svm)) - return true; - -- if (sev_es_guest(vcpu->kvm)) { -- /* -- * SEV-ES guests to not expose RFLAGS. Use the VMCB interrupt mask -- * bit to determine the state of the IF flag. -- */ -- if (!(vmcb->control.int_state & SVM_GUEST_INTERRUPT_MASK)) -- return true; -- } else if (is_guest_mode(vcpu)) { -+ if (is_guest_mode(vcpu)) { - /* As long as interrupts are being delivered... */ - if ((svm->nested.ctl.int_ctl & V_INTR_MASKING_MASK) - ? !(svm->vmcb01.ptr->save.rflags & X86_EFLAGS_IF) -@@ -3503,7 +3519,7 @@ bool svm_interrupt_blocked(struct kvm_vcpu *vcpu) - if (nested_exit_on_intr(svm)) - return false; - } else { -- if (!(kvm_get_rflags(vcpu) & X86_EFLAGS_IF)) -+ if (!svm_get_if_flag(vcpu)) - return true; - } - -@@ -4376,10 +4392,17 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const char *smstate) - * Enter the nested guest now - */ - -+ vmcb_mark_all_dirty(svm->vmcb01.ptr); -+ - vmcb12 = map.hva; - nested_load_control_from_vmcb12(svm, &vmcb12->control); - ret = enter_svm_guest_mode(vcpu, vmcb12_gpa, vmcb12, false); - -+ if (ret) -+ goto unmap_save; -+ -+ svm->nested.nested_run_pending = 1; -+ - unmap_save: - kvm_vcpu_unmap(vcpu, &map_save, true); - unmap_map: -@@ -4405,8 +4428,13 @@ static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int i - bool smep, smap, is_user; - unsigned long cr4; - -+ /* Emulation is always possible when KVM has access to all guest state. */ -+ if (!sev_guest(vcpu->kvm)) -+ return true; -+ - /* -- * When the guest is an SEV-ES guest, emulation is not possible. -+ * Emulation is impossible for SEV-ES guests as KVM doesn't have access -+ * to guest register state. - */ - if (sev_es_guest(vcpu->kvm)) - return false; -@@ -4454,23 +4482,27 @@ static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int i - if (likely(!insn || insn_len)) - return true; - -- /* -- * If RIP is invalid, go ahead with emulation which will cause an -- * internal error exit. -- */ -- if (!kvm_vcpu_gfn_to_memslot(vcpu, kvm_rip_read(vcpu) >> PAGE_SHIFT)) -- return true; -- - cr4 = kvm_read_cr4(vcpu); - smep = cr4 & X86_CR4_SMEP; - smap = cr4 & X86_CR4_SMAP; - is_user = svm_get_cpl(vcpu) == 3; - if (smap && (!smep || is_user)) { -- if (!sev_guest(vcpu->kvm)) -- return true; -- - pr_err_ratelimited("KVM: SEV Guest triggered AMD Erratum 1096\n"); -- kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); -+ -+ /* -+ * If the fault occurred in userspace, arbitrarily inject #GP -+ * to avoid killing the guest and to hopefully avoid confusing -+ * the guest kernel too much, e.g. injecting #PF would not be -+ * coherent with respect to the guest's page tables. Request -+ * triple fault if the fault occurred in the kernel as there's -+ * no fault that KVM can inject without confusing the guest. -+ * In practice, the triple fault is moot as no sane SEV kernel -+ * will execute from user memory while also running with SMAP=1. -+ */ -+ if (is_user) -+ kvm_inject_gp(vcpu, 0); -+ else -+ kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); - } - - return false; -@@ -4562,6 +4594,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { - .cache_reg = svm_cache_reg, - .get_rflags = svm_get_rflags, - .set_rflags = svm_set_rflags, -+ .get_if_flag = svm_get_if_flag, - - .tlb_flush_all = svm_flush_tlb, - .tlb_flush_current = svm_flush_tlb, -@@ -4592,7 +4625,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { - .load_eoi_exitmap = svm_load_eoi_exitmap, - .hwapic_irr_update = svm_hwapic_irr_update, - .hwapic_isr_update = svm_hwapic_isr_update, -- .sync_pir_to_irr = kvm_lapic_find_highest_irr, - .apicv_post_state_restore = avic_post_state_restore, - - .set_tss_addr = svm_set_tss_addr, -diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h -index 5d30db599e10d..ff0855c03c917 100644 ---- a/arch/x86/kvm/svm/svm.h -+++ b/arch/x86/kvm/svm/svm.h -@@ -461,7 +461,7 @@ static inline bool nested_exit_on_nmi(struct vcpu_svm *svm) - - int enter_svm_guest_mode(struct kvm_vcpu *vcpu, - u64 vmcb_gpa, struct vmcb *vmcb12, bool from_vmrun); --void svm_leave_nested(struct vcpu_svm *svm); -+void svm_leave_nested(struct kvm_vcpu *vcpu); - void svm_free_nested(struct vcpu_svm *svm); - int svm_allocate_nested(struct vcpu_svm *svm); - int nested_svm_vmrun(struct kvm_vcpu *vcpu); -diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c -index ba6f99f584ac3..a7ed30d5647af 100644 ---- a/arch/x86/kvm/vmx/evmcs.c -+++ b/arch/x86/kvm/vmx/evmcs.c -@@ -362,6 +362,7 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata) - case MSR_IA32_VMX_PROCBASED_CTLS2: - ctl_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC; - break; -+ case MSR_IA32_VMX_TRUE_PINBASED_CTLS: - case MSR_IA32_VMX_PINBASED_CTLS: - ctl_high &= ~EVMCS1_UNSUPPORTED_PINCTRL; - break; -diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h -index 152ab0aa82cf6..b43976e4b9636 100644 ---- a/arch/x86/kvm/vmx/evmcs.h -+++ b/arch/x86/kvm/vmx/evmcs.h -@@ -59,7 +59,9 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs); - SECONDARY_EXEC_SHADOW_VMCS | \ - SECONDARY_EXEC_TSC_SCALING | \ - SECONDARY_EXEC_PAUSE_LOOP_EXITING) --#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL) -+#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL \ -+ (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ -+ VM_EXIT_SAVE_VMX_PREEMPTION_TIMER) - #define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) - #define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING) - -diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c -index eedcebf580041..a0193b11c381d 100644 ---- a/arch/x86/kvm/vmx/nested.c -+++ b/arch/x86/kvm/vmx/nested.c -@@ -523,29 +523,6 @@ static int nested_vmx_check_tpr_shadow_controls(struct kvm_vcpu *vcpu, - return 0; - } - --/* -- * Check if MSR is intercepted for L01 MSR bitmap. -- */ --static bool msr_write_intercepted_l01(struct kvm_vcpu *vcpu, u32 msr) --{ -- unsigned long *msr_bitmap; -- int f = sizeof(unsigned long); -- -- if (!cpu_has_vmx_msr_bitmap()) -- return true; -- -- msr_bitmap = to_vmx(vcpu)->vmcs01.msr_bitmap; -- -- if (msr <= 0x1fff) { -- return !!test_bit(msr, msr_bitmap + 0x800 / f); -- } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { -- msr &= 0x1fff; -- return !!test_bit(msr, msr_bitmap + 0xc00 / f); -- } -- -- return true; --} -- - /* - * If a msr is allowed by L0, we should check whether it is allowed by L1. - * The corresponding bit will be cleared unless both of L0 and L1 allow it. -@@ -599,6 +576,34 @@ static inline void enable_x2apic_msr_intercepts(unsigned long *msr_bitmap) - } - } - -+#define BUILD_NVMX_MSR_INTERCEPT_HELPER(rw) \ -+static inline \ -+void nested_vmx_set_msr_##rw##_intercept(struct vcpu_vmx *vmx, \ -+ unsigned long *msr_bitmap_l1, \ -+ unsigned long *msr_bitmap_l0, u32 msr) \ -+{ \ -+ if (vmx_test_msr_bitmap_##rw(vmx->vmcs01.msr_bitmap, msr) || \ -+ vmx_test_msr_bitmap_##rw(msr_bitmap_l1, msr)) \ -+ vmx_set_msr_bitmap_##rw(msr_bitmap_l0, msr); \ -+ else \ -+ vmx_clear_msr_bitmap_##rw(msr_bitmap_l0, msr); \ -+} -+BUILD_NVMX_MSR_INTERCEPT_HELPER(read) -+BUILD_NVMX_MSR_INTERCEPT_HELPER(write) -+ -+static inline void nested_vmx_set_intercept_for_msr(struct vcpu_vmx *vmx, -+ unsigned long *msr_bitmap_l1, -+ unsigned long *msr_bitmap_l0, -+ u32 msr, int types) -+{ -+ if (types & MSR_TYPE_R) -+ nested_vmx_set_msr_read_intercept(vmx, msr_bitmap_l1, -+ msr_bitmap_l0, msr); -+ if (types & MSR_TYPE_W) -+ nested_vmx_set_msr_write_intercept(vmx, msr_bitmap_l1, -+ msr_bitmap_l0, msr); -+} -+ - /* - * Merge L0's and L1's MSR bitmap, return false to indicate that - * we do not use the hardware. -@@ -606,10 +611,11 @@ static inline void enable_x2apic_msr_intercepts(unsigned long *msr_bitmap) - static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, - struct vmcs12 *vmcs12) - { -+ struct vcpu_vmx *vmx = to_vmx(vcpu); - int msr; - unsigned long *msr_bitmap_l1; -- unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap; -- struct kvm_host_map *map = &to_vmx(vcpu)->nested.msr_bitmap_map; -+ unsigned long *msr_bitmap_l0 = vmx->nested.vmcs02.msr_bitmap; -+ struct kvm_host_map *map = &vmx->nested.msr_bitmap_map; - - /* Nothing to do if the MSR bitmap is not in use. */ - if (!cpu_has_vmx_msr_bitmap() || -@@ -660,44 +666,27 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, - } - } - -- /* KVM unconditionally exposes the FS/GS base MSRs to L1. */ -+ /* -+ * Always check vmcs01's bitmap to honor userspace MSR filters and any -+ * other runtime changes to vmcs01's bitmap, e.g. dynamic pass-through. -+ */ - #ifdef CONFIG_X86_64 -- nested_vmx_disable_intercept_for_msr(msr_bitmap_l1, msr_bitmap_l0, -- MSR_FS_BASE, MSR_TYPE_RW); -+ nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, -+ MSR_FS_BASE, MSR_TYPE_RW); - -- nested_vmx_disable_intercept_for_msr(msr_bitmap_l1, msr_bitmap_l0, -- MSR_GS_BASE, MSR_TYPE_RW); -+ nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, -+ MSR_GS_BASE, MSR_TYPE_RW); - -- nested_vmx_disable_intercept_for_msr(msr_bitmap_l1, msr_bitmap_l0, -- MSR_KERNEL_GS_BASE, MSR_TYPE_RW); -+ nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, -+ MSR_KERNEL_GS_BASE, MSR_TYPE_RW); - #endif -+ nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, -+ MSR_IA32_SPEC_CTRL, MSR_TYPE_RW); - -- /* -- * Checking the L0->L1 bitmap is trying to verify two things: -- * -- * 1. L0 gave a permission to L1 to actually passthrough the MSR. This -- * ensures that we do not accidentally generate an L02 MSR bitmap -- * from the L12 MSR bitmap that is too permissive. -- * 2. That L1 or L2s have actually used the MSR. This avoids -- * unnecessarily merging of the bitmap if the MSR is unused. This -- * works properly because we only update the L01 MSR bitmap lazily. -- * So even if L0 should pass L1 these MSRs, the L01 bitmap is only -- * updated to reflect this when L1 (or its L2s) actually write to -- * the MSR. -- */ -- if (!msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL)) -- nested_vmx_disable_intercept_for_msr( -- msr_bitmap_l1, msr_bitmap_l0, -- MSR_IA32_SPEC_CTRL, -- MSR_TYPE_R | MSR_TYPE_W); -- -- if (!msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD)) -- nested_vmx_disable_intercept_for_msr( -- msr_bitmap_l1, msr_bitmap_l0, -- MSR_IA32_PRED_CMD, -- MSR_TYPE_W); -+ nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, -+ MSR_IA32_PRED_CMD, MSR_TYPE_W); - -- kvm_vcpu_unmap(vcpu, &to_vmx(vcpu)->nested.msr_bitmap_map, false); -+ kvm_vcpu_unmap(vcpu, &vmx->nested.msr_bitmap_map, false); - - return true; - } -@@ -1191,29 +1180,26 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu, - WARN_ON(!enable_vpid); - - /* -- * If VPID is enabled and used by vmc12, but L2 does not have a unique -- * TLB tag (ASID), i.e. EPT is disabled and KVM was unable to allocate -- * a VPID for L2, flush the current context as the effective ASID is -- * common to both L1 and L2. -- * -- * Defer the flush so that it runs after vmcs02.EPTP has been set by -- * KVM_REQ_LOAD_MMU_PGD (if nested EPT is enabled) and to avoid -- * redundant flushes further down the nested pipeline. -- * -- * If a TLB flush isn't required due to any of the above, and vpid12 is -- * changing then the new "virtual" VPID (vpid12) will reuse the same -- * "real" VPID (vpid02), and so needs to be flushed. There's no direct -- * mapping between vpid02 and vpid12, vpid02 is per-vCPU and reused for -- * all nested vCPUs. Remember, a flush on VM-Enter does not invalidate -- * guest-physical mappings, so there is no need to sync the nEPT MMU. -+ * VPID is enabled and in use by vmcs12. If vpid12 is changing, then -+ * emulate a guest TLB flush as KVM does not track vpid12 history nor -+ * is the VPID incorporated into the MMU context. I.e. KVM must assume -+ * that the new vpid12 has never been used and thus represents a new -+ * guest ASID that cannot have entries in the TLB. - */ -- if (!nested_has_guest_tlb_tag(vcpu)) { -- kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); -- } else if (is_vmenter && -- vmcs12->virtual_processor_id != vmx->nested.last_vpid) { -+ if (is_vmenter && vmcs12->virtual_processor_id != vmx->nested.last_vpid) { - vmx->nested.last_vpid = vmcs12->virtual_processor_id; -- vpid_sync_context(nested_get_vpid02(vcpu)); -+ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); -+ return; - } -+ -+ /* -+ * If VPID is enabled, used by vmc12, and vpid12 is not changing but -+ * does not have a unique TLB tag (ASID), i.e. EPT is disabled and -+ * KVM was unable to allocate a VPID for L2, flush the current context -+ * as the effective ASID is common to both L1 and L2. -+ */ -+ if (!nested_has_guest_tlb_tag(vcpu)) -+ kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); - } - - static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask) -@@ -2623,8 +2609,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, - - if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) && - WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL, -- vmcs12->guest_ia32_perf_global_ctrl))) -+ vmcs12->guest_ia32_perf_global_ctrl))) { -+ *entry_failure_code = ENTRY_FAIL_DEFAULT; - return -EINVAL; -+ } - - kvm_rsp_write(vcpu, vmcs12->guest_rsp); - kvm_rip_write(vcpu, vmcs12->guest_rip); -@@ -2865,6 +2853,17 @@ static int nested_vmx_check_controls(struct kvm_vcpu *vcpu, - return 0; - } - -+static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu, -+ struct vmcs12 *vmcs12) -+{ -+#ifdef CONFIG_X86_64 -+ if (CC(!!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) != -+ !!(vcpu->arch.efer & EFER_LMA))) -+ return -EINVAL; -+#endif -+ return 0; -+} -+ - static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, - struct vmcs12 *vmcs12) - { -@@ -2889,18 +2888,16 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, - return -EINVAL; - - #ifdef CONFIG_X86_64 -- ia32e = !!(vcpu->arch.efer & EFER_LMA); -+ ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE); - #else - ia32e = false; - #endif - - if (ia32e) { -- if (CC(!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE)) || -- CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) -+ if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) - return -EINVAL; - } else { -- if (CC(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) || -- CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || -+ if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || - CC(vmcs12->host_cr4 & X86_CR4_PCIDE) || - CC((vmcs12->host_rip) >> 32)) - return -EINVAL; -@@ -3360,8 +3357,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, - }; - u32 failed_index; - -- if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) -- kvm_vcpu_flush_tlb_current(vcpu); -+ kvm_service_local_tlb_flush_requests(vcpu); - - evaluate_pending_interrupts = exec_controls_get(vmx) & - (CPU_BASED_INTR_WINDOW_EXITING | CPU_BASED_NMI_WINDOW_EXITING); -@@ -3570,6 +3566,9 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) - if (nested_vmx_check_controls(vcpu, vmcs12)) - return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); - -+ if (nested_vmx_check_address_space_size(vcpu, vmcs12)) -+ return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD); -+ - if (nested_vmx_check_host_state(vcpu, vmcs12)) - return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD); - -@@ -4515,9 +4514,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, - (void)nested_get_evmcs_page(vcpu); - } - -- /* Service the TLB flush request for L2 before switching to L1. */ -- if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) -- kvm_vcpu_flush_tlb_current(vcpu); -+ /* Service pending TLB flush requests for L2 before switching to L1. */ -+ kvm_service_local_tlb_flush_requests(vcpu); - - /* - * VCPU_EXREG_PDPTR will be clobbered in arch/x86/kvm/vmx/vmx.h between -@@ -6750,6 +6748,7 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)) - } - - struct kvm_x86_nested_ops vmx_nested_ops = { -+ .leave_nested = vmx_leave_nested, - .check_events = vmx_check_nested_events, - .hv_timer_pending = nested_vmx_preemption_timer_pending, - .triple_fault = nested_vmx_triple_fault, -diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c -index 10cc4f65c4efd..6427d95de01cf 100644 ---- a/arch/x86/kvm/vmx/pmu_intel.c -+++ b/arch/x86/kvm/vmx/pmu_intel.c -@@ -68,10 +68,11 @@ static void global_ctrl_changed(struct kvm_pmu *pmu, u64 data) - reprogram_counter(pmu, bit); - } - --static unsigned intel_find_arch_event(struct kvm_pmu *pmu, -- u8 event_select, -- u8 unit_mask) -+static unsigned int intel_pmc_perf_hw_id(struct kvm_pmc *pmc) - { -+ struct kvm_pmu *pmu = pmc_to_pmu(pmc); -+ u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT; -+ u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; - int i; - - for (i = 0; i < ARRAY_SIZE(intel_arch_events); i++) -@@ -706,7 +707,7 @@ static void intel_pmu_cleanup(struct kvm_vcpu *vcpu) - } - - struct kvm_pmu_ops intel_pmu_ops = { -- .find_arch_event = intel_find_arch_event, -+ .pmc_perf_hw_id = intel_pmc_perf_hw_id, - .find_fixed_event = intel_find_fixed_event, - .pmc_is_enabled = intel_pmc_is_enabled, - .pmc_idx_to_pmc = intel_pmc_idx_to_pmc, -diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c -index 5f81ef092bd43..46fb83d6a286e 100644 ---- a/arch/x86/kvm/vmx/posted_intr.c -+++ b/arch/x86/kvm/vmx/posted_intr.c -@@ -5,6 +5,7 @@ - #include - - #include "lapic.h" -+#include "irq.h" - #include "posted_intr.h" - #include "trace.h" - #include "vmx.h" -@@ -14,7 +15,7 @@ - * can find which vCPU should be waken up. - */ - static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu); --static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock); -+static DEFINE_PER_CPU(raw_spinlock_t, blocked_vcpu_on_cpu_lock); - - static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) - { -@@ -50,7 +51,7 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) - - /* The full case. */ - do { -- old.control = new.control = pi_desc->control; -+ old.control = new.control = READ_ONCE(pi_desc->control); - - dest = cpu_physical_id(cpu); - -@@ -77,13 +78,18 @@ after_clear_sn: - pi_set_on(pi_desc); - } - -+static bool vmx_can_use_vtd_pi(struct kvm *kvm) -+{ -+ return irqchip_in_kernel(kvm) && enable_apicv && -+ kvm_arch_has_assigned_device(kvm) && -+ irq_remapping_cap(IRQ_POSTING_CAP); -+} -+ - void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) - { - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - -- if (!kvm_arch_has_assigned_device(vcpu->kvm) || -- !irq_remapping_cap(IRQ_POSTING_CAP) || -- !kvm_vcpu_apicv_active(vcpu)) -+ if (!vmx_can_use_vtd_pi(vcpu->kvm)) - return; - - /* Set SN when the vCPU is preempted */ -@@ -98,7 +104,7 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) - unsigned int dest; - - do { -- old.control = new.control = pi_desc->control; -+ old.control = new.control = READ_ONCE(pi_desc->control); - WARN(old.nv != POSTED_INTR_WAKEUP_VECTOR, - "Wakeup handler not enabled while the VCPU is blocked\n"); - -@@ -115,9 +121,9 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) - new.control) != old.control); - - if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { -- spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); -+ raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - list_del(&vcpu->blocked_vcpu_list); -- spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); -+ raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - vcpu->pre_pcpu = -1; - } - } -@@ -141,24 +147,23 @@ int pi_pre_block(struct kvm_vcpu *vcpu) - struct pi_desc old, new; - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - -- if (!kvm_arch_has_assigned_device(vcpu->kvm) || -- !irq_remapping_cap(IRQ_POSTING_CAP) || -- !kvm_vcpu_apicv_active(vcpu)) -+ if (!vmx_can_use_vtd_pi(vcpu->kvm) || -+ vmx_interrupt_blocked(vcpu)) - return 0; - - WARN_ON(irqs_disabled()); - local_irq_disable(); - if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { - vcpu->pre_pcpu = vcpu->cpu; -- spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); -+ raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - list_add_tail(&vcpu->blocked_vcpu_list, - &per_cpu(blocked_vcpu_on_cpu, - vcpu->pre_pcpu)); -- spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); -+ raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - } - - do { -- old.control = new.control = pi_desc->control; -+ old.control = new.control = READ_ONCE(pi_desc->control); - - WARN((pi_desc->sn == 1), - "Warning: SN field of posted-interrupts " -@@ -211,7 +216,7 @@ void pi_wakeup_handler(void) - struct kvm_vcpu *vcpu; - int cpu = smp_processor_id(); - -- spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); -+ raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); - list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu), - blocked_vcpu_list) { - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); -@@ -219,13 +224,13 @@ void pi_wakeup_handler(void) - if (pi_test_on(pi_desc) == 1) - kvm_vcpu_kick(vcpu); - } -- spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); -+ raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); - } - - void __init pi_init_cpu(int cpu) - { - INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu)); -- spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); -+ raw_spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); - } - - bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu) -@@ -270,9 +275,7 @@ int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq, - struct vcpu_data vcpu_info; - int idx, ret = 0; - -- if (!kvm_arch_has_assigned_device(kvm) || -- !irq_remapping_cap(IRQ_POSTING_CAP) || -- !kvm_vcpu_apicv_active(kvm->vcpus[0])) -+ if (!vmx_can_use_vtd_pi(kvm)) - return 0; - - idx = srcu_read_lock(&kvm->irq_srcu); -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index 7d595effb66f0..322485ab9271c 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -769,24 +769,13 @@ void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu) - /* - * Check if MSR is intercepted for currently loaded MSR bitmap. - */ --static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr) -+static bool msr_write_intercepted(struct vcpu_vmx *vmx, u32 msr) - { -- unsigned long *msr_bitmap; -- int f = sizeof(unsigned long); -- -- if (!cpu_has_vmx_msr_bitmap()) -+ if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS)) - return true; - -- msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap; -- -- if (msr <= 0x1fff) { -- return !!test_bit(msr, msr_bitmap + 0x800 / f); -- } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { -- msr &= 0x1fff; -- return !!test_bit(msr, msr_bitmap + 0xc00 / f); -- } -- -- return true; -+ return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap, -+ MSR_IA32_SPEC_CTRL); - } - - static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx, -@@ -1370,6 +1359,11 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) - vmx->emulation_required = vmx_emulation_required(vcpu); - } - -+static bool vmx_get_if_flag(struct kvm_vcpu *vcpu) -+{ -+ return vmx_get_rflags(vcpu) & X86_EFLAGS_IF; -+} -+ - u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu) - { - u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); -@@ -2927,6 +2921,13 @@ static void vmx_flush_tlb_all(struct kvm_vcpu *vcpu) - } - } - -+static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu) -+{ -+ if (is_guest_mode(vcpu)) -+ return nested_get_vpid02(vcpu); -+ return to_vmx(vcpu)->vpid; -+} -+ - static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) - { - struct kvm_mmu *mmu = vcpu->arch.mmu; -@@ -2939,31 +2940,29 @@ static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) - if (enable_ept) - ept_sync_context(construct_eptp(vcpu, root_hpa, - mmu->shadow_root_level)); -- else if (!is_guest_mode(vcpu)) -- vpid_sync_context(to_vmx(vcpu)->vpid); - else -- vpid_sync_context(nested_get_vpid02(vcpu)); -+ vpid_sync_context(vmx_get_current_vpid(vcpu)); - } - - static void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr) - { - /* -- * vpid_sync_vcpu_addr() is a nop if vmx->vpid==0, see the comment in -+ * vpid_sync_vcpu_addr() is a nop if vpid==0, see the comment in - * vmx_flush_tlb_guest() for an explanation of why this is ok. - */ -- vpid_sync_vcpu_addr(to_vmx(vcpu)->vpid, addr); -+ vpid_sync_vcpu_addr(vmx_get_current_vpid(vcpu), addr); - } - - static void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu) - { - /* -- * vpid_sync_context() is a nop if vmx->vpid==0, e.g. if enable_vpid==0 -- * or a vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit -- * are required to flush GVA->{G,H}PA mappings from the TLB if vpid is -+ * vpid_sync_context() is a nop if vpid==0, e.g. if enable_vpid==0 or a -+ * vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit are -+ * required to flush GVA->{G,H}PA mappings from the TLB if vpid is - * disabled (VM-Enter with vpid enabled and vpid==0 is disallowed), - * i.e. no explicit INVVPID is necessary. - */ -- vpid_sync_context(to_vmx(vcpu)->vpid); -+ vpid_sync_context(vmx_get_current_vpid(vcpu)); - } - - void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu) -@@ -3695,46 +3694,6 @@ void free_vpid(int vpid) - spin_unlock(&vmx_vpid_lock); - } - --static void vmx_clear_msr_bitmap_read(ulong *msr_bitmap, u32 msr) --{ -- int f = sizeof(unsigned long); -- -- if (msr <= 0x1fff) -- __clear_bit(msr, msr_bitmap + 0x000 / f); -- else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -- __clear_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); --} -- --static void vmx_clear_msr_bitmap_write(ulong *msr_bitmap, u32 msr) --{ -- int f = sizeof(unsigned long); -- -- if (msr <= 0x1fff) -- __clear_bit(msr, msr_bitmap + 0x800 / f); -- else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -- __clear_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); --} -- --static void vmx_set_msr_bitmap_read(ulong *msr_bitmap, u32 msr) --{ -- int f = sizeof(unsigned long); -- -- if (msr <= 0x1fff) -- __set_bit(msr, msr_bitmap + 0x000 / f); -- else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -- __set_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); --} -- --static void vmx_set_msr_bitmap_write(ulong *msr_bitmap, u32 msr) --{ -- int f = sizeof(unsigned long); -- -- if (msr <= 0x1fff) -- __set_bit(msr, msr_bitmap + 0x800 / f); -- else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -- __set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); --} -- - void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type) - { - struct vcpu_vmx *vmx = to_vmx(vcpu); -@@ -4012,8 +3971,7 @@ static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) - if (pi_test_and_set_on(&vmx->pi_desc)) - return 0; - -- if (vcpu != kvm_get_running_vcpu() && -- !kvm_vcpu_trigger_posted_interrupt(vcpu, false)) -+ if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false)) - kvm_vcpu_kick(vcpu); - - return 0; -@@ -4833,8 +4791,33 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) - dr6 = vmx_get_exit_qual(vcpu); - if (!(vcpu->guest_debug & - (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { -+ /* -+ * If the #DB was due to ICEBP, a.k.a. INT1, skip the -+ * instruction. ICEBP generates a trap-like #DB, but -+ * despite its interception control being tied to #DB, -+ * is an instruction intercept, i.e. the VM-Exit occurs -+ * on the ICEBP itself. Note, skipping ICEBP also -+ * clears STI and MOVSS blocking. -+ * -+ * For all other #DBs, set vmcs.PENDING_DBG_EXCEPTIONS.BS -+ * if single-step is enabled in RFLAGS and STI or MOVSS -+ * blocking is active, as the CPU doesn't set the bit -+ * on VM-Exit due to #DB interception. VM-Entry has a -+ * consistency check that a single-step #DB is pending -+ * in this scenario as the previous instruction cannot -+ * have toggled RFLAGS.TF 0=>1 (because STI and POP/MOV -+ * don't modify RFLAGS), therefore the one instruction -+ * delay when activating single-step breakpoints must -+ * have already expired. Note, the CPU sets/clears BS -+ * as appropriate for all other VM-Exits types. -+ */ - if (is_icebp(intr_info)) - WARN_ON(!skip_emulated_instruction(vcpu)); -+ else if ((vmx_get_rflags(vcpu) & X86_EFLAGS_TF) && -+ (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & -+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS))) -+ vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, -+ vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS) | DR6_BS); - - kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); - return 1; -@@ -5907,18 +5890,14 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) - vmx_flush_pml_buffer(vcpu); - - /* -- * We should never reach this point with a pending nested VM-Enter, and -- * more specifically emulation of L2 due to invalid guest state (see -- * below) should never happen as that means we incorrectly allowed a -- * nested VM-Enter with an invalid vmcs12. -+ * KVM should never reach this point with a pending nested VM-Enter. -+ * More specifically, short-circuiting VM-Entry to emulate L2 due to -+ * invalid guest state should never happen as that means KVM knowingly -+ * allowed a nested VM-Enter with an invalid vmcs12. More below. - */ - if (KVM_BUG_ON(vmx->nested.nested_run_pending, vcpu->kvm)) - return -EIO; - -- /* If guest state is invalid, start emulating */ -- if (vmx->emulation_required) -- return handle_invalid_guest_state(vcpu); -- - if (is_guest_mode(vcpu)) { - /* - * PML is never enabled when running L2, bail immediately if a -@@ -5940,10 +5919,30 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) - */ - nested_mark_vmcs12_pages_dirty(vcpu); - -+ /* -+ * Synthesize a triple fault if L2 state is invalid. In normal -+ * operation, nested VM-Enter rejects any attempt to enter L2 -+ * with invalid state. However, those checks are skipped if -+ * state is being stuffed via RSM or KVM_SET_NESTED_STATE. If -+ * L2 state is invalid, it means either L1 modified SMRAM state -+ * or userspace provided bad state. Synthesize TRIPLE_FAULT as -+ * doing so is architecturally allowed in the RSM case, and is -+ * the least awful solution for the userspace case without -+ * risking false positives. -+ */ -+ if (vmx->emulation_required) { -+ nested_vmx_vmexit(vcpu, EXIT_REASON_TRIPLE_FAULT, 0, 0); -+ return 1; -+ } -+ - if (nested_vmx_reflect_vmexit(vcpu)) - return 1; - } - -+ /* If guest state is invalid, start emulating. L2 is handled above. */ -+ if (vmx->emulation_required) -+ return handle_invalid_guest_state(vcpu); -+ - if (exit_reason.failed_vmentry) { - dump_vmcs(vcpu); - vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY; -@@ -6288,9 +6287,9 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) - { - struct vcpu_vmx *vmx = to_vmx(vcpu); - int max_irr; -- bool max_irr_updated; -+ bool got_posted_interrupt; - -- if (KVM_BUG_ON(!vcpu->arch.apicv_active, vcpu->kvm)) -+ if (KVM_BUG_ON(!enable_apicv, vcpu->kvm)) - return -EIO; - - if (pi_test_on(&vmx->pi_desc)) { -@@ -6300,22 +6299,33 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) - * But on x86 this is just a compiler barrier anyway. - */ - smp_mb__after_atomic(); -- max_irr_updated = -+ got_posted_interrupt = - kvm_apic_update_irr(vcpu, vmx->pi_desc.pir, &max_irr); -- -- /* -- * If we are running L2 and L1 has a new pending interrupt -- * which can be injected, this may cause a vmexit or it may -- * be injected into L2. Either way, this interrupt will be -- * processed via KVM_REQ_EVENT, not RVI, because we do not use -- * virtual interrupt delivery to inject L1 interrupts into L2. -- */ -- if (is_guest_mode(vcpu) && max_irr_updated) -- kvm_make_request(KVM_REQ_EVENT, vcpu); - } else { - max_irr = kvm_lapic_find_highest_irr(vcpu); -+ got_posted_interrupt = false; - } -- vmx_hwapic_irr_update(vcpu, max_irr); -+ -+ /* -+ * Newly recognized interrupts are injected via either virtual interrupt -+ * delivery (RVI) or KVM_REQ_EVENT. Virtual interrupt delivery is -+ * disabled in two cases: -+ * -+ * 1) If L2 is running and the vCPU has a new pending interrupt. If L1 -+ * wants to exit on interrupts, KVM_REQ_EVENT is needed to synthesize a -+ * VM-Exit to L1. If L1 doesn't want to exit, the interrupt is injected -+ * into L2, but KVM doesn't use virtual interrupt delivery to inject -+ * interrupts into L2, and so KVM_REQ_EVENT is again needed. -+ * -+ * 2) If APICv is disabled for this vCPU, assigned devices may still -+ * attempt to post interrupts. The posted interrupt vector will cause -+ * a VM-Exit and the subsequent entry will call sync_pir_to_irr. -+ */ -+ if (!is_guest_mode(vcpu) && kvm_vcpu_apicv_active(vcpu)) -+ vmx_set_rvi(max_irr); -+ else if (got_posted_interrupt) -+ kvm_make_request(KVM_REQ_EVENT, vcpu); -+ - return max_irr; - } - -@@ -6626,9 +6636,7 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu) - * consistency check VM-Exit due to invalid guest state and bail. - */ - if (unlikely(vmx->emulation_required)) { -- -- /* We don't emulate invalid state of a nested guest */ -- vmx->fail = is_guest_mode(vcpu); -+ vmx->fail = 0; - - vmx->exit_reason.full = EXIT_REASON_INVALID_STATE; - vmx->exit_reason.failed_vmentry = 1; -@@ -6720,7 +6728,7 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu) - * If the L02 MSR bitmap does not intercept the MSR, then we need to - * save it. - */ -- if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) -+ if (unlikely(!msr_write_intercepted(vmx, MSR_IA32_SPEC_CTRL))) - vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); - - x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0); -@@ -7524,6 +7532,7 @@ static int vmx_leave_smm(struct kvm_vcpu *vcpu, const char *smstate) - if (ret) - return ret; - -+ vmx->nested.nested_run_pending = 1; - vmx->nested.smm.guest_mode = false; - } - return 0; -@@ -7551,6 +7560,8 @@ static void vmx_migrate_timers(struct kvm_vcpu *vcpu) - - static void hardware_unsetup(void) - { -+ kvm_set_posted_intr_wakeup_handler(NULL); -+ - if (nested) - nested_vmx_hardware_unsetup(); - -@@ -7606,6 +7617,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { - .cache_reg = vmx_cache_reg, - .get_rflags = vmx_get_rflags, - .set_rflags = vmx_set_rflags, -+ .get_if_flag = vmx_get_if_flag, - - .tlb_flush_all = vmx_flush_tlb_all, - .tlb_flush_current = vmx_flush_tlb_current, -@@ -7809,10 +7821,10 @@ static __init int hardware_setup(void) - ple_window_shrink = 0; - } - -- if (!cpu_has_vmx_apicv()) { -+ if (!cpu_has_vmx_apicv()) - enable_apicv = 0; -+ if (!enable_apicv) - vmx_x86_ops.sync_pir_to_irr = NULL; -- } - - if (cpu_has_vmx_tsc_scaling()) { - kvm_has_tsc_control = true; -@@ -7879,8 +7891,6 @@ static __init int hardware_setup(void) - vmx_x86_ops.request_immediate_exit = __kvm_request_immediate_exit; - } - -- kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler); -- - kvm_mce_cap_supported |= MCG_LMCE_P; - - if (pt_mode != PT_MODE_SYSTEM && pt_mode != PT_MODE_HOST_GUEST) -@@ -7904,6 +7914,9 @@ static __init int hardware_setup(void) - r = alloc_kvm_area(); - if (r) - nested_vmx_hardware_unsetup(); -+ -+ kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler); -+ - return r; - } - -@@ -7912,6 +7925,7 @@ static struct kvm_x86_init_ops vmx_init_ops __initdata = { - .disabled_by_bios = vmx_disabled_by_bios, - .check_processor_compatibility = vmx_check_processor_compat, - .hardware_setup = hardware_setup, -+ .intel_pt_intr_in_guest = vmx_pt_mode_is_host_guest, - - .runtime_ops = &vmx_x86_ops, - }; -diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h -index 592217fd7d920..3f9c8548625d6 100644 ---- a/arch/x86/kvm/vmx/vmx.h -+++ b/arch/x86/kvm/vmx/vmx.h -@@ -400,6 +400,69 @@ static inline void vmx_set_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, - - void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu); - -+static inline bool vmx_test_msr_bitmap_read(ulong *msr_bitmap, u32 msr) -+{ -+ int f = sizeof(unsigned long); -+ -+ if (msr <= 0x1fff) -+ return test_bit(msr, msr_bitmap + 0x000 / f); -+ else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -+ return test_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); -+ return true; -+} -+ -+static inline bool vmx_test_msr_bitmap_write(ulong *msr_bitmap, u32 msr) -+{ -+ int f = sizeof(unsigned long); -+ -+ if (msr <= 0x1fff) -+ return test_bit(msr, msr_bitmap + 0x800 / f); -+ else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -+ return test_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); -+ return true; -+} -+ -+static inline void vmx_clear_msr_bitmap_read(ulong *msr_bitmap, u32 msr) -+{ -+ int f = sizeof(unsigned long); -+ -+ if (msr <= 0x1fff) -+ __clear_bit(msr, msr_bitmap + 0x000 / f); -+ else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -+ __clear_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); -+} -+ -+static inline void vmx_clear_msr_bitmap_write(ulong *msr_bitmap, u32 msr) -+{ -+ int f = sizeof(unsigned long); -+ -+ if (msr <= 0x1fff) -+ __clear_bit(msr, msr_bitmap + 0x800 / f); -+ else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -+ __clear_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); -+} -+ -+static inline void vmx_set_msr_bitmap_read(ulong *msr_bitmap, u32 msr) -+{ -+ int f = sizeof(unsigned long); -+ -+ if (msr <= 0x1fff) -+ __set_bit(msr, msr_bitmap + 0x000 / f); -+ else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -+ __set_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); -+} -+ -+static inline void vmx_set_msr_bitmap_write(ulong *msr_bitmap, u32 msr) -+{ -+ int f = sizeof(unsigned long); -+ -+ if (msr <= 0x1fff) -+ __set_bit(msr, msr_bitmap + 0x800 / f); -+ else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) -+ __set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); -+} -+ -+ - static inline u8 vmx_get_rvi(void) - { - return vmcs_read16(GUEST_INTR_STATUS) & 0xff; -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index bfe0de3008a60..8213f7fb71a7b 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -848,6 +848,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long cr3) - - memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs)); - kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR); -+ kvm_make_request(KVM_REQ_LOAD_MMU_PGD, vcpu); - vcpu->arch.pdptrs_from_userspace = false; - - out: -@@ -1091,6 +1092,18 @@ static void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid) - unsigned long roots_to_free = 0; - int i; - -+ /* -+ * MOV CR3 and INVPCID are usually not intercepted when using TDP, but -+ * this is reachable when running EPT=1 and unrestricted_guest=0, and -+ * also via the emulator. KVM's TDP page tables are not in the scope of -+ * the invalidation, but the guest's TLB entries need to be flushed as -+ * the CPU may have cached entries in its TLB for the target PCID. -+ */ -+ if (unlikely(tdp_enabled)) { -+ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); -+ return; -+ } -+ - /* - * If neither the current CR3 nor any of the prev_roots use the given - * PCID, then nothing needs to be done here because a resync will -@@ -1311,7 +1324,7 @@ static const u32 msrs_to_save_all[] = { - MSR_IA32_UMWAIT_CONTROL, - - MSR_ARCH_PERFMON_FIXED_CTR0, MSR_ARCH_PERFMON_FIXED_CTR1, -- MSR_ARCH_PERFMON_FIXED_CTR0 + 2, MSR_ARCH_PERFMON_FIXED_CTR0 + 3, -+ MSR_ARCH_PERFMON_FIXED_CTR0 + 2, - MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS, - MSR_CORE_PERF_GLOBAL_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL, - MSR_ARCH_PERFMON_PERFCTR0, MSR_ARCH_PERFMON_PERFCTR1, -@@ -3193,10 +3206,36 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu) - static_call(kvm_x86_tlb_flush_guest)(vcpu); - } - -+ -+static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu) -+{ -+ ++vcpu->stat.tlb_flush; -+ static_call(kvm_x86_tlb_flush_current)(vcpu); -+} -+ -+/* -+ * Service "local" TLB flush requests, which are specific to the current MMU -+ * context. In addition to the generic event handling in vcpu_enter_guest(), -+ * TLB flushes that are targeted at an MMU context also need to be serviced -+ * prior before nested VM-Enter/VM-Exit. -+ */ -+void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu) -+{ -+ if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) -+ kvm_vcpu_flush_tlb_current(vcpu); -+ -+ if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) -+ kvm_vcpu_flush_tlb_guest(vcpu); -+} -+EXPORT_SYMBOL_GPL(kvm_service_local_tlb_flush_requests); -+ - static void record_steal_time(struct kvm_vcpu *vcpu) - { -- struct kvm_host_map map; -- struct kvm_steal_time *st; -+ struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; -+ struct kvm_steal_time __user *st; -+ struct kvm_memslots *slots; -+ u64 steal; -+ u32 version; - - if (kvm_xen_msr_enabled(vcpu->kvm)) { - kvm_xen_runstate_set_running(vcpu); -@@ -3206,47 +3245,86 @@ static void record_steal_time(struct kvm_vcpu *vcpu) - if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) - return; - -- /* -EAGAIN is returned in atomic context so we can just return. */ -- if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, -- &map, &vcpu->arch.st.cache, false)) -+ if (WARN_ON_ONCE(current->mm != vcpu->kvm->mm)) - return; - -- st = map.hva + -- offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); -+ slots = kvm_memslots(vcpu->kvm); -+ -+ if (unlikely(slots->generation != ghc->generation || -+ kvm_is_error_hva(ghc->hva) || !ghc->memslot)) { -+ gfn_t gfn = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; - -+ /* We rely on the fact that it fits in a single page. */ -+ BUILD_BUG_ON((sizeof(*st) - 1) & KVM_STEAL_VALID_BITS); -+ -+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gfn, sizeof(*st)) || -+ kvm_is_error_hva(ghc->hva) || !ghc->memslot) -+ return; -+ } -+ -+ st = (struct kvm_steal_time __user *)ghc->hva; - /* - * Doing a TLB flush here, on the guest's behalf, can avoid - * expensive IPIs. - */ - if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) { -- u8 st_preempted = xchg(&st->preempted, 0); -+ u8 st_preempted = 0; -+ int err = -EFAULT; -+ -+ if (!user_access_begin(st, sizeof(*st))) -+ return; -+ -+ asm volatile("1: xchgb %0, %2\n" -+ "xor %1, %1\n" -+ "2:\n" -+ _ASM_EXTABLE_UA(1b, 2b) -+ : "+q" (st_preempted), -+ "+&r" (err), -+ "+m" (st->preempted)); -+ if (err) -+ goto out; -+ -+ user_access_end(); -+ -+ vcpu->arch.st.preempted = 0; - - trace_kvm_pv_tlb_flush(vcpu->vcpu_id, - st_preempted & KVM_VCPU_FLUSH_TLB); - if (st_preempted & KVM_VCPU_FLUSH_TLB) - kvm_vcpu_flush_tlb_guest(vcpu); -+ -+ if (!user_access_begin(st, sizeof(*st))) -+ goto dirty; - } else { -- st->preempted = 0; -- } -+ if (!user_access_begin(st, sizeof(*st))) -+ return; - -- vcpu->arch.st.preempted = 0; -+ unsafe_put_user(0, &st->preempted, out); -+ vcpu->arch.st.preempted = 0; -+ } - -- if (st->version & 1) -- st->version += 1; /* first time write, random junk */ -+ unsafe_get_user(version, &st->version, out); -+ if (version & 1) -+ version += 1; /* first time write, random junk */ - -- st->version += 1; -+ version += 1; -+ unsafe_put_user(version, &st->version, out); - - smp_wmb(); - -- st->steal += current->sched_info.run_delay - -+ unsafe_get_user(steal, &st->steal, out); -+ steal += current->sched_info.run_delay - - vcpu->arch.st.last_steal; - vcpu->arch.st.last_steal = current->sched_info.run_delay; -+ unsafe_put_user(steal, &st->steal, out); - -- smp_wmb(); -- -- st->version += 1; -+ version += 1; -+ unsafe_put_user(version, &st->version, out); - -- kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, false); -+ out: -+ user_access_end(); -+ dirty: -+ mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa)); - } - - int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) -@@ -3282,7 +3360,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) - - if (!msr_info->host_initiated) - return 1; -- if (guest_cpuid_has(vcpu, X86_FEATURE_PDCM) && kvm_get_msr_feature(&msr_ent)) -+ if (kvm_get_msr_feature(&msr_ent)) - return 1; - if (data & ~msr_ent.data) - return 1; -@@ -3376,6 +3454,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) - if (data & ~supported_xss) - return 1; - vcpu->arch.ia32_xss = data; -+ kvm_update_cpuid_runtime(vcpu); - break; - case MSR_SMI_COUNT: - if (!msr_info->host_initiated) -@@ -4285,8 +4364,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) - - static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) - { -- struct kvm_host_map map; -- struct kvm_steal_time *st; -+ struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; -+ struct kvm_steal_time __user *st; -+ struct kvm_memslots *slots; -+ static const u8 preempted = KVM_VCPU_PREEMPTED; - - if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) - return; -@@ -4294,16 +4375,23 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) - if (vcpu->arch.st.preempted) - return; - -- if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, &map, -- &vcpu->arch.st.cache, true)) -+ /* This happens on process exit */ -+ if (unlikely(current->mm != vcpu->kvm->mm)) -+ return; -+ -+ slots = kvm_memslots(vcpu->kvm); -+ -+ if (unlikely(slots->generation != ghc->generation || -+ kvm_is_error_hva(ghc->hva) || !ghc->memslot)) - return; - -- st = map.hva + -- offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); -+ st = (struct kvm_steal_time __user *)ghc->hva; -+ BUILD_BUG_ON(sizeof(st->preempted) != sizeof(preempted)); - -- st->preempted = vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; -+ if (!copy_to_user_nofault(&st->preempted, &preempted, sizeof(preempted))) -+ vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; - -- kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, true); -+ mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa)); - } - - void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) -@@ -4331,8 +4419,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) - static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, - struct kvm_lapic_state *s) - { -- if (vcpu->arch.apicv_active) -- static_call(kvm_x86_sync_pir_to_irr)(vcpu); -+ static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); - - return kvm_apic_get_state(vcpu, s); - } -@@ -4642,8 +4729,10 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, - vcpu->arch.apic->sipi_vector = events->sipi_vector; - - if (events->flags & KVM_VCPUEVENT_VALID_SMM) { -- if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) -+ if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) { -+ kvm_x86_ops.nested_ops->leave_nested(vcpu); - kvm_smm_changed(vcpu, events->smi.smm); -+ } - - vcpu->arch.smi_pending = events->smi.pending; - -@@ -6948,7 +7037,13 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size, - unsigned short port, void *val, unsigned int count) - { - if (vcpu->arch.pio.count) { -- /* Complete previous iteration. */ -+ /* -+ * Complete a previous iteration that required userspace I/O. -+ * Note, @count isn't guaranteed to match pio.count as userspace -+ * can modify ECX before rerunning the vCPU. Ignore any such -+ * shenanigans as KVM doesn't support modifying the rep count, -+ * and the emulator ensures @count doesn't overflow the buffer. -+ */ - } else { - int r = __emulator_pio_in(vcpu, size, port, count); - if (!r) -@@ -6957,7 +7052,6 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size, - /* Results already available, fall through. */ - } - -- WARN_ON(count != vcpu->arch.pio.count); - complete_emulator_pio_in(vcpu, val); - return 1; - } -@@ -7905,7 +7999,12 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, - * updating interruptibility state and injecting single-step #DBs. - */ - if (emulation_type & EMULTYPE_SKIP) { -- kvm_rip_write(vcpu, ctxt->_eip); -+ if (ctxt->mode != X86EMUL_MODE_PROT64) -+ ctxt->eip = (u32)ctxt->_eip; -+ else -+ ctxt->eip = ctxt->_eip; -+ -+ kvm_rip_write(vcpu, ctxt->eip); - if (ctxt->eflags & X86_EFLAGS_RF) - kvm_set_rflags(vcpu, ctxt->eflags & ~X86_EFLAGS_RF); - return 1; -@@ -7969,6 +8068,9 @@ restart: - writeback = false; - r = 0; - vcpu->arch.complete_userspace_io = complete_emulated_mmio; -+ } else if (vcpu->arch.complete_userspace_io) { -+ writeback = false; -+ r = 0; - } else if (r == EMULATION_RESTART) - goto restart; - else -@@ -8340,7 +8442,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = { - .is_in_guest = kvm_is_in_guest, - .is_user_mode = kvm_is_user_mode, - .get_guest_ip = kvm_get_guest_ip, -- .handle_intel_pt_intr = kvm_handle_intel_pt_intr, -+ .handle_intel_pt_intr = NULL, - }; - - #ifdef CONFIG_X86_64 -@@ -8461,8 +8563,6 @@ int kvm_arch_init(void *opaque) - - kvm_timer_init(); - -- perf_register_guest_info_callbacks(&kvm_guest_cbs); -- - if (boot_cpu_has(X86_FEATURE_XSAVE)) { - host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); - supported_xcr0 = host_xcr0 & KVM_SUPPORTED_XCR0; -@@ -8496,7 +8596,6 @@ void kvm_arch_exit(void) - clear_hv_tscchange_cb(); - #endif - kvm_lapic_exit(); -- perf_unregister_guest_info_callbacks(&kvm_guest_cbs); - - if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) - cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, -@@ -8686,7 +8785,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) - - trace_kvm_hypercall(nr, a0, a1, a2, a3); - -- op_64_bit = is_64_bit_mode(vcpu); -+ op_64_bit = is_64_bit_hypercall(vcpu); - if (!op_64_bit) { - nr &= 0xFFFFFFFF; - a0 &= 0xFFFFFFFF; -@@ -8790,14 +8889,7 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) - { - struct kvm_run *kvm_run = vcpu->run; - -- /* -- * if_flag is obsolete and useless, so do not bother -- * setting it for SEV-ES guests. Userspace can just -- * use kvm_run->ready_for_interrupt_injection. -- */ -- kvm_run->if_flag = !vcpu->arch.guest_state_protected -- && (kvm_get_rflags(vcpu) & X86_EFLAGS_IF) != 0; -- -+ kvm_run->if_flag = static_call(kvm_x86_get_if_flag)(vcpu); - kvm_run->cr8 = kvm_get_cr8(vcpu); - kvm_run->apic_base = kvm_get_apic_base(vcpu); - -@@ -9359,8 +9451,7 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) - if (irqchip_split(vcpu->kvm)) - kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); - else { -- if (vcpu->arch.apicv_active) -- static_call(kvm_x86_sync_pir_to_irr)(vcpu); -+ static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); - if (ioapic_in_kernel(vcpu->kvm)) - kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); - } -@@ -9378,12 +9469,16 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu) - if (!kvm_apic_hw_enabled(vcpu->arch.apic)) - return; - -- if (to_hv_vcpu(vcpu)) -+ if (to_hv_vcpu(vcpu)) { - bitmap_or((ulong *)eoi_exit_bitmap, - vcpu->arch.ioapic_handled_vectors, - to_hv_synic(vcpu)->vec_bitmap, 256); -+ static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap); -+ return; -+ } - -- static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap); -+ static_call(kvm_x86_load_eoi_exitmap)( -+ vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors); - } - - void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, -@@ -9475,10 +9570,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) - /* Flushing all ASIDs flushes the current ASID... */ - kvm_clear_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); - } -- if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) -- kvm_vcpu_flush_tlb_current(vcpu); -- if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) -- kvm_vcpu_flush_tlb_guest(vcpu); -+ kvm_service_local_tlb_flush_requests(vcpu); - - if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) { - vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS; -@@ -9629,10 +9721,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) - - /* - * This handles the case where a posted interrupt was -- * notified with kvm_vcpu_kick. -+ * notified with kvm_vcpu_kick. Assigned devices can -+ * use the POSTED_INTR_VECTOR even if APICv is disabled, -+ * so do it even if APICv is disabled on this vCPU. - */ -- if (kvm_lapic_enabled(vcpu) && vcpu->arch.apicv_active) -- static_call(kvm_x86_sync_pir_to_irr)(vcpu); -+ if (kvm_lapic_enabled(vcpu)) -+ static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); - - if (kvm_vcpu_exit_request(vcpu)) { - vcpu->mode = OUTSIDE_GUEST_MODE; -@@ -9668,8 +9762,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) - if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST)) - break; - -- if (vcpu->arch.apicv_active) -- static_call(kvm_x86_sync_pir_to_irr)(vcpu); -+ if (kvm_lapic_enabled(vcpu)) -+ static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); - - if (unlikely(kvm_vcpu_exit_request(vcpu))) { - exit_fastpath = EXIT_FASTPATH_EXIT_HANDLED; -@@ -10817,11 +10911,8 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) - - void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) - { -- struct gfn_to_pfn_cache *cache = &vcpu->arch.st.cache; - int idx; - -- kvm_release_pfn(cache->pfn, cache->dirty, cache); -- - kvmclock_reset(vcpu); - - static_call(kvm_x86_vcpu_free)(vcpu); -@@ -10908,7 +10999,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) - - vcpu->arch.msr_misc_features_enables = 0; - -- vcpu->arch.xcr0 = XFEATURE_MASK_FP; -+ __kvm_set_xcr(vcpu, 0, XFEATURE_MASK_FP); -+ __kvm_set_msr(vcpu, MSR_IA32_XSS, 0, true); - } - - memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs)); -@@ -10927,8 +11019,6 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) - eax = 0x600; - kvm_rdx_write(vcpu, eax); - -- vcpu->arch.ia32_xss = 0; -- - static_call(kvm_x86_vcpu_reset)(vcpu, init_event); - - kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); -@@ -11104,6 +11194,10 @@ int kvm_arch_hardware_setup(void *opaque) - memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops)); - kvm_ops_static_call_update(); - -+ if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest()) -+ kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr; -+ perf_register_guest_info_callbacks(&kvm_guest_cbs); -+ - if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES)) - supported_xss = 0; - -@@ -11131,6 +11225,9 @@ int kvm_arch_hardware_setup(void *opaque) - - void kvm_arch_hardware_unsetup(void) - { -+ perf_unregister_guest_info_callbacks(&kvm_guest_cbs); -+ kvm_guest_cbs.handle_intel_pt_intr = NULL; -+ - static_call(kvm_x86_hardware_unsetup)(); - } - -diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h -index 7d66d63dc55a6..bc7ef6820ac8f 100644 ---- a/arch/x86/kvm/x86.h -+++ b/arch/x86/kvm/x86.h -@@ -103,6 +103,7 @@ static inline unsigned int __shrink_ple_window(unsigned int val, - - #define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL - -+void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu); - int kvm_check_nested_events(struct kvm_vcpu *vcpu); - - static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) -@@ -153,12 +154,24 @@ static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu) - { - int cs_db, cs_l; - -+ WARN_ON_ONCE(vcpu->arch.guest_state_protected); -+ - if (!is_long_mode(vcpu)) - return false; - static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l); - return cs_l; - } - -+static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu) -+{ -+ /* -+ * If running with protected guest state, the CS register is not -+ * accessible. The hypercall register values will have had to been -+ * provided in 64-bit mode, so assume the guest is in 64-bit. -+ */ -+ return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu); -+} -+ - static inline bool x86_exception_has_error_code(unsigned int vector) - { - static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) | -@@ -173,12 +186,6 @@ static inline bool mmu_is_nested(struct kvm_vcpu *vcpu) - return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu; - } - --static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu) --{ -- ++vcpu->stat.tlb_flush; -- static_call(kvm_x86_tlb_flush_current)(vcpu); --} -- - static inline int is_pae(struct kvm_vcpu *vcpu) - { - return kvm_read_cr4_bits(vcpu, X86_CR4_PAE); -diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c -index 8f62baebd0286..ab9f88de6deb9 100644 ---- a/arch/x86/kvm/xen.c -+++ b/arch/x86/kvm/xen.c -@@ -93,32 +93,57 @@ static void kvm_xen_update_runstate(struct kvm_vcpu *v, int state) - void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) - { - struct kvm_vcpu_xen *vx = &v->arch.xen; -+ struct gfn_to_hva_cache *ghc = &vx->runstate_cache; -+ struct kvm_memslots *slots = kvm_memslots(v->kvm); -+ bool atomic = (state == RUNSTATE_runnable); - uint64_t state_entry_time; -- unsigned int offset; -+ int __user *user_state; -+ uint64_t __user *user_times; - - kvm_xen_update_runstate(v, state); - - if (!vx->runstate_set) - return; - -- BUILD_BUG_ON(sizeof(struct compat_vcpu_runstate_info) != 0x2c); -+ if (unlikely(slots->generation != ghc->generation || kvm_is_error_hva(ghc->hva)) && -+ kvm_gfn_to_hva_cache_init(v->kvm, ghc, ghc->gpa, ghc->len)) -+ return; -+ -+ /* We made sure it fits in a single page */ -+ BUG_ON(!ghc->memslot); -+ -+ if (atomic) -+ pagefault_disable(); - -- offset = offsetof(struct compat_vcpu_runstate_info, state_entry_time); --#ifdef CONFIG_X86_64 - /* -- * The only difference is alignment of uint64_t in 32-bit. -- * So the first field 'state' is accessed directly using -- * offsetof() (where its offset happens to be zero), while the -- * remaining fields which are all uint64_t, start at 'offset' -- * which we tweak here by adding 4. -+ * The only difference between 32-bit and 64-bit versions of the -+ * runstate struct us the alignment of uint64_t in 32-bit, which -+ * means that the 64-bit version has an additional 4 bytes of -+ * padding after the first field 'state'. -+ * -+ * So we use 'int __user *user_state' to point to the state field, -+ * and 'uint64_t __user *user_times' for runstate_entry_time. So -+ * the actual array of time[] in each state starts at user_times[1]. - */ -+ BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state) != 0); -+ BUILD_BUG_ON(offsetof(struct compat_vcpu_runstate_info, state) != 0); -+ user_state = (int __user *)ghc->hva; -+ -+ BUILD_BUG_ON(sizeof(struct compat_vcpu_runstate_info) != 0x2c); -+ -+ user_times = (uint64_t __user *)(ghc->hva + -+ offsetof(struct compat_vcpu_runstate_info, -+ state_entry_time)); -+#ifdef CONFIG_X86_64 - BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state_entry_time) != - offsetof(struct compat_vcpu_runstate_info, state_entry_time) + 4); - BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, time) != - offsetof(struct compat_vcpu_runstate_info, time) + 4); - - if (v->kvm->arch.xen.long_mode) -- offset = offsetof(struct vcpu_runstate_info, state_entry_time); -+ user_times = (uint64_t __user *)(ghc->hva + -+ offsetof(struct vcpu_runstate_info, -+ state_entry_time)); - #endif - /* - * First write the updated state_entry_time at the appropriate -@@ -132,10 +157,8 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) - BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state_entry_time) != - sizeof(state_entry_time)); - -- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, -- &state_entry_time, offset, -- sizeof(state_entry_time))) -- return; -+ if (__put_user(state_entry_time, user_times)) -+ goto out; - smp_wmb(); - - /* -@@ -149,11 +172,8 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) - BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state) != - sizeof(vx->current_runstate)); - -- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, -- &vx->current_runstate, -- offsetof(struct vcpu_runstate_info, state), -- sizeof(vx->current_runstate))) -- return; -+ if (__put_user(vx->current_runstate, user_state)) -+ goto out; - - /* - * Write the actual runstate times immediately after the -@@ -168,24 +188,23 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) - BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) != - sizeof(vx->runstate_times)); - -- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, -- &vx->runstate_times[0], -- offset + sizeof(u64), -- sizeof(vx->runstate_times))) -- return; -- -+ if (__copy_to_user(user_times + 1, vx->runstate_times, sizeof(vx->runstate_times))) -+ goto out; - smp_wmb(); - - /* - * Finally, clear the XEN_RUNSTATE_UPDATE bit in the guest's - * runstate_entry_time field. - */ -- - state_entry_time &= ~XEN_RUNSTATE_UPDATE; -- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, -- &state_entry_time, offset, -- sizeof(state_entry_time))) -- return; -+ __put_user(state_entry_time, user_times); -+ smp_wmb(); -+ -+ out: -+ mark_page_dirty_in_slot(v->kvm, ghc->memslot, ghc->gpa >> PAGE_SHIFT); -+ -+ if (atomic) -+ pagefault_enable(); - } - - int __kvm_xen_has_interrupt(struct kvm_vcpu *v) -@@ -299,7 +318,7 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) - break; - - case KVM_XEN_ATTR_TYPE_SHARED_INFO: -- data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_gfn); -+ data->u.shared_info.gfn = kvm->arch.xen.shinfo_gfn; - r = 0; - break; - -@@ -337,6 +356,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) - break; - } - -+ /* It must fit within a single page */ -+ if ((data->u.gpa & ~PAGE_MASK) + sizeof(struct vcpu_info) > PAGE_SIZE) { -+ r = -EINVAL; -+ break; -+ } -+ - r = kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.xen.vcpu_info_cache, - data->u.gpa, -@@ -354,6 +379,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) - break; - } - -+ /* It must fit within a single page */ -+ if ((data->u.gpa & ~PAGE_MASK) + sizeof(struct pvclock_vcpu_time_info) > PAGE_SIZE) { -+ r = -EINVAL; -+ break; -+ } -+ - r = kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.xen.vcpu_time_info_cache, - data->u.gpa, -@@ -375,6 +406,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) - break; - } - -+ /* It must fit within a single page */ -+ if ((data->u.gpa & ~PAGE_MASK) + sizeof(struct vcpu_runstate_info) > PAGE_SIZE) { -+ r = -EINVAL; -+ break; -+ } -+ - r = kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.xen.runstate_cache, - data->u.gpa, -@@ -698,7 +735,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) - kvm_hv_hypercall_enabled(vcpu)) - return kvm_hv_hypercall(vcpu); - -- longmode = is_64_bit_mode(vcpu); -+ longmode = is_64_bit_hypercall(vcpu); - if (!longmode) { - params[0] = (u32)kvm_rbx_read(vcpu); - params[1] = (u32)kvm_rcx_read(vcpu); -diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c -index a1d24fdc07cf0..eb3ccffb9b9dc 100644 ---- a/arch/x86/lib/insn-eval.c -+++ b/arch/x86/lib/insn-eval.c -@@ -1417,7 +1417,7 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) - } - } - --static int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) -+int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) - { - unsigned long seg_base = 0; - -diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c -index c565def611e24..55e371cc69fd5 100644 ---- a/arch/x86/lib/insn.c -+++ b/arch/x86/lib/insn.c -@@ -13,6 +13,7 @@ - #endif - #include /*__ignore_sync_check__ */ - #include /* __ignore_sync_check__ */ -+#include /* __ignore_sync_check__ */ - - #include - #include -@@ -37,10 +38,10 @@ - ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) - - #define __get_next(t, insn) \ -- ({ t r; memcpy(&r, insn->next_byte, sizeof(t)); insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) -+ ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); }) - - #define __peek_nbyte_next(t, insn, n) \ -- ({ t r; memcpy(&r, (insn)->next_byte + n, sizeof(t)); leXX_to_cpu(t, r); }) -+ ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); }) - - #define get_next(t, insn) \ - ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) -diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S -index ec9922cba30a4..5385d26af6e45 100644 ---- a/arch/x86/lib/retpoline.S -+++ b/arch/x86/lib/retpoline.S -@@ -34,7 +34,7 @@ SYM_FUNC_START(__x86_indirect_thunk_\reg) - - ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ - __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ -- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD -+ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE - - SYM_FUNC_END(__x86_indirect_thunk_\reg) - -diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c -index f5e1e60c9095f..6c2f1b76a0b61 100644 ---- a/arch/x86/mm/cpu_entry_area.c -+++ b/arch/x86/mm/cpu_entry_area.c -@@ -110,6 +110,13 @@ static void __init percpu_setup_exception_stacks(unsigned int cpu) - cea_map_stack(NMI); - cea_map_stack(DB); - cea_map_stack(MCE); -+ -+ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { -+ if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) { -+ cea_map_stack(VC); -+ cea_map_stack(VC2); -+ } -+ } - } - #else - static inline void percpu_setup_exception_stacks(unsigned int cpu) -diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c -index 84a2c8c4af735..4bfed53e210ec 100644 ---- a/arch/x86/mm/fault.c -+++ b/arch/x86/mm/fault.c -@@ -32,6 +32,7 @@ - #include /* VMALLOC_START, ... */ - #include /* kvm_handle_async_pf */ - #include /* fixup_vdso_exception() */ -+#include - - #define CREATE_TRACE_POINTS - #include -@@ -631,6 +632,9 @@ static noinline void - page_fault_oops(struct pt_regs *regs, unsigned long error_code, - unsigned long address) - { -+#ifdef CONFIG_VMAP_STACK -+ struct stack_info info; -+#endif - unsigned long flags; - int sig; - -@@ -649,9 +653,7 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code, - * that we're in vmalloc space to avoid this. - */ - if (is_vmalloc_addr((void *)address) && -- (((unsigned long)current->stack - 1 - address < PAGE_SIZE) || -- address - ((unsigned long)current->stack + THREAD_SIZE) < PAGE_SIZE)) { -- unsigned long stack = __this_cpu_ist_top_va(DF) - sizeof(void *); -+ get_stack_guard_info((void *)address, &info)) { - /* - * We're likely to be running with very little stack space - * left. It's plausible that we'd hit this condition but -@@ -662,13 +664,11 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code, - * and then double-fault, though, because we're likely to - * break the console driver and lose most of the stack dump. - */ -- asm volatile ("movq %[stack], %%rsp\n\t" -- "call handle_stack_overflow\n\t" -- "1: jmp 1b" -- : ASM_CALL_CONSTRAINT -- : "D" ("kernel stack overflow (page fault)"), -- "S" (regs), "d" (address), -- [stack] "rm" (stack)); -+ call_on_stack(__this_cpu_ist_top_va(DF) - sizeof(void*), -+ handle_stack_overflow, -+ ASM_CALL_ARG3, -+ , [arg1] "r" (regs), [arg2] "r" (address), [arg3] "r" (&info)); -+ - unreachable(); - } - #endif -diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c -index ff08dc4636347..e29b1418d00c7 100644 ---- a/arch/x86/mm/mem_encrypt.c -+++ b/arch/x86/mm/mem_encrypt.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c -index 470b202084306..700ce8fdea87c 100644 ---- a/arch/x86/mm/mem_encrypt_identity.c -+++ b/arch/x86/mm/mem_encrypt_identity.c -@@ -27,6 +27,15 @@ - #undef CONFIG_PARAVIRT_XXL - #undef CONFIG_PARAVIRT_SPINLOCKS - -+/* -+ * This code runs before CPU feature bits are set. By default, the -+ * pgtable_l5_enabled() function uses bit X86_FEATURE_LA57 to determine if -+ * 5-level paging is active, so that won't work here. USE_EARLY_PGTABLE_L5 -+ * is provided to handle this situation and, instead, use a variable that -+ * has been set by the early boot code. -+ */ -+#define USE_EARLY_PGTABLE_L5 -+ - #include - #include - #include -diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c -index 9ea57389c554b..d99434dc215c2 100644 ---- a/arch/x86/net/bpf_jit_comp.c -+++ b/arch/x86/net/bpf_jit_comp.c -@@ -721,6 +721,20 @@ static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64) - *pprog = prog; - } - -+/* -+ * Similar version of maybe_emit_mod() for a single register -+ */ -+static void maybe_emit_1mod(u8 **pprog, u32 reg, bool is64) -+{ -+ u8 *prog = *pprog; -+ -+ if (is64) -+ EMIT1(add_1mod(0x48, reg)); -+ else if (is_ereg(reg)) -+ EMIT1(add_1mod(0x40, reg)); -+ *pprog = prog; -+} -+ - /* LDX: dst_reg = *(u8*)(src_reg + off) */ - static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off) - { -@@ -951,10 +965,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, - /* neg dst */ - case BPF_ALU | BPF_NEG: - case BPF_ALU64 | BPF_NEG: -- if (BPF_CLASS(insn->code) == BPF_ALU64) -- EMIT1(add_1mod(0x48, dst_reg)); -- else if (is_ereg(dst_reg)) -- EMIT1(add_1mod(0x40, dst_reg)); -+ maybe_emit_1mod(&prog, dst_reg, -+ BPF_CLASS(insn->code) == BPF_ALU64); - EMIT2(0xF7, add_1reg(0xD8, dst_reg)); - break; - -@@ -968,10 +980,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, - case BPF_ALU64 | BPF_AND | BPF_K: - case BPF_ALU64 | BPF_OR | BPF_K: - case BPF_ALU64 | BPF_XOR | BPF_K: -- if (BPF_CLASS(insn->code) == BPF_ALU64) -- EMIT1(add_1mod(0x48, dst_reg)); -- else if (is_ereg(dst_reg)) -- EMIT1(add_1mod(0x40, dst_reg)); -+ maybe_emit_1mod(&prog, dst_reg, -+ BPF_CLASS(insn->code) == BPF_ALU64); - - /* - * b3 holds 'normal' opcode, b2 short form only valid -@@ -1112,10 +1122,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, - case BPF_ALU64 | BPF_LSH | BPF_K: - case BPF_ALU64 | BPF_RSH | BPF_K: - case BPF_ALU64 | BPF_ARSH | BPF_K: -- if (BPF_CLASS(insn->code) == BPF_ALU64) -- EMIT1(add_1mod(0x48, dst_reg)); -- else if (is_ereg(dst_reg)) -- EMIT1(add_1mod(0x40, dst_reg)); -+ maybe_emit_1mod(&prog, dst_reg, -+ BPF_CLASS(insn->code) == BPF_ALU64); - - b3 = simple_alu_opcodes[BPF_OP(insn->code)]; - if (imm32 == 1) -@@ -1146,10 +1154,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, - } - - /* shl %rax, %cl | shr %rax, %cl | sar %rax, %cl */ -- if (BPF_CLASS(insn->code) == BPF_ALU64) -- EMIT1(add_1mod(0x48, dst_reg)); -- else if (is_ereg(dst_reg)) -- EMIT1(add_1mod(0x40, dst_reg)); -+ maybe_emit_1mod(&prog, dst_reg, -+ BPF_CLASS(insn->code) == BPF_ALU64); - - b3 = simple_alu_opcodes[BPF_OP(insn->code)]; - EMIT2(0xD3, add_1reg(b3, dst_reg)); -@@ -1274,19 +1280,54 @@ st: if (is_imm8(insn->off)) - case BPF_LDX | BPF_MEM | BPF_DW: - case BPF_LDX | BPF_PROBE_MEM | BPF_DW: - if (BPF_MODE(insn->code) == BPF_PROBE_MEM) { -- /* test src_reg, src_reg */ -- maybe_emit_mod(&prog, src_reg, src_reg, true); /* always 1 byte */ -- EMIT2(0x85, add_2reg(0xC0, src_reg, src_reg)); -- /* jne start_of_ldx */ -- EMIT2(X86_JNE, 0); -+ /* Though the verifier prevents negative insn->off in BPF_PROBE_MEM -+ * add abs(insn->off) to the limit to make sure that negative -+ * offset won't be an issue. -+ * insn->off is s16, so it won't affect valid pointers. -+ */ -+ u64 limit = TASK_SIZE_MAX + PAGE_SIZE + abs(insn->off); -+ u8 *end_of_jmp1, *end_of_jmp2; -+ -+ /* Conservatively check that src_reg + insn->off is a kernel address: -+ * 1. src_reg + insn->off >= limit -+ * 2. src_reg + insn->off doesn't become small positive. -+ * Cannot do src_reg + insn->off >= limit in one branch, -+ * since it needs two spare registers, but JIT has only one. -+ */ -+ -+ /* movabsq r11, limit */ -+ EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG)); -+ EMIT((u32)limit, 4); -+ EMIT(limit >> 32, 4); -+ /* cmp src_reg, r11 */ -+ maybe_emit_mod(&prog, src_reg, AUX_REG, true); -+ EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG)); -+ /* if unsigned '<' goto end_of_jmp2 */ -+ EMIT2(X86_JB, 0); -+ end_of_jmp1 = prog; -+ -+ /* mov r11, src_reg */ -+ emit_mov_reg(&prog, true, AUX_REG, src_reg); -+ /* add r11, insn->off */ -+ maybe_emit_1mod(&prog, AUX_REG, true); -+ EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off); -+ /* jmp if not carry to start_of_ldx -+ * Otherwise ERR_PTR(-EINVAL) + 128 will be the user addr -+ * that has to be rejected. -+ */ -+ EMIT2(0x73 /* JNC */, 0); -+ end_of_jmp2 = prog; -+ - /* xor dst_reg, dst_reg */ - emit_mov_imm32(&prog, false, dst_reg, 0); - /* jmp byte_after_ldx */ - EMIT2(0xEB, 0); - -- /* populate jmp_offset for JNE above */ -- temp[4] = prog - temp - 5 /* sizeof(test + jne) */; -+ /* populate jmp_offset for JB above to jump to xor dst_reg */ -+ end_of_jmp1[-1] = end_of_jmp2 - end_of_jmp1; -+ /* populate jmp_offset for JNC above to jump to start_of_ldx */ - start_of_ldx = prog; -+ end_of_jmp2[-1] = start_of_ldx - end_of_jmp2; - } - emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off); - if (BPF_MODE(insn->code) == BPF_PROBE_MEM) { -@@ -1332,7 +1373,7 @@ st: if (is_imm8(insn->off)) - * End result: x86 insn "mov rbx, qword ptr [rax+0x14]" - * of 4 bytes will be ignored and rbx will be zero inited. - */ -- ex->fixup = (prog - temp) | (reg2pt_regs[dst_reg] << 8); -+ ex->fixup = (prog - start_of_ldx) | (reg2pt_regs[dst_reg] << 8); - } - break; - -@@ -1459,10 +1500,8 @@ st: if (is_imm8(insn->off)) - case BPF_JMP | BPF_JSET | BPF_K: - case BPF_JMP32 | BPF_JSET | BPF_K: - /* test dst_reg, imm32 */ -- if (BPF_CLASS(insn->code) == BPF_JMP) -- EMIT1(add_1mod(0x48, dst_reg)); -- else if (is_ereg(dst_reg)) -- EMIT1(add_1mod(0x40, dst_reg)); -+ maybe_emit_1mod(&prog, dst_reg, -+ BPF_CLASS(insn->code) == BPF_JMP); - EMIT2_off32(0xF7, add_1reg(0xC0, dst_reg), imm32); - goto emit_cond_jmp; - -@@ -1495,10 +1534,8 @@ st: if (is_imm8(insn->off)) - } - - /* cmp dst_reg, imm8/32 */ -- if (BPF_CLASS(insn->code) == BPF_JMP) -- EMIT1(add_1mod(0x48, dst_reg)); -- else if (is_ereg(dst_reg)) -- EMIT1(add_1mod(0x40, dst_reg)); -+ maybe_emit_1mod(&prog, dst_reg, -+ BPF_CLASS(insn->code) == BPF_JMP); - - if (is_imm8(imm32)) - EMIT3(0x83, add_1reg(0xF8, dst_reg), imm32); -diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c -index 2edd86649468f..615a76d700194 100644 ---- a/arch/x86/pci/fixup.c -+++ b/arch/x86/pci/fixup.c -@@ -353,8 +353,8 @@ static void pci_fixup_video(struct pci_dev *pdev) - } - } - } --DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, -- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); -+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, -+ PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); - - - static const struct dmi_system_id msi_k8t_dmi_table[] = { -diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c -index b15ebfe40a73e..b0b848d6933af 100644 ---- a/arch/x86/platform/efi/quirks.c -+++ b/arch/x86/platform/efi/quirks.c -@@ -277,7 +277,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) - return; - } - -- new = early_memremap(data.phys_map, data.size); -+ new = early_memremap_prot(data.phys_map, data.size, -+ pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL))); - if (!new) { - pr_err("Failed to map new boot services memmap\n"); - return; -diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c -index 31b5856010cba..1d20ed4b28729 100644 ---- a/arch/x86/realmode/init.c -+++ b/arch/x86/realmode/init.c -@@ -17,6 +17,32 @@ u32 *trampoline_cr4_features; - /* Hold the pgd entry used on booting additional CPUs */ - pgd_t trampoline_pgd_entry; - -+void load_trampoline_pgtable(void) -+{ -+#ifdef CONFIG_X86_32 -+ load_cr3(initial_page_table); -+#else -+ /* -+ * This function is called before exiting to real-mode and that will -+ * fail with CR4.PCIDE still set. -+ */ -+ if (boot_cpu_has(X86_FEATURE_PCID)) -+ cr4_clear_bits(X86_CR4_PCIDE); -+ -+ write_cr3(real_mode_header->trampoline_pgd); -+#endif -+ -+ /* -+ * The CR3 write above will not flush global TLB entries. -+ * Stale, global entries from previous page tables may still be -+ * present. Flush those stale entries. -+ * -+ * This ensures that memory accessed while running with -+ * trampoline_pgd is *actually* mapped into trampoline_pgd. -+ */ -+ __flush_tlb_all(); -+} -+ - void __init reserve_real_mode(void) - { - phys_addr_t mem; -@@ -72,6 +98,7 @@ static void __init setup_real_mode(void) - #ifdef CONFIG_X86_64 - u64 *trampoline_pgd; - u64 efer; -+ int i; - #endif - - base = (unsigned char *)real_mode_header; -@@ -128,8 +155,17 @@ static void __init setup_real_mode(void) - trampoline_header->flags = 0; - - trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); -+ -+ /* Map the real mode stub as virtual == physical */ - trampoline_pgd[0] = trampoline_pgd_entry.pgd; -- trampoline_pgd[511] = init_top_pgt[511].pgd; -+ -+ /* -+ * Include the entirety of the kernel mapping into the trampoline -+ * PGD. This way, all mappings present in the normal kernel page -+ * tables are usable while running on trampoline_pgd. -+ */ -+ for (i = pgd_index(__PAGE_OFFSET); i < PTRS_PER_PGD; i++) -+ trampoline_pgd[i] = init_top_pgt[i].pgd; - #endif - - sme_sev_setup_real_mode(trampoline_header); -diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c -index 58f51667e2e4b..8249685b40960 100644 ---- a/arch/x86/um/syscalls_64.c -+++ b/arch/x86/um/syscalls_64.c -@@ -11,6 +11,7 @@ - #include - #include /* XXX This should get the constants from libc */ - #include -+#include - - long arch_prctl(struct task_struct *task, int option, - unsigned long __user *arg2) -@@ -35,7 +36,7 @@ long arch_prctl(struct task_struct *task, int option, - switch (option) { - case ARCH_SET_FS: - case ARCH_SET_GS: -- ret = restore_registers(pid, ¤t->thread.regs.regs); -+ ret = restore_pid_registers(pid, ¤t->thread.regs.regs); - if (ret) - return ret; - break; -diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c -index a7b7d674f5005..133ef31639df1 100644 ---- a/arch/x86/xen/enlighten_pv.c -+++ b/arch/x86/xen/enlighten_pv.c -@@ -1364,10 +1364,6 @@ asmlinkage __visible void __init xen_start_kernel(void) - - xen_acpi_sleep_register(); - -- /* Avoid searching for BIOS MP tables */ -- x86_init.mpparse.find_smp_config = x86_init_noop; -- x86_init.mpparse.get_smp_config = x86_init_uint_noop; -- - xen_boot_params_init_edd(); - - #ifdef CONFIG_ACPI -diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c -index 7ed56c6075b0c..477c484eb202c 100644 ---- a/arch/x86/xen/smp_pv.c -+++ b/arch/x86/xen/smp_pv.c -@@ -148,28 +148,12 @@ int xen_smp_intr_init_pv(unsigned int cpu) - return rc; - } - --static void __init xen_fill_possible_map(void) --{ -- int i, rc; -- -- if (xen_initial_domain()) -- return; -- -- for (i = 0; i < nr_cpu_ids; i++) { -- rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); -- if (rc >= 0) { -- num_processors++; -- set_cpu_possible(i, true); -- } -- } --} -- --static void __init xen_filter_cpu_maps(void) -+static void __init _get_smp_config(unsigned int early) - { - int i, rc; - unsigned int subtract = 0; - -- if (!xen_initial_domain()) -+ if (early) - return; - - num_processors = 0; -@@ -210,7 +194,6 @@ static void __init xen_pv_smp_prepare_boot_cpu(void) - * sure the old memory can be recycled. */ - make_lowmem_page_readwrite(xen_initial_gdt); - -- xen_filter_cpu_maps(); - xen_setup_vcpu_info_placement(); - - /* -@@ -486,5 +469,8 @@ static const struct smp_ops xen_smp_ops __initconst = { - void __init xen_smp_init(void) - { - smp_ops = xen_smp_ops; -- xen_fill_possible_map(); -+ -+ /* Avoid searching for BIOS MP tables */ -+ x86_init.mpparse.find_smp_config = x86_init_noop; -+ x86_init.mpparse.get_smp_config = _get_smp_config; - } -diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S -index 1e626444712be..3bebf66569b48 100644 ---- a/arch/x86/xen/xen-asm.S -+++ b/arch/x86/xen/xen-asm.S -@@ -20,6 +20,7 @@ - - #include - #include -+#include <../entry/calling.h> - - /* - * Enable events. This clears the event mask and tests the pending -@@ -191,6 +192,25 @@ SYM_CODE_START(xen_iret) - jmp hypercall_iret - SYM_CODE_END(xen_iret) - -+/* -+ * XEN pv doesn't use trampoline stack, PER_CPU_VAR(cpu_tss_rw + TSS_sp0) is -+ * also the kernel stack. Reusing swapgs_restore_regs_and_return_to_usermode() -+ * in XEN pv would cause %rsp to move up to the top of the kernel stack and -+ * leave the IRET frame below %rsp, which is dangerous to be corrupted if #NMI -+ * interrupts. And swapgs_restore_regs_and_return_to_usermode() pushing the IRET -+ * frame at the same address is useless. -+ */ -+SYM_CODE_START(xenpv_restore_regs_and_return_to_usermode) -+ UNWIND_HINT_REGS -+ POP_REGS -+ -+ /* stackleak_erase() can work safely on the kernel stack. */ -+ STACKLEAK_ERASE_NOCLOBBER -+ -+ addq $8, %rsp /* skip regs->orig_ax */ -+ jmp xen_iret -+SYM_CODE_END(xenpv_restore_regs_and_return_to_usermode) -+ - /* - * Xen handles syscall callbacks much like ordinary exceptions, which - * means we have: -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 480e1a1348596..e66970bf27dbe 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -5991,48 +5991,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, - - spin_lock_irq(&bfqd->lock); - bfqq = bfq_init_rq(rq); -- -- /* -- * Reqs with at_head or passthrough flags set are to be put -- * directly into dispatch list. Additional case for putting rq -- * directly into the dispatch queue: the only active -- * bfq_queues are bfqq and either its waker bfq_queue or one -- * of its woken bfq_queues. The rationale behind this -- * additional condition is as follows: -- * - consider a bfq_queue, say Q1, detected as a waker of -- * another bfq_queue, say Q2 -- * - by definition of a waker, Q1 blocks the I/O of Q2, i.e., -- * some I/O of Q1 needs to be completed for new I/O of Q2 -- * to arrive. A notable example of waker is journald -- * - so, Q1 and Q2 are in any respect the queues of two -- * cooperating processes (or of two cooperating sets of -- * processes): the goal of Q1's I/O is doing what needs to -- * be done so that new Q2's I/O can finally be -- * issued. Therefore, if the service of Q1's I/O is delayed, -- * then Q2's I/O is delayed too. Conversely, if Q2's I/O is -- * delayed, the goal of Q1's I/O is hindered. -- * - as a consequence, if some I/O of Q1/Q2 arrives while -- * Q2/Q1 is the only queue in service, there is absolutely -- * no point in delaying the service of such an I/O. The -- * only possible result is a throughput loss -- * - so, when the above condition holds, the best option is to -- * have the new I/O dispatched as soon as possible -- * - the most effective and efficient way to attain the above -- * goal is to put the new I/O directly in the dispatch -- * list -- * - as an additional restriction, Q1 and Q2 must be the only -- * busy queues for this commit to put the I/O of Q2/Q1 in -- * the dispatch list. This is necessary, because, if also -- * other queues are waiting for service, then putting new -- * I/O directly in the dispatch list may evidently cause a -- * violation of service guarantees for the other queues -- */ -- if (!bfqq || -- (bfqq != bfqd->in_service_queue && -- bfqd->in_service_queue != NULL && -- bfq_tot_busy_queues(bfqd) == 1 + bfq_bfqq_busy(bfqq) && -- (bfqq->waker_bfqq == bfqd->in_service_queue || -- bfqd->in_service_queue->waker_bfqq == bfqq)) || at_head) { -+ if (!bfqq || at_head) { - if (at_head) - list_add(&rq->queuelist, &bfqd->dispatch); - else -@@ -6059,7 +6018,6 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, - * merge). - */ - cmd_flags = rq->cmd_flags; -- - spin_unlock_irq(&bfqd->lock); - - bfq_update_insert_stats(q, bfqq, idle_timer_disabled, -@@ -6920,6 +6878,8 @@ static void bfq_exit_queue(struct elevator_queue *e) - spin_unlock_irq(&bfqd->lock); - #endif - -+ wbt_enable_default(bfqd->queue); -+ - kfree(bfqd); - } - -diff --git a/block/bio-integrity.c b/block/bio-integrity.c -index 6b47cddbbca17..4a7c33ed9a661 100644 ---- a/block/bio-integrity.c -+++ b/block/bio-integrity.c -@@ -373,7 +373,7 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) - struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); - unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9); - -- bip->bip_iter.bi_sector += bytes_done >> 9; -+ bip->bip_iter.bi_sector += bio_integrity_intervals(bi, bytes_done >> 9); - bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes); - } - -diff --git a/block/bio.c b/block/bio.c -index a6fb6a0b42955..25f1ed261100b 100644 ---- a/block/bio.c -+++ b/block/bio.c -@@ -567,7 +567,8 @@ void bio_truncate(struct bio *bio, unsigned new_size) - offset = new_size - done; - else - offset = 0; -- zero_user(bv.bv_page, offset, bv.bv_len - offset); -+ zero_user(bv.bv_page, bv.bv_offset + offset, -+ bv.bv_len - offset); - truncated = true; - } - done += bv.bv_len; -diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c -index 9a1c5839dd469..0eec59e4df65c 100644 ---- a/block/blk-cgroup.c -+++ b/block/blk-cgroup.c -@@ -633,6 +633,14 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, - - q = bdev->bd_disk->queue; - -+ /* -+ * blkcg_deactivate_policy() requires queue to be frozen, we can grab -+ * q_usage_counter to prevent concurrent with blkcg_deactivate_policy(). -+ */ -+ ret = blk_queue_enter(q, 0); -+ if (ret) -+ goto fail; -+ - rcu_read_lock(); - spin_lock_irq(&q->queue_lock); - -@@ -667,13 +675,13 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, - new_blkg = blkg_alloc(pos, q, GFP_KERNEL); - if (unlikely(!new_blkg)) { - ret = -ENOMEM; -- goto fail; -+ goto fail_exit_queue; - } - - if (radix_tree_preload(GFP_KERNEL)) { - blkg_free(new_blkg); - ret = -ENOMEM; -- goto fail; -+ goto fail_exit_queue; - } - - rcu_read_lock(); -@@ -702,6 +710,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, - goto success; - } - success: -+ blk_queue_exit(q); - ctx->bdev = bdev; - ctx->blkg = blkg; - ctx->body = input; -@@ -712,6 +721,8 @@ fail_preloaded: - fail_unlock: - spin_unlock_irq(&q->queue_lock); - rcu_read_unlock(); -+fail_exit_queue: -+ blk_queue_exit(q); - fail: - blkdev_put_no_open(bdev); - /* -diff --git a/block/blk-core.c b/block/blk-core.c -index 4d8f5fe915887..42ac3a985c2d7 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -350,13 +350,6 @@ void blk_queue_start_drain(struct request_queue *q) - wake_up_all(&q->mq_freeze_wq); - } - --void blk_set_queue_dying(struct request_queue *q) --{ -- blk_queue_flag_set(QUEUE_FLAG_DYING, q); -- blk_queue_start_drain(q); --} --EXPORT_SYMBOL_GPL(blk_set_queue_dying); -- - /** - * blk_cleanup_queue - shutdown a request queue - * @q: request queue to shutdown -@@ -374,7 +367,8 @@ void blk_cleanup_queue(struct request_queue *q) - WARN_ON_ONCE(blk_queue_registered(q)); - - /* mark @q DYING, no new request or merges will be allowed afterwards */ -- blk_set_queue_dying(q); -+ blk_queue_flag_set(QUEUE_FLAG_DYING, q); -+ blk_queue_start_drain(q); - - blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q); - blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q); -@@ -389,8 +383,10 @@ void blk_cleanup_queue(struct request_queue *q) - blk_queue_flag_set(QUEUE_FLAG_DEAD, q); - - blk_sync_queue(q); -- if (queue_is_mq(q)) -+ if (queue_is_mq(q)) { -+ blk_mq_cancel_work_sync(q); - blk_mq_exit_queue(q); -+ } - - /* - * In theory, request pool of sched_tags belongs to request queue. -@@ -887,10 +883,8 @@ static noinline_for_stack bool submit_bio_checks(struct bio *bio) - if (unlikely(!current->io_context)) - create_task_io_context(current, GFP_ATOMIC, q->node); - -- if (blk_throtl_bio(bio)) { -- blkcg_bio_issue_init(bio); -+ if (blk_throtl_bio(bio)) - return false; -- } - - blk_cgroup_bio_start(bio); - blkcg_bio_issue_init(bio); -@@ -1293,20 +1287,32 @@ void blk_account_io_start(struct request *rq) - } - - static unsigned long __part_start_io_acct(struct block_device *part, -- unsigned int sectors, unsigned int op) -+ unsigned int sectors, unsigned int op, -+ unsigned long start_time) - { - const int sgrp = op_stat_group(op); -- unsigned long now = READ_ONCE(jiffies); - - part_stat_lock(); -- update_io_ticks(part, now, false); -+ update_io_ticks(part, start_time, false); - part_stat_inc(part, ios[sgrp]); - part_stat_add(part, sectors[sgrp], sectors); - part_stat_local_inc(part, in_flight[op_is_write(op)]); - part_stat_unlock(); - -- return now; -+ return start_time; -+} -+ -+/** -+ * bio_start_io_acct_time - start I/O accounting for bio based drivers -+ * @bio: bio to start account for -+ * @start_time: start time that should be passed back to bio_end_io_acct(). -+ */ -+void bio_start_io_acct_time(struct bio *bio, unsigned long start_time) -+{ -+ __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), -+ bio_op(bio), start_time); - } -+EXPORT_SYMBOL_GPL(bio_start_io_acct_time); - - /** - * bio_start_io_acct - start I/O accounting for bio based drivers -@@ -1316,14 +1322,15 @@ static unsigned long __part_start_io_acct(struct block_device *part, - */ - unsigned long bio_start_io_acct(struct bio *bio) - { -- return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), bio_op(bio)); -+ return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), -+ bio_op(bio), jiffies); - } - EXPORT_SYMBOL_GPL(bio_start_io_acct); - - unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors, - unsigned int op) - { -- return __part_start_io_acct(disk->part0, sectors, op); -+ return __part_start_io_acct(disk->part0, sectors, op, jiffies); - } - EXPORT_SYMBOL(disk_start_io_acct); - -diff --git a/block/blk-flush.c b/block/blk-flush.c -index 4201728bf3a5a..94a86acbb7f67 100644 ---- a/block/blk-flush.c -+++ b/block/blk-flush.c -@@ -235,8 +235,10 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) - * avoiding use-after-free. - */ - WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE); -- if (fq->rq_status != BLK_STS_OK) -+ if (fq->rq_status != BLK_STS_OK) { - error = fq->rq_status; -+ fq->rq_status = BLK_STS_OK; -+ } - - if (!q->elevator) { - flush_rq->tag = BLK_MQ_NO_TAG; -diff --git a/block/blk-iocost.c b/block/blk-iocost.c -index b3880e4ba22a1..eb7b0d6bd11f6 100644 ---- a/block/blk-iocost.c -+++ b/block/blk-iocost.c -@@ -2311,7 +2311,14 @@ static void ioc_timer_fn(struct timer_list *timer) - hwm = current_hweight_max(iocg); - new_hwi = hweight_after_donation(iocg, old_hwi, hwm, - usage, &now); -- if (new_hwi < hwm) { -+ /* -+ * Donation calculation assumes hweight_after_donation -+ * to be positive, a condition that a donor w/ hwa < 2 -+ * can't meet. Don't bother with donation if hwa is -+ * below 2. It's not gonna make a meaningful difference -+ * anyway. -+ */ -+ if (new_hwi < hwm && hwa >= 2) { - iocg->hweight_donating = hwa; - iocg->hweight_after_donation = new_hwi; - list_add(&iocg->surplus_list, &surpluses); -diff --git a/block/blk-map.c b/block/blk-map.c -index 4526adde01564..c7f71d83eff18 100644 ---- a/block/blk-map.c -+++ b/block/blk-map.c -@@ -446,7 +446,7 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data, - if (bytes > len) - bytes = len; - -- page = alloc_page(GFP_NOIO | gfp_mask); -+ page = alloc_page(GFP_NOIO | __GFP_ZERO | gfp_mask); - if (!page) - goto cleanup; - -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 652a31fc3bb38..82de39926a9f6 100644 ---- a/block/blk-mq.c -+++ b/block/blk-mq.c -@@ -763,7 +763,6 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list) - /* this request will be re-inserted to io scheduler queue */ - blk_mq_sched_requeue_request(rq); - -- BUG_ON(!list_empty(&rq->queuelist)); - blk_mq_add_to_requeue_list(rq, true, kick_requeue_list); - } - EXPORT_SYMBOL(blk_mq_requeue_request); -@@ -2148,14 +2147,14 @@ static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq) - } - - /* -- * Allow 4x BLK_MAX_REQUEST_COUNT requests on plug queue for multiple -+ * Allow 2x BLK_MAX_REQUEST_COUNT requests on plug queue for multiple - * queues. This is important for md arrays to benefit from merging - * requests. - */ - static inline unsigned short blk_plug_max_rq_count(struct blk_plug *plug) - { - if (plug->multiple_queues) -- return BLK_MAX_REQUEST_COUNT * 4; -+ return BLK_MAX_REQUEST_COUNT * 2; - return BLK_MAX_REQUEST_COUNT; - } - -@@ -4019,6 +4018,19 @@ unsigned int blk_mq_rq_cpu(struct request *rq) - } - EXPORT_SYMBOL(blk_mq_rq_cpu); - -+void blk_mq_cancel_work_sync(struct request_queue *q) -+{ -+ if (queue_is_mq(q)) { -+ struct blk_mq_hw_ctx *hctx; -+ int i; -+ -+ cancel_delayed_work_sync(&q->requeue_work); -+ -+ queue_for_each_hw_ctx(q, hctx, i) -+ cancel_delayed_work_sync(&hctx->run_work); -+ } -+} -+ - static int __init blk_mq_init(void) - { - int i; -diff --git a/block/blk-mq.h b/block/blk-mq.h -index d08779f77a265..7cdca23b6263d 100644 ---- a/block/blk-mq.h -+++ b/block/blk-mq.h -@@ -129,6 +129,8 @@ extern int blk_mq_sysfs_register(struct request_queue *q); - extern void blk_mq_sysfs_unregister(struct request_queue *q); - extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx); - -+void blk_mq_cancel_work_sync(struct request_queue *q); -+ - void blk_mq_release(struct request_queue *q); - - static inline struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q, -diff --git a/block/blk-pm.c b/block/blk-pm.c -index 17bd020268d42..2dad62cc15727 100644 ---- a/block/blk-pm.c -+++ b/block/blk-pm.c -@@ -163,27 +163,19 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); - /** - * blk_post_runtime_resume - Post runtime resume processing - * @q: the queue of the device -- * @err: return value of the device's runtime_resume function - * - * Description: -- * Update the queue's runtime status according to the return value of the -- * device's runtime_resume function. If the resume was successful, call -- * blk_set_runtime_active() to do the real work of restarting the queue. -+ * For historical reasons, this routine merely calls blk_set_runtime_active() -+ * to do the real work of restarting the queue. It does this regardless of -+ * whether the device's runtime-resume succeeded; even if it failed the -+ * driver or error handler will need to communicate with the device. - * - * This function should be called near the end of the device's - * runtime_resume callback. - */ --void blk_post_runtime_resume(struct request_queue *q, int err) -+void blk_post_runtime_resume(struct request_queue *q) - { -- if (!q->dev) -- return; -- if (!err) { -- blk_set_runtime_active(q); -- } else { -- spin_lock_irq(&q->queue_lock); -- q->rpm_status = RPM_SUSPENDED; -- spin_unlock_irq(&q->queue_lock); -- } -+ blk_set_runtime_active(q); - } - EXPORT_SYMBOL(blk_post_runtime_resume); - -@@ -201,7 +193,7 @@ EXPORT_SYMBOL(blk_post_runtime_resume); - * runtime PM status and re-enable peeking requests from the queue. It - * should be called before first request is added to the queue. - * -- * This function is also called by blk_post_runtime_resume() for successful -+ * This function is also called by blk_post_runtime_resume() for - * runtime resumes. It does everything necessary to restart the queue. - */ - void blk_set_runtime_active(struct request_queue *q) -diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c -index 614d9d47de36b..4737ec024ee9b 100644 ---- a/block/blk-sysfs.c -+++ b/block/blk-sysfs.c -@@ -805,16 +805,6 @@ static void blk_release_queue(struct kobject *kobj) - - blk_free_queue_stats(q->stats); - -- if (queue_is_mq(q)) { -- struct blk_mq_hw_ctx *hctx; -- int i; -- -- cancel_delayed_work_sync(&q->requeue_work); -- -- queue_for_each_hw_ctx(q, hctx, i) -- cancel_delayed_work_sync(&hctx->run_work); -- } -- - blk_exit_queue(q); - - blk_queue_free_zone_bitmaps(q); -diff --git a/block/blk-wbt.c b/block/blk-wbt.c -index 874c1c37bf0c6..0c119be0e8133 100644 ---- a/block/blk-wbt.c -+++ b/block/blk-wbt.c -@@ -357,6 +357,9 @@ static void wb_timer_fn(struct blk_stat_callback *cb) - unsigned int inflight = wbt_inflight(rwb); - int status; - -+ if (!rwb->rqos.q->disk) -+ return; -+ - status = latency_exceeded(rwb, cb->stat); - - trace_wbt_timer(rwb->rqos.q->disk->bdi, status, rqd->scale_step, -diff --git a/block/blk-zoned.c b/block/blk-zoned.c -index 1d0c76c18fc52..774ecc598bee2 100644 ---- a/block/blk-zoned.c -+++ b/block/blk-zoned.c -@@ -429,9 +429,10 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, - op = REQ_OP_ZONE_RESET; - - /* Invalidate the page cache, including dirty pages. */ -+ filemap_invalidate_lock(bdev->bd_inode->i_mapping); - ret = blkdev_truncate_zone_range(bdev, mode, &zrange); - if (ret) -- return ret; -+ goto fail; - break; - case BLKOPENZONE: - op = REQ_OP_ZONE_OPEN; -@@ -449,15 +450,9 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, - ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors, - GFP_KERNEL); - -- /* -- * Invalidate the page cache again for zone reset: writes can only be -- * direct for zoned devices so concurrent writes would not add any page -- * to the page cache after/during reset. The page cache may be filled -- * again due to concurrent reads though and dropping the pages for -- * these is fine. -- */ -- if (!ret && cmd == BLKRESETZONE) -- ret = blkdev_truncate_zone_range(bdev, mode, &zrange); -+fail: -+ if (cmd == BLKRESETZONE) -+ filemap_invalidate_unlock(bdev->bd_inode->i_mapping); - - return ret; - } -diff --git a/block/blk.h b/block/blk.h -index 6c3c00a8fe19d..aab72194d2266 100644 ---- a/block/blk.h -+++ b/block/blk.h -@@ -184,6 +184,12 @@ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list, - void blk_account_io_start(struct request *req); - void blk_account_io_done(struct request *req, u64 now); - -+/* -+ * Plug flush limits -+ */ -+#define BLK_MAX_REQUEST_COUNT 32 -+#define BLK_PLUG_FLUSH_SIZE (128 * 1024) -+ - /* - * Internal elevator interface - */ -diff --git a/block/elevator.c b/block/elevator.c -index ff45d8388f487..1b5e57f6115f3 100644 ---- a/block/elevator.c -+++ b/block/elevator.c -@@ -523,8 +523,6 @@ void elv_unregister_queue(struct request_queue *q) - kobject_del(&e->kobj); - - e->registered = 0; -- /* Re-enable throttling in case elevator disabled it */ -- wbt_enable_default(q); - } - } - -@@ -694,12 +692,18 @@ void elevator_init_mq(struct request_queue *q) - if (!e) - return; - -+ /* -+ * We are called before adding disk, when there isn't any FS I/O, -+ * so freezing queue plus canceling dispatch work is enough to -+ * drain any dispatch activities originated from passthrough -+ * requests, then no need to quiesce queue which may add long boot -+ * latency, especially when lots of disks are involved. -+ */ - blk_mq_freeze_queue(q); -- blk_mq_quiesce_queue(q); -+ blk_mq_cancel_work_sync(q); - - err = blk_mq_init_sched(q, e); - -- blk_mq_unquiesce_queue(q); - blk_mq_unfreeze_queue(q); - - if (err) { -diff --git a/block/genhd.c b/block/genhd.c -index ab12ae6e636e8..2dcedbe4ef046 100644 ---- a/block/genhd.c -+++ b/block/genhd.c -@@ -420,6 +420,8 @@ int device_add_disk(struct device *parent, struct gendisk *disk, - DISK_MAX_PARTS); - disk->minors = DISK_MAX_PARTS; - } -+ if (disk->first_minor + disk->minors > MINORMASK + 1) -+ return -EINVAL; - } else { - if (WARN_ON(disk->minors)) - return -EINVAL; -@@ -432,10 +434,6 @@ int device_add_disk(struct device *parent, struct gendisk *disk, - disk->flags |= GENHD_FL_EXT_DEVT; - } - -- ret = disk_alloc_events(disk); -- if (ret) -- goto out_free_ext_minor; -- - /* delay uevents, until we scanned partition table */ - dev_set_uevent_suppress(ddev, 1); - -@@ -446,7 +444,12 @@ int device_add_disk(struct device *parent, struct gendisk *disk, - ddev->devt = MKDEV(disk->major, disk->first_minor); - ret = device_add(ddev); - if (ret) -- goto out_disk_release_events; -+ goto out_free_ext_minor; -+ -+ ret = disk_alloc_events(disk); -+ if (ret) -+ goto out_device_del; -+ - if (!sysfs_deprecated) { - ret = sysfs_create_link(block_depr, &ddev->kobj, - kobject_name(&ddev->kobj)); -@@ -467,11 +470,15 @@ int device_add_disk(struct device *parent, struct gendisk *disk, - - disk->part0->bd_holder_dir = - kobject_create_and_add("holders", &ddev->kobj); -- if (!disk->part0->bd_holder_dir) -+ if (!disk->part0->bd_holder_dir) { -+ ret = -ENOMEM; - goto out_del_integrity; -+ } - disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); -- if (!disk->slave_dir) -+ if (!disk->slave_dir) { -+ ret = -ENOMEM; - goto out_put_holder_dir; -+ } - - ret = bd_register_pending_holders(disk); - if (ret < 0) -@@ -530,8 +537,6 @@ out_del_block_link: - sysfs_remove_link(block_depr, dev_name(ddev)); - out_device_del: - device_del(ddev); --out_disk_release_events: -- disk_release_events(disk); - out_free_ext_minor: - if (disk->major == BLOCK_EXT_MAJOR) - blk_free_ext_minor(disk->first_minor); -@@ -539,6 +544,20 @@ out_free_ext_minor: - } - EXPORT_SYMBOL(device_add_disk); - -+/** -+ * blk_mark_disk_dead - mark a disk as dead -+ * @disk: disk to mark as dead -+ * -+ * Mark as disk as dead (e.g. surprise removed) and don't accept any new I/O -+ * to this disk. -+ */ -+void blk_mark_disk_dead(struct gendisk *disk) -+{ -+ set_bit(GD_DEAD, &disk->state); -+ blk_queue_start_drain(disk->queue); -+} -+EXPORT_SYMBOL_GPL(blk_mark_disk_dead); -+ - /** - * del_gendisk - remove the gendisk - * @disk: the struct gendisk to remove -@@ -1082,6 +1101,8 @@ static void disk_release(struct device *dev) - might_sleep(); - WARN_ON_ONCE(disk_live(disk)); - -+ blk_mq_cancel_work_sync(disk->queue); -+ - disk_release_events(disk); - kfree(disk->random); - xa_destroy(&disk->part_tbl); -diff --git a/block/ioctl.c b/block/ioctl.c -index eb0491e90b9a0..a31be7fa31a51 100644 ---- a/block/ioctl.c -+++ b/block/ioctl.c -@@ -113,6 +113,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, - uint64_t range[2]; - uint64_t start, len; - struct request_queue *q = bdev_get_queue(bdev); -+ struct inode *inode = bdev->bd_inode; - int err; - - if (!(mode & FMODE_WRITE)) -@@ -135,12 +136,17 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, - if (start + len > i_size_read(bdev->bd_inode)) - return -EINVAL; - -+ filemap_invalidate_lock(inode->i_mapping); - err = truncate_bdev_range(bdev, mode, start, start + len - 1); - if (err) -- return err; -+ goto fail; - -- return blkdev_issue_discard(bdev, start >> 9, len >> 9, -- GFP_KERNEL, flags); -+ err = blkdev_issue_discard(bdev, start >> 9, len >> 9, -+ GFP_KERNEL, flags); -+ -+fail: -+ filemap_invalidate_unlock(inode->i_mapping); -+ return err; - } - - static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode, -@@ -148,6 +154,7 @@ static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode, - { - uint64_t range[2]; - uint64_t start, end, len; -+ struct inode *inode = bdev->bd_inode; - int err; - - if (!(mode & FMODE_WRITE)) -@@ -170,12 +177,17 @@ static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode, - return -EINVAL; - - /* Invalidate the page cache, including dirty pages */ -+ filemap_invalidate_lock(inode->i_mapping); - err = truncate_bdev_range(bdev, mode, start, end); - if (err) -- return err; -+ goto fail; -+ -+ err = blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL, -+ BLKDEV_ZERO_NOUNMAP); - -- return blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL, -- BLKDEV_ZERO_NOUNMAP); -+fail: -+ filemap_invalidate_unlock(inode->i_mapping); -+ return err; - } - - static int put_ushort(unsigned short __user *argp, unsigned short val) -diff --git a/block/ioprio.c b/block/ioprio.c -index 0e4ff245f2bf2..6f01d35a5145a 100644 ---- a/block/ioprio.c -+++ b/block/ioprio.c -@@ -69,7 +69,14 @@ int ioprio_check_cap(int ioprio) - - switch (class) { - case IOPRIO_CLASS_RT: -- if (!capable(CAP_SYS_NICE) && !capable(CAP_SYS_ADMIN)) -+ /* -+ * Originally this only checked for CAP_SYS_ADMIN, -+ * which was implicitly allowed for pid 0 by security -+ * modules such as SELinux. Make sure we check -+ * CAP_SYS_ADMIN first to avoid a denial/avc for -+ * possibly missing CAP_SYS_NICE permission. -+ */ -+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) - return -EPERM; - fallthrough; - /* rt has prio field too */ -@@ -213,6 +220,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) - pgrp = task_pgrp(current); - else - pgrp = find_vpid(who); -+ read_lock(&tasklist_lock); - do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { - tmpio = get_task_ioprio(p); - if (tmpio < 0) -@@ -222,6 +230,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) - else - ret = ioprio_best(ret, tmpio); - } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); -+ read_unlock(&tasklist_lock); -+ - break; - case IOPRIO_WHO_USER: - uid = make_kuid(current_user_ns(), who); -diff --git a/block/mq-deadline.c b/block/mq-deadline.c -index 7f3c3932b723e..cd2342d297048 100644 ---- a/block/mq-deadline.c -+++ b/block/mq-deadline.c -@@ -811,7 +811,7 @@ SHOW_JIFFIES(deadline_read_expire_show, dd->fifo_expire[DD_READ]); - SHOW_JIFFIES(deadline_write_expire_show, dd->fifo_expire[DD_WRITE]); - SHOW_INT(deadline_writes_starved_show, dd->writes_starved); - SHOW_INT(deadline_front_merges_show, dd->front_merges); --SHOW_INT(deadline_async_depth_show, dd->front_merges); -+SHOW_INT(deadline_async_depth_show, dd->async_depth); - SHOW_INT(deadline_fifo_batch_show, dd->fifo_batch); - #undef SHOW_INT - #undef SHOW_JIFFIES -@@ -840,7 +840,7 @@ STORE_JIFFIES(deadline_read_expire_store, &dd->fifo_expire[DD_READ], 0, INT_MAX) - STORE_JIFFIES(deadline_write_expire_store, &dd->fifo_expire[DD_WRITE], 0, INT_MAX); - STORE_INT(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX); - STORE_INT(deadline_front_merges_store, &dd->front_merges, 0, 1); --STORE_INT(deadline_async_depth_store, &dd->front_merges, 1, INT_MAX); -+STORE_INT(deadline_async_depth_store, &dd->async_depth, 1, INT_MAX); - STORE_INT(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX); - #undef STORE_FUNCTION - #undef STORE_INT -diff --git a/crypto/Kconfig b/crypto/Kconfig -index 536df4b6b825c..285f82647d2b7 100644 ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -233,12 +233,12 @@ config CRYPTO_DH - - config CRYPTO_ECC - tristate -+ select CRYPTO_RNG_DEFAULT - - config CRYPTO_ECDH - tristate "ECDH algorithm" - select CRYPTO_ECC - select CRYPTO_KPP -- select CRYPTO_RNG_DEFAULT - help - Generic implementation of the ECDH algorithm - -diff --git a/crypto/algapi.c b/crypto/algapi.c -index 43f999dba4dc0..f3d95af3e4284 100644 ---- a/crypto/algapi.c -+++ b/crypto/algapi.c -@@ -1277,3 +1277,4 @@ module_exit(crypto_algapi_exit); - - MODULE_LICENSE("GPL"); - MODULE_DESCRIPTION("Cryptographic algorithms API"); -+MODULE_SOFTDEP("pre: cryptomgr"); -diff --git a/crypto/api.c b/crypto/api.c -index c4eda56cff891..5ffcd3ab4a753 100644 ---- a/crypto/api.c -+++ b/crypto/api.c -@@ -603,4 +603,3 @@ EXPORT_SYMBOL_GPL(crypto_req_done); - - MODULE_DESCRIPTION("Cryptographic core API"); - MODULE_LICENSE("GPL"); --MODULE_SOFTDEP("pre: cryptomgr"); -diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c -index a11b3208760f3..f6d3a84e3c214 100644 ---- a/crypto/jitterentropy.c -+++ b/crypto/jitterentropy.c -@@ -265,7 +265,6 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) - { - __u64 delta2 = jent_delta(ec->last_delta, current_delta); - __u64 delta3 = jent_delta(ec->last_delta2, delta2); -- unsigned int delta_masked = current_delta & JENT_APT_WORD_MASK; - - ec->last_delta = current_delta; - ec->last_delta2 = delta2; -@@ -274,7 +273,7 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) - * Insert the result of the comparison of two back-to-back time - * deltas. - */ -- jent_apt_insert(ec, delta_masked); -+ jent_apt_insert(ec, current_delta); - - if (!current_delta || !delta2 || !delta3) { - /* RCT with a stuck bit */ -diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c -index d569c7ed6c800..9d10b846ccf73 100644 ---- a/crypto/pcrypt.c -+++ b/crypto/pcrypt.c -@@ -78,12 +78,14 @@ static void pcrypt_aead_enc(struct padata_priv *padata) - { - struct pcrypt_request *preq = pcrypt_padata_request(padata); - struct aead_request *req = pcrypt_request_ctx(preq); -+ int ret; - -- padata->info = crypto_aead_encrypt(req); -+ ret = crypto_aead_encrypt(req); - -- if (padata->info == -EINPROGRESS) -+ if (ret == -EINPROGRESS) - return; - -+ padata->info = ret; - padata_do_serial(padata); - } - -@@ -123,12 +125,14 @@ static void pcrypt_aead_dec(struct padata_priv *padata) - { - struct pcrypt_request *preq = pcrypt_padata_request(padata); - struct aead_request *req = pcrypt_request_ctx(preq); -+ int ret; - -- padata->info = crypto_aead_decrypt(req); -+ ret = crypto_aead_decrypt(req); - -- if (padata->info == -EINPROGRESS) -+ if (ret == -EINPROGRESS) - return; - -+ padata->info = ret; - padata_do_serial(padata); - } - -diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c -index 82b0400985a51..00149657a4bc1 100644 ---- a/crypto/tcrypt.c -+++ b/crypto/tcrypt.c -@@ -1333,7 +1333,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, - - if (bs > XBUFSIZE * PAGE_SIZE) { - pr_err("template (%u) too big for buffer (%lu)\n", -- *b_size, XBUFSIZE * PAGE_SIZE); -+ bs, XBUFSIZE * PAGE_SIZE); - goto out; - } - -@@ -1386,8 +1386,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, - memset(cur->xbuf[p], 0xff, k); - - skcipher_request_set_crypt(cur->req, cur->sg, -- cur->sg, *b_size, -- iv); -+ cur->sg, bs, iv); - } - - if (secs) { -diff --git a/drivers/Makefile b/drivers/Makefile -index be5d40ae14882..a110338c860c7 100644 ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -41,8 +41,7 @@ obj-$(CONFIG_DMADEVICES) += dma/ - # SOC specific infrastructure drivers. - obj-y += soc/ - --obj-$(CONFIG_VIRTIO) += virtio/ --obj-$(CONFIG_VIRTIO_PCI_LIB) += virtio/ -+obj-y += virtio/ - obj-$(CONFIG_VDPA) += vdpa/ - obj-$(CONFIG_XEN) += xen/ - -diff --git a/drivers/accessibility/speakup/speakup_dectlk.c b/drivers/accessibility/speakup/speakup_dectlk.c -index 580ec796816bc..78ca4987e619e 100644 ---- a/drivers/accessibility/speakup/speakup_dectlk.c -+++ b/drivers/accessibility/speakup/speakup_dectlk.c -@@ -44,6 +44,7 @@ static struct var_t vars[] = { - { CAPS_START, .u.s = {"[:dv ap 160] " } }, - { CAPS_STOP, .u.s = {"[:dv ap 100 ] " } }, - { RATE, .u.n = {"[:ra %d] ", 180, 75, 650, 0, 0, NULL } }, -+ { PITCH, .u.n = {"[:dv ap %d] ", 122, 50, 350, 0, 0, NULL } }, - { INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } }, - { VOL, .u.n = {"[:dv g5 %d] ", 86, 60, 86, 0, 0, NULL } }, - { PUNCT, .u.n = {"[:pu %c] ", 0, 0, 2, 0, 0, "nsa" } }, -diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c -index b0cb662233f1a..81aff651a0d49 100644 ---- a/drivers/acpi/ac.c -+++ b/drivers/acpi/ac.c -@@ -61,6 +61,7 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); - - static int ac_sleep_before_get_state_ms; - static int ac_check_pmic = 1; -+static int ac_only; - - static struct acpi_driver acpi_ac_driver = { - .name = "ac", -@@ -93,6 +94,11 @@ static int acpi_ac_get_state(struct acpi_ac *ac) - if (!ac) - return -EINVAL; - -+ if (ac_only) { -+ ac->state = 1; -+ return 0; -+ } -+ - status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, - &ac->state); - if (ACPI_FAILURE(status)) { -@@ -200,6 +206,12 @@ static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d) - return 0; - } - -+static int __init ac_only_quirk(const struct dmi_system_id *d) -+{ -+ ac_only = 1; -+ return 0; -+} -+ - /* Please keep this list alphabetically sorted */ - static const struct dmi_system_id ac_dmi_table[] __initconst = { - { -@@ -209,6 +221,13 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = { - DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), - }, - }, -+ { -+ /* Kodlix GK45 returning incorrect state */ -+ .callback = ac_only_quirk, -+ .matches = { -+ DMI_MATCH(DMI_PRODUCT_NAME, "GK45"), -+ }, -+ }, - { - /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ - .callback = ac_do_not_check_pmic_quirk, -diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h -index d41b810e367c4..4366d36ef1198 100644 ---- a/drivers/acpi/acpica/acglobal.h -+++ b/drivers/acpi/acpica/acglobal.h -@@ -226,6 +226,8 @@ extern struct acpi_bit_register_info - acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; - ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); - ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b); -+ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0); -+ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b_s0); - - /***************************************************************************** - * -diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c -index 06f3c9df1e22d..8618500f23b39 100644 ---- a/drivers/acpi/acpica/exfield.c -+++ b/drivers/acpi/acpica/exfield.c -@@ -330,12 +330,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, - obj_desc->field.base_byte_offset, - source_desc->buffer.pointer, data_length); - -- if ((obj_desc->field.region_obj->region.address == -- PCC_MASTER_SUBSPACE -- && MASTER_SUBSPACE_COMMAND(obj_desc->field. -- base_byte_offset)) -- || GENERIC_SUBSPACE_COMMAND(obj_desc->field. -- base_byte_offset)) { -+ if (MASTER_SUBSPACE_COMMAND(obj_desc->field.base_byte_offset)) { - - /* Perform the write */ - -diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c -index b639e930d6429..44b7c350ed5ca 100644 ---- a/drivers/acpi/acpica/exoparg1.c -+++ b/drivers/acpi/acpica/exoparg1.c -@@ -1007,7 +1007,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) - (walk_state, return_desc, - &temp_desc); - if (ACPI_FAILURE(status)) { -- goto cleanup; -+ return_ACPI_STATUS -+ (status); - } - - return_desc = temp_desc; -diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c -index 803402aefaeb6..7ee2939c08cd4 100644 ---- a/drivers/acpi/acpica/hwesleep.c -+++ b/drivers/acpi/acpica/hwesleep.c -@@ -104,7 +104,9 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) - - /* Flush caches, as per ACPI specification */ - -- ACPI_FLUSH_CPU_CACHE(); -+ if (sleep_state < ACPI_STATE_S4) { -+ ACPI_FLUSH_CPU_CACHE(); -+ } - - status = acpi_os_enter_sleep(sleep_state, sleep_control, 0); - if (status == AE_CTRL_TERMINATE) { -@@ -147,17 +149,13 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) - - acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) - { -- acpi_status status; - u8 sleep_type_value; - - ACPI_FUNCTION_TRACE(hw_extended_wake_prep); - -- status = acpi_get_sleep_type_data(ACPI_STATE_S0, -- &acpi_gbl_sleep_type_a, -- &acpi_gbl_sleep_type_b); -- if (ACPI_SUCCESS(status)) { -+ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) { - sleep_type_value = -- ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & -+ ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) & - ACPI_X_SLEEP_TYPE_MASK); - - (void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE), -diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c -index 14baa13bf8482..5efa3d8e483e0 100644 ---- a/drivers/acpi/acpica/hwsleep.c -+++ b/drivers/acpi/acpica/hwsleep.c -@@ -110,7 +110,9 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) - - /* Flush caches, as per ACPI specification */ - -- ACPI_FLUSH_CPU_CACHE(); -+ if (sleep_state < ACPI_STATE_S4) { -+ ACPI_FLUSH_CPU_CACHE(); -+ } - - status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control); - if (status == AE_CTRL_TERMINATE) { -@@ -179,7 +181,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) - - acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) - { -- acpi_status status; -+ acpi_status status = AE_OK; - struct acpi_bit_register_info *sleep_type_reg_info; - struct acpi_bit_register_info *sleep_enable_reg_info; - u32 pm1a_control; -@@ -192,10 +194,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) - * This is unclear from the ACPI Spec, but it is required - * by some machines. - */ -- status = acpi_get_sleep_type_data(ACPI_STATE_S0, -- &acpi_gbl_sleep_type_a, -- &acpi_gbl_sleep_type_b); -- if (ACPI_SUCCESS(status)) { -+ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) { - sleep_type_reg_info = - acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); - sleep_enable_reg_info = -@@ -216,9 +215,9 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) - - /* Insert the SLP_TYP bits */ - -- pm1a_control |= (acpi_gbl_sleep_type_a << -+ pm1a_control |= (acpi_gbl_sleep_type_a_s0 << - sleep_type_reg_info->bit_position); -- pm1b_control |= (acpi_gbl_sleep_type_b << -+ pm1b_control |= (acpi_gbl_sleep_type_b_s0 << - sleep_type_reg_info->bit_position); - - /* Write the control registers and ignore any errors */ -diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c -index 89b12afed564e..ba77598ee43e8 100644 ---- a/drivers/acpi/acpica/hwxfsleep.c -+++ b/drivers/acpi/acpica/hwxfsleep.c -@@ -162,8 +162,6 @@ acpi_status acpi_enter_sleep_state_s4bios(void) - return_ACPI_STATUS(status); - } - -- ACPI_FLUSH_CPU_CACHE(); -- - status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, - (u32)acpi_gbl_FADT.s4_bios_request, 8); - if (ACPI_FAILURE(status)) { -@@ -217,6 +215,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) - return_ACPI_STATUS(status); - } - -+ status = acpi_get_sleep_type_data(ACPI_STATE_S0, -+ &acpi_gbl_sleep_type_a_s0, -+ &acpi_gbl_sleep_type_b_s0); -+ if (ACPI_FAILURE(status)) { -+ acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID; -+ } -+ - /* Execute the _PTS method (Prepare To Sleep) */ - - arg_list.count = 1; -diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c -index e5ba9795ec696..8d7736d2d2699 100644 ---- a/drivers/acpi/acpica/utdelete.c -+++ b/drivers/acpi/acpica/utdelete.c -@@ -422,6 +422,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) - ACPI_WARNING((AE_INFO, - "Obj %p, Reference Count is already zero, cannot decrement\n", - object)); -+ return; - } - - ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS, -diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c -index 3b23fb775ac45..f2f8f05662deb 100644 ---- a/drivers/acpi/arm64/iort.c -+++ b/drivers/acpi/arm64/iort.c -@@ -1361,9 +1361,17 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res, - res[0].start = pmcg->page0_base_address; - res[0].end = pmcg->page0_base_address + SZ_4K - 1; - res[0].flags = IORESOURCE_MEM; -- res[1].start = pmcg->page1_base_address; -- res[1].end = pmcg->page1_base_address + SZ_4K - 1; -- res[1].flags = IORESOURCE_MEM; -+ /* -+ * The initial version in DEN0049C lacked a way to describe register -+ * page 1, which makes it broken for most PMCG implementations; in -+ * that case, just let the driver fail gracefully if it expects to -+ * find a second memory resource. -+ */ -+ if (node->revision > 0) { -+ res[1].start = pmcg->page1_base_address; -+ res[1].end = pmcg->page1_base_address + SZ_4K - 1; -+ res[1].flags = IORESOURCE_MEM; -+ } - - if (pmcg->overflow_gsiv) - acpi_iort_register_irq(pmcg->overflow_gsiv, "overflow", -diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c -index dae91f906cea9..ead0114f27c9f 100644 ---- a/drivers/acpi/battery.c -+++ b/drivers/acpi/battery.c -@@ -53,6 +53,7 @@ static int battery_bix_broken_package; - static int battery_notification_delay_ms; - static int battery_ac_is_broken; - static int battery_check_pmic = 1; -+static int battery_quirk_notcharging; - static unsigned int cache_time = 1000; - module_param(cache_time, uint, 0644); - MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); -@@ -169,7 +170,7 @@ static int acpi_battery_is_charged(struct acpi_battery *battery) - return 1; - - /* fallback to using design values for broken batteries */ -- if (battery->design_capacity == battery->capacity_now) -+ if (battery->design_capacity <= battery->capacity_now) - return 1; - - /* we don't do any sort of metric based on percentages */ -@@ -217,6 +218,8 @@ static int acpi_battery_get_property(struct power_supply *psy, - val->intval = POWER_SUPPLY_STATUS_CHARGING; - else if (acpi_battery_is_charged(battery)) - val->intval = POWER_SUPPLY_STATUS_FULL; -+ else if (battery_quirk_notcharging) -+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; - else - val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - break; -@@ -1111,6 +1114,12 @@ battery_do_not_check_pmic_quirk(const struct dmi_system_id *d) - return 0; - } - -+static int __init battery_quirk_not_charging(const struct dmi_system_id *d) -+{ -+ battery_quirk_notcharging = 1; -+ return 0; -+} -+ - static const struct dmi_system_id bat_dmi_table[] __initconst = { - { - /* NEC LZ750/LS */ -@@ -1155,6 +1164,19 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), - }, - }, -+ { -+ /* -+ * On Lenovo ThinkPads the BIOS specification defines -+ * a state when the bits for charging and discharging -+ * are both set to 0. That state is "Not Charging". -+ */ -+ .callback = battery_quirk_not_charging, -+ .ident = "Lenovo ThinkPad", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"), -+ }, -+ }, - {}, - }; - -diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c -index fa923a9292244..dd535b4b9a160 100644 ---- a/drivers/acpi/bus.c -+++ b/drivers/acpi/bus.c -@@ -98,8 +98,8 @@ int acpi_bus_get_status(struct acpi_device *device) - acpi_status status; - unsigned long long sta; - -- if (acpi_device_always_present(device)) { -- acpi_set_device_status(device, ACPI_STA_DEFAULT); -+ if (acpi_device_override_status(device, &sta)) { -+ acpi_set_device_status(device, sta); - return 0; - } - -diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c -index bd482108310cf..6fe28a2d387bd 100644 ---- a/drivers/acpi/cppc_acpi.c -+++ b/drivers/acpi/cppc_acpi.c -@@ -411,7 +411,7 @@ bool acpi_cpc_valid(void) - struct cpc_desc *cpc_ptr; - int cpu; - -- for_each_possible_cpu(cpu) { -+ for_each_present_cpu(cpu) { - cpc_ptr = per_cpu(cpc_desc_ptr, cpu); - if (!cpc_ptr) - return false; -@@ -1011,7 +1011,14 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) - static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf) - { - struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); -- struct cpc_register_resource *reg = &cpc_desc->cpc_regs[reg_idx]; -+ struct cpc_register_resource *reg; -+ -+ if (!cpc_desc) { -+ pr_debug("No CPC descriptor for CPU:%d\n", cpunum); -+ return -ENODEV; -+ } -+ -+ reg = &cpc_desc->cpc_regs[reg_idx]; - - if (CPC_IN_PCC(reg)) { - int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); -diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c -index e629e891d1bb3..9b859ff976e89 100644 ---- a/drivers/acpi/ec.c -+++ b/drivers/acpi/ec.c -@@ -166,6 +166,7 @@ struct acpi_ec_query { - struct transaction transaction; - struct work_struct work; - struct acpi_ec_query_handler *handler; -+ struct acpi_ec *ec; - }; - - static int acpi_ec_query(struct acpi_ec *ec, u8 *data); -@@ -452,6 +453,7 @@ static void acpi_ec_submit_query(struct acpi_ec *ec) - ec_dbg_evt("Command(%s) submitted/blocked", - acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); - ec->nr_pending_queries++; -+ ec->events_in_progress++; - queue_work(ec_wq, &ec->work); - } - } -@@ -518,7 +520,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) - #ifdef CONFIG_PM_SLEEP - static void __acpi_ec_flush_work(void) - { -- drain_workqueue(ec_wq); /* flush ec->work */ -+ flush_workqueue(ec_wq); /* flush ec->work */ - flush_workqueue(ec_query_wq); /* flush queries */ - } - -@@ -1103,7 +1105,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) - } - EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); - --static struct acpi_ec_query *acpi_ec_create_query(u8 *pval) -+static struct acpi_ec_query *acpi_ec_create_query(struct acpi_ec *ec, u8 *pval) - { - struct acpi_ec_query *q; - struct transaction *t; -@@ -1111,11 +1113,13 @@ static struct acpi_ec_query *acpi_ec_create_query(u8 *pval) - q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); - if (!q) - return NULL; -+ - INIT_WORK(&q->work, acpi_ec_event_processor); - t = &q->transaction; - t->command = ACPI_EC_COMMAND_QUERY; - t->rdata = pval; - t->rlen = 1; -+ q->ec = ec; - return q; - } - -@@ -1132,13 +1136,21 @@ static void acpi_ec_event_processor(struct work_struct *work) - { - struct acpi_ec_query *q = container_of(work, struct acpi_ec_query, work); - struct acpi_ec_query_handler *handler = q->handler; -+ struct acpi_ec *ec = q->ec; - - ec_dbg_evt("Query(0x%02x) started", handler->query_bit); -+ - if (handler->func) - handler->func(handler->data); - else if (handler->handle) - acpi_evaluate_object(handler->handle, NULL, NULL, NULL); -+ - ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit); -+ -+ spin_lock_irq(&ec->lock); -+ ec->queries_in_progress--; -+ spin_unlock_irq(&ec->lock); -+ - acpi_ec_delete_query(q); - } - -@@ -1148,7 +1160,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) - int result; - struct acpi_ec_query *q; - -- q = acpi_ec_create_query(&value); -+ q = acpi_ec_create_query(ec, &value); - if (!q) - return -ENOMEM; - -@@ -1170,19 +1182,20 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) - } - - /* -- * It is reported that _Qxx are evaluated in a parallel way on -- * Windows: -+ * It is reported that _Qxx are evaluated in a parallel way on Windows: - * https://bugzilla.kernel.org/show_bug.cgi?id=94411 - * -- * Put this log entry before schedule_work() in order to make -- * it appearing before any other log entries occurred during the -- * work queue execution. -+ * Put this log entry before queue_work() to make it appear in the log -+ * before any other messages emitted during workqueue handling. - */ - ec_dbg_evt("Query(0x%02x) scheduled", value); -- if (!queue_work(ec_query_wq, &q->work)) { -- ec_dbg_evt("Query(0x%02x) overlapped", value); -- result = -EBUSY; -- } -+ -+ spin_lock_irq(&ec->lock); -+ -+ ec->queries_in_progress++; -+ queue_work(ec_query_wq, &q->work); -+ -+ spin_unlock_irq(&ec->lock); - - err_exit: - if (result) -@@ -1240,6 +1253,10 @@ static void acpi_ec_event_handler(struct work_struct *work) - ec_dbg_evt("Event stopped"); - - acpi_ec_check_event(ec); -+ -+ spin_lock_irqsave(&ec->lock, flags); -+ ec->events_in_progress--; -+ spin_unlock_irqrestore(&ec->lock, flags); - } - - static void acpi_ec_handle_interrupt(struct acpi_ec *ec) -@@ -2021,6 +2038,7 @@ void acpi_ec_set_gpe_wake_mask(u8 action) - - bool acpi_ec_dispatch_gpe(void) - { -+ bool work_in_progress; - u32 ret; - - if (!first_ec) -@@ -2041,8 +2059,19 @@ bool acpi_ec_dispatch_gpe(void) - if (ret == ACPI_INTERRUPT_HANDLED) - pm_pr_dbg("ACPI EC GPE dispatched\n"); - -- /* Flush the event and query workqueues. */ -- acpi_ec_flush_work(); -+ /* Drain EC work. */ -+ do { -+ acpi_ec_flush_work(); -+ -+ pm_pr_dbg("ACPI EC work flushed\n"); -+ -+ spin_lock_irq(&first_ec->lock); -+ -+ work_in_progress = first_ec->events_in_progress + -+ first_ec->queries_in_progress > 0; -+ -+ spin_unlock_irq(&first_ec->lock); -+ } while (work_in_progress && !pm_wakeup_pending()); - - return false; - } -diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h -index d91b560e88674..54b2be94d23dc 100644 ---- a/drivers/acpi/internal.h -+++ b/drivers/acpi/internal.h -@@ -183,6 +183,8 @@ struct acpi_ec { - struct work_struct work; - unsigned long timestamp; - unsigned long nr_pending_queries; -+ unsigned int events_in_progress; -+ unsigned int queries_in_progress; - bool busy_polling; - unsigned int polling_guard; - }; -diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c -index a371f273f99dd..9cde299eba880 100644 ---- a/drivers/acpi/pmic/intel_pmic.c -+++ b/drivers/acpi/pmic/intel_pmic.c -@@ -211,31 +211,36 @@ static acpi_status intel_pmic_regs_handler(u32 function, - void *handler_context, void *region_context) - { - struct intel_pmic_opregion *opregion = region_context; -- int result = 0; -+ int result = -EINVAL; -+ -+ if (function == ACPI_WRITE) { -+ switch (address) { -+ case 0: -+ return AE_OK; -+ case 1: -+ opregion->ctx.addr |= (*value64 & 0xff) << 8; -+ return AE_OK; -+ case 2: -+ opregion->ctx.addr |= *value64 & 0xff; -+ return AE_OK; -+ case 3: -+ opregion->ctx.val = *value64 & 0xff; -+ return AE_OK; -+ case 4: -+ if (*value64) { -+ result = regmap_write(opregion->regmap, opregion->ctx.addr, -+ opregion->ctx.val); -+ } else { -+ result = regmap_read(opregion->regmap, opregion->ctx.addr, -+ &opregion->ctx.val); -+ } -+ opregion->ctx.addr = 0; -+ } -+ } - -- switch (address) { -- case 0: -- return AE_OK; -- case 1: -- opregion->ctx.addr |= (*value64 & 0xff) << 8; -- return AE_OK; -- case 2: -- opregion->ctx.addr |= *value64 & 0xff; -+ if (function == ACPI_READ && address == 3) { -+ *value64 = opregion->ctx.val; - return AE_OK; -- case 3: -- opregion->ctx.val = *value64 & 0xff; -- return AE_OK; -- case 4: -- if (*value64) { -- result = regmap_write(opregion->regmap, opregion->ctx.addr, -- opregion->ctx.val); -- } else { -- result = regmap_read(opregion->regmap, opregion->ctx.addr, -- &opregion->ctx.val); -- if (result == 0) -- *value64 = opregion->ctx.val; -- } -- memset(&opregion->ctx, 0x00, sizeof(opregion->ctx)); - } - - if (result < 0) { -diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c -index f0ed4414edb1f..c95eedd58f5bf 100644 ---- a/drivers/acpi/power.c -+++ b/drivers/acpi/power.c -@@ -52,7 +52,6 @@ struct acpi_power_resource { - u32 order; - unsigned int ref_count; - u8 state; -- bool wakeup_enabled; - struct mutex resource_lock; - struct list_head dependents; - }; -@@ -615,20 +614,19 @@ int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p) - - list_for_each_entry(entry, list, node) { - struct acpi_power_resource *resource = entry->resource; -- int result; - u8 state; - - mutex_lock(&resource->resource_lock); - -- result = acpi_power_get_state(resource, &state); -- if (result) { -- mutex_unlock(&resource->resource_lock); -- return result; -- } -- if (state == ACPI_POWER_RESOURCE_STATE_ON) { -- resource->ref_count++; -- resource->wakeup_enabled = true; -- } -+ /* -+ * Make sure that the power resource state and its reference -+ * counter value are consistent with each other. -+ */ -+ if (!resource->ref_count && -+ !acpi_power_get_state(resource, &state) && -+ state == ACPI_POWER_RESOURCE_STATE_ON) -+ __acpi_power_off(resource); -+ - if (system_level > resource->system_level) - system_level = resource->system_level; - -@@ -711,7 +709,6 @@ int acpi_device_sleep_wake(struct acpi_device *dev, - */ - int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) - { -- struct acpi_power_resource_entry *entry; - int err = 0; - - if (!dev || !dev->wakeup.flags.valid) -@@ -722,26 +719,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) - if (dev->wakeup.prepare_count++) - goto out; - -- list_for_each_entry(entry, &dev->wakeup.resources, node) { -- struct acpi_power_resource *resource = entry->resource; -- -- mutex_lock(&resource->resource_lock); -- -- if (!resource->wakeup_enabled) { -- err = acpi_power_on_unlocked(resource); -- if (!err) -- resource->wakeup_enabled = true; -- } -- -- mutex_unlock(&resource->resource_lock); -- -- if (err) { -- dev_err(&dev->dev, -- "Cannot turn wakeup power resources on\n"); -- dev->wakeup.flags.valid = 0; -- goto out; -- } -+ err = acpi_power_on_list(&dev->wakeup.resources); -+ if (err) { -+ dev_err(&dev->dev, "Cannot turn on wakeup power resources\n"); -+ dev->wakeup.flags.valid = 0; -+ goto out; - } -+ - /* - * Passing 3 as the third argument below means the device may be - * put into arbitrary power state afterward. -@@ -771,39 +755,31 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) - - mutex_lock(&acpi_device_lock); - -- if (--dev->wakeup.prepare_count > 0) -+ /* Do nothing if wakeup power has not been enabled for this device. */ -+ if (dev->wakeup.prepare_count <= 0) - goto out; - -- /* -- * Executing the code below even if prepare_count is already zero when -- * the function is called may be useful, for example for initialisation. -- */ -- if (dev->wakeup.prepare_count < 0) -- dev->wakeup.prepare_count = 0; -+ if (--dev->wakeup.prepare_count > 0) -+ goto out; - - err = acpi_device_sleep_wake(dev, 0, 0, 0); - if (err) - goto out; - -+ /* -+ * All of the power resources in the list need to be turned off even if -+ * there are errors. -+ */ - list_for_each_entry(entry, &dev->wakeup.resources, node) { -- struct acpi_power_resource *resource = entry->resource; -- -- mutex_lock(&resource->resource_lock); -- -- if (resource->wakeup_enabled) { -- err = acpi_power_off_unlocked(resource); -- if (!err) -- resource->wakeup_enabled = false; -- } -- -- mutex_unlock(&resource->resource_lock); -+ int ret; - -- if (err) { -- dev_err(&dev->dev, -- "Cannot turn wakeup power resources off\n"); -- dev->wakeup.flags.valid = 0; -- break; -- } -+ ret = acpi_power_off(entry->resource); -+ if (ret && !err) -+ err = ret; -+ } -+ if (err) { -+ dev_err(&dev->dev, "Cannot turn off wakeup power resources\n"); -+ dev->wakeup.flags.valid = 0; - } - - out: -diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c -index e312ebaed8db4..781e312f45342 100644 ---- a/drivers/acpi/property.c -+++ b/drivers/acpi/property.c -@@ -1090,15 +1090,10 @@ struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode) - /* All data nodes have parent pointer so just return that */ - return to_acpi_data_node(fwnode)->parent; - } else if (is_acpi_device_node(fwnode)) { -- acpi_handle handle, parent_handle; -+ struct device *dev = to_acpi_device_node(fwnode)->dev.parent; - -- handle = to_acpi_device_node(fwnode)->handle; -- if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) { -- struct acpi_device *adev; -- -- if (!acpi_bus_get_device(parent_handle, &adev)) -- return acpi_fwnode_handle(adev); -- } -+ if (dev) -+ return acpi_fwnode_handle(to_acpi_device(dev)); - } - - return NULL; -diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c -index ee78a210c6068..3c25ce8c95ba1 100644 ---- a/drivers/acpi/resource.c -+++ b/drivers/acpi/resource.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_X86 - #define valid_IRQ(i) (((i) != 0) && ((i) != 2)) -@@ -380,9 +381,58 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity) - } - EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type); - -+static const struct dmi_system_id medion_laptop[] = { -+ { -+ .ident = "MEDION P15651", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), -+ DMI_MATCH(DMI_BOARD_NAME, "M15T"), -+ }, -+ }, -+ { -+ .ident = "MEDION S17405", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), -+ DMI_MATCH(DMI_BOARD_NAME, "M17T"), -+ }, -+ }, -+ { } -+}; -+ -+struct irq_override_cmp { -+ const struct dmi_system_id *system; -+ unsigned char irq; -+ unsigned char triggering; -+ unsigned char polarity; -+ unsigned char shareable; -+}; -+ -+static const struct irq_override_cmp skip_override_table[] = { -+ { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, -+}; -+ -+static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, -+ u8 shareable) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) { -+ const struct irq_override_cmp *entry = &skip_override_table[i]; -+ -+ if (dmi_check_system(entry->system) && -+ entry->irq == gsi && -+ entry->triggering == triggering && -+ entry->polarity == polarity && -+ entry->shareable == shareable) -+ return false; -+ } -+ -+ return true; -+} -+ - static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, - u8 triggering, u8 polarity, u8 shareable, -- bool legacy) -+ bool check_override) - { - int irq, p, t; - -@@ -401,7 +451,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, - * using extended IRQ descriptors we take the IRQ configuration - * from _CRS directly. - */ -- if (legacy && !acpi_get_override_irq(gsi, &t, &p)) { -+ if (check_override && -+ acpi_dev_irq_override(gsi, triggering, polarity, shareable) && -+ !acpi_get_override_irq(gsi, &t, &p)) { - u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; - u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - -diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index 5b54c80b9d32a..6e9cd41c5f9b1 100644 ---- a/drivers/acpi/scan.c -+++ b/drivers/acpi/scan.c -@@ -1690,6 +1690,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) - { - struct list_head resource_list; - bool is_serial_bus_slave = false; -+ static const struct acpi_device_id ignore_serial_bus_ids[] = { - /* - * These devices have multiple I2cSerialBus resources and an i2c-client - * must be instantiated for each, each with its own i2c_device_id. -@@ -1698,11 +1699,18 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) - * drivers/platform/x86/i2c-multi-instantiate.c driver, which knows - * which i2c_device_id to use for each resource. - */ -- static const struct acpi_device_id i2c_multi_instantiate_ids[] = { - {"BSG1160", }, - {"BSG2150", }, - {"INT33FE", }, - {"INT3515", }, -+ /* -+ * HIDs of device with an UartSerialBusV2 resource for which userspace -+ * expects a regular tty cdev to be created (instead of the in kernel -+ * serdev) and which have a kernel driver which expects a platform_dev -+ * such as the rfkill-gpio driver. -+ */ -+ {"BCM4752", }, -+ {"LNV4752", }, - {} - }; - -@@ -1716,8 +1724,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) - fwnode_property_present(&device->fwnode, "baud"))) - return true; - -- /* Instantiate a pdev for the i2c-multi-instantiate drv to bind to */ -- if (!acpi_match_device_ids(device, i2c_multi_instantiate_ids)) -+ if (!acpi_match_device_ids(device, ignore_serial_bus_ids)) - return false; - - INIT_LIST_HEAD(&resource_list); -diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c -index 3023224515abe..7ae09e4b45927 100644 ---- a/drivers/acpi/sleep.c -+++ b/drivers/acpi/sleep.c -@@ -767,6 +767,7 @@ bool acpi_s2idle_wake(void) - return true; - } - -+ pm_wakeup_clear(acpi_sci_irq); - rearm_wake_irq(acpi_sci_irq); - } - -diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c -index 1c48358b43ba3..e0185e841b2a3 100644 ---- a/drivers/acpi/x86/s2idle.c -+++ b/drivers/acpi/x86/s2idle.c -@@ -424,15 +424,11 @@ static int lps0_device_attach(struct acpi_device *adev, - mem_sleep_current = PM_SUSPEND_TO_IDLE; - - /* -- * Some Intel based LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U don't -- * use intel-hid or intel-vbtn but require the EC GPE to be enabled while -- * suspended for certain wakeup devices to work, so mark it as wakeup-capable. -- * -- * Only enable on !AMD as enabling this universally causes problems for a number -- * of AMD based systems. -+ * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the -+ * EC GPE to be enabled while suspended for certain wakeup devices to -+ * work, so mark it as wakeup-capable. - */ -- if (!acpi_s2idle_vendor_amd()) -- acpi_ec_mark_gpe_for_wake(); -+ acpi_ec_mark_gpe_for_wake(); - - return 0; - } -diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c -index f22f23933063b..b3fb428461c6f 100644 ---- a/drivers/acpi/x86/utils.c -+++ b/drivers/acpi/x86/utils.c -@@ -22,58 +22,71 @@ - * Some BIOS-es (temporarily) hide specific APCI devices to work around Windows - * driver bugs. We use DMI matching to match known cases of this. - * -- * We work around this by always reporting ACPI_STA_DEFAULT for these -- * devices. Note this MUST only be done for devices where this is safe. -+ * Likewise sometimes some not-actually present devices are sometimes -+ * reported as present, which may cause issues. - * -- * This forcing of devices to be present is limited to specific CPU (SoC) -- * models both to avoid potentially causing trouble on other models and -- * because some HIDs are re-used on different SoCs for completely -- * different devices. -+ * We work around this by using the below quirk list to override the status -+ * reported by the _STA method with a fixed value (ACPI_STA_DEFAULT or 0). -+ * Note this MUST only be done for devices where this is safe. -+ * -+ * This status overriding is limited to specific CPU (SoC) models both to -+ * avoid potentially causing trouble on other models and because some HIDs -+ * are re-used on different SoCs for completely different devices. - */ --struct always_present_id { -+struct override_status_id { - struct acpi_device_id hid[2]; - struct x86_cpu_id cpu_ids[2]; - struct dmi_system_id dmi_ids[2]; /* Optional */ - const char *uid; -+ const char *path; -+ unsigned long long status; - }; - --#define X86_MATCH(model) X86_MATCH_INTEL_FAM6_MODEL(model, NULL) -- --#define ENTRY(hid, uid, cpu_models, dmi...) { \ -+#define ENTRY(status, hid, uid, path, cpu_model, dmi...) { \ - { { hid, }, {} }, \ -- { cpu_models, {} }, \ -+ { X86_MATCH_INTEL_FAM6_MODEL(cpu_model, NULL), {} }, \ - { { .matches = dmi }, {} }, \ - uid, \ -+ path, \ -+ status, \ - } - --static const struct always_present_id always_present_ids[] = { -+#define PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \ -+ ENTRY(ACPI_STA_DEFAULT, hid, uid, NULL, cpu_model, dmi) -+ -+#define NOT_PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \ -+ ENTRY(0, hid, uid, NULL, cpu_model, dmi) -+ -+#define PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \ -+ ENTRY(ACPI_STA_DEFAULT, "", NULL, path, cpu_model, dmi) -+ -+#define NOT_PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \ -+ ENTRY(0, "", NULL, path, cpu_model, dmi) -+ -+static const struct override_status_id override_status_ids[] = { - /* - * Bay / Cherry Trail PWM directly poked by GPU driver in win10, - * but Linux uses a separate PWM driver, harmless if not used. - */ -- ENTRY("80860F09", "1", X86_MATCH(ATOM_SILVERMONT), {}), -- ENTRY("80862288", "1", X86_MATCH(ATOM_AIRMONT), {}), -+ PRESENT_ENTRY_HID("80860F09", "1", ATOM_SILVERMONT, {}), -+ PRESENT_ENTRY_HID("80862288", "1", ATOM_AIRMONT, {}), - -- /* Lenovo Yoga Book uses PWM2 for keyboard backlight control */ -- ENTRY("80862289", "2", X86_MATCH(ATOM_AIRMONT), { -- DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), -- }), - /* - * The INT0002 device is necessary to clear wakeup interrupt sources - * on Cherry Trail devices, without it we get nobody cared IRQ msgs. - */ -- ENTRY("INT0002", "1", X86_MATCH(ATOM_AIRMONT), {}), -+ PRESENT_ENTRY_HID("INT0002", "1", ATOM_AIRMONT, {}), - /* - * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides - * the touchscreen ACPI device until a certain time - * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed - * *and* _STA has been called at least 3 times since. - */ -- ENTRY("SYNA7500", "1", X86_MATCH(HASWELL_L), { -+ PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), - }), -- ENTRY("SYNA7500", "1", X86_MATCH(HASWELL_L), { -+ PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"), - }), -@@ -81,54 +94,83 @@ static const struct always_present_id always_present_ids[] = { - /* - * The GPD win BIOS dated 20170221 has disabled the accelerometer, the - * drivers sometimes cause crashes under Windows and this is how the -- * manufacturer has solved this :| Note that the the DMI data is less -- * generic then it seems, a board_vendor of "AMI Corporation" is quite -- * rare and a board_name of "Default String" also is rare. -+ * manufacturer has solved this :| The DMI match may not seem unique, -+ * but it is. In the 67000+ DMI decode dumps from linux-hardware.org -+ * only 116 have board_vendor set to "AMI Corporation" and of those 116 -+ * only the GPD win and pocket entries' board_name is "Default string". - * - * Unfortunately the GPD pocket also uses these strings and its BIOS - * was copy-pasted from the GPD win, so it has a disabled KIOX000A - * node which we should not enable, thus we also check the BIOS date. - */ -- ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { -+ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, { - DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "Default string"), - DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), - DMI_MATCH(DMI_BIOS_DATE, "02/21/2017") - }), -- ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { -+ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, { - DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "Default string"), - DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), - DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") - }), -- ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { -+ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, { - DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "Default string"), - DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), - DMI_MATCH(DMI_BIOS_DATE, "05/25/2017") - }), -+ -+ /* -+ * The GPD win/pocket have a PCI wifi card, but its DSDT has the SDIO -+ * mmc controller enabled and that has a child-device which _PS3 -+ * method sets a GPIO causing the PCI wifi card to turn off. -+ * See above remark about uniqueness of the DMI match. -+ */ -+ NOT_PRESENT_ENTRY_PATH("\\_SB_.PCI0.SDHB.BRC1", ATOM_AIRMONT, { -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ }), - }; - --bool acpi_device_always_present(struct acpi_device *adev) -+bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status) - { - bool ret = false; - unsigned int i; - -- for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) { -- if (acpi_match_device_ids(adev, always_present_ids[i].hid)) -+ for (i = 0; i < ARRAY_SIZE(override_status_ids); i++) { -+ if (!x86_match_cpu(override_status_ids[i].cpu_ids)) - continue; - -- if (!adev->pnp.unique_id || -- strcmp(adev->pnp.unique_id, always_present_ids[i].uid)) -+ if (override_status_ids[i].dmi_ids[0].matches[0].slot && -+ !dmi_check_system(override_status_ids[i].dmi_ids)) - continue; - -- if (!x86_match_cpu(always_present_ids[i].cpu_ids)) -- continue; -+ if (override_status_ids[i].path) { -+ struct acpi_buffer path = { ACPI_ALLOCATE_BUFFER, NULL }; -+ bool match; - -- if (always_present_ids[i].dmi_ids[0].matches[0].slot && -- !dmi_check_system(always_present_ids[i].dmi_ids)) -- continue; -+ if (acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &path)) -+ continue; -+ -+ match = strcmp((char *)path.pointer, override_status_ids[i].path) == 0; -+ kfree(path.pointer); -+ -+ if (!match) -+ continue; -+ } else { -+ if (acpi_match_device_ids(adev, override_status_ids[i].hid)) -+ continue; -+ -+ if (!adev->pnp.unique_id || -+ strcmp(adev->pnp.unique_id, override_status_ids[i].uid)) -+ continue; -+ } - -+ *status = override_status_ids[i].status; - ret = true; - break; - } -diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c -index 962041148482c..6c0f7f4f7d1de 100644 ---- a/drivers/amba/bus.c -+++ b/drivers/amba/bus.c -@@ -377,9 +377,6 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent) - void __iomem *tmp; - int i, ret; - -- WARN_ON(dev->irq[0] == (unsigned int)-1); -- WARN_ON(dev->irq[1] == (unsigned int)-1); -- - ret = request_resource(parent, &dev->res); - if (ret) - goto err_out; -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index 9edacc8b97688..99ae919255f4d 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -1608,15 +1608,21 @@ static void binder_cleanup_transaction(struct binder_transaction *t, - /** - * binder_get_object() - gets object and checks for valid metadata - * @proc: binder_proc owning the buffer -+ * @u: sender's user pointer to base of buffer - * @buffer: binder_buffer that we're parsing. - * @offset: offset in the @buffer at which to validate an object. - * @object: struct binder_object to read into - * -- * Return: If there's a valid metadata object at @offset in @buffer, the -+ * Copy the binder object at the given offset into @object. If @u is -+ * provided then the copy is from the sender's buffer. If not, then -+ * it is copied from the target's @buffer. -+ * -+ * Return: If there's a valid metadata object at @offset, the - * size of that object. Otherwise, it returns zero. The object - * is read into the struct binder_object pointed to by @object. - */ - static size_t binder_get_object(struct binder_proc *proc, -+ const void __user *u, - struct binder_buffer *buffer, - unsigned long offset, - struct binder_object *object) -@@ -1626,10 +1632,16 @@ static size_t binder_get_object(struct binder_proc *proc, - size_t object_size = 0; - - read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); -- if (offset > buffer->data_size || read_size < sizeof(*hdr) || -- binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, -- offset, read_size)) -+ if (offset > buffer->data_size || read_size < sizeof(*hdr)) - return 0; -+ if (u) { -+ if (copy_from_user(object, u + offset, read_size)) -+ return 0; -+ } else { -+ if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, -+ offset, read_size)) -+ return 0; -+ } - - /* Ok, now see if we read a complete object. */ - hdr = &object->hdr; -@@ -1702,7 +1714,7 @@ static struct binder_buffer_object *binder_validate_ptr( - b, buffer_offset, - sizeof(object_offset))) - return NULL; -- object_size = binder_get_object(proc, b, object_offset, object); -+ object_size = binder_get_object(proc, NULL, b, object_offset, object); - if (!object_size || object->hdr.type != BINDER_TYPE_PTR) - return NULL; - if (object_offsetp) -@@ -1767,7 +1779,8 @@ static bool binder_validate_fixup(struct binder_proc *proc, - unsigned long buffer_offset; - struct binder_object last_object; - struct binder_buffer_object *last_bbo; -- size_t object_size = binder_get_object(proc, b, last_obj_offset, -+ size_t object_size = binder_get_object(proc, NULL, b, -+ last_obj_offset, - &last_object); - if (object_size != sizeof(*last_bbo)) - return false; -@@ -1870,7 +1883,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, - binder_dec_node(buffer->target_node, 1, 0); - - off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); -- off_end_offset = is_failure ? failed_at : -+ off_end_offset = is_failure && failed_at ? failed_at : - off_start_offset + buffer->offsets_size; - for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; - buffer_offset += sizeof(binder_size_t)) { -@@ -1882,7 +1895,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, - if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, - buffer, buffer_offset, - sizeof(object_offset))) -- object_size = binder_get_object(proc, buffer, -+ object_size = binder_get_object(proc, NULL, buffer, - object_offset, &object); - if (object_size == 0) { - pr_err("transaction release %d bad object at offset %lld, size %zd\n", -@@ -1956,9 +1969,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, - binder_size_t fd_buf_size; - binder_size_t num_valid; - -- if (proc->tsk != current->group_leader) { -+ if (is_failure) { - /* -- * Nothing to do if running in sender context - * The fd fixups have not been applied so no - * fds need to be closed. - */ -@@ -2056,7 +2068,7 @@ static int binder_translate_binder(struct flat_binder_object *fp, - ret = -EINVAL; - goto done; - } -- if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { -+ if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { - ret = -EPERM; - goto done; - } -@@ -2102,7 +2114,7 @@ static int binder_translate_handle(struct flat_binder_object *fp, - proc->pid, thread->pid, fp->handle); - return -EINVAL; - } -- if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { -+ if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { - ret = -EPERM; - goto done; - } -@@ -2190,7 +2202,7 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset, - ret = -EBADF; - goto err_fget; - } -- ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file); -+ ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); - if (ret < 0) { - ret = -EPERM; - goto err_security; -@@ -2270,8 +2282,8 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda, - if (!ret) - ret = binder_translate_fd(fd, offset, t, thread, - in_reply_to); -- if (ret < 0) -- return ret; -+ if (ret) -+ return ret > 0 ? -EINVAL : ret; - } - return 0; - } -@@ -2456,6 +2468,7 @@ static void binder_transaction(struct binder_proc *proc, - binder_size_t off_start_offset, off_end_offset; - binder_size_t off_min; - binder_size_t sg_buf_offset, sg_buf_end_offset; -+ binder_size_t user_offset = 0; - struct binder_proc *target_proc = NULL; - struct binder_thread *target_thread = NULL; - struct binder_node *target_node = NULL; -@@ -2470,6 +2483,8 @@ static void binder_transaction(struct binder_proc *proc, - int t_debug_id = atomic_inc_return(&binder_last_id); - char *secctx = NULL; - u32 secctx_sz = 0; -+ const void __user *user_buffer = (const void __user *) -+ (uintptr_t)tr->data.ptr.buffer; - - e = binder_transaction_log_add(&binder_transaction_log); - e->debug_id = t_debug_id; -@@ -2595,8 +2610,8 @@ static void binder_transaction(struct binder_proc *proc, - return_error_line = __LINE__; - goto err_invalid_target_handle; - } -- if (security_binder_transaction(proc->tsk, -- target_proc->tsk) < 0) { -+ if (security_binder_transaction(proc->cred, -+ target_proc->cred) < 0) { - return_error = BR_FAILED_REPLY; - return_error_param = -EPERM; - return_error_line = __LINE__; -@@ -2722,16 +2737,7 @@ static void binder_transaction(struct binder_proc *proc, - u32 secid; - size_t added_size; - -- /* -- * Arguably this should be the task's subjective LSM secid but -- * we can't reliably access the subjective creds of a task -- * other than our own so we must use the objective creds, which -- * are safe to access. The downside is that if a task is -- * temporarily overriding it's creds it will not be reflected -- * here; however, it isn't clear that binder would handle that -- * case well anyway. -- */ -- security_task_getsecid_obj(proc->tsk, &secid); -+ security_cred_getsecid(proc->cred, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); - if (ret) { - return_error = BR_FAILED_REPLY; -@@ -2790,19 +2796,6 @@ static void binder_transaction(struct binder_proc *proc, - t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); - trace_binder_transaction_alloc_buf(t->buffer); - -- if (binder_alloc_copy_user_to_buffer( -- &target_proc->alloc, -- t->buffer, 0, -- (const void __user *) -- (uintptr_t)tr->data.ptr.buffer, -- tr->data_size)) { -- binder_user_error("%d:%d got transaction with invalid data ptr\n", -- proc->pid, thread->pid); -- return_error = BR_FAILED_REPLY; -- return_error_param = -EFAULT; -- return_error_line = __LINE__; -- goto err_copy_data_failed; -- } - if (binder_alloc_copy_user_to_buffer( - &target_proc->alloc, - t->buffer, -@@ -2847,6 +2840,7 @@ static void binder_transaction(struct binder_proc *proc, - size_t object_size; - struct binder_object object; - binder_size_t object_offset; -+ binder_size_t copy_size; - - if (binder_alloc_copy_from_buffer(&target_proc->alloc, - &object_offset, -@@ -2858,8 +2852,27 @@ static void binder_transaction(struct binder_proc *proc, - return_error_line = __LINE__; - goto err_bad_offset; - } -- object_size = binder_get_object(target_proc, t->buffer, -- object_offset, &object); -+ -+ /* -+ * Copy the source user buffer up to the next object -+ * that will be processed. -+ */ -+ copy_size = object_offset - user_offset; -+ if (copy_size && (user_offset > object_offset || -+ binder_alloc_copy_user_to_buffer( -+ &target_proc->alloc, -+ t->buffer, user_offset, -+ user_buffer + user_offset, -+ copy_size))) { -+ binder_user_error("%d:%d got transaction with invalid data ptr\n", -+ proc->pid, thread->pid); -+ return_error = BR_FAILED_REPLY; -+ return_error_param = -EFAULT; -+ return_error_line = __LINE__; -+ goto err_copy_data_failed; -+ } -+ object_size = binder_get_object(target_proc, user_buffer, -+ t->buffer, object_offset, &object); - if (object_size == 0 || object_offset < off_min) { - binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n", - proc->pid, thread->pid, -@@ -2871,6 +2884,11 @@ static void binder_transaction(struct binder_proc *proc, - return_error_line = __LINE__; - goto err_bad_offset; - } -+ /* -+ * Set offset to the next buffer fragment to be -+ * copied -+ */ -+ user_offset = object_offset + object_size; - - hdr = &object.hdr; - off_min = object_offset + object_size; -@@ -2966,9 +2984,14 @@ static void binder_transaction(struct binder_proc *proc, - } - ret = binder_translate_fd_array(fda, parent, t, thread, - in_reply_to); -- if (ret < 0) { -+ if (!ret) -+ ret = binder_alloc_copy_to_buffer(&target_proc->alloc, -+ t->buffer, -+ object_offset, -+ fda, sizeof(*fda)); -+ if (ret) { - return_error = BR_FAILED_REPLY; -- return_error_param = ret; -+ return_error_param = ret > 0 ? -EINVAL : ret; - return_error_line = __LINE__; - goto err_translate_failed; - } -@@ -3038,6 +3061,19 @@ static void binder_transaction(struct binder_proc *proc, - goto err_bad_object_type; - } - } -+ /* Done processing objects, copy the rest of the buffer */ -+ if (binder_alloc_copy_user_to_buffer( -+ &target_proc->alloc, -+ t->buffer, user_offset, -+ user_buffer + user_offset, -+ tr->data_size - user_offset)) { -+ binder_user_error("%d:%d got transaction with invalid data ptr\n", -+ proc->pid, thread->pid); -+ return_error = BR_FAILED_REPLY; -+ return_error_param = -EFAULT; -+ return_error_line = __LINE__; -+ goto err_copy_data_failed; -+ } - if (t->buffer->oneway_spam_suspect) - tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; - else -@@ -3185,6 +3221,7 @@ err_invalid_target_handle: - * binder_free_buf() - free the specified buffer - * @proc: binder proc that owns buffer - * @buffer: buffer to be freed -+ * @is_failure: failed to send transaction - * - * If buffer for an async transaction, enqueue the next async - * transaction from the node. -@@ -3194,7 +3231,7 @@ err_invalid_target_handle: - static void - binder_free_buf(struct binder_proc *proc, - struct binder_thread *thread, -- struct binder_buffer *buffer) -+ struct binder_buffer *buffer, bool is_failure) - { - binder_inner_proc_lock(proc); - if (buffer->transaction) { -@@ -3222,7 +3259,7 @@ binder_free_buf(struct binder_proc *proc, - binder_node_inner_unlock(buf_node); - } - trace_binder_transaction_buffer_release(buffer); -- binder_transaction_buffer_release(proc, thread, buffer, 0, false); -+ binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure); - binder_alloc_free_buf(&proc->alloc, buffer); - } - -@@ -3424,7 +3461,7 @@ static int binder_thread_write(struct binder_proc *proc, - proc->pid, thread->pid, (u64)data_ptr, - buffer->debug_id, - buffer->transaction ? "active" : "finished"); -- binder_free_buf(proc, thread, buffer); -+ binder_free_buf(proc, thread, buffer, false); - break; - } - -@@ -4117,7 +4154,7 @@ retry: - buffer->transaction = NULL; - binder_cleanup_transaction(t, "fd fixups failed", - BR_FAILED_REPLY); -- binder_free_buf(proc, thread, buffer); -+ binder_free_buf(proc, thread, buffer, true); - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "%d:%d %stransaction %d fd fixups failed %d/%d, line %d\n", - proc->pid, thread->pid, -@@ -4353,6 +4390,7 @@ static void binder_free_proc(struct binder_proc *proc) - } - binder_alloc_deferred_release(&proc->alloc); - put_task_struct(proc->tsk); -+ put_cred(proc->cred); - binder_stats_deleted(BINDER_STAT_PROC); - kfree(proc); - } -@@ -4430,23 +4468,20 @@ static int binder_thread_release(struct binder_proc *proc, - __release(&t->lock); - - /* -- * If this thread used poll, make sure we remove the waitqueue -- * from any epoll data structures holding it with POLLFREE. -- * waitqueue_active() is safe to use here because we're holding -- * the inner lock. -+ * If this thread used poll, make sure we remove the waitqueue from any -+ * poll data structures holding it. - */ -- if ((thread->looper & BINDER_LOOPER_STATE_POLL) && -- waitqueue_active(&thread->wait)) { -- wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE); -- } -+ if (thread->looper & BINDER_LOOPER_STATE_POLL) -+ wake_up_pollfree(&thread->wait); - - binder_inner_proc_unlock(thread->proc); - - /* -- * This is needed to avoid races between wake_up_poll() above and -- * and ep_remove_waitqueue() called for other reasons (eg the epoll file -- * descriptor being closed); ep_remove_waitqueue() holds an RCU read -- * lock, so we can be sure it's done after calling synchronize_rcu(). -+ * This is needed to avoid races between wake_up_pollfree() above and -+ * someone else removing the last entry from the queue for other reasons -+ * (e.g. ep_remove_wait_queue() being called due to an epoll file -+ * descriptor being closed). Such other users hold an RCU read lock, so -+ * we can be sure they're done after we call synchronize_rcu(). - */ - if (thread->looper & BINDER_LOOPER_STATE_POLL) - synchronize_rcu(); -@@ -4564,7 +4599,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp, - ret = -EBUSY; - goto out; - } -- ret = security_binder_set_context_mgr(proc->tsk); -+ ret = security_binder_set_context_mgr(proc->cred); - if (ret < 0) - goto out; - if (uid_valid(context->binder_context_mgr_uid)) { -@@ -5055,6 +5090,7 @@ static int binder_open(struct inode *nodp, struct file *filp) - spin_lock_init(&proc->outer_lock); - get_task_struct(current->group_leader); - proc->tsk = current->group_leader; -+ proc->cred = get_cred(filp->f_cred); - INIT_LIST_HEAD(&proc->todo); - init_waitqueue_head(&proc->freeze_wait); - proc->default_priority = task_nice(current); -diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c -index 340515f54498c..47bc74a8c7b6f 100644 ---- a/drivers/android/binder_alloc.c -+++ b/drivers/android/binder_alloc.c -@@ -671,7 +671,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc, - BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); - - if (buffer->async_transaction) { -- alloc->free_async_space += size + sizeof(struct binder_buffer); -+ alloc->free_async_space += buffer_size + sizeof(struct binder_buffer); - - binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "%d: binder_free_buf size %zd async free %zd\n", -diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h -index 402c4d4362a83..d6b6b8cb73465 100644 ---- a/drivers/android/binder_internal.h -+++ b/drivers/android/binder_internal.h -@@ -364,6 +364,9 @@ struct binder_ref { - * (invariant after initialized) - * @tsk task_struct for group_leader of process - * (invariant after initialized) -+ * @cred struct cred associated with the `struct file` -+ * in binder_open() -+ * (invariant after initialized) - * @deferred_work_node: element for binder_deferred_list - * (protected by binder_deferred_lock) - * @deferred_work: bitmap of deferred work to perform -@@ -426,6 +429,7 @@ struct binder_proc { - struct list_head waiting_threads; - int pid; - struct task_struct *tsk; -+ const struct cred *cred; - struct hlist_node deferred_work_node; - int deferred_work; - int outstanding_txns; -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index 186cbf90c8ead..812731e80f8e0 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -442,6 +442,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { - /* AMD */ - { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ - { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ -+ { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */ - /* AMD is using RAID class only for ahci controllers */ - { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, -diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c -index 5b3fa2cbe7223..395772fa39432 100644 ---- a/drivers/ata/libahci.c -+++ b/drivers/ata/libahci.c -@@ -2305,6 +2305,18 @@ int ahci_port_resume(struct ata_port *ap) - EXPORT_SYMBOL_GPL(ahci_port_resume); - - #ifdef CONFIG_PM -+static void ahci_handle_s2idle(struct ata_port *ap) -+{ -+ void __iomem *port_mmio = ahci_port_base(ap); -+ u32 devslp; -+ -+ if (pm_suspend_via_firmware()) -+ return; -+ devslp = readl(port_mmio + PORT_DEVSLP); -+ if ((devslp & PORT_DEVSLP_ADSE)) -+ ata_msleep(ap, devslp_idle_timeout); -+} -+ - static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) - { - const char *emsg = NULL; -@@ -2318,6 +2330,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) - ata_port_freeze(ap); - } - -+ if (acpi_storage_d3(ap->host->dev)) -+ ahci_handle_s2idle(ap); -+ - ahci_rpm_put_port(ap); - return rc; - } -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index eed65311b5d1d..24b67d78cb83d 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -2007,7 +2007,7 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, - - retry: - ata_tf_init(dev, &tf); -- if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) && -+ if (ata_dma_enabled(dev) && ata_id_has_read_log_dma_ext(dev->id) && - !(dev->horkage & ATA_HORKAGE_NO_DMA_LOG)) { - tf.command = ATA_CMD_READ_LOG_DMA_EXT; - tf.protocol = ATA_PROT_DMA; -@@ -2031,8 +2031,9 @@ retry: - dev->horkage |= ATA_HORKAGE_NO_DMA_LOG; - goto retry; - } -- ata_dev_err(dev, "Read log page 0x%02x failed, Emask 0x%x\n", -- (unsigned int)page, err_mask); -+ ata_dev_err(dev, -+ "Read log 0x%02x page 0x%02x failed, Emask 0x%x\n", -+ (unsigned int)log, (unsigned int)page, err_mask); - } - - return err_mask; -@@ -2166,6 +2167,9 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev) - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - -+ if (!ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) -+ return; -+ - err_mask = ata_read_log_page(dev, - ATA_LOG_IDENTIFY_DEVICE, - ATA_LOG_SATA_SETTINGS, -@@ -2442,7 +2446,8 @@ static void ata_dev_config_devslp(struct ata_device *dev) - * Check device sleep capability. Get DevSlp timing variables - * from SATA Settings page of Identify Device Data Log. - */ -- if (!ata_id_has_devslp(dev->id)) -+ if (!ata_id_has_devslp(dev->id) || -+ !ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) - return; - - err_mask = ata_read_log_page(dev, -@@ -3851,6 +3856,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { - { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, - /* Odd clown on sil3726/4726 PMPs */ - { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, -+ /* Similar story with ASMedia 1092 */ -+ { "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE }, - - /* Weird ATAPI devices */ - { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, -@@ -4007,6 +4014,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { - - /* devices that don't properly handle TRIM commands */ - { "SuperSSpeed S238*", NULL, ATA_HORKAGE_NOTRIM, }, -+ { "M88V29*", NULL, ATA_HORKAGE_NOTRIM, }, - - /* - * As defined, the DRAT (Deterministic Read After Trim) and RZAT -diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c -index bf9c4b6c5c3d4..1d4a6f1e88cd1 100644 ---- a/drivers/ata/libata-eh.c -+++ b/drivers/ata/libata-eh.c -@@ -93,6 +93,12 @@ static const unsigned long ata_eh_identify_timeouts[] = { - ULONG_MAX, - }; - -+static const unsigned long ata_eh_revalidate_timeouts[] = { -+ 15000, /* Some drives are slow to read log pages when waking-up */ -+ 15000, /* combined time till here is enough even for media access */ -+ ULONG_MAX, -+}; -+ - static const unsigned long ata_eh_flush_timeouts[] = { - 15000, /* be generous with flush */ - 15000, /* ditto */ -@@ -129,6 +135,8 @@ static const struct ata_eh_cmd_timeout_ent - ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { - { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), - .timeouts = ata_eh_identify_timeouts, }, -+ { .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT), -+ .timeouts = ata_eh_revalidate_timeouts, }, - { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), - .timeouts = ata_eh_other_timeouts, }, - { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index 1fb4611f7eeb9..10303611d17b9 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -2826,8 +2826,19 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) - goto invalid_fld; - } - -- if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0) -- tf->protocol = ATA_PROT_NCQ_NODATA; -+ if ((cdb[2 + cdb_offset] & 0x3) == 0) { -+ /* -+ * When T_LENGTH is zero (No data is transferred), dir should -+ * be DMA_NONE. -+ */ -+ if (scmd->sc_data_direction != DMA_NONE) { -+ fp = 2 + cdb_offset; -+ goto invalid_fld; -+ } -+ -+ if (ata_is_ncq(tf->protocol)) -+ tf->protocol = ATA_PROT_NCQ_NODATA; -+ } - - /* enable LBA */ - tf->flags |= ATA_TFLAG_LBA; -diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c -index f242157bc81bb..9d371859e81ed 100644 ---- a/drivers/ata/pata_hpt37x.c -+++ b/drivers/ata/pata_hpt37x.c -@@ -919,6 +919,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) - irqmask &= ~0x10; - pci_write_config_byte(dev, 0x5a, irqmask); - -+ /* -+ * HPT371 chips physically have only one channel, the secondary one, -+ * but the primary channel registers do exist! Go figure... -+ * So, we manually disable the non-existing channel here -+ * (if the BIOS hasn't done this already). -+ */ -+ if (dev->device == PCI_DEVICE_ID_TTI_HPT371) { -+ u8 mcr1; -+ -+ pci_read_config_byte(dev, 0x50, &mcr1); -+ mcr1 &= ~0x04; -+ pci_write_config_byte(dev, 0x50, mcr1); -+ } -+ - /* - * default to pci clock. make sure MA15/16 are set to output - * to prevent drives having problems with 40-pin cables. Needed -@@ -950,14 +964,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) - - if ((freq >> 12) != 0xABCDE) { - int i; -- u8 sr; -+ u16 sr; - u32 total = 0; - - pr_warn("BIOS has not set timing clocks\n"); - - /* This is the process the HPT371 BIOS is reported to use */ - for (i = 0; i < 128; i++) { -- pci_read_config_byte(dev, 0x78, &sr); -+ pci_read_config_word(dev, 0x78, &sr); - total += sr & 0x1FF; - udelay(15); - } -diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c -index e5838b23c9e0a..3b31a4f596d86 100644 ---- a/drivers/ata/sata_fsl.c -+++ b/drivers/ata/sata_fsl.c -@@ -1394,6 +1394,14 @@ static int sata_fsl_init_controller(struct ata_host *host) - return 0; - } - -+static void sata_fsl_host_stop(struct ata_host *host) -+{ -+ struct sata_fsl_host_priv *host_priv = host->private_data; -+ -+ iounmap(host_priv->hcr_base); -+ kfree(host_priv); -+} -+ - /* - * scsi mid-layer and libata interface structures - */ -@@ -1426,6 +1434,8 @@ static struct ata_port_operations sata_fsl_ops = { - .port_start = sata_fsl_port_start, - .port_stop = sata_fsl_port_stop, - -+ .host_stop = sata_fsl_host_stop, -+ - .pmp_attach = sata_fsl_pmp_attach, - .pmp_detach = sata_fsl_pmp_detach, - }; -@@ -1480,9 +1490,9 @@ static int sata_fsl_probe(struct platform_device *ofdev) - host_priv->ssr_base = ssr_base; - host_priv->csr_base = csr_base; - -- irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); -- if (!irq) { -- dev_err(&ofdev->dev, "invalid irq from platform\n"); -+ irq = platform_get_irq(ofdev, 0); -+ if (irq < 0) { -+ retval = irq; - goto error_exit_with_cleanup; - } - host_priv->irq = irq; -@@ -1557,10 +1567,6 @@ static int sata_fsl_remove(struct platform_device *ofdev) - - ata_host_detach(host); - -- irq_dispose_mapping(host_priv->irq); -- iounmap(host_priv->hcr_base); -- kfree(host_priv); -- - return 0; - } - -diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c -index 304accde365c8..6c010d4efa4ae 100644 ---- a/drivers/auxdisplay/charlcd.c -+++ b/drivers/auxdisplay/charlcd.c -@@ -578,6 +578,9 @@ static int charlcd_init(struct charlcd *lcd) - * Since charlcd_init_display() needs to write data, we have to - * enable mark the LCD initialized just before. - */ -+ if (WARN_ON(!lcd->ops->init_display)) -+ return -EINVAL; -+ - ret = lcd->ops->init_display(lcd); - if (ret) - return ret; -diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c -index 1e69cc6d21a0d..ed58083499907 100644 ---- a/drivers/auxdisplay/ht16k33.c -+++ b/drivers/auxdisplay/ht16k33.c -@@ -219,6 +219,15 @@ static const struct backlight_ops ht16k33_bl_ops = { - .check_fb = ht16k33_bl_check_fb, - }; - -+/* -+ * Blank events will be passed to the actual device handling the backlight when -+ * we return zero here. -+ */ -+static int ht16k33_blank(int blank, struct fb_info *info) -+{ -+ return 0; -+} -+ - static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma) - { - struct ht16k33_priv *priv = info->par; -@@ -231,6 +240,7 @@ static const struct fb_ops ht16k33_fb_ops = { - .owner = THIS_MODULE, - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, -+ .fb_blank = ht16k33_blank, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, -@@ -413,6 +423,33 @@ static int ht16k33_probe(struct i2c_client *client, - if (err) - return err; - -+ /* Backlight */ -+ memset(&bl_props, 0, sizeof(struct backlight_properties)); -+ bl_props.type = BACKLIGHT_RAW; -+ bl_props.max_brightness = MAX_BRIGHTNESS; -+ -+ bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", -+ &client->dev, priv, -+ &ht16k33_bl_ops, &bl_props); -+ if (IS_ERR(bl)) { -+ dev_err(&client->dev, "failed to register backlight\n"); -+ return PTR_ERR(bl); -+ } -+ -+ err = of_property_read_u32(node, "default-brightness-level", -+ &dft_brightness); -+ if (err) { -+ dft_brightness = MAX_BRIGHTNESS; -+ } else if (dft_brightness > MAX_BRIGHTNESS) { -+ dev_warn(&client->dev, -+ "invalid default brightness level: %u, using %u\n", -+ dft_brightness, MAX_BRIGHTNESS); -+ dft_brightness = MAX_BRIGHTNESS; -+ } -+ -+ bl->props.brightness = dft_brightness; -+ ht16k33_bl_update_status(bl); -+ - /* Framebuffer (2 bytes per column) */ - BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE); - fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL); -@@ -445,6 +482,7 @@ static int ht16k33_probe(struct i2c_client *client, - fbdev->info->screen_size = HT16K33_FB_SIZE; - fbdev->info->fix = ht16k33_fb_fix; - fbdev->info->var = ht16k33_fb_var; -+ fbdev->info->bl_dev = bl; - fbdev->info->pseudo_palette = NULL; - fbdev->info->flags = FBINFO_FLAG_DEFAULT; - fbdev->info->par = priv; -@@ -460,34 +498,6 @@ static int ht16k33_probe(struct i2c_client *client, - goto err_fbdev_unregister; - } - -- /* Backlight */ -- memset(&bl_props, 0, sizeof(struct backlight_properties)); -- bl_props.type = BACKLIGHT_RAW; -- bl_props.max_brightness = MAX_BRIGHTNESS; -- -- bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", -- &client->dev, priv, -- &ht16k33_bl_ops, &bl_props); -- if (IS_ERR(bl)) { -- dev_err(&client->dev, "failed to register backlight\n"); -- err = PTR_ERR(bl); -- goto err_fbdev_unregister; -- } -- -- err = of_property_read_u32(node, "default-brightness-level", -- &dft_brightness); -- if (err) { -- dft_brightness = MAX_BRIGHTNESS; -- } else if (dft_brightness > MAX_BRIGHTNESS) { -- dev_warn(&client->dev, -- "invalid default brightness level: %u, using %u\n", -- dft_brightness, MAX_BRIGHTNESS); -- dft_brightness = MAX_BRIGHTNESS; -- } -- -- bl->props.brightness = dft_brightness; -- ht16k33_bl_update_status(bl); -- - ht16k33_fb_queue(priv); - return 0; - -diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c -index 1cce409ce5cac..e33ce0151cdfd 100644 ---- a/drivers/auxdisplay/img-ascii-lcd.c -+++ b/drivers/auxdisplay/img-ascii-lcd.c -@@ -280,6 +280,16 @@ static int img_ascii_lcd_display(struct img_ascii_lcd_ctx *ctx, - if (msg[count - 1] == '\n') - count--; - -+ if (!count) { -+ /* clear the LCD */ -+ devm_kfree(&ctx->pdev->dev, ctx->message); -+ ctx->message = NULL; -+ ctx->message_len = 0; -+ memset(ctx->curr, ' ', ctx->cfg->num_chars); -+ ctx->cfg->update(ctx); -+ return 0; -+ } -+ - new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL); - if (!new_msg) - return -ENOMEM; -diff --git a/drivers/auxdisplay/lcd2s.c b/drivers/auxdisplay/lcd2s.c -index 38ba08628ccb3..2578b2d454397 100644 ---- a/drivers/auxdisplay/lcd2s.c -+++ b/drivers/auxdisplay/lcd2s.c -@@ -238,7 +238,7 @@ static int lcd2s_redefine_char(struct charlcd *lcd, char *esc) - if (buf[1] > 7) - return 1; - -- i = 0; -+ i = 2; - shift = 0; - value = 0; - while (*esc && i < LCD2S_CHARACTER_SIZE + 2) { -@@ -298,6 +298,10 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c, - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) - return -EIO; - -+ lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL); -+ if (!lcd2s) -+ return -ENOMEM; -+ - /* Test, if the display is responding */ - err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF); - if (err < 0) -@@ -307,12 +311,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c, - if (!lcd) - return -ENOMEM; - -- lcd2s = kzalloc(sizeof(struct lcd2s_data), GFP_KERNEL); -- if (!lcd2s) { -- err = -ENOMEM; -- goto fail1; -- } -- - lcd->drvdata = lcd2s; - lcd2s->i2c = i2c; - lcd2s->charlcd = lcd; -@@ -321,26 +319,24 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c, - err = device_property_read_u32(&i2c->dev, "display-height-chars", - &lcd->height); - if (err) -- goto fail2; -+ goto fail1; - - err = device_property_read_u32(&i2c->dev, "display-width-chars", - &lcd->width); - if (err) -- goto fail2; -+ goto fail1; - - lcd->ops = &lcd2s_ops; - - err = charlcd_register(lcd2s->charlcd); - if (err) -- goto fail2; -+ goto fail1; - - i2c_set_clientdata(i2c, lcd2s); - return 0; - --fail2: -- kfree(lcd2s); - fail1: -- kfree(lcd); -+ charlcd_free(lcd2s->charlcd); - return err; - } - -@@ -349,7 +345,7 @@ static int lcd2s_i2c_remove(struct i2c_client *i2c) - struct lcd2s_data *lcd2s = i2c_get_clientdata(i2c); - - charlcd_unregister(lcd2s->charlcd); -- kfree(lcd2s->charlcd); -+ charlcd_free(lcd2s->charlcd); - return 0; - } - -diff --git a/drivers/base/component.c b/drivers/base/component.c -index 5e79299f6c3ff..870485cbbb87c 100644 ---- a/drivers/base/component.c -+++ b/drivers/base/component.c -@@ -246,7 +246,7 @@ static int try_to_bring_up_master(struct master *master, - return 0; - } - -- if (!devres_open_group(master->parent, NULL, GFP_KERNEL)) -+ if (!devres_open_group(master->parent, master, GFP_KERNEL)) - return -ENOMEM; - - /* Found all components */ -@@ -258,6 +258,7 @@ static int try_to_bring_up_master(struct master *master, - return ret; - } - -+ devres_close_group(master->parent, NULL); - master->bound = true; - return 1; - } -@@ -282,7 +283,7 @@ static void take_down_master(struct master *master) - { - if (master->bound) { - master->ops->unbind(master->parent); -- devres_release_group(master->parent, NULL); -+ devres_release_group(master->parent, master); - master->bound = false; - } - } -diff --git a/drivers/base/core.c b/drivers/base/core.c -index 249da496581a0..8e73a34e10055 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -485,8 +485,7 @@ static void device_link_release_fn(struct work_struct *work) - /* Ensure that all references to the link object have been dropped. */ - device_link_synchronize_removal(); - -- while (refcount_dec_not_one(&link->rpm_active)) -- pm_runtime_put(link->supplier); -+ pm_runtime_release_supplier(link, true); - - put_device(link->consumer); - put_device(link->supplier); -@@ -821,9 +820,7 @@ struct device_link *device_link_add(struct device *consumer, - dev_bus_name(supplier), dev_name(supplier), - dev_bus_name(consumer), dev_name(consumer)); - if (device_register(&link->link_dev)) { -- put_device(consumer); -- put_device(supplier); -- kfree(link); -+ put_device(&link->link_dev); - link = NULL; - goto out; - } -diff --git a/drivers/base/dd.c b/drivers/base/dd.c -index 68ea1f949daa9..6b66306932016 100644 ---- a/drivers/base/dd.c -+++ b/drivers/base/dd.c -@@ -629,6 +629,9 @@ re_probe: - drv->remove(dev); - - devres_release_all(dev); -+ arch_teardown_dma_ops(dev); -+ kfree(dev->dma_range_map); -+ dev->dma_range_map = NULL; - driver_sysfs_remove(dev); - dev->driver = NULL; - dev_set_drvdata(dev, NULL); -@@ -1208,6 +1211,8 @@ static void __device_release_driver(struct device *dev, struct device *parent) - - devres_release_all(dev); - arch_teardown_dma_ops(dev); -+ kfree(dev->dma_range_map); -+ dev->dma_range_map = NULL; - dev->driver = NULL; - dev_set_drvdata(dev, NULL); - if (dev->pm_domain && dev->pm_domain->dismiss) -diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c -index 8be352ab4ddbf..fa13ad49d2116 100644 ---- a/drivers/base/devtmpfs.c -+++ b/drivers/base/devtmpfs.c -@@ -59,8 +59,15 @@ static struct dentry *public_dev_mount(struct file_system_type *fs_type, int fla - const char *dev_name, void *data) - { - struct super_block *s = mnt->mnt_sb; -+ int err; -+ - atomic_inc(&s->s_active); - down_write(&s->s_umount); -+ err = reconfigure_single(s, flags, data); -+ if (err < 0) { -+ deactivate_locked_super(s); -+ return ERR_PTR(err); -+ } - return dget(s->s_root); - } - -diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c -index bdbedc6660a87..ef904b8b112e6 100644 ---- a/drivers/base/firmware_loader/main.c -+++ b/drivers/base/firmware_loader/main.c -@@ -100,12 +100,15 @@ static struct firmware_cache fw_cache; - extern struct builtin_fw __start_builtin_fw[]; - extern struct builtin_fw __end_builtin_fw[]; - --static void fw_copy_to_prealloc_buf(struct firmware *fw, -+static bool fw_copy_to_prealloc_buf(struct firmware *fw, - void *buf, size_t size) - { -- if (!buf || size < fw->size) -- return; -+ if (!buf) -+ return true; -+ if (size < fw->size) -+ return false; - memcpy(buf, fw->data, fw->size); -+ return true; - } - - static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, -@@ -117,9 +120,7 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, - if (strcmp(name, b_fw->name) == 0) { - fw->size = b_fw->size; - fw->data = b_fw->data; -- fw_copy_to_prealloc_buf(fw, buf, size); -- -- return true; -+ return fw_copy_to_prealloc_buf(fw, buf, size); - } - } - -diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c -index cbea78e79f3df..6bce40e2506e5 100644 ---- a/drivers/base/power/main.c -+++ b/drivers/base/power/main.c -@@ -711,6 +711,7 @@ static void dpm_noirq_resume_devices(pm_message_t state) - dev = to_device(dpm_noirq_list.next); - get_device(dev); - list_move_tail(&dev->power.entry, &dpm_late_early_list); -+ - mutex_unlock(&dpm_list_mtx); - - if (!is_async(dev)) { -@@ -725,8 +726,9 @@ static void dpm_noirq_resume_devices(pm_message_t state) - } - } - -- mutex_lock(&dpm_list_mtx); - put_device(dev); -+ -+ mutex_lock(&dpm_list_mtx); - } - mutex_unlock(&dpm_list_mtx); - async_synchronize_full(); -@@ -852,6 +854,7 @@ void dpm_resume_early(pm_message_t state) - dev = to_device(dpm_late_early_list.next); - get_device(dev); - list_move_tail(&dev->power.entry, &dpm_suspended_list); -+ - mutex_unlock(&dpm_list_mtx); - - if (!is_async(dev)) { -@@ -865,8 +868,10 @@ void dpm_resume_early(pm_message_t state) - pm_dev_err(dev, state, " early", error); - } - } -- mutex_lock(&dpm_list_mtx); -+ - put_device(dev); -+ -+ mutex_lock(&dpm_list_mtx); - } - mutex_unlock(&dpm_list_mtx); - async_synchronize_full(); -@@ -1029,7 +1034,12 @@ void dpm_resume(pm_message_t state) - } - if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_prepared_list); -+ -+ mutex_unlock(&dpm_list_mtx); -+ - put_device(dev); -+ -+ mutex_lock(&dpm_list_mtx); - } - mutex_unlock(&dpm_list_mtx); - async_synchronize_full(); -@@ -1051,7 +1061,7 @@ static void device_complete(struct device *dev, pm_message_t state) - const char *info = NULL; - - if (dev->power.syscore) -- return; -+ goto out; - - device_lock(dev); - -@@ -1081,6 +1091,7 @@ static void device_complete(struct device *dev, pm_message_t state) - - device_unlock(dev); - -+out: - pm_runtime_put(dev); - } - -@@ -1106,14 +1117,16 @@ void dpm_complete(pm_message_t state) - get_device(dev); - dev->power.is_prepared = false; - list_move(&dev->power.entry, &list); -+ - mutex_unlock(&dpm_list_mtx); - - trace_device_pm_callback_start(dev, "", state.event); - device_complete(dev, state); - trace_device_pm_callback_end(dev, 0); - -- mutex_lock(&dpm_list_mtx); - put_device(dev); -+ -+ mutex_lock(&dpm_list_mtx); - } - list_splice(&list, &dpm_list); - mutex_unlock(&dpm_list_mtx); -@@ -1298,17 +1311,21 @@ static int dpm_noirq_suspend_devices(pm_message_t state) - error = device_suspend_noirq(dev); - - mutex_lock(&dpm_list_mtx); -+ - if (error) { - pm_dev_err(dev, state, " noirq", error); - dpm_save_failed_dev(dev_name(dev)); -- put_device(dev); -- break; -- } -- if (!list_empty(&dev->power.entry)) -+ } else if (!list_empty(&dev->power.entry)) { - list_move(&dev->power.entry, &dpm_noirq_list); -+ } -+ -+ mutex_unlock(&dpm_list_mtx); -+ - put_device(dev); - -- if (async_error) -+ mutex_lock(&dpm_list_mtx); -+ -+ if (error || async_error) - break; - } - mutex_unlock(&dpm_list_mtx); -@@ -1475,23 +1492,28 @@ int dpm_suspend_late(pm_message_t state) - struct device *dev = to_device(dpm_suspended_list.prev); - - get_device(dev); -+ - mutex_unlock(&dpm_list_mtx); - - error = device_suspend_late(dev); - - mutex_lock(&dpm_list_mtx); -+ - if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &dpm_late_early_list); - - if (error) { - pm_dev_err(dev, state, " late", error); - dpm_save_failed_dev(dev_name(dev)); -- put_device(dev); -- break; - } -+ -+ mutex_unlock(&dpm_list_mtx); -+ - put_device(dev); - -- if (async_error) -+ mutex_lock(&dpm_list_mtx); -+ -+ if (error || async_error) - break; - } - mutex_unlock(&dpm_list_mtx); -@@ -1751,21 +1773,27 @@ int dpm_suspend(pm_message_t state) - struct device *dev = to_device(dpm_prepared_list.prev); - - get_device(dev); -+ - mutex_unlock(&dpm_list_mtx); - - error = device_suspend(dev); - - mutex_lock(&dpm_list_mtx); -+ - if (error) { - pm_dev_err(dev, state, "", error); - dpm_save_failed_dev(dev_name(dev)); -- put_device(dev); -- break; -- } -- if (!list_empty(&dev->power.entry)) -+ } else if (!list_empty(&dev->power.entry)) { - list_move(&dev->power.entry, &dpm_suspended_list); -+ } -+ -+ mutex_unlock(&dpm_list_mtx); -+ - put_device(dev); -- if (async_error) -+ -+ mutex_lock(&dpm_list_mtx); -+ -+ if (error || async_error) - break; - } - mutex_unlock(&dpm_list_mtx); -@@ -1794,9 +1822,6 @@ static int device_prepare(struct device *dev, pm_message_t state) - int (*callback)(struct device *) = NULL; - int ret = 0; - -- if (dev->power.syscore) -- return 0; -- - /* - * If a device's parent goes into runtime suspend at the wrong time, - * it won't be possible to resume the device. To prevent this we -@@ -1805,6 +1830,9 @@ static int device_prepare(struct device *dev, pm_message_t state) - */ - pm_runtime_get_noresume(dev); - -+ if (dev->power.syscore) -+ return 0; -+ - device_lock(dev); - - dev->power.wakeup_path = false; -@@ -1878,10 +1906,11 @@ int dpm_prepare(pm_message_t state) - device_block_probing(); - - mutex_lock(&dpm_list_mtx); -- while (!list_empty(&dpm_list)) { -+ while (!list_empty(&dpm_list) && !error) { - struct device *dev = to_device(dpm_list.next); - - get_device(dev); -+ - mutex_unlock(&dpm_list_mtx); - - trace_device_pm_callback_start(dev, "", state.event); -@@ -1889,21 +1918,23 @@ int dpm_prepare(pm_message_t state) - trace_device_pm_callback_end(dev, error); - - mutex_lock(&dpm_list_mtx); -- if (error) { -- if (error == -EAGAIN) { -- put_device(dev); -- error = 0; -- continue; -- } -+ -+ if (!error) { -+ dev->power.is_prepared = true; -+ if (!list_empty(&dev->power.entry)) -+ list_move_tail(&dev->power.entry, &dpm_prepared_list); -+ } else if (error == -EAGAIN) { -+ error = 0; -+ } else { - dev_info(dev, "not prepared for power transition: code %d\n", - error); -- put_device(dev); -- break; - } -- dev->power.is_prepared = true; -- if (!list_empty(&dev->power.entry)) -- list_move_tail(&dev->power.entry, &dpm_prepared_list); -+ -+ mutex_unlock(&dpm_list_mtx); -+ - put_device(dev); -+ -+ mutex_lock(&dpm_list_mtx); - } - mutex_unlock(&dpm_list_mtx); - trace_suspend_resume(TPS("dpm_prepare"), state.event, false); -diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c -index ec94049442b99..44ae3909e64bb 100644 ---- a/drivers/base/power/runtime.c -+++ b/drivers/base/power/runtime.c -@@ -305,19 +305,40 @@ static int rpm_get_suppliers(struct device *dev) - return 0; - } - -+/** -+ * pm_runtime_release_supplier - Drop references to device link's supplier. -+ * @link: Target device link. -+ * @check_idle: Whether or not to check if the supplier device is idle. -+ * -+ * Drop all runtime PM references associated with @link to its supplier device -+ * and if @check_idle is set, check if that device is idle (and so it can be -+ * suspended). -+ */ -+void pm_runtime_release_supplier(struct device_link *link, bool check_idle) -+{ -+ struct device *supplier = link->supplier; -+ -+ /* -+ * The additional power.usage_count check is a safety net in case -+ * the rpm_active refcount becomes saturated, in which case -+ * refcount_dec_not_one() would return true forever, but it is not -+ * strictly necessary. -+ */ -+ while (refcount_dec_not_one(&link->rpm_active) && -+ atomic_read(&supplier->power.usage_count) > 0) -+ pm_runtime_put_noidle(supplier); -+ -+ if (check_idle) -+ pm_request_idle(supplier); -+} -+ - static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend) - { - struct device_link *link; - - list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, -- device_links_read_lock_held()) { -- -- while (refcount_dec_not_one(&link->rpm_active)) -- pm_runtime_put_noidle(link->supplier); -- -- if (try_to_suspend) -- pm_request_idle(link->supplier); -- } -+ device_links_read_lock_held()) -+ pm_runtime_release_supplier(link, try_to_suspend); - } - - static void rpm_put_suppliers(struct device *dev) -@@ -1770,9 +1791,7 @@ void pm_runtime_drop_link(struct device_link *link) - return; - - pm_runtime_drop_link_count(link->consumer); -- -- while (refcount_dec_not_one(&link->rpm_active)) -- pm_runtime_put(link->supplier); -+ pm_runtime_release_supplier(link, true); - } - - static bool pm_runtime_need_not_resume(struct device *dev) -diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c -index 99bda0da23a82..8666590201c9a 100644 ---- a/drivers/base/power/wakeup.c -+++ b/drivers/base/power/wakeup.c -@@ -34,7 +34,8 @@ suspend_state_t pm_suspend_target_state; - bool events_check_enabled __read_mostly; - - /* First wakeup IRQ seen by the kernel in the last cycle. */ --unsigned int pm_wakeup_irq __read_mostly; -+static unsigned int wakeup_irq[2] __read_mostly; -+static DEFINE_RAW_SPINLOCK(wakeup_irq_lock); - - /* If greater than 0 and the system is suspending, terminate the suspend. */ - static atomic_t pm_abort_suspend __read_mostly; -@@ -942,19 +943,45 @@ void pm_system_cancel_wakeup(void) - atomic_dec_if_positive(&pm_abort_suspend); - } - --void pm_wakeup_clear(bool reset) -+void pm_wakeup_clear(unsigned int irq_number) - { -- pm_wakeup_irq = 0; -- if (reset) -+ raw_spin_lock_irq(&wakeup_irq_lock); -+ -+ if (irq_number && wakeup_irq[0] == irq_number) -+ wakeup_irq[0] = wakeup_irq[1]; -+ else -+ wakeup_irq[0] = 0; -+ -+ wakeup_irq[1] = 0; -+ -+ raw_spin_unlock_irq(&wakeup_irq_lock); -+ -+ if (!irq_number) - atomic_set(&pm_abort_suspend, 0); - } - - void pm_system_irq_wakeup(unsigned int irq_number) - { -- if (pm_wakeup_irq == 0) { -- pm_wakeup_irq = irq_number; -+ unsigned long flags; -+ -+ raw_spin_lock_irqsave(&wakeup_irq_lock, flags); -+ -+ if (wakeup_irq[0] == 0) -+ wakeup_irq[0] = irq_number; -+ else if (wakeup_irq[1] == 0) -+ wakeup_irq[1] = irq_number; -+ else -+ irq_number = 0; -+ -+ raw_spin_unlock_irqrestore(&wakeup_irq_lock, flags); -+ -+ if (irq_number) - pm_system_wakeup(); -- } -+} -+ -+unsigned int pm_wakeup_irq(void) -+{ -+ return wakeup_irq[0]; - } - - /** -diff --git a/drivers/base/property.c b/drivers/base/property.c -index 453918eb7390c..4c77837769c6e 100644 ---- a/drivers/base/property.c -+++ b/drivers/base/property.c -@@ -1269,8 +1269,10 @@ fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id, - - fwnode_graph_for_each_endpoint(fwnode, ep) { - node = fwnode_graph_get_remote_port_parent(ep); -- if (!fwnode_device_is_available(node)) -+ if (!fwnode_device_is_available(node)) { -+ fwnode_handle_put(node); - continue; -+ } - - ret = match(node, con_id, data); - fwnode_handle_put(node); -diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c -index d2656581a6085..4a446259a184e 100644 ---- a/drivers/base/regmap/regmap-irq.c -+++ b/drivers/base/regmap/regmap-irq.c -@@ -189,11 +189,9 @@ static void regmap_irq_sync_unlock(struct irq_data *data) - ret = regmap_write(map, reg, d->mask_buf[i]); - if (d->chip->clear_ack) { - if (d->chip->ack_invert && !ret) -- ret = regmap_write(map, reg, -- d->mask_buf[i]); -+ ret = regmap_write(map, reg, UINT_MAX); - else if (!ret) -- ret = regmap_write(map, reg, -- ~d->mask_buf[i]); -+ ret = regmap_write(map, reg, 0); - } - if (ret != 0) - dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", -@@ -556,11 +554,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) - data->status_buf[i]); - if (chip->clear_ack) { - if (chip->ack_invert && !ret) -- ret = regmap_write(map, reg, -- data->status_buf[i]); -+ ret = regmap_write(map, reg, UINT_MAX); - else if (!ret) -- ret = regmap_write(map, reg, -- ~data->status_buf[i]); -+ ret = regmap_write(map, reg, 0); - } - if (ret != 0) - dev_err(map->dev, "Failed to ack 0x%x: %d\n", -@@ -817,13 +813,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, - d->status_buf[i] & d->mask_buf[i]); - if (chip->clear_ack) { - if (chip->ack_invert && !ret) -- ret = regmap_write(map, reg, -- (d->status_buf[i] & -- d->mask_buf[i])); -+ ret = regmap_write(map, reg, UINT_MAX); - else if (!ret) -- ret = regmap_write(map, reg, -- ~(d->status_buf[i] & -- d->mask_buf[i])); -+ ret = regmap_write(map, reg, 0); - } - if (ret != 0) { - dev_err(map->dev, "Failed to ack 0x%x: %d\n", -diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c -index 21a0c2562ec06..f7811641ed5ae 100644 ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -647,6 +647,7 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, - if (ret) - return ret; - -+ regmap_debugfs_exit(map); - regmap_debugfs_init(map); - - /* Add a devres resource for dev_get_regmap() */ -diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c -index c46f6a8e14d23..3ba1232ce8451 100644 ---- a/drivers/base/swnode.c -+++ b/drivers/base/swnode.c -@@ -535,7 +535,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, - return -ENOENT; - - if (nargs_prop) { -- error = property_entry_read_int_array(swnode->node->properties, -+ error = property_entry_read_int_array(ref->node->properties, - nargs_prop, sizeof(u32), - &nargs_prop_val, 1); - if (error) -diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c -index a093644ac39fb..aab48b292a3bb 100644 ---- a/drivers/block/ataflop.c -+++ b/drivers/block/ataflop.c -@@ -298,6 +298,7 @@ static struct atari_floppy_struct { - disk change detection) */ - int flags; /* flags */ - struct gendisk *disk[NUM_DISK_MINORS]; -+ bool registered[NUM_DISK_MINORS]; - int ref; - int type; - struct blk_mq_tag_set tag_set; -@@ -456,10 +457,20 @@ static DEFINE_TIMER(fd_timer, check_change); - - static void fd_end_request_cur(blk_status_t err) - { -+ DPRINT(("fd_end_request_cur(), bytes %d of %d\n", -+ blk_rq_cur_bytes(fd_request), -+ blk_rq_bytes(fd_request))); -+ - if (!blk_update_request(fd_request, err, - blk_rq_cur_bytes(fd_request))) { -+ DPRINT(("calling __blk_mq_end_request()\n")); - __blk_mq_end_request(fd_request, err); - fd_request = NULL; -+ } else { -+ /* requeue rest of request */ -+ DPRINT(("calling blk_mq_requeue_request()\n")); -+ blk_mq_requeue_request(fd_request, true); -+ fd_request = NULL; - } - } - -@@ -653,9 +664,6 @@ static inline void copy_buffer(void *from, void *to) - *p2++ = *p1++; - } - -- -- -- - /* General Interrupt Handling */ - - static void (*FloppyIRQHandler)( int status ) = NULL; -@@ -700,12 +708,21 @@ static void fd_error( void ) - if (fd_request->error_count >= MAX_ERRORS) { - printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive ); - fd_end_request_cur(BLK_STS_IOERR); -+ finish_fdc(); -+ return; - } - else if (fd_request->error_count == RECALIBRATE_ERRORS) { - printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive ); - if (SelectedDrive != -1) - SUD.track = -1; - } -+ /* need to re-run request to recalibrate */ -+ atari_disable_irq( IRQ_MFP_FDC ); -+ -+ setup_req_params( SelectedDrive ); -+ do_fd_action( SelectedDrive ); -+ -+ atari_enable_irq( IRQ_MFP_FDC ); - } - - -@@ -732,8 +749,10 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) - if (type) { - type--; - if (type >= NUM_DISK_MINORS || -- minor2disktype[type].drive_types > DriveType) -+ minor2disktype[type].drive_types > DriveType) { -+ finish_fdc(); - return -EINVAL; -+ } - } - - q = unit[drive].disk[type]->queue; -@@ -751,6 +770,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) - } - - if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { -+ finish_fdc(); - ret = -EINVAL; - goto out; - } -@@ -791,6 +811,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) - - wait_for_completion(&format_wait); - -+ finish_fdc(); - ret = FormatError ? -EIO : 0; - out: - blk_mq_unquiesce_queue(q); -@@ -825,6 +846,7 @@ static void do_fd_action( int drive ) - else { - /* all sectors finished */ - fd_end_request_cur(BLK_STS_OK); -+ finish_fdc(); - return; - } - } -@@ -1229,6 +1251,7 @@ static void fd_rwsec_done1(int status) - else { - /* all sectors finished */ - fd_end_request_cur(BLK_STS_OK); -+ finish_fdc(); - } - return; - -@@ -1350,7 +1373,7 @@ static void fd_times_out(struct timer_list *unused) - - static void finish_fdc( void ) - { -- if (!NeedSeek) { -+ if (!NeedSeek || !stdma_is_locked_by(floppy_irq)) { - finish_fdc_done( 0 ); - } - else { -@@ -1385,7 +1408,8 @@ static void finish_fdc_done( int dummy ) - start_motor_off_timer(); - - local_irq_save(flags); -- stdma_release(); -+ if (stdma_is_locked_by(floppy_irq)) -+ stdma_release(); - local_irq_restore(flags); - - DPRINT(("finish_fdc() finished\n")); -@@ -1475,15 +1499,6 @@ static void setup_req_params( int drive ) - ReqTrack, ReqSector, (unsigned long)ReqData )); - } - --static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx) --{ -- spin_lock_irq(&ataflop_lock); -- atari_disable_irq(IRQ_MFP_FDC); -- finish_fdc(); -- atari_enable_irq(IRQ_MFP_FDC); -- spin_unlock_irq(&ataflop_lock); --} -- - static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, - const struct blk_mq_queue_data *bd) - { -@@ -1491,6 +1506,10 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, - int drive = floppy - unit; - int type = floppy->type; - -+ DPRINT(("Queue request: drive %d type %d sectors %d of %d last %d\n", -+ drive, type, blk_rq_cur_sectors(bd->rq), -+ blk_rq_sectors(bd->rq), bd->last)); -+ - spin_lock_irq(&ataflop_lock); - if (fd_request) { - spin_unlock_irq(&ataflop_lock); -@@ -1511,6 +1530,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, - /* drive not connected */ - printk(KERN_ERR "Unknown Device: fd%d\n", drive ); - fd_end_request_cur(BLK_STS_IOERR); -+ stdma_release(); - goto out; - } - -@@ -1527,11 +1547,13 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, - if (--type >= NUM_DISK_MINORS) { - printk(KERN_WARNING "fd%d: invalid disk format", drive ); - fd_end_request_cur(BLK_STS_IOERR); -+ stdma_release(); - goto out; - } - if (minor2disktype[type].drive_types > DriveType) { - printk(KERN_WARNING "fd%d: unsupported disk format", drive ); - fd_end_request_cur(BLK_STS_IOERR); -+ stdma_release(); - goto out; - } - type = minor2disktype[type].index; -@@ -1550,8 +1572,6 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, - setup_req_params( drive ); - do_fd_action( drive ); - -- if (bd->last) -- finish_fdc(); - atari_enable_irq( IRQ_MFP_FDC ); - - out: -@@ -1634,6 +1654,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, - /* what if type > 0 here? Overwrite specified entry ? */ - if (type) { - /* refuse to re-set a predefined type for now */ -+ finish_fdc(); - return -EINVAL; - } - -@@ -1701,8 +1722,10 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, - - /* sanity check */ - if (setprm.track != dtp->blocks/dtp->spt/2 || -- setprm.head != 2) -+ setprm.head != 2) { -+ finish_fdc(); - return -EINVAL; -+ } - - UDT = dtp; - set_capacity(disk, UDT->blocks); -@@ -1962,7 +1985,6 @@ static const struct block_device_operations floppy_fops = { - - static const struct blk_mq_ops ataflop_mq_ops = { - .queue_rq = ataflop_queue_rq, -- .commit_rqs = ataflop_commit_rqs, - }; - - static int ataflop_alloc_disk(unsigned int drive, unsigned int type) -@@ -1986,8 +2008,6 @@ static int ataflop_alloc_disk(unsigned int drive, unsigned int type) - return 0; - } - --static DEFINE_MUTEX(ataflop_probe_lock); -- - static void ataflop_probe(dev_t dev) - { - int drive = MINOR(dev) & 3; -@@ -1998,12 +2018,46 @@ static void ataflop_probe(dev_t dev) - - if (drive >= FD_MAX_UNITS || type >= NUM_DISK_MINORS) - return; -- mutex_lock(&ataflop_probe_lock); - if (!unit[drive].disk[type]) { -- if (ataflop_alloc_disk(drive, type) == 0) -+ if (ataflop_alloc_disk(drive, type) == 0) { - add_disk(unit[drive].disk[type]); -+ unit[drive].registered[type] = true; -+ } -+ } -+} -+ -+static void atari_floppy_cleanup(void) -+{ -+ int i; -+ int type; -+ -+ for (i = 0; i < FD_MAX_UNITS; i++) { -+ for (type = 0; type < NUM_DISK_MINORS; type++) { -+ if (!unit[i].disk[type]) -+ continue; -+ del_gendisk(unit[i].disk[type]); -+ blk_cleanup_queue(unit[i].disk[type]->queue); -+ put_disk(unit[i].disk[type]); -+ } -+ blk_mq_free_tag_set(&unit[i].tag_set); -+ } -+ -+ del_timer_sync(&fd_timer); -+ atari_stram_free(DMABuffer); -+} -+ -+static void atari_cleanup_floppy_disk(struct atari_floppy_struct *fs) -+{ -+ int type; -+ -+ for (type = 0; type < NUM_DISK_MINORS; type++) { -+ if (!fs->disk[type]) -+ continue; -+ if (fs->registered[type]) -+ del_gendisk(fs->disk[type]); -+ blk_cleanup_disk(fs->disk[type]); - } -- mutex_unlock(&ataflop_probe_lock); -+ blk_mq_free_tag_set(&fs->tag_set); - } - - static int __init atari_floppy_init (void) -@@ -2015,11 +2069,6 @@ static int __init atari_floppy_init (void) - /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ - return -ENODEV; - -- mutex_lock(&ataflop_probe_lock); -- ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe); -- if (ret) -- goto out_unlock; -- - for (i = 0; i < FD_MAX_UNITS; i++) { - memset(&unit[i].tag_set, 0, sizeof(unit[i].tag_set)); - unit[i].tag_set.ops = &ataflop_mq_ops; -@@ -2065,6 +2114,7 @@ static int __init atari_floppy_init (void) - unit[i].track = -1; - unit[i].flags = 0; - add_disk(unit[i].disk[0]); -+ unit[i].registered[0] = true; - } - - printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n", -@@ -2072,18 +2122,17 @@ static int __init atari_floppy_init (void) - UseTrackbuffer ? "" : "no "); - config_types(); - -- return 0; -+ ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe); -+ if (ret) { -+ printk(KERN_ERR "atari_floppy_init: cannot register block device\n"); -+ atari_floppy_cleanup(); -+ } -+ return ret; - - err: -- while (--i >= 0) { -- blk_cleanup_queue(unit[i].disk[0]->queue); -- put_disk(unit[i].disk[0]); -- blk_mq_free_tag_set(&unit[i].tag_set); -- } -+ while (--i >= 0) -+ atari_cleanup_floppy_disk(&unit[i]); - -- unregister_blkdev(FLOPPY_MAJOR, "fd"); --out_unlock: -- mutex_unlock(&ataflop_probe_lock); - return ret; - } - -@@ -2128,22 +2177,8 @@ __setup("floppy=", atari_floppy_setup); - - static void __exit atari_floppy_exit(void) - { -- int i, type; -- -- for (i = 0; i < FD_MAX_UNITS; i++) { -- for (type = 0; type < NUM_DISK_MINORS; type++) { -- if (!unit[i].disk[type]) -- continue; -- del_gendisk(unit[i].disk[type]); -- blk_cleanup_queue(unit[i].disk[type]->queue); -- put_disk(unit[i].disk[type]); -- } -- blk_mq_free_tag_set(&unit[i].tag_set); -- } - unregister_blkdev(FLOPPY_MAJOR, "fd"); -- -- del_timer_sync(&fd_timer); -- atari_stram_free( DMABuffer ); -+ atari_floppy_cleanup(); - } - - module_init(atari_floppy_init) -diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c -index fef79ea52e3ed..4a6a74177b3c9 100644 ---- a/drivers/block/floppy.c -+++ b/drivers/block/floppy.c -@@ -1014,7 +1014,7 @@ static DECLARE_DELAYED_WORK(fd_timer, fd_timer_workfn); - static void cancel_activity(void) - { - do_floppy = NULL; -- cancel_delayed_work_sync(&fd_timer); -+ cancel_delayed_work(&fd_timer); - cancel_work_sync(&floppy_work); - } - -@@ -3080,6 +3080,8 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr) - } - } - -+#define MAX_LEN (1UL << MAX_ORDER << PAGE_SHIFT) -+ - static int raw_cmd_copyin(int cmd, void __user *param, - struct floppy_raw_cmd **rcmd) - { -@@ -3107,7 +3109,7 @@ loop: - ptr->resultcode = 0; - - if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { -- if (ptr->length <= 0) -+ if (ptr->length <= 0 || ptr->length >= MAX_LEN) - return -EINVAL; - ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); - fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); -@@ -4478,6 +4480,7 @@ static const struct blk_mq_ops floppy_mq_ops = { - }; - - static struct platform_device floppy_device[N_DRIVE]; -+static bool registered[N_DRIVE]; - - static bool floppy_available(int drive) - { -@@ -4693,6 +4696,8 @@ static int __init do_floppy_init(void) - if (err) - goto out_remove_drives; - -+ registered[drive] = true; -+ - device_add_disk(&floppy_device[drive].dev, disks[drive][0], - NULL); - } -@@ -4703,7 +4708,8 @@ out_remove_drives: - while (drive--) { - if (floppy_available(drive)) { - del_gendisk(disks[drive][0]); -- platform_device_unregister(&floppy_device[drive]); -+ if (registered[drive]) -+ platform_device_unregister(&floppy_device[drive]); - } - } - out_release_dma: -@@ -4946,7 +4952,8 @@ static void __exit floppy_module_exit(void) - if (disks[drive][i]) - del_gendisk(disks[drive][i]); - } -- platform_device_unregister(&floppy_device[drive]); -+ if (registered[drive]) -+ platform_device_unregister(&floppy_device[drive]); - } - for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { - if (disks[drive][i]) -diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 7bf4686af774e..92f9d32bfae5e 100644 ---- a/drivers/block/loop.c -+++ b/drivers/block/loop.c -@@ -79,6 +79,7 @@ - #include - #include - #include -+#include - - #include "loop.h" - -@@ -272,19 +273,6 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) - blk_mq_unfreeze_queue(lo->lo_queue); - } - --/** -- * loop_validate_block_size() - validates the passed in block size -- * @bsize: size to validate -- */ --static int --loop_validate_block_size(unsigned short bsize) --{ -- if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize)) -- return -EINVAL; -- -- return 0; --} -- - /** - * loop_set_size() - sets device size and notifies userspace - * @lo: struct loop_device to set the size for -@@ -952,8 +940,13 @@ static void loop_config_discard(struct loop_device *lo) - granularity = 0; - - } else { -+ struct kstatfs sbuf; -+ - max_discard_sectors = UINT_MAX >> 9; -- granularity = inode->i_sb->s_blocksize; -+ if (!vfs_statfs(&file->f_path, &sbuf)) -+ granularity = sbuf.f_bsize; -+ else -+ max_discard_sectors = 0; - } - - if (max_discard_sectors) { -@@ -1236,7 +1229,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, - } - - if (config->block_size) { -- error = loop_validate_block_size(config->block_size); -+ error = blk_validate_block_size(config->block_size); - if (error) - goto out_unlock; - } -@@ -1759,7 +1752,7 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) - if (lo->lo_state != Lo_bound) - return -ENXIO; - -- err = loop_validate_block_size(arg); -+ err = blk_validate_block_size(arg); - if (err) - return err; - -@@ -2442,7 +2435,7 @@ static int loop_control_remove(int idx) - int ret; - - if (idx < 0) { -- pr_warn("deleting an unspecified loop device is not supported.\n"); -+ pr_warn_once("deleting an unspecified loop device is not supported.\n"); - return -EINVAL; - } - -diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c -index 901855717cb53..ba61e72741eab 100644 ---- a/drivers/block/mtip32xx/mtip32xx.c -+++ b/drivers/block/mtip32xx/mtip32xx.c -@@ -4112,7 +4112,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) - "Completion workers still active!\n"); - } - -- blk_set_queue_dying(dd->queue); -+ blk_mark_disk_dead(dd->disk); - set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); - - /* Clean up the block layer. */ -diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c -index 1183f7872b713..577c7dba5d78d 100644 ---- a/drivers/block/nbd.c -+++ b/drivers/block/nbd.c -@@ -122,10 +122,10 @@ struct nbd_device { - struct work_struct remove_work; - - struct list_head list; -- struct task_struct *task_recv; - struct task_struct *task_setup; - - unsigned long flags; -+ pid_t pid; /* pid of nbd-client, if attached */ - - char *backend; - }; -@@ -217,7 +217,7 @@ static ssize_t pid_show(struct device *dev, - struct gendisk *disk = dev_to_disk(dev); - struct nbd_device *nbd = (struct nbd_device *)disk->private_data; - -- return sprintf(buf, "%d\n", task_pid_nr(nbd->task_recv)); -+ return sprintf(buf, "%d\n", nbd->pid); - } - - static const struct device_attribute pid_attr = { -@@ -329,7 +329,7 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, - nbd->config->bytesize = bytesize; - nbd->config->blksize_bits = __ffs(blksize); - -- if (!nbd->task_recv) -+ if (!nbd->pid) - return 0; - - if (nbd->config->flags & NBD_FLAG_SEND_TRIM) { -@@ -1241,7 +1241,7 @@ static void nbd_config_put(struct nbd_device *nbd) - if (test_and_clear_bit(NBD_RT_HAS_PID_FILE, - &config->runtime_flags)) - device_remove_file(disk_to_dev(nbd->disk), &pid_attr); -- nbd->task_recv = NULL; -+ nbd->pid = 0; - if (test_and_clear_bit(NBD_RT_HAS_BACKEND_FILE, - &config->runtime_flags)) { - device_remove_file(disk_to_dev(nbd->disk), &backend_attr); -@@ -1282,7 +1282,7 @@ static int nbd_start_device(struct nbd_device *nbd) - int num_connections = config->num_connections; - int error = 0, i; - -- if (nbd->task_recv) -+ if (nbd->pid) - return -EBUSY; - if (!config->socks) - return -EINVAL; -@@ -1301,7 +1301,7 @@ static int nbd_start_device(struct nbd_device *nbd) - } - - blk_mq_update_nr_hw_queues(&nbd->tag_set, config->num_connections); -- nbd->task_recv = current; -+ nbd->pid = task_pid_nr(current); - - nbd_parse_flags(nbd); - -@@ -1557,8 +1557,8 @@ static int nbd_dbg_tasks_show(struct seq_file *s, void *unused) - { - struct nbd_device *nbd = s->private; - -- if (nbd->task_recv) -- seq_printf(s, "recv: %d\n", task_pid_nr(nbd->task_recv)); -+ if (nbd->pid) -+ seq_printf(s, "recv: %d\n", nbd->pid); - - return 0; - } -@@ -1749,11 +1749,11 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) - disk->major = NBD_MAJOR; - - /* Too big first_minor can cause duplicate creation of -- * sysfs files/links, since first_minor will be truncated to -- * byte in __device_add_disk(). -+ * sysfs files/links, since index << part_shift might overflow, or -+ * MKDEV() expect that the max bits of first_minor is 20. - */ - disk->first_minor = index << part_shift; -- if (disk->first_minor > 0xff) { -+ if (disk->first_minor < index || disk->first_minor > MINORMASK) { - err = -EINVAL; - goto out_free_idr; - } -@@ -2135,7 +2135,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) - mutex_lock(&nbd->config_lock); - config = nbd->config; - if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) || -- !nbd->task_recv) { -+ !nbd->pid) { - dev_err(nbd_to_dev(nbd), - "not configured, cannot reconfigure\n"); - ret = -EINVAL; -diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c -index e65c9d706f6fb..c4a52f33604dc 100644 ---- a/drivers/block/rbd.c -+++ b/drivers/block/rbd.c -@@ -7182,7 +7182,7 @@ static ssize_t do_rbd_remove(struct bus_type *bus, - * IO to complete/fail. - */ - blk_mq_freeze_queue(rbd_dev->disk->queue); -- blk_set_queue_dying(rbd_dev->disk->queue); -+ blk_mark_disk_dead(rbd_dev->disk); - } - - del_gendisk(rbd_dev->disk); -diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c -index 72902104f1112..1becbbb3be139 100644 ---- a/drivers/block/xen-blkfront.c -+++ b/drivers/block/xen-blkfront.c -@@ -1290,7 +1290,8 @@ free_shadow: - rinfo->ring_ref[i] = GRANT_INVALID_REF; - } - } -- free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE)); -+ free_pages_exact(rinfo->ring.sring, -+ info->nr_ring_pages * XEN_PAGE_SIZE); - rinfo->ring.sring = NULL; - - if (rinfo->irq) -@@ -1374,9 +1375,15 @@ static int blkif_get_final_status(enum blk_req_status s1, - return BLKIF_RSP_OKAY; - } - --static bool blkif_completion(unsigned long *id, -- struct blkfront_ring_info *rinfo, -- struct blkif_response *bret) -+/* -+ * Return values: -+ * 1 response processed. -+ * 0 missing further responses. -+ * -1 error while processing. -+ */ -+static int blkif_completion(unsigned long *id, -+ struct blkfront_ring_info *rinfo, -+ struct blkif_response *bret) - { - int i = 0; - struct scatterlist *sg; -@@ -1399,7 +1406,7 @@ static bool blkif_completion(unsigned long *id, - - /* Wait the second response if not yet here. */ - if (s2->status < REQ_DONE) -- return false; -+ return 0; - - bret->status = blkif_get_final_status(s->status, - s2->status); -@@ -1450,42 +1457,43 @@ static bool blkif_completion(unsigned long *id, - } - /* Add the persistent grant into the list of free grants */ - for (i = 0; i < num_grant; i++) { -- if (gnttab_query_foreign_access(s->grants_used[i]->gref)) { -+ if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) { - /* - * If the grant is still mapped by the backend (the - * backend has chosen to make this grant persistent) - * we add it at the head of the list, so it will be - * reused first. - */ -- if (!info->feature_persistent) -- pr_alert_ratelimited("backed has not unmapped grant: %u\n", -- s->grants_used[i]->gref); -+ if (!info->feature_persistent) { -+ pr_alert("backed has not unmapped grant: %u\n", -+ s->grants_used[i]->gref); -+ return -1; -+ } - list_add(&s->grants_used[i]->node, &rinfo->grants); - rinfo->persistent_gnts_c++; - } else { - /* -- * If the grant is not mapped by the backend we end the -- * foreign access and add it to the tail of the list, -- * so it will not be picked again unless we run out of -- * persistent grants. -+ * If the grant is not mapped by the backend we add it -+ * to the tail of the list, so it will not be picked -+ * again unless we run out of persistent grants. - */ -- gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL); - s->grants_used[i]->gref = GRANT_INVALID_REF; - list_add_tail(&s->grants_used[i]->node, &rinfo->grants); - } - } - if (s->req.operation == BLKIF_OP_INDIRECT) { - for (i = 0; i < INDIRECT_GREFS(num_grant); i++) { -- if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) { -- if (!info->feature_persistent) -- pr_alert_ratelimited("backed has not unmapped grant: %u\n", -- s->indirect_grants[i]->gref); -+ if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) { -+ if (!info->feature_persistent) { -+ pr_alert("backed has not unmapped grant: %u\n", -+ s->indirect_grants[i]->gref); -+ return -1; -+ } - list_add(&s->indirect_grants[i]->node, &rinfo->grants); - rinfo->persistent_gnts_c++; - } else { - struct page *indirect_page; - -- gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL); - /* - * Add the used indirect page back to the list of - * available pages for indirect grefs. -@@ -1500,7 +1508,7 @@ static bool blkif_completion(unsigned long *id, - } - } - -- return true; -+ return 1; - } - - static irqreturn_t blkif_interrupt(int irq, void *dev_id) -@@ -1511,9 +1519,12 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) - unsigned long flags; - struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id; - struct blkfront_info *info = rinfo->dev_info; -+ unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS; - -- if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) -+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { -+ xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); - return IRQ_HANDLED; -+ } - - spin_lock_irqsave(&rinfo->ring_lock, flags); - again: -@@ -1529,6 +1540,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) - unsigned long id; - unsigned int op; - -+ eoiflag = 0; -+ - RING_COPY_RESPONSE(&rinfo->ring, i, &bret); - id = bret.id; - -@@ -1561,12 +1574,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) - } - - if (bret.operation != BLKIF_OP_DISCARD) { -+ int ret; -+ - /* - * We may need to wait for an extra response if the - * I/O request is split in 2 - */ -- if (!blkif_completion(&id, rinfo, &bret)) -+ ret = blkif_completion(&id, rinfo, &bret); -+ if (!ret) - continue; -+ if (unlikely(ret < 0)) -+ goto err; - } - - if (add_id_to_freelist(rinfo, id)) { -@@ -1645,6 +1663,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) - - spin_unlock_irqrestore(&rinfo->ring_lock, flags); - -+ xen_irq_lateeoi(irq, eoiflag); -+ - return IRQ_HANDLED; - - err: -@@ -1652,6 +1672,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) - - spin_unlock_irqrestore(&rinfo->ring_lock, flags); - -+ /* No EOI in order to avoid further interrupts. */ -+ - pr_alert("%s disabled for further use\n", info->gd->disk_name); - return IRQ_HANDLED; - } -@@ -1669,8 +1691,7 @@ static int setup_blkring(struct xenbus_device *dev, - for (i = 0; i < info->nr_ring_pages; i++) - rinfo->ring_ref[i] = GRANT_INVALID_REF; - -- sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH, -- get_order(ring_size)); -+ sring = alloc_pages_exact(ring_size, GFP_NOIO); - if (!sring) { - xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); - return -ENOMEM; -@@ -1680,7 +1701,7 @@ static int setup_blkring(struct xenbus_device *dev, - - err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref); - if (err < 0) { -- free_pages((unsigned long)sring, get_order(ring_size)); -+ free_pages_exact(sring, ring_size); - rinfo->ring.sring = NULL; - goto fail; - } -@@ -1691,8 +1712,8 @@ static int setup_blkring(struct xenbus_device *dev, - if (err) - goto fail; - -- err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0, -- "blkif", rinfo); -+ err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt, -+ 0, "blkif", rinfo); - if (err <= 0) { - xenbus_dev_fatal(dev, err, - "bind_evtchn_to_irqhandler failed"); -@@ -2119,7 +2140,7 @@ static void blkfront_closing(struct blkfront_info *info) - - /* No more blkif_request(). */ - blk_mq_stop_hw_queues(info->rq); -- blk_set_queue_dying(info->rq); -+ blk_mark_disk_dead(info->gd); - set_capacity(info->gd, 0); - - for_each_rinfo(info, rinfo, i) { -@@ -2520,11 +2541,10 @@ static void purge_persistent_grants(struct blkfront_info *info) - list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants, - node) { - if (gnt_list_entry->gref == GRANT_INVALID_REF || -- gnttab_query_foreign_access(gnt_list_entry->gref)) -+ !gnttab_try_end_foreign_access(gnt_list_entry->gref)) - continue; - - list_del(&gnt_list_entry->node); -- gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL); - rinfo->persistent_gnts_c--; - gnt_list_entry->gref = GRANT_INVALID_REF; - list_add_tail(&gnt_list_entry->node, &rinfo->grants); -diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c -index fcaf2750f68f7..6383c81ac5b37 100644 ---- a/drivers/block/zram/zram_drv.c -+++ b/drivers/block/zram/zram_drv.c -@@ -910,7 +910,7 @@ static ssize_t read_block_state(struct file *file, char __user *buf, - zram_test_flag(zram, index, ZRAM_HUGE) ? 'h' : '.', - zram_test_flag(zram, index, ZRAM_IDLE) ? 'i' : '.'); - -- if (count < copied) { -+ if (count <= copied) { - zram_slot_unlock(zram, index); - break; - } -diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c -index 5a321b4076aab..cab93935cc7f1 100644 ---- a/drivers/bluetooth/bfusb.c -+++ b/drivers/bluetooth/bfusb.c -@@ -628,6 +628,9 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i - data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; - data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); - -+ if (!data->bulk_pkt_size) -+ goto done; -+ - rwlock_init(&data->lock); - - data->reassembly = NULL; -diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c -index e4182acee488c..d9ceca7a7935c 100644 ---- a/drivers/bluetooth/btbcm.c -+++ b/drivers/bluetooth/btbcm.c -@@ -8,6 +8,7 @@ - - #include - #include -+#include - #include - - #include -@@ -343,6 +344,52 @@ static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev) - return skb; - } - -+static const struct dmi_system_id disable_broken_read_transmit_power[] = { -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,1"), -+ }, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,2"), -+ }, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,4"), -+ }, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir8,1"), -+ }, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir8,2"), -+ }, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac20,1"), -+ }, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac20,2"), -+ }, -+ }, -+ { } -+}; -+ - static int btbcm_read_info(struct hci_dev *hdev) - { - struct sk_buff *skb; -@@ -363,6 +410,10 @@ static int btbcm_read_info(struct hci_dev *hdev) - bt_dev_info(hdev, "BCM: features 0x%2.2x", skb->data[1]); - kfree_skb(skb); - -+ /* Read DMI and disable broken Read LE Min/Max Tx Power */ -+ if (dmi_first_match(disable_broken_read_transmit_power)) -+ set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks); -+ - return 0; - } - -diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c -index f1705b46fc889..e73d4c719b0ad 100644 ---- a/drivers/bluetooth/btintel.c -+++ b/drivers/bluetooth/btintel.c -@@ -2193,8 +2193,15 @@ static int btintel_setup_combined(struct hci_dev *hdev) - * As a workaround, send HCI Reset command first which will reset the - * number of completed commands and allow normal command processing - * from now on. -+ * -+ * Regarding the INTEL_BROKEN_SHUTDOWN_LED flag, these devices maybe -+ * in the SW_RFKILL ON state as a workaround of fixing LED issue during -+ * the shutdown() procedure, and once the device is in SW_RFKILL ON -+ * state, the only way to exit out of it is sending the HCI_Reset -+ * command. - */ -- if (btintel_test_flag(hdev, INTEL_BROKEN_INITIAL_NCMD)) { -+ if (btintel_test_flag(hdev, INTEL_BROKEN_INITIAL_NCMD) || -+ btintel_test_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED)) { - skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, - HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { -@@ -2263,12 +2270,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) - set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, - &hdev->quirks); - -- /* These devices have an issue with LED which doesn't -- * go off immediately during shutdown. Set the flag -- * here to send the LED OFF command during shutdown. -- */ -- btintel_set_flag(hdev, INTEL_BROKEN_LED); -- - err = btintel_legacy_rom_setup(hdev, &ver); - break; - case 0x0b: /* SfP */ -@@ -2329,10 +2330,14 @@ static int btintel_setup_combined(struct hci_dev *hdev) - case 0x12: /* ThP */ - case 0x13: /* HrP */ - case 0x14: /* CcP */ -- /* Some legacy bootloader devices from JfP supports both old -- * and TLV based HCI_Intel_Read_Version command. But we don't -- * want to use the TLV based setup routines for those legacy -- * bootloader device. -+ /* Some legacy bootloader devices starting from JfP, -+ * the operational firmware supports both old and TLV based -+ * HCI_Intel_Read_Version command based on the command -+ * parameter. -+ * -+ * For upgrading firmware case, the TLV based version cannot -+ * be used because the firmware filename for legacy bootloader -+ * is based on the old format. - * - * Also, it is not easy to convert TLV based version from the - * legacy version format. -@@ -2344,6 +2349,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) - err = btintel_read_version(hdev, &ver); - if (err) - return err; -+ -+ /* Apply the device specific HCI quirks -+ * -+ * All Legacy bootloader devices support WBS -+ */ -+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); -+ -+ /* Valid LE States quirk for JfP/ThP familiy */ -+ if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12) -+ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); -+ -+ /* Setup MSFT Extension support */ -+ btintel_set_msft_opcode(hdev, ver.hw_variant); -+ - err = btintel_bootloader_setup(hdev, &ver); - break; - case 0x17: -@@ -2399,9 +2418,10 @@ static int btintel_shutdown_combined(struct hci_dev *hdev) - - /* Some platforms have an issue with BT LED when the interface is - * down or BT radio is turned off, which takes 5 seconds to BT LED -- * goes off. This command turns off the BT LED immediately. -+ * goes off. As a workaround, sends HCI_Intel_SW_RFKILL to put the -+ * device in the RFKILL ON state which turns off the BT LED immediately. - */ -- if (btintel_test_flag(hdev, INTEL_BROKEN_LED)) { -+ if (btintel_test_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED)) { - skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - ret = PTR_ERR(skb); -diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h -index aa64072bbe68d..704e3b7bcb77c 100644 ---- a/drivers/bluetooth/btintel.h -+++ b/drivers/bluetooth/btintel.h -@@ -145,7 +145,7 @@ enum { - INTEL_FIRMWARE_FAILED, - INTEL_BOOTING, - INTEL_BROKEN_INITIAL_NCMD, -- INTEL_BROKEN_LED, -+ INTEL_BROKEN_SHUTDOWN_LED, - INTEL_ROM_LEGACY, - - __INTEL_NUM_FLAGS, -diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c -index 9872ef18f9fea..1cbdeca1fdc4a 100644 ---- a/drivers/bluetooth/btmtksdio.c -+++ b/drivers/bluetooth/btmtksdio.c -@@ -1042,6 +1042,8 @@ static int btmtksdio_runtime_suspend(struct device *dev) - if (!bdev) - return 0; - -+ sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); -+ - sdio_claim_host(bdev->func); - - sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err); -diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c -index e9d91d7c0db48..9ba22b13b4fa0 100644 ---- a/drivers/bluetooth/btmtkuart.c -+++ b/drivers/bluetooth/btmtkuart.c -@@ -158,8 +158,10 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, - int err; - - hlen = sizeof(*hdr) + wmt_params->dlen; -- if (hlen > 255) -- return -EINVAL; -+ if (hlen > 255) { -+ err = -EINVAL; -+ goto err_free_skb; -+ } - - hdr = (struct mtk_wmt_hdr *)&wc; - hdr->dir = 1; -@@ -173,7 +175,7 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, - err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc); - if (err < 0) { - clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); -- return err; -+ goto err_free_skb; - } - - /* The vendor specific WMT commands are all answered by a vendor -@@ -190,13 +192,14 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, - if (err == -EINTR) { - bt_dev_err(hdev, "Execution of wmt command interrupted"); - clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); -- return err; -+ goto err_free_skb; - } - - if (err) { - bt_dev_err(hdev, "Execution of wmt command timed out"); - clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); -- return -ETIMEDOUT; -+ err = -ETIMEDOUT; -+ goto err_free_skb; - } - - /* Parse and handle the return WMT event */ -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index 60d2fce59a71d..ac90392cce339 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -59,6 +59,7 @@ static struct usb_driver btusb_driver; - #define BTUSB_WIDEBAND_SPEECH 0x400000 - #define BTUSB_VALID_LE_STATES 0x800000 - #define BTUSB_QCA_WCN6855 0x1000000 -+#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED 0x2000000 - #define BTUSB_INTEL_BROKEN_INITIAL_NCMD 0x4000000 - - static const struct usb_device_id btusb_table[] = { -@@ -295,6 +296,24 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x0cf3, 0xe600), .driver_info = BTUSB_QCA_WCN6855 | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0cc), .driver_info = BTUSB_QCA_WCN6855 | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0d6), .driver_info = BTUSB_QCA_WCN6855 | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0e3), .driver_info = BTUSB_QCA_WCN6855 | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x10ab, 0x9309), .driver_info = BTUSB_QCA_WCN6855 | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x10ab, 0x9409), .driver_info = BTUSB_QCA_WCN6855 | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0d0), .driver_info = BTUSB_QCA_WCN6855 | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - - /* Broadcom BCM2035 */ - { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, -@@ -365,10 +384,13 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED }, - { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, - { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED | -- BTUSB_INTEL_BROKEN_INITIAL_NCMD }, -- { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL_COMBINED }, -+ BTUSB_INTEL_BROKEN_INITIAL_NCMD | -+ BTUSB_INTEL_BROKEN_SHUTDOWN_LED }, -+ { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL_COMBINED | -+ BTUSB_INTEL_BROKEN_SHUTDOWN_LED }, - { USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_COMBINED }, -- { USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL_COMBINED }, -+ { USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL_COMBINED | -+ BTUSB_INTEL_BROKEN_SHUTDOWN_LED }, - { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_COMBINED }, - - /* Other Intel Bluetooth devices */ -@@ -384,6 +406,14 @@ static const struct usb_device_id blacklist_table[] = { - /* Realtek 8852AE Bluetooth devices */ - { USB_DEVICE(0x0bda, 0xc852), .driver_info = BTUSB_REALTEK | - BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x0bda, 0x385a), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x0bda, 0x4852), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x04c5, 0x165c), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x04ca, 0x4006), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, - - /* Realtek Bluetooth devices */ - { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), -@@ -410,10 +440,21 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x13d3, 0x3563), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, - -+ /* MediaTek MT7922A Bluetooth devices */ -+ { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, -+ - /* Additional Realtek 8723AE Bluetooth devices */ - { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, - { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK }, -@@ -433,6 +474,10 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK }, - { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK }, - -+ /* Additional Realtek 8761B Bluetooth devices */ -+ { USB_DEVICE(0x2357, 0x0604), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ - /* Additional Realtek 8761BU Bluetooth devices */ - { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK | - BTUSB_WIDEBAND_SPEECH }, -@@ -451,10 +496,6 @@ static const struct usb_device_id blacklist_table[] = { - /* Additional Realtek 8822CE Bluetooth devices */ - { USB_DEVICE(0x04ca, 0x4005), .driver_info = BTUSB_REALTEK | - BTUSB_WIDEBAND_SPEECH }, -- /* Bluetooth component of Realtek 8852AE device */ -- { USB_DEVICE(0x04ca, 0x4006), .driver_info = BTUSB_REALTEK | -- BTUSB_WIDEBAND_SPEECH }, -- - { USB_DEVICE(0x04c5, 0x161f), .driver_info = BTUSB_REALTEK | - BTUSB_WIDEBAND_SPEECH }, - { USB_DEVICE(0x0b05, 0x18ef), .driver_info = BTUSB_REALTEK | -@@ -2217,6 +2258,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) - skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC); - if (!skb) { - hdev->stat.err_rx++; -+ kfree(urb->setup_packet); - return; - } - -@@ -2237,6 +2279,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) - data->evt_skb = skb_clone(skb, GFP_ATOMIC); - if (!data->evt_skb) { - kfree_skb(skb); -+ kfree(urb->setup_packet); - return; - } - } -@@ -2245,6 +2288,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) - if (err < 0) { - kfree_skb(data->evt_skb); - data->evt_skb = NULL; -+ kfree(urb->setup_packet); - return; - } - -@@ -2255,6 +2299,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) - wake_up_bit(&data->flags, - BTUSB_TX_WAIT_VND_EVT); - } -+ kfree(urb->setup_packet); - return; - } else if (urb->status == -ENOENT) { - /* Avoid suspend failed when usb_kill_urb */ -@@ -2275,6 +2320,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) - usb_anchor_urb(urb, &data->ctrl_anchor); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { -+ kfree(urb->setup_packet); - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected - */ -@@ -2515,6 +2561,7 @@ static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwnam - } else { - bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)", - status); -+ err = -EIO; - goto err_release_fw; - } - } -@@ -2804,11 +2851,16 @@ static int btusb_mtk_setup(struct hci_dev *hdev) - case 0x7668: - fwname = FIRMWARE_MT7668; - break; -+ case 0x7922: - case 0x7961: - snprintf(fw_bin_name, sizeof(fw_bin_name), - "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", - dev_id & 0xffff, (fw_version & 0xff) + 1); - err = btusb_mtk_setup_firmware_79xx(hdev, fw_bin_name); -+ if (err < 0) { -+ bt_dev_err(hdev, "Failed to set up firmware (%d)", err); -+ return err; -+ } - - /* It's Device EndPoint Reset Option Register */ - btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); -@@ -2828,6 +2880,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev) - } - - hci_set_msft_opcode(hdev, 0xFD30); -+ hci_set_aosp_capable(hdev); - goto done; - default: - bt_dev_err(hdev, "Unsupported hardware variant (%08x)", -@@ -3808,6 +3861,9 @@ static int btusb_probe(struct usb_interface *intf, - - if (id->driver_info & BTUSB_INTEL_BROKEN_INITIAL_NCMD) - btintel_set_flag(hdev, INTEL_BROKEN_INITIAL_NCMD); -+ -+ if (id->driver_info & BTUSB_INTEL_BROKEN_SHUTDOWN_LED) -+ btintel_set_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED); - } - - if (id->driver_info & BTUSB_MARVELL) -diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c -index ef54afa293574..7abf99f0ee399 100644 ---- a/drivers/bluetooth/hci_bcm.c -+++ b/drivers/bluetooth/hci_bcm.c -@@ -1188,7 +1188,12 @@ static int bcm_probe(struct platform_device *pdev) - return -ENOMEM; - - dev->dev = &pdev->dev; -- dev->irq = platform_get_irq(pdev, 0); -+ -+ ret = platform_get_irq(pdev, 0); -+ if (ret < 0) -+ return ret; -+ -+ dev->irq = ret; - - /* Initialize routing field to an unused value */ - dev->pcm_int_params[0] = 0xff; -diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c -index 0c0dedece59c5..d49a39d17d7dc 100644 ---- a/drivers/bluetooth/hci_h5.c -+++ b/drivers/bluetooth/hci_h5.c -@@ -587,9 +587,11 @@ static int h5_recv(struct hci_uart *hu, const void *data, int count) - count -= processed; - } - -- pm_runtime_get(&hu->serdev->dev); -- pm_runtime_mark_last_busy(&hu->serdev->dev); -- pm_runtime_put_autosuspend(&hu->serdev->dev); -+ if (hu->serdev) { -+ pm_runtime_get(&hu->serdev->dev); -+ pm_runtime_mark_last_busy(&hu->serdev->dev); -+ pm_runtime_put_autosuspend(&hu->serdev->dev); -+ } - - return 0; - } -@@ -846,6 +848,8 @@ static int h5_serdev_probe(struct serdev_device *serdev) - h5->vnd = data->vnd; - } - -+ if (data->driver_info & H5_INFO_WAKEUP_DISABLE) -+ set_bit(H5_WAKEUP_DISABLE, &h5->flags); - - h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(h5->enable_gpio)) -@@ -860,9 +864,6 @@ static int h5_serdev_probe(struct serdev_device *serdev) - if (err) - return err; - -- if (data->driver_info & H5_INFO_WAKEUP_DISABLE) -- set_bit(H5_WAKEUP_DISABLE, &h5->flags); -- - return 0; - } - -@@ -962,11 +963,13 @@ static void h5_btrtl_open(struct h5 *h5) - serdev_device_set_parity(h5->hu->serdev, SERDEV_PARITY_EVEN); - serdev_device_set_baudrate(h5->hu->serdev, 115200); - -- pm_runtime_set_active(&h5->hu->serdev->dev); -- pm_runtime_use_autosuspend(&h5->hu->serdev->dev); -- pm_runtime_set_autosuspend_delay(&h5->hu->serdev->dev, -- SUSPEND_TIMEOUT_MS); -- pm_runtime_enable(&h5->hu->serdev->dev); -+ if (!test_bit(H5_WAKEUP_DISABLE, &h5->flags)) { -+ pm_runtime_set_active(&h5->hu->serdev->dev); -+ pm_runtime_use_autosuspend(&h5->hu->serdev->dev); -+ pm_runtime_set_autosuspend_delay(&h5->hu->serdev->dev, -+ SUSPEND_TIMEOUT_MS); -+ pm_runtime_enable(&h5->hu->serdev->dev); -+ } - - /* The controller needs up to 500ms to wakeup */ - gpiod_set_value_cansleep(h5->enable_gpio, 1); -@@ -976,7 +979,8 @@ static void h5_btrtl_open(struct h5 *h5) - - static void h5_btrtl_close(struct h5 *h5) - { -- pm_runtime_disable(&h5->hu->serdev->dev); -+ if (!test_bit(H5_WAKEUP_DISABLE, &h5->flags)) -+ pm_runtime_disable(&h5->hu->serdev->dev); - - gpiod_set_value_cansleep(h5->device_wake_gpio, 0); - gpiod_set_value_cansleep(h5->enable_gpio, 0); -diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c -index 53deea2eb7b4d..8eb7fddfb9300 100644 ---- a/drivers/bluetooth/hci_qca.c -+++ b/drivers/bluetooth/hci_qca.c -@@ -1927,6 +1927,9 @@ static int qca_power_off(struct hci_dev *hdev) - hu->hdev->hw_error = NULL; - hu->hdev->cmd_timeout = NULL; - -+ del_timer_sync(&qca->wake_retrans_timer); -+ del_timer_sync(&qca->tx_idle_timer); -+ - /* Stop sending shutdown command if soc crashes. */ - if (soc_type != QCA_ROME - && qca->memdump_state == QCA_MEMDUMP_IDLE) { -@@ -2055,14 +2058,14 @@ static int qca_serdev_probe(struct serdev_device *serdev) - - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); -- if (!qcadev->bt_en && data->soc_type == QCA_WCN6750) { -+ if (IS_ERR_OR_NULL(qcadev->bt_en) && data->soc_type == QCA_WCN6750) { - dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); - power_ctrl_enabled = false; - } - - qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", - GPIOD_IN); -- if (!qcadev->sw_ctrl && data->soc_type == QCA_WCN6750) -+ if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && data->soc_type == QCA_WCN6750) - dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); - - qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); -@@ -2084,7 +2087,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) - - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); -- if (!qcadev->bt_en) { -+ if (IS_ERR_OR_NULL(qcadev->bt_en)) { - dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); - power_ctrl_enabled = false; - } -diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c -index 8ab26dec5f6e8..8469f9876dd26 100644 ---- a/drivers/bluetooth/hci_vhci.c -+++ b/drivers/bluetooth/hci_vhci.c -@@ -121,6 +121,8 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) - if (opcode & 0x80) - set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); - -+ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); -+ - if (hci_register_dev(hdev) < 0) { - BT_ERR("Can't register HCI device"); - hci_free_dev(hdev); -diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c -index 57908ce4fae85..076e4942a3f0e 100644 ---- a/drivers/bluetooth/virtio_bt.c -+++ b/drivers/bluetooth/virtio_bt.c -@@ -202,6 +202,9 @@ static void virtbt_rx_handle(struct virtio_bluetooth *vbt, struct sk_buff *skb) - hci_skb_pkt_type(skb) = pkt_type; - hci_recv_frame(vbt->hdev, skb); - break; -+ default: -+ kfree_skb(skb); -+ break; - } - } - -diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c -index 5aaca6d0f52b2..f1ec344175928 100644 ---- a/drivers/bus/mhi/core/init.c -+++ b/drivers/bus/mhi/core/init.c -@@ -788,6 +788,7 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, - mhi_chan->offload_ch = ch_cfg->offload_channel; - mhi_chan->db_cfg.reset_req = ch_cfg->doorbell_mode_switch; - mhi_chan->pre_alloc = ch_cfg->auto_queue; -+ mhi_chan->wake_capable = ch_cfg->wake_capable; - - /* - * If MHI host allocates buffers, then the channel direction -diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c -index fb99e3727155b..bb9a2043f3a20 100644 ---- a/drivers/bus/mhi/core/pm.c -+++ b/drivers/bus/mhi/core/pm.c -@@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) - } - EXPORT_SYMBOL_GPL(mhi_pm_suspend); - --int mhi_pm_resume(struct mhi_controller *mhi_cntrl) -+static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) - { - struct mhi_chan *itr, *tmp; - struct device *dev = &mhi_cntrl->mhi_dev->dev; -@@ -898,8 +898,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) - if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) - return -EIO; - -- if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) -- return -EINVAL; -+ if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { -+ dev_warn(dev, "Resuming from non M3 state (%s)\n", -+ TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl))); -+ if (!force) -+ return -EINVAL; -+ } - - /* Notify clients about exiting LPM */ - list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { -@@ -940,8 +944,19 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) - - return 0; - } -+ -+int mhi_pm_resume(struct mhi_controller *mhi_cntrl) -+{ -+ return __mhi_pm_resume(mhi_cntrl, false); -+} - EXPORT_SYMBOL_GPL(mhi_pm_resume); - -+int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl) -+{ -+ return __mhi_pm_resume(mhi_cntrl, true); -+} -+EXPORT_SYMBOL_GPL(mhi_pm_resume_force); -+ - int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) - { - int ret; -@@ -1038,7 +1053,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) - enum mhi_ee_type current_ee; - enum dev_st_transition next_state; - struct device *dev = &mhi_cntrl->mhi_dev->dev; -- u32 val; -+ u32 interval_us = 25000; /* poll register field every 25 milliseconds */ - int ret; - - dev_info(dev, "Requested to power ON\n"); -@@ -1055,10 +1070,6 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) - mutex_lock(&mhi_cntrl->pm_mutex); - mhi_cntrl->pm_state = MHI_PM_DISABLE; - -- ret = mhi_init_irq_setup(mhi_cntrl); -- if (ret) -- goto error_setup_irq; -- - /* Setup BHI INTVEC */ - write_lock_irq(&mhi_cntrl->pm_lock); - mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); -@@ -1072,7 +1083,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) - dev_err(dev, "%s is not a valid EE for power on\n", - TO_MHI_EXEC_STR(current_ee)); - ret = -EIO; -- goto error_async_power_up; -+ goto error_exit; - } - - state = mhi_get_mhi_state(mhi_cntrl); -@@ -1081,20 +1092,12 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) - - if (state == MHI_STATE_SYS_ERR) { - mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); -- ret = wait_event_timeout(mhi_cntrl->state_event, -- MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state) || -- mhi_read_reg_field(mhi_cntrl, -- mhi_cntrl->regs, -- MHICTRL, -- MHICTRL_RESET_MASK, -- MHICTRL_RESET_SHIFT, -- &val) || -- !val, -- msecs_to_jiffies(mhi_cntrl->timeout_ms)); -- if (!ret) { -- ret = -EIO; -+ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, -+ MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, -+ interval_us); -+ if (ret) { - dev_info(dev, "Failed to reset MHI due to syserr state\n"); -- goto error_async_power_up; -+ goto error_exit; - } - - /* -@@ -1104,6 +1107,10 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) - mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); - } - -+ ret = mhi_init_irq_setup(mhi_cntrl); -+ if (ret) -+ goto error_exit; -+ - /* Transition to next state */ - next_state = MHI_IN_PBL(current_ee) ? - DEV_ST_TRANSITION_PBL : DEV_ST_TRANSITION_READY; -@@ -1116,10 +1123,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) - - return 0; - --error_async_power_up: -- mhi_deinit_free_irq(mhi_cntrl); -- --error_setup_irq: -+error_exit: - mhi_cntrl->pm_state = MHI_PM_DISABLE; - mutex_unlock(&mhi_cntrl->pm_mutex); - -diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c -index 59a4896a80309..d340d6864e13a 100644 ---- a/drivers/bus/mhi/pci_generic.c -+++ b/drivers/bus/mhi/pci_generic.c -@@ -20,7 +20,7 @@ - - #define MHI_PCI_DEFAULT_BAR_NUM 0 - --#define MHI_POST_RESET_DELAY_MS 500 -+#define MHI_POST_RESET_DELAY_MS 2000 - - #define HEALTH_CHECK_PERIOD (HZ * 2) - -@@ -366,6 +366,7 @@ static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = { - .config = &modem_foxconn_sdx55_config, - .bar_num = MHI_PCI_DEFAULT_BAR_NUM, - .dma_data_width = 32, -+ .mru_default = 32768, - .sideband_wake = false, - }; - -@@ -401,6 +402,7 @@ static const struct mhi_pci_dev_info mhi_mv31_info = { - .config = &modem_mv31_config, - .bar_num = MHI_PCI_DEFAULT_BAR_NUM, - .dma_data_width = 32, -+ .mru_default = 32768, - }; - - static const struct pci_device_id mhi_pci_id_table[] = { -@@ -1018,7 +1020,7 @@ static int __maybe_unused mhi_pci_freeze(struct device *dev) - * context. - */ - if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { -- mhi_power_down(mhi_cntrl, false); -+ mhi_power_down(mhi_cntrl, true); - mhi_unprepare_after_power_down(mhi_cntrl); - } - -diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c -index 6f225dddc74f4..4566e730ef2b8 100644 ---- a/drivers/bus/sunxi-rsb.c -+++ b/drivers/bus/sunxi-rsb.c -@@ -687,11 +687,11 @@ err_clk_disable: - - static void sunxi_rsb_hw_exit(struct sunxi_rsb *rsb) - { -- /* Keep the clock and PM reference counts consistent. */ -- if (pm_runtime_status_suspended(rsb->dev)) -- pm_runtime_resume(rsb->dev); - reset_control_assert(rsb->rstc); -- clk_disable_unprepare(rsb->clk); -+ -+ /* Keep the clock and PM reference counts consistent. */ -+ if (!pm_runtime_status_suspended(rsb->dev)) -+ clk_disable_unprepare(rsb->clk); - } - - static int __maybe_unused sunxi_rsb_runtime_suspend(struct device *dev) -diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c -index 6a8b7fb5be58d..ebf22929ff328 100644 ---- a/drivers/bus/ti-sysc.c -+++ b/drivers/bus/ti-sysc.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -17,6 +18,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -51,11 +53,18 @@ struct sysc_address { - struct list_head node; - }; - -+struct sysc_module { -+ struct sysc *ddata; -+ struct list_head node; -+}; -+ - struct sysc_soc_info { - unsigned long general_purpose:1; - enum sysc_soc soc; -- struct mutex list_lock; /* disabled modules list lock */ -+ struct mutex list_lock; /* disabled and restored modules list lock */ - struct list_head disabled_modules; -+ struct list_head restored_modules; -+ struct notifier_block nb; - }; - - enum sysc_clocks { -@@ -223,37 +232,77 @@ static u32 sysc_read_sysstatus(struct sysc *ddata) - return sysc_read(ddata, offset); - } - --/* Poll on reset status */ --static int sysc_wait_softreset(struct sysc *ddata) -+static int sysc_poll_reset_sysstatus(struct sysc *ddata) - { -- u32 sysc_mask, syss_done, rstval; -- int syss_offset, error = 0; -- -- if (ddata->cap->regbits->srst_shift < 0) -- return 0; -- -- syss_offset = ddata->offsets[SYSC_SYSSTATUS]; -- sysc_mask = BIT(ddata->cap->regbits->srst_shift); -+ int error, retries; -+ u32 syss_done, rstval; - - if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) - syss_done = 0; - else - syss_done = ddata->cfg.syss_mask; - -- if (syss_offset >= 0) { -+ if (likely(!timekeeping_suspended)) { - error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata, - rstval, (rstval & ddata->cfg.syss_mask) == - syss_done, 100, MAX_MODULE_SOFTRESET_WAIT); -+ } else { -+ retries = MAX_MODULE_SOFTRESET_WAIT; -+ while (retries--) { -+ rstval = sysc_read_sysstatus(ddata); -+ if ((rstval & ddata->cfg.syss_mask) == syss_done) -+ return 0; -+ udelay(2); /* Account for udelay flakeyness */ -+ } -+ error = -ETIMEDOUT; -+ } -+ -+ return error; -+} -+ -+static int sysc_poll_reset_sysconfig(struct sysc *ddata) -+{ -+ int error, retries; -+ u32 sysc_mask, rstval; -+ -+ sysc_mask = BIT(ddata->cap->regbits->srst_shift); - -- } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { -+ if (likely(!timekeeping_suspended)) { - error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata, - rstval, !(rstval & sysc_mask), - 100, MAX_MODULE_SOFTRESET_WAIT); -+ } else { -+ retries = MAX_MODULE_SOFTRESET_WAIT; -+ while (retries--) { -+ rstval = sysc_read_sysconfig(ddata); -+ if (!(rstval & sysc_mask)) -+ return 0; -+ udelay(2); /* Account for udelay flakeyness */ -+ } -+ error = -ETIMEDOUT; - } - - return error; - } - -+/* Poll on reset status */ -+static int sysc_wait_softreset(struct sysc *ddata) -+{ -+ int syss_offset, error = 0; -+ -+ if (ddata->cap->regbits->srst_shift < 0) -+ return 0; -+ -+ syss_offset = ddata->offsets[SYSC_SYSSTATUS]; -+ -+ if (syss_offset >= 0) -+ error = sysc_poll_reset_sysstatus(ddata); -+ else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) -+ error = sysc_poll_reset_sysconfig(ddata); -+ -+ return error; -+} -+ - static int sysc_add_named_clock_from_child(struct sysc *ddata, - const char *name, - const char *optfck_name) -@@ -1518,7 +1567,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { - 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), - SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | -- SYSC_QUIRK_REINIT_ON_RESUME), -+ SYSC_QUIRK_REINIT_ON_CTX_LOST), - SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, - SYSC_MODULE_QUIRK_WDT), - /* PRUSS on am3, am4 and am5 */ -@@ -2401,6 +2450,78 @@ static struct dev_pm_domain sysc_child_pm_domain = { - } - }; - -+/* Caller needs to take list_lock if ever used outside of cpu_pm */ -+static void sysc_reinit_modules(struct sysc_soc_info *soc) -+{ -+ struct sysc_module *module; -+ struct list_head *pos; -+ struct sysc *ddata; -+ -+ list_for_each(pos, &sysc_soc->restored_modules) { -+ module = list_entry(pos, struct sysc_module, node); -+ ddata = module->ddata; -+ sysc_reinit_module(ddata, ddata->enabled); -+ } -+} -+ -+/** -+ * sysc_context_notifier - optionally reset and restore module after idle -+ * @nb: notifier block -+ * @cmd: unused -+ * @v: unused -+ * -+ * Some interconnect target modules need to be restored, or reset and restored -+ * on CPU_PM CPU_PM_CLUSTER_EXIT notifier. This is needed at least for am335x -+ * OTG and GPMC target modules even if the modules are unused. -+ */ -+static int sysc_context_notifier(struct notifier_block *nb, unsigned long cmd, -+ void *v) -+{ -+ struct sysc_soc_info *soc; -+ -+ soc = container_of(nb, struct sysc_soc_info, nb); -+ -+ switch (cmd) { -+ case CPU_CLUSTER_PM_ENTER: -+ break; -+ case CPU_CLUSTER_PM_ENTER_FAILED: /* No need to restore context */ -+ break; -+ case CPU_CLUSTER_PM_EXIT: -+ sysc_reinit_modules(soc); -+ break; -+ } -+ -+ return NOTIFY_OK; -+} -+ -+/** -+ * sysc_add_restored - optionally add reset and restore quirk hanlling -+ * @ddata: device data -+ */ -+static void sysc_add_restored(struct sysc *ddata) -+{ -+ struct sysc_module *restored_module; -+ -+ restored_module = kzalloc(sizeof(*restored_module), GFP_KERNEL); -+ if (!restored_module) -+ return; -+ -+ restored_module->ddata = ddata; -+ -+ mutex_lock(&sysc_soc->list_lock); -+ -+ list_add(&restored_module->node, &sysc_soc->restored_modules); -+ -+ if (sysc_soc->nb.notifier_call) -+ goto out_unlock; -+ -+ sysc_soc->nb.notifier_call = sysc_context_notifier; -+ cpu_pm_register_notifier(&sysc_soc->nb); -+ -+out_unlock: -+ mutex_unlock(&sysc_soc->list_lock); -+} -+ - /** - * sysc_legacy_idle_quirk - handle children in omap_device compatible way - * @ddata: device driver data -@@ -2900,12 +3021,14 @@ static int sysc_add_disabled(unsigned long base) - } - - /* -- * One time init to detect the booted SoC and disable unavailable features. -+ * One time init to detect the booted SoC, disable unavailable features -+ * and initialize list for optional cpu_pm notifier. -+ * - * Note that we initialize static data shared across all ti-sysc instances - * so ddata is only used for SoC type. This can be called from module_init - * once we no longer need to rely on platform data. - */ --static int sysc_init_soc(struct sysc *ddata) -+static int sysc_init_static_data(struct sysc *ddata) - { - const struct soc_device_attribute *match; - struct ti_sysc_platform_data *pdata; -@@ -2921,6 +3044,7 @@ static int sysc_init_soc(struct sysc *ddata) - - mutex_init(&sysc_soc->list_lock); - INIT_LIST_HEAD(&sysc_soc->disabled_modules); -+ INIT_LIST_HEAD(&sysc_soc->restored_modules); - sysc_soc->general_purpose = true; - - pdata = dev_get_platdata(ddata->dev); -@@ -2985,15 +3109,24 @@ static int sysc_init_soc(struct sysc *ddata) - return 0; - } - --static void sysc_cleanup_soc(void) -+static void sysc_cleanup_static_data(void) - { -+ struct sysc_module *restored_module; - struct sysc_address *disabled_module; - struct list_head *pos, *tmp; - - if (!sysc_soc) - return; - -+ if (sysc_soc->nb.notifier_call) -+ cpu_pm_unregister_notifier(&sysc_soc->nb); -+ - mutex_lock(&sysc_soc->list_lock); -+ list_for_each_safe(pos, tmp, &sysc_soc->restored_modules) { -+ restored_module = list_entry(pos, struct sysc_module, node); -+ list_del(pos); -+ kfree(restored_module); -+ } - list_for_each_safe(pos, tmp, &sysc_soc->disabled_modules) { - disabled_module = list_entry(pos, struct sysc_address, node); - list_del(pos); -@@ -3061,7 +3194,7 @@ static int sysc_probe(struct platform_device *pdev) - ddata->dev = &pdev->dev; - platform_set_drvdata(pdev, ddata); - -- error = sysc_init_soc(ddata); -+ error = sysc_init_static_data(ddata); - if (error) - return error; - -@@ -3159,6 +3292,9 @@ static int sysc_probe(struct platform_device *pdev) - pm_runtime_put(&pdev->dev); - } - -+ if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_CTX_LOST) -+ sysc_add_restored(ddata); -+ - return 0; - - err: -@@ -3240,7 +3376,7 @@ static void __exit sysc_exit(void) - { - bus_unregister_notifier(&platform_bus_type, &sysc_nb); - platform_driver_unregister(&sysc_driver); -- sysc_cleanup_soc(); -+ sysc_cleanup_static_data(); - } - module_exit(sysc_exit); - -diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c -index ed3c4c42fc23b..d68d05d5d3838 100644 ---- a/drivers/char/agp/parisc-agp.c -+++ b/drivers/char/agp/parisc-agp.c -@@ -281,7 +281,7 @@ agp_ioc_init(void __iomem *ioc_regs) - return 0; - } - --static int -+static int __init - lba_find_capability(int cap) - { - struct _parisc_agp_info *info = &parisc_agp_info; -@@ -366,7 +366,7 @@ fail: - return error; - } - --static int -+static int __init - find_quicksilver(struct device *dev, void *data) - { - struct parisc_device **lba = data; -@@ -378,7 +378,7 @@ find_quicksilver(struct device *dev, void *data) - return 0; - } - --static int -+static int __init - parisc_agp_init(void) - { - extern struct sba_device *sba_list; -diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c -index 8ad7b515a51b8..6c00ea0085553 100644 ---- a/drivers/char/hw_random/mtk-rng.c -+++ b/drivers/char/hw_random/mtk-rng.c -@@ -166,8 +166,13 @@ static int mtk_rng_runtime_resume(struct device *dev) - return mtk_rng_init(&priv->rng); - } - --static UNIVERSAL_DEV_PM_OPS(mtk_rng_pm_ops, mtk_rng_runtime_suspend, -- mtk_rng_runtime_resume, NULL); -+static const struct dev_pm_ops mtk_rng_pm_ops = { -+ SET_RUNTIME_PM_OPS(mtk_rng_runtime_suspend, -+ mtk_rng_runtime_resume, NULL) -+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -+ pm_runtime_force_resume) -+}; -+ - #define MTK_RNG_PM_OPS (&mtk_rng_pm_ops) - #else /* CONFIG_PM */ - #define MTK_RNG_PM_OPS NULL -diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c -index e96cb5c4f97a3..fe91090e04a46 100644 ---- a/drivers/char/ipmi/ipmi_msghandler.c -+++ b/drivers/char/ipmi/ipmi_msghandler.c -@@ -191,6 +191,8 @@ struct ipmi_user { - struct work_struct remove_work; - }; - -+static struct workqueue_struct *remove_work_wq; -+ - static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) - __acquires(user->release_barrier) - { -@@ -1261,7 +1263,7 @@ static void free_user(struct kref *ref) - struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); - - /* SRCU cleanup must happen in task context. */ -- schedule_work(&user->remove_work); -+ queue_work(remove_work_wq, &user->remove_work); - } - - static void _ipmi_destroy_user(struct ipmi_user *user) -@@ -2930,7 +2932,7 @@ cleanup_bmc_device(struct kref *ref) - * with removing the device attributes while reading a device - * attribute. - */ -- schedule_work(&bmc->remove_work); -+ queue_work(remove_work_wq, &bmc->remove_work); - } - - /* -@@ -4789,7 +4791,9 @@ static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0); - static void free_smi_msg(struct ipmi_smi_msg *msg) - { - atomic_dec(&smi_msg_inuse_count); -- kfree(msg); -+ /* Try to keep as much stuff out of the panic path as possible. */ -+ if (!oops_in_progress) -+ kfree(msg); - } - - struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) -@@ -4808,7 +4812,9 @@ EXPORT_SYMBOL(ipmi_alloc_smi_msg); - static void free_recv_msg(struct ipmi_recv_msg *msg) - { - atomic_dec(&recv_msg_inuse_count); -- kfree(msg); -+ /* Try to keep as much stuff out of the panic path as possible. */ -+ if (!oops_in_progress) -+ kfree(msg); - } - - static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) -@@ -4826,7 +4832,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) - - void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) - { -- if (msg->user) -+ if (msg->user && !oops_in_progress) - kref_put(&msg->user->refcount, free_user); - msg->done(msg); - } -@@ -5142,7 +5148,16 @@ static int ipmi_init_msghandler(void) - if (initialized) - goto out; - -- init_srcu_struct(&ipmi_interfaces_srcu); -+ rv = init_srcu_struct(&ipmi_interfaces_srcu); -+ if (rv) -+ goto out; -+ -+ remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq"); -+ if (!remove_work_wq) { -+ pr_err("unable to create ipmi-msghandler-remove-wq workqueue"); -+ rv = -ENOMEM; -+ goto out_wq; -+ } - - timer_setup(&ipmi_timer, ipmi_timeout, 0); - mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); -@@ -5151,6 +5166,9 @@ static int ipmi_init_msghandler(void) - - initialized = true; - -+out_wq: -+ if (rv) -+ cleanup_srcu_struct(&ipmi_interfaces_srcu); - out: - mutex_unlock(&ipmi_interfaces_mutex); - return rv; -@@ -5174,6 +5192,8 @@ static void __exit cleanup_ipmi(void) - int count; - - if (initialized) { -+ destroy_workqueue(remove_work_wq); -+ - atomic_notifier_chain_unregister(&panic_notifier_list, - &panic_block); - -diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c -index 20d5af92966d4..8d7a8898e80b0 100644 ---- a/drivers/char/ipmi/ipmi_ssif.c -+++ b/drivers/char/ipmi/ipmi_ssif.c -@@ -1659,6 +1659,9 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) - } - } - -+ ssif_info->client = client; -+ i2c_set_clientdata(client, ssif_info); -+ - rv = ssif_check_and_remove(client, ssif_info); - /* If rv is 0 and addr source is not SI_ACPI, continue probing */ - if (!rv && ssif_info->addr_source == SI_ACPI) { -@@ -1679,9 +1682,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) - ipmi_addr_src_to_str(ssif_info->addr_source), - client->addr, client->adapter->name, slave_addr); - -- ssif_info->client = client; -- i2c_set_clientdata(client, ssif_info); -- - /* Now check for system interface capabilities */ - msg[0] = IPMI_NETFN_APP_REQUEST << 2; - msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD; -@@ -1881,6 +1881,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) - - dev_err(&ssif_info->client->dev, - "Unable to start IPMI SSIF: %d\n", rv); -+ i2c_set_clientdata(client, NULL); - kfree(ssif_info); - } - kfree(resp); -diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c -index e4ff3b50de7f3..883b4a3410122 100644 ---- a/drivers/char/ipmi/ipmi_watchdog.c -+++ b/drivers/char/ipmi/ipmi_watchdog.c -@@ -342,13 +342,17 @@ static atomic_t msg_tofree = ATOMIC_INIT(0); - static DECLARE_COMPLETION(msg_wait); - static void msg_free_smi(struct ipmi_smi_msg *msg) - { -- if (atomic_dec_and_test(&msg_tofree)) -- complete(&msg_wait); -+ if (atomic_dec_and_test(&msg_tofree)) { -+ if (!oops_in_progress) -+ complete(&msg_wait); -+ } - } - static void msg_free_recv(struct ipmi_recv_msg *msg) - { -- if (atomic_dec_and_test(&msg_tofree)) -- complete(&msg_wait); -+ if (atomic_dec_and_test(&msg_tofree)) { -+ if (!oops_in_progress) -+ complete(&msg_wait); -+ } - } - static struct ipmi_smi_msg smi_msg = { - .done = msg_free_smi -@@ -434,8 +438,10 @@ static int _ipmi_set_timeout(int do_heartbeat) - rv = __ipmi_set_timeout(&smi_msg, - &recv_msg, - &send_heartbeat_now); -- if (rv) -+ if (rv) { -+ atomic_set(&msg_tofree, 0); - return rv; -+ } - - wait_for_completion(&msg_wait); - -@@ -497,7 +503,7 @@ static void panic_halt_ipmi_heartbeat(void) - msg.cmd = IPMI_WDOG_RESET_TIMER; - msg.data = NULL; - msg.data_len = 0; -- atomic_inc(&panic_done_count); -+ atomic_add(2, &panic_done_count); - rv = ipmi_request_supply_msgs(watchdog_user, - (struct ipmi_addr *) &addr, - 0, -@@ -507,7 +513,7 @@ static void panic_halt_ipmi_heartbeat(void) - &panic_halt_heartbeat_recv_msg, - 1); - if (rv) -- atomic_dec(&panic_done_count); -+ atomic_sub(2, &panic_done_count); - } - - static struct ipmi_smi_msg panic_halt_smi_msg = { -@@ -531,12 +537,12 @@ static void panic_halt_ipmi_set_timeout(void) - /* Wait for the messages to be free. */ - while (atomic_read(&panic_done_count) != 0) - ipmi_poll_interface(watchdog_user); -- atomic_inc(&panic_done_count); -+ atomic_add(2, &panic_done_count); - rv = __ipmi_set_timeout(&panic_halt_smi_msg, - &panic_halt_recv_msg, - &send_heartbeat_now); - if (rv) { -- atomic_dec(&panic_done_count); -+ atomic_sub(2, &panic_done_count); - pr_warn("Unable to extend the watchdog timeout\n"); - } else { - if (send_heartbeat_now) -@@ -580,6 +586,7 @@ restart: - &recv_msg, - 1); - if (rv) { -+ atomic_set(&msg_tofree, 0); - pr_warn("heartbeat send failure: %d\n", rv); - return rv; - } -diff --git a/drivers/char/ipmi/kcs_bmc_serio.c b/drivers/char/ipmi/kcs_bmc_serio.c -index 7948cabde50b4..7e2067628a6ce 100644 ---- a/drivers/char/ipmi/kcs_bmc_serio.c -+++ b/drivers/char/ipmi/kcs_bmc_serio.c -@@ -73,10 +73,12 @@ static int kcs_bmc_serio_add_device(struct kcs_bmc_device *kcs_bmc) - struct serio *port; - - priv = devm_kzalloc(kcs_bmc->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; - - /* Use kzalloc() as the allocation is cleaned up with kfree() via serio_unregister_port() */ - port = kzalloc(sizeof(*port), GFP_KERNEL); -- if (!(priv && port)) -+ if (!port) - return -ENOMEM; - - port->id.type = SERIO_8042; -diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h -index 9ccb6b270b071..95164246afd1a 100644 ---- a/drivers/char/mwave/3780i.h -+++ b/drivers/char/mwave/3780i.h -@@ -68,7 +68,7 @@ typedef struct { - unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */ - unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */ - unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */ -- unsigned char Reserved:5; /* 0: Reserved */ -+ unsigned short Reserved:13; /* 0: Reserved */ - } DSP_ISA_SLAVE_CONTROL; - - -diff --git a/drivers/char/random.c b/drivers/char/random.c -index 605969ed0f965..ebe86de9d0acc 100644 ---- a/drivers/char/random.c -+++ b/drivers/char/random.c -@@ -461,6 +461,7 @@ static struct crng_state primary_crng = { - * its value (from 0->1->2). - */ - static int crng_init = 0; -+static bool crng_need_final_init = false; - #define crng_ready() (likely(crng_init > 1)) - static int crng_init_cnt = 0; - static unsigned long crng_global_init_time = 0; -@@ -828,6 +829,36 @@ static void __init crng_initialize_primary(struct crng_state *crng) - crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; - } - -+static void crng_finalize_init(struct crng_state *crng) -+{ -+ if (crng != &primary_crng || crng_init >= 2) -+ return; -+ if (!system_wq) { -+ /* We can't call numa_crng_init until we have workqueues, -+ * so mark this for processing later. */ -+ crng_need_final_init = true; -+ return; -+ } -+ -+ invalidate_batched_entropy(); -+ numa_crng_init(); -+ crng_init = 2; -+ process_random_ready_list(); -+ wake_up_interruptible(&crng_init_wait); -+ kill_fasync(&fasync, SIGIO, POLL_IN); -+ pr_notice("crng init done\n"); -+ if (unseeded_warning.missed) { -+ pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n", -+ unseeded_warning.missed); -+ unseeded_warning.missed = 0; -+ } -+ if (urandom_warning.missed) { -+ pr_notice("%d urandom warning(s) missed due to ratelimiting\n", -+ urandom_warning.missed); -+ urandom_warning.missed = 0; -+ } -+} -+ - #ifdef CONFIG_NUMA - static void do_numa_crng_init(struct work_struct *work) - { -@@ -843,8 +874,8 @@ static void do_numa_crng_init(struct work_struct *work) - crng_initialize_secondary(crng); - pool[i] = crng; - } -- mb(); -- if (cmpxchg(&crng_node_pool, NULL, pool)) { -+ /* pairs with READ_ONCE() in select_crng() */ -+ if (cmpxchg_release(&crng_node_pool, NULL, pool) != NULL) { - for_each_node(i) - kfree(pool[i]); - kfree(pool); -@@ -857,18 +888,38 @@ static void numa_crng_init(void) - { - schedule_work(&numa_crng_init_work); - } -+ -+static struct crng_state *select_crng(void) -+{ -+ struct crng_state **pool; -+ int nid = numa_node_id(); -+ -+ /* pairs with cmpxchg_release() in do_numa_crng_init() */ -+ pool = READ_ONCE(crng_node_pool); -+ if (pool && pool[nid]) -+ return pool[nid]; -+ -+ return &primary_crng; -+} - #else - static void numa_crng_init(void) {} -+ -+static struct crng_state *select_crng(void) -+{ -+ return &primary_crng; -+} - #endif - - /* - * crng_fast_load() can be called by code in the interrupt service -- * path. So we can't afford to dilly-dally. -+ * path. So we can't afford to dilly-dally. Returns the number of -+ * bytes processed from cp. - */ --static int crng_fast_load(const char *cp, size_t len) -+static size_t crng_fast_load(const char *cp, size_t len) - { - unsigned long flags; - char *p; -+ size_t ret = 0; - - if (!spin_trylock_irqsave(&primary_crng.lock, flags)) - return 0; -@@ -879,7 +930,7 @@ static int crng_fast_load(const char *cp, size_t len) - p = (unsigned char *) &primary_crng.state[4]; - while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) { - p[crng_init_cnt % CHACHA_KEY_SIZE] ^= *cp; -- cp++; crng_init_cnt++; len--; -+ cp++; crng_init_cnt++; len--; ret++; - } - spin_unlock_irqrestore(&primary_crng.lock, flags); - if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { -@@ -887,7 +938,7 @@ static int crng_fast_load(const char *cp, size_t len) - crng_init = 1; - pr_notice("fast init done\n"); - } -- return 1; -+ return ret; - } - - /* -@@ -962,38 +1013,23 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) - crng->state[i+4] ^= buf.key[i] ^ rv; - } - memzero_explicit(&buf, sizeof(buf)); -- crng->init_time = jiffies; -+ WRITE_ONCE(crng->init_time, jiffies); - spin_unlock_irqrestore(&crng->lock, flags); -- if (crng == &primary_crng && crng_init < 2) { -- invalidate_batched_entropy(); -- numa_crng_init(); -- crng_init = 2; -- process_random_ready_list(); -- wake_up_interruptible(&crng_init_wait); -- kill_fasync(&fasync, SIGIO, POLL_IN); -- pr_notice("crng init done\n"); -- if (unseeded_warning.missed) { -- pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n", -- unseeded_warning.missed); -- unseeded_warning.missed = 0; -- } -- if (urandom_warning.missed) { -- pr_notice("%d urandom warning(s) missed due to ratelimiting\n", -- urandom_warning.missed); -- urandom_warning.missed = 0; -- } -- } -+ crng_finalize_init(crng); - } - - static void _extract_crng(struct crng_state *crng, - __u8 out[CHACHA_BLOCK_SIZE]) - { -- unsigned long v, flags; -- -- if (crng_ready() && -- (time_after(crng_global_init_time, crng->init_time) || -- time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) -- crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); -+ unsigned long v, flags, init_time; -+ -+ if (crng_ready()) { -+ init_time = READ_ONCE(crng->init_time); -+ if (time_after(READ_ONCE(crng_global_init_time), init_time) || -+ time_after(jiffies, init_time + CRNG_RESEED_INTERVAL)) -+ crng_reseed(crng, crng == &primary_crng ? -+ &input_pool : NULL); -+ } - spin_lock_irqsave(&crng->lock, flags); - if (arch_get_random_long(&v)) - crng->state[14] ^= v; -@@ -1005,15 +1041,7 @@ static void _extract_crng(struct crng_state *crng, - - static void extract_crng(__u8 out[CHACHA_BLOCK_SIZE]) - { -- struct crng_state *crng = NULL; -- --#ifdef CONFIG_NUMA -- if (crng_node_pool) -- crng = crng_node_pool[numa_node_id()]; -- if (crng == NULL) --#endif -- crng = &primary_crng; -- _extract_crng(crng, out); -+ _extract_crng(select_crng(), out); - } - - /* -@@ -1042,15 +1070,7 @@ static void _crng_backtrack_protect(struct crng_state *crng, - - static void crng_backtrack_protect(__u8 tmp[CHACHA_BLOCK_SIZE], int used) - { -- struct crng_state *crng = NULL; -- --#ifdef CONFIG_NUMA -- if (crng_node_pool) -- crng = crng_node_pool[numa_node_id()]; -- if (crng == NULL) --#endif -- crng = &primary_crng; -- _crng_backtrack_protect(crng, tmp, used); -+ _crng_backtrack_protect(select_crng(), tmp, used); - } - - static ssize_t extract_crng_user(void __user *buf, size_t nbytes) -@@ -1269,7 +1289,7 @@ void add_interrupt_randomness(int irq, int irq_flags) - if (unlikely(crng_init == 0)) { - if ((fast_pool->count >= 64) && - crng_fast_load((char *) fast_pool->pool, -- sizeof(fast_pool->pool))) { -+ sizeof(fast_pool->pool)) > 0) { - fast_pool->count = 0; - fast_pool->last = now; - } -@@ -1775,6 +1795,8 @@ static void __init init_std_data(struct entropy_store *r) - int __init rand_initialize(void) - { - init_std_data(&input_pool); -+ if (crng_need_final_init) -+ crng_finalize_init(&primary_crng); - crng_initialize_primary(&primary_crng); - crng_global_init_time = jiffies; - if (ratelimit_disable) { -@@ -1941,7 +1963,10 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) - */ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; -- input_pool.entropy_count = 0; -+ if (xchg(&input_pool.entropy_count, 0) && random_write_wakeup_bits) { -+ wake_up_interruptible(&random_write_wait); -+ kill_fasync(&fasync, SIGIO, POLL_OUT); -+ } - return 0; - case RNDRESEEDCRNG: - if (!capable(CAP_SYS_ADMIN)) -@@ -1949,7 +1974,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) - if (crng_init < 2) - return -ENODATA; - crng_reseed(&primary_crng, &input_pool); -- crng_global_init_time = jiffies - 1; -+ WRITE_ONCE(crng_global_init_time, jiffies - 1); - return 0; - default: - return -EINVAL; -@@ -2275,15 +2300,19 @@ void add_hwgenerator_randomness(const char *buffer, size_t count, - struct entropy_store *poolp = &input_pool; - - if (unlikely(crng_init == 0)) { -- crng_fast_load(buffer, count); -- return; -+ size_t ret = crng_fast_load(buffer, count); -+ count -= ret; -+ buffer += ret; -+ if (!count || crng_init == 0) -+ return; - } - - /* Suspend writing if we're above the trickle threshold. - * We'll be woken up again once below random_write_wakeup_thresh, - * or when the calling thread is about to terminate. - */ -- wait_event_interruptible(random_write_wait, kthread_should_stop() || -+ wait_event_interruptible(random_write_wait, -+ !system_wq || kthread_should_stop() || - ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); - mix_pool_bytes(poolp, buffer, count); - credit_entropy_bits(poolp, entropy); -diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c -index ddaeceb7e1091..df37e7b6a10a5 100644 ---- a/drivers/char/tpm/tpm-chip.c -+++ b/drivers/char/tpm/tpm-chip.c -@@ -474,13 +474,21 @@ static void tpm_del_char_device(struct tpm_chip *chip) - - /* Make the driver uncallable. */ - down_write(&chip->ops_sem); -- if (chip->flags & TPM_CHIP_FLAG_TPM2) { -- if (!tpm_chip_start(chip)) { -- tpm2_shutdown(chip, TPM2_SU_CLEAR); -- tpm_chip_stop(chip); -+ -+ /* -+ * Check if chip->ops is still valid: In case that the controller -+ * drivers shutdown handler unregisters the controller in its -+ * shutdown handler we are called twice and chip->ops to NULL. -+ */ -+ if (chip->ops) { -+ if (chip->flags & TPM_CHIP_FLAG_TPM2) { -+ if (!tpm_chip_start(chip)) { -+ tpm2_shutdown(chip, TPM2_SU_CLEAR); -+ tpm_chip_stop(chip); -+ } - } -+ chip->ops = NULL; - } -- chip->ops = NULL; - up_write(&chip->ops_sem); - } - -diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c -index 784b8b3cb903f..97e916856cf3e 100644 ---- a/drivers/char/tpm/tpm2-space.c -+++ b/drivers/char/tpm/tpm2-space.c -@@ -455,6 +455,9 @@ static int tpm2_map_response_body(struct tpm_chip *chip, u32 cc, u8 *rsp, - if (be32_to_cpu(data->capability) != TPM2_CAP_HANDLES) - return 0; - -+ if (be32_to_cpu(data->count) > (UINT_MAX - TPM_HEADER_SIZE - 9) / 4) -+ return -EFAULT; -+ - if (len != TPM_HEADER_SIZE + 9 + 4 * be32_to_cpu(data->count)) - return -EFAULT; - -diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c -index 69579efb247b3..dc56b976d8162 100644 ---- a/drivers/char/tpm/tpm_tis_core.c -+++ b/drivers/char/tpm/tpm_tis_core.c -@@ -48,6 +48,7 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, - unsigned long timeout, wait_queue_head_t *queue, - bool check_cancel) - { -+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); - unsigned long stop; - long rc; - u8 status; -@@ -80,8 +81,8 @@ again: - } - } else { - do { -- usleep_range(TPM_TIMEOUT_USECS_MIN, -- TPM_TIMEOUT_USECS_MAX); -+ usleep_range(priv->timeout_min, -+ priv->timeout_max); - status = chip->ops->status(chip); - if ((status & mask) == mask) - return 0; -@@ -945,9 +946,24 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, - chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX); - chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX); - chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX); -+ priv->timeout_min = TPM_TIMEOUT_USECS_MIN; -+ priv->timeout_max = TPM_TIMEOUT_USECS_MAX; - priv->phy_ops = phy_ops; -+ - dev_set_drvdata(&chip->dev, priv); - -+ rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); -+ if (rc < 0) -+ return rc; -+ -+ priv->manufacturer_id = vendor; -+ -+ if (priv->manufacturer_id == TPM_VID_ATML && -+ !(chip->flags & TPM_CHIP_FLAG_TPM2)) { -+ priv->timeout_min = TIS_TIMEOUT_MIN_ATML; -+ priv->timeout_max = TIS_TIMEOUT_MAX_ATML; -+ } -+ - if (is_bsw()) { - priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, - ILB_REMAP_SIZE); -@@ -978,7 +994,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, - intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | - TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; - intmask &= ~TPM_GLOBAL_INT_ENABLE; -+ -+ rc = request_locality(chip, 0); -+ if (rc < 0) { -+ rc = -ENODEV; -+ goto out_err; -+ } -+ - tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); -+ release_locality(chip, 0); - - rc = tpm_chip_start(chip); - if (rc) -@@ -988,12 +1012,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, - if (rc) - goto out_err; - -- rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); -- if (rc < 0) -- goto out_err; -- -- priv->manufacturer_id = vendor; -- - rc = tpm_tis_read8(priv, TPM_RID(0), &rid); - if (rc < 0) - goto out_err; -diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h -index b2a3c6c72882d..3be24f221e32a 100644 ---- a/drivers/char/tpm/tpm_tis_core.h -+++ b/drivers/char/tpm/tpm_tis_core.h -@@ -54,6 +54,8 @@ enum tis_defaults { - TIS_MEM_LEN = 0x5000, - TIS_SHORT_TIMEOUT = 750, /* ms */ - TIS_LONG_TIMEOUT = 2000, /* 2 sec */ -+ TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ -+ TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */ - }; - - /* Some timeout values are needed before it is known whether the chip is -@@ -98,6 +100,8 @@ struct tpm_tis_data { - wait_queue_head_t read_queue; - const struct tpm_tis_phy_ops *phy_ops; - unsigned short rng_quality; -+ unsigned int timeout_min; /* usecs */ -+ unsigned int timeout_max; /* usecs */ - }; - - struct tpm_tis_phy_ops { -diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c -index 54584b4b00d19..aaa59a00eeaef 100644 ---- a/drivers/char/tpm/tpm_tis_spi_main.c -+++ b/drivers/char/tpm/tpm_tis_spi_main.c -@@ -267,6 +267,7 @@ static const struct spi_device_id tpm_tis_spi_id[] = { - { "st33htpm-spi", (unsigned long)tpm_tis_spi_probe }, - { "slb9670", (unsigned long)tpm_tis_spi_probe }, - { "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe }, -+ { "tpm_tis-spi", (unsigned long)tpm_tis_spi_probe }, - { "cr50", (unsigned long)cr50_spi_probe }, - {} - }; -diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c -index e7f88f35c7028..dc3551796e5ed 100644 ---- a/drivers/char/xillybus/xillyusb.c -+++ b/drivers/char/xillybus/xillyusb.c -@@ -1912,6 +1912,7 @@ static int xillyusb_setup_base_eps(struct xillyusb_dev *xdev) - - dealloc: - endpoint_dealloc(xdev->msg_ep); /* Also frees FIFO mem if allocated */ -+ xdev->msg_ep = NULL; - return -ENOMEM; - } - -diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c -index a80427980bf73..04d0dd8385945 100644 ---- a/drivers/clk/at91/clk-master.c -+++ b/drivers/clk/at91/clk-master.c -@@ -280,7 +280,7 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, - - else if (pres == 3) - pres = MASTER_PRES_MAX; -- else -+ else if (pres) - pres = ffs(pres) - 1; - - spin_lock_irqsave(master->lock, flags); -@@ -309,7 +309,7 @@ static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, - spin_unlock_irqrestore(master->lock, flags); - - pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; -- if (pres == 3 && characteristics->have_div3_pres) -+ if (pres == MASTER_PRES_MAX && characteristics->have_div3_pres) - pres = 3; - else - pres = (1 << pres); -@@ -610,7 +610,7 @@ static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, - - if (div == 3) - div = MASTER_PRES_MAX; -- else -+ else if (div) - div = ffs(div) - 1; - - spin_lock_irqsave(master->lock, flags); -diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c -index 34e3ab13741ac..1f52409475e9c 100644 ---- a/drivers/clk/at91/clk-sam9x60-pll.c -+++ b/drivers/clk/at91/clk-sam9x60-pll.c -@@ -71,8 +71,8 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw, - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - struct sam9x60_frac *frac = to_sam9x60_frac(core); - -- return (parent_rate * (frac->mul + 1) + -- ((u64)parent_rate * frac->frac >> 22)); -+ return parent_rate * (frac->mul + 1) + -+ DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22)); - } - - static int sam9x60_frac_pll_prepare(struct clk_hw *hw) -diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c -index 20ee9dccee787..b40035b011d0a 100644 ---- a/drivers/clk/at91/pmc.c -+++ b/drivers/clk/at91/pmc.c -@@ -267,6 +267,11 @@ static int __init pmc_register_ops(void) - if (!np) - return -ENODEV; - -+ if (!of_device_is_available(np)) { -+ of_node_put(np); -+ return -ENODEV; -+ } -+ - pmcreg = device_node_to_regmap(np); - of_node_put(np); - if (IS_ERR(pmcreg)) -diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c -index cf8c079aa086a..019e712f90d6f 100644 ---- a/drivers/clk/at91/sama7g5.c -+++ b/drivers/clk/at91/sama7g5.c -@@ -982,16 +982,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) - } - - parent_names[0] = "cpupll_divpmcck"; -- hw = at91_clk_register_master_pres(regmap, "cpuck", 1, parent_names, -- &mck0_layout, &mck0_characteristics, -- &pmc_mck0_lock, -- CLK_SET_RATE_PARENT, 0); -- if (IS_ERR(hw)) -- goto err_free; -- -- sama7g5_pmc->chws[PMC_CPU] = hw; -- -- hw = at91_clk_register_master_div(regmap, "mck0", "cpuck", -+ hw = at91_clk_register_master_div(regmap, "mck0", "cpupll_divpmcck", - &mck0_layout, &mck0_characteristics, - &pmc_mck0_lock, 0); - if (IS_ERR(hw)) -diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c -index a254512965eb8..3667b4d731e71 100644 ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -932,8 +932,7 @@ static int bcm2835_clock_is_on(struct clk_hw *hw) - - static u32 bcm2835_clock_choose_div(struct clk_hw *hw, - unsigned long rate, -- unsigned long parent_rate, -- bool round_up) -+ unsigned long parent_rate) - { - struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - const struct bcm2835_clock_data *data = clock->data; -@@ -945,10 +944,6 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, - - rem = do_div(temp, rate); - div = temp; -- -- /* Round up and mask off the unused bits */ -- if (round_up && ((div & unused_frac_mask) != 0 || rem != 0)) -- div += unused_frac_mask + 1; - div &= ~unused_frac_mask; - - /* different clamping limits apply for a mash clock */ -@@ -1079,7 +1074,7 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, - struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - struct bcm2835_cprman *cprman = clock->cprman; - const struct bcm2835_clock_data *data = clock->data; -- u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); -+ u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate); - u32 ctl; - - spin_lock(&cprman->regs_lock); -@@ -1130,7 +1125,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, - - if (!(BIT(parent_idx) & data->set_rate_parent)) { - *prate = clk_hw_get_rate(parent); -- *div = bcm2835_clock_choose_div(hw, rate, *prate, true); -+ *div = bcm2835_clock_choose_div(hw, rate, *prate); - - *avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div); - -@@ -1216,7 +1211,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, - rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, - &div, &prate, - &avgrate); -- if (rate > best_rate && rate <= req->rate) { -+ if (abs(req->rate - rate) < abs(req->rate - best_rate)) { - best_parent = parent; - best_prate = prate; - best_rate = rate; -diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c -index bc3be5f3eae15..24dab2312bc6f 100644 ---- a/drivers/clk/clk-ast2600.c -+++ b/drivers/clk/clk-ast2600.c -@@ -51,6 +51,8 @@ static DEFINE_SPINLOCK(aspeed_g6_clk_lock); - static struct clk_hw_onecell_data *aspeed_g6_clk_data; - - static void __iomem *scu_g6_base; -+/* AST2600 revision: A0, A1, A2, etc */ -+static u8 soc_rev; - - /* - * Clocks marked with CLK_IS_CRITICAL: -@@ -191,9 +193,8 @@ static struct clk_hw *ast2600_calc_pll(const char *name, u32 val) - static struct clk_hw *ast2600_calc_apll(const char *name, u32 val) - { - unsigned int mult, div; -- u32 chip_id = readl(scu_g6_base + ASPEED_G6_SILICON_REV); - -- if (((chip_id & CHIP_REVISION_ID) >> 16) >= 2) { -+ if (soc_rev >= 2) { - if (val & BIT(24)) { - /* Pass through mode */ - mult = div = 1; -@@ -707,7 +708,7 @@ static const u32 ast2600_a1_axi_ahb200_tbl[] = { - static void __init aspeed_g6_cc(struct regmap *map) - { - struct clk_hw *hw; -- u32 val, div, divbits, chip_id, axi_div, ahb_div; -+ u32 val, div, divbits, axi_div, ahb_div; - - clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, 25000000); - -@@ -738,8 +739,7 @@ static void __init aspeed_g6_cc(struct regmap *map) - axi_div = 2; - - divbits = (val >> 11) & 0x3; -- regmap_read(map, ASPEED_G6_SILICON_REV, &chip_id); -- if (chip_id & BIT(16)) { -+ if (soc_rev >= 1) { - if (!divbits) { - ahb_div = ast2600_a1_axi_ahb200_tbl[(val >> 8) & 0x3]; - if (val & BIT(16)) -@@ -784,6 +784,8 @@ static void __init aspeed_g6_cc_init(struct device_node *np) - if (!scu_g6_base) - return; - -+ soc_rev = (readl(scu_g6_base + ASPEED_G6_SILICON_REV) & CHIP_REVISION_ID) >> 16; -+ - aspeed_g6_clk_data = kzalloc(struct_size(aspeed_g6_clk_data, hws, - ASPEED_G6_NUM_CLKS), GFP_KERNEL); - if (!aspeed_g6_clk_data) -diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c -index e6d6599d310a1..fad78a22218e8 100644 ---- a/drivers/clk/clk-bm1880.c -+++ b/drivers/clk/clk-bm1880.c -@@ -522,14 +522,6 @@ static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_cl - return hw; - } - --static void bm1880_clk_unregister_pll(struct clk_hw *hw) --{ -- struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw); -- -- clk_hw_unregister(hw); -- kfree(pll_hw); --} -- - static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks, - int num_clks, - struct bm1880_clock_data *data) -@@ -555,7 +547,7 @@ static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks, - - err_clk: - while (i--) -- bm1880_clk_unregister_pll(data->hw_data.hws[clks[i].pll.id]); -+ clk_hw_unregister(data->hw_data.hws[clks[i].pll.id]); - - return PTR_ERR(hw); - } -@@ -695,14 +687,6 @@ static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_cl - return hw; - } - --static void bm1880_clk_unregister_div(struct clk_hw *hw) --{ -- struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); -- -- clk_hw_unregister(hw); -- kfree(div_hw); --} -- - static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks, - int num_clks, - struct bm1880_clock_data *data) -@@ -729,7 +713,7 @@ static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks, - - err_clk: - while (i--) -- bm1880_clk_unregister_div(data->hw_data.hws[clks[i].div.id]); -+ clk_hw_unregister(data->hw_data.hws[clks[i].div.id]); - - return PTR_ERR(hw); - } -diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c -index 57ae183982d8c..f7b41366666e5 100644 ---- a/drivers/clk/clk-si5341.c -+++ b/drivers/clk/clk-si5341.c -@@ -1740,7 +1740,7 @@ static int si5341_probe(struct i2c_client *client, - clk_prepare(data->clk[i].hw.clk); - } - -- err = of_clk_add_hw_provider(client->dev.of_node, of_clk_si5341_get, -+ err = devm_of_clk_add_hw_provider(&client->dev, of_clk_si5341_get, - data); - if (err) { - dev_err(&client->dev, "unable to add clk provider\n"); -diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c -index af46176ad0539..473dfe632cc57 100644 ---- a/drivers/clk/clk-stm32f4.c -+++ b/drivers/clk/clk-stm32f4.c -@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = { - { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, -- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, - }; - - static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { -@@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { - { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, -- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, - }; - - static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { -@@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { - { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, -- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, - }; - - static const struct stm32f4_gate_data stm32f769_gates[] __initconst = { -@@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = { - { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, -- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" }, - }; - -diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c -index 65508eb89ec99..ac11cefc31911 100644 ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -3340,6 +3340,24 @@ static int __init clk_debug_init(void) - { - struct clk_core *core; - -+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS -+ pr_warn("\n"); -+ pr_warn("********************************************************************\n"); -+ pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); -+ pr_warn("** **\n"); -+ pr_warn("** WRITEABLE clk DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); -+ pr_warn("** **\n"); -+ pr_warn("** This means that this kernel is built to expose clk operations **\n"); -+ pr_warn("** such as parent or rate setting, enabling, disabling, etc. **\n"); -+ pr_warn("** to userspace, which may compromise security on your system. **\n"); -+ pr_warn("** **\n"); -+ pr_warn("** If you see this message and you are not debugging the **\n"); -+ pr_warn("** kernel, report this immediately to your vendor! **\n"); -+ pr_warn("** **\n"); -+ pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); -+ pr_warn("********************************************************************\n"); -+#endif -+ - rootdir = debugfs_create_dir("clk", NULL); - - debugfs_create_file("clk_summary", 0444, rootdir, &all_lists, -@@ -3415,6 +3433,14 @@ static int __clk_core_init(struct clk_core *core) - - clk_prepare_lock(); - -+ /* -+ * Set hw->core after grabbing the prepare_lock to synchronize with -+ * callers of clk_core_fill_parent_index() where we treat hw->core -+ * being NULL as the clk not being registered yet. This is crucial so -+ * that clks aren't parented until their parent is fully registered. -+ */ -+ core->hw->core = core; -+ - ret = clk_pm_runtime_get(core); - if (ret) - goto unlock; -@@ -3579,8 +3605,10 @@ static int __clk_core_init(struct clk_core *core) - out: - clk_pm_runtime_put(core); - unlock: -- if (ret) -+ if (ret) { - hlist_del_init(&core->child_node); -+ core->hw->core = NULL; -+ } - - clk_prepare_unlock(); - -@@ -3844,7 +3872,6 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) - core->num_parents = init->num_parents; - core->min_rate = 0; - core->max_rate = ULONG_MAX; -- hw->core = core; - - ret = clk_core_populate_parent_map(core, init); - if (ret) -@@ -3862,7 +3889,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) - goto fail_create_clk; - } - -- clk_core_link_consumer(hw->core, hw->clk); -+ clk_core_link_consumer(core, hw->clk); - - ret = __clk_core_init(core); - if (!ret) -diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c -index 5dbb6a9377324..206e4c43f68f8 100644 ---- a/drivers/clk/imx/clk-imx6ul.c -+++ b/drivers/clk/imx/clk-imx6ul.c -@@ -161,7 +161,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) - hws[IMX6UL_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); - hws[IMX6UL_PLL6_BYPASS] = imx_clk_hw_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); - hws[IMX6UL_PLL7_BYPASS] = imx_clk_hw_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); -- hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT); - - /* Do not bypass PLLs initially */ - clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk); -@@ -270,6 +269,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) - hws[IMX6UL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); - hws[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_hw_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT); - hws[IMX6UL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); -+ hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); - - hws[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); - hws[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); -diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c -index c55577604e16a..021355a247081 100644 ---- a/drivers/clk/imx/clk-imx8mn.c -+++ b/drivers/clk/imx/clk-imx8mn.c -@@ -277,9 +277,9 @@ static const char * const imx8mn_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audi - - static const char * const imx8mn_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; - --static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", -- "sys_pll1_200m", "audio_pll2_out", "vpu_pll", -- "sys_pll1_80m", }; -+static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", -+ "sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m", -+ "dummy", "sys_pll1_80m", }; - static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", - "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", - "video_pll1_out", "osc_32k", }; -diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c -index d3e905cf867d7..b23758083ce52 100644 ---- a/drivers/clk/imx/clk-imx8qxp-lpcg.c -+++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c -@@ -370,7 +370,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = { - .probe = imx8qxp_lpcg_clk_probe, - }; - --builtin_platform_driver(imx8qxp_lpcg_clk_driver); -+module_platform_driver(imx8qxp_lpcg_clk_driver); - - MODULE_AUTHOR("Aisheng Dong "); - MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver"); -diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c -index c53a688d8ccca..40a2efb1329be 100644 ---- a/drivers/clk/imx/clk-imx8qxp.c -+++ b/drivers/clk/imx/clk-imx8qxp.c -@@ -308,7 +308,7 @@ static struct platform_driver imx8qxp_clk_driver = { - }, - .probe = imx8qxp_clk_probe, - }; --builtin_platform_driver(imx8qxp_clk_driver); -+module_platform_driver(imx8qxp_clk_driver); - - MODULE_AUTHOR("Aisheng Dong "); - MODULE_DESCRIPTION("NXP i.MX8QXP clock driver"); -diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c -index 266c7595d3302..af31633a8862e 100644 ---- a/drivers/clk/ingenic/cgu.c -+++ b/drivers/clk/ingenic/cgu.c -@@ -453,15 +453,15 @@ ingenic_clk_calc_div(struct clk_hw *hw, - } - - /* Impose hardware constraints */ -- div = min_t(unsigned, div, 1 << clk_info->div.bits); -- div = max_t(unsigned, div, 1); -+ div = clamp_t(unsigned int, div, clk_info->div.div, -+ clk_info->div.div << clk_info->div.bits); - - /* - * If the divider value itself must be divided before being written to - * the divider register, we must ensure we don't have any bits set that - * would be lost as a result of doing so. - */ -- div /= clk_info->div.div; -+ div = DIV_ROUND_UP(div, clk_info->div.div); - div *= clk_info->div.div; - - return div; -diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c -index 5154b0cf8ad6c..66ff141da0a42 100644 ---- a/drivers/clk/ingenic/jz4725b-cgu.c -+++ b/drivers/clk/ingenic/jz4725b-cgu.c -@@ -139,11 +139,10 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { - }, - - [JZ4725B_CLK_I2S] = { -- "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, -+ "i2s", CGU_CLK_MUX | CGU_CLK_DIV, - .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 }, - .mux = { CGU_REG_CPCCR, 31, 1 }, - .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, -- .gate = { CGU_REG_CLKGR, 6 }, - }, - - [JZ4725B_CLK_SPI] = { -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index d6eed760327d0..608e0e8ca49a8 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = { - }; - - static struct clk_regmap gxbb_mpll0_div = { -+ .data = &(struct meson_clk_mpll_data){ -+ .sdm = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 0, -+ .width = 14, -+ }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL, -+ .shift = 25, -+ .width = 1, -+ }, -+ .n2 = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 16, -+ .width = 9, -+ }, -+ .lock = &meson_clk_lock, -+ }, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mpll0_div", -+ .ops = &meson_clk_mpll_ops, -+ .parent_hws = (const struct clk_hw *[]) { -+ &gxbb_mpll_prediv.hw -+ }, -+ .num_parents = 1, -+ }, -+}; -+ -+static struct clk_regmap gxl_mpll0_div = { - .data = &(struct meson_clk_mpll_data){ - .sdm = { - .reg_off = HHI_MPLL_CNTL7, -@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = { - .hw.init = &(struct clk_init_data){ - .name = "mpll0", - .ops = &clk_regmap_gate_ops, -- .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw }, -+ .parent_data = &(const struct clk_parent_data) { -+ /* -+ * Note: -+ * GXL and GXBB have different SDM_EN registers. We -+ * fallback to the global naming string mechanism so -+ * mpll0_div picks up the appropriate one. -+ */ -+ .name = "mpll0_div", -+ .index = -1, -+ }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { - [CLKID_VAPB_1] = &gxbb_vapb_1.hw, - [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, - [CLKID_VAPB] = &gxbb_vapb.hw, -- [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw, -+ [CLKID_MPLL0_DIV] = &gxl_mpll0_div.hw, - [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw, - [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw, - [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw, -@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = { - &gxbb_mpll0, - &gxbb_mpll1, - &gxbb_mpll2, -- &gxbb_mpll0_div, -+ &gxl_mpll0_div, - &gxbb_mpll1_div, - &gxbb_mpll2_div, - &gxbb_cts_amclk_div, -diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c -index 08ba59ec3fb17..71bdd7c3ff034 100644 ---- a/drivers/clk/mvebu/ap-cpu-clk.c -+++ b/drivers/clk/mvebu/ap-cpu-clk.c -@@ -256,12 +256,15 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) - int cpu, err; - - err = of_property_read_u32(dn, "reg", &cpu); -- if (WARN_ON(err)) -+ if (WARN_ON(err)) { -+ of_node_put(dn); - return err; -+ } - - /* If cpu2 or cpu3 is enabled */ - if (cpu & APN806_CLUSTER_NUM_MASK) { - nclusters = 2; -+ of_node_put(dn); - break; - } - } -@@ -288,8 +291,10 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) - int cpu, err; - - err = of_property_read_u32(dn, "reg", &cpu); -- if (WARN_ON(err)) -+ if (WARN_ON(err)) { -+ of_node_put(dn); - return err; -+ } - - cluster_index = cpu & APN806_CLUSTER_NUM_MASK; - cluster_index >>= APN806_CLUSTER_NUM_OFFSET; -@@ -301,6 +306,7 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) - parent = of_clk_get(np, cluster_index); - if (IS_ERR(parent)) { - dev_err(dev, "Could not get the clock parent\n"); -+ of_node_put(dn); - return -EINVAL; - } - parent_name = __clk_get_name(parent); -@@ -319,8 +325,10 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) - init.parent_names = &parent_name; - - ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw); -- if (ret) -+ if (ret) { -+ of_node_put(dn); - return ret; -+ } - ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw; - } - -diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c -index eaedcceb766f9..8f65b9bdafce4 100644 ---- a/drivers/clk/qcom/clk-alpha-pll.c -+++ b/drivers/clk/qcom/clk-alpha-pll.c -@@ -1429,6 +1429,15 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops); - void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, - const struct alpha_pll_config *config) - { -+ /* -+ * If the bootloader left the PLL enabled it's likely that there are -+ * RCGs that will lock up if we disable the PLL below. -+ */ -+ if (trion_pll_is_enabled(pll, regmap)) { -+ pr_debug("Trion PLL is already enabled, skipping configuration\n"); -+ return; -+ } -+ - clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); - regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); - clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); -diff --git a/drivers/clk/qcom/clk-regmap-mux.c b/drivers/clk/qcom/clk-regmap-mux.c -index b2d00b4519634..45d9cca28064f 100644 ---- a/drivers/clk/qcom/clk-regmap-mux.c -+++ b/drivers/clk/qcom/clk-regmap-mux.c -@@ -28,7 +28,7 @@ static u8 mux_get_parent(struct clk_hw *hw) - val &= mask; - - if (mux->parent_map) -- return qcom_find_src_index(hw, mux->parent_map, val); -+ return qcom_find_cfg_index(hw, mux->parent_map, val); - - return val; - } -diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c -index 60d2a78d13950..2af04fc4abfa9 100644 ---- a/drivers/clk/qcom/common.c -+++ b/drivers/clk/qcom/common.c -@@ -69,6 +69,18 @@ int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src) - } - EXPORT_SYMBOL_GPL(qcom_find_src_index); - -+int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, u8 cfg) -+{ -+ int i, num_parents = clk_hw_get_num_parents(hw); -+ -+ for (i = 0; i < num_parents; i++) -+ if (cfg == map[i].cfg) -+ return i; -+ -+ return -ENOENT; -+} -+EXPORT_SYMBOL_GPL(qcom_find_cfg_index); -+ - struct regmap * - qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc) - { -diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h -index bb39a7e106d8a..9c8f7b798d9fc 100644 ---- a/drivers/clk/qcom/common.h -+++ b/drivers/clk/qcom/common.h -@@ -49,6 +49,8 @@ extern void - qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count); - extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, - u8 src); -+extern int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, -+ u8 cfg); - - extern int qcom_cc_register_board_clk(struct device *dev, const char *path, - const char *name, unsigned long rate); -diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c -index 3c3a7ff045621..9b1674b28d45d 100644 ---- a/drivers/clk/qcom/gcc-msm8996.c -+++ b/drivers/clk/qcom/gcc-msm8996.c -@@ -2937,20 +2937,6 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { - }, - }; - --static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { -- .halt_reg = 0x82014, -- .clkr = { -- .enable_reg = 0x82014, -- .enable_mask = BIT(0), -- .hw.init = &(struct clk_init_data){ -- .name = "gcc_aggre1_pnoc_ahb_clk", -- .parent_names = (const char *[]){ "periph_noc_clk_src" }, -- .num_parents = 1, -- .ops = &clk_branch2_ops, -- }, -- }, --}; -- - static struct clk_branch gcc_aggre2_ufs_axi_clk = { - .halt_reg = 0x83014, - .clkr = { -@@ -3474,7 +3460,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { - [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, - [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, - [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, -- [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, - [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, - [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, - [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, -diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c -index 6cefcdc869905..ce7c5ba2b9b7a 100644 ---- a/drivers/clk/qcom/gcc-sc7280.c -+++ b/drivers/clk/qcom/gcc-sc7280.c -@@ -2998,7 +2998,7 @@ static struct clk_branch gcc_cfg_noc_lpass_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_cfg_noc_lpass_clk", -- .ops = &clk_branch2_ops, -+ .ops = &clk_branch2_aon_ops, - }, - }, - }; -diff --git a/drivers/clk/qcom/gcc-sm6125.c b/drivers/clk/qcom/gcc-sm6125.c -index 543cfab7561f9..431b55bb0d2f7 100644 ---- a/drivers/clk/qcom/gcc-sm6125.c -+++ b/drivers/clk/qcom/gcc-sm6125.c -@@ -1121,7 +1121,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { - .name = "gcc_sdcc1_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), -- .ops = &clk_rcg2_ops, -+ .ops = &clk_rcg2_floor_ops, - }, - }; - -@@ -1143,7 +1143,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { - .name = "gcc_sdcc1_ice_core_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), -- .ops = &clk_rcg2_floor_ops, -+ .ops = &clk_rcg2_ops, - }, - }; - -diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c -index 761922ea5db76..1c92e73cd2b8c 100644 ---- a/drivers/clk/renesas/rzg2l-cpg.c -+++ b/drivers/clk/renesas/rzg2l-cpg.c -@@ -638,10 +638,16 @@ static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device - pm_clk_destroy(dev); - } - -+static void rzg2l_cpg_genpd_remove(void *data) -+{ -+ pm_genpd_remove(data); -+} -+ - static int __init rzg2l_cpg_add_clk_domain(struct device *dev) - { - struct device_node *np = dev->of_node; - struct generic_pm_domain *genpd; -+ int ret; - - genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); - if (!genpd) -@@ -652,10 +658,15 @@ static int __init rzg2l_cpg_add_clk_domain(struct device *dev) - GENPD_FLAG_ACTIVE_WAKEUP; - genpd->attach_dev = rzg2l_cpg_attach_dev; - genpd->detach_dev = rzg2l_cpg_detach_dev; -- pm_genpd_init(genpd, &pm_domain_always_on_gov, false); -+ ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false); -+ if (ret) -+ return ret; - -- of_genpd_add_provider_simple(np, genpd); -- return 0; -+ ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, genpd); -+ if (ret) -+ return ret; -+ -+ return of_genpd_add_provider_simple(np, genpd); - } - - static int __init rzg2l_cpg_probe(struct platform_device *pdev) -diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c -index f32366d9336e7..bd9a8782fec3d 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c -+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c -@@ -1464,7 +1464,7 @@ static void __init sun4i_ccu_init(struct device_node *node, - val &= ~GENMASK(7, 6); - writel(val | (2 << 6), reg + SUN4I_AHB_REG); - -- sunxi_ccu_probe(node, reg, desc); -+ of_sunxi_ccu_probe(node, reg, desc); - } - - static void __init sun4i_a10_ccu_setup(struct device_node *node) -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c -index a56142b909938..6f2a589705561 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c -@@ -196,7 +196,7 @@ static int sun50i_a100_r_ccu_probe(struct platform_device *pdev) - if (IS_ERR(reg)) - return PTR_ERR(reg); - -- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc); -+ return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_r_ccu_desc); - } - - static const struct of_device_id sun50i_a100_r_ccu_ids[] = { -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c -index 81b48c73d389f..913bb08e6dee8 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c -@@ -1247,7 +1247,7 @@ static int sun50i_a100_ccu_probe(struct platform_device *pdev) - writel(val, reg + sun50i_a100_usb2_clk_regs[i]); - } - -- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_ccu_desc); -+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_ccu_desc); - if (ret) - return ret; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -index 149cfde817cba..54f25c624f020 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -@@ -955,7 +955,7 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev) - - writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG); - -- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); -+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc); - if (ret) - return ret; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -index f8909a7ed5539..f30d7eb5424d8 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c -@@ -232,7 +232,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, - return; - } - -- sunxi_ccu_probe(node, reg, desc); -+ of_sunxi_ccu_probe(node, reg, desc); - } - - static void __init sun50i_h6_r_ccu_setup(struct device_node *node) -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c -index bff446b782907..c0800da2fa3d7 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c -@@ -1240,7 +1240,7 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev) - val |= BIT(24); - writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG); - -- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); -+ return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); - } - - static const struct of_device_id sun50i_h6_ccu_ids[] = { -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -index 225307305880e..22eb18079a154 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c -@@ -1141,9 +1141,7 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node) - val |= BIT(24); - writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG); - -- i = sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); -- if (i) -- pr_err("%pOF: probing clocks fails: %d\n", node, i); -+ of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); - } - - CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu", -diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c -index b78e9b507c1c6..1f4bc0e773a7e 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun5i.c -+++ b/drivers/clk/sunxi-ng/ccu-sun5i.c -@@ -1012,7 +1012,7 @@ static void __init sun5i_ccu_init(struct device_node *node, - val &= ~GENMASK(7, 6); - writel(val | (2 << 6), reg + SUN5I_AHB_REG); - -- sunxi_ccu_probe(node, reg, desc); -+ of_sunxi_ccu_probe(node, reg, desc); - } - - static void __init sun5i_a10s_ccu_setup(struct device_node *node) -diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c -index 9b40d53266a3f..3df5c0b415804 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c -+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c -@@ -1257,7 +1257,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node) - val |= 0x3 << 12; - writel(val, reg + SUN6I_A31_AHB1_REG); - -- sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); -+ of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); - - ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, - &sun6i_a31_cpu_nb); -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c -index 103aa504f6c8a..577bb235d6584 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c -@@ -745,7 +745,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node) - val &= ~BIT(16); - writel(val, reg + SUN8I_A23_PLL_MIPI_REG); - -- sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); -+ of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); - } - CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu", - sun8i_a23_ccu_setup); -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c -index 91838cd110377..8f65cd03f5acc 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c -@@ -805,7 +805,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node) - val &= ~BIT(16); - writel(val, reg + SUN8I_A33_PLL_MIPI_REG); - -- sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); -+ of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); - - /* Gate then ungate PLL CPU after any rate changes */ - ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb); -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c -index 2b434521c5ccf..c2ddcd2ddab4e 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c -@@ -906,7 +906,7 @@ static int sun8i_a83t_ccu_probe(struct platform_device *pdev) - sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG); - sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG); - -- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc); -+ return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a83t_ccu_desc); - } - - static const struct of_device_id sun8i_a83t_ccu_ids[] = { -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c -index 524f33275bc73..4b94b6041b271 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c -@@ -342,7 +342,7 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev) - goto err_disable_mod_clk; - } - -- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc); -+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc); - if (ret) - goto err_assert_reset; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -index 7e629a4493afd..d2fc2903787d8 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -@@ -1154,7 +1154,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, - val &= ~GENMASK(19, 16); - writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG); - -- sunxi_ccu_probe(node, reg, desc); -+ of_sunxi_ccu_probe(node, reg, desc); - - /* Gate then ungate PLL CPU after any rate changes */ - ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb); -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c -index 4c8c491b87c27..9e754d1f754a1 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c -@@ -265,7 +265,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, - return; - } - -- sunxi_ccu_probe(node, reg, desc); -+ of_sunxi_ccu_probe(node, reg, desc); - } - - static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c -index 84153418453f4..002e0c3a04dbe 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c -@@ -1346,7 +1346,7 @@ static int sun8i_r40_ccu_probe(struct platform_device *pdev) - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - -- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_r40_ccu_desc); -+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_r40_ccu_desc); - if (ret) - return ret; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c -index f49724a22540e..ce150f83ab54e 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c -@@ -822,7 +822,7 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node, - val &= ~GENMASK(19, 16); - writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG); - -- sunxi_ccu_probe(node, reg, ccu_desc); -+ of_sunxi_ccu_probe(node, reg, ccu_desc); - } - - static void __init sun8i_v3s_ccu_setup(struct device_node *node) -diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c -index 6616e8114f623..261e64416f26a 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c -+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c -@@ -246,8 +246,7 @@ static int sun9i_a80_de_clk_probe(struct platform_device *pdev) - goto err_disable_clk; - } - -- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, -- &sun9i_a80_de_clk_desc); -+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_de_clk_desc); - if (ret) - goto err_assert_reset; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c -index 4b4a507d04edf..596243b3e0fa3 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c -+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c -@@ -117,8 +117,7 @@ static int sun9i_a80_usb_clk_probe(struct platform_device *pdev) - return ret; - } - -- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, -- &sun9i_a80_usb_clk_desc); -+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_usb_clk_desc); - if (ret) - goto err_disable_clk; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c -index ef29582676f6e..97aaed0e68500 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c -+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c -@@ -1231,7 +1231,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev) - sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C0CPUX_REG); - sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C1CPUX_REG); - -- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc); -+ return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_ccu_desc); - } - - static const struct of_device_id sun9i_a80_ccu_ids[] = { -diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c -index 7ecc3a5a5b5e1..61ad7ee91c114 100644 ---- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c -+++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c -@@ -538,7 +538,7 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node) - val &= ~GENMASK(19, 16); - writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG); - -- sunxi_ccu_probe(node, reg, &suniv_ccu_desc); -+ of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc); - - /* Gate then ungate PLL CPU after any rate changes */ - ccu_pll_notifier_register(&suniv_pll_cpu_nb); -diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c -index 2e20e650b6c01..88cb569e58358 100644 ---- a/drivers/clk/sunxi-ng/ccu_common.c -+++ b/drivers/clk/sunxi-ng/ccu_common.c -@@ -7,6 +7,7 @@ - - #include - #include -+#include - #include - #include - -@@ -14,6 +15,11 @@ - #include "ccu_gate.h" - #include "ccu_reset.h" - -+struct sunxi_ccu { -+ const struct sunxi_ccu_desc *desc; -+ struct ccu_reset reset; -+}; -+ - static DEFINE_SPINLOCK(ccu_lock); - - void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) -@@ -79,12 +85,15 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb) - &pll_nb->clk_nb); - } - --int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, -- const struct sunxi_ccu_desc *desc) -+static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, -+ struct device_node *node, void __iomem *reg, -+ const struct sunxi_ccu_desc *desc) - { - struct ccu_reset *reset; - int i, ret; - -+ ccu->desc = desc; -+ - for (i = 0; i < desc->num_ccu_clks; i++) { - struct ccu_common *cclk = desc->ccu_clks[i]; - -@@ -103,7 +112,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, - continue; - - name = hw->init->name; -- ret = of_clk_hw_register(node, hw); -+ if (dev) -+ ret = clk_hw_register(dev, hw); -+ else -+ ret = of_clk_hw_register(node, hw); - if (ret) { - pr_err("Couldn't register clock %d - %s\n", i, name); - goto err_clk_unreg; -@@ -115,15 +127,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, - if (ret) - goto err_clk_unreg; - -- reset = kzalloc(sizeof(*reset), GFP_KERNEL); -- if (!reset) { -- ret = -ENOMEM; -- goto err_alloc_reset; -- } -- -+ reset = &ccu->reset; - reset->rcdev.of_node = node; - reset->rcdev.ops = &ccu_reset_ops; -- reset->rcdev.owner = THIS_MODULE; -+ reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE; - reset->rcdev.nr_resets = desc->num_resets; - reset->base = reg; - reset->lock = &ccu_lock; -@@ -131,13 +138,11 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, - - ret = reset_controller_register(&reset->rcdev); - if (ret) -- goto err_of_clk_unreg; -+ goto err_del_provider; - - return 0; - --err_of_clk_unreg: -- kfree(reset); --err_alloc_reset: -+err_del_provider: - of_clk_del_provider(node); - err_clk_unreg: - while (--i >= 0) { -@@ -149,3 +154,59 @@ err_clk_unreg: - } - return ret; - } -+ -+static void devm_sunxi_ccu_release(struct device *dev, void *res) -+{ -+ struct sunxi_ccu *ccu = res; -+ const struct sunxi_ccu_desc *desc = ccu->desc; -+ int i; -+ -+ reset_controller_unregister(&ccu->reset.rcdev); -+ of_clk_del_provider(dev->of_node); -+ -+ for (i = 0; i < desc->hw_clks->num; i++) { -+ struct clk_hw *hw = desc->hw_clks->hws[i]; -+ -+ if (!hw) -+ continue; -+ clk_hw_unregister(hw); -+ } -+} -+ -+int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, -+ const struct sunxi_ccu_desc *desc) -+{ -+ struct sunxi_ccu *ccu; -+ int ret; -+ -+ ccu = devres_alloc(devm_sunxi_ccu_release, sizeof(*ccu), GFP_KERNEL); -+ if (!ccu) -+ return -ENOMEM; -+ -+ ret = sunxi_ccu_probe(ccu, dev, dev->of_node, reg, desc); -+ if (ret) { -+ devres_free(ccu); -+ return ret; -+ } -+ -+ devres_add(dev, ccu); -+ -+ return 0; -+} -+ -+void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, -+ const struct sunxi_ccu_desc *desc) -+{ -+ struct sunxi_ccu *ccu; -+ int ret; -+ -+ ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); -+ if (!ccu) -+ return; -+ -+ ret = sunxi_ccu_probe(ccu, NULL, node, reg, desc); -+ if (ret) { -+ pr_err("%pOF: probing clocks failed: %d\n", node, ret); -+ kfree(ccu); -+ } -+} -diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h -index 04e7a12200a21..98a1834b58bb4 100644 ---- a/drivers/clk/sunxi-ng/ccu_common.h -+++ b/drivers/clk/sunxi-ng/ccu_common.h -@@ -63,7 +63,9 @@ struct ccu_pll_nb { - - int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb); - --int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, -- const struct sunxi_ccu_desc *desc); -+int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, -+ const struct sunxi_ccu_desc *desc); -+void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, -+ const struct sunxi_ccu_desc *desc); - - #endif /* _COMMON_H_ */ -diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig -index 0f5e3983951a8..08f8cb944a2ac 100644 ---- a/drivers/clocksource/Kconfig -+++ b/drivers/clocksource/Kconfig -@@ -24,6 +24,7 @@ config I8253_LOCK - - config OMAP_DM_TIMER - bool -+ select TIMER_OF - - config CLKBLD_I8253 - def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK -diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c -index 3819ef5b70989..3245eb0c602d2 100644 ---- a/drivers/clocksource/dw_apb_timer_of.c -+++ b/drivers/clocksource/dw_apb_timer_of.c -@@ -47,7 +47,7 @@ static int __init timer_get_base_and_rate(struct device_node *np, - pr_warn("pclk for %pOFn is present, but could not be activated\n", - np); - -- if (!of_property_read_u32(np, "clock-freq", rate) && -+ if (!of_property_read_u32(np, "clock-freq", rate) || - !of_property_read_u32(np, "clock-frequency", rate)) - return 0; - -diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c -index b6f97960d8ee0..1fccb457fcc54 100644 ---- a/drivers/clocksource/timer-ti-dm-systimer.c -+++ b/drivers/clocksource/timer-ti-dm-systimer.c -@@ -241,8 +241,7 @@ static void __init dmtimer_systimer_assign_alwon(void) - bool quirk_unreliable_oscillator = false; - - /* Quirk unreliable 32 KiHz oscillator with incomplete dts */ -- if (of_machine_is_compatible("ti,omap3-beagle") || -- of_machine_is_compatible("timll,omap3-devkit8000")) { -+ if (of_machine_is_compatible("ti,omap3-beagle-ab4")) { - quirk_unreliable_oscillator = true; - counter_32k = -ENODEV; - } -diff --git a/drivers/comedi/drivers/dt9812.c b/drivers/comedi/drivers/dt9812.c -index 634f57730c1e0..704b04d2980d3 100644 ---- a/drivers/comedi/drivers/dt9812.c -+++ b/drivers/comedi/drivers/dt9812.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - - #include "../comedi_usb.h" -@@ -237,22 +238,42 @@ static int dt9812_read_info(struct comedi_device *dev, - { - struct usb_device *usb = comedi_to_usb_dev(dev); - struct dt9812_private *devpriv = dev->private; -- struct dt9812_usb_cmd cmd; -+ struct dt9812_usb_cmd *cmd; -+ size_t tbuf_size; - int count, ret; -+ void *tbuf; - -- cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA); -- cmd.u.flash_data_info.address = -+ tbuf_size = max(sizeof(*cmd), buf_size); -+ -+ tbuf = kzalloc(tbuf_size, GFP_KERNEL); -+ if (!tbuf) -+ return -ENOMEM; -+ -+ cmd = tbuf; -+ -+ cmd->cmd = cpu_to_le32(DT9812_R_FLASH_DATA); -+ cmd->u.flash_data_info.address = - cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset); -- cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size); -+ cmd->u.flash_data_info.numbytes = cpu_to_le16(buf_size); - - /* DT9812 only responds to 32 byte writes!! */ - ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), -- &cmd, 32, &count, DT9812_USB_TIMEOUT); -+ cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); - if (ret) -- return ret; -+ goto out; -+ -+ ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), -+ tbuf, buf_size, &count, DT9812_USB_TIMEOUT); -+ if (!ret) { -+ if (count == buf_size) -+ memcpy(buf, tbuf, buf_size); -+ else -+ ret = -EREMOTEIO; -+ } -+out: -+ kfree(tbuf); - -- return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), -- buf, buf_size, &count, DT9812_USB_TIMEOUT); -+ return ret; - } - - static int dt9812_read_multiple_registers(struct comedi_device *dev, -@@ -261,22 +282,42 @@ static int dt9812_read_multiple_registers(struct comedi_device *dev, - { - struct usb_device *usb = comedi_to_usb_dev(dev); - struct dt9812_private *devpriv = dev->private; -- struct dt9812_usb_cmd cmd; -+ struct dt9812_usb_cmd *cmd; - int i, count, ret; -+ size_t buf_size; -+ void *buf; - -- cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG); -- cmd.u.read_multi_info.count = reg_count; -+ buf_size = max_t(size_t, sizeof(*cmd), reg_count); -+ -+ buf = kzalloc(buf_size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ cmd = buf; -+ -+ cmd->cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG); -+ cmd->u.read_multi_info.count = reg_count; - for (i = 0; i < reg_count; i++) -- cmd.u.read_multi_info.address[i] = address[i]; -+ cmd->u.read_multi_info.address[i] = address[i]; - - /* DT9812 only responds to 32 byte writes!! */ - ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), -- &cmd, 32, &count, DT9812_USB_TIMEOUT); -+ cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); - if (ret) -- return ret; -+ goto out; -+ -+ ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), -+ buf, reg_count, &count, DT9812_USB_TIMEOUT); -+ if (!ret) { -+ if (count == reg_count) -+ memcpy(value, buf, reg_count); -+ else -+ ret = -EREMOTEIO; -+ } -+out: -+ kfree(buf); - -- return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), -- value, reg_count, &count, DT9812_USB_TIMEOUT); -+ return ret; - } - - static int dt9812_write_multiple_registers(struct comedi_device *dev, -@@ -285,19 +326,27 @@ static int dt9812_write_multiple_registers(struct comedi_device *dev, - { - struct usb_device *usb = comedi_to_usb_dev(dev); - struct dt9812_private *devpriv = dev->private; -- struct dt9812_usb_cmd cmd; -+ struct dt9812_usb_cmd *cmd; - int i, count; -+ int ret; -+ -+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); -+ if (!cmd) -+ return -ENOMEM; - -- cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG); -- cmd.u.read_multi_info.count = reg_count; -+ cmd->cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG); -+ cmd->u.read_multi_info.count = reg_count; - for (i = 0; i < reg_count; i++) { -- cmd.u.write_multi_info.write[i].address = address[i]; -- cmd.u.write_multi_info.write[i].value = value[i]; -+ cmd->u.write_multi_info.write[i].address = address[i]; -+ cmd->u.write_multi_info.write[i].value = value[i]; - } - - /* DT9812 only responds to 32 byte writes!! */ -- return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), -- &cmd, 32, &count, DT9812_USB_TIMEOUT); -+ ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), -+ cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); -+ kfree(cmd); -+ -+ return ret; - } - - static int dt9812_rmw_multiple_registers(struct comedi_device *dev, -@@ -306,17 +355,25 @@ static int dt9812_rmw_multiple_registers(struct comedi_device *dev, - { - struct usb_device *usb = comedi_to_usb_dev(dev); - struct dt9812_private *devpriv = dev->private; -- struct dt9812_usb_cmd cmd; -+ struct dt9812_usb_cmd *cmd; - int i, count; -+ int ret; -+ -+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); -+ if (!cmd) -+ return -ENOMEM; - -- cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG); -- cmd.u.rmw_multi_info.count = reg_count; -+ cmd->cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG); -+ cmd->u.rmw_multi_info.count = reg_count; - for (i = 0; i < reg_count; i++) -- cmd.u.rmw_multi_info.rmw[i] = rmw[i]; -+ cmd->u.rmw_multi_info.rmw[i] = rmw[i]; - - /* DT9812 only responds to 32 byte writes!! */ -- return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), -- &cmd, 32, &count, DT9812_USB_TIMEOUT); -+ ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), -+ cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); -+ kfree(cmd); -+ -+ return ret; - } - - static int dt9812_digital_in(struct comedi_device *dev, u8 *bits) -diff --git a/drivers/comedi/drivers/ni_usb6501.c b/drivers/comedi/drivers/ni_usb6501.c -index 5b6d9d783b2f7..c42987b74b1dc 100644 ---- a/drivers/comedi/drivers/ni_usb6501.c -+++ b/drivers/comedi/drivers/ni_usb6501.c -@@ -144,6 +144,10 @@ static const u8 READ_COUNTER_RESPONSE[] = {0x00, 0x01, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00}; - -+/* Largest supported packets */ -+static const size_t TX_MAX_SIZE = sizeof(SET_PORT_DIR_REQUEST); -+static const size_t RX_MAX_SIZE = sizeof(READ_PORT_RESPONSE); -+ - enum commands { - READ_PORT, - WRITE_PORT, -@@ -501,6 +505,12 @@ static int ni6501_find_endpoints(struct comedi_device *dev) - if (!devpriv->ep_rx || !devpriv->ep_tx) - return -ENODEV; - -+ if (usb_endpoint_maxp(devpriv->ep_rx) < RX_MAX_SIZE) -+ return -ENODEV; -+ -+ if (usb_endpoint_maxp(devpriv->ep_tx) < TX_MAX_SIZE) -+ return -ENODEV; -+ - return 0; - } - -diff --git a/drivers/comedi/drivers/vmk80xx.c b/drivers/comedi/drivers/vmk80xx.c -index 9f920819cd742..4b00a9ea611ab 100644 ---- a/drivers/comedi/drivers/vmk80xx.c -+++ b/drivers/comedi/drivers/vmk80xx.c -@@ -90,6 +90,9 @@ enum { - #define IC3_VERSION BIT(0) - #define IC6_VERSION BIT(1) - -+#define MIN_BUF_SIZE 64 -+#define PACKET_TIMEOUT 10000 /* ms */ -+ - enum vmk80xx_model { - VMK8055_MODEL, - VMK8061_MODEL -@@ -157,22 +160,21 @@ static void vmk80xx_do_bulk_msg(struct comedi_device *dev) - __u8 rx_addr; - unsigned int tx_pipe; - unsigned int rx_pipe; -- size_t size; -+ size_t tx_size; -+ size_t rx_size; - - tx_addr = devpriv->ep_tx->bEndpointAddress; - rx_addr = devpriv->ep_rx->bEndpointAddress; - tx_pipe = usb_sndbulkpipe(usb, tx_addr); - rx_pipe = usb_rcvbulkpipe(usb, rx_addr); -+ tx_size = usb_endpoint_maxp(devpriv->ep_tx); -+ rx_size = usb_endpoint_maxp(devpriv->ep_rx); - -- /* -- * The max packet size attributes of the K8061 -- * input/output endpoints are identical -- */ -- size = usb_endpoint_maxp(devpriv->ep_tx); -+ usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, tx_size, NULL, -+ PACKET_TIMEOUT); - -- usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, -- size, NULL, devpriv->ep_tx->bInterval); -- usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10); -+ usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, rx_size, NULL, -+ PACKET_TIMEOUT); - } - - static int vmk80xx_read_packet(struct comedi_device *dev) -@@ -191,7 +193,7 @@ static int vmk80xx_read_packet(struct comedi_device *dev) - pipe = usb_rcvintpipe(usb, ep->bEndpointAddress); - return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf, - usb_endpoint_maxp(ep), NULL, -- HZ * 10); -+ PACKET_TIMEOUT); - } - - static int vmk80xx_write_packet(struct comedi_device *dev, int cmd) -@@ -212,7 +214,7 @@ static int vmk80xx_write_packet(struct comedi_device *dev, int cmd) - pipe = usb_sndintpipe(usb, ep->bEndpointAddress); - return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf, - usb_endpoint_maxp(ep), NULL, -- HZ * 10); -+ PACKET_TIMEOUT); - } - - static int vmk80xx_reset_device(struct comedi_device *dev) -@@ -678,12 +680,12 @@ static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev) - struct vmk80xx_private *devpriv = dev->private; - size_t size; - -- size = usb_endpoint_maxp(devpriv->ep_rx); -+ size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE); - devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL); - if (!devpriv->usb_rx_buf) - return -ENOMEM; - -- size = usb_endpoint_maxp(devpriv->ep_tx); -+ size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE); - devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); - if (!devpriv->usb_tx_buf) - return -ENOMEM; -diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c -index 5782b15a8caad..eeac6d8092298 100644 ---- a/drivers/cpufreq/cpufreq.c -+++ b/drivers/cpufreq/cpufreq.c -@@ -1004,10 +1004,9 @@ static struct kobj_type ktype_cpufreq = { - .release = cpufreq_sysfs_release, - }; - --static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu) -+static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu, -+ struct device *dev) - { -- struct device *dev = get_cpu_device(cpu); -- - if (unlikely(!dev)) - return; - -@@ -1391,7 +1390,7 @@ static int cpufreq_online(unsigned int cpu) - if (new_policy) { - for_each_cpu(j, policy->related_cpus) { - per_cpu(cpufreq_cpu_data, j) = policy; -- add_cpu_dev_symlink(policy, j); -+ add_cpu_dev_symlink(policy, j, get_cpu_device(j)); - } - - policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req), -@@ -1403,7 +1402,7 @@ static int cpufreq_online(unsigned int cpu) - - ret = freq_qos_add_request(&policy->constraints, - policy->min_freq_req, FREQ_QOS_MIN, -- policy->min); -+ FREQ_QOS_MIN_DEFAULT_VALUE); - if (ret < 0) { - /* - * So we don't call freq_qos_remove_request() for an -@@ -1423,7 +1422,7 @@ static int cpufreq_online(unsigned int cpu) - - ret = freq_qos_add_request(&policy->constraints, - policy->max_freq_req, FREQ_QOS_MAX, -- policy->max); -+ FREQ_QOS_MAX_DEFAULT_VALUE); - if (ret < 0) { - policy->max_freq_req = NULL; - goto out_destroy_policy; -@@ -1565,7 +1564,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) - /* Create sysfs link on CPU registration */ - policy = per_cpu(cpufreq_cpu_data, cpu); - if (policy) -- add_cpu_dev_symlink(policy, cpu); -+ add_cpu_dev_symlink(policy, cpu, dev); - - return 0; - } -@@ -2523,8 +2522,15 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, - if (ret) - return ret; - -+ /* -+ * Resolve policy min/max to available frequencies. It ensures -+ * no frequency resolution will neither overshoot the requested maximum -+ * nor undershoot the requested minimum. -+ */ - policy->min = new_data.min; - policy->max = new_data.max; -+ policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L); -+ policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H); - trace_cpu_frequency_limits(policy); - - policy->cached_target_freq = UINT_MAX; -diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c -index 8c176b7dae415..e15c3bc17a55c 100644 ---- a/drivers/cpufreq/intel_pstate.c -+++ b/drivers/cpufreq/intel_pstate.c -@@ -537,7 +537,8 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu) - * scaling factor is too high, so recompute it to make the HWP_CAP - * highest performance correspond to the maximum turbo frequency. - */ -- if (turbo_freq < cpu->pstate.turbo_pstate * scaling) { -+ cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling; -+ if (turbo_freq < cpu->pstate.turbo_freq) { - cpu->pstate.turbo_freq = turbo_freq; - scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate); - cpu->pstate.scaling = scaling; -@@ -998,9 +999,22 @@ static void intel_pstate_hwp_offline(struct cpudata *cpu) - */ - value &= ~GENMASK_ULL(31, 24); - value |= HWP_ENERGY_PERF_PREFERENCE(cpu->epp_cached); -- WRITE_ONCE(cpu->hwp_req_cached, value); -+ /* -+ * However, make sure that EPP will be set to "performance" when -+ * the CPU is brought back online again and the "performance" -+ * scaling algorithm is still in effect. -+ */ -+ cpu->epp_policy = CPUFREQ_POLICY_UNKNOWN; - } - -+ /* -+ * Clear the desired perf field in the cached HWP request value to -+ * prevent nonzero desired values from being leaked into the active -+ * mode. -+ */ -+ value &= ~HWP_DESIRED_PERF(~0L); -+ WRITE_ONCE(cpu->hwp_req_cached, value); -+ - value &= ~GENMASK_ULL(31, 0); - min_perf = HWP_LOWEST_PERF(READ_ONCE(cpu->hwp_cap_cached)); - -@@ -2241,6 +2255,7 @@ static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = { - X86_MATCH(BROADWELL_D, core_funcs), - X86_MATCH(BROADWELL_X, core_funcs), - X86_MATCH(SKYLAKE_X, core_funcs), -+ X86_MATCH(ICELAKE_X, core_funcs), - {} - }; - -@@ -2902,6 +2917,27 @@ static int intel_cpufreq_cpu_exit(struct cpufreq_policy *policy) - return intel_pstate_cpu_exit(policy); - } - -+static int intel_cpufreq_suspend(struct cpufreq_policy *policy) -+{ -+ intel_pstate_suspend(policy); -+ -+ if (hwp_active) { -+ struct cpudata *cpu = all_cpu_data[policy->cpu]; -+ u64 value = READ_ONCE(cpu->hwp_req_cached); -+ -+ /* -+ * Clear the desired perf field in MSR_HWP_REQUEST in case -+ * intel_cpufreq_adjust_perf() is in use and the last value -+ * written by it may not be suitable. -+ */ -+ value &= ~HWP_DESIRED_PERF(~0L); -+ wrmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, value); -+ WRITE_ONCE(cpu->hwp_req_cached, value); -+ } -+ -+ return 0; -+} -+ - static struct cpufreq_driver intel_cpufreq = { - .flags = CPUFREQ_CONST_LOOPS, - .verify = intel_cpufreq_verify_policy, -@@ -2911,7 +2947,7 @@ static struct cpufreq_driver intel_cpufreq = { - .exit = intel_cpufreq_cpu_exit, - .offline = intel_cpufreq_cpu_offline, - .online = intel_pstate_cpu_online, -- .suspend = intel_pstate_suspend, -+ .suspend = intel_cpufreq_suspend, - .resume = intel_pstate_resume, - .update_limits = intel_pstate_update_limits, - .name = "intel_cpufreq", -diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c -index a2be0df7e1747..35d93361fda1a 100644 ---- a/drivers/cpufreq/qcom-cpufreq-hw.c -+++ b/drivers/cpufreq/qcom-cpufreq-hw.c -@@ -304,7 +304,8 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) - if (capacity > max_capacity) - capacity = max_capacity; - -- arch_set_thermal_pressure(policy->cpus, max_capacity - capacity); -+ arch_set_thermal_pressure(policy->related_cpus, -+ max_capacity - capacity); - - /* - * In the unlikely case policy is unregistered do not enable -@@ -342,9 +343,9 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data) - - /* Disable interrupt and enable polling */ - disable_irq_nosync(c_data->throttle_irq); -- qcom_lmh_dcvs_notify(c_data); -+ schedule_delayed_work(&c_data->throttle_work, 0); - -- return 0; -+ return IRQ_HANDLED; - } - - static const struct qcom_cpufreq_soc_data qcom_soc_data = { -diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c -index 53ec9585ccd44..469e18547d06c 100644 ---- a/drivers/cpuidle/sysfs.c -+++ b/drivers/cpuidle/sysfs.c -@@ -488,6 +488,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) - &kdev->kobj, "state%d", i); - if (ret) { - kobject_put(&kobj->kobj); -+ kfree(kobj); - goto error_state; - } - cpuidle_add_s2idle_attr_group(kobj); -@@ -619,6 +620,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) - &kdev->kobj, "driver"); - if (ret) { - kobject_put(&kdrv->kobj); -+ kfree(kdrv); - return ret; - } - -@@ -705,7 +707,6 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) - if (!kdev) - return -ENOMEM; - kdev->dev = dev; -- dev->kobj_dev = kdev; - - init_completion(&kdev->kobj_unregister); - -@@ -713,9 +714,11 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) - "cpuidle"); - if (error) { - kobject_put(&kdev->kobj); -+ kfree(kdev); - return error; - } - -+ dev->kobj_dev = kdev; - kobject_uevent(&kdev->kobj, KOBJ_ADD); - - return 0; -diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c -index 9391ccc03382d..fe05584031914 100644 ---- a/drivers/crypto/atmel-aes.c -+++ b/drivers/crypto/atmel-aes.c -@@ -960,6 +960,7 @@ static int atmel_aes_handle_queue(struct atmel_aes_dev *dd, - ctx = crypto_tfm_ctx(areq->tfm); - - dd->areq = areq; -+ dd->ctx = ctx; - start_async = (areq != new_areq); - dd->is_async = start_async; - -@@ -1274,7 +1275,6 @@ static int atmel_aes_init_tfm(struct crypto_skcipher *tfm) - - crypto_skcipher_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx)); - ctx->base.dd = dd; -- ctx->base.dd->ctx = &ctx->base; - ctx->base.start = atmel_aes_start; - - return 0; -@@ -1291,7 +1291,6 @@ static int atmel_aes_ctr_init_tfm(struct crypto_skcipher *tfm) - - crypto_skcipher_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx)); - ctx->base.dd = dd; -- ctx->base.dd->ctx = &ctx->base; - ctx->base.start = atmel_aes_ctr_start; - - return 0; -@@ -1783,7 +1782,6 @@ static int atmel_aes_gcm_init(struct crypto_aead *tfm) - - crypto_aead_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx)); - ctx->base.dd = dd; -- ctx->base.dd->ctx = &ctx->base; - ctx->base.start = atmel_aes_gcm_start; - - return 0; -@@ -1927,7 +1925,6 @@ static int atmel_aes_xts_init_tfm(struct crypto_skcipher *tfm) - crypto_skcipher_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx) + - crypto_skcipher_reqsize(ctx->fallback_tfm)); - ctx->base.dd = dd; -- ctx->base.dd->ctx = &ctx->base; - ctx->base.start = atmel_aes_xts_start; - - return 0; -@@ -2154,7 +2151,6 @@ static int atmel_aes_authenc_init_tfm(struct crypto_aead *tfm, - crypto_aead_set_reqsize(tfm, (sizeof(struct atmel_aes_authenc_reqctx) + - auth_reqsize)); - ctx->base.dd = dd; -- ctx->base.dd->ctx = &ctx->base; - ctx->base.start = atmel_aes_authenc_start; - - return 0; -diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c -index 8697ae53b0633..d3d8bb0a69900 100644 ---- a/drivers/crypto/caam/caamalg.c -+++ b/drivers/crypto/caam/caamalg.c -@@ -1533,6 +1533,9 @@ static int aead_do_one_req(struct crypto_engine *engine, void *areq) - - ret = caam_jr_enqueue(ctx->jrdev, desc, aead_crypt_done, req); - -+ if (ret == -ENOSPC && engine->retry_support) -+ return ret; -+ - if (ret != -EINPROGRESS) { - aead_unmap(ctx->jrdev, rctx->edesc, req); - kfree(rctx->edesc); -@@ -1762,6 +1765,9 @@ static int skcipher_do_one_req(struct crypto_engine *engine, void *areq) - - ret = caam_jr_enqueue(ctx->jrdev, desc, skcipher_crypt_done, req); - -+ if (ret == -ENOSPC && engine->retry_support) -+ return ret; -+ - if (ret != -EINPROGRESS) { - skcipher_unmap(ctx->jrdev, rctx->edesc, req); - kfree(rctx->edesc); -diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c -index 8b8ed77d8715d..6753f0e6e55d1 100644 ---- a/drivers/crypto/caam/caamalg_qi2.c -+++ b/drivers/crypto/caam/caamalg_qi2.c -@@ -5470,7 +5470,7 @@ int dpaa2_caam_enqueue(struct device *dev, struct caam_request *req) - dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1])); - dpaa2_fd_set_flc(&fd, req->flc_dma); - -- ppriv = this_cpu_ptr(priv->ppriv); -+ ppriv = raw_cpu_ptr(priv->ppriv); - for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) { - err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid, - &fd); -diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c -index e8a6d8bc43b5d..36ef738e4a181 100644 ---- a/drivers/crypto/caam/caamhash.c -+++ b/drivers/crypto/caam/caamhash.c -@@ -765,6 +765,9 @@ static int ahash_do_one_req(struct crypto_engine *engine, void *areq) - - ret = caam_jr_enqueue(jrdev, desc, state->ahash_op_done, req); - -+ if (ret == -ENOSPC && engine->retry_support) -+ return ret; -+ - if (ret != -EINPROGRESS) { - ahash_unmap(jrdev, state->edesc, req, 0); - kfree(state->edesc); -diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c -index e313233ec6de7..8867275767101 100644 ---- a/drivers/crypto/caam/caampkc.c -+++ b/drivers/crypto/caam/caampkc.c -@@ -380,6 +380,9 @@ static int akcipher_do_one_req(struct crypto_engine *engine, void *areq) - - ret = caam_jr_enqueue(jrdev, desc, req_ctx->akcipher_op_done, req); - -+ if (ret == -ENOSPC && engine->retry_support) -+ return ret; -+ - if (ret != -EINPROGRESS) { - rsa_pub_unmap(jrdev, req_ctx->edesc, req); - rsa_io_unmap(jrdev, req_ctx->edesc, req); -@@ -1153,16 +1156,27 @@ static struct caam_akcipher_alg caam_rsa = { - int caam_pkc_init(struct device *ctrldev) - { - struct caam_drv_private *priv = dev_get_drvdata(ctrldev); -- u32 pk_inst; -+ u32 pk_inst, pkha; - int err; - init_done = false; - - /* Determine public key hardware accelerator presence. */ -- if (priv->era < 10) -+ if (priv->era < 10) { - pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & - CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; -- else -- pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK; -+ } else { -+ pkha = rd_reg32(&priv->ctrl->vreg.pkha); -+ pk_inst = pkha & CHA_VER_NUM_MASK; -+ -+ /* -+ * Newer CAAMs support partially disabled functionality. If this is the -+ * case, the number is non-zero, but this bit is set to indicate that -+ * no encryption or decryption is supported. Only signing and verifying -+ * is supported. -+ */ -+ if (pkha & CHA_VER_MISC_PKHA_NO_CRYPT) -+ pk_inst = 0; -+ } - - /* Do not register algorithms if PKHA is not present. */ - if (!pk_inst) -diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h -index af61f3a2c0d46..3738625c02509 100644 ---- a/drivers/crypto/caam/regs.h -+++ b/drivers/crypto/caam/regs.h -@@ -322,6 +322,9 @@ struct version_regs { - /* CHA Miscellaneous Information - AESA_MISC specific */ - #define CHA_VER_MISC_AES_GCM BIT(1 + CHA_VER_MISC_SHIFT) - -+/* CHA Miscellaneous Information - PKHA_MISC specific */ -+#define CHA_VER_MISC_PKHA_NO_CRYPT BIT(7 + CHA_VER_MISC_SHIFT) -+ - /* - * caam_perfmon - Performance Monitor/Secure Memory Status/ - * CAAM Global Status/Component Version IDs -diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c -index 2ecb0e1f65d8d..e2806ca3300a8 100644 ---- a/drivers/crypto/ccp/sev-dev.c -+++ b/drivers/crypto/ccp/sev-dev.c -@@ -241,7 +241,7 @@ static int __sev_platform_init_locked(int *error) - struct psp_device *psp = psp_master; - struct sev_data_init data; - struct sev_device *sev; -- int rc = 0; -+ int psp_ret, rc = 0; - - if (!psp || !psp->sev_data) - return -ENODEV; -@@ -266,7 +266,21 @@ static int __sev_platform_init_locked(int *error) - data.tmr_len = SEV_ES_TMR_SIZE; - } - -- rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, error); -+ rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); -+ if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) { -+ /* -+ * Initialization command returned an integrity check failure -+ * status code, meaning that firmware load and validation of SEV -+ * related persistent data has failed. Retrying the -+ * initialization function should succeed by replacing the state -+ * with a reset state. -+ */ -+ dev_dbg(sev->dev, "SEV: retrying INIT command"); -+ rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); -+ } -+ if (error) -+ *error = psp_ret; -+ - if (rc) - return rc; - -@@ -1091,18 +1105,6 @@ void sev_pci_init(void) - - /* Initialize the platform */ - rc = sev_platform_init(&error); -- if (rc && (error == SEV_RET_SECURE_DATA_INVALID)) { -- /* -- * INIT command returned an integrity check failure -- * status code, meaning that firmware load and -- * validation of SEV related persistent data has -- * failed and persistent state has been erased. -- * Retrying INIT command here should succeed. -- */ -- dev_dbg(sev->dev, "SEV: retrying INIT command"); -- rc = sev_platform_init(&error); -- } -- - if (rc) { - dev_err(sev->dev, "SEV: failed to INIT error %#x\n", error); - return; -diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c -index e599ac6dc162a..790fa9058a36d 100644 ---- a/drivers/crypto/ccree/cc_driver.c -+++ b/drivers/crypto/ccree/cc_driver.c -@@ -103,7 +103,8 @@ MODULE_DEVICE_TABLE(of, arm_ccree_dev_of_match); - static void init_cc_cache_params(struct cc_drvdata *drvdata) - { - struct device *dev = drvdata_to_dev(drvdata); -- u32 cache_params, ace_const, val, mask; -+ u32 cache_params, ace_const, val; -+ u64 mask; - - /* compute CC_AXIM_CACHE_PARAMS */ - cache_params = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS)); -diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c -index a032c192ef1d6..7ba7641723a0b 100644 ---- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c -+++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c -@@ -1865,7 +1865,7 @@ static int hpre_curve25519_src_init(struct hpre_asym_request *hpre_req, - */ - if (memcmp(ptr, p, ctx->key_sz) == 0) { - dev_err(dev, "gx is p!\n"); -- return -EINVAL; -+ goto err; - } else if (memcmp(ptr, p, ctx->key_sz) > 0) { - hpre_curve25519_src_modulo_p(ptr); - } -diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c -index 369562d34d66a..ff1122153fbec 100644 ---- a/drivers/crypto/hisilicon/qm.c -+++ b/drivers/crypto/hisilicon/qm.c -@@ -5986,7 +5986,7 @@ int hisi_qm_resume(struct device *dev) - if (ret) - pci_err(pdev, "failed to start qm(%d)\n", ret); - -- return 0; -+ return ret; - } - EXPORT_SYMBOL_GPL(hisi_qm_resume); - -diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c -index 146a55ac4b9b0..be1ad55a208f6 100644 ---- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c -+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c -@@ -494,12 +494,11 @@ static ssize_t kvf_limits_store(struct device *dev, - { - struct otx2_cptpf_dev *cptpf = dev_get_drvdata(dev); - int lfs_num; -+ int ret; - -- if (kstrtoint(buf, 0, &lfs_num)) { -- dev_err(dev, "lfs count %d must be in range [1 - %d]\n", -- lfs_num, num_online_cpus()); -- return -EINVAL; -- } -+ ret = kstrtoint(buf, 0, &lfs_num); -+ if (ret) -+ return ret; - if (lfs_num < 1 || lfs_num > num_online_cpus()) { - dev_err(dev, "lfs count %d must be in range [1 - %d]\n", - lfs_num, num_online_cpus()); -diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c -index dff34b3ec09e1..7c1b92aaab398 100644 ---- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c -+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c -@@ -29,7 +29,8 @@ static struct otx2_cpt_bitmap get_cores_bmap(struct device *dev, - bool found = false; - int i; - -- if (eng_grp->g->engs_num > OTX2_CPT_MAX_ENGINES) { -+ if (eng_grp->g->engs_num < 0 || -+ eng_grp->g->engs_num > OTX2_CPT_MAX_ENGINES) { - dev_err(dev, "unsupported number of engines %d on octeontx2\n", - eng_grp->g->engs_num); - return bmap; -diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c -index a72723455df72..877a948469bd1 100644 ---- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c -+++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c -@@ -1274,6 +1274,7 @@ static int aead_do_fallback(struct aead_request *req, bool is_enc) - req->base.complete, req->base.data); - aead_request_set_crypt(&rctx->fbk_req, req->src, - req->dst, req->cryptlen, req->iv); -+ aead_request_set_ad(&rctx->fbk_req, req->assoclen); - ret = is_enc ? crypto_aead_encrypt(&rctx->fbk_req) : - crypto_aead_decrypt(&rctx->fbk_req); - } else { -diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c -index 9b968ac4ee7b6..a196bb8b17010 100644 ---- a/drivers/crypto/omap-aes.c -+++ b/drivers/crypto/omap-aes.c -@@ -1302,7 +1302,7 @@ static int omap_aes_suspend(struct device *dev) - - static int omap_aes_resume(struct device *dev) - { -- pm_runtime_resume_and_get(dev); -+ pm_runtime_get_sync(dev); - return 0; - } - #endif -diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c -index 33d8e50dcbdac..88c0ded411f15 100644 ---- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c -+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c -@@ -1,5 +1,6 @@ - // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) - /* Copyright(c) 2020 Intel Corporation */ -+#include - #include - #include - #include -@@ -161,6 +162,35 @@ static void adf_enable_ints(struct adf_accel_dev *accel_dev) - ADF_CSR_WR(addr, ADF_4XXX_SMIAPF_MASK_OFFSET, 0); - } - -+static int adf_init_device(struct adf_accel_dev *accel_dev) -+{ -+ void __iomem *addr; -+ u32 status; -+ u32 csr; -+ int ret; -+ -+ addr = (&GET_BARS(accel_dev)[ADF_4XXX_PMISC_BAR])->virt_addr; -+ -+ /* Temporarily mask PM interrupt */ -+ csr = ADF_CSR_RD(addr, ADF_4XXX_ERRMSK2); -+ csr |= ADF_4XXX_PM_SOU; -+ ADF_CSR_WR(addr, ADF_4XXX_ERRMSK2, csr); -+ -+ /* Set DRV_ACTIVE bit to power up the device */ -+ ADF_CSR_WR(addr, ADF_4XXX_PM_INTERRUPT, ADF_4XXX_PM_DRV_ACTIVE); -+ -+ /* Poll status register to make sure the device is powered up */ -+ ret = read_poll_timeout(ADF_CSR_RD, status, -+ status & ADF_4XXX_PM_INIT_STATE, -+ ADF_4XXX_PM_POLL_DELAY_US, -+ ADF_4XXX_PM_POLL_TIMEOUT_US, true, addr, -+ ADF_4XXX_PM_STATUS); -+ if (ret) -+ dev_err(&GET_DEV(accel_dev), "Failed to power up the device\n"); -+ -+ return ret; -+} -+ - static int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) - { - return 0; -@@ -215,6 +245,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) - hw_data->exit_arb = adf_exit_arb; - hw_data->get_arb_mapping = adf_get_arbiter_mapping; - hw_data->enable_ints = adf_enable_ints; -+ hw_data->init_device = adf_init_device; - hw_data->reset_device = adf_reset_flr; - hw_data->admin_ae_mask = ADF_4XXX_ADMIN_AE_MASK; - hw_data->uof_get_num_objs = uof_get_num_objs; -diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h -index 4fe2a776293c2..924bac6feb372 100644 ---- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h -+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h -@@ -62,6 +62,16 @@ - #define ADF_4XXX_ADMINMSGLR_OFFSET (0x500578) - #define ADF_4XXX_MAILBOX_BASE_OFFSET (0x600970) - -+/* Power management */ -+#define ADF_4XXX_PM_POLL_DELAY_US 20 -+#define ADF_4XXX_PM_POLL_TIMEOUT_US USEC_PER_SEC -+#define ADF_4XXX_PM_STATUS (0x50A00C) -+#define ADF_4XXX_PM_INTERRUPT (0x50A028) -+#define ADF_4XXX_PM_DRV_ACTIVE BIT(20) -+#define ADF_4XXX_PM_INIT_STATE BIT(21) -+/* Power management source in ERRSOU2 and ERRMSK2 */ -+#define ADF_4XXX_PM_SOU BIT(18) -+ - /* Firmware Binaries */ - #define ADF_4XXX_FW "qat_4xxx.bin" - #define ADF_4XXX_MMP "qat_4xxx_mmp.bin" -diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h -index 38c0af6d4e43e..580566cfcb04c 100644 ---- a/drivers/crypto/qat/qat_common/adf_accel_devices.h -+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h -@@ -166,6 +166,7 @@ struct adf_hw_device_data { - int (*init_arb)(struct adf_accel_dev *accel_dev); - void (*exit_arb)(struct adf_accel_dev *accel_dev); - const u32 *(*get_arb_mapping)(void); -+ int (*init_device)(struct adf_accel_dev *accel_dev); - void (*disable_iov)(struct adf_accel_dev *accel_dev); - void (*configure_iov_threads)(struct adf_accel_dev *accel_dev, - bool enable); -diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c -index 60bc7b991d351..e3749e5817d94 100644 ---- a/drivers/crypto/qat/qat_common/adf_init.c -+++ b/drivers/crypto/qat/qat_common/adf_init.c -@@ -79,6 +79,11 @@ int adf_dev_init(struct adf_accel_dev *accel_dev) - return -EFAULT; - } - -+ if (hw_data->init_device && hw_data->init_device(accel_dev)) { -+ dev_err(&GET_DEV(accel_dev), "Failed to initialize device\n"); -+ return -EFAULT; -+ } -+ - if (hw_data->init_admin_comms && hw_data->init_admin_comms(accel_dev)) { - dev_err(&GET_DEV(accel_dev), "Failed initialize admin comms\n"); - return -EFAULT; -diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c -index 976b9ab7617cd..7ec81989beb03 100644 ---- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c -+++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c -@@ -117,37 +117,19 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) - - mutex_lock(lock); - -- /* Check if PF2VF CSR is in use by remote function */ -+ /* Check if the PFVF CSR is in use by remote function */ - val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); - if ((val & remote_in_use_mask) == remote_in_use_pattern) { - dev_dbg(&GET_DEV(accel_dev), -- "PF2VF CSR in use by remote function\n"); -+ "PFVF CSR in use by remote function\n"); - ret = -EBUSY; - goto out; - } - -- /* Attempt to get ownership of PF2VF CSR */ - msg &= ~local_in_use_mask; - msg |= local_in_use_pattern; -- ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg); - -- /* Wait in case remote func also attempting to get ownership */ -- msleep(ADF_IOV_MSG_COLLISION_DETECT_DELAY); -- -- val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); -- if ((val & local_in_use_mask) != local_in_use_pattern) { -- dev_dbg(&GET_DEV(accel_dev), -- "PF2VF CSR in use by remote - collision detected\n"); -- ret = -EBUSY; -- goto out; -- } -- -- /* -- * This function now owns the PV2VF CSR. The IN_USE_BY pattern must -- * remain in the PF2VF CSR for all writes including ACK from remote -- * until this local function relinquishes the CSR. Send the message -- * by interrupting the remote. -- */ -+ /* Attempt to get ownership of the PFVF CSR */ - ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg | int_bit); - - /* Wait for confirmation from remote func it received the message */ -@@ -162,7 +144,14 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) - ret = -EIO; - } - -- /* Finished with PF2VF CSR; relinquish it and leave msg in CSR */ -+ if (val != msg) { -+ dev_dbg(&GET_DEV(accel_dev), -+ "Collision - PFVF CSR overwritten by remote function\n"); -+ ret = -EIO; -+ goto out; -+ } -+ -+ /* Finished with the PFVF CSR; relinquish it and leave msg in CSR */ - ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, val & ~local_in_use_mask); - out: - mutex_unlock(lock); -@@ -170,12 +159,13 @@ out: - } - - /** -- * adf_iov_putmsg() - send PF2VF message -+ * adf_iov_putmsg() - send PFVF message - * @accel_dev: Pointer to acceleration device. - * @msg: Message to send -- * @vf_nr: VF number to which the message will be sent -+ * @vf_nr: VF number to which the message will be sent if on PF, ignored -+ * otherwise - * -- * Function sends a message from the PF to a VF -+ * Function sends a message through the PFVF channel - * - * Return: 0 on success, error code otherwise. - */ -@@ -204,6 +194,11 @@ void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) - - /* Read message from the VF */ - msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); -+ if (!(msg & ADF_VF2PF_INT)) { -+ dev_info(&GET_DEV(accel_dev), -+ "Spurious VF2PF interrupt, msg %X. Ignored\n", msg); -+ goto out; -+ } - - /* To ACK, clear the VF2PFINT bit */ - msg &= ~ADF_VF2PF_INT; -@@ -287,6 +282,7 @@ void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) - if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) - dev_err(&GET_DEV(accel_dev), "Failed to send response to VF\n"); - -+out: - /* re-enable interrupt on PF from this VF */ - adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_nr)); - -diff --git a/drivers/crypto/qat/qat_common/adf_vf_isr.c b/drivers/crypto/qat/qat_common/adf_vf_isr.c -index 7828a6573f3e2..2e300c255ab94 100644 ---- a/drivers/crypto/qat/qat_common/adf_vf_isr.c -+++ b/drivers/crypto/qat/qat_common/adf_vf_isr.c -@@ -101,6 +101,11 @@ static void adf_pf2vf_bh_handler(void *data) - - /* Read the message from PF */ - msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0)); -+ if (!(msg & ADF_PF2VF_INT)) { -+ dev_info(&GET_DEV(accel_dev), -+ "Spurious PF2VF interrupt, msg %X. Ignored\n", msg); -+ goto out; -+ } - - if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) - /* Ignore legacy non-system (non-kernel) PF2VF messages */ -@@ -149,6 +154,7 @@ static void adf_pf2vf_bh_handler(void *data) - msg &= ~ADF_PF2VF_INT; - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); - -+out: - /* Re-enable PF2VF interrupts */ - adf_enable_pf2vf_interrupts(accel_dev); - return; -diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c -index 290e2446a2f35..97a530171f07a 100644 ---- a/drivers/crypto/qce/aead.c -+++ b/drivers/crypto/qce/aead.c -@@ -802,8 +802,8 @@ static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_devi - - ret = crypto_register_aead(alg); - if (ret) { -- kfree(tmpl); - dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name); -+ kfree(tmpl); - return ret; - } - -diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c -index 8e6fcf2c21cc0..59159f5e64e52 100644 ---- a/drivers/crypto/qce/sha.c -+++ b/drivers/crypto/qce/sha.c -@@ -498,8 +498,8 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def, - - ret = crypto_register_ahash(alg); - if (ret) { -- kfree(tmpl); - dev_err(qce->dev, "%s registration failed\n", base->cra_name); -+ kfree(tmpl); - return ret; - } - -diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c -index 8ff10928f581d..3d27cd5210ef5 100644 ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -484,8 +484,8 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def, - - ret = crypto_register_skcipher(alg); - if (ret) { -- kfree(tmpl); - dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name); -+ kfree(tmpl); - return ret; - } - -diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c -index 55aa3a71169b0..7717e9e5977bb 100644 ---- a/drivers/crypto/s5p-sss.c -+++ b/drivers/crypto/s5p-sss.c -@@ -2171,6 +2171,8 @@ static int s5p_aes_probe(struct platform_device *pdev) - - variant = find_s5p_sss_version(pdev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; - - /* - * Note: HASH and PRNG uses the same registers in secss, avoid -diff --git a/drivers/crypto/stm32/stm32-crc32.c b/drivers/crypto/stm32/stm32-crc32.c -index 75867c0b00172..be1bf39a317de 100644 ---- a/drivers/crypto/stm32/stm32-crc32.c -+++ b/drivers/crypto/stm32/stm32-crc32.c -@@ -279,7 +279,7 @@ static struct shash_alg algs[] = { - .digestsize = CHKSUM_DIGEST_SIZE, - .base = { - .cra_name = "crc32", -- .cra_driver_name = DRIVER_NAME, -+ .cra_driver_name = "stm32-crc32-crc32", - .cra_priority = 200, - .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, - .cra_blocksize = CHKSUM_BLOCK_SIZE, -@@ -301,7 +301,7 @@ static struct shash_alg algs[] = { - .digestsize = CHKSUM_DIGEST_SIZE, - .base = { - .cra_name = "crc32c", -- .cra_driver_name = DRIVER_NAME, -+ .cra_driver_name = "stm32-crc32-crc32c", - .cra_priority = 200, - .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, - .cra_blocksize = CHKSUM_BLOCK_SIZE, -diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c -index 7389a0536ff02..81eb136b6c11d 100644 ---- a/drivers/crypto/stm32/stm32-cryp.c -+++ b/drivers/crypto/stm32/stm32-cryp.c -@@ -37,7 +37,6 @@ - /* Mode mask = bits [15..0] */ - #define FLG_MODE_MASK GENMASK(15, 0) - /* Bit [31..16] status */ --#define FLG_CCM_PADDED_WA BIT(16) - - /* Registers */ - #define CRYP_CR 0x00000000 -@@ -105,8 +104,6 @@ - /* Misc */ - #define AES_BLOCK_32 (AES_BLOCK_SIZE / sizeof(u32)) - #define GCM_CTR_INIT 2 --#define _walked_in (cryp->in_walk.offset - cryp->in_sg->offset) --#define _walked_out (cryp->out_walk.offset - cryp->out_sg->offset) - #define CRYP_AUTOSUSPEND_DELAY 50 - - struct stm32_cryp_caps { -@@ -144,26 +141,16 @@ struct stm32_cryp { - size_t authsize; - size_t hw_blocksize; - -- size_t total_in; -- size_t total_in_save; -- size_t total_out; -- size_t total_out_save; -+ size_t payload_in; -+ size_t header_in; -+ size_t payload_out; - -- struct scatterlist *in_sg; - struct scatterlist *out_sg; -- struct scatterlist *out_sg_save; -- -- struct scatterlist in_sgl; -- struct scatterlist out_sgl; -- bool sgs_copied; -- -- int in_sg_len; -- int out_sg_len; - - struct scatter_walk in_walk; - struct scatter_walk out_walk; - -- u32 last_ctr[4]; -+ __be32 last_ctr[4]; - u32 gcm_ctr; - }; - -@@ -262,6 +249,7 @@ static inline int stm32_cryp_wait_output(struct stm32_cryp *cryp) - } - - static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp); -+static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err); - - static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx) - { -@@ -283,103 +271,6 @@ static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx) - return cryp; - } - --static int stm32_cryp_check_aligned(struct scatterlist *sg, size_t total, -- size_t align) --{ -- int len = 0; -- -- if (!total) -- return 0; -- -- if (!IS_ALIGNED(total, align)) -- return -EINVAL; -- -- while (sg) { -- if (!IS_ALIGNED(sg->offset, sizeof(u32))) -- return -EINVAL; -- -- if (!IS_ALIGNED(sg->length, align)) -- return -EINVAL; -- -- len += sg->length; -- sg = sg_next(sg); -- } -- -- if (len != total) -- return -EINVAL; -- -- return 0; --} -- --static int stm32_cryp_check_io_aligned(struct stm32_cryp *cryp) --{ -- int ret; -- -- ret = stm32_cryp_check_aligned(cryp->in_sg, cryp->total_in, -- cryp->hw_blocksize); -- if (ret) -- return ret; -- -- ret = stm32_cryp_check_aligned(cryp->out_sg, cryp->total_out, -- cryp->hw_blocksize); -- -- return ret; --} -- --static void sg_copy_buf(void *buf, struct scatterlist *sg, -- unsigned int start, unsigned int nbytes, int out) --{ -- struct scatter_walk walk; -- -- if (!nbytes) -- return; -- -- scatterwalk_start(&walk, sg); -- scatterwalk_advance(&walk, start); -- scatterwalk_copychunks(buf, &walk, nbytes, out); -- scatterwalk_done(&walk, out, 0); --} -- --static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp) --{ -- void *buf_in, *buf_out; -- int pages, total_in, total_out; -- -- if (!stm32_cryp_check_io_aligned(cryp)) { -- cryp->sgs_copied = 0; -- return 0; -- } -- -- total_in = ALIGN(cryp->total_in, cryp->hw_blocksize); -- pages = total_in ? get_order(total_in) : 1; -- buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); -- -- total_out = ALIGN(cryp->total_out, cryp->hw_blocksize); -- pages = total_out ? get_order(total_out) : 1; -- buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); -- -- if (!buf_in || !buf_out) { -- dev_err(cryp->dev, "Can't allocate pages when unaligned\n"); -- cryp->sgs_copied = 0; -- return -EFAULT; -- } -- -- sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0); -- -- sg_init_one(&cryp->in_sgl, buf_in, total_in); -- cryp->in_sg = &cryp->in_sgl; -- cryp->in_sg_len = 1; -- -- sg_init_one(&cryp->out_sgl, buf_out, total_out); -- cryp->out_sg_save = cryp->out_sg; -- cryp->out_sg = &cryp->out_sgl; -- cryp->out_sg_len = 1; -- -- cryp->sgs_copied = 1; -- -- return 0; --} -- - static void stm32_cryp_hw_write_iv(struct stm32_cryp *cryp, __be32 *iv) - { - if (!iv) -@@ -481,16 +372,99 @@ static int stm32_cryp_gcm_init(struct stm32_cryp *cryp, u32 cfg) - - /* Wait for end of processing */ - ret = stm32_cryp_wait_enable(cryp); -- if (ret) -+ if (ret) { - dev_err(cryp->dev, "Timeout (gcm init)\n"); -+ return ret; -+ } - -- return ret; -+ /* Prepare next phase */ -+ if (cryp->areq->assoclen) { -+ cfg |= CR_PH_HEADER; -+ stm32_cryp_write(cryp, CRYP_CR, cfg); -+ } else if (stm32_cryp_get_input_text_len(cryp)) { -+ cfg |= CR_PH_PAYLOAD; -+ stm32_cryp_write(cryp, CRYP_CR, cfg); -+ } -+ -+ return 0; -+} -+ -+static void stm32_crypt_gcmccm_end_header(struct stm32_cryp *cryp) -+{ -+ u32 cfg; -+ int err; -+ -+ /* Check if whole header written */ -+ if (!cryp->header_in) { -+ /* Wait for completion */ -+ err = stm32_cryp_wait_busy(cryp); -+ if (err) { -+ dev_err(cryp->dev, "Timeout (gcm/ccm header)\n"); -+ stm32_cryp_write(cryp, CRYP_IMSCR, 0); -+ stm32_cryp_finish_req(cryp, err); -+ return; -+ } -+ -+ if (stm32_cryp_get_input_text_len(cryp)) { -+ /* Phase 3 : payload */ -+ cfg = stm32_cryp_read(cryp, CRYP_CR); -+ cfg &= ~CR_CRYPEN; -+ stm32_cryp_write(cryp, CRYP_CR, cfg); -+ -+ cfg &= ~CR_PH_MASK; -+ cfg |= CR_PH_PAYLOAD | CR_CRYPEN; -+ stm32_cryp_write(cryp, CRYP_CR, cfg); -+ } else { -+ /* -+ * Phase 4 : tag. -+ * Nothing to read, nothing to write, caller have to -+ * end request -+ */ -+ } -+ } -+} -+ -+static void stm32_cryp_write_ccm_first_header(struct stm32_cryp *cryp) -+{ -+ unsigned int i; -+ size_t written; -+ size_t len; -+ u32 alen = cryp->areq->assoclen; -+ u32 block[AES_BLOCK_32] = {0}; -+ u8 *b8 = (u8 *)block; -+ -+ if (alen <= 65280) { -+ /* Write first u32 of B1 */ -+ b8[0] = (alen >> 8) & 0xFF; -+ b8[1] = alen & 0xFF; -+ len = 2; -+ } else { -+ /* Build the two first u32 of B1 */ -+ b8[0] = 0xFF; -+ b8[1] = 0xFE; -+ b8[2] = (alen & 0xFF000000) >> 24; -+ b8[3] = (alen & 0x00FF0000) >> 16; -+ b8[4] = (alen & 0x0000FF00) >> 8; -+ b8[5] = alen & 0x000000FF; -+ len = 6; -+ } -+ -+ written = min_t(size_t, AES_BLOCK_SIZE - len, alen); -+ -+ scatterwalk_copychunks((char *)block + len, &cryp->in_walk, written, 0); -+ for (i = 0; i < AES_BLOCK_32; i++) -+ stm32_cryp_write(cryp, CRYP_DIN, block[i]); -+ -+ cryp->header_in -= written; -+ -+ stm32_crypt_gcmccm_end_header(cryp); - } - - static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg) - { - int ret; -- u8 iv[AES_BLOCK_SIZE], b0[AES_BLOCK_SIZE]; -+ u32 iv_32[AES_BLOCK_32], b0_32[AES_BLOCK_32]; -+ u8 *iv = (u8 *)iv_32, *b0 = (u8 *)b0_32; - __be32 *bd; - u32 *d; - unsigned int i, textlen; -@@ -531,10 +505,24 @@ static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg) - - /* Wait for end of processing */ - ret = stm32_cryp_wait_enable(cryp); -- if (ret) -+ if (ret) { - dev_err(cryp->dev, "Timeout (ccm init)\n"); -+ return ret; -+ } - -- return ret; -+ /* Prepare next phase */ -+ if (cryp->areq->assoclen) { -+ cfg |= CR_PH_HEADER | CR_CRYPEN; -+ stm32_cryp_write(cryp, CRYP_CR, cfg); -+ -+ /* Write first (special) block (may move to next phase [payload]) */ -+ stm32_cryp_write_ccm_first_header(cryp); -+ } else if (stm32_cryp_get_input_text_len(cryp)) { -+ cfg |= CR_PH_PAYLOAD; -+ stm32_cryp_write(cryp, CRYP_CR, cfg); -+ } -+ -+ return 0; - } - - static int stm32_cryp_hw_init(struct stm32_cryp *cryp) -@@ -542,7 +530,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) - int ret; - u32 cfg, hw_mode; - -- pm_runtime_resume_and_get(cryp->dev); -+ pm_runtime_get_sync(cryp->dev); - - /* Disable interrupt */ - stm32_cryp_write(cryp, CRYP_IMSCR, 0); -@@ -605,16 +593,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) - if (ret) - return ret; - -- /* Phase 2 : header (authenticated data) */ -- if (cryp->areq->assoclen) { -- cfg |= CR_PH_HEADER; -- } else if (stm32_cryp_get_input_text_len(cryp)) { -- cfg |= CR_PH_PAYLOAD; -- stm32_cryp_write(cryp, CRYP_CR, cfg); -- } else { -- cfg |= CR_PH_INIT; -- } -- - break; - - case CR_DES_CBC: -@@ -633,8 +611,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) - - stm32_cryp_write(cryp, CRYP_CR, cfg); - -- cryp->flags &= ~FLG_CCM_PADDED_WA; -- - return 0; - } - -@@ -644,28 +620,9 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err) - /* Phase 4 : output tag */ - err = stm32_cryp_read_auth_tag(cryp); - -- if (!err && (!(is_gcm(cryp) || is_ccm(cryp)))) -+ if (!err && (!(is_gcm(cryp) || is_ccm(cryp) || is_ecb(cryp)))) - stm32_cryp_get_iv(cryp); - -- if (cryp->sgs_copied) { -- void *buf_in, *buf_out; -- int pages, len; -- -- buf_in = sg_virt(&cryp->in_sgl); -- buf_out = sg_virt(&cryp->out_sgl); -- -- sg_copy_buf(buf_out, cryp->out_sg_save, 0, -- cryp->total_out_save, 1); -- -- len = ALIGN(cryp->total_in_save, cryp->hw_blocksize); -- pages = len ? get_order(len) : 1; -- free_pages((unsigned long)buf_in, pages); -- -- len = ALIGN(cryp->total_out_save, cryp->hw_blocksize); -- pages = len ? get_order(len) : 1; -- free_pages((unsigned long)buf_out, pages); -- } -- - pm_runtime_mark_last_busy(cryp->dev); - pm_runtime_put_autosuspend(cryp->dev); - -@@ -674,8 +631,6 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err) - else - crypto_finalize_skcipher_request(cryp->engine, cryp->req, - err); -- -- memset(cryp->ctx->key, 0, cryp->ctx->keylen); - } - - static int stm32_cryp_cpu_start(struct stm32_cryp *cryp) -@@ -801,7 +756,20 @@ static int stm32_cryp_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key, - static int stm32_cryp_aes_gcm_setauthsize(struct crypto_aead *tfm, - unsigned int authsize) - { -- return authsize == AES_BLOCK_SIZE ? 0 : -EINVAL; -+ switch (authsize) { -+ case 4: -+ case 8: -+ case 12: -+ case 13: -+ case 14: -+ case 15: -+ case 16: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; - } - - static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, -@@ -825,31 +793,61 @@ static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, - - static int stm32_cryp_aes_ecb_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % AES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT); - } - - static int stm32_cryp_aes_ecb_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % AES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_AES | FLG_ECB); - } - - static int stm32_cryp_aes_cbc_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % AES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT); - } - - static int stm32_cryp_aes_cbc_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % AES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_AES | FLG_CBC); - } - - static int stm32_cryp_aes_ctr_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT); - } - - static int stm32_cryp_aes_ctr_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_AES | FLG_CTR); - } - -@@ -863,53 +861,122 @@ static int stm32_cryp_aes_gcm_decrypt(struct aead_request *req) - return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM); - } - -+static inline int crypto_ccm_check_iv(const u8 *iv) -+{ -+ /* 2 <= L <= 8, so 1 <= L' <= 7. */ -+ if (iv[0] < 1 || iv[0] > 7) -+ return -EINVAL; -+ -+ return 0; -+} -+ - static int stm32_cryp_aes_ccm_encrypt(struct aead_request *req) - { -+ int err; -+ -+ err = crypto_ccm_check_iv(req->iv); -+ if (err) -+ return err; -+ - return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM | FLG_ENCRYPT); - } - - static int stm32_cryp_aes_ccm_decrypt(struct aead_request *req) - { -+ int err; -+ -+ err = crypto_ccm_check_iv(req->iv); -+ if (err) -+ return err; -+ - return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM); - } - - static int stm32_cryp_des_ecb_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT); - } - - static int stm32_cryp_des_ecb_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_DES | FLG_ECB); - } - - static int stm32_cryp_des_cbc_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT); - } - - static int stm32_cryp_des_cbc_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_DES | FLG_CBC); - } - - static int stm32_cryp_tdes_ecb_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT); - } - - static int stm32_cryp_tdes_ecb_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB); - } - - static int stm32_cryp_tdes_cbc_encrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT); - } - - static int stm32_cryp_tdes_cbc_decrypt(struct skcipher_request *req) - { -+ if (req->cryptlen % DES_BLOCK_SIZE) -+ return -EINVAL; -+ -+ if (req->cryptlen == 0) -+ return 0; -+ - return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC); - } - -@@ -919,6 +986,7 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req, - struct stm32_cryp_ctx *ctx; - struct stm32_cryp *cryp; - struct stm32_cryp_reqctx *rctx; -+ struct scatterlist *in_sg; - int ret; - - if (!req && !areq) -@@ -944,76 +1012,55 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req, - if (req) { - cryp->req = req; - cryp->areq = NULL; -- cryp->total_in = req->cryptlen; -- cryp->total_out = cryp->total_in; -+ cryp->header_in = 0; -+ cryp->payload_in = req->cryptlen; -+ cryp->payload_out = req->cryptlen; -+ cryp->authsize = 0; - } else { - /* - * Length of input and output data: - * Encryption case: -- * INPUT = AssocData || PlainText -+ * INPUT = AssocData || PlainText - * <- assoclen -> <- cryptlen -> -- * <------- total_in -----------> - * -- * OUTPUT = AssocData || CipherText || AuthTag -- * <- assoclen -> <- cryptlen -> <- authsize -> -- * <---------------- total_out -----------------> -+ * OUTPUT = AssocData || CipherText || AuthTag -+ * <- assoclen -> <-- cryptlen --> <- authsize -> - * - * Decryption case: -- * INPUT = AssocData || CipherText || AuthTag -- * <- assoclen -> <--------- cryptlen ---------> -- * <- authsize -> -- * <---------------- total_in ------------------> -+ * INPUT = AssocData || CipherTex || AuthTag -+ * <- assoclen ---> <---------- cryptlen ----------> - * -- * OUTPUT = AssocData || PlainText -- * <- assoclen -> <- crypten - authsize -> -- * <---------- total_out -----------------> -+ * OUTPUT = AssocData || PlainText -+ * <- assoclen -> <- cryptlen - authsize -> - */ - cryp->areq = areq; - cryp->req = NULL; - cryp->authsize = crypto_aead_authsize(crypto_aead_reqtfm(areq)); -- cryp->total_in = areq->assoclen + areq->cryptlen; -- if (is_encrypt(cryp)) -- /* Append auth tag to output */ -- cryp->total_out = cryp->total_in + cryp->authsize; -- else -- /* No auth tag in output */ -- cryp->total_out = cryp->total_in - cryp->authsize; -+ if (is_encrypt(cryp)) { -+ cryp->payload_in = areq->cryptlen; -+ cryp->header_in = areq->assoclen; -+ cryp->payload_out = areq->cryptlen; -+ } else { -+ cryp->payload_in = areq->cryptlen - cryp->authsize; -+ cryp->header_in = areq->assoclen; -+ cryp->payload_out = cryp->payload_in; -+ } - } - -- cryp->total_in_save = cryp->total_in; -- cryp->total_out_save = cryp->total_out; -+ in_sg = req ? req->src : areq->src; -+ scatterwalk_start(&cryp->in_walk, in_sg); - -- cryp->in_sg = req ? req->src : areq->src; - cryp->out_sg = req ? req->dst : areq->dst; -- cryp->out_sg_save = cryp->out_sg; -- -- cryp->in_sg_len = sg_nents_for_len(cryp->in_sg, cryp->total_in); -- if (cryp->in_sg_len < 0) { -- dev_err(cryp->dev, "Cannot get in_sg_len\n"); -- ret = cryp->in_sg_len; -- return ret; -- } -- -- cryp->out_sg_len = sg_nents_for_len(cryp->out_sg, cryp->total_out); -- if (cryp->out_sg_len < 0) { -- dev_err(cryp->dev, "Cannot get out_sg_len\n"); -- ret = cryp->out_sg_len; -- return ret; -- } -- -- ret = stm32_cryp_copy_sgs(cryp); -- if (ret) -- return ret; -- -- scatterwalk_start(&cryp->in_walk, cryp->in_sg); - scatterwalk_start(&cryp->out_walk, cryp->out_sg); - - if (is_gcm(cryp) || is_ccm(cryp)) { - /* In output, jump after assoc data */ -- scatterwalk_advance(&cryp->out_walk, cryp->areq->assoclen); -- cryp->total_out -= cryp->areq->assoclen; -+ scatterwalk_copychunks(NULL, &cryp->out_walk, cryp->areq->assoclen, 2); - } - -+ if (is_ctr(cryp)) -+ memset(cryp->last_ctr, 0, sizeof(cryp->last_ctr)); -+ - ret = stm32_cryp_hw_init(cryp); - return ret; - } -@@ -1061,8 +1108,7 @@ static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq) - if (!cryp) - return -ENODEV; - -- if (unlikely(!cryp->areq->assoclen && -- !stm32_cryp_get_input_text_len(cryp))) { -+ if (unlikely(!cryp->payload_in && !cryp->header_in)) { - /* No input data to process: get tag and finish */ - stm32_cryp_finish_req(cryp, 0); - return 0; -@@ -1071,43 +1117,10 @@ static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq) - return stm32_cryp_cpu_start(cryp); - } - --static u32 *stm32_cryp_next_out(struct stm32_cryp *cryp, u32 *dst, -- unsigned int n) --{ -- scatterwalk_advance(&cryp->out_walk, n); -- -- if (unlikely(cryp->out_sg->length == _walked_out)) { -- cryp->out_sg = sg_next(cryp->out_sg); -- if (cryp->out_sg) { -- scatterwalk_start(&cryp->out_walk, cryp->out_sg); -- return (sg_virt(cryp->out_sg) + _walked_out); -- } -- } -- -- return (u32 *)((u8 *)dst + n); --} -- --static u32 *stm32_cryp_next_in(struct stm32_cryp *cryp, u32 *src, -- unsigned int n) --{ -- scatterwalk_advance(&cryp->in_walk, n); -- -- if (unlikely(cryp->in_sg->length == _walked_in)) { -- cryp->in_sg = sg_next(cryp->in_sg); -- if (cryp->in_sg) { -- scatterwalk_start(&cryp->in_walk, cryp->in_sg); -- return (sg_virt(cryp->in_sg) + _walked_in); -- } -- } -- -- return (u32 *)((u8 *)src + n); --} -- - static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) - { -- u32 cfg, size_bit, *dst, d32; -- u8 *d8; -- unsigned int i, j; -+ u32 cfg, size_bit; -+ unsigned int i; - int ret = 0; - - /* Update Config */ -@@ -1130,7 +1143,7 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) - stm32_cryp_write(cryp, CRYP_DIN, size_bit); - - size_bit = is_encrypt(cryp) ? cryp->areq->cryptlen : -- cryp->areq->cryptlen - AES_BLOCK_SIZE; -+ cryp->areq->cryptlen - cryp->authsize; - size_bit *= 8; - if (cryp->caps->swap_final) - size_bit = (__force u32)cpu_to_be32(size_bit); -@@ -1139,11 +1152,9 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) - stm32_cryp_write(cryp, CRYP_DIN, size_bit); - } else { - /* CCM: write CTR0 */ -- u8 iv[AES_BLOCK_SIZE]; -- u32 *iv32 = (u32 *)iv; -- __be32 *biv; -- -- biv = (void *)iv; -+ u32 iv32[AES_BLOCK_32]; -+ u8 *iv = (u8 *)iv32; -+ __be32 *biv = (__be32 *)iv32; - - memcpy(iv, cryp->areq->iv, AES_BLOCK_SIZE); - memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1); -@@ -1165,39 +1176,18 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) - } - - if (is_encrypt(cryp)) { -+ u32 out_tag[AES_BLOCK_32]; -+ - /* Get and write tag */ -- dst = sg_virt(cryp->out_sg) + _walked_out; -+ for (i = 0; i < AES_BLOCK_32; i++) -+ out_tag[i] = stm32_cryp_read(cryp, CRYP_DOUT); - -- for (i = 0; i < AES_BLOCK_32; i++) { -- if (cryp->total_out >= sizeof(u32)) { -- /* Read a full u32 */ -- *dst = stm32_cryp_read(cryp, CRYP_DOUT); -- -- dst = stm32_cryp_next_out(cryp, dst, -- sizeof(u32)); -- cryp->total_out -= sizeof(u32); -- } else if (!cryp->total_out) { -- /* Empty fifo out (data from input padding) */ -- stm32_cryp_read(cryp, CRYP_DOUT); -- } else { -- /* Read less than an u32 */ -- d32 = stm32_cryp_read(cryp, CRYP_DOUT); -- d8 = (u8 *)&d32; -- -- for (j = 0; j < cryp->total_out; j++) { -- *((u8 *)dst) = *(d8++); -- dst = stm32_cryp_next_out(cryp, dst, 1); -- } -- cryp->total_out = 0; -- } -- } -+ scatterwalk_copychunks(out_tag, &cryp->out_walk, cryp->authsize, 1); - } else { - /* Get and check tag */ - u32 in_tag[AES_BLOCK_32], out_tag[AES_BLOCK_32]; - -- scatterwalk_map_and_copy(in_tag, cryp->in_sg, -- cryp->total_in_save - cryp->authsize, -- cryp->authsize, 0); -+ scatterwalk_copychunks(in_tag, &cryp->in_walk, cryp->authsize, 0); - - for (i = 0; i < AES_BLOCK_32; i++) - out_tag[i] = stm32_cryp_read(cryp, CRYP_DOUT); -@@ -1217,115 +1207,59 @@ static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) - { - u32 cr; - -- if (unlikely(cryp->last_ctr[3] == 0xFFFFFFFF)) { -- cryp->last_ctr[3] = 0; -- cryp->last_ctr[2]++; -- if (!cryp->last_ctr[2]) { -- cryp->last_ctr[1]++; -- if (!cryp->last_ctr[1]) -- cryp->last_ctr[0]++; -- } -+ if (unlikely(cryp->last_ctr[3] == cpu_to_be32(0xFFFFFFFF))) { -+ /* -+ * In this case, we need to increment manually the ctr counter, -+ * as HW doesn't handle the U32 carry. -+ */ -+ crypto_inc((u8 *)cryp->last_ctr, sizeof(cryp->last_ctr)); - - cr = stm32_cryp_read(cryp, CRYP_CR); - stm32_cryp_write(cryp, CRYP_CR, cr & ~CR_CRYPEN); - -- stm32_cryp_hw_write_iv(cryp, (__be32 *)cryp->last_ctr); -+ stm32_cryp_hw_write_iv(cryp, cryp->last_ctr); - - stm32_cryp_write(cryp, CRYP_CR, cr); - } - -- cryp->last_ctr[0] = stm32_cryp_read(cryp, CRYP_IV0LR); -- cryp->last_ctr[1] = stm32_cryp_read(cryp, CRYP_IV0RR); -- cryp->last_ctr[2] = stm32_cryp_read(cryp, CRYP_IV1LR); -- cryp->last_ctr[3] = stm32_cryp_read(cryp, CRYP_IV1RR); -+ /* The IV registers are BE */ -+ cryp->last_ctr[0] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV0LR)); -+ cryp->last_ctr[1] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV0RR)); -+ cryp->last_ctr[2] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV1LR)); -+ cryp->last_ctr[3] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV1RR)); - } - --static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp) -+static void stm32_cryp_irq_read_data(struct stm32_cryp *cryp) - { -- unsigned int i, j; -- u32 d32, *dst; -- u8 *d8; -- size_t tag_size; -- -- /* Do no read tag now (if any) */ -- if (is_encrypt(cryp) && (is_gcm(cryp) || is_ccm(cryp))) -- tag_size = cryp->authsize; -- else -- tag_size = 0; -- -- dst = sg_virt(cryp->out_sg) + _walked_out; -+ unsigned int i; -+ u32 block[AES_BLOCK_32]; - -- for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { -- if (likely(cryp->total_out - tag_size >= sizeof(u32))) { -- /* Read a full u32 */ -- *dst = stm32_cryp_read(cryp, CRYP_DOUT); -+ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) -+ block[i] = stm32_cryp_read(cryp, CRYP_DOUT); - -- dst = stm32_cryp_next_out(cryp, dst, sizeof(u32)); -- cryp->total_out -= sizeof(u32); -- } else if (cryp->total_out == tag_size) { -- /* Empty fifo out (data from input padding) */ -- d32 = stm32_cryp_read(cryp, CRYP_DOUT); -- } else { -- /* Read less than an u32 */ -- d32 = stm32_cryp_read(cryp, CRYP_DOUT); -- d8 = (u8 *)&d32; -- -- for (j = 0; j < cryp->total_out - tag_size; j++) { -- *((u8 *)dst) = *(d8++); -- dst = stm32_cryp_next_out(cryp, dst, 1); -- } -- cryp->total_out = tag_size; -- } -- } -- -- return !(cryp->total_out - tag_size) || !cryp->total_in; -+ scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize, -+ cryp->payload_out), 1); -+ cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, -+ cryp->payload_out); - } - - static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp) - { -- unsigned int i, j; -- u32 *src; -- u8 d8[4]; -- size_t tag_size; -- -- /* Do no write tag (if any) */ -- if (is_decrypt(cryp) && (is_gcm(cryp) || is_ccm(cryp))) -- tag_size = cryp->authsize; -- else -- tag_size = 0; -- -- src = sg_virt(cryp->in_sg) + _walked_in; -+ unsigned int i; -+ u32 block[AES_BLOCK_32] = {0}; - -- for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { -- if (likely(cryp->total_in - tag_size >= sizeof(u32))) { -- /* Write a full u32 */ -- stm32_cryp_write(cryp, CRYP_DIN, *src); -+ scatterwalk_copychunks(block, &cryp->in_walk, min_t(size_t, cryp->hw_blocksize, -+ cryp->payload_in), 0); -+ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) -+ stm32_cryp_write(cryp, CRYP_DIN, block[i]); - -- src = stm32_cryp_next_in(cryp, src, sizeof(u32)); -- cryp->total_in -= sizeof(u32); -- } else if (cryp->total_in == tag_size) { -- /* Write padding data */ -- stm32_cryp_write(cryp, CRYP_DIN, 0); -- } else { -- /* Write less than an u32 */ -- memset(d8, 0, sizeof(u32)); -- for (j = 0; j < cryp->total_in - tag_size; j++) { -- d8[j] = *((u8 *)src); -- src = stm32_cryp_next_in(cryp, src, 1); -- } -- -- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); -- cryp->total_in = tag_size; -- } -- } -+ cryp->payload_in -= min_t(size_t, cryp->hw_blocksize, cryp->payload_in); - } - - static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) - { - int err; -- u32 cfg, tmp[AES_BLOCK_32]; -- size_t total_in_ori = cryp->total_in; -- struct scatterlist *out_sg_ori = cryp->out_sg; -+ u32 cfg, block[AES_BLOCK_32] = {0}; - unsigned int i; - - /* 'Special workaround' procedure described in the datasheet */ -@@ -1350,18 +1284,25 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) - - /* b) pad and write the last block */ - stm32_cryp_irq_write_block(cryp); -- cryp->total_in = total_in_ori; -+ /* wait end of process */ - err = stm32_cryp_wait_output(cryp); - if (err) { -- dev_err(cryp->dev, "Timeout (write gcm header)\n"); -+ dev_err(cryp->dev, "Timeout (write gcm last data)\n"); - return stm32_cryp_finish_req(cryp, err); - } - - /* c) get and store encrypted data */ -- stm32_cryp_irq_read_data(cryp); -- scatterwalk_map_and_copy(tmp, out_sg_ori, -- cryp->total_in_save - total_in_ori, -- total_in_ori, 0); -+ /* -+ * Same code as stm32_cryp_irq_read_data(), but we want to store -+ * block value -+ */ -+ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) -+ block[i] = stm32_cryp_read(cryp, CRYP_DOUT); -+ -+ scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize, -+ cryp->payload_out), 1); -+ cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, -+ cryp->payload_out); - - /* d) change mode back to AES GCM */ - cfg &= ~CR_ALGO_MASK; -@@ -1374,19 +1315,13 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) - stm32_cryp_write(cryp, CRYP_CR, cfg); - - /* f) write padded data */ -- for (i = 0; i < AES_BLOCK_32; i++) { -- if (cryp->total_in) -- stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); -- else -- stm32_cryp_write(cryp, CRYP_DIN, 0); -- -- cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); -- } -+ for (i = 0; i < AES_BLOCK_32; i++) -+ stm32_cryp_write(cryp, CRYP_DIN, block[i]); - - /* g) Empty fifo out */ - err = stm32_cryp_wait_output(cryp); - if (err) { -- dev_err(cryp->dev, "Timeout (write gcm header)\n"); -+ dev_err(cryp->dev, "Timeout (write gcm padded data)\n"); - return stm32_cryp_finish_req(cryp, err); - } - -@@ -1399,16 +1334,14 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) - - static void stm32_cryp_irq_set_npblb(struct stm32_cryp *cryp) - { -- u32 cfg, payload_bytes; -+ u32 cfg; - - /* disable ip, set NPBLB and reneable ip */ - cfg = stm32_cryp_read(cryp, CRYP_CR); - cfg &= ~CR_CRYPEN; - stm32_cryp_write(cryp, CRYP_CR, cfg); - -- payload_bytes = is_decrypt(cryp) ? cryp->total_in - cryp->authsize : -- cryp->total_in; -- cfg |= (cryp->hw_blocksize - payload_bytes) << CR_NBPBL_SHIFT; -+ cfg |= (cryp->hw_blocksize - cryp->payload_in) << CR_NBPBL_SHIFT; - cfg |= CR_CRYPEN; - stm32_cryp_write(cryp, CRYP_CR, cfg); - } -@@ -1417,13 +1350,11 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) - { - int err = 0; - u32 cfg, iv1tmp; -- u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32], tmp[AES_BLOCK_32]; -- size_t last_total_out, total_in_ori = cryp->total_in; -- struct scatterlist *out_sg_ori = cryp->out_sg; -+ u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32]; -+ u32 block[AES_BLOCK_32] = {0}; - unsigned int i; - - /* 'Special workaround' procedure described in the datasheet */ -- cryp->flags |= FLG_CCM_PADDED_WA; - - /* a) disable ip */ - stm32_cryp_write(cryp, CRYP_IMSCR, 0); -@@ -1453,7 +1384,7 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) - - /* b) pad and write the last block */ - stm32_cryp_irq_write_block(cryp); -- cryp->total_in = total_in_ori; -+ /* wait end of process */ - err = stm32_cryp_wait_output(cryp); - if (err) { - dev_err(cryp->dev, "Timeout (wite ccm padded data)\n"); -@@ -1461,13 +1392,16 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) - } - - /* c) get and store decrypted data */ -- last_total_out = cryp->total_out; -- stm32_cryp_irq_read_data(cryp); -+ /* -+ * Same code as stm32_cryp_irq_read_data(), but we want to store -+ * block value -+ */ -+ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) -+ block[i] = stm32_cryp_read(cryp, CRYP_DOUT); - -- memset(tmp, 0, sizeof(tmp)); -- scatterwalk_map_and_copy(tmp, out_sg_ori, -- cryp->total_out_save - last_total_out, -- last_total_out, 0); -+ scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize, -+ cryp->payload_out), 1); -+ cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, cryp->payload_out); - - /* d) Load again CRYP_CSGCMCCMxR */ - for (i = 0; i < ARRAY_SIZE(cstmp2); i++) -@@ -1484,10 +1418,10 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) - stm32_cryp_write(cryp, CRYP_CR, cfg); - - /* g) XOR and write padded data */ -- for (i = 0; i < ARRAY_SIZE(tmp); i++) { -- tmp[i] ^= cstmp1[i]; -- tmp[i] ^= cstmp2[i]; -- stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); -+ for (i = 0; i < ARRAY_SIZE(block); i++) { -+ block[i] ^= cstmp1[i]; -+ block[i] ^= cstmp2[i]; -+ stm32_cryp_write(cryp, CRYP_DIN, block[i]); - } - - /* h) wait for completion */ -@@ -1501,30 +1435,34 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) - - static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) - { -- if (unlikely(!cryp->total_in)) { -+ if (unlikely(!cryp->payload_in)) { - dev_warn(cryp->dev, "No more data to process\n"); - return; - } - -- if (unlikely(cryp->total_in < AES_BLOCK_SIZE && -+ if (unlikely(cryp->payload_in < AES_BLOCK_SIZE && - (stm32_cryp_get_hw_mode(cryp) == CR_AES_GCM) && - is_encrypt(cryp))) { - /* Padding for AES GCM encryption */ -- if (cryp->caps->padding_wa) -+ if (cryp->caps->padding_wa) { - /* Special case 1 */ -- return stm32_cryp_irq_write_gcm_padded_data(cryp); -+ stm32_cryp_irq_write_gcm_padded_data(cryp); -+ return; -+ } - - /* Setting padding bytes (NBBLB) */ - stm32_cryp_irq_set_npblb(cryp); - } - -- if (unlikely((cryp->total_in - cryp->authsize < AES_BLOCK_SIZE) && -+ if (unlikely((cryp->payload_in < AES_BLOCK_SIZE) && - (stm32_cryp_get_hw_mode(cryp) == CR_AES_CCM) && - is_decrypt(cryp))) { - /* Padding for AES CCM decryption */ -- if (cryp->caps->padding_wa) -+ if (cryp->caps->padding_wa) { - /* Special case 2 */ -- return stm32_cryp_irq_write_ccm_padded_data(cryp); -+ stm32_cryp_irq_write_ccm_padded_data(cryp); -+ return; -+ } - - /* Setting padding bytes (NBBLB) */ - stm32_cryp_irq_set_npblb(cryp); -@@ -1536,192 +1474,60 @@ static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) - stm32_cryp_irq_write_block(cryp); - } - --static void stm32_cryp_irq_write_gcm_header(struct stm32_cryp *cryp) -+static void stm32_cryp_irq_write_gcmccm_header(struct stm32_cryp *cryp) - { -- int err; -- unsigned int i, j; -- u32 cfg, *src; -- -- src = sg_virt(cryp->in_sg) + _walked_in; -- -- for (i = 0; i < AES_BLOCK_32; i++) { -- stm32_cryp_write(cryp, CRYP_DIN, *src); -- -- src = stm32_cryp_next_in(cryp, src, sizeof(u32)); -- cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); -- -- /* Check if whole header written */ -- if ((cryp->total_in_save - cryp->total_in) == -- cryp->areq->assoclen) { -- /* Write padding if needed */ -- for (j = i + 1; j < AES_BLOCK_32; j++) -- stm32_cryp_write(cryp, CRYP_DIN, 0); -- -- /* Wait for completion */ -- err = stm32_cryp_wait_busy(cryp); -- if (err) { -- dev_err(cryp->dev, "Timeout (gcm header)\n"); -- return stm32_cryp_finish_req(cryp, err); -- } -- -- if (stm32_cryp_get_input_text_len(cryp)) { -- /* Phase 3 : payload */ -- cfg = stm32_cryp_read(cryp, CRYP_CR); -- cfg &= ~CR_CRYPEN; -- stm32_cryp_write(cryp, CRYP_CR, cfg); -- -- cfg &= ~CR_PH_MASK; -- cfg |= CR_PH_PAYLOAD; -- cfg |= CR_CRYPEN; -- stm32_cryp_write(cryp, CRYP_CR, cfg); -- } else { -- /* Phase 4 : tag */ -- stm32_cryp_write(cryp, CRYP_IMSCR, 0); -- stm32_cryp_finish_req(cryp, 0); -- } -- -- break; -- } -- -- if (!cryp->total_in) -- break; -- } --} -+ unsigned int i; -+ u32 block[AES_BLOCK_32] = {0}; -+ size_t written; - --static void stm32_cryp_irq_write_ccm_header(struct stm32_cryp *cryp) --{ -- int err; -- unsigned int i = 0, j, k; -- u32 alen, cfg, *src; -- u8 d8[4]; -- -- src = sg_virt(cryp->in_sg) + _walked_in; -- alen = cryp->areq->assoclen; -- -- if (!_walked_in) { -- if (cryp->areq->assoclen <= 65280) { -- /* Write first u32 of B1 */ -- d8[0] = (alen >> 8) & 0xFF; -- d8[1] = alen & 0xFF; -- d8[2] = *((u8 *)src); -- src = stm32_cryp_next_in(cryp, src, 1); -- d8[3] = *((u8 *)src); -- src = stm32_cryp_next_in(cryp, src, 1); -- -- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); -- i++; -- -- cryp->total_in -= min_t(size_t, 2, cryp->total_in); -- } else { -- /* Build the two first u32 of B1 */ -- d8[0] = 0xFF; -- d8[1] = 0xFE; -- d8[2] = alen & 0xFF000000; -- d8[3] = alen & 0x00FF0000; -- -- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); -- i++; -- -- d8[0] = alen & 0x0000FF00; -- d8[1] = alen & 0x000000FF; -- d8[2] = *((u8 *)src); -- src = stm32_cryp_next_in(cryp, src, 1); -- d8[3] = *((u8 *)src); -- src = stm32_cryp_next_in(cryp, src, 1); -- -- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); -- i++; -- -- cryp->total_in -= min_t(size_t, 2, cryp->total_in); -- } -- } -+ written = min_t(size_t, AES_BLOCK_SIZE, cryp->header_in); - -- /* Write next u32 */ -- for (; i < AES_BLOCK_32; i++) { -- /* Build an u32 */ -- memset(d8, 0, sizeof(u32)); -- for (k = 0; k < sizeof(u32); k++) { -- d8[k] = *((u8 *)src); -- src = stm32_cryp_next_in(cryp, src, 1); -- -- cryp->total_in -= min_t(size_t, 1, cryp->total_in); -- if ((cryp->total_in_save - cryp->total_in) == alen) -- break; -- } -+ scatterwalk_copychunks(block, &cryp->in_walk, written, 0); -+ for (i = 0; i < AES_BLOCK_32; i++) -+ stm32_cryp_write(cryp, CRYP_DIN, block[i]); - -- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); -- -- if ((cryp->total_in_save - cryp->total_in) == alen) { -- /* Write padding if needed */ -- for (j = i + 1; j < AES_BLOCK_32; j++) -- stm32_cryp_write(cryp, CRYP_DIN, 0); -- -- /* Wait for completion */ -- err = stm32_cryp_wait_busy(cryp); -- if (err) { -- dev_err(cryp->dev, "Timeout (ccm header)\n"); -- return stm32_cryp_finish_req(cryp, err); -- } -- -- if (stm32_cryp_get_input_text_len(cryp)) { -- /* Phase 3 : payload */ -- cfg = stm32_cryp_read(cryp, CRYP_CR); -- cfg &= ~CR_CRYPEN; -- stm32_cryp_write(cryp, CRYP_CR, cfg); -- -- cfg &= ~CR_PH_MASK; -- cfg |= CR_PH_PAYLOAD; -- cfg |= CR_CRYPEN; -- stm32_cryp_write(cryp, CRYP_CR, cfg); -- } else { -- /* Phase 4 : tag */ -- stm32_cryp_write(cryp, CRYP_IMSCR, 0); -- stm32_cryp_finish_req(cryp, 0); -- } -+ cryp->header_in -= written; - -- break; -- } -- } -+ stm32_crypt_gcmccm_end_header(cryp); - } - - static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg) - { - struct stm32_cryp *cryp = arg; - u32 ph; -+ u32 it_mask = stm32_cryp_read(cryp, CRYP_IMSCR); - - if (cryp->irq_status & MISR_OUT) - /* Output FIFO IRQ: read data */ -- if (unlikely(stm32_cryp_irq_read_data(cryp))) { -- /* All bytes processed, finish */ -- stm32_cryp_write(cryp, CRYP_IMSCR, 0); -- stm32_cryp_finish_req(cryp, 0); -- return IRQ_HANDLED; -- } -+ stm32_cryp_irq_read_data(cryp); - - if (cryp->irq_status & MISR_IN) { -- if (is_gcm(cryp)) { -+ if (is_gcm(cryp) || is_ccm(cryp)) { - ph = stm32_cryp_read(cryp, CRYP_CR) & CR_PH_MASK; - if (unlikely(ph == CR_PH_HEADER)) - /* Write Header */ -- stm32_cryp_irq_write_gcm_header(cryp); -- else -- /* Input FIFO IRQ: write data */ -- stm32_cryp_irq_write_data(cryp); -- cryp->gcm_ctr++; -- } else if (is_ccm(cryp)) { -- ph = stm32_cryp_read(cryp, CRYP_CR) & CR_PH_MASK; -- if (unlikely(ph == CR_PH_HEADER)) -- /* Write Header */ -- stm32_cryp_irq_write_ccm_header(cryp); -+ stm32_cryp_irq_write_gcmccm_header(cryp); - else - /* Input FIFO IRQ: write data */ - stm32_cryp_irq_write_data(cryp); -+ if (is_gcm(cryp)) -+ cryp->gcm_ctr++; - } else { - /* Input FIFO IRQ: write data */ - stm32_cryp_irq_write_data(cryp); - } - } - -+ /* Mask useless interrupts */ -+ if (!cryp->payload_in && !cryp->header_in) -+ it_mask &= ~IMSCR_IN; -+ if (!cryp->payload_out) -+ it_mask &= ~IMSCR_OUT; -+ stm32_cryp_write(cryp, CRYP_IMSCR, it_mask); -+ -+ if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) -+ stm32_cryp_finish_req(cryp, 0); -+ - return IRQ_HANDLED; - } - -@@ -1742,7 +1548,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = AES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1759,7 +1565,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = AES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1777,7 +1583,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = 1, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1795,7 +1601,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = DES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1812,7 +1618,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = DES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1830,7 +1636,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = DES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1847,7 +1653,7 @@ static struct skcipher_alg crypto_algs[] = { - .base.cra_flags = CRYPTO_ALG_ASYNC, - .base.cra_blocksize = DES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .base.cra_alignmask = 0xf, -+ .base.cra_alignmask = 0, - .base.cra_module = THIS_MODULE, - - .init = stm32_cryp_init_tfm, -@@ -1877,7 +1683,7 @@ static struct aead_alg aead_algs[] = { - .cra_flags = CRYPTO_ALG_ASYNC, - .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .cra_alignmask = 0xf, -+ .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - }, -@@ -1897,7 +1703,7 @@ static struct aead_alg aead_algs[] = { - .cra_flags = CRYPTO_ALG_ASYNC, - .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct stm32_cryp_ctx), -- .cra_alignmask = 0xf, -+ .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - }, -@@ -2025,8 +1831,6 @@ err_engine1: - list_del(&cryp->list); - spin_unlock(&cryp_list.lock); - -- pm_runtime_disable(dev); -- pm_runtime_put_noidle(dev); - pm_runtime_disable(dev); - pm_runtime_put_noidle(dev); - -diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c -index 389de9e3302d5..d33006d43f761 100644 ---- a/drivers/crypto/stm32/stm32-hash.c -+++ b/drivers/crypto/stm32/stm32-hash.c -@@ -813,7 +813,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err) - static int stm32_hash_hw_init(struct stm32_hash_dev *hdev, - struct stm32_hash_request_ctx *rctx) - { -- pm_runtime_resume_and_get(hdev->dev); -+ pm_runtime_get_sync(hdev->dev); - - if (!(HASH_FLAGS_INIT & hdev->flags)) { - stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT); -@@ -962,7 +962,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out) - u32 *preg; - unsigned int i; - -- pm_runtime_resume_and_get(hdev->dev); -+ pm_runtime_get_sync(hdev->dev); - - while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY)) - cpu_relax(); -@@ -1000,7 +1000,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in) - - preg = rctx->hw_context; - -- pm_runtime_resume_and_get(hdev->dev); -+ pm_runtime_get_sync(hdev->dev); - - stm32_hash_write(hdev, HASH_IMR, *preg++); - stm32_hash_write(hdev, HASH_STR, *preg++); -diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c -index 8e45aa07d662f..5444b5a7fd3c4 100644 ---- a/drivers/cxl/pci.c -+++ b/drivers/cxl/pci.c -@@ -972,7 +972,7 @@ static void __iomem *cxl_mem_map_regblock(struct cxl_mem *cxlm, - if (pci_resource_len(pdev, bar) < offset) { - dev_err(dev, "BAR%d: %pr: too small (offset: %#llx)\n", bar, - &pdev->resource[bar], (unsigned long long)offset); -- return IOMEM_ERR_PTR(-ENXIO); -+ return NULL; - } - - addr = pci_iomap(pdev, bar, 0); -diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c -index 9652c3ee41e7f..2bb2f9a0499f7 100644 ---- a/drivers/cxl/pmem.c -+++ b/drivers/cxl/pmem.c -@@ -149,14 +149,24 @@ static void cxl_nvb_update_state(struct work_struct *work) - put_device(&cxl_nvb->dev); - } - -+static void cxl_nvdimm_bridge_state_work(struct cxl_nvdimm_bridge *cxl_nvb) -+{ -+ /* -+ * Take a reference that the workqueue will drop if new work -+ * gets queued. -+ */ -+ get_device(&cxl_nvb->dev); -+ if (!queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) -+ put_device(&cxl_nvb->dev); -+} -+ - static void cxl_nvdimm_bridge_remove(struct device *dev) - { - struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); - - if (cxl_nvb->state == CXL_NVB_ONLINE) - cxl_nvb->state = CXL_NVB_OFFLINE; -- if (queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) -- get_device(&cxl_nvb->dev); -+ cxl_nvdimm_bridge_state_work(cxl_nvb); - } - - static int cxl_nvdimm_bridge_probe(struct device *dev) -@@ -177,8 +187,7 @@ static int cxl_nvdimm_bridge_probe(struct device *dev) - } - - cxl_nvb->state = CXL_NVB_ONLINE; -- if (queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) -- get_device(&cxl_nvb->dev); -+ cxl_nvdimm_bridge_state_work(cxl_nvb); - - return 0; - } -diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c -index 63d32261b63ff..61e20ae7b08b7 100644 ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -74,7 +74,7 @@ static void dma_buf_release(struct dentry *dentry) - * If you hit this BUG() it means someone dropped their ref to the - * dma-buf while still having pending operation to the buffer. - */ -- BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active); -+ BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active); - - dma_buf_stats_teardown(dmabuf); - dmabuf->ops->release(dmabuf); -@@ -82,6 +82,7 @@ static void dma_buf_release(struct dentry *dentry) - if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) - dma_resv_fini(dmabuf->resv); - -+ WARN_ON(!list_empty(&dmabuf->attachments)); - module_put(dmabuf->owner); - kfree(dmabuf->name); - kfree(dmabuf); -@@ -205,16 +206,55 @@ static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb) - wake_up_locked_poll(dcb->poll, dcb->active); - dcb->active = 0; - spin_unlock_irqrestore(&dcb->poll->lock, flags); -+ dma_fence_put(fence); -+} -+ -+static bool dma_buf_poll_shared(struct dma_resv *resv, -+ struct dma_buf_poll_cb_t *dcb) -+{ -+ struct dma_resv_list *fobj = dma_resv_shared_list(resv); -+ struct dma_fence *fence; -+ int i, r; -+ -+ if (!fobj) -+ return false; -+ -+ for (i = 0; i < fobj->shared_count; ++i) { -+ fence = rcu_dereference_protected(fobj->shared[i], -+ dma_resv_held(resv)); -+ dma_fence_get(fence); -+ r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb); -+ if (!r) -+ return true; -+ dma_fence_put(fence); -+ } -+ -+ return false; -+} -+ -+static bool dma_buf_poll_excl(struct dma_resv *resv, -+ struct dma_buf_poll_cb_t *dcb) -+{ -+ struct dma_fence *fence = dma_resv_excl_fence(resv); -+ int r; -+ -+ if (!fence) -+ return false; -+ -+ dma_fence_get(fence); -+ r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb); -+ if (!r) -+ return true; -+ dma_fence_put(fence); -+ -+ return false; - } - - static __poll_t dma_buf_poll(struct file *file, poll_table *poll) - { - struct dma_buf *dmabuf; - struct dma_resv *resv; -- struct dma_resv_list *fobj; -- struct dma_fence *fence_excl; - __poll_t events; -- unsigned shared_count, seq; - - dmabuf = file->private_data; - if (!dmabuf || !dmabuf->resv) -@@ -228,101 +268,50 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) - if (!events) - return 0; - --retry: -- seq = read_seqcount_begin(&resv->seq); -- rcu_read_lock(); -- -- fobj = rcu_dereference(resv->fence); -- if (fobj) -- shared_count = fobj->shared_count; -- else -- shared_count = 0; -- fence_excl = dma_resv_excl_fence(resv); -- if (read_seqcount_retry(&resv->seq, seq)) { -- rcu_read_unlock(); -- goto retry; -- } -- -- if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) { -- struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl; -- __poll_t pevents = EPOLLIN; -+ dma_resv_lock(resv, NULL); - -- if (shared_count == 0) -- pevents |= EPOLLOUT; -+ if (events & EPOLLOUT) { -+ struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_out; - -+ /* Check that callback isn't busy */ - spin_lock_irq(&dmabuf->poll.lock); -- if (dcb->active) { -- dcb->active |= pevents; -- events &= ~pevents; -- } else -- dcb->active = pevents; -+ if (dcb->active) -+ events &= ~EPOLLOUT; -+ else -+ dcb->active = EPOLLOUT; - spin_unlock_irq(&dmabuf->poll.lock); - -- if (events & pevents) { -- if (!dma_fence_get_rcu(fence_excl)) { -- /* force a recheck */ -- events &= ~pevents; -- dma_buf_poll_cb(NULL, &dcb->cb); -- } else if (!dma_fence_add_callback(fence_excl, &dcb->cb, -- dma_buf_poll_cb)) { -- events &= ~pevents; -- dma_fence_put(fence_excl); -- } else { -- /* -- * No callback queued, wake up any additional -- * waiters. -- */ -- dma_fence_put(fence_excl); -+ if (events & EPOLLOUT) { -+ if (!dma_buf_poll_shared(resv, dcb) && -+ !dma_buf_poll_excl(resv, dcb)) -+ /* No callback queued, wake up any other waiters */ - dma_buf_poll_cb(NULL, &dcb->cb); -- } -+ else -+ events &= ~EPOLLOUT; - } - } - -- if ((events & EPOLLOUT) && shared_count > 0) { -- struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_shared; -- int i; -+ if (events & EPOLLIN) { -+ struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_in; - -- /* Only queue a new callback if no event has fired yet */ -+ /* Check that callback isn't busy */ - spin_lock_irq(&dmabuf->poll.lock); - if (dcb->active) -- events &= ~EPOLLOUT; -+ events &= ~EPOLLIN; - else -- dcb->active = EPOLLOUT; -+ dcb->active = EPOLLIN; - spin_unlock_irq(&dmabuf->poll.lock); - -- if (!(events & EPOLLOUT)) -- goto out; -- -- for (i = 0; i < shared_count; ++i) { -- struct dma_fence *fence = rcu_dereference(fobj->shared[i]); -- -- if (!dma_fence_get_rcu(fence)) { -- /* -- * fence refcount dropped to zero, this means -- * that fobj has been freed -- * -- * call dma_buf_poll_cb and force a recheck! -- */ -- events &= ~EPOLLOUT; -+ if (events & EPOLLIN) { -+ if (!dma_buf_poll_excl(resv, dcb)) -+ /* No callback queued, wake up any other waiters */ - dma_buf_poll_cb(NULL, &dcb->cb); -- break; -- } -- if (!dma_fence_add_callback(fence, &dcb->cb, -- dma_buf_poll_cb)) { -- dma_fence_put(fence); -- events &= ~EPOLLOUT; -- break; -- } -- dma_fence_put(fence); -+ else -+ events &= ~EPOLLIN; - } -- -- /* No callback queued, wake up any additional waiters. */ -- if (i == shared_count) -- dma_buf_poll_cb(NULL, &dcb->cb); - } - --out: -- rcu_read_unlock(); -+ dma_resv_unlock(resv); - return events; - } - -@@ -565,8 +554,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) - dmabuf->owner = exp_info->owner; - spin_lock_init(&dmabuf->name_lock); - init_waitqueue_head(&dmabuf->poll); -- dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll; -- dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0; -+ dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll; -+ dmabuf->cb_in.active = dmabuf->cb_out.active = 0; - - if (!resv) { - resv = (struct dma_resv *)&dmabuf[1]; -diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c -index d3fbd950be944..3e07f961e2f3d 100644 ---- a/drivers/dma-buf/dma-fence-array.c -+++ b/drivers/dma-buf/dma-fence-array.c -@@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(struct dma_fence *fence) - { - struct dma_fence_array *array = to_dma_fence_array(fence); - -- return atomic_read(&array->num_pending) <= 0; -+ if (atomic_read(&array->num_pending) > 0) -+ return false; -+ -+ dma_fence_array_clear_pending_error(array); -+ return true; - } - - static void dma_fence_array_release(struct dma_fence *fence) -diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c -index 56bf5ad01ad54..8f5848aa144fe 100644 ---- a/drivers/dma-buf/dma-heap.c -+++ b/drivers/dma-buf/dma-heap.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -135,6 +136,7 @@ static long dma_heap_ioctl(struct file *file, unsigned int ucmd, - if (nr >= ARRAY_SIZE(dma_heap_ioctl_cmds)) - return -EINVAL; - -+ nr = array_index_nospec(nr, ARRAY_SIZE(dma_heap_ioctl_cmds)); - /* Get the kernel ioctl cmd that matches */ - kcmd = dma_heap_ioctl_cmds[nr]; - -diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c -index 0c05b79870f96..83f02bd51dda6 100644 ---- a/drivers/dma-buf/heaps/cma_heap.c -+++ b/drivers/dma-buf/heaps/cma_heap.c -@@ -124,10 +124,11 @@ static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - struct cma_heap_buffer *buffer = dmabuf->priv; - struct dma_heap_attachment *a; - -+ mutex_lock(&buffer->lock); -+ - if (buffer->vmap_cnt) - invalidate_kernel_vmap_range(buffer->vaddr, buffer->len); - -- mutex_lock(&buffer->lock); - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; -@@ -144,10 +145,11 @@ static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - struct cma_heap_buffer *buffer = dmabuf->priv; - struct dma_heap_attachment *a; - -+ mutex_lock(&buffer->lock); -+ - if (buffer->vmap_cnt) - flush_kernel_vmap_range(buffer->vaddr, buffer->len); - -- mutex_lock(&buffer->lock); - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; -diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c -index 23a7e74ef9666..8660508f3684f 100644 ---- a/drivers/dma-buf/heaps/system_heap.c -+++ b/drivers/dma-buf/heaps/system_heap.c -@@ -289,7 +289,7 @@ static void system_heap_dma_buf_release(struct dma_buf *dmabuf) - int i; - - table = &buffer->sg_table; -- for_each_sg(table->sgl, sg, table->nents, i) { -+ for_each_sgtable_sg(table, sg, i) { - struct page *page = sg_page(sg); - - __free_pages(page, compound_order(page)); -diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c -index ab78e0f6afd70..8177aed160060 100644 ---- a/drivers/dma/at_xdmac.c -+++ b/drivers/dma/at_xdmac.c -@@ -99,6 +99,7 @@ - #define AT_XDMAC_CNDC_NDE (0x1 << 0) /* Channel x Next Descriptor Enable */ - #define AT_XDMAC_CNDC_NDSUP (0x1 << 1) /* Channel x Next Descriptor Source Update */ - #define AT_XDMAC_CNDC_NDDUP (0x1 << 2) /* Channel x Next Descriptor Destination Update */ -+#define AT_XDMAC_CNDC_NDVIEW_MASK GENMASK(28, 27) - #define AT_XDMAC_CNDC_NDVIEW_NDV0 (0x0 << 3) /* Channel x Next Descriptor View 0 */ - #define AT_XDMAC_CNDC_NDVIEW_NDV1 (0x1 << 3) /* Channel x Next Descriptor View 1 */ - #define AT_XDMAC_CNDC_NDVIEW_NDV2 (0x2 << 3) /* Channel x Next Descriptor View 2 */ -@@ -155,7 +156,7 @@ - #define AT_XDMAC_CC_WRIP (0x1 << 23) /* Write in Progress (read only) */ - #define AT_XDMAC_CC_WRIP_DONE (0x0 << 23) - #define AT_XDMAC_CC_WRIP_IN_PROGRESS (0x1 << 23) --#define AT_XDMAC_CC_PERID(i) (0x7f & (i) << 24) /* Channel Peripheral Identifier */ -+#define AT_XDMAC_CC_PERID(i) ((0x7f & (i)) << 24) /* Channel Peripheral Identifier */ - #define AT_XDMAC_CDS_MSP 0x2C /* Channel Data Stride Memory Set Pattern */ - #define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */ - #define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */ -@@ -252,15 +253,15 @@ struct at_xdmac { - - /* Linked List Descriptor */ - struct at_xdmac_lld { -- dma_addr_t mbr_nda; /* Next Descriptor Member */ -- u32 mbr_ubc; /* Microblock Control Member */ -- dma_addr_t mbr_sa; /* Source Address Member */ -- dma_addr_t mbr_da; /* Destination Address Member */ -- u32 mbr_cfg; /* Configuration Register */ -- u32 mbr_bc; /* Block Control Register */ -- u32 mbr_ds; /* Data Stride Register */ -- u32 mbr_sus; /* Source Microblock Stride Register */ -- u32 mbr_dus; /* Destination Microblock Stride Register */ -+ u32 mbr_nda; /* Next Descriptor Member */ -+ u32 mbr_ubc; /* Microblock Control Member */ -+ u32 mbr_sa; /* Source Address Member */ -+ u32 mbr_da; /* Destination Address Member */ -+ u32 mbr_cfg; /* Configuration Register */ -+ u32 mbr_bc; /* Block Control Register */ -+ u32 mbr_ds; /* Data Stride Register */ -+ u32 mbr_sus; /* Source Microblock Stride Register */ -+ u32 mbr_dus; /* Destination Microblock Stride Register */ - }; - - /* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */ -@@ -385,9 +386,6 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, - - dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first); - -- if (at_xdmac_chan_is_enabled(atchan)) -- return; -- - /* Set transfer as active to not try to start it again. */ - first->active_xfer = true; - -@@ -405,7 +403,8 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, - */ - if (at_xdmac_chan_is_cyclic(atchan)) - reg = AT_XDMAC_CNDC_NDVIEW_NDV1; -- else if (first->lld.mbr_ubc & AT_XDMAC_MBR_UBC_NDV3) -+ else if ((first->lld.mbr_ubc & -+ AT_XDMAC_CNDC_NDVIEW_MASK) == AT_XDMAC_MBR_UBC_NDV3) - reg = AT_XDMAC_CNDC_NDVIEW_NDV3; - else - reg = AT_XDMAC_CNDC_NDVIEW_NDV2; -@@ -476,13 +475,12 @@ static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx) - spin_lock_irqsave(&atchan->lock, irqflags); - cookie = dma_cookie_assign(tx); - -+ list_add_tail(&desc->xfer_node, &atchan->xfers_list); -+ spin_unlock_irqrestore(&atchan->lock, irqflags); -+ - dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", - __func__, atchan, desc); -- list_add_tail(&desc->xfer_node, &atchan->xfers_list); -- if (list_is_singular(&atchan->xfers_list)) -- at_xdmac_start_xfer(atchan, desc); - -- spin_unlock_irqrestore(&atchan->lock, irqflags); - return cookie; - } - -@@ -1623,14 +1621,17 @@ static void at_xdmac_handle_cyclic(struct at_xdmac_chan *atchan) - struct at_xdmac_desc *desc; - struct dma_async_tx_descriptor *txd; - -- if (!list_empty(&atchan->xfers_list)) { -- desc = list_first_entry(&atchan->xfers_list, -- struct at_xdmac_desc, xfer_node); -- txd = &desc->tx_dma_desc; -- -- if (txd->flags & DMA_PREP_INTERRUPT) -- dmaengine_desc_get_callback_invoke(txd, NULL); -+ spin_lock_irq(&atchan->lock); -+ if (list_empty(&atchan->xfers_list)) { -+ spin_unlock_irq(&atchan->lock); -+ return; - } -+ desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, -+ xfer_node); -+ spin_unlock_irq(&atchan->lock); -+ txd = &desc->tx_dma_desc; -+ if (txd->flags & DMA_PREP_INTERRUPT) -+ dmaengine_desc_get_callback_invoke(txd, NULL); - } - - static void at_xdmac_handle_error(struct at_xdmac_chan *atchan) -@@ -1784,11 +1785,9 @@ static void at_xdmac_issue_pending(struct dma_chan *chan) - - dev_dbg(chan2dev(&atchan->chan), "%s\n", __func__); - -- if (!at_xdmac_chan_is_cyclic(atchan)) { -- spin_lock_irqsave(&atchan->lock, flags); -- at_xdmac_advance_work(atchan); -- spin_unlock_irqrestore(&atchan->lock, flags); -- } -+ spin_lock_irqsave(&atchan->lock, flags); -+ at_xdmac_advance_work(atchan); -+ spin_unlock_irqrestore(&atchan->lock, flags); - - return; - } -@@ -1926,6 +1925,30 @@ static void at_xdmac_free_chan_resources(struct dma_chan *chan) - return; - } - -+static void at_xdmac_axi_config(struct platform_device *pdev) -+{ -+ struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); -+ bool dev_m2m = false; -+ u32 dma_requests; -+ -+ if (!atxdmac->layout->axi_config) -+ return; /* Not supported */ -+ -+ if (!of_property_read_u32(pdev->dev.of_node, "dma-requests", -+ &dma_requests)) { -+ dev_info(&pdev->dev, "controller in mem2mem mode.\n"); -+ dev_m2m = true; -+ } -+ -+ if (dev_m2m) { -+ at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_M2M); -+ at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_M2M); -+ } else { -+ at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_P2M); -+ at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_P2M); -+ } -+} -+ - #ifdef CONFIG_PM - static int atmel_xdmac_prepare(struct device *dev) - { -@@ -1975,6 +1998,7 @@ static int atmel_xdmac_resume(struct device *dev) - struct at_xdmac *atxdmac = dev_get_drvdata(dev); - struct at_xdmac_chan *atchan; - struct dma_chan *chan, *_chan; -+ struct platform_device *pdev = container_of(dev, struct platform_device, dev); - int i; - int ret; - -@@ -1982,6 +2006,8 @@ static int atmel_xdmac_resume(struct device *dev) - if (ret) - return ret; - -+ at_xdmac_axi_config(pdev); -+ - /* Clear pending interrupts. */ - for (i = 0; i < atxdmac->dma.chancnt; i++) { - atchan = &atxdmac->chan[i]; -@@ -2007,30 +2033,6 @@ static int atmel_xdmac_resume(struct device *dev) - } - #endif /* CONFIG_PM_SLEEP */ - --static void at_xdmac_axi_config(struct platform_device *pdev) --{ -- struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); -- bool dev_m2m = false; -- u32 dma_requests; -- -- if (!atxdmac->layout->axi_config) -- return; /* Not supported */ -- -- if (!of_property_read_u32(pdev->dev.of_node, "dma-requests", -- &dma_requests)) { -- dev_info(&pdev->dev, "controller in mem2mem mode.\n"); -- dev_m2m = true; -- } -- -- if (dev_m2m) { -- at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_M2M); -- at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_M2M); -- } else { -- at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_P2M); -- at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_P2M); -- } --} -- - static int at_xdmac_probe(struct platform_device *pdev) - { - struct at_xdmac *atxdmac; -diff --git a/drivers/dma/bestcomm/ata.c b/drivers/dma/bestcomm/ata.c -index 2fd87f83cf90b..e169f18da551f 100644 ---- a/drivers/dma/bestcomm/ata.c -+++ b/drivers/dma/bestcomm/ata.c -@@ -133,7 +133,7 @@ void bcom_ata_reset_bd(struct bcom_task *tsk) - struct bcom_ata_var *var; - - /* Reset all BD */ -- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); -+ memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); - - tsk->index = 0; - tsk->outdex = 0; -diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c -index d91cbbe7a48fb..8c42e5ca00a99 100644 ---- a/drivers/dma/bestcomm/bestcomm.c -+++ b/drivers/dma/bestcomm/bestcomm.c -@@ -95,7 +95,7 @@ bcom_task_alloc(int bd_count, int bd_size, int priv_size) - tsk->bd = bcom_sram_alloc(bd_count * bd_size, 4, &tsk->bd_pa); - if (!tsk->bd) - goto error; -- memset(tsk->bd, 0x00, bd_count * bd_size); -+ memset_io(tsk->bd, 0x00, bd_count * bd_size); - - tsk->num_bd = bd_count; - tsk->bd_size = bd_size; -@@ -186,16 +186,16 @@ bcom_load_image(int task, u32 *task_image) - inc = bcom_task_inc(task); - - /* Clear & copy */ -- memset(var, 0x00, BCOM_VAR_SIZE); -- memset(inc, 0x00, BCOM_INC_SIZE); -+ memset_io(var, 0x00, BCOM_VAR_SIZE); -+ memset_io(inc, 0x00, BCOM_INC_SIZE); - - desc_src = (u32 *)(hdr + 1); - var_src = desc_src + hdr->desc_size; - inc_src = var_src + hdr->var_size; - -- memcpy(desc, desc_src, hdr->desc_size * sizeof(u32)); -- memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32)); -- memcpy(inc, inc_src, hdr->inc_size * sizeof(u32)); -+ memcpy_toio(desc, desc_src, hdr->desc_size * sizeof(u32)); -+ memcpy_toio(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32)); -+ memcpy_toio(inc, inc_src, hdr->inc_size * sizeof(u32)); - - return 0; - } -@@ -302,13 +302,13 @@ static int bcom_engine_init(void) - return -ENOMEM; - } - -- memset(bcom_eng->tdt, 0x00, tdt_size); -- memset(bcom_eng->ctx, 0x00, ctx_size); -- memset(bcom_eng->var, 0x00, var_size); -- memset(bcom_eng->fdt, 0x00, fdt_size); -+ memset_io(bcom_eng->tdt, 0x00, tdt_size); -+ memset_io(bcom_eng->ctx, 0x00, ctx_size); -+ memset_io(bcom_eng->var, 0x00, var_size); -+ memset_io(bcom_eng->fdt, 0x00, fdt_size); - - /* Copy the FDT for the EU#3 */ -- memcpy(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops)); -+ memcpy_toio(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops)); - - /* Initialize Task base structure */ - for (task=0; taskindex = 0; - tsk->outdex = 0; - -- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); -+ memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); - - /* Configure some stuff */ - bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_RX_BD_PRAGMA); -@@ -241,7 +241,7 @@ bcom_fec_tx_reset(struct bcom_task *tsk) - tsk->index = 0; - tsk->outdex = 0; - -- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); -+ memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); - - /* Configure some stuff */ - bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA); -diff --git a/drivers/dma/bestcomm/gen_bd.c b/drivers/dma/bestcomm/gen_bd.c -index 906ddba6a6f5d..8a24a5cbc2633 100644 ---- a/drivers/dma/bestcomm/gen_bd.c -+++ b/drivers/dma/bestcomm/gen_bd.c -@@ -142,7 +142,7 @@ bcom_gen_bd_rx_reset(struct bcom_task *tsk) - tsk->index = 0; - tsk->outdex = 0; - -- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); -+ memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); - - /* Configure some stuff */ - bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_RX_BD_PRAGMA); -@@ -226,7 +226,7 @@ bcom_gen_bd_tx_reset(struct bcom_task *tsk) - tsk->index = 0; - tsk->outdex = 0; - -- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); -+ memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); - - /* Configure some stuff */ - bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA); -diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h -index 1bfbd64b13717..53f16d3f00294 100644 ---- a/drivers/dma/dmaengine.h -+++ b/drivers/dma/dmaengine.h -@@ -176,7 +176,7 @@ dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx, - static inline bool - dmaengine_desc_callback_valid(struct dmaengine_desc_callback *cb) - { -- return (cb->callback) ? true : false; -+ return cb->callback || cb->callback_result; - } - - struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); -diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c -index 83a5ff2ecf2a0..b468ca36d3a01 100644 ---- a/drivers/dma/idxd/device.c -+++ b/drivers/dma/idxd/device.c -@@ -394,8 +394,6 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) - lockdep_assert_held(&wq->wq_lock); - memset(wq->wqcfg, 0, idxd->wqcfg_size); - wq->type = IDXD_WQT_NONE; -- wq->size = 0; -- wq->group = NULL; - wq->threshold = 0; - wq->priority = 0; - wq->ats_dis = 0; -@@ -404,6 +402,15 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) - memset(wq->name, 0, WQ_NAME_SIZE); - } - -+static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq) -+{ -+ lockdep_assert_held(&wq->wq_lock); -+ -+ idxd_wq_disable_cleanup(wq); -+ wq->size = 0; -+ wq->group = NULL; -+} -+ - static void idxd_wq_ref_release(struct percpu_ref *ref) - { - struct idxd_wq *wq = container_of(ref, struct idxd_wq, wq_active); -@@ -427,7 +434,6 @@ void idxd_wq_quiesce(struct idxd_wq *wq) - { - percpu_ref_kill(&wq->wq_active); - wait_for_completion(&wq->wq_dead); -- percpu_ref_exit(&wq->wq_active); - } - - /* Device control bits */ -@@ -584,6 +590,8 @@ void idxd_device_reset(struct idxd_device *idxd) - spin_lock(&idxd->dev_lock); - idxd_device_clear_state(idxd); - idxd->state = IDXD_DEV_DISABLED; -+ idxd_unmask_error_interrupts(idxd); -+ idxd_msix_perm_setup(idxd); - spin_unlock(&idxd->dev_lock); - } - -@@ -710,6 +718,7 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd) - - if (wq->state == IDXD_WQ_ENABLED) { - idxd_wq_disable_cleanup(wq); -+ idxd_wq_device_reset_cleanup(wq); - wq->state = IDXD_WQ_DISABLED; - } - } -diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c -index e0f056c1d1f56..c39e9483206ad 100644 ---- a/drivers/dma/idxd/dma.c -+++ b/drivers/dma/idxd/dma.c -@@ -311,6 +311,7 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev) - - err_dma: - idxd_wq_quiesce(wq); -+ percpu_ref_exit(&wq->wq_active); - err_ref: - idxd_wq_free_resources(wq); - err_res_alloc: -@@ -328,9 +329,9 @@ static void idxd_dmaengine_drv_remove(struct idxd_dev *idxd_dev) - mutex_lock(&wq->wq_lock); - idxd_wq_quiesce(wq); - idxd_unregister_dma_channel(wq); -- __drv_disable_wq(wq); - idxd_wq_free_resources(wq); -- wq->type = IDXD_WQT_NONE; -+ __drv_disable_wq(wq); -+ percpu_ref_exit(&wq->wq_active); - mutex_unlock(&wq->wq_lock); - } - -diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c -index eb09bc591c316..7bf03f371ce19 100644 ---- a/drivers/dma/idxd/init.c -+++ b/drivers/dma/idxd/init.c -@@ -797,11 +797,19 @@ static void idxd_remove(struct pci_dev *pdev) - int msixcnt = pci_msix_vec_count(pdev); - int i; - -- dev_dbg(&pdev->dev, "%s called\n", __func__); -+ idxd_unregister_devices(idxd); -+ /* -+ * When ->release() is called for the idxd->conf_dev, it frees all the memory related -+ * to the idxd context. The driver still needs those bits in order to do the rest of -+ * the cleanup. However, we do need to unbound the idxd sub-driver. So take a ref -+ * on the device here to hold off the freeing while allowing the idxd sub-driver -+ * to unbind. -+ */ -+ get_device(idxd_confdev(idxd)); -+ device_unregister(idxd_confdev(idxd)); - idxd_shutdown(pdev); - if (device_pasid_enabled(idxd)) - idxd_disable_system_pasid(idxd); -- idxd_unregister_devices(idxd); - - for (i = 0; i < msixcnt; i++) { - irq_entry = &idxd->irq_entries[i]; -@@ -815,7 +823,7 @@ static void idxd_remove(struct pci_dev *pdev) - pci_disable_device(pdev); - destroy_workqueue(idxd->wq); - perfmon_pmu_remove(idxd); -- device_unregister(idxd_confdev(idxd)); -+ put_device(idxd_confdev(idxd)); - } - - static struct pci_driver idxd_pci_driver = { -diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c -index ca88fa7a328e7..6d6af0dc3c0ec 100644 ---- a/drivers/dma/idxd/irq.c -+++ b/drivers/dma/idxd/irq.c -@@ -63,6 +63,9 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) - int i; - bool err = false; - -+ if (cause & IDXD_INTC_HALT_STATE) -+ goto halt; -+ - if (cause & IDXD_INTC_ERR) { - spin_lock(&idxd->dev_lock); - for (i = 0; i < 4; i++) -@@ -121,6 +124,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) - if (!err) - return 0; - -+halt: - gensts.bits = ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET); - if (gensts.state == IDXD_DEVICE_STATE_HALT) { - idxd->state = IDXD_DEV_HALTED; -@@ -133,9 +137,10 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) - INIT_WORK(&idxd->work, idxd_device_reinit); - queue_work(idxd->wq, &idxd->work); - } else { -- spin_lock(&idxd->dev_lock); -+ idxd->state = IDXD_DEV_HALTED; - idxd_wqs_quiesce(idxd); - idxd_wqs_unmap_portal(idxd); -+ spin_lock(&idxd->dev_lock); - idxd_device_clear_state(idxd); - dev_err(&idxd->pdev->dev, - "idxd halted, need %s.\n", -diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h -index ffc7550a77eeb..97ffb06de9b0d 100644 ---- a/drivers/dma/idxd/registers.h -+++ b/drivers/dma/idxd/registers.h -@@ -158,6 +158,7 @@ enum idxd_device_reset_type { - #define IDXD_INTC_CMD 0x02 - #define IDXD_INTC_OCCUPY 0x04 - #define IDXD_INTC_PERFMON_OVFL 0x08 -+#define IDXD_INTC_HALT_STATE 0x10 - - #define IDXD_CMD_OFFSET 0xa0 - union idxd_command_reg { -diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c -index de76fb4abac24..83452fbbb168b 100644 ---- a/drivers/dma/idxd/submit.c -+++ b/drivers/dma/idxd/submit.c -@@ -106,6 +106,7 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, - { - struct idxd_desc *d, *t, *found = NULL; - struct llist_node *head; -+ LIST_HEAD(flist); - - desc->completion->status = IDXD_COMP_DESC_ABORT; - /* -@@ -120,7 +121,11 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, - found = desc; - continue; - } -- list_add_tail(&desc->list, &ie->work_list); -+ -+ if (d->completion->status) -+ list_add_tail(&d->list, &flist); -+ else -+ list_add_tail(&d->list, &ie->work_list); - } - } - -@@ -130,6 +135,17 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, - - if (found) - complete_desc(found, IDXD_COMPLETE_ABORT); -+ -+ /* -+ * complete_desc() will return desc to allocator and the desc can be -+ * acquired by a different process and the desc->list can be modified. -+ * Delete desc from list so the list trasversing does not get corrupted -+ * by the other process. -+ */ -+ list_for_each_entry_safe(d, t, &flist, list) { -+ list_del_init(&d->list); -+ complete_desc(d, IDXD_COMPLETE_NORMAL); -+ } - } - - int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) -diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c -index 89f1814ff27a0..26d11885c50ec 100644 ---- a/drivers/dma/mmp_pdma.c -+++ b/drivers/dma/mmp_pdma.c -@@ -727,12 +727,6 @@ static int mmp_pdma_config_write(struct dma_chan *dchan, - - chan->dir = direction; - chan->dev_addr = addr; -- /* FIXME: drivers should be ported over to use the filter -- * function. Once that's done, the following two lines can -- * be removed. -- */ -- if (cfg->slave_id) -- chan->drcmr = cfg->slave_id; - - return 0; - } -diff --git a/drivers/dma/ptdma/ptdma-dev.c b/drivers/dma/ptdma/ptdma-dev.c -index 8a6bf291a73fe..daafea5bc35d9 100644 ---- a/drivers/dma/ptdma/ptdma-dev.c -+++ b/drivers/dma/ptdma/ptdma-dev.c -@@ -207,7 +207,7 @@ int pt_core_init(struct pt_device *pt) - if (!cmd_q->qbase) { - dev_err(dev, "unable to allocate command queue\n"); - ret = -ENOMEM; -- goto e_dma_alloc; -+ goto e_destroy_pool; - } - - cmd_q->qidx = 0; -@@ -229,8 +229,10 @@ int pt_core_init(struct pt_device *pt) - - /* Request an irq */ - ret = request_irq(pt->pt_irq, pt_core_irq_handler, 0, dev_name(pt->dev), pt); -- if (ret) -- goto e_pool; -+ if (ret) { -+ dev_err(dev, "unable to allocate an IRQ\n"); -+ goto e_free_dma; -+ } - - /* Update the device registers with queue information. */ - cmd_q->qcontrol &= ~CMD_Q_SIZE; -@@ -250,21 +252,20 @@ int pt_core_init(struct pt_device *pt) - /* Register the DMA engine support */ - ret = pt_dmaengine_register(pt); - if (ret) -- goto e_dmaengine; -+ goto e_free_irq; - - /* Set up debugfs entries */ - ptdma_debugfs_setup(pt); - - return 0; - --e_dmaengine: -+e_free_irq: - free_irq(pt->pt_irq, pt); - --e_dma_alloc: -+e_free_dma: - dma_free_coherent(dev, cmd_q->qsize, cmd_q->qbase, cmd_q->qbase_dma); - --e_pool: -- dev_err(dev, "unable to allocate an IRQ\n"); -+e_destroy_pool: - dma_pool_destroy(pt->cmd_q.dma_pool); - - return ret; -diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c -index 4a2a796e348c1..aa6e552249ab9 100644 ---- a/drivers/dma/pxa_dma.c -+++ b/drivers/dma/pxa_dma.c -@@ -910,13 +910,6 @@ static void pxad_get_config(struct pxad_chan *chan, - *dcmd |= PXA_DCMD_BURST16; - else if (maxburst == 32) - *dcmd |= PXA_DCMD_BURST32; -- -- /* FIXME: drivers should be ported over to use the filter -- * function. Once that's done, the following two lines can -- * be removed. -- */ -- if (chan->cfg.slave_id) -- chan->drcmr = chan->cfg.slave_id; - } - - static struct dma_async_tx_descriptor * -diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c -index 6885b3dcd7a97..f4c46b3b6d9d7 100644 ---- a/drivers/dma/sh/rcar-dmac.c -+++ b/drivers/dma/sh/rcar-dmac.c -@@ -1868,8 +1868,13 @@ static int rcar_dmac_probe(struct platform_device *pdev) - - dmac->dev = &pdev->dev; - platform_set_drvdata(pdev, dmac); -- dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); -- dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); -+ ret = dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); -+ if (ret) -+ return ret; -+ -+ ret = dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); -+ if (ret) -+ return ret; - - ret = rcar_dmac_parse_of(&pdev->dev, dmac); - if (ret < 0) -diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c -index 7f72b3f4cd1ae..19ac95c0098f0 100644 ---- a/drivers/dma/sh/shdma-base.c -+++ b/drivers/dma/sh/shdma-base.c -@@ -115,8 +115,10 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) - ret = pm_runtime_get(schan->dev); - - spin_unlock_irq(&schan->chan_lock); -- if (ret < 0) -+ if (ret < 0) { - dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret); -+ pm_runtime_put(schan->dev); -+ } - - pm_runtime_barrier(schan->dev); - -diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c -index 962b6e05287b5..d95c421877fb7 100644 ---- a/drivers/dma/st_fdma.c -+++ b/drivers/dma/st_fdma.c -@@ -874,4 +874,4 @@ MODULE_LICENSE("GPL v2"); - MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver"); - MODULE_AUTHOR("Ludovic.barre "); - MODULE_AUTHOR("Peter Griffin "); --MODULE_ALIAS("platform: " DRIVER_NAME); -+MODULE_ALIAS("platform:" DRIVER_NAME); -diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c -index 9063c727962ed..7dfc743ac4338 100644 ---- a/drivers/dma/stm32-dma.c -+++ b/drivers/dma/stm32-dma.c -@@ -270,7 +270,6 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len, - u32 threshold) - { - enum dma_slave_buswidth max_width; -- u64 addr = buf_addr; - - if (threshold == STM32_DMA_FIFO_THRESHOLD_FULL) - max_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -@@ -281,7 +280,7 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len, - max_width > DMA_SLAVE_BUSWIDTH_1_BYTE) - max_width = max_width >> 1; - -- if (do_div(addr, max_width)) -+ if (buf_addr & (max_width - 1)) - max_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - - return max_width; -@@ -753,8 +752,14 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, - if (src_bus_width < 0) - return src_bus_width; - -- /* Set memory burst size */ -- src_maxburst = STM32_DMA_MAX_BURST; -+ /* -+ * Set memory burst size - burst not possible if address is not aligned on -+ * the address boundary equal to the size of the transfer -+ */ -+ if (buf_addr & (buf_len - 1)) -+ src_maxburst = 1; -+ else -+ src_maxburst = STM32_DMA_MAX_BURST; - src_best_burst = stm32_dma_get_best_burst(buf_len, - src_maxburst, - fifoth, -@@ -803,8 +808,14 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, - if (dst_bus_width < 0) - return dst_bus_width; - -- /* Set memory burst size */ -- dst_maxburst = STM32_DMA_MAX_BURST; -+ /* -+ * Set memory burst size - burst not possible if address is not aligned on -+ * the address boundary equal to the size of the transfer -+ */ -+ if (buf_addr & (buf_len - 1)) -+ dst_maxburst = 1; -+ else -+ dst_maxburst = STM32_DMA_MAX_BURST; - dst_best_burst = stm32_dma_get_best_burst(buf_len, - dst_maxburst, - fifoth, -diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c -index a42164389ebc2..d5d55732adba1 100644 ---- a/drivers/dma/stm32-dmamux.c -+++ b/drivers/dma/stm32-dmamux.c -@@ -292,10 +292,12 @@ static int stm32_dmamux_probe(struct platform_device *pdev) - ret = of_dma_router_register(node, stm32_dmamux_route_allocate, - &stm32_dmamux->dmarouter); - if (ret) -- goto err_clk; -+ goto pm_disable; - - return 0; - -+pm_disable: -+ pm_runtime_disable(&pdev->dev); - err_clk: - clk_disable_unprepare(stm32_dmamux->clk); - -diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c -index 18cbd1e43c2e8..f17a9ffcd00da 100644 ---- a/drivers/dma/stm32-mdma.c -+++ b/drivers/dma/stm32-mdma.c -@@ -184,7 +184,7 @@ - #define STM32_MDMA_CTBR(x) (0x68 + 0x40 * (x)) - #define STM32_MDMA_CTBR_DBUS BIT(17) - #define STM32_MDMA_CTBR_SBUS BIT(16) --#define STM32_MDMA_CTBR_TSEL_MASK GENMASK(7, 0) -+#define STM32_MDMA_CTBR_TSEL_MASK GENMASK(5, 0) - #define STM32_MDMA_CTBR_TSEL(n) STM32_MDMA_SET(n, \ - STM32_MDMA_CTBR_TSEL_MASK) - -diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c -index b1115a6d1935c..d1dff3a29db59 100644 ---- a/drivers/dma/tegra210-adma.c -+++ b/drivers/dma/tegra210-adma.c -@@ -867,7 +867,7 @@ static int tegra_adma_probe(struct platform_device *pdev) - - pm_runtime_enable(&pdev->dev); - -- ret = pm_runtime_get_sync(&pdev->dev); -+ ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret < 0) - goto rpm_disable; - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index a35858610780c..041d8e32d6300 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -1348,6 +1348,7 @@ static int bcdma_get_bchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; - enum udma_tp_level tpl; -+ int ret; - - if (uc->bchan) { - dev_dbg(ud->dev, "chan%d: already have bchan%d allocated\n", -@@ -1365,8 +1366,11 @@ static int bcdma_get_bchan(struct udma_chan *uc) - tpl = ud->bchan_tpl.levels - 1; - - uc->bchan = __udma_reserve_bchan(ud, tpl, -1); -- if (IS_ERR(uc->bchan)) -- return PTR_ERR(uc->bchan); -+ if (IS_ERR(uc->bchan)) { -+ ret = PTR_ERR(uc->bchan); -+ uc->bchan = NULL; -+ return ret; -+ } - - uc->tchan = uc->bchan; - -@@ -1376,6 +1380,7 @@ static int bcdma_get_bchan(struct udma_chan *uc) - static int udma_get_tchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -+ int ret; - - if (uc->tchan) { - dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n", -@@ -1390,8 +1395,11 @@ static int udma_get_tchan(struct udma_chan *uc) - */ - uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl, - uc->config.mapped_channel_id); -- if (IS_ERR(uc->tchan)) -- return PTR_ERR(uc->tchan); -+ if (IS_ERR(uc->tchan)) { -+ ret = PTR_ERR(uc->tchan); -+ uc->tchan = NULL; -+ return ret; -+ } - - if (ud->tflow_cnt) { - int tflow_id; -@@ -1421,6 +1429,7 @@ static int udma_get_tchan(struct udma_chan *uc) - static int udma_get_rchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -+ int ret; - - if (uc->rchan) { - dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n", -@@ -1435,8 +1444,13 @@ static int udma_get_rchan(struct udma_chan *uc) - */ - uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl, - uc->config.mapped_channel_id); -+ if (IS_ERR(uc->rchan)) { -+ ret = PTR_ERR(uc->rchan); -+ uc->rchan = NULL; -+ return ret; -+ } - -- return PTR_ERR_OR_ZERO(uc->rchan); -+ return 0; - } - - static int udma_get_chan_pair(struct udma_chan *uc) -@@ -1490,6 +1504,7 @@ static int udma_get_chan_pair(struct udma_chan *uc) - static int udma_get_rflow(struct udma_chan *uc, int flow_id) - { - struct udma_dev *ud = uc->ud; -+ int ret; - - if (!uc->rchan) { - dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id); -@@ -1503,8 +1518,13 @@ static int udma_get_rflow(struct udma_chan *uc, int flow_id) - } - - uc->rflow = __udma_get_rflow(ud, flow_id); -+ if (IS_ERR(uc->rflow)) { -+ ret = PTR_ERR(uc->rflow); -+ uc->rflow = NULL; -+ return ret; -+ } - -- return PTR_ERR_OR_ZERO(uc->rflow); -+ return 0; - } - - static void bcdma_put_bchan(struct udma_chan *uc) -diff --git a/drivers/dma/uniphier-xdmac.c b/drivers/dma/uniphier-xdmac.c -index d6b8a202474f4..290836b7e1be2 100644 ---- a/drivers/dma/uniphier-xdmac.c -+++ b/drivers/dma/uniphier-xdmac.c -@@ -131,8 +131,9 @@ uniphier_xdmac_next_desc(struct uniphier_xdmac_chan *xc) - static void uniphier_xdmac_chan_start(struct uniphier_xdmac_chan *xc, - struct uniphier_xdmac_desc *xd) - { -- u32 src_mode, src_addr, src_width; -- u32 dst_mode, dst_addr, dst_width; -+ u32 src_mode, src_width; -+ u32 dst_mode, dst_width; -+ dma_addr_t src_addr, dst_addr; - u32 val, its, tnum; - enum dma_slave_buswidth buswidth; - -diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c -index b280a53e8570a..ce5c66e6897d2 100644 ---- a/drivers/dma/xilinx/xilinx_dpdma.c -+++ b/drivers/dma/xilinx/xilinx_dpdma.c -@@ -271,9 +271,6 @@ struct xilinx_dpdma_device { - /* ----------------------------------------------------------------------------- - * DebugFS - */ -- --#ifdef CONFIG_DEBUG_FS -- - #define XILINX_DPDMA_DEBUGFS_READ_MAX_SIZE 32 - #define XILINX_DPDMA_DEBUGFS_UINT16_MAX_STR "65535" - -@@ -299,7 +296,7 @@ struct xilinx_dpdma_debugfs_request { - - static void xilinx_dpdma_debugfs_desc_done_irq(struct xilinx_dpdma_chan *chan) - { -- if (chan->id == dpdma_debugfs.chan_id) -+ if (IS_ENABLED(CONFIG_DEBUG_FS) && chan->id == dpdma_debugfs.chan_id) - dpdma_debugfs.xilinx_dpdma_irq_done_count++; - } - -@@ -462,16 +459,6 @@ static void xilinx_dpdma_debugfs_init(struct xilinx_dpdma_device *xdev) - dev_err(xdev->dev, "Failed to create debugfs testcase file\n"); - } - --#else --static void xilinx_dpdma_debugfs_init(struct xilinx_dpdma_device *xdev) --{ --} -- --static void xilinx_dpdma_debugfs_desc_done_irq(struct xilinx_dpdma_chan *chan) --{ --} --#endif /* CONFIG_DEBUG_FS */ -- - /* ----------------------------------------------------------------------------- - * I/O Accessors - */ -diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c -index 3a6d2416cb0f6..5dd29789f97d3 100644 ---- a/drivers/edac/altera_edac.c -+++ b/drivers/edac/altera_edac.c -@@ -350,7 +350,7 @@ static int altr_sdram_probe(struct platform_device *pdev) - if (irq < 0) { - edac_printk(KERN_ERR, EDAC_MC, - "No irq %d in DT\n", irq); -- return -ENODEV; -+ return irq; - } - - /* Arria10 has a 2nd IRQ */ -diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c -index 99b06a3e8fb12..4fce75013674f 100644 ---- a/drivers/edac/amd64_edac.c -+++ b/drivers/edac/amd64_edac.c -@@ -1065,12 +1065,14 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) - #define CS_ODD_PRIMARY BIT(1) - #define CS_EVEN_SECONDARY BIT(2) - #define CS_ODD_SECONDARY BIT(3) -+#define CS_3R_INTERLEAVE BIT(4) - - #define CS_EVEN (CS_EVEN_PRIMARY | CS_EVEN_SECONDARY) - #define CS_ODD (CS_ODD_PRIMARY | CS_ODD_SECONDARY) - - static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) - { -+ u8 base, count = 0; - int cs_mode = 0; - - if (csrow_enabled(2 * dimm, ctrl, pvt)) -@@ -1083,6 +1085,20 @@ static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) - if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt)) - cs_mode |= CS_ODD_SECONDARY; - -+ /* -+ * 3 Rank inteleaving support. -+ * There should be only three bases enabled and their two masks should -+ * be equal. -+ */ -+ for_each_chip_select(base, ctrl, pvt) -+ count += csrow_enabled(base, ctrl, pvt); -+ -+ if (count == 3 && -+ pvt->csels[ctrl].csmasks[0] == pvt->csels[ctrl].csmasks[1]) { -+ edac_dbg(1, "3R interleaving in use.\n"); -+ cs_mode |= CS_3R_INTERLEAVE; -+ } -+ - return cs_mode; - } - -@@ -1891,10 +1907,14 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, - * - * The MSB is the number of bits in the full mask because BIT[0] is - * always 0. -+ * -+ * In the special 3 Rank interleaving case, a single bit is flipped -+ * without swapping with the most significant bit. This can be handled -+ * by keeping the MSB where it is and ignoring the single zero bit. - */ - msb = fls(addr_mask_orig) - 1; - weight = hweight_long(addr_mask_orig); -- num_zero_bits = msb - weight; -+ num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE); - - /* Take the number of zero bits off from the top of the mask. */ - addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1); -diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c -index 2c5975674723a..a859ddd9d4a13 100644 ---- a/drivers/edac/edac_mc.c -+++ b/drivers/edac/edac_mc.c -@@ -215,7 +215,7 @@ void *edac_align_ptr(void **p, unsigned int size, int n_elems) - else - return (char *)ptr; - -- r = (unsigned long)p % align; -+ r = (unsigned long)ptr % align; - - if (r == 0) - return (char *)ptr; -diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c -index 83345bfac246f..6cf50ee0b77c5 100644 ---- a/drivers/edac/i10nm_base.c -+++ b/drivers/edac/i10nm_base.c -@@ -358,6 +358,9 @@ static int i10nm_get_hbm_munits(void) - - mbase = ioremap(base + off, I10NM_HBM_IMC_MMIO_SIZE); - if (!mbase) { -+ pci_dev_put(d->imc[lmc].mdev); -+ d->imc[lmc].mdev = NULL; -+ - i10nm_printk(KERN_ERR, "Failed to ioremap for hbm mc 0x%llx\n", - base + off); - return -ENOMEM; -@@ -368,6 +371,12 @@ static int i10nm_get_hbm_munits(void) - - mcmtr = I10NM_GET_MCMTR(&d->imc[lmc], 0); - if (!I10NM_IS_HBM_IMC(mcmtr)) { -+ iounmap(d->imc[lmc].mbase); -+ d->imc[lmc].mbase = NULL; -+ d->imc[lmc].hbm_mc = false; -+ pci_dev_put(d->imc[lmc].mdev); -+ d->imc[lmc].mdev = NULL; -+ - i10nm_printk(KERN_ERR, "This isn't an hbm mc!\n"); - return -ENODEV; - } -diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c -index 4c626fcd4dcbb..1522d4aa2ca62 100644 ---- a/drivers/edac/sb_edac.c -+++ b/drivers/edac/sb_edac.c -@@ -1052,7 +1052,7 @@ static u64 haswell_get_tohm(struct sbridge_pvt *pvt) - pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOHM_1, ®); - rc = ((reg << 6) | rc) << 26; - -- return rc | 0x1ffffff; -+ return rc | 0x3ffffff; - } - - static u64 knl_get_tolm(struct sbridge_pvt *pvt) -diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c -index 7d08627e738b3..a5486d86fdd2f 100644 ---- a/drivers/edac/synopsys_edac.c -+++ b/drivers/edac/synopsys_edac.c -@@ -1352,8 +1352,7 @@ static int mc_probe(struct platform_device *pdev) - } - } - -- if (of_device_is_compatible(pdev->dev.of_node, -- "xlnx,zynqmp-ddrc-2.40a")) -+ if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) - setup_address_map(priv); - #endif - -diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c -index 2ccd1db5e98ff..7197f9fa02457 100644 ---- a/drivers/edac/xgene_edac.c -+++ b/drivers/edac/xgene_edac.c -@@ -1919,7 +1919,7 @@ static int xgene_edac_probe(struct platform_device *pdev) - irq = platform_get_irq_optional(pdev, i); - if (irq < 0) { - dev_err(&pdev->dev, "No IRQ resource\n"); -- rc = -EINVAL; -+ rc = irq; - goto out_err; - } - rc = devm_request_irq(&pdev->dev, irq, -diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c -index de416f9e79213..f5219334fd3a5 100644 ---- a/drivers/firmware/arm_scmi/base.c -+++ b/drivers/firmware/arm_scmi/base.c -@@ -34,6 +34,12 @@ struct scmi_msg_resp_base_attributes { - __le16 reserved; - }; - -+struct scmi_msg_resp_base_discover_agent { -+ __le32 agent_id; -+ u8 name[SCMI_MAX_STR_SIZE]; -+}; -+ -+ - struct scmi_msg_base_error_notify { - __le32 event_control; - #define BASE_TP_NOTIFY_ALL BIT(0) -@@ -225,18 +231,21 @@ static int scmi_base_discover_agent_get(const struct scmi_protocol_handle *ph, - int id, char *name) - { - int ret; -+ struct scmi_msg_resp_base_discover_agent *agent_info; - struct scmi_xfer *t; - - ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_AGENT, -- sizeof(__le32), SCMI_MAX_STR_SIZE, &t); -+ sizeof(__le32), sizeof(*agent_info), &t); - if (ret) - return ret; - - put_unaligned_le32(id, t->tx.buf); - - ret = ph->xops->do_xfer(ph, t); -- if (!ret) -- strlcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE); -+ if (!ret) { -+ agent_info = t->rx.buf; -+ strlcpy(name, agent_info->name, SCMI_MAX_STR_SIZE); -+ } - - ph->xops->xfer_put(ph, t); - -diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c -index b406b3f78f467..d76bab3aaac45 100644 ---- a/drivers/firmware/arm_scmi/driver.c -+++ b/drivers/firmware/arm_scmi/driver.c -@@ -2112,7 +2112,7 @@ static void __exit scmi_driver_exit(void) - } - module_exit(scmi_driver_exit); - --MODULE_ALIAS("platform: arm-scmi"); -+MODULE_ALIAS("platform:arm-scmi"); - MODULE_AUTHOR("Sudeep Holla "); - MODULE_DESCRIPTION("ARM SCMI protocol driver"); - MODULE_LICENSE("GPL v2"); -diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c -index 4371fdcd5a73f..581d34c957695 100644 ---- a/drivers/firmware/arm_scmi/scmi_pm_domain.c -+++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c -@@ -138,9 +138,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) - scmi_pd_data->domains = domains; - scmi_pd_data->num_domains = num_domains; - -- of_genpd_add_provider_onecell(np, scmi_pd_data); -- -- return 0; -+ return of_genpd_add_provider_onecell(np, scmi_pd_data); - } - - static const struct scmi_device_id scmi_id_table[] = { -diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c -index 308471586381f..cdbb287bd8bcd 100644 ---- a/drivers/firmware/arm_scmi/sensors.c -+++ b/drivers/firmware/arm_scmi/sensors.c -@@ -637,7 +637,7 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph, - if (ret) - return ret; - -- put_unaligned_le32(cpu_to_le32(sensor_id), t->tx.buf); -+ put_unaligned_le32(sensor_id, t->tx.buf); - ret = ph->xops->do_xfer(ph, t); - if (!ret) { - struct sensors_info *si = ph->get_priv(ph); -diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c -index 11e8efb713751..87039c5c03fdb 100644 ---- a/drivers/firmware/arm_scmi/virtio.c -+++ b/drivers/firmware/arm_scmi/virtio.c -@@ -82,7 +82,8 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev) - } - - static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, -- struct scmi_vio_msg *msg) -+ struct scmi_vio_msg *msg, -+ struct device *dev) - { - struct scatterlist sg_in; - int rc; -@@ -94,8 +95,7 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, - - rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC); - if (rc) -- dev_err_once(vioch->cinfo->dev, -- "failed to add to virtqueue (%d)\n", rc); -+ dev_err_once(dev, "failed to add to virtqueue (%d)\n", rc); - else - virtqueue_kick(vioch->vqueue); - -@@ -108,7 +108,7 @@ static void scmi_finalize_message(struct scmi_vio_channel *vioch, - struct scmi_vio_msg *msg) - { - if (vioch->is_rx) { -- scmi_vio_feed_vq_rx(vioch, msg); -+ scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev); - } else { - /* Here IRQs are assumed to be already disabled by the caller */ - spin_lock(&vioch->lock); -@@ -269,7 +269,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, - list_add_tail(&msg->list, &vioch->free_list); - spin_unlock_irqrestore(&vioch->lock, flags); - } else { -- scmi_vio_feed_vq_rx(vioch, msg); -+ scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev); - } - } - -diff --git a/drivers/firmware/arm_scmi/voltage.c b/drivers/firmware/arm_scmi/voltage.c -index a5048956a0be9..ac08e819088bb 100644 ---- a/drivers/firmware/arm_scmi/voltage.c -+++ b/drivers/firmware/arm_scmi/voltage.c -@@ -156,7 +156,7 @@ static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph, - int cnt; - - cmd->domain_id = cpu_to_le32(v->id); -- cmd->level_index = desc_index; -+ cmd->level_index = cpu_to_le32(desc_index); - ret = ph->xops->do_xfer(ph, tl); - if (ret) - break; -diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c -index b19ce1a83f91a..b2c829e95bd14 100644 ---- a/drivers/firmware/efi/efi-init.c -+++ b/drivers/firmware/efi/efi-init.c -@@ -235,6 +235,11 @@ void __init efi_init(void) - } - - reserve_regions(); -+ /* -+ * For memblock manipulation, the cap should come after the memblock_add(). -+ * And now, memblock is fully populated, it is time to do capping. -+ */ -+ early_init_dt_check_for_usable_mem_range(); - efi_esrt_init(); - efi_mokvar_table_init(); - -diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index 847f33ffc4aed..9fa86288b78a9 100644 ---- a/drivers/firmware/efi/efi.c -+++ b/drivers/firmware/efi/efi.c -@@ -719,6 +719,13 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr, - systab_hdr->revision >> 16, - systab_hdr->revision & 0xffff, - vendor); -+ -+ if (IS_ENABLED(CONFIG_X86_64) && -+ systab_hdr->revision > EFI_1_10_SYSTEM_TABLE_REVISION && -+ !strcmp(vendor, "Apple")) { -+ pr_info("Apple Mac detected, using EFI v1.10 runtime services only\n"); -+ efi.runtime_version = EFI_1_10_SYSTEM_TABLE_REVISION; -+ } - } - - static __initdata char memory_type_name[][13] = { -diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c -index 2363fee9211c9..9cc556013d085 100644 ---- a/drivers/firmware/efi/libstub/arm64-stub.c -+++ b/drivers/firmware/efi/libstub/arm64-stub.c -@@ -119,9 +119,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, - if (image->image_base != _text) - efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n"); - -- if (!IS_ALIGNED((u64)_text, EFI_KIMG_ALIGN)) -- efi_err("FIRMWARE BUG: kernel image not aligned on %ldk boundary\n", -- EFI_KIMG_ALIGN >> 10); -+ if (!IS_ALIGNED((u64)_text, SEGMENT_ALIGN)) -+ efi_err("FIRMWARE BUG: kernel image not aligned on %dk boundary\n", -+ SEGMENT_ALIGN >> 10); - - kernel_size = _edata - _text; - kernel_memsize = kernel_size + (_end - _edata); -diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c -index 380e4e2513994..9c460843442f5 100644 ---- a/drivers/firmware/efi/libstub/riscv-stub.c -+++ b/drivers/firmware/efi/libstub/riscv-stub.c -@@ -25,7 +25,7 @@ typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned long); - - static u32 hartid; - --static u32 get_boot_hartid_from_fdt(void) -+static int get_boot_hartid_from_fdt(void) - { - const void *fdt; - int chosen_node, len; -@@ -33,23 +33,26 @@ static u32 get_boot_hartid_from_fdt(void) - - fdt = get_efi_config_table(DEVICE_TREE_GUID); - if (!fdt) -- return U32_MAX; -+ return -EINVAL; - - chosen_node = fdt_path_offset(fdt, "/chosen"); - if (chosen_node < 0) -- return U32_MAX; -+ return -EINVAL; - - prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); - if (!prop || len != sizeof(u32)) -- return U32_MAX; -+ return -EINVAL; - -- return fdt32_to_cpu(*prop); -+ hartid = fdt32_to_cpu(*prop); -+ return 0; - } - - efi_status_t check_platform_features(void) - { -- hartid = get_boot_hartid_from_fdt(); -- if (hartid == U32_MAX) { -+ int ret; -+ -+ ret = get_boot_hartid_from_fdt(); -+ if (ret) { - efi_err("/chosen/boot-hartid missing or invalid!\n"); - return EFI_UNSUPPORTED; - } -diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c -index abdc8a6a39631..cae590bd08f27 100644 ---- a/drivers/firmware/efi/vars.c -+++ b/drivers/firmware/efi/vars.c -@@ -742,6 +742,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, - { - const struct efivar_operations *ops; - efi_status_t status; -+ unsigned long varsize; - - if (!__efivars) - return -EINVAL; -@@ -764,15 +765,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, - return efivar_entry_set_nonblocking(name, vendor, attributes, - size, data); - -+ varsize = size + ucs2_strsize(name, 1024); - if (!block) { - if (down_trylock(&efivars_lock)) - return -EBUSY; -+ status = check_var_size_nonblocking(attributes, varsize); - } else { - if (down_interruptible(&efivars_lock)) - return -EINTR; -+ status = check_var_size(attributes, varsize); - } - -- status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); - if (status != EFI_SUCCESS) { - up(&efivars_lock); - return -ENOSPC; -diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig -index 97968aece54f8..931544c9f63d4 100644 ---- a/drivers/firmware/google/Kconfig -+++ b/drivers/firmware/google/Kconfig -@@ -3,9 +3,9 @@ menuconfig GOOGLE_FIRMWARE - bool "Google Firmware Drivers" - default n - help -- These firmware drivers are used by Google's servers. They are -- only useful if you are working directly on one of their -- proprietary servers. If in doubt, say "N". -+ These firmware drivers are used by Google servers, -+ Chromebooks and other devices using coreboot firmware. -+ If in doubt, say "N". - - if GOOGLE_FIRMWARE - -diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c -index 9a369a2eda71d..116eb465cdb42 100644 ---- a/drivers/firmware/psci/psci_checker.c -+++ b/drivers/firmware/psci/psci_checker.c -@@ -155,7 +155,7 @@ static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups) - if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) - return -ENOMEM; - -- cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups), -+ cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups), - GFP_KERNEL); - if (!cpu_groups) { - free_cpumask_var(tmp); -diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c -index 2ee97bab74409..27a64de919817 100644 ---- a/drivers/firmware/qcom_scm.c -+++ b/drivers/firmware/qcom_scm.c -@@ -252,7 +252,7 @@ static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id, - break; - default: - pr_err("Unknown SMC convention being used\n"); -- return -EINVAL; -+ return false; - } - - ret = qcom_scm_call(dev, &desc, &res); -diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c -index 172c751a4f6c2..f08e056ed0ae4 100644 ---- a/drivers/firmware/qemu_fw_cfg.c -+++ b/drivers/firmware/qemu_fw_cfg.c -@@ -388,9 +388,7 @@ static void fw_cfg_sysfs_cache_cleanup(void) - struct fw_cfg_sysfs_entry *entry, *next; - - list_for_each_entry_safe(entry, next, &fw_cfg_entry_cache, list) { -- /* will end up invoking fw_cfg_sysfs_cache_delist() -- * via each object's release() method (i.e. destructor) -- */ -+ fw_cfg_sysfs_cache_delist(entry); - kobject_put(&entry->kobj); - } - } -@@ -448,7 +446,6 @@ static void fw_cfg_sysfs_release_entry(struct kobject *kobj) - { - struct fw_cfg_sysfs_entry *entry = to_entry(kobj); - -- fw_cfg_sysfs_cache_delist(entry); - kfree(entry); - } - -@@ -601,20 +598,18 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) - /* set file entry information */ - entry->size = be32_to_cpu(f->size); - entry->select = be16_to_cpu(f->select); -- memcpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); -+ strscpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); - - /* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ - err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype, - fw_cfg_sel_ko, "%d", entry->select); -- if (err) { -- kobject_put(&entry->kobj); -- return err; -- } -+ if (err) -+ goto err_put_entry; - - /* add raw binary content access */ - err = sysfs_create_bin_file(&entry->kobj, &fw_cfg_sysfs_attr_raw); - if (err) -- goto err_add_raw; -+ goto err_del_entry; - - /* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */ - fw_cfg_build_symlink(fw_cfg_fname_kset, &entry->kobj, entry->name); -@@ -623,9 +618,10 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) - fw_cfg_sysfs_cache_enlist(entry); - return 0; - --err_add_raw: -+err_del_entry: - kobject_del(&entry->kobj); -- kfree(entry); -+err_put_entry: -+ kobject_put(&entry->kobj); - return err; - } - -diff --git a/drivers/firmware/scpi_pm_domain.c b/drivers/firmware/scpi_pm_domain.c -index 51201600d789b..800673910b511 100644 ---- a/drivers/firmware/scpi_pm_domain.c -+++ b/drivers/firmware/scpi_pm_domain.c -@@ -16,7 +16,6 @@ struct scpi_pm_domain { - struct generic_pm_domain genpd; - struct scpi_ops *ops; - u32 domain; -- char name[30]; - }; - - /* -@@ -110,8 +109,13 @@ static int scpi_pm_domain_probe(struct platform_device *pdev) - - scpi_pd->domain = i; - scpi_pd->ops = scpi_ops; -- sprintf(scpi_pd->name, "%pOFn.%d", np, i); -- scpi_pd->genpd.name = scpi_pd->name; -+ scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL, -+ "%pOFn.%d", np, i); -+ if (!scpi_pd->genpd.name) { -+ dev_err(dev, "Failed to allocate genpd name:%pOFn.%d\n", -+ np, i); -+ continue; -+ } - scpi_pd->genpd.power_off = scpi_pd_power_off; - scpi_pd->genpd.power_on = scpi_pd_power_on; - -diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c -index 581aa5e9b0778..dd7c3d5e8b0bb 100644 ---- a/drivers/firmware/smccc/soc_id.c -+++ b/drivers/firmware/smccc/soc_id.c -@@ -50,7 +50,7 @@ static int __init smccc_soc_init(void) - arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, - ARM_SMCCC_ARCH_SOC_ID, &res); - -- if (res.a0 == SMCCC_RET_NOT_SUPPORTED) { -+ if ((int)res.a0 == SMCCC_RET_NOT_SUPPORTED) { - pr_info("ARCH_SOC_ID not implemented, skipping ....\n"); - return 0; - } -diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c -index b86761904949c..303a491e520d1 100644 ---- a/drivers/firmware/sysfb_simplefb.c -+++ b/drivers/firmware/sysfb_simplefb.c -@@ -113,12 +113,16 @@ __init int sysfb_create_simplefb(const struct screen_info *si, - sysfb_apply_efi_quirks(pd); - - ret = platform_device_add_resources(pd, &res, 1); -- if (ret) -+ if (ret) { -+ platform_device_put(pd); - return ret; -+ } - - ret = platform_device_add_data(pd, mode, sizeof(*mode)); -- if (ret) -+ if (ret) { -+ platform_device_put(pd); - return ret; -+ } - - return platform_device_add(pd); - } -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index fae5141251e5d..947474f6abb45 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -523,6 +523,7 @@ config GPIO_REG - config GPIO_ROCKCHIP - tristate "Rockchip GPIO support" - depends on ARCH_ROCKCHIP || COMPILE_TEST -+ select GENERIC_IRQ_CHIP - select GPIOLIB_IRQCHIP - default ARCH_ROCKCHIP - help -diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c -index 34e35b64dcdc0..23047dc84ef1b 100644 ---- a/drivers/gpio/gpio-aggregator.c -+++ b/drivers/gpio/gpio-aggregator.c -@@ -273,7 +273,8 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset) - { - struct gpiochip_fwd *fwd = gpiochip_get_data(chip); - -- return gpiod_get_value(fwd->descs[offset]); -+ return chip->can_sleep ? gpiod_get_value_cansleep(fwd->descs[offset]) -+ : gpiod_get_value(fwd->descs[offset]); - } - - static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, -@@ -292,7 +293,10 @@ static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, - for_each_set_bit(i, mask, fwd->chip.ngpio) - descs[j++] = fwd->descs[i]; - -- error = gpiod_get_array_value(j, descs, NULL, values); -+ if (fwd->chip.can_sleep) -+ error = gpiod_get_array_value_cansleep(j, descs, NULL, values); -+ else -+ error = gpiod_get_array_value(j, descs, NULL, values); - if (error) - return error; - -@@ -327,7 +331,10 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value) - { - struct gpiochip_fwd *fwd = gpiochip_get_data(chip); - -- gpiod_set_value(fwd->descs[offset], value); -+ if (chip->can_sleep) -+ gpiod_set_value_cansleep(fwd->descs[offset], value); -+ else -+ gpiod_set_value(fwd->descs[offset], value); - } - - static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, -@@ -346,7 +353,10 @@ static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, - descs[j++] = fwd->descs[i]; - } - -- gpiod_set_array_value(j, descs, NULL, values); -+ if (fwd->chip.can_sleep) -+ gpiod_set_array_value_cansleep(j, descs, NULL, values); -+ else -+ gpiod_set_array_value(j, descs, NULL, values); - } - - static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip, -diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c -index 3d6ef37a7702a..454cefbeecf0e 100644 ---- a/drivers/gpio/gpio-aspeed-sgpio.c -+++ b/drivers/gpio/gpio-aspeed-sgpio.c -@@ -31,7 +31,7 @@ struct aspeed_sgpio { - struct gpio_chip chip; - struct irq_chip intc; - struct clk *pclk; -- spinlock_t lock; -+ raw_spinlock_t lock; - void __iomem *base; - int irq; - }; -@@ -173,12 +173,12 @@ static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset) - enum aspeed_sgpio_reg reg; - int rc = 0; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata; - rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset)); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return rc; - } -@@ -215,11 +215,11 @@ static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val) - struct aspeed_sgpio *gpio = gpiochip_get_data(gc); - unsigned long flags; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - sgpio_set_value(gc, offset, val); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - } - - static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset) -@@ -236,9 +236,9 @@ static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int v - /* No special action is required for setting the direction; we'll - * error-out in sgpio_set_value if this isn't an output GPIO */ - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - rc = sgpio_set_value(gc, offset, val); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return rc; - } -@@ -277,11 +277,11 @@ static void aspeed_sgpio_irq_ack(struct irq_data *d) - - status_addr = bank_reg(gpio, bank, reg_irq_status); - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - iowrite32(bit, status_addr); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - } - - static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) -@@ -296,7 +296,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) - irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset); - addr = bank_reg(gpio, bank, reg_irq_enable); - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - reg = ioread32(addr); - if (set) -@@ -306,7 +306,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) - - iowrite32(reg, addr); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - } - - static void aspeed_sgpio_irq_mask(struct irq_data *d) -@@ -355,7 +355,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type) - return -EINVAL; - } - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - addr = bank_reg(gpio, bank, reg_irq_type0); - reg = ioread32(addr); -@@ -372,7 +372,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type) - reg = (reg & ~bit) | type2; - iowrite32(reg, addr); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - irq_set_handler_locked(d, handler); - -@@ -395,7 +395,7 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc) - reg = ioread32(bank_reg(data, bank, reg_irq_status)); - - for_each_set_bit(p, ®, 32) -- generic_handle_domain_irq(gc->irq.domain, i * 32 + p * 2); -+ generic_handle_domain_irq(gc->irq.domain, (i * 32 + p) * 2); - } - - chained_irq_exit(ic, desc); -@@ -467,7 +467,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, - - reg = bank_reg(gpio, to_bank(offset), reg_tolerance); - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - val = readl(reg); - -@@ -478,7 +478,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, - - writel(val, reg); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return 0; - } -@@ -575,7 +575,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) - iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval | - ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL); - -- spin_lock_init(&gpio->lock); -+ raw_spin_lock_init(&gpio->lock); - - gpio->chip.parent = &pdev->dev; - gpio->chip.ngpio = nr_gpios * 2; -diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c -index 3c8f20c57695f..318a7d95a1a8b 100644 ---- a/drivers/gpio/gpio-aspeed.c -+++ b/drivers/gpio/gpio-aspeed.c -@@ -53,7 +53,7 @@ struct aspeed_gpio_config { - struct aspeed_gpio { - struct gpio_chip chip; - struct irq_chip irqc; -- spinlock_t lock; -+ raw_spinlock_t lock; - void __iomem *base; - int irq; - const struct aspeed_gpio_config *config; -@@ -413,14 +413,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, - unsigned long flags; - bool copro; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - copro = aspeed_gpio_copro_request(gpio, offset); - - __aspeed_gpio_set(gc, offset, val); - - if (copro) - aspeed_gpio_copro_release(gpio, offset); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - } - - static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) -@@ -435,7 +435,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) - if (!have_input(gpio, offset)) - return -ENOTSUPP; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - reg = ioread32(addr); - reg &= ~GPIO_BIT(offset); -@@ -445,7 +445,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) - if (copro) - aspeed_gpio_copro_release(gpio, offset); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return 0; - } -@@ -463,7 +463,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc, - if (!have_output(gpio, offset)) - return -ENOTSUPP; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - reg = ioread32(addr); - reg |= GPIO_BIT(offset); -@@ -474,7 +474,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc, - - if (copro) - aspeed_gpio_copro_release(gpio, offset); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return 0; - } -@@ -492,11 +492,11 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) - if (!have_output(gpio, offset)) - return GPIO_LINE_DIRECTION_IN; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; - } -@@ -539,14 +539,14 @@ static void aspeed_gpio_irq_ack(struct irq_data *d) - - status_addr = bank_reg(gpio, bank, reg_irq_status); - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - copro = aspeed_gpio_copro_request(gpio, offset); - - iowrite32(bit, status_addr); - - if (copro) - aspeed_gpio_copro_release(gpio, offset); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - } - - static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) -@@ -565,7 +565,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) - - addr = bank_reg(gpio, bank, reg_irq_enable); - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - copro = aspeed_gpio_copro_request(gpio, offset); - - reg = ioread32(addr); -@@ -577,7 +577,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) - - if (copro) - aspeed_gpio_copro_release(gpio, offset); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - } - - static void aspeed_gpio_irq_mask(struct irq_data *d) -@@ -629,7 +629,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type) - return -EINVAL; - } - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - copro = aspeed_gpio_copro_request(gpio, offset); - - addr = bank_reg(gpio, bank, reg_irq_type0); -@@ -649,7 +649,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type) - - if (copro) - aspeed_gpio_copro_release(gpio, offset); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - irq_set_handler_locked(d, handler); - -@@ -716,7 +716,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip, - - treg = bank_reg(gpio, to_bank(offset), reg_tolerance); - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - copro = aspeed_gpio_copro_request(gpio, offset); - - val = readl(treg); -@@ -730,7 +730,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip, - - if (copro) - aspeed_gpio_copro_release(gpio, offset); -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return 0; - } -@@ -856,7 +856,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset, - return rc; - } - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - if (timer_allocation_registered(gpio, offset)) { - rc = unregister_allocated_timer(gpio, offset); -@@ -916,7 +916,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset, - configure_timer(gpio, offset, i); - - out: -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return rc; - } -@@ -927,13 +927,13 @@ static int disable_debounce(struct gpio_chip *chip, unsigned int offset) - unsigned long flags; - int rc; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - rc = unregister_allocated_timer(gpio, offset); - if (!rc) - configure_timer(gpio, offset, 0); - -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - - return rc; - } -@@ -1015,7 +1015,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc, - return -EINVAL; - bindex = offset >> 3; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - /* Sanity check, this shouldn't happen */ - if (gpio->cf_copro_bankmap[bindex] == 0xff) { -@@ -1036,7 +1036,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc, - if (bit) - *bit = GPIO_OFFSET(offset); - bail: -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - return rc; - } - EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio); -@@ -1060,7 +1060,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc) - return -EINVAL; - bindex = offset >> 3; - -- spin_lock_irqsave(&gpio->lock, flags); -+ raw_spin_lock_irqsave(&gpio->lock, flags); - - /* Sanity check, this shouldn't happen */ - if (gpio->cf_copro_bankmap[bindex] == 0) { -@@ -1074,7 +1074,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc) - aspeed_gpio_change_cmd_source(gpio, bank, bindex, - GPIO_CMDSRC_ARM); - bail: -- spin_unlock_irqrestore(&gpio->lock, flags); -+ raw_spin_unlock_irqrestore(&gpio->lock, flags); - return rc; - } - EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio); -@@ -1148,7 +1148,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) - if (IS_ERR(gpio->base)) - return PTR_ERR(gpio->base); - -- spin_lock_init(&gpio->lock); -+ raw_spin_lock_init(&gpio->lock); - - gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node); - if (!gpio_id) -diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c -index 026903e3ef543..08b9e2cf4f2d6 100644 ---- a/drivers/gpio/gpio-dln2.c -+++ b/drivers/gpio/gpio-dln2.c -@@ -46,6 +46,7 @@ - struct dln2_gpio { - struct platform_device *pdev; - struct gpio_chip gpio; -+ struct irq_chip irqchip; - - /* - * Cache pin direction to save us one transfer, since the hardware has -@@ -383,15 +384,6 @@ static void dln2_irq_bus_unlock(struct irq_data *irqd) - mutex_unlock(&dln2->irq_lock); - } - --static struct irq_chip dln2_gpio_irqchip = { -- .name = "dln2-irq", -- .irq_mask = dln2_irq_mask, -- .irq_unmask = dln2_irq_unmask, -- .irq_set_type = dln2_irq_set_type, -- .irq_bus_lock = dln2_irq_bus_lock, -- .irq_bus_sync_unlock = dln2_irq_bus_unlock, --}; -- - static void dln2_gpio_event(struct platform_device *pdev, u16 echo, - const void *data, int len) - { -@@ -473,8 +465,15 @@ static int dln2_gpio_probe(struct platform_device *pdev) - dln2->gpio.direction_output = dln2_gpio_direction_output; - dln2->gpio.set_config = dln2_gpio_set_config; - -+ dln2->irqchip.name = "dln2-irq", -+ dln2->irqchip.irq_mask = dln2_irq_mask, -+ dln2->irqchip.irq_unmask = dln2_irq_unmask, -+ dln2->irqchip.irq_set_type = dln2_irq_set_type, -+ dln2->irqchip.irq_bus_lock = dln2_irq_bus_lock, -+ dln2->irqchip.irq_bus_sync_unlock = dln2_irq_bus_unlock, -+ - girq = &dln2->gpio.irq; -- girq->chip = &dln2_gpio_irqchip; -+ girq->chip = &dln2->irqchip; - /* The event comes from the outside so no parent handler */ - girq->parent_handler = NULL; - girq->num_parents = 0; -diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c -index 50003ad2e5898..52b8b72ded77f 100644 ---- a/drivers/gpio/gpio-idt3243x.c -+++ b/drivers/gpio/gpio-idt3243x.c -@@ -132,7 +132,7 @@ static int idt_gpio_probe(struct platform_device *pdev) - struct device *dev = &pdev->dev; - struct gpio_irq_chip *girq; - struct idt_gpio_ctrl *ctrl; -- unsigned int parent_irq; -+ int parent_irq; - int ngpios; - int ret; - -@@ -164,8 +164,8 @@ static int idt_gpio_probe(struct platform_device *pdev) - return PTR_ERR(ctrl->pic); - - parent_irq = platform_get_irq(pdev, 0); -- if (!parent_irq) -- return -EINVAL; -+ if (parent_irq < 0) -+ return parent_irq; - - girq = &ctrl->gc.irq; - girq->chip = &idt_gpio_irqchip; -diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c -index 70d6ae20b1da5..a964e25ea6206 100644 ---- a/drivers/gpio/gpio-mpc8xxx.c -+++ b/drivers/gpio/gpio-mpc8xxx.c -@@ -47,7 +47,7 @@ struct mpc8xxx_gpio_chip { - unsigned offset, int value); - - struct irq_domain *irq; -- unsigned int irqn; -+ int irqn; - }; - - /* -@@ -388,8 +388,8 @@ static int mpc8xxx_probe(struct platform_device *pdev) - } - - mpc8xxx_gc->irqn = platform_get_irq(pdev, 0); -- if (!mpc8xxx_gc->irqn) -- return 0; -+ if (mpc8xxx_gc->irqn < 0) -+ return mpc8xxx_gc->irqn; - - mpc8xxx_gc->irq = irq_domain_create_linear(fwnode, - MPC8XXX_GPIO_PINS, -diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c -index eeeb39bc171dc..bd75401b549d1 100644 ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -205,7 +205,7 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc) - status = realtek_gpio_read_isr(ctrl, lines_done / 8); - port_pin_count = min(gc->ngpio - lines_done, 8U); - for_each_set_bit(offset, &status, port_pin_count) -- generic_handle_domain_irq(gc->irq.domain, offset); -+ generic_handle_domain_irq(gc->irq.domain, offset + lines_done); - } - - chained_irq_exit(irq_chip, desc); -diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c -index ce63cbd14d69a..24155c038f6d0 100644 ---- a/drivers/gpio/gpio-rockchip.c -+++ b/drivers/gpio/gpio-rockchip.c -@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) - level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); - polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); - -- switch (type) { -- case IRQ_TYPE_EDGE_BOTH: -+ if (type == IRQ_TYPE_EDGE_BOTH) { - if (bank->gpio_type == GPIO_TYPE_V2) { -- bank->toggle_edge_mode &= ~mask; - rockchip_gpio_writel_bit(bank, d->hwirq, 1, - bank->gpio_regs->int_bothedge); - goto out; -@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) - else - polarity |= mask; - } -- break; -- case IRQ_TYPE_EDGE_RISING: -- bank->toggle_edge_mode &= ~mask; -- level |= mask; -- polarity |= mask; -- break; -- case IRQ_TYPE_EDGE_FALLING: -- bank->toggle_edge_mode &= ~mask; -- level |= mask; -- polarity &= ~mask; -- break; -- case IRQ_TYPE_LEVEL_HIGH: -- bank->toggle_edge_mode &= ~mask; -- level &= ~mask; -- polarity |= mask; -- break; -- case IRQ_TYPE_LEVEL_LOW: -- bank->toggle_edge_mode &= ~mask; -- level &= ~mask; -- polarity &= ~mask; -- break; -- default: -- ret = -EINVAL; -- goto out; -+ } else { -+ if (bank->gpio_type == GPIO_TYPE_V2) { -+ rockchip_gpio_writel_bit(bank, d->hwirq, 0, -+ bank->gpio_regs->int_bothedge); -+ } else { -+ bank->toggle_edge_mode &= ~mask; -+ } -+ switch (type) { -+ case IRQ_TYPE_EDGE_RISING: -+ level |= mask; -+ polarity |= mask; -+ break; -+ case IRQ_TYPE_EDGE_FALLING: -+ level |= mask; -+ polarity &= ~mask; -+ break; -+ case IRQ_TYPE_LEVEL_HIGH: -+ level &= ~mask; -+ polarity |= mask; -+ break; -+ case IRQ_TYPE_LEVEL_LOW: -+ level &= ~mask; -+ polarity &= ~mask; -+ break; -+ default: -+ ret = -EINVAL; -+ goto out; -+ } - } - - rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); -diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c -index 403f9e833d6a3..7d82388b4ab7c 100644 ---- a/drivers/gpio/gpio-sifive.c -+++ b/drivers/gpio/gpio-sifive.c -@@ -223,7 +223,7 @@ static int sifive_gpio_probe(struct platform_device *pdev) - NULL, - chip->base + SIFIVE_GPIO_OUTPUT_EN, - chip->base + SIFIVE_GPIO_INPUT_EN, -- 0); -+ BGPIOF_READ_OUTPUT_REG_SET); - if (ret) { - dev_err(dev, "unable to init generic GPIO\n"); - return ret; -diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c -index c99858f40a27e..00762de3d4096 100644 ---- a/drivers/gpio/gpio-tegra186.c -+++ b/drivers/gpio/gpio-tegra186.c -@@ -337,9 +337,12 @@ static int tegra186_gpio_of_xlate(struct gpio_chip *chip, - return offset + pin; - } - -+#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio) -+ - static void tegra186_irq_ack(struct irq_data *data) - { -- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); -+ struct tegra_gpio *gpio = to_tegra_gpio(gc); - void __iomem *base; - - base = tegra186_gpio_get_base(gpio, data->hwirq); -@@ -351,7 +354,8 @@ static void tegra186_irq_ack(struct irq_data *data) - - static void tegra186_irq_mask(struct irq_data *data) - { -- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); -+ struct tegra_gpio *gpio = to_tegra_gpio(gc); - void __iomem *base; - u32 value; - -@@ -366,7 +370,8 @@ static void tegra186_irq_mask(struct irq_data *data) - - static void tegra186_irq_unmask(struct irq_data *data) - { -- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); -+ struct tegra_gpio *gpio = to_tegra_gpio(gc); - void __iomem *base; - u32 value; - -@@ -381,7 +386,8 @@ static void tegra186_irq_unmask(struct irq_data *data) - - static int tegra186_irq_set_type(struct irq_data *data, unsigned int type) - { -- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); -+ struct tegra_gpio *gpio = to_tegra_gpio(gc); - void __iomem *base; - u32 value; - -diff --git a/drivers/gpio/gpio-virtio.c b/drivers/gpio/gpio-virtio.c -index d24f1c9264bc9..dd3b23c9580b1 100644 ---- a/drivers/gpio/gpio-virtio.c -+++ b/drivers/gpio/gpio-virtio.c -@@ -81,11 +81,7 @@ static int _virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio, - virtqueue_kick(vgpio->request_vq); - mutex_unlock(&vgpio->lock); - -- if (!wait_for_completion_timeout(&line->completion, HZ)) { -- dev_err(dev, "GPIO operation timed out\n"); -- ret = -ETIMEDOUT; -- goto out; -- } -+ wait_for_completion(&line->completion); - - if (unlikely(res->status != VIRTIO_GPIO_STATUS_OK)) { - dev_err(dev, "GPIO request failed: %d\n", gpio); -diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c -index 47712b6903b51..d040c72fea582 100644 ---- a/drivers/gpio/gpiolib-acpi.c -+++ b/drivers/gpio/gpiolib-acpi.c -@@ -1059,10 +1059,17 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind - irq_flags = acpi_dev_get_irq_type(info.triggering, - info.polarity); - -- /* Set type if specified and different than the current one */ -- if (irq_flags != IRQ_TYPE_NONE && -- irq_flags != irq_get_trigger_type(irq)) -- irq_set_irq_type(irq, irq_flags); -+ /* -+ * If the IRQ is not already in use then set type -+ * if specified and different than the current one. -+ */ -+ if (can_request_irq(irq, irq_flags)) { -+ if (irq_flags != IRQ_TYPE_NONE && -+ irq_flags != irq_get_trigger_type(irq)) -+ irq_set_irq_type(irq, irq_flags); -+ } else { -+ dev_dbg(&adev->dev, "IRQ %d already in use\n", irq); -+ } - - return irq; - } -diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c -index c7b5446d01fd2..ffa0256cad5a0 100644 ---- a/drivers/gpio/gpiolib-cdev.c -+++ b/drivers/gpio/gpiolib-cdev.c -@@ -330,7 +330,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) - goto out_free_lh; - } - -- ret = gpiod_request(desc, lh->label); -+ ret = gpiod_request_user(desc, lh->label); - if (ret) - goto out_free_lh; - lh->descs[i] = desc; -@@ -1378,7 +1378,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip) - goto out_free_linereq; - } - -- ret = gpiod_request(desc, lr->label); -+ ret = gpiod_request_user(desc, lr->label); - if (ret) - goto out_free_linereq; - -@@ -1764,7 +1764,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) - } - } - -- ret = gpiod_request(desc, le->label); -+ ret = gpiod_request_user(desc, le->label); - if (ret) - goto out_free_le; - le->desc = desc; -diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c -index 4098bc7f88b7e..44c1ad51b3fe9 100644 ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -475,12 +475,9 @@ static ssize_t export_store(struct class *class, - * they may be undone on its behalf too. - */ - -- status = gpiod_request(desc, "sysfs"); -- if (status) { -- if (status == -EPROBE_DEFER) -- status = -ENODEV; -+ status = gpiod_request_user(desc, "sysfs"); -+ if (status) - goto done; -- } - - status = gpiod_set_transitory(desc, false); - if (!status) { -diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h -index 30bc3f80f83e6..c31f4626915de 100644 ---- a/drivers/gpio/gpiolib.h -+++ b/drivers/gpio/gpiolib.h -@@ -135,6 +135,18 @@ struct gpio_desc { - - int gpiod_request(struct gpio_desc *desc, const char *label); - void gpiod_free(struct gpio_desc *desc); -+ -+static inline int gpiod_request_user(struct gpio_desc *desc, const char *label) -+{ -+ int ret; -+ -+ ret = gpiod_request(desc, label); -+ if (ret == -EPROBE_DEFER) -+ ret = -ENODEV; -+ -+ return ret; -+} -+ - int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, - unsigned long lflags, enum gpiod_flags dflags); - int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -index 269437b013280..7e73ac6fb21db 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -@@ -1069,6 +1069,7 @@ struct amdgpu_device { - bool runpm; - bool in_runpm; - bool has_pr3; -+ bool is_fw_fb; - - bool pm_sysfs_en; - bool ucode_sysfs_en; -@@ -1078,8 +1079,6 @@ struct amdgpu_device { - char product_name[32]; - char serial[20]; - -- struct amdgpu_autodump autodump; -- - atomic_t throttling_logging_enabled; - struct ratelimit_state throttling_logging_rs; - uint32_t ras_hw_enabled; -@@ -1398,12 +1397,10 @@ int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_sta - int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev); - - void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps); --bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); - void amdgpu_acpi_detect(void); - #else - static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; } - static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } --static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } - static inline void amdgpu_acpi_detect(void) { } - static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; } - static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, -@@ -1412,6 +1409,14 @@ static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev, - enum amdgpu_ss ss_state) { return 0; } - #endif - -+#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) -+bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); -+bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); -+#else -+static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } -+static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } -+#endif -+ - int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, - uint64_t addr, struct amdgpu_bo **bo, - struct amdgpu_bo_va_mapping **mapping); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c -index 4811b0faafd9a..0e12315fa0cb8 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c -@@ -1031,6 +1031,20 @@ void amdgpu_acpi_detect(void) - } - } - -+#if IS_ENABLED(CONFIG_SUSPEND) -+/** -+ * amdgpu_acpi_is_s3_active -+ * -+ * @adev: amdgpu_device_pointer -+ * -+ * returns true if supported, false if not. -+ */ -+bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) -+{ -+ return !(adev->flags & AMD_IS_APU) || -+ (pm_suspend_target_state == PM_SUSPEND_MEM); -+} -+ - /** - * amdgpu_acpi_is_s0ix_active - * -@@ -1040,11 +1054,24 @@ void amdgpu_acpi_detect(void) - */ - bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) - { --#if IS_ENABLED(CONFIG_AMD_PMC) && IS_ENABLED(CONFIG_SUSPEND) -- if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { -- if (adev->flags & AMD_IS_APU) -- return pm_suspend_target_state == PM_SUSPEND_TO_IDLE; -+ if (!(adev->flags & AMD_IS_APU) || -+ (pm_suspend_target_state != PM_SUSPEND_TO_IDLE)) -+ return false; -+ -+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) { -+ dev_warn_once(adev->dev, -+ "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n" -+ "To use suspend-to-idle change the sleep mode in BIOS setup.\n"); -+ return false; - } --#endif -+ -+#if !IS_ENABLED(CONFIG_AMD_PMC) -+ dev_warn_once(adev->dev, -+ "Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n"); - return false; -+#else -+ return true; -+#endif /* CONFIG_AMD_PMC */ - } -+ -+#endif /* CONFIG_SUSPEND */ -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c -index 054c1a224defb..ab36cce59d2e4 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c -@@ -1393,7 +1393,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( - struct sg_table *sg = NULL; - uint64_t user_addr = 0; - struct amdgpu_bo *bo; -- struct drm_gem_object *gobj; -+ struct drm_gem_object *gobj = NULL; - u32 domain, alloc_domain; - u64 alloc_flags; - int ret; -@@ -1503,14 +1503,16 @@ allocate_init_user_pages_failed: - remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); - drm_vma_node_revoke(&gobj->vma_node, drm_priv); - err_node_allow: -- amdgpu_bo_unref(&bo); - /* Don't unreserve system mem limit twice */ - goto err_reserve_limit; - err_bo_create: - unreserve_mem_limit(adev, size, alloc_domain, !!sg); - err_reserve_limit: - mutex_destroy(&(*mem)->lock); -- kfree(*mem); -+ if (gobj) -+ drm_gem_object_put(gobj); -+ else -+ kfree(*mem); - err: - if (sg) { - sg_free_table(sg); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c -index 15c45b2a39835..714178f1b6c6e 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c -@@ -61,7 +61,7 @@ static void amdgpu_bo_list_free(struct kref *ref) - - int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, - struct drm_amdgpu_bo_list_entry *info, -- unsigned num_entries, struct amdgpu_bo_list **result) -+ size_t num_entries, struct amdgpu_bo_list **result) - { - unsigned last_entry = 0, first_userptr = num_entries; - struct amdgpu_bo_list_entry *array; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h -index c905a4cfc173d..044b41f0bfd9c 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h -@@ -61,7 +61,7 @@ int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, - int amdgpu_bo_list_create(struct amdgpu_device *adev, - struct drm_file *filp, - struct drm_amdgpu_bo_list_entry *info, -- unsigned num_entries, -+ size_t num_entries, - struct amdgpu_bo_list **list); - - static inline struct amdgpu_bo_list_entry * -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c -index b9c11c2b2885a..df1f9b88a53f9 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c -@@ -387,6 +387,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder) - native_mode->vdisplay != 0 && - native_mode->clock != 0) { - mode = drm_mode_duplicate(dev, native_mode); -+ if (!mode) -+ return NULL; -+ - mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; - drm_mode_set_name(mode); - -@@ -401,6 +404,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder) - * simpler. - */ - mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); -+ if (!mode) -+ return NULL; -+ - mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; - DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); - } -@@ -827,6 +833,7 @@ static int amdgpu_connector_vga_get_modes(struct drm_connector *connector) - - amdgpu_connector_get_edid(connector); - ret = amdgpu_connector_ddc_get_modes(connector); -+ amdgpu_get_native_mode(connector); - - return ret; - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -index 463b9c0283f7e..ec30d81586a79 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -@@ -27,7 +27,6 @@ - #include - #include - #include --#include - - #include "amdgpu.h" - #include "amdgpu_pm.h" -@@ -37,85 +36,7 @@ - #include "amdgpu_securedisplay.h" - #include "amdgpu_fw_attestation.h" - --int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev) --{ - #if defined(CONFIG_DEBUG_FS) -- unsigned long timeout = 600 * HZ; -- int ret; -- -- wake_up_interruptible(&adev->autodump.gpu_hang); -- -- ret = wait_for_completion_interruptible_timeout(&adev->autodump.dumping, timeout); -- if (ret == 0) { -- pr_err("autodump: timeout, move on to gpu recovery\n"); -- return -ETIMEDOUT; -- } --#endif -- return 0; --} -- --#if defined(CONFIG_DEBUG_FS) -- --static int amdgpu_debugfs_autodump_open(struct inode *inode, struct file *file) --{ -- struct amdgpu_device *adev = inode->i_private; -- int ret; -- -- file->private_data = adev; -- -- ret = down_read_killable(&adev->reset_sem); -- if (ret) -- return ret; -- -- if (adev->autodump.dumping.done) { -- reinit_completion(&adev->autodump.dumping); -- ret = 0; -- } else { -- ret = -EBUSY; -- } -- -- up_read(&adev->reset_sem); -- -- return ret; --} -- --static int amdgpu_debugfs_autodump_release(struct inode *inode, struct file *file) --{ -- struct amdgpu_device *adev = file->private_data; -- -- complete_all(&adev->autodump.dumping); -- return 0; --} -- --static unsigned int amdgpu_debugfs_autodump_poll(struct file *file, struct poll_table_struct *poll_table) --{ -- struct amdgpu_device *adev = file->private_data; -- -- poll_wait(file, &adev->autodump.gpu_hang, poll_table); -- -- if (amdgpu_in_reset(adev)) -- return POLLIN | POLLRDNORM | POLLWRNORM; -- -- return 0; --} -- --static const struct file_operations autodump_debug_fops = { -- .owner = THIS_MODULE, -- .open = amdgpu_debugfs_autodump_open, -- .poll = amdgpu_debugfs_autodump_poll, -- .release = amdgpu_debugfs_autodump_release, --}; -- --static void amdgpu_debugfs_autodump_init(struct amdgpu_device *adev) --{ -- init_completion(&adev->autodump.dumping); -- complete_all(&adev->autodump.dumping); -- init_waitqueue_head(&adev->autodump.gpu_hang); -- -- debugfs_create_file("amdgpu_autodump", 0600, -- adev_to_drm(adev)->primary->debugfs_root, -- adev, &autodump_debug_fops); --} - - /** - * amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes -@@ -1588,7 +1509,6 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) - } - - amdgpu_ras_debugfs_create_all(adev); -- amdgpu_debugfs_autodump_init(adev); - amdgpu_rap_debugfs_init(adev); - amdgpu_securedisplay_debugfs_init(adev); - amdgpu_fw_attestation_debugfs_init(adev); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h -index 141a8474e24f2..8b641f40fdf66 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h -@@ -26,10 +26,6 @@ - /* - * Debugfs - */ --struct amdgpu_autodump { -- struct completion dumping; -- struct wait_queue_head gpu_hang; --}; - - int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); - int amdgpu_debugfs_init(struct amdgpu_device *adev); -@@ -37,4 +33,3 @@ void amdgpu_debugfs_fini(struct amdgpu_device *adev); - void amdgpu_debugfs_fence_init(struct amdgpu_device *adev); - void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev); - void amdgpu_debugfs_gem_init(struct amdgpu_device *adev); --int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index af9bdf16eefd4..1545884dc703e 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -2394,6 +2394,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) - if (r) - goto init_failed; - -+ r = amdgpu_amdkfd_resume_iommu(adev); -+ if (r) -+ goto init_failed; -+ - r = amdgpu_device_ip_hw_init_phase1(adev); - if (r) - goto init_failed; -@@ -2432,10 +2436,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) - if (!adev->gmc.xgmi.pending_reset) - amdgpu_amdkfd_device_init(adev); - -- r = amdgpu_amdkfd_resume_iommu(adev); -- if (r) -- goto init_failed; -- - amdgpu_fru_get_product_info(adev); - - init_failed: -@@ -2745,6 +2745,11 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev) - adev->ip_blocks[i].status.hw = false; - } - -+ if (amdgpu_sriov_vf(adev)) { -+ if (amdgpu_virt_release_full_gpu(adev, false)) -+ DRM_ERROR("failed to release exclusive mode on fini\n"); -+ } -+ - return 0; - } - -@@ -2805,10 +2810,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) - - amdgpu_ras_fini(adev); - -- if (amdgpu_sriov_vf(adev)) -- if (amdgpu_virt_release_full_gpu(adev, false)) -- DRM_ERROR("failed to release exclusive mode on fini\n"); -- - return 0; - } - -@@ -3531,6 +3532,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, - adev->rmmio_size = pci_resource_len(adev->pdev, 2); - } - -+ for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++) -+ atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN); -+ - adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); - if (adev->rmmio == NULL) { - return -ENOMEM; -@@ -3850,7 +3854,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) - /* disable all interrupts */ - amdgpu_irq_disable_all(adev); - if (adev->mode_info.mode_config_initialized){ -- if (!amdgpu_device_has_dc_support(adev)) -+ if (!drm_drv_uses_atomic_modeset(adev_to_drm(adev))) - drm_helper_force_disable_all(adev_to_drm(adev)); - else - drm_atomic_helper_shutdown(adev_to_drm(adev)); -@@ -3876,8 +3880,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) - - void amdgpu_device_fini_sw(struct amdgpu_device *adev) - { -- amdgpu_device_ip_fini(adev); - amdgpu_fence_driver_sw_fini(adev); -+ amdgpu_device_ip_fini(adev); - release_firmware(adev->firmware.gpu_info_fw); - adev->firmware.gpu_info_fw = NULL; - adev->accel_working = false; -@@ -4466,10 +4470,6 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, - if (reset_context->reset_req_dev == adev) - job = reset_context->job; - -- /* no need to dump if device is not in good state during probe period */ -- if (!adev->gmc.xgmi.pending_reset) -- amdgpu_debugfs_wait_dump(adev); -- - if (amdgpu_sriov_vf(adev)) { - /* stop the data exchange thread */ - amdgpu_virt_fini_data_exchange(adev); -@@ -5130,7 +5130,7 @@ skip_hw_reset: - drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res); - } - -- if (!amdgpu_device_has_dc_support(tmp_adev) && !job_signaled) { -+ if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) { - drm_helper_resume_force_mode(adev_to_drm(tmp_adev)); - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c -index ada7bc19118ac..a919f5daacd91 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c -@@ -415,10 +415,15 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev) - } - } - -+union gc_info { -+ struct gc_info_v1_0 v1; -+ struct gc_info_v2_0 v2; -+}; -+ - int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev) - { - struct binary_header *bhdr; -- struct gc_info_v1_0 *gc_info; -+ union gc_info *gc_info; - - if (!adev->mman.discovery_bin) { - DRM_ERROR("ip discovery uninitialized\n"); -@@ -426,27 +431,54 @@ int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev) - } - - bhdr = (struct binary_header *)adev->mman.discovery_bin; -- gc_info = (struct gc_info_v1_0 *)(adev->mman.discovery_bin + -+ gc_info = (union gc_info *)(adev->mman.discovery_bin + - le16_to_cpu(bhdr->table_list[GC].offset)); -- -- adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->gc_num_se); -- adev->gfx.config.max_cu_per_sh = 2 * (le32_to_cpu(gc_info->gc_num_wgp0_per_sa) + -- le32_to_cpu(gc_info->gc_num_wgp1_per_sa)); -- adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->gc_num_sa_per_se); -- adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->gc_num_rb_per_se); -- adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->gc_num_gl2c); -- adev->gfx.config.max_gprs = le32_to_cpu(gc_info->gc_num_gprs); -- adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->gc_num_max_gs_thds); -- adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->gc_gs_table_depth); -- adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->gc_gsprim_buff_depth); -- adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->gc_double_offchip_lds_buffer); -- adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->gc_wave_size); -- adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->gc_max_waves_per_simd); -- adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->gc_max_scratch_slots_per_cu); -- adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->gc_lds_size); -- adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->gc_num_sc_per_se) / -- le32_to_cpu(gc_info->gc_num_sa_per_se); -- adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->gc_num_packer_per_sc); -- -+ switch (gc_info->v1.header.version_major) { -+ case 1: -+ adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->v1.gc_num_se); -+ adev->gfx.config.max_cu_per_sh = 2 * (le32_to_cpu(gc_info->v1.gc_num_wgp0_per_sa) + -+ le32_to_cpu(gc_info->v1.gc_num_wgp1_per_sa)); -+ adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->v1.gc_num_sa_per_se); -+ adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->v1.gc_num_rb_per_se); -+ adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->v1.gc_num_gl2c); -+ adev->gfx.config.max_gprs = le32_to_cpu(gc_info->v1.gc_num_gprs); -+ adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->v1.gc_num_max_gs_thds); -+ adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->v1.gc_gs_table_depth); -+ adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->v1.gc_gsprim_buff_depth); -+ adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->v1.gc_double_offchip_lds_buffer); -+ adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->v1.gc_wave_size); -+ adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->v1.gc_max_waves_per_simd); -+ adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->v1.gc_max_scratch_slots_per_cu); -+ adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->v1.gc_lds_size); -+ adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v1.gc_num_sc_per_se) / -+ le32_to_cpu(gc_info->v1.gc_num_sa_per_se); -+ adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v1.gc_num_packer_per_sc); -+ break; -+ case 2: -+ adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->v2.gc_num_se); -+ adev->gfx.config.max_cu_per_sh = le32_to_cpu(gc_info->v2.gc_num_cu_per_sh); -+ adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->v2.gc_num_sh_per_se); -+ adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->v2.gc_num_rb_per_se); -+ adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->v2.gc_num_tccs); -+ adev->gfx.config.max_gprs = le32_to_cpu(gc_info->v2.gc_num_gprs); -+ adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->v2.gc_num_max_gs_thds); -+ adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->v2.gc_gs_table_depth); -+ adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->v2.gc_gsprim_buff_depth); -+ adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->v2.gc_double_offchip_lds_buffer); -+ adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->v2.gc_wave_size); -+ adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->v2.gc_max_waves_per_simd); -+ adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->v2.gc_max_scratch_slots_per_cu); -+ adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->v2.gc_lds_size); -+ adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v2.gc_num_sc_per_se) / -+ le32_to_cpu(gc_info->v2.gc_num_sh_per_se); -+ adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v2.gc_num_packer_per_sc); -+ break; -+ default: -+ dev_err(adev->dev, -+ "Unhandled GC info table %d.%d\n", -+ gc_info->v1.header.version_major, -+ gc_info->v1.header.version_minor); -+ return -EINVAL; -+ } - return 0; - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -index ae6ab93c868b8..7444484a12bf8 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -@@ -384,7 +384,7 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach) - struct amdgpu_vm_bo_base *bo_base; - int r; - -- if (bo->tbo.resource->mem_type == TTM_PL_SYSTEM) -+ if (!bo->tbo.resource || bo->tbo.resource->mem_type == TTM_PL_SYSTEM) - return; - - r = ttm_bo_validate(&bo->tbo, &placement, &ctx); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index f18240f873878..5a7fef324c820 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #include "amdgpu.h" - #include "amdgpu_irq.h" -@@ -890,6 +891,717 @@ MODULE_PARM_DESC(smu_pptable_id, - "specify pptable id to be used (-1 = auto(default) value, 0 = use pptable from vbios, > 0 = soft pptable id)"); - module_param_named(smu_pptable_id, amdgpu_smu_pptable_id, int, 0444); - -+/* These devices are not supported by amdgpu. -+ * They are supported by the mach64, r128, radeon drivers -+ */ -+static const u16 amdgpu_unsupported_pciidlist[] = { -+ /* mach64 */ -+ 0x4354, -+ 0x4358, -+ 0x4554, -+ 0x4742, -+ 0x4744, -+ 0x4749, -+ 0x474C, -+ 0x474D, -+ 0x474E, -+ 0x474F, -+ 0x4750, -+ 0x4751, -+ 0x4752, -+ 0x4753, -+ 0x4754, -+ 0x4755, -+ 0x4756, -+ 0x4757, -+ 0x4758, -+ 0x4759, -+ 0x475A, -+ 0x4C42, -+ 0x4C44, -+ 0x4C47, -+ 0x4C49, -+ 0x4C4D, -+ 0x4C4E, -+ 0x4C50, -+ 0x4C51, -+ 0x4C52, -+ 0x4C53, -+ 0x5654, -+ 0x5655, -+ 0x5656, -+ /* r128 */ -+ 0x4c45, -+ 0x4c46, -+ 0x4d46, -+ 0x4d4c, -+ 0x5041, -+ 0x5042, -+ 0x5043, -+ 0x5044, -+ 0x5045, -+ 0x5046, -+ 0x5047, -+ 0x5048, -+ 0x5049, -+ 0x504A, -+ 0x504B, -+ 0x504C, -+ 0x504D, -+ 0x504E, -+ 0x504F, -+ 0x5050, -+ 0x5051, -+ 0x5052, -+ 0x5053, -+ 0x5054, -+ 0x5055, -+ 0x5056, -+ 0x5057, -+ 0x5058, -+ 0x5245, -+ 0x5246, -+ 0x5247, -+ 0x524b, -+ 0x524c, -+ 0x534d, -+ 0x5446, -+ 0x544C, -+ 0x5452, -+ /* radeon */ -+ 0x3150, -+ 0x3151, -+ 0x3152, -+ 0x3154, -+ 0x3155, -+ 0x3E50, -+ 0x3E54, -+ 0x4136, -+ 0x4137, -+ 0x4144, -+ 0x4145, -+ 0x4146, -+ 0x4147, -+ 0x4148, -+ 0x4149, -+ 0x414A, -+ 0x414B, -+ 0x4150, -+ 0x4151, -+ 0x4152, -+ 0x4153, -+ 0x4154, -+ 0x4155, -+ 0x4156, -+ 0x4237, -+ 0x4242, -+ 0x4336, -+ 0x4337, -+ 0x4437, -+ 0x4966, -+ 0x4967, -+ 0x4A48, -+ 0x4A49, -+ 0x4A4A, -+ 0x4A4B, -+ 0x4A4C, -+ 0x4A4D, -+ 0x4A4E, -+ 0x4A4F, -+ 0x4A50, -+ 0x4A54, -+ 0x4B48, -+ 0x4B49, -+ 0x4B4A, -+ 0x4B4B, -+ 0x4B4C, -+ 0x4C57, -+ 0x4C58, -+ 0x4C59, -+ 0x4C5A, -+ 0x4C64, -+ 0x4C66, -+ 0x4C67, -+ 0x4E44, -+ 0x4E45, -+ 0x4E46, -+ 0x4E47, -+ 0x4E48, -+ 0x4E49, -+ 0x4E4A, -+ 0x4E4B, -+ 0x4E50, -+ 0x4E51, -+ 0x4E52, -+ 0x4E53, -+ 0x4E54, -+ 0x4E56, -+ 0x5144, -+ 0x5145, -+ 0x5146, -+ 0x5147, -+ 0x5148, -+ 0x514C, -+ 0x514D, -+ 0x5157, -+ 0x5158, -+ 0x5159, -+ 0x515A, -+ 0x515E, -+ 0x5460, -+ 0x5462, -+ 0x5464, -+ 0x5548, -+ 0x5549, -+ 0x554A, -+ 0x554B, -+ 0x554C, -+ 0x554D, -+ 0x554E, -+ 0x554F, -+ 0x5550, -+ 0x5551, -+ 0x5552, -+ 0x5554, -+ 0x564A, -+ 0x564B, -+ 0x564F, -+ 0x5652, -+ 0x5653, -+ 0x5657, -+ 0x5834, -+ 0x5835, -+ 0x5954, -+ 0x5955, -+ 0x5974, -+ 0x5975, -+ 0x5960, -+ 0x5961, -+ 0x5962, -+ 0x5964, -+ 0x5965, -+ 0x5969, -+ 0x5a41, -+ 0x5a42, -+ 0x5a61, -+ 0x5a62, -+ 0x5b60, -+ 0x5b62, -+ 0x5b63, -+ 0x5b64, -+ 0x5b65, -+ 0x5c61, -+ 0x5c63, -+ 0x5d48, -+ 0x5d49, -+ 0x5d4a, -+ 0x5d4c, -+ 0x5d4d, -+ 0x5d4e, -+ 0x5d4f, -+ 0x5d50, -+ 0x5d52, -+ 0x5d57, -+ 0x5e48, -+ 0x5e4a, -+ 0x5e4b, -+ 0x5e4c, -+ 0x5e4d, -+ 0x5e4f, -+ 0x6700, -+ 0x6701, -+ 0x6702, -+ 0x6703, -+ 0x6704, -+ 0x6705, -+ 0x6706, -+ 0x6707, -+ 0x6708, -+ 0x6709, -+ 0x6718, -+ 0x6719, -+ 0x671c, -+ 0x671d, -+ 0x671f, -+ 0x6720, -+ 0x6721, -+ 0x6722, -+ 0x6723, -+ 0x6724, -+ 0x6725, -+ 0x6726, -+ 0x6727, -+ 0x6728, -+ 0x6729, -+ 0x6738, -+ 0x6739, -+ 0x673e, -+ 0x6740, -+ 0x6741, -+ 0x6742, -+ 0x6743, -+ 0x6744, -+ 0x6745, -+ 0x6746, -+ 0x6747, -+ 0x6748, -+ 0x6749, -+ 0x674A, -+ 0x6750, -+ 0x6751, -+ 0x6758, -+ 0x6759, -+ 0x675B, -+ 0x675D, -+ 0x675F, -+ 0x6760, -+ 0x6761, -+ 0x6762, -+ 0x6763, -+ 0x6764, -+ 0x6765, -+ 0x6766, -+ 0x6767, -+ 0x6768, -+ 0x6770, -+ 0x6771, -+ 0x6772, -+ 0x6778, -+ 0x6779, -+ 0x677B, -+ 0x6840, -+ 0x6841, -+ 0x6842, -+ 0x6843, -+ 0x6849, -+ 0x684C, -+ 0x6850, -+ 0x6858, -+ 0x6859, -+ 0x6880, -+ 0x6888, -+ 0x6889, -+ 0x688A, -+ 0x688C, -+ 0x688D, -+ 0x6898, -+ 0x6899, -+ 0x689b, -+ 0x689c, -+ 0x689d, -+ 0x689e, -+ 0x68a0, -+ 0x68a1, -+ 0x68a8, -+ 0x68a9, -+ 0x68b0, -+ 0x68b8, -+ 0x68b9, -+ 0x68ba, -+ 0x68be, -+ 0x68bf, -+ 0x68c0, -+ 0x68c1, -+ 0x68c7, -+ 0x68c8, -+ 0x68c9, -+ 0x68d8, -+ 0x68d9, -+ 0x68da, -+ 0x68de, -+ 0x68e0, -+ 0x68e1, -+ 0x68e4, -+ 0x68e5, -+ 0x68e8, -+ 0x68e9, -+ 0x68f1, -+ 0x68f2, -+ 0x68f8, -+ 0x68f9, -+ 0x68fa, -+ 0x68fe, -+ 0x7100, -+ 0x7101, -+ 0x7102, -+ 0x7103, -+ 0x7104, -+ 0x7105, -+ 0x7106, -+ 0x7108, -+ 0x7109, -+ 0x710A, -+ 0x710B, -+ 0x710C, -+ 0x710E, -+ 0x710F, -+ 0x7140, -+ 0x7141, -+ 0x7142, -+ 0x7143, -+ 0x7144, -+ 0x7145, -+ 0x7146, -+ 0x7147, -+ 0x7149, -+ 0x714A, -+ 0x714B, -+ 0x714C, -+ 0x714D, -+ 0x714E, -+ 0x714F, -+ 0x7151, -+ 0x7152, -+ 0x7153, -+ 0x715E, -+ 0x715F, -+ 0x7180, -+ 0x7181, -+ 0x7183, -+ 0x7186, -+ 0x7187, -+ 0x7188, -+ 0x718A, -+ 0x718B, -+ 0x718C, -+ 0x718D, -+ 0x718F, -+ 0x7193, -+ 0x7196, -+ 0x719B, -+ 0x719F, -+ 0x71C0, -+ 0x71C1, -+ 0x71C2, -+ 0x71C3, -+ 0x71C4, -+ 0x71C5, -+ 0x71C6, -+ 0x71C7, -+ 0x71CD, -+ 0x71CE, -+ 0x71D2, -+ 0x71D4, -+ 0x71D5, -+ 0x71D6, -+ 0x71DA, -+ 0x71DE, -+ 0x7200, -+ 0x7210, -+ 0x7211, -+ 0x7240, -+ 0x7243, -+ 0x7244, -+ 0x7245, -+ 0x7246, -+ 0x7247, -+ 0x7248, -+ 0x7249, -+ 0x724A, -+ 0x724B, -+ 0x724C, -+ 0x724D, -+ 0x724E, -+ 0x724F, -+ 0x7280, -+ 0x7281, -+ 0x7283, -+ 0x7284, -+ 0x7287, -+ 0x7288, -+ 0x7289, -+ 0x728B, -+ 0x728C, -+ 0x7290, -+ 0x7291, -+ 0x7293, -+ 0x7297, -+ 0x7834, -+ 0x7835, -+ 0x791e, -+ 0x791f, -+ 0x793f, -+ 0x7941, -+ 0x7942, -+ 0x796c, -+ 0x796d, -+ 0x796e, -+ 0x796f, -+ 0x9400, -+ 0x9401, -+ 0x9402, -+ 0x9403, -+ 0x9405, -+ 0x940A, -+ 0x940B, -+ 0x940F, -+ 0x94A0, -+ 0x94A1, -+ 0x94A3, -+ 0x94B1, -+ 0x94B3, -+ 0x94B4, -+ 0x94B5, -+ 0x94B9, -+ 0x9440, -+ 0x9441, -+ 0x9442, -+ 0x9443, -+ 0x9444, -+ 0x9446, -+ 0x944A, -+ 0x944B, -+ 0x944C, -+ 0x944E, -+ 0x9450, -+ 0x9452, -+ 0x9456, -+ 0x945A, -+ 0x945B, -+ 0x945E, -+ 0x9460, -+ 0x9462, -+ 0x946A, -+ 0x946B, -+ 0x947A, -+ 0x947B, -+ 0x9480, -+ 0x9487, -+ 0x9488, -+ 0x9489, -+ 0x948A, -+ 0x948F, -+ 0x9490, -+ 0x9491, -+ 0x9495, -+ 0x9498, -+ 0x949C, -+ 0x949E, -+ 0x949F, -+ 0x94C0, -+ 0x94C1, -+ 0x94C3, -+ 0x94C4, -+ 0x94C5, -+ 0x94C6, -+ 0x94C7, -+ 0x94C8, -+ 0x94C9, -+ 0x94CB, -+ 0x94CC, -+ 0x94CD, -+ 0x9500, -+ 0x9501, -+ 0x9504, -+ 0x9505, -+ 0x9506, -+ 0x9507, -+ 0x9508, -+ 0x9509, -+ 0x950F, -+ 0x9511, -+ 0x9515, -+ 0x9517, -+ 0x9519, -+ 0x9540, -+ 0x9541, -+ 0x9542, -+ 0x954E, -+ 0x954F, -+ 0x9552, -+ 0x9553, -+ 0x9555, -+ 0x9557, -+ 0x955f, -+ 0x9580, -+ 0x9581, -+ 0x9583, -+ 0x9586, -+ 0x9587, -+ 0x9588, -+ 0x9589, -+ 0x958A, -+ 0x958B, -+ 0x958C, -+ 0x958D, -+ 0x958E, -+ 0x958F, -+ 0x9590, -+ 0x9591, -+ 0x9593, -+ 0x9595, -+ 0x9596, -+ 0x9597, -+ 0x9598, -+ 0x9599, -+ 0x959B, -+ 0x95C0, -+ 0x95C2, -+ 0x95C4, -+ 0x95C5, -+ 0x95C6, -+ 0x95C7, -+ 0x95C9, -+ 0x95CC, -+ 0x95CD, -+ 0x95CE, -+ 0x95CF, -+ 0x9610, -+ 0x9611, -+ 0x9612, -+ 0x9613, -+ 0x9614, -+ 0x9615, -+ 0x9616, -+ 0x9640, -+ 0x9641, -+ 0x9642, -+ 0x9643, -+ 0x9644, -+ 0x9645, -+ 0x9647, -+ 0x9648, -+ 0x9649, -+ 0x964a, -+ 0x964b, -+ 0x964c, -+ 0x964e, -+ 0x964f, -+ 0x9710, -+ 0x9711, -+ 0x9712, -+ 0x9713, -+ 0x9714, -+ 0x9715, -+ 0x9802, -+ 0x9803, -+ 0x9804, -+ 0x9805, -+ 0x9806, -+ 0x9807, -+ 0x9808, -+ 0x9809, -+ 0x980A, -+ 0x9900, -+ 0x9901, -+ 0x9903, -+ 0x9904, -+ 0x9905, -+ 0x9906, -+ 0x9907, -+ 0x9908, -+ 0x9909, -+ 0x990A, -+ 0x990B, -+ 0x990C, -+ 0x990D, -+ 0x990E, -+ 0x990F, -+ 0x9910, -+ 0x9913, -+ 0x9917, -+ 0x9918, -+ 0x9919, -+ 0x9990, -+ 0x9991, -+ 0x9992, -+ 0x9993, -+ 0x9994, -+ 0x9995, -+ 0x9996, -+ 0x9997, -+ 0x9998, -+ 0x9999, -+ 0x999A, -+ 0x999B, -+ 0x999C, -+ 0x999D, -+ 0x99A0, -+ 0x99A2, -+ 0x99A4, -+ /* radeon secondary ids */ -+ 0x3171, -+ 0x3e70, -+ 0x4164, -+ 0x4165, -+ 0x4166, -+ 0x4168, -+ 0x4170, -+ 0x4171, -+ 0x4172, -+ 0x4173, -+ 0x496e, -+ 0x4a69, -+ 0x4a6a, -+ 0x4a6b, -+ 0x4a70, -+ 0x4a74, -+ 0x4b69, -+ 0x4b6b, -+ 0x4b6c, -+ 0x4c6e, -+ 0x4e64, -+ 0x4e65, -+ 0x4e66, -+ 0x4e67, -+ 0x4e68, -+ 0x4e69, -+ 0x4e6a, -+ 0x4e71, -+ 0x4f73, -+ 0x5569, -+ 0x556b, -+ 0x556d, -+ 0x556f, -+ 0x5571, -+ 0x5854, -+ 0x5874, -+ 0x5940, -+ 0x5941, -+ 0x5b72, -+ 0x5b73, -+ 0x5b74, -+ 0x5b75, -+ 0x5d44, -+ 0x5d45, -+ 0x5d6d, -+ 0x5d6f, -+ 0x5d72, -+ 0x5d77, -+ 0x5e6b, -+ 0x5e6d, -+ 0x7120, -+ 0x7124, -+ 0x7129, -+ 0x712e, -+ 0x712f, -+ 0x7162, -+ 0x7163, -+ 0x7166, -+ 0x7167, -+ 0x7172, -+ 0x7173, -+ 0x71a0, -+ 0x71a1, -+ 0x71a3, -+ 0x71a7, -+ 0x71bb, -+ 0x71e0, -+ 0x71e1, -+ 0x71e2, -+ 0x71e6, -+ 0x71e7, -+ 0x71f2, -+ 0x7269, -+ 0x726b, -+ 0x726e, -+ 0x72a0, -+ 0x72a8, -+ 0x72b1, -+ 0x72b3, -+ 0x793f, -+}; -+ - static const struct pci_device_id pciidlist[] = { - #ifdef CONFIG_DRM_AMDGPU_SI - {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, -@@ -1246,14 +1958,45 @@ MODULE_DEVICE_TABLE(pci, pciidlist); - - static const struct drm_driver amdgpu_kms_driver; - -+static bool amdgpu_is_fw_framebuffer(resource_size_t base, -+ resource_size_t size) -+{ -+ bool found = false; -+#if IS_REACHABLE(CONFIG_FB) -+ struct apertures_struct *a; -+ -+ a = alloc_apertures(1); -+ if (!a) -+ return false; -+ -+ a->ranges[0].base = base; -+ a->ranges[0].size = size; -+ -+ found = is_firmware_framebuffer(a); -+ kfree(a); -+#endif -+ return found; -+} -+ - static int amdgpu_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) - { - struct drm_device *ddev; - struct amdgpu_device *adev; - unsigned long flags = ent->driver_data; -- int ret, retry = 0; -+ int ret, retry = 0, i; - bool supports_atomic = false; -+ bool is_fw_fb; -+ resource_size_t base, size; -+ -+ if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev)) -+ amdgpu_aspm = 0; -+ -+ /* skip devices which are owned by radeon */ -+ for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) { -+ if (amdgpu_unsupported_pciidlist[i] == pdev->device) -+ return -ENODEV; -+ } - - if (amdgpu_virtual_display || - amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK)) -@@ -1310,6 +2053,10 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, - } - #endif - -+ base = pci_resource_start(pdev, 0); -+ size = pci_resource_len(pdev, 0); -+ is_fw_fb = amdgpu_is_fw_framebuffer(base, size); -+ - /* Get rid of things like offb */ - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver); - if (ret) -@@ -1322,6 +2069,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, - adev->dev = &pdev->dev; - adev->pdev = pdev; - ddev = adev_to_drm(adev); -+ adev->is_fw_fb = is_fw_fb; - - if (!supports_atomic) - ddev->driver_features &= ~DRIVER_ATOMIC; -@@ -1471,13 +2219,20 @@ static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work) - static int amdgpu_pmops_prepare(struct device *dev) - { - struct drm_device *drm_dev = dev_get_drvdata(dev); -+ struct amdgpu_device *adev = drm_to_adev(drm_dev); - - /* Return a positive number here so - * DPM_FLAG_SMART_SUSPEND works properly - */ - if (amdgpu_device_supports_boco(drm_dev)) -- return pm_runtime_suspended(dev) && -- pm_suspend_via_firmware(); -+ return pm_runtime_suspended(dev); -+ -+ /* if we will not support s3 or s2i for the device -+ * then skip suspend -+ */ -+ if (!amdgpu_acpi_is_s0ix_active(adev) && -+ !amdgpu_acpi_is_s3_active(adev)) -+ return 1; - - return 0; - } -@@ -1498,7 +2253,10 @@ static int amdgpu_pmops_suspend(struct device *dev) - adev->in_s3 = true; - r = amdgpu_device_suspend(drm_dev, true); - adev->in_s3 = false; -- -+ if (r) -+ return r; -+ if (!adev->in_s0ix) -+ r = amdgpu_asic_reset(adev); - return r; - } - -@@ -1575,12 +2333,27 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev) - if (amdgpu_device_supports_px(drm_dev)) - drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - -+ /* -+ * By setting mp1_state as PP_MP1_STATE_UNLOAD, MP1 will do some -+ * proper cleanups and put itself into a state ready for PNP. That -+ * can address some random resuming failure observed on BOCO capable -+ * platforms. -+ * TODO: this may be also needed for PX capable platform. -+ */ -+ if (amdgpu_device_supports_boco(drm_dev)) -+ adev->mp1_state = PP_MP1_STATE_UNLOAD; -+ - ret = amdgpu_device_suspend(drm_dev, false); - if (ret) { - adev->in_runpm = false; -+ if (amdgpu_device_supports_boco(drm_dev)) -+ adev->mp1_state = PP_MP1_STATE_NONE; - return ret; - } - -+ if (amdgpu_device_supports_boco(drm_dev)) -+ adev->mp1_state = PP_MP1_STATE_NONE; -+ - if (amdgpu_device_supports_px(drm_dev)) { - /* Only need to handle PCI state in the driver for ATPX - * PCI core handles it for _PR3. -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c -index 8d682befe0d68..14499f0de32dc 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c -@@ -552,9 +552,6 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) - if (!ring || !ring->fence_drv.initialized) - continue; - -- if (!ring->no_scheduler) -- drm_sched_stop(&ring->sched, NULL); -- - /* You can't wait for HW to signal if it's gone */ - if (!drm_dev_is_unplugged(&adev->ddev)) - r = amdgpu_fence_wait_empty(ring); -@@ -614,11 +611,6 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev) - if (!ring || !ring->fence_drv.initialized) - continue; - -- if (!ring->no_scheduler) { -- drm_sched_resubmit_jobs(&ring->sched); -- drm_sched_start(&ring->sched, true); -- } -- - /* enable the interrupt */ - if (ring->fence_drv.irq_src) - amdgpu_irq_get(adev, ring->fence_drv.irq_src, -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c -index d6aa032890ee8..a1e63ba4c54a5 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c -@@ -61,7 +61,7 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf) - } - - ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, -- TTM_BO_VM_NUM_PREFAULT, 1); -+ TTM_BO_VM_NUM_PREFAULT); - - drm_dev_exit(idx); - } else { -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c -index f3d62e196901a..0c7963dfacad1 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c -@@ -223,7 +223,7 @@ int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev, - */ - int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) - { -- unsigned int count = AMDGPU_IH_MAX_NUM_IVS; -+ unsigned int count; - u32 wptr; - - if (!ih->enabled || adev->shutdown) -@@ -232,6 +232,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) - wptr = amdgpu_ih_get_wptr(adev, ih); - - restart_ih: -+ count = AMDGPU_IH_MAX_NUM_IVS; - DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, ih->rptr, wptr); - - /* Order reading of wptr vs. reading of IH ring data */ -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c -index cc2e0c9cfe0a1..4f3c62adccbde 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c -@@ -333,7 +333,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev) - if (!amdgpu_device_has_dc_support(adev)) { - if (!adev->enable_virtual_display) - /* Disable vblank IRQs aggressively for power-saving */ -- /* XXX: can this be enabled for DC? */ - adev_to_drm(adev)->vblank_disable_immediate = true; - - r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -index 7e45640fbee02..09a2fe8390591 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -@@ -206,6 +206,12 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags) - adev->runpm = true; - break; - } -+ /* XXX: disable runtime pm if we are the primary adapter -+ * to avoid displays being re-enabled after DPMS. -+ * This needs to be sorted out and fixed properly. -+ */ -+ if (adev->is_fw_fb) -+ adev->runpm = false; - if (adev->runpm) - dev_info(adev->dev, "Using BACO for runtime pm\n"); - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c -index 9b41cb8c3de54..86e2090bbd6e0 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c -@@ -2207,12 +2207,16 @@ static int psp_hw_start(struct psp_context *psp) - return ret; - } - -+ if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) -+ goto skip_pin_bo; -+ - ret = psp_tmr_init(psp); - if (ret) { - DRM_ERROR("PSP tmr init failed!\n"); - return ret; - } - -+skip_pin_bo: - /* - * For ASICs with DF Cstate management centralized - * to PMFW, TMR setup should be performed after PMFW -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c -index 94126dc396888..8132f66177c27 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c -@@ -1892,7 +1892,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, - unsigned i; - int r; - -- if (direct_submit && !ring->sched.ready) { -+ if (!direct_submit && !ring->sched.ready) { - DRM_ERROR("Trying to move memory with ring turned off.\n"); - return -EINVAL; - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c -index ce982afeff913..7d58bf410be05 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c -@@ -142,15 +142,16 @@ static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc, - static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_atomic_state *state) - { -+ unsigned long flags; - if (crtc->state->event) { -- spin_lock(&crtc->dev->event_lock); -+ spin_lock_irqsave(&crtc->dev->event_lock, flags); - - if (drm_crtc_vblank_get(crtc) != 0) - drm_crtc_send_vblank_event(crtc, crtc->state->event); - else - drm_crtc_arm_vblank_event(crtc, crtc->state->event); - -- spin_unlock(&crtc->dev->event_lock); -+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - - crtc->state->event = NULL; - } -@@ -504,8 +505,8 @@ static int amdgpu_vkms_sw_fini(void *handle) - int i = 0; - - for (i = 0; i < adev->mode_info.num_crtc; i++) -- if (adev->mode_info.crtcs[i]) -- hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer); -+ if (adev->amdgpu_vkms_output[i].vblank_hrtimer.function) -+ hrtimer_cancel(&adev->amdgpu_vkms_output[i].vblank_hrtimer); - - kfree(adev->mode_info.bios_hardcoded_edid); - kfree(adev->amdgpu_vkms_output); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c -index 6b15cad78de9d..fd37bb39774c8 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c -@@ -768,11 +768,17 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, - * Check if all VM PDs/PTs are ready for updates - * - * Returns: -- * True if eviction list is empty. -+ * True if VM is not evicting. - */ - bool amdgpu_vm_ready(struct amdgpu_vm *vm) - { -- return list_empty(&vm->evicted); -+ bool ret; -+ -+ amdgpu_vm_eviction_lock(vm); -+ ret = !vm->evicting; -+ amdgpu_vm_eviction_unlock(vm); -+ -+ return ret && list_empty(&vm->evicted); - } - - /** -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c -index 978ac927ac11d..a799e0b1ff736 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c -@@ -386,6 +386,7 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) - "%s", "xgmi_hive_info"); - if (ret) { - dev_err(adev->dev, "XGMI: failed initializing kobject for xgmi hive\n"); -+ kobject_put(&hive->kobj); - kfree(hive); - hive = NULL; - goto pro_end; -diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c -index 54f28c075f214..f10ce740a29cc 100644 ---- a/drivers/gpu/drm/amd/amdgpu/cik.c -+++ b/drivers/gpu/drm/amd/amdgpu/cik.c -@@ -1428,6 +1428,10 @@ static int cik_asic_reset(struct amdgpu_device *adev) - { - int r; - -+ /* APUs don't have full asic reset */ -+ if (adev->flags & AMD_IS_APU) -+ return 0; -+ - if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) { - dev_info(adev->dev, "BACO reset\n"); - r = amdgpu_dpm_baco_reset(adev); -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c -index 16dbe593cba2e..970d59a21005a 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c -@@ -7729,8 +7729,19 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev) - switch (adev->asic_type) { - case CHIP_VANGOGH: - case CHIP_YELLOW_CARP: -- clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) | -- ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL); -+ preempt_disable(); -+ clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); -+ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); -+ hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); -+ /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over -+ * roughly every 42 seconds. -+ */ -+ if (hi_check != clock_hi) { -+ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); -+ clock_hi = hi_check; -+ } -+ preempt_enable(); -+ clock = clock_lo | (clock_hi << 32ULL); - break; - default: - preempt_disable(); -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -index 025184a556ee6..c39e53a41f13a 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -@@ -140,6 +140,11 @@ MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin"); - #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c - #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX 0 - -+#define mmGOLDEN_TSC_COUNT_UPPER_Renoir 0x0025 -+#define mmGOLDEN_TSC_COUNT_UPPER_Renoir_BASE_IDX 1 -+#define mmGOLDEN_TSC_COUNT_LOWER_Renoir 0x0026 -+#define mmGOLDEN_TSC_COUNT_LOWER_Renoir_BASE_IDX 1 -+ - enum ta_ras_gfx_subblock { - /*CPC*/ - TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0, -@@ -3056,8 +3061,8 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) - AMD_PG_SUPPORT_CP | - AMD_PG_SUPPORT_GDS | - AMD_PG_SUPPORT_RLC_SMU_HS)) { -- WREG32(mmRLC_JUMP_TABLE_RESTORE, -- adev->gfx.rlc.cp_table_gpu_addr >> 8); -+ WREG32_SOC15(GC, 0, mmRLC_JUMP_TABLE_RESTORE, -+ adev->gfx.rlc.cp_table_gpu_addr >> 8); - gfx_v9_0_init_gfx_power_gating(adev); - } - } -@@ -4228,19 +4233,38 @@ failed_kiq_read: - - static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev) - { -- uint64_t clock; -+ uint64_t clock, clock_lo, clock_hi, hi_check; - -- amdgpu_gfx_off_ctrl(adev, false); -- mutex_lock(&adev->gfx.gpu_clock_mutex); -- if (adev->asic_type == CHIP_VEGA10 && amdgpu_sriov_runtime(adev)) { -- clock = gfx_v9_0_kiq_read_clock(adev); -- } else { -- WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); -- clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | -- ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); -+ switch (adev->asic_type) { -+ case CHIP_RENOIR: -+ preempt_disable(); -+ clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); -+ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); -+ hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); -+ /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over -+ * roughly every 42 seconds. -+ */ -+ if (hi_check != clock_hi) { -+ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); -+ clock_hi = hi_check; -+ } -+ preempt_enable(); -+ clock = clock_lo | (clock_hi << 32ULL); -+ break; -+ default: -+ amdgpu_gfx_off_ctrl(adev, false); -+ mutex_lock(&adev->gfx.gpu_clock_mutex); -+ if (adev->asic_type == CHIP_VEGA10 && amdgpu_sriov_runtime(adev)) { -+ clock = gfx_v9_0_kiq_read_clock(adev); -+ } else { -+ WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); -+ clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | -+ ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); -+ } -+ mutex_unlock(&adev->gfx.gpu_clock_mutex); -+ amdgpu_gfx_off_ctrl(adev, true); -+ break; - } -- mutex_unlock(&adev->gfx.gpu_clock_mutex); -- amdgpu_gfx_off_ctrl(adev, true); - return clock; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c -index bda1542ef1ddf..f51fd0688eca7 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c -@@ -162,7 +162,6 @@ static void gfxhub_v1_0_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC);/* XXX for emulation. */ - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ATC_EN, 1); -diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c -index 14c1c1a297dd3..6e0ace2fbfab1 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c -@@ -196,7 +196,6 @@ static void gfxhub_v2_0_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC); /* UC, uncached */ - -diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c -index 1a374ec0514a5..9328991e8807f 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c -@@ -197,7 +197,6 @@ static void gfxhub_v2_1_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC); /* UC, uncached */ - -diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c -index e47104a1f5596..3c01be6610144 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c -@@ -1021,10 +1021,14 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) - return -EINVAL; - } - -+ if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) -+ goto skip_pin_bo; -+ - r = amdgpu_gart_table_vram_pin(adev); - if (r) - return r; - -+skip_pin_bo: - r = adev->gfxhub.funcs->gart_enable(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c -index 0e81e03e9b498..0fe714f54cca9 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c -@@ -841,12 +841,12 @@ static int gmc_v6_0_sw_init(void *handle) - - adev->gmc.mc_mask = 0xffffffffffULL; - -- r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44)); -+ r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); - if (r) { - dev_warn(adev->dev, "No suitable DMA available.\n"); - return r; - } -- adev->need_swiotlb = drm_need_swiotlb(44); -+ adev->need_swiotlb = drm_need_swiotlb(40); - - r = gmc_v6_0_init_microcode(adev); - if (r) { -diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c -index 492ebed2915be..63b890f1e8afb 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c -@@ -515,10 +515,10 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev) - static int gmc_v8_0_mc_init(struct amdgpu_device *adev) - { - int r; -+ u32 tmp; - - adev->gmc.vram_width = amdgpu_atombios_get_vram_width(adev); - if (!adev->gmc.vram_width) { -- u32 tmp; - int chansize, numchan; - - /* Get VRAM informations */ -@@ -562,8 +562,15 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) - adev->gmc.vram_width = numchan * chansize; - } - /* size in MB on si */ -- adev->gmc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; -- adev->gmc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; -+ tmp = RREG32(mmCONFIG_MEMSIZE); -+ /* some boards may have garbage in the upper 16 bits */ -+ if (tmp & 0xffff0000) { -+ DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); -+ if (tmp & 0xffff) -+ tmp &= 0xffff; -+ } -+ adev->gmc.mc_vram_size = tmp * 1024ULL * 1024ULL; -+ adev->gmc.real_vram_size = adev->gmc.mc_vram_size; - - if (!(adev->flags & AMD_IS_APU)) { - r = amdgpu_device_resize_fb_bar(adev); -diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c -index 5551359d5dfdc..c67e212443429 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c -@@ -72,6 +72,9 @@ - #define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x049d - #define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 - -+#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_DCN2 0x05ea -+#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_DCN2_BASE_IDX 2 -+ - - static const char *gfxhub_client_ids[] = { - "CB", -@@ -1103,6 +1106,8 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev) - u32 d1vga_control = RREG32_SOC15(DCE, 0, mmD1VGA_CONTROL); - unsigned size; - -+ /* TODO move to DC so GMC doesn't need to hard-code DCN registers */ -+ - if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) { - size = AMDGPU_VBIOS_VGA_ALLOCATION; - } else { -@@ -1110,7 +1115,6 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev) - - switch (adev->asic_type) { - case CHIP_RAVEN: -- case CHIP_RENOIR: - viewport = RREG32_SOC15(DCE, 0, mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION); - size = (REG_GET_FIELD(viewport, - HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) * -@@ -1118,6 +1122,14 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev) - HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH) * - 4); - break; -+ case CHIP_RENOIR: -+ viewport = RREG32_SOC15(DCE, 0, mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_DCN2); -+ size = (REG_GET_FIELD(viewport, -+ HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) * -+ REG_GET_FIELD(viewport, -+ HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH) * -+ 4); -+ break; - case CHIP_VEGA10: - case CHIP_VEGA12: - case CHIP_VEGA20: -@@ -1708,10 +1720,14 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) - return -EINVAL; - } - -+ if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) -+ goto skip_pin_bo; -+ - r = amdgpu_gart_table_vram_pin(adev); - if (r) - return r; - -+skip_pin_bo: - r = adev->gfxhub.funcs->gart_enable(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c -index a99953833820e..b3bede1dc41da 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c -@@ -145,7 +145,6 @@ static void mmhub_v1_0_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC);/* XXX for emulation. */ - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ATC_EN, 1); -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c -index f80a14a1b82dc..f5f7181f9af5f 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c -@@ -165,7 +165,6 @@ static void mmhub_v1_7_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC);/* XXX for emulation. */ - tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ATC_EN, 1); -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c -index 7ded6b2f058ef..2e58ed2caa485 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c -@@ -269,7 +269,6 @@ static void mmhub_v2_0_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC); /* UC, uncached */ - -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c -index 88e457a150e02..c63b6b9349350 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c -@@ -194,7 +194,6 @@ static void mmhub_v2_3_init_tlb_regs(struct amdgpu_device *adev) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC); /* UC, uncached */ - -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c -index c4ef822bbe8c5..ff49eeaf78824 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c -@@ -189,8 +189,6 @@ static void mmhub_v9_4_init_tlb_regs(struct amdgpu_device *adev, int hubid) - ENABLE_ADVANCED_DRIVER_MODEL, 1); - tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL, - SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); -- tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL, -- ECO_BITS, 0); - tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL, - MTYPE, MTYPE_UC);/* XXX for emulation. */ - tmp = REG_SET_FIELD(tmp, VMSHAREDVC0_MC_VM_MX_L1_TLB_CNTL, -diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c -index 8931000dcd418..e37948c157692 100644 ---- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c -@@ -2062,6 +2062,10 @@ static int sdma_v4_0_suspend(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ /* SMU saves SDMA state for us */ -+ if (adev->in_s0ix) -+ return 0; -+ - return sdma_v4_0_hw_fini(adev); - } - -@@ -2069,6 +2073,10 @@ static int sdma_v4_0_resume(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ /* SMU restores SDMA state for us */ -+ if (adev->in_s0ix) -+ return 0; -+ - return sdma_v4_0_hw_init(adev); - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c -index 0fc97c364fd76..6439d5c3d8d8b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/soc15.c -+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c -@@ -607,8 +607,8 @@ soc15_asic_reset_method(struct amdgpu_device *adev) - static int soc15_asic_reset(struct amdgpu_device *adev) - { - /* original raven doesn't have full asic reset */ -- if ((adev->apu_flags & AMD_APU_IS_RAVEN) && -- !(adev->apu_flags & AMD_APU_IS_RAVEN2)) -+ if ((adev->apu_flags & AMD_APU_IS_RAVEN) || -+ (adev->apu_flags & AMD_APU_IS_RAVEN2)) - return 0; - - switch (soc15_asic_reset_method(adev)) { -@@ -1273,8 +1273,11 @@ static int soc15_common_early_init(void *handle) - AMD_CG_SUPPORT_SDMA_LS | - AMD_CG_SUPPORT_VCN_MGCG; - -+ /* -+ * MMHUB PG needs to be disabled for Picasso for -+ * stability reasons. -+ */ - adev->pg_flags = AMD_PG_SUPPORT_SDMA | -- AMD_PG_SUPPORT_MMHUB | - AMD_PG_SUPPORT_VCN; - } else { - adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | -diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c -index 7232241e3bfb2..0fef925b66024 100644 ---- a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c -+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c -@@ -698,6 +698,19 @@ static int uvd_v3_1_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->uvd.idle_work); -+ -+ if (RREG32(mmUVD_STATUS) != 0) -+ uvd_v3_1_stop(adev); -+ -+ return 0; -+} -+ -+static int uvd_v3_1_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -722,17 +735,6 @@ static int uvd_v3_1_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- if (RREG32(mmUVD_STATUS) != 0) -- uvd_v3_1_stop(adev); -- -- return 0; --} -- --static int uvd_v3_1_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = uvd_v3_1_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c -index 52d6de969f462..c108b83817951 100644 ---- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c -+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c -@@ -212,6 +212,19 @@ static int uvd_v4_2_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->uvd.idle_work); -+ -+ if (RREG32(mmUVD_STATUS) != 0) -+ uvd_v4_2_stop(adev); -+ -+ return 0; -+} -+ -+static int uvd_v4_2_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -236,17 +249,6 @@ static int uvd_v4_2_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- if (RREG32(mmUVD_STATUS) != 0) -- uvd_v4_2_stop(adev); -- -- return 0; --} -- --static int uvd_v4_2_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = uvd_v4_2_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c -index db6d06758e4d4..563493d1f8306 100644 ---- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c -@@ -210,6 +210,19 @@ static int uvd_v5_0_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->uvd.idle_work); -+ -+ if (RREG32(mmUVD_STATUS) != 0) -+ uvd_v5_0_stop(adev); -+ -+ return 0; -+} -+ -+static int uvd_v5_0_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -234,17 +247,6 @@ static int uvd_v5_0_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- if (RREG32(mmUVD_STATUS) != 0) -- uvd_v5_0_stop(adev); -- -- return 0; --} -- --static int uvd_v5_0_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = uvd_v5_0_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c -index bc571833632ea..72f8762907681 100644 ---- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c -@@ -543,6 +543,19 @@ static int uvd_v6_0_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->uvd.idle_work); -+ -+ if (RREG32(mmUVD_STATUS) != 0) -+ uvd_v6_0_stop(adev); -+ -+ return 0; -+} -+ -+static int uvd_v6_0_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -567,17 +580,6 @@ static int uvd_v6_0_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- if (RREG32(mmUVD_STATUS) != 0) -- uvd_v6_0_stop(adev); -- -- return 0; --} -- --static int uvd_v6_0_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = uvd_v6_0_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c -index b6e82d75561f6..1fd9ca21a091b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c -@@ -606,6 +606,23 @@ static int uvd_v7_0_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->uvd.idle_work); -+ -+ if (!amdgpu_sriov_vf(adev)) -+ uvd_v7_0_stop(adev); -+ else { -+ /* full access mode, so don't touch any UVD register */ -+ DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); -+ } -+ -+ return 0; -+} -+ -+static int uvd_v7_0_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -630,21 +647,6 @@ static int uvd_v7_0_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- if (!amdgpu_sriov_vf(adev)) -- uvd_v7_0_stop(adev); -- else { -- /* full access mode, so don't touch any UVD register */ -- DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); -- } -- -- return 0; --} -- --static int uvd_v7_0_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = uvd_v7_0_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c -index b70c17f0c52e8..98952fd387e73 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c -@@ -479,6 +479,17 @@ static int vce_v2_0_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->vce.idle_work); -+ -+ return 0; -+} -+ -+static int vce_v2_0_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -502,14 +513,6 @@ static int vce_v2_0_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- return 0; --} -- --static int vce_v2_0_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = vce_v2_0_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c -index 9de66893ccd6d..8fb5df7181e09 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c -@@ -490,6 +490,21 @@ static int vce_v3_0_hw_fini(void *handle) - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ cancel_delayed_work_sync(&adev->vce.idle_work); -+ -+ r = vce_v3_0_wait_for_idle(handle); -+ if (r) -+ return r; -+ -+ vce_v3_0_stop(adev); -+ return vce_v3_0_set_clockgating_state(adev, AMD_CG_STATE_GATE); -+} -+ -+static int vce_v3_0_suspend(void *handle) -+{ -+ int r; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ - /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work -@@ -513,19 +528,6 @@ static int vce_v3_0_hw_fini(void *handle) - AMD_CG_STATE_GATE); - } - -- r = vce_v3_0_wait_for_idle(handle); -- if (r) -- return r; -- -- vce_v3_0_stop(adev); -- return vce_v3_0_set_clockgating_state(adev, AMD_CG_STATE_GATE); --} -- --static int vce_v3_0_suspend(void *handle) --{ -- int r; -- struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- - r = vce_v3_0_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c -index fec902b800c28..70b8c88d30513 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c -@@ -542,29 +542,8 @@ static int vce_v4_0_hw_fini(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -- /* -- * Proper cleanups before halting the HW engine: -- * - cancel the delayed idle work -- * - enable powergating -- * - enable clockgating -- * - disable dpm -- * -- * TODO: to align with the VCN implementation, move the -- * jobs for clockgating/powergating/dpm setting to -- * ->set_powergating_state(). -- */ - cancel_delayed_work_sync(&adev->vce.idle_work); - -- if (adev->pm.dpm_enabled) { -- amdgpu_dpm_enable_vce(adev, false); -- } else { -- amdgpu_asic_set_vce_clocks(adev, 0, 0); -- amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, -- AMD_PG_STATE_GATE); -- amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, -- AMD_CG_STATE_GATE); -- } -- - if (!amdgpu_sriov_vf(adev)) { - /* vce_v4_0_wait_for_idle(handle); */ - vce_v4_0_stop(adev); -@@ -594,6 +573,29 @@ static int vce_v4_0_suspend(void *handle) - drm_dev_exit(idx); - } - -+ /* -+ * Proper cleanups before halting the HW engine: -+ * - cancel the delayed idle work -+ * - enable powergating -+ * - enable clockgating -+ * - disable dpm -+ * -+ * TODO: to align with the VCN implementation, move the -+ * jobs for clockgating/powergating/dpm setting to -+ * ->set_powergating_state(). -+ */ -+ cancel_delayed_work_sync(&adev->vce.idle_work); -+ -+ if (adev->pm.dpm_enabled) { -+ amdgpu_dpm_enable_vce(adev, false); -+ } else { -+ amdgpu_asic_set_vce_clocks(adev, 0, 0); -+ amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, -+ AMD_PG_STATE_GATE); -+ amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, -+ AMD_CG_STATE_GATE); -+ } -+ - r = vce_v4_0_hw_fini(adev); - if (r) - return r; -diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c -index 121ee9f2b8d16..462008d506904 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c -@@ -253,6 +253,13 @@ static int vcn_v1_0_suspend(void *handle) - { - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ bool idle_work_unexecuted; -+ -+ idle_work_unexecuted = cancel_delayed_work_sync(&adev->vcn.idle_work); -+ if (idle_work_unexecuted) { -+ if (adev->pm.dpm_enabled) -+ amdgpu_dpm_enable_uvd(adev, false); -+ } - - r = vcn_v1_0_hw_fini(adev); - if (r) -diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c -index f4686e918e0d1..c405075a572c1 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c -@@ -22,6 +22,7 @@ - */ - - #include -+#include - - #include "amdgpu.h" - #include "amdgpu_vcn.h" -@@ -192,11 +193,14 @@ static int vcn_v2_0_sw_init(void *handle) - */ - static int vcn_v2_0_sw_fini(void *handle) - { -- int r; -+ int r, idx; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr; - -- fw_shared->present_flag_0 = 0; -+ if (drm_dev_enter(&adev->ddev, &idx)) { -+ fw_shared->present_flag_0 = 0; -+ drm_dev_exit(idx); -+ } - - amdgpu_virt_free_mm_table(adev); - -diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c -index e0c0c3734432e..a0956d8623770 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c -+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c -@@ -22,6 +22,7 @@ - */ - - #include -+#include - - #include "amdgpu.h" - #include "amdgpu_vcn.h" -@@ -233,17 +234,21 @@ static int vcn_v2_5_sw_init(void *handle) - */ - static int vcn_v2_5_sw_fini(void *handle) - { -- int i, r; -+ int i, r, idx; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - volatile struct amdgpu_fw_shared *fw_shared; - -- for (i = 0; i < adev->vcn.num_vcn_inst; i++) { -- if (adev->vcn.harvest_config & (1 << i)) -- continue; -- fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; -- fw_shared->present_flag_0 = 0; -+ if (drm_dev_enter(&adev->ddev, &idx)) { -+ for (i = 0; i < adev->vcn.num_vcn_inst; i++) { -+ if (adev->vcn.harvest_config & (1 << i)) -+ continue; -+ fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; -+ fw_shared->present_flag_0 = 0; -+ } -+ drm_dev_exit(idx); - } - -+ - if (amdgpu_sriov_vf(adev)) - amdgpu_virt_free_mm_table(adev); - -diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c -index fe9a7cc8d9eb0..6645ebbd2696c 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vi.c -+++ b/drivers/gpu/drm/amd/amdgpu/vi.c -@@ -956,6 +956,10 @@ static int vi_asic_reset(struct amdgpu_device *adev) - { - int r; - -+ /* APUs don't have full asic reset */ -+ if (adev->flags & AMD_IS_APU) -+ return 0; -+ - if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) { - dev_info(adev->dev, "BACO reset\n"); - r = amdgpu_dpm_baco_reset(adev); -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c -index cfedfb1e8596c..c33d689f29e8e 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c -@@ -1060,6 +1060,9 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink, - return -ENODEV; - /* same everything but the other direction */ - props2 = kmemdup(props, sizeof(*props2), GFP_KERNEL); -+ if (!props2) -+ return -ENOMEM; -+ - props2->node_from = id_to; - props2->node_to = id_from; - props2->kobj = NULL; -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c -index 4a416231b24c8..88c483f699894 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c -@@ -916,6 +916,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, - kfd_double_confirm_iommu_support(kfd); - - if (kfd_iommu_device_init(kfd)) { -+ kfd->use_iommu_v2 = false; - dev_err(kfd_device, "Error initializing iommuv2\n"); - goto device_iommu_error; - } -@@ -924,6 +925,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, - - svm_migrate_init((struct amdgpu_device *)kfd->kgd); - -+ if(kgd2kfd_resume_iommu(kfd)) -+ goto device_iommu_error; -+ - if (kfd_resume(kfd)) - goto kfd_resume_error; - -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c -index f8fce9d05f50c..4f2e0cc8a51a8 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c -@@ -1225,6 +1225,11 @@ static int stop_cpsch(struct device_queue_manager *dqm) - bool hanging; - - dqm_lock(dqm); -+ if (!dqm->sched_running) { -+ dqm_unlock(dqm); -+ return 0; -+ } -+ - if (!dqm->is_hws_hang) - unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); - hanging = dqm->is_hws_hang || dqm->is_resetting; -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -index 9d0f65a90002d..830809b694dd9 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -@@ -936,7 +936,7 @@ svm_range_split(struct svm_range *prange, uint64_t start, uint64_t last, - } - - static int --svm_range_split_tail(struct svm_range *prange, struct svm_range *new, -+svm_range_split_tail(struct svm_range *prange, - uint64_t new_last, struct list_head *insert_list) - { - struct svm_range *tail; -@@ -948,7 +948,7 @@ svm_range_split_tail(struct svm_range *prange, struct svm_range *new, - } - - static int --svm_range_split_head(struct svm_range *prange, struct svm_range *new, -+svm_range_split_head(struct svm_range *prange, - uint64_t new_start, struct list_head *insert_list) - { - struct svm_range *head; -@@ -1307,7 +1307,7 @@ struct svm_validate_context { - struct svm_range *prange; - bool intr; - unsigned long bitmap[MAX_GPU_INSTANCE]; -- struct ttm_validate_buffer tv[MAX_GPU_INSTANCE+1]; -+ struct ttm_validate_buffer tv[MAX_GPU_INSTANCE]; - struct list_head validate_list; - struct ww_acquire_ctx ticket; - }; -@@ -1334,11 +1334,6 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx) - ctx->tv[gpuidx].num_shared = 4; - list_add(&ctx->tv[gpuidx].head, &ctx->validate_list); - } -- if (ctx->prange->svm_bo && ctx->prange->ttm_res) { -- ctx->tv[MAX_GPU_INSTANCE].bo = &ctx->prange->svm_bo->bo->tbo; -- ctx->tv[MAX_GPU_INSTANCE].num_shared = 1; -- list_add(&ctx->tv[MAX_GPU_INSTANCE].head, &ctx->validate_list); -- } - - r = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->validate_list, - ctx->intr, NULL); -@@ -1570,7 +1565,6 @@ retry_flush_work: - static void svm_range_restore_work(struct work_struct *work) - { - struct delayed_work *dwork = to_delayed_work(work); -- struct amdkfd_process_info *process_info; - struct svm_range_list *svms; - struct svm_range *prange; - struct kfd_process *p; -@@ -1590,12 +1584,10 @@ static void svm_range_restore_work(struct work_struct *work) - * the lifetime of this thread, kfd_process and mm will be valid. - */ - p = container_of(svms, struct kfd_process, svms); -- process_info = p->kgd_process_info; - mm = p->mm; - if (!mm) - return; - -- mutex_lock(&process_info->lock); - svm_range_list_lock_and_flush_work(svms, mm); - mutex_lock(&svms->lock); - -@@ -1648,7 +1640,6 @@ static void svm_range_restore_work(struct work_struct *work) - out_reschedule: - mutex_unlock(&svms->lock); - mmap_write_unlock(mm); -- mutex_unlock(&process_info->lock); - - /* If validation failed, reschedule another attempt */ - if (evicted_ranges) { -@@ -1764,49 +1755,54 @@ static struct svm_range *svm_range_clone(struct svm_range *old) - } - - /** -- * svm_range_handle_overlap - split overlap ranges -- * @svms: svm range list header -- * @new: range added with this attributes -- * @start: range added start address, in pages -- * @last: range last address, in pages -- * @update_list: output, the ranges attributes are updated. For set_attr, this -- * will do validation and map to GPUs. For unmap, this will be -- * removed and unmap from GPUs -- * @insert_list: output, the ranges will be inserted into svms, attributes are -- * not changes. For set_attr, this will add into svms. -- * @remove_list:output, the ranges will be removed from svms -- * @left: the remaining range after overlap, For set_attr, this will be added -- * as new range. -+ * svm_range_add - add svm range and handle overlap -+ * @p: the range add to this process svms -+ * @start: page size aligned -+ * @size: page size aligned -+ * @nattr: number of attributes -+ * @attrs: array of attributes -+ * @update_list: output, the ranges need validate and update GPU mapping -+ * @insert_list: output, the ranges need insert to svms -+ * @remove_list: output, the ranges are replaced and need remove from svms - * -- * Total have 5 overlap cases. -+ * Check if the virtual address range has overlap with any existing ranges, -+ * split partly overlapping ranges and add new ranges in the gaps. All changes -+ * should be applied to the range_list and interval tree transactionally. If -+ * any range split or allocation fails, the entire update fails. Therefore any -+ * existing overlapping svm_ranges are cloned and the original svm_ranges left -+ * unchanged. - * -- * This function handles overlap of an address interval with existing -- * struct svm_ranges for applying new attributes. This may require -- * splitting existing struct svm_ranges. All changes should be applied to -- * the range_list and interval tree transactionally. If any split operation -- * fails, the entire update fails. Therefore the existing overlapping -- * svm_ranges are cloned and the original svm_ranges left unchanged. If the -- * transaction succeeds, the modified clones are added and the originals -- * freed. Otherwise the clones are removed and the old svm_ranges remain. -+ * If the transaction succeeds, the caller can update and insert clones and -+ * new ranges, then free the originals. - * -- * Context: The caller must hold svms->lock -+ * Otherwise the caller can free the clones and new ranges, while the old -+ * svm_ranges remain unchanged. -+ * -+ * Context: Process context, caller must hold svms->lock -+ * -+ * Return: -+ * 0 - OK, otherwise error code - */ - static int --svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, -- unsigned long start, unsigned long last, -- struct list_head *update_list, -- struct list_head *insert_list, -- struct list_head *remove_list, -- unsigned long *left) -+svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, -+ uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs, -+ struct list_head *update_list, struct list_head *insert_list, -+ struct list_head *remove_list) - { -+ unsigned long last = start + size - 1UL; -+ struct svm_range_list *svms = &p->svms; - struct interval_tree_node *node; -+ struct svm_range new = {0}; - struct svm_range *prange; - struct svm_range *tmp; - int r = 0; - -+ pr_debug("svms 0x%p [0x%llx 0x%lx]\n", &p->svms, start, last); -+ - INIT_LIST_HEAD(update_list); - INIT_LIST_HEAD(insert_list); - INIT_LIST_HEAD(remove_list); -+ svm_range_apply_attrs(p, &new, nattr, attrs); - - node = interval_tree_iter_first(&svms->objects, start, last); - while (node) { -@@ -1834,14 +1830,14 @@ svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, - - if (node->start < start) { - pr_debug("change old range start\n"); -- r = svm_range_split_head(prange, new, start, -+ r = svm_range_split_head(prange, start, - insert_list); - if (r) - goto out; - } - if (node->last > last) { - pr_debug("change old range last\n"); -- r = svm_range_split_tail(prange, new, last, -+ r = svm_range_split_tail(prange, last, - insert_list); - if (r) - goto out; -@@ -1853,7 +1849,7 @@ svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, - prange = old; - } - -- if (!svm_range_is_same_attrs(prange, new)) -+ if (!svm_range_is_same_attrs(prange, &new)) - list_add(&prange->update_list, update_list); - - /* insert a new node if needed */ -@@ -1873,8 +1869,16 @@ svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, - start = next_start; - } - -- if (left && start <= last) -- *left = last - start + 1; -+ /* add a final range at the end if needed */ -+ if (start <= last) { -+ prange = svm_range_new(svms, start, last); -+ if (!prange) { -+ r = -ENOMEM; -+ goto out; -+ } -+ list_add(&prange->insert_list, insert_list); -+ list_add(&prange->update_list, update_list); -+ } - - out: - if (r) -@@ -2702,59 +2706,6 @@ svm_range_is_valid(struct mm_struct *mm, uint64_t start, uint64_t size) - return true; - } - --/** -- * svm_range_add - add svm range and handle overlap -- * @p: the range add to this process svms -- * @start: page size aligned -- * @size: page size aligned -- * @nattr: number of attributes -- * @attrs: array of attributes -- * @update_list: output, the ranges need validate and update GPU mapping -- * @insert_list: output, the ranges need insert to svms -- * @remove_list: output, the ranges are replaced and need remove from svms -- * -- * Check if the virtual address range has overlap with the registered ranges, -- * split the overlapped range, copy and adjust pages address and vram nodes in -- * old and new ranges. -- * -- * Context: Process context, caller must hold svms->lock -- * -- * Return: -- * 0 - OK, otherwise error code -- */ --static int --svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, -- uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs, -- struct list_head *update_list, struct list_head *insert_list, -- struct list_head *remove_list) --{ -- uint64_t last = start + size - 1UL; -- struct svm_range_list *svms; -- struct svm_range new = {0}; -- struct svm_range *prange; -- unsigned long left = 0; -- int r = 0; -- -- pr_debug("svms 0x%p [0x%llx 0x%llx]\n", &p->svms, start, last); -- -- svm_range_apply_attrs(p, &new, nattr, attrs); -- -- svms = &p->svms; -- -- r = svm_range_handle_overlap(svms, &new, start, last, update_list, -- insert_list, remove_list, &left); -- if (r) -- return r; -- -- if (left) { -- prange = svm_range_new(svms, last - left + 1, last); -- list_add(&prange->insert_list, insert_list); -- list_add(&prange->update_list, update_list); -- } -- -- return 0; --} -- - /** - * svm_range_best_prefetch_location - decide the best prefetch location - * @prange: svm range structure -@@ -2979,7 +2930,6 @@ static int - svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, - uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs) - { -- struct amdkfd_process_info *process_info = p->kgd_process_info; - struct mm_struct *mm = current->mm; - struct list_head update_list; - struct list_head insert_list; -@@ -2998,8 +2948,6 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, - - svms = &p->svms; - -- mutex_lock(&process_info->lock); -- - svm_range_list_lock_and_flush_work(svms, mm); - - if (!svm_range_is_valid(mm, start, size)) { -@@ -3075,8 +3023,6 @@ out_unlock_range: - mutex_unlock(&svms->lock); - mmap_read_unlock(mm); - out: -- mutex_unlock(&process_info->lock); -- - pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid, - &p->svms, start, start + size - 1, r); - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 1ea31dcc7a8b0..cd611444ad177 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -1141,8 +1141,15 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) - case CHIP_RAVEN: - case CHIP_RENOIR: - init_data.flags.gpu_vm_support = true; -- if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) -+ switch (adev->dm.dmcub_fw_version) { -+ case 0: /* development */ -+ case 0x1: /* linux-firmware.git hash 6d9f399 */ -+ case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */ -+ init_data.flags.disable_dmcu = false; -+ break; -+ default: - init_data.flags.disable_dmcu = true; -+ } - break; - case CHIP_VANGOGH: - case CHIP_YELLOW_CARP: -@@ -2206,6 +2213,9 @@ static int dm_resume(void *handle) - if (amdgpu_in_reset(adev)) { - dc_state = dm->cached_dc_state; - -+ if (dc_enable_dmub_notifications(adev->dm.dc)) -+ amdgpu_dm_outbox_init(adev); -+ - r = dm_dmub_hw_init(adev); - if (r) - DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); -@@ -2217,8 +2227,8 @@ static int dm_resume(void *handle) - - for (i = 0; i < dc_state->stream_count; i++) { - dc_state->streams[i]->mode_changed = true; -- for (j = 0; j < dc_state->stream_status->plane_count; j++) { -- dc_state->stream_status->plane_states[j]->update_flags.raw -+ for (j = 0; j < dc_state->stream_status[i].plane_count; j++) { -+ dc_state->stream_status[i].plane_states[j]->update_flags.raw - = 0xffffffff; - } - } -@@ -2253,6 +2263,10 @@ static int dm_resume(void *handle) - /* TODO: Remove dc_state->dccg, use dc->dccg directly. */ - dc_resource_state_construct(dm->dc, dm_state->context); - -+ /* Re-enable outbox interrupts for DPIA. */ -+ if (dc_enable_dmub_notifications(adev->dm.dc)) -+ amdgpu_dm_outbox_init(adev); -+ - /* Before powering on DC we need to re-initialize DMUB. */ - r = dm_dmub_hw_init(adev); - if (r) -@@ -3213,7 +3227,7 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) - - /* Use GRPH_PFLIP interrupt */ - for (i = DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT; -- i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + adev->mode_info.num_crtc - 1; -+ i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + dc->caps.max_otg_num - 1; - i++) { - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->pageflip_irq); - if (r) { -@@ -3798,6 +3812,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) - } - #endif - -+ /* Disable vblank IRQs aggressively for power-saving. */ -+ adev_to_drm(adev)->vblank_disable_immediate = true; -+ - /* loops over all connectors on the board */ - for (i = 0; i < link_cnt; i++) { - struct dc_link *link = NULL; -@@ -3839,8 +3856,17 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) - } else if (dc_link_detect(link, DETECT_REASON_BOOT)) { - amdgpu_dm_update_connector_after_detect(aconnector); - register_backlight_device(dm, link); -+ -+ if (dm->num_of_edps) -+ update_connector_ext_caps(aconnector); - if (amdgpu_dc_feature_mask & DC_PSR_MASK) - amdgpu_dm_set_psr_caps(link); -+ -+ /* TODO: Fix vblank control helpers to delay PSR entry to allow this when -+ * PSR is also supported. -+ */ -+ if (link->psr_settings.psr_feature_enabled) -+ adev_to_drm(adev)->vblank_disable_immediate = false; - } - - -@@ -5587,6 +5613,7 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector, - struct dsc_dec_dpcd_caps *dsc_caps) - { - stream->timing.flags.DSC = 0; -+ dsc_caps->is_dsc_supported = false; - - if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) { - dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc, -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c -index cce062adc4391..8a441a22c46ec 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c -@@ -314,6 +314,14 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) - ret = -EINVAL; - goto cleanup; - } -+ -+ if ((aconn->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) && -+ (aconn->base.connector_type != DRM_MODE_CONNECTOR_eDP)) { -+ DRM_DEBUG_DRIVER("No DP connector available for CRC source\n"); -+ ret = -EINVAL; -+ goto cleanup; -+ } -+ - } - - #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -index 8080bba5b7a76..e94ddd5e7b638 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -@@ -247,6 +247,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, - { - struct amdgpu_dm_connector *connector = file_inode(f)->i_private; - struct dc_link *link = connector->dc_link; -+ struct dc *dc = (struct dc *)link->dc; - struct dc_link_settings prefer_link_settings; - char *wr_buf = NULL; - const uint32_t wr_buf_size = 40; -@@ -313,7 +314,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, - prefer_link_settings.lane_count = param[0]; - prefer_link_settings.link_rate = param[1]; - -- dp_retrain_link_dp_test(link, &prefer_link_settings, false); -+ dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true); - - kfree(wr_buf); - return size; -@@ -2907,10 +2908,13 @@ static int crc_win_update_set(void *data, u64 val) - struct amdgpu_device *adev = drm_to_adev(new_crtc->dev); - struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk; - -+ if (!crc_rd_wrk) -+ return 0; -+ - if (val) { - spin_lock_irq(&adev_to_drm(adev)->event_lock); - spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock); -- if (crc_rd_wrk && crc_rd_wrk->crtc) { -+ if (crc_rd_wrk->crtc) { - old_crtc = crc_rd_wrk->crtc; - old_acrtc = to_amdgpu_crtc(old_crtc); - } -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c -index 6fee12c91ef59..d793eec69d61e 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c -@@ -40,6 +40,39 @@ - - #include "dm_helpers.h" - -+struct monitor_patch_info { -+ unsigned int manufacturer_id; -+ unsigned int product_id; -+ void (*patch_func)(struct dc_edid_caps *edid_caps, unsigned int param); -+ unsigned int patch_param; -+}; -+static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param); -+ -+static const struct monitor_patch_info monitor_patch_table[] = { -+{0x6D1E, 0x5BBF, set_max_dsc_bpp_limit, 15}, -+{0x6D1E, 0x5B9A, set_max_dsc_bpp_limit, 15}, -+}; -+ -+static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param) -+{ -+ if (edid_caps) -+ edid_caps->panel_patch.max_dsc_target_bpp_limit = param; -+} -+ -+static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps) -+{ -+ int i, ret = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(monitor_patch_table); i++) -+ if ((edid_caps->manufacturer_id == monitor_patch_table[i].manufacturer_id) -+ && (edid_caps->product_id == monitor_patch_table[i].product_id)) { -+ monitor_patch_table[i].patch_func(edid_caps, monitor_patch_table[i].patch_param); -+ ret++; -+ } -+ -+ return ret; -+} -+ - /* dm_helpers_parse_edid_caps - * - * Parse edid caps -@@ -125,6 +158,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps( - kfree(sads); - kfree(sadb); - -+ amdgpu_dm_patch_edid_caps(edid_caps); -+ - return result; - } - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -index 7af0d58c231b6..74885ff77f96a 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -@@ -36,6 +36,8 @@ - #include "dm_helpers.h" - - #include "dc_link_ddc.h" -+#include "ddc_service_types.h" -+#include "dpcd_defs.h" - - #include "i2caux_interface.h" - #include "dmub_cmd.h" -@@ -155,6 +157,16 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { - }; - - #if defined(CONFIG_DRM_AMD_DC_DCN) -+static bool needs_dsc_aux_workaround(struct dc_link *link) -+{ -+ if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && -+ (link->dpcd_caps.dpcd_rev.raw == DPCD_REV_14 || link->dpcd_caps.dpcd_rev.raw == DPCD_REV_12) && -+ link->dpcd_caps.sink_count.bits.SINK_COUNT >= 2) -+ return true; -+ -+ return false; -+} -+ - static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) - { - struct dc_sink *dc_sink = aconnector->dc_sink; -@@ -164,7 +176,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto - u8 *dsc_branch_dec_caps = NULL; - - aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port); --#if defined(CONFIG_HP_HOOK_WORKAROUND) -+ - /* - * drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs - * because it only check the dsc/fec caps of the "port variable" and not the dock -@@ -174,10 +186,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto - * Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux - * - */ -- -- if (!aconnector->dsc_aux && !port->parent->port_parent) -+ if (!aconnector->dsc_aux && !port->parent->port_parent && -+ needs_dsc_aux_workaround(aconnector->dc_link)) - aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; --#endif -+ - if (!aconnector->dsc_aux) - return false; - -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c -index bb31541f80723..6420527fe476c 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c -@@ -306,8 +306,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) - case FAMILY_NV: - if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { - dcn3_clk_mgr_destroy(clk_mgr); -- } -- if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { -+ } else if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { - dcn3_clk_mgr_destroy(clk_mgr); - } - if (ASICREV_IS_BEIGE_GOBY_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c -index 1861a147a7fa1..5c5cbeb59c4d9 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c -@@ -437,8 +437,10 @@ static void dcn3_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) - clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1; - - /* Refresh bounding box */ -+ DC_FP_START(); - clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box( - clk_mgr->base.ctx->dc, clk_mgr_base->bw_params); -+ DC_FP_END(); - } - - static bool dcn3_is_smu_present(struct clk_mgr *clk_mgr_base) -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c -index 7046da14bb2a5..329ce4e84b83c 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c -@@ -582,32 +582,32 @@ static struct wm_table lpddr5_wm_table = { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, -- .sr_exit_time_us = 5.32, -- .sr_enter_plus_exit_time_us = 6.38, -+ .sr_exit_time_us = 13.5, -+ .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, -- .sr_exit_time_us = 9.82, -- .sr_enter_plus_exit_time_us = 11.196, -+ .sr_exit_time_us = 13.5, -+ .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, -- .sr_exit_time_us = 9.89, -- .sr_enter_plus_exit_time_us = 11.24, -+ .sr_exit_time_us = 13.5, -+ .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.65333, -- .sr_exit_time_us = 9.748, -- .sr_enter_plus_exit_time_us = 11.102, -+ .sr_exit_time_us = 13.5, -+ .sr_enter_plus_exit_time_us = 16.5, - .valid = true, - }, - } -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c -index 377c4e53a2b37..8f6e6496ea787 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c -@@ -157,6 +157,7 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, - union display_idle_optimization_u idle_info = { 0 }; - idle_info.idle_info.df_request_disabled = 1; - idle_info.idle_info.phy_ref_clk_off = 1; -+ idle_info.idle_info.s0i2_rdy = 1; - dcn31_smu_set_display_idle_optimization(clk_mgr, idle_info.data); - /* update power state */ - clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER; -@@ -323,38 +324,38 @@ static struct clk_bw_params dcn31_bw_params = { - - }; - --static struct wm_table ddr4_wm_table = { -+static struct wm_table ddr5_wm_table = { - .entries = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, -- .sr_exit_time_us = 6.09, -- .sr_enter_plus_exit_time_us = 7.14, -+ .sr_exit_time_us = 9, -+ .sr_enter_plus_exit_time_us = 11, - .valid = true, - }, - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, -- .sr_exit_time_us = 10.12, -- .sr_enter_plus_exit_time_us = 11.48, -+ .sr_exit_time_us = 9, -+ .sr_enter_plus_exit_time_us = 11, - .valid = true, - }, - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, -- .sr_exit_time_us = 10.12, -- .sr_enter_plus_exit_time_us = 11.48, -+ .sr_exit_time_us = 9, -+ .sr_enter_plus_exit_time_us = 11, - .valid = true, - }, - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, - .pstate_latency_us = 11.72, -- .sr_exit_time_us = 10.12, -- .sr_enter_plus_exit_time_us = 11.48, -+ .sr_exit_time_us = 9, -+ .sr_enter_plus_exit_time_us = 11, - .valid = true, - }, - } -@@ -682,7 +683,7 @@ void dcn31_clk_mgr_construct( - if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) { - dcn31_bw_params.wm_table = lpddr5_wm_table; - } else { -- dcn31_bw_params.wm_table = ddr4_wm_table; -+ dcn31_bw_params.wm_table = ddr5_wm_table; - } - /* Saved clocks configured at boot for debug purposes */ - dcn31_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info); -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c -index 8c2b77eb94593..21d2cbc3cbb20 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c -@@ -119,6 +119,16 @@ int dcn31_smu_send_msg_with_param( - - result = dcn31_smu_wait_for_response(clk_mgr, 10, 200000); - -+ if (result == VBIOSSMC_Result_Failed) { -+ if (msg_id == VBIOSSMC_MSG_TransferTableDram2Smu && -+ param == TABLE_WATERMARKS) -+ DC_LOG_WARNING("Watermarks table not configured properly by SMU"); -+ else -+ ASSERT(0); -+ REG_WRITE(MP1_SMN_C2PMSG_91, VBIOSSMC_Result_OK); -+ return -1; -+ } -+ - if (IS_SMU_TIMEOUT(result)) { - ASSERT(0); - dm_helpers_smu_timeout(CTX, msg_id, param, 10 * 200000); -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index c798c65d42765..b37c4d2e7a1e0 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -891,10 +891,13 @@ static bool dc_construct(struct dc *dc, - goto fail; - #ifdef CONFIG_DRM_AMD_DC_DCN - dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; --#endif - -- if (dc->res_pool->funcs->update_bw_bounding_box) -+ if (dc->res_pool->funcs->update_bw_bounding_box) { -+ DC_FP_START(); - dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); -+ DC_FP_END(); -+ } -+#endif - - /* Creation of current_state must occur after dc->dml - * is initialized in dc_create_resource_pool because -@@ -1118,6 +1121,8 @@ struct dc *dc_create(const struct dc_init_data *init_params) - - dc->caps.max_dp_protocol_version = DP_VERSION_1_4; - -+ dc->caps.max_otg_num = dc->res_pool->res_cap->num_timing_generator; -+ - if (dc->res_pool->dmcu != NULL) - dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version; - } -@@ -2703,7 +2708,8 @@ static void commit_planes_for_stream(struct dc *dc, - #endif - - if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) -- if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { -+ if (top_pipe_to_program && -+ top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { - if (should_use_dmub_lock(stream->link)) { - union dmub_hw_lock_flags hw_locks = { 0 }; - struct dmub_hw_lock_inst_flags inst_flags = { 0 }; -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c -index 1e44b13c1c7de..3c4205248efc2 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c -@@ -1696,6 +1696,8 @@ static void enable_stream_features(struct pipe_ctx *pipe_ctx) - union down_spread_ctrl old_downspread; - union down_spread_ctrl new_downspread; - -+ memset(&old_downspread, 0, sizeof(old_downspread)); -+ - core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL, - &old_downspread.raw, sizeof(old_downspread)); - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c -index 6d655e158267a..605b96873d8cd 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c -@@ -3650,7 +3650,9 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) - lttpr_dpcd_data, - sizeof(lttpr_dpcd_data)); - if (status != DC_OK) { -- dm_error("%s: Read LTTPR caps data failed.\n", __func__); -+#if defined(CONFIG_DRM_AMD_DC_DCN) -+ DC_LOG_DP2("%s: Read LTTPR caps data failed.\n", __func__); -+#endif - return false; - } - -@@ -3913,6 +3915,26 @@ static bool retrieve_link_cap(struct dc_link *link) - dp_hw_fw_revision.ieee_fw_rev, - sizeof(dp_hw_fw_revision.ieee_fw_rev)); - -+ /* Quirk for Apple MBP 2018 15" Retina panels: wrong DP_MAX_LINK_RATE */ -+ { -+ uint8_t str_mbp_2018[] = { 101, 68, 21, 103, 98, 97 }; -+ uint8_t fwrev_mbp_2018[] = { 7, 4 }; -+ uint8_t fwrev_mbp_2018_vega[] = { 8, 4 }; -+ -+ /* We also check for the firmware revision as 16,1 models have an -+ * identical device id and are incorrectly quirked otherwise. -+ */ -+ if ((link->dpcd_caps.sink_dev_id == 0x0010fa) && -+ !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2018, -+ sizeof(str_mbp_2018)) && -+ (!memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018, -+ sizeof(fwrev_mbp_2018)) || -+ !memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018_vega, -+ sizeof(fwrev_mbp_2018_vega)))) { -+ link->reported_link_cap.link_rate = LINK_RATE_RBR2; -+ } -+ } -+ - memset(&link->dpcd_caps.dsc_caps, '\0', - sizeof(link->dpcd_caps.dsc_caps)); - memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap)); -@@ -4690,7 +4712,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready) - link_enc->funcs->fec_set_ready(link_enc, true); - link->fec_state = dc_link_fec_ready; - } else { -- link_enc->funcs->fec_set_ready(link->link_enc, false); -+ link_enc->funcs->fec_set_ready(link_enc, false); - link->fec_state = dc_link_fec_not_ready; - dm_error("dpcd write failed to set fec_ready"); - } -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -index a60396d5be445..7ae409f7dcf8d 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -@@ -1623,6 +1623,10 @@ bool dc_is_stream_unchanged( - if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) - return false; - -+ // Only Have Audio left to check whether it is same or not. This is a corner case for Tiled sinks -+ if (old_stream->audio_info.mode_count != stream->audio_info.mode_count) -+ return false; -+ - return true; - } - -@@ -1795,9 +1799,6 @@ enum dc_status dc_remove_stream_from_ctx( - dc->res_pool, - del_pipe->stream_res.stream_enc, - false); -- /* Release link encoder from stream in new dc_state. */ -- if (dc->res_pool->funcs->link_enc_unassign) -- dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream); - - if (del_pipe->stream_res.audio) - update_audio_usage( -diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h -index 3ab52d9a82cf6..e0f58fab5e8ed 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc.h -+++ b/drivers/gpu/drm/amd/display/dc/dc.h -@@ -185,6 +185,7 @@ struct dc_caps { - struct dc_color_caps color; - bool vbios_lttpr_aware; - bool vbios_lttpr_enable; -+ uint32_t max_otg_num; - }; - - struct dc_bug_wa { -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -index df8a7718a85fc..3af49cdf89ebd 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -@@ -1522,7 +1522,7 @@ void dcn10_power_down_on_boot(struct dc *dc) - for (i = 0; i < dc->link_count; i++) { - struct dc_link *link = dc->links[i]; - -- if (link->link_enc->funcs->is_dig_enabled && -+ if (link->link_enc && link->link_enc->funcs->is_dig_enabled && - link->link_enc->funcs->is_dig_enabled(link->link_enc) && - dc->hwss.power_down) { - dc->hwss.power_down(dc); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c -index 34001a30d449a..10e613ec7d24f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c -@@ -78,6 +78,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { - .get_clock = dcn10_get_clock, - .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, - .calc_vupdate_position = dcn10_calc_vupdate_position, -+ .power_down = dce110_power_down, - .set_backlight_level = dce110_set_backlight_level, - .set_abm_immediate_disable = dce110_set_abm_immediate_disable, - .set_pipe = dce110_set_pipe, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c -index e3e01b17c164e..ede11eb120d4f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c -@@ -1854,7 +1854,9 @@ static void swizzle_to_dml_params( - case DC_SW_VAR_D_X: - *sw_mode = dm_sw_var_d_x; - break; -- -+ case DC_SW_VAR_R_X: -+ *sw_mode = dm_sw_var_r_x; -+ break; - default: - ASSERT(0); /* Not supported */ - break; -@@ -3152,7 +3154,7 @@ void dcn20_calculate_dlg_params( - - context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml, - &context->res_ctx.pipe_ctx[i].rq_regs, -- pipes[pipe_idx].pipe); -+ &pipes[pipe_idx].pipe); - pipe_idx++; - } - } -@@ -3668,16 +3670,22 @@ static bool init_soc_bounding_box(struct dc *dc, - clock_limits_available = (status == PP_SMU_RESULT_OK); - } - -- if (clock_limits_available && uclk_states_available && num_states) -+ if (clock_limits_available && uclk_states_available && num_states) { -+ DC_FP_START(); - dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states); -- else if (clock_limits_available) -+ DC_FP_END(); -+ } else if (clock_limits_available) { -+ DC_FP_START(); - dcn20_cap_soc_clocks(loaded_bb, max_clocks); -+ DC_FP_END(); -+ } - } - - loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; - loaded_ip->max_num_dpp = pool->base.pipe_count; -+ DC_FP_START(); - dcn20_patch_bounding_box(dc, loaded_bb); -- -+ DC_FP_END(); - return true; - } - -@@ -3697,8 +3705,6 @@ static bool dcn20_resource_construct( - enum dml_project dml_project_version = - get_dml_project_version(ctx->asic_id.hw_internal_rev); - -- DC_FP_START(); -- - ctx->dc_bios->regs = &bios_regs; - pool->base.funcs = &dcn20_res_pool_funcs; - -@@ -4047,12 +4053,10 @@ static bool dcn20_resource_construct( - pool->base.oem_device = NULL; - } - -- DC_FP_END(); - return true; - - create_fail: - -- DC_FP_END(); - dcn20_resource_destruct(pool); - - return false; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c -index fbbdf99761838..92a308ad1213c 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c -@@ -874,7 +874,7 @@ static const struct dc_debug_options debug_defaults_drv = { - .clock_trace = true, - .disable_pplib_clock_request = true, - .min_disp_clk_khz = 100000, -- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, -+ .pipe_split_policy = MPC_SPLIT_DYNAMIC, - .force_single_disp_pipe_split = false, - .disable_dcc = DCC_ENABLE, - .vsr_support = true, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -index fafed1e4a998d..0950784bafa49 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -@@ -1002,7 +1002,8 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, - /* turning off DPG */ - pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, false); - for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) -- mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false); -+ if (mpcc_pipe->plane_res.hubp) -+ mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false); - - stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space, - color_depth, solid_color, width, height, offset); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c -index a0de309475a97..0294d0cc47595 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c -@@ -840,7 +840,7 @@ static const struct dc_debug_options debug_defaults_drv = { - .timing_trace = false, - .clock_trace = true, - .disable_pplib_clock_request = true, -- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, -+ .pipe_split_policy = MPC_SPLIT_DYNAMIC, - .force_single_disp_pipe_split = false, - .disable_dcc = DCC_ENABLE, - .vsr_support = true, -@@ -1879,7 +1879,6 @@ static noinline bool dcn30_internal_validate_bw( - dc->res_pool->funcs->update_soc_for_wm_a(dc, context); - pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); - -- DC_FP_START(); - if (!pipe_cnt) { - out = true; - goto validate_out; -@@ -2103,7 +2102,6 @@ validate_fail: - out = false; - - validate_out: -- DC_FP_END(); - return out; - } - -@@ -2304,7 +2302,9 @@ bool dcn30_validate_bandwidth(struct dc *dc, - - BW_VAL_TRACE_COUNT(); - -+ DC_FP_START(); - out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate); -+ DC_FP_END(); - - if (pipe_cnt == 0) - goto validate_out; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -index 912285fdce18e..dea358b01791c 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -@@ -863,7 +863,7 @@ static const struct dc_debug_options debug_defaults_drv = { - .disable_clock_gate = true, - .disable_pplib_clock_request = true, - .disable_pplib_wm_range = true, -- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, -+ .pipe_split_policy = MPC_SPLIT_AVOID, - .force_single_disp_pipe_split = false, - .disable_dcc = DCC_ENABLE, - .vsr_support = true, -@@ -1622,12 +1622,106 @@ static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b - dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); - } - -+static void calculate_wm_set_for_vlevel( -+ int vlevel, -+ struct wm_range_table_entry *table_entry, -+ struct dcn_watermarks *wm_set, -+ struct display_mode_lib *dml, -+ display_e2e_pipe_params_st *pipes, -+ int pipe_cnt) -+{ -+ double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; -+ -+ ASSERT(vlevel < dml->soc.num_states); -+ /* only pipe 0 is read for voltage and dcf/soc clocks */ -+ pipes[0].clks_cfg.voltage = vlevel; -+ pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; -+ pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; -+ -+ dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; -+ dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; -+ dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; -+ -+ wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; -+ wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; -+ wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; -+ wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; -+ wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; -+ wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; -+ wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; -+ wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; -+ dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; -+ -+} -+ -+static void dcn301_calculate_wm_and_dlg( -+ struct dc *dc, struct dc_state *context, -+ display_e2e_pipe_params_st *pipes, -+ int pipe_cnt, -+ int vlevel_req) -+{ -+ int i, pipe_idx; -+ int vlevel, vlevel_max; -+ struct wm_range_table_entry *table_entry; -+ struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; -+ -+ ASSERT(bw_params); -+ -+ vlevel_max = bw_params->clk_table.num_entries - 1; -+ -+ /* WM Set D */ -+ table_entry = &bw_params->wm_table.entries[WM_D]; -+ if (table_entry->wm_type == WM_TYPE_RETRAINING) -+ vlevel = 0; -+ else -+ vlevel = vlevel_max; -+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, -+ &context->bw_ctx.dml, pipes, pipe_cnt); -+ /* WM Set C */ -+ table_entry = &bw_params->wm_table.entries[WM_C]; -+ vlevel = min(max(vlevel_req, 2), vlevel_max); -+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, -+ &context->bw_ctx.dml, pipes, pipe_cnt); -+ /* WM Set B */ -+ table_entry = &bw_params->wm_table.entries[WM_B]; -+ vlevel = min(max(vlevel_req, 1), vlevel_max); -+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, -+ &context->bw_ctx.dml, pipes, pipe_cnt); -+ -+ /* WM Set A */ -+ table_entry = &bw_params->wm_table.entries[WM_A]; -+ vlevel = min(vlevel_req, vlevel_max); -+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, -+ &context->bw_ctx.dml, pipes, pipe_cnt); -+ -+ for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { -+ if (!context->res_ctx.pipe_ctx[i].stream) -+ continue; -+ -+ pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); -+ pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); -+ -+ if (dc->config.forced_clocks) { -+ pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; -+ pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; -+ } -+ if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) -+ pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; -+ if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) -+ pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; -+ -+ pipe_idx++; -+ } -+ -+ dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); -+} -+ - static struct resource_funcs dcn301_res_pool_funcs = { - .destroy = dcn301_destroy_resource_pool, - .link_enc_create = dcn301_link_encoder_create, - .panel_cntl_create = dcn301_panel_cntl_create, - .validate_bandwidth = dcn30_validate_bandwidth, -- .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg, -+ .calculate_wm_and_dlg = dcn301_calculate_wm_and_dlg, - .update_soc_for_wm_a = dcn30_update_soc_for_wm_a, - .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, - .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c -index 7d3ff5d444023..2292bb82026e2 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c -@@ -211,7 +211,7 @@ static const struct dc_debug_options debug_defaults_drv = { - .timing_trace = false, - .clock_trace = true, - .disable_pplib_clock_request = true, -- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, -+ .pipe_split_policy = MPC_SPLIT_DYNAMIC, - .force_single_disp_pipe_split = false, - .disable_dcc = DCC_ENABLE, - .vsr_support = true, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c -index dd38796ba30ad..589ddab61c2a9 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c -@@ -193,7 +193,7 @@ static const struct dc_debug_options debug_defaults_drv = { - .timing_trace = false, - .clock_trace = true, - .disable_pplib_clock_request = true, -- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, -+ .pipe_split_policy = MPC_SPLIT_DYNAMIC, - .force_single_disp_pipe_split = false, - .disable_dcc = DCC_ENABLE, - .vsr_support = true, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c -index 90c73a1cb9861..5e3bcaf12cac4 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c -@@ -138,8 +138,11 @@ static uint32_t convert_and_clamp( - ret_val = wm_ns * refclk_mhz; - ret_val /= 1000; - -- if (ret_val > clamp_value) -+ if (ret_val > clamp_value) { -+ /* clamping WMs is abnormal, unexpected and may lead to underflow*/ -+ ASSERT(0); - ret_val = clamp_value; -+ } - - return ret_val; - } -@@ -159,7 +162,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->a.urgent_ns > hubbub2->watermarks.a.urgent_ns) { - hubbub2->watermarks.a.urgent_ns = watermarks->a.urgent_ns; - prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); - -@@ -193,7 +196,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub2->watermarks.a.urgent_latency_ns) { - hubbub2->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; - prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, - DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); - } else if (watermarks->a.urgent_latency_ns < hubbub2->watermarks.a.urgent_latency_ns) -@@ -203,7 +206,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->b.urgent_ns > hubbub2->watermarks.b.urgent_ns) { - hubbub2->watermarks.b.urgent_ns = watermarks->b.urgent_ns; - prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); - -@@ -237,7 +240,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub2->watermarks.b.urgent_latency_ns) { - hubbub2->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; - prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, - DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); - } else if (watermarks->b.urgent_latency_ns < hubbub2->watermarks.b.urgent_latency_ns) -@@ -247,7 +250,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->c.urgent_ns > hubbub2->watermarks.c.urgent_ns) { - hubbub2->watermarks.c.urgent_ns = watermarks->c.urgent_ns; - prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); - -@@ -281,7 +284,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub2->watermarks.c.urgent_latency_ns) { - hubbub2->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; - prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, - DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); - } else if (watermarks->c.urgent_latency_ns < hubbub2->watermarks.c.urgent_latency_ns) -@@ -291,7 +294,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->d.urgent_ns > hubbub2->watermarks.d.urgent_ns) { - hubbub2->watermarks.d.urgent_ns = watermarks->d.urgent_ns; - prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, - DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); - -@@ -325,7 +328,7 @@ static bool hubbub31_program_urgent_watermarks( - if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub2->watermarks.d.urgent_latency_ns) { - hubbub2->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; - prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0x3fff); - REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, - DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); - } else if (watermarks->d.urgent_latency_ns < hubbub2->watermarks.d.urgent_latency_ns) -@@ -351,7 +354,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" -@@ -367,7 +370,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->a.cstate_pstate.cstate_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" -@@ -383,7 +386,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_A calculated =%d\n" -@@ -399,7 +402,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->a.cstate_pstate.cstate_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_A calculated =%d\n" -@@ -416,7 +419,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" -@@ -432,7 +435,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->b.cstate_pstate.cstate_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" -@@ -448,7 +451,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_B calculated =%d\n" -@@ -464,7 +467,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->b.cstate_pstate.cstate_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_B calculated =%d\n" -@@ -481,7 +484,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" -@@ -497,7 +500,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->c.cstate_pstate.cstate_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" -@@ -513,7 +516,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_C calculated =%d\n" -@@ -529,7 +532,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->c.cstate_pstate.cstate_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_C calculated =%d\n" -@@ -546,7 +549,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" -@@ -562,7 +565,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->d.cstate_pstate.cstate_exit_ns; - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_exit_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" -@@ -578,7 +581,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, 0, - DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_D calculated =%d\n" -@@ -594,7 +597,7 @@ static bool hubbub31_program_stutter_watermarks( - watermarks->d.cstate_pstate.cstate_exit_z8_ns; - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_exit_z8_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, 0, - DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_D calculated =%d\n" -@@ -625,7 +628,7 @@ static bool hubbub31_program_pstate_watermarks( - watermarks->a.cstate_pstate.pstate_change_ns; - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.pstate_change_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0, - DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" -@@ -642,7 +645,7 @@ static bool hubbub31_program_pstate_watermarks( - watermarks->b.cstate_pstate.pstate_change_ns; - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.pstate_change_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0, - DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" -@@ -659,7 +662,7 @@ static bool hubbub31_program_pstate_watermarks( - watermarks->c.cstate_pstate.pstate_change_ns; - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.pstate_change_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0, - DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" -@@ -676,7 +679,7 @@ static bool hubbub31_program_pstate_watermarks( - watermarks->d.cstate_pstate.pstate_change_ns; - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.pstate_change_ns, -- refclk_mhz, 0x1fffff); -+ refclk_mhz, 0xffff); - REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0, - DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" -diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c -index 40011cd3c8ef0..4e9fe090b770a 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c -@@ -100,6 +100,8 @@ static const struct hw_sequencer_funcs dcn31_funcs = { - .z10_save_init = dcn31_z10_save_init, - .is_abm_supported = dcn31_is_abm_supported, - .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, -+ .optimize_pwr_state = dcn21_optimize_pwr_state, -+ .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, - .update_visual_confirm_color = dcn20_update_visual_confirm_color, - }; - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c -index 79e92ecca96c1..d4fe5352421fc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c -@@ -352,6 +352,14 @@ static const struct dce110_clk_src_regs clk_src_regs[] = { - clk_src_regs(3, D), - clk_src_regs(4, E) - }; -+/*pll_id being rempped in dmub, in driver it is logical instance*/ -+static const struct dce110_clk_src_regs clk_src_regs_b0[] = { -+ clk_src_regs(0, A), -+ clk_src_regs(1, B), -+ clk_src_regs(2, F), -+ clk_src_regs(3, G), -+ clk_src_regs(4, E) -+}; - - static const struct dce110_clk_src_shift cs_shift = { - CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) -@@ -462,7 +470,8 @@ static const struct dcn30_afmt_mask afmt_mask = { - SE_DCN3_REG_LIST(id)\ - } - --static const struct dcn10_stream_enc_registers stream_enc_regs[] = { -+/* Some encoders won't be initialized here - but they're logical, not physical. */ -+static const struct dcn10_stream_enc_registers stream_enc_regs[ENGINE_ID_COUNT] = { - stream_enc_regs(0), - stream_enc_regs(1), - stream_enc_regs(2), -@@ -923,7 +932,7 @@ static const struct dc_debug_options debug_defaults_drv = { - .timing_trace = false, - .clock_trace = true, - .disable_pplib_clock_request = false, -- .pipe_split_policy = MPC_SPLIT_AVOID, -+ .pipe_split_policy = MPC_SPLIT_DYNAMIC, - .force_single_disp_pipe_split = false, - .disable_dcc = DCC_ENABLE, - .vsr_support = true, -@@ -2019,14 +2028,27 @@ static bool dcn31_resource_construct( - dcn30_clock_source_create(ctx, ctx->dc_bios, - CLOCK_SOURCE_COMBO_PHY_PLL1, - &clk_src_regs[1], false); -- pool->base.clock_sources[DCN31_CLK_SRC_PLL2] = -+ /*move phypllx_pixclk_resync to dmub next*/ -+ if (dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { -+ pool->base.clock_sources[DCN31_CLK_SRC_PLL2] = -+ dcn30_clock_source_create(ctx, ctx->dc_bios, -+ CLOCK_SOURCE_COMBO_PHY_PLL2, -+ &clk_src_regs_b0[2], false); -+ pool->base.clock_sources[DCN31_CLK_SRC_PLL3] = -+ dcn30_clock_source_create(ctx, ctx->dc_bios, -+ CLOCK_SOURCE_COMBO_PHY_PLL3, -+ &clk_src_regs_b0[3], false); -+ } else { -+ pool->base.clock_sources[DCN31_CLK_SRC_PLL2] = - dcn30_clock_source_create(ctx, ctx->dc_bios, - CLOCK_SOURCE_COMBO_PHY_PLL2, - &clk_src_regs[2], false); -- pool->base.clock_sources[DCN31_CLK_SRC_PLL3] = -+ pool->base.clock_sources[DCN31_CLK_SRC_PLL3] = - dcn30_clock_source_create(ctx, ctx->dc_bios, - CLOCK_SOURCE_COMBO_PHY_PLL3, - &clk_src_regs[3], false); -+ } -+ - pool->base.clock_sources[DCN31_CLK_SRC_PLL4] = - dcn30_clock_source_create(ctx, ctx->dc_bios, - CLOCK_SOURCE_COMBO_PHY_PLL4, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h -index 93571c9769967..cc4bed675588c 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h -@@ -39,4 +39,35 @@ struct resource_pool *dcn31_create_resource_pool( - const struct dc_init_data *init_data, - struct dc *dc); - -+/*temp: B0 specific before switch to dcn313 headers*/ -+#ifndef regPHYPLLF_PIXCLK_RESYNC_CNTL -+#define regPHYPLLF_PIXCLK_RESYNC_CNTL 0x007e -+#define regPHYPLLF_PIXCLK_RESYNC_CNTL_BASE_IDX 1 -+#define regPHYPLLG_PIXCLK_RESYNC_CNTL 0x005f -+#define regPHYPLLG_PIXCLK_RESYNC_CNTL_BASE_IDX 1 -+ -+//PHYPLLF_PIXCLK_RESYNC_CNTL -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_PIXCLK_RESYNC_ENABLE__SHIFT 0x0 -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_DEEP_COLOR_DTO_ENABLE_STATUS__SHIFT 0x1 -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_DCCG_DEEP_COLOR_CNTL__SHIFT 0x4 -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_PIXCLK_ENABLE__SHIFT 0x8 -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_PIXCLK_DOUBLE_RATE_ENABLE__SHIFT 0x9 -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_PIXCLK_RESYNC_ENABLE_MASK 0x00000001L -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_DEEP_COLOR_DTO_ENABLE_STATUS_MASK 0x00000002L -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_DCCG_DEEP_COLOR_CNTL_MASK 0x00000030L -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_PIXCLK_ENABLE_MASK 0x00000100L -+#define PHYPLLF_PIXCLK_RESYNC_CNTL__PHYPLLF_PIXCLK_DOUBLE_RATE_ENABLE_MASK 0x00000200L -+ -+//PHYPLLG_PIXCLK_RESYNC_CNTL -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_PIXCLK_RESYNC_ENABLE__SHIFT 0x0 -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_DEEP_COLOR_DTO_ENABLE_STATUS__SHIFT 0x1 -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_DCCG_DEEP_COLOR_CNTL__SHIFT 0x4 -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_PIXCLK_ENABLE__SHIFT 0x8 -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_PIXCLK_DOUBLE_RATE_ENABLE__SHIFT 0x9 -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_PIXCLK_RESYNC_ENABLE_MASK 0x00000001L -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_DEEP_COLOR_DTO_ENABLE_STATUS_MASK 0x00000002L -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_DCCG_DEEP_COLOR_CNTL_MASK 0x00000030L -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_PIXCLK_ENABLE_MASK 0x00000100L -+#define PHYPLLG_PIXCLK_RESYNC_CNTL__PHYPLLG_PIXCLK_DOUBLE_RATE_ENABLE_MASK 0x00000200L -+#endif - #endif /* _DCN31_RESOURCE_H_ */ -diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile -index 56055df2e8d2e..9009b92490f34 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile -@@ -70,6 +70,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(fram - CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags) -+CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags) - CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) - CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags) - CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_rcflags) -@@ -84,6 +85,7 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_rcfla - CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_rcflags) - CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_rcflags) - CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_rcflags) -+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_rcflags) - endif - CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags) - CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags) -@@ -99,6 +101,7 @@ DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o - DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o - DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o - DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o -+DML += dsc/rc_calc_fpu.o - endif - - AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML)) -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c -index 2091dd8c252da..8c168f348a27f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c -@@ -768,12 +768,12 @@ static void dml20_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, - - void dml20_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param) -+ const display_pipe_params_st *pipe_param) - { - display_rq_params_st rq_param = {0}; - - memset(rq_regs, 0, sizeof(*rq_regs)); -- dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src); -+ dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src); - extract_rq_regs(mode_lib, rq_regs, rq_param); - - print__rq_regs_st(mode_lib, *rq_regs); -@@ -1549,7 +1549,7 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, - void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h -index d0b90947f5409..8b23867e97c18 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h -@@ -43,7 +43,7 @@ struct display_mode_lib; - void dml20_rq_dlg_get_rq_reg( - struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param); -+ const display_pipe_params_st *pipe_param); - - - // Function: dml_rq_dlg_get_dlg_reg -@@ -61,7 +61,7 @@ void dml20_rq_dlg_get_dlg_reg( - struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c -index 1a0c14e465faa..26ececfd40cdc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c -@@ -768,12 +768,12 @@ static void dml20v2_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, - - void dml20v2_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param) -+ const display_pipe_params_st *pipe_param) - { - display_rq_params_st rq_param = {0}; - - memset(rq_regs, 0, sizeof(*rq_regs)); -- dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src); -+ dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src); - extract_rq_regs(mode_lib, rq_regs, rq_param); - - print__rq_regs_st(mode_lib, *rq_regs); -@@ -1550,7 +1550,7 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, - void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h -index 27cf8bed9376f..2b4e46ea1c3df 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h -@@ -43,7 +43,7 @@ struct display_mode_lib; - void dml20v2_rq_dlg_get_rq_reg( - struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param); -+ const display_pipe_params_st *pipe_param); - - - // Function: dml_rq_dlg_get_dlg_reg -@@ -61,7 +61,7 @@ void dml20v2_rq_dlg_get_dlg_reg( - struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c -index 287e31052b307..736978c4d40a1 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c -@@ -694,7 +694,7 @@ static void get_surf_rq_param( - display_data_rq_sizing_params_st *rq_sizing_param, - display_data_rq_dlg_params_st *rq_dlg_param, - display_data_rq_misc_params_st *rq_misc_param, -- const display_pipe_params_st pipe_param, -+ const display_pipe_params_st *pipe_param, - bool is_chroma) - { - bool mode_422 = false; -@@ -706,30 +706,30 @@ static void get_surf_rq_param( - - // FIXME check if ppe apply for both luma and chroma in 422 case - if (is_chroma) { -- vp_width = pipe_param.src.viewport_width_c / ppe; -- vp_height = pipe_param.src.viewport_height_c; -- data_pitch = pipe_param.src.data_pitch_c; -- meta_pitch = pipe_param.src.meta_pitch_c; -+ vp_width = pipe_param->src.viewport_width_c / ppe; -+ vp_height = pipe_param->src.viewport_height_c; -+ data_pitch = pipe_param->src.data_pitch_c; -+ meta_pitch = pipe_param->src.meta_pitch_c; - } else { -- vp_width = pipe_param.src.viewport_width / ppe; -- vp_height = pipe_param.src.viewport_height; -- data_pitch = pipe_param.src.data_pitch; -- meta_pitch = pipe_param.src.meta_pitch; -+ vp_width = pipe_param->src.viewport_width / ppe; -+ vp_height = pipe_param->src.viewport_height; -+ data_pitch = pipe_param->src.data_pitch; -+ meta_pitch = pipe_param->src.meta_pitch; - } - -- if (pipe_param.dest.odm_combine) { -+ if (pipe_param->dest.odm_combine) { - unsigned int access_dir; - unsigned int full_src_vp_width; - unsigned int hactive_half; - unsigned int src_hactive_half; -- access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed -- hactive_half = pipe_param.dest.hactive / 2; -+ access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed -+ hactive_half = pipe_param->dest.hactive / 2; - if (is_chroma) { -- full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width; -- src_hactive_half = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_half; -+ full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; -+ src_hactive_half = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_half; - } else { -- full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width; -- src_hactive_half = pipe_param.scale_ratio_depth.hscl_ratio * hactive_half; -+ full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; -+ src_hactive_half = pipe_param->scale_ratio_depth.hscl_ratio * hactive_half; - } - - if (access_dir == 0) { -@@ -754,7 +754,7 @@ static void get_surf_rq_param( - rq_sizing_param->meta_chunk_bytes = 2048; - rq_sizing_param->min_meta_chunk_bytes = 256; - -- if (pipe_param.src.hostvm) -+ if (pipe_param->src.hostvm) - rq_sizing_param->mpte_group_bytes = 512; - else - rq_sizing_param->mpte_group_bytes = 2048; -@@ -768,23 +768,23 @@ static void get_surf_rq_param( - vp_height, - data_pitch, - meta_pitch, -- pipe_param.src.source_format, -- pipe_param.src.sw_mode, -- pipe_param.src.macro_tile_size, -- pipe_param.src.source_scan, -- pipe_param.src.hostvm, -+ pipe_param->src.source_format, -+ pipe_param->src.sw_mode, -+ pipe_param->src.macro_tile_size, -+ pipe_param->src.source_scan, -+ pipe_param->src.hostvm, - is_chroma); - } - - static void dml_rq_dlg_get_rq_params( - struct display_mode_lib *mode_lib, - display_rq_params_st *rq_param, -- const display_pipe_params_st pipe_param) -+ const display_pipe_params_st *pipe_param) - { - // get param for luma surface -- rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 -- || pipe_param.src.source_format == dm_420_10; -- rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10; -+ rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 -+ || pipe_param->src.source_format == dm_420_10; -+ rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10; - - get_surf_rq_param( - mode_lib, -@@ -794,7 +794,7 @@ static void dml_rq_dlg_get_rq_params( - pipe_param, - 0); - -- if (is_dual_plane((enum source_format_class) (pipe_param.src.source_format))) { -+ if (is_dual_plane((enum source_format_class) (pipe_param->src.source_format))) { - // get param for chroma surface - get_surf_rq_param( - mode_lib, -@@ -806,14 +806,14 @@ static void dml_rq_dlg_get_rq_params( - } - - // calculate how to split the det buffer space between luma and chroma -- handle_det_buf_split(mode_lib, rq_param, pipe_param.src); -+ handle_det_buf_split(mode_lib, rq_param, pipe_param->src); - print__rq_params_st(mode_lib, *rq_param); - } - - void dml21_rq_dlg_get_rq_reg( - struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param) -+ const display_pipe_params_st *pipe_param) - { - display_rq_params_st rq_param = {0}; - -@@ -1658,7 +1658,7 @@ void dml21_rq_dlg_get_dlg_reg( - struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -@@ -1696,7 +1696,7 @@ void dml21_rq_dlg_get_dlg_reg( - // system parameter calculation done - - dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); -- dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe); -+ dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); - dml_rq_dlg_get_dlg_params( - mode_lib, - e2e_pipe_param, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h -index e8f7785e3fc63..af6ad0ca9cf8a 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h -@@ -44,7 +44,7 @@ struct display_mode_lib; - void dml21_rq_dlg_get_rq_reg( - struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param); -+ const display_pipe_params_st *pipe_param); - - // Function: dml_rq_dlg_get_dlg_reg - // Calculate and return DLG and TTU register struct given the system setting -@@ -61,7 +61,7 @@ void dml21_rq_dlg_get_dlg_reg( - struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c -index 0d934fae1c3a6..2120e0941a095 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c -@@ -747,7 +747,7 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, - display_data_rq_sizing_params_st *rq_sizing_param, - display_data_rq_dlg_params_st *rq_dlg_param, - display_data_rq_misc_params_st *rq_misc_param, -- const display_pipe_params_st pipe_param, -+ const display_pipe_params_st *pipe_param, - bool is_chroma, - bool is_alpha) - { -@@ -761,32 +761,32 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, - - // FIXME check if ppe apply for both luma and chroma in 422 case - if (is_chroma | is_alpha) { -- vp_width = pipe_param.src.viewport_width_c / ppe; -- vp_height = pipe_param.src.viewport_height_c; -- data_pitch = pipe_param.src.data_pitch_c; -- meta_pitch = pipe_param.src.meta_pitch_c; -- surface_height = pipe_param.src.surface_height_y / 2.0; -+ vp_width = pipe_param->src.viewport_width_c / ppe; -+ vp_height = pipe_param->src.viewport_height_c; -+ data_pitch = pipe_param->src.data_pitch_c; -+ meta_pitch = pipe_param->src.meta_pitch_c; -+ surface_height = pipe_param->src.surface_height_y / 2.0; - } else { -- vp_width = pipe_param.src.viewport_width / ppe; -- vp_height = pipe_param.src.viewport_height; -- data_pitch = pipe_param.src.data_pitch; -- meta_pitch = pipe_param.src.meta_pitch; -- surface_height = pipe_param.src.surface_height_y; -+ vp_width = pipe_param->src.viewport_width / ppe; -+ vp_height = pipe_param->src.viewport_height; -+ data_pitch = pipe_param->src.data_pitch; -+ meta_pitch = pipe_param->src.meta_pitch; -+ surface_height = pipe_param->src.surface_height_y; - } - -- if (pipe_param.dest.odm_combine) { -+ if (pipe_param->dest.odm_combine) { - unsigned int access_dir = 0; - unsigned int full_src_vp_width = 0; - unsigned int hactive_odm = 0; - unsigned int src_hactive_odm = 0; -- access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed -- hactive_odm = pipe_param.dest.hactive / ((unsigned int)pipe_param.dest.odm_combine*2); -+ access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed -+ hactive_odm = pipe_param->dest.hactive / ((unsigned int) pipe_param->dest.odm_combine*2); - if (is_chroma) { -- full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width; -- src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_odm; -+ full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; -+ src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_odm; - } else { -- full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width; -- src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio * hactive_odm; -+ full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; -+ src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio * hactive_odm; - } - - if (access_dir == 0) { -@@ -815,7 +815,7 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, - rq_sizing_param->meta_chunk_bytes = 2048; - rq_sizing_param->min_meta_chunk_bytes = 256; - -- if (pipe_param.src.hostvm) -+ if (pipe_param->src.hostvm) - rq_sizing_param->mpte_group_bytes = 512; - else - rq_sizing_param->mpte_group_bytes = 2048; -@@ -828,28 +828,28 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, - vp_height, - data_pitch, - meta_pitch, -- pipe_param.src.source_format, -- pipe_param.src.sw_mode, -- pipe_param.src.macro_tile_size, -- pipe_param.src.source_scan, -- pipe_param.src.hostvm, -+ pipe_param->src.source_format, -+ pipe_param->src.sw_mode, -+ pipe_param->src.macro_tile_size, -+ pipe_param->src.source_scan, -+ pipe_param->src.hostvm, - is_chroma, - surface_height); - } - - static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, - display_rq_params_st *rq_param, -- const display_pipe_params_st pipe_param) -+ const display_pipe_params_st *pipe_param) - { - // get param for luma surface -- rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 -- || pipe_param.src.source_format == dm_420_10 -- || pipe_param.src.source_format == dm_rgbe_alpha -- || pipe_param.src.source_format == dm_420_12; -+ rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 -+ || pipe_param->src.source_format == dm_420_10 -+ || pipe_param->src.source_format == dm_rgbe_alpha -+ || pipe_param->src.source_format == dm_420_12; - -- rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10; -+ rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10; - -- rq_param->rgbe_alpha = (pipe_param.src.source_format == dm_rgbe_alpha)?1:0; -+ rq_param->rgbe_alpha = (pipe_param->src.source_format == dm_rgbe_alpha)?1:0; - - get_surf_rq_param(mode_lib, - &(rq_param->sizing.rq_l), -@@ -859,7 +859,7 @@ static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, - 0, - 0); - -- if (is_dual_plane((enum source_format_class)(pipe_param.src.source_format))) { -+ if (is_dual_plane((enum source_format_class)(pipe_param->src.source_format))) { - // get param for chroma surface - get_surf_rq_param(mode_lib, - &(rq_param->sizing.rq_c), -@@ -871,13 +871,13 @@ static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, - } - - // calculate how to split the det buffer space between luma and chroma -- handle_det_buf_split(mode_lib, rq_param, pipe_param.src); -+ handle_det_buf_split(mode_lib, rq_param, pipe_param->src); - print__rq_params_st(mode_lib, *rq_param); - } - - void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param) -+ const display_pipe_params_st *pipe_param) - { - display_rq_params_st rq_param = { 0 }; - -@@ -1831,7 +1831,7 @@ static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, - void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -@@ -1866,7 +1866,7 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, - // system parameter calculation done - - dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); -- dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe); -+ dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); - dml_rq_dlg_get_dlg_params(mode_lib, - e2e_pipe_param, - num_pipes, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h -index c04965cceff35..625e41f8d5751 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h -@@ -41,7 +41,7 @@ struct display_mode_lib; - // See also: - void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param); -+ const display_pipe_params_st *pipe_param); - - // Function: dml_rq_dlg_get_dlg_reg - // Calculate and return DLG and TTU register struct given the system setting -@@ -57,7 +57,7 @@ void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c -index c23905bc733ae..57bd4e3f8a823 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c -@@ -738,7 +738,7 @@ static void get_surf_rq_param( - display_data_rq_sizing_params_st *rq_sizing_param, - display_data_rq_dlg_params_st *rq_dlg_param, - display_data_rq_misc_params_st *rq_misc_param, -- const display_pipe_params_st pipe_param, -+ const display_pipe_params_st *pipe_param, - bool is_chroma, - bool is_alpha) - { -@@ -752,33 +752,33 @@ static void get_surf_rq_param( - - // FIXME check if ppe apply for both luma and chroma in 422 case - if (is_chroma | is_alpha) { -- vp_width = pipe_param.src.viewport_width_c / ppe; -- vp_height = pipe_param.src.viewport_height_c; -- data_pitch = pipe_param.src.data_pitch_c; -- meta_pitch = pipe_param.src.meta_pitch_c; -- surface_height = pipe_param.src.surface_height_y / 2.0; -+ vp_width = pipe_param->src.viewport_width_c / ppe; -+ vp_height = pipe_param->src.viewport_height_c; -+ data_pitch = pipe_param->src.data_pitch_c; -+ meta_pitch = pipe_param->src.meta_pitch_c; -+ surface_height = pipe_param->src.surface_height_y / 2.0; - } else { -- vp_width = pipe_param.src.viewport_width / ppe; -- vp_height = pipe_param.src.viewport_height; -- data_pitch = pipe_param.src.data_pitch; -- meta_pitch = pipe_param.src.meta_pitch; -- surface_height = pipe_param.src.surface_height_y; -+ vp_width = pipe_param->src.viewport_width / ppe; -+ vp_height = pipe_param->src.viewport_height; -+ data_pitch = pipe_param->src.data_pitch; -+ meta_pitch = pipe_param->src.meta_pitch; -+ surface_height = pipe_param->src.surface_height_y; - } - -- if (pipe_param.dest.odm_combine) { -+ if (pipe_param->dest.odm_combine) { - unsigned int access_dir; - unsigned int full_src_vp_width; - unsigned int hactive_odm; - unsigned int src_hactive_odm; - -- access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed -- hactive_odm = pipe_param.dest.hactive / ((unsigned int) pipe_param.dest.odm_combine * 2); -+ access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed -+ hactive_odm = pipe_param->dest.hactive / ((unsigned int) pipe_param->dest.odm_combine * 2); - if (is_chroma) { -- full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width; -- src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_odm; -+ full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; -+ src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_odm; - } else { -- full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width; -- src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio * hactive_odm; -+ full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; -+ src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio * hactive_odm; - } - - if (access_dir == 0) { -@@ -808,7 +808,7 @@ static void get_surf_rq_param( - rq_sizing_param->meta_chunk_bytes = 2048; - rq_sizing_param->min_meta_chunk_bytes = 256; - -- if (pipe_param.src.hostvm) -+ if (pipe_param->src.hostvm) - rq_sizing_param->mpte_group_bytes = 512; - else - rq_sizing_param->mpte_group_bytes = 2048; -@@ -822,38 +822,38 @@ static void get_surf_rq_param( - vp_height, - data_pitch, - meta_pitch, -- pipe_param.src.source_format, -- pipe_param.src.sw_mode, -- pipe_param.src.macro_tile_size, -- pipe_param.src.source_scan, -- pipe_param.src.hostvm, -+ pipe_param->src.source_format, -+ pipe_param->src.sw_mode, -+ pipe_param->src.macro_tile_size, -+ pipe_param->src.source_scan, -+ pipe_param->src.hostvm, - is_chroma, - surface_height); - } - --static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_params_st pipe_param) -+static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_params_st *pipe_param) - { - // get param for luma surface -- rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 || pipe_param.src.source_format == dm_420_10 || pipe_param.src.source_format == dm_rgbe_alpha -- || pipe_param.src.source_format == dm_420_12; -+ rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 || pipe_param->src.source_format == dm_420_10 || pipe_param->src.source_format == dm_rgbe_alpha -+ || pipe_param->src.source_format == dm_420_12; - -- rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10; -+ rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10; - -- rq_param->rgbe_alpha = (pipe_param.src.source_format == dm_rgbe_alpha) ? 1 : 0; -+ rq_param->rgbe_alpha = (pipe_param->src.source_format == dm_rgbe_alpha) ? 1 : 0; - - get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), &(rq_param->dlg.rq_l), &(rq_param->misc.rq_l), pipe_param, 0, 0); - -- if (is_dual_plane((enum source_format_class) (pipe_param.src.source_format))) { -+ if (is_dual_plane((enum source_format_class) (pipe_param->src.source_format))) { - // get param for chroma surface - get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), &(rq_param->dlg.rq_c), &(rq_param->misc.rq_c), pipe_param, 1, rq_param->rgbe_alpha); - } - - // calculate how to split the det buffer space between luma and chroma -- handle_det_buf_split(mode_lib, rq_param, pipe_param.src); -+ handle_det_buf_split(mode_lib, rq_param, pipe_param->src); - print__rq_params_st(mode_lib, *rq_param); - } - --void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_pipe_params_st pipe_param) -+void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_pipe_params_st *pipe_param) - { - display_rq_params_st rq_param = {0}; - -@@ -1677,7 +1677,7 @@ void dml31_rq_dlg_get_dlg_reg( - struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -@@ -1704,7 +1704,7 @@ void dml31_rq_dlg_get_dlg_reg( - // system parameter calculation done - - dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); -- dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe); -+ dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); - dml_rq_dlg_get_dlg_params( - mode_lib, - e2e_pipe_param, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h -index adf8518f761f9..8ee991351699d 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h -@@ -41,7 +41,7 @@ struct display_mode_lib; - // See also: - void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param); -+ const display_pipe_params_st *pipe_param); - - // Function: dml_rq_dlg_get_dlg_reg - // Calculate and return DLG and TTU register struct given the system setting -@@ -57,7 +57,7 @@ void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, - void dml31_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h -index 1051ca1a23b8a..edb9f7567d6d9 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h -@@ -80,11 +80,11 @@ enum dm_swizzle_mode { - dm_sw_SPARE_13 = 24, - dm_sw_64kb_s_x = 25, - dm_sw_64kb_d_x = 26, -- dm_sw_SPARE_14 = 27, -+ dm_sw_64kb_r_x = 27, - dm_sw_SPARE_15 = 28, - dm_sw_var_s_x = 29, - dm_sw_var_d_x = 30, -- dm_sw_64kb_r_x, -+ dm_sw_var_r_x = 31, - dm_sw_gfx7_2d_thin_l_vp, - dm_sw_gfx7_2d_thin_gl, - }; -diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h -index d42a0aeca6be2..72b1957022aa2 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h -@@ -49,7 +49,7 @@ struct dml_funcs { - struct display_mode_lib *mode_lib, - display_dlg_regs_st *dlg_regs, - display_ttu_regs_st *ttu_regs, -- display_e2e_pipe_params_st *e2e_pipe_param, -+ const display_e2e_pipe_params_st *e2e_pipe_param, - const unsigned int num_pipes, - const unsigned int pipe_idx, - const bool cstate_en, -@@ -60,7 +60,7 @@ struct dml_funcs { - void (*rq_dlg_get_rq_reg)( - struct display_mode_lib *mode_lib, - display_rq_regs_st *rq_regs, -- const display_pipe_params_st pipe_param); -+ const display_pipe_params_st *pipe_param); - void (*recalculate)(struct display_mode_lib *mode_lib); - void (*validate)(struct display_mode_lib *mode_lib); - }; -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h b/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h -new file mode 100644 -index 0000000000000..e5fac9f4181d8 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h -@@ -0,0 +1,704 @@ -+ -+/* -+ * Copyright 2017 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+ -+const qp_table qp_table_422_10bpc_min = { -+ { 6, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 12, 16} }, -+ { 6.5, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 12, 16} }, -+ { 7, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 7, 9, 9, 9, 11, 15} }, -+ { 7.5, { 0, 2, 4, 6, 6, 6, 6, 7, 7, 7, 8, 9, 9, 11, 15} }, -+ { 8, { 0, 2, 3, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 11, 14} }, -+ { 8.5, { 0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 14} }, -+ { 9, { 0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 13} }, -+ { 9.5, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 13} }, -+ { 10, { 0, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12} }, -+ {10.5, { 0, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 11, 12} }, -+ { 11, { 0, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11} }, -+ {11.5, { 0, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 10, 11} }, -+ { 12, { 0, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10} }, -+ {12.5, { 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} }, -+ { 13, { 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 6, 6, 8, 8, 9} }, -+ {13.5, { 0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 9} }, -+ { 14, { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8} }, -+ {14.5, { 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8} }, -+ { 15, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 6, 8} }, -+ {15.5, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -+ { 16, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 7} }, -+ {16.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6} }, -+ { 17, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 6} }, -+ {17.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -+ { 18, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 5} }, -+ {18.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 5} }, -+ { 19, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 4} }, -+ {19.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 4} }, -+ { 20, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 3} } -+}; -+ -+ -+const qp_table qp_table_444_8bpc_max = { -+ { 6, { 4, 6, 8, 8, 9, 9, 9, 10, 11, 12, 12, 12, 12, 13, 15} }, -+ { 6.5, { 4, 6, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 12, 13, 15} }, -+ { 7, { 4, 5, 7, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 13, 14} }, -+ { 7.5, { 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -+ { 8, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -+ { 8.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -+ { 9, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 13} }, -+ { 9.5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 13} }, -+ { 10, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -+ {10.5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 11, 12} }, -+ { 11, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11} }, -+ {11.5, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -+ { 12, { 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -+ {12.5, { 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -+ { 13, { 1, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 10} }, -+ {13.5, { 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10} }, -+ { 14, { 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} }, -+ {14.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9} }, -+ { 15, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -+ {15.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -+ { 16, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8} }, -+ {16.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8} }, -+ { 17, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 8} }, -+ {17.5, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 8} }, -+ { 18, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7} }, -+ {18.5, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7} }, -+ { 19, { 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6} }, -+ {19.5, { 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6} }, -+ { 20, { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 6} }, -+ {20.5, { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 6} }, -+ { 21, { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -+ {21.5, { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -+ { 22, { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} }, -+ {22.5, { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} }, -+ { 23, { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4} }, -+ {23.5, { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4} }, -+ { 24, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_420_12bpc_max = { -+ { 4, {11, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 21, 22} }, -+ { 4.5, {10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -+ { 5, { 9, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 21} }, -+ { 5.5, { 8, 10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 19, 20} }, -+ { 6, { 6, 9, 11, 12, 13, 14, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -+ { 6.5, { 6, 8, 10, 11, 11, 13, 14, 15, 15, 16, 16, 17, 17, 18, 19} }, -+ { 7, { 5, 7, 9, 10, 10, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18} }, -+ { 7.5, { 5, 7, 8, 9, 9, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17} }, -+ { 8, { 4, 6, 7, 8, 8, 10, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -+ { 8.5, { 3, 6, 6, 7, 7, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -+ { 9, { 3, 5, 6, 7, 7, 10, 11, 12, 12, 13, 13, 14, 14, 14, 15} }, -+ { 9.5, { 2, 5, 6, 6, 7, 9, 10, 11, 12, 12, 13, 13, 13, 14, 15} }, -+ { 10, { 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 15} }, -+ {10.5, { 2, 3, 5, 5, 6, 7, 8, 9, 11, 11, 12, 12, 12, 12, 14} }, -+ { 11, { 1, 3, 4, 5, 6, 6, 7, 9, 10, 11, 11, 11, 12, 12, 13} }, -+ {11.5, { 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 10, 11, 11, 11, 13} }, -+ { 12, { 1, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 12} }, -+ {12.5, { 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 11} }, -+ { 13, { 1, 1, 1, 2, 4, 4, 6, 6, 7, 8, 8, 9, 9, 9, 11} }, -+ {13.5, { 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8, 9, 11} }, -+ { 14, { 1, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} }, -+ {14.5, { 0, 1, 1, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -+ { 15, { 0, 1, 1, 1, 1, 2, 3, 3, 5, 5, 5, 6, 6, 7, 9} }, -+ {15.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8} }, -+ { 16, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 7} }, -+ {16.5, { 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 7} }, -+ { 17, { 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 6} }, -+ {17.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6} }, -+ { 18, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 5} } -+}; -+ -+ -+const qp_table qp_table_444_10bpc_min = { -+ { 6, { 0, 4, 7, 7, 9, 9, 9, 9, 9, 10, 10, 10, 10, 12, 18} }, -+ { 6.5, { 0, 4, 6, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 12, 18} }, -+ { 7, { 0, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 10, 10, 12, 17} }, -+ { 7.5, { 0, 4, 6, 6, 7, 8, 8, 8, 8, 8, 9, 9, 10, 12, 17} }, -+ { 8, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16} }, -+ { 8.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16} }, -+ { 9, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -+ { 9.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -+ { 10, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 15} }, -+ {10.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 15} }, -+ { 11, { 0, 3, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -+ {11.5, { 0, 3, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -+ { 12, { 0, 2, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -+ {12.5, { 0, 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 9, 9, 11, 14} }, -+ { 13, { 0, 2, 4, 4, 5, 6, 7, 7, 7, 7, 8, 9, 9, 11, 13} }, -+ {13.5, { 0, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 11, 13} }, -+ { 14, { 0, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 11, 13} }, -+ {14.5, { 0, 2, 3, 4, 5, 5, 6, 6, 6, 7, 7, 8, 9, 11, 12} }, -+ { 15, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 11, 12} }, -+ {15.5, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 11, 12} }, -+ { 16, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 10, 11} }, -+ {16.5, { 0, 1, 2, 3, 4, 5, 5, 6, 6, 6, 7, 8, 8, 10, 11} }, -+ { 17, { 0, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 9, 11} }, -+ {17.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 11} }, -+ { 18, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} }, -+ {18.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} }, -+ { 19, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9} }, -+ {19.5, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9} }, -+ { 20, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 9} }, -+ {20.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 9} }, -+ { 21, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 9} }, -+ {21.5, { 0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8} }, -+ { 22, { 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 8} }, -+ {22.5, { 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -+ { 23, { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 7} }, -+ {23.5, { 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 7} }, -+ { 24, { 0, 0, 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 7} }, -+ {24.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 7} }, -+ { 25, { 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} }, -+ {25.5, { 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -+ { 26, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 5} }, -+ {26.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 5} }, -+ { 27, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} }, -+ {27.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} }, -+ { 28, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4} }, -+ {28.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 4} }, -+ { 29, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3} }, -+ {29.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3} }, -+ { 30, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} } -+}; -+ -+ -+const qp_table qp_table_420_8bpc_max = { -+ { 4, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 13, 14} }, -+ { 4.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -+ { 5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 12, 13} }, -+ { 5.5, { 3, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12} }, -+ { 6, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -+ { 6.5, { 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -+ { 7, { 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10} }, -+ { 7.5, { 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9} }, -+ { 8, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -+ { 8.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8} }, -+ { 9, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7} }, -+ { 9.5, { 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -+ { 10, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6} }, -+ {10.5, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} }, -+ { 11, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5} }, -+ {11.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -+ { 12, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4} } -+}; -+ -+ -+const qp_table qp_table_444_8bpc_min = { -+ { 6, { 0, 1, 3, 3, 5, 5, 5, 5, 5, 6, 6, 6, 6, 9, 14} }, -+ { 6.5, { 0, 1, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 9, 14} }, -+ { 7, { 0, 0, 2, 2, 4, 4, 4, 4, 4, 5, 5, 6, 6, 9, 13} }, -+ { 7.5, { 0, 0, 2, 2, 3, 4, 4, 4, 4, 4, 5, 5, 6, 9, 13} }, -+ { 8, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 8, 12} }, -+ { 8.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 8, 12} }, -+ { 9, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} }, -+ { 9.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} }, -+ { 10, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -+ {10.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -+ { 11, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -+ {11.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -+ { 12, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -+ {12.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 4, 5, 5, 7, 10} }, -+ { 13, { 0, 0, 1, 1, 2, 3, 3, 3, 3, 3, 4, 5, 5, 7, 9} }, -+ {13.5, { 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -+ { 14, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -+ {14.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ { 15, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ {15.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ { 16, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -+ {16.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -+ { 17, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -+ {17.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -+ { 18, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -+ {18.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -+ { 19, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5} }, -+ {19.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5} }, -+ { 20, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5} }, -+ {20.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5} }, -+ { 21, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} }, -+ {21.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} }, -+ { 22, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} }, -+ {22.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} }, -+ { 23, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} }, -+ {23.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} }, -+ { 24, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3} } -+}; -+ -+ -+const qp_table qp_table_444_12bpc_min = { -+ { 6, { 0, 5, 11, 11, 13, 13, 13, 13, 13, 14, 14, 14, 14, 17, 22} }, -+ { 6.5, { 0, 5, 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 17, 22} }, -+ { 7, { 0, 5, 10, 10, 12, 12, 12, 12, 12, 13, 13, 14, 14, 17, 21} }, -+ { 7.5, { 0, 5, 9, 10, 11, 12, 12, 12, 12, 12, 13, 13, 14, 17, 21} }, -+ { 8, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 12, 13, 13, 13, 16, 20} }, -+ { 8.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 12, 13, 13, 13, 16, 20} }, -+ { 9, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -+ { 9.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -+ { 10, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -+ {10.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -+ { 11, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ {11.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ { 12, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ {12.5, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ { 13, { 0, 4, 7, 8, 9, 11, 11, 11, 11, 11, 13, 13, 13, 15, 17} }, -+ {13.5, { 0, 3, 6, 7, 9, 10, 10, 11, 11, 11, 12, 13, 13, 15, 17} }, -+ { 14, { 0, 3, 5, 6, 9, 9, 9, 10, 11, 11, 12, 13, 13, 15, 17} }, -+ {14.5, { 0, 2, 5, 6, 8, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ { 15, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ {15.5, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ { 16, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 12, 12, 14, 15} }, -+ {16.5, { 0, 2, 3, 5, 7, 8, 9, 10, 11, 11, 11, 12, 12, 14, 15} }, -+ { 17, { 0, 2, 3, 5, 5, 6, 9, 9, 10, 10, 11, 11, 12, 13, 15} }, -+ {17.5, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 15} }, -+ { 18, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -+ {18.5, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -+ { 19, { 0, 1, 2, 4, 5, 5, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ {19.5, { 0, 1, 2, 4, 5, 5, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ { 20, { 0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 9, 10, 10, 11, 13} }, -+ {20.5, { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 13} }, -+ { 21, { 0, 1, 2, 3, 4, 5, 5, 7, 7, 8, 9, 10, 10, 11, 13} }, -+ {21.5, { 0, 1, 2, 3, 3, 4, 5, 7, 7, 8, 9, 10, 10, 11, 12} }, -+ { 22, { 0, 0, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 12} }, -+ {22.5, { 0, 0, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 11} }, -+ { 23, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 7, 9, 9, 9, 9, 11} }, -+ {23.5, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 7, 9, 9, 9, 9, 11} }, -+ { 24, { 0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 8, 8, 9, 11} }, -+ {24.5, { 0, 0, 1, 2, 3, 4, 4, 6, 6, 7, 8, 8, 8, 9, 11} }, -+ { 25, { 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 8, 8, 10} }, -+ {25.5, { 0, 0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} }, -+ { 26, { 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 9} }, -+ {26.5, { 0, 0, 1, 2, 2, 3, 4, 5, 5, 5, 7, 7, 7, 7, 9} }, -+ { 27, { 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -+ {27.5, { 0, 0, 1, 1, 2, 2, 4, 4, 4, 5, 6, 7, 7, 7, 9} }, -+ { 28, { 0, 0, 0, 1, 1, 2, 3, 4, 4, 4, 6, 6, 6, 7, 9} }, -+ {28.5, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 8} }, -+ { 29, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8} }, -+ {29.5, { 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7} }, -+ { 30, { 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 5, 5, 5, 5, 7} }, -+ {30.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 7} }, -+ { 31, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 7} }, -+ {31.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -+ { 32, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 6} }, -+ {32.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 6} }, -+ { 33, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} }, -+ {33.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} }, -+ { 34, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 5} }, -+ {34.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 3, 5} }, -+ { 35, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} }, -+ {35.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 4} }, -+ { 36, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} } -+}; -+ -+ -+const qp_table qp_table_420_12bpc_min = { -+ { 4, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 21} }, -+ { 4.5, { 0, 4, 8, 9, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -+ { 5, { 0, 4, 8, 9, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -+ { 5.5, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -+ { 6, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ { 6.5, { 0, 4, 6, 8, 9, 10, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ { 7, { 0, 3, 5, 7, 9, 10, 10, 11, 11, 11, 13, 13, 13, 15, 17} }, -+ { 7.5, { 0, 3, 5, 7, 8, 9, 10, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ { 8, { 0, 2, 4, 6, 7, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ { 8.5, { 0, 2, 4, 6, 6, 9, 9, 10, 11, 11, 12, 12, 13, 14, 15} }, -+ { 9, { 0, 2, 4, 6, 6, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14} }, -+ { 9.5, { 0, 2, 4, 5, 6, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14} }, -+ { 10, { 0, 2, 3, 5, 6, 7, 8, 8, 9, 10, 10, 12, 12, 12, 14} }, -+ {10.5, { 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 11, 11, 13} }, -+ { 11, { 0, 2, 3, 4, 5, 5, 6, 8, 8, 9, 9, 10, 11, 11, 12} }, -+ {11.5, { 0, 1, 2, 3, 4, 5, 5, 7, 8, 8, 9, 10, 10, 10, 12} }, -+ { 12, { 0, 0, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 11} }, -+ {12.5, { 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 10} }, -+ { 13, { 0, 0, 0, 1, 3, 3, 5, 5, 6, 7, 7, 8, 8, 8, 10} }, -+ {13.5, { 0, 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 7, 8, 10} }, -+ { 14, { 0, 0, 0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 7, 9} }, -+ {14.5, { 0, 0, 0, 0, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 8} }, -+ { 15, { 0, 0, 0, 0, 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 8} }, -+ {15.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -+ { 16, { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 6} }, -+ {16.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6} }, -+ { 17, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 5} }, -+ {17.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 5} }, -+ { 18, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_422_12bpc_min = { -+ { 6, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 16, 20} }, -+ { 6.5, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 16, 20} }, -+ { 7, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -+ { 7.5, { 0, 4, 8, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -+ { 8, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -+ { 8.5, { 0, 3, 6, 8, 9, 10, 10, 11, 11, 11, 12, 13, 13, 15, 18} }, -+ { 9, { 0, 3, 5, 8, 9, 10, 10, 10, 11, 11, 12, 13, 13, 15, 17} }, -+ { 9.5, { 0, 3, 5, 7, 8, 9, 10, 10, 11, 11, 12, 13, 13, 15, 17} }, -+ { 10, { 0, 2, 4, 6, 7, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ {10.5, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -+ { 11, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 14, 15} }, -+ {11.5, { 0, 2, 4, 6, 7, 7, 9, 9, 10, 11, 11, 12, 12, 14, 15} }, -+ { 12, { 0, 2, 4, 6, 6, 6, 8, 8, 9, 9, 11, 11, 12, 13, 14} }, -+ {12.5, { 0, 1, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 13, 14} }, -+ { 13, { 0, 1, 3, 4, 5, 5, 7, 8, 8, 9, 10, 10, 11, 12, 13} }, -+ {13.5, { 0, 1, 3, 3, 4, 5, 7, 7, 8, 8, 10, 10, 10, 12, 13} }, -+ { 14, { 0, 0, 2, 3, 4, 5, 6, 6, 7, 7, 9, 10, 10, 11, 12} }, -+ {14.5, { 0, 0, 1, 3, 4, 4, 6, 6, 6, 7, 9, 9, 9, 11, 12} }, -+ { 15, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 6, 8, 9, 9, 10, 12} }, -+ {15.5, { 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 8, 8, 8, 10, 11} }, -+ { 16, { 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 8, 8, 8, 9, 11} }, -+ {16.5, { 0, 0, 0, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7, 9, 10} }, -+ { 17, { 0, 0, 0, 1, 2, 2, 4, 4, 4, 5, 6, 6, 6, 8, 10} }, -+ {17.5, { 0, 0, 0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 8, 9} }, -+ { 18, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 9} }, -+ {18.5, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 3, 5, 5, 5, 7, 9} }, -+ { 19, { 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 8} }, -+ {19.5, { 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 6, 8} }, -+ { 20, { 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 7} }, -+ {20.5, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 7} }, -+ { 21, { 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -+ {21.5, { 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 6} }, -+ { 22, { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 6} }, -+ {22.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 5} }, -+ { 23, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 5} }, -+ {23.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 4} }, -+ { 24, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_422_12bpc_max = { -+ { 6, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -+ { 6.5, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -+ { 7, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20} }, -+ { 7.5, { 9, 10, 12, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20} }, -+ { 8, { 6, 9, 10, 12, 14, 15, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -+ { 8.5, { 6, 8, 9, 11, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 19} }, -+ { 9, { 5, 7, 8, 10, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 18} }, -+ { 9.5, { 5, 7, 7, 9, 10, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18} }, -+ { 10, { 4, 6, 6, 8, 9, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -+ {10.5, { 4, 6, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -+ { 11, { 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -+ {11.5, { 3, 5, 6, 8, 9, 9, 11, 11, 12, 13, 13, 14, 14, 15, 16} }, -+ { 12, { 3, 5, 6, 8, 8, 8, 10, 10, 11, 11, 13, 13, 14, 14, 15} }, -+ {12.5, { 3, 4, 6, 7, 8, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15} }, -+ { 13, { 2, 4, 5, 6, 7, 7, 9, 10, 10, 11, 12, 12, 13, 13, 14} }, -+ {13.5, { 2, 4, 5, 5, 6, 7, 9, 9, 10, 10, 12, 12, 12, 13, 14} }, -+ { 14, { 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 11, 12, 12, 12, 13} }, -+ {14.5, { 2, 3, 3, 5, 6, 6, 8, 8, 8, 9, 11, 11, 11, 12, 13} }, -+ { 15, { 2, 3, 3, 5, 5, 6, 7, 8, 8, 8, 10, 11, 11, 11, 13} }, -+ {15.5, { 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 10, 10, 10, 11, 12} }, -+ { 16, { 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 10, 10, 10, 10, 12} }, -+ {16.5, { 1, 2, 2, 4, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 11} }, -+ { 17, { 1, 1, 2, 3, 4, 4, 6, 6, 6, 7, 8, 8, 8, 9, 11} }, -+ {17.5, { 1, 1, 2, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8, 9, 10} }, -+ { 18, { 1, 1, 1, 2, 3, 3, 5, 5, 5, 6, 7, 7, 8, 8, 10} }, -+ {18.5, { 1, 1, 1, 2, 3, 3, 5, 5, 5, 5, 7, 7, 7, 8, 10} }, -+ { 19, { 1, 1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 9} }, -+ {19.5, { 1, 1, 1, 2, 2, 2, 4, 5, 5, 5, 6, 6, 6, 7, 9} }, -+ { 20, { 1, 1, 1, 2, 2, 2, 4, 5, 5, 5, 6, 6, 6, 6, 8} }, -+ {20.5, { 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 8} }, -+ { 21, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 7} }, -+ {21.5, { 0, 0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 7} }, -+ { 22, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 7} }, -+ {22.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 6} }, -+ { 23, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6} }, -+ {23.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5} }, -+ { 24, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5} } -+}; -+ -+ -+const qp_table qp_table_444_12bpc_max = { -+ { 6, {12, 14, 16, 16, 17, 17, 17, 18, 19, 20, 20, 20, 20, 21, 23} }, -+ { 6.5, {12, 14, 15, 16, 16, 16, 17, 18, 19, 19, 20, 20, 20, 21, 23} }, -+ { 7, {12, 13, 15, 15, 16, 16, 16, 17, 18, 19, 19, 20, 20, 21, 22} }, -+ { 7.5, {12, 13, 14, 15, 15, 16, 16, 17, 18, 18, 19, 19, 20, 21, 22} }, -+ { 8, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -+ { 8.5, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -+ { 9, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 21} }, -+ { 9.5, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 21} }, -+ { 10, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20} }, -+ {10.5, {10, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 18, 19, 20} }, -+ { 11, { 9, 11, 13, 14, 15, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19} }, -+ {11.5, { 9, 11, 13, 14, 15, 15, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -+ { 12, { 6, 9, 12, 13, 14, 14, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -+ {12.5, { 6, 9, 12, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 19} }, -+ { 13, { 5, 9, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 17, 18} }, -+ {13.5, { 5, 8, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 18} }, -+ { 14, { 5, 8, 10, 11, 12, 12, 12, 13, 14, 14, 15, 16, 16, 16, 18} }, -+ {14.5, { 4, 7, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17} }, -+ { 15, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -+ {15.5, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -+ { 16, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 13, 14, 14, 15, 16} }, -+ {16.5, { 4, 5, 7, 8, 10, 11, 11, 12, 13, 13, 13, 14, 14, 15, 16} }, -+ { 17, { 4, 5, 7, 8, 8, 9, 11, 11, 12, 12, 12, 13, 13, 14, 16} }, -+ {17.5, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 16} }, -+ { 18, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 15} }, -+ {18.5, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 15} }, -+ { 19, { 3, 4, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 14} }, -+ {19.5, { 3, 4, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 14} }, -+ { 20, { 2, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11, 11, 12, 14} }, -+ {20.5, { 2, 3, 5, 5, 7, 8, 8, 8, 9, 10, 10, 11, 11, 12, 14} }, -+ { 21, { 2, 3, 5, 5, 7, 7, 7, 8, 8, 9, 10, 11, 11, 12, 14} }, -+ {21.5, { 2, 3, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13} }, -+ { 22, { 2, 2, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 10, 11, 13} }, -+ {22.5, { 2, 2, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 10, 11, 12} }, -+ { 23, { 2, 2, 4, 5, 5, 6, 7, 7, 7, 8, 10, 10, 10, 10, 12} }, -+ {23.5, { 2, 2, 3, 5, 5, 6, 7, 7, 7, 8, 10, 10, 10, 10, 12} }, -+ { 24, { 2, 2, 3, 4, 4, 5, 7, 7, 7, 8, 9, 9, 9, 10, 12} }, -+ {24.5, { 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 9, 9, 10, 12} }, -+ { 25, { 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9, 11} }, -+ {25.5, { 1, 1, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 9, 11} }, -+ { 26, { 1, 1, 3, 3, 3, 4, 5, 6, 6, 7, 8, 8, 8, 8, 10} }, -+ {26.5, { 1, 1, 2, 3, 3, 4, 5, 6, 6, 6, 8, 8, 8, 8, 10} }, -+ { 27, { 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 10} }, -+ {27.5, { 1, 1, 2, 2, 3, 3, 5, 5, 5, 6, 7, 8, 8, 8, 10} }, -+ { 28, { 0, 1, 1, 2, 2, 3, 4, 5, 5, 5, 7, 7, 7, 8, 10} }, -+ {28.5, { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -+ { 29, { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 9} }, -+ {29.5, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8} }, -+ { 30, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6, 6, 6, 8} }, -+ {30.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8} }, -+ { 31, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8} }, -+ {31.5, { 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8} }, -+ { 32, { 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 7} }, -+ {32.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 7} }, -+ { 33, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -+ {33.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -+ { 34, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 6} }, -+ {34.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 3, 3, 3, 3, 4, 6} }, -+ { 35, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} }, -+ {35.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 5} }, -+ { 36, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_420_8bpc_min = { -+ { 4, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 13} }, -+ { 4.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -+ { 5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -+ { 5.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -+ { 6, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -+ { 6.5, { 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 5, 7, 10} }, -+ { 7, { 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -+ { 7.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ { 8, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ { 8.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -+ { 9, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6} }, -+ { 9.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -+ { 10, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5} }, -+ {10.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 5} }, -+ { 11, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4} }, -+ {11.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} }, -+ { 12, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 3} } -+}; -+ -+ -+const qp_table qp_table_422_8bpc_min = { -+ { 6, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -+ { 6.5, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -+ { 7, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -+ { 7.5, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -+ { 8, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -+ { 8.5, { 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 7, 10} }, -+ { 9, { 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -+ { 9.5, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 9} }, -+ { 10, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ {10.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -+ { 11, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -+ {11.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -+ { 12, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6} }, -+ {12.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -+ { 13, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5} }, -+ {13.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 5} }, -+ { 14, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4} }, -+ {14.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4} }, -+ { 15, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 4} }, -+ {15.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} }, -+ { 16, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} } -+}; -+ -+ -+const qp_table qp_table_422_10bpc_max = { -+ { 6, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -+ { 6.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -+ { 7, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -+ { 7.5, { 5, 6, 8, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16} }, -+ { 8, { 4, 6, 7, 9, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -+ { 8.5, { 4, 5, 6, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15} }, -+ { 9, { 3, 4, 5, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14} }, -+ { 9.5, { 3, 4, 4, 6, 6, 8, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -+ { 10, { 2, 3, 3, 5, 5, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ {10.5, { 2, 3, 3, 5, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ { 11, { 2, 3, 3, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -+ {11.5, { 2, 3, 3, 5, 5, 5, 7, 7, 8, 9, 9, 10, 10, 11, 12} }, -+ { 12, { 2, 3, 3, 5, 5, 5, 7, 7, 8, 8, 9, 9, 10, 10, 11} }, -+ {12.5, { 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -+ { 13, { 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10} }, -+ {13.5, { 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10} }, -+ { 14, { 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 9} }, -+ {14.5, { 1, 2, 2, 3, 4, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9} }, -+ { 15, { 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 7, 9} }, -+ {15.5, { 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 8} }, -+ { 16, { 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 8} }, -+ {16.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7} }, -+ { 17, { 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 7} }, -+ {17.5, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6} }, -+ { 18, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 6} }, -+ {18.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 6} }, -+ { 19, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 5} }, -+ {19.5, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 5} }, -+ { 20, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_420_10bpc_max = { -+ { 4, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 17, 18} }, -+ { 4.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -+ { 5, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 16, 17} }, -+ { 5.5, { 6, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 16} }, -+ { 6, { 4, 6, 8, 9, 10, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -+ { 6.5, { 4, 5, 7, 8, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 15} }, -+ { 7, { 3, 4, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14} }, -+ { 7.5, { 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13} }, -+ { 8, { 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ { 8.5, { 1, 3, 3, 4, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -+ { 9, { 1, 3, 3, 4, 4, 6, 7, 8, 8, 9, 9, 10, 10, 10, 11} }, -+ { 9.5, { 1, 3, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 11} }, -+ { 10, { 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, 11} }, -+ {10.5, { 1, 1, 3, 3, 3, 4, 5, 5, 7, 7, 8, 8, 8, 8, 10} }, -+ { 11, { 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 8, 9} }, -+ {11.5, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 7, 9} }, -+ { 12, { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 8} }, -+ {12.5, { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -+ { 13, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7} }, -+ {13.5, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} }, -+ { 14, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -+ {14.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5} }, -+ { 15, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} } -+}; -+ -+ -+const qp_table qp_table_420_10bpc_min = { -+ { 4, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 17} }, -+ { 4.5, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -+ { 5, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -+ { 5.5, { 0, 3, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15} }, -+ { 6, { 0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -+ { 6.5, { 0, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 11, 14} }, -+ { 7, { 0, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 11, 13} }, -+ { 7.5, { 0, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 11, 12} }, -+ { 8, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12} }, -+ { 8.5, { 0, 2, 2, 3, 3, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11} }, -+ { 9, { 0, 2, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10} }, -+ { 9.5, { 0, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10} }, -+ { 10, { 0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 8, 8, 8, 10} }, -+ {10.5, { 0, 0, 2, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -+ { 11, { 0, 0, 1, 2, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8} }, -+ {11.5, { 0, 0, 0, 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 8} }, -+ { 12, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 7} }, -+ {12.5, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6} }, -+ { 13, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -+ {13.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 5} }, -+ { 14, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} }, -+ {14.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4} }, -+ { 15, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_444_10bpc_max = { -+ { 6, { 8, 10, 12, 12, 13, 13, 13, 14, 15, 16, 16, 16, 16, 17, 19} }, -+ { 6.5, { 8, 10, 11, 12, 12, 12, 13, 14, 15, 15, 16, 16, 16, 17, 19} }, -+ { 7, { 8, 9, 11, 11, 12, 12, 12, 13, 14, 15, 15, 16, 16, 17, 18} }, -+ { 7.5, { 8, 9, 10, 11, 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18} }, -+ { 8, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -+ { 8.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -+ { 9, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 17} }, -+ { 9.5, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 17} }, -+ { 10, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -+ {10.5, { 6, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 14, 15, 16} }, -+ { 11, { 5, 7, 9, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15} }, -+ {11.5, { 5, 7, 9, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -+ { 12, { 4, 6, 8, 9, 10, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -+ {12.5, { 4, 6, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15} }, -+ { 13, { 3, 6, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 14} }, -+ {13.5, { 3, 5, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14} }, -+ { 14, { 3, 5, 6, 7, 8, 8, 8, 9, 10, 10, 11, 12, 12, 12, 14} }, -+ {14.5, { 2, 4, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13} }, -+ { 15, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ {15.5, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -+ { 16, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12} }, -+ {16.5, { 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12} }, -+ { 17, { 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 12} }, -+ {17.5, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 12} }, -+ { 18, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11} }, -+ {18.5, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11} }, -+ { 19, { 1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 10} }, -+ {19.5, { 1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 10} }, -+ { 20, { 1, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 10} }, -+ {20.5, { 1, 2, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 10} }, -+ { 21, { 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 7, 8, 10} }, -+ {21.5, { 1, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 7, 7, 8, 9} }, -+ { 22, { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 9} }, -+ {22.5, { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8} }, -+ { 23, { 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 8} }, -+ {23.5, { 1, 1, 1, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 8} }, -+ { 24, { 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 8} }, -+ {24.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 8} }, -+ { 25, { 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 7} }, -+ {25.5, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 7} }, -+ { 26, { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 6} }, -+ {26.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 6} }, -+ { 27, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -+ {27.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -+ { 28, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 5} }, -+ {28.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} }, -+ { 29, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4} }, -+ {29.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4} }, -+ { 30, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4} } -+}; -+ -+ -+const qp_table qp_table_422_8bpc_max = { -+ { 6, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -+ { 6.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -+ { 7, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -+ { 7.5, { 3, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12} }, -+ { 8, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -+ { 8.5, { 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -+ { 9, { 1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10} }, -+ { 9.5, { 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10} }, -+ { 10, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -+ {10.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -+ { 11, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8} }, -+ {11.5, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8} }, -+ { 12, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7} }, -+ {12.5, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7} }, -+ { 13, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6} }, -+ {13.5, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 6} }, -+ { 14, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5} }, -+ {14.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5} }, -+ { 15, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 5} }, -+ {15.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} }, -+ { 16, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} } -+}; -+ -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c -new file mode 100644 -index 0000000000000..3ee858f311d12 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c -@@ -0,0 +1,291 @@ -+/* -+ * Copyright 2021 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#include "rc_calc_fpu.h" -+ -+#include "qp_tables.h" -+#include "amdgpu_dm/dc_fpu.h" -+ -+#define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min) -+ -+#define MODE_SELECT(val444, val422, val420) \ -+ (cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420)) -+ -+ -+#define TABLE_CASE(mode, bpc, max) case (table_hash(mode, BPC_##bpc, max)): \ -+ table = qp_table_##mode##_##bpc##bpc_##max; \ -+ table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \ -+ break -+ -+static int median3(int a, int b, int c) -+{ -+ if (a > b) -+ swap(a, b); -+ if (b > c) -+ swap(b, c); -+ if (a > b) -+ swap(b, c); -+ -+ return b; -+} -+ -+static double dsc_roundf(double num) -+{ -+ if (num < 0.0) -+ num = num - 0.5; -+ else -+ num = num + 0.5; -+ -+ return (int)(num); -+} -+ -+static double dsc_ceil(double num) -+{ -+ double retval = (int)num; -+ -+ if (retval != num && num > 0) -+ retval = num + 1; -+ -+ return (int)retval; -+} -+ -+static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, -+ enum max_min max_min, float bpp) -+{ -+ int mode = MODE_SELECT(444, 422, 420); -+ int sel = table_hash(mode, bpc, max_min); -+ int table_size = 0; -+ int index; -+ const struct qp_entry *table = 0L; -+ -+ // alias enum -+ enum { min = DAL_MM_MIN, max = DAL_MM_MAX }; -+ switch (sel) { -+ TABLE_CASE(444, 8, max); -+ TABLE_CASE(444, 8, min); -+ TABLE_CASE(444, 10, max); -+ TABLE_CASE(444, 10, min); -+ TABLE_CASE(444, 12, max); -+ TABLE_CASE(444, 12, min); -+ TABLE_CASE(422, 8, max); -+ TABLE_CASE(422, 8, min); -+ TABLE_CASE(422, 10, max); -+ TABLE_CASE(422, 10, min); -+ TABLE_CASE(422, 12, max); -+ TABLE_CASE(422, 12, min); -+ TABLE_CASE(420, 8, max); -+ TABLE_CASE(420, 8, min); -+ TABLE_CASE(420, 10, max); -+ TABLE_CASE(420, 10, min); -+ TABLE_CASE(420, 12, max); -+ TABLE_CASE(420, 12, min); -+ } -+ -+ if (table == 0) -+ return; -+ -+ index = (bpp - table[0].bpp) * 2; -+ -+ /* requested size is bigger than the table */ -+ if (index >= table_size) { -+ dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n"); -+ return; -+ } -+ -+ memcpy(qps, table[index].qps, sizeof(qp_set)); -+} -+ -+static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) -+{ -+ int *p = ofs; -+ -+ if (mode == CM_444 || mode == CM_RGB) { -+ *p++ = (bpp <= 6) ? (0) : ((((bpp >= 8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); -+ *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); -+ *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); -+ *p++ = (bpp <= 6) ? (-4) : ((((bpp >= 8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); -+ *p++ = (bpp <= 6) ? (-6) : ((((bpp >= 8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); -+ *p++ = (bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0)))); -+ *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0)))); -+ *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0)))); -+ *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0)))); -+ *p++ = (bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0)))); -+ *p++ = -10; -+ *p++ = (bpp <= 6) ? (-12) : ((bpp >= 8) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2 / 2.0)))); -+ *p++ = -12; -+ *p++ = -12; -+ *p++ = -12; -+ } else if (mode == CM_422) { -+ *p++ = (bpp <= 8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp - 8) * (8 / 2.0)))); -+ *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp - 8) * (8 / 2.0)))); -+ *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp - 8) * (4 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp - 8) * (2 / 2.0)))); -+ *p++ = (bpp <= 8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp - 8) * (2 / 2.0)))); -+ *p++ = -10; -+ *p++ = (bpp <= 6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2.0 / 1)))); -+ *p++ = -12; -+ *p++ = -12; -+ *p++ = -12; -+ } else { -+ *p++ = (bpp <= 6) ? (2) : ((bpp >= 8) ? (10) : (2 + dsc_roundf((bpp - 6) * (8 / 2.0)))); -+ *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (8) : (0 + dsc_roundf((bpp - 6) * (8 / 2.0)))); -+ *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (6) : (0 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-2) : ((bpp >= 8) ? (4) : (-2 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-4) : ((bpp >= 8) ? (2) : (-4 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-6) : ((bpp >= 8) ? (0) : (-6 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-2) : (-8 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-4) : (-8 + dsc_roundf((bpp - 6) * (4 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-6) : (-8 + dsc_roundf((bpp - 6) * (2 / 2.0)))); -+ *p++ = (bpp <= 6) ? (-10) : ((bpp >= 8) ? (-8) : (-10 + dsc_roundf((bpp - 6) * (2 / 2.0)))); -+ *p++ = -10; -+ *p++ = (bpp <= 4) ? (-12) : ((bpp >= 5) ? (-10) : (-12 + dsc_roundf((bpp - 4) * (2 / 1.0)))); -+ *p++ = -12; -+ *p++ = -12; -+ *p++ = -12; -+ } -+} -+ -+void _do_calc_rc_params(struct rc_params *rc, -+ enum colour_mode cm, -+ enum bits_per_comp bpc, -+ u16 drm_bpp, -+ bool is_navite_422_or_420, -+ int slice_width, -+ int slice_height, -+ int minor_version) -+{ -+ float bpp; -+ float bpp_group; -+ float initial_xmit_delay_factor; -+ int padding_pixels; -+ int i; -+ -+ dc_assert_fp_enabled(); -+ -+ bpp = ((float)drm_bpp / 16.0); -+ /* in native_422 or native_420 modes, the bits_per_pixel is double the -+ * target bpp (the latter is what calc_rc_params expects) -+ */ -+ if (is_navite_422_or_420) -+ bpp /= 2.0; -+ -+ rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -+ rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -+ -+ bpp_group = MODE_SELECT(bpp, bpp * 2.0, bpp * 2.0); -+ -+ switch (cm) { -+ case CM_420: -+ rc->initial_fullness_offset = (bpp >= 6) ? (2048) : ((bpp <= 4) ? (6144) : ((((bpp > 4) && (bpp <= 5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp - 5) * (3584))))); -+ rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group))); -+ rc->second_line_bpg_offset = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group))); -+ break; -+ case CM_422: -+ rc->initial_fullness_offset = (bpp >= 8) ? (2048) : ((bpp <= 7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584)))); -+ rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group))); -+ rc->second_line_bpg_offset = 0; -+ break; -+ case CM_444: -+ case CM_RGB: -+ rc->initial_fullness_offset = (bpp >= 12) ? (2048) : ((bpp <= 8) ? (6144) : ((((bpp > 8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2))))); -+ rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group))); -+ rc->second_line_bpg_offset = 0; -+ break; -+ } -+ -+ initial_xmit_delay_factor = (cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0; -+ rc->initial_xmit_delay = dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor); -+ -+ if (cm == CM_422 || cm == CM_420) -+ slice_width /= 2; -+ -+ padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0; -+ if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) { -+ if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1) -+ rc->initial_xmit_delay++; -+ } -+ -+ rc->flatness_min_qp = ((bpc == BPC_8) ? (3) : ((bpc == BPC_10) ? (7) : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -+ rc->flatness_max_qp = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -+ rc->flatness_det_thresh = 2 << (bpc - 8); -+ -+ get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp); -+ get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp); -+ if (cm == CM_444 && minor_version == 1) { -+ for (i = 0; i < QP_SET_SIZE; ++i) { -+ rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0; -+ rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0; -+ } -+ } -+ get_ofs_set(rc->ofs, cm, bpp); -+ -+ /* fixed parameters */ -+ rc->rc_model_size = 8192; -+ rc->rc_edge_factor = 6; -+ rc->rc_tgt_offset_hi = 3; -+ rc->rc_tgt_offset_lo = 3; -+ -+ rc->rc_buf_thresh[0] = 896; -+ rc->rc_buf_thresh[1] = 1792; -+ rc->rc_buf_thresh[2] = 2688; -+ rc->rc_buf_thresh[3] = 3584; -+ rc->rc_buf_thresh[4] = 4480; -+ rc->rc_buf_thresh[5] = 5376; -+ rc->rc_buf_thresh[6] = 6272; -+ rc->rc_buf_thresh[7] = 6720; -+ rc->rc_buf_thresh[8] = 7168; -+ rc->rc_buf_thresh[9] = 7616; -+ rc->rc_buf_thresh[10] = 7744; -+ rc->rc_buf_thresh[11] = 7872; -+ rc->rc_buf_thresh[12] = 8000; -+ rc->rc_buf_thresh[13] = 8064; -+} -+ -+u32 _do_bytes_per_pixel_calc(int slice_width, -+ u16 drm_bpp, -+ bool is_navite_422_or_420) -+{ -+ float bpp; -+ u32 bytes_per_pixel; -+ double d_bytes_per_pixel; -+ -+ dc_assert_fp_enabled(); -+ -+ bpp = ((float)drm_bpp / 16.0); -+ d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; -+ // TODO: Make sure the formula for calculating this is precise (ceiling -+ // vs. floor, and at what point they should be applied) -+ if (is_navite_422_or_420) -+ d_bytes_per_pixel /= 2; -+ -+ bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000); -+ -+ return bytes_per_pixel; -+} -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h -new file mode 100644 -index 0000000000000..b93b95409fbe2 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h -@@ -0,0 +1,94 @@ -+/* -+ * Copyright 2021 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#ifndef __RC_CALC_FPU_H__ -+#define __RC_CALC_FPU_H__ -+ -+#include "os_types.h" -+#include -+ -+#define QP_SET_SIZE 15 -+ -+typedef int qp_set[QP_SET_SIZE]; -+ -+struct rc_params { -+ int rc_quant_incr_limit0; -+ int rc_quant_incr_limit1; -+ int initial_fullness_offset; -+ int initial_xmit_delay; -+ int first_line_bpg_offset; -+ int second_line_bpg_offset; -+ int flatness_min_qp; -+ int flatness_max_qp; -+ int flatness_det_thresh; -+ qp_set qp_min; -+ qp_set qp_max; -+ qp_set ofs; -+ int rc_model_size; -+ int rc_edge_factor; -+ int rc_tgt_offset_hi; -+ int rc_tgt_offset_lo; -+ int rc_buf_thresh[QP_SET_SIZE - 1]; -+}; -+ -+enum colour_mode { -+ CM_RGB, /* 444 RGB */ -+ CM_444, /* 444 YUV or simple 422 */ -+ CM_422, /* native 422 */ -+ CM_420 /* native 420 */ -+}; -+ -+enum bits_per_comp { -+ BPC_8 = 8, -+ BPC_10 = 10, -+ BPC_12 = 12 -+}; -+ -+enum max_min { -+ DAL_MM_MIN = 0, -+ DAL_MM_MAX = 1 -+}; -+ -+struct qp_entry { -+ float bpp; -+ const qp_set qps; -+}; -+ -+typedef struct qp_entry qp_table[]; -+ -+u32 _do_bytes_per_pixel_calc(int slice_width, -+ u16 drm_bpp, -+ bool is_navite_422_or_420); -+ -+void _do_calc_rc_params(struct rc_params *rc, -+ enum colour_mode cm, -+ enum bits_per_comp bpc, -+ u16 drm_bpp, -+ bool is_navite_422_or_420, -+ int slice_width, -+ int slice_height, -+ int minor_version); -+ -+#endif -diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile -index 8d31eb75c6a6e..a2537229ee88b 100644 ---- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile -@@ -1,35 +1,6 @@ - # SPDX-License-Identifier: MIT - # - # Makefile for the 'dsc' sub-component of DAL. -- --ifdef CONFIG_X86 --dsc_ccflags := -mhard-float -msse --endif -- --ifdef CONFIG_PPC64 --dsc_ccflags := -mhard-float -maltivec --endif -- --ifdef CONFIG_CC_IS_GCC --ifeq ($(call cc-ifversion, -lt, 0701, y), y) --IS_OLD_GCC = 1 --endif --endif -- --ifdef CONFIG_X86 --ifdef IS_OLD_GCC --# Stack alignment mismatch, proceed with caution. --# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 --# (8B stack alignment). --dsc_ccflags += -mpreferred-stack-boundary=4 --else --dsc_ccflags += -msse2 --endif --endif -- --CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags) --CFLAGS_REMOVE_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_rcflags) -- - DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o - - AMD_DAL_DSC = $(addprefix $(AMDDALPATH)/dc/dsc/,$(DSC)) -diff --git a/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h b/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h -deleted file mode 100644 -index e5fac9f4181d8..0000000000000 ---- a/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h -+++ /dev/null -@@ -1,704 +0,0 @@ -- --/* -- * Copyright 2017 Advanced Micro Devices, Inc. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -- * -- * Authors: AMD -- * -- */ -- -- --const qp_table qp_table_422_10bpc_min = { -- { 6, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 12, 16} }, -- { 6.5, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 12, 16} }, -- { 7, { 0, 4, 5, 6, 6, 6, 6, 7, 7, 7, 9, 9, 9, 11, 15} }, -- { 7.5, { 0, 2, 4, 6, 6, 6, 6, 7, 7, 7, 8, 9, 9, 11, 15} }, -- { 8, { 0, 2, 3, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 11, 14} }, -- { 8.5, { 0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 14} }, -- { 9, { 0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 13} }, -- { 9.5, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 13} }, -- { 10, { 0, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12} }, -- {10.5, { 0, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 11, 12} }, -- { 11, { 0, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11} }, -- {11.5, { 0, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 10, 11} }, -- { 12, { 0, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10} }, -- {12.5, { 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} }, -- { 13, { 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 6, 6, 8, 8, 9} }, -- {13.5, { 0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 9} }, -- { 14, { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8} }, -- {14.5, { 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8} }, -- { 15, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 6, 8} }, -- {15.5, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -- { 16, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 7} }, -- {16.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6} }, -- { 17, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 6} }, -- {17.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -- { 18, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 5} }, -- {18.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 5} }, -- { 19, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 4} }, -- {19.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 4} }, -- { 20, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 3} } --}; -- -- --const qp_table qp_table_444_8bpc_max = { -- { 6, { 4, 6, 8, 8, 9, 9, 9, 10, 11, 12, 12, 12, 12, 13, 15} }, -- { 6.5, { 4, 6, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 12, 13, 15} }, -- { 7, { 4, 5, 7, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 13, 14} }, -- { 7.5, { 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -- { 8, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -- { 8.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -- { 9, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 13} }, -- { 9.5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 13} }, -- { 10, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -- {10.5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 11, 12} }, -- { 11, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11} }, -- {11.5, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -- { 12, { 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -- {12.5, { 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -- { 13, { 1, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 10} }, -- {13.5, { 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10} }, -- { 14, { 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} }, -- {14.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9} }, -- { 15, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -- {15.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -- { 16, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8} }, -- {16.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8} }, -- { 17, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 8} }, -- {17.5, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 8} }, -- { 18, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7} }, -- {18.5, { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7} }, -- { 19, { 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6} }, -- {19.5, { 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6} }, -- { 20, { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 6} }, -- {20.5, { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 6} }, -- { 21, { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -- {21.5, { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -- { 22, { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} }, -- {22.5, { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} }, -- { 23, { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4} }, -- {23.5, { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4} }, -- { 24, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4} } --}; -- -- --const qp_table qp_table_420_12bpc_max = { -- { 4, {11, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 21, 22} }, -- { 4.5, {10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -- { 5, { 9, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 21} }, -- { 5.5, { 8, 10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 19, 20} }, -- { 6, { 6, 9, 11, 12, 13, 14, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -- { 6.5, { 6, 8, 10, 11, 11, 13, 14, 15, 15, 16, 16, 17, 17, 18, 19} }, -- { 7, { 5, 7, 9, 10, 10, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18} }, -- { 7.5, { 5, 7, 8, 9, 9, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17} }, -- { 8, { 4, 6, 7, 8, 8, 10, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -- { 8.5, { 3, 6, 6, 7, 7, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -- { 9, { 3, 5, 6, 7, 7, 10, 11, 12, 12, 13, 13, 14, 14, 14, 15} }, -- { 9.5, { 2, 5, 6, 6, 7, 9, 10, 11, 12, 12, 13, 13, 13, 14, 15} }, -- { 10, { 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 15} }, -- {10.5, { 2, 3, 5, 5, 6, 7, 8, 9, 11, 11, 12, 12, 12, 12, 14} }, -- { 11, { 1, 3, 4, 5, 6, 6, 7, 9, 10, 11, 11, 11, 12, 12, 13} }, -- {11.5, { 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 10, 11, 11, 11, 13} }, -- { 12, { 1, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 12} }, -- {12.5, { 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 11} }, -- { 13, { 1, 1, 1, 2, 4, 4, 6, 6, 7, 8, 8, 9, 9, 9, 11} }, -- {13.5, { 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8, 9, 11} }, -- { 14, { 1, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} }, -- {14.5, { 0, 1, 1, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -- { 15, { 0, 1, 1, 1, 1, 2, 3, 3, 5, 5, 5, 6, 6, 7, 9} }, -- {15.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8} }, -- { 16, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 7} }, -- {16.5, { 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 7} }, -- { 17, { 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 6} }, -- {17.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6} }, -- { 18, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 5} } --}; -- -- --const qp_table qp_table_444_10bpc_min = { -- { 6, { 0, 4, 7, 7, 9, 9, 9, 9, 9, 10, 10, 10, 10, 12, 18} }, -- { 6.5, { 0, 4, 6, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 12, 18} }, -- { 7, { 0, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 10, 10, 12, 17} }, -- { 7.5, { 0, 4, 6, 6, 7, 8, 8, 8, 8, 8, 9, 9, 10, 12, 17} }, -- { 8, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16} }, -- { 8.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 8, 9, 9, 9, 12, 16} }, -- { 9, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -- { 9.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -- { 10, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 15} }, -- {10.5, { 0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 15} }, -- { 11, { 0, 3, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -- {11.5, { 0, 3, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -- { 12, { 0, 2, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -- {12.5, { 0, 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 9, 9, 11, 14} }, -- { 13, { 0, 2, 4, 4, 5, 6, 7, 7, 7, 7, 8, 9, 9, 11, 13} }, -- {13.5, { 0, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 11, 13} }, -- { 14, { 0, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 11, 13} }, -- {14.5, { 0, 2, 3, 4, 5, 5, 6, 6, 6, 7, 7, 8, 9, 11, 12} }, -- { 15, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 11, 12} }, -- {15.5, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 11, 12} }, -- { 16, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 10, 11} }, -- {16.5, { 0, 1, 2, 3, 4, 5, 5, 6, 6, 6, 7, 8, 8, 10, 11} }, -- { 17, { 0, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 9, 11} }, -- {17.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 11} }, -- { 18, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} }, -- {18.5, { 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10} }, -- { 19, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9} }, -- {19.5, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9} }, -- { 20, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 9} }, -- {20.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 9} }, -- { 21, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 9} }, -- {21.5, { 0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8} }, -- { 22, { 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 8} }, -- {22.5, { 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -- { 23, { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 7} }, -- {23.5, { 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 7} }, -- { 24, { 0, 0, 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 7} }, -- {24.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 7} }, -- { 25, { 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} }, -- {25.5, { 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -- { 26, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 5} }, -- {26.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 5} }, -- { 27, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} }, -- {27.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} }, -- { 28, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4} }, -- {28.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 4} }, -- { 29, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3} }, -- {29.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3} }, -- { 30, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} } --}; -- -- --const qp_table qp_table_420_8bpc_max = { -- { 4, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 13, 14} }, -- { 4.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -- { 5, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 12, 13} }, -- { 5.5, { 3, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12} }, -- { 6, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -- { 6.5, { 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -- { 7, { 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10} }, -- { 7.5, { 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9} }, -- { 8, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -- { 8.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8} }, -- { 9, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7} }, -- { 9.5, { 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -- { 10, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6} }, -- {10.5, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} }, -- { 11, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5} }, -- {11.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5} }, -- { 12, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4} } --}; -- -- --const qp_table qp_table_444_8bpc_min = { -- { 6, { 0, 1, 3, 3, 5, 5, 5, 5, 5, 6, 6, 6, 6, 9, 14} }, -- { 6.5, { 0, 1, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 9, 14} }, -- { 7, { 0, 0, 2, 2, 4, 4, 4, 4, 4, 5, 5, 6, 6, 9, 13} }, -- { 7.5, { 0, 0, 2, 2, 3, 4, 4, 4, 4, 4, 5, 5, 6, 9, 13} }, -- { 8, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 8, 12} }, -- { 8.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 8, 12} }, -- { 9, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} }, -- { 9.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} }, -- { 10, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -- {10.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -- { 11, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -- {11.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -- { 12, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -- {12.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 4, 5, 5, 7, 10} }, -- { 13, { 0, 0, 1, 1, 2, 3, 3, 3, 3, 3, 4, 5, 5, 7, 9} }, -- {13.5, { 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -- { 14, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -- {14.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8} }, -- { 15, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -- {15.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -- { 16, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -- {16.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -- { 17, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -- {17.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -- { 18, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -- {18.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -- { 19, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5} }, -- {19.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5} }, -- { 20, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5} }, -- {20.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5} }, -- { 21, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} }, -- {21.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} }, -- { 22, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} }, -- {22.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} }, -- { 23, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} }, -- {23.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} }, -- { 24, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3} } --}; -- -- --const qp_table qp_table_444_12bpc_min = { -- { 6, { 0, 5, 11, 11, 13, 13, 13, 13, 13, 14, 14, 14, 14, 17, 22} }, -- { 6.5, { 0, 5, 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 17, 22} }, -- { 7, { 0, 5, 10, 10, 12, 12, 12, 12, 12, 13, 13, 14, 14, 17, 21} }, -- { 7.5, { 0, 5, 9, 10, 11, 12, 12, 12, 12, 12, 13, 13, 14, 17, 21} }, -- { 8, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 12, 13, 13, 13, 16, 20} }, -- { 8.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 12, 13, 13, 13, 16, 20} }, -- { 9, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -- { 9.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -- { 10, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -- {10.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -- { 11, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- {11.5, { 0, 4, 8, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- { 12, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- {12.5, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- { 13, { 0, 4, 7, 8, 9, 11, 11, 11, 11, 11, 13, 13, 13, 15, 17} }, -- {13.5, { 0, 3, 6, 7, 9, 10, 10, 11, 11, 11, 12, 13, 13, 15, 17} }, -- { 14, { 0, 3, 5, 6, 9, 9, 9, 10, 11, 11, 12, 13, 13, 15, 17} }, -- {14.5, { 0, 2, 5, 6, 8, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -- { 15, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -- {15.5, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -- { 16, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 12, 12, 14, 15} }, -- {16.5, { 0, 2, 3, 5, 7, 8, 9, 10, 11, 11, 11, 12, 12, 14, 15} }, -- { 17, { 0, 2, 3, 5, 5, 6, 9, 9, 10, 10, 11, 11, 12, 13, 15} }, -- {17.5, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 15} }, -- { 18, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -- {18.5, { 0, 2, 3, 5, 5, 6, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -- { 19, { 0, 1, 2, 4, 5, 5, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- {19.5, { 0, 1, 2, 4, 5, 5, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- { 20, { 0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 9, 10, 10, 11, 13} }, -- {20.5, { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 13} }, -- { 21, { 0, 1, 2, 3, 4, 5, 5, 7, 7, 8, 9, 10, 10, 11, 13} }, -- {21.5, { 0, 1, 2, 3, 3, 4, 5, 7, 7, 8, 9, 10, 10, 11, 12} }, -- { 22, { 0, 0, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 12} }, -- {22.5, { 0, 0, 1, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 11} }, -- { 23, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 7, 9, 9, 9, 9, 11} }, -- {23.5, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 7, 9, 9, 9, 9, 11} }, -- { 24, { 0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 8, 8, 9, 11} }, -- {24.5, { 0, 0, 1, 2, 3, 4, 4, 6, 6, 7, 8, 8, 8, 9, 11} }, -- { 25, { 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 8, 8, 10} }, -- {25.5, { 0, 0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 10} }, -- { 26, { 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 9} }, -- {26.5, { 0, 0, 1, 2, 2, 3, 4, 5, 5, 5, 7, 7, 7, 7, 9} }, -- { 27, { 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -- {27.5, { 0, 0, 1, 1, 2, 2, 4, 4, 4, 5, 6, 7, 7, 7, 9} }, -- { 28, { 0, 0, 0, 1, 1, 2, 3, 4, 4, 4, 6, 6, 6, 7, 9} }, -- {28.5, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 8} }, -- { 29, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8} }, -- {29.5, { 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7} }, -- { 30, { 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 5, 5, 5, 5, 7} }, -- {30.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 7} }, -- { 31, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 7} }, -- {31.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -- { 32, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 6} }, -- {32.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 6} }, -- { 33, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} }, -- {33.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 5} }, -- { 34, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 5} }, -- {34.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 3, 5} }, -- { 35, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} }, -- {35.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 4} }, -- { 36, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3} } --}; -- -- --const qp_table qp_table_420_12bpc_min = { -- { 4, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 21} }, -- { 4.5, { 0, 4, 8, 9, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -- { 5, { 0, 4, 8, 9, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 20} }, -- { 5.5, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -- { 6, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- { 6.5, { 0, 4, 6, 8, 9, 10, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- { 7, { 0, 3, 5, 7, 9, 10, 10, 11, 11, 11, 13, 13, 13, 15, 17} }, -- { 7.5, { 0, 3, 5, 7, 8, 9, 10, 10, 11, 11, 12, 13, 13, 15, 16} }, -- { 8, { 0, 2, 4, 6, 7, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -- { 8.5, { 0, 2, 4, 6, 6, 9, 9, 10, 11, 11, 12, 12, 13, 14, 15} }, -- { 9, { 0, 2, 4, 6, 6, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14} }, -- { 9.5, { 0, 2, 4, 5, 6, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14} }, -- { 10, { 0, 2, 3, 5, 6, 7, 8, 8, 9, 10, 10, 12, 12, 12, 14} }, -- {10.5, { 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 11, 11, 13} }, -- { 11, { 0, 2, 3, 4, 5, 5, 6, 8, 8, 9, 9, 10, 11, 11, 12} }, -- {11.5, { 0, 1, 2, 3, 4, 5, 5, 7, 8, 8, 9, 10, 10, 10, 12} }, -- { 12, { 0, 0, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 11} }, -- {12.5, { 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 10} }, -- { 13, { 0, 0, 0, 1, 3, 3, 5, 5, 6, 7, 7, 8, 8, 8, 10} }, -- {13.5, { 0, 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 7, 8, 10} }, -- { 14, { 0, 0, 0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 7, 9} }, -- {14.5, { 0, 0, 0, 0, 1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 8} }, -- { 15, { 0, 0, 0, 0, 0, 1, 2, 2, 4, 4, 4, 5, 5, 6, 8} }, -- {15.5, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7} }, -- { 16, { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 6} }, -- {16.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6} }, -- { 17, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 5} }, -- {17.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 5} }, -- { 18, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 4} } --}; -- -- --const qp_table qp_table_422_12bpc_min = { -- { 6, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 16, 20} }, -- { 6.5, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 16, 20} }, -- { 7, { 0, 4, 9, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -- { 7.5, { 0, 4, 8, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 19} }, -- { 8, { 0, 4, 7, 8, 10, 11, 11, 11, 11, 11, 13, 13, 13, 15, 18} }, -- { 8.5, { 0, 3, 6, 8, 9, 10, 10, 11, 11, 11, 12, 13, 13, 15, 18} }, -- { 9, { 0, 3, 5, 8, 9, 10, 10, 10, 11, 11, 12, 13, 13, 15, 17} }, -- { 9.5, { 0, 3, 5, 7, 8, 9, 10, 10, 11, 11, 12, 13, 13, 15, 17} }, -- { 10, { 0, 2, 4, 6, 7, 9, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -- {10.5, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 15, 16} }, -- { 11, { 0, 2, 4, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 14, 15} }, -- {11.5, { 0, 2, 4, 6, 7, 7, 9, 9, 10, 11, 11, 12, 12, 14, 15} }, -- { 12, { 0, 2, 4, 6, 6, 6, 8, 8, 9, 9, 11, 11, 12, 13, 14} }, -- {12.5, { 0, 1, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 13, 14} }, -- { 13, { 0, 1, 3, 4, 5, 5, 7, 8, 8, 9, 10, 10, 11, 12, 13} }, -- {13.5, { 0, 1, 3, 3, 4, 5, 7, 7, 8, 8, 10, 10, 10, 12, 13} }, -- { 14, { 0, 0, 2, 3, 4, 5, 6, 6, 7, 7, 9, 10, 10, 11, 12} }, -- {14.5, { 0, 0, 1, 3, 4, 4, 6, 6, 6, 7, 9, 9, 9, 11, 12} }, -- { 15, { 0, 0, 1, 3, 3, 4, 5, 6, 6, 6, 8, 9, 9, 10, 12} }, -- {15.5, { 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 8, 8, 8, 10, 11} }, -- { 16, { 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 8, 8, 8, 9, 11} }, -- {16.5, { 0, 0, 0, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7, 9, 10} }, -- { 17, { 0, 0, 0, 1, 2, 2, 4, 4, 4, 5, 6, 6, 6, 8, 10} }, -- {17.5, { 0, 0, 0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 8, 9} }, -- { 18, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 9} }, -- {18.5, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 3, 5, 5, 5, 7, 9} }, -- { 19, { 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 8} }, -- {19.5, { 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 6, 8} }, -- { 20, { 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 7} }, -- {20.5, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 7} }, -- { 21, { 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -- {21.5, { 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 6} }, -- { 22, { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 6} }, -- {22.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 5} }, -- { 23, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 5} }, -- {23.5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 4} }, -- { 24, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 4} } --}; -- -- --const qp_table qp_table_422_12bpc_max = { -- { 6, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -- { 6.5, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -- { 7, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20} }, -- { 7.5, { 9, 10, 12, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20} }, -- { 8, { 6, 9, 10, 12, 14, 15, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -- { 8.5, { 6, 8, 9, 11, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 19} }, -- { 9, { 5, 7, 8, 10, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 18} }, -- { 9.5, { 5, 7, 7, 9, 10, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18} }, -- { 10, { 4, 6, 6, 8, 9, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -- {10.5, { 4, 6, 6, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -- { 11, { 4, 5, 6, 8, 9, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -- {11.5, { 3, 5, 6, 8, 9, 9, 11, 11, 12, 13, 13, 14, 14, 15, 16} }, -- { 12, { 3, 5, 6, 8, 8, 8, 10, 10, 11, 11, 13, 13, 14, 14, 15} }, -- {12.5, { 3, 4, 6, 7, 8, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15} }, -- { 13, { 2, 4, 5, 6, 7, 7, 9, 10, 10, 11, 12, 12, 13, 13, 14} }, -- {13.5, { 2, 4, 5, 5, 6, 7, 9, 9, 10, 10, 12, 12, 12, 13, 14} }, -- { 14, { 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 11, 12, 12, 12, 13} }, -- {14.5, { 2, 3, 3, 5, 6, 6, 8, 8, 8, 9, 11, 11, 11, 12, 13} }, -- { 15, { 2, 3, 3, 5, 5, 6, 7, 8, 8, 8, 10, 11, 11, 11, 13} }, -- {15.5, { 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 10, 10, 10, 11, 12} }, -- { 16, { 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 10, 10, 10, 10, 12} }, -- {16.5, { 1, 2, 2, 4, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 11} }, -- { 17, { 1, 1, 2, 3, 4, 4, 6, 6, 6, 7, 8, 8, 8, 9, 11} }, -- {17.5, { 1, 1, 2, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8, 9, 10} }, -- { 18, { 1, 1, 1, 2, 3, 3, 5, 5, 5, 6, 7, 7, 8, 8, 10} }, -- {18.5, { 1, 1, 1, 2, 3, 3, 5, 5, 5, 5, 7, 7, 7, 8, 10} }, -- { 19, { 1, 1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 9} }, -- {19.5, { 1, 1, 1, 2, 2, 2, 4, 5, 5, 5, 6, 6, 6, 7, 9} }, -- { 20, { 1, 1, 1, 2, 2, 2, 4, 5, 5, 5, 6, 6, 6, 6, 8} }, -- {20.5, { 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 8} }, -- { 21, { 0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 7} }, -- {21.5, { 0, 0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 7} }, -- { 22, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 7} }, -- {22.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 6} }, -- { 23, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6} }, -- {23.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5} }, -- { 24, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5} } --}; -- -- --const qp_table qp_table_444_12bpc_max = { -- { 6, {12, 14, 16, 16, 17, 17, 17, 18, 19, 20, 20, 20, 20, 21, 23} }, -- { 6.5, {12, 14, 15, 16, 16, 16, 17, 18, 19, 19, 20, 20, 20, 21, 23} }, -- { 7, {12, 13, 15, 15, 16, 16, 16, 17, 18, 19, 19, 20, 20, 21, 22} }, -- { 7.5, {12, 13, 14, 15, 15, 16, 16, 17, 18, 18, 19, 19, 20, 21, 22} }, -- { 8, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -- { 8.5, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21} }, -- { 9, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 21} }, -- { 9.5, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 21} }, -- { 10, {11, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20} }, -- {10.5, {10, 12, 13, 14, 15, 15, 15, 16, 17, 17, 18, 18, 18, 19, 20} }, -- { 11, { 9, 11, 13, 14, 15, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19} }, -- {11.5, { 9, 11, 13, 14, 15, 15, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -- { 12, { 6, 9, 12, 13, 14, 14, 15, 16, 16, 17, 17, 17, 17, 18, 19} }, -- {12.5, { 6, 9, 12, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 19} }, -- { 13, { 5, 9, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 17, 18} }, -- {13.5, { 5, 8, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 18} }, -- { 14, { 5, 8, 10, 11, 12, 12, 12, 13, 14, 14, 15, 16, 16, 16, 18} }, -- {14.5, { 4, 7, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17} }, -- { 15, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -- {15.5, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17} }, -- { 16, { 4, 7, 9, 10, 10, 11, 11, 12, 13, 13, 13, 14, 14, 15, 16} }, -- {16.5, { 4, 5, 7, 8, 10, 11, 11, 12, 13, 13, 13, 14, 14, 15, 16} }, -- { 17, { 4, 5, 7, 8, 8, 9, 11, 11, 12, 12, 12, 13, 13, 14, 16} }, -- {17.5, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 16} }, -- { 18, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 15} }, -- {18.5, { 3, 5, 7, 8, 8, 9, 10, 11, 12, 12, 12, 13, 13, 14, 15} }, -- { 19, { 3, 4, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 14} }, -- {19.5, { 3, 4, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 14} }, -- { 20, { 2, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11, 11, 12, 14} }, -- {20.5, { 2, 3, 5, 5, 7, 8, 8, 8, 9, 10, 10, 11, 11, 12, 14} }, -- { 21, { 2, 3, 5, 5, 7, 7, 7, 8, 8, 9, 10, 11, 11, 12, 14} }, -- {21.5, { 2, 3, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13} }, -- { 22, { 2, 2, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 10, 11, 13} }, -- {22.5, { 2, 2, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 10, 11, 12} }, -- { 23, { 2, 2, 4, 5, 5, 6, 7, 7, 7, 8, 10, 10, 10, 10, 12} }, -- {23.5, { 2, 2, 3, 5, 5, 6, 7, 7, 7, 8, 10, 10, 10, 10, 12} }, -- { 24, { 2, 2, 3, 4, 4, 5, 7, 7, 7, 8, 9, 9, 9, 10, 12} }, -- {24.5, { 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 9, 9, 10, 12} }, -- { 25, { 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9, 11} }, -- {25.5, { 1, 1, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 9, 11} }, -- { 26, { 1, 1, 3, 3, 3, 4, 5, 6, 6, 7, 8, 8, 8, 8, 10} }, -- {26.5, { 1, 1, 2, 3, 3, 4, 5, 6, 6, 6, 8, 8, 8, 8, 10} }, -- { 27, { 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 10} }, -- {27.5, { 1, 1, 2, 2, 3, 3, 5, 5, 5, 6, 7, 8, 8, 8, 10} }, -- { 28, { 0, 1, 1, 2, 2, 3, 4, 5, 5, 5, 7, 7, 7, 8, 10} }, -- {28.5, { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -- { 29, { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 9} }, -- {29.5, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8} }, -- { 30, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6, 6, 6, 8} }, -- {30.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8} }, -- { 31, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 8} }, -- {31.5, { 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8} }, -- { 32, { 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 7} }, -- {32.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 7} }, -- { 33, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -- {33.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -- { 34, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 6} }, -- {34.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 3, 3, 3, 3, 4, 6} }, -- { 35, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} }, -- {35.5, { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 5} }, -- { 36, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4} } --}; -- -- --const qp_table qp_table_420_8bpc_min = { -- { 4, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 13} }, -- { 4.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -- { 5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -- { 5.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -- { 6, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -- { 6.5, { 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 5, 7, 10} }, -- { 7, { 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -- { 7.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8} }, -- { 8, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -- { 8.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -- { 9, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6} }, -- { 9.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -- { 10, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5} }, -- {10.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 5} }, -- { 11, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4} }, -- {11.5, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4} }, -- { 12, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 3} } --}; -- -- --const qp_table qp_table_422_8bpc_min = { -- { 6, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -- { 6.5, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 8, 12} }, -- { 7, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -- { 7.5, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11} }, -- { 8, { 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10} }, -- { 8.5, { 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 7, 10} }, -- { 9, { 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 4, 5, 5, 7, 9} }, -- { 9.5, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 9} }, -- { 10, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -- {10.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 8} }, -- { 11, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -- {11.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7} }, -- { 12, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6} }, -- {12.5, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6} }, -- { 13, { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5} }, -- {13.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 5} }, -- { 14, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4} }, -- {14.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4} }, -- { 15, { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 4} }, -- {15.5, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} }, -- { 16, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3} } --}; -- -- --const qp_table qp_table_422_10bpc_max = { -- { 6, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -- { 6.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -- { 7, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -- { 7.5, { 5, 6, 8, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16} }, -- { 8, { 4, 6, 7, 9, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -- { 8.5, { 4, 5, 6, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15} }, -- { 9, { 3, 4, 5, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14} }, -- { 9.5, { 3, 4, 4, 6, 6, 8, 8, 9, 10, 10, 11, 11, 12, 13, 14} }, -- { 10, { 2, 3, 3, 5, 5, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- {10.5, { 2, 3, 3, 5, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- { 11, { 2, 3, 3, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -- {11.5, { 2, 3, 3, 5, 5, 5, 7, 7, 8, 9, 9, 10, 10, 11, 12} }, -- { 12, { 2, 3, 3, 5, 5, 5, 7, 7, 8, 8, 9, 9, 10, 10, 11} }, -- {12.5, { 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -- { 13, { 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10} }, -- {13.5, { 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10} }, -- { 14, { 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 9} }, -- {14.5, { 1, 2, 2, 3, 4, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9} }, -- { 15, { 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 7, 9} }, -- {15.5, { 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 8} }, -- { 16, { 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 8} }, -- {16.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7} }, -- { 17, { 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 7} }, -- {17.5, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6} }, -- { 18, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 6} }, -- {18.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 6} }, -- { 19, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 5} }, -- {19.5, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 5} }, -- { 20, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 4} } --}; -- -- --const qp_table qp_table_420_10bpc_max = { -- { 4, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 17, 18} }, -- { 4.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -- { 5, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 16, 17} }, -- { 5.5, { 6, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 16} }, -- { 6, { 4, 6, 8, 9, 10, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -- { 6.5, { 4, 5, 7, 8, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 15} }, -- { 7, { 3, 4, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 13, 14} }, -- { 7.5, { 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13} }, -- { 8, { 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- { 8.5, { 1, 3, 3, 4, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -- { 9, { 1, 3, 3, 4, 4, 6, 7, 8, 8, 9, 9, 10, 10, 10, 11} }, -- { 9.5, { 1, 3, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 11} }, -- { 10, { 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, 11} }, -- {10.5, { 1, 1, 3, 3, 3, 4, 5, 5, 7, 7, 8, 8, 8, 8, 10} }, -- { 11, { 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 8, 9} }, -- {11.5, { 0, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 7, 7, 9} }, -- { 12, { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 8} }, -- {12.5, { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7} }, -- { 13, { 0, 0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7} }, -- {13.5, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 6} }, -- { 14, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -- {14.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5} }, -- { 15, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 5} } --}; -- -- --const qp_table qp_table_420_10bpc_min = { -- { 4, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 17} }, -- { 4.5, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -- { 5, { 0, 4, 4, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 12, 16} }, -- { 5.5, { 0, 3, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15} }, -- { 6, { 0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14} }, -- { 6.5, { 0, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 11, 14} }, -- { 7, { 0, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 11, 13} }, -- { 7.5, { 0, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 11, 12} }, -- { 8, { 0, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12} }, -- { 8.5, { 0, 2, 2, 3, 3, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11} }, -- { 9, { 0, 2, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10} }, -- { 9.5, { 0, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10} }, -- { 10, { 0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 8, 8, 8, 10} }, -- {10.5, { 0, 0, 2, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 7, 9} }, -- { 11, { 0, 0, 1, 2, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8} }, -- {11.5, { 0, 0, 0, 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 8} }, -- { 12, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 7} }, -- {12.5, { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 6} }, -- { 13, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -- {13.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 5} }, -- { 14, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} }, -- {14.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4} }, -- { 15, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 4} } --}; -- -- --const qp_table qp_table_444_10bpc_max = { -- { 6, { 8, 10, 12, 12, 13, 13, 13, 14, 15, 16, 16, 16, 16, 17, 19} }, -- { 6.5, { 8, 10, 11, 12, 12, 12, 13, 14, 15, 15, 16, 16, 16, 17, 19} }, -- { 7, { 8, 9, 11, 11, 12, 12, 12, 13, 14, 15, 15, 16, 16, 17, 18} }, -- { 7.5, { 8, 9, 10, 11, 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18} }, -- { 8, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -- { 8.5, { 8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17} }, -- { 9, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 17} }, -- { 9.5, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 17} }, -- { 10, { 7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16} }, -- {10.5, { 6, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 14, 15, 16} }, -- { 11, { 5, 7, 9, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15} }, -- {11.5, { 5, 7, 9, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -- { 12, { 4, 6, 8, 9, 10, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15} }, -- {12.5, { 4, 6, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15} }, -- { 13, { 3, 6, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 14} }, -- {13.5, { 3, 5, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14} }, -- { 14, { 3, 5, 6, 7, 8, 8, 8, 9, 10, 10, 11, 12, 12, 12, 14} }, -- {14.5, { 2, 4, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13} }, -- { 15, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- {15.5, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13} }, -- { 16, { 2, 4, 5, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12} }, -- {16.5, { 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12} }, -- { 17, { 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 12} }, -- {17.5, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 12} }, -- { 18, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11} }, -- {18.5, { 1, 3, 4, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11} }, -- { 19, { 1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 10} }, -- {19.5, { 1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 10} }, -- { 20, { 1, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 10} }, -- {20.5, { 1, 2, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 10} }, -- { 21, { 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 7, 8, 10} }, -- {21.5, { 1, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 7, 7, 8, 9} }, -- { 22, { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 9} }, -- {22.5, { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8} }, -- { 23, { 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 8} }, -- {23.5, { 1, 1, 1, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 8} }, -- { 24, { 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 8} }, -- {24.5, { 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 8} }, -- { 25, { 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 7} }, -- {25.5, { 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 7} }, -- { 26, { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 6} }, -- {26.5, { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 6} }, -- { 27, { 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6} }, -- {27.5, { 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 6} }, -- { 28, { 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 5} }, -- {28.5, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 5} }, -- { 29, { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4} }, -- {29.5, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4} }, -- { 30, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4} } --}; -- -- --const qp_table qp_table_422_8bpc_max = { -- { 6, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -- { 6.5, { 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13} }, -- { 7, { 3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12} }, -- { 7.5, { 3, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12} }, -- { 8, { 2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11} }, -- { 8.5, { 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11} }, -- { 9, { 1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10} }, -- { 9.5, { 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10} }, -- { 10, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -- {10.5, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9} }, -- { 11, { 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8} }, -- {11.5, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8} }, -- { 12, { 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7} }, -- {12.5, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7} }, -- { 13, { 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6} }, -- {13.5, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 6} }, -- { 14, { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5} }, -- {14.5, { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5} }, -- { 15, { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 5} }, -- {15.5, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} }, -- { 16, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} } --}; -- -diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c -index 7b294f637881a..b19d3aeb5962c 100644 ---- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c -+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c -@@ -23,266 +23,7 @@ - * Authors: AMD - * - */ --#include -- --#include "os_types.h" - #include "rc_calc.h" --#include "qp_tables.h" -- --#define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min) -- --#define MODE_SELECT(val444, val422, val420) \ -- (cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420)) -- -- --#define TABLE_CASE(mode, bpc, max) case (table_hash(mode, BPC_##bpc, max)): \ -- table = qp_table_##mode##_##bpc##bpc_##max; \ -- table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \ -- break -- -- --static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, -- enum max_min max_min, float bpp) --{ -- int mode = MODE_SELECT(444, 422, 420); -- int sel = table_hash(mode, bpc, max_min); -- int table_size = 0; -- int index; -- const struct qp_entry *table = 0L; -- -- // alias enum -- enum { min = DAL_MM_MIN, max = DAL_MM_MAX }; -- switch (sel) { -- TABLE_CASE(444, 8, max); -- TABLE_CASE(444, 8, min); -- TABLE_CASE(444, 10, max); -- TABLE_CASE(444, 10, min); -- TABLE_CASE(444, 12, max); -- TABLE_CASE(444, 12, min); -- TABLE_CASE(422, 8, max); -- TABLE_CASE(422, 8, min); -- TABLE_CASE(422, 10, max); -- TABLE_CASE(422, 10, min); -- TABLE_CASE(422, 12, max); -- TABLE_CASE(422, 12, min); -- TABLE_CASE(420, 8, max); -- TABLE_CASE(420, 8, min); -- TABLE_CASE(420, 10, max); -- TABLE_CASE(420, 10, min); -- TABLE_CASE(420, 12, max); -- TABLE_CASE(420, 12, min); -- } -- -- if (table == 0) -- return; -- -- index = (bpp - table[0].bpp) * 2; -- -- /* requested size is bigger than the table */ -- if (index >= table_size) { -- dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n"); -- return; -- } -- -- memcpy(qps, table[index].qps, sizeof(qp_set)); --} -- --static double dsc_roundf(double num) --{ -- if (num < 0.0) -- num = num - 0.5; -- else -- num = num + 0.5; -- -- return (int)(num); --} -- --static double dsc_ceil(double num) --{ -- double retval = (int)num; -- -- if (retval != num && num > 0) -- retval = num + 1; -- -- return (int)retval; --} -- --static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp) --{ -- int *p = ofs; -- -- if (mode == CM_444 || mode == CM_RGB) { -- *p++ = (bpp <= 6) ? (0) : ((((bpp >= 8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); -- *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0)))))); -- *p++ = (bpp <= 6) ? (-2) : ((((bpp >= 8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); -- *p++ = (bpp <= 6) ? (-4) : ((((bpp >= 8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); -- *p++ = (bpp <= 6) ? (-6) : ((((bpp >= 8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp - 6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0)))))); -- *p++ = (bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0)))); -- *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0)))); -- *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0)))); -- *p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0)))); -- *p++ = (bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0)))); -- *p++ = -10; -- *p++ = (bpp <= 6) ? (-12) : ((bpp >= 8) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2 / 2.0)))); -- *p++ = -12; -- *p++ = -12; -- *p++ = -12; -- } else if (mode == CM_422) { -- *p++ = (bpp <= 8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp - 8) * (8 / 2.0)))); -- *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp - 8) * (8 / 2.0)))); -- *p++ = (bpp <= 8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -- *p++ = (bpp <= 8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -- *p++ = (bpp <= 8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -- *p++ = (bpp <= 8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -- *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp - 8) * (6 / 2.0)))); -- *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp - 8) * (4 / 2.0)))); -- *p++ = (bpp <= 8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp - 8) * (2 / 2.0)))); -- *p++ = (bpp <= 8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp - 8) * (2 / 2.0)))); -- *p++ = -10; -- *p++ = (bpp <= 6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp - 6) * (2.0 / 1)))); -- *p++ = -12; -- *p++ = -12; -- *p++ = -12; -- } else { -- *p++ = (bpp <= 6) ? (2) : ((bpp >= 8) ? (10) : (2 + dsc_roundf((bpp - 6) * (8 / 2.0)))); -- *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (8) : (0 + dsc_roundf((bpp - 6) * (8 / 2.0)))); -- *p++ = (bpp <= 6) ? (0) : ((bpp >= 8) ? (6) : (0 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -- *p++ = (bpp <= 6) ? (-2) : ((bpp >= 8) ? (4) : (-2 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -- *p++ = (bpp <= 6) ? (-4) : ((bpp >= 8) ? (2) : (-4 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -- *p++ = (bpp <= 6) ? (-6) : ((bpp >= 8) ? (0) : (-6 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -- *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-2) : (-8 + dsc_roundf((bpp - 6) * (6 / 2.0)))); -- *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-4) : (-8 + dsc_roundf((bpp - 6) * (4 / 2.0)))); -- *p++ = (bpp <= 6) ? (-8) : ((bpp >= 8) ? (-6) : (-8 + dsc_roundf((bpp - 6) * (2 / 2.0)))); -- *p++ = (bpp <= 6) ? (-10) : ((bpp >= 8) ? (-8) : (-10 + dsc_roundf((bpp - 6) * (2 / 2.0)))); -- *p++ = -10; -- *p++ = (bpp <= 4) ? (-12) : ((bpp >= 5) ? (-10) : (-12 + dsc_roundf((bpp - 4) * (2 / 1.0)))); -- *p++ = -12; -- *p++ = -12; -- *p++ = -12; -- } --} -- --static int median3(int a, int b, int c) --{ -- if (a > b) -- swap(a, b); -- if (b > c) -- swap(b, c); -- if (a > b) -- swap(b, c); -- -- return b; --} -- --static void _do_calc_rc_params(struct rc_params *rc, enum colour_mode cm, -- enum bits_per_comp bpc, u16 drm_bpp, -- bool is_navite_422_or_420, -- int slice_width, int slice_height, -- int minor_version) --{ -- float bpp; -- float bpp_group; -- float initial_xmit_delay_factor; -- int padding_pixels; -- int i; -- -- bpp = ((float)drm_bpp / 16.0); -- /* in native_422 or native_420 modes, the bits_per_pixel is double the -- * target bpp (the latter is what calc_rc_params expects) -- */ -- if (is_navite_422_or_420) -- bpp /= 2.0; -- -- rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -- rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -- -- bpp_group = MODE_SELECT(bpp, bpp * 2.0, bpp * 2.0); -- -- switch (cm) { -- case CM_420: -- rc->initial_fullness_offset = (bpp >= 6) ? (2048) : ((bpp <= 4) ? (6144) : ((((bpp > 4) && (bpp <= 5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp - 5) * (3584))))); -- rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group))); -- rc->second_line_bpg_offset = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group))); -- break; -- case CM_422: -- rc->initial_fullness_offset = (bpp >= 8) ? (2048) : ((bpp <= 7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584)))); -- rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group))); -- rc->second_line_bpg_offset = 0; -- break; -- case CM_444: -- case CM_RGB: -- rc->initial_fullness_offset = (bpp >= 12) ? (2048) : ((bpp <= 8) ? (6144) : ((((bpp > 8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2))))); -- rc->first_line_bpg_offset = median3(0, (12 + (int) (0.09 * min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group))); -- rc->second_line_bpg_offset = 0; -- break; -- } -- -- initial_xmit_delay_factor = (cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0; -- rc->initial_xmit_delay = dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor); -- -- if (cm == CM_422 || cm == CM_420) -- slice_width /= 2; -- -- padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0; -- if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) { -- if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1) -- rc->initial_xmit_delay++; -- } -- -- rc->flatness_min_qp = ((bpc == BPC_8) ? (3) : ((bpc == BPC_10) ? (7) : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -- rc->flatness_max_qp = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); -- rc->flatness_det_thresh = 2 << (bpc - 8); -- -- get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp); -- get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp); -- if (cm == CM_444 && minor_version == 1) { -- for (i = 0; i < QP_SET_SIZE; ++i) { -- rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0; -- rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0; -- } -- } -- get_ofs_set(rc->ofs, cm, bpp); -- -- /* fixed parameters */ -- rc->rc_model_size = 8192; -- rc->rc_edge_factor = 6; -- rc->rc_tgt_offset_hi = 3; -- rc->rc_tgt_offset_lo = 3; -- -- rc->rc_buf_thresh[0] = 896; -- rc->rc_buf_thresh[1] = 1792; -- rc->rc_buf_thresh[2] = 2688; -- rc->rc_buf_thresh[3] = 3584; -- rc->rc_buf_thresh[4] = 4480; -- rc->rc_buf_thresh[5] = 5376; -- rc->rc_buf_thresh[6] = 6272; -- rc->rc_buf_thresh[7] = 6720; -- rc->rc_buf_thresh[8] = 7168; -- rc->rc_buf_thresh[9] = 7616; -- rc->rc_buf_thresh[10] = 7744; -- rc->rc_buf_thresh[11] = 7872; -- rc->rc_buf_thresh[12] = 8000; -- rc->rc_buf_thresh[13] = 8064; --} -- --static u32 _do_bytes_per_pixel_calc(int slice_width, u16 drm_bpp, -- bool is_navite_422_or_420) --{ -- float bpp; -- u32 bytes_per_pixel; -- double d_bytes_per_pixel; -- -- bpp = ((float)drm_bpp / 16.0); -- d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; -- // TODO: Make sure the formula for calculating this is precise (ceiling -- // vs. floor, and at what point they should be applied) -- if (is_navite_422_or_420) -- d_bytes_per_pixel /= 2; -- -- bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000); -- -- return bytes_per_pixel; --} - - /** - * calc_rc_params - reads the user's cmdline mode -diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h -index 262f06afcbf95..c2340e001b578 100644 ---- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h -+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h -@@ -27,55 +27,7 @@ - #ifndef __RC_CALC_H__ - #define __RC_CALC_H__ - -- --#define QP_SET_SIZE 15 -- --typedef int qp_set[QP_SET_SIZE]; -- --struct rc_params { -- int rc_quant_incr_limit0; -- int rc_quant_incr_limit1; -- int initial_fullness_offset; -- int initial_xmit_delay; -- int first_line_bpg_offset; -- int second_line_bpg_offset; -- int flatness_min_qp; -- int flatness_max_qp; -- int flatness_det_thresh; -- qp_set qp_min; -- qp_set qp_max; -- qp_set ofs; -- int rc_model_size; -- int rc_edge_factor; -- int rc_tgt_offset_hi; -- int rc_tgt_offset_lo; -- int rc_buf_thresh[QP_SET_SIZE - 1]; --}; -- --enum colour_mode { -- CM_RGB, /* 444 RGB */ -- CM_444, /* 444 YUV or simple 422 */ -- CM_422, /* native 422 */ -- CM_420 /* native 420 */ --}; -- --enum bits_per_comp { -- BPC_8 = 8, -- BPC_10 = 10, -- BPC_12 = 12 --}; -- --enum max_min { -- DAL_MM_MIN = 0, -- DAL_MM_MAX = 1 --}; -- --struct qp_entry { -- float bpp; -- const qp_set qps; --}; -- --typedef struct qp_entry qp_table[]; -+#include "dml/dsc/rc_calc_fpu.h" - - void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps); - u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps); -diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c -index ef830aded5b1c..1e19dd674e5a2 100644 ---- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c -+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c -@@ -22,7 +22,6 @@ - * Authors: AMD - * - */ --#include "os_types.h" - #include - #include "dscc_types.h" - #include "rc_calc.h" -diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h -index 571fcf23cea92..a3a9ea077f505 100644 ---- a/drivers/gpu/drm/amd/display/include/logger_types.h -+++ b/drivers/gpu/drm/amd/display/include/logger_types.h -@@ -72,6 +72,9 @@ - #define DC_LOG_DSC(...) DRM_DEBUG_KMS(__VA_ARGS__) - #define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__) - #define DC_LOG_DWB(...) DRM_DEBUG_KMS(__VA_ARGS__) -+#if defined(CONFIG_DRM_AMD_DC_DCN) -+#define DC_LOG_DP2(...) DRM_DEBUG_KMS(__VA_ARGS__) -+#endif - - struct dal_logger; - -diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h -index 257f280d3d53f..bd077ea224a40 100644 ---- a/drivers/gpu/drm/amd/include/amd_shared.h -+++ b/drivers/gpu/drm/amd/include/amd_shared.h -@@ -98,7 +98,8 @@ enum amd_ip_block_type { - AMD_IP_BLOCK_TYPE_ACP, - AMD_IP_BLOCK_TYPE_VCN, - AMD_IP_BLOCK_TYPE_MES, -- AMD_IP_BLOCK_TYPE_JPEG -+ AMD_IP_BLOCK_TYPE_JPEG, -+ AMD_IP_BLOCK_TYPE_NUM, - }; - - enum amd_clockgating_state { -diff --git a/drivers/gpu/drm/amd/include/discovery.h b/drivers/gpu/drm/amd/include/discovery.h -index 7ec4331e67f26..a486769b66c6a 100644 ---- a/drivers/gpu/drm/amd/include/discovery.h -+++ b/drivers/gpu/drm/amd/include/discovery.h -@@ -143,6 +143,55 @@ struct gc_info_v1_0 { - uint32_t gc_num_gl2a; - }; - -+struct gc_info_v1_1 { -+ struct gpu_info_header header; -+ -+ uint32_t gc_num_se; -+ uint32_t gc_num_wgp0_per_sa; -+ uint32_t gc_num_wgp1_per_sa; -+ uint32_t gc_num_rb_per_se; -+ uint32_t gc_num_gl2c; -+ uint32_t gc_num_gprs; -+ uint32_t gc_num_max_gs_thds; -+ uint32_t gc_gs_table_depth; -+ uint32_t gc_gsprim_buff_depth; -+ uint32_t gc_parameter_cache_depth; -+ uint32_t gc_double_offchip_lds_buffer; -+ uint32_t gc_wave_size; -+ uint32_t gc_max_waves_per_simd; -+ uint32_t gc_max_scratch_slots_per_cu; -+ uint32_t gc_lds_size; -+ uint32_t gc_num_sc_per_se; -+ uint32_t gc_num_sa_per_se; -+ uint32_t gc_num_packer_per_sc; -+ uint32_t gc_num_gl2a; -+ uint32_t gc_num_tcp_per_sa; -+ uint32_t gc_num_sdp_interface; -+ uint32_t gc_num_tcps; -+}; -+ -+struct gc_info_v2_0 { -+ struct gpu_info_header header; -+ -+ uint32_t gc_num_se; -+ uint32_t gc_num_cu_per_sh; -+ uint32_t gc_num_sh_per_se; -+ uint32_t gc_num_rb_per_se; -+ uint32_t gc_num_tccs; -+ uint32_t gc_num_gprs; -+ uint32_t gc_num_max_gs_thds; -+ uint32_t gc_gs_table_depth; -+ uint32_t gc_gsprim_buff_depth; -+ uint32_t gc_parameter_cache_depth; -+ uint32_t gc_double_offchip_lds_buffer; -+ uint32_t gc_wave_size; -+ uint32_t gc_max_waves_per_simd; -+ uint32_t gc_max_scratch_slots_per_cu; -+ uint32_t gc_lds_size; -+ uint32_t gc_num_sc_per_se; -+ uint32_t gc_num_packer_per_sc; -+}; -+ - typedef struct harvest_info_header { - uint32_t signature; /* Table Signature */ - uint32_t version; /* Table Version */ -diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c -index 03581d5b18360..08362d506534b 100644 ---- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c -+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c -@@ -927,6 +927,13 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block - { - int ret = 0; - const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; -+ enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON; -+ -+ if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) { -+ dev_dbg(adev->dev, "IP block%d already in the target %s state!", -+ block_type, gate ? "gate" : "ungate"); -+ return 0; -+ } - - switch (block_type) { - case AMD_IP_BLOCK_TYPE_UVD: -@@ -979,6 +986,9 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block - break; - } - -+ if (!ret) -+ atomic_set(&adev->pm.pwr_state[block_type], pwr_state); -+ - return ret; - } - -diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -index 249cb0aeb5ae4..640db5020ccc3 100644 ---- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c -+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -@@ -2117,6 +2117,12 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ - } - } - -+ /* setting should not be allowed from VF */ -+ if (amdgpu_sriov_vf(adev)) { -+ dev_attr->attr.mode &= ~S_IWUGO; -+ dev_attr->store = NULL; -+ } -+ - #undef DEVICE_ATTR_IS - - return 0; -@@ -3439,8 +3445,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, - attr == &sensor_dev_attr_power2_cap_min.dev_attr.attr || - attr == &sensor_dev_attr_power2_cap.dev_attr.attr || - attr == &sensor_dev_attr_power2_cap_default.dev_attr.attr || -- attr == &sensor_dev_attr_power2_label.dev_attr.attr || -- attr == &sensor_dev_attr_power1_label.dev_attr.attr)) -+ attr == &sensor_dev_attr_power2_label.dev_attr.attr)) - return 0; - - return effective_mode; -diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h -index 98f1b3d8c1d59..16e3f72d31b9f 100644 ---- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h -+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h -@@ -417,6 +417,12 @@ struct amdgpu_dpm { - enum amd_dpm_forced_level forced_level; - }; - -+enum ip_power_state { -+ POWER_STATE_UNKNOWN, -+ POWER_STATE_ON, -+ POWER_STATE_OFF, -+}; -+ - struct amdgpu_pm { - struct mutex mutex; - u32 current_sclk; -@@ -452,6 +458,8 @@ struct amdgpu_pm { - struct i2c_adapter smu_i2c; - struct mutex smu_i2c_mutex; - struct list_head pm_attr_list; -+ -+ atomic_t pwr_state[AMD_IP_BLOCK_TYPE_NUM]; - }; - - #define R600_SSTU_DFLT 0 -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c -index 1de3ae77e03ed..1f406f21b452f 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c -@@ -1036,13 +1036,13 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, - else - i = 1; - -- size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", -+ size += sprintf(buf + size, "0: %uMhz %s\n", - data->gfx_min_freq_limit/100, - i == 0 ? "*" : ""); -- size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", -+ size += sprintf(buf + size, "1: %uMhz %s\n", - i == 1 ? now : SMU10_UMD_PSTATE_GFXCLK, - i == 1 ? "*" : ""); -- size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", -+ size += sprintf(buf + size, "2: %uMhz %s\n", - data->gfx_max_freq_limit/100, - i == 2 ? "*" : ""); - break; -@@ -1050,7 +1050,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); - - for (i = 0; i < mclk_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, - mclk_table->entries[i].clk / 100, - ((mclk_table->entries[i].clk / 100) -@@ -1065,10 +1065,10 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, - if (ret) - return ret; - -- size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); -- size += sysfs_emit_at(buf, size, "0: %10uMhz\n", -+ size += sprintf(buf + size, "%s:\n", "OD_SCLK"); -+ size += sprintf(buf + size, "0: %10uMhz\n", - (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq); -- size += sysfs_emit_at(buf, size, "1: %10uMhz\n", -+ size += sprintf(buf + size, "1: %10uMhz\n", - (data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq); - } - break; -@@ -1081,8 +1081,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, - if (ret) - return ret; - -- size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); -- size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", -+ size += sprintf(buf + size, "%s:\n", "OD_RANGE"); -+ size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", - min_freq, max_freq); - } - break; -@@ -1456,6 +1456,8 @@ static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) - if (!buf) - return -EINVAL; - -+ phm_get_sysfs_buf(&buf, &size); -+ - size += sysfs_emit_at(buf, size, "%s %16s %s %s %s %s\n",title[0], - title[1], title[2], title[3], title[4], title[5]); - -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -index e7803ce8f67aa..611969bf45207 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -@@ -4926,7 +4926,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, - now = i; - - for (i = 0; i < sclk_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, sclk_table->dpm_levels[i].value / 100, - (i == now) ? "*" : ""); - break; -@@ -4941,7 +4941,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, - now = i; - - for (i = 0; i < mclk_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, mclk_table->dpm_levels[i].value / 100, - (i == now) ? "*" : ""); - break; -@@ -4955,7 +4955,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, - now = i; - - for (i = 0; i < pcie_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %s %s\n", i, -+ size += sprintf(buf + size, "%d: %s %s\n", i, - (pcie_table->dpm_levels[i].value == 0) ? "2.5GT/s, x8" : - (pcie_table->dpm_levels[i].value == 1) ? "5.0GT/s, x16" : - (pcie_table->dpm_levels[i].value == 2) ? "8.0GT/s, x16" : "", -@@ -4963,32 +4963,32 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, - break; - case OD_SCLK: - if (hwmgr->od_enabled) { -- size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); -+ size += sprintf(buf + size, "%s:\n", "OD_SCLK"); - for (i = 0; i < odn_sclk_table->num_of_pl; i++) -- size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n", -+ size += sprintf(buf + size, "%d: %10uMHz %10umV\n", - i, odn_sclk_table->entries[i].clock/100, - odn_sclk_table->entries[i].vddc); - } - break; - case OD_MCLK: - if (hwmgr->od_enabled) { -- size = sysfs_emit(buf, "%s:\n", "OD_MCLK"); -+ size += sprintf(buf + size, "%s:\n", "OD_MCLK"); - for (i = 0; i < odn_mclk_table->num_of_pl; i++) -- size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n", -+ size += sprintf(buf + size, "%d: %10uMHz %10umV\n", - i, odn_mclk_table->entries[i].clock/100, - odn_mclk_table->entries[i].vddc); - } - break; - case OD_RANGE: - if (hwmgr->od_enabled) { -- size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); -- size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", -+ size += sprintf(buf + size, "%s:\n", "OD_RANGE"); -+ size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", - data->golden_dpm_table.sclk_table.dpm_levels[0].value/100, - hwmgr->platform_descriptor.overdriveLimit.engineClock/100); -- size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n", -+ size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n", - data->golden_dpm_table.mclk_table.dpm_levels[0].value/100, - hwmgr->platform_descriptor.overdriveLimit.memoryClock/100); -- size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n", -+ size += sprintf(buf + size, "VDDC: %7umV %11umV\n", - data->odn_dpm_table.min_vddc, - data->odn_dpm_table.max_vddc); - } -@@ -5518,6 +5518,8 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) - if (!buf) - return -EINVAL; - -+ phm_get_sysfs_buf(&buf, &size); -+ - size += sysfs_emit_at(buf, size, "%s %16s %16s %16s %16s %16s %16s %16s\n", - title[0], title[1], title[2], title[3], - title[4], title[5], title[6], title[7]); -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -index b94a77e4e7147..03bf8f0692228 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -@@ -1559,7 +1559,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr, - CURR_SCLK_INDEX); - - for (i = 0; i < sclk_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, sclk_table->entries[i].clk / 100, - (i == now) ? "*" : ""); - break; -@@ -1571,7 +1571,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr, - CURR_MCLK_INDEX); - - for (i = SMU8_NUM_NBPMEMORYCLOCK; i > 0; i--) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - SMU8_NUM_NBPMEMORYCLOCK-i, data->sys_info.nbp_memory_clock[i-1] / 100, - (SMU8_NUM_NBPMEMORYCLOCK-i == now) ? "*" : ""); - break; -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h -index ad33983a8064e..2a75da1e9f035 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h -@@ -109,6 +109,19 @@ int phm_irq_process(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, - struct amdgpu_iv_entry *entry); - -+/* -+ * Helper function to make sysfs_emit_at() happy. Align buf to -+ * the current page boundary and record the offset. -+ */ -+static inline void phm_get_sysfs_buf(char **buf, int *offset) -+{ -+ if (!*buf || !offset) -+ return; -+ -+ *offset = offset_in_page(*buf); -+ *buf -= *offset; -+} -+ - int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr); - - void *smu_atom_get_data_table(void *dev, uint32_t table, uint16_t *size, -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -index c152a61ddd2c9..e6336654c5655 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -@@ -4548,6 +4548,8 @@ static int vega10_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) - int ret = 0; - int size = 0; - -+ phm_get_sysfs_buf(&buf, &size); -+ - ret = vega10_get_enabled_smc_features(hwmgr, &features_enabled); - PP_ASSERT_WITH_CODE(!ret, - "[EnableAllSmuFeatures] Failed to get enabled smc features!", -@@ -4650,7 +4652,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, - else - count = sclk_table->count; - for (i = 0; i < count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, sclk_table->dpm_levels[i].value / 100, - (i == now) ? "*" : ""); - break; -@@ -4661,7 +4663,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); - - for (i = 0; i < mclk_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, mclk_table->dpm_levels[i].value / 100, - (i == now) ? "*" : ""); - break; -@@ -4672,7 +4674,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); - - for (i = 0; i < soc_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, soc_table->dpm_levels[i].value / 100, - (i == now) ? "*" : ""); - break; -@@ -4684,7 +4686,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, - PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now); - - for (i = 0; i < dcef_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, dcef_table->dpm_levels[i].value / 100, - (dcef_table->dpm_levels[i].value / 100 == now) ? - "*" : ""); -@@ -4698,7 +4700,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, - gen_speed = pptable->PcieGenSpeed[i]; - lane_width = pptable->PcieLaneCount[i]; - -- size += sysfs_emit_at(buf, size, "%d: %s %s %s\n", i, -+ size += sprintf(buf + size, "%d: %s %s %s\n", i, - (gen_speed == 0) ? "2.5GT/s," : - (gen_speed == 1) ? "5.0GT/s," : - (gen_speed == 2) ? "8.0GT/s," : -@@ -4717,34 +4719,34 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, - - case OD_SCLK: - if (hwmgr->od_enabled) { -- size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); -+ size += sprintf(buf + size, "%s:\n", "OD_SCLK"); - podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk; - for (i = 0; i < podn_vdd_dep->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n", -+ size += sprintf(buf + size, "%d: %10uMhz %10umV\n", - i, podn_vdd_dep->entries[i].clk / 100, - podn_vdd_dep->entries[i].vddc); - } - break; - case OD_MCLK: - if (hwmgr->od_enabled) { -- size = sysfs_emit(buf, "%s:\n", "OD_MCLK"); -+ size += sprintf(buf + size, "%s:\n", "OD_MCLK"); - podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk; - for (i = 0; i < podn_vdd_dep->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n", -+ size += sprintf(buf + size, "%d: %10uMhz %10umV\n", - i, podn_vdd_dep->entries[i].clk/100, - podn_vdd_dep->entries[i].vddc); - } - break; - case OD_RANGE: - if (hwmgr->od_enabled) { -- size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); -- size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", -+ size += sprintf(buf + size, "%s:\n", "OD_RANGE"); -+ size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", - data->golden_dpm_table.gfx_table.dpm_levels[0].value/100, - hwmgr->platform_descriptor.overdriveLimit.engineClock/100); -- size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n", -+ size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n", - data->golden_dpm_table.mem_table.dpm_levels[0].value/100, - hwmgr->platform_descriptor.overdriveLimit.memoryClock/100); -- size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n", -+ size += sprintf(buf + size, "VDDC: %7umV %11umV\n", - data->odn_dpm_table.min_vddc, - data->odn_dpm_table.max_vddc); - } -@@ -5112,6 +5114,8 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) - if (!buf) - return -EINVAL; - -+ phm_get_sysfs_buf(&buf, &size); -+ - size += sysfs_emit_at(buf, size, "%s %16s %s %s %s %s\n",title[0], - title[1], title[2], title[3], title[4], title[5]); - -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c -index 8558718e15a8f..a2f4d6773d458 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c -@@ -2141,6 +2141,8 @@ static int vega12_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) - int ret = 0; - int size = 0; - -+ phm_get_sysfs_buf(&buf, &size); -+ - ret = vega12_get_enabled_smc_features(hwmgr, &features_enabled); - PP_ASSERT_WITH_CODE(!ret, - "[EnableAllSmuFeatures] Failed to get enabled smc features!", -@@ -2256,7 +2258,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, - "Attempt to get gfx clk levels Failed!", - return -1); - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : ""); - break; -@@ -2272,7 +2274,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, - "Attempt to get memory clk levels Failed!", - return -1); - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : ""); - break; -@@ -2290,7 +2292,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, - "Attempt to get soc clk levels Failed!", - return -1); - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); - break; -@@ -2308,7 +2310,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, - "Attempt to get dcef clk levels Failed!", - return -1); - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); - break; -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c -index 0cf39c1244b1c..85d55ab4e369f 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c -@@ -3238,6 +3238,8 @@ static int vega20_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) - int ret = 0; - int size = 0; - -+ phm_get_sysfs_buf(&buf, &size); -+ - ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled); - PP_ASSERT_WITH_CODE(!ret, - "[EnableAllSmuFeatures] Failed to get enabled smc features!", -@@ -3372,13 +3374,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - return ret); - - if (vega20_get_sclks(hwmgr, &clocks)) { -- size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", -+ size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", - now / 100); - break; - } - - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); - break; -@@ -3390,13 +3392,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - return ret); - - if (vega20_get_memclocks(hwmgr, &clocks)) { -- size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", -+ size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", - now / 100); - break; - } - - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); - break; -@@ -3408,13 +3410,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - return ret); - - if (vega20_get_socclocks(hwmgr, &clocks)) { -- size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", -+ size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", - now / 100); - break; - } - - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); - break; -@@ -3426,7 +3428,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - return ret); - - for (i = 0; i < fclk_dpm_table->count; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, fclk_dpm_table->dpm_levels[i].value, - fclk_dpm_table->dpm_levels[i].value == (now / 100) ? "*" : ""); - break; -@@ -3438,13 +3440,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - return ret); - - if (vega20_get_dcefclocks(hwmgr, &clocks)) { -- size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", -+ size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", - now / 100); - break; - } - - for (i = 0; i < clocks.num_levels; i++) -- size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", -+ size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); - break; -@@ -3458,7 +3460,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - gen_speed = pptable->PcieGenSpeed[i]; - lane_width = pptable->PcieLaneCount[i]; - -- size += sysfs_emit_at(buf, size, "%d: %s %s %dMhz %s\n", i, -+ size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, - (gen_speed == 0) ? "2.5GT/s," : - (gen_speed == 1) ? "5.0GT/s," : - (gen_speed == 2) ? "8.0GT/s," : -@@ -3479,18 +3481,18 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - case OD_SCLK: - if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id && - od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) { -- size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); -- size += sysfs_emit_at(buf, size, "0: %10uMhz\n", -+ size += sprintf(buf + size, "%s:\n", "OD_SCLK"); -+ size += sprintf(buf + size, "0: %10uMhz\n", - od_table->GfxclkFmin); -- size += sysfs_emit_at(buf, size, "1: %10uMhz\n", -+ size += sprintf(buf + size, "1: %10uMhz\n", - od_table->GfxclkFmax); - } - break; - - case OD_MCLK: - if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { -- size = sysfs_emit(buf, "%s:\n", "OD_MCLK"); -- size += sysfs_emit_at(buf, size, "1: %10uMhz\n", -+ size += sprintf(buf + size, "%s:\n", "OD_MCLK"); -+ size += sprintf(buf + size, "1: %10uMhz\n", - od_table->UclkFmax); - } - -@@ -3503,14 +3505,14 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id && - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id && - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) { -- size = sysfs_emit(buf, "%s:\n", "OD_VDDC_CURVE"); -- size += sysfs_emit_at(buf, size, "0: %10uMhz %10dmV\n", -+ size += sprintf(buf + size, "%s:\n", "OD_VDDC_CURVE"); -+ size += sprintf(buf + size, "0: %10uMhz %10dmV\n", - od_table->GfxclkFreq1, - od_table->GfxclkVolt1 / VOLTAGE_SCALE); -- size += sysfs_emit_at(buf, size, "1: %10uMhz %10dmV\n", -+ size += sprintf(buf + size, "1: %10uMhz %10dmV\n", - od_table->GfxclkFreq2, - od_table->GfxclkVolt2 / VOLTAGE_SCALE); -- size += sysfs_emit_at(buf, size, "2: %10uMhz %10dmV\n", -+ size += sprintf(buf + size, "2: %10uMhz %10dmV\n", - od_table->GfxclkFreq3, - od_table->GfxclkVolt3 / VOLTAGE_SCALE); - } -@@ -3518,17 +3520,17 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - break; - - case OD_RANGE: -- size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); -+ size += sprintf(buf + size, "%s:\n", "OD_RANGE"); - - if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id && - od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) { -- size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", -+ size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n", - od8_settings[OD8_SETTING_GFXCLK_FMIN].min_value, - od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value); - } - - if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { -- size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", -+ size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", - od8_settings[OD8_SETTING_UCLK_FMAX].min_value, - od8_settings[OD8_SETTING_UCLK_FMAX].max_value); - } -@@ -3539,22 +3541,22 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id && - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id && - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) { -- size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n", -+ size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n", - od8_settings[OD8_SETTING_GFXCLK_FREQ1].min_value, - od8_settings[OD8_SETTING_GFXCLK_FREQ1].max_value); -- size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n", -+ size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n", - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].min_value, - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].max_value); -- size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n", -+ size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n", - od8_settings[OD8_SETTING_GFXCLK_FREQ2].min_value, - od8_settings[OD8_SETTING_GFXCLK_FREQ2].max_value); -- size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n", -+ size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n", - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].min_value, - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].max_value); -- size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n", -+ size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n", - od8_settings[OD8_SETTING_GFXCLK_FREQ3].min_value, - od8_settings[OD8_SETTING_GFXCLK_FREQ3].max_value); -- size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n", -+ size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n", - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].min_value, - od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].max_value); - } -@@ -4003,6 +4005,8 @@ static int vega20_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) - if (!buf) - return -EINVAL; - -+ phm_get_sysfs_buf(&buf, &size); -+ - size += sysfs_emit_at(buf, size, "%16s %s %s %s %s %s %s %s %s %s %s\n", - title[0], title[1], title[2], title[3], title[4], title[5], - title[6], title[7], title[8], title[9], title[10]); -diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -index 04863a7971155..6dc83cfad9d84 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -@@ -1386,8 +1386,14 @@ static int smu_disable_dpms(struct smu_context *smu) - { - struct amdgpu_device *adev = smu->adev; - int ret = 0; -+ /* -+ * TODO: (adev->in_suspend && !adev->in_s0ix) is added to pair -+ * the workaround which always reset the asic in suspend. -+ * It's likely that workaround will be dropped in the future. -+ * Then the change here should be dropped together. -+ */ - bool use_baco = !smu->is_apu && -- ((amdgpu_in_reset(adev) && -+ (((amdgpu_in_reset(adev) || (adev->in_suspend && !adev->in_s0ix)) && - (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || - ((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev))); - -@@ -1536,9 +1542,7 @@ static int smu_suspend(void *handle) - - smu->watermarks_bitmap &= ~(WATERMARKS_LOADED); - -- /* skip CGPG when in S0ix */ -- if (smu->is_apu && !adev->in_s0ix) -- smu_set_gfx_cgpg(&adev->smu, false); -+ smu_set_gfx_cgpg(&adev->smu, false); - - return 0; - } -@@ -1569,8 +1573,7 @@ static int smu_resume(void *handle) - return ret; - } - -- if (smu->is_apu) -- smu_set_gfx_cgpg(&adev->smu, true); -+ smu_set_gfx_cgpg(&adev->smu, true); - - smu->disable_uclk_switch = 0; - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -index b1ad451af06bd..dfba0bc732073 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -@@ -1265,7 +1265,7 @@ static int navi10_print_clk_levels(struct smu_context *smu, - enum smu_clk_type clk_type, char *buf) - { - uint16_t *curve_settings; -- int i, size = 0, ret = 0; -+ int i, levels, size = 0, ret = 0; - uint32_t cur_value = 0, value = 0, count = 0; - uint32_t freq_values[3] = {0}; - uint32_t mark_index = 0; -@@ -1319,14 +1319,17 @@ static int navi10_print_clk_levels(struct smu_context *smu, - freq_values[1] = cur_value; - mark_index = cur_value == freq_values[0] ? 0 : - cur_value == freq_values[2] ? 2 : 1; -- if (mark_index != 1) -- freq_values[1] = (freq_values[0] + freq_values[2]) / 2; - -- for (i = 0; i < 3; i++) { -+ levels = 3; -+ if (mark_index != 1) { -+ levels = 2; -+ freq_values[1] = freq_values[2]; -+ } -+ -+ for (i = 0; i < levels; i++) { - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, freq_values[i], - i == mark_index ? "*" : ""); - } -- - } - break; - case SMU_PCIE: -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -index ca57221e39629..574a9d7f7a5e7 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -@@ -418,6 +418,36 @@ static int sienna_cichlid_store_powerplay_table(struct smu_context *smu) - return 0; - } - -+static int sienna_cichlid_patch_pptable_quirk(struct smu_context *smu) -+{ -+ struct amdgpu_device *adev = smu->adev; -+ uint32_t *board_reserved; -+ uint16_t *freq_table_gfx; -+ uint32_t i; -+ -+ /* Fix some OEM SKU specific stability issues */ -+ GET_PPTABLE_MEMBER(BoardReserved, &board_reserved); -+ if ((adev->pdev->device == 0x73DF) && -+ (adev->pdev->revision == 0XC3) && -+ (adev->pdev->subsystem_device == 0x16C2) && -+ (adev->pdev->subsystem_vendor == 0x1043)) -+ board_reserved[0] = 1387; -+ -+ GET_PPTABLE_MEMBER(FreqTableGfx, &freq_table_gfx); -+ if ((adev->pdev->device == 0x73DF) && -+ (adev->pdev->revision == 0XC3) && -+ ((adev->pdev->subsystem_device == 0x16C2) || -+ (adev->pdev->subsystem_device == 0x133C)) && -+ (adev->pdev->subsystem_vendor == 0x1043)) { -+ for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++) { -+ if (freq_table_gfx[i] > 2500) -+ freq_table_gfx[i] = 2500; -+ } -+ } -+ -+ return 0; -+} -+ - static int sienna_cichlid_setup_pptable(struct smu_context *smu) - { - int ret = 0; -@@ -438,7 +468,7 @@ static int sienna_cichlid_setup_pptable(struct smu_context *smu) - if (ret) - return ret; - -- return ret; -+ return sienna_cichlid_patch_pptable_quirk(smu); - } - - static int sienna_cichlid_tables_init(struct smu_context *smu) -@@ -1278,21 +1308,37 @@ static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu) - &dpm_context->dpm_tables.soc_table; - struct smu_umd_pstate_table *pstate_table = - &smu->pstate_table; -+ struct amdgpu_device *adev = smu->adev; - - pstate_table->gfxclk_pstate.min = gfx_table->min; - pstate_table->gfxclk_pstate.peak = gfx_table->max; -- if (gfx_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK) -- pstate_table->gfxclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK; - - pstate_table->uclk_pstate.min = mem_table->min; - pstate_table->uclk_pstate.peak = mem_table->max; -- if (mem_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK) -- pstate_table->uclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK; - - pstate_table->socclk_pstate.min = soc_table->min; - pstate_table->socclk_pstate.peak = soc_table->max; -- if (soc_table->max >= SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK) -+ -+ switch (adev->asic_type) { -+ case CHIP_SIENNA_CICHLID: -+ case CHIP_NAVY_FLOUNDER: -+ pstate_table->gfxclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK; -+ pstate_table->uclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK; - pstate_table->socclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK; -+ break; -+ case CHIP_DIMGREY_CAVEFISH: -+ pstate_table->gfxclk_pstate.standard = DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_GFXCLK; -+ pstate_table->uclk_pstate.standard = DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_MEMCLK; -+ pstate_table->socclk_pstate.standard = DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_SOCCLK; -+ break; -+ case CHIP_BEIGE_GOBY: -+ pstate_table->gfxclk_pstate.standard = BEIGE_GOBY_UMD_PSTATE_PROFILING_GFXCLK; -+ pstate_table->uclk_pstate.standard = BEIGE_GOBY_UMD_PSTATE_PROFILING_MEMCLK; -+ pstate_table->socclk_pstate.standard = BEIGE_GOBY_UMD_PSTATE_PROFILING_SOCCLK; -+ break; -+ default: -+ break; -+ } - - return 0; - } -@@ -3728,14 +3774,14 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, - - static int sienna_cichlid_enable_mgpu_fan_boost(struct smu_context *smu) - { -- struct smu_table_context *table_context = &smu->smu_table; -- PPTable_t *smc_pptable = table_context->driver_pptable; -+ uint16_t *mgpu_fan_boost_limit_rpm; - -+ GET_PPTABLE_MEMBER(MGpuFanBoostLimitRpm, &mgpu_fan_boost_limit_rpm); - /* - * Skip the MGpuFanBoost setting for those ASICs - * which do not support it - */ -- if (!smc_pptable->MGpuFanBoostLimitRpm) -+ if (*mgpu_fan_boost_limit_rpm == 0) - return 0; - - return smu_cmn_send_smc_msg_with_param(smu, -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h -index 38cd0ece24f6b..42f705c7a36f8 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h -@@ -33,6 +33,14 @@ typedef enum { - #define SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK 960 - #define SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK 1000 - -+#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_GFXCLK 1950 -+#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_SOCCLK 960 -+#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_MEMCLK 676 -+ -+#define BEIGE_GOBY_UMD_PSTATE_PROFILING_GFXCLK 2200 -+#define BEIGE_GOBY_UMD_PSTATE_PROFILING_SOCCLK 960 -+#define BEIGE_GOBY_UMD_PSTATE_PROFILING_MEMCLK 1000 -+ - extern void sienna_cichlid_set_ppt_funcs(struct smu_context *smu); - - #endif -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c -index f6ef0ce6e9e2c..a9dceef4a7011 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c -@@ -1386,52 +1386,38 @@ static int vangogh_set_performance_level(struct smu_context *smu, - uint32_t soc_mask, mclk_mask, fclk_mask; - uint32_t vclk_mask = 0, dclk_mask = 0; - -+ smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -+ smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -+ - switch (level) { - case AMD_DPM_FORCED_LEVEL_HIGH: -- smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; -+ smu->gfx_actual_hard_min_freq = smu->gfx_default_soft_max_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; - - ret = vangogh_force_dpm_limit_value(smu, true); -+ if (ret) -+ return ret; - break; - case AMD_DPM_FORCED_LEVEL_LOW: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; -- smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; -- -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -+ smu->gfx_actual_soft_max_freq = smu->gfx_default_hard_min_freq; - - ret = vangogh_force_dpm_limit_value(smu, false); -+ if (ret) -+ return ret; - break; - case AMD_DPM_FORCED_LEVEL_AUTO: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -- - ret = vangogh_unforce_dpm_levels(smu); -- break; -- case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: -- smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; -- smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; -- -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -- -- ret = smu_cmn_send_smc_msg_with_param(smu, -- SMU_MSG_SetHardMinGfxClk, -- VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL); -- if (ret) -- return ret; -- -- ret = smu_cmn_send_smc_msg_with_param(smu, -- SMU_MSG_SetSoftMaxGfxClk, -- VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL); - if (ret) - return ret; -+ break; -+ case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: -+ smu->gfx_actual_hard_min_freq = VANGOGH_UMD_PSTATE_STANDARD_GFXCLK; -+ smu->gfx_actual_soft_max_freq = VANGOGH_UMD_PSTATE_STANDARD_GFXCLK; - - ret = vangogh_get_profiling_clk_mask(smu, level, - &vclk_mask, -@@ -1446,32 +1432,15 @@ static int vangogh_set_performance_level(struct smu_context *smu, - vangogh_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask); - vangogh_force_clk_levels(smu, SMU_VCLK, 1 << vclk_mask); - vangogh_force_clk_levels(smu, SMU_DCLK, 1 << dclk_mask); -- - break; - case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; -- smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; -- -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -- -- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinVcn, -- VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL); -- if (ret) -- return ret; -- -- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxVcn, -- VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL); -- if (ret) -- return ret; -+ smu->gfx_actual_soft_max_freq = smu->gfx_default_hard_min_freq; - break; - case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -- - ret = vangogh_get_profiling_clk_mask(smu, level, - NULL, - NULL, -@@ -1484,29 +1453,29 @@ static int vangogh_set_performance_level(struct smu_context *smu, - vangogh_force_clk_levels(smu, SMU_FCLK, 1 << fclk_mask); - break; - case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: -- smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; -- smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; -- -- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; -- smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; -- -- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, -- VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL); -- if (ret) -- return ret; -+ smu->gfx_actual_hard_min_freq = VANGOGH_UMD_PSTATE_PEAK_GFXCLK; -+ smu->gfx_actual_soft_max_freq = VANGOGH_UMD_PSTATE_PEAK_GFXCLK; - -- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, -- VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL); -+ ret = vangogh_set_peak_clock_by_device(smu); - if (ret) - return ret; -- -- ret = vangogh_set_peak_clock_by_device(smu); - break; - case AMD_DPM_FORCED_LEVEL_MANUAL: - case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: - default: -- break; -+ return 0; - } -+ -+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, -+ smu->gfx_actual_hard_min_freq, NULL); -+ if (ret) -+ return ret; -+ -+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, -+ smu->gfx_actual_soft_max_freq, NULL); -+ if (ret) -+ return ret; -+ - return ret; - } - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c -index d60b8c5e87157..9c91e79c955fb 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c -@@ -120,7 +120,8 @@ int smu_v12_0_powergate_sdma(struct smu_context *smu, bool gate) - - int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable) - { -- if (!(smu->adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) -+ /* Until now the SMU12 only implemented for Renoir series so here neen't do APU check. */ -+ if (!(smu->adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) || smu->adev->in_s0ix) - return 0; - - return smu_cmn_send_smc_msg_with_param(smu, -@@ -191,6 +192,9 @@ int smu_v12_0_fini_smc_tables(struct smu_context *smu) - kfree(smu_table->watermarks_table); - smu_table->watermarks_table = NULL; - -+ kfree(smu_table->gpu_metrics_table); -+ smu_table->gpu_metrics_table = NULL; -+ - return 0; - } - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c -index 5019903db492a..c9cfeb094750d 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c -@@ -1619,7 +1619,7 @@ static int aldebaran_allow_xgmi_power_down(struct smu_context *smu, bool en) - { - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GmiPwrDnControl, -- en ? 1 : 0, -+ en ? 0 : 1, - NULL); - } - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -index a0e50f23b1dd7..8d4aa16b2ae7c 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -@@ -197,6 +197,7 @@ int smu_v13_0_check_fw_status(struct smu_context *smu) - - int smu_v13_0_check_fw_version(struct smu_context *smu) - { -+ struct amdgpu_device *adev = smu->adev; - uint32_t if_version = 0xff, smu_version = 0xff; - uint16_t smu_major; - uint8_t smu_minor, smu_debug; -@@ -209,6 +210,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu) - smu_major = (smu_version >> 16) & 0xffff; - smu_minor = (smu_version >> 8) & 0xff; - smu_debug = (smu_version >> 0) & 0xff; -+ if (smu->is_apu) -+ adev->pm.fw_version = smu_version; - - switch (smu->adev->asic_type) { - case CHIP_ALDEBARAN: -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c -index a403657151ba1..0e1a843608e43 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c -@@ -291,14 +291,9 @@ static int yellow_carp_post_smu_init(struct smu_context *smu) - - static int yellow_carp_mode_reset(struct smu_context *smu, int type) - { -- int ret = 0, index = 0; -- -- index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, -- SMU_MSG_GfxDeviceDriverReset); -- if (index < 0) -- return index == -EACCES ? 0 : index; -+ int ret = 0; - -- ret = smu_cmn_send_smc_msg_with_param(smu, (uint16_t)index, type, NULL); -+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, type, NULL); - if (ret) - dev_err(smu->adev->dev, "Failed to mode reset!\n"); - -diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c -index b53fee6f1c170..65f172807a0d5 100644 ---- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c -+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c -@@ -291,7 +291,7 @@ vga_pw_show(struct device *dev, struct device_attribute *attr, char *buf) - if (rc) - return rc; - -- return sprintf(buf, "%u\n", reg & 1); -+ return sprintf(buf, "%u\n", reg); - } - static DEVICE_ATTR_RO(vga_pw); - -diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c -index 1e30eaeb0e1b3..d5c98f79d58d3 100644 ---- a/drivers/gpu/drm/ast/ast_mode.c -+++ b/drivers/gpu/drm/ast/ast_mode.c -@@ -1121,7 +1121,10 @@ static void ast_crtc_reset(struct drm_crtc *crtc) - if (crtc->state) - crtc->funcs->atomic_destroy_state(crtc, crtc->state); - -- __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); -+ if (ast_state) -+ __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); -+ else -+ __drm_atomic_helper_crtc_reset(crtc, NULL); - } - - static struct drm_crtc_state * -diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h -index d9eb353a4bf09..dbe1cc620f6e6 100644 ---- a/drivers/gpu/drm/ast/ast_tables.h -+++ b/drivers/gpu/drm/ast/ast_tables.h -@@ -282,8 +282,6 @@ static const struct ast_vbios_enhtable res_1360x768[] = { - }; - - static const struct ast_vbios_enhtable res_1600x900[] = { -- {1800, 1600, 24, 80, 1000, 900, 1, 3, VCLK108, /* 60Hz */ -- (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 3, 0x3A }, - {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */ - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | - AST2500PreCatchCRT), 60, 1, 0x3A }, -diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c -index cab6c8b92efd4..6a4f20fccf841 100644 ---- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c -+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c -@@ -998,11 +998,21 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - if (!blocking) - return 0; - -+ /* -+ * db[1]!=0: entering PSR, wait for fully active remote frame buffer. -+ * db[1]==0: exiting PSR, wait for either -+ * (a) ACTIVE_RESYNC - the sink "must display the -+ * incoming active frames from the Source device with no visible -+ * glitches and/or artifacts", even though timings may still be -+ * re-synchronizing; or -+ * (b) INACTIVE - the transition is fully complete. -+ */ - ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status, - psr_status >= 0 && - ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) || -- (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500, -- DP_TIMEOUT_PSR_LOOP_MS * 1000); -+ (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC || -+ psr_status == DP_PSR_SINK_INACTIVE))), -+ 1500, DP_TIMEOUT_PSR_LOOP_MS * 1000); - if (ret) { - dev_warn(dp->dev, "Failed to apply PSR %d\n", ret); - return ret; -diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c -index 14d73fb1dd15b..ea414cd349b5c 100644 ---- a/drivers/gpu/drm/bridge/analogix/anx7625.c -+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c -@@ -720,7 +720,7 @@ static int edid_read(struct anx7625_data *ctx, - ret = sp_tx_aux_rd(ctx, 0xf1); - - if (ret) { -- sp_tx_rst_aux(ctx); -+ ret = sp_tx_rst_aux(ctx); - DRM_DEV_DEBUG_DRIVER(dev, "edid read fail, reset!\n"); - } else { - ret = anx7625_reg_block_read(ctx, ctx->i2c.rx_p0_client, -@@ -735,7 +735,7 @@ static int edid_read(struct anx7625_data *ctx, - if (cnt > EDID_TRY_CNT) - return -EIO; - -- return 0; -+ return ret; - } - - static int segments_edid_read(struct anx7625_data *ctx, -@@ -785,7 +785,7 @@ static int segments_edid_read(struct anx7625_data *ctx, - if (cnt > EDID_TRY_CNT) - return -EIO; - -- return 0; -+ return ret; - } - - static int sp_tx_edid_read(struct anx7625_data *ctx, -@@ -887,7 +887,11 @@ static int sp_tx_edid_read(struct anx7625_data *ctx, - } - - /* Reset aux channel */ -- sp_tx_rst_aux(ctx); -+ ret = sp_tx_rst_aux(ctx); -+ if (ret < 0) { -+ DRM_DEV_ERROR(dev, "Failed to reset aux channel!\n"); -+ return ret; -+ } - - return (blocks_num + 1); - } -diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c -index 05eb759da6fc6..847a0dce7f1d3 100644 ---- a/drivers/gpu/drm/bridge/display-connector.c -+++ b/drivers/gpu/drm/bridge/display-connector.c -@@ -107,7 +107,7 @@ static int display_connector_probe(struct platform_device *pdev) - { - struct display_connector *conn; - unsigned int type; -- const char *label; -+ const char *label = NULL; - int ret; - - conn = devm_kzalloc(&pdev->dev, sizeof(*conn), GFP_KERNEL); -diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c -index 2f2a09adb4bc8..06b59b422c696 100644 ---- a/drivers/gpu/drm/bridge/ite-it66121.c -+++ b/drivers/gpu/drm/bridge/ite-it66121.c -@@ -889,7 +889,7 @@ unlock: - static int it66121_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { -- u32 vendor_ids[2], device_ids[2], revision_id; -+ u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 }; - struct device_node *ep; - int ret; - struct it66121_ctx *ctx; -@@ -918,11 +918,26 @@ static int it66121_probe(struct i2c_client *client, - return -EINVAL; - - ep = of_graph_get_remote_node(dev->of_node, 1, -1); -- if (!ep) -- return -EPROBE_DEFER; -+ if (!ep) { -+ dev_err(ctx->dev, "The endpoint is unconnected\n"); -+ return -EINVAL; -+ } -+ -+ if (!of_device_is_available(ep)) { -+ of_node_put(ep); -+ dev_err(ctx->dev, "The remote device is disabled\n"); -+ return -ENODEV; -+ } - - ctx->next_bridge = of_drm_find_bridge(ep); - of_node_put(ep); -+ if (!ctx->next_bridge) { -+ dev_dbg(ctx->dev, "Next bridge not found, deferring probe\n"); -+ return -EPROBE_DEFER; -+ } -+ -+ if (!ctx->next_bridge) -+ return -EPROBE_DEFER; - - i2c_set_clientdata(client, ctx); - mutex_init(&ctx->lock); -diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c -index 3cac16db970f0..010657ea7af78 100644 ---- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c -+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c -@@ -167,9 +167,10 @@ static void lt9611uxc_hpd_work(struct work_struct *work) - struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work); - bool connected; - -- if (lt9611uxc->connector.dev) -- drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); -- else { -+ if (lt9611uxc->connector.dev) { -+ if (lt9611uxc->connector.dev->mode_config.funcs) -+ drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); -+ } else { - - mutex_lock(<9611uxc->ocm_lock); - connected = lt9611uxc->hdmi_connected; -@@ -339,6 +340,8 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc - return -ENODEV; - } - -+ lt9611uxc->connector.polled = DRM_CONNECTOR_POLL_HPD; -+ - drm_connector_helper_add(<9611uxc->connector, - <9611uxc_bridge_connector_helper_funcs); - ret = drm_connector_init(bridge->dev, <9611uxc->connector, -diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c -index d2808c4a6fb1c..cce98bf2a4e73 100644 ---- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c -+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c -@@ -306,19 +306,10 @@ out: - mutex_unlock(&ge_b850v3_lvds_dev_mutex); - } - --static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, -- const struct i2c_device_id *id) -+static int ge_b850v3_register(void) - { -+ struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c; - struct device *dev = &stdp4028_i2c->dev; -- int ret; -- -- ret = ge_b850v3_lvds_init(dev); -- -- if (ret) -- return ret; -- -- ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c; -- i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr); - - /* drm bridge initialization */ - ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs; -@@ -343,6 +334,27 @@ static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, - "ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr); - } - -+static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, -+ const struct i2c_device_id *id) -+{ -+ struct device *dev = &stdp4028_i2c->dev; -+ int ret; -+ -+ ret = ge_b850v3_lvds_init(dev); -+ -+ if (ret) -+ return ret; -+ -+ ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c; -+ i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr); -+ -+ /* Only register after both bridges are probed */ -+ if (!ge_b850v3_lvds_ptr->stdp2690_i2c) -+ return 0; -+ -+ return ge_b850v3_register(); -+} -+ - static int stdp4028_ge_b850v3_fw_remove(struct i2c_client *stdp4028_i2c) - { - ge_b850v3_lvds_remove(); -@@ -386,7 +398,11 @@ static int stdp2690_ge_b850v3_fw_probe(struct i2c_client *stdp2690_i2c, - ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c; - i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr); - -- return 0; -+ /* Only register after both bridges are probed */ -+ if (!ge_b850v3_lvds_ptr->stdp4028_i2c) -+ return 0; -+ -+ return ge_b850v3_register(); - } - - static int stdp2690_ge_b850v3_fw_remove(struct i2c_client *stdp2690_i2c) -diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c -index ed8ac5059cd26..af07eeb47ca02 100644 ---- a/drivers/gpu/drm/bridge/nwl-dsi.c -+++ b/drivers/gpu/drm/bridge/nwl-dsi.c -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps) - /* - * ui2bc - UI time periods to byte clock cycles - */ --static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui) -+static u32 ui2bc(unsigned int ui) - { -- u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); -- -- return DIV64_U64_ROUND_UP(ui * dsi->lanes, -- dsi->mode.clock * 1000 * bpp); -+ return DIV_ROUND_UP(ui, BITS_PER_BYTE); - } - - /* -@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi) - } - - /* values in byte clock cycles */ -- cycles = ui2bc(dsi, cfg->clk_pre); -+ cycles = ui2bc(cfg->clk_pre); - DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles); - nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles); - cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero); - DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles); -- cycles += ui2bc(dsi, cfg->clk_pre); -+ cycles += ui2bc(cfg->clk_pre); - DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles); - nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles); - cycles = ps2bc(dsi, cfg->hs_exit); -@@ -939,6 +937,40 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) - drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0); - } - -+static u32 *nwl_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ u32 output_fmt, -+ unsigned int *num_input_fmts) -+{ -+ u32 *input_fmts, input_fmt; -+ -+ *num_input_fmts = 0; -+ -+ switch (output_fmt) { -+ /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */ -+ case MEDIA_BUS_FMT_FIXED: -+ input_fmt = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_RGB666_1X18: -+ case MEDIA_BUS_FMT_RGB565_1X16: -+ input_fmt = output_fmt; -+ break; -+ default: -+ return NULL; -+ } -+ -+ input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL); -+ if (!input_fmts) -+ return NULL; -+ input_fmts[0] = input_fmt; -+ *num_input_fmts = 1; -+ -+ return input_fmts; -+} -+ - static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { - .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, -@@ -946,6 +978,7 @@ static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { - .atomic_check = nwl_dsi_bridge_atomic_check, - .atomic_enable = nwl_dsi_bridge_atomic_enable, - .atomic_disable = nwl_dsi_bridge_atomic_disable, -+ .atomic_get_input_bus_fmts = nwl_bridge_atomic_get_input_bus_fmts, - .mode_set = nwl_dsi_bridge_mode_set, - .mode_valid = nwl_dsi_bridge_mode_valid, - .attach = nwl_dsi_bridge_attach, -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c -index d0db1acf11d73..7d2ed0ed2fe26 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c -@@ -320,13 +320,17 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream) - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_dw_hdmi *dw = substream->private_data; - void __iomem *base = dw->data.base; -+ u8 *eld; - int ret; - - runtime->hw = dw_hdmi_hw; - -- ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld); -- if (ret < 0) -- return ret; -+ eld = dw->data.get_eld(dw->data.hdmi); -+ if (eld) { -+ ret = snd_pcm_hw_constraint_eld(runtime, eld); -+ if (ret < 0) -+ return ret; -+ } - - ret = snd_pcm_limit_hw_rates(runtime); - if (ret < 0) -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h -index cb07dc0da5a70..f72d27208ebef 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h -@@ -9,15 +9,15 @@ struct dw_hdmi_audio_data { - void __iomem *base; - int irq; - struct dw_hdmi *hdmi; -- u8 *eld; -+ u8 *(*get_eld)(struct dw_hdmi *hdmi); - }; - - struct dw_hdmi_i2s_audio_data { - struct dw_hdmi *hdmi; -- u8 *eld; - - void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); - u8 (*read)(struct dw_hdmi *hdmi, int offset); -+ u8 *(*get_eld)(struct dw_hdmi *hdmi); - }; - - #endif -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -index feb04f127b550..f50b47ac11a82 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -@@ -135,8 +135,15 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf, - size_t len) - { - struct dw_hdmi_i2s_audio_data *audio = data; -+ u8 *eld; -+ -+ eld = audio->get_eld(audio->hdmi); -+ if (eld) -+ memcpy(buf, eld, min_t(size_t, MAX_ELD_BYTES, len)); -+ else -+ /* Pass en empty ELD if connector not available */ -+ memset(buf, 0, len); - -- memcpy(buf, audio->eld, min_t(size_t, MAX_ELD_BYTES, len)); - return 0; - } - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index f08d0fded61f7..e1211a5b334ba 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -757,6 +757,14 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) - hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); - } - -+static u8 *hdmi_audio_get_eld(struct dw_hdmi *hdmi) -+{ -+ if (!hdmi->curr_conn) -+ return NULL; -+ -+ return hdmi->curr_conn->eld; -+} -+ - static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) - { - hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); -@@ -3431,7 +3439,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, - audio.base = hdmi->regs; - audio.irq = irq; - audio.hdmi = hdmi; -- audio.eld = hdmi->connector.eld; -+ audio.get_eld = hdmi_audio_get_eld; - hdmi->enable_audio = dw_hdmi_ahb_audio_enable; - hdmi->disable_audio = dw_hdmi_ahb_audio_disable; - -@@ -3444,7 +3452,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, - struct dw_hdmi_i2s_audio_data audio; - - audio.hdmi = hdmi; -- audio.eld = hdmi->connector.eld; -+ audio.get_eld = hdmi_audio_get_eld; - audio.write = hdmi_writeb; - audio.read = hdmi_readb; - hdmi->enable_audio = dw_hdmi_i2s_audio_enable; -diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -index 41d48a393e7f5..45a5f1e48f0ef 100644 ---- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -@@ -188,6 +188,7 @@ static const struct regmap_config ti_sn65dsi86_regmap_config = { - .val_bits = 8, - .volatile_table = &ti_sn_bridge_volatile_table, - .cache_type = REGCACHE_NONE, -+ .max_register = 0xFF, - }; - - static void ti_sn65dsi86_write_u16(struct ti_sn65dsi86 *pdata, -@@ -1472,6 +1473,7 @@ static inline void ti_sn_gpio_unregister(void) {} - - static void ti_sn65dsi86_runtime_disable(void *data) - { -+ pm_runtime_dont_use_autosuspend(data); - pm_runtime_disable(data); - } - -@@ -1531,11 +1533,11 @@ static int ti_sn65dsi86_probe(struct i2c_client *client, - "failed to get reference clock\n"); - - pm_runtime_enable(dev); -+ pm_runtime_set_autosuspend_delay(pdata->dev, 500); -+ pm_runtime_use_autosuspend(pdata->dev); - ret = devm_add_action_or_reset(dev, ti_sn65dsi86_runtime_disable, dev); - if (ret) - return ret; -- pm_runtime_set_autosuspend_delay(pdata->dev, 500); -- pm_runtime_use_autosuspend(pdata->dev); - - ti_sn65dsi86_debugfs_init(pdata); - -diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c -index ff1416cd609a5..a1e4c7905ebbe 100644 ---- a/drivers/gpu/drm/drm_atomic.c -+++ b/drivers/gpu/drm/drm_atomic.c -@@ -1310,8 +1310,10 @@ int drm_atomic_check_only(struct drm_atomic_state *state) - - DRM_DEBUG_ATOMIC("checking %p\n", state); - -- for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) -- requested_crtc |= drm_crtc_mask(crtc); -+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { -+ if (new_crtc_state->enable) -+ requested_crtc |= drm_crtc_mask(crtc); -+ } - - for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { - ret = drm_atomic_plane_check(old_plane_state, new_plane_state); -@@ -1360,8 +1362,10 @@ int drm_atomic_check_only(struct drm_atomic_state *state) - } - } - -- for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) -- affected_crtc |= drm_crtc_mask(crtc); -+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { -+ if (new_crtc_state->enable) -+ affected_crtc |= drm_crtc_mask(crtc); -+ } - - /* - * For commits that allow modesets drivers can add other CRTCs to the -diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c -index 2c0c6ec928200..ff2bc9a118011 100644 ---- a/drivers/gpu/drm/drm_atomic_helper.c -+++ b/drivers/gpu/drm/drm_atomic_helper.c -@@ -1001,7 +1001,7 @@ crtc_needs_disable(struct drm_crtc_state *old_state, - * it's in self refresh mode and needs to be fully disabled. - */ - return old_state->active || -- (old_state->self_refresh_active && !new_state->enable) || -+ (old_state->self_refresh_active && !new_state->active) || - new_state->self_refresh_active; - } - -diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c -index 909f318331816..f195c70131373 100644 ---- a/drivers/gpu/drm/drm_atomic_uapi.c -+++ b/drivers/gpu/drm/drm_atomic_uapi.c -@@ -76,15 +76,17 @@ int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, - state->mode_blob = NULL; - - if (mode) { -+ struct drm_property_blob *blob; -+ - drm_mode_convert_to_umode(&umode, mode); -- state->mode_blob = -- drm_property_create_blob(state->crtc->dev, -- sizeof(umode), -- &umode); -- if (IS_ERR(state->mode_blob)) -- return PTR_ERR(state->mode_blob); -+ blob = drm_property_create_blob(crtc->dev, -+ sizeof(umode), &umode); -+ if (IS_ERR(blob)) -+ return PTR_ERR(blob); - - drm_mode_copy(&state->mode, mode); -+ -+ state->mode_blob = blob; - state->enable = true; - drm_dbg_atomic(crtc->dev, - "Set [MODE:%s] for [CRTC:%d:%s] state %p\n", -diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c -index 6d0f2c447f3b9..7bb24523a7493 100644 ---- a/drivers/gpu/drm/drm_dp_helper.c -+++ b/drivers/gpu/drm/drm_dp_helper.c -@@ -3214,27 +3214,13 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli - const u16 level) - { - int ret; -- u8 dpcd_buf, new_dpcd_buf; -+ u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; - -- ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf); -- if (ret != 1) { -- drm_dbg_kms(aux->drm_dev, -- "%s: Failed to read backlight mode: %d\n", aux->name, ret); -- return ret < 0 ? ret : -EIO; -- } -- -- new_dpcd_buf = dpcd_buf; -- -- if ((dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { -- new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK; -- new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; -- -- if (bl->pwmgen_bit_count) { -- ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); -- if (ret != 1) -- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n", -- aux->name, ret); -- } -+ if (bl->pwmgen_bit_count) { -+ ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); -+ if (ret != 1) -+ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n", -+ aux->name, ret); - } - - if (bl->pwm_freq_pre_divider) { -@@ -3244,16 +3230,14 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli - "%s: Failed to write aux backlight frequency: %d\n", - aux->name, ret); - else -- new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE; -+ dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE; - } - -- if (new_dpcd_buf != dpcd_buf) { -- ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf); -- if (ret != 1) { -- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n", -- aux->name, ret); -- return ret < 0 ? ret : -EIO; -- } -+ ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, dpcd_buf); -+ if (ret != 1) { -+ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n", -+ aux->name, ret); -+ return ret < 0 ? ret : -EIO; - } - - ret = drm_edp_backlight_set_level(aux, bl, level); -diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c -index 7a5097467ba5c..b3a1636d1b984 100644 ---- a/drivers/gpu/drm/drm_drv.c -+++ b/drivers/gpu/drm/drm_drv.c -@@ -581,6 +581,7 @@ static int drm_dev_init(struct drm_device *dev, - const struct drm_driver *driver, - struct device *parent) - { -+ struct inode *inode; - int ret; - - if (!drm_core_init_complete) { -@@ -617,13 +618,15 @@ static int drm_dev_init(struct drm_device *dev, - if (ret) - return ret; - -- dev->anon_inode = drm_fs_inode_new(); -- if (IS_ERR(dev->anon_inode)) { -- ret = PTR_ERR(dev->anon_inode); -+ inode = drm_fs_inode_new(); -+ if (IS_ERR(inode)) { -+ ret = PTR_ERR(inode); - DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret); - goto err; - } - -+ dev->anon_inode = inode; -+ - if (drm_core_check_feature(dev, DRIVER_RENDER)) { - ret = drm_minor_alloc(dev, DRM_MINOR_RENDER); - if (ret) -diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c -index ea9a79bc95839..6ad4361a5cbc7 100644 ---- a/drivers/gpu/drm/drm_edid.c -+++ b/drivers/gpu/drm/drm_edid.c -@@ -5205,6 +5205,7 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi - if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) - return quirks; - -+ info->color_formats |= DRM_COLOR_FORMAT_RGB444; - drm_parse_cea_ext(connector, edid); - - /* -@@ -5253,7 +5254,6 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi - DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n", - connector->name, info->bpc); - -- info->color_formats |= DRM_COLOR_FORMAT_RGB444; - if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) - info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; - if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) -diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c -index 8e7a124d6c5a3..22bf690910b25 100644 ---- a/drivers/gpu/drm/drm_fb_helper.c -+++ b/drivers/gpu/drm/drm_fb_helper.c -@@ -1743,7 +1743,13 @@ void drm_fb_helper_fill_info(struct fb_info *info, - sizes->fb_width, sizes->fb_height); - - info->par = fb_helper; -- snprintf(info->fix.id, sizeof(info->fix.id), "%s", -+ /* -+ * The DRM drivers fbdev emulation device name can be confusing if the -+ * driver name also has a "drm" suffix on it. Leading to names such as -+ * "simpledrmdrmfb" in /proc/fb. Unfortunately, it's an uAPI and can't -+ * be changed due user-space tools (e.g: pm-utils) matching against it. -+ */ -+ snprintf(info->fix.id, sizeof(info->fix.id), "%sdrmfb", - fb_helper->dev->driver->name); - - } -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index d53388199f34c..6533efa840204 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -210,8 +210,13 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) - dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map); - drm_prime_gem_destroy(gem_obj, cma_obj->sgt); - } else if (cma_obj->vaddr) { -- dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, -- cma_obj->vaddr, cma_obj->paddr); -+ if (cma_obj->map_noncoherent) -+ dma_free_noncoherent(gem_obj->dev->dev, cma_obj->base.size, -+ cma_obj->vaddr, cma_obj->paddr, -+ DMA_TO_DEVICE); -+ else -+ dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, -+ cma_obj->vaddr, cma_obj->paddr); - } - - drm_gem_object_release(gem_obj); -@@ -510,6 +515,7 @@ int drm_gem_cma_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) - */ - vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); - vma->vm_flags &= ~VM_PFNMAP; -+ vma->vm_flags |= VM_DONTEXPAND; - - cma_obj = to_drm_gem_cma_obj(obj); - -diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c -index e1b2ce4921ae7..448c2f2d803a6 100644 ---- a/drivers/gpu/drm/drm_panel_orientation_quirks.c -+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c -@@ -109,6 +109,18 @@ static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = { - .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, - }; - -+static const struct drm_dmi_panel_orientation_data lcd1280x1920_rightside_up = { -+ .width = 1280, -+ .height = 1920, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd1600x2560_leftside_up = { -+ .width = 1600, -+ .height = 2560, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, -+}; -+ - static const struct dmi_system_id orientation_data[] = { - { /* Acer One 10 (S1003) */ - .matches = { -@@ -205,6 +217,13 @@ static const struct dmi_system_id orientation_data[] = { - DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"), - }, - .driver_data = (void *)&itworks_tw891, -+ }, { /* KD Kurio Smart C15200 2-in-1 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "KD Interactive"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Kurio Smart"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "KDM960BCP"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, - }, { /* - * Lenovo Ideapad Miix 310 laptop, only some production batches - * have a portrait screen, the resolution checks makes the quirk -@@ -223,12 +242,23 @@ static const struct dmi_system_id orientation_data[] = { - DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), - }, - .driver_data = (void *)&lcd800x1280_rightside_up, -- }, { /* Lenovo Ideapad D330 */ -+ }, { /* Lenovo Ideapad D330-10IGM (HD) */ - .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -- DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81H3"), - DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), - }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Lenovo Ideapad D330-10IGM (FHD) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Yoga Book X90F / X91F / X91L */ -+ .matches = { -+ /* Non exact match to match all versions */ -+ DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), -+ }, - .driver_data = (void *)&lcd1200x1920_rightside_up, - }, { /* OneGX1 Pro */ - .matches = { -@@ -237,6 +267,25 @@ static const struct dmi_system_id orientation_data[] = { - DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), - }, - .driver_data = (void *)&onegx1_pro, -+ }, { /* OneXPlayer */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONE-NETBOOK TECHNOLOGY CO., LTD."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), -+ }, -+ .driver_data = (void *)&lcd1600x2560_leftside_up, -+ }, { /* Samsung GalaxyBook 10.6 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"), -+ }, -+ .driver_data = (void *)&lcd1280x1920_rightside_up, -+ }, { /* Valve Steam Deck */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, - }, { /* VIOS LTH17 */ - .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), -diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c -index 5b2d0ca03705c..838b32b70bce6 100644 ---- a/drivers/gpu/drm/drm_plane_helper.c -+++ b/drivers/gpu/drm/drm_plane_helper.c -@@ -123,7 +123,6 @@ static int drm_plane_helper_check_update(struct drm_plane *plane, - .crtc_w = drm_rect_width(dst), - .crtc_h = drm_rect_height(dst), - .rotation = rotation, -- .visible = *visible, - }; - struct drm_crtc_state crtc_state = { - .crtc = crtc, -diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c -index deb23dbec8b52..d6c7f4f9a7a29 100644 ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) - if (obj->funcs && obj->funcs->mmap) { - vma->vm_ops = obj->funcs->vm_ops; - -+ drm_gem_object_get(obj); - ret = obj->funcs->mmap(obj, vma); -- if (ret) -+ if (ret) { -+ drm_gem_object_put(obj); - return ret; -+ } - vma->vm_private_data = obj; -- drm_gem_object_get(obj); - return 0; - } - -diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c -index c9a9d74f338c1..c313a5b4549c4 100644 ---- a/drivers/gpu/drm/drm_syncobj.c -+++ b/drivers/gpu/drm/drm_syncobj.c -@@ -404,8 +404,17 @@ int drm_syncobj_find_fence(struct drm_file *file_private, - - if (*fence) { - ret = dma_fence_chain_find_seqno(fence, point); -- if (!ret) -+ if (!ret) { -+ /* If the requested seqno is already signaled -+ * drm_syncobj_find_fence may return a NULL -+ * fence. To make sure the recipient gets -+ * signalled, use a new fence instead. -+ */ -+ if (!*fence) -+ *fence = dma_fence_get_stub(); -+ - goto out; -+ } - dma_fence_put(*fence); - } else { - ret = -EINVAL; -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c -index 486259e154aff..90488ab8c6d8e 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c -+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c -@@ -469,6 +469,12 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, - return -EINVAL; - } - -+ if (args->stream_size > SZ_128K || args->nr_relocs > SZ_128K || -+ args->nr_bos > SZ_128K || args->nr_pmrs > 128) { -+ DRM_ERROR("submit arguments out of size limits\n"); -+ return -EINVAL; -+ } -+ - /* - * Copy the command submission and bo array to kernel space in - * one go, and do this outside of any locks. -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h -index 1c75c8ed5bcea..85eddd492774d 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h -+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h -@@ -130,6 +130,7 @@ struct etnaviv_gpu { - - /* hang detection */ - u32 hangcheck_dma_addr; -+ u32 hangcheck_fence; - - void __iomem *mmio; - int irq; -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c -index feb6da1b6cebc..bbf391f48f949 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c -+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c -@@ -107,8 +107,10 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job - */ - dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS); - change = dma_addr - gpu->hangcheck_dma_addr; -- if (change < 0 || change > 16) { -+ if (gpu->completed_fence != gpu->hangcheck_fence || -+ change < 0 || change > 16) { - gpu->hangcheck_dma_addr = dma_addr; -+ gpu->hangcheck_fence = gpu->completed_fence; - goto out_no_timeout; - } - -diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -index cd818a6291835..00e53de4812bb 100644 ---- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -+++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -@@ -225,12 +225,29 @@ static int hyperv_vmbus_remove(struct hv_device *hdev) - { - struct drm_device *dev = hv_get_drvdata(hdev); - struct hyperv_drm_device *hv = to_hv(dev); -+ struct pci_dev *pdev; - - drm_dev_unplug(dev); - drm_atomic_helper_shutdown(dev); - vmbus_close(hdev->channel); - hv_set_drvdata(hdev, NULL); -- vmbus_free_mmio(hv->mem->start, hv->fb_size); -+ -+ /* -+ * Free allocated MMIO memory only on Gen2 VMs. -+ * On Gen1 VMs, release the PCI device -+ */ -+ if (efi_enabled(EFI_BOOT)) { -+ vmbus_free_mmio(hv->mem->start, hv->fb_size); -+ } else { -+ pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, -+ PCI_DEVICE_ID_HYPERV_VIDEO, NULL); -+ if (!pdev) { -+ drm_err(dev, "Unable to find PCI Hyper-V video\n"); -+ return -ENODEV; -+ } -+ pci_release_region(pdev, 0); -+ pci_dev_put(pdev); -+ } - - return 0; - } -diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig -index f960f5d7664e6..fe6b34774483f 100644 ---- a/drivers/gpu/drm/i915/Kconfig -+++ b/drivers/gpu/drm/i915/Kconfig -@@ -101,6 +101,7 @@ config DRM_I915_USERPTR - config DRM_I915_GVT - bool "Enable Intel GVT-g graphics virtualization host support" - depends on DRM_I915 -+ depends on X86 - depends on 64BIT - default n - help -diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile -index 335ba9f43d8f7..26cf754229451 100644 ---- a/drivers/gpu/drm/i915/Makefile -+++ b/drivers/gpu/drm/i915/Makefile -@@ -211,6 +211,8 @@ i915-y += \ - display/intel_dpio_phy.o \ - display/intel_dpll.o \ - display/intel_dpll_mgr.o \ -+ display/intel_dpt.o \ -+ display/intel_drrs.o \ - display/intel_dsb.o \ - display/intel_fb.o \ - display/intel_fbc.o \ -diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c -index be352e9f0afc1..63baaf6988ade 100644 ---- a/drivers/gpu/drm/i915/display/g4x_hdmi.c -+++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c -@@ -584,6 +584,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv, - else - intel_encoder->enable = g4x_enable_hdmi; - } -+ intel_encoder->shutdown = intel_hdmi_encoder_shutdown; - - intel_encoder->type = INTEL_OUTPUT_HDMI; - intel_encoder->power_domain = intel_port_to_power_domain(port); -diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c -index a3eae3f3eadce..638a00b2dc2d2 100644 ---- a/drivers/gpu/drm/i915/display/icl_dsi.c -+++ b/drivers/gpu/drm/i915/display/icl_dsi.c -@@ -711,10 +711,7 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder, - intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val); - - for_each_dsi_phy(phy, intel_dsi->phys) { -- if (DISPLAY_VER(dev_priv) >= 12) -- val |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); -- else -- val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); -+ val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); - } - intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val); - -@@ -1150,8 +1147,6 @@ static void - gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) - { -- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -- - /* step 4a: power up all lanes of the DDI used by DSI */ - gen11_dsi_power_up_lanes(encoder); - -@@ -1177,8 +1172,7 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, - gen11_dsi_configure_transcoder(encoder, crtc_state); - - /* Step 4l: Gate DDI clocks */ -- if (DISPLAY_VER(dev_priv) == 11) -- gen11_dsi_gate_clocks(encoder); -+ gen11_dsi_gate_clocks(encoder); - } - - static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) -diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c -index fd71346aac7bc..32d5a556b7eac 100644 ---- a/drivers/gpu/drm/i915/display/intel_bios.c -+++ b/drivers/gpu/drm/i915/display/intel_bios.c -@@ -1692,6 +1692,39 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) - return 0; - } - -+static u8 dvo_port_type(u8 dvo_port) -+{ -+ switch (dvo_port) { -+ case DVO_PORT_HDMIA: -+ case DVO_PORT_HDMIB: -+ case DVO_PORT_HDMIC: -+ case DVO_PORT_HDMID: -+ case DVO_PORT_HDMIE: -+ case DVO_PORT_HDMIF: -+ case DVO_PORT_HDMIG: -+ case DVO_PORT_HDMIH: -+ case DVO_PORT_HDMII: -+ return DVO_PORT_HDMIA; -+ case DVO_PORT_DPA: -+ case DVO_PORT_DPB: -+ case DVO_PORT_DPC: -+ case DVO_PORT_DPD: -+ case DVO_PORT_DPE: -+ case DVO_PORT_DPF: -+ case DVO_PORT_DPG: -+ case DVO_PORT_DPH: -+ case DVO_PORT_DPI: -+ return DVO_PORT_DPA; -+ case DVO_PORT_MIPIA: -+ case DVO_PORT_MIPIB: -+ case DVO_PORT_MIPIC: -+ case DVO_PORT_MIPID: -+ return DVO_PORT_MIPIA; -+ default: -+ return dvo_port; -+ } -+} -+ - static enum port __dvo_port_to_port(int n_ports, int n_dvo, - const int port_mapping[][3], u8 dvo_port) - { -@@ -2622,35 +2655,17 @@ bool intel_bios_is_port_edp(struct drm_i915_private *i915, enum port port) - return false; - } - --static bool child_dev_is_dp_dual_mode(const struct child_device_config *child, -- enum port port) -+static bool child_dev_is_dp_dual_mode(const struct child_device_config *child) - { -- static const struct { -- u16 dp, hdmi; -- } port_mapping[] = { -- /* -- * Buggy VBTs may declare DP ports as having -- * HDMI type dvo_port :( So let's check both. -- */ -- [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, -- [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, -- [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, -- [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, -- [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, -- }; -- -- if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) -- return false; -- - if ((child->device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) != - (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS)) - return false; - -- if (child->dvo_port == port_mapping[port].dp) -+ if (dvo_port_type(child->dvo_port) == DVO_PORT_DPA) - return true; - - /* Only accept a HDMI dvo_port as DP++ if it has an AUX channel */ -- if (child->dvo_port == port_mapping[port].hdmi && -+ if (dvo_port_type(child->dvo_port) == DVO_PORT_HDMIA && - child->aux_channel != 0) - return true; - -@@ -2660,10 +2675,36 @@ static bool child_dev_is_dp_dual_mode(const struct child_device_config *child, - bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *i915, - enum port port) - { -+ static const struct { -+ u16 dp, hdmi; -+ } port_mapping[] = { -+ /* -+ * Buggy VBTs may declare DP ports as having -+ * HDMI type dvo_port :( So let's check both. -+ */ -+ [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, -+ [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, -+ [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, -+ [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, -+ [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, -+ }; - const struct intel_bios_encoder_data *devdata; - -+ if (HAS_DDI(i915)) { -+ const struct intel_bios_encoder_data *devdata; -+ -+ devdata = intel_bios_encoder_data_lookup(i915, port); -+ -+ return devdata && child_dev_is_dp_dual_mode(&devdata->child); -+ } -+ -+ if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) -+ return false; -+ - list_for_each_entry(devdata, &i915->vbt.display_devices, node) { -- if (child_dev_is_dp_dual_mode(&devdata->child, port)) -+ if ((devdata->child.dvo_port == port_mapping[port].dp || -+ devdata->child.dvo_port == port_mapping[port].hdmi) && -+ child_dev_is_dp_dual_mode(&devdata->child)) - return true; - } - -diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c -index 4b94256d73197..7144c76ac9701 100644 ---- a/drivers/gpu/drm/i915/display/intel_bw.c -+++ b/drivers/gpu/drm/i915/display/intel_bw.c -@@ -681,6 +681,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) - unsigned int max_bw_point = 0, max_bw = 0; - unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points; - unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points; -+ bool changed = false; - u32 mask = 0; - - /* FIXME earlier gens need some checks too */ -@@ -724,6 +725,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) - new_bw_state->data_rate[crtc->pipe] = new_data_rate; - new_bw_state->num_active_planes[crtc->pipe] = new_active_planes; - -+ changed = true; -+ - drm_dbg_kms(&dev_priv->drm, - "pipe %c data rate %u num active planes %u\n", - pipe_name(crtc->pipe), -@@ -731,7 +734,19 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) - new_bw_state->num_active_planes[crtc->pipe]); - } - -- if (!new_bw_state) -+ old_bw_state = intel_atomic_get_old_bw_state(state); -+ new_bw_state = intel_atomic_get_new_bw_state(state); -+ -+ if (new_bw_state && -+ intel_can_enable_sagv(dev_priv, old_bw_state) != -+ intel_can_enable_sagv(dev_priv, new_bw_state)) -+ changed = true; -+ -+ /* -+ * If none of our inputs (data rates, number of active -+ * planes, SAGV yes/no) changed then nothing to do here. -+ */ -+ if (!changed) - return 0; - - ret = intel_atomic_lock_global_state(&new_bw_state->base); -@@ -814,7 +829,6 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) - */ - new_bw_state->qgv_points_mask = ~allowed_points & mask; - -- old_bw_state = intel_atomic_get_old_bw_state(state); - /* - * If the actual mask had changed we need to make sure that - * the commits are serialized(in case this is a nomodeset, nonblocking) -diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h -index 46c6eecbd9175..0ceaed1c96562 100644 ---- a/drivers/gpu/drm/i915/display/intel_bw.h -+++ b/drivers/gpu/drm/i915/display/intel_bw.h -@@ -30,19 +30,19 @@ struct intel_bw_state { - */ - u8 pipe_sagv_reject; - -+ /* bitmask of active pipes */ -+ u8 active_pipes; -+ - /* - * Current QGV points mask, which restricts - * some particular SAGV states, not to confuse - * with pipe_sagv_mask. - */ -- u8 qgv_points_mask; -+ u16 qgv_points_mask; - - unsigned int data_rate[I915_MAX_PIPES]; - u8 num_active_planes[I915_MAX_PIPES]; - -- /* bitmask of active pipes */ -- u8 active_pipes; -- - int min_cdclk; - }; - -diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c -index bd184325d0c75..f61901e26409e 100644 ---- a/drivers/gpu/drm/i915/display/intel_ddi.c -+++ b/drivers/gpu/drm/i915/display/intel_ddi.c -@@ -40,6 +40,7 @@ - #include "intel_dp_link_training.h" - #include "intel_dp_mst.h" - #include "intel_dpio_phy.h" -+#include "intel_drrs.h" - #include "intel_dsi.h" - #include "intel_fdi.h" - #include "intel_fifo_underrun.h" -@@ -4432,6 +4433,7 @@ static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) - enum phy phy = intel_port_to_phy(i915, encoder->port); - - intel_dp_encoder_shutdown(encoder); -+ intel_hdmi_encoder_shutdown(encoder); - - if (!intel_phy_is_tc(i915, phy)) - return; -diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c -index ba2c08f1a797c..876620455ed31 100644 ---- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c -+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c -@@ -476,14 +476,14 @@ static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi = { - static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_dp[] = { - /* NT mV Trans mV db */ - { .icl = { 0xA, 0x33, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ -- { .icl = { 0xA, 0x47, 0x36, 0x00, 0x09 } }, /* 350 500 3.1 */ -- { .icl = { 0xC, 0x64, 0x34, 0x00, 0x0B } }, /* 350 700 6.0 */ -- { .icl = { 0x6, 0x7F, 0x30, 0x00, 0x0F } }, /* 350 900 8.2 */ -+ { .icl = { 0xA, 0x47, 0x38, 0x00, 0x07 } }, /* 350 500 3.1 */ -+ { .icl = { 0xC, 0x64, 0x33, 0x00, 0x0C } }, /* 350 700 6.0 */ -+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 350 900 8.2 */ - { .icl = { 0xA, 0x46, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */ -- { .icl = { 0xC, 0x64, 0x38, 0x00, 0x07 } }, /* 500 700 2.9 */ -+ { .icl = { 0xC, 0x64, 0x37, 0x00, 0x08 } }, /* 500 700 2.9 */ - { .icl = { 0x6, 0x7F, 0x32, 0x00, 0x0D } }, /* 500 900 5.1 */ - { .icl = { 0xC, 0x61, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */ -- { .icl = { 0x6, 0x7F, 0x38, 0x00, 0x07 } }, /* 600 900 3.5 */ -+ { .icl = { 0x6, 0x7F, 0x37, 0x00, 0x08 } }, /* 600 900 3.5 */ - { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ - }; - -diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c -index 17f44ffea5866..625ce6975eeba 100644 ---- a/drivers/gpu/drm/i915/display/intel_display.c -+++ b/drivers/gpu/drm/i915/display/intel_display.c -@@ -84,6 +84,7 @@ - #include "intel_display_types.h" - #include "intel_dmc.h" - #include "intel_dp_link_training.h" -+#include "intel_dpt.h" - #include "intel_fbc.h" - #include "intel_fdi.h" - #include "intel_fbdev.h" -@@ -126,182 +127,6 @@ static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); - static void intel_modeset_setup_hw_state(struct drm_device *dev, - struct drm_modeset_acquire_ctx *ctx); - --struct i915_dpt { -- struct i915_address_space vm; -- -- struct drm_i915_gem_object *obj; -- struct i915_vma *vma; -- void __iomem *iomem; --}; -- --#define i915_is_dpt(vm) ((vm)->is_dpt) -- --static inline struct i915_dpt * --i915_vm_to_dpt(struct i915_address_space *vm) --{ -- BUILD_BUG_ON(offsetof(struct i915_dpt, vm)); -- GEM_BUG_ON(!i915_is_dpt(vm)); -- return container_of(vm, struct i915_dpt, vm); --} -- --#define dpt_total_entries(dpt) ((dpt)->vm.total >> PAGE_SHIFT) -- --static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) --{ -- writeq(pte, addr); --} -- --static void dpt_insert_page(struct i915_address_space *vm, -- dma_addr_t addr, -- u64 offset, -- enum i915_cache_level level, -- u32 flags) --{ -- struct i915_dpt *dpt = i915_vm_to_dpt(vm); -- gen8_pte_t __iomem *base = dpt->iomem; -- -- gen8_set_pte(base + offset / I915_GTT_PAGE_SIZE, -- vm->pte_encode(addr, level, flags)); --} -- --static void dpt_insert_entries(struct i915_address_space *vm, -- struct i915_vma *vma, -- enum i915_cache_level level, -- u32 flags) --{ -- struct i915_dpt *dpt = i915_vm_to_dpt(vm); -- gen8_pte_t __iomem *base = dpt->iomem; -- const gen8_pte_t pte_encode = vm->pte_encode(0, level, flags); -- struct sgt_iter sgt_iter; -- dma_addr_t addr; -- int i; -- -- /* -- * Note that we ignore PTE_READ_ONLY here. The caller must be careful -- * not to allow the user to override access to a read only page. -- */ -- -- i = vma->node.start / I915_GTT_PAGE_SIZE; -- for_each_sgt_daddr(addr, sgt_iter, vma->pages) -- gen8_set_pte(&base[i++], pte_encode | addr); --} -- --static void dpt_clear_range(struct i915_address_space *vm, -- u64 start, u64 length) --{ --} -- --static void dpt_bind_vma(struct i915_address_space *vm, -- struct i915_vm_pt_stash *stash, -- struct i915_vma *vma, -- enum i915_cache_level cache_level, -- u32 flags) --{ -- struct drm_i915_gem_object *obj = vma->obj; -- u32 pte_flags; -- -- /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ -- pte_flags = 0; -- if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj)) -- pte_flags |= PTE_READ_ONLY; -- if (i915_gem_object_is_lmem(obj)) -- pte_flags |= PTE_LM; -- -- vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); -- -- vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; -- -- /* -- * Without aliasing PPGTT there's no difference between -- * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally -- * upgrade to both bound if we bind either to avoid double-binding. -- */ -- atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags); --} -- --static void dpt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) --{ -- vm->clear_range(vm, vma->node.start, vma->size); --} -- --static void dpt_cleanup(struct i915_address_space *vm) --{ -- struct i915_dpt *dpt = i915_vm_to_dpt(vm); -- -- i915_gem_object_put(dpt->obj); --} -- --static struct i915_address_space * --intel_dpt_create(struct intel_framebuffer *fb) --{ -- struct drm_gem_object *obj = &intel_fb_obj(&fb->base)->base; -- struct drm_i915_private *i915 = to_i915(obj->dev); -- struct drm_i915_gem_object *dpt_obj; -- struct i915_address_space *vm; -- struct i915_dpt *dpt; -- size_t size; -- int ret; -- -- if (intel_fb_needs_pot_stride_remap(fb)) -- size = intel_remapped_info_size(&fb->remapped_view.gtt.remapped); -- else -- size = DIV_ROUND_UP_ULL(obj->size, I915_GTT_PAGE_SIZE); -- -- size = round_up(size * sizeof(gen8_pte_t), I915_GTT_PAGE_SIZE); -- -- if (HAS_LMEM(i915)) -- dpt_obj = i915_gem_object_create_lmem(i915, size, 0); -- else -- dpt_obj = i915_gem_object_create_stolen(i915, size); -- if (IS_ERR(dpt_obj)) -- return ERR_CAST(dpt_obj); -- -- ret = i915_gem_object_set_cache_level(dpt_obj, I915_CACHE_NONE); -- if (ret) { -- i915_gem_object_put(dpt_obj); -- return ERR_PTR(ret); -- } -- -- dpt = kzalloc(sizeof(*dpt), GFP_KERNEL); -- if (!dpt) { -- i915_gem_object_put(dpt_obj); -- return ERR_PTR(-ENOMEM); -- } -- -- vm = &dpt->vm; -- -- vm->gt = &i915->gt; -- vm->i915 = i915; -- vm->dma = i915->drm.dev; -- vm->total = (size / sizeof(gen8_pte_t)) * I915_GTT_PAGE_SIZE; -- vm->is_dpt = true; -- -- i915_address_space_init(vm, VM_CLASS_DPT); -- -- vm->insert_page = dpt_insert_page; -- vm->clear_range = dpt_clear_range; -- vm->insert_entries = dpt_insert_entries; -- vm->cleanup = dpt_cleanup; -- -- vm->vma_ops.bind_vma = dpt_bind_vma; -- vm->vma_ops.unbind_vma = dpt_unbind_vma; -- vm->vma_ops.set_pages = ggtt_set_pages; -- vm->vma_ops.clear_pages = clear_pages; -- -- vm->pte_encode = gen8_ggtt_pte_encode; -- -- dpt->obj = dpt_obj; -- -- return &dpt->vm; --} -- --static void intel_dpt_destroy(struct i915_address_space *vm) --{ -- struct i915_dpt *dpt = i915_vm_to_dpt(vm); -- -- i915_vm_close(&dpt->vm); --} -- - /* returns HPLL frequency in kHz */ - int vlv_get_hpll_vco(struct drm_i915_private *dev_priv) - { -@@ -1879,49 +1704,6 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc, - intel_wait_for_vblank(dev_priv, crtc->pipe); - } - --static struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) --{ -- struct drm_i915_private *i915 = vm->i915; -- struct i915_dpt *dpt = i915_vm_to_dpt(vm); -- intel_wakeref_t wakeref; -- struct i915_vma *vma; -- void __iomem *iomem; -- -- wakeref = intel_runtime_pm_get(&i915->runtime_pm); -- atomic_inc(&i915->gpu_error.pending_fb_pin); -- -- vma = i915_gem_object_ggtt_pin(dpt->obj, NULL, 0, 4096, -- HAS_LMEM(i915) ? 0 : PIN_MAPPABLE); -- if (IS_ERR(vma)) -- goto err; -- -- iomem = i915_vma_pin_iomap(vma); -- i915_vma_unpin(vma); -- if (IS_ERR(iomem)) { -- vma = iomem; -- goto err; -- } -- -- dpt->vma = vma; -- dpt->iomem = iomem; -- -- i915_vma_get(vma); -- --err: -- atomic_dec(&i915->gpu_error.pending_fb_pin); -- intel_runtime_pm_put(&i915->runtime_pm, wakeref); -- -- return vma; --} -- --static void intel_dpt_unpin(struct i915_address_space *vm) --{ -- struct i915_dpt *dpt = i915_vm_to_dpt(vm); -- -- i915_vma_unpin_iomap(dpt->vma); -- i915_vma_put(dpt->vma); --} -- - static bool - intel_reuse_initial_plane_obj(struct drm_i915_private *i915, - const struct intel_initial_plane_config *plane_config, -diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c -index 8fdacb252bb19..b136a0fc0963b 100644 ---- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c -+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c -@@ -13,6 +13,7 @@ - #include "intel_display_types.h" - #include "intel_dmc.h" - #include "intel_dp.h" -+#include "intel_drrs.h" - #include "intel_fbc.h" - #include "intel_hdcp.h" - #include "intel_hdmi.h" -diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h -index 6beeeeba1bed2..b56850d964919 100644 ---- a/drivers/gpu/drm/i915/display/intel_display_types.h -+++ b/drivers/gpu/drm/i915/display/intel_display_types.h -@@ -1639,6 +1639,9 @@ struct intel_dp { - struct intel_dp_pcon_frl frl; - - struct intel_psr psr; -+ -+ /* When we last wrote the OUI for eDP */ -+ unsigned long last_oui_write; - }; - - enum lspcon_vendor { -diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c -index b3c8e1c450efb..73076737add75 100644 ---- a/drivers/gpu/drm/i915/display/intel_dmc.c -+++ b/drivers/gpu/drm/i915/display/intel_dmc.c -@@ -606,7 +606,7 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv, - continue; - - offset = readcount + dmc->dmc_info[id].dmc_offset * 4; -- if (fw->size - offset < 0) { -+ if (offset > fw->size) { - drm_err(&dev_priv->drm, "Reading beyond the fw_size\n"); - continue; - } -diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c -index 5cf152be44877..dbff4b6aa22bf 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp.c -+++ b/drivers/gpu/drm/i915/display/intel_dp.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -55,6 +56,7 @@ - #include "intel_dp_mst.h" - #include "intel_dpio_phy.h" - #include "intel_dpll.h" -+#include "intel_drrs.h" - #include "intel_fifo_underrun.h" - #include "intel_hdcp.h" - #include "intel_hdmi.h" -@@ -111,6 +113,12 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp) - static void intel_dp_unset_edid(struct intel_dp *intel_dp); - static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); - -+static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp) -+{ -+ intel_dp->sink_rates[0] = 162000; -+ intel_dp->num_sink_rates = 1; -+} -+ - /* update sink rates from dpcd */ - static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) - { -@@ -1603,46 +1611,6 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp, - intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA); - } - --static void --intel_dp_drrs_compute_config(struct intel_dp *intel_dp, -- struct intel_crtc_state *pipe_config, -- int output_bpp, bool constant_n) --{ -- struct intel_connector *intel_connector = intel_dp->attached_connector; -- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -- int pixel_clock; -- -- if (pipe_config->vrr.enable) -- return; -- -- /* -- * DRRS and PSR can't be enable together, so giving preference to PSR -- * as it allows more power-savings by complete shutting down display, -- * so to guarantee this, intel_dp_drrs_compute_config() must be called -- * after intel_psr_compute_config(). -- */ -- if (pipe_config->has_psr) -- return; -- -- if (!intel_connector->panel.downclock_mode || -- dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) -- return; -- -- pipe_config->has_drrs = true; -- -- pixel_clock = intel_connector->panel.downclock_mode->clock; -- if (pipe_config->splitter.enable) -- pixel_clock /= pipe_config->splitter.link_count; -- -- intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock, -- pipe_config->port_clock, &pipe_config->dp_m2_n2, -- constant_n, pipe_config->fec_enable); -- -- /* FIXME: abstract this better */ -- if (pipe_config->splitter.enable) -- pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count; --} -- - int - intel_dp_compute_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config, -@@ -1767,6 +1735,12 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, - intel_dp->lane_count = lane_count; - } - -+static void intel_dp_reset_max_link_params(struct intel_dp *intel_dp) -+{ -+ intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); -+ intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); -+} -+ - /* Enable backlight PWM and backlight PP control. */ - void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) -@@ -1852,6 +1826,16 @@ intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful) - - if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) - drm_err(&i915->drm, "Failed to write source OUI\n"); -+ -+ intel_dp->last_oui_write = jiffies; -+} -+ -+void intel_dp_wait_source_oui(struct intel_dp *intel_dp) -+{ -+ struct drm_i915_private *i915 = dp_to_i915(intel_dp); -+ -+ drm_dbg_kms(&i915->drm, "Performing OUI wait\n"); -+ wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, 30); - } - - /* If the device supports it, try to set the power state appropriately */ -@@ -1926,8 +1910,7 @@ void intel_dp_sync_state(struct intel_encoder *encoder, - if (intel_dp->dpcd[DP_DPCD_REV] == 0) - intel_dp_get_dpcd(intel_dp); - -- intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); -- intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); -+ intel_dp_reset_max_link_params(intel_dp); - } - - bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, -@@ -2462,6 +2445,9 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) - */ - intel_psr_init_dpcd(intel_dp); - -+ /* Clear the default sink rates */ -+ intel_dp->num_sink_rates = 0; -+ - /* Read the eDP 1.4+ supported link rates. */ - if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { - __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; -@@ -2497,6 +2483,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) - intel_dp_set_sink_rates(intel_dp); - - intel_dp_set_common_rates(intel_dp); -+ intel_dp_reset_max_link_params(intel_dp); - - /* Read the eDP DSC DPCD registers */ - if (DISPLAY_VER(dev_priv) >= 10) -@@ -4240,12 +4227,7 @@ intel_dp_detect(struct drm_connector *connector, - * supports link training fallback params. - */ - if (intel_dp->reset_link_params || intel_dp->is_mst) { -- /* Initial max link lane count */ -- intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); -- -- /* Initial max link rate */ -- intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); -- -+ intel_dp_reset_max_link_params(intel_dp); - intel_dp->reset_link_params = false; - } - -@@ -4716,432 +4698,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect - drm_connector_attach_vrr_capable_property(connector); - } - --/** -- * intel_dp_set_drrs_state - program registers for RR switch to take effect -- * @dev_priv: i915 device -- * @crtc_state: a pointer to the active intel_crtc_state -- * @refresh_rate: RR to be programmed -- * -- * This function gets called when refresh rate (RR) has to be changed from -- * one frequency to another. Switches can be between high and low RR -- * supported by the panel or to any other RR based on media playback (in -- * this case, RR value needs to be passed from user space). -- * -- * The caller of this function needs to take a lock on dev_priv->drrs. -- */ --static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, -- const struct intel_crtc_state *crtc_state, -- int refresh_rate) --{ -- struct intel_dp *intel_dp = dev_priv->drrs.dp; -- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -- enum drrs_refresh_rate_type index = DRRS_HIGH_RR; -- -- if (refresh_rate <= 0) { -- drm_dbg_kms(&dev_priv->drm, -- "Refresh rate should be positive non-zero.\n"); -- return; -- } -- -- if (intel_dp == NULL) { -- drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n"); -- return; -- } -- -- if (!crtc) { -- drm_dbg_kms(&dev_priv->drm, -- "DRRS: intel_crtc not initialized\n"); -- return; -- } -- -- if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) { -- drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n"); -- return; -- } -- -- if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) == -- refresh_rate) -- index = DRRS_LOW_RR; -- -- if (index == dev_priv->drrs.refresh_rate_type) { -- drm_dbg_kms(&dev_priv->drm, -- "DRRS requested for previously set RR...ignoring\n"); -- return; -- } -- -- if (!crtc_state->hw.active) { -- drm_dbg_kms(&dev_priv->drm, -- "eDP encoder disabled. CRTC not Active\n"); -- return; -- } -- -- if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { -- switch (index) { -- case DRRS_HIGH_RR: -- intel_dp_set_m_n(crtc_state, M1_N1); -- break; -- case DRRS_LOW_RR: -- intel_dp_set_m_n(crtc_state, M2_N2); -- break; -- case DRRS_MAX_RR: -- default: -- drm_err(&dev_priv->drm, -- "Unsupported refreshrate type\n"); -- } -- } else if (DISPLAY_VER(dev_priv) > 6) { -- i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder); -- u32 val; -- -- val = intel_de_read(dev_priv, reg); -- if (index > DRRS_HIGH_RR) { -- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) -- val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; -- else -- val |= PIPECONF_EDP_RR_MODE_SWITCH; -- } else { -- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) -- val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV; -- else -- val &= ~PIPECONF_EDP_RR_MODE_SWITCH; -- } -- intel_de_write(dev_priv, reg, val); -- } -- -- dev_priv->drrs.refresh_rate_type = index; -- -- drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n", -- refresh_rate); --} -- --static void --intel_edp_drrs_enable_locked(struct intel_dp *intel_dp) --{ -- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -- -- dev_priv->drrs.busy_frontbuffer_bits = 0; -- dev_priv->drrs.dp = intel_dp; --} -- --/** -- * intel_edp_drrs_enable - init drrs struct if supported -- * @intel_dp: DP struct -- * @crtc_state: A pointer to the active crtc state. -- * -- * Initializes frontbuffer_bits and drrs.dp -- */ --void intel_edp_drrs_enable(struct intel_dp *intel_dp, -- const struct intel_crtc_state *crtc_state) --{ -- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -- -- if (!crtc_state->has_drrs) -- return; -- -- drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n"); -- -- mutex_lock(&dev_priv->drrs.mutex); -- -- if (dev_priv->drrs.dp) { -- drm_warn(&dev_priv->drm, "DRRS already enabled\n"); -- goto unlock; -- } -- -- intel_edp_drrs_enable_locked(intel_dp); -- --unlock: -- mutex_unlock(&dev_priv->drrs.mutex); --} -- --static void --intel_edp_drrs_disable_locked(struct intel_dp *intel_dp, -- const struct intel_crtc_state *crtc_state) --{ -- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -- -- if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) { -- int refresh; -- -- refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode); -- intel_dp_set_drrs_state(dev_priv, crtc_state, refresh); -- } -- -- dev_priv->drrs.dp = NULL; --} -- --/** -- * intel_edp_drrs_disable - Disable DRRS -- * @intel_dp: DP struct -- * @old_crtc_state: Pointer to old crtc_state. -- * -- */ --void intel_edp_drrs_disable(struct intel_dp *intel_dp, -- const struct intel_crtc_state *old_crtc_state) --{ -- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -- -- if (!old_crtc_state->has_drrs) -- return; -- -- mutex_lock(&dev_priv->drrs.mutex); -- if (!dev_priv->drrs.dp) { -- mutex_unlock(&dev_priv->drrs.mutex); -- return; -- } -- -- intel_edp_drrs_disable_locked(intel_dp, old_crtc_state); -- mutex_unlock(&dev_priv->drrs.mutex); -- -- cancel_delayed_work_sync(&dev_priv->drrs.work); --} -- --/** -- * intel_edp_drrs_update - Update DRRS state -- * @intel_dp: Intel DP -- * @crtc_state: new CRTC state -- * -- * This function will update DRRS states, disabling or enabling DRRS when -- * executing fastsets. For full modeset, intel_edp_drrs_disable() and -- * intel_edp_drrs_enable() should be called instead. -- */ --void --intel_edp_drrs_update(struct intel_dp *intel_dp, -- const struct intel_crtc_state *crtc_state) --{ -- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -- -- if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) -- return; -- -- mutex_lock(&dev_priv->drrs.mutex); -- -- /* New state matches current one? */ -- if (crtc_state->has_drrs == !!dev_priv->drrs.dp) -- goto unlock; -- -- if (crtc_state->has_drrs) -- intel_edp_drrs_enable_locked(intel_dp); -- else -- intel_edp_drrs_disable_locked(intel_dp, crtc_state); -- --unlock: -- mutex_unlock(&dev_priv->drrs.mutex); --} -- --static void intel_edp_drrs_downclock_work(struct work_struct *work) --{ -- struct drm_i915_private *dev_priv = -- container_of(work, typeof(*dev_priv), drrs.work.work); -- struct intel_dp *intel_dp; -- -- mutex_lock(&dev_priv->drrs.mutex); -- -- intel_dp = dev_priv->drrs.dp; -- -- if (!intel_dp) -- goto unlock; -- -- /* -- * The delayed work can race with an invalidate hence we need to -- * recheck. -- */ -- -- if (dev_priv->drrs.busy_frontbuffer_bits) -- goto unlock; -- -- if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) { -- struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; -- -- intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, -- drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); -- } -- --unlock: -- mutex_unlock(&dev_priv->drrs.mutex); --} -- --/** -- * intel_edp_drrs_invalidate - Disable Idleness DRRS -- * @dev_priv: i915 device -- * @frontbuffer_bits: frontbuffer plane tracking bits -- * -- * This function gets called everytime rendering on the given planes start. -- * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR). -- * -- * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. -- */ --void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, -- unsigned int frontbuffer_bits) --{ -- struct intel_dp *intel_dp; -- struct drm_crtc *crtc; -- enum pipe pipe; -- -- if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) -- return; -- -- cancel_delayed_work(&dev_priv->drrs.work); -- -- mutex_lock(&dev_priv->drrs.mutex); -- -- intel_dp = dev_priv->drrs.dp; -- if (!intel_dp) { -- mutex_unlock(&dev_priv->drrs.mutex); -- return; -- } -- -- crtc = dp_to_dig_port(intel_dp)->base.base.crtc; -- pipe = to_intel_crtc(crtc)->pipe; -- -- frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); -- dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; -- -- /* invalidate means busy screen hence upclock */ -- if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) -- intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, -- drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); -- -- mutex_unlock(&dev_priv->drrs.mutex); --} -- --/** -- * intel_edp_drrs_flush - Restart Idleness DRRS -- * @dev_priv: i915 device -- * @frontbuffer_bits: frontbuffer plane tracking bits -- * -- * This function gets called every time rendering on the given planes has -- * completed or flip on a crtc is completed. So DRRS should be upclocked -- * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again, -- * if no other planes are dirty. -- * -- * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. -- */ --void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, -- unsigned int frontbuffer_bits) --{ -- struct intel_dp *intel_dp; -- struct drm_crtc *crtc; -- enum pipe pipe; -- -- if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) -- return; -- -- cancel_delayed_work(&dev_priv->drrs.work); -- -- mutex_lock(&dev_priv->drrs.mutex); -- -- intel_dp = dev_priv->drrs.dp; -- if (!intel_dp) { -- mutex_unlock(&dev_priv->drrs.mutex); -- return; -- } -- -- crtc = dp_to_dig_port(intel_dp)->base.base.crtc; -- pipe = to_intel_crtc(crtc)->pipe; -- -- frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); -- dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; -- -- /* flush means busy screen hence upclock */ -- if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) -- intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, -- drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); -- -- /* -- * flush also means no more activity hence schedule downclock, if all -- * other fbs are quiescent too -- */ -- if (!dev_priv->drrs.busy_frontbuffer_bits) -- schedule_delayed_work(&dev_priv->drrs.work, -- msecs_to_jiffies(1000)); -- mutex_unlock(&dev_priv->drrs.mutex); --} -- --/** -- * DOC: Display Refresh Rate Switching (DRRS) -- * -- * Display Refresh Rate Switching (DRRS) is a power conservation feature -- * which enables swtching between low and high refresh rates, -- * dynamically, based on the usage scenario. This feature is applicable -- * for internal panels. -- * -- * Indication that the panel supports DRRS is given by the panel EDID, which -- * would list multiple refresh rates for one resolution. -- * -- * DRRS is of 2 types - static and seamless. -- * Static DRRS involves changing refresh rate (RR) by doing a full modeset -- * (may appear as a blink on screen) and is used in dock-undock scenario. -- * Seamless DRRS involves changing RR without any visual effect to the user -- * and can be used during normal system usage. This is done by programming -- * certain registers. -- * -- * Support for static/seamless DRRS may be indicated in the VBT based on -- * inputs from the panel spec. -- * -- * DRRS saves power by switching to low RR based on usage scenarios. -- * -- * The implementation is based on frontbuffer tracking implementation. When -- * there is a disturbance on the screen triggered by user activity or a periodic -- * system activity, DRRS is disabled (RR is changed to high RR). When there is -- * no movement on screen, after a timeout of 1 second, a switch to low RR is -- * made. -- * -- * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate() -- * and intel_edp_drrs_flush() are called. -- * -- * DRRS can be further extended to support other internal panels and also -- * the scenario of video playback wherein RR is set based on the rate -- * requested by userspace. -- */ -- --/** -- * intel_dp_drrs_init - Init basic DRRS work and mutex. -- * @connector: eDP connector -- * @fixed_mode: preferred mode of panel -- * -- * This function is called only once at driver load to initialize basic -- * DRRS stuff. -- * -- * Returns: -- * Downclock mode if panel supports it, else return NULL. -- * DRRS support is determined by the presence of downclock mode (apart -- * from VBT setting). -- */ --static struct drm_display_mode * --intel_dp_drrs_init(struct intel_connector *connector, -- struct drm_display_mode *fixed_mode) --{ -- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); -- struct drm_display_mode *downclock_mode = NULL; -- -- INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); -- mutex_init(&dev_priv->drrs.mutex); -- -- if (DISPLAY_VER(dev_priv) <= 6) { -- drm_dbg_kms(&dev_priv->drm, -- "DRRS supported for Gen7 and above\n"); -- return NULL; -- } -- -- if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) { -- drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n"); -- return NULL; -- } -- -- downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode); -- if (!downclock_mode) { -- drm_dbg_kms(&dev_priv->drm, -- "Downclock mode is not found. DRRS not supported\n"); -- return NULL; -- } -- -- dev_priv->drrs.type = dev_priv->vbt.drrs_type; -- -- dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR; -- drm_dbg_kms(&dev_priv->drm, -- "seamless DRRS supported for eDP panel.\n"); -- return downclock_mode; --} -- - static bool intel_edp_init_connector(struct intel_dp *intel_dp, - struct intel_connector *intel_connector) - { -@@ -5296,6 +4852,9 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, - return false; - - intel_dp_set_source_rates(intel_dp); -+ intel_dp_set_default_sink_rates(intel_dp); -+ intel_dp_set_common_rates(intel_dp); -+ intel_dp_reset_max_link_params(intel_dp); - - intel_dp->reset_link_params = true; - intel_dp->pps.pps_pipe = INVALID_PIPE; -diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h -index 680631b5b4378..3dd6ebc2f6b14 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp.h -+++ b/drivers/gpu/drm/i915/display/intel_dp.h -@@ -70,17 +70,6 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp); - int intel_dp_max_lane_count(struct intel_dp *intel_dp); - int intel_dp_rate_select(struct intel_dp *intel_dp, int rate); - --void intel_edp_drrs_enable(struct intel_dp *intel_dp, -- const struct intel_crtc_state *crtc_state); --void intel_edp_drrs_disable(struct intel_dp *intel_dp, -- const struct intel_crtc_state *crtc_state); --void intel_edp_drrs_update(struct intel_dp *intel_dp, -- const struct intel_crtc_state *crtc_state); --void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, -- unsigned int frontbuffer_bits); --void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, -- unsigned int frontbuffer_bits); -- - void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, - u8 *link_bw, u8 *rate_select); - bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); -@@ -129,4 +118,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); - void intel_dp_phy_test(struct intel_encoder *encoder); - -+void intel_dp_wait_source_oui(struct intel_dp *intel_dp); -+ - #endif /* __INTEL_DP_H__ */ -diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -index 6ac568617ef37..c82f8febe7303 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -@@ -35,6 +35,7 @@ - */ - - #include "intel_display_types.h" -+#include "intel_dp.h" - #include "intel_dp_aux_backlight.h" - #include "intel_panel.h" - -@@ -106,6 +107,8 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) - int ret; - u8 tcon_cap[4]; - -+ intel_dp_wait_source_oui(intel_dp); -+ - ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap)); - if (ret != sizeof(tcon_cap)) - return false; -@@ -204,6 +207,8 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state, - int ret; - u8 old_ctrl, ctrl; - -+ intel_dp_wait_source_oui(intel_dp); -+ - ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl); - if (ret != 1) { - drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret); -diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c -new file mode 100644 -index 0000000000000..22acd945a9e47 ---- /dev/null -+++ b/drivers/gpu/drm/i915/display/intel_dpt.c -@@ -0,0 +1,229 @@ -+// SPDX-License-Identifier: MIT -+/* -+ * Copyright © 2021 Intel Corporation -+ */ -+ -+#include "i915_drv.h" -+#include "intel_display_types.h" -+#include "intel_dpt.h" -+#include "intel_fb.h" -+#include "gt/gen8_ppgtt.h" -+ -+struct i915_dpt { -+ struct i915_address_space vm; -+ -+ struct drm_i915_gem_object *obj; -+ struct i915_vma *vma; -+ void __iomem *iomem; -+}; -+ -+#define i915_is_dpt(vm) ((vm)->is_dpt) -+ -+static inline struct i915_dpt * -+i915_vm_to_dpt(struct i915_address_space *vm) -+{ -+ BUILD_BUG_ON(offsetof(struct i915_dpt, vm)); -+ GEM_BUG_ON(!i915_is_dpt(vm)); -+ return container_of(vm, struct i915_dpt, vm); -+} -+ -+#define dpt_total_entries(dpt) ((dpt)->vm.total >> PAGE_SHIFT) -+ -+static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) -+{ -+ writeq(pte, addr); -+} -+ -+static void dpt_insert_page(struct i915_address_space *vm, -+ dma_addr_t addr, -+ u64 offset, -+ enum i915_cache_level level, -+ u32 flags) -+{ -+ struct i915_dpt *dpt = i915_vm_to_dpt(vm); -+ gen8_pte_t __iomem *base = dpt->iomem; -+ -+ gen8_set_pte(base + offset / I915_GTT_PAGE_SIZE, -+ vm->pte_encode(addr, level, flags)); -+} -+ -+static void dpt_insert_entries(struct i915_address_space *vm, -+ struct i915_vma *vma, -+ enum i915_cache_level level, -+ u32 flags) -+{ -+ struct i915_dpt *dpt = i915_vm_to_dpt(vm); -+ gen8_pte_t __iomem *base = dpt->iomem; -+ const gen8_pte_t pte_encode = vm->pte_encode(0, level, flags); -+ struct sgt_iter sgt_iter; -+ dma_addr_t addr; -+ int i; -+ -+ /* -+ * Note that we ignore PTE_READ_ONLY here. The caller must be careful -+ * not to allow the user to override access to a read only page. -+ */ -+ -+ i = vma->node.start / I915_GTT_PAGE_SIZE; -+ for_each_sgt_daddr(addr, sgt_iter, vma->pages) -+ gen8_set_pte(&base[i++], pte_encode | addr); -+} -+ -+static void dpt_clear_range(struct i915_address_space *vm, -+ u64 start, u64 length) -+{ -+} -+ -+static void dpt_bind_vma(struct i915_address_space *vm, -+ struct i915_vm_pt_stash *stash, -+ struct i915_vma *vma, -+ enum i915_cache_level cache_level, -+ u32 flags) -+{ -+ struct drm_i915_gem_object *obj = vma->obj; -+ u32 pte_flags; -+ -+ /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ -+ pte_flags = 0; -+ if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj)) -+ pte_flags |= PTE_READ_ONLY; -+ if (i915_gem_object_is_lmem(obj)) -+ pte_flags |= PTE_LM; -+ -+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); -+ -+ vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; -+ -+ /* -+ * Without aliasing PPGTT there's no difference between -+ * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally -+ * upgrade to both bound if we bind either to avoid double-binding. -+ */ -+ atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags); -+} -+ -+static void dpt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) -+{ -+ vm->clear_range(vm, vma->node.start, vma->size); -+} -+ -+static void dpt_cleanup(struct i915_address_space *vm) -+{ -+ struct i915_dpt *dpt = i915_vm_to_dpt(vm); -+ -+ i915_gem_object_put(dpt->obj); -+} -+ -+struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) -+{ -+ struct drm_i915_private *i915 = vm->i915; -+ struct i915_dpt *dpt = i915_vm_to_dpt(vm); -+ intel_wakeref_t wakeref; -+ struct i915_vma *vma; -+ void __iomem *iomem; -+ -+ wakeref = intel_runtime_pm_get(&i915->runtime_pm); -+ atomic_inc(&i915->gpu_error.pending_fb_pin); -+ -+ vma = i915_gem_object_ggtt_pin(dpt->obj, NULL, 0, 4096, -+ HAS_LMEM(i915) ? 0 : PIN_MAPPABLE); -+ if (IS_ERR(vma)) -+ goto err; -+ -+ iomem = i915_vma_pin_iomap(vma); -+ i915_vma_unpin(vma); -+ if (IS_ERR(iomem)) { -+ vma = iomem; -+ goto err; -+ } -+ -+ dpt->vma = vma; -+ dpt->iomem = iomem; -+ -+ i915_vma_get(vma); -+ -+err: -+ atomic_dec(&i915->gpu_error.pending_fb_pin); -+ intel_runtime_pm_put(&i915->runtime_pm, wakeref); -+ -+ return vma; -+} -+ -+void intel_dpt_unpin(struct i915_address_space *vm) -+{ -+ struct i915_dpt *dpt = i915_vm_to_dpt(vm); -+ -+ i915_vma_unpin_iomap(dpt->vma); -+ i915_vma_put(dpt->vma); -+} -+ -+struct i915_address_space * -+intel_dpt_create(struct intel_framebuffer *fb) -+{ -+ struct drm_gem_object *obj = &intel_fb_obj(&fb->base)->base; -+ struct drm_i915_private *i915 = to_i915(obj->dev); -+ struct drm_i915_gem_object *dpt_obj; -+ struct i915_address_space *vm; -+ struct i915_dpt *dpt; -+ size_t size; -+ int ret; -+ -+ if (intel_fb_needs_pot_stride_remap(fb)) -+ size = intel_remapped_info_size(&fb->remapped_view.gtt.remapped); -+ else -+ size = DIV_ROUND_UP_ULL(obj->size, I915_GTT_PAGE_SIZE); -+ -+ size = round_up(size * sizeof(gen8_pte_t), I915_GTT_PAGE_SIZE); -+ -+ if (HAS_LMEM(i915)) -+ dpt_obj = i915_gem_object_create_lmem(i915, size, 0); -+ else -+ dpt_obj = i915_gem_object_create_stolen(i915, size); -+ if (IS_ERR(dpt_obj)) -+ return ERR_CAST(dpt_obj); -+ -+ ret = i915_gem_object_set_cache_level(dpt_obj, I915_CACHE_NONE); -+ if (ret) { -+ i915_gem_object_put(dpt_obj); -+ return ERR_PTR(ret); -+ } -+ -+ dpt = kzalloc(sizeof(*dpt), GFP_KERNEL); -+ if (!dpt) { -+ i915_gem_object_put(dpt_obj); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ vm = &dpt->vm; -+ -+ vm->gt = &i915->gt; -+ vm->i915 = i915; -+ vm->dma = i915->drm.dev; -+ vm->total = (size / sizeof(gen8_pte_t)) * I915_GTT_PAGE_SIZE; -+ vm->is_dpt = true; -+ -+ i915_address_space_init(vm, VM_CLASS_DPT); -+ -+ vm->insert_page = dpt_insert_page; -+ vm->clear_range = dpt_clear_range; -+ vm->insert_entries = dpt_insert_entries; -+ vm->cleanup = dpt_cleanup; -+ -+ vm->vma_ops.bind_vma = dpt_bind_vma; -+ vm->vma_ops.unbind_vma = dpt_unbind_vma; -+ vm->vma_ops.set_pages = ggtt_set_pages; -+ vm->vma_ops.clear_pages = clear_pages; -+ -+ vm->pte_encode = gen8_ggtt_pte_encode; -+ -+ dpt->obj = dpt_obj; -+ -+ return &dpt->vm; -+} -+ -+void intel_dpt_destroy(struct i915_address_space *vm) -+{ -+ struct i915_dpt *dpt = i915_vm_to_dpt(vm); -+ -+ i915_vm_close(&dpt->vm); -+} -diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h -new file mode 100644 -index 0000000000000..45142b8f849f6 ---- /dev/null -+++ b/drivers/gpu/drm/i915/display/intel_dpt.h -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: MIT */ -+/* -+ * Copyright © 2021 Intel Corporation -+ */ -+ -+#ifndef __INTEL_DPT_H__ -+#define __INTEL_DPT_H__ -+ -+struct i915_address_space; -+struct i915_vma; -+struct intel_framebuffer; -+ -+void intel_dpt_destroy(struct i915_address_space *vm); -+struct i915_vma *intel_dpt_pin(struct i915_address_space *vm); -+void intel_dpt_unpin(struct i915_address_space *vm); -+struct i915_address_space * -+intel_dpt_create(struct intel_framebuffer *fb); -+ -+#endif /* __INTEL_DPT_H__ */ -diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c -new file mode 100644 -index 0000000000000..3c7d6bf579484 ---- /dev/null -+++ b/drivers/gpu/drm/i915/display/intel_drrs.c -@@ -0,0 +1,485 @@ -+// SPDX-License-Identifier: MIT -+/* -+ * Copyright © 2021 Intel Corporation -+ */ -+ -+#include "i915_drv.h" -+#include "intel_atomic.h" -+#include "intel_de.h" -+#include "intel_display_types.h" -+#include "intel_drrs.h" -+#include "intel_panel.h" -+ -+/** -+ * DOC: Display Refresh Rate Switching (DRRS) -+ * -+ * Display Refresh Rate Switching (DRRS) is a power conservation feature -+ * which enables swtching between low and high refresh rates, -+ * dynamically, based on the usage scenario. This feature is applicable -+ * for internal panels. -+ * -+ * Indication that the panel supports DRRS is given by the panel EDID, which -+ * would list multiple refresh rates for one resolution. -+ * -+ * DRRS is of 2 types - static and seamless. -+ * Static DRRS involves changing refresh rate (RR) by doing a full modeset -+ * (may appear as a blink on screen) and is used in dock-undock scenario. -+ * Seamless DRRS involves changing RR without any visual effect to the user -+ * and can be used during normal system usage. This is done by programming -+ * certain registers. -+ * -+ * Support for static/seamless DRRS may be indicated in the VBT based on -+ * inputs from the panel spec. -+ * -+ * DRRS saves power by switching to low RR based on usage scenarios. -+ * -+ * The implementation is based on frontbuffer tracking implementation. When -+ * there is a disturbance on the screen triggered by user activity or a periodic -+ * system activity, DRRS is disabled (RR is changed to high RR). When there is -+ * no movement on screen, after a timeout of 1 second, a switch to low RR is -+ * made. -+ * -+ * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate() -+ * and intel_edp_drrs_flush() are called. -+ * -+ * DRRS can be further extended to support other internal panels and also -+ * the scenario of video playback wherein RR is set based on the rate -+ * requested by userspace. -+ */ -+ -+void -+intel_dp_drrs_compute_config(struct intel_dp *intel_dp, -+ struct intel_crtc_state *pipe_config, -+ int output_bpp, bool constant_n) -+{ -+ struct intel_connector *intel_connector = intel_dp->attached_connector; -+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -+ int pixel_clock; -+ -+ if (pipe_config->vrr.enable) -+ return; -+ -+ /* -+ * DRRS and PSR can't be enable together, so giving preference to PSR -+ * as it allows more power-savings by complete shutting down display, -+ * so to guarantee this, intel_dp_drrs_compute_config() must be called -+ * after intel_psr_compute_config(). -+ */ -+ if (pipe_config->has_psr) -+ return; -+ -+ if (!intel_connector->panel.downclock_mode || -+ dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) -+ return; -+ -+ pipe_config->has_drrs = true; -+ -+ pixel_clock = intel_connector->panel.downclock_mode->clock; -+ if (pipe_config->splitter.enable) -+ pixel_clock /= pipe_config->splitter.link_count; -+ -+ intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock, -+ pipe_config->port_clock, &pipe_config->dp_m2_n2, -+ constant_n, pipe_config->fec_enable); -+ -+ /* FIXME: abstract this better */ -+ if (pipe_config->splitter.enable) -+ pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count; -+} -+ -+/** -+ * intel_dp_set_drrs_state - program registers for RR switch to take effect -+ * @dev_priv: i915 device -+ * @crtc_state: a pointer to the active intel_crtc_state -+ * @refresh_rate: RR to be programmed -+ * -+ * This function gets called when refresh rate (RR) has to be changed from -+ * one frequency to another. Switches can be between high and low RR -+ * supported by the panel or to any other RR based on media playback (in -+ * this case, RR value needs to be passed from user space). -+ * -+ * The caller of this function needs to take a lock on dev_priv->drrs. -+ */ -+static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, -+ const struct intel_crtc_state *crtc_state, -+ int refresh_rate) -+{ -+ struct intel_dp *intel_dp = dev_priv->drrs.dp; -+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -+ enum drrs_refresh_rate_type index = DRRS_HIGH_RR; -+ -+ if (refresh_rate <= 0) { -+ drm_dbg_kms(&dev_priv->drm, -+ "Refresh rate should be positive non-zero.\n"); -+ return; -+ } -+ -+ if (intel_dp == NULL) { -+ drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n"); -+ return; -+ } -+ -+ if (!crtc) { -+ drm_dbg_kms(&dev_priv->drm, -+ "DRRS: intel_crtc not initialized\n"); -+ return; -+ } -+ -+ if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) { -+ drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n"); -+ return; -+ } -+ -+ if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) == -+ refresh_rate) -+ index = DRRS_LOW_RR; -+ -+ if (index == dev_priv->drrs.refresh_rate_type) { -+ drm_dbg_kms(&dev_priv->drm, -+ "DRRS requested for previously set RR...ignoring\n"); -+ return; -+ } -+ -+ if (!crtc_state->hw.active) { -+ drm_dbg_kms(&dev_priv->drm, -+ "eDP encoder disabled. CRTC not Active\n"); -+ return; -+ } -+ -+ if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { -+ switch (index) { -+ case DRRS_HIGH_RR: -+ intel_dp_set_m_n(crtc_state, M1_N1); -+ break; -+ case DRRS_LOW_RR: -+ intel_dp_set_m_n(crtc_state, M2_N2); -+ break; -+ case DRRS_MAX_RR: -+ default: -+ drm_err(&dev_priv->drm, -+ "Unsupported refreshrate type\n"); -+ } -+ } else if (DISPLAY_VER(dev_priv) > 6) { -+ i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder); -+ u32 val; -+ -+ val = intel_de_read(dev_priv, reg); -+ if (index > DRRS_HIGH_RR) { -+ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) -+ val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; -+ else -+ val |= PIPECONF_EDP_RR_MODE_SWITCH; -+ } else { -+ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) -+ val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV; -+ else -+ val &= ~PIPECONF_EDP_RR_MODE_SWITCH; -+ } -+ intel_de_write(dev_priv, reg, val); -+ } -+ -+ dev_priv->drrs.refresh_rate_type = index; -+ -+ drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n", -+ refresh_rate); -+} -+ -+static void -+intel_edp_drrs_enable_locked(struct intel_dp *intel_dp) -+{ -+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -+ -+ dev_priv->drrs.busy_frontbuffer_bits = 0; -+ dev_priv->drrs.dp = intel_dp; -+} -+ -+/** -+ * intel_edp_drrs_enable - init drrs struct if supported -+ * @intel_dp: DP struct -+ * @crtc_state: A pointer to the active crtc state. -+ * -+ * Initializes frontbuffer_bits and drrs.dp -+ */ -+void intel_edp_drrs_enable(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *crtc_state) -+{ -+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -+ -+ if (!crtc_state->has_drrs) -+ return; -+ -+ drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n"); -+ -+ mutex_lock(&dev_priv->drrs.mutex); -+ -+ if (dev_priv->drrs.dp) { -+ drm_warn(&dev_priv->drm, "DRRS already enabled\n"); -+ goto unlock; -+ } -+ -+ intel_edp_drrs_enable_locked(intel_dp); -+ -+unlock: -+ mutex_unlock(&dev_priv->drrs.mutex); -+} -+ -+static void -+intel_edp_drrs_disable_locked(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *crtc_state) -+{ -+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -+ -+ if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) { -+ int refresh; -+ -+ refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode); -+ intel_dp_set_drrs_state(dev_priv, crtc_state, refresh); -+ } -+ -+ dev_priv->drrs.dp = NULL; -+} -+ -+/** -+ * intel_edp_drrs_disable - Disable DRRS -+ * @intel_dp: DP struct -+ * @old_crtc_state: Pointer to old crtc_state. -+ * -+ */ -+void intel_edp_drrs_disable(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *old_crtc_state) -+{ -+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -+ -+ if (!old_crtc_state->has_drrs) -+ return; -+ -+ mutex_lock(&dev_priv->drrs.mutex); -+ if (!dev_priv->drrs.dp) { -+ mutex_unlock(&dev_priv->drrs.mutex); -+ return; -+ } -+ -+ intel_edp_drrs_disable_locked(intel_dp, old_crtc_state); -+ mutex_unlock(&dev_priv->drrs.mutex); -+ -+ cancel_delayed_work_sync(&dev_priv->drrs.work); -+} -+ -+/** -+ * intel_edp_drrs_update - Update DRRS state -+ * @intel_dp: Intel DP -+ * @crtc_state: new CRTC state -+ * -+ * This function will update DRRS states, disabling or enabling DRRS when -+ * executing fastsets. For full modeset, intel_edp_drrs_disable() and -+ * intel_edp_drrs_enable() should be called instead. -+ */ -+void -+intel_edp_drrs_update(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *crtc_state) -+{ -+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); -+ -+ if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) -+ return; -+ -+ mutex_lock(&dev_priv->drrs.mutex); -+ -+ /* New state matches current one? */ -+ if (crtc_state->has_drrs == !!dev_priv->drrs.dp) -+ goto unlock; -+ -+ if (crtc_state->has_drrs) -+ intel_edp_drrs_enable_locked(intel_dp); -+ else -+ intel_edp_drrs_disable_locked(intel_dp, crtc_state); -+ -+unlock: -+ mutex_unlock(&dev_priv->drrs.mutex); -+} -+ -+static void intel_edp_drrs_downclock_work(struct work_struct *work) -+{ -+ struct drm_i915_private *dev_priv = -+ container_of(work, typeof(*dev_priv), drrs.work.work); -+ struct intel_dp *intel_dp; -+ -+ mutex_lock(&dev_priv->drrs.mutex); -+ -+ intel_dp = dev_priv->drrs.dp; -+ -+ if (!intel_dp) -+ goto unlock; -+ -+ /* -+ * The delayed work can race with an invalidate hence we need to -+ * recheck. -+ */ -+ -+ if (dev_priv->drrs.busy_frontbuffer_bits) -+ goto unlock; -+ -+ if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) { -+ struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; -+ -+ intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, -+ drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); -+ } -+ -+unlock: -+ mutex_unlock(&dev_priv->drrs.mutex); -+} -+ -+/** -+ * intel_edp_drrs_invalidate - Disable Idleness DRRS -+ * @dev_priv: i915 device -+ * @frontbuffer_bits: frontbuffer plane tracking bits -+ * -+ * This function gets called everytime rendering on the given planes start. -+ * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR). -+ * -+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. -+ */ -+void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, -+ unsigned int frontbuffer_bits) -+{ -+ struct intel_dp *intel_dp; -+ struct drm_crtc *crtc; -+ enum pipe pipe; -+ -+ if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) -+ return; -+ -+ cancel_delayed_work(&dev_priv->drrs.work); -+ -+ mutex_lock(&dev_priv->drrs.mutex); -+ -+ intel_dp = dev_priv->drrs.dp; -+ if (!intel_dp) { -+ mutex_unlock(&dev_priv->drrs.mutex); -+ return; -+ } -+ -+ crtc = dp_to_dig_port(intel_dp)->base.base.crtc; -+ pipe = to_intel_crtc(crtc)->pipe; -+ -+ frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); -+ dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; -+ -+ /* invalidate means busy screen hence upclock */ -+ if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) -+ intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, -+ drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); -+ -+ mutex_unlock(&dev_priv->drrs.mutex); -+} -+ -+/** -+ * intel_edp_drrs_flush - Restart Idleness DRRS -+ * @dev_priv: i915 device -+ * @frontbuffer_bits: frontbuffer plane tracking bits -+ * -+ * This function gets called every time rendering on the given planes has -+ * completed or flip on a crtc is completed. So DRRS should be upclocked -+ * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again, -+ * if no other planes are dirty. -+ * -+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. -+ */ -+void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, -+ unsigned int frontbuffer_bits) -+{ -+ struct intel_dp *intel_dp; -+ struct drm_crtc *crtc; -+ enum pipe pipe; -+ -+ if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) -+ return; -+ -+ cancel_delayed_work(&dev_priv->drrs.work); -+ -+ mutex_lock(&dev_priv->drrs.mutex); -+ -+ intel_dp = dev_priv->drrs.dp; -+ if (!intel_dp) { -+ mutex_unlock(&dev_priv->drrs.mutex); -+ return; -+ } -+ -+ crtc = dp_to_dig_port(intel_dp)->base.base.crtc; -+ pipe = to_intel_crtc(crtc)->pipe; -+ -+ frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); -+ dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; -+ -+ /* flush means busy screen hence upclock */ -+ if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) -+ intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, -+ drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); -+ -+ /* -+ * flush also means no more activity hence schedule downclock, if all -+ * other fbs are quiescent too -+ */ -+ if (!dev_priv->drrs.busy_frontbuffer_bits) -+ schedule_delayed_work(&dev_priv->drrs.work, -+ msecs_to_jiffies(1000)); -+ mutex_unlock(&dev_priv->drrs.mutex); -+} -+ -+/** -+ * intel_dp_drrs_init - Init basic DRRS work and mutex. -+ * @connector: eDP connector -+ * @fixed_mode: preferred mode of panel -+ * -+ * This function is called only once at driver load to initialize basic -+ * DRRS stuff. -+ * -+ * Returns: -+ * Downclock mode if panel supports it, else return NULL. -+ * DRRS support is determined by the presence of downclock mode (apart -+ * from VBT setting). -+ */ -+struct drm_display_mode * -+intel_dp_drrs_init(struct intel_connector *connector, -+ struct drm_display_mode *fixed_mode) -+{ -+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev); -+ struct intel_encoder *encoder = connector->encoder; -+ struct drm_display_mode *downclock_mode = NULL; -+ -+ INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); -+ mutex_init(&dev_priv->drrs.mutex); -+ -+ if (DISPLAY_VER(dev_priv) <= 6) { -+ drm_dbg_kms(&dev_priv->drm, -+ "DRRS supported for Gen7 and above\n"); -+ return NULL; -+ } -+ -+ if ((DISPLAY_VER(dev_priv) < 8 && !HAS_GMCH(dev_priv)) && -+ encoder->port != PORT_A) { -+ drm_dbg_kms(&dev_priv->drm, -+ "DRRS only supported on eDP port A\n"); -+ return NULL; -+ } -+ -+ if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) { -+ drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n"); -+ return NULL; -+ } -+ -+ downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode); -+ if (!downclock_mode) { -+ drm_dbg_kms(&dev_priv->drm, -+ "Downclock mode is not found. DRRS not supported\n"); -+ return NULL; -+ } -+ -+ dev_priv->drrs.type = dev_priv->vbt.drrs_type; -+ -+ dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR; -+ drm_dbg_kms(&dev_priv->drm, -+ "seamless DRRS supported for eDP panel.\n"); -+ return downclock_mode; -+} -diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h -new file mode 100644 -index 0000000000000..ffa175b4cf4f4 ---- /dev/null -+++ b/drivers/gpu/drm/i915/display/intel_drrs.h -@@ -0,0 +1,32 @@ -+/* SPDX-License-Identifier: MIT */ -+/* -+ * Copyright © 2021 Intel Corporation -+ */ -+ -+#ifndef __INTEL_DRRS_H__ -+#define __INTEL_DRRS_H__ -+ -+#include -+ -+struct drm_i915_private; -+struct intel_crtc_state; -+struct intel_connector; -+struct intel_dp; -+ -+void intel_edp_drrs_enable(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *crtc_state); -+void intel_edp_drrs_disable(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *crtc_state); -+void intel_edp_drrs_update(struct intel_dp *intel_dp, -+ const struct intel_crtc_state *crtc_state); -+void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, -+ unsigned int frontbuffer_bits); -+void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, -+ unsigned int frontbuffer_bits); -+void intel_dp_drrs_compute_config(struct intel_dp *intel_dp, -+ struct intel_crtc_state *pipe_config, -+ int output_bpp, bool constant_n); -+struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector, -+ struct drm_display_mode *fixed_mode); -+ -+#endif /* __INTEL_DRRS_H__ */ -diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c -index c60a81a81c09c..c6413c5409420 100644 ---- a/drivers/gpu/drm/i915/display/intel_fb.c -+++ b/drivers/gpu/drm/i915/display/intel_fb.c -@@ -172,8 +172,9 @@ static void intel_fb_plane_dims(const struct intel_framebuffer *fb, int color_pl - - intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, &fb->base, main_plane); - intel_fb_plane_get_subsampling(&hsub, &vsub, &fb->base, color_plane); -- *w = fb->base.width / main_hsub / hsub; -- *h = fb->base.height / main_vsub / vsub; -+ -+ *w = DIV_ROUND_UP(fb->base.width, main_hsub * hsub); -+ *h = DIV_ROUND_UP(fb->base.height, main_vsub * vsub); - } - - static u32 intel_adjust_tile_offset(int *x, int *y, -diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c -index 8e75debcce1a9..e4834d84ce5e3 100644 ---- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c -+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c -@@ -62,6 +62,7 @@ - #include "intel_display_types.h" - #include "intel_fbc.h" - #include "intel_frontbuffer.h" -+#include "intel_drrs.h" - #include "intel_psr.h" - - /** -diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c -index b04685bb6439c..c3787512295dd 100644 ---- a/drivers/gpu/drm/i915/display/intel_hdmi.c -+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c -@@ -53,21 +53,20 @@ - #include "intel_panel.h" - #include "intel_snps_phy.h" - --static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) -+static struct drm_i915_private *intel_hdmi_to_i915(struct intel_hdmi *intel_hdmi) - { -- return hdmi_to_dig_port(intel_hdmi)->base.base.dev; -+ return to_i915(hdmi_to_dig_port(intel_hdmi)->base.base.dev); - } - - static void - assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) - { -- struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); -- struct drm_i915_private *dev_priv = to_i915(dev); -+ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(intel_hdmi); - u32 enabled_bits; - - enabled_bits = HAS_DDI(dev_priv) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; - -- drm_WARN(dev, -+ drm_WARN(&dev_priv->drm, - intel_de_read(dev_priv, intel_hdmi->hdmi_reg) & enabled_bits, - "HDMI port enabled, expecting disabled\n"); - } -@@ -1246,13 +1245,14 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, - - void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) - { -- struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); -- struct i2c_adapter *adapter = -- intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); -+ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); -+ struct i2c_adapter *adapter; - - if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI) - return; - -+ adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); -+ - drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n", - enable ? "Enabling" : "Disabling"); - -@@ -1830,7 +1830,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, - int clock, bool respect_downstream_limits, - bool has_hdmi_sink) - { -- struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); -+ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); - - if (clock < 25000) - return MODE_CLOCK_LOW; -@@ -1946,8 +1946,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { - struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); -- struct drm_device *dev = intel_hdmi_to_dev(hdmi); -- struct drm_i915_private *dev_priv = to_i915(dev); -+ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); - enum drm_mode_status status; - int clock = mode->clock; - int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; -@@ -2260,6 +2259,17 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, - return 0; - } - -+void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder) -+{ -+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); -+ -+ /* -+ * Give a hand to buggy BIOSen which forget to turn -+ * the TMDS output buffers back on after a reboot. -+ */ -+ intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); -+} -+ - static void - intel_hdmi_unset_edid(struct drm_connector *connector) - { -diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h -index b43a180d007e0..2bf440eb400ab 100644 ---- a/drivers/gpu/drm/i915/display/intel_hdmi.h -+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h -@@ -28,6 +28,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, - int intel_hdmi_compute_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config, - struct drm_connector_state *conn_state); -+void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder); - bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, - struct drm_connector *connector, - bool high_tmds_clock_ratio, -diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c -index 3855fba709807..f7f49b69830fa 100644 ---- a/drivers/gpu/drm/i915/display/intel_opregion.c -+++ b/drivers/gpu/drm/i915/display/intel_opregion.c -@@ -361,6 +361,21 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, - port++; - } - -+ /* -+ * The port numbering and mapping here is bizarre. The now-obsolete -+ * swsci spec supports ports numbered [0..4]. Port E is handled as a -+ * special case, but port F and beyond are not. The functionality is -+ * supposed to be obsolete for new platforms. Just bail out if the port -+ * number is out of bounds after mapping. -+ */ -+ if (port > 4) { -+ drm_dbg_kms(&dev_priv->drm, -+ "[ENCODER:%d:%s] port %c (index %u) out of bounds for display power state notification\n", -+ intel_encoder->base.base.id, intel_encoder->base.name, -+ port_name(intel_encoder->port), port); -+ return -EINVAL; -+ } -+ - if (!enable) - parm |= 4 << 8; - -diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c -index 7e3f5c6ca4846..dfa5f18171e3b 100644 ---- a/drivers/gpu/drm/i915/display/intel_overlay.c -+++ b/drivers/gpu/drm/i915/display/intel_overlay.c -@@ -959,6 +959,9 @@ static int check_overlay_dst(struct intel_overlay *overlay, - const struct intel_crtc_state *pipe_config = - overlay->crtc->config; - -+ if (rec->dst_height == 0 || rec->dst_width == 0) -+ return -EINVAL; -+ - if (rec->dst_x < pipe_config->pipe_src_w && - rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w && - rec->dst_y < pipe_config->pipe_src_h && -diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c -index 18b52b64af955..536b319ffe5ba 100644 ---- a/drivers/gpu/drm/i915/display/intel_snps_phy.c -+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c -@@ -32,7 +32,7 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv) - if (intel_de_wait_for_clear(dev_priv, ICL_PHY_MISC(phy), - DG2_PHY_DP_TX_ACK_MASK, 25)) - DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n", -- phy); -+ phy_name(phy)); - } - } - -diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c -index 3ffece568ed98..0e885440be242 100644 ---- a/drivers/gpu/drm/i915/display/intel_tc.c -+++ b/drivers/gpu/drm/i915/display/intel_tc.c -@@ -291,10 +291,11 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) - static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) - { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); -+ enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); - struct intel_uncore *uncore = &i915->uncore; - u32 val; - -- val = intel_uncore_read(uncore, TCSS_DDI_STATUS(dig_port->tc_phy_fia_idx)); -+ val = intel_uncore_read(uncore, TCSS_DDI_STATUS(tc_port)); - if (val == 0xffffffff) { - drm_dbg_kms(&i915->drm, - "Port %s: PHY in TCCOLD, assuming not complete\n", -diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h -index 2471f36aaff38..3012cbe5b0b7c 100644 ---- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h -+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h -@@ -298,6 +298,7 @@ struct drm_i915_gem_object { - I915_BO_ALLOC_USER) - #define I915_BO_READONLY BIT(4) - #define I915_TILING_QUIRK_BIT 5 /* unknown swizzling; do not release! */ -+#define I915_BO_WAS_BOUND_BIT 6 - - /** - * @mem_flags - Mutable placement-related flags -diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c -index 8eb1c3a6fc9cd..9053cea3395a6 100644 ---- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c -+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c -@@ -10,6 +10,8 @@ - #include "i915_gem_lmem.h" - #include "i915_gem_mman.h" - -+#include "gt/intel_gt.h" -+ - void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, - struct sg_table *pages, - unsigned int sg_page_sizes) -@@ -160,7 +162,6 @@ retry: - /* Immediately discard the backing storage */ - void i915_gem_object_truncate(struct drm_i915_gem_object *obj) - { -- drm_gem_free_mmap_offset(&obj->base); - if (obj->ops->truncate) - obj->ops->truncate(obj); - } -@@ -218,6 +219,14 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) - __i915_gem_object_reset_page_iter(obj); - obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0; - -+ if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { -+ struct drm_i915_private *i915 = to_i915(obj->base.dev); -+ intel_wakeref_t wakeref; -+ -+ with_intel_runtime_pm_if_active(&i915->runtime_pm, wakeref) -+ intel_gt_invalidate_tlbs(&i915->gt); -+ } -+ - return pages; - } - -diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c -index 6ea13159bffcc..4b823fbfe76a1 100644 ---- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c -+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c -@@ -759,11 +759,9 @@ static void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj) - if (obj->mm.madv != I915_MADV_WILLNEED) { - bo->priority = I915_TTM_PRIO_PURGE; - } else if (!i915_gem_object_has_pages(obj)) { -- if (bo->priority < I915_TTM_PRIO_HAS_PAGES) -- bo->priority = I915_TTM_PRIO_HAS_PAGES; -+ bo->priority = I915_TTM_PRIO_NO_PAGES; - } else { -- if (bo->priority > I915_TTM_PRIO_NO_PAGES) -- bo->priority = I915_TTM_PRIO_NO_PAGES; -+ bo->priority = I915_TTM_PRIO_HAS_PAGES; - } - - ttm_bo_move_to_lru_tail(bo, bo->resource, NULL); -diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -index de5f9c86b9a44..cafb0608ffb46 100644 ---- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -@@ -2140,10 +2140,6 @@ static void __execlists_unhold(struct i915_request *rq) - if (p->flags & I915_DEPENDENCY_WEAK) - continue; - -- /* Propagate any change in error status */ -- if (rq->fence.error) -- i915_request_set_error_once(w, rq->fence.error); -- - if (w->engine != rq->engine) - continue; - -diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c -index 62d40c9866427..e1e1d17d49fdd 100644 ---- a/drivers/gpu/drm/i915/gt/intel_gt.c -+++ b/drivers/gpu/drm/i915/gt/intel_gt.c -@@ -29,6 +29,8 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) - - spin_lock_init(>->irq_lock); - -+ mutex_init(>->tlb_invalidate_lock); -+ - INIT_LIST_HEAD(>->closed_vma); - spin_lock_init(>->closed_lock); - -@@ -895,3 +897,103 @@ void intel_gt_info_print(const struct intel_gt_info *info, - - intel_sseu_dump(&info->sseu, p); - } -+ -+struct reg_and_bit { -+ i915_reg_t reg; -+ u32 bit; -+}; -+ -+static struct reg_and_bit -+get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8, -+ const i915_reg_t *regs, const unsigned int num) -+{ -+ const unsigned int class = engine->class; -+ struct reg_and_bit rb = { }; -+ -+ if (drm_WARN_ON_ONCE(&engine->i915->drm, -+ class >= num || !regs[class].reg)) -+ return rb; -+ -+ rb.reg = regs[class]; -+ if (gen8 && class == VIDEO_DECODE_CLASS) -+ rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */ -+ else -+ rb.bit = engine->instance; -+ -+ rb.bit = BIT(rb.bit); -+ -+ return rb; -+} -+ -+void intel_gt_invalidate_tlbs(struct intel_gt *gt) -+{ -+ static const i915_reg_t gen8_regs[] = { -+ [RENDER_CLASS] = GEN8_RTCR, -+ [VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */ -+ [VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR, -+ [COPY_ENGINE_CLASS] = GEN8_BTCR, -+ }; -+ static const i915_reg_t gen12_regs[] = { -+ [RENDER_CLASS] = GEN12_GFX_TLB_INV_CR, -+ [VIDEO_DECODE_CLASS] = GEN12_VD_TLB_INV_CR, -+ [VIDEO_ENHANCEMENT_CLASS] = GEN12_VE_TLB_INV_CR, -+ [COPY_ENGINE_CLASS] = GEN12_BLT_TLB_INV_CR, -+ }; -+ struct drm_i915_private *i915 = gt->i915; -+ struct intel_uncore *uncore = gt->uncore; -+ struct intel_engine_cs *engine; -+ enum intel_engine_id id; -+ const i915_reg_t *regs; -+ unsigned int num = 0; -+ -+ if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) -+ return; -+ -+ if (GRAPHICS_VER(i915) == 12) { -+ regs = gen12_regs; -+ num = ARRAY_SIZE(gen12_regs); -+ } else if (GRAPHICS_VER(i915) >= 8 && GRAPHICS_VER(i915) <= 11) { -+ regs = gen8_regs; -+ num = ARRAY_SIZE(gen8_regs); -+ } else if (GRAPHICS_VER(i915) < 8) { -+ return; -+ } -+ -+ if (drm_WARN_ONCE(&i915->drm, !num, -+ "Platform does not implement TLB invalidation!")) -+ return; -+ -+ GEM_TRACE("\n"); -+ -+ assert_rpm_wakelock_held(&i915->runtime_pm); -+ -+ mutex_lock(>->tlb_invalidate_lock); -+ intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); -+ -+ for_each_engine(engine, gt, id) { -+ /* -+ * HW architecture suggest typical invalidation time at 40us, -+ * with pessimistic cases up to 100us and a recommendation to -+ * cap at 1ms. We go a bit higher just in case. -+ */ -+ const unsigned int timeout_us = 100; -+ const unsigned int timeout_ms = 4; -+ struct reg_and_bit rb; -+ -+ rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); -+ if (!i915_mmio_reg_offset(rb.reg)) -+ continue; -+ -+ intel_uncore_write_fw(uncore, rb.reg, rb.bit); -+ if (__intel_wait_for_register_fw(uncore, -+ rb.reg, rb.bit, 0, -+ timeout_us, timeout_ms, -+ NULL)) -+ drm_err_ratelimited(>->i915->drm, -+ "%s TLB invalidation did not complete in %ums!\n", -+ engine->name, timeout_ms); -+ } -+ -+ intel_uncore_forcewake_put_delayed(uncore, FORCEWAKE_ALL); -+ mutex_unlock(>->tlb_invalidate_lock); -+} -diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h -index 74e771871a9bd..c0169d6017c2d 100644 ---- a/drivers/gpu/drm/i915/gt/intel_gt.h -+++ b/drivers/gpu/drm/i915/gt/intel_gt.h -@@ -90,4 +90,6 @@ void intel_gt_info_print(const struct intel_gt_info *info, - - void intel_gt_watchdog_work(struct work_struct *work); - -+void intel_gt_invalidate_tlbs(struct intel_gt *gt); -+ - #endif /* __INTEL_GT_H__ */ -diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h -index a81e21bf1bd1a..9fbcbcc6c35db 100644 ---- a/drivers/gpu/drm/i915/gt/intel_gt_types.h -+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h -@@ -72,6 +72,8 @@ struct intel_gt { - - struct intel_uc uc; - -+ struct mutex tlb_invalidate_lock; -+ - struct intel_gt_timelines { - spinlock_t lock; /* protects active_list */ - struct list_head active_list; -diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c -index aae609d7d85dd..6b5ab19a2ada9 100644 ---- a/drivers/gpu/drm/i915/gt/intel_workarounds.c -+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c -@@ -621,13 +621,6 @@ static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine, - FF_MODE2_GS_TIMER_MASK, - FF_MODE2_GS_TIMER_224, - 0, false); -- -- /* -- * Wa_14012131227:dg1 -- * Wa_1508744258:tgl,rkl,dg1,adl-s,adl-p -- */ -- wa_masked_en(wal, GEN7_COMMON_SLICE_CHICKEN1, -- GEN9_RHWO_OPTIMIZATION_DISABLE); - } - - static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine, -diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c -index 65a3e7fdb2b2c..95ff630157b9c 100644 ---- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c -+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c -@@ -133,7 +133,7 @@ static int guc_action_slpc_unset_param(struct intel_guc *guc, u8 id) - { - u32 request[] = { - GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, -- SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 2), -+ SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1), - id, - }; - -diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c -index 87d8dc8f51b96..93c9de8f43e8e 100644 ---- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c -+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c -@@ -148,11 +148,12 @@ static inline void clr_context_registered(struct intel_context *ce) - #define SCHED_STATE_BLOCKED_SHIFT 4 - #define SCHED_STATE_BLOCKED BIT(SCHED_STATE_BLOCKED_SHIFT) - #define SCHED_STATE_BLOCKED_MASK (0xfff << SCHED_STATE_BLOCKED_SHIFT) -+ - static inline void init_sched_state(struct intel_context *ce) - { - /* Only should be called from guc_lrc_desc_pin() */ - atomic_set(&ce->guc_sched_state_no_lock, 0); -- ce->guc_state.sched_state = 0; -+ ce->guc_state.sched_state &= SCHED_STATE_BLOCKED_MASK; - } - - static inline bool -@@ -352,20 +353,29 @@ static inline void set_lrc_desc_registered(struct intel_guc *guc, u32 id, - xa_unlock_irqrestore(&guc->context_lookup, flags); - } - -+static void decr_outstanding_submission_g2h(struct intel_guc *guc) -+{ -+ if (atomic_dec_and_test(&guc->outstanding_submission_g2h)) -+ wake_up_all(&guc->ct.wq); -+} -+ - static int guc_submission_send_busy_loop(struct intel_guc *guc, - const u32 *action, - u32 len, - u32 g2h_len_dw, - bool loop) - { -- int err; -- -- err = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop); -+ /* -+ * We always loop when a send requires a reply (i.e. g2h_len_dw > 0), -+ * so we don't handle the case where we don't get a reply because we -+ * aborted the send due to the channel being busy. -+ */ -+ GEM_BUG_ON(g2h_len_dw && !loop); - -- if (!err && g2h_len_dw) -+ if (g2h_len_dw) - atomic_inc(&guc->outstanding_submission_g2h); - -- return err; -+ return intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop); - } - - int intel_guc_wait_for_pending_msg(struct intel_guc *guc, -@@ -616,7 +626,7 @@ static void scrub_guc_desc_for_outstanding_g2h(struct intel_guc *guc) - init_sched_state(ce); - - if (pending_enable || destroyed || deregister) { -- atomic_dec(&guc->outstanding_submission_g2h); -+ decr_outstanding_submission_g2h(guc); - if (deregister) - guc_signal_context_fence(ce); - if (destroyed) { -@@ -635,7 +645,7 @@ static void scrub_guc_desc_for_outstanding_g2h(struct intel_guc *guc) - intel_engine_signal_breadcrumbs(ce->engine); - } - intel_context_sched_disable_unpin(ce); -- atomic_dec(&guc->outstanding_submission_g2h); -+ decr_outstanding_submission_g2h(guc); - spin_lock_irqsave(&ce->guc_state.lock, flags); - guc_blocked_fence_complete(ce); - spin_unlock_irqrestore(&ce->guc_state.lock, flags); -@@ -797,15 +807,13 @@ __unwind_incomplete_requests(struct intel_context *ce) - - spin_lock_irqsave(&sched_engine->lock, flags); - spin_lock(&ce->guc_active.lock); -- list_for_each_entry_safe(rq, rn, -- &ce->guc_active.requests, -- sched.link) { -+ list_for_each_entry_safe_reverse(rq, rn, -+ &ce->guc_active.requests, -+ sched.link) { - if (i915_request_completed(rq)) - continue; - - list_del_init(&rq->sched.link); -- spin_unlock(&ce->guc_active.lock); -- - __i915_request_unsubmit(rq); - - /* Push the request back into the queue for later resubmission. */ -@@ -816,10 +824,8 @@ __unwind_incomplete_requests(struct intel_context *ce) - } - GEM_BUG_ON(i915_sched_engine_is_empty(sched_engine)); - -- list_add_tail(&rq->sched.link, pl); -+ list_add(&rq->sched.link, pl); - set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); -- -- spin_lock(&ce->guc_active.lock); - } - spin_unlock(&ce->guc_active.lock); - spin_unlock_irqrestore(&sched_engine->lock, flags); -@@ -828,17 +834,33 @@ __unwind_incomplete_requests(struct intel_context *ce) - static void __guc_reset_context(struct intel_context *ce, bool stalled) - { - struct i915_request *rq; -+ unsigned long flags; - u32 head; -+ bool skip = false; - - intel_context_get(ce); - - /* -- * GuC will implicitly mark the context as non-schedulable -- * when it sends the reset notification. Make sure our state -- * reflects this change. The context will be marked enabled -- * on resubmission. -+ * GuC will implicitly mark the context as non-schedulable when it sends -+ * the reset notification. Make sure our state reflects this change. The -+ * context will be marked enabled on resubmission. -+ * -+ * XXX: If the context is reset as a result of the request cancellation -+ * this G2H is received after the schedule disable complete G2H which is -+ * wrong as this creates a race between the request cancellation code -+ * re-submitting the context and this G2H handler. This is a bug in the -+ * GuC but can be worked around in the meantime but converting this to a -+ * NOP if a pending enable is in flight as this indicates that a request -+ * cancellation has occurred. - */ -- clr_context_enabled(ce); -+ spin_lock_irqsave(&ce->guc_state.lock, flags); -+ if (likely(!context_pending_enable(ce))) -+ clr_context_enabled(ce); -+ else -+ skip = true; -+ spin_unlock_irqrestore(&ce->guc_state.lock, flags); -+ if (unlikely(skip)) -+ goto out_put; - - rq = intel_context_find_active_request(ce); - if (!rq) { -@@ -857,6 +879,7 @@ static void __guc_reset_context(struct intel_context *ce, bool stalled) - out_replay: - guc_reset_state(ce, head, stalled); - __unwind_incomplete_requests(ce); -+out_put: - intel_context_put(ce); - } - -@@ -1233,8 +1256,7 @@ static int register_context(struct intel_context *ce, bool loop) - } - - static int __guc_action_deregister_context(struct intel_guc *guc, -- u32 guc_id, -- bool loop) -+ u32 guc_id) - { - u32 action[] = { - INTEL_GUC_ACTION_DEREGISTER_CONTEXT, -@@ -1243,16 +1265,16 @@ static int __guc_action_deregister_context(struct intel_guc *guc, - - return guc_submission_send_busy_loop(guc, action, ARRAY_SIZE(action), - G2H_LEN_DW_DEREGISTER_CONTEXT, -- loop); -+ true); - } - --static int deregister_context(struct intel_context *ce, u32 guc_id, bool loop) -+static int deregister_context(struct intel_context *ce, u32 guc_id) - { - struct intel_guc *guc = ce_to_guc(ce); - - trace_intel_context_deregister(ce); - -- return __guc_action_deregister_context(guc, guc_id, loop); -+ return __guc_action_deregister_context(guc, guc_id); - } - - static intel_engine_mask_t adjust_engine_mask(u8 class, intel_engine_mask_t mask) -@@ -1340,26 +1362,23 @@ static int guc_lrc_desc_pin(struct intel_context *ce, bool loop) - * registering this context. - */ - if (context_registered) { -+ bool disabled; -+ unsigned long flags; -+ - trace_intel_context_steal_guc_id(ce); -- if (!loop) { -+ GEM_BUG_ON(!loop); -+ -+ /* Seal race with Reset */ -+ spin_lock_irqsave(&ce->guc_state.lock, flags); -+ disabled = submission_disabled(guc); -+ if (likely(!disabled)) { - set_context_wait_for_deregister_to_register(ce); - intel_context_get(ce); -- } else { -- bool disabled; -- unsigned long flags; -- -- /* Seal race with Reset */ -- spin_lock_irqsave(&ce->guc_state.lock, flags); -- disabled = submission_disabled(guc); -- if (likely(!disabled)) { -- set_context_wait_for_deregister_to_register(ce); -- intel_context_get(ce); -- } -- spin_unlock_irqrestore(&ce->guc_state.lock, flags); -- if (unlikely(disabled)) { -- reset_lrc_desc(guc, desc_idx); -- return 0; /* Will get registered later */ -- } -+ } -+ spin_unlock_irqrestore(&ce->guc_state.lock, flags); -+ if (unlikely(disabled)) { -+ reset_lrc_desc(guc, desc_idx); -+ return 0; /* Will get registered later */ - } - - /* -@@ -1367,13 +1386,9 @@ static int guc_lrc_desc_pin(struct intel_context *ce, bool loop) - * context whose guc_id was stolen. - */ - with_intel_runtime_pm(runtime_pm, wakeref) -- ret = deregister_context(ce, ce->guc_id, loop); -- if (unlikely(ret == -EBUSY)) { -- clr_context_wait_for_deregister_to_register(ce); -- intel_context_put(ce); -- } else if (unlikely(ret == -ENODEV)) { -+ ret = deregister_context(ce, ce->guc_id); -+ if (unlikely(ret == -ENODEV)) - ret = 0; /* Will get registered later */ -- } - } else { - with_intel_runtime_pm(runtime_pm, wakeref) - ret = register_context(ce, loop); -@@ -1548,6 +1563,23 @@ static struct i915_sw_fence *guc_context_block(struct intel_context *ce) - return &ce->guc_blocked; - } - -+#define SCHED_STATE_MULTI_BLOCKED_MASK \ -+ (SCHED_STATE_BLOCKED_MASK & ~SCHED_STATE_BLOCKED) -+#define SCHED_STATE_NO_UNBLOCK \ -+ (SCHED_STATE_MULTI_BLOCKED_MASK | \ -+ SCHED_STATE_PENDING_DISABLE | \ -+ SCHED_STATE_BANNED) -+ -+static bool context_cant_unblock(struct intel_context *ce) -+{ -+ lockdep_assert_held(&ce->guc_state.lock); -+ -+ return (ce->guc_state.sched_state & SCHED_STATE_NO_UNBLOCK) || -+ context_guc_id_invalid(ce) || -+ !lrc_desc_registered(ce_to_guc(ce), ce->guc_id) || -+ !intel_context_is_pinned(ce); -+} -+ - static void guc_context_unblock(struct intel_context *ce) - { - struct intel_guc *guc = ce_to_guc(ce); -@@ -1562,9 +1594,7 @@ static void guc_context_unblock(struct intel_context *ce) - spin_lock_irqsave(&ce->guc_state.lock, flags); - - if (unlikely(submission_disabled(guc) || -- !intel_context_is_pinned(ce) || -- context_pending_disable(ce) || -- context_blocked(ce) > 1)) { -+ context_cant_unblock(ce))) { - enable = false; - } else { - enable = true; -@@ -1601,6 +1631,13 @@ static void guc_context_cancel_request(struct intel_context *ce, - guc_reset_state(ce, intel_ring_wrap(ce->ring, rq->head), - true); - } -+ -+ /* -+ * XXX: Racey if context is reset, see comment in -+ * __guc_reset_context(). -+ */ -+ flush_work(&ce_to_guc(ce)->ct.requests.worker); -+ - guc_context_unblock(ce); - } - } -@@ -1730,7 +1767,7 @@ static inline void guc_lrc_desc_unpin(struct intel_context *ce) - GEM_BUG_ON(context_enabled(ce)); - - clr_context_registered(ce); -- deregister_context(ce, ce->guc_id, true); -+ deregister_context(ce, ce->guc_id); - } - - static void __guc_context_destroy(struct intel_context *ce) -@@ -2583,12 +2620,6 @@ g2h_context_lookup(struct intel_guc *guc, u32 desc_idx) - return ce; - } - --static void decr_outstanding_submission_g2h(struct intel_guc *guc) --{ -- if (atomic_dec_and_test(&guc->outstanding_submission_g2h)) -- wake_up_all(&guc->ct.wq); --} -- - int intel_guc_deregister_done_process_msg(struct intel_guc *guc, - const u32 *msg, - u32 len) -@@ -2721,7 +2752,12 @@ static void guc_handle_context_reset(struct intel_guc *guc, - { - trace_intel_context_reset(ce); - -- if (likely(!intel_context_is_banned(ce))) { -+ /* -+ * XXX: Racey if request cancellation has occurred, see comment in -+ * __guc_reset_context(). -+ */ -+ if (likely(!intel_context_is_banned(ce) && -+ !context_blocked(ce))) { - capture_error_state(guc, ce); - guc_context_replay(ce); - } -diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c -index 1bbd09ad52873..1ad7259fb1f0c 100644 ---- a/drivers/gpu/drm/i915/i915_pci.c -+++ b/drivers/gpu/drm/i915/i915_pci.c -@@ -865,7 +865,7 @@ static const struct intel_device_info jsl_info = { - }, \ - TGL_CURSOR_OFFSETS, \ - .has_global_mocs = 1, \ -- .display.has_dsb = 1 -+ .display.has_dsb = 0 /* FIXME: LUT load is broken with DSB */ - - static const struct intel_device_info tgl_info = { - GEN12_FEATURES, -diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h -index 9023d4ecf3b37..c65473fc90935 100644 ---- a/drivers/gpu/drm/i915/i915_reg.h -+++ b/drivers/gpu/drm/i915/i915_reg.h -@@ -2669,6 +2669,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) - #define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1 << 28) - #define GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT (1 << 24) - -+#define GEN8_RTCR _MMIO(0x4260) -+#define GEN8_M1TCR _MMIO(0x4264) -+#define GEN8_M2TCR _MMIO(0x4268) -+#define GEN8_BTCR _MMIO(0x426c) -+#define GEN8_VTCR _MMIO(0x4270) -+ - #if 0 - #define PRB0_TAIL _MMIO(0x2030) - #define PRB0_HEAD _MMIO(0x2034) -@@ -2763,6 +2769,11 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) - #define FAULT_VA_HIGH_BITS (0xf << 0) - #define FAULT_GTT_SEL (1 << 4) - -+#define GEN12_GFX_TLB_INV_CR _MMIO(0xced8) -+#define GEN12_VD_TLB_INV_CR _MMIO(0xcedc) -+#define GEN12_VE_TLB_INV_CR _MMIO(0xcee0) -+#define GEN12_BLT_TLB_INV_CR _MMIO(0xcee4) -+ - #define GEN12_AUX_ERR_DBG _MMIO(0x43f4) - - #define FPGA_DBG _MMIO(0x42300) -diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c -index 4b7fc4647e460..dfd20060812bc 100644 ---- a/drivers/gpu/drm/i915/i915_vma.c -+++ b/drivers/gpu/drm/i915/i915_vma.c -@@ -434,6 +434,9 @@ int i915_vma_bind(struct i915_vma *vma, - vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags); - } - -+ if (vma->obj) -+ set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); -+ - atomic_or(bind_flags, &vma->flags); - return 0; - } -diff --git a/drivers/gpu/drm/i915/intel_pch.c b/drivers/gpu/drm/i915/intel_pch.c -index d1d4b97b86f59..287f5a3d0b354 100644 ---- a/drivers/gpu/drm/i915/intel_pch.c -+++ b/drivers/gpu/drm/i915/intel_pch.c -@@ -108,6 +108,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) - /* Comet Lake V PCH is based on KBP, which is SPT compatible */ - return PCH_SPT; - case INTEL_PCH_ICP_DEVICE_ID_TYPE: -+ case INTEL_PCH_ICP2_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n"); - drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv)); - return PCH_ICP; -@@ -123,7 +124,6 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) - !IS_GEN9_BC(dev_priv)); - return PCH_TGP; - case INTEL_PCH_JSP_DEVICE_ID_TYPE: -- case INTEL_PCH_JSP2_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n"); - drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv)); - return PCH_JSP; -diff --git a/drivers/gpu/drm/i915/intel_pch.h b/drivers/gpu/drm/i915/intel_pch.h -index 7c0d83d292dcc..994c56fcb1991 100644 ---- a/drivers/gpu/drm/i915/intel_pch.h -+++ b/drivers/gpu/drm/i915/intel_pch.h -@@ -50,11 +50,11 @@ enum intel_pch { - #define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 - #define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 - #define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 -+#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880 - #define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 - #define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080 - #define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380 - #define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 --#define INTEL_PCH_JSP2_DEVICE_ID_TYPE 0x3880 - #define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 - #define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 - #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index a725792d5248b..9c5e4758947b6 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3063,9 +3063,9 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) - * The BIOS provided WM memory latency values are often - * inadequate for high resolution displays. Adjust them. - */ -- changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) | -- ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) | -- ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); -+ changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12); -+ changed |= ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12); -+ changed |= ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); - - if (!changed) - return; -@@ -4020,6 +4020,17 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state) - return ret; - } - -+ if (intel_can_enable_sagv(dev_priv, new_bw_state) != -+ intel_can_enable_sagv(dev_priv, old_bw_state)) { -+ ret = intel_atomic_serialize_global_state(&new_bw_state->base); -+ if (ret) -+ return ret; -+ } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) { -+ ret = intel_atomic_lock_global_state(&new_bw_state->base); -+ if (ret) -+ return ret; -+ } -+ - for_each_new_intel_crtc_in_state(state, crtc, - new_crtc_state, i) { - struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal; -@@ -4035,17 +4046,6 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state) - intel_can_enable_sagv(dev_priv, new_bw_state); - } - -- if (intel_can_enable_sagv(dev_priv, new_bw_state) != -- intel_can_enable_sagv(dev_priv, old_bw_state)) { -- ret = intel_atomic_serialize_global_state(&new_bw_state->base); -- if (ret) -- return ret; -- } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) { -- ret = intel_atomic_lock_global_state(&new_bw_state->base); -- if (ret) -- return ret; -- } -- - return 0; - } - -@@ -4708,6 +4708,10 @@ static const struct dbuf_slice_conf_entry dg2_allowed_dbufs[] = { - }; - - static const struct dbuf_slice_conf_entry adlp_allowed_dbufs[] = { -+ /* -+ * Keep the join_mbus cases first so check_mbus_joined() -+ * will prefer them over the !join_mbus cases. -+ */ - { - .active_pipes = BIT(PIPE_A), - .dbuf_mask = { -@@ -4722,6 +4726,20 @@ static const struct dbuf_slice_conf_entry adlp_allowed_dbufs[] = { - }, - .join_mbus = true, - }, -+ { -+ .active_pipes = BIT(PIPE_A), -+ .dbuf_mask = { -+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2), -+ }, -+ .join_mbus = false, -+ }, -+ { -+ .active_pipes = BIT(PIPE_B), -+ .dbuf_mask = { -+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4), -+ }, -+ .join_mbus = false, -+ }, - { - .active_pipes = BIT(PIPE_A) | BIT(PIPE_B), - .dbuf_mask = { -@@ -4826,7 +4844,7 @@ static bool check_mbus_joined(u8 active_pipes, - { - int i; - -- for (i = 0; i < dbuf_slices[i].active_pipes; i++) { -+ for (i = 0; dbuf_slices[i].active_pipes != 0; i++) { - if (dbuf_slices[i].active_pipes == active_pipes) - return dbuf_slices[i].join_mbus; - } -@@ -4838,13 +4856,14 @@ static bool adlp_check_mbus_joined(u8 active_pipes) - return check_mbus_joined(active_pipes, adlp_allowed_dbufs); - } - --static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, -+static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus, - const struct dbuf_slice_conf_entry *dbuf_slices) - { - int i; - -- for (i = 0; i < dbuf_slices[i].active_pipes; i++) { -- if (dbuf_slices[i].active_pipes == active_pipes) -+ for (i = 0; dbuf_slices[i].active_pipes != 0; i++) { -+ if (dbuf_slices[i].active_pipes == active_pipes && -+ dbuf_slices[i].join_mbus == join_mbus) - return dbuf_slices[i].dbuf_mask[pipe]; - } - return 0; -@@ -4855,7 +4874,7 @@ static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, - * returns correspondent DBuf slice mask as stated in BSpec for particular - * platform. - */ --static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes) -+static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus) - { - /* - * FIXME: For ICL this is still a bit unclear as prev BSpec revision -@@ -4869,37 +4888,41 @@ static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes) - * still here - we will need it once those additional constraints - * pop up. - */ -- return compute_dbuf_slices(pipe, active_pipes, icl_allowed_dbufs); -+ return compute_dbuf_slices(pipe, active_pipes, join_mbus, -+ icl_allowed_dbufs); - } - --static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes) -+static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus) - { -- return compute_dbuf_slices(pipe, active_pipes, tgl_allowed_dbufs); -+ return compute_dbuf_slices(pipe, active_pipes, join_mbus, -+ tgl_allowed_dbufs); - } - --static u32 adlp_compute_dbuf_slices(enum pipe pipe, u32 active_pipes) -+static u8 adlp_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus) - { -- return compute_dbuf_slices(pipe, active_pipes, adlp_allowed_dbufs); -+ return compute_dbuf_slices(pipe, active_pipes, join_mbus, -+ adlp_allowed_dbufs); - } - --static u32 dg2_compute_dbuf_slices(enum pipe pipe, u32 active_pipes) -+static u8 dg2_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus) - { -- return compute_dbuf_slices(pipe, active_pipes, dg2_allowed_dbufs); -+ return compute_dbuf_slices(pipe, active_pipes, join_mbus, -+ dg2_allowed_dbufs); - } - --static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes) -+static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes, bool join_mbus) - { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - enum pipe pipe = crtc->pipe; - - if (IS_DG2(dev_priv)) -- return dg2_compute_dbuf_slices(pipe, active_pipes); -+ return dg2_compute_dbuf_slices(pipe, active_pipes, join_mbus); - else if (IS_ALDERLAKE_P(dev_priv)) -- return adlp_compute_dbuf_slices(pipe, active_pipes); -+ return adlp_compute_dbuf_slices(pipe, active_pipes, join_mbus); - else if (DISPLAY_VER(dev_priv) == 12) -- return tgl_compute_dbuf_slices(pipe, active_pipes); -+ return tgl_compute_dbuf_slices(pipe, active_pipes, join_mbus); - else if (DISPLAY_VER(dev_priv) == 11) -- return icl_compute_dbuf_slices(pipe, active_pipes); -+ return icl_compute_dbuf_slices(pipe, active_pipes, join_mbus); - /* - * For anything else just return one slice yet. - * Should be extended for other platforms. -@@ -6110,11 +6133,16 @@ skl_compute_ddb(struct intel_atomic_state *state) - return ret; - } - -+ if (IS_ALDERLAKE_P(dev_priv)) -+ new_dbuf_state->joined_mbus = -+ adlp_check_mbus_joined(new_dbuf_state->active_pipes); -+ - for_each_intel_crtc(&dev_priv->drm, crtc) { - enum pipe pipe = crtc->pipe; - - new_dbuf_state->slices[pipe] = -- skl_compute_dbuf_slices(crtc, new_dbuf_state->active_pipes); -+ skl_compute_dbuf_slices(crtc, new_dbuf_state->active_pipes, -+ new_dbuf_state->joined_mbus); - - if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe]) - continue; -@@ -6126,9 +6154,6 @@ skl_compute_ddb(struct intel_atomic_state *state) - - new_dbuf_state->enabled_slices = intel_dbuf_enabled_slices(new_dbuf_state); - -- if (IS_ALDERLAKE_P(dev_priv)) -- new_dbuf_state->joined_mbus = adlp_check_mbus_joined(new_dbuf_state->active_pipes); -- - if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices || - old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) { - ret = intel_atomic_serialize_global_state(&new_dbuf_state->base); -@@ -6609,6 +6634,7 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv) - enum pipe pipe = crtc->pipe; - unsigned int mbus_offset; - enum plane_id plane_id; -+ u8 slices; - - skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal); - crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal; -@@ -6628,19 +6654,22 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv) - skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_uv); - } - -- dbuf_state->slices[pipe] = -- skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes); -- - dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state); - - /* - * Used for checking overlaps, so we need absolute - * offsets instead of MBUS relative offsets. - */ -- mbus_offset = mbus_ddb_offset(dev_priv, dbuf_state->slices[pipe]); -+ slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes, -+ dbuf_state->joined_mbus); -+ mbus_offset = mbus_ddb_offset(dev_priv, slices); - crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start; - crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end; - -+ /* The slices actually used by the planes on the pipe */ -+ dbuf_state->slices[pipe] = -+ skl_ddb_dbuf_slice_mask(dev_priv, &crtc_state->wm.skl.ddb); -+ - drm_dbg_kms(&dev_priv->drm, - "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n", - crtc->base.base.id, crtc->base.name, -diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c -index 6b38bc2811c1b..de8d0558389c4 100644 ---- a/drivers/gpu/drm/i915/intel_uncore.c -+++ b/drivers/gpu/drm/i915/intel_uncore.c -@@ -718,7 +718,8 @@ void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore, - } - - static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, -- enum forcewake_domains fw_domains) -+ enum forcewake_domains fw_domains, -+ bool delayed) - { - struct intel_uncore_forcewake_domain *domain; - unsigned int tmp; -@@ -733,7 +734,11 @@ static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, - continue; - } - -- uncore->funcs.force_wake_put(uncore, domain->mask); -+ if (delayed && -+ !(domain->uncore->fw_domains_timer & domain->mask)) -+ fw_domain_arm_timer(domain); -+ else -+ uncore->funcs.force_wake_put(uncore, domain->mask); - } - } - -@@ -754,7 +759,20 @@ void intel_uncore_forcewake_put(struct intel_uncore *uncore, - return; - - spin_lock_irqsave(&uncore->lock, irqflags); -- __intel_uncore_forcewake_put(uncore, fw_domains); -+ __intel_uncore_forcewake_put(uncore, fw_domains, false); -+ spin_unlock_irqrestore(&uncore->lock, irqflags); -+} -+ -+void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, -+ enum forcewake_domains fw_domains) -+{ -+ unsigned long irqflags; -+ -+ if (!uncore->funcs.force_wake_put) -+ return; -+ -+ spin_lock_irqsave(&uncore->lock, irqflags); -+ __intel_uncore_forcewake_put(uncore, fw_domains, true); - spin_unlock_irqrestore(&uncore->lock, irqflags); - } - -@@ -796,7 +814,7 @@ void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore, - if (!uncore->funcs.force_wake_put) - return; - -- __intel_uncore_forcewake_put(uncore, fw_domains); -+ __intel_uncore_forcewake_put(uncore, fw_domains, false); - } - - void assert_forcewakes_inactive(struct intel_uncore *uncore) -diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h -index 3c0b0a8b5250d..4c63209dcf530 100644 ---- a/drivers/gpu/drm/i915/intel_uncore.h -+++ b/drivers/gpu/drm/i915/intel_uncore.h -@@ -229,6 +229,8 @@ void intel_uncore_forcewake_get(struct intel_uncore *uncore, - enum forcewake_domains domains); - void intel_uncore_forcewake_put(struct intel_uncore *uncore, - enum forcewake_domains domains); -+void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, -+ enum forcewake_domains domains); - void intel_uncore_forcewake_flush(struct intel_uncore *uncore, - enum forcewake_domains fw_domains); - -diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c -index 9558e9e1b431b..cb685fe2039b4 100644 ---- a/drivers/gpu/drm/imx/imx-drm-core.c -+++ b/drivers/gpu/drm/imx/imx-drm-core.c -@@ -81,7 +81,6 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) - struct drm_plane_state *old_plane_state, *new_plane_state; - bool plane_disabling = false; - int i; -- bool fence_cookie = dma_fence_begin_signalling(); - - drm_atomic_helper_commit_modeset_disables(dev, state); - -@@ -112,7 +111,6 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) - } - - drm_atomic_helper_commit_hw_done(state); -- dma_fence_end_signalling(fence_cookie); - } - - static const struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = { -diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c -index 00404ba4126dd..2735b8eb35376 100644 ---- a/drivers/gpu/drm/kmb/kmb_plane.c -+++ b/drivers/gpu/drm/kmb/kmb_plane.c -@@ -158,12 +158,6 @@ static void kmb_plane_atomic_disable(struct drm_plane *plane, - case LAYER_1: - kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE; - break; -- case LAYER_2: -- kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL1_ENABLE; -- break; -- case LAYER_3: -- kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL2_ENABLE; -- break; - } - - kmb->plane_status[plane_id].disable = true; -diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c -index 65fdca366e41f..36c9905894278 100644 ---- a/drivers/gpu/drm/lima/lima_device.c -+++ b/drivers/gpu/drm/lima/lima_device.c -@@ -357,6 +357,7 @@ int lima_device_init(struct lima_device *ldev) - int err, i; - - dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); -+ dma_set_max_seg_size(ldev->dev, UINT_MAX); - - err = lima_clk_init(ldev); - if (err) -diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c -index 93b40c245f007..5d90d2eb00193 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dsi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - - #include