Merge remote-tracking branch 'torvalds/master' into perf/core
To pick up fixes from perf/urgent that got into upstream. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Коммит
473b2922c7
7
.mailmap
7
.mailmap
|
@ -168,6 +168,7 @@ Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
|
|||
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
|
||||
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
||||
John Stultz <johnstul@us.ibm.com>
|
||||
Jordan Crouse <jordan@cosmicpenguin.net> <jcrouse@codeaurora.org>
|
||||
<josh@joshtriplett.org> <josh@freedesktop.org>
|
||||
<josh@joshtriplett.org> <josh@kernel.org>
|
||||
<josh@joshtriplett.org> <josht@linux.vnet.ibm.com>
|
||||
|
@ -253,8 +254,14 @@ Morten Welinder <welinder@anemone.rentec.com>
|
|||
Morten Welinder <welinder@darter.rentec.com>
|
||||
Morten Welinder <welinder@troll.com>
|
||||
Mythri P K <mythripk@ti.com>
|
||||
Nadia Yvette Chambers <nyc@holomorphy.com> William Lee Irwin III <wli@holomorphy.com>
|
||||
Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com>
|
||||
Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
Nicholas Piggin <npiggin@gmail.com> <npiggen@suse.de>
|
||||
Nicholas Piggin <npiggin@gmail.com> <npiggin@kernel.dk>
|
||||
Nicholas Piggin <npiggin@gmail.com> <npiggin@suse.de>
|
||||
Nicholas Piggin <npiggin@gmail.com> <nickpiggin@yahoo.com.au>
|
||||
Nicholas Piggin <npiggin@gmail.com> <piggin@cyberone.com.au>
|
||||
Nicolas Ferre <nicolas.ferre@microchip.com> <nicolas.ferre@atmel.com>
|
||||
Nicolas Pitre <nico@fluxnic.net> <nicolas.pitre@linaro.org>
|
||||
Nicolas Pitre <nico@fluxnic.net> <nico@linaro.org>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
What: /sys/kernel/debug/moxtet/input
|
||||
Date: March 2019
|
||||
KernelVersion: 5.3
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) Read input from the shift registers, in hexadecimal.
|
||||
Returns N+1 bytes, where N is the number of Moxtet connected
|
||||
modules. The first byte is from the CPU board itself.
|
||||
|
@ -19,7 +19,7 @@ Description: (Read) Read input from the shift registers, in hexadecimal.
|
|||
What: /sys/kernel/debug/moxtet/output
|
||||
Date: March 2019
|
||||
KernelVersion: 5.3
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (RW) Read last written value to the shift registers, in
|
||||
hexadecimal, or write values to the shift registers, also
|
||||
in hexadecimal.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
What: /sys/kernel/debug/turris-mox-rwtm/do_sign
|
||||
Date: Jun 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description:
|
||||
|
||||
======= ===========================================================
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
What: /sys/bus/moxtet/devices/moxtet-<name>.<addr>/module_description
|
||||
Date: March 2019
|
||||
KernelVersion: 5.3
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) Moxtet module description. Format: string
|
||||
|
||||
What: /sys/bus/moxtet/devices/moxtet-<name>.<addr>/module_id
|
||||
Date: March 2019
|
||||
KernelVersion: 5.3
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) Moxtet module ID. Format: %x
|
||||
|
||||
What: /sys/bus/moxtet/devices/moxtet-<name>.<addr>/module_name
|
||||
Date: March 2019
|
||||
KernelVersion: 5.3
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) Moxtet module name. Format: string
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
What: /sys/class/leds/<led>/device/brightness
|
||||
Date: July 2020
|
||||
KernelVersion: 5.9
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (RW) On the front panel of the Turris Omnia router there is also
|
||||
a button which can be used to control the intensity of all the
|
||||
LEDs at once, so that if they are too bright, user can dim them.
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
What: /sys/firmware/turris-mox-rwtm/board_version
|
||||
Date: August 2019
|
||||
KernelVersion: 5.4
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) Board version burned into eFuses of this Turris Mox board.
|
||||
Format: %i
|
||||
|
||||
What: /sys/firmware/turris-mox-rwtm/mac_address*
|
||||
Date: August 2019
|
||||
KernelVersion: 5.4
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) MAC addresses burned into eFuses of this Turris Mox board.
|
||||
Format: %pM
|
||||
|
||||
What: /sys/firmware/turris-mox-rwtm/pubkey
|
||||
Date: August 2019
|
||||
KernelVersion: 5.4
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) ECDSA public key (in pubkey hex compressed form) computed
|
||||
as pair to the ECDSA private key burned into eFuses of this
|
||||
Turris Mox Board.
|
||||
|
@ -24,7 +24,7 @@ Description: (Read) ECDSA public key (in pubkey hex compressed form) computed
|
|||
What: /sys/firmware/turris-mox-rwtm/ram_size
|
||||
Date: August 2019
|
||||
KernelVersion: 5.4
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) RAM size in MiB of this Turris Mox board as was detected
|
||||
during manufacturing and burned into eFuses. Can be 512 or 1024.
|
||||
Format: %i
|
||||
|
@ -32,6 +32,6 @@ Description: (Read) RAM size in MiB of this Turris Mox board as was detected
|
|||
What: /sys/firmware/turris-mox-rwtm/serial_number
|
||||
Date: August 2019
|
||||
KernelVersion: 5.4
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Contact: Marek Behún <kabel@kernel.org>
|
||||
Description: (Read) Serial number burned into eFuses of this Turris Mox device.
|
||||
Format: %016X
|
||||
|
|
|
@ -32,7 +32,7 @@ Optional node properties:
|
|||
- "#thermal-sensor-cells" Used to expose itself to thermal fw.
|
||||
|
||||
Read more about iio bindings at
|
||||
Documentation/devicetree/bindings/iio/iio-bindings.txt
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/
|
||||
|
||||
Example:
|
||||
ncp15wb473@0 {
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Bindings for GPIO bitbanged I2C
|
||||
|
||||
maintainers:
|
||||
- Wolfram Sang <wolfram@the-dreams.de>
|
||||
- Wolfram Sang <wsa@kernel.org>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX
|
||||
|
||||
maintainers:
|
||||
- Wolfram Sang <wolfram@the-dreams.de>
|
||||
- Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
|
|
|
@ -14,8 +14,9 @@ description: >
|
|||
Industrial I/O subsystem bindings for ADC controller found in
|
||||
Ingenic JZ47xx SoCs.
|
||||
|
||||
ADC clients must use the format described in iio-bindings.txt, giving
|
||||
a phandle and IIO specifier pair ("io-channels") to the ADC controller.
|
||||
ADC clients must use the format described in
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml,
|
||||
giving a phandle and IIO specifier pair ("io-channels") to the ADC controller.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
@ -24,7 +24,9 @@ properties:
|
|||
description: >
|
||||
List of phandle and IIO specifier pairs.
|
||||
Each pair defines one ADC channel to which a joystick axis is connected.
|
||||
See Documentation/devicetree/bindings/iio/iio-bindings.txt for details.
|
||||
See
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
||||
for details.
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
|
|
@ -5,7 +5,10 @@ Required properties:
|
|||
- compatible: must be "resistive-adc-touch"
|
||||
The device must be connected to an ADC device that provides channels for
|
||||
position measurement and optional pressure.
|
||||
Refer to ../iio/iio-bindings.txt for details
|
||||
Refer to
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
||||
for details
|
||||
|
||||
- iio-channels: must have at least two channels connected to an ADC device.
|
||||
These should correspond to the channels exposed by the ADC device and should
|
||||
have the right index as the ADC device registers them. These channels
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: CZ.NIC's Turris Omnia LEDs driver
|
||||
|
||||
maintainers:
|
||||
- Marek Behún <marek.behun@nic.cz>
|
||||
- Marek Behún <kabel@kernel.org>
|
||||
|
||||
description:
|
||||
This module adds support for the RGB LEDs found on the front panel of the
|
||||
|
|
|
@ -72,7 +72,9 @@ Required child device properties:
|
|||
pwm|regulator|rtc|sysctrl|usb]";
|
||||
|
||||
A few child devices require ADC channels from the GPADC node. Those follow the
|
||||
standard bindings from iio/iio-bindings.txt and iio/adc/adc.txt
|
||||
standard bindings from
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
||||
and Documentation/devicetree/bindings/iio/adc/adc.yaml
|
||||
|
||||
abx500-temp : io-channels "aux1" and "aux2" for measuring external
|
||||
temperatures.
|
||||
|
|
|
@ -16,14 +16,14 @@ Optional subnodes:
|
|||
The sub-functions of CPCAP get their own node with their own compatible values,
|
||||
which are described in the following files:
|
||||
|
||||
- ../power/supply/cpcap-battery.txt
|
||||
- ../power/supply/cpcap-charger.txt
|
||||
- ../regulator/cpcap-regulator.txt
|
||||
- ../phy/phy-cpcap-usb.txt
|
||||
- ../input/cpcap-pwrbutton.txt
|
||||
- ../rtc/cpcap-rtc.txt
|
||||
- ../leds/leds-cpcap.txt
|
||||
- ../iio/adc/cpcap-adc.txt
|
||||
- Documentation/devicetree/bindings/power/supply/cpcap-battery.txt
|
||||
- Documentation/devicetree/bindings/power/supply/cpcap-charger.txt
|
||||
- Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
|
||||
- Documentation/devicetree/bindings/phy/phy-cpcap-usb.txt
|
||||
- Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
|
||||
- Documentation/devicetree/bindings/rtc/cpcap-rtc.txt
|
||||
- Documentation/devicetree/bindings/leds/leds-cpcap.txt
|
||||
- Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
|
||||
|
||||
The only exception is the audio codec. Instead of a compatible value its
|
||||
node must be named "audio-codec".
|
||||
|
|
|
@ -32,7 +32,7 @@ required:
|
|||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -49,7 +49,7 @@ properties:
|
|||
description:
|
||||
Reference to an nvmem node for the MAC address
|
||||
|
||||
nvmem-cells-names:
|
||||
nvmem-cell-names:
|
||||
const: mac-address
|
||||
|
||||
phy-connection-type:
|
||||
|
|
|
@ -65,6 +65,71 @@ KSZ9031:
|
|||
step is 60ps. The default value is the neutral setting, so setting
|
||||
rxc-skew-ps=<0> actually results in -900 picoseconds adjustment.
|
||||
|
||||
The KSZ9031 hardware supports a range of skew values from negative to
|
||||
positive, where the specific range is property dependent. All values
|
||||
specified in the devicetree are offset by the minimum value so they
|
||||
can be represented as positive integers in the devicetree since it's
|
||||
difficult to represent a negative number in the devictree.
|
||||
|
||||
The following 5-bit values table apply to rxc-skew-ps and txc-skew-ps.
|
||||
|
||||
Pad Skew Value Delay (ps) Devicetree Value
|
||||
------------------------------------------------------
|
||||
0_0000 -900ps 0
|
||||
0_0001 -840ps 60
|
||||
0_0010 -780ps 120
|
||||
0_0011 -720ps 180
|
||||
0_0100 -660ps 240
|
||||
0_0101 -600ps 300
|
||||
0_0110 -540ps 360
|
||||
0_0111 -480ps 420
|
||||
0_1000 -420ps 480
|
||||
0_1001 -360ps 540
|
||||
0_1010 -300ps 600
|
||||
0_1011 -240ps 660
|
||||
0_1100 -180ps 720
|
||||
0_1101 -120ps 780
|
||||
0_1110 -60ps 840
|
||||
0_1111 0ps 900
|
||||
1_0000 60ps 960
|
||||
1_0001 120ps 1020
|
||||
1_0010 180ps 1080
|
||||
1_0011 240ps 1140
|
||||
1_0100 300ps 1200
|
||||
1_0101 360ps 1260
|
||||
1_0110 420ps 1320
|
||||
1_0111 480ps 1380
|
||||
1_1000 540ps 1440
|
||||
1_1001 600ps 1500
|
||||
1_1010 660ps 1560
|
||||
1_1011 720ps 1620
|
||||
1_1100 780ps 1680
|
||||
1_1101 840ps 1740
|
||||
1_1110 900ps 1800
|
||||
1_1111 960ps 1860
|
||||
|
||||
The following 4-bit values table apply to the txdX-skew-ps, rxdX-skew-ps
|
||||
data pads, and the rxdv-skew-ps, txen-skew-ps control pads.
|
||||
|
||||
Pad Skew Value Delay (ps) Devicetree Value
|
||||
------------------------------------------------------
|
||||
0000 -420ps 0
|
||||
0001 -360ps 60
|
||||
0010 -300ps 120
|
||||
0011 -240ps 180
|
||||
0100 -180ps 240
|
||||
0101 -120ps 300
|
||||
0110 -60ps 360
|
||||
0111 0ps 420
|
||||
1000 60ps 480
|
||||
1001 120ps 540
|
||||
1010 180ps 600
|
||||
1011 240ps 660
|
||||
1100 300ps 720
|
||||
1101 360ps 780
|
||||
1110 420ps 840
|
||||
1111 480ps 900
|
||||
|
||||
Optional properties:
|
||||
|
||||
Maximum value of 1860, default value 900:
|
||||
|
@ -120,11 +185,21 @@ KSZ9131:
|
|||
|
||||
Examples:
|
||||
|
||||
/* Attach to an Ethernet device with autodetected PHY */
|
||||
&enet {
|
||||
rxc-skew-ps = <1800>;
|
||||
rxdv-skew-ps = <0>;
|
||||
txc-skew-ps = <1800>;
|
||||
txen-skew-ps = <0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* Attach to an explicitly-specified PHY */
|
||||
mdio {
|
||||
phy0: ethernet-phy@0 {
|
||||
rxc-skew-ps = <3000>;
|
||||
rxc-skew-ps = <1800>;
|
||||
rxdv-skew-ps = <0>;
|
||||
txc-skew-ps = <3000>;
|
||||
txc-skew-ps = <1800>;
|
||||
txen-skew-ps = <0>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
@ -133,3 +208,20 @@ Examples:
|
|||
phy = <&phy0>;
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
|
||||
References
|
||||
|
||||
Micrel ksz9021rl/rn Data Sheet, Revision 1.2. Dated 2/13/2014.
|
||||
http://www.micrel.com/_PDF/Ethernet/datasheets/ksz9021rl-rn_ds.pdf
|
||||
|
||||
Micrel ksz9031rnx Data Sheet, Revision 2.1. Dated 11/20/2014.
|
||||
http://www.micrel.com/_PDF/Ethernet/datasheets/KSZ9031RNX.pdf
|
||||
|
||||
Notes:
|
||||
|
||||
Note that a previous version of the Micrel ksz9021rl/rn Data Sheet
|
||||
was missing extended register 106 (transmit data pad skews), and
|
||||
incorrectly specified the ps per step as 200ps/step instead of
|
||||
120ps/step. The latest update to this document reflects the latest
|
||||
revision of the Micrel specification even though usage in the kernel
|
||||
still reflects that incorrect document.
|
||||
|
|
|
@ -976,9 +976,9 @@ constraints on coalescing parameters and their values.
|
|||
|
||||
|
||||
PAUSE_GET
|
||||
============
|
||||
=========
|
||||
|
||||
Gets channel counts like ``ETHTOOL_GPAUSE`` ioctl request.
|
||||
Gets pause frame settings like ``ETHTOOL_GPAUSEPARAM`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
|
@ -1007,7 +1007,7 @@ the statistics in the following structure:
|
|||
Each member has a corresponding attribute defined.
|
||||
|
||||
PAUSE_SET
|
||||
============
|
||||
=========
|
||||
|
||||
Sets pause parameters like ``ETHTOOL_GPAUSEPARAM`` ioctl request.
|
||||
|
||||
|
@ -1024,7 +1024,7 @@ Request contents:
|
|||
EEE_GET
|
||||
=======
|
||||
|
||||
Gets channel counts like ``ETHTOOL_GEEE`` ioctl request.
|
||||
Gets Energy Efficient Ethernet settings like ``ETHTOOL_GEEE`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
|
@ -1054,7 +1054,7 @@ first 32 are provided by the ``ethtool_ops`` callback.
|
|||
EEE_SET
|
||||
=======
|
||||
|
||||
Sets pause parameters like ``ETHTOOL_GEEEPARAM`` ioctl request.
|
||||
Sets Energy Efficient Ethernet parameters like ``ETHTOOL_SEEE`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
|
|
30
MAINTAINERS
30
MAINTAINERS
|
@ -1790,19 +1790,26 @@ F: drivers/net/ethernet/cortina/
|
|||
F: drivers/pinctrl/pinctrl-gemini.c
|
||||
F: drivers/rtc/rtc-ftrtc010.c
|
||||
|
||||
ARM/CZ.NIC TURRIS MOX SUPPORT
|
||||
M: Marek Behun <marek.behun@nic.cz>
|
||||
ARM/CZ.NIC TURRIS SUPPORT
|
||||
M: Marek Behun <kabel@kernel.org>
|
||||
S: Maintained
|
||||
W: http://mox.turris.cz
|
||||
W: https://www.turris.cz/
|
||||
F: Documentation/ABI/testing/debugfs-moxtet
|
||||
F: Documentation/ABI/testing/sysfs-bus-moxtet-devices
|
||||
F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
|
||||
F: Documentation/devicetree/bindings/bus/moxtet.txt
|
||||
F: Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
|
||||
F: Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
|
||||
F: Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml
|
||||
F: Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt
|
||||
F: drivers/bus/moxtet.c
|
||||
F: drivers/firmware/turris-mox-rwtm.c
|
||||
F: drivers/leds/leds-turris-omnia.c
|
||||
F: drivers/mailbox/armada-37xx-rwtm-mailbox.c
|
||||
F: drivers/gpio/gpio-moxtet.c
|
||||
F: drivers/watchdog/armada_37xx_wdt.c
|
||||
F: include/dt-bindings/bus/moxtet.h
|
||||
F: include/linux/armada-37xx-rwtm-mailbox.h
|
||||
F: include/linux/moxtet.h
|
||||
|
||||
ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
|
||||
|
@ -7474,8 +7481,9 @@ F: include/uapi/asm-generic/
|
|||
GENERIC PHY FRAMEWORK
|
||||
M: Kishon Vijay Abraham I <kishon@ti.com>
|
||||
M: Vinod Koul <vkoul@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-phy@lists.infradead.org
|
||||
S: Supported
|
||||
Q: https://patchwork.kernel.org/project/linux-phy/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git
|
||||
F: Documentation/devicetree/bindings/phy/
|
||||
F: drivers/phy/
|
||||
|
@ -14851,6 +14859,14 @@ L: linux-arm-msm@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/iommu/arm/arm-smmu/qcom_iommu.c
|
||||
|
||||
QUALCOMM IPC ROUTER (QRTR) DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/trace/events/qrtr.h
|
||||
F: include/uapi/linux/qrtr.h
|
||||
F: net/qrtr/
|
||||
|
||||
QUALCOMM IPCC MAILBOX DRIVER
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
|
@ -15200,6 +15216,7 @@ F: fs/reiserfs/
|
|||
REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM
|
||||
M: Ohad Ben-Cohen <ohad@wizery.com>
|
||||
M: Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
M: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
L: linux-remoteproc@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git rproc-next
|
||||
|
@ -15213,6 +15230,7 @@ F: include/linux/remoteproc/
|
|||
REMOTE PROCESSOR MESSAGING (RPMSG) SUBSYSTEM
|
||||
M: Ohad Ben-Cohen <ohad@wizery.com>
|
||||
M: Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
M: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
L: linux-remoteproc@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git rpmsg-next
|
||||
|
@ -15629,8 +15647,8 @@ F: Documentation/s390/pci.rst
|
|||
|
||||
S390 VFIO AP DRIVER
|
||||
M: Tony Krowiak <akrowiak@linux.ibm.com>
|
||||
M: Pierre Morel <pmorel@linux.ibm.com>
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Jason Herne <jjherne@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
|
@ -15642,6 +15660,7 @@ F: drivers/s390/crypto/vfio_ap_private.h
|
|||
S390 VFIO-CCW DRIVER
|
||||
M: Cornelia Huck <cohuck@redhat.com>
|
||||
M: Eric Farman <farman@linux.ibm.com>
|
||||
M: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
R: Halil Pasic <pasic@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: kvm@vger.kernel.org
|
||||
|
@ -15652,6 +15671,7 @@ F: include/uapi/linux/vfio_ccw.h
|
|||
|
||||
S390 VFIO-PCI DRIVER
|
||||
M: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
M: Eric Farman <farman@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
VERSION = 5
|
||||
PATCHLEVEL = 12
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Frozen Wasteland
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
memory {
|
||||
device_type = "memory";
|
||||
/* CONFIG_LINUX_RAM_BASE needs to match low mem start */
|
||||
reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MB low mem */
|
||||
reg = <0x0 0x80000000 0x0 0x40000000 /* 1 GB low mem */
|
||||
0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */
|
||||
};
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
|
|||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
|
||||
|
||||
return err;
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
|
||||
|
@ -110,7 +110,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
|
|||
&(sf->uc.uc_mcontext.regs.scratch),
|
||||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||
if (err)
|
||||
return err;
|
||||
return -EFAULT;
|
||||
|
||||
set_current_blocked(&set);
|
||||
regs->bta = uregs.scratch.bta;
|
||||
|
|
|
@ -187,25 +187,26 @@ static void init_unwind_table(struct unwind_table *table, const char *name,
|
|||
const void *table_start, unsigned long table_size,
|
||||
const u8 *header_start, unsigned long header_size)
|
||||
{
|
||||
const u8 *ptr = header_start + 4;
|
||||
const u8 *end = header_start + header_size;
|
||||
|
||||
table->core.pc = (unsigned long)core_start;
|
||||
table->core.range = core_size;
|
||||
table->init.pc = (unsigned long)init_start;
|
||||
table->init.range = init_size;
|
||||
table->address = table_start;
|
||||
table->size = table_size;
|
||||
|
||||
/* See if the linker provided table looks valid. */
|
||||
if (header_size <= 4
|
||||
|| header_start[0] != 1
|
||||
|| (void *)read_pointer(&ptr, end, header_start[1]) != table_start
|
||||
|| header_start[2] == DW_EH_PE_omit
|
||||
|| read_pointer(&ptr, end, header_start[2]) <= 0
|
||||
|| header_start[3] == DW_EH_PE_omit)
|
||||
header_start = NULL;
|
||||
|
||||
/* To avoid the pointer addition with NULL pointer.*/
|
||||
if (header_start != NULL) {
|
||||
const u8 *ptr = header_start + 4;
|
||||
const u8 *end = header_start + header_size;
|
||||
/* See if the linker provided table looks valid. */
|
||||
if (header_size <= 4
|
||||
|| header_start[0] != 1
|
||||
|| (void *)read_pointer(&ptr, end, header_start[1])
|
||||
!= table_start
|
||||
|| header_start[2] == DW_EH_PE_omit
|
||||
|| read_pointer(&ptr, end, header_start[2]) <= 0
|
||||
|| header_start[3] == DW_EH_PE_omit)
|
||||
header_start = NULL;
|
||||
}
|
||||
table->hdrsz = header_size;
|
||||
smp_wmb();
|
||||
table->header = header_start;
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
|
||||
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
|
||||
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
|
||||
MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
|
||||
MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
|
||||
MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
|
||||
|
||||
internal-regs {
|
||||
|
||||
|
@ -389,6 +390,7 @@
|
|||
phy1: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <1>;
|
||||
marvell,reg-init = <3 18 0 0x4985>;
|
||||
|
||||
/* irq is connected to &pcawan pin 7 */
|
||||
};
|
||||
|
|
|
@ -308,14 +308,6 @@
|
|||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
bsc_intr: interrupt-controller@7ef00040 {
|
||||
compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
|
||||
reg = <0x7ef00040 0x30>;
|
||||
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
||||
aon_intr: interrupt-controller@7ef00100 {
|
||||
compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
|
||||
reg = <0x7ef00100 0x30>;
|
||||
|
@ -362,8 +354,6 @@
|
|||
reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>;
|
||||
reg-names = "bsc", "auto-i2c";
|
||||
clock-frequency = <97500>;
|
||||
interrupt-parent = <&bsc_intr>;
|
||||
interrupts = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -405,8 +395,6 @@
|
|||
reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>;
|
||||
reg-names = "bsc", "auto-i2c";
|
||||
clock-frequency = <97500>;
|
||||
interrupt-parent = <&bsc_intr>;
|
||||
interrupts = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -433,6 +433,7 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <&vdd_sd1_reg>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -442,5 +443,6 @@
|
|||
&pinctrl_usdhc3_cdwp>;
|
||||
cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <&vdd_sd0_reg>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
i2c1 = &i2c2;
|
||||
i2c2 = &i2c3;
|
||||
i2c3 = &i2c4;
|
||||
mmc0 = &mmc1;
|
||||
mmc1 = &mmc2;
|
||||
mmc2 = &mmc3;
|
||||
mmc3 = &mmc4;
|
||||
mmc4 = &mmc5;
|
||||
serial0 = &uart1;
|
||||
serial1 = &uart2;
|
||||
serial2 = &uart3;
|
||||
|
|
|
@ -770,14 +770,6 @@
|
|||
ti,max-div = <2>;
|
||||
};
|
||||
|
||||
sha2md5_fck: sha2md5_fck@15c8 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,gate-clock";
|
||||
clocks = <&l3_div_ck>;
|
||||
ti,bit-shift = <1>;
|
||||
reg = <0x15c8>;
|
||||
};
|
||||
|
||||
usb_phy_cm_clk32k: usb_phy_cm_clk32k@640 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,gate-clock";
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
i2c2 = &i2c3;
|
||||
i2c3 = &i2c4;
|
||||
i2c4 = &i2c5;
|
||||
mmc0 = &mmc1;
|
||||
mmc1 = &mmc2;
|
||||
mmc2 = &mmc3;
|
||||
mmc3 = &mmc4;
|
||||
mmc4 = &mmc5;
|
||||
serial0 = &uart1;
|
||||
serial1 = &uart2;
|
||||
serial2 = &uart3;
|
||||
|
|
|
@ -65,7 +65,7 @@ static void __init keystone_init(void)
|
|||
static long long __init keystone_pv_fixup(void)
|
||||
{
|
||||
long long offset;
|
||||
phys_addr_t mem_start, mem_end;
|
||||
u64 mem_start, mem_end;
|
||||
|
||||
mem_start = memblock_start_of_DRAM();
|
||||
mem_end = memblock_end_of_DRAM();
|
||||
|
@ -78,7 +78,7 @@ static long long __init keystone_pv_fixup(void)
|
|||
if (mem_start < KEYSTONE_HIGH_PHYS_START ||
|
||||
mem_end > KEYSTONE_HIGH_PHYS_END) {
|
||||
pr_crit("Invalid address space for memory (%08llx-%08llx)\n",
|
||||
(u64)mem_start, (u64)mem_end);
|
||||
mem_start, mem_end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/platform_data/gpio-omap.h>
|
||||
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include "ams-delta-fiq.h"
|
||||
#include "board-ams-delta.h"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -20,6 +21,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "omap-secure.h"
|
||||
#include "soc.h"
|
||||
|
||||
static phys_addr_t omap_secure_memblock_base;
|
||||
|
||||
|
@ -213,3 +215,40 @@ void __init omap_secure_init(void)
|
|||
{
|
||||
omap_optee_init_check();
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy dispatcher call after core OSWR and MPU off. Updates the ROM return
|
||||
* address after MMU has been re-enabled after CPU1 has been woken up again.
|
||||
* Otherwise the ROM code will attempt to use the earlier physical return
|
||||
* address that got set with MMU off when waking up CPU1. Only used on secure
|
||||
* devices.
|
||||
*/
|
||||
static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CPU_CLUSTER_PM_EXIT:
|
||||
omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
|
||||
FLAG_START_CRITICAL,
|
||||
0, 0, 0, 0, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block secure_notifier_block = {
|
||||
.notifier_call = cpu_notifier,
|
||||
};
|
||||
|
||||
static int __init secure_pm_init(void)
|
||||
{
|
||||
if (omap_type() == OMAP2_DEVICE_TYPE_GP || !soc_is_omap44xx())
|
||||
return 0;
|
||||
|
||||
cpu_pm_register_notifier(&secure_notifier_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
omap_arch_initcall(secure_pm_init);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#define OMAP5_DRA7_MON_SET_ACR_INDEX 0x107
|
||||
|
||||
/* Secure PPA(Primary Protected Application) APIs */
|
||||
#define OMAP4_PPA_SERVICE_0 0x21
|
||||
#define OMAP4_PPA_L2_POR_INDEX 0x23
|
||||
#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
|
||||
|
||||
|
|
|
@ -246,10 +246,10 @@ int __init omap4_cpcap_init(void)
|
|||
omap_voltage_register_pmic(voltdm, &omap443x_max8952_mpu);
|
||||
|
||||
if (of_machine_is_compatible("motorola,droid-bionic")) {
|
||||
voltdm = voltdm_lookup("mpu");
|
||||
voltdm = voltdm_lookup("core");
|
||||
omap_voltage_register_pmic(voltdm, &omap_cpcap_core);
|
||||
|
||||
voltdm = voltdm_lookup("mpu");
|
||||
voltdm = voltdm_lookup("iva");
|
||||
omap_voltage_register_pmic(voltdm, &omap_cpcap_iva);
|
||||
} else {
|
||||
voltdm = voltdm_lookup("core");
|
||||
|
|
|
@ -502,16 +502,20 @@ static inline void mainstone_init_keypad(void) {}
|
|||
#endif
|
||||
|
||||
static int mst_pcmcia0_irqs[11] = {
|
||||
[0 ... 10] = -1,
|
||||
[0 ... 4] = -1,
|
||||
[5] = MAINSTONE_S0_CD_IRQ,
|
||||
[6 ... 7] = -1,
|
||||
[8] = MAINSTONE_S0_STSCHG_IRQ,
|
||||
[9] = -1,
|
||||
[10] = MAINSTONE_S0_IRQ,
|
||||
};
|
||||
|
||||
static int mst_pcmcia1_irqs[11] = {
|
||||
[0 ... 10] = -1,
|
||||
[0 ... 4] = -1,
|
||||
[5] = MAINSTONE_S1_CD_IRQ,
|
||||
[6 ... 7] = -1,
|
||||
[8] = MAINSTONE_S1_STSCHG_IRQ,
|
||||
[9] = -1,
|
||||
[10] = MAINSTONE_S1_IRQ,
|
||||
};
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
#define MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0
|
||||
#define MX8MM_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0
|
||||
#define MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0
|
||||
#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0
|
||||
#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x310 0x000 0x5 0x0
|
||||
#define MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0
|
||||
#define MX8MM_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0
|
||||
#define MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
#define MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x310 0x000 0x5 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0
|
||||
#define MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Device Tree file for CZ.NIC Turris Mox Board
|
||||
* 2019 by Marek Behun <marek.behun@nic.cz>
|
||||
* 2019 by Marek Behún <kabel@kernel.org>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
|
|
@ -310,9 +310,11 @@
|
|||
};
|
||||
|
||||
CP11X_LABEL(sata0): sata@540000 {
|
||||
compatible = "marvell,armada-8k-ahci";
|
||||
compatible = "marvell,armada-8k-ahci",
|
||||
"generic-ahci";
|
||||
reg = <0x540000 0x30000>;
|
||||
dma-coherent;
|
||||
interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&CP11X_LABEL(clk) 1 15>,
|
||||
<&CP11X_LABEL(clk) 1 16>;
|
||||
#address-cells = <1>;
|
||||
|
@ -320,12 +322,10 @@
|
|||
status = "disabled";
|
||||
|
||||
sata-port@0 {
|
||||
interrupts = <109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
sata-port@1 {
|
||||
interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -278,6 +278,7 @@
|
|||
#define CPTR_EL2_DEFAULT CPTR_EL2_RES1
|
||||
|
||||
/* Hyp Debug Configuration Register bits */
|
||||
#define MDCR_EL2_TTRF (1 << 19)
|
||||
#define MDCR_EL2_TPMS (1 << 14)
|
||||
#define MDCR_EL2_E2PB_MASK (UL(0x3))
|
||||
#define MDCR_EL2_E2PB_SHIFT (UL(12))
|
||||
|
|
|
@ -383,7 +383,6 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
|
|||
* of support.
|
||||
*/
|
||||
S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
|
|
@ -89,6 +89,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
|
|||
* - Debug ROM Address (MDCR_EL2_TDRA)
|
||||
* - OS related registers (MDCR_EL2_TDOSA)
|
||||
* - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB)
|
||||
* - Self-hosted Trace Filter controls (MDCR_EL2_TTRF)
|
||||
*
|
||||
* Additionally, KVM only traps guest accesses to the debug registers if
|
||||
* the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY
|
||||
|
@ -112,6 +113,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
|
|||
vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
|
||||
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
|
||||
MDCR_EL2_TPMS |
|
||||
MDCR_EL2_TTRF |
|
||||
MDCR_EL2_TPMCR |
|
||||
MDCR_EL2_TDRA |
|
||||
MDCR_EL2_TDOSA);
|
||||
|
|
|
@ -429,6 +429,13 @@ u64 __vgic_v3_get_gic_config(void)
|
|||
if (has_vhe())
|
||||
flags = local_daif_save();
|
||||
|
||||
/*
|
||||
* Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates
|
||||
* that to be able to set ICC_SRE_EL1.SRE to 0, all the
|
||||
* interrupt overrides must be set. You've got to love this.
|
||||
*/
|
||||
sysreg_clear_set(hcr_el2, 0, HCR_AMO | HCR_FMO | HCR_IMO);
|
||||
isb();
|
||||
write_gicreg(0, ICC_SRE_EL1);
|
||||
isb();
|
||||
|
||||
|
@ -436,6 +443,8 @@ u64 __vgic_v3_get_gic_config(void)
|
|||
|
||||
write_gicreg(sre, ICC_SRE_EL1);
|
||||
isb();
|
||||
sysreg_clear_set(hcr_el2, HCR_AMO | HCR_FMO | HCR_IMO, 0);
|
||||
isb();
|
||||
|
||||
if (has_vhe())
|
||||
local_daif_restore(flags);
|
||||
|
|
|
@ -54,8 +54,7 @@
|
|||
|
||||
static inline unsigned long user_stack_pointer(struct pt_regs *regs)
|
||||
{
|
||||
/* FIXME: should this be bspstore + nr_dirty regs? */
|
||||
return regs->ar_bspstore;
|
||||
return regs->r12;
|
||||
}
|
||||
|
||||
static inline int is_syscall_success(struct pt_regs *regs)
|
||||
|
@ -79,11 +78,6 @@ static inline long regs_return_value(struct pt_regs *regs)
|
|||
unsigned long __ip = instruction_pointer(regs); \
|
||||
(__ip & ~3UL) + ((__ip & 3UL) << 2); \
|
||||
})
|
||||
/*
|
||||
* Why not default? Because user_stack_pointer() on ia64 gives register
|
||||
* stack backing store instead...
|
||||
*/
|
||||
#define current_user_stack_pointer() (current_pt_regs()->r12)
|
||||
|
||||
/* given a pointer to a task_struct, return the user's pt_regs */
|
||||
# define task_pt_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
|
||||
|
|
|
@ -167,7 +167,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
|
|||
((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
|
||||
})
|
||||
#else
|
||||
#define ARCH_PFN_OFFSET (m68k_memory[0].addr)
|
||||
#define ARCH_PFN_OFFSET (m68k_memory[0].addr >> PAGE_SHIFT)
|
||||
#include <asm-generic/memory_model.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include <asm/prom.h>
|
||||
|
||||
#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
|
||||
const char __section(".appended_dtb") __appended_dtb[0x100000];
|
||||
char __section(".appended_dtb") __appended_dtb[0x100000];
|
||||
#endif /* CONFIG_MIPS_ELF_APPENDED_DTB */
|
||||
|
||||
struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
|
||||
|
|
|
@ -238,7 +238,7 @@ void flush_dcache_page(struct page *page)
|
|||
{
|
||||
struct address_space *mapping;
|
||||
|
||||
mapping = page_mapping(page);
|
||||
mapping = page_mapping_file(page);
|
||||
if (mapping && !mapping_mapped(mapping))
|
||||
set_bit(PG_dcache_dirty, &page->flags);
|
||||
else {
|
||||
|
|
|
@ -72,7 +72,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
|
|||
#endif
|
||||
case 4: return __cmpxchg_u32((unsigned int *)ptr,
|
||||
(unsigned int)old, (unsigned int)new_);
|
||||
case 1: return __cmpxchg_u8((u8 *)ptr, (u8)old, (u8)new_);
|
||||
case 1: return __cmpxchg_u8((u8 *)ptr, old & 0xff, new_ & 0xff);
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
|
|
|
@ -272,7 +272,6 @@ on downward growing arches, it looks like this:
|
|||
regs->gr[23] = 0; \
|
||||
} while(0)
|
||||
|
||||
struct task_struct;
|
||||
struct mm_struct;
|
||||
|
||||
/* Free all resources held by a thread. */
|
||||
|
|
|
@ -5,34 +5,10 @@
|
|||
* Floating-point emulation code
|
||||
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
|
||||
*/
|
||||
/*
|
||||
* BEGIN_DESC
|
||||
*
|
||||
* File:
|
||||
* @(#) pa/fp/fpu.h $Revision: 1.1 $
|
||||
*
|
||||
* Purpose:
|
||||
* <<please update with a synopis of the functionality provided by this file>>
|
||||
*
|
||||
*
|
||||
* END_DESC
|
||||
*/
|
||||
|
||||
#ifdef __NO_PA_HDRS
|
||||
PA header file -- do not include this header file for non-PA builds.
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _MACHINE_FPU_INCLUDED /* allows multiple inclusion */
|
||||
#define _MACHINE_FPU_INCLUDED
|
||||
|
||||
#if 0
|
||||
#ifndef _SYS_STDSYMS_INCLUDED
|
||||
# include <sys/stdsyms.h>
|
||||
#endif /* _SYS_STDSYMS_INCLUDED */
|
||||
#include <machine/pdc/pdc_rqsts.h>
|
||||
#endif
|
||||
|
||||
#define PA83_FPU_FLAG 0x00000001
|
||||
#define PA89_FPU_FLAG 0x00000002
|
||||
#define PA2_0_FPU_FLAG 0x00000010
|
||||
|
@ -43,21 +19,19 @@
|
|||
#define COPR_FP 0x00000080 /* Floating point -- Coprocessor 0 */
|
||||
#define SFU_MPY_DIVIDE 0x00008000 /* Multiply/Divide __ SFU 0 */
|
||||
|
||||
|
||||
#define EM_FPU_TYPE_OFFSET 272
|
||||
|
||||
/* version of EMULATION software for COPR,0,0 instruction */
|
||||
#define EMULATION_VERSION 4
|
||||
|
||||
/*
|
||||
* The only was to differeniate between TIMEX and ROLEX (or PCX-S and PCX-T)
|
||||
* is thorough the potential type field from the PDC_MODEL call. The
|
||||
* following flags are used at assist this differeniation.
|
||||
* The only way to differentiate between TIMEX and ROLEX (or PCX-S and PCX-T)
|
||||
* is through the potential type field from the PDC_MODEL call.
|
||||
* The following flags are used to assist this differentiation.
|
||||
*/
|
||||
|
||||
#define ROLEX_POTENTIAL_KEY_FLAGS PDC_MODEL_CPU_KEY_WORD_TO_IO
|
||||
#define TIMEX_POTENTIAL_KEY_FLAGS (PDC_MODEL_CPU_KEY_QUAD_STORE | \
|
||||
PDC_MODEL_CPU_KEY_RECIP_SQRT)
|
||||
|
||||
|
||||
#endif /* ! _MACHINE_FPU_INCLUDED */
|
||||
|
|
|
@ -191,3 +191,7 @@ $(obj)/prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o FORCE
|
|||
targets += prom_init_check
|
||||
|
||||
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
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
|
||||
|
||||
obj-y += ptrace.o ptrace-view.o
|
||||
obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o
|
||||
obj-y += ptrace-fpu.o
|
||||
obj-$(CONFIG_COMPAT) += ptrace32.o
|
||||
obj-$(CONFIG_VSX) += ptrace-vsx.o
|
||||
ifneq ($(CONFIG_VSX),y)
|
||||
obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o
|
||||
obj-y += ptrace-novsx.o
|
||||
endif
|
||||
obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
|
||||
obj-$(CONFIG_SPE) += ptrace-spe.o
|
||||
|
|
|
@ -165,22 +165,8 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
|
|||
extern const struct user_regset_view user_ppc_native_view;
|
||||
|
||||
/* ptrace-fpu */
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
|
||||
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
|
||||
#else
|
||||
static inline int
|
||||
ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ptrace-(no)adv */
|
||||
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
|
||||
|
|
|
@ -8,32 +8,42 @@
|
|||
|
||||
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
#endif
|
||||
|
||||
if (index > PT_FPSCR)
|
||||
return -EIO;
|
||||
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
|
||||
else
|
||||
*data = child->thread.fp_state.fpscr;
|
||||
#else
|
||||
*data = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
#endif
|
||||
|
||||
if (index > PT_FPSCR)
|
||||
return -EIO;
|
||||
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
|
||||
else
|
||||
child->thread.fp_state.fpscr = data;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
int fpr_get(struct task_struct *target, const struct user_regset *regset,
|
||||
struct membuf to)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
|
||||
offsetof(struct thread_fp_state, fpr[32]));
|
||||
|
||||
flush_fp_to_thread(target);
|
||||
|
||||
return membuf_write(&to, &target->thread.fp_state, 33 * sizeof(u64));
|
||||
#else
|
||||
return membuf_write(&to, &empty_zero_page, 33 * sizeof(u64));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -46,6 +50,7 @@ int fpr_set(struct task_struct *target, const struct user_regset *regset,
|
|||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
|
||||
offsetof(struct thread_fp_state, fpr[32]));
|
||||
|
||||
|
@ -53,4 +58,7 @@ int fpr_set(struct task_struct *target, const struct user_regset *regset,
|
|||
|
||||
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.fp_state, 0, -1);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -522,13 +522,11 @@ static const struct user_regset native_regsets[] = {
|
|||
.size = sizeof(long), .align = sizeof(long),
|
||||
.regset_get = gpr_get, .set = gpr_set
|
||||
},
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
[REGSET_FPR] = {
|
||||
.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
|
||||
.size = sizeof(double), .align = sizeof(double),
|
||||
.regset_get = fpr_get, .set = fpr_set
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
[REGSET_VMX] = {
|
||||
.core_note_type = NT_PPC_VMX, .n = 34,
|
||||
|
|
|
@ -775,7 +775,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
else
|
||||
prepare_save_user_regs(1);
|
||||
|
||||
if (!user_write_access_begin(frame, sizeof(*frame)))
|
||||
if (!user_access_begin(frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
||||
/* Put the siginfo & fill in most of the ucontext */
|
||||
|
@ -809,17 +809,15 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
unsafe_put_user(PPC_INST_ADDI + __NR_rt_sigreturn, &mctx->mc_pad[0],
|
||||
failed);
|
||||
unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed);
|
||||
asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
|
||||
}
|
||||
unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed);
|
||||
|
||||
user_write_access_end();
|
||||
user_access_end();
|
||||
|
||||
if (copy_siginfo_to_user(&frame->info, &ksig->info))
|
||||
goto badframe;
|
||||
|
||||
if (tramp == (unsigned long)mctx->mc_pad)
|
||||
flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
|
||||
|
||||
regs->link = tramp;
|
||||
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
|
@ -844,7 +842,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
user_write_access_end();
|
||||
user_access_end();
|
||||
|
||||
badframe:
|
||||
signal_fault(tsk, regs, "handle_rt_signal32", frame);
|
||||
|
@ -879,7 +877,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
else
|
||||
prepare_save_user_regs(1);
|
||||
|
||||
if (!user_write_access_begin(frame, sizeof(*frame)))
|
||||
if (!user_access_begin(frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
sc = (struct sigcontext __user *) &frame->sctx;
|
||||
|
||||
|
@ -908,11 +906,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
/* Set up the sigreturn trampoline: li r0,sigret; sc */
|
||||
unsafe_put_user(PPC_INST_ADDI + __NR_sigreturn, &mctx->mc_pad[0], failed);
|
||||
unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed);
|
||||
asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
|
||||
}
|
||||
user_write_access_end();
|
||||
|
||||
if (tramp == (unsigned long)mctx->mc_pad)
|
||||
flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
|
||||
user_access_end();
|
||||
|
||||
regs->link = tramp;
|
||||
|
||||
|
@ -935,7 +931,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
user_write_access_end();
|
||||
user_access_end();
|
||||
|
||||
badframe:
|
||||
signal_fault(tsk, regs, "handle_signal32", frame);
|
||||
|
|
|
@ -887,7 +887,8 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
|
|||
|
||||
want_v = hpte_encode_avpn(vpn, psize, ssize);
|
||||
|
||||
flags = (newpp & 7) | H_AVPN;
|
||||
flags = (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO)) | H_AVPN;
|
||||
flags |= (newpp & HPTE_R_KEY_HI) >> 48;
|
||||
if (mmu_has_feature(MMU_FTR_KERNEL_RO))
|
||||
/* Move pp0 into bit 8 (IBM 55) */
|
||||
flags |= (newpp & HPTE_R_PP0) >> 55;
|
||||
|
|
|
@ -452,12 +452,28 @@ static int do_suspend(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct pseries_suspend_info - State shared between CPUs for join/suspend.
|
||||
* @counter: Threads are to increment this upon resuming from suspend
|
||||
* or if an error is received from H_JOIN. The thread which performs
|
||||
* the first increment (i.e. sets it to 1) is responsible for
|
||||
* waking the other threads.
|
||||
* @done: False if join/suspend is in progress. True if the operation is
|
||||
* complete (successful or not).
|
||||
*/
|
||||
struct pseries_suspend_info {
|
||||
atomic_t counter;
|
||||
bool done;
|
||||
};
|
||||
|
||||
static int do_join(void *arg)
|
||||
{
|
||||
atomic_t *counter = arg;
|
||||
struct pseries_suspend_info *info = arg;
|
||||
atomic_t *counter = &info->counter;
|
||||
long hvrc;
|
||||
int ret;
|
||||
|
||||
retry:
|
||||
/* Must ensure MSR.EE off for H_JOIN. */
|
||||
hard_irq_disable();
|
||||
hvrc = plpar_hcall_norets(H_JOIN);
|
||||
|
@ -473,8 +489,20 @@ static int do_join(void *arg)
|
|||
case H_SUCCESS:
|
||||
/*
|
||||
* The suspend is complete and this cpu has received a
|
||||
* prod.
|
||||
* prod, or we've received a stray prod from unrelated
|
||||
* code (e.g. paravirt spinlocks) and we need to join
|
||||
* again.
|
||||
*
|
||||
* This barrier orders the return from H_JOIN above vs
|
||||
* the load of info->done. It pairs with the barrier
|
||||
* in the wakeup/prod path below.
|
||||
*/
|
||||
smp_mb();
|
||||
if (READ_ONCE(info->done) == false) {
|
||||
pr_info_ratelimited("premature return from H_JOIN on CPU %i, retrying",
|
||||
smp_processor_id());
|
||||
goto retry;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case H_BAD_MODE:
|
||||
|
@ -488,6 +516,13 @@ static int do_join(void *arg)
|
|||
|
||||
if (atomic_inc_return(counter) == 1) {
|
||||
pr_info("CPU %u waking all threads\n", smp_processor_id());
|
||||
WRITE_ONCE(info->done, true);
|
||||
/*
|
||||
* This barrier orders the store to info->done vs subsequent
|
||||
* H_PRODs to wake the other CPUs. It pairs with the barrier
|
||||
* in the H_SUCCESS case above.
|
||||
*/
|
||||
smp_mb();
|
||||
prod_others();
|
||||
}
|
||||
/*
|
||||
|
@ -535,11 +570,16 @@ static int pseries_suspend(u64 handle)
|
|||
int ret;
|
||||
|
||||
while (true) {
|
||||
atomic_t counter = ATOMIC_INIT(0);
|
||||
struct pseries_suspend_info info;
|
||||
unsigned long vasi_state;
|
||||
int vasi_err;
|
||||
|
||||
ret = stop_machine(do_join, &counter, cpu_online_mask);
|
||||
info = (struct pseries_suspend_info) {
|
||||
.counter = ATOMIC_INIT(0),
|
||||
.done = false,
|
||||
};
|
||||
|
||||
ret = stop_machine(do_join, &info, cpu_online_mask);
|
||||
if (ret == 0)
|
||||
break;
|
||||
/*
|
||||
|
|
|
@ -314,7 +314,7 @@ endchoice
|
|||
# Common NUMA Features
|
||||
config NUMA
|
||||
bool "NUMA Memory Allocation and Scheduler Support"
|
||||
depends on SMP
|
||||
depends on SMP && MMU
|
||||
select GENERIC_ARCH_NUMA
|
||||
select OF_NUMA
|
||||
select ARCH_SUPPORTS_NUMA_BALANCING
|
||||
|
|
|
@ -306,7 +306,9 @@ do { \
|
|||
* data types like structures or arrays.
|
||||
*
|
||||
* @ptr must have pointer-to-simple-variable type, and @x must be assignable
|
||||
* to the result of dereferencing @ptr.
|
||||
* to the result of dereferencing @ptr. The value of @x is copied to avoid
|
||||
* re-ordering where @x is evaluated inside the block that enables user-space
|
||||
* access (thus bypassing user space protection if @x is a function).
|
||||
*
|
||||
* Caller must check the pointer with access_ok() before calling this
|
||||
* function.
|
||||
|
@ -316,12 +318,13 @@ do { \
|
|||
#define __put_user(x, ptr) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
|
||||
__typeof__(*__gu_ptr) __val = (x); \
|
||||
long __pu_err = 0; \
|
||||
\
|
||||
__chk_user_ptr(__gu_ptr); \
|
||||
\
|
||||
__enable_user_access(); \
|
||||
__put_user_nocheck(x, __gu_ptr, __pu_err); \
|
||||
__put_user_nocheck(__val, __gu_ptr, __pu_err); \
|
||||
__disable_user_access(); \
|
||||
\
|
||||
__pu_err; \
|
||||
|
|
|
@ -447,6 +447,7 @@ ENDPROC(__switch_to)
|
|||
#endif
|
||||
|
||||
.section ".rodata"
|
||||
.align LGREG
|
||||
/* Exception vector table */
|
||||
ENTRY(excp_vect_table)
|
||||
RISCV_PTR do_trap_insn_misaligned
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <asm/stacktrace.h>
|
||||
|
||||
register const unsigned long sp_in_global __asm__("sp");
|
||||
register unsigned long sp_in_global __asm__("sp");
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ void __init kasan_init(void)
|
|||
break;
|
||||
|
||||
kasan_populate(kasan_mem_to_shadow(start), kasan_mem_to_shadow(end));
|
||||
};
|
||||
}
|
||||
|
||||
for (i = 0; i < PTRS_PER_PTE; i++)
|
||||
set_pte(&kasan_early_shadow_pte[i],
|
||||
|
|
|
@ -12,6 +12,7 @@ enum stack_type {
|
|||
STACK_TYPE_IRQ,
|
||||
STACK_TYPE_NODAT,
|
||||
STACK_TYPE_RESTART,
|
||||
STACK_TYPE_MCCK,
|
||||
};
|
||||
|
||||
struct stack_info {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <vdso/datapage.h>
|
||||
|
||||
struct arch_vdso_data {
|
||||
__u64 tod_steering_delta;
|
||||
__s64 tod_steering_delta;
|
||||
__u64 tod_steering_end;
|
||||
};
|
||||
|
||||
|
|
|
@ -37,10 +37,12 @@ static int diag8_noresponse(int cmdlen)
|
|||
|
||||
static int diag8_response(int cmdlen, char *response, int *rlen)
|
||||
{
|
||||
unsigned long _cmdlen = cmdlen | 0x40000000L;
|
||||
unsigned long _rlen = *rlen;
|
||||
register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
|
||||
register unsigned long reg3 asm ("3") = (addr_t) response;
|
||||
register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
|
||||
register unsigned long reg5 asm ("5") = *rlen;
|
||||
register unsigned long reg4 asm ("4") = _cmdlen;
|
||||
register unsigned long reg5 asm ("5") = _rlen;
|
||||
|
||||
asm volatile(
|
||||
" diag %2,%0,0x8\n"
|
||||
|
|
|
@ -79,6 +79,15 @@ static bool in_nodat_stack(unsigned long sp, struct stack_info *info)
|
|||
return in_stack(sp, info, STACK_TYPE_NODAT, top - THREAD_SIZE, top);
|
||||
}
|
||||
|
||||
static bool in_mcck_stack(unsigned long sp, struct stack_info *info)
|
||||
{
|
||||
unsigned long frame_size, top;
|
||||
|
||||
frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
|
||||
top = S390_lowcore.mcck_stack + frame_size;
|
||||
return in_stack(sp, info, STACK_TYPE_MCCK, top - THREAD_SIZE, top);
|
||||
}
|
||||
|
||||
static bool in_restart_stack(unsigned long sp, struct stack_info *info)
|
||||
{
|
||||
unsigned long frame_size, top;
|
||||
|
@ -108,7 +117,8 @@ int get_stack_info(unsigned long sp, struct task_struct *task,
|
|||
/* Check per-cpu stacks */
|
||||
if (!in_irq_stack(sp, info) &&
|
||||
!in_nodat_stack(sp, info) &&
|
||||
!in_restart_stack(sp, info))
|
||||
!in_restart_stack(sp, info) &&
|
||||
!in_mcck_stack(sp, info))
|
||||
goto unknown;
|
||||
|
||||
recursion_check:
|
||||
|
|
|
@ -174,7 +174,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
|
|||
|
||||
memcpy(®s->int_code, &S390_lowcore.ext_cpu_addr, 4);
|
||||
regs->int_parm = S390_lowcore.ext_params;
|
||||
regs->int_parm_long = *(unsigned long *)S390_lowcore.ext_params2;
|
||||
regs->int_parm_long = S390_lowcore.ext_params2;
|
||||
|
||||
from_idle = !user_mode(regs) && regs->psw.addr == (unsigned long)psw_idle_exit;
|
||||
if (from_idle)
|
||||
|
|
|
@ -354,7 +354,7 @@ static int __init stack_realloc(void)
|
|||
if (!new)
|
||||
panic("Couldn't allocate machine check stack");
|
||||
WRITE_ONCE(S390_lowcore.mcck_stack, new + STACK_INIT_OFFSET);
|
||||
memblock_free(old, THREAD_SIZE);
|
||||
memblock_free_late(old, THREAD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
early_initcall(stack_realloc);
|
||||
|
|
|
@ -80,10 +80,12 @@ void __init time_early_init(void)
|
|||
{
|
||||
struct ptff_qto qto;
|
||||
struct ptff_qui qui;
|
||||
int cs;
|
||||
|
||||
/* Initialize TOD steering parameters */
|
||||
tod_steering_end = tod_clock_base.tod;
|
||||
vdso_data->arch_data.tod_steering_end = tod_steering_end;
|
||||
for (cs = 0; cs < CS_BASES; cs++)
|
||||
vdso_data[cs].arch_data.tod_steering_end = tod_steering_end;
|
||||
|
||||
if (!test_facility(28))
|
||||
return;
|
||||
|
@ -366,6 +368,7 @@ static void clock_sync_global(unsigned long delta)
|
|||
{
|
||||
unsigned long now, adj;
|
||||
struct ptff_qto qto;
|
||||
int cs;
|
||||
|
||||
/* Fixup the monotonic sched clock. */
|
||||
tod_clock_base.eitod += delta;
|
||||
|
@ -381,7 +384,10 @@ static void clock_sync_global(unsigned long delta)
|
|||
panic("TOD clock sync offset %li is too large to drift\n",
|
||||
tod_steering_delta);
|
||||
tod_steering_end = now + (abs(tod_steering_delta) << 15);
|
||||
vdso_data->arch_data.tod_steering_end = tod_steering_end;
|
||||
for (cs = 0; cs < CS_BASES; cs++) {
|
||||
vdso_data[cs].arch_data.tod_steering_end = tod_steering_end;
|
||||
vdso_data[cs].arch_data.tod_steering_delta = tod_steering_delta;
|
||||
}
|
||||
|
||||
/* Update LPAR offset. */
|
||||
if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0)
|
||||
|
|
|
@ -56,8 +56,13 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
|
|||
else
|
||||
set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
|
||||
|
||||
/* Flush this CPU's TLB. */
|
||||
/*
|
||||
* Flush this CPU's TLB, assuming whoever did the allocation/free is
|
||||
* likely to continue running on this CPU.
|
||||
*/
|
||||
preempt_disable();
|
||||
flush_tlb_one_kernel(addr);
|
||||
preempt_enable();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ void native_play_dead(void);
|
|||
void play_dead_common(void);
|
||||
void wbinvd_on_cpu(int cpu);
|
||||
int wbinvd_on_all_cpus(void);
|
||||
void cond_wakeup_cpu0(void);
|
||||
|
||||
void native_smp_send_reschedule(int cpu);
|
||||
void native_send_call_func_ipi(const struct cpumask *mask);
|
||||
|
|
|
@ -1554,10 +1554,18 @@ void __init acpi_boot_table_init(void)
|
|||
/*
|
||||
* Initialize the ACPI boot-time table parser.
|
||||
*/
|
||||
if (acpi_table_init()) {
|
||||
if (acpi_locate_initial_tables())
|
||||
disable_acpi();
|
||||
return;
|
||||
}
|
||||
else
|
||||
acpi_reserve_initial_tables();
|
||||
}
|
||||
|
||||
int __init early_acpi_boot_init(void)
|
||||
{
|
||||
if (acpi_disabled)
|
||||
return 1;
|
||||
|
||||
acpi_table_init_complete();
|
||||
|
||||
acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
|
||||
|
||||
|
@ -1570,18 +1578,9 @@ void __init acpi_boot_table_init(void)
|
|||
} else {
|
||||
printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
|
||||
disable_acpi();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int __init early_acpi_boot_init(void)
|
||||
{
|
||||
/*
|
||||
* If acpi_disabled, bail out
|
||||
*/
|
||||
if (acpi_disabled)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Process the Multiple APIC Description Table (MADT), if present
|
||||
|
|
|
@ -1045,6 +1045,9 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
cleanup_highmap();
|
||||
|
||||
/* Look for ACPI tables and reserve memory occupied by them. */
|
||||
acpi_boot_table_init();
|
||||
|
||||
memblock_set_current_limit(ISA_END_ADDRESS);
|
||||
e820__memblock_setup();
|
||||
|
||||
|
@ -1136,11 +1139,6 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
early_platform_quirks();
|
||||
|
||||
/*
|
||||
* Parse the ACPI tables for possible boot-time SMP configuration.
|
||||
*/
|
||||
acpi_boot_table_init();
|
||||
|
||||
early_acpi_boot_init();
|
||||
|
||||
initmem_init();
|
||||
|
|
|
@ -1659,13 +1659,17 @@ void play_dead_common(void)
|
|||
local_irq_disable();
|
||||
}
|
||||
|
||||
static bool wakeup_cpu0(void)
|
||||
/**
|
||||
* cond_wakeup_cpu0 - Wake up CPU0 if needed.
|
||||
*
|
||||
* If NMI wants to wake up CPU0, start CPU0.
|
||||
*/
|
||||
void cond_wakeup_cpu0(void)
|
||||
{
|
||||
if (smp_processor_id() == 0 && enable_start_cpu0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
start_cpu0();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cond_wakeup_cpu0);
|
||||
|
||||
/*
|
||||
* We need to flush the caches before going to sleep, lest we have
|
||||
|
@ -1734,11 +1738,8 @@ static inline void mwait_play_dead(void)
|
|||
__monitor(mwait_ptr, 0, 0);
|
||||
mb();
|
||||
__mwait(eax, 0);
|
||||
/*
|
||||
* If NMI wants to wake up CPU0, start CPU0.
|
||||
*/
|
||||
if (wakeup_cpu0())
|
||||
start_cpu0();
|
||||
|
||||
cond_wakeup_cpu0();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1749,11 +1750,8 @@ void hlt_play_dead(void)
|
|||
|
||||
while (1) {
|
||||
native_halt();
|
||||
/*
|
||||
* If NMI wants to wake up CPU0, start CPU0.
|
||||
*/
|
||||
if (wakeup_cpu0())
|
||||
start_cpu0();
|
||||
|
||||
cond_wakeup_cpu0();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -556,7 +556,7 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
|
|||
tsk->thread.trap_nr = X86_TRAP_GP;
|
||||
|
||||
if (fixup_vdso_exception(regs, X86_TRAP_GP, error_code, 0))
|
||||
return;
|
||||
goto exit;
|
||||
|
||||
show_signal(tsk, SIGSEGV, "", desc, regs, error_code);
|
||||
force_sig(SIGSEGV);
|
||||
|
@ -1057,7 +1057,7 @@ static void math_error(struct pt_regs *regs, int trapnr)
|
|||
goto exit;
|
||||
|
||||
if (fixup_vdso_exception(regs, trapnr, 0, 0))
|
||||
return;
|
||||
goto exit;
|
||||
|
||||
force_sig_fault(SIGFPE, si_code,
|
||||
(void __user *)uprobe_get_trap_addr(regs));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ccflags-y += -Iarch/x86/kvm
|
||||
ccflags-y += -I $(srctree)/arch/x86/kvm
|
||||
ccflags-$(CONFIG_KVM_WERROR) += -Werror
|
||||
|
||||
ifeq ($(CONFIG_FRAME_POINTER),y)
|
||||
|
|
|
@ -5884,6 +5884,7 @@ static void kvm_recover_nx_lpages(struct kvm *kvm)
|
|||
struct kvm_mmu_page *sp;
|
||||
unsigned int ratio;
|
||||
LIST_HEAD(invalid_list);
|
||||
bool flush = false;
|
||||
ulong to_zap;
|
||||
|
||||
rcu_idx = srcu_read_lock(&kvm->srcu);
|
||||
|
@ -5905,19 +5906,19 @@ static void kvm_recover_nx_lpages(struct kvm *kvm)
|
|||
lpage_disallowed_link);
|
||||
WARN_ON_ONCE(!sp->lpage_disallowed);
|
||||
if (is_tdp_mmu_page(sp)) {
|
||||
kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn,
|
||||
sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level));
|
||||
flush |= kvm_tdp_mmu_zap_sp(kvm, sp);
|
||||
} else {
|
||||
kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
|
||||
WARN_ON_ONCE(sp->lpage_disallowed);
|
||||
}
|
||||
|
||||
if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) {
|
||||
kvm_mmu_commit_zap_page(kvm, &invalid_list);
|
||||
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
|
||||
cond_resched_rwlock_write(&kvm->mmu_lock);
|
||||
flush = false;
|
||||
}
|
||||
}
|
||||
kvm_mmu_commit_zap_page(kvm, &invalid_list);
|
||||
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
|
||||
|
||||
write_unlock(&kvm->mmu_lock);
|
||||
srcu_read_unlock(&kvm->srcu, rcu_idx);
|
||||
|
|
|
@ -86,7 +86,7 @@ static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
|
|||
list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link)
|
||||
|
||||
static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||
gfn_t start, gfn_t end, bool can_yield);
|
||||
gfn_t start, gfn_t end, bool can_yield, bool flush);
|
||||
|
||||
void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root)
|
||||
{
|
||||
|
@ -99,7 +99,7 @@ void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root)
|
|||
|
||||
list_del(&root->link);
|
||||
|
||||
zap_gfn_range(kvm, root, 0, max_gfn, false);
|
||||
zap_gfn_range(kvm, root, 0, max_gfn, false, false);
|
||||
|
||||
free_page((unsigned long)root->spt);
|
||||
kmem_cache_free(mmu_page_header_cache, root);
|
||||
|
@ -668,20 +668,21 @@ static inline bool tdp_mmu_iter_cond_resched(struct kvm *kvm,
|
|||
* scheduler needs the CPU or there is contention on the MMU lock. If this
|
||||
* function cannot yield, it will not release the MMU lock or reschedule and
|
||||
* the caller must ensure it does not supply too large a GFN range, or the
|
||||
* operation can cause a soft lockup.
|
||||
* operation can cause a soft lockup. Note, in some use cases a flush may be
|
||||
* required by prior actions. Ensure the pending flush is performed prior to
|
||||
* yielding.
|
||||
*/
|
||||
static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||
gfn_t start, gfn_t end, bool can_yield)
|
||||
gfn_t start, gfn_t end, bool can_yield, bool flush)
|
||||
{
|
||||
struct tdp_iter iter;
|
||||
bool flush_needed = false;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
tdp_root_for_each_pte(iter, root, start, end) {
|
||||
if (can_yield &&
|
||||
tdp_mmu_iter_cond_resched(kvm, &iter, flush_needed)) {
|
||||
flush_needed = false;
|
||||
tdp_mmu_iter_cond_resched(kvm, &iter, flush)) {
|
||||
flush = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -699,11 +700,11 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
|
|||
continue;
|
||||
|
||||
tdp_mmu_set_spte(kvm, &iter, 0);
|
||||
flush_needed = true;
|
||||
flush = true;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
return flush_needed;
|
||||
return flush;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -712,13 +713,14 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
|
|||
* SPTEs have been cleared and a TLB flush is needed before releasing the
|
||||
* MMU lock.
|
||||
*/
|
||||
bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end)
|
||||
bool __kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end,
|
||||
bool can_yield)
|
||||
{
|
||||
struct kvm_mmu_page *root;
|
||||
bool flush = false;
|
||||
|
||||
for_each_tdp_mmu_root_yield_safe(kvm, root)
|
||||
flush |= zap_gfn_range(kvm, root, start, end, true);
|
||||
flush = zap_gfn_range(kvm, root, start, end, can_yield, flush);
|
||||
|
||||
return flush;
|
||||
}
|
||||
|
@ -930,7 +932,7 @@ static int zap_gfn_range_hva_wrapper(struct kvm *kvm,
|
|||
struct kvm_mmu_page *root, gfn_t start,
|
||||
gfn_t end, unsigned long unused)
|
||||
{
|
||||
return zap_gfn_range(kvm, root, start, end, false);
|
||||
return zap_gfn_range(kvm, root, start, end, false, false);
|
||||
}
|
||||
|
||||
int kvm_tdp_mmu_zap_hva_range(struct kvm *kvm, unsigned long start,
|
||||
|
|
|
@ -8,7 +8,29 @@
|
|||
hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu);
|
||||
void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root);
|
||||
|
||||
bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end);
|
||||
bool __kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end,
|
||||
bool can_yield);
|
||||
static inline bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start,
|
||||
gfn_t end)
|
||||
{
|
||||
return __kvm_tdp_mmu_zap_gfn_range(kvm, start, end, true);
|
||||
}
|
||||
static inline bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
|
||||
{
|
||||
gfn_t end = sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level);
|
||||
|
||||
/*
|
||||
* Don't allow yielding, as the caller may have a flush pending. Note,
|
||||
* if mmu_lock is held for write, zapping will never yield in this case,
|
||||
* but explicitly disallow it for safety. The TDP MMU does not yield
|
||||
* until it has made forward progress (steps sideways), and when zapping
|
||||
* a single shadow page that it's guaranteed to see (thus the mmu_lock
|
||||
* requirement), its "step sideways" will always step beyond the bounds
|
||||
* of the shadow page's gfn range and stop iterating before yielding.
|
||||
*/
|
||||
lockdep_assert_held_write(&kvm->mmu_lock);
|
||||
return __kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn, end, false);
|
||||
}
|
||||
void kvm_tdp_mmu_zap_all(struct kvm *kvm);
|
||||
|
||||
int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
|
||||
|
|
|
@ -246,11 +246,18 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12)
|
||||
static bool nested_vmcb_check_save(struct vcpu_svm *svm, struct vmcb *vmcb12)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = &svm->vcpu;
|
||||
bool vmcb12_lma;
|
||||
|
||||
/*
|
||||
* FIXME: these should be done after copying the fields,
|
||||
* to avoid TOC/TOU races. For these save area checks
|
||||
* the possible damage is limited since kvm_set_cr0 and
|
||||
* kvm_set_cr4 handle failure; EFER_SVME is an exception
|
||||
* so it is force-set later in nested_prepare_vmcb_save.
|
||||
*/
|
||||
if ((vmcb12->save.efer & EFER_SVME) == 0)
|
||||
return false;
|
||||
|
||||
|
@ -271,7 +278,7 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12)
|
|||
if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4))
|
||||
return false;
|
||||
|
||||
return nested_vmcb_check_controls(&vmcb12->control);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void load_nested_vmcb_control(struct vcpu_svm *svm,
|
||||
|
@ -396,7 +403,14 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12)
|
|||
svm->vmcb->save.gdtr = vmcb12->save.gdtr;
|
||||
svm->vmcb->save.idtr = vmcb12->save.idtr;
|
||||
kvm_set_rflags(&svm->vcpu, vmcb12->save.rflags | X86_EFLAGS_FIXED);
|
||||
svm_set_efer(&svm->vcpu, vmcb12->save.efer);
|
||||
|
||||
/*
|
||||
* Force-set EFER_SVME even though it is checked earlier on the
|
||||
* VMCB12, because the guest can flip the bit between the check
|
||||
* and now. Clearing EFER_SVME would call svm_free_nested.
|
||||
*/
|
||||
svm_set_efer(&svm->vcpu, vmcb12->save.efer | EFER_SVME);
|
||||
|
||||
svm_set_cr0(&svm->vcpu, vmcb12->save.cr0);
|
||||
svm_set_cr4(&svm->vcpu, vmcb12->save.cr4);
|
||||
svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = vmcb12->save.cr2;
|
||||
|
@ -468,7 +482,6 @@ int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb12_gpa,
|
|||
|
||||
|
||||
svm->nested.vmcb12_gpa = vmcb12_gpa;
|
||||
load_nested_vmcb_control(svm, &vmcb12->control);
|
||||
nested_prepare_vmcb_control(svm);
|
||||
nested_prepare_vmcb_save(svm, vmcb12);
|
||||
|
||||
|
@ -515,7 +528,10 @@ int nested_svm_vmrun(struct vcpu_svm *svm)
|
|||
if (WARN_ON_ONCE(!svm->nested.initialized))
|
||||
return -EINVAL;
|
||||
|
||||
if (!nested_vmcb_checks(svm, vmcb12)) {
|
||||
load_nested_vmcb_control(svm, &vmcb12->control);
|
||||
|
||||
if (!nested_vmcb_check_save(svm, vmcb12) ||
|
||||
!nested_vmcb_check_controls(&svm->nested.ctl)) {
|
||||
vmcb12->control.exit_code = SVM_EXIT_ERR;
|
||||
vmcb12->control.exit_code_hi = 0;
|
||||
vmcb12->control.exit_info_1 = 0;
|
||||
|
@ -1209,6 +1225,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
|
|||
*/
|
||||
if (!(save->cr0 & X86_CR0_PG))
|
||||
goto out_free;
|
||||
if (!(save->efer & EFER_SVME))
|
||||
goto out_free;
|
||||
|
||||
/*
|
||||
* All checks done, we can enter guest mode. L1 control fields
|
||||
|
|
|
@ -98,6 +98,8 @@ static enum index msr_to_index(u32 msr)
|
|||
static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
|
||||
enum pmu_type type)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu);
|
||||
|
||||
switch (msr) {
|
||||
case MSR_F15H_PERF_CTL0:
|
||||
case MSR_F15H_PERF_CTL1:
|
||||
|
@ -105,6 +107,9 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
|
|||
case MSR_F15H_PERF_CTL3:
|
||||
case MSR_F15H_PERF_CTL4:
|
||||
case MSR_F15H_PERF_CTL5:
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE))
|
||||
return NULL;
|
||||
fallthrough;
|
||||
case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
|
||||
if (type != PMU_TYPE_EVNTSEL)
|
||||
return NULL;
|
||||
|
@ -115,6 +120,9 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
|
|||
case MSR_F15H_PERF_CTR3:
|
||||
case MSR_F15H_PERF_CTR4:
|
||||
case MSR_F15H_PERF_CTR5:
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE))
|
||||
return NULL;
|
||||
fallthrough;
|
||||
case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3:
|
||||
if (type != PMU_TYPE_COUNTER)
|
||||
return NULL;
|
||||
|
|
|
@ -271,8 +271,7 @@ static struct kmem_cache *x86_emulator_cache;
|
|||
* When called, it means the previous get/set msr reached an invalid msr.
|
||||
* Return true if we want to ignore/silent this failed msr access.
|
||||
*/
|
||||
static bool kvm_msr_ignored_check(struct kvm_vcpu *vcpu, u32 msr,
|
||||
u64 data, bool write)
|
||||
static bool kvm_msr_ignored_check(u32 msr, u64 data, bool write)
|
||||
{
|
||||
const char *op = write ? "wrmsr" : "rdmsr";
|
||||
|
||||
|
@ -1445,7 +1444,7 @@ static int do_get_msr_feature(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
|
|||
if (r == KVM_MSR_RET_INVALID) {
|
||||
/* Unconditionally clear the output for simplicity */
|
||||
*data = 0;
|
||||
if (kvm_msr_ignored_check(vcpu, index, 0, false))
|
||||
if (kvm_msr_ignored_check(index, 0, false))
|
||||
r = 0;
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1619,7 @@ static int kvm_set_msr_ignored_check(struct kvm_vcpu *vcpu,
|
|||
int ret = __kvm_set_msr(vcpu, index, data, host_initiated);
|
||||
|
||||
if (ret == KVM_MSR_RET_INVALID)
|
||||
if (kvm_msr_ignored_check(vcpu, index, data, true))
|
||||
if (kvm_msr_ignored_check(index, data, true))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
|
@ -1658,7 +1657,7 @@ static int kvm_get_msr_ignored_check(struct kvm_vcpu *vcpu,
|
|||
if (ret == KVM_MSR_RET_INVALID) {
|
||||
/* Unconditionally clear *data for simplicity */
|
||||
*data = 0;
|
||||
if (kvm_msr_ignored_check(vcpu, index, 0, false))
|
||||
if (kvm_msr_ignored_check(index, 0, false))
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
@ -2329,7 +2328,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
|
|||
kvm_vcpu_write_tsc_offset(vcpu, offset);
|
||||
raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
|
||||
|
||||
spin_lock(&kvm->arch.pvclock_gtod_sync_lock);
|
||||
spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
|
||||
if (!matched) {
|
||||
kvm->arch.nr_vcpus_matched_tsc = 0;
|
||||
} else if (!already_matched) {
|
||||
|
@ -2337,7 +2336,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
|
|||
}
|
||||
|
||||
kvm_track_tsc_matching(vcpu);
|
||||
spin_unlock(&kvm->arch.pvclock_gtod_sync_lock);
|
||||
spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
|
||||
}
|
||||
|
||||
static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
|
||||
|
@ -2559,13 +2558,16 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
|
|||
int i;
|
||||
struct kvm_vcpu *vcpu;
|
||||
struct kvm_arch *ka = &kvm->arch;
|
||||
unsigned long flags;
|
||||
|
||||
kvm_hv_invalidate_tsc_page(kvm);
|
||||
|
||||
spin_lock(&ka->pvclock_gtod_sync_lock);
|
||||
kvm_make_mclock_inprogress_request(kvm);
|
||||
|
||||
/* no guest entries from this point */
|
||||
spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
|
||||
pvclock_update_vm_gtod_copy(kvm);
|
||||
spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
|
||||
|
||||
kvm_for_each_vcpu(i, vcpu, kvm)
|
||||
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
|
||||
|
@ -2573,8 +2575,6 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
|
|||
/* guest entries allowed */
|
||||
kvm_for_each_vcpu(i, vcpu, kvm)
|
||||
kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu);
|
||||
|
||||
spin_unlock(&ka->pvclock_gtod_sync_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2582,17 +2582,18 @@ u64 get_kvmclock_ns(struct kvm *kvm)
|
|||
{
|
||||
struct kvm_arch *ka = &kvm->arch;
|
||||
struct pvclock_vcpu_time_info hv_clock;
|
||||
unsigned long flags;
|
||||
u64 ret;
|
||||
|
||||
spin_lock(&ka->pvclock_gtod_sync_lock);
|
||||
spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
|
||||
if (!ka->use_master_clock) {
|
||||
spin_unlock(&ka->pvclock_gtod_sync_lock);
|
||||
spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
|
||||
return get_kvmclock_base_ns() + ka->kvmclock_offset;
|
||||
}
|
||||
|
||||
hv_clock.tsc_timestamp = ka->master_cycle_now;
|
||||
hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
|
||||
spin_unlock(&ka->pvclock_gtod_sync_lock);
|
||||
spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
|
||||
|
||||
/* both __this_cpu_read() and rdtsc() should be on the same cpu */
|
||||
get_cpu();
|
||||
|
@ -2686,13 +2687,13 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
|
|||
* If the host uses TSC clock, then passthrough TSC as stable
|
||||
* to the guest.
|
||||
*/
|
||||
spin_lock(&ka->pvclock_gtod_sync_lock);
|
||||
spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
|
||||
use_master_clock = ka->use_master_clock;
|
||||
if (use_master_clock) {
|
||||
host_tsc = ka->master_cycle_now;
|
||||
kernel_ns = ka->master_kernel_ns;
|
||||
}
|
||||
spin_unlock(&ka->pvclock_gtod_sync_lock);
|
||||
spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
|
||||
|
||||
/* Keep irq disabled to prevent changes to the clock */
|
||||
local_irq_save(flags);
|
||||
|
@ -5726,6 +5727,7 @@ set_pit2_out:
|
|||
}
|
||||
#endif
|
||||
case KVM_SET_CLOCK: {
|
||||
struct kvm_arch *ka = &kvm->arch;
|
||||
struct kvm_clock_data user_ns;
|
||||
u64 now_ns;
|
||||
|
||||
|
@ -5744,8 +5746,22 @@ set_pit2_out:
|
|||
* pvclock_update_vm_gtod_copy().
|
||||
*/
|
||||
kvm_gen_update_masterclock(kvm);
|
||||
now_ns = get_kvmclock_ns(kvm);
|
||||
kvm->arch.kvmclock_offset += user_ns.clock - now_ns;
|
||||
|
||||
/*
|
||||
* This pairs with kvm_guest_time_update(): when masterclock is
|
||||
* in use, we use master_kernel_ns + kvmclock_offset to set
|
||||
* unsigned 'system_time' so if we use get_kvmclock_ns() (which
|
||||
* is slightly ahead) here we risk going negative on unsigned
|
||||
* 'system_time' when 'user_ns.clock' is very small.
|
||||
*/
|
||||
spin_lock_irq(&ka->pvclock_gtod_sync_lock);
|
||||
if (kvm->arch.use_master_clock)
|
||||
now_ns = ka->master_kernel_ns;
|
||||
else
|
||||
now_ns = get_kvmclock_base_ns();
|
||||
ka->kvmclock_offset = user_ns.clock - now_ns;
|
||||
spin_unlock_irq(&ka->pvclock_gtod_sync_lock);
|
||||
|
||||
kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE);
|
||||
break;
|
||||
}
|
||||
|
@ -7724,6 +7740,7 @@ static void kvm_hyperv_tsc_notifier(void)
|
|||
struct kvm *kvm;
|
||||
struct kvm_vcpu *vcpu;
|
||||
int cpu;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&kvm_lock);
|
||||
list_for_each_entry(kvm, &vm_list, vm_list)
|
||||
|
@ -7739,17 +7756,15 @@ static void kvm_hyperv_tsc_notifier(void)
|
|||
list_for_each_entry(kvm, &vm_list, vm_list) {
|
||||
struct kvm_arch *ka = &kvm->arch;
|
||||
|
||||
spin_lock(&ka->pvclock_gtod_sync_lock);
|
||||
|
||||
spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
|
||||
pvclock_update_vm_gtod_copy(kvm);
|
||||
spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
|
||||
|
||||
kvm_for_each_vcpu(cpu, vcpu, kvm)
|
||||
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
|
||||
|
||||
kvm_for_each_vcpu(cpu, vcpu, kvm)
|
||||
kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu);
|
||||
|
||||
spin_unlock(&ka->pvclock_gtod_sync_lock);
|
||||
}
|
||||
mutex_unlock(&kvm_lock);
|
||||
}
|
||||
|
|
|
@ -250,7 +250,6 @@ static inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu)
|
|||
void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock, int sec_hi_ofs);
|
||||
void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
|
||||
|
||||
void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr);
|
||||
u64 get_kvmclock_ns(struct kvm *kvm);
|
||||
|
||||
int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
|
||||
|
|
|
@ -1689,7 +1689,16 @@ emit_jmp:
|
|||
}
|
||||
|
||||
if (image) {
|
||||
if (unlikely(proglen + ilen > oldproglen)) {
|
||||
/*
|
||||
* When populating the image, assert that:
|
||||
*
|
||||
* i) We do not write beyond the allocated space, and
|
||||
* ii) addrs[i] did not change from the prior run, in order
|
||||
* to validate assumptions made for computing branch
|
||||
* displacements.
|
||||
*/
|
||||
if (unlikely(proglen + ilen > oldproglen ||
|
||||
proglen + ilen != addrs[i])) {
|
||||
pr_err("bpf_jit: fatal error\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
|
@ -2276,7 +2276,16 @@ notyet:
|
|||
}
|
||||
|
||||
if (image) {
|
||||
if (unlikely(proglen + ilen > oldproglen)) {
|
||||
/*
|
||||
* When populating the image, assert that:
|
||||
*
|
||||
* i) We do not write beyond the allocated space, and
|
||||
* ii) addrs[i] did not change from the prior run, in order
|
||||
* to validate assumptions made for computing branch
|
||||
* displacements.
|
||||
*/
|
||||
if (unlikely(proglen + ilen > oldproglen ||
|
||||
proglen + ilen != addrs[i])) {
|
||||
pr_err("bpf_jit: fatal error\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
|
@ -99,37 +99,6 @@
|
|||
LOAD_CP_REGS_TAB(6)
|
||||
LOAD_CP_REGS_TAB(7)
|
||||
|
||||
/*
|
||||
* coprocessor_flush(struct thread_info*, index)
|
||||
* a2 a3
|
||||
*
|
||||
* Save coprocessor registers for coprocessor 'index'.
|
||||
* The register values are saved to or loaded from the coprocessor area
|
||||
* inside the task_info structure.
|
||||
*
|
||||
* Note that this function doesn't update the coprocessor_owner information!
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(coprocessor_flush)
|
||||
|
||||
/* reserve 4 bytes on stack to save a0 */
|
||||
abi_entry(4)
|
||||
|
||||
s32i a0, a1, 0
|
||||
movi a0, .Lsave_cp_regs_jump_table
|
||||
addx8 a3, a3, a0
|
||||
l32i a4, a3, 4
|
||||
l32i a3, a3, 0
|
||||
add a2, a2, a4
|
||||
beqz a3, 1f
|
||||
callx0 a3
|
||||
1: l32i a0, a1, 0
|
||||
|
||||
abi_ret(4)
|
||||
|
||||
ENDPROC(coprocessor_flush)
|
||||
|
||||
/*
|
||||
* Entry condition:
|
||||
*
|
||||
|
@ -245,6 +214,39 @@ ENTRY(fast_coprocessor)
|
|||
|
||||
ENDPROC(fast_coprocessor)
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* coprocessor_flush(struct thread_info*, index)
|
||||
* a2 a3
|
||||
*
|
||||
* Save coprocessor registers for coprocessor 'index'.
|
||||
* The register values are saved to or loaded from the coprocessor area
|
||||
* inside the task_info structure.
|
||||
*
|
||||
* Note that this function doesn't update the coprocessor_owner information!
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(coprocessor_flush)
|
||||
|
||||
/* reserve 4 bytes on stack to save a0 */
|
||||
abi_entry(4)
|
||||
|
||||
s32i a0, a1, 0
|
||||
movi a0, .Lsave_cp_regs_jump_table
|
||||
addx8 a3, a3, a0
|
||||
l32i a4, a3, 4
|
||||
l32i a3, a3, 0
|
||||
add a2, a2, a4
|
||||
beqz a3, 1f
|
||||
callx0 a3
|
||||
1: l32i a0, a1, 0
|
||||
|
||||
abi_ret(4)
|
||||
|
||||
ENDPROC(coprocessor_flush)
|
||||
|
||||
.data
|
||||
|
||||
ENTRY(coprocessor_owner)
|
||||
|
|
|
@ -112,8 +112,11 @@ good_area:
|
|||
*/
|
||||
fault = handle_mm_fault(vma, address, flags, regs);
|
||||
|
||||
if (fault_signal_pending(fault, regs))
|
||||
if (fault_signal_pending(fault, regs)) {
|
||||
if (!user_mode(regs))
|
||||
goto bad_page_fault;
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
|
|
|
@ -277,7 +277,7 @@ static struct bio *__bio_chain_endio(struct bio *bio)
|
|||
{
|
||||
struct bio *parent = bio->bi_private;
|
||||
|
||||
if (!parent->bi_status)
|
||||
if (bio->bi_status && !parent->bi_status)
|
||||
parent->bi_status = bio->bi_status;
|
||||
bio_put(bio);
|
||||
return parent;
|
||||
|
|
|
@ -302,7 +302,6 @@ static const char *const rqf_name[] = {
|
|||
RQF_NAME(QUIET),
|
||||
RQF_NAME(ELVPRIV),
|
||||
RQF_NAME(IO_STAT),
|
||||
RQF_NAME(ALLOCED),
|
||||
RQF_NAME(PM),
|
||||
RQF_NAME(HASHED),
|
||||
RQF_NAME(STATS),
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
#ifdef CONFIG_X86
|
||||
#include <asm/apic.h>
|
||||
#include <asm/cpu.h>
|
||||
#endif
|
||||
|
||||
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
|
||||
|
@ -541,6 +542,10 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
|
|||
wait_for_freeze();
|
||||
} else
|
||||
return -ENODEV;
|
||||
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_HOTPLUG_CPU)
|
||||
cond_wakeup_cpu0();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Never reached */
|
||||
|
|
|
@ -1670,6 +1670,8 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
|
|||
device_initialize(&device->dev);
|
||||
dev_set_uevent_suppress(&device->dev, true);
|
||||
acpi_init_coherency(device);
|
||||
/* Assume there are unmet deps to start with. */
|
||||
device->dep_unmet = 1;
|
||||
}
|
||||
|
||||
void acpi_device_add_finalize(struct acpi_device *device)
|
||||
|
@ -1933,6 +1935,8 @@ static void acpi_scan_dep_init(struct acpi_device *adev)
|
|||
{
|
||||
struct acpi_dep_data *dep;
|
||||
|
||||
adev->dep_unmet = 0;
|
||||
|
||||
mutex_lock(&acpi_dep_list_lock);
|
||||
|
||||
list_for_each_entry(dep, &acpi_dep_list, node) {
|
||||
|
@ -1980,7 +1984,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
|
|||
return AE_CTRL_DEPTH;
|
||||
|
||||
acpi_scan_init_hotplug(device);
|
||||
if (!check_dep)
|
||||
/*
|
||||
* If check_dep is true at this point, the device has no dependencies,
|
||||
* or the creation of the device object would have been postponed above.
|
||||
*/
|
||||
if (check_dep)
|
||||
device->dep_unmet = 0;
|
||||
else
|
||||
acpi_scan_dep_init(device);
|
||||
|
||||
out:
|
||||
|
|
|
@ -780,7 +780,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
|
|||
}
|
||||
|
||||
/*
|
||||
* acpi_table_init()
|
||||
* acpi_locate_initial_tables()
|
||||
*
|
||||
* find RSDP, find and checksum SDT/XSDT.
|
||||
* checksum all tables, print SDT/XSDT
|
||||
|
@ -788,7 +788,7 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
|
|||
* result: sdt_entry[] is initialized
|
||||
*/
|
||||
|
||||
int __init acpi_table_init(void)
|
||||
int __init acpi_locate_initial_tables(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
|
@ -803,9 +803,45 @@ int __init acpi_table_init(void)
|
|||
status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
acpi_table_initrd_scan();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init acpi_reserve_initial_tables(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ACPI_MAX_TABLES; i++) {
|
||||
struct acpi_table_desc *table_desc = &initial_tables[i];
|
||||
u64 start = table_desc->address;
|
||||
u64 size = table_desc->length;
|
||||
|
||||
if (!start || !size)
|
||||
break;
|
||||
|
||||
pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n",
|
||||
table_desc->signature.ascii, start, start + size - 1);
|
||||
|
||||
memblock_reserve(start, size);
|
||||
}
|
||||
}
|
||||
|
||||
void __init acpi_table_init_complete(void)
|
||||
{
|
||||
acpi_table_initrd_scan();
|
||||
check_multiple_madt();
|
||||
}
|
||||
|
||||
int __init acpi_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = acpi_locate_initial_tables();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
acpi_table_init_complete();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,9 @@ static void deferred_probe_work_func(struct work_struct *work)
|
|||
|
||||
get_device(dev);
|
||||
|
||||
kfree(dev->p->deferred_probe_reason);
|
||||
dev->p->deferred_probe_reason = NULL;
|
||||
|
||||
/*
|
||||
* Drop the mutex while probing each device; the probe path may
|
||||
* manipulate the deferred list
|
||||
|
@ -289,14 +292,16 @@ int driver_deferred_probe_check_state(struct device *dev)
|
|||
|
||||
static void deferred_probe_timeout_work_func(struct work_struct *work)
|
||||
{
|
||||
struct device_private *private, *p;
|
||||
struct device_private *p;
|
||||
|
||||
driver_deferred_probe_timeout = 0;
|
||||
driver_deferred_probe_trigger();
|
||||
flush_work(&deferred_probe_work);
|
||||
|
||||
list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe)
|
||||
dev_info(private->device, "deferred probe pending\n");
|
||||
mutex_lock(&deferred_probe_mutex);
|
||||
list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe)
|
||||
dev_info(p->device, "deferred probe pending\n");
|
||||
mutex_unlock(&deferred_probe_mutex);
|
||||
wake_up_all(&probe_timeout_waitqueue);
|
||||
}
|
||||
static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func);
|
||||
|
|
|
@ -1690,8 +1690,8 @@ void pm_runtime_get_suppliers(struct device *dev)
|
|||
device_links_read_lock_held())
|
||||
if (link->flags & DL_FLAG_PM_RUNTIME) {
|
||||
link->supplier_preactivated = true;
|
||||
refcount_inc(&link->rpm_active);
|
||||
pm_runtime_get_sync(link->supplier);
|
||||
refcount_inc(&link->rpm_active);
|
||||
}
|
||||
|
||||
device_links_read_unlock(idx);
|
||||
|
@ -1704,6 +1704,8 @@ void pm_runtime_get_suppliers(struct device *dev)
|
|||
void pm_runtime_put_suppliers(struct device *dev)
|
||||
{
|
||||
struct device_link *link;
|
||||
unsigned long flags;
|
||||
bool put;
|
||||
int idx;
|
||||
|
||||
idx = device_links_read_lock();
|
||||
|
@ -1712,7 +1714,11 @@ void pm_runtime_put_suppliers(struct device *dev)
|
|||
device_links_read_lock_held())
|
||||
if (link->supplier_preactivated) {
|
||||
link->supplier_preactivated = false;
|
||||
if (refcount_dec_not_one(&link->rpm_active))
|
||||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
put = pm_runtime_status_suspended(dev) &&
|
||||
refcount_dec_not_one(&link->rpm_active);
|
||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
||||
if (put)
|
||||
pm_runtime_put(link->supplier);
|
||||
}
|
||||
|
||||
|
|
|
@ -1369,10 +1369,13 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
|
|||
}
|
||||
|
||||
if (dev->zoned)
|
||||
cmd->error = null_process_zoned_cmd(cmd, op,
|
||||
sector, nr_sectors);
|
||||
sts = null_process_zoned_cmd(cmd, op, sector, nr_sectors);
|
||||
else
|
||||
cmd->error = null_process_cmd(cmd, op, sector, nr_sectors);
|
||||
sts = null_process_cmd(cmd, op, sector, nr_sectors);
|
||||
|
||||
/* Do not overwrite errors (e.g. timeout errors) */
|
||||
if (cmd->error == BLK_STS_OK)
|
||||
cmd->error = sts;
|
||||
|
||||
out:
|
||||
nullb_complete_cmd(cmd);
|
||||
|
@ -1451,8 +1454,20 @@ static bool should_requeue_request(struct request *rq)
|
|||
|
||||
static enum blk_eh_timer_return null_timeout_rq(struct request *rq, bool res)
|
||||
{
|
||||
struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq);
|
||||
|
||||
pr_info("rq %p timed out\n", rq);
|
||||
blk_mq_complete_request(rq);
|
||||
|
||||
/*
|
||||
* If the device is marked as blocking (i.e. memory backed or zoned
|
||||
* device), the submission path may be blocked waiting for resources
|
||||
* and cause real timeouts. For these real timeouts, the submission
|
||||
* path will complete the request using blk_mq_complete_request().
|
||||
* Only fake timeouts need to execute blk_mq_complete_request() here.
|
||||
*/
|
||||
cmd->error = BLK_STS_TIMEOUT;
|
||||
if (cmd->fake_timeout)
|
||||
blk_mq_complete_request(rq);
|
||||
return BLK_EH_DONE;
|
||||
}
|
||||
|
||||
|
@ -1473,6 +1488,7 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
cmd->rq = bd->rq;
|
||||
cmd->error = BLK_STS_OK;
|
||||
cmd->nq = nq;
|
||||
cmd->fake_timeout = should_timeout_request(bd->rq);
|
||||
|
||||
blk_mq_start_request(bd->rq);
|
||||
|
||||
|
@ -1489,7 +1505,7 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
return BLK_STS_OK;
|
||||
}
|
||||
}
|
||||
if (should_timeout_request(bd->rq))
|
||||
if (cmd->fake_timeout)
|
||||
return BLK_STS_OK;
|
||||
|
||||
return null_handle_cmd(cmd, sector, nr_sectors, req_op(bd->rq));
|
||||
|
|
|
@ -22,6 +22,7 @@ struct nullb_cmd {
|
|||
blk_status_t error;
|
||||
struct nullb_queue *nq;
|
||||
struct hrtimer timer;
|
||||
bool fake_timeout;
|
||||
};
|
||||
|
||||
struct nullb_queue {
|
||||
|
|
|
@ -891,7 +891,7 @@ next:
|
|||
out:
|
||||
for (i = last_map; i < num; i++) {
|
||||
/* Don't zap current batch's valid persistent grants. */
|
||||
if(i >= last_map + segs_to_map)
|
||||
if(i >= map_until)
|
||||
pages[i]->persistent_gnt = NULL;
|
||||
pages[i]->handle = BLKBACK_INVALID_HANDLE;
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче