mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-05 21:35:46 +02:00
Merge branch 'v5.6/base' into v5.6/standard/base
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
This commit is contained in:
commit
845f054fe1
|
@ -2795,7 +2795,7 @@
|
||||||
<name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>]
|
<name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>]
|
||||||
|
|
||||||
mtdparts= [MTD]
|
mtdparts= [MTD]
|
||||||
See drivers/mtd/cmdlinepart.c.
|
See drivers/mtd/parsers/cmdlinepart.c
|
||||||
|
|
||||||
multitce=off [PPC] This parameter disables the use of the pSeries
|
multitce=off [PPC] This parameter disables the use of the pSeries
|
||||||
firmware feature for updating multiple TCE entries
|
firmware feature for updating multiple TCE entries
|
||||||
|
@ -5085,8 +5085,7 @@
|
||||||
|
|
||||||
usbcore.old_scheme_first=
|
usbcore.old_scheme_first=
|
||||||
[USB] Start with the old device initialization
|
[USB] Start with the old device initialization
|
||||||
scheme, applies only to low and full-speed devices
|
scheme (default 0 = off).
|
||||||
(default 0 = off).
|
|
||||||
|
|
||||||
usbcore.usbfs_memory_mb=
|
usbcore.usbfs_memory_mb=
|
||||||
[USB] Memory limit (in MB) for buffers allocated by
|
[USB] Memory limit (in MB) for buffers allocated by
|
||||||
|
|
|
@ -65,6 +65,12 @@ max_pid_namespaces
|
||||||
The maximum number of pid namespaces that any user in the current
|
The maximum number of pid namespaces that any user in the current
|
||||||
user namespace may create.
|
user namespace may create.
|
||||||
|
|
||||||
|
max_time_namespaces
|
||||||
|
===================
|
||||||
|
|
||||||
|
The maximum number of time namespaces that any user in the current
|
||||||
|
user namespace may create.
|
||||||
|
|
||||||
max_user_namespaces
|
max_user_namespaces
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ Tegra194:
|
||||||
--------
|
--------
|
||||||
|
|
||||||
pcie@14180000 {
|
pcie@14180000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>;
|
||||||
reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
|
|
@ -53,13 +53,12 @@ properties:
|
||||||
description:
|
description:
|
||||||
Reference to an nvmem node for the calibration data
|
Reference to an nvmem node for the calibration data
|
||||||
|
|
||||||
nvmem-cells-names:
|
nvmem-cell-names:
|
||||||
minItems: 1
|
minItems: 1
|
||||||
maxItems: 2
|
maxItems: 2
|
||||||
items:
|
items:
|
||||||
- enum:
|
- const: calib
|
||||||
- caldata
|
- const: calib_sel
|
||||||
- calsel
|
|
||||||
|
|
||||||
"#qcom,sensors":
|
"#qcom,sensors":
|
||||||
allOf:
|
allOf:
|
||||||
|
@ -125,7 +124,7 @@ examples:
|
||||||
<0x4a8000 0x1000>; /* SROT */
|
<0x4a8000 0x1000>; /* SROT */
|
||||||
|
|
||||||
nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
|
nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
|
||||||
nvmem-cell-names = "caldata", "calsel";
|
nvmem-cell-names = "calib", "calib_sel";
|
||||||
|
|
||||||
interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
interrupt-names = "uplow";
|
interrupt-names = "uplow";
|
||||||
|
|
|
@ -8,3 +8,4 @@ HD-Audio
|
||||||
models
|
models
|
||||||
controls
|
controls
|
||||||
dp-mst
|
dp-mst
|
||||||
|
realtek-pc-beep
|
||||||
|
|
|
@ -216,8 +216,6 @@ alc298-dell-aio
|
||||||
ALC298 fixups on Dell AIO machines
|
ALC298 fixups on Dell AIO machines
|
||||||
alc275-dell-xps
|
alc275-dell-xps
|
||||||
ALC275 fixups on Dell XPS models
|
ALC275 fixups on Dell XPS models
|
||||||
alc256-dell-xps13
|
|
||||||
ALC256 fixups on Dell XPS13
|
|
||||||
lenovo-spk-noise
|
lenovo-spk-noise
|
||||||
Workaround for speaker noise on Lenovo machines
|
Workaround for speaker noise on Lenovo machines
|
||||||
lenovo-hotkey
|
lenovo-hotkey
|
||||||
|
|
129
Documentation/sound/hd-audio/realtek-pc-beep.rst
Normal file
129
Documentation/sound/hd-audio/realtek-pc-beep.rst
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
===============================
|
||||||
|
Realtek PC Beep Hidden Register
|
||||||
|
===============================
|
||||||
|
|
||||||
|
This file documents the "PC Beep Hidden Register", which is present in certain
|
||||||
|
Realtek HDA codecs and controls a muxer and pair of passthrough mixers that can
|
||||||
|
route audio between pins but aren't themselves exposed as HDA widgets. As far
|
||||||
|
as I can tell, these hidden routes are designed to allow flexible PC Beep output
|
||||||
|
for codecs that don't have mixer widgets in their output paths. Why it's easier
|
||||||
|
to hide a mixer behind an undocumented vendor register than to just expose it
|
||||||
|
as a widget, I have no idea.
|
||||||
|
|
||||||
|
Register Description
|
||||||
|
====================
|
||||||
|
|
||||||
|
The register is accessed via processing coefficient 0x36 on NID 20h. Bits not
|
||||||
|
identified below have no discernible effect on my machine, a Dell XPS 13 9350::
|
||||||
|
|
||||||
|
MSB LSB
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| |h|S|L| | B |R| | Known bits
|
||||||
|
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
|0|0|1|1| 0x7 |0|0x0|1| 0x7 | Reset value
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
1Ah input select (B): 2 bits
|
||||||
|
When zero, expose the PC Beep line (from the internal beep generator, when
|
||||||
|
enabled with the Set Beep Generation verb on NID 01h, or else from the
|
||||||
|
external PCBEEP pin) on the 1Ah pin node. When nonzero, expose the headphone
|
||||||
|
jack (or possibly Line In on some machines) input instead. If PC Beep is
|
||||||
|
selected, the 1Ah boost control has no effect.
|
||||||
|
|
||||||
|
Amplify 1Ah loopback, left (L): 1 bit
|
||||||
|
Amplify the left channel of 1Ah before mixing it into outputs as specified
|
||||||
|
by h and S bits. Does not affect the level of 1Ah exposed to other widgets.
|
||||||
|
|
||||||
|
Amplify 1Ah loopback, right (R): 1 bit
|
||||||
|
Amplify the right channel of 1Ah before mixing it into outputs as specified
|
||||||
|
by h and S bits. Does not affect the level of 1Ah exposed to other widgets.
|
||||||
|
|
||||||
|
Loopback 1Ah to 21h [active low] (h): 1 bit
|
||||||
|
When zero, mix 1Ah (possibly with amplification, depending on L and R bits)
|
||||||
|
into 21h (headphone jack on my machine). Mixed signal respects the mute
|
||||||
|
setting on 21h.
|
||||||
|
|
||||||
|
Loopback 1Ah to 14h (S): 1 bit
|
||||||
|
When one, mix 1Ah (possibly with amplification, depending on L and R bits)
|
||||||
|
into 14h (internal speaker on my machine). Mixed signal **ignores** the mute
|
||||||
|
setting on 14h and is present whenever 14h is configured as an output.
|
||||||
|
|
||||||
|
Path diagrams
|
||||||
|
=============
|
||||||
|
|
||||||
|
1Ah input selection (DIV is the PC Beep divider set on NID 01h)::
|
||||||
|
|
||||||
|
<Beep generator> <PCBEEP pin> <Headphone jack>
|
||||||
|
| | |
|
||||||
|
+--DIV--+--!DIV--+ {1Ah boost control}
|
||||||
|
| |
|
||||||
|
+--(b == 0)--+--(b != 0)--+
|
||||||
|
|
|
||||||
|
>1Ah (Beep/Headphone Mic/Line In)<
|
||||||
|
|
||||||
|
Loopback of 1Ah to 21h/14h::
|
||||||
|
|
||||||
|
<1Ah (Beep/Headphone Mic/Line In)>
|
||||||
|
|
|
||||||
|
{amplify if L/R}
|
||||||
|
|
|
||||||
|
+-----!h-----+-----S-----+
|
||||||
|
| |
|
||||||
|
{21h mute control} |
|
||||||
|
| |
|
||||||
|
>21h (Headphone)< >14h (Internal Speaker)<
|
||||||
|
|
||||||
|
Background
|
||||||
|
==========
|
||||||
|
|
||||||
|
All Realtek HDA codecs have a vendor-defined widget with node ID 20h which
|
||||||
|
provides access to a bank of registers that control various codec functions.
|
||||||
|
Registers are read and written via the standard HDA processing coefficient
|
||||||
|
verbs (Set/Get Coefficient Index, Set/Get Processing Coefficient). The node is
|
||||||
|
named "Realtek Vendor Registers" in public datasheets' verb listings and,
|
||||||
|
apart from that, is entirely undocumented.
|
||||||
|
|
||||||
|
This particular register, exposed at coefficient 0x36 and named in commits from
|
||||||
|
Realtek, is of note: unlike most registers, which seem to control detailed
|
||||||
|
amplifier parameters not in scope of the HDA specification, it controls audio
|
||||||
|
routing which could just as easily have been defined using standard HDA mixer
|
||||||
|
and selector widgets.
|
||||||
|
|
||||||
|
Specifically, it selects between two sources for the input pin widget with Node
|
||||||
|
ID (NID) 1Ah: the widget's signal can come either from an audio jack (on my
|
||||||
|
laptop, a Dell XPS 13 9350, it's the headphone jack, but comments in Realtek
|
||||||
|
commits indicate that it might be a Line In on some machines) or from the PC
|
||||||
|
Beep line (which is itself multiplexed between the codec's internal beep
|
||||||
|
generator and external PCBEEP pin, depending on if the beep generator is
|
||||||
|
enabled via verbs on NID 01h). Additionally, it can mix (with optional
|
||||||
|
amplification) that signal onto the 21h and/or 14h output pins.
|
||||||
|
|
||||||
|
The register's reset value is 0x3717, corresponding to PC Beep on 1Ah that is
|
||||||
|
then amplified and mixed into both the headphones and the speakers. Not only
|
||||||
|
does this violate the HDA specification, which says that "[a vendor defined
|
||||||
|
beep input pin] connection may be maintained *only* while the Link reset
|
||||||
|
(**RST#**) is asserted", it means that we cannot ignore the register if we care
|
||||||
|
about the input that 1Ah would otherwise expose or if the PCBEEP trace is
|
||||||
|
poorly shielded and picks up chassis noise (both of which are the case on my
|
||||||
|
machine).
|
||||||
|
|
||||||
|
Unfortunately, there are lots of ways to get this register configuration wrong.
|
||||||
|
Linux, it seems, has gone through most of them. For one, the register resets
|
||||||
|
after S3 suspend: judging by existing code, this isn't the case for all vendor
|
||||||
|
registers, and it's led to some fixes that improve behavior on cold boot but
|
||||||
|
don't last after suspend. Other fixes have successfully switched the 1Ah input
|
||||||
|
away from PC Beep but have failed to disable both loopback paths. On my
|
||||||
|
machine, this means that the headphone input is amplified and looped back to
|
||||||
|
the headphone output, which uses the exact same pins! As you might expect, this
|
||||||
|
causes terrible headphone noise, the character of which is controlled by the
|
||||||
|
1Ah boost control. (If you've seen instructions online to fix XPS 13 headphone
|
||||||
|
noise by changing "Headphone Mic Boost" in ALSA, now you know why.)
|
||||||
|
|
||||||
|
The information here has been obtained through black-box reverse engineering of
|
||||||
|
the ALC256 codec's behavior and is not guaranteed to be correct. It likely
|
||||||
|
also applies for the ALC255, ALC257, ALC235, and ALC236, since those codecs
|
||||||
|
seem to be close relatives of the ALC256. (They all share one initialization
|
||||||
|
function.) Additionally, other codecs like the ALC225 and ALC285 also have this
|
||||||
|
register, judging by existing fixups in ``patch_realtek.c``, but specific
|
||||||
|
data (e.g. node IDs, bit positions, pin mappings) for those codecs may differ
|
||||||
|
from what I've described here.
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 5
|
VERSION = 5
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 9
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Kleptomaniac Octopus
|
NAME = Kleptomaniac Octopus
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
soc {
|
soc {
|
||||||
firmware: firmware {
|
firmware: firmware {
|
||||||
compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
|
compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
mboxes = <&mailbox>;
|
mboxes = <&mailbox>;
|
||||||
dma-ranges;
|
dma-ranges;
|
||||||
};
|
};
|
||||||
|
|
|
@ -372,6 +372,7 @@
|
||||||
"dsi0_ddr2",
|
"dsi0_ddr2",
|
||||||
"dsi0_ddr";
|
"dsi0_ddr";
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
aux: aux@7e215000 {
|
aux: aux@7e215000 {
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>;
|
gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>;
|
||||||
gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>;
|
gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>;
|
||||||
num-chipselects = <1>;
|
num-chipselects = <1>;
|
||||||
cs-gpios = <&gpy4 3 GPIO_ACTIVE_HIGH>;
|
cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>;
|
||||||
|
|
||||||
lcd@0 {
|
lcd@0 {
|
||||||
compatible = "samsung,ld9040";
|
compatible = "samsung,ld9040";
|
||||||
|
@ -124,8 +124,6 @@
|
||||||
vci-supply = <&ldo17_reg>;
|
vci-supply = <&ldo17_reg>;
|
||||||
reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
|
reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
|
||||||
spi-max-frequency = <1200000>;
|
spi-max-frequency = <1200000>;
|
||||||
spi-cpol;
|
|
||||||
spi-cpha;
|
|
||||||
power-on-delay = <10>;
|
power-on-delay = <10>;
|
||||||
reset-delay = <10>;
|
reset-delay = <10>;
|
||||||
panel-width-mm = <90>;
|
panel-width-mm = <90>;
|
||||||
|
|
|
@ -1039,9 +1039,8 @@
|
||||||
compatible = "fsl,imx6q-fec";
|
compatible = "fsl,imx6q-fec";
|
||||||
reg = <0x02188000 0x4000>;
|
reg = <0x02188000 0x4000>;
|
||||||
interrupt-names = "int0", "pps";
|
interrupt-names = "int0", "pps";
|
||||||
interrupts-extended =
|
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
|
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
<&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
clocks = <&clks IMX6QDL_CLK_ENET>,
|
clocks = <&clks IMX6QDL_CLK_ENET>,
|
||||||
<&clks IMX6QDL_CLK_ENET>,
|
<&clks IMX6QDL_CLK_ENET>,
|
||||||
<&clks IMX6QDL_CLK_ENET_REF>;
|
<&clks IMX6QDL_CLK_ENET_REF>;
|
||||||
|
|
|
@ -77,7 +77,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&fec {
|
&fec {
|
||||||
/delete-property/interrupts-extended;
|
|
||||||
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -345,7 +345,7 @@
|
||||||
&iomuxc {
|
&iomuxc {
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
|
pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
|
||||||
&pinctrl_gpio7>;
|
&pinctrl_gpio7 &pinctrl_usbc_det>;
|
||||||
|
|
||||||
pinctrl_gpio1: gpio1-grp {
|
pinctrl_gpio1: gpio1-grp {
|
||||||
fsl,pins = <
|
fsl,pins = <
|
||||||
|
@ -450,7 +450,6 @@
|
||||||
|
|
||||||
pinctrl_enet1: enet1grp {
|
pinctrl_enet1: enet1grp {
|
||||||
fsl,pins = <
|
fsl,pins = <
|
||||||
MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14
|
|
||||||
MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x73
|
MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x73
|
||||||
MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x73
|
MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x73
|
||||||
MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x73
|
MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x73
|
||||||
|
@ -648,6 +647,12 @@
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pinctrl_usbc_det: gpio-usbc-det {
|
||||||
|
fsl,pins = <
|
||||||
|
MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
pinctrl_usbh_reg: gpio-usbh-vbus {
|
pinctrl_usbh_reg: gpio-usbh-vbus {
|
||||||
fsl,pins = <
|
fsl,pins = <
|
||||||
MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 /* SODIMM 129 USBH PEN */
|
MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 /* SODIMM 129 USBH PEN */
|
||||||
|
|
|
@ -341,6 +341,11 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* RNG not directly accessible on N950/N9. */
|
||||||
|
&rng_target {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
&usb_otg_hs {
|
&usb_otg_hs {
|
||||||
interface-type = <0>;
|
interface-type = <0>;
|
||||||
usb-phy = <&usb2_phy>;
|
usb-phy = <&usb2_phy>;
|
||||||
|
|
|
@ -58,11 +58,14 @@
|
||||||
|
|
||||||
lvds-encoder {
|
lvds-encoder {
|
||||||
compatible = "ti,sn75lvds83", "lvds-encoder";
|
compatible = "ti,sn75lvds83", "lvds-encoder";
|
||||||
|
|
||||||
|
ports {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
port@0 {
|
port@0 {
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
|
|
||||||
lvds_in_vop0: endpoint {
|
lvds_in_vop0: endpoint {
|
||||||
remote-endpoint = <&vop0_out_lvds>;
|
remote-endpoint = <&vop0_out_lvds>;
|
||||||
};
|
};
|
||||||
|
@ -70,11 +73,13 @@
|
||||||
|
|
||||||
port@1 {
|
port@1 {
|
||||||
reg = <1>;
|
reg = <1>;
|
||||||
|
|
||||||
lvds_out_panel: endpoint {
|
lvds_out_panel: endpoint {
|
||||||
remote-endpoint = <&panel_in_lvds>;
|
remote-endpoint = <&panel_in_lvds>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
panel {
|
panel {
|
||||||
compatible = "innolux,ee101ia-01d", "panel-lvds";
|
compatible = "innolux,ee101ia-01d", "panel-lvds";
|
||||||
|
@ -465,7 +470,7 @@
|
||||||
non-removable;
|
non-removable;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
|
pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
|
||||||
vmmcq-supply = <&vccio_wl>;
|
vqmmc-supply = <&vccio_wl>;
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
|
@ -314,7 +314,7 @@
|
||||||
|
|
||||||
display_clocks: clock@1000000 {
|
display_clocks: clock@1000000 {
|
||||||
compatible = "allwinner,sun8i-a83t-de2-clk";
|
compatible = "allwinner,sun8i-a83t-de2-clk";
|
||||||
reg = <0x01000000 0x100000>;
|
reg = <0x01000000 0x10000>;
|
||||||
clocks = <&ccu CLK_BUS_DE>,
|
clocks = <&ccu CLK_BUS_DE>,
|
||||||
<&ccu CLK_PLL_DE>;
|
<&ccu CLK_PLL_DE>;
|
||||||
clock-names = "bus",
|
clock-names = "bus",
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
display_clocks: clock@1000000 {
|
display_clocks: clock@1000000 {
|
||||||
compatible = "allwinner,sun8i-r40-de2-clk",
|
compatible = "allwinner,sun8i-r40-de2-clk",
|
||||||
"allwinner,sun8i-h3-de2-clk";
|
"allwinner,sun8i-h3-de2-clk";
|
||||||
reg = <0x01000000 0x100000>;
|
reg = <0x01000000 0x10000>;
|
||||||
clocks = <&ccu CLK_BUS_DE>,
|
clocks = <&ccu CLK_BUS_DE>,
|
||||||
<&ccu CLK_DE>;
|
<&ccu CLK_DE>;
|
||||||
clock-names = "bus",
|
clock-names = "bus",
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
|
|
||||||
display_clocks: clock@1000000 {
|
display_clocks: clock@1000000 {
|
||||||
compatible = "allwinner,sun8i-v3s-de2-clk";
|
compatible = "allwinner,sun8i-v3s-de2-clk";
|
||||||
reg = <0x01000000 0x100000>;
|
reg = <0x01000000 0x10000>;
|
||||||
clocks = <&ccu CLK_BUS_DE>,
|
clocks = <&ccu CLK_BUS_DE>,
|
||||||
<&ccu CLK_DE>;
|
<&ccu CLK_DE>;
|
||||||
clock-names = "bus",
|
clock-names = "bus",
|
||||||
|
|
|
@ -114,7 +114,7 @@
|
||||||
|
|
||||||
display_clocks: clock@1000000 {
|
display_clocks: clock@1000000 {
|
||||||
/* compatible is in per SoC .dtsi file */
|
/* compatible is in per SoC .dtsi file */
|
||||||
reg = <0x01000000 0x100000>;
|
reg = <0x01000000 0x10000>;
|
||||||
clocks = <&ccu CLK_BUS_DE>,
|
clocks = <&ccu CLK_BUS_DE>,
|
||||||
<&ccu CLK_DE>;
|
<&ccu CLK_DE>;
|
||||||
clock-names = "bus",
|
clock-names = "bus",
|
||||||
|
|
|
@ -91,8 +91,10 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
|
||||||
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
|
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
|
||||||
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
|
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CONFIG_ARM_CPU_SUSPEND),y)
|
||||||
AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
|
AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
|
||||||
obj-$(CONFIG_SOC_IMX6) += resume-imx6.o
|
obj-$(CONFIG_SOC_IMX6) += resume-imx6.o
|
||||||
|
endif
|
||||||
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
|
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
|
||||||
|
|
||||||
obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
|
obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
|
||||||
|
|
|
@ -929,7 +929,11 @@ static inline void emit_a32_rsh_i64(const s8 dst[],
|
||||||
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
||||||
|
|
||||||
/* Do LSR operation */
|
/* Do LSR operation */
|
||||||
if (val < 32) {
|
if (val == 0) {
|
||||||
|
/* An immediate value of 0 encodes a shift amount of 32
|
||||||
|
* for LSR. To shift by 0, don't do anything.
|
||||||
|
*/
|
||||||
|
} else if (val < 32) {
|
||||||
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
||||||
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
||||||
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx);
|
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx);
|
||||||
|
@ -955,7 +959,11 @@ static inline void emit_a32_arsh_i64(const s8 dst[],
|
||||||
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
||||||
|
|
||||||
/* Do ARSH operation */
|
/* Do ARSH operation */
|
||||||
if (val < 32) {
|
if (val == 0) {
|
||||||
|
/* An immediate value of 0 encodes a shift amount of 32
|
||||||
|
* for ASR. To shift by 0, don't do anything.
|
||||||
|
*/
|
||||||
|
} else if (val < 32) {
|
||||||
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
||||||
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
||||||
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
|
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
|
||||||
|
@ -992,21 +1000,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
|
||||||
arm_bpf_put_reg32(dst_hi, rd[0], ctx);
|
arm_bpf_put_reg32(dst_hi, rd[0], ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_ldst_imm(s16 off, const u8 size)
|
||||||
|
{
|
||||||
|
s16 off_max = 0;
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case BPF_B:
|
||||||
|
case BPF_W:
|
||||||
|
off_max = 0xfff;
|
||||||
|
break;
|
||||||
|
case BPF_H:
|
||||||
|
off_max = 0xff;
|
||||||
|
break;
|
||||||
|
case BPF_DW:
|
||||||
|
/* Need to make sure off+4 does not overflow. */
|
||||||
|
off_max = 0xfff - 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -off_max <= off && off <= off_max;
|
||||||
|
}
|
||||||
|
|
||||||
/* *(size *)(dst + off) = src */
|
/* *(size *)(dst + off) = src */
|
||||||
static inline void emit_str_r(const s8 dst, const s8 src[],
|
static inline void emit_str_r(const s8 dst, const s8 src[],
|
||||||
s32 off, struct jit_ctx *ctx, const u8 sz){
|
s16 off, struct jit_ctx *ctx, const u8 sz){
|
||||||
const s8 *tmp = bpf2a32[TMP_REG_1];
|
const s8 *tmp = bpf2a32[TMP_REG_1];
|
||||||
s32 off_max;
|
|
||||||
s8 rd;
|
s8 rd;
|
||||||
|
|
||||||
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
||||||
|
|
||||||
if (sz == BPF_H)
|
if (!is_ldst_imm(off, sz)) {
|
||||||
off_max = 0xff;
|
|
||||||
else
|
|
||||||
off_max = 0xfff;
|
|
||||||
|
|
||||||
if (off < 0 || off > off_max) {
|
|
||||||
emit_a32_mov_i(tmp[0], off, ctx);
|
emit_a32_mov_i(tmp[0], off, ctx);
|
||||||
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
|
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
|
||||||
rd = tmp[0];
|
rd = tmp[0];
|
||||||
|
@ -1035,18 +1057,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[],
|
||||||
|
|
||||||
/* dst = *(size*)(src + off) */
|
/* dst = *(size*)(src + off) */
|
||||||
static inline void emit_ldx_r(const s8 dst[], const s8 src,
|
static inline void emit_ldx_r(const s8 dst[], const s8 src,
|
||||||
s32 off, struct jit_ctx *ctx, const u8 sz){
|
s16 off, struct jit_ctx *ctx, const u8 sz){
|
||||||
const s8 *tmp = bpf2a32[TMP_REG_1];
|
const s8 *tmp = bpf2a32[TMP_REG_1];
|
||||||
const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
|
const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
|
||||||
s8 rm = src;
|
s8 rm = src;
|
||||||
s32 off_max;
|
|
||||||
|
|
||||||
if (sz == BPF_H)
|
if (!is_ldst_imm(off, sz)) {
|
||||||
off_max = 0xff;
|
|
||||||
else
|
|
||||||
off_max = 0xfff;
|
|
||||||
|
|
||||||
if (off < 0 || off > off_max) {
|
|
||||||
emit_a32_mov_i(tmp[0], off, ctx);
|
emit_a32_mov_i(tmp[0], off, ctx);
|
||||||
emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
|
emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
|
||||||
rm = tmp[0];
|
rm = tmp[0];
|
||||||
|
|
|
@ -65,6 +65,10 @@ stack_protector_prepare: prepare0
|
||||||
include/generated/asm-offsets.h))
|
include/generated/asm-offsets.h))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Ensure that if the compiler supports branch protection we default it
|
||||||
|
# off.
|
||||||
|
KBUILD_CFLAGS += $(call cc-option,-mbranch-protection=none)
|
||||||
|
|
||||||
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
|
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
|
||||||
KBUILD_CPPFLAGS += -mbig-endian
|
KBUILD_CPPFLAGS += -mbig-endian
|
||||||
CHECKFLAGS += -D__AARCH64EB__
|
CHECKFLAGS += -D__AARCH64EB__
|
||||||
|
|
|
@ -264,7 +264,7 @@
|
||||||
|
|
||||||
display_clocks: clock@0 {
|
display_clocks: clock@0 {
|
||||||
compatible = "allwinner,sun50i-a64-de2-clk";
|
compatible = "allwinner,sun50i-a64-de2-clk";
|
||||||
reg = <0x0 0x100000>;
|
reg = <0x0 0x10000>;
|
||||||
clocks = <&ccu CLK_BUS_DE>,
|
clocks = <&ccu CLK_BUS_DE>,
|
||||||
<&ccu CLK_DE>;
|
<&ccu CLK_DE>;
|
||||||
clock-names = "bus",
|
clock-names = "bus",
|
||||||
|
|
|
@ -38,8 +38,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pmu {
|
pmu {
|
||||||
compatible = "arm,cortex-a53-pmu",
|
compatible = "arm,cortex-a53-pmu";
|
||||||
"arm,armv8-pmuv3";
|
|
||||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
|
|
@ -70,8 +70,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pmu {
|
pmu {
|
||||||
compatible = "arm,cortex-a53-pmu",
|
compatible = "arm,cortex-a53-pmu";
|
||||||
"arm,armv8-pmuv3";
|
|
||||||
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
|
|
@ -76,3 +76,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&ir {
|
||||||
|
linux,rc-map-name = "rc-videostrong-kii-pro";
|
||||||
|
};
|
||||||
|
|
|
@ -750,6 +750,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&usb3_phy0 {
|
&usb3_phy0 {
|
||||||
|
vbus-supply = <®_5v_p>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,12 @@
|
||||||
#include "armada-372x.dtsi"
|
#include "armada-372x.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
aliases {
|
||||||
|
ethernet0 = ð0;
|
||||||
|
serial0 = &uart0;
|
||||||
|
serial1 = &uart1;
|
||||||
|
};
|
||||||
|
|
||||||
chosen {
|
chosen {
|
||||||
stdout-path = "serial0:115200n8";
|
stdout-path = "serial0:115200n8";
|
||||||
};
|
};
|
||||||
|
|
|
@ -367,6 +367,7 @@
|
||||||
pinctrl-0 = <&cp0_copper_eth_phy_reset>;
|
pinctrl-0 = <&cp0_copper_eth_phy_reset>;
|
||||||
reset-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>;
|
reset-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>;
|
||||||
reset-assert-us = <10000>;
|
reset-assert-us = <10000>;
|
||||||
|
reset-deassert-us = <10000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
switch0: switch0@4 {
|
switch0: switch0@4 {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
cpu0: cpu@0 {
|
cpu0: cpu@0 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a72", "arm,armv8";
|
compatible = "arm,cortex-a72";
|
||||||
reg = <0x000>;
|
reg = <0x000>;
|
||||||
enable-method = "psci";
|
enable-method = "psci";
|
||||||
#cooling-cells = <2>;
|
#cooling-cells = <2>;
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
};
|
};
|
||||||
cpu1: cpu@1 {
|
cpu1: cpu@1 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a72", "arm,armv8";
|
compatible = "arm,cortex-a72";
|
||||||
reg = <0x001>;
|
reg = <0x001>;
|
||||||
enable-method = "psci";
|
enable-method = "psci";
|
||||||
#cooling-cells = <2>;
|
#cooling-cells = <2>;
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
};
|
};
|
||||||
cpu2: cpu@100 {
|
cpu2: cpu@100 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a72", "arm,armv8";
|
compatible = "arm,cortex-a72";
|
||||||
reg = <0x100>;
|
reg = <0x100>;
|
||||||
enable-method = "psci";
|
enable-method = "psci";
|
||||||
#cooling-cells = <2>;
|
#cooling-cells = <2>;
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
};
|
};
|
||||||
cpu3: cpu@101 {
|
cpu3: cpu@101 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a72", "arm,armv8";
|
compatible = "arm,cortex-a72";
|
||||||
reg = <0x101>;
|
reg = <0x101>;
|
||||||
enable-method = "psci";
|
enable-method = "psci";
|
||||||
#cooling-cells = <2>;
|
#cooling-cells = <2>;
|
||||||
|
|
|
@ -1208,7 +1208,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@14100000 {
|
pcie@14100000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>;
|
||||||
reg = <0x00 0x14100000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x14100000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x30000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x30000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
@ -1253,7 +1253,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@14120000 {
|
pcie@14120000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>;
|
||||||
reg = <0x00 0x14120000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x14120000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x32000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x32000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
@ -1298,7 +1298,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@14140000 {
|
pcie@14140000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>;
|
||||||
reg = <0x00 0x14140000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x14140000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x34000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x34000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
@ -1343,7 +1343,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@14160000 {
|
pcie@14160000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>;
|
||||||
reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x36000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x36000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
@ -1388,7 +1388,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@14180000 {
|
pcie@14180000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>;
|
||||||
reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
@ -1433,7 +1433,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@141a0000 {
|
pcie@141a0000 {
|
||||||
compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
|
compatible = "nvidia,tegra194-pcie";
|
||||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>;
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>;
|
||||||
reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */
|
reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
0x00 0x3a000000 0x0 0x00040000 /* configuration space (256K) */
|
0x00 0x3a000000 0x0 0x00040000 /* configuration space (256K) */
|
||||||
|
@ -1481,6 +1481,105 @@
|
||||||
0x82000000 0x0 0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */
|
0x82000000 0x0 0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pcie_ep@14160000 {
|
||||||
|
compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep";
|
||||||
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>;
|
||||||
|
reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
|
0x00 0x36040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */
|
||||||
|
0x00 0x36080000 0x0 0x00040000 /* DBI reg space (256K) */
|
||||||
|
0x14 0x00000000 0x4 0x00000000>; /* Address Space (16G) */
|
||||||
|
reg-names = "appl", "atu_dma", "dbi", "addr_space";
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
|
||||||
|
num-lanes = <4>;
|
||||||
|
num-ib-windows = <2>;
|
||||||
|
num-ob-windows = <8>;
|
||||||
|
|
||||||
|
clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_4>;
|
||||||
|
clock-names = "core";
|
||||||
|
|
||||||
|
resets = <&bpmp TEGRA194_RESET_PEX0_CORE_4_APB>,
|
||||||
|
<&bpmp TEGRA194_RESET_PEX0_CORE_4>;
|
||||||
|
reset-names = "apb", "core";
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
|
||||||
|
interrupt-names = "intr";
|
||||||
|
|
||||||
|
nvidia,bpmp = <&bpmp 4>;
|
||||||
|
|
||||||
|
nvidia,aspm-cmrt-us = <60>;
|
||||||
|
nvidia,aspm-pwr-on-t-us = <20>;
|
||||||
|
nvidia,aspm-l0s-entrance-latency-us = <3>;
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie_ep@14180000 {
|
||||||
|
compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep";
|
||||||
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>;
|
||||||
|
reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
|
0x00 0x38040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */
|
||||||
|
0x00 0x38080000 0x0 0x00040000 /* DBI reg space (256K) */
|
||||||
|
0x18 0x00000000 0x4 0x00000000>; /* Address Space (16G) */
|
||||||
|
reg-names = "appl", "atu_dma", "dbi", "addr_space";
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
|
||||||
|
num-lanes = <8>;
|
||||||
|
num-ib-windows = <2>;
|
||||||
|
num-ob-windows = <8>;
|
||||||
|
|
||||||
|
clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>;
|
||||||
|
clock-names = "core";
|
||||||
|
|
||||||
|
resets = <&bpmp TEGRA194_RESET_PEX0_CORE_0_APB>,
|
||||||
|
<&bpmp TEGRA194_RESET_PEX0_CORE_0>;
|
||||||
|
reset-names = "apb", "core";
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
|
||||||
|
interrupt-names = "intr";
|
||||||
|
|
||||||
|
nvidia,bpmp = <&bpmp 0>;
|
||||||
|
|
||||||
|
nvidia,aspm-cmrt-us = <60>;
|
||||||
|
nvidia,aspm-pwr-on-t-us = <20>;
|
||||||
|
nvidia,aspm-l0s-entrance-latency-us = <3>;
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie_ep@141a0000 {
|
||||||
|
compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep";
|
||||||
|
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>;
|
||||||
|
reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */
|
||||||
|
0x00 0x3a040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */
|
||||||
|
0x00 0x3a080000 0x0 0x00040000 /* DBI reg space (256K) */
|
||||||
|
0x1c 0x00000000 0x4 0x00000000>; /* Address Space (16G) */
|
||||||
|
reg-names = "appl", "atu_dma", "dbi", "addr_space";
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
|
||||||
|
num-lanes = <8>;
|
||||||
|
num-ib-windows = <2>;
|
||||||
|
num-ob-windows = <8>;
|
||||||
|
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&clkreq_c5_bi_dir_state>;
|
||||||
|
|
||||||
|
clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>;
|
||||||
|
clock-names = "core";
|
||||||
|
|
||||||
|
resets = <&bpmp TEGRA194_RESET_PEX1_CORE_5_APB>,
|
||||||
|
<&bpmp TEGRA194_RESET_PEX1_CORE_5>;
|
||||||
|
reset-names = "apb", "core";
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
|
||||||
|
interrupt-names = "intr";
|
||||||
|
|
||||||
|
nvidia,bpmp = <&bpmp 5>;
|
||||||
|
|
||||||
|
nvidia,aspm-cmrt-us = <60>;
|
||||||
|
nvidia,aspm-pwr-on-t-us = <20>;
|
||||||
|
nvidia,aspm-l0s-entrance-latency-us = <3>;
|
||||||
|
};
|
||||||
|
|
||||||
sysram@40000000 {
|
sysram@40000000 {
|
||||||
compatible = "nvidia,tegra194-sysram", "mmio-sram";
|
compatible = "nvidia,tegra194-sysram", "mmio-sram";
|
||||||
reg = <0x0 0x40000000 0x0 0x50000>;
|
reg = <0x0 0x40000000 0x0 0x50000>;
|
||||||
|
|
|
@ -309,6 +309,7 @@
|
||||||
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
dma-coherent;
|
dma-coherent;
|
||||||
power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>;
|
power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>;
|
||||||
|
clocks = <&k3_clks 151 2>, <&k3_clks 151 7>;
|
||||||
assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>;
|
assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>;
|
||||||
assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
|
assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
|
||||||
<&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
|
<&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
|
||||||
|
@ -348,6 +349,7 @@
|
||||||
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
dma-coherent;
|
dma-coherent;
|
||||||
power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
|
power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
|
||||||
|
clocks = <&k3_clks 152 2>;
|
||||||
assigned-clocks = <&k3_clks 152 2>;
|
assigned-clocks = <&k3_clks 152 2>;
|
||||||
assigned-clock-parents = <&k3_clks 152 4>; /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
|
assigned-clock-parents = <&k3_clks 152 4>; /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,9 @@
|
||||||
#ifndef CONFIG_BROKEN_GAS_INST
|
#ifndef CONFIG_BROKEN_GAS_INST
|
||||||
|
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
#define __emit_inst(x) .inst (x)
|
// The space separator is omitted so that __emit_inst(x) can be parsed as
|
||||||
|
// either an assembler directive or an assembler macro argument.
|
||||||
|
#define __emit_inst(x) .inst(x)
|
||||||
#else
|
#else
|
||||||
#define __emit_inst(x) ".inst " __stringify((x)) "\n\t"
|
#define __emit_inst(x) ".inst " __stringify((x)) "\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -601,7 +601,7 @@ static struct undef_hook setend_hooks[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* Thumb mode */
|
/* Thumb mode */
|
||||||
.instr_mask = 0x0000fff7,
|
.instr_mask = 0xfffffff7,
|
||||||
.instr_val = 0x0000b650,
|
.instr_val = 0x0000b650,
|
||||||
.pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK),
|
.pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK),
|
||||||
.pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR),
|
.pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR),
|
||||||
|
|
|
@ -260,18 +260,7 @@ static int __aarch32_alloc_vdso_pages(void)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = aarch32_alloc_kuser_vdso_page();
|
return aarch32_alloc_kuser_vdso_page();
|
||||||
if (ret) {
|
|
||||||
unsigned long c_vvar =
|
|
||||||
(unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]);
|
|
||||||
unsigned long c_vdso =
|
|
||||||
(unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]);
|
|
||||||
|
|
||||||
free_page(c_vvar);
|
|
||||||
free_page(c_vdso);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int __aarch32_alloc_vdso_pages(void)
|
static int __aarch32_alloc_vdso_pages(void)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/memory_hotplug.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
#include <asm/ptdump.h>
|
#include <asm/ptdump.h>
|
||||||
|
@ -7,7 +8,10 @@
|
||||||
static int ptdump_show(struct seq_file *m, void *v)
|
static int ptdump_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
struct ptdump_info *info = m->private;
|
struct ptdump_info *info = m->private;
|
||||||
|
|
||||||
|
get_online_mems();
|
||||||
ptdump_walk(m, info);
|
ptdump_walk(m, info);
|
||||||
|
put_online_mems();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DEFINE_SHOW_ATTRIBUTE(ptdump);
|
DEFINE_SHOW_ATTRIBUTE(ptdump);
|
||||||
|
|
|
@ -172,10 +172,7 @@
|
||||||
addi r6, 0xe
|
addi r6, 0xe
|
||||||
cpwcr r6, cpcr30
|
cpwcr r6, cpcr30
|
||||||
|
|
||||||
lsri r6, 28
|
movi r6, 0
|
||||||
addi r6, 2
|
|
||||||
lsli r6, 28
|
|
||||||
addi r6, 0xe
|
|
||||||
cpwcr r6, cpcr31
|
cpwcr r6, cpcr31
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,6 @@
|
||||||
#define MTCR_DIST 0xC0006420
|
#define MTCR_DIST 0xC0006420
|
||||||
#define MFCR_DIST 0xC0006020
|
#define MFCR_DIST 0xC0006020
|
||||||
|
|
||||||
void __init init_fpu(void)
|
|
||||||
{
|
|
||||||
mtcr("cr<1, 2>", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fpu_libc_helper() is to help libc to excute:
|
* fpu_libc_helper() is to help libc to excute:
|
||||||
* - mfcr %a, cr<1, 2>
|
* - mfcr %a, cr<1, 2>
|
||||||
|
|
|
@ -230,11 +230,8 @@
|
||||||
addi r6, 0x1ce
|
addi r6, 0x1ce
|
||||||
mtcr r6, cr<30, 15> /* Set MSA0 */
|
mtcr r6, cr<30, 15> /* Set MSA0 */
|
||||||
|
|
||||||
lsri r6, 28
|
movi r6, 0
|
||||||
addi r6, 2
|
mtcr r6, cr<31, 15> /* Clr MSA1 */
|
||||||
lsli r6, 28
|
|
||||||
addi r6, 0x1ce
|
|
||||||
mtcr r6, cr<31, 15> /* Set MSA1 */
|
|
||||||
|
|
||||||
/* enable MMU */
|
/* enable MMU */
|
||||||
mfcr r6, cr18
|
mfcr r6, cr18
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
int fpu_libc_helper(struct pt_regs *regs);
|
int fpu_libc_helper(struct pt_regs *regs);
|
||||||
void fpu_fpe(struct pt_regs *regs);
|
void fpu_fpe(struct pt_regs *regs);
|
||||||
void __init init_fpu(void);
|
|
||||||
|
static inline void init_fpu(void) { mtcr("cr<1, 2>", 0); }
|
||||||
|
|
||||||
void save_to_user_fp(struct user_fp *user_fp);
|
void save_to_user_fp(struct user_fp *user_fp);
|
||||||
void restore_from_user_fp(struct user_fp *user_fp);
|
void restore_from_user_fp(struct user_fp *user_fp);
|
||||||
|
|
|
@ -43,6 +43,7 @@ extern struct cpuinfo_csky cpu_data[];
|
||||||
struct thread_struct {
|
struct thread_struct {
|
||||||
unsigned long ksp; /* kernel stack pointer */
|
unsigned long ksp; /* kernel stack pointer */
|
||||||
unsigned long sr; /* saved status register */
|
unsigned long sr; /* saved status register */
|
||||||
|
unsigned long trap_no; /* saved status register */
|
||||||
|
|
||||||
/* FPU regs */
|
/* FPU regs */
|
||||||
struct user_fp __aligned(16) user_fp;
|
struct user_fp __aligned(16) user_fp;
|
||||||
|
|
|
@ -21,6 +21,11 @@ END(_start)
|
||||||
ENTRY(_start_smp_secondary)
|
ENTRY(_start_smp_secondary)
|
||||||
SETUP_MMU
|
SETUP_MMU
|
||||||
|
|
||||||
|
/* copy msa1 from CPU0 */
|
||||||
|
lrw r6, secondary_msa1
|
||||||
|
ld.w r6, (r6, 0)
|
||||||
|
mtcr r6, cr<31, 15>
|
||||||
|
|
||||||
/* set stack point */
|
/* set stack point */
|
||||||
lrw r6, secondary_stack
|
lrw r6, secondary_stack
|
||||||
ld.w r6, (r6, 0)
|
ld.w r6, (r6, 0)
|
||||||
|
|
|
@ -24,26 +24,9 @@ struct screen_info screen_info = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
phys_addr_t __init_memblock memblock_end_of_REG0(void)
|
|
||||||
{
|
|
||||||
return (memblock.memory.regions[0].base +
|
|
||||||
memblock.memory.regions[0].size);
|
|
||||||
}
|
|
||||||
|
|
||||||
phys_addr_t __init_memblock memblock_start_of_REG1(void)
|
|
||||||
{
|
|
||||||
return memblock.memory.regions[1].base;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t __init_memblock memblock_size_of_REG1(void)
|
|
||||||
{
|
|
||||||
return memblock.memory.regions[1].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init csky_memblock_init(void)
|
static void __init csky_memblock_init(void)
|
||||||
{
|
{
|
||||||
unsigned long zone_size[MAX_NR_ZONES];
|
unsigned long zone_size[MAX_NR_ZONES];
|
||||||
unsigned long zhole_size[MAX_NR_ZONES];
|
|
||||||
signed long size;
|
signed long size;
|
||||||
|
|
||||||
memblock_reserve(__pa(_stext), _end - _stext);
|
memblock_reserve(__pa(_stext), _end - _stext);
|
||||||
|
@ -54,54 +37,36 @@ static void __init csky_memblock_init(void)
|
||||||
memblock_dump_all();
|
memblock_dump_all();
|
||||||
|
|
||||||
memset(zone_size, 0, sizeof(zone_size));
|
memset(zone_size, 0, sizeof(zone_size));
|
||||||
memset(zhole_size, 0, sizeof(zhole_size));
|
|
||||||
|
|
||||||
min_low_pfn = PFN_UP(memblock_start_of_DRAM());
|
min_low_pfn = PFN_UP(memblock_start_of_DRAM());
|
||||||
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
||||||
|
|
||||||
max_low_pfn = PFN_UP(memblock_end_of_REG0());
|
|
||||||
if (max_low_pfn == 0)
|
|
||||||
max_low_pfn = max_pfn;
|
|
||||||
|
|
||||||
size = max_pfn - min_low_pfn;
|
size = max_pfn - min_low_pfn;
|
||||||
|
|
||||||
if (memblock.memory.cnt > 1) {
|
if (size <= PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET))
|
||||||
|
zone_size[ZONE_NORMAL] = size;
|
||||||
|
else if (size < PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) {
|
||||||
zone_size[ZONE_NORMAL] =
|
zone_size[ZONE_NORMAL] =
|
||||||
PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn;
|
PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET);
|
||||||
zhole_size[ZONE_NORMAL] =
|
max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
|
||||||
PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn;
|
|
||||||
} else {
|
} else {
|
||||||
if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET))
|
|
||||||
zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn;
|
|
||||||
else {
|
|
||||||
zone_size[ZONE_NORMAL] =
|
zone_size[ZONE_NORMAL] =
|
||||||
PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
|
PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
|
||||||
max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
|
max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
|
||||||
}
|
write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHMEM
|
#ifdef CONFIG_HIGHMEM
|
||||||
size = 0;
|
zone_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
|
||||||
if (memblock.memory.cnt > 1) {
|
|
||||||
size = PFN_DOWN(memblock_size_of_REG1());
|
|
||||||
highstart_pfn = PFN_DOWN(memblock_start_of_REG1());
|
|
||||||
} else {
|
|
||||||
size = max_pfn - min_low_pfn -
|
|
||||||
PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
|
|
||||||
highstart_pfn = min_low_pfn +
|
|
||||||
PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
zone_size[ZONE_HIGHMEM] = size;
|
|
||||||
|
|
||||||
|
highstart_pfn = max_low_pfn;
|
||||||
highend_pfn = max_pfn;
|
highend_pfn = max_pfn;
|
||||||
#endif
|
#endif
|
||||||
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
||||||
|
|
||||||
dma_contiguous_reserve(0);
|
dma_contiguous_reserve(0);
|
||||||
|
|
||||||
free_area_init_node(0, zone_size, min_low_pfn, zhole_size);
|
free_area_init_node(0, zone_size, min_low_pfn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init setup_arch(char **cmdline_p)
|
void __init setup_arch(char **cmdline_p)
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/pgalloc.h>
|
#include <asm/pgalloc.h>
|
||||||
|
#ifdef CONFIG_CPU_HAS_FPU
|
||||||
|
#include <abi/fpu.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ipi_data_struct {
|
struct ipi_data_struct {
|
||||||
unsigned long bits ____cacheline_aligned;
|
unsigned long bits ____cacheline_aligned;
|
||||||
|
@ -156,6 +159,8 @@ volatile unsigned int secondary_hint;
|
||||||
volatile unsigned int secondary_ccr;
|
volatile unsigned int secondary_ccr;
|
||||||
volatile unsigned int secondary_stack;
|
volatile unsigned int secondary_stack;
|
||||||
|
|
||||||
|
unsigned long secondary_msa1;
|
||||||
|
|
||||||
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
|
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
|
||||||
{
|
{
|
||||||
unsigned long mask = 1 << cpu;
|
unsigned long mask = 1 << cpu;
|
||||||
|
@ -164,6 +169,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
|
||||||
(unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8;
|
(unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8;
|
||||||
secondary_hint = mfcr("cr31");
|
secondary_hint = mfcr("cr31");
|
||||||
secondary_ccr = mfcr("cr18");
|
secondary_ccr = mfcr("cr18");
|
||||||
|
secondary_msa1 = read_mmu_msa1();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Because other CPUs are in reset status, we must flush data
|
* Because other CPUs are in reset status, we must flush data
|
||||||
|
|
|
@ -115,8 +115,9 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
||||||
int sig;
|
int sig;
|
||||||
unsigned long vector;
|
unsigned long vector;
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
|
struct task_struct *tsk = current;
|
||||||
|
|
||||||
vector = (mfcr("psr") >> 16) & 0xff;
|
vector = (regs->sr >> 16) & 0xff;
|
||||||
|
|
||||||
switch (vector) {
|
switch (vector) {
|
||||||
case VEC_ZERODIV:
|
case VEC_ZERODIV:
|
||||||
|
@ -129,6 +130,7 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
||||||
sig = SIGTRAP;
|
sig = SIGTRAP;
|
||||||
break;
|
break;
|
||||||
case VEC_ILLEGAL:
|
case VEC_ILLEGAL:
|
||||||
|
tsk->thread.trap_no = vector;
|
||||||
die_if_kernel("Kernel mode ILLEGAL", regs, vector);
|
die_if_kernel("Kernel mode ILLEGAL", regs, vector);
|
||||||
#ifndef CONFIG_CPU_NO_USER_BKPT
|
#ifndef CONFIG_CPU_NO_USER_BKPT
|
||||||
if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
|
if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT)
|
||||||
|
@ -146,16 +148,20 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
||||||
sig = SIGTRAP;
|
sig = SIGTRAP;
|
||||||
break;
|
break;
|
||||||
case VEC_ACCESS:
|
case VEC_ACCESS:
|
||||||
|
tsk->thread.trap_no = vector;
|
||||||
return buserr(regs);
|
return buserr(regs);
|
||||||
#ifdef CONFIG_CPU_NEED_SOFTALIGN
|
#ifdef CONFIG_CPU_NEED_SOFTALIGN
|
||||||
case VEC_ALIGN:
|
case VEC_ALIGN:
|
||||||
|
tsk->thread.trap_no = vector;
|
||||||
return csky_alignment(regs);
|
return csky_alignment(regs);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_CPU_HAS_FPU
|
#ifdef CONFIG_CPU_HAS_FPU
|
||||||
case VEC_FPE:
|
case VEC_FPE:
|
||||||
|
tsk->thread.trap_no = vector;
|
||||||
die_if_kernel("Kernel mode FPE", regs, vector);
|
die_if_kernel("Kernel mode FPE", regs, vector);
|
||||||
return fpu_fpe(regs);
|
return fpu_fpe(regs);
|
||||||
case VEC_PRIV:
|
case VEC_PRIV:
|
||||||
|
tsk->thread.trap_no = vector;
|
||||||
die_if_kernel("Kernel mode PRIV", regs, vector);
|
die_if_kernel("Kernel mode PRIV", regs, vector);
|
||||||
if (fpu_libc_helper(regs))
|
if (fpu_libc_helper(regs))
|
||||||
return;
|
return;
|
||||||
|
@ -164,5 +170,8 @@ asmlinkage void trap_c(struct pt_regs *regs)
|
||||||
sig = SIGSEGV;
|
sig = SIGSEGV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsk->thread.trap_no = vector;
|
||||||
|
|
||||||
send_sig(sig, current, 0);
|
send_sig(sig, current, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,11 +179,14 @@ bad_area:
|
||||||
bad_area_nosemaphore:
|
bad_area_nosemaphore:
|
||||||
/* User mode accesses just cause a SIGSEGV */
|
/* User mode accesses just cause a SIGSEGV */
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
|
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||||
force_sig_fault(SIGSEGV, si_code, (void __user *)address);
|
force_sig_fault(SIGSEGV, si_code, (void __user *)address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
no_context:
|
no_context:
|
||||||
|
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||||
|
|
||||||
/* Are we prepared to handle this kernel fault? */
|
/* Are we prepared to handle this kernel fault? */
|
||||||
if (fixup_exception(regs))
|
if (fixup_exception(regs))
|
||||||
return;
|
return;
|
||||||
|
@ -198,6 +201,8 @@ no_context:
|
||||||
die_if_kernel("Oops", regs, write);
|
die_if_kernel("Oops", regs, write);
|
||||||
|
|
||||||
out_of_memory:
|
out_of_memory:
|
||||||
|
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We ran out of memory, call the OOM killer, and return the userspace
|
* We ran out of memory, call the OOM killer, and return the userspace
|
||||||
* (which will retry the fault, or kill us if we got oom-killed).
|
* (which will retry the fault, or kill us if we got oom-killed).
|
||||||
|
@ -206,6 +211,8 @@ out_of_memory:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do_sigbus:
|
do_sigbus:
|
||||||
|
tsk->thread.trap_no = (regs->sr >> 16) & 0xff;
|
||||||
|
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
/* Kernel mode? Handle exceptions or die */
|
/* Kernel mode? Handle exceptions or die */
|
||||||
|
|
|
@ -62,6 +62,11 @@
|
||||||
enable-active-high;
|
enable-active-high;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ir: ir {
|
||||||
|
compatible = "gpio-ir-receiver";
|
||||||
|
gpios = <&gpe 3 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
|
|
||||||
wlan0_power: fixedregulator@1 {
|
wlan0_power: fixedregulator@1 {
|
||||||
compatible = "regulator-fixed";
|
compatible = "regulator-fixed";
|
||||||
regulator-name = "wlan0_power";
|
regulator-name = "wlan0_power";
|
||||||
|
|
|
@ -2199,6 +2199,9 @@ static int octeon_irq_cib_map(struct irq_domain *d,
|
||||||
}
|
}
|
||||||
|
|
||||||
cd = kzalloc(sizeof(*cd), GFP_KERNEL);
|
cd = kzalloc(sizeof(*cd), GFP_KERNEL);
|
||||||
|
if (!cd)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
cd->host_data = host_data;
|
cd->host_data = host_data;
|
||||||
cd->bit = hw;
|
cd->bit = hw;
|
||||||
|
|
||||||
|
|
|
@ -1481,6 +1481,7 @@ static void build_r4000_tlb_refill_handler(void)
|
||||||
|
|
||||||
static void setup_pw(void)
|
static void setup_pw(void)
|
||||||
{
|
{
|
||||||
|
unsigned int pwctl;
|
||||||
unsigned long pgd_i, pgd_w;
|
unsigned long pgd_i, pgd_w;
|
||||||
#ifndef __PAGETABLE_PMD_FOLDED
|
#ifndef __PAGETABLE_PMD_FOLDED
|
||||||
unsigned long pmd_i, pmd_w;
|
unsigned long pmd_i, pmd_w;
|
||||||
|
@ -1507,6 +1508,7 @@ static void setup_pw(void)
|
||||||
|
|
||||||
pte_i = ilog2(_PAGE_GLOBAL);
|
pte_i = ilog2(_PAGE_GLOBAL);
|
||||||
pte_w = 0;
|
pte_w = 0;
|
||||||
|
pwctl = 1 << 30; /* Set PWDirExt */
|
||||||
|
|
||||||
#ifndef __PAGETABLE_PMD_FOLDED
|
#ifndef __PAGETABLE_PMD_FOLDED
|
||||||
write_c0_pwfield(pgd_i << 24 | pmd_i << 12 | pt_i << 6 | pte_i);
|
write_c0_pwfield(pgd_i << 24 | pmd_i << 12 | pt_i << 6 | pte_i);
|
||||||
|
@ -1517,8 +1519,9 @@ static void setup_pw(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||||
write_c0_pwctl(1 << 6 | psn);
|
pwctl |= (1 << 6 | psn);
|
||||||
#endif
|
#endif
|
||||||
|
write_c0_pwctl(pwctl);
|
||||||
write_c0_kpgd((long)swapper_pg_dir);
|
write_c0_kpgd((long)swapper_pg_dir);
|
||||||
kscratch_used_mask |= (1 << 7); /* KScratch6 is used for KPGD */
|
kscratch_used_mask |= (1 << 7); /* KScratch6 is used for KPGD */
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,12 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
|
||||||
extern int hash__has_transparent_hugepage(void);
|
extern int hash__has_transparent_hugepage(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return pmd;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
|
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
|
||||||
|
|
|
@ -246,7 +246,7 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
|
||||||
*/
|
*/
|
||||||
static inline int hash__pmd_trans_huge(pmd_t pmd)
|
static inline int hash__pmd_trans_huge(pmd_t pmd)
|
||||||
{
|
{
|
||||||
return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE)) ==
|
return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)) ==
|
||||||
(_PAGE_PTE | H_PAGE_THP_HUGE));
|
(_PAGE_PTE | H_PAGE_THP_HUGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +272,12 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
|
||||||
unsigned long addr, pmd_t *pmdp);
|
unsigned long addr, pmd_t *pmdp);
|
||||||
extern int hash__has_transparent_hugepage(void);
|
extern int hash__has_transparent_hugepage(void);
|
||||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||||
|
|
||||||
|
static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return __pmd(pmd_val(pmd) | (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
|
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
|
||||||
|
|
|
@ -1303,7 +1303,9 @@ extern void serialize_against_pte_lookup(struct mm_struct *mm);
|
||||||
|
|
||||||
static inline pmd_t pmd_mkdevmap(pmd_t pmd)
|
static inline pmd_t pmd_mkdevmap(pmd_t pmd)
|
||||||
{
|
{
|
||||||
return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP));
|
if (radix_enabled())
|
||||||
|
return radix__pmd_mkdevmap(pmd);
|
||||||
|
return hash__pmd_mkdevmap(pmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pmd_devmap(pmd_t pmd)
|
static inline int pmd_devmap(pmd_t pmd)
|
||||||
|
|
|
@ -263,6 +263,11 @@ static inline int radix__has_transparent_hugepage(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline pmd_t radix__pmd_mkdevmap(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP));
|
||||||
|
}
|
||||||
|
|
||||||
extern int __meminit radix__vmemmap_create_mapping(unsigned long start,
|
extern int __meminit radix__vmemmap_create_mapping(unsigned long start,
|
||||||
unsigned long page_size,
|
unsigned long page_size,
|
||||||
unsigned long phys);
|
unsigned long phys);
|
||||||
|
|
|
@ -27,12 +27,12 @@ struct drmem_lmb_info {
|
||||||
extern struct drmem_lmb_info *drmem_info;
|
extern struct drmem_lmb_info *drmem_info;
|
||||||
|
|
||||||
#define for_each_drmem_lmb_in_range(lmb, start, end) \
|
#define for_each_drmem_lmb_in_range(lmb, start, end) \
|
||||||
for ((lmb) = (start); (lmb) <= (end); (lmb)++)
|
for ((lmb) = (start); (lmb) < (end); (lmb)++)
|
||||||
|
|
||||||
#define for_each_drmem_lmb(lmb) \
|
#define for_each_drmem_lmb(lmb) \
|
||||||
for_each_drmem_lmb_in_range((lmb), \
|
for_each_drmem_lmb_in_range((lmb), \
|
||||||
&drmem_info->lmbs[0], \
|
&drmem_info->lmbs[0], \
|
||||||
&drmem_info->lmbs[drmem_info->n_lmbs - 1])
|
&drmem_info->lmbs[drmem_info->n_lmbs])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The of_drconf_cell_v1 struct defines the layout of the LMB data
|
* The of_drconf_cell_v1 struct defines the layout of the LMB data
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
|
|
||||||
#define JMP_BUF_LEN 23
|
#define JMP_BUF_LEN 23
|
||||||
|
|
||||||
extern long setjmp(long *) __attribute__((returns_twice));
|
typedef long jmp_buf[JMP_BUF_LEN];
|
||||||
extern void longjmp(long *, long) __attribute__((noreturn));
|
|
||||||
|
extern int setjmp(jmp_buf env) __attribute__((returns_twice));
|
||||||
|
extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_SETJMP_H */
|
#endif /* _ASM_POWERPC_SETJMP_H */
|
||||||
|
|
|
@ -139,7 +139,6 @@ static void __init cpufeatures_setup_cpu(void)
|
||||||
/* Initialize the base environment -- clear FSCR/HFSCR. */
|
/* Initialize the base environment -- clear FSCR/HFSCR. */
|
||||||
hv_mode = !!(mfmsr() & MSR_HV);
|
hv_mode = !!(mfmsr() & MSR_HV);
|
||||||
if (hv_mode) {
|
if (hv_mode) {
|
||||||
/* CPU_FTR_HVMODE is used early in PACA setup */
|
|
||||||
cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
|
cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
|
||||||
mtspr(SPRN_HFSCR, 0);
|
mtspr(SPRN_HFSCR, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -710,7 +710,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
|
||||||
stw r10,_CCR(r1)
|
stw r10,_CCR(r1)
|
||||||
stw r1,KSP(r3) /* Set old stack pointer */
|
stw r1,KSP(r3) /* Set old stack pointer */
|
||||||
|
|
||||||
kuap_check r2, r4
|
kuap_check r2, r0
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* We need a sync somewhere here to make sure that if the
|
/* We need a sync somewhere here to make sure that if the
|
||||||
* previous task gets rescheduled on another CPU, it sees all
|
* previous task gets rescheduled on another CPU, it sees all
|
||||||
|
|
|
@ -264,6 +264,9 @@ int kprobe_handler(struct pt_regs *regs)
|
||||||
if (user_mode(regs))
|
if (user_mode(regs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't want to be preempted for the entire
|
* We don't want to be preempted for the entire
|
||||||
* duration of kprobe processing
|
* duration of kprobe processing
|
||||||
|
|
|
@ -176,7 +176,7 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
|
||||||
struct paca_struct **paca_ptrs __read_mostly;
|
struct paca_struct **paca_ptrs __read_mostly;
|
||||||
EXPORT_SYMBOL(paca_ptrs);
|
EXPORT_SYMBOL(paca_ptrs);
|
||||||
|
|
||||||
void __init initialise_paca(struct paca_struct *new_paca, int cpu)
|
void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
new_paca->lppaca_ptr = NULL;
|
new_paca->lppaca_ptr = NULL;
|
||||||
|
@ -205,7 +205,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put the paca pointer into r13 and SPRG_PACA */
|
/* Put the paca pointer into r13 and SPRG_PACA */
|
||||||
void setup_paca(struct paca_struct *new_paca)
|
void __nostackprotector setup_paca(struct paca_struct *new_paca)
|
||||||
{
|
{
|
||||||
/* Setup r13 */
|
/* Setup r13 */
|
||||||
local_paca = new_paca;
|
local_paca = new_paca;
|
||||||
|
@ -214,11 +214,15 @@ void setup_paca(struct paca_struct *new_paca)
|
||||||
/* On Book3E, initialize the TLB miss exception frames */
|
/* On Book3E, initialize the TLB miss exception frames */
|
||||||
mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
|
mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
|
||||||
#else
|
#else
|
||||||
/* In HV mode, we setup both HPACA and PACA to avoid problems
|
/*
|
||||||
|
* In HV mode, we setup both HPACA and PACA to avoid problems
|
||||||
* if we do a GET_PACA() before the feature fixups have been
|
* if we do a GET_PACA() before the feature fixups have been
|
||||||
* applied
|
* applied.
|
||||||
|
*
|
||||||
|
* Normally you should test against CPU_FTR_HVMODE, but CPU features
|
||||||
|
* are not yet set up when we first reach here.
|
||||||
*/
|
*/
|
||||||
if (early_cpu_has_feature(CPU_FTR_HVMODE))
|
if (mfmsr() & MSR_HV)
|
||||||
mtspr(SPRN_SPRG_HPACA, local_paca);
|
mtspr(SPRN_SPRG_HPACA, local_paca);
|
||||||
#endif
|
#endif
|
||||||
mtspr(SPRN_SPRG_PACA, local_paca);
|
mtspr(SPRN_SPRG_PACA, local_paca);
|
||||||
|
|
|
@ -1773,6 +1773,9 @@ static void __init prom_rtas_os_term(char *str)
|
||||||
if (token == 0)
|
if (token == 0)
|
||||||
prom_panic("Could not get token for ibm,os-term\n");
|
prom_panic("Could not get token for ibm,os-term\n");
|
||||||
os_term_args.token = cpu_to_be32(token);
|
os_term_args.token = cpu_to_be32(token);
|
||||||
|
os_term_args.nargs = cpu_to_be32(1);
|
||||||
|
os_term_args.nret = cpu_to_be32(1);
|
||||||
|
os_term_args.args[0] = cpu_to_be32(__pa(str));
|
||||||
prom_rtas_hcall((uint64_t)&os_term_args);
|
prom_rtas_hcall((uint64_t)&os_term_args);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC_SVM */
|
#endif /* CONFIG_PPC_SVM */
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
#ifndef __ARCH_POWERPC_KERNEL_SETUP_H
|
#ifndef __ARCH_POWERPC_KERNEL_SETUP_H
|
||||||
#define __ARCH_POWERPC_KERNEL_SETUP_H
|
#define __ARCH_POWERPC_KERNEL_SETUP_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_CC_IS_CLANG
|
||||||
|
#define __nostackprotector
|
||||||
|
#else
|
||||||
|
#define __nostackprotector __attribute__((__optimize__("no-stack-protector")))
|
||||||
|
#endif
|
||||||
|
|
||||||
void initialize_cache_info(void);
|
void initialize_cache_info(void);
|
||||||
void irqstack_early_init(void);
|
void irqstack_early_init(void);
|
||||||
|
|
||||||
|
|
|
@ -279,24 +279,42 @@ void __init record_spr_defaults(void)
|
||||||
* device-tree is not accessible via normal means at this point.
|
* device-tree is not accessible via normal means at this point.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void __init early_setup(unsigned long dt_ptr)
|
void __init __nostackprotector early_setup(unsigned long dt_ptr)
|
||||||
{
|
{
|
||||||
static __initdata struct paca_struct boot_paca;
|
static __initdata struct paca_struct boot_paca;
|
||||||
|
|
||||||
/* -------- printk is _NOT_ safe to use here ! ------- */
|
/* -------- printk is _NOT_ safe to use here ! ------- */
|
||||||
|
|
||||||
/* Try new device tree based feature discovery ... */
|
/*
|
||||||
if (!dt_cpu_ftrs_init(__va(dt_ptr)))
|
* Assume we're on cpu 0 for now.
|
||||||
/* Otherwise use the old style CPU table */
|
*
|
||||||
identify_cpu(0, mfspr(SPRN_PVR));
|
* We need to load a PACA very early for a few reasons.
|
||||||
|
*
|
||||||
/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
|
* The stack protector canary is stored in the paca, so as soon as we
|
||||||
|
* call any stack protected code we need r13 pointing somewhere valid.
|
||||||
|
*
|
||||||
|
* If we are using kcov it will call in_task() in its instrumentation,
|
||||||
|
* which relies on the current task from the PACA.
|
||||||
|
*
|
||||||
|
* dt_cpu_ftrs_init() calls into generic OF/fdt code, as well as
|
||||||
|
* printk(), which can trigger both stack protector and kcov.
|
||||||
|
*
|
||||||
|
* percpu variables and spin locks also use the paca.
|
||||||
|
*
|
||||||
|
* So set up a temporary paca. It will be replaced below once we know
|
||||||
|
* what CPU we are on.
|
||||||
|
*/
|
||||||
initialise_paca(&boot_paca, 0);
|
initialise_paca(&boot_paca, 0);
|
||||||
setup_paca(&boot_paca);
|
setup_paca(&boot_paca);
|
||||||
fixup_boot_paca();
|
fixup_boot_paca();
|
||||||
|
|
||||||
/* -------- printk is now safe to use ------- */
|
/* -------- printk is now safe to use ------- */
|
||||||
|
|
||||||
|
/* Try new device tree based feature discovery ... */
|
||||||
|
if (!dt_cpu_ftrs_init(__va(dt_ptr)))
|
||||||
|
/* Otherwise use the old style CPU table */
|
||||||
|
identify_cpu(0, mfspr(SPRN_PVR));
|
||||||
|
|
||||||
/* Enable early debugging if any specified (see udbg.h) */
|
/* Enable early debugging if any specified (see udbg.h) */
|
||||||
udbg_early_init();
|
udbg_early_init();
|
||||||
|
|
||||||
|
@ -516,6 +534,8 @@ static bool __init parse_cache_info(struct device_node *np,
|
||||||
lsizep = of_get_property(np, propnames[3], NULL);
|
lsizep = of_get_property(np, propnames[3], NULL);
|
||||||
if (bsizep == NULL)
|
if (bsizep == NULL)
|
||||||
bsizep = lsizep;
|
bsizep = lsizep;
|
||||||
|
if (lsizep == NULL)
|
||||||
|
lsizep = bsizep;
|
||||||
if (lsizep != NULL)
|
if (lsizep != NULL)
|
||||||
lsize = be32_to_cpu(*lsizep);
|
lsize = be32_to_cpu(*lsizep);
|
||||||
if (bsizep != NULL)
|
if (bsizep != NULL)
|
||||||
|
|
|
@ -473,8 +473,10 @@ static long restore_tm_sigcontexts(struct task_struct *tsk,
|
||||||
err |= __get_user(tsk->thread.ckpt_regs.ccr,
|
err |= __get_user(tsk->thread.ckpt_regs.ccr,
|
||||||
&sc->gp_regs[PT_CCR]);
|
&sc->gp_regs[PT_CCR]);
|
||||||
|
|
||||||
|
/* Don't allow userspace to set the trap value */
|
||||||
|
regs->trap = 0;
|
||||||
|
|
||||||
/* These regs are not checkpointed; they can go in 'regs'. */
|
/* These regs are not checkpointed; they can go in 'regs'. */
|
||||||
err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
|
|
||||||
err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
|
err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
|
||||||
err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
|
err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
|
||||||
err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
|
err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
|
||||||
|
|
|
@ -522,35 +522,6 @@ static inline void clear_irq_work_pending(void)
|
||||||
"i" (offsetof(struct paca_struct, irq_work_pending)));
|
"i" (offsetof(struct paca_struct, irq_work_pending)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_irq_work_raise(void)
|
|
||||||
{
|
|
||||||
preempt_disable();
|
|
||||||
set_irq_work_pending_flag();
|
|
||||||
/*
|
|
||||||
* Non-nmi code running with interrupts disabled will replay
|
|
||||||
* irq_happened before it re-enables interrupts, so setthe
|
|
||||||
* decrementer there instead of causing a hardware exception
|
|
||||||
* which would immediately hit the masked interrupt handler
|
|
||||||
* and have the net effect of setting the decrementer in
|
|
||||||
* irq_happened.
|
|
||||||
*
|
|
||||||
* NMI interrupts can not check this when they return, so the
|
|
||||||
* decrementer hardware exception is raised, which will fire
|
|
||||||
* when interrupts are next enabled.
|
|
||||||
*
|
|
||||||
* BookE does not support this yet, it must audit all NMI
|
|
||||||
* interrupt handlers to ensure they call nmi_enter() so this
|
|
||||||
* check would be correct.
|
|
||||||
*/
|
|
||||||
if (IS_ENABLED(CONFIG_BOOKE) || !irqs_disabled() || in_nmi()) {
|
|
||||||
set_dec(1);
|
|
||||||
} else {
|
|
||||||
hard_irq_disable();
|
|
||||||
local_paca->irq_happened |= PACA_IRQ_DEC;
|
|
||||||
}
|
|
||||||
preempt_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* 32-bit */
|
#else /* 32-bit */
|
||||||
|
|
||||||
DEFINE_PER_CPU(u8, irq_work_pending);
|
DEFINE_PER_CPU(u8, irq_work_pending);
|
||||||
|
@ -559,16 +530,27 @@ DEFINE_PER_CPU(u8, irq_work_pending);
|
||||||
#define test_irq_work_pending() __this_cpu_read(irq_work_pending)
|
#define test_irq_work_pending() __this_cpu_read(irq_work_pending)
|
||||||
#define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0)
|
#define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0)
|
||||||
|
|
||||||
|
#endif /* 32 vs 64 bit */
|
||||||
|
|
||||||
void arch_irq_work_raise(void)
|
void arch_irq_work_raise(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* 64-bit code that uses irq soft-mask can just cause an immediate
|
||||||
|
* interrupt here that gets soft masked, if this is called under
|
||||||
|
* local_irq_disable(). It might be possible to prevent that happening
|
||||||
|
* by noticing interrupts are disabled and setting decrementer pending
|
||||||
|
* to be replayed when irqs are enabled. The problem there is that
|
||||||
|
* tracing can call irq_work_raise, including in code that does low
|
||||||
|
* level manipulations of irq soft-mask state (e.g., trace_hardirqs_on)
|
||||||
|
* which could get tangled up if we're messing with the same state
|
||||||
|
* here.
|
||||||
|
*/
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
set_irq_work_pending_flag();
|
set_irq_work_pending_flag();
|
||||||
set_dec(1);
|
set_dec(1);
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* 32 vs 64 bit */
|
|
||||||
|
|
||||||
#else /* CONFIG_IRQ_WORK */
|
#else /* CONFIG_IRQ_WORK */
|
||||||
|
|
||||||
#define test_irq_work_pending() 0
|
#define test_irq_work_pending() 0
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
# Makefile for the linux kernel.
|
# Makefile for the linux kernel.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Avoid clang warnings around longjmp/setjmp declarations
|
|
||||||
CFLAGS_crash.o += -ffreestanding
|
|
||||||
|
|
||||||
obj-y += core.o crash.o core_$(BITS).o
|
obj-y += core.o crash.o core_$(BITS).o
|
||||||
|
|
||||||
obj-$(CONFIG_PPC32) += relocate_32.o
|
obj-$(CONFIG_PPC32) += relocate_32.o
|
||||||
|
|
|
@ -3616,6 +3616,7 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
|
||||||
if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested &&
|
if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested &&
|
||||||
kvmppc_get_gpr(vcpu, 3) == H_CEDE) {
|
kvmppc_get_gpr(vcpu, 3) == H_CEDE) {
|
||||||
kvmppc_nested_cede(vcpu);
|
kvmppc_nested_cede(vcpu);
|
||||||
|
kvmppc_set_gpr(vcpu, 3, 0);
|
||||||
trap = 0;
|
trap = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -806,6 +806,9 @@ out:
|
||||||
|
|
||||||
void kvmppc_uvmem_free(void)
|
void kvmppc_uvmem_free(void)
|
||||||
{
|
{
|
||||||
|
if (!kvmppc_uvmem_bitmap)
|
||||||
|
return;
|
||||||
|
|
||||||
memunmap_pages(&kvmppc_uvmem_pgmap);
|
memunmap_pages(&kvmppc_uvmem_pgmap);
|
||||||
release_mem_region(kvmppc_uvmem_pgmap.res.start,
|
release_mem_region(kvmppc_uvmem_pgmap.res.start,
|
||||||
resource_size(&kvmppc_uvmem_pgmap.res));
|
resource_size(&kvmppc_uvmem_pgmap.res));
|
||||||
|
|
|
@ -101,7 +101,7 @@ static void __init kasan_remap_early_shadow_ro(void)
|
||||||
|
|
||||||
kasan_populate_pte(kasan_early_shadow_pte, prot);
|
kasan_populate_pte(kasan_early_shadow_pte, prot);
|
||||||
|
|
||||||
for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) {
|
for (k_cur = k_start & PAGE_MASK; k_cur != k_end; k_cur += PAGE_SIZE) {
|
||||||
pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
|
pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
|
||||||
pte_t *ptep = pte_offset_kernel(pmd, k_cur);
|
pte_t *ptep = pte_offset_kernel(pmd, k_cur);
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,7 @@ void mmu_mark_initmem_nx(void)
|
||||||
mmu_mapin_ram_chunk(etext8, einittext8, PAGE_KERNEL);
|
mmu_mapin_ram_chunk(etext8, einittext8, PAGE_KERNEL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_tlbil_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_STRICT_KERNEL_RWX
|
#ifdef CONFIG_STRICT_KERNEL_RWX
|
||||||
|
@ -199,6 +200,8 @@ void mmu_mark_rodata_ro(void)
|
||||||
~(LARGE_PAGE_SIZE_8M - 1)));
|
~(LARGE_PAGE_SIZE_8M - 1)));
|
||||||
mmu_patch_addis(&patch__dtlbmiss_romem_top, -__pa(_sinittext));
|
mmu_patch_addis(&patch__dtlbmiss_romem_top, -__pa(_sinittext));
|
||||||
|
|
||||||
|
_tlbil_all();
|
||||||
|
|
||||||
/* Update page tables for PTDUMP and BDI */
|
/* Update page tables for PTDUMP and BDI */
|
||||||
mmu_mapin_ram_chunk(0, sinittext, __pgprot(0));
|
mmu_mapin_ram_chunk(0, sinittext, __pgprot(0));
|
||||||
mmu_mapin_ram_chunk(0, etext, PAGE_KERNEL_ROX);
|
mmu_mapin_ram_chunk(0, etext, PAGE_KERNEL_ROX);
|
||||||
|
|
|
@ -397,7 +397,7 @@ _GLOBAL(set_context)
|
||||||
* extern void loadcam_entry(unsigned int index)
|
* extern void loadcam_entry(unsigned int index)
|
||||||
*
|
*
|
||||||
* Load TLBCAM[index] entry in to the L2 CAM MMU
|
* Load TLBCAM[index] entry in to the L2 CAM MMU
|
||||||
* Must preserve r7, r8, r9, and r10
|
* Must preserve r7, r8, r9, r10 and r11
|
||||||
*/
|
*/
|
||||||
_GLOBAL(loadcam_entry)
|
_GLOBAL(loadcam_entry)
|
||||||
mflr r5
|
mflr r5
|
||||||
|
@ -433,6 +433,10 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
|
||||||
*/
|
*/
|
||||||
_GLOBAL(loadcam_multi)
|
_GLOBAL(loadcam_multi)
|
||||||
mflr r8
|
mflr r8
|
||||||
|
/* Don't switch to AS=1 if already there */
|
||||||
|
mfmsr r11
|
||||||
|
andi. r11,r11,MSR_IS
|
||||||
|
bne 10f
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up temporary TLB entry that is the same as what we're
|
* Set up temporary TLB entry that is the same as what we're
|
||||||
|
@ -458,6 +462,7 @@ _GLOBAL(loadcam_multi)
|
||||||
mtmsr r6
|
mtmsr r6
|
||||||
isync
|
isync
|
||||||
|
|
||||||
|
10:
|
||||||
mr r9,r3
|
mr r9,r3
|
||||||
add r10,r3,r4
|
add r10,r3,r4
|
||||||
2: bl loadcam_entry
|
2: bl loadcam_entry
|
||||||
|
@ -466,6 +471,10 @@ _GLOBAL(loadcam_multi)
|
||||||
mr r3,r9
|
mr r3,r9
|
||||||
blt 2b
|
blt 2b
|
||||||
|
|
||||||
|
/* Don't return to AS=0 if we were in AS=1 at function start */
|
||||||
|
andi. r11,r11,MSR_IS
|
||||||
|
bne 3f
|
||||||
|
|
||||||
/* Return to AS=0 and clear the temporary entry */
|
/* Return to AS=0 and clear the temporary entry */
|
||||||
mfmsr r6
|
mfmsr r6
|
||||||
rlwinm. r6,r6,0,~(MSR_IS|MSR_DS)
|
rlwinm. r6,r6,0,~(MSR_IS|MSR_DS)
|
||||||
|
@ -481,6 +490,7 @@ _GLOBAL(loadcam_multi)
|
||||||
tlbwe
|
tlbwe
|
||||||
isync
|
isync
|
||||||
|
|
||||||
|
3:
|
||||||
mtlr r8
|
mtlr r8
|
||||||
blr
|
blr
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -397,7 +397,7 @@ config PPC_KUAP
|
||||||
|
|
||||||
config PPC_KUAP_DEBUG
|
config PPC_KUAP_DEBUG
|
||||||
bool "Extra debugging for Kernel Userspace Access Protection"
|
bool "Extra debugging for Kernel Userspace Access Protection"
|
||||||
depends on PPC_HAVE_KUAP && (PPC_RADIX_MMU || PPC_32)
|
depends on PPC_KUAP && (PPC_RADIX_MMU || PPC32)
|
||||||
help
|
help
|
||||||
Add extra debugging for Kernel Userspace Access Protection (KUAP)
|
Add extra debugging for Kernel Userspace Access Protection (KUAP)
|
||||||
If you're unsure, say N.
|
If you're unsure, say N.
|
||||||
|
|
|
@ -291,23 +291,6 @@ static int __init maple_probe(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
define_machine(maple) {
|
|
||||||
.name = "Maple",
|
|
||||||
.probe = maple_probe,
|
|
||||||
.setup_arch = maple_setup_arch,
|
|
||||||
.init_IRQ = maple_init_IRQ,
|
|
||||||
.pci_irq_fixup = maple_pci_irq_fixup,
|
|
||||||
.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
|
|
||||||
.restart = maple_restart,
|
|
||||||
.halt = maple_halt,
|
|
||||||
.get_boot_time = maple_get_boot_time,
|
|
||||||
.set_rtc_time = maple_set_rtc_time,
|
|
||||||
.get_rtc_time = maple_get_rtc_time,
|
|
||||||
.calibrate_decr = generic_calibrate_decr,
|
|
||||||
.progress = maple_progress,
|
|
||||||
.power_save = power4_idle,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_EDAC
|
#ifdef CONFIG_EDAC
|
||||||
/*
|
/*
|
||||||
* Register a platform device for CPC925 memory controller on
|
* Register a platform device for CPC925 memory controller on
|
||||||
|
@ -364,3 +347,20 @@ static int __init maple_cpc925_edac_setup(void)
|
||||||
}
|
}
|
||||||
machine_device_initcall(maple, maple_cpc925_edac_setup);
|
machine_device_initcall(maple, maple_cpc925_edac_setup);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
define_machine(maple) {
|
||||||
|
.name = "Maple",
|
||||||
|
.probe = maple_probe,
|
||||||
|
.setup_arch = maple_setup_arch,
|
||||||
|
.init_IRQ = maple_init_IRQ,
|
||||||
|
.pci_irq_fixup = maple_pci_irq_fixup,
|
||||||
|
.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
|
||||||
|
.restart = maple_restart,
|
||||||
|
.halt = maple_halt,
|
||||||
|
.get_boot_time = maple_get_boot_time,
|
||||||
|
.set_rtc_time = maple_set_rtc_time,
|
||||||
|
.get_rtc_time = maple_get_rtc_time,
|
||||||
|
.calibrate_decr = generic_calibrate_decr,
|
||||||
|
.progress = maple_progress,
|
||||||
|
.power_save = power4_idle,
|
||||||
|
};
|
||||||
|
|
|
@ -223,7 +223,7 @@ static int get_lmb_range(u32 drc_index, int n_lmbs,
|
||||||
struct drmem_lmb **end_lmb)
|
struct drmem_lmb **end_lmb)
|
||||||
{
|
{
|
||||||
struct drmem_lmb *lmb, *start, *end;
|
struct drmem_lmb *lmb, *start, *end;
|
||||||
struct drmem_lmb *last_lmb;
|
struct drmem_lmb *limit;
|
||||||
|
|
||||||
start = NULL;
|
start = NULL;
|
||||||
for_each_drmem_lmb(lmb) {
|
for_each_drmem_lmb(lmb) {
|
||||||
|
@ -236,10 +236,10 @@ static int get_lmb_range(u32 drc_index, int n_lmbs,
|
||||||
if (!start)
|
if (!start)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
end = &start[n_lmbs - 1];
|
end = &start[n_lmbs];
|
||||||
|
|
||||||
last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1];
|
limit = &drmem_info->lmbs[drmem_info->n_lmbs];
|
||||||
if (end > last_lmb)
|
if (end > limit)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*start_lmb = start;
|
*start_lmb = start;
|
||||||
|
|
|
@ -683,6 +683,17 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
/*
|
||||||
|
* Enable translation as we will be accessing per-cpu variables
|
||||||
|
* in save_mce_event() which may fall outside RMO region, also
|
||||||
|
* leave it enabled because subsequently we will be queuing work
|
||||||
|
* to workqueues where again per-cpu variables accessed, besides
|
||||||
|
* fwnmi_release_errinfo() crashes when called in realmode on
|
||||||
|
* pseries.
|
||||||
|
* Note: All the realmode handling like flushing SLB entries for
|
||||||
|
* SLB multihit is done by now.
|
||||||
|
*/
|
||||||
|
mtmsr(mfmsr() | MSR_IR | MSR_DR);
|
||||||
save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED,
|
save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED,
|
||||||
&mce_err, regs->nip, eaddr, paddr);
|
&mce_err, regs->nip, eaddr, paddr);
|
||||||
|
|
||||||
|
|
|
@ -68,13 +68,6 @@ static u32 xive_ipi_irq;
|
||||||
/* Xive state for each CPU */
|
/* Xive state for each CPU */
|
||||||
static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu);
|
static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu);
|
||||||
|
|
||||||
/*
|
|
||||||
* A "disabled" interrupt should never fire, to catch problems
|
|
||||||
* we set its logical number to this
|
|
||||||
*/
|
|
||||||
#define XIVE_BAD_IRQ 0x7fffffff
|
|
||||||
#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1)
|
|
||||||
|
|
||||||
/* An invalid CPU target */
|
/* An invalid CPU target */
|
||||||
#define XIVE_INVALID_TARGET (-1)
|
#define XIVE_INVALID_TARGET (-1)
|
||||||
|
|
||||||
|
@ -265,11 +258,15 @@ notrace void xmon_xive_do_dump(int cpu)
|
||||||
|
|
||||||
int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d)
|
int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d)
|
||||||
{
|
{
|
||||||
|
struct irq_chip *chip = irq_data_get_irq_chip(d);
|
||||||
int rc;
|
int rc;
|
||||||
u32 target;
|
u32 target;
|
||||||
u8 prio;
|
u8 prio;
|
||||||
u32 lirq;
|
u32 lirq;
|
||||||
|
|
||||||
|
if (!is_xive_irq(chip))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq);
|
rc = xive_ops->get_irq_config(hw_irq, &target, &prio, &lirq);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
xmon_printf("IRQ 0x%08x : no config rc=%d\n", hw_irq, rc);
|
xmon_printf("IRQ 0x%08x : no config rc=%d\n", hw_irq, rc);
|
||||||
|
@ -1150,7 +1147,7 @@ static int xive_setup_cpu_ipi(unsigned int cpu)
|
||||||
xc = per_cpu(xive_cpu, cpu);
|
xc = per_cpu(xive_cpu, cpu);
|
||||||
|
|
||||||
/* Check if we are already setup */
|
/* Check if we are already setup */
|
||||||
if (xc->hw_ipi != 0)
|
if (xc->hw_ipi != XIVE_BAD_IRQ)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Grab an IPI from the backend, this will populate xc->hw_ipi */
|
/* Grab an IPI from the backend, this will populate xc->hw_ipi */
|
||||||
|
@ -1187,7 +1184,7 @@ static void xive_cleanup_cpu_ipi(unsigned int cpu, struct xive_cpu *xc)
|
||||||
/* Disable the IPI and free the IRQ data */
|
/* Disable the IPI and free the IRQ data */
|
||||||
|
|
||||||
/* Already cleaned up ? */
|
/* Already cleaned up ? */
|
||||||
if (xc->hw_ipi == 0)
|
if (xc->hw_ipi == XIVE_BAD_IRQ)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Mask the IPI */
|
/* Mask the IPI */
|
||||||
|
@ -1343,6 +1340,7 @@ static int xive_prepare_cpu(unsigned int cpu)
|
||||||
if (np)
|
if (np)
|
||||||
xc->chip_id = of_get_ibm_chip_id(np);
|
xc->chip_id = of_get_ibm_chip_id(np);
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
|
xc->hw_ipi = XIVE_BAD_IRQ;
|
||||||
|
|
||||||
per_cpu(xive_cpu, cpu) = xc;
|
per_cpu(xive_cpu, cpu) = xc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc)
|
||||||
s64 rc;
|
s64 rc;
|
||||||
|
|
||||||
/* Free the IPI */
|
/* Free the IPI */
|
||||||
if (!xc->hw_ipi)
|
if (xc->hw_ipi == XIVE_BAD_IRQ)
|
||||||
return;
|
return;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
rc = opal_xive_free_irq(xc->hw_ipi);
|
rc = opal_xive_free_irq(xc->hw_ipi);
|
||||||
|
@ -320,7 +320,7 @@ static void xive_native_put_ipi(unsigned int cpu, struct xive_cpu *xc)
|
||||||
msleep(OPAL_BUSY_DELAY_MS);
|
msleep(OPAL_BUSY_DELAY_MS);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
xc->hw_ipi = 0;
|
xc->hw_ipi = XIVE_BAD_IRQ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -560,11 +560,11 @@ static int xive_spapr_get_ipi(unsigned int cpu, struct xive_cpu *xc)
|
||||||
|
|
||||||
static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc)
|
static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc)
|
||||||
{
|
{
|
||||||
if (!xc->hw_ipi)
|
if (xc->hw_ipi == XIVE_BAD_IRQ)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xive_irq_bitmap_free(xc->hw_ipi);
|
xive_irq_bitmap_free(xc->hw_ipi);
|
||||||
xc->hw_ipi = 0;
|
xc->hw_ipi = XIVE_BAD_IRQ;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
#ifndef __XIVE_INTERNAL_H
|
#ifndef __XIVE_INTERNAL_H
|
||||||
#define __XIVE_INTERNAL_H
|
#define __XIVE_INTERNAL_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A "disabled" interrupt should never fire, to catch problems
|
||||||
|
* we set its logical number to this
|
||||||
|
*/
|
||||||
|
#define XIVE_BAD_IRQ 0x7fffffff
|
||||||
|
#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1)
|
||||||
|
|
||||||
/* Each CPU carry one of these with various per-CPU state */
|
/* Each CPU carry one of these with various per-CPU state */
|
||||||
struct xive_cpu {
|
struct xive_cpu {
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Makefile for xmon
|
# Makefile for xmon
|
||||||
|
|
||||||
# Avoid clang warnings around longjmp/setjmp declarations
|
|
||||||
subdir-ccflags-y := -ffreestanding
|
|
||||||
|
|
||||||
GCOV_PROFILE := n
|
GCOV_PROFILE := n
|
||||||
KCOV_INSTRUMENT := n
|
KCOV_INSTRUMENT := n
|
||||||
UBSAN_SANITIZE := n
|
UBSAN_SANITIZE := n
|
||||||
|
|
|
@ -342,6 +342,7 @@ static int cbc_aes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
memcpy(walk.iv, param.iv, AES_BLOCK_SIZE);
|
memcpy(walk.iv, param.iv, AES_BLOCK_SIZE);
|
||||||
ret = skcipher_walk_done(&walk, nbytes - n);
|
ret = skcipher_walk_done(&walk, nbytes - n);
|
||||||
}
|
}
|
||||||
|
memzero_explicit(¶m, sizeof(param));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,6 +471,8 @@ static int xts_aes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
walk.dst.virt.addr, walk.src.virt.addr, n);
|
walk.dst.virt.addr, walk.src.virt.addr, n);
|
||||||
ret = skcipher_walk_done(&walk, nbytes - n);
|
ret = skcipher_walk_done(&walk, nbytes - n);
|
||||||
}
|
}
|
||||||
|
memzero_explicit(&pcc_param, sizeof(pcc_param));
|
||||||
|
memzero_explicit(&xts_param, sizeof(xts_param));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,9 @@ struct lowcore {
|
||||||
|
|
||||||
/* br %r1 trampoline */
|
/* br %r1 trampoline */
|
||||||
__u16 br_r1_trampoline; /* 0x0400 */
|
__u16 br_r1_trampoline; /* 0x0400 */
|
||||||
__u8 pad_0x0402[0x0e00-0x0402]; /* 0x0402 */
|
__u32 return_lpswe; /* 0x0402 */
|
||||||
|
__u32 return_mcck_lpswe; /* 0x0406 */
|
||||||
|
__u8 pad_0x040a[0x0e00-0x040a]; /* 0x040a */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0xe00 contains the address of the IPL Parameter Information
|
* 0xe00 contains the address of the IPL Parameter Information
|
||||||
|
|
|
@ -161,6 +161,7 @@ typedef struct thread_struct thread_struct;
|
||||||
#define INIT_THREAD { \
|
#define INIT_THREAD { \
|
||||||
.ksp = sizeof(init_stack) + (unsigned long) &init_stack, \
|
.ksp = sizeof(init_stack) + (unsigned long) &init_stack, \
|
||||||
.fpu.regs = (void *) init_task.thread.fpu.fprs, \
|
.fpu.regs = (void *) init_task.thread.fpu.fprs, \
|
||||||
|
.last_break = 1, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <linux/bits.h>
|
#include <linux/bits.h>
|
||||||
#include <uapi/asm/setup.h>
|
#include <uapi/asm/setup.h>
|
||||||
|
#include <linux/build_bug.h>
|
||||||
|
|
||||||
#define EP_OFFSET 0x10008
|
#define EP_OFFSET 0x10008
|
||||||
#define EP_STRING "S390EP"
|
#define EP_STRING "S390EP"
|
||||||
|
@ -162,6 +163,12 @@ static inline unsigned long kaslr_offset(void)
|
||||||
return __kaslr_offset;
|
return __kaslr_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 gen_lpswe(unsigned long addr)
|
||||||
|
{
|
||||||
|
BUILD_BUG_ON(addr > 0xfff);
|
||||||
|
return 0xb2b20000 | addr;
|
||||||
|
}
|
||||||
|
|
||||||
#else /* __ASSEMBLY__ */
|
#else /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#define IPL_DEVICE (IPL_DEVICE_OFFSET)
|
#define IPL_DEVICE (IPL_DEVICE_OFFSET)
|
||||||
|
|
|
@ -124,6 +124,8 @@ int main(void)
|
||||||
OFFSET(__LC_EXT_DAMAGE_CODE, lowcore, external_damage_code);
|
OFFSET(__LC_EXT_DAMAGE_CODE, lowcore, external_damage_code);
|
||||||
OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address);
|
OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address);
|
||||||
OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr);
|
OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr);
|
||||||
|
OFFSET(__LC_RETURN_LPSWE, lowcore, return_lpswe);
|
||||||
|
OFFSET(__LC_RETURN_MCCK_LPSWE, lowcore, return_mcck_lpswe);
|
||||||
OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw);
|
OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw);
|
||||||
OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw);
|
OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw);
|
||||||
OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw);
|
OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw);
|
||||||
|
|
|
@ -84,7 +84,7 @@ static int show_diag_stat(struct seq_file *m, void *v)
|
||||||
|
|
||||||
static void *show_diag_stat_start(struct seq_file *m, loff_t *pos)
|
static void *show_diag_stat_start(struct seq_file *m, loff_t *pos)
|
||||||
{
|
{
|
||||||
return *pos <= nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL;
|
return *pos <= NR_DIAG_STAT ? (void *)((unsigned long) *pos + 1) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *show_diag_stat_next(struct seq_file *m, void *v, loff_t *pos)
|
static void *show_diag_stat_next(struct seq_file *m, void *v, loff_t *pos)
|
||||||
|
@ -133,7 +133,7 @@ void diag_stat_inc(enum diag_stat_enum nr)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(diag_stat_inc);
|
EXPORT_SYMBOL(diag_stat_inc);
|
||||||
|
|
||||||
void diag_stat_inc_norecursion(enum diag_stat_enum nr)
|
void notrace diag_stat_inc_norecursion(enum diag_stat_enum nr)
|
||||||
{
|
{
|
||||||
this_cpu_inc(diag_stat.counter[nr]);
|
this_cpu_inc(diag_stat.counter[nr]);
|
||||||
trace_s390_diagnose_norecursion(diag_map[nr].code);
|
trace_s390_diagnose_norecursion(diag_map[nr].code);
|
||||||
|
|
|
@ -115,26 +115,29 @@ _LPP_OFFSET = __LC_LPP
|
||||||
|
|
||||||
.macro SWITCH_ASYNC savearea,timer
|
.macro SWITCH_ASYNC savearea,timer
|
||||||
tmhh %r8,0x0001 # interrupting from user ?
|
tmhh %r8,0x0001 # interrupting from user ?
|
||||||
jnz 1f
|
jnz 2f
|
||||||
lgr %r14,%r9
|
lgr %r14,%r9
|
||||||
|
cghi %r14,__LC_RETURN_LPSWE
|
||||||
|
je 0f
|
||||||
slg %r14,BASED(.Lcritical_start)
|
slg %r14,BASED(.Lcritical_start)
|
||||||
clg %r14,BASED(.Lcritical_length)
|
clg %r14,BASED(.Lcritical_length)
|
||||||
jhe 0f
|
jhe 1f
|
||||||
|
0:
|
||||||
lghi %r11,\savearea # inside critical section, do cleanup
|
lghi %r11,\savearea # inside critical section, do cleanup
|
||||||
brasl %r14,cleanup_critical
|
brasl %r14,cleanup_critical
|
||||||
tmhh %r8,0x0001 # retest problem state after cleanup
|
tmhh %r8,0x0001 # retest problem state after cleanup
|
||||||
jnz 1f
|
jnz 2f
|
||||||
0: lg %r14,__LC_ASYNC_STACK # are we already on the target stack?
|
1: lg %r14,__LC_ASYNC_STACK # are we already on the target stack?
|
||||||
slgr %r14,%r15
|
slgr %r14,%r15
|
||||||
srag %r14,%r14,STACK_SHIFT
|
srag %r14,%r14,STACK_SHIFT
|
||||||
jnz 2f
|
jnz 3f
|
||||||
CHECK_STACK \savearea
|
CHECK_STACK \savearea
|
||||||
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
|
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
|
||||||
j 3f
|
j 4f
|
||||||
1: UPDATE_VTIME %r14,%r15,\timer
|
2: UPDATE_VTIME %r14,%r15,\timer
|
||||||
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
|
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
|
||||||
2: lg %r15,__LC_ASYNC_STACK # load async stack
|
3: lg %r15,__LC_ASYNC_STACK # load async stack
|
||||||
3: la %r11,STACK_FRAME_OVERHEAD(%r15)
|
4: la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro UPDATE_VTIME w1,w2,enter_timer
|
.macro UPDATE_VTIME w1,w2,enter_timer
|
||||||
|
@ -401,7 +404,7 @@ ENTRY(system_call)
|
||||||
stpt __LC_EXIT_TIMER
|
stpt __LC_EXIT_TIMER
|
||||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||||
lmg %r11,%r15,__PT_R11(%r11)
|
lmg %r11,%r15,__PT_R11(%r11)
|
||||||
lpswe __LC_RETURN_PSW
|
b __LC_RETURN_LPSWE(%r0)
|
||||||
.Lsysc_done:
|
.Lsysc_done:
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -608,43 +611,50 @@ ENTRY(pgm_check_handler)
|
||||||
BPOFF
|
BPOFF
|
||||||
stmg %r8,%r15,__LC_SAVE_AREA_SYNC
|
stmg %r8,%r15,__LC_SAVE_AREA_SYNC
|
||||||
lg %r10,__LC_LAST_BREAK
|
lg %r10,__LC_LAST_BREAK
|
||||||
lg %r12,__LC_CURRENT
|
srag %r11,%r10,12
|
||||||
|
jnz 0f
|
||||||
|
/* if __LC_LAST_BREAK is < 4096, it contains one of
|
||||||
|
* the lpswe addresses in lowcore. Set it to 1 (initial state)
|
||||||
|
* to prevent leaking that address to userspace.
|
||||||
|
*/
|
||||||
|
lghi %r10,1
|
||||||
|
0: lg %r12,__LC_CURRENT
|
||||||
lghi %r11,0
|
lghi %r11,0
|
||||||
larl %r13,cleanup_critical
|
larl %r13,cleanup_critical
|
||||||
lmg %r8,%r9,__LC_PGM_OLD_PSW
|
lmg %r8,%r9,__LC_PGM_OLD_PSW
|
||||||
tmhh %r8,0x0001 # test problem state bit
|
tmhh %r8,0x0001 # test problem state bit
|
||||||
jnz 2f # -> fault in user space
|
jnz 3f # -> fault in user space
|
||||||
#if IS_ENABLED(CONFIG_KVM)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
# cleanup critical section for program checks in sie64a
|
# cleanup critical section for program checks in sie64a
|
||||||
lgr %r14,%r9
|
lgr %r14,%r9
|
||||||
slg %r14,BASED(.Lsie_critical_start)
|
slg %r14,BASED(.Lsie_critical_start)
|
||||||
clg %r14,BASED(.Lsie_critical_length)
|
clg %r14,BASED(.Lsie_critical_length)
|
||||||
jhe 0f
|
jhe 1f
|
||||||
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
|
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
|
||||||
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
|
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
|
||||||
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
|
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
|
||||||
larl %r9,sie_exit # skip forward to sie_exit
|
larl %r9,sie_exit # skip forward to sie_exit
|
||||||
lghi %r11,_PIF_GUEST_FAULT
|
lghi %r11,_PIF_GUEST_FAULT
|
||||||
#endif
|
#endif
|
||||||
0: tmhh %r8,0x4000 # PER bit set in old PSW ?
|
1: tmhh %r8,0x4000 # PER bit set in old PSW ?
|
||||||
jnz 1f # -> enabled, can't be a double fault
|
jnz 2f # -> enabled, can't be a double fault
|
||||||
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
||||||
jnz .Lpgm_svcper # -> single stepped svc
|
jnz .Lpgm_svcper # -> single stepped svc
|
||||||
1: CHECK_STACK __LC_SAVE_AREA_SYNC
|
2: CHECK_STACK __LC_SAVE_AREA_SYNC
|
||||||
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
|
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
|
||||||
# CHECK_VMAP_STACK branches to stack_overflow or 4f
|
# CHECK_VMAP_STACK branches to stack_overflow or 5f
|
||||||
CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
|
CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,5f
|
||||||
2: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
|
3: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
|
||||||
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
|
BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
|
||||||
lg %r15,__LC_KERNEL_STACK
|
lg %r15,__LC_KERNEL_STACK
|
||||||
lgr %r14,%r12
|
lgr %r14,%r12
|
||||||
aghi %r14,__TASK_thread # pointer to thread_struct
|
aghi %r14,__TASK_thread # pointer to thread_struct
|
||||||
lghi %r13,__LC_PGM_TDB
|
lghi %r13,__LC_PGM_TDB
|
||||||
tm __LC_PGM_ILC+2,0x02 # check for transaction abort
|
tm __LC_PGM_ILC+2,0x02 # check for transaction abort
|
||||||
jz 3f
|
jz 4f
|
||||||
mvc __THREAD_trap_tdb(256,%r14),0(%r13)
|
mvc __THREAD_trap_tdb(256,%r14),0(%r13)
|
||||||
3: stg %r10,__THREAD_last_break(%r14)
|
4: stg %r10,__THREAD_last_break(%r14)
|
||||||
4: lgr %r13,%r11
|
5: lgr %r13,%r11
|
||||||
la %r11,STACK_FRAME_OVERHEAD(%r15)
|
la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||||
stmg %r0,%r7,__PT_R0(%r11)
|
stmg %r0,%r7,__PT_R0(%r11)
|
||||||
# clear user controlled registers to prevent speculative use
|
# clear user controlled registers to prevent speculative use
|
||||||
|
@ -663,14 +673,14 @@ ENTRY(pgm_check_handler)
|
||||||
stg %r13,__PT_FLAGS(%r11)
|
stg %r13,__PT_FLAGS(%r11)
|
||||||
stg %r10,__PT_ARGS(%r11)
|
stg %r10,__PT_ARGS(%r11)
|
||||||
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
||||||
jz 5f
|
jz 6f
|
||||||
tmhh %r8,0x0001 # kernel per event ?
|
tmhh %r8,0x0001 # kernel per event ?
|
||||||
jz .Lpgm_kprobe
|
jz .Lpgm_kprobe
|
||||||
oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP
|
oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP
|
||||||
mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
|
mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE
|
mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE
|
||||||
mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
|
mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
|
||||||
5: REENABLE_IRQS
|
6: REENABLE_IRQS
|
||||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||||
larl %r1,pgm_check_table
|
larl %r1,pgm_check_table
|
||||||
llgh %r10,__PT_INT_CODE+2(%r11)
|
llgh %r10,__PT_INT_CODE+2(%r11)
|
||||||
|
@ -775,7 +785,7 @@ ENTRY(io_int_handler)
|
||||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||||
.Lio_exit_kernel:
|
.Lio_exit_kernel:
|
||||||
lmg %r11,%r15,__PT_R11(%r11)
|
lmg %r11,%r15,__PT_R11(%r11)
|
||||||
lpswe __LC_RETURN_PSW
|
b __LC_RETURN_LPSWE(%r0)
|
||||||
.Lio_done:
|
.Lio_done:
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1214,7 +1224,7 @@ ENTRY(mcck_int_handler)
|
||||||
stpt __LC_EXIT_TIMER
|
stpt __LC_EXIT_TIMER
|
||||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||||
0: lmg %r11,%r15,__PT_R11(%r11)
|
0: lmg %r11,%r15,__PT_R11(%r11)
|
||||||
lpswe __LC_RETURN_MCCK_PSW
|
b __LC_RETURN_MCCK_LPSWE
|
||||||
|
|
||||||
.Lmcck_panic:
|
.Lmcck_panic:
|
||||||
lg %r15,__LC_NODAT_STACK
|
lg %r15,__LC_NODAT_STACK
|
||||||
|
@ -1271,6 +1281,8 @@ ENDPROC(stack_overflow)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(cleanup_critical)
|
ENTRY(cleanup_critical)
|
||||||
|
cghi %r9,__LC_RETURN_LPSWE
|
||||||
|
je .Lcleanup_lpswe
|
||||||
#if IS_ENABLED(CONFIG_KVM)
|
#if IS_ENABLED(CONFIG_KVM)
|
||||||
clg %r9,BASED(.Lcleanup_table_sie) # .Lsie_gmap
|
clg %r9,BASED(.Lcleanup_table_sie) # .Lsie_gmap
|
||||||
jl 0f
|
jl 0f
|
||||||
|
@ -1424,6 +1436,7 @@ ENDPROC(cleanup_critical)
|
||||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
||||||
mvc 0(64,%r11),__PT_R8(%r9)
|
mvc 0(64,%r11),__PT_R8(%r9)
|
||||||
lmg %r0,%r7,__PT_R0(%r9)
|
lmg %r0,%r7,__PT_R0(%r9)
|
||||||
|
.Lcleanup_lpswe:
|
||||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||||
BR_EX %r14,%r11
|
BR_EX %r14,%r11
|
||||||
.Lcleanup_sysc_restore_insn:
|
.Lcleanup_sysc_restore_insn:
|
||||||
|
|
|
@ -1576,6 +1576,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
|
||||||
unsigned long range = 0, size;
|
unsigned long range = 0, size;
|
||||||
unsigned long long overflow = 0;
|
unsigned long long overflow = 0;
|
||||||
struct perf_output_handle *handle = &cpuhw->handle;
|
struct perf_output_handle *handle = &cpuhw->handle;
|
||||||
|
unsigned long num_sdb;
|
||||||
|
|
||||||
aux = perf_get_aux(handle);
|
aux = perf_get_aux(handle);
|
||||||
if (WARN_ON_ONCE(!aux))
|
if (WARN_ON_ONCE(!aux))
|
||||||
|
@ -1587,13 +1588,14 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
|
||||||
size >> PAGE_SHIFT);
|
size >> PAGE_SHIFT);
|
||||||
perf_aux_output_end(handle, size);
|
perf_aux_output_end(handle, size);
|
||||||
|
|
||||||
|
num_sdb = aux->sfb.num_sdb;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
/* Get an output handle */
|
/* Get an output handle */
|
||||||
aux = perf_aux_output_begin(handle, cpuhw->event);
|
aux = perf_aux_output_begin(handle, cpuhw->event);
|
||||||
if (handle->size == 0) {
|
if (handle->size == 0) {
|
||||||
pr_err("The AUX buffer with %lu pages for the "
|
pr_err("The AUX buffer with %lu pages for the "
|
||||||
"diagnostic-sampling mode is full\n",
|
"diagnostic-sampling mode is full\n",
|
||||||
aux->sfb.num_sdb);
|
num_sdb);
|
||||||
debug_sprintf_event(sfdbg, 1,
|
debug_sprintf_event(sfdbg, 1,
|
||||||
"%s: AUX buffer used up\n",
|
"%s: AUX buffer used up\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
|
|
@ -106,6 +106,7 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long new_stackp,
|
||||||
p->thread.system_timer = 0;
|
p->thread.system_timer = 0;
|
||||||
p->thread.hardirq_timer = 0;
|
p->thread.hardirq_timer = 0;
|
||||||
p->thread.softirq_timer = 0;
|
p->thread.softirq_timer = 0;
|
||||||
|
p->thread.last_break = 1;
|
||||||
|
|
||||||
frame->sf.back_chain = 0;
|
frame->sf.back_chain = 0;
|
||||||
/* new return point is ret_from_fork */
|
/* new return point is ret_from_fork */
|
||||||
|
|
|
@ -165,8 +165,9 @@ static void show_cpu_mhz(struct seq_file *m, unsigned long n)
|
||||||
static int show_cpuinfo(struct seq_file *m, void *v)
|
static int show_cpuinfo(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
unsigned long n = (unsigned long) v - 1;
|
unsigned long n = (unsigned long) v - 1;
|
||||||
|
unsigned long first = cpumask_first(cpu_online_mask);
|
||||||
|
|
||||||
if (!n)
|
if (n == first)
|
||||||
show_cpu_summary(m, v);
|
show_cpu_summary(m, v);
|
||||||
if (!machine_has_cpu_mhz)
|
if (!machine_has_cpu_mhz)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -179,6 +180,8 @@ static inline void *c_update(loff_t *pos)
|
||||||
{
|
{
|
||||||
if (*pos)
|
if (*pos)
|
||||||
*pos = cpumask_next(*pos - 1, cpu_online_mask);
|
*pos = cpumask_next(*pos - 1, cpu_online_mask);
|
||||||
|
else
|
||||||
|
*pos = cpumask_first(cpu_online_mask);
|
||||||
return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL;
|
return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
#include <asm/nospec-branch.h>
|
#include <asm/nospec-branch.h>
|
||||||
#include <asm/mem_detect.h>
|
#include <asm/mem_detect.h>
|
||||||
#include <asm/uv.h>
|
#include <asm/uv.h>
|
||||||
|
#include <asm/asm-offsets.h>
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -450,6 +451,8 @@ static void __init setup_lowcore_dat_off(void)
|
||||||
lc->spinlock_index = 0;
|
lc->spinlock_index = 0;
|
||||||
arch_spin_lock_setup(0);
|
arch_spin_lock_setup(0);
|
||||||
lc->br_r1_trampoline = 0x07f1; /* br %r1 */
|
lc->br_r1_trampoline = 0x07f1; /* br %r1 */
|
||||||
|
lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW);
|
||||||
|
lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW);
|
||||||
|
|
||||||
set_prefix((u32)(unsigned long) lc);
|
set_prefix((u32)(unsigned long) lc);
|
||||||
lowcore_ptr[0] = lc;
|
lowcore_ptr[0] = lc;
|
||||||
|
|
|
@ -212,6 +212,8 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
|
||||||
lc->spinlock_lockval = arch_spin_lockval(cpu);
|
lc->spinlock_lockval = arch_spin_lockval(cpu);
|
||||||
lc->spinlock_index = 0;
|
lc->spinlock_index = 0;
|
||||||
lc->br_r1_trampoline = 0x07f1; /* br %r1 */
|
lc->br_r1_trampoline = 0x07f1; /* br %r1 */
|
||||||
|
lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW);
|
||||||
|
lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW);
|
||||||
if (nmi_alloc_per_cpu(lc))
|
if (nmi_alloc_per_cpu(lc))
|
||||||
goto out_async;
|
goto out_async;
|
||||||
if (vdso_alloc_per_cpu(lc))
|
if (vdso_alloc_per_cpu(lc))
|
||||||
|
@ -401,7 +403,7 @@ int smp_find_processor_id(u16 address)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool arch_vcpu_is_preempted(int cpu)
|
bool notrace arch_vcpu_is_preempted(int cpu)
|
||||||
{
|
{
|
||||||
if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
|
if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
|
||||||
return false;
|
return false;
|
||||||
|
@ -411,7 +413,7 @@ bool arch_vcpu_is_preempted(int cpu)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(arch_vcpu_is_preempted);
|
EXPORT_SYMBOL(arch_vcpu_is_preempted);
|
||||||
|
|
||||||
void smp_yield_cpu(int cpu)
|
void notrace smp_yield_cpu(int cpu)
|
||||||
{
|
{
|
||||||
if (!MACHINE_HAS_DIAG9C)
|
if (!MACHINE_HAS_DIAG9C)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -14,7 +14,7 @@ EXPORT_TRACEPOINT_SYMBOL(s390_diagnose);
|
||||||
|
|
||||||
static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
|
static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
|
||||||
|
|
||||||
void trace_s390_diagnose_norecursion(int diag_nr)
|
void notrace trace_s390_diagnose_norecursion(int diag_nr)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int *depth;
|
unsigned int *depth;
|
||||||
|
|
|
@ -1930,6 +1930,9 @@ static int gfn_to_memslot_approx(struct kvm_memslots *slots, gfn_t gfn)
|
||||||
start = slot + 1;
|
start = slot + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (start >= slots->used_slots)
|
||||||
|
return slots->used_slots - 1;
|
||||||
|
|
||||||
if (gfn >= memslots[start].base_gfn &&
|
if (gfn >= memslots[start].base_gfn &&
|
||||||
gfn < memslots[start].base_gfn + memslots[start].npages) {
|
gfn < memslots[start].base_gfn + memslots[start].npages) {
|
||||||
atomic_set(&slots->lru_slot, start);
|
atomic_set(&slots->lru_slot, start);
|
||||||
|
|
|
@ -1202,6 +1202,7 @@ static int vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
||||||
scb_s->iprcc = PGM_ADDRESSING;
|
scb_s->iprcc = PGM_ADDRESSING;
|
||||||
scb_s->pgmilc = 4;
|
scb_s->pgmilc = 4;
|
||||||
scb_s->gpsw.addr = __rewind_psw(scb_s->gpsw, 4);
|
scb_s->gpsw.addr = __rewind_psw(scb_s->gpsw, 4);
|
||||||
|
rc = 1;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void)
|
||||||
{
|
{
|
||||||
mm_segment_t old_fs;
|
mm_segment_t old_fs;
|
||||||
unsigned long asce, cr;
|
unsigned long asce, cr;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
old_fs = current->thread.mm_segment;
|
old_fs = current->thread.mm_segment;
|
||||||
if (old_fs & 1)
|
if (old_fs & 1)
|
||||||
return old_fs;
|
return old_fs;
|
||||||
|
/* protect against a concurrent page table upgrade */
|
||||||
|
local_irq_save(flags);
|
||||||
current->thread.mm_segment |= 1;
|
current->thread.mm_segment |= 1;
|
||||||
asce = S390_lowcore.kernel_asce;
|
asce = S390_lowcore.kernel_asce;
|
||||||
if (likely(old_fs == USER_DS)) {
|
if (likely(old_fs == USER_DS)) {
|
||||||
|
@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void)
|
||||||
__ctl_load(asce, 7, 7);
|
__ctl_load(asce, 7, 7);
|
||||||
set_cpu_flag(CIF_ASCE_SECONDARY);
|
set_cpu_flag(CIF_ASCE_SECONDARY);
|
||||||
}
|
}
|
||||||
|
local_irq_restore(flags);
|
||||||
return old_fs;
|
return old_fs;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(enable_sacf_uaccess);
|
EXPORT_SYMBOL(enable_sacf_uaccess);
|
||||||
|
|
|
@ -787,14 +787,18 @@ static void gmap_call_notifier(struct gmap *gmap, unsigned long start,
|
||||||
static inline unsigned long *gmap_table_walk(struct gmap *gmap,
|
static inline unsigned long *gmap_table_walk(struct gmap *gmap,
|
||||||
unsigned long gaddr, int level)
|
unsigned long gaddr, int level)
|
||||||
{
|
{
|
||||||
|
const int asce_type = gmap->asce & _ASCE_TYPE_MASK;
|
||||||
unsigned long *table;
|
unsigned long *table;
|
||||||
|
|
||||||
if ((gmap->asce & _ASCE_TYPE_MASK) + 4 < (level * 4))
|
if ((gmap->asce & _ASCE_TYPE_MASK) + 4 < (level * 4))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (gmap_is_shadow(gmap) && gmap->removed)
|
if (gmap_is_shadow(gmap) && gmap->removed)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (gaddr & (-1UL << (31 + ((gmap->asce & _ASCE_TYPE_MASK) >> 2)*11)))
|
|
||||||
|
if (asce_type != _ASCE_TYPE_REGION1 &&
|
||||||
|
gaddr & (-1UL << (31 + (asce_type >> 2) * 11)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
table = gmap->table;
|
table = gmap->table;
|
||||||
switch (gmap->asce & _ASCE_TYPE_MASK) {
|
switch (gmap->asce & _ASCE_TYPE_MASK) {
|
||||||
case _ASCE_TYPE_REGION1:
|
case _ASCE_TYPE_REGION1:
|
||||||
|
@ -1840,6 +1844,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t,
|
||||||
goto out_free;
|
goto out_free;
|
||||||
} else if (*table & _REGION_ENTRY_ORIGIN) {
|
} else if (*table & _REGION_ENTRY_ORIGIN) {
|
||||||
rc = -EAGAIN; /* Race with shadow */
|
rc = -EAGAIN; /* Race with shadow */
|
||||||
|
goto out_free;
|
||||||
}
|
}
|
||||||
crst_table_init(s_r3t, _REGION3_ENTRY_EMPTY);
|
crst_table_init(s_r3t, _REGION3_ENTRY_EMPTY);
|
||||||
/* mark as invalid as long as the parent table is not protected */
|
/* mark as invalid as long as the parent table is not protected */
|
||||||
|
|
|
@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg)
|
||||||
{
|
{
|
||||||
struct mm_struct *mm = arg;
|
struct mm_struct *mm = arg;
|
||||||
|
|
||||||
if (current->active_mm == mm)
|
/* we must change all active ASCEs to avoid the creation of new TLBs */
|
||||||
set_user_asce(mm);
|
if (current->active_mm == mm) {
|
||||||
|
S390_lowcore.user_asce = mm->context.asce;
|
||||||
|
if (current->thread.mm_segment == USER_DS) {
|
||||||
|
__ctl_load(S390_lowcore.user_asce, 1, 1);
|
||||||
|
/* Mark user-ASCE present in CR1 */
|
||||||
|
clear_cpu_flag(CIF_ASCE_PRIMARY);
|
||||||
|
}
|
||||||
|
if (current->thread.mm_segment == USER_DS_SACF) {
|
||||||
|
__ctl_load(S390_lowcore.user_asce, 7, 7);
|
||||||
|
/* enable_sacf_uaccess does all or nothing */
|
||||||
|
WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY));
|
||||||
|
}
|
||||||
|
}
|
||||||
__tlb_flush_local();
|
__tlb_flush_local();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -415,6 +415,10 @@ void __init vmem_map_init(void)
|
||||||
SET_MEMORY_RO | SET_MEMORY_X);
|
SET_MEMORY_RO | SET_MEMORY_X);
|
||||||
__set_memory(__stext_dma, (__etext_dma - __stext_dma) >> PAGE_SHIFT,
|
__set_memory(__stext_dma, (__etext_dma - __stext_dma) >> PAGE_SHIFT,
|
||||||
SET_MEMORY_RO | SET_MEMORY_X);
|
SET_MEMORY_RO | SET_MEMORY_X);
|
||||||
|
|
||||||
|
/* we need lowcore executable for our LPSWE instructions */
|
||||||
|
set_memory_x(0, 1);
|
||||||
|
|
||||||
pr_info("Write protected kernel read-only data: %luk\n",
|
pr_info("Write protected kernel read-only data: %luk\n",
|
||||||
(unsigned long)(__end_rodata - _stext) >> 10);
|
(unsigned long)(__end_rodata - _stext) >> 10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,6 @@ static struct irq_chip zpci_irq_chip = {
|
||||||
.name = "PCI-MSI",
|
.name = "PCI-MSI",
|
||||||
.irq_unmask = pci_msi_unmask_irq,
|
.irq_unmask = pci_msi_unmask_irq,
|
||||||
.irq_mask = pci_msi_mask_irq,
|
.irq_mask = pci_msi_mask_irq,
|
||||||
.irq_set_affinity = zpci_set_irq_affinity,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void zpci_handle_cpu_local_irq(bool rescan)
|
static void zpci_handle_cpu_local_irq(bool rescan)
|
||||||
|
@ -276,7 +275,9 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||||
rc = -EIO;
|
rc = -EIO;
|
||||||
if (hwirq - bit >= msi_vecs)
|
if (hwirq - bit >= msi_vecs)
|
||||||
break;
|
break;
|
||||||
irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE, msi->affinity);
|
irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE,
|
||||||
|
(irq_delivery == DIRECTED) ?
|
||||||
|
msi->affinity : NULL);
|
||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
rc = irq_set_msi_desc(irq, msi);
|
rc = irq_set_msi_desc(irq, msi);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user